Salome HOME
Copyrights update 2015.
[modules/geom.git] / src / GEOMImpl / GEOMImpl_CopyDriver.cxx
1 // Copyright (C) 2007-2015  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 #include "GEOMImpl_CopyDriver.hxx"
24 #include "GEOMImpl_ICopy.hxx"
25 #include "GEOMImpl_ITransferData.hxx"
26 #include "GEOMImpl_Types.hxx"
27 #include "GEOM_Function.hxx"
28 #include "GEOM_Object.hxx"
29 #include "GEOMAlgo_GetInPlace.hxx"
30 #include "GEOMAlgo_GetInPlaceAPI.hxx"
31
32 #include <TopoDS_Shape.hxx>
33 #include <TopExp.hxx>
34 #include <TNaming_CopyShape.hxx>
35 #include <TColStd_IndexedDataMapOfTransientTransient.hxx>
36 #include <TFunction_Logbook.hxx>
37 #include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
38 #include <TopTools_IndexedMapOfShape.hxx>
39 #include <TopTools_ListIteratorOfListOfShape.hxx>
40 #include <TopTools_ListOfShape.hxx>
41 #include <TopTools_MapIteratorOfMapOfShape.hxx>
42
43
44 #define NB_DATUM             2
45 #define DATUM_NAME_INDEX     1
46 #define DATUM_MATERIAL_INDEX 2
47
48
49 //=======================================================================
50 //function : GetID
51 //purpose  :
52 //======================================================================= 
53 const Standard_GUID& GEOMImpl_CopyDriver::GetID()
54 {
55   static Standard_GUID aCopyDriver("FF1BBB53-5D14-4df2-980B-3A668264EA16");
56   return aCopyDriver; 
57 }
58
59
60 //=======================================================================
61 //function : GEOMImpl_CopyDriver
62 //purpose  : 
63 //=======================================================================
64 GEOMImpl_CopyDriver::GEOMImpl_CopyDriver() 
65 {
66 }
67
68 //=======================================================================
69 //function : Execute
70 //purpose  :
71 //======================================================================= 
72 Standard_Integer GEOMImpl_CopyDriver::Execute(TFunction_Logbook& log) const
73 {
74   if (Label().IsNull()) return 0;    
75   Handle(GEOM_Function) aFunction = GEOM_Function::GetFunction(Label());
76
77   Standard_Integer aType = aFunction->GetType();
78
79   if (aType == TRANSFER_DATA) {
80     return transferData(log);
81   }
82
83   GEOMImpl_ICopy aCI (aFunction);
84   TopoDS_Shape aCopy;
85   
86   if(aType == COPY_WITH_REF) {
87   
88     Handle(GEOM_Function) aRefFunction = aCI.GetOriginal();
89     if (aRefFunction.IsNull()) return 0;
90     TopoDS_Shape anOriginal = aRefFunction->GetValue();
91
92     TColStd_IndexedDataMapOfTransientTransient aMap;
93   
94     TNaming_CopyShape::CopyTool(anOriginal, aMap, aCopy);
95   }
96   else if(aType == COPY_WITHOUT_REF) {
97     aCopy = aFunction->GetValue();
98   }
99   
100   if (aCopy.IsNull()) return 0;
101
102   aFunction->SetValue(aCopy);
103
104   log.SetTouched(Label()); 
105
106   return 1;    
107 }
108
109 //================================================================================
110 /*!
111  * \brief Returns a name of creation operation and names and values of creation parameters
112  */
113 //================================================================================
114
115 bool GEOMImpl_CopyDriver::
116 GetCreationInformation(std::string&             theOperationName,
117                        std::vector<GEOM_Param>& theParams)
118 {
119   if (Label().IsNull()) return 0;
120   Handle(GEOM_Function) function = GEOM_Function::GetFunction(Label());
121
122   GEOMImpl_ICopy aCI( function );
123   Standard_Integer aType = function->GetType();
124
125
126   switch ( aType ) {
127   case COPY_WITH_REF:
128     theOperationName = "MakeCopy";
129     AddParam( theParams, "Original", aCI.GetOriginal() );
130     break;
131   case COPY_WITHOUT_REF:
132   {
133     theOperationName = "RestoreShape";
134     TDF_Label label = Label();
135     Handle(GEOM_Object) obj = GEOM_Object::GetObject(label);
136     if ( !obj.IsNull() && obj->GetType() == GEOM_FREE_BOUNDS )
137       theOperationName = "CHECK_FREE_BNDS";
138     break;
139   }
140   default:
141     return false;
142   }
143   
144   return true;
145 }
146
147 //================================================================================
148 /*!
149  * \brief Performs Transfer Data operation.
150  */
151 //================================================================================
152
153 Standard_Integer GEOMImpl_CopyDriver::transferData(TFunction_Logbook& log) const
154 {
155   Handle(GEOM_Function)  aFunction = GEOM_Function::GetFunction(Label());
156   GEOMImpl_ITransferData aTD (aFunction);
157   Handle(GEOM_Function)  aRef1     = aTD.GetRef1();
158   Handle(GEOM_Function)  aRef2     = aTD.GetRef2();
159
160   if (aRef1.IsNull() || aRef2.IsNull()) {
161     return 0;
162   }
163
164   TopoDS_Shape                              aShape1     = aRef1->GetValue();
165   TopoDS_Shape                              aShape2     = aRef2->GetValue();
166   const int                                 aFindMethod = aTD.GetFindMethod();
167   TopTools_IndexedDataMapOfShapeListOfShape aMapSoDest;
168   TopTools_IndexedMapOfShape                anIndices1;
169
170   TopExp::MapShapes(aShape1, anIndices1);
171
172   switch (aFindMethod) {
173     case TD_GET_IN_PLACE:
174       if (!getInPlace(aShape1, anIndices1, aShape2, aMapSoDest)) {
175         return 0;
176       }
177       break;
178     case TD_GET_IN_PLACE_OLD:
179       if (!getInPlaceOld(aRef1, anIndices1, aShape2, aMapSoDest)) {
180         return 0;
181       }
182       break;
183     case TD_GET_IN_PLACE_BY_HISTORY:
184       if (!getInPlaceByHistory(aRef1, anIndices1, aShape2, aRef2, aMapSoDest)) {
185         return 0;
186       }
187       break;
188     default:
189       return 0;
190   }
191
192   // Perform copying names.
193   Handle(TColStd_HArray1OfExtendedString) aDatumName   =
194     new TColStd_HArray1OfExtendedString(1, NB_DATUM);
195   Handle(TColStd_HArray1OfInteger)        aDatumMaxVal =
196     new TColStd_HArray1OfInteger(1, NB_DATUM, 0);
197   Handle(TColStd_HArray1OfInteger)        aDatumVal    =
198     new TColStd_HArray1OfInteger(1, NB_DATUM, 0);
199   GEOMImpl_ITransferData                  aTD1(aRef1);
200   GEOMImpl_ITransferData                  aTD2(aRef2);
201   Standard_Integer                        i;
202   Standard_Integer                        aNbShapes = anIndices1.Extent();
203   TopTools_MapOfShape                     aMapFence;
204
205   aDatumName->SetValue(DATUM_NAME_INDEX,     "GEOM_TRANSFER_DATA_NAMES");
206   aDatumName->SetValue(DATUM_MATERIAL_INDEX, "GEOM_TRANSFER_DATA_MATERIALS");
207
208   for (i = 1; i <= aNbShapes; ++i) {
209     const TopoDS_Shape      &aSource   = anIndices1.FindKey(i);
210     TCollection_AsciiString  aName     = aTD1.GetName(aSource);
211     TCollection_AsciiString  aMaterial = aTD1.GetMaterial(aSource);
212
213     // Transfer name
214     if (!aName.IsEmpty()) {
215       aDatumMaxVal->ChangeValue(DATUM_NAME_INDEX)++;
216
217       if (aMapSoDest.Contains(aSource)) {
218         aDatumVal->ChangeValue(DATUM_NAME_INDEX)++;
219
220         // Copy name to the list of subshapes of the second shape.
221         const TopTools_ListOfShape         &aListDest =
222           aMapSoDest.FindFromKey(aSource);
223         TopTools_ListIteratorOfListOfShape  anIt(aListDest);
224
225         for (; anIt.More(); anIt.Next()) {
226           const TopoDS_Shape &aShapeDest = anIt.Value();
227
228           if (aMapFence.Add(aShapeDest)) {
229             aTD2.SetName(aShapeDest, aName);
230           }
231         }
232       }
233     }
234
235     // Transfer Material
236     if (!aMaterial.IsEmpty()) {
237       aDatumMaxVal->ChangeValue(DATUM_MATERIAL_INDEX)++;
238
239       if (aMapSoDest.Contains(aSource)) {
240         aDatumVal->ChangeValue(DATUM_MATERIAL_INDEX)++;
241
242         // Copy material to the list of subshapes of the second shape.
243         const TopTools_ListOfShape         &aListDest =
244           aMapSoDest.FindFromKey(aSource);
245         TopTools_ListIteratorOfListOfShape  anIt(aListDest);
246
247         for (; anIt.More(); anIt.Next()) {
248           const TopoDS_Shape &aShapeDest = anIt.Value();
249
250           if (aMapFence.Add(aShapeDest)) {
251             aTD2.SetMaterial(aShapeDest, aMaterial);
252           }
253         }
254       }
255     }
256   }
257
258   // Store results.
259   aTD.SetDatumName(aDatumName);
260   aTD.SetDatumMaxVal(aDatumMaxVal);
261   aTD.SetDatumVal(aDatumVal);
262
263   return 1;
264 }
265
266 //================================================================================
267 /*!
268  * \brief For each subshape of the source shape compute coinsident sub-shapes
269  *        of the destination shape using GetInPlace method.
270  */
271 //================================================================================
272
273 Standard_Boolean GEOMImpl_CopyDriver::getInPlace
274     (const TopoDS_Shape                              &theSourceShape,
275      const TopTools_IndexedMapOfShape                &theSourceIndices,
276      const TopoDS_Shape                              &theDestinationShape,
277            TopTools_IndexedDataMapOfShapeListOfShape &theMapSourceDest) const
278 {
279   // Searching for the sub-shapes inside theDestinationShape shape
280   GEOMAlgo_GetInPlace aGIP;
281
282   if (!GEOMAlgo_GetInPlaceAPI::GetInPlace
283           (theDestinationShape, theSourceShape, aGIP)) {
284     return Standard_False;
285   }
286
287   const GEOMAlgo_DataMapOfShapeMapOfShape &aShapesIn = aGIP.ShapesIn();
288   const GEOMAlgo_DataMapOfShapeMapOfShape &aShapesOn = aGIP.ShapesOn();
289   Standard_Integer                         i;
290   Standard_Integer                         j;
291   Standard_Integer                         aNbShapes = theSourceIndices.Extent();
292
293   for (i = 1; i <= aNbShapes; ++i) {
294     const TopoDS_Shape   &aSource = theSourceIndices.FindKey(i);
295     TopTools_ListOfShape  aListShapes2;
296     TopTools_MapOfShape   aMapShapes2;
297
298     for (j = 0; j < 2; ++j) {
299       const GEOMAlgo_DataMapOfShapeMapOfShape &aShapes2 =
300                     j == 0 ? aShapesIn : aShapesOn;
301
302       if (aShapes2.IsBound(aSource)) {
303         const TopTools_MapOfShape &aMapShapesDest =
304           aShapes2.Find(aSource);
305         TopTools_MapIteratorOfMapOfShape aMapIter(aMapShapesDest);
306
307         for (; aMapIter.More(); aMapIter.Next()) {
308           const TopoDS_Shape &aShapeDest = aMapIter.Key();
309
310           if (aMapShapes2.Add(aShapeDest)) {
311             aListShapes2.Append(aShapeDest);
312           }
313         }
314       }
315     }
316
317     if (!aListShapes2.IsEmpty()) {
318       theMapSourceDest.Add(aSource, aListShapes2);
319     }
320   }
321
322   return Standard_True;
323 }
324
325 //================================================================================
326 /*!
327  * \brief For each subshape of the source shape compute coinsident sub-shapes
328  *        of the destination shape using an old implementation
329  *        of GetInPlace algorithm.
330  */
331 //================================================================================
332
333 Standard_Boolean GEOMImpl_CopyDriver::getInPlaceOld
334     (const Handle(GEOM_Function)                     &theSourceRef,
335      const TopTools_IndexedMapOfShape                &theSourceIndices,
336      const TopoDS_Shape                              &theDestinationShape,
337            TopTools_IndexedDataMapOfShapeListOfShape &theMapSourceDest) const
338 {
339   const Standard_Integer aNbShapes = theSourceIndices.Extent();
340   Standard_Integer       i;
341   Standard_Integer       iErr;
342   TopTools_ListOfShape   aModifiedList;
343   GEOMImpl_ITransferData aTDSource(theSourceRef);
344
345   for (i = 1; i <= aNbShapes; ++i) {
346     const TopoDS_Shape      &aSource   = theSourceIndices.FindKey(i);
347     TCollection_AsciiString  aName     = aTDSource.GetName(aSource);
348     TCollection_AsciiString  aMaterial = aTDSource.GetMaterial(aSource);
349
350     if (aName.IsEmpty() && aMaterial.IsEmpty()) {
351       continue;
352     }
353
354     // Call old GetInPlace.
355     iErr = GEOMAlgo_GetInPlaceAPI::GetInPlaceOld
356       (theDestinationShape, aSource, aModifiedList);
357
358     if (iErr == 3) {
359       // Nothing is found. Skip.
360       continue;
361     }
362
363     if (iErr) {
364       // Error.
365       return Standard_False;
366     }
367
368     theMapSourceDest.Add(aSource, aModifiedList);
369   }
370
371   return Standard_True;
372 }
373
374 //================================================================================
375 /*!
376  * \brief For each subshape of the source shape compute coinsident sub-shapes
377  *        of the destination shape using GetInPlaceByHistory algorithm.
378  */
379 //================================================================================
380
381 Standard_Boolean GEOMImpl_CopyDriver::getInPlaceByHistory
382     (const Handle(GEOM_Function)                     &theSourceRef,
383      const TopTools_IndexedMapOfShape                &theSourceIndices,
384      const TopoDS_Shape                              &theDestinationShape,
385      const Handle(GEOM_Function)                     &theDestinationRef,
386            TopTools_IndexedDataMapOfShapeListOfShape &theMapSourceDest) const
387 {
388   const Standard_Integer aNbShapes = theSourceIndices.Extent();
389   Standard_Integer       i;
390   GEOMImpl_ITransferData aTDSource(theSourceRef);
391   TopTools_IndexedMapOfShape aDestIndices;
392
393   TopExp::MapShapes(theDestinationShape, aDestIndices);
394
395   for (i = 1; i <= aNbShapes; ++i) {
396     const TopoDS_Shape      &aSource   = theSourceIndices.FindKey(i);
397     TCollection_AsciiString  aName     = aTDSource.GetName(aSource);
398     TCollection_AsciiString  aMaterial = aTDSource.GetMaterial(aSource);
399
400     if (aName.IsEmpty() && aMaterial.IsEmpty()) {
401       continue;
402     }
403
404     // Call GetInPlaceByHistory.
405     TopTools_ListOfShape aModifiedList;
406     const Standard_Boolean isFound = GEOMAlgo_GetInPlaceAPI::GetInPlaceByHistory
407       (theDestinationRef, aDestIndices, aSource, aModifiedList);
408
409     if (isFound && !aModifiedList.IsEmpty()) {
410       theMapSourceDest.Add(aSource, aModifiedList);
411     }
412   }
413
414   return Standard_True;
415 }
416
417 IMPLEMENT_STANDARD_HANDLE (GEOMImpl_CopyDriver,GEOM_BaseDriver);
418
419 IMPLEMENT_STANDARD_RTTIEXT (GEOMImpl_CopyDriver,GEOM_BaseDriver);