0032781: Coding - get rid of unused headers [BRepCheck to ChFiKPart]
[occt.git] / src / BRepFeat / BRepFeat_MakePrism.cxx
1 // Created on: 1996-02-13
2 // Created by: Jacques GOUSSARD
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 <BRepAlgoAPI_Cut.hxx>
20 #include <BRepAlgoAPI_Fuse.hxx>
21 #include <BRepBndLib.hxx>
22 #include <BRepFeat.hxx>
23 #include <BRepFeat_MakePrism.hxx>
24 #include <BRepLib_MakeFace.hxx>
25 #include <BRepPrimAPI_MakeBox.hxx>
26 #include <BRepTools.hxx>
27 #include <Geom_Curve.hxx>
28 #include <Geom_Line.hxx>
29 #include <Geom_Plane.hxx>
30 #include <Geom_RectangularTrimmedSurface.hxx>
31 #include <Geom_Surface.hxx>
32 #include <gp_Ax1.hxx>
33 #include <gp_Dir.hxx>
34 #include <gp_Pln.hxx>
35 #include <gp_Pnt.hxx>
36 #include <gp_Vec.hxx>
37 #include <LocOpe.hxx>
38 #include <LocOpe_CSIntersector.hxx>
39 #include <LocOpe_PntFace.hxx>
40 #include <LocOpe_Prism.hxx>
41 #include <Precision.hxx>
42 #include <Standard_ConstructionError.hxx>
43 #include <TColGeom_SequenceOfCurve.hxx>
44 #include <TColgp_SequenceOfPnt.hxx>
45 #include <TopExp_Explorer.hxx>
46 #include <TopoDS.hxx>
47 #include <TopoDS_Edge.hxx>
48 #include <TopoDS_Face.hxx>
49 #include <TopoDS_Shape.hxx>
50 #include <TopoDS_Solid.hxx>
51 #include <TopTools_ListOfShape.hxx>
52
53 #ifdef OCCT_DEBUG
54 extern Standard_Boolean BRepFeat_GettraceFEAT();
55 #endif
56
57 static void MajMap(const TopoDS_Shape&, // base
58                    const LocOpe_Prism&,
59                    TopTools_DataMapOfShapeListOfShape&, // myMap
60                    TopoDS_Shape&,  // myFShape
61                    TopoDS_Shape&); // myLShape
62
63 static Standard_Boolean ToFuse(const TopoDS_Face& ,
64                                const TopoDS_Face&);
65
66 static Standard_Real HeightMax(const TopoDS_Shape& theSbase,
67                                const TopoDS_Face& theSkface,
68                                const TopoDS_Shape& theSFrom,
69                                const TopoDS_Shape& theSUntil);
70
71 static Standard_Integer SensOfPrism(const Handle(Geom_Curve) C,
72                                     const TopoDS_Shape& Until);
73
74 static Handle(Geom_Curve) TestCurve(const TopoDS_Shape&,
75                                     const gp_Vec&);
76
77
78 //=======================================================================
79 //function : Init
80 //purpose  : 
81 //=======================================================================
82
83 void BRepFeat_MakePrism::Init(const TopoDS_Shape& Sbase,
84                               const TopoDS_Shape& Pbase,
85                               const TopoDS_Face& Skface,
86                               const gp_Dir& Direc,
87                               const Standard_Integer Mode,
88                               const Standard_Boolean Modify)
89 {
90 #ifdef OCCT_DEBUG
91   Standard_Boolean trc = BRepFeat_GettraceFEAT();
92   if (trc) std::cout << "BRepFeat_MakePrism::Init" << std::endl;
93 #endif
94   mySkface = Skface;
95   SketchFaceValid();
96   mySbase  = Sbase;
97   BasisShapeValid();
98   myPbase  = Pbase;
99   mySlface.Clear();
100   myDir    = Direc;
101   if(Mode == 0) {
102     myFuse   = Standard_False;
103     myJustFeat = Standard_False;
104   }
105   else if(Mode == 1) {
106     myFuse   = Standard_True;
107     myJustFeat = Standard_False;
108   }
109   else if(Mode == 2) {
110     myFuse   = Standard_True;
111     myJustFeat = Standard_True;
112   }
113   else {    
114   }
115   myModify = Modify;
116   myJustGluer = Standard_False;
117
118
119   //-------------- ifv
120   //mySkface.Nullify();
121   //-------------- ifv
122
123
124   myShape.Nullify();
125   myNewEdges.Clear();
126   myTgtEdges.Clear();
127   myMap.Clear();
128   myFShape.Nullify();
129   myLShape.Nullify();
130   TopExp_Explorer exp;
131   for (exp.Init(mySbase,TopAbs_FACE);exp.More();exp.Next()) {
132     TopTools_ListOfShape thelist;
133     myMap.Bind(exp.Current(), thelist);
134     myMap(exp.Current()).Append(exp.Current());
135   }
136 #ifdef OCCT_DEBUG
137   if (trc) {
138     if (myJustFeat)  std::cout << " Just Feature" << std::endl;
139     if (myFuse)  std::cout << " Fuse" << std::endl;
140     if (!myFuse)  std::cout << " Cut" << std::endl;
141     if (!myModify) std::cout << " Modify = 0" << std::endl;
142   }
143 #endif 
144 }
145
146
147 //=======================================================================
148 //function : Add
149 //purpose  : add elements of sliding (edge on face)
150 //=======================================================================
151
152 void BRepFeat_MakePrism::Add(const TopoDS_Edge& E,
153                              const TopoDS_Face& F)
154 {
155 #ifdef OCCT_DEBUG
156   Standard_Boolean trc = BRepFeat_GettraceFEAT();
157   if (trc) std::cout << "BRepFeat_MakePrism::Add(Edge,face)" << std::endl;
158 #endif
159   TopExp_Explorer exp;
160   for (exp.Init(mySbase,TopAbs_FACE);exp.More();exp.Next()) {
161     if (exp.Current().IsSame(F)) {
162       break;
163     }
164   }
165   if (!exp.More()) {
166     throw Standard_ConstructionError();
167   }
168   
169   for (exp.Init(myPbase,TopAbs_EDGE);exp.More();exp.Next()) {
170     if (exp.Current().IsSame(E)) {
171       break;
172     }
173   }
174   if (!exp.More()) {
175     throw Standard_ConstructionError();
176   }
177   
178   if (!mySlface.IsBound(F)) {
179     TopTools_ListOfShape thelist1;
180     mySlface.Bind(F, thelist1);
181   }
182   TopTools_ListIteratorOfListOfShape itl(mySlface(F));
183   for (; itl.More();itl.Next()) {
184     if (itl.Value().IsSame(E)) {
185       break;
186     }
187   }
188   if (!itl.More()) {
189     mySlface(F).Append(E);
190   }
191 }
192
193
194 //=======================================================================
195 //function : Perform
196 //purpose  : construction of prism of length Length and 
197 //           call of reconstruction topo
198 //=======================================================================
199
200 void BRepFeat_MakePrism::Perform(const Standard_Real Length)
201 {
202 #ifdef OCCT_DEBUG
203   Standard_Boolean trc = BRepFeat_GettraceFEAT();
204   if (trc) std::cout << "BRepFeat_MakePrism::Perform(Length)" << std::endl;
205 #endif
206   mySFrom.Nullify();
207   ShapeFromValid();
208   mySUntil.Nullify();
209   ShapeUntilValid();
210   myGluedF.Clear();
211   myPerfSelection = BRepFeat_NoSelection;
212   PerfSelectionValid();
213   gp_Vec V(Length*myDir);
214   
215 //construction of prism of height Length
216
217   LocOpe_Prism thePrism(myPbase,V);
218   TopoDS_Shape VraiPrism = thePrism.Shape();
219   
220 // management of descendants
221   MajMap(myPbase,thePrism,myMap,myFShape,myLShape);
222   
223
224   myGShape = VraiPrism;    // the primitive
225   GeneratedShapeValid();
226   
227   TopoDS_Face FFace;
228   
229   Standard_Boolean found = Standard_False;
230
231 // try to detect the faces of gluing 
232 // in case if the top of the prism is tangent to the initial shape
233
234   if(!mySkface.IsNull() || !mySlface.IsEmpty()) {
235     if(myLShape.ShapeType() == TopAbs_WIRE) {
236       TopExp_Explorer ex1(VraiPrism, TopAbs_FACE);
237       for(; ex1.More(); ex1.Next()) {
238         TopExp_Explorer ex2(ex1.Current(), TopAbs_WIRE);
239         for(; ex2.More(); ex2.Next()) {
240           if(ex2.Current().IsSame(myLShape)) {
241             FFace = TopoDS::Face(ex1.Current());
242             found = Standard_True;
243             break;
244           }
245         }
246         if(found) break;
247       }
248     }
249     
250     TopExp_Explorer exp(mySbase, TopAbs_FACE);
251     for(; exp.More(); exp.Next()) {
252       const TopoDS_Face& ff = TopoDS::Face(exp.Current());
253       if(ToFuse(ff, FFace)) {
254         TopTools_DataMapOfShapeListOfShape sl;
255         if(!FFace.IsSame(myPbase) && BRepFeat::IsInside(ff, FFace)) 
256           break;
257       }
258     }
259   }
260
261 // management of faces of gluing given by the user
262
263   GluedFacesValid();
264
265   if(!myGluedF.IsEmpty()) {   // case gluing
266     myJustGluer = Standard_True;
267     thePrism.Curves(myCurves);
268     myBCurve = thePrism.BarycCurve();    
269     GlobalPerform();  // topological reconstruction 
270   }
271
272 // if there is no gluing  -> call of ope topo
273   if(!myJustGluer) {
274     if(myFuse == 1 && !myJustFeat) {
275       BRepAlgoAPI_Fuse f(mySbase, myGShape);
276       myShape = f.Shape();
277       UpdateDescendants(f, myShape, Standard_False);
278       Done();
279     }
280     else if(myFuse == 0) {
281       BRepAlgoAPI_Cut c(mySbase, myGShape);
282       myShape = c.Shape();
283       UpdateDescendants(c, myShape, Standard_False);
284       Done();
285     }
286     else {
287       myShape = myGShape;
288       Done();
289     }
290   }
291 }
292
293
294 //=======================================================================
295 //function : Perform
296 //purpose  : construction of prism oriented at the face Until, sufficiently 
297 //           long; call of topological reconstruction          
298 //=======================================================================
299
300 void BRepFeat_MakePrism::Perform(const TopoDS_Shape& Until)
301 {
302 #ifdef OCCT_DEBUG
303   Standard_Boolean trc = BRepFeat_GettraceFEAT();
304   if (trc) std::cout << "BRepFeat_MakePrism::Perform(Until)" << std::endl;
305 #endif
306   if (Until.IsNull()) {
307     throw Standard_ConstructionError();
308   }
309   TopExp_Explorer exp(Until, TopAbs_FACE);
310   if (!exp.More()) {
311     throw Standard_ConstructionError();
312   }
313   myGluedF.Clear();
314   myPerfSelection = BRepFeat_SelectionU;
315   PerfSelectionValid();
316   mySFrom.Nullify();
317   ShapeFromValid();
318   mySUntil = Until;
319   Standard_Boolean Trf = TransformShapeFU(1);  
320   ShapeUntilValid();
321   Handle(Geom_Curve) C = TestCurve(myPbase,myDir);  
322   Standard_Integer sens = SensOfPrism(C, mySUntil);
323   Standard_Real Height = HeightMax(mySbase, mySkface, mySFrom, mySUntil);
324   gp_Vec V(2*sens*Height*myDir);
325
326 // construction of long prism
327   LocOpe_Prism thePrism(myPbase,V);
328   TopoDS_Shape VraiPrism = thePrism.Shape();
329
330 // in case of support of face Until
331   if(!Trf) {    
332     MajMap(myPbase,thePrism,myMap,myFShape,myLShape);    
333     myGShape = VraiPrism;
334     GeneratedShapeValid();
335     GluedFacesValid();
336     thePrism.Curves(myCurves);
337     myBCurve = thePrism.BarycCurve();
338     GlobalPerform();
339   }
340   else {    // until support -> passage to topological operations
341     MajMap(myPbase,thePrism,myMap,myFShape,myLShape);    
342     TColGeom_SequenceOfCurve scur;
343     scur.Clear();    
344     scur.Append(C);
345
346 // direction of the prism depending on Until
347
348     LocOpe_CSIntersector ASI(mySUntil);
349     ASI.Perform(scur);
350     TopAbs_Orientation Or;
351     if (ASI.IsDone() && ASI.NbPoints(1) >=1) {
352       if (myFuse == 1) {
353         Or = ASI.Point(1, 1).Orientation();
354       }
355       else {
356         Or = ASI.Point(1, ASI.NbPoints(1)).Orientation();
357       }
358       if(sens==-1) Or=TopAbs::Reverse(Or);
359       TopoDS_Face FUntil = ASI.Point(1,1).Face();
360       TopoDS_Shape Comp;
361       BRep_Builder B;
362       B.MakeCompound(TopoDS::Compound(Comp));
363       TopoDS_Solid S = BRepFeat::Tool(mySUntil, FUntil, Or);
364       if (!S.IsNull()) B.Add(Comp,S);
365       BRepAlgoAPI_Cut trP(VraiPrism,Comp);
366       UpdateDescendants(trP, trP.Shape(), Standard_False);
367       //
368       TopExp_Explorer ex(trP.Shape(), TopAbs_SOLID);
369       TopoDS_Shape Cutsh = ex.Current();
370       if (myFuse == 1 && !myJustFeat) {
371         BRepAlgoAPI_Fuse f(mySbase, Cutsh);
372         myShape = f.Shape();
373         UpdateDescendants(f, myShape, Standard_False);
374         Done();
375       }
376       else if(myFuse == 0) {
377         BRepAlgoAPI_Cut c(mySbase, Cutsh);
378         myShape = c.Shape();
379         UpdateDescendants(c, myShape, Standard_False);
380         Done();
381       }
382       else {
383         myShape = Cutsh;
384         Done();
385       }
386     }
387   }
388 }
389
390 //=======================================================================
391 //function : Perform
392 //purpose  : construction of a sufficiently long and properly oriented prism
393 //           call of topological reconstruction
394 //=======================================================================
395
396 void BRepFeat_MakePrism::Perform(const TopoDS_Shape& From,
397                                  const TopoDS_Shape& Until)
398 {
399 #ifdef OCCT_DEBUG
400   Standard_Boolean trc = BRepFeat_GettraceFEAT();
401   if (trc) std::cout << "BRepFeat_MakePrism::Perform(From,Until)" << std::endl;
402 #endif
403   if (From.IsNull() || Until.IsNull()) {
404     throw Standard_ConstructionError();
405   }
406
407   if (!mySkface.IsNull()) {
408     if (From.IsSame(mySkface)) {
409       myJustGluer = Standard_True;
410       Perform(Until);
411       if (myJustGluer) return;
412     }
413     else if (Until.IsSame(mySkface)) {
414       myJustGluer = Standard_True;
415       Perform(From);
416       if (myJustGluer) return;
417     } 
418   }
419   
420   myGluedF.Clear();
421   myPerfSelection = BRepFeat_SelectionFU;
422   PerfSelectionValid();
423   
424   TopExp_Explorer exp(From, TopAbs_FACE);
425   if (!exp.More()) {
426     throw Standard_ConstructionError();
427   }
428   exp.Init(Until, TopAbs_FACE);
429   if (!exp.More()) {
430     throw Standard_ConstructionError();
431   }
432   mySFrom = From;
433   Standard_Boolean Trff = TransformShapeFU(0);
434   ShapeFromValid();
435   mySUntil = Until;
436   Standard_Boolean Trfu = TransformShapeFU(1);
437   ShapeUntilValid();  
438   if(Trfu != Trff) {
439     NotDone();
440     myStatusError = BRepFeat_IncTypes;
441     return;
442   }
443
444 // length depending on bounding boxes
445
446   Standard_Real Height = HeightMax(mySbase, mySkface, mySFrom, mySUntil);
447   Handle(Geom_Curve) C = TestCurve(myPbase,myDir);  
448   Standard_Integer sens;  // direction of prism
449   Standard_Integer tran;  // transfer of prism
450   if(From.IsSame(Until)) {
451     sens = 1;
452     tran = -1;
453   }
454   else {
455     sens = SensOfPrism(C, mySUntil);
456     tran = sens*SensOfPrism(C, mySFrom);
457   }
458   LocOpe_Prism thePrism;   
459   if(tran < 0) {
460     gp_Vec Vtra(-3*Height*sens/2.*myDir);
461     thePrism.Perform(myPbase,3*sens*Height*myDir,Vtra);
462   }
463   else {
464     thePrism.Perform(myPbase,2*sens*Height*myDir);
465   }
466   TopoDS_Shape VraiPrism = thePrism.Shape();
467   
468   if(!Trff) {
469     MajMap(myPbase,thePrism,myMap,myFShape,myLShape);
470     
471     myGShape = VraiPrism;
472     GeneratedShapeValid();
473     GluedFacesValid();
474     thePrism.Curves(myCurves);
475     myBCurve = thePrism.BarycCurve();
476     GlobalPerform();
477   }
478   else {    // case until support -> topological operation
479     MajMap(myPbase,thePrism,myMap,myFShape,myLShape);    
480     TColGeom_SequenceOfCurve scur;
481     scur.Clear();    
482     scur.Append(C);
483     LocOpe_CSIntersector ASI1(mySUntil);
484     LocOpe_CSIntersector ASI2(mySFrom);
485     ASI1.Perform(scur);
486     ASI2.Perform(scur);
487     TopAbs_Orientation OrU, OrF;
488     TopoDS_Face FFrom, FUntil;
489     Standard_Real ParF, ParU;
490     if (ASI1.IsDone() && ASI1.NbPoints(1) >=1) {
491       if (myFuse == 1) {
492               OrU = ASI1.Point(1,1).Orientation();
493       }
494       else {
495               OrU = ASI1.Point(1,ASI1.NbPoints(1)).Orientation();
496       }
497       if(sens==-1) OrU = TopAbs::Reverse(OrU);
498       FUntil = ASI1.Point(1,1).Face();
499       ParU = ASI1.Point(1,1).Parameter();
500     }
501     else {
502       NotDone();
503       myStatusError = BRepFeat_NoIntersectU;
504       return;
505     }
506     if (ASI2.IsDone() && ASI2.NbPoints(1) >=1) {
507       OrF = ASI2.Point(1,1).Orientation();
508       if(sens==1) OrF = TopAbs::Reverse(OrF);
509       FFrom = ASI2.Point(1,1).Face();
510       ParF = ASI2.Point(1,1).Parameter();
511     }
512     else {
513       NotDone();
514       myStatusError = BRepFeat_NoIntersectF;
515       return;
516     }
517     if(tran > 0 && (Abs(ParU) < Abs(ParF)))
518     {
519       TopAbs_Orientation Or;
520       Or = OrU;
521       OrU = OrF;
522       OrF = Or;
523     }
524     //
525     TopTools_ListOfShape aLTools;
526     TopoDS_Solid S = BRepFeat::Tool(mySUntil, FUntil, OrU);
527     if (!S.IsNull()) {
528       aLTools.Append(S);
529     }
530     else {
531       NotDone();
532       myStatusError = BRepFeat_NullToolU;
533       return;
534     }
535     TopoDS_Solid SS = BRepFeat::Tool(mySFrom, FFrom, OrF);
536     if (!SS.IsNull()) {
537       aLTools.Append(SS);
538     }
539     else {
540       NotDone();
541       myStatusError = BRepFeat_NullToolF;
542       return;
543     }
544     //
545     TopTools_ListOfShape aLObj;
546     aLObj.Append(VraiPrism);
547     //
548     BRepAlgoAPI_Cut trP;
549     trP.SetArguments(aLObj);
550     trP.SetTools(aLTools);
551     trP.Build();
552     UpdateDescendants(trP, trP.Shape(), Standard_False);
553     if(myFuse == 1 && !myJustFeat) {
554       BRepAlgoAPI_Fuse f(mySbase, trP.Shape());
555       myShape = f.Shape();
556       UpdateDescendants(f, myShape, Standard_False);
557       Done();
558     }
559     else if(myFuse == 0) {
560       BRepAlgoAPI_Cut c(mySbase, trP.Shape());
561       myShape = c.Shape();
562       UpdateDescendants(c, myShape, Standard_False);
563       Done();
564     }
565     else {
566       myShape = trP.Shape();
567       Done();
568     }
569   }
570 }
571
572 //=======================================================================
573 //function : PerformUntilEnd
574 //purpose  : construction of a prism and reconstruction
575 //=======================================================================
576
577 void BRepFeat_MakePrism::PerformUntilEnd()
578 {
579 #ifdef OCCT_DEBUG
580   Standard_Boolean trc = BRepFeat_GettraceFEAT();
581   if (trc) std::cout << "BRepFeat_MakePrism::PerformUntilEnd()" << std::endl;
582 #endif
583   myPerfSelection = BRepFeat_SelectionSh;
584   PerfSelectionValid();
585   myGluedF.Clear();
586   mySUntil.Nullify();
587   ShapeUntilValid();
588   mySFrom.Nullify();
589   ShapeFromValid();
590   Standard_Real Height = HeightMax(mySbase, mySkface, mySFrom, mySUntil);
591   gp_Vec V(2*Height*myDir);
592   
593   LocOpe_Prism thePrism(myPbase,V);
594   TopoDS_Shape VraiPrism = thePrism.Shape();
595   
596   MajMap(myPbase,thePrism,myMap,myFShape,myLShape);
597   
598   myGShape = VraiPrism;
599   GeneratedShapeValid();
600   GluedFacesValid();
601
602   if(myFuse == 0) {
603     BRepAlgoAPI_Cut c(mySbase, myGShape);
604     if (c.IsDone()) {
605       myShape = c.Shape();
606       UpdateDescendants(c, myShape, Standard_False);
607       Done();
608     }
609   }
610   else {
611     thePrism.Curves(myCurves);
612     myBCurve = thePrism.BarycCurve();
613     GlobalPerform();
614   }
615 }
616
617 //=======================================================================
618 //function : PerformFromEnd
619 //purpose  : 
620 //=======================================================================
621
622 void BRepFeat_MakePrism::PerformFromEnd(const TopoDS_Shape& Until)
623 {
624 #ifdef OCCT_DEBUG
625   Standard_Boolean trc = BRepFeat_GettraceFEAT();
626   if (trc) std::cout << "BRepFeat_MakePrism::PerformFromEnd(From,Until)" << std::endl;
627 #endif
628   if (Until.IsNull()) {
629     throw Standard_ConstructionError();
630   }
631   if (!mySkface.IsNull() && Until.IsSame(mySkface)) {
632     myDir.Reverse();
633     PerformUntilEnd();
634     return;
635   }
636   TopExp_Explorer exp;
637   exp.Init(Until, TopAbs_FACE);
638   if (!exp.More()) {
639     throw Standard_ConstructionError();
640   }
641   myPerfSelection = BRepFeat_SelectionShU;
642   PerfSelectionValid();
643   mySFrom.Nullify();
644   ShapeFromValid();
645   mySUntil = Until;
646   Standard_Boolean Trf = TransformShapeFU(1);
647   ShapeUntilValid();
648   Handle(Geom_Curve) C = TestCurve(myPbase,myDir);  
649   Standard_Integer sens = SensOfPrism(C, mySUntil);
650   Standard_Real Height = HeightMax(mySbase, mySkface, mySFrom, mySUntil);
651   gp_Vec Vtra(-3*Height*sens/2.*myDir);
652   gp_Vec Vect(3*sens*Height*myDir);
653   LocOpe_Prism thePrism(myPbase,Vect,Vtra);
654   TopoDS_Shape VraiPrism = thePrism.Shape();
655   
656   if(!Trf) {  // case face until 
657     MajMap(myPbase,thePrism,myMap,myFShape,myLShape);
658     myGShape = VraiPrism;
659     GeneratedShapeValid();
660     myGluedF.Clear();
661     GluedFacesValid();
662     thePrism.Curves(myCurves);
663     myBCurve = thePrism.BarycCurve();
664     GlobalPerform();
665   }
666   else {   // case support
667     MajMap(myPbase,thePrism,myMap,myFShape,myLShape);    
668     TColGeom_SequenceOfCurve scur;
669     scur.Clear();    
670     scur.Append(C);
671     LocOpe_CSIntersector ASI1(mySUntil);
672     LocOpe_CSIntersector ASI2(mySbase);
673     ASI1.Perform(scur);
674     ASI2.Perform(scur);
675     TopAbs_Orientation OrU = TopAbs_FORWARD, OrF = TopAbs_FORWARD;
676     TopoDS_Face FUntil, FFrom;
677     if (ASI1.IsDone() && ASI1.NbPoints(1) >=1) {
678       OrU = ASI1.Point(1,1).Orientation();
679       if(sens==-1) {
680         OrU = TopAbs::Reverse(OrU);
681       }
682       FUntil = ASI1.Point(1,1).Face();
683     }
684     if (ASI2.IsDone() && ASI2.NbPoints(1) >=1) {
685       OrF = ASI2.Point(1,1).Orientation();
686 //      if(sens==1) OrF = TopAbs::Reverse(OrF);
687       FFrom = ASI2.Point(1 ,1).Face();
688       Handle(Geom_Surface) S = BRep_Tool::Surface(FFrom);
689       if (S->DynamicType() == 
690           STANDARD_TYPE(Geom_RectangularTrimmedSurface)) {
691         S = Handle(Geom_RectangularTrimmedSurface)::
692           DownCast(S)->BasisSurface();
693       }
694       BRepLib_MakeFace fac(S, Precision::Confusion());
695       mySFrom = fac.Face();  
696       Trf = TransformShapeFU(0);
697       FFrom = TopoDS::Face(mySFrom);
698     }
699
700     TopTools_ListOfShape aLTools;
701     TopoDS_Solid Sol = BRepFeat::Tool(mySUntil, FUntil, OrU);
702     if (!Sol.IsNull()) {
703       aLTools.Append(Sol);
704     }
705     else {
706       NotDone();
707       myStatusError = BRepFeat_NullToolU;
708       return;
709     }
710
711     TopoDS_Solid Sol1 = BRepFeat::Tool(mySFrom, FFrom, OrF);
712     if (!Sol1.IsNull()) {
713       aLTools.Append(Sol1);
714     }
715     else {
716       NotDone();
717       myStatusError = BRepFeat_NullToolF;
718       return;
719     }
720     //
721     TopTools_ListOfShape aLObj;
722     aLObj.Append(VraiPrism);
723     //
724     BRepAlgoAPI_Cut trP;
725     trP.SetArguments(aLObj);
726     trP.SetTools(aLTools);
727     trP.Build();
728     //
729     UpdateDescendants(trP, trP.Shape(), Standard_False);
730     if(myFuse == 1 && !myJustFeat) {
731       BRepAlgoAPI_Fuse f(mySbase, trP.Shape());
732       myShape = f.Shape();
733       UpdateDescendants(f, myShape, Standard_False);
734       Done();
735     }
736     else if(myFuse == 0) {
737       BRepAlgoAPI_Cut c(mySbase, trP.Shape());
738       myShape = c.Shape();
739       UpdateDescendants(c, myShape, Standard_False);
740       Done();
741     }
742     else {
743       myShape = trP.Shape();
744       Done();
745     }
746   }
747 }
748
749 //=======================================================================
750 //function : PerformThruAll
751 //purpose  : 
752 //=======================================================================
753
754 void BRepFeat_MakePrism::PerformThruAll()
755 {
756 #ifdef OCCT_DEBUG
757   Standard_Boolean trc = BRepFeat_GettraceFEAT();
758   if (trc) std::cout << "BRepFeat_MakePrism::PerformThruAll()" << std::endl;
759 #endif
760   mySUntil.Nullify();
761   ShapeUntilValid();
762   mySFrom.Nullify();
763   ShapeFromValid();
764   if(myFuse == 0) {
765     myPerfSelection = BRepFeat_NoSelection;
766   }
767   else {
768     myPerfSelection = BRepFeat_SelectionSh;
769   }
770   PerfSelectionValid();
771   myGluedF.Clear();
772   GluedFacesValid();
773
774   Standard_Real Height = HeightMax(mySbase, mySkface, mySFrom, mySUntil);
775   gp_Vec V(3*Height*myDir);
776   gp_Vec Vtra(-3*Height/2.*myDir);
777   LocOpe_Prism thePrism(myPbase,V,Vtra);
778   TopoDS_Shape VraiPrism = thePrism.Shape();
779   MajMap(myPbase,thePrism,myMap,myFShape,myLShape);
780
781   myGShape = VraiPrism;
782   GeneratedShapeValid();  
783
784   if(myFuse == 0) {
785     BRepAlgoAPI_Cut c(mySbase, myGShape);
786     if (c.IsDone()) {
787       myShape = c.Shape();
788       UpdateDescendants(c, myShape, Standard_False);
789       Done();
790     }
791   }
792   else {
793     thePrism.Curves(myCurves);
794     myBCurve = thePrism.BarycCurve();
795     GlobalPerform();
796   }
797 }
798
799 //=======================================================================
800 //function : PerformUntilHauteur
801 //purpose  : 
802 //=======================================================================
803
804 void BRepFeat_MakePrism::PerformUntilHeight(const TopoDS_Shape& Until,
805                                             const Standard_Real Length)
806 {
807 #ifdef OCCT_DEBUG
808   Standard_Boolean trc = BRepFeat_GettraceFEAT();
809   if (trc) std::cout << "BRepFeat_MakePrism::PerformUntilHeight(Until,Length)" << std::endl;
810 #endif
811   if (Until.IsNull()) {
812     Perform(Length);
813   }
814   if(Length == 0) {
815     Perform(Until);
816   }
817   TopExp_Explorer exp(Until, TopAbs_FACE);
818   if (!exp.More()) {
819     throw Standard_ConstructionError();
820   }
821   myGluedF.Clear();
822   myPerfSelection = BRepFeat_NoSelection;
823   PerfSelectionValid();
824   mySFrom.Nullify();
825   ShapeFromValid();
826   mySUntil = Until;
827   Standard_Boolean Trf = TransformShapeFU(1);
828   ShapeUntilValid();
829   Handle(Geom_Curve) C = TestCurve(myPbase,myDir);  
830   Standard_Integer sens = SensOfPrism(C, mySUntil);
831   gp_Vec V(sens*Length*myDir);
832   LocOpe_Prism thePrism(myPbase,V);
833   TopoDS_Shape VraiPrism = thePrism.Shape();
834
835   if(!Trf) {
836     MajMap(myPbase,thePrism,myMap,myFShape,myLShape);
837     
838     myGShape = VraiPrism;
839     GeneratedShapeValid();
840     GluedFacesValid();
841     thePrism.Curves(myCurves);
842     myBCurve = thePrism.BarycCurve();
843     GlobalPerform();
844   }
845   else {
846     MajMap(myPbase,thePrism,myMap,myFShape,myLShape);    
847     TColGeom_SequenceOfCurve scur;
848     scur.Clear();    
849     scur.Append(C);
850     LocOpe_CSIntersector ASI(mySUntil);
851     ASI.Perform(scur);
852     TopAbs_Orientation Or;
853     if (ASI.IsDone() && ASI.NbPoints(1) >=1) {
854       if (myFuse == 1) {
855         Or = ASI.Point(1,1).Orientation();
856       }
857       else {
858         Or = ASI.Point(1,ASI.NbPoints(1)).Orientation();
859       }
860       if(sens==-1) Or=TopAbs::Reverse(Or);
861       TopoDS_Face FUntil = ASI.Point(1,1).Face();
862       TopoDS_Shape Comp;
863       BRep_Builder B;
864       B.MakeCompound(TopoDS::Compound(Comp));
865       TopoDS_Solid S = BRepFeat::Tool(mySUntil, FUntil, Or);
866       if (!S.IsNull()) B.Add(Comp,S);
867
868       BRepAlgoAPI_Cut trP(VraiPrism,Comp);
869       UpdateDescendants(trP, trP.Shape(), Standard_False);
870       if(myFuse == 1 && !myJustFeat) {
871         BRepAlgoAPI_Fuse f(mySbase, trP.Shape());
872         myShape = f.Shape();
873         UpdateDescendants(f, myShape, Standard_False);
874         Done();
875       }
876       else if(myFuse == 0) {
877         BRepAlgoAPI_Cut c(mySbase, trP.Shape());
878         myShape = c.Shape();
879         UpdateDescendants(c, myShape, Standard_False);
880         Done();
881       }
882       else {
883         myShape = trP.Shape();
884         Done();
885       }
886     }
887   }
888 }
889
890 //=======================================================================
891 //function : Curves
892 //purpose  : sequence of curves parallel to the axis of prism 
893 //=======================================================================
894
895 void BRepFeat_MakePrism::Curves(TColGeom_SequenceOfCurve& scur)
896 {
897   scur = myCurves;
898 }
899
900 //=======================================================================
901 //function : BarycCurve
902 //purpose  : curve parallel to the axis of the prism passing through the center  
903 //           of masses
904 //=======================================================================
905
906 Handle(Geom_Curve) BRepFeat_MakePrism::BarycCurve()
907 {
908   return myBCurve;
909 }
910
911
912 //=======================================================================
913 //function : HeightMax
914 //purpose  : Calculate the height of the prism following the parameters of
915 //           bounding box
916 //=======================================================================
917
918 static Standard_Real HeightMax(const TopoDS_Shape& theSbase,
919                                const TopoDS_Face&  theSkface,
920                                const TopoDS_Shape& theSFrom,
921                                const TopoDS_Shape& theSUntil)
922 {
923   Bnd_Box Box;
924   BRepBndLib::Add(theSbase,Box);
925   BRepBndLib::Add(theSkface,Box);
926   if(!theSFrom.IsNull()) {
927     Standard_Boolean FacRevolInfini = Standard_False;
928     TopExp_Explorer exp;
929     exp.Init(theSFrom, TopAbs_EDGE);
930     for(; exp.More(); exp.Next()) {
931       TopExp_Explorer exp1;
932       exp1.Init(exp.Current(), TopAbs_VERTEX);
933       if(!exp1.More()) {
934         FacRevolInfini = Standard_True;
935         break;
936       }
937     }
938     if(!FacRevolInfini)
939       BRepBndLib::Add(theSFrom,Box);
940   }
941   if(!theSUntil.IsNull()) 
942   {
943     Standard_Boolean FacRevolInfini = Standard_False;
944     TopExp_Explorer exp;
945     exp.Init(theSUntil, TopAbs_EDGE);
946     for(; exp.More(); exp.Next()) 
947     {
948       TopExp_Explorer exp1;
949       exp1.Init(exp.Current(), TopAbs_VERTEX);
950       if(!exp1.More()) 
951       {
952         FacRevolInfini = Standard_True;
953         break;
954       }
955     }
956     if(!FacRevolInfini)
957       BRepBndLib::Add(theSUntil,Box);
958   }
959
960   Standard_Real c[6];
961
962   Box.Get(c[0],c[2],c[4],c[1],c[3],c[5]);
963   Standard_Real parmin=c[0], parmax = c[0];
964   for(Standard_Integer i = 0 ; i < 6; i++) {
965     if(c[i] > parmax) parmax = c[i];
966     if(c[i] < parmin ) parmin = c[i];    
967   }
968 //#ifndef OCCT_DEBUG
969   Standard_Real Height = fabs(2.*(parmax - parmin));
970 //#else
971 //  Standard_Real Height = abs(2.*(parmax - parmin));
972 //#endif
973   return(Height);
974 }
975
976
977 //=======================================================================
978 //function : SensOfPrism
979 //purpose  : Direction of the prism depending on the shape Until
980 //=======================================================================
981 Standard_Integer SensOfPrism(const Handle(Geom_Curve) C,
982                              const TopoDS_Shape& Until)
983 {
984   LocOpe_CSIntersector ASI1(Until);
985   TColGeom_SequenceOfCurve scur;
986   scur.Append(C);
987   ASI1.Perform(scur);
988   Standard_Integer sens = 1;
989   if(ASI1.IsDone() && ASI1.NbPoints(1) >= 1) {
990     if(ASI1.Point(1, 1).Parameter() < 0. && 
991        ASI1.Point(1, ASI1.NbPoints(1)).Parameter() < 0.) {
992       sens = -1;
993     }
994   }
995   else if(BRepFeat::ParametricBarycenter(Until,C) < 0) {
996       sens = -1;
997   }
998   else {}
999   return sens;
1000 }
1001
1002 //=======================================================================
1003 //function : MajMap
1004 //purpose  : management of descendants
1005 //=======================================================================
1006
1007 static void MajMap(const TopoDS_Shape& theB,
1008                    const LocOpe_Prism& theP,
1009                    TopTools_DataMapOfShapeListOfShape& theMap, // myMap
1010                    TopoDS_Shape& theFShape,  // myFShape
1011                    TopoDS_Shape& theLShape) // myLShape
1012 {
1013   TopExp_Explorer exp(theP.FirstShape(),TopAbs_WIRE);
1014   if (exp.More()) {
1015     theFShape = exp.Current();
1016     TopTools_ListOfShape thelist2;
1017     theMap.Bind(theFShape, thelist2);
1018     for (exp.Init(theP.FirstShape(),TopAbs_FACE);exp.More();exp.Next()) {
1019       theMap(theFShape).Append(exp.Current());
1020     }
1021   }
1022   
1023   exp.Init(theP.LastShape(),TopAbs_WIRE);
1024   if (exp.More()) {
1025     theLShape = exp.Current();
1026     TopTools_ListOfShape thelist3;
1027     theMap.Bind(theLShape, thelist3);
1028     for (exp.Init(theP.LastShape(),TopAbs_FACE);exp.More();exp.Next()) {
1029       theMap(theLShape).Append(exp.Current());
1030     }
1031   }
1032
1033   for (exp.Init(theB,TopAbs_EDGE); exp.More(); exp.Next()) {
1034     if (!theMap.IsBound(exp.Current())) {
1035       TopTools_ListOfShape thelist4;
1036       theMap.Bind(exp.Current(), thelist4);
1037       theMap(exp.Current()) = theP.Shapes(exp.Current());
1038     }
1039   }
1040 }
1041
1042
1043 //=======================================================================
1044 //function : MajMap
1045 //purpose  : management of descendants
1046 //=======================================================================
1047
1048 static Handle(Geom_Curve) TestCurve(const TopoDS_Shape& Base,
1049                                     const gp_Vec& V)
1050 {
1051   gp_Pnt bar(0., 0., 0.);
1052   TColgp_SequenceOfPnt spt;
1053   LocOpe::SampleEdges(Base,spt);
1054   for (Standard_Integer jj=1;jj<=spt.Length(); jj++) {
1055     const gp_Pnt& pvt = spt(jj);
1056     bar.ChangeCoord() += pvt.XYZ();
1057   }
1058   bar.ChangeCoord().Divide(spt.Length());
1059   gp_Ax1 newAx(bar,V);
1060   Handle(Geom_Line) theLin = new Geom_Line(newAx);
1061   return theLin;
1062 }
1063
1064
1065
1066
1067 //=======================================================================
1068 //function : ToFuse
1069 //purpose  : face SameDomaine or not
1070 //=======================================================================
1071
1072 static Standard_Boolean ToFuse (const TopoDS_Face& F1, const TopoDS_Face& F2)
1073 {
1074   if (F1.IsNull() || F2.IsNull()) {
1075     return Standard_False;
1076   }
1077
1078   Handle(Geom_Surface) S1,S2;
1079   TopLoc_Location loc1, loc2;
1080   Handle(Standard_Type) typS1,typS2;
1081   const Standard_Real tollin = Precision::Confusion();
1082   const Standard_Real tolang = Precision::Angular();
1083
1084   S1 = BRep_Tool::Surface(F1,loc1);
1085   S2 = BRep_Tool::Surface(F2,loc2);
1086
1087   typS1 = S1->DynamicType();
1088   typS2 = S2->DynamicType();
1089
1090   if (typS1 == STANDARD_TYPE(Geom_RectangularTrimmedSurface)) {
1091     S1 =  Handle(Geom_RectangularTrimmedSurface)::DownCast (S1)->BasisSurface();
1092     typS1 = S1->DynamicType();
1093   }
1094
1095   if (typS2 == STANDARD_TYPE(Geom_RectangularTrimmedSurface)) {
1096     S2 =  Handle(Geom_RectangularTrimmedSurface)::DownCast (S2)->BasisSurface();
1097     typS2 = S2->DynamicType();
1098   }
1099
1100   if (typS1 != typS2) {
1101     return Standard_False;
1102   }
1103
1104
1105   Standard_Boolean ValRet = Standard_False;
1106   if (typS1 == STANDARD_TYPE(Geom_Plane)) {
1107     gp_Pln pl1( Handle(Geom_Plane)::DownCast (S1)->Pln());
1108     gp_Pln pl2( Handle(Geom_Plane)::DownCast (S2)->Pln());
1109
1110     // apply locations
1111     if (! loc1.IsIdentity())
1112       pl1.Transform (loc1.Transformation());
1113     if (! loc2.IsIdentity())
1114       pl2.Transform (loc2.Transformation());
1115
1116     if (pl1.Position().IsCoplanar(pl2.Position(),tollin,tolang)) {
1117       ValRet = Standard_True;
1118     }
1119   }
1120
1121   return ValRet;
1122 }
1123
1124
1125
1126
1127
1128