b311480e |
1 | // Created on: 1993-11-26 |
2 | // Created by: Modelistation |
3 | // Copyright (c) 1993-1999 Matra Datavision |
973c2be1 |
4 | // Copyright (c) 1999-2014 OPEN CASCADE SAS |
b311480e |
5 | // |
973c2be1 |
6 | // This file is part of Open CASCADE Technology software library. |
b311480e |
7 | // |
d5f74e42 |
8 | // This library is free software; you can redistribute it and/or modify it under |
9 | // the terms of the GNU Lesser General Public License version 2.1 as published |
973c2be1 |
10 | // by the Free Software Foundation, with special exception defined in the file |
11 | // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT |
12 | // distribution for complete text of the license and disclaimer of any warranty. |
b311480e |
13 | // |
973c2be1 |
14 | // Alternatively, this file may be used under the terms of Open CASCADE |
15 | // commercial license or contractual agreement. |
7fd59977 |
16 | |
e2e0498b |
17 | #include <IntPatch_ALineToWLine.hxx> |
7fd59977 |
18 | |
e2e0498b |
19 | #include <Adaptor3d_HSurface.hxx> |
20 | #include <ElSLib.hxx> |
42cf5bc1 |
21 | #include <IntPatch_ALine.hxx> |
e2e0498b |
22 | #include <IntPatch_Point.hxx> |
23 | #include <IntPatch_SpecialPoints.hxx> |
42cf5bc1 |
24 | #include <IntPatch_WLine.hxx> |
e2e0498b |
25 | #include <IntSurf.hxx> |
42cf5bc1 |
26 | #include <IntSurf_LineOn2S.hxx> |
7fd59977 |
27 | |
7fd59977 |
28 | //======================================================================= |
e2e0498b |
29 | //function : AddPointIntoLine |
7fd59977 |
30 | //purpose : |
31 | //======================================================================= |
e2e0498b |
32 | static inline void AddPointIntoLine(Handle(IntSurf_LineOn2S) theLine, |
33 | const Standard_Real* const theArrPeriods, |
34 | IntSurf_PntOn2S &thePoint, |
35 | IntPatch_Point* theVertex = 0) |
36 | { |
37 | if(theLine->NbPoints() > 0) |
38 | { |
39 | if(thePoint.IsSame(theLine->Value(theLine->NbPoints()), Precision::Confusion())) |
40 | return; |
41 | |
42 | IntPatch_SpecialPoints::AdjustPointAndVertex(theLine->Value(theLine->NbPoints()), |
43 | theArrPeriods, thePoint, theVertex); |
44 | } |
45 | |
46 | theLine->Add(thePoint); |
47 | } |
48 | |
49 | //======================================================================= |
50 | //function : AddVertexPoint |
51 | //purpose : Extracts IntSurf_PntOn2S from theVertex and adds result in theLine. |
52 | //======================================================================= |
53 | static void AddVertexPoint(Handle(IntSurf_LineOn2S)& theLine, |
54 | IntPatch_Point &theVertex, |
55 | const Standard_Real* const theArrPeriods) |
56 | { |
57 | IntSurf_PntOn2S anApexPoint = theVertex.PntOn2S(); |
58 | AddPointIntoLine(theLine, theArrPeriods, anApexPoint, &theVertex); |
7fd59977 |
59 | } |
e2e0498b |
60 | |
61 | //======================================================================= |
62 | //function : IsPoleOrSeam |
63 | //purpose : Processes theVertex depending on its type |
64 | // (pole/apex/point on boundary etc.) and adds it in theLine. |
65 | // theSingularSurfaceID contains the ID of surface with |
66 | // special point (0 - none, 1 - theS1, 2 - theS2) |
67 | //======================================================================= |
68 | static IntPatch_SpecPntType IsPoleOrSeam(const Handle(Adaptor3d_HSurface)& theS1, |
69 | const Handle(Adaptor3d_HSurface)& theS2, |
70 | Handle(IntSurf_LineOn2S)& theLine, |
71 | IntPatch_Point &theVertex, |
72 | const Standard_Real* const theArrPeriods, |
73 | const Standard_Real theTol3d, |
74 | Standard_Integer& theSingularSurfaceID) |
75 | { |
76 | const Standard_Integer aNbPnts = theLine->NbPoints(); |
77 | if(aNbPnts == 0) |
78 | return IntPatch_SPntNone; |
79 | |
80 | theSingularSurfaceID = 0; |
81 | |
82 | for(Standard_Integer i = 0; i < 2; i++) |
83 | { |
84 | const Standard_Boolean isReversed = (i > 0); |
85 | const GeomAbs_SurfaceType aType = isReversed? theS2->GetType() : theS1->GetType(); |
86 | |
87 | IntPatch_SpecPntType anAddedPType = IntPatch_SPntNone; |
88 | IntSurf_PntOn2S anApexPoint; |
89 | |
90 | switch(aType) |
91 | { |
92 | case GeomAbs_Sphere: |
93 | case GeomAbs_Cone: |
94 | { |
95 | if(IntPatch_SpecialPoints:: |
96 | AddSingularPole((isReversed? theS2 : theS1), (isReversed? theS1 : theS2), |
97 | theLine->Value(aNbPnts), theTol3d, theVertex, |
98 | anApexPoint, isReversed, Standard_True)) |
99 | { |
100 | anAddedPType = IntPatch_SPntPole; |
101 | break; |
102 | } |
103 | } |
104 | case GeomAbs_Torus: |
105 | if(aType == GeomAbs_Torus) |
106 | { |
107 | if(IntPatch_SpecialPoints:: |
108 | AddCrossUVIsoPoint((isReversed? theS2 : theS1), (isReversed? theS1 : theS2), |
109 | theLine->Value(aNbPnts), theTol3d, |
110 | anApexPoint, isReversed)) |
111 | { |
112 | anAddedPType = IntPatch_SPntSeamUV; |
113 | break; |
114 | } |
115 | } |
116 | case GeomAbs_Cylinder: |
117 | theSingularSurfaceID = i + 1; |
118 | AddVertexPoint(theLine, theVertex, theArrPeriods); |
119 | return IntPatch_SPntSeamU; |
120 | |
121 | default: |
122 | break; |
123 | } |
124 | |
125 | if(anAddedPType != IntPatch_SPntNone) |
126 | { |
127 | theSingularSurfaceID = i + 1; |
128 | AddPointIntoLine(theLine, theArrPeriods, anApexPoint, &theVertex); |
129 | return anAddedPType; |
130 | } |
131 | } |
132 | |
133 | return IntPatch_SPntNone; |
134 | } |
135 | |
7fd59977 |
136 | //======================================================================= |
137 | //function : IntPatch_ALineToWLine |
138 | //purpose : |
139 | //======================================================================= |
e2e0498b |
140 | IntPatch_ALineToWLine::IntPatch_ALineToWLine(const Handle(Adaptor3d_HSurface)& theS1, |
141 | const Handle(Adaptor3d_HSurface)& theS2, |
142 | const Standard_Integer theNbPoints) : |
143 | myS1(theS1), |
144 | myS2(theS2), |
145 | myNbPointsInWline(theNbPoints), |
7fd59977 |
146 | myTolOpenDomain(1.e-9), |
e2e0498b |
147 | myTolTransition(1.e-8), |
148 | myTol3D(Precision::Confusion()) |
7fd59977 |
149 | { |
e2e0498b |
150 | const GeomAbs_SurfaceType aTyps1 = theS1->GetType(); |
151 | const GeomAbs_SurfaceType aTyps2 = theS2->GetType(); |
152 | |
153 | switch(aTyps1) |
154 | { |
155 | case GeomAbs_Plane: |
156 | myQuad1.SetValue(theS1->Plane()); |
157 | break; |
158 | |
159 | case GeomAbs_Cylinder: |
160 | myQuad1.SetValue(theS1->Cylinder()); |
161 | break; |
162 | |
163 | case GeomAbs_Sphere: |
164 | myQuad1.SetValue(theS1->Sphere()); |
165 | break; |
166 | |
167 | case GeomAbs_Cone: |
168 | myQuad1.SetValue(theS1->Cone()); |
169 | break; |
170 | |
171 | case GeomAbs_Torus: |
172 | myQuad1.SetValue(theS1->Torus()); |
173 | break; |
174 | |
175 | default: |
176 | break; |
177 | } |
178 | |
179 | switch(aTyps2) |
180 | { |
181 | case GeomAbs_Plane: |
182 | myQuad2.SetValue(theS2->Plane()); |
183 | break; |
184 | case GeomAbs_Cylinder: |
185 | myQuad2.SetValue(theS2->Cylinder()); |
186 | break; |
187 | |
188 | case GeomAbs_Sphere: |
189 | myQuad2.SetValue(theS2->Sphere()); |
190 | break; |
191 | |
192 | case GeomAbs_Cone: |
193 | myQuad2.SetValue(theS2->Cone()); |
194 | break; |
195 | |
196 | case GeomAbs_Torus: |
197 | myQuad2.SetValue(theS2->Torus()); |
198 | break; |
199 | |
200 | default: |
201 | break; |
202 | } |
7fd59977 |
203 | } |
e2e0498b |
204 | |
7fd59977 |
205 | //======================================================================= |
206 | //function : SetTol3D |
207 | //purpose : |
208 | //======================================================================= |
209 | void IntPatch_ALineToWLine::SetTol3D(const Standard_Real aTol) |
210 | { |
211 | myTol3D = aTol; |
212 | } |
213 | //======================================================================= |
214 | //function : Tol3D |
215 | //purpose : |
216 | //======================================================================= |
217 | Standard_Real IntPatch_ALineToWLine::Tol3D()const |
218 | { |
219 | return myTol3D; |
220 | } |
221 | //======================================================================= |
222 | //function : SetTolTransition |
223 | //purpose : |
224 | //======================================================================= |
225 | void IntPatch_ALineToWLine::SetTolTransition(const Standard_Real aTol) |
226 | { |
227 | myTolTransition = aTol; |
228 | } |
229 | //======================================================================= |
230 | //function : TolTransition |
231 | //purpose : |
232 | //======================================================================= |
233 | Standard_Real IntPatch_ALineToWLine::TolTransition()const |
234 | { |
235 | return myTolTransition; |
236 | } |
237 | //======================================================================= |
7fd59977 |
238 | //function : SetTolOpenDomain |
239 | //purpose : |
240 | //======================================================================= |
241 | void IntPatch_ALineToWLine::SetTolOpenDomain(const Standard_Real aTol) |
242 | { |
243 | myTolOpenDomain = aTol; |
244 | } |
245 | //======================================================================= |
246 | //function : TolOpenDomain |
247 | //purpose : |
248 | //======================================================================= |
249 | Standard_Real IntPatch_ALineToWLine::TolOpenDomain()const |
250 | { |
251 | return myTolOpenDomain; |
252 | } |
253 | //======================================================================= |
7fd59977 |
254 | //function : MakeWLine |
255 | //purpose : |
256 | //======================================================================= |
e2e0498b |
257 | void IntPatch_ALineToWLine::MakeWLine(const Handle(IntPatch_ALine)& theAline, |
258 | IntPatch_SequenceOfLine& theLines) const |
7fd59977 |
259 | { |
260 | Standard_Boolean included; |
e2e0498b |
261 | Standard_Real f = theAline->FirstParameter(included); |
7fd59977 |
262 | if(!included) { |
263 | f+=myTolOpenDomain; |
264 | } |
e2e0498b |
265 | Standard_Real l = theAline->LastParameter(included); |
7fd59977 |
266 | if(!included) { |
267 | l-=myTolOpenDomain; |
268 | } |
e2e0498b |
269 | |
270 | MakeWLine(theAline, f, l, theLines); |
7fd59977 |
271 | } |
272 | |
273 | //======================================================================= |
274 | //function : MakeWLine |
275 | //purpose : |
276 | //======================================================================= |
e2e0498b |
277 | void IntPatch_ALineToWLine::MakeWLine(const Handle(IntPatch_ALine)& theALine, |
278 | const Standard_Real theFPar, |
279 | const Standard_Real theLPar, |
280 | IntPatch_SequenceOfLine& theLines) const |
7fd59977 |
281 | { |
e2e0498b |
282 | const Standard_Integer aNbVert = theALine->NbVertex(); |
283 | const Standard_Real aTol = 2.0*myTol3D+Precision::Confusion(); |
284 | IntPatch_SpecPntType aPrePointExist = IntPatch_SPntNone; |
285 | |
286 | NCollection_Array1<Standard_Real> aVertexParams(1, aNbVert); |
287 | NCollection_Array1<IntPatch_Point> aSeqVertex(1, aNbVert); |
288 | |
289 | //It is possible to have several vertices with equal parameters. |
290 | NCollection_Array1<Standard_Boolean> hasVertexBeenChecked(1, aNbVert); |
291 | |
292 | Handle(IntSurf_LineOn2S) aLinOn2S; |
293 | Standard_Real aParameter = theFPar; |
294 | |
295 | for(Standard_Integer i = aVertexParams.Lower(); i <= aVertexParams.Upper(); i++) |
296 | { |
297 | const Standard_Real aPar = theALine->Vertex(i).ParameterOnLine(); |
298 | aVertexParams(i) = aPar; |
299 | hasVertexBeenChecked(i) = Standard_False; |
7fd59977 |
300 | } |
e2e0498b |
301 | |
302 | Standard_Integer aSingularSurfaceID = 0; |
303 | Standard_Real anArrPeriods[] = { 0.0, //U1 |
304 | 0.0, //V1 |
305 | 0.0, //U2 |
306 | 0.0}; //V2 |
307 | |
308 | IntSurf::SetPeriod(myS1, myS2, anArrPeriods); |
309 | |
310 | IntSurf_PntOn2S aPrevLPoint; |
311 | |
312 | while(aParameter < theLPar) |
313 | { |
314 | Standard_Real aStep = (theLPar - aParameter) / (Standard_Real)(myNbPointsInWline - 1); |
315 | if(aStep < Epsilon(theLPar)) |
316 | break; |
317 | |
318 | Standard_Integer aNewVertID = 0; |
319 | aLinOn2S = new IntSurf_LineOn2S; |
320 | |
321 | const Standard_Real aStepMin = 0.1*aStep, aStepMax = 10.0*aStep; |
322 | |
323 | Standard_Boolean isLast = Standard_False; |
324 | Standard_Real aPrevParam = aParameter; |
325 | for(; !isLast; aParameter += aStep) |
7fd59977 |
326 | { |
e2e0498b |
327 | IntSurf_PntOn2S aPOn2S; |
328 | |
329 | if(theLPar <= aParameter) |
330 | { |
331 | isLast = Standard_True; |
332 | if(aPrePointExist != IntPatch_SPntNone) |
333 | { |
334 | break; |
335 | } |
336 | else |
337 | { |
338 | aParameter = theLPar; |
339 | } |
7fd59977 |
340 | } |
e2e0498b |
341 | |
342 | Standard_Real aTgMagn = 0.0; |
343 | { |
344 | gp_Pnt aPnt3d; |
345 | gp_Vec aTg; |
346 | theALine->D1(aParameter, aPnt3d, aTg); |
347 | aTgMagn = aTg.Magnitude(); |
348 | Standard_Real u1 = 0.0, v1 = 0.0, u2 = 0.0, v2 = 0.0; |
349 | myQuad1.Parameters(aPnt3d, u1, v1); |
350 | myQuad2.Parameters(aPnt3d, u2, v2); |
351 | aPOn2S.SetValue(aPnt3d, u1, v1, u2, v2); |
7fd59977 |
352 | } |
e2e0498b |
353 | |
354 | if(aPrePointExist != IntPatch_SPntNone) |
355 | { |
356 | const Standard_Real aURes = Max(myS1->UResolution(myTol3D), |
357 | myS2->UResolution(myTol3D)), |
358 | aVRes = Max(myS1->VResolution(myTol3D), |
359 | myS2->VResolution(myTol3D)); |
360 | |
361 | const Standard_Real aTol2d = (aPrePointExist == IntPatch_SPntPole) ? -1.0 : |
362 | (aPrePointExist == IntPatch_SPntSeamV)? aVRes : |
363 | (aPrePointExist == IntPatch_SPntSeamUV)? Max(aURes, aVRes) : aURes; |
364 | |
365 | IntSurf_PntOn2S aRPT = aPOn2S; |
366 | |
367 | if (aPrePointExist == IntPatch_SPntPole) |
368 | { |
369 | Standard_Real aPrt = 0.5*(aPrevParam + theLPar); |
370 | for (Standard_Integer i = aVertexParams.Lower(); i <= aVertexParams.Upper(); i++) |
371 | { |
372 | const Standard_Real aParam = aVertexParams(i); |
373 | |
374 | if (aParam <= aPrevParam) |
375 | continue; |
376 | |
377 | aPrt = 0.5*(aParam + aPrevParam); |
378 | break; |
379 | } |
380 | |
381 | const gp_Pnt aPnt3d(theALine->Value(aPrt)); |
382 | Standard_Real u1, v1, u2, v2; |
383 | myQuad1.Parameters(aPnt3d, u1, v1); |
384 | myQuad2.Parameters(aPnt3d, u2, v2); |
385 | aRPT.SetValue(aPnt3d, u1, v1, u2, v2); |
386 | |
387 | if (aPOn2S.IsSame(aPrevLPoint, Max(Precision::Approximation(), aTol))) |
388 | { |
389 | //Set V-parameter as precise value found on the previous step. |
390 | if (aSingularSurfaceID == 1) |
391 | { |
392 | aPOn2S.ParametersOnS1(u2, v2); |
393 | aPOn2S.SetValue(Standard_True, u1, v2); |
394 | } |
395 | else //if (aSingularSurfaceID == 2) |
396 | { |
397 | aPOn2S.ParametersOnS2(u1, v1); |
398 | aPOn2S.SetValue(Standard_False, u2, v1); |
399 | } |
400 | } |
401 | } |
402 | |
403 | if(IntPatch_SpecialPoints:: |
404 | ContinueAfterSpecialPoint(myS1, myS2, aRPT, |
405 | aPrePointExist, aTol2d, |
406 | aPrevLPoint, Standard_False)) |
407 | { |
408 | AddPointIntoLine(aLinOn2S, anArrPeriods, aPrevLPoint); |
409 | } |
410 | else if(aParameter == theLPar) |
411 | {// Strictly equal!!! |
412 | break; |
413 | } |
7fd59977 |
414 | } |
e2e0498b |
415 | |
416 | aPrePointExist = IntPatch_SPntNone; |
417 | |
418 | Standard_Integer aVertexNumber = -1; |
419 | for(Standard_Integer i = aVertexParams.Lower(); i <= aVertexParams.Upper(); i++) |
420 | { |
421 | if(hasVertexBeenChecked(i)) |
422 | continue; |
423 | |
424 | const Standard_Real aParam = aVertexParams(i); |
425 | if( ((aPrevParam < aParam) && (aParam <= aParameter)) || |
426 | ((aPrevParam == aParameter) && (aParam == aParameter))) |
427 | { |
428 | aVertexNumber = i; |
429 | break; |
430 | } |
7fd59977 |
431 | } |
e2e0498b |
432 | |
433 | aPrevParam = aParameter; |
434 | |
435 | if(aVertexNumber < 0) |
436 | { |
437 | StepComputing(theALine, aPOn2S, theLPar, aParameter, aTgMagn, |
438 | aStepMin, aStepMax, myTol3D, aStep); |
439 | AddPointIntoLine(aLinOn2S, anArrPeriods, aPOn2S); |
440 | aPrevLPoint = aPOn2S; |
441 | continue; |
7fd59977 |
442 | } |
7fd59977 |
443 | |
e2e0498b |
444 | IntPatch_Point aVtx = theALine->Vertex(aVertexNumber); |
445 | const Standard_Real aNewVertexParam = aLinOn2S->NbPoints() + 1; |
446 | |
447 | //ATTENTION!!! |
448 | // IsPoleOrSeam inserts new point in aLinOn2S if aVtx respects |
449 | //to some special point. Otherwise, aLinOn2S is not changed. |
450 | |
451 | aPrePointExist = IsPoleOrSeam(myS1, myS2, aLinOn2S, aVtx, |
452 | anArrPeriods, aTol, aSingularSurfaceID); |
453 | |
454 | const Standard_Real aCurVertParam = aVtx.ParameterOnLine(); |
455 | if(aPrePointExist != IntPatch_SPntNone) |
7fd59977 |
456 | { |
e2e0498b |
457 | aPrevParam = aParameter = aCurVertParam; |
7fd59977 |
458 | } |
e2e0498b |
459 | else |
460 | { |
461 | if(aVtx.Tolerance() > aTol) |
462 | { |
463 | aVtx.SetValue(aPOn2S); |
464 | AddPointIntoLine(aLinOn2S, anArrPeriods, aPOn2S); |
465 | } |
466 | else |
467 | { |
468 | AddVertexPoint(aLinOn2S, aVtx, anArrPeriods); |
469 | } |
7fd59977 |
470 | } |
7fd59977 |
471 | |
e2e0498b |
472 | aPrevLPoint = aPOn2S = aLinOn2S->Value(aLinOn2S->NbPoints()); |
473 | |
474 | { |
475 | Standard_Boolean isFound = Standard_False; |
476 | const Standard_Real aSqTol = aTol*aTol; |
477 | const gp_Pnt aP1(theALine->Value(aCurVertParam)); |
478 | const IntSurf_PntOn2S& aVertP2S = aVtx.PntOn2S(); |
479 | const Standard_Real aVertToler = aVtx.Tolerance(); |
480 | |
481 | for(Standard_Integer i = aVertexParams.Lower(); i <= aVertexParams.Upper(); i++) |
482 | { |
483 | if(hasVertexBeenChecked(i)) |
484 | continue; |
485 | |
486 | const gp_Pnt aP2(theALine->Value(aVertexParams(i))); |
487 | |
488 | if(aP1.SquareDistance(aP2) < aSqTol) |
489 | { |
490 | IntPatch_Point aVtx = theALine->Vertex(i); |
491 | aVtx.SetValue(aVertP2S); |
492 | aVtx.SetTolerance(aVertToler); |
493 | aVtx.SetParameter(aNewVertexParam); |
494 | aSeqVertex(++aNewVertID) = aVtx; |
495 | hasVertexBeenChecked(i) = Standard_True; |
496 | isFound = Standard_True; |
497 | } |
498 | else if(isFound) |
499 | { |
500 | break; |
501 | } |
502 | } |
7fd59977 |
503 | } |
e2e0498b |
504 | |
505 | if(aPrePointExist != IntPatch_SPntNone) |
506 | break; |
507 | }//for(; !isLast; aParameter += aStep) |
508 | |
509 | if(aLinOn2S->NbPoints() < 2) |
510 | { |
511 | aParameter += aStep; |
512 | continue; |
7fd59977 |
513 | } |
e2e0498b |
514 | |
515 | //----------------------------------------------------------------- |
516 | //-- Computation of transitions of the line on two surfaces --- |
517 | //----------------------------------------------------------------- |
518 | IntSurf_TypeTrans trans1,trans2; |
519 | { |
520 | Standard_Integer indice1; |
521 | Standard_Real dotcross; |
522 | gp_Pnt aPP0, aPP1; |
7fd59977 |
523 | // |
e2e0498b |
524 | trans1=IntSurf_Undecided; |
525 | trans2=IntSurf_Undecided; |
7fd59977 |
526 | // |
e2e0498b |
527 | indice1 = aLinOn2S->NbPoints()/3; |
528 | if(indice1<=2) { |
529 | indice1 = 2; |
7fd59977 |
530 | } |
531 | // |
e2e0498b |
532 | aPP1=aLinOn2S->Value(indice1).Value(); |
533 | aPP0=aLinOn2S->Value(indice1-1).Value(); |
7fd59977 |
534 | // |
e2e0498b |
535 | gp_Vec tgvalid(aPP0, aPP1); |
536 | gp_Vec aNQ1 = myQuad1.Normale(aPP0); |
537 | gp_Vec aNQ2 = myQuad2.Normale(aPP0); |
7fd59977 |
538 | // |
e2e0498b |
539 | dotcross = tgvalid.DotCross(aNQ2, aNQ1); |
540 | if (dotcross > myTolTransition) { |
541 | trans1 = IntSurf_Out; |
542 | trans2 = IntSurf_In; |
7fd59977 |
543 | } |
e2e0498b |
544 | else if(dotcross < -myTolTransition) { |
545 | trans1 = IntSurf_In; |
546 | trans2 = IntSurf_Out; |
547 | } |
7fd59977 |
548 | } |
e2e0498b |
549 | |
550 | //----------------------------------------------------------------- |
551 | //-- W L i n e c r e a t i o n --- |
552 | //----------------------------------------------------------------- |
553 | Handle(IntPatch_WLine) aWLine; |
7fd59977 |
554 | // |
e2e0498b |
555 | if(theALine->TransitionOnS1() == IntSurf_Touch) { |
556 | aWLine = new IntPatch_WLine(aLinOn2S, |
557 | theALine->IsTangent(), |
558 | theALine->SituationS1(), |
559 | theALine->SituationS2()); |
7fd59977 |
560 | } |
e2e0498b |
561 | if(theALine->TransitionOnS1() == IntSurf_Undecided) { |
562 | aWLine = new IntPatch_WLine(aLinOn2S, theALine->IsTangent()); |
563 | } |
564 | else { |
565 | aWLine = new IntPatch_WLine(aLinOn2S, theALine->IsTangent(), |
566 | trans1, // aline->TransitionOnS1(), |
567 | trans2); //aline->TransitionOnS2()); |
7fd59977 |
568 | } |
7fd59977 |
569 | |
e2e0498b |
570 | for(Standard_Integer i = aSeqVertex.Lower(); i <= aNewVertID; i++) |
7fd59977 |
571 | { |
e2e0498b |
572 | const IntPatch_Point& aVtx = aSeqVertex(i); |
573 | aWLine->AddVertex(aVtx); |
7fd59977 |
574 | } |
e2e0498b |
575 | |
576 | aWLine->SetPeriod(anArrPeriods[0],anArrPeriods[1],anArrPeriods[2],anArrPeriods[3]); |
577 | |
578 | aWLine->ComputeVertexParameters(myTol3D); |
579 | |
580 | aWLine->EnablePurging(Standard_False); |
581 | theLines.Append(aWLine); |
582 | }//while(aParameter < theLPar) |
7fd59977 |
583 | } |
584 | |
7fd59977 |
585 | //======================================================================= |
e2e0498b |
586 | //function : CheckDeflection |
587 | //purpose : Returns: |
588 | // -1 - step is too small |
589 | // 0 - step is normal |
590 | // +1 - step is too big |
7fd59977 |
591 | //======================================================================= |
e2e0498b |
592 | Standard_Integer IntPatch_ALineToWLine::CheckDeflection(const gp_XYZ& theMidPt, |
593 | const Standard_Real theMaxDeflection) const |
7fd59977 |
594 | { |
e2e0498b |
595 | Standard_Real aDist = Abs(myQuad1.Distance(theMidPt)); |
596 | if(aDist > theMaxDeflection) |
597 | return 1; |
598 | |
599 | aDist = Max(Abs(myQuad2.Distance(theMidPt)), aDist); |
600 | |
601 | if(aDist > theMaxDeflection) |
602 | return 1; |
603 | |
604 | if((aDist + aDist) < theMaxDeflection) |
605 | return -1; |
606 | |
607 | return 0; |
608 | } |
609 | |
7fd59977 |
610 | //======================================================================= |
e2e0498b |
611 | //function : StepComputing |
7fd59977 |
612 | //purpose : |
613 | //======================================================================= |
e2e0498b |
614 | Standard_Boolean IntPatch_ALineToWLine:: |
615 | StepComputing(const Handle(IntPatch_ALine)& theALine, |
616 | const IntSurf_PntOn2S& thePOn2S, |
617 | const Standard_Real theLastParOfAline, |
618 | const Standard_Real theCurParam, |
619 | const Standard_Real theTgMagnitude, |
620 | const Standard_Real theStepMin, |
621 | const Standard_Real theStepMax, |
622 | const Standard_Real theMaxDeflection, |
623 | Standard_Real& theStep) const |
7fd59977 |
624 | { |
e2e0498b |
625 | if(theTgMagnitude < Precision::Confusion()) |
626 | return Standard_False; |
627 | |
628 | const Standard_Real anEps = myTol3D; |
629 | |
630 | //Indeed, 1.0e+15 < 2^50 < 1.0e+16. Therefore, |
631 | //if we apply bisection method to the range with length |
632 | //1.0e+6 then we will be able to find solution with max error ~1.0e-9. |
633 | const Standard_Integer aNbIterMax = 50; |
634 | |
635 | const Standard_Real aNotFilledRange = theLastParOfAline - theCurParam; |
636 | Standard_Real aMinStep = theStepMin, aMaxStep = Min(theStepMax, aNotFilledRange); |
637 | |
638 | if(aMinStep > aMaxStep) |
639 | { |
640 | theStep = aMaxStep; |
641 | return Standard_True; |
7fd59977 |
642 | } |
e2e0498b |
643 | |
644 | const Standard_Real aR = IntPatch_PointLine:: |
645 | CurvatureRadiusOfIntersLine(myS1, myS2, thePOn2S); |
646 | |
647 | if(aR < 0.0) |
648 | { |
649 | return Standard_False; |
650 | } |
651 | else |
652 | { |
653 | //The 3D-step is defined as length of the tangent to the osculating circle |
654 | //by the condition that the distance from end point of the tangent to the |
655 | //circle is no greater than anEps. theStep is the step in |
656 | //parameter space of intersection curve (must be converted from 3D-step). |
657 | |
658 | theStep = Min(sqrt(anEps*(2.0*aR + anEps))/theTgMagnitude, aMaxStep); |
659 | theStep = Max(theStep, aMinStep); |
7fd59977 |
660 | } |
e2e0498b |
661 | |
662 | //The step value has been computed for osculating circle. |
663 | //Now it should be checked for real intersection curve |
664 | //and is made more precise in case of necessity. |
665 | |
666 | Standard_Integer aNbIter = 0; |
667 | do |
668 | { |
669 | aNbIter++; |
670 | |
671 | const gp_XYZ& aP1 = thePOn2S.Value().XYZ(); |
672 | const gp_XYZ aP2(theALine->Value(theCurParam + theStep).XYZ()); |
673 | const Standard_Integer aStatus = CheckDeflection(0.5*(aP1 + aP2), theMaxDeflection); |
674 | |
675 | if(aStatus == 0) |
676 | break; |
677 | |
678 | if(aStatus < 0) |
679 | { |
680 | aMinStep = theStep; |
7fd59977 |
681 | } |
e2e0498b |
682 | else //if(aStatus > 0) |
683 | { |
684 | aMaxStep = theStep; |
7fd59977 |
685 | } |
e2e0498b |
686 | |
687 | theStep = 0.5*(aMinStep + aMaxStep); |
7fd59977 |
688 | } |
e2e0498b |
689 | while(((aMaxStep - aMinStep) > Precision::PConfusion()) && (aNbIter <= aNbIterMax)); |
690 | |
691 | if(aNbIter > aNbIterMax) |
692 | return Standard_False; |
693 | |
694 | return Standard_True; |
7fd59977 |
695 | } |