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