// Created on: 1993-08-10 // Created by: Christophe MARION // Copyright (c) 1993-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 #include #include #include #include #include #include #include #include #include #include #include #include #include #include //======================================================================= //function : Insert //purpose : explore the faces and insert them //======================================================================= void HLRTopoBRep_DSFiller::Insert (const TopoDS_Shape& S, Contap_Contour& FO, HLRTopoBRep_Data& DS, BRepTopAdaptor_MapOfShapeTool& MST, const Standard_Integer nbIso) { TopTools_MapOfShape ShapeMap; TopExp_Explorer ex(S,TopAbs_FACE); DS.Clear(); Standard_Boolean withPCurve = Standard_True; // instead of nbIso != 0; Standard_Integer f = 0; while (ex.More()) { if (ShapeMap.Add(ex.Current())) { f++; TopoDS_Face S1 = TopoDS::Face(ex.Current()); S1.Orientation(TopAbs_FORWARD); Handle(BRepTopAdaptor_TopolTool) Domain; Handle(Adaptor3d_HSurface) Surface; if(MST.IsBound(S1)) { BRepTopAdaptor_Tool& BRT = MST.ChangeFind(S1); Domain = BRT.GetTopolTool(); Surface = BRT.GetSurface(); } else { BRepTopAdaptor_Tool BRT(S1,Precision::PConfusion()); MST.Bind(S1,BRT); Domain = BRT.GetTopolTool(); Surface = BRT.GetSurface(); } FO.Perform(Surface, Domain); if (FO.IsDone()) { if (!FO.IsEmpty()) InsertFace(f,S1,FO,DS,withPCurve); } if (nbIso != 0) HLRTopoBRep_FaceIsoLiner::Perform(f,S1,DS,nbIso); } ex.Next(); } ProcessEdges(DS); } //======================================================================= //function : InsertFace //purpose : private, insert the outlines of a face //======================================================================= void HLRTopoBRep_DSFiller::InsertFace (const Standard_Integer /*FI*/, const TopoDS_Face& F, Contap_Contour& FO, HLRTopoBRep_Data& DS, const Standard_Boolean withPCurve) { // Insert the intersections of FO in DS const Standard_Real tol = BRep_Tool::Tolerance(F); TopTools_ListOfShape& IntL = DS.AddIntL(F); TopTools_ListOfShape& OutL = DS.AddOutL(F); TopoDS_Vertex VF,VL; /* TopTools_MapOfShape VM; TopExp_Explorer ex(F,TopAbs_EDGE); while (ex.More()) { const TopoDS_Edge& E = TopoDS::Edge(ex.Current()); if (BRep_Tool::IsClosed(E,F)) { TopExp::Vertices(E,VF,VL); VM.Add(VF); VM.Add(VL); } ex.Next(); } */ const Standard_Integer NbLines = FO.NbLines(); Standard_Integer CurLine; for (CurLine = 1; CurLine <= NbLines; CurLine++) { const Contap_Line& Line = FO.Line(CurLine); const Standard_Integer NbPoints = Line.NbVertex(); Standard_Integer CurPoint; if (Line.TypeContour() == Contap_Restriction) { // OutLine on restriction TopoDS_Edge E = (*(BRepAdaptor_Curve2d*)&(Line.Arc()->Curve2d())).Edge(); OutL.Append(E); TopExp::Vertices(E,VF,VL); // insert the Internal points. for (CurPoint = 1; CurPoint <= NbPoints; CurPoint++) { Contap_Point P = Line.Vertex(CurPoint); if (P.IsInternal()) { if (P.Value().IsEqual(BRep_Tool::Pnt(VF),BRep_Tool::Tolerance(VF))) { if (P.Value().IsEqual(BRep_Tool::Pnt(VL),BRep_Tool::Tolerance(VL))) { InsertVertex(P,tol,E,DS); } } } } } else { for (CurPoint = 1; CurPoint <= NbPoints; CurPoint++) { const Contap_Point PF = Line.Vertex(CurPoint); if (PF.IsInternal() && CurPoint != 1) VF = VL; else VF = MakeVertex(PF,tol,DS); const Standard_Real parF = PF.ParameterOnLine(); if (CurPoint < NbPoints) { const Contap_Point PL = Line.Vertex(CurPoint+1); VL = MakeVertex(PL,tol,DS); const Standard_Real parL = PL.ParameterOnLine(); if( (parL-parF) > Precision::PConfusion() ) { Handle(Geom_Curve) C; Handle(Geom2d_Curve) C2d; Standard_Real first = parF; Standard_Real last = parL; Standard_Boolean InsuffisantNumberOfPoints=Standard_False; switch (Line.TypeContour()) { case Contap_Lin : { C = new Geom_Line(Line.Line()); if (withPCurve) { Handle(Geom_Surface) S = BRep_Tool::Surface(F); Standard_Real Tol = 1e-7; C2d = GeomProjLib::Curve2d(C,first,last,S,Tol); } } break; case Contap_Circle : { C = new Geom_Circle(Line.Circle()); if (withPCurve) { TopLoc_Location Loc; Handle(Geom_Surface) S = BRep_Tool::Surface(F,Loc); if (!Loc.IsIdentity()) { S = Handle(Geom_Surface)::DownCast(S->Transformed(Loc.Transformation())); } Standard_Real Tol = 1e-7; C2d = GeomProjLib::Curve2d(C,first,last,S,Tol); } } break; case Contap_Walking : { // copy the points Standard_Integer ipF = Standard_Integer(parF); Standard_Integer ipL = Standard_Integer(parL); if(ipL-ipF < 1) { InsuffisantNumberOfPoints=Standard_True; //std::cout<<"\n !! Pb ds HLRTopoBRep_DSFiller.cxx (Contour App Nbp <3)"<Maxx) Maxx=P.X(); if(P.Y()>Maxy) Maxy=P.Y(); if(P.Z()>Maxz) Maxz=P.Z(); Points.SetValue(i,P); } mults(1)=mults(nbp)=2; Handle(Geom_BSplineCurve) AppC; Handle(Geom2d_BSplineCurve) AppC2d; AppC = new Geom_BSplineCurve(Points,knots,mults,1); if(withPCurve) { TColgp_Array1OfPnt2d Points2d(1,nbp); for(Standard_Integer i=1;i<=nbp;i++) { Standard_Real u,v; Line.Point(i+ipF-1).ParametersOnS2(u,v); if(uMaxu) Maxu=u; if(v>Maxv) Maxv=v; Points2d.SetValue(i,gp_Pnt2d(u,v)); } AppC2d = new Geom2d_BSplineCurve(Points2d,knots,mults,1); } first = 1; last = nbp; Handle(BRepApprox_ApproxLine) AppLine; Handle(Geom2d_BSplineCurve) CNull; AppLine = new BRepApprox_ApproxLine(AppC,AppC2d,CNull); Standard_Integer dmin=4,dmax=8,niter=0; Standard_Boolean tg= Standard_False; BRepApprox_Approx Approx; Standard_Real TOL3d,TOL2d,TOL=0.0001; Maxx-=Minx; Maxy-=Miny; Maxz-=Minz; Maxu-=Minu; Maxv-=Minv; if(Maxy>Maxx) Maxx=Maxy; if(Maxz>Maxx) Maxx=Maxy; if(Maxv>Maxu) Maxu=Maxv; TOL3d=TOL*Maxx; if(TOL3d<1e-12) TOL3d=1e-12; else if(TOL3d>0.1) TOL3d=0.1; TOL2d=TOL*Maxu; if(TOL2d<1e-12) TOL2d=1e-12; else if(TOL2d>0.1) TOL2d=0.1; //-- std::cout<<"\nHLRTopoBRep_DSFiller : nbp="<Vertex(); DS.AddOutV(V); } else { // if on arc, insert in the DS if (P.IsOnArc()) { const TopoDS_Edge& E = (*(BRepAdaptor_Curve2d*)&((P.Arc())->Curve2d())).Edge(); Standard_Real Par = P.ParameterOnArc(); const gp_Pnt& P3d = P.Value(); for (DS.InitVertex(E); DS.MoreVertex(); DS.NextVertex()) { TopoDS_Vertex curV = DS.Vertex(); Standard_Real curP = DS.Parameter(); const gp_Pnt& PPP=BRep_Tool::Pnt(curV); Standard_Real TTT=BRep_Tool::Tolerance(curV); if (P3d.IsEqual(PPP,TTT)) { V = curV; break; } else if (Par < curP) { B.MakeVertex(V,P.Value(),tol); DS.InsertBefore(V,Par); break; } } if (!DS.MoreVertex()) { B.MakeVertex(V,P.Value(),tol); DS.Append(V,Par); } DS.AddOutV(V); } // if internal create a vertex and insert in the DS else { B.MakeVertex(V,P.Value(),tol); if (P.IsInternal()) DS.AddIntV(V); else DS.AddOutV(V); } } return V; } //======================================================================= //function : InsertVertex //purpose : private, insert a vertex from an internal intersection point // on resctriction //======================================================================= void HLRTopoBRep_DSFiller::InsertVertex (const Contap_Point& P, const Standard_Real tol, const TopoDS_Edge& E, HLRTopoBRep_Data& DS) { BRep_Builder B; TopoDS_Vertex V; if (P.IsVertex()) { V = Handle(BRepTopAdaptor_HVertex)::DownCast(P.Vertex())->Vertex(); } else { Standard_Real Par = P.ParameterOnLine(); for (DS.InitVertex(E); DS.MoreVertex(); DS.NextVertex()) { TopoDS_Vertex curV = DS.Vertex(); Standard_Real curP = DS.Parameter(); if (P.Value().IsEqual(BRep_Tool::Pnt(curV), BRep_Tool::Tolerance(curV))) { V = curV; break; } else if (Par < curP) { B.MakeVertex(V,P.Value(),tol); DS.InsertBefore(V,Par); break; } } if (!DS.MoreVertex()) { B.MakeVertex(V,P.Value(),tol); DS.Append(V,Par); } } DS.AddIntV(V); } //======================================================================= //function : ProcessEdges //purpose : private, split edges with outline vertices //======================================================================= void HLRTopoBRep_DSFiller::ProcessEdges (HLRTopoBRep_Data& DS) { BRep_Builder B; TopoDS_Edge newE; TopoDS_Vertex VF,VL,VI; Standard_Real PF,PL,PI; for (DS.InitEdge(); DS.MoreEdge(); DS.NextEdge()) { TopoDS_Edge E = DS.Edge(); TopTools_ListOfShape& SplE = DS.AddSplE(E); VF = TopExp::FirstVertex(E); VL = TopExp::LastVertex(E); BRep_Tool::Range(E,PF,PL); VF.Orientation(TopAbs_FORWARD); VL.Orientation(TopAbs_REVERSED); for (DS.InitVertex(E); DS.MoreVertex(); DS.NextVertex()) { VI = DS.Vertex(); PI = DS.Parameter(); VI.Orientation(TopAbs_REVERSED); newE = E; newE.EmptyCopy(); newE.Orientation(TopAbs_FORWARD); B.Add(newE,VF); B.UpdateVertex(VF,PF,newE,BRep_Tool::Tolerance(VF)); B.Add(newE,VI); B.UpdateVertex(VI,PI,newE,BRep_Tool::Tolerance(VI)); newE.Orientation(E.Orientation()); SplE.Append(newE); VF = VI; PF = PI; VF.Orientation(TopAbs_FORWARD); } newE = E; newE.EmptyCopy(); newE.Orientation(TopAbs_FORWARD); B.Add(newE,VF); B.UpdateVertex(VF,PF,newE,BRep_Tool::Tolerance(VF)); B.Add(newE,VL); B.UpdateVertex(VL,PL,newE,BRep_Tool::Tolerance(VL)); newE.Orientation(E.Orientation()); SplE.Append(newE); } }