1 // Copyright (c) 1995-1999 Matra Datavision
2 // Copyright (c) 1999-2014 OPEN CASCADE SAS
4 // This file is part of Open CASCADE Technology software library.
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
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.
12 // Alternatively, this file may be used under the terms of Open CASCADE
13 // commercial license or contractual agreement.
15 #include <BRepMesh_ShapeTool.hxx>
17 #include <Bnd_Box.hxx>
18 #include <TopoDS_Edge.hxx>
19 #include <BRepBndLib.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>
26 #include <BRep_Builder.hxx>
29 //! Auxilary struct to take a tolerance of edge.
32 static Standard_Real Get(const TopoDS_Shape& theEdge)
34 return BRep_Tool::Tolerance(TopoDS::Edge(theEdge));
38 //! Auxilary struct to take a tolerance of vertex.
39 struct VertexTolerance
41 static Standard_Real Get(const TopoDS_Shape& theVertex)
43 return BRep_Tool::Tolerance(TopoDS::Vertex(theVertex));
47 //! Returns maximum tolerance of face element of the specified type.
48 template<TopAbs_ShapeEnum ShapeType, class ToleranceExtractor>
49 Standard_Real MaxTolerance(const TopoDS_Face& theFace)
51 Standard_Real aMaxTolerance = RealFirst();
52 TopExp_Explorer aExplorer(theFace, ShapeType);
53 for (; aExplorer.More(); aExplorer.Next())
55 Standard_Real aTolerance = ToleranceExtractor::Get(aExplorer.Current());
56 if (aTolerance > aMaxTolerance)
57 aMaxTolerance = aTolerance;
64 //=======================================================================
65 //function : BoxMaxDimension
67 //=======================================================================
68 Standard_Real BRepMesh_ShapeTool::MaxFaceTolerance(const TopoDS_Face& theFace)
70 Standard_Real aMaxTolerance = BRep_Tool::Tolerance(theFace);
72 Standard_Real aTolerance = Max(
73 MaxTolerance<TopAbs_EDGE, EdgeTolerance >(theFace),
74 MaxTolerance<TopAbs_VERTEX, VertexTolerance>(theFace));
76 return Max(aMaxTolerance, aTolerance);
79 //=======================================================================
80 //function : BoxMaxDimension
82 //=======================================================================
83 void BRepMesh_ShapeTool::BoxMaxDimension(const Bnd_Box& theBox,
84 Standard_Real& theMaxDimension)
89 Standard_Real aMinX, aMinY, aMinZ, aMaxX, aMaxY, aMaxZ;
90 theBox.Get(aMinX, aMinY, aMinZ, aMaxX, aMaxY, aMaxZ);
92 theMaxDimension = Max(aMaxX - aMinX, Max(aMaxY - aMinY, aMaxZ - aMinZ));
95 //=======================================================================
96 //function : RelativeEdgeDeflection
98 //=======================================================================
99 Standard_Real BRepMesh_ShapeTool::RelativeEdgeDeflection(
100 const TopoDS_Edge& theEdge,
101 const Standard_Real theDeflection,
102 const Standard_Real theMaxShapeSize,
103 Standard_Real& theAdjustmentCoefficient)
105 theAdjustmentCoefficient = 1.;
106 Standard_Real aDefEdge = theDeflection;
111 BRepBndLib::Add(theEdge, aBox);
112 BoxMaxDimension(aBox, aDefEdge);
114 // Adjust resulting value in relation to the total size
115 theAdjustmentCoefficient = theMaxShapeSize / (2 * aDefEdge);
116 if (theAdjustmentCoefficient < 0.5)
117 theAdjustmentCoefficient = 0.5;
118 else if (theAdjustmentCoefficient > 2.)
119 theAdjustmentCoefficient = 2.;
121 return (theAdjustmentCoefficient * aDefEdge * theDeflection);
124 //=======================================================================
127 //=======================================================================
128 gp_XY BRepMesh_ShapeTool::FindUV(
129 const Standard_Integer theIndexOfPnt3d,
130 const gp_Pnt2d& thePnt2d,
131 const TopoDS_Vertex& theVertex,
132 const Standard_Real theMinDistance,
133 const Handle(BRepMesh_FaceAttribute)& theFaceAttribute,
134 const Handle(BRepAdaptor_HSurface)& theSurface,
135 BRepMeshCol::DMapOfIntegerListOfXY& theLocation2dMap)
137 const gp_XY& aPnt2d = thePnt2d.Coord();
138 if (!theLocation2dMap.IsBound(theIndexOfPnt3d))
140 BRepMeshCol::ListOfXY aPoints2d;
141 aPoints2d.Append(aPnt2d);
142 theLocation2dMap.Bind(theIndexOfPnt3d, aPoints2d);
146 BRepMeshCol::ListOfXY& aPoints2d =
147 theLocation2dMap.ChangeFind(theIndexOfPnt3d);
149 // Find the most closest 2d point to the given one.
151 Standard_Real aMinDist = RealLast();
152 BRepMeshCol::ListOfXY::Iterator aPoint2dIt(aPoints2d);
153 for (; aPoint2dIt.More(); aPoint2dIt.Next())
155 const gp_XY& aCurPnt2d = aPoint2dIt.Value();
157 Standard_Real aDist = (aPnt2d - aCurPnt2d).Modulus();
158 if (aDist < aMinDist)
165 const Standard_Real aTolerance =
166 Min(2. * BRep_Tool::Tolerance(theVertex), theMinDistance);
169 Standard_Real aDiffU, aDiffV;
170 if (theFaceAttribute.IsNull())
172 aDiffU = theSurface->LastUParameter() - theSurface->FirstUParameter();
173 aDiffV = theSurface->LastVParameter() - theSurface->FirstVParameter();
177 aDiffU = theFaceAttribute->GetUMax() - theFaceAttribute->GetUMin();
178 aDiffV = theFaceAttribute->GetVMax() - theFaceAttribute->GetVMin();
181 const Standard_Real Utol2d = .5 * aDiffU;
182 const Standard_Real Vtol2d = .5 * aDiffV;
184 const gp_Pnt aPnt1 = theSurface->Value( aUV.X(), aUV.Y());
185 const gp_Pnt aPnt2 = theSurface->Value(aPnt2d.X(), aPnt2d.Y());
187 //! If selected point is too far from the given one in parametric space
188 //! or their positions in 3d are different, add the given point as unique.
189 if (Abs(aUV.X() - aPnt2d.X()) > Utol2d ||
190 Abs(aUV.Y() - aPnt2d.Y()) > Vtol2d ||
191 !aPnt1.IsEqual(aPnt2, aTolerance))
194 aPoints2d.Append(aUV);
200 //=======================================================================
201 //function : AddInFace
203 //=======================================================================
204 void BRepMesh_ShapeTool::AddInFace(
205 const TopoDS_Face& theFace,
206 Handle(Poly_Triangulation)& theTriangulation)
208 const TopLoc_Location& aLoc = theFace.Location();
209 if (!aLoc.IsIdentity())
211 gp_Trsf aTrsf = aLoc.Transformation();
214 TColgp_Array1OfPnt& aNodes = theTriangulation->ChangeNodes();
215 for (Standard_Integer i = aNodes.Lower(); i <= aNodes.Upper(); ++i)
216 aNodes(i).Transform(aTrsf);
219 BRep_Builder aBuilder;
220 aBuilder.UpdateFace(theFace, theTriangulation);
223 //=======================================================================
224 //function : NullifyFace
226 //=======================================================================
227 void BRepMesh_ShapeTool::NullifyFace(const TopoDS_Face& theFace)
229 BRep_Builder aBuilder;
230 aBuilder.UpdateFace(theFace, Handle(Poly_Triangulation)());
233 //=======================================================================
234 //function : NullifyEdge
236 //=======================================================================
237 void BRepMesh_ShapeTool::NullifyEdge(
238 const TopoDS_Edge& theEdge,
239 const Handle(Poly_Triangulation)& theTriangulation,
240 const TopLoc_Location& theLocation)
242 UpdateEdge(theEdge, Handle(Poly_PolygonOnTriangulation)(),
243 theTriangulation, theLocation);
246 //=======================================================================
247 //function : UpdateEdge
249 //=======================================================================
250 void BRepMesh_ShapeTool::UpdateEdge(
251 const TopoDS_Edge& theEdge,
252 const Handle(Poly_PolygonOnTriangulation)& thePolygon,
253 const Handle(Poly_Triangulation)& theTriangulation,
254 const TopLoc_Location& theLocation)
256 BRep_Builder aBuilder;
257 aBuilder.UpdateEdge(theEdge, thePolygon, theTriangulation, theLocation);
260 //=======================================================================
261 //function : UpdateEdge
263 //=======================================================================
264 void BRepMesh_ShapeTool::UpdateEdge(
265 const TopoDS_Edge& theEdge,
266 const Handle(Poly_PolygonOnTriangulation)& thePolygon1,
267 const Handle(Poly_PolygonOnTriangulation)& thePolygon2,
268 const Handle(Poly_Triangulation)& theTriangulation,
269 const TopLoc_Location& theLocation)
271 BRep_Builder aBuilder;
272 aBuilder.UpdateEdge(theEdge, thePolygon1, thePolygon2,
273 theTriangulation, theLocation);