Salome HOME
Internal issue 0022865: Restructurization of Partition packages.
[modules/geom.git] / src / GEOMAlgo_NEW / GEOMAlgo_GlueDetector.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 // File:        GEOMAlgo_GlueDetector.cxx
23 // Created:     
24 // Author:      Peter KURNEV
25 //              <pkv@irinox>
26 //
27 #include <GEOMAlgo_GlueDetector.hxx>
28
29 #include <Bnd_Box.hxx>
30 #include <NCollection_UBTreeFiller.hxx>
31
32 #include <TColStd_ListOfInteger.hxx>
33 #include <TColStd_ListIteratorOfListOfInteger.hxx>
34 #include <TColStd_MapIteratorOfMapOfInteger.hxx>
35
36 #include <TopoDS_Shape.hxx>
37 #include <TopoDS_Face.hxx>
38 #include <TopoDS_Edge.hxx>
39 #include <TopoDS_Compound.hxx>
40 #include <TopoDS_Vertex.hxx>
41 #include <TopoDS_Iterator.hxx>
42 #include <TopoDS_Compound.hxx>
43
44 #include <TopTools_IndexedMapOfShape.hxx>
45 #include <TopTools_ListOfShape.hxx>
46 #include <TopTools_ListIteratorOfListOfShape.hxx>
47 #include <TopTools_DataMapIteratorOfDataMapOfShapeListOfShape.hxx>
48 #include <TopTools_MapOfShape.hxx>
49 #include <TopTools_MapIteratorOfMapOfShape.hxx>
50
51 #include <TopExp.hxx>
52 #include <BRep_Tool.hxx>
53 #include <BRep_Builder.hxx>
54 #include <BRepBndLib.hxx>
55
56 #include <NMTDS_BndSphereTree.hxx>
57 #include <NMTDS_BndSphere.hxx>
58 #include <NMTDS_IndexedDataMapOfShapeBndSphere.hxx>
59
60 #include <GEOMAlgo_IndexedDataMapOfIntegerShape.hxx>
61 #include <GEOMAlgo_PassKeyShape.hxx>
62 #include <GEOMAlgo_IndexedDataMapOfPassKeyShapeListOfShape.hxx>
63 #include <GEOMAlgo_Tools.hxx>
64
65 //=======================================================================
66 //function : 
67 //purpose  : 
68 //=======================================================================
69 GEOMAlgo_GlueDetector::GEOMAlgo_GlueDetector()
70 :
71   GEOMAlgo_GluerAlgo(),
72   GEOMAlgo_Algo()
73 {}
74 //=======================================================================
75 //function : ~
76 //purpose  : 
77 //=======================================================================
78 GEOMAlgo_GlueDetector::~GEOMAlgo_GlueDetector()
79 {}
80 //=======================================================================
81 //function : Perform
82 //purpose  : 
83 //=======================================================================
84 void GEOMAlgo_GlueDetector::Perform()
85 {
86   myErrorStatus=0;
87   myWarningStatus=0;
88   //
89   CheckData();
90   if (myErrorStatus) {
91     return;
92   }
93   //
94   // Initialize the context
95   GEOMAlgo_GluerAlgo::Perform();
96   //
97   DetectVertices();
98   if (myErrorStatus) {
99     return;
100   }
101   //
102   DetectEdges();
103   if (myErrorStatus) {
104     return;
105   }
106   //
107   DetectFaces();
108   if (myErrorStatus) {
109     return;
110   }
111 }
112 //=======================================================================
113 //function : DetectVertices
114 //purpose  : 
115 //=======================================================================
116 void GEOMAlgo_GlueDetector::DetectVertices()
117 {
118   Standard_Integer j, i, aNbV, aNbVSD;
119   Standard_Real aTolV;
120   gp_Pnt aPV;
121   TColStd_ListIteratorOfListOfInteger aIt;
122   TopoDS_Shape aVF;
123   TopTools_IndexedMapOfShape aMV;
124   TopTools_MapOfShape aMVProcessed;
125   TopTools_ListIteratorOfListOfShape aItS;
126   TopTools_DataMapIteratorOfDataMapOfShapeListOfShape aItIm;
127   TopTools_DataMapOfShapeListOfShape aMVV;
128   GEOMAlgo_IndexedDataMapOfIntegerShape aMIS;
129   NMTDS_IndexedDataMapOfShapeBndSphere aMSB;
130   //
131   NMTDS_BndSphereTreeSelector aSelector;
132   NMTDS_BndSphereTree aBBTree;
133   NCollection_UBTreeFiller <Standard_Integer, NMTDS_BndSphere> aTreeFiller(aBBTree);
134   //
135   myErrorStatus=0;
136   //
137   TopExp::MapShapes(myArgument, TopAbs_VERTEX, aMV);
138   aNbV=aMV.Extent();
139   if (!aNbV) {
140     myErrorStatus=2; // no vertices in source shape
141     return;
142   }
143   //
144   for (i=1; i<=aNbV; ++i) {
145     NMTDS_BndSphere aBox;
146     //
147     const TopoDS_Vertex& aV=*((TopoDS_Vertex*)&aMV(i));
148     aPV=BRep_Tool::Pnt(aV);
149     aTolV=BRep_Tool::Tolerance(aV);
150     //
151     aBox.SetGap(myTolerance);
152     aBox.SetCenter(aPV);
153     aBox.SetRadius(aTolV);
154     //
155     aTreeFiller.Add(i, aBox);
156     //
157     aMIS.Add(i, aV);
158     aMSB.Add(aV, aBox); 
159   }
160   //
161   aTreeFiller.Fill();
162   //
163   //---------------------------------------------------
164   // Chains
165   for (i=1; i<=aNbV; ++i) {
166     const TopoDS_Shape& aV=aMV(i);
167     //
168     if (aMVProcessed.Contains(aV)) {
169       continue;
170     }
171     //
172     Standard_Integer aNbIP, aIP, aNbIP1, aIP1;
173     TopTools_ListOfShape aLVSD;
174     TColStd_MapOfInteger aMIP, aMIP1, aMIPC;
175     TColStd_MapIteratorOfMapOfInteger aIt1;
176     //
177     aMIP.Add(i);
178     while(1) {
179       aNbIP=aMIP.Extent();
180       aIt1.Initialize(aMIP);
181       for(; aIt1.More(); aIt1.Next()) {
182         aIP=aIt1.Key();
183         if (aMIPC.Contains(aIP)) {
184           continue;
185         }
186         //
187         const TopoDS_Shape& aVP=aMIS.FindFromKey(aIP);
188         const NMTDS_BndSphere& aBoxVP=aMSB.FindFromKey(aVP);
189         //
190         aSelector.Clear();
191         aSelector.SetBox(aBoxVP);
192         //
193         aNbVSD=aBBTree.Select(aSelector);
194         if (!aNbVSD) {
195           continue;  // it shoild not be so [at least IP itself]    
196         }
197         //
198         const TColStd_ListOfInteger& aLI=aSelector.Indices();
199         aIt.Initialize(aLI);
200         for (; aIt.More(); aIt.Next()) {
201           aIP1=aIt.Value();
202           if (aMIP.Contains(aIP1)) {
203             continue;
204           }
205           aMIP1.Add(aIP1);
206         } //for (; aIt.More(); aIt.Next()) {
207       }//for(; aIt1.More(); aIt1.Next()) {
208       //
209       aNbIP1=aMIP1.Extent();
210       if (!aNbIP1) {
211         break;
212       }
213       //
214       aIt1.Initialize(aMIP);
215       for(; aIt1.More(); aIt1.Next()) {
216         aIP=aIt1.Key();
217         aMIPC.Add(aIP);
218       }
219       //
220       aMIP.Clear();
221       aIt1.Initialize(aMIP1);
222       for(; aIt1.More(); aIt1.Next()) {
223         aIP=aIt1.Key();
224         aMIP.Add(aIP);
225       }
226       aMIP1.Clear();
227     }// while(1)
228     //
229     // Fill myImages
230     aNbIP=aMIPC.Extent();
231     //
232     if (!aNbIP) {// no SD vertices is found
233       aMVProcessed.Add(aV);
234       continue;
235     }
236     //else { // SD vertices founded [ aMIPC ]
237     aIt1.Initialize(aMIPC);
238     for(j=0; aIt1.More(); aIt1.Next(), ++j) {
239       aIP=aIt1.Key();
240       const TopoDS_Shape& aVP=aMIS.FindFromKey(aIP);
241       if (!j) {
242         aVF=aVP;
243       }
244       aLVSD.Append(aVP);
245       aMVProcessed.Add(aVP);
246     }
247     //}
248     myImages.Bind(aVF, aLVSD);
249   }// for (i=1; i<=aNbV; ++i) {
250   //------------------------------
251   // Origins
252   aItIm.Initialize(myImages);
253   for (; aItIm.More(); aItIm.Next()) {
254     const TopoDS_Shape& aV=aItIm.Key();
255     const TopTools_ListOfShape& aLVSD=aItIm.Value();
256     aItS.Initialize(aLVSD);
257     for (; aItS.More(); aItS.Next()) {
258       const TopoDS_Shape& aVSD=aItS.Value();
259       if (!myOrigins.IsBound(aVSD)) {
260         myOrigins.Bind(aVSD, aV);
261       }
262     }
263   }
264 }
265 //=======================================================================
266 //function : DetectFaces
267 //purpose  : 
268 //=======================================================================
269 void GEOMAlgo_GlueDetector::DetectFaces()
270 {
271   DetectShapes(TopAbs_FACE);
272 }
273 //=======================================================================
274 //function : DetectEdges
275 //purpose  : 
276 //=======================================================================
277 void GEOMAlgo_GlueDetector::DetectEdges()
278 {
279   DetectShapes(TopAbs_EDGE);
280 }
281 //=======================================================================
282 //function : DetectShapes
283 //purpose  : 
284 //=======================================================================
285 void GEOMAlgo_GlueDetector::DetectShapes(const TopAbs_ShapeEnum aType)
286 {
287   Standard_Boolean bDegenerated;
288   Standard_Integer i, aNbF, aNbSDF, iErr;
289   TopTools_IndexedMapOfShape aMF;
290   TopTools_ListIteratorOfListOfShape aItLS;
291   GEOMAlgo_PassKeyShape aPKF;
292   GEOMAlgo_IndexedDataMapOfPassKeyShapeListOfShape aMPKLF;
293   //
294   myErrorStatus=0;
295   //
296   TopExp::MapShapes(myArgument, aType, aMF);
297   //
298   aNbF=aMF.Extent();
299   for (i=1; i<=aNbF; ++i) {
300     const TopoDS_Shape& aS=aMF(i);
301     // 
302     if (aType==TopAbs_FACE) {
303       const TopoDS_Face& aF=*((TopoDS_Face*)&aS);
304       FacePassKey(aF, aPKF);
305     }
306     else if (aType==TopAbs_EDGE) {
307       const TopoDS_Edge& aE=*((TopoDS_Edge*)&aS);
308       EdgePassKey(aE, aPKF);
309     }
310     //
311     if (myErrorStatus) {
312       return;
313     }
314     //
315     if (aMPKLF.Contains(aPKF)) {
316       TopTools_ListOfShape& aLSDF=aMPKLF.ChangeFromKey(aPKF);
317       aLSDF.Append(aS);
318     }
319     else {
320       TopTools_ListOfShape aLSDF;
321       //
322       aLSDF.Append(aS);
323       aMPKLF.Add(aPKF, aLSDF);
324     }
325   }
326   // check geometric coincidence
327   if (myCheckGeometry) {
328     iErr=GEOMAlgo_Tools::RefineSDShapes(aMPKLF, myTolerance, myContext);
329     if (iErr) {
330       myErrorStatus=200;
331       return;
332     }
333   }
334   //
335   // Images/Origins
336   aNbF=aMPKLF.Extent();
337   for (i=1; i<=aNbF; ++i) {
338     const TopTools_ListOfShape& aLSDF=aMPKLF(i);
339     aNbSDF=aLSDF.Extent();
340     if (!aNbSDF) {
341       myErrorStatus=4; // it must not be
342     }
343     //
344     if (aNbSDF==1) {
345       continue;
346     }
347     //
348     const TopoDS_Shape& aS1=aLSDF.First();  
349     //
350     if (aType==TopAbs_EDGE) {
351       const TopoDS_Edge& aE1=*((TopoDS_Edge*)&aS1);
352       bDegenerated=BRep_Tool::Degenerated(aE1);
353       if (bDegenerated) {
354         continue;
355       }
356     }
357     //
358     myImages.Bind(aS1, aLSDF);
359     // origins
360     aItLS.Initialize(aLSDF);
361     for (; aItLS.More(); aItLS.Next()) {
362       const TopoDS_Shape& aFSD=aItLS.Value();
363       if (!myOrigins.IsBound(aFSD)) {
364         myOrigins.Bind(aFSD, aS1);
365       }
366     }
367   }// for (i=1; i<=aNbF; ++i)
368 }
369 //=======================================================================
370 //function : FacePassKey
371 //purpose  : 
372 //=======================================================================
373 void GEOMAlgo_GlueDetector::FacePassKey(const TopoDS_Face& aF, 
374                                         GEOMAlgo_PassKeyShape& aPK)
375 {
376   Standard_Integer i, aNbE;
377   TopoDS_Shape aER;
378   TopTools_ListOfShape aLE;
379   TopTools_IndexedMapOfShape aME;
380   //
381   TopExp::MapShapes(aF, TopAbs_EDGE, aME);
382   //
383   aNbE=aME.Extent();
384   for (i=1; i<=aNbE; ++i) {
385     const TopoDS_Shape& aE=aME(i);
386     //
387     const TopoDS_Edge& aEE=*((TopoDS_Edge*)&aE);
388     if (BRep_Tool::Degenerated(aEE)) {
389       continue;
390     }
391     // 
392     if (myOrigins.IsBound(aE)) {
393       aER=myOrigins.Find(aE);
394     }
395     else {
396       aER=aE;
397     }
398     aLE.Append(aER);
399   }
400   aPK.SetShapes(aLE);
401 }
402 //=======================================================================
403 //function : EdgePassKey
404 //purpose  : 
405 //=======================================================================
406 void GEOMAlgo_GlueDetector::EdgePassKey(const TopoDS_Edge& aE, 
407                                         GEOMAlgo_PassKeyShape& aPK)
408 {
409   TopAbs_Orientation aOr;
410   TopoDS_Shape aVR;
411   TopoDS_Iterator aIt;
412   TopTools_ListOfShape aLV;
413   //
414   aIt.Initialize(aE);
415   for (; aIt.More(); aIt.Next()) {
416     const TopoDS_Shape& aV=aIt.Value();
417     aOr=aV.Orientation();
418     if (aOr==TopAbs_FORWARD || aOr==TopAbs_REVERSED) {
419       if (myOrigins.IsBound(aV)) {
420         aVR=myOrigins.Find(aV);
421       }
422       else {
423         aVR=aV;
424       }
425       aLV.Append(aVR);
426     }
427   }
428   //
429   aPK.SetShapes(aLV);
430 }