1 // File: GEOMAlgo_Gluer.cxx
2 // Created: Sat Dec 04 12:45:53 2004
3 // Author: Peter KURNEV
7 #include <GEOMAlgo_Gluer.ixx>
9 #include <TColStd_ListOfInteger.hxx>
10 #include <TColStd_ListIteratorOfListOfInteger.hxx>
15 #include <Geom_Curve.hxx>
16 #include <Geom_Surface.hxx>
18 #include <Bnd_Box.hxx>
19 #include <Bnd_HArray1OfBox.hxx>
20 #include <Bnd_BoundSortBox.hxx>
21 #include <BRepBndLib.hxx>
23 #include <TopLoc_Location.hxx>
24 #include <TopAbs_ShapeEnum.hxx>
25 #include <TopAbs_Orientation.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>
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>
44 #include <TopExp_Explorer.hxx>
46 #include <BRep_Tool.hxx>
47 #include <BRep_Builder.hxx>
49 #include <IntTools_Context.hxx>
50 #include <BOPTools_Tools.hxx>
51 #include <BOPTools_Tools3D.hxx>
52 #include <BOPTools_Tools2D.hxx>
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>
60 //=======================================================================
61 //function : GEOMAlgo_Gluer
63 //=======================================================================
64 GEOMAlgo_Gluer::GEOMAlgo_Gluer()
70 myCheckGeometry=Standard_True;
71 myTypeResult=TopAbs_SOLID;
73 //=======================================================================
74 //function : ~GEOMAlgo_Gluer
76 //=======================================================================
77 GEOMAlgo_Gluer::~GEOMAlgo_Gluer()
80 //=======================================================================
81 //function : SetCheckGeometry
83 //=======================================================================
84 void GEOMAlgo_Gluer::SetCheckGeometry(const Standard_Boolean aFlag)
86 myCheckGeometry=aFlag;
88 //=======================================================================
89 //function : CheckGeometry
91 //=======================================================================
92 Standard_Boolean GEOMAlgo_Gluer::CheckGeometry() const
94 return myCheckGeometry;
97 //=======================================================================
100 //=======================================================================
101 const TopTools_DataMapOfShapeListOfShape& GEOMAlgo_Gluer::Images()const
105 //=======================================================================
108 //=======================================================================
109 const TopTools_DataMapOfShapeShape& GEOMAlgo_Gluer::Origins()const
113 //=======================================================================
116 //=======================================================================
117 void GEOMAlgo_Gluer::Perform()
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
135 for (i=0; i<aNb; ++i) {
145 //=======================================================================
146 //function : CheckResult
148 //=======================================================================
149 void GEOMAlgo_Gluer::CheckResult()
153 if (myResult.IsNull()) {
158 Standard_Boolean bFound;
159 Standard_Integer i, j, aNbS, aNbFS, aNbSx;
160 TopTools_IndexedMapOfShape aMS, aMFS;
161 TopTools_IndexedDataMapOfShapeListOfShape aMFR;
163 TopExp::MapShapesAndAncestors(myResult, TopAbs_FACE, myTypeResult, aMFR);
164 TopExp::MapShapes(myResult, myTypeResult, aMS);
167 for (i=1; i<=aNbS; ++i) {
168 const TopoDS_Shape& aSolid=aMS(i);
171 TopExp::MapShapes(aSolid, TopAbs_FACE, aMFS);
173 bFound=Standard_False;
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);
193 //=======================================================================
194 //function : CheckData
196 //=======================================================================
197 void GEOMAlgo_Gluer::CheckData()
201 if (myShape.IsNull()) {
207 //=======================================================================
208 //function : InnerTolerance
210 //=======================================================================
211 void GEOMAlgo_Gluer::InnerTolerance()
216 Standard_Real aX[3][2], dH, dHmin, aCoef, aTolTresh;
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]);
222 dHmin=aX[0][1]-aX[0][0];
223 for (i=1; i<3; ++i) {
224 dH=aX[i][1]-aX[i][0];
232 aTolTresh=aCoef*dHmin;
233 if (myTol>aTolTresh) {
237 //=======================================================================
238 //function : MakeSolids
240 //=======================================================================
241 void GEOMAlgo_Gluer::MakeSolids()
245 Standard_Integer i, aNbS;
246 TopAbs_Orientation anOr;
247 TopoDS_Solid aNewSolid;
248 TopTools_IndexedMapOfShape aMS;
249 TopExp_Explorer aExp;
252 TopExp::MapShapes(myShape, TopAbs_SOLID, aMS);
254 for (i=1; i<=aNbS; ++i) {
255 const TopoDS_Solid& aSolid=TopoDS::Solid(aMS(i));
256 anOr=aSolid.Orientation();
258 aBB.MakeSolid(aNewSolid);
259 aNewSolid.Orientation(anOr);
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);
267 TopTools_ListOfShape aLS;
270 myImages.Bind(aNewSolid, aLS);
271 myOrigins.Bind(aSolid, aNewSolid);
274 //=======================================================================
275 //function : MakeShells
277 //=======================================================================
278 void GEOMAlgo_Gluer::MakeShells()
282 Standard_Boolean bIsToReverse;
283 Standard_Integer i, aNbS;
284 TopAbs_Orientation anOr;
285 TopoDS_Shell aNewShell;
287 TopTools_IndexedMapOfShape aMS;
288 TopExp_Explorer aExp;
291 TopExp::MapShapes(myShape, TopAbs_SHELL, aMS);
294 for (i=1; i<=aNbS; ++i) {
295 const TopoDS_Shell& aShell=TopoDS::Shell(aMS(i));
296 anOr=aShell.Orientation();
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);
308 bIsToReverse=IsToReverse(aFR, aF);
312 aBB.Add(aNewShell, aFR);
315 TopTools_ListOfShape aLS;
318 myImages.Bind(aNewShell, aLS);
319 myOrigins.Bind(aShell, aNewShell);
322 //=======================================================================
323 //function : MakeFaces
325 //=======================================================================
326 void GEOMAlgo_Gluer::MakeFaces()
328 MakeShapes(TopAbs_FACE);
330 //=======================================================================
331 //function : MakeEdges
333 //=======================================================================
334 void GEOMAlgo_Gluer::MakeEdges()
336 MakeShapes(TopAbs_EDGE);
338 //=======================================================================
339 //function : MakeShapes
341 //=======================================================================
342 void GEOMAlgo_Gluer::MakeShapes(const TopAbs_ShapeEnum aType)
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;
353 TopExp::MapShapes(myShape, aType, aMF);
356 for (i=1; i<=aNbF; ++i) {
357 const TopoDS_Shape& aS=aMF(i);
360 if (aType==TopAbs_FACE) {
361 const TopoDS_Face& aF=TopoDS::Face(aS);
362 FacePassKey(aF, aPKF);
364 else if (aType==TopAbs_EDGE) {
365 const TopoDS_Edge& aE=TopoDS::Edge(aS);
366 EdgePassKey(aE, aPKF);
373 if (aMPKLF.Contains(aPKF)) {
374 TopTools_ListOfShape& aLSDF=aMPKLF.ChangeFromKey(aPKF);
378 TopTools_ListOfShape aLSDF;
381 aMPKLF.Add(aPKF, aLSDF);
384 // check geometric coincidence
385 if (myCheckGeometry) {
386 iErr=GEOMAlgo_Tools::RefineSDShapes(aMPKLF, myTol, myContext); //XX
394 aNbF=aMPKLF.Extent();
395 for (i=1; i<=aNbF; ++i) {
396 const TopTools_ListOfShape& aLSDF=aMPKLF(i);
397 aNbSDF=aLSDF.Extent();
399 myErrorStatus=4; // it must not be
402 const TopoDS_Shape& aS1=aLSDF.First();
403 if (aType==TopAbs_FACE) {
404 TopoDS_Face aNewFace;
406 const TopoDS_Face& aF1=TopoDS::Face(aS1);
407 MakeFace(aF1, aNewFace);
410 else if (aType==TopAbs_EDGE) {
411 TopoDS_Edge aNewEdge;
413 const TopoDS_Edge& aE1=TopoDS::Edge(aS1);
414 MakeEdge(aE1, aNewEdge);
418 myImages.Bind(aNewShape, aLSDF);
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);
429 //=======================================================================
430 //function : MakeVertices
432 //=======================================================================
433 void GEOMAlgo_Gluer::MakeVertices()
437 Standard_Boolean bFound;
438 Standard_Integer i, aNbV, aIndex, aNbVSD;
439 TColStd_ListIteratorOfListOfInteger aIt;
440 Handle(Bnd_HArray1OfBox) aHAB;
441 Bnd_BoundSortBox aBSB;
443 TopTools_IndexedMapOfShape aMV;
444 TopTools_ListIteratorOfListOfShape aItS;
445 TopTools_DataMapIteratorOfDataMapOfShapeListOfShape aItIm;
446 GEOMAlgo_IndexedDataMapOfIntegerShape aMIS;
447 GEOMAlgo_IndexedDataMapOfShapeBox aMSB;
449 TopExp::MapShapes(myShape, TopAbs_VERTEX, aMV);
452 myErrorStatus=2; // no vertices in source shape
456 aHAB=new Bnd_HArray1OfBox(1, aNbV);
458 for (i=1; i<=aNbV; ++i) {
459 const TopoDS_Shape& aV=aMV(i);
462 aBox.SetGap(myTol);//XX
463 BRepBndLib::Add(aV, aBox);
464 aHAB->SetValue(i, aBox);
469 aBSB.Initialize(aHAB);
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);
477 myErrorStatus=3; // it must not be
482 TopTools_ListOfShape aLVSD;
485 bFound=Standard_False;
487 for (; aIt.More(); aIt.Next()) {
489 const TopoDS_Shape& aVx=aMIS.FindFromKey(aIndex);
490 if (myImages.IsBound(aVx)) {
491 bFound=Standard_True;
497 TopTools_ListOfShape& aLVI=myImages.ChangeFind(aVF);
501 myImages.Bind(aV, aLVSD);
506 aItIm.Initialize(myImages);
507 for (; aItIm.More(); aItIm.Next()) {
508 TopTools_ListOfShape aLVSDNew;
509 TopTools_MapOfShape aM;
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();
517 aLVSDNew.Append(aVSD);
520 TopTools_ListOfShape& aLVI=myImages.ChangeFind(aV);
522 aLVI.Append(aLVSDNew);
526 aItIm.Initialize(myImages);
527 for (; aItIm.More(); aItIm.Next()) {
528 const TopoDS_Shape& aV=aItIm.Key();
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);
541 //=======================================================================
542 //function : FacePassKey
544 //=======================================================================
545 void GEOMAlgo_Gluer::FacePassKey(const TopoDS_Face& aF,
546 GEOMAlgo_PassKey& aPK)
548 Standard_Integer i, aNbE, aNbMax;
549 TopTools_ListOfShape aLE;
550 TopTools_IndexedMapOfShape aME;
552 TopExp::MapShapes(aF, TopAbs_EDGE, aME);
555 if (!aNbE || aNbE>aNbMax) {
556 myErrorStatus=101; // temprorary
560 for (i=1; i<=aNbE; ++i) {
561 const TopoDS_Shape& aE=aME(i);
562 if (!myOrigins.IsBound(aE)) {
566 const TopoDS_Shape& aER=myOrigins.Find(aE);
571 //=======================================================================
572 //function : EdgePassKey
574 //=======================================================================
575 void GEOMAlgo_Gluer::EdgePassKey(const TopoDS_Edge& aE,
576 GEOMAlgo_PassKey& aPK)
578 TopoDS_Vertex aV1, aV2;
580 TopExp::Vertices(aE, aV1, aV2);
582 if (!myOrigins.IsBound(aV1) || !myOrigins.IsBound(aV2) ) {
586 const TopoDS_Shape& aVR1=myOrigins.Find(aV1);
587 const TopoDS_Shape& aVR2=myOrigins.Find(aV2);
588 aPK.SetIds(aVR1, aVR2);
590 //=======================================================================
591 //function : MakeEdge
593 //=======================================================================
594 void GEOMAlgo_Gluer::MakeEdge(const TopoDS_Edge& aE,
595 TopoDS_Edge& aNewEdge)
599 Standard_Real aT1, aT2;
600 TopoDS_Vertex aV1, aV2, aVR1, aVR2;
604 aEx.Orientation(TopAbs_FORWARD);
606 TopExp::Vertices(aEx, aV1, aV2);
608 aT1=BRep_Tool::Parameter(aV1, aEx);
609 aT2=BRep_Tool::Parameter(aV2, aEx);
611 aVR1=TopoDS::Vertex(myOrigins.Find(aV1));
612 aVR1.Orientation(TopAbs_FORWARD);
613 aVR2=TopoDS::Vertex(myOrigins.Find(aV2));
614 aVR2.Orientation(TopAbs_REVERSED);
616 BOPTools_Tools::MakeSplitEdge(aEx, aVR1, aT1, aVR2, aT2, aNewEdge);
619 //=======================================================================
620 //function : MakeFace
622 //=======================================================================
623 void GEOMAlgo_Gluer::MakeFace(const TopoDS_Face& aF,
624 TopoDS_Face& aNewFace)
628 Standard_Boolean bIsToReverse;
632 TopoDS_Face aFFWD, newFace;
633 TopLoc_Location aLoc;
634 Handle(Geom_Surface) aS;
635 TopExp_Explorer aExpW, aExpE;
639 aFFWD.Orientation(TopAbs_FORWARD);
641 aS=BRep_Tool::Surface(aFFWD, aLoc);
642 aTol=BRep_Tool::Tolerance(aFFWD);
644 aBB.MakeFace (newFace, aS, aLoc, aTol);
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);
656 BOPTools_Tools2D::BuildPCurveForEdgeOnFace(aER, aFFWD);
658 bIsToReverse=BOPTools_Tools3D::IsSplitToReverse1(aER, aE, myContext);
663 aBB.Add(newWire, aER);
665 aBB.Add(newFace, newWire);
669 //=======================================================================
670 //function : IsToReverse
672 //=======================================================================
673 Standard_Boolean GEOMAlgo_Gluer::IsToReverse(const TopoDS_Face& aFR,
674 const TopoDS_Face& aF)
676 Standard_Boolean bRet;
677 Standard_Real aT, aT1, aT2, aTR, aScPr;
678 TopExp_Explorer aExp;
679 Handle(Geom_Curve)aC3D;
685 aExp.Init(aF, TopAbs_EDGE);
689 const TopoDS_Edge& aE=TopoDS::Edge(aExp.Current());
690 const TopoDS_Edge& aER=TopoDS::Edge(myOrigins.Find(aE));
692 aC3D=BRep_Tool::Curve(aE, aT1, aT2);
693 aT=BOPTools_Tools2D::IntermediatePoint(aT1, aT2);
695 myContext.ProjectPointOnEdge(aP, aER, aTR);
697 BOPTools_Tools3D::GetNormalToFaceOnEdge (aE, aF, aT, aDNF);
698 if (aF.Orientation()==TopAbs_REVERSED) {
702 BOPTools_Tools3D::GetNormalToFaceOnEdge (aER, aFR, aTR, aDNFR);
703 if (aFR.Orientation()==TopAbs_REVERSED) {
711 //=======================================================================
712 //function : BuildResult
714 //=======================================================================
715 void GEOMAlgo_Gluer::BuildResult()
717 TopoDS_Compound aCmp;
719 TopAbs_ShapeEnum aType;
720 TopTools_DataMapIteratorOfDataMapOfShapeListOfShape aItIm;
722 aBB.MakeCompound(aCmp);
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) {
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
749 // 1 - some shapes can not be glued by faces
756 #include <Standard_Static.hxx>
757 #include <OSD_Chronometer.hxx>
759 static Standard_Real S_ChronoTime;
760 Standard_STATIC(OSD_Chronometer, S_Chrono);
762 static void StartChrono();
763 static void StopChrono();
764 static void TimeShow();
765 static void TimeReset();
766 static int HasChrono();
768 //=======================================================================
769 //function : StartChrono
771 //=======================================================================
780 //=======================================================================
781 //function : StopChrono
783 //=======================================================================
787 Standard_Real Chrono;
789 S_Chrono().Show(Chrono);
791 S_ChronoTime+=Chrono;
794 //=======================================================================
795 //function : TimeReset
797 //=======================================================================
804 //=======================================================================
805 //function : TimeShow
807 //=======================================================================
811 cout << "Tps: " << S_ChronoTime << endl;
814 //=======================================================================
815 //function : HasChrono
817 //=======================================================================
820 char *xr=getenv ("XCHRONO");
822 if (!strcmp (xr, "yes")) {