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;
Tol : Real from Standard;
edges : DataMapOfShapePairOfPolygon from BRepMesh;
returns Status from BRepMesh;
---C++: inline
- NaturalRestriction(me)
- returns Boolean from Standard;
- ---C++: inline
-
Destroy(me: in out);
---C++: alias ~
U2 : Real from Standard;
V2 : Real from Standard;
myState : Status from BRepMesh;
- isnatural : Boolean from Standard;
end Classifier from BRepMesh;
#include <ElCLib.hxx>
// Geometry
#include <gp_Pnt.hxx>
-#include <gp_Pnt2d.hxx>
+#include <gp_Pnt2d.hxx>
#include <TColgp_SequenceOfPnt2d.hxx>
#include <TColgp_Array1OfPnt2d.hxx>
#include <GeomAbs_SurfaceType.hxx>
//=======================================================================
void BRepMesh_Classifier::AnalizeWire (const TColgp_SequenceOfPnt2d& theSeqPnt2d,
- const Standard_Real Umin, const Standard_Real Umax,
- const Standard_Real Vmin, const Standard_Real Vmax)
+ const Standard_Real Umin, const Standard_Real Umax,
+ const Standard_Real Vmin, const Standard_Real Vmax)
{
const Standard_Integer nbpnts = theSeqPnt2d.Length();
if (nbpnts < 2) return;
//=======================================================================
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,
- const Standard_Real TolUV,
- const BRepMesh_DataMapOfShapePairOfPolygon& edges,
- const TColStd_IndexedMapOfInteger& themap,
- const Handle(BRepMesh_DataStructureOfDelaun)& 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)
+ const Standard_Real TolUV,
+ const BRepMesh_DataMapOfShapePairOfPolygon& edges,
+ const TColStd_IndexedMapOfInteger& themap,
+ const Handle(BRepMesh_DataStructureOfDelaun)& Str,
+ const Standard_Real Umin,
+ const Standard_Real Umax,
+ const Standard_Real Vmin,
+ const Standard_Real Vmax):
+ Toluv(TolUV), Face(aFace),
+ myState(BRepMesh_NoError)
{
//-- impasse sur les surfs definies sur plus d une periode
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;
+ // 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;
+ NOD = pair.First();
+ iFirst = 1;
iLast = NOD->NbNodes();
iIncr = 1;
}
else
{
- NOD = pair.Last();
- iFirst = NOD->NbNodes();
+ NOD = pair.Last();
+ iFirst = NOD->NbNodes();
iLast = 1;
iIncr = -1;
}
- const TColStd_Array1OfInteger& indices = NOD->Nodes();
+ 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));
+ // 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;
+ // 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 there's a gap between edges -> raise <falsewire> flag
+ if (nbedges)
{
if (indexFirst != lastindex)
{
falsewire = Standard_True;
break;
}
- }
- else firstindex = indexFirst;
- lastindex = indexLast;
+ }
+ else firstindex = indexFirst;
+ lastindex = indexLast;
- // Record first vertex (to detect loops)
- NodeInSeq.Bind(indexFirst,SeqPnt2d.Length()+1);
+ // Record first vertex (to detect loops)
+ NodeInSeq.Bind(indexFirst,SeqPnt2d.Length()+1);
- // Add vertices in sequence
+ // Add vertices in sequence
for (i = iFirst; i != iLast; i += iIncr)
{
index = (i == iFirst)? indexFirst : themap.FindKey(indices(i));
#endif
}
- // Now, is there a loop?
- if (NodeInSeq.IsBound(indexLast))
+ // 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++;
+ // 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++;
}
}
// Isn't it open?
if (falsewire || (firstindex != lastindex) || SeqPnt2d.Length() > 1)
{
- myState = BRepMesh_OpenWire;
- return;
+ myState = BRepMesh_OpenWire;
+ return;
}
}
else
}
}
- // 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);
for (j = i; j <= nbwires; j++)
{
//for i==j the algorithm check current wire on selfintersection
- if (j == i)
+ if (j == i)
{
jk = ik + 2; jkEnd = ikEnd;
}
jk = jkEnd + 1; jkEnd = jk + aWireLength(j) - 1;
}
// Explore second wire
- for (; jk <= jkEnd; jk++)
+ 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];
+ 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];
+ A2 = Coordinates2[5];
B2 = -Coordinates2[4];
C2 = - x21*A2 - y21*B2;
- //mu2 = Sqrt(A2*A2+B2*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);
+ //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)
+ 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;
- //check on belonging of intersection point to the both of segments
+ 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;
+ //check on belonging of intersection point to the both of segments
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 )
{
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)
+ (xc-x21)*(xc-x22) < 0.0 && (yc-y21)*(yc-y22) < 0.0)
{
- //different segments may have common vertex (why "<" but "<=")
- myState = BRepMesh_SelfIntersectingWire; return;
- }
+ //different segments may have common vertex (why "<" but "<=")
+ myState = BRepMesh_SelfIntersectingWire; return;
+ }
}
- }
+ }
}
}
}
{
return myState;
}
-
-//=======================================================================
-//function : NaturalRestriction
-//purpose :
-//=======================================================================
-
-inline Standard_Boolean BRepMesh_Classifier::NaturalRestriction() const
-{
- return isnatural;
-}
-- Author: Didier PIFFAULT
-- <dpf@nonox>
---Copyright: Matra Datavision 1993, 1994
-
+
class Delaun from BRepMesh
is
-- Interface :
- Create (Vertices : in out Array1OfVertexOfDelaun from BRepMesh;
- ZPositive : in Boolean from Standard=Standard_True)
+ Create (Vertices : in out Array1OfVertexOfDelaun from BRepMesh;
+ ZPositive : in Boolean from Standard=Standard_True)
---Purpose: Creates the triangulation with an empty Mesh
-- data structure.
returns Delaun from BRepMesh;
- Create (OldMesh : mutable DataStructureOfDelaun from BRepMesh;
- Vertices : in out Array1OfVertexOfDelaun from BRepMesh;
- ZPositive : in Boolean from Standard=Standard_True)
+ Create (OldMesh : mutable DataStructureOfDelaun from BRepMesh;
+ Vertices : in out Array1OfVertexOfDelaun from BRepMesh;
+ ZPositive : in Boolean from Standard=Standard_True)
---Purpose: Creates the triangulation with and existant
-- Mesh data structure.
returns Delaun from BRepMesh;
- Create (OldMesh : mutable DataStructureOfDelaun from BRepMesh;
- VertexIndices : in out Array1OfInteger from TColStd;
- ZPositive : in Boolean from Standard=Standard_True)
+ Create (OldMesh : mutable DataStructureOfDelaun from BRepMesh;
+ VertexIndices : in out Array1OfInteger from TColStd;
+ ZPositive : in Boolean from Standard=Standard_True)
---Purpose: Creates the triangulation with and existant
-- Mesh data structure.
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;
- theVertex : in Vertex from BRepMesh);
+ RemoveVertex (me : in out;
+ theVertex : in Vertex from BRepMesh);
---Purpose: Removes a vertex in the triangulation.
- AddVertices (me : in out;
- Vertices : in out Array1OfVertexOfDelaun from BRepMesh);
+ AddVertices (me : in out;
+ Vertices : in out Array1OfVertexOfDelaun from BRepMesh);
---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;
- theEdge : in Integer from Standard)
+ UseEdge (me : in out;
+ theEdge : in Integer from Standard)
---Purpose: Modify mesh to use the edge. Return True if done.
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 &
---Purpose: Gives the Mesh data structure.
returns DataStructureOfDelaun from BRepMesh;
- Frontier (me : in out)
+ Frontier (me : in out)
---Purpose: Gives the list of frontier edges
---C++: return const &
returns MapOfInteger from BRepMesh;
- InternalEdges (me : in out)
+ InternalEdges (me : in out)
---Purpose: Gives the list of internal edges
---C++: return const &
returns MapOfInteger from BRepMesh;
- FreeEdges (me : in out)
+ FreeEdges (me : in out)
---Purpose: Gives the list of free edges used only one time
---C++: return const &
returns MapOfInteger from BRepMesh;
- GetVertex (me;
- vIndex : in Integer from Standard)
+ GetVertex (me;
+ vIndex : in Integer from Standard)
---C++: return const &
---C++: inline
returns Vertex from BRepMesh;
- GetEdge (me;
- eIndex : in Integer from Standard)
+ GetEdge (me;
+ eIndex : in Integer from Standard)
---C++: return const &
---C++: inline
returns Edge from BRepMesh;
- GetTriangle (me;
- tIndex : in Integer from Standard)
+ GetTriangle (me;
+ tIndex : in Integer from Standard)
---C++: return const &
---C++: inline
returns Triangle from BRepMesh;
- -- Implementation :
+ -- Implementation :
- Init (me : in out;
- Vertices : in out Array1OfVertexOfDelaun from BRepMesh);
- ---Purpose: Initializes the triangulation with an Array of
+ Init (me : in out;
+ Vertices : in out Array1OfVertexOfDelaun from BRepMesh);
+ ---Purpose: Initializes the triangulation with an Array of
-- Vertex.
Compute (me : in out;
---Purpose: Computes the triangulation and add the vertices
-- 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;
- theBox : Box2d from Bnd);
- ---Purpose: Build the super mesh .
+ theBox : Box2d from Bnd);
+ ---Purpose: Build the super mesh .
FrontierAdjust (me : in out)
is private;
- MeshLeftPolygonOf (me : in out;
- EdgeIndex : Integer from Standard;
- EdgeSens : Boolean from Standard)
+ MeshLeftPolygonOf (me : in out;
+ EdgeIndex : Integer from Standard;
+ EdgeSens : Boolean from Standard)
---Purpose: Find left polygon of the edge and call MeshPolygon.
is private;
CreateTriangles(me : in out;
- vertexIndex : Integer from Standard;
+ vertexIndex : Integer from Standard;
--vertex : in Vertex from BRepMesh;
freeEdges: out MapOfIntegerInteger from BRepMesh)
---Purpose: Creates the triangles beetween the node
-- When an edge is suppressed more than one time
-- it is destroyed.
is private;
+
+
+ Perform (me: in out;
+ theBndBox : out Box2d from Bnd;
+ theVertexIndices: out Array1OfInteger from TColStd)
+ is private;
- Contains (me;
- TrianIndex : Integer from Standard;
- theVertex : in Vertex from BRepMesh;
- edgeOn : out Integer from Standard)
- ---Purpose: Test if triangle of index <TrianIndex>
- -- contains geometricaly <theVertex>. If <EdgeOn>
- -- is != 0 then theVertex is on Edge of index
- -- <edgeOn>.
- returns Boolean from Standard;
+ Contains (me;
+ TrianIndex : Integer from Standard;
+ theVertex : in Vertex from BRepMesh;
+ edgeOn : out Integer from Standard)
+ ---Purpose: Test if triangle of index <TrianIndex>
+ -- contains geometricaly <theVertex>. If <EdgeOn>
+ -- is != 0 then theVertex is on Edge of index
+ -- <edgeOn>.
+ returns Boolean from Standard;
+
+
+ CreateTrianglesOnNewVertices(me : in out;
+ theVertexIndices: out Array1OfInteger from TColStd)
+ --vertex : in Vertex from BRepMesh;
+ ---Purpose: Creates the triangles on new nodes
+ is private;
+
- TriangleContaining
- (me : in out;
- theVertex : in Vertex from BRepMesh)
- ---Purpose: Gives the index of triangle containing
- -- geometricaly <theVertex>.
- returns Integer from Standard;
-
-
- fields MeshData : DataStructureOfDelaun from BRepMesh;
- PositiveOrientation : Boolean from Standard;
- tCircles : CircleTool from BRepMesh;
- supVert1 : Integer from Standard;
- supVert2 : Integer from Standard;
- supVert3 : Integer from Standard;
- supTrian : Triangle from BRepMesh;
- mapEdges : MapOfInteger from BRepMesh;
+ fields MeshData : DataStructureOfDelaun from BRepMesh;
+ PositiveOrientation : Boolean from Standard;
+ tCircles : CircleTool from BRepMesh;
+ supVert1 : Integer from Standard;
+ supVert2 : Integer from Standard;
+ supVert3 : Integer from Standard;
+ supTrian : Triangle from BRepMesh;
+ mapEdges : MapOfInteger from BRepMesh;
end Delaun;
#include <Bnd_Box2d.hxx>
#include <gp.hxx>
#include <TColStd_MapOfInteger.hxx>
+#include <TColStd_Array1OfBoolean.hxx>
#include <BRepMesh_MapOfIntegerInteger.hxx>
#include <BRepMesh_HeapSortIndexedVertexOfDelaun.hxx>
#include <BRepMesh_ComparatorOfIndexedVertexOfDelaun.hxx>
#include <BRepMesh_SelectorOfDataStructureOfDelaun.hxx>
#include <BRepMesh_HeapSortVertexOfDelaun.hxx>
#include <BRepMesh_ComparatorOfVertexOfDelaun.hxx>
+#include <TColgp_Array1OfXY.hxx>
+#include <TColStd_Array1OfReal.hxx>
typedef TColStd_ListIteratorOfListOfInteger IteratorOnListOfInteger;
typedef TColStd_ListOfInteger ListOfInteger;
vertexIndices(niver)=MeshData->AddNode(Vertices(niver));
}
- theBox.Enlarge(Precision::PConfusion());
- SuperMesh(theBox);
-
- BRepMesh_HeapSortIndexedVertexOfDelaun::Sort
- (vertexIndices,
- BRepMesh_ComparatorOfIndexedVertexOfDelaun(SortingDirection,
- Precision::PConfusion(),
- MeshData));
-
- Compute(vertexIndices);
+ Perform(theBox, vertexIndices);
}
theBox.Add(gp_Pnt2d(GetVertex(VertexIndices(niver)).Coord()));
}
- theBox.Enlarge(Precision::PConfusion());
- SuperMesh(theBox);
+ Perform(theBox, VertexIndices);
+ }
+}
+
+//=======================================================================
+//function : Perform
+//purpose :
+//=======================================================================
+void BRepMesh_Delaun::Perform (Bnd_Box2d& theBndBox, TColStd_Array1OfInteger& theVertexIndices)
+{
+ theBndBox.Enlarge(Precision::PConfusion());
+ SuperMesh(theBndBox);
- BRepMesh_HeapSortIndexedVertexOfDelaun::Sort
- (VertexIndices,
- BRepMesh_ComparatorOfIndexedVertexOfDelaun(SortingDirection,
- Precision::PConfusion(),
- MeshData));
+ BRepMesh_HeapSortIndexedVertexOfDelaun::Sort
+ (theVertexIndices,
+ BRepMesh_ComparatorOfIndexedVertexOfDelaun(SortingDirection,
+ Precision::PConfusion(),
+ MeshData));
- Compute(VertexIndices);
- }
+ Compute(theVertexIndices);
}
//=======================================================================
Standard_Integer iVert=VertexIndices.Lower();
CreateTriangles(VertexIndices(iVert), loopEdges);
- // Insertion of nodes :
- 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()) {
+ CreateTrianglesOnNewVertices(VertexIndices);
// 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
// - 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();
cirL.Remove(itT);
break;
- }
- }
-
- 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();
-
+ }*/
+ // Insertion of nodes :
}
// destruction of triangles containing a top of the super triangle
}
-//=======================================================================
-//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
//purpose :
BRepMesh_ListOfInteger::Iterator itconx;
ListOfInteger tril;
- // find external triangles on boundary edges
- BRepMesh_MapOfInteger::Iterator itFr(Frontier());
- for (; itFr.More(); itFr.Next()) {
- const BRepMesh_PairOfIndex& aPair = MeshData->ElemConnectedTo(itFr.Key());
- for(Standard_Integer j = 1, jn = aPair.Extent(); j <= jn; j++) {
- const BRepMesh_Triangle& trc=GetTriangle(aPair.Index(j));
- trc.Edges(e1,e2,e3,o1,o2,o3);
- if ((itFr.Key()==e1 && !o1) ||
- (itFr.Key()==e2 && !o2) ||
- (itFr.Key()==e3 && !o3)) {
+ 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());
+ for (; itFr.More(); itFr.Next()) {
+ const BRepMesh_PairOfIndex& aPair = MeshData->ElemConnectedTo(itFr.Key());
+ for(Standard_Integer j = 1, jn = aPair.Extent(); j <= jn; j++) {
+ const BRepMesh_Triangle& trc=GetTriangle(aPair.Index(j));
+ trc.Edges(e1,e2,e3,o1,o2,o3);
+ if ((itFr.Key()==e1 && !o1) ||
+ (itFr.Key()==e2 && !o2) ||
+ (itFr.Key()==e3 && !o3)) {
#ifdef TRIANGULATION_DEBUG
- if (Triangulation_Trace>0) {
- cout << "---> destruction du triangle " << aPair.Index(j) << endl;
- }
+ if (Triangulation_Trace>0) {
+ cout << "---> destruction du triangle " << aPair.Index(j) << endl;
+ }
#endif
- tril.Append(aPair.Index(j));
+ tril.Append(aPair.Index(j));
+ }
}
}
- }
- // destruction of external triangles on boundary edges
- for (; !tril.IsEmpty(); tril.RemoveFirst()) {
- DeleteTriangle(tril.First(), loopEdges);
- }
+ // destruction of external triangles on boundary edges
+ for (; !tril.IsEmpty(); tril.RemoveFirst()) {
+ DeleteTriangle(tril.First(), loopEdges);
+ }
- // destrucrion of remaining hanging edges :
- BRepMesh_MapOfIntegerInteger::Iterator itFE(loopEdges);
+ // destrucrion of remaining hanging edges :
+ BRepMesh_MapOfIntegerInteger::Iterator itFE(loopEdges);
- for (; itFE.More(); itFE.Next()) {
- if (MeshData->ElemConnectedTo(itFE.Key()).IsEmpty())
- MeshData->RemoveLink(itFE.Key());
- }
+ for (; itFE.More(); itFE.Next()) {
+ if (MeshData->ElemConnectedTo(itFE.Key()).IsEmpty())
+ MeshData->RemoveLink(itFE.Key());
+ }
- // destruction of triangles crossing the boundary edges and
- // their replacement by makeshift triangles
- itFr.Reset();
- for (; itFr.More(); itFr.Next()) {
- if (MeshData->ElemConnectedTo(itFr.Key()).IsEmpty()) {
- MeshLeftPolygonOf(itFr.Key(), Standard_True);
+ // destruction of triangles crossing the boundary edges and
+ // their replacement by makeshift triangles
+ if ( pass == 1 )
+ {
+ itFr.Reset();
+ }
+ else
+ {
+ // in some cases there remain unused boundaries check
+ itFr.Initialize(Frontier());
+ }
+
+ for (; itFr.More(); itFr.Next()) {
+ if (MeshData->ElemConnectedTo(itFr.Key()).IsEmpty()) {
+ MeshLeftPolygonOf(itFr.Key(), Standard_True);
+ }
}
- }
- // After this processing there sometimes remain triangles outside boundaries.
- // Destruction of these triangles :
- Standard_Integer nbFront;
+ if ( pass == 2 ) break;
- // For each edge with only one connection
- // If one of its tops already passes two boundary edges,
- // the connected triangle is outside of the contour
- Standard_Boolean again = Standard_True;
+ // After this processing there sometimes remain triangles outside boundaries.
+ // Destruction of these triangles :
+ Standard_Integer nbFront;
- while (again) {
- tril.Clear();
- loopEdges.Clear();
+ // For each edge with only one connection
+ // If one of its tops already passes two boundary edges,
+ // the connected triangle is outside of the contour
+ Standard_Boolean again = Standard_True;
- for (itFr.Initialize(FreeEdges()); itFr.More(); itFr.Next()) {
- const BRepMesh_Edge& edg=GetEdge(itFr.Key());
- if (edg.Movability()!=BRepMesh_Frontier) {
- nbFront=0;
- if (MeshData->ElemConnectedTo(itFr.Key()).IsEmpty())
- loopEdges.Bind(itFr.Key(), Standard_True);
- else {
- for (itconx.Init(MeshData->LinkNeighboursOf(edg.FirstNode()));
- itconx.More(); itconx.Next()) {
- if (GetEdge(itconx.Value()).Movability()==BRepMesh_Frontier) {
- nbFront++;
- if (nbFront>1) break;
- }
- }
- if (nbFront==2) {
- const BRepMesh_PairOfIndex& aPair = MeshData->ElemConnectedTo(itFr.Key());
- for(Standard_Integer j = 1, jn = aPair.Extent(); j <= jn; j++) {
- const Standard_Integer elemId = aPair.Index(j);
- GetTriangle(elemId).Edges(e1, e2, e3, o1, o2, o3);
- if (GetEdge(e1).Movability()==BRepMesh_Free &&
- GetEdge(e2).Movability()==BRepMesh_Free &&
- GetEdge(e3).Movability()==BRepMesh_Free) {
-#ifdef TRIANGULATION_DEBUG
- if (Triangulation_Trace>0) {
- cout << " ----> destruction du triangle" << elemId <<endl;
- }
-#endif
- tril.Append(elemId);
+ while (again) {
+ tril.Clear();
+ loopEdges.Clear();
+
+ for (itFr.Initialize(FreeEdges()); itFr.More(); itFr.Next()) {
+ const BRepMesh_Edge& edg=GetEdge(itFr.Key());
+ if (edg.Movability()!=BRepMesh_Frontier) {
+ nbFront=0;
+ if (MeshData->ElemConnectedTo(itFr.Key()).IsEmpty())
+ loopEdges.Bind(itFr.Key(), Standard_True);
+ else {
+ for (itconx.Init(MeshData->LinkNeighboursOf(edg.FirstNode()));
+ itconx.More(); itconx.Next()) {
+ if (GetEdge(itconx.Value()).Movability()==BRepMesh_Frontier) {
+ nbFront++;
+ if (nbFront>1) break;
+ }
+ }
+ if (nbFront==2) {
+ const BRepMesh_PairOfIndex& aPair = MeshData->ElemConnectedTo(itFr.Key());
+ for(Standard_Integer j = 1, jn = aPair.Extent(); j <= jn; j++) {
+ const Standard_Integer elemId = aPair.Index(j);
+ GetTriangle(elemId).Edges(e1, e2, e3, o1, o2, o3);
+ if (GetEdge(e1).Movability()==BRepMesh_Free &&
+ GetEdge(e2).Movability()==BRepMesh_Free &&
+ GetEdge(e3).Movability()==BRepMesh_Free) {
+ #ifdef TRIANGULATION_DEBUG
+ if (Triangulation_Trace>0) {
+ cout << " ----> destruction du triangle" << elemId <<endl;
+ }
+ #endif
+ tril.Append(elemId);
+ }
}
}
}
}
}
- }
- // Destruction des triangles :
- Standard_Integer kk = 0;
- for (; !tril.IsEmpty(); tril.RemoveFirst()) {
- DeleteTriangle(tril.First(), loopEdges);
- kk++;
- }
+ // Destruction des triangles :
+ Standard_Integer kk = 0;
+ for (; !tril.IsEmpty(); tril.RemoveFirst()) {
+ DeleteTriangle(tril.First(), loopEdges);
+ kk++;
+ }
- // destruction of remaining hanging edges
- for (itFE.Initialize(loopEdges); itFE.More(); itFE.Next()) {
- if (MeshData->ElemConnectedTo(itFE.Key()).IsEmpty())
- MeshData->RemoveLink(itFE.Key());
- }
+ // destruction of remaining hanging edges
+ for (itFE.Initialize(loopEdges); itFE.More(); itFE.Next()) {
+ if (MeshData->ElemConnectedTo(itFE.Key()).IsEmpty())
+ MeshData->RemoveLink(itFE.Key());
+ }
- 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
// after "mesh left polygon"
for (itFr.Initialize(Frontier()); itFr.More(); itFr.Next()) {
if (MeshData->ElemConnectedTo(itFr.Key()).IsEmpty()) {
MeshLeftPolygonOf(itFr.Key(), Standard_True);
}
- }
+ } */
}
}
//=======================================================================
-//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.
+//function : CreateTrianglesOnNewVertices
+//purpose : Creation of triangles from the new nodes
//=======================================================================
-
-void BRepMesh_Delaun::DeleteTriangle (const Standard_Integer tIndex,
- BRepMesh_MapOfIntegerInteger& fEdges)
+void BRepMesh_Delaun::CreateTrianglesOnNewVertices (TColStd_Array1OfInteger& theVertexIndices)
{
- tCircles.Delete(tIndex);
-
- Standard_Integer fe1, fe2, fe3;
- Standard_Boolean or1, or2, or3;
- GetTriangle(tIndex).Edges(fe1, fe2, fe3, or1, or2, or3);
- MeshData->RemoveElement(tIndex);
-
- 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);
- }
+ BRepMesh_MapOfIntegerInteger loopEdges(10,MeshData->Allocator());
-}
+ Standard_Integer iVert;
+ // Insertion of nodes :
+ Standard_Boolean modif=Standard_True;
+ Standard_Integer edgon, triPer;
+ Standard_Integer e1, e2, e3;
+ 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);
-//=======================================================================
-//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(aVert.Coord());
+
+ BRepMesh_ListOfInteger::Iterator itT(cirL);
+ for (; itT.More(); itT.Next()) {
- // Iterator in the list of indexes of circles containing the node :
- BRepMesh_ListOfInteger& cirL=tCircles.Select(theVert.Coord());
+ // 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(), aVert, 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;
+ }
+ }
+ }
- Standard_Integer edgon=0;
- Standard_Integer triPer=0;
- Standard_Integer e1, e2, e3;
- Standard_Boolean o1, o2, o3;
+ if (triPer>0) {
+ DeleteTriangle(triPer, loopEdges);
- BRepMesh_ListOfInteger::Iterator itT(cirL);
- 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(), theVert, 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;
+ 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(aVertIdx, loopEdges);
}
}
+ // check that internal edges are not crossed by triangles
+ BRepMesh_MapOfInteger::Iterator itFr(InternalEdges());
- if (triPer>0) {
-
- BRepMesh_MapOfIntegerInteger loopEdges(10,MeshData->Allocator());
- DeleteTriangle(triPer, loopEdges);
-
- Standard_Boolean modif=Standard_True;
- while (modif && !cirL.IsEmpty()) {
- modif=Standard_False;
- BRepMesh_ListOfInteger::Iterator itT1(cirL);
- for (; itT1.More(); itT1.Next()) {
- GetTriangle(itT.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;
- }
- }
+ // 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);
}
+ }
- // Creation of triangles with the current node and free edges
- // and removal of these edges from the list of free edges
- CreateTriangles(nv, loopEdges);
+ // adjustment of meshes to boundary edges
+ FrontierAdjust();
+}
- // Check that internal edges are not crossed by the triangles
- BRepMesh_MapOfInteger::Iterator itFr(InternalEdges());
+//=======================================================================
+//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.
+//=======================================================================
- // 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);
- }
- }
+void BRepMesh_Delaun::DeleteTriangle (const Standard_Integer tIndex,
+ BRepMesh_MapOfIntegerInteger& fEdges)
+{
+ tCircles.Delete(tIndex);
- FrontierAdjust();
+ 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));
+ }
}
-
}
//=======================================================================
(vertices,
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 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
- BRepMesh_ListOfInteger& cirL=tCircles.Select(vertices(niver).Coord());
-
- edgon=0;
- triPer=0;
-
- BRepMesh_ListOfInteger::Iterator itT(cirL);
- 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();
-}
-
+
+ TColStd_Array1OfInteger vertexIndices(vertices.Lower(), vertices.Upper());
-//=======================================================================
-//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;
- }
+ for (niver=vertices.Lower(); niver<=vertices.Upper(); niver++)
+ vertexIndices(niver)=MeshData->AddNode(vertices(niver));
- 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;
+ CreateTrianglesOnNewVertices(vertexIndices);
}
//=======================================================================
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
//purpose :
//function : Contains
//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,
const BRepMesh_Vertex& vert,
Standard_Integer& edgOn)const
{
- edgOn=0;
- Standard_Integer e1, e2, e3, p1, p2, p3;
- Standard_Boolean o1, o2, o3;
- GetTriangle(tri).Edges(e1, e2, e3, o1, o2, o3);
- const BRepMesh_Edge& edg1=GetEdge(e1);
- const BRepMesh_Edge& edg2=GetEdge(e2);
- const BRepMesh_Edge& edg3=GetEdge(e3);
- if (o1) {
- p1=edg1.FirstNode();
- p2=edg1.LastNode();
+ edgOn = 0;
+ TColStd_Array1OfInteger e(1,3);
+ TColStd_Array1OfInteger p(1,3);
+ TColStd_Array1OfBoolean o(1,3);
+ GetTriangle(tri).Edges(e(1), e(2), e(3), o(1), o(2), o(3));
+ const BRepMesh_Edge* edg[3] = { &GetEdge(e(1)),
+ &GetEdge(e(2)),
+ &GetEdge(e(3)) };
+ if (o(1)) {
+ p(1) = edg[0]->FirstNode();
+ p(2) = edg[0]->LastNode();
}
else {
- p2=edg1.FirstNode();
- p1=edg1.LastNode();
- }
- if (o3) p3=edg3.FirstNode();
- else p3=edg3.LastNode();
-
- const gp_XY& P1=GetVertex(p1).Coord();
- const gp_XY& P2=GetVertex(p2).Coord();
- const gp_XY& P3=GetVertex(p3).Coord();
- gp_XY E1(P2); E1.Subtract(P1);
- gp_XY E2(P3); E2.Subtract(P2);
- gp_XY E3(P1); E3.Subtract(P3);
-
- Standard_Real mode1=E1.SquareModulus();
- //Standard_Real dist=Sqrt(mode1);
- if (mode1<=EPSEPS) return Standard_False;
- Standard_Real v1=E1^(vert.Coord()-P1);
- Standard_Real distMin=(v1*v1)/mode1;
- edgOn=e1;
-
- Standard_Real mode2=E2.SquareModulus();
- Standard_Real dist;
- //dist=Sqrt(mode2);
- if (mode2<=EPSEPS) return Standard_False;
- Standard_Real v2=E2^(vert.Coord()-P2);
- dist=(v2*v2)/mode2;
- if (dist<distMin) {
- edgOn=e2;
- distMin=dist;
+ p(2) = edg[0]->FirstNode();
+ p(1) = edg[0]->LastNode();
}
-
- Standard_Real mode3=E3.SquareModulus();
- //dist=Sqrt(mode3);
- if (mode3<=EPSEPS) return Standard_False;
- Standard_Real v3=E3^(vert.Coord()-P3);
- dist=(v3*v3)/mode3;
- if (dist<distMin) {
- edgOn=e3;
- distMin=dist;
- }
-
- if (distMin>EPSEPS) {
- Standard_Integer edf=edgOn;
- edgOn=0;
- if (edf==e1 && edg1.Movability()!=BRepMesh_Free) {
- 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;
+ if (o(3)) p(3) = edg[2]->FirstNode();
+ else p(3) = edg[2]->LastNode();
+
+ TColgp_Array1OfXY P(1,3);
+ P(1) = GetVertex(p(1)).Coord();
+ P(2) = GetVertex(p(2)).Coord();
+ P(3) = GetVertex(p(3)).Coord();
+
+ TColgp_Array1OfXY E(1,3);
+ E(1) = P(2); E(1).Subtract(P(1));
+ E(2) = P(3); E(2).Subtract(P(2));
+ E(3) = P(1); E(3).Subtract(P(3));
+
+ Standard_Real distMin;
+ TColStd_Array1OfReal v (1,3);
+ TColStd_Array1OfReal mode(1,3);
+
+ distMin = calculateDist(E, P, e, vert, v, mode, edgOn);
+ if ( distMin < 0 )
+ return Standard_False;
+
+ if ( distMin > EPSEPS ) {
+ Standard_Integer edf = edgOn;
+ edgOn = 0;
+ if ( edf != 0 )
+ {
+ Standard_Integer i = 1;
+ for(; i <= 3; i++ )
+ {
+ if( edf == e(i) )
+ break;
+ }
+
+ if( edg[i-1]->Movability() != BRepMesh_Free )
+ if ( v(i) < (mode(i)/5.) ) edgOn = e(i);
}
}
- return (v1+v2+v3!=0. &&((v1>=0. && v2>=0. && v3>=0.) ||
- (v1<=0. && v2<=0. && v3<=0.)));
+ 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.)));
}
-//=======================================================================
-//function : TriangleContaining
-//purpose :
-//=======================================================================
-Standard_Integer BRepMesh_Delaun::TriangleContaining(const BRepMesh_Vertex& vert)
-{
- const BRepMesh_ListOfInteger& cirL=tCircles.Select(vert.Coord());
-
- BRepMesh_ListOfInteger::Iterator itT(cirL);
- Standard_Integer triPer=0;
- 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 triPer;
-}
last : Real from Standard)
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
(me : mutable;
myInshape(theInshape)
{
myAllocator = new NCollection_IncAllocator(64000);
- if (theRelative)
- {
- 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;
- }
+ if(myRelative)
+ BoxMaxDimension(theBox, myDtotale);
}
//=======================================================================
myInshape(theInshape)
{
myAllocator = new NCollection_IncAllocator(64000);
- if (theRelative)
- {
- 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;
- }
+ 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;
+ theBox.Get(TXmin, TYmin, TZmin, TXmax, TYmax, TZmax);
+ theMaxDim = TXmax-TXmin;
+ const Standard_Real dy = TYmax-TYmin;
+ const Standard_Real dz = TZmax-TZmin;
+ if (dy > theMaxDim) theMaxDim = dy;
+ if (dz > theMaxDim) theMaxDim = dz;
+}
+
+//=======================================================================
+//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;
+}
+
//=======================================================================
//function : Perform(shape)
//purpose :
i = 1;
Standard_Real defedge, defface;
- Standard_Real dx, dy, dz;
Standard_Integer nbEdge = 0;
Standard_Real savangle = myAngle;
Standard_Real cdef;
defedge = P->Deflection();
}
else {
- Bnd_Box B;
- 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;
+ defedge = RelativeEdgeDeflection(edge, myDeflection, myDtotale, cdef);
myAngle = savangle * cdef;
}
defface = defface + defedge;
BS.D0 (myumin, myvmin, P11);
BS.D0 (myumin, dfvave, P21);
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, dfvave, P22);
BS.D0 (dfucur, myvmax, P32);
BS.D0(myumin, myvmin, P11);
BS.D0(dfuave, myvmin, P21);
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 (dfuave, dfvcur, P22);
BS.D0 (myumax, dfvcur, P32);
myStructure.Nullify();
}
-
//=======================================================================
//function : Add
//purpose :
tabvert_corr(i) = i;
}
myStructure->ReplaceNodes(aMoveNodes);
-
+
Standard_Boolean rajout;
BRepMesh_ClassifierPtr& classifier = theAttrib->GetClassifier();
switch (thetype)
{
- case GeomAbs_Plane:
- rajout = !classifier->NaturalRestriction();
- break;
case GeomAbs_Sphere:
case GeomAbs_Torus:
rajout = Standard_True;
Standard_Real deltaX = myAttrib->GetDeltaX();
Standard_Real deltaY = myAttrib->GetDeltaY();
- if (thetype == GeomAbs_Plane && !theClassifier->NaturalRestriction())
- {
- // 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();
+ if (thetype == GeomAbs_Sphere)
+ {
+ gp_Sphere S = BS.Sphere();
const Standard_Real R = S.Radius();
// Calculate parameters for iteration in V direction
myModified = Standard_False;
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
if (myBox.IsVoid())
return;
- myBox.Get(TXmin, TYmin, TZmin, TXmax, TYmax, TZmax);
- dx = TXmax-TXmin;
- dy = TYmax-TYmin;
- dz = TZmax-TZmin;
- mydtotale = dx;
- if (dy > mydtotale) mydtotale = dy;
- if (dz > mydtotale) mydtotale = dz;
+ BRepMesh_FastDiscret::BoxMaxDimension(myBox, mydtotale);
for (ex.Init(S, TopAbs_EDGE); ex.More(); ex.Next()) {
if(BRep_Tool::IsGeometric(TopoDS::Edge(ex.Current()))) {
Standard_Real f, l, defedge;
Standard_Integer i, nbNodes;
TopLoc_Location L;
- Standard_Real aXmin, aYmin, aZmin, aXmax, aYmax, aZmax;
+ Standard_Real cdef = 1.;
ex.Init(S ,TopAbs_EDGE, TopAbs_FACE);
while (ex.More()) {
continue;
}
- if (myRelative) {
- Bnd_Box B;
- BRepBndLib::Add(E, 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;
- // 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;
+ if (myRelative)
+ defedge = BRepMesh_FastDiscret::RelativeEdgeDeflection(E, myDeflection,
+ mydtotale, cdef);
+ else
+ defedge = myDeflection;
Handle(Poly_Polygon3D) P3D = BRep_Tool::Polygon3D(E, L);
Standard_Boolean maill = Standard_False;
TColgp_Array1OfPnt Nodes(1, nbNodes);
TColStd_Array1OfReal UVNodes(1, nbNodes);
for ( i = 1; i <= nbNodes; i++) {
- Nodes(i) = TD.Value(i);
- UVNodes(i) = TD.Parameter(i);
+ Nodes(i) = TD.Value(i);
+ UVNodes(i) = TD.Parameter(i);
}
BRep_Builder B;
Handle(Poly_PolygonOnTriangulation) Poly, NullPoly;
Standard_Boolean found = Standard_False;
Standard_Real defedge;
+ Standard_Real cdef = 1.;
BRep_Builder B;
Standard_Boolean defined = Standard_False;
i++;
if (!T.IsNull() && !Poly.IsNull()) {
if (!defined) {
- if (myRelative) {
- Bnd_Box aBox;
- BRepBndLib::Add(E, 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;
- }
- else defedge = myDeflection;
- mymapedge.Bind(E, defedge);
- defined = Standard_True;
+ if (myRelative)
+ defedge = BRepMesh_FastDiscret::RelativeEdgeDeflection(E, myDeflection,
+ mydtotale, cdef);
+ else
+ defedge = myDeflection;
+ mymapedge.Bind(E, defedge);
+ defined = Standard_True;
}
if ((!myRelative && Poly->Deflection() <= 1.1*defedge) ||
- (myRelative && Poly->Deflection() <= 1.1*defedge))
- found = Standard_True;
+ (myRelative && Poly->Deflection() <= 1.1*defedge))
+ found = Standard_True;
else {
- myModified = Standard_True;
- B.UpdateEdge(E, NullPoly, T, l);
+ myModified = Standard_True;
+ B.UpdateEdge(E, NullPoly, T, l);
}
}
} while (!Poly.IsNull());
BRep_Builder B;
TopExp_Explorer ex;
- Standard_Real defedge, defface;
+ Standard_Real defedge, defface, cdef = 1.;
Standard_Integer nbEdge = 0;
if (myRelative) {
defface = 0.;
const TopoDS_Edge& edge = TopoDS::Edge(ex.Current());
nbEdge++;
if (mymapedge.IsBound(edge)) {
- defedge = mymapedge(edge);
- }
- else {
- Bnd_Box aBox;
- 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;
+ defedge = mymapedge(edge);
}
+ else
+ defedge = BRepMesh_FastDiscret::RelativeEdgeDeflection(edge, myDeflection, mydtotale, cdef);
defface = defface + defedge;
}
if (nbEdge != 0) defface = defface / nbEdge;
if (!T.IsNull()) {
if ((!myRelative && T->Deflection() <= 1.1*defface) ||
- (myRelative && T->Deflection() <= 1.1*defface)) {
- for (ex.Init(F, TopAbs_EDGE);
- ex.More();
- ex.Next()) {
- const TopoDS_Shape& E = ex.Current();
- Poly = BRep_Tool::PolygonOnTriangulation(TopoDS::Edge(E), T, l);
- if (Poly.IsNull() || myMap.Contains(E)) {
- WillBeTriangulated = Standard_True;
- // cas un peu special. la triangulation est bonne, mais
- // l'edge n'a pas de representation polygonalisee sur celle-ci.
- break;
- }
+ (myRelative && T->Deflection() <= 1.1*defface)) {
+ for (ex.Init(F, TopAbs_EDGE); ex.More(); ex.Next()) {
+ const TopoDS_Shape& E = ex.Current();
+ Poly = BRep_Tool::PolygonOnTriangulation(TopoDS::Edge(E), T, l);
+ if (Poly.IsNull() || myMap.Contains(E)) {
+ WillBeTriangulated = Standard_True;
+ // cas un peu special. la triangulation est bonne, mais
+ // l'edge n'a pas de representation polygonalisee sur celle-ci.
+ break;
+ }
}
}
else WillBeTriangulated = Standard_True;
myModified = Standard_True;
if (!T.IsNull()) {
for (ex.Init(F, TopAbs_EDGE); ex.More(); ex.Next()) {
- B.UpdateEdge(TopoDS::Edge(ex.Current()), NullPoly, T, l);
- myMap.Remove(ex.Current());
+ B.UpdateEdge(TopoDS::Edge(ex.Current()), NullPoly, T, l);
+ myMap.Remove(ex.Current());
}
B.UpdateFace(F, TNull);
}