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