b311480e |
1 | // Created on: 1993-12-21 |
2 | // Created by: Isabelle GRIGNON |
3 | // Copyright (c) 1993-1999 Matra Datavision |
973c2be1 |
4 | // Copyright (c) 1999-2014 OPEN CASCADE SAS |
b311480e |
5 | // |
973c2be1 |
6 | // This file is part of Open CASCADE Technology software library. |
b311480e |
7 | // |
d5f74e42 |
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 |
973c2be1 |
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. |
b311480e |
13 | // |
973c2be1 |
14 | // Alternatively, this file may be used under the terms of Open CASCADE |
15 | // commercial license or contractual agreement. |
7fd59977 |
16 | |
7fd59977 |
17 | |
42cf5bc1 |
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> |
7fd59977 |
24 | #include <gp_Pnt.hxx> |
7fd59977 |
25 | #include <gp_Pnt2d.hxx> |
42cf5bc1 |
26 | #include <gp_Vec.hxx> |
7fd59977 |
27 | #include <gp_Vec2d.hxx> |
28 | #include <Precision.hxx> |
29 | #include <TopExp_Explorer.hxx> |
30 | #include <TopoDS.hxx> |
42cf5bc1 |
31 | #include <TopoDS_Edge.hxx> |
7fd59977 |
32 | |
33 | //======================================================================= |
34 | //function : ConcaveSide |
81bba717 |
35 | //purpose : calculate the concave face at the neighborhood of the border of |
36 | // 2 faces. |
7fd59977 |
37 | //======================================================================= |
7fd59977 |
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(); |
7d92212e |
55 | //F1.Orientation(TopAbs_FORWARD); |
56 | //F2.Orientation(TopAbs_FORWARD); |
7fd59977 |
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(); |
7d92212e |
103 | if (F1.Orientation() == TopAbs_REVERSED) |
104 | ns1.Reverse(); |
7fd59977 |
105 | S2.D1(p2d2.X(),p2d2.Y(),pt2,DU2,DV2); |
106 | ns2 = DU2.Crossed(DV2); |
107 | ns2.Normalize(); |
7d92212e |
108 | if (F2.Orientation() == TopAbs_REVERSED) |
109 | ns2.Reverse(); |
7fd59977 |
110 | |
111 | dint1 = ns1.Crossed(tgE1); |
112 | dint2 = ns2.Crossed(tgE2); |
113 | Standard_Real ang = ns1.CrossMagnitude(ns2); |
c6541a0c |
114 | if(ang > 0.0001*M_PI){ |
7fd59977 |
115 | Standard_Real scal = ns2.Dot(dint1); |
116 | if ( scal <= 0. ){ |
117 | ns2.Reverse(); |
118 | Or2 = TopAbs_REVERSED; |
119 | } |
120 | scal = ns1.Dot(dint2); |
121 | if ( scal <= 0. ){ |
122 | ns1.Reverse(); |
123 | Or1 = TopAbs_REVERSED; |
124 | } |
125 | } |
126 | else { |
81bba717 |
127 | //the faces are locally tangent - this is fake! |
7fd59977 |
128 | if(dint1.Dot(dint2) < 0.){ |
81bba717 |
129 | //This is a forgotten regularity |
7fd59977 |
130 | gp_Vec DDU, DDV, DDUV; |
131 | S1.D2(p2d1.X(),p2d1.Y(),pt1,DU1,DV1,DDU,DDV,DDUV); |
132 | DU1 += ( DU1 * dint1 < 0) ? -DDU : DDU; |
133 | DV1 += ( DV1 * dint1 < 0) ? -DDV : DDV; |
134 | ns1 = DU1.Crossed(DV1); |
135 | ns1.Normalize(); |
7d92212e |
136 | if (F1.Orientation() == TopAbs_REVERSED) |
137 | ns1.Reverse(); |
7fd59977 |
138 | S2.D2(p2d2.X(),p2d2.Y(),pt2,DU2,DV2,DDU,DDV,DDUV); |
139 | DU2 += ( DU2 * dint2 < 0) ? -DDU : DDU; |
140 | DV2 += ( DV2 * dint2 < 0) ? -DDV : DDV; |
141 | ns2 = DU2.Crossed(DV2); |
142 | ns2.Normalize(); |
7d92212e |
143 | if (F2.Orientation() == TopAbs_REVERSED) |
144 | ns2.Reverse(); |
7fd59977 |
145 | |
146 | dint1 = ns1.Crossed(tgE1); |
147 | dint2 = ns2.Crossed(tgE2); |
148 | ang = ns1.CrossMagnitude(ns2); |
c6541a0c |
149 | if(ang > 0.0001*M_PI){ |
7fd59977 |
150 | Standard_Real scal = ns2.Dot(dint1); |
151 | if ( scal <= 0. ){ |
152 | ns2.Reverse(); |
153 | Or2 = TopAbs_REVERSED; |
154 | } |
155 | scal = ns1.Dot(dint2); |
156 | if ( scal <= 0. ){ |
157 | ns1.Reverse(); |
158 | Or1 = TopAbs_REVERSED; |
159 | } |
160 | } |
161 | else { |
0797d9d3 |
162 | #ifdef OCCT_DEBUG |
81bba717 |
163 | cout<<"ConcaveSide : no concave face"<<endl; |
7fd59977 |
164 | #endif |
81bba717 |
165 | //This 10 shows that the face at end is in the extension of one of two base faces |
7fd59977 |
166 | return 10; |
167 | } |
168 | } |
169 | else { |
81bba717 |
170 | //here it turns back, the points are taken in faces |
171 | //neither too close nor too far as much as possible. |
7fd59977 |
172 | Standard_Real u,v; |
0797d9d3 |
173 | #ifdef OCCT_DEBUG |
7fd59977 |
174 | // Standard_Real deport = 1000*BRep_Tool::Tolerance(E); |
175 | #endif |
176 | ChFi3d_Coefficient(dint1,DU1,DV1,u,v); |
177 | p2d1.SetX(p2d1.X() + u); p2d1.SetY(p2d1.Y() + v); |
178 | ChFi3d_Coefficient(dint1,DU2,DV2,u,v); |
179 | p2d2.SetX(p2d2.X() + u); p2d2.SetY(p2d2.Y() + v); |
180 | S1.D1(p2d1.X(),p2d1.Y(),pt1,DU1,DV1); |
181 | ns1 = DU1.Crossed(DV1); |
7d92212e |
182 | if (F1.Orientation() == TopAbs_REVERSED) |
183 | ns1.Reverse(); |
7fd59977 |
184 | S2.D1(p2d2.X(),p2d2.Y(),pt2,DU2,DV2); |
185 | ns2 = DU2.Crossed(DV2); |
7d92212e |
186 | if (F2.Orientation() == TopAbs_REVERSED) |
187 | ns2.Reverse(); |
7fd59977 |
188 | gp_Vec vref(pt1,pt2); |
189 | if(ns1.Dot(vref) < 0.){ |
190 | Or1 = TopAbs_REVERSED; |
191 | } |
192 | if(ns2.Dot(vref) > 0.){ |
193 | Or2 = TopAbs_REVERSED; |
194 | } |
195 | } |
196 | } |
197 | |
198 | |
199 | if (Or1 == TopAbs_FORWARD) { |
200 | if (Or2 == TopAbs_FORWARD) ChoixConge = 1; |
201 | else ChoixConge = 7; |
202 | } |
203 | else { |
204 | if (Or2 == TopAbs_FORWARD) ChoixConge = 3; |
205 | else ChoixConge = 5; |
206 | } |
207 | if ((ns1.Crossed(ns2)).Dot(tgE) >= 0.) ChoixConge++ ; |
208 | return ChoixConge; |
209 | } |
210 | |
211 | //======================================================================= |
212 | //function : NextSide |
213 | //purpose : |
214 | // |
215 | //======================================================================= |
216 | |
217 | Standard_Integer ChFi3d::NextSide(TopAbs_Orientation& Or1, |
218 | TopAbs_Orientation& Or2, |
219 | const TopAbs_Orientation OrSave1, |
220 | const TopAbs_Orientation OrSave2, |
221 | const Standard_Integer ChoixSave) |
222 | { |
223 | if (Or1 == TopAbs_FORWARD){Or1 = OrSave1;} |
224 | else { |
225 | Or1 = TopAbs::Reverse(OrSave1); |
226 | } |
227 | if (Or2 == TopAbs_FORWARD){Or2 = OrSave2;} |
228 | else { |
229 | Or2 = TopAbs::Reverse(OrSave2); |
230 | } |
231 | |
232 | Standard_Integer ChoixConge; |
233 | if (Or1 == TopAbs_FORWARD) { |
234 | if (Or2 == TopAbs_FORWARD) ChoixConge = 1; |
235 | else { |
236 | if(ChoixSave < 0) ChoixConge = 3; |
237 | else ChoixConge = 7; |
238 | } |
239 | } |
240 | else { |
241 | if (Or2 == TopAbs_FORWARD) { |
242 | if(ChoixSave < 0) ChoixConge = 7; |
243 | else ChoixConge = 3; |
244 | } |
245 | else ChoixConge = 5; |
246 | } |
247 | if (Abs(ChoixSave)%2 == 0) ChoixConge++; |
248 | return ChoixConge; |
249 | } |
250 | |
251 | |
252 | //======================================================================= |
253 | //function : NextSide |
254 | //purpose : |
255 | // |
256 | //======================================================================= |
257 | |
258 | void ChFi3d::NextSide(TopAbs_Orientation& Or, |
259 | const TopAbs_Orientation OrSave, |
260 | const TopAbs_Orientation OrFace) |
261 | { |
262 | if (Or == OrFace){Or = OrSave;} |
263 | else { |
264 | Or = TopAbs::Reverse(OrSave); |
265 | } |
266 | } |
267 | |
268 | |
269 | |
270 | //======================================================================= |
271 | //function : SameSide |
272 | //purpose : |
273 | // |
274 | //======================================================================= |
275 | |
276 | Standard_Boolean ChFi3d::SameSide(const TopAbs_Orientation Or, |
277 | const TopAbs_Orientation OrSave1, |
278 | const TopAbs_Orientation OrSave2, |
279 | const TopAbs_Orientation OrFace1, |
280 | const TopAbs_Orientation OrFace2) |
281 | { |
282 | TopAbs_Orientation o1,o2; |
283 | if (Or == OrFace1){o1 = OrSave1;} |
284 | else { |
285 | o1 = TopAbs::Reverse(OrSave1); |
286 | } |
287 | if (Or == OrFace2){o2 = OrSave2;} |
288 | else { |
289 | o2 = TopAbs::Reverse(OrSave2); |
290 | } |
291 | return (o1 == o2); |
292 | } |