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_EdgeParameterProvider.hxx>
27 #include <BRepMesh_IEdgeTool.hxx>
28 #include <BRepMesh_EdgeTessellator.hxx>
29 #include <BRepMesh_EdgeTessellationExtractor.hxx>
31 #include <BRepAdaptor_Curve.hxx>
32 #include <BRepAdaptor_Surface.hxx>
33 #include <BRepAdaptor_HSurface.hxx>
35 #include <Bnd_Box.hxx>
36 #include <BRepTools.hxx>
37 #include <BRepBndLib.hxx>
38 #include <BndLib_Add3dCurve.hxx>
39 #include <Poly_Triangulation.hxx>
40 #include <Poly_PolygonOnTriangulation.hxx>
42 #include <Precision.hxx>
43 #include <Geom2d_Curve.hxx>
44 #include <Geom_Surface.hxx>
45 #include <Geom_Plane.hxx>
46 #include <GeomAbs_SurfaceType.hxx>
47 #include <Extrema_LocateExtPC.hxx>
49 #include <TColStd_Array1OfInteger.hxx>
50 #include <TColStd_HArray1OfReal.hxx>
51 #include <TColgp_Array1OfPnt2d.hxx>
52 #include <TColGeom2d_SequenceOfCurve.hxx>
53 #include <SortTools_ShellSortOfReal.hxx>
54 #include <TCollection_CompareOfReal.hxx>
56 #include <TopTools_SequenceOfShape.hxx>
57 #include <TopTools_ListIteratorOfListOfShape.hxx>
61 #include <TopoDS_Vertex.hxx>
63 #include <TopExp_Explorer.hxx>
65 #include <OSD_Parallel.hxx>
67 #include <Standard_ErrorHandler.hxx>
68 #include <Standard_Failure.hxx>
69 #include <NCollection_IncAllocator.hxx>
71 #include <BRep_ListIteratorOfListOfPointRepresentation.hxx>
72 #include <BRep_PointRepresentation.hxx>
76 #define UVDEFLECTION 1.e-05
79 //=======================================================================
80 //function : BRepMesh_FastDiscret
82 //=======================================================================
83 BRepMesh_FastDiscret::BRepMesh_FastDiscret(
84 const Standard_Real theDefle,
85 const Standard_Real theAngl,
86 const Bnd_Box& theBox,
87 const Standard_Boolean theWithShare,
88 const Standard_Boolean theInshape,
89 const Standard_Boolean theRelative,
90 const Standard_Boolean theShapetrigu,
91 const Standard_Boolean isInParallel,
92 const Standard_Real theMinSize,
93 const Standard_Boolean isInternalVerticesMode,
94 const Standard_Boolean isControlSurfaceDeflection)
96 myDeflection (theDefle),
97 myWithShare (theWithShare),
98 myInParallel (isInParallel),
99 myRelative (theRelative),
100 myShapetrigu (theShapetrigu),
101 myInshape (theInshape),
102 myBoundaryVertices(new BRepMesh::DMapOfVertexInteger),
103 myBoundaryPoints(new BRepMesh::DMapOfIntegerPnt),
104 myMinSize(theMinSize),
105 myInternalVerticesMode(isInternalVerticesMode),
106 myIsControlSurfaceDeflection(isControlSurfaceDeflection)
109 BRepMesh_ShapeTool::BoxMaxDimension(theBox, myDtotale);
112 //=======================================================================
113 //function : BRepMesh_FastDiscret
115 //=======================================================================
116 BRepMesh_FastDiscret::BRepMesh_FastDiscret(
117 const TopoDS_Shape& theShape,
118 const Standard_Real theDefle,
119 const Standard_Real theAngl,
120 const Bnd_Box& theBox,
121 const Standard_Boolean theWithShare,
122 const Standard_Boolean theInshape,
123 const Standard_Boolean theRelative,
124 const Standard_Boolean theShapetrigu,
125 const Standard_Boolean isInParallel,
126 const Standard_Real theMinSize,
127 const Standard_Boolean isInternalVerticesMode,
128 const Standard_Boolean isControlSurfaceDeflection)
130 myDeflection (theDefle),
131 myWithShare (theWithShare),
132 myInParallel (isInParallel),
133 myRelative (theRelative),
134 myShapetrigu (theShapetrigu),
135 myInshape (theInshape),
136 myBoundaryVertices(new BRepMesh::DMapOfVertexInteger),
137 myBoundaryPoints(new BRepMesh::DMapOfIntegerPnt),
138 myMinSize(theMinSize),
139 myInternalVerticesMode(isInternalVerticesMode),
140 myIsControlSurfaceDeflection(isControlSurfaceDeflection)
143 BRepMesh_ShapeTool::BoxMaxDimension(theBox, myDtotale);
148 //=======================================================================
149 //function : InitSharedFaces
151 //=======================================================================
152 void BRepMesh_FastDiscret::InitSharedFaces(const TopoDS_Shape& theShape)
154 TopExp::MapShapesAndAncestors(theShape, TopAbs_EDGE, TopAbs_FACE, mySharedFaces);
157 //=======================================================================
158 //function : Perform(shape)
160 //=======================================================================
161 void BRepMesh_FastDiscret::Perform(const TopoDS_Shape& theShape)
163 InitSharedFaces(theShape);
165 std::vector<TopoDS_Face> aFaces;
166 TopExp_Explorer anExplorer(theShape, TopAbs_FACE);
167 for (; anExplorer.More(); anExplorer.Next())
169 const TopoDS_Face& aFace = TopoDS::Face(anExplorer.Current());
171 aFaces.push_back(aFace);
174 OSD_Parallel::ForEach(aFaces.begin(), aFaces.end(), *this, !myInParallel);
178 //=======================================================================
181 //=======================================================================
182 void BRepMesh_FastDiscret::Process(const TopoDS_Face& theFace) const
184 Handle(BRepMesh_FaceAttribute) anAttribute;
185 if (GetFaceAttribute(theFace, anAttribute))
191 BRepMesh_FastDiscretFace aTool(GetAngle(), myMinSize,
192 myInternalVerticesMode, myIsControlSurfaceDeflection);
193 aTool.Perform(anAttribute);
195 catch (Standard_Failure)
197 anAttribute->SetStatus(BRepMesh_Failure);
202 //=======================================================================
203 //function : resetDataStructure
205 //=======================================================================
206 void BRepMesh_FastDiscret::resetDataStructure()
208 Handle(NCollection_IncAllocator) aAllocator;
209 if (myAttribute->ChangeStructure().IsNull())
210 aAllocator = new NCollection_IncAllocator(BRepMesh::MEMORY_BLOCK_SIZE_HUGE);
212 aAllocator = myAttribute->ChangeStructure()->Allocator();
214 myAttribute->Clear();
215 aAllocator->Reset(Standard_False);
216 Handle(BRepMesh_DataStructureOfDelaun) aStructure =
217 new BRepMesh_DataStructureOfDelaun(aAllocator);
219 const Standard_Real aTolU = myAttribute->ToleranceU();
220 const Standard_Real aTolV = myAttribute->ToleranceV();
221 const Standard_Real uCellSize = 14.0 * aTolU;
222 const Standard_Real vCellSize = 14.0 * aTolV;
224 aStructure->Data()->SetCellSize ( uCellSize, vCellSize);
225 aStructure->Data()->SetTolerance( aTolU , aTolV );
227 myAttribute->ChangeStructure() = aStructure;
230 //=======================================================================
231 //function : Add(face)
233 //=======================================================================
234 Standard_Integer BRepMesh_FastDiscret::Add(const TopoDS_Face& theFace)
240 // Initialize face attributes
241 myAttribute.Nullify();
242 GetFaceAttribute(theFace, myAttribute);
243 if (myAttribute.IsNull())
245 myAttribute = new BRepMesh_FaceAttribute(theFace,
246 myBoundaryVertices, myBoundaryPoints);
248 myAttributes.Bind(theFace, myAttribute);
251 BRepMesh::HIMapOfInteger& aVertexEdgeMap = myAttribute->ChangeVertexEdgeMap();
252 BRepMesh::HDMapOfShapePairOfPolygon& aInternalEdges = myAttribute->ChangeInternalEdges();
254 resetDataStructure();
259 myBoundaryVertices->Clear();
260 myBoundaryPoints->Clear();
263 Standard_Real defedge;
264 Standard_Integer nbEdge = 0;
265 Standard_Real savangle = myAngle;
267 Standard_Real maxdef = 2.* BRepMesh_ShapeTool::MaxFaceTolerance(theFace);
269 Standard_Real defface = 0.;
271 defface = Max(myDeflection, maxdef);
273 NCollection_Sequence<EdgePCurve> aPCurves;
274 NCollection_Sequence<TopoDS_Edge> aFaceEdges;
276 const TopoDS_Face& aFace = myAttribute->Face();
277 const Handle(BRepAdaptor_HSurface)& gFace = myAttribute->Surface();
278 TopExp_Explorer aWireIt(aFace, TopAbs_WIRE);
279 for (; aWireIt.More(); aWireIt.Next())
281 TopExp_Explorer aEdgeIt(aWireIt.Current(), TopAbs_EDGE);
282 for (; aEdgeIt.More(); aEdgeIt.Next(), ++nbEdge)
284 const TopoDS_Edge& aEdge = TopoDS::Edge(aEdgeIt.Current());
285 if (!myMapdefle.IsBound(aEdge))
289 if (myEdges.IsBound(aEdge))
291 const BRepMesh_PairOfPolygon& aPair = myEdges.Find(aEdge);
292 const Handle(Poly_PolygonOnTriangulation)& aPolygon = aPair.First();
293 defedge = aPolygon->Deflection();
297 defedge = BRepMesh_ShapeTool::RelativeEdgeDeflection(
298 aEdge, myDeflection, myDtotale, cdef);
300 myAngle = savangle * cdef;
304 defface = Max(maxdef, defface);
308 defedge = myDeflection;
311 defedge = Max(maxdef, defedge);
312 defedge = Max(UVDEFLECTION, defedge);
313 myMapdefle.Bind(aEdge, defedge);
317 defedge = myMapdefle(aEdge);
321 defface = Max(maxdef, defface);
325 Standard_Real aFirstParam, aLastParam;
326 Handle(Geom2d_Curve) aCurve2d =
327 BRep_Tool::CurveOnSurface(aEdge, aFace, aFirstParam, aLastParam);
329 if (aCurve2d.IsNull())
332 EdgePCurve aPCurve = { aCurve2d, aFirstParam, aLastParam };
333 aPCurves.Append(aPCurve);
334 aFaceEdges.Append(aEdge);
336 add(aEdge, aPCurve, defedge);
341 if ( nbEdge == 0 || aVertexEdgeMap->Extent() < 3 )
343 myAttribute->ChangeStructure().Nullify();
344 myAttribute->SetStatus(BRepMesh_Failure);
345 return myAttribute->GetStatus();
350 defface = defface / nbEdge;
354 defface = myDeflection;
358 defface = Max(maxdef, defface);
360 TopLoc_Location aLoc;
361 Handle(Poly_Triangulation) aTriangulation = BRep_Tool::Triangulation(aFace, aLoc);
363 if (!myShapetrigu || aTriangulation.IsNull())
365 Standard_Real xCur, yCur;
366 Standard_Real maxX, minX, maxY, minY;
368 minX = minY = 1.e100;
369 maxX = maxY =-1.e100;
371 Standard_Integer ipn = 0;
372 Standard_Integer i1 = 1;
373 for ( i1 = 1; i1 <= aVertexEdgeMap->Extent(); ++i1 )
375 const BRepMesh_Vertex& aVertex =
376 myAttribute->ChangeStructure()->GetNode(aVertexEdgeMap->FindKey(i1));
380 xCur = aVertex.Coord().X();
381 yCur = aVertex.Coord().Y();
383 minX = Min(xCur, minX);
384 maxX = Max(xCur, maxX);
385 minY = Min(yCur, minY);
386 maxY = Max(yCur, maxY);
389 Standard_Real myumin = minX;
390 Standard_Real myumax = maxX;
391 Standard_Real myvmin = minY;
392 Standard_Real myvmax = maxY;
394 const Standard_Real umin = gFace->FirstUParameter();
395 const Standard_Real umax = gFace->LastUParameter();
396 const Standard_Real vmin = gFace->FirstVParameter();
397 const Standard_Real vmax = gFace->LastVParameter();
399 if (myumin < umin || myumax > umax)
401 if (gFace->IsUPeriodic())
403 if ((myumax - myumin) > (umax - umin))
404 myumax = myumin + (umax - umin);
416 if (myvmin < vmin || myvmax > vmax)
418 if (gFace->IsVPeriodic())
420 if ((myvmax - myvmin) > (vmax - vmin))
421 myvmax = myvmin + (vmax - vmin);
433 GeomAbs_SurfaceType aSurfType = gFace->GetType();
434 // Fast verification of the validity of calculated limits.
435 // If wrong, sure a problem of pcurve.
436 if (aSurfType == GeomAbs_BezierSurface &&
437 (myumin < -0.5 || myumax > 1.5 || myvmin < -0.5 || myvmax > 1.5) )
439 myAttribute->ChangeStructure().Nullify();
440 myAttribute->SetStatus(BRepMesh_Failure);
441 return myAttribute->GetStatus();
444 //define parameters for correct parametrics
445 Standard_Real deltaX = 1.0;
446 Standard_Real deltaY = 1.0;
449 BRepMesh::HClassifier& aClassifier = myAttribute->ChangeClassifier();
450 BRepMesh_WireChecker aDFaceChecker(aFace, Precision::PConfusion(),
451 aInternalEdges, aVertexEdgeMap, myAttribute->ChangeStructure(),
452 myumin, myumax, myvmin, myvmax, myInParallel );
454 aDFaceChecker.ReCompute(aClassifier);
455 BRepMesh_Status aCheckStatus = aDFaceChecker.Status();
457 if (aCheckStatus == BRepMesh_SelfIntersectingWire)
459 Standard_Integer nbmaill = 0;
460 Standard_Real eps = Precision::Confusion();
461 while (nbmaill < 5 && aCheckStatus != BRepMesh_ReMesh)
465 resetDataStructure();
466 for (Standard_Integer j = 1; j <= aFaceEdges.Length(); ++j)
468 const TopoDS_Edge& anEdge = aFaceEdges(j);
469 if (myEdges.IsBound(anEdge))
470 myEdges.UnBind(anEdge);
472 defedge = Max(myMapdefle(anEdge) / 3.0, eps);
473 myMapdefle.Bind(anEdge, defedge);
475 add(anEdge, aPCurves(j), defedge);
478 aDFaceChecker.ReCompute(aClassifier);
479 if (aDFaceChecker.Status() == BRepMesh_NoError)
480 aCheckStatus = BRepMesh_ReMesh;
484 myAttribute->SetStatus(aCheckStatus);
485 if (!myAttribute->IsValid())
487 myAttribute->ChangeStructure().Nullify();
488 return myAttribute->GetStatus();
492 // try to find the real length:
493 // akm (bug OCC16) : We must calculate these measures in non-singular
494 // parts of face. Let's try to compute average value of three
495 // (umin, (umin+umax)/2, umax), and respectively for v.
497 Standard_Real longu = 0.0, longv = 0.0; //, last , first;
498 gp_Pnt P11, P12, P21, P22, P31, P32;
500 Standard_Real du = 0.05 * ( myumax - myumin );
501 Standard_Real dv = 0.05 * ( myvmax - myvmin );
502 Standard_Real dfuave = 0.5 * ( myumin + myumax );
503 Standard_Real dfvave = 0.5 * ( myvmin + myvmax );
504 Standard_Real dfucur, dfvcur;
507 gFace->D0(myumin, myvmin, P11);
508 gFace->D0(myumin, dfvave, P21);
509 gFace->D0(myumin, myvmax, P31);
510 for (i1=1, dfucur=myumin+du; i1 <= 20; i1++, dfucur+=du)
512 gFace->D0(dfucur, myvmin, P12);
513 gFace->D0(dfucur, dfvave, P22);
514 gFace->D0(dfucur, myvmax, P32);
515 longu += ( P11.Distance(P12) + P21.Distance(P22) + P31.Distance(P32) );
522 gFace->D0(myumin, myvmin, P11);
523 gFace->D0(dfuave, myvmin, P21);
524 gFace->D0(myumax, myvmin, P31);
525 for (i1=1, dfvcur=myvmin+dv; i1 <= 20; i1++, dfvcur+=dv)
527 gFace->D0(myumin, dfvcur, P12);
528 gFace->D0(dfuave, dfvcur, P22);
529 gFace->D0(myumax, dfvcur, P32);
530 longv += ( P11.Distance(P12) + P21.Distance(P22) + P31.Distance(P32) );
538 // akm (bug OCC16) ^^^^^
540 if (longu <= 1.e-16 || longv <= 1.e-16)
543 myAttribute->ChangeStructure().Nullify();
544 myAttribute->SetStatus(BRepMesh_Failure);
545 return myAttribute->GetStatus();
549 if (aSurfType == GeomAbs_Torus)
551 gp_Torus Tor = gFace->Torus();
552 Standard_Real r = Tor.MinorRadius(), R = Tor.MajorRadius();
553 Standard_Real Du, Dv;//, pasu, pasv;
555 Dv = Max(1.0e0 - (defface/r),0.0e0) ;
556 Standard_Real oldDv = 2.0 * ACos (Dv);
557 oldDv = Min(oldDv, myAngle);
558 Dv = 0.9*oldDv; //TWOTHIRD * oldDv;
561 Standard_Integer nbV = Max((Standard_Integer)((myvmax-myvmin)/Dv), 2);
562 Dv = (myvmax-myvmin)/(nbV+1);
564 Standard_Real ru = R + r;
567 Du = Max(1.0e0 - (defface/ru),0.0e0);
568 Du = (2.0 * ACos (Du));
569 Du = Min(Du, myAngle);
570 Standard_Real aa = sqrt(Du*Du + oldDv*oldDv);
572 if (aa < gp::Resolution())
574 myAttribute->ChangeStructure().Nullify();
575 return myAttribute->GetStatus();
578 Du = Du * Min(oldDv, Du) / aa;
585 Standard_Integer nbU = Max((Standard_Integer)((myumax-myumin)/Du), 2);
586 nbU = Max(nbU, (Standard_Integer)(nbV*(myumax-myumin)*R/((myvmax-myvmin)*r)/5.));
588 Du = (myumax-myumin)/(nbU+1);
589 //-- DeltaX and DeltaY are chosen so that to avoid "jumping"
590 //-- of points on the grid
594 else if (aSurfType == GeomAbs_Cylinder)
596 gp_Cylinder Cyl = gFace->Cylinder();
597 Standard_Real R = Cyl.Radius();
599 // Calculate parameters for iteration in U direction
600 Standard_Real Du = 1.0 - (defface/R);
604 Du = 2.0 * ACos (Du);
613 deltaX = (myumax-myumin)/longu;
614 deltaY = (myvmax-myvmin)/longv;
617 // Restore face attribute
618 myAttribute->SetDefFace(defface);
619 myAttribute->SetUMax(myumax);
620 myAttribute->SetVMax(myvmax);
621 myAttribute->SetUMin(myumin);
622 myAttribute->SetVMin(myvmin);
623 myAttribute->SetDeltaX(deltaX);
624 myAttribute->SetDeltaY(deltaY);
627 catch(Standard_Failure)
629 myAttribute->SetStatus(BRepMesh_Failure);
632 myAttribute->ChangeMeshNodes() =
633 myAttribute->ChangeStructure()->Data()->Vertices();
635 myAttribute->ChangeStructure().Nullify();
636 return myAttribute->GetStatus();
639 //=======================================================================
640 //function : getEdgeAttributes
642 //=======================================================================
643 Standard_Boolean BRepMesh_FastDiscret::getEdgeAttributes(
644 const TopoDS_Edge& theEdge,
645 const BRepMesh_FastDiscret::EdgePCurve& thePCurve,
646 const Standard_Real theDefEdge,
647 BRepMesh_FastDiscret::EdgeAttributes& theAttributes) const
649 EdgeAttributes& aEAttr = theAttributes;
652 TopExp::Vertices(theEdge, aEAttr.FirstVertex, aEAttr.LastVertex);
653 if (aEAttr.FirstVertex.IsNull() || aEAttr.LastVertex.IsNull())
654 return Standard_False;
656 // Get range on 2d curve
657 const TopoDS_Face& aFace = myAttribute->Face();
658 BRep_Tool::Range(theEdge, aFace, aEAttr.FirstParam, aEAttr.LastParam);
660 // Get end points on 2d curve
661 BRep_Tool::UVPoints(theEdge, aFace, aEAttr.FirstUV, aEAttr.LastUV);
664 aEAttr.FirstUV.IsEqual(aEAttr.LastUV, Precision::PConfusion());
666 //Control tolerance of vertices
667 const Handle(BRepAdaptor_HSurface)& gFace = myAttribute->Surface();
668 gp_Pnt pFirst = gFace->Value(aEAttr.FirstUV.X(), aEAttr.FirstUV.Y());
669 gp_Pnt pLast = gFace->Value(aEAttr.LastUV.X(), aEAttr.LastUV.Y());
671 aEAttr.MinDist = 10. * Max(pFirst.Distance(BRep_Tool::Pnt(aEAttr.FirstVertex)),
672 pLast .Distance(BRep_Tool::Pnt(aEAttr.LastVertex)));
674 if (aEAttr.MinDist < BRep_Tool::Tolerance(aEAttr.FirstVertex) ||
675 aEAttr.MinDist < BRep_Tool::Tolerance(aEAttr.LastVertex))
677 aEAttr.MinDist = theDefEdge;
682 // 1. is it really sameUV without being degenerated
684 thePCurve.Curve2d->D0(thePCurve.FirstParam, uvF);
685 thePCurve.Curve2d->D0(thePCurve.LastParam, uvL);
687 if (!aEAttr.FirstUV.IsEqual(uvF, Precision::PConfusion()))
688 aEAttr.FirstUV = uvF;
690 if (!aEAttr.LastUV.IsEqual(uvL, Precision::PConfusion()))
694 return Standard_True;
697 //=======================================================================
698 //function : registerEdgeVertices
700 //=======================================================================
701 void BRepMesh_FastDiscret::registerEdgeVertices(
702 BRepMesh_FastDiscret::EdgeAttributes& theAttributes,
703 Standard_Integer& ipf,
704 Standard_Integer& ivf,
705 Standard_Integer& isvf,
706 Standard_Integer& ipl,
707 Standard_Integer& ivl,
708 Standard_Integer& isvl)
710 EdgeAttributes& aEAttr = theAttributes;
711 if (aEAttr.FirstVExtractor.IsNull())
713 // Use edge geometry to produce tesselation.
714 aEAttr.FirstVExtractor =
715 new TopoDSVExplorer(aEAttr.FirstVertex, aEAttr.IsSameUV, aEAttr.LastVertex);
718 if (aEAttr.LastVExtractor.IsNull())
720 // Use edge geometry to produce tesselation.
721 aEAttr.LastVExtractor =
722 new TopoDSVExplorer(aEAttr.LastVertex, aEAttr.IsSameUV, aEAttr.FirstVertex);
726 // Process first vertex
727 ipf = myAttribute->GetVertexIndex(aEAttr.FirstVExtractor, Standard_True);
728 aTmpUV = BRepMesh_ShapeTool::FindUV(ipf, aEAttr.FirstUV, aEAttr.FirstVertex,
729 aEAttr.MinDist, myAttribute);
731 myAttribute->AddNode(ipf, aTmpUV, BRepMesh_Frontier, ivf, isvf);
733 // Process last vertex
734 ipl = aEAttr.LastVertex.IsSame(aEAttr.FirstVertex) ? ipf :
735 myAttribute->GetVertexIndex(aEAttr.LastVExtractor, Standard_True);
736 aTmpUV = BRepMesh_ShapeTool::FindUV(ipl, aEAttr.LastUV, aEAttr.LastVertex,
737 aEAttr.MinDist, myAttribute);
739 myAttribute->AddNode(ipl, aTmpUV, BRepMesh_Frontier, ivl, isvl);
742 //=======================================================================
745 //=======================================================================
746 void BRepMesh_FastDiscret::add(
747 const TopoDS_Edge& theEdge,
748 const BRepMesh_FastDiscret::EdgePCurve& thePCurve,
749 const Standard_Real theDefEdge)
751 const TopAbs_Orientation orEdge = theEdge.Orientation();
752 if (orEdge == TopAbs_EXTERNAL)
755 EdgeAttributes aEAttr;
756 if (!getEdgeAttributes(theEdge, thePCurve, theDefEdge, aEAttr))
759 if (!myEdges.IsBound(theEdge))
761 update(theEdge, thePCurve.Curve2d, theDefEdge, aEAttr);
765 Standard_Integer ipf, ivf, isvf, ipl, ivl, isvl;
766 registerEdgeVertices(aEAttr, ipf, ivf, isvf, ipl, ivl, isvl);
768 // If this Edge has been already checked and it is not degenerated,
769 // the points of the polygon calculated at the first check are retrieved :
771 // retrieve the polygone:
772 const BRepMesh_PairOfPolygon& aPair = myEdges.Find(theEdge);
773 const Handle(Poly_PolygonOnTriangulation)& aPolygon = aPair.First();
774 const TColStd_Array1OfInteger& aNodes = aPolygon->Nodes();
775 Handle(TColStd_HArray1OfReal) aParams = aPolygon->Parameters();
778 const Standard_Integer aNodesNb = aNodes.Length();
779 TColStd_Array1OfInteger aNewNodes (1, aNodesNb);
780 TColStd_Array1OfReal aNewParams(1, aNodesNb);
782 aNewNodes (1) = isvf;
783 aNewParams(1) = aEAttr.FirstParam;
785 aNewNodes (aNodesNb) = isvl;
786 aNewParams(aNodesNb) = aEAttr.LastParam;
788 const TopoDS_Face& aFace = myAttribute->Face();
789 if (!BRepMesh_ShapeTool::IsDegenerated(theEdge, aFace))
791 BRepMesh_EdgeParameterProvider aProvider(theEdge, aFace, aParams);
792 for (Standard_Integer i = 2; i < aNodesNb; ++i)
794 const Standard_Integer aPointId = aNodes(i);
795 const gp_Pnt& aPnt = myBoundaryPoints->Find(aPointId);
797 const Standard_Real aParam = aProvider.Parameter(i, aPnt);
798 gp_Pnt2d aUV = thePCurve.Curve2d->Value(aParam);
800 Standard_Integer iv2, isv;
801 myAttribute->AddNode(aPointId, aUV.Coord(), BRepMesh_OnCurve, iv2, isv);
804 aNewParams(i) = aParam;
808 Handle(Poly_PolygonOnTriangulation) P1 =
809 new Poly_PolygonOnTriangulation(aNewNodes, aNewParams);
811 storePolygon(theEdge, P1, theDefEdge);
814 //=======================================================================
815 //function : update(edge)
817 //=======================================================================
818 void BRepMesh_FastDiscret::update(
819 const TopoDS_Edge& theEdge,
820 const Handle(Geom2d_Curve)& theC2d,
821 const Standard_Real theDefEdge,
822 BRepMesh_FastDiscret::EdgeAttributes& theAttributes)
824 EdgeAttributes& aEAttr = theAttributes;
826 const TopoDS_Face& aFace = myAttribute->Face();
827 Handle(BRepMesh_IEdgeTool) aEdgeTool;
828 // Try to find existing tessellation.
829 for (Standard_Integer i = 1; aEdgeTool.IsNull(); ++i)
831 TopLoc_Location aLoc;
832 Handle(Poly_Triangulation) aTriangulation;
833 Handle(Poly_PolygonOnTriangulation) aPolygon;
834 BRep_Tool::PolygonOnTriangulation(theEdge, aPolygon, aTriangulation, aLoc, i);
836 if (aPolygon.IsNull())
839 if (aTriangulation.IsNull() || !aPolygon->HasParameters())
842 if (aPolygon->Deflection() > 1.1 * theDefEdge)
845 const TColgp_Array1OfPnt& aNodes = aTriangulation->Nodes();
846 const TColStd_Array1OfInteger& aIndices = aPolygon->Nodes();
847 Handle(TColStd_HArray1OfReal) aParams = aPolygon->Parameters();
849 aEAttr.FirstVExtractor = new PolyVExplorer(aEAttr.FirstVertex,
850 aEAttr.IsSameUV, aEAttr.LastVertex, aIndices(1), aNodes, aLoc);
852 aEAttr.LastVExtractor = new PolyVExplorer(aEAttr.LastVertex,
853 aEAttr.IsSameUV, aEAttr.FirstVertex, aIndices(aIndices.Length()), aNodes, aLoc);
855 aEdgeTool = new BRepMesh_EdgeTessellationExtractor(theEdge, theC2d,
856 aFace, aTriangulation, aPolygon, aLoc);
859 if (aEdgeTool.IsNull())
861 aEdgeTool = new BRepMesh_EdgeTessellator(theEdge, myAttribute,
862 mySharedFaces, theDefEdge, myAngle, myMinSize);
865 Standard_Integer ipf, ivf, isvf, ipl, ivl, isvl;
866 registerEdgeVertices(aEAttr, ipf, ivf, isvf, ipl, ivl, isvl);
868 Handle(Poly_PolygonOnTriangulation) P1, P2;
869 if (BRepMesh_ShapeTool::IsDegenerated(theEdge, aFace))
871 const Standard_Integer aNodesNb = 2;
872 TColStd_Array1OfInteger aNewNodes (1, aNodesNb);
873 TColStd_Array1OfInteger aNewNodInStruct(1, aNodesNb);
874 TColStd_Array1OfReal aNewParams (1, aNodesNb);
876 aNewNodInStruct(1) = ipf;
877 aNewNodes (1) = isvf;
878 aNewParams (1) = aEAttr.FirstParam;
880 aNewNodInStruct(aNodesNb) = ipl;
881 aNewNodes (aNodesNb) = isvl;
882 aNewParams (aNodesNb) = aEAttr.LastParam;
884 P1 = new Poly_PolygonOnTriangulation(aNewNodes, aNewParams);
885 P2 = new Poly_PolygonOnTriangulation(aNewNodInStruct, aNewParams);
889 const Standard_Integer aNodesNb = aEdgeTool->NbPoints();
890 TColStd_Array1OfInteger aNewNodes (1, aNodesNb);
891 TColStd_Array1OfInteger aNewNodInStruct(1, aNodesNb);
892 TColStd_Array1OfReal aNewParams (1, aNodesNb);
894 aNewNodInStruct(1) = ipf;
895 aNewNodes (1) = isvf;
896 aNewParams (1) = aEAttr.FirstParam;
898 aNewNodInStruct(aNodesNb) = ipl;
899 aNewNodes (aNodesNb) = isvl;
900 aNewParams (aNodesNb) = aEAttr.LastParam;
902 Standard_Integer aLastPointId = myAttribute->LastPointId();
903 for (Standard_Integer i = 2; i < aNodesNb; ++i)
907 Standard_Real aParam;
908 aEdgeTool->Value(i, aParam, aPnt, aUV);
909 myBoundaryPoints->Bind(++aLastPointId, aPnt);
911 Standard_Integer iv2, isv;
912 myAttribute->AddNode(aLastPointId, aUV.Coord(), BRepMesh_Frontier, iv2, isv);
914 aNewNodInStruct(i) = aLastPointId;
916 aNewParams (i) = aParam;
919 P1 = new Poly_PolygonOnTriangulation(aNewNodes, aNewParams);
920 P2 = new Poly_PolygonOnTriangulation(aNewNodInStruct, aNewParams);
923 storePolygon(theEdge, P1, theDefEdge);
924 storePolygonSharedData(theEdge, P2, theDefEdge);
927 //=======================================================================
928 //function : storeInternalPolygon
930 //=======================================================================
931 void BRepMesh_FastDiscret::storePolygon(
932 const TopoDS_Edge& theEdge,
933 Handle(Poly_PolygonOnTriangulation)& thePolygon,
934 const Standard_Real theDeflection)
936 thePolygon->Deflection(theDeflection);
937 BRepMesh::HDMapOfShapePairOfPolygon& aInternalEdges = myAttribute->ChangeInternalEdges();
938 if (aInternalEdges->IsBound(theEdge))
940 BRepMesh_PairOfPolygon& aPair = aInternalEdges->ChangeFind(theEdge);
941 if (theEdge.Orientation() == TopAbs_REVERSED)
942 aPair.Append(thePolygon);
944 aPair.Prepend(thePolygon);
949 BRepMesh_PairOfPolygon aPair;
950 aPair.Append(thePolygon);
951 aInternalEdges->Bind(theEdge, aPair);
954 //=======================================================================
955 //function : storePolygonSharedData
957 //=======================================================================
958 void BRepMesh_FastDiscret::storePolygonSharedData(
959 const TopoDS_Edge& theEdge,
960 Handle(Poly_PolygonOnTriangulation)& thePolygon,
961 const Standard_Real theDeflection)
963 thePolygon->Deflection(theDeflection);
964 BRepMesh_PairOfPolygon aPair;
965 aPair.Append(thePolygon);
966 myEdges.Bind(theEdge, aPair);
969 //=======================================================================
970 //function : GetFaceAttribute
972 //=======================================================================
973 Standard_Boolean BRepMesh_FastDiscret::GetFaceAttribute(
974 const TopoDS_Face& theFace,
975 Handle(BRepMesh_FaceAttribute)& theAttribute ) const
977 if (myAttributes.IsBound(theFace))
979 theAttribute = myAttributes(theFace);
980 return Standard_True;
983 return Standard_False;
986 //=======================================================================
987 //function : RemoveFaceAttribute
989 //=======================================================================
990 void BRepMesh_FastDiscret::RemoveFaceAttribute(const TopoDS_Face& theFace)
992 if (myAttributes.IsBound(theFace))
993 myAttributes.UnBind(theFace);