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