]> SALOME platform Git repositories - modules/geom.git/blob - src/GEOMAlgo/GEOMAlgo_Gluer.cxx
Salome HOME
ad1a7c79c3572cd94cbfc23f056ad4579b97a8aa
[modules/geom.git] / src / GEOMAlgo / GEOMAlgo_Gluer.cxx
1 // File:        GEOMAlgo_Gluer.cxx
2 // Created:     Sat Dec 04 12:45:53 2004
3 // Author:      Peter KURNEV
4 //              <peter@PREFEX>
5
6
7 #include <GEOMAlgo_Gluer.ixx>
8
9 #include <TColStd_ListOfInteger.hxx>
10 #include <TColStd_ListIteratorOfListOfInteger.hxx>
11
12 #include <gp_Pnt.hxx>
13 #include <gp_Dir.hxx>
14
15 #include <Geom_Curve.hxx>
16 #include <Geom_Surface.hxx>
17
18 #include <Bnd_Box.hxx>
19 #include <Bnd_HArray1OfBox.hxx>
20 #include <Bnd_BoundSortBox.hxx>
21 #include <BRepBndLib.hxx>
22
23 #include <TopLoc_Location.hxx>
24 #include <TopAbs_ShapeEnum.hxx>
25 #include <TopAbs_Orientation.hxx>
26
27 #include <TopoDS.hxx>
28 #include <TopoDS_Edge.hxx>
29 #include <TopoDS_Vertex.hxx>
30 #include <TopoDS_Shape.hxx>
31 #include <TopoDS_Compound.hxx>
32 #include <TopoDS_Wire.hxx>
33 #include <TopoDS_Shell.hxx>
34 #include <TopoDS_Solid.hxx>
35
36 #include <TopTools_IndexedMapOfShape.hxx>
37 #include <TopTools_ListOfShape.hxx>
38 #include <TopTools_ListIteratorOfListOfShape.hxx>
39 #include <TopTools_DataMapIteratorOfDataMapOfShapeListOfShape.hxx>
40 #include <TopTools_MapOfShape.hxx>
41 #include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
42
43 #include <TopExp.hxx>
44 #include <TopExp_Explorer.hxx>
45
46 #include <BRep_Tool.hxx>
47 #include <BRep_Builder.hxx>
48
49 #include <IntTools_Context.hxx>
50 #include <BOPTools_Tools.hxx>
51 #include <BOPTools_Tools3D.hxx>
52 #include <BOPTools_Tools2D.hxx>
53
54 #include <GEOMAlgo_IndexedDataMapOfIntegerShape.hxx>
55 #include <GEOMAlgo_IndexedDataMapOfShapeBox.hxx>
56 #include <GEOMAlgo_IndexedDataMapOfPassKeyListOfShape.hxx>
57 #include <GEOMAlgo_PassKey.hxx>
58 #include <GEOMAlgo_Tools.hxx>
59
60 //=======================================================================
61 //function : GEOMAlgo_Gluer
62 //purpose  : 
63 //=======================================================================
64 GEOMAlgo_Gluer::GEOMAlgo_Gluer()
65 :
66   GEOMAlgo_ShapeAlgo()
67 {
68   myTolerance=0.0001;
69   myTol=myTolerance;
70   myCheckGeometry=Standard_True;
71   myTypeResult=TopAbs_SOLID;
72 }
73 //=======================================================================
74 //function : ~GEOMAlgo_Gluer
75 //purpose  : 
76 //=======================================================================
77 GEOMAlgo_Gluer::~GEOMAlgo_Gluer()
78 {
79 }
80 //=======================================================================
81 //function : SetCheckGeometry
82 //purpose  : 
83 //=======================================================================
84 void GEOMAlgo_Gluer::SetCheckGeometry(const Standard_Boolean aFlag)
85 {
86   myCheckGeometry=aFlag;
87 }
88 //=======================================================================
89 //function : CheckGeometry
90 //purpose  : 
91 //=======================================================================
92 Standard_Boolean GEOMAlgo_Gluer::CheckGeometry() const
93 {
94   return myCheckGeometry;
95 }
96
97 //=======================================================================
98 //function : Images
99 //purpose  : 
100 //=======================================================================
101 const TopTools_DataMapOfShapeListOfShape& GEOMAlgo_Gluer::Images()const
102 {
103   return myImages;
104 }
105 //=======================================================================
106 //function : Origins
107 //purpose  : 
108 //=======================================================================
109 const TopTools_DataMapOfShapeShape& GEOMAlgo_Gluer::Origins()const
110 {
111   return myOrigins;
112 }
113 //=======================================================================
114 //function : Perform
115 //purpose  : 
116 //=======================================================================
117 void GEOMAlgo_Gluer::Perform()
118 {
119   myErrorStatus=0;
120   myWarningStatus=0;
121   //
122   Standard_Integer i;
123   const Standard_Integer aNb=9;
124   void (GEOMAlgo_Gluer::* pF[aNb])()={
125     &GEOMAlgo_Gluer::CheckData,       &GEOMAlgo_Gluer::InnerTolerance,
126     &GEOMAlgo_Gluer::MakeVertices,    &GEOMAlgo_Gluer::MakeEdges,
127     &GEOMAlgo_Gluer::MakeFaces,       &GEOMAlgo_Gluer::MakeShells,
128     &GEOMAlgo_Gluer::MakeSolids,      &GEOMAlgo_Gluer::BuildResult,
129     &GEOMAlgo_Gluer::CheckResult
130   };
131   //
132   //TimeReset(); 
133   //StartChrono();
134   //
135   for (i=0; i<aNb; ++i) {
136     (this->*pF[i])();
137     if (myErrorStatus) {
138       return;
139     }
140   }
141   //
142   //StopChrono(); 
143   //TimeShow(); 
144 }
145 //=======================================================================
146 //function : CheckResult
147 //purpose  : 
148 //=======================================================================
149 void GEOMAlgo_Gluer::CheckResult()
150 {
151   myErrorStatus=0;
152   //
153   if (myResult.IsNull()) {
154     myErrorStatus=6;
155     return; 
156   }
157   // 
158   Standard_Boolean bFound;
159   Standard_Integer i, j, aNbS, aNbFS, aNbSx;
160   TopTools_IndexedMapOfShape aMS, aMFS;
161   TopTools_IndexedDataMapOfShapeListOfShape aMFR;
162   //
163   TopExp::MapShapesAndAncestors(myResult, TopAbs_FACE, myTypeResult, aMFR);
164   TopExp::MapShapes(myResult, myTypeResult, aMS);
165   //
166   aNbS=aMS.Extent();
167   for (i=1; i<=aNbS; ++i) {
168     const TopoDS_Shape& aSolid=aMS(i);
169     //
170     aMFS.Clear();
171     TopExp::MapShapes(aSolid, TopAbs_FACE, aMFS);
172     //
173     bFound=Standard_False;
174     aNbFS=aMFS.Extent();
175     for (j=1; j<=aNbFS; ++j) {
176       const TopoDS_Shape& aFS=aMFS(j);
177       if (aMFR.Contains(aFS)) {
178         const TopTools_ListOfShape& aLSx=aMFR.FindFromKey(aFS);
179         aNbSx=aLSx.Extent();
180         if (aNbSx==2) {
181           bFound=!bFound;
182           break;
183         }
184       }
185     }
186     //
187     if (!bFound) {
188       myWarningStatus=1;
189       break;
190     }
191   }
192 }
193 //=======================================================================
194 //function : CheckData
195 //purpose  : 
196 //=======================================================================
197 void GEOMAlgo_Gluer::CheckData()
198 {
199   myErrorStatus=0;
200   //
201   if (myShape.IsNull()) {
202     myErrorStatus=5;
203     return; 
204   }
205   
206 }
207 //=======================================================================
208 //function : InnerTolerance
209 //purpose  : 
210 //=======================================================================
211 void GEOMAlgo_Gluer::InnerTolerance()
212 {
213   myErrorStatus=0;
214   //
215   Standard_Integer i;
216   Standard_Real aX[3][2], dH, dHmin, aCoef, aTolTresh;
217   Bnd_Box aBox;
218   //
219   BRepBndLib::Add(myShape, aBox);
220   aBox.Get(aX[0][0], aX[1][0], aX[2][0], aX[0][1], aX[1][1], aX[2][1]);
221   //
222   dHmin=aX[0][1]-aX[0][0];
223   for (i=1; i<3; ++i) {
224     dH=aX[i][1]-aX[i][0];
225     if (dH<dHmin) {
226       dHmin=dH;
227     }
228   }
229   //
230   myTol=myTolerance;
231   aCoef=0.01;
232   aTolTresh=aCoef*dHmin;
233   if (myTol>aTolTresh) {
234     myTol=aTolTresh;
235   }
236 }
237 //=======================================================================
238 //function : MakeSolids
239 //purpose  : 
240 //=======================================================================
241 void GEOMAlgo_Gluer::MakeSolids()
242 {
243   myErrorStatus=0;
244   //
245   Standard_Integer i, aNbS;
246   TopAbs_Orientation anOr;
247   TopoDS_Solid aNewSolid;
248   TopTools_IndexedMapOfShape aMS;
249   TopExp_Explorer aExp;
250   BRep_Builder aBB;
251   //
252   TopExp::MapShapes(myShape, TopAbs_SOLID, aMS);
253   aNbS=aMS.Extent();
254   for (i=1; i<=aNbS; ++i) {
255     const TopoDS_Solid& aSolid=TopoDS::Solid(aMS(i));
256     anOr=aSolid.Orientation();
257     //
258     aBB.MakeSolid(aNewSolid);
259     aNewSolid.Orientation(anOr);
260     //
261     aExp.Init(aSolid, TopAbs_SHELL);
262     for (; aExp.More(); aExp.Next()) {
263       const TopoDS_Shape& aShell=aExp.Current();
264       const TopoDS_Shape& aShellR=myOrigins.Find(aShell);
265       aBB.Add(aNewSolid, aShellR);
266     }
267     TopTools_ListOfShape aLS;
268     //
269     aLS.Append(aSolid);
270     myImages.Bind(aNewSolid, aLS);
271     myOrigins.Bind(aSolid, aNewSolid);
272   }
273 }
274 //=======================================================================
275 //function : MakeShells
276 //purpose  : 
277 //=======================================================================
278 void GEOMAlgo_Gluer::MakeShells()
279 {
280   myErrorStatus=0;
281   //
282   Standard_Boolean bIsToReverse;
283   Standard_Integer i, aNbS;
284   TopAbs_Orientation anOr;
285   TopoDS_Shell aNewShell;
286   TopoDS_Face aFR;
287   TopTools_IndexedMapOfShape aMS;
288   TopExp_Explorer aExp;
289   BRep_Builder aBB;
290   //
291   TopExp::MapShapes(myShape, TopAbs_SHELL, aMS);
292   //
293   aNbS=aMS.Extent();
294   for (i=1; i<=aNbS; ++i) {
295     const TopoDS_Shell& aShell=TopoDS::Shell(aMS(i));
296     anOr=aShell.Orientation();
297     //
298     aBB.MakeShell(aNewShell);
299     aNewShell.Orientation(anOr);
300     aExp.Init(aShell, TopAbs_FACE);
301     for (; aExp.More(); aExp.Next()) {
302       const TopoDS_Face& aF=TopoDS::Face(aExp.Current());
303       aFR=TopoDS::Face(myOrigins.Find(aF));
304       if (aFR.IsSame(aF)) {
305         aBB.Add(aNewShell, aF);
306         continue;
307       }
308       bIsToReverse=IsToReverse(aFR, aF);
309       if (bIsToReverse) {
310         aFR.Reverse();
311       }
312       aBB.Add(aNewShell, aFR);
313     }
314     //
315     TopTools_ListOfShape aLS;
316     //
317     aLS.Append(aShell);
318     myImages.Bind(aNewShell, aLS);
319     myOrigins.Bind(aShell, aNewShell);
320   }
321 }
322 //=======================================================================
323 //function : MakeFaces
324 //purpose  : 
325 //=======================================================================
326 void GEOMAlgo_Gluer::MakeFaces()
327 {
328   MakeShapes(TopAbs_FACE);
329 }
330 //=======================================================================
331 //function : MakeEdges
332 //purpose  : 
333 //=======================================================================
334 void GEOMAlgo_Gluer::MakeEdges()
335 {
336   MakeShapes(TopAbs_EDGE);
337 }
338 //=======================================================================
339 //function : MakeShapes
340 //purpose  : 
341 //=======================================================================
342 void GEOMAlgo_Gluer::MakeShapes(const TopAbs_ShapeEnum aType)
343 {
344   myErrorStatus=0;
345   //
346   Standard_Integer i, aNbF, aNbSDF, iErr;
347   TopoDS_Shape aNewShape;
348   TopTools_IndexedMapOfShape aMF;
349   TopTools_ListIteratorOfListOfShape aItS;
350   GEOMAlgo_PassKey aPKF;
351   GEOMAlgo_IndexedDataMapOfPassKeyListOfShape aMPKLF;
352   //
353   TopExp::MapShapes(myShape, aType, aMF);
354   //
355   aNbF=aMF.Extent();
356   for (i=1; i<=aNbF; ++i) {
357     const TopoDS_Shape& aS=aMF(i);
358     // 
359     aPKF.Clear();
360     if (aType==TopAbs_FACE) {
361       const TopoDS_Face& aF=TopoDS::Face(aS);
362       FacePassKey(aF, aPKF);
363     }
364     else if (aType==TopAbs_EDGE) {
365       const TopoDS_Edge& aE=TopoDS::Edge(aS);
366       EdgePassKey(aE, aPKF);
367     }
368     //
369     if (myErrorStatus) {
370       return;
371     }
372     //
373     if (aMPKLF.Contains(aPKF)) {
374       TopTools_ListOfShape& aLSDF=aMPKLF.ChangeFromKey(aPKF);
375       aLSDF.Append(aS);
376     }
377     else {
378       TopTools_ListOfShape aLSDF;
379       //
380       aLSDF.Append(aS);
381       aMPKLF.Add(aPKF, aLSDF);
382     }
383   }
384   // check geometric coincidence
385   if (myCheckGeometry) {
386     iErr=GEOMAlgo_Tools::RefineSDShapes(aMPKLF, myTol, myContext); //XX
387     if (iErr) {
388       myErrorStatus=200;
389       return;
390     }
391   }
392   //
393   // Images/Origins
394   aNbF=aMPKLF.Extent();
395   for (i=1; i<=aNbF; ++i) {
396     const TopTools_ListOfShape& aLSDF=aMPKLF(i);
397     aNbSDF=aLSDF.Extent();
398     if (!aNbSDF) {
399       myErrorStatus=4; // it must not be
400     }
401     //
402     const TopoDS_Shape& aS1=aLSDF.First();
403     if (aType==TopAbs_FACE) {
404       TopoDS_Face aNewFace;
405       //
406       const TopoDS_Face& aF1=TopoDS::Face(aS1);
407       MakeFace(aF1, aNewFace);
408       aNewShape=aNewFace;
409     }
410     else if (aType==TopAbs_EDGE) {
411       TopoDS_Edge aNewEdge;
412       //
413       const TopoDS_Edge& aE1=TopoDS::Edge(aS1);
414       MakeEdge(aE1, aNewEdge);
415       aNewShape=aNewEdge;
416     }
417     //
418     myImages.Bind(aNewShape, aLSDF);
419     // origins
420     aItS.Initialize(aLSDF);
421     for (; aItS.More(); aItS.Next()) {
422       const TopoDS_Shape& aFSD=aItS.Value();
423       if (!myOrigins.IsBound(aFSD)) {
424         myOrigins.Bind(aFSD, aNewShape);
425       }
426     }
427   }
428 }
429 //=======================================================================
430 //function : MakeVertices
431 //purpose  : 
432 //=======================================================================
433 void GEOMAlgo_Gluer::MakeVertices()
434 {
435   myErrorStatus=0;
436   //
437   Standard_Boolean bFound; 
438   Standard_Integer i, aNbV, aIndex, aNbVSD;
439   TColStd_ListIteratorOfListOfInteger aIt;
440   Handle(Bnd_HArray1OfBox) aHAB;
441   Bnd_BoundSortBox aBSB;
442   TopoDS_Shape aSTmp;
443   TopTools_IndexedMapOfShape aMV;
444   TopTools_ListIteratorOfListOfShape aItS;
445   TopTools_DataMapIteratorOfDataMapOfShapeListOfShape aItIm;
446   GEOMAlgo_IndexedDataMapOfIntegerShape aMIS;
447   GEOMAlgo_IndexedDataMapOfShapeBox aMSB;
448   //
449   TopExp::MapShapes(myShape, TopAbs_VERTEX, aMV);
450   aNbV=aMV.Extent();
451   if (!aNbV) {
452     myErrorStatus=2; // no vertices in source shape
453     return;
454   }
455   //
456   aHAB=new Bnd_HArray1OfBox(1, aNbV);
457   //
458   for (i=1; i<=aNbV; ++i) {
459     const TopoDS_Shape& aV=aMV(i);
460     Bnd_Box aBox;
461     //
462     aBox.SetGap(myTol);//XX 
463     BRepBndLib::Add(aV, aBox);
464     aHAB->SetValue(i, aBox);
465     aMIS.Add(i, aV);
466     aMSB.Add(aV, aBox); 
467   }
468   //
469   aBSB.Initialize(aHAB);
470   //
471   for (i=1; i<=aNbV; ++i) {
472     const TopoDS_Shape& aV=aMV(i);
473     const Bnd_Box& aBoxV=aMSB.FindFromKey(aV);
474     const TColStd_ListOfInteger& aLI=aBSB.Compare(aBoxV);
475     aNbVSD=aLI.Extent();
476     if (!aNbVSD) {
477       myErrorStatus=3; // it must not be 
478       return;
479     }
480     //
481     // Images
482     TopTools_ListOfShape aLVSD;
483     TopoDS_Shape aVF;
484     //
485     bFound=Standard_False;
486     aIt.Initialize(aLI);
487     for (; aIt.More(); aIt.Next()) {
488       aIndex=aIt.Value();
489       const TopoDS_Shape& aVx=aMIS.FindFromKey(aIndex);
490       if (myImages.IsBound(aVx)) {
491         bFound=Standard_True;
492         aVF=aVx;
493       }
494       aLVSD.Append(aVx);
495     }
496     if (bFound) {
497       TopTools_ListOfShape& aLVI=myImages.ChangeFind(aVF);
498       aLVI.Append(aLVSD);
499     }
500     else {
501       myImages.Bind(aV, aLVSD);
502     }
503   }
504   //
505   // Refine Images
506   aItIm.Initialize(myImages);
507   for (; aItIm.More(); aItIm.Next()) {
508     TopTools_ListOfShape aLVSDNew;
509     TopTools_MapOfShape aM;
510     //
511     const TopoDS_Shape& aV=aItIm.Key();
512     const TopTools_ListOfShape& aLVSD=aItIm.Value();
513     aItS.Initialize(aLVSD);
514     for (; aItS.More(); aItS.Next()) {
515       const TopoDS_Shape& aVSD=aItS.Value();
516       if (aM.Add(aVSD)) {
517         aLVSDNew.Append(aVSD);
518       }
519     }
520     TopTools_ListOfShape& aLVI=myImages.ChangeFind(aV);
521     aLVI.Clear();
522     aLVI.Append(aLVSDNew);
523   }
524   //
525   // Origins
526   aItIm.Initialize(myImages);
527   for (; aItIm.More(); aItIm.Next()) {
528     const TopoDS_Shape& aV=aItIm.Key();
529     //
530     const TopTools_ListOfShape& aLVSD=myImages.Find(aV);
531     aItS.Initialize(aLVSD);
532     for (; aItS.More(); aItS.Next()) {
533       const TopoDS_Shape& aVSD=aItS.Value();
534       if (!myOrigins.IsBound(aVSD)) {
535         myOrigins.Bind(aVSD, aV);
536       }
537     }
538   }
539   //
540 }
541 //=======================================================================
542 //function : FacePassKey
543 //purpose  : 
544 //=======================================================================
545 void GEOMAlgo_Gluer::FacePassKey(const TopoDS_Face& aF, 
546                                  GEOMAlgo_PassKey& aPK)
547 {
548   Standard_Integer i, aNbE, aNbMax;
549   TopTools_ListOfShape aLE;
550   TopTools_IndexedMapOfShape aME;
551   //
552   TopExp::MapShapes(aF, TopAbs_EDGE, aME);
553   aNbE=aME.Extent();
554   aNbMax=aPK.NbMax();
555   if (!aNbE || aNbE>aNbMax) {
556      myErrorStatus=101; // temprorary
557      return;
558   }
559   //
560   for (i=1; i<=aNbE; ++i) {
561     const TopoDS_Shape& aE=aME(i);
562     if (!myOrigins.IsBound(aE)) {
563       myErrorStatus=102;
564       return;
565     }
566     const TopoDS_Shape& aER=myOrigins.Find(aE);
567     aLE.Append(aER);
568   }
569   aPK.SetIds(aLE);
570 }
571 //=======================================================================
572 //function : EdgePassKey
573 //purpose  : 
574 //=======================================================================
575 void GEOMAlgo_Gluer::EdgePassKey(const TopoDS_Edge& aE, 
576                                  GEOMAlgo_PassKey& aPK)
577 {
578   TopoDS_Vertex aV1, aV2;
579   //
580   TopExp::Vertices(aE, aV1, aV2);
581   //
582   if (!myOrigins.IsBound(aV1) || !myOrigins.IsBound(aV2) ) {
583      myErrorStatus=100;
584      return;
585   }
586   const TopoDS_Shape& aVR1=myOrigins.Find(aV1);
587   const TopoDS_Shape& aVR2=myOrigins.Find(aV2);
588   aPK.SetIds(aVR1, aVR2);
589 }
590 //=======================================================================
591 //function : MakeEdge
592 //purpose  : 
593 //=======================================================================
594 void GEOMAlgo_Gluer::MakeEdge(const TopoDS_Edge& aE, 
595                               TopoDS_Edge& aNewEdge)
596 {
597   myErrorStatus=0;
598   //
599   Standard_Real aT1, aT2;
600   TopoDS_Vertex aV1, aV2, aVR1, aVR2;
601   TopoDS_Edge aEx;
602   //
603   aEx=aE;
604   aEx.Orientation(TopAbs_FORWARD);
605   //
606   TopExp::Vertices(aEx, aV1, aV2);
607   //
608   aT1=BRep_Tool::Parameter(aV1, aEx);
609   aT2=BRep_Tool::Parameter(aV2, aEx);
610   //
611   aVR1=TopoDS::Vertex(myOrigins.Find(aV1));
612   aVR1.Orientation(TopAbs_FORWARD);
613   aVR2=TopoDS::Vertex(myOrigins.Find(aV2));
614   aVR2.Orientation(TopAbs_REVERSED);
615   //
616   BOPTools_Tools::MakeSplitEdge(aEx, aVR1, aT1, aVR2, aT2, aNewEdge); 
617 }
618 //
619 //=======================================================================
620 //function : MakeFace
621 //purpose  : 
622 //=======================================================================
623 void GEOMAlgo_Gluer::MakeFace(const TopoDS_Face& aF, 
624                               TopoDS_Face& aNewFace)
625 {
626   myErrorStatus=0;
627   //
628   Standard_Boolean bIsToReverse;
629   Standard_Real aTol;
630   TopoDS_Edge aER;
631   TopoDS_Wire newWire;
632   TopoDS_Face aFFWD, newFace;
633   TopLoc_Location aLoc;
634   Handle(Geom_Surface) aS;
635   TopExp_Explorer aExpW, aExpE;
636   BRep_Builder aBB;
637   //
638   aFFWD=aF;
639   aFFWD.Orientation(TopAbs_FORWARD);
640   //
641   aS=BRep_Tool::Surface(aFFWD, aLoc);
642   aTol=BRep_Tool::Tolerance(aFFWD);
643   //
644   aBB.MakeFace (newFace, aS, aLoc, aTol);
645   //
646   aExpW.Init(aFFWD, TopAbs_WIRE);
647   for (; aExpW.More(); aExpW.Next()) {
648     aBB.MakeWire(newWire);
649     const TopoDS_Wire& aW=TopoDS::Wire(aExpW.Current());
650     aExpE.Init(aW, TopAbs_EDGE);
651     for (; aExpE.More(); aExpE.Next()) {
652       const TopoDS_Edge& aE=TopoDS::Edge(aExpE.Current());
653       aER=TopoDS::Edge(myOrigins.Find(aE));
654       aER.Orientation(TopAbs_FORWARD);
655       // build p-curve
656       BOPTools_Tools2D::BuildPCurveForEdgeOnFace(aER, aFFWD);
657       // orient image 
658       bIsToReverse=BOPTools_Tools3D::IsSplitToReverse1(aER, aE, myContext);
659       if (bIsToReverse) {
660         aER.Reverse();
661       }
662       //
663       aBB.Add(newWire, aER);
664     }
665     aBB.Add(newFace, newWire);
666   }
667   aNewFace=newFace;
668 }
669 //=======================================================================
670 //function : IsToReverse
671 //purpose  : 
672 //=======================================================================
673 Standard_Boolean GEOMAlgo_Gluer::IsToReverse(const TopoDS_Face& aFR,
674                                              const TopoDS_Face& aF)
675 {
676   Standard_Boolean bRet;
677   Standard_Real aT, aT1, aT2, aTR, aScPr;
678   TopExp_Explorer aExp;
679   Handle(Geom_Curve)aC3D;
680   gp_Pnt aP;
681   gp_Dir aDNF, aDNFR;
682   //
683   bRet=Standard_False;
684   //
685   aExp.Init(aF, TopAbs_EDGE);
686   if (!aExp.More()) {
687     return bRet;
688   }
689   const TopoDS_Edge& aE=TopoDS::Edge(aExp.Current());
690   const TopoDS_Edge& aER=TopoDS::Edge(myOrigins.Find(aE));
691   //
692   aC3D=BRep_Tool::Curve(aE, aT1, aT2);
693   aT=BOPTools_Tools2D::IntermediatePoint(aT1, aT2);
694   aC3D->D0(aT, aP);
695   myContext.ProjectPointOnEdge(aP, aER, aTR);
696   //
697   BOPTools_Tools3D::GetNormalToFaceOnEdge (aE, aF, aT, aDNF);
698   if (aF.Orientation()==TopAbs_REVERSED) {
699     aDNF.Reverse();
700   }
701   //
702   BOPTools_Tools3D::GetNormalToFaceOnEdge (aER, aFR, aTR, aDNFR);
703   if (aFR.Orientation()==TopAbs_REVERSED) {
704     aDNFR.Reverse();
705   }
706   //
707   aScPr=aDNF*aDNFR;
708   return (aScPr<0.);
709 }
710 //
711 //=======================================================================
712 //function : BuildResult
713 //purpose  : 
714 //=======================================================================
715 void GEOMAlgo_Gluer::BuildResult()
716 {
717   TopoDS_Compound aCmp;
718   BRep_Builder aBB;
719   TopAbs_ShapeEnum aType;
720   TopTools_DataMapIteratorOfDataMapOfShapeListOfShape aItIm;
721   //
722   aBB.MakeCompound(aCmp);
723   //
724   aItIm.Initialize(myImages);
725   for (; aItIm.More(); aItIm.Next()) {
726     const TopoDS_Shape& aIm=aItIm.Key();
727     aType=aIm.ShapeType();
728     if(aType==myTypeResult) {
729       aBB.Add(aCmp, aIm);
730     }
731   }
732   myResult=aCmp;
733 }
734 //
735 // ErrorStatus
736 //
737 // 1   - the object is just initialized 
738 // 2   - no vertices found in source shape
739 // 3   - nb same domain vertices for the vertex Vi =0
740 // 4   - nb same domain edges(faces) for the edge Ei(face Fi)  =0
741 // 5   - source shape is Null
742 // 6   - result shape is Null
743 // 101 - nb edges > PassKey.NbMax() in FacesPassKey()
744 // 102 - the edge Ei can not be found in myOrigins Map
745 // 100 - the vertex Vi can not be found in myOrigins Map
746 //
747 // WarningStatus
748 //
749 // 1   - some shapes can not be glued by faces
750 //
751      
752 /*
753 //
754 // CHRONOMETER
755 //
756 #include <Standard_Static.hxx>
757 #include <OSD_Chronometer.hxx>
758
759 static Standard_Real S_ChronoTime;
760 Standard_STATIC(OSD_Chronometer, S_Chrono);
761
762 static void StartChrono();
763 static void StopChrono(); 
764 static void TimeShow(); 
765 static void TimeReset(); 
766 static int HasChrono();
767
768 //=======================================================================
769 //function : StartChrono
770 //purpose  : 
771 //=======================================================================
772 void StartChrono() 
773 {
774   if (HasChrono()){
775     S_Chrono().Reset();
776     S_Chrono().Start();
777   }
778 }
779
780 //=======================================================================
781 //function : StopChrono
782 //purpose  : 
783 //=======================================================================
784 void StopChrono() 
785
786   if (HasChrono()) {
787     Standard_Real Chrono;
788     S_Chrono().Stop();
789     S_Chrono().Show(Chrono);
790     //
791     S_ChronoTime+=Chrono;
792   }
793 }
794 //=======================================================================
795 //function : TimeReset
796 //purpose  : 
797 //=======================================================================
798 void TimeReset() 
799 {
800   if (HasChrono()){
801     S_ChronoTime=0;
802   }
803 }
804 //=======================================================================
805 //function : TimeShow
806 //purpose  : 
807 //=======================================================================
808 void TimeShow() 
809
810   if (HasChrono()){
811     cout << "Tps: " << S_ChronoTime << endl;
812   }
813 }
814 //=======================================================================
815 //function : HasChrono
816 //purpose  : 
817 //=======================================================================
818 int HasChrono() 
819
820   char *xr=getenv ("XCHRONO");
821   if (xr!=NULL){
822     if (!strcmp (xr, "yes")) {
823       return 1;
824     }
825   }
826   return 0;
827 }
828 */