0022627: Change OCCT memory management defaults
[occt.git] / src / QANewModTopOpe / QANewModTopOpe.cxx
CommitLineData
7fd59977 1// File: QANewModTopOpe.cxx
2// Created: Mon Jan 28 14:24:19 2002
3// Author: Igor FEOKTISTOV <ifv@nnov.matra-dtv.fr>
4// Copyright: SAMTECH S.A. 2002
5
7fd59977 6// Lastly modified by :
7// +---------------------------------------------------------------------------+
8// ! pat ! Optimise IsConnected() ! 04/16/03! 4.0-2!
9// +---------------------------------------------------------------------------+
10
11
12#include <QANewModTopOpe.ixx>
13#include <TopAbs.hxx>
14#include <TopoDS_Iterator.hxx>
15#include <BRepCheck_Analyzer.hxx>
16#include <TopoDS_Shape.hxx>
17#include <TopoDS_Shell.hxx>
18#include <TopoDS.hxx>
19#include <TopExp_Explorer.hxx>
20#include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
21#include <TopTools_ListOfShape.hxx>
22#include <TopoDS_Edge.hxx>
23#include <TopoDS_Face.hxx>
24#include <TopExp.hxx>
25#include <TopTools_DataMapOfShapeInteger.hxx>
26#include <math_Matrix.hxx>
27#include <TopTools_ListIteratorOfListOfShape.hxx>
28#include <BRepTools_Substitution.hxx>
29#include <BRepCheck_ListIteratorOfListOfStatus.hxx>
30#include <BRepCheck_Result.hxx>
31#include <BRepCheck.hxx>
32#include <BRepCheck_Shell.hxx>
33#include <BRepCheck_Wire.hxx>
34#include <TopTools_MapIteratorOfMapOfShape.hxx>
35#include <TopTools_MapOfShape.hxx>
36
37static Standard_Boolean NoInternalVertices(const TopoDS_Shape& TheS);
38static Standard_Boolean CorrectOrientation(const TopoDS_Shell& TheS);
39
40static TopoDS_Shape RemoveIntExtEdges(const TopoDS_Shape& TheS)
41{
42
43 TopoDS_Shape aCopy = TheS;
44 BRepTools_Substitution aSubst;
45 TopTools_ListOfShape anEmptyList;
46 TopAbs_Orientation anOr;
47
48 TopExp_Explorer anExp(aCopy, TopAbs_EDGE);
49 for(; anExp.More(); anExp.Next()) {
50 anOr = anExp.Current().Orientation();
51 if(anOr == TopAbs_INTERNAL || anOr == TopAbs_EXTERNAL) {
52 if(!aSubst.IsCopied(anExp.Current())) {
53 aSubst.Substitute(anExp.Current(), anEmptyList);
54 }
55 }
56 }
57
58 aSubst.Build(aCopy);
59
60 if(aSubst.IsCopied(aCopy)) {
61 aCopy = aSubst.Copy(aCopy).First();
62 }
63
64 return aCopy;
65}
66
67Standard_Boolean QANewModTopOpe::IsValid(const TopoDS_Shape& TheS, const Standard_Boolean GeomControls)
68{
69
70 TopExp_Explorer anExp, anExp1;
71 TopoDS_Shape aCopy;
72
73 anExp.Init(TheS, TopAbs_SOLID);
74 for(; anExp.More(); anExp.Next()) {
75
76 aCopy = RemoveIntExtEdges(anExp.Current());
77
78 BRepCheck_Analyzer anAnlz(aCopy, GeomControls);
79
80 if(anAnlz.IsValid()) continue;
81 else return Standard_False;
82
83 }
84
85 anExp.Init(TheS, TopAbs_SHELL, TopAbs_SOLID);
86 for(; anExp.More(); anExp.Next()) {
87
88 aCopy = RemoveIntExtEdges(anExp.Current());
89
90 Handle(BRepCheck_Shell) aChkSh = new BRepCheck_Shell(TopoDS::Shell(aCopy));
91 aChkSh->Minimum();
92 aChkSh->Closed(Standard_True);
93 aChkSh->Orientation(Standard_True);
94 BRepCheck_ListIteratorOfListOfStatus anItl(aChkSh->Status());
95 for (;anItl.More(); anItl.Next()) {
96 if((anItl.Value() == BRepCheck_NoError) ||
97 (anItl.Value() == BRepCheck_InvalidMultiConnexity) ||
98 (anItl.Value() == BRepCheck_NotClosed) ||
99 (anItl.Value() == BRepCheck_BadOrientationOfSubshape)) continue;
100 return Standard_False;
101 }
102
103 anExp1.Init(anExp.Current(), TopAbs_FACE);
104 for(; anExp1.More(); anExp1.Next()) {
105 if(IsValid(anExp1.Current())) continue;
106 else return Standard_False;
107 }
108 }
109
110 anExp.Init(TheS, TopAbs_FACE, TopAbs_SHELL);
111 for(; anExp.More(); anExp.Next()) {
112
113 aCopy = RemoveIntExtEdges(anExp.Current());
114
115 BRepCheck_Analyzer anAnlz(aCopy, GeomControls);
116
117 if(anAnlz.IsValid()) continue;
118 else return Standard_False;
119
120 }
121
122 anExp.Init(TheS, TopAbs_WIRE, TopAbs_FACE);
123 for(; anExp.More(); anExp.Next()) {
124
125 BRepCheck_Analyzer anAnlz(anExp.Current(), GeomControls);
126
127 Handle(BRepCheck_Result) aChkWr = anAnlz.Result(anExp.Current());
128 BRepCheck_ListIteratorOfListOfStatus anItl(aChkWr->Status());
129 for (;anItl.More(); anItl.Next()) {
130
131 if(anItl.Value() == BRepCheck_NoError ||
132 anItl.Value() == BRepCheck_BadOrientationOfSubshape) continue;
133
134 return Standard_False;
135
136 }
137
138 }
139
140 anExp.Init(TheS, TopAbs_EDGE, TopAbs_WIRE);
141 for(; anExp.More(); anExp.Next()) {
142
143 BRepCheck_Analyzer anAnlz(anExp.Current(), GeomControls);
144
145 if(anAnlz.IsValid()) continue;
146 else return Standard_False;
147
148 }
149
150 return Standard_True;
151}
152
153Standard_Boolean QANewModTopOpe::IsManifold(const TopoDS_Shape& TheS)
154{
155
156 Standard_Boolean aRes = Standard_False;
157
158 if(TheS.IsNull()) return aRes;
159
160 TopAbs_ShapeEnum aType = TheS.ShapeType();
161
162 switch (aType) {
163
164 case TopAbs_COMPOUND :
165 {
166 TopoDS_Iterator anIter(TheS);
167 if(!anIter.More()) return aRes;
168 const TopoDS_Shape& aS = anIter.Value();
169 anIter.Next();
170 if(anIter.More()) aRes = IsCompoundManifold(TopoDS::Compound(TheS));
171 else aRes = IsManifold(aS);
172 }
173 break;
174 case TopAbs_COMPSOLID :
175 aRes = Standard_False;
176 break;
177 case TopAbs_SOLID :
178 {
179 aRes = NoInternalVertices(TheS);
180 }
181 break;
182 case TopAbs_SHELL :
183 {
184 aRes = NoInternalVertices(TheS);
185 if(aRes) aRes = CorrectOrientation(TopoDS::Shell(TheS));
186 }
187 break;
188 case TopAbs_FACE :
189 {
190 aRes = NoInternalVertices(TheS);
191 }
192 break;
193 case TopAbs_WIRE :
194 {
195 aRes = NoInternalVertices(TheS);
196 }
197 break;
198 case TopAbs_EDGE :
199 aRes = NoInternalVertices(TheS);
200 break;
201 case TopAbs_VERTEX :
202 aRes = Standard_True;
203 break;
204 case TopAbs_SHAPE :
205 default :
206 ;
207 }
208
209
210 return aRes;
211
212}
213
214static Standard_Boolean NoInternalVertices(const TopoDS_Shape& TheS)
215{
216
217 TopAbs_Orientation anOrnt;
218 TopExp_Explorer anExp(TheS, TopAbs_VERTEX);
219 for(; anExp.More(); anExp.Next()) {
220
221 anOrnt = anExp.Current().Orientation();
222
223 if(anOrnt == TopAbs_FORWARD) continue;
224 if(anOrnt == TopAbs_REVERSED) continue;
225
226 return Standard_False;
227
228 }
229
230 return Standard_True;
231
232}
233
234static Standard_Boolean CorrectOrientation(const TopoDS_Shell& TheS)
235{
236
237 TopoDS_Iterator anIter(TheS);
238
239 if(!anIter.More()) return Standard_False; //Empty shell;
240 anIter.Next();
241 if(!anIter.More()) return Standard_True; // only one face
242
243
244 TopTools_IndexedDataMapOfShapeListOfShape aMapEdgeFace;
245 TopExp::MapShapesAndAncestors(TheS, TopAbs_EDGE, TopAbs_FACE, aMapEdgeFace);
246
247 Standard_Integer i, nbEdgs = aMapEdgeFace.Extent();
248 TopExp_Explorer anExp;
249 TopAbs_Orientation anOrnt;
250
251 for(i = 1; i <= nbEdgs; i++) {
252
253 const TopTools_ListOfShape& aL = aMapEdgeFace(i);
254
255 if(aL.Extent() > 2) return Standard_False;
256 if(aL.Extent() == 1) continue;
257
258 const TopoDS_Shape& anE = aMapEdgeFace.FindKey(i);
259
260 anExp.Init(aL.First(), TopAbs_EDGE);
261 for(; anExp.More(); anExp.Next()) {
262 if(anE.IsSame(anExp.Current())) {
263 anOrnt = anExp.Current().Orientation();
264 break;
265 }
266 }
267
268 anExp.Init(aL.Last(), TopAbs_EDGE);
269 for(; anExp.More(); anExp.Next()) {
270 if(anE.IsSame(anExp.Current())) {
271 if(anOrnt == anExp.Current().Orientation()) return Standard_False;
272 break;
273 }
274 }
275
276 }
277
278 return Standard_True;
279
280}
281
282Standard_Boolean QANewModTopOpe::IsCompoundManifold(const TopoDS_Compound& TheS)
283{
284 Standard_Boolean aRes = Standard_True;
285
286 TopExp_Explorer anExp;
287
288 anExp.Init(TheS, TopAbs_COMPSOLID);
289 if(anExp.More()) {
290
291 aRes = Standard_False;
292 return aRes;
293
294 }
295
296 TopTools_ListOfShape aList;
297 TopExp_Explorer anExp1;
298 TopTools_DataMapOfShapeInteger aMap;
299 Standard_Integer n = 0, connect;
300
301 anExp.Init(TheS, TopAbs_SOLID);
302 for(; anExp.More(); anExp.Next()) {
303 aRes = IsManifold(anExp.Current());
304 if(!aRes) return aRes;
305 ++n;
306 anExp1.Init(anExp.Current(), TopAbs_FACE);
307 for(; anExp1.More(); anExp1.Next()) {
308 if(aMap.IsBound(anExp1.Current())) {
309 connect = aMap(anExp1.Current());
310 if(n != connect) {
311 aRes = Standard_False;
312 return aRes;
313 }
314 }
315 else {
316 aMap.Bind(anExp1.Current(), n);
317 }
318 }
319
320 anExp1.Init(anExp.Current(), TopAbs_EDGE);
321 for(; anExp1.More(); anExp1.Next()) {
322 if(aMap.IsBound(anExp1.Current())) {
323 connect = aMap(anExp1.Current());
324 if(n != connect) {
325 aRes = Standard_False;
326 return aRes;
327 }
328 }
329 else {
330 aMap.Bind(anExp1.Current(), n);
331 }
332 }
333
334 anExp1.Init(anExp.Current(), TopAbs_VERTEX);
335 for(; anExp1.More(); anExp1.Next()) {
336 if(aMap.IsBound(anExp1.Current())) {
337 connect = aMap(anExp1.Current());
338 if(n != connect) {
339 aRes = Standard_False;
340 return aRes;
341 }
342 }
343 else {
344 aMap.Bind(anExp1.Current(), n);
345 }
346 }
347 }
348
349 anExp.Init(TheS, TopAbs_SHELL, TopAbs_SOLID);
350 for(; anExp.More(); anExp.Next()) {
351 aRes = IsManifold(anExp.Current());
352 if(!aRes) return aRes;
353 ++n;
354 anExp1.Init(anExp.Current(), TopAbs_FACE);
355 for(; anExp1.More(); anExp1.Next()) {
356 if(aMap.IsBound(anExp1.Current())) {
357 connect = aMap(anExp1.Current());
358 if(n != connect) {
359 aRes = Standard_False;
360 return aRes;
361 }
362 }
363 else {
364 aMap.Bind(anExp1.Current(), n);
365 }
366 }
367
368 anExp1.Init(anExp.Current(), TopAbs_EDGE);
369 for(; anExp1.More(); anExp1.Next()) {
370 if(aMap.IsBound(anExp1.Current())) {
371 connect = aMap(anExp1.Current());
372 if(n != connect) {
373 aRes = Standard_False;
374 return aRes;
375 }
376 }
377 else {
378 aMap.Bind(anExp1.Current(), n);
379 }
380 }
381
382 anExp1.Init(anExp.Current(), TopAbs_VERTEX);
383 for(; anExp1.More(); anExp1.Next()) {
384 if(aMap.IsBound(anExp1.Current())) {
385 connect = aMap(anExp1.Current());
386 if(n != connect) {
387 aRes = Standard_False;
388 return aRes;
389 }
390 }
391 else {
392 aMap.Bind(anExp1.Current(), n);
393 }
394 }
395 }
396
397 anExp.Init(TheS, TopAbs_FACE, TopAbs_SHELL);
398 for(; anExp.More(); anExp.Next()) {
399 aRes = IsManifold(anExp.Current());
400 if(!aRes) return aRes;
401 ++n;
402
403 anExp1.Init(anExp.Current(), TopAbs_EDGE);
404 for(; anExp1.More(); anExp1.Next()) {
405 if(aMap.IsBound(anExp1.Current())) {
406 connect = aMap(anExp1.Current());
407 if(n != connect) {
408 aRes = Standard_False;
409 return aRes;
410 }
411 }
412 else {
413 aMap.Bind(anExp1.Current(), n);
414 }
415 }
416
417 anExp1.Init(anExp.Current(), TopAbs_VERTEX);
418 for(; anExp1.More(); anExp1.Next()) {
419 if(aMap.IsBound(anExp1.Current())) {
420 connect = aMap(anExp1.Current());
421 if(n != connect) {
422 aRes = Standard_False;
423 return aRes;
424 }
425 }
426 else {
427 aMap.Bind(anExp1.Current(), n);
428 }
429 }
430 }
431
432 anExp.Init(TheS, TopAbs_WIRE, TopAbs_FACE);
433 for(; anExp.More(); anExp.Next()) {
434 aRes = IsManifold(anExp.Current());
435 if(!aRes) return aRes;
436 ++n;
437
438 anExp1.Init(anExp.Current(), TopAbs_EDGE);
439 for(; anExp1.More(); anExp1.Next()) {
440 if(aMap.IsBound(anExp1.Current())) {
441 connect = aMap(anExp1.Current());
442 if(n != connect) {
443 aRes = Standard_False;
444 return aRes;
445 }
446 }
447 else {
448 aMap.Bind(anExp1.Current(), n);
449 }
450 }
451
452 anExp1.Init(anExp.Current(), TopAbs_VERTEX);
453 for(; anExp1.More(); anExp1.Next()) {
454 if(aMap.IsBound(anExp1.Current())) {
455 connect = aMap(anExp1.Current());
456 if(n != connect) {
457 aRes = Standard_False;
458 return aRes;
459 }
460 }
461 else {
462 aMap.Bind(anExp1.Current(), n);
463 }
464 }
465 }
466
467 anExp.Init(TheS, TopAbs_EDGE, TopAbs_WIRE);
468 for(; anExp.More(); anExp.Next()) {
469 aRes = IsManifold(anExp.Current());
470 if(!aRes) return aRes;
471 ++n;
472
473 anExp1.Init(anExp.Current(), TopAbs_VERTEX);
474 for(; anExp1.More(); anExp1.Next()) {
475 if(aMap.IsBound(anExp1.Current())) {
476 connect = aMap(anExp1.Current());
477 if(n != connect) {
478 aRes = Standard_False;
479 return aRes;
480 }
481 }
482 else {
483 aMap.Bind(anExp1.Current(), n);
484 }
485 }
486 }
487
488 anExp.Init(TheS, TopAbs_VERTEX, TopAbs_EDGE);
489 for(; anExp.More(); anExp.Next()) {
490 ++n;
491
492 if(aMap.IsBound(anExp.Current())) {
493 connect = aMap(anExp.Current());
494 if(n != connect) {
495 aRes = Standard_False;
496 return aRes;
497 }
498 }
499 else {
500 aMap.Bind(anExp.Current(), n);
501 }
502 }
503
504 return aRes;
505}
506
507
508TopAbs_ShapeEnum QANewModTopOpe::TypeOfShape(const TopoDS_Shape& TheS)
509{
510 if(TheS.ShapeType() != TopAbs_COMPOUND) return TheS.ShapeType();
511
512 TopAbs_ShapeEnum aType = TopAbs_COMPOUND;
513
514 TopoDS_Iterator anIter(TheS);
515
516 if(!anIter.More()) return aType;
517
518 aType = TypeOfShape(anIter.Value());
519
520 if(aType == TopAbs_COMPOUND) return aType;
521
522 anIter.Next();
523
524 for(; anIter.More(); anIter.Next()) {
525
526 if(TypeOfShape(anIter.Value()) != aType) return TopAbs_COMPOUND;
527
528 }
529
530 return aType;
531
532}
533
534
535Standard_Boolean QANewModTopOpe::IsConnected(const TopoDS_Shape& TheS)
536{
537 cout << "QANewModTopOpe::IsConnected BEGIN" << endl;
538 Standard_Boolean aRes = Standard_True;
539
540 if(TheS.IsNull()) return aRes;
541
542 TopAbs_ShapeEnum aType = TheS.ShapeType();
543
544 if(aType != TopAbs_COMPOUND) return aRes;
545
546 TopTools_ListOfShape aCompList;
547 TopTools_DataMapOfShapeInteger aMap;
548 TopTools_MapOfShape aSMap;
549 TopoDS_Iterator anTDIter;
550 TopExp_Explorer anExp;
551
552 anTDIter.Initialize(TheS);
553 for(; anTDIter.More(); anTDIter.Next()) {
554 if(anTDIter.Value().ShapeType() == TopAbs_COMPOUND) aCompList.Append(anTDIter.Value());
555 else aSMap.Add(anTDIter.Value());
556 }
557
558 TopTools_ListIteratorOfListOfShape anIter(aCompList);
559 for(;anIter.More(); anIter.Next()) {
560 anTDIter.Initialize(anIter.Value());
561 for(; anTDIter.More(); anTDIter.Next()) {
562 if(anTDIter.Value().ShapeType() == TopAbs_COMPOUND) aCompList.Append(anTDIter.Value());
563 else aSMap.Add(anTDIter.Value());
564 }
565 }
566 //cout << "QANewModTopOpe::IsConnected(2)" << endl;
567
568
569 Standard_Integer nbs = aSMap.Extent();
570 if(nbs <= 1) return aRes;
571
572 // math_Matrix aMat(1, nbs, 1, nbs, 0.0);
573 int *aMat = new int[nbs*nbs];
574 Standard_Integer aMax=nbs*nbs;
575 for(Standard_Integer kk=0;kk<aMax;kk++) aMat[kk]=0;
576
577 TopTools_MapIteratorOfMapOfShape anMIter(aSMap);
578 Standard_Integer n = 1;
579 Standard_Integer connect;
580 const TopoDS_Shape& aFirstShape = anMIter.Key();
581
582 // aMat(n,n) = 1.;
583 aMat[0] = 1;
584
585 anExp.Init(aFirstShape, TopAbs_VERTEX);
586 for(; anExp.More(); anExp.Next()) {
587 aMap.Bind(anExp.Current(), n);
588 }
589
590 anMIter.Next();
591
592 for(; anMIter.More(); anMIter.Next()) {
593 ++n;
594 aMat[(n-1)*nbs+n-1] = 1;
595 // aMat(n,n) = 1.;
596
597 const TopoDS_Shape& aShape = anMIter.Key();
598
599 anExp.Init(aShape, TopAbs_VERTEX);
600 for(; anExp.More(); anExp.Next()) {
601 if(aMap.IsBound(anExp.Current())) {
602 connect = aMap(anExp.Current());
603 //aMat(n, connect) = 1.;
604 //aMat(connect, n) = 1.;
605 aMat[(n-1)*nbs+connect-1] = 1;
606 aMat[(connect-1)*nbs+n-1] = 1;
607 }
608 else {
609 aMap.Bind(anExp.Current(), n);
610 }
611 }
612 }
613 //cout << "QANewModTopOpe::IsConnected(3)Lnbs=" <<nbs<< endl;
614
615 Standard_Integer k,i,ncount=0;
616 Standard_Real p;
617 Standard_Boolean aNotChanged;
618 // math_Vector aRow(1, nbs), aCol(1, nbs);
619
620 // aRow = aMat.Row(1);
621
622 for(k = 1; k <= nbs; k++) {
623 aRes = Standard_True;
624 aNotChanged = Standard_True;
625 for(n = 1; n <= nbs; n++) {
626 // if(aMat(1, n) < 1.) {
627 if(aMat[n-1] == 0) {
628 // aRow = aMat.Row(1);
629 //aCol = aMat.Col(n);
630 p=0.;
631 for(i=1;i<=nbs;i++) {
632 //ncount++;
633 // if(aMat(1,i) > 0. && aMat(i,n)> 0.) {
634 if(aMat[i-1] == 1 && aMat[(i-1)*nbs+n-1] == 1) {
635 p=1.;
636 break;
637 }
638 // p+=aMat(1,i)*aMat(i,n);
639 }
640 //p = aRow*aCol;
641 if(p > 0.0) {
642 // aMat(1, n) = 1.0;
643 // aMat(n, 1) = 1.0;
644 aMat[n-1] = 1;
645 aMat[(n-1)*nbs+1-1] = 1;
646 aNotChanged = Standard_False;
647 }
648 aRes = Standard_False;
649 }
650 }
651 if(aNotChanged) break;
652 if(aRes) break;
653 }
654 delete aMat;
655
656 // cout << "QANewModTopOpe::IsConnected END: aRes="<<aRes << ";ncount="<<ncount<<endl;
657 cout << "QANewModTopOpe::IsConnected END: aRes="<<aRes <<endl;
658 return aRes;
659
660}
661
662
663// @@SDM: begin
664
665// Copyright SAMTECH ..........................................Version 3.0-00
666// Lastly modified by : pat Date : 04/16/03
667
668// File history synopsis (creation,modification,correction)
669// +---------------------------------------------------------------------------+
670// ! Developer ! Comments ! Date ! Version !
671// +-----------!-----------------------------------------!----------!----------+
672// ! ifv ! Creation !28-01-2002! 3.0-00-1!
673// ! ivan ! print de trace ! 01/21/03! 4.0-1!
674// ! pat ! Optimise IsConnected() ! 04/16/03! 4.0-2!
675// +---------------------------------------------------------------------------+
676
677// @@SDM: end