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