1 // Created on: 1996-02-27
2 // Created by: Ekaterina SMIRNOVA
3 // Copyright (c) 1996-1999 Matra Datavision
4 // Copyright (c) 1999-2014 OPEN CASCADE SAS
6 // This file is part of Open CASCADE Technology software library.
8 // This library is free software; you can redistribute it and/or modify it under
9 // the terms of the GNU Lesser General Public License version 2.1 as published
10 // by the Free Software Foundation, with special exception defined in the file
11 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
12 // distribution for complete text of the license and disclaimer of any warranty.
14 // Alternatively, this file may be used under the terms of Open CASCADE
15 // commercial license or contractual agreement.
17 #include <BRepMesh_FastDiscret.hxx>
19 #include <BRepMesh_WireChecker.hxx>
20 #include <BRepMesh_FastDiscretFace.hxx>
21 #include <BRepMesh_FaceAttribute.hxx>
22 #include <BRepMesh_DataStructureOfDelaun.hxx>
23 #include <BRepMesh_GeomTool.hxx>
24 #include <BRepMesh_PairOfPolygon.hxx>
25 #include <BRepMesh_Classifier.hxx>
26 #include <BRepMesh_ShapeTool.hxx>
28 #include <BRepAdaptor_Curve.hxx>
29 #include <BRepAdaptor_Surface.hxx>
30 #include <BRepAdaptor_HSurface.hxx>
32 #include <Bnd_Box.hxx>
33 #include <BRepTools.hxx>
34 #include <BRepBndLib.hxx>
35 #include <BndLib_Add3dCurve.hxx>
36 #include <BRep_Tool.hxx>
37 #include <Poly_Triangulation.hxx>
38 #include <Poly_PolygonOnTriangulation.hxx>
40 #include <Precision.hxx>
41 #include <Geom2d_Curve.hxx>
42 #include <Geom_Surface.hxx>
43 #include <Geom_Plane.hxx>
44 #include <GeomAbs_SurfaceType.hxx>
45 #include <Extrema_LocateExtPC.hxx>
47 #include <TColStd_Array1OfInteger.hxx>
48 #include <TColStd_HArray1OfReal.hxx>
49 #include <TColgp_Array1OfPnt.hxx>
50 #include <TColgp_Array1OfPnt2d.hxx>
51 #include <TColGeom2d_SequenceOfCurve.hxx>
52 #include <SortTools_ShellSortOfReal.hxx>
53 #include <TCollection_CompareOfReal.hxx>
55 #include <TopTools_SequenceOfShape.hxx>
56 #include <TopTools_ListIteratorOfListOfShape.hxx>
57 #include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
61 #include <TopoDS_Vertex.hxx>
63 #include <TopExp_Explorer.hxx>
65 #include <Standard_ErrorHandler.hxx>
66 #include <Standard_Failure.hxx>
67 #include <NCollection_IncAllocator.hxx>
69 #include <BRep_ListIteratorOfListOfPointRepresentation.hxx>
70 #include <BRep_PointRepresentation.hxx>
75 // paralleling using Intel TBB
76 #include <tbb/parallel_for_each.h>
79 #define UVDEFLECTION 1.e-05
81 IMPLEMENT_STANDARD_HANDLE (BRepMesh_FastDiscret, Standard_Transient)
82 IMPLEMENT_STANDARD_RTTIEXT(BRepMesh_FastDiscret, Standard_Transient)
84 //=======================================================================
85 //function : BRepMesh_FastDiscret
87 //=======================================================================
88 BRepMesh_FastDiscret::BRepMesh_FastDiscret(const Standard_Real theDefle,
89 const Standard_Real theAngl,
90 const Bnd_Box& theBox,
91 const Standard_Boolean theWithShare,
92 const Standard_Boolean theInshape,
93 const Standard_Boolean theRelative,
94 const Standard_Boolean theShapetrigu,
95 const Standard_Boolean isInParallel)
97 myDeflection (theDefle),
98 myWithShare (theWithShare),
99 myInParallel (isInParallel),
101 myRelative (theRelative),
102 myShapetrigu (theShapetrigu),
103 myInshape (theInshape)
105 myAllocator = new NCollection_IncAllocator(64000);
107 BRepMesh_ShapeTool::BoxMaxDimension(theBox, myDtotale);
110 //=======================================================================
111 //function : BRepMesh_FastDiscret
113 //=======================================================================
115 BRepMesh_FastDiscret::BRepMesh_FastDiscret(const TopoDS_Shape& theShape,
116 const Standard_Real theDefle,
117 const Standard_Real theAngl,
118 const Bnd_Box& theBox,
119 const Standard_Boolean theWithShare,
120 const Standard_Boolean theInshape,
121 const Standard_Boolean theRelative,
122 const Standard_Boolean theShapetrigu,
123 const Standard_Boolean isInParallel)
125 myDeflection (theDefle),
126 myWithShare (theWithShare),
127 myInParallel (isInParallel),
129 myRelative (theRelative),
130 myShapetrigu (theShapetrigu),
131 myInshape (theInshape)
133 myAllocator = new NCollection_IncAllocator(64000);
135 BRepMesh_ShapeTool::BoxMaxDimension(theBox, myDtotale);
139 //=======================================================================
140 //function : SetParallel
142 //=======================================================================
143 void BRepMesh_FastDiscret::SetParallel (const Standard_Boolean theInParallel)
145 myInParallel = theInParallel;
148 //=======================================================================
149 //function : IsParallel
151 //=======================================================================
152 Standard_Boolean BRepMesh_FastDiscret::IsParallel() const
157 //=======================================================================
158 //function : Perform(shape)
160 //=======================================================================
162 void BRepMesh_FastDiscret::Perform(const TopoDS_Shape& theShape)
164 TopTools_IndexedDataMapOfShapeListOfShape anAncestors;
165 TopExp::MapShapesAndAncestors(theShape, TopAbs_EDGE, TopAbs_FACE, anAncestors);
166 std::vector<TopoDS_Face> aFaces;
167 for (TopExp_Explorer ex(theShape, TopAbs_FACE); ex.More(); ex.Next()) {
168 TopoDS_Face aF = TopoDS::Face(ex.Current());
169 Add(aF, anAncestors);
170 aFaces.push_back(aF);
176 CreateMutexesForSubShapes(theShape, TopAbs_EDGE);
177 // mesh faces in parallel threads using TBB
178 tbb::parallel_for_each (aFaces.begin(), aFaces.end(), *this);
184 for (std::vector<TopoDS_Face>::iterator it(aFaces.begin()); it != aFaces.end(); it++)
192 //=======================================================================
195 //=======================================================================
197 void BRepMesh_FastDiscret::Process(const TopoDS_Face& theFace) const
199 //cout << "START face " << theFace.TShape().operator->() << endl << flush;
200 Handle(BRepMesh_FaceAttribute) fattribute;
201 if ( GetFaceAttribute (theFace, fattribute) )
203 BRepMesh_FastDiscretFace aTool (GetAngle(), WithShare());
204 aTool.Add (theFace, fattribute, GetMapOfDefEdge(), myMutexProvider);
206 //cout << "END face " << theFace.TShape().operator->() << endl << flush;
209 //=======================================================================
210 //function : Add(face)
212 //=======================================================================
214 #define MESH_FAILURE(theface) \
216 myFacestate = BRepMesh_Failure; \
217 myNottriangulated.Append(theface); \
221 void BRepMesh_FastDiscret::Add(const TopoDS_Face& theface,
222 const TopTools_IndexedDataMapOfShapeListOfShape& theAncestors)
229 TopoDS_Face face = theface;
230 BRepTools::Update(face);
231 face.Orientation(TopAbs_FORWARD);
232 myStructure.Nullify();
233 Handle(NCollection_IncAllocator) anAlloc = Handle(NCollection_IncAllocator)::DownCast(myAllocator);
234 anAlloc->Reset(Standard_False);
235 myStructure=new BRepMesh_DataStructureOfDelaun(anAlloc);
237 Standard_Real aUmin, aVmin, aUmax, aVmax;
238 BRepTools::UVBounds (theface, aUmin, aUmax, aVmin, aVmax);
239 Standard_Real aTolU = Max( Precision::PConfusion(), (aUmax - aUmin) * UVDEFLECTION );
240 Standard_Real aTolV = Max( Precision::PConfusion(), (aVmax - aVmin) * UVDEFLECTION );
241 myStructure->Data().SetCellSize ( 14 * aTolU, 14 * aTolV );
242 myStructure->Data().SetTolerance( aTolU, aTolV );
244 BRepAdaptor_Surface BS(face, Standard_False);
245 Handle(BRepAdaptor_HSurface) gFace = new BRepAdaptor_HSurface(BS);
247 GeomAbs_SurfaceType thetype;
248 thetype = BS.GetType();
250 gp_Pnt2d uvFirst, uvLast;
252 Handle(Poly_Triangulation) T;
261 myLocation2d.Clear();
262 myInternaledges.Clear();
267 Standard_Real defedge, defface;
268 Standard_Integer nbEdge = 0;
269 Standard_Real savangle = myAngle;
271 Standard_Real maxdef = 2.* BRepMesh_ShapeTool::MaxFaceTolerance(theface);
274 if (!myRelative) defface = Max(myDeflection, maxdef);
276 BRepMeshCol::SequenceOfReal aFSeq, aLSeq;
277 TColGeom2d_SequenceOfCurve aCSeq;
278 TopTools_SequenceOfShape aShSeq;
280 TopoDS_Iterator exW(face);
282 for (; exW.More(); exW.Next()) {
283 const TopoDS_Shape& aWire = exW.Value();
284 if (aWire.ShapeType() != TopAbs_WIRE)
286 TopoDS_Iterator ex(aWire);
287 for(; ex.More(); ex.Next()) {
288 const TopoDS_Edge& edge = TopoDS::Edge(ex.Value());
290 if (!myMapdefle.IsBound(edge)) {
292 if (myEdges.IsBound(edge)) {
293 const BRepMesh_PairOfPolygon& pair = myEdges.Find(edge);
294 const Handle(Poly_PolygonOnTriangulation)& P = pair.First();
295 defedge = P->Deflection();
298 defedge = BRepMesh_ShapeTool::RelativeEdgeDeflection(edge,
299 myDeflection, myDtotale, cdef);
301 myAngle = savangle * cdef;
303 defface = defface + defedge;
304 defface = Max(maxdef, defface);
306 else defedge = myDeflection;
308 defedge = Max(maxdef, defedge);
309 defedge = Max(UVDEFLECTION , defedge);
310 myMapdefle.Bind(edge, defedge);
313 defedge = myMapdefle(edge);
314 if (myRelative) {defface = defface + defedge; defface = Max(maxdef, defface);}
317 Handle(Geom2d_Curve) C = BRep_Tool::CurveOnSurface(edge, face, f1, l1);
318 if (C.IsNull()) continue;
324 Add(edge, face, gFace, C, theAncestors, defedge, f1, l1);
329 if (nbEdge == 0 || myVemap.Extent() < 3)
331 MESH_FAILURE(theface);
334 if (myRelative ) defface = defface / nbEdge;
335 else defface = myDeflection;
337 if (myWithShare) defface = Max(maxdef, defface);
339 T = BRep_Tool::Triangulation(face, loc);
341 if (!myShapetrigu || T.IsNull()) {
343 Standard_Real xCur, yCur;
344 Standard_Real maxX, minX, maxY, minY;
348 Standard_Integer ipn = 0;
349 Standard_Integer i1 =1;
350 for (i1 = 1; i1 <= myVemap.Extent(); i1++) {
351 const BRepMesh_Vertex& aV = myStructure->GetNode(myVemap.FindKey(i1));
355 minX=Min(xCur, minX);
356 maxX=Max(xCur, maxX);
357 minY=Min(yCur, minY);
358 maxY=Max(yCur, maxY);
360 Standard_Real myumin = minX;
361 Standard_Real myumax = maxX;
362 Standard_Real myvmin = minY;
363 Standard_Real myvmax = maxY;
365 const Standard_Real umin = BS.FirstUParameter();
366 const Standard_Real umax = BS.LastUParameter();
367 const Standard_Real vmin = BS.FirstVParameter();
368 const Standard_Real vmax = BS.LastVParameter();
370 if (myumin < umin || myumax > umax)
372 if (BS.IsUPeriodic())
374 if ((myumax - myumin) > (umax - umin))
376 myumax = myumin + (umax - umin);
381 if (umin > myumin) myumin = umin;
382 if (umax < myumax) myumax = umax;
386 if (myvmin < vmin || myvmax > vmax)
388 if (BS.IsVPeriodic())
390 if ((myvmax - myvmin) > (vmax - vmin))
392 myvmax = myvmin + (vmax - vmin);
397 if (vmin > myvmin) myvmin = vmin;
398 if (vmax < myvmax) myvmax = vmax;
402 // fast verification of the validity of calculated limits. If wrong,
403 // sure a problem of pcurve.
404 if (thetype == GeomAbs_BezierSurface &&
405 (myumin < -0.5 || myumax > 1.5 || myvmin < -0.5 || myvmax > 1.5))
407 MESH_FAILURE(theface);
410 //define parameters for correct parametrics
412 Standard_Real deltaX = 1.0;
413 Standard_Real deltaY = 1.0;
414 Standard_Integer nbVertices = myVemap.Extent();
415 const Standard_Real tolclass = Precision::PConfusion(); //0.03*Max(myumax-myumin, myvmax-myvmin);
417 BRepMeshCol::HClassifier classifier = new BRepMesh_Classifier;
419 BRepMesh_WireChecker aDFaceChecker(face,
420 tolclass, myInternaledges, myVemap, myStructure,
421 myumin, myumax, myvmin, myvmax, myInParallel);
422 aDFaceChecker.ReCompute(classifier);
424 myFacestate = aDFaceChecker.Status();
425 if (myFacestate == BRepMesh_SelfIntersectingWire)
427 Standard_Integer nbmaill = 0;
428 Standard_Real eps = Precision::Confusion();
429 while (nbmaill < 5 && myFacestate != BRepMesh_ReMesh)
433 //clear the structure of links
434 myStructure.Nullify();
435 myStructure = new BRepMesh_DataStructureOfDelaun(anAlloc);
438 myLocation2d.Clear();
439 myInternaledges.Clear();
442 for(j1 = 1; j1 <= aShSeq.Length(); j1++)
444 const TopoDS_Edge& edge = TopoDS::Edge(aShSeq.Value(j1));
445 if (myEdges.IsBound(edge))
447 myEdges.UnBind(edge);
448 myInternaledges.UnBind(edge);
453 for( j1 = 1; j1 <= aShSeq.Length(); j1++)
455 const TopoDS_Edge& edge = TopoDS::Edge(aShSeq.Value(j1));
456 defedge = myMapdefle(edge) / 3.;
457 defedge = Max(defedge, eps);
458 myMapdefle.Bind(edge, defedge);
459 const Handle(Geom2d_Curve)& C = aCSeq.Value(j1);
460 Add(edge, face, gFace, C, theAncestors, defedge, aFSeq.Value(j1), aLSeq.Value(j1));
463 aDFaceChecker.ReCompute(classifier);
464 if (aDFaceChecker.Status() == BRepMesh_NoError)
466 myFacestate = BRepMesh_ReMesh;
468 nbVertices = myVemap.Extent();
473 if (myFacestate != BRepMesh_NoError && myFacestate != BRepMesh_ReMesh)
475 myNottriangulated.Append(face);
476 classifier.Nullify();
480 // try to find the real length:
481 // akm (bug OCC16) : We must calculate these measures in non-singular
482 // parts of face. Let's try to compute average value of three
483 // (umin, (umin+umax)/2, umax), and respectively for v.
485 Standard_Real longu = 0.0, longv = 0.0; //, last , first;
486 gp_Pnt P11, P12, P21, P22, P31, P32;
488 Standard_Real du = (myumax-myumin)/20;
489 Standard_Real dv = (myvmax-myvmin)/20;
490 Standard_Real dfuave=(myumin+myumax)/2, dfucur;
491 Standard_Real dfvave=(myvmin+myvmax)/2, dfvcur;
493 BS.D0 (myumin, myvmin, P11);
494 BS.D0 (myumin, dfvave, P21);
495 BS.D0 (myumin, myvmax, P31);
496 for (i1=1, dfucur=myumin+du; i1 <= 20; i1++, dfucur+=du) {
497 BS.D0 (dfucur, myvmin, P12);
498 BS.D0 (dfucur, dfvave, P22);
499 BS.D0 (dfucur, myvmax, P32);
500 longu += ( P11.Distance(P12) + P21.Distance(P22) + P31.Distance(P32) );
506 BS.D0(myumin, myvmin, P11);
507 BS.D0(dfuave, myvmin, P21);
508 BS.D0(myumax, myvmin, P31);
509 for (i1=1, dfvcur=myvmin+dv; i1 <= 20; i1++, dfvcur+=dv) {
510 BS.D0 (myumin, dfvcur, P12);
511 BS.D0 (dfuave, dfvcur, P22);
512 BS.D0 (myumax, dfvcur, P32);
513 longv += ( P11.Distance(P12) + P21.Distance(P22) + P31.Distance(P32) );
520 // akm (bug OCC16) ^^^^^
522 if (longu <= 1.e-16 || longv <= 1.e-16) {
524 #ifdef DEB_MESH_CHRONO
526 MESH_CHRONO_TSTOP(thetype);
528 MESH_FAILURE(theface);
532 if (thetype == GeomAbs_Torus) {
533 gp_Torus Tor = BS.Torus();
534 Standard_Real r = Tor.MinorRadius(), R = Tor.MajorRadius();
535 Standard_Real Du, Dv;//, pasu, pasv;
537 Dv = Max(1.0e0 - (defface/r),0.0e0) ;
538 Standard_Real oldDv = 2.0 * ACos (Dv);
539 oldDv = Min(oldDv, myAngle);
540 Dv = 0.9*oldDv; //TWOTHIRD * oldDv;
543 Standard_Integer nbV = Max((Standard_Integer)((myvmax-myvmin)/Dv), 2);
544 Dv = (myvmax-myvmin)/(nbV+1);
546 Standard_Real ru = R + r;
548 Du = Max(1.0e0 - (defface/ru),0.0e0);
549 Du = (2.0 * ACos (Du));
550 Du = Min(Du, myAngle);
551 Standard_Real aa = sqrt(Du*Du + oldDv*oldDv);
552 if(aa < gp::Resolution())
555 Du = Du * Min(oldDv, Du) / aa;
559 Standard_Integer nbU = Max((Standard_Integer)((myumax-myumin)/Du), 2);
560 nbU = Max(nbU, (Standard_Integer)(nbV*(myumax-myumin)*R/((myvmax-myvmin)*r)/5.));
562 Du = (myumax-myumin)/(nbU+1);
563 //-- DeltaX and DeltaY are chosen so that to avoid "jumping"
564 //-- of points on the grid
568 else if (thetype == GeomAbs_Cylinder) {
569 /*Standard_Real aMax = Max(myumax,myvmax);
570 deltaX = 0.01; //1./aMax; //0.01;
572 gp_Cylinder Cyl = BS.Cylinder();
573 Standard_Real R = Cyl.Radius();
574 // Calculate parameters for iteration in U direction
575 Standard_Real Du = 1.0 - (defface/R);
576 if (Du < 0.0) Du = 0.0;
577 Du = 2.0 * ACos (Du);
578 if (Du > GetAngle()) Du = GetAngle();
583 deltaX = (myumax-myumin)/longu;
584 deltaY = (myvmax-myvmin)/longv;
587 if(!myMapattrib.IsBound(theface))
589 Handle(BRepMesh_FaceAttribute) aFA = new BRepMesh_FaceAttribute();
590 aFA->GetDefFace() = defface;
591 aFA->GetUMax() = myumax;
592 aFA->GetVMax() = myvmax;
593 aFA->GetUMin() = myumin;
594 aFA->GetVMin() = myvmin;
595 aFA->GetDeltaX() = deltaX;
596 aFA->GetDeltaY() = deltaY;
597 aFA->GetMinX() = minX;
598 aFA->GetMinY() = minY;
599 aFA->GetClassifier() = classifier;
600 myMapattrib.Bind(theface, aFA);
603 //Standard_Integer nbVertices = myVemap.Extent();
604 T = new Poly_Triangulation(nbVertices, 1, Standard_True);
605 TColgp_Array1OfPnt& Nodes = T->ChangeNodes();
606 TColgp_Array1OfPnt2d& Nodes2d = T->ChangeUVNodes();
608 Standard_Integer index;
609 for (i = 1; i <= nbVertices; i++) {
610 index = myVemap.FindKey(i);
611 Nodes(i) = Pnt(index);
612 Nodes2d(i).SetXY(Vertex(index).Coord());
614 BRepMesh_ShapeTool::AddInFace(face, T);
616 BRepMeshCol::DMapOfShapePairOfPolygon::Iterator It(myInternaledges);
617 for (; It.More(); It.Next())
619 const TopoDS_Edge& aEdge = TopoDS::Edge(It.Key());
620 const BRepMesh_PairOfPolygon& pair = It.Value();
621 const Handle(Poly_PolygonOnTriangulation)& NOD1 = pair.First();
622 const Handle(Poly_PolygonOnTriangulation)& NOD2 = pair.Last();
624 BRepMesh_ShapeTool::UpdateEdge(aEdge, NOD1, T, loc);
626 BRepMesh_ShapeTool::UpdateEdge(aEdge, NOD1, NOD2, T, loc);
632 catch(Standard_Failure)
634 MESH_FAILURE(theface);
637 myStructure.Nullify();
640 //=======================================================================
641 //function : splitSegment
643 //=======================================================================
644 static void splitSegment( BRepMesh_GeomTool& theGT,
645 const Handle(Geom_Surface)& theSurf,
646 const Handle(Geom2d_Curve)& theCurve2d,
647 const BRepAdaptor_Curve& theBAC,
648 const Standard_Real theSquareEDef,
649 const Standard_Real theFirst,
650 const Standard_Real theLast,
651 const Standard_Integer theNbIter)
653 //limit ineration depth
656 gp_Pnt2d uvf, uvl, uvm;
657 gp_Pnt P3dF, P3dL, midP3d, midP3dFromSurf;
658 Standard_Real midpar;
660 if(Abs(theLast - theFirst) < 2*Precision::PConfusion())
663 theCurve2d->D0(theFirst, uvf);
664 theCurve2d->D0(theLast, uvl);
666 P3dF = theSurf->Value(uvf.X(), uvf.Y());
667 P3dL = theSurf->Value(uvl.X(), uvl.Y());
669 if(P3dF.SquareDistance(P3dL) < theSquareEDef)
672 uvm = gp_Pnt2d((uvf.XY() + uvl.XY())*0.5);
673 midP3dFromSurf = theSurf->Value(uvm.X(), uvm.Y());
675 gp_XYZ aVec = P3dL.XYZ()-P3dF.XYZ();
678 gp_XYZ Vec1 = midP3dFromSurf.XYZ() - P3dF.XYZ();
679 Standard_Real aModulus = Vec1.Dot(aVec);
680 gp_XYZ aProj = aVec*aModulus;
681 gp_XYZ aDist = Vec1 - aProj;
683 if(aDist.SquareModulus() < theSquareEDef)
686 midpar = (theFirst + theLast) * 0.5;
687 theBAC.D0(midpar, midP3d);
688 theGT.AddPoint(midP3d, midpar, Standard_False);
690 splitSegment(theGT, theSurf, theCurve2d, theBAC, theSquareEDef, theFirst, midpar, theNbIter+1);
691 splitSegment(theGT, theSurf, theCurve2d, theBAC, theSquareEDef, midpar, theLast, theNbIter+1);
694 //=======================================================================
697 //=======================================================================
698 void BRepMesh_FastDiscret::Add( const TopoDS_Edge& theEdge,
699 const TopoDS_Face& theFace,
700 const Handle(BRepAdaptor_HSurface)& theGFace,
701 const Handle(Geom2d_Curve)& theC2d,
702 const TopTools_IndexedDataMapOfShapeListOfShape& theAncestors,
703 const Standard_Real theDefEdge,
704 const Standard_Real theFirst,
705 const Standard_Real theLast)
707 const TopAbs_Orientation orEdge = theEdge.Orientation();
708 if (orEdge == TopAbs_EXTERNAL) return;
710 const Standard_Boolean isEdgeBound = myEdges.IsBound(theEdge);
714 if (Update(theEdge, theFace, theC2d, theDefEdge, theFirst, theLast))
720 TopoDS_Vertex pBegin, pEnd;
721 TopExp::Vertices(theEdge, pBegin, pEnd);
722 if (pBegin.IsNull() || pEnd.IsNull())
727 Standard_Real wFirst, wLast;
728 BRep_Tool::Range(theEdge, theFace, wFirst, wLast);
730 gp_Pnt2d uvFirst, uvLast;
731 BRep_Tool::UVPoints(theEdge, theFace, uvFirst, uvLast);
733 const Standard_Boolean sameUV = uvFirst.IsEqual(uvLast, Precision::PConfusion());
735 //Control vertexes tolerances
736 gp_Pnt pFirst = theGFace->Value(uvFirst.X(), uvFirst.Y());
737 gp_Pnt pLast = theGFace->Value(uvLast.X(), uvLast.Y());
739 Standard_Real mindist = 10. * Max(pFirst.Distance(BRep_Tool::Pnt(pBegin)),
740 pLast.Distance(BRep_Tool::Pnt(pEnd)));
742 if(mindist < BRep_Tool::Tolerance(pBegin) ||
743 mindist < BRep_Tool::Tolerance(pEnd) ) mindist = theDefEdge;
745 // control of degenerated non-coded edges.
747 Standard_Boolean degener = BRep_Tool::Degenerated(theEdge);
751 if (pBegin.IsSame(pEnd))
753 // calculation of the length of the edge in 3D
754 Standard_Real longueur = 0.0;
755 Standard_Real du = (wLast-wFirst)/20;
757 BRepAdaptor_Curve BC(theEdge);
759 Standard_Real tolV = BRep_Tool::Tolerance(pBegin);
760 Standard_Real tolV2 = 1.2*tolV;
761 for (Standard_Integer l = 1; l <= 20; l++) {
762 BC.D0(wFirst + l*du, P2);
763 longueur += P1.Distance(P2);
764 if (longueur > tolV2) break;
768 if (longueur < tolV2)
770 degener = Standard_True;
778 // 1. is it really sameUV without being degenerated
780 theC2d->D0(theFirst, uvF);
781 theC2d->D0(theLast, uvL);
782 if (!uvFirst.IsEqual(uvF, Precision::PConfusion()))
786 if (!uvLast.IsEqual(uvL, Precision::PConfusion()))
794 // Process first vertex
795 Standard_Integer ipf;
796 if (myVertices.IsBound(pBegin))
798 ipf = myVertices.Find(pBegin);
802 if (sameUV && myVertices.IsBound(pEnd))
804 ipf = myVertices.Find(pEnd);
810 myLocation3d.Bind(ipf, BRep_Tool::Pnt(pBegin));
812 myVertices.Bind(pBegin, ipf);
815 Handle(BRepMesh_FaceAttribute) aFaceAttribute;
816 GetFaceAttribute ( theFace, aFaceAttribute );
817 theUV = BRepMesh_ShapeTool::FindUV(ipf, uvFirst,
818 pBegin, mindist, aFaceAttribute, theGFace, myLocation2d);
820 BRepMesh_Vertex vf(theUV, ipf, BRepMesh_Frontier);
821 Standard_Integer ivf = myStructure->AddNode(vf);
823 // Process last vertex
824 Standard_Integer ipl;
825 if (pEnd.IsSame(pBegin))
831 if (myVertices.IsBound(pEnd))
833 ipl = myVertices.Find(pEnd);
845 myLocation3d.Bind(ipl, BRep_Tool::Pnt(pEnd));
847 myVertices.Bind(pEnd,ipl);
851 theUV = BRepMesh_ShapeTool::FindUV(ipl, uvLast,
852 pEnd, mindist, aFaceAttribute, theGFace, myLocation2d);
854 BRepMesh_Vertex vl(theUV, ipl, BRepMesh_Frontier);
855 Standard_Integer ivl= myStructure->AddNode(vl);
857 Standard_Integer isvf = myVemap.FindIndex(ivf);
858 if (isvf == 0) isvf = myVemap.Add(ivf);
859 Standard_Integer isvl = myVemap.FindIndex(ivl);
860 if (isvl == 0) isvl = myVemap.Add(ivl);
862 Standard_Real otherdefedge = 0.5*theDefEdge;
867 Handle(Poly_PolygonOnTriangulation) P1;
871 Handle(Poly_PolygonOnTriangulation) P2;
876 TColStd_Array1OfInteger Nodes(1, 2), NodInStruct(1, 2);
877 TColStd_Array1OfReal Param(1, 2);
879 NodInStruct(1) = ipf;
883 NodInStruct(2) = ipl;
887 P1 = new Poly_PolygonOnTriangulation(Nodes, Param);
888 P2 = new Poly_PolygonOnTriangulation(NodInStruct, Param);
892 if (orEdge == TopAbs_INTERNAL) otherdefedge *= 0.5;
894 BRepAdaptor_Curve cons;
895 Standard_Boolean isSameParam = BRep_Tool::SameParameter(theEdge);
898 cons.Initialize(theEdge);
902 cons.Initialize(theEdge, theFace);
906 Standard_Integer nbpmin = 2;
907 const GeomAbs_CurveType aCurveType = cons.GetType();
908 if ( aCurveType == GeomAbs_Circle )
911 BRepMesh_GeomTool GT(cons, wFirst, wLast, otherdefedge, 0.5 * myAngle, nbpmin);
913 if ( aCurveType == GeomAbs_BSplineCurve )
915 const Standard_Integer aNbInt = cons.NbIntervals( GeomAbs_C1 );
918 TColStd_Array1OfReal anIntervals( 1, aNbInt + 1 );
919 cons.Intervals( anIntervals, GeomAbs_C1 );
920 for ( Standard_Integer aIntIt = 1; aIntIt <= aNbInt; ++aIntIt )
922 const Standard_Real& aStartInt = anIntervals.Value( aIntIt );
923 const Standard_Real& anEndInt = anIntervals.Value( aIntIt + 1 );
925 BRepMesh_GeomTool aDetalizator( cons, aStartInt, anEndInt,
926 otherdefedge, 0.5 * myAngle, nbpmin );
928 Standard_Integer aNbAddNodes = aDetalizator.NbPoints();
929 for ( Standard_Integer aNodeIt = 1; aNodeIt <= aNbAddNodes; ++aNodeIt )
931 Standard_Real aParam;
934 aDetalizator.Value( aNodeIt, theGFace, aParam, aPoint3d, aPoint2d );
935 GT.AddPoint( aPoint3d, aParam, Standard_False );
941 // PTv, chl/922/G9, Take into account internal vertices
942 // it is necessary for internal edges, which do not split other edges, by their vertex
943 TopoDS_Iterator exV(theEdge);
944 for ( ; exV.More(); exV.Next() )
946 TopoDS_Vertex aIntV = TopoDS::Vertex(exV.Value());
947 if ( aIntV.Orientation() == TopAbs_INTERNAL )
948 GT.AddPoint(BRep_Tool::Pnt(aIntV),
949 BRep_Tool::Parameter(aIntV, theEdge),
954 Standard_Integer nbnodes = GT.NbPoints();
955 //Check deflection in 2d space for improvement of edge tesselation.
956 if( isSameParam && nbnodes > 1)
958 Standard_Real aSquareEdgeDef = otherdefedge * otherdefedge;
959 const TopTools_ListOfShape& lf = theAncestors.FindFromKey(theEdge);
960 TopTools_ListIteratorOfListOfShape itl(lf);
961 for (; itl.More(); itl.Next()) {
962 const TopoDS_Face& aFace = TopoDS::Face (itl.Value());
964 TopLoc_Location aLoc;
965 Standard_Real aF, aL;
966 Handle(Geom_Surface) aSurf = BRep_Tool::Surface(aFace, aLoc);
967 const Handle(Standard_Type)& aType = aSurf->DynamicType();
968 if(aType == STANDARD_TYPE(Geom_Plane))
970 Handle(Geom2d_Curve) aCurve2d = BRep_Tool::CurveOnSurface(theEdge, aFace, aF, aL);
971 if(Abs(aF-wFirst)>Precision::PConfusion()||Abs(aL-wLast)>Precision::PConfusion())
976 nbnodes = GT.NbPoints();
977 TColStd_Array1OfReal aParamArray(1, nbnodes);
978 for (i = 1; i <= nbnodes; i++)
980 GT.Value(i, theGFace, parf, P3d, uvf);
981 aParamArray.SetValue(i, parf);
983 for (i = 1; i < nbnodes; i++)
985 splitSegment(GT, aSurf, aCurve2d, cons, aSquareEdgeDef, aParamArray(i), aParamArray(i+1), 1);
990 // Creation of polygons on triangulation:
992 nbnodes = GT.NbPoints();
994 TColStd_Array1OfInteger Nodes(1, nbnodes);
995 TColStd_Array1OfInteger NodInStruct(1, nbnodes);
996 TColStd_Array1OfReal Param(1, nbnodes);
998 // processing of the 1st point:
1000 NodInStruct(1) = ipf;
1004 Nodes(nbnodes) = isvl;
1005 NodInStruct(nbnodes) = ipl;
1006 Param(nbnodes) = wLast;
1010 Standard_Integer iv2;
1011 for (i = 2; i < GT.NbPoints(); i++)
1014 GT.Value(i, theGFace, puv, P3d, uv);
1016 myLocation3d.Bind(myNbLocat, P3d);
1017 NodInStruct(i) = myNbLocat;
1019 v2.Initialize(uv.Coord(), myNbLocat, BRepMesh_OnCurve);
1020 iv2=myStructure->AddNode(v2);
1022 Standard_Integer isv = myVemap.FindIndex(iv2);
1023 if (isv == 0) isv = myVemap.Add(iv2);
1025 NodInStruct(i) = myNbLocat;
1028 if (orEdge == TopAbs_FORWARD)
1029 myStructure->AddLink(BRepMesh_Edge(ivf, iv2, BRepMesh_Frontier));
1030 else if (orEdge == TopAbs_REVERSED)
1031 myStructure->AddLink(BRepMesh_Edge(iv2, ivf, BRepMesh_Frontier));
1032 else if (orEdge == TopAbs_INTERNAL)
1033 myStructure->AddLink(BRepMesh_Edge(ivf, iv2, BRepMesh_Fixed));
1038 P1 = new Poly_PolygonOnTriangulation(Nodes, Param);
1039 P2 = new Poly_PolygonOnTriangulation(NodInStruct, Param);
1042 P2->Deflection(otherdefedge);
1043 BRepMesh_PairOfPolygon pair;
1045 myEdges.Bind(theEdge, pair);
1048 if (orEdge == TopAbs_FORWARD)
1049 myStructure->AddLink(BRepMesh_Edge(ivf, ivl, BRepMesh_Frontier));
1050 else if (orEdge == TopAbs_REVERSED)
1051 myStructure->AddLink(BRepMesh_Edge(ivl, ivf, BRepMesh_Frontier));
1052 else if (orEdge == TopAbs_INTERNAL)
1053 myStructure->AddLink(BRepMesh_Edge(ivf, ivl, BRepMesh_Fixed));
1058 // If this Edge has been already checked and it is not degenerated,
1059 // the points of the polygon calculated at the first check are retrieved :
1064 // Create 2d polygon for degenerated edge
1065 TColStd_Array1OfInteger Nodes(1, 2);
1066 TColStd_Array1OfReal PPar(1, 2);
1074 P1 = new Poly_PolygonOnTriangulation(Nodes, PPar);
1078 // retrieve the polygone:
1079 const BRepMesh_PairOfPolygon& pair = myEdges.Find(theEdge);
1080 const Handle(Poly_PolygonOnTriangulation)& P = pair.First();
1081 const TColStd_Array1OfInteger& NOD = P->Nodes();
1082 Handle(TColStd_HArray1OfReal) Par = P->Parameters();
1085 const Standard_Integer nbnodes = NOD.Length();
1086 TColStd_Array1OfInteger Nodes(1, nbnodes);
1087 TColStd_Array1OfReal PPar(1, nbnodes);
1088 Standard_Integer iv2;
1093 Nodes(nbnodes) = isvl;
1094 PPar(nbnodes) = wLast;
1099 if (BRep_Tool::SameParameter(theEdge))
1101 for (i = 2; i < nbnodes; i++)
1103 const Standard_Real puv = Par->Value(i);
1104 theC2d->D0(puv, uv);
1105 v2.Initialize(uv.Coord(), NOD(i), BRepMesh_OnCurve);
1106 iv2 = myStructure->AddNode(v2);
1108 Standard_Integer isv = myVemap.FindIndex(iv2);
1109 if (isv == 0) isv = myVemap.Add(iv2);
1113 if (orEdge==TopAbs_FORWARD)
1114 myStructure->AddLink(BRepMesh_Edge(ivf, iv2, BRepMesh_Frontier));
1115 else if (orEdge == TopAbs_REVERSED)
1116 myStructure->AddLink(BRepMesh_Edge(iv2, ivf, BRepMesh_Frontier));
1117 else if (orEdge == TopAbs_INTERNAL)
1118 myStructure->AddLink(BRepMesh_Edge(ivf, iv2, BRepMesh_Fixed));
1125 const Standard_Real wFold = Par->Value(Par->Lower());
1126 const Standard_Real wLold = Par->Value(Par->Upper());
1128 Standard_Real wKoef = 1.;
1129 if ((wFold != wFirst || wLold != wLast) && wLold != wFold)
1131 wKoef = (wLast - wFirst) / (wLold - wFold);
1134 BRepAdaptor_Curve cons(theEdge, theFace);
1135 Extrema_LocateExtPC pcos;
1136 pcos.Initialize(cons, cons.FirstParameter(),
1137 cons.LastParameter(), Precision::PConfusion());
1139 Standard_Real wPrev;
1140 Standard_Real wCur = wFirst;
1141 Standard_Real wCurFound = wFirst;
1142 for (i = 2; i < nbnodes; i++)
1144 P3d = myLocation3d(NOD(i));
1147 wCur = wFirst + wKoef*(Par->Value(i) - wFold);
1148 wCurFound += (wCur - wPrev);
1149 pcos.Perform(P3d, wCurFound);
1150 if (pcos.IsDone()) wCurFound = pcos.Point().Parameter();
1151 theC2d->D0(wCurFound, uv);
1152 v2.Initialize(uv.Coord(), NOD(i), BRepMesh_OnCurve);
1153 iv2 = myStructure->AddNode(v2);
1155 Standard_Integer isv = myVemap.FindIndex(iv2);
1156 if (isv == 0) isv = myVemap.Add(iv2);
1158 PPar(i) = wCurFound;
1160 if (orEdge==TopAbs_FORWARD)
1161 myStructure->AddLink(BRepMesh_Edge(ivf, iv2, BRepMesh_Frontier));
1162 else if (orEdge == TopAbs_REVERSED)
1163 myStructure->AddLink(BRepMesh_Edge(iv2, ivf, BRepMesh_Frontier));
1164 else if (orEdge == TopAbs_INTERNAL)
1165 myStructure->AddLink(BRepMesh_Edge(ivf, iv2, BRepMesh_Fixed));
1172 P1 = new Poly_PolygonOnTriangulation(Nodes, PPar);
1175 if (orEdge == TopAbs_FORWARD)
1176 myStructure->AddLink(BRepMesh_Edge(ivf, ivl, BRepMesh_Frontier));
1177 else if (orEdge == TopAbs_REVERSED)
1178 myStructure->AddLink(BRepMesh_Edge(ivl, ivf, BRepMesh_Frontier));
1179 else if (orEdge == TopAbs_INTERNAL)
1180 myStructure->AddLink(BRepMesh_Edge(ivf, ivl, BRepMesh_Fixed));
1185 P1->Deflection(theDefEdge);
1186 if (myInternaledges.IsBound(theEdge))
1188 BRepMesh_PairOfPolygon& pair = myInternaledges.ChangeFind(theEdge);
1189 if (orEdge == TopAbs_REVERSED)
1196 BRepMesh_PairOfPolygon pair1;
1198 myInternaledges.Bind(theEdge, pair1);
1203 //=======================================================================
1204 //function : Update(edge)
1206 //=======================================================================
1207 Standard_Boolean BRepMesh_FastDiscret::Update(const TopoDS_Edge& theEdge,
1208 const TopoDS_Face& theFace,
1209 const Handle(Geom2d_Curve)& theC2d,
1210 const Standard_Real theDefEdge,
1211 const Standard_Real theFirst,
1212 const Standard_Real theLast)
1214 TopLoc_Location Loc;
1215 Handle(Poly_Triangulation) T;
1216 Handle(Poly_PolygonOnTriangulation) Poly, NullPoly;
1218 Standard_Integer i = 1;
1219 Standard_Boolean found = Standard_False;
1222 BRep_Tool::PolygonOnTriangulation(theEdge,Poly,T,Loc,i);
1224 if (!found && !T.IsNull() && T->HasUVNodes() &&
1225 !Poly.IsNull() && Poly->HasParameters())
1227 if (Poly->Deflection() <= 1.1*theDefEdge)
1229 // 2d vertex indices
1230 TopAbs_Orientation orEdge = theEdge.Orientation();
1231 Standard_Integer iv1, iv2, ivl;
1232 Standard_Integer isv1, isv, isvl;
1234 // Get range on 2d curve
1235 Standard_Real wFirst, wLast;
1236 BRep_Tool::Range(theEdge, theFace, wFirst, wLast);
1238 // Get end points on 2d curve
1239 gp_Pnt2d uvFirst, uvLast;
1240 BRep_Tool::UVPoints(theEdge, theFace, uvFirst, uvLast);
1243 TopoDS_Vertex pBegin, pEnd;
1244 TopExp::Vertices(theEdge,pBegin,pEnd);
1246 const Standard_Boolean sameUV =
1247 uvFirst.IsEqual(uvLast, Precision::PConfusion());
1249 //Controle vertice tolerances
1250 BRepAdaptor_Surface BS(theFace, Standard_False);
1251 Handle(BRepAdaptor_HSurface) gFace = new BRepAdaptor_HSurface(BS);
1254 gp_Pnt pFirst = gFace->Value(uvFirst.X(), uvFirst.Y());
1255 gp_Pnt pLast = gFace->Value(uvLast.X(), uvLast.Y());
1257 Standard_Real mindist = 10. * Max(pFirst.Distance(BRep_Tool::Pnt(pBegin)),
1258 pLast.Distance(BRep_Tool::Pnt(pEnd)));
1260 if (mindist < BRep_Tool::Tolerance(pBegin) ||
1261 mindist < BRep_Tool::Tolerance(pEnd) ) mindist = theDefEdge;
1265 // 1. is it really sameUV without being degenerated
1267 theC2d->D0(theFirst, uvF);
1268 theC2d->D0(theLast, uvL);
1269 if (!uvFirst.IsEqual(uvF, Precision::PConfusion())) {
1272 if (!uvLast.IsEqual(uvL, Precision::PConfusion())) {
1277 const TColgp_Array1OfPnt& Nodes = T->Nodes();
1278 const TColStd_Array1OfInteger& Indices = Poly->Nodes();
1279 Handle(TColStd_HArray1OfReal) Param = Poly->Parameters();
1281 const Standard_Integer nbnodes = Indices.Length();
1282 TColStd_Array1OfInteger NewNodes(1, nbnodes);
1283 TColStd_Array1OfInteger NewNodInStruct(1, nbnodes);
1288 // Process first vertex
1289 Standard_Integer ipf;
1290 if (myVertices.IsBound(pBegin))
1292 ipf = myVertices.Find(pBegin);
1296 if (sameUV && myVertices.IsBound(pEnd))
1298 ipf = myVertices.Find(pEnd);
1302 P3d = Nodes(Indices(1));
1303 if (!Loc.IsIdentity())
1304 P3d.Transform(Loc.Transformation());
1306 myLocation3d.Bind(myNbLocat,P3d);
1309 myVertices.Bind(pBegin,ipf);
1311 NewNodInStruct(1) = ipf;
1313 Handle(BRepMesh_FaceAttribute) aFaceAttribute;
1314 GetFaceAttribute ( theFace, aFaceAttribute );
1315 theUV = BRepMesh_ShapeTool::FindUV(ipf, uvFirst,
1316 pBegin, mindist, aFaceAttribute, gFace, myLocation2d);
1318 BRepMesh_Vertex vf(theUV,ipf,BRepMesh_Frontier);
1319 iv1 = myStructure->AddNode(vf);
1320 isv1 = myVemap.FindIndex(iv1);
1321 if (isv1 == 0) isv1 = myVemap.Add(iv1);
1324 // Process last vertex
1325 Standard_Integer ipl;
1326 if (pEnd.IsSame(pBegin))
1332 if (myVertices.IsBound(pEnd))
1334 ipl = myVertices.Find(pEnd);
1346 myLocation3d.Bind(myNbLocat,Nodes(Indices(nbnodes)).Transformed(Loc.Transformation()));
1349 myVertices.Bind(pEnd,ipl);
1352 NewNodInStruct(nbnodes) = ipl;
1353 theUV = BRepMesh_ShapeTool::FindUV(ipl, uvLast,
1354 pEnd, mindist, aFaceAttribute, gFace, myLocation2d);
1356 BRepMesh_Vertex vl(theUV,ipl,BRepMesh_Frontier);
1358 ivl = myStructure->AddNode(vl);
1359 isvl = myVemap.FindIndex(ivl);
1360 if (isvl == 0) isvl = myVemap.Add(ivl);
1362 NewNodes(nbnodes) = isvl;
1367 if (BRep_Tool::SameParameter(theEdge))
1369 for (i = 2; i < Indices.Length(); i++)
1372 P3d = Nodes(Indices(i));
1373 if (!Loc.IsIdentity())
1374 P3d.Transform(Loc.Transformation());
1376 myLocation3d.Bind(myNbLocat, P3d);
1377 NewNodInStruct(i) = myNbLocat;
1379 uv = theC2d->Value(Param->Value(i));
1380 v.Initialize(uv.Coord(), myNbLocat, BRepMesh_Frontier);
1381 iv2 = myStructure->AddNode(v);
1382 isv = myVemap.FindIndex(iv2);
1383 if (isv == 0) isv = myVemap.Add(iv2);
1387 if (orEdge == TopAbs_FORWARD)
1388 myStructure->AddLink(BRepMesh_Edge(iv1,iv2,BRepMesh_Frontier));
1389 else if (orEdge == TopAbs_REVERSED)
1390 myStructure->AddLink(BRepMesh_Edge(iv2,iv1,BRepMesh_Frontier));
1391 else if (orEdge == TopAbs_INTERNAL)
1392 myStructure->AddLink(BRepMesh_Edge(iv1,iv2,BRepMesh_Fixed));
1398 if (orEdge == TopAbs_FORWARD)
1399 myStructure->AddLink(BRepMesh_Edge(iv1,ivl,BRepMesh_Frontier));
1400 else if (orEdge == TopAbs_REVERSED)
1401 myStructure->AddLink(BRepMesh_Edge(ivl,iv1,BRepMesh_Frontier));
1402 else if (orEdge == TopAbs_INTERNAL)
1403 myStructure->AddLink(BRepMesh_Edge(iv1,ivl,BRepMesh_Fixed));
1410 const Standard_Real wFold = Param->Value(Param->Lower());
1411 const Standard_Real wLold = Param->Value(Param->Upper());
1413 Standard_Real wKoef = 1.;
1414 if ((wFold != wFirst || wLold != wLast) && wLold != wFold)
1416 wKoef = (wLast - wFirst) / (wLold - wFold);
1419 BRepAdaptor_Curve cons(theEdge, theFace);
1420 Extrema_LocateExtPC pcos;
1421 pcos.Initialize(cons, cons.FirstParameter(),
1422 cons.LastParameter(), Precision::PConfusion());
1424 Standard_Real wPrev;
1425 Standard_Real wCur = wFirst;
1426 Standard_Real wCurFound = wFirst;
1427 for (i = 2; i < Indices.Length(); i++)
1430 P3d = Nodes(Indices(i));
1431 if (!Loc.IsIdentity())
1432 P3d.Transform(Loc.Transformation());
1434 myLocation3d.Bind(myNbLocat, P3d);
1435 NewNodInStruct(i) = myNbLocat;
1438 wCur = wFirst + wKoef*(Param->Value(i) - wFold);
1439 wCurFound += (wCur - wPrev);
1440 pcos.Perform(P3d, wCurFound);
1441 if (pcos.IsDone()) wCurFound = pcos.Point().Parameter();
1442 theC2d->D0(wCurFound, uv);
1443 v.Initialize(uv.Coord(), myNbLocat, BRepMesh_Frontier);
1444 iv2 = myStructure->AddNode(v);
1445 isv = myVemap.FindIndex(iv2);
1446 if (isv == 0) isv = myVemap.Add(iv2);
1451 if (orEdge == TopAbs_FORWARD)
1452 myStructure->AddLink(BRepMesh_Edge(iv1,iv2,BRepMesh_Frontier));
1453 else if (orEdge == TopAbs_REVERSED)
1454 myStructure->AddLink(BRepMesh_Edge(iv2,iv1,BRepMesh_Frontier));
1455 else if (orEdge == TopAbs_INTERNAL)
1456 myStructure->AddLink(BRepMesh_Edge(iv1,iv2,BRepMesh_Fixed));
1462 if (orEdge == TopAbs_FORWARD)
1463 myStructure->AddLink(BRepMesh_Edge(iv1,ivl,BRepMesh_Frontier));
1464 else if (orEdge == TopAbs_REVERSED)
1465 myStructure->AddLink(BRepMesh_Edge(ivl,iv1,BRepMesh_Frontier));
1466 else if (orEdge == TopAbs_INTERNAL)
1467 myStructure->AddLink(BRepMesh_Edge(iv1,ivl,BRepMesh_Fixed));
1471 Handle(Poly_PolygonOnTriangulation) P1 =
1472 new Poly_PolygonOnTriangulation(NewNodes, Param->Array1());
1473 P1->Deflection(theDefEdge);
1474 if (myInternaledges.IsBound(theEdge))
1476 BRepMesh_PairOfPolygon& pair = myInternaledges.ChangeFind(theEdge);
1477 if (theEdge.Orientation() == TopAbs_REVERSED)
1484 BRepMesh_PairOfPolygon pair1;
1486 myInternaledges.Bind(theEdge, pair1);
1489 Handle(Poly_PolygonOnTriangulation) P2 =
1490 new Poly_PolygonOnTriangulation(NewNodInStruct, Param->Array1());
1491 P2->Deflection(theDefEdge);
1492 BRepMesh_PairOfPolygon pair;
1494 myEdges.Bind(theEdge, pair);
1496 found = Standard_True;
1500 BRepMesh_ShapeTool::NullifyEdge(theEdge, T, Loc);
1501 BRepMesh_ShapeTool::NullifyFace(theFace);
1504 else if (!T.IsNull() && !T->HasUVNodes())
1506 BRepMesh_ShapeTool::NullifyEdge(theEdge, T, Loc);
1507 BRepMesh_ShapeTool::NullifyFace(theFace);
1510 while (!Poly.IsNull());
1515 //=======================================================================
1518 //=======================================================================
1519 Standard_Integer BRepMesh_FastDiscret::NbTriangles() const
1521 return myStructure->NbElements();
1524 //=======================================================================
1525 //function : Triangle
1527 //=======================================================================
1529 const BRepMesh_Triangle& BRepMesh_FastDiscret::Triangle
1530 (const Standard_Integer Index) const
1532 return myStructure->GetElement(Index);
1535 //=======================================================================
1536 //function : NbEdges
1538 //=======================================================================
1540 Standard_Integer BRepMesh_FastDiscret::NbEdges() const
1542 return myStructure->NbLinks();
1545 //=======================================================================
1548 //=======================================================================
1550 const BRepMesh_Edge& BRepMesh_FastDiscret::Edge(const Standard_Integer Index) const
1552 return myStructure->GetLink(Index);
1555 //=======================================================================
1556 //function : NbVertices
1558 //=======================================================================
1560 Standard_Integer BRepMesh_FastDiscret::NbVertices() const
1562 return myStructure->NbNodes();
1565 //=======================================================================
1568 //=======================================================================
1570 const BRepMesh_Vertex& BRepMesh_FastDiscret::Vertex
1571 (const Standard_Integer Index) const
1573 return myStructure->GetNode(Index);
1576 //=======================================================================
1579 //=======================================================================
1581 const gp_Pnt& BRepMesh_FastDiscret::Pnt(const Standard_Integer Index) const
1583 return myLocation3d(myStructure->GetNode(Index).Location3d());
1586 //=======================================================================
1587 //function : VerticesOfDomain
1589 //=======================================================================
1591 void BRepMesh_FastDiscret::VerticesOfDomain(BRepMeshCol::MapOfInteger& Indices) const
1595 // recuperate from the map of edges.
1596 const BRepMeshCol::MapOfInteger& edmap = myStructure->LinksOfDomain();
1598 // iterator on edges.
1599 BRepMeshCol::MapOfInteger::Iterator iter(edmap);
1601 Standard_Integer ind_edge;
1602 for (iter.Reset(); iter.More(); iter.Next()) {
1603 ind_edge = iter.Key();
1604 const BRepMesh_Edge& Ed = Edge(ind_edge);
1605 Indices.Add(Ed.FirstNode());
1606 Indices.Add(Ed.LastNode());
1610 BRepMesh_Status BRepMesh_FastDiscret::CurrentFaceStatus() const
1615 //=======================================================================
1616 //function : GetFaceAttribute
1618 //=======================================================================
1620 Standard_Boolean BRepMesh_FastDiscret::GetFaceAttribute(const TopoDS_Face& theFace,
1621 Handle(BRepMesh_FaceAttribute)& theFattrib) const
1623 if(myMapattrib.IsBound(theFace))
1625 theFattrib = myMapattrib(theFace);
1626 return Standard_True;
1628 return Standard_False;
1631 //=======================================================================
1632 //function : RemoveFaceAttribute
1634 //=======================================================================
1636 void BRepMesh_FastDiscret::RemoveFaceAttribute(const TopoDS_Face& theFace)
1638 if(myMapattrib.IsBound(theFace))
1639 myMapattrib.UnBind(theFace);
1642 //=======================================================================
1643 //function : CreateMutexesForSubShapes
1645 //=======================================================================
1646 void BRepMesh_FastDiscret::CreateMutexesForSubShapes(const TopoDS_Shape& theShape,
1647 const TopAbs_ShapeEnum theType)
1649 myMutexProvider.CreateMutexesForSubShapes(theShape, theType);
1652 //=======================================================================
1653 //function : RemoveAllMutexes
1655 //=======================================================================
1656 void BRepMesh_FastDiscret::RemoveAllMutexes()
1658 myMutexProvider.RemoveAllMutexes();