b311480e |
1 | // Created by: Peter KURNEV |
973c2be1 |
2 | // Copyright (c) 1999-2014 OPEN CASCADE SAS |
b311480e |
3 | // |
973c2be1 |
4 | // This file is part of Open CASCADE Technology software library. |
b311480e |
5 | // |
d5f74e42 |
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 |
973c2be1 |
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. |
b311480e |
11 | // |
973c2be1 |
12 | // Alternatively, this file may be used under the terms of Open CASCADE |
13 | // commercial license or contractual agreement. |
7fd59977 |
14 | |
7fd59977 |
15 | |
42cf5bc1 |
16 | #include <BOPTools_AlgoTools2D.hxx> |
17 | #include <BRep_Builder.hxx> |
18 | #include <BRep_CurveRepresentation.hxx> |
19 | #include <BRep_GCurve.hxx> |
20 | #include <BRep_ListIteratorOfListOfCurveRepresentation.hxx> |
21 | #include <BRep_TEdge.hxx> |
22 | #include <BRep_Tool.hxx> |
23 | #include <BRepAdaptor_Curve.hxx> |
42cf5bc1 |
24 | #include <BRepAdaptor_Surface.hxx> |
25 | #include <BRepClass_FaceClassifier.hxx> |
26 | #include <BRepTools.hxx> |
27 | #include <Geom2d_BSplineCurve.hxx> |
7fd59977 |
28 | #include <Geom2d_Circle.hxx> |
42cf5bc1 |
29 | #include <Geom2d_Curve.hxx> |
7fd59977 |
30 | #include <Geom2d_Ellipse.hxx> |
7fd59977 |
31 | #include <Geom2d_Hyperbola.hxx> |
42cf5bc1 |
32 | #include <Geom2d_Line.hxx> |
33 | #include <Geom2d_Parabola.hxx> |
f1baf495 |
34 | #include <Geom2d_TrimmedCurve.hxx> |
f1baf495 |
35 | #include <Geom2dAdaptor.hxx> |
7fd59977 |
36 | #include <Geom_Curve.hxx> |
f1baf495 |
37 | #include <Geom_Plane.hxx> |
42cf5bc1 |
38 | #include <Geom_RectangularTrimmedSurface.hxx> |
39 | #include <Geom_Surface.hxx> |
40 | #include <Geom_TrimmedCurve.hxx> |
f1baf495 |
41 | #include <GeomAdaptor_Curve.hxx> |
42cf5bc1 |
42 | #include <GeomAdaptor_Surface.hxx> |
43 | #include <GeomInt.hxx> |
0a807dd9 |
44 | #include <GeomLib.hxx> |
f1baf495 |
45 | #include <GeomProjLib.hxx> |
42cf5bc1 |
46 | #include <gp.hxx> |
fc88faf1 |
47 | #include <gp_Cylinder.hxx> |
42cf5bc1 |
48 | #include <gp_Pnt.hxx> |
49 | #include <gp_Pnt2d.hxx> |
50 | #include <gp_Vec.hxx> |
51 | #include <gp_Vec2d.hxx> |
52 | #include <IntTools_Context.hxx> |
53 | #include <IntTools_Tools.hxx> |
54 | #include <Precision.hxx> |
55 | #include <ProjLib_ProjectedCurve.hxx> |
f48cb55d |
56 | #include <ProjLib.hxx> |
42cf5bc1 |
57 | #include <Standard_ConstructionError.hxx> |
58 | #include <Standard_NotImplemented.hxx> |
59 | #include <TopExp.hxx> |
fc88faf1 |
60 | #include <TopExp_Explorer.hxx> |
42cf5bc1 |
61 | #include <TopLoc_Location.hxx> |
62 | #include <TopoDS_Edge.hxx> |
63 | #include <TopoDS_Face.hxx> |
7fd59977 |
64 | |
fc88faf1 |
65 | static |
66 | Standard_Real MaxToleranceEdge (const TopoDS_Face& ); |
7fd59977 |
67 | |
4e57c75e |
68 | //======================================================================= |
69 | //function : BuildPCurveForEdgeOnFace |
70 | //purpose : |
71 | //======================================================================= |
f1baf495 |
72 | void BOPTools_AlgoTools2D::BuildPCurveForEdgeOnFace (const TopoDS_Edge& aE, |
51db0179 |
73 | const TopoDS_Face& aF, |
74 | const Handle(IntTools_Context)& theContext) |
4e57c75e |
75 | { |
76 | BRep_Builder aBB; |
77 | Handle(Geom2d_Curve) aC2D; |
78 | Standard_Real aTolPC, aTolFact, aTolEdge, aFirst, aLast; |
79 | |
80 | Standard_Boolean aHasOld; |
f1baf495 |
81 | aHasOld=BOPTools_AlgoTools2D::HasCurveOnSurface (aE, aF, aC2D, |
82 | aFirst, aLast, |
83 | aTolEdge); |
4e57c75e |
84 | if (aHasOld) { |
85 | return; |
86 | } |
87 | |
88 | |
51db0179 |
89 | BOPTools_AlgoTools2D::CurveOnSurface(aE, aF, aC2D, aTolPC, theContext); |
4e57c75e |
90 | |
91 | aTolEdge=BRep_Tool::Tolerance(aE); |
92 | |
93 | aTolFact=Max(aTolEdge, aTolPC); |
94 | |
95 | aBB.UpdateEdge(aE, aC2D, aF, aTolFact); |
96 | return; |
97 | } |
98 | |
7fd59977 |
99 | //======================================================================= |
100 | //function : EdgeTangent |
101 | //purpose : |
102 | //======================================================================= |
f1baf495 |
103 | Standard_Boolean BOPTools_AlgoTools2D::EdgeTangent |
104 | (const TopoDS_Edge& anEdge, |
105 | const Standard_Real aT, |
106 | gp_Vec& aTau) |
7fd59977 |
107 | { |
108 | Standard_Boolean isdgE; |
109 | Standard_Real first, last; |
110 | |
111 | isdgE = BRep_Tool::Degenerated(anEdge); |
112 | if (isdgE) { |
113 | return Standard_False; |
114 | } |
7fd59977 |
115 | |
116 | Handle(Geom_Curve) aC=BRep_Tool::Curve(anEdge, first, last); |
117 | gp_Pnt aP; |
118 | aC->D1(aT, aP, aTau); |
119 | Standard_Real mod = aTau.Magnitude(); |
120 | if(mod > gp::Resolution()) { |
121 | aTau /= mod; |
122 | } |
123 | else { |
124 | return Standard_False; |
125 | } |
126 | //aTau.Normalize(); |
127 | if (anEdge.Orientation() == TopAbs_REVERSED){ |
128 | aTau.Reverse(); |
129 | } |
130 | return Standard_True; |
131 | } |
132 | |
7fd59977 |
133 | //======================================================================= |
134 | //function : PointOnOnSurface |
135 | //purpose : |
136 | //======================================================================= |
f1baf495 |
137 | void BOPTools_AlgoTools2D::PointOnSurface (const TopoDS_Edge& aE, |
138 | const TopoDS_Face& aF, |
139 | const Standard_Real aParameter, |
140 | Standard_Real& U, |
51db0179 |
141 | Standard_Real& V, |
142 | const Handle(IntTools_Context)& theContext) |
7fd59977 |
143 | { |
144 | gp_Pnt2d aP2D; |
145 | Handle(Geom2d_Curve) aC2D; |
146 | Standard_Real aToler, aFirst, aLast; |
147 | |
51db0179 |
148 | BOPTools_AlgoTools2D::CurveOnSurface (aE, aF, aC2D, aFirst, aLast, aToler, theContext); |
7fd59977 |
149 | aC2D->D0(aParameter, aP2D); |
150 | U=aP2D.X(); |
151 | V=aP2D.Y(); |
152 | return; |
153 | } |
154 | |
155 | //======================================================================= |
156 | //function : CurveOnSurface |
157 | //purpose : |
158 | //======================================================================= |
f1baf495 |
159 | void BOPTools_AlgoTools2D::CurveOnSurface (const TopoDS_Edge& aE, |
160 | const TopoDS_Face& aF, |
161 | Handle(Geom2d_Curve)& aC2D, |
51db0179 |
162 | Standard_Real& aToler, |
163 | const Handle(IntTools_Context)& theContext) |
7fd59977 |
164 | { |
165 | Standard_Real aFirst, aLast; |
f1baf495 |
166 | // |
51db0179 |
167 | BOPTools_AlgoTools2D::CurveOnSurface(aE, aF, aC2D, aFirst, aLast, aToler, theContext); |
f1baf495 |
168 | // |
7fd59977 |
169 | return; |
170 | } |
171 | //======================================================================= |
172 | //function : CurveOnSurface |
173 | //purpose : |
174 | //======================================================================= |
f1baf495 |
175 | void BOPTools_AlgoTools2D::CurveOnSurface (const TopoDS_Edge& aE, |
176 | const TopoDS_Face& aF, |
177 | Handle(Geom2d_Curve)& aC2D, |
178 | Standard_Real& aFirst, |
179 | Standard_Real& aLast, |
51db0179 |
180 | Standard_Real& aToler, |
181 | const Handle(IntTools_Context)& theContext) |
7fd59977 |
182 | { |
183 | Standard_Boolean aHasOld; |
184 | Handle(Geom2d_Curve) C2D; |
185 | |
f1baf495 |
186 | aHasOld=BOPTools_AlgoTools2D::HasCurveOnSurface (aE, aF, C2D, |
187 | aFirst, aLast, |
188 | aToler); |
7fd59977 |
189 | if (aHasOld) { |
190 | aC2D=C2D; |
191 | return; |
192 | } |
193 | |
51db0179 |
194 | BOPTools_AlgoTools2D::Make2D(aE, aF, C2D, aFirst, aLast, aToler, theContext); |
7fd59977 |
195 | aC2D=C2D; |
196 | return; |
197 | } |
7fd59977 |
198 | //======================================================================= |
199 | //function : HasCurveOnSurface |
200 | //purpose : |
201 | //======================================================================= |
f1baf495 |
202 | Standard_Boolean BOPTools_AlgoTools2D::HasCurveOnSurface |
203 | (const TopoDS_Edge& aE, |
204 | const TopoDS_Face& aF, |
205 | Handle(Geom2d_Curve)& aC2D, |
206 | Standard_Real& aFirst, |
207 | Standard_Real& aLast, |
208 | Standard_Real& aToler) |
7fd59977 |
209 | { |
210 | Standard_Boolean aHasOld; |
211 | |
212 | aToler=BRep_Tool::Tolerance(aE); |
213 | BRep_Tool::Range(aE, aFirst, aLast); |
214 | |
215 | if((aLast - aFirst) < Precision::PConfusion()) { |
216 | return Standard_False; |
217 | } |
218 | |
f1baf495 |
219 | aC2D=BRep_Tool::CurveOnSurface(aE, aF, aFirst, aLast); |
7fd59977 |
220 | aHasOld=!aC2D.IsNull(); |
221 | return aHasOld; |
222 | } |
223 | //======================================================================= |
224 | //function : HasCurveOnSurface |
225 | //purpose : |
226 | //======================================================================= |
f1baf495 |
227 | Standard_Boolean BOPTools_AlgoTools2D::HasCurveOnSurface |
228 | (const TopoDS_Edge& aE, |
229 | const TopoDS_Face& aF) |
7fd59977 |
230 | { |
f1baf495 |
231 | Standard_Boolean bHasOld; |
7fd59977 |
232 | Handle(Geom2d_Curve) aC2D; |
233 | Standard_Real aFirst, aLast; |
f1baf495 |
234 | // |
7fd59977 |
235 | BRep_Tool::Range(aE, aFirst, aLast); |
f1baf495 |
236 | // |
7fd59977 |
237 | if((aLast - aFirst) < Precision::PConfusion()) { |
238 | return Standard_False; |
239 | } |
f1baf495 |
240 | // |
241 | aC2D=BRep_Tool::CurveOnSurface(aE, aF, aFirst, aLast); |
242 | bHasOld=!aC2D.IsNull(); |
243 | // |
244 | return bHasOld; |
7fd59977 |
245 | } |
7fd59977 |
246 | //======================================================================= |
247 | //function : AdjustPCurveOnFace |
248 | //purpose : |
249 | //======================================================================= |
51db0179 |
250 | void BOPTools_AlgoTools2D::AdjustPCurveOnFace |
251 | (const TopoDS_Face& theF, |
252 | const Handle(Geom_Curve)& theC3D, |
253 | const Handle(Geom2d_Curve)& theC2D, |
254 | Handle(Geom2d_Curve)& theC2DA, |
255 | const Handle(IntTools_Context)& theContext) |
7fd59977 |
256 | { |
51db0179 |
257 | Standard_Real aT1 = theC3D->FirstParameter(); |
258 | Standard_Real aT2 = theC3D->LastParameter(); |
fd372378 |
259 | // |
51db0179 |
260 | BOPTools_AlgoTools2D::AdjustPCurveOnFace (theF, aT1, aT2, theC2D, theC2DA, theContext); |
fd372378 |
261 | } |
7fd59977 |
262 | //======================================================================= |
263 | //function : AdjustPCurveOnFace |
264 | //purpose : |
265 | //======================================================================= |
f1baf495 |
266 | void BOPTools_AlgoTools2D::AdjustPCurveOnFace |
51db0179 |
267 | (const TopoDS_Face& theF, |
268 | const Standard_Real theFirst, |
269 | const Standard_Real theLast, |
270 | const Handle(Geom2d_Curve)& theC2D, |
271 | Handle(Geom2d_Curve)& theC2DA, |
272 | const Handle(IntTools_Context)& theContext) |
fd372378 |
273 | { |
51db0179 |
274 | BRepAdaptor_Surface aBASTmp; |
275 | const BRepAdaptor_Surface* pBAS; |
276 | if (!theContext.IsNull()) { |
277 | pBAS = &theContext->SurfaceAdaptor(theF); |
278 | } |
279 | else { |
280 | aBASTmp.Initialize(theF, Standard_True); |
281 | pBAS = &aBASTmp; |
282 | } |
fd372378 |
283 | // |
51db0179 |
284 | BOPTools_AlgoTools2D::AdjustPCurveOnSurf(*pBAS, theFirst, theLast, theC2D, theC2DA); |
fd372378 |
285 | } |
fd372378 |
286 | //======================================================================= |
287 | //function : AdjustPCurveOnFace |
288 | //purpose : |
289 | //======================================================================= |
51db0179 |
290 | void BOPTools_AlgoTools2D::AdjustPCurveOnSurf |
fd372378 |
291 | (const BRepAdaptor_Surface& aBAS, |
f1baf495 |
292 | const Standard_Real aFirst, |
293 | const Standard_Real aLast, |
51db0179 |
294 | const Handle(Geom2d_Curve)& aC2D, |
f1baf495 |
295 | Handle(Geom2d_Curve)& aC2DA) |
7fd59977 |
296 | { |
655fddc8 |
297 | Standard_Boolean mincond, maxcond; |
7fd59977 |
298 | Standard_Real UMin, UMax, VMin, VMax, aT, u2, v2, du, dv, aDelta; |
655fddc8 |
299 | Standard_Real aUPeriod; |
7fd59977 |
300 | // |
fd372378 |
301 | const TopoDS_Face& aF=aBAS.Face(); |
302 | UMin=aBAS.FirstUParameter(); |
303 | UMax=aBAS.LastUParameter(); |
304 | VMin=aBAS.FirstVParameter(); |
305 | VMax=aBAS.LastVParameter(); |
306 | // |
fd372378 |
307 | aDelta=Precision::PConfusion(); |
7fd59977 |
308 | |
309 | aT =.5*(aFirst+aLast); |
310 | |
311 | gp_Pnt2d pC2D; |
312 | aC2D->D0(aT, pC2D); |
313 | |
314 | u2 = pC2D.X(); |
315 | v2 = pC2D.Y(); |
fc88faf1 |
316 | // |
317 | // du |
7fd59977 |
318 | du = 0.; |
319 | if (aBAS.IsUPeriodic()) { |
655fddc8 |
320 | aUPeriod = aBAS.UPeriod(); |
fd372378 |
321 | |
7fd59977 |
322 | // |
67e36f0c |
323 | // a. try to clarify u2 using the precision (aDelta) |
324 | if (fabs(u2-UMin) < aDelta) { |
325 | u2=UMin; |
326 | } |
327 | else if (fabs(u2-UMin-aUPeriod) < aDelta) { |
9c0b61f3 |
328 | u2=UMin+aUPeriod; |
329 | } |
67e36f0c |
330 | // b. compute du again using clarified value of u2 |
331 | GeomInt::AdjustPeriodic(u2, UMin, UMax, aUPeriod, u2, du, 0.); |
fc88faf1 |
332 | // |
333 | if (du==0.) { |
334 | if (aBAS.GetType()==GeomAbs_Cylinder) { |
335 | Standard_Real aR, dFi, aTol; |
336 | // |
337 | gp_Cylinder aCylinder=aBAS.Cylinder(); |
338 | aR=aCylinder.Radius(); |
339 | aTol=MaxToleranceEdge(aF); |
340 | dFi=aTol/aR; |
341 | if (dFi<aDelta) { |
342 | dFi=aDelta; |
343 | } |
344 | // |
345 | mincond = (UMin - u2 > dFi); |
346 | maxcond = (u2 - UMax > dFi); |
347 | if (mincond || maxcond) { |
348 | du = ( mincond ) ? aUPeriod : -aUPeriod; |
349 | } |
350 | } |
351 | } |
655fddc8 |
352 | } |
fc88faf1 |
353 | |
7fd59977 |
354 | // dv |
355 | dv = 0.; |
356 | if (aBAS.IsVPeriodic()) { |
357 | Standard_Real aVPeriod, aVm, aVr, aVmid, dVm, dVr; |
358 | // |
655fddc8 |
359 | aVPeriod = aBAS.VPeriod(); |
7fd59977 |
360 | mincond = (VMin - v2 > aDelta); |
361 | maxcond = (v2 - VMax > aDelta); |
655fddc8 |
362 | // |
363 | if (mincond || maxcond) { |
7fd59977 |
364 | dv = ( mincond ) ? aVPeriod : -aVPeriod; |
365 | } |
366 | // |
7fd59977 |
367 | if ((VMax-VMin<aVPeriod) && dv) { |
368 | aVm=v2; |
369 | aVr=v2+dv; |
370 | aVmid=0.5*(VMin+VMax); |
371 | dVm=fabs(aVm-aVmid); |
372 | dVr=fabs(aVr-aVmid); |
373 | if (dVm<dVr) { |
4e57c75e |
374 | dv=0.; |
7fd59977 |
375 | } |
376 | } |
7fd59977 |
377 | } |
378 | // |
d8a24e83 |
379 | { |
380 | //check the point with classifier |
381 | Standard_Real u,v; |
382 | u = u2 + du; |
383 | v = v2 + dv; |
384 | if (aBAS.IsUPeriodic()) { |
385 | aUPeriod = aBAS.UPeriod(); |
386 | if ((UMax - UMin - 2*aDelta) > aUPeriod) { |
387 | if ((u > (UMin + aDelta + aUPeriod)) || |
388 | (u < (UMax - aDelta - aUPeriod))) { |
389 | BRepClass_FaceClassifier aClassifier; |
390 | aClassifier.Perform(aF, gp_Pnt2d(u, v), aDelta); |
391 | TopAbs_State Status = aClassifier.State(); |
392 | if (Status == TopAbs_OUT) { |
393 | du += (u > (UMin + aDelta + aUPeriod)) ? -aUPeriod : aUPeriod; |
394 | } |
395 | } |
396 | } |
397 | } |
398 | // |
399 | u = u2 + du; |
400 | if (aBAS.IsVPeriodic()) { |
401 | Standard_Real aVPeriod = aBAS.VPeriod(); |
402 | if ((VMax - VMin - 2*aDelta) > aVPeriod) { |
403 | if ((v > (VMin + aDelta + aVPeriod)) || |
404 | (v < (VMax - aDelta - aVPeriod))) { |
405 | BRepClass_FaceClassifier aClassifier; |
406 | aClassifier.Perform(aF, gp_Pnt2d(u, v), aDelta); |
407 | TopAbs_State Status = aClassifier.State(); |
408 | if (Status == TopAbs_OUT) { |
409 | dv += (v > (VMin + aDelta + aVPeriod)) ? -aVPeriod : aVPeriod; |
410 | } |
411 | } |
412 | } |
413 | } |
414 | } |
7fd59977 |
415 | // Translation if necessary |
416 | Handle(Geom2d_Curve) aC2Dx=aC2D; |
417 | |
418 | if ( du != 0. || dv != 0.) { |
419 | Handle(Geom2d_Curve) PCT = Handle(Geom2d_Curve)::DownCast(aC2Dx->Copy()); |
420 | gp_Vec2d aV2D(du,dv); |
421 | PCT->Translate(aV2D); |
422 | aC2Dx = PCT; |
423 | } |
424 | |
425 | aC2DA=aC2Dx; |
426 | } |
427 | |
4e57c75e |
428 | //======================================================================= |
429 | //function : IntermediatePoint |
430 | //purpose : |
431 | //======================================================================= |
f1baf495 |
432 | Standard_Real BOPTools_AlgoTools2D::IntermediatePoint |
433 | (const Standard_Real aFirst, |
434 | const Standard_Real aLast) |
4e57c75e |
435 | { |
436 | //define parameter division number as 10*e^(-PI) = 0.43213918 |
437 | const Standard_Real PAR_T = 0.43213918; |
438 | Standard_Real aParm; |
439 | aParm=(1.-PAR_T)*aFirst + PAR_T*aLast; |
440 | return aParm; |
441 | } |
442 | //======================================================================= |
443 | //function : IntermediatePoint |
444 | //purpose : |
445 | //======================================================================= |
f1baf495 |
446 | Standard_Real BOPTools_AlgoTools2D::IntermediatePoint |
447 | (const TopoDS_Edge& aE) |
4e57c75e |
448 | |
449 | { |
450 | Standard_Real aT, aT1, aT2; |
451 | |
452 | Handle(Geom_Curve)aC1=BRep_Tool::Curve(aE, aT1, aT2); |
453 | if (aC1.IsNull()) |
454 | BRep_Tool::Range(aE, aT1, aT2); |
455 | |
456 | aT=BOPTools_AlgoTools2D::IntermediatePoint(aT1, aT2); |
457 | return aT; |
458 | } |
4e57c75e |
459 | //======================================================================= |
460 | //function : Make2D |
461 | //purpose : |
462 | //======================================================================= |
acccace3 |
463 | void BOPTools_AlgoTools2D::Make2D (const TopoDS_Edge& aE, |
f1baf495 |
464 | const TopoDS_Face& aF, |
465 | Handle(Geom2d_Curve)& aC2D, |
466 | Standard_Real& aFirst, |
467 | Standard_Real& aLast, |
51db0179 |
468 | Standard_Real& aToler, |
469 | const Handle(IntTools_Context)& theContext) |
4e57c75e |
470 | { |
471 | Standard_Boolean aLocIdentity; |
472 | Standard_Real f3d, l3d; |
473 | TopLoc_Location aLoc; |
474 | |
475 | Handle(Geom2d_Curve) C2D; |
476 | |
477 | |
478 | C2D=BRep_Tool::CurveOnSurface(aE, aF, aFirst, aLast); |
479 | |
480 | if (!C2D.IsNull()) { |
481 | aC2D=C2D; |
482 | return; |
483 | } |
484 | |
485 | Handle(Geom_Curve) C3D2, C3D; |
486 | C3D = BRep_Tool::Curve(aE, aLoc, f3d, l3d); |
487 | // |
488 | if (C3D.IsNull()) { |
489 | // aE has no 3D curve, so nothing is done |
490 | } |
491 | // |
492 | aLocIdentity=aLoc.IsIdentity(); |
493 | |
494 | if (aLocIdentity) { |
495 | C3D2 = C3D; |
496 | } |
497 | else { |
498 | C3D2 = Handle(Geom_Curve):: |
499 | DownCast(C3D->Transformed(aLoc.Transformation())); |
500 | } |
501 | |
502 | // |
ee5ee7db |
503 | aToler = BRep_Tool::Tolerance(aE); |
51db0179 |
504 | BOPTools_AlgoTools2D::MakePCurveOnFace(aF, C3D2, f3d, l3d, aC2D, aToler, theContext); |
4e57c75e |
505 | // |
506 | aFirst = f3d; |
507 | aLast = l3d; |
508 | } |
509 | |
510 | //======================================================================= |
511 | //function : MakePCurveOnFace |
512 | //purpose : |
513 | //======================================================================= |
f1baf495 |
514 | void BOPTools_AlgoTools2D::MakePCurveOnFace (const TopoDS_Face& aF, |
515 | const Handle(Geom_Curve)& aC3D, |
516 | Handle(Geom2d_Curve)& aC2D, //-> |
51db0179 |
517 | Standard_Real& TolReached2d, |
518 | const Handle(IntTools_Context)& theContext) |
4e57c75e |
519 | { |
520 | Standard_Real aFirst, aLast; |
521 | |
522 | aFirst = aC3D -> FirstParameter(); |
523 | aLast = aC3D -> LastParameter(); |
524 | // |
525 | TolReached2d=0.; |
526 | // |
51db0179 |
527 | BOPTools_AlgoTools2D::MakePCurveOnFace |
528 | (aF, aC3D, aFirst, aLast, aC2D, TolReached2d, theContext); |
4e57c75e |
529 | } |
530 | |
531 | //======================================================================= |
532 | //function : MakePCurveOnFace |
533 | //purpose : |
534 | //======================================================================= |
51db0179 |
535 | void BOPTools_AlgoTools2D::MakePCurveOnFace |
f1baf495 |
536 | (const TopoDS_Face& aF, |
537 | const Handle(Geom_Curve)& aC3D, |
fd372378 |
538 | const Standard_Real aT1, |
539 | const Standard_Real aT2, |
51db0179 |
540 | Handle(Geom2d_Curve)& aC2D, |
541 | Standard_Real& TolReached2d, |
542 | const Handle(IntTools_Context)& theContext) |
4e57c75e |
543 | { |
51db0179 |
544 | BRepAdaptor_Surface aBASTmp; |
545 | const BRepAdaptor_Surface* pBAS; |
546 | if (!theContext.IsNull()) { |
547 | pBAS = &theContext->SurfaceAdaptor(aF); |
548 | } |
549 | else { |
550 | aBASTmp.Initialize(aF, Standard_True); |
551 | pBAS = &aBASTmp; |
552 | } |
fd372378 |
553 | // |
c22b52d6 |
554 | Handle(BRepAdaptor_Surface) aBAHS = new BRepAdaptor_Surface(*pBAS); |
555 | Handle(GeomAdaptor_Curve) aBAHC = new GeomAdaptor_Curve(aC3D, aT1, aT2); |
f2843558 |
556 | // |
51db0179 |
557 | Standard_Real aTolR; |
f998596a |
558 | Standard_Real aTR = Precision::Confusion();//1.e-7; |
559 | Standard_Real aMaxTol = 1.e3 * aTR; //0.0001 |
560 | Standard_Boolean isAnaSurf = ProjLib::IsAnaSurf(aBAHS); |
561 | |
4e57c75e |
562 | //when the type of surface is GeomAbs_SurfaceOfRevolution |
f998596a |
563 | if (pBAS->GetType() == GeomAbs_SurfaceOfRevolution) |
564 | { |
fd372378 |
565 | if (TolReached2d > aTR) { |
566 | aTR=TolReached2d; |
567 | } |
568 | // |
4e57c75e |
569 | ProjLib_ProjectedCurve aProj1(aBAHS, aBAHC, aTR); |
f48cb55d |
570 | ProjLib::MakePCurveOfType(aProj1, aC2D); |
4e57c75e |
571 | aTolR = aProj1.GetTolerance(); |
fd372378 |
572 | } |
f998596a |
573 | else |
574 | { |
575 | ProjLib_ProjectedCurve aProjCurv(aBAHS); |
576 | Standard_Integer aDegMin = -1, aDegMax = -1, aMaxSegments = -1; |
577 | Standard_Real aMaxDist = -1; |
578 | AppParCurves_Constraint aBndPnt = AppParCurves_TangencyPoint; |
579 | if ((TolReached2d >= 10. * aTR) && (TolReached2d <= aMaxTol || isAnaSurf)) |
580 | { |
581 | aTR = Min(aMaxTol, 0.1*TolReached2d); |
582 | aMaxSegments = 100; |
583 | aMaxDist = 1.e3*TolReached2d; |
47a27171 |
584 | if(!isAnaSurf || TolReached2d > 1.) |
f998596a |
585 | { |
586 | aBndPnt = AppParCurves_PassPoint; |
587 | } |
588 | } |
589 | else if(TolReached2d > aMaxTol) |
590 | { |
591 | aTR = Min(TolReached2d, 1.e3 * aMaxTol); |
592 | aMaxDist = 1.e2 * aTR; |
593 | aMaxSegments = 100; |
594 | } |
595 | aProjCurv.Load(aTR); |
596 | aProjCurv.SetDegree(aDegMin, aDegMax); |
597 | aProjCurv.SetMaxSegments(aMaxSegments); |
598 | aProjCurv.SetBndPnt(aBndPnt); |
599 | aProjCurv.SetMaxDist(aMaxDist); |
600 | aProjCurv.Perform(aBAHC); |
f48cb55d |
601 | ProjLib::MakePCurveOfType(aProjCurv, aC2D); |
4e57c75e |
602 | aTolR=aProjCurv.GetTolerance(); |
603 | } |
604 | // |
f998596a |
605 | if (aC2D.IsNull() && (aTR < aMaxTol || aTR < TolReached2d)) |
606 | { |
607 | aTR = Max(TolReached2d, aMaxTol); |
608 | ProjLib_ProjectedCurve aProjCurvAgain(aBAHS, aBAHC, aTR);// 2 |
f48cb55d |
609 | ProjLib::MakePCurveOfType(aProjCurvAgain, aC2D); |
4e57c75e |
610 | aTolR = aProjCurvAgain.GetTolerance(); |
4e57c75e |
611 | } |
b9a7d225 |
612 | // |
613 | if(aC2D.IsNull()) |
614 | { |
9775fa61 |
615 | throw Standard_ConstructionError("BOPTools_AlgoTools2D::MakePCurveOnFace : PCurve is Null"); |
b9a7d225 |
616 | } |
617 | // |
4e57c75e |
618 | TolReached2d=aTolR; |
0a807dd9 |
619 | |
620 | // Adjust curve for periodic surface |
51db0179 |
621 | Handle(Geom2d_Curve) aC2DA; |
622 | BOPTools_AlgoTools2D::AdjustPCurveOnSurf (*pBAS, aT1, aT2, aC2D, aC2DA); |
0a807dd9 |
623 | aC2D = aC2DA; |
624 | |
625 | // Make sure that the range of the 2D curve is sufficient for representation of the 3D curve. |
626 | Standard_Real aTCFirst = aC2D->FirstParameter(); |
627 | Standard_Real aTCLast = aC2D->LastParameter(); |
628 | if ((aTCFirst - aT1) > Precision::PConfusion() || |
629 | (aT2 - aTCLast ) > Precision::PConfusion()) |
630 | { |
631 | if (aTCFirst < aT1) aTCFirst = aT1; |
632 | if (aTCLast > aT2) aTCLast = aT2; |
633 | |
634 | GeomLib::SameRange(Precision::PConfusion(), aC2D, |
635 | aTCFirst, aTCLast, aT1, aT2, aC2D); |
636 | } |
637 | |
1b7ae951 |
638 | // compute the appropriate tolerance for the edge |
51db0179 |
639 | Handle(Geom_Surface) aS = pBAS->Surface().Surface(); |
640 | aS = Handle(Geom_Surface)::DownCast(aS->Transformed(pBAS->Trsf())); |
641 | // |
642 | Standard_Real aT; |
1b7ae951 |
643 | if (IntTools_Tools::ComputeTolerance |
fd372378 |
644 | (aC3D, aC2D, aS, aT1, aT2, aTolR, aT)) { |
1b7ae951 |
645 | if (aTolR > TolReached2d) { |
646 | TolReached2d = aTolR; |
647 | } |
648 | } |
4e57c75e |
649 | } |
7fd59977 |
650 | |
fc88faf1 |
651 | //======================================================================= |
652 | //function : MaxToleranceEdge |
653 | //purpose : |
654 | //======================================================================= |
655 | Standard_Real MaxToleranceEdge (const TopoDS_Face& aF) |
656 | { |
657 | Standard_Real aTol, aTolMax; |
658 | TopExp_Explorer aExp; |
659 | // |
660 | aTolMax=0.; |
661 | aExp.Init(aF, TopAbs_EDGE); |
662 | for (; aExp.More(); aExp.Next()) { |
663 | const TopoDS_Edge& aE=*((TopoDS_Edge *)&aExp.Current()); |
664 | aTol=BRep_Tool::Tolerance(aE); |
665 | if (aTol>aTolMax) { |
666 | aTolMax=aTol; |
667 | } |
668 | } |
669 | return aTolMax; |
670 | } |
39067947 |
671 | |
672 | //======================================================================= |
673 | //function : IsEdgeIsoline |
674 | //purpose : |
675 | //======================================================================= |
676 | void BOPTools_AlgoTools2D::IsEdgeIsoline( const TopoDS_Edge& theE, |
677 | const TopoDS_Face& theF, |
678 | Standard_Boolean& isTheUIso, |
679 | Standard_Boolean& isTheVIso) |
680 | { |
681 | isTheUIso = isTheVIso = Standard_False; |
682 | |
683 | gp_Vec2d aT; |
684 | gp_Pnt2d aP; |
685 | Standard_Real aFirst = 0.0, aLast = 0.0; |
686 | const Handle(Geom2d_Curve) aPC = BRep_Tool::CurveOnSurface(theE, theF, aFirst, aLast); |
687 | |
688 | aPC->D1(0.5*(aFirst+aLast), aP, aT); |
689 | |
690 | const Standard_Real aSqMagn = aT.SquareMagnitude(); |
691 | if(aSqMagn <= gp::Resolution()) |
692 | return; |
693 | |
694 | //Normalyze aT |
695 | aT /= sqrt(aSqMagn); |
696 | |
697 | //sin(da) ~ da, when da->0. |
698 | const Standard_Real aTol = Precision::Angular(); |
699 | const gp_Vec2d aRefVDir(0.0, 1.0), aRefUDir(1.0, 0.0); |
700 | |
701 | const Standard_Real aDPv = aT.CrossMagnitude(aRefVDir), |
702 | aDPu = aT.CrossMagnitude(aRefUDir); |
703 | |
704 | isTheUIso = (aDPv <= aTol); |
705 | isTheVIso = (aDPu <= aTol); |
f48cb55d |
706 | } |