Salome HOME
This commit was generated by cvs2git to create tag 'TRIPOLI_323'.
[modules/geom.git] / src / GEOMAlgo / GEOMAlgo_GlueDetector.cxx
1 // Copyright (C) 2007-2012  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:        GEOMAlgo_GlueDetector.cxx
24 // Author:      Peter KURNEV
25
26 #include <GEOMAlgo_GlueDetector.hxx>
27
28 #include <Bnd_Box.hxx>
29 #include <NCollection_UBTreeFiller.hxx>
30
31 #include <TColStd_ListOfInteger.hxx>
32 #include <TColStd_ListIteratorOfListOfInteger.hxx>
33 #include <TColStd_MapIteratorOfMapOfInteger.hxx>
34
35 #include <TopoDS_Shape.hxx>
36 #include <TopoDS_Face.hxx>
37 #include <TopoDS_Edge.hxx>
38 #include <TopoDS_Compound.hxx>
39 #include <TopoDS_Vertex.hxx>
40 #include <TopoDS_Iterator.hxx>
41 #include <TopoDS_Compound.hxx>
42
43 #include <TopTools_IndexedMapOfShape.hxx>
44 #include <TopTools_ListOfShape.hxx>
45 #include <TopTools_ListIteratorOfListOfShape.hxx>
46 #include <TopTools_DataMapIteratorOfDataMapOfShapeListOfShape.hxx>
47 #include <TopTools_MapOfShape.hxx>
48 #include <TopTools_MapIteratorOfMapOfShape.hxx>
49
50 #include <TopExp.hxx>
51 #include <BRep_Tool.hxx>
52 #include <BRep_Builder.hxx>
53 #include <BRepBndLib.hxx>
54
55 #include <NMTDS_BndSphereTree.hxx>
56 #include <NMTDS_BndSphere.hxx>
57 #include <NMTDS_IndexedDataMapOfShapeBndSphere.hxx>
58
59 #include <GEOMAlgo_IndexedDataMapOfIntegerShape.hxx>
60 #include <GEOMAlgo_PassKeyShape.hxx>
61 #include <GEOMAlgo_IndexedDataMapOfPassKeyShapeListOfShape.hxx>
62 #include <GEOMAlgo_Tools.hxx>
63 //
64 #include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
65 #include <TopExp.hxx>
66 #include <TopExp_Explorer.hxx>
67 #include <TopTools_MapOfShape.hxx>
68
69 //modified by NIZNHY-PKV Tue Mar 13 10:25:47 2012f
70 static
71   Standard_Integer CheckAncesstors
72   (const TopoDS_Shape& aVSD,
73    const TopTools_MapOfShape& aMVSD,
74    const TopTools_IndexedDataMapOfShapeListOfShape& aMVE,
75    const TopTools_IndexedDataMapOfShapeListOfShape& aMEV,
76    TopTools_IndexedDataMapOfShapeListOfShape& aMEVZ);
77 //modified by NIZNHY-PKV Tue Mar 13 10:25:50 2012t
78
79 //=======================================================================
80 //function :
81 //purpose  :
82 //=======================================================================
83 GEOMAlgo_GlueDetector::GEOMAlgo_GlueDetector()
84 :
85   GEOMAlgo_GluerAlgo(),
86   GEOMAlgo_Algo()
87 {}
88 //=======================================================================
89 //function : ~
90 //purpose  :
91 //=======================================================================
92 GEOMAlgo_GlueDetector::~GEOMAlgo_GlueDetector()
93 {}
94 //modified by NIZNHY-PKV Tue Mar 13 12:26:50 2012f
95 //=======================================================================
96 //function : StickedShapes
97 //purpose  :
98 //=======================================================================
99 const TopTools_IndexedDataMapOfShapeListOfShape&
100   GEOMAlgo_GlueDetector::StickedShapes()
101 {
102   return myStickedShapes;
103 }
104 //modified by NIZNHY-PKV Tue Mar 13 12:26:54 2012t
105 //=======================================================================
106 //function : Perform
107 //purpose  :
108 //=======================================================================
109 void GEOMAlgo_GlueDetector::Perform()
110 {
111   myErrorStatus=0;
112   myWarningStatus=0;
113   myStickedShapes.Clear();
114   //
115   CheckData();
116   if (myErrorStatus) {
117     return;
118   }
119   //
120   // Initialize the context
121   GEOMAlgo_GluerAlgo::Perform();
122   //
123   DetectVertices();
124   if (myErrorStatus) {
125     return;
126   }
127   //
128   //modified by NIZNHY-PKV Wed Mar 14 08:00:09 2012f
129   CheckDetected();
130   if (myErrorStatus) {
131     return;
132   }
133   //modified by NIZNHY-PKV Wed Mar 14 08:00:12 2012t
134   //
135   DetectEdges();
136   if (myErrorStatus) {
137     return;
138   }
139   //
140   DetectFaces();
141   if (myErrorStatus) {
142     return;
143   }
144 }
145 //=======================================================================
146 //function : DetectVertices
147 //purpose  :
148 //=======================================================================
149 void GEOMAlgo_GlueDetector::DetectVertices()
150 {
151   Standard_Integer j, i, aNbV, aNbVSD;
152   Standard_Real aTolV;
153   gp_Pnt aPV;
154   TColStd_ListIteratorOfListOfInteger aIt;
155   TopoDS_Shape aVF;
156   TopTools_IndexedMapOfShape aMV;
157   TopTools_MapOfShape aMVProcessed;
158   TopTools_ListIteratorOfListOfShape aItS;
159   TopTools_DataMapIteratorOfDataMapOfShapeListOfShape aItIm;
160   TopTools_DataMapOfShapeListOfShape aMVV;
161   GEOMAlgo_IndexedDataMapOfIntegerShape aMIS;
162   NMTDS_IndexedDataMapOfShapeBndSphere aMSB;
163   NMTDS_BndSphereTreeSelector aSelector;
164   NMTDS_BndSphereTree aBBTree;
165   NCollection_UBTreeFiller <Standard_Integer, NMTDS_BndSphere> aTreeFiller(aBBTree);
166   //
167   myErrorStatus=0;
168   //
169   TopExp::MapShapes(myArgument, TopAbs_VERTEX, aMV);
170   aNbV=aMV.Extent();
171   if (!aNbV) {
172     myErrorStatus=2; // no vertices in source shape
173     return;
174   }
175   //
176   for (i=1; i<=aNbV; ++i) {
177     NMTDS_BndSphere aBox;
178     //
179     const TopoDS_Vertex& aV=*((TopoDS_Vertex*)&aMV(i));
180     aPV=BRep_Tool::Pnt(aV);
181     aTolV=BRep_Tool::Tolerance(aV);
182     //
183     aBox.SetGap(myTolerance);
184     aBox.SetCenter(aPV);
185     aBox.SetRadius(aTolV);
186     //
187     aTreeFiller.Add(i, aBox);
188     //
189     aMIS.Add(i, aV);
190     aMSB.Add(aV, aBox);
191   }
192   //
193   aTreeFiller.Fill();
194   //
195   //---------------------------------------------------
196   // Chains
197   for (i=1; i<=aNbV; ++i) {
198     const TopoDS_Shape& aV=aMV(i);
199     //
200     if (aMVProcessed.Contains(aV)) {
201       continue;
202     }
203     //
204     Standard_Integer aNbIP, aIP, aNbIP1, aIP1;
205     TopTools_ListOfShape aLVSD;
206     TColStd_MapOfInteger aMIP, aMIP1, aMIPC;
207     TColStd_MapIteratorOfMapOfInteger aIt1;
208     //
209     aMIP.Add(i);
210     while(1) {
211       aNbIP=aMIP.Extent();
212       aIt1.Initialize(aMIP);
213       for(; aIt1.More(); aIt1.Next()) {
214         aIP=aIt1.Key();
215         if (aMIPC.Contains(aIP)) {
216           continue;
217         }
218         //
219         const TopoDS_Shape& aVP=aMIS.FindFromKey(aIP);
220         const NMTDS_BndSphere& aBoxVP=aMSB.FindFromKey(aVP);
221         //
222         aSelector.Clear();
223         aSelector.SetBox(aBoxVP);
224         //
225         aNbVSD=aBBTree.Select(aSelector);
226         if (!aNbVSD) {
227           continue;  // it shoild not be so [at least IP itself]
228         }
229         //
230         const TColStd_ListOfInteger& aLI=aSelector.Indices();
231         aIt.Initialize(aLI);
232         for (; aIt.More(); aIt.Next()) {
233           aIP1=aIt.Value();
234           if (aMIP.Contains(aIP1)) {
235             continue;
236           }
237           aMIP1.Add(aIP1);
238         } //for (; aIt.More(); aIt.Next()) {
239       }//for(; aIt1.More(); aIt1.Next()) {
240       //
241       aNbIP1=aMIP1.Extent();
242       if (!aNbIP1) {
243         break;
244       }
245       //
246       aIt1.Initialize(aMIP);
247       for(; aIt1.More(); aIt1.Next()) {
248         aIP=aIt1.Key();
249         aMIPC.Add(aIP);
250       }
251       //
252       aMIP.Clear();
253       aIt1.Initialize(aMIP1);
254       for(; aIt1.More(); aIt1.Next()) {
255         aIP=aIt1.Key();
256         aMIP.Add(aIP);
257       }
258       aMIP1.Clear();
259     }// while(1)
260     //
261     // Fill myImages
262     aNbIP=aMIPC.Extent();
263     //
264     if (!aNbIP) {// no SD vertices is found
265       aMVProcessed.Add(aV);
266       continue;
267     }
268     //else { // SD vertices founded [ aMIPC ]
269     aIt1.Initialize(aMIPC);
270     for(j=0; aIt1.More(); aIt1.Next(), ++j) {
271       aIP=aIt1.Key();
272       const TopoDS_Shape& aVP=aMIS.FindFromKey(aIP);
273       if (!j) {
274         aVF=aVP;
275       }
276       aLVSD.Append(aVP);
277       aMVProcessed.Add(aVP);
278     }
279     //}
280     myImages.Bind(aVF, aLVSD);
281   }// for (i=1; i<=aNbV; ++i) {
282   //------------------------------
283   // Origins
284   aItIm.Initialize(myImages);
285   for (; aItIm.More(); aItIm.Next()) {
286     const TopoDS_Shape& aV=aItIm.Key();
287     const TopTools_ListOfShape& aLVSD=aItIm.Value();
288     aItS.Initialize(aLVSD);
289     for (; aItS.More(); aItS.Next()) {
290       const TopoDS_Shape& aVSD=aItS.Value();
291       if (!myOrigins.IsBound(aVSD)) {
292         myOrigins.Bind(aVSD, aV);
293       }
294     }
295   }
296 }
297 //=======================================================================
298 //function : DetectFaces
299 //purpose  :
300 //=======================================================================
301 void GEOMAlgo_GlueDetector::DetectFaces()
302 {
303   DetectShapes(TopAbs_FACE);
304 }
305 //=======================================================================
306 //function : DetectEdges
307 //purpose  :
308 //=======================================================================
309 void GEOMAlgo_GlueDetector::DetectEdges()
310 {
311   DetectShapes(TopAbs_EDGE);
312 }
313 //=======================================================================
314 //function : DetectShapes
315 //purpose  :
316 //=======================================================================
317 void GEOMAlgo_GlueDetector::DetectShapes(const TopAbs_ShapeEnum aType)
318 {
319   Standard_Boolean bDegenerated;
320   Standard_Integer i, aNbF, aNbSDF, iErr;
321   TopTools_IndexedMapOfShape aMF;
322   TopTools_ListIteratorOfListOfShape aItLS;
323   GEOMAlgo_PassKeyShape aPKF;
324   GEOMAlgo_IndexedDataMapOfPassKeyShapeListOfShape aMPKLF;
325   //
326   myErrorStatus=0;
327   //
328   TopExp::MapShapes(myArgument, aType, aMF);
329   //
330   aNbF=aMF.Extent();
331   for (i=1; i<=aNbF; ++i) {
332     const TopoDS_Shape& aS=aMF(i);
333     //
334     if (aType==TopAbs_FACE) {
335       const TopoDS_Face& aF=*((TopoDS_Face*)&aS);
336       FacePassKey(aF, aPKF);
337     }
338     else if (aType==TopAbs_EDGE) {
339       const TopoDS_Edge& aE=*((TopoDS_Edge*)&aS);
340       EdgePassKey(aE, aPKF);
341     }
342     //
343     if (myErrorStatus) {
344       return;
345     }
346     //
347     if (aMPKLF.Contains(aPKF)) {
348       TopTools_ListOfShape& aLSDF=aMPKLF.ChangeFromKey(aPKF);
349       aLSDF.Append(aS);
350     }
351     else {
352       TopTools_ListOfShape aLSDF;
353       //
354       aLSDF.Append(aS);
355       aMPKLF.Add(aPKF, aLSDF);
356     }
357   }
358   // check geometric coincidence
359   if (myCheckGeometry) {
360     iErr=GEOMAlgo_Tools::RefineSDShapes(aMPKLF, myTolerance, myContext);
361     if (iErr) {
362       myErrorStatus=200;
363       return;
364     }
365   }
366   //
367   // Images/Origins
368   aNbF=aMPKLF.Extent();
369   for (i=1; i<=aNbF; ++i) {
370     const TopTools_ListOfShape& aLSDF=aMPKLF(i);
371     aNbSDF=aLSDF.Extent();
372     if (!aNbSDF) {
373       myErrorStatus=4; // it must not be
374     }
375     //
376     if (aNbSDF==1) {
377       continue;
378     }
379     //
380     const TopoDS_Shape& aS1=aLSDF.First();
381     //
382     if (aType==TopAbs_EDGE) {
383       const TopoDS_Edge& aE1=*((TopoDS_Edge*)&aS1);
384       bDegenerated=BRep_Tool::Degenerated(aE1);
385       if (bDegenerated) {
386         continue;
387       }
388     }
389     //
390     myImages.Bind(aS1, aLSDF);
391     //
392     // origins
393     aItLS.Initialize(aLSDF);
394     for (; aItLS.More(); aItLS.Next()) {
395       const TopoDS_Shape& aFSD=aItLS.Value();
396       if (!myOrigins.IsBound(aFSD)) {
397         myOrigins.Bind(aFSD, aS1);
398       }
399     }
400   }// for (i=1; i<=aNbF; ++i)
401 }
402 //=======================================================================
403 //function : FacePassKey
404 //purpose  :
405 //=======================================================================
406 void GEOMAlgo_GlueDetector::FacePassKey(const TopoDS_Face& aF,
407                                         GEOMAlgo_PassKeyShape& aPK)
408 {
409   Standard_Integer i, aNbE;
410   TopoDS_Shape aER;
411   TopTools_ListOfShape aLE;
412   TopTools_IndexedMapOfShape aME;
413   //
414   TopExp::MapShapes(aF, TopAbs_EDGE, aME);
415   //
416   aNbE=aME.Extent();
417   for (i=1; i<=aNbE; ++i) {
418     const TopoDS_Shape& aE=aME(i);
419     //
420     const TopoDS_Edge& aEE=*((TopoDS_Edge*)&aE);
421     if (BRep_Tool::Degenerated(aEE)) {
422       continue;
423     }
424     //
425     if (myOrigins.IsBound(aE)) {
426       aER=myOrigins.Find(aE);
427     }
428     else {
429       aER=aE;
430     }
431     aLE.Append(aER);
432   }
433   aPK.SetShapes(aLE);
434 }
435 //=======================================================================
436 //function : EdgePassKey
437 //purpose  :
438 //=======================================================================
439 void GEOMAlgo_GlueDetector::EdgePassKey(const TopoDS_Edge& aE,
440                                         GEOMAlgo_PassKeyShape& aPK)
441 {
442   TopAbs_Orientation aOr;
443   TopoDS_Shape aVR;
444   TopoDS_Iterator aIt;
445   TopTools_ListOfShape aLV;
446   //
447   aIt.Initialize(aE);
448   for (; aIt.More(); aIt.Next()) {
449     const TopoDS_Shape& aV=aIt.Value();
450     aOr=aV.Orientation();
451     if (aOr==TopAbs_FORWARD || aOr==TopAbs_REVERSED) {
452       if (myOrigins.IsBound(aV)) {
453         aVR=myOrigins.Find(aV);
454       }
455       else {
456         aVR=aV;
457       }
458       aLV.Append(aVR);
459     }
460   }
461   //
462   aPK.SetShapes(aLV);
463 }
464 //modified by NIZNHY-PKV Tue Mar 13 09:54:18 2012f
465 //=======================================================================
466 //function : CheckDetected
467 //purpose  :
468 //=======================================================================
469 void GEOMAlgo_GlueDetector::CheckDetected()
470 {
471   TopoDS_Iterator aItA;
472   TopExp_Explorer aExp;
473   TopTools_ListOfShape aLV;
474   TopTools_MapOfShape aMFence;
475   TopTools_DataMapIteratorOfDataMapOfShapeListOfShape aItIm;
476   TopTools_IndexedDataMapOfShapeListOfShape aMVE, aMEV;
477   //
478   // 1. aMVE, aMEV
479   TopExp::MapShapesAndAncestors(myArgument, TopAbs_VERTEX, TopAbs_EDGE, aMVE);
480   //
481   aExp.Init(myArgument, TopAbs_EDGE);
482   for (; aExp.More(); aExp.Next()) {
483     const TopoDS_Shape& aE=aExp.Current();
484     //
485     aLV.Clear();
486     aMFence.Clear();
487     aItA.Initialize(aE);
488     for (; aItA.More(); aItA.Next()) {
489       const TopoDS_Shape& aV=aItA.Value();
490       if (aMFence.Add(aV)) {
491         aLV.Append(aV);
492       }
493     }
494     //
495     aMEV.Add(aE, aLV);
496   }
497   // 2. Checking
498   aItIm.Initialize(myImages);
499   for (; aItIm.More(); aItIm.Next()) {
500     //const TopoDS_Shape& aV=aItIm.Key();
501     const TopTools_ListOfShape& aLVSD=aItIm.Value();
502     CheckDetected(aLVSD, aMVE, aMEV);
503   }
504 }
505 //=======================================================================
506 //function : CheckDetected
507 //purpose  :
508 //=======================================================================
509 void GEOMAlgo_GlueDetector::CheckDetected
510   (const TopTools_ListOfShape& aLVSD,
511    const TopTools_IndexedDataMapOfShapeListOfShape& aMVE,
512    const TopTools_IndexedDataMapOfShapeListOfShape& aMEV)
513 {
514   Standard_Integer i, aNbVSD, aNbA, iRet;
515   TopAbs_ShapeEnum aTypeS, aTypeA[2];
516   TopExp_Explorer aExp, aExpA;
517   TopTools_MapOfShape aMFence, aMVSD;
518   TopTools_ListOfShape aLV;
519   TopTools_ListIteratorOfListOfShape aItLS;
520   //
521   myErrorStatus=0;
522   //
523   aNbVSD=aLVSD.Extent();
524   if (aNbVSD < 2) {
525     return ;
526   }
527   //
528   aItLS.Initialize(aLVSD);
529   for (; aItLS.More(); aItLS.Next()) {
530     const TopoDS_Shape& aVSD=aItLS.Value();
531     aMVSD.Add(aVSD);
532   }
533   //
534   aItLS.Initialize(aLVSD);
535   for (; aItLS.More(); aItLS.Next()) {
536     const TopoDS_Shape& aVSD=aItLS.Value();
537     //
538     iRet=CheckAncesstors(aVSD, aMVSD, aMVE, aMEV, myStickedShapes);
539     if (iRet) {
540       // Sticked shapes detected
541       myWarningStatus=2;
542     }
543   }
544 }
545 //=======================================================================
546 //function : CheckAncesstors
547 //purpose  :
548 //=======================================================================
549 Standard_Integer CheckAncesstors
550   (const TopoDS_Shape& aVSD,
551    const TopTools_MapOfShape& aMVSD,
552    const TopTools_IndexedDataMapOfShapeListOfShape& aMVE,
553    const TopTools_IndexedDataMapOfShapeListOfShape& aMEV,
554    TopTools_IndexedDataMapOfShapeListOfShape& aMEVZ)
555 {
556   Standard_Address pLE, pLV, pLVZ;
557   Standard_Integer iRet, aNbVX;
558   TopTools_ListIteratorOfListOfShape aItLE, aItLV;
559   TopTools_MapOfShape aMFence;
560   TopTools_ListOfShape aLVX;
561   //
562   iRet=0;
563   //
564   pLE=aMVE.FindFromKey1(aVSD);
565   if (!pLE) {
566     return iRet;
567   }
568   //
569   const TopTools_ListOfShape& aLE=*((TopTools_ListOfShape*)pLE);
570   aItLE.Initialize(aLE);
571   for (; aItLE.More(); aItLE.Next()) {
572     const TopoDS_Shape& aE=aItLE.Value();
573     //
574     pLV=aMEV.FindFromKey1(aE);
575     if (!pLV) {
576       continue; // it should be not so
577     }
578     //
579     aLVX.Clear();
580     const TopTools_ListOfShape& aLV=*((TopTools_ListOfShape*)pLV);
581     aItLV.Initialize(aLV);
582     for (; aItLV.More(); aItLV.Next()) {
583       const TopoDS_Shape& aV=aItLV.Value();
584       if (!aV.IsSame(aVSD)) {
585         if (aMVSD.Contains(aV)) {
586           if (aMFence.Add(aV)) {
587             aLVX.Append(aV);
588           }
589         }
590       }
591     }
592     //
593     aNbVX=aLVX.Extent();
594     if (!aNbVX) {
595       continue;
596     }
597     //
598     iRet=1;
599     //
600     pLVZ=aMEVZ.FindFromKey1(aE);
601     if (!pLVZ) {
602       aMEVZ.Add(aE, aLVX);
603     }
604     else {
605       TopTools_ListOfShape& aLVZ=*((TopTools_ListOfShape*)pLVZ);
606       aLVZ.Append(aLVX);
607     }
608   }
609   //
610   return iRet;
611 }
612 //modified by NIZNHY-PKV Tue Mar 13 09:54:59 2012t