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