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