mirror of
https://git.dev.opencascade.org/repos/occt.git
synced 2025-04-05 18:16:23 +03:00
0022946: BRepFeat_SplitShape crashes on splitting a face by two edges
null check for pcurve added to avoid exceptions Correction to avoid the regression: check after PutPCurve(edg,fac)
This commit is contained in:
parent
a0b4c5eac5
commit
ed60a55e7f
@ -43,6 +43,7 @@ uses Spliter from LocOpe,
|
||||
Face from TopoDS,
|
||||
Wire from TopoDS,
|
||||
Edge from TopoDS,
|
||||
Compound from TopoDS,
|
||||
Vertex from TopoDS,
|
||||
ListOfShape from TopTools,
|
||||
ShapeModification from BRepBuilderAPI
|
||||
@ -94,6 +95,20 @@ is
|
||||
|
||||
is static;
|
||||
|
||||
Add(me: in out; Comp: Compound from TopoDS;
|
||||
F: Face from TopoDS)
|
||||
---Purpose: Adds the compound <Comp> on the face <F>. The
|
||||
-- compound <Comp> must consist of edges lying on the
|
||||
-- face <F>. If edges are geometrically connected,
|
||||
-- they must be connected topologically, i.e. they
|
||||
-- must share common vertices.
|
||||
--
|
||||
-- Raises NoSuchObject if <F> does not belong to the original shape.
|
||||
---C++: inline
|
||||
raises NoSuchObject from Standard,
|
||||
ConstructionError from Standard
|
||||
|
||||
is static;
|
||||
|
||||
|
||||
Add(me: in out; E : Edge from TopoDS;
|
||||
|
@ -84,6 +84,17 @@ inline void BRepFeat_SplitShape::Add(const TopoDS_Edge& E,
|
||||
myWOnShape->Bind(E,F);
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : Add
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
inline void BRepFeat_SplitShape::Add(const TopoDS_Compound& Comp,
|
||||
const TopoDS_Face& F)
|
||||
{
|
||||
myWOnShape->Bind(Comp,F);
|
||||
}
|
||||
|
||||
|
||||
//=======================================================================
|
||||
//function : Add
|
||||
|
@ -745,12 +745,12 @@ static Standard_Integer SPLS(Draw_Interpretor& ,
|
||||
return 1; // on n`a rien recupere
|
||||
}
|
||||
TopAbs_ShapeEnum wtyp = W.ShapeType();
|
||||
if (wtyp != TopAbs_WIRE && wtyp != TopAbs_EDGE && pick) {
|
||||
if (wtyp != TopAbs_WIRE && wtyp != TopAbs_EDGE && wtyp != TopAbs_COMPOUND && pick) {
|
||||
Standard_Real u,v;
|
||||
DBRep_DrawableShape::LastPick(W,u,v);
|
||||
wtyp = W.ShapeType();
|
||||
}
|
||||
if (wtyp != TopAbs_WIRE && wtyp != TopAbs_EDGE) {
|
||||
if (wtyp != TopAbs_WIRE && wtyp != TopAbs_EDGE && wtyp != TopAbs_COMPOUND) {
|
||||
EF = DBRep::Get(a[i]);
|
||||
break;
|
||||
}
|
||||
@ -761,9 +761,12 @@ static Standard_Integer SPLS(Draw_Interpretor& ,
|
||||
if (wtyp == TopAbs_WIRE) {
|
||||
Spls.Add(TopoDS::Wire(W),TopoDS::Face(EF));
|
||||
}
|
||||
else {
|
||||
else if (wtyp == TopAbs_EDGE) {
|
||||
Spls.Add(TopoDS::Edge(W),TopoDS::Face(EF));
|
||||
}
|
||||
else {
|
||||
Spls.Add(TopoDS::Compound(W),TopoDS::Face(EF));
|
||||
}
|
||||
}
|
||||
i++;
|
||||
}
|
||||
@ -2255,7 +2258,7 @@ void BRepTest::FeatureCommands (Draw_Interpretor& theCommands)
|
||||
|
||||
|
||||
theCommands.Add("splitshape",
|
||||
"splitshape result shape face wire/edge [wire/edge ...][face wire/edge [wire/edge...] ...] [@ edgeonshape edgeonwire [edgeonshape edgeonwire...]]",
|
||||
"splitshape result shape face wire/edge/compound [wire/edge/compound ...][face wire/edge/compound [wire/edge/compound...] ...] [@ edgeonshape edgeonwire [edgeonshape edgeonwire...]]",
|
||||
__FILE__,SPLS,g);
|
||||
|
||||
|
||||
|
@ -27,7 +27,8 @@ deferred class ProjectedWires from LocOpe inherits TShared from MMgt
|
||||
uses Face from TopoDS,
|
||||
Wire from TopoDS,
|
||||
Edge from TopoDS,
|
||||
Vertex from TopoDS
|
||||
Vertex from TopoDS,
|
||||
Shape from TopoDS
|
||||
|
||||
is
|
||||
|
||||
@ -84,5 +85,9 @@ is
|
||||
returns Boolean from Standard
|
||||
is deferred;
|
||||
|
||||
IsFaceWithSection(me; aFace : Shape from TopoDS)
|
||||
---Purpose: tells is the face to be split by section or not
|
||||
returns Boolean from Standard
|
||||
is deferred;
|
||||
|
||||
end ProjectedWires;
|
||||
|
@ -92,6 +92,14 @@ is
|
||||
-- wire(s) of a sub-face of <F>
|
||||
is static;
|
||||
|
||||
Add(me: in out; Lwires: ListOfShape from TopTools;
|
||||
F: Face from TopoDS)
|
||||
---Purpose: Adds the list of wires <Lwires> on the face <F>.
|
||||
raises NoSuchObject from Standard,
|
||||
-- if <F> does not belong to the original shape.
|
||||
ConstructionError from Standard
|
||||
is static;
|
||||
|
||||
|
||||
Shape(me)
|
||||
---Purpose: Returns the "original" shape.
|
||||
|
@ -27,14 +27,19 @@
|
||||
#include <TopTools_MapOfShape.hxx>
|
||||
#include <TopTools_DataMapOfShapeListOfShape.hxx>
|
||||
#include <TopTools_DataMapIteratorOfDataMapOfShapeListOfShape.hxx>
|
||||
#include <TopTools_DataMapOfShapeInteger.hxx>
|
||||
#include <TopTools_DataMapOfShapeShape.hxx>
|
||||
#include <TopTools_DataMapIteratorOfDataMapOfShapeShape.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 <BRepLib_MakeWire.hxx>
|
||||
#include <BRep_Tool.hxx>
|
||||
#include <BRepTools.hxx>
|
||||
#include <BRepTools_WireExplorer.hxx>
|
||||
#include <BRep_Builder.hxx>
|
||||
|
||||
#include <BRepClass_FaceExplorer.hxx>
|
||||
@ -67,6 +72,11 @@ static void ChoixUV(const TopoDS_Edge&,
|
||||
gp_Vec2d&,
|
||||
const Standard_Real tol);
|
||||
|
||||
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)
|
||||
{
|
||||
@ -220,6 +230,303 @@ void LocOpe_SplitShape::Add(const TopoDS_Vertex& V,
|
||||
}
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : Add
|
||||
//purpose : adds the list of wires on the face <F>
|
||||
//=======================================================================
|
||||
|
||||
void LocOpe_SplitShape::Add(const TopTools_ListOfShape& Lwires,
|
||||
const TopoDS_Face& F)
|
||||
{
|
||||
|
||||
if (myDone) {
|
||||
Standard_ConstructionError::Raise();
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
for (; itl.More(); itl.Next())
|
||||
{
|
||||
const TopoDS_Face& fac = TopoDS::Face(itl.Value());
|
||||
Standard_Boolean AllWiresInside = Standard_True;
|
||||
TopTools_ListIteratorOfListOfShape itwires(Lwires);
|
||||
for (; itwires.More(); itwires.Next())
|
||||
{
|
||||
const TopoDS_Wire& aWire = TopoDS::Wire(itwires.Value());
|
||||
if (!IsInside(fac, aWire))
|
||||
{
|
||||
AllWiresInside = Standard_False;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (AllWiresInside)
|
||||
break;
|
||||
}
|
||||
if (!itl.More()) {
|
||||
Standard_ConstructionError::Raise();
|
||||
}
|
||||
|
||||
TopoDS_Face FaceRef = TopoDS::Face(itl.Value());
|
||||
FaceRef.Orientation(TopAbs_FORWARD);
|
||||
lf.Remove(itl);
|
||||
|
||||
TopTools_ListOfShape NewWires;
|
||||
|
||||
TopTools_DataMapOfShapeInteger SectionsTimes;
|
||||
for (itl.Initialize(Lwires); 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(Lwires); 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(Lwires); 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(Lwires); 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//=======================================================================
|
||||
@ -1047,7 +1354,7 @@ static Standard_Boolean IsInside(const TopoDS_Face& F,
|
||||
// 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;
|
||||
|
||||
@ -1169,3 +1476,88 @@ static void ChoixUV(const TopoDS_Edge& Last,
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//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;
|
||||
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 if (V2.IsSame(RefVertex))
|
||||
{
|
||||
anOr = TopAbs_REVERSED;
|
||||
break;
|
||||
}
|
||||
}
|
||||
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;
|
||||
}
|
||||
|
@ -148,6 +148,7 @@ void LocOpe_Spliter::Perform(const Handle(LocOpe_ProjectedWires)& PW)
|
||||
TopoDS_Edge Ed;
|
||||
Standard_Real prm;
|
||||
|
||||
TopTools_MapOfShape theFacesWithSection;
|
||||
for (PW->InitEdgeIterator(); PW->MoreEdge(); PW->NextEdge()) {
|
||||
const TopoDS_Edge& edg = PW->Edge();
|
||||
for (exp.Init(edg,TopAbs_VERTEX); exp.More(); exp.Next()) {
|
||||
@ -170,7 +171,10 @@ void LocOpe_Spliter::Perform(const Handle(LocOpe_ProjectedWires)& PW)
|
||||
else {
|
||||
TopoDS_Face fac = PW->OnFace();
|
||||
if(!myMap.IsBound(fac)) continue;
|
||||
Standard_Boolean IsFaceWithSec = PW->IsFaceWithSection(fac);
|
||||
fac = TopoDS::Face(myMap(fac).First());
|
||||
if (IsFaceWithSec)
|
||||
theFacesWithSection.Add(fac);
|
||||
if (!mapFE.Contains(fac)) {
|
||||
TopTools_ListOfShape thelist;
|
||||
mapFE.Add(fac, thelist);
|
||||
@ -189,10 +193,12 @@ void LocOpe_Spliter::Perform(const Handle(LocOpe_ProjectedWires)& PW)
|
||||
// RebuildWires(ledges);
|
||||
RebuildWires(ledges, PW);
|
||||
// Modified by skv - Mon May 31 12:32:54 2004 OCC5865 End
|
||||
for (itl.Initialize(ledges); itl.More(); itl.Next()) {
|
||||
if (theFacesWithSection.Contains(fac))
|
||||
theCFace.Add(ledges, fac);
|
||||
else
|
||||
for (itl.Initialize(ledges); itl.More(); itl.Next())
|
||||
theCFace.Add(TopoDS::Wire(itl.Value()),fac);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Mise a jour des descendants
|
||||
|
@ -28,11 +28,13 @@ class WiresOnShape from LocOpe inherits ProjectedWires from LocOpe
|
||||
uses Shape from TopoDS,
|
||||
Face from TopoDS,
|
||||
Wire from TopoDS,
|
||||
Compound from TopoDS,
|
||||
Edge from TopoDS,
|
||||
Vertex from TopoDS,
|
||||
DataMapOfShapeShape from TopTools,
|
||||
-- DataMapIteratorOfDataMapOfShapeShape from TopTools
|
||||
IndexedDataMapOfShapeShape from TopTools
|
||||
IndexedDataMapOfShapeShape from TopTools,
|
||||
MapOfShape from TopTools
|
||||
|
||||
|
||||
is
|
||||
@ -52,6 +54,10 @@ is
|
||||
|
||||
is static;
|
||||
|
||||
Bind(me: mutable; Comp: Compound from TopoDS;
|
||||
F: Face from TopoDS)
|
||||
|
||||
is static;
|
||||
|
||||
Bind(me: mutable; E: Edge from TopoDS;
|
||||
F: Face from TopoDS)
|
||||
@ -130,11 +136,18 @@ is
|
||||
returns Boolean from Standard
|
||||
;
|
||||
|
||||
IsFaceWithSection(me; aFace : Shape from TopoDS)
|
||||
---Purpose: tells is the face to be split by section or not
|
||||
---C++: inline
|
||||
returns Boolean from Standard
|
||||
;
|
||||
|
||||
|
||||
fields
|
||||
|
||||
myShape : Shape from TopoDS;
|
||||
myMapEF : IndexedDataMapOfShapeShape from TopTools;
|
||||
myFacesWithSection : MapOfShape from TopTools;
|
||||
myMap : DataMapOfShapeShape from TopTools;
|
||||
myDone : Boolean from Standard;
|
||||
myIndex : Integer from Standard;
|
||||
|
@ -53,6 +53,14 @@
|
||||
#include <TopoDS_Compound.hxx>
|
||||
#include <BRepLib.hxx>
|
||||
|
||||
#include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
|
||||
#include <BRepAdaptor_Curve2d.hxx>
|
||||
#include <Bnd_Box2d.hxx>
|
||||
#include <BndLib_Add2dCurve.hxx>
|
||||
#include <Extrema_ExtCC.hxx>
|
||||
#include <BRepLib_MakeVertex.hxx>
|
||||
|
||||
|
||||
static Standard_Boolean Project(const TopoDS_Vertex&,
|
||||
const TopoDS_Face&,
|
||||
TopoDS_Edge&,
|
||||
@ -70,6 +78,11 @@ static void PutPCurves(const TopoDS_Edge&,
|
||||
const TopoDS_Edge&,
|
||||
const TopoDS_Shape&);
|
||||
|
||||
static void FindInternalIntersections(const TopoDS_Edge&,
|
||||
const TopoDS_Face&,
|
||||
TopTools_IndexedDataMapOfShapeListOfShape&,
|
||||
TopTools_DataMapOfShapeShape&,
|
||||
TopTools_MapOfShape&);
|
||||
|
||||
//=======================================================================
|
||||
//function : LocOpe_WiresOnShape
|
||||
@ -105,11 +118,24 @@ void LocOpe_WiresOnShape::Init(const TopoDS_Shape& S)
|
||||
void LocOpe_WiresOnShape::Bind(const TopoDS_Wire& W,
|
||||
const TopoDS_Face& F)
|
||||
{
|
||||
for (TopExp_Explorer exp(W,TopAbs_EDGE); exp.More(); exp.Next()) {
|
||||
for (TopExp_Explorer exp(W, TopAbs_EDGE); exp.More(); exp.Next()) {
|
||||
Bind(TopoDS::Edge(exp.Current()),F);
|
||||
}
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : Bind
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
void LocOpe_WiresOnShape::Bind(const TopoDS_Compound& Comp,
|
||||
const TopoDS_Face& F)
|
||||
{
|
||||
for (TopExp_Explorer exp(Comp, TopAbs_EDGE); exp.More(); exp.Next()) {
|
||||
Bind(TopoDS::Edge(exp.Current()),F);
|
||||
}
|
||||
myFacesWithSection.Add(F);
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : Bind
|
||||
@ -201,6 +227,38 @@ void LocOpe_WiresOnShape::BindAll()
|
||||
myMap.Bind(ite.Key(),ite.Value());
|
||||
}
|
||||
|
||||
TopTools_IndexedDataMapOfShapeListOfShape Splits;
|
||||
Standard_Integer Ind;
|
||||
for (Ind = 1; Ind <= myMapEF.Extent(); Ind++)
|
||||
{
|
||||
const TopoDS_Edge& edg = TopoDS::Edge(myMapEF.FindKey(Ind));
|
||||
const TopoDS_Face& fac = TopoDS::Face(myMapEF(Ind));
|
||||
|
||||
PutPCurve(edg,fac);
|
||||
Standard_Real pf, pl;
|
||||
Handle(Geom2d_Curve) aPCurve = BRep_Tool::CurveOnSurface(edg, fac, pf, pl);
|
||||
if (aPCurve.IsNull())
|
||||
continue;
|
||||
|
||||
FindInternalIntersections(edg, fac, Splits, myMap, theMap);
|
||||
}
|
||||
|
||||
for (Ind = 1; Ind <= Splits.Extent(); Ind++)
|
||||
{
|
||||
TopoDS_Shape anEdge = Splits.FindKey(Ind);
|
||||
TopoDS_Shape aFace = myMapEF.FindFromKey(anEdge);
|
||||
//Remove "anEdge" from "myMapEF"
|
||||
TopoDS_Shape LastEdge = myMapEF.FindKey(myMapEF.Extent());
|
||||
TopoDS_Shape LastFace = myMapEF(myMapEF.Extent());
|
||||
myMapEF.RemoveLast();
|
||||
if (myMapEF.FindIndex(anEdge) != 0)
|
||||
myMapEF.Substitute(myMapEF.FindIndex(anEdge), LastEdge, LastFace);
|
||||
////////////////////////////////
|
||||
TopTools_ListIteratorOfListOfShape itl(Splits(Ind));
|
||||
for (; itl.More(); itl.Next())
|
||||
myMapEF.Add(itl.Value(), aFace);
|
||||
}
|
||||
|
||||
// Il faut s`occuper maintenant des vertex "de changement de face",
|
||||
// et des vertex "libres"
|
||||
// TopTools_DataMapIteratorOfDataMapOfShapeShape ite2;
|
||||
@ -208,12 +266,12 @@ void LocOpe_WiresOnShape::BindAll()
|
||||
// for (ite.Initialize(myMapEF); ite.More(); ite.Next()) {
|
||||
// const TopoDS_Edge& edg = TopoDS::Edge(ite.Key());
|
||||
// const TopoDS_Face& fac = TopoDS::Face(ite.Value());
|
||||
for (Standard_Integer Ind = 1; Ind <= myMapEF.Extent(); Ind++) {
|
||||
for (Ind = 1; Ind <= myMapEF.Extent(); Ind++) {
|
||||
const TopoDS_Edge& edg = TopoDS::Edge(myMapEF.FindKey(Ind));
|
||||
const TopoDS_Face& fac = TopoDS::Face(myMapEF(Ind));
|
||||
// JAG 02.02.96 : On verifie les pcurves...
|
||||
|
||||
PutPCurve(edg,fac);
|
||||
//PutPCurve(edg,fac);
|
||||
|
||||
for (exp.Init(edg,TopAbs_VERTEX); exp.More(); exp.Next()) {
|
||||
const TopoDS_Vertex& vtx = TopoDS::Vertex(exp.Current());
|
||||
@ -1006,3 +1064,173 @@ void PutPCurves(const TopoDS_Edge& Efrom,
|
||||
}
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : FindInternalIntersections
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
void FindInternalIntersections(const TopoDS_Edge& theEdge,
|
||||
const TopoDS_Face& theFace,
|
||||
TopTools_IndexedDataMapOfShapeListOfShape& Splits,
|
||||
TopTools_DataMapOfShapeShape& GlobalMap,
|
||||
TopTools_MapOfShape& theMap)
|
||||
{
|
||||
Standard_Real TolExt = Precision::PConfusion();
|
||||
Standard_Integer i, j, aNbExt;
|
||||
|
||||
TColStd_SequenceOfReal SplitPars;
|
||||
|
||||
TopoDS_Vertex theVertices [2];
|
||||
TopExp::Vertices(theEdge, theVertices[0], theVertices[1]);
|
||||
if (theEdge.Orientation() == TopAbs_REVERSED)
|
||||
{
|
||||
theVertices[0].Reverse();
|
||||
theVertices[1].Reverse();
|
||||
}
|
||||
gp_Pnt thePnt [2];
|
||||
thePnt[0] = BRep_Tool::Pnt(theVertices[0]);
|
||||
thePnt[1] = BRep_Tool::Pnt(theVertices[1]);
|
||||
|
||||
BRepAdaptor_Curve2d thePCurve(theEdge, theFace);
|
||||
Bnd_Box2d theBox;
|
||||
BndLib_Add2dCurve::Add(thePCurve, BRep_Tool::Tolerance(theEdge), theBox);
|
||||
|
||||
Standard_Real thePar [2];
|
||||
Standard_Real /*theFpar, theLpar,*/ aFpar, aLpar;
|
||||
const Handle(Geom_Curve)& theCurve = BRep_Tool::Curve(theEdge, thePar[0], thePar[1]);
|
||||
GeomAdaptor_Curve theGAcurve(theCurve, thePar[0], thePar[1]);
|
||||
|
||||
TopExp_Explorer Explo(theFace, TopAbs_EDGE);
|
||||
for (; Explo.More(); Explo.Next())
|
||||
{
|
||||
const TopoDS_Edge& anEdge = TopoDS::Edge(Explo.Current());
|
||||
BRepAdaptor_Curve2d aPCurve(anEdge, theFace);
|
||||
Bnd_Box2d aBox;
|
||||
BndLib_Add2dCurve::Add(aPCurve, BRep_Tool::Tolerance(anEdge), aBox);
|
||||
if (theBox.IsOut(aBox))
|
||||
continue;
|
||||
|
||||
const Handle(Geom_Curve)& aCurve = BRep_Tool::Curve(anEdge, aFpar, aLpar);
|
||||
GeomAdaptor_Curve aGAcurve(aCurve, aFpar, aLpar);
|
||||
Extrema_ExtCC anExtrema(theGAcurve, aGAcurve, TolExt, TolExt);
|
||||
|
||||
if (!anExtrema.IsDone())
|
||||
continue;
|
||||
if (anExtrema.IsParallel())
|
||||
continue;
|
||||
|
||||
aNbExt = anExtrema.NbExt();
|
||||
Standard_Real MaxTol = Max(BRep_Tool::Tolerance(theEdge), BRep_Tool::Tolerance(anEdge));
|
||||
for (i = 1; i <= aNbExt; i++)
|
||||
{
|
||||
Standard_Real aDist = Sqrt(anExtrema.SquareDistance(i));
|
||||
if (aDist > MaxTol)
|
||||
continue;
|
||||
|
||||
Extrema_POnCurv aPOnC1, aPOnC2;
|
||||
anExtrema.Points(i, aPOnC1, aPOnC2);
|
||||
Standard_Real theIntPar = aPOnC1.Parameter();
|
||||
Standard_Real anIntPar = aPOnC2.Parameter();
|
||||
Standard_Boolean IntersFound = Standard_False;
|
||||
for (j = 0; j < 2; j++) //try to find intersection on an extremity of "theEdge"
|
||||
{
|
||||
if (Abs(theIntPar - thePar[j]) <= Precision::PConfusion() &&
|
||||
aDist <= Precision::Confusion())
|
||||
{
|
||||
theMap.Add(theVertices[j]);
|
||||
TopExp_Explorer exp2(anEdge, TopAbs_VERTEX);
|
||||
for (; exp2.More(); exp2.Next())
|
||||
{
|
||||
const TopoDS_Vertex& aVertex = TopoDS::Vertex(exp2.Current());
|
||||
if (aVertex.IsSame(theVertices[j]))
|
||||
{
|
||||
IntersFound = Standard_True;
|
||||
break;
|
||||
}
|
||||
if (BRepTools::Compare(theVertices[j], aVertex))
|
||||
{
|
||||
GlobalMap.Bind(theVertices[j], aVertex);
|
||||
IntersFound = Standard_True;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!IntersFound)
|
||||
{
|
||||
GlobalMap.Bind(theVertices[j], anEdge);
|
||||
IntersFound = Standard_True;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!IntersFound) //intersection is inside "theEdge" => split
|
||||
{
|
||||
gp_Pnt aPoint = aCurve->Value(anIntPar);
|
||||
if (aPoint.Distance(thePnt[0]) > BRep_Tool::Tolerance(theVertices[0]) &&
|
||||
aPoint.Distance(thePnt[1]) > BRep_Tool::Tolerance(theVertices[1]))
|
||||
SplitPars.Append(theIntPar);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (SplitPars.IsEmpty())
|
||||
return;
|
||||
|
||||
//Sort
|
||||
for (i = 1; i < SplitPars.Length(); i++)
|
||||
for (j = i+1; j <= SplitPars.Length(); j++)
|
||||
if (SplitPars(i) > SplitPars(j))
|
||||
{
|
||||
Standard_Real Tmp = SplitPars(i);
|
||||
SplitPars(i) = SplitPars(j);
|
||||
SplitPars(j) = Tmp;
|
||||
}
|
||||
|
||||
//Remove repeating points
|
||||
i = 1;
|
||||
while (i < SplitPars.Length())
|
||||
{
|
||||
gp_Pnt Pnt1 = theCurve->Value(SplitPars(i));
|
||||
gp_Pnt Pnt2 = theCurve->Value(SplitPars(i+1));
|
||||
if (Pnt1.Distance(Pnt2) <= Precision::Confusion())
|
||||
SplitPars.Remove(i+1);
|
||||
else
|
||||
i++;
|
||||
}
|
||||
|
||||
//Split
|
||||
TopTools_ListOfShape NewEdges;
|
||||
BRep_Builder BB;
|
||||
//theVertices[0].Orientation(TopAbs_FORWARD);
|
||||
//theVertices[1].Orientation(TopAbs_REVERSED);
|
||||
TopoDS_Vertex FirstVertex = theVertices[0], LastVertex;
|
||||
Standard_Real FirstPar = thePar[0], LastPar;
|
||||
for (i = 1; i <= SplitPars.Length()+1; i++)
|
||||
{
|
||||
FirstVertex.Orientation(TopAbs_FORWARD);
|
||||
if (i <= SplitPars.Length())
|
||||
{
|
||||
LastPar = SplitPars(i);
|
||||
gp_Pnt LastPoint = theCurve->Value(LastPar);
|
||||
LastVertex = BRepLib_MakeVertex(LastPoint);
|
||||
}
|
||||
else
|
||||
{
|
||||
LastPar = thePar[1];
|
||||
LastVertex = theVertices[1];
|
||||
}
|
||||
LastVertex.Orientation(TopAbs_REVERSED);
|
||||
|
||||
TopoDS_Shape aLocalShape = theEdge.EmptyCopied();
|
||||
TopoDS_Edge NewEdge = TopoDS::Edge(aLocalShape);
|
||||
BB.Range(NewEdge, FirstPar, LastPar);
|
||||
BB.Add(NewEdge, FirstVertex);
|
||||
BB.Add(NewEdge, LastVertex);
|
||||
|
||||
NewEdges.Append(NewEdge);
|
||||
FirstVertex = LastVertex;
|
||||
FirstPar = LastPar;
|
||||
}
|
||||
|
||||
if (!NewEdges.IsEmpty())
|
||||
Splits.Add(theEdge, NewEdges);
|
||||
}
|
||||
|
@ -29,3 +29,13 @@ inline Standard_Boolean LocOpe_WiresOnShape::IsDone() const
|
||||
{
|
||||
return myDone;
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : IsFaceWithSection
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
inline Standard_Boolean LocOpe_WiresOnShape::IsFaceWithSection(const TopoDS_Shape& aFace) const
|
||||
{
|
||||
return (myFacesWithSection.Contains(aFace));
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user