// File: LocOpe_SplitShape.cxx // Created: Tue Jun 27 16:37:40 1995 // 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 #include static Standard_Boolean IsInside(const TopoDS_Face&, const TopoDS_Wire&, const TopoDS_Wire&); static Standard_Boolean IsInside(const TopoDS_Face&, const TopoDS_Wire&); static void ChoixUV(const TopoDS_Edge&, const TopoDS_Face&, const TopTools_MapOfShape&, TopTools_MapIteratorOfMapOfShape&, gp_Pnt2d&, gp_Vec2d&, const Standard_Real tol); inline Standard_Boolean SameUV(const gp_Pnt2d& P1, const gp_Pnt2d& P2, const BRepAdaptor_Surface& theBAS)//const Standard_Real tol) { // Standard_Real tol = Precision::Confusion(); // return P1.SquareDistance(P2) < 10*tol; //gka Standard_Boolean isSame = Standard_True; if(theBAS.IsUPeriodic()) isSame = (fabs(P1.X() - P2.X()) < theBAS.UPeriod() *0.5); if(theBAS.IsVPeriodic()) isSame = (isSame && (fabs(P1.Y() - P2.Y()) < theBAS.VPeriod() *0.5)); return isSame; //return P1.SquareDistance(P2) < tol * tol; //IFV } //======================================================================= //function : Init //purpose : //======================================================================= void LocOpe_SplitShape::Init(const TopoDS_Shape& S) { myDone = Standard_False; myShape = S; myDblE.Clear(); myMap.Clear(); Put(myShape); } //======================================================================= //function : CanSplit //purpose : //======================================================================= Standard_Boolean LocOpe_SplitShape::CanSplit(const TopoDS_Edge& E) const { if (myDone) { return Standard_False; } if (myMap.IsEmpty()) { return Standard_False; } if (!myMap.IsBound(E)) { return Standard_False; } // On verifie que l`edge n`appartient pas a un wire deja reconstruit TopExp_Explorer exp; TopTools_DataMapIteratorOfDataMapOfShapeListOfShape itm(myMap); for (; itm.More(); itm.Next()) { if (itm.Key().ShapeType() == TopAbs_WIRE && !itm.Value().IsEmpty()) { for (exp.Init(itm.Key(),TopAbs_EDGE); exp.More(); exp.Next()) { if (exp.Current().IsSame(E)) { return Standard_False; } } } } return Standard_True; } //======================================================================= //function : Add //purpose : //======================================================================= void LocOpe_SplitShape::Add(const TopoDS_Vertex& V, const Standard_Real P, const TopoDS_Edge& E) { if (!CanSplit(E)) { Standard_ConstructionError::Raise(); } BRep_Builder B; TopTools_ListOfShape& le = myMap(E); if (le.IsEmpty()) { le.Append(E); } TopTools_ListIteratorOfListOfShape itl(le); Standard_Real f,l; for (; itl.More(); itl.Next()) { const TopoDS_Edge& edg = TopoDS::Edge(itl.Value()); BRep_Tool::Range(edg,f,l); if (P>f && P Value(f); } else { pfirst = C2d->Value(l); } for (exp.Init(W.Oriented(TopAbs_FORWARD),TopAbs_EDGE); exp.More(); exp.Next()) { const TopoDS_Edge& edg = TopoDS::Edge(exp.Current()); if( nbE>1 && edg.IsSame(LastEdge) ) continue; for (exp2.Init(edg,TopAbs_VERTEX); exp2.More(); exp2.Next()) { if (exp2.Current().IsSame(Vlast)) { break; } } if (exp2.More()) { LastEdge = edg; LastEdge.Orientation(edg.Orientation()); break; } } aLocalFace = FaceRef.Oriented(wfirst.Orientation()); C2d = BRep_Tool::CurveOnSurface(LastEdge, TopoDS::Face(aLocalFace), f, l); // C2d = BRep_Tool::CurveOnSurface // (LastEdge, // TopoDS::Face(FaceRef.Oriented(wfirst.Orientation())), // f,l); if (LastEdge.Orientation() == TopAbs_FORWARD) { C2d->D1(l,plast,dlast); // plast = C2d->Value(l); } else { // plast = C2d->Value(f); C2d->D1(f,plast,dlast); dlast.Reverse(); } Standard_Boolean cond; if(IsPeriodic) { cond = !(Vfirst.IsSame(Vlast) && SameUV(pfirst,plast,BAS)); } else { cond = !(Vfirst.IsSame(Vlast)); } while (cond) { PossE.Clear(); // On enchaine par la fin for (exp.Init(wfirst.Oriented(TopAbs_FORWARD),TopAbs_EDGE); exp.More(); exp.Next()) { const TopoDS_Edge& edg = TopoDS::Edge(exp.Current()); if (MapE.Contains(edg) && !myDblE.Contains(edg)) { continue; } orient = edg.Orientation(); TopExp::Vertices(edg,vdeb,vfin); if (orient == TopAbs_FORWARD && Vlast.IsSame(vdeb)) { PossE.Add(edg.Oriented(orient)); } else if (orient == TopAbs_REVERSED && Vlast.IsSame(vfin)) { PossE.Add(edg.Oriented(orient)); } } nbPoss = PossE.Extent(); if (nbPoss == 1) { itm.Initialize(PossE); TopoDS_Shape aLocalFace = FaceRef.Oriented(wfirst.Orientation()); C2d = BRep_Tool::CurveOnSurface(TopoDS::Edge(itm.Key()), TopoDS::Face(aLocalFace), f, l); // C2d = BRep_Tool::CurveOnSurface // (TopoDS::Edge(itm.Key()), // TopoDS::Face(FaceRef.Oriented(wfirst.Orientation())), // f,l); if (itm.Key().Orientation() == TopAbs_FORWARD) { // plast = C2d->Value(l); C2d->D1(l,plast,dlast); } else { // plast = C2d->Value(f); C2d->D1(f,plast,dlast); dlast.Reverse(); } } else if (nbPoss > 1) { // Faire choix en U,V... TopoDS_Shape aLocalFace = FaceRef.Oriented(wfirst.Orientation()); toll = Max(BAS.UResolution(toll), BAS.VResolution(toll)); ChoixUV(LastEdge, TopoDS::Face(aLocalFace), PossE, itm, plast, dlast, toll); // ChoixUV(LastEdge, // TopoDS::Face(FaceRef.Oriented(wfirst.Orientation())), // PossE, // itm, // plast, // dlast, toll); } if (nbPoss >= 1) { B.Add(newW1,itm.Key()); if (MapE.Contains(itm.Key())) { myDblE.Remove(itm.Key()); } else { MapE.Add(itm.Key()); } LastEdge = TopoDS::Edge(itm.Key()); if (LastEdge.Orientation() == TopAbs_FORWARD) { Vlast = TopExp::LastVertex(LastEdge); } else { Vlast = TopExp::FirstVertex(LastEdge); } toll = BRep_Tool::Tolerance(Vlast); tol1 = Max(tolf, toll); } //MODIFICATION PIERRE SMEYERS : si pas de possibilite, on sort avec erreur else{ cout<<"erreur Spliter : pas de chainage du wire"<Value(prm)); // BRepClass_FaceClassifier classif(newFace,pt2d,Precision::PConfusion()); // return (classif.State() == TopAbs_IN); if (!Reversed) { return (classif.Perform(pt2d) == TopAbs_IN); } else { return (classif.Perform(pt2d) == TopAbs_OUT); } } //======================================================================= //function : IsInside //purpose : //======================================================================= static Standard_Boolean IsInside(const TopoDS_Face& F, const TopoDS_Wire& W) { // Attention, c`est tres boeuf !!!! TopExp_Explorer exp(W,TopAbs_EDGE); for( ; exp.More(); exp.Next()) { const TopoDS_Edge& edg = TopoDS::Edge(exp.Current()); // TopExp_Explorer exp2(edg,TopAbs_VERTEX); // const TopoDS_Vertex& vtx = TopoDS::Vertex(exp2.Current()); // Standard_Real prm = BRep_Tool::Parameter(vtx,edg); Standard_Real f,l,prm; Handle(Geom2d_Curve) C2d = BRep_Tool::CurveOnSurface(edg,F,f,l); if (!Precision::IsNegativeInfinite(f) && !Precision::IsPositiveInfinite(l)) { prm = (f+l)/2.; } else { if (Precision::IsNegativeInfinite(f) && Precision::IsPositiveInfinite(l)){ prm = 0.; } else if (Precision::IsNegativeInfinite(f)) { prm = l-1.; } else { prm = f+1.; } } gp_Pnt2d pt2d(C2d->Value(prm)); // BRepClass_FaceClassifier classif(F,pt2d,Precision::PConfusion()); // return (classif.State() != TopAbs_OUT); BRepTopAdaptor_FClass2d classif(F,Precision::PConfusion()); Standard_Boolean stat = classif.Perform(pt2d); // return (classif.Perform(pt2d) != TopAbs_OUT); if(stat == TopAbs_OUT) return Standard_False; if(stat == TopAbs_ON) { Standard_Integer nbPnt =10; Standard_Integer nbOut =0,nbIn =0,nbOn=0; Standard_Integer j =1; for( ; j<= nbPnt ; j++) { //check neighbouring point //prm = .66 * prm + .34 * l; prm = f + (l-f)/nbPnt*(j-1); pt2d = C2d->Value(prm); stat = classif.Perform(pt2d); if(stat == TopAbs_OUT ) nbOut++; else if(stat == TopAbs_IN) nbIn++; else nbOn++; } if(nbOut > nbIn + nbOn) return Standard_False; } } return Standard_True; } //======================================================================= //function : ChoixUV //purpose : //======================================================================= static void ChoixUV(const TopoDS_Edge& Last, const TopoDS_Face& F, const TopTools_MapOfShape& Poss, TopTools_MapIteratorOfMapOfShape& It, gp_Pnt2d& plst, gp_Vec2d& dlst, const Standard_Real toll) { Standard_Real f,l; // gp_Pnt2d p2d,psav; gp_Pnt2d p2d; gp_Vec2d v2d; BRepAdaptor_Surface surf(F,Standard_False); // no restriction // Standard_Real tol = Precision::PConfusion() //BRep_Tool::Tolerance(Last)); Standard_Real tol; TopoDS_Vertex vtx; gp_Dir2d ref2d(dlst); Handle(Geom2d_Curve) C2d; Standard_Integer index = 0, imin=0; Standard_Real angmax = -PI, dist, ang; for (It.Initialize(Poss); It.More(); It.Next()) { index++; C2d = BRep_Tool::CurveOnSurface(TopoDS::Edge(It.Key()),F,f,l); if (It.Key().Orientation() == TopAbs_FORWARD) { // p2d = C2d->Value(f); C2d->D1(f,p2d,v2d); vtx = TopExp::FirstVertex(TopoDS::Edge(It.Key())); } else { // p2d = C2d->Value(l); C2d->D1(l,p2d,v2d); v2d.Reverse(); vtx = TopExp::LastVertex(TopoDS::Edge(It.Key())); } if (surf.IsUPeriodic()) if ((fabs(p2d.Y() - plst.Y()) <= toll) || ((surf.IsVPeriodic()) && (fabs(fabs(p2d.Y() - plst.Y()) - surf.VPeriod()) <= toll))) { if (fabs(p2d.X() - plst.X() - surf.UPeriod()) <= toll) p2d.SetX(p2d.X() - surf.UPeriod()); else if (fabs(plst.X() - p2d.X() - surf.UPeriod()) <= toll) p2d.SetX(p2d.X() + surf.UPeriod()); } if (surf.IsVPeriodic()) if (fabs(p2d.X() - plst.X()) <= toll) { if (fabs(p2d.Y() - plst.Y() - surf.VPeriod()) <= toll) p2d.SetY(p2d.Y() - surf.VPeriod()); else if (fabs(plst.Y() - p2d.Y() - surf.VPeriod()) <= toll) p2d.SetY(p2d.Y() + surf.VPeriod()); } tol = BRep_Tool::Tolerance(vtx); tol = Max(surf.UResolution(tol), surf.VResolution(tol)); tol = Max(toll, tol); tol *= tol; dist = p2d.SquareDistance(plst); if (!Last.IsSame(It.Key())) { ang = ref2d.Angle(gp_Dir2d(v2d)); } else { ang = -PI; } //if ((dist < dmin - tol) || //(dist <= dmin+tol && ang > angmax)) { if ((dist < tol) && (ang > angmax)) { imin = index; // dmin = dist; angmax = ang; } } for (index = 1, It.Initialize(Poss); It.More(); It.Next()) { if (index == imin) { C2d = BRep_Tool::CurveOnSurface(TopoDS::Edge(It.Key()),F,f,l); if (It.Key().Orientation() == TopAbs_FORWARD) { // plst = C2d->Value(l); C2d->D1(l,plst,dlst); } else { // plst = C2d->Value(f); C2d->D1(f,plst,dlst); dlst.Reverse(); } break; } index++; } }