1 // Created on: 2016-04-19
2 // Copyright (c) 2016 OPEN CASCADE SAS
3 // Created by: Oleg AGASHIN
4 //
5 // This file is part of Open CASCADE Technology software library.
6 //
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.
12 //
13 // Alternatively, this file may be used under the terms of Open CASCADE
14 // commercial license or contractual agreement.
15
16 #include <BRepMesh_ShapeTool.hxx>
17 #include <IMeshData_Edge.hxx>
18 #include <IMeshData_PCurve.hxx>
19 #include <TopoDS_Vertex.hxx>
20 #include <TopExp.hxx>
21 #include <TopExp_Explorer.hxx>
22 #include <BRep_Tool.hxx>
23 #include <BRep_Builder.hxx>
24 #include <ShapeAnalysis_Edge.hxx>
25 #include <BRepAdaptor_Curve.hxx>
26 #include <Precision.hxx>
27 #include <Bnd_Box.hxx>
28
29 IMPLEMENT_STANDARD_RTTIEXT(BRepMesh_ShapeTool, Standard_Transient)
30
31 namespace
32 {
33 //! Auxiliary struct to take a tolerance of edge.
34 struct EdgeTolerance
35 {
Get__anon3614a4520111::EdgeTolerance36 static Standard_Real Get(const TopoDS_Shape& theEdge)
37 {
38 return BRep_Tool::Tolerance(TopoDS::Edge(theEdge));
39 }
40 };
41
42 //! Auxiliary struct to take a tolerance of vertex.
43 struct VertexTolerance
44 {
Get__anon3614a4520111::VertexTolerance45 static Standard_Real Get(const TopoDS_Shape& theVertex)
46 {
47 return BRep_Tool::Tolerance(TopoDS::Vertex(theVertex));
48 }
49 };
50
51 //! Returns maximum tolerance of face element of the specified type.
52 template<TopAbs_ShapeEnum ShapeType, class ToleranceExtractor>
MaxTolerance(const TopoDS_Face & theFace)53 Standard_Real MaxTolerance(const TopoDS_Face& theFace)
54 {
55 Standard_Real aMaxTolerance = RealFirst();
56 TopExp_Explorer aExplorer(theFace, ShapeType);
57 for (; aExplorer.More(); aExplorer.Next())
58 {
59 Standard_Real aTolerance = ToleranceExtractor::Get(aExplorer.Current());
60 if (aTolerance > aMaxTolerance)
61 aMaxTolerance = aTolerance;
62 }
63
64 return aMaxTolerance;
65 }
66 }
67
68 //=======================================================================
69 //function : MaxFaceTolerance
70 //purpose :
71 //=======================================================================
MaxFaceTolerance(const TopoDS_Face & theFace)72 Standard_Real BRepMesh_ShapeTool::MaxFaceTolerance(const TopoDS_Face& theFace)
73 {
74 Standard_Real aMaxTolerance = BRep_Tool::Tolerance(theFace);
75
76 Standard_Real aTolerance = Max(
77 MaxTolerance<TopAbs_EDGE, EdgeTolerance >(theFace),
78 MaxTolerance<TopAbs_VERTEX, VertexTolerance>(theFace));
79
80 return Max(aMaxTolerance, aTolerance);
81 }
82
83 //=======================================================================
84 //function : BoxMaxDimension
85 //purpose :
86 //=======================================================================
BoxMaxDimension(const Bnd_Box & theBox,Standard_Real & theMaxDimension)87 void BRepMesh_ShapeTool::BoxMaxDimension(const Bnd_Box& theBox,
88 Standard_Real& theMaxDimension)
89 {
90 if (theBox.IsVoid())
91 return;
92
93 Standard_Real aMinX, aMinY, aMinZ, aMaxX, aMaxY, aMaxZ;
94 theBox.Get(aMinX, aMinY, aMinZ, aMaxX, aMaxY, aMaxZ);
95
96 theMaxDimension = Max(aMaxX - aMinX, Max(aMaxY - aMinY, aMaxZ - aMinZ));
97 }
98
99 //=======================================================================
100 //function : CheckAndUpdateFlags
101 //purpose :
102 //=======================================================================
CheckAndUpdateFlags(const IMeshData::IEdgeHandle & theEdge,const IMeshData::IPCurveHandle & thePCurve)103 void BRepMesh_ShapeTool::CheckAndUpdateFlags (
104 const IMeshData::IEdgeHandle& theEdge,
105 const IMeshData::IPCurveHandle& thePCurve)
106 {
107 if (!theEdge->GetSameParam () &&
108 !theEdge->GetSameRange () &&
109 theEdge->GetDegenerated ())
110 {
111 // Nothing to do worse.
112 return;
113 }
114
115 const TopoDS_Edge& aEdge = theEdge->GetEdge ();
116 const TopoDS_Face& aFace = thePCurve->GetFace ()->GetFace ();
117
118 Handle (Geom_Curve) aCurve;
119 Standard_Real aFirstParam, aLastParam;
120 Range (aEdge, aCurve, aFirstParam, aLastParam);
121 if (aCurve.IsNull())
122 {
123 theEdge->SetDegenerated(Standard_True);
124 return;
125 }
126
127 BRepAdaptor_Curve aCurveOnSurf(aEdge, aFace);
128 if (theEdge->GetSameParam () || theEdge->GetSameRange ())
129 {
130 if (theEdge->GetSameRange ())
131 {
132 const Standard_Real aDiffFirst = aCurveOnSurf.FirstParameter () - aFirstParam;
133 const Standard_Real aDiffLast = aCurveOnSurf.LastParameter () - aLastParam;
134 theEdge->SetSameRange (
135 Abs (aDiffFirst) < Precision::PConfusion () &&
136 Abs (aDiffLast ) < Precision::PConfusion ());
137
138 if (!theEdge->GetSameRange())
139 {
140 theEdge->SetSameParam(Standard_False);
141 }
142 }
143 }
144
145 if (!theEdge->GetDegenerated ()/* || theEdge->GetSameParam ()*/)
146 {
147 TopoDS_Vertex aStartVertex, aEndVertex;
148 TopExp::Vertices (aEdge, aStartVertex, aEndVertex);
149 if (aStartVertex.IsNull() || aEndVertex.IsNull())
150 {
151 theEdge->SetDegenerated(Standard_True);
152 return;
153 }
154
155 if (aStartVertex.IsSame(aEndVertex))
156 {
157 const Standard_Integer aPointsNb = 20;
158 const Standard_Real aVertexTolerance = BRep_Tool::Tolerance (aStartVertex);
159 const Standard_Real aDu = (aLastParam - aFirstParam) / aPointsNb;
160 //const Standard_Real aEdgeTolerance = BRep_Tool::Tolerance (aEdge);
161 //const Standard_Real aSqEdgeTolerance = aEdgeTolerance * aEdgeTolerance;
162
163 gp_Pnt aPrevPnt;
164 aCurve->D0 (aFirstParam, aPrevPnt);
165
166 Standard_Real aLength = 0.0;
167 for (Standard_Integer i = 1; i <= aPointsNb; ++i)
168 {
169 const Standard_Real aParameter = aFirstParam + i * aDu;
170 // Calculation of the length of the edge in 3D
171 // in order to check degenerativity
172 gp_Pnt aPnt;
173 aCurve->D0 (aParameter, aPnt);
174 aLength += aPrevPnt.Distance (aPnt);
175
176 //if (theEdge->GetSameParam ())
177 //{
178 // // Check that points taken at the 3d and pcurve using
179 // // same parameter are within tolerance of an edge.
180 // gp_Pnt aPntOnSurf;
181 // aCurveOnSurf.D0 (aParameter, aPntOnSurf);
182 // theEdge->SetSameParam (aPnt.SquareDistance (aPntOnSurf) < aSqEdgeTolerance);
183 //}
184
185 if (aLength > aVertexTolerance /*&& !theEdge->GetSameParam()*/)
186 {
187 break;
188 }
189
190 aPrevPnt = aPnt;
191 }
192
193 theEdge->SetDegenerated (aLength < aVertexTolerance);
194 }
195 }
196 }
197
198 //=======================================================================
199 //function : AddInFace
200 //purpose :
201 //=======================================================================
AddInFace(const TopoDS_Face & theFace,Handle (Poly_Triangulation)& theTriangulation)202 void BRepMesh_ShapeTool::AddInFace(
203 const TopoDS_Face& theFace,
204 Handle(Poly_Triangulation)& theTriangulation)
205 {
206 const TopLoc_Location& aLoc = theFace.Location();
207 if (!aLoc.IsIdentity())
208 {
209 gp_Trsf aTrsf = aLoc.Transformation();
210 aTrsf.Invert();
211 for (Standard_Integer aNodeIter = 1; aNodeIter <= theTriangulation->NbNodes(); ++aNodeIter)
212 {
213 gp_Pnt aNode = theTriangulation->Node (aNodeIter);
214 aNode.Transform (aTrsf);
215 theTriangulation->SetNode (aNodeIter, aNode);
216 }
217 }
218
219 BRep_Builder aBuilder;
220 aBuilder.UpdateFace(theFace, theTriangulation);
221 }
222
223
224 //=======================================================================
225 //function : NullifyFace
226 //purpose :
227 //=======================================================================
NullifyFace(const TopoDS_Face & theFace)228 void BRepMesh_ShapeTool::NullifyFace (const TopoDS_Face& theFace)
229 {
230 BRep_Builder aBuilder;
231 aBuilder.UpdateFace (theFace, Handle (Poly_Triangulation)());
232 }
233
234 //=======================================================================
235 //function : NullifyEdge
236 //purpose :
237 //=======================================================================
NullifyEdge(const TopoDS_Edge & theEdge,const Handle (Poly_Triangulation)& theTriangulation,const TopLoc_Location & theLocation)238 void BRepMesh_ShapeTool::NullifyEdge (
239 const TopoDS_Edge& theEdge,
240 const Handle (Poly_Triangulation)& theTriangulation,
241 const TopLoc_Location& theLocation)
242 {
243 UpdateEdge (theEdge, Handle (Poly_PolygonOnTriangulation)(),
244 theTriangulation, theLocation);
245 }
246
247 //=======================================================================
248 //function : NullifyEdge
249 //purpose :
250 //=======================================================================
NullifyEdge(const TopoDS_Edge & theEdge,const TopLoc_Location & theLocation)251 void BRepMesh_ShapeTool::NullifyEdge (
252 const TopoDS_Edge& theEdge,
253 const TopLoc_Location& theLocation)
254 {
255 BRep_Builder aBuilder;
256 aBuilder.UpdateEdge (theEdge, Handle (Poly_Polygon3D)(), theLocation);
257 }
258
259 //=======================================================================
260 //function : UpdateEdge
261 //purpose :
262 //=======================================================================
UpdateEdge(const TopoDS_Edge & theEdge,const Handle (Poly_PolygonOnTriangulation)& thePolygon,const Handle (Poly_Triangulation)& theTriangulation,const TopLoc_Location & theLocation)263 void BRepMesh_ShapeTool::UpdateEdge (
264 const TopoDS_Edge& theEdge,
265 const Handle (Poly_PolygonOnTriangulation)& thePolygon,
266 const Handle (Poly_Triangulation)& theTriangulation,
267 const TopLoc_Location& theLocation)
268 {
269 BRep_Builder aBuilder;
270 aBuilder.UpdateEdge (theEdge, thePolygon, theTriangulation, theLocation);
271 }
272
273 //=======================================================================
274 //function : UpdateEdge
275 //purpose :
276 //=======================================================================
UpdateEdge(const TopoDS_Edge & theEdge,const Handle (Poly_PolygonOnTriangulation)& thePolygon1,const Handle (Poly_PolygonOnTriangulation)& thePolygon2,const Handle (Poly_Triangulation)& theTriangulation,const TopLoc_Location & theLocation)277 void BRepMesh_ShapeTool::UpdateEdge (
278 const TopoDS_Edge& theEdge,
279 const Handle (Poly_PolygonOnTriangulation)& thePolygon1,
280 const Handle (Poly_PolygonOnTriangulation)& thePolygon2,
281 const Handle (Poly_Triangulation)& theTriangulation,
282 const TopLoc_Location& theLocation)
283 {
284 BRep_Builder aBuilder;
285 aBuilder.UpdateEdge (theEdge, thePolygon1, thePolygon2,
286 theTriangulation, theLocation);
287 }
288
289 //=======================================================================
290 //function : UpdateEdge
291 //purpose :
292 //=======================================================================
UpdateEdge(const TopoDS_Edge & theEdge,const Handle (Poly_Polygon3D)& thePolygon)293 void BRepMesh_ShapeTool::UpdateEdge(
294 const TopoDS_Edge& theEdge,
295 const Handle(Poly_Polygon3D)& thePolygon)
296 {
297 BRep_Builder aBuilder;
298 aBuilder.UpdateEdge(theEdge, thePolygon);
299 }
300
301 //=======================================================================
302 //function : UseLocation
303 //purpose :
304 //=======================================================================
UseLocation(const gp_Pnt & thePnt,const TopLoc_Location & theLoc)305 gp_Pnt BRepMesh_ShapeTool::UseLocation (
306 const gp_Pnt& thePnt,
307 const TopLoc_Location& theLoc)
308 {
309 if (theLoc.IsIdentity())
310 {
311 return thePnt;
312 }
313
314 return thePnt.Transformed (theLoc.Transformation ());
315 }
316
317 //=======================================================================
318 //function : UVPoints
319 //purpose :
320 //=======================================================================
UVPoints(const TopoDS_Edge & theEdge,const TopoDS_Face & theFace,gp_Pnt2d & theFirstPoint2d,gp_Pnt2d & theLastPoint2d,const Standard_Boolean isConsiderOrientation)321 Standard_Boolean BRepMesh_ShapeTool::UVPoints (
322 const TopoDS_Edge& theEdge,
323 const TopoDS_Face& theFace,
324 gp_Pnt2d& theFirstPoint2d,
325 gp_Pnt2d& theLastPoint2d,
326 const Standard_Boolean isConsiderOrientation)
327 {
328
329 Handle (Geom2d_Curve) aCurve2d;
330 Standard_Real aFirstParam, aLastParam;
331 if (!Range(theEdge, theFace, aCurve2d, aFirstParam, aLastParam, isConsiderOrientation))
332 {
333 return Standard_False;
334 }
335
336 aCurve2d->D0 (aFirstParam, theFirstPoint2d);
337 aCurve2d->D0 (aLastParam, theLastPoint2d);
338 return Standard_True;
339 }
340
341 //=======================================================================
342 //function : Range
343 //purpose :
344 //=======================================================================
Range(const TopoDS_Edge & theEdge,const TopoDS_Face & theFace,Handle (Geom2d_Curve)& thePCurve,Standard_Real & theFirstParam,Standard_Real & theLastParam,const Standard_Boolean isConsiderOrientation)345 Standard_Boolean BRepMesh_ShapeTool::Range (
346 const TopoDS_Edge& theEdge,
347 const TopoDS_Face& theFace,
348 Handle (Geom2d_Curve)& thePCurve,
349 Standard_Real& theFirstParam,
350 Standard_Real& theLastParam,
351 const Standard_Boolean isConsiderOrientation)
352 {
353
354 ShapeAnalysis_Edge aEdge;
355 return aEdge.PCurve (theEdge, theFace, thePCurve,
356 theFirstParam, theLastParam,
357 isConsiderOrientation);
358 }
359
360 //=======================================================================
361 //function : Range
362 //purpose :
363 //=======================================================================
Range(const TopoDS_Edge & theEdge,Handle (Geom_Curve)& theCurve,Standard_Real & theFirstParam,Standard_Real & theLastParam,const Standard_Boolean isConsiderOrientation)364 Standard_Boolean BRepMesh_ShapeTool::Range (
365 const TopoDS_Edge& theEdge,
366 Handle (Geom_Curve)& theCurve,
367 Standard_Real& theFirstParam,
368 Standard_Real& theLastParam,
369 const Standard_Boolean isConsiderOrientation)
370 {
371
372 ShapeAnalysis_Edge aEdge;
373 return aEdge.Curve3d (theEdge, theCurve,
374 theFirstParam, theLastParam,
375 isConsiderOrientation);
376 }
377