Salome HOME
Fix bug in structural elements (PAL #2012)
[modules/geom.git] / src / NMTDS / NMTDS_Iterator.cxx
1 // Copyright (C) 2007-2011  CEA/DEN, EDF R&D, OPEN CASCADE
2 //
3 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
5 //
6 // This library is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU Lesser General Public
8 // License as published by the Free Software Foundation; either
9 // version 2.1 of the License.
10 //
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 // Lesser General Public License for more details.
15 //
16 // You should have received a copy of the GNU Lesser General Public
17 // License along with this library; if not, write to the Free Software
18 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
19 //
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
21 //
22
23 // File:        NMTDS_Iterator.cxx
24 // Created:     Sun May 07 15:04:41 2006
25 // Author:      Peter KURNEV
26 //
27 #include <NMTDS_Iterator.ixx>
28 //
29 #include <Bnd_Box.hxx>
30 //
31 #include <TColStd_ListOfInteger.hxx>
32 #include <TColStd_ListIteratorOfListOfInteger.hxx>
33 #include <TColStd_MapOfInteger.hxx>
34 #include <TColStd_MapIteratorOfMapOfInteger.hxx>
35 #include <TColStd_DataMapOfIntegerInteger.hxx>
36 #include <TColStd_DataMapOfIntegerListOfInteger.hxx>
37 #include <TColStd_DataMapIteratorOfDataMapOfIntegerListOfInteger.hxx>
38 #include <TColStd_MapOfInteger.hxx>
39 //
40 #include <TopoDS.hxx>
41 #include <TopoDS_Vertex.hxx>
42 #include <TopoDS_Shape.hxx>
43 //
44 #include <TopTools_DataMapOfShapeInteger.hxx>
45 //
46 #include <NMTDS_BoxBndTree.hxx>
47 #include <NCollection_UBTreeFiller.hxx>
48 #include <NMTDS_CArray1OfIndexRange.hxx>
49 #include <NMTDS_IndexRange.hxx>
50 #include <NMTDS_PassKeyBoolean.hxx>
51 #include <NMTDS_MapOfPassKeyBoolean.hxx>
52 #include <NMTDS_IndexedDataMapOfShapeBox.hxx>
53 #include <NMTDS_IndexedDataMapOfIntegerShape.hxx>
54 #include <NMTDS_Tools.hxx>
55 #include <NMTDS_DataMapOfIntegerMapOfInteger.hxx>
56 #include <NMTDS_DataMapIteratorOfDataMapOfIntegerMapOfInteger.hxx>
57
58 //=======================================================================
59 //function : NMTDS_Iterator
60 //purpose  : 
61 //=======================================================================
62   NMTDS_Iterator::NMTDS_Iterator()
63 {
64   myDS=NULL; 
65   myLength=0;
66 }
67 //=======================================================================
68 //function : ~NMTDS_Iterator
69 //purpose  : 
70 //=======================================================================
71   NMTDS_Iterator::~NMTDS_Iterator()
72 {
73 }
74 //=======================================================================
75 // function: SetDS
76 // purpose: 
77 //=======================================================================
78   void NMTDS_Iterator::SetDS(const NMTDS_PShapesDataStructure& aDS)
79 {
80   myDS=aDS;
81 }
82 //=======================================================================
83 // function: DS
84 // purpose: 
85 //=======================================================================
86   const NMTDS_ShapesDataStructure&  NMTDS_Iterator::DS()const
87 {
88   return *myDS;
89 }
90 //=======================================================================
91 // function: ExpectedLength
92 // purpose: 
93 //=======================================================================
94   Standard_Integer NMTDS_Iterator::ExpectedLength() const
95 {
96   return myLength;
97 }
98 //=======================================================================
99 // function: BlockLength
100 // purpose: 
101 //=======================================================================
102   Standard_Integer NMTDS_Iterator::BlockLength() const
103 {
104   Standard_Integer aNbIIs;
105   Standard_Real aCfPredict=.5;
106   
107   aNbIIs=ExpectedLength();
108   
109   if (aNbIIs<=1) {
110     return 1;
111   }
112   //
113   aNbIIs=(Standard_Integer) (aCfPredict*(Standard_Real)aNbIIs);
114   return aNbIIs;
115 }
116 //=======================================================================
117 // function: Initialize
118 // purpose: 
119 //=======================================================================
120   void NMTDS_Iterator::Initialize(const TopAbs_ShapeEnum aType1,
121                                   const TopAbs_ShapeEnum aType2)
122 {
123   Standard_Integer iX;
124   //
125   iX=NMTDS_Tools::TypeToInteger(aType1, aType2);
126   if (iX>=0) {
127     myIterator.Initialize(myLists[iX]);
128     myLength=myLists[iX].Extent();
129   }
130   else {
131     myIterator.Initialize(myEmptyList);
132     myLength=0;
133   }
134 }
135 //=======================================================================
136 // function: More
137 // purpose: 
138 //=======================================================================
139   Standard_Boolean NMTDS_Iterator::More()const
140 {
141   return myIterator.More();
142 }
143 //=======================================================================
144 // function: Next
145 // purpose: 
146 //=======================================================================
147   void NMTDS_Iterator::Next()
148 {
149   myIterator.Next();
150 }
151 //=======================================================================
152 // function: Current
153 // purpose: 
154 //=======================================================================
155   void NMTDS_Iterator::Current(Standard_Integer& aIndex1,
156                                Standard_Integer& aIndex2,
157                                Standard_Boolean& aWithSubShape) const
158 {
159   const NMTDS_PassKeyBoolean& aPKB=myIterator.Value();
160   aPKB.Ids(aIndex1, aIndex2);
161   aWithSubShape=aPKB.Flag();
162 }
163 //=======================================================================
164 // function: SDVertices
165 // purpose: 
166 //=======================================================================
167   const TColStd_DataMapOfIntegerListOfInteger& NMTDS_Iterator::SDVertices()const
168 {
169   return myMVSD;
170 }
171 //=======================================================================
172 // function: Prepare
173 // purpose: 
174 //=======================================================================
175   void NMTDS_Iterator::Prepare()
176 {
177   Standard_Integer i;
178   //
179   myLength=0;
180   for (i=0; i<6; ++i) {
181     myLists[i].Clear();
182   }
183   myMVSD.Clear();
184   //
185   if (myDS==NULL){
186     return;
187   }
188   Intersect();
189 }
190 //=======================================================================
191 // function: Intersect
192 // purpose: 
193 //=======================================================================
194   void NMTDS_Iterator::Intersect()
195 {
196   Standard_Boolean bFlag;
197   Standard_Integer aNb, i, aNbB, aNbR, iFlag;
198   Standard_Integer i1, i2, aNbSD, iX, j, iDS, jB, iR, k, aNbLV, aNbLV1;
199   TColStd_ListIteratorOfListOfInteger aIt;
200   TColStd_DataMapOfIntegerInteger aMII;
201   TColStd_DataMapOfIntegerListOfInteger aMVSD;
202   TColStd_DataMapIteratorOfDataMapOfIntegerListOfInteger aItVSD;
203   TopTools_DataMapOfShapeInteger aMSI;
204   TopAbs_ShapeEnum aTi, aTj;
205   NMTDS_PassKeyBoolean aPKXB; 
206   NMTDS_MapOfPassKeyBoolean aMPKXB;
207   NMTDS_IndexedDataMapOfShapeBox aMSB;
208   //
209   NMTDS_BoxBndTreeSelector aSelector;
210   NMTDS_BoxBndTree aBBTree;
211   NCollection_UBTreeFiller <Standard_Integer, Bnd_Box> aTreeFiller(aBBTree);
212   //
213   const NMTDS_CArray1OfIndexRange& aRanges=myDS->Ranges();
214   aNbR=aRanges.Extent();
215   //
216   aNb=myDS->NumberOfShapesOfTheObject();
217   for (i=1; i<=aNb; ++i) {
218     const TopoDS_Shape& aS=myDS->Shape(i);
219     aTi=aS.ShapeType();
220     if (NMTDS_Tools::HasBRep(aTi)) {
221       Bnd_Box aBoxEx;
222       //
223       myDS->ComputeBoxEx(i, aBoxEx);
224       aMSI.Bind(aS, i);
225       aMSB.Add(aS, aBoxEx);
226     }
227   }
228   //
229   aNbB=aMSB.Extent();
230   //
231   for (i=1; i<=aNbB; ++i) {
232     const TopoDS_Shape& aS=aMSB.FindKey(i);
233     const Bnd_Box& aBoxEx=aMSB(i);
234     //
235     aTreeFiller.Add(i, aBoxEx);
236     //
237     iDS=aMSI.Find(aS);
238     aMII.Bind(i, iDS);
239   }
240   //
241   aTreeFiller.Fill();
242   //
243   for (iR=1; iR<aNbR; ++iR) {
244     const NMTDS_IndexRange& aR=aRanges(iR);
245     i1=aR.First();
246     i2=aR.Last();
247     for (i=i1; i<=i2; ++i) {
248       const TopoDS_Shape& aSi=myDS->Shape(i);
249       aTi=aSi.ShapeType();
250       if (!NMTDS_Tools::HasBRep(aTi)){
251         continue;
252       }
253       const Bnd_Box& aBoxEx=aMSB.FindFromKey(aSi);
254       aSelector.Clear();
255       aSelector.SetBox(aBoxEx);
256       //
257       aNbSD=aBBTree.Select(aSelector);
258       //
259       if (!aNbSD){
260         continue;
261       }
262       //
263       const TColStd_ListOfInteger& aLI=aSelector.Indices();
264       //
265       k=0;
266       TColStd_ListOfInteger aLV;
267       //
268       aIt.Initialize(aLI);
269       for (; aIt.More(); aIt.Next()) {
270         jB=aIt.Value();  // box index in MII
271         j=aMII.Find(jB); // DS index
272         if (j>=i1 && j<=i2) {
273           continue;// same range
274         }
275         //
276         aPKXB.SetIds(i, j);
277         //
278         if (aMPKXB.Add(aPKXB)) {
279           bFlag=Standard_False;// Bounding boxes are intersected
280           const Bnd_Box& aBoxi=myDS->GetBoundingBox(i);
281           const Bnd_Box& aBoxj=myDS->GetBoundingBox(j);
282           if (aBoxi.IsOut(aBoxj)) {
283             bFlag=!bFlag; //Bounding boxes of Sub-shapes are intersected
284           }
285           const TopoDS_Shape& aSj=myDS->Shape(j);
286           aTj=aSj.ShapeType();
287           iX=NMTDS_Tools::TypeToInteger(aTi, aTj);
288           //bFlag=(iStatus==2);
289           aPKXB.SetFlag(bFlag);
290           myLists[iX].Append(aPKXB);
291           //
292           // VSD prepare
293           if (iX==5) { //VV
294             aLV.Append(j);
295           }
296         }// if (aMPKXB.Add(aPKXB)) {
297       }// for (; aIt.More(); aIt.Next()) {
298       //
299       // VSD treatment
300       aNbLV=aLV.Extent();
301       if (aNbLV) {
302         TColStd_ListOfInteger aLV1;
303         //
304         const TopoDS_Vertex& aVi=TopoDS::Vertex(aSi);
305         aIt.Initialize(aLV);
306         for (; aIt.More(); aIt.Next()) {
307           j=aIt.Value();  
308           const TopoDS_Shape&  aSj=myDS->Shape(j);
309           const TopoDS_Vertex& aVj=TopoDS::Vertex(aSj);
310           iFlag=NMTDS_Tools::ComputeVV(aVi, aVj);
311           if (!iFlag) {
312             aLV1.Append(j);
313           }
314           else {
315             aPKXB.SetIds(i, j);
316             aMPKXB.Remove(aPKXB);
317           }
318         }
319         //
320         //modified by NIZNHY-PKV Mon Sep 27 08:31:04 2010f
321         aNbLV1=aLV1.Extent();
322         if (aNbLV1) {
323           aMVSD.Bind(i, aLV1);
324         }
325         //aMVSD.Bind(i, aLV1);
326         //modified by NIZNHY-PKV Mon Sep 27 08:31:21 2010t
327       }
328     }//for (i=i1; i<=i2; ++i) {
329   }//for (iR=1; iR<aNbR; ++iR) {
330   //
331   //
332   // Chains
333   //=================
334   myMVSD.Clear();
335   NMTDS_Iterator::FillMVSD(aMVSD, myMVSD);
336 }
337 //=======================================================================
338 //function : FillMVSD
339 //purpose  : 
340 //=======================================================================
341   void NMTDS_Iterator::FillMVSD(const TColStd_DataMapOfIntegerListOfInteger& aMVSD,
342                                 TColStd_DataMapOfIntegerListOfInteger& bMVSD)
343 {
344   Standard_Boolean bFound;
345   Standard_Integer aNbVSD, iCnt, i, j, k;
346   TColStd_ListOfInteger aLV;
347   TColStd_ListIteratorOfListOfInteger aIt;
348   TColStd_MapOfInteger aMF;
349   TColStd_MapIteratorOfMapOfInteger aItMI;
350   TColStd_DataMapIteratorOfDataMapOfIntegerListOfInteger aItVSD;
351   NMTDS_DataMapOfIntegerMapOfInteger aDMIMI;
352   NMTDS_DataMapIteratorOfDataMapOfIntegerMapOfInteger aIti, aItj;
353   //
354   aNbVSD=aMVSD.Extent();
355   if (!aNbVSD) {
356     return;
357   }
358   //
359   aItVSD.Initialize(aMVSD);
360   for (; aItVSD.More(); aItVSD.Next()) {
361     TColStd_MapOfInteger aMI;
362     //
363     i=aItVSD.Key();
364     aMI.Add(i);
365     const TColStd_ListOfInteger& aLVSD=aItVSD.Value();
366     aIt.Initialize(aLVSD);
367     for (; aIt.More(); aIt.Next()) {
368       j=aIt.Value();
369       aMI.Add(j);
370     }
371     aDMIMI.Bind(i, aMI);
372   }
373   // i
374   aIti.Initialize(aDMIMI);
375   for (; aIti.More(); aIti.Next()) {
376     i=aIti.Key();
377     if (aMF.Contains(i)) {
378       continue;
379     }
380     aMF.Add(i);
381     //
382     //TColStd_MapOfInteger& aMIi=aDMIMI.ChangeFind(i);
383     TColStd_MapOfInteger *pMIi=(TColStd_MapOfInteger *)&aIti.Value();
384     TColStd_MapOfInteger& aMIi=*pMIi;
385     //  j
386     while (1) {
387       iCnt=0;
388       aItj.Initialize(aDMIMI);
389       for (; aItj.More(); aItj.Next()) {
390         j=aItj.Key();
391         if (aMF.Contains(j)) {
392           continue;
393         }
394         //
395         //TColStd_MapOfInteger& aMIj=aDMIMI.ChangeFind(j);
396         TColStd_MapOfInteger *pMj=(TColStd_MapOfInteger *)&aItj.Value();
397         TColStd_MapOfInteger& aMIj=*pMj;
398         //
399         aItMI.Initialize(aMIj);
400         for (; aItMI.More(); aItMI.Next()) {
401           k=aItMI.Key();
402           bFound=aMIi.Contains(k);
403           if (bFound) {
404             break;
405           }
406         }
407         if (!bFound) {
408           continue;
409         }
410         //
411         aItMI.Initialize(aMIj);
412         for (; aItMI.More(); aItMI.Next()) {
413           k=aItMI.Key();
414           aMIi.Add(k);
415         }
416         //
417         if (aMF.Add(j)) {
418           ++iCnt;
419         }
420       } //for (; aItj.More(); aItj.Next()) {
421       if (!iCnt) {
422         break;
423       }
424     } // while (1) {
425     //
426     aLV.Clear();
427     aItMI.Initialize(aMIi);
428     for (; aItMI.More(); aItMI.Next()) {
429       k=aItMI.Key();
430         if (k!=i) {
431           aLV.Append(k);
432         }
433     }
434     bMVSD.Bind(i, aLV);
435   }// for (; aIti.More(); aIti.Next()) {
436 }
437
438   /*  
439   {
440     // check
441     TColStd_DataMapIteratorOfDataMapOfIntegerListOfInteger aItX;
442     //
443     printf(" \n");
444     printf(" myMVSD.Extent()=%d\n", myMVSD.Extent());
445     aItX.Initialize(myMVSD);
446     for (; aItX.More(); aItX.Next()) {
447       i=aItX.Key();
448       printf(" i=%d (", i);
449       const TColStd_ListOfInteger& aLV=aItX.Value();
450       aIt.Initialize(aLV);
451       for (; aIt.More(); aIt.Next()) {
452         j=aIt.Value();
453         printf(" %d", j);
454       }
455       printf(")\n");
456     }
457   }
458 */
459