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