1 // Created on: 2016-07-07
2 // Copyright (c) 2016 OPEN CASCADE SAS
3 // Created by: Oleg AGASHIN
5 // This file is part of Open CASCADE Technology software library.
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.
13 // Alternatively, this file may be used under the terms of Open CASCADE
14 // commercial license or contractual agreement.
16 #include <BRepMesh_DefaultRangeSplitter.hxx>
18 #include <GCPnts_AbscissaPoint.hxx>
19 #include <GeomAdaptor_Curve.hxx>
20 #include <GeomAbs_IsoType.hxx>
21 #include <BRep_Tool.hxx>
23 //=======================================================================
26 //=======================================================================
27 void BRepMesh_DefaultRangeSplitter::Reset(const IMeshData::IFaceHandle& theDFace,
28 const IMeshTools_Parameters& /*theParameters*/)
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();
37 //=======================================================================
40 //=======================================================================
41 void BRepMesh_DefaultRangeSplitter::AddPoint(const gp_Pnt2d& thePoint)
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);
49 //=======================================================================
50 // Function: AdjustRange
52 //=======================================================================
53 void BRepMesh_DefaultRangeSplitter::AdjustRange()
55 const Handle(BRepAdaptor_HSurface)& aSurface = GetSurface();
56 updateRange(aSurface->FirstUParameter(), aSurface->LastUParameter(),
57 aSurface->IsUPeriodic(), myRangeU.first, myRangeU.second);
59 if (myRangeU.second < myRangeU.first)
61 myIsValid = Standard_False;
65 updateRange(aSurface->FirstVParameter(), aSurface->LastVParameter(),
66 aSurface->IsVPeriodic(), myRangeV.first, myRangeV.second);
68 if (myRangeV.second < myRangeV.first)
70 myIsValid = Standard_False;
74 const Standard_Real aLengthU = computeLengthU();
75 const Standard_Real aLengthV = computeLengthV();
76 myIsValid = aLengthU > Precision::PConfusion () && aLengthV > Precision::PConfusion ();
80 computeTolerance(aLengthU, aLengthV);
81 computeDelta (aLengthU, aLengthV);
85 //=======================================================================
88 //=======================================================================
89 Standard_Boolean BRepMesh_DefaultRangeSplitter::IsValid()
94 //=======================================================================
97 //=======================================================================
98 gp_Pnt2d BRepMesh_DefaultRangeSplitter::Scale(const gp_Pnt2d& thePoint,
99 const Standard_Boolean isToFaceBasis) const
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);
108 //=======================================================================
109 // Function: GenerateSurfaceNodes
111 //=======================================================================
112 Handle(IMeshData::ListOfPnt2d) BRepMesh_DefaultRangeSplitter::GenerateSurfaceNodes(
113 const IMeshTools_Parameters& /*theParameters*/) const
115 return Handle(IMeshData::ListOfPnt2d)();
118 //=======================================================================
119 // Function: computeTolerance
121 //=======================================================================
122 void BRepMesh_DefaultRangeSplitter::computeTolerance(
123 const Standard_Real /*theLenU*/,
124 const Standard_Real /*theLenV*/)
126 const Standard_Real aDiffU = myRangeU.second - myRangeU.first;
127 const Standard_Real aDiffV = myRangeV.second - myRangeV.first;
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);
134 const Standard_Real aDeflectionUV = 1.e-05;
135 myTolerance.first = Max(Min(aDeflectionUV, aResU), 1e-7 * aDiffU);
136 myTolerance.second = Max(Min(aDeflectionUV, aResV), 1e-7 * aDiffV);
139 //=======================================================================
140 // Function: computeDelta
142 //=======================================================================
143 void BRepMesh_DefaultRangeSplitter::computeDelta(
144 const Standard_Real theLengthU,
145 const Standard_Real theLengthV)
147 const Standard_Real aDiffU = myRangeU.second - myRangeU.first;
148 const Standard_Real aDiffV = myRangeV.second - myRangeV.first;
150 myDelta.first = aDiffU / (theLengthU < myTolerance.first ? 1. : theLengthU);
151 myDelta.second = aDiffV / (theLengthV < myTolerance.second ? 1. : theLengthV);
154 //=======================================================================
155 // Function: computeLengthU
157 //=======================================================================
158 Standard_Real BRepMesh_DefaultRangeSplitter::computeLengthU()
160 Standard_Real longu = 0.0;
161 gp_Pnt P11, P12, P21, P22, P31, P32;
163 Standard_Real du = 0.05 * (myRangeU.second - myRangeU.first);
164 Standard_Real dfvave = 0.5 * (myRangeV.second + myRangeV.first);
165 Standard_Real dfucur;
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)
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));
186 //=======================================================================
187 // Function: computeLengthV
189 //=======================================================================
190 Standard_Real BRepMesh_DefaultRangeSplitter::computeLengthV()
192 Standard_Real longv = 0.0;
193 gp_Pnt P11, P12, P21, P22, P31, P32;
195 Standard_Real dv = 0.05 * (myRangeV.second - myRangeV.first);
196 Standard_Real dfuave = 0.5 * (myRangeU.second + myRangeU.first);
197 Standard_Real dfvcur;
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)
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));
218 //=======================================================================
219 // Function: updateRange
221 //=======================================================================
222 void 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)
229 if (theDiscreteFirst < theGeomFirst ||
230 theDiscreteLast > theGeomLast)
234 if ((theDiscreteLast - theDiscreteFirst) > (theGeomLast - theGeomFirst))
236 theDiscreteLast = theDiscreteFirst + (theGeomLast - theGeomFirst);
241 if ((theDiscreteFirst < theGeomLast) && (theDiscreteLast > theGeomFirst))
243 //Protection against the faces whose pcurve is out of the surface's domain
244 //(see issue #23675 and test cases "bugs iges buc60820*")
246 if (theGeomFirst > theDiscreteFirst)
248 theDiscreteFirst = theGeomFirst;
251 if (theGeomLast < theDiscreteLast)
253 theDiscreteLast = theGeomLast;