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