Warnings on vc14 were eliminated
[occt.git] / src / BRepMesh / BRepMesh_ShapeTool.cxx
CommitLineData
b311480e 1// Copyright (c) 1995-1999 Matra Datavision
973c2be1 2// Copyright (c) 1999-2014 OPEN CASCADE SAS
b311480e 3//
973c2be1 4// This file is part of Open CASCADE Technology software library.
b311480e 5//
d5f74e42 6// This library is free software; you can redistribute it and/or modify it under
7// the terms of the GNU Lesser General Public License version 2.1 as published
973c2be1 8// by the Free Software Foundation, with special exception defined in the file
9// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
10// distribution for complete text of the license and disclaimer of any warranty.
b311480e 11//
973c2be1 12// Alternatively, this file may be used under the terms of Open CASCADE
13// commercial license or contractual agreement.
b311480e 14
fc9b36d6 15#include <BRepMesh_ShapeTool.hxx>
16
17#include <Bnd_Box.hxx>
18#include <TopoDS_Edge.hxx>
7fd59977 19#include <BRepBndLib.hxx>
fc9b36d6 20#include <TopoDS.hxx>
21#include <BRep_Tool.hxx>
22#include <TopExp_Explorer.hxx>
23#include <BRepAdaptor_HSurface.hxx>
24#include <TColgp_Array1OfPnt.hxx>
25#include <Poly_Triangulation.hxx>
7fd59977 26#include <BRep_Builder.hxx>
ceb418e1 27#include <TopExp.hxx>
28#include <BRepAdaptor_Curve.hxx>
7fd59977 29
fc9b36d6 30namespace {
31 //! Auxilary struct to take a tolerance of edge.
32 struct EdgeTolerance
33 {
34 static Standard_Real Get(const TopoDS_Shape& theEdge)
35 {
36 return BRep_Tool::Tolerance(TopoDS::Edge(theEdge));
37 }
38 };
7fd59977 39
fc9b36d6 40 //! Auxilary struct to take a tolerance of vertex.
41 struct VertexTolerance
42 {
43 static Standard_Real Get(const TopoDS_Shape& theVertex)
44 {
45 return BRep_Tool::Tolerance(TopoDS::Vertex(theVertex));
46 }
47 };
7fd59977 48
fc9b36d6 49 //! Returns maximum tolerance of face element of the specified type.
50 template<TopAbs_ShapeEnum ShapeType, class ToleranceExtractor>
51 Standard_Real MaxTolerance(const TopoDS_Face& theFace)
52 {
53 Standard_Real aMaxTolerance = RealFirst();
54 TopExp_Explorer aExplorer(theFace, ShapeType);
55 for (; aExplorer.More(); aExplorer.Next())
56 {
57 Standard_Real aTolerance = ToleranceExtractor::Get(aExplorer.Current());
58 if (aTolerance > aMaxTolerance)
59 aMaxTolerance = aTolerance;
60 }
61
62 return aMaxTolerance;
7fd59977 63 }
7fd59977 64}
65
fc9b36d6 66//=======================================================================
67//function : BoxMaxDimension
68//purpose :
69//=======================================================================
70Standard_Real BRepMesh_ShapeTool::MaxFaceTolerance(const TopoDS_Face& theFace)
7fd59977 71{
fc9b36d6 72 Standard_Real aMaxTolerance = BRep_Tool::Tolerance(theFace);
73
74 Standard_Real aTolerance = Max(
75 MaxTolerance<TopAbs_EDGE, EdgeTolerance >(theFace),
76 MaxTolerance<TopAbs_VERTEX, VertexTolerance>(theFace));
77
78 return Max(aMaxTolerance, aTolerance);
7fd59977 79}
80
fc9b36d6 81//=======================================================================
82//function : BoxMaxDimension
83//purpose :
84//=======================================================================
85void BRepMesh_ShapeTool::BoxMaxDimension(const Bnd_Box& theBox,
86 Standard_Real& theMaxDimension)
7fd59977 87{
fc9b36d6 88 if(theBox.IsVoid())
89 return;
90
91 Standard_Real aMinX, aMinY, aMinZ, aMaxX, aMaxY, aMaxZ;
92 theBox.Get(aMinX, aMinY, aMinZ, aMaxX, aMaxY, aMaxZ);
93
94 theMaxDimension = Max(aMaxX - aMinX, Max(aMaxY - aMinY, aMaxZ - aMinZ));
7fd59977 95}
96
fc9b36d6 97//=======================================================================
98//function : RelativeEdgeDeflection
99//purpose :
100//=======================================================================
101Standard_Real BRepMesh_ShapeTool::RelativeEdgeDeflection(
102 const TopoDS_Edge& theEdge,
103 const Standard_Real theDeflection,
104 const Standard_Real theMaxShapeSize,
105 Standard_Real& theAdjustmentCoefficient)
7fd59977 106{
fc9b36d6 107 theAdjustmentCoefficient = 1.;
108 Standard_Real aDefEdge = theDeflection;
109 if(theEdge.IsNull())
110 return aDefEdge;
111
112 Bnd_Box aBox;
ceb418e1 113 BRepBndLib::Add(theEdge, aBox, Standard_False);
fc9b36d6 114 BoxMaxDimension(aBox, aDefEdge);
115
116 // Adjust resulting value in relation to the total size
117 theAdjustmentCoefficient = theMaxShapeSize / (2 * aDefEdge);
118 if (theAdjustmentCoefficient < 0.5)
119 theAdjustmentCoefficient = 0.5;
120 else if (theAdjustmentCoefficient > 2.)
121 theAdjustmentCoefficient = 2.;
122
123 return (theAdjustmentCoefficient * aDefEdge * theDeflection);
7fd59977 124}
125
fc9b36d6 126//=======================================================================
127//function : FindUV
128//purpose :
129//=======================================================================
130gp_XY BRepMesh_ShapeTool::FindUV(
ceb418e1 131 const Standard_Integer theIndexOfPnt3d,
132 const gp_Pnt2d& thePnt2d,
ceb418e1 133 const Standard_Real theMinDistance,
134 const Handle(BRepMesh_FaceAttribute)& theFaceAttribute)
7fd59977 135{
fc9b36d6 136 const gp_XY& aPnt2d = thePnt2d.Coord();
2caff0b3 137 BRepMesh::HDMapOfIntegerListOfXY& aLocation2D =
ceb418e1 138 theFaceAttribute->ChangeLocation2D();
139
2caff0b3 140 if (!aLocation2D->IsBound(theIndexOfPnt3d))
fc9b36d6 141 {
848fa7e3 142 BRepMesh::ListOfXY aPoints2d;
fc9b36d6 143 aPoints2d.Append(aPnt2d);
2caff0b3 144 aLocation2D->Bind(theIndexOfPnt3d, aPoints2d);
fc9b36d6 145 return aPnt2d;
146 }
147
2caff0b3 148 BRepMesh::ListOfXY& aPoints2d = aLocation2D->ChangeFind(theIndexOfPnt3d);
fc9b36d6 149
150 // Find the most closest 2d point to the given one.
151 gp_XY aUV;
152 Standard_Real aMinDist = RealLast();
848fa7e3 153 BRepMesh::ListOfXY::Iterator aPoint2dIt(aPoints2d);
fc9b36d6 154 for (; aPoint2dIt.More(); aPoint2dIt.Next())
155 {
156 const gp_XY& aCurPnt2d = aPoint2dIt.Value();
157
158 Standard_Real aDist = (aPnt2d - aCurPnt2d).Modulus();
159 if (aDist < aMinDist)
160 {
161 aUV = aCurPnt2d;
162 aMinDist = aDist;
163 }
164 }
165
81093856 166 const Standard_Real aTolerance = theMinDistance;
fc9b36d6 167
168 // Get face limits
ceb418e1 169 Standard_Real aDiffU = theFaceAttribute->GetUMax() - theFaceAttribute->GetUMin();
170 Standard_Real aDiffV = theFaceAttribute->GetVMax() - theFaceAttribute->GetVMin();
fc9b36d6 171
172 const Standard_Real Utol2d = .5 * aDiffU;
173 const Standard_Real Vtol2d = .5 * aDiffV;
174
ceb418e1 175 const Handle(BRepAdaptor_HSurface)& aSurface = theFaceAttribute->Surface();
176 const gp_Pnt aPnt1 = aSurface->Value(aUV.X(), aUV.Y());
177 const gp_Pnt aPnt2 = aSurface->Value(aPnt2d.X(), aPnt2d.Y());
fc9b36d6 178
179 //! If selected point is too far from the given one in parametric space
180 //! or their positions in 3d are different, add the given point as unique.
181 if (Abs(aUV.X() - aPnt2d.X()) > Utol2d ||
182 Abs(aUV.Y() - aPnt2d.Y()) > Vtol2d ||
183 !aPnt1.IsEqual(aPnt2, aTolerance))
184 {
185 aUV = aPnt2d;
186 aPoints2d.Append(aUV);
187 }
188
189 return aUV;
7fd59977 190}
191
fc9b36d6 192//=======================================================================
193//function : AddInFace
194//purpose :
195//=======================================================================
196void BRepMesh_ShapeTool::AddInFace(
197 const TopoDS_Face& theFace,
198 Handle(Poly_Triangulation)& theTriangulation)
7fd59977 199{
fc9b36d6 200 const TopLoc_Location& aLoc = theFace.Location();
201 if (!aLoc.IsIdentity())
202 {
203 gp_Trsf aTrsf = aLoc.Transformation();
204 aTrsf.Invert();
205
206 TColgp_Array1OfPnt& aNodes = theTriangulation->ChangeNodes();
207 for (Standard_Integer i = aNodes.Lower(); i <= aNodes.Upper(); ++i)
208 aNodes(i).Transform(aTrsf);
209 }
210
211 BRep_Builder aBuilder;
212 aBuilder.UpdateFace(theFace, theTriangulation);
7fd59977 213}
214
fc9b36d6 215//=======================================================================
216//function : NullifyFace
217//purpose :
218//=======================================================================
219void BRepMesh_ShapeTool::NullifyFace(const TopoDS_Face& theFace)
7fd59977 220{
fc9b36d6 221 BRep_Builder aBuilder;
222 aBuilder.UpdateFace(theFace, Handle(Poly_Triangulation)());
7fd59977 223}
224
fc9b36d6 225//=======================================================================
226//function : NullifyEdge
227//purpose :
228//=======================================================================
229void BRepMesh_ShapeTool::NullifyEdge(
230 const TopoDS_Edge& theEdge,
231 const Handle(Poly_Triangulation)& theTriangulation,
232 const TopLoc_Location& theLocation)
7fd59977 233{
fc9b36d6 234 UpdateEdge(theEdge, Handle(Poly_PolygonOnTriangulation)(),
235 theTriangulation, theLocation);
7fd59977 236}
237
fc9b36d6 238//=======================================================================
239//function : UpdateEdge
240//purpose :
241//=======================================================================
242void BRepMesh_ShapeTool::UpdateEdge(
243 const TopoDS_Edge& theEdge,
244 const Handle(Poly_PolygonOnTriangulation)& thePolygon,
245 const Handle(Poly_Triangulation)& theTriangulation,
246 const TopLoc_Location& theLocation)
247{
248 BRep_Builder aBuilder;
249 aBuilder.UpdateEdge(theEdge, thePolygon, theTriangulation, theLocation);
250}
7fd59977 251
fc9b36d6 252//=======================================================================
253//function : UpdateEdge
254//purpose :
255//=======================================================================
256void BRepMesh_ShapeTool::UpdateEdge(
257 const TopoDS_Edge& theEdge,
258 const Handle(Poly_PolygonOnTriangulation)& thePolygon1,
259 const Handle(Poly_PolygonOnTriangulation)& thePolygon2,
260 const Handle(Poly_Triangulation)& theTriangulation,
261 const TopLoc_Location& theLocation)
7fd59977 262{
fc9b36d6 263 BRep_Builder aBuilder;
264 aBuilder.UpdateEdge(theEdge, thePolygon1, thePolygon2,
265 theTriangulation, theLocation);
7fd59977 266}
ceb418e1 267
268//=======================================================================
269//function : UseLocation
270//purpose :
271//=======================================================================
272gp_Pnt BRepMesh_ShapeTool::UseLocation(const gp_Pnt& thePnt,
273 const TopLoc_Location& theLoc)
274{
275 if (theLoc.IsIdentity())
276 return thePnt;
277
278 return thePnt.Transformed(theLoc.Transformation());
279}
280
281//=======================================================================
282//function : IsDegenerated
283//purpose :
284//=======================================================================
285Standard_Boolean BRepMesh_ShapeTool::IsDegenerated(
286 const TopoDS_Edge& theEdge,
287 const TopoDS_Face& theFace)
288{
289 // Get vertices
290 TopoDS_Vertex pBegin, pEnd;
291 TopExp::Vertices(theEdge, pBegin, pEnd);
292 if (pBegin.IsNull() || pEnd.IsNull())
293 return Standard_True;
294
295 if (BRep_Tool::Degenerated(theEdge))
296 return Standard_True;
297
298 if (!pBegin.IsSame(pEnd))
299 return Standard_False;
300
301 Standard_Real wFirst, wLast;
302 BRep_Tool::Range(theEdge, theFace, wFirst, wLast);
303
304 // calculation of the length of the edge in 3D
305 Standard_Real longueur = 0.0;
306 Standard_Real du = (wLast - wFirst) * 0.05;
307 gp_Pnt P1, P2;
308 BRepAdaptor_Curve BC(theEdge);
309 BC.D0(wFirst, P1);
310 Standard_Real tolV = BRep_Tool::Tolerance(pBegin);
311 Standard_Real tolV2 = 1.2 * tolV;
312
313 for (Standard_Integer l = 1; l <= 20; ++l)
314 {
315 BC.D0(wFirst + l * du, P2);
316 longueur += P1.Distance(P2);
317
318 if (longueur > tolV2)
319 break;
320
321 P1 = P2;
322 }
323
324 if (longueur < tolV2)
325 return Standard_True;
326
327 return Standard_False;
328}