0026937: Eliminate NO_CXX_EXCEPTION macro support
[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-2014 OPEN CASCADE SAS
5 //
6 // This file is part of Open CASCADE Technology software library.
7 //
8 // This library is free software; you can redistribute it and/or modify it under
9 // the terms of the GNU Lesser General Public License version 2.1 as published
10 // by the Free Software Foundation, with special exception defined in the file
11 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
12 // distribution for complete text of the license and disclaimer of any warranty.
13 //
14 // Alternatively, this file may be used under the terms of Open CASCADE
15 // commercial license or contractual agreement.
16
17 #include <IntPatch_WLine.hxx>
18
19 static 
20   Standard_Integer SetQuad(const Handle(Adaptor3d_HSurface)& theS,
21                            GeomAbs_SurfaceType& theTS,
22                            IntSurf_Quadric& theQuad);
23
24 //=======================================================================
25 //function : IntPatch_ImpImpIntersection
26 //purpose  : 
27 //=======================================================================
28 IntPatch_ImpImpIntersection::IntPatch_ImpImpIntersection ():
29 myDone(IntStatus_Fail)
30 {
31 }
32 //=======================================================================
33 //function : IntPatch_ImpImpIntersection
34 //purpose  : 
35 //=======================================================================
36 IntPatch_ImpImpIntersection::IntPatch_ImpImpIntersection
37        (const Handle(Adaptor3d_HSurface)&  S1,
38         const Handle(Adaptor3d_TopolTool)& D1,
39         const Handle(Adaptor3d_HSurface)&  S2,
40         const Handle(Adaptor3d_TopolTool)& D2,
41         const Standard_Real TolArc,
42         const Standard_Real TolTang,
43         const Standard_Boolean theIsReqToKeepRLine)
44 {
45   Perform(S1,D1,S2,D2,TolArc,TolTang, theIsReqToKeepRLine);
46 }
47 //=======================================================================
48 //function : Perform
49 //purpose  : 
50 //=======================================================================
51 void IntPatch_ImpImpIntersection::Perform(const Handle(Adaptor3d_HSurface)&  S1,
52                                           const Handle(Adaptor3d_TopolTool)& D1,
53                                           const Handle(Adaptor3d_HSurface)&  S2,
54                                           const Handle(Adaptor3d_TopolTool)& D2,
55                                           const Standard_Real TolArc,
56                                           const Standard_Real TolTang,
57                                           const Standard_Boolean theIsReqToKeepRLine)
58 {
59   myDone = IntStatus_Fail;
60   spnt.Clear();
61   slin.Clear();
62
63   Standard_Boolean isPostProcessingRequired = Standard_True;
64
65   empt = Standard_True;
66   tgte = Standard_False;
67   oppo = Standard_False;
68
69   Standard_Boolean all1 = Standard_False;
70   Standard_Boolean all2 = Standard_False;
71   Standard_Boolean SameSurf = Standard_False;
72   Standard_Boolean multpoint = Standard_False;
73
74   Standard_Boolean nosolonS1 = Standard_False;
75   // indique s il y a des points sur restriction du carreau 1
76   Standard_Boolean nosolonS2 = Standard_False;
77   // indique s il y a des points sur restriction du carreau 2
78   Standard_Integer i, nbpt, nbseg;
79   IntPatch_SequenceOfSegmentOfTheSOnBounds edg1,edg2;
80   IntPatch_SequenceOfPathPointOfTheSOnBounds pnt1,pnt2;
81   //
82   // On commence par intersecter les supports des surfaces
83   IntSurf_Quadric quad1, quad2;
84   IntPatch_ArcFunction AFunc;
85   const Standard_Real Tolang = 1.e-8;
86   GeomAbs_SurfaceType typs1, typs2;
87   Standard_Boolean bEmpty = Standard_False;
88   //
89   const Standard_Integer iT1 = SetQuad(S1, typs1, quad1);
90   const Standard_Integer iT2 = SetQuad(S2, typs2, quad2);
91   //
92   if (!iT1 || !iT2) {
93     throw Standard_ConstructionError();
94     return;
95   }
96   //
97   const Standard_Boolean bReverse = iT1 > iT2;
98   const Standard_Integer iTT = iT1*10 + iT2;
99   //
100   switch (iTT) {
101     case 11: { // Plane/Plane
102       if (!IntPP(quad1, quad2, Tolang, TolTang, SameSurf, slin)) {
103         return;
104       }
105       break;
106     }
107     //
108     case 12:
109     case 21: { // Plane/Cylinder
110       Standard_Real VMin, VMax, H;
111       //
112       const Handle(Adaptor3d_HSurface)& aSCyl = bReverse ? S2 : S1;
113       VMin = aSCyl->FirstVParameter();
114       VMax = aSCyl->LastVParameter();
115       H = (Precision::IsNegativeInfinite(VMin) || 
116            Precision::IsPositiveInfinite(VMax)) ? 0 : (VMax - VMin);
117       //
118       if (!IntPCy(quad1, quad2, Tolang, TolTang, bReverse, empt, slin, H)) {
119         return;
120       }
121       bEmpty = empt;
122       break;
123     }
124     //
125     case 13:
126     case 31: { // Plane/Cone
127       if (!IntPCo(quad1, quad2, Tolang, TolTang, bReverse, empt, multpoint, slin, spnt)) {
128         return;
129       }
130       bEmpty = empt;
131       break;
132     }
133     //
134     case 14:
135     case 41: { // Plane/Sphere
136       if (!IntPSp(quad1, quad2, Tolang, TolTang, bReverse, empt, slin, spnt)) {
137         return;
138       }
139       bEmpty = empt;
140       break;
141     }
142     //
143     case 15:
144     case 51: { // Plane/Torus
145       if (!IntPTo(quad1, quad2, TolTang, bReverse, empt, slin)) {
146         return;
147       }
148       bEmpty = empt;
149       break;
150     }
151     //
152     case 22:
153       { // Cylinder/Cylinder
154         Bnd_Box2d aBox1, aBox2;
155
156         const Standard_Real aU1f = S1->FirstUParameter();
157         Standard_Real aU1l = S1->LastUParameter();
158         const Standard_Real aU2f = S2->FirstUParameter();
159         Standard_Real aU2l = S2->LastUParameter();
160
161         const Standard_Real anUperiod = 2.0*M_PI;
162
163         if(aU1l - aU1f > anUperiod)
164           aU1l = aU1f + anUperiod;
165
166         if(aU2l - aU2f > anUperiod)
167           aU2l = aU2f + anUperiod;
168
169         aBox1.Add(gp_Pnt2d(aU1f, S1->FirstVParameter()));
170         aBox1.Add(gp_Pnt2d(aU1l, S1->LastVParameter()));
171         aBox2.Add(gp_Pnt2d(aU2f, S2->FirstVParameter()));
172         aBox2.Add(gp_Pnt2d(aU2l, S2->LastVParameter()));
173
174         // Resolution is too big if the cylinder radius is
175         // too small. Therefore, we shall bounde its value above. 
176         // Here, we use simple constant.
177         const Standard_Real a2DTol = Min(1.0e-4, Min( S1->UResolution(TolTang),
178                                             S2->UResolution(TolTang)));
179
180         //The bigger range the bigger nunber of points in Walking-line (WLine)
181         //we will be able to add and, consequently, we will obtain more
182         //precise intersection line.
183         //Every point of WLine is determined as function from U1-parameter,
184         //where U1 is U-parameter on 1st quadric.
185         //Therefore, we should use quadric with bigger range as 1st parameter
186         //in IntCyCy() function.
187         //On the other hand, there is no point in reversing in case of
188         //analytical intersection (when result is line, ellipse, point...).
189         //This result is independent of the arguments order.
190         Standard_Boolean isReversed = ((aU2l - aU2f) < (aU1l - aU1f));
191
192         if(isReversed)
193         {
194           myDone = IntCyCy(quad2, quad1, TolTang, a2DTol, aBox2, aBox1,
195                                     Standard_True, empt, SameSurf, multpoint, slin, spnt);
196         }
197         else
198         {
199           myDone = IntCyCy(quad1, quad2, TolTang, a2DTol, aBox1, aBox2,
200                                     Standard_False, empt, SameSurf, multpoint, slin, spnt);
201         }
202
203         if (myDone == IntPatch_ImpImpIntersection::IntStatus_Fail)
204         {
205           return;
206         }
207
208         bEmpty = empt;
209         if(!slin.IsEmpty())
210         {
211           const Handle(IntPatch_WLine)& aWLine = 
212                                     Handle(IntPatch_WLine)::DownCast(slin.Value(1));
213
214           if(!aWLine.IsNull())
215           {//No geometric solution
216             isPostProcessingRequired = Standard_False;
217           }
218         }
219
220         break;
221       }
222     //
223     case 23:
224     case 32: { // Cylinder/Cone
225       if (!IntCyCo(quad1, quad2, TolTang, bReverse, empt, multpoint, slin, spnt)) {
226         return;
227       }
228       bEmpty = empt;
229       break;
230     }
231     //
232     case 24:
233     case 42: { // Cylinder/Sphere
234       if (!IntCySp(quad1, quad2, TolTang, bReverse, empt, multpoint, slin, spnt)) {
235         return;
236       }
237       bEmpty = empt;
238       break;
239     }
240     //
241     case 25:
242     case 52: { // Cylinder/Torus
243       if (!IntCyTo(quad1, quad2, TolTang, bReverse, empt, slin)) {
244         return;
245       }
246       bEmpty = empt;
247       break;
248     }
249     //
250     case 33: { // Cone/Cone
251       if (!IntCoCo(quad1, quad2, TolTang, empt, SameSurf, multpoint, slin, spnt)) {
252         return;
253       }
254       bEmpty = empt;
255       break;
256     }
257     //
258     case 34:
259     case 43: { // Cone/Sphere
260       if (!IntCoSp(quad1, quad2, TolTang, bReverse, empt, multpoint, slin, spnt)) {
261         return;
262       }
263       bEmpty = empt;
264       break;
265     }
266     //
267     case 35:
268     case 53: { // Cone/Torus
269       if (!IntCoTo(quad1, quad2, TolTang, bReverse, empt, slin)) {
270         return;
271       }
272       break;
273     }
274     //
275     case 44: { // Sphere/Sphere
276       if (!IntSpSp(quad1, quad2, TolTang, empt, SameSurf, slin, spnt)) {
277         return;
278       }
279       bEmpty = empt;
280       break;
281     }
282     //
283     case 45:
284     case 54: { // Sphere/Torus
285       if (!IntSpTo(quad1, quad2, TolTang, bReverse, empt, slin)) {
286         return;
287       }
288       bEmpty = empt;
289       break;
290     }
291     //
292     case 55: { // Torus/Torus
293       if (!IntToTo(quad1, quad2, TolTang, SameSurf, empt, slin)) {
294         return;
295       }
296       bEmpty = empt;
297       break;
298     }
299     //
300     default: {
301       throw Standard_ConstructionError();
302       break;
303     }
304   }
305   //
306   if (bEmpty) {
307     if (myDone == IntStatus_Fail)
308       myDone = IntStatus_OK;
309
310     return;
311   }
312   //
313
314   if(isPostProcessingRequired)
315   {
316     if (!SameSurf) {
317       AFunc.SetQuadric(quad2);
318       AFunc.Set(S1);
319     
320       solrst.Perform(AFunc, D1, TolArc, TolTang);
321       if (!solrst.IsDone()) {
322         return;
323       }
324
325       if (solrst.AllArcSolution() && typs1 == typs2) {
326         all1 = Standard_True;
327       }
328       nbpt = solrst.NbPoints();
329       nbseg= solrst.NbSegments();
330       for (i=1; i<= nbpt; i++) {
331         pnt1.Append(solrst.Point(i));
332       }
333       for (i=1; i<= nbseg; i++) {
334         edg1.Append(solrst.Segment(i));
335       }
336       nosolonS1 = (nbpt == 0) && (nbseg == 0);
337
338       if (nosolonS1 && all1) {  // cas de face sans restrictions
339         all1 = Standard_False;
340       }
341     }//if (!SameSurf) {
342     else {
343       nosolonS1 = Standard_True;
344     }
345
346     if (!SameSurf) {
347       AFunc.SetQuadric(quad1);
348       AFunc.Set(S2);
349
350       solrst.Perform(AFunc, D2, TolArc, TolTang);
351       if (!solrst.IsDone()) {
352         return;
353       }
354     
355       if (solrst.AllArcSolution() && typs1 == typs2) {
356         all2 = Standard_True;
357       }
358       nbpt = solrst.NbPoints();
359       nbseg= solrst.NbSegments();
360       for (i=1; i<= nbpt; i++) {
361         pnt2.Append(solrst.Point(i));
362       }
363     
364       for (i=1; i<= nbseg; i++) {
365         edg2.Append(solrst.Segment(i));
366       }
367       nosolonS2 = (nbpt == 0) && (nbseg == 0);
368
369       if (nosolonS2 && all2) {  // cas de face sans restrictions
370         all2 = Standard_False;
371       }
372     }// if (!SameSurf) {
373     else {
374       nosolonS2 = Standard_True;
375     }
376     //
377     if (SameSurf || (all1 && all2)) {
378       // faces "paralleles" parfaites
379       empt = Standard_False;
380       tgte = Standard_True;
381       slin.Clear();
382       spnt.Clear();
383
384       gp_Pnt Ptreference;
385
386       switch (typs1) {
387       case GeomAbs_Plane:      {
388         Ptreference = (S1->Plane()).Location();
389       }
390         break;
391       case GeomAbs_Cylinder: {
392         Ptreference = ElSLib::Value(0.,0.,S1->Cylinder());
393       }
394         break;
395       case GeomAbs_Sphere:      {
396         Ptreference = ElSLib::Value(M_PI/4.,M_PI/4.,S1->Sphere());
397       }
398         break;
399       case GeomAbs_Cone:      {
400         Ptreference = ElSLib::Value(0.,10.,S1->Cone());
401       }
402         break;
403       case GeomAbs_Torus:      {
404         Ptreference = ElSLib::Value(0.,0.,S1->Torus());
405       }
406         break;
407       default: 
408         break;
409       }
410       //
411       oppo = quad1.Normale(Ptreference).Dot(quad2.Normale(Ptreference)) < 0.0;
412       myDone = IntStatus_OK;
413       return;
414     }// if (SameSurf || (all1 && all2)) {
415
416     if (!nosolonS1 || !nosolonS2) {
417       empt = Standard_False;
418       // C est la qu il faut commencer a bosser...
419       PutPointsOnLine(S1,S2,pnt1, slin, Standard_True, D1, quad1,quad2,
420                       multpoint,TolArc);
421     
422       PutPointsOnLine(S1,S2,pnt2, slin, Standard_False,D2, quad2,quad1,
423                       multpoint,TolArc);
424
425       if (edg1.Length() != 0) {
426         ProcessSegments(edg1,slin,quad1,quad2,Standard_True,TolArc);
427       }
428
429       if (edg2.Length() != 0) {
430         ProcessSegments(edg2,slin,quad1,quad2,Standard_False,TolArc);
431       }
432
433       if (edg1.Length() !=0 || edg2.Length() !=0) {
434         //      ProcessRLine(slin,S1,S2,TolArc);
435         ProcessRLine(slin,quad1,quad2,TolArc, theIsReqToKeepRLine);
436       }
437     }//if (!nosolonS1 || !nosolonS2) {
438     else {
439       empt = ((slin.Length()==0) && (spnt.Length()==0));
440     }
441   }
442   
443   Standard_Integer  nblin = slin.Length(),
444                     aNbPnt = spnt.Length();
445   //
446   //modified by NIZNHY-PKV Tue Sep 06 10:03:35 2011f
447   if (aNbPnt) {
448     IntPatch_SequenceOfPoint aSIP;
449     //
450     for(i=1; i<=aNbPnt; ++i) {
451       Standard_Real aU1, aV1, aU2, aV2;
452       gp_Pnt2d aP2D;
453       TopAbs_State aState1, aState2;
454       //
455       const IntPatch_Point& aIP=spnt(i);
456       aIP.Parameters(aU1, aV1, aU2, aV2);
457       //
458       aP2D.SetCoord(aU1, aV1);
459       aState1=D1->Classify(aP2D, TolArc);
460       //
461       aP2D.SetCoord(aU2, aV2);
462       aState2=D2->Classify(aP2D, TolArc);
463       //
464       if(aState1!=TopAbs_OUT && aState2!=TopAbs_OUT) {
465         aSIP.Append(aIP);
466       }
467     }
468     //
469     spnt.Clear();
470     //
471     aNbPnt=aSIP.Length();
472     for(i=1; i<=aNbPnt; ++i) {
473       const IntPatch_Point& aIP=aSIP(i);
474       spnt.Append(aIP);
475     }
476     //
477   }//  if (aNbPnt) {
478   //modified by NIZNHY-PKV Tue Sep 06 10:18:20 2011t
479   //
480   for(i=1; i<=nblin; i++) {
481     IntPatch_IType thetype = slin.Value(i)->ArcType();
482     if(  (thetype ==  IntPatch_Ellipse)
483        ||(thetype ==  IntPatch_Circle)
484        ||(thetype ==  IntPatch_Lin)
485        ||(thetype ==  IntPatch_Parabola)
486        ||(thetype ==  IntPatch_Hyperbola)) { 
487       Handle(IntPatch_GLine)& glin = *((Handle(IntPatch_GLine)*)&slin.Value(i));
488     glin->ComputeVertexParameters(TolArc); 
489     }
490     else if(thetype == IntPatch_Analytic) { 
491       Handle(IntPatch_ALine)& aligold = *((Handle(IntPatch_ALine)*)&slin.Value(i));
492       aligold->ComputeVertexParameters(TolArc);
493     }
494     else if(thetype == IntPatch_Restriction) {
495       Handle(IntPatch_RLine)& rlig = *((Handle(IntPatch_RLine)*)&slin.Value(i));
496       rlig->ComputeVertexParameters(TolArc); 
497     }
498   }
499   //
500   //----------------------------------------------------------------
501   //-- On place 2 vertex sur les courbes de GLine qui n en 
502   //-- contiennent pas. 
503   for(i=1; i<=nblin; i++) {
504     gp_Pnt P;
505     IntPatch_Point point;
506     Standard_Real u1,v1,u2,v2; 
507     if(slin.Value(i)->ArcType() == IntPatch_Circle) { 
508       const Handle(IntPatch_GLine)& glin = *((Handle(IntPatch_GLine)*)&slin.Value(i));
509       if(glin->NbVertex() == 0) { 
510         gp_Circ Circ = glin->Circle();
511         P=ElCLib::Value(0.0,Circ);
512         quad1.Parameters(P,u1,v1);
513         quad2.Parameters(P,u2,v2);
514         point.SetValue(P,TolArc,Standard_False);
515         point.SetParameters(u1,v1,u2,v2);
516         point.SetParameter(0.0);
517         glin->AddVertex(point);
518
519         P=ElCLib::Value(0.0,Circ);
520         quad1.Parameters(P,u1,v1);
521         quad2.Parameters(P,u2,v2);
522         point.SetValue(P,TolArc,Standard_False);
523         point.SetParameters(u1,v1,u2,v2);
524         point.SetParameter(M_PI+M_PI);
525         glin->AddVertex(point);
526       }
527     }
528     
529     else if(slin.Value(i)->ArcType() == IntPatch_Ellipse) { 
530       const Handle(IntPatch_GLine)& glin = *((Handle(IntPatch_GLine)*)&slin.Value(i));
531       if(glin->NbVertex() == 0) { 
532         gp_Elips Elips = glin->Ellipse();
533         P=ElCLib::Value(0.0,Elips);
534         quad1.Parameters(P,u1,v1);
535         quad2.Parameters(P,u2,v2);
536         point.SetValue(P,TolArc,Standard_False);
537         point.SetParameters(u1,v1,u2,v2);
538         point.SetParameter(0.0);
539         glin->AddVertex(point);
540
541         P=ElCLib::Value(0.0,Elips);
542         quad1.Parameters(P,u1,v1);
543         quad2.Parameters(P,u2,v2);
544         point.SetValue(P,TolArc,Standard_False);
545         point.SetParameters(u1,v1,u2,v2);
546         point.SetParameter(M_PI+M_PI);
547         glin->AddVertex(point);
548       }
549     }
550   }
551   myDone = IntStatus_OK;
552 }
553
554 //=======================================================================
555 //function : SetQuad
556 //purpose  : 
557 //=======================================================================
558 Standard_Integer SetQuad(const Handle(Adaptor3d_HSurface)& theS,
559                          GeomAbs_SurfaceType& theTS,
560                          IntSurf_Quadric& theQuad)
561 {
562   theTS = theS->GetType();
563   Standard_Integer iRet = 0;
564   switch (theTS) {
565   case GeomAbs_Plane:
566     theQuad.SetValue(theS->Plane());
567     iRet = 1;
568     break;
569   case GeomAbs_Cylinder:
570     theQuad.SetValue(theS->Cylinder());
571     iRet = 2;
572     break;
573   case GeomAbs_Cone:
574     theQuad.SetValue(theS->Cone());
575     iRet = 3;
576     break;
577   case GeomAbs_Sphere:
578     theQuad.SetValue(theS->Sphere());
579     iRet = 4;
580     break;
581   case GeomAbs_Torus:
582     theQuad.SetValue(theS->Torus());
583     iRet = 5;
584     break;
585   default:
586     break;
587   }
588   //
589   return iRet;
590 }
591