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