b311480e |
1 | // Created on: 1998-12-23 |
2 | // Created by: Xuan PHAM PHU |
3 | // Copyright (c) 1998-1999 Matra Datavision |
4 | // Copyright (c) 1999-2012 OPEN CASCADE SAS |
5 | // |
6 | // The content of this file is subject to the Open CASCADE Technology Public |
7 | // License Version 6.5 (the "License"). You may not use the content of this file |
8 | // except in compliance with the License. Please obtain a copy of the License |
9 | // at http://www.opencascade.org and read it completely before using this file. |
10 | // |
11 | // The Initial Developer of the Original Code is Open CASCADE S.A.S., having its |
12 | // main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France. |
13 | // |
14 | // The Original Code and all software distributed under the License is |
15 | // distributed on an "AS IS" basis, without warranty of any kind, and the |
16 | // Initial Developer hereby disclaims all such warranties, including without |
17 | // limitation, any warranties of merchantability, fitness for a particular |
18 | // purpose or non-infringement. Please see the License for the specific terms |
19 | // and conditions governing the rights and limitations under the License. |
20 | |
7fd59977 |
21 | |
22 | |
23 | #include <TopOpeBRepTool.hxx> |
24 | #include <TopOpeBRepTool_EXPORT.hxx> |
25 | #include <TopOpeBRepTool_CLASSI.hxx> |
26 | #include <TopOpeBRepTool_REGUW.hxx> |
27 | #include <TopOpeBRepTool_TOOL.hxx> |
28 | #include <TopOpeBRepTool_define.hxx> |
29 | #include <TopExp_Explorer.hxx> |
30 | #include <BRep_Tool.hxx> |
31 | #include <TopAbs.hxx> |
32 | #include <TopoDS.hxx> |
33 | |
34 | #ifdef DRAW |
35 | #include <TopOpeBRepTool_DRAW.hxx> |
36 | #endif |
37 | |
38 | #define SAME (-1) |
39 | #define DIFF (-2) |
40 | #define UNKNOWN ( 0) |
41 | #define oneINtwo ( 1) |
42 | #define twoINone ( 2) |
43 | |
44 | #define M_FORWARD(sta) (sta == TopAbs_FORWARD) |
45 | #define M_REVERSED(sta) (sta == TopAbs_REVERSED) |
46 | #define M_INTERNAL(sta) (sta == TopAbs_INTERNAL) |
47 | #define M_EXTERNAL(sta) (sta == TopAbs_EXTERNAL) |
48 | |
49 | #ifdef DEB |
1d0a9d4d |
50 | extern Standard_Boolean TopOpeBRepTool_GettraceREGUFA(); |
7fd59977 |
51 | static TopTools_IndexedMapOfShape STATIC_mapw,STATIC_mapf; |
52 | static Standard_Integer FUN_adds(const TopoDS_Shape& s) { |
53 | TopAbs_ShapeEnum typ = s.ShapeType(); |
54 | TCollection_AsciiString aa; Standard_Integer is = 0; |
55 | if (typ == TopAbs_WIRE) {aa = TCollection_AsciiString("wi"); is = STATIC_mapw.Add(s); } |
56 | if (typ == TopAbs_FACE) {aa = TCollection_AsciiString("fa"); is = STATIC_mapf.Add(s); } |
57 | #ifdef DRAW |
58 | FUN_tool_draw(aa,s,is); |
59 | #endif |
60 | return is; |
61 | } |
62 | Standard_EXPORT void FUN_tool_coutsta(const Standard_Integer& sta, const Standard_Integer& i1, const Standard_Integer& i2) |
63 | { |
64 | switch (sta) { |
65 | case SAME: |
66 | cout<<i1<<" gives SAME bnd with "<<i2<<endl; break; |
67 | case DIFF: |
68 | cout<<i1<<" gives OUT bnd with "<<i2<<endl; break; |
69 | case oneINtwo: |
70 | cout<<i1<<" is IN "<<i2<<endl; break; |
71 | case twoINone: |
72 | cout<<i2<<" is IN "<<i1<<endl; break; |
73 | } |
74 | } |
75 | #endif |
76 | |
77 | Standard_EXPORT void FUN_addOwlw(const TopoDS_Shape& Ow, const TopTools_ListOfShape& lw, TopTools_ListOfShape& lresu); |
78 | |
79 | //======================================================================= |
80 | //function : RegularizeWires |
81 | //purpose : |
82 | //======================================================================= |
83 | |
84 | Standard_Boolean TopOpeBRepTool::RegularizeWires(const TopoDS_Face& theFace, |
85 | TopTools_DataMapOfShapeListOfShape& mapoldWnewW, |
86 | TopTools_DataMapOfShapeListOfShape& ESplits) // (e,esp); esp = splits of e |
87 | { |
88 | if (theFace.IsNull()) return Standard_False; |
89 | TopoDS_Shape aLocalShape = theFace.Oriented(TopAbs_FORWARD); |
90 | TopoDS_Face aFace = TopoDS::Face(aLocalShape); |
91 | // TopoDS_Face aFace = TopoDS::Face(theFace.Oriented(TopAbs_FORWARD)); |
92 | |
93 | TopOpeBRepTool_REGUW REGUW(aFace); |
94 | REGUW.SetOwNw(mapoldWnewW); |
95 | REGUW.SetEsplits(ESplits); |
96 | |
97 | // Standard_Boolean hasregu = Standard_False; |
98 | TopExp_Explorer exw(aFace, TopAbs_WIRE); |
99 | for (; exw.More(); exw.Next()) { |
100 | const TopoDS_Shape& W = exw.Current(); |
101 | REGUW.Init(W); |
102 | Standard_Boolean ok = REGUW.MapS(); |
103 | if (!ok) return Standard_False; |
104 | ok = REGUW.SplitEds(); |
105 | if (!ok) return Standard_False; |
106 | ok = REGUW.REGU(); |
107 | if (!ok) return Standard_False; |
108 | } |
109 | |
110 | REGUW.GetEsplits(ESplits); |
111 | REGUW.GetOwNw(mapoldWnewW); |
112 | return Standard_True; |
113 | } |
114 | |
115 | //======================================================================= |
116 | //function : Regularize |
117 | //purpose : |
118 | //======================================================================= |
119 | |
120 | Standard_Boolean TopOpeBRepTool::Regularize(const TopoDS_Face& theFace, |
121 | TopTools_ListOfShape& aListOfFaces, |
122 | TopTools_DataMapOfShapeListOfShape& ESplits) |
123 | { |
124 | TopOpeBRepTool_REGUW REGUW(theFace); |
125 | aListOfFaces.Clear(); |
126 | TopTools_DataMapOfShapeListOfShape mapoldWnewW; |
127 | Standard_Boolean regu = TopOpeBRepTool::RegularizeWires(theFace,mapoldWnewW,ESplits); |
128 | if (regu) { |
129 | regu = TopOpeBRepTool::RegularizeFace(theFace,mapoldWnewW,aListOfFaces); |
130 | } |
131 | return regu; |
132 | } |
133 | |
134 | //********************************************************************** |
135 | // classifying wires |
136 | //********************************************************************** |
137 | |
138 | // ------------------------------------------------------------ |
139 | // ------------------ classifying wires ----------------------- |
140 | |
141 | // function : bFgreaterbFF (F,FF) |
142 | // purpose : returns False if <F>'s 3d bounding box smaller than <FF>'s |
143 | |
144 | // function : mkBnd2d (W,F,B2d) |
145 | // purpose : get 2d bounding box <B2d> of wire <W>'s UV |
146 | // representation on face <F>. |
147 | |
148 | // function : classiBnd2d (B,ismaller) |
149 | // purpose : compare the two 2d bounding boxes of array <B> |
150 | // if found, B<ismaller> is the smaller one and returns IN |
151 | // else if boxes are disjoint, returns OUT |
152 | // else return UNKNOWN |
153 | // function : classiBnd2d (B) |
154 | // purpose : returns SAME,DIFF,UNKNOWN,oneINtwo or twoINone |
155 | |
156 | |
157 | // function : mkboundedF(W,boundedF) |
158 | // purpose : |
159 | |
160 | // function : FindAPointInTheFace(F,u,v) |
161 | // purpose : |
162 | |
163 | // function : GetFP2d(W,boundedF,p2d) |
164 | // purpose : computes <boundedF> the bounded face built up with wire <W> |
165 | // and <p2d> a point in <boundedF> |
166 | // |
167 | |
168 | // function : classiwithp2d(wi) |
169 | // purpose : classify wires (wi(k),k = 1,2) |
170 | // prequesitory : wires of <wi> are not intersecting each other. |
171 | |
172 | // function : ClassifW(F,mapoldWnewW,mapWlow) |
173 | // purpose : all wires described in <mapoldWnewW> are on face <F> |
174 | // <mapoldWnewW> = map with : |
175 | // key = a wire of <F> |
176 | // item = the splits of the previous wire (can be an empty list) |
177 | // the aim is to get map <mapWlow> with : |
178 | // key = a new face's boundary |
179 | // item = wires dexcribing holes in the previous face |
180 | // (can be an empty list) |
181 | // ------------------------------------------------------------ |
182 | |
183 | /*static TopAbs_State FUN_tool_classiBnd2d(const Bnd_Array1OfBox2d& B,Standard_Integer& ismaller, |
184 | const Standard_Boolean chklarge = Standard_True) |
185 | { |
186 | // purpose : |
187 | // Getting <ismaller>, index of the smallest Bnd Box |
188 | // if B(i) is IN B(j): ismaller = i, |
189 | // return IN. |
190 | // else: ismaller = 1, |
191 | // if B(1) and B(2) are disjoint, return OUT |
192 | // if B(1) and B(2) are same, return ON |
193 | // else return UNKNOWN. |
194 | ismaller = 1; |
195 | |
196 | TColStd_Array2OfReal UV(1,2, 1,4); |
197 | for (Standard_Integer i = 1; i <= 2; i++) |
198 | // (Umin(i), Vmin(i), Umax(i), Vmax(i)) |
199 | B(i).Get(UV(i,1), UV(i,3), UV(i,2), UV(i,4)); |
200 | |
201 | #ifdef DEB |
202 | Standard_Boolean trc = Standard_False; |
203 | if (trc) { |
204 | for (Standard_Integer i = 1; i <= 2; i++) |
205 | cout<<"B("<<i<<") = ("<<UV(i,1)<<" "<<UV(i,3)<<" "<<UV(i,2)<<" "<<UV(i,4)<<")"<<endl; |
206 | } |
207 | #endif |
208 | |
209 | Standard_Boolean smaller, same; |
210 | Standard_Integer ii, jj; |
211 | Standard_Real tol = 1.e-6; |
212 | |
213 | Standard_Boolean disjoint = Standard_False; |
214 | for (Standard_Integer k = 1; k <= 3; k+=2) { |
215 | for (i = 1; i <= 2; i++) { |
216 | ii = i; jj = (i == 1) ? 2 : 1; |
217 | // diff = Umin<ii> - Umax<jj> : k = 1 |
218 | // diff = Vmin<ii> - Vmax<jj> : k = 3 |
219 | Standard_Real diff = UV(ii,k) - UV(jj,k+1); |
220 | // IMPORTANT : for splitted faces sharing same edge, use |
221 | // chklarge = True. |
222 | disjoint = chklarge ? (diff >= -tol) : (diff > 0.); |
223 | if (disjoint) {ismaller = 1; return TopAbs_OUT;} |
224 | } |
225 | } |
226 | |
227 | for (i = 1; i <= 2; i++) { |
228 | ii = i; jj = (i == 1) ? 2 : 1; |
229 | smaller = same = Standard_True; |
230 | for (Standard_Integer k = 1; k <= 3; k += 2){ |
231 | // diff = Umin<ii> - Umin<jj> : k = 1 |
232 | // diff = Vmin<ii> - Vmin<jj> : k = 3 |
233 | Standard_Real diff = UV(ii,k) - UV(jj,k); |
234 | smaller = chklarge ? (smaller && (diff > -tol)) : (smaller && (diff > 0.)); |
235 | same = same && (Abs(diff) <= tol); |
236 | } |
237 | for (k = 2; k <= 4; k +=2){ |
238 | // diff = Umax<ii> - Umax<jj> : k = 2 |
239 | // diff = Vmax<ii> - Vmax<jj> : k = 4 |
240 | Standard_Real diff = UV(ii,k) - UV(jj,k); |
241 | smaller = chklarge ? (smaller && (diff < tol)) : (smaller && (diff < 0.)); |
242 | same = same && (Abs(diff) <= tol); |
243 | } |
244 | |
245 | if (same) return TopAbs_ON; |
246 | if (smaller) { |
247 | ismaller = ii; |
248 | return TopAbs_IN; |
249 | } |
250 | } |
251 | return TopAbs_UNKNOWN; |
252 | } |
253 | |
254 | #define SAME (-1) |
255 | #define DIFF (-2) |
256 | #define UNKNOWN ( 0) |
257 | #define oneINtwo ( 1) |
258 | #define twoINone ( 2) |
259 | |
260 | Standard_EXPORT Standard_Integer FUN_tool_classiBnd2d(const Bnd_Array1OfBox2d& B, |
261 | const Standard_Boolean chklarge = Standard_True) |
262 | { |
263 | Standard_Integer ismaller; |
264 | TopAbs_State sta = FUN_tool_classiBnd2d(B, ismaller, chklarge); |
265 | Standard_Integer res = -10; |
266 | switch (sta) { |
267 | case TopAbs_IN : |
268 | res = ismaller; break; |
269 | case TopAbs_OUT : |
270 | res = DIFF; break; |
271 | case TopAbs_ON : |
272 | res = SAME; break; |
273 | case TopAbs_UNKNOWN : |
274 | res = UNKNOWN; break; |
275 | } |
276 | return res; |
277 | } |
278 | |
279 | static Standard_Boolean FUN_tool_mkboundedF(const TopoDS_Wire& W, TopoDS_Face& boundedF) |
280 | { |
281 | BRepLib_MakeFace mf(W, Standard_False); |
282 | Standard_Boolean done = mf.IsDone(); |
283 | if (done) boundedF = mf.Face(); |
284 | return done; |
285 | } |
286 | Standard_Boolean FUN_tool_FindAPointInTheFace(const TopoDS_Face& F, |
287 | Standard_Real& u, Standard_Real& v) |
288 | { |
289 | Standard_Boolean ok = BRepClass3d_SolidExplorer::FindAPointInTheFace(F,u,v); |
290 | return ok; |
291 | } |
292 | static Standard_Boolean FUN_tool_GetFP2d(const TopoDS_Shape& W, |
293 | TopoDS_Shape& boundedF, gp_Pnt2d& p2d) |
294 | { |
295 | Standard_Boolean ok = FUN_tool_mkboundedF(TopoDS::Wire(W), TopoDS::Face(boundedF)); |
296 | if (!ok) return Standard_False; |
297 | |
298 | Standard_Real u,v; ok = FUN_tool_FindAPointInTheFace(TopoDS::Face(boundedF),u,v); |
299 | if (!ok) return Standard_False; |
300 | p2d = gp_Pnt2d(u,v); |
301 | return Standard_True; |
302 | } |
303 | static Standard_Integer FUN_tool_classiwithp2d(const TopTools_Array1OfShape& wi) |
304 | { |
305 | Standard_Integer stares = UNKNOWN; |
306 | TopTools_Array1OfShape fa(1,2); |
307 | TColgp_Array1OfPnt p3d(1,2); |
308 | for (Standard_Integer k = 1; k <= 2; k++) { |
309 | gp_Pnt2d p2d; |
310 | Standard_Boolean ok = FUN_tool_GetFP2d(wi(k), fa(k), p2d); |
311 | if (!ok) return UNKNOWN; |
312 | BRepAdaptor_Surface BS(TopoDS::Face(fa(k))); |
313 | p3d(k) = BS.Value(p2d.X(),p2d.Y()); |
314 | } |
315 | |
316 | TopAbs_State sta; |
317 | Standard_Integer i,j; i = j = 0; |
318 | for (Standard_Integer nite = 1; nite <= 2; nite++) { |
319 | i = nite; |
320 | j = (i == 1) ? 2 : 1; |
321 | TopoDS_Face f = TopoDS::Face(fa(j)); |
322 | const gp_Pnt p = p3d(i); |
323 | Standard_Real tol = BRep_Tool::Tolerance(f); |
324 | BRepClass_FaceClassifier Fclass(f, p, tol); |
325 | sta = Fclass.State(); |
326 | if (sta == TopAbs_IN) break; |
327 | } |
328 | switch (sta) { |
329 | case TopAbs_IN : |
330 | stares = i; break; |
331 | case TopAbs_OUT : |
332 | stares = DIFF; break; |
333 | case TopAbs_ON : |
334 | case TopAbs_UNKNOWN : |
335 | stares = UNKNOWN; break; |
336 | } |
337 | return stares; |
338 | } |
339 | |
340 | Standard_EXPORT Standard_Boolean FUN_tool_ClassifW(const TopoDS_Face& F, |
341 | const TopTools_DataMapOfShapeListOfShape& mapoldWnewW, |
342 | TopTools_DataMapOfShapeListOfShape& mapWlow) |
343 | { |
344 | // NYI : create maps to store Bnd_Box2d, and faces. |
345 | |
346 | #ifdef DEB |
347 | Standard_Boolean trc = TopOpeBRepTool_GettraceREGUFA(); |
348 | if (trc) cout<<"** ClassifW :"<<endl; |
349 | STATIC_mapw.Clear(); |
350 | #endif |
351 | |
352 | // Purpose : |
353 | // -------- |
354 | // Filling the map <mapWlow> : with (key + item) = new face, |
355 | // item = (newface has holes) ? list of wires IN the wire key: empty list |
356 | |
357 | // prequesitory : <mapoldWnewW> binds (non splitted wire of <F>, emptylos) |
358 | // (splitted wire of <F>, splits of the wire) |
359 | |
360 | // Mapping : |
361 | // -------- |
362 | // Filling <oldW> : list of wires of <F> |
363 | // Filling <mapWlow> : with (non-splitted old wire, emptylos), |
364 | // (split of old wire, emptylos) |
365 | TopTools_ListOfShape oldW; |
366 | Standard_Integer noldW = mapoldWnewW.Extent(); |
367 | Standard_Boolean oneoldW = (noldW == 1); |
368 | TopTools_DataMapIteratorOfDataMapOfShapeListOfShape ite(mapoldWnewW); |
369 | TopTools_ListOfShape emptylos; |
370 | |
371 | // -------------- |
372 | // * noldW == 1 : |
373 | // -------------- |
374 | if (oneoldW) { |
375 | const TopoDS_Wire& oldwi = TopoDS::Wire(ite.Key()); |
376 | const TopTools_ListOfShape& low = ite.Value(); |
377 | Standard_Integer nw = low.Extent(); |
378 | if (nw == 0) {mapWlow.Bind(oldwi,emptylos); return Standard_True;} |
379 | if (nw == 1) {mapWlow.Bind(low.First(),emptylos); return Standard_True;} |
380 | |
381 | // <complWoldw> = {(newwire, emptylos)} |
382 | TopTools_DataMapOfShapeListOfShape complWoldw; |
383 | TopTools_ListIteratorOfListOfShape itlw(low); |
384 | for (; itlw.More(); itlw.Next()) complWoldw.Bind(itlw.Value(), emptylos); |
385 | |
386 | // iteration on <complWoldw> : |
387 | Standard_Integer ncompl = complWoldw.Extent(); |
388 | Standard_Boolean go = Standard_True; |
389 | Standard_Integer nite = 0, nitemax = Standard_Integer(ncompl*(ncompl-1)/2); |
390 | while (go && (nite <= nitemax)){ |
391 | Bnd_Array1OfBox2d Bnd2d(1,2); |
392 | TopTools_Array1OfShape wi(1,2); |
393 | |
394 | TopTools_DataMapIteratorOfDataMapOfShapeListOfShape itmap(complWoldw); |
395 | wi(1) = itmap.Key(); |
396 | if (ncompl == 1) { |
397 | mapWlow.Bind(wi(1),itmap.Value()); |
398 | break; |
399 | } |
400 | FUN_tool_mkBnd2d(wi(1), F, Bnd2d(1)); |
401 | Standard_Boolean OUTall = Standard_False; |
402 | Standard_Boolean oneINother = Standard_False; |
403 | Standard_Integer sma,gre; // dummy if !oneINother |
404 | |
405 | for (; itmap.More(); itmap.Next()) { |
406 | wi(2) = itmap.Key(); |
407 | if (wi(1).IsSame(wi(2))) continue; |
408 | FUN_tool_mkBnd2d(wi(2), F, Bnd2d(2)); |
409 | |
410 | // sta : wi(1) / wi(2) |
411 | Standard_Integer sta = FUN_tool_classiBnd2d(Bnd2d); |
412 | nite++; |
413 | if ((sta == SAME)||(sta == UNKNOWN)) sta = FUN_tool_classiwithp2d(wi); |
414 | #ifdef DEB |
415 | if (trc) {cout<<"#wi :";FUN_tool_coutsta(sta,FUN_adds(wi(1)),FUN_adds(wi(2)));} |
416 | #endif |
417 | if ((sta == SAME)||(sta == UNKNOWN)) return Standard_False; |
418 | if ((sta == DIFF) && itmap.More()) {OUTall = Standard_True; continue;}// w(1) OUT w(2) |
419 | sma = (sta == oneINtwo) ? 1 : 2; |
420 | gre = (sta == oneINtwo) ? 2 : 1; |
421 | oneINother = Standard_True; |
422 | break; |
423 | } // itmap |
424 | |
425 | if (oneINother) { |
426 | // Updating map <complWoldw> with : |
427 | // - key = wi(gre), |
428 | // item += wi(sma) && item += item(wi(sma)) |
429 | // - unbinding key = (wi(sma)) |
430 | TopTools_ListOfShape& lwgre = complWoldw.ChangeFind(wi(gre)); |
431 | lwgre.Append(wi(sma)); |
432 | TopTools_ListIteratorOfListOfShape itwsma(complWoldw.Find(wi(sma))); |
433 | for (; itwsma.More(); itwsma.Next()) lwgre.Append(itwsma.Value()); |
434 | complWoldw.UnBind(wi(sma)); |
435 | } |
436 | else if (OUTall) {mapWlow.Bind(wi(1),emptylos); complWoldw.UnBind(wi(1));} |
437 | else return Standard_False; |
438 | |
439 | ncompl = complWoldw.Extent(); |
440 | go = (ncompl >= 1); |
441 | } |
442 | return Standard_True; |
443 | } // oneoldW |
444 | |
445 | |
446 | // ------------- |
447 | // * noldW > 1 : |
448 | // ------------- |
449 | for (; ite.More(); ite.Next()){ |
450 | const TopoDS_Wire& oldwi = TopoDS::Wire(ite.Key()); |
451 | const TopTools_ListOfShape& low = ite.Value(); |
452 | TopTools_ListIteratorOfListOfShape itlow(low); |
453 | if (low.IsEmpty()) mapWlow.Bind(oldwi, emptylos); |
454 | else |
455 | for (; itlow.More(); itlow.Next()) mapWlow.Bind(itlow.Value(), emptylos); |
456 | oldW.Append(oldwi); |
457 | } |
458 | |
459 | // classifying wires of <mapoldWnewW> : |
460 | // ----------------------------------- |
461 | // <Owi> : old wires |
462 | // <OBnd2d> : old wires' bounding boxes |
463 | // <Owhassp>(k) : Owi(k) has splits |
464 | |
465 | TopTools_ListOfShape oldWcopy; oldWcopy.Assign(oldW); |
466 | for (TopTools_ListIteratorOfListOfShape itoldW(oldW); itoldW.More(); itoldW.Next()) { |
467 | |
468 | TopTools_Array1OfShape Owi(1,2); |
469 | Bnd_Array1OfBox2d OBnd2d(1,2); |
470 | TColStd_Array1OfBoolean Owhassp(1,2); |
471 | |
472 | Owi(1) = itoldW.Value(); |
473 | if (oldWcopy.Extent() <1) break; |
474 | oldWcopy.RemoveFirst(); |
475 | |
476 | Owhassp(1) = !mapoldWnewW.Find(Owi(1)).IsEmpty(); |
477 | Standard_Boolean Owi1notkey = !mapWlow.IsBound(Owi(1)); |
478 | if (Owi1notkey && !Owhassp(1)) continue; |
479 | |
480 | FUN_tool_mkBnd2d(Owi(1), F, OBnd2d(1)); |
481 | |
482 | // Classifying oldwire(i) with oldwires(j): j = i+1..nwiresofF |
483 | Standard_Integer osma,ogre,osta; |
484 | TopTools_ListIteratorOfListOfShape itoldWcopy(oldWcopy); |
485 | for (; itoldWcopy.More(); itoldWcopy.Next()) { |
486 | |
487 | TopTools_Array1OfListOfShape newwi(1,2); |
488 | Owi(2) = TopoDS::Wire(itoldWcopy.Value()); |
489 | Standard_Boolean Owi2notkey = !mapWlow.IsBound(Owi(2)); |
490 | Owhassp(2) = !mapoldWnewW.Find(Owi(2)).IsEmpty(); |
491 | if (Owi2notkey && !Owhassp(2)) continue; |
492 | FUN_tool_mkBnd2d(Owi(2), F, OBnd2d(2)); |
493 | |
494 | // <osma>, <ogre> : |
495 | // ---------------- |
496 | // Classifying Ow<i> with Ow<j> : |
497 | osta = FUN_tool_classiBnd2d(OBnd2d); |
498 | if ((osta == SAME)||(osta == UNKNOWN)) osta = FUN_tool_classiwithp2d(Owi); |
499 | #ifdef DEB |
500 | if (trc) {cout<<"wi : "; FUN_tool_coutsta(osta,FUN_adds(Owi(1)),FUN_adds(Owi(2)));} |
501 | #endif |
502 | if ((osta == SAME)||(osta == UNKNOWN)) return Standard_False; |
503 | if (osta == DIFF) continue; // Ow(1), Ow(2) are disjoint |
504 | // Owi<sma> is IN Owi<grea> |
505 | osma = (osta == oneINtwo) ? 1 : 2; |
506 | ogre = (osta == oneINtwo) ? 2 : 1; |
507 | |
508 | // Owhassp<k> : newwi<k> = splits (Owi<k>) |
509 | // !Owhassp<k> : newwi<k> = Owi<k> |
510 | for (Standard_Integer i = 1; i <= 2; i++) { |
511 | const TopoDS_Shape& owi = Owi(i); |
512 | if (!Owhassp(i)) newwi(i).Append(owi); |
513 | else newwi(i) = mapoldWnewW.Find(owi); |
514 | } |
515 | |
516 | // |
517 | // classifying wires of newwi<sma> with wires of newwi<gre> : |
518 | // |
519 | Standard_Integer sta, sma, gre; |
520 | TopTools_ListIteratorOfListOfShape itnwi(newwi(osma)); |
521 | for (; itnwi.More(); itnwi.Next()) { |
522 | // <wi> : new wires |
523 | // <Bnd2d> : new wires' bounding boxes |
524 | TopTools_Array1OfShape wi(1,2); |
525 | Bnd_Array1OfBox2d Bnd2d(1,2); |
526 | |
527 | wi(1) = itnwi.Value(); // wi(1) in {newwi(osma)} |
528 | Standard_Boolean wi1notkey = !mapWlow.IsBound(wi(1)); |
529 | if (wi1notkey) continue; |
530 | |
531 | if (!Owhassp(osma)) Bnd2d(1).Add(OBnd2d(osma)); |
532 | else FUN_tool_mkBnd2d(wi(1), F, Bnd2d(1)); |
533 | |
534 | TopTools_ListIteratorOfListOfShape itnwj(newwi(ogre)); |
535 | for (; itnwj.More(); itnwj.Next()) { |
536 | |
537 | wi(2) = itnwj.Value(); // wi(2) in {newwi(ogre)} |
538 | Standard_Boolean wi2notkey = !mapWlow.IsBound(wi(2)); |
539 | if (wi2notkey) continue; |
540 | |
541 | // empty the bounding box |
542 | Bnd_Box2d newB2d; |
543 | if (!Owhassp(ogre)) newB2d.Add(OBnd2d(ogre)); |
544 | else FUN_tool_mkBnd2d(wi(2), F, newB2d); |
545 | FUN_tool_UpdateBnd2d(Bnd2d(2),newB2d); |
546 | |
547 | // Classifying wi(1) with wi(2) : |
548 | sta = FUN_tool_classiBnd2d(Bnd2d); |
549 | #ifdef DEB |
550 | if (trc) {cout<<"wi : "; FUN_tool_coutsta(sta,STATIC_mapw.FindIndex(wi(1)), |
551 | STATIC_mapw.FindIndex(wi(2)));} |
552 | #endif |
553 | if ((sta == SAME)||(sta == UNKNOWN)) sta = FUN_tool_classiwithp2d(wi); |
554 | if ((sta == SAME)||(sta == UNKNOWN)) return Standard_False; |
555 | if (sta == DIFF) continue; |
556 | // wi<sma> is IN wi<grea> |
557 | sma = (sta == oneINtwo) ? 1 : 2; |
558 | gre = (sta == oneINtwo) ? 2 : 1; |
559 | |
560 | // Updating map <mapWlow> with : |
561 | // - key = wi(gre), |
562 | // item += wi(sma) && item += item(wi(sma)) |
563 | // - unbinding key = (wi(sma)) |
564 | TopTools_ListOfShape& lwgre = mapWlow.ChangeFind(wi(gre)); |
565 | lwgre.Append(wi(sma)); |
566 | TopTools_ListIteratorOfListOfShape itwsma(mapWlow.Find(wi(sma))); |
567 | for (; itwsma.More(); itwsma.Next()) lwgre.Append(itwsma.Value()); |
568 | mapWlow.UnBind(wi(sma)); |
569 | break; |
570 | // wi<sma> IN wi<gre>, wi<sma> is OUT {newwi<gre>} / wi<gre> |
571 | // wi<sma> is classified / all newwires. |
572 | } |
573 | } // itnwi(newwi(sma)) |
574 | }// itoldWcopy |
575 | } // itoldW |
576 | return Standard_True; |
577 | } |
578 | // ------------------------------------------------------------ |
579 | // -------------------- building up faces --------------------- |
580 | // ------------------------------------------------------------ |
581 | |
582 | Standard_EXPORT Standard_Boolean FUN_tool_MakeFaces(const TopoDS_Face& theFace, |
583 | TopTools_DataMapOfShapeListOfShape& mapWlow, |
584 | TopTools_ListOfShape& aListOfFaces) |
585 | { |
586 | #ifdef DEB |
587 | Standard_Boolean trc = TopOpeBRepTool_GettraceREGUFA(); |
588 | if (trc) cout<<"** MakeFaces :"<<endl; |
589 | #endif |
590 | Standard_Boolean toreverse = M_REVERSED(theFace.Orientation()); |
591 | TopoDS_Face F = TopoDS::Face(theFace.Oriented(TopAbs_FORWARD)); |
592 | BRep_Builder BB; |
593 | |
594 | TopTools_DataMapIteratorOfDataMapOfShapeListOfShape itm(mapWlow); |
595 | for (; itm.More(); itm.Next()) { |
596 | const TopoDS_Wire& wi = TopoDS::Wire(itm.Key()); |
597 | TopoDS_Shape FF = F.EmptyCopied(); BB.Add(FF,wi); |
598 | // BB.MakeFace(FF); // put a TShape |
599 | |
600 | TopTools_ListIteratorOfListOfShape itlow(itm.Value()); |
601 | for (; itlow.More(); itlow.Next()) { |
602 | const TopoDS_Wire& wwi = TopoDS::Wire(itlow.Value()); |
603 | BB.Add(FF,wwi); |
604 | } |
605 | |
606 | if (toreverse) FF.Orientation(TopAbs_REVERSED); |
607 | aListOfFaces.Append(FF); |
608 | } |
609 | |
610 | #ifdef DEB |
611 | if (trc) { |
612 | cout<<"sp(fa"<<FUN_adds(theFace)<<")="; |
613 | TopTools_ListIteratorOfListOfShape it(aListOfFaces); |
614 | for (; it.More(); it.Next()) cout<<" fa"<<FUN_adds(it.Value()); |
615 | cout<<endl; |
616 | } |
617 | #endif |
618 | |
619 | return Standard_True; |
620 | }*/ |
621 | |
622 | Standard_EXPORT Standard_Boolean FUN_tool_ClassifW(const TopoDS_Face& F, |
623 | const TopTools_DataMapOfShapeListOfShape& mapOwNw, |
624 | TopTools_DataMapOfShapeListOfShape& mapWlow) |
625 | { |
626 | #ifdef DEB |
627 | Standard_Boolean trc = TopOpeBRepTool_GettraceREGUFA(); |
628 | if (trc) cout<<"** ClassifW :"<<endl; |
629 | #endif |
630 | Standard_Real tolF = BRep_Tool::Tolerance(F); |
631 | Standard_Real toluv = TopOpeBRepTool_TOOL::TolUV(F,tolF); |
632 | TopoDS_Shape aLocalShape = F.Oriented(TopAbs_FORWARD); |
633 | TopoDS_Face FFOR = TopoDS::Face(aLocalShape); |
634 | // TopoDS_Face FFOR = TopoDS::Face(F.Oriented(TopAbs_FORWARD)); |
635 | TopOpeBRepTool_CLASSI CLASSI; CLASSI.Init2d(FFOR); |
636 | |
637 | TopTools_ListOfShape null; |
638 | TopTools_ListOfShape oldW; |
639 | Standard_Integer noldW = mapOwNw.Extent(); |
640 | TopTools_DataMapIteratorOfDataMapOfShapeListOfShape itm(mapOwNw); |
641 | |
642 | // noldW = 1 |
643 | // --------- |
644 | if (noldW == 1) { |
7fd59977 |
645 | const TopTools_ListOfShape& low = itm.Value(); |
646 | Standard_Boolean ok = CLASSI.Classilist(low,mapWlow); |
647 | if (!ok) return Standard_False; |
648 | return Standard_True; |
649 | } |
650 | |
651 | // noldW > 1 |
652 | // --------- |
653 | TopTools_ListOfShape lOws; |
654 | for (; itm.More(); itm.Next()){ |
655 | const TopoDS_Shape& owi = itm.Key(); |
656 | lOws.Append(owi); |
657 | const TopTools_ListOfShape& low = itm.Value(); |
658 | TopTools_ListOfShape lwresu; FUN_addOwlw(owi,low,lwresu); |
659 | TopTools_ListIteratorOfListOfShape itw(lwresu); |
660 | for (; itw.More(); itw.Next()) mapWlow.Bind(itw.Value(), null); |
661 | }//itm(mapOwNw) |
662 | |
663 | TopTools_MapOfShape mapdone; |
664 | Standard_Integer nOw = noldW; |
665 | Standard_Integer nite = 0, nitemax = Standard_Integer(nOw*(nOw-1)/2); |
666 | while (nite <= nitemax){ |
667 | nOw = lOws.Extent(); |
668 | if (nOw == 0) break; |
669 | |
670 | TopTools_ListIteratorOfListOfShape itOw(lOws); |
671 | const TopoDS_Shape& Ow1 = itOw.Value(); |
672 | Standard_Boolean isb1 = mapWlow.IsBound(Ow1); |
673 | isb1 = isb1 || !mapdone.Contains(Ow1); |
674 | if (!isb1) continue; |
675 | |
676 | const TopTools_ListOfShape& lw1 = mapOwNw.Find(Ow1); |
6e6cd5d9 |
677 | |
7fd59977 |
678 | if (nOw == 1) { |
679 | // all wires of <mapWs> have been treated, except the last one |
680 | // if (nw1 == 0) mapWlow binds already (Ow1,null); |
681 | // else {mapWlow binds already (w1k,null), w1k in lw1} |
682 | break; |
683 | }//nOw == 1 |
684 | |
685 | itOw.Next(); |
686 | Standard_Boolean OUTall = Standard_False; |
687 | TopoDS_Shape Ow2; |
688 | Standard_Integer sta12 = UNKNOWN; |
689 | for (; itOw.More(); itOw.Next()){ |
690 | Ow2 = itOw.Value(); |
691 | Standard_Boolean isb2 = mapWlow.IsBound(Ow2); |
692 | isb2 = isb2 || !mapdone.Contains(Ow2); |
693 | if (!isb2) continue; |
694 | Standard_Integer stabnd2d12 = CLASSI.ClassiBnd2d(Ow1,Ow2,toluv,Standard_True); |
695 | sta12 = CLASSI.Classip2d(Ow1,Ow2, stabnd2d12); |
696 | if (sta12 == DIFF) {OUTall = Standard_True; continue;} |
697 | else if ((sta12 == UNKNOWN)||(sta12 == SAME)) return Standard_False; |
698 | break; |
699 | } |
700 | if (OUTall) { |
701 | // if (nw1 == 0) mapWlow binds already (Ow1,null); |
702 | // else {mapWlow binds already (w1k,null), w1k in lw1} |
703 | TopTools_ListOfShape ldone; FUN_addOwlw(Ow1,lw1,ldone); |
704 | TopTools_ListIteratorOfListOfShape itw(ldone); |
705 | for (; itw.More(); itw.Next()) mapdone.Add(itw.Value()); |
706 | #ifdef DEB |
707 | if (trc) cout<<"old wires :wi"<<FUN_adds(Ow1)<<" is OUT all old wires"<<endl; |
708 | #endif |
709 | lOws.RemoveFirst(); |
710 | }//OUTall |
711 | else { |
712 | #ifdef DEB |
713 | if (trc) {cout<<"old wires :wi -> "; |
714 | FUN_tool_coutsta(sta12,FUN_adds(Ow1),FUN_adds(Ow2)); |
715 | cout<<endl;} |
716 | #endif |
717 | const TopTools_ListOfShape& lw2 = mapOwNw.Find(Ow2); |
7fd59977 |
718 | |
719 | TopTools_ListOfShape lw1r; FUN_addOwlw(Ow1,lw1,lw1r); |
720 | TopTools_ListOfShape lw2r; FUN_addOwlw(Ow2,lw2,lw2r); |
721 | TopTools_ListOfShape lgre,lsma; |
722 | if (sta12 == oneINtwo) {lgre.Append(lw2r); lsma.Append(lw1r);} |
723 | if (sta12 == twoINone) {lgre.Append(lw1r); lsma.Append(lw2r);} |
724 | |
725 | TopTools_ListIteratorOfListOfShape itsma(lsma); |
726 | for (; itsma.More(); itsma.Next()){ |
727 | const TopoDS_Shape& wsma = itsma.Value(); |
728 | Standard_Boolean isbsma = mapWlow.IsBound(wsma); |
729 | isbsma = isbsma || !mapdone.Contains(wsma); |
730 | if (!isbsma) continue; |
731 | |
732 | TopTools_ListIteratorOfListOfShape itgre(lgre); |
733 | for (; itgre.More(); itgre.Next()){ |
734 | const TopoDS_Shape& wgre = itgre.Value(); |
735 | Standard_Boolean isbgre = mapWlow.IsBound(wgre); |
736 | isbgre = isbgre || !mapdone.Contains(wgre); |
737 | if (!isbgre) continue; |
738 | |
739 | Standard_Integer stabnd2d = CLASSI.ClassiBnd2d(wsma,wgre,toluv,Standard_True); |
740 | Standard_Integer sta = CLASSI.Classip2d(wsma,wgre, stabnd2d); |
741 | #ifdef DEB |
742 | if (trc) {cout<<" wires :wi -> "; |
743 | FUN_tool_coutsta(sta,FUN_adds(wsma),FUN_adds(wgre)); |
744 | cout<<endl;} |
745 | #endif |
746 | |
747 | if (sta == DIFF) continue; |
748 | else if (sta == oneINtwo) {// wsma IN wgre |
749 | mapWlow.ChangeFind(wgre).Append(mapWlow.ChangeFind(wsma)); |
750 | mapWlow.UnBind(wsma); |
751 | } |
752 | else if (sta == twoINone) {// wgre IN wsma |
753 | mapWlow.ChangeFind(wsma).Append(mapWlow.ChangeFind(wgre)); |
754 | mapWlow.UnBind(wgre); |
755 | } |
756 | else return Standard_False; |
757 | }//itgre |
758 | }//itsma |
759 | lOws.RemoveFirst(); |
760 | } //!OUTall |
761 | }//nite |
762 | return Standard_True; |
763 | } |
764 | |
765 | //======================================================================= |
766 | //function : RegularizeFace |
767 | //purpose : |
768 | //======================================================================= |
769 | |
770 | Standard_Boolean TopOpeBRepTool::RegularizeFace(const TopoDS_Face& theFace, |
771 | const TopTools_DataMapOfShapeListOfShape& mapoldWnewW, |
772 | TopTools_ListOfShape& newFaces) |
773 | { |
774 | // <mapWlow> |
775 | // --------- |
776 | // key = wire <w>, |
777 | // item = if the new face has holes, the item contains wires |
778 | // classified IN the area described by the boundary <w> |
779 | // on <aFace>, |
780 | // else : the item is an empty list, <w> describes the |
781 | // whole new face. |
782 | TopTools_DataMapOfShapeListOfShape mapWlow; |
783 | |
784 | // Classifying wires : |
785 | // ------------------- |
786 | // Standard_Boolean classifok = FUN_tool_ClassifW(theFace, mapoldWnewW, mapWlow); |
787 | TopoDS_Shape aLocalShape = theFace.Oriented(TopAbs_FORWARD); |
788 | TopoDS_Face aFace = TopoDS::Face(aLocalShape); |
789 | // TopoDS_Face aFace = TopoDS::Face(theFace.Oriented(TopAbs_FORWARD)); |
790 | |
791 | Standard_Boolean classifok = FUN_tool_ClassifW(aFace, mapoldWnewW, mapWlow); |
792 | if (!classifok) return Standard_False; |
793 | |
794 | // <aListOfFaces> |
795 | // ------------- |
796 | Standard_Boolean facesbuilt = TopOpeBRepTool_TOOL::WireToFace(theFace, mapWlow, newFaces); |
797 | if (!facesbuilt) return Standard_False; |
798 | return Standard_True; |
799 | } |