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