0022723: Wrong intersection curve for the case of intersection between cylinder and...
[occt.git] / src / IntPatch / IntPatch_ImpImpIntersection_2.gxx
1 // File:      IntPatch_ImpImpIntersection_2.gxx
2 // Created:   Thu May  7 08:47:45 1992
3 // Author:    Jacques GOUSSARD
4 // Copyright: OPEN CASCADE 1992
5
6 //=======================================================================
7 //function : IntPatch_ImpImpIntersection
8 //purpose  : 
9 //=======================================================================
10 IntPatch_ImpImpIntersection::IntPatch_ImpImpIntersection ():
11        done(Standard_False)
12 {
13 }
14 //=======================================================================
15 //function : IntPatch_ImpImpIntersection
16 //purpose  : 
17 //=======================================================================
18 IntPatch_ImpImpIntersection::IntPatch_ImpImpIntersection
19        (const Handle(Adaptor3d_HSurface)&  S1,
20         const Handle(Adaptor3d_TopolTool)& D1,
21         const Handle(Adaptor3d_HSurface)&  S2,
22         const Handle(Adaptor3d_TopolTool)& D2,
23         const Standard_Real TolArc,
24         const Standard_Real TolTang)
25 {
26   Perform(S1,D1,S2,D2,TolArc,TolTang);
27 }
28 //=======================================================================
29 //function : Perform
30 //purpose  : 
31 //=======================================================================
32 void IntPatch_ImpImpIntersection::Perform(const Handle(Adaptor3d_HSurface)&  S1,
33                                           const Handle(Adaptor3d_TopolTool)& D1,
34                                           const Handle(Adaptor3d_HSurface)&  S2,
35                                           const Handle(Adaptor3d_TopolTool)& D2,
36                                           const Standard_Real TolArc,
37                                           const Standard_Real TolTang) {
38   done = Standard_False;
39   spnt.Clear();
40   slin.Clear();
41
42   empt = Standard_True;
43   tgte = Standard_False;
44   oppo = Standard_False;
45
46   Standard_Boolean all1 = Standard_False;
47   Standard_Boolean all2 = Standard_False;
48   Standard_Boolean SameSurf = Standard_False;
49   Standard_Boolean multpoint = Standard_False;
50
51   Standard_Boolean nosolonS1 = Standard_False;
52   // indique s il y a des points sur restriction du carreau 1
53   Standard_Boolean nosolonS2 = Standard_False;
54   // indique s il y a des points sur restriction du carreau 2
55   Standard_Integer i, nbpt, nbseg;
56   IntPatch_SequenceOfSegmentOfTheSOnBounds edg1,edg2;
57   IntPatch_SequenceOfPathPointOfTheSOnBounds pnt1,pnt2;
58   //
59   // On commence par intersecter les supports des surfaces
60   IntSurf_Quadric quad1;
61   IntSurf_Quadric quad2;
62   IntPatch_ArcFunction AFunc;
63   Standard_Real Tolang = 1.e-8;
64   GeomAbs_SurfaceType typs1 = S1->GetType();
65   GeomAbs_SurfaceType typs2 = S2->GetType();
66   //
67   switch (typs1) {
68
69   case GeomAbs_Plane :
70     {
71       quad1.SetValue(S1->Plane());
72
73       switch (typs2) {
74
75       case GeomAbs_Plane:
76         {
77           quad2.SetValue(S2->Plane());
78           if (!IntPP(quad1,quad2,Tolang,TolTang,SameSurf,slin)) {
79             return;
80           }
81         }
82         break;
83         
84         
85       case GeomAbs_Cylinder:
86         {
87           quad2.SetValue(S2->Cylinder());
88           if (!IntPCy(quad1,quad2,Tolang,TolTang,Standard_False,empt,slin)) {
89             return;
90           }
91           if (empt) {
92             done = Standard_True;
93             return;
94           }
95         }
96         break;
97
98       case GeomAbs_Sphere:
99         {
100           quad2.SetValue(S2->Sphere());
101           //modified by NIZNHY-PKV Tue Sep 20 09:03:06 2011f
102           if (!IntPSp(quad1,quad2,Tolang,TolTang,Standard_False,empt,slin,spnt)) {
103           //if (!IntPSp(quad1,quad2,TolTang,Standard_False,empt,slin,spnt)) {
104             //modified by NIZNHY-PKV Tue Sep 20 09:03:10 2011t
105             return;
106           }
107           if (empt) {
108             done = Standard_True;
109             return;
110           }
111         }
112         break;
113         
114       case GeomAbs_Cone:
115         {
116           quad2.SetValue(S2->Cone());
117           if (!IntPCo(quad1,quad2,Tolang,TolTang,Standard_False,
118                       empt,multpoint,slin,spnt)) {
119             return;
120           }
121           if (empt) {
122             done = Standard_True;
123             return;
124           }
125         }
126         break;
127       default: 
128         {
129           Standard_ConstructionError::Raise();
130           break;
131         }
132       }
133     }
134     break;
135
136   case GeomAbs_Cylinder:
137     {
138       quad1.SetValue(S1->Cylinder());
139       switch (typs2){
140
141       case GeomAbs_Plane:
142         {
143           quad2.SetValue(S2->Plane());
144           if (!IntPCy(quad1,quad2,Tolang,TolTang,Standard_True,empt,slin)) {
145             return;
146           }
147           if (empt) {
148             done = Standard_True;
149             return;
150           }
151         }
152         break;
153
154       case GeomAbs_Cylinder:
155         {
156           quad2.SetValue(S2->Cylinder());
157           if (!IntCyCy(quad1,quad2,TolTang,empt,SameSurf,multpoint,slin,spnt)) {
158             return;
159           }
160           if (empt) {
161             done = Standard_True;
162             return;
163           }
164         }
165         break;
166
167       case GeomAbs_Sphere:
168         {
169           quad2.SetValue(S2->Sphere());
170           if (!IntCySp(quad1,quad2,TolTang,Standard_False,empt,multpoint,
171                        slin,spnt)) {
172             return;
173           }
174           if (empt) {
175             done = Standard_True;
176
177             return;
178           }
179         }
180         break;
181
182       case GeomAbs_Cone:
183         {
184           quad2.SetValue(S2->Cone());
185           if (!IntCyCo(quad1,quad2,TolTang,Standard_False,empt,multpoint,
186                        slin,spnt)) {
187             return;
188           }
189           if (empt) {
190             done = Standard_True;
191             return;
192           }
193         }
194         break;
195       default: 
196         {
197           Standard_ConstructionError::Raise();
198           break;
199         }
200       }
201
202     }
203     break;
204
205   case GeomAbs_Sphere:
206     {
207       quad1.SetValue(S1->Sphere());
208
209       switch (typs2){
210
211       case GeomAbs_Plane:
212         {
213           quad2.SetValue(S2->Plane());
214           //modified by NIZNHY-PKV Tue Sep 20 09:03:35 2011f
215           if (!IntPSp(quad1,quad2,Tolang,TolTang,Standard_True,empt,slin,spnt)) {
216           //if (!IntPSp(quad1,quad2,TolTang,Standard_True,empt,slin,spnt)) {
217             //modified by NIZNHY-PKV Tue Sep 20 09:03:38 2011t
218             return;
219           }
220           if (empt) {
221             done = Standard_True;
222             return;
223           }
224         }
225         break;
226
227       case GeomAbs_Cylinder:
228         {
229           quad2.SetValue(S2->Cylinder());
230           if (!IntCySp(quad1,quad2,TolTang,Standard_True,empt,multpoint,
231                        slin,spnt)) {
232             return;
233           }
234           if (empt) {
235             done = Standard_True;
236             return;
237           }
238         }
239         break;
240
241       case GeomAbs_Sphere:
242         {
243           quad2.SetValue(S2->Sphere());
244           if (!IntSpSp(quad1,quad2,TolTang,empt,SameSurf,slin,spnt)) {
245             return;
246           }
247           if (empt) {
248             done = Standard_True;
249             return;
250           }
251         }
252         break;
253
254       case GeomAbs_Cone:
255         {
256           quad2.SetValue(S2->Cone());
257           if (!IntCoSp(quad1,quad2,TolTang,Standard_True,empt,multpoint,
258                        slin,spnt)) {
259             return;
260           }
261           if (empt) {
262             done = Standard_True;
263             return;
264           }
265         }
266         break;
267       default: 
268         {
269           Standard_ConstructionError::Raise();
270           break;
271         }
272       }
273
274     }
275     break;
276
277   case GeomAbs_Cone:
278     {
279       quad1.SetValue(S1->Cone());
280
281       switch (typs2){
282
283       case GeomAbs_Plane:
284         {
285           quad2.SetValue(S2->Plane());
286           if (!IntPCo(quad1,quad2,Tolang,TolTang,Standard_True,
287                       empt,multpoint,slin,spnt)) {
288             return;
289           }
290           if (empt) {
291             done = Standard_True;
292             return;
293           }
294         }
295         break;
296
297       case GeomAbs_Cylinder:
298         {
299           quad2.SetValue(S2->Cylinder());
300           if (!IntCyCo(quad1,quad2,TolTang,Standard_True,empt,multpoint,
301                        slin,spnt)) {
302             return;
303           }
304           if (empt) {
305             done = Standard_True;
306             return;
307           }
308         }
309         break;
310
311       case GeomAbs_Sphere:
312         {
313           quad2.SetValue(S2->Sphere());
314           if (!IntCoSp(quad1,quad2,TolTang,Standard_False,empt,multpoint,
315                        slin,spnt)) {
316             return;
317           }
318           if (empt) {
319             done = Standard_True;
320             return;
321           }
322         }
323         break;
324
325       case GeomAbs_Cone:
326         {
327           quad2.SetValue(S2->Cone());
328           if (!IntCoCo(quad1,quad2,TolTang,empt,SameSurf,multpoint,
329                        slin,spnt)) {
330             return;
331           }
332           if (empt) {
333             done = Standard_True;
334             return;
335           }
336         }
337         break;
338
339       default:
340         {
341           Standard_ConstructionError::Raise();
342           break;
343         }
344       }
345
346     }
347     break;
348     default:
349     {
350       Standard_ConstructionError::Raise();
351       break;
352     }
353   } //switch (typs1) {
354   //
355   if (!SameSurf) {
356     AFunc.SetQuadric(quad2);
357     AFunc.Set(S1);
358     
359     solrst.Perform(AFunc, D1, TolArc, TolTang);
360     if (!solrst.IsDone()) {
361       return;
362     }
363
364     if (solrst.AllArcSolution() && typs1 == typs2) {
365       all1 = Standard_True;
366     }
367     nbpt = solrst.NbPoints();
368     nbseg= solrst.NbSegments();
369     for (i=1; i<= nbpt; i++) {
370       pnt1.Append(solrst.Point(i));
371     }
372     for (i=1; i<= nbseg; i++) {
373       edg1.Append(solrst.Segment(i));
374     }
375     nosolonS1 = (nbpt == 0) && (nbseg == 0);
376
377     if (nosolonS1 && all1) {  // cas de face sans restrictions
378       all1 = Standard_False;
379     }
380   }//if (!SameSurf) {
381   else {
382     nosolonS1 = Standard_True;
383   }
384
385   if (!SameSurf) {
386     AFunc.SetQuadric(quad1);
387     AFunc.Set(S2);
388
389     solrst.Perform(AFunc, D2, TolArc, TolTang);
390     if (!solrst.IsDone()) {
391       return;
392     }
393     
394     if (solrst.AllArcSolution() && typs1 == typs2) {
395       all2 = Standard_True;
396     }
397     nbpt = solrst.NbPoints();
398     nbseg= solrst.NbSegments();
399     for (i=1; i<= nbpt; i++) {
400       pnt2.Append(solrst.Point(i));
401     }
402     
403     for (i=1; i<= nbseg; i++) {
404       edg2.Append(solrst.Segment(i));
405     }
406     nosolonS2 = (nbpt == 0) && (nbseg == 0);
407
408     if (nosolonS2 && all2) {  // cas de face sans restrictions
409       all2 = Standard_False;
410     }
411   }// if (!SameSurf) {
412   else {
413     nosolonS2 = Standard_True;
414   }
415   //
416   if (SameSurf || (all1 && all2)) {
417     // faces "paralleles" parfaites
418     empt = Standard_False;
419     tgte = Standard_True;
420     slin.Clear();
421     spnt.Clear();
422
423     gp_Pnt Ptreference;
424
425     switch (typs1) {
426     case GeomAbs_Plane:      {
427       Ptreference = (S1->Plane()).Location();
428     }
429       break;
430     case GeomAbs_Cylinder: {
431       Ptreference = ElSLib::Value(0.,0.,S1->Cylinder());
432     }
433       break;
434     case GeomAbs_Sphere:      {
435       Ptreference = ElSLib::Value(PI/4.,PI/4.,S1->Sphere());
436     }
437       break;
438     case GeomAbs_Cone:      {
439       Ptreference = ElSLib::Value(0.,10.,S1->Cone());
440     }
441       break;
442     default: 
443       break;
444     }
445     //
446     oppo = quad1.Normale(Ptreference).Dot(quad2.Normale(Ptreference)) < 0.0;
447     done = Standard_True;
448     return;
449   }// if (SameSurf || (all1 && all2)) {
450
451   if (!nosolonS1 || !nosolonS2) {
452     empt = Standard_False;
453     // C est la qu il faut commencer a bosser...
454     PutPointsOnLine(S1,S2,pnt1, slin, Standard_True, D1, quad1,quad2,
455                     multpoint,TolArc);
456     
457     PutPointsOnLine(S1,S2,pnt2, slin, Standard_False,D2, quad2,quad1,
458                     multpoint,TolArc);
459
460     if (edg1.Length() != 0) {
461       ProcessSegments(edg1,slin,quad1,quad2,Standard_True,TolArc);
462     }
463
464     if (edg2.Length() != 0) {
465       ProcessSegments(edg2,slin,quad1,quad2,Standard_False,TolArc);
466     }
467
468     if (edg1.Length() !=0 || edg2.Length() !=0) {
469       //      ProcessRLine(slin,S1,S2,TolArc);
470       ProcessRLine(slin,quad1,quad2,TolArc);
471     }
472   }//if (!nosolonS1 || !nosolonS2) {
473   else {
474     empt = ((slin.Length()==0) && (spnt.Length()==0));
475   }
476   //
477   Standard_Integer nblin, aNbPnt;
478   //
479   //modified by NIZNHY-PKV Tue Sep 06 10:03:35 2011f
480   aNbPnt=spnt.Length();
481   if (aNbPnt) {
482     IntPatch_SequenceOfPoint aSIP;
483     //
484     for(i=1; i<=aNbPnt; ++i) {
485       Standard_Real aU1, aV1, aU2, aV2;
486       gp_Pnt2d aP2D;
487       TopAbs_State aState1, aState2;
488       //
489       const IntPatch_Point& aIP=spnt(i);
490       aIP.Parameters(aU1, aV1, aU2, aV2);
491       //
492       aP2D.SetCoord(aU1, aV1);
493       aState1=D1->Classify(aP2D, TolArc);
494       //
495       aP2D.SetCoord(aU2, aV2);
496       aState2=D2->Classify(aP2D, TolArc);
497       //
498       if(aState1!=TopAbs_OUT && aState2!=TopAbs_OUT) {
499         aSIP.Append(aIP);
500       }
501     }
502     //
503     spnt.Clear();
504     //
505     aNbPnt=aSIP.Length();
506     for(i=1; i<=aNbPnt; ++i) {
507       const IntPatch_Point& aIP=aSIP(i);
508       spnt.Append(aIP);
509     }
510     //
511   }//  if (aNbPnt) {
512   //modified by NIZNHY-PKV Tue Sep 06 10:18:20 2011t
513   //
514   nblin = slin.Length();
515   for(i=1; i<=nblin; i++) {
516     IntPatch_IType thetype = slin.Value(i)->ArcType();
517     if(  (thetype ==  IntPatch_Ellipse)
518        ||(thetype ==  IntPatch_Circle)
519        ||(thetype ==  IntPatch_Lin)
520        ||(thetype ==  IntPatch_Parabola)
521        ||(thetype ==  IntPatch_Hyperbola)) { 
522       Handle(IntPatch_GLine)& glin = *((Handle(IntPatch_GLine)*)&slin.Value(i));
523     glin->ComputeVertexParameters(TolArc); 
524     }
525     else if(thetype == IntPatch_Analytic) { 
526       Handle(IntPatch_ALine)& aligold = *((Handle(IntPatch_ALine)*)&slin.Value(i));
527       aligold->ComputeVertexParameters(TolArc);
528     }
529     else if(thetype == IntPatch_Restriction) {
530       Handle(IntPatch_RLine)& rlig = *((Handle(IntPatch_RLine)*)&slin.Value(i));
531       rlig->ComputeVertexParameters(TolArc); 
532     }
533   }
534   //
535   //----------------------------------------------------------------
536   //-- On place 2 vertex sur les courbes de GLine qui n en 
537   //-- contiennent pas. 
538   for(i=1; i<=nblin; i++) {
539     gp_Pnt P;
540     IntPatch_Point point;
541     Standard_Real u1,v1,u2,v2; 
542     Standard_Integer nbv;
543     if(slin.Value(i)->ArcType() == IntPatch_Circle) { 
544       const Handle(IntPatch_GLine)& glin = *((Handle(IntPatch_GLine)*)&slin.Value(i));
545       nbv = glin->NbVertex();
546       if(glin->NbVertex() == 0) { 
547         gp_Circ Circ = glin->Circle();
548         P=ElCLib::Value(0.0,Circ);
549         quad1.Parameters(P,u1,v1);
550         quad2.Parameters(P,u2,v2);
551         point.SetValue(P,TolArc,Standard_False);
552         point.SetParameters(u1,v1,u2,v2);
553         point.SetParameter(0.0);
554         glin->AddVertex(point);
555
556         P=ElCLib::Value(0.0,Circ);
557         quad1.Parameters(P,u1,v1);
558         quad2.Parameters(P,u2,v2);
559         point.SetValue(P,TolArc,Standard_False);
560         point.SetParameters(u1,v1,u2,v2);
561         point.SetParameter(PI+PI);
562         glin->AddVertex(point);
563       }
564     }
565     
566     else if(slin.Value(i)->ArcType() == IntPatch_Ellipse) { 
567       const Handle(IntPatch_GLine)& glin = *((Handle(IntPatch_GLine)*)&slin.Value(i));
568       nbv = glin->NbVertex();
569       if(glin->NbVertex() == 0) { 
570         gp_Elips Elips = glin->Ellipse();
571         P=ElCLib::Value(0.0,Elips);
572         quad1.Parameters(P,u1,v1);
573         quad2.Parameters(P,u2,v2);
574         point.SetValue(P,TolArc,Standard_False);
575         point.SetParameters(u1,v1,u2,v2);
576         point.SetParameter(0.0);
577         glin->AddVertex(point);
578
579         P=ElCLib::Value(0.0,Elips);
580         quad1.Parameters(P,u1,v1);
581         quad2.Parameters(P,u2,v2);
582         point.SetValue(P,TolArc,Standard_False);
583         point.SetParameters(u1,v1,u2,v2);
584         point.SetParameter(PI+PI);
585         glin->AddVertex(point);
586       }
587     }
588   }
589   done = Standard_True;
590 }
591