// File: LocOpe_WiresOnShape.cxx // Created: Thu Jan 11 13:48:03 1996 // Author: Jacques GOUSSARD // #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&); //======================================================================= //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_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()); } // 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 (Standard_Integer 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 = "<