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