1
0
mirror of https://git.dev.opencascade.org/repos/occt.git synced 2025-04-06 18:26:22 +03:00
occt/src/BRepAlgo/BRepAlgo_Loop.cxx
abv 498ce76bde 0024129: Eliminate remaining compiler warnings in MSVC++ 2008 32 bit with warning level 4
List of resolved warnings:

c4063: Aspect.cdl; TObj_Application.cxx; PCDM.cdl; OpenGl_Workspace_5.cxx;
c4100: XDEDRAW.cxx; ViewerTest_ViewerCommands.cxx; TopOpeBRep_FacesFiller_1.cxx; TopClass_Classifier3d.gxx; TDataStd_ReferenceArray.cxx; QABugs_19.cxx; IntPatch_ImpImpIntersection_5.gxx; HLRTopoBRep_DSFiller.cxx; HLRBRep_Data.lxx; DPrsStd_AISPresentationCommands.cxx; BRepMesh_Delaun.cxx;
c4127: BOPTools_AlgoTools2D.cxx; MAT_Mat.gxx; GeomFill_SweepSectionGenerator.cxx; BRepMesh_Delaun.cxx;
c4189: IntCurveSurface_Inter.gxx; IGESToBRep_BRepEntity.cxx; BRepMesh_Delaun.cxx; BRepAlgo_Loop.cxx; IntStart_SearchOnBoundaries_1.gxx;
c4190: Plugin_Macro.hxx;
c4389: Visual3d_View.cxx; TopOpeBRep/TopOpeBRep_vpr.cxx; TDataStd_BooleanArray.cxx; IntPatch_ALine.cxx;
c4701: BRepAlgo.cxx;
c4702: MNaming_NamingRetrievalDriver_1.cxx; MNaming_NamingRetrievalDriver_2.cxx; BRepClass3d_SolidExplorer.cxx;
c4706: TestTopOpe_BOOP.cxx;

Additional fixes:
- old-style declarations of C functions in IGES and STEP parsers
- clean-up of debug code, fixes for building in Debug mode
- in BRepFill_TrimShellCorner.cxx, lines 878-9, wrong use of assignment instead of comparison fixed
- fix for Plugin_Macro reverted; warning 4190 disabled instead
- in IntPatch_ALine.cxx, line 520, wrong comparison of boolean with index fixed
- in InterfaceGraphic_Visual3d.hxx, field IsCustomMatrix made boolean
- in TopOpeBRepBuild_ShapeSet, obsolete (unused) methods removed
2013-09-18 09:13:31 +04:00

917 lines
27 KiB
C++
Executable File

// Created on: 1995-11-10
// Created by: Yves FRICAUD
// Copyright (c) 1995-1999 Matra Datavision
// Copyright (c) 1999-2012 OPEN CASCADE SAS
//
// The content of this file is subject to the Open CASCADE Technology Public
// License Version 6.5 (the "License"). You may not use the content of this file
// except in compliance with the License. Please obtain a copy of the License
// at http://www.opencascade.org and read it completely before using this file.
//
// The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
// main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
//
// The Original Code and all software distributed under the License is
// distributed on an "AS IS" basis, without warranty of any kind, and the
// Initial Developer hereby disclaims all such warranties, including without
// limitation, any warranties of merchantability, fitness for a particular
// purpose or non-infringement. Please see the License for the specific terms
// and conditions governing the rights and limitations under the License.
#include <stdio.h>
#include <BRepAlgo_Loop.ixx>
#include <BRep_Builder.hxx>
#include <BRepAlgo_FaceRestrictor.hxx>
#include <BRep_Tool.hxx>
#include <Geom2d_Curve.hxx>
#include <Geom_Surface.hxx>
#include <TopExp.hxx>
#include <TopTools_SequenceOfShape.hxx>
#include <TopTools_MapOfShape.hxx>
#include <TopTools_ListIteratorOfListOfShape.hxx>
#include <TopTools_DataMapIteratorOfDataMapOfShapeListOfShape.hxx>
#include <TopoDS.hxx>
#include <TopoDS_Vertex.hxx>
#include <TopoDS_Wire.hxx>
#include <gp_Pnt.hxx>
#include <gp_Pnt2d.hxx>
#include <Precision.hxx>
#include <BRep_TVertex.hxx>
#include <BRep_TEdge.hxx>
#include <TopExp_Explorer.hxx>
#include <TopoDS_Iterator.hxx>
#include <TopTools_DataMapIteratorOfDataMapOfShapeShape.hxx>
#ifdef DRAW
#include <DBRep.hxx>
#endif
#ifdef DEBUG_ALGO
Standard_Boolean AffichLoop = Standard_False;
Standard_Integer NbLoops = 0;
Standard_Integer NbWires = 1;
static char* name = new char[100];
#endif
//=======================================================================
//function : BRepAlgo_Loop
//purpose :
//=======================================================================
BRepAlgo_Loop::BRepAlgo_Loop()
{
}
//=======================================================================
//function : Init
//purpose :
//=======================================================================
void BRepAlgo_Loop::Init(const TopoDS_Face& F)
{
myConstEdges.Clear();
myVerOnEdges.Clear();
myNewWires .Clear();
myNewFaces .Clear();
myNewEdges .Clear();
myFace = F;
}
//=======================================================================
//function : Bubble
//purpose : Orders the sequence of vertices by increasing parameter.
//=======================================================================
static void Bubble(const TopoDS_Edge& E,
TopTools_SequenceOfShape& Seq)
{
Standard_Boolean Invert = Standard_True;
Standard_Integer NbPoints = Seq.Length();
Standard_Real U1,U2;
TopoDS_Vertex V1,V2;
while (Invert) {
Invert = Standard_False;
for ( Standard_Integer i = 1; i < NbPoints; i++) {
TopoDS_Shape aLocalV = Seq.Value(i) .Oriented(TopAbs_INTERNAL);
V1 = TopoDS::Vertex(aLocalV);
aLocalV = Seq.Value(i+1).Oriented(TopAbs_INTERNAL);
V2 = TopoDS::Vertex(aLocalV);
// V1 = TopoDS::Vertex(Seq.Value(i) .Oriented(TopAbs_INTERNAL));
// V2 = TopoDS::Vertex(Seq.Value(i+1).Oriented(TopAbs_INTERNAL));
U1 = BRep_Tool::Parameter(V1,E);
U2 = BRep_Tool::Parameter(V2,E);
if (U2 < U1) {
Seq.Exchange(i,i+1);
Invert = Standard_True;
}
}
}
}
//=======================================================================
//function : AddEdges
//purpose :
//=======================================================================
void BRepAlgo_Loop::AddEdge (TopoDS_Edge& E,
const TopTools_ListOfShape& LV)
{
myVerOnEdges.Bind(E,LV);
}
//=======================================================================
//function : AddConstEdges
//purpose :
//=======================================================================
void BRepAlgo_Loop::AddConstEdge (const TopoDS_Edge& E)
{
myConstEdges.Append(E);
}
//=======================================================================
//function : AddConstEdges
//purpose :
//=======================================================================
void BRepAlgo_Loop::AddConstEdges(const TopTools_ListOfShape& LE)
{
TopTools_ListIteratorOfListOfShape itl(LE);
for (; itl.More(); itl.Next()) {
myConstEdges.Append(itl.Value());
}
}
//=======================================================================
//function : UpdateClosedEdge
//purpose : If the first or the last vertex of intersection
// coincides with the closing vertex, it is removed from SV.
// it will be added at the beginning and the end of SV by the caller.
//=======================================================================
static TopoDS_Vertex UpdateClosedEdge(const TopoDS_Edge& E,
TopTools_SequenceOfShape& SV)
{
TopoDS_Vertex VB [2], V1, V2, VRes;
gp_Pnt P,PC;
Standard_Boolean OnStart = 0, OnEnd = 0;
//// modified by jgv, 13.04.04 for OCC5634 ////
TopExp::Vertices (E,V1,V2);
//Standard_Real Tol = Precision::Confusion();
Standard_Real Tol = BRep_Tool::Tolerance( V1 );
///////////////////////////////////////////////
if (SV.IsEmpty()) return VRes;
VB[0] = TopoDS::Vertex(SV.First());
VB[1] = TopoDS::Vertex(SV.Last ());
PC = BRep_Tool::Pnt(V1);
for ( Standard_Integer i = 0 ; i < 2 ; i++) {
P = BRep_Tool::Pnt(VB [i]);
if (P.IsEqual(PC,Tol)) {
VRes = VB [i];
if (i == 0) OnStart = Standard_True;
else OnEnd = Standard_True;
}
}
if (OnStart && OnEnd) {
if (!VB[0].IsSame(VB[1])) {
#ifdef DEBUG_ALGO
if (AffichLoop)
cout <<"Two different vertices on the closing vertex"<<endl;
#endif
}
else {
SV.Remove(1);
if (!SV.IsEmpty()) SV.Remove(SV.Length());
}
}
else if (OnStart) SV.Remove(1);
else if (OnEnd ) SV.Remove(SV.Length());
return VRes;
}
//=======================================================================
//function : RemovePendingEdges
//purpose :
//=======================================================================
static void RemovePendingEdges(TopTools_DataMapOfShapeListOfShape& MVE)
{
//--------------------------------
// Remove hanging edges.
//--------------------------------
TopTools_DataMapIteratorOfDataMapOfShapeListOfShape Mapit;
TopTools_ListOfShape ToRemove;
TopTools_ListIteratorOfListOfShape itl;
Standard_Boolean YaSupress = Standard_True;
TopoDS_Vertex V1,V2;
while (YaSupress) {
YaSupress = Standard_False;
TopTools_ListOfShape VToRemove;
TopTools_MapOfShape EToRemove;
for (Mapit.Initialize(MVE); Mapit.More(); Mapit.Next()) {
if (Mapit.Value().IsEmpty()) {
VToRemove.Append(Mapit.Key());
}
if (Mapit.Value().Extent() == 1) {
const TopoDS_Edge& E = TopoDS::Edge(Mapit.Value().First());
TopExp::Vertices(E,V1,V2) ;
if (!V1.IsSame(V2)) {
VToRemove.Append(Mapit.Key());
EToRemove.Add(Mapit.Value().First());
}
}
}
if (!VToRemove.IsEmpty()) {
YaSupress = Standard_True;
for (itl.Initialize(VToRemove); itl.More(); itl.Next()) {
MVE.UnBind(itl.Value());
}
if (!EToRemove.IsEmpty()) {
for (Mapit.Initialize(MVE); Mapit.More(); Mapit.Next()) {
TopTools_ListOfShape& LE = MVE.ChangeFind(Mapit.Key());
itl.Initialize(LE);
while (itl.More()) {
if (EToRemove.Contains(itl.Value())) {
LE.Remove(itl);
}
else itl.Next();
}
}
}
}
}
}
//=======================================================================
//function : SamePnt2d
//purpose :
//=======================================================================
static Standard_Boolean SamePnt2d(TopoDS_Vertex V,
TopoDS_Edge& E1,
TopoDS_Edge& E2,
TopoDS_Face& F)
{
Standard_Real f1,f2,l1,l2;
gp_Pnt2d P1,P2;
TopoDS_Shape aLocalF = F.Oriented(TopAbs_FORWARD);
TopoDS_Face FF = TopoDS::Face(aLocalF);
// TopoDS_Face FF = TopoDS::Face(F.Oriented(TopAbs_FORWARD));
Handle(Geom2d_Curve) C1 = BRep_Tool::CurveOnSurface(E1,FF,f1,l1);
Handle(Geom2d_Curve) C2 = BRep_Tool::CurveOnSurface(E2,FF,f2,l2);
if (E1.Orientation () == TopAbs_FORWARD) P1 = C1->Value(f1);
else P1 = C1->Value(l1);
if (E2.Orientation () == TopAbs_FORWARD) P2 = C2->Value(l2);
else P2 = C2->Value(f2);
Standard_Real Tol = 100*BRep_Tool::Tolerance(V);
Standard_Real Dist = P1.Distance(P2);
return Dist < Tol;
}
//=======================================================================
//function : SelectEdge
//purpose : Find edge <NE> connected to <CE> by vertex <CV> in the
// list <LE>. <NE> is removed from the list. If <CE> is
// also in the list <LE> with the same orientation, it is
// removed from the list.
//=======================================================================
static Standard_Boolean SelectEdge(const TopoDS_Face& F,
const TopoDS_Edge& CE,
const TopoDS_Vertex& CV,
TopoDS_Edge& NE,
TopTools_ListOfShape& LE)
{
TopTools_ListIteratorOfListOfShape itl;
NE.Nullify();
#ifdef DEBUG_ALGO
if (AffichLoop) {
if ( LE.Extent() > 2) {
cout <<"vertex on more than 2 edges in a face."<<endl;
}
}
#endif
for ( itl.Initialize(LE); itl.More(); itl.Next()) {
if (itl.Value().IsEqual(CE)) {
LE.Remove(itl);
break;
}
}
if (LE.Extent() > 1) {
//--------------------------------------------------------------
// Several edges possible.
// - Test edges different from CE , Selection of edge
// for which CV has U,V closer to the face
// than corresponding to CE.
// - If several edges give representation less than the tolerance.
// discrimination on tangents.
//--------------------------------------------------------------
TopLoc_Location L;
Standard_Real f,l;
TopoDS_Face FForward = F;
FForward.Orientation(TopAbs_FORWARD);
Handle(Geom2d_Curve) C = BRep_Tool::CurveOnSurface(CE,FForward,f,l);
Standard_Integer k = 1, kmin = 0;
Standard_Real dist,distmin = 100*BRep_Tool::Tolerance(CV);
Standard_Real u ;
if (CE.Orientation () == TopAbs_FORWARD) u = l;
else u = f;
gp_Pnt2d P2,PV = C->Value(u);
for ( itl.Initialize(LE); itl.More(); itl.Next()) {
const TopoDS_Edge& E = TopoDS::Edge(itl.Value());
if (!E.IsSame(CE)) {
C = BRep_Tool::CurveOnSurface(E,FForward,f,l);
if (E.Orientation () == TopAbs_FORWARD) u = f;
else u = l;
P2 = C->Value(u);
dist = PV.Distance(P2);
if ( dist <= distmin) {
kmin = k;
distmin = dist;
}
}
k++;
}
if (kmin == 0) return Standard_False;
k = 1; itl.Initialize(LE);
while (k < kmin) {k++; itl.Next();}
NE = TopoDS::Edge(itl.Value());
LE.Remove(itl);
}
else if (LE.Extent() == 1) {
NE = TopoDS::Edge(LE.First());
LE.RemoveFirst();
}
else {
return Standard_False;
}
#ifdef DRAW
if (AffichLoop) {
DBRep::Set("Selected",NE);
}
#endif
return Standard_True;
}
//=======================================================================
//function : Store
//purpose :
//=======================================================================
static void PurgeNewEdges(TopTools_DataMapOfShapeListOfShape& NewEdges,
const TopTools_MapOfShape& UsedEdges)
{
TopTools_DataMapIteratorOfDataMapOfShapeListOfShape it(NewEdges);
for (; it.More(); it.Next()) {
TopTools_ListOfShape& LNE = NewEdges.ChangeFind(it.Key());
TopTools_ListIteratorOfListOfShape itL(LNE);
while (itL.More()) {
const TopoDS_Shape& NE = itL.Value();
if (!UsedEdges.Contains(NE)) {
LNE.Remove(itL);
}
else {
itL.Next();
}
}
}
}
//=======================================================================
//function : Store
//purpose :
//=======================================================================
static void StoreInMVE (const TopoDS_Face& F,
TopoDS_Edge& E,
TopTools_DataMapOfShapeListOfShape& MVE,
Standard_Boolean& YaCouture,
TopTools_DataMapOfShapeShape& VerticesForSubstitute )
{
TopoDS_Vertex V1, V2, V;
TopTools_ListOfShape Empty;
Standard_Real Tol = 0.001; //5.e-05; //5.e-07;
// gp_Pnt P1, P2, P;
gp_Pnt P1, P;
TopTools_DataMapIteratorOfDataMapOfShapeListOfShape Mapit;
BRep_Builder BB;
for (Mapit.Initialize( MVE ); Mapit.More(); Mapit.Next())
{
V = TopoDS::Vertex( Mapit.Key() );
P = BRep_Tool::Pnt( V );
TopTools_ListOfShape VList;
TopoDS_Iterator VerExp( E );
for (; VerExp.More(); VerExp.Next())
VList.Append( VerExp.Value() );
TopTools_ListIteratorOfListOfShape itl( VList );
for (; itl.More(); itl.Next())
{
V1 = TopoDS::Vertex( itl.Value() );
P1 = BRep_Tool::Pnt( V1 );
if (P.IsEqual( P1, Tol ) && !V.IsSame(V1))
{
V.Orientation( V1.Orientation() );
if (VerticesForSubstitute.IsBound( V1 ))
{
TopoDS_Shape OldNewV = VerticesForSubstitute( V1 );
if (! OldNewV.IsSame( V ))
{
VerticesForSubstitute.Bind( OldNewV, V );
VerticesForSubstitute( V1 ) = V;
}
}
else
{
if (VerticesForSubstitute.IsBound( V ))
{
TopoDS_Shape NewNewV = VerticesForSubstitute( V );
if (! NewNewV.IsSame( V1 ))
VerticesForSubstitute.Bind( V1, NewNewV );
}
else
{
VerticesForSubstitute.Bind( V1, V );
TopTools_DataMapIteratorOfDataMapOfShapeShape mapit( VerticesForSubstitute );
for (; mapit.More(); mapit.Next())
if (mapit.Value().IsSame( V1 ))
VerticesForSubstitute( mapit.Key() ) = V;
}
}
E.Free( Standard_True );
BB.Remove( E, V1 );
BB.Add( E, V );
}
}
}
TopExp::Vertices(E,V1,V2);
if( V1.IsNull() && V2.IsNull() ){ YaCouture = Standard_False; return; }
if (!MVE.IsBound(V1)) {
MVE.Bind(V1,Empty);
}
MVE(V1).Append(E);
if (!V1.IsSame(V2)) {
if (!MVE.IsBound(V2)) {
MVE.Bind(V2,Empty);
}
MVE(V2).Append(E);
}
TopLoc_Location L ;
Handle(Geom_Surface) S = BRep_Tool::Surface(F,L);
if (BRep_Tool::IsClosed(E,S,L)) {
MVE(V2).Append(E.Reversed());
if (!V1.IsSame(V2)) {
MVE(V1).Append(E.Reversed());
}
YaCouture = Standard_True;
}
}
//=======================================================================
//function : Perform
//purpose :
//=======================================================================
void BRepAlgo_Loop::Perform()
{
TopTools_DataMapIteratorOfDataMapOfShapeListOfShape Mapit;
TopTools_ListIteratorOfListOfShape itl;
TopoDS_Vertex V1,V2;
Standard_Boolean YaCouture = Standard_False;
#ifdef DEBUG_ALGO
if (AffichLoop) {
cout <<"NewLoop"<<endl;
NbLoops++;
#ifdef DRAW
sprintf(name,"FLoop_%d",NbLoops);
DBRep::Set(name,myFace);
Standard_Integer NbEdges = 1;
#endif
for (Mapit.Initialize(myVerOnEdges); Mapit.More(); Mapit.Next()) {
const TopoDS_Edge& E = TopoDS::Edge(Mapit.Key());
#ifdef DRAW
sprintf(name,"EEE_%d_%d",NbLoops,NbEdges++);
DBRep::Set(name,E);
#endif
}
for (itl.Initialize(myConstEdges); itl.More(); itl.Next()) {
const TopoDS_Edge& E = TopoDS::Edge(itl.Value());
#ifdef DRAW
sprintf(name,"EEE_%d_%d",NbLoops,NbEdges++);
DBRep::Set(name,E);
#endif
}
}
#endif
//------------------------------------------------
// Cut edges
//------------------------------------------------
for (Mapit.Initialize(myVerOnEdges); Mapit.More(); Mapit.Next()) {
TopTools_ListOfShape LCE;
CutEdge (TopoDS::Edge(Mapit.Key()),Mapit.Value(), LCE);
myNewEdges.Bind(Mapit.Key(),LCE);
}
//-----------------------------------
// Construction map vertex => edges
//-----------------------------------
TopTools_DataMapOfShapeListOfShape MVE;
// add cut edges.
for (Mapit.Initialize(myNewEdges); Mapit.More(); Mapit.Next()) {
for (itl.Initialize(myNewEdges(Mapit.Key())); itl.More(); itl.Next()) {
TopoDS_Edge& E = TopoDS::Edge(itl.Value());
StoreInMVE(myFace,E,MVE,YaCouture,myVerticesForSubstitute);
}
}
// add const edges
// Sewn edges can be doubled or not in myConstEdges
// => call only once StoreInMVE which should double them
TopTools_MapOfShape DejaVu;
for (itl.Initialize(myConstEdges); itl.More(); itl.Next()) {
TopoDS_Edge& E = TopoDS::Edge(itl.Value());
if (DejaVu.Add(E))
StoreInMVE(myFace,E,MVE,YaCouture,myVerticesForSubstitute);
}
#ifdef DRAW
if (AffichLoop) {
cout <<"NewLoop"<<endl;
Standard_Integer NbEdges = 1;
TopTools_MapOfShape Done;
for (Mapit.Initialize(MVE); Mapit.More();Mapit.Next()) {
for (itl.Initialize(Mapit.Value()); itl.More(); itl.Next()) {
TopoDS_Edge& E = TopoDS::Edge(itl.Value());
if (Done.Add(E)) {
sprintf(name,"EEC_%d_%d",NbLoops,NbEdges++);
DBRep::Set(name,E);
}
}
}
}
#endif
//-----------------------------------------------
// Construction of wires and new faces.
//----------------------------------------------
TopoDS_Vertex VF,VL,CV;
TopoDS_Edge CE,NE,EF;
BRep_Builder B;
TopoDS_Wire NW;
Standard_Boolean End;
TopTools_MapOfShape UsedEdges;
while (!MVE.IsEmpty()) {
B.MakeWire(NW);
//--------------------------------
// Removal of hanging edges.
//--------------------------------
RemovePendingEdges(MVE);
if (MVE.IsEmpty()) break;
//--------------------------------
// Start edge.
//--------------------------------
Mapit.Initialize(MVE);
EF = CE = TopoDS::Edge(Mapit.Value().First());
TopExp::Vertices(CE,V1,V2);
//--------------------------------
// VF vertex start of new wire
//--------------------------------
if (CE.Orientation() == TopAbs_FORWARD) { CV = VF = V1;}
else { CV = VF = V2;}
if (!MVE.IsBound(CV)) continue;
for ( itl.Initialize(MVE(CV)); itl.More(); itl.Next()) {
if (itl.Value().IsEqual(CE)) {
MVE(CV).Remove(itl);
break;
}
}
End = Standard_False;
while (!End) {
//-------------------------------
// Construction of a wire.
//-------------------------------
TopExp::Vertices(CE,V1,V2);
if (!CV.IsSame(V1)) CV = V1; else CV = V2;
B.Add (NW,CE);
UsedEdges.Add(CE);
if (!MVE.IsBound(CV) || MVE(CV).IsEmpty()) {
End = Standard_True;
}
else {
End = !SelectEdge(myFace,CE,CV,NE,MVE(CV));
if (!End) {
CE = NE;
if (MVE(CV).IsEmpty()) MVE.UnBind(CV);
}
}
}
//--------------------------------------------------
// Add new wire to the set of wires
//------------------------------------------------
Standard_Real Tol = 0.001; //5.e-05; //5.e-07;
TopExp_Explorer explo( NW, TopAbs_VERTEX );
for (; explo.More(); explo.Next())
{
const TopoDS_Vertex& aV = TopoDS::Vertex( explo.Current() );
Handle(BRep_TVertex)& TV = *((Handle(BRep_TVertex)*) &(aV).TShape());
TV->Tolerance( Tol );
TV->Modified( Standard_True );
}
for (explo.Init( NW, TopAbs_EDGE ); explo.More(); explo.Next())
{
const TopoDS_Edge& aE = TopoDS::Edge( explo.Current() );
Handle(BRep_TEdge)& TE = *((Handle(BRep_TEdge)*) &(aE).TShape());
TE->Tolerance( Tol );
TE->Modified( Standard_True );
}
if (VF.IsSame(CV) && SamePnt2d(VF,EF,CE,myFace))
myNewWires.Append (NW);
#ifdef DEBUG_ALGO
else {
cout <<"BRepAlgo_Loop: Open Wire"<<endl;
if (AffichLoop)
cout << "OpenWire is : NW_"<<NbLoops<<"_"<<NbWires<<endl;
}
#endif
#ifdef DRAW
if (AffichLoop) {
sprintf(name,"NW_%d_%d",NbLoops,NbWires++);
DBRep::Set(name,NW);
}
#endif
}
PurgeNewEdges(myNewEdges,UsedEdges);
}
//=======================================================================
//function : CutEdges
//purpose :
//=======================================================================
void BRepAlgo_Loop::CutEdge (const TopoDS_Edge& E,
const TopTools_ListOfShape& VOnE,
TopTools_ListOfShape& NE ) const
{
TopoDS_Shape aLocalE = E.Oriented(TopAbs_FORWARD);
TopoDS_Edge WE = TopoDS::Edge(aLocalE);
Standard_Real U1,U2;
TopoDS_Vertex V1,V2;
TopTools_SequenceOfShape SV;
TopTools_ListIteratorOfListOfShape it(VOnE);
BRep_Builder B;
for ( ; it.More(); it.Next()) {
SV.Append(it.Value());
}
//--------------------------------
// Parse vertices on the edge.
//--------------------------------
Bubble (WE,SV);
Standard_Integer NbVer = SV.Length();
//----------------------------------------------------------------
// Construction of new edges.
// Note : vertices at the extremities of edges are not
// onligatorily in the list of vertices
//----------------------------------------------------------------
if (SV.IsEmpty()) {
NE.Append(E);
return;
}
TopoDS_Vertex VF,VL;
Standard_Real f,l;
BRep_Tool::Range(WE,f,l);
TopExp::Vertices(WE,VF,VL);
if (NbVer == 2) {
if (SV(1).IsEqual(VF) && SV(2).IsEqual(VL)) {
NE.Append(E);
#ifdef DRAW
if (AffichLoop) {
DBRep::Set("ECOpied",E);
}
#endif
return;
}
}
//----------------------------------------------------
// Processing of closed edges
// If a vertex of intersection is on the common vertex
// it should appear at the beginning and end of SV.
//----------------------------------------------------
TopoDS_Vertex VCEI;
if (!VF.IsNull() && VF.IsSame(VL)) {
VCEI = UpdateClosedEdge(WE,SV);
if (!VCEI.IsNull()) {
TopoDS_Shape aLocalV = VCEI.Oriented(TopAbs_FORWARD);
VF = TopoDS::Vertex(aLocalV);
aLocalV = VCEI.Oriented(TopAbs_REVERSED);
VL = TopoDS::Vertex(aLocalV);
// VF = TopoDS::Vertex(VCEI.Oriented(TopAbs_FORWARD));
// VL = TopoDS::Vertex(VCEI.Oriented(TopAbs_REVERSED));
}
SV.Prepend(VF);
SV.Append(VL);
}
else {
//-----------------------------------------
// Eventually all extremities of the edge.
//-----------------------------------------
if (!VF.IsNull() && !VF.IsSame(SV.First())) SV.Prepend(VF);
if (!VL.IsNull() && !VL.IsSame(SV.Last ())) SV.Append (VL);
}
while (!SV.IsEmpty()) {
while (!SV.IsEmpty() &&
SV.First().Orientation() != TopAbs_FORWARD) {
SV.Remove(1);
}
if (SV.IsEmpty())
break;
V1 = TopoDS::Vertex(SV.First());
SV.Remove(1);
if (SV.IsEmpty())
break;
if (SV.First().Orientation() == TopAbs_REVERSED) {
V2 = TopoDS::Vertex(SV.First());
SV.Remove(1);
//-------------------------------------------
// Copy the edge and restriction by V1 V2.
//-------------------------------------------
TopoDS_Shape NewEdge = WE.EmptyCopied();
TopoDS_Shape aLocalEdge = V1.Oriented(TopAbs_FORWARD);
B.Add (NewEdge,aLocalEdge);
aLocalEdge = V2.Oriented(TopAbs_REVERSED);
B.Add (TopoDS::Edge(NewEdge),aLocalEdge);
// B.Add (NewEdge,V1.Oriented(TopAbs_FORWARD));
// B.Add (NewEdge,V2.Oriented(TopAbs_REVERSED));
if (V1.IsSame(VF))
U1 = f;
else
// U1=BRep_Tool::Parameter
// (TopoDS::Vertex(V1.Oriented(TopAbs_INTERNAL)),WE);
{
TopoDS_Shape aLocalV = V1.Oriented(TopAbs_INTERNAL);
U1=BRep_Tool::Parameter(TopoDS::Vertex(aLocalV),WE);
}
if (V2.IsSame(VL))
U2 = l;
else
{
TopoDS_Shape aLocalV = V2.Oriented(TopAbs_INTERNAL);
U2=BRep_Tool::Parameter(TopoDS::Vertex(aLocalV),WE);
// U2=BRep_Tool::Parameter
// (TopoDS::Vertex(V2.Oriented(TopAbs_INTERNAL)),WE);
}
B.Range (TopoDS::Edge(NewEdge),U1,U2);
#ifdef DRAW
if (AffichLoop) {
DBRep::Set("Cut",NewEdge);
}
#endif
NE.Append(NewEdge.Oriented(E.Orientation()));
}
}
//Remove edges with size <= tolerance
Standard_Real Tol = 0.001; //5.e-05; //5.e-07;
it.Initialize(NE);
while (it.More())
{
// skl : I change "E" to "EE"
TopoDS_Edge EE = TopoDS::Edge( it.Value() );
Standard_Real fpar, lpar;
BRep_Tool::Range( EE, fpar, lpar );
if (lpar - fpar <= Precision::Confusion())
NE.Remove(it);
else
{
gp_Pnt2d pf, pl;
BRep_Tool::UVPoints( EE, myFace, pf, pl );
if (pf.Distance(pl) <= Tol && !EE.Closed())
NE.Remove(it);
else
it.Next();
}
}
}
//=======================================================================
//function : NewWires
//purpose :
//=======================================================================
const TopTools_ListOfShape& BRepAlgo_Loop::NewWires() const
{
return myNewWires;
}
//=======================================================================
//function : NewFaces
//purpose :
//=======================================================================
const TopTools_ListOfShape& BRepAlgo_Loop::NewFaces() const
{
return myNewFaces;
}
//=======================================================================
//function : WiresToFaces
//purpose :
//=======================================================================
void BRepAlgo_Loop::WiresToFaces()
{
if (!myNewWires.IsEmpty()) {
BRepAlgo_FaceRestrictor FR;
TopoDS_Shape aLocalS = myFace.Oriented(TopAbs_FORWARD);
FR.Init (TopoDS::Face(aLocalS),Standard_False);
// FR.Init (TopoDS::Face(myFace.Oriented(TopAbs_FORWARD)),
// Standard_False);
TopTools_ListIteratorOfListOfShape it(myNewWires);
for (; it.More(); it.Next()) {
FR.Add(TopoDS::Wire(it.Value()));
}
FR.Perform();
if (FR.IsDone()) {
TopAbs_Orientation OriF = myFace.Orientation();
for (; FR.More(); FR.Next()) {
myNewFaces.Append(FR.Current().Oriented(OriF));
}
}
}
}
//=======================================================================
//function : NewEdges
//purpose :
//=======================================================================
const TopTools_ListOfShape& BRepAlgo_Loop::NewEdges(const TopoDS_Edge& E) const
{
return myNewEdges(E);
}
//=======================================================================
//function : GetVerticesForSubstitute
//purpose :
//=======================================================================
void BRepAlgo_Loop::GetVerticesForSubstitute( TopTools_DataMapOfShapeShape& VerVerMap ) const
{
VerVerMap = myVerticesForSubstitute;
}
//=======================================================================
//function : VerticesForSubstitute
//purpose :
//=======================================================================
void BRepAlgo_Loop::VerticesForSubstitute( TopTools_DataMapOfShapeShape& VerVerMap )
{
myVerticesForSubstitute = VerVerMap;
}