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