2e6d7cb3e9d401d34ab2a0be578d30a60159bc94
[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 IntPatch_ImpImpIntersection::IntPatch_ImpImpIntersection ():
7        done(Standard_False)
8 {
9 }
10 //--------------------------------------------------------------
11 IntPatch_ImpImpIntersection::IntPatch_ImpImpIntersection
12        (const Handle(Adaptor3d_HSurface)&  S1,
13         const Handle(Adaptor3d_TopolTool)& D1,
14         const Handle(Adaptor3d_HSurface)&  S2,
15         const Handle(Adaptor3d_TopolTool)& D2,
16         const Standard_Real TolArc,
17         const Standard_Real TolTang)
18 {
19   Perform(S1,D1,S2,D2,TolArc,TolTang);
20 }
21 //--------------------------------------------------------------
22 void IntPatch_ImpImpIntersection::Perform(const Handle(Adaptor3d_HSurface)&  S1,
23                                           const Handle(Adaptor3d_TopolTool)& D1,
24                                           const Handle(Adaptor3d_HSurface)&  S2,
25                                           const Handle(Adaptor3d_TopolTool)& D2,
26                                           const Standard_Real TolArc,
27                                           const Standard_Real TolTang) {
28   done = Standard_False;
29   spnt.Clear();
30   slin.Clear();
31
32   empt = Standard_True;
33   tgte = Standard_False;
34   oppo = Standard_False;
35
36   Standard_Boolean all1 = Standard_False;
37   Standard_Boolean all2 = Standard_False;
38   Standard_Boolean SameSurf = Standard_False;
39   Standard_Boolean multpoint = Standard_False;
40
41   Standard_Boolean nosolonS1 = Standard_False;
42               // indique s il y a des points sur restriction du carreau 1
43   Standard_Boolean nosolonS2 = Standard_False;
44               // indique s il y a des points sur restriction du carreau 2
45
46   Standard_Integer i, nbpt, nbseg;
47
48   IntPatch_SequenceOfSegmentOfTheSOnBounds edg1,edg2;
49   IntPatch_SequenceOfPathPointOfTheSOnBounds pnt1,pnt2;
50
51   // On commence par intersecter les supports des surfaces
52
53   IntSurf_Quadric quad1;
54   IntSurf_Quadric quad2;
55   IntPatch_ArcFunction AFunc;
56   Standard_Real Tolang = 1.e-8;
57   GeomAbs_SurfaceType typs1 = S1->GetType();
58   GeomAbs_SurfaceType typs2 = S2->GetType();
59
60
61   switch (typs1) {
62
63   case GeomAbs_Plane :
64     {
65       quad1.SetValue(S1->Plane());
66
67       switch (typs2) {
68
69       case GeomAbs_Plane:
70         {
71           quad2.SetValue(S2->Plane());
72           if (!IntPP(quad1,quad2,Tolang,TolTang,SameSurf,slin)) {
73             return;
74           }
75         }
76         break;
77         
78         
79       case GeomAbs_Cylinder:
80         {
81           quad2.SetValue(S2->Cylinder());
82           if (!IntPCy(quad1,quad2,Tolang,TolTang,Standard_False,empt,slin)) {
83             return;
84           }
85           if (empt) {
86             done = Standard_True;
87             return;
88           }
89         }
90         break;
91
92       case GeomAbs_Sphere:
93         {
94           quad2.SetValue(S2->Sphere());
95           if (!IntPSp(quad1,quad2,TolTang,Standard_False,empt,slin,spnt)) {
96             return;
97           }
98           if (empt) {
99             done = Standard_True;
100             return;
101           }
102         }
103         break;
104         
105       case GeomAbs_Cone:
106         {
107           quad2.SetValue(S2->Cone());
108           if (!IntPCo(quad1,quad2,Tolang,TolTang,Standard_False,
109                       empt,multpoint,slin,spnt)) {
110             return;
111           }
112           if (empt) {
113             done = Standard_True;
114             return;
115           }
116         }
117         break;
118       default: 
119         {
120           Standard_ConstructionError::Raise();
121           break;
122         }
123       }
124     }
125     break;
126
127   case GeomAbs_Cylinder:
128     {
129       quad1.SetValue(S1->Cylinder());
130       switch (typs2){
131
132       case GeomAbs_Plane:
133         {
134           quad2.SetValue(S2->Plane());
135           if (!IntPCy(quad1,quad2,Tolang,TolTang,Standard_True,empt,slin)) {
136             return;
137           }
138           if (empt) {
139             done = Standard_True;
140             return;
141           }
142         }
143         break;
144
145       case GeomAbs_Cylinder:
146         {
147           quad2.SetValue(S2->Cylinder());
148           if (!IntCyCy(quad1,quad2,TolTang,empt,SameSurf,multpoint,slin,spnt)) {
149             return;
150           }
151           if (empt) {
152             done = Standard_True;
153             return;
154           }
155         }
156         break;
157
158       case GeomAbs_Sphere:
159         {
160           quad2.SetValue(S2->Sphere());
161           if (!IntCySp(quad1,quad2,TolTang,Standard_False,empt,multpoint,
162                        slin,spnt)) {
163             return;
164           }
165           if (empt) {
166             done = Standard_True;
167
168             return;
169           }
170         }
171         break;
172
173       case GeomAbs_Cone:
174         {
175           quad2.SetValue(S2->Cone());
176           if (!IntCyCo(quad1,quad2,TolTang,Standard_False,empt,multpoint,
177                        slin,spnt)) {
178             return;
179           }
180           if (empt) {
181             done = Standard_True;
182             return;
183           }
184         }
185         break;
186       default: 
187         {
188           Standard_ConstructionError::Raise();
189           break;
190         }
191       }
192
193     }
194     break;
195
196   case GeomAbs_Sphere:
197     {
198       quad1.SetValue(S1->Sphere());
199
200       switch (typs2){
201
202       case GeomAbs_Plane:
203         {
204           quad2.SetValue(S2->Plane());
205           if (!IntPSp(quad1,quad2,TolTang,Standard_True,empt,slin,spnt)) {
206             return;
207           }
208           if (empt) {
209             done = Standard_True;
210             return;
211           }
212         }
213         break;
214
215       case GeomAbs_Cylinder:
216         {
217           quad2.SetValue(S2->Cylinder());
218           if (!IntCySp(quad1,quad2,TolTang,Standard_True,empt,multpoint,
219                        slin,spnt)) {
220             return;
221           }
222           if (empt) {
223             done = Standard_True;
224             return;
225           }
226         }
227         break;
228
229       case GeomAbs_Sphere:
230         {
231           quad2.SetValue(S2->Sphere());
232           if (!IntSpSp(quad1,quad2,TolTang,empt,SameSurf,slin,spnt)) {
233             return;
234           }
235           if (empt) {
236             done = Standard_True;
237             return;
238           }
239         }
240         break;
241
242       case GeomAbs_Cone:
243         {
244           quad2.SetValue(S2->Cone());
245           if (!IntCoSp(quad1,quad2,TolTang,Standard_True,empt,multpoint,
246                        slin,spnt)) {
247             return;
248           }
249           if (empt) {
250             done = Standard_True;
251             return;
252           }
253         }
254         break;
255       default: 
256         {
257           Standard_ConstructionError::Raise();
258           break;
259         }
260       }
261
262     }
263     break;
264
265   case GeomAbs_Cone:
266     {
267       quad1.SetValue(S1->Cone());
268
269       switch (typs2){
270
271       case GeomAbs_Plane:
272         {
273           quad2.SetValue(S2->Plane());
274           if (!IntPCo(quad1,quad2,Tolang,TolTang,Standard_True,
275                       empt,multpoint,slin,spnt)) {
276             return;
277           }
278           if (empt) {
279             done = Standard_True;
280             return;
281           }
282         }
283         break;
284
285       case GeomAbs_Cylinder:
286         {
287           quad2.SetValue(S2->Cylinder());
288           if (!IntCyCo(quad1,quad2,TolTang,Standard_True,empt,multpoint,
289                        slin,spnt)) {
290             return;
291           }
292           if (empt) {
293             done = Standard_True;
294             return;
295           }
296         }
297         break;
298
299       case GeomAbs_Sphere:
300         {
301           quad2.SetValue(S2->Sphere());
302           if (!IntCoSp(quad1,quad2,TolTang,Standard_False,empt,multpoint,
303                        slin,spnt)) {
304             return;
305           }
306           if (empt) {
307             done = Standard_True;
308             return;
309           }
310         }
311         break;
312
313       case GeomAbs_Cone:
314         {
315           quad2.SetValue(S2->Cone());
316           if (!IntCoCo(quad1,quad2,TolTang,empt,SameSurf,multpoint,
317                        slin,spnt)) {
318             return;
319           }
320           if (empt) {
321             done = Standard_True;
322             return;
323           }
324         }
325         break;
326
327       default:
328         {
329           Standard_ConstructionError::Raise();
330           break;
331         }
332       }
333
334     }
335     break;
336     default:
337     {
338       Standard_ConstructionError::Raise();
339       break;
340     }
341   }
342
343
344   if (!SameSurf) {
345
346     AFunc.SetQuadric(quad2);
347     AFunc.Set(S1);
348     
349     solrst.Perform(AFunc, D1, TolArc, TolTang);
350
351
352     if (!solrst.IsDone()) {
353       return;
354     }
355
356
357     if (solrst.AllArcSolution() && typs1 == typs2) {
358       all1 = Standard_True;
359     }
360     nbpt = solrst.NbPoints();
361     nbseg= solrst.NbSegments();
362     for (i=1; i<= nbpt; i++) {
363       pnt1.Append(solrst.Point(i));
364     }
365     for (i=1; i<= nbseg; i++) {
366       edg1.Append(solrst.Segment(i));
367     }
368     nosolonS1 = (nbpt == 0) && (nbseg == 0);
369
370     if (nosolonS1 && all1) {  // cas de face sans restrictions
371       all1 = Standard_False;
372     }
373
374   }
375   else {
376     nosolonS1 = Standard_True;
377   }
378
379   if (!SameSurf) {
380
381     AFunc.SetQuadric(quad1);
382     AFunc.Set(S2);
383
384     solrst.Perform(AFunc, D2, TolArc, TolTang);
385
386     if (!solrst.IsDone()) {
387       return;
388     }
389     
390     if (solrst.AllArcSolution() && typs1 == typs2) {
391       all2 = Standard_True;
392     }
393     nbpt = solrst.NbPoints();
394     nbseg= solrst.NbSegments();
395     for (i=1; i<= nbpt; i++) {
396       pnt2.Append(solrst.Point(i));
397     }
398     
399     for (i=1; i<= nbseg; i++) {
400       edg2.Append(solrst.Segment(i));
401     }
402     nosolonS2 = (nbpt == 0) && (nbseg == 0);
403
404     if (nosolonS2 && all2) {  // cas de face sans restrictions
405       all2 = Standard_False;
406     }
407
408   }
409   else {
410     nosolonS2 = Standard_True;
411   }
412
413   if (SameSurf || (all1 && all2)) {
414
415     // faces "paralleles" parfaites
416
417     empt = Standard_False;
418     tgte = Standard_True;
419     slin.Clear();
420     spnt.Clear();
421
422     gp_Pnt Ptreference;
423
424     switch (typs1) {
425     case GeomAbs_Plane:
426       {
427         Ptreference = (S1->Plane()).Location();
428       }
429       break;
430     case GeomAbs_Cylinder:
431       {
432         Ptreference = ElSLib::Value(0.,0.,S1->Cylinder());
433       }
434       break;
435     case GeomAbs_Sphere:
436       {
437         Ptreference = ElSLib::Value(PI/4.,PI/4.,S1->Sphere());
438       }
439       break;
440     case GeomAbs_Cone:
441       {
442         Ptreference = ElSLib::Value(0.,10.,S1->Cone());
443       }
444       break;
445     
446 #ifndef DEB
447     default: 
448       break;
449 #endif
450     }
451     oppo = quad1.Normale(Ptreference).Dot(quad2.Normale(Ptreference)) < 0.0;
452
453     done = Standard_True;
454     return;
455   }
456
457   if (!nosolonS1 || !nosolonS2) {
458
459
460     empt = Standard_False;
461
462     // C est la qu il faut commencer a bosser...
463
464
465     PutPointsOnLine(S1,S2,pnt1, slin, Standard_True, D1, quad1,quad2,
466                     multpoint,TolArc);
467     
468     PutPointsOnLine(S1,S2,pnt2, slin, Standard_False,D2, quad2,quad1,
469                     multpoint,TolArc);
470
471     if (edg1.Length() != 0) {
472       ProcessSegments(edg1,slin,quad1,quad2,Standard_True,TolArc);
473     }
474
475     if (edg2.Length() != 0) {
476       ProcessSegments(edg2,slin,quad1,quad2,Standard_False,TolArc);
477     }
478
479     if (edg1.Length() !=0 || edg2.Length() !=0) {
480 //      ProcessRLine(slin,S1,S2,TolArc);
481       ProcessRLine(slin,quad1,quad2,TolArc);
482     }
483
484   }
485   else {
486     empt = ((slin.Length()==0) && (spnt.Length()==0));
487   }
488
489   Standard_Integer nblin = slin.Length();
490
491
492
493   for(i=1; i<=nblin; i++) {
494     IntPatch_IType thetype = slin.Value(i)->ArcType();
495     if(  (thetype ==  IntPatch_Ellipse)
496        ||(thetype ==  IntPatch_Circle)
497        ||(thetype ==  IntPatch_Lin)
498        ||(thetype ==  IntPatch_Parabola)
499        ||(thetype ==  IntPatch_Hyperbola)) { 
500       Handle(IntPatch_GLine)& glin = *((Handle(IntPatch_GLine)*)&slin.Value(i));
501       
502 /*      if(thetype  == IntPatch_Circle) { 
503         gp_Pnt P;
504         IntPatch_Point point;
505         Standard_Real u1,v1,u2,v2; 
506         Standard_Boolean Addf = Standard_False;
507         Standard_Boolean Addl = Standard_False;
508         Standard_Integer v=0;
509         Standard_Integer nbv;
510         gp_Circ Circ = glin->Circle();
511         nbv = glin->NbVertex();
512         if(glin->HasFirstPoint() == Standard_False) { 
513           P=ElCLib::Value(0.0,Circ);
514           quad1.Parameters(P,u1,v1); quad2.Parameters(P,u2,v2);
515           point.SetValue(P,TolArc,Standard_False);
516           point.SetParameters(u1,v1,u2,v2); 
517           point.SetParameter(0.0);
518           glin->AddVertex(point);
519           nbv++;
520           glin->SetFirstPoint(nbv);
521         }
522         if(glin->HasLastPoint() == Standard_False) { 
523           P=ElCLib::Value(0.0,Circ);
524           quad1.Parameters(P,u1,v1); quad2.Parameters(P,u2,v2);
525           point.SetValue(P,TolArc,Standard_False);
526           point.SetParameters(u1,v1,u2,v2);
527           point.SetParameter(PI+PI);
528           glin->AddVertex(point);
529           nbv++;
530           glin->SetLastPoint(nbv);
531         }
532       }
533       else if(thetype == IntPatch_Ellipse) { 
534         gp_Pnt P;
535         IntPatch_Point point;
536         Standard_Real u1,v1,u2,v2; 
537         Standard_Boolean Addf = Standard_False;
538         Standard_Boolean Addl = Standard_False;
539         Standard_Integer v=0;
540         Standard_Integer nbv;
541         gp_Elips Elips = glin->Ellipse();
542         nbv = glin->NbVertex();
543         if(glin->HasFirstPoint() == Standard_False) { 
544           P=ElCLib::Value(0.0,Elips);
545           quad1.Parameters(P,u1,v1);  quad2.Parameters(P,u2,v2);
546           point.SetValue(P,TolArc,Standard_False);
547           point.SetParameters(u1,v1,u2,v2);
548           point.SetParameter(0.0);
549           glin->AddVertex(point);
550           nbv++;
551           glin->SetFirstPoint(nbv);
552         }
553         if(glin->HasLastPoint() == Standard_False) {
554           P=ElCLib::Value(0.0,Elips);
555           quad1.Parameters(P,u1,v1);  quad2.Parameters(P,u2,v2);
556           point.SetValue(P,TolArc,Standard_False);
557           point.SetParameters(u1,v1,u2,v2);
558           point.SetParameter(PI+PI);
559           glin->AddVertex(point);
560           nbv++;
561           glin->SetLastPoint(nbv);
562         }
563         } 
564 */
565     glin->ComputeVertexParameters(TolArc); 
566     }
567     else if(thetype == IntPatch_Analytic) { 
568       Handle(IntPatch_ALine)& aligold = *((Handle(IntPatch_ALine)*)&slin.Value(i));
569       aligold->ComputeVertexParameters(TolArc);
570     }
571     else if(thetype == IntPatch_Restriction) {
572       Handle(IntPatch_RLine)& rlig = *((Handle(IntPatch_RLine)*)&slin.Value(i));
573       rlig->ComputeVertexParameters(TolArc); 
574     }
575   }
576 #if 1 
577   //----------------------------------------------------------------
578   //-- On place 2 vertex sur les courbes de GLine qui n en 
579   //-- contiennent pas. 
580   
581   for(i=1; i<=nblin; i++) {
582     gp_Pnt P;
583     IntPatch_Point point;
584     Standard_Real u1,v1,u2,v2; 
585 #ifdef DEB
586     Standard_Boolean Addf = Standard_False;
587     Standard_Boolean Addl = Standard_False;
588     Standard_Integer v=0;
589 #endif
590     Standard_Integer nbv;
591     if(slin.Value(i)->ArcType() == IntPatch_Circle) { 
592       const Handle(IntPatch_GLine)& glin = *((Handle(IntPatch_GLine)*)&slin.Value(i));
593       nbv = glin->NbVertex();
594       if(glin->NbVertex() == 0) { 
595         gp_Circ Circ = glin->Circle();
596         P=ElCLib::Value(0.0,Circ);
597         quad1.Parameters(P,u1,v1);
598         quad2.Parameters(P,u2,v2);
599         point.SetValue(P,TolArc,Standard_False);
600         point.SetParameters(u1,v1,u2,v2);
601         point.SetParameter(0.0);
602         glin->AddVertex(point);
603
604         P=ElCLib::Value(0.0,Circ);
605         quad1.Parameters(P,u1,v1);
606         quad2.Parameters(P,u2,v2);
607         point.SetValue(P,TolArc,Standard_False);
608         point.SetParameters(u1,v1,u2,v2);
609         point.SetParameter(PI+PI);
610         glin->AddVertex(point);
611       }
612     }
613     
614     else if(slin.Value(i)->ArcType() == IntPatch_Ellipse) { 
615       const Handle(IntPatch_GLine)& glin = *((Handle(IntPatch_GLine)*)&slin.Value(i));
616       nbv = glin->NbVertex();
617       if(glin->NbVertex() == 0) { 
618         gp_Elips Elips = glin->Ellipse();
619         P=ElCLib::Value(0.0,Elips);
620         quad1.Parameters(P,u1,v1);
621         quad2.Parameters(P,u2,v2);
622         point.SetValue(P,TolArc,Standard_False);
623         point.SetParameters(u1,v1,u2,v2);
624         point.SetParameter(0.0);
625         glin->AddVertex(point);
626
627         P=ElCLib::Value(0.0,Elips);
628         quad1.Parameters(P,u1,v1);
629         quad2.Parameters(P,u2,v2);
630         point.SetValue(P,TolArc,Standard_False);
631         point.SetParameters(u1,v1,u2,v2);
632         point.SetParameter(PI+PI);
633         glin->AddVertex(point);
634       }
635     }
636   }
637 #endif
638
639   done = Standard_True;
640 }
641 //--------------------------------------------------------------
642
643
644 #if 0
645 //-- Ancien bout de code 
646   //----------------------------------------------------------------
647   //-- On place 2 vertex sur les courbes de GLine qui n en 
648   //-- contiennent pas. 
649   
650   for(i=1; i<=nblin; i++) {
651     gp_Pnt P;
652     IntPatch_Point point;
653     Standard_Real u1,v1,u2,v2; 
654     Standard_Boolean Addf = Standard_False;
655     Standard_Boolean Addl = Standard_False;
656     Standard_Integer v=0;
657     Standard_Integer nbv;
658     if(slin.Value(i)->ArcType() == IntPatch_Circle) { 
659       const Handle(IntPatch_GLine)& glin = *((Handle(IntPatch_GLine)*)&slin.Value(i));
660       nbv = glin->NbVertex();
661       if(glin->NbVertex() == 0) { Addf=Addl=Standard_True; } 
662       else { 
663         if(glin->HasFirstPoint() == Standard_False) { 
664           Addf = Standard_True;
665           for(v=1;v<=nbv;v++) { 
666             Standard_Real gv = glin->Vertex(v).ParameterOnLine();
667             if(gv<Precision::PConfusion()) 
668               Addf = Standard_False;
669           }
670         }
671         if(glin->HasLastPoint() == Standard_False) { 
672           Addl = Standard_True;
673           for(v=1;v<=nbv;v++) { 
674             Standard_Real gv = glin->Vertex(v).ParameterOnLine();
675             if((PI+PI-gv)<Precision::PConfusion()) 
676               Addl = Standard_False;
677           }
678         }
679       }
680       if(Addl || Addf) { 
681         gp_Circ Circ = glin->Circle();
682         if(Addf) { 
683           P=ElCLib::Value(0.0,Circ);
684           quad1.Parameters(P,u1,v1);
685           quad2.Parameters(P,u2,v2);
686           point.SetValue(P,TolArc,Standard_False);
687           point.SetParameters(u1,v1,u2,v2);
688           point.SetParameter(0.0);
689           glin->AddVertex(point);
690         }
691         if(Addl) { 
692           P=ElCLib::Value(0.0,Circ);
693           quad1.Parameters(P,u1,v1);
694           quad2.Parameters(P,u2,v2);
695           point.SetValue(P,TolArc,Standard_False);
696           point.SetParameters(u1,v1,u2,v2);
697           point.SetParameter(PI+PI);
698           glin->AddVertex(point);
699         }
700       }
701     }
702     
703     else if(slin.Value(i)->ArcType() == IntPatch_Ellipse) { 
704       const Handle(IntPatch_GLine)& glin = *((Handle(IntPatch_GLine)*)&slin.Value(i));
705       nbv = glin->NbVertex();
706       if(glin->NbVertex() == 0) { Addf=Addl=Standard_True; } 
707       else { 
708         if(glin->HasFirstPoint() == Standard_False) { 
709           Addf = Standard_True;
710           for(v=1;v<=nbv;v++) { 
711             Standard_Real gv = glin->Vertex(v).ParameterOnLine();
712             if(gv<Precision::PConfusion()) 
713               Addf = Standard_False;
714           }
715         }
716         if(glin->HasLastPoint() == Standard_False) { 
717           Addl = Standard_True;
718           for(v=1;v<=nbv;v++) { 
719             Standard_Real gv = glin->Vertex(v).ParameterOnLine();
720             if((PI+PI-gv)<Precision::PConfusion()) 
721               Addl = Standard_False;
722           }
723         }
724       }
725       if(Addl || Addf) { 
726         gp_Elips Elips = glin->Ellipse();
727         if(Addf) { 
728           P=ElCLib::Value(0.0,Elips);
729           quad1.Parameters(P,u1,v1);
730           quad2.Parameters(P,u2,v2);
731           point.SetValue(P,TolArc,Standard_False);
732           point.SetParameters(u1,v1,u2,v2);
733           point.SetParameter(0.0);
734           glin->AddVertex(point);
735         }
736         if(Addl) { 
737           P=ElCLib::Value(0.0,Elips);
738           quad1.Parameters(P,u1,v1);
739           quad2.Parameters(P,u2,v2);
740           point.SetValue(P,TolArc,Standard_False);
741           point.SetParameters(u1,v1,u2,v2);
742           point.SetParameter(PI+PI);
743           glin->AddVertex(point);
744         }
745       }
746     }
747   }
748 #endif