0022922: Clean up warnings on uninitialized / unused variables
[occt.git] / src / TopOpeBRepTool / TopOpeBRepTool_REGUS.cxx
CommitLineData
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
36Standard_IMPORT Standard_Boolean TopOpeBRepTool_GettraceREGUSO();
37static TopTools_IndexedMapOfShape STATIC_mape, STATIC_mapf, STATIC_mapw, STATIC_mapsh;
38static 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
53static 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
67TopOpeBRepTool_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
88void 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
106const TopoDS_Shape& TopOpeBRepTool_REGUS::S() const
107{
108 return myS;
109}
110
111
112//=======================================================================
113//function : SetFsplits
114//purpose :
115//=======================================================================
116
117void TopOpeBRepTool_REGUS::SetFsplits(TopTools_DataMapOfShapeListOfShape& Fsplits)
118{
119 myFsplits = Fsplits;
120}
121//=======================================================================
122//function : GetFsplits
123//purpose :
124//=======================================================================
125
126void TopOpeBRepTool_REGUS::GetFsplits(TopTools_DataMapOfShapeListOfShape& Fsplits) const
127{
128 Fsplits = myFsplits;
129}
130
131//=======================================================================
132//function : SetOshNsh
133//purpose :
134//=======================================================================
135
136void TopOpeBRepTool_REGUS::SetOshNsh(TopTools_DataMapOfShapeListOfShape& OshNsh)
137{
138 myOshNsh = OshNsh;
139}
140//=======================================================================
141//function : GetOshNsh
142//purpose :
143//=======================================================================
144
145void TopOpeBRepTool_REGUS::GetOshNsh(TopTools_DataMapOfShapeListOfShape& OshNsh) const
146{
147 OshNsh = myOshNsh;
148}
149
150//=======================================================================
151//function : MapS
152//purpose :
153//=======================================================================
154
155Standard_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
202Standard_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
238Standard_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
330Standard_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);
6e6cd5d9 343
7fd59977 344 if (!issp) continue;
345
346 myFsplits.Bind(f,lfsp);
347
348 // updating the map of connexity :
349 // f -> lfsp = {fsp}
350 mynF--;
351 TopTools_ListIteratorOfListOfShape itf(lfsp);
352 for (; itf.More(); itf.Next()){
353 const TopoDS_Shape& fsp = itf.Value(); mynF++;
354
355 TopExp_Explorer exe(fsp, TopAbs_EDGE);
356 for (; exe.More(); exe.Next()) {
357 // fsp -> {e}
358 const TopoDS_Shape& e = exe.Current();
359 Standard_Boolean isb = mymapeFs.IsBound(e);
360 if (!isb) {FUN_Raise(); return Standard_False;}
361
362 // <mymapeFs>
363 TopTools_ListOfShape& lof = mymapeFs.ChangeFind(e);
364 TopOpeBRepTool_TOOL::Remove(lof,f);
365 lof.Append(fsp);
366
367 // <mymapemult>
368 Standard_Integer nf = lof.Extent();
369 if (nf > 2) mymapemult.Add(e);
370 }//exe(fsp)
371 }//itf(lfsp)
372
373#ifdef DEB
374 if (trc) {
375 cout <<"split(f"<<FUN_adds(f)<<")= ";
376 TopTools_ListIteratorOfListOfShape it(lfsp);
377 for (; it.More(); it.Next()) cout<<" f"<<FUN_adds(it.Value());
378 cout<<endl;}
379#endif
380 }//exf(myS)
381 return Standard_True;
382}
383
384static void FUN_update(const TopoDS_Shape& fcur, TopTools_MapOfShape& edstoconnect)
385// purpose : <e> edge of <fcur>
386// 1. <e> is INTERNAL or EXTERNAL -> nothing is done
387// 2. <e> is closing edge of <fcur> -> nothing is done
388// 3. <e> is already bound in <edstoconnect> -> remove it from the map
389// (then has 2 ancestor faces stored in the current Block)
390// 4. elsewhere, add it in the map.
391//
392// !! if <fcur> is INTERNAL/EXTERNAL -> nothing is done
393{
394 TopAbs_Orientation ofcur = fcur.Orientation();
395 if (M_INTERNAL(ofcur) || M_EXTERNAL(ofcur)) return;
396
397 TopExp_Explorer exe(fcur, TopAbs_EDGE);
398 for (; exe.More(); exe.Next()){
399 const TopoDS_Shape& e = exe.Current();
400 TopAbs_Orientation oe = e.Orientation();
401 if (M_INTERNAL(oe) || M_EXTERNAL(oe)) continue;
402
403 Standard_Boolean isclo = TopOpeBRepTool_TOOL::IsClosingE(TopoDS::Edge(e),TopoDS::Face(fcur));
404 if (isclo) continue;
405
406 Standard_Boolean isb = edstoconnect.Contains(e);
407 if (isb) edstoconnect.Remove(e);
408 else edstoconnect.Add(e);
409 }//exe
410}
411
412//=======================================================================
413//function : REGU
414//purpose :
415//=======================================================================
416
417Standard_Boolean TopOpeBRepTool_REGUS::REGU()
418{
419#ifdef DEB
420 Standard_Boolean trc = TopOpeBRepTool_GettraceREGUSO();
421 Standard_Integer ishe = FUN_adds(myS);
422 if (trc) cout<<"** REGU **"<<ishe<<endl;
423#endif
424 TopTools_ListOfShape Splits;
425 Standard_Boolean toregu = !mymapemult.IsEmpty() || (mynF != myoldnF);
426 if (!toregu) return Standard_False;
427
428 // purpose : myS -> {Blocks},
429 // a Block is a closed shell with "valid" edges.
430 // - a valid edge in a Block has at most two ancestor faces -
431 //
432 // Give us the starting couple (<ei>, <fi>) :
433 // * If <ei> has only one untouched ancestor face <fj> left, fj+1 <- fj
434 // Else among the untouched ancestors faces, we choose the one for which
435 // angle (<veci>, <vecj>) is the smallest; providing face <fj> reduces
436 // the matter described by <fi>.
437 // * update <mymapeFs> for <ei> (<fj> as touched).
438 // * Update <mymapemult> for <fi>'s bound edges :
439 // - if bound edge is not in the map, add it.
440 // - else if bound edge has two ancestor faces in current list <mylFinBlock>,
441 // delete it form the map.
442 //
443// TopTools_ListOfShape lFinBlock; // <lFinBlock> describes a valid closed shell when <myedstoconnect> is emptied.
444 mylFinBlock.Clear();
445 Standard_Integer nite = 0;
446 while (nite <= mynF) {
447 Standard_Boolean startBlock = mylFinBlock.IsEmpty();
448 Standard_Boolean endBlock = myedstoconnect.IsEmpty() && (!startBlock);
449
450#ifdef DEB
451 Standard_Boolean tr=Standard_False;
452 if (tr) {
453 TopTools_MapIteratorOfMapOfShape it(myedstoconnect);
454 cout<<"still to connect : ";
455 for (; it.More(); it.Next()) cout<<" e"<<FUN_adds(it.Key());
456 cout<<endl;
457 }
458#endif
459
460 //* endBlock
461 // ---------
462 if (endBlock) {
463 // building up shell on <mylFinBlock>
464 Standard_Integer nFcur = mylFinBlock.Extent();
465 Standard_Boolean unchanged = (nFcur==myoldnF) && (mynF==myoldnF);
466 if (unchanged) {
467#ifdef DEB
468 if (trc) cout<<"#** shell"<<ishe<<" valid\n";
469#endif
470 return Standard_False; // nyi analysis if we should raise or not
471 }
472 else {
473 TopoDS_Shell newShe; TopOpeBRepTool_TOOL::MkShell(mylFinBlock,newShe);
474 Splits.Append(newShe);
475#ifdef DEB
476 if (trc) {cout<<"#** shell "<<ishe<<" gives new shell "<<FUN_adds(newShe)<<endl;
477 for (TopTools_ListIteratorOfListOfShape it(mylFinBlock); it.More(); it.Next()) cout <<";dins f"<<FUN_adds(it.Value());
478 cout<<endl<<endl;}
479#endif
480 mylFinBlock.Clear();
481 startBlock = Standard_True;
482 }
483 }//endBlock
484
485 //* all faces touched
486 // ------------------
487 Standard_Boolean FINI = (nite == mynF);
488 if (FINI) break;
489
490 Standard_Integer advance=Standard_False;
491 //* initializing a new Block
492 // -------------------------
493 if (startBlock || endBlock) {
494 advance = InitBlock();
495 if (!advance) return Standard_False;
496 }//startBlock||endBlock
497
498 //* choosing next face
499 // -------------------
500 else {
501 advance = NextinBlock();
502 }
503
504 // ** updating connexity
505 ::FUN_update(myf,myedstoconnect);
506
507 if (!advance) {
508 endBlock = myedstoconnect.IsEmpty() && (!startBlock);
509 if (!endBlock) return Standard_False;
510 else continue;
511 }
512
513 TopExp_Explorer exe(myf, TopAbs_EDGE);
514 for (; exe.More(); exe.Next()){
515 const TopoDS_Shape& e = exe.Current();
516 Standard_Boolean isb = mymapeFs.IsBound(e);
517 if (!isb) continue; // ancestors faces of <e> are stored in Blocks
518 TopOpeBRepTool_TOOL::Remove(mymapeFs.ChangeFind(e),myf);
519 }//exe
520
521 mylFinBlock.Append(myf); nite++;
522 }//nite <= mynF
523
524 myOshNsh.Bind(S(), Splits);
525 return Standard_True;
526}
527
528//=======================================================================
529//function : InitBlock
530//purpose :
531//=======================================================================
532
533Standard_Boolean TopOpeBRepTool_REGUS::InitBlock()
534{
535 Standard_Integer nec = myedstoconnect.Extent();
536 if (nec != 0) return Standard_False; // should be empty
537
538 TopTools_ListOfShape eds;
539 TopTools_DataMapIteratorOfDataMapOfShapeListOfShape itm(mymapeFs);
540 for (; itm.More(); itm.Next()) eds.Append(itm.Key());
541
542 TopTools_ListIteratorOfListOfShape ite(eds);
543 for (; ite.More(); ite.Next()){
544 const TopoDS_Shape& e = ite.Value();
545 const TopTools_ListOfShape& lof = mymapeFs.Find(e);
546 if (lof.IsEmpty()) {mymapeFs.UnBind(e); continue;}
547 myf = lof.First();
548#ifdef DEB
549 Standard_Boolean trc = TopOpeBRepTool_GettraceREGUSO();
550 if (trc) cout<<"* Block : first face = f"<<FUN_adds(myf)<<endl;
551#endif
552 return Standard_True;
553 }
554 return Standard_False;
555}
556
557//=======================================================================
558//function : NextinBlock
559//purpose :
560//=======================================================================
561
562Standard_Boolean TopOpeBRepTool_REGUS::NextinBlock()
563{
564#ifdef DEB
565 Standard_Boolean trc = TopOpeBRepTool_GettraceREGUSO();
566#endif
567 // we try to connect first edge of <myf> bound in <myedstoconnect>
568 TopTools_ListOfShape eds;
569 TopExp_Explorer exe(myf, TopAbs_EDGE);
570 for (; exe.More(); exe.Next()){
571 const TopoDS_Shape& e = exe.Current();
572 Standard_Boolean isb = myedstoconnect.Contains(e);
573 if (isb) eds.Append(e);
574 }//exe
575 Standard_Boolean alleftouched = eds.IsEmpty();
576 if (alleftouched) {
577 TopTools_MapIteratorOfMapOfShape itc(myedstoconnect);
578 for (; itc.More(); itc.Next()){
579 const TopoDS_Shape& e = itc.Key();
580 Standard_Boolean isb = mymapeFs.IsBound(e);
581 // all ancestor faces of <e> have been stored
582 if (!isb) {myedstoconnect.Remove(e); continue;}
583
584 const TopTools_ListOfShape& lof = mymapeFs.Find(e); Standard_Integer nf = lof.Extent();
585 if (nf == 0) {myedstoconnect.Remove(e); mymapeFs.UnBind(e);
586 continue;}
587
588// myf = lof.First(); 130499
589 if (lof.Extent() == 1) myf = lof.First();
590 else {
591 // looking for first face stored in the current block
592 // connexed to e
593
594 TopTools_ListIteratorOfListOfShape itff(mylFinBlock);
595 TopTools_MapOfShape mapf;for (; itff.More(); itff.Next()) mapf.Add(itff.Value());
596 // lofc : the list of faces connexed to e in <myS>
597 // lof : the list of untouched faces connexed to e in <myS>
598 const TopTools_ListOfShape& lofc = mymapeFsstatic.Find(e);
6e6cd5d9 599
7fd59977 600 itff.Initialize(lofc);
601 TopoDS_Face fref;
602 for (; itff.More(); itff.Next()) {
603 const TopoDS_Face& fc = TopoDS::Face(itff.Value());
604 Standard_Boolean isb = mapf.Contains(fc);
605 if (isb) {fref = fc; break;}
606 } // itff(lofc)
607 if (fref.IsNull()) {
608 return Standard_False; // !!!!!!!!!! a revoir 130499
609 }
610 else {
611 myf = fref;
612 TopoDS_Face ffound; Standard_Boolean ok = NearestF(TopoDS::Edge(e),lof,ffound);
613 if (!ok) return Standard_False;
614 myf = ffound;
615 }
616 }
617
618 return Standard_True;
619 }
620 return Standard_False;
621 }
622
623 TopTools_ListIteratorOfListOfShape ite(eds);
624 for (; ite.More(); ite.Next()){
625 const TopoDS_Shape& e = ite.Value();
626 Standard_Boolean isb = mymapeFs.IsBound(e);
627 // all ancestor faces of <e> have been stored
628 if (!isb) {myedstoconnect.Remove(e); continue;}
629
630 const TopTools_ListOfShape& lof = mymapeFs.Find(e); Standard_Integer nf = lof.Extent();
631 if (nf == 0) {myedstoconnect.Remove(e); mymapeFs.UnBind(e);
632 continue;}
633#ifdef DEB
634 if (trc) {cout<<"e"<<FUN_adds(e)<<" on "<<nf<<" untouched f:"<<endl;}
635#endif
636 if (nf == 1) myf = lof.First();
637 else {
638 TopoDS_Face ffound; Standard_Boolean ok = NearestF(TopoDS::Edge(e),lof,ffound);
639 if (!ok) return Standard_False;
640 myf = ffound;
641 }
642#ifdef DEB
643 if (trc) cout<<"->myf = f"<<FUN_adds(myf)<<endl;
644#endif
645 return Standard_True;
646 }//itm(myedstoconnect)
647 return Standard_False;
648}
649
650static Standard_Boolean FUN_vectors(const TopoDS_Face& f, const TopoDS_Edge& e, const Standard_Real pare,
651 gp_Dir& nt, gp_Dir& xx, const Standard_Real tola, const Standard_Boolean approx)
652{
653 // <nt> :
654 if (approx) {
655 Standard_Boolean ok = TopOpeBRepTool_TOOL::tryNgApp(pare,e,f,tola,nt);
656 if (!ok) return Standard_False;
657 }
658 else {
659 gp_Vec tmp; Standard_Boolean ok = FUN_tool_nggeomF(pare,e,f,tmp);
660 if (!ok) return Standard_False;
661 nt = gp_Dir(tmp);
662 }
663 if (M_REVERSED(f.Orientation())) nt.Reverse();
664 // <xx> :
665 Standard_Boolean ok = FUN_tool_getxx(f,e,pare,xx);
666 if (!ok) return Standard_False;
667 return Standard_True;
668}
669
670//=======================================================================
671//function : NearestF
672//purpose :
673//=======================================================================
674
675Standard_Boolean TopOpeBRepTool_REGUS::NearestF(const TopoDS_Edge& e, const TopTools_ListOfShape& lof, TopoDS_Face& ffound) const
676// prequesitory : <e> is shared by <myf> and faces of <lof>.
677//
678// NYIXPU!!!!!!!! if (xx1 tg xx2) -> use curvatures
679//
680{
681#ifdef DEB
682 Standard_Boolean trc = TopOpeBRepTool_GettraceREGUSO();
683#endif
684 ffound.Nullify();
685 TopoDS_Face fref = TopoDS::Face(myf);
7fd59977 686
687 // Give us egde <e>, and a reference face <fref> (= <myf>)
688 // - parameter on <e> = <pare>.
689 // - xxi = tangent fo face fi at pnt(e,pare) oriented INSIDE 2d(fi)
690 // normal to tge = tg(e,pare).
691 // purpose : looking for ffound /
692 // MatterAng(xxref, xxfound) = Min{ MatterAng(xxref, xxi), xxi for fi in <lof>
693 // providing fi reduces 3d(fref) }
694
695 // <parone> :
696 Standard_Real f,l; FUN_tool_bounds(e,f,l); Standard_Real eps = 0.45678; Standard_Real pare = (1-eps)*f+eps*l;
697
698 // RONd (x,y,z) = (xxref,ntref,x^y)
699 Standard_Real tola = Precision::Angular()*1.e3; //gp_Dir xapp,yapp; Standard_Boolean refapp = Standard_False;
700 gp_Dir x,y; Standard_Boolean ok = ::FUN_vectors(fref,e,pare,y,x,tola,Standard_False);
701 if (!ok) {FUN_Raise(); return Standard_False;}
702#ifdef DEB
703 gp_Dir z = x^y;
704#endif
705
706 // initializing
707 // ------------
708 Standard_Real angfound = 0;
709 TopTools_ListIteratorOfListOfShape itf(lof);
710 for (; itf.More(); itf.Next()){
711 ffound = TopoDS::Face(itf.Value());
712 gp_Dir ntfound,xxfound;
713 ok = ::FUN_vectors(ffound,e,pare,ntfound,xxfound,tola,Standard_False);
714 if (!ok) {FUN_Raise(); return Standard_False;}
715
716 Standard_Boolean oppo = TopOpeBRepTool_TOOL::Matter(x,y,xxfound,ntfound,tola, angfound);
717#ifdef DEB
718 if (trc&&!oppo) cout<<" f"<<FUN_adds(fref)<<",f"<<FUN_adds(ffound)<<" not oppo"<<endl;
719#endif
720 if (!oppo) {ffound.Nullify(); continue;}
721
722 if (angfound < tola) {
723// refapp = Standard_True; ::FUN_vectors(fref,e,pare,yapp,xapp,tola,Standard_True);
724// ::FUN_vectors(ffound,e,pare,ntfound,xxfound,tola,Standard_True);
725// TopOpeBRepTool_TOOL::Matter(xapp,yapp,xxfound,ntfound,tola, angfound);
726 ok = TopOpeBRepTool_TOOL::MatterKPtg(fref,ffound,e,angfound);
727 if (!ok) {FUN_Raise(); return Standard_False;}
728 }
729#ifdef DEB
730 if (trc) cout<<" ang("<<"f"<<FUN_adds(fref)<<",f"<<FUN_adds(ffound)<<")="<<angfound<<endl;
731#endif
732 break;
733 }
734 if (ffound.IsNull()) {FUN_Raise(); return Standard_False;}
735 if (itf.More()) itf.Next();
736 else return Standard_True;
737
738 // selecting nearest face
739 // ----------------------
740 for (; itf.More(); itf.Next()){
741 gp_Dir nti,xxi;
742 const TopoDS_Face& fi = TopoDS::Face(itf.Value());
743 ok = ::FUN_vectors(fi,e,pare,nti,xxi,tola,Standard_False);
744 if (!ok) {FUN_Raise(); return Standard_False;}
745
746 Standard_Real angi = 0;
747 Standard_Boolean oppo = TopOpeBRepTool_TOOL::Matter(x,y,xxi,nti,tola, angi);
748#ifdef DEB
749 if (trc&&!oppo) cout<<" f"<<FUN_adds(fref)<<",f"<<FUN_adds(fi)<<" not oppo"<<endl;
750#endif
751 if (!oppo) continue;
752
753 if (angi < tola) {
754// if (!refapp) ::FUN_vectors(fref,e,pare,yapp,xapp,tola,Standard_True);
755// ::FUN_vectors(fi,e,pare,nti,xxi,tola,Standard_True);
756// TopOpeBRepTool_TOOL::Matter(xapp,yapp,xxi,nti,tola, angi);
757 ok = TopOpeBRepTool_TOOL::MatterKPtg(fref,fi,e,angi);
758 if (!ok) {FUN_Raise(); return Standard_False;}
759 }
760#ifdef DEB
761 if (trc) cout<<" ang("<<"f"<<FUN_adds(fref)<<",f"<<FUN_adds(fi)<<")="<<angi<<endl;
762#endif
763 if (angi > angfound) continue;
764 angfound = angi;
765 ffound = fi;
766 }
767 return Standard_True;
768}
769
770
771