1 // File: LocOpe_SplitShape.cxx
2 // Created: Tue Jun 27 16:37:40 1995
3 // Author: Jacques GOUSSARD
7 #include <LocOpe_SplitShape.ixx>
9 #include <TopTools_ListOfShape.hxx>
10 #include <TopTools_ListIteratorOfListOfShape.hxx>
11 #include <TopTools_MapOfShape.hxx>
12 #include <TopTools_DataMapOfShapeListOfShape.hxx>
13 #include <TopTools_DataMapIteratorOfDataMapOfShapeListOfShape.hxx>
14 #include <TopTools_MapIteratorOfMapOfShape.hxx>
15 #include <TopoDS_Iterator.hxx>
16 #include <TopExp_Explorer.hxx>
17 #include <BRep_Builder.hxx>
18 #include <TopoDS_Vertex.hxx>
19 #include <BRepLib_MakeFace.hxx>
20 #include <BRep_Tool.hxx>
21 #include <BRepTools.hxx>
22 #include <BRep_Builder.hxx>
24 #include <BRepClass_FaceExplorer.hxx>
25 #include <BRepTopAdaptor_FClass2d.hxx>
26 #include <BRepAdaptor_Surface.hxx>
28 #include <Geom2d_Curve.hxx>
29 #include <gp_Pnt2d.hxx>
30 #include <gp_Vec2d.hxx>
31 #include <gp_Dir2d.hxx>
34 #include <Precision.hxx>
35 #include <BRepTools.hxx>
37 #include <Standard_ErrorHandler.hxx>
39 static Standard_Boolean IsInside(const TopoDS_Face&,
43 static Standard_Boolean IsInside(const TopoDS_Face&,
46 static void ChoixUV(const TopoDS_Edge&,
48 const TopTools_MapOfShape&,
49 TopTools_MapIteratorOfMapOfShape&,
52 const Standard_Real tol);
54 inline Standard_Boolean SameUV(const gp_Pnt2d& P1, const gp_Pnt2d& P2,
55 const BRepAdaptor_Surface& theBAS)//const Standard_Real tol)
57 // Standard_Real tol = Precision::Confusion();
58 // return P1.SquareDistance(P2) < 10*tol;
60 Standard_Boolean isSame = Standard_True;
61 if(theBAS.IsUPeriodic())
62 isSame = (fabs(P1.X() - P2.X()) < theBAS.UPeriod() *0.5);
63 if(theBAS.IsVPeriodic())
64 isSame = (isSame && (fabs(P1.Y() - P2.Y()) < theBAS.VPeriod() *0.5));
66 //return P1.SquareDistance(P2) < tol * tol; //IFV
71 //=======================================================================
74 //=======================================================================
76 void LocOpe_SplitShape::Init(const TopoDS_Shape& S)
78 myDone = Standard_False;
86 //=======================================================================
89 //=======================================================================
91 Standard_Boolean LocOpe_SplitShape::CanSplit(const TopoDS_Edge& E) const
94 return Standard_False;
96 if (myMap.IsEmpty()) {
97 return Standard_False;
100 if (!myMap.IsBound(E)) {
101 return Standard_False;
104 // On verifie que l`edge n`appartient pas a un wire deja reconstruit
106 TopTools_DataMapIteratorOfDataMapOfShapeListOfShape itm(myMap);
107 for (; itm.More(); itm.Next()) {
108 if (itm.Key().ShapeType() == TopAbs_WIRE && !itm.Value().IsEmpty()) {
109 for (exp.Init(itm.Key(),TopAbs_EDGE); exp.More(); exp.Next()) {
110 if (exp.Current().IsSame(E)) {
111 return Standard_False;
116 return Standard_True;
120 //=======================================================================
123 //=======================================================================
125 void LocOpe_SplitShape::Add(const TopoDS_Vertex& V,
126 const Standard_Real P,
127 const TopoDS_Edge& E)
130 Standard_ConstructionError::Raise();
134 TopTools_ListOfShape& le = myMap(E);
138 TopTools_ListIteratorOfListOfShape itl(le);
141 for (; itl.More(); itl.Next()) {
142 const TopoDS_Edge& edg = TopoDS::Edge(itl.Value());
143 BRep_Tool::Range(edg,f,l);
149 Standard_ConstructionError::Raise();
151 TopoDS_Edge edg = TopoDS::Edge(itl.Value());
153 if (V.Orientation() == TopAbs_FORWARD ||
154 V.Orientation() == TopAbs_REVERSED) {
156 TopoDS_Shape aLocalShape = edg.EmptyCopied();
157 TopoDS_Edge E1 = TopoDS::Edge(aLocalShape);
158 aLocalShape = edg.EmptyCopied();
159 TopoDS_Edge E2 = TopoDS::Edge(aLocalShape);
160 // TopoDS_Edge E1 = TopoDS::Edge(edg.EmptyCopied());
161 // TopoDS_Edge E2 = TopoDS::Edge(edg.EmptyCopied());
162 E1.Orientation(TopAbs_FORWARD);
163 E2.Orientation(TopAbs_FORWARD);
164 TopoDS_Vertex newVtx = V;
165 newVtx.Orientation(TopAbs_REVERSED);
167 B.UpdateVertex(newVtx,P,E1,BRep_Tool::Tolerance(V));
168 newVtx.Orientation(TopAbs_FORWARD);
170 B.UpdateVertex(newVtx,P,E2,BRep_Tool::Tolerance(V));
171 edg.Orientation(TopAbs_FORWARD);
173 for (exp.Init(edg,TopAbs_VERTEX); exp.More(); exp.Next()) {
174 // for (TopExp_Explorer exp(edg,TopAbs_VERTEX); exp.More(); exp.Next()) {
175 const TopoDS_Vertex& vtx = TopoDS::Vertex(exp.Current());
176 f = BRep_Tool::Parameter(vtx,edg);
179 B.UpdateVertex(vtx,f,E1,BRep_Tool::Tolerance(vtx));
183 B.UpdateVertex(vtx,f,E2,BRep_Tool::Tolerance(vtx));
190 TopoDS_Shape aLocalShape = edg.EmptyCopied();
191 TopoDS_Edge E1 = TopoDS::Edge(aLocalShape);
192 // TopoDS_Edge E1 = TopoDS::Edge(edg.EmptyCopied());
194 for (exp.Init(edg,TopAbs_VERTEX); exp.More(); exp.Next()) {
195 // for (TopExp_Explorer exp(edg,TopAbs_VERTEX); exp.More(); exp.Next()) {
196 const TopoDS_Vertex& vtx = TopoDS::Vertex(exp.Current());
197 f = BRep_Tool::Parameter(vtx,edg);
199 B.UpdateVertex(vtx,f,E1,BRep_Tool::Tolerance(vtx));
202 B.UpdateVertex(V,P,E1,BRep_Tool::Tolerance(V));
209 //=======================================================================
212 //=======================================================================
214 void LocOpe_SplitShape::Add(const TopoDS_Wire& W,
215 const TopoDS_Face& F)
219 Standard_ConstructionError::Raise();
224 TopTools_ListOfShape& lf = myMap(F);
230 if (!LocOpe::Closed(W,F)) {
236 } catch (Standard_Failure ) {
238 cout << "Warning: SpliShape internal problem detected, some faces may be lost. Check input edges/wires" <<endl;
242 // JAG 10.11.95 Codage des regularites
244 for (exp.Init(W,TopAbs_EDGE); exp.More(); exp.Next()) {
245 const TopoDS_Edge& edg = TopoDS::Edge(exp.Current());
246 if (!BRep_Tool::HasContinuity(edg,F,F)) {
247 B.Continuity(edg,F,F,GeomAbs_CN);
254 //=======================================================================
255 //function : AddClosedWire
257 //=======================================================================
259 void LocOpe_SplitShape::AddClosedWire(const TopoDS_Wire& W,
260 const TopoDS_Face& F)
264 // On cherche la face descendante de F qui continent le wire
265 TopTools_ListOfShape& lf = myMap(F);
266 TopTools_ListIteratorOfListOfShape itl(lf);
268 for (; itl.More(); itl.Next()) {
269 const TopoDS_Face& fac = TopoDS::Face(itl.Value());
271 outerW = BRepTools::OuterWire(fac);
272 if (IsInside(F,W,outerW)) {
276 if (IsInside(fac,W)) {
282 Standard_ConstructionError::Raise();
287 TopAbs_Orientation orWire = W.Orientation();
288 TopoDS_Shape aLocalFace = F.EmptyCopied();
289 TopoDS_Face newFace = TopoDS::Face(aLocalFace);
290 // TopoDS_Face newFace = TopoDS::Face(F.EmptyCopied());
291 newFace.Orientation(TopAbs_FORWARD);
294 // BRepGProp::SurfaceProperties (newFace,GP);
295 // if (GP.Mass() < 0) {
296 BRepTopAdaptor_FClass2d classif(newFace,Precision::PConfusion());
297 if (classif.PerformInfinitePoint() == TopAbs_IN) {
298 //le wire donne defini un trou
299 aLocalFace = F.EmptyCopied();
300 newFace = TopoDS::Face(aLocalFace);
301 // newFace = TopoDS::Face(F.EmptyCopied());
302 newFace.Orientation(TopAbs_FORWARD);
303 orWire = TopAbs::Reverse(orWire);
304 B.Add(newFace,W.Oriented(orWire));
307 TopoDS_Face FaceRef = TopoDS::Face(itl.Value());
308 FaceRef.Orientation(TopAbs_FORWARD);
311 aLocalFace = FaceRef.EmptyCopied();
312 TopoDS_Face newRef = TopoDS::Face(aLocalFace);
313 // TopoDS_Face newRef = TopoDS::Face(FaceRef.EmptyCopied());
314 newRef.Orientation(TopAbs_FORWARD);
316 // On suppose que les edges du wire ont des courbes 2d.
317 // Comme on ne change pas de surface de base, pas besoin d`UpdateEdge.
319 for (exp.Init(FaceRef.Oriented(TopAbs_FORWARD),TopAbs_WIRE);
320 exp.More(); exp.Next()) {
321 const TopoDS_Wire& wir = TopoDS::Wire(exp.Current());
322 if (IsInside(F,wir,W)) {
329 B.Add(newRef,W.Oriented(TopAbs::Reverse(orWire)));
336 //=======================================================================
337 //function : AddOpenWire
339 //=======================================================================
341 void LocOpe_SplitShape::AddOpenWire(const TopoDS_Wire& W,
342 const TopoDS_Face& F)
344 // On cherche la face descendante de F qui continent le wire
345 TopTools_ListOfShape& lf = myMap(F);
346 TopTools_ListIteratorOfListOfShape itl(lf);
347 TopoDS_Vertex Vfirst,Vlast;
349 BRepTools::Update(F);
351 // TopExp::Vertices(W,Vfirst,Vlast);
353 Standard_Real tolf, toll, tol1;
355 TopoDS_Shape aLocalShape = W.Oriented(TopAbs_FORWARD);
356 TopExp::Vertices(TopoDS::Wire(aLocalShape),Vfirst,Vlast);
357 // TopExp::Vertices(TopoDS::Wire(W.Oriented(TopAbs_FORWARD)),Vfirst,Vlast);
359 tolf = BRep_Tool::Tolerance(Vfirst);
360 toll = BRep_Tool::Tolerance(Vlast);
361 tol1 = Max(tolf, toll);
364 TopExp_Explorer exp,exp2;
366 TopoDS_Wire wfirst,wlast;
367 for (; itl.More(); itl.Next()) {
368 const TopoDS_Face& fac = TopoDS::Face(itl.Value());
369 if (!IsInside(fac,W)) {
373 Standard_Boolean ffound = Standard_False;
374 Standard_Boolean lfound = Standard_False;
375 for (exp.Init(fac,TopAbs_WIRE); exp.More(); exp.Next()) {
376 const TopoDS_Wire& wir = TopoDS::Wire(exp.Current());
377 for (exp2.Init(wir,TopAbs_VERTEX); exp2.More(); exp2.Next()) {
378 if (!ffound && exp2.Current().IsSame(Vfirst)) {
379 ffound = Standard_True;
382 else if (!lfound && exp2.Current().IsSame(Vlast)) {
383 lfound = Standard_True;
386 if (ffound && lfound) {
399 Standard_ConstructionError::Raise();
402 TopoDS_Face FaceRef = TopoDS::Face(itl.Value());
403 FaceRef.Orientation(TopAbs_FORWARD);
407 BRepAdaptor_Surface BAS(FaceRef, Standard_False);
409 Standard_Boolean IsPeriodic = BAS.IsUPeriodic() || BAS.IsVPeriodic();
411 tol1 = Max(BAS.UResolution(tol1), BAS.VResolution(tol1));
413 if (wfirst.IsSame(wlast)) {
414 // on cree 2 faces en remplacement de itl.Value()
417 for (exp.Init(wfirst,TopAbs_EDGE); exp.More(); exp.Next()) {
418 if (BRep_Tool::IsClosed(TopoDS::Edge(exp.Current()),FaceRef)) {
419 myDblE.Add(exp.Current());
423 TopAbs_Orientation orient;
424 TopoDS_Wire newW1,newW2;
426 newW1.Orientation(TopAbs_FORWARD);
428 newW2.Orientation(TopAbs_FORWARD);
430 Standard_Integer nbE = 0;
431 for (exp.Init(W.Oriented(TopAbs_FORWARD),TopAbs_EDGE);
432 exp.More(); exp.Next()) {
434 const TopoDS_Edge& edg = TopoDS::Edge(exp.Current());
435 orient = edg.Orientation();
437 B.Add(newW2,edg.Oriented(TopAbs::Reverse(orient)));
440 TopTools_MapOfShape MapE, PossE;
441 TopTools_MapIteratorOfMapOfShape itm;
442 TopoDS_Vertex vdeb,vfin;
443 Standard_Integer nbPoss;
445 // On recherche l`edge contenant Vlast
446 TopoDS_Edge LastEdge;
447 gp_Pnt2d pfirst,plast;
449 Handle(Geom2d_Curve) C2d;
452 for (exp.Init(W.Oriented(TopAbs_FORWARD),TopAbs_EDGE);
453 exp.More(); exp.Next()) {
454 const TopoDS_Edge& edg = TopoDS::Edge(exp.Current());
455 for (exp2.Init(edg,TopAbs_VERTEX); exp2.More(); exp2.Next()) {
456 if (exp2.Current().IsSame(Vfirst)) {
462 LastEdge.Orientation(edg.Orientation());
467 TopoDS_Shape aLocalFace = FaceRef.Oriented(wfirst.Orientation());
468 C2d = BRep_Tool::CurveOnSurface(LastEdge, TopoDS::Face(aLocalFace), f, l);
469 // C2d = BRep_Tool::CurveOnSurface
471 // TopoDS::Face(FaceRef.Oriented(wfirst.Orientation())),
473 if (LastEdge.Orientation() == TopAbs_FORWARD) {
474 pfirst = C2d->Value(f);
477 pfirst = C2d->Value(l);
480 for (exp.Init(W.Oriented(TopAbs_FORWARD),TopAbs_EDGE);
481 exp.More(); exp.Next()) {
482 const TopoDS_Edge& edg = TopoDS::Edge(exp.Current());
483 if( nbE>1 && edg.IsSame(LastEdge) )
485 for (exp2.Init(edg,TopAbs_VERTEX); exp2.More(); exp2.Next()) {
486 if (exp2.Current().IsSame(Vlast)) {
492 LastEdge.Orientation(edg.Orientation());
496 aLocalFace = FaceRef.Oriented(wfirst.Orientation());
497 C2d = BRep_Tool::CurveOnSurface(LastEdge, TopoDS::Face(aLocalFace), f, l);
498 // C2d = BRep_Tool::CurveOnSurface
500 // TopoDS::Face(FaceRef.Oriented(wfirst.Orientation())),
502 if (LastEdge.Orientation() == TopAbs_FORWARD) {
503 C2d->D1(l,plast,dlast);
504 // plast = C2d->Value(l);
507 // plast = C2d->Value(f);
508 C2d->D1(f,plast,dlast);
512 Standard_Boolean cond;
516 cond = !(Vfirst.IsSame(Vlast) && SameUV(pfirst,plast,BAS));
519 cond = !(Vfirst.IsSame(Vlast));
525 // On enchaine par la fin
526 for (exp.Init(wfirst.Oriented(TopAbs_FORWARD),TopAbs_EDGE);
527 exp.More(); exp.Next()) {
528 const TopoDS_Edge& edg = TopoDS::Edge(exp.Current());
529 if (MapE.Contains(edg) && !myDblE.Contains(edg)) {
533 orient = edg.Orientation();
534 TopExp::Vertices(edg,vdeb,vfin);
535 if (orient == TopAbs_FORWARD && Vlast.IsSame(vdeb)) {
536 PossE.Add(edg.Oriented(orient));
538 else if (orient == TopAbs_REVERSED && Vlast.IsSame(vfin)) {
539 PossE.Add(edg.Oriented(orient));
542 nbPoss = PossE.Extent();
544 itm.Initialize(PossE);
545 TopoDS_Shape aLocalFace = FaceRef.Oriented(wfirst.Orientation());
546 C2d = BRep_Tool::CurveOnSurface(TopoDS::Edge(itm.Key()),
547 TopoDS::Face(aLocalFace), f, l);
548 // C2d = BRep_Tool::CurveOnSurface
549 // (TopoDS::Edge(itm.Key()),
550 // TopoDS::Face(FaceRef.Oriented(wfirst.Orientation())),
552 if (itm.Key().Orientation() == TopAbs_FORWARD) {
553 // plast = C2d->Value(l);
554 C2d->D1(l,plast,dlast);
557 // plast = C2d->Value(f);
558 C2d->D1(f,plast,dlast);
562 else if (nbPoss > 1) {
563 // Faire choix en U,V...
564 TopoDS_Shape aLocalFace = FaceRef.Oriented(wfirst.Orientation());
566 toll = Max(BAS.UResolution(toll), BAS.VResolution(toll));
568 ChoixUV(LastEdge, TopoDS::Face(aLocalFace), PossE,
569 itm, plast, dlast, toll);
571 // TopoDS::Face(FaceRef.Oriented(wfirst.Orientation())),
580 B.Add(newW1,itm.Key());
581 if (MapE.Contains(itm.Key())) {
582 myDblE.Remove(itm.Key());
587 LastEdge = TopoDS::Edge(itm.Key());
588 if (LastEdge.Orientation() == TopAbs_FORWARD) {
589 Vlast = TopExp::LastVertex(LastEdge);
592 Vlast = TopExp::FirstVertex(LastEdge);
595 toll = BRep_Tool::Tolerance(Vlast);
596 tol1 = Max(tolf, toll);
599 //MODIFICATION PIERRE SMEYERS : si pas de possibilite, on sort avec erreur
601 cout<<"erreur Spliter : pas de chainage du wire"<<endl;
602 Standard_ConstructionError::Raise();
606 tol1 = Max(BAS.UResolution(tol1), BAS.VResolution(tol1));
609 cond = !(Vfirst.IsSame(Vlast) && SameUV(pfirst,plast,BAS));
612 cond = !(Vfirst.IsSame(Vlast));
617 for (exp.Init(wfirst.Oriented(TopAbs_FORWARD),TopAbs_EDGE);
618 exp.More(); exp.Next()) {
619 const TopoDS_Edge& edg = TopoDS::Edge(exp.Current());
620 if (!MapE.Contains(edg)) {
624 else if (myDblE.Contains(edg)) {
625 for (itm.Initialize(MapE); itm.More(); itm.Next()) {
626 const TopoDS_Edge& edg2 = TopoDS::Edge(itm.Key());
627 if (edg.IsSame(edg2) && edg.Orientation() != edg2.Orientation()) {
635 TopoDS_Face newF1,newF2;
636 aLocalFace = FaceRef.EmptyCopied();
637 newF1 = TopoDS::Face(aLocalFace);
638 newF1.Orientation(TopAbs_FORWARD);
639 aLocalFace = FaceRef.EmptyCopied();
640 newF2 = TopoDS::Face(aLocalFace);
641 // newF2 = TopoDS::Face(FaceRef.EmptyCopied());
642 newF2.Orientation(TopAbs_FORWARD);
644 // modifs JAG 97.05.28
646 TopAbs_Orientation orfila;
648 TopAbs_Orientation orfila=TopAbs_FORWARD;
650 for (exp.Init(FaceRef.Oriented(TopAbs_FORWARD),TopAbs_WIRE);
651 exp.More(); exp.Next()) {
652 const TopoDS_Wire& wir = TopoDS::Wire(exp.Current());
653 if (wir.IsSame(wfirst)) {
654 orfila = exp.Current().Orientation();
659 B.Add(newF1,newW1.Oriented(orfila));
660 B.Add(newF2,newW2.Oriented(orfila));
661 // Standard_Boolean exch = Standard_False;
662 BRepTopAdaptor_FClass2d classif(newF1,Precision::PConfusion());
663 if (classif.PerformInfinitePoint() == TopAbs_OUT) {
664 BRepTopAdaptor_FClass2d classi(newF2,Precision::PConfusion());
665 if (classi.PerformInfinitePoint() == TopAbs_IN) {
666 TopoDS_Face tempF = newF2;
672 for (exp.ReInit(); exp.More(); exp.Next()) {
673 const TopoDS_Wire& wir = TopoDS::Wire(exp.Current());
674 if (!wir.IsSame(wfirst)) {
675 // if (IsInside(F,wir,newW1) || IsInside(F,newW1,wir)) {
676 if (IsInside(newF1, wir)) {
679 else if (IsInside(newF2, wir)) {
683 // Ce wire est ni dans newF2 ni dans newF1
684 // Peut etre faut il construire une troisieme face
685 cout << "WARNING: LocOpe_SPlitShape : Ce wire est ni dans newF2 ni dans newF1" << endl;
692 // Mise a jour des descendants des wires
693 for (exp.Init(F,TopAbs_WIRE); exp.More(); exp.Next()) {
694 TopTools_ListOfShape& ls = myMap(exp.Current());
696 for (; itl.More(); itl.Next()) {
697 if (itl.Value().IsSame(wfirst)) {
701 if (itl.More()) { // on a trouve le wire
709 // on ne cree qu`une seule face
710 TopoDS_Wire outerW = BRepTools::OuterWire(FaceRef);
714 newWire.Orientation(TopAbs_FORWARD);
715 TopAbs_Orientation orient,orRelat;
717 if (wfirst.Orientation() == wlast.Orientation()) {
718 orRelat = TopAbs_FORWARD;
721 orRelat = TopAbs_REVERSED;
724 if (wlast.IsSame(outerW)) {
730 for (exp.Init(wfirst.Oriented(TopAbs_FORWARD),TopAbs_EDGE);
731 exp.More(); exp.Next()) {
732 B.Add(newWire,TopoDS::Edge(exp.Current()));
736 for (exp.Init(wlast.Oriented(TopAbs_FORWARD),TopAbs_EDGE);
737 exp.More(); exp.Next()) {
738 const TopoDS_Edge& edg = TopoDS::Edge(exp.Current());
739 orient = TopAbs::Compose(edg.Orientation(),orRelat);
740 B.Add(newWire,edg.Oriented(orient));
744 // Edges du wire ajoute, et dans les 2 sens
745 for (exp.Init(W.Oriented(TopAbs_FORWARD),TopAbs_EDGE);
746 exp.More(); exp.Next()) {
747 const TopoDS_Edge& edg = TopoDS::Edge(exp.Current());
748 orient = edg.Orientation();
749 B.Add(newWire,edg.Oriented(orient));
750 B.Add(newWire,edg.Oriented(TopAbs::Reverse(orient)));
751 myDblE.Add(edg.Oriented(orient));
754 // on refait une face
756 TopoDS_Shape aLocalFace = FaceRef.EmptyCopied();
757 newFace = TopoDS::Face(aLocalFace);
758 // newFace = TopoDS::Face(FaceRef.EmptyCopied());
759 FaceRef.Orientation(TopAbs_FORWARD);
760 for (exp.Init(FaceRef.Oriented(TopAbs_FORWARD),TopAbs_WIRE);
761 exp.More(); exp.Next()) {
762 const TopoDS_Wire& wir = TopoDS::Wire(exp.Current());
763 if (wir.IsSame(wfirst)) {
764 B.Add(newFace,newWire.Oriented(wir.Orientation()));
766 else if (!wir.IsSame(wlast)) {
772 // Mise a jour des descendants des wires
773 for (exp.Init(F,TopAbs_WIRE); exp.More(); exp.Next()) {
774 TopTools_ListOfShape& ls = myMap(exp.Current());
776 Standard_Boolean touch = Standard_False;
778 if (itl.Value().IsSame(wfirst) || itl.Value().IsSame(wlast)) {
780 touch = Standard_True;
795 //=======================================================================
798 //=======================================================================
800 const TopTools_ListOfShape& LocOpe_SplitShape::LeftOf(const TopoDS_Wire& W,
801 const TopoDS_Face& F)
803 if (myShape.IsNull()) {
804 Standard_NoSuchObject::Raise();
807 TopExp_Explorer exp,expw,expf;
808 exp.Init(myShape,TopAbs_FACE);
809 for (; exp.More(); exp.Next()) {
810 if (exp.Current().IsSame(F)) {
815 Standard_NoSuchObject::Raise();
819 const TopoDS_Face& theFace = TopoDS::Face(exp.Current());
820 TopAbs_Orientation orFace = theFace.Orientation();
821 TopTools_ListIteratorOfListOfShape itl,itl2;
823 for (expw.Init(W,TopAbs_EDGE); expw.More(); expw.Next()) {
824 const TopoDS_Edge& edg = TopoDS::Edge(expw.Current());
825 for (itl.Initialize(myMap(theFace)); itl.More(); itl.Next()) {
826 TopoDS_Face fac = TopoDS::Face(itl.Value());
827 fac.Orientation(orFace);
828 for (expf.Init(fac,TopAbs_EDGE); expf.More(); expf.Next()) {
829 const TopoDS_Edge& edgbis = TopoDS::Edge(expf.Current());
830 if (edgbis.IsSame(edg) &&
831 edgbis.Orientation() == edg.Orientation()) {
832 for (itl2.Initialize(myLeft); itl2.More(); itl2.Next()) {
833 if (itl2.Value().IsSame(fac)) {
837 if (!itl2.More()) { // la face n`est pas deja presente
843 if (expf.More()) { // face found
852 //=======================================================================
853 //function : DescendantShapes
855 //=======================================================================
857 const TopTools_ListOfShape& LocOpe_SplitShape::DescendantShapes
858 (const TopoDS_Shape& S)
862 myDone = Standard_True;
865 if (!myDblE.IsEmpty()) {
866 cout << "Le shape comporte des faces invalides" << endl;
874 //=======================================================================
877 //=======================================================================
879 void LocOpe_SplitShape::Put(const TopoDS_Shape& S)
881 if (!myMap.IsBound(S)) {
882 TopTools_ListOfShape thelist;
883 myMap.Bind(S, thelist);
884 if (S.ShapeType() != TopAbs_VERTEX) {
885 for(TopoDS_Iterator theIterator(S);theIterator.More();
886 theIterator.Next()) {
887 Put(theIterator.Value());
897 //=======================================================================
900 //=======================================================================
902 Standard_Boolean LocOpe_SplitShape::Rebuild(const TopoDS_Shape& S)
906 TopTools_ListIteratorOfListOfShape itr(myMap(S));
908 if (itr.Value().IsSame(S)) {
909 return Standard_False;
911 return Standard_True;
913 Standard_Boolean rebuild = Standard_False;
915 for(it.Initialize(S); it.More(); it.Next()) {
916 rebuild = Rebuild(it.Value()) || rebuild;
921 TopoDS_Shape result = S.EmptyCopied();
922 TopAbs_Orientation orient;
923 for(it.Initialize(S); it.More(); it.Next()) {
924 orient = it.Value().Orientation();
925 for (itr.Initialize(myMap(it.Value())); itr.More(); itr.Next()) {
926 B.Add(result,itr.Value().Oriented(orient));
929 myMap(S).Append(result);
939 //=======================================================================
940 //function : IsInside
942 //=======================================================================
944 static Standard_Boolean IsInside(const TopoDS_Face& F,
945 const TopoDS_Wire& W1,
946 const TopoDS_Wire& W2)
948 // Attention, c`est tres boeuf !!!!
950 TopoDS_Shape aLocalShape = F.EmptyCopied();
951 TopoDS_Face newFace = TopoDS::Face(aLocalShape);
952 // TopoDS_Face newFace = TopoDS::Face(F.EmptyCopied());
954 TopAbs_Orientation orWire =
957 newFace.Orientation(TopAbs_FORWARD);
960 // BRepGProp::SurfaceProperties(newFace,GP);
961 // if (GP.Mass() < 0) {
962 BRepTopAdaptor_FClass2d classif(newFace,Precision::PConfusion());
963 Standard_Boolean Reversed = Standard_False;
964 if (classif.PerformInfinitePoint() == TopAbs_IN) {
965 //le wire donne defini un trou
966 // newFace = TopoDS::Face(F.EmptyCopied());
967 // newFace.Orientation(TopAbs_FORWARD);
968 // orWire = TopAbs::Reverse(orWire);
969 // B.Add(newFace,W2.Oriented(orWire));
970 Reversed = Standard_True;
973 // Standard_Real U,V;
974 TopExp_Explorer exp(W1,TopAbs_EDGE);
975 const TopoDS_Edge& edg = TopoDS::Edge(exp.Current());
976 TopExp_Explorer exp2(edg,TopAbs_VERTEX);
977 const TopoDS_Vertex& vtx = TopoDS::Vertex(exp2.Current());
978 Standard_Real prm = BRep_Tool::Parameter(vtx,edg);
980 Handle(Geom2d_Curve) C2d = BRep_Tool::CurveOnSurface(edg,F,f,l);
983 cout << "Edge is not on surface" <<endl;
985 return Standard_False;
987 gp_Pnt2d pt2d(C2d->Value(prm));
988 // BRepClass_FaceClassifier classif(newFace,pt2d,Precision::PConfusion());
989 // return (classif.State() == TopAbs_IN);
991 return (classif.Perform(pt2d) == TopAbs_IN);
994 return (classif.Perform(pt2d) == TopAbs_OUT);
999 //=======================================================================
1000 //function : IsInside
1002 //=======================================================================
1004 static Standard_Boolean IsInside(const TopoDS_Face& F,
1005 const TopoDS_Wire& W)
1007 // Attention, c`est tres boeuf !!!!
1008 TopExp_Explorer exp(W,TopAbs_EDGE);
1009 for( ; exp.More(); exp.Next()) {
1010 const TopoDS_Edge& edg = TopoDS::Edge(exp.Current());
1011 // TopExp_Explorer exp2(edg,TopAbs_VERTEX);
1012 // const TopoDS_Vertex& vtx = TopoDS::Vertex(exp2.Current());
1013 // Standard_Real prm = BRep_Tool::Parameter(vtx,edg);
1014 Standard_Real f,l,prm;
1015 Handle(Geom2d_Curve) C2d = BRep_Tool::CurveOnSurface(edg,F,f,l);
1016 if (!Precision::IsNegativeInfinite(f) &&
1017 !Precision::IsPositiveInfinite(l)) {
1021 if (Precision::IsNegativeInfinite(f) &&
1022 Precision::IsPositiveInfinite(l)){
1025 else if (Precision::IsNegativeInfinite(f)) {
1033 gp_Pnt2d pt2d(C2d->Value(prm));
1034 // BRepClass_FaceClassifier classif(F,pt2d,Precision::PConfusion());
1035 // return (classif.State() != TopAbs_OUT);
1036 BRepTopAdaptor_FClass2d classif(F,Precision::PConfusion());
1037 Standard_Boolean stat = classif.Perform(pt2d);
1038 // return (classif.Perform(pt2d) != TopAbs_OUT);
1039 if(stat == TopAbs_OUT) return Standard_False;
1041 if(stat == TopAbs_ON) {
1042 Standard_Integer nbPnt =10;
1043 Standard_Integer nbOut =0,nbIn =0,nbOn=0;
1044 Standard_Integer j =1;
1045 for( ; j<= nbPnt ; j++)
1047 //check neighbouring point
1048 //prm = .66 * prm + .34 * l;
1049 prm = f + (l-f)/nbPnt*(j-1);
1050 pt2d = C2d->Value(prm);
1051 stat = classif.Perform(pt2d);
1052 if(stat == TopAbs_OUT )
1054 else if(stat == TopAbs_IN)
1059 if(nbOut > nbIn + nbOn)
1060 return Standard_False;
1063 return Standard_True;
1067 //=======================================================================
1068 //function : ChoixUV
1070 //=======================================================================
1072 static void ChoixUV(const TopoDS_Edge& Last,
1073 const TopoDS_Face& F,
1074 const TopTools_MapOfShape& Poss,
1075 TopTools_MapIteratorOfMapOfShape& It,
1078 const Standard_Real toll)
1082 // gp_Pnt2d p2d,psav;
1086 BRepAdaptor_Surface surf(F,Standard_False); // no restriction
1087 // Standard_Real tol = Precision::PConfusion() //BRep_Tool::Tolerance(Last));
1093 gp_Dir2d ref2d(dlst);
1095 Handle(Geom2d_Curve) C2d;
1097 Standard_Integer index = 0, imin=0;
1098 Standard_Real angmax = -M_PI, dist, ang;
1101 for (It.Initialize(Poss); It.More(); It.Next()) {
1103 C2d = BRep_Tool::CurveOnSurface(TopoDS::Edge(It.Key()),F,f,l);
1104 if (It.Key().Orientation() == TopAbs_FORWARD) {
1105 // p2d = C2d->Value(f);
1107 vtx = TopExp::FirstVertex(TopoDS::Edge(It.Key()));
1110 // p2d = C2d->Value(l);
1113 vtx = TopExp::LastVertex(TopoDS::Edge(It.Key()));
1116 if (surf.IsUPeriodic())
1117 if ((fabs(p2d.Y() - plst.Y()) <= toll) ||
1118 ((surf.IsVPeriodic()) &&
1119 (fabs(fabs(p2d.Y() - plst.Y()) - surf.VPeriod()) <= toll)))
1120 if (fabs(p2d.X() - plst.X() - surf.UPeriod()) <= toll)
1121 p2d.SetX(p2d.X() - surf.UPeriod());
1122 else if (fabs(plst.X() - p2d.X() - surf.UPeriod()) <= toll)
1123 p2d.SetX(p2d.X() + surf.UPeriod());
1125 if (surf.IsVPeriodic())
1126 if (fabs(p2d.X() - plst.X()) <= toll)
1127 if (fabs(p2d.Y() - plst.Y() - surf.VPeriod()) <= toll)
1128 p2d.SetY(p2d.Y() - surf.VPeriod());
1129 else if (fabs(plst.Y() - p2d.Y() - surf.VPeriod()) <= toll)
1130 p2d.SetY(p2d.Y() + surf.VPeriod());
1132 tol = BRep_Tool::Tolerance(vtx);
1133 tol = Max(surf.UResolution(tol), surf.VResolution(tol));
1134 tol = Max(toll, tol); tol *= tol;
1136 dist = p2d.SquareDistance(plst);
1138 if (!Last.IsSame(It.Key())) {
1139 ang = ref2d.Angle(gp_Dir2d(v2d));
1145 //if ((dist < dmin - tol) ||
1146 //(dist <= dmin+tol && ang > angmax)) {
1147 if ((dist < tol) && (ang > angmax)) {
1154 for (index = 1, It.Initialize(Poss); It.More(); It.Next()) {
1155 if (index == imin) {
1156 C2d = BRep_Tool::CurveOnSurface(TopoDS::Edge(It.Key()),F,f,l);
1157 if (It.Key().Orientation() == TopAbs_FORWARD) {
1158 // plst = C2d->Value(l);
1159 C2d->D1(l,plst,dlst);
1162 // plst = C2d->Value(f);
1163 C2d->D1(f,plst,dlst);