7fd59977 |
1 | // File: IntPatch_ImpImpIntersection_4.gxx |
2 | // Created: Thu May 7 08:47:45 1992 |
3 | // Author: Jacques GOUSSARD |
4 | // Copyright: OPEN CASCADE 1992 |
5 | |
6 | #include <IntAna_ListOfCurve.hxx> |
7 | #include <IntAna_ListIteratorOfListOfCurve.hxx> |
8 | |
9 | static |
10 | Standard_Boolean ExploreCurve(const gp_Cylinder& aCy, |
11 | const gp_Cone& aCo, |
12 | IntAna_Curve& aC, |
13 | const Standard_Real aTol, |
14 | IntAna_ListOfCurve& aLC); |
15 | static |
16 | Standard_Boolean IsToReverse(const gp_Cylinder& Cy1, |
17 | const gp_Cylinder& Cy2, |
18 | const Standard_Real Tol); |
19 | |
20 | //======================================================================= |
21 | //function : ProcessBounds |
22 | //purpose : |
23 | //======================================================================= |
24 | void ProcessBounds(const Handle(IntPatch_ALine)& alig, //-- ligne courante |
25 | const IntPatch_SequenceOfLine& slin, |
26 | const IntSurf_Quadric& Quad1, |
27 | const IntSurf_Quadric& Quad2, |
28 | Standard_Boolean& procf, |
29 | const gp_Pnt& ptf, //-- Debut Ligne Courante |
30 | const Standard_Real first, //-- Paramf |
31 | Standard_Boolean& procl, |
32 | const gp_Pnt& ptl, //-- Fin Ligne courante |
33 | const Standard_Real last, //-- Paraml |
34 | Standard_Boolean& Multpoint, |
35 | const Standard_Real Tol) |
36 | { |
37 | Standard_Integer j,k; |
38 | Standard_Real U1,V1,U2,V2; |
39 | IntPatch_Point ptsol; |
40 | Standard_Real d; |
41 | |
42 | if (procf && procl) { |
43 | j = slin.Length() + 1; |
44 | } |
45 | else { |
46 | j = 1; |
47 | } |
48 | |
49 | |
50 | //-- On prend les lignes deja enregistrees |
51 | |
52 | while (j <= slin.Length()) { |
53 | if(slin.Value(j)->ArcType() == IntPatch_Analytic) { |
54 | const Handle(IntPatch_ALine)& aligold = *((Handle(IntPatch_ALine)*)&slin.Value(j)); |
55 | k = 1; |
56 | |
57 | //-- On prend les vertex des lignes deja enregistrees |
58 | |
59 | while (k <= aligold->NbVertex()) { |
60 | ptsol = aligold->Vertex(k); |
61 | if (!procf) { |
62 | d=ptf.Distance(ptsol.Value()); |
63 | if (d <= Tol) { |
64 | if (!ptsol.IsMultiple()) { |
65 | //-- le point ptsol (de aligold) est declare multiple sur aligold |
66 | Multpoint = Standard_True; |
67 | ptsol.SetMultiple(Standard_True); |
68 | aligold->Replace(k,ptsol); |
69 | } |
70 | ptsol.SetParameter(first); |
71 | alig->AddVertex(ptsol); |
72 | alig->SetFirstPoint(alig->NbVertex()); |
73 | procf = Standard_True; |
74 | |
75 | //-- On restore le point avec son parametre sur aligold |
76 | ptsol = aligold->Vertex(k); |
77 | |
78 | } |
79 | } |
80 | if (!procl) { |
81 | if (ptl.Distance(ptsol.Value()) <= Tol) { |
82 | if (!ptsol.IsMultiple()) { |
83 | Multpoint = Standard_True; |
84 | ptsol.SetMultiple(Standard_True); |
85 | aligold->Replace(k,ptsol); |
86 | } |
87 | ptsol.SetParameter(last); |
88 | alig->AddVertex(ptsol); |
89 | alig->SetLastPoint(alig->NbVertex()); |
90 | procl = Standard_True; |
91 | |
92 | //-- On restore le point avec son parametre sur aligold |
93 | ptsol = aligold->Vertex(k); |
94 | |
95 | } |
96 | } |
97 | if (procf && procl) { |
98 | k = aligold->NbVertex()+1; |
99 | } |
100 | else { |
101 | k = k+1; |
102 | } |
103 | } |
104 | if (procf && procl) { |
105 | j = slin.Length()+1; |
106 | } |
107 | else { |
108 | j = j+1; |
109 | } |
110 | } |
111 | } |
112 | if (!procf && !procl) { |
113 | Quad1.Parameters(ptf,U1,V1); |
114 | Quad2.Parameters(ptf,U2,V2); |
115 | ptsol.SetValue(ptf,Tol,Standard_False); |
116 | ptsol.SetParameters(U1,V1,U2,V2); |
117 | ptsol.SetParameter(first); |
118 | if (ptf.Distance(ptl) <= Tol) { |
119 | ptsol.SetMultiple(Standard_True); // a voir |
120 | Multpoint = Standard_True; // a voir de meme |
121 | alig->AddVertex(ptsol); |
122 | alig->SetFirstPoint(alig->NbVertex()); |
123 | |
124 | ptsol.SetParameter(last); |
125 | alig->AddVertex(ptsol); |
126 | alig->SetLastPoint(alig->NbVertex()); |
127 | } |
128 | else { |
129 | alig->AddVertex(ptsol); |
130 | alig->SetFirstPoint(alig->NbVertex()); |
131 | Quad1.Parameters(ptl,U1,V1); |
132 | Quad2.Parameters(ptl,U2,V2); |
133 | ptsol.SetValue(ptl,Tol,Standard_False); |
134 | ptsol.SetParameters(U1,V1,U2,V2); |
135 | ptsol.SetParameter(last); |
136 | alig->AddVertex(ptsol); |
137 | alig->SetLastPoint(alig->NbVertex()); |
138 | } |
139 | } |
140 | else if (!procf) { |
141 | Quad1.Parameters(ptf,U1,V1); |
142 | Quad2.Parameters(ptf,U2,V2); |
143 | ptsol.SetValue(ptf,Tol,Standard_False); |
144 | ptsol.SetParameters(U1,V1,U2,V2); |
145 | ptsol.SetParameter(first); |
146 | alig->AddVertex(ptsol); |
147 | alig->SetFirstPoint(alig->NbVertex()); |
148 | } |
149 | else if (!procl) { |
150 | Quad1.Parameters(ptl,U1,V1); |
151 | Quad2.Parameters(ptl,U2,V2); |
152 | ptsol.SetValue(ptl,Tol,Standard_False); |
153 | ptsol.SetParameters(U1,V1,U2,V2); |
154 | ptsol.SetParameter(last); |
155 | alig->AddVertex(ptsol); |
156 | alig->SetLastPoint(alig->NbVertex()); |
157 | } |
158 | } |
159 | //======================================================================= |
160 | //function : IntCyCy |
161 | //purpose : |
162 | //======================================================================= |
163 | Standard_Boolean IntCyCy(const IntSurf_Quadric& Quad1, |
164 | const IntSurf_Quadric& Quad2, |
165 | const Standard_Real Tol, |
166 | Standard_Boolean& Empty, |
167 | Standard_Boolean& Same, |
168 | Standard_Boolean& Multpoint, |
169 | IntPatch_SequenceOfLine& slin, |
170 | IntPatch_SequenceOfPoint& spnt) |
171 | |
172 | { |
173 | IntPatch_Point ptsol; |
174 | |
175 | Standard_Integer i; |
176 | |
177 | IntSurf_TypeTrans trans1,trans2; |
178 | IntAna_ResultType typint; |
179 | |
180 | gp_Elips elipsol; |
181 | gp_Lin linsol; |
182 | |
183 | gp_Cylinder Cy1(Quad1.Cylinder()); |
184 | gp_Cylinder Cy2(Quad2.Cylinder()); |
185 | |
186 | IntAna_QuadQuadGeo inter(Cy1,Cy2,Tol); |
187 | |
188 | if (!inter.IsDone()) {return Standard_False;} |
189 | |
190 | typint = inter.TypeInter(); |
191 | Standard_Integer NbSol = inter.NbSolutions(); |
192 | Empty = Standard_False; |
193 | Same = Standard_False; |
194 | |
195 | switch (typint) { |
196 | |
197 | case IntAna_Empty : |
198 | { |
199 | Empty = Standard_True; |
200 | } |
201 | break; |
202 | |
203 | case IntAna_Same: |
204 | { |
205 | Same = Standard_True; |
206 | } |
207 | break; |
208 | |
209 | |
210 | case IntAna_Point : |
211 | { |
212 | gp_Pnt psol(inter.Point(1)); |
213 | Standard_Real U1,V1,U2,V2; |
214 | Quad1.Parameters(psol,U1,V1); |
215 | Quad2.Parameters(psol,U2,V2); |
216 | ptsol.SetValue(psol,Tol,Standard_True); |
217 | ptsol.SetParameters(U1,V1,U2,V2); |
218 | spnt.Append(ptsol); |
219 | } |
220 | break; |
221 | |
222 | case IntAna_Line: |
223 | { |
224 | gp_Pnt ptref; |
225 | if (NbSol == 1) { // ligne de tangence |
226 | linsol = inter.Line(1); |
227 | ptref = linsol.Location(); |
228 | gp_Dir crb1(gp_Vec(ptref,Cy1.Location())); |
229 | gp_Dir crb2(gp_Vec(ptref,Cy2.Location())); |
230 | gp_Vec norm1(Quad1.Normale(ptref)); |
231 | gp_Vec norm2(Quad2.Normale(ptref)); |
232 | IntSurf_Situation situcyl1; |
233 | IntSurf_Situation situcyl2; |
234 | |
235 | if (crb1.Dot(crb2) < 0.) { // centre de courbures "opposes" |
236 | if (norm1.Dot(crb1) > 0.) { |
237 | situcyl2 = IntSurf_Inside; |
238 | } |
239 | else { |
240 | situcyl2 = IntSurf_Outside; |
241 | } |
242 | if (norm2.Dot(crb2) > 0.) { |
243 | situcyl1 = IntSurf_Inside; |
244 | } |
245 | else { |
246 | situcyl1 = IntSurf_Outside; |
247 | } |
248 | } |
249 | else { |
250 | if (Cy1.Radius() < Cy2.Radius()) { |
251 | if (norm1.Dot(crb1) > 0.) { |
252 | situcyl2 = IntSurf_Inside; |
253 | } |
254 | else { |
255 | situcyl2 = IntSurf_Outside; |
256 | } |
257 | if (norm2.Dot(crb2) > 0.) { |
258 | situcyl1 = IntSurf_Outside; |
259 | } |
260 | else { |
261 | situcyl1 = IntSurf_Inside; |
262 | } |
263 | } |
264 | else { |
265 | if (norm1.Dot(crb1) > 0.) { |
266 | situcyl2 = IntSurf_Outside; |
267 | } |
268 | else { |
269 | situcyl2 = IntSurf_Inside; |
270 | } |
271 | if (norm2.Dot(crb2) > 0.) { |
272 | situcyl1 = IntSurf_Inside; |
273 | } |
274 | else { |
275 | situcyl1 = IntSurf_Outside; |
276 | } |
277 | } |
278 | } |
279 | Handle(IntPatch_GLine) glig = new IntPatch_GLine(linsol, Standard_True, situcyl1, situcyl2); |
280 | slin.Append(glig); |
281 | } |
282 | else { |
283 | for (i=1; i <= NbSol; i++) { |
284 | linsol = inter.Line(i); |
285 | ptref = linsol.Location(); |
286 | gp_Vec lsd = linsol.Direction(); |
287 | Standard_Real qwe = lsd.DotCross(Quad2.Normale(ptref),Quad1.Normale(ptref)); |
288 | if (qwe >0.00000001) { |
289 | trans1 = IntSurf_Out; |
290 | trans2 = IntSurf_In; |
291 | } |
292 | else if (qwe <-0.00000001) { |
293 | trans1 = IntSurf_In; |
294 | trans2 = IntSurf_Out; |
295 | } |
296 | else { |
297 | trans1=trans2=IntSurf_Undecided; |
298 | } |
299 | |
300 | Handle(IntPatch_GLine) glig = new IntPatch_GLine(linsol, Standard_False,trans1,trans2); |
301 | slin.Append(glig); |
302 | } |
303 | } |
304 | } |
305 | break; |
306 | |
307 | case IntAna_Ellipse: |
308 | { |
309 | gp_Vec Tgt; |
310 | gp_Pnt ptref; |
311 | IntPatch_Point pmult1; |
312 | IntPatch_Point pmult2; |
313 | elipsol = inter.Ellipse(1); |
314 | gp_Pnt pttang1(ElCLib::Value(PI*0.5,elipsol)); |
315 | gp_Pnt pttang2(ElCLib::Value(1.5*PI,elipsol)); |
316 | |
317 | Multpoint = Standard_True; |
318 | pmult1.SetValue(pttang1,Tol,Standard_True); |
319 | pmult2.SetValue(pttang2,Tol,Standard_True); |
320 | pmult1.SetMultiple(Standard_True); |
321 | pmult2.SetMultiple(Standard_True); |
322 | |
323 | Standard_Real oU1,oV1,oU2,oV2; |
324 | Quad1.Parameters(pttang1,oU1,oV1); |
325 | Quad2.Parameters(pttang1,oU2,oV2); |
326 | pmult1.SetParameters(oU1,oV1,oU2,oV2); |
327 | |
328 | Quad1.Parameters(pttang2,oU1,oV1); |
329 | Quad2.Parameters(pttang2,oU2,oV2); |
330 | pmult2.SetParameters(oU1,oV1,oU2,oV2); |
331 | |
332 | |
333 | // on traite la premiere ellipse |
334 | |
335 | //-- Calcul de la Transition de la ligne |
336 | ElCLib::D1(0.,elipsol,ptref,Tgt); |
337 | Standard_Real qwe=Tgt.DotCross(Quad2.Normale(ptref),Quad1.Normale(ptref)); |
338 | if (qwe>0.00000001) { |
339 | trans1 = IntSurf_Out; |
340 | trans2 = IntSurf_In; |
341 | } |
342 | else if (qwe<-0.00000001) { |
343 | trans1 = IntSurf_In; |
344 | trans2 = IntSurf_Out; |
345 | } |
346 | else { |
347 | trans1=trans2=IntSurf_Undecided; |
348 | } |
349 | //-- Transition calculee au point 0 -> Trans2 , Trans1 |
350 | //-- car ici, on devarit calculer en PI |
351 | Handle(IntPatch_GLine) glig = new IntPatch_GLine(elipsol,Standard_False,trans2,trans1); |
352 | pmult1.SetParameter(PI/2.); |
353 | glig->AddVertex(pmult1); |
354 | glig->SetFirstPoint(1); |
355 | pmult2.SetParameter(1.5*PI); |
356 | glig->AddVertex(pmult2); |
357 | glig->SetLastPoint(2); |
358 | slin.Append(glig); |
359 | |
360 | //-- Transitions calculee au point 0 OK |
361 | glig = new IntPatch_GLine(elipsol,Standard_False,trans1,trans2); |
362 | pmult2.SetParameter(-PI/2.); |
363 | glig->AddVertex(pmult2); |
364 | glig->SetFirstPoint(1); |
365 | glig->AddVertex(pmult1); |
366 | glig->SetLastPoint(2); |
367 | slin.Append(glig); |
368 | |
369 | |
370 | // on traite la deuxieme ellipse |
371 | |
372 | elipsol = inter.Ellipse(2); |
373 | |
374 | Standard_Real param1 = ElCLib::Parameter(elipsol,pttang1); |
375 | Standard_Real param2 = ElCLib::Parameter(elipsol,pttang2); |
376 | Standard_Real parampourtransition; |
377 | if (param1 < param2) { |
378 | pmult1.SetParameter(PI*0.5); |
379 | pmult2.SetParameter(1.5*PI); |
380 | parampourtransition = PI; |
381 | } |
382 | else { |
383 | pmult1.SetParameter(-PI*0.5); |
384 | pmult2.SetParameter(PI*0.5); |
385 | parampourtransition = 0.0; |
386 | } |
387 | |
388 | //-- Calcul des transitions de ligne pour la premiere ligne |
389 | ElCLib::D1(parampourtransition,elipsol,ptref,Tgt); |
390 | qwe=Tgt.DotCross(Quad2.Normale(ptref),Quad1.Normale(ptref)); |
391 | if(qwe> 0.00000001) { |
392 | trans1 = IntSurf_Out; |
393 | trans2 = IntSurf_In; |
394 | } |
395 | else if(qwe< -0.00000001) { |
396 | trans1 = IntSurf_In; |
397 | trans2 = IntSurf_Out; |
398 | } |
399 | else { |
400 | trans1=trans2=IntSurf_Undecided; |
401 | } |
402 | //-- La transition a ete calculee sur un point de cette ligne |
403 | glig = new IntPatch_GLine(elipsol,Standard_False,trans1,trans2); |
404 | glig->AddVertex(pmult1); |
405 | glig->SetFirstPoint(1); |
406 | glig->AddVertex(pmult2); |
407 | glig->SetLastPoint(2); |
408 | slin.Append(glig); |
409 | |
410 | if (param1 < param2) { |
411 | pmult2.SetParameter(-PI*0.5); |
412 | } |
413 | else { |
414 | pmult1.SetParameter(1.5*PI); |
415 | } |
416 | |
417 | //-- Sur l'autre ligne, on invertse la transition |
418 | glig = new IntPatch_GLine(elipsol,Standard_False,trans2,trans1); |
419 | glig->AddVertex(pmult2); |
420 | glig->SetFirstPoint(1); |
421 | glig->AddVertex(pmult1); |
422 | glig->SetLastPoint(2); |
423 | slin.Append(glig); |
424 | } |
425 | break; |
426 | |
427 | |
428 | case IntAna_NoGeometricSolution: |
429 | { |
430 | Standard_Boolean bReverse; |
431 | Standard_Real U1,V1,U2,V2; |
432 | gp_Pnt psol; |
433 | // |
434 | bReverse=IsToReverse(Cy1, Cy2, Tol); |
435 | if (bReverse){ |
436 | Cy2=Quad1.Cylinder(); |
437 | Cy1=Quad2.Cylinder(); |
438 | } |
439 | // |
440 | IntAna_IntQuadQuad anaint(Cy1,Cy2,Tol); |
441 | if (!anaint.IsDone()) { |
442 | return Standard_False; |
443 | } |
444 | |
445 | if (anaint.NbPnt() == 0 && anaint.NbCurve() == 0) { |
446 | Empty = Standard_True; |
447 | } |
448 | else { |
449 | NbSol = anaint.NbPnt(); |
450 | for (i = 1; i <= NbSol; i++) { |
451 | psol = anaint.Point(i); |
452 | Quad1.Parameters(psol,U1,V1); |
453 | Quad2.Parameters(psol,U2,V2); |
454 | ptsol.SetValue(psol,Tol,Standard_True); |
455 | ptsol.SetParameters(U1,V1,U2,V2); |
456 | spnt.Append(ptsol); |
457 | } |
458 | |
459 | gp_Pnt ptvalid, ptf, ptl; |
460 | gp_Vec tgvalid; |
461 | |
462 | Standard_Real first,last,para; |
463 | IntAna_Curve curvsol; |
464 | Standard_Boolean tgfound; |
465 | Standard_Integer kount; |
466 | |
467 | NbSol = anaint.NbCurve(); |
468 | for (i = 1; i <= NbSol; i++) { |
469 | curvsol = anaint.Curve(i); |
470 | curvsol.Domain(first,last); |
471 | ptf = curvsol.Value(first); |
472 | ptl = curvsol.Value(last); |
473 | |
474 | para = last; |
475 | kount = 1; |
476 | tgfound = Standard_False; |
477 | |
478 | while (!tgfound) { |
479 | para = (1.123*first + para)/2.123; |
480 | tgfound = curvsol.D1u(para,ptvalid,tgvalid); |
481 | if (!tgfound) { |
482 | kount ++; |
483 | tgfound = kount > 5; |
484 | } |
485 | } |
486 | Handle(IntPatch_ALine) alig; |
487 | if (kount <= 5) { |
488 | Standard_Real qwe = tgvalid.DotCross(Quad2.Normale(ptvalid), |
489 | Quad1.Normale(ptvalid)); |
490 | if(qwe>0.00000001) { |
491 | trans1 = IntSurf_Out; |
492 | trans2 = IntSurf_In; |
493 | } |
494 | else if(qwe<-0.00000001) { |
495 | trans1 = IntSurf_In; |
496 | trans2 = IntSurf_Out; |
497 | } |
498 | else { |
499 | trans1=trans2=IntSurf_Undecided; |
500 | } |
501 | alig = new IntPatch_ALine(curvsol,Standard_False,trans1,trans2); |
502 | } |
503 | else { |
504 | alig = new IntPatch_ALine(curvsol,Standard_False); |
505 | //-- cout << "Transition indeterminee" << endl; |
506 | } |
507 | Standard_Boolean TempFalse1 = Standard_False; |
508 | Standard_Boolean TempFalse2 = Standard_False; |
509 | |
510 | ProcessBounds(alig,slin,Quad1,Quad2,TempFalse1,ptf,first, |
511 | TempFalse2,ptl,last,Multpoint,Tol); |
512 | slin.Append(alig); |
513 | } |
514 | } |
515 | } |
516 | break; |
517 | |
518 | default: |
519 | { |
520 | return Standard_False; |
521 | } |
522 | } |
523 | return Standard_True; |
524 | } |
525 | |
526 | |
527 | //======================================================================= |
528 | //function : IntCySp |
529 | //purpose : |
530 | //======================================================================= |
531 | Standard_Boolean IntCySp(const IntSurf_Quadric& Quad1, |
532 | const IntSurf_Quadric& Quad2, |
533 | const Standard_Real Tol, |
534 | const Standard_Boolean Reversed, |
535 | Standard_Boolean& Empty, |
536 | Standard_Boolean& Multpoint, |
537 | IntPatch_SequenceOfLine& slin, |
538 | IntPatch_SequenceOfPoint& spnt) |
539 | |
540 | { |
541 | Standard_Integer i; |
542 | |
543 | IntSurf_TypeTrans trans1,trans2; |
544 | IntAna_ResultType typint; |
545 | IntPatch_Point ptsol; |
546 | gp_Circ cirsol; |
547 | |
548 | gp_Cylinder Cy; |
549 | gp_Sphere Sp; |
550 | |
551 | if (!Reversed) { |
552 | Cy = Quad1.Cylinder(); |
553 | Sp = Quad2.Sphere(); |
554 | } |
555 | else { |
556 | Cy = Quad2.Cylinder(); |
557 | Sp = Quad1.Sphere(); |
558 | } |
559 | IntAna_QuadQuadGeo inter(Cy,Sp,Tol); |
560 | |
561 | if (!inter.IsDone()) {return Standard_False;} |
562 | |
563 | typint = inter.TypeInter(); |
564 | Standard_Integer NbSol = inter.NbSolutions(); |
565 | Empty = Standard_False; |
566 | |
567 | switch (typint) { |
568 | |
569 | case IntAna_Empty : |
570 | { |
571 | Empty = Standard_True; |
572 | } |
573 | break; |
574 | |
575 | case IntAna_Point : |
576 | { |
577 | gp_Pnt psol(inter.Point(1)); |
578 | Standard_Real U1,V1,U2,V2; |
579 | Quad1.Parameters(psol,U1,V1); |
580 | Quad2.Parameters(psol,U2,V2); |
581 | ptsol.SetValue(psol,Tol,Standard_True); |
582 | ptsol.SetParameters(U1,V1,U2,V2); |
583 | spnt.Append(ptsol); |
584 | } |
585 | break; |
586 | |
587 | case IntAna_Circle: |
588 | { |
589 | cirsol = inter.Circle(1); |
590 | gp_Vec Tgt; |
591 | gp_Pnt ptref; |
592 | ElCLib::D1(0.,cirsol,ptref,Tgt); |
593 | |
594 | if (NbSol == 1) { |
595 | gp_Vec TestCurvature(ptref,Sp.Location()); |
596 | gp_Vec Normsp,Normcyl; |
597 | if (!Reversed) { |
598 | Normcyl = Quad1.Normale(ptref); |
599 | Normsp = Quad2.Normale(ptref); |
600 | } |
601 | else { |
602 | Normcyl = Quad2.Normale(ptref); |
603 | Normsp = Quad1.Normale(ptref); |
604 | } |
605 | |
606 | IntSurf_Situation situcyl; |
607 | IntSurf_Situation situsp; |
608 | |
609 | if (Normcyl.Dot(TestCurvature) > 0.) { |
610 | situsp = IntSurf_Outside; |
611 | if (Normsp.Dot(Normcyl) > 0.) { |
612 | situcyl = IntSurf_Inside; |
613 | } |
614 | else { |
615 | situcyl = IntSurf_Outside; |
616 | } |
617 | } |
618 | else { |
619 | situsp = IntSurf_Inside; |
620 | if (Normsp.Dot(Normcyl) > 0.) { |
621 | situcyl = IntSurf_Outside; |
622 | } |
623 | else { |
624 | situcyl = IntSurf_Inside; |
625 | } |
626 | } |
627 | Handle(IntPatch_GLine) glig; |
628 | if (!Reversed) { |
629 | glig = new IntPatch_GLine(cirsol, Standard_True, situcyl, situsp); |
630 | } |
631 | else { |
632 | glig = new IntPatch_GLine(cirsol, Standard_True, situsp, situcyl); |
633 | } |
634 | slin.Append(glig); |
635 | } |
636 | else { |
637 | if (Tgt.DotCross(Quad2.Normale(ptref),Quad1.Normale(ptref)) > 0.0) { |
638 | trans1 = IntSurf_Out; |
639 | trans2 = IntSurf_In; |
640 | } |
641 | else { |
642 | trans1 = IntSurf_In; |
643 | trans2 = IntSurf_Out; |
644 | } |
645 | Handle(IntPatch_GLine) glig = new IntPatch_GLine(cirsol,Standard_False,trans1,trans2); |
646 | slin.Append(glig); |
647 | |
648 | cirsol = inter.Circle(2); |
649 | ElCLib::D1(0.,cirsol,ptref,Tgt); |
650 | Standard_Real qwe = Tgt.DotCross(Quad2.Normale(ptref),Quad1.Normale(ptref)); |
651 | if(qwe> 0.0000001) { |
652 | trans1 = IntSurf_Out; |
653 | trans2 = IntSurf_In; |
654 | } |
655 | else if(qwe<-0.0000001) { |
656 | trans1 = IntSurf_In; |
657 | trans2 = IntSurf_Out; |
658 | } |
659 | else { |
660 | trans1=trans2=IntSurf_Undecided; |
661 | } |
662 | glig = new IntPatch_GLine(cirsol,Standard_False,trans1,trans2); |
663 | slin.Append(glig); |
664 | } |
665 | } |
666 | break; |
667 | |
668 | case IntAna_NoGeometricSolution: |
669 | { |
670 | gp_Pnt psol; |
671 | Standard_Real U1,V1,U2,V2; |
672 | IntAna_IntQuadQuad anaint(Cy,Sp,Tol); |
673 | if (!anaint.IsDone()) { |
674 | return Standard_False; |
675 | } |
676 | |
677 | if (anaint.NbPnt()==0 && anaint.NbCurve()==0) { |
678 | Empty = Standard_True; |
679 | } |
680 | else { |
681 | |
682 | NbSol = anaint.NbPnt(); |
683 | for (i = 1; i <= NbSol; i++) { |
684 | psol = anaint.Point(i); |
685 | Quad1.Parameters(psol,U1,V1); |
686 | Quad2.Parameters(psol,U2,V2); |
687 | ptsol.SetValue(psol,Tol,Standard_True); |
688 | ptsol.SetParameters(U1,V1,U2,V2); |
689 | spnt.Append(ptsol); |
690 | } |
691 | |
692 | gp_Pnt ptvalid,ptf,ptl; |
693 | gp_Vec tgvalid; |
694 | Standard_Real first,last,para; |
695 | IntAna_Curve curvsol; |
696 | Standard_Boolean tgfound; |
697 | Standard_Integer kount; |
698 | |
699 | NbSol = anaint.NbCurve(); |
700 | for (i = 1; i <= NbSol; i++) { |
701 | curvsol = anaint.Curve(i); |
702 | curvsol.Domain(first,last); |
703 | ptf = curvsol.Value(first); |
704 | ptl = curvsol.Value(last); |
705 | |
706 | para = last; |
707 | kount = 1; |
708 | tgfound = Standard_False; |
709 | |
710 | while (!tgfound) { |
711 | para = (1.123*first + para)/2.123; |
712 | tgfound = curvsol.D1u(para,ptvalid,tgvalid); |
713 | if (!tgfound) { |
714 | kount ++; |
715 | tgfound = kount > 5; |
716 | } |
717 | } |
718 | Handle(IntPatch_ALine) alig; |
719 | if (kount <= 5) { |
720 | Standard_Real qwe = tgvalid.DotCross(Quad2.Normale(ptvalid), |
721 | Quad1.Normale(ptvalid)); |
722 | if(qwe> 0.00000001) { |
723 | trans1 = IntSurf_Out; |
724 | trans2 = IntSurf_In; |
725 | } |
726 | else if(qwe<-0.00000001) { |
727 | trans1 = IntSurf_In; |
728 | trans2 = IntSurf_Out; |
729 | } |
730 | else { |
731 | trans1=trans2=IntSurf_Undecided; |
732 | } |
733 | alig = new IntPatch_ALine(curvsol,Standard_False,trans1,trans2); |
734 | } |
735 | else { |
736 | alig = new IntPatch_ALine(curvsol,Standard_False); |
737 | } |
738 | Standard_Boolean TempFalse1a = Standard_False; |
739 | Standard_Boolean TempFalse2a = Standard_False; |
740 | |
741 | //-- ptf et ptl : points debut et fin de alig |
742 | |
743 | ProcessBounds(alig,slin,Quad1,Quad2,TempFalse1a,ptf,first, |
744 | TempFalse2a,ptl,last,Multpoint,Tol); |
745 | slin.Append(alig); |
746 | } //-- boucle sur les lignes |
747 | } //-- solution avec au moins une lihne |
748 | } |
749 | break; |
750 | |
751 | default: |
752 | { |
753 | return Standard_False; |
754 | } |
755 | } |
756 | return Standard_True; |
757 | } |
758 | //======================================================================= |
759 | //function : IntCyCo |
760 | //purpose : |
761 | //======================================================================= |
762 | Standard_Boolean IntCyCo(const IntSurf_Quadric& Quad1, |
763 | const IntSurf_Quadric& Quad2, |
764 | const Standard_Real Tol, |
765 | const Standard_Boolean Reversed, |
766 | Standard_Boolean& Empty, |
767 | Standard_Boolean& Multpoint, |
768 | IntPatch_SequenceOfLine& slin, |
769 | IntPatch_SequenceOfPoint& spnt) |
770 | |
771 | { |
772 | IntPatch_Point ptsol; |
773 | |
774 | Standard_Integer i; |
775 | |
776 | IntSurf_TypeTrans trans1,trans2; |
777 | IntAna_ResultType typint; |
778 | gp_Circ cirsol; |
779 | |
780 | gp_Cylinder Cy; |
781 | gp_Cone Co; |
782 | |
783 | if (!Reversed) { |
784 | Cy = Quad1.Cylinder(); |
785 | Co = Quad2.Cone(); |
786 | } |
787 | else { |
788 | Cy = Quad2.Cylinder(); |
789 | Co = Quad1.Cone(); |
790 | } |
791 | IntAna_QuadQuadGeo inter(Cy,Co,Tol); |
792 | |
793 | if (!inter.IsDone()) {return Standard_False;} |
794 | |
795 | typint = inter.TypeInter(); |
796 | Standard_Integer NbSol = inter.NbSolutions(); |
797 | Empty = Standard_False; |
798 | |
799 | switch (typint) { |
800 | |
801 | case IntAna_Empty : { |
802 | Empty = Standard_True; |
803 | } |
804 | break; |
805 | |
806 | case IntAna_Point :{ |
807 | gp_Pnt psol(inter.Point(1)); |
808 | Standard_Real U1,V1,U2,V2; |
809 | Quad1.Parameters(psol,U1,V1); |
810 | Quad1.Parameters(psol,U2,V2); |
811 | ptsol.SetValue(psol,Tol,Standard_True); |
812 | ptsol.SetParameters(U1,V1,U2,V2); |
813 | spnt.Append(ptsol); |
814 | } |
815 | break; |
816 | |
817 | case IntAna_Circle: { |
818 | gp_Vec Tgt; |
819 | gp_Pnt ptref; |
820 | Standard_Integer j; |
821 | Standard_Real qwe; |
822 | // |
823 | for(j=1; j<=2; ++j) { |
824 | cirsol = inter.Circle(j); |
825 | ElCLib::D1(0.,cirsol,ptref,Tgt); |
826 | qwe = Tgt.DotCross(Quad2.Normale(ptref),Quad1.Normale(ptref)); |
827 | if(qwe> 0.00000001) { |
828 | trans1 = IntSurf_Out; |
829 | trans2 = IntSurf_In; |
830 | } |
831 | else if(qwe<-0.00000001) { |
832 | trans1 = IntSurf_In; |
833 | trans2 = IntSurf_Out; |
834 | } |
835 | else { |
836 | trans1=trans2=IntSurf_Undecided; |
837 | } |
838 | Handle(IntPatch_GLine) glig = new IntPatch_GLine(cirsol,Standard_False,trans1,trans2); |
839 | slin.Append(glig); |
840 | } |
841 | } |
842 | break; |
843 | |
844 | case IntAna_NoGeometricSolution: { |
845 | gp_Pnt psol; |
846 | Standard_Real U1,V1,U2,V2; |
847 | IntAna_IntQuadQuad anaint(Cy,Co,Tol); |
848 | if (!anaint.IsDone()) { |
849 | return Standard_False; |
850 | } |
851 | |
852 | if (anaint.NbPnt() == 0 && anaint.NbCurve() == 0) { |
853 | Empty = Standard_True; |
854 | } |
855 | else { |
856 | NbSol = anaint.NbPnt(); |
857 | for (i = 1; i <= NbSol; i++) { |
858 | psol = anaint.Point(i); |
859 | Quad1.Parameters(psol,U1,V1); |
860 | Quad2.Parameters(psol,U2,V2); |
861 | ptsol.SetValue(psol,Tol,Standard_True); |
862 | ptsol.SetParameters(U1,V1,U2,V2); |
863 | spnt.Append(ptsol); |
864 | } |
865 | |
866 | gp_Pnt ptvalid, ptf, ptl; |
867 | gp_Vec tgvalid; |
868 | // |
869 | Standard_Real first,last,para; |
870 | Standard_Boolean tgfound,firstp,lastp,kept; |
871 | Standard_Integer kount; |
872 | // |
873 | // |
874 | //IntAna_Curve curvsol; |
875 | IntAna_Curve aC; |
876 | IntAna_ListOfCurve aLC; |
877 | IntAna_ListIteratorOfListOfCurve aIt; |
878 | Standard_Boolean bToSplit; |
879 | |
880 | // |
881 | NbSol = anaint.NbCurve(); |
882 | for (i = 1; i <= NbSol; ++i) { |
883 | kept = Standard_False; |
884 | //curvsol = anaint.Curve(i); |
885 | aC=anaint.Curve(i); |
886 | aLC.Clear(); |
887 | bToSplit=ExploreCurve(Cy, Co, aC, 10.*Tol, aLC); |
888 | // |
889 | aIt.Initialize(aLC); |
890 | for (; aIt.More(); aIt.Next()) { |
891 | IntAna_Curve& curvsol=aIt.Value(); |
892 | // |
893 | curvsol.Domain(first, last); |
894 | firstp = !curvsol.IsFirstOpen(); |
895 | lastp = !curvsol.IsLastOpen(); |
896 | if (firstp) { |
897 | ptf = curvsol.Value(first); |
898 | } |
899 | if (lastp) { |
900 | ptl = curvsol.Value(last); |
901 | } |
902 | para = last; |
903 | kount = 1; |
904 | tgfound = Standard_False; |
905 | |
906 | while (!tgfound) { |
907 | para = (1.123*first + para)/2.123; |
908 | tgfound = curvsol.D1u(para,ptvalid,tgvalid); |
909 | if (!tgfound) { |
910 | kount ++; |
911 | tgfound = kount > 5; |
912 | } |
913 | } |
914 | Handle(IntPatch_ALine) alig; |
915 | if (kount <= 5) { |
916 | Standard_Real qwe = tgvalid.DotCross(Quad2.Normale(ptvalid), |
917 | Quad1.Normale(ptvalid)); |
918 | if(qwe> 0.00000001) { |
919 | trans1 = IntSurf_Out; |
920 | trans2 = IntSurf_In; |
921 | } |
922 | else if(qwe<-0.00000001) { |
923 | trans1 = IntSurf_In; |
924 | trans2 = IntSurf_Out; |
925 | } |
926 | else { |
927 | trans1=trans2=IntSurf_Undecided; |
928 | } |
929 | alig = new IntPatch_ALine(curvsol,Standard_False,trans1,trans2); |
930 | kept = Standard_True; |
931 | } |
932 | else { |
933 | ptvalid = curvsol.Value(para); |
934 | alig = new IntPatch_ALine(curvsol,Standard_False); |
935 | kept = Standard_True; |
936 | //-- cout << "Transition indeterminee" << endl; |
937 | } |
938 | if (kept) { |
939 | Standard_Boolean Nfirstp = !firstp; |
940 | Standard_Boolean Nlastp = !lastp; |
941 | ProcessBounds(alig,slin,Quad1,Quad2,Nfirstp,ptf,first, |
942 | Nlastp,ptl,last,Multpoint,Tol); |
943 | slin.Append(alig); |
944 | } |
945 | } // for (; aIt.More(); aIt.Next()) |
946 | } // for (i = 1; i <= NbSol; ++i) |
947 | } |
948 | } |
949 | break; |
950 | |
951 | default: |
952 | return Standard_False; |
953 | |
954 | } // switch (typint) |
955 | |
956 | return Standard_True; |
957 | } |
958 | //======================================================================= |
959 | //function : ExploreCurve |
960 | //purpose : |
961 | //======================================================================= |
962 | Standard_Boolean ExploreCurve(const gp_Cylinder& ,//aCy, |
963 | const gp_Cone& aCo, |
964 | IntAna_Curve& aC, |
965 | const Standard_Real aTol, |
966 | IntAna_ListOfCurve& aLC) |
967 | |
968 | { |
969 | Standard_Boolean bFind=Standard_False; |
970 | Standard_Real aTheta, aT1, aT2, aDst; |
971 | gp_Pnt aPapx, aPx; |
972 | // |
973 | //aC.Dump(); |
974 | // |
975 | aLC.Clear(); |
976 | aLC.Append(aC); |
977 | // |
978 | aPapx=aCo.Apex(); |
979 | // |
980 | aC.Domain(aT1, aT2); |
981 | // |
982 | aPx=aC.Value(aT1); |
983 | aDst=aPx.Distance(aPapx); |
984 | if (aDst<aTol) { |
985 | return bFind; |
986 | } |
987 | aPx=aC.Value(aT2); |
988 | aDst=aPx.Distance(aPapx); |
989 | if (aDst<aTol) { |
990 | return bFind; |
991 | } |
992 | // |
993 | bFind=aC.FindParameter(aPapx, aTheta); |
994 | if (!bFind){ |
995 | return bFind; |
996 | } |
997 | // |
998 | aPx=aC.Value(aTheta); |
999 | aDst=aPx.Distance(aPapx); |
1000 | if (aDst>aTol) { |
1001 | return !bFind; |
1002 | } |
1003 | // |
1004 | // need to be splitted at aTheta |
1005 | IntAna_Curve aC1, aC2; |
1006 | // |
1007 | aC1=aC; |
1008 | aC1.SetDomain(aT1, aTheta); |
1009 | aC2=aC; |
1010 | aC2.SetDomain(aTheta, aT2); |
1011 | // |
1012 | aLC.Clear(); |
1013 | aLC.Append(aC1); |
1014 | aLC.Append(aC2); |
1015 | // |
1016 | return bFind; |
1017 | } |
1018 | //======================================================================= |
1019 | //function : IsToReverse |
1020 | //purpose : |
1021 | //======================================================================= |
1022 | Standard_Boolean IsToReverse(const gp_Cylinder& Cy1, |
1023 | const gp_Cylinder& Cy2, |
1024 | const Standard_Real Tol) |
1025 | { |
1026 | Standard_Boolean bRet; |
1027 | Standard_Real aR1,aR2, dR, aSc1, aSc2; |
1028 | // |
1029 | bRet=Standard_False; |
1030 | // |
1031 | aR1=Cy1.Radius(); |
1032 | aR2=Cy2.Radius(); |
1033 | dR=aR1-aR2; |
1034 | if (dR<0.) { |
1035 | dR=-dR; |
1036 | } |
1037 | if (dR>Tol) { |
1038 | bRet=aR1>aR2; |
1039 | } |
1040 | else { |
1041 | gp_Dir aDZ(0.,0.,1.); |
1042 | // |
1043 | const gp_Dir& aDir1=Cy1.Axis().Direction(); |
1044 | aSc1=aDir1*aDZ; |
1045 | if (aSc1<0.) { |
1046 | aSc1=-aSc1; |
1047 | } |
1048 | // |
1049 | const gp_Dir& aDir2=Cy2.Axis().Direction(); |
1050 | aSc2=aDir2*aDZ; |
1051 | if (aSc2<0.) { |
1052 | aSc2=-aSc2; |
1053 | } |
1054 | // |
1055 | if (aSc2<aSc1) { |
1056 | bRet=!bRet; |
1057 | } |
1058 | }//if (dR<Tol) { |
1059 | return bRet; |
1060 | } |