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