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