Salome HOME
Merge from V5_1_main 14/05/2010
[modules/geom.git] / src / GEOMAlgo / GEOMAlgo_GlueAnalyser.cxx
1 //  Copyright (C) 2007-2010  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 // Created:     Wed Dec 15 11:08:09 2004
25 // Author:      Peter KURNEV
26 //              <pkv@irinox>
27 //
28 #include <GEOMAlgo_GlueAnalyser.ixx>
29
30 #include <TopoDS.hxx>
31 #include <TopoDS_Shape.hxx>
32 #include <TopoDS_Face.hxx>
33 #include <TopoDS_Edge.hxx>
34 #include <TopoDS_Compound.hxx>
35
36 #include <BRep_Builder.hxx>
37
38 #include <TopExp.hxx>
39
40 #include <TopTools_IndexedMapOfShape.hxx>
41 #include <TopTools_ListOfShape.hxx>
42 #include <TopTools_ListIteratorOfListOfShape.hxx>
43 #include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
44 #include <TopTools_DataMapIteratorOfDataMapOfShapeListOfShape.hxx>
45
46 #include <GEOMAlgo_PassKeyShape.hxx>
47 #include <GEOMAlgo_IndexedDataMapOfPassKeyShapeListOfShape.hxx>
48 #include <GEOMAlgo_Tools.hxx>
49 #include <GEOMAlgo_CoupleOfShapes.hxx>
50
51 #include <GEOMAlgo_Gluer.hxx>
52 #include <Bnd_HArray1OfBox.hxx>
53 #include <Bnd_BoundSortBox.hxx>
54 #include <TopoDS_Vertex.hxx>
55 #include <GEOMAlgo_IndexedDataMapOfIntegerShape.hxx>
56 #include <GEOMAlgo_IndexedDataMapOfShapeBox.hxx>
57 #include <Bnd_Box.hxx>
58 #include <TColStd_ListOfInteger.hxx>
59 #include <TopTools_MapOfShape.hxx>
60 #include <TColStd_ListIteratorOfListOfInteger.hxx>
61 #include <BRepBndLib.hxx>
62
63 //=======================================================================
64 //function : 
65 //purpose  : 
66 //=======================================================================
67   GEOMAlgo_GlueAnalyser::GEOMAlgo_GlueAnalyser()
68 :
69   GEOMAlgo_Gluer()
70 {}
71 //=======================================================================
72 //function : ~
73 //purpose  : 
74 //=======================================================================
75   GEOMAlgo_GlueAnalyser::~GEOMAlgo_GlueAnalyser()
76 {}
77 //=======================================================================
78 //function : HasSolidsToGlue
79 //purpose  : 
80 //=======================================================================
81   Standard_Boolean GEOMAlgo_GlueAnalyser::HasSolidsToGlue()const
82 {
83   return !mySolidsToGlue.IsEmpty();
84 }
85 //=======================================================================
86 //function : HasSolidsAlone
87 //purpose  : 
88 //=======================================================================
89   Standard_Boolean GEOMAlgo_GlueAnalyser::HasSolidsAlone()const
90 {
91   return !mySolidsAlone.IsEmpty();
92 }
93 //=======================================================================
94 //function : SolidsToGlue
95 //purpose  : 
96 //=======================================================================
97   const GEOMAlgo_ListOfCoupleOfShapes& GEOMAlgo_GlueAnalyser::SolidsToGlue()const
98 {
99   return mySolidsToGlue;
100 }
101 //=======================================================================
102 //function : SolidsAlone
103 //purpose  : 
104 //=======================================================================
105   const TopTools_ListOfShape& GEOMAlgo_GlueAnalyser::SolidsAlone()const
106 {
107   return mySolidsAlone;
108 }
109 //=======================================================================
110 //function : Perform
111 //purpose  : 
112 //=======================================================================
113   void GEOMAlgo_GlueAnalyser::Perform()
114 {
115   myErrorStatus=0;
116   myWarningStatus=0;
117   //
118   mySolidsToGlue.Clear();
119   mySolidsAlone.Clear();
120   //
121   CheckData();
122   if (myErrorStatus) {
123     return;
124   }
125   //
126   InnerTolerance();
127   if (myErrorStatus) {
128     return;
129   }
130   //
131   DetectVertices();
132   if (myErrorStatus) {
133     return;
134   }
135   //
136   DetectEdges();
137   if (myErrorStatus) {
138     return;
139   }
140   //
141   DetectFaces();
142   if (myErrorStatus) {
143     return;
144   }
145   //
146   DetectSolids();
147   if (myErrorStatus) {
148     return;
149   }
150 }
151 //=======================================================================
152 //function : DetectVertices
153 //purpose  : 
154 //=======================================================================
155   void GEOMAlgo_GlueAnalyser::DetectVertices()
156 {
157   myErrorStatus=0;
158   //
159   Standard_Integer j, i, aNbV, aIndex, aNbVSD;
160   TColStd_ListIteratorOfListOfInteger aIt;
161   Handle(Bnd_HArray1OfBox) aHAB;
162   Bnd_BoundSortBox aBSB;
163   TopoDS_Shape aSTmp, aVF;
164   TopoDS_Vertex aVnew;
165   TopTools_IndexedMapOfShape aMV, aMVProcessed;
166   TopTools_ListIteratorOfListOfShape aItS;
167   TopTools_DataMapIteratorOfDataMapOfShapeListOfShape aItIm;
168   GEOMAlgo_IndexedDataMapOfIntegerShape aMIS;
169   GEOMAlgo_IndexedDataMapOfShapeBox aMSB;
170   //
171   TopExp::MapShapes(myShape, TopAbs_VERTEX, aMV);
172   aNbV=aMV.Extent();
173   if (!aNbV) {
174     myErrorStatus=2; // no vertices in source shape
175     return;
176   }
177   //
178   aHAB=new Bnd_HArray1OfBox(1, aNbV);
179   //
180   for (i=1; i<=aNbV; ++i) {
181     const TopoDS_Shape& aV=aMV(i);
182     Bnd_Box aBox;
183     //
184     aBox.SetGap(myTol); 
185     BRepBndLib::Add(aV, aBox);
186     aHAB->SetValue(i, aBox);
187     aMIS.Add(i, aV);
188     aMSB.Add(aV, aBox); 
189   }
190   //
191   aBSB.Initialize(aHAB);
192   //
193   for (i=1; i<=aNbV; ++i) {
194     const TopoDS_Shape& aV=aMV(i);
195     //
196     if (aMVProcessed.Contains(aV)) {
197       continue;
198     }
199     //
200     const Bnd_Box& aBoxV=aMSB.FindFromKey(aV);
201     const TColStd_ListOfInteger& aLI=aBSB.Compare(aBoxV);
202     aNbVSD=aLI.Extent();
203     if (!aNbVSD) {
204       myErrorStatus=3; // it must not be 
205       return;
206     }
207     //
208     // Images
209     TopTools_ListOfShape aLVSD;
210     //
211     aIt.Initialize(aLI);
212     for (j=0; aIt.More(); aIt.Next(), ++j) {
213       aIndex=aIt.Value();
214       const TopoDS_Shape& aVx=aMIS.FindFromKey(aIndex);
215       if(!j) {
216         aVF=aVx;
217       }
218       aLVSD.Append(aVx);
219       aMVProcessed.Add(aVx);
220     }
221     myImages.Bind(aVF, aLVSD);
222   }
223   // Origins
224   aItIm.Initialize(myImages);
225   for (; aItIm.More(); aItIm.Next()) {
226     const TopoDS_Shape& aV=aItIm.Key();
227     const TopTools_ListOfShape& aLVSD=aItIm.Value();
228     //
229     aItS.Initialize(aLVSD);
230     for (; aItS.More(); aItS.Next()) {
231       const TopoDS_Shape& aVSD=aItS.Value();
232       if (!myOrigins.IsBound(aVSD)) {
233         myOrigins.Bind(aVSD, aV);
234       }
235     }
236   }
237 }
238 //=======================================================================
239 //function : DetectFaces
240 //purpose  : 
241 //=======================================================================
242   void GEOMAlgo_GlueAnalyser::DetectFaces()
243 {
244   DetectShapes(TopAbs_FACE);
245 }
246 //=======================================================================
247 //function : DetectEdges
248 //purpose  : 
249 //=======================================================================
250   void GEOMAlgo_GlueAnalyser::DetectEdges()
251 {
252   DetectShapes(TopAbs_EDGE);
253 }
254 //=======================================================================
255 //function : DetectShapes
256 //purpose  : 
257 //=======================================================================
258   void GEOMAlgo_GlueAnalyser::DetectShapes(const TopAbs_ShapeEnum aType)
259 {
260   myErrorStatus=0;
261   //
262   Standard_Integer i, aNbF, aNbSDF, iErr;
263   TopoDS_Shape aNewShape;
264   TopTools_IndexedMapOfShape aMF;
265   TopTools_ListIteratorOfListOfShape aItS;
266   GEOMAlgo_PassKeyShape aPKF;
267   GEOMAlgo_IndexedDataMapOfPassKeyShapeListOfShape aMPKLF;
268   //
269   TopExp::MapShapes(myShape, aType, aMF);
270   //
271   aNbF=aMF.Extent();
272   for (i=1; i<=aNbF; ++i) {
273     const TopoDS_Shape& aS=aMF(i);
274     // 
275     //aPKF.Clear();//qft
276     if (aType==TopAbs_FACE) {
277       const TopoDS_Face& aF=TopoDS::Face(aS);
278       FacePassKey(aF, aPKF);
279     }
280     else if (aType==TopAbs_EDGE) {
281       const TopoDS_Edge& aE=TopoDS::Edge(aS);
282       EdgePassKey(aE, aPKF);
283     }
284     //
285     if (myErrorStatus) {
286       return;
287     }
288     //
289     if (aMPKLF.Contains(aPKF)) {
290       TopTools_ListOfShape& aLSDF=aMPKLF.ChangeFromKey(aPKF);
291       aLSDF.Append(aS);
292     }
293     else {
294       TopTools_ListOfShape aLSDF;
295       //
296       aLSDF.Append(aS);
297       aMPKLF.Add(aPKF, aLSDF);
298     }
299   }
300   // check geometric coincidence
301   if (myCheckGeometry) {
302     iErr=GEOMAlgo_Tools::RefineSDShapes(aMPKLF, myTol, myContext); //XX
303     if (iErr) {
304       myErrorStatus=200;
305       return;
306     }
307   }
308   //
309   // Images/Origins
310   aNbF=aMPKLF.Extent();
311   for (i=1; i<=aNbF; ++i) {
312     const TopTools_ListOfShape& aLSDF=aMPKLF(i);
313     aNbSDF=aLSDF.Extent();
314     if (!aNbSDF) {
315       myErrorStatus=4; // it must not be
316     }
317     //
318     const TopoDS_Shape& aS1=aLSDF.First();
319     aNewShape=aS1;
320     //
321     myImages.Bind(aNewShape, aLSDF);
322     // origins
323     aItS.Initialize(aLSDF);
324     for (; aItS.More(); aItS.Next()) {
325       const TopoDS_Shape& aFSD=aItS.Value();
326       if (!myOrigins.IsBound(aFSD)) {
327         myOrigins.Bind(aFSD, aNewShape);
328       }
329     }
330   }
331 }
332 //=======================================================================
333 //function : DetectSolids
334 //purpose  : 
335 //=======================================================================
336   void GEOMAlgo_GlueAnalyser::DetectSolids()
337 {
338   myErrorStatus=0;
339   //
340   Standard_Integer i, aNbF, aNbS, aNbC, aNbX;
341   TopoDS_Compound aCmp;
342   BRep_Builder aBB;
343   TopTools_IndexedDataMapOfShapeListOfShape aMFS;
344   TopTools_IndexedMapOfShape aMx, aMS;
345   TopTools_DataMapIteratorOfDataMapOfShapeListOfShape aItIm;
346   GEOMAlgo_CoupleOfShapes aCS;
347   //
348   GEOMAlgo_IndexedDataMapOfPassKeyShapeListOfShape aMPKLS;
349   GEOMAlgo_PassKeyShape aPKSx;
350   //
351   aBB.MakeCompound(aCmp);
352   //
353   TopExp::MapShapesAndAncestors(myShape, TopAbs_FACE, TopAbs_SOLID, aMFS);
354   //
355   aItIm.Initialize(myImages);
356   for (; aItIm.More(); aItIm.Next()) {
357     const TopoDS_Shape& aIm=aItIm.Key();
358     if (aIm.ShapeType()!=TopAbs_FACE) {
359       continue;
360     }
361     //
362     const TopTools_ListOfShape& aLF=aItIm.Value();
363     aNbF=aLF.Extent();
364     if (aNbF!=2) {
365       continue;
366     }
367     //
368     TopoDS_Shape aSx[2], aFx[2];
369     //
370     aFx[0]=aLF.First();
371     aFx[1]=aLF.Last();
372     for (i=0; i<2; ++i) {
373       if (!aMFS.Contains(aFx[i])) {
374         continue;// it must not be so
375       }
376       //
377       const TopTools_ListOfShape& aLS=aMFS.FindFromKey(aFx[i]);
378       aNbS=aLS.Extent();
379       if (aNbS!=1) {
380         continue;
381       }
382       aSx[i]=aLS.First();
383     }
384     //
385     if (aSx[0].IsNull() || aSx[1].IsNull()) {
386       continue;
387     }
388     //
389     //aPKSx.Clear();//qft
390     //qf
391     //aPKSx.SetIds(aSx[0], aSx[1]);
392     aPKSx.SetShapes(aSx[0], aSx[1]);
393     //qt
394     //
395     if (!aMPKLS.Contains(aPKSx)) {
396       TopTools_ListOfShape aLSx;
397       //
398       aLSx.Append(aSx[0]);
399       aLSx.Append(aSx[1]);
400       //
401       aMPKLS.Add(aPKSx, aLSx);
402     }
403   }
404   //
405   mySolidsToGlue.Clear();
406   mySolidsAlone.Clear();
407   
408   //
409   aNbC=aMPKLS.Extent();
410   if (!aNbC) {
411     return;
412   }
413   //
414   for (i=1; i<=aNbC; ++i) {
415     const TopTools_ListOfShape& aLSx=aMPKLS(i);
416     const TopoDS_Shape& aSx1=aLSx.First();
417     const TopoDS_Shape& aSx2=aLSx.Last();
418     aCS.SetShape1(aSx1);
419     aCS.SetShape2(aSx2);
420     mySolidsToGlue.Append(aCS);
421     //
422     if (!aMx.Contains(aSx1)) {
423       aBB.Add(aCmp, aSx1);
424       aMx.Add(aSx1);
425     }
426     if (!aMx.Contains(aSx2)) {
427       aBB.Add(aCmp, aSx2);
428       aMx.Add(aSx2);
429     }
430   }
431   myResult=aCmp;
432   //
433   // check alone solids
434   TopExp::MapShapes(myShape, TopAbs_SOLID, aMS);
435   //
436   aNbX=aMx.Extent();
437   for (i=1; i<=aNbX; ++i) {
438     const TopoDS_Shape& aSx=aMx(i);
439     if (!aMS.Contains(aSx)) {
440       mySolidsAlone.Append(aSx);
441     }
442   }
443 }
444
445 /*
446 // A
447   // Make vertices
448   aMV.Clear();
449   aItIm.Initialize(myImages);
450   for (; aItIm.More(); aItIm.Next()) {
451     const TopoDS_Shape& aV=aItIm.Key();
452     aMV.Add(aV);
453     const TopTools_ListOfShape& aLVSD=aItIm.Value();
454     MakeVertex(aLVSD, aVnew);//ZZ
455     myImages.Bind(aVnew, aLVSD);
456   }
457   //
458   aNbV=aMV.Extent();
459   for (i=1; i<=aNbV; ++i) {
460     const TopoDS_Shape& aV=aMV(i);
461     myImages.UnBind(aV);
462   }
463   //
464   */