1 // Created on: 1998-07-28
2 // Created by: LECLERE Florence
3 // Copyright (c) 1998-1999 Matra Datavision
4 // Copyright (c) 1999-2014 OPEN CASCADE SAS
6 // This file is part of Open CASCADE Technology software library.
8 // This library is free software; you can redistribute it and/or modify it under
9 // the terms of the GNU Lesser General Public License version 2.1 as published
10 // by the Free Software Foundation, with special exception defined in the file
11 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
12 // distribution for complete text of the license and disclaimer of any warranty.
14 // Alternatively, this file may be used under the terms of Open CASCADE
15 // commercial license or contractual agreement.
17 #include <TopOpeBRepBuild_FuseFace.hxx>
19 #include <TopTools_ListOfShape.hxx>
20 #include <TopTools_ListIteratorOfListOfShape.hxx>
21 #include <TopTools_MapOfShape.hxx>
23 #include <TopTools_DataMapOfShapeListOfShape.hxx>
24 #include <TopTools_DataMapIteratorOfDataMapOfShapeListOfShape.hxx>
25 #include <TopTools_DataMapOfShapeInteger.hxx>
26 #include <TopTools_DataMapIteratorOfDataMapOfShapeInteger.hxx>
28 #include <TopExp_Explorer.hxx>
31 #include <TopoDS_Face.hxx>
32 #include <TopoDS_Wire.hxx>
33 #include <TopoDS_Edge.hxx>
35 #include <BRepLib_MakeWire.hxx>
36 #include <BRepLib_MakeFace.hxx>
37 #include <BRepLib_MakeEdge.hxx>
39 #include <BRep_Builder.hxx>
40 #include <BRep_Tool.hxx>
41 #include <BRepCheck_Analyzer.hxx>
43 #include <Geom_Surface.hxx>
44 #include <Geom_RectangularTrimmedSurface.hxx>
45 #include <Geom_Curve.hxx>
46 #include <Geom_TrimmedCurve.hxx>
47 #include <Geom_Line.hxx>
48 #include <Geom_Circle.hxx>
49 #include <Geom_Ellipse.hxx>
50 #include <Geom_BSplineCurve.hxx>
51 #include <Geom_BezierCurve.hxx>
52 #include <TColgp_Array1OfPnt.hxx>
53 #include <TColStd_Array1OfReal.hxx>
54 #include <TColStd_Array1OfInteger.hxx>
56 #include <Precision.hxx>
59 extern Standard_Boolean TopOpeBRepBuild_GettraceFUFA();
62 static void GroupShape(TopTools_ListOfShape&,
64 TopTools_DataMapOfShapeListOfShape&);
66 static void GroupEdge(TopTools_DataMapOfShapeListOfShape&,
67 TopTools_DataMapOfShapeListOfShape&);
69 static void MakeEdge(TopTools_DataMapOfShapeListOfShape&);
71 static Standard_Boolean SameSupport(const TopoDS_Edge&,
74 //=======================================================================
77 //=======================================================================
78 void TopOpeBRepBuild_FuseFace::Init(const TopTools_ListOfShape& LIF,
79 const TopTools_ListOfShape& LRF,
80 const Standard_Integer CXM)
83 Standard_Boolean trc = TopOpeBRepBuild_GettraceFUFA();
84 if (trc) cout << "TopOpeBRepBuild_FuseFace::Init" << endl;
89 myInternal = Standard_False;
92 myInternal = Standard_True;
97 cout << " TopOpeBRepBuild_FuseFace::Init : Keep internal connections" << endl;
99 cout << " TopOpeBRepBuild_FuseFace::Init : Suppress internal connections" << endl;
114 myModified = Standard_False;
115 myDone = Standard_False;
119 //=======================================================================
120 //function : PerformFace
121 //purpose : fusion des faces cosurfaciques, connexes par une ou
123 //=======================================================================
125 void TopOpeBRepBuild_FuseFace::PerformFace()
128 Standard_Boolean trc = TopOpeBRepBuild_GettraceFUFA();
129 if (trc) cout << "TopOpeBRepBuild_FuseFace::PerformFace()" << endl;
132 myModified = Standard_False;
134 if (myLRF.IsEmpty()) {
136 if (trc) cout<<" TopOpeBRepBuild_FuseFace::PerformFace : Empty list of reconstructed faces"<<endl;
138 myModified = Standard_False;
139 myDone = Standard_True;
144 Standard_Integer number = myLRF.Extent();
147 if (trc) cout<<" TopOpeBRepBuild_FuseFace::PerformFace : only 1 reconstructed face"<<endl;
149 myModified = Standard_False;
150 myDone = Standard_True;
155 TopTools_ListIteratorOfListOfShape it2,it3,it4;
156 TopTools_DataMapIteratorOfDataMapOfShapeListOfShape itt1,itt2,itt3;
157 TopAbs_Orientation ori1;
159 Standard_Boolean Ori3dReversed = Standard_False;
160 Standard_Boolean Ori3dForward = Standard_False;
161 TopTools_ListOfShape mylist;
162 for(it2.Initialize(myLRF); it2.More(); it2.Next()) {
163 TopoDS_Shape fac = it2.Value();
164 ori1 = fac.Orientation();
165 if (ori1 == TopAbs_FORWARD) {
166 Ori3dForward = Standard_True;
168 if (ori1 == TopAbs_REVERSED) {
169 Ori3dReversed = Standard_True;
171 BRepCheck_Analyzer ana(fac);
172 if (!ana.IsValid(fac)) {
173 // if (!BRepCheck_Analyzer::IsValid(fac)) {
175 if (trc) cout<<" TopOpeBRepBuild_FuseFace::PerformFace : Invalid reconstructed face"<<endl;
177 myModified = Standard_False;
178 myDone = Standard_True;
182 fac.Orientation(TopAbs_FORWARD);
186 // Orientation 3d de l'espace limite par la face
187 if (Ori3dForward && Ori3dReversed) {
189 if (trc) cout<<" TopOpeBRepBuild_FuseFace::PerformFace : Bad faces 3d orientation"<<endl;
191 myModified = Standard_False;
192 myDone = Standard_True;
197 // listes de faces avec edges communes.
198 Standard_Boolean Keep_Edge;
199 Keep_Edge = Standard_False;
200 TopTools_DataMapOfShapeListOfShape mapFacLFac;
201 GroupShape(mylist,Keep_Edge,mapFacLFac);
202 if (mapFacLFac.IsEmpty()) {
204 if (trc) cout<<" TopOpeBRepBuild_FuseFace::PerformFace : Empty list of faces"<<endl;
206 myModified = Standard_False;
207 myDone = Standard_True;
211 Standard_Integer n1 = myLRF.Extent();
212 Standard_Integer n2 = mapFacLFac.Extent();
215 if (trc) cout<<" TopOpeBRepBuild_FuseFace::PerformFace : No connection"<<endl;
217 myModified = Standard_False;
218 myDone = Standard_True;
224 //boucle sur les listes des faces de 1 face de LRF
226 for (itt1.Initialize(mapFacLFac); itt1.More(); itt1.Next()) {
227 const TopoDS_Shape& fac = itt1.Key();
228 TopoDS_Face facref = TopoDS::Face(fac);
229 const TopTools_ListOfShape& LFac = mapFacLFac.Find(fac);
231 Standard_Integer n11 = LFac.Extent();
233 TopTools_ListOfShape LWir;
234 for(it2.Initialize(LFac); it2.More(); it2.Next()) {
235 const TopoDS_Shape& fac1 = it2.Value();
238 for (exp.Init(fac1,TopAbs_WIRE); exp.More(); exp.Next()) {
239 const TopoDS_Shape& wir = exp.Current();
243 // listes des wires avec edges communes.
244 Keep_Edge = Standard_False;
245 TopTools_DataMapOfShapeListOfShape mapWirLWir;
246 GroupShape(LWir,Keep_Edge,mapWirLWir);
247 if (mapWirLWir.IsEmpty()) {
249 if (trc) cout<<" TopOpeBRepBuild_FuseFace::PerformFace : Empty list of wires"<<endl;
251 myModified = Standard_False;
252 myDone = Standard_True;
257 // boucle sur les listes des wires de 1 face de LRF
258 TopTools_ListOfShape myFaceLIE,myFaceLEE,myFaceLME,myFaceLW;
259 for (itt2.Initialize(mapWirLWir); itt2.More(); itt2.Next()) {
260 const TopoDS_Shape& wir = itt2.Key();
261 const TopTools_ListOfShape& LWir1 = mapWirLWir.Find(wir);
263 Standard_Integer n22 = LWir1.Extent();
265 // boucle sur 1 liste des wires avec edges communes.
266 TopTools_ListOfShape LEdg;
267 for(it3.Initialize(LWir1); it3.More(); it3.Next()) {
268 const TopoDS_Shape& wir1 = it3.Value();
271 for (exp.Init(wir1,TopAbs_EDGE); exp.More(); exp.Next()) {
272 const TopoDS_Shape& edg = exp.Current();
276 // listes des edges avec edges communes.
277 Keep_Edge = Standard_True;
278 TopTools_DataMapOfShapeListOfShape mapEdgLEdg;
279 GroupShape(LEdg,Keep_Edge,mapEdgLEdg);
280 if (mapEdgLEdg.IsEmpty()) {
282 if (trc) cout<<" TopOpeBRepBuild_FuseFace::PerformFace : Empty list of edges"<<endl;
284 myModified = Standard_False;
285 myDone = Standard_True;
290 // Elimination selon logique pure
291 // boucle sur les listes des egdes de 1 wire de 1 face de LRF
292 TopTools_ListOfShape myWireLE;
293 for (itt3.Initialize(mapEdgLEdg); itt3.More(); itt3.Next()) {
294 const TopoDS_Shape& edg = itt3.Key();
295 const TopTools_ListOfShape& LEdg1 = mapEdgLEdg.Find(edg);
296 Standard_Boolean OriReversed = Standard_False;
297 Standard_Boolean OriForward = Standard_False;
298 Standard_Boolean OriInternal = Standard_False;
299 Standard_Boolean OriExternal = Standard_False;
300 for(it4.Initialize(LEdg1); it4.More(); it4.Next()) {
301 const TopoDS_Shape& edg1 = it4.Value();
302 ori1 = edg1.Orientation();
303 if (ori1 == TopAbs_REVERSED) {
306 if (trc) cout<<" TopOpeBRepBuild_FuseFace::PerformFace : Bad faces orientation"<<endl;
308 myModified = Standard_False;
309 myDone = Standard_True;
313 OriReversed = Standard_True;
315 else if (ori1 == TopAbs_FORWARD) {
318 if (trc) cout<<" TopOpeBRepBuild_FuseFace::PerformFace : Bad faces orientation"<<endl;
320 myModified = Standard_False;
321 myDone = Standard_True;
325 OriForward = Standard_True;
327 else if (ori1 == TopAbs_INTERNAL) {
328 OriInternal = Standard_True;
330 else if (ori1 == TopAbs_EXTERNAL) {
331 OriExternal = Standard_True;
335 // - Traitement edge selon orientation
336 // On privilegie orientation selon 1) reversed ou forward
339 // pour traiter cas ou l'on a au moins 2 orientations differentes parmi
340 // forward et reversed - interne - externe
342 if (OriReversed || OriForward) {
343 if (OriReversed && OriForward) {
344 // TopoDS_Shape& edg1 = edg.Oriented(TopAbs_INTERNAL);
345 const TopoDS_Shape& edg1 = edg.Oriented(TopAbs_INTERNAL);
347 myFaceLME.Append(edg1);
348 } else if (OriReversed) {
349 // TopoDS_Shape& edg1 = edg.Oriented(TopAbs_REVERSED);
350 const TopoDS_Shape& edg1 = edg.Oriented(TopAbs_REVERSED);
351 myWireLE.Append(edg1);
353 // TopoDS_Shape& edg1 = edg.Oriented(TopAbs_FORWARD);
354 const TopoDS_Shape& edg1 = edg.Oriented(TopAbs_FORWARD);
355 myWireLE.Append(edg1);
358 else if (OriInternal) {
359 // TopoDS_Shape& edg1 = edg.Oriented(TopAbs_INTERNAL);
360 const TopoDS_Shape& edg1 = edg.Oriented(TopAbs_INTERNAL);
362 myFaceLIE.Append(edg1);
364 else if (OriExternal) {
365 // TopoDS_Shape& edg1 = edg.Oriented(TopAbs_EXTERNAL);
366 const TopoDS_Shape& edg1 = edg.Oriented(TopAbs_EXTERNAL);
368 myFaceLEE.Append(edg1);
372 // Reconstrution de 1 wire de 1 face de LRF
373 // Attention cas ou une liste de wire connectes conduit a plusieurs Wires
374 Standard_Integer number1 = myWireLE.Extent();
375 while (number1 > 0) {
380 if (trc) cout<<" TopOpeBRepBuild_FuseFace::PerformFace : Failure in making wire"<<endl;
382 myModified = Standard_False;
383 myDone = Standard_True;
388 // Astuce pour contourner Wire Not Closed
389 TopoDS_Wire W = MW.Wire();
390 BRepLib_MakeWire MW1(W);
396 TopTools_MapOfShape M;
397 Standard_Integer nb = 0;
398 for (exp.Init(W,TopAbs_EDGE); exp.More(); exp.Next()) {
399 const TopoDS_Shape& edg3 = exp.Current();
408 TopTools_ListOfShape ListEdge;
409 for(it3.Initialize(myWireLE); it3.More(); it3.Next()) {
410 const TopoDS_Shape& edg2 = it3.Value();
412 ListEdge.Append(edg2);
415 myWireLE.Assign(ListEdge);
416 number1 = myWireLE.Extent();
421 myFaceLW.Append(wir);
425 // Reconstrution de 1 face de LRF
426 Handle(Geom_Surface) S = BRep_Tool::Surface(facref);
427 if (S->DynamicType() ==
428 STANDARD_TYPE(Geom_RectangularTrimmedSurface)) {
429 S = Handle(Geom_RectangularTrimmedSurface)::
430 DownCast(S)->BasisSurface();
432 BRepLib_MakeFace MF(S, Precision::Confusion());
434 for(it2.Initialize(myFaceLW); it2.More(); it2.Next()) {
435 const TopoDS_Wire& wir1 = TopoDS::Wire(it2.Value());
439 // Ajout des Edges Internes
442 for (it2.Initialize(myFaceLIE); it2.More(); it2.Next()) {
443 const TopoDS_Edge& edg1 = TopoDS::Edge(it2.Value());
444 BRepLib_MakeWire MW(edg1);
446 const TopoDS_Wire& W = MW.Wire();
449 for (it2.Initialize(myFaceLEE); it2.More(); it2.Next()) {
450 const TopoDS_Edge& edg1 = TopoDS::Edge(it2.Value());
451 BRepLib_MakeWire MW(edg1);
453 const TopoDS_Wire& W = MW.Wire();
457 for (it2.Initialize(myFaceLME); it2.More(); it2.Next()) {
458 const TopoDS_Edge& edg1 = TopoDS::Edge(it2.Value());
459 BRepLib_MakeWire MW(edg1);
461 const TopoDS_Wire& W = MW.Wire();
468 if (trc) cout<<" TopOpeBRepBuild_FuseFace::PerformFace : Failure in making face"<<endl;
470 myModified = Standard_False;
471 myDone = Standard_True;
475 TopoDS_Face F = MF.Face();
482 myLFF.Append(facref);
486 if (myLFF.IsEmpty()) {
488 if (trc) cout<<" TopOpeBRepBuild_FuseFace::PerformFace : Empty list of fusionned faces"<<endl;
490 myModified = Standard_False;
491 myDone = Standard_True;
496 myModified = Standard_True;
497 myDone = Standard_True;
500 if (trc) cout << " TopOpeBRepBuild_FuseFace::PerformFace() : Done" << endl;
504 //=======================================================================
505 //function : PerformEdge
506 //purpose : fusion des edges cosurfaciques, connexes par une ou
508 //=======================================================================
510 void TopOpeBRepBuild_FuseFace::PerformEdge()
513 Standard_Boolean trc = TopOpeBRepBuild_GettraceFUFA();
514 if (trc) cout << "TopOpeBRepBuild_FuseFace::PerformEdge()" << endl;
516 TopTools_DataMapOfShapeListOfShape mapVerLEdg,mapTampon;
518 TopTools_ListIteratorOfListOfShape it1;
519 TopTools_DataMapIteratorOfDataMapOfShapeListOfShape itt1;
520 // TopAbs_Orientation ori,ori1;
523 //boucle sur les listes des faces de 1 face de LRF
525 for (it1.Initialize(myLFF); it1.More(); it1.Next()) {
526 const TopoDS_Shape& fac = it1.Value();
528 TopExp_Explorer expw;
529 for (expw.Init(fac,TopAbs_WIRE); expw.More(); expw.Next()) {
530 const TopoDS_Shape& wir = expw.Current();
532 TopExp_Explorer expe;
533 for (expe.Init(wir,TopAbs_EDGE); expe.More(); expe.Next()) {
534 const TopoDS_Shape& edg = expe.Current();
536 TopExp_Explorer expv;
537 for (expv.Init(edg,TopAbs_VERTEX); expv.More(); expv.Next()) {
538 const TopoDS_Shape& ver = expv.Current();
539 if (!mapVerLEdg.IsBound(ver)) {
540 TopTools_ListOfShape LmapEdg;
542 mapVerLEdg.Bind(ver,LmapEdg);
545 TopTools_ListOfShape& LmapEdg = mapVerLEdg.ChangeFind(ver);
553 //nettoyage du tableau mapVerLSh : shap1 : shap1 shap2 shap3
554 //On ne garde que les vertex qui appartiennent a - exactement 2 edges
555 // - de meme support geometrique
556 mapTampon = mapVerLEdg;
559 for (itt1.Initialize(mapTampon); itt1.More(); itt1.Next()) {
560 const TopoDS_Shape& ver = itt1.Key();
561 const TopTools_ListOfShape& LmapEdg = mapTampon.Find(ver);
562 Standard_Integer number = LmapEdg.Extent();
564 it1.Initialize(LmapEdg);
565 const TopoDS_Edge& edg1 = TopoDS::Edge(it1.Value());
567 const TopoDS_Edge& edg2 = TopoDS::Edge(it1.Value());
568 if (SameSupport(edg1,edg2)) {
569 mapVerLEdg.Bind(ver,LmapEdg);
574 //On regroupe ensemble tous les edges consecutifs et SameSupport
575 TopTools_DataMapOfShapeListOfShape mapEdgLEdg;
576 GroupEdge(mapVerLEdg,mapEdgLEdg);
578 //On construit les edges somme des edges consecutifs et SameSupport
579 MakeEdge(mapEdgLEdg);
581 myModified = Standard_True;
582 myDone = Standard_True;
585 if (trc) cout << " TopOpeBRepBuild_FuseFace::PerformEdge() : Done" << endl;
589 //=======================================================================
590 //function : ClearEdge
591 //purpose : Nettoyage des Faces : Suppression des edges internes et externes
592 //=======================================================================
594 void TopOpeBRepBuild_FuseFace::ClearEdge()
597 Standard_Boolean trc = TopOpeBRepBuild_GettraceFUFA();
598 if (trc) cout << "TopOpeBRepBuild_FuseFace::ClearEdge()" << endl;
601 TopTools_ListIteratorOfListOfShape it1,it2;
602 TopAbs_Orientation ori;
603 TopTools_ListOfShape myLFFnew;
606 //boucle sur les listes des faces de 1 face de LRF
608 for (it1.Initialize(myLFF); it1.More(); it1.Next()) {
609 const TopoDS_Shape& fac = it1.Value();
611 TopTools_ListOfShape myFaceLW;
612 TopExp_Explorer expw;
613 for (expw.Init(fac,TopAbs_WIRE); expw.More(); expw.Next()) {
614 const TopoDS_Shape& wir = expw.Current();
616 TopTools_ListOfShape myWireLE;
617 TopExp_Explorer expe;
618 for (expe.Init(wir,TopAbs_EDGE); expe.More(); expe.Next()) {
619 const TopoDS_Shape& edg = expe.Current();
621 // Elimination selon des edges interne et externe
623 ori = edg.Orientation();
624 if (ori == TopAbs_INTERNAL) {
627 else if (ori == TopAbs_EXTERNAL) {
631 myWireLE.Append(edg);
635 // Reconstrution de 1 wire de 1 face de LRF
636 if (!myWireLE.IsEmpty()) {
641 if (trc) cout<<" TopOpeBRepBuild_FuseFace::ClearEdge : Failure in making wire"<<endl;
643 myModified = Standard_False;
644 myDone = Standard_True;
649 // Astuce pour contourner Wire Not Closed
650 TopoDS_Wire W = MW.Wire();
651 BRepLib_MakeWire MW1(W);
658 // Reconstrution de 1 face de LRF
659 if (myFaceLW.IsEmpty()) {
661 if (trc) cout<<" TopOpeBRepBuild_FuseFace::ClearEdge : Empty list of wires"<<endl;
663 myModified = Standard_False;
664 myDone = Standard_True;
668 it2.Initialize(myFaceLW);
669 const TopoDS_Wire& wir = TopoDS::Wire(it2.Value());
670 const Standard_Boolean OnlyPlane = Standard_False;
671 BRepLib_MakeFace MF(wir,OnlyPlane);
674 for( ; it2.More(); it2.Next()) {
675 const TopoDS_Wire& wir1 = TopoDS::Wire(it2.Value());
680 if (trc) cout<<" TopOpeBRepBuild_FuseFace::ClearEdge : Failure in making face"<<endl;
682 myModified = Standard_False;
683 myDone = Standard_True;
687 const TopoDS_Face& F = MF.Face();
691 if (myLFFnew.IsEmpty()) {
693 if (trc) cout<<" TopOpeBRepBuild_FuseFace::ClearEdge : Empty list of fusionned faces"<<endl;
695 myModified = Standard_False;
696 myDone = Standard_True;
702 myModified = Standard_True;
703 myDone = Standard_True;
706 if (trc) cout << " TopOpeBRepBuild_FuseFace::ClearEdge() : Done" << endl;
710 //=======================================================================
711 //function : ClearVertex
712 //purpose : Nettoyage des Faces : Suppression des vertex internes et externes
713 //=======================================================================
715 void TopOpeBRepBuild_FuseFace::ClearVertex()
718 Standard_Boolean trc = TopOpeBRepBuild_GettraceFUFA();
719 if (trc) cout << "TopOpeBRepBuild_FuseFace::ClearVertex()" << endl;
723 if (trc) cout << " TopOpeBRepBuild_FuseFace::ClearVertex() : Done" << endl;
727 //=======================================================================
728 //function : GroupShape
730 //=======================================================================
732 static void GroupShape(TopTools_ListOfShape& mylist,Standard_Boolean Keep_Edge, TopTools_DataMapOfShapeListOfShape& mymapShLSh)
734 TopTools_ListIteratorOfListOfShape it,it1,it2;
735 TopTools_DataMapOfShapeListOfShape mapEdgLSh,mapShLSh;
736 TopTools_ListOfShape LmapSh4;
737 TopAbs_Orientation ori;
739 // construction du tableau C=locmapEdgLSh : egde1 - shap1 shap2 shap3
740 // construction du tableau locmapShLSh : shap1 - shap1 shap2 shap3
742 for(it.Initialize(mylist); it.More(); it.Next()) {
743 const TopoDS_Shape& shap1 = it.Value();
744 TopTools_ListOfShape LmapSh;
745 LmapSh.Append(shap1);
747 mapShLSh.Bind(shap1,LmapSh);
749 TopExp_Explorer expe;
750 for (expe.Init(shap1,TopAbs_EDGE); expe.More(); expe.Next()) {
751 const TopoDS_Shape& edg1 = expe.Current();
752 // verification si Edge a prendre en compte
753 ori = edg1.Orientation();
754 Standard_Boolean Edge_OK = Standard_True;
755 if (ori == TopAbs_INTERNAL || ori == TopAbs_EXTERNAL) {
756 Edge_OK = Standard_False;
758 if (Edge_OK || Keep_Edge) {
759 if (!mapEdgLSh.IsBound(edg1)) {
760 TopTools_ListOfShape LmapEdg;
761 LmapEdg.Append(shap1);
762 mapEdgLSh.Bind(edg1,LmapEdg);
765 TopTools_ListOfShape& LmapEdg = mapEdgLSh.ChangeFind(edg1);
766 LmapEdg.Append(shap1);
770 // Recuperation premier shape de liste liee a edg1
771 it1.Initialize(LmapEdg);
772 const TopoDS_Shape& shap2 = it1.Value();
774 // Controle si premier shape et shape courant sont deja lies
775 TopTools_ListOfShape LmapSh1;
776 LmapSh1 = mapShLSh.Find(shap2);
777 for(it1.Initialize(LmapSh1); it1.More(); it1.Next()) {
778 const TopoDS_Shape& shap = it1.Value();
779 if (shap.IsSame(shap1)) {
783 // Premier shape et Shape courant ne sont pas deja lies
785 const TopTools_ListOfShape& LmapSh11 = mapShLSh.Find(shap1);
786 const TopTools_ListOfShape& LmapSh2 = mapShLSh.Find(shap2);
787 TopTools_ListOfShape Lmap1;
788 TopTools_ListOfShape Lmap2;
789 Lmap1.Assign(LmapSh11);
790 Lmap2.Assign(LmapSh2);
792 for(it2.Initialize(Lmap1); it2.More(); it2.Next()) {
793 const TopoDS_Shape& shap = it2.Value();
794 TopTools_ListOfShape& Lmap = mapShLSh.ChangeFind(shap);
795 TopTools_ListOfShape Lmap3;
799 for(it2.Initialize(Lmap2); it2.More(); it2.Next()) {
800 const TopoDS_Shape& shap = it2.Value();
801 TopTools_ListOfShape& Lmap = mapShLSh.ChangeFind(shap);
802 TopTools_ListOfShape Lmap3;
813 // nettoyage du tableau mapShLSh : shap1 : shap1 shap2 shap3
816 TopTools_DataMapIteratorOfDataMapOfShapeListOfShape itt;
818 TopTools_MapOfShape M;
819 for (itt.Initialize(mapShLSh); itt.More(); itt.Next()) {
820 const TopoDS_Shape& shap1 = itt.Key();
822 const TopTools_ListOfShape& LmapSh = mapShLSh.Find(shap1);
823 mymapShLSh.Bind(shap1,LmapSh);
825 for(it1.Initialize(LmapSh); it1.More(); it1.Next()) {
826 const TopoDS_Shape& shap2 = it1.Value();
833 mymapShLSh = mapEdgLSh;
837 //=======================================================================
838 //function : GroupEdge
840 //=======================================================================
842 static void GroupEdge(TopTools_DataMapOfShapeListOfShape& mymapVerLEdg, TopTools_DataMapOfShapeListOfShape& mymapEdgLEdg)
844 TopTools_ListIteratorOfListOfShape it1,it2;
845 TopTools_DataMapIteratorOfDataMapOfShapeListOfShape itt;
846 TopTools_DataMapOfShapeListOfShape mapEdgLEdg;
848 // construction du tableau C=locmapEdgLSh : egde1 - shap1 shap2 shap3
849 // construction du tableau locmapShLSh : shap1 - shap1 shap2 shap3
850 for(itt.Initialize(mymapVerLEdg); itt.More(); itt.Next()) {
851 const TopoDS_Shape& ver1 = itt.Key();
852 TopTools_ListOfShape LmapEdg;
853 LmapEdg = mymapVerLEdg.Find(ver1);
855 it1.Initialize(LmapEdg);
856 const TopoDS_Edge& edg1 = TopoDS::Edge(it1.Value());
858 const TopoDS_Edge& edg2 = TopoDS::Edge(it1.Value());
860 Standard_Boolean Edge1Add,Edge2Add;
861 TopoDS_Edge edgold,edgnew;
862 if (mapEdgLEdg.IsBound(edg1)) {
863 Edge1Add = Standard_False;
866 Edge1Add = Standard_True;
869 if (mapEdgLEdg.IsBound(edg2)) {
870 Edge2Add = Standard_False;
873 Edge2Add = Standard_True;
877 if (!(Edge1Add || Edge2Add)) {
880 else if (Edge1Add && Edge2Add) {
881 mapEdgLEdg.Bind(edg1,LmapEdg);
882 mapEdgLEdg.Bind(edg2,LmapEdg);
887 // Recuperation premier shape de liste liee a edg1 et mise a jour
889 TopTools_ListOfShape LmapEdg11;
890 LmapEdg11.Append(edgnew);
891 mapEdgLEdg.Bind(edgnew,LmapEdg11);
893 TopTools_ListOfShape LmapEdg1;
894 LmapEdg1 = mapEdgLEdg.Find(edgold);
896 for(it2.Initialize(LmapEdg1); it2.More(); it2.Next()) {
897 const TopoDS_Shape& edg22 = it2.Value();
898 TopTools_ListOfShape& LmapEdg2 = mapEdgLEdg.ChangeFind(edgnew);
899 LmapEdg2.Append(edg22);
900 TopTools_ListOfShape& LmapEdg3 = mapEdgLEdg.ChangeFind(edg22);
901 LmapEdg3.Append(edgnew);
906 // nettoyage du tableau mapEdgLedg : edg1 : edg1 edg2 edg3
908 TopTools_MapOfShape M;
910 for (itt.Initialize(mapEdgLEdg); itt.More(); itt.Next()) {
911 const TopoDS_Shape& edg1 = itt.Key();
913 const TopTools_ListOfShape& LmapEdg = mapEdgLEdg.Find(edg1);
914 mymapEdgLEdg.Bind(edg1,LmapEdg);
916 for(it1.Initialize(LmapEdg); it1.More(); it1.Next()) {
917 const TopoDS_Shape& edg2 = it1.Value();
924 //=======================================================================
925 //function : MakeEdge
927 //=======================================================================
929 static void MakeEdge(TopTools_DataMapOfShapeListOfShape& mymapEdgLEdg)
932 Standard_Boolean trc = TopOpeBRepBuild_GettraceFUFA();
935 TopTools_ListIteratorOfListOfShape it;
936 TopTools_DataMapIteratorOfDataMapOfShapeListOfShape itt1;
937 TopTools_DataMapIteratorOfDataMapOfShapeInteger itt2;
938 TopTools_DataMapOfShapeListOfShape mapEdgLEdg;
940 // construction du tableau C=locmapEdgLSh : egde1 - shap1 shap2 shap3
941 // construction du tableau locmapShLSh : shap1 - shap1 shap2 shap3
942 for(itt1.Initialize(mymapEdgLEdg); itt1.More(); itt1.Next()) {
943 const TopoDS_Shape& edg1 = itt1.Key();
944 TopTools_ListOfShape LmapEdg;
945 LmapEdg = mymapEdgLEdg.Find(edg1);
946 TopTools_DataMapOfShapeInteger mapVerInt;
948 Standard_Integer VertexExtrem;
950 for(it.Initialize(LmapEdg); it.More(); it.Next()) {
951 const TopoDS_Edge& edg2 = TopoDS::Edge(it.Value());
953 TopExp_Explorer expv;
954 for (expv.Init(edg2,TopAbs_VERTEX); expv.More(); expv.Next()) {
955 const TopoDS_Shape& ver = expv.Current();
958 if (mapVerInt.IsBound(ver)) {
961 mapVerInt.Bind(ver,VertexExtrem);
966 TopTools_ListOfShape myEdgeLV,myEdgeLMV;
967 for(itt2.Initialize(mapVerInt); itt2.More(); itt2.Next()) {
968 const TopoDS_Shape& ver = itt2.Key();
969 VertexExtrem = mapVerInt.Find(ver);
970 if (VertexExtrem == 1) {
971 myEdgeLV.Append(ver);
974 // TopoDS_Shape& ver1 = ver.Oriented(TopAbs_INTERNAL);
975 const TopoDS_Shape& ver1 = ver.Oriented(TopAbs_INTERNAL);
976 myEdgeLMV.Append(ver1);
979 Standard_Integer number = myEdgeLV.Extent();
982 if (trc) cout<<" TopOpeBRepBuild_FuseFace::MakeEdge : Failure in reconstructing new edge"<<endl;
986 it.Initialize(myEdgeLV);
987 const TopoDS_Vertex& ver1 = TopoDS::Vertex(it.Value());
988 // TopoDS_Shape& verf = ver1.Oriented(TopAbs_FORWARD);
989 const TopoDS_Shape& verf = ver1.Oriented(TopAbs_FORWARD);
991 const TopoDS_Vertex& ver2 = TopoDS::Vertex(it.Value());
992 // TopoDS_Shape& verl = ver2.Oriented(TopAbs_FORWARD);
993 const TopoDS_Shape& verl = ver2.Oriented(TopAbs_FORWARD);
995 Handle(Geom_Curve) curv;
996 const TopoDS_Edge& edg = TopoDS::Edge(edg1);
998 Standard_Real first,last;
999 curv = BRep_Tool::Curve(edg,loc,first,last);
1001 BRepLib_MakeEdge ME(curv,TopoDS::Vertex(verf),TopoDS::Vertex(verl));
1002 const TopoDS_Edge& edgnew = ME.Edge();
1004 // if (myInternal) {
1005 // for (it.Initialize(myEdgeLMV); it.More(); it.Next()) {
1006 // const TopoDS_Vertex& ver1 = TopoDS::Vertex(it.Value());
1008 // B.MakeEdge(edgnew);
1009 // B.Add(edgnew,ver1);
1012 mapEdgLEdg.Bind(edgnew,LmapEdg);
1015 mymapEdgLEdg = mapEdgLEdg;
1018 //=======================================================================
1019 //function : SameSupport
1020 //purpose : Edges SameSupport ou pas
1021 //=======================================================================
1023 Standard_Boolean SameSupport(const TopoDS_Edge& E1,
1024 const TopoDS_Edge& E2)
1027 Standard_Boolean trc = TopOpeBRepBuild_GettraceFUFA();
1030 if (E1.IsNull() || E2.IsNull()) {
1031 return Standard_False;
1035 Handle(Geom_Curve) C1,C2;
1036 TopLoc_Location loc;
1037 Standard_Real f1,l1,f2,l2;
1038 Handle(Standard_Type) typC1,typC2;
1040 C1 = BRep_Tool::Curve(E1,loc,f1,l1);
1041 if (!loc.IsIdentity()) {
1042 Handle(Geom_Geometry) GG1 = C1->Transformed(loc.Transformation());
1043 C1 = Handle(Geom_Curve)::DownCast (GG1);
1045 C2 = BRep_Tool::Curve(E2,loc,f2,l2);
1046 if (!loc.IsIdentity()) {
1047 Handle(Geom_Geometry) GG2 = C2->Transformed(loc.Transformation());
1048 C2 = Handle(Geom_Curve)::DownCast (GG2);
1051 typC1 = C1->DynamicType();
1052 typC2 = C2->DynamicType();
1054 if (typC1 == STANDARD_TYPE(Geom_TrimmedCurve)) {
1055 C1 = Handle(Geom_TrimmedCurve)::DownCast (C1)->BasisCurve();
1056 typC1 = C1->DynamicType();
1059 if (typC2 == STANDARD_TYPE(Geom_TrimmedCurve)) {
1060 C2 = Handle(Geom_TrimmedCurve)::DownCast (C2)->BasisCurve();
1061 typC2 = C2->DynamicType();
1064 if (typC1 != typC2) {
1065 return Standard_False;
1068 if (typC1 != STANDARD_TYPE(Geom_Line) &&
1069 typC1 != STANDARD_TYPE(Geom_Circle) &&
1070 typC1 != STANDARD_TYPE(Geom_Ellipse) &&
1071 typC1 != STANDARD_TYPE(Geom_BSplineCurve) &&
1072 typC1 != STANDARD_TYPE(Geom_BezierCurve)) {
1074 if (trc) cout << " TopOpeBRepBuild_FuseFace : Type de Support non traite" << endl;
1076 return Standard_False;
1079 // On a presomption de confusion
1080 const Standard_Real tollin = Precision::Confusion();
1081 const Standard_Real tolang = Precision::Angular();
1082 if (typC1 == STANDARD_TYPE(Geom_Line)) {
1083 gp_Lin li1( Handle(Geom_Line)::DownCast (C1)->Lin());
1084 gp_Lin li2( Handle(Geom_Line)::DownCast (C2)->Lin());
1086 if (Abs(li1.Angle(li2)) <= tolang &&
1087 li1.Location().SquareDistance(li2.Location()) <= tollin*tollin) {
1088 return Standard_True;
1090 return Standard_False;
1092 else if (typC1 == STANDARD_TYPE(Geom_Circle)) {
1093 gp_Circ ci1 = Handle(Geom_Circle)::DownCast (C1)->Circ();
1094 gp_Circ ci2 = Handle(Geom_Circle)::DownCast (C2)->Circ();
1095 if (Abs(ci1.Radius()-ci2.Radius()) <= tollin &&
1096 ci1.Location().SquareDistance(ci2.Location()) <= tollin*tollin) {
1097 // Point debut, calage dans periode, et detection meme sens
1098 return Standard_True;
1100 return Standard_False;
1102 else if (typC1 == STANDARD_TYPE(Geom_Ellipse)) {
1103 gp_Elips ci1 = Handle(Geom_Ellipse)::DownCast (C1)->Elips();
1104 gp_Elips ci2 = Handle(Geom_Ellipse)::DownCast (C2)->Elips();
1106 if (Abs(ci1.MajorRadius()-ci2.MajorRadius()) <= tollin &&
1107 Abs(ci1.MinorRadius()-ci2.MinorRadius()) <= tollin &&
1108 ci1.Location().SquareDistance(ci2.Location()) <= tollin*tollin) {
1109 // Point debut, calage dans periode, et detection meme sens
1110 return Standard_True;
1112 return Standard_False;
1114 else if (typC1 == STANDARD_TYPE(Geom_BSplineCurve)) {
1115 Handle(Geom_BSplineCurve) B1 = Handle(Geom_BSplineCurve)::DownCast (C1);
1116 Handle(Geom_BSplineCurve) B2 = Handle(Geom_BSplineCurve)::DownCast (C2);
1118 Standard_Integer nbpoles = B1->NbPoles();
1119 if (nbpoles != B2->NbPoles()) {
1120 return Standard_False;
1123 Standard_Integer nbknots = B1->NbKnots();
1124 if (nbknots != B2->NbKnots()) {
1125 return Standard_False;
1128 TColgp_Array1OfPnt P1(1, nbpoles), P2(1, nbpoles);
1132 Standard_Real tol3d = BRep_Tool::Tolerance(E1);
1133 for (Standard_Integer p = 1; p <= nbpoles; p++) {
1134 if ( (P1(p)).Distance(P2(p)) > tol3d) {
1135 return Standard_False;
1139 TColStd_Array1OfReal K1(1, nbknots), K2(1, nbknots);
1143 TColStd_Array1OfInteger M1(1, nbknots), M2(1, nbknots);
1144 B1->Multiplicities(M1);
1145 B2->Multiplicities(M2);
1147 for (Standard_Integer k = 1; k <= nbknots; k++) {
1148 if ((K1(k)-K2(k)) > tollin) {
1149 return Standard_False;
1151 if (Abs(M1(k)-M2(k)) > tollin) {
1152 return Standard_False;
1156 if (!B1->IsRational()) {
1157 if (B2->IsRational()) {
1158 return Standard_False;
1162 if (!B2->IsRational()) {
1163 return Standard_False;
1167 if (B1->IsRational()) {
1168 TColStd_Array1OfReal W1(1, nbpoles), W2(1, nbpoles);
1172 for (Standard_Integer w = 1; w <= nbpoles; w++) {
1173 if (Abs(W1(w)-W2(w)) > tollin) {
1174 return Standard_False;
1178 return Standard_True;
1180 else if (typC1 == STANDARD_TYPE(Geom_BezierCurve)) {
1181 Handle(Geom_BezierCurve) B1 = Handle(Geom_BezierCurve)::DownCast (C1);
1182 Handle(Geom_BezierCurve) B2 = Handle(Geom_BezierCurve)::DownCast (C2);
1184 Standard_Integer nbpoles = B1->NbPoles();
1185 if (nbpoles != B2->NbPoles()) {
1186 return Standard_False;
1189 TColgp_Array1OfPnt P1(1, nbpoles), P2(1, nbpoles);
1193 for (Standard_Integer p = 1; p <= nbpoles; p++) {
1194 if ( (P1(p)).Distance(P2(p)) > tollin) {
1195 return Standard_False;
1199 if (!B1->IsRational()) {
1200 if (B2->IsRational()) {
1201 return Standard_False;
1205 if (!B2->IsRational()) {
1206 return Standard_False;
1210 if (B1->IsRational()) {
1211 TColStd_Array1OfReal W1(1, nbpoles), W2(1, nbpoles);
1215 for (Standard_Integer w = 1; w <= nbpoles; w++) {
1216 if (Abs(W1(w)-W2(w)) > tollin) {
1217 return Standard_False;
1221 return Standard_True;
1223 return Standard_False;