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