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