1 // Created on: 1996-09-03
2 // Created by: Olga KOULECHOVA
3 // Copyright (c) 1996-1999 Matra Datavision
4 // Copyright (c) 1999-2014 OPEN CASCADE SAS
5 //
6 // This file is part of Open CASCADE Technology software library.
7 //
8 // This library is free software; you can redistribute it and/or modify it under
9 // the terms of the GNU Lesser General Public License version 2.1 as published
10 // by the Free Software Foundation, with special exception defined in the file
11 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
12 // distribution for complete text of the license and disclaimer of any warranty.
13 //
14 // Alternatively, this file may be used under the terms of Open CASCADE
15 // commercial license or contractual agreement.
16
17
18 #include <Bnd_Box.hxx>
19 #include <BRep_Builder.hxx>
20 #include <BRep_Tool.hxx>
21 #include <BRepAlgo.hxx>
22 #include <BRepAlgoAPI_Cut.hxx>
23 #include <BRepAlgoAPI_Fuse.hxx>
24 #include <BRepBndLib.hxx>
25 #include <BRepFeat.hxx>
26 #include <BRepFeat_MakeDPrism.hxx>
27 #include <BRepLib.hxx>
28 #include <BRepLib_MakeFace.hxx>
29 #include <BRepPrimAPI_MakeBox.hxx>
30 #include <BRepTools.hxx>
31 #include <Geom2d_Curve.hxx>
32 #include <Geom_Curve.hxx>
33 #include <Geom_Line.hxx>
34 #include <Geom_Plane.hxx>
35 #include <Geom_RectangularTrimmedSurface.hxx>
36 #include <Geom_Surface.hxx>
37 #include <gp_Pln.hxx>
38 #include <gp_Pnt.hxx>
39 #include <gp_Pnt2d.hxx>
40 #include <gp_Vec.hxx>
41 #include <LocOpe.hxx>
42 #include <LocOpe_CSIntersector.hxx>
43 #include <LocOpe_DPrism.hxx>
44 #include <LocOpe_PntFace.hxx>
45 #include <LocOpe_SequenceOfLin.hxx>
46 #include <Precision.hxx>
47 #include <Standard_ConstructionError.hxx>
48 #include <TColGeom_SequenceOfCurve.hxx>
49 #include <TColgp_SequenceOfPnt.hxx>
50 #include <TopAbs.hxx>
51 #include <TopExp.hxx>
52 #include <TopExp_Explorer.hxx>
53 #include <TopoDS.hxx>
54 #include <TopoDS_Compound.hxx>
55 #include <TopoDS_Edge.hxx>
56 #include <TopoDS_Face.hxx>
57 #include <TopoDS_Shape.hxx>
58 #include <TopoDS_Shell.hxx>
59 #include <TopoDS_Solid.hxx>
60 #include <TopTools_DataMapIteratorOfDataMapOfShapeListOfShape.hxx>
61 #include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
62 #include <TopTools_ListIteratorOfListOfShape.hxx>
63 #include <TopTools_MapIteratorOfMapOfShape.hxx>
64 #include <TopTools_MapOfShape.hxx>
65
66 #ifdef OCCT_DEBUG
67 extern Standard_Boolean BRepFeat_GettraceFEAT();
68 #endif
69
70 static void MajMap(const TopoDS_Shape&,
71 const LocOpe_DPrism&,
72 TopTools_DataMapOfShapeListOfShape&, // myMap
73 TopoDS_Shape&, // myFShape
74 TopoDS_Shape&); // myLShape
75
76 static Standard_Real HeightMax(const TopoDS_Shape& theSbase,
77 const TopoDS_Face& theSkface,
78 const TopoDS_Shape& theSFrom,
79 const TopoDS_Shape& theSUntil);
80
81 static Standard_Integer SensOfPrism(const Handle(Geom_Curve) C,
82 const TopoDS_Shape& Until);
83
84 static Handle(Geom_Curve) TestCurve(const TopoDS_Face&);
85
86
87 //=======================================================================
88 //function : Init
89 //purpose :
90 //=======================================================================
91
Init(const TopoDS_Shape & Sbase,const TopoDS_Face & Pbase,const TopoDS_Face & Skface,const Standard_Real Angle,const Standard_Integer Mode,const Standard_Boolean Modify)92 void BRepFeat_MakeDPrism::Init(const TopoDS_Shape& Sbase,
93 const TopoDS_Face& Pbase,
94 const TopoDS_Face& Skface,
95 const Standard_Real Angle,
96 const Standard_Integer Mode,
97 const Standard_Boolean Modify)
98
99 {
100 #ifdef OCCT_DEBUG
101 Standard_Boolean trc = BRepFeat_GettraceFEAT();
102 if (trc) std::cout << "BRepFeat_MakeDPrism::Init" << std::endl;
103 #endif
104 mySkface = Skface;
105 SketchFaceValid();
106 mySbase = Sbase;
107 BasisShapeValid();
108 myPbase = Pbase;
109 mySlface.Clear();
110 if(Mode == 0) {
111 myFuse = Standard_False;
112 myJustFeat = Standard_False;
113 }
114 else if(Mode == 1) {
115 myFuse = Standard_True;
116 myJustFeat = Standard_False;
117 }
118 else if(Mode == 2) {
119 myFuse = Standard_True;
120 myJustFeat = Standard_True;
121 }
122 else {
123 }
124 myModify = Modify;
125 myJustGluer = Standard_False;
126
127
128 //-------------- ifv
129 //mySkface.Nullify();
130 //-------------- ifv
131
132 myShape.Nullify();
133 myMap.Clear();
134 myFShape.Nullify();
135 myLShape.Nullify();
136 myTopEdges.Clear();
137 myLatEdges.Clear();
138 TopExp_Explorer exp;
139 for (exp.Init(mySbase,TopAbs_FACE);exp.More();exp.Next()) {
140 TopTools_ListOfShape thelist;
141 myMap.Bind(exp.Current(), thelist);
142 myMap(exp.Current()).Append(exp.Current());
143 }
144 myAngle = Angle;
145 #ifdef OCCT_DEBUG
146 if (trc) {
147 if (myJustFeat) std::cout << " Just Feature" << std::endl;
148 if (myFuse) std::cout << " Fuse" << std::endl;
149 if (!myFuse) std::cout << " Cut" << std::endl;
150 if (!myModify) std::cout << " Modify = 0" << std::endl;
151 // std::cout <<" Angle = " << myAngle << std::endl;
152 }
153 #endif
154 }
155
156
157 //=======================================================================
158 //function : Add
159 //purpose : add sliding faces and edges
160 //=======================================================================
161
Add(const TopoDS_Edge & E,const TopoDS_Face & F)162 void BRepFeat_MakeDPrism::Add(const TopoDS_Edge& E,
163 const TopoDS_Face& F)
164 {
165 #ifdef OCCT_DEBUG
166 Standard_Boolean trc = BRepFeat_GettraceFEAT();
167 if (trc) std::cout << "BRepFeat_MakeDPrism::Add(Edge,face)" << std::endl;
168 #endif
169 TopExp_Explorer exp;
170 for (exp.Init(mySbase,TopAbs_FACE);exp.More();exp.Next()) {
171 if (exp.Current().IsSame(F)) {
172 break;
173 }
174 }
175 if (!exp.More()) {
176 throw Standard_ConstructionError();
177 }
178
179 for (exp.Init(myPbase,TopAbs_EDGE);exp.More();exp.Next()) {
180 if (exp.Current().IsSame(E)) {
181 break;
182 }
183 }
184 if (!exp.More()) {
185 throw Standard_ConstructionError();
186 }
187
188 if (!mySlface.IsBound(F)) {
189 TopTools_ListOfShape thelist;
190 mySlface.Bind(F, thelist);
191 }
192 TopTools_ListIteratorOfListOfShape itl(mySlface(F));
193 for (; itl.More();itl.Next()) {
194 if (itl.Value().IsSame(E)) {
195 break;
196 }
197 }
198 if (!itl.More()) {
199 mySlface(F).Append(E);
200 }
201 }
202
203
204 //=======================================================================
205 //function : Perform
206 //purpose : feature of Height
207 //=======================================================================
208
Perform(const Standard_Real Height)209 void BRepFeat_MakeDPrism::Perform(const Standard_Real Height)
210 {
211 #ifdef OCCT_DEBUG
212 Standard_Boolean trc = BRepFeat_GettraceFEAT();
213 if (trc) std::cout << "BRepFeat_MakeDPrism::Perform(Height)" << std::endl;
214 #endif
215 mySFrom.Nullify();
216 ShapeFromValid();
217 mySUntil.Nullify();
218 ShapeUntilValid();
219 myGluedF.Clear();
220 myPerfSelection = BRepFeat_NoSelection;
221 PerfSelectionValid();
222
223 Standard_Real theheight = Height/cos(myAngle);
224 // myPbase.Orientation(TopAbs_FORWARD);
225
226 LocOpe_DPrism theDPrism(myPbase,theheight,myAngle);
227 TopoDS_Shape VraiDPrism = theDPrism.Shape();
228
229 MajMap(myPbase,theDPrism,myMap,myFShape,myLShape);
230
231 myGShape = VraiDPrism;
232 GeneratedShapeValid();
233 TopoDS_Shape Base = theDPrism.FirstShape();
234 TopExp_Explorer exp(Base, TopAbs_FACE);
235 TopoDS_Face theBase = TopoDS::Face(exp.Current());
236 exp.Next();
237 if(exp.More()) {
238 NotDone();
239 myStatusError = BRepFeat_InvFirstShape;
240 return;
241 }
242
243 // management of gluing faces
244
245 GluedFacesValid();
246
247 if(!myGluedF.IsEmpty()) { // case gluing
248 myJustGluer = Standard_True;
249 theDPrism.Curves(myCurves);
250 myBCurve = theDPrism.BarycCurve();
251 GlobalPerform();
252 }
253
254 // if there is no gluing -> call topological operations
255 if(!myJustGluer) {
256 if(myFuse == 1) {
257 BRepAlgoAPI_Fuse f(mySbase, myGShape);
258 myShape = f.Shape();
259 UpdateDescendants(f, myShape, Standard_False);
260 Done();
261 }
262 else if(myFuse == 0) {
263 BRepAlgoAPI_Cut c(mySbase, myGShape);
264 myShape = c.Shape();
265 UpdateDescendants(c, myShape, Standard_False);
266 Done();
267 }
268 else {
269 myShape = myGShape;
270 Done();
271 }
272 }
273 }
274
275 //=======================================================================
276 //function : Perform
277 //purpose : feature limited by the shape Until
278 //=======================================================================
279
Perform(const TopoDS_Shape & Until)280 void BRepFeat_MakeDPrism::Perform(const TopoDS_Shape& Until)
281 {
282 #ifdef OCCT_DEBUG
283 Standard_Boolean trc = BRepFeat_GettraceFEAT();
284 if (trc) std::cout << "BRepFeat_MakeDPrism::Perform(Until)" << std::endl;
285 #endif
286 if (Until.IsNull()) {
287 throw Standard_ConstructionError();
288 }
289 TopExp_Explorer exp(Until, TopAbs_FACE);
290 if (!exp.More()) {
291 throw Standard_ConstructionError();
292 }
293 // myPbase.Orientation(TopAbs_FORWARD);
294
295 myGluedF.Clear();
296 myPerfSelection = BRepFeat_SelectionU;
297 PerfSelectionValid();
298 mySFrom.Nullify();
299 ShapeFromValid();
300 mySUntil = Until;
301 Standard_Boolean Trf = TransformShapeFU(1);
302 ShapeUntilValid();
303 Handle(Geom_Curve) C = TestCurve(myPbase);
304 Standard_Integer sens = SensOfPrism(C, mySUntil);
305
306 BRep_Builder bB;
307 Standard_Real Height =
308 sens*HeightMax(mySbase, mySkface, mySFrom, mySUntil);
309 LocOpe_DPrism theDPrism(myPbase,Height,myAngle);
310 TopoDS_Shape VraiDPrism = theDPrism.Shape();
311 if(!Trf) {
312 MajMap(myPbase,theDPrism,myMap,myFShape,myLShape);
313 myGShape = VraiDPrism;
314 GeneratedShapeValid();
315 TopoDS_Shape Base = theDPrism.FirstShape();
316 exp.Init(Base, TopAbs_FACE);
317 TopoDS_Face theBase = TopoDS::Face(exp.Current());
318 exp.Next();
319 if(exp.More()) {
320 NotDone();
321 myStatusError = BRepFeat_InvFirstShape;
322 return;
323 }
324
325 GluedFacesValid();
326 theDPrism.Curves(myCurves);
327 myBCurve = theDPrism.BarycCurve();
328 GlobalPerform();
329 }
330 else {
331 MajMap(myPbase,theDPrism,myMap,myFShape,myLShape);
332 Handle(Geom_Curve) C1;
333 if(sens == -1) {
334 C1 = C->Reversed();
335 }
336 else {
337 C1 = C;
338 }
339
340 TColGeom_SequenceOfCurve scur;
341 scur.Clear();
342 scur.Append(C1);
343 LocOpe_CSIntersector ASI(mySUntil);
344 ASI.Perform(scur);
345 TopAbs_Orientation Or;
346 if (ASI.IsDone() && ASI.NbPoints(1) >=1) {
347 if (myFuse == 1) {
348 Or = ASI.Point(1,1).Orientation();
349 }
350 else {
351 Or = ASI.Point(1,ASI.NbPoints(1)).Orientation();
352 }
353 // Standard_Real prm = ASI.Point(1,1).Parameter();
354 // if(prm < 0) Or = TopAbs::Reverse(Or);
355 TopoDS_Face FUntil = ASI.Point(1,1).Face();
356 TopoDS_Shape Comp;
357 bB.MakeCompound(TopoDS::Compound(Comp));
358 TopoDS_Solid S = BRepFeat::Tool(mySUntil, FUntil, Or);
359 if (!S.IsNull()) bB.Add(Comp,S);
360
361 BRepAlgoAPI_Cut trP(VraiDPrism,Comp);
362 UpdateDescendants(trP, trP.Shape(), Standard_False);
363
364 TopExp_Explorer ex(trP.Shape(), TopAbs_SOLID);
365 TopoDS_Shape Cutsh = ex.Current();
366 if(myFuse == 1) {
367 BRepAlgoAPI_Fuse f(mySbase, Cutsh);
368 myShape = f.Shape();
369 UpdateDescendants(f, myShape, Standard_False);
370 Done();
371 }
372 else if(myFuse == 0) {
373 BRepAlgoAPI_Cut c(mySbase, Cutsh);
374 myShape = c.Shape();
375 UpdateDescendants(c, myShape, Standard_False);
376 Done();
377 }
378 else {
379 myShape = Cutsh;
380 Done();
381 }
382 }
383 }
384 TopTools_ListIteratorOfListOfShape ited(myNewEdges);
385 for (; ited.More();ited.Next()) {
386 const TopoDS_Edge& ledg=TopoDS::Edge(ited.Value());
387 if (!BRepAlgo::IsValid(ledg)) {
388 bB.SameRange(ledg, Standard_False);
389 bB.SameParameter(ledg, Standard_False);
390 BRepLib::SameParameter(ledg, BRep_Tool::Tolerance(ledg));
391 }
392 }
393 }
394
395
396 //=======================================================================
397 //function : Perform
398 //purpose : feature limited by two shapes
399 //=======================================================================
400
Perform(const TopoDS_Shape & From,const TopoDS_Shape & Until)401 void BRepFeat_MakeDPrism::Perform(const TopoDS_Shape& From,
402 const TopoDS_Shape& Until)
403 {
404 #ifdef OCCT_DEBUG
405 Standard_Boolean trc = BRepFeat_GettraceFEAT();
406 if (trc) std::cout << "BRepFeat_MakeDPrism::Perform(From,Until)" << std::endl;
407 #endif
408 if (From.IsNull() || Until.IsNull()) {
409 throw Standard_ConstructionError();
410 }
411
412 if (!mySkface.IsNull()) {
413 if (From.IsSame(mySkface)) {
414 myJustGluer = Standard_True;
415 Perform(Until);
416 if (myJustGluer) return;
417 }
418 else if (Until.IsSame(mySkface)) {
419 myJustGluer = Standard_True;
420 Perform(From);
421 if (myJustGluer) return;
422 }
423 }
424 // myPbase.Orientation(TopAbs_FORWARD);
425
426 myGluedF.Clear();
427 myPerfSelection = BRepFeat_SelectionFU;
428 PerfSelectionValid();
429
430 TopExp_Explorer exp(From, TopAbs_FACE);
431 if (!exp.More()) {
432 throw Standard_ConstructionError();
433 }
434 exp.Init(Until, TopAbs_FACE);
435 if (!exp.More()) {
436 throw Standard_ConstructionError();
437 }
438 mySFrom = From;
439 Standard_Boolean Trff = TransformShapeFU(0);
440 ShapeFromValid();
441 mySUntil = Until;
442 Standard_Boolean Trfu = TransformShapeFU(1);
443 ShapeUntilValid();
444 if(Trfu != Trff) {
445 NotDone();
446 myStatusError = BRepFeat_IncTypes;
447 return;
448 }
449 Handle(Geom_Curve) C = TestCurve(myPbase);
450 Standard_Integer sens;
451 if(From.IsSame(Until)) {
452 sens = 1;
453 }
454 else {
455 sens = SensOfPrism(C, mySUntil);
456 }
457
458 Standard_Real Height =
459 sens*HeightMax(mySbase, myPbase, mySFrom, mySUntil);
460 LocOpe_DPrism theDPrism(myPbase, Height, Height, myAngle);
461 TopoDS_Shape VraiDPrism = theDPrism.Shape();
462
463
464 if(!Trff) {
465 MajMap(myPbase,theDPrism,myMap,myFShape,myLShape);
466
467 // Make systematically dprism
468 myGShape = VraiDPrism;
469 GeneratedShapeValid();
470
471 // management of gluing faces
472 // mySbase, myPbase, mySlface, theDPrism, myGluedF);
473 GluedFacesValid();
474 theDPrism.Curves(myCurves);
475 myBCurve = theDPrism.BarycCurve();
476
477 // topologic reconstruction
478 GlobalPerform();
479 }
480 else {
481 // management of descendants
482 MajMap(myPbase,theDPrism,myMap,myFShape,myLShape);
483 Handle(Geom_Curve) C1;
484 if(sens == -1) {
485 C1 = C->Reversed();
486 }
487 else {
488 C1 = C;
489 }
490 TColGeom_SequenceOfCurve scur;
491 scur.Clear();
492 scur.Append(C1);
493 LocOpe_CSIntersector ASI1(mySUntil);
494 LocOpe_CSIntersector ASI2(mySFrom);
495 ASI1.Perform(scur);
496 ASI2.Perform(scur);
497 TopAbs_Orientation OrU, OrF;
498 TopoDS_Face FFrom, FUntil;
499 //direction of dprism
500 if (ASI1.IsDone() && ASI1.NbPoints(1) >=1) {
501 if (myFuse == 1) {
502 OrU = ASI1.Point(1,1).Orientation();
503 }
504 else {
505 OrU = ASI1.Point(1,ASI1.NbPoints(1)).Orientation();
506 }
507 // Standard_Real prm = ASI1.Point(1,1).Parameter();
508 // if(prm < 0) OrU = TopAbs::Reverse(OrU);
509 FUntil = ASI1.Point(1,1).Face();
510 }
511 else {
512 NotDone();
513 myStatusError = BRepFeat_NoIntersectU;
514 return;
515 }
516 if (ASI2.IsDone() && ASI2.NbPoints(1) >=1) {
517 OrF = ASI2.Point(1,1).Orientation();
518 // Standard_Real prm = ASI2.Point(1,1).Parameter();
519 OrF = TopAbs::Reverse(OrF);
520 FFrom = ASI2.Point(1,1).Face();
521 }
522 else {
523 NotDone();
524 myStatusError = BRepFeat_NoIntersectF;
525 return;
526 }
527 TopoDS_Shape Comp;
528 BRep_Builder B;
529 B.MakeCompound(TopoDS::Compound(Comp));
530 TopoDS_Solid S = BRepFeat::Tool(mySUntil, FUntil, OrU);
531 if (!S.IsNull()) B.Add(Comp,S);
532 else {
533 NotDone();
534 myStatusError = BRepFeat_NullToolU;
535 return;
536 }
537 TopoDS_Solid SS = BRepFeat::Tool(mySFrom, FFrom, OrF);
538 if (!SS.IsNull()) B.Add(Comp,SS);
539 else {
540 NotDone();
541 myStatusError = BRepFeat_NullToolF;
542 return;
543 }
544
545 BRepAlgoAPI_Cut trP(VraiDPrism,Comp);
546
547 if(myFuse == 1) {
548 BRepAlgoAPI_Fuse f(mySbase, trP.Shape());
549 myShape = f.Shape();
550 UpdateDescendants(f, myShape, Standard_False);
551 Done();
552 }
553 //
554 else if(myFuse == 0) {
555 BRepAlgoAPI_Cut c(mySbase, trP.Shape());
556 myShape = c.Shape();
557 UpdateDescendants(c, myShape, Standard_False);
558 Done();
559 }
560 else {
561 myShape = trP.Shape();
562 Done();
563 }
564 }
565 }
566
567
568 //=======================================================================
569 //function : Perform
570 //purpose : feature semi-infinie
571 //=======================================================================
572
PerformUntilEnd()573 void BRepFeat_MakeDPrism::PerformUntilEnd()
574 {
575 #ifdef OCCT_DEBUG
576 Standard_Boolean trc = BRepFeat_GettraceFEAT();
577 if (trc) std::cout << "BRepFeat_MakeDPrism::PerformUntilEnd()" << std::endl;
578 #endif
579 myPerfSelection = BRepFeat_SelectionSh;
580 PerfSelectionValid();
581 myGluedF.Clear();
582 mySUntil.Nullify();
583 ShapeUntilValid();
584 mySFrom.Nullify();
585 ShapeFromValid();
586 Standard_Real Height = HeightMax(mySbase, mySkface, mySFrom, mySUntil);
587 // myPbase.Orientation(TopAbs_FORWARD);
588
589 LocOpe_DPrism theDPrism(myPbase, Height, myAngle);
590 TopoDS_Shape VraiDPrism = theDPrism.Shape();
591
592 MajMap(myPbase,theDPrism,myMap,myFShape,myLShape);
593
594 myGShape = VraiDPrism;
595 GeneratedShapeValid();
596 GluedFacesValid();
597 theDPrism.Curves(myCurves);
598 myBCurve = theDPrism.BarycCurve();
599 GlobalPerform();
600 }
601
602 //=======================================================================
603 //function : PerformFromEnd
604 //purpose : feature semiinfinite limited by the shape Until from the other side
605 //=======================================================================
606
PerformFromEnd(const TopoDS_Shape & Until)607 void BRepFeat_MakeDPrism::PerformFromEnd(const TopoDS_Shape& Until)
608 {
609 #ifdef OCCT_DEBUG
610 Standard_Boolean trc = BRepFeat_GettraceFEAT();
611 if (trc) std::cout << "BRepFeat_MakeDPrism::PerformFromEnd(From,Until)" << std::endl;
612 #endif
613 if (Until.IsNull()) {
614 throw Standard_ConstructionError();
615 }
616 if (!mySkface.IsNull() && Until.IsSame(mySkface)) {
617 PerformUntilEnd();
618 return;
619 }
620 TopExp_Explorer exp;
621 exp.Init(Until, TopAbs_FACE);
622 if (!exp.More()) {
623 throw Standard_ConstructionError();
624 }
625 // myPbase.Orientation(TopAbs_FORWARD);
626 myPerfSelection = BRepFeat_SelectionShU;
627 PerfSelectionValid();
628 mySFrom.Nullify();
629 ShapeFromValid();
630 mySUntil = Until;
631 Standard_Boolean Trf = TransformShapeFU(1);
632 ShapeUntilValid();
633 Handle(Geom_Curve) C = TestCurve(myPbase);
634 Standard_Integer sens = SensOfPrism(C, mySUntil);
635 Standard_Real Height =
636 sens*HeightMax(mySbase, mySkface, mySFrom, mySUntil);
637
638 LocOpe_DPrism theDPrism(myPbase, Height, Height, myAngle);
639 TopoDS_Shape VraiDPrism = theDPrism.Shape();
640 if(VraiDPrism.IsNull()) {
641 NotDone();
642 myStatusError = BRepFeat_NullRealTool;
643 return;
644 }
645
646 if(!Trf) { // case finite face
647 MajMap(myPbase,theDPrism,myMap,myFShape,myLShape);
648 myGShape = VraiDPrism;
649 GeneratedShapeValid();
650 myGluedF.Clear();
651 GluedFacesValid();
652 theDPrism.Curves(myCurves);
653 myBCurve = theDPrism.BarycCurve();
654 GlobalPerform();
655 }
656 else { // case support
657 MajMap(myPbase,theDPrism,myMap,myFShape,myLShape);
658 Handle(Geom_Curve) C2;
659 if(sens == -1) {
660 C2 = C->Reversed();
661 }
662 else {
663 C2 = C;
664 }
665 TColGeom_SequenceOfCurve scur;
666 scur.Clear();
667 scur.Append(C2);
668 LocOpe_CSIntersector ASI1(mySUntil);
669 LocOpe_CSIntersector ASI2(mySbase);
670 ASI1.Perform(scur);
671 ASI2.Perform(scur);
672 TopAbs_Orientation OrU = TopAbs_FORWARD, OrF = TopAbs_FORWARD;
673 TopoDS_Face FUntil, FFrom;
674 if (ASI1.IsDone() && ASI1.NbPoints(1) >=1) {
675 OrU = ASI1.Point(1,1).Orientation();
676 Standard_Real prm = ASI1.Point(1,1).Parameter();
677 if(prm < 0) OrU = TopAbs::Reverse(OrU);
678 FUntil = ASI1.Point(1,1).Face();
679 }
680
681 if (ASI2.IsDone() && ASI2.NbPoints(1) >=1) {
682 Standard_Integer jj = ASI2.NbPoints(1);
683 Standard_Real prm = ASI2.Point(1,1).Parameter();
684 FFrom = ASI2.Point(1, 1).Face();
685 OrF = ASI2.Point(1,1).Orientation();
686 OrF = TopAbs::Reverse(OrF);
687 for(Standard_Integer iii = 1; iii <= jj; iii++) {
688 if(ASI2.Point(1,iii).Parameter() < prm) {
689 prm = ASI2.Point(1,iii).Parameter();
690 FFrom = ASI2.Point(1, iii).Face();
691 OrF = ASI2.Point(1,iii).Orientation();
692 OrF = TopAbs::Reverse(OrF);
693 }
694 }
695 Handle(Geom_Surface) S = BRep_Tool::Surface(FFrom);
696 if (S->DynamicType() ==
697 STANDARD_TYPE(Geom_RectangularTrimmedSurface)) {
698 S = Handle(Geom_RectangularTrimmedSurface)::
699 DownCast(S)->BasisSurface();
700 }
701 BRepLib_MakeFace fac(S, Precision::Confusion());
702 mySFrom = fac.Face();
703 Trf = TransformShapeFU(0);
704 // FFrom = TopoDS::Face(mySFrom);
705 }
706
707 TopoDS_Shape Comp;
708 BRep_Builder B;
709 B.MakeCompound(TopoDS::Compound(Comp));
710 TopoDS_Solid Sol = BRepFeat::Tool(mySUntil, FUntil, OrU);
711 if (!Sol.IsNull()) B.Add(Comp,Sol);
712 else {
713 NotDone();
714 myStatusError = BRepFeat_NullToolU;
715 return;
716 }
717
718 TopoDS_Solid Sol1 = BRepFeat::Tool(mySFrom, FFrom, OrF);
719 if (!Sol1.IsNull()) B.Add(Comp,Sol1);
720 else {
721 NotDone();
722 myStatusError = BRepFeat_NullToolF;
723 return;
724 }
725
726 BRepAlgoAPI_Cut trP(VraiDPrism,Comp);
727 if(myFuse == 1) {
728 BRepAlgoAPI_Fuse f(mySbase, trP.Shape());
729 myShape = f.Shape();
730 UpdateDescendants(f, myShape, Standard_False);
731 Done();
732 }
733 else if(myFuse == 0) {
734 BRepAlgoAPI_Cut c(mySbase, trP.Shape());
735 myShape = c.Shape();
736 UpdateDescendants(c, myShape, Standard_False);
737 Done();
738 }
739 else {
740 myShape = trP.Shape();
741 Done();
742 }
743 }
744 }
745
746
747
748 //=======================================================================
749 //function : PerformThruAll
750 //purpose : feature throughout the entire initial shape
751 //=======================================================================
752
PerformThruAll()753 void BRepFeat_MakeDPrism::PerformThruAll()
754 {
755 #ifdef OCCT_DEBUG
756 Standard_Boolean trc = BRepFeat_GettraceFEAT();
757 if (trc) std::cout << "BRepFeat_MakeDPrism::PerformThruAll()" << std::endl;
758 #endif
759 mySUntil.Nullify();
760 ShapeUntilValid();
761 mySFrom.Nullify();
762 ShapeFromValid();
763 if(myFuse == 0) {
764 myPerfSelection = BRepFeat_NoSelection;
765 }
766 else {
767 myPerfSelection = BRepFeat_SelectionSh;
768 }
769
770 PerfSelectionValid();
771 // myPbase.Orientation(TopAbs_FORWARD);
772 myGluedF.Clear();
773 GluedFacesValid();
774
775 Standard_Real Height = HeightMax(mySbase, mySkface, mySFrom, mySUntil);
776 LocOpe_DPrism theDPrism(myPbase, Height, Height, myAngle);
777 TopoDS_Shape VraiDPrism = theDPrism.Shape();
778 MajMap(myPbase,theDPrism,myMap,myFShape,myLShape);
779
780 myGShape = VraiDPrism;
781 GeneratedShapeValid();
782
783 if(myFuse == 0) {
784 BRepAlgoAPI_Cut c(mySbase, myGShape);
785 if (c.IsDone()) {
786 myShape = c.Shape();
787 UpdateDescendants(c, myShape, Standard_False);
788 Done();
789 }
790 }
791 else {
792 theDPrism.Curves(myCurves);
793 myBCurve = theDPrism.BarycCurve();
794 GlobalPerform();
795 }
796 }
797
798
799 //=======================================================================
800 //function : PerformUntilHeight
801 //purpose : feature until the shape is of the given height
802 //=======================================================================
803
PerformUntilHeight(const TopoDS_Shape & Until,const Standard_Real Height)804 void BRepFeat_MakeDPrism::PerformUntilHeight(const TopoDS_Shape& Until,
805 const Standard_Real Height)
806 {
807 #ifdef OCCT_DEBUG
808 Standard_Boolean trc = BRepFeat_GettraceFEAT();
809 if (trc) std::cout << "BRepFeat_MakeDPrism::PerformUntilHeight(Until,Height)" << std::endl;
810 #endif
811 if (Until.IsNull()) {
812 Perform(Height);
813 }
814 if(Height == 0) {
815 Perform(Until);
816 }
817 TopExp_Explorer exp(Until, TopAbs_FACE);
818 if (!exp.More()) {
819 throw Standard_ConstructionError();
820 }
821 // myPbase.Orientation(TopAbs_FORWARD);
822 myGluedF.Clear();
823 myPerfSelection = BRepFeat_NoSelection;
824 PerfSelectionValid();
825 mySFrom.Nullify();
826 ShapeFromValid();
827 mySUntil = Until;
828 Standard_Boolean Trf = TransformShapeFU(1);
829 ShapeUntilValid();
830 Handle(Geom_Curve) C = TestCurve(myPbase);
831 Standard_Integer sens = SensOfPrism(C, mySUntil);
832
833 LocOpe_DPrism theDPrism(myPbase,sens*Height,myAngle);
834 TopoDS_Shape VraiDPrism = theDPrism.Shape();
835
836 if(!Trf) { // case face finished
837 MajMap(myPbase,theDPrism,myMap,myFShape,myLShape);
838 myGShape = VraiDPrism;
839 GeneratedShapeValid();
840 TopoDS_Shape Base = theDPrism.FirstShape();
841 exp.Init(Base, TopAbs_FACE);
842 TopoDS_Face theBase = TopoDS::Face(exp.Current());
843 exp.Next();
844 if(exp.More()) {
845 NotDone();
846 myStatusError = BRepFeat_InvFirstShape;
847 return;
848 }
849
850 GluedFacesValid();
851 theDPrism.Curves(myCurves);
852 myBCurve = theDPrism.BarycCurve();
853 GlobalPerform();
854 }
855 else { // case support
856 MajMap(myPbase,theDPrism,myMap,myFShape,myLShape);
857 Handle(Geom_Curve) C1;
858 if(sens == -1) {
859 C1 = C->Reversed();
860 }
861 else {
862 C1 = C;
863 }
864 TColGeom_SequenceOfCurve scur;
865 scur.Clear();
866 scur.Append(C1);
867 LocOpe_CSIntersector ASI(mySUntil);
868 ASI.Perform(scur);
869 TopAbs_Orientation Or;
870 if (ASI.IsDone() && ASI.NbPoints(1) >=1) {
871 if (myFuse == 1) {
872 Or = ASI.Point(1,1).Orientation();
873 }
874 else {
875 Or = ASI.Point(1,ASI.NbPoints(1)).Orientation();
876 }
877 // Standard_Real prm = ASI.Point(1,1).Parameter();
878 // if(prm < 0) Or = TopAbs::Reverse(Or);
879 TopoDS_Face FUntil = ASI.Point(1,1).Face();
880 TopoDS_Shape Comp;
881 BRep_Builder B;
882 B.MakeCompound(TopoDS::Compound(Comp));
883 TopoDS_Solid S = BRepFeat::Tool(mySUntil, FUntil, Or);
884 if (!S.IsNull()) B.Add(Comp,S);
885 BRepAlgoAPI_Cut trP(VraiDPrism,Comp);
886 if(myFuse == 1) {
887 BRepAlgoAPI_Fuse f(mySbase, trP.Shape());
888 myShape = f.Shape();
889 UpdateDescendants(f, myShape, Standard_False);
890 Done();
891 }
892 else if(myFuse == 0) {
893 BRepAlgoAPI_Cut c(mySbase, trP.Shape());
894 myShape = c.Shape();
895 UpdateDescendants(c, myShape, Standard_False);
896 Done();
897 }
898 else {
899 myShape = trP.Shape();
900 Done();
901 }
902 }
903 }
904 }
905
906
907 //=======================================================================
908 //function : Curves
909 //purpose : curves parallel to the axis of the prism
910 //=======================================================================
911
Curves(TColGeom_SequenceOfCurve & scur)912 void BRepFeat_MakeDPrism::Curves(TColGeom_SequenceOfCurve& scur)
913 {
914 scur = myCurves;
915 }
916
917 //============================================================================
918 // function : BRepFeat_BossEgdes
919 // purpose: Determination of TopEdges and LatEdges.
920 // sig = 1 -> TopEdges = FirstShape of the DPrism
921 // sig = 2 -> TOpEdges = LastShape of the DPrism
922 //============================================================================
BossEdges(const Standard_Integer signature)923 void BRepFeat_MakeDPrism::BossEdges (const Standard_Integer signature)
924 {
925 #ifdef OCCT_DEBUG
926 Standard_Boolean trc = BRepFeat_GettraceFEAT();
927 if (trc) std::cout << "BRepFeat_MakeDPrism::BossEdges (integer)" << std::endl;
928 #endif
929 TopTools_ListOfShape theLastShape;
930 theLastShape.Clear();
931 if (signature == 1 || signature == -1) {
932 theLastShape = FirstShape();
933 }
934 else if (signature == 2 || signature == -2) {
935 theLastShape = LastShape();
936 }
937 else {
938 return;
939 }
940
941 // Edges Top
942 TopTools_ListIteratorOfListOfShape itLS;
943 TopExp_Explorer ExpE;
944 for (itLS.Initialize(theLastShape);itLS.More();itLS.Next()) {
945 const TopoDS_Face& FF = TopoDS::Face(itLS.Value());
946 for (ExpE.Init(FF,TopAbs_EDGE);ExpE.More();ExpE.Next()) {
947 const TopoDS_Edge& EE = TopoDS::Edge(ExpE.Current());
948 myTopEdges.Append(EE);
949 }
950 }
951
952 // Edges Bottom
953 if (signature < 0) {
954 // Attention check if TgtEdges is important
955 myLatEdges = NewEdges();
956 }
957 else if (signature > 0) {
958 if ( !myShape.IsNull() ) {
959 TopTools_MapOfShape MapE;
960 Standard_Boolean Found;
961
962 TopExp_Explorer ExpF;
963 for (ExpF.Init(myShape,TopAbs_FACE);ExpF.More();ExpF.Next()) {
964 Found = Standard_False;
965 const TopoDS_Face& FF = TopoDS::Face(ExpF.Current());
966 for (itLS.Initialize(theLastShape);itLS.More();itLS.Next()) {
967 const TopoDS_Face& TopFace = TopoDS::Face(itLS.Value());
968 if (!FF.IsSame(TopFace)) {
969 for (ExpE.Init(FF,TopAbs_EDGE);ExpE.More() && !Found ;ExpE.Next()) {
970 const TopoDS_Edge& E1 = TopoDS::Edge(ExpE.Current());
971 TopoDS_Vertex V1,V2;
972 TopExp::Vertices (E1,V1,V2);
973 TopTools_ListIteratorOfListOfShape it(myTopEdges);
974 for (;it.More() && !Found ; it.Next()) {
975 TopoDS_Edge E2 = TopoDS::Edge(it.Value());
976 TopoDS_Vertex VT1,VT2;
977 TopExp::Vertices (E2,VT1,VT2);
978
979 if (V1.IsSame(VT1) || V1.IsSame(VT2) || V2.IsSame(VT1) || V2.IsSame(VT2)) {
980 Found = Standard_True;
981 TopExp_Explorer ExpE2;
982 for (ExpE2.Init(FF,TopAbs_EDGE);ExpE2.More();ExpE2.Next()) {
983 const TopoDS_Edge& E3 = TopoDS::Edge(ExpE2.Current());
984 if (MapE.Contains(E3)) {
985 MapE.Remove(E3); }
986 else {
987 MapE.Add(E3);}
988 }
989 }
990 }
991 }
992 }
993 }
994 }
995
996 TopTools_ListIteratorOfListOfShape it(myTopEdges);
997 for (;it.More() ; it.Next()) {
998 if (MapE.Contains(it.Value())) {MapE.Remove(it.Value()); }
999 }
1000
1001 TopTools_MapIteratorOfMapOfShape itMap;
1002 for (itMap.Initialize(MapE);itMap.More();itMap.Next()) {
1003 if (!BRep_Tool::Degenerated(TopoDS::Edge(itMap.Key())))
1004 myLatEdges.Append(itMap.Key());
1005 }
1006 }
1007 }
1008 }
1009
1010
1011
1012 //============================================================================
1013 // function : BRepFeat_TopEgdes
1014 // Purpose: Returns the list of TopoDS Edges of the top of the boss
1015 //============================================================================
TopEdges()1016 const TopTools_ListOfShape& BRepFeat_MakeDPrism::TopEdges ()
1017 {
1018 return myTopEdges;
1019 }
1020
1021 //============================================================================
1022 // function : BRepFeat_LatEgdes
1023 // Purpose: Returns the list of TopoDS Edges of the top of the boss
1024 //============================================================================
LatEdges()1025 const TopTools_ListOfShape& BRepFeat_MakeDPrism::LatEdges ()
1026 {
1027 return myLatEdges;
1028 }
1029
1030 //=======================================================================
1031 //function : BarycCurve
1032 //purpose : passe par le centre de masses de la primitive
1033 //=======================================================================
1034
Handle(Geom_Curve)1035 Handle(Geom_Curve) BRepFeat_MakeDPrism::BarycCurve()
1036 {
1037 return myBCurve;
1038 }
1039
1040
1041 //=======================================================================
1042 //function : HeightMax
1043 //purpose : Calculate the height of the prism following the parameters of the bounding box
1044 //=======================================================================
1045
HeightMax(const TopoDS_Shape & theSbase,const TopoDS_Face & theSkface,const TopoDS_Shape & theSFrom,const TopoDS_Shape & theSUntil)1046 static Standard_Real HeightMax(const TopoDS_Shape& theSbase, // shape initial
1047 const TopoDS_Face& theSkface, // face de sketch
1048 const TopoDS_Shape& theSFrom, // shape from
1049 const TopoDS_Shape& theSUntil) // shape until
1050 {
1051 Bnd_Box Box;
1052 BRepBndLib::Add(theSbase,Box);
1053 BRepBndLib::Add(theSkface,Box);
1054 if(!theSFrom.IsNull()) {
1055 BRepBndLib::Add(theSFrom,Box);
1056 }
1057 if(!theSUntil.IsNull()) {
1058 BRepBndLib::Add(theSUntil,Box);
1059 }
1060 Standard_Real c[6];
1061
1062 Box.Get(c[0],c[2],c[4],c[1],c[3],c[5]);
1063 // Standard_Real parmin=c[0], parmax = c[0];
1064 // for(Standard_Integer i = 0 ; i < 6; i++) {
1065 // if(c[i] > parmax) parmax = c[i];
1066 // if(c[i] < parmin ) parmin = c[i];
1067 // }
1068 // Standard_Real Height = abs(2.*(parmax - parmin));
1069 // return(2.*Height);
1070 //#ifndef OCCT_DEBUG
1071 Standard_Real par = Max( Max( fabs(c[1] - c[0]), fabs(c[3] - c[2]) ), fabs(c[5] - c[4]) );
1072 //#else
1073 // Standard_Real par = Max( Max( abs(c[1] - c[0]), abs(c[3] - c[2]) ), abs(c[5] - c[4]) );
1074 //#endif
1075 #ifdef OCCT_DEBUG
1076 std::cout << "Height = > " << par << std::endl;
1077 #endif
1078 return par;
1079 }
1080
1081
1082
1083
1084
1085 //=======================================================================
1086 //function : SensOfPrism
1087 //purpose : determine the direction of prism generation
1088 //=======================================================================
SensOfPrism(const Handle (Geom_Curve)C,const TopoDS_Shape & Until)1089 Standard_Integer SensOfPrism(const Handle(Geom_Curve) C,
1090 const TopoDS_Shape& Until)
1091 {
1092 LocOpe_CSIntersector ASI1(Until);
1093 TColGeom_SequenceOfCurve scur;
1094 scur.Append(C);
1095 ASI1.Perform(scur);
1096 Standard_Integer sens = 1;
1097 if(ASI1.IsDone() && ASI1.NbPoints(1) >= 1) {
1098 Standard_Integer nb = ASI1.NbPoints(1);
1099 Standard_Real prm1 = ASI1.Point(1, 1).Parameter();
1100 Standard_Real prm2 = ASI1.Point(1, nb).Parameter();
1101 if(prm1 < 0. && prm2 < 0.) {
1102 sens = -1;
1103 }
1104 }
1105 else if(BRepFeat::ParametricBarycenter(Until,C) < 0) {
1106 sens = -1;
1107 }
1108 else {}
1109 return sens;
1110 }
1111
1112 //=======================================================================
1113 //function : MajMap
1114 //purpose :
1115 //=======================================================================
1116
MajMap(const TopoDS_Shape & theB,const LocOpe_DPrism & theP,TopTools_DataMapOfShapeListOfShape & theMap,TopoDS_Shape & theFShape,TopoDS_Shape & theLShape)1117 static void MajMap(const TopoDS_Shape& theB,
1118 const LocOpe_DPrism& theP,
1119 TopTools_DataMapOfShapeListOfShape& theMap, // myMap
1120 TopoDS_Shape& theFShape, // myFShape
1121 TopoDS_Shape& theLShape) // myLShape
1122 {
1123 TopExp_Explorer exp;
1124 if(!theP.FirstShape().IsNull()) {
1125 exp.Init(theP.FirstShape(),TopAbs_WIRE);
1126 if (exp.More()) {
1127 theFShape = exp.Current();
1128 TopTools_ListOfShape thelist;
1129 theMap.Bind(theFShape, thelist);
1130 for (exp.Init(theP.FirstShape(),TopAbs_FACE);exp.More();exp.Next()) {
1131 theMap(theFShape).Append(exp.Current());
1132 }
1133 }
1134 }
1135
1136 if(!theP.LastShape().IsNull()) {
1137 exp.Init(theP.LastShape(),TopAbs_WIRE);
1138 if (exp.More()) {
1139 theLShape = exp.Current();
1140 TopTools_ListOfShape thelist1;
1141 theMap.Bind(theLShape, thelist1);
1142 for (exp.Init(theP.LastShape(),TopAbs_FACE);exp.More();exp.Next()) {
1143 theMap(theLShape).Append(exp.Current());
1144 }
1145 }
1146 }
1147
1148 for (exp.Init(theB,TopAbs_EDGE); exp.More(); exp.Next()) {
1149 if (!theMap.IsBound(exp.Current())) {
1150 const TopoDS_Edge& edg = TopoDS::Edge(exp.Current());
1151 TopTools_ListOfShape thelist2;
1152 theMap.Bind(edg, thelist2);
1153 theMap(edg) = theP.Shapes(edg);
1154 }
1155 }
1156 }
1157
1158
1159 //=======================================================================
1160 //function : MajMap
1161 //purpose :
1162 //=======================================================================
1163
TestCurve(const TopoDS_Face & Base)1164 static Handle(Geom_Curve) TestCurve(const TopoDS_Face& Base)
1165 {
1166 gp_Pnt bar(0., 0., 0.);
1167 TColgp_SequenceOfPnt spt;
1168 LocOpe::SampleEdges(Base,spt);
1169 for (Standard_Integer jj=1;jj<=spt.Length(); jj++) {
1170 const gp_Pnt& pvt = spt(jj);
1171 bar.ChangeCoord() += pvt.XYZ();
1172 }
1173 bar.ChangeCoord().Divide(spt.Length());
1174 Handle(Geom_Surface) s = BRep_Tool::Surface(Base);
1175 if (s->DynamicType() == STANDARD_TYPE(Geom_RectangularTrimmedSurface)) {
1176 s = Handle(Geom_RectangularTrimmedSurface)::
1177 DownCast(s)->BasisSurface();
1178 }
1179 Handle (Geom_Plane) P = Handle(Geom_Plane)::DownCast(s);
1180 if(P.IsNull()) {
1181 Handle(Geom_Curve) toto;
1182 return toto;
1183 }
1184 gp_Pln pp = P->Pln();
1185 gp_Dir Normale(pp.Position().XDirection()^pp.Position().YDirection());
1186 gp_Ax1 theAx(bar, Normale);
1187 Handle(Geom_Line) theLin = new Geom_Line(theAx);
1188 return theLin;
1189 }
1190
1191