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