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