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)
186 // Initialize face attributes
187 myAttribute.Nullify();
188 GetFaceAttribute(theFace, myAttribute);
189 if (myAttribute.IsNull())
191 myAttribute = new BRepMesh_FaceAttribute(theFace,
192 myBoundaryVertices, myBoundaryPoints,myParameters.AdaptiveMin);
194 myAttributes.Bind(theFace, myAttribute);
197 BRepMesh::HIMapOfInteger& aVertexEdgeMap = myAttribute->ChangeVertexEdgeMap();
198 BRepMesh::HDMapOfShapePairOfPolygon& aInternalEdges = myAttribute->ChangeInternalEdges();
200 resetDataStructure();
202 Standard_Real defedge;
203 Standard_Integer nbEdge = 0;
204 Standard_Real savangle = myParameters.Angle;
206 Standard_Real maxdef = 2.* BRepMesh_ShapeTool::MaxFaceTolerance(theFace);
208 Standard_Real defface = 0.;
209 if (!myParameters.Relative)
210 defface = Max(myParameters.Deflection, maxdef);
212 NCollection_Sequence<EdgePCurve> aPCurves;
213 NCollection_Sequence<TopoDS_Edge> aFaceEdges;
215 const TopoDS_Face& aFace = myAttribute->Face();
216 const Handle(BRepAdaptor_HSurface)& gFace = myAttribute->Surface();
217 TopExp_Explorer aWireIt(aFace, TopAbs_WIRE);
218 for (; aWireIt.More(); aWireIt.Next())
220 TopExp_Explorer aEdgeIt(aWireIt.Current(), TopAbs_EDGE);
221 for (; aEdgeIt.More(); aEdgeIt.Next(), ++nbEdge)
223 const TopoDS_Edge& aEdge = TopoDS::Edge(aEdgeIt.Current());
224 if (!myMapdefle.IsBound(aEdge))
226 if (myParameters.Relative)
228 if (myEdges.IsBound(aEdge))
230 const BRepMesh_PairOfPolygon& aPair = myEdges.Find(aEdge);
231 const Handle(Poly_PolygonOnTriangulation)& aPolygon = aPair.First();
232 defedge = aPolygon->Deflection();
236 defedge = BRepMesh_ShapeTool::RelativeEdgeDeflection(
237 aEdge, myParameters.Deflection, myDtotale, cdef);
239 myParameters.Angle = savangle * cdef;
243 defface = Max(maxdef, defface);
247 defedge = myParameters.Deflection;
250 defedge = Max(maxdef, defedge);
251 defedge = Max(UVDEFLECTION, defedge);
252 myMapdefle.Bind(aEdge, defedge);
256 defedge = myMapdefle(aEdge);
257 if ( myParameters.Relative )
260 defface = Max(maxdef, defface);
264 Standard_Real aFirstParam, aLastParam;
265 Handle(Geom2d_Curve) aCurve2d =
266 BRep_Tool::CurveOnSurface(aEdge, aFace, aFirstParam, aLastParam);
268 if (aCurve2d.IsNull())
271 EdgePCurve aPCurve = { aCurve2d, aFirstParam, aLastParam };
272 aPCurves.Append(aPCurve);
273 aFaceEdges.Append(aEdge);
275 add(aEdge, aPCurve, defedge);
276 myParameters.Angle = savangle;
280 if ( nbEdge == 0 || aVertexEdgeMap->Extent() < 3 )
282 myAttribute->ChangeStructure().Nullify();
283 myAttribute->SetStatus(BRepMesh_Failure);
284 return myAttribute->GetStatus();
287 if ( myParameters.Relative )
289 defface = defface / nbEdge;
293 defface = myParameters.Deflection;
296 defface = Max(maxdef, defface);
298 TopLoc_Location aLoc;
299 Handle(Poly_Triangulation) aTriangulation = BRep_Tool::Triangulation(aFace, aLoc);
301 if ( aTriangulation.IsNull() )
303 Standard_Real xCur, yCur;
304 Standard_Real maxX, minX, maxY, minY;
306 minX = minY = 1.e100;
307 maxX = maxY =-1.e100;
309 Standard_Integer ipn = 0;
310 Standard_Integer i1 = 1;
311 for ( i1 = 1; i1 <= aVertexEdgeMap->Extent(); ++i1 )
313 const BRepMesh_Vertex& aVertex =
314 myAttribute->ChangeStructure()->GetNode(aVertexEdgeMap->FindKey(i1));
318 xCur = aVertex.Coord().X();
319 yCur = aVertex.Coord().Y();
321 minX = Min(xCur, minX);
322 maxX = Max(xCur, maxX);
323 minY = Min(yCur, minY);
324 maxY = Max(yCur, maxY);
327 Standard_Real myumin = minX;
328 Standard_Real myumax = maxX;
329 Standard_Real myvmin = minY;
330 Standard_Real myvmax = maxY;
332 const Standard_Real umin = gFace->FirstUParameter();
333 const Standard_Real umax = gFace->LastUParameter();
334 const Standard_Real vmin = gFace->FirstVParameter();
335 const Standard_Real vmax = gFace->LastVParameter();
337 if (myumin < umin || myumax > umax)
339 if (gFace->IsUPeriodic())
341 if ((myumax - myumin) > (umax - umin))
342 myumax = myumin + (umax - umin);
354 if (myvmin < vmin || myvmax > vmax)
356 if (gFace->IsVPeriodic())
358 if ((myvmax - myvmin) > (vmax - vmin))
359 myvmax = myvmin + (vmax - vmin);
371 GeomAbs_SurfaceType aSurfType = gFace->GetType();
372 // Fast verification of the validity of calculated limits.
373 // If wrong, sure a problem of pcurve.
374 if (aSurfType == GeomAbs_BezierSurface &&
375 (myumin < -0.5 || myumax > 1.5 || myvmin < -0.5 || myvmax > 1.5) )
377 myAttribute->ChangeStructure().Nullify();
378 myAttribute->SetStatus(BRepMesh_Failure);
379 return myAttribute->GetStatus();
382 //define parameters for correct parametrics
383 Standard_Real deltaX = 1.0;
384 Standard_Real deltaY = 1.0;
387 Standard_Real aTolU, aTolV;
388 myAttribute->ChangeStructure()->Data()->GetTolerance(aTolU, aTolV);
389 const Standard_Real aTol = Sqrt(aTolU * aTolU + aTolV * aTolV);
391 BRepMesh::HClassifier& aClassifier = myAttribute->ChangeClassifier();
392 BRepMesh_WireChecker aDFaceChecker(aFace, aTol, aInternalEdges,
393 aVertexEdgeMap, myAttribute->ChangeStructure(),
394 myumin, myumax, myvmin, myvmax, myParameters.InParallel );
396 aDFaceChecker.ReCompute(aClassifier);
397 BRepMesh_Status aCheckStatus = aDFaceChecker.Status();
399 if (aCheckStatus == BRepMesh_SelfIntersectingWire)
401 Standard_Integer nbmaill = 0;
402 Standard_Real eps = Precision::Confusion();
403 while (nbmaill < 5 && aCheckStatus != BRepMesh_ReMesh)
407 resetDataStructure();
408 for (Standard_Integer j = 1; j <= aFaceEdges.Length(); ++j)
410 const TopoDS_Edge& anEdge = aFaceEdges(j);
411 if (myEdges.IsBound(anEdge))
412 myEdges.UnBind(anEdge);
414 defedge = Max(myMapdefle(anEdge) / 3.0, eps);
415 myMapdefle.Bind(anEdge, defedge);
417 add(anEdge, aPCurves(j), defedge);
420 aDFaceChecker.ReCompute(aClassifier);
421 if (aDFaceChecker.Status() == BRepMesh_NoError)
422 aCheckStatus = BRepMesh_ReMesh;
426 myAttribute->SetStatus(aCheckStatus);
427 if (!myAttribute->IsValid())
429 myAttribute->ChangeStructure().Nullify();
430 return myAttribute->GetStatus();
434 // try to find the real length:
435 // akm (bug OCC16) : We must calculate these measures in non-singular
436 // parts of face. Let's try to compute average value of three
437 // (umin, (umin+umax)/2, umax), and respectively for v.
439 Standard_Real longu = 0.0, longv = 0.0; //, last , first;
440 gp_Pnt P11, P12, P21, P22, P31, P32;
442 Standard_Real du = 0.05 * ( myumax - myumin );
443 Standard_Real dv = 0.05 * ( myvmax - myvmin );
444 Standard_Real dfuave = 0.5 * ( myumin + myumax );
445 Standard_Real dfvave = 0.5 * ( myvmin + myvmax );
446 Standard_Real dfucur, dfvcur;
449 gFace->D0(myumin, myvmin, P11);
450 gFace->D0(myumin, dfvave, P21);
451 gFace->D0(myumin, myvmax, P31);
452 for (i1=1, dfucur=myumin+du; i1 <= 20; i1++, dfucur+=du)
454 gFace->D0(dfucur, myvmin, P12);
455 gFace->D0(dfucur, dfvave, P22);
456 gFace->D0(dfucur, myvmax, P32);
457 longu += ( P11.Distance(P12) + P21.Distance(P22) + P31.Distance(P32) );
464 gFace->D0(myumin, myvmin, P11);
465 gFace->D0(dfuave, myvmin, P21);
466 gFace->D0(myumax, myvmin, P31);
467 for (i1=1, dfvcur=myvmin+dv; i1 <= 20; i1++, dfvcur+=dv)
469 gFace->D0(myumin, dfvcur, P12);
470 gFace->D0(dfuave, dfvcur, P22);
471 gFace->D0(myumax, dfvcur, P32);
472 longv += ( P11.Distance(P12) + P21.Distance(P22) + P31.Distance(P32) );
480 // akm (bug OCC16) ^^^^^
482 if (longu <= 1.e-16 || longv <= 1.e-16)
485 myAttribute->ChangeStructure().Nullify();
486 myAttribute->SetStatus(BRepMesh_Failure);
487 return myAttribute->GetStatus();
491 if (aSurfType == GeomAbs_Torus)
493 gp_Torus Tor = gFace->Torus();
494 Standard_Real r = Tor.MinorRadius(), R = Tor.MajorRadius();
495 Standard_Real Du, Dv;//, pasu, pasv;
497 Dv = Max(1.0e0 - (defface/r),0.0e0) ;
498 Standard_Real oldDv = 2.0 * ACos (Dv);
499 oldDv = Min(oldDv, myParameters.Angle);
500 Dv = 0.9*oldDv; //TWOTHIRD * oldDv;
503 Standard_Integer nbV = Max((Standard_Integer)((myvmax-myvmin)/Dv), 2);
504 Dv = (myvmax-myvmin)/(nbV+1);
506 Standard_Real ru = R + r;
509 Du = Max(1.0e0 - (defface/ru),0.0e0);
510 Du = (2.0 * ACos (Du));
511 Du = Min(Du, myParameters.Angle);
512 Standard_Real aa = sqrt(Du*Du + oldDv*oldDv);
514 if (aa < gp::Resolution())
516 myAttribute->ChangeStructure().Nullify();
517 return myAttribute->GetStatus();
520 Du = Du * Min(oldDv, Du) / aa;
527 Standard_Integer nbU = Max((Standard_Integer)((myumax-myumin)/Du), 2);
528 nbU = Max(nbU, (Standard_Integer)(nbV*(myumax-myumin)*R/((myvmax-myvmin)*r)/5.));
530 Du = (myumax-myumin)/(nbU+1);
531 //-- DeltaX and DeltaY are chosen so that to avoid "jumping"
532 //-- of points on the grid
536 else if (aSurfType == GeomAbs_Cylinder)
538 gp_Cylinder Cyl = gFace->Cylinder();
539 Standard_Real R = Cyl.Radius();
541 // Calculate parameters for iteration in U direction
542 Standard_Real Du = 1.0 - (defface/R);
546 Du = 2.0 * ACos (Du);
547 if (Du > myParameters.Angle)
548 Du = myParameters.Angle;
555 deltaX = (myumax-myumin)/longu;
556 deltaY = (myvmax-myvmin)/longv;
559 // Restore face attribute
560 myAttribute->SetDefFace(defface);
561 myAttribute->SetUMax(myumax);
562 myAttribute->SetVMax(myvmax);
563 myAttribute->SetUMin(myumin);
564 myAttribute->SetVMin(myvmin);
565 myAttribute->SetDeltaX(deltaX);
566 myAttribute->SetDeltaY(deltaY);
569 catch(Standard_Failure)
571 myAttribute->SetStatus(BRepMesh_Failure);
574 myAttribute->ChangeMeshNodes() =
575 myAttribute->ChangeStructure()->Data()->Vertices();
577 myAttribute->ChangeStructure().Nullify();
578 return myAttribute->GetStatus();
581 //=======================================================================
582 //function : getEdgeAttributes
584 //=======================================================================
585 Standard_Boolean BRepMesh_FastDiscret::getEdgeAttributes(
586 const TopoDS_Edge& theEdge,
587 const BRepMesh_FastDiscret::EdgePCurve& thePCurve,
588 const Standard_Real theDefEdge,
589 BRepMesh_FastDiscret::EdgeAttributes& theAttributes) const
591 EdgeAttributes& aEAttr = theAttributes;
594 TopExp::Vertices(theEdge, aEAttr.FirstVertex, aEAttr.LastVertex);
595 if (aEAttr.FirstVertex.IsNull() || aEAttr.LastVertex.IsNull())
596 return Standard_False;
598 // Get range on 2d curve
599 const TopoDS_Face& aFace = myAttribute->Face();
600 BRep_Tool::Range(theEdge, aFace, aEAttr.FirstParam, aEAttr.LastParam);
602 // Get end points on 2d curve
603 BRep_Tool::UVPoints(theEdge, aFace, aEAttr.FirstUV, aEAttr.LastUV);
606 aEAttr.FirstUV.IsEqual(aEAttr.LastUV, Precision::PConfusion());
608 //Control tolerance of vertices
609 const Handle(BRepAdaptor_HSurface)& gFace = myAttribute->Surface();
610 gp_Pnt pFirst = gFace->Value(aEAttr.FirstUV.X(), aEAttr.FirstUV.Y());
611 gp_Pnt pLast = gFace->Value(aEAttr.LastUV.X(), aEAttr.LastUV.Y());
613 aEAttr.MinDist = 10. * Max(pFirst.Distance(BRep_Tool::Pnt(aEAttr.FirstVertex)),
614 pLast .Distance(BRep_Tool::Pnt(aEAttr.LastVertex)));
616 if (aEAttr.MinDist < BRep_Tool::Tolerance(aEAttr.FirstVertex) ||
617 aEAttr.MinDist < BRep_Tool::Tolerance(aEAttr.LastVertex))
619 aEAttr.MinDist = theDefEdge;
624 // 1. is it really sameUV without being degenerated
626 thePCurve.Curve2d->D0(thePCurve.FirstParam, uvF);
627 thePCurve.Curve2d->D0(thePCurve.LastParam, uvL);
629 if (!aEAttr.FirstUV.IsEqual(uvF, Precision::PConfusion()))
630 aEAttr.FirstUV = uvF;
632 if (!aEAttr.LastUV.IsEqual(uvL, Precision::PConfusion()))
636 return Standard_True;
639 //=======================================================================
640 //function : registerEdgeVertices
642 //=======================================================================
643 void BRepMesh_FastDiscret::registerEdgeVertices(
644 BRepMesh_FastDiscret::EdgeAttributes& theAttributes,
645 Standard_Integer& ipf,
646 Standard_Integer& ivf,
647 Standard_Integer& isvf,
648 Standard_Integer& ipl,
649 Standard_Integer& ivl,
650 Standard_Integer& isvl)
652 EdgeAttributes& aEAttr = theAttributes;
653 if (aEAttr.FirstVExtractor.IsNull())
655 // Use edge geometry to produce tesselation.
656 aEAttr.FirstVExtractor =
657 new TopoDSVExplorer(aEAttr.FirstVertex, aEAttr.IsSameUV, aEAttr.LastVertex);
660 if (aEAttr.LastVExtractor.IsNull())
662 // Use edge geometry to produce tesselation.
663 aEAttr.LastVExtractor =
664 new TopoDSVExplorer(aEAttr.LastVertex, aEAttr.IsSameUV, aEAttr.FirstVertex);
668 // Process first vertex
669 ipf = myAttribute->GetVertexIndex(aEAttr.FirstVExtractor, Standard_True);
670 aTmpUV = BRepMesh_ShapeTool::FindUV(ipf, aEAttr.FirstUV, aEAttr.FirstVertex,
671 aEAttr.MinDist, myAttribute);
673 myAttribute->AddNode(ipf, aTmpUV, BRepMesh_Frontier, ivf, isvf);
675 // Process last vertex
676 ipl = aEAttr.LastVertex.IsSame(aEAttr.FirstVertex) ? ipf :
677 myAttribute->GetVertexIndex(aEAttr.LastVExtractor, Standard_True);
678 aTmpUV = BRepMesh_ShapeTool::FindUV(ipl, aEAttr.LastUV, aEAttr.LastVertex,
679 aEAttr.MinDist, myAttribute);
681 myAttribute->AddNode(ipl, aTmpUV, BRepMesh_Frontier, ivl, isvl);
684 //=======================================================================
687 //=======================================================================
688 void BRepMesh_FastDiscret::add(
689 const TopoDS_Edge& theEdge,
690 const BRepMesh_FastDiscret::EdgePCurve& thePCurve,
691 const Standard_Real theDefEdge)
693 const TopAbs_Orientation orEdge = theEdge.Orientation();
694 if (orEdge == TopAbs_EXTERNAL)
697 EdgeAttributes aEAttr;
698 if (!getEdgeAttributes(theEdge, thePCurve, theDefEdge, aEAttr))
701 if (!myEdges.IsBound(theEdge))
703 update(theEdge, thePCurve.Curve2d, theDefEdge, aEAttr);
707 Standard_Integer ipf, ivf, isvf, ipl, ivl, isvl;
708 registerEdgeVertices(aEAttr, ipf, ivf, isvf, ipl, ivl, isvl);
710 // If this Edge has been already checked and it is not degenerated,
711 // the points of the polygon calculated at the first check are retrieved :
713 // retrieve the polygone:
714 const BRepMesh_PairOfPolygon& aPair = myEdges.Find(theEdge);
715 const Handle(Poly_PolygonOnTriangulation)& aPolygon = aPair.First();
716 const TColStd_Array1OfInteger& aNodes = aPolygon->Nodes();
717 Handle(TColStd_HArray1OfReal) aParams = aPolygon->Parameters();
720 const Standard_Integer aNodesNb = aNodes.Length();
721 TColStd_Array1OfInteger aNewNodes (1, aNodesNb);
722 TColStd_Array1OfReal aNewParams(1, aNodesNb);
724 aNewNodes (1) = isvf;
725 aNewParams(1) = aEAttr.FirstParam;
727 aNewNodes (aNodesNb) = isvl;
728 aNewParams(aNodesNb) = aEAttr.LastParam;
730 const TopoDS_Face& aFace = myAttribute->Face();
731 if (!BRepMesh_ShapeTool::IsDegenerated(theEdge, aFace))
733 BRepMesh_EdgeParameterProvider aProvider(theEdge, aFace, aParams);
734 for (Standard_Integer i = 2; i < aNodesNb; ++i)
736 const Standard_Integer aPointId = aNodes(i);
737 const gp_Pnt& aPnt = myBoundaryPoints->Find(aPointId);
739 const Standard_Real aParam = aProvider.Parameter(i, aPnt);
740 gp_Pnt2d aUV = thePCurve.Curve2d->Value(aParam);
742 Standard_Integer iv2, isv;
743 myAttribute->AddNode(aPointId, aUV.Coord(), BRepMesh_OnCurve, iv2, isv);
746 aNewParams(i) = aParam;
750 Handle(Poly_PolygonOnTriangulation) P1 =
751 new Poly_PolygonOnTriangulation(aNewNodes, aNewParams);
753 storePolygon(theEdge, P1, theDefEdge);
756 //=======================================================================
757 //function : update(edge)
759 //=======================================================================
760 void BRepMesh_FastDiscret::update(
761 const TopoDS_Edge& theEdge,
762 const Handle(Geom2d_Curve)& theC2d,
763 const Standard_Real theDefEdge,
764 BRepMesh_FastDiscret::EdgeAttributes& theAttributes)
766 EdgeAttributes& aEAttr = theAttributes;
768 const TopoDS_Face& aFace = myAttribute->Face();
769 Handle(BRepMesh_IEdgeTool) aEdgeTool;
770 // Try to find existing tessellation.
771 for (Standard_Integer i = 1; aEdgeTool.IsNull(); ++i)
773 TopLoc_Location aLoc;
774 Handle(Poly_Triangulation) aTriangulation;
775 Handle(Poly_PolygonOnTriangulation) aPolygon;
776 BRep_Tool::PolygonOnTriangulation(theEdge, aPolygon, aTriangulation, aLoc, i);
778 if (aPolygon.IsNull())
781 if (aTriangulation.IsNull() || !aPolygon->HasParameters())
784 if (aPolygon->Deflection() > 1.1 * theDefEdge)
787 const TColgp_Array1OfPnt& aNodes = aTriangulation->Nodes();
788 const TColStd_Array1OfInteger& aIndices = aPolygon->Nodes();
789 Handle(TColStd_HArray1OfReal) aParams = aPolygon->Parameters();
791 aEAttr.FirstVExtractor = new PolyVExplorer(aEAttr.FirstVertex,
792 aEAttr.IsSameUV, aEAttr.LastVertex, aIndices(1), aNodes, aLoc);
794 aEAttr.LastVExtractor = new PolyVExplorer(aEAttr.LastVertex,
795 aEAttr.IsSameUV, aEAttr.FirstVertex, aIndices(aIndices.Length()), aNodes, aLoc);
797 aEdgeTool = new BRepMesh_EdgeTessellationExtractor(theEdge, theC2d,
798 aFace, aTriangulation, aPolygon, aLoc);
801 if (aEdgeTool.IsNull())
803 aEdgeTool = new BRepMesh_EdgeTessellator(theEdge, myAttribute,
804 mySharedFaces, theDefEdge, myParameters.Angle, myParameters.MinSize);
807 Standard_Integer ipf, ivf, isvf, ipl, ivl, isvl;
808 registerEdgeVertices(aEAttr, ipf, ivf, isvf, ipl, ivl, isvl);
810 Handle(Poly_PolygonOnTriangulation) P1, P2;
811 if (BRepMesh_ShapeTool::IsDegenerated(theEdge, aFace))
813 const Standard_Integer aNodesNb = 2;
814 TColStd_Array1OfInteger aNewNodes (1, aNodesNb);
815 TColStd_Array1OfInteger aNewNodInStruct(1, aNodesNb);
816 TColStd_Array1OfReal aNewParams (1, aNodesNb);
818 aNewNodInStruct(1) = ipf;
819 aNewNodes (1) = isvf;
820 aNewParams (1) = aEAttr.FirstParam;
822 aNewNodInStruct(aNodesNb) = ipl;
823 aNewNodes (aNodesNb) = isvl;
824 aNewParams (aNodesNb) = aEAttr.LastParam;
826 P1 = new Poly_PolygonOnTriangulation(aNewNodes, aNewParams);
827 P2 = new Poly_PolygonOnTriangulation(aNewNodInStruct, aNewParams);
831 const Standard_Integer aNodesNb = aEdgeTool->NbPoints();
832 TColStd_Array1OfInteger aNewNodesVec (1, aNodesNb);
833 TColStd_Array1OfInteger aNewNodesInStructVec(1, aNodesNb);
834 TColStd_Array1OfReal aNewParamsVec (1, aNodesNb);
836 Standard_Integer aNodesCount = 1;
837 aNewNodesInStructVec(aNodesCount) = ipf;
838 aNewNodesVec (aNodesCount) = isvf;
839 aNewParamsVec (aNodesCount) = aEAttr.FirstParam;
842 Standard_Integer aLastPointId = myAttribute->LastPointId();
843 for (Standard_Integer i = 2; i < aNodesNb; ++i)
847 Standard_Real aParam;
848 if (!aEdgeTool->Value(i, aParam, aPnt, aUV))
851 myBoundaryPoints->Bind(++aLastPointId, aPnt);
853 Standard_Integer iv2, isv;
854 myAttribute->AddNode(aLastPointId, aUV.Coord(), BRepMesh_Frontier, iv2, isv);
856 aNewNodesInStructVec(aNodesCount) = aLastPointId;
857 aNewNodesVec (aNodesCount) = isv;
858 aNewParamsVec (aNodesCount) = aParam;
862 aNewNodesInStructVec(aNodesCount) = ipl;
863 aNewNodesVec (aNodesCount) = isvl;
864 aNewParamsVec (aNodesCount) = aEAttr.LastParam;
866 TColStd_Array1OfInteger aNewNodes (aNewNodesVec.First (), 1, aNodesCount);
867 TColStd_Array1OfInteger aNewNodInStruct(aNewNodesInStructVec.First(), 1, aNodesCount);
868 TColStd_Array1OfReal aNewParams (aNewParamsVec.First(), 1, aNodesCount);
870 P1 = new Poly_PolygonOnTriangulation(aNewNodes, aNewParams);
871 P2 = new Poly_PolygonOnTriangulation(aNewNodInStruct, aNewParams);
874 storePolygon(theEdge, P1, theDefEdge);
875 storePolygonSharedData(theEdge, P2, theDefEdge);
878 //=======================================================================
879 //function : storeInternalPolygon
881 //=======================================================================
882 void BRepMesh_FastDiscret::storePolygon(
883 const TopoDS_Edge& theEdge,
884 Handle(Poly_PolygonOnTriangulation)& thePolygon,
885 const Standard_Real theDeflection)
887 thePolygon->Deflection(theDeflection);
888 BRepMesh::HDMapOfShapePairOfPolygon& aInternalEdges = myAttribute->ChangeInternalEdges();
889 if (aInternalEdges->IsBound(theEdge))
891 BRepMesh_PairOfPolygon& aPair = aInternalEdges->ChangeFind(theEdge);
892 if (theEdge.Orientation() == TopAbs_REVERSED)
893 aPair.Append(thePolygon);
895 aPair.Prepend(thePolygon);
900 BRepMesh_PairOfPolygon aPair;
901 aPair.Append(thePolygon);
902 aInternalEdges->Bind(theEdge, aPair);
905 //=======================================================================
906 //function : storePolygonSharedData
908 //=======================================================================
909 void BRepMesh_FastDiscret::storePolygonSharedData(
910 const TopoDS_Edge& theEdge,
911 Handle(Poly_PolygonOnTriangulation)& thePolygon,
912 const Standard_Real theDeflection)
914 thePolygon->Deflection(theDeflection);
915 BRepMesh_PairOfPolygon aPair;
916 aPair.Append(thePolygon);
917 myEdges.Bind(theEdge, aPair);
920 //=======================================================================
921 //function : GetFaceAttribute
923 //=======================================================================
924 Standard_Boolean BRepMesh_FastDiscret::GetFaceAttribute(
925 const TopoDS_Face& theFace,
926 Handle(BRepMesh_FaceAttribute)& theAttribute ) const
928 if (myAttributes.IsBound(theFace))
930 theAttribute = myAttributes(theFace);
931 return Standard_True;
934 return Standard_False;
937 //=======================================================================
938 //function : RemoveFaceAttribute
940 //=======================================================================
941 void BRepMesh_FastDiscret::RemoveFaceAttribute(const TopoDS_Face& theFace)
943 if (myAttributes.IsBound(theFace))
944 myAttributes.UnBind(theFace);