66b4f30567c241abf5580fcbf2f5216d8521ad54
[occt.git] / src / ChFi3d / ChFi3d.cxx
1 // Created on: 1993-12-21
2 // Created by: Isabelle GRIGNON
3 // Copyright (c) 1993-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
18 #include <BRep_Tool.hxx>
19 #include <BRepAdaptor_Curve.hxx>
20 #include <BRepAdaptor_Curve2d.hxx>
21 #include <BRepAdaptor_Surface.hxx>
22 #include <ChFi3d.hxx>
23 #include <ChFi3d_Builder_0.hxx>
24 #include <gp_Pnt.hxx>
25 #include <gp_Pnt2d.hxx>
26 #include <gp_Vec.hxx>
27 #include <gp_Vec2d.hxx>
28 #include <Precision.hxx>
29 #include <TopExp_Explorer.hxx>
30 #include <TopoDS.hxx>
31 #include <TopoDS_Edge.hxx>
32
33 //=======================================================================
34 //function : ConcaveSide
35 //purpose  : calculate the concave face at the neighborhood of the border of
36 //           2 faces.
37 //=======================================================================
38 Standard_Integer ChFi3d::ConcaveSide(const BRepAdaptor_Surface& S1, 
39                                      const BRepAdaptor_Surface& S2, 
40                                      const TopoDS_Edge& E, 
41                                      TopAbs_Orientation& Or1, 
42                                      TopAbs_Orientation& Or2)
43
44 {
45   Standard_Integer ChoixConge;
46   Or1 = Or2 = TopAbs_FORWARD;
47   BRepAdaptor_Curve CE(E);
48   Standard_Real first = CE.FirstParameter();
49   Standard_Real last = CE.LastParameter();
50   Standard_Real par = 0.691254*first + 0.308746*last;
51
52   gp_Pnt pt, pt1, pt2; gp_Vec tgE, tgE1, tgE2, ns1, ns2, dint1, dint2;
53   TopoDS_Face F1 = S1.Face();
54   TopoDS_Face F2 = S2.Face();
55   F1.Orientation(TopAbs_FORWARD);
56   F2.Orientation(TopAbs_FORWARD);
57   
58   CE.D1(par,pt,tgE);
59   tgE.Normalize();
60   tgE2 = tgE1 = tgE;
61   if(E.Orientation() == TopAbs_REVERSED) tgE.Reverse();
62
63   TopoDS_Edge E1 = E, E2 = E;
64   E1.Orientation(TopAbs_FORWARD);
65   E2.Orientation(TopAbs_FORWARD);
66
67   if(F1.IsSame(F2) && BRep_Tool::IsClosed(E,F1)) {
68     E2.Orientation(TopAbs_REVERSED);
69     tgE2.Reverse();
70   }
71   else {
72     TopExp_Explorer Exp;
73     Standard_Boolean found = 0;
74     for (Exp.Init(F1,TopAbs_EDGE); 
75          Exp.More() && !found; 
76          Exp.Next()) {
77       if (E.IsSame(TopoDS::Edge(Exp.Current()))){
78         if(Exp.Current().Orientation() == TopAbs_REVERSED) tgE1.Reverse();
79         found = Standard_True;
80       }
81     }
82     if (!found) { return 0; }
83     found = 0;
84     for (Exp.Init(F2,TopAbs_EDGE); 
85          Exp.More() && !found; 
86          Exp.Next()) {
87       if (E.IsSame(TopoDS::Edge(Exp.Current()))){
88         if(Exp.Current().Orientation() == TopAbs_REVERSED) tgE2.Reverse();
89         found = Standard_True;
90       }
91     }
92     if (!found) { return 0; }
93   }
94   BRepAdaptor_Curve2d pc1(E1,F1);
95   BRepAdaptor_Curve2d pc2(E2,F2);
96   gp_Pnt2d p2d1,p2d2;
97   gp_Vec DU1,DV1,DU2,DV2;
98   p2d1 = pc1.Value(par);
99   p2d2 = pc2.Value(par);
100   S1.D1(p2d1.X(),p2d1.Y(),pt1,DU1,DV1);
101   ns1 = DU1.Crossed(DV1);
102   ns1.Normalize();
103   S2.D1(p2d2.X(),p2d2.Y(),pt2,DU2,DV2);
104   ns2 = DU2.Crossed(DV2);
105   ns2.Normalize();
106
107   dint1 = ns1.Crossed(tgE1);
108   dint2 = ns2.Crossed(tgE2);
109   Standard_Real ang = ns1.CrossMagnitude(ns2);
110   if(ang > 0.0001*M_PI){
111     Standard_Real scal = ns2.Dot(dint1);
112     if ( scal <= 0. ){
113       ns2.Reverse();
114       Or2 = TopAbs_REVERSED; 
115     }
116     scal = ns1.Dot(dint2);
117     if ( scal <= 0. ){
118       ns1.Reverse();
119       Or1 = TopAbs_REVERSED; 
120     }
121   }
122   else { 
123     //the faces are locally tangent - this is fake!
124     if(dint1.Dot(dint2) < 0.){
125       //This is a forgotten regularity
126       gp_Vec DDU, DDV, DDUV;
127       S1.D2(p2d1.X(),p2d1.Y(),pt1,DU1,DV1,DDU,DDV,DDUV);
128       DU1 += ( DU1 * dint1 < 0) ? -DDU : DDU;
129       DV1 += ( DV1 * dint1 < 0) ? -DDV : DDV;
130       ns1 = DU1.Crossed(DV1);
131       ns1.Normalize();
132       S2.D2(p2d2.X(),p2d2.Y(),pt2,DU2,DV2,DDU,DDV,DDUV);
133       DU2 += ( DU2 * dint2 < 0) ? -DDU : DDU;
134       DV2 += ( DV2 * dint2 < 0) ? -DDV : DDV;
135       ns2 = DU2.Crossed(DV2);
136       ns2.Normalize();
137       
138       dint1 = ns1.Crossed(tgE1);
139       dint2 = ns2.Crossed(tgE2);
140       ang = ns1.CrossMagnitude(ns2);
141       if(ang > 0.0001*M_PI){
142         Standard_Real scal = ns2.Dot(dint1);
143         if ( scal <= 0. ){
144           ns2.Reverse();
145           Or2 = TopAbs_REVERSED; 
146         }
147         scal = ns1.Dot(dint2);
148         if ( scal <= 0. ){
149           ns1.Reverse();
150           Or1 = TopAbs_REVERSED; 
151         }
152       }
153       else {
154 #ifdef OCCT_DEBUG
155         cout<<"ConcaveSide : no concave face"<<endl;
156 #endif
157         //This 10 shows that the face at end is in the extension of one of two base faces
158         return 10;
159       }
160     }
161     else {
162       //here it turns back, the points are taken in faces
163       //neither too close nor too far as much as possible.
164       Standard_Real u,v;
165 #ifdef OCCT_DEBUG
166 //      Standard_Real deport = 1000*BRep_Tool::Tolerance(E);
167 #endif
168       ChFi3d_Coefficient(dint1,DU1,DV1,u,v);
169       p2d1.SetX(p2d1.X() + u); p2d1.SetY(p2d1.Y() + v);
170       ChFi3d_Coefficient(dint1,DU2,DV2,u,v);
171       p2d2.SetX(p2d2.X() + u); p2d2.SetY(p2d2.Y() + v);
172       S1.D1(p2d1.X(),p2d1.Y(),pt1,DU1,DV1);
173       ns1 = DU1.Crossed(DV1);
174       S2.D1(p2d2.X(),p2d2.Y(),pt2,DU2,DV2);
175       ns2 = DU2.Crossed(DV2);
176       gp_Vec vref(pt1,pt2);
177       if(ns1.Dot(vref) < 0.){
178         Or1 = TopAbs_REVERSED;
179       }
180       if(ns2.Dot(vref) > 0.){
181         Or2 = TopAbs_REVERSED;
182       }
183     }
184   }
185
186
187   if (Or1 == TopAbs_FORWARD) {
188     if (Or2 == TopAbs_FORWARD) ChoixConge = 1;
189     else ChoixConge = 7;
190   }
191   else {
192     if (Or2 == TopAbs_FORWARD) ChoixConge = 3;
193     else ChoixConge = 5;
194   }
195   if ((ns1.Crossed(ns2)).Dot(tgE) >= 0.) ChoixConge++ ;
196   return ChoixConge;
197 }
198
199 //=======================================================================
200 //function : NextSide
201 //purpose  : 
202 //           
203 //=======================================================================
204
205 Standard_Integer  ChFi3d::NextSide(TopAbs_Orientation& Or1, 
206                                    TopAbs_Orientation& Or2,
207                                    const TopAbs_Orientation OrSave1, 
208                                    const TopAbs_Orientation OrSave2,
209                                    const Standard_Integer ChoixSave)
210 {
211   if (Or1 == TopAbs_FORWARD){Or1 = OrSave1;}
212   else {
213     Or1 = TopAbs::Reverse(OrSave1);
214   }
215   if (Or2 == TopAbs_FORWARD){Or2 = OrSave2;}
216   else {
217     Or2 = TopAbs::Reverse(OrSave2);
218   }
219
220   Standard_Integer ChoixConge;
221   if (Or1 == TopAbs_FORWARD) {
222     if (Or2 == TopAbs_FORWARD) ChoixConge = 1;
223     else {
224       if(ChoixSave < 0) ChoixConge = 3;
225       else ChoixConge = 7;
226     }
227   }
228   else {
229     if (Or2 == TopAbs_FORWARD) {
230       if(ChoixSave < 0) ChoixConge = 7;
231       else ChoixConge = 3;
232     }
233     else ChoixConge = 5;
234   }
235   if (Abs(ChoixSave)%2 == 0) ChoixConge++;
236   return ChoixConge;
237 }
238
239
240 //=======================================================================
241 //function : NextSide
242 //purpose  : 
243 //           
244 //=======================================================================
245
246 void ChFi3d::NextSide(TopAbs_Orientation& Or, 
247                      const TopAbs_Orientation OrSave, 
248                      const TopAbs_Orientation OrFace) 
249 {
250   if (Or == OrFace){Or = OrSave;}
251   else {
252     Or = TopAbs::Reverse(OrSave);
253   }
254 }
255
256
257
258 //=======================================================================
259 //function : SameSide
260 //purpose  : 
261 //           
262 //=======================================================================
263
264 Standard_Boolean  ChFi3d::SameSide(const TopAbs_Orientation Or, 
265                                    const TopAbs_Orientation OrSave1, 
266                                    const TopAbs_Orientation OrSave2,
267                                    const TopAbs_Orientation OrFace1, 
268                                    const TopAbs_Orientation OrFace2)
269 {
270   TopAbs_Orientation o1,o2;
271   if (Or == OrFace1){o1 = OrSave1;}
272   else {
273     o1 = TopAbs::Reverse(OrSave1);
274   }
275   if (Or == OrFace2){o2 = OrSave2;}
276   else {
277     o2 = TopAbs::Reverse(OrSave2);
278   }
279   return (o1 == o2);
280 }