Salome HOME
IMPs 19998 and 21191: new gluing by PKV
[modules/geom.git] / src / GEOMAlgo / GEOMAlgo_Gluer2_3.cxx
1 //  Copyright (C) 2007-2008  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_Gluer2_3.cxx
23 // Created:     
24 // Author:      Peter KURNEV
25 //              <peter@PREFEX>
26 //
27 #include <GEOMAlgo_Gluer2.hxx>
28
29 #include <TopAbs_ShapeEnum.hxx>
30
31 #include <TopoDS_Shape.hxx>
32 #include <TopoDS_Edge.hxx>
33
34 #include <BRep_Tool.hxx>
35
36 #include <TopExp.hxx>
37 #include <TopExp_Explorer.hxx>
38
39 #include <TopTools_DataMapIteratorOfDataMapOfShapeListOfShape.hxx>
40 #include <TopTools_DataMapOfShapeListOfShape.hxx>
41 #include <TopTools_ListOfShape.hxx>
42 #include <TopTools_MapOfShape.hxx>
43 #include <TopTools_MapIteratorOfMapOfShape.hxx>
44 #include <TopTools_DataMapIteratorOfDataMapOfShapeListOfShape.hxx>
45 #include <TopTools_ListIteratorOfListOfShape.hxx>
46 #include <TopTools_IndexedMapOfShape.hxx>
47
48 #include <NMTTools_CoupleOfShape.hxx>
49 #include <NMTTools_ListOfCoupleOfShape.hxx>
50 #include <NMTTools_ListIteratorOfListOfCoupleOfShape.hxx>
51 #include <NMTTools_IndexedDataMapOfShapeIndexedMapOfShape.hxx>
52 #include <NMTTools_Tools.hxx>
53
54 #include <GEOMAlgo_GlueDetector.hxx>
55
56
57 static
58   void MapShapes1(const TopoDS_Shape& aS,
59                   const TopAbs_ShapeEnum aType,
60                   TopTools_IndexedMapOfShape& aM);
61
62 //=======================================================================
63 //function : Detect
64 //purpose  : 
65 //=======================================================================
66 void GEOMAlgo_Gluer2::Detect()
67 {
68   Standard_Boolean bCheckGeometry;
69   Standard_Integer iErr, aNbSD;
70   TopTools_ListIteratorOfListOfShape aItLS;
71   TopTools_DataMapIteratorOfDataMapOfShapeListOfShape aItDMSLS;
72   GEOMAlgo_GlueDetector aDetector;
73   //
74   myErrorStatus=0;
75   myWarningStatus=0;
76   //
77   myImagesDetected.Clear();
78   myOriginsDetected.Clear();
79   //
80   bCheckGeometry=Standard_True;
81   aDetector.SetArgument(myArgument);
82   aDetector.SetTolerance(myTolerance);
83   aDetector.SetCheckGeometry(bCheckGeometry);
84   //
85   aDetector.Perform();
86   iErr=aDetector.ErrorStatus();
87   if (iErr) {
88     myErrorStatus=11;// Detector failed
89     return;
90   }
91   //
92   const TopTools_DataMapOfShapeListOfShape& aImages=aDetector.Images();
93   aItDMSLS.Initialize(aImages);
94   for (; aItDMSLS.More(); aItDMSLS.Next()) {
95     const TopoDS_Shape& aSkey=aItDMSLS.Key();
96     const TopTools_ListOfShape& aLSD=aItDMSLS.Value();
97     aNbSD=aLSD.Extent();
98     myImagesDetected.Bind(aSkey, aLSD);
99   }
100   //
101   aItDMSLS.Initialize(myImagesDetected);
102   for (; aItDMSLS.More(); aItDMSLS.Next()) {
103     const TopoDS_Shape& aSkey=aItDMSLS.Key();
104     const TopTools_ListOfShape& aLSD=aItDMSLS.Value();
105     aItLS.Initialize(aLSD);
106     for (; aItLS.More(); aItLS.Next()) {
107       const TopoDS_Shape& aSx=aItLS.Value();
108       myOriginsDetected.Bind(aSx, aSkey);
109     }
110   }
111 }
112 //=======================================================================
113 //function : PerformShapesToWork
114 //purpose  : 
115 //=======================================================================
116 void GEOMAlgo_Gluer2::PerformShapesToWork()
117
118   Standard_Integer aNbSG, i, j, aNbC, aNb, aNbSD;
119   TopTools_ListIteratorOfListOfShape aItLS1, aItLS2;
120   TopTools_DataMapIteratorOfDataMapOfShapeListOfShape aItDMSLS;
121   NMTTools_CoupleOfShape aCS;
122   NMTTools_ListOfCoupleOfShape aLCS;
123   NMTTools_ListIteratorOfListOfCoupleOfShape aItCS; 
124   //
125   myErrorStatus=0;
126   myWarningStatus=0;
127   //
128   myImagesToWork.Clear();
129   myOriginsToWork.Clear();
130   //
131   aNbSD=myImagesDetected.Extent();
132   if (!aNbSD) {// no shapes to glue detected
133     myWarningStatus=1;
134     return;
135   }
136   //
137   aNbSG=myShapesToGlue.Extent();
138   if (!aNbSG) {
139     // glue all possible
140     myImagesToWork=myImagesDetected;
141     //
142     aItDMSLS.Initialize(myImagesToWork);
143     for (; aItDMSLS.More(); aItDMSLS.Next()) {
144       const TopoDS_Shape& aSkey=aItDMSLS.Key();
145       const TopTools_ListOfShape& aLSD=aItDMSLS.Value();
146       aItLS1.Initialize(aLSD);
147       for (; aItLS1.More(); aItLS1.Next()) {
148         const TopoDS_Shape& aSx=aItLS1.Value();
149         myOriginsToWork.Bind(aSx, aSkey);
150       }
151     }
152     return;
153   }// if (!aNbSG) {
154   //
155   // 1. Make pairs
156   aItDMSLS.Initialize(myShapesToGlue);
157   for (; aItDMSLS.More(); aItDMSLS.Next()) {
158     const TopoDS_Shape& aSkey=aItDMSLS.Key();
159     const TopTools_ListOfShape& aLSG=aItDMSLS.Value();
160     aItLS1.Initialize(aLSG);
161     for (i=0; aItLS1.More(); aItLS1.Next(), ++i) {
162       aItLS2.Initialize(aLSG);
163       for (j=0; aItLS2.More(); aItLS2.Next(), ++j) {
164         if (j>i) {
165           const TopoDS_Shape& aSG1=aItLS1.Value();
166           const TopoDS_Shape& aSG2=aItLS2.Value();
167           aCS.SetShape1(aSG1);
168           aCS.SetShape2(aSG2);
169           TreatPair(aCS, aLCS);
170         }
171       }
172     }
173   }
174   //
175   // 2. Find Chains
176   TopTools_ListOfShape aLSX;
177   NMTTools_IndexedDataMapOfShapeIndexedMapOfShape aMC;
178   //
179   NMTTools_Tools::FindChains(aLCS, aMC);
180   //
181   // 3. myImagesToWork, myOriginsToWork
182   aNbC=aMC.Extent();
183   for (i=1; i<=aNbC; ++i) {
184     const TopoDS_Shape& aSkey=aMC.FindKey(i);
185     const TopTools_IndexedMapOfShape& aM=aMC(i);
186     aLSX.Clear();
187     aNb=aM.Extent();
188     for (j=1; j<=aNb; ++j) {
189       const TopoDS_Shape& aS=aM(j);
190       aLSX.Append(aS);
191       myOriginsToWork.Bind(aS, aSkey);
192     }
193     myImagesToWork.Bind(aSkey, aLSX);
194   }
195 }
196 //=======================================================================
197 //function : TreatPair
198 //purpose  : 
199 //=======================================================================
200 void GEOMAlgo_Gluer2::TreatPair(const NMTTools_CoupleOfShape& aCS,
201                                 NMTTools_ListOfCoupleOfShape& aLCS)
202 {
203   if (myErrorStatus) {
204     return;
205   }
206   //
207   Standard_Integer i, aNbS1, aNbS2, aNbS;
208   TopAbs_ShapeEnum aType, aTypeS;
209   TopTools_ListIteratorOfListOfShape aItLS;
210   TopTools_IndexedMapOfShape aMS1, aMS2;
211   TopTools_DataMapOfShapeListOfShape aDMSLS;
212   TopTools_DataMapIteratorOfDataMapOfShapeListOfShape aItDMSLS;
213   NMTTools_CoupleOfShape aCSS;
214   //
215   // 1. Checking the pair on whether it can be glued at all
216   // 1.1
217   const TopoDS_Shape& aS1=aCS.Shape1();
218   if (!myOriginsDetected.IsBound(aS1)) {
219     myErrorStatus=30;
220     return;
221   }
222   const TopoDS_Shape& aSkey1=myOriginsDetected.Find(aS1);
223   // 1.2
224   const TopoDS_Shape& aS2=aCS.Shape2();
225   if (!myOriginsDetected.IsBound(aS2)) {
226     myErrorStatus=30;
227     return;
228   }
229   const TopoDS_Shape& aSkey2=myOriginsDetected.Find(aS2);
230   // 1.3
231   if (!aSkey1.IsSame(aSkey2)) {
232     myErrorStatus=33;
233     return;
234   }
235   //
236   // 2. Append the pair to the aLCS
237   aLCS.Append(aCS);
238   //
239   // 3. Treatment the subshapes of the pair
240   aType=aS1.ShapeType();
241   if (aType==TopAbs_VERTEX) {
242     return;
243   }
244   aTypeS=TopAbs_EDGE;
245   if (aType==aTypeS) {
246     aTypeS=TopAbs_VERTEX;
247   }
248   //
249   MapShapes1(aS1, aTypeS, aMS1);
250   MapShapes1(aS2, aTypeS, aMS2);
251   //
252   aNbS1=aMS1.Extent();
253   aNbS2=aMS2.Extent();
254   if (aNbS1!=aNbS2) {
255     myErrorStatus=31;
256     return;
257   }
258   //
259   // 1.
260   for (i=1; i<=aNbS1; ++i) {
261     const TopoDS_Shape& aSS1=aMS1(i);
262     if (aMS2.Contains(aSS1)) {
263       continue;
264     }
265     //
266     if (!myOriginsDetected.IsBound(aSS1)) {
267       myErrorStatus=30;
268       return;
269     }
270     //
271     const TopoDS_Shape& aSkey=myOriginsDetected.Find(aSS1);
272     if (aDMSLS.IsBound(aSkey)) {
273       TopTools_ListOfShape& aLS=aDMSLS.ChangeFind(aSkey);
274       aLS.Append(aSS1);
275     }
276     else {
277       TopTools_ListOfShape aLS;
278       //
279       aLS.Append(aSS1);
280       aDMSLS.Bind(aSkey, aLS);
281     }
282   }
283   //
284   // 2.
285   for (i=1; i<=aNbS2; ++i) {
286     const TopoDS_Shape& aSS2=aMS2(i);
287     if (aMS1.Contains(aSS2)) {
288       continue;
289     }
290     //
291     if (!myOriginsDetected.IsBound(aSS2)) {
292       myErrorStatus=30;
293       return;
294     }
295     //
296     const TopoDS_Shape& aSkey=myOriginsDetected.Find(aSS2);
297     if (aDMSLS.IsBound(aSkey)) {
298       TopTools_ListOfShape& aLS=aDMSLS.ChangeFind(aSkey);
299       aLS.Append(aSS2);
300     }
301     else {
302       TopTools_ListOfShape aLS;
303       //
304       aLS.Append(aSS2);
305       aDMSLS.Bind(aSkey, aLS);
306     }
307   }
308   //
309   // 3.
310   aItDMSLS.Initialize(aDMSLS);
311   for (; aItDMSLS.More(); aItDMSLS.Next()) {
312     const TopoDS_Shape& aSkey=aItDMSLS.Key();
313     const TopTools_ListOfShape& aLS=aItDMSLS.Value();
314     aNbS=aLS.Extent();
315     if (aNbS!=2) {
316       myErrorStatus=32;
317       return;
318     }
319     //
320     const TopoDS_Shape& aSS1=aLS.First();
321     const TopoDS_Shape& aSS2=aLS.Last();
322     aCSS.SetShape1(aSS1);
323     aCSS.SetShape2(aSS2);
324     TreatPair(aCSS, aLCS);
325   }
326 }
327 //=======================================================================
328 //function : MapShapes1
329 //purpose  : 
330 //=======================================================================
331 void MapShapes1(const TopoDS_Shape& aS,
332                const TopAbs_ShapeEnum aType,
333                TopTools_IndexedMapOfShape& aM)
334 {
335   TopExp_Explorer aEx (aS, aType);
336   while (aEx.More()) {
337     const TopoDS_Shape aSx=aEx.Current();
338     if (aType==TopAbs_EDGE) {
339       const TopoDS_Edge& aEx=*((TopoDS_Edge*)&aSx);
340       if (BRep_Tool::Degenerated(aEx)) {
341         continue;
342       }
343     }
344     aM.Add(aSx);
345     aEx.Next();
346   }
347 }