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