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