106ac70854dac1b3dad0dfd5187f0328bfa7b348
[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 static 
18   Standard_Integer SetQuad(const Handle(Adaptor3d_HSurface)& theS,
19                            GeomAbs_SurfaceType& theTS,
20                            IntSurf_Quadric& theQuad);
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, quad2;
77   IntPatch_ArcFunction AFunc;
78   const Standard_Real Tolang = 1.e-8;
79   GeomAbs_SurfaceType typs1, typs2;
80   Standard_Boolean bEmpty = Standard_False;
81   //
82   const Standard_Integer iT1 = SetQuad(S1, typs1, quad1);
83   const Standard_Integer iT2 = SetQuad(S2, typs2, quad2);
84   //
85   if (!iT1 || !iT2) {
86     Standard_ConstructionError::Raise();
87     return;
88   }
89   //
90   const Standard_Boolean bReverse = iT1 > iT2;
91   const Standard_Integer iTT = iT1*10 + iT2;
92   //
93   switch (iTT) {
94     case 11: { // Plane/Plane
95       if (!IntPP(quad1, quad2, Tolang, TolTang, SameSurf, slin)) {
96         return;
97       }
98       break;
99     }
100     //
101     case 12:
102     case 21: { // Plane/Cylinder
103       Standard_Real VMin, VMax, H;
104       //
105       const Handle(Adaptor3d_HSurface)& aSCyl = bReverse ? S2 : S1;
106       VMin = aSCyl->FirstVParameter();
107       VMax = aSCyl->LastVParameter();
108       H = (Precision::IsNegativeInfinite(VMin) || 
109            Precision::IsPositiveInfinite(VMax)) ? 0 : (VMax - VMin);
110       //
111       if (!IntPCy(quad1, quad2, Tolang, TolTang, bReverse, empt, slin, H)) {
112         return;
113       }
114       bEmpty = empt;
115       break;
116     }
117     //
118     case 13:
119     case 31: { // Plane/Cone
120       if (!IntPCo(quad1, quad2, Tolang, TolTang, bReverse, empt, multpoint, slin, spnt)) {
121         return;
122       }
123       bEmpty = empt;
124       break;
125     }
126     //
127     case 14:
128     case 41: { // Plane/Sphere
129       if (!IntPSp(quad1, quad2, Tolang, TolTang, bReverse, empt, slin, spnt)) {
130         return;
131       }
132       bEmpty = empt;
133       break;
134     }
135     //
136     case 15:
137     case 51: { // Plane/Torus
138       if (!IntPTo(quad1, quad2, TolTang, bReverse, empt, slin)) {
139         return;
140       }
141       bEmpty = empt;
142       break;
143     }
144     //
145     case 22: { // Cylinder/Cylinder
146       if (!IntCyCy(quad1, quad2, TolTang, empt, SameSurf, multpoint, slin, spnt)) {
147         return;
148       }
149       bEmpty = empt;
150       break;
151     }
152     //
153     case 23:
154     case 32: { // Cylinder/Cone
155       if (!IntCyCo(quad1, quad2, TolTang, bReverse, empt, multpoint, slin, spnt)) {
156         return;
157       }
158       bEmpty = empt;
159       break;
160     }
161     //
162     case 24:
163     case 42: { // Cylinder/Sphere
164       if (!IntCySp(quad1, quad2, TolTang, bReverse, empt, multpoint, slin, spnt)) {
165         return;
166       }
167       bEmpty = empt;
168       break;
169     }
170     //
171     case 25:
172     case 52: { // Cylinder/Torus
173       if (!IntCyTo(quad1, quad2, TolTang, bReverse, empt, slin)) {
174         return;
175       }
176       bEmpty = empt;
177       break;
178     }
179     //
180     case 33: { // Cone/Cone
181       if (!IntCoCo(quad1, quad2, TolTang, empt, SameSurf, multpoint, slin, spnt)) {
182         return;
183       }
184       bEmpty = empt;
185       break;
186     }
187     //
188     case 34:
189     case 43: { // Cone/Sphere
190       if (!IntCoSp(quad1, quad2, TolTang, bReverse, empt, multpoint, slin, spnt)) {
191         return;
192       }
193       bEmpty = empt;
194       break;
195     }
196     //
197     case 35:
198     case 53: { // Cone/Torus
199       if (!IntCoTo(quad1, quad2, TolTang, bReverse, empt, slin)) {
200         return;
201       }
202       break;
203     }
204     //
205     case 44: { // Sphere/Sphere
206       if (!IntSpSp(quad1, quad2, TolTang, empt, SameSurf, slin, spnt)) {
207         return;
208       }
209       bEmpty = empt;
210       break;
211     }
212     //
213     case 45:
214     case 54: { // Sphere/Torus
215       if (!IntSpTo(quad1, quad2, TolTang, bReverse, empt, slin)) {
216         return;
217       }
218       bEmpty = empt;
219       break;
220     }
221     //
222     case 55: { // Torus/Torus
223       if (!IntToTo(quad1, quad2, TolTang, SameSurf, empt, slin)) {
224         return;
225       }
226       bEmpty = empt;
227       break;
228     }
229     //
230     default: {
231       Standard_ConstructionError::Raise();
232       break;
233     }
234   }
235   //
236   if (bEmpty) {
237     done = Standard_True;
238     return;
239   }
240   //
241   if (!SameSurf) {
242     AFunc.SetQuadric(quad2);
243     AFunc.Set(S1);
244     
245     solrst.Perform(AFunc, D1, TolArc, TolTang);
246     if (!solrst.IsDone()) {
247       return;
248     }
249
250     if (solrst.AllArcSolution() && typs1 == typs2) {
251       all1 = Standard_True;
252     }
253     nbpt = solrst.NbPoints();
254     nbseg= solrst.NbSegments();
255     for (i=1; i<= nbpt; i++) {
256       pnt1.Append(solrst.Point(i));
257     }
258     for (i=1; i<= nbseg; i++) {
259       edg1.Append(solrst.Segment(i));
260     }
261     nosolonS1 = (nbpt == 0) && (nbseg == 0);
262
263     if (nosolonS1 && all1) {  // cas de face sans restrictions
264       all1 = Standard_False;
265     }
266   }//if (!SameSurf) {
267   else {
268     nosolonS1 = Standard_True;
269   }
270
271   if (!SameSurf) {
272     AFunc.SetQuadric(quad1);
273     AFunc.Set(S2);
274
275     solrst.Perform(AFunc, D2, TolArc, TolTang);
276     if (!solrst.IsDone()) {
277       return;
278     }
279     
280     if (solrst.AllArcSolution() && typs1 == typs2) {
281       all2 = Standard_True;
282     }
283     nbpt = solrst.NbPoints();
284     nbseg= solrst.NbSegments();
285     for (i=1; i<= nbpt; i++) {
286       pnt2.Append(solrst.Point(i));
287     }
288     
289     for (i=1; i<= nbseg; i++) {
290       edg2.Append(solrst.Segment(i));
291     }
292     nosolonS2 = (nbpt == 0) && (nbseg == 0);
293
294     if (nosolonS2 && all2) {  // cas de face sans restrictions
295       all2 = Standard_False;
296     }
297   }// if (!SameSurf) {
298   else {
299     nosolonS2 = Standard_True;
300   }
301   //
302   if (SameSurf || (all1 && all2)) {
303     // faces "paralleles" parfaites
304     empt = Standard_False;
305     tgte = Standard_True;
306     slin.Clear();
307     spnt.Clear();
308
309     gp_Pnt Ptreference;
310
311     switch (typs1) {
312     case GeomAbs_Plane:      {
313       Ptreference = (S1->Plane()).Location();
314     }
315       break;
316     case GeomAbs_Cylinder: {
317       Ptreference = ElSLib::Value(0.,0.,S1->Cylinder());
318     }
319       break;
320     case GeomAbs_Sphere:      {
321       Ptreference = ElSLib::Value(M_PI/4.,M_PI/4.,S1->Sphere());
322     }
323       break;
324     case GeomAbs_Cone:      {
325       Ptreference = ElSLib::Value(0.,10.,S1->Cone());
326     }
327       break;
328     case GeomAbs_Torus:      {
329       Ptreference = ElSLib::Value(0.,0.,S1->Torus());
330     }
331       break;
332     default: 
333       break;
334     }
335     //
336     oppo = quad1.Normale(Ptreference).Dot(quad2.Normale(Ptreference)) < 0.0;
337     done = Standard_True;
338     return;
339   }// if (SameSurf || (all1 && all2)) {
340
341   if (!nosolonS1 || !nosolonS2) {
342     empt = Standard_False;
343     // C est la qu il faut commencer a bosser...
344     PutPointsOnLine(S1,S2,pnt1, slin, Standard_True, D1, quad1,quad2,
345                     multpoint,TolArc);
346     
347     PutPointsOnLine(S1,S2,pnt2, slin, Standard_False,D2, quad2,quad1,
348                     multpoint,TolArc);
349
350     if (edg1.Length() != 0) {
351       ProcessSegments(edg1,slin,quad1,quad2,Standard_True,TolArc);
352     }
353
354     if (edg2.Length() != 0) {
355       ProcessSegments(edg2,slin,quad1,quad2,Standard_False,TolArc);
356     }
357
358     if (edg1.Length() !=0 || edg2.Length() !=0) {
359       //      ProcessRLine(slin,S1,S2,TolArc);
360       ProcessRLine(slin,quad1,quad2,TolArc);
361     }
362   }//if (!nosolonS1 || !nosolonS2) {
363   else {
364     empt = ((slin.Length()==0) && (spnt.Length()==0));
365   }
366   //
367   Standard_Integer nblin, aNbPnt;
368   //
369   //modified by NIZNHY-PKV Tue Sep 06 10:03:35 2011f
370   aNbPnt=spnt.Length();
371   if (aNbPnt) {
372     IntPatch_SequenceOfPoint aSIP;
373     //
374     for(i=1; i<=aNbPnt; ++i) {
375       Standard_Real aU1, aV1, aU2, aV2;
376       gp_Pnt2d aP2D;
377       TopAbs_State aState1, aState2;
378       //
379       const IntPatch_Point& aIP=spnt(i);
380       aIP.Parameters(aU1, aV1, aU2, aV2);
381       //
382       aP2D.SetCoord(aU1, aV1);
383       aState1=D1->Classify(aP2D, TolArc);
384       //
385       aP2D.SetCoord(aU2, aV2);
386       aState2=D2->Classify(aP2D, TolArc);
387       //
388       if(aState1!=TopAbs_OUT && aState2!=TopAbs_OUT) {
389         aSIP.Append(aIP);
390       }
391     }
392     //
393     spnt.Clear();
394     //
395     aNbPnt=aSIP.Length();
396     for(i=1; i<=aNbPnt; ++i) {
397       const IntPatch_Point& aIP=aSIP(i);
398       spnt.Append(aIP);
399     }
400     //
401   }//  if (aNbPnt) {
402   //modified by NIZNHY-PKV Tue Sep 06 10:18:20 2011t
403   //
404   nblin = slin.Length();
405   for(i=1; i<=nblin; i++) {
406     IntPatch_IType thetype = slin.Value(i)->ArcType();
407     if(  (thetype ==  IntPatch_Ellipse)
408        ||(thetype ==  IntPatch_Circle)
409        ||(thetype ==  IntPatch_Lin)
410        ||(thetype ==  IntPatch_Parabola)
411        ||(thetype ==  IntPatch_Hyperbola)) { 
412       Handle(IntPatch_GLine)& glin = *((Handle(IntPatch_GLine)*)&slin.Value(i));
413     glin->ComputeVertexParameters(TolArc); 
414     }
415     else if(thetype == IntPatch_Analytic) { 
416       Handle(IntPatch_ALine)& aligold = *((Handle(IntPatch_ALine)*)&slin.Value(i));
417       aligold->ComputeVertexParameters(TolArc);
418     }
419     else if(thetype == IntPatch_Restriction) {
420       Handle(IntPatch_RLine)& rlig = *((Handle(IntPatch_RLine)*)&slin.Value(i));
421       rlig->ComputeVertexParameters(TolArc); 
422     }
423   }
424   //
425   //----------------------------------------------------------------
426   //-- On place 2 vertex sur les courbes de GLine qui n en 
427   //-- contiennent pas. 
428   for(i=1; i<=nblin; i++) {
429     gp_Pnt P;
430     IntPatch_Point point;
431     Standard_Real u1,v1,u2,v2; 
432     if(slin.Value(i)->ArcType() == IntPatch_Circle) { 
433       const Handle(IntPatch_GLine)& glin = *((Handle(IntPatch_GLine)*)&slin.Value(i));
434       if(glin->NbVertex() == 0) { 
435         gp_Circ Circ = glin->Circle();
436         P=ElCLib::Value(0.0,Circ);
437         quad1.Parameters(P,u1,v1);
438         quad2.Parameters(P,u2,v2);
439         point.SetValue(P,TolArc,Standard_False);
440         point.SetParameters(u1,v1,u2,v2);
441         point.SetParameter(0.0);
442         glin->AddVertex(point);
443
444         P=ElCLib::Value(0.0,Circ);
445         quad1.Parameters(P,u1,v1);
446         quad2.Parameters(P,u2,v2);
447         point.SetValue(P,TolArc,Standard_False);
448         point.SetParameters(u1,v1,u2,v2);
449         point.SetParameter(M_PI+M_PI);
450         glin->AddVertex(point);
451       }
452     }
453     
454     else if(slin.Value(i)->ArcType() == IntPatch_Ellipse) { 
455       const Handle(IntPatch_GLine)& glin = *((Handle(IntPatch_GLine)*)&slin.Value(i));
456       if(glin->NbVertex() == 0) { 
457         gp_Elips Elips = glin->Ellipse();
458         P=ElCLib::Value(0.0,Elips);
459         quad1.Parameters(P,u1,v1);
460         quad2.Parameters(P,u2,v2);
461         point.SetValue(P,TolArc,Standard_False);
462         point.SetParameters(u1,v1,u2,v2);
463         point.SetParameter(0.0);
464         glin->AddVertex(point);
465
466         P=ElCLib::Value(0.0,Elips);
467         quad1.Parameters(P,u1,v1);
468         quad2.Parameters(P,u2,v2);
469         point.SetValue(P,TolArc,Standard_False);
470         point.SetParameters(u1,v1,u2,v2);
471         point.SetParameter(M_PI+M_PI);
472         glin->AddVertex(point);
473       }
474     }
475   }
476   done = Standard_True;
477 }
478
479 //=======================================================================
480 //function : SetQuad
481 //purpose  : 
482 //=======================================================================
483 Standard_Integer SetQuad(const Handle(Adaptor3d_HSurface)& theS,
484                          GeomAbs_SurfaceType& theTS,
485                          IntSurf_Quadric& theQuad)
486 {
487   theTS = theS->GetType();
488   Standard_Integer iRet = 0;
489   switch (theTS) {
490   case GeomAbs_Plane:
491     theQuad.SetValue(theS->Plane());
492     iRet = 1;
493     break;
494   case GeomAbs_Cylinder:
495     theQuad.SetValue(theS->Cylinder());
496     iRet = 2;
497     break;
498   case GeomAbs_Cone:
499     theQuad.SetValue(theS->Cone());
500     iRet = 3;
501     break;
502   case GeomAbs_Sphere:
503     theQuad.SetValue(theS->Sphere());
504     iRet = 4;
505     break;
506   case GeomAbs_Torus:
507     theQuad.SetValue(theS->Torus());
508     iRet = 5;
509     break;
510   default:
511     break;
512   }
513   //
514   return iRet;
515 }
516