// Created on: 1998-07-28 // Created by: LECLERE Florence // Copyright (c) 1998-1999 Matra Datavision // Copyright (c) 1999-2014 OPEN CASCADE SAS // // This file is part of Open CASCADE Technology software library. // // This library is free software; you can redistribute it and/or modify it under // the terms of the GNU Lesser General Public License version 2.1 as published // by the Free Software Foundation, with special exception defined in the file // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT // distribution for complete text of the license and disclaimer of any warranty. // // Alternatively, this file may be used under the terms of Open CASCADE // commercial license or contractual agreement. #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #ifdef OCCT_DEBUG extern Standard_Boolean TopOpeBRepBuild_GettraceFUFA(); #endif static void GroupShape(TopTools_ListOfShape&, Standard_Boolean, TopTools_DataMapOfShapeListOfShape&); static void GroupEdge(TopTools_DataMapOfShapeListOfShape&, TopTools_DataMapOfShapeListOfShape&); static void MakeEdge(TopTools_DataMapOfShapeListOfShape&); static Standard_Boolean SameSupport(const TopoDS_Edge&, const TopoDS_Edge&); //======================================================================= //function : Init //purpose : //======================================================================= void TopOpeBRepBuild_FuseFace::Init(const TopTools_ListOfShape& LIF, const TopTools_ListOfShape& LRF, const Standard_Integer CXM) { #ifdef OCCT_DEBUG Standard_Boolean trc = TopOpeBRepBuild_GettraceFUFA(); if (trc) cout << "TopOpeBRepBuild_FuseFace::Init" << endl; #endif myLIF = LIF; myLRF = LRF; if(CXM == 1) { myInternal = Standard_False; } else if(CXM == 2) { myInternal = Standard_True; } // CXM #ifdef OCCT_DEBUG if (trc) { if (myInternal) { cout << " TopOpeBRepBuild_FuseFace::Init : Keep internal connections" << endl; } else { cout << " TopOpeBRepBuild_FuseFace::Init : Suppress internal connections" << endl; } } #endif myLFF.Clear(); myLIE.Clear(); myLEE.Clear(); myLME.Clear(); myLIV.Clear(); myLEV.Clear(); myLMV.Clear(); myModified = Standard_False; myDone = Standard_False; } //======================================================================= //function : PerformFace //purpose : fusion des faces cosurfaciques, connexes par une ou //plusieurs aretes //======================================================================= void TopOpeBRepBuild_FuseFace::PerformFace() { #ifdef OCCT_DEBUG Standard_Boolean trc = TopOpeBRepBuild_GettraceFUFA(); if (trc) cout << "TopOpeBRepBuild_FuseFace::PerformFace()" << endl; #endif myModified = Standard_False; myLFF.Clear(); if (myLRF.IsEmpty()) { #ifdef OCCT_DEBUG if (trc) cout<<" TopOpeBRepBuild_FuseFace::PerformFace : Empty list of reconstructed faces"< 0) { BRepLib_MakeWire MW; MW.Add(myWireLE); if (!MW.IsDone()) { #ifdef OCCT_DEBUG if (trc) cout<<" TopOpeBRepBuild_FuseFace::PerformFace : Failure in making wire"<DynamicType() == STANDARD_TYPE(Geom_RectangularTrimmedSurface)) { S = Handle(Geom_RectangularTrimmedSurface):: DownCast(S)->BasisSurface(); } BRepLib_MakeFace MF(S, Precision::Confusion()); for(it2.Initialize(myFaceLW); it2.More(); it2.Next()) { const TopoDS_Wire& wir1 = TopoDS::Wire(it2.Value()); MF.Add(wir1); } // Ajout des Edges Internes // Externes // Modifiees for (it2.Initialize(myFaceLIE); it2.More(); it2.Next()) { const TopoDS_Edge& edg1 = TopoDS::Edge(it2.Value()); BRepLib_MakeWire MW(edg1); // MW.Add(edg1); const TopoDS_Wire& W = MW.Wire(); MF.Add(W); } for (it2.Initialize(myFaceLEE); it2.More(); it2.Next()) { const TopoDS_Edge& edg1 = TopoDS::Edge(it2.Value()); BRepLib_MakeWire MW(edg1); // MW.Add(edg1); const TopoDS_Wire& W = MW.Wire(); MF.Add(W); } if (myInternal) { for (it2.Initialize(myFaceLME); it2.More(); it2.Next()) { const TopoDS_Edge& edg1 = TopoDS::Edge(it2.Value()); BRepLib_MakeWire MW(edg1); // MW.Add(edg1); const TopoDS_Wire& W = MW.Wire(); MF.Add(W); } } if (!MF.IsDone()) { #ifdef OCCT_DEBUG if (trc) cout<<" TopOpeBRepBuild_FuseFace::PerformFace : Failure in making face"<Transformed(loc.Transformation()); C1 = Handle(Geom_Curve)::DownCast (GG1); } C2 = BRep_Tool::Curve(E2,loc,f2,l2); if (!loc.IsIdentity()) { Handle(Geom_Geometry) GG2 = C2->Transformed(loc.Transformation()); C2 = Handle(Geom_Curve)::DownCast (GG2); } typC1 = C1->DynamicType(); typC2 = C2->DynamicType(); if (typC1 == STANDARD_TYPE(Geom_TrimmedCurve)) { C1 = Handle(Geom_TrimmedCurve)::DownCast (C1)->BasisCurve(); typC1 = C1->DynamicType(); } if (typC2 == STANDARD_TYPE(Geom_TrimmedCurve)) { C2 = Handle(Geom_TrimmedCurve)::DownCast (C2)->BasisCurve(); typC2 = C2->DynamicType(); } if (typC1 != typC2) { return Standard_False; } if (typC1 != STANDARD_TYPE(Geom_Line) && typC1 != STANDARD_TYPE(Geom_Circle) && typC1 != STANDARD_TYPE(Geom_Ellipse) && typC1 != STANDARD_TYPE(Geom_BSplineCurve) && typC1 != STANDARD_TYPE(Geom_BezierCurve)) { #ifdef OCCT_DEBUG if (trc) cout << " TopOpeBRepBuild_FuseFace : Type de Support non traite" << endl; #endif return Standard_False; } // On a presomption de confusion const Standard_Real tollin = Precision::Confusion(); const Standard_Real tolang = Precision::Angular(); if (typC1 == STANDARD_TYPE(Geom_Line)) { gp_Lin li1( Handle(Geom_Line)::DownCast (C1)->Lin()); gp_Lin li2( Handle(Geom_Line)::DownCast (C2)->Lin()); if (Abs(li1.Angle(li2)) <= tolang && li1.Location().SquareDistance(li2.Location()) <= tollin*tollin) { return Standard_True; } return Standard_False; } else if (typC1 == STANDARD_TYPE(Geom_Circle)) { gp_Circ ci1 = Handle(Geom_Circle)::DownCast (C1)->Circ(); gp_Circ ci2 = Handle(Geom_Circle)::DownCast (C2)->Circ(); if (Abs(ci1.Radius()-ci2.Radius()) <= tollin && ci1.Location().SquareDistance(ci2.Location()) <= tollin*tollin) { // Point debut, calage dans periode, et detection meme sens return Standard_True; } return Standard_False; } else if (typC1 == STANDARD_TYPE(Geom_Ellipse)) { gp_Elips ci1 = Handle(Geom_Ellipse)::DownCast (C1)->Elips(); gp_Elips ci2 = Handle(Geom_Ellipse)::DownCast (C2)->Elips(); if (Abs(ci1.MajorRadius()-ci2.MajorRadius()) <= tollin && Abs(ci1.MinorRadius()-ci2.MinorRadius()) <= tollin && ci1.Location().SquareDistance(ci2.Location()) <= tollin*tollin) { // Point debut, calage dans periode, et detection meme sens return Standard_True; } return Standard_False; } else if (typC1 == STANDARD_TYPE(Geom_BSplineCurve)) { Handle(Geom_BSplineCurve) B1 = Handle(Geom_BSplineCurve)::DownCast (C1); Handle(Geom_BSplineCurve) B2 = Handle(Geom_BSplineCurve)::DownCast (C2); Standard_Integer nbpoles = B1->NbPoles(); if (nbpoles != B2->NbPoles()) { return Standard_False; } Standard_Integer nbknots = B1->NbKnots(); if (nbknots != B2->NbKnots()) { return Standard_False; } TColgp_Array1OfPnt P1(1, nbpoles), P2(1, nbpoles); B1->Poles(P1); B2->Poles(P2); Standard_Real tol3d = BRep_Tool::Tolerance(E1); for (Standard_Integer p = 1; p <= nbpoles; p++) { if ( (P1(p)).Distance(P2(p)) > tol3d) { return Standard_False; } } TColStd_Array1OfReal K1(1, nbknots), K2(1, nbknots); B1->Knots(K1); B2->Knots(K2); TColStd_Array1OfInteger M1(1, nbknots), M2(1, nbknots); B1->Multiplicities(M1); B2->Multiplicities(M2); for (Standard_Integer k = 1; k <= nbknots; k++) { if ((K1(k)-K2(k)) > tollin) { return Standard_False; } if (Abs(M1(k)-M2(k)) > tollin) { return Standard_False; } } if (!B1->IsRational()) { if (B2->IsRational()) { return Standard_False; } } else { if (!B2->IsRational()) { return Standard_False; } } if (B1->IsRational()) { TColStd_Array1OfReal W1(1, nbpoles), W2(1, nbpoles); B1->Weights(W1); B2->Weights(W2); for (Standard_Integer w = 1; w <= nbpoles; w++) { if (Abs(W1(w)-W2(w)) > tollin) { return Standard_False; } } } return Standard_True; } else if (typC1 == STANDARD_TYPE(Geom_BezierCurve)) { Handle(Geom_BezierCurve) B1 = Handle(Geom_BezierCurve)::DownCast (C1); Handle(Geom_BezierCurve) B2 = Handle(Geom_BezierCurve)::DownCast (C2); Standard_Integer nbpoles = B1->NbPoles(); if (nbpoles != B2->NbPoles()) { return Standard_False; } TColgp_Array1OfPnt P1(1, nbpoles), P2(1, nbpoles); B1->Poles(P1); B2->Poles(P2); for (Standard_Integer p = 1; p <= nbpoles; p++) { if ( (P1(p)).Distance(P2(p)) > tollin) { return Standard_False; } } if (!B1->IsRational()) { if (B2->IsRational()) { return Standard_False; } } else { if (!B2->IsRational()) { return Standard_False; } } if (B1->IsRational()) { TColStd_Array1OfReal W1(1, nbpoles), W2(1, nbpoles); B1->Weights(W1); B2->Weights(W2); for (Standard_Integer w = 1; w <= nbpoles; w++) { if (Abs(W1(w)-W2(w)) > tollin) { return Standard_False; } } } return Standard_True; } return Standard_False; }