-// File: LocOpe_SplitShape.cxx
-// Created: Tue Jun 27 16:37:40 1995
-// Author: Jacques GOUSSARD
-// <jag@bravox>
+// Created on: 1995-06-27
+// Created by: Jacques GOUSSARD
+// Copyright (c) 1995-1999 Matra Datavision
+// Copyright (c) 1999-2014 OPEN CASCADE SAS
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License version 2.1 as published
+// by the Free Software Foundation, with special exception defined in the file
+// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
+// distribution for complete text of the license and disclaimer of any warranty.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement.
-#include <LocOpe_SplitShape.ixx>
-
-#include <TopTools_ListOfShape.hxx>
-#include <TopTools_ListIteratorOfListOfShape.hxx>
-#include <TopTools_MapOfShape.hxx>
-#include <TopTools_DataMapOfShapeListOfShape.hxx>
-#include <TopTools_DataMapIteratorOfDataMapOfShapeListOfShape.hxx>
-#include <TopTools_MapIteratorOfMapOfShape.hxx>
-#include <TopoDS_Iterator.hxx>
-#include <TopExp_Explorer.hxx>
#include <BRep_Builder.hxx>
-#include <TopoDS_Vertex.hxx>
-#include <BRepLib_MakeFace.hxx>
#include <BRep_Tool.hxx>
-#include <BRepTools.hxx>
-#include <BRep_Builder.hxx>
-
+#include <BRepAdaptor_Surface.hxx>
#include <BRepClass_FaceExplorer.hxx>
+#include <BRepLib_MakeFace.hxx>
+#include <BRepLib_MakeWire.hxx>
+#include <BRepTools.hxx>
+#include <BRepTools_WireExplorer.hxx>
#include <BRepTopAdaptor_FClass2d.hxx>
-#include <BRepAdaptor_Surface.hxx>
-
#include <Geom2d_Curve.hxx>
+#include <gp_Dir2d.hxx>
#include <gp_Pnt2d.hxx>
#include <gp_Vec2d.hxx>
-#include <gp_Dir2d.hxx>
-#include <TopoDS.hxx>
-#include <TopExp.hxx>
-#include <Precision.hxx>
-#include <BRepTools.hxx>
#include <LocOpe.hxx>
+#include <LocOpe_SplitShape.hxx>
+#include <Precision.hxx>
+#include <Standard_ConstructionError.hxx>
#include <Standard_ErrorHandler.hxx>
+#include <Standard_NoSuchObject.hxx>
+#include <StdFail_NotDone.hxx>
+#include <TopExp.hxx>
+#include <TopExp_Explorer.hxx>
+#include <TopoDS.hxx>
+#include <TopoDS_Edge.hxx>
+#include <TopoDS_Face.hxx>
+#include <TopoDS_Iterator.hxx>
+#include <TopoDS_Shape.hxx>
+#include <TopoDS_Vertex.hxx>
+#include <TopoDS_Wire.hxx>
+#include <TopTools_DataMapIteratorOfDataMapOfShapeListOfShape.hxx>
+#include <TopTools_DataMapIteratorOfDataMapOfShapeShape.hxx>
+#include <TopTools_DataMapOfShapeInteger.hxx>
+#include <TopTools_DataMapOfShapeListOfShape.hxx>
+#include <TopTools_DataMapOfShapeShape.hxx>
+#include <TopTools_IndexedMapOfShape.hxx>
+#include <TopTools_ListIteratorOfListOfShape.hxx>
+#include <TopTools_ListOfShape.hxx>
+#include <TopTools_MapIteratorOfMapOfOrientedShape.hxx>
+#include <TopTools_MapIteratorOfMapOfShape.hxx>
+#include <TopTools_MapOfOrientedShape.hxx>
+#include <TopTools_MapOfShape.hxx>
+#include <ShapeAnalysis_Edge.hxx>
+#include <Geom2dAPI_ProjectPointOnCurve.hxx>
+
+#include <Geom_Surface.hxx>
static Standard_Boolean IsInside(const TopoDS_Face&,
const TopoDS_Wire&,
static Standard_Boolean IsInside(const TopoDS_Face&,
const TopoDS_Wire&);
-static void ChoixUV(const TopoDS_Edge&,
+static void GetDirection(const TopoDS_Edge&,
+ const TopoDS_Face&,
+ gp_Pnt2d&,
+ gp_Vec2d&,
+ Standard_Boolean isFirstEnd);
+
+static Standard_Boolean ChoixUV(const TopoDS_Edge&,
const TopoDS_Face&,
- const TopTools_MapOfShape&,
- TopTools_MapIteratorOfMapOfShape&,
+ const TopTools_IndexedMapOfShape&,
+ TopoDS_Edge&,
gp_Pnt2d&,
- gp_Vec2d&,
- const Standard_Real tol);
+ gp_Vec2d&);
+
+static TopoDS_Shape ChooseDirection(const TopoDS_Shape&,
+ const TopoDS_Vertex&,
+ const TopoDS_Face&,
+ const TopTools_ListOfShape&);
inline Standard_Boolean SameUV(const gp_Pnt2d& P1, const gp_Pnt2d& P2,
const BRepAdaptor_Surface& theBAS)//const Standard_Real tol)
{
- // Standard_Real tol = Precision::Confusion();
- // return P1.SquareDistance(P2) < 10*tol;
- //gka
Standard_Boolean isSame = Standard_True;
if(theBAS.IsUPeriodic())
isSame = (fabs(P1.X() - P2.X()) < theBAS.UPeriod() *0.5);
const TopoDS_Edge& E)
{
if (!CanSplit(E)) {
- Standard_ConstructionError::Raise();
+ return;
}
BRep_Builder B;
}
TopTools_ListIteratorOfListOfShape itl(le);
Standard_Real f,l;
-
+ TopTools_ListOfShape aNewList;
for (; itl.More(); itl.Next()) {
const TopoDS_Edge& edg = TopoDS::Edge(itl.Value());
BRep_Tool::Range(edg,f,l);
- if (P>f && P <l) {
+ if (P > f + Precision::PConfusion() && P < l - Precision::PConfusion()) {
break;
+
}
+ aNewList.Append(edg);
}
if (!itl.More()) {
- Standard_ConstructionError::Raise();
+ return;
}
TopoDS_Edge edg = TopoDS::Edge(itl.Value());
le.Remove(itl);
if (V.Orientation() == TopAbs_FORWARD ||
V.Orientation() == TopAbs_REVERSED) {
+ edg.Orientation(TopAbs_FORWARD);
+ TopoDS_Vertex aCurV1, aCurV2;
+ TopExp::Vertices(edg, aCurV1, aCurV2);
+ Standard_Real aPar1 = BRep_Tool::Parameter(aCurV1,edg);
+
+ Standard_Real aPar2 = BRep_Tool::Parameter(aCurV2,edg);
+
TopoDS_Shape aLocalShape = edg.EmptyCopied();
TopoDS_Edge E1 = TopoDS::Edge(aLocalShape);
aLocalShape = edg.EmptyCopied();
E1.Orientation(TopAbs_FORWARD);
E2.Orientation(TopAbs_FORWARD);
TopoDS_Vertex newVtx = V;
+ Standard_Real aTolSplitV = BRep_Tool::Tolerance(V);
+
+ aCurV1.Orientation(TopAbs_FORWARD);
+
+ B.Add(E1,aCurV1);
+ //for degenerated edges tolerance of vertices should be set to maximal value
+ //from tolerance of the vertex of the edge and tolerance of splitting vertex
+ Standard_Real aTolV1 = ( BRep_Tool::Degenerated(edg) ?
+ Max(BRep_Tool::Tolerance(aCurV1), aTolSplitV) : BRep_Tool::Tolerance(aCurV1));
+
+ B.UpdateVertex(aCurV1,aPar1,E1, aTolV1);
newVtx.Orientation(TopAbs_REVERSED);
B.Add(E1,newVtx);
B.UpdateVertex(newVtx,P,E1,BRep_Tool::Tolerance(V));
newVtx.Orientation(TopAbs_FORWARD);
B.Add(E2,newVtx);
B.UpdateVertex(newVtx,P,E2,BRep_Tool::Tolerance(V));
- edg.Orientation(TopAbs_FORWARD);
- TopExp_Explorer exp;
- for (exp.Init(edg,TopAbs_VERTEX); exp.More(); exp.Next()) {
- // for (TopExp_Explorer exp(edg,TopAbs_VERTEX); exp.More(); exp.Next()) {
- const TopoDS_Vertex& vtx = TopoDS::Vertex(exp.Current());
- f = BRep_Tool::Parameter(vtx,edg);
- if (f < P) {
- B.Add(E1,vtx);
- B.UpdateVertex(vtx,f,E1,BRep_Tool::Tolerance(vtx));
- }
- else {
- B.Add(E2,vtx);
- B.UpdateVertex(vtx,f,E2,BRep_Tool::Tolerance(vtx));
- }
+
+ aCurV2.Orientation(TopAbs_REVERSED);
+ B.Add(E2,aCurV2);
+
+ //for degenerated edges tolerance of vertices should be set to maximal value
+ //from tolerance of the vertex of the edge and tolerance of splitting vertex
+ Standard_Real aTolV2 = ( BRep_Tool::Degenerated(edg) ? aTolV1 : BRep_Tool::Tolerance(aCurV2));
+ B.UpdateVertex(aCurV2,aPar2,E2,aTolV2);
+
+ aNewList.Append(E1);
+ aNewList.Append(E2);
+ for (; itl.More(); itl.Next())
+ {
+ const TopoDS_Edge& edg1 = TopoDS::Edge(itl.Value());
+ aNewList.Append(edg1);
}
- le.Append(E1);
- le.Append(E2);
+ myMap.UnBind(E);
+ myMap.Bind(E, aNewList);
+
}
else {
TopoDS_Shape aLocalShape = edg.EmptyCopied();
TopoDS_Edge E1 = TopoDS::Edge(aLocalShape);
- // TopoDS_Edge E1 = TopoDS::Edge(edg.EmptyCopied());
+
TopExp_Explorer exp;
for (exp.Init(edg,TopAbs_VERTEX); exp.More(); exp.Next()) {
- // for (TopExp_Explorer exp(edg,TopAbs_VERTEX); exp.More(); exp.Next()) {
+
const TopoDS_Vertex& vtx = TopoDS::Vertex(exp.Current());
f = BRep_Tool::Parameter(vtx,edg);
B.Add(E1,vtx);
}
}
+//=======================================================================
+//function : Add
+//purpose : adds the list of wires on the face <F>
+//=======================================================================
+
+Standard_Boolean LocOpe_SplitShape::Add(const TopTools_ListOfShape& Lwires,
+ const TopoDS_Face& F)
+{
+
+ if (myDone) {
+ return Standard_False;
+ }
+
+ TopTools_ListOfShape& lf = myMap(F);
+ if (lf.IsEmpty()) {
+ Rebuild(F);
+ }
+
+ // On cherche la face descendante de F qui continent le wire
+ lf = myMap(F);
+ TopTools_ListIteratorOfListOfShape itl(lf);
+ TopoDS_Vertex Vfirst,Vlast;
+
+ BRepTools::Update(F);
+
+ TopTools_ListOfShape aLInside;
+ for (; itl.More(); itl.Next())
+ {
+ const TopoDS_Face& fac = TopoDS::Face(itl.Value());
+ TopTools_ListIteratorOfListOfShape itwires(Lwires);
+ for (; itwires.More(); itwires.Next())
+ {
+ const TopoDS_Wire& aWire = TopoDS::Wire(itwires.Value());
+ if (IsInside(fac, aWire))
+ {
+ aLInside.Append(aWire);
+
+ }
+ }
+ if(aLInside.Extent())
+ break;
+ }
+ if (!aLInside.Extent() || !itl.More()) {
+ return Standard_False;
+ }
+
+ TopoDS_Face FaceRef = TopoDS::Face(itl.Value());
+ FaceRef.Orientation(TopAbs_FORWARD);
+ lf.Remove(itl);
+
+ TopTools_ListOfShape NewWires;
+
+ TopTools_DataMapOfShapeInteger SectionsTimes;
+ for (itl.Initialize(aLInside); itl.More(); itl.Next())
+ SectionsTimes.Bind(itl.Value(), 2);
+
+ TopTools_ListOfShape BreakVertices;
+ TopTools_ListOfShape BreakOnWires;
+
+ TopTools_DataMapOfShapeShape VerWireMap;
+ Standard_Integer i;
+ TopExp_Explorer ExploF, ExploW;
+ for (itl.Initialize(aLInside); itl.More(); itl.Next())
+ {
+ const TopoDS_Wire& aSection = TopoDS::Wire(itl.Value());
+ TopoDS_Vertex Ver [2];
+ TopExp::Vertices(aSection, Ver[0], Ver[1]);
+ for (i = 0; i < 2; i++)
+ {
+ if (VerWireMap.IsBound(Ver[i]))
+ continue;
+ for (ExploF.Init(FaceRef, TopAbs_WIRE); ExploF.More(); ExploF.Next())
+ {
+ const TopoDS_Shape& aWire = ExploF.Current();
+ TopoDS_Shape aVer;
+ for (ExploW.Init(aWire, TopAbs_VERTEX); ExploW.More(); ExploW.Next())
+ {
+ aVer = ExploW.Current();
+ if (aVer.IsSame(Ver[i]))
+ break;
+ }
+ if (aVer.IsSame(Ver[i]))
+ {
+ VerWireMap.Bind(aVer, aWire);
+ break;
+ }
+ }
+ }
+ }
+
+ TopTools_DataMapOfShapeListOfShape VerSecMap;
+ for (itl.Initialize(aLInside); itl.More(); itl.Next())
+ {
+ const TopoDS_Wire& aWire = TopoDS::Wire(itl.Value());
+ TopoDS_Vertex V1, V2;
+ TopExp::Vertices(aWire, V1, V2);
+ TopTools_ListOfShape LW1, LW2;
+ if (!VerSecMap.IsBound(V1))
+ VerSecMap.Bind(V1, LW1);
+ VerSecMap(V1).Append(aWire);
+ if (!VerSecMap.IsBound(V2))
+ VerSecMap.Bind(V2, LW2);
+ VerSecMap(V2).Append(aWire);
+ }
+
+ //TopTools_IndexedDataMapOfShapeShape InnerTouchingWiresOnVertex;
+
+ TopoDS_Wire outerW = BRepTools::OuterWire(FaceRef);
+ TopoDS_Wire CurWire = outerW;
+ BRepLib_MakeWire *MW;
+ MW = new BRepLib_MakeWire();
+ BRepTools_WireExplorer wexp(CurWire, FaceRef);
+ for (;;)
+ {
+ TopoDS_Vertex theStartVertex = wexp.CurrentVertex(), CurVertex;
+ TopoDS_Edge CurEdge = wexp.Current();
+ TopoDS_Edge LastEdge = CurEdge;
+ MW->Add(CurEdge);
+ TopoDS_Wire aSectionWire;
+ TopoDS_Vertex aBreakVertex;
+ wexp.Next();
+ if (!wexp.More())
+ wexp.Init(CurWire, FaceRef);
+ for (;;)
+ {
+ if (MW->Wire().Closed())
+ break;
+ CurVertex = wexp.CurrentVertex();
+ if (VerSecMap.IsBound(CurVertex))
+ {
+ TopoDS_Shape aLocalWire = ChooseDirection(LastEdge, CurVertex, FaceRef, VerSecMap(CurVertex));
+ aSectionWire = TopoDS::Wire(aLocalWire);
+ break;
+ }
+ CurEdge = wexp.Current();
+ MW->Add(CurEdge);
+ LastEdge = CurEdge;
+ wexp.Next();
+ if (!wexp.More())
+ wexp.Init(CurWire, FaceRef);
+ }
+ if (MW->Wire().Closed())
+ {
+ NewWires.Append(MW->Wire());
+ theStartVertex = TopoDS::Vertex(BreakVertices.First());
+ BreakVertices.RemoveFirst();
+ CurWire = TopoDS::Wire(BreakOnWires.First());
+ BreakOnWires.RemoveFirst();
+ wexp.Init(CurWire, FaceRef);
+ while (!wexp.CurrentVertex().IsSame(theStartVertex))
+ wexp.Next();
+ MW = new BRepLib_MakeWire();
+ continue;
+ }
+ aBreakVertex = CurVertex;
+ BreakVertices.Append(aBreakVertex);
+ BreakOnWires.Append(CurWire);
+ for (;;)
+ {
+ MW->Add(aSectionWire);
+ (SectionsTimes(aSectionWire))--;
+ if (SectionsTimes(aSectionWire) == 0)
+ SectionsTimes.UnBind(aSectionWire);
+ if (MW->Wire().Closed())
+ {
+ NewWires.Append(MW->Wire());
+ if (SectionsTimes.IsEmpty())
+ break;
+ theStartVertex = TopoDS::Vertex(BreakVertices.First());
+ BreakVertices.RemoveFirst();
+ CurWire = TopoDS::Wire(BreakOnWires.First());
+ BreakOnWires.RemoveFirst();
+ wexp.Init(CurWire, FaceRef);
+ while (!wexp.CurrentVertex().IsSame(theStartVertex))
+ wexp.Next();
+ MW = new BRepLib_MakeWire();
+ break;
+ }
+ else
+ {
+ TopoDS_Vertex V1, V2, aStartVertex;
+ TopExp::Vertices(aSectionWire, V1, V2);
+ aStartVertex = (V1.IsSame(aBreakVertex))? V2 : V1;
+ CurWire = TopoDS::Wire(VerWireMap(aStartVertex));
+
+ wexp.Init(CurWire, FaceRef);
+ while (!wexp.CurrentVertex().IsSame(aStartVertex))
+ wexp.Next();
+
+ const TopTools_ListOfShape& Lsections = VerSecMap(aStartVertex);
+ if (Lsections.Extent() == 1)
+ break;
+
+ //else: choose the way
+ TopoDS_Wire NextSectionWire =
+ TopoDS::Wire((aSectionWire.IsSame(Lsections.First()))? Lsections.Last() : Lsections.First());
+
+ Standard_Integer Times = 0;
+ TopTools_DataMapIteratorOfDataMapOfShapeShape itVW(VerWireMap);
+ for (; itVW.More(); itVW.Next())
+ if (itVW.Value().IsSame(CurWire))
+ Times++;
+ if (Times == 1) //it is inner touching wire
+ {
+ //InnerTouchingWiresOnVertex.Bind(aWire, aStartVertex);
+ }
+ else
+ {
+ //we have to choose the direction
+ TopoDS_Edge aStartEdge = wexp.Current();
+ TopTools_ListOfShape Ldirs;
+ Ldirs.Append(aStartEdge);
+ Ldirs.Append(NextSectionWire);
+ TopoDS_Shape theDirection = ChooseDirection(aSectionWire, aStartVertex, FaceRef, Ldirs);
+ if (theDirection.IsSame(aStartEdge))
+ break;
+ }
+ aSectionWire = NextSectionWire;
+ aBreakVertex = aStartVertex;
+ } //end of else (MW is not closed)
+ } //end of for (;;) (loop on section wires)
+ if (SectionsTimes.IsEmpty())
+ break;
+ } //end of global for (;;)
+
+ TopTools_ListOfShape NewFaces;
+ BRep_Builder BB;
+ for (itl.Initialize(NewWires); itl.More(); itl.Next())
+ {
+ TopoDS_Shape aLocalFace = FaceRef.EmptyCopied();
+ TopoDS_Face aNewFace = TopoDS::Face(aLocalFace);
+ aNewFace.Orientation(TopAbs_FORWARD);
+ BB.Add(aNewFace, itl.Value());
+ NewFaces.Append(aNewFace);
+ }
+
+ //Inserting holes
+ TopTools_ListOfShape Holes;
+ for (ExploF.Init(FaceRef, TopAbs_WIRE); ExploF.More(); ExploF.Next())
+ {
+ const TopoDS_Shape& aWire = ExploF.Current();
+ ExploW.Init(aWire, TopAbs_EDGE);
+ TopoDS_Shape anEdge = ExploW.Current();
+ Standard_Boolean found = Standard_False;
+ for (itl.Initialize(NewWires); itl.More(); itl.Next())
+ {
+ const TopoDS_Shape& aNewWire = itl.Value();
+ for (ExploW.Init(aNewWire, TopAbs_EDGE); ExploW.More(); ExploW.Next())
+ {
+ if (anEdge.IsSame(ExploW.Current()))
+ {
+ found = Standard_True;
+ break;
+ }
+ }
+ if (found)
+ break;
+ }
+ if (!found)
+ Holes.Append(aWire);
+ }
+ TopTools_ListIteratorOfListOfShape itlNewF;
+ for (itl.Initialize(Holes); itl.More(); itl.Next())
+ {
+ const TopoDS_Wire& aHole = TopoDS::Wire(itl.Value());
+ for (itlNewF.Initialize(NewFaces); itlNewF.More(); itlNewF.Next())
+ {
+ TopoDS_Face& aNewFace = TopoDS::Face(itlNewF.Value());
+ if (IsInside(aNewFace, aHole))
+ {
+ BB.Add(aNewFace, aHole);
+ break;
+ }
+ }
+ }
+
+ //Update "myMap"
+ lf.Append(NewFaces);
+
+ //Update of descendants of wires
+ for (ExploF.Init(F, TopAbs_WIRE); ExploF.More(); ExploF.Next())
+ {
+ TopTools_ListOfShape& ls = myMap(ExploF.Current());
+ ls.Clear();
+ }
+ ///////////////////
+
+ // JAG 10.11.95 Codage des regularites
+ for (itl.Initialize(aLInside); itl.More(); itl.Next())
+ for (ExploW.Init(itl.Value(), TopAbs_EDGE); ExploW.More(); ExploW.Next())
+ {
+ const TopoDS_Edge& edg = TopoDS::Edge(ExploW.Current());
+ if (!BRep_Tool::HasContinuity(edg,F,F)) {
+ BB.Continuity(edg,F,F,GeomAbs_CN);
+ }
+ }
+ return Standard_True;
+}
//=======================================================================
//purpose :
//=======================================================================
-void LocOpe_SplitShape::Add(const TopoDS_Wire& W,
+Standard_Boolean LocOpe_SplitShape::Add(const TopoDS_Wire& W,
const TopoDS_Face& F)
{
if (myDone) {
- Standard_ConstructionError::Raise();
+ return Standard_False;
}
try {
OCC_CATCH_SIGNALS
if (!LocOpe::Closed(W,F)) {
- AddOpenWire(W,F);
+ if(!AddOpenWire(W,F))
+ return Standard_False;
}
else {
- AddClosedWire(W,F);
+ if(!AddClosedWire(W,F))
+ return Standard_False;
}
} catch (Standard_Failure ) {
-#ifdef DEB
+#ifdef OCCT_DEBUG
cout << "Warning: SpliShape internal problem detected, some faces may be lost. Check input edges/wires" <<endl;
#endif
- return;
+ return Standard_False;
}
// JAG 10.11.95 Codage des regularites
BRep_Builder B;
B.Continuity(edg,F,F,GeomAbs_CN);
}
}
+ return Standard_True;
}
//purpose :
//=======================================================================
-void LocOpe_SplitShape::AddClosedWire(const TopoDS_Wire& W,
+Standard_Boolean LocOpe_SplitShape::AddClosedWire(const TopoDS_Wire& W,
const TopoDS_Face& F)
{
TopExp_Explorer exp;
TopoDS_Wire outerW;
for (; itl.More(); itl.Next()) {
const TopoDS_Face& fac = TopoDS::Face(itl.Value());
- /*
- outerW = BRepTools::OuterWire(fac);
- if (IsInside(F,W,outerW)) {
- break;
- }
- */
+
if (IsInside(fac,W)) {
break;
}
}
if (!itl.More()) {
- Standard_ConstructionError::Raise();
+ return Standard_False;
}
BRep_Builder B;
B.Add(newRef,W.Oriented(TopAbs::Reverse(orWire)));
lf.Append(newRef);
lf.Append(newFace);
-
+ return Standard_True;
}
+//=======================================================================
+//function : checkOverlapping
+//purpose :
+//=======================================================================
+
+static Standard_Boolean checkOverlapping(const TopoDS_Edge& theEdge1, const TopoDS_Edge& theEdge2,
+ const TopoDS_Face& theFace)
+{
+
+ BRepAdaptor_Surface anAdS(theFace,Standard_False );
+
+ Standard_Real MaxTol = (BRep_Tool::Tolerance(theEdge1) + BRep_Tool::Tolerance(theEdge2));
+
+ Standard_Real aMaxTol2d = Max(anAdS.UResolution(MaxTol),anAdS.VResolution(MaxTol));
+ Standard_Real aTolAng = M_PI/180.;
+ Geom2dAPI_ProjectPointOnCurve proj;
+ Standard_Real aF1, aL1,aF2, aL2;
+
+ Handle(Geom2d_Curve) aCrv1 = BRep_Tool::CurveOnSurface(theEdge1, theFace, aF1, aL1);
+ Handle(Geom2d_Curve) aCrv2 = BRep_Tool::CurveOnSurface(theEdge2, theFace, aF2, aL2);
+ Standard_Integer j =1, nbP = 4;
+ Standard_Real aStep = ( aL2 - aF2)/nbP;
+ for( ; j < nbP; j++)
+ {
+ Standard_Real par2 = aF2 + aStep * j;
+ gp_Pnt2d aP2d;
+ gp_Vec2d aV2;
+ aCrv2->D1(par2, aP2d, aV2);
+
+ proj.Init(aP2d,aCrv1, aF1, aL1);
+ //check intermediate points
+ if(!proj.NbPoints() || proj.LowerDistance() > aMaxTol2d)
+ return Standard_False;
+ Standard_Real par1 = proj.LowerDistanceParameter();
+ gp_Pnt2d aP2d1;
+ gp_Vec2d aV1;
+ aCrv1->D1(par1, aP2d1, aV1);
+
+ if( !aV1.IsParallel(aV2, aTolAng))
+ return Standard_False;
+ }
+ return Standard_True;
+
+}
//=======================================================================
//function : AddOpenWire
//purpose :
//=======================================================================
-void LocOpe_SplitShape::AddOpenWire(const TopoDS_Wire& W,
+Standard_Boolean LocOpe_SplitShape::AddOpenWire(const TopoDS_Wire& W,
const TopoDS_Face& F)
{
// On cherche la face descendante de F qui continent le wire
BRepTools::Update(F);
- // TopExp::Vertices(W,Vfirst,Vlast);
-
Standard_Real tolf, toll, tol1;
TopoDS_Shape aLocalShape = W.Oriented(TopAbs_FORWARD);
TopExp::Vertices(TopoDS::Wire(aLocalShape),Vfirst,Vlast);
- // TopExp::Vertices(TopoDS::Wire(W.Oriented(TopAbs_FORWARD)),Vfirst,Vlast);
tolf = BRep_Tool::Tolerance(Vfirst);
toll = BRep_Tool::Tolerance(Vlast);
tol1 = Max(tolf, toll);
- TopExp_Explorer exp,exp2;
+ TopExp_Explorer exp,exp2;
TopoDS_Wire wfirst,wlast;
for (; itl.More(); itl.Next()) {
- const TopoDS_Face& fac = TopoDS::Face(itl.Value());
+ TopoDS_Face fac = TopoDS::Face(itl.Value());
if (!IsInside(fac,W)) {
continue;
}
-
+
+ fac.Orientation(TopAbs_FORWARD);
Standard_Boolean ffound = Standard_False;
Standard_Boolean lfound = Standard_False;
for (exp.Init(fac,TopAbs_WIRE); exp.More(); exp.Next()) {
}
}
if (!itl.More()) {
- Standard_ConstructionError::Raise();
+ return Standard_False;
}
TopoDS_Face FaceRef = TopoDS::Face(itl.Value());
if (wfirst.IsSame(wlast)) {
// on cree 2 faces en remplacement de itl.Value()
// Essai JAG
-
+ TopTools_ListOfShape WiresFirst;
for (exp.Init(wfirst,TopAbs_EDGE); exp.More(); exp.Next()) {
if (BRep_Tool::IsClosed(TopoDS::Edge(exp.Current()),FaceRef)) {
myDblE.Add(exp.Current());
}
+ WiresFirst.Append(exp.Current());
}
TopAbs_Orientation orient;
B.MakeWire(newW2);
newW2.Orientation(TopAbs_FORWARD);
- Standard_Integer nbE = 0;
+ Standard_Integer nbE = 0;
for (exp.Init(W.Oriented(TopAbs_FORWARD),TopAbs_EDGE);
exp.More(); exp.Next()) {
nbE++;
const TopoDS_Edge& edg = TopoDS::Edge(exp.Current());
- orient = edg.Orientation();
- B.Add(newW1,edg);
- B.Add(newW2,edg.Oriented(TopAbs::Reverse(orient)));
- }
-
- TopTools_MapOfShape MapE, PossE;
- TopTools_MapIteratorOfMapOfShape itm;
+ orient = edg.Orientation();
+ WiresFirst.Append(edg);
+ WiresFirst.Append(edg.Oriented(TopAbs::Reverse(orient)));
+ myDblE.Add(edg);
+ }
+
+ TopTools_IndexedMapOfShape PossE;
+ TopTools_MapOfOrientedShape MapE;
TopoDS_Vertex vdeb,vfin;
Standard_Integer nbPoss;
TopoDS_Shape aLocalFace = FaceRef.Oriented(wfirst.Orientation());
C2d = BRep_Tool::CurveOnSurface(LastEdge, TopoDS::Face(aLocalFace), f, l);
- // C2d = BRep_Tool::CurveOnSurface
- // (LastEdge,
- // TopoDS::Face(FaceRef.Oriented(wfirst.Orientation())),
- // f,l);
+
if (LastEdge.Orientation() == TopAbs_FORWARD) {
pfirst = C2d->Value(f);
}
}
}
aLocalFace = FaceRef.Oriented(wfirst.Orientation());
- C2d = BRep_Tool::CurveOnSurface(LastEdge, TopoDS::Face(aLocalFace), f, l);
- // C2d = BRep_Tool::CurveOnSurface
- // (LastEdge,
- // TopoDS::Face(FaceRef.Oriented(wfirst.Orientation())),
- // f,l);
- if (LastEdge.Orientation() == TopAbs_FORWARD) {
- C2d->D1(l,plast,dlast);
- // plast = C2d->Value(l);
- }
- else {
- // plast = C2d->Value(f);
- C2d->D1(f,plast,dlast);
- dlast.Reverse();
- }
-
+ GetDirection(LastEdge, TopoDS::Face(aLocalFace),plast , dlast, Standard_False);
+
Standard_Boolean cond;
if(IsPeriodic) {
else {
cond = !(Vfirst.IsSame(Vlast));
}
-
- while (cond) {
+
+ while (cond) {
PossE.Clear();
- // On enchaine par la fin
- for (exp.Init(wfirst.Oriented(TopAbs_FORWARD),TopAbs_EDGE);
- exp.More(); exp.Next()) {
- const TopoDS_Edge& edg = TopoDS::Edge(exp.Current());
- if (MapE.Contains(edg) && !myDblE.Contains(edg)) {
- continue;
- }
+ // On enchaine par la fin
+ TopTools_ListIteratorOfListOfShape lexp(WiresFirst);
+ for (; lexp.More(); lexp.Next()) {
+ const TopoDS_Edge& edg = TopoDS::Edge(lexp.Value());
orient = edg.Orientation();
TopExp::Vertices(edg,vdeb,vfin);
- if (orient == TopAbs_FORWARD && Vlast.IsSame(vdeb)) {
- PossE.Add(edg.Oriented(orient));
- }
- else if (orient == TopAbs_REVERSED && Vlast.IsSame(vfin)) {
- PossE.Add(edg.Oriented(orient));
- }
+
+ if ((orient == TopAbs_FORWARD && Vlast.IsSame(vdeb)) ||
+ (orient == TopAbs_REVERSED && Vlast.IsSame(vfin)))
+ PossE.Add(edg);
}
nbPoss = PossE.Extent();
+ if (nbPoss == 0)
+ {
+ break;
+ }
+
+ TopoDS_Edge aNextEdge;
if (nbPoss == 1) {
- itm.Initialize(PossE);
- TopoDS_Shape aLocalFace = FaceRef.Oriented(wfirst.Orientation());
- C2d = BRep_Tool::CurveOnSurface(TopoDS::Edge(itm.Key()),
- TopoDS::Face(aLocalFace), f, l);
- // C2d = BRep_Tool::CurveOnSurface
- // (TopoDS::Edge(itm.Key()),
- // TopoDS::Face(FaceRef.Oriented(wfirst.Orientation())),
- // f,l);
- if (itm.Key().Orientation() == TopAbs_FORWARD) {
- // plast = C2d->Value(l);
- C2d->D1(l,plast,dlast);
- }
- else {
- // plast = C2d->Value(f);
- C2d->D1(f,plast,dlast);
- dlast.Reverse();
- }
+ aNextEdge = TopoDS::Edge (PossE.FindKey (1));
+ TopoDS_Shape aLocalFaceTemp = FaceRef.Oriented(wfirst.Orientation());
+ GetDirection(aNextEdge, TopoDS::Face(aLocalFaceTemp),plast , dlast, Standard_False);
+
}
else if (nbPoss > 1) {
// Faire choix en U,V...
- TopoDS_Shape aLocalFace = FaceRef.Oriented(wfirst.Orientation());
+ TopoDS_Shape aLocalFaceTemp = FaceRef.Oriented(wfirst.Orientation());
- ChoixUV(LastEdge, TopoDS::Face(aLocalFace), PossE,
- itm, plast, dlast, toll);
- // ChoixUV(LastEdge,
- // TopoDS::Face(FaceRef.Oriented(wfirst.Orientation())),
- // PossE,
- // itm,
- // plast,
- // dlast, toll);
+ if(!ChoixUV(LastEdge, TopoDS::Face(aLocalFaceTemp), PossE,
+ aNextEdge, plast, dlast))
+ return Standard_False;
}
if (nbPoss >= 1) {
- B.Add(newW1,itm.Key());
- if (MapE.Contains(itm.Key())) {
- myDblE.Remove(itm.Key());
- }
- else {
- MapE.Add(itm.Key());
+ if (aNextEdge.IsNull())
+ {
+ // loop is not closed. Split is not possible
+ return Standard_False;
}
- LastEdge = TopoDS::Edge(itm.Key());
+
+ if (MapE.Contains(aNextEdge))
+ break;
+ B.Add(newW1, aNextEdge);
+ MapE.Add(aNextEdge);
+ LastEdge = aNextEdge;
+
if (LastEdge.Orientation() == TopAbs_FORWARD) {
Vlast = TopExp::LastVertex(LastEdge);
}
//MODIFICATION PIERRE SMEYERS : si pas de possibilite, on sort avec erreur
else{
cout<<"erreur Spliter : pas de chainage du wire"<<endl;
- Standard_ConstructionError::Raise();
+ return Standard_False;
}
//fin MODIF.
tol1 = Max(BAS.UResolution(tol1), BAS.VResolution(tol1));
- if(IsPeriodic) {
- cond = !(Vfirst.IsSame(Vlast) && SameUV(pfirst,plast,BAS));
- }
- else {
- cond = !(Vfirst.IsSame(Vlast));
- }
-
}
-
- for (exp.Init(wfirst.Oriented(TopAbs_FORWARD),TopAbs_EDGE);
- exp.More(); exp.Next()) {
- const TopoDS_Edge& edg = TopoDS::Edge(exp.Current());
+
+ Standard_Integer nbAddBound =0;
+ TopTools_ListIteratorOfListOfShape lexp(WiresFirst);
+ TopoDS_Shape anE1, anE2;
+ for (; lexp.More(); lexp.Next()) {
+ const TopoDS_Edge& edg = TopoDS::Edge(lexp.Value());
if (!MapE.Contains(edg)) {
B.Add(newW2,edg);
MapE.Add(edg);
+ nbAddBound++;
+ if(anE1.IsNull())
+ anE1 = edg;
+ else
+ anE2 = edg;
+
}
- else if (myDblE.Contains(edg)) {
- for (itm.Initialize(MapE); itm.More(); itm.Next()) {
- const TopoDS_Edge& edg2 = TopoDS::Edge(itm.Key());
- if (edg.IsSame(edg2) && edg.Orientation() != edg2.Orientation()) {
- B.Add(newW2,edg);
- myDblE.Remove(edg);
- }
- }
- }
+ }
+ //check overlapping edges for second face
+ if(nbAddBound <2)
+ return Standard_False;
+ if(nbAddBound ==2 && !anE1.IsNull() && !anE2.IsNull())
+ {
+ if(checkOverlapping(TopoDS::Edge(anE1), TopoDS::Edge(anE2),FaceRef ))
+ return Standard_False;
+
}
+
+ nbAddBound =0;
+ TopoDS_Shape anE11, anE12;
+ TopoDS_Iterator anItE(newW1, Standard_False);
+ for( ; anItE.More(); anItE.Next())
+ {
+ if( anItE.Value().ShapeType() != TopAbs_EDGE)
+ continue;
+ nbAddBound++;
+ if(anE11.IsNull())
+ anE11 = anItE.Value();
+ else
+ anE12 = anItE.Value();
+
+ }
+ //check overlapping edges for first face
+ if(nbAddBound <2)
+ return Standard_False;
+ if(nbAddBound ==2 && !anE11.IsNull() && !anE12.IsNull())
+ {
+ if(checkOverlapping(TopoDS::Edge(anE11), TopoDS::Edge(anE12), FaceRef))
+ return Standard_False;
+
+ }
+
TopoDS_Face newF1,newF2;
aLocalFace = FaceRef.EmptyCopied();
newF1 = TopoDS::Face(aLocalFace);
newF1.Orientation(TopAbs_FORWARD);
aLocalFace = FaceRef.EmptyCopied();
newF2 = TopoDS::Face(aLocalFace);
- // newF2 = TopoDS::Face(FaceRef.EmptyCopied());
newF2.Orientation(TopAbs_FORWARD);
// modifs JAG 97.05.28
-#ifdef DEB
- TopAbs_Orientation orfila;
-#else
- TopAbs_Orientation orfila=TopAbs_FORWARD;
-#endif
- for (exp.Init(FaceRef.Oriented(TopAbs_FORWARD),TopAbs_WIRE);
- exp.More(); exp.Next()) {
- const TopoDS_Wire& wir = TopoDS::Wire(exp.Current());
- if (wir.IsSame(wfirst)) {
- orfila = exp.Current().Orientation();
- break;
- }
- }
-
- B.Add(newF1,newW1.Oriented(orfila));
- B.Add(newF2,newW2.Oriented(orfila));
- // Standard_Boolean exch = Standard_False;
- BRepTopAdaptor_FClass2d classif(newF1,Precision::PConfusion());
- if (classif.PerformInfinitePoint() == TopAbs_OUT) {
- BRepTopAdaptor_FClass2d classi(newF2,Precision::PConfusion());
- if (classi.PerformInfinitePoint() == TopAbs_IN) {
- TopoDS_Face tempF = newF2;
- newF2 = newF1;
- newF1 = tempF;
- }
- }
-
- for (exp.ReInit(); exp.More(); exp.Next()) {
+
+ B.Add(newF1,newW1);
+ B.Add(newF2,newW2);
+ for (exp.Init(FaceRef.Oriented(TopAbs_FORWARD),TopAbs_WIRE); exp.More(); exp.Next()) {
const TopoDS_Wire& wir = TopoDS::Wire(exp.Current());
if (!wir.IsSame(wfirst)) {
- // if (IsInside(F,wir,newW1) || IsInside(F,newW1,wir)) {
if (IsInside(newF1, wir)) {
B.Add(newF1,wir);
}
}
}
+ return Standard_True;
}
Rebuild(myShape);
myDone = Standard_True;
}
-#ifdef DEB
+#ifdef OCCT_DEBUG
if (!myDblE.IsEmpty()) {
cout << "Le shape comporte des faces invalides" << endl;
}
}
}
+static void updateToleraces(const TopoDS_Face& theFace, const TopTools_DataMapOfShapeListOfShape& theMap)
+{
+ TopExp_Explorer aExpE(theFace, TopAbs_EDGE);
+ for (; aExpE.More(); aExpE.Next())
+ {
+ if (!theMap.IsBound(aExpE.Current()))
+ continue;
+ const TopTools_ListOfShape& lEdges = theMap(aExpE.Current());
+ if (lEdges.Extent() <= 1)
+ continue;
+
+ TopTools_ListIteratorOfListOfShape itrE(lEdges);
+ ShapeAnalysis_Edge aSae;
+
+ for (; itrE.More(); itrE.Next())
+ {
+ TopoDS_Edge aCurE = TopoDS::Edge(itrE.Value());
+ Standard_Real amaxdev = 0.;
+ if (aSae.CheckSameParameter(aCurE, theFace, amaxdev))
+ {
+ BRep_Builder aB;
+ aB.UpdateEdge(aCurE, amaxdev);
+ }
+ }
+ }
+}
//=======================================================================
//function : Rebuild
//purpose :
Standard_Boolean LocOpe_SplitShape::Rebuild(const TopoDS_Shape& S)
{
-
+ if (S.ShapeType() == TopAbs_FACE)
+ updateToleraces(TopoDS::Face(S), myMap);
TopTools_ListIteratorOfListOfShape itr(myMap(S));
if (itr.More()) {
if (itr.Value().IsSame(S)) {
B.Add(result,itr.Value().Oriented(orient));
}
}
+ // Assign "Closed" flag for Wires and Shells only
+ if (result.ShapeType() == TopAbs_WIRE || result.ShapeType() == TopAbs_SHELL)
+ result.Closed (BRep_Tool::IsClosed(result));
myMap(S).Append(result);
}
else {
Standard_Real f,l;
Handle(Geom2d_Curve) C2d = BRep_Tool::CurveOnSurface(edg,F,f,l);
if(C2d.IsNull()) {
-#ifdef DEB
+#ifdef OCCT_DEBUG
cout << "Edge is not on surface" <<endl;
#endif
return Standard_False;
// BRepClass_FaceClassifier classif(F,pt2d,Precision::PConfusion());
// return (classif.State() != TopAbs_OUT);
BRepTopAdaptor_FClass2d classif(F,Precision::PConfusion());
- Standard_Boolean stat = classif.Perform(pt2d);
+ TopAbs_State stat = classif.Perform(pt2d);
// return (classif.Perform(pt2d) != TopAbs_OUT);
if(stat == TopAbs_OUT) return Standard_False;
return Standard_True;
}
+//=======================================================================
+//function : GetDirection
+//purpose :
+//=======================================================================
+static void GetDirection(const TopoDS_Edge& theEdge,
+ const TopoDS_Face& theFace,
+ gp_Pnt2d& thePnt,
+ gp_Vec2d& theDir,
+ Standard_Boolean isFirstEnd)
+{
+ Standard_Real aFirst, aLast;
+ Handle(Geom2d_Curve) aC2d = BRep_Tool::CurveOnSurface (theEdge, theFace, aFirst, aLast);
+
+ TopAbs_Orientation anOr = theEdge.Orientation();
+ TopoDS_Vertex aVtx;
+ Standard_Boolean takeFirst = ((anOr == TopAbs_FORWARD && isFirstEnd) ||
+ (anOr == TopAbs_REVERSED && !isFirstEnd));
+
+ Standard_Real dpar = (aLast - aFirst)*0.01;
+ gp_Pnt2d aP2d;
+ if (takeFirst)
+ {
+ aC2d->D0 (aFirst, thePnt);
+ gp_Pnt2d aNextPnt = aC2d->Value(aFirst + dpar);
+ theDir = gp_Vec2d(thePnt, aNextPnt);
+ }
+
+ else
+ {
+ aC2d->D0 (aLast, thePnt);
+ gp_Pnt2d aPrevPnt = aC2d->Value(aLast - dpar);
+ theDir = gp_Vec2d( aPrevPnt, thePnt );
+ }
+ if(anOr == TopAbs_REVERSED)
+ theDir.Reverse();
+}
//=======================================================================
//function : ChoixUV
//purpose :
//=======================================================================
-static void ChoixUV(const TopoDS_Edge& Last,
+Standard_Boolean ChoixUV(const TopoDS_Edge& Last,
const TopoDS_Face& F,
- const TopTools_MapOfShape& Poss,
- TopTools_MapIteratorOfMapOfShape& It,
+ const TopTools_IndexedMapOfShape& Poss,
+ TopoDS_Edge& theResEdge,
gp_Pnt2d& plst,
- gp_Vec2d& dlst,
- const Standard_Real toll)
+ gp_Vec2d& dlst)
{
-
- Standard_Real f,l;
- // gp_Pnt2d p2d,psav;
gp_Pnt2d p2d;
gp_Vec2d v2d;
gp_Pnt aPCur, aPlst;
BRepAdaptor_Surface surf(F,Standard_False); // no restriction
- // Standard_Real tol = Precision::PConfusion() //BRep_Tool::Tolerance(Last));
surf.D0 (plst.X(), plst.Y(), aPlst);
- Standard_Real tol;
-
- TopoDS_Vertex vtx;
-
gp_Dir2d ref2d(dlst);
Handle(Geom2d_Curve) C2d;
+
Standard_Integer index = 0, imin=0;
- Standard_Real angmax = -M_PI, dist, ang;
-
-
- for (It.Initialize(Poss); It.More(); It.Next()) {
- index++;
- C2d = BRep_Tool::CurveOnSurface(TopoDS::Edge(It.Key()),F,f,l);
- if (It.Key().Orientation() == TopAbs_FORWARD) {
- // p2d = C2d->Value(f);
- C2d->D1(f,p2d,v2d);
- vtx = TopExp::FirstVertex(TopoDS::Edge(It.Key()));
- }
- else {
- // p2d = C2d->Value(l);
- C2d->D1(l,p2d,v2d);
- v2d.Reverse();
- vtx = TopExp::LastVertex(TopoDS::Edge(It.Key()));
- }
+ Standard_Real angmax = -M_PI, ang;
+
+ for (index = 1; index <= Poss.Extent(); index++) {
+ TopoDS_Edge anEdge = TopoDS::Edge (Poss.FindKey (index));
+
+ GetDirection(anEdge, F, p2d, v2d, Standard_True);
surf.D0 (p2d.X(), p2d.Y(), aPCur);
- tol = BRep_Tool::Tolerance(vtx);
- tol = Max(toll, tol); tol *= tol;
-
- dist = aPCur.SquareDistance(aPlst);
-
- if (!Last.IsSame(It.Key())) {
+ if (!Last.IsSame(anEdge)) {
ang = ref2d.Angle(gp_Dir2d(v2d));
}
else {
ang = -M_PI;
}
- //if ((dist < dmin - tol) ||
- //(dist <= dmin+tol && ang > angmax)) {
- if ((dist < tol) && (ang > angmax)) {
+ if ( (ang > angmax)) {
imin = index;
- // dmin = dist;
angmax = ang;
}
}
- for (index = 1, It.Initialize(Poss); It.More(); It.Next()) {
- if (index == imin) {
- C2d = BRep_Tool::CurveOnSurface(TopoDS::Edge(It.Key()),F,f,l);
- if (It.Key().Orientation() == TopAbs_FORWARD) {
- // plst = C2d->Value(l);
- C2d->D1(l,plst,dlst);
+ if (imin)
+ {
+ theResEdge = TopoDS::Edge (Poss.FindKey (imin));
+ GetDirection(theResEdge, F, plst, dlst, Standard_False);
+ }
+
+ return imin != 0;
+}
+
+//=======================================================================
+//function : ChooseDirection
+//purpose :
+//=======================================================================
+
+static TopoDS_Shape ChooseDirection(const TopoDS_Shape& RefDir,
+ const TopoDS_Vertex& RefVertex,
+ const TopoDS_Face& theFace,
+ const TopTools_ListOfShape& Ldirs)
+{
+ TopExp_Explorer Explo(RefDir, TopAbs_EDGE);
+ TopoDS_Edge RefEdge;
+ TopoDS_Vertex V1, V2;
+ TopAbs_Orientation anOr = TopAbs_FORWARD;
+ for (; Explo.More(); Explo.Next())
+ {
+ RefEdge = TopoDS::Edge(Explo.Current());
+ TopExp::Vertices(RefEdge, V1, V2);
+ if (V1.IsSame(RefVertex))
+ {
+ anOr = TopAbs_REVERSED;
+ break;
+ }
+ else if (V2.IsSame(RefVertex))
+ {
+ anOr = TopAbs_FORWARD;
+ break;
+ }
+ }
+
+ Standard_Real RefFirst, RefLast;
+ Handle(Geom2d_Curve) RefCurve = BRep_Tool::CurveOnSurface(RefEdge, theFace, RefFirst, RefLast);
+ gp_Pnt2d RefPnt;
+ gp_Vec2d RefVec;
+
+ //Standard_Real RefPar = (RefEdge.Orientation() == TopAbs_FORWARD)? RefLast : RefFirst;
+ Standard_Real RefPar = (anOr == TopAbs_FORWARD)? RefLast : RefFirst;
+ RefCurve->D1(RefPar, RefPnt, RefVec);
+ if (anOr == TopAbs_FORWARD)
+ RefVec.Reverse();
+
+ Handle(Geom2d_Curve) aCurve;
+ Standard_Real aFirst, aLast, aPar;
+ gp_Vec2d aVec;
+ Standard_Real MinAngle = RealLast(), anAngle;
+ TopoDS_Shape TargetDir;
+ TopTools_ListIteratorOfListOfShape itl(Ldirs);
+ for (; itl.More(); itl.Next())
+ {
+ const TopoDS_Shape& aShape = itl.Value();
+ TopoDS_Edge anEdge;
+ for (Explo.Init(aShape, TopAbs_EDGE); Explo.More(); Explo.Next())
+ {
+ anEdge = TopoDS::Edge(Explo.Current());
+ TopExp::Vertices(anEdge, V1, V2);
+ if (V1.IsSame(RefVertex))
+ {
+ anOr = TopAbs_FORWARD;
+ break;
}
- else {
- // plst = C2d->Value(f);
- C2d->D1(f,plst,dlst);
- dlst.Reverse();
+ else if (V2.IsSame(RefVertex))
+ {
+ anOr = TopAbs_REVERSED;
+ break;
}
- break;
}
- index++;
+ aCurve = BRep_Tool::CurveOnSurface(anEdge, theFace, aFirst, aLast);
+ aPar = (anOr == TopAbs_FORWARD)? aFirst : aLast;
+ aCurve->D1(aPar, RefPnt, aVec);
+ if (anOr == TopAbs_REVERSED)
+ aVec.Reverse();
+ anAngle = aVec.Angle(RefVec);
+ if (anAngle < 0.)
+ anAngle += 2.*M_PI;
+
+ if (anAngle < MinAngle)
+ {
+ MinAngle = anAngle;
+ TargetDir = aShape;
+ }
}
+ return TargetDir;
}