0031668: Visualization - WebGL sample doesn't work on Emscripten 1.39
[occt.git] / src / BRepMesh / BRepMesh_DefaultRangeSplitter.cxx
CommitLineData
7bd071ed 1// Created on: 2016-07-07
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_DefaultRangeSplitter.hxx>
17
18#include <GCPnts_AbscissaPoint.hxx>
19#include <GeomAdaptor_Curve.hxx>
20#include <GeomAbs_IsoType.hxx>
936ce1f2 21#include <BRep_Tool.hxx>
7bd071ed 22
23//=======================================================================
24// Function: Reset
25// Purpose :
26//=======================================================================
27void BRepMesh_DefaultRangeSplitter::Reset(const IMeshData::IFaceHandle& theDFace,
28 const IMeshTools_Parameters& /*theParameters*/)
29{
30 myDFace = theDFace;
31 myRangeU.first = myRangeV.first = 1.e100;
32 myRangeU.second = myRangeV.second = -1.e100;
33 myDelta.first = myDelta.second = 1.;
34 myTolerance.first = myTolerance.second = Precision::Confusion();
35}
36
37//=======================================================================
38// Function: AddPoint
39// Purpose :
40//=======================================================================
41void BRepMesh_DefaultRangeSplitter::AddPoint(const gp_Pnt2d& thePoint)
42{
43 myRangeU.first = Min(thePoint.X(), myRangeU.first);
44 myRangeU.second = Max(thePoint.X(), myRangeU.second);
45 myRangeV.first = Min(thePoint.Y(), myRangeV.first);
46 myRangeV.second = Max(thePoint.Y(), myRangeV.second);
47}
48
49//=======================================================================
50// Function: AdjustRange
51// Purpose :
52//=======================================================================
53void BRepMesh_DefaultRangeSplitter::AdjustRange()
54{
55 const Handle(BRepAdaptor_HSurface)& aSurface = GetSurface();
56 updateRange(aSurface->FirstUParameter(), aSurface->LastUParameter(),
57 aSurface->IsUPeriodic(), myRangeU.first, myRangeU.second);
58
59 if (myRangeU.second < myRangeU.first)
60 {
61 myIsValid = Standard_False;
62 return;
63 }
64
65 updateRange(aSurface->FirstVParameter(), aSurface->LastVParameter(),
66 aSurface->IsVPeriodic(), myRangeV.first, myRangeV.second);
67
68 if (myRangeV.second < myRangeV.first)
69 {
70 myIsValid = Standard_False;
71 return;
72 }
73
74 const Standard_Real aLengthU = computeLengthU();
75 const Standard_Real aLengthV = computeLengthV();
76 myIsValid = aLengthU > Precision::PConfusion () && aLengthV > Precision::PConfusion ();
77
78 if (myIsValid)
79 {
80 computeTolerance(aLengthU, aLengthV);
81 computeDelta (aLengthU, aLengthV);
82 }
83}
84
85//=======================================================================
86// Function: IsValid
87// Purpose :
88//=======================================================================
89Standard_Boolean BRepMesh_DefaultRangeSplitter::IsValid()
90{
91 return myIsValid;
92}
93
94//=======================================================================
95// Function: Scale
96// Purpose :
97//=======================================================================
98gp_Pnt2d BRepMesh_DefaultRangeSplitter::Scale(const gp_Pnt2d& thePoint,
99 const Standard_Boolean isToFaceBasis) const
100{
101 return isToFaceBasis ?
102 gp_Pnt2d ((thePoint.X () - myRangeU.first) / myDelta.first,
103 (thePoint.Y () - myRangeV.first) / myDelta.second) :
104 gp_Pnt2d (thePoint.X () * myDelta.first + myRangeU.first,
105 thePoint.Y () * myDelta.second + myRangeV.first);
106}
107
108//=======================================================================
109// Function: GenerateSurfaceNodes
110// Purpose :
111//=======================================================================
112Handle(IMeshData::ListOfPnt2d) BRepMesh_DefaultRangeSplitter::GenerateSurfaceNodes(
113 const IMeshTools_Parameters& /*theParameters*/) const
114{
115 return Handle(IMeshData::ListOfPnt2d)();
116}
117
118//=======================================================================
119// Function: computeTolerance
120// Purpose :
121//=======================================================================
122void BRepMesh_DefaultRangeSplitter::computeTolerance(
123 const Standard_Real /*theLenU*/,
124 const Standard_Real /*theLenV*/)
125{
126 const Standard_Real aDiffU = myRangeU.second - myRangeU.first;
127 const Standard_Real aDiffV = myRangeV.second - myRangeV.first;
128
936ce1f2 129 const Standard_Real aTolerance = BRep_Tool::Tolerance (myDFace->GetFace());
130 const Adaptor3d_Surface& aSurface = GetSurface()->Surface();
131 const Standard_Real aResU = aSurface.UResolution (aTolerance);
132 const Standard_Real aResV = aSurface.VResolution (aTolerance);
133
7bd071ed 134 const Standard_Real aDeflectionUV = 1.e-05;
936ce1f2 135 myTolerance.first = Max(Min(aDeflectionUV, aResU), 1e-7 * aDiffU);
136 myTolerance.second = Max(Min(aDeflectionUV, aResV), 1e-7 * aDiffV);
7bd071ed 137}
138
139//=======================================================================
140// Function: computeDelta
141// Purpose :
142//=======================================================================
143void BRepMesh_DefaultRangeSplitter::computeDelta(
144 const Standard_Real theLengthU,
145 const Standard_Real theLengthV)
146{
147 const Standard_Real aDiffU = myRangeU.second - myRangeU.first;
148 const Standard_Real aDiffV = myRangeV.second - myRangeV.first;
149
150 myDelta.first = aDiffU / (theLengthU < myTolerance.first ? 1. : theLengthU);
151 myDelta.second = aDiffV / (theLengthV < myTolerance.second ? 1. : theLengthV);
152}
153
154//=======================================================================
155// Function: computeLengthU
156// Purpose :
157//=======================================================================
158Standard_Real BRepMesh_DefaultRangeSplitter::computeLengthU()
159{
160 Standard_Real longu = 0.0;
161 gp_Pnt P11, P12, P21, P22, P31, P32;
162
163 Standard_Real du = 0.05 * (myRangeU.second - myRangeU.first);
164 Standard_Real dfvave = 0.5 * (myRangeV.second + myRangeV.first);
165 Standard_Real dfucur;
166 Standard_Integer i1;
167
168 const Handle(BRepAdaptor_HSurface)& gFace = GetSurface();
169 gFace->D0(myRangeU.first, myRangeV.first, P11);
170 gFace->D0(myRangeU.first, dfvave, P21);
171 gFace->D0(myRangeU.first, myRangeV.second, P31);
172 for (i1 = 1, dfucur = myRangeU.first + du; i1 <= 20; i1++, dfucur += du)
173 {
174 gFace->D0(dfucur, myRangeV.first, P12);
175 gFace->D0(dfucur, dfvave, P22);
176 gFace->D0(dfucur, myRangeV.second, P32);
177 longu += (P11.Distance(P12) + P21.Distance(P22) + P31.Distance(P32));
178 P11 = P12;
179 P21 = P22;
180 P31 = P32;
181 }
182
183 return longu / 3.;
184}
185
186//=======================================================================
187// Function: computeLengthV
188// Purpose :
189//=======================================================================
190Standard_Real BRepMesh_DefaultRangeSplitter::computeLengthV()
191{
192 Standard_Real longv = 0.0;
193 gp_Pnt P11, P12, P21, P22, P31, P32;
194
195 Standard_Real dv = 0.05 * (myRangeV.second - myRangeV.first);
196 Standard_Real dfuave = 0.5 * (myRangeU.second + myRangeU.first);
197 Standard_Real dfvcur;
198 Standard_Integer i1;
199
200 const Handle(BRepAdaptor_HSurface)& gFace = GetSurface();
201 gFace->D0(myRangeU.first, myRangeV.first, P11);
202 gFace->D0(dfuave, myRangeV.first, P21);
203 gFace->D0(myRangeU.second, myRangeV.first, P31);
204 for (i1 = 1, dfvcur = myRangeV.first + dv; i1 <= 20; i1++, dfvcur += dv)
205 {
206 gFace->D0(myRangeU.first, dfvcur, P12);
207 gFace->D0(dfuave, dfvcur, P22);
208 gFace->D0(myRangeU.second, dfvcur, P32);
209 longv += (P11.Distance(P12) + P21.Distance(P22) + P31.Distance(P32));
210 P11 = P12;
211 P21 = P22;
212 P31 = P32;
213 }
214
215 return longv / 3.;
216}
217
218//=======================================================================
219// Function: updateRange
220// Purpose :
221//=======================================================================
222void BRepMesh_DefaultRangeSplitter::updateRange(
223 const Standard_Real theGeomFirst,
224 const Standard_Real theGeomLast,
225 const Standard_Boolean isPeriodic,
226 Standard_Real& theDiscreteFirst,
227 Standard_Real& theDiscreteLast)
228{
229 if (theDiscreteFirst < theGeomFirst ||
230 theDiscreteLast > theGeomLast)
231 {
232 if (isPeriodic)
233 {
234 if ((theDiscreteLast - theDiscreteFirst) > (theGeomLast - theGeomFirst))
235 {
236 theDiscreteLast = theDiscreteFirst + (theGeomLast - theGeomFirst);
237 }
238 }
239 else
240 {
241 if ((theDiscreteFirst < theGeomLast) && (theDiscreteLast > theGeomFirst))
242 {
243 //Protection against the faces whose pcurve is out of the surface's domain
244 //(see issue #23675 and test cases "bugs iges buc60820*")
245
246 if (theGeomFirst > theDiscreteFirst)
247 {
248 theDiscreteFirst = theGeomFirst;
249 }
250
251 if (theGeomLast < theDiscreteLast)
252 {
253 theDiscreteLast = theGeomLast;
254 }
255 }
256 }
257 }
258}