1
0
mirror of https://git.dev.opencascade.org/repos/occt.git synced 2025-04-21 10:13:43 +03:00

0022564: BRepMesh_Classifier improvements

This commit is contained in:
EPA 2011-09-02 08:16:09 +00:00 committed by bugmaster
parent c99551fa0f
commit 2b59653e67
9 changed files with 568 additions and 1336 deletions

View File

@ -23,15 +23,6 @@ uses
is is
Create (F : Face from TopoDS;
Tol : Real from Standard;
edges : DataMapOfShapePairOfPolygon from BRepMesh;
themap : IndexedMapOfInteger from TColStd;
Str : IndexedMapOfVertex from BRepMesh;
Umin, Umax, Vmin, Vmax: Real from Standard)
returns Classifier from BRepMesh;
Create (F : Face from TopoDS; Create (F : Face from TopoDS;
Tol : Real from Standard; Tol : Real from Standard;
edges : DataMapOfShapePairOfPolygon from BRepMesh; edges : DataMapOfShapePairOfPolygon from BRepMesh;
@ -49,10 +40,6 @@ is
returns Status from BRepMesh; returns Status from BRepMesh;
---C++: inline ---C++: inline
NaturalRestriction(me)
returns Boolean from Standard;
---C++: inline
Destroy(me: in out); Destroy(me: in out);
---C++: alias ~ ---C++: alias ~
@ -76,6 +63,5 @@ fields
U2 : Real from Standard; U2 : Real from Standard;
V2 : Real from Standard; V2 : Real from Standard;
myState : Status from BRepMesh; myState : Status from BRepMesh;
isnatural : Boolean from Standard;
end Classifier from BRepMesh; end Classifier from BRepMesh;

View File

@ -139,339 +139,6 @@ void BRepMesh_Classifier::AnalizeWire (const TColgp_SequenceOfPnt2d& theSeqPnt2
//purpose : //purpose :
//======================================================================= //=======================================================================
BRepMesh_Classifier::BRepMesh_Classifier(const TopoDS_Face& aFace,
const Standard_Real TolUV,
const BRepMesh_DataMapOfShapePairOfPolygon& edges,
const TColStd_IndexedMapOfInteger& themap,
const BRepMesh_IndexedMapOfVertex& Str,
const Standard_Real Umin,
const Standard_Real Umax,
const Standard_Real Vmin,
const Standard_Real Vmax):
Toluv(TolUV), Face(aFace),
myState(BRepMesh_NoError),
isnatural(Standard_False)
{
//-- impasse sur les surfs definies sur plus d une periode
//-- once definition
Face.Orientation(TopAbs_FORWARD);
TopoDS_Edge edge;
BRepTools_WireExplorer WireExplorer;
//TopExp_Explorer FaceExplorer;
TopoDS_Iterator FaceExplorer;
TColgp_SequenceOfPnt2d aWirePoints, aWire;
TColStd_SequenceOfInteger aWireLength;
//-- twice definitions
TopAbs_Orientation anOr = TopAbs_FORWARD;
Standard_Boolean falsewire = Standard_False;
Standard_Integer i, index, firstindex = 0, lastindex = 0, nbedges = 0;
#ifdef DEB_MESH
debwire = 0;
#endif
for(FaceExplorer.Initialize(Face); FaceExplorer.More(); FaceExplorer.Next())
{
#ifdef DEB_MESH
if (debclass) { debwire++; cout <<endl; cout << "#wire no "<<debwire; debedge = 0;}
#endif
if(FaceExplorer.Value().ShapeType() != TopAbs_WIRE)
continue;
// For each wire we create a data map, linking vertices (only
// the ends of edges) with their positions in the sequence of
// all 2d points from this wire.
// When we meet some vertex for the second time - the piece
// of sequence is treated for a HOLE and quits the sequence.
// Actually, we must unbind the vertices belonging to the
// loop from the map, but since they can't appear twice on the
// valid wire, leave them for a little speed up.
nbedges = 0;
TColgp_SequenceOfPnt2d SeqPnt2d;
TColStd_DataMapOfIntegerInteger NodeInSeq;
// Start traversing the wire
for (WireExplorer.Init(TopoDS::Wire(FaceExplorer.Value()),Face); WireExplorer.More(); WireExplorer.Next())
{
edge = WireExplorer.Current();
#ifdef DEB_MESH
if (debclass) { debedge++; cout << endl; cout << "#edge no "<<debedge <<endl;}
#endif
anOr = edge.Orientation();
if (anOr != TopAbs_FORWARD && anOr != TopAbs_REVERSED) continue;
if (edges.IsBound(edge))
{
// Retrieve polygon
// Define the direction for adding points to SeqPnt2d
Standard_Integer iFirst,iLast,iIncr;
const BRepMesh_PairOfPolygon& pair = edges.Find(edge);
Handle(Poly_PolygonOnTriangulation) NOD;
if (anOr == TopAbs_FORWARD)
{
NOD = pair.First();
iFirst = 1;
iLast = NOD->NbNodes();
iIncr = 1;
}
else
{
NOD = pair.Last();
iFirst = NOD->NbNodes();
iLast = 1;
iIncr = -1;
}
const TColStd_Array1OfInteger& indices = NOD->Nodes();
// indexFirst and nodeLast are the indices of first and last
// vertices of the edge in IndexedMap <Str>
const Standard_Integer indexFirst = themap.FindKey(indices(iFirst));
const Standard_Integer indexLast = themap.FindKey(indices(iLast));
// Skip degenerated edge : OCC481(apo)
if (indexLast == indexFirst && (iLast-iFirst) == iIncr) continue;
// If there's a gap between edges -> raise <falsewire> flag
if (nbedges)
{
if (indexFirst != lastindex)
{
falsewire = Standard_True;
break;
}
}
else firstindex = indexFirst;
lastindex = indexLast;
// Record first vertex (to detect loops)
NodeInSeq.Bind(indexFirst,SeqPnt2d.Length()+1);
// Add vertices in sequence
for (i = iFirst; i != iLast; i += iIncr)
{
index = (i == iFirst)? indexFirst : themap.FindKey(indices(i));
gp_Pnt2d vp(Str(index).Coord());
SeqPnt2d.Append(vp);
#ifdef DEB_MESH
if (debclass) cout<<"point p"<<index<<" "<<vp.X()<<" "<< vp.Y()<<endl;
#endif
}
// Now, is there a loop?
if (NodeInSeq.IsBound(indexLast))
{
// Yes, treat it separately as a hole
// 1. Divide points into main wire and a loop
const Standard_Integer iWireStart = NodeInSeq(indexLast);
if(iWireStart < SeqPnt2d.Length()) {
SeqPnt2d.Split(iWireStart, aWire);
//OCC319-> the operation will be done later
// 2. Proceed the loop
//AnalizeWire(aLoop, Umin, Umax, Vmin, Vmax, aWirePoints, aWireLength, NbBiPoint);
aWireLength.Append(aWire.Length());
aWirePoints.Append(aWire);
//<-OCC319
}
}
nbedges++;
}
}
if (nbedges)
{
// Isn't it open?
if (falsewire || (firstindex != lastindex) || SeqPnt2d.Length() > 1)
{
myState = BRepMesh_OpenWire;
return;
}
}
else
{
#ifdef DEB_MESH
cout <<"Warning : empty wire" <<endl;
#endif
}
}
// Check natural restriction
const Standard_Integer nbwires = aWireLength.Length();
if (nbwires == 1 && nbedges == 4)
{
Handle(Geom2d_Curve) C2d;
Standard_Real pfbid, plbid;
isnatural = Standard_True;
for(FaceExplorer.Initialize(Face); FaceExplorer.More(); FaceExplorer.Next())
{
if(FaceExplorer.Value().ShapeType() != TopAbs_WIRE)
continue;
TopoDS_Iterator aEdgeIt(FaceExplorer.Value());
for( ; aEdgeIt.More(); aEdgeIt.Next())
{
edge = TopoDS::Edge(aEdgeIt.Value());
if(anOr == TopAbs_FORWARD || anOr == TopAbs_REVERSED)
{
C2d = BRep_Tool::CurveOnSurface(edge,Face,pfbid,plbid);
//OCC316(APO): if(!IsLine(C2d)) { isnatural = Standard_False; break; }
if(!C2d.IsNull() && !IsLine(C2d)) { isnatural = Standard_False; break; }
else
{ // sont-ce des isos:
gp_Pnt2d P1, P2;
C2d->D0(pfbid, P1);
C2d->D0(plbid, P2);
if ((Abs(P1.X()-P2.X()) > 1.e-04) && (Abs(P1.Y()-P2.Y()) > 1.e-04)) { isnatural = Standard_False; break; }
}
}
}
}
}
Standard_Integer NbBiPoint = aWirePoints.Length();
BRepMesh_Array1OfBiPoint BiPoints(0,NbBiPoint);
BRepMesh_BiPoint *BP;
Standard_Real *Coordinates1;
Standard_Real x1, y1, x2, y2, xstart, ystart;
Standard_Integer j, l = 1;
BP = &(BiPoints.ChangeValue(1));
// Fill array of segments (bi-points)
for (i = 1; i <= nbwires; i++)
{
const Standard_Integer len = aWireLength(i) + 1;
for (j = 1; j <= len; j++)
{
// Obtain last point of the segment
if (j == len)
{
x2 = xstart;
y2 = ystart;
}
else
{
const gp_Pnt2d& PT = aWirePoints(l); l++;
x2 = PT.X();
y2 = PT.Y();
}
// Build segment (bi-point)
if (j == 1)
{
xstart = x2;
ystart = y2;
}
else
{
Coordinates1 = ((Standard_Real*)(BP->Coordinates())); BP++;
Coordinates1[0] = x1;
Coordinates1[1] = y1;
Coordinates1[2] = x2;
Coordinates1[3] = y2;
Coordinates1[4] = x2 - x1;
Coordinates1[5] = y2 - y1;
}
x1 = x2;
y1 = y2;
}
}
Standard_Real *Coordinates2;
Standard_Real A1, B1, C1, A2, B2, C2, AB, BC, CA, xc, yc;
Standard_Real mu1, d, mu2;
Standard_Integer ik, ikEnd = 0, jk, jkEnd;
Standard_Real x11, x12, y11, y12, x21, x22, y21, y22;
for(i = 1; i <= nbwires; i++)
{
ik = ikEnd + 1; ikEnd += aWireLength(i);
// Explore first wire
for (; ik <= ikEnd; ik++)
{
Coordinates1 = ((Standard_Real*)(BiPoints.ChangeValue(ik).Coordinates()));
x11 = Coordinates1[0];
y11 = Coordinates1[1];
x12 = Coordinates1[2];
y12 = Coordinates1[3];
A1 = Coordinates1[5];
B1 = -Coordinates1[4];
C1 = - x11*A1 - y11*B1;
//mu1 = Sqrt(A1*A1+B1*B1);
mu1 = A1*A1+B1*B1;
for (j = i; j <= nbwires; j++)
{
//for i==j the algorithm check current wire on selfintersection
if (j == i)
{
jk = ik + 2; jkEnd = ikEnd;
}
else
{
jk = jkEnd + 1; jkEnd = jk + aWireLength(j) - 1;
}
// Explore second wire
for (; jk <= jkEnd; jk++)
{
// don't check end's segment of the wire on selfrestriction
if (jk == ikEnd) continue;
Coordinates2 = ((Standard_Real*)(BiPoints.ChangeValue(jk).Coordinates()));
x21 = Coordinates2[0];
y21 = Coordinates2[1];
x22 = Coordinates2[2];
y22 = Coordinates2[3];
A2 = Coordinates2[5];
B2 = -Coordinates2[4];
C2 = - x21*A2 - y21*B2;
//mu2 = Sqrt(A2*A2+B2*B2);
mu2 = A2*A2+B2*B2;
//different segments may have common vertex (see OCC287 bug for example)
//if(x22 == x11 && y22 == y11){ myState = BRepMesh_OpenWire; return;}
AB = A1*B2 - A2*B1;
//check on minimal of distance between current segment and points of another linear segments - OCC319
//d = Abs(A1*x22 + B1*y22 + C1);
d = A1*x22 + B1*y22 + C1;
if(i != j && // if compared wires are different &&
AB*AB > PARALL_COND*PARALL_COND*mu1*mu2 && // angle between two segments greater then PARALL_COND &&
d*d < MIN_DIST*MIN_DIST*mu1 && // distance between vertex of the segment and other one's less then MIN_DIST
(x22-x11)*(x22-x12) < 0.0 && (y22-y11)*(y22-y12) < 0.0)
{
myState = BRepMesh_SelfIntersectingWire; return;
}
//look for intersection of two linear segments
if(Abs(AB) <= RESOLUTION) continue; //current segments seem parallel - no intersection
//calculate coordinates of point of the intersection
BC = B1*C2 - B2*C1; xc = BC/AB;
CA = C1*A2 - C2*A1; yc = CA/AB;
if( Abs(xc-x11) > RESOLUTION && Abs(xc-x12) > RESOLUTION &&
Abs(yc-y11) > RESOLUTION && Abs(yc-y12) > RESOLUTION &&
Abs(xc-x21) > RESOLUTION && Abs(xc-x22) > RESOLUTION &&
Abs(yc-y21) > RESOLUTION && Abs(yc-y22) > RESOLUTION )
{
//check on belonging of intersection point to the both of segments
if((xc-x11)*(xc-x12) < 0.0 && (yc-y11)*(yc-y12) < 0.0 &&
(xc-x21)*(xc-x22) < 0.0 && (yc-y21)*(yc-y22) < 0.0)
{
//different segments may have common vertex (why "<" but "<=")
myState = BRepMesh_SelfIntersectingWire; return;
}
}
}
}
}
}
// Find holes
for (i = nbwires; i >= 1; i--)
{
NbBiPoint = aWirePoints.Length() - aWireLength(i) + 1;
aWirePoints.Split(NbBiPoint, aWire);
AnalizeWire(aWire, Umin, Umax, Vmin, Vmax);
}
}
//Wind code duplication
BRepMesh_Classifier::BRepMesh_Classifier(const TopoDS_Face& aFace, BRepMesh_Classifier::BRepMesh_Classifier(const TopoDS_Face& aFace,
const Standard_Real TolUV, const Standard_Real TolUV,
const BRepMesh_DataMapOfShapePairOfPolygon& edges, const BRepMesh_DataMapOfShapePairOfPolygon& edges,
@ -482,8 +149,7 @@ BRepMesh_Classifier::BRepMesh_Classifier(const TopoDS_Face& aFace,
const Standard_Real Vmin, const Standard_Real Vmin,
const Standard_Real Vmax): const Standard_Real Vmax):
Toluv(TolUV), Face(aFace), Toluv(TolUV), Face(aFace),
myState(BRepMesh_NoError), myState(BRepMesh_NoError)
isnatural(Standard_False)
{ {
//-- impasse sur les surfs definies sur plus d une periode //-- impasse sur les surfs definies sur plus d une periode
@ -608,7 +274,6 @@ BRepMesh_Classifier::BRepMesh_Classifier(const TopoDS_Face& aFace,
//<-OCC319 //<-OCC319
} }
} }
nbedges++; nbedges++;
} }
} }
@ -630,38 +295,7 @@ BRepMesh_Classifier::BRepMesh_Classifier(const TopoDS_Face& aFace,
} }
} }
// Check natural restriction
const Standard_Integer nbwires = aWireLength.Length(); const Standard_Integer nbwires = aWireLength.Length();
if (nbwires == 1 && nbedges == 4)
{
Handle(Geom2d_Curve) C2d;
Standard_Real pfbid, plbid;
isnatural = Standard_True;
for(FaceExplorer.Initialize(Face); FaceExplorer.More(); FaceExplorer.Next())
{
if(FaceExplorer.Value().ShapeType() != TopAbs_WIRE)
continue;
TopoDS_Iterator aEdgeIt(FaceExplorer.Value());
for( ; aEdgeIt.More(); aEdgeIt.Next())
{
edge = TopoDS::Edge(aEdgeIt.Value());
if(anOr == TopAbs_FORWARD || anOr == TopAbs_REVERSED)
{
C2d = BRep_Tool::CurveOnSurface(edge,Face,pfbid,plbid);
//OCC316(APO): if(!IsLine(C2d)) { isnatural = Standard_False; break; }
if(!C2d.IsNull() && !IsLine(C2d)) { isnatural = Standard_False; break; }
else
{ // sont-ce des isos:
gp_Pnt2d P1, P2;
C2d->D0(pfbid, P1);
C2d->D0(plbid, P2);
if ((Abs(P1.X()-P2.X()) > 1.e-04) && (Abs(P1.Y()-P2.Y()) > 1.e-04)) { isnatural = Standard_False; break; }
}
}
}
}
}
Standard_Integer NbBiPoint = aWirePoints.Length(); Standard_Integer NbBiPoint = aWirePoints.Length();
BRepMesh_Array1OfBiPoint BiPoints(0,NbBiPoint); BRepMesh_Array1OfBiPoint BiPoints(0,NbBiPoint);

View File

@ -15,13 +15,3 @@ inline BRepMesh_Status BRepMesh_Classifier::State() const
{ {
return myState; return myState;
} }
//=======================================================================
//function : NaturalRestriction
//purpose :
//=======================================================================
inline Standard_Boolean BRepMesh_Classifier::NaturalRestriction() const
{
return isnatural;
}

View File

@ -56,11 +56,6 @@ class Delaun from BRepMesh
returns Delaun from BRepMesh; returns Delaun from BRepMesh;
AddVertex (me : in out;
theVertex : in Vertex from BRepMesh);
---Purpose: Adds a new vertex in the triangulation.
RemoveVertex (me : in out; RemoveVertex (me : in out;
theVertex : in Vertex from BRepMesh); theVertex : in Vertex from BRepMesh);
---Purpose: Removes a vertex in the triangulation. ---Purpose: Removes a vertex in the triangulation.
@ -71,27 +66,12 @@ class Delaun from BRepMesh
---Purpose: Adds some vertices in the triangulation. ---Purpose: Adds some vertices in the triangulation.
RevertDiagonal (me : in out;
theEdge : in Integer from Standard)
---Purpose: Substitutes the Edge beetween to triangles by the
-- other diagonal of the quadrilatere if it is
-- possible (convex polygon). Return True if done.
returns Boolean from Standard;
UseEdge (me : in out; UseEdge (me : in out;
theEdge : in Integer from Standard) theEdge : in Integer from Standard)
---Purpose: Modify mesh to use the edge. Return True if done. ---Purpose: Modify mesh to use the edge. Return True if done.
returns Boolean from Standard; returns Boolean from Standard;
SmoothMesh (me : in out;
Epsilon : in Real from Standard);
---Purpose: Smooths the mesh in 2d space. The method is to
-- move the free and OnSurface vertices at the
-- barycentre of their polygon.
Result (me) Result (me)
---C++: return const & ---C++: return const &
---Purpose: Gives the Mesh data structure. ---Purpose: Gives the Mesh data structure.
@ -149,10 +129,6 @@ class Delaun from BRepMesh
---Purpose: Computes the triangulation and add the vertices ---Purpose: Computes the triangulation and add the vertices
-- edges and triangles to the Mesh data structure. -- edges and triangles to the Mesh data structure.
ReCompute (me : in out;
VertexIndices : in out Array1OfInteger from TColStd);
---Purpose: Clear the existing triangles and recomputes
-- the triangulation .
SuperMesh (me : in out; SuperMesh (me : in out;
theBox : Box2d from Bnd); theBox : Box2d from Bnd);
@ -196,6 +172,12 @@ class Delaun from BRepMesh
is private; is private;
Perform (me: in out;
theBndBox : out Box2d from Bnd;
theVertexIndices: out Array1OfInteger from TColStd)
is private;
Contains (me; Contains (me;
TrianIndex : Integer from Standard; TrianIndex : Integer from Standard;
theVertex : in Vertex from BRepMesh; theVertex : in Vertex from BRepMesh;
@ -206,12 +188,12 @@ class Delaun from BRepMesh
-- <edgeOn>. -- <edgeOn>.
returns Boolean from Standard; returns Boolean from Standard;
TriangleContaining
(me : in out; CreateTrianglesOnNewVertices(me : in out;
theVertex : in Vertex from BRepMesh) theVertexIndices: out Array1OfInteger from TColStd)
---Purpose: Gives the index of triangle containing --vertex : in Vertex from BRepMesh;
-- geometricaly <theVertex>. ---Purpose: Creates the triangles on new nodes
returns Integer from Standard; is private;
fields MeshData : DataStructureOfDelaun from BRepMesh; fields MeshData : DataStructureOfDelaun from BRepMesh;

View File

@ -13,6 +13,7 @@
#include <Bnd_Box2d.hxx> #include <Bnd_Box2d.hxx>
#include <gp.hxx> #include <gp.hxx>
#include <TColStd_MapOfInteger.hxx> #include <TColStd_MapOfInteger.hxx>
#include <TColStd_Array1OfBoolean.hxx>
#include <BRepMesh_MapOfIntegerInteger.hxx> #include <BRepMesh_MapOfIntegerInteger.hxx>
#include <BRepMesh_HeapSortIndexedVertexOfDelaun.hxx> #include <BRepMesh_HeapSortIndexedVertexOfDelaun.hxx>
#include <BRepMesh_ComparatorOfIndexedVertexOfDelaun.hxx> #include <BRepMesh_ComparatorOfIndexedVertexOfDelaun.hxx>
@ -20,6 +21,8 @@
#include <BRepMesh_SelectorOfDataStructureOfDelaun.hxx> #include <BRepMesh_SelectorOfDataStructureOfDelaun.hxx>
#include <BRepMesh_HeapSortVertexOfDelaun.hxx> #include <BRepMesh_HeapSortVertexOfDelaun.hxx>
#include <BRepMesh_ComparatorOfVertexOfDelaun.hxx> #include <BRepMesh_ComparatorOfVertexOfDelaun.hxx>
#include <TColgp_Array1OfXY.hxx>
#include <TColStd_Array1OfReal.hxx>
typedef TColStd_ListIteratorOfListOfInteger IteratorOnListOfInteger; typedef TColStd_ListIteratorOfListOfInteger IteratorOnListOfInteger;
typedef TColStd_ListOfInteger ListOfInteger; typedef TColStd_ListOfInteger ListOfInteger;
@ -95,16 +98,7 @@ void BRepMesh_Delaun::Init(BRepMesh_Array1OfVertexOfDelaun& Vertices)
vertexIndices(niver)=MeshData->AddNode(Vertices(niver)); vertexIndices(niver)=MeshData->AddNode(Vertices(niver));
} }
theBox.Enlarge(Precision::PConfusion()); Perform(theBox, vertexIndices);
SuperMesh(theBox);
BRepMesh_HeapSortIndexedVertexOfDelaun::Sort
(vertexIndices,
BRepMesh_ComparatorOfIndexedVertexOfDelaun(SortingDirection,
Precision::PConfusion(),
MeshData));
Compute(vertexIndices);
} }
@ -126,17 +120,26 @@ BRepMesh_Delaun::BRepMesh_Delaun
theBox.Add(gp_Pnt2d(GetVertex(VertexIndices(niver)).Coord())); theBox.Add(gp_Pnt2d(GetVertex(VertexIndices(niver)).Coord()));
} }
theBox.Enlarge(Precision::PConfusion()); Perform(theBox, VertexIndices);
SuperMesh(theBox); }
}
//=======================================================================
//function : Perform
//purpose :
//=======================================================================
void BRepMesh_Delaun::Perform (Bnd_Box2d& theBndBox, TColStd_Array1OfInteger& theVertexIndices)
{
theBndBox.Enlarge(Precision::PConfusion());
SuperMesh(theBndBox);
BRepMesh_HeapSortIndexedVertexOfDelaun::Sort BRepMesh_HeapSortIndexedVertexOfDelaun::Sort
(VertexIndices, (theVertexIndices,
BRepMesh_ComparatorOfIndexedVertexOfDelaun(SortingDirection, BRepMesh_ComparatorOfIndexedVertexOfDelaun(SortingDirection,
Precision::PConfusion(), Precision::PConfusion(),
MeshData)); MeshData));
Compute(VertexIndices); Compute(theVertexIndices);
}
} }
//======================================================================= //=======================================================================
@ -160,87 +163,17 @@ void BRepMesh_Delaun::Compute (TColStd_Array1OfInteger& VertexIndices)
Standard_Integer iVert=VertexIndices.Lower(); Standard_Integer iVert=VertexIndices.Lower();
CreateTriangles(VertexIndices(iVert), loopEdges); CreateTriangles(VertexIndices(iVert), loopEdges);
// Insertion of nodes : CreateTrianglesOnNewVertices(VertexIndices);
Standard_Boolean modif=Standard_True;
Standard_Integer edgeOn, triPerce;
Standard_Integer aVertIdx;
for (iVert++; iVert<=VertexIndices.Upper(); iVert++) {
aVertIdx = VertexIndices(iVert);
const BRepMesh_Vertex& refToVert=GetVertex(aVertIdx);
loopEdges.Clear();
// List of indices of circles containing the node :
BRepMesh_ListOfInteger& cirL=tCircles.Select(refToVert.Coord());
BRepMesh_ListOfInteger::Iterator itT(cirL);
edgeOn=0;
triPerce=0;
for (; itT.More(); itT.Next()) {
// To add a node in the mesh it is necessary to check to conditions // To add a node in the mesh it is necessary to check to conditions
// - the node should be located on the border of the mesh and in an existing triangle // - the node should be located on the border of the mesh and in an existing triangle
// - all adjacent triangles should belong to a component connected with this triangle // - all adjacent triangles should belong to a component connected with this triangle
if (Contains(itT.Value(), refToVert, edgeOn)) { /* if (Contains(itT.Value(), refToVert, edgeOn)) {
triPerce=itT.Value(); triPerce=itT.Value();
cirL.Remove(itT); cirL.Remove(itT);
break; break;
} }*/
} // Insertion of nodes :
if (triPerce>0) {
DeleteTriangle(triPerce, loopEdges);
modif=Standard_True;
while (modif && !cirL.IsEmpty()) {
modif=Standard_False;
BRepMesh_ListOfInteger::Iterator itT1(cirL);
for (; itT1.More(); itT1.Next()) {
GetTriangle(itT1.Value()).Edges(e1,e2,e3,o1,o2,o3);
if (loopEdges.IsBound(e1) ||
loopEdges.IsBound(e2) ||
loopEdges.IsBound(e3)) {
modif=Standard_True;
DeleteTriangle(itT1.Value(), loopEdges);
cirL.Remove(itT1);
break;
}
}
}
#ifdef TRIANGULATION_DEBUG
if (Triangulation_Trace>0) {
cout << " creation triangle avec le vertex: ";
cout << refToVert.Coord().X() << " " << refToVert.Coord().Y() << endl;
}
#endif
// Creation of triangles with the current node
// and free edges and removal of these edges from the list of free edges
CreateTriangles(aVertIdx, loopEdges);
}
}
// check that internal edges are not crossed by triangles
BRepMesh_MapOfInteger::Iterator itFr(InternalEdges());
// destruction of triancles intersecting internal edges
// and their replacement by makeshift triangles
Standard_Integer nbc;
itFr.Reset();
for (; itFr.More(); itFr.Next()) {
nbc = MeshData->ElemConnectedTo(itFr.Key()).Extent();
if (nbc == 0) {
MeshLeftPolygonOf(itFr.Key(), Standard_True);
MeshLeftPolygonOf(itFr.Key(), Standard_False);
}
}
// adjustment of meshes to boundary edges
FrontierAdjust();
} }
// destruction of triangles containing a top of the super triangle // destruction of triangles containing a top of the super triangle
@ -269,22 +202,6 @@ void BRepMesh_Delaun::Compute (TColStd_Array1OfInteger& VertexIndices)
} }
//=======================================================================
//function : ReCompute
//purpose :
//=======================================================================
void BRepMesh_Delaun::ReCompute (TColStd_Array1OfInteger& VertexIndices)
{
MeshData->ClearDomain();
// Initialisation du CircleTool :
tCircles.Initialize(VertexIndices.Length());
if (VertexIndices.Length()>2)
Compute(VertexIndices);
}
//======================================================================= //=======================================================================
//function : FrontierAdjust //function : FrontierAdjust
//purpose : //purpose :
@ -297,7 +214,13 @@ void BRepMesh_Delaun::FrontierAdjust()
BRepMesh_ListOfInteger::Iterator itconx; BRepMesh_ListOfInteger::Iterator itconx;
ListOfInteger tril; ListOfInteger tril;
// find external triangles on boundary edges Standard_Integer pass = 1;
for (; pass <= 2; pass++ )
{
// 1 pass): find external triangles on boundary edges
// 2 pass): find external triangles on boundary edges
// because in comlex curved boundaries external triangles can appear
// after "mesh left polygon"
BRepMesh_MapOfInteger::Iterator itFr(Frontier()); BRepMesh_MapOfInteger::Iterator itFr(Frontier());
for (; itFr.More(); itFr.Next()) { for (; itFr.More(); itFr.Next()) {
const BRepMesh_PairOfIndex& aPair = MeshData->ElemConnectedTo(itFr.Key()); const BRepMesh_PairOfIndex& aPair = MeshData->ElemConnectedTo(itFr.Key());
@ -332,13 +255,24 @@ void BRepMesh_Delaun::FrontierAdjust()
// destruction of triangles crossing the boundary edges and // destruction of triangles crossing the boundary edges and
// their replacement by makeshift triangles // their replacement by makeshift triangles
if ( pass == 1 )
{
itFr.Reset(); itFr.Reset();
}
else
{
// in some cases there remain unused boundaries check
itFr.Initialize(Frontier());
}
for (; itFr.More(); itFr.Next()) { for (; itFr.More(); itFr.Next()) {
if (MeshData->ElemConnectedTo(itFr.Key()).IsEmpty()) { if (MeshData->ElemConnectedTo(itFr.Key()).IsEmpty()) {
MeshLeftPolygonOf(itFr.Key(), Standard_True); MeshLeftPolygonOf(itFr.Key(), Standard_True);
} }
} }
if ( pass == 2 ) break;
// After this processing there sometimes remain triangles outside boundaries. // After this processing there sometimes remain triangles outside boundaries.
// Destruction of these triangles : // Destruction of these triangles :
Standard_Integer nbFront; Standard_Integer nbFront;
@ -402,8 +336,9 @@ void BRepMesh_Delaun::FrontierAdjust()
if (kk == 0) break; if (kk == 0) break;
} }
}
// find external triangles on boundary edges /* // find external triangles on boundary edges
// because in comlex curved boundaries external triangles can appear // because in comlex curved boundaries external triangles can appear
// after "mesh left polygon" // after "mesh left polygon"
for (itFr.Initialize(Frontier()); itFr.More(); itFr.Next()) { for (itFr.Initialize(Frontier()); itFr.More(); itFr.Next()) {
@ -440,7 +375,7 @@ void BRepMesh_Delaun::FrontierAdjust()
if (MeshData->ElemConnectedTo(itFr.Key()).IsEmpty()) { if (MeshData->ElemConnectedTo(itFr.Key()).IsEmpty()) {
MeshLeftPolygonOf(itFr.Key(), Standard_True); MeshLeftPolygonOf(itFr.Key(), Standard_True);
} }
} } */
} }
@ -913,54 +848,30 @@ void BRepMesh_Delaun::CreateTriangles (const Standard_Integer theVertexIndex,
} }
//======================================================================= //=======================================================================
//function : DeleteTriangle //function : CreateTrianglesOnNewVertices
//purpose : The concerned triangles are deleted and the freed edges are added in //purpose : Creation of triangles from the new nodes
// <loopEdges>. If an edge is added twice, it does not exist and
// it is necessary to destroy it. This corresponds to the destruction of two
// connected triangles.
//======================================================================= //=======================================================================
void BRepMesh_Delaun::CreateTrianglesOnNewVertices (TColStd_Array1OfInteger& theVertexIndices)
void BRepMesh_Delaun::DeleteTriangle (const Standard_Integer tIndex,
BRepMesh_MapOfIntegerInteger& fEdges)
{ {
tCircles.Delete(tIndex); BRepMesh_MapOfIntegerInteger loopEdges(10,MeshData->Allocator());
Standard_Integer fe1, fe2, fe3; Standard_Integer iVert;
Standard_Boolean or1, or2, or3; // Insertion of nodes :
GetTriangle(tIndex).Edges(fe1, fe2, fe3, or1, or2, or3); Standard_Boolean modif=Standard_True;
MeshData->RemoveElement(tIndex); Standard_Integer edgon, triPer;
if (!fEdges.Bind(fe1, or1)) {
fEdges.UnBind(fe1);
MeshData->RemoveLink(fe1);
}
if (!fEdges.Bind(fe2, or2)) {
fEdges.UnBind(fe2);
MeshData->RemoveLink(fe2);
}
if (!fEdges.Bind(fe3, or3)) {
fEdges.UnBind(fe3);
MeshData->RemoveLink(fe3);
}
}
//=======================================================================
//function : AddVertex
//purpose :
//=======================================================================
void BRepMesh_Delaun::AddVertex(const BRepMesh_Vertex& theVert)
{
Standard_Integer nv = MeshData->AddNode(theVert);
// Iterator in the list of indexes of circles containing the node :
BRepMesh_ListOfInteger& cirL=tCircles.Select(theVert.Coord());
Standard_Integer edgon=0;
Standard_Integer triPer=0;
Standard_Integer e1, e2, e3; Standard_Integer e1, e2, e3;
Standard_Boolean o1, o2, o3; Standard_Boolean o1, o2, o3;
Standard_Integer aVertIdx;
for( iVert = theVertexIndices.Lower(); iVert<=theVertexIndices.Upper(); iVert++ )
{
loopEdges.Clear();
edgon = 0, triPer = 0;
aVertIdx = theVertexIndices(iVert);
const BRepMesh_Vertex& aVert = GetVertex(aVertIdx);
// Iterator in the list of indexes of circles containing the node
BRepMesh_ListOfInteger& cirL=tCircles.Select(aVert.Coord());
BRepMesh_ListOfInteger::Iterator itT(cirL); BRepMesh_ListOfInteger::Iterator itT(cirL);
for (; itT.More(); itT.Next()) { for (; itT.More(); itT.Next()) {
@ -968,7 +879,7 @@ void BRepMesh_Delaun::AddVertex(const BRepMesh_Vertex& theVert)
// To add a node in the mesh it is necessary to check conditions: // To add a node in the mesh it is necessary to check conditions:
// - the node should be within the boundaries of the mesh and so in an existing triangle // - the node should be within the boundaries of the mesh and so in an existing triangle
// - all adjacent triangles should belong to a component connected with this triangle // - all adjacent triangles should belong to a component connected with this triangle
if (Contains(itT.Value(), theVert, edgon)) { if (Contains(itT.Value(), aVert, edgon)) {
if (edgon==0) { if (edgon==0) {
triPer=itT.Value(); triPer=itT.Value();
cirL.Remove(itT); cirL.Remove(itT);
@ -983,16 +894,14 @@ void BRepMesh_Delaun::AddVertex(const BRepMesh_Vertex& theVert)
} }
if (triPer>0) { if (triPer>0) {
BRepMesh_MapOfIntegerInteger loopEdges(10,MeshData->Allocator());
DeleteTriangle(triPer, loopEdges); DeleteTriangle(triPer, loopEdges);
Standard_Boolean modif=Standard_True; modif=Standard_True;
while (modif && !cirL.IsEmpty()) { while (modif && !cirL.IsEmpty()) {
modif=Standard_False; modif=Standard_False;
BRepMesh_ListOfInteger::Iterator itT1(cirL); BRepMesh_ListOfInteger::Iterator itT1(cirL);
for (; itT1.More(); itT1.Next()) { for (; itT1.More(); itT1.Next()) {
GetTriangle(itT.Value()).Edges(e1,e2,e3,o1,o2,o3); GetTriangle(itT1.Value()).Edges(e1,e2,e3,o1,o2,o3);
if (loopEdges.IsBound(e1) || if (loopEdges.IsBound(e1) ||
loopEdges.IsBound(e2) || loopEdges.IsBound(e2) ||
loopEdges.IsBound(e3)) { loopEdges.IsBound(e3)) {
@ -1006,14 +915,16 @@ void BRepMesh_Delaun::AddVertex(const BRepMesh_Vertex& theVert)
// Creation of triangles with the current node and free edges // Creation of triangles with the current node and free edges
// and removal of these edges from the list of free edges // and removal of these edges from the list of free edges
CreateTriangles(nv, loopEdges); CreateTriangles(aVertIdx, loopEdges);
}
// Check that internal edges are not crossed by the triangles }
// check that internal edges are not crossed by triangles
BRepMesh_MapOfInteger::Iterator itFr(InternalEdges()); BRepMesh_MapOfInteger::Iterator itFr(InternalEdges());
// Destruction of triangles crossing internal edges and // destruction of triancles intersecting internal edges
// their replacement by makeshift triangles // and their replacement by makeshift triangles
Standard_Integer nbc; Standard_Integer nbc;
itFr.Reset(); itFr.Reset();
for (; itFr.More(); itFr.Next()) { for (; itFr.More(); itFr.Next()) {
nbc = MeshData->ElemConnectedTo(itFr.Key()).Extent(); nbc = MeshData->ElemConnectedTo(itFr.Key()).Extent();
@ -1023,10 +934,37 @@ void BRepMesh_Delaun::AddVertex(const BRepMesh_Vertex& theVert)
} }
} }
// adjustment of meshes to boundary edges
FrontierAdjust(); FrontierAdjust();
} }
//=======================================================================
//function : DeleteTriangle
//purpose : The concerned triangles are deleted and the freed edges are added in
// <loopEdges>. If an edge is added twice, it does not exist and
// it is necessary to destroy it. This corresponds to the destruction of two
// connected triangles.
//=======================================================================
void BRepMesh_Delaun::DeleteTriangle (const Standard_Integer tIndex,
BRepMesh_MapOfIntegerInteger& fEdges)
{
tCircles.Delete(tIndex);
TColStd_Array1OfInteger fe(1,3);
TColStd_Array1OfBoolean ornt(1,3);
GetTriangle(tIndex).Edges(fe(1), fe(2), fe(3), ornt(1), ornt(2), ornt(3));
MeshData->RemoveElement(tIndex);
Standard_Integer i = 1;
for(; i <= 3; i++ )
{
if (!fEdges.Bind(fe(i), ornt(i)))
{
fEdges.UnBind(fe(i));
MeshData->RemoveLink(fe(i));
}
}
} }
//======================================================================= //=======================================================================
@ -1107,218 +1045,14 @@ void BRepMesh_Delaun::AddVertices(BRepMesh_Array1OfVertexOfDelaun& vertices)
(vertices, (vertices,
BRepMesh_ComparatorOfVertexOfDelaun(SortingDirection, Precision::PConfusion())); BRepMesh_ComparatorOfVertexOfDelaun(SortingDirection, Precision::PConfusion()));
BRepMesh_MapOfIntegerInteger loopEdges(10,MeshData->Allocator());
Standard_Boolean modif=Standard_True;
Standard_Integer edgon, triPer;
Standard_Integer e1, e2, e3;
Standard_Boolean o1, o2, o3;
Standard_Integer niver; Standard_Integer niver;
Standard_Integer aIdxVert;
for (niver=vertices.Lower(); niver<=vertices.Upper(); niver++) {
aIdxVert = MeshData->AddNode(vertices(niver));
// Iterator in the list of indexes of circles containing the node TColStd_Array1OfInteger vertexIndices(vertices.Lower(), vertices.Upper());
BRepMesh_ListOfInteger& cirL=tCircles.Select(vertices(niver).Coord());
edgon=0; for (niver=vertices.Lower(); niver<=vertices.Upper(); niver++)
triPer=0; vertexIndices(niver)=MeshData->AddNode(vertices(niver));
BRepMesh_ListOfInteger::Iterator itT(cirL); CreateTrianglesOnNewVertices(vertexIndices);
for (; itT.More(); itT.Next()) {
// To add a node in the mesh it is necessary to check conditions:
// - the node should be within the boundaries of the mesh and so in an existing triangle
// - all adjacent triangles should belong to a component connected with this triangle
if (Contains(itT.Value(), vertices(niver), edgon)) {
if (edgon==0) {
triPer=itT.Value();
cirL.Remove(itT);
break;
}
else if (GetEdge(edgon).Movability()==BRepMesh_Free) {
triPer=itT.Value();
cirL.Remove(itT);
break;
}
}
}
if (triPer>0) {
DeleteTriangle(triPer, loopEdges);
modif=Standard_True;
while (modif && !cirL.IsEmpty()) {
modif=Standard_False;
BRepMesh_ListOfInteger::Iterator itT1(cirL);
for (; itT1.More(); itT1.Next()) {
GetTriangle(itT1.Value()).Edges(e1,e2,e3,o1,o2,o3);
if (loopEdges.IsBound(e1) ||
loopEdges.IsBound(e2) ||
loopEdges.IsBound(e3)) {
modif=Standard_True;
DeleteTriangle(itT1.Value(), loopEdges);
cirL.Remove(itT1);
break;
}
}
}
// Creation of triangles with the current node and free edges
// and removal of these edges from the list of free edges
CreateTriangles(aIdxVert, loopEdges);
}
}
// Check that internal edges are not crossed by triangles
BRepMesh_MapOfInteger::Iterator itFr(InternalEdges());
// Destruction of triangles crossing internal edges
//and their replacement by makeshift triangles
Standard_Integer nbc;
itFr.Reset();
for (; itFr.More(); itFr.Next()) {
nbc = MeshData->ElemConnectedTo(itFr.Key()).Extent();
if (nbc == 0) {
MeshLeftPolygonOf(itFr.Key(), Standard_True);
MeshLeftPolygonOf(itFr.Key(), Standard_False);
}
}
// Adjustment of meshes to boundary edges
FrontierAdjust();
}
//=======================================================================
//function : RevertDiagonal
//purpose :
//=======================================================================
Standard_Boolean BRepMesh_Delaun::RevertDiagonal(const Standard_Integer ind)
{
const BRepMesh_PairOfIndex& elConx = MeshData->ElemConnectedTo(ind);
const BRepMesh_Edge& lEdge = GetEdge(ind);
if (elConx.Extent()==2 && lEdge.Movability()==BRepMesh_Free) {
Standard_Integer t1(elConx.FirstIndex());
Standard_Integer t2(elConx.LastIndex());
Standard_Integer e1t1, e2t1, e3t1, e1t2, e2t2, e3t2 ;
Standard_Boolean o1t1, o2t1, o3t1, o1t2, o2t2, o3t2;
#ifndef DEB
Standard_Integer ed13=0, ed23=0, ed14=0, ed24=0, v1, v2, v3=0, v4=0, vc1;
Standard_Boolean oindt1=Standard_False, or13=Standard_False,
or23=Standard_False, or14=Standard_False, or24=Standard_False, orien;
#else
Standard_Integer ed13, ed23, ed14, ed24, v1, v2, v3, v4, vc1;
Standard_Boolean oindt1, or13, or23, or14, or24, orien;
#endif
GetTriangle(t1).Edges(e1t1, e2t1, e3t1, o1t1, o2t1, o3t1);
GetTriangle(t2).Edges(e1t2, e2t2, e3t2, o1t2, o2t2, o3t2);
v1=lEdge.FirstNode(); v2=lEdge.LastNode();
if (e1t1==ind) {
if (o2t1) v3 =GetEdge(e2t1).LastNode();
else v3 =GetEdge(e2t1).FirstNode();
ed13=e3t1; ed23=e2t1;
or13=o3t1; or23=o2t1;
oindt1=o1t1;
}
else if (e2t1==ind) {
if (o3t1) v3 =GetEdge(e3t1).LastNode();
else v3 =GetEdge(e3t1).FirstNode();
ed13=e1t1; ed23=e3t1;
or13=o1t1; or23=o3t1;
oindt1=o2t1;
}
else if (e3t1==ind) {
if (o1t1) v3 =GetEdge(e1t1).LastNode();
else v3 =GetEdge(e1t1).FirstNode();
ed13=e2t1; ed23=e1t1;
or13=o2t1; or23=o1t1;
oindt1=o3t1;
}
if (e1t2==ind) {
if (o2t2) v4 =GetEdge(e2t2).LastNode();
else v4 =GetEdge(e2t2).FirstNode();
ed14=e2t2; ed24=e3t2;
or14=o2t2; or24=o3t2;
}
else if (e2t2==ind) {
if (o3t2) v4 =GetEdge(e3t2).LastNode();
else v4 =GetEdge(e3t2).FirstNode();
ed14=e3t2; ed24=e1t2;
or14=o3t2; or24=o1t2;
}
else if (e3t2==ind) {
if (o1t2) v4 =GetEdge(e1t2).LastNode();
else v4 =GetEdge(e1t2).FirstNode();
ed14=e1t2; ed24=e2t2;
or14=o1t2; or24=o2t2;
}
if (!oindt1) {
vc1=v3; v3=v4; v4=vc1;
vc1=ed13; ed13=ed24; ed24=vc1;
orien =or13; or13=or24; or24=orien ;
vc1=ed14; ed14=ed23; ed23=vc1;
orien =or14; or14=or23; or23=orien ;
}
const BRepMesh_Vertex& vert1 = GetVertex(v1);
const BRepMesh_Vertex& vert2 = GetVertex(v2);
const BRepMesh_Vertex& vert3 = GetVertex(v3);
const BRepMesh_Vertex& vert4 = GetVertex(v4);
gp_XY ved13(vert1.Coord()); ved13.Subtract(vert3.Coord());
gp_XY ved14(vert4.Coord()); ved14.Subtract(vert1.Coord());
gp_XY ved23(vert3.Coord()); ved23.Subtract(vert2.Coord());
gp_XY ved24(vert2.Coord()); ved24.Subtract(vert4.Coord());
Standard_Real z13, z24, modul;
z13=z24=0.;
modul=ved13.Modulus();
if (modul>Precision::PConfusion()) {
ved13.SetCoord(ved13.X()/modul, ved13.Y()/modul);
z13=ved13^ved14;
}
modul=ved24.Modulus();
if (modul>Precision::PConfusion()) {
ved24.SetCoord(ved24.X()/modul, ved24.Y()/modul);
z24=ved24^ved23;
}
if (Abs(z13)>=Precision::PConfusion()&&Abs(z24)>=Precision::PConfusion()) {
if ((z13>0. && z24>0.) || (z13<0. && z24<0.)) {
tCircles.Delete(t1);
tCircles.Delete(t2);
if (!tCircles.Add(vert4.Coord(), vert2.Coord(), vert3.Coord(), t1) &&
!tCircles.Add(vert3.Coord(), vert1.Coord(), vert4.Coord(), t2)) {
Standard_Integer newd=ind;
BRepMesh_Edge newEdg=BRepMesh_Edge(v3, v4, BRepMesh_Free);
if (!MeshData->SubstituteLink(newd, newEdg)) {
newd=MeshData->IndexOf(newEdg);
MeshData->RemoveLink(ind);
}
MeshData->SubstituteElement(t1, BRepMesh_Triangle(ed24, ed23, newd,
or24, or23, Standard_True,
BRepMesh_Free));
MeshData->SubstituteElement(t2, BRepMesh_Triangle(ed13, ed14, newd,
or13, or14, Standard_False,
BRepMesh_Free));
return Standard_True;
}
else {
if (oindt1) {
tCircles.Add(vert1.Coord(), vert2.Coord(), vert3.Coord(), t1);
tCircles.Add(vert2.Coord(), vert1.Coord(), vert4.Coord(), t2);
}
else {
tCircles.Add(vert1.Coord(), vert2.Coord(), vert3.Coord(), t2);
tCircles.Add(vert2.Coord(), vert1.Coord(), vert4.Coord(), t1);
}
}
}
}
}
return Standard_False;
} }
//======================================================================= //=======================================================================
@ -1394,46 +1128,6 @@ Standard_Boolean BRepMesh_Delaun::UseEdge(const Standard_Integer ind)
return Standard_False; return Standard_False;
} }
//=======================================================================
//function : SmoothMesh
//purpose :
//=======================================================================
void BRepMesh_Delaun::SmoothMesh(const Standard_Real Epsilon)
{
Standard_Integer baryVert, polyVert, nbPolyVert;
Standard_Real uSom, vSom, newU, newV;
Standard_Integer nbVert=MeshData->NbNodes();
BRepMesh_ListOfInteger::Iterator itNeig;
uSom=vSom=0;
for (baryVert=1; baryVert<=nbVert; baryVert++) {
const BRepMesh_Vertex& curVert=GetVertex(baryVert);
if (curVert.Movability()==BRepMesh_Free) {
const BRepMesh_ListOfInteger& neighEdg=MeshData->LinkNeighboursOf(baryVert);
if (neighEdg.Extent()>2) {
nbPolyVert=0;
for (itNeig.Init(neighEdg); itNeig.More(); itNeig.Next()) {
const BRepMesh_Edge& nedg=GetEdge(itNeig.Value());
polyVert=nedg.FirstNode();
if (polyVert==baryVert) polyVert=nedg.LastNode();
nbPolyVert++;
const gp_XY& pVal = GetVertex(polyVert).Coord();
uSom+=pVal.X();
vSom+=pVal.Y();
}
if (nbPolyVert>2) {
newU=uSom/(Standard_Real)nbPolyVert;
newV=vSom/(Standard_Real)nbPolyVert;
if (!curVert.Coord().IsEqual(gp_XY(newU, newV), Epsilon)) {
BRepMesh_Vertex newVert(newU, newV, curVert.Movability());
MeshData->MoveNode(baryVert, newVert);
}
}
}
}
}
}
//======================================================================= //=======================================================================
//function : Result //function : Result
//purpose : //purpose :
@ -1499,103 +1193,92 @@ const BRepMesh_MapOfInteger& BRepMesh_Delaun::FreeEdges ()
//function : Contains //function : Contains
//purpose : //purpose :
//======================================================================= //=======================================================================
static Standard_Real calculateDist(const TColgp_Array1OfXY& E,
const TColgp_Array1OfXY& P,
const TColStd_Array1OfInteger& e,
const BRepMesh_Vertex& vert,
TColStd_Array1OfReal& v,
TColStd_Array1OfReal& mode,
Standard_Integer& edgOn)
{
Standard_Real distMin = -1;
Standard_Integer i = 1;
for(; i <= 3; i++ )
{
mode(i) = E(i).SquareModulus();
if (mode(i) <= EPSEPS) return -1;
v(i) = E(i)^(vert.Coord()-P(i));
Standard_Real dist = (v(i)*v(i))/mode(i);
if ( distMin < 0 || dist < distMin )
{
edgOn = e(i);
distMin = dist;
}
}
return distMin;
}
Standard_Boolean BRepMesh_Delaun::Contains(const Standard_Integer tri, Standard_Boolean BRepMesh_Delaun::Contains(const Standard_Integer tri,
const BRepMesh_Vertex& vert, const BRepMesh_Vertex& vert,
Standard_Integer& edgOn)const Standard_Integer& edgOn)const
{ {
edgOn = 0; edgOn = 0;
Standard_Integer e1, e2, e3, p1, p2, p3; TColStd_Array1OfInteger e(1,3);
Standard_Boolean o1, o2, o3; TColStd_Array1OfInteger p(1,3);
GetTriangle(tri).Edges(e1, e2, e3, o1, o2, o3); TColStd_Array1OfBoolean o(1,3);
const BRepMesh_Edge& edg1=GetEdge(e1); GetTriangle(tri).Edges(e(1), e(2), e(3), o(1), o(2), o(3));
const BRepMesh_Edge& edg2=GetEdge(e2); const BRepMesh_Edge* edg[3] = { &GetEdge(e(1)),
const BRepMesh_Edge& edg3=GetEdge(e3); &GetEdge(e(2)),
if (o1) { &GetEdge(e(3)) };
p1=edg1.FirstNode(); if (o(1)) {
p2=edg1.LastNode(); p(1) = edg[0]->FirstNode();
p(2) = edg[0]->LastNode();
} }
else { else {
p2=edg1.FirstNode(); p(2) = edg[0]->FirstNode();
p1=edg1.LastNode(); p(1) = edg[0]->LastNode();
} }
if (o3) p3=edg3.FirstNode(); if (o(3)) p(3) = edg[2]->FirstNode();
else p3=edg3.LastNode(); else p(3) = edg[2]->LastNode();
const gp_XY& P1=GetVertex(p1).Coord(); TColgp_Array1OfXY P(1,3);
const gp_XY& P2=GetVertex(p2).Coord(); P(1) = GetVertex(p(1)).Coord();
const gp_XY& P3=GetVertex(p3).Coord(); P(2) = GetVertex(p(2)).Coord();
gp_XY E1(P2); E1.Subtract(P1); P(3) = GetVertex(p(3)).Coord();
gp_XY E2(P3); E2.Subtract(P2);
gp_XY E3(P1); E3.Subtract(P3);
Standard_Real mode1=E1.SquareModulus(); TColgp_Array1OfXY E(1,3);
//Standard_Real dist=Sqrt(mode1); E(1) = P(2); E(1).Subtract(P(1));
if (mode1<=EPSEPS) return Standard_False; E(2) = P(3); E(2).Subtract(P(2));
Standard_Real v1=E1^(vert.Coord()-P1); E(3) = P(1); E(3).Subtract(P(3));
Standard_Real distMin=(v1*v1)/mode1;
edgOn=e1;
Standard_Real mode2=E2.SquareModulus(); Standard_Real distMin;
Standard_Real dist; TColStd_Array1OfReal v (1,3);
//dist=Sqrt(mode2); TColStd_Array1OfReal mode(1,3);
if (mode2<=EPSEPS) return Standard_False;
Standard_Real v2=E2^(vert.Coord()-P2);
dist=(v2*v2)/mode2;
if (dist<distMin) {
edgOn=e2;
distMin=dist;
}
Standard_Real mode3=E3.SquareModulus(); distMin = calculateDist(E, P, e, vert, v, mode, edgOn);
//dist=Sqrt(mode3); if ( distMin < 0 )
if (mode3<=EPSEPS) return Standard_False; return Standard_False;
Standard_Real v3=E3^(vert.Coord()-P3);
dist=(v3*v3)/mode3;
if (dist<distMin) {
edgOn=e3;
distMin=dist;
}
if ( distMin > EPSEPS ) { if ( distMin > EPSEPS ) {
Standard_Integer edf = edgOn; Standard_Integer edf = edgOn;
edgOn = 0; edgOn = 0;
if (edf==e1 && edg1.Movability()!=BRepMesh_Free) { if ( edf != 0 )
if (v1<(mode1/5.)) edgOn=e1;
}
else if (edf==e2 && edg2.Movability()!=BRepMesh_Free) {
if (v2<(mode2/5.)) edgOn=e2;
}
else if (edf==e3 && edg3.Movability()!=BRepMesh_Free) {
if (v3<(mode3/5.)) edgOn=e3;
}
}
return (v1+v2+v3!=0. &&((v1>=0. && v2>=0. && v3>=0.) ||
(v1<=0. && v2<=0. && v3<=0.)));
}
//=======================================================================
//function : TriangleContaining
//purpose :
//=======================================================================
Standard_Integer BRepMesh_Delaun::TriangleContaining(const BRepMesh_Vertex& vert)
{ {
const BRepMesh_ListOfInteger& cirL=tCircles.Select(vert.Coord()); Standard_Integer i = 1;
for(; i <= 3; i++ )
{
if( edf == e(i) )
break;
}
BRepMesh_ListOfInteger::Iterator itT(cirL); if( edg[i-1]->Movability() != BRepMesh_Free )
Standard_Integer triPer=0; if ( v(i) < (mode(i)/5.) ) edgOn = e(i);
Standard_Integer edgon=0;
for (; itT.More(); itT.Next()) {
if (Contains(itT.Value(), vert, edgon)) {
if (edgon==0) {
triPer=itT.Value();
break;
}
else if (GetEdge(edgon).Movability()==BRepMesh_Free) {
triPer=itT.Value();
break;
} }
} }
return (v(1)+v(2)+v(3) != 0. && ((v(1) >= 0. && v(2) >= 0. && v(3) >= 0.) ||
(v(1) <= 0. && v(2) <= 0. && v(3) <= 0.)));
} }
return triPer;
}

View File

@ -128,6 +128,18 @@ is
last : Real from Standard) last : Real from Standard)
returns Boolean is private; returns Boolean is private;
RelativeEdgeDeflection(myclass;
edge : Edge from TopoDS;
defle : Real from Standard;
dtotale : Real from Standard;
cdef : out Real from Standard)
---Purpose: Returns computed relative deflection for edge
returns Real from Standard;
BoxMaxDimension(myclass;
box : in Box from Bnd;
maxdim : out Real from Standard);
---Purpose: Returns the maximal dimension of Bnd_Box
InternalVertices InternalVertices
(me : mutable; (me : mutable;

View File

@ -126,16 +126,8 @@ BRepMesh_FastDiscret::BRepMesh_FastDiscret(const Standard_Real theDefle,
myInshape(theInshape) myInshape(theInshape)
{ {
myAllocator = new NCollection_IncAllocator(64000); myAllocator = new NCollection_IncAllocator(64000);
if (theRelative) if(myRelative)
{ BoxMaxDimension(theBox, myDtotale);
Standard_Real TXmin, TYmin, TZmin, TXmax, TYmax, TZmax;
theBox.Get(TXmin, TYmin, TZmin, TXmax, TYmax, TZmax);
myDtotale = TXmax-TXmin;
const Standard_Real dy = TYmax-TYmin;
const Standard_Real dz = TZmax-TZmin;
if (dy > myDtotale) myDtotale = dy;
if (dz > myDtotale) myDtotale = dz;
}
} }
//======================================================================= //=======================================================================
@ -156,17 +148,55 @@ BRepMesh_FastDiscret::BRepMesh_FastDiscret(const Standard_Real theDefle,
myInshape(theInshape) myInshape(theInshape)
{ {
myAllocator = new NCollection_IncAllocator(64000); myAllocator = new NCollection_IncAllocator(64000);
if (theRelative) if(myRelative)
BoxMaxDimension(theBox, myDtotale);
Perform(theShape);
}
//=======================================================================
//function : BoxMaxDimension
//purpose :
//=======================================================================
void BRepMesh_FastDiscret::BoxMaxDimension(const Bnd_Box& theBox, Standard_Real& theMaxDim)
{ {
if(theBox.IsVoid())
return;
Standard_Real TXmin, TYmin, TZmin, TXmax, TYmax, TZmax; Standard_Real TXmin, TYmin, TZmin, TXmax, TYmax, TZmax;
theBox.Get(TXmin, TYmin, TZmin, TXmax, TYmax, TZmax); theBox.Get(TXmin, TYmin, TZmin, TXmax, TYmax, TZmax);
myDtotale = TXmax-TXmin; theMaxDim = TXmax-TXmin;
const Standard_Real dy = TYmax-TYmin; const Standard_Real dy = TYmax-TYmin;
const Standard_Real dz = TZmax-TZmin; const Standard_Real dz = TZmax-TZmin;
if (dy > myDtotale) myDtotale = dy; if (dy > theMaxDim) theMaxDim = dy;
if (dz > myDtotale) myDtotale = dz; if (dz > theMaxDim) theMaxDim = dz;
} }
Perform(theShape);
//=======================================================================
//function : RelativeEdgeDeflection
//purpose :
//=======================================================================
Standard_Real BRepMesh_FastDiscret::RelativeEdgeDeflection(const TopoDS_Edge& theEdge,
const Standard_Real theDefle,
const Standard_Real theDTotale,
Standard_Real& theDefCoef)
{
theDefCoef = 1.;
Standard_Real defedge = theDefle;
if(theEdge.IsNull())
return defedge;
Bnd_Box B;
BRepBndLib::Add(theEdge, B);
BoxMaxDimension(B, defedge);
// adjusted in relation to the total size:
theDefCoef = theDTotale/(2*defedge);
if (theDefCoef < 0.5) theDefCoef = 0.5;
if (theDefCoef > 2.) theDefCoef = 2.;
defedge = theDefCoef * defedge * theDefle;
return defedge;
} }
//======================================================================= //=======================================================================
@ -270,7 +300,6 @@ void BRepMesh_FastDiscret::Add(const TopoDS_Face& theface)
i = 1; i = 1;
Standard_Real defedge, defface; Standard_Real defedge, defface;
Standard_Real dx, dy, dz;
Standard_Integer nbEdge = 0; Standard_Integer nbEdge = 0;
Standard_Real savangle = myAngle; Standard_Real savangle = myAngle;
Standard_Real cdef; Standard_Real cdef;
@ -301,20 +330,7 @@ void BRepMesh_FastDiscret::Add(const TopoDS_Face& theface)
defedge = P->Deflection(); defedge = P->Deflection();
} }
else { else {
Bnd_Box B; defedge = RelativeEdgeDeflection(edge, myDeflection, myDtotale, cdef);
BRepBndLib::Add(edge, B);
B.Get(aXmin, aYmin, aZmin, aXmax, aYmax, aZmax);
dx = aXmax-aXmin;
dy = aYmax-aYmin;
dz = aZmax-aZmin;
defedge = dx;
if (defedge < dy) defedge = dy;
if (defedge < dz) defedge = dz;
// adjusted in relation to the total size:
cdef = myDtotale/(2*defedge);
if (cdef < 0.5) cdef = 0.5;
if (cdef > 2.) cdef = 2.;
defedge = cdef * defedge * myDeflection;
myAngle = savangle * cdef; myAngle = savangle * cdef;
} }
defface = defface + defedge; defface = defface + defedge;
@ -510,7 +526,7 @@ void BRepMesh_FastDiscret::Add(const TopoDS_Face& theface)
BS.D0 (myumin, myvmin, P11); BS.D0 (myumin, myvmin, P11);
BS.D0 (myumin, dfvave, P21); BS.D0 (myumin, dfvave, P21);
BS.D0 (myumin, myvmax, P31); BS.D0 (myumin, myvmax, P31);
for (i1=0, dfucur=myumin; i1 <= 20; i1++, dfucur+=du) { for (i1=1, dfucur=myumin+du; i1 <= 20; i1++, dfucur+=du) {
BS.D0 (dfucur, myvmin, P12); BS.D0 (dfucur, myvmin, P12);
BS.D0 (dfucur, dfvave, P22); BS.D0 (dfucur, dfvave, P22);
BS.D0 (dfucur, myvmax, P32); BS.D0 (dfucur, myvmax, P32);
@ -523,7 +539,7 @@ void BRepMesh_FastDiscret::Add(const TopoDS_Face& theface)
BS.D0(myumin, myvmin, P11); BS.D0(myumin, myvmin, P11);
BS.D0(dfuave, myvmin, P21); BS.D0(dfuave, myvmin, P21);
BS.D0(myumax, myvmin, P31); BS.D0(myumax, myvmin, P31);
for (i1=0, dfvcur=myvmin; i1 <= 20; i1++, dfvcur+=dv) { for (i1=1, dfvcur=myvmin+dv; i1 <= 20; i1++, dfvcur+=dv) {
BS.D0 (myumin, dfvcur, P12); BS.D0 (myumin, dfvcur, P12);
BS.D0 (dfuave, dfvcur, P22); BS.D0 (dfuave, dfvcur, P22);
BS.D0 (myumax, dfvcur, P32); BS.D0 (myumax, dfvcur, P32);
@ -663,7 +679,6 @@ void BRepMesh_FastDiscret::Add(const TopoDS_Face& theface)
myStructure.Nullify(); myStructure.Nullify();
} }
//======================================================================= //=======================================================================
//function : Add //function : Add
//purpose : //purpose :

View File

@ -224,9 +224,6 @@ void BRepMesh_FastDiscretFace::Add(const TopoDS_Face& theFace
switch (thetype) switch (thetype)
{ {
case GeomAbs_Plane:
rajout = !classifier->NaturalRestriction();
break;
case GeomAbs_Sphere: case GeomAbs_Sphere:
case GeomAbs_Torus: case GeomAbs_Torus:
rajout = Standard_True; rajout = Standard_True;
@ -617,24 +614,7 @@ void BRepMesh_FastDiscretFace::InternalVertices(const Handle(BRepAdaptor_HSurfac
Standard_Real deltaX = myAttrib->GetDeltaX(); Standard_Real deltaX = myAttrib->GetDeltaX();
Standard_Real deltaY = myAttrib->GetDeltaY(); Standard_Real deltaY = myAttrib->GetDeltaY();
if (thetype == GeomAbs_Plane && !theClassifier->NaturalRestriction()) if (thetype == GeomAbs_Sphere)
{
// rajout d`un seul point au milieu.
const Standard_Real U = 0.5*(umin+umax);
const Standard_Real V = 0.5*(vmin+vmax);
if (theClassifier->Perform(gp_Pnt2d(U, V)) == TopAbs_IN)
{
// Record 3d point
BRepMesh_GeomTool::D0(theCaro, U, V, p3d);
myNbLocat++;
myLocation3d.Bind(myNbLocat, p3d);
// Record 2d point
p2d.SetCoord((U-umin)/deltaX, (V-vmin)/deltaY);
newV.Initialize(p2d.XY(), myNbLocat, BRepMesh_Free);
theInternalV.Append(newV);
}
}
else if (thetype == GeomAbs_Sphere)
{ {
gp_Sphere S = BS.Sphere(); gp_Sphere S = BS.Sphere();
const Standard_Real R = S.Radius(); const Standard_Real R = S.Radius();

View File

@ -178,20 +178,11 @@ void BRepMesh_IncrementalMesh::Update(const TopoDS_Shape& S)
myModified = Standard_False; myModified = Standard_False;
TopExp_Explorer ex; TopExp_Explorer ex;
Standard_Real TXmin, TYmin, TZmin, TXmax, TYmax, TZmax;
Standard_Real dx, dy, dz;
//AGV 080407: Since version 6.2.0 there would be exception without this check //AGV 080407: Since version 6.2.0 there would be exception without this check
if (myBox.IsVoid()) if (myBox.IsVoid())
return; return;
myBox.Get(TXmin, TYmin, TZmin, TXmax, TYmax, TZmax); BRepMesh_FastDiscret::BoxMaxDimension(myBox, mydtotale);
dx = TXmax-TXmin;
dy = TYmax-TYmin;
dz = TZmax-TZmin;
mydtotale = dx;
if (dy > mydtotale) mydtotale = dy;
if (dz > mydtotale) mydtotale = dz;
for (ex.Init(S, TopAbs_EDGE); ex.More(); ex.Next()) { for (ex.Init(S, TopAbs_EDGE); ex.More(); ex.Next()) {
if(BRep_Tool::IsGeometric(TopoDS::Edge(ex.Current()))) { if(BRep_Tool::IsGeometric(TopoDS::Edge(ex.Current()))) {
@ -231,7 +222,7 @@ void BRepMesh_IncrementalMesh::Update(const TopoDS_Shape& S)
Standard_Real f, l, defedge; Standard_Real f, l, defedge;
Standard_Integer i, nbNodes; Standard_Integer i, nbNodes;
TopLoc_Location L; TopLoc_Location L;
Standard_Real aXmin, aYmin, aZmin, aXmax, aYmax, aZmax; Standard_Real cdef = 1.;
ex.Init(S ,TopAbs_EDGE, TopAbs_FACE); ex.Init(S ,TopAbs_EDGE, TopAbs_FACE);
while (ex.More()) { while (ex.More()) {
@ -242,23 +233,11 @@ void BRepMesh_IncrementalMesh::Update(const TopoDS_Shape& S)
continue; continue;
} }
if (myRelative) { if (myRelative)
Bnd_Box B; defedge = BRepMesh_FastDiscret::RelativeEdgeDeflection(E, myDeflection,
BRepBndLib::Add(E, B); mydtotale, cdef);
B.Get(aXmin, aYmin, aZmin, aXmax, aYmax, aZmax); else
dx = aXmax-aXmin; defedge = myDeflection;
dy = aYmax-aYmin;
dz = aZmax-aZmin;
defedge = dx;
if (defedge < dy) defedge = dy;
if (defedge < dz) defedge = dz;
// ajustement par rapport a la taille totale:
Standard_Real cdef = mydtotale/(2*defedge);
if (cdef < 0.5) cdef = 0.5;
if (cdef > 2.) cdef = 2.;
defedge = cdef * defedge * myDeflection;
}
else defedge = myDeflection;
Handle(Poly_Polygon3D) P3D = BRep_Tool::Polygon3D(E, L); Handle(Poly_Polygon3D) P3D = BRep_Tool::Polygon3D(E, L);
Standard_Boolean maill = Standard_False; Standard_Boolean maill = Standard_False;
@ -305,6 +284,7 @@ void BRepMesh_IncrementalMesh::Update(const TopoDS_Edge& E)
Handle(Poly_PolygonOnTriangulation) Poly, NullPoly; Handle(Poly_PolygonOnTriangulation) Poly, NullPoly;
Standard_Boolean found = Standard_False; Standard_Boolean found = Standard_False;
Standard_Real defedge; Standard_Real defedge;
Standard_Real cdef = 1.;
BRep_Builder B; BRep_Builder B;
Standard_Boolean defined = Standard_False; Standard_Boolean defined = Standard_False;
@ -313,24 +293,11 @@ void BRepMesh_IncrementalMesh::Update(const TopoDS_Edge& E)
i++; i++;
if (!T.IsNull() && !Poly.IsNull()) { if (!T.IsNull() && !Poly.IsNull()) {
if (!defined) { if (!defined) {
if (myRelative) { if (myRelative)
Bnd_Box aBox; defedge = BRepMesh_FastDiscret::RelativeEdgeDeflection(E, myDeflection,
BRepBndLib::Add(E, aBox); mydtotale, cdef);
Standard_Real aXmin, aYmin, aZmin, aXmax, aYmax, aZmax, dx, dy, dz; else
aBox.Get(aXmin, aYmin, aZmin, aXmax, aYmax, aZmax); defedge = myDeflection;
dx = aXmax-aXmin;
dy = aYmax-aYmin;
dz = aZmax-aZmin;
defedge = dx;
if (defedge < dy) defedge = dy;
if (defedge < dz) defedge = dz;
// ajustement par rapport a la taille totale:
Standard_Real cdef = mydtotale/(2*defedge);
if (cdef < 0.5) cdef = 0.5;
if (cdef > 2.) cdef = 2.;
defedge = cdef * defedge * myDeflection;
}
else defedge = myDeflection;
mymapedge.Bind(E, defedge); mymapedge.Bind(E, defedge);
defined = Standard_True; defined = Standard_True;
} }
@ -369,7 +336,7 @@ void BRepMesh_IncrementalMesh::Update(const TopoDS_Face& F)
BRep_Builder B; BRep_Builder B;
TopExp_Explorer ex; TopExp_Explorer ex;
Standard_Real defedge, defface; Standard_Real defedge, defface, cdef = 1.;
Standard_Integer nbEdge = 0; Standard_Integer nbEdge = 0;
if (myRelative) { if (myRelative) {
defface = 0.; defface = 0.;
@ -380,23 +347,8 @@ void BRepMesh_IncrementalMesh::Update(const TopoDS_Face& F)
if (mymapedge.IsBound(edge)) { if (mymapedge.IsBound(edge)) {
defedge = mymapedge(edge); defedge = mymapedge(edge);
} }
else { else
Bnd_Box aBox; defedge = BRepMesh_FastDiscret::RelativeEdgeDeflection(edge, myDeflection, mydtotale, cdef);
BRepBndLib::Add(edge, aBox);
Standard_Real aXmin, aYmin, aZmin, aXmax, aYmax, aZmax, dx, dy, dz;
aBox.Get(aXmin, aYmin, aZmin, aXmax, aYmax, aZmax);
dx = aXmax-aXmin;
dy = aYmax-aYmin;
dz = aZmax-aZmin;
defedge = dx;
if (defedge < dy) defedge = dy;
if (defedge < dz) defedge = dz;
// ajustement par rapport a la taille totale:
Standard_Real cdef = mydtotale/(2*defedge);
if (cdef < 0.5) cdef = 0.5;
if (cdef > 2.) cdef = 2.;
defedge = cdef * defedge * myDeflection;
}
defface = defface + defedge; defface = defface + defedge;
} }
if (nbEdge != 0) defface = defface / nbEdge; if (nbEdge != 0) defface = defface / nbEdge;
@ -408,9 +360,7 @@ void BRepMesh_IncrementalMesh::Update(const TopoDS_Face& F)
if (!T.IsNull()) { if (!T.IsNull()) {
if ((!myRelative && T->Deflection() <= 1.1*defface) || if ((!myRelative && T->Deflection() <= 1.1*defface) ||
(myRelative && T->Deflection() <= 1.1*defface)) { (myRelative && T->Deflection() <= 1.1*defface)) {
for (ex.Init(F, TopAbs_EDGE); for (ex.Init(F, TopAbs_EDGE); ex.More(); ex.Next()) {
ex.More();
ex.Next()) {
const TopoDS_Shape& E = ex.Current(); const TopoDS_Shape& E = ex.Current();
Poly = BRep_Tool::PolygonOnTriangulation(TopoDS::Edge(E), T, l); Poly = BRep_Tool::PolygonOnTriangulation(TopoDS::Edge(E), T, l);
if (Poly.IsNull() || myMap.Contains(E)) { if (Poly.IsNull() || myMap.Contains(E)) {