1
0
mirror of https://git.dev.opencascade.org/repos/occt.git synced 2025-04-04 18:06:22 +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:
jgv 2012-04-06 11:52:38 +04:00
parent a0b4c5eac5
commit ed60a55e7f
10 changed files with 705 additions and 14 deletions

View File

@ -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;

View File

@ -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

View File

@ -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);

View File

@ -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;

View File

@ -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.

View File

@ -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;
}

View File

@ -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()) {
@ -169,8 +170,11 @@ void LocOpe_Spliter::Perform(const Handle(LocOpe_ProjectedWires)& PW)
}
else {
TopoDS_Face fac = PW->OnFace();
if(!myMap.IsBound(fac)) continue;
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,9 +193,11 @@ 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()) {
theCFace.Add(TopoDS::Wire(itl.Value()),fac);
}
if (theFacesWithSection.Contains(fac))
theCFace.Add(ledges, fac);
else
for (itl.Initialize(ledges); itl.More(); itl.Next())
theCFace.Add(TopoDS::Wire(itl.Value()),fac);
}

View File

@ -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)
@ -129,12 +135,19 @@ is
-- Else returns <Standard_False>.
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;

View File

@ -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);
}

View File

@ -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));
}