0026586: Eliminate compile warnings obtained by building occt with vc14: declaration...
[occt.git] / src / BRepMesh / BRepMesh_EdgeTessellator.cxx
CommitLineData
ceb418e1 1// Created on: 2014-08-13
2// Created by: Oleg AGASHIN
3// Copyright (c) 2011-2014 OPEN CASCADE SAS
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_EdgeTessellator.hxx>
17#include <Geom_Surface.hxx>
18#include <Geom_Plane.hxx>
19#include <Geom2d_Curve.hxx>
20#include <TopoDS_Edge.hxx>
21#include <TopoDS_Face.hxx>
22#include <BRepAdaptor_HSurface.hxx>
23#include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
24#include <TopLoc_Location.hxx>
25#include <BRep_Tool.hxx>
26#include <TColStd_Array1OfReal.hxx>
27#include <TopExp_Explorer.hxx>
28#include <TopoDS_Vertex.hxx>
29#include <TopoDS.hxx>
30#include <TopTools_ListIteratorOfListOfShape.hxx>
31#include <TopTools_ListOfShape.hxx>
32#include <TColStd_Array1OfReal.hxx>
33
ceb418e1 34
35//=======================================================================
36//function : Constructor
37//purpose :
38//=======================================================================
39BRepMesh_EdgeTessellator::BRepMesh_EdgeTessellator(
40 const TopoDS_Edge& theEdge,
41 const Handle(BRepMesh_FaceAttribute)& theFaceAttribute,
42 const TopTools_IndexedDataMapOfShapeListOfShape& theMapOfSharedFaces,
43 const Standard_Real theLinDeflection,
74da0216 44 const Standard_Real theAngDeflection,
45 const Standard_Real theMinSize)
ceb418e1 46 : mySurface(theFaceAttribute->Surface())
47{
48 Standard_Real aPreciseAngDef = 0.5 * theAngDeflection;
49 Standard_Real aPreciseLinDef = 0.5 * theLinDeflection;
50 if (theEdge.Orientation() == TopAbs_INTERNAL)
51 aPreciseLinDef *= 0.5;
52
53 mySquareEdgeDef = aPreciseLinDef * aPreciseLinDef;
74da0216 54 mySquareMinSize = Max(mySquareEdgeDef, theMinSize * theMinSize);
ceb418e1 55
56 Standard_Boolean isSameParam = BRep_Tool::SameParameter(theEdge);
57 if (isSameParam)
58 myCOnS.Initialize(theEdge);
59 else
60 myCOnS.Initialize(theEdge, theFaceAttribute->Face());
61
ceb418e1 62 const GeomAbs_CurveType aCurveType = myCOnS.GetType();
63 Standard_Integer aMinPntNb = (aCurveType == GeomAbs_Circle) ? 4 : 2; //OCC287
64
65 // Get range on 2d curve
66 Standard_Real aFirstParam, aLastParam;
67 BRep_Tool::Range(theEdge, theFaceAttribute->Face(), aFirstParam, aLastParam);
68 myTool = new BRepMesh_GeomTool(myCOnS, aFirstParam, aLastParam,
74da0216 69 aPreciseLinDef, aPreciseAngDef, aMinPntNb, theMinSize);
ceb418e1 70
71 if (aCurveType == GeomAbs_BSplineCurve)
72 {
77e39787 73 // bug24220
ceb418e1 74 const Standard_Integer aNbInt = myCOnS.NbIntervals(GeomAbs_C1);
75 if ( aNbInt > 0 )
76 {
77 TColStd_Array1OfReal anIntervals( 1, aNbInt + 1 );
78 myCOnS.Intervals(anIntervals, GeomAbs_C1);
79 for (Standard_Integer aIntIt = 1; aIntIt <= aNbInt; ++aIntIt)
80 {
81 const Standard_Real& aStartInt = anIntervals.Value( aIntIt );
82 const Standard_Real& anEndInt = anIntervals.Value( aIntIt + 1 );
83
84 BRepMesh_GeomTool aDetalizator(myCOnS, aStartInt, anEndInt,
74da0216 85 aPreciseLinDef, aPreciseAngDef, aMinPntNb, theMinSize);
ceb418e1 86
87 Standard_Integer aNbAddNodes = aDetalizator.NbPoints();
88 for ( Standard_Integer aNodeIt = 1; aNodeIt <= aNbAddNodes; ++aNodeIt )
89 {
90 Standard_Real aParam;
91 gp_Pnt aPoint3d;
92 gp_Pnt2d aPoint2d;
93 aDetalizator.Value( aNodeIt, mySurface, aParam, aPoint3d, aPoint2d );
94 myTool->AddPoint( aPoint3d, aParam, Standard_False );
95 }
96 }
97 }
98 }
77e39787 99
ceb418e1 100 // PTv, chl/922/G9, Take into account internal vertices
101 // it is necessary for internal edges, which do not split other edges, by their vertex
102 TopExp_Explorer aVertexIt(theEdge, TopAbs_VERTEX);
103 for (; aVertexIt.More(); aVertexIt.Next())
104 {
105 const TopoDS_Vertex& aVertex = TopoDS::Vertex(aVertexIt.Current());
106 if (aVertex.Orientation() != TopAbs_INTERNAL)
107 continue;
108
109 myTool->AddPoint(BRep_Tool::Pnt(aVertex),
110 BRep_Tool::Parameter(aVertex, theEdge), Standard_True);
111 }
112
113 Standard_Integer aNodesNb = myTool->NbPoints();
114 //Check deflection in 2d space for improvement of edge tesselation.
115 if( isSameParam && aNodesNb > 1)
116 {
117 const TopTools_ListOfShape& aSharedFaces = theMapOfSharedFaces.FindFromKey(theEdge);
118 TopTools_ListIteratorOfListOfShape aFaceIt(aSharedFaces);
119 for (; aFaceIt.More(); aFaceIt.Next())
120 {
121 TopLoc_Location aLoc;
122 const TopoDS_Face& aFace = TopoDS::Face(aFaceIt.Value());
123 Handle(Geom_Surface) aSurf = BRep_Tool::Surface(aFace, aLoc);
124
125 if (aSurf->IsInstance(STANDARD_TYPE(Geom_Plane)))
126 continue;
127
128 Standard_Real aF, aL;
129 Handle(Geom2d_Curve) aCurve2d = BRep_Tool::CurveOnSurface(theEdge, aFace, aF, aL);
130 if ( Abs(aF - aFirstParam) > Precision::PConfusion() ||
131 Abs(aL - aLastParam ) > Precision::PConfusion() )
132 {
133 continue;
134 }
135
136 aNodesNb = myTool->NbPoints();
137 TColStd_Array1OfReal aParamArray(1, aNodesNb);
138 for (Standard_Integer i = 1; i <= aNodesNb; ++i)
139 {
140 gp_Pnt2d aTmpUV;
141 gp_Pnt aTmpPnt;
142 Standard_Real aParam;
143 myTool->Value(i, mySurface, aParam, aTmpPnt, aTmpUV);
144 aParamArray.SetValue(i, aParam);
145 }
146
147 for (Standard_Integer i = 1; i < aNodesNb; ++i)
148 splitSegment(aSurf, aCurve2d, aParamArray(i), aParamArray(i + 1), 1);
149 }
150 }
151}
152
153//=======================================================================
154//function : Value
155//purpose :
156//=======================================================================
157void BRepMesh_EdgeTessellator::Value(const Standard_Integer theIndex,
158 Standard_Real& theParameter,
159 gp_Pnt& thePoint,
160 gp_Pnt2d& theUV)
161{
162 myTool->Value(theIndex, mySurface, theParameter, thePoint, theUV);
163}
164
165//=======================================================================
166//function : splitSegment
167//purpose :
168//=======================================================================
169void BRepMesh_EdgeTessellator::splitSegment(
170 const Handle(Geom_Surface)& theSurf,
171 const Handle(Geom2d_Curve)& theCurve2d,
172 const Standard_Real theFirst,
173 const Standard_Real theLast,
174 const Standard_Integer theNbIter)
175{
176 // limit iteration depth
177 if(theNbIter > 10)
178 return;
179
180 gp_Pnt2d uvf, uvl, uvm;
181 gp_Pnt P3dF, P3dL, midP3d, midP3dFromSurf;
182 Standard_Real midpar;
183
184 if(Abs(theLast - theFirst) < 2 * Precision::PConfusion())
185 return;
186
187 theCurve2d->D0(theFirst, uvf);
188 theCurve2d->D0(theLast, uvl);
189
190 P3dF = theSurf->Value(uvf.X(), uvf.Y());
191 P3dL = theSurf->Value(uvl.X(), uvl.Y());
192
74da0216 193 if(P3dF.SquareDistance(P3dL) < mySquareMinSize)
ceb418e1 194 return;
195
196 uvm = gp_Pnt2d((uvf.XY() + uvl.XY())*0.5);
197 midP3dFromSurf = theSurf->Value(uvm.X(), uvm.Y());
198
74da0216 199 gp_XYZ Vec1 = midP3dFromSurf.XYZ() - P3dF.XYZ();
200 if(Vec1.SquareModulus() < mySquareMinSize)
201 return;
202
ceb418e1 203 gp_XYZ aVec = P3dL.XYZ() - P3dF.XYZ();
204 aVec.Normalize();
205
ceb418e1 206 Standard_Real aModulus = Vec1.Dot(aVec);
207 gp_XYZ aProj = aVec * aModulus;
208 gp_XYZ aDist = Vec1 - aProj;
209
210 if(aDist.SquareModulus() < mySquareEdgeDef)
211 return;
212
213 midpar = (theFirst + theLast) * 0.5;
214 myCOnS.D0(midpar, midP3d);
215 myTool->AddPoint(midP3d, midpar, Standard_False);
216
217 splitSegment(theSurf, theCurve2d, theFirst, midpar, theNbIter + 1);
218 splitSegment(theSurf, theCurve2d, midpar, theLast, theNbIter + 1);
219}