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_DataMapOfShapeInteger.hxx>
31 #include <TopTools_DataMapOfShapeShape.hxx>
32 #include <TopTools_DataMapIteratorOfDataMapOfShapeShape.hxx>
33 #include <TopTools_MapIteratorOfMapOfShape.hxx>
34 #include <TopoDS_Iterator.hxx>
35 #include <TopExp_Explorer.hxx>
36 #include <BRep_Builder.hxx>
37 #include <TopoDS_Vertex.hxx>
38 #include <BRepLib_MakeFace.hxx>
39 #include <BRepLib_MakeWire.hxx>
40 #include <BRep_Tool.hxx>
41 #include <BRepTools.hxx>
42 #include <BRepTools_WireExplorer.hxx>
43 #include <BRep_Builder.hxx>
45 #include <BRepClass_FaceExplorer.hxx>
46 #include <BRepTopAdaptor_FClass2d.hxx>
47 #include <BRepAdaptor_Surface.hxx>
49 #include <Geom2d_Curve.hxx>
50 #include <gp_Pnt2d.hxx>
51 #include <gp_Vec2d.hxx>
52 #include <gp_Dir2d.hxx>
55 #include <Precision.hxx>
56 #include <BRepTools.hxx>
58 #include <Standard_ErrorHandler.hxx>
60 static Standard_Boolean IsInside(const TopoDS_Face&,
64 static Standard_Boolean IsInside(const TopoDS_Face&,
67 static void ChoixUV(const TopoDS_Edge&,
69 const TopTools_MapOfShape&,
70 TopTools_MapIteratorOfMapOfShape&,
73 const Standard_Real tol);
75 static TopoDS_Shape ChooseDirection(const TopoDS_Shape&,
78 const TopTools_ListOfShape&);
80 inline Standard_Boolean SameUV(const gp_Pnt2d& P1, const gp_Pnt2d& P2,
81 const BRepAdaptor_Surface& theBAS)//const Standard_Real tol)
83 // Standard_Real tol = Precision::Confusion();
84 // return P1.SquareDistance(P2) < 10*tol;
86 Standard_Boolean isSame = Standard_True;
87 if(theBAS.IsUPeriodic())
88 isSame = (fabs(P1.X() - P2.X()) < theBAS.UPeriod() *0.5);
89 if(theBAS.IsVPeriodic())
90 isSame = (isSame && (fabs(P1.Y() - P2.Y()) < theBAS.VPeriod() *0.5));
92 //return P1.SquareDistance(P2) < tol * tol; //IFV
97 //=======================================================================
100 //=======================================================================
102 void LocOpe_SplitShape::Init(const TopoDS_Shape& S)
104 myDone = Standard_False;
112 //=======================================================================
113 //function : CanSplit
115 //=======================================================================
117 Standard_Boolean LocOpe_SplitShape::CanSplit(const TopoDS_Edge& E) const
120 return Standard_False;
122 if (myMap.IsEmpty()) {
123 return Standard_False;
126 if (!myMap.IsBound(E)) {
127 return Standard_False;
130 // On verifie que l`edge n`appartient pas a un wire deja reconstruit
132 TopTools_DataMapIteratorOfDataMapOfShapeListOfShape itm(myMap);
133 for (; itm.More(); itm.Next()) {
134 if (itm.Key().ShapeType() == TopAbs_WIRE && !itm.Value().IsEmpty()) {
135 for (exp.Init(itm.Key(),TopAbs_EDGE); exp.More(); exp.Next()) {
136 if (exp.Current().IsSame(E)) {
137 return Standard_False;
142 return Standard_True;
146 //=======================================================================
149 //=======================================================================
151 void LocOpe_SplitShape::Add(const TopoDS_Vertex& V,
152 const Standard_Real P,
153 const TopoDS_Edge& E)
156 Standard_ConstructionError::Raise();
160 TopTools_ListOfShape& le = myMap(E);
164 TopTools_ListIteratorOfListOfShape itl(le);
167 for (; itl.More(); itl.Next()) {
168 const TopoDS_Edge& edg = TopoDS::Edge(itl.Value());
169 BRep_Tool::Range(edg,f,l);
175 Standard_ConstructionError::Raise();
177 TopoDS_Edge edg = TopoDS::Edge(itl.Value());
179 if (V.Orientation() == TopAbs_FORWARD ||
180 V.Orientation() == TopAbs_REVERSED) {
182 TopoDS_Shape aLocalShape = edg.EmptyCopied();
183 TopoDS_Edge E1 = TopoDS::Edge(aLocalShape);
184 aLocalShape = edg.EmptyCopied();
185 TopoDS_Edge E2 = TopoDS::Edge(aLocalShape);
186 // TopoDS_Edge E1 = TopoDS::Edge(edg.EmptyCopied());
187 // TopoDS_Edge E2 = TopoDS::Edge(edg.EmptyCopied());
188 E1.Orientation(TopAbs_FORWARD);
189 E2.Orientation(TopAbs_FORWARD);
190 TopoDS_Vertex newVtx = V;
191 newVtx.Orientation(TopAbs_REVERSED);
193 B.UpdateVertex(newVtx,P,E1,BRep_Tool::Tolerance(V));
194 newVtx.Orientation(TopAbs_FORWARD);
196 B.UpdateVertex(newVtx,P,E2,BRep_Tool::Tolerance(V));
197 edg.Orientation(TopAbs_FORWARD);
199 for (exp.Init(edg,TopAbs_VERTEX); exp.More(); exp.Next()) {
200 // for (TopExp_Explorer exp(edg,TopAbs_VERTEX); exp.More(); exp.Next()) {
201 const TopoDS_Vertex& vtx = TopoDS::Vertex(exp.Current());
202 f = BRep_Tool::Parameter(vtx,edg);
205 B.UpdateVertex(vtx,f,E1,BRep_Tool::Tolerance(vtx));
209 B.UpdateVertex(vtx,f,E2,BRep_Tool::Tolerance(vtx));
216 TopoDS_Shape aLocalShape = edg.EmptyCopied();
217 TopoDS_Edge E1 = TopoDS::Edge(aLocalShape);
218 // TopoDS_Edge E1 = TopoDS::Edge(edg.EmptyCopied());
220 for (exp.Init(edg,TopAbs_VERTEX); exp.More(); exp.Next()) {
221 // for (TopExp_Explorer exp(edg,TopAbs_VERTEX); exp.More(); exp.Next()) {
222 const TopoDS_Vertex& vtx = TopoDS::Vertex(exp.Current());
223 f = BRep_Tool::Parameter(vtx,edg);
225 B.UpdateVertex(vtx,f,E1,BRep_Tool::Tolerance(vtx));
228 B.UpdateVertex(V,P,E1,BRep_Tool::Tolerance(V));
233 //=======================================================================
235 //purpose : adds the list of wires on the face <F>
236 //=======================================================================
238 void LocOpe_SplitShape::Add(const TopTools_ListOfShape& Lwires,
239 const TopoDS_Face& F)
243 Standard_ConstructionError::Raise();
246 TopTools_ListOfShape& lf = myMap(F);
251 // On cherche la face descendante de F qui continent le wire
253 TopTools_ListIteratorOfListOfShape itl(lf);
254 TopoDS_Vertex Vfirst,Vlast;
256 BRepTools::Update(F);
258 for (; itl.More(); itl.Next())
260 const TopoDS_Face& fac = TopoDS::Face(itl.Value());
261 Standard_Boolean AllWiresInside = Standard_True;
262 TopTools_ListIteratorOfListOfShape itwires(Lwires);
263 for (; itwires.More(); itwires.Next())
265 const TopoDS_Wire& aWire = TopoDS::Wire(itwires.Value());
266 if (!IsInside(fac, aWire))
268 AllWiresInside = Standard_False;
276 Standard_ConstructionError::Raise();
279 TopoDS_Face FaceRef = TopoDS::Face(itl.Value());
280 FaceRef.Orientation(TopAbs_FORWARD);
283 TopTools_ListOfShape NewWires;
285 TopTools_DataMapOfShapeInteger SectionsTimes;
286 for (itl.Initialize(Lwires); itl.More(); itl.Next())
287 SectionsTimes.Bind(itl.Value(), 2);
289 TopTools_ListOfShape BreakVertices;
290 TopTools_ListOfShape BreakOnWires;
292 TopTools_DataMapOfShapeShape VerWireMap;
294 TopExp_Explorer ExploF, ExploW;
295 for (itl.Initialize(Lwires); itl.More(); itl.Next())
297 const TopoDS_Wire& aSection = TopoDS::Wire(itl.Value());
298 TopoDS_Vertex Ver [2];
299 TopExp::Vertices(aSection, Ver[0], Ver[1]);
300 for (i = 0; i < 2; i++)
302 if (VerWireMap.IsBound(Ver[i]))
304 for (ExploF.Init(FaceRef, TopAbs_WIRE); ExploF.More(); ExploF.Next())
306 const TopoDS_Shape& aWire = ExploF.Current();
308 for (ExploW.Init(aWire, TopAbs_VERTEX); ExploW.More(); ExploW.Next())
310 aVer = ExploW.Current();
311 if (aVer.IsSame(Ver[i]))
314 if (aVer.IsSame(Ver[i]))
316 VerWireMap.Bind(aVer, aWire);
323 TopTools_DataMapOfShapeListOfShape VerSecMap;
324 for (itl.Initialize(Lwires); itl.More(); itl.Next())
326 const TopoDS_Wire& aWire = TopoDS::Wire(itl.Value());
327 TopoDS_Vertex V1, V2;
328 TopExp::Vertices(aWire, V1, V2);
329 TopTools_ListOfShape LW1, LW2;
330 if (!VerSecMap.IsBound(V1))
331 VerSecMap.Bind(V1, LW1);
332 VerSecMap(V1).Append(aWire);
333 if (!VerSecMap.IsBound(V2))
334 VerSecMap.Bind(V2, LW2);
335 VerSecMap(V2).Append(aWire);
338 //TopTools_IndexedDataMapOfShapeShape InnerTouchingWiresOnVertex;
340 TopoDS_Wire outerW = BRepTools::OuterWire(FaceRef);
341 TopoDS_Wire CurWire = outerW;
342 BRepLib_MakeWire *MW;
343 MW = new BRepLib_MakeWire();
344 BRepTools_WireExplorer wexp(CurWire, FaceRef);
347 TopoDS_Vertex theStartVertex = wexp.CurrentVertex(), CurVertex;
348 TopoDS_Edge CurEdge = wexp.Current();
349 TopoDS_Edge LastEdge = CurEdge;
351 TopoDS_Wire aSectionWire;
352 TopoDS_Vertex aBreakVertex;
355 wexp.Init(CurWire, FaceRef);
358 if (MW->Wire().Closed())
360 CurVertex = wexp.CurrentVertex();
361 if (VerSecMap.IsBound(CurVertex))
363 TopoDS_Shape aLocalWire = ChooseDirection(LastEdge, CurVertex, FaceRef, VerSecMap(CurVertex));
364 aSectionWire = TopoDS::Wire(aLocalWire);
367 CurEdge = wexp.Current();
372 wexp.Init(CurWire, FaceRef);
374 if (MW->Wire().Closed())
376 NewWires.Append(MW->Wire());
377 theStartVertex = TopoDS::Vertex(BreakVertices.First());
378 BreakVertices.RemoveFirst();
379 CurWire = TopoDS::Wire(BreakOnWires.First());
380 BreakOnWires.RemoveFirst();
381 wexp.Init(CurWire, FaceRef);
382 while (!wexp.CurrentVertex().IsSame(theStartVertex))
384 MW = new BRepLib_MakeWire();
387 aBreakVertex = CurVertex;
388 BreakVertices.Append(aBreakVertex);
389 BreakOnWires.Append(CurWire);
392 MW->Add(aSectionWire);
393 (SectionsTimes(aSectionWire))--;
394 if (SectionsTimes(aSectionWire) == 0)
395 SectionsTimes.UnBind(aSectionWire);
396 if (MW->Wire().Closed())
398 NewWires.Append(MW->Wire());
399 if (SectionsTimes.IsEmpty())
401 theStartVertex = TopoDS::Vertex(BreakVertices.First());
402 BreakVertices.RemoveFirst();
403 CurWire = TopoDS::Wire(BreakOnWires.First());
404 BreakOnWires.RemoveFirst();
405 wexp.Init(CurWire, FaceRef);
406 while (!wexp.CurrentVertex().IsSame(theStartVertex))
408 MW = new BRepLib_MakeWire();
413 TopoDS_Vertex V1, V2, aStartVertex;
414 TopExp::Vertices(aSectionWire, V1, V2);
415 aStartVertex = (V1.IsSame(aBreakVertex))? V2 : V1;
416 CurWire = TopoDS::Wire(VerWireMap(aStartVertex));
418 wexp.Init(CurWire, FaceRef);
419 while (!wexp.CurrentVertex().IsSame(aStartVertex))
422 const TopTools_ListOfShape& Lsections = VerSecMap(aStartVertex);
423 if (Lsections.Extent() == 1)
426 //else: choose the way
427 TopoDS_Wire NextSectionWire =
428 TopoDS::Wire((aSectionWire.IsSame(Lsections.First()))? Lsections.Last() : Lsections.First());
430 Standard_Integer Times = 0;
431 TopTools_DataMapIteratorOfDataMapOfShapeShape itVW(VerWireMap);
432 for (; itVW.More(); itVW.Next())
433 if (itVW.Value().IsSame(CurWire))
435 if (Times == 1) //it is inner touching wire
437 //InnerTouchingWiresOnVertex.Bind(aWire, aStartVertex);
441 //we have to choose the direction
442 TopoDS_Edge aStartEdge = wexp.Current();
443 TopTools_ListOfShape Ldirs;
444 Ldirs.Append(aStartEdge);
445 Ldirs.Append(NextSectionWire);
446 TopoDS_Shape theDirection = ChooseDirection(aSectionWire, aStartVertex, FaceRef, Ldirs);
447 if (theDirection.IsSame(aStartEdge))
450 aSectionWire = NextSectionWire;
451 aBreakVertex = aStartVertex;
452 } //end of else (MW is not closed)
453 } //end of for (;;) (loop on section wires)
454 if (SectionsTimes.IsEmpty())
456 } //end of global for (;;)
458 TopTools_ListOfShape NewFaces;
460 for (itl.Initialize(NewWires); itl.More(); itl.Next())
462 TopoDS_Shape aLocalFace = FaceRef.EmptyCopied();
463 TopoDS_Face aNewFace = TopoDS::Face(aLocalFace);
464 aNewFace.Orientation(TopAbs_FORWARD);
465 BB.Add(aNewFace, itl.Value());
466 NewFaces.Append(aNewFace);
470 TopTools_ListOfShape Holes;
471 for (ExploF.Init(FaceRef, TopAbs_WIRE); ExploF.More(); ExploF.Next())
473 const TopoDS_Shape& aWire = ExploF.Current();
474 ExploW.Init(aWire, TopAbs_EDGE);
475 TopoDS_Shape anEdge = ExploW.Current();
476 Standard_Boolean found = Standard_False;
477 for (itl.Initialize(NewWires); itl.More(); itl.Next())
479 const TopoDS_Shape& aNewWire = itl.Value();
480 for (ExploW.Init(aNewWire, TopAbs_EDGE); ExploW.More(); ExploW.Next())
482 if (anEdge.IsSame(ExploW.Current()))
484 found = Standard_True;
494 TopTools_ListIteratorOfListOfShape itlNewF;
495 for (itl.Initialize(Holes); itl.More(); itl.Next())
497 const TopoDS_Wire& aHole = TopoDS::Wire(itl.Value());
498 for (itlNewF.Initialize(NewFaces); itlNewF.More(); itlNewF.Next())
500 TopoDS_Face& aNewFace = TopoDS::Face(itlNewF.Value());
501 if (IsInside(aNewFace, aHole))
503 BB.Add(aNewFace, aHole);
512 //Update of descendants of wires
513 for (ExploF.Init(F, TopAbs_WIRE); ExploF.More(); ExploF.Next())
515 TopTools_ListOfShape& ls = myMap(ExploF.Current());
520 // JAG 10.11.95 Codage des regularites
521 for (itl.Initialize(Lwires); itl.More(); itl.Next())
522 for (ExploW.Init(itl.Value(), TopAbs_EDGE); ExploW.More(); ExploW.Next())
524 const TopoDS_Edge& edg = TopoDS::Edge(ExploW.Current());
525 if (!BRep_Tool::HasContinuity(edg,F,F)) {
526 BB.Continuity(edg,F,F,GeomAbs_CN);
532 //=======================================================================
535 //=======================================================================
537 void LocOpe_SplitShape::Add(const TopoDS_Wire& W,
538 const TopoDS_Face& F)
542 Standard_ConstructionError::Raise();
547 TopTools_ListOfShape& lf = myMap(F);
553 if (!LocOpe::Closed(W,F)) {
559 } catch (Standard_Failure ) {
561 cout << "Warning: SpliShape internal problem detected, some faces may be lost. Check input edges/wires" <<endl;
565 // JAG 10.11.95 Codage des regularites
567 for (exp.Init(W,TopAbs_EDGE); exp.More(); exp.Next()) {
568 const TopoDS_Edge& edg = TopoDS::Edge(exp.Current());
569 if (!BRep_Tool::HasContinuity(edg,F,F)) {
570 B.Continuity(edg,F,F,GeomAbs_CN);
577 //=======================================================================
578 //function : AddClosedWire
580 //=======================================================================
582 void LocOpe_SplitShape::AddClosedWire(const TopoDS_Wire& W,
583 const TopoDS_Face& F)
587 // On cherche la face descendante de F qui continent le wire
588 TopTools_ListOfShape& lf = myMap(F);
589 TopTools_ListIteratorOfListOfShape itl(lf);
591 for (; itl.More(); itl.Next()) {
592 const TopoDS_Face& fac = TopoDS::Face(itl.Value());
594 outerW = BRepTools::OuterWire(fac);
595 if (IsInside(F,W,outerW)) {
599 if (IsInside(fac,W)) {
605 Standard_ConstructionError::Raise();
610 TopAbs_Orientation orWire = W.Orientation();
611 TopoDS_Shape aLocalFace = F.EmptyCopied();
612 TopoDS_Face newFace = TopoDS::Face(aLocalFace);
613 // TopoDS_Face newFace = TopoDS::Face(F.EmptyCopied());
614 newFace.Orientation(TopAbs_FORWARD);
617 // BRepGProp::SurfaceProperties (newFace,GP);
618 // if (GP.Mass() < 0) {
619 BRepTopAdaptor_FClass2d classif(newFace,Precision::PConfusion());
620 if (classif.PerformInfinitePoint() == TopAbs_IN) {
621 //le wire donne defini un trou
622 aLocalFace = F.EmptyCopied();
623 newFace = TopoDS::Face(aLocalFace);
624 // newFace = TopoDS::Face(F.EmptyCopied());
625 newFace.Orientation(TopAbs_FORWARD);
626 orWire = TopAbs::Reverse(orWire);
627 B.Add(newFace,W.Oriented(orWire));
630 TopoDS_Face FaceRef = TopoDS::Face(itl.Value());
631 FaceRef.Orientation(TopAbs_FORWARD);
634 aLocalFace = FaceRef.EmptyCopied();
635 TopoDS_Face newRef = TopoDS::Face(aLocalFace);
636 // TopoDS_Face newRef = TopoDS::Face(FaceRef.EmptyCopied());
637 newRef.Orientation(TopAbs_FORWARD);
639 // On suppose que les edges du wire ont des courbes 2d.
640 // Comme on ne change pas de surface de base, pas besoin d`UpdateEdge.
642 for (exp.Init(FaceRef.Oriented(TopAbs_FORWARD),TopAbs_WIRE);
643 exp.More(); exp.Next()) {
644 const TopoDS_Wire& wir = TopoDS::Wire(exp.Current());
645 if (IsInside(F,wir,W)) {
652 B.Add(newRef,W.Oriented(TopAbs::Reverse(orWire)));
659 //=======================================================================
660 //function : AddOpenWire
662 //=======================================================================
664 void LocOpe_SplitShape::AddOpenWire(const TopoDS_Wire& W,
665 const TopoDS_Face& F)
667 // On cherche la face descendante de F qui continent le wire
668 TopTools_ListOfShape& lf = myMap(F);
669 TopTools_ListIteratorOfListOfShape itl(lf);
670 TopoDS_Vertex Vfirst,Vlast;
672 BRepTools::Update(F);
674 // TopExp::Vertices(W,Vfirst,Vlast);
676 Standard_Real tolf, toll, tol1;
678 TopoDS_Shape aLocalShape = W.Oriented(TopAbs_FORWARD);
679 TopExp::Vertices(TopoDS::Wire(aLocalShape),Vfirst,Vlast);
680 // TopExp::Vertices(TopoDS::Wire(W.Oriented(TopAbs_FORWARD)),Vfirst,Vlast);
682 tolf = BRep_Tool::Tolerance(Vfirst);
683 toll = BRep_Tool::Tolerance(Vlast);
684 tol1 = Max(tolf, toll);
687 TopExp_Explorer exp,exp2;
689 TopoDS_Wire wfirst,wlast;
690 for (; itl.More(); itl.Next()) {
691 const TopoDS_Face& fac = TopoDS::Face(itl.Value());
692 if (!IsInside(fac,W)) {
696 Standard_Boolean ffound = Standard_False;
697 Standard_Boolean lfound = Standard_False;
698 for (exp.Init(fac,TopAbs_WIRE); exp.More(); exp.Next()) {
699 const TopoDS_Wire& wir = TopoDS::Wire(exp.Current());
700 for (exp2.Init(wir,TopAbs_VERTEX); exp2.More(); exp2.Next()) {
701 if (!ffound && exp2.Current().IsSame(Vfirst)) {
702 ffound = Standard_True;
705 else if (!lfound && exp2.Current().IsSame(Vlast)) {
706 lfound = Standard_True;
709 if (ffound && lfound) {
722 Standard_ConstructionError::Raise();
725 TopoDS_Face FaceRef = TopoDS::Face(itl.Value());
726 FaceRef.Orientation(TopAbs_FORWARD);
730 BRepAdaptor_Surface BAS(FaceRef, Standard_False);
732 Standard_Boolean IsPeriodic = BAS.IsUPeriodic() || BAS.IsVPeriodic();
734 tol1 = Max(BAS.UResolution(tol1), BAS.VResolution(tol1));
736 if (wfirst.IsSame(wlast)) {
737 // on cree 2 faces en remplacement de itl.Value()
740 for (exp.Init(wfirst,TopAbs_EDGE); exp.More(); exp.Next()) {
741 if (BRep_Tool::IsClosed(TopoDS::Edge(exp.Current()),FaceRef)) {
742 myDblE.Add(exp.Current());
746 TopAbs_Orientation orient;
747 TopoDS_Wire newW1,newW2;
749 newW1.Orientation(TopAbs_FORWARD);
751 newW2.Orientation(TopAbs_FORWARD);
753 Standard_Integer nbE = 0;
754 for (exp.Init(W.Oriented(TopAbs_FORWARD),TopAbs_EDGE);
755 exp.More(); exp.Next()) {
757 const TopoDS_Edge& edg = TopoDS::Edge(exp.Current());
758 orient = edg.Orientation();
760 B.Add(newW2,edg.Oriented(TopAbs::Reverse(orient)));
763 TopTools_MapOfShape MapE, PossE;
764 TopTools_MapIteratorOfMapOfShape itm;
765 TopoDS_Vertex vdeb,vfin;
766 Standard_Integer nbPoss;
768 // On recherche l`edge contenant Vlast
769 TopoDS_Edge LastEdge;
770 gp_Pnt2d pfirst,plast;
772 Handle(Geom2d_Curve) C2d;
775 for (exp.Init(W.Oriented(TopAbs_FORWARD),TopAbs_EDGE);
776 exp.More(); exp.Next()) {
777 const TopoDS_Edge& edg = TopoDS::Edge(exp.Current());
778 for (exp2.Init(edg,TopAbs_VERTEX); exp2.More(); exp2.Next()) {
779 if (exp2.Current().IsSame(Vfirst)) {
785 LastEdge.Orientation(edg.Orientation());
790 TopoDS_Shape aLocalFace = FaceRef.Oriented(wfirst.Orientation());
791 C2d = BRep_Tool::CurveOnSurface(LastEdge, TopoDS::Face(aLocalFace), f, l);
792 // C2d = BRep_Tool::CurveOnSurface
794 // TopoDS::Face(FaceRef.Oriented(wfirst.Orientation())),
796 if (LastEdge.Orientation() == TopAbs_FORWARD) {
797 pfirst = C2d->Value(f);
800 pfirst = C2d->Value(l);
803 for (exp.Init(W.Oriented(TopAbs_FORWARD),TopAbs_EDGE);
804 exp.More(); exp.Next()) {
805 const TopoDS_Edge& edg = TopoDS::Edge(exp.Current());
806 if( nbE>1 && edg.IsSame(LastEdge) )
808 for (exp2.Init(edg,TopAbs_VERTEX); exp2.More(); exp2.Next()) {
809 if (exp2.Current().IsSame(Vlast)) {
815 LastEdge.Orientation(edg.Orientation());
819 aLocalFace = FaceRef.Oriented(wfirst.Orientation());
820 C2d = BRep_Tool::CurveOnSurface(LastEdge, TopoDS::Face(aLocalFace), f, l);
821 // C2d = BRep_Tool::CurveOnSurface
823 // TopoDS::Face(FaceRef.Oriented(wfirst.Orientation())),
825 if (LastEdge.Orientation() == TopAbs_FORWARD) {
826 C2d->D1(l,plast,dlast);
827 // plast = C2d->Value(l);
830 // plast = C2d->Value(f);
831 C2d->D1(f,plast,dlast);
835 Standard_Boolean cond;
839 cond = !(Vfirst.IsSame(Vlast) && SameUV(pfirst,plast,BAS));
842 cond = !(Vfirst.IsSame(Vlast));
848 // On enchaine par la fin
849 for (exp.Init(wfirst.Oriented(TopAbs_FORWARD),TopAbs_EDGE);
850 exp.More(); exp.Next()) {
851 const TopoDS_Edge& edg = TopoDS::Edge(exp.Current());
852 if (MapE.Contains(edg) && !myDblE.Contains(edg)) {
856 orient = edg.Orientation();
857 TopExp::Vertices(edg,vdeb,vfin);
858 if (orient == TopAbs_FORWARD && Vlast.IsSame(vdeb)) {
859 PossE.Add(edg.Oriented(orient));
861 else if (orient == TopAbs_REVERSED && Vlast.IsSame(vfin)) {
862 PossE.Add(edg.Oriented(orient));
865 nbPoss = PossE.Extent();
867 itm.Initialize(PossE);
868 TopoDS_Shape aLocalFace = FaceRef.Oriented(wfirst.Orientation());
869 C2d = BRep_Tool::CurveOnSurface(TopoDS::Edge(itm.Key()),
870 TopoDS::Face(aLocalFace), f, l);
871 // C2d = BRep_Tool::CurveOnSurface
872 // (TopoDS::Edge(itm.Key()),
873 // TopoDS::Face(FaceRef.Oriented(wfirst.Orientation())),
875 if (itm.Key().Orientation() == TopAbs_FORWARD) {
876 // plast = C2d->Value(l);
877 C2d->D1(l,plast,dlast);
880 // plast = C2d->Value(f);
881 C2d->D1(f,plast,dlast);
885 else if (nbPoss > 1) {
886 // Faire choix en U,V...
887 TopoDS_Shape aLocalFace = FaceRef.Oriented(wfirst.Orientation());
889 ChoixUV(LastEdge, TopoDS::Face(aLocalFace), PossE,
890 itm, plast, dlast, toll);
892 // TopoDS::Face(FaceRef.Oriented(wfirst.Orientation())),
901 B.Add(newW1,itm.Key());
902 if (MapE.Contains(itm.Key())) {
903 myDblE.Remove(itm.Key());
908 LastEdge = TopoDS::Edge(itm.Key());
909 if (LastEdge.Orientation() == TopAbs_FORWARD) {
910 Vlast = TopExp::LastVertex(LastEdge);
913 Vlast = TopExp::FirstVertex(LastEdge);
916 toll = BRep_Tool::Tolerance(Vlast);
917 tol1 = Max(tolf, toll);
920 //MODIFICATION PIERRE SMEYERS : si pas de possibilite, on sort avec erreur
922 cout<<"erreur Spliter : pas de chainage du wire"<<endl;
923 Standard_ConstructionError::Raise();
927 tol1 = Max(BAS.UResolution(tol1), BAS.VResolution(tol1));
930 cond = !(Vfirst.IsSame(Vlast) && SameUV(pfirst,plast,BAS));
933 cond = !(Vfirst.IsSame(Vlast));
938 for (exp.Init(wfirst.Oriented(TopAbs_FORWARD),TopAbs_EDGE);
939 exp.More(); exp.Next()) {
940 const TopoDS_Edge& edg = TopoDS::Edge(exp.Current());
941 if (!MapE.Contains(edg)) {
945 else if (myDblE.Contains(edg)) {
946 for (itm.Initialize(MapE); itm.More(); itm.Next()) {
947 const TopoDS_Edge& edg2 = TopoDS::Edge(itm.Key());
948 if (edg.IsSame(edg2) && edg.Orientation() != edg2.Orientation()) {
956 TopoDS_Face newF1,newF2;
957 aLocalFace = FaceRef.EmptyCopied();
958 newF1 = TopoDS::Face(aLocalFace);
959 newF1.Orientation(TopAbs_FORWARD);
960 aLocalFace = FaceRef.EmptyCopied();
961 newF2 = TopoDS::Face(aLocalFace);
962 // newF2 = TopoDS::Face(FaceRef.EmptyCopied());
963 newF2.Orientation(TopAbs_FORWARD);
965 // modifs JAG 97.05.28
967 TopAbs_Orientation orfila;
969 TopAbs_Orientation orfila=TopAbs_FORWARD;
971 for (exp.Init(FaceRef.Oriented(TopAbs_FORWARD),TopAbs_WIRE);
972 exp.More(); exp.Next()) {
973 const TopoDS_Wire& wir = TopoDS::Wire(exp.Current());
974 if (wir.IsSame(wfirst)) {
975 orfila = exp.Current().Orientation();
980 B.Add(newF1,newW1.Oriented(orfila));
981 B.Add(newF2,newW2.Oriented(orfila));
982 // Standard_Boolean exch = Standard_False;
983 BRepTopAdaptor_FClass2d classif(newF1,Precision::PConfusion());
984 if (classif.PerformInfinitePoint() == TopAbs_OUT) {
985 BRepTopAdaptor_FClass2d classi(newF2,Precision::PConfusion());
986 if (classi.PerformInfinitePoint() == TopAbs_IN) {
987 TopoDS_Face tempF = newF2;
993 for (exp.ReInit(); exp.More(); exp.Next()) {
994 const TopoDS_Wire& wir = TopoDS::Wire(exp.Current());
995 if (!wir.IsSame(wfirst)) {
996 // if (IsInside(F,wir,newW1) || IsInside(F,newW1,wir)) {
997 if (IsInside(newF1, wir)) {
1000 else if (IsInside(newF2, wir)) {
1004 // Ce wire est ni dans newF2 ni dans newF1
1005 // Peut etre faut il construire une troisieme face
1006 cout << "WARNING: LocOpe_SPlitShape : Ce wire est ni dans newF2 ni dans newF1" << endl;
1013 // Mise a jour des descendants des wires
1014 for (exp.Init(F,TopAbs_WIRE); exp.More(); exp.Next()) {
1015 TopTools_ListOfShape& ls = myMap(exp.Current());
1017 for (; itl.More(); itl.Next()) {
1018 if (itl.Value().IsSame(wfirst)) {
1022 if (itl.More()) { // on a trouve le wire
1030 // on ne cree qu`une seule face
1031 TopoDS_Wire outerW = BRepTools::OuterWire(FaceRef);
1032 TopoDS_Wire newWire;
1033 TopoDS_Face newFace;
1034 B.MakeWire(newWire);
1035 newWire.Orientation(TopAbs_FORWARD);
1036 TopAbs_Orientation orient,orRelat;
1038 if (wfirst.Orientation() == wlast.Orientation()) {
1039 orRelat = TopAbs_FORWARD;
1042 orRelat = TopAbs_REVERSED;
1045 if (wlast.IsSame(outerW)) {
1051 for (exp.Init(wfirst.Oriented(TopAbs_FORWARD),TopAbs_EDGE);
1052 exp.More(); exp.Next()) {
1053 B.Add(newWire,TopoDS::Edge(exp.Current()));
1057 for (exp.Init(wlast.Oriented(TopAbs_FORWARD),TopAbs_EDGE);
1058 exp.More(); exp.Next()) {
1059 const TopoDS_Edge& edg = TopoDS::Edge(exp.Current());
1060 orient = TopAbs::Compose(edg.Orientation(),orRelat);
1061 B.Add(newWire,edg.Oriented(orient));
1065 // Edges du wire ajoute, et dans les 2 sens
1066 for (exp.Init(W.Oriented(TopAbs_FORWARD),TopAbs_EDGE);
1067 exp.More(); exp.Next()) {
1068 const TopoDS_Edge& edg = TopoDS::Edge(exp.Current());
1069 orient = edg.Orientation();
1070 B.Add(newWire,edg.Oriented(orient));
1071 B.Add(newWire,edg.Oriented(TopAbs::Reverse(orient)));
1072 myDblE.Add(edg.Oriented(orient));
1075 // on refait une face
1077 TopoDS_Shape aLocalFace = FaceRef.EmptyCopied();
1078 newFace = TopoDS::Face(aLocalFace);
1079 // newFace = TopoDS::Face(FaceRef.EmptyCopied());
1080 FaceRef.Orientation(TopAbs_FORWARD);
1081 for (exp.Init(FaceRef.Oriented(TopAbs_FORWARD),TopAbs_WIRE);
1082 exp.More(); exp.Next()) {
1083 const TopoDS_Wire& wir = TopoDS::Wire(exp.Current());
1084 if (wir.IsSame(wfirst)) {
1085 B.Add(newFace,newWire.Oriented(wir.Orientation()));
1087 else if (!wir.IsSame(wlast)) {
1093 // Mise a jour des descendants des wires
1094 for (exp.Init(F,TopAbs_WIRE); exp.More(); exp.Next()) {
1095 TopTools_ListOfShape& ls = myMap(exp.Current());
1097 Standard_Boolean touch = Standard_False;
1098 while (itl.More()) {
1099 if (itl.Value().IsSame(wfirst) || itl.Value().IsSame(wlast)) {
1101 touch = Standard_True;
1116 //=======================================================================
1119 //=======================================================================
1121 const TopTools_ListOfShape& LocOpe_SplitShape::LeftOf(const TopoDS_Wire& W,
1122 const TopoDS_Face& F)
1124 if (myShape.IsNull()) {
1125 Standard_NoSuchObject::Raise();
1128 TopExp_Explorer exp,expw,expf;
1129 exp.Init(myShape,TopAbs_FACE);
1130 for (; exp.More(); exp.Next()) {
1131 if (exp.Current().IsSame(F)) {
1136 Standard_NoSuchObject::Raise();
1140 const TopoDS_Face& theFace = TopoDS::Face(exp.Current());
1141 TopAbs_Orientation orFace = theFace.Orientation();
1142 TopTools_ListIteratorOfListOfShape itl,itl2;
1144 for (expw.Init(W,TopAbs_EDGE); expw.More(); expw.Next()) {
1145 const TopoDS_Edge& edg = TopoDS::Edge(expw.Current());
1146 for (itl.Initialize(myMap(theFace)); itl.More(); itl.Next()) {
1147 TopoDS_Face fac = TopoDS::Face(itl.Value());
1148 fac.Orientation(orFace);
1149 for (expf.Init(fac,TopAbs_EDGE); expf.More(); expf.Next()) {
1150 const TopoDS_Edge& edgbis = TopoDS::Edge(expf.Current());
1151 if (edgbis.IsSame(edg) &&
1152 edgbis.Orientation() == edg.Orientation()) {
1153 for (itl2.Initialize(myLeft); itl2.More(); itl2.Next()) {
1154 if (itl2.Value().IsSame(fac)) {
1158 if (!itl2.More()) { // la face n`est pas deja presente
1164 if (expf.More()) { // face found
1173 //=======================================================================
1174 //function : DescendantShapes
1176 //=======================================================================
1178 const TopTools_ListOfShape& LocOpe_SplitShape::DescendantShapes
1179 (const TopoDS_Shape& S)
1183 myDone = Standard_True;
1186 if (!myDblE.IsEmpty()) {
1187 cout << "Le shape comporte des faces invalides" << endl;
1195 //=======================================================================
1198 //=======================================================================
1200 void LocOpe_SplitShape::Put(const TopoDS_Shape& S)
1202 if (!myMap.IsBound(S)) {
1203 TopTools_ListOfShape thelist;
1204 myMap.Bind(S, thelist);
1205 if (S.ShapeType() != TopAbs_VERTEX) {
1206 for(TopoDS_Iterator theIterator(S);theIterator.More();
1207 theIterator.Next()) {
1208 Put(theIterator.Value());
1218 //=======================================================================
1219 //function : Rebuild
1221 //=======================================================================
1223 Standard_Boolean LocOpe_SplitShape::Rebuild(const TopoDS_Shape& S)
1227 TopTools_ListIteratorOfListOfShape itr(myMap(S));
1229 if (itr.Value().IsSame(S)) {
1230 return Standard_False;
1232 return Standard_True;
1234 Standard_Boolean rebuild = Standard_False;
1236 for(it.Initialize(S); it.More(); it.Next()) {
1237 rebuild = Rebuild(it.Value()) || rebuild;
1242 TopoDS_Shape result = S.EmptyCopied();
1243 TopAbs_Orientation orient;
1244 for(it.Initialize(S); it.More(); it.Next()) {
1245 orient = it.Value().Orientation();
1246 for (itr.Initialize(myMap(it.Value())); itr.More(); itr.Next()) {
1247 B.Add(result,itr.Value().Oriented(orient));
1250 myMap(S).Append(result);
1260 //=======================================================================
1261 //function : IsInside
1263 //=======================================================================
1265 static Standard_Boolean IsInside(const TopoDS_Face& F,
1266 const TopoDS_Wire& W1,
1267 const TopoDS_Wire& W2)
1269 // Attention, c`est tres boeuf !!!!
1271 TopoDS_Shape aLocalShape = F.EmptyCopied();
1272 TopoDS_Face newFace = TopoDS::Face(aLocalShape);
1273 // TopoDS_Face newFace = TopoDS::Face(F.EmptyCopied());
1275 //TopAbs_Orientation orWire = W2.Orientation();
1277 newFace.Orientation(TopAbs_FORWARD);
1280 // BRepGProp::SurfaceProperties(newFace,GP);
1281 // if (GP.Mass() < 0) {
1282 BRepTopAdaptor_FClass2d classif(newFace,Precision::PConfusion());
1283 Standard_Boolean Reversed = Standard_False;
1284 if (classif.PerformInfinitePoint() == TopAbs_IN) {
1285 //le wire donne defini un trou
1286 // newFace = TopoDS::Face(F.EmptyCopied());
1287 // newFace.Orientation(TopAbs_FORWARD);
1288 // orWire = TopAbs::Reverse(orWire);
1289 // B.Add(newFace,W2.Oriented(orWire));
1290 Reversed = Standard_True;
1293 // Standard_Real U,V;
1294 TopExp_Explorer exp(W1,TopAbs_EDGE);
1295 const TopoDS_Edge& edg = TopoDS::Edge(exp.Current());
1296 TopExp_Explorer exp2(edg,TopAbs_VERTEX);
1297 const TopoDS_Vertex& vtx = TopoDS::Vertex(exp2.Current());
1298 Standard_Real prm = BRep_Tool::Parameter(vtx,edg);
1300 Handle(Geom2d_Curve) C2d = BRep_Tool::CurveOnSurface(edg,F,f,l);
1303 cout << "Edge is not on surface" <<endl;
1305 return Standard_False;
1307 gp_Pnt2d pt2d(C2d->Value(prm));
1308 // BRepClass_FaceClassifier classif(newFace,pt2d,Precision::PConfusion());
1309 // return (classif.State() == TopAbs_IN);
1311 return (classif.Perform(pt2d) == TopAbs_IN);
1314 return (classif.Perform(pt2d) == TopAbs_OUT);
1319 //=======================================================================
1320 //function : IsInside
1322 //=======================================================================
1324 static Standard_Boolean IsInside(const TopoDS_Face& F,
1325 const TopoDS_Wire& W)
1327 // Attention, c`est tres boeuf !!!!
1328 TopExp_Explorer exp(W,TopAbs_EDGE);
1329 for( ; exp.More(); exp.Next()) {
1330 const TopoDS_Edge& edg = TopoDS::Edge(exp.Current());
1331 // TopExp_Explorer exp2(edg,TopAbs_VERTEX);
1332 // const TopoDS_Vertex& vtx = TopoDS::Vertex(exp2.Current());
1333 // Standard_Real prm = BRep_Tool::Parameter(vtx,edg);
1334 Standard_Real f,l,prm;
1335 Handle(Geom2d_Curve) C2d = BRep_Tool::CurveOnSurface(edg,F,f,l);
1336 if (!Precision::IsNegativeInfinite(f) &&
1337 !Precision::IsPositiveInfinite(l)) {
1341 if (Precision::IsNegativeInfinite(f) &&
1342 Precision::IsPositiveInfinite(l)){
1345 else if (Precision::IsNegativeInfinite(f)) {
1353 gp_Pnt2d pt2d(C2d->Value(prm));
1354 // BRepClass_FaceClassifier classif(F,pt2d,Precision::PConfusion());
1355 // return (classif.State() != TopAbs_OUT);
1356 BRepTopAdaptor_FClass2d classif(F,Precision::PConfusion());
1357 TopAbs_State stat = classif.Perform(pt2d);
1358 // return (classif.Perform(pt2d) != TopAbs_OUT);
1359 if(stat == TopAbs_OUT) return Standard_False;
1361 if(stat == TopAbs_ON) {
1362 Standard_Integer nbPnt =10;
1363 Standard_Integer nbOut =0,nbIn =0,nbOn=0;
1364 Standard_Integer j =1;
1365 for( ; j<= nbPnt ; j++)
1367 //check neighbouring point
1368 //prm = .66 * prm + .34 * l;
1369 prm = f + (l-f)/nbPnt*(j-1);
1370 pt2d = C2d->Value(prm);
1371 stat = classif.Perform(pt2d);
1372 if(stat == TopAbs_OUT )
1374 else if(stat == TopAbs_IN)
1379 if(nbOut > nbIn + nbOn)
1380 return Standard_False;
1383 return Standard_True;
1387 //=======================================================================
1388 //function : ChoixUV
1390 //=======================================================================
1392 static void ChoixUV(const TopoDS_Edge& Last,
1393 const TopoDS_Face& F,
1394 const TopTools_MapOfShape& Poss,
1395 TopTools_MapIteratorOfMapOfShape& It,
1398 const Standard_Real toll)
1402 // gp_Pnt2d p2d,psav;
1405 gp_Pnt aPCur, aPlst;
1407 BRepAdaptor_Surface surf(F,Standard_False); // no restriction
1408 // Standard_Real tol = Precision::PConfusion() //BRep_Tool::Tolerance(Last));
1409 surf.D0 (plst.X(), plst.Y(), aPlst);
1415 gp_Dir2d ref2d(dlst);
1417 Handle(Geom2d_Curve) C2d;
1419 Standard_Integer index = 0, imin=0;
1420 Standard_Real angmax = -M_PI, dist, ang;
1423 for (It.Initialize(Poss); It.More(); It.Next()) {
1425 C2d = BRep_Tool::CurveOnSurface(TopoDS::Edge(It.Key()),F,f,l);
1426 if (It.Key().Orientation() == TopAbs_FORWARD) {
1427 // p2d = C2d->Value(f);
1429 vtx = TopExp::FirstVertex(TopoDS::Edge(It.Key()));
1432 // p2d = C2d->Value(l);
1435 vtx = TopExp::LastVertex(TopoDS::Edge(It.Key()));
1438 surf.D0 (p2d.X(), p2d.Y(), aPCur);
1440 tol = BRep_Tool::Tolerance(vtx);
1441 tol = Max(toll, tol); tol *= tol;
1443 dist = aPCur.SquareDistance(aPlst);
1445 if (!Last.IsSame(It.Key())) {
1446 ang = ref2d.Angle(gp_Dir2d(v2d));
1452 //if ((dist < dmin - tol) ||
1453 //(dist <= dmin+tol && ang > angmax)) {
1454 if ((dist < tol) && (ang > angmax)) {
1461 for (index = 1, It.Initialize(Poss); It.More(); It.Next()) {
1462 if (index == imin) {
1463 C2d = BRep_Tool::CurveOnSurface(TopoDS::Edge(It.Key()),F,f,l);
1464 if (It.Key().Orientation() == TopAbs_FORWARD) {
1465 // plst = C2d->Value(l);
1466 C2d->D1(l,plst,dlst);
1469 // plst = C2d->Value(f);
1470 C2d->D1(f,plst,dlst);
1480 //=======================================================================
1481 //function : ChooseDirection
1483 //=======================================================================
1485 static TopoDS_Shape ChooseDirection(const TopoDS_Shape& RefDir,
1486 const TopoDS_Vertex& RefVertex,
1487 const TopoDS_Face& theFace,
1488 const TopTools_ListOfShape& Ldirs)
1490 TopExp_Explorer Explo(RefDir, TopAbs_EDGE);
1491 TopoDS_Edge RefEdge;
1492 TopoDS_Vertex V1, V2;
1493 TopAbs_Orientation anOr;
1494 for (; Explo.More(); Explo.Next())
1496 RefEdge = TopoDS::Edge(Explo.Current());
1497 TopExp::Vertices(RefEdge, V1, V2);
1498 if (V1.IsSame(RefVertex))
1500 anOr = TopAbs_REVERSED;
1503 else if (V2.IsSame(RefVertex))
1505 anOr = TopAbs_FORWARD;
1510 Standard_Real RefFirst, RefLast;
1511 Handle(Geom2d_Curve) RefCurve = BRep_Tool::CurveOnSurface(RefEdge, theFace, RefFirst, RefLast);
1515 //Standard_Real RefPar = (RefEdge.Orientation() == TopAbs_FORWARD)? RefLast : RefFirst;
1516 Standard_Real RefPar = (anOr == TopAbs_FORWARD)? RefLast : RefFirst;
1517 RefCurve->D1(RefPar, RefPnt, RefVec);
1518 if (anOr == TopAbs_FORWARD)
1521 Handle(Geom2d_Curve) aCurve;
1522 Standard_Real aFirst, aLast, aPar;
1524 Standard_Real MinAngle = RealLast(), anAngle;
1525 TopoDS_Shape TargetDir;
1526 TopTools_ListIteratorOfListOfShape itl(Ldirs);
1527 for (; itl.More(); itl.Next())
1529 const TopoDS_Shape& aShape = itl.Value();
1531 for (Explo.Init(aShape, TopAbs_EDGE); Explo.More(); Explo.Next())
1533 anEdge = TopoDS::Edge(Explo.Current());
1534 TopExp::Vertices(anEdge, V1, V2);
1535 if (V1.IsSame(RefVertex))
1537 anOr = TopAbs_FORWARD;
1540 else if (V2.IsSame(RefVertex))
1542 anOr = TopAbs_REVERSED;
1546 aCurve = BRep_Tool::CurveOnSurface(anEdge, theFace, aFirst, aLast);
1547 aPar = (anOr == TopAbs_FORWARD)? aFirst : aLast;
1548 aCurve->D1(aPar, RefPnt, aVec);
1549 if (anOr == TopAbs_REVERSED)
1551 anAngle = aVec.Angle(RefVec);
1555 if (anAngle < MinAngle)