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 |
46 | extern Standard_Boolean TopOpeBRepTool_GettraceREGUSO(); |
7fd59977 |
47 | static TopTools_IndexedMapOfShape STATIC_mape, STATIC_mapf, STATIC_mapw, STATIC_mapsh; |
48 | static 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 | |
63 | static 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 | |
77 | TopOpeBRepTool_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 | |
98 | void 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 | |
116 | const TopoDS_Shape& TopOpeBRepTool_REGUS::S() const |
117 | { |
118 | return myS; |
119 | } |
120 | |
121 | |
122 | //======================================================================= |
123 | //function : SetFsplits |
124 | //purpose : |
125 | //======================================================================= |
126 | |
127 | void TopOpeBRepTool_REGUS::SetFsplits(TopTools_DataMapOfShapeListOfShape& Fsplits) |
128 | { |
129 | myFsplits = Fsplits; |
130 | } |
131 | //======================================================================= |
132 | //function : GetFsplits |
133 | //purpose : |
134 | //======================================================================= |
135 | |
136 | void TopOpeBRepTool_REGUS::GetFsplits(TopTools_DataMapOfShapeListOfShape& Fsplits) const |
137 | { |
138 | Fsplits = myFsplits; |
139 | } |
140 | |
141 | //======================================================================= |
142 | //function : SetOshNsh |
143 | //purpose : |
144 | //======================================================================= |
145 | |
146 | void TopOpeBRepTool_REGUS::SetOshNsh(TopTools_DataMapOfShapeListOfShape& OshNsh) |
147 | { |
148 | myOshNsh = OshNsh; |
149 | } |
150 | //======================================================================= |
151 | //function : GetOshNsh |
152 | //purpose : |
153 | //======================================================================= |
154 | |
155 | void TopOpeBRepTool_REGUS::GetOshNsh(TopTools_DataMapOfShapeListOfShape& OshNsh) const |
156 | { |
157 | OshNsh = myOshNsh; |
158 | } |
159 | |
160 | //======================================================================= |
161 | //function : MapS |
162 | //purpose : |
163 | //======================================================================= |
164 | |
165 | Standard_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 | |
212 | Standard_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 | |
248 | Standard_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 | |
340 | Standard_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 | |
394 | static 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 | |
427 | Standard_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 | |
543 | Standard_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 | |
572 | Standard_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 | |
660 | static 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 | |
685 | Standard_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 | |