1 // File: BRepMesh_FastDiscret.cxx
2 // Created: Tue Feb 27 16:39:53 1996
3 // Author: Ekaterina SMIRNOVA
4 // Copyright: Open CASCADE SAS 2008
6 #include <BRepMesh_FastDiscret.ixx>
8 #include <BRepMesh_FastDiscretFace.hxx>
9 #include <BRepMesh_FaceAttribute.hxx>
10 #include <BRepMesh_DataStructureOfDelaun.hxx>
11 #include <BRepMesh_ClassifierPtr.hxx>
12 #include <BRepMesh_GeomTool.hxx>
13 #include <BRepMesh_PairOfPolygon.hxx>
14 #include <BRepMesh_DataMapOfShapePairOfPolygon.hxx>
15 #include <BRepMesh_DataMapIteratorOfDataMapOfShapePairOfPolygon.hxx>
16 #include <Geom_Plane.hxx>
17 #include <GeomAbs_IsoType.hxx>
18 #include <GeomAbs_SurfaceType.hxx>
20 #include <TColStd_HArray1OfReal.hxx>
21 #include <Precision.hxx>
23 #include <BRep_Builder.hxx>
24 #include <BRep_Tool.hxx>
25 #include <Poly_Triangulation.hxx>
26 #include <Poly_PolygonOnTriangulation.hxx>
27 #include <Poly_Connect.hxx>
28 #include <TColStd_SequenceOfInteger.hxx>
29 #include <TColStd_Array1OfInteger.hxx>
30 #include <TColStd_HArray1OfInteger.hxx>
32 #include <TColgp_Array1OfPnt.hxx>
33 #include <TColgp_Array1OfPnt2d.hxx>
34 #include <Precision.hxx>
36 #include <BRepAdaptor_Curve.hxx>
37 #include <BRepAdaptor_Surface.hxx>
38 #include <BRepAdaptor_HSurface.hxx>
39 #include <BRepTools.hxx>
40 #include <BndLib_Add3dCurve.hxx>
41 #include <BRepBndLib.hxx>
42 #include <Bnd_Box.hxx>
45 #include <TopExp_Explorer.hxx>
47 #include <Geom2d_Curve.hxx>
49 #include <TColStd_DataMapOfIntegerInteger.hxx>
50 #include <BRepMesh_ShapeTool.hxx>
52 #include <Geom_Surface.hxx>
53 #include <Adaptor3d_IsoCurve.hxx>
54 #include <BRepMesh_IndexedMapOfVertex.hxx>
55 #include <Extrema_LocateExtPC.hxx>
57 #include <BRepMesh_ListOfXY.hxx>
58 #include <BRepMesh_ListIteratorOfListOfXY.hxx>
60 #include <TColStd_Array1OfInteger.hxx>
61 #include <BRepMesh_IDMapOfNodeOfDataStructureOfDelaun.hxx>
62 #include <Standard_ErrorHandler.hxx>
63 #include <Standard_Failure.hxx>
64 //#include <TColStd_DataMapOfInteger.hxx>
65 #include <TColGeom2d_SequenceOfCurve.hxx>
66 #include <TopTools_SequenceOfShape.hxx>
67 #include <NCollection_IncAllocator.hxx>
69 #include <BRep_ListIteratorOfListOfPointRepresentation.hxx>
70 #include <BRep_PointRepresentation.hxx>
71 #include <BRep_TVertex.hxx>
72 #include <TColStd_MapOfInteger.hxx>
73 #include <SortTools_ShellSortOfReal.hxx>
74 #include <TCollection_CompareOfReal.hxx>
76 #include <TopTools_HArray1OfShape.hxx>
77 #include <TopTools_ListIteratorOfListOfShape.hxx>
82 // paralleling using Intel TBB
83 #include <tbb/parallel_for_each.h>
86 #define UVDEFLECTION 1.e-05
88 inline Standard_Real MaxFaceTol (const TopoDS_Face& theFace)
90 Standard_Real T, TMax = BRep_Tool::Tolerance(theFace);
93 for (Ex.Init(theFace,TopAbs_EDGE); Ex.More(); Ex.Next())
95 T = BRep_Tool::Tolerance(TopoDS::Edge(Ex.Current()));
96 if (T > TMax) TMax = T;
99 for (Ex.Init(theFace,TopAbs_VERTEX); Ex.More(); Ex.Next())
101 T = BRep_Tool::Tolerance(TopoDS::Vertex(Ex.Current()));
102 if (T > TMax) TMax = T;
109 //=======================================================================
110 //function : BRepMesh_FastDiscret
112 //=======================================================================
113 BRepMesh_FastDiscret::BRepMesh_FastDiscret(const Standard_Real theDefle,
114 const Standard_Real theAngl,
115 const Bnd_Box& theBox,
116 const Standard_Boolean theWithShare,
117 const Standard_Boolean theInshape,
118 const Standard_Boolean theRelative,
119 const Standard_Boolean theShapetrigu) :
121 myDeflection (theDefle),
122 myWithShare (theWithShare),
123 myInParallel (Standard_False),
125 myRelative (theRelative),
126 myShapetrigu (theShapetrigu),
127 myInshape (theInshape)
129 myAllocator = new NCollection_IncAllocator(64000);
131 BoxMaxDimension(theBox, myDtotale);
134 //=======================================================================
135 //function : BRepMesh_FastDiscret
137 //=======================================================================
139 BRepMesh_FastDiscret::BRepMesh_FastDiscret(const Standard_Real theDefle,
140 const TopoDS_Shape& theShape,
141 const Bnd_Box& theBox,
142 const Standard_Real theAngl,
143 const Standard_Boolean theWithShare,
144 const Standard_Boolean theInshape,
145 const Standard_Boolean theRelative,
146 const Standard_Boolean theShapetrigu):
148 myDeflection (theDefle),
149 myWithShare (theWithShare),
150 myInParallel (Standard_False),
152 myRelative (theRelative),
153 myShapetrigu (theShapetrigu),
154 myInshape (theInshape)
156 myAllocator = new NCollection_IncAllocator(64000);
158 BoxMaxDimension(theBox, myDtotale);
162 //=======================================================================
163 //function : BoxMaxDimension
165 //=======================================================================
167 void BRepMesh_FastDiscret::BoxMaxDimension(const Bnd_Box& theBox, Standard_Real& theMaxDim)
171 Standard_Real TXmin, TYmin, TZmin, TXmax, TYmax, TZmax;
172 theBox.Get(TXmin, TYmin, TZmin, TXmax, TYmax, TZmax);
173 theMaxDim = TXmax-TXmin;
174 const Standard_Real dy = TYmax-TYmin;
175 const Standard_Real dz = TZmax-TZmin;
176 if (dy > theMaxDim) theMaxDim = dy;
177 if (dz > theMaxDim) theMaxDim = dz;
180 //=======================================================================
181 //function : RelativeEdgeDeflection
183 //=======================================================================
185 Standard_Real BRepMesh_FastDiscret::RelativeEdgeDeflection(const TopoDS_Edge& theEdge,
186 const Standard_Real theDefle,
187 const Standard_Real theDTotale,
188 Standard_Real& theDefCoef)
191 Standard_Real defedge = theDefle;
196 BRepBndLib::Add(theEdge, B);
197 BoxMaxDimension(B, defedge);
199 // adjusted in relation to the total size:
200 theDefCoef = theDTotale/(2*defedge);
201 if (theDefCoef < 0.5) theDefCoef = 0.5;
202 if (theDefCoef > 2.) theDefCoef = 2.;
203 defedge = theDefCoef * defedge * theDefle;
208 //=======================================================================
209 //function : Perform(shape)
211 //=======================================================================
213 void BRepMesh_FastDiscret::Perform(const TopoDS_Shape& theShape)
215 TopTools_IndexedDataMapOfShapeListOfShape anAncestors;
216 TopExp::MapShapesAndAncestors(theShape, TopAbs_EDGE, TopAbs_FACE, anAncestors);
217 std::vector<TopoDS_Face> aFaces;
218 for (TopExp_Explorer ex(theShape, TopAbs_FACE); ex.More(); ex.Next()) {
219 TopoDS_Face aF = TopoDS::Face(ex.Current());
220 Add(aF, anAncestors);
221 aFaces.push_back(aF);
227 // mesh faces in parallel threads using TBB
228 tbb::parallel_for_each (aFaces.begin(), aFaces.end(), *this);
230 // alternative parallelization not yet available
231 for (std::vector<TopoDS_Face>::iterator it(aFaces.begin()); it != aFaces.end(); it++)
237 for (std::vector<TopoDS_Face>::iterator it(aFaces.begin()); it != aFaces.end(); it++)
243 //=======================================================================
246 //=======================================================================
248 void BRepMesh_FastDiscret::Process(const TopoDS_Face& theFace) const
250 //cout << "START face " << theFace.TShape().operator->() << endl << flush;
251 Handle(BRepMesh_FaceAttribute) fattribute;
252 if ( GetFaceAttribute (theFace, fattribute) )
254 BRepMesh_FastDiscretFace aTool (GetAngle(), WithShare());
255 aTool.Add (theFace, fattribute, GetMapOfDefEdge());
257 //cout << "END face " << theFace.TShape().operator->() << endl << flush;
260 //=======================================================================
261 //function : Add(face)
263 //=======================================================================
265 #define MESH_FAILURE(theface) \
267 myFacestate = BRepMesh_Failure; \
268 myNottriangulated.Append(theface); \
272 void BRepMesh_FastDiscret::Add(const TopoDS_Face& theface,
273 const TopTools_IndexedDataMapOfShapeListOfShape& theAncestors)
280 TopoDS_Face face = theface;
281 BRepTools::Update(face);
282 face.Orientation(TopAbs_FORWARD);
283 myStructure.Nullify();
284 Handle(NCollection_IncAllocator) anAlloc = Handle(NCollection_IncAllocator)::DownCast(myAllocator);
285 anAlloc->Reset(Standard_False);
286 myStructure=new BRepMesh_DataStructureOfDelaun(anAlloc);
288 Standard_Real aXmin, aYmin, aZmin, aXmax, aYmax, aZmax;
289 BRepTools::UVBounds(theface, aXmin, aXmax, aYmin, aYmax);
290 Standard_Real aTolU = (aXmax - aXmin) * UVDEFLECTION;
291 Standard_Real aTolV = (aYmax - aYmin) * UVDEFLECTION;
292 myStructure->Data().SetCellSize ( 14 * aTolU, 14 * aTolV );
293 myStructure->Data().SetTolerance( aTolU, aTolV );
295 BRepAdaptor_Surface BS(face, Standard_False);
296 Handle(BRepAdaptor_HSurface) gFace = new BRepAdaptor_HSurface(BS);
298 GeomAbs_SurfaceType thetype;
299 thetype = BS.GetType();
301 gp_Pnt2d uvFirst, uvLast;
303 TopAbs_Orientation orFace = face.Orientation();
304 Handle(Poly_Triangulation) T;
313 myLocation2d.Clear();
314 myInternaledges.Clear();
319 Standard_Real defedge, defface;
320 Standard_Integer nbEdge = 0;
321 Standard_Real savangle = myAngle;
323 Standard_Real maxdef = 2.* MaxFaceTol(theface);
326 if (!myRelative) defface = Max(myDeflection, maxdef);
328 TColStd_SequenceOfReal aFSeq, aLSeq;
329 TColGeom2d_SequenceOfCurve aCSeq;
330 TopTools_SequenceOfShape aShSeq;
332 TopoDS_Iterator exW(face);
334 for (; exW.More(); exW.Next()) {
335 const TopoDS_Shape& aWire = exW.Value();
336 if (aWire.ShapeType() != TopAbs_WIRE)
338 TopoDS_Iterator ex(aWire);
339 for(; ex.More(); ex.Next()) {
340 const TopoDS_Edge& edge = TopoDS::Edge(ex.Value());
342 if (!myMapdefle.IsBound(edge)) {
344 if (myEdges.IsBound(edge)) {
345 const BRepMesh_PairOfPolygon& pair = myEdges.Find(edge);
346 const Handle(Poly_PolygonOnTriangulation)& P = pair.First();
347 defedge = P->Deflection();
350 defedge = RelativeEdgeDeflection(edge, myDeflection, myDtotale, cdef);
351 myAngle = savangle * cdef;
353 defface = defface + defedge;
354 defface = Max(maxdef, defface);
356 else defedge = myDeflection;
358 defedge = Max(maxdef, defedge);
359 defedge = Max(UVDEFLECTION , defedge);
360 myMapdefle.Bind(edge, defedge);
363 defedge = myMapdefle(edge);
364 if (myRelative) {defface = defface + defedge; defface = Max(maxdef, defface);}
367 Handle(Geom2d_Curve) C = BRep_Tool::CurveOnSurface(edge, face, f1, l1);
368 if (C.IsNull()) continue;
374 Add(edge, face, gFace, C, theAncestors, defedge, f1, l1);
379 if (nbEdge == 0 || myVemap.Extent() < 3)
381 MESH_FAILURE(theface);
384 if (myRelative ) defface = defface / nbEdge;
385 else defface = myDeflection;
387 if (myWithShare) defface = Max(maxdef, defface);
389 T = BRep_Tool::Triangulation(face, loc);
391 if (!myShapetrigu || T.IsNull()) {
393 Standard_Real xCur, yCur;
394 Standard_Real maxX, minX, maxY, minY;
398 Standard_Integer ipn = 0;
399 Standard_Integer i1 =1;
400 for (i1 = 1; i1 <= myVemap.Extent(); i1++) {
401 const BRepMesh_Vertex& aV = myStructure->GetNode(myVemap.FindKey(i1));
405 minX=Min(xCur, minX);
406 maxX=Max(xCur, maxX);
407 minY=Min(yCur, minY);
408 maxY=Max(yCur, maxY);
410 Standard_Real myumin = minX;
411 Standard_Real myumax = maxX;
412 Standard_Real myvmin = minY;
413 Standard_Real myvmax = maxY;
415 const Standard_Real umin = BS.FirstUParameter();
416 const Standard_Real umax = BS.LastUParameter();
417 const Standard_Real vmin = BS.FirstVParameter();
418 const Standard_Real vmax = BS.LastVParameter();
420 if (myumin < umin || myumax > umax)
422 if (BS.IsUPeriodic())
424 if ((myumax - myumin) > (umax - umin))
426 myumax = myumin + (umax - umin);
431 if (umin > myumin) myumin = umin;
432 if (umax < myumax) myumax = umax;
436 if (myvmin < vmin || myvmax > vmax)
438 if (BS.IsVPeriodic())
440 if ((myvmax - myvmin) > (vmax - vmin))
442 myvmax = myvmin + (vmax - vmin);
447 if (vmin > myvmin) myvmin = vmin;
448 if (vmax < myvmax) myvmax = vmax;
452 // fast verification of the validity of calculated limits. If wrong,
453 // sure a problem of pcurve.
454 if (thetype == GeomAbs_BezierSurface &&
455 (myumin < -0.5 || myumax > 1.5 || myvmin < -0.5 || myvmax > 1.5))
457 MESH_FAILURE(theface);
460 //define parameters for correct parametrics
462 Standard_Real deltaX = 1.0;
463 Standard_Real deltaY = 1.0;
464 Standard_Integer nbVertices = myVemap.Extent();
465 const Standard_Real tolclass = Precision::PConfusion(); //0.03*Max(myumax-myumin, myvmax-myvmin);
467 BRepMesh_ClassifierPtr classifier (
468 new BRepMesh_Classifier(face, tolclass, myInternaledges, myVemap,
469 myStructure, myumin, myumax, myvmin, myvmax) );
471 myFacestate = classifier->State();
472 if (myFacestate == BRepMesh_SelfIntersectingWire)
474 Standard_Integer nbmaill = 0;
475 Standard_Real eps = Precision::Confusion();
476 while (nbmaill < 5 && myFacestate != BRepMesh_ReMesh)
480 //clear the structure of links
481 myStructure.Nullify();
482 myStructure = new BRepMesh_DataStructureOfDelaun(anAlloc);
485 myLocation2d.Clear();
486 myInternaledges.Clear();
489 for(j1 = 1; j1 <= aShSeq.Length(); j1++)
491 const TopoDS_Edge& edge = TopoDS::Edge(aShSeq.Value(j1));
492 if (myEdges.IsBound(edge))
494 myEdges.UnBind(edge);
495 myInternaledges.UnBind(edge);
500 for( j1 = 1; j1 <= aShSeq.Length(); j1++)
502 const TopoDS_Edge& edge = TopoDS::Edge(aShSeq.Value(j1));
503 defedge = myMapdefle(edge) / 3.;
504 defedge = Max(defedge, eps);
505 myMapdefle.Bind(edge, defedge);
506 const Handle(Geom2d_Curve)& C = aCSeq.Value(j1);
507 Add(edge, face, gFace, C, theAncestors, defedge, aFSeq.Value(j1), aLSeq.Value(j1));
510 classifier.Nullify();
512 classifier = new BRepMesh_Classifier(face, tolclass, myInternaledges, myVemap,
513 myStructure, myumin, myumax, myvmin, myvmax);
515 if (classifier->State() == BRepMesh_NoError)
517 myFacestate = BRepMesh_ReMesh;
519 nbVertices = myVemap.Extent();
523 if (myFacestate != BRepMesh_NoError && myFacestate != BRepMesh_ReMesh)
525 myNottriangulated.Append(face);
526 classifier.Nullify();
530 // try to find the real length:
531 // akm (bug OCC16) : We must calculate these measures in non-singular
532 // parts of face. Let's try to compute average value of three
533 // (umin, (umin+umax)/2, umax), and respectively for v.
535 Standard_Real longu = 0.0, longv = 0.0; //, last , first;
536 gp_Pnt P11, P12, P21, P22, P31, P32;
538 Standard_Real du = (myumax-myumin)/20;
539 Standard_Real dv = (myvmax-myvmin)/20;
540 Standard_Real dfuave=(myumin+myumax)/2, dfucur;
541 Standard_Real dfvave=(myvmin+myvmax)/2, dfvcur;
543 BS.D0 (myumin, myvmin, P11);
544 BS.D0 (myumin, dfvave, P21);
545 BS.D0 (myumin, myvmax, P31);
546 for (i1=1, dfucur=myumin+du; i1 <= 20; i1++, dfucur+=du) {
547 BS.D0 (dfucur, myvmin, P12);
548 BS.D0 (dfucur, dfvave, P22);
549 BS.D0 (dfucur, myvmax, P32);
550 longu += ( P11.Distance(P12) + P21.Distance(P22) + P31.Distance(P32) );
556 BS.D0(myumin, myvmin, P11);
557 BS.D0(dfuave, myvmin, P21);
558 BS.D0(myumax, myvmin, P31);
559 for (i1=1, dfvcur=myvmin+dv; i1 <= 20; i1++, dfvcur+=dv) {
560 BS.D0 (myumin, dfvcur, P12);
561 BS.D0 (dfuave, dfvcur, P22);
562 BS.D0 (myumax, dfvcur, P32);
563 longv += ( P11.Distance(P12) + P21.Distance(P22) + P31.Distance(P32) );
570 // akm (bug OCC16) ^^^^^
572 if (longu <= 1.e-16 || longv <= 1.e-16) {
574 #ifdef DEB_MESH_CHRONO
576 MESH_CHRONO_TSTOP(thetype);
578 MESH_FAILURE(theface);
582 if (thetype == GeomAbs_Torus) {
583 gp_Torus Tor = BS.Torus();
584 Standard_Real r = Tor.MinorRadius(), R = Tor.MajorRadius();
585 Standard_Real Du, Dv;//, pasu, pasv;
587 Dv = Max(1.0e0 - (defface/r),0.0e0) ;
588 Standard_Real oldDv = 2.0 * ACos (Dv);
589 oldDv = Min(oldDv, myAngle);
590 Dv = 0.9*oldDv; //TWOTHIRD * oldDv;
593 Standard_Integer nbV = Max((Standard_Integer)((myvmax-myvmin)/Dv), 2);
594 Dv = (myvmax-myvmin)/(nbV+1);
596 Standard_Real ru = R + r;
598 Du = Max(1.0e0 - (defface/ru),0.0e0);
599 Du = (2.0 * ACos (Du));
600 Du = Min(Du, myAngle);
601 Standard_Real aa = sqrt(Du*Du + oldDv*oldDv);
602 if(aa < gp::Resolution())
605 Du = Du * Min(oldDv, Du) / aa;
609 Standard_Integer nbU = Max((Standard_Integer)((myumax-myumin)/Du), 2);
610 nbU = Max(nbU, (Standard_Integer)(nbV*(myumax-myumin)*R/((myvmax-myvmin)*r)/5.));
612 Du = (myumax-myumin)/(nbU+1);
613 //-- DeltaX and DeltaY are chosen so that to avoid "jumping"
614 //-- of points on the grid
618 else if (thetype == GeomAbs_Cylinder) {
619 /*Standard_Real aMax = Max(myumax,myvmax);
620 deltaX = 0.01; //1./aMax; //0.01;
622 gp_Cylinder Cyl = BS.Cylinder();
623 Standard_Real R = Cyl.Radius();
624 // Calculate parameters for iteration in U direction
625 Standard_Real Du = 1.0 - (defface/R);
626 if (Du < 0.0) Du = 0.0;
627 Du = 2.0 * ACos (Du);
628 if (Du > GetAngle()) Du = GetAngle();
633 deltaX = (myumax-myumin)/longu;
634 deltaY = (myvmax-myvmin)/longv;
637 if(!myMapattrib.IsBound(theface))
639 Handle(BRepMesh_FaceAttribute) aFA = new BRepMesh_FaceAttribute();
640 aFA->GetDefFace() = defface;
641 aFA->GetUMax() = myumax;
642 aFA->GetVMax() = myvmax;
643 aFA->GetUMin() = myumin;
644 aFA->GetVMin() = myvmin;
645 aFA->GetDeltaX() = deltaX;
646 aFA->GetDeltaY() = deltaY;
647 aFA->GetMinX() = minX;
648 aFA->GetMinY() = minY;
649 aFA->GetClassifier() = classifier;
650 myMapattrib.Bind(theface, aFA);
653 //Standard_Integer nbVertices = myVemap.Extent();
654 T = new Poly_Triangulation(nbVertices, 1, Standard_True);
655 TColgp_Array1OfPnt& Nodes = T->ChangeNodes();
656 TColgp_Array1OfPnt2d& Nodes2d = T->ChangeUVNodes();
658 Standard_Integer index;
659 for (i = 1; i <= nbVertices; i++) {
660 index = myVemap.FindKey(i);
661 Nodes(i) = Pnt(index);
662 Nodes2d(i).SetXY(Vertex(index).Coord());
665 // storage of triangulation in the BRep.
666 //TopLoc_Location loc = face.Location();
667 if (!loc.IsIdentity()) {
668 gp_Trsf tr = loc.Transformation();
670 for (i = Nodes.Lower(); i <= Nodes.Upper(); i++)
671 Nodes(i).Transform(tr);
675 B.UpdateFace(face, T);
677 BRepMesh_DataMapIteratorOfDataMapOfShapePairOfPolygon It(myInternaledges);
678 for (; It.More(); It.Next()) {
679 const BRepMesh_PairOfPolygon& pair = It.Value();
680 const Handle(Poly_PolygonOnTriangulation)& NOD1 = pair.First();
681 const Handle(Poly_PolygonOnTriangulation)& NOD2 = pair.Last();
683 B.UpdateEdge(TopoDS::Edge(It.Key()), NOD1, T, loc);
685 B.UpdateEdge(TopoDS::Edge(It.Key()), NOD1, NOD2, T, loc);
691 catch(Standard_Failure)
693 MESH_FAILURE(theface);
696 myStructure.Nullify();
699 //=======================================================================
700 //function : splitSegment
702 //=======================================================================
703 static void splitSegment( BRepMesh_GeomTool& theGT,
704 const Handle(Geom_Surface)& theSurf,
705 const Handle(Geom2d_Curve)& theCurve2d,
706 const BRepAdaptor_Curve& theBAC,
707 const Standard_Real theSquareEDef,
708 const Standard_Real theFirst,
709 const Standard_Real theLast,
710 const Standard_Integer theNbIter)
712 //limit ineration depth
715 gp_Pnt2d uvf, uvl, uvm;
716 gp_Pnt P3dF, P3dL, midP3d, midP3dFromSurf;
717 Standard_Real midpar;
719 if(Abs(theLast - theFirst) < 2*Precision::PConfusion())
722 theCurve2d->D0(theFirst, uvf);
723 theCurve2d->D0(theLast, uvl);
725 P3dF = theSurf->Value(uvf.X(), uvf.Y());
726 P3dL = theSurf->Value(uvl.X(), uvl.Y());
728 if(P3dF.SquareDistance(P3dL) < theSquareEDef)
731 uvm = gp_Pnt2d((uvf.XY() + uvl.XY())*0.5);
732 midP3dFromSurf = theSurf->Value(uvm.X(), uvm.Y());
734 gp_XYZ aVec = P3dL.XYZ()-P3dF.XYZ();
737 gp_XYZ Vec1 = midP3dFromSurf.XYZ() - P3dF.XYZ();
738 Standard_Real aModulus = Vec1.Dot(aVec);
739 gp_XYZ aProj = aVec*aModulus;
740 gp_XYZ aDist = Vec1 - aProj;
742 if(aDist.SquareModulus() < theSquareEDef)
745 midpar = (theFirst + theLast) * 0.5;
746 theBAC.D0(midpar, midP3d);
747 theGT.AddPoint(midP3d, midpar, Standard_False);
749 splitSegment(theGT, theSurf, theCurve2d, theBAC, theSquareEDef, theFirst, midpar, theNbIter+1);
750 splitSegment(theGT, theSurf, theCurve2d, theBAC, theSquareEDef, midpar, theLast, theNbIter+1);
753 //=======================================================================
756 //=======================================================================
757 void BRepMesh_FastDiscret::Add( const TopoDS_Edge& theEdge,
758 const TopoDS_Face& theFace,
759 const Handle(BRepAdaptor_HSurface)& theGFace,
760 const Handle(Geom2d_Curve)& theC2d,
761 const TopTools_IndexedDataMapOfShapeListOfShape& theAncestors,
762 const Standard_Real theDefEdge,
763 const Standard_Real theFirst,
764 const Standard_Real theLast)
766 const TopAbs_Orientation orEdge = theEdge.Orientation();
767 if (orEdge == TopAbs_EXTERNAL) return;
769 const Standard_Boolean isEdgeBound = myEdges.IsBound(theEdge);
773 if (Update(theEdge, theFace, theC2d, theDefEdge, theFirst, theLast))
779 TopoDS_Vertex pBegin, pEnd;
780 TopExp::Vertices(theEdge, pBegin, pEnd);
781 if (pBegin.IsNull() || pEnd.IsNull())
786 Standard_Real wFirst, wLast;
787 BRep_Tool::Range(theEdge, theFace, wFirst, wLast);
789 gp_Pnt2d uvFirst, uvLast;
790 BRep_Tool::UVPoints(theEdge, theFace, uvFirst, uvLast);
792 const Standard_Boolean sameUV = uvFirst.IsEqual(uvLast, Precision::PConfusion());
794 //Control vertexes tolerances
795 gp_Pnt pFirst = theGFace->Value(uvFirst.X(), uvFirst.Y());
796 gp_Pnt pLast = theGFace->Value(uvLast.X(), uvLast.Y());
798 Standard_Real mindist = 10. * Max(pFirst.Distance(BRep_Tool::Pnt(pBegin)),
799 pLast.Distance(BRep_Tool::Pnt(pEnd)));
801 if(mindist < BRep_Tool::Tolerance(pBegin) ||
802 mindist < BRep_Tool::Tolerance(pEnd) ) mindist = theDefEdge;
804 // control of degenerated non-coded edges.
806 Standard_Boolean degener = BRep_Tool::Degenerated(theEdge);
810 if (pBegin.IsSame(pEnd))
812 // calculation of the length of the edge in 3D
813 Standard_Real longueur = 0.0;
814 Standard_Real du = (wLast-wFirst)/20;
816 BRepAdaptor_Curve BC(theEdge);
818 Standard_Real tolV = BRep_Tool::Tolerance(pBegin);
819 Standard_Real tolV2 = 1.2*tolV;
820 for (Standard_Integer l = 1; l <= 20; l++) {
821 BC.D0(wFirst + l*du, P2);
822 longueur += P1.Distance(P2);
823 if (longueur > tolV2) break;
827 if (longueur < tolV2)
829 degener = Standard_True;
837 // 1. is it really sameUV without being degenerated
839 theC2d->D0(theFirst, uvF);
840 theC2d->D0(theLast, uvL);
841 if (!uvFirst.IsEqual(uvF, Precision::PConfusion()))
845 if (!uvLast.IsEqual(uvL, Precision::PConfusion()))
853 // Process first vertex
854 Standard_Integer ipf;
855 if (myVertices.IsBound(pBegin))
857 ipf = myVertices.Find(pBegin);
861 if (sameUV && myVertices.IsBound(pEnd))
863 ipf = myVertices.Find(pEnd);
869 myLocation3d.Bind(ipf, BRep_Tool::Pnt(pBegin));
871 myVertices.Bind(pBegin, ipf);
873 theUV = BRepMesh_FastDiscretFace::FindUV(pBegin, uvFirst, ipf, theGFace, mindist, myLocation2d);
874 BRepMesh_Vertex vf(theUV, ipf, BRepMesh_Frontier);
875 Standard_Integer ivf = myStructure->AddNode(vf);
877 // Process last vertex
878 Standard_Integer ipl;
879 if (pEnd.IsSame(pBegin))
885 if (myVertices.IsBound(pEnd))
887 ipl = myVertices.Find(pEnd);
899 myLocation3d.Bind(ipl, BRep_Tool::Pnt(pEnd));
901 myVertices.Bind(pEnd,ipl);
904 theUV = BRepMesh_FastDiscretFace::FindUV(pEnd, uvLast, ipl, theGFace, mindist, myLocation2d);
905 BRepMesh_Vertex vl(theUV, ipl, BRepMesh_Frontier);
906 Standard_Integer ivl= myStructure->AddNode(vl);
908 Standard_Integer isvf = myVemap.FindIndex(ivf);
909 if (isvf == 0) isvf = myVemap.Add(ivf);
910 Standard_Integer isvl = myVemap.FindIndex(ivl);
911 if (isvl == 0) isvl = myVemap.Add(ivl);
913 Standard_Real otherdefedge = 0.5*theDefEdge;
918 Handle(Poly_PolygonOnTriangulation) P1;
922 Handle(Poly_PolygonOnTriangulation) P2;
927 TColStd_Array1OfInteger Nodes(1, 2), NodInStruct(1, 2);
928 TColStd_Array1OfReal Param(1, 2);
930 NodInStruct(1) = ipf;
934 NodInStruct(2) = ipl;
938 P1 = new Poly_PolygonOnTriangulation(Nodes, Param);
939 P2 = new Poly_PolygonOnTriangulation(NodInStruct, Param);
943 if (orEdge == TopAbs_INTERNAL) otherdefedge *= 0.5;
945 BRepAdaptor_Curve cons;
946 Standard_Boolean isSameParam = BRep_Tool::SameParameter(theEdge);
949 cons.Initialize(theEdge);
953 cons.Initialize(theEdge, theFace);
957 Standard_Integer nbpmin = 2;
958 if (cons.GetType() == GeomAbs_Circle) nbpmin = 4; //OCC287
959 BRepMesh_GeomTool GT(cons, wFirst, wLast, 0.5*myAngle, otherdefedge, nbpmin);
961 // PTv, chl/922/G9, Take into account internal vertices
962 // it is necessary for internal edges, which do not split other edges, by their vertex
963 TopoDS_Iterator exV(theEdge);
964 for ( ; exV.More(); exV.Next() )
966 TopoDS_Vertex aIntV = TopoDS::Vertex(exV.Value());
967 if ( aIntV.Orientation() == TopAbs_INTERNAL )
968 GT.AddPoint(BRep_Tool::Pnt(aIntV),
969 BRep_Tool::Parameter(aIntV, theEdge),
974 Standard_Integer nbnodes = GT.NbPoints();
975 //Check deflection in 2d space for improvement of edge tesselation.
976 if( isSameParam && nbnodes > 1)
978 Standard_Real aSquareEdgeDef = otherdefedge * otherdefedge;
979 const TopTools_ListOfShape& lf = theAncestors.FindFromKey(theEdge);
980 TopTools_ListIteratorOfListOfShape itl(lf);
981 for (; itl.More(); itl.Next()) {
982 const TopoDS_Face& aFace = TopoDS::Face (itl.Value());
984 TopLoc_Location aLoc;
985 Standard_Real aF, aL;
986 Handle(Geom_Surface) aSurf = BRep_Tool::Surface(aFace, aLoc);
987 const Handle(Standard_Type)& aType = aSurf->DynamicType();
988 if(aType == STANDARD_TYPE(Geom_Plane))
990 Handle(Geom2d_Curve) aCurve2d = BRep_Tool::CurveOnSurface(theEdge, aFace, aF, aL);
991 if(Abs(aF-wFirst)>Precision::PConfusion()||Abs(aL-wLast)>Precision::PConfusion())
996 nbnodes = GT.NbPoints();
997 TColStd_Array1OfReal aParamArray(1, nbnodes);
998 for (i = 1; i <= nbnodes; i++)
1000 GT.Value(cons, theGFace, i, parf, P3d, uvf);
1001 aParamArray.SetValue(i, parf);
1003 for (i = 1; i < nbnodes; i++)
1005 splitSegment(GT, aSurf, aCurve2d, cons, aSquareEdgeDef, aParamArray(i), aParamArray(i+1), 1);
1010 // Creation of polygons on triangulation:
1012 nbnodes = GT.NbPoints();
1014 TColStd_Array1OfInteger Nodes(1, nbnodes);
1015 TColStd_Array1OfInteger NodInStruct(1, nbnodes);
1016 TColStd_Array1OfReal Param(1, nbnodes);
1018 // processing of the 1st point:
1020 NodInStruct(1) = ipf;
1024 Nodes(nbnodes) = isvl;
1025 NodInStruct(nbnodes) = ipl;
1026 Param(nbnodes) = wLast;
1030 Standard_Integer iv2;
1031 for (i = 2; i < GT.NbPoints(); i++)
1034 GT.Value(cons, theGFace, i, puv, P3d, uv);
1036 myLocation3d.Bind(myNbLocat, P3d);
1037 NodInStruct(i) = myNbLocat;
1039 v2.Initialize(uv.Coord(), myNbLocat, BRepMesh_OnCurve);
1040 iv2=myStructure->AddNode(v2);
1042 Standard_Integer isv = myVemap.FindIndex(iv2);
1043 if (isv == 0) isv = myVemap.Add(iv2);
1045 NodInStruct(i) = myNbLocat;
1048 if (orEdge == TopAbs_FORWARD)
1049 myStructure->AddLink(BRepMesh_Edge(ivf, iv2, BRepMesh_Frontier));
1050 else if (orEdge == TopAbs_REVERSED)
1051 myStructure->AddLink(BRepMesh_Edge(iv2, ivf, BRepMesh_Frontier));
1052 else if (orEdge == TopAbs_INTERNAL)
1053 myStructure->AddLink(BRepMesh_Edge(ivf, iv2, BRepMesh_Fixed));
1058 P1 = new Poly_PolygonOnTriangulation(Nodes, Param);
1059 P2 = new Poly_PolygonOnTriangulation(NodInStruct, Param);
1062 P2->Deflection(otherdefedge);
1063 BRepMesh_PairOfPolygon pair;
1065 myEdges.Bind(theEdge, pair);
1068 if (orEdge == TopAbs_FORWARD)
1069 myStructure->AddLink(BRepMesh_Edge(ivf, ivl, BRepMesh_Frontier));
1070 else if (orEdge == TopAbs_REVERSED)
1071 myStructure->AddLink(BRepMesh_Edge(ivl, ivf, BRepMesh_Frontier));
1072 else if (orEdge == TopAbs_INTERNAL)
1073 myStructure->AddLink(BRepMesh_Edge(ivf, ivl, BRepMesh_Fixed));
1078 // If this Edge has been already checked and it is not degenerated,
1079 // the points of the polygon calculated at the first check are retrieved :
1084 // Create 2d polygon for degenerated edge
1085 TColStd_Array1OfInteger Nodes(1, 2);
1086 TColStd_Array1OfReal PPar(1, 2);
1094 P1 = new Poly_PolygonOnTriangulation(Nodes, PPar);
1098 // retrieve the polygone:
1099 const BRepMesh_PairOfPolygon& pair = myEdges.Find(theEdge);
1100 const Handle(Poly_PolygonOnTriangulation)& P = pair.First();
1101 const TColStd_Array1OfInteger& NOD = P->Nodes();
1102 Handle(TColStd_HArray1OfReal) Par = P->Parameters();
1105 const Standard_Integer nbnodes = NOD.Length();
1106 TColStd_Array1OfInteger Nodes(1, nbnodes);
1107 TColStd_Array1OfReal PPar(1, nbnodes);
1108 Standard_Integer iv2;
1113 Nodes(nbnodes) = isvl;
1114 PPar(nbnodes) = wLast;
1119 if (BRep_Tool::SameParameter(theEdge))
1121 for (i = 2; i < nbnodes; i++)
1123 const Standard_Real puv = Par->Value(i);
1124 theC2d->D0(puv, uv);
1125 v2.Initialize(uv.Coord(), NOD(i), BRepMesh_OnCurve);
1126 iv2 = myStructure->AddNode(v2);
1128 Standard_Integer isv = myVemap.FindIndex(iv2);
1129 if (isv == 0) isv = myVemap.Add(iv2);
1133 if (orEdge==TopAbs_FORWARD)
1134 myStructure->AddLink(BRepMesh_Edge(ivf, iv2, BRepMesh_Frontier));
1135 else if (orEdge == TopAbs_REVERSED)
1136 myStructure->AddLink(BRepMesh_Edge(iv2, ivf, BRepMesh_Frontier));
1137 else if (orEdge == TopAbs_INTERNAL)
1138 myStructure->AddLink(BRepMesh_Edge(ivf, iv2, BRepMesh_Fixed));
1145 const Standard_Real wFold = Par->Value(Par->Lower());
1146 const Standard_Real wLold = Par->Value(Par->Upper());
1148 Standard_Real wKoef = 1.;
1149 if ((wFold != wFirst || wLold != wLast) && wLold != wFold)
1151 wKoef = (wLast - wFirst) / (wLold - wFold);
1154 BRepAdaptor_Curve cons(theEdge, theFace);
1155 Extrema_LocateExtPC pcos;
1156 pcos.Initialize(cons, cons.FirstParameter(),
1157 cons.LastParameter(), Precision::PConfusion());
1159 Standard_Real wPrev;
1160 Standard_Real wCur = wFirst;
1161 Standard_Real wCurFound = wFirst;
1162 for (i = 2; i < nbnodes; i++)
1164 P3d = myLocation3d(NOD(i));
1167 wCur = wFirst + wKoef*(Par->Value(i) - wFold);
1168 wCurFound += (wCur - wPrev);
1169 pcos.Perform(P3d, wCurFound);
1170 if (pcos.IsDone()) wCurFound = pcos.Point().Parameter();
1171 theC2d->D0(wCurFound, uv);
1172 v2.Initialize(uv.Coord(), NOD(i), BRepMesh_OnCurve);
1173 iv2 = myStructure->AddNode(v2);
1175 Standard_Integer isv = myVemap.FindIndex(iv2);
1176 if (isv == 0) isv = myVemap.Add(iv2);
1178 PPar(i) = wCurFound;
1180 if (orEdge==TopAbs_FORWARD)
1181 myStructure->AddLink(BRepMesh_Edge(ivf, iv2, BRepMesh_Frontier));
1182 else if (orEdge == TopAbs_REVERSED)
1183 myStructure->AddLink(BRepMesh_Edge(iv2, ivf, BRepMesh_Frontier));
1184 else if (orEdge == TopAbs_INTERNAL)
1185 myStructure->AddLink(BRepMesh_Edge(ivf, iv2, BRepMesh_Fixed));
1192 P1 = new Poly_PolygonOnTriangulation(Nodes, PPar);
1195 if (orEdge == TopAbs_FORWARD)
1196 myStructure->AddLink(BRepMesh_Edge(ivf, ivl, BRepMesh_Frontier));
1197 else if (orEdge == TopAbs_REVERSED)
1198 myStructure->AddLink(BRepMesh_Edge(ivl, ivf, BRepMesh_Frontier));
1199 else if (orEdge == TopAbs_INTERNAL)
1200 myStructure->AddLink(BRepMesh_Edge(ivf, ivl, BRepMesh_Fixed));
1205 P1->Deflection(theDefEdge);
1206 if (myInternaledges.IsBound(theEdge))
1208 BRepMesh_PairOfPolygon& pair = myInternaledges.ChangeFind(theEdge);
1209 if (orEdge == TopAbs_REVERSED)
1216 BRepMesh_PairOfPolygon pair1;
1218 myInternaledges.Bind(theEdge, pair1);
1223 //=======================================================================
1224 //function : Update(edge)
1226 //=======================================================================
1227 Standard_Boolean BRepMesh_FastDiscret::Update(const TopoDS_Edge& theEdge,
1228 const TopoDS_Face& theFace,
1229 const Handle(Geom2d_Curve)& theC2d,
1230 const Standard_Real theDefEdge,
1231 const Standard_Real theFirst,
1232 const Standard_Real theLast)
1234 TopLoc_Location Loc;
1235 Handle(Poly_Triangulation) T, TNull;
1236 Handle(Poly_PolygonOnTriangulation) Poly, NullPoly;
1238 Standard_Integer i = 1;
1239 Standard_Boolean found = Standard_False;
1242 BRep_Tool::PolygonOnTriangulation(theEdge,Poly,T,Loc,i);
1244 if (!found && !T.IsNull() && T->HasUVNodes() &&
1245 !Poly.IsNull() && Poly->HasParameters())
1247 if (Poly->Deflection() <= 1.1*theDefEdge)
1249 // 2d vertex indices
1250 TopAbs_Orientation orEdge = theEdge.Orientation();
1251 Standard_Integer iv1, iv2, ivl;
1252 Standard_Integer isv1, isv, isvl;
1254 // Get range on 2d curve
1255 Standard_Real wFirst, wLast;
1256 BRep_Tool::Range(theEdge, theFace, wFirst, wLast);
1258 // Get end points on 2d curve
1259 gp_Pnt2d uvFirst, uvLast;
1260 BRep_Tool::UVPoints(theEdge, theFace, uvFirst, uvLast);
1263 TopoDS_Vertex pBegin, pEnd;
1264 TopExp::Vertices(theEdge,pBegin,pEnd);
1266 const Standard_Boolean sameUV =
1267 uvFirst.IsEqual(uvLast, Precision::PConfusion());
1269 //Controle vertice tolerances
1270 BRepAdaptor_Surface BS(theFace, Standard_False);
1271 Handle(BRepAdaptor_HSurface) gFace = new BRepAdaptor_HSurface(BS);
1274 gp_Pnt pFirst = gFace->Value(uvFirst.X(), uvFirst.Y());
1275 gp_Pnt pLast = gFace->Value(uvLast.X(), uvLast.Y());
1277 Standard_Real mindist = 10. * Max(pFirst.Distance(BRep_Tool::Pnt(pBegin)),
1278 pLast.Distance(BRep_Tool::Pnt(pEnd)));
1280 if (mindist < BRep_Tool::Tolerance(pBegin) ||
1281 mindist < BRep_Tool::Tolerance(pEnd) ) mindist = theDefEdge;
1285 // 1. is it really sameUV without being degenerated
1287 theC2d->D0(theFirst, uvF);
1288 theC2d->D0(theLast, uvL);
1289 if (!uvFirst.IsEqual(uvF, Precision::PConfusion())) {
1292 if (!uvLast.IsEqual(uvL, Precision::PConfusion())) {
1297 const TColgp_Array1OfPnt& Nodes = T->Nodes();
1298 const TColStd_Array1OfInteger& Indices = Poly->Nodes();
1299 Handle(TColStd_HArray1OfReal) Param = Poly->Parameters();
1301 const Standard_Integer nbnodes = Indices.Length();
1302 TColStd_Array1OfInteger NewNodes(1, nbnodes);
1303 TColStd_Array1OfInteger NewNodInStruct(1, nbnodes);
1308 // Process first vertex
1309 Standard_Integer ipf;
1310 if (myVertices.IsBound(pBegin))
1312 ipf = myVertices.Find(pBegin);
1316 if (sameUV && myVertices.IsBound(pEnd))
1318 ipf = myVertices.Find(pEnd);
1322 P3d = Nodes(Indices(1));
1323 if (!Loc.IsIdentity())
1324 P3d.Transform(Loc.Transformation());
1326 myLocation3d.Bind(myNbLocat,P3d);
1329 myVertices.Bind(pBegin,ipf);
1331 NewNodInStruct(1) = ipf;
1332 theUV = BRepMesh_FastDiscretFace::FindUV(pBegin, uvFirst, ipf, gFace, mindist, myLocation2d);
1333 BRepMesh_Vertex vf(theUV,ipf,BRepMesh_Frontier);
1334 iv1 = myStructure->AddNode(vf);
1335 isv1 = myVemap.FindIndex(iv1);
1336 if (isv1 == 0) isv1 = myVemap.Add(iv1);
1339 // Process last vertex
1340 Standard_Integer ipl;
1341 if (pEnd.IsSame(pBegin))
1347 if (myVertices.IsBound(pEnd))
1349 ipl = myVertices.Find(pEnd);
1362 myLocation3d.Bind(myNbLocat,Nodes(Indices(nbnodes)).Transformed(Loc.Transformation()));
1365 myVertices.Bind(pEnd,ipl);
1368 NewNodInStruct(nbnodes) = ipl;
1369 theUV = BRepMesh_FastDiscretFace::FindUV(pEnd, uvLast, ipl, gFace, mindist, myLocation2d);
1370 BRepMesh_Vertex vl(theUV,ipl,BRepMesh_Frontier);
1372 ivl = myStructure->AddNode(vl);
1373 isvl = myVemap.FindIndex(ivl);
1374 if (isvl == 0) isvl = myVemap.Add(ivl);
1376 NewNodes(nbnodes) = isvl;
1381 if (BRep_Tool::SameParameter(theEdge))
1383 for (i = 2; i < Indices.Length(); i++)
1386 P3d = Nodes(Indices(i));
1387 if (!Loc.IsIdentity())
1388 P3d.Transform(Loc.Transformation());
1390 myLocation3d.Bind(myNbLocat, P3d);
1391 NewNodInStruct(i) = myNbLocat;
1393 uv = theC2d->Value(Param->Value(i));
1394 v.Initialize(uv.Coord(), myNbLocat, BRepMesh_Frontier);
1395 iv2 = myStructure->AddNode(v);
1396 isv = myVemap.FindIndex(iv2);
1397 if (isv == 0) isv = myVemap.Add(iv2);
1401 if (orEdge == TopAbs_FORWARD)
1402 myStructure->AddLink(BRepMesh_Edge(iv1,iv2,BRepMesh_Frontier));
1403 else if (orEdge == TopAbs_REVERSED)
1404 myStructure->AddLink(BRepMesh_Edge(iv2,iv1,BRepMesh_Frontier));
1405 else if (orEdge == TopAbs_INTERNAL)
1406 myStructure->AddLink(BRepMesh_Edge(iv1,iv2,BRepMesh_Fixed));
1412 if (orEdge == TopAbs_FORWARD)
1413 myStructure->AddLink(BRepMesh_Edge(iv1,ivl,BRepMesh_Frontier));
1414 else if (orEdge == TopAbs_REVERSED)
1415 myStructure->AddLink(BRepMesh_Edge(ivl,iv1,BRepMesh_Frontier));
1416 else if (orEdge == TopAbs_INTERNAL)
1417 myStructure->AddLink(BRepMesh_Edge(iv1,ivl,BRepMesh_Fixed));
1424 const Standard_Real wFold = Param->Value(Param->Lower());
1425 const Standard_Real wLold = Param->Value(Param->Upper());
1427 Standard_Real wKoef = 1.;
1428 if ((wFold != wFirst || wLold != wLast) && wLold != wFold)
1430 wKoef = (wLast - wFirst) / (wLold - wFold);
1433 BRepAdaptor_Curve cons(theEdge, theFace);
1434 Extrema_LocateExtPC pcos;
1435 pcos.Initialize(cons, cons.FirstParameter(),
1436 cons.LastParameter(), Precision::PConfusion());
1438 Standard_Real wPrev;
1439 Standard_Real wCur = wFirst;
1440 Standard_Real wCurFound = wFirst;
1441 for (i = 2; i < Indices.Length(); i++)
1444 P3d = Nodes(Indices(i));
1445 if (!Loc.IsIdentity())
1446 P3d.Transform(Loc.Transformation());
1448 myLocation3d.Bind(myNbLocat, P3d);
1449 NewNodInStruct(i) = myNbLocat;
1452 wCur = wFirst + wKoef*(Param->Value(i) - wFold);
1453 wCurFound += (wCur - wPrev);
1454 pcos.Perform(P3d, wCurFound);
1455 if (pcos.IsDone()) wCurFound = pcos.Point().Parameter();
1456 theC2d->D0(wCurFound, uv);
1457 v.Initialize(uv.Coord(), myNbLocat, BRepMesh_Frontier);
1458 iv2 = myStructure->AddNode(v);
1459 isv = myVemap.FindIndex(iv2);
1460 if (isv == 0) isv = myVemap.Add(iv2);
1465 if (orEdge == TopAbs_FORWARD)
1466 myStructure->AddLink(BRepMesh_Edge(iv1,iv2,BRepMesh_Frontier));
1467 else if (orEdge == TopAbs_REVERSED)
1468 myStructure->AddLink(BRepMesh_Edge(iv2,iv1,BRepMesh_Frontier));
1469 else if (orEdge == TopAbs_INTERNAL)
1470 myStructure->AddLink(BRepMesh_Edge(iv1,iv2,BRepMesh_Fixed));
1476 if (orEdge == TopAbs_FORWARD)
1477 myStructure->AddLink(BRepMesh_Edge(iv1,ivl,BRepMesh_Frontier));
1478 else if (orEdge == TopAbs_REVERSED)
1479 myStructure->AddLink(BRepMesh_Edge(ivl,iv1,BRepMesh_Frontier));
1480 else if (orEdge == TopAbs_INTERNAL)
1481 myStructure->AddLink(BRepMesh_Edge(iv1,ivl,BRepMesh_Fixed));
1485 Handle(Poly_PolygonOnTriangulation) P1 =
1486 new Poly_PolygonOnTriangulation(NewNodes, Param->Array1());
1487 P1->Deflection(theDefEdge);
1488 if (myInternaledges.IsBound(theEdge))
1490 BRepMesh_PairOfPolygon& pair = myInternaledges.ChangeFind(theEdge);
1491 if (theEdge.Orientation() == TopAbs_REVERSED)
1498 BRepMesh_PairOfPolygon pair1;
1500 myInternaledges.Bind(theEdge, pair1);
1503 Handle(Poly_PolygonOnTriangulation) P2 =
1504 new Poly_PolygonOnTriangulation(NewNodInStruct, Param->Array1());
1505 P2->Deflection(theDefEdge);
1506 BRepMesh_PairOfPolygon pair;
1508 myEdges.Bind(theEdge, pair);
1510 found = Standard_True;
1515 B.UpdateEdge(theEdge,NullPoly,T,Loc);
1516 B.UpdateFace(theFace,TNull);
1519 else if (!T.IsNull() && !T->HasUVNodes())
1522 B.UpdateEdge(theEdge,NullPoly,T,Loc);
1523 B.UpdateFace(theFace,TNull);
1526 while (!Poly.IsNull());
1531 //=======================================================================
1534 //=======================================================================
1535 Standard_Integer BRepMesh_FastDiscret::NbTriangles() const
1537 return myStructure->NbElements();
1540 //=======================================================================
1541 //function : Triangle
1543 //=======================================================================
1545 const BRepMesh_Triangle& BRepMesh_FastDiscret::Triangle
1546 (const Standard_Integer Index) const
1548 return myStructure->GetElement(Index);
1551 //=======================================================================
1552 //function : NbEdges
1554 //=======================================================================
1556 Standard_Integer BRepMesh_FastDiscret::NbEdges() const
1558 return myStructure->NbLinks();
1561 //=======================================================================
1564 //=======================================================================
1566 const BRepMesh_Edge& BRepMesh_FastDiscret::Edge(const Standard_Integer Index) const
1568 return myStructure->GetLink(Index);
1571 //=======================================================================
1572 //function : NbVertices
1574 //=======================================================================
1576 Standard_Integer BRepMesh_FastDiscret::NbVertices() const
1578 return myStructure->NbNodes();
1581 //=======================================================================
1584 //=======================================================================
1586 const BRepMesh_Vertex& BRepMesh_FastDiscret::Vertex
1587 (const Standard_Integer Index) const
1589 return myStructure->GetNode(Index);
1592 //=======================================================================
1595 //=======================================================================
1597 const gp_Pnt& BRepMesh_FastDiscret::Pnt(const Standard_Integer Index) const
1599 return myLocation3d(myStructure->GetNode(Index).Location3d());
1602 //=======================================================================
1603 //function : VerticesOfDomain
1605 //=======================================================================
1607 void BRepMesh_FastDiscret::VerticesOfDomain(BRepMesh_MapOfInteger& Indices) const
1611 // recuperate from the map of edges.
1612 const BRepMesh_MapOfInteger& edmap = myStructure->LinkOfDomain();
1614 // iterator on edges.
1615 BRepMesh_MapOfInteger::Iterator iter(edmap);
1617 Standard_Integer ind_edge;
1618 for (iter.Reset(); iter.More(); iter.Next()) {
1619 ind_edge = iter.Key();
1620 const BRepMesh_Edge& Ed = Edge(ind_edge);
1621 Indices.Add(Ed.FirstNode());
1622 Indices.Add(Ed.LastNode());
1626 BRepMesh_Status BRepMesh_FastDiscret::CurrentFaceStatus() const
1631 //=======================================================================
1632 //function : GetFaceAttribute
1634 //=======================================================================
1636 Standard_Boolean BRepMesh_FastDiscret::GetFaceAttribute(const TopoDS_Face& theFace,
1637 Handle(BRepMesh_FaceAttribute)& theFattrib) const
1639 if(myMapattrib.IsBound(theFace))
1641 theFattrib = myMapattrib(theFace);
1642 return Standard_True;
1644 return Standard_False;
1647 //=======================================================================
1648 //function : RemoveFaceAttribute
1650 //=======================================================================
1652 void BRepMesh_FastDiscret::RemoveFaceAttribute(const TopoDS_Face& theFace)
1654 if(myMapattrib.IsBound(theFace))
1655 myMapattrib.UnBind(theFace);