417d1c8e234632c96dbd5ba1e4f7763621b7abb9
[occt.git] / src / IntImpParGen / IntImpParGen_Tool.cxx
1 // Created on: 1992-06-10
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 <IntImpParGen_Tool.hxx>
18 #include <gp.hxx>
19
20
21 #define TOLERANCE_ANGULAIRE 0.00000001
22
23 //----------------------------------------------------------------------
24 Standard_Real NormalizeOnDomain(Standard_Real& Param,const IntRes2d_Domain& TheDomain) {
25   Standard_Real modParam = Param;
26   if(TheDomain.IsClosed()) {
27     Standard_Real Periode,t;
28     TheDomain.EquivalentParameters(t,Periode);
29     Periode-=t;
30     if(TheDomain.HasFirstPoint()) {
31       while(modParam<TheDomain.FirstParameter()) {
32         modParam+=Periode;
33       }
34     }
35     if(TheDomain.HasLastPoint()) {
36       if(modParam>TheDomain.LastParameter()) {
37         modParam-=Periode;
38       }
39     }
40   }
41   return(modParam);
42 }
43 //----------------------------------------------------------------------
44 void Determine_Position(IntRes2d_Position& Pos1,
45                         const IntRes2d_Domain& TheDomain,
46                         const gp_Pnt2d& Pnt1,
47                         const Standard_Real Param1) {
48   
49   Pos1=IntRes2d_Middle;
50
51   if(TheDomain.HasFirstPoint()) { 
52     if(Pnt1.Distance(TheDomain.FirstPoint()) 
53        <= TheDomain.FirstTolerance()) {
54       Pos1=IntRes2d_Head;       
55     }
56   }
57    
58   if(TheDomain.HasLastPoint()) {
59     if(Pnt1.Distance(TheDomain.LastPoint()) 
60        <= TheDomain.LastTolerance()) {
61       if(Pos1==IntRes2d_Head) {
62         if(Abs(Param1-TheDomain.LastParameter())
63            < Abs(Param1-TheDomain.FirstParameter()))
64           Pos1=IntRes2d_End;    
65       }
66       else {
67         Pos1=IntRes2d_End; 
68       }
69     } 
70   }
71 }   
72 //----------------------------------------------------------------------
73 void Determine_Transition(const IntRes2d_Position    Pos1,
74                           gp_Vec2d&                  Tan1,
75                           const gp_Vec2d&            Norm1,
76                           IntRes2d_Transition&       T1,
77                           const IntRes2d_Position    Pos2,
78                           gp_Vec2d&                  Tan2,
79                           const gp_Vec2d&            Norm2,
80                           IntRes2d_Transition&       T2,
81 //                        const Standard_Real        Tolerance_Angulaire) {
82                           const Standard_Real        ) {
83   
84   Standard_Boolean courbure1=Standard_True;
85   Standard_Boolean courbure2=Standard_True;
86   Standard_Boolean decide=Standard_True;
87   if (Tan1.Magnitude()<=gp::Resolution()) {
88     Tan1=Norm1;
89     courbure1=Standard_False;
90     if (Tan1.Magnitude()<=gp::Resolution()) {    // transition undecided
91       decide=Standard_False;
92     }
93   }
94   
95   if (Tan2.Magnitude()<=gp::Resolution()) {
96     Tan2=Norm2;
97     courbure2=Standard_False;
98     if (Tan2.Magnitude()<=gp::Resolution()) {    // transition undecided
99       decide=Standard_False;
100     }
101   }
102   
103   if (!decide) {
104     T1.SetValue(Pos1);
105     T2.SetValue(Pos2);
106   }
107   else {
108     Standard_Real sgn=Tan1.Crossed(Tan2);
109     Standard_Real norm=Tan1.Magnitude()*Tan2.Magnitude();
110
111     if (Abs(sgn)<=TOLERANCE_ANGULAIRE*norm) {   // Transition TOUCH #########
112       Standard_Boolean opos=(Tan1.Dot(Tan2))<0;
113       if (!(courbure1||courbure2)) {
114         T1.SetValue(Standard_True,Pos1,IntRes2d_Unknown,opos);
115         T2.SetValue(Standard_True,Pos2,IntRes2d_Unknown,opos);
116       }
117       else {
118         gp_Vec2d Norm;
119         Tan1.Normalized();
120         Norm.SetCoord(-Tan1.Y(),Tan1.X());
121         Standard_Real Val1,Val2;
122         if (!courbure1) {
123           Val1=0.0;
124         }
125         else {
126           Val1=Norm.Dot(Norm1);
127         }
128         if (!courbure2) {
129           Val2=0.0;
130         }
131         else {
132           Val2=Norm.Dot(Norm2);
133         }
134         
135         if (Abs(Val1-Val2) <= gp::Resolution()) {
136           T1.SetValue(Standard_True,Pos1,IntRes2d_Unknown,opos);
137           T2.SetValue(Standard_True,Pos2,IntRes2d_Unknown,opos);
138         }
139         else if (Val2 > Val1) {
140           T2.SetValue(Standard_True,Pos2,IntRes2d_Inside,opos);
141           if (opos) {
142             T1.SetValue(Standard_True,Pos1,IntRes2d_Inside,opos);
143           }
144           else {
145             T1.SetValue(Standard_True,Pos1,IntRes2d_Outside,opos);
146           }
147         }
148         else {         // Val1 > Val2
149           T2.SetValue(Standard_True,Pos2,IntRes2d_Outside,opos);
150           if (opos) {
151             T1.SetValue(Standard_True,Pos1,IntRes2d_Outside,opos);
152           }
153           else {
154             T1.SetValue(Standard_True,Pos1,IntRes2d_Inside,opos);
155           }
156         }
157       }
158     }
159     else if (sgn<0) {
160       T1.SetValue(Standard_False,Pos1,IntRes2d_In);
161       T2.SetValue(Standard_False,Pos2,IntRes2d_Out);
162     }
163     else {     // sgn>0
164       T1.SetValue(Standard_False,Pos1,IntRes2d_Out);
165       T2.SetValue(Standard_False,Pos2,IntRes2d_In);
166     }
167   }
168 }
169