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