1 // Created on: 1995-06-27
2 // Created by: Jacques GOUSSARD
3 // Copyright (c) 1995-1999 Matra Datavision
4 // Copyright (c) 1999-2014 OPEN CASCADE SAS
6 // This file is part of Open CASCADE Technology software library.
8 // This library is free software; you can redistribute it and/or modify it under
9 // the terms of the GNU Lesser General Public License version 2.1 as published
10 // by the Free Software Foundation, with special exception defined in the file
11 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
12 // distribution for complete text of the license and disclaimer of any warranty.
14 // Alternatively, this file may be used under the terms of Open CASCADE
15 // commercial license or contractual agreement.
18 #include <BRep_Builder.hxx>
19 #include <BRep_Tool.hxx>
20 #include <BRepAdaptor_Surface.hxx>
21 #include <BRepClass_FaceExplorer.hxx>
22 #include <BRepLib_MakeFace.hxx>
23 #include <BRepLib_MakeWire.hxx>
24 #include <BRepTools.hxx>
25 #include <BRepTools_WireExplorer.hxx>
26 #include <BRepTopAdaptor_FClass2d.hxx>
27 #include <Geom2d_Curve.hxx>
28 #include <gp_Dir2d.hxx>
29 #include <gp_Pnt2d.hxx>
30 #include <gp_Vec2d.hxx>
32 #include <LocOpe_SplitShape.hxx>
33 #include <Precision.hxx>
34 #include <Standard_ConstructionError.hxx>
35 #include <Standard_ErrorHandler.hxx>
36 #include <Standard_NoSuchObject.hxx>
37 #include <StdFail_NotDone.hxx>
39 #include <TopExp_Explorer.hxx>
41 #include <TopoDS_Edge.hxx>
42 #include <TopoDS_Face.hxx>
43 #include <TopoDS_Iterator.hxx>
44 #include <TopoDS_Shape.hxx>
45 #include <TopoDS_Vertex.hxx>
46 #include <TopoDS_Wire.hxx>
47 #include <TopTools_DataMapIteratorOfDataMapOfShapeListOfShape.hxx>
48 #include <TopTools_DataMapIteratorOfDataMapOfShapeShape.hxx>
49 #include <TopTools_DataMapOfShapeInteger.hxx>
50 #include <TopTools_DataMapOfShapeListOfShape.hxx>
51 #include <TopTools_DataMapOfShapeShape.hxx>
52 #include <TopTools_IndexedMapOfShape.hxx>
53 #include <TopTools_ListIteratorOfListOfShape.hxx>
54 #include <TopTools_ListOfShape.hxx>
55 #include <TopTools_MapIteratorOfMapOfOrientedShape.hxx>
56 #include <TopTools_MapIteratorOfMapOfShape.hxx>
57 #include <TopTools_MapOfOrientedShape.hxx>
58 #include <TopTools_MapOfShape.hxx>
60 static Standard_Boolean IsInside(const TopoDS_Face&,
64 static Standard_Boolean IsInside(const TopoDS_Face&,
67 static void GetDirection(const TopoDS_Edge&,
73 static void ChoixUV(const TopoDS_Edge&,
75 const TopTools_IndexedMapOfShape&,
79 const Standard_Real tol);
81 static TopoDS_Shape ChooseDirection(const TopoDS_Shape&,
84 const TopTools_ListOfShape&);
86 inline Standard_Boolean SameUV(const gp_Pnt2d& P1, const gp_Pnt2d& P2,
87 const BRepAdaptor_Surface& theBAS)//const Standard_Real tol)
89 // Standard_Real tol = Precision::Confusion();
90 // return P1.SquareDistance(P2) < 10*tol;
92 Standard_Boolean isSame = Standard_True;
93 if(theBAS.IsUPeriodic())
94 isSame = (fabs(P1.X() - P2.X()) < theBAS.UPeriod() *0.5);
95 if(theBAS.IsVPeriodic())
96 isSame = (isSame && (fabs(P1.Y() - P2.Y()) < theBAS.VPeriod() *0.5));
98 //return P1.SquareDistance(P2) < tol * tol; //IFV
103 //=======================================================================
106 //=======================================================================
108 void LocOpe_SplitShape::Init(const TopoDS_Shape& S)
110 myDone = Standard_False;
118 //=======================================================================
119 //function : CanSplit
121 //=======================================================================
123 Standard_Boolean LocOpe_SplitShape::CanSplit(const TopoDS_Edge& E) const
126 return Standard_False;
128 if (myMap.IsEmpty()) {
129 return Standard_False;
132 if (!myMap.IsBound(E)) {
133 return Standard_False;
136 // On verifie que l`edge n`appartient pas a un wire deja reconstruit
138 TopTools_DataMapIteratorOfDataMapOfShapeListOfShape itm(myMap);
139 for (; itm.More(); itm.Next()) {
140 if (itm.Key().ShapeType() == TopAbs_WIRE && !itm.Value().IsEmpty()) {
141 for (exp.Init(itm.Key(),TopAbs_EDGE); exp.More(); exp.Next()) {
142 if (exp.Current().IsSame(E)) {
143 return Standard_False;
148 return Standard_True;
152 //=======================================================================
155 //=======================================================================
157 void LocOpe_SplitShape::Add(const TopoDS_Vertex& V,
158 const Standard_Real P,
159 const TopoDS_Edge& E)
162 Standard_ConstructionError::Raise();
166 TopTools_ListOfShape& le = myMap(E);
170 TopTools_ListIteratorOfListOfShape itl(le);
173 for (; itl.More(); itl.Next()) {
174 const TopoDS_Edge& edg = TopoDS::Edge(itl.Value());
175 BRep_Tool::Range(edg,f,l);
181 Standard_ConstructionError::Raise();
183 TopoDS_Edge edg = TopoDS::Edge(itl.Value());
185 if (V.Orientation() == TopAbs_FORWARD ||
186 V.Orientation() == TopAbs_REVERSED) {
188 TopoDS_Shape aLocalShape = edg.EmptyCopied();
189 TopoDS_Edge E1 = TopoDS::Edge(aLocalShape);
190 aLocalShape = edg.EmptyCopied();
191 TopoDS_Edge E2 = TopoDS::Edge(aLocalShape);
192 // TopoDS_Edge E1 = TopoDS::Edge(edg.EmptyCopied());
193 // TopoDS_Edge E2 = TopoDS::Edge(edg.EmptyCopied());
194 E1.Orientation(TopAbs_FORWARD);
195 E2.Orientation(TopAbs_FORWARD);
196 TopoDS_Vertex newVtx = V;
197 newVtx.Orientation(TopAbs_REVERSED);
199 B.UpdateVertex(newVtx,P,E1,BRep_Tool::Tolerance(V));
200 newVtx.Orientation(TopAbs_FORWARD);
202 B.UpdateVertex(newVtx,P,E2,BRep_Tool::Tolerance(V));
203 edg.Orientation(TopAbs_FORWARD);
205 for (exp.Init(edg,TopAbs_VERTEX); exp.More(); exp.Next()) {
206 // for (TopExp_Explorer exp(edg,TopAbs_VERTEX); exp.More(); exp.Next()) {
207 const TopoDS_Vertex& vtx = TopoDS::Vertex(exp.Current());
208 f = BRep_Tool::Parameter(vtx,edg);
211 B.UpdateVertex(vtx,f,E1,BRep_Tool::Tolerance(vtx));
215 B.UpdateVertex(vtx,f,E2,BRep_Tool::Tolerance(vtx));
222 TopoDS_Shape aLocalShape = edg.EmptyCopied();
223 TopoDS_Edge E1 = TopoDS::Edge(aLocalShape);
224 // TopoDS_Edge E1 = TopoDS::Edge(edg.EmptyCopied());
226 for (exp.Init(edg,TopAbs_VERTEX); exp.More(); exp.Next()) {
227 // for (TopExp_Explorer exp(edg,TopAbs_VERTEX); exp.More(); exp.Next()) {
228 const TopoDS_Vertex& vtx = TopoDS::Vertex(exp.Current());
229 f = BRep_Tool::Parameter(vtx,edg);
231 B.UpdateVertex(vtx,f,E1,BRep_Tool::Tolerance(vtx));
234 B.UpdateVertex(V,P,E1,BRep_Tool::Tolerance(V));
239 //=======================================================================
241 //purpose : adds the list of wires on the face <F>
242 //=======================================================================
244 void LocOpe_SplitShape::Add(const TopTools_ListOfShape& Lwires,
245 const TopoDS_Face& F)
249 Standard_ConstructionError::Raise();
252 TopTools_ListOfShape& lf = myMap(F);
257 // On cherche la face descendante de F qui continent le wire
259 TopTools_ListIteratorOfListOfShape itl(lf);
260 TopoDS_Vertex Vfirst,Vlast;
262 BRepTools::Update(F);
264 for (; itl.More(); itl.Next())
266 const TopoDS_Face& fac = TopoDS::Face(itl.Value());
267 Standard_Boolean AllWiresInside = Standard_True;
268 TopTools_ListIteratorOfListOfShape itwires(Lwires);
269 for (; itwires.More(); itwires.Next())
271 const TopoDS_Wire& aWire = TopoDS::Wire(itwires.Value());
272 if (!IsInside(fac, aWire))
274 AllWiresInside = Standard_False;
282 Standard_ConstructionError::Raise();
285 TopoDS_Face FaceRef = TopoDS::Face(itl.Value());
286 FaceRef.Orientation(TopAbs_FORWARD);
289 TopTools_ListOfShape NewWires;
291 TopTools_DataMapOfShapeInteger SectionsTimes;
292 for (itl.Initialize(Lwires); itl.More(); itl.Next())
293 SectionsTimes.Bind(itl.Value(), 2);
295 TopTools_ListOfShape BreakVertices;
296 TopTools_ListOfShape BreakOnWires;
298 TopTools_DataMapOfShapeShape VerWireMap;
300 TopExp_Explorer ExploF, ExploW;
301 for (itl.Initialize(Lwires); itl.More(); itl.Next())
303 const TopoDS_Wire& aSection = TopoDS::Wire(itl.Value());
304 TopoDS_Vertex Ver [2];
305 TopExp::Vertices(aSection, Ver[0], Ver[1]);
306 for (i = 0; i < 2; i++)
308 if (VerWireMap.IsBound(Ver[i]))
310 for (ExploF.Init(FaceRef, TopAbs_WIRE); ExploF.More(); ExploF.Next())
312 const TopoDS_Shape& aWire = ExploF.Current();
314 for (ExploW.Init(aWire, TopAbs_VERTEX); ExploW.More(); ExploW.Next())
316 aVer = ExploW.Current();
317 if (aVer.IsSame(Ver[i]))
320 if (aVer.IsSame(Ver[i]))
322 VerWireMap.Bind(aVer, aWire);
329 TopTools_DataMapOfShapeListOfShape VerSecMap;
330 for (itl.Initialize(Lwires); itl.More(); itl.Next())
332 const TopoDS_Wire& aWire = TopoDS::Wire(itl.Value());
333 TopoDS_Vertex V1, V2;
334 TopExp::Vertices(aWire, V1, V2);
335 TopTools_ListOfShape LW1, LW2;
336 if (!VerSecMap.IsBound(V1))
337 VerSecMap.Bind(V1, LW1);
338 VerSecMap(V1).Append(aWire);
339 if (!VerSecMap.IsBound(V2))
340 VerSecMap.Bind(V2, LW2);
341 VerSecMap(V2).Append(aWire);
344 //TopTools_IndexedDataMapOfShapeShape InnerTouchingWiresOnVertex;
346 TopoDS_Wire outerW = BRepTools::OuterWire(FaceRef);
347 TopoDS_Wire CurWire = outerW;
348 BRepLib_MakeWire *MW;
349 MW = new BRepLib_MakeWire();
350 BRepTools_WireExplorer wexp(CurWire, FaceRef);
353 TopoDS_Vertex theStartVertex = wexp.CurrentVertex(), CurVertex;
354 TopoDS_Edge CurEdge = wexp.Current();
355 TopoDS_Edge LastEdge = CurEdge;
357 TopoDS_Wire aSectionWire;
358 TopoDS_Vertex aBreakVertex;
361 wexp.Init(CurWire, FaceRef);
364 if (MW->Wire().Closed())
366 CurVertex = wexp.CurrentVertex();
367 if (VerSecMap.IsBound(CurVertex))
369 TopoDS_Shape aLocalWire = ChooseDirection(LastEdge, CurVertex, FaceRef, VerSecMap(CurVertex));
370 aSectionWire = TopoDS::Wire(aLocalWire);
373 CurEdge = wexp.Current();
378 wexp.Init(CurWire, FaceRef);
380 if (MW->Wire().Closed())
382 NewWires.Append(MW->Wire());
383 theStartVertex = TopoDS::Vertex(BreakVertices.First());
384 BreakVertices.RemoveFirst();
385 CurWire = TopoDS::Wire(BreakOnWires.First());
386 BreakOnWires.RemoveFirst();
387 wexp.Init(CurWire, FaceRef);
388 while (!wexp.CurrentVertex().IsSame(theStartVertex))
390 MW = new BRepLib_MakeWire();
393 aBreakVertex = CurVertex;
394 BreakVertices.Append(aBreakVertex);
395 BreakOnWires.Append(CurWire);
398 MW->Add(aSectionWire);
399 (SectionsTimes(aSectionWire))--;
400 if (SectionsTimes(aSectionWire) == 0)
401 SectionsTimes.UnBind(aSectionWire);
402 if (MW->Wire().Closed())
404 NewWires.Append(MW->Wire());
405 if (SectionsTimes.IsEmpty())
407 theStartVertex = TopoDS::Vertex(BreakVertices.First());
408 BreakVertices.RemoveFirst();
409 CurWire = TopoDS::Wire(BreakOnWires.First());
410 BreakOnWires.RemoveFirst();
411 wexp.Init(CurWire, FaceRef);
412 while (!wexp.CurrentVertex().IsSame(theStartVertex))
414 MW = new BRepLib_MakeWire();
419 TopoDS_Vertex V1, V2, aStartVertex;
420 TopExp::Vertices(aSectionWire, V1, V2);
421 aStartVertex = (V1.IsSame(aBreakVertex))? V2 : V1;
422 CurWire = TopoDS::Wire(VerWireMap(aStartVertex));
424 wexp.Init(CurWire, FaceRef);
425 while (!wexp.CurrentVertex().IsSame(aStartVertex))
428 const TopTools_ListOfShape& Lsections = VerSecMap(aStartVertex);
429 if (Lsections.Extent() == 1)
432 //else: choose the way
433 TopoDS_Wire NextSectionWire =
434 TopoDS::Wire((aSectionWire.IsSame(Lsections.First()))? Lsections.Last() : Lsections.First());
436 Standard_Integer Times = 0;
437 TopTools_DataMapIteratorOfDataMapOfShapeShape itVW(VerWireMap);
438 for (; itVW.More(); itVW.Next())
439 if (itVW.Value().IsSame(CurWire))
441 if (Times == 1) //it is inner touching wire
443 //InnerTouchingWiresOnVertex.Bind(aWire, aStartVertex);
447 //we have to choose the direction
448 TopoDS_Edge aStartEdge = wexp.Current();
449 TopTools_ListOfShape Ldirs;
450 Ldirs.Append(aStartEdge);
451 Ldirs.Append(NextSectionWire);
452 TopoDS_Shape theDirection = ChooseDirection(aSectionWire, aStartVertex, FaceRef, Ldirs);
453 if (theDirection.IsSame(aStartEdge))
456 aSectionWire = NextSectionWire;
457 aBreakVertex = aStartVertex;
458 } //end of else (MW is not closed)
459 } //end of for (;;) (loop on section wires)
460 if (SectionsTimes.IsEmpty())
462 } //end of global for (;;)
464 TopTools_ListOfShape NewFaces;
466 for (itl.Initialize(NewWires); itl.More(); itl.Next())
468 TopoDS_Shape aLocalFace = FaceRef.EmptyCopied();
469 TopoDS_Face aNewFace = TopoDS::Face(aLocalFace);
470 aNewFace.Orientation(TopAbs_FORWARD);
471 BB.Add(aNewFace, itl.Value());
472 NewFaces.Append(aNewFace);
476 TopTools_ListOfShape Holes;
477 for (ExploF.Init(FaceRef, TopAbs_WIRE); ExploF.More(); ExploF.Next())
479 const TopoDS_Shape& aWire = ExploF.Current();
480 ExploW.Init(aWire, TopAbs_EDGE);
481 TopoDS_Shape anEdge = ExploW.Current();
482 Standard_Boolean found = Standard_False;
483 for (itl.Initialize(NewWires); itl.More(); itl.Next())
485 const TopoDS_Shape& aNewWire = itl.Value();
486 for (ExploW.Init(aNewWire, TopAbs_EDGE); ExploW.More(); ExploW.Next())
488 if (anEdge.IsSame(ExploW.Current()))
490 found = Standard_True;
500 TopTools_ListIteratorOfListOfShape itlNewF;
501 for (itl.Initialize(Holes); itl.More(); itl.Next())
503 const TopoDS_Wire& aHole = TopoDS::Wire(itl.Value());
504 for (itlNewF.Initialize(NewFaces); itlNewF.More(); itlNewF.Next())
506 TopoDS_Face& aNewFace = TopoDS::Face(itlNewF.Value());
507 if (IsInside(aNewFace, aHole))
509 BB.Add(aNewFace, aHole);
518 //Update of descendants of wires
519 for (ExploF.Init(F, TopAbs_WIRE); ExploF.More(); ExploF.Next())
521 TopTools_ListOfShape& ls = myMap(ExploF.Current());
526 // JAG 10.11.95 Codage des regularites
527 for (itl.Initialize(Lwires); itl.More(); itl.Next())
528 for (ExploW.Init(itl.Value(), TopAbs_EDGE); ExploW.More(); ExploW.Next())
530 const TopoDS_Edge& edg = TopoDS::Edge(ExploW.Current());
531 if (!BRep_Tool::HasContinuity(edg,F,F)) {
532 BB.Continuity(edg,F,F,GeomAbs_CN);
538 //=======================================================================
541 //=======================================================================
543 void LocOpe_SplitShape::Add(const TopoDS_Wire& W,
544 const TopoDS_Face& F)
548 Standard_ConstructionError::Raise();
553 TopTools_ListOfShape& lf = myMap(F);
559 if (!LocOpe::Closed(W,F)) {
565 } catch (Standard_Failure ) {
567 cout << "Warning: SpliShape internal problem detected, some faces may be lost. Check input edges/wires" <<endl;
571 // JAG 10.11.95 Codage des regularites
573 for (exp.Init(W,TopAbs_EDGE); exp.More(); exp.Next()) {
574 const TopoDS_Edge& edg = TopoDS::Edge(exp.Current());
575 if (!BRep_Tool::HasContinuity(edg,F,F)) {
576 B.Continuity(edg,F,F,GeomAbs_CN);
583 //=======================================================================
584 //function : AddClosedWire
586 //=======================================================================
588 void LocOpe_SplitShape::AddClosedWire(const TopoDS_Wire& W,
589 const TopoDS_Face& F)
593 // On cherche la face descendante de F qui continent le wire
594 TopTools_ListOfShape& lf = myMap(F);
595 TopTools_ListIteratorOfListOfShape itl(lf);
597 for (; itl.More(); itl.Next()) {
598 const TopoDS_Face& fac = TopoDS::Face(itl.Value());
600 outerW = BRepTools::OuterWire(fac);
601 if (IsInside(F,W,outerW)) {
605 if (IsInside(fac,W)) {
611 Standard_ConstructionError::Raise();
616 TopAbs_Orientation orWire = W.Orientation();
617 TopoDS_Shape aLocalFace = F.EmptyCopied();
618 TopoDS_Face newFace = TopoDS::Face(aLocalFace);
619 // TopoDS_Face newFace = TopoDS::Face(F.EmptyCopied());
620 newFace.Orientation(TopAbs_FORWARD);
623 // BRepGProp::SurfaceProperties (newFace,GP);
624 // if (GP.Mass() < 0) {
625 BRepTopAdaptor_FClass2d classif(newFace,Precision::PConfusion());
626 if (classif.PerformInfinitePoint() == TopAbs_IN) {
627 //le wire donne defini un trou
628 aLocalFace = F.EmptyCopied();
629 newFace = TopoDS::Face(aLocalFace);
630 // newFace = TopoDS::Face(F.EmptyCopied());
631 newFace.Orientation(TopAbs_FORWARD);
632 orWire = TopAbs::Reverse(orWire);
633 B.Add(newFace,W.Oriented(orWire));
636 TopoDS_Face FaceRef = TopoDS::Face(itl.Value());
637 FaceRef.Orientation(TopAbs_FORWARD);
640 aLocalFace = FaceRef.EmptyCopied();
641 TopoDS_Face newRef = TopoDS::Face(aLocalFace);
642 // TopoDS_Face newRef = TopoDS::Face(FaceRef.EmptyCopied());
643 newRef.Orientation(TopAbs_FORWARD);
645 // On suppose que les edges du wire ont des courbes 2d.
646 // Comme on ne change pas de surface de base, pas besoin d`UpdateEdge.
648 for (exp.Init(FaceRef.Oriented(TopAbs_FORWARD),TopAbs_WIRE);
649 exp.More(); exp.Next()) {
650 const TopoDS_Wire& wir = TopoDS::Wire(exp.Current());
651 if (IsInside(F,wir,W)) {
658 B.Add(newRef,W.Oriented(TopAbs::Reverse(orWire)));
665 //=======================================================================
666 //function : AddOpenWire
668 //=======================================================================
670 void LocOpe_SplitShape::AddOpenWire(const TopoDS_Wire& W,
671 const TopoDS_Face& F)
673 // On cherche la face descendante de F qui continent le wire
674 TopTools_ListOfShape& lf = myMap(F);
675 TopTools_ListIteratorOfListOfShape itl(lf);
676 TopoDS_Vertex Vfirst,Vlast;
678 BRepTools::Update(F);
680 Standard_Real tolf, toll, tol1;
682 TopoDS_Shape aLocalShape = W.Oriented(TopAbs_FORWARD);
683 TopExp::Vertices(TopoDS::Wire(aLocalShape),Vfirst,Vlast);
685 tolf = BRep_Tool::Tolerance(Vfirst);
686 toll = BRep_Tool::Tolerance(Vlast);
687 tol1 = Max(tolf, toll);
690 TopExp_Explorer exp,exp2;
692 TopoDS_Wire wfirst,wlast;
693 for (; itl.More(); itl.Next()) {
694 TopoDS_Face fac = TopoDS::Face(itl.Value());
695 if (!IsInside(fac,W)) {
699 fac.Orientation(TopAbs_FORWARD);
700 Standard_Boolean ffound = Standard_False;
701 Standard_Boolean lfound = Standard_False;
702 for (exp.Init(fac,TopAbs_WIRE); exp.More(); exp.Next()) {
703 const TopoDS_Wire& wir = TopoDS::Wire(exp.Current());
704 for (exp2.Init(wir,TopAbs_VERTEX); exp2.More(); exp2.Next()) {
705 if (!ffound && exp2.Current().IsSame(Vfirst)) {
706 ffound = Standard_True;
709 else if (!lfound && exp2.Current().IsSame(Vlast)) {
710 lfound = Standard_True;
713 if (ffound && lfound) {
726 Standard_ConstructionError::Raise();
729 TopoDS_Face FaceRef = TopoDS::Face(itl.Value());
730 FaceRef.Orientation(TopAbs_FORWARD);
734 BRepAdaptor_Surface BAS(FaceRef, Standard_False);
736 Standard_Boolean IsPeriodic = BAS.IsUPeriodic() || BAS.IsVPeriodic();
738 tol1 = Max(BAS.UResolution(tol1), BAS.VResolution(tol1));
740 if (wfirst.IsSame(wlast)) {
741 // on cree 2 faces en remplacement de itl.Value()
743 TopTools_ListOfShape WiresFirst;
744 for (exp.Init(wfirst,TopAbs_EDGE); exp.More(); exp.Next()) {
745 if (BRep_Tool::IsClosed(TopoDS::Edge(exp.Current()),FaceRef)) {
746 myDblE.Add(exp.Current());
748 WiresFirst.Append(exp.Current());
751 TopAbs_Orientation orient;
752 TopoDS_Wire newW1,newW2;
754 newW1.Orientation(TopAbs_FORWARD);
756 newW2.Orientation(TopAbs_FORWARD);
758 Standard_Integer nbE = 0;
759 for (exp.Init(W.Oriented(TopAbs_FORWARD),TopAbs_EDGE);
760 exp.More(); exp.Next()) {
762 const TopoDS_Edge& edg = TopoDS::Edge(exp.Current());
763 orient = edg.Orientation();
764 WiresFirst.Append(edg);
765 WiresFirst.Append(edg.Oriented(TopAbs::Reverse(orient)));
769 TopTools_IndexedMapOfShape PossE;
770 TopTools_MapOfOrientedShape MapE;
771 TopoDS_Vertex vdeb,vfin;
772 Standard_Integer nbPoss;
774 // On recherche l`edge contenant Vlast
775 TopoDS_Edge LastEdge;
776 gp_Pnt2d pfirst,plast;
778 Handle(Geom2d_Curve) C2d;
781 for (exp.Init(W.Oriented(TopAbs_FORWARD),TopAbs_EDGE);
782 exp.More(); exp.Next()) {
783 const TopoDS_Edge& edg = TopoDS::Edge(exp.Current());
784 for (exp2.Init(edg,TopAbs_VERTEX); exp2.More(); exp2.Next()) {
785 if (exp2.Current().IsSame(Vfirst)) {
791 LastEdge.Orientation(edg.Orientation());
796 TopoDS_Shape aLocalFace = FaceRef.Oriented(wfirst.Orientation());
797 C2d = BRep_Tool::CurveOnSurface(LastEdge, TopoDS::Face(aLocalFace), f, l);
799 if (LastEdge.Orientation() == TopAbs_FORWARD) {
800 pfirst = C2d->Value(f);
803 pfirst = C2d->Value(l);
806 for (exp.Init(W.Oriented(TopAbs_FORWARD),TopAbs_EDGE);
807 exp.More(); exp.Next()) {
808 const TopoDS_Edge& edg = TopoDS::Edge(exp.Current());
809 if( nbE>1 && edg.IsSame(LastEdge) )
811 for (exp2.Init(edg,TopAbs_VERTEX); exp2.More(); exp2.Next()) {
812 if (exp2.Current().IsSame(Vlast)) {
818 LastEdge.Orientation(edg.Orientation());
822 aLocalFace = FaceRef.Oriented(wfirst.Orientation());
823 C2d = BRep_Tool::CurveOnSurface(LastEdge, TopoDS::Face(aLocalFace), f, l);
824 Standard_Real dpar = (l - f)*0.01;
826 if (LastEdge.Orientation() == TopAbs_FORWARD) {
827 C2d->D1(l,plast,dlast);
828 if (dlast.Magnitude() < gp::Resolution())
830 gp_Pnt2d PrevPnt = C2d->Value(l - dpar);
831 dlast.SetXY(plast.XY() - PrevPnt.XY());
835 C2d->D1(f,plast,dlast);
836 if (dlast.Magnitude() < gp::Resolution())
838 gp_Pnt2d NextPnt = C2d->Value(f + dpar);
839 dlast.SetXY(NextPnt.XY() - plast.XY());
844 Standard_Boolean cond;
848 cond = !(Vfirst.IsSame(Vlast) && SameUV(pfirst,plast,BAS));
851 cond = !(Vfirst.IsSame(Vlast));
857 // On enchaine par la fin
858 TopTools_ListIteratorOfListOfShape lexp(WiresFirst);
859 for (; lexp.More(); lexp.Next()) {
860 const TopoDS_Edge& edg = TopoDS::Edge(lexp.Value());
862 orient = edg.Orientation();
863 TopExp::Vertices(edg,vdeb,vfin);
864 if (orient == TopAbs_FORWARD && Vlast.IsSame(vdeb)) {
865 PossE.Add(edg.Oriented(orient));
867 else if (orient == TopAbs_REVERSED && Vlast.IsSame(vfin)) {
868 PossE.Add(edg.Oriented(orient));
871 nbPoss = PossE.Extent();
877 TopoDS_Edge aNextEdge;
879 aNextEdge = TopoDS::Edge (PossE.FindKey (1));
880 TopoDS_Shape aLocalFaceTemp = FaceRef.Oriented(wfirst.Orientation());
881 C2d = BRep_Tool::CurveOnSurface(aNextEdge,
882 TopoDS::Face(aLocalFaceTemp), f, l);
883 Standard_Real dparnew = (l - f)*0.01;
885 if (aNextEdge.Orientation() == TopAbs_FORWARD) {
886 C2d->D1(l,plast,dlast);
887 if (dlast.Magnitude() < gp::Resolution())
889 gp_Pnt2d PrevPnt = C2d->Value(l - dparnew);
890 dlast.SetXY(plast.XY() - PrevPnt.XY());
894 C2d->D1(f,plast,dlast);
895 if (dlast.Magnitude() < gp::Resolution())
897 gp_Pnt2d NextPnt = C2d->Value(f + dparnew);
898 dlast.SetXY(NextPnt.XY() - plast.XY());
903 else if (nbPoss > 1) {
904 // Faire choix en U,V...
905 TopoDS_Shape aLocalFaceTemp = FaceRef.Oriented(wfirst.Orientation());
907 ChoixUV(LastEdge, TopoDS::Face(aLocalFaceTemp), PossE,
908 aNextEdge, plast, dlast, toll);
912 if (aNextEdge.IsNull())
914 // loop is not closed. Split is not possible
915 Standard_ConstructionError::Raise("Split is not possible: split loop is not closed");
918 if (MapE.Contains(aNextEdge))
920 B.Add(newW1, aNextEdge);
922 LastEdge = aNextEdge;
924 if (LastEdge.Orientation() == TopAbs_FORWARD) {
925 Vlast = TopExp::LastVertex(LastEdge);
928 Vlast = TopExp::FirstVertex(LastEdge);
931 toll = BRep_Tool::Tolerance(Vlast);
932 tol1 = Max(tolf, toll);
935 //MODIFICATION PIERRE SMEYERS : si pas de possibilite, on sort avec erreur
937 cout<<"erreur Spliter : pas de chainage du wire"<<endl;
938 Standard_ConstructionError::Raise();
942 tol1 = Max(BAS.UResolution(tol1), BAS.VResolution(tol1));
946 TopTools_ListIteratorOfListOfShape lexp(WiresFirst);
947 for (; lexp.More(); lexp.Next()) {
948 const TopoDS_Edge& edg = TopoDS::Edge(lexp.Value());
949 if (!MapE.Contains(edg)) {
955 TopoDS_Face newF1,newF2;
956 aLocalFace = FaceRef.EmptyCopied();
957 newF1 = TopoDS::Face(aLocalFace);
958 newF1.Orientation(TopAbs_FORWARD);
959 aLocalFace = FaceRef.EmptyCopied();
960 newF2 = TopoDS::Face(aLocalFace);
961 newF2.Orientation(TopAbs_FORWARD);
963 // modifs JAG 97.05.28
966 //BRepTools::Write(newF1, "k:/queries/WrongBOP/NewF1.brep");
968 //BRepTools::Write(newF2, "k:/queries/WrongBOP/NewF2.brep");
970 for (exp.Init(FaceRef.Oriented(TopAbs_FORWARD),TopAbs_WIRE); exp.More(); exp.Next()) {
971 const TopoDS_Wire& wir = TopoDS::Wire(exp.Current());
972 if (!wir.IsSame(wfirst)) {
973 if (IsInside(newF1, wir)) {
976 else if (IsInside(newF2, wir)) {
980 // Ce wire est ni dans newF2 ni dans newF1
981 // Peut etre faut il construire une troisieme face
982 cout << "WARNING: LocOpe_SPlitShape : Ce wire est ni dans newF2 ni dans newF1" << endl;
989 // Mise a jour des descendants des wires
990 for (exp.Init(F,TopAbs_WIRE); exp.More(); exp.Next()) {
991 TopTools_ListOfShape& ls = myMap(exp.Current());
993 for (; itl.More(); itl.Next()) {
994 if (itl.Value().IsSame(wfirst)) {
998 if (itl.More()) { // on a trouve le wire
1006 // on ne cree qu`une seule face
1007 TopoDS_Wire outerW = BRepTools::OuterWire(FaceRef);
1008 TopoDS_Wire newWire;
1009 TopoDS_Face newFace;
1010 B.MakeWire(newWire);
1011 newWire.Orientation(TopAbs_FORWARD);
1012 TopAbs_Orientation orient,orRelat;
1014 if (wfirst.Orientation() == wlast.Orientation()) {
1015 orRelat = TopAbs_FORWARD;
1018 orRelat = TopAbs_REVERSED;
1021 if (wlast.IsSame(outerW)) {
1027 for (exp.Init(wfirst.Oriented(TopAbs_FORWARD),TopAbs_EDGE);
1028 exp.More(); exp.Next()) {
1029 B.Add(newWire,TopoDS::Edge(exp.Current()));
1033 for (exp.Init(wlast.Oriented(TopAbs_FORWARD),TopAbs_EDGE);
1034 exp.More(); exp.Next()) {
1035 const TopoDS_Edge& edg = TopoDS::Edge(exp.Current());
1036 orient = TopAbs::Compose(edg.Orientation(),orRelat);
1037 B.Add(newWire,edg.Oriented(orient));
1041 // Edges du wire ajoute, et dans les 2 sens
1042 for (exp.Init(W.Oriented(TopAbs_FORWARD),TopAbs_EDGE);
1043 exp.More(); exp.Next()) {
1044 const TopoDS_Edge& edg = TopoDS::Edge(exp.Current());
1045 orient = edg.Orientation();
1046 B.Add(newWire,edg.Oriented(orient));
1047 B.Add(newWire,edg.Oriented(TopAbs::Reverse(orient)));
1048 myDblE.Add(edg.Oriented(orient));
1051 // on refait une face
1053 TopoDS_Shape aLocalFace = FaceRef.EmptyCopied();
1054 newFace = TopoDS::Face(aLocalFace);
1055 // newFace = TopoDS::Face(FaceRef.EmptyCopied());
1056 FaceRef.Orientation(TopAbs_FORWARD);
1057 for (exp.Init(FaceRef.Oriented(TopAbs_FORWARD),TopAbs_WIRE);
1058 exp.More(); exp.Next()) {
1059 const TopoDS_Wire& wir = TopoDS::Wire(exp.Current());
1060 if (wir.IsSame(wfirst)) {
1061 B.Add(newFace,newWire.Oriented(wir.Orientation()));
1063 else if (!wir.IsSame(wlast)) {
1069 // Mise a jour des descendants des wires
1070 for (exp.Init(F,TopAbs_WIRE); exp.More(); exp.Next()) {
1071 TopTools_ListOfShape& ls = myMap(exp.Current());
1073 Standard_Boolean touch = Standard_False;
1074 while (itl.More()) {
1075 if (itl.Value().IsSame(wfirst) || itl.Value().IsSame(wlast)) {
1077 touch = Standard_True;
1092 //=======================================================================
1095 //=======================================================================
1097 const TopTools_ListOfShape& LocOpe_SplitShape::LeftOf(const TopoDS_Wire& W,
1098 const TopoDS_Face& F)
1100 if (myShape.IsNull()) {
1101 Standard_NoSuchObject::Raise();
1104 TopExp_Explorer exp,expw,expf;
1105 exp.Init(myShape,TopAbs_FACE);
1106 for (; exp.More(); exp.Next()) {
1107 if (exp.Current().IsSame(F)) {
1112 Standard_NoSuchObject::Raise();
1116 const TopoDS_Face& theFace = TopoDS::Face(exp.Current());
1117 TopAbs_Orientation orFace = theFace.Orientation();
1118 TopTools_ListIteratorOfListOfShape itl,itl2;
1120 for (expw.Init(W,TopAbs_EDGE); expw.More(); expw.Next()) {
1121 const TopoDS_Edge& edg = TopoDS::Edge(expw.Current());
1122 for (itl.Initialize(myMap(theFace)); itl.More(); itl.Next()) {
1123 TopoDS_Face fac = TopoDS::Face(itl.Value());
1124 fac.Orientation(orFace);
1125 for (expf.Init(fac,TopAbs_EDGE); expf.More(); expf.Next()) {
1126 const TopoDS_Edge& edgbis = TopoDS::Edge(expf.Current());
1127 if (edgbis.IsSame(edg) &&
1128 edgbis.Orientation() == edg.Orientation()) {
1129 for (itl2.Initialize(myLeft); itl2.More(); itl2.Next()) {
1130 if (itl2.Value().IsSame(fac)) {
1134 if (!itl2.More()) { // la face n`est pas deja presente
1140 if (expf.More()) { // face found
1149 //=======================================================================
1150 //function : DescendantShapes
1152 //=======================================================================
1154 const TopTools_ListOfShape& LocOpe_SplitShape::DescendantShapes
1155 (const TopoDS_Shape& S)
1159 myDone = Standard_True;
1162 if (!myDblE.IsEmpty()) {
1163 cout << "Le shape comporte des faces invalides" << endl;
1171 //=======================================================================
1174 //=======================================================================
1176 void LocOpe_SplitShape::Put(const TopoDS_Shape& S)
1178 if (!myMap.IsBound(S)) {
1179 TopTools_ListOfShape thelist;
1180 myMap.Bind(S, thelist);
1181 if (S.ShapeType() != TopAbs_VERTEX) {
1182 for(TopoDS_Iterator theIterator(S);theIterator.More();
1183 theIterator.Next()) {
1184 Put(theIterator.Value());
1194 //=======================================================================
1195 //function : Rebuild
1197 //=======================================================================
1199 Standard_Boolean LocOpe_SplitShape::Rebuild(const TopoDS_Shape& S)
1203 TopTools_ListIteratorOfListOfShape itr(myMap(S));
1205 if (itr.Value().IsSame(S)) {
1206 return Standard_False;
1208 return Standard_True;
1210 Standard_Boolean rebuild = Standard_False;
1212 for(it.Initialize(S); it.More(); it.Next()) {
1213 rebuild = Rebuild(it.Value()) || rebuild;
1218 TopoDS_Shape result = S.EmptyCopied();
1219 TopAbs_Orientation orient;
1220 for(it.Initialize(S); it.More(); it.Next()) {
1221 orient = it.Value().Orientation();
1222 for (itr.Initialize(myMap(it.Value())); itr.More(); itr.Next()) {
1223 B.Add(result,itr.Value().Oriented(orient));
1226 // Assign "Closed" flag for Wires and Shells only
1227 if (result.ShapeType() == TopAbs_WIRE || result.ShapeType() == TopAbs_SHELL)
1228 result.Closed (BRep_Tool::IsClosed(result));
1229 myMap(S).Append(result);
1239 //=======================================================================
1240 //function : IsInside
1242 //=======================================================================
1244 static Standard_Boolean IsInside(const TopoDS_Face& F,
1245 const TopoDS_Wire& W1,
1246 const TopoDS_Wire& W2)
1248 // Attention, c`est tres boeuf !!!!
1250 TopoDS_Shape aLocalShape = F.EmptyCopied();
1251 TopoDS_Face newFace = TopoDS::Face(aLocalShape);
1252 // TopoDS_Face newFace = TopoDS::Face(F.EmptyCopied());
1254 //TopAbs_Orientation orWire = W2.Orientation();
1256 newFace.Orientation(TopAbs_FORWARD);
1259 // BRepGProp::SurfaceProperties(newFace,GP);
1260 // if (GP.Mass() < 0) {
1261 BRepTopAdaptor_FClass2d classif(newFace,Precision::PConfusion());
1262 Standard_Boolean Reversed = Standard_False;
1263 if (classif.PerformInfinitePoint() == TopAbs_IN) {
1264 //le wire donne defini un trou
1265 // newFace = TopoDS::Face(F.EmptyCopied());
1266 // newFace.Orientation(TopAbs_FORWARD);
1267 // orWire = TopAbs::Reverse(orWire);
1268 // B.Add(newFace,W2.Oriented(orWire));
1269 Reversed = Standard_True;
1272 // Standard_Real U,V;
1273 TopExp_Explorer exp(W1,TopAbs_EDGE);
1274 const TopoDS_Edge& edg = TopoDS::Edge(exp.Current());
1275 TopExp_Explorer exp2(edg,TopAbs_VERTEX);
1276 const TopoDS_Vertex& vtx = TopoDS::Vertex(exp2.Current());
1277 Standard_Real prm = BRep_Tool::Parameter(vtx,edg);
1279 Handle(Geom2d_Curve) C2d = BRep_Tool::CurveOnSurface(edg,F,f,l);
1282 cout << "Edge is not on surface" <<endl;
1284 return Standard_False;
1286 gp_Pnt2d pt2d(C2d->Value(prm));
1287 // BRepClass_FaceClassifier classif(newFace,pt2d,Precision::PConfusion());
1288 // return (classif.State() == TopAbs_IN);
1290 return (classif.Perform(pt2d) == TopAbs_IN);
1293 return (classif.Perform(pt2d) == TopAbs_OUT);
1298 //=======================================================================
1299 //function : IsInside
1301 //=======================================================================
1303 static Standard_Boolean IsInside(const TopoDS_Face& F,
1304 const TopoDS_Wire& W)
1306 // Attention, c`est tres boeuf !!!!
1307 TopExp_Explorer exp(W,TopAbs_EDGE);
1308 for( ; exp.More(); exp.Next()) {
1309 const TopoDS_Edge& edg = TopoDS::Edge(exp.Current());
1310 // TopExp_Explorer exp2(edg,TopAbs_VERTEX);
1311 // const TopoDS_Vertex& vtx = TopoDS::Vertex(exp2.Current());
1312 // Standard_Real prm = BRep_Tool::Parameter(vtx,edg);
1313 Standard_Real f,l,prm;
1314 Handle(Geom2d_Curve) C2d = BRep_Tool::CurveOnSurface(edg,F,f,l);
1315 if (!Precision::IsNegativeInfinite(f) &&
1316 !Precision::IsPositiveInfinite(l)) {
1320 if (Precision::IsNegativeInfinite(f) &&
1321 Precision::IsPositiveInfinite(l)){
1324 else if (Precision::IsNegativeInfinite(f)) {
1332 gp_Pnt2d pt2d(C2d->Value(prm));
1333 // BRepClass_FaceClassifier classif(F,pt2d,Precision::PConfusion());
1334 // return (classif.State() != TopAbs_OUT);
1335 BRepTopAdaptor_FClass2d classif(F,Precision::PConfusion());
1336 TopAbs_State stat = classif.Perform(pt2d);
1337 // return (classif.Perform(pt2d) != TopAbs_OUT);
1338 if(stat == TopAbs_OUT) return Standard_False;
1340 if(stat == TopAbs_ON) {
1341 Standard_Integer nbPnt =10;
1342 Standard_Integer nbOut =0,nbIn =0,nbOn=0;
1343 Standard_Integer j =1;
1344 for( ; j<= nbPnt ; j++)
1346 //check neighbouring point
1347 //prm = .66 * prm + .34 * l;
1348 prm = f + (l-f)/nbPnt*(j-1);
1349 pt2d = C2d->Value(prm);
1350 stat = classif.Perform(pt2d);
1351 if(stat == TopAbs_OUT )
1353 else if(stat == TopAbs_IN)
1358 if(nbOut > nbIn + nbOn)
1359 return Standard_False;
1362 return Standard_True;
1365 //=======================================================================
1366 //function : GetDirection
1368 //=======================================================================
1369 static void GetDirection(const TopoDS_Edge& theEdge,
1370 const TopoDS_Face& theFace,
1371 Standard_Real& theTol,
1375 Standard_Real aFirst, aLast;
1376 Handle(Geom2d_Curve) aC2d = BRep_Tool::CurveOnSurface (theEdge, theFace, aFirst, aLast);
1378 TopAbs_Orientation anOr = theEdge.Orientation();
1380 if (anOr == TopAbs_FORWARD)
1382 aVtx = TopExp::FirstVertex (theEdge);
1383 aC2d->D0 (aFirst, thePnt);
1387 aVtx = TopExp::LastVertex (theEdge);
1388 aC2d->D0 (aLast, thePnt);
1391 BRepAdaptor_Surface aSurf (theFace, Standard_False);
1392 theTol = BRep_Tool::Tolerance (aVtx);
1393 Standard_Real aTol = Max (aSurf.UResolution (theTol), aSurf.VResolution (theTol));
1394 aTol = Min (aTol, (aLast - aFirst)*0.1);
1398 if (anOr == TopAbs_FORWARD)
1401 aC2d->D0 (aFirst, aP2d);
1406 aC2d->D0 (aLast, aP2d);
1408 theDir = gp_Vec2d (thePnt, aP2d);
1411 //=======================================================================
1412 //function : ChoixUV
1414 //=======================================================================
1416 static void ChoixUV(const TopoDS_Edge& Last,
1417 const TopoDS_Face& F,
1418 const TopTools_IndexedMapOfShape& Poss,
1419 TopoDS_Edge& theResEdge,
1422 const Standard_Real toll)
1428 gp_Pnt aPCur, aPlst;
1430 BRepAdaptor_Surface surf(F,Standard_False); // no restriction
1431 surf.D0 (plst.X(), plst.Y(), aPlst);
1435 gp_Dir2d ref2d(dlst);
1437 Handle(Geom2d_Curve) C2d;
1440 Standard_Integer index = 0, imin=0;
1441 Standard_Real angmax = -M_PI, dist, ang;
1444 for (index = 1; index <= Poss.Extent(); index++) {
1445 TopoDS_Edge anEdge = TopoDS::Edge (Poss.FindKey (index));
1446 GetDirection (anEdge, F, tol, p2d, v2d);
1448 surf.D0 (p2d.X(), p2d.Y(), aPCur);
1450 tol = Max(toll, tol); tol *= tol;
1452 dist = aPCur.SquareDistance(aPlst);
1454 if (!Last.IsSame(anEdge)) {
1455 ang = ref2d.Angle(gp_Dir2d(v2d));
1461 if ((dist - tol < Epsilon(1.0)) && (ang > angmax)) {
1469 theResEdge = TopoDS::Edge (Poss.FindKey (imin));
1470 C2d = BRep_Tool::CurveOnSurface (theResEdge, F, f, l);
1471 dpar = (l - f)*0.01;
1472 if (theResEdge.Orientation() == TopAbs_FORWARD)
1474 C2d->D1 (l, plst, dlst);
1475 if (dlst.Magnitude() < gp::Resolution())
1477 gp_Pnt2d PrevPnt = C2d->Value(l - dpar);
1478 dlst.SetXY(plst.XY() - PrevPnt.XY());
1483 C2d->D1 (f, plst, dlst);
1484 if (dlst.Magnitude() < gp::Resolution())
1486 gp_Pnt2d NextPnt = C2d->Value(f + dpar);
1487 dlst.SetXY(NextPnt.XY() - plst.XY());
1495 //=======================================================================
1496 //function : ChooseDirection
1498 //=======================================================================
1500 static TopoDS_Shape ChooseDirection(const TopoDS_Shape& RefDir,
1501 const TopoDS_Vertex& RefVertex,
1502 const TopoDS_Face& theFace,
1503 const TopTools_ListOfShape& Ldirs)
1505 TopExp_Explorer Explo(RefDir, TopAbs_EDGE);
1506 TopoDS_Edge RefEdge;
1507 TopoDS_Vertex V1, V2;
1508 TopAbs_Orientation anOr = TopAbs_FORWARD;
1509 for (; Explo.More(); Explo.Next())
1511 RefEdge = TopoDS::Edge(Explo.Current());
1512 TopExp::Vertices(RefEdge, V1, V2);
1513 if (V1.IsSame(RefVertex))
1515 anOr = TopAbs_REVERSED;
1518 else if (V2.IsSame(RefVertex))
1520 anOr = TopAbs_FORWARD;
1525 Standard_Real RefFirst, RefLast;
1526 Handle(Geom2d_Curve) RefCurve = BRep_Tool::CurveOnSurface(RefEdge, theFace, RefFirst, RefLast);
1530 //Standard_Real RefPar = (RefEdge.Orientation() == TopAbs_FORWARD)? RefLast : RefFirst;
1531 Standard_Real RefPar = (anOr == TopAbs_FORWARD)? RefLast : RefFirst;
1532 RefCurve->D1(RefPar, RefPnt, RefVec);
1533 if (anOr == TopAbs_FORWARD)
1536 Handle(Geom2d_Curve) aCurve;
1537 Standard_Real aFirst, aLast, aPar;
1539 Standard_Real MinAngle = RealLast(), anAngle;
1540 TopoDS_Shape TargetDir;
1541 TopTools_ListIteratorOfListOfShape itl(Ldirs);
1542 for (; itl.More(); itl.Next())
1544 const TopoDS_Shape& aShape = itl.Value();
1546 for (Explo.Init(aShape, TopAbs_EDGE); Explo.More(); Explo.Next())
1548 anEdge = TopoDS::Edge(Explo.Current());
1549 TopExp::Vertices(anEdge, V1, V2);
1550 if (V1.IsSame(RefVertex))
1552 anOr = TopAbs_FORWARD;
1555 else if (V2.IsSame(RefVertex))
1557 anOr = TopAbs_REVERSED;
1561 aCurve = BRep_Tool::CurveOnSurface(anEdge, theFace, aFirst, aLast);
1562 aPar = (anOr == TopAbs_FORWARD)? aFirst : aLast;
1563 aCurve->D1(aPar, RefPnt, aVec);
1564 if (anOr == TopAbs_REVERSED)
1566 anAngle = aVec.Angle(RefVec);
1570 if (anAngle < MinAngle)