1 // Created on: 2016-04-19
2 // Copyright (c) 2016 OPEN CASCADE SAS
3 // Created by: Oleg AGASHIN
5 // This file is part of Open CASCADE Technology software library.
7 // This library is free software; you can redistribute it and/or modify it under
8 // the terms of the GNU Lesser General Public License version 2.1 as published
9 // by the Free Software Foundation, with special exception defined in the file
10 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
11 // distribution for complete text of the license and disclaimer of any warranty.
13 // Alternatively, this file may be used under the terms of Open CASCADE
14 // commercial license or contractual agreement.
16 #include <BRepMesh_EdgeDiscret.hxx>
17 #include <BRepMesh_Deflection.hxx>
18 #include <IMeshData_Model.hxx>
19 #include <IMeshData_Face.hxx>
20 #include <IMeshData_PCurve.hxx>
22 #include <BRepMesh_ShapeTool.hxx>
23 #include <BRepMesh_EdgeTessellationExtractor.hxx>
24 #include <IMeshData_ParametersListArrayAdaptor.hxx>
25 #include <BRepMesh_CurveTessellator.hxx>
26 #include <OSD_Parallel.hxx>
28 IMPLEMENT_STANDARD_RTTIEXT(BRepMesh_EdgeDiscret, IMeshTools_ModelAlgo)
30 //=======================================================================
31 // Function: Constructor
33 //=======================================================================
34 BRepMesh_EdgeDiscret::BRepMesh_EdgeDiscret ()
38 //=======================================================================
39 // Function: Destructor
41 //=======================================================================
42 BRepMesh_EdgeDiscret::~BRepMesh_EdgeDiscret ()
46 //=======================================================================
47 // Function: CreateFreeEdgeTessellator
49 //=======================================================================
50 Handle(IMeshTools_CurveTessellator) BRepMesh_EdgeDiscret::CreateEdgeTessellator(
51 const IMeshData::IEdgeHandle& theDEdge,
52 const IMeshTools_Parameters& theParameters,
53 const Standard_Integer theMinPointsNb)
55 return new BRepMesh_CurveTessellator(theDEdge, theParameters, theMinPointsNb);
58 //=======================================================================
59 // Function: CreateEdgeTessellator
61 //=======================================================================
62 Handle(IMeshTools_CurveTessellator) BRepMesh_EdgeDiscret::CreateEdgeTessellator(
63 const IMeshData::IEdgeHandle& theDEdge,
64 const TopAbs_Orientation theOrientation,
65 const IMeshData::IFaceHandle& theDFace,
66 const IMeshTools_Parameters& theParameters,
67 const Standard_Integer theMinPointsNb)
69 return theDEdge->GetSameParam() ?
70 new BRepMesh_CurveTessellator(theDEdge, theParameters, theMinPointsNb) :
71 new BRepMesh_CurveTessellator(theDEdge, theOrientation, theDFace, theParameters, theMinPointsNb);
74 //=======================================================================
75 // Function: CreateEdgeTessellationExtractor
77 //=======================================================================
78 Handle(IMeshTools_CurveTessellator) BRepMesh_EdgeDiscret::CreateEdgeTessellationExtractor(
79 const IMeshData::IEdgeHandle& theDEdge,
80 const IMeshData::IFaceHandle& theDFace)
82 return new BRepMesh_EdgeTessellationExtractor(theDEdge, theDFace);
85 //=======================================================================
88 //=======================================================================
89 Standard_Boolean BRepMesh_EdgeDiscret::performInternal (
90 const Handle (IMeshData_Model)& theModel,
91 const IMeshTools_Parameters& theParameters,
92 const Message_ProgressRange& theRange)
96 myParameters = theParameters;
100 return Standard_False;
103 OSD_Parallel::For (0, myModel->EdgesNb (), *this, !myParameters.InParallel);
105 myModel.Nullify(); // Do not hold link to model.
106 return Standard_True;
109 //=======================================================================
112 //=======================================================================
113 void BRepMesh_EdgeDiscret::process (const Standard_Integer theEdgeIndex) const
115 const IMeshData::IEdgeHandle& aDEdge = myModel->GetEdge (theEdgeIndex);
120 BRepMesh_Deflection::ComputeDeflection (aDEdge, myModel->GetMaxSize (), myParameters);
122 Handle (IMeshTools_CurveTessellator) aEdgeTessellator;
123 if (!aDEdge->IsFree ())
125 // Iterate over pcurves and check deflection on corresponding face.
126 Standard_Real aMinDeflection = RealLast ();
127 Standard_Integer aMinPCurveIndex = -1;
128 for (Standard_Integer aPCurveIt = 0; aPCurveIt < aDEdge->PCurvesNb (); ++aPCurveIt)
130 const IMeshData::IPCurveHandle& aPCurve = aDEdge->GetPCurve (aPCurveIt);
131 const Standard_Real aTmpDeflection = checkExistingPolygonAndUpdateStatus(aDEdge, aPCurve);
132 if (aTmpDeflection < aMinDeflection)
134 // Identify pcurve with the smallest deflection in order to
135 // retrieve polygon that represents the most smooth discretization.
136 aMinDeflection = aTmpDeflection;
137 aMinPCurveIndex = aPCurveIt;
140 BRepMesh_ShapeTool::CheckAndUpdateFlags (aDEdge, aPCurve);
143 if (aMinPCurveIndex != -1)
145 aDEdge->SetDeflection (aMinDeflection);
146 const IMeshData::IFaceHandle aDFace = aDEdge->GetPCurve(aMinPCurveIndex)->GetFace();
147 aEdgeTessellator = CreateEdgeTessellationExtractor(aDEdge, aDFace);
151 const IMeshData::IPCurveHandle& aPCurve = aDEdge->GetPCurve(0);
152 const IMeshData::IFaceHandle aDFace = aPCurve->GetFace();
153 aEdgeTessellator = BRepMesh_EdgeDiscret::CreateEdgeTessellator(
154 aDEdge, aPCurve->GetOrientation(), aDFace, myParameters);
159 TopLoc_Location aLoc;
160 const Handle (Poly_Polygon3D)& aPoly3D = BRep_Tool::Polygon3D (aDEdge->GetEdge (), aLoc);
161 if (!aPoly3D.IsNull ())
163 if (aPoly3D->HasParameters() &&
164 BRepMesh_Deflection::IsConsistent (aPoly3D->Deflection(),
165 aDEdge->GetDeflection(),
166 myParameters.AllowQualityDecrease))
168 // Edge already has suitable 3d polygon.
169 aDEdge->SetStatus(IMeshData_Reused);
174 aDEdge->SetStatus(IMeshData_Outdated);
178 aEdgeTessellator = CreateEdgeTessellator(aDEdge, myParameters);
181 Tessellate3d (aDEdge, aEdgeTessellator, Standard_True);
182 if (!aDEdge->IsFree())
184 Tessellate2d(aDEdge, Standard_True);
187 catch (Standard_Failure const&)
189 aDEdge->SetStatus (IMeshData_Failure);
193 //=======================================================================
194 // Function: checkExistingPolygonAndUpdateStatus
196 //=======================================================================
197 Standard_Real BRepMesh_EdgeDiscret::checkExistingPolygonAndUpdateStatus(
198 const IMeshData::IEdgeHandle& theDEdge,
199 const IMeshData::IPCurveHandle& thePCurve) const
201 const TopoDS_Edge& aEdge = theDEdge->GetEdge ();
202 const TopoDS_Face& aFace = thePCurve->GetFace ()->GetFace ();
204 TopLoc_Location aLoc;
205 const Handle (Poly_Triangulation)& aFaceTriangulation =
206 BRep_Tool::Triangulation (aFace, aLoc);
208 Standard_Real aDeflection = RealLast ();
209 if (aFaceTriangulation.IsNull())
214 const Handle (Poly_PolygonOnTriangulation)& aPolygon =
215 BRep_Tool::PolygonOnTriangulation (aEdge, aFaceTriangulation, aLoc);
217 if (!aPolygon.IsNull ())
219 Standard_Boolean isConsistent = aPolygon->HasParameters() &&
220 BRepMesh_Deflection::IsConsistent (aPolygon->Deflection(),
221 theDEdge->GetDeflection(),
222 myParameters.AllowQualityDecrease);
226 // Nullify edge data and mark discrete pcurve to
227 // notify necessity to mesh the entire face.
228 theDEdge->SetStatus(IMeshData_Outdated);
232 aDeflection = aPolygon->Deflection();
239 //=======================================================================
240 // Function: Tessellate3d
242 //=======================================================================
243 void BRepMesh_EdgeDiscret::Tessellate3d(
244 const IMeshData::IEdgeHandle& theDEdge,
245 const Handle (IMeshTools_CurveTessellator)& theTessellator,
246 const Standard_Boolean theUpdateEnds)
248 // Create 3d polygon.
249 const IMeshData::ICurveHandle& aCurve = theDEdge->GetCurve();
251 const TopoDS_Edge& aEdge = theDEdge->GetEdge();
252 TopoDS_Vertex aFirstVertex, aLastVertex;
253 TopExp::Vertices(aEdge, aFirstVertex, aLastVertex);
255 if(aFirstVertex.IsNull() || aLastVertex.IsNull())
261 Standard_Real aParam;
262 theTessellator->Value(1, aPoint, aParam);
263 aCurve->AddPoint(BRep_Tool::Pnt(aFirstVertex), aParam);
266 if (!theDEdge->GetDegenerated())
268 for (Standard_Integer i = 2; i < theTessellator->PointsNb(); ++i)
271 Standard_Real aParam;
272 if (!theTessellator->Value(i, aPoint, aParam))
277 aCurve->AddPoint(aPoint, aParam);
281 aCurve->InsertPoint(aCurve->ParametersNb() - 1, aPoint, aParam);
289 Standard_Real aParam;
290 theTessellator->Value(theTessellator->PointsNb(), aPoint, aParam);
291 aCurve->AddPoint(BRep_Tool::Pnt(aLastVertex), aParam);
295 //=======================================================================
296 // Function: Tessellate2d
298 //=======================================================================
299 void BRepMesh_EdgeDiscret::Tessellate2d(
300 const IMeshData::IEdgeHandle& theDEdge,
301 const Standard_Boolean theUpdateEnds)
303 const IMeshData::ICurveHandle& aCurve = theDEdge->GetCurve();
304 for (Standard_Integer aPCurveIt = 0; aPCurveIt < theDEdge->PCurvesNb(); ++aPCurveIt)
306 const IMeshData::IPCurveHandle& aPCurve = theDEdge->GetPCurve(aPCurveIt);
307 const IMeshData::IFaceHandle aDFace = aPCurve->GetFace();
308 IMeshData::ICurveArrayAdaptorHandle aCurveArray(new IMeshData::ICurveArrayAdaptor(aCurve));
309 BRepMesh_EdgeParameterProvider<IMeshData::ICurveArrayAdaptorHandle> aProvider(
310 theDEdge, aPCurve->GetOrientation(), aDFace, aCurveArray);
312 const Handle(Adaptor2d_Curve2d)& aGeomPCurve = aProvider.GetPCurve();
314 Standard_Integer aParamIdx, aParamNb;
318 aParamNb = aCurve->ParametersNb();
323 aParamNb = aCurve->ParametersNb() - 1;
326 for (; aParamIdx < aParamNb; ++aParamIdx)
328 const Standard_Real aParam = aProvider.Parameter(aParamIdx, aCurve->GetPoint(aParamIdx));
331 aGeomPCurve->D0(aParam, aPoint2d);
334 aPCurve->AddPoint(aPoint2d, aParam);
338 aPCurve->InsertPoint(aPCurve->ParametersNb() - 1, aPoint2d, aParam);