// Created on: 1996-01-11 // Created by: Jacques GOUSSARD // Copyright (c) 1996-1999 Matra Datavision // Copyright (c) 1999-2012 OPEN CASCADE SAS // // The content of this file is subject to the Open CASCADE Technology Public // License Version 6.5 (the "License"). You may not use the content of this file // except in compliance with the License. Please obtain a copy of the License // at http://www.opencascade.org and read it completely before using this file. // // The Initial Developer of the Original Code is Open CASCADE S.A.S., having its // main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France. // // The Original Code and all software distributed under the License is // distributed on an "AS IS" basis, without warranty of any kind, and the // Initial Developer hereby disclaims all such warranties, including without // limitation, any warranties of merchantability, fitness for a particular // purpose or non-infringement. Please see the License for the specific terms // and conditions governing the rights and limitations under the License. #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 static Standard_Boolean Project(const TopoDS_Vertex&, const TopoDS_Face&, TopoDS_Edge&, Standard_Real&); static Standard_Real Project(const TopoDS_Vertex&, const TopoDS_Edge&); static void PutPCurve(const TopoDS_Edge&, const TopoDS_Face&); static void PutPCurves(const TopoDS_Edge&, const TopoDS_Edge&, const TopoDS_Shape&); static void FindInternalIntersections(const TopoDS_Edge&, const TopoDS_Face&, TopTools_IndexedDataMapOfShapeListOfShape&, TopTools_DataMapOfShapeShape&, TopTools_MapOfShape&); //======================================================================= //function : LocOpe_WiresOnShape //purpose : //======================================================================= LocOpe_WiresOnShape::LocOpe_WiresOnShape(const TopoDS_Shape& S): myShape(S),myDone(Standard_False) {} //======================================================================= //function : Init //purpose : //======================================================================= void LocOpe_WiresOnShape::Init(const TopoDS_Shape& S) { myShape = S; myDone = Standard_False; myMap.Clear(); myMapEF.Clear(); } //======================================================================= //function : Bind //purpose : //======================================================================= void LocOpe_WiresOnShape::Bind(const TopoDS_Wire& W, const TopoDS_Face& F) { for (TopExp_Explorer exp(W, TopAbs_EDGE); exp.More(); exp.Next()) { Bind(TopoDS::Edge(exp.Current()),F); } } //======================================================================= //function : Bind //purpose : //======================================================================= void LocOpe_WiresOnShape::Bind(const TopoDS_Compound& Comp, const TopoDS_Face& F) { for (TopExp_Explorer exp(Comp, TopAbs_EDGE); exp.More(); exp.Next()) { Bind(TopoDS::Edge(exp.Current()),F); } myFacesWithSection.Add(F); } //======================================================================= //function : Bind //purpose : //======================================================================= void LocOpe_WiresOnShape::Bind(const TopoDS_Edge& E, const TopoDS_Face& F) { // if (!myMapEF.IsBound(E)) { if (!myMapEF.Contains(E)) { // for (TopExp_Explorer exp(F,TopAbs_EDGE);exp.More();exp.Next()) { TopExp_Explorer exp(F,TopAbs_EDGE) ; for ( ;exp.More();exp.Next()) { if (exp.Current().IsSame(E)) { break; } } if (!exp.More()) { // myMapEF.Bind(E,F); myMapEF.Add(E,F); } } else { Standard_ConstructionError::Raise(); } } //======================================================================= //function : Bind //purpose : //======================================================================= void LocOpe_WiresOnShape::Bind(const TopoDS_Edge& Ewir, const TopoDS_Edge& Efac) { if (Ewir.IsSame(Efac)) { return; } myMap.Bind(Ewir,Efac); } //======================================================================= //function : BindAll //purpose : //======================================================================= void LocOpe_WiresOnShape::BindAll() { if (myDone) { return; } TopTools_MapOfShape theMap; // Detection des vertex a projeter ou a "binder" avec des vertex existants TopTools_DataMapOfShapeShape mapV; TopTools_DataMapIteratorOfDataMapOfShapeShape ite(myMap); TopExp_Explorer exp,exp2; for (; ite.More(); ite.Next()) { const TopoDS_Edge& eref = TopoDS::Edge(ite.Key()); const TopoDS_Edge& eimg = TopoDS::Edge(ite.Value()); PutPCurves(eref,eimg,myShape); for (exp.Init(eref,TopAbs_VERTEX); exp.More(); exp.Next()) { const TopoDS_Vertex& vtx = TopoDS::Vertex(exp.Current()); if (!theMap.Contains(vtx)) { // pas deja traite for (exp2.Init(eimg,TopAbs_VERTEX); exp2.More(); exp2.Next()) { const TopoDS_Vertex& vtx2 = TopoDS::Vertex(exp2.Current()); if (vtx2.IsSame(vtx)) { break; } else if (BRepTools::Compare(vtx,vtx2)) { mapV.Bind(vtx,vtx2); break; } } if (!exp2.More()) { mapV.Bind(vtx,eimg); } theMap.Add(vtx); } } } for (ite.Initialize(mapV); ite.More(); ite.Next()) { myMap.Bind(ite.Key(),ite.Value()); } TopTools_IndexedDataMapOfShapeListOfShape Splits; Standard_Integer Ind; for (Ind = 1; Ind <= myMapEF.Extent(); Ind++) { const TopoDS_Edge& edg = TopoDS::Edge(myMapEF.FindKey(Ind)); const TopoDS_Face& fac = TopoDS::Face(myMapEF(Ind)); PutPCurve(edg,fac); Standard_Real pf, pl; Handle(Geom2d_Curve) aPCurve = BRep_Tool::CurveOnSurface(edg, fac, pf, pl); if (aPCurve.IsNull()) continue; FindInternalIntersections(edg, fac, Splits, myMap, theMap); } for (Ind = 1; Ind <= Splits.Extent(); Ind++) { TopoDS_Shape anEdge = Splits.FindKey(Ind); TopoDS_Shape aFace = myMapEF.FindFromKey(anEdge); //Remove "anEdge" from "myMapEF" TopoDS_Shape LastEdge = myMapEF.FindKey(myMapEF.Extent()); TopoDS_Shape LastFace = myMapEF(myMapEF.Extent()); myMapEF.RemoveLast(); if (myMapEF.FindIndex(anEdge) != 0) myMapEF.Substitute(myMapEF.FindIndex(anEdge), LastEdge, LastFace); //////////////////////////////// TopTools_ListIteratorOfListOfShape itl(Splits(Ind)); for (; itl.More(); itl.Next()) myMapEF.Add(itl.Value(), aFace); } // Il faut s`occuper maintenant des vertex "de changement de face", // et des vertex "libres" // TopTools_DataMapIteratorOfDataMapOfShapeShape ite2; // for (ite.Initialize(myMapEF); ite.More(); ite.Next()) { // const TopoDS_Edge& edg = TopoDS::Edge(ite.Key()); // const TopoDS_Face& fac = TopoDS::Face(ite.Value()); for (Ind = 1; Ind <= myMapEF.Extent(); Ind++) { const TopoDS_Edge& edg = TopoDS::Edge(myMapEF.FindKey(Ind)); const TopoDS_Face& fac = TopoDS::Face(myMapEF(Ind)); // JAG 02.02.96 : On verifie les pcurves... //PutPCurve(edg,fac); for (exp.Init(edg,TopAbs_VERTEX); exp.More(); exp.Next()) { const TopoDS_Vertex& vtx = TopoDS::Vertex(exp.Current()); if (theMap.Contains(vtx)) { continue; } TopoDS_Edge Epro; Standard_Real prm; Standard_Boolean ok = Project(vtx,fac,Epro,prm); if (ok) { for (exp2.Init(Epro,TopAbs_VERTEX); exp2.More(); exp2.Next()) { const TopoDS_Vertex& vtx2 = TopoDS::Vertex(exp2.Current()); if (vtx2.IsSame(vtx)) { break; } else if (BRepTools::Compare(vtx,vtx2)) { myMap.Bind(vtx,vtx2); break; } } if (!exp2.More()) { myMap.Bind(vtx,Epro); } theMap.Add(vtx); } } } // Modified by Sergey KHROMOV - Mon Feb 12 16:26:50 2001 Begin for (ite.Initialize(myMap); ite.More(); ite.Next()) if ((ite.Key()).ShapeType() == TopAbs_EDGE) myMapEF.Add(ite.Key(),ite.Value()); // Modified by Sergey KHROMOV - Mon Feb 12 16:26:52 2001 End myDone = Standard_True; } //======================================================================= //function : InitEdgeIterator //purpose : //======================================================================= void LocOpe_WiresOnShape::InitEdgeIterator() { BindAll(); // myIt.Initialize(myMapEF); myIndex = 1; } //======================================================================= //function : MoreEdge //purpose : //======================================================================= Standard_Boolean LocOpe_WiresOnShape::MoreEdge() { // return myIt.More(); return (myIndex <= myMapEF.Extent()); } //======================================================================= //function : Edge //purpose : //======================================================================= TopoDS_Edge LocOpe_WiresOnShape::Edge() { // return TopoDS::Edge(myIt.Key()); return TopoDS::Edge(myMapEF.FindKey(myIndex)); } //======================================================================= //function : Face //purpose : //======================================================================= TopoDS_Face LocOpe_WiresOnShape::OnFace() { // return TopoDS::Face(myIt.Value()); return TopoDS::Face(myMapEF(myIndex)); } //======================================================================= //function : OnEdge //purpose : //======================================================================= Standard_Boolean LocOpe_WiresOnShape::OnEdge(TopoDS_Edge& E) { // if (myMap.IsBound(myIt.Key())) { if (myMap.IsBound(myMapEF.FindKey(myIndex))) { // E = TopoDS::Edge(myMap(myIt.Key())); E = TopoDS::Edge(myMap(myMapEF.FindKey(myIndex))); return Standard_True; } return Standard_False; } //======================================================================= //function : NextEdge //purpose : //======================================================================= void LocOpe_WiresOnShape::NextEdge() { // myIt.Next(); myIndex++; } //======================================================================= //function : OnVertex //purpose : //======================================================================= Standard_Boolean LocOpe_WiresOnShape::OnVertex(const TopoDS_Vertex& Vw, TopoDS_Vertex& Vs) { if (myMap.IsBound(Vw)) { if (myMap(Vw).ShapeType() == TopAbs_VERTEX) { Vs = TopoDS::Vertex(myMap(Vw)); return Standard_True; } return Standard_False; } return Standard_False; } //======================================================================= //function : OnEdge //purpose : //======================================================================= Standard_Boolean LocOpe_WiresOnShape::OnEdge(const TopoDS_Vertex& V, TopoDS_Edge& Ed, Standard_Real& prm) { if (!myMap.IsBound(V) || myMap(V).ShapeType() == TopAbs_VERTEX) { return Standard_False; } Ed = TopoDS::Edge(myMap(V)); prm = Project(V,Ed); return Standard_True; } //======================================================================= //function : Project //purpose : //======================================================================= Standard_Boolean Project(const TopoDS_Vertex& V, const TopoDS_Face& F, TopoDS_Edge& theEdge, Standard_Real& param) { Handle(Geom_Curve) C; TopLoc_Location Loc; Standard_Real f,l; Standard_Real dmin = RealLast(); gp_Pnt toproj(BRep_Tool::Pnt(V)); Standard_Boolean valret = Standard_False; GeomAPI_ProjectPointOnCurve proj; for (TopExp_Explorer exp(F.Oriented(TopAbs_FORWARD),TopAbs_EDGE); exp.More(); exp.Next()) { const TopoDS_Edge& edg = TopoDS::Edge(exp.Current()); if (!BRep_Tool::Degenerated(edg)) { C = BRep_Tool::Curve(edg,Loc,f,l); if (!Loc.IsIdentity()) { Handle(Geom_Geometry) GG = C->Transformed(Loc.Transformation()); C = *((Handle(Geom_Curve)*)&GG); } proj.Init(toproj,C,f,l); if (proj.NbPoints() > 0) { if (proj.LowerDistance() < dmin) { theEdge = edg; theEdge.Orientation(edg.Orientation()); dmin = proj.LowerDistance(); param = proj.LowerDistanceParameter(); } } } } if(theEdge.IsNull()) return Standard_False; Standard_Real ttol = BRep_Tool::Tolerance(V) + BRep_Tool::Tolerance(theEdge); if (dmin <= ttol) { valret = Standard_True; BRep_Builder B; B.UpdateVertex(V, Max(dmin, BRep_Tool::Tolerance(V))); } #ifdef DEB_MESH else { cout <<"LocOpe_WiresOnShape::Project --> le vertex projete est a une "; cout <<"distance / la face = "< split { gp_Pnt aPoint = aCurve->Value(anIntPar); if (aPoint.Distance(thePnt[0]) > BRep_Tool::Tolerance(theVertices[0]) && aPoint.Distance(thePnt[1]) > BRep_Tool::Tolerance(theVertices[1])) SplitPars.Append(theIntPar); } } } if (SplitPars.IsEmpty()) return; //Sort for (i = 1; i < SplitPars.Length(); i++) for (j = i+1; j <= SplitPars.Length(); j++) if (SplitPars(i) > SplitPars(j)) { Standard_Real Tmp = SplitPars(i); SplitPars(i) = SplitPars(j); SplitPars(j) = Tmp; } //Remove repeating points i = 1; while (i < SplitPars.Length()) { gp_Pnt Pnt1 = theCurve->Value(SplitPars(i)); gp_Pnt Pnt2 = theCurve->Value(SplitPars(i+1)); if (Pnt1.Distance(Pnt2) <= Precision::Confusion()) SplitPars.Remove(i+1); else i++; } //Split TopTools_ListOfShape NewEdges; BRep_Builder BB; //theVertices[0].Orientation(TopAbs_FORWARD); //theVertices[1].Orientation(TopAbs_REVERSED); TopoDS_Vertex FirstVertex = theVertices[0], LastVertex; Standard_Real FirstPar = thePar[0], LastPar; for (i = 1; i <= SplitPars.Length()+1; i++) { FirstVertex.Orientation(TopAbs_FORWARD); if (i <= SplitPars.Length()) { LastPar = SplitPars(i); gp_Pnt LastPoint = theCurve->Value(LastPar); LastVertex = BRepLib_MakeVertex(LastPoint); } else { LastPar = thePar[1]; LastVertex = theVertices[1]; } LastVertex.Orientation(TopAbs_REVERSED); TopoDS_Shape aLocalShape = theEdge.EmptyCopied(); TopoDS_Edge NewEdge = TopoDS::Edge(aLocalShape); BB.Range(NewEdge, FirstPar, LastPar); BB.Add(NewEdge, FirstVertex); BB.Add(NewEdge, LastVertex); NewEdges.Append(NewEdge); FirstVertex = LastVertex; FirstPar = LastPar; } if (!NewEdges.IsEmpty()) Splits.Add(theEdge, NewEdges); }