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