Integration of OCCT 6.5.0 from SVN
[occt.git] / src / ChFi3d / ChFi3d.cxx
1 // File:        ChFi3d.cxx
2 // Created:     Tue Dec 21 16:19:36 1993
3 // Author:      Isabelle GRIGNON
4 //              <isg@sdsun2>
5
6
7 #include <ChFi3d.ixx>
8 #include <ChFi3d_Builder_0.hxx>
9 #include <BRepAdaptor_Surface.hxx>
10 #include <BRepAdaptor_Curve2d.hxx>
11 #include <BRepAdaptor_Curve.hxx>
12 #include <BRep_Tool.hxx>
13
14 #include <gp_Pnt.hxx>
15 #include <gp_Vec.hxx>
16 #include <gp_Pnt2d.hxx>
17 #include <gp_Vec2d.hxx>
18 #include <Precision.hxx>
19 #include <TopExp_Explorer.hxx>
20 #include <TopoDS.hxx>
21
22
23 //=======================================================================
24 //function : ConcaveSide
25 //purpose  : calcule le cote concave au voisinage de la frontiere
26 //           de 2 faces.
27 //=======================================================================
28
29 Standard_Integer ChFi3d::ConcaveSide(const BRepAdaptor_Surface& S1, 
30                                      const BRepAdaptor_Surface& S2, 
31                                      const TopoDS_Edge& E, 
32                                      TopAbs_Orientation& Or1, 
33                                      TopAbs_Orientation& Or2)
34
35 {
36   Standard_Integer ChoixConge;
37   Or1 = Or2 = TopAbs_FORWARD;
38   BRepAdaptor_Curve CE(E);
39   Standard_Real first = CE.FirstParameter();
40   Standard_Real last = CE.LastParameter();
41   Standard_Real par = 0.691254*first + 0.308746*last;
42
43   gp_Pnt pt, pt1, pt2; gp_Vec tgE, tgE1, tgE2, ns1, ns2, dint1, dint2;
44   TopoDS_Face F1 = S1.Face();
45   TopoDS_Face F2 = S2.Face();
46   F1.Orientation(TopAbs_FORWARD);
47   F2.Orientation(TopAbs_FORWARD);
48   
49   CE.D1(par,pt,tgE);
50   tgE.Normalize();
51   tgE2 = tgE1 = tgE;
52   if(E.Orientation() == TopAbs_REVERSED) tgE.Reverse();
53
54   TopoDS_Edge E1 = E, E2 = E;
55   E1.Orientation(TopAbs_FORWARD);
56   E2.Orientation(TopAbs_FORWARD);
57
58   if(F1.IsSame(F2) && BRep_Tool::IsClosed(E,F1)) {
59     E2.Orientation(TopAbs_REVERSED);
60     tgE2.Reverse();
61   }
62   else {
63     TopExp_Explorer Exp;
64     Standard_Boolean found = 0;
65     for (Exp.Init(F1,TopAbs_EDGE); 
66          Exp.More() && !found; 
67          Exp.Next()) {
68       if (E.IsSame(TopoDS::Edge(Exp.Current()))){
69         if(Exp.Current().Orientation() == TopAbs_REVERSED) tgE1.Reverse();
70         found = Standard_True;
71       }
72     }
73     if (!found) { return 0; }
74     found = 0;
75     for (Exp.Init(F2,TopAbs_EDGE); 
76          Exp.More() && !found; 
77          Exp.Next()) {
78       if (E.IsSame(TopoDS::Edge(Exp.Current()))){
79         if(Exp.Current().Orientation() == TopAbs_REVERSED) tgE2.Reverse();
80         found = Standard_True;
81       }
82     }
83     if (!found) { return 0; }
84   }
85   BRepAdaptor_Curve2d pc1(E1,F1);
86   BRepAdaptor_Curve2d pc2(E2,F2);
87   gp_Pnt2d p2d1,p2d2;
88   gp_Vec DU1,DV1,DU2,DV2;
89   p2d1 = pc1.Value(par);
90   p2d2 = pc2.Value(par);
91   S1.D1(p2d1.X(),p2d1.Y(),pt1,DU1,DV1);
92   ns1 = DU1.Crossed(DV1);
93   ns1.Normalize();
94   S2.D1(p2d2.X(),p2d2.Y(),pt2,DU2,DV2);
95   ns2 = DU2.Crossed(DV2);
96   ns2.Normalize();
97
98   dint1 = ns1.Crossed(tgE1);
99   dint2 = ns2.Crossed(tgE2);
100   Standard_Real ang = ns1.CrossMagnitude(ns2);
101   if(ang > 0.0001*PI){
102     Standard_Real scal = ns2.Dot(dint1);
103     if ( scal <= 0. ){
104       ns2.Reverse();
105       Or2 = TopAbs_REVERSED; 
106     }
107     scal = ns1.Dot(dint2);
108     if ( scal <= 0. ){
109       ns1.Reverse();
110       Or1 = TopAbs_REVERSED; 
111     }
112   }
113   else { 
114     //les faces sont localement tangentes on bidouille!!
115     if(dint1.Dot(dint2) < 0.){
116       //ici c'est une regularite oubliee
117       gp_Vec DDU, DDV, DDUV;
118       S1.D2(p2d1.X(),p2d1.Y(),pt1,DU1,DV1,DDU,DDV,DDUV);
119       DU1 += ( DU1 * dint1 < 0) ? -DDU : DDU;
120       DV1 += ( DV1 * dint1 < 0) ? -DDV : DDV;
121       ns1 = DU1.Crossed(DV1);
122       ns1.Normalize();
123       S2.D2(p2d2.X(),p2d2.Y(),pt2,DU2,DV2,DDU,DDV,DDUV);
124       DU2 += ( DU2 * dint2 < 0) ? -DDU : DDU;
125       DV2 += ( DV2 * dint2 < 0) ? -DDV : DDV;
126       ns2 = DU2.Crossed(DV2);
127       ns2.Normalize();
128       
129       dint1 = ns1.Crossed(tgE1);
130       dint2 = ns2.Crossed(tgE2);
131       ang = ns1.CrossMagnitude(ns2);
132       if(ang > 0.0001*PI){
133         Standard_Real scal = ns2.Dot(dint1);
134         if ( scal <= 0. ){
135           ns2.Reverse();
136           Or2 = TopAbs_REVERSED; 
137         }
138         scal = ns1.Dot(dint2);
139         if ( scal <= 0. ){
140           ns1.Reverse();
141           Or1 = TopAbs_REVERSED; 
142         }
143       }
144       else {
145 #ifdef DEB
146         cout<<"ConcaveSide : pas de cote concave"<<endl;
147 #endif
148         //ce 10 montre que la face en bout est dans le prolongement de l'une des deux faces d'appui
149         return 10;
150       }
151     }
152     else {
153       //ici ca rebrousse, on prend des points dans les faces
154       //ni trop pres ni trop loin, comme on peut.
155       Standard_Real u,v;
156 #ifdef DEB
157 //      Standard_Real deport = 1000*BRep_Tool::Tolerance(E);
158 #endif
159       ChFi3d_Coefficient(dint1,DU1,DV1,u,v);
160       p2d1.SetX(p2d1.X() + u); p2d1.SetY(p2d1.Y() + v);
161       ChFi3d_Coefficient(dint1,DU2,DV2,u,v);
162       p2d2.SetX(p2d2.X() + u); p2d2.SetY(p2d2.Y() + v);
163       S1.D1(p2d1.X(),p2d1.Y(),pt1,DU1,DV1);
164       ns1 = DU1.Crossed(DV1);
165       S2.D1(p2d2.X(),p2d2.Y(),pt2,DU2,DV2);
166       ns2 = DU2.Crossed(DV2);
167       gp_Vec vref(pt1,pt2);
168       if(ns1.Dot(vref) < 0.){
169         Or1 = TopAbs_REVERSED;
170       }
171       if(ns2.Dot(vref) > 0.){
172         Or2 = TopAbs_REVERSED;
173       }
174     }
175   }
176
177
178   if (Or1 == TopAbs_FORWARD) {
179     if (Or2 == TopAbs_FORWARD) ChoixConge = 1;
180     else ChoixConge = 7;
181   }
182   else {
183     if (Or2 == TopAbs_FORWARD) ChoixConge = 3;
184     else ChoixConge = 5;
185   }
186   if ((ns1.Crossed(ns2)).Dot(tgE) >= 0.) ChoixConge++ ;
187   return ChoixConge;
188 }
189
190 //=======================================================================
191 //function : NextSide
192 //purpose  : 
193 //           
194 //=======================================================================
195
196 Standard_Integer  ChFi3d::NextSide(TopAbs_Orientation& Or1, 
197                                    TopAbs_Orientation& Or2,
198                                    const TopAbs_Orientation OrSave1, 
199                                    const TopAbs_Orientation OrSave2,
200                                    const Standard_Integer ChoixSave)
201 {
202   if (Or1 == TopAbs_FORWARD){Or1 = OrSave1;}
203   else {
204     Or1 = TopAbs::Reverse(OrSave1);
205   }
206   if (Or2 == TopAbs_FORWARD){Or2 = OrSave2;}
207   else {
208     Or2 = TopAbs::Reverse(OrSave2);
209   }
210
211   Standard_Integer ChoixConge;
212   if (Or1 == TopAbs_FORWARD) {
213     if (Or2 == TopAbs_FORWARD) ChoixConge = 1;
214     else {
215       if(ChoixSave < 0) ChoixConge = 3;
216       else ChoixConge = 7;
217     }
218   }
219   else {
220     if (Or2 == TopAbs_FORWARD) {
221       if(ChoixSave < 0) ChoixConge = 7;
222       else ChoixConge = 3;
223     }
224     else ChoixConge = 5;
225   }
226   if (Abs(ChoixSave)%2 == 0) ChoixConge++;
227   return ChoixConge;
228 }
229
230
231 //=======================================================================
232 //function : NextSide
233 //purpose  : 
234 //           
235 //=======================================================================
236
237 void ChFi3d::NextSide(TopAbs_Orientation& Or, 
238                      const TopAbs_Orientation OrSave, 
239                      const TopAbs_Orientation OrFace) 
240 {
241   if (Or == OrFace){Or = OrSave;}
242   else {
243     Or = TopAbs::Reverse(OrSave);
244   }
245 }
246
247
248
249 //=======================================================================
250 //function : SameSide
251 //purpose  : 
252 //           
253 //=======================================================================
254
255 Standard_Boolean  ChFi3d::SameSide(const TopAbs_Orientation Or, 
256                                    const TopAbs_Orientation OrSave1, 
257                                    const TopAbs_Orientation OrSave2,
258                                    const TopAbs_Orientation OrFace1, 
259                                    const TopAbs_Orientation OrFace2)
260 {
261   TopAbs_Orientation o1,o2;
262   if (Or == OrFace1){o1 = OrSave1;}
263   else {
264     o1 = TopAbs::Reverse(OrSave1);
265   }
266   if (Or == OrFace2){o2 = OrSave2;}
267   else {
268     o2 = TopAbs::Reverse(OrSave2);
269   }
270   return (o1 == o2);
271 }