7fd59977 |
1 | // File: TopOpeBRepTool_REGUS.cxx |
2 | // Created: Mon Jan 4 15:34:02 1999 |
3 | // Author: Xuan PHAM PHU |
4 | // <xpu@poulopox.paris1.matra-dtv.fr> |
5 | |
6 | #include <TopOpeBRepTool_REGUS.ixx> |
7 | #include <TopoDS_Shell.hxx> |
8 | #include <TopoDS.hxx> |
9 | #include <BRep_Tool.hxx> |
10 | #include <Precision.hxx> |
11 | #include <TopExp_Explorer.hxx> |
12 | #include <TopExp.hxx> |
13 | #include <TopOpeBRepTool_TOOL.hxx> |
14 | #include <TopOpeBRepTool_EXPORT.hxx> |
15 | #include <TopOpeBRepTool_REGUW.hxx> |
16 | #include <TopOpeBRepTool_CLASSI.hxx> |
17 | #include <TopOpeBRepTool_define.hxx> |
18 | #include <TopOpeBRepTool_connexity.hxx> |
19 | |
20 | #ifdef DRAW |
21 | #include <TopOpeBRepTool_DRAW.hxx> |
22 | #endif |
23 | |
24 | #define M_FORWARD(ori) (ori == TopAbs_FORWARD) |
25 | #define M_REVERSED(ori) (ori == TopAbs_REVERSED) |
26 | #define M_INTERNAL(ori) (ori == TopAbs_INTERNAL) |
27 | #define M_EXTERNAL(ori) (ori == TopAbs_EXTERNAL) |
28 | |
29 | #define FORWARD (1) |
30 | #define REVERSED (2) |
31 | #define INTERNAL (3) |
32 | #define EXTERNAL (4) |
33 | #define CLOSING (5) |
34 | |
35 | #ifdef DEB |
36 | Standard_IMPORT Standard_Boolean TopOpeBRepTool_GettraceREGUSO(); |
37 | static TopTools_IndexedMapOfShape STATIC_mape, STATIC_mapf, STATIC_mapw, STATIC_mapsh; |
38 | static Standard_Integer FUN_adds(const TopoDS_Shape& s) { |
39 | TopAbs_ShapeEnum typ = s.ShapeType(); |
40 | TCollection_AsciiString aa; Standard_Integer is = 0; |
41 | if (typ == TopAbs_SHELL) {aa = TCollection_AsciiString("s"); is = STATIC_mapsh.Add(s);} |
42 | if (typ == TopAbs_WIRE) {aa = TCollection_AsciiString("w"); is = STATIC_mapw.Add(s); } |
43 | if (typ == TopAbs_FACE) {aa = TCollection_AsciiString("f"); is = STATIC_mapf.Add(s); } |
44 | if (typ == TopAbs_EDGE) {aa = TCollection_AsciiString("e"); is = STATIC_mape.Add(s); } |
45 | #ifdef DRAW |
46 | Standard_Boolean trc = TopOpeBRepTool_GettraceREGUSO(); |
47 | if (trc) FUN_tool_draw(aa,s,is); |
48 | #endif |
49 | return is; |
50 | } |
51 | #endif |
52 | |
53 | static void FUN_Raise() |
54 | { |
55 | #ifdef DEB |
56 | Standard_Boolean trc = TopOpeBRepTool_GettraceREGUSO(); |
57 | if (trc) cout<<"***** Failure in REGUS **********"<<endl; |
58 | // Standard_Failure::Raise("REGUS"); |
59 | #endif |
60 | } |
61 | |
62 | //======================================================================= |
63 | //function : Create |
64 | //purpose : |
65 | //======================================================================= |
66 | |
67 | TopOpeBRepTool_REGUS::TopOpeBRepTool_REGUS() |
68 | { |
69 | hasnewsplits = Standard_False; |
70 | mynF = myoldnF = 0; |
71 | |
72 | myFsplits.Clear(); |
73 | myOshNsh.Clear(); |
74 | |
75 | myS.Nullify(); |
76 | mymapeFs.Clear(); |
77 | mymapeFsstatic.Clear(); |
78 | mymapemult.Clear(); |
79 | |
80 | myedstoconnect.Clear(); |
81 | } |
82 | |
83 | //======================================================================= |
84 | //function : Init |
85 | //purpose : |
86 | //======================================================================= |
87 | |
88 | void TopOpeBRepTool_REGUS::Init(const TopoDS_Shape& S) |
89 | { |
90 | hasnewsplits = Standard_False; |
91 | |
92 | mynF = myoldnF = 0; |
93 | myS = S; |
94 | |
95 | mymapeFs.Clear(); |
96 | mymapeFsstatic.Clear(); |
97 | mymapemult.Clear(); |
98 | myedstoconnect.Clear(); |
99 | } |
100 | |
101 | //======================================================================= |
102 | //function : S |
103 | //purpose : |
104 | //======================================================================= |
105 | |
106 | const TopoDS_Shape& TopOpeBRepTool_REGUS::S() const |
107 | { |
108 | return myS; |
109 | } |
110 | |
111 | |
112 | //======================================================================= |
113 | //function : SetFsplits |
114 | //purpose : |
115 | //======================================================================= |
116 | |
117 | void TopOpeBRepTool_REGUS::SetFsplits(TopTools_DataMapOfShapeListOfShape& Fsplits) |
118 | { |
119 | myFsplits = Fsplits; |
120 | } |
121 | //======================================================================= |
122 | //function : GetFsplits |
123 | //purpose : |
124 | //======================================================================= |
125 | |
126 | void TopOpeBRepTool_REGUS::GetFsplits(TopTools_DataMapOfShapeListOfShape& Fsplits) const |
127 | { |
128 | Fsplits = myFsplits; |
129 | } |
130 | |
131 | //======================================================================= |
132 | //function : SetOshNsh |
133 | //purpose : |
134 | //======================================================================= |
135 | |
136 | void TopOpeBRepTool_REGUS::SetOshNsh(TopTools_DataMapOfShapeListOfShape& OshNsh) |
137 | { |
138 | myOshNsh = OshNsh; |
139 | } |
140 | //======================================================================= |
141 | //function : GetOshNsh |
142 | //purpose : |
143 | //======================================================================= |
144 | |
145 | void TopOpeBRepTool_REGUS::GetOshNsh(TopTools_DataMapOfShapeListOfShape& OshNsh) const |
146 | { |
147 | OshNsh = myOshNsh; |
148 | } |
149 | |
150 | //======================================================================= |
151 | //function : MapS |
152 | //purpose : |
153 | //======================================================================= |
154 | |
155 | Standard_Boolean TopOpeBRepTool_REGUS::MapS() |
156 | { |
157 | #ifdef DEB |
158 | Standard_Boolean trc = TopOpeBRepTool_GettraceREGUSO(); |
159 | Standard_Integer ish = FUN_adds(S()); |
160 | if (trc) cout<<"** MAPPING ** shape"<<ish<<endl; |
161 | #endif |
162 | |
163 | // mymapeFs, myoldnF : |
164 | myoldnF = 0; |
165 | TopExp_Explorer exf(myS, TopAbs_FACE); |
166 | for (; exf.More(); exf.Next()){ |
167 | const TopoDS_Shape& f = exf.Current(); myoldnF++; |
168 | |
169 | TopExp_Explorer exe(f, TopAbs_EDGE); |
170 | for (; exe.More(); exe.Next()){ |
171 | const TopoDS_Shape& e = exe.Current(); |
172 | Standard_Boolean isb = mymapeFs.IsBound(e); |
173 | if (isb) {mymapeFs.ChangeFind(e).Append(f); mymapeFsstatic.ChangeFind(e).Append(f);} |
174 | else {TopTools_ListOfShape lof; lof.Append(f); mymapeFs.Bind(e,lof); mymapeFsstatic.Bind(e,lof);} |
175 | }//exe |
176 | }//exf |
177 | mynF = myoldnF; |
178 | |
179 | // mymapemult : |
180 | TopTools_DataMapIteratorOfDataMapOfShapeListOfShape itm(mymapeFs); |
181 | for (; itm.More(); itm.Next()){ |
182 | const TopoDS_Shape& e = itm.Key(); |
183 | const TopTools_ListOfShape& lof = itm.Value(); |
184 | Standard_Integer nf = lof.Extent(); |
185 | if (nf > 2) mymapemult.Add(e); |
186 | #ifdef DEB |
187 | if (trc) { |
188 | cout <<"co(e"<<FUN_adds(e)<<")= "; |
189 | TopTools_ListIteratorOfListOfShape it(lof); |
190 | for (; it.More(); it.Next())cout<<" f"<<FUN_adds(it.Value()); |
191 | cout<<endl;} |
192 | #endif |
193 | }//itm(mymapeFs) |
194 | return Standard_True; |
195 | } |
196 | |
197 | //======================================================================= |
198 | //function : WireToFace |
199 | //purpose : |
200 | //======================================================================= |
201 | |
202 | Standard_Boolean TopOpeBRepTool_REGUS::WireToFace(const TopoDS_Face& Fanc, const TopTools_ListOfShape& nWs, TopTools_ListOfShape& nFs) |
203 | { |
204 | #ifdef DEB |
205 | Standard_Boolean trc = TopOpeBRepTool_GettraceREGUSO(); |
206 | #endif |
207 | nFs.Clear(); |
208 | TopTools_DataMapOfShapeListOfShape mapWlow; |
209 | TopoDS_Shape aLocalShape = Fanc.Oriented(TopAbs_FORWARD); |
210 | TopoDS_Face aFace = TopoDS::Face(aLocalShape); |
211 | // TopoDS_Face aFace = TopoDS::Face(Fanc.Oriented(TopAbs_FORWARD)); |
212 | TopOpeBRepTool_CLASSI classi; classi.Init2d(aFace); |
213 | |
214 | Standard_Boolean classifok = classi.Classilist(nWs,mapWlow); |
215 | if (!classifok) { |
216 | #ifdef DEB |
217 | if (trc) cout<<"** classif fails"<<endl; |
218 | #endif |
219 | return Standard_False; |
220 | } |
221 | |
222 | Standard_Boolean facesbuilt = TopOpeBRepTool_TOOL::WireToFace(Fanc, mapWlow, nFs); |
223 | if (!facesbuilt) { |
224 | #ifdef DEB |
225 | if (trc) cout<<"** facesbuilt fails"<<endl; |
226 | #endif |
227 | return Standard_False; |
228 | } |
229 | return Standard_True; |
230 | } |
231 | |
232 | |
233 | //======================================================================= |
234 | //function : SplitF |
235 | //purpose : |
236 | //======================================================================= |
237 | |
238 | Standard_Boolean TopOpeBRepTool_REGUS::SplitF(const TopoDS_Face& Fanc, TopTools_ListOfShape& FSplits) |
239 | { |
240 | // prequesitory : All edges have already been splitted, there is no |
241 | // internal vertex on edge, except for internal edge. |
242 | TopAbs_Orientation oAnc = Fanc.Orientation(); |
243 | TopoDS_Shape aLocalShape = Fanc.Oriented(TopAbs_FORWARD); |
244 | TopoDS_Face aFace = TopoDS::Face(aLocalShape); |
245 | // TopoDS_Face aFace = TopoDS::Face(Fanc.Oriented(TopAbs_FORWARD)); |
246 | |
247 | FSplits.Clear(); |
248 | |
249 | TopOpeBRepTool_REGUW REGUW(aFace); |
250 | |
251 | TopTools_ListOfShape nWs; Standard_Boolean hassp = Standard_False; |
252 | TopExp_Explorer exw(aFace, TopAbs_WIRE); |
253 | for (; exw.More(); exw.Next()) { |
254 | const TopoDS_Shape& w = exw.Current(); |
255 | REGUW.Init(w); |
256 | REGUW.MapS(); |
257 | |
258 | TopTools_ListOfShape eIs; |
259 | // -------- |
260 | TopExp_Explorer exe(w, TopAbs_EDGE); |
261 | for (; exe.More(); exe.Next()){ |
262 | const TopoDS_Shape& e = exe.Current(); |
263 | if (M_INTERNAL(e.Orientation())) eIs.Append(e); |
264 | }//exe |
265 | |
266 | TopTools_ListIteratorOfListOfShape ite(eIs); |
267 | // if (!ite.More()) {nWs.Append(w); continue;} |
268 | |
269 | while (ite.More()) { |
270 | const TopoDS_Edge& eI = TopoDS::Edge(ite.Value()); |
271 | TopoDS_Vertex vf,vl; |
272 | TopoDS_Shape aLocalShape = eI.Oriented(TopAbs_FORWARD); |
273 | TopExp::Vertices(TopoDS::Edge(aLocalShape),vf,vl); |
274 | // TopExp::Vertices(TopoDS::Edge(eI.Oriented(TopAbs_FORWARD)),vf,vl); |
275 | TopOpeBRepTool_connexity cof; REGUW.Connexity(vf,cof); TopTools_ListOfShape lef; Standard_Integer nef = cof.AllItems(lef); |
276 | TopOpeBRepTool_connexity col; REGUW.Connexity(vl,col); TopTools_ListOfShape lel; Standard_Integer nel = col.AllItems(lel); |
277 | if ((nef <= 1)||(nel <= 1)) {eIs.Remove(ite);continue;} |
278 | |
279 | // prequesitory : we do not have internal vertices in edges oriented FOR |
280 | aLocalShape = eI.Oriented(TopAbs_REVERSED); |
281 | TopoDS_Edge eR = TopoDS::Edge(aLocalShape); |
282 | aLocalShape = eI.Oriented(TopAbs_FORWARD); |
283 | TopoDS_Edge eF = TopoDS::Edge(aLocalShape); |
284 | // TopoDS_Edge eR = TopoDS::Edge(eI.Oriented(TopAbs_REVERSED)); |
285 | // TopoDS_Edge eF = TopoDS::Edge(eI.Oriented(TopAbs_FORWARD)); |
286 | |
287 | TopExp_Explorer exv(eI, TopAbs_VERTEX); |
288 | for (; exv.More(); exv.Next()){ |
289 | const TopoDS_Vertex& v = TopoDS::Vertex(exv.Current()); |
290 | Standard_Boolean ok = REGUW.RemoveOldConnexity(v,INTERNAL,eI); |
291 | if (!ok) return Standard_False; |
292 | Standard_Integer ivF = TopOpeBRepTool_TOOL::OriinSor(v,eF); |
293 | ok = REGUW.AddNewConnexity(v,ivF,eF); |
294 | if (!ok) return Standard_False; |
295 | Standard_Integer ivR = TopOpeBRepTool_TOOL::OriinSor(v,eR); |
296 | ok = REGUW.AddNewConnexity(v,ivR,eR); |
297 | if (!ok) return Standard_False; |
298 | ok = REGUW.UpdateMultiple(v); |
299 | if (!ok) return Standard_False; |
300 | }//exv |
301 | ite.Next(); |
302 | }//ite(eIs) |
303 | |
304 | // now all edges of <eIs> are INTERNAL edges of <w> |
305 | // their 2 bounds are of connexity > 1. |
306 | // if (eIs.IsEmpty()) {nWs.Append(w); continue;} |
307 | |
308 | TopTools_ListOfShape spW; |
309 | // -------- |
310 | Standard_Boolean spok = REGUW.REGU(); // only first step |
311 | if (!spok) {FUN_Raise(); return Standard_False;} |
312 | REGUW.GetSplits(spW); |
313 | if (!spW.IsEmpty()) {nWs.Append(spW); hassp = Standard_True;} |
314 | }//exw |
315 | |
316 | if (!hassp) return Standard_False; |
317 | TopTools_ListOfShape nFs; Standard_Boolean ok = TopOpeBRepTool_REGUS::WireToFace(aFace, nWs,nFs); |
318 | if (!ok) {FUN_Raise(); return Standard_False;} |
319 | |
320 | TopTools_ListIteratorOfListOfShape itf(nFs); |
321 | for (; itf.More(); itf.Next()) FSplits.Append(itf.Value().Oriented(oAnc)); |
322 | return Standard_True; |
323 | } |
324 | |
325 | //======================================================================= |
326 | //function : SplitFaces |
327 | //purpose : |
328 | //======================================================================= |
329 | |
330 | Standard_Boolean TopOpeBRepTool_REGUS::SplitFaces() |
331 | { |
332 | #ifdef DEB |
333 | Standard_Boolean trc = TopOpeBRepTool_GettraceREGUSO(); |
334 | Standard_Integer ish = FUN_adds(S()); |
335 | if (trc) cout<<"** SPLITTING FACES ** shape"<<ish<<endl; |
336 | #endif |
337 | TopExp_Explorer exf(myS, TopAbs_FACE); |
338 | for (; exf.More(); exf.Next()){ |
339 | |
340 | // splitting face : |
341 | const TopoDS_Face& f = TopoDS::Face(exf.Current()); |
342 | TopTools_ListOfShape lfsp; Standard_Boolean issp = TopOpeBRepTool_REGUS::SplitF(f,lfsp); |
343 | #ifdef DEB |
344 | Standard_Integer nf = |
345 | #endif |
346 | lfsp.Extent(); |
347 | if (!issp) continue; |
348 | |
349 | myFsplits.Bind(f,lfsp); |
350 | |
351 | // updating the map of connexity : |
352 | // f -> lfsp = {fsp} |
353 | mynF--; |
354 | TopTools_ListIteratorOfListOfShape itf(lfsp); |
355 | for (; itf.More(); itf.Next()){ |
356 | const TopoDS_Shape& fsp = itf.Value(); mynF++; |
357 | |
358 | TopExp_Explorer exe(fsp, TopAbs_EDGE); |
359 | for (; exe.More(); exe.Next()) { |
360 | // fsp -> {e} |
361 | const TopoDS_Shape& e = exe.Current(); |
362 | Standard_Boolean isb = mymapeFs.IsBound(e); |
363 | if (!isb) {FUN_Raise(); return Standard_False;} |
364 | |
365 | // <mymapeFs> |
366 | TopTools_ListOfShape& lof = mymapeFs.ChangeFind(e); |
367 | TopOpeBRepTool_TOOL::Remove(lof,f); |
368 | lof.Append(fsp); |
369 | |
370 | // <mymapemult> |
371 | Standard_Integer nf = lof.Extent(); |
372 | if (nf > 2) mymapemult.Add(e); |
373 | }//exe(fsp) |
374 | }//itf(lfsp) |
375 | |
376 | #ifdef DEB |
377 | if (trc) { |
378 | cout <<"split(f"<<FUN_adds(f)<<")= "; |
379 | TopTools_ListIteratorOfListOfShape it(lfsp); |
380 | for (; it.More(); it.Next()) cout<<" f"<<FUN_adds(it.Value()); |
381 | cout<<endl;} |
382 | #endif |
383 | }//exf(myS) |
384 | return Standard_True; |
385 | } |
386 | |
387 | static void FUN_update(const TopoDS_Shape& fcur, TopTools_MapOfShape& edstoconnect) |
388 | // purpose : <e> edge of <fcur> |
389 | // 1. <e> is INTERNAL or EXTERNAL -> nothing is done |
390 | // 2. <e> is closing edge of <fcur> -> nothing is done |
391 | // 3. <e> is already bound in <edstoconnect> -> remove it from the map |
392 | // (then has 2 ancestor faces stored in the current Block) |
393 | // 4. elsewhere, add it in the map. |
394 | // |
395 | // !! if <fcur> is INTERNAL/EXTERNAL -> nothing is done |
396 | { |
397 | TopAbs_Orientation ofcur = fcur.Orientation(); |
398 | if (M_INTERNAL(ofcur) || M_EXTERNAL(ofcur)) return; |
399 | |
400 | TopExp_Explorer exe(fcur, TopAbs_EDGE); |
401 | for (; exe.More(); exe.Next()){ |
402 | const TopoDS_Shape& e = exe.Current(); |
403 | TopAbs_Orientation oe = e.Orientation(); |
404 | if (M_INTERNAL(oe) || M_EXTERNAL(oe)) continue; |
405 | |
406 | Standard_Boolean isclo = TopOpeBRepTool_TOOL::IsClosingE(TopoDS::Edge(e),TopoDS::Face(fcur)); |
407 | if (isclo) continue; |
408 | |
409 | Standard_Boolean isb = edstoconnect.Contains(e); |
410 | if (isb) edstoconnect.Remove(e); |
411 | else edstoconnect.Add(e); |
412 | }//exe |
413 | } |
414 | |
415 | //======================================================================= |
416 | //function : REGU |
417 | //purpose : |
418 | //======================================================================= |
419 | |
420 | Standard_Boolean TopOpeBRepTool_REGUS::REGU() |
421 | { |
422 | #ifdef DEB |
423 | Standard_Boolean trc = TopOpeBRepTool_GettraceREGUSO(); |
424 | Standard_Integer ishe = FUN_adds(myS); |
425 | if (trc) cout<<"** REGU **"<<ishe<<endl; |
426 | #endif |
427 | TopTools_ListOfShape Splits; |
428 | Standard_Boolean toregu = !mymapemult.IsEmpty() || (mynF != myoldnF); |
429 | if (!toregu) return Standard_False; |
430 | |
431 | // purpose : myS -> {Blocks}, |
432 | // a Block is a closed shell with "valid" edges. |
433 | // - a valid edge in a Block has at most two ancestor faces - |
434 | // |
435 | // Give us the starting couple (<ei>, <fi>) : |
436 | // * If <ei> has only one untouched ancestor face <fj> left, fj+1 <- fj |
437 | // Else among the untouched ancestors faces, we choose the one for which |
438 | // angle (<veci>, <vecj>) is the smallest; providing face <fj> reduces |
439 | // the matter described by <fi>. |
440 | // * update <mymapeFs> for <ei> (<fj> as touched). |
441 | // * Update <mymapemult> for <fi>'s bound edges : |
442 | // - if bound edge is not in the map, add it. |
443 | // - else if bound edge has two ancestor faces in current list <mylFinBlock>, |
444 | // delete it form the map. |
445 | // |
446 | // TopTools_ListOfShape lFinBlock; // <lFinBlock> describes a valid closed shell when <myedstoconnect> is emptied. |
447 | mylFinBlock.Clear(); |
448 | Standard_Integer nite = 0; |
449 | while (nite <= mynF) { |
450 | Standard_Boolean startBlock = mylFinBlock.IsEmpty(); |
451 | Standard_Boolean endBlock = myedstoconnect.IsEmpty() && (!startBlock); |
452 | |
453 | #ifdef DEB |
454 | Standard_Boolean tr=Standard_False; |
455 | if (tr) { |
456 | TopTools_MapIteratorOfMapOfShape it(myedstoconnect); |
457 | cout<<"still to connect : "; |
458 | for (; it.More(); it.Next()) cout<<" e"<<FUN_adds(it.Key()); |
459 | cout<<endl; |
460 | } |
461 | #endif |
462 | |
463 | //* endBlock |
464 | // --------- |
465 | if (endBlock) { |
466 | // building up shell on <mylFinBlock> |
467 | Standard_Integer nFcur = mylFinBlock.Extent(); |
468 | Standard_Boolean unchanged = (nFcur==myoldnF) && (mynF==myoldnF); |
469 | if (unchanged) { |
470 | #ifdef DEB |
471 | if (trc) cout<<"#** shell"<<ishe<<" valid\n"; |
472 | #endif |
473 | return Standard_False; // nyi analysis if we should raise or not |
474 | } |
475 | else { |
476 | TopoDS_Shell newShe; TopOpeBRepTool_TOOL::MkShell(mylFinBlock,newShe); |
477 | Splits.Append(newShe); |
478 | #ifdef DEB |
479 | if (trc) {cout<<"#** shell "<<ishe<<" gives new shell "<<FUN_adds(newShe)<<endl; |
480 | for (TopTools_ListIteratorOfListOfShape it(mylFinBlock); it.More(); it.Next()) cout <<";dins f"<<FUN_adds(it.Value()); |
481 | cout<<endl<<endl;} |
482 | #endif |
483 | mylFinBlock.Clear(); |
484 | startBlock = Standard_True; |
485 | } |
486 | }//endBlock |
487 | |
488 | //* all faces touched |
489 | // ------------------ |
490 | Standard_Boolean FINI = (nite == mynF); |
491 | if (FINI) break; |
492 | |
493 | Standard_Integer advance=Standard_False; |
494 | //* initializing a new Block |
495 | // ------------------------- |
496 | if (startBlock || endBlock) { |
497 | advance = InitBlock(); |
498 | if (!advance) return Standard_False; |
499 | }//startBlock||endBlock |
500 | |
501 | //* choosing next face |
502 | // ------------------- |
503 | else { |
504 | advance = NextinBlock(); |
505 | } |
506 | |
507 | // ** updating connexity |
508 | ::FUN_update(myf,myedstoconnect); |
509 | |
510 | if (!advance) { |
511 | endBlock = myedstoconnect.IsEmpty() && (!startBlock); |
512 | if (!endBlock) return Standard_False; |
513 | else continue; |
514 | } |
515 | |
516 | TopExp_Explorer exe(myf, TopAbs_EDGE); |
517 | for (; exe.More(); exe.Next()){ |
518 | const TopoDS_Shape& e = exe.Current(); |
519 | Standard_Boolean isb = mymapeFs.IsBound(e); |
520 | if (!isb) continue; // ancestors faces of <e> are stored in Blocks |
521 | TopOpeBRepTool_TOOL::Remove(mymapeFs.ChangeFind(e),myf); |
522 | }//exe |
523 | |
524 | mylFinBlock.Append(myf); nite++; |
525 | }//nite <= mynF |
526 | |
527 | myOshNsh.Bind(S(), Splits); |
528 | return Standard_True; |
529 | } |
530 | |
531 | //======================================================================= |
532 | //function : InitBlock |
533 | //purpose : |
534 | //======================================================================= |
535 | |
536 | Standard_Boolean TopOpeBRepTool_REGUS::InitBlock() |
537 | { |
538 | Standard_Integer nec = myedstoconnect.Extent(); |
539 | if (nec != 0) return Standard_False; // should be empty |
540 | |
541 | TopTools_ListOfShape eds; |
542 | TopTools_DataMapIteratorOfDataMapOfShapeListOfShape itm(mymapeFs); |
543 | for (; itm.More(); itm.Next()) eds.Append(itm.Key()); |
544 | |
545 | TopTools_ListIteratorOfListOfShape ite(eds); |
546 | for (; ite.More(); ite.Next()){ |
547 | const TopoDS_Shape& e = ite.Value(); |
548 | const TopTools_ListOfShape& lof = mymapeFs.Find(e); |
549 | if (lof.IsEmpty()) {mymapeFs.UnBind(e); continue;} |
550 | myf = lof.First(); |
551 | #ifdef DEB |
552 | Standard_Boolean trc = TopOpeBRepTool_GettraceREGUSO(); |
553 | if (trc) cout<<"* Block : first face = f"<<FUN_adds(myf)<<endl; |
554 | #endif |
555 | return Standard_True; |
556 | } |
557 | return Standard_False; |
558 | } |
559 | |
560 | //======================================================================= |
561 | //function : NextinBlock |
562 | //purpose : |
563 | //======================================================================= |
564 | |
565 | Standard_Boolean TopOpeBRepTool_REGUS::NextinBlock() |
566 | { |
567 | #ifdef DEB |
568 | Standard_Boolean trc = TopOpeBRepTool_GettraceREGUSO(); |
569 | #endif |
570 | // we try to connect first edge of <myf> bound in <myedstoconnect> |
571 | TopTools_ListOfShape eds; |
572 | TopExp_Explorer exe(myf, TopAbs_EDGE); |
573 | for (; exe.More(); exe.Next()){ |
574 | const TopoDS_Shape& e = exe.Current(); |
575 | Standard_Boolean isb = myedstoconnect.Contains(e); |
576 | if (isb) eds.Append(e); |
577 | }//exe |
578 | Standard_Boolean alleftouched = eds.IsEmpty(); |
579 | if (alleftouched) { |
580 | TopTools_MapIteratorOfMapOfShape itc(myedstoconnect); |
581 | for (; itc.More(); itc.Next()){ |
582 | const TopoDS_Shape& e = itc.Key(); |
583 | Standard_Boolean isb = mymapeFs.IsBound(e); |
584 | // all ancestor faces of <e> have been stored |
585 | if (!isb) {myedstoconnect.Remove(e); continue;} |
586 | |
587 | const TopTools_ListOfShape& lof = mymapeFs.Find(e); Standard_Integer nf = lof.Extent(); |
588 | if (nf == 0) {myedstoconnect.Remove(e); mymapeFs.UnBind(e); |
589 | continue;} |
590 | |
591 | // myf = lof.First(); 130499 |
592 | if (lof.Extent() == 1) myf = lof.First(); |
593 | else { |
594 | // looking for first face stored in the current block |
595 | // connexed to e |
596 | |
597 | TopTools_ListIteratorOfListOfShape itff(mylFinBlock); |
598 | TopTools_MapOfShape mapf;for (; itff.More(); itff.Next()) mapf.Add(itff.Value()); |
599 | // lofc : the list of faces connexed to e in <myS> |
600 | // lof : the list of untouched faces connexed to e in <myS> |
601 | const TopTools_ListOfShape& lofc = mymapeFsstatic.Find(e); |
602 | #ifdef DEB |
603 | Standard_Integer nfc = |
604 | #endif |
605 | lofc.Extent(); |
606 | itff.Initialize(lofc); |
607 | TopoDS_Face fref; |
608 | for (; itff.More(); itff.Next()) { |
609 | const TopoDS_Face& fc = TopoDS::Face(itff.Value()); |
610 | Standard_Boolean isb = mapf.Contains(fc); |
611 | if (isb) {fref = fc; break;} |
612 | } // itff(lofc) |
613 | if (fref.IsNull()) { |
614 | return Standard_False; // !!!!!!!!!! a revoir 130499 |
615 | } |
616 | else { |
617 | myf = fref; |
618 | TopoDS_Face ffound; Standard_Boolean ok = NearestF(TopoDS::Edge(e),lof,ffound); |
619 | if (!ok) return Standard_False; |
620 | myf = ffound; |
621 | } |
622 | } |
623 | |
624 | return Standard_True; |
625 | } |
626 | return Standard_False; |
627 | } |
628 | |
629 | TopTools_ListIteratorOfListOfShape ite(eds); |
630 | for (; ite.More(); ite.Next()){ |
631 | const TopoDS_Shape& e = ite.Value(); |
632 | Standard_Boolean isb = mymapeFs.IsBound(e); |
633 | // all ancestor faces of <e> have been stored |
634 | if (!isb) {myedstoconnect.Remove(e); continue;} |
635 | |
636 | const TopTools_ListOfShape& lof = mymapeFs.Find(e); Standard_Integer nf = lof.Extent(); |
637 | if (nf == 0) {myedstoconnect.Remove(e); mymapeFs.UnBind(e); |
638 | continue;} |
639 | #ifdef DEB |
640 | if (trc) {cout<<"e"<<FUN_adds(e)<<" on "<<nf<<" untouched f:"<<endl;} |
641 | #endif |
642 | if (nf == 1) myf = lof.First(); |
643 | else { |
644 | TopoDS_Face ffound; Standard_Boolean ok = NearestF(TopoDS::Edge(e),lof,ffound); |
645 | if (!ok) return Standard_False; |
646 | myf = ffound; |
647 | } |
648 | #ifdef DEB |
649 | if (trc) cout<<"->myf = f"<<FUN_adds(myf)<<endl; |
650 | #endif |
651 | return Standard_True; |
652 | }//itm(myedstoconnect) |
653 | return Standard_False; |
654 | } |
655 | |
656 | static Standard_Boolean FUN_vectors(const TopoDS_Face& f, const TopoDS_Edge& e, const Standard_Real pare, |
657 | gp_Dir& nt, gp_Dir& xx, const Standard_Real tola, const Standard_Boolean approx) |
658 | { |
659 | // <nt> : |
660 | if (approx) { |
661 | Standard_Boolean ok = TopOpeBRepTool_TOOL::tryNgApp(pare,e,f,tola,nt); |
662 | if (!ok) return Standard_False; |
663 | } |
664 | else { |
665 | gp_Vec tmp; Standard_Boolean ok = FUN_tool_nggeomF(pare,e,f,tmp); |
666 | if (!ok) return Standard_False; |
667 | nt = gp_Dir(tmp); |
668 | } |
669 | if (M_REVERSED(f.Orientation())) nt.Reverse(); |
670 | // <xx> : |
671 | Standard_Boolean ok = FUN_tool_getxx(f,e,pare,xx); |
672 | if (!ok) return Standard_False; |
673 | return Standard_True; |
674 | } |
675 | |
676 | //======================================================================= |
677 | //function : NearestF |
678 | //purpose : |
679 | //======================================================================= |
680 | |
681 | Standard_Boolean TopOpeBRepTool_REGUS::NearestF(const TopoDS_Edge& e, const TopTools_ListOfShape& lof, TopoDS_Face& ffound) const |
682 | // prequesitory : <e> is shared by <myf> and faces of <lof>. |
683 | // |
684 | // NYIXPU!!!!!!!! if (xx1 tg xx2) -> use curvatures |
685 | // |
686 | { |
687 | #ifdef DEB |
688 | Standard_Boolean trc = TopOpeBRepTool_GettraceREGUSO(); |
689 | #endif |
690 | ffound.Nullify(); |
691 | TopoDS_Face fref = TopoDS::Face(myf); |
692 | #ifdef DEB |
693 | Standard_Integer nf = |
694 | #endif |
695 | lof.Extent();//deb |
696 | |
697 | // Give us egde <e>, and a reference face <fref> (= <myf>) |
698 | // - parameter on <e> = <pare>. |
699 | // - xxi = tangent fo face fi at pnt(e,pare) oriented INSIDE 2d(fi) |
700 | // normal to tge = tg(e,pare). |
701 | // purpose : looking for ffound / |
702 | // MatterAng(xxref, xxfound) = Min{ MatterAng(xxref, xxi), xxi for fi in <lof> |
703 | // providing fi reduces 3d(fref) } |
704 | |
705 | // <parone> : |
706 | Standard_Real f,l; FUN_tool_bounds(e,f,l); Standard_Real eps = 0.45678; Standard_Real pare = (1-eps)*f+eps*l; |
707 | |
708 | // RONd (x,y,z) = (xxref,ntref,x^y) |
709 | Standard_Real tola = Precision::Angular()*1.e3; //gp_Dir xapp,yapp; Standard_Boolean refapp = Standard_False; |
710 | gp_Dir x,y; Standard_Boolean ok = ::FUN_vectors(fref,e,pare,y,x,tola,Standard_False); |
711 | if (!ok) {FUN_Raise(); return Standard_False;} |
712 | #ifdef DEB |
713 | gp_Dir z = x^y; |
714 | #endif |
715 | |
716 | // initializing |
717 | // ------------ |
718 | Standard_Real angfound = 0; |
719 | TopTools_ListIteratorOfListOfShape itf(lof); |
720 | for (; itf.More(); itf.Next()){ |
721 | ffound = TopoDS::Face(itf.Value()); |
722 | gp_Dir ntfound,xxfound; |
723 | ok = ::FUN_vectors(ffound,e,pare,ntfound,xxfound,tola,Standard_False); |
724 | if (!ok) {FUN_Raise(); return Standard_False;} |
725 | |
726 | Standard_Boolean oppo = TopOpeBRepTool_TOOL::Matter(x,y,xxfound,ntfound,tola, angfound); |
727 | #ifdef DEB |
728 | if (trc&&!oppo) cout<<" f"<<FUN_adds(fref)<<",f"<<FUN_adds(ffound)<<" not oppo"<<endl; |
729 | #endif |
730 | if (!oppo) {ffound.Nullify(); continue;} |
731 | |
732 | if (angfound < tola) { |
733 | // refapp = Standard_True; ::FUN_vectors(fref,e,pare,yapp,xapp,tola,Standard_True); |
734 | // ::FUN_vectors(ffound,e,pare,ntfound,xxfound,tola,Standard_True); |
735 | // TopOpeBRepTool_TOOL::Matter(xapp,yapp,xxfound,ntfound,tola, angfound); |
736 | ok = TopOpeBRepTool_TOOL::MatterKPtg(fref,ffound,e,angfound); |
737 | if (!ok) {FUN_Raise(); return Standard_False;} |
738 | } |
739 | #ifdef DEB |
740 | if (trc) cout<<" ang("<<"f"<<FUN_adds(fref)<<",f"<<FUN_adds(ffound)<<")="<<angfound<<endl; |
741 | #endif |
742 | break; |
743 | } |
744 | if (ffound.IsNull()) {FUN_Raise(); return Standard_False;} |
745 | if (itf.More()) itf.Next(); |
746 | else return Standard_True; |
747 | |
748 | // selecting nearest face |
749 | // ---------------------- |
750 | for (; itf.More(); itf.Next()){ |
751 | gp_Dir nti,xxi; |
752 | const TopoDS_Face& fi = TopoDS::Face(itf.Value()); |
753 | ok = ::FUN_vectors(fi,e,pare,nti,xxi,tola,Standard_False); |
754 | if (!ok) {FUN_Raise(); return Standard_False;} |
755 | |
756 | Standard_Real angi = 0; |
757 | Standard_Boolean oppo = TopOpeBRepTool_TOOL::Matter(x,y,xxi,nti,tola, angi); |
758 | #ifdef DEB |
759 | if (trc&&!oppo) cout<<" f"<<FUN_adds(fref)<<",f"<<FUN_adds(fi)<<" not oppo"<<endl; |
760 | #endif |
761 | if (!oppo) continue; |
762 | |
763 | if (angi < tola) { |
764 | // if (!refapp) ::FUN_vectors(fref,e,pare,yapp,xapp,tola,Standard_True); |
765 | // ::FUN_vectors(fi,e,pare,nti,xxi,tola,Standard_True); |
766 | // TopOpeBRepTool_TOOL::Matter(xapp,yapp,xxi,nti,tola, angi); |
767 | ok = TopOpeBRepTool_TOOL::MatterKPtg(fref,fi,e,angi); |
768 | if (!ok) {FUN_Raise(); return Standard_False;} |
769 | } |
770 | #ifdef DEB |
771 | if (trc) cout<<" ang("<<"f"<<FUN_adds(fref)<<",f"<<FUN_adds(fi)<<")="<<angi<<endl; |
772 | #endif |
773 | if (angi > angfound) continue; |
774 | angfound = angi; |
775 | ffound = fi; |
776 | } |
777 | return Standard_True; |
778 | } |
779 | |
780 | |
781 | |