0024157: Parallelization of assembly part of BO
[occt.git] / src / IntImpParGen / IntImpParGen_Intersector.gxx
1 // Created on: 1992-03-02
2 // Created by: Laurent BUCHARD
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 #include <Standard_ConstructionError.hxx>
24 #include <IntRes2d_Domain.hxx>
25 #include <IntRes2d_IntersectionPoint.hxx>
26 #include <IntRes2d_IntersectionSegment.hxx>
27 #include <IntRes2d_SequenceOfIntersectionPoint.hxx>
28 #include <IntRes2d_SequenceOfIntersectionSegment.hxx>
29 #include <IntRes2d_Transition.hxx>
30 #include <IntRes2d_Position.hxx>
31
32 #include <IntImpParGen.hxx>
33
34 #include <math_FunctionSample.hxx>
35 #include <math_FunctionAllRoots.hxx>
36
37 #include <TColStd_Array1OfReal.hxx>
38 #include <gp.hxx>
39 #include <gp_Vec2d.hxx>
40
41 //======================================================================
42 #define EPSDIST Tol
43 #define EPSNUL  TolConf
44 #define EPSX    ParTool::EpsX(TheParCurve)
45 #define NB_ECHANTILLONS 
46
47
48
49
50 //======================================================================
51 void IntImpParGen_Intersector::And_Domaine_Objet1_Intersections(const ImpTool& TheImpTool,
52                               const ParCurve& TheParCurve,
53                               const IntRes2d_Domain& TheImpCurveDomain,
54                               const IntRes2d_Domain& TheParCurveDomain,
55                               Standard_Integer& NbResultats,
56                               TColStd_Array1OfReal& Inter2_And_Domain2,
57                               TColStd_Array1OfReal& Inter1,
58                               TColStd_Array1OfReal& Resultat1,
59                               TColStd_Array1OfReal& Resultat2,
60                               const Standard_Real EpsNul) const {
61
62   
63   Standard_Integer Nb_Bornes_Intersection=NbResultats;
64   NbResultats=0;
65   
66   for(Standard_Integer i=1; i<=Nb_Bornes_Intersection; i+=2) {
67     Standard_Boolean reverse=Standard_False;
68     
69     Standard_Real param1=Inter1.Value(i);
70     Standard_Real param2=Inter1.Value(i+1);
71
72     Standard_Integer indice_1=i;
73     Standard_Integer indice_2=i+1;
74
75     if(param1>param2) {
76       Standard_Real t=param1; param1=param2; param2=t;
77       indice_1=i+1;
78       indice_2=i;
79       reverse=Standard_True;
80     }
81
82     gp_Pnt2d Pt1=TheImpTool.Value(param1);
83     gp_Pnt2d Pt2=TheImpTool.Value(param2);
84     gp_Pnt2d Pt;
85
86     Standard_Boolean IsOnTheImpCurveDomain1=Standard_True;
87     Standard_Boolean IsOnABoundary1=Standard_False;
88
89     Standard_Boolean IsOnTheImpCurveDomain2=Standard_True;
90     Standard_Boolean IsOnABoundary2=Standard_False;
91     //--------------------------------------------------------------------
92     if(TheImpCurveDomain.HasFirstPoint()) { 
93       if(param1<TheImpCurveDomain.FirstParameter()) {             
94         if(Pt1.Distance(TheImpCurveDomain.FirstPoint()) 
95            > TheImpCurveDomain.FirstTolerance()) {
96           IsOnTheImpCurveDomain1=Standard_False; 
97         }
98         else {    IsOnABoundary1=Standard_True;         }
99       }
100     }
101     if(IsOnTheImpCurveDomain1 && TheImpCurveDomain.HasLastPoint()) {
102       if(param1>TheImpCurveDomain.LastParameter()) {
103         if(Pt1.Distance(TheImpCurveDomain.LastPoint()) 
104            > TheImpCurveDomain.FirstTolerance()) {
105           IsOnTheImpCurveDomain1=Standard_False; 
106         }
107         else {    IsOnABoundary1=Standard_True;         }
108       }
109     }
110     //--------------------------------------------------------------------
111     if(TheImpCurveDomain.HasFirstPoint()) { 
112       if(param2<TheImpCurveDomain.FirstParameter()) {             
113         if(Pt2.Distance(TheImpCurveDomain.FirstPoint()) 
114            > TheImpCurveDomain.FirstTolerance()) {
115           IsOnTheImpCurveDomain2=Standard_False; 
116         }
117         else {    IsOnABoundary2=Standard_True;         }
118       }
119     }
120     if(IsOnTheImpCurveDomain2 && TheImpCurveDomain.HasLastPoint()) {
121       if(param2>TheImpCurveDomain.LastParameter()) {
122         if(Pt2.Distance(TheImpCurveDomain.LastPoint()) 
123            > TheImpCurveDomain.FirstTolerance()) {
124           IsOnTheImpCurveDomain2=Standard_False; 
125         }
126         else {    IsOnABoundary2=Standard_True;         }
127       }
128     }
129
130     if(IsOnTheImpCurveDomain1) {
131       //------------------------------------------------------------------
132       //---                 la borne 1 est sur le domaine               --
133       NbResultats++;
134       Resultat1.SetValue(NbResultats,Inter1.Value(indice_1));
135       Resultat2.SetValue(NbResultats,Inter2_And_Domain2.Value(indice_1));
136       //---               la borne2 est aussi sur le domaine           ---
137       if(IsOnTheImpCurveDomain2) {
138         NbResultats++;
139         Resultat1.SetValue(NbResultats,Inter1.Value(indice_2));
140         Resultat2.SetValue(NbResultats,Inter2_And_Domain2.Value(indice_2));
141       }
142       else {
143         //---    Borne1 sur domaine et Borne 2 Hors Domaine           ---
144         Standard_Real t;
145         NbResultats++;
146         t=TheImpCurveDomain.LastParameter();  
147         Resultat1.SetValue(NbResultats,t);
148 //      Standard_Real popResult = FindV(t,Pt,TheImpTool,TheParCurve,
149 //                                                                TheParCurveDomain,
150 //                                                                Inter2_And_Domain2.Value(indice_1),
151 //                                                                Inter2_And_Domain2.Value(indice_2),
152 //                                                                EpsNul);
153 //      
154 //      Resultat2.SetValue(NbResultats,popResult);
155         Resultat2.SetValue(NbResultats,
156                            IntImpParGen_Intersector::FindV(t,Pt,TheImpTool,TheParCurve,
157                                                            TheParCurveDomain,
158                                                            Inter2_And_Domain2.Value(indice_1),
159                                                            Inter2_And_Domain2.Value(indice_2),
160                                                            EpsNul));
161       }
162     }
163     else { //======= la borne1 n est pas sur le domaine ========
164       if(IsOnTheImpCurveDomain2) {
165         Standard_Real t;
166         NbResultats++;
167         t=TheImpCurveDomain.FirstParameter(); 
168         
169         Resultat1.SetValue(NbResultats,t);
170         Resultat2.SetValue(NbResultats,
171                            IntImpParGen_Intersector::FindV(t,Pt,TheImpTool,TheParCurve,
172                                  TheParCurveDomain,
173                                  Inter2_And_Domain2.Value(indice_1),
174                                  Inter2_And_Domain2.Value(indice_2),
175                                  EpsNul));
176         
177         NbResultats++;
178         Resultat1.SetValue(NbResultats,Inter1.Value(indice_2));
179         Resultat2.SetValue(NbResultats,Inter2_And_Domain2.Value(indice_2));
180       }
181       else {  //====== la borne2 et la borne1 sont hors domaine =====
182         if(param1<TheImpCurveDomain.FirstParameter()
183            && param2>TheImpCurveDomain.LastParameter()) {
184           Standard_Real t;
185           NbResultats++;
186           t=TheImpCurveDomain.FirstParameter();
187           Resultat1.SetValue(NbResultats,t);
188           Resultat2.SetValue(NbResultats,
189                              IntImpParGen_Intersector::FindV(t,Pt,TheImpTool,TheParCurve,
190                                                              TheParCurveDomain,
191                                                              Inter2_And_Domain2.Value(indice_1),
192                                                              Inter2_And_Domain2.Value(indice_2),
193                                                              EpsNul));
194
195
196           
197           NbResultats++;
198           t=TheImpCurveDomain.LastParameter();
199           Resultat1.SetValue(NbResultats,t);
200           Resultat2.SetValue(NbResultats,
201                              IntImpParGen_Intersector::FindV(t,Pt,TheImpTool,TheParCurve,
202                                    TheParCurveDomain,
203                                    Inter2_And_Domain2.Value(indice_1),
204                                    Inter2_And_Domain2.Value(indice_2),
205                                    EpsNul));
206           
207         }
208       }
209     }
210   }
211 }
212 //======================================================================
213 //--     C o n s t r u c t e u r s     e t     P e r f o r m 
214 IntImpParGen_Intersector::IntImpParGen_Intersector() {
215   done=Standard_False;
216 }
217 //----------------------------------------------------------------------
218 //--
219 IntImpParGen_Intersector::IntImpParGen_Intersector(const ImpTool& TheImpTool,
220                                         const IntRes2d_Domain& TheImpCurveDomain,
221                                         const ParCurve& TheParCurve,
222                                         const IntRes2d_Domain& TheParCurveDomain,
223                                         const Standard_Real TolConf,
224                                         const Standard_Real Tol) {
225   Perform(TheImpTool,TheImpCurveDomain,TheParCurve,TheParCurveDomain,TolConf,Tol);
226 }
227 //----------------------------------------------------------------------
228 //--
229 void IntImpParGen_Intersector::Perform(const ImpTool& TheImpTool,
230                                         const IntRes2d_Domain& TheImpCurveDomain,
231                                         const ParCurve& TheParCurve,
232                                         const IntRes2d_Domain& TheParCurveDomain,
233                                         const Standard_Real TolConf,
234                                         const Standard_Real Tol) {
235
236
237   Standard_Integer i,nb_segments_solution, nb_points_solution;
238   Standard_Real param1,param2,EpsX, EpsNul, EpsDist;
239   
240   IntRes2d_Transition Trans1,Trans2;
241   gp_Pnt2d pt1,pt2;
242   gp_Vec2d Tan1,Tan2,Norm1,Norm2;
243   IntRes2d_Position Pos1,Pos2;
244
245
246   //----------------------------------------------
247   //-- On teste apres appel aux maths si les bornes 
248   //-- des domaines sont des solutions
249   //-- 
250   Standard_Boolean HeadOnImp =Standard_False;
251   Standard_Boolean HeadOnPar =Standard_False;
252   Standard_Boolean EndOnImp  =Standard_False;
253   Standard_Boolean EndOnPar  =Standard_False;
254
255   this->ResetFields();
256
257   IntImpParGen_MyImpParTool TheImpParTool(TheImpTool,TheParCurve);
258
259   if (! (TheParCurveDomain.HasFirstPoint() &&
260          TheParCurveDomain.HasLastPoint())) {
261     Standard_ConstructionError::Raise("Domaine sur courbe incorrect");
262     }
263   
264   Standard_Integer nb_echantillons = ParTool::NbSamples(TheParCurve,
265                                                         TheParCurveDomain.FirstParameter(),
266                                                         TheParCurveDomain.LastParameter());
267
268   EpsX = EPSX;
269   if(EpsX>1.0e-10) EpsX = 1.0e-10;
270   EpsNul=(TolConf<=1.0e-10)? 1.0e-10: TolConf;
271   EpsDist=(Tol<=1.0e-10)? 1.0e-10: Tol;
272   
273   Standard_Real Tolerance_Angulaire=EpsDist;  
274   
275
276
277   if((TheParCurveDomain.LastParameter() - TheParCurveDomain.FirstParameter()) < 100.0*EpsX) {
278     EpsX = (TheParCurveDomain.LastParameter() - TheParCurveDomain.FirstParameter())*0.01;
279   }
280
281     math_FunctionSample Sample2(TheParCurveDomain.FirstParameter(),
282                                 TheParCurveDomain.LastParameter(),
283                                 nb_echantillons);
284     
285     math_FunctionAllRoots Sol(TheImpParTool,
286                               Sample2,
287                               EpsX,
288                               EpsDist,
289                               EpsNul);
290     
291     if(!Sol.IsDone()) {done = Standard_False; return; }
292     
293     nb_segments_solution=Sol.NbIntervals();
294     nb_points_solution=Sol.NbPoints();
295     
296     //--------------------------------------------------------------------
297   //--   T r a i t e m e n t    d e s   P o i n t s   S o l u t i o n s
298   for(i=1; i<=nb_points_solution; i++) {
299     gp_Pnt2d Pt;
300     param2=Sol.GetPoint(i);
301     param1=FindU(param2,Pt,TheParCurve,TheImpTool);
302   
303     if(TheImpCurveDomain.IsClosed()) {
304       param1 = IntImpParGen::NormalizeOnDomain( param1
305                                  ,TheImpCurveDomain);
306     }
307     
308     Standard_Boolean IsOnTheImpCurveDomain=Standard_True;
309     if(TheImpCurveDomain.HasFirstPoint()) { 
310       if(param1<TheImpCurveDomain.FirstParameter()) {             
311         if(Pt.Distance(TheImpCurveDomain.FirstPoint()) 
312            > TheImpCurveDomain.FirstTolerance()) {
313           IsOnTheImpCurveDomain=Standard_False; 
314         }
315       }
316     }
317     if(IsOnTheImpCurveDomain && TheImpCurveDomain.HasLastPoint()) {
318       if(param1>TheImpCurveDomain.LastParameter()) {
319         if(Pt.Distance(TheImpCurveDomain.LastPoint()) 
320            > TheImpCurveDomain.FirstTolerance()) {
321           IsOnTheImpCurveDomain=Standard_False; 
322         }
323       }
324     }
325     
326     if(IsOnTheImpCurveDomain) {
327       TheImpTool.D2(param1,pt1,Tan1,Norm1);
328       ParTool::D2(TheParCurve,param2,pt2,Tan2,Norm2);
329       
330       IntImpParGen::DeterminePosition(Pos1,TheImpCurveDomain,pt1,param1);
331       IntImpParGen::DeterminePosition(Pos2,TheParCurveDomain,pt2,param2);
332       
333       if(Pos1==IntRes2d_End)  EndOnImp  = Standard_True;
334       else if(Pos1==IntRes2d_Head) HeadOnImp = Standard_True;
335       if(Pos2==IntRes2d_End)  EndOnPar  = Standard_True;
336       else if(Pos2==IntRes2d_Head) HeadOnPar = Standard_True;
337
338       IntImpParGen::DetermineTransition(Pos1,Tan1,Norm1,Trans1,
339                            Pos2,Tan2,Norm2,Trans2,
340                            Tolerance_Angulaire);
341
342       IntRes2d_IntersectionPoint IP(pt1,param1,param2
343                                     ,Trans1,Trans2
344                                     ,ReversedParameters());
345       Insert(IP);
346     }
347   } 
348   //-- F i n   d u   T r a i t e m e n t   d e s   P t s   S o l.
349
350
351   //--------------------------------------------------------------------
352   //--        T r a i t e m e n t   D e s   S e g m e n t s          ---
353   //--------------------------------------------------------------------
354   //--  On a N segments solution sur le domaine de V    soit au pire :
355   //--    --> N segments solution sur le domaine de U 
356   //--    -->2N segments si la courbe en U est fermee
357   //--   
358
359   TColStd_Array1OfReal Inter2_and_Domaine2(1,2+8*nb_segments_solution);
360   TColStd_Array1OfReal Inter1(1,2+8*nb_segments_solution);
361
362   Standard_Integer nb_segments_crees=0;
363
364   for (Standard_Integer j2=1,j=1;j<=nb_segments_solution;j++,j2+=2) {
365     Standard_Real param2_inf,param2_sup;
366     Standard_Real param1_inf,param1_sup;
367     gp_Pnt2d Ptemp;
368     
369     Sol.GetInterval(j,param2_inf,param2_sup);
370     param1_inf=FindU(param2_inf,Ptemp,TheParCurve,TheImpTool);
371     param1_sup=FindU(param2_sup,Ptemp,TheParCurve,TheImpTool);    
372
373     //----------------------------------------------------------------------
374     //--         C o u r b e    I m p l i c i t e    F e r m e e 
375
376     if(TheImpCurveDomain.IsClosed()) {
377
378       gp_Pnt2d Ptemp;
379       gp_Vec2d T1,T2,N1,N2;
380       Standard_Real param1_origine,param1_fin;
381
382       TheImpCurveDomain.EquivalentParameters(param1_origine,param1_fin);
383       Standard_Real Periode=param1_fin-param1_origine;
384
385       while(param1_inf<param1_origine) { param1_inf+=Periode; }
386       while(param1_sup<param1_origine) { param1_sup+=Periode; }      
387
388       ParTool::D2(TheParCurve,param2_inf,Ptemp,T2,N2);
389       TheImpTool.D2(param1_inf,Ptemp,T1,N1);
390       if(T1.Magnitude()<=gp::Resolution()) T1=N1;
391       if(T2.Magnitude()<=gp::Resolution()) T2=N2;
392
393       if(T1.Dot(T2) >=0.0) {
394         //---  param1_inf designe un point entrant (et T1 est vers la matiere)
395         if(param1_inf>=param1_sup) {    param1_sup+=Periode;    }
396       }
397       else { //---  param1_inf : point sortant (et T1 est Hors matiere)
398         if(param1_inf<=param1_sup) {    param1_inf+=Periode;     }
399       }
400       //--- On cree un nouveau segment decale de Periode
401       //--  Exemple de Pb : Domaine PI/4  PI/2   et intervalle 0,PI
402       //--                  Domaine 1.5PI 2.5PI  et intervalle 0,PI
403       //--        -2pi                  0                2pi     
404       //--   ------|--------------------|-----------------|-----------
405       //--            [----------------------------]               Domaine
406       //--                                   [~~~~~~~~~~~~~~~~~]   Inters.
407       //--
408       //--  On cree un nouvel intervalle 
409       //--   interv decale
410       //--  [a~~~~~~~~~~~~b]                 [a~~~~~~~~~~~~~~~b]  et  [a~~~]
411       //--
412       //
413
414       if(TheImpCurveDomain.LastParameter() 
415          > ((param1_inf>param1_sup)? (param1_sup+Periode): 
416                                       (param1_inf+Periode))) {
417         Inter2_and_Domaine2.SetValue(j2,param2_inf);
418         Inter1.SetValue(j2,param1_inf+Periode);
419       
420         Inter2_and_Domaine2.SetValue(j2+1,param2_sup);
421         Inter1.SetValue(j2+1,param1_sup+Periode);     
422         j2+=2;
423         nb_segments_crees++;
424       }
425                                                                        
426       if(TheImpCurveDomain.FirstParameter() 
427          <((param1_inf<param1_sup)? (param1_sup-Periode): (param1_inf-Periode))) {
428         Inter2_and_Domaine2.SetValue(j2,param2_inf);
429         Inter1.SetValue(j2,param1_inf-Periode);
430         
431         Inter2_and_Domaine2.SetValue(j2+1,param2_sup);
432         Inter1.SetValue(j2+1,param1_sup-Periode);     
433         j2+=2;
434         nb_segments_crees++;
435       }
436     }
437     //--   F i n     C o u r b e    I m p l i c i t e    F e r m e e 
438     //----------------------------------------------------------------------
439
440
441     Inter2_and_Domaine2.SetValue(j2,param2_inf);
442     Inter1.SetValue(j2,param1_inf);
443     
444     Inter2_and_Domaine2.SetValue(j2+1,param2_sup);
445     Inter1.SetValue(j2+1,param1_sup);
446   } 
447   
448   //------------------------------------------------------------------
449   //--  INTER2_DOMAINE2 : Intersection AND CurveDomain : Function of PARAM2
450   //--    INTER1        : Intersection AND CurveDomain : Function of PARAM1
451   //------------------------------------------------------------------  
452   //--
453   TColStd_Array1OfReal Resultat1(1,2+(1+nb_segments_solution)*2);
454   TColStd_Array1OfReal Resultat2(1,2+(1+nb_segments_solution)*2);
455   nb_segments_solution+=nb_segments_crees;
456   Standard_Integer NbResultats=nb_segments_solution*2;
457
458   And_Domaine_Objet1_Intersections(TheImpTool,
459                                    TheParCurve,
460                                    TheImpCurveDomain,
461                                    TheParCurveDomain,
462                                    NbResultats,
463                                    Inter2_and_Domaine2,Inter1,
464                                    Resultat1,Resultat2,EpsNul);
465
466   //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
467   //Calcule_Toutes_Transitions(NbResultats,
468   //                         Resultat1,Resultat2,
469   //                         TheImpTool,
470   //                         TheImpCurveDomain,
471   //                         TheParCurve,
472   //                         TheParCurveDomain); 
473   //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
474   //~~~ Fonction Calcule_Toutes_Transitions Repportee ici pour cause ~~~~~
475   //~~~~~       D acces aux methodes Protected APPEND
476   //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
477   {
478     IntRes2d_Position Pos1,Pos2;
479     IntRes2d_Transition Trans1,Trans2;
480     gp_Vec2d Tan1,Tan2,Norm1,Norm2;
481     gp_Pnt2d Pt1_on1,Pt2_on1,Pt1_on2,Pt2_on2;
482     Standard_Real Param1_on1,Param2_on1,Param1_on2,Param2_on2;
483     
484     Standard_Real Dist_Mini_ImpCurve=EPSNUL;
485     Standard_Real Tolerance_Angulaire=Dist_Mini_ImpCurve; 
486     
487     
488     for(Standard_Integer i=1; i<=NbResultats ; i+=2) {
489       Standard_Integer ip1=i+1;
490       Standard_Boolean OnlyOnePoint=Standard_False;
491       
492       Param1_on1=Resultat1.Value(i);
493       Param1_on2=Resultat2.Value(i);
494       Param2_on1=Resultat1.Value(ip1);
495       Param2_on2=Resultat2.Value(ip1);
496
497       Pt1_on1=TheImpTool.Value(Param1_on1);
498       Pt2_on1=TheImpTool.Value(Param2_on1);
499       Pt1_on2=ParTool::Value(TheParCurve,Param1_on2);
500       Pt2_on2=ParTool::Value(TheParCurve,Param2_on2);
501       
502       if(!TheImpCurveDomain.IsClosed()) { 
503         if( Pt1_on1.Distance(Pt2_on1) <= Dist_Mini_ImpCurve ) {
504           if( Pt1_on2.Distance(Pt2_on2) <= Dist_Mini_ImpCurve ) {
505             OnlyOnePoint=Standard_True;
506           }
507         }
508       }  
509
510       Param1_on1=IntImpParGen::NormalizeOnDomain(Param1_on1,TheImpCurveDomain);
511       Param1_on2=IntImpParGen::NormalizeOnDomain(Param1_on2,TheParCurveDomain);
512
513       TheImpTool.D2(Param1_on1,Pt1_on1,Tan1,Norm1);
514       ParTool::D2(TheParCurve,Param1_on2,Pt1_on2,Tan2,Norm2);
515       
516       IntImpParGen::DeterminePosition(Pos1,TheImpCurveDomain,Pt1_on1,Param1_on1);
517       IntImpParGen::DeterminePosition(Pos2,TheParCurveDomain,Pt1_on2,Param1_on2);
518
519       if(Pos1==IntRes2d_End)  EndOnImp  = Standard_True;
520       else if(Pos1==IntRes2d_Head) HeadOnImp = Standard_True;
521       if(Pos2==IntRes2d_End)  EndOnPar  = Standard_True;
522       else if(Pos2==IntRes2d_Head) HeadOnPar = Standard_True;
523       
524
525       IntImpParGen::DetermineTransition(Pos1,Tan1,Norm1,Trans1,
526                            Pos2,Tan2,Norm2,Trans2,
527                            Tolerance_Angulaire);
528       
529       //============== Detection du cas : L intersection est en bout
530       //==============  sur les 2 domaines
531       
532       if(Pos1!=IntRes2d_Middle && Pos2!=IntRes2d_Middle) {
533         Standard_Real m=0.5*(Pt1_on1.X() + Pt1_on2.X());
534         Pt1_on1.SetX(m);
535         m=0.5*(Pt1_on1.Y() + Pt1_on2.Y());
536         Pt1_on1.SetY(m);
537       }
538
539       IntRes2d_IntersectionPoint new_p1(Pt1_on1
540                                         ,Param1_on1,Param1_on2
541                                         ,Trans1,Trans2
542                                         ,ReversedParameters());
543       if(!OnlyOnePoint) {
544         IntRes2d_IntersectionPoint new_p2;
545
546         Param2_on1=IntImpParGen::NormalizeOnDomain(Param2_on1,TheImpCurveDomain);
547         Param2_on2=IntImpParGen::NormalizeOnDomain(Param2_on2,TheParCurveDomain);
548
549         TheImpTool.D2(Param2_on1,Pt2_on1,Tan1,Norm1);
550         ParTool::D2(TheParCurve,Param2_on2,Pt2_on2,Tan2,Norm2);
551         
552         IntImpParGen::DeterminePosition(Pos1,TheImpCurveDomain,Pt2_on1,Param2_on1);
553         IntImpParGen::DeterminePosition(Pos2,TheParCurveDomain,Pt2_on2,Param2_on2);
554         
555         if(Pos1==IntRes2d_End)  EndOnImp  = Standard_True;
556         else if(Pos1==IntRes2d_Head) HeadOnImp = Standard_True;
557         if(Pos2==IntRes2d_End)  EndOnPar  = Standard_True;
558         else if(Pos2==IntRes2d_Head) HeadOnPar = Standard_True;
559
560         IntImpParGen::DetermineTransition(Pos1,Tan1,Norm1,Trans1,
561                                           Pos2,Tan2,Norm2,Trans2,
562                                           Tolerance_Angulaire);
563         
564         
565         //============== Detection du cas : L intersection est en bout
566         //==============  sur les 2 domaines 
567         
568         if(Pos1!=IntRes2d_Middle && Pos2!=IntRes2d_Middle) {
569           Standard_Real m=0.5*(Pt2_on1.X() + Pt2_on2.X() );
570           Pt2_on1.SetX(m);
571           m=0.5*(Pt2_on1.Y() + Pt2_on2.Y());
572           Pt2_on1.SetY(m);
573         }
574
575         new_p2.SetValues(Pt2_on1,Param2_on1,Param2_on2
576                          ,Trans1,Trans2
577                          ,ReversedParameters());
578
579         Standard_Boolean segopposite=((Tan1.Dot(Tan2) < 0.0)? 
580                                       Standard_True : Standard_False);
581         
582         IntRes2d_IntersectionSegment new_seg(new_p1,new_p2
583                                              ,segopposite
584                                              ,ReversedParameters());
585         Append(new_seg);
586       }
587       else {
588         Insert(new_p1); 
589       }
590     }
591   } //~~~~~~~~~~~~  Fin du corps de la fonction Calc...Transitions~~~~~~~~~~
592   
593   //-------------------------------------------
594   //-- On teste les points en bouts solutions
595   //-- 
596   if(!HeadOnImp && TheImpCurveDomain.HasFirstPoint()) { 
597     if(!HeadOnPar) { 
598       if(TheImpCurveDomain.FirstPoint().Distance(TheParCurveDomain.FirstPoint()) 
599          <= Max(TheImpCurveDomain.FirstTolerance(),TheParCurveDomain.FirstTolerance())) { 
600         param1 = TheImpCurveDomain.FirstParameter();
601         param2 = TheParCurveDomain.FirstParameter();
602         TheImpTool.D2(param1,pt1,Tan1,Norm1);
603         ParTool::D2(TheParCurve,param2,pt2,Tan2,Norm2);
604         IntImpParGen::DetermineTransition(IntRes2d_Head,Tan1,Norm1,Trans1,
605                                           IntRes2d_Head,Tan2,Norm2,Trans2,
606                                           Tolerance_Angulaire);
607         IntRes2d_IntersectionPoint IP(TheImpCurveDomain.FirstPoint(),
608                                       param1,param2,
609                                       Trans1,Trans2,
610                                       ReversedParameters());
611         Insert(IP);
612       }
613     }
614     if(!EndOnPar) { 
615       if(TheImpCurveDomain.FirstPoint().Distance(TheParCurveDomain.LastPoint()) 
616          <= Max(TheImpCurveDomain.FirstTolerance(),TheParCurveDomain.LastTolerance())) { 
617         param1 = TheImpCurveDomain.FirstParameter();
618         param2 = TheParCurveDomain.LastParameter();
619         TheImpTool.D2(param1,pt1,Tan1,Norm1);
620         ParTool::D2(TheParCurve,param2,pt2,Tan2,Norm2);
621         IntImpParGen::DetermineTransition(IntRes2d_Head,Tan1,Norm1,Trans1,
622                                           IntRes2d_End ,Tan2,Norm2,Trans2,
623                                           Tolerance_Angulaire);
624         IntRes2d_IntersectionPoint IP(TheImpCurveDomain.FirstPoint(),
625                                       param1,param2,
626                                       Trans1,Trans2,
627                                       ReversedParameters());
628         Insert(IP);
629       }
630     }
631   }
632   
633   if(!EndOnImp && TheImpCurveDomain.HasLastPoint()) { 
634     if(!HeadOnPar) { 
635       if(TheImpCurveDomain.LastPoint().Distance(TheParCurveDomain.FirstPoint()) 
636          <= Max(TheImpCurveDomain.LastTolerance(),TheParCurveDomain.FirstTolerance())) {
637         param1 = TheImpCurveDomain.LastParameter();
638         param2 = TheParCurveDomain.FirstParameter();
639         TheImpTool.D2(param1,pt1,Tan1,Norm1);
640         ParTool::D2(TheParCurve,param2,pt2,Tan2,Norm2);
641         IntImpParGen::DetermineTransition(IntRes2d_End,Tan1,Norm1,Trans1,
642                                           IntRes2d_Head,Tan2,Norm2,Trans2,
643                                           Tolerance_Angulaire);
644         IntRes2d_IntersectionPoint IP(TheImpCurveDomain.LastPoint(),
645                                       param1,param2,
646                                       Trans1,Trans2,
647                                       ReversedParameters());
648         Insert(IP);
649       }
650     }
651     if(!EndOnPar) { 
652       if(TheImpCurveDomain.LastPoint().Distance(TheParCurveDomain.LastPoint()) 
653          <= Max(TheImpCurveDomain.LastTolerance(),TheParCurveDomain.LastTolerance())) {
654         param1 = TheImpCurveDomain.LastParameter();
655         param2 = TheParCurveDomain.LastParameter();
656         TheImpTool.D2(param1,pt1,Tan1,Norm1);
657         ParTool::D2(TheParCurve,param2,pt2,Tan2,Norm2);
658         IntImpParGen::DetermineTransition(IntRes2d_End,Tan1,Norm1,Trans1,
659                                           IntRes2d_End,Tan2,Norm2,Trans2,
660                                           Tolerance_Angulaire);
661         IntRes2d_IntersectionPoint IP(TheImpCurveDomain.LastPoint(),
662                                       param1,param2,
663                                       Trans1,Trans2,
664                                       ReversedParameters());
665         Insert(IP);
666       }
667     }
668   }
669   done=Standard_True; 
670 }
671
672
673
674
675
676
677 Standard_Real IntImpParGen_Intersector::FindU(const Standard_Real parameter
678                                               ,gp_Pnt2d& point
679                                               ,const ParCurve& TheParCurve
680                                               ,const ImpTool& TheImpTool) const 
681 {
682   point=ParTool::Value(TheParCurve,parameter);
683   return(TheImpTool.FindParameter(point));
684 }
685
686 Standard_Real IntImpParGen_Intersector::FindV(const Standard_Real parameter
687                   ,gp_Pnt2d& point
688                   ,const ImpTool& TheImpTool
689                   ,const ParCurve& TheParCurve
690                   ,const IntRes2d_Domain& TheParCurveDomain
691                   ,const Standard_Real V0
692                   ,const Standard_Real V1
693                   ,const Standard_Real Tolerance) const 
694 {
695   point=TheImpTool.Value(parameter);
696   if(TheParCurveDomain.IsClosed()) {
697     Standard_Real V = ProjectOnPCurveTool::FindParameter(TheParCurve,
698                                                          point,
699                                                          Tolerance);
700     return(IntImpParGen::NormalizeOnDomain(V,TheParCurveDomain));
701   }
702   else {
703     Standard_Real VV0 = V0;
704     Standard_Real VV1 = V1;
705     if(V1<V0) { VV0 = V1; VV1 = V0; } 
706     //-- ??????????????????????????????????????????????????????????????????????
707     //-- Modif le 15 Septembre 1992 : On Teste le parametre retourne 
708     //--??????????????????????????????????????????????????????????????????????
709     Standard_Real X = ProjectOnPCurveTool::FindParameter(TheParCurve,
710                                                          point,
711                                                          VV0,VV1,Tolerance);
712     if(X>VV1) X=VV1; else if(X<VV0) X=VV0;
713     return(X);
714   }
715 }