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