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>
54 #include <TopTools_SequenceOfShape.hxx>
55 #include <TopTools_ListIteratorOfListOfShape.hxx>
59 #include <TopoDS_Vertex.hxx>
61 #include <TopExp_Explorer.hxx>
63 #include <OSD_Parallel.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>
74 IMPLEMENT_STANDARD_RTTIEXT(BRepMesh_FastDiscret,Standard_Transient)
76 #define UVDEFLECTION 1.e-05
78 //=======================================================================
79 //function : BRepMesh_FastDiscret
81 //=======================================================================
82 BRepMesh_FastDiscret::BRepMesh_FastDiscret( const Bnd_Box& theBox,
83 const BRepMesh_FastDiscret::Parameters& theParams)
85 myBoundaryVertices(new BRepMesh::DMapOfVertexInteger),
86 myBoundaryPoints(new BRepMesh::DMapOfIntegerPnt),
87 myParameters(theParams),
90 if ( myParameters.Relative )
91 BRepMesh_ShapeTool::BoxMaxDimension(theBox, myDtotale);
94 //=======================================================================
95 //function : InitSharedFaces
97 //=======================================================================
98 void BRepMesh_FastDiscret::InitSharedFaces(const TopoDS_Shape& theShape)
100 TopExp::MapShapesAndAncestors(theShape, TopAbs_EDGE, TopAbs_FACE, mySharedFaces);
103 //=======================================================================
104 //function : Perform(shape)
106 //=======================================================================
107 void BRepMesh_FastDiscret::Perform(const TopoDS_Shape& theShape)
109 InitSharedFaces(theShape);
111 std::vector<TopoDS_Face> aFaces;
112 TopExp_Explorer anExplorer(theShape, TopAbs_FACE);
113 for (; anExplorer.More(); anExplorer.Next())
115 const TopoDS_Face& aFace = TopoDS::Face(anExplorer.Current());
117 aFaces.push_back(aFace);
120 OSD_Parallel::ForEach(aFaces.begin(), aFaces.end(), *this, !myParameters.InParallel);
124 //=======================================================================
127 //=======================================================================
128 void BRepMesh_FastDiscret::Process(const TopoDS_Face& theFace) const
130 Handle(BRepMesh_FaceAttribute) anAttribute;
131 if (GetFaceAttribute(theFace, anAttribute))
137 BRepMesh_FastDiscretFace aTool(myParameters.Angle, myParameters.MinSize,
138 myParameters.InternalVerticesMode, myParameters.ControlSurfaceDeflection);
139 aTool.Perform(anAttribute);
141 catch (Standard_Failure)
143 anAttribute->SetStatus(BRepMesh_Failure);
148 //=======================================================================
149 //function : resetDataStructure
151 //=======================================================================
152 void BRepMesh_FastDiscret::resetDataStructure()
154 Handle(NCollection_IncAllocator) aAllocator;
155 if (myAttribute->ChangeStructure().IsNull())
156 aAllocator = new NCollection_IncAllocator(BRepMesh::MEMORY_BLOCK_SIZE_HUGE);
158 aAllocator = myAttribute->ChangeStructure()->Allocator();
160 myAttribute->Clear();
161 aAllocator->Reset(Standard_False);
162 Handle(BRepMesh_DataStructureOfDelaun) aStructure =
163 new BRepMesh_DataStructureOfDelaun(aAllocator);
165 const Standard_Real aTolU = myAttribute->ToleranceU();
166 const Standard_Real aTolV = myAttribute->ToleranceV();
167 const Standard_Real uCellSize = 14.0 * aTolU;
168 const Standard_Real vCellSize = 14.0 * aTolV;
170 aStructure->Data()->SetCellSize ( uCellSize, vCellSize);
171 aStructure->Data()->SetTolerance( aTolU , aTolV );
173 myAttribute->ChangeStructure() = aStructure;
176 //=======================================================================
177 //function : Add(face)
179 //=======================================================================
180 Standard_Integer BRepMesh_FastDiscret::Add(const TopoDS_Face& theFace)
182 myAttribute.Nullify();
183 GetFaceAttribute(theFace, myAttribute, Standard_True);
189 // Initialize face attributes
190 if (!myAttribute->IsInitialized ())
191 myAttribute->SetFace (theFace, myParameters.AdaptiveMin);
193 BRepMesh::HIMapOfInteger& aVertexEdgeMap = myAttribute->ChangeVertexEdgeMap();
194 BRepMesh::HDMapOfShapePairOfPolygon& aInternalEdges = myAttribute->ChangeInternalEdges();
196 resetDataStructure();
198 Standard_Real defedge;
199 Standard_Integer nbEdge = 0;
200 Standard_Real savangle = myParameters.Angle;
202 Standard_Real maxdef = 2.* BRepMesh_ShapeTool::MaxFaceTolerance(theFace);
204 Standard_Real defface = 0.;
205 if (!myParameters.Relative)
206 defface = Max(myParameters.Deflection, maxdef);
208 NCollection_Sequence<EdgePCurve> aPCurves;
209 NCollection_Sequence<TopoDS_Edge> aFaceEdges;
211 const TopoDS_Face& aFace = myAttribute->Face();
212 const Handle(BRepAdaptor_HSurface)& gFace = myAttribute->Surface();
213 TopExp_Explorer aWireIt(aFace, TopAbs_WIRE);
214 for (; aWireIt.More(); aWireIt.Next())
216 TopExp_Explorer aEdgeIt(aWireIt.Current(), TopAbs_EDGE);
217 for (; aEdgeIt.More(); aEdgeIt.Next(), ++nbEdge)
219 const TopoDS_Edge& aEdge = TopoDS::Edge(aEdgeIt.Current());
220 if (!myMapdefle.IsBound(aEdge))
222 if (myParameters.Relative)
224 if (myEdges.IsBound(aEdge))
226 const BRepMesh_PairOfPolygon& aPair = myEdges.Find(aEdge);
227 const Handle(Poly_PolygonOnTriangulation)& aPolygon = aPair.First();
228 defedge = aPolygon->Deflection();
232 defedge = BRepMesh_ShapeTool::RelativeEdgeDeflection(
233 aEdge, myParameters.Deflection, myDtotale, cdef);
235 myParameters.Angle = savangle * cdef;
239 defface = Max(maxdef, defface);
243 defedge = myParameters.Deflection;
246 defedge = Max(maxdef, defedge);
247 defedge = Max(UVDEFLECTION, defedge);
248 myMapdefle.Bind(aEdge, defedge);
252 defedge = myMapdefle(aEdge);
253 if ( myParameters.Relative )
256 defface = Max(maxdef, defface);
260 Standard_Real aFirstParam, aLastParam;
261 Handle(Geom2d_Curve) aCurve2d =
262 BRep_Tool::CurveOnSurface(aEdge, aFace, aFirstParam, aLastParam);
264 if (aCurve2d.IsNull())
267 EdgePCurve aPCurve = { aCurve2d, aFirstParam, aLastParam };
268 aPCurves.Append(aPCurve);
269 aFaceEdges.Append(aEdge);
271 add(aEdge, aPCurve, defedge);
272 myParameters.Angle = savangle;
276 if ( nbEdge == 0 || aVertexEdgeMap->Extent() < 3 )
278 myAttribute->ChangeStructure().Nullify();
279 myAttribute->SetStatus(BRepMesh_Failure);
280 return myAttribute->GetStatus();
283 if ( myParameters.Relative )
285 defface = defface / nbEdge;
289 defface = myParameters.Deflection;
292 defface = Max(maxdef, defface);
294 TopLoc_Location aLoc;
295 Handle(Poly_Triangulation) aTriangulation = BRep_Tool::Triangulation(aFace, aLoc);
297 if ( aTriangulation.IsNull() )
299 Standard_Real xCur, yCur;
300 Standard_Real maxX, minX, maxY, minY;
302 minX = minY = 1.e100;
303 maxX = maxY =-1.e100;
305 Standard_Integer ipn = 0;
306 Standard_Integer i1 = 1;
307 for ( i1 = 1; i1 <= aVertexEdgeMap->Extent(); ++i1 )
309 const BRepMesh_Vertex& aVertex =
310 myAttribute->ChangeStructure()->GetNode(aVertexEdgeMap->FindKey(i1));
314 xCur = aVertex.Coord().X();
315 yCur = aVertex.Coord().Y();
317 minX = Min(xCur, minX);
318 maxX = Max(xCur, maxX);
319 minY = Min(yCur, minY);
320 maxY = Max(yCur, maxY);
323 Standard_Real myumin = minX;
324 Standard_Real myumax = maxX;
325 Standard_Real myvmin = minY;
326 Standard_Real myvmax = maxY;
328 const Standard_Real umin = gFace->FirstUParameter();
329 const Standard_Real umax = gFace->LastUParameter();
330 const Standard_Real vmin = gFace->FirstVParameter();
331 const Standard_Real vmax = gFace->LastVParameter();
333 if (myumin < umin || myumax > umax)
335 if (gFace->IsUPeriodic())
337 if ((myumax - myumin) > (umax - umin))
338 myumax = myumin + (umax - umin);
350 if (myvmin < vmin || myvmax > vmax)
352 if (gFace->IsVPeriodic())
354 if ((myvmax - myvmin) > (vmax - vmin))
355 myvmax = myvmin + (vmax - vmin);
367 GeomAbs_SurfaceType aSurfType = gFace->GetType();
368 // Fast verification of the validity of calculated limits.
369 // If wrong, sure a problem of pcurve.
370 if (aSurfType == GeomAbs_BezierSurface &&
371 (myumin < -0.5 || myumax > 1.5 || myvmin < -0.5 || myvmax > 1.5) )
373 myAttribute->ChangeStructure().Nullify();
374 myAttribute->SetStatus(BRepMesh_Failure);
375 return myAttribute->GetStatus();
378 //define parameters for correct parametrics
379 Standard_Real deltaX = 1.0;
380 Standard_Real deltaY = 1.0;
383 Standard_Real aTolU, aTolV;
384 myAttribute->ChangeStructure()->Data()->GetTolerance(aTolU, aTolV);
385 const Standard_Real aTol = Sqrt(aTolU * aTolU + aTolV * aTolV);
387 BRepMesh::HClassifier& aClassifier = myAttribute->ChangeClassifier();
388 BRepMesh_WireChecker aDFaceChecker(aFace, aTol, aInternalEdges,
389 aVertexEdgeMap, myAttribute->ChangeStructure(),
390 myumin, myumax, myvmin, myvmax, myParameters.InParallel );
392 aDFaceChecker.ReCompute(aClassifier);
393 BRepMesh_Status aCheckStatus = aDFaceChecker.Status();
395 if (aCheckStatus == BRepMesh_SelfIntersectingWire)
397 Standard_Integer nbmaill = 0;
398 Standard_Real eps = Precision::Confusion();
399 while (nbmaill < 5 && aCheckStatus != BRepMesh_ReMesh)
403 resetDataStructure();
404 for (Standard_Integer j = 1; j <= aFaceEdges.Length(); ++j)
406 const TopoDS_Edge& anEdge = aFaceEdges(j);
407 if (myEdges.IsBound(anEdge))
408 myEdges.UnBind(anEdge);
410 defedge = Max(myMapdefle(anEdge) / 3.0, eps);
411 myMapdefle.Bind(anEdge, defedge);
413 add(anEdge, aPCurves(j), defedge);
416 aDFaceChecker.ReCompute(aClassifier);
417 if (aDFaceChecker.Status() == BRepMesh_NoError)
418 aCheckStatus = BRepMesh_ReMesh;
422 myAttribute->SetStatus(aCheckStatus);
423 if (!myAttribute->IsValid())
425 myAttribute->ChangeStructure().Nullify();
426 return myAttribute->GetStatus();
430 // try to find the real length:
431 // akm (bug OCC16) : We must calculate these measures in non-singular
432 // parts of face. Let's try to compute average value of three
433 // (umin, (umin+umax)/2, umax), and respectively for v.
435 Standard_Real longu = 0.0, longv = 0.0; //, last , first;
436 gp_Pnt P11, P12, P21, P22, P31, P32;
438 Standard_Real du = 0.05 * ( myumax - myumin );
439 Standard_Real dv = 0.05 * ( myvmax - myvmin );
440 Standard_Real dfuave = 0.5 * ( myumin + myumax );
441 Standard_Real dfvave = 0.5 * ( myvmin + myvmax );
442 Standard_Real dfucur, dfvcur;
445 gFace->D0(myumin, myvmin, P11);
446 gFace->D0(myumin, dfvave, P21);
447 gFace->D0(myumin, myvmax, P31);
448 for (i1=1, dfucur=myumin+du; i1 <= 20; i1++, dfucur+=du)
450 gFace->D0(dfucur, myvmin, P12);
451 gFace->D0(dfucur, dfvave, P22);
452 gFace->D0(dfucur, myvmax, P32);
453 longu += ( P11.Distance(P12) + P21.Distance(P22) + P31.Distance(P32) );
460 gFace->D0(myumin, myvmin, P11);
461 gFace->D0(dfuave, myvmin, P21);
462 gFace->D0(myumax, myvmin, P31);
463 for (i1=1, dfvcur=myvmin+dv; i1 <= 20; i1++, dfvcur+=dv)
465 gFace->D0(myumin, dfvcur, P12);
466 gFace->D0(dfuave, dfvcur, P22);
467 gFace->D0(myumax, dfvcur, P32);
468 longv += ( P11.Distance(P12) + P21.Distance(P22) + P31.Distance(P32) );
476 // akm (bug OCC16) ^^^^^
478 if (longu <= 1.e-16 || longv <= 1.e-16)
481 myAttribute->ChangeStructure().Nullify();
482 myAttribute->SetStatus(BRepMesh_Failure);
483 return myAttribute->GetStatus();
487 if (aSurfType == GeomAbs_Torus)
489 gp_Torus Tor = gFace->Torus();
490 Standard_Real r = Tor.MinorRadius(), R = Tor.MajorRadius();
491 Standard_Real Du, Dv;//, pasu, pasv;
493 Dv = Max(1.0e0 - (defface/r),0.0e0) ;
494 Standard_Real oldDv = 2.0 * ACos (Dv);
495 oldDv = Min(oldDv, myParameters.Angle);
496 Dv = 0.9*oldDv; //TWOTHIRD * oldDv;
499 Standard_Integer nbV = Max((Standard_Integer)((myvmax-myvmin)/Dv), 2);
500 Dv = (myvmax-myvmin)/(nbV+1);
502 Standard_Real ru = R + r;
505 Du = Max(1.0e0 - (defface/ru),0.0e0);
506 Du = (2.0 * ACos (Du));
507 Du = Min(Du, myParameters.Angle);
508 Standard_Real aa = sqrt(Du*Du + oldDv*oldDv);
510 if (aa < gp::Resolution())
512 myAttribute->ChangeStructure().Nullify();
513 return myAttribute->GetStatus();
516 Du = Du * Min(oldDv, Du) / aa;
523 Standard_Integer nbU = Max((Standard_Integer)((myumax-myumin)/Du), 2);
524 nbU = Max(nbU, (Standard_Integer)(nbV*(myumax-myumin)*R/((myvmax-myvmin)*r)/5.));
526 Du = (myumax-myumin)/(nbU+1);
527 //-- DeltaX and DeltaY are chosen so that to avoid "jumping"
528 //-- of points on the grid
532 else if (aSurfType == GeomAbs_Cylinder)
534 gp_Cylinder Cyl = gFace->Cylinder();
535 Standard_Real R = Cyl.Radius();
537 // Calculate parameters for iteration in U direction
538 Standard_Real Du = 1.0 - (defface/R);
542 Du = 2.0 * ACos (Du);
543 if (Du > myParameters.Angle)
544 Du = myParameters.Angle;
551 deltaX = (myumax-myumin)/longu;
552 deltaY = (myvmax-myvmin)/longv;
555 // Restore face attribute
556 myAttribute->SetDefFace(defface);
557 myAttribute->SetUMax(myumax);
558 myAttribute->SetVMax(myvmax);
559 myAttribute->SetUMin(myumin);
560 myAttribute->SetVMin(myvmin);
561 myAttribute->SetDeltaX(deltaX);
562 myAttribute->SetDeltaY(deltaY);
565 myAttribute->ChangeMeshNodes() =
566 myAttribute->ChangeStructure()->Data()->Vertices();
568 catch(Standard_Failure)
570 myAttribute->SetStatus(BRepMesh_Failure);
573 myAttribute->ChangeStructure().Nullify();
574 return myAttribute->GetStatus();
577 //=======================================================================
578 //function : getEdgeAttributes
580 //=======================================================================
581 Standard_Boolean BRepMesh_FastDiscret::getEdgeAttributes(
582 const TopoDS_Edge& theEdge,
583 const BRepMesh_FastDiscret::EdgePCurve& thePCurve,
584 const Standard_Real theDefEdge,
585 BRepMesh_FastDiscret::EdgeAttributes& theAttributes) const
587 EdgeAttributes& aEAttr = theAttributes;
590 TopExp::Vertices(theEdge, aEAttr.FirstVertex, aEAttr.LastVertex);
591 if (aEAttr.FirstVertex.IsNull() || aEAttr.LastVertex.IsNull())
592 return Standard_False;
594 // Get range on 2d curve
595 const TopoDS_Face& aFace = myAttribute->Face();
596 BRep_Tool::Range(theEdge, aFace, aEAttr.FirstParam, aEAttr.LastParam);
598 // Get end points on 2d curve
599 BRep_Tool::UVPoints(theEdge, aFace, aEAttr.FirstUV, aEAttr.LastUV);
602 aEAttr.FirstUV.IsEqual(aEAttr.LastUV, Precision::PConfusion());
604 //Control tolerance of vertices
605 const Handle(BRepAdaptor_HSurface)& gFace = myAttribute->Surface();
606 gp_Pnt pFirst = gFace->Value(aEAttr.FirstUV.X(), aEAttr.FirstUV.Y());
607 gp_Pnt pLast = gFace->Value(aEAttr.LastUV.X(), aEAttr.LastUV.Y());
609 aEAttr.MinDist = 10. * Max(pFirst.Distance(BRep_Tool::Pnt(aEAttr.FirstVertex)),
610 pLast .Distance(BRep_Tool::Pnt(aEAttr.LastVertex)));
612 if (aEAttr.MinDist < BRep_Tool::Tolerance(aEAttr.FirstVertex) ||
613 aEAttr.MinDist < BRep_Tool::Tolerance(aEAttr.LastVertex))
615 aEAttr.MinDist = theDefEdge;
620 // 1. is it really sameUV without being degenerated
622 thePCurve.Curve2d->D0(thePCurve.FirstParam, uvF);
623 thePCurve.Curve2d->D0(thePCurve.LastParam, uvL);
625 if (!aEAttr.FirstUV.IsEqual(uvF, Precision::PConfusion()))
626 aEAttr.FirstUV = uvF;
628 if (!aEAttr.LastUV.IsEqual(uvL, Precision::PConfusion()))
632 return Standard_True;
635 //=======================================================================
636 //function : registerEdgeVertices
638 //=======================================================================
639 void BRepMesh_FastDiscret::registerEdgeVertices(
640 BRepMesh_FastDiscret::EdgeAttributes& theAttributes,
641 Standard_Integer& ipf,
642 Standard_Integer& ivf,
643 Standard_Integer& isvf,
644 Standard_Integer& ipl,
645 Standard_Integer& ivl,
646 Standard_Integer& isvl)
648 EdgeAttributes& aEAttr = theAttributes;
649 if (aEAttr.FirstVExtractor.IsNull())
651 // Use edge geometry to produce tesselation.
652 aEAttr.FirstVExtractor =
653 new TopoDSVExplorer(aEAttr.FirstVertex, aEAttr.IsSameUV, aEAttr.LastVertex);
656 if (aEAttr.LastVExtractor.IsNull())
658 // Use edge geometry to produce tesselation.
659 aEAttr.LastVExtractor =
660 new TopoDSVExplorer(aEAttr.LastVertex, aEAttr.IsSameUV, aEAttr.FirstVertex);
664 // Process first vertex
665 ipf = myAttribute->GetVertexIndex(aEAttr.FirstVExtractor, Standard_True);
666 aTmpUV = BRepMesh_ShapeTool::FindUV(ipf, aEAttr.FirstUV, aEAttr.FirstVertex,
667 aEAttr.MinDist, myAttribute);
669 myAttribute->AddNode(ipf, aTmpUV, BRepMesh_Frontier, ivf, isvf);
671 // Process last vertex
672 ipl = aEAttr.LastVertex.IsSame(aEAttr.FirstVertex) ? ipf :
673 myAttribute->GetVertexIndex(aEAttr.LastVExtractor, Standard_True);
674 aTmpUV = BRepMesh_ShapeTool::FindUV(ipl, aEAttr.LastUV, aEAttr.LastVertex,
675 aEAttr.MinDist, myAttribute);
677 myAttribute->AddNode(ipl, aTmpUV, BRepMesh_Frontier, ivl, isvl);
680 //=======================================================================
683 //=======================================================================
684 void BRepMesh_FastDiscret::add(
685 const TopoDS_Edge& theEdge,
686 const BRepMesh_FastDiscret::EdgePCurve& thePCurve,
687 const Standard_Real theDefEdge)
689 const TopAbs_Orientation orEdge = theEdge.Orientation();
690 if (orEdge == TopAbs_EXTERNAL)
693 EdgeAttributes aEAttr;
694 if (!getEdgeAttributes(theEdge, thePCurve, theDefEdge, aEAttr))
697 if (!myEdges.IsBound(theEdge))
699 update(theEdge, thePCurve.Curve2d, theDefEdge, aEAttr);
703 Standard_Integer ipf, ivf, isvf, ipl, ivl, isvl;
704 registerEdgeVertices(aEAttr, ipf, ivf, isvf, ipl, ivl, isvl);
706 // If this Edge has been already checked and it is not degenerated,
707 // the points of the polygon calculated at the first check are retrieved :
709 // retrieve the polygone:
710 const BRepMesh_PairOfPolygon& aPair = myEdges.Find(theEdge);
711 const Handle(Poly_PolygonOnTriangulation)& aPolygon = aPair.First();
712 const TColStd_Array1OfInteger& aNodes = aPolygon->Nodes();
713 Handle(TColStd_HArray1OfReal) aParams = aPolygon->Parameters();
716 const Standard_Integer aNodesNb = aNodes.Length();
717 TColStd_Array1OfInteger aNewNodes (1, aNodesNb);
718 TColStd_Array1OfReal aNewParams(1, aNodesNb);
720 aNewNodes (1) = isvf;
721 aNewParams(1) = aEAttr.FirstParam;
723 aNewNodes (aNodesNb) = isvl;
724 aNewParams(aNodesNb) = aEAttr.LastParam;
726 const TopoDS_Face& aFace = myAttribute->Face();
727 if (!BRepMesh_ShapeTool::IsDegenerated(theEdge, aFace))
729 BRepMesh_EdgeParameterProvider aProvider(theEdge, aFace, aParams);
730 for (Standard_Integer i = 2; i < aNodesNb; ++i)
732 const Standard_Integer aPointId = aNodes(i);
733 const gp_Pnt& aPnt = myBoundaryPoints->Find(aPointId);
735 const Standard_Real aParam = aProvider.Parameter(i, aPnt);
736 gp_Pnt2d aUV = thePCurve.Curve2d->Value(aParam);
738 Standard_Integer iv2, isv;
739 myAttribute->AddNode(aPointId, aUV.Coord(), BRepMesh_OnCurve, iv2, isv);
742 aNewParams(i) = aParam;
746 Handle(Poly_PolygonOnTriangulation) P1 =
747 new Poly_PolygonOnTriangulation(aNewNodes, aNewParams);
749 storePolygon(theEdge, P1, theDefEdge);
752 //=======================================================================
753 //function : update(edge)
755 //=======================================================================
756 void BRepMesh_FastDiscret::update(
757 const TopoDS_Edge& theEdge,
758 const Handle(Geom2d_Curve)& theC2d,
759 const Standard_Real theDefEdge,
760 BRepMesh_FastDiscret::EdgeAttributes& theAttributes)
762 EdgeAttributes& aEAttr = theAttributes;
764 const TopoDS_Face& aFace = myAttribute->Face();
765 Handle(BRepMesh_IEdgeTool) aEdgeTool;
766 // Try to find existing tessellation.
767 for (Standard_Integer i = 1; aEdgeTool.IsNull(); ++i)
769 TopLoc_Location aLoc;
770 Handle(Poly_Triangulation) aTriangulation;
771 Handle(Poly_PolygonOnTriangulation) aPolygon;
772 BRep_Tool::PolygonOnTriangulation(theEdge, aPolygon, aTriangulation, aLoc, i);
774 if (aPolygon.IsNull())
777 if (aTriangulation.IsNull() || !aPolygon->HasParameters())
780 if (aPolygon->Deflection() > 1.1 * theDefEdge)
783 const TColgp_Array1OfPnt& aNodes = aTriangulation->Nodes();
784 const TColStd_Array1OfInteger& aIndices = aPolygon->Nodes();
785 Handle(TColStd_HArray1OfReal) aParams = aPolygon->Parameters();
787 aEAttr.FirstVExtractor = new PolyVExplorer(aEAttr.FirstVertex,
788 aEAttr.IsSameUV, aEAttr.LastVertex, aIndices(1), aNodes, aLoc);
790 aEAttr.LastVExtractor = new PolyVExplorer(aEAttr.LastVertex,
791 aEAttr.IsSameUV, aEAttr.FirstVertex, aIndices(aIndices.Length()), aNodes, aLoc);
793 aEdgeTool = new BRepMesh_EdgeTessellationExtractor(theEdge, theC2d,
794 aFace, aTriangulation, aPolygon, aLoc);
797 if (aEdgeTool.IsNull())
799 aEdgeTool = new BRepMesh_EdgeTessellator(theEdge, myAttribute,
800 mySharedFaces, theDefEdge, myParameters.Angle, myParameters.MinSize);
803 Standard_Integer ipf, ivf, isvf, ipl, ivl, isvl;
804 registerEdgeVertices(aEAttr, ipf, ivf, isvf, ipl, ivl, isvl);
806 Handle(Poly_PolygonOnTriangulation) P1, P2;
807 if (BRepMesh_ShapeTool::IsDegenerated(theEdge, aFace))
809 const Standard_Integer aNodesNb = 2;
810 TColStd_Array1OfInteger aNewNodes (1, aNodesNb);
811 TColStd_Array1OfInteger aNewNodInStruct(1, aNodesNb);
812 TColStd_Array1OfReal aNewParams (1, aNodesNb);
814 aNewNodInStruct(1) = ipf;
815 aNewNodes (1) = isvf;
816 aNewParams (1) = aEAttr.FirstParam;
818 aNewNodInStruct(aNodesNb) = ipl;
819 aNewNodes (aNodesNb) = isvl;
820 aNewParams (aNodesNb) = aEAttr.LastParam;
822 P1 = new Poly_PolygonOnTriangulation(aNewNodes, aNewParams);
823 P2 = new Poly_PolygonOnTriangulation(aNewNodInStruct, aNewParams);
827 const Standard_Integer aNodesNb = aEdgeTool->NbPoints();
828 TColStd_Array1OfInteger aNewNodesVec (1, aNodesNb);
829 TColStd_Array1OfInteger aNewNodesInStructVec(1, aNodesNb);
830 TColStd_Array1OfReal aNewParamsVec (1, aNodesNb);
832 Standard_Integer aNodesCount = 1;
833 aNewNodesInStructVec(aNodesCount) = ipf;
834 aNewNodesVec (aNodesCount) = isvf;
835 aNewParamsVec (aNodesCount) = aEAttr.FirstParam;
838 Standard_Integer aLastPointId = myAttribute->LastPointId();
839 for (Standard_Integer i = 2; i < aNodesNb; ++i)
843 Standard_Real aParam;
844 if (!aEdgeTool->Value(i, aParam, aPnt, aUV))
847 myBoundaryPoints->Bind(++aLastPointId, aPnt);
849 Standard_Integer iv2, isv;
850 myAttribute->AddNode(aLastPointId, aUV.Coord(), BRepMesh_Frontier, iv2, isv);
852 aNewNodesInStructVec(aNodesCount) = aLastPointId;
853 aNewNodesVec (aNodesCount) = isv;
854 aNewParamsVec (aNodesCount) = aParam;
858 aNewNodesInStructVec(aNodesCount) = ipl;
859 aNewNodesVec (aNodesCount) = isvl;
860 aNewParamsVec (aNodesCount) = aEAttr.LastParam;
862 TColStd_Array1OfInteger aNewNodes (aNewNodesVec.First (), 1, aNodesCount);
863 TColStd_Array1OfInteger aNewNodInStruct(aNewNodesInStructVec.First(), 1, aNodesCount);
864 TColStd_Array1OfReal aNewParams (aNewParamsVec.First(), 1, aNodesCount);
866 P1 = new Poly_PolygonOnTriangulation(aNewNodes, aNewParams);
867 P2 = new Poly_PolygonOnTriangulation(aNewNodInStruct, aNewParams);
870 storePolygon(theEdge, P1, theDefEdge);
871 storePolygonSharedData(theEdge, P2, theDefEdge);
874 //=======================================================================
875 //function : storeInternalPolygon
877 //=======================================================================
878 void BRepMesh_FastDiscret::storePolygon(
879 const TopoDS_Edge& theEdge,
880 Handle(Poly_PolygonOnTriangulation)& thePolygon,
881 const Standard_Real theDeflection)
883 thePolygon->Deflection(theDeflection);
884 BRepMesh::HDMapOfShapePairOfPolygon& aInternalEdges = myAttribute->ChangeInternalEdges();
885 if (aInternalEdges->IsBound(theEdge))
887 BRepMesh_PairOfPolygon& aPair = aInternalEdges->ChangeFind(theEdge);
888 if (theEdge.Orientation() == TopAbs_REVERSED)
889 aPair.Append(thePolygon);
891 aPair.Prepend(thePolygon);
896 BRepMesh_PairOfPolygon aPair;
897 aPair.Append(thePolygon);
898 aInternalEdges->Bind(theEdge, aPair);
901 //=======================================================================
902 //function : storePolygonSharedData
904 //=======================================================================
905 void BRepMesh_FastDiscret::storePolygonSharedData(
906 const TopoDS_Edge& theEdge,
907 Handle(Poly_PolygonOnTriangulation)& thePolygon,
908 const Standard_Real theDeflection)
910 thePolygon->Deflection(theDeflection);
911 BRepMesh_PairOfPolygon aPair;
912 aPair.Append(thePolygon);
913 myEdges.Bind(theEdge, aPair);
916 //=======================================================================
917 //function : GetFaceAttribute
919 //=======================================================================
920 Standard_Boolean BRepMesh_FastDiscret::GetFaceAttribute(
921 const TopoDS_Face& theFace,
922 Handle(BRepMesh_FaceAttribute)& theAttribute,
923 const Standard_Boolean isForceCreate) const
925 if (myAttributes.IsBound(theFace))
927 theAttribute = myAttributes(theFace);
928 return Standard_True;
930 else if (isForceCreate)
932 theAttribute = new BRepMesh_FaceAttribute(myBoundaryVertices, myBoundaryPoints);
933 myAttributes.Bind(theFace, theAttribute);
936 return Standard_False;
939 //=======================================================================
940 //function : RemoveFaceAttribute
942 //=======================================================================
943 void BRepMesh_FastDiscret::RemoveFaceAttribute(const TopoDS_Face& theFace)
945 if (myAttributes.IsBound(theFace))
946 myAttributes.UnBind(theFace);