From 2b59653e6752b45ba9e6d586361818cdedf9bd4f Mon Sep 17 00:00:00 2001 From: EPA <> Date: Fri, 2 Sep 2011 08:16:09 +0000 Subject: [PATCH] 0022564: BRepMesh_Classifier improvements --- src/BRepMesh/BRepMesh_Classifier.cdl | 14 - src/BRepMesh/BRepMesh_Classifier.cxx | 532 ++---------- src/BRepMesh/BRepMesh_Classifier.lxx | 10 - src/BRepMesh/BRepMesh_Delaun.cdl | 148 ++-- src/BRepMesh/BRepMesh_Delaun.cxx | 945 +++++++--------------- src/BRepMesh/BRepMesh_FastDiscret.cdl | 12 + src/BRepMesh/BRepMesh_FastDiscret.cxx | 91 ++- src/BRepMesh/BRepMesh_FastDiscretFace.cxx | 28 +- src/BRepMesh/BRepMesh_IncrementalMesh.cxx | 124 +-- 9 files changed, 568 insertions(+), 1336 deletions(-) diff --git a/src/BRepMesh/BRepMesh_Classifier.cdl b/src/BRepMesh/BRepMesh_Classifier.cdl index 886c2e08e1..e5b71ad478 100755 --- a/src/BRepMesh/BRepMesh_Classifier.cdl +++ b/src/BRepMesh/BRepMesh_Classifier.cdl @@ -23,15 +23,6 @@ uses 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; @@ -49,10 +40,6 @@ is returns Status from BRepMesh; ---C++: inline - NaturalRestriction(me) - returns Boolean from Standard; - ---C++: inline - Destroy(me: in out); ---C++: alias ~ @@ -76,6 +63,5 @@ fields U2 : Real from Standard; V2 : Real from Standard; myState : Status from BRepMesh; - isnatural : Boolean from Standard; end Classifier from BRepMesh; diff --git a/src/BRepMesh/BRepMesh_Classifier.cxx b/src/BRepMesh/BRepMesh_Classifier.cxx index 30fd998d4a..1201d04a29 100755 --- a/src/BRepMesh/BRepMesh_Classifier.cxx +++ b/src/BRepMesh/BRepMesh_Classifier.cxx @@ -15,7 +15,7 @@ #include // Geometry #include -#include +#include #include #include #include @@ -88,8 +88,8 @@ static Standard_Boolean IsLine(const Handle(Geom2d_Curve)& C2d) //======================================================================= 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; @@ -140,350 +140,16 @@ void BRepMesh_Classifier::AnalizeWire (const TColgp_SequenceOfPnt2d& theSeqPnt2 //======================================================================= 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 <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 - 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 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"< 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" <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 @@ -537,50 +203,50 @@ BRepMesh_Classifier::BRepMesh_Classifier(const TopoDS_Face& aFace, 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 - 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 + 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 flag - if (nbedges) + // If there's a gap between edges -> raise 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)); @@ -592,24 +258,23 @@ BRepMesh_Classifier::BRepMesh_Classifier(const TopoDS_Face& aFace, #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++; } } @@ -618,8 +283,8 @@ BRepMesh_Classifier::BRepMesh_Classifier(const TopoDS_Face& aFace, // Isn't it open? if (falsewire || (firstindex != lastindex) || SeqPnt2d.Length() > 1) { - myState = BRepMesh_OpenWire; - return; + myState = BRepMesh_OpenWire; + return; } } else @@ -630,38 +295,7 @@ BRepMesh_Classifier::BRepMesh_Classifier(const TopoDS_Face& aFace, } } - // 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); @@ -734,7 +368,7 @@ BRepMesh_Classifier::BRepMesh_Classifier(const TopoDS_Face& aFace, 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; } @@ -743,52 +377,52 @@ BRepMesh_Classifier::BRepMesh_Classifier(const TopoDS_Face& aFace, 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; + } } - } + } } } } diff --git a/src/BRepMesh/BRepMesh_Classifier.lxx b/src/BRepMesh/BRepMesh_Classifier.lxx index b687b17deb..816ccdd3e1 100755 --- a/src/BRepMesh/BRepMesh_Classifier.lxx +++ b/src/BRepMesh/BRepMesh_Classifier.lxx @@ -15,13 +15,3 @@ inline BRepMesh_Status BRepMesh_Classifier::State() const { return myState; } - -//======================================================================= -//function : NaturalRestriction -//purpose : -//======================================================================= - -inline Standard_Boolean BRepMesh_Classifier::NaturalRestriction() const -{ - return isnatural; -} diff --git a/src/BRepMesh/BRepMesh_Delaun.cdl b/src/BRepMesh/BRepMesh_Delaun.cdl index 70c20fd9ad..e22c547a61 100755 --- a/src/BRepMesh/BRepMesh_Delaun.cdl +++ b/src/BRepMesh/BRepMesh_Delaun.cdl @@ -3,7 +3,7 @@ -- Author: Didier PIFFAULT -- ---Copyright: Matra Datavision 1993, 1994 - + class Delaun from BRepMesh @@ -33,115 +33,95 @@ 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; @@ -149,14 +129,10 @@ class Delaun from BRepMesh ---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) @@ -164,9 +140,9 @@ class Delaun from BRepMesh 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; @@ -178,7 +154,7 @@ class Delaun from BRepMesh 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 @@ -194,34 +170,40 @@ class Delaun from BRepMesh -- 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 - -- contains geometricaly . If - -- is != 0 then theVertex is on Edge of index - -- . - returns Boolean from Standard; - - TriangleContaining - (me : in out; - theVertex : in Vertex from BRepMesh) - ---Purpose: Gives the index of triangle containing - -- geometricaly . - returns Integer from Standard; + Contains (me; + TrianIndex : Integer from Standard; + theVertex : in Vertex from BRepMesh; + edgeOn : out Integer from Standard) + ---Purpose: Test if triangle of index + -- contains geometricaly . If + -- is != 0 then theVertex is on Edge of index + -- . + returns Boolean 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; + CreateTrianglesOnNewVertices(me : in out; + theVertexIndices: out Array1OfInteger from TColStd) + --vertex : in Vertex from BRepMesh; + ---Purpose: Creates the triangles on new nodes + is private; + + + 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; diff --git a/src/BRepMesh/BRepMesh_Delaun.cxx b/src/BRepMesh/BRepMesh_Delaun.cxx index 74f72a5811..b58e49f883 100755 --- a/src/BRepMesh/BRepMesh_Delaun.cxx +++ b/src/BRepMesh/BRepMesh_Delaun.cxx @@ -13,6 +13,7 @@ #include #include #include +#include #include #include #include @@ -20,6 +21,8 @@ #include #include #include +#include +#include typedef TColStd_ListIteratorOfListOfInteger IteratorOnListOfInteger; typedef TColStd_ListOfInteger ListOfInteger; @@ -95,16 +98,7 @@ void BRepMesh_Delaun::Init(BRepMesh_Array1OfVertexOfDelaun& Vertices) 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); } @@ -126,19 +120,28 @@ BRepMesh_Delaun::BRepMesh_Delaun theBox.Add(gp_Pnt2d(GetVertex(VertexIndices(niver)).Coord())); } - theBox.Enlarge(Precision::PConfusion()); - SuperMesh(theBox); - - BRepMesh_HeapSortIndexedVertexOfDelaun::Sort - (VertexIndices, - BRepMesh_ComparatorOfIndexedVertexOfDelaun(SortingDirection, - Precision::PConfusion(), - MeshData)); - - Compute(VertexIndices); + 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 + (theVertexIndices, + BRepMesh_ComparatorOfIndexedVertexOfDelaun(SortingDirection, + Precision::PConfusion(), + MeshData)); + + Compute(theVertexIndices); +} + //======================================================================= //function : Compute //purpose : @@ -160,87 +163,17 @@ void BRepMesh_Delaun::Compute (TColStd_Array1OfInteger& VertexIndices) 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 @@ -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 //purpose : @@ -297,113 +214,131 @@ void BRepMesh_Delaun::FrontierAdjust() 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); - } - - // 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()); - } - - // 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 external triangles on boundary edges + for (; !tril.IsEmpty(); tril.RemoveFirst()) { + DeleteTriangle(tril.First(), loopEdges); } - } - // After this processing there sometimes remain triangles outside boundaries. - // Destruction of these triangles : - Standard_Integer nbFront; + // destrucrion of remaining hanging edges : + BRepMesh_MapOfIntegerInteger::Iterator itFE(loopEdges); - // 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 (; itFE.More(); itFE.Next()) { + if (MeshData->ElemConnectedTo(itFE.Key()).IsEmpty()) + MeshData->RemoveLink(itFE.Key()); + } - while (again) { - tril.Clear(); - loopEdges.Clear(); + // 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); + } + } - 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 <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 <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()) { @@ -440,7 +375,7 @@ void BRepMesh_Delaun::FrontierAdjust() if (MeshData->ElemConnectedTo(itFr.Key()).IsEmpty()) { MeshLeftPolygonOf(itFr.Key(), Standard_True); } - } + } */ } @@ -912,6 +847,97 @@ void BRepMesh_Delaun::CreateTriangles (const Standard_Integer theVertexIndex, } } +//======================================================================= +//function : CreateTrianglesOnNewVertices +//purpose : Creation of triangles from the new nodes +//======================================================================= +void BRepMesh_Delaun::CreateTrianglesOnNewVertices (TColStd_Array1OfInteger& theVertexIndices) +{ + 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); + + // 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()) { + + // 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; + } + } + } + + 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(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(); +} + //======================================================================= //function : DeleteTriangle //purpose : The concerned triangles are deleted and the freed edges are added in @@ -925,108 +951,20 @@ void BRepMesh_Delaun::DeleteTriangle (const Standard_Integer tIndex, { tCircles.Delete(tIndex); - Standard_Integer fe1, fe2, fe3; - Standard_Boolean or1, or2, or3; - GetTriangle(tIndex).Edges(fe1, fe2, fe3, or1, or2, or3); + 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); - 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_Boolean o1, o2, o3; - - 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; - } + Standard_Integer i = 1; + for(; i <= 3; i++ ) + { + if (!fEdges.Bind(fe(i), ornt(i))) + { + fEdges.UnBind(fe(i)); + MeshData->RemoveLink(fe(i)); } } - - 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; - } - } - } - - // Creation of triangles with the current node and free edges - // and removal of these edges from the list of free edges - CreateTriangles(nv, loopEdges); - - // Check that internal edges are not crossed by the 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); - } - } - - FrontierAdjust(); - - } - } //======================================================================= @@ -1107,218 +1045,14 @@ void BRepMesh_Delaun::AddVertices(BRepMesh_Array1OfVertexOfDelaun& vertices) (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)); + + TColStd_Array1OfInteger vertexIndices(vertices.Lower(), vertices.Upper()); - // Iterator in the list of indexes of circles containing the node - BRepMesh_ListOfInteger& cirL=tCircles.Select(vertices(niver).Coord()); + for (niver=vertices.Lower(); niver<=vertices.Upper(); niver++) + vertexIndices(niver)=MeshData->AddNode(vertices(niver)); - 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(); -} - - -//======================================================================= -//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; + CreateTrianglesOnNewVertices(vertexIndices); } //======================================================================= @@ -1394,46 +1128,6 @@ Standard_Boolean BRepMesh_Delaun::UseEdge(const Standard_Integer ind) 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 : @@ -1499,103 +1193,92 @@ const BRepMesh_MapOfInteger& BRepMesh_Delaun::FreeEdges () //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(); + p(2) = edg[0]->FirstNode(); + p(1) = edg[0]->LastNode(); } - if (o3) p3=edg3.FirstNode(); - else p3=edg3.LastNode(); + if (o(3)) p(3) = edg[2]->FirstNode(); + else p(3) = edg[2]->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); + 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 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 (distEPSEPS) { - 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; + 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; -} diff --git a/src/BRepMesh/BRepMesh_FastDiscret.cdl b/src/BRepMesh/BRepMesh_FastDiscret.cdl index 65b0059071..60af9fc6cc 100755 --- a/src/BRepMesh/BRepMesh_FastDiscret.cdl +++ b/src/BRepMesh/BRepMesh_FastDiscret.cdl @@ -128,6 +128,18 @@ is 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; diff --git a/src/BRepMesh/BRepMesh_FastDiscret.cxx b/src/BRepMesh/BRepMesh_FastDiscret.cxx index aebfb77710..5f962a6403 100755 --- a/src/BRepMesh/BRepMesh_FastDiscret.cxx +++ b/src/BRepMesh/BRepMesh_FastDiscret.cxx @@ -126,16 +126,8 @@ BRepMesh_FastDiscret::BRepMesh_FastDiscret(const Standard_Real theDefle, 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); } //======================================================================= @@ -156,19 +148,57 @@ BRepMesh_FastDiscret::BRepMesh_FastDiscret(const Standard_Real theDefle, 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 : @@ -270,7 +300,6 @@ void BRepMesh_FastDiscret::Add(const TopoDS_Face& theface) i = 1; Standard_Real defedge, defface; - Standard_Real dx, dy, dz; Standard_Integer nbEdge = 0; Standard_Real savangle = myAngle; Standard_Real cdef; @@ -301,20 +330,7 @@ void BRepMesh_FastDiscret::Add(const TopoDS_Face& theface) 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; @@ -510,7 +526,7 @@ void BRepMesh_FastDiscret::Add(const TopoDS_Face& theface) 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); @@ -523,7 +539,7 @@ void BRepMesh_FastDiscret::Add(const TopoDS_Face& theface) 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); @@ -663,7 +679,6 @@ void BRepMesh_FastDiscret::Add(const TopoDS_Face& theface) myStructure.Nullify(); } - //======================================================================= //function : Add //purpose : diff --git a/src/BRepMesh/BRepMesh_FastDiscretFace.cxx b/src/BRepMesh/BRepMesh_FastDiscretFace.cxx index 17946bd421..518866bc0e 100755 --- a/src/BRepMesh/BRepMesh_FastDiscretFace.cxx +++ b/src/BRepMesh/BRepMesh_FastDiscretFace.cxx @@ -217,16 +217,13 @@ void BRepMesh_FastDiscretFace::Add(const TopoDS_Face& theFace 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; @@ -617,26 +614,9 @@ void BRepMesh_FastDiscretFace::InternalVertices(const Handle(BRepAdaptor_HSurfac 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 diff --git a/src/BRepMesh/BRepMesh_IncrementalMesh.cxx b/src/BRepMesh/BRepMesh_IncrementalMesh.cxx index eb1a977220..7f8fcf926c 100755 --- a/src/BRepMesh/BRepMesh_IncrementalMesh.cxx +++ b/src/BRepMesh/BRepMesh_IncrementalMesh.cxx @@ -178,20 +178,11 @@ void BRepMesh_IncrementalMesh::Update(const TopoDS_Shape& S) 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()))) { @@ -231,7 +222,7 @@ void BRepMesh_IncrementalMesh::Update(const TopoDS_Shape& S) 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()) { @@ -242,23 +233,11 @@ void BRepMesh_IncrementalMesh::Update(const TopoDS_Shape& S) 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; @@ -279,8 +258,8 @@ void BRepMesh_IncrementalMesh::Update(const TopoDS_Shape& S) 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; @@ -305,6 +284,7 @@ void BRepMesh_IncrementalMesh::Update(const TopoDS_Edge& E) 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; @@ -313,33 +293,20 @@ void BRepMesh_IncrementalMesh::Update(const TopoDS_Edge& E) 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()); @@ -369,7 +336,7 @@ void BRepMesh_IncrementalMesh::Update(const TopoDS_Face& F) BRep_Builder B; TopExp_Explorer ex; - Standard_Real defedge, defface; + Standard_Real defedge, defface, cdef = 1.; Standard_Integer nbEdge = 0; if (myRelative) { defface = 0.; @@ -378,25 +345,10 @@ void BRepMesh_IncrementalMesh::Update(const TopoDS_Face& F) 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; @@ -407,18 +359,16 @@ void BRepMesh_IncrementalMesh::Update(const TopoDS_Face& F) 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; @@ -428,8 +378,8 @@ void BRepMesh_IncrementalMesh::Update(const TopoDS_Face& F) 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); }