0027961: Visualization - remove unused and no more working OpenGl_AVIWriter
[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>
81093856 20#include <Geom2dAdaptor_Curve.hxx>
ceb418e1 21#include <TopoDS_Edge.hxx>
22#include <TopoDS_Face.hxx>
23#include <BRepAdaptor_HSurface.hxx>
24#include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
25#include <TopLoc_Location.hxx>
26#include <BRep_Tool.hxx>
27#include <TColStd_Array1OfReal.hxx>
28#include <TopExp_Explorer.hxx>
29#include <TopoDS_Vertex.hxx>
30#include <TopoDS.hxx>
31#include <TopTools_ListIteratorOfListOfShape.hxx>
32#include <TopTools_ListOfShape.hxx>
33#include <TColStd_Array1OfReal.hxx>
34
ceb418e1 35
92efcf78 36IMPLEMENT_STANDARD_RTTIEXT(BRepMesh_EdgeTessellator,BRepMesh_IEdgeTool)
37
ceb418e1 38//=======================================================================
39//function : Constructor
40//purpose :
41//=======================================================================
42BRepMesh_EdgeTessellator::BRepMesh_EdgeTessellator(
43 const TopoDS_Edge& theEdge,
44 const Handle(BRepMesh_FaceAttribute)& theFaceAttribute,
45 const TopTools_IndexedDataMapOfShapeListOfShape& theMapOfSharedFaces,
46 const Standard_Real theLinDeflection,
74da0216 47 const Standard_Real theAngDeflection,
48 const Standard_Real theMinSize)
ceb418e1 49 : mySurface(theFaceAttribute->Surface())
50{
51 Standard_Real aPreciseAngDef = 0.5 * theAngDeflection;
52 Standard_Real aPreciseLinDef = 0.5 * theLinDeflection;
53 if (theEdge.Orientation() == TopAbs_INTERNAL)
54 aPreciseLinDef *= 0.5;
55
56 mySquareEdgeDef = aPreciseLinDef * aPreciseLinDef;
74da0216 57 mySquareMinSize = Max(mySquareEdgeDef, theMinSize * theMinSize);
660b601e 58 myEdgeSqTol = BRep_Tool::Tolerance (theEdge);
59 myEdgeSqTol *= myEdgeSqTol;
ceb418e1 60
61 Standard_Boolean isSameParam = BRep_Tool::SameParameter(theEdge);
62 if (isSameParam)
63 myCOnS.Initialize(theEdge);
64 else
65 myCOnS.Initialize(theEdge, theFaceAttribute->Face());
66
ceb418e1 67 const GeomAbs_CurveType aCurveType = myCOnS.GetType();
68 Standard_Integer aMinPntNb = (aCurveType == GeomAbs_Circle) ? 4 : 2; //OCC287
69
81093856 70 // Get 2d curve and init geom tool
ceb418e1 71 Standard_Real aFirstParam, aLastParam;
81093856 72 Handle(Geom2d_Curve) aCurve2d =
73 BRep_Tool::CurveOnSurface(theEdge, theFaceAttribute->Face(), aFirstParam, aLastParam);
74 myCurve2d.Load(aCurve2d, aFirstParam, aLastParam);
ceb418e1 75 myTool = new BRepMesh_GeomTool(myCOnS, aFirstParam, aLastParam,
74da0216 76 aPreciseLinDef, aPreciseAngDef, aMinPntNb, theMinSize);
ceb418e1 77
78 if (aCurveType == GeomAbs_BSplineCurve)
79 {
77e39787 80 // bug24220
ceb418e1 81 const Standard_Integer aNbInt = myCOnS.NbIntervals(GeomAbs_C1);
82 if ( aNbInt > 0 )
83 {
84 TColStd_Array1OfReal anIntervals( 1, aNbInt + 1 );
85 myCOnS.Intervals(anIntervals, GeomAbs_C1);
86 for (Standard_Integer aIntIt = 1; aIntIt <= aNbInt; ++aIntIt)
87 {
88 const Standard_Real& aStartInt = anIntervals.Value( aIntIt );
89 const Standard_Real& anEndInt = anIntervals.Value( aIntIt + 1 );
90
91 BRepMesh_GeomTool aDetalizator(myCOnS, aStartInt, anEndInt,
74da0216 92 aPreciseLinDef, aPreciseAngDef, aMinPntNb, theMinSize);
ceb418e1 93
94 Standard_Integer aNbAddNodes = aDetalizator.NbPoints();
95 for ( Standard_Integer aNodeIt = 1; aNodeIt <= aNbAddNodes; ++aNodeIt )
96 {
97 Standard_Real aParam;
98 gp_Pnt aPoint3d;
99 gp_Pnt2d aPoint2d;
81093856 100 aDetalizator.Value( aNodeIt, aParam, aPoint3d);
101 myCurve2d.D0(aParam, aPoint2d);
102
ceb418e1 103 myTool->AddPoint( aPoint3d, aParam, Standard_False );
104 }
105 }
106 }
107 }
77e39787 108
ceb418e1 109 // PTv, chl/922/G9, Take into account internal vertices
110 // it is necessary for internal edges, which do not split other edges, by their vertex
111 TopExp_Explorer aVertexIt(theEdge, TopAbs_VERTEX);
112 for (; aVertexIt.More(); aVertexIt.Next())
113 {
114 const TopoDS_Vertex& aVertex = TopoDS::Vertex(aVertexIt.Current());
115 if (aVertex.Orientation() != TopAbs_INTERNAL)
116 continue;
117
118 myTool->AddPoint(BRep_Tool::Pnt(aVertex),
119 BRep_Tool::Parameter(aVertex, theEdge), Standard_True);
120 }
121
122 Standard_Integer aNodesNb = myTool->NbPoints();
123 //Check deflection in 2d space for improvement of edge tesselation.
124 if( isSameParam && aNodesNb > 1)
125 {
126 const TopTools_ListOfShape& aSharedFaces = theMapOfSharedFaces.FindFromKey(theEdge);
127 TopTools_ListIteratorOfListOfShape aFaceIt(aSharedFaces);
128 for (; aFaceIt.More(); aFaceIt.Next())
129 {
81093856 130 const TopoDS_Face& aFace = TopoDS::Face(aFaceIt.Value());
131 BRepAdaptor_Surface aSurf(aFace, Standard_False);
ceb418e1 132
81093856 133 if (aSurf.GetType() == GeomAbs_Plane)
ceb418e1 134 continue;
135
136 Standard_Real aF, aL;
6482df81 137 aCurve2d = BRep_Tool::CurveOnSurface(theEdge, aFace, aF, aL);
ceb418e1 138 if ( Abs(aF - aFirstParam) > Precision::PConfusion() ||
139 Abs(aL - aLastParam ) > Precision::PConfusion() )
140 {
141 continue;
142 }
81093856 143 Geom2dAdaptor_Curve aGACurve(aCurve2d, aF, aL);
ceb418e1 144
145 aNodesNb = myTool->NbPoints();
146 TColStd_Array1OfReal aParamArray(1, aNodesNb);
147 for (Standard_Integer i = 1; i <= aNodesNb; ++i)
148 {
ceb418e1 149 gp_Pnt aTmpPnt;
150 Standard_Real aParam;
81093856 151 myTool->Value(i, aParam, aTmpPnt);
ceb418e1 152 aParamArray.SetValue(i, aParam);
153 }
154
155 for (Standard_Integer i = 1; i < aNodesNb; ++i)
81093856 156 splitSegment(aSurf, aGACurve, aParamArray(i), aParamArray(i + 1), 1);
ceb418e1 157 }
158 }
660b601e 159
160 const Standard_Real aTol = Precision::Confusion();
161 const Standard_Real aDu = mySurface->UResolution (aTol);
162 const Standard_Real aDv = mySurface->VResolution (aTol);
163
164 myFaceRangeU[0] = mySurface->FirstUParameter() - aDu;
165 myFaceRangeU[1] = mySurface->LastUParameter() + aDu;
166
167 myFaceRangeV[0] = mySurface->FirstVParameter() - aDv;
168 myFaceRangeV[1] = mySurface->LastVParameter() + aDv;
ceb418e1 169}
170
171//=======================================================================
172//function : Value
173//purpose :
174//=======================================================================
660b601e 175Standard_Boolean BRepMesh_EdgeTessellator::Value(
176 const Standard_Integer theIndex,
177 Standard_Real& theParameter,
178 gp_Pnt& thePoint,
179 gp_Pnt2d& theUV)
ceb418e1 180{
81093856 181 myTool->Value(theIndex, theParameter, thePoint);
182 myCurve2d.D0(theParameter, theUV);
660b601e 183
184 // If point coordinates are out of surface range,
185 // it is necessary to re-project point.
186 if (mySurface->GetType() != GeomAbs_BSplineSurface &&
187 mySurface->GetType() != GeomAbs_BezierSurface &&
188 mySurface->GetType() != GeomAbs_OtherSurface)
189 {
190 return Standard_True;
191 }
192
193 // Let skip periodic case.
194 if (mySurface->IsUPeriodic() || mySurface->IsVPeriodic())
195 return Standard_True;
196
197 // Point lies within the surface range - nothing to do.
198 if (theUV.X() > myFaceRangeU[0] && theUV.X() < myFaceRangeU[1] &&
199 theUV.Y() > myFaceRangeV[0] && theUV.Y() < myFaceRangeV[1])
200 {
201 return Standard_True;
202 }
203
204 gp_Pnt aPntOnSurf;
205 mySurface->D0 (theUV.X (), theUV.Y (), aPntOnSurf);
206
207 return (thePoint.SquareDistance (aPntOnSurf) < myEdgeSqTol);
ceb418e1 208}
209
210//=======================================================================
211//function : splitSegment
212//purpose :
213//=======================================================================
214void BRepMesh_EdgeTessellator::splitSegment(
81093856 215 const Adaptor3d_Surface& theSurf,
216 const Geom2dAdaptor_Curve& theCurve2d,
ceb418e1 217 const Standard_Real theFirst,
218 const Standard_Real theLast,
219 const Standard_Integer theNbIter)
220{
221 // limit iteration depth
222 if(theNbIter > 10)
223 return;
224
225 gp_Pnt2d uvf, uvl, uvm;
226 gp_Pnt P3dF, P3dL, midP3d, midP3dFromSurf;
227 Standard_Real midpar;
228
229 if(Abs(theLast - theFirst) < 2 * Precision::PConfusion())
230 return;
231
81093856 232 theCurve2d.D0(theFirst, uvf);
233 theCurve2d.D0(theLast, uvl);
ceb418e1 234
81093856 235 P3dF = theSurf.Value(uvf.X(), uvf.Y());
236 P3dL = theSurf.Value(uvl.X(), uvl.Y());
ceb418e1 237
74da0216 238 if(P3dF.SquareDistance(P3dL) < mySquareMinSize)
ceb418e1 239 return;
240
241 uvm = gp_Pnt2d((uvf.XY() + uvl.XY())*0.5);
81093856 242 midP3dFromSurf = theSurf.Value(uvm.X(), uvm.Y());
ceb418e1 243
74da0216 244 gp_XYZ Vec1 = midP3dFromSurf.XYZ() - P3dF.XYZ();
245 if(Vec1.SquareModulus() < mySquareMinSize)
246 return;
247
ceb418e1 248 gp_XYZ aVec = P3dL.XYZ() - P3dF.XYZ();
249 aVec.Normalize();
250
ceb418e1 251 Standard_Real aModulus = Vec1.Dot(aVec);
252 gp_XYZ aProj = aVec * aModulus;
253 gp_XYZ aDist = Vec1 - aProj;
254
255 if(aDist.SquareModulus() < mySquareEdgeDef)
256 return;
257
258 midpar = (theFirst + theLast) * 0.5;
259 myCOnS.D0(midpar, midP3d);
260 myTool->AddPoint(midP3d, midpar, Standard_False);
261
262 splitSegment(theSurf, theCurve2d, theFirst, midpar, theNbIter + 1);
263 splitSegment(theSurf, theCurve2d, midpar, theLast, theNbIter + 1);
264}