1 // Created on: 1995-06-27
2 // Created by: Jacques GOUSSARD
3 // Copyright (c) 1995-1999 Matra Datavision
4 // Copyright (c) 1999-2012 OPEN CASCADE SAS
6 // The content of this file is subject to the Open CASCADE Technology Public
7 // License Version 6.5 (the "License"). You may not use the content of this file
8 // except in compliance with the License. Please obtain a copy of the License
9 // at http://www.opencascade.org and read it completely before using this file.
11 // The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
12 // main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
14 // The Original Code and all software distributed under the License is
15 // distributed on an "AS IS" basis, without warranty of any kind, and the
16 // Initial Developer hereby disclaims all such warranties, including without
17 // limitation, any warranties of merchantability, fitness for a particular
18 // purpose or non-infringement. Please see the License for the specific terms
19 // and conditions governing the rights and limitations under the License.
23 #include <LocOpe_SplitShape.ixx>
25 #include <TopTools_ListOfShape.hxx>
26 #include <TopTools_ListIteratorOfListOfShape.hxx>
27 #include <TopTools_MapOfShape.hxx>
28 #include <TopTools_DataMapOfShapeListOfShape.hxx>
29 #include <TopTools_DataMapIteratorOfDataMapOfShapeListOfShape.hxx>
30 #include <TopTools_MapIteratorOfMapOfShape.hxx>
31 #include <TopoDS_Iterator.hxx>
32 #include <TopExp_Explorer.hxx>
33 #include <BRep_Builder.hxx>
34 #include <TopoDS_Vertex.hxx>
35 #include <BRepLib_MakeFace.hxx>
36 #include <BRep_Tool.hxx>
37 #include <BRepTools.hxx>
38 #include <BRep_Builder.hxx>
40 #include <BRepClass_FaceExplorer.hxx>
41 #include <BRepTopAdaptor_FClass2d.hxx>
42 #include <BRepAdaptor_Surface.hxx>
44 #include <Geom2d_Curve.hxx>
45 #include <gp_Pnt2d.hxx>
46 #include <gp_Vec2d.hxx>
47 #include <gp_Dir2d.hxx>
50 #include <Precision.hxx>
51 #include <BRepTools.hxx>
53 #include <Standard_ErrorHandler.hxx>
55 static Standard_Boolean IsInside(const TopoDS_Face&,
59 static Standard_Boolean IsInside(const TopoDS_Face&,
62 static void ChoixUV(const TopoDS_Edge&,
64 const TopTools_MapOfShape&,
65 TopTools_MapIteratorOfMapOfShape&,
68 const Standard_Real tol);
70 inline Standard_Boolean SameUV(const gp_Pnt2d& P1, const gp_Pnt2d& P2,
71 const BRepAdaptor_Surface& theBAS)//const Standard_Real tol)
73 // Standard_Real tol = Precision::Confusion();
74 // return P1.SquareDistance(P2) < 10*tol;
76 Standard_Boolean isSame = Standard_True;
77 if(theBAS.IsUPeriodic())
78 isSame = (fabs(P1.X() - P2.X()) < theBAS.UPeriod() *0.5);
79 if(theBAS.IsVPeriodic())
80 isSame = (isSame && (fabs(P1.Y() - P2.Y()) < theBAS.VPeriod() *0.5));
82 //return P1.SquareDistance(P2) < tol * tol; //IFV
87 //=======================================================================
90 //=======================================================================
92 void LocOpe_SplitShape::Init(const TopoDS_Shape& S)
94 myDone = Standard_False;
102 //=======================================================================
103 //function : CanSplit
105 //=======================================================================
107 Standard_Boolean LocOpe_SplitShape::CanSplit(const TopoDS_Edge& E) const
110 return Standard_False;
112 if (myMap.IsEmpty()) {
113 return Standard_False;
116 if (!myMap.IsBound(E)) {
117 return Standard_False;
120 // On verifie que l`edge n`appartient pas a un wire deja reconstruit
122 TopTools_DataMapIteratorOfDataMapOfShapeListOfShape itm(myMap);
123 for (; itm.More(); itm.Next()) {
124 if (itm.Key().ShapeType() == TopAbs_WIRE && !itm.Value().IsEmpty()) {
125 for (exp.Init(itm.Key(),TopAbs_EDGE); exp.More(); exp.Next()) {
126 if (exp.Current().IsSame(E)) {
127 return Standard_False;
132 return Standard_True;
136 //=======================================================================
139 //=======================================================================
141 void LocOpe_SplitShape::Add(const TopoDS_Vertex& V,
142 const Standard_Real P,
143 const TopoDS_Edge& E)
146 Standard_ConstructionError::Raise();
150 TopTools_ListOfShape& le = myMap(E);
154 TopTools_ListIteratorOfListOfShape itl(le);
157 for (; itl.More(); itl.Next()) {
158 const TopoDS_Edge& edg = TopoDS::Edge(itl.Value());
159 BRep_Tool::Range(edg,f,l);
165 Standard_ConstructionError::Raise();
167 TopoDS_Edge edg = TopoDS::Edge(itl.Value());
169 if (V.Orientation() == TopAbs_FORWARD ||
170 V.Orientation() == TopAbs_REVERSED) {
172 TopoDS_Shape aLocalShape = edg.EmptyCopied();
173 TopoDS_Edge E1 = TopoDS::Edge(aLocalShape);
174 aLocalShape = edg.EmptyCopied();
175 TopoDS_Edge E2 = TopoDS::Edge(aLocalShape);
176 // TopoDS_Edge E1 = TopoDS::Edge(edg.EmptyCopied());
177 // TopoDS_Edge E2 = TopoDS::Edge(edg.EmptyCopied());
178 E1.Orientation(TopAbs_FORWARD);
179 E2.Orientation(TopAbs_FORWARD);
180 TopoDS_Vertex newVtx = V;
181 newVtx.Orientation(TopAbs_REVERSED);
183 B.UpdateVertex(newVtx,P,E1,BRep_Tool::Tolerance(V));
184 newVtx.Orientation(TopAbs_FORWARD);
186 B.UpdateVertex(newVtx,P,E2,BRep_Tool::Tolerance(V));
187 edg.Orientation(TopAbs_FORWARD);
189 for (exp.Init(edg,TopAbs_VERTEX); exp.More(); exp.Next()) {
190 // for (TopExp_Explorer exp(edg,TopAbs_VERTEX); exp.More(); exp.Next()) {
191 const TopoDS_Vertex& vtx = TopoDS::Vertex(exp.Current());
192 f = BRep_Tool::Parameter(vtx,edg);
195 B.UpdateVertex(vtx,f,E1,BRep_Tool::Tolerance(vtx));
199 B.UpdateVertex(vtx,f,E2,BRep_Tool::Tolerance(vtx));
206 TopoDS_Shape aLocalShape = edg.EmptyCopied();
207 TopoDS_Edge E1 = TopoDS::Edge(aLocalShape);
208 // TopoDS_Edge E1 = TopoDS::Edge(edg.EmptyCopied());
210 for (exp.Init(edg,TopAbs_VERTEX); exp.More(); exp.Next()) {
211 // for (TopExp_Explorer exp(edg,TopAbs_VERTEX); exp.More(); exp.Next()) {
212 const TopoDS_Vertex& vtx = TopoDS::Vertex(exp.Current());
213 f = BRep_Tool::Parameter(vtx,edg);
215 B.UpdateVertex(vtx,f,E1,BRep_Tool::Tolerance(vtx));
218 B.UpdateVertex(V,P,E1,BRep_Tool::Tolerance(V));
225 //=======================================================================
228 //=======================================================================
230 void LocOpe_SplitShape::Add(const TopoDS_Wire& W,
231 const TopoDS_Face& F)
235 Standard_ConstructionError::Raise();
240 TopTools_ListOfShape& lf = myMap(F);
246 if (!LocOpe::Closed(W,F)) {
252 } catch (Standard_Failure ) {
254 cout << "Warning: SpliShape internal problem detected, some faces may be lost. Check input edges/wires" <<endl;
258 // JAG 10.11.95 Codage des regularites
260 for (exp.Init(W,TopAbs_EDGE); exp.More(); exp.Next()) {
261 const TopoDS_Edge& edg = TopoDS::Edge(exp.Current());
262 if (!BRep_Tool::HasContinuity(edg,F,F)) {
263 B.Continuity(edg,F,F,GeomAbs_CN);
270 //=======================================================================
271 //function : AddClosedWire
273 //=======================================================================
275 void LocOpe_SplitShape::AddClosedWire(const TopoDS_Wire& W,
276 const TopoDS_Face& F)
280 // On cherche la face descendante de F qui continent le wire
281 TopTools_ListOfShape& lf = myMap(F);
282 TopTools_ListIteratorOfListOfShape itl(lf);
284 for (; itl.More(); itl.Next()) {
285 const TopoDS_Face& fac = TopoDS::Face(itl.Value());
287 outerW = BRepTools::OuterWire(fac);
288 if (IsInside(F,W,outerW)) {
292 if (IsInside(fac,W)) {
298 Standard_ConstructionError::Raise();
303 TopAbs_Orientation orWire = W.Orientation();
304 TopoDS_Shape aLocalFace = F.EmptyCopied();
305 TopoDS_Face newFace = TopoDS::Face(aLocalFace);
306 // TopoDS_Face newFace = TopoDS::Face(F.EmptyCopied());
307 newFace.Orientation(TopAbs_FORWARD);
310 // BRepGProp::SurfaceProperties (newFace,GP);
311 // if (GP.Mass() < 0) {
312 BRepTopAdaptor_FClass2d classif(newFace,Precision::PConfusion());
313 if (classif.PerformInfinitePoint() == TopAbs_IN) {
314 //le wire donne defini un trou
315 aLocalFace = F.EmptyCopied();
316 newFace = TopoDS::Face(aLocalFace);
317 // newFace = TopoDS::Face(F.EmptyCopied());
318 newFace.Orientation(TopAbs_FORWARD);
319 orWire = TopAbs::Reverse(orWire);
320 B.Add(newFace,W.Oriented(orWire));
323 TopoDS_Face FaceRef = TopoDS::Face(itl.Value());
324 FaceRef.Orientation(TopAbs_FORWARD);
327 aLocalFace = FaceRef.EmptyCopied();
328 TopoDS_Face newRef = TopoDS::Face(aLocalFace);
329 // TopoDS_Face newRef = TopoDS::Face(FaceRef.EmptyCopied());
330 newRef.Orientation(TopAbs_FORWARD);
332 // On suppose que les edges du wire ont des courbes 2d.
333 // Comme on ne change pas de surface de base, pas besoin d`UpdateEdge.
335 for (exp.Init(FaceRef.Oriented(TopAbs_FORWARD),TopAbs_WIRE);
336 exp.More(); exp.Next()) {
337 const TopoDS_Wire& wir = TopoDS::Wire(exp.Current());
338 if (IsInside(F,wir,W)) {
345 B.Add(newRef,W.Oriented(TopAbs::Reverse(orWire)));
352 //=======================================================================
353 //function : AddOpenWire
355 //=======================================================================
357 void LocOpe_SplitShape::AddOpenWire(const TopoDS_Wire& W,
358 const TopoDS_Face& F)
360 // On cherche la face descendante de F qui continent le wire
361 TopTools_ListOfShape& lf = myMap(F);
362 TopTools_ListIteratorOfListOfShape itl(lf);
363 TopoDS_Vertex Vfirst,Vlast;
365 BRepTools::Update(F);
367 // TopExp::Vertices(W,Vfirst,Vlast);
369 Standard_Real tolf, toll, tol1;
371 TopoDS_Shape aLocalShape = W.Oriented(TopAbs_FORWARD);
372 TopExp::Vertices(TopoDS::Wire(aLocalShape),Vfirst,Vlast);
373 // TopExp::Vertices(TopoDS::Wire(W.Oriented(TopAbs_FORWARD)),Vfirst,Vlast);
375 tolf = BRep_Tool::Tolerance(Vfirst);
376 toll = BRep_Tool::Tolerance(Vlast);
377 tol1 = Max(tolf, toll);
380 TopExp_Explorer exp,exp2;
382 TopoDS_Wire wfirst,wlast;
383 for (; itl.More(); itl.Next()) {
384 const TopoDS_Face& fac = TopoDS::Face(itl.Value());
385 if (!IsInside(fac,W)) {
389 Standard_Boolean ffound = Standard_False;
390 Standard_Boolean lfound = Standard_False;
391 for (exp.Init(fac,TopAbs_WIRE); exp.More(); exp.Next()) {
392 const TopoDS_Wire& wir = TopoDS::Wire(exp.Current());
393 for (exp2.Init(wir,TopAbs_VERTEX); exp2.More(); exp2.Next()) {
394 if (!ffound && exp2.Current().IsSame(Vfirst)) {
395 ffound = Standard_True;
398 else if (!lfound && exp2.Current().IsSame(Vlast)) {
399 lfound = Standard_True;
402 if (ffound && lfound) {
415 Standard_ConstructionError::Raise();
418 TopoDS_Face FaceRef = TopoDS::Face(itl.Value());
419 FaceRef.Orientation(TopAbs_FORWARD);
423 BRepAdaptor_Surface BAS(FaceRef, Standard_False);
425 Standard_Boolean IsPeriodic = BAS.IsUPeriodic() || BAS.IsVPeriodic();
427 tol1 = Max(BAS.UResolution(tol1), BAS.VResolution(tol1));
429 if (wfirst.IsSame(wlast)) {
430 // on cree 2 faces en remplacement de itl.Value()
433 for (exp.Init(wfirst,TopAbs_EDGE); exp.More(); exp.Next()) {
434 if (BRep_Tool::IsClosed(TopoDS::Edge(exp.Current()),FaceRef)) {
435 myDblE.Add(exp.Current());
439 TopAbs_Orientation orient;
440 TopoDS_Wire newW1,newW2;
442 newW1.Orientation(TopAbs_FORWARD);
444 newW2.Orientation(TopAbs_FORWARD);
446 Standard_Integer nbE = 0;
447 for (exp.Init(W.Oriented(TopAbs_FORWARD),TopAbs_EDGE);
448 exp.More(); exp.Next()) {
450 const TopoDS_Edge& edg = TopoDS::Edge(exp.Current());
451 orient = edg.Orientation();
453 B.Add(newW2,edg.Oriented(TopAbs::Reverse(orient)));
456 TopTools_MapOfShape MapE, PossE;
457 TopTools_MapIteratorOfMapOfShape itm;
458 TopoDS_Vertex vdeb,vfin;
459 Standard_Integer nbPoss;
461 // On recherche l`edge contenant Vlast
462 TopoDS_Edge LastEdge;
463 gp_Pnt2d pfirst,plast;
465 Handle(Geom2d_Curve) C2d;
468 for (exp.Init(W.Oriented(TopAbs_FORWARD),TopAbs_EDGE);
469 exp.More(); exp.Next()) {
470 const TopoDS_Edge& edg = TopoDS::Edge(exp.Current());
471 for (exp2.Init(edg,TopAbs_VERTEX); exp2.More(); exp2.Next()) {
472 if (exp2.Current().IsSame(Vfirst)) {
478 LastEdge.Orientation(edg.Orientation());
483 TopoDS_Shape aLocalFace = FaceRef.Oriented(wfirst.Orientation());
484 C2d = BRep_Tool::CurveOnSurface(LastEdge, TopoDS::Face(aLocalFace), f, l);
485 // C2d = BRep_Tool::CurveOnSurface
487 // TopoDS::Face(FaceRef.Oriented(wfirst.Orientation())),
489 if (LastEdge.Orientation() == TopAbs_FORWARD) {
490 pfirst = C2d->Value(f);
493 pfirst = C2d->Value(l);
496 for (exp.Init(W.Oriented(TopAbs_FORWARD),TopAbs_EDGE);
497 exp.More(); exp.Next()) {
498 const TopoDS_Edge& edg = TopoDS::Edge(exp.Current());
499 if( nbE>1 && edg.IsSame(LastEdge) )
501 for (exp2.Init(edg,TopAbs_VERTEX); exp2.More(); exp2.Next()) {
502 if (exp2.Current().IsSame(Vlast)) {
508 LastEdge.Orientation(edg.Orientation());
512 aLocalFace = FaceRef.Oriented(wfirst.Orientation());
513 C2d = BRep_Tool::CurveOnSurface(LastEdge, TopoDS::Face(aLocalFace), f, l);
514 // C2d = BRep_Tool::CurveOnSurface
516 // TopoDS::Face(FaceRef.Oriented(wfirst.Orientation())),
518 if (LastEdge.Orientation() == TopAbs_FORWARD) {
519 C2d->D1(l,plast,dlast);
520 // plast = C2d->Value(l);
523 // plast = C2d->Value(f);
524 C2d->D1(f,plast,dlast);
528 Standard_Boolean cond;
532 cond = !(Vfirst.IsSame(Vlast) && SameUV(pfirst,plast,BAS));
535 cond = !(Vfirst.IsSame(Vlast));
541 // On enchaine par la fin
542 for (exp.Init(wfirst.Oriented(TopAbs_FORWARD),TopAbs_EDGE);
543 exp.More(); exp.Next()) {
544 const TopoDS_Edge& edg = TopoDS::Edge(exp.Current());
545 if (MapE.Contains(edg) && !myDblE.Contains(edg)) {
549 orient = edg.Orientation();
550 TopExp::Vertices(edg,vdeb,vfin);
551 if (orient == TopAbs_FORWARD && Vlast.IsSame(vdeb)) {
552 PossE.Add(edg.Oriented(orient));
554 else if (orient == TopAbs_REVERSED && Vlast.IsSame(vfin)) {
555 PossE.Add(edg.Oriented(orient));
558 nbPoss = PossE.Extent();
560 itm.Initialize(PossE);
561 TopoDS_Shape aLocalFace = FaceRef.Oriented(wfirst.Orientation());
562 C2d = BRep_Tool::CurveOnSurface(TopoDS::Edge(itm.Key()),
563 TopoDS::Face(aLocalFace), f, l);
564 // C2d = BRep_Tool::CurveOnSurface
565 // (TopoDS::Edge(itm.Key()),
566 // TopoDS::Face(FaceRef.Oriented(wfirst.Orientation())),
568 if (itm.Key().Orientation() == TopAbs_FORWARD) {
569 // plast = C2d->Value(l);
570 C2d->D1(l,plast,dlast);
573 // plast = C2d->Value(f);
574 C2d->D1(f,plast,dlast);
578 else if (nbPoss > 1) {
579 // Faire choix en U,V...
580 TopoDS_Shape aLocalFace = FaceRef.Oriented(wfirst.Orientation());
582 ChoixUV(LastEdge, TopoDS::Face(aLocalFace), PossE,
583 itm, plast, dlast, toll);
585 // TopoDS::Face(FaceRef.Oriented(wfirst.Orientation())),
594 B.Add(newW1,itm.Key());
595 if (MapE.Contains(itm.Key())) {
596 myDblE.Remove(itm.Key());
601 LastEdge = TopoDS::Edge(itm.Key());
602 if (LastEdge.Orientation() == TopAbs_FORWARD) {
603 Vlast = TopExp::LastVertex(LastEdge);
606 Vlast = TopExp::FirstVertex(LastEdge);
609 toll = BRep_Tool::Tolerance(Vlast);
610 tol1 = Max(tolf, toll);
613 //MODIFICATION PIERRE SMEYERS : si pas de possibilite, on sort avec erreur
615 cout<<"erreur Spliter : pas de chainage du wire"<<endl;
616 Standard_ConstructionError::Raise();
620 tol1 = Max(BAS.UResolution(tol1), BAS.VResolution(tol1));
623 cond = !(Vfirst.IsSame(Vlast) && SameUV(pfirst,plast,BAS));
626 cond = !(Vfirst.IsSame(Vlast));
631 for (exp.Init(wfirst.Oriented(TopAbs_FORWARD),TopAbs_EDGE);
632 exp.More(); exp.Next()) {
633 const TopoDS_Edge& edg = TopoDS::Edge(exp.Current());
634 if (!MapE.Contains(edg)) {
638 else if (myDblE.Contains(edg)) {
639 for (itm.Initialize(MapE); itm.More(); itm.Next()) {
640 const TopoDS_Edge& edg2 = TopoDS::Edge(itm.Key());
641 if (edg.IsSame(edg2) && edg.Orientation() != edg2.Orientation()) {
649 TopoDS_Face newF1,newF2;
650 aLocalFace = FaceRef.EmptyCopied();
651 newF1 = TopoDS::Face(aLocalFace);
652 newF1.Orientation(TopAbs_FORWARD);
653 aLocalFace = FaceRef.EmptyCopied();
654 newF2 = TopoDS::Face(aLocalFace);
655 // newF2 = TopoDS::Face(FaceRef.EmptyCopied());
656 newF2.Orientation(TopAbs_FORWARD);
658 // modifs JAG 97.05.28
660 TopAbs_Orientation orfila;
662 TopAbs_Orientation orfila=TopAbs_FORWARD;
664 for (exp.Init(FaceRef.Oriented(TopAbs_FORWARD),TopAbs_WIRE);
665 exp.More(); exp.Next()) {
666 const TopoDS_Wire& wir = TopoDS::Wire(exp.Current());
667 if (wir.IsSame(wfirst)) {
668 orfila = exp.Current().Orientation();
673 B.Add(newF1,newW1.Oriented(orfila));
674 B.Add(newF2,newW2.Oriented(orfila));
675 // Standard_Boolean exch = Standard_False;
676 BRepTopAdaptor_FClass2d classif(newF1,Precision::PConfusion());
677 if (classif.PerformInfinitePoint() == TopAbs_OUT) {
678 BRepTopAdaptor_FClass2d classi(newF2,Precision::PConfusion());
679 if (classi.PerformInfinitePoint() == TopAbs_IN) {
680 TopoDS_Face tempF = newF2;
686 for (exp.ReInit(); exp.More(); exp.Next()) {
687 const TopoDS_Wire& wir = TopoDS::Wire(exp.Current());
688 if (!wir.IsSame(wfirst)) {
689 // if (IsInside(F,wir,newW1) || IsInside(F,newW1,wir)) {
690 if (IsInside(newF1, wir)) {
693 else if (IsInside(newF2, wir)) {
697 // Ce wire est ni dans newF2 ni dans newF1
698 // Peut etre faut il construire une troisieme face
699 cout << "WARNING: LocOpe_SPlitShape : Ce wire est ni dans newF2 ni dans newF1" << endl;
706 // Mise a jour des descendants des wires
707 for (exp.Init(F,TopAbs_WIRE); exp.More(); exp.Next()) {
708 TopTools_ListOfShape& ls = myMap(exp.Current());
710 for (; itl.More(); itl.Next()) {
711 if (itl.Value().IsSame(wfirst)) {
715 if (itl.More()) { // on a trouve le wire
723 // on ne cree qu`une seule face
724 TopoDS_Wire outerW = BRepTools::OuterWire(FaceRef);
728 newWire.Orientation(TopAbs_FORWARD);
729 TopAbs_Orientation orient,orRelat;
731 if (wfirst.Orientation() == wlast.Orientation()) {
732 orRelat = TopAbs_FORWARD;
735 orRelat = TopAbs_REVERSED;
738 if (wlast.IsSame(outerW)) {
744 for (exp.Init(wfirst.Oriented(TopAbs_FORWARD),TopAbs_EDGE);
745 exp.More(); exp.Next()) {
746 B.Add(newWire,TopoDS::Edge(exp.Current()));
750 for (exp.Init(wlast.Oriented(TopAbs_FORWARD),TopAbs_EDGE);
751 exp.More(); exp.Next()) {
752 const TopoDS_Edge& edg = TopoDS::Edge(exp.Current());
753 orient = TopAbs::Compose(edg.Orientation(),orRelat);
754 B.Add(newWire,edg.Oriented(orient));
758 // Edges du wire ajoute, et dans les 2 sens
759 for (exp.Init(W.Oriented(TopAbs_FORWARD),TopAbs_EDGE);
760 exp.More(); exp.Next()) {
761 const TopoDS_Edge& edg = TopoDS::Edge(exp.Current());
762 orient = edg.Orientation();
763 B.Add(newWire,edg.Oriented(orient));
764 B.Add(newWire,edg.Oriented(TopAbs::Reverse(orient)));
765 myDblE.Add(edg.Oriented(orient));
768 // on refait une face
770 TopoDS_Shape aLocalFace = FaceRef.EmptyCopied();
771 newFace = TopoDS::Face(aLocalFace);
772 // newFace = TopoDS::Face(FaceRef.EmptyCopied());
773 FaceRef.Orientation(TopAbs_FORWARD);
774 for (exp.Init(FaceRef.Oriented(TopAbs_FORWARD),TopAbs_WIRE);
775 exp.More(); exp.Next()) {
776 const TopoDS_Wire& wir = TopoDS::Wire(exp.Current());
777 if (wir.IsSame(wfirst)) {
778 B.Add(newFace,newWire.Oriented(wir.Orientation()));
780 else if (!wir.IsSame(wlast)) {
786 // Mise a jour des descendants des wires
787 for (exp.Init(F,TopAbs_WIRE); exp.More(); exp.Next()) {
788 TopTools_ListOfShape& ls = myMap(exp.Current());
790 Standard_Boolean touch = Standard_False;
792 if (itl.Value().IsSame(wfirst) || itl.Value().IsSame(wlast)) {
794 touch = Standard_True;
809 //=======================================================================
812 //=======================================================================
814 const TopTools_ListOfShape& LocOpe_SplitShape::LeftOf(const TopoDS_Wire& W,
815 const TopoDS_Face& F)
817 if (myShape.IsNull()) {
818 Standard_NoSuchObject::Raise();
821 TopExp_Explorer exp,expw,expf;
822 exp.Init(myShape,TopAbs_FACE);
823 for (; exp.More(); exp.Next()) {
824 if (exp.Current().IsSame(F)) {
829 Standard_NoSuchObject::Raise();
833 const TopoDS_Face& theFace = TopoDS::Face(exp.Current());
834 TopAbs_Orientation orFace = theFace.Orientation();
835 TopTools_ListIteratorOfListOfShape itl,itl2;
837 for (expw.Init(W,TopAbs_EDGE); expw.More(); expw.Next()) {
838 const TopoDS_Edge& edg = TopoDS::Edge(expw.Current());
839 for (itl.Initialize(myMap(theFace)); itl.More(); itl.Next()) {
840 TopoDS_Face fac = TopoDS::Face(itl.Value());
841 fac.Orientation(orFace);
842 for (expf.Init(fac,TopAbs_EDGE); expf.More(); expf.Next()) {
843 const TopoDS_Edge& edgbis = TopoDS::Edge(expf.Current());
844 if (edgbis.IsSame(edg) &&
845 edgbis.Orientation() == edg.Orientation()) {
846 for (itl2.Initialize(myLeft); itl2.More(); itl2.Next()) {
847 if (itl2.Value().IsSame(fac)) {
851 if (!itl2.More()) { // la face n`est pas deja presente
857 if (expf.More()) { // face found
866 //=======================================================================
867 //function : DescendantShapes
869 //=======================================================================
871 const TopTools_ListOfShape& LocOpe_SplitShape::DescendantShapes
872 (const TopoDS_Shape& S)
876 myDone = Standard_True;
879 if (!myDblE.IsEmpty()) {
880 cout << "Le shape comporte des faces invalides" << endl;
888 //=======================================================================
891 //=======================================================================
893 void LocOpe_SplitShape::Put(const TopoDS_Shape& S)
895 if (!myMap.IsBound(S)) {
896 TopTools_ListOfShape thelist;
897 myMap.Bind(S, thelist);
898 if (S.ShapeType() != TopAbs_VERTEX) {
899 for(TopoDS_Iterator theIterator(S);theIterator.More();
900 theIterator.Next()) {
901 Put(theIterator.Value());
911 //=======================================================================
914 //=======================================================================
916 Standard_Boolean LocOpe_SplitShape::Rebuild(const TopoDS_Shape& S)
920 TopTools_ListIteratorOfListOfShape itr(myMap(S));
922 if (itr.Value().IsSame(S)) {
923 return Standard_False;
925 return Standard_True;
927 Standard_Boolean rebuild = Standard_False;
929 for(it.Initialize(S); it.More(); it.Next()) {
930 rebuild = Rebuild(it.Value()) || rebuild;
935 TopoDS_Shape result = S.EmptyCopied();
936 TopAbs_Orientation orient;
937 for(it.Initialize(S); it.More(); it.Next()) {
938 orient = it.Value().Orientation();
939 for (itr.Initialize(myMap(it.Value())); itr.More(); itr.Next()) {
940 B.Add(result,itr.Value().Oriented(orient));
943 myMap(S).Append(result);
953 //=======================================================================
954 //function : IsInside
956 //=======================================================================
958 static Standard_Boolean IsInside(const TopoDS_Face& F,
959 const TopoDS_Wire& W1,
960 const TopoDS_Wire& W2)
962 // Attention, c`est tres boeuf !!!!
964 TopoDS_Shape aLocalShape = F.EmptyCopied();
965 TopoDS_Face newFace = TopoDS::Face(aLocalShape);
966 // TopoDS_Face newFace = TopoDS::Face(F.EmptyCopied());
968 //TopAbs_Orientation orWire = W2.Orientation();
970 newFace.Orientation(TopAbs_FORWARD);
973 // BRepGProp::SurfaceProperties(newFace,GP);
974 // if (GP.Mass() < 0) {
975 BRepTopAdaptor_FClass2d classif(newFace,Precision::PConfusion());
976 Standard_Boolean Reversed = Standard_False;
977 if (classif.PerformInfinitePoint() == TopAbs_IN) {
978 //le wire donne defini un trou
979 // newFace = TopoDS::Face(F.EmptyCopied());
980 // newFace.Orientation(TopAbs_FORWARD);
981 // orWire = TopAbs::Reverse(orWire);
982 // B.Add(newFace,W2.Oriented(orWire));
983 Reversed = Standard_True;
986 // Standard_Real U,V;
987 TopExp_Explorer exp(W1,TopAbs_EDGE);
988 const TopoDS_Edge& edg = TopoDS::Edge(exp.Current());
989 TopExp_Explorer exp2(edg,TopAbs_VERTEX);
990 const TopoDS_Vertex& vtx = TopoDS::Vertex(exp2.Current());
991 Standard_Real prm = BRep_Tool::Parameter(vtx,edg);
993 Handle(Geom2d_Curve) C2d = BRep_Tool::CurveOnSurface(edg,F,f,l);
996 cout << "Edge is not on surface" <<endl;
998 return Standard_False;
1000 gp_Pnt2d pt2d(C2d->Value(prm));
1001 // BRepClass_FaceClassifier classif(newFace,pt2d,Precision::PConfusion());
1002 // return (classif.State() == TopAbs_IN);
1004 return (classif.Perform(pt2d) == TopAbs_IN);
1007 return (classif.Perform(pt2d) == TopAbs_OUT);
1012 //=======================================================================
1013 //function : IsInside
1015 //=======================================================================
1017 static Standard_Boolean IsInside(const TopoDS_Face& F,
1018 const TopoDS_Wire& W)
1020 // Attention, c`est tres boeuf !!!!
1021 TopExp_Explorer exp(W,TopAbs_EDGE);
1022 for( ; exp.More(); exp.Next()) {
1023 const TopoDS_Edge& edg = TopoDS::Edge(exp.Current());
1024 // TopExp_Explorer exp2(edg,TopAbs_VERTEX);
1025 // const TopoDS_Vertex& vtx = TopoDS::Vertex(exp2.Current());
1026 // Standard_Real prm = BRep_Tool::Parameter(vtx,edg);
1027 Standard_Real f,l,prm;
1028 Handle(Geom2d_Curve) C2d = BRep_Tool::CurveOnSurface(edg,F,f,l);
1029 if (!Precision::IsNegativeInfinite(f) &&
1030 !Precision::IsPositiveInfinite(l)) {
1034 if (Precision::IsNegativeInfinite(f) &&
1035 Precision::IsPositiveInfinite(l)){
1038 else if (Precision::IsNegativeInfinite(f)) {
1046 gp_Pnt2d pt2d(C2d->Value(prm));
1047 // BRepClass_FaceClassifier classif(F,pt2d,Precision::PConfusion());
1048 // return (classif.State() != TopAbs_OUT);
1049 BRepTopAdaptor_FClass2d classif(F,Precision::PConfusion());
1050 Standard_Boolean stat = classif.Perform(pt2d);
1051 // return (classif.Perform(pt2d) != TopAbs_OUT);
1052 if(stat == TopAbs_OUT) return Standard_False;
1054 if(stat == TopAbs_ON) {
1055 Standard_Integer nbPnt =10;
1056 Standard_Integer nbOut =0,nbIn =0,nbOn=0;
1057 Standard_Integer j =1;
1058 for( ; j<= nbPnt ; j++)
1060 //check neighbouring point
1061 //prm = .66 * prm + .34 * l;
1062 prm = f + (l-f)/nbPnt*(j-1);
1063 pt2d = C2d->Value(prm);
1064 stat = classif.Perform(pt2d);
1065 if(stat == TopAbs_OUT )
1067 else if(stat == TopAbs_IN)
1072 if(nbOut > nbIn + nbOn)
1073 return Standard_False;
1076 return Standard_True;
1080 //=======================================================================
1081 //function : ChoixUV
1083 //=======================================================================
1085 static void ChoixUV(const TopoDS_Edge& Last,
1086 const TopoDS_Face& F,
1087 const TopTools_MapOfShape& Poss,
1088 TopTools_MapIteratorOfMapOfShape& It,
1091 const Standard_Real toll)
1095 // gp_Pnt2d p2d,psav;
1098 gp_Pnt aPCur, aPlst;
1100 BRepAdaptor_Surface surf(F,Standard_False); // no restriction
1101 // Standard_Real tol = Precision::PConfusion() //BRep_Tool::Tolerance(Last));
1102 surf.D0 (plst.X(), plst.Y(), aPlst);
1108 gp_Dir2d ref2d(dlst);
1110 Handle(Geom2d_Curve) C2d;
1112 Standard_Integer index = 0, imin=0;
1113 Standard_Real angmax = -M_PI, dist, ang;
1116 for (It.Initialize(Poss); It.More(); It.Next()) {
1118 C2d = BRep_Tool::CurveOnSurface(TopoDS::Edge(It.Key()),F,f,l);
1119 if (It.Key().Orientation() == TopAbs_FORWARD) {
1120 // p2d = C2d->Value(f);
1122 vtx = TopExp::FirstVertex(TopoDS::Edge(It.Key()));
1125 // p2d = C2d->Value(l);
1128 vtx = TopExp::LastVertex(TopoDS::Edge(It.Key()));
1131 surf.D0 (p2d.X(), p2d.Y(), aPCur);
1133 tol = BRep_Tool::Tolerance(vtx);
1134 tol = Max(toll, tol); tol *= tol;
1136 dist = aPCur.SquareDistance(aPlst);
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);