1 // Created by: Peter KURNEV
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 <IntTools_ShrunkRange.ixx>
17 #include <Precision.hxx>
20 #include <gp_Circ.hxx>
22 #include <Geom_Curve.hxx>
24 #include <BRep_Tool.hxx>
25 #include <BRepBuilderAPI_MakeVertex.hxx>
26 #include <BRepAdaptor_Curve.hxx>
27 #include <BndLib_Add3dCurve.hxx>
28 #include <IntTools_Context.hxx>
32 //=======================================================================
35 //=======================================================================
36 IntTools_ShrunkRange::IntTools_ShrunkRange ()
44 //=======================================================================
47 //=======================================================================
48 IntTools_ShrunkRange::~IntTools_ShrunkRange ()
51 //=======================================================================
54 //=======================================================================
55 void IntTools_ShrunkRange::SetData(const TopoDS_Edge& aE,
56 const Standard_Real aT1,
57 const Standard_Real aT2,
58 const TopoDS_Vertex& aV1,
59 const TopoDS_Vertex& aV2)
68 //=======================================================================
69 //function : SetContext
71 //=======================================================================
72 void IntTools_ShrunkRange::SetContext(const Handle(IntTools_Context)& aCtx)
76 //=======================================================================
79 //=======================================================================
80 const Handle(IntTools_Context)& IntTools_ShrunkRange::Context()const
84 //=======================================================================
87 //=======================================================================
88 const TopoDS_Edge& IntTools_ShrunkRange::Edge() const
92 //=======================================================================
93 //function : ShrunkRange
95 //=======================================================================
96 void IntTools_ShrunkRange::ShrunkRange(Standard_Real& aT1,
97 Standard_Real& aT2) const
102 //=======================================================================
105 //=======================================================================
106 const Bnd_Box& IntTools_ShrunkRange::BndBox() const
110 //=======================================================================
111 //function : ErrorStatus
113 //=======================================================================
114 Standard_Integer IntTools_ShrunkRange::ErrorStatus() const
116 return myErrorStatus;
119 //=======================================================================
120 //function : SetShrunkRange
122 //=======================================================================
123 void IntTools_ShrunkRange::SetShrunkRange(const Standard_Real aT1,
124 const Standard_Real aT2)
129 BRepAdaptor_Curve aBAC(myEdge);
130 BndLib_Add3dCurve::Add (aBAC, aT1, aT2, 0., myBndBox);
133 //=======================================================================
136 //=======================================================================
137 void IntTools_ShrunkRange::Perform()
139 Standard_Real aCF, aCL, aTolE, aTolV1;
140 Standard_Real aTolV2, t1, t11, t1C, t2, t12, t2C;
141 Standard_Real aCoeff1, aCoeff2, aTol1, aTol2, dt1, dt2, aR, anEps;
142 Standard_Integer pri;
143 Standard_Boolean bInf1, bInf2, bAppr;
144 GeomAbs_CurveType aCurveType;
145 Handle(Geom_Curve) aC;
152 aTolE =BRep_Tool::Tolerance(myEdge);
153 aTolV1=BRep_Tool::Tolerance(myV1);
154 aTolV2=BRep_Tool::Tolerance(myV2);
155 //for edges with the tolerance value
156 //more than the tolerance value of vertices
157 if (aTolV1 < aTolE) {
161 if (aTolV2 < aTolE) {
168 BRepAdaptor_Curve aBAC(myEdge);
169 aCurveType=aBAC.GetType();
171 aC=BRep_Tool::Curve(myEdge, aCF, aCL);
172 BRep_Tool::Range(myEdge, aCF, aCL);
174 if (t1 < aCF || t2 > aCL) {
179 bAppr = !(fabs(t2 - t1) > 100);
180 if (fabs(t2 - t1) < anEps) {
190 aTol1 = aTolV1+aTolE;
191 aTol2 = aTolV2+aTolE;
193 aCoeff1 = (aTolE>0.05) ? 1. : 2.;
196 aCoeff1=(aTol1>0.05) ? 1.5 : 2.;
197 aCoeff2=(aTol2>0.05) ? 1.5 : 2.;
200 if (aCurveType==GeomAbs_Line && (aCoeff1 != 1 || aCoeff2 != 1)) {
201 Standard_Real aTV1, aTV2, aEps;
202 gp_Pnt aPV1, aPV2, aPC1, aPC2;
205 aEps=Precision::Confusion();
206 aEps=aEps*aEps;//1.e-14;
209 aPV1=BRep_Tool::Pnt(myV1);
210 aTV1=ElCLib::Parameter(aL, aPV1);
212 aPV2=BRep_Tool::Pnt(myV2);
213 aTV2=ElCLib::Parameter(aL, aPV2);
215 if (fabs(aTV1-aCF)<aEps) {
218 if (fabs(aTV2-aCL)<aEps) {
227 if (aCurveType==GeomAbs_Line) {
228 Standard_Real dt1x, dt2x;
230 dt1x = aBAC.Resolution(dt1);
233 dt2x = aBAC.Resolution(dt2);
236 if (t11>t2 || t12<t1) {
243 Standard_Real ddx=aTolE;//1.e-12;
244 BndLib_Add3dCurve::Add (aBAC, t1C, t2C, ddx, myBndBox);
251 if (aCurveType==GeomAbs_Circle) {
252 gp_Circ aCrc=aBAC.Circle();
263 bInf1=Precision::IsNegativeInfinite(t1);
269 Standard_Real d1 = aCoeff1*aTol1;
270 // dt1 = aBAC.Resolution(d1);
274 aBAC.D1(t1, aPoint, aD1vec1);
275 Standard_Real ad1length1 = aD1vec1.Magnitude();
276 Standard_Boolean bTryOtherPoints = Standard_False;
277 dt1 = (t2 - t1) * 0.5;
279 if(ad1length1 > 1.e-12) {
280 dt1 = d1 / ad1length1;
282 if(dt1 > (t2 - t1)) {
283 // bad parametrization, big tolerance or too small range
284 bTryOtherPoints = Standard_True;
288 bTryOtherPoints = Standard_True;
291 if(bTryOtherPoints) {
292 Standard_Integer nbsamples = 5;
293 Standard_Integer ii = 0;
294 Standard_Real adelta = (t2 - t1) / (nbsamples + 1);
295 Standard_Boolean bFound = Standard_False;
297 for(ii = 1; ii <= nbsamples; ii++) {
298 Standard_Real aparameter = t1 + (adelta * ii);
300 aBAC.D1(aparameter, aPoint2, aD1vec1);
302 if(aPoint.Distance(aPoint2) < d1)
304 ad1length1 = aD1vec1.Magnitude();
306 if(ad1length1 > 1.e-12) {
307 dt1 = d1 / ad1length1;
309 if(dt1 < (t2 - t1)) {
310 bFound = Standard_True;
317 if(dt1 > (t2 - t1)) {
318 dt1 = aBAC.Resolution(d1);
329 gp_Vec aV11(aP1, aP11);
330 // avoid exception if aP1 == aP11
331 if (aV11.SquareMagnitude() < gp::Resolution())
338 aP1L.SetCoord (aP1.X()+d1*aD11.X(),
340 aP1.Z()+d1*aD11.Z());
342 BRepBuilderAPI_MakeVertex aMV1(aP1L);
343 const TopoDS_Vertex& aV1L=aMV1.Vertex();
345 pri=myCtx->ComputeVE (aV1L, myEdge, t1C);
358 bInf2=Precision::IsPositiveInfinite(t2);
364 Standard_Real d2 = aCoeff2*aTol2;
365 // dt2 = aBAC.Resolution(d2);
370 aBAC.D1(t2, aPoint, aD1vec2);
371 Standard_Real ad1length2 = aD1vec2.Magnitude();
372 Standard_Boolean bTryOtherPoints = Standard_False;
373 dt2 = (t2 - t1) * 0.5;
375 if(ad1length2 > 1.e-12) {
376 dt2 = d2 / ad1length2;
378 if(dt2 > (t2 - t1)) {
379 bTryOtherPoints = Standard_True;
383 bTryOtherPoints = Standard_True;
386 if(bTryOtherPoints) {
387 Standard_Integer nbsamples = 5;
388 Standard_Integer ii = 0;
389 Standard_Real adelta = (t2 - t1) / (nbsamples + 1);
390 Standard_Boolean bFound = Standard_False;
392 for(ii = 1; ii <= nbsamples; ii++) {
393 Standard_Real aparameter = t2 - (adelta * ii);
395 aBAC.D1(aparameter, aPoint2, aD1vec2);
397 if(aPoint.Distance(aPoint2) < d2)
399 ad1length2 = aD1vec2.Magnitude();
401 if(ad1length2 > 1.e-12) {
402 dt2 = d2 / ad1length2;
404 if(dt2 < (t2 - t1)) {
405 bFound = Standard_True;
412 if(dt2 > (t2 - t1)) {
413 dt2 = aBAC.Resolution(d2);
425 gp_Vec aV12(aP2, aP12);
426 // avoid exception if aP1 == aP11
427 if (aV12.SquareMagnitude() < gp::Resolution())
434 aP2L.SetCoord (aP2.X()+d2*aD12.X(),
436 aP2.Z()+d2*aD12.Z());
438 BRepBuilderAPI_MakeVertex aMV2(aP2L);
439 const TopoDS_Vertex& aV2L=aMV2.Vertex();
441 pri=myCtx->ComputeVE (aV2L, myEdge, t2C);
453 t2C=t1C+0.1*(t2-t1C);
457 t2C=t1C+0.1*(t2-t1C);
460 if (t2C-t1C < anEps) {
469 Standard_Real ddx=aTolE;//1.e-12;
470 BndLib_Add3dCurve::Add (aBAC, t1C, t2C, ddx, myBndBox);
472 /////////////////////////////////////////////////////////////////////////
476 // 1- Nothing has been done
477 // 2- The source range is out of the edge's range
478 // 3- t1 < t2 for source range
479 // 4- Can not project V1L to the Edge;
480 // 5- Can not project V2L to the Edge;
481 // 6- for obtained shrunk range [t11, t12] -> t11>t2 || t12<t1;
482 // 7- too small range.