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