Salome HOME
Merge remote branch 'origin/V7_dev' into V8_0_0_BR
[modules/geom.git] / src / GEOMImpl / GEOMImpl_CopyDriver.cxx
index 8eb25b4079c2073bcee7235411c235f3eabe0935..37fb1074097cf43c0570caa0c23319556fe89fa1 100644 (file)
@@ -1,18 +1,50 @@
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
 
-using namespace std;
 #include "GEOMImpl_CopyDriver.hxx"
 #include "GEOMImpl_ICopy.hxx"
+#include "GEOMImpl_ITransferData.hxx"
 #include "GEOMImpl_Types.hxx"
 #include "GEOM_Function.hxx"
+#include "GEOM_Object.hxx"
+#include "GEOMAlgo_GetInPlace.hxx"
+#include "GEOMAlgo_GetInPlaceAPI.hxx"
 
-#include <BRep_Tool.hxx>
-#include <gp_Pnt.hxx>
-#include <TopoDS.hxx>
 #include <TopoDS_Shape.hxx>
-#include <TopoDS_Vertex.hxx>
-#include <TopAbs.hxx>
+#include <TopExp.hxx>
 #include <TNaming_CopyShape.hxx>
 #include <TColStd_IndexedDataMapOfTransientTransient.hxx>
+#include <TFunction_Logbook.hxx>
+#include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
+#include <TopTools_IndexedMapOfShape.hxx>
+#include <TopTools_ListIteratorOfListOfShape.hxx>
+#include <TopTools_ListOfShape.hxx>
+#include <TopTools_MapIteratorOfMapOfShape.hxx>
+
+
+#define NB_DATUM             2
+#define DATUM_NAME_INDEX     1
+#define DATUM_MATERIAL_INDEX 2
+
 
 //=======================================================================
 //function : GetID
@@ -44,6 +76,10 @@ Standard_Integer GEOMImpl_CopyDriver::Execute(TFunction_Logbook& log) const
 
   Standard_Integer aType = aFunction->GetType();
 
+  if (aType == TRANSFER_DATA) {
+    return transferData(log);
+  }
+
   GEOMImpl_ICopy aCI (aFunction);
   TopoDS_Shape aCopy;
   
@@ -70,45 +106,314 @@ Standard_Integer GEOMImpl_CopyDriver::Execute(TFunction_Logbook& log) const
   return 1;    
 }
 
+//================================================================================
+/*!
+ * \brief Returns a name of creation operation and names and values of creation parameters
+ */
+//================================================================================
 
-//=======================================================================
-//function :  GEOMImpl_CopyDriver_Type_
-//purpose  :
-//======================================================================= 
-Standard_EXPORT Handle_Standard_Type& GEOMImpl_CopyDriver_Type_()
+bool GEOMImpl_CopyDriver::
+GetCreationInformation(std::string&             theOperationName,
+                       std::vector<GEOM_Param>& theParams)
 {
+  if (Label().IsNull()) return 0;
+  Handle(GEOM_Function) function = GEOM_Function::GetFunction(Label());
+
+  GEOMImpl_ICopy aCI( function );
+  Standard_Integer aType = function->GetType();
+
 
-  static Handle_Standard_Type aType1 = STANDARD_TYPE(TFunction_Driver);
-  if ( aType1.IsNull()) aType1 = STANDARD_TYPE(TFunction_Driver);
-  static Handle_Standard_Type aType2 = STANDARD_TYPE(MMgt_TShared);
-  if ( aType2.IsNull()) aType2 = STANDARD_TYPE(MMgt_TShared); 
-  static Handle_Standard_Type aType3 = STANDARD_TYPE(Standard_Transient);
-  if ( aType3.IsNull()) aType3 = STANDARD_TYPE(Standard_Transient);
-
-  static Handle_Standard_Transient _Ancestors[]= {aType1,aType2,aType3,NULL};
-  static Handle_Standard_Type _aType = new Standard_Type("GEOMImpl_CopyDriver",
-                                                        sizeof(GEOMImpl_CopyDriver),
-                                                        1,
-                                                        (Standard_Address)_Ancestors,
-                                                        (Standard_Address)NULL);
-
-  return _aType;
+  switch ( aType ) {
+  case COPY_WITH_REF:
+    theOperationName = "MakeCopy";
+    AddParam( theParams, "Original", aCI.GetOriginal() );
+    break;
+  case COPY_WITHOUT_REF:
+  {
+    theOperationName = "RestoreShape";
+    TDF_Label label = Label();
+    Handle(GEOM_Object) obj = GEOM_Object::GetObject(label);
+    if ( !obj.IsNull() && obj->GetType() == GEOM_FREE_BOUNDS )
+      theOperationName = "CHECK_FREE_BNDS";
+    break;
+  }
+  default:
+    return false;
+  }
+  
+  return true;
 }
 
-//=======================================================================
-//function : DownCast
-//purpose  :
-//======================================================================= 
-const Handle(GEOMImpl_CopyDriver) Handle(GEOMImpl_CopyDriver)::DownCast(const Handle(Standard_Transient)& AnObject)
+//================================================================================
+/*!
+ * \brief Performs Transfer Data operation.
+ */
+//================================================================================
+
+Standard_Integer GEOMImpl_CopyDriver::transferData(TFunction_Logbook& log) const
+{
+  Handle(GEOM_Function)  aFunction = GEOM_Function::GetFunction(Label());
+  GEOMImpl_ITransferData aTD (aFunction);
+  Handle(GEOM_Function)  aRef1     = aTD.GetRef1();
+  Handle(GEOM_Function)  aRef2     = aTD.GetRef2();
+
+  if (aRef1.IsNull() || aRef2.IsNull()) {
+    return 0;
+  }
+
+  TopoDS_Shape                              aShape1     = aRef1->GetValue();
+  TopoDS_Shape                              aShape2     = aRef2->GetValue();
+  const int                                 aFindMethod = aTD.GetFindMethod();
+  TopTools_IndexedDataMapOfShapeListOfShape aMapSoDest;
+  TopTools_IndexedMapOfShape                anIndices1;
+
+  TopExp::MapShapes(aShape1, anIndices1);
+
+  switch (aFindMethod) {
+    case TD_GET_IN_PLACE:
+      if (!getInPlace(aShape1, anIndices1, aShape2, aMapSoDest)) {
+        return 0;
+      }
+      break;
+    case TD_GET_IN_PLACE_OLD:
+      if (!getInPlaceOld(aRef1, anIndices1, aShape2, aMapSoDest)) {
+        return 0;
+      }
+      break;
+    case TD_GET_IN_PLACE_BY_HISTORY:
+      if (!getInPlaceByHistory(aRef1, anIndices1, aShape2, aRef2, aMapSoDest)) {
+        return 0;
+      }
+      break;
+    default:
+      return 0;
+  }
+
+  // Perform copying names.
+  Handle(TColStd_HArray1OfExtendedString) aDatumName   =
+    new TColStd_HArray1OfExtendedString(1, NB_DATUM);
+  Handle(TColStd_HArray1OfInteger)        aDatumMaxVal =
+    new TColStd_HArray1OfInteger(1, NB_DATUM, 0);
+  Handle(TColStd_HArray1OfInteger)        aDatumVal    =
+    new TColStd_HArray1OfInteger(1, NB_DATUM, 0);
+  GEOMImpl_ITransferData                  aTD1(aRef1);
+  GEOMImpl_ITransferData                  aTD2(aRef2);
+  Standard_Integer                        i;
+  Standard_Integer                        aNbShapes = anIndices1.Extent();
+  TopTools_MapOfShape                     aMapFence;
+
+  aDatumName->SetValue(DATUM_NAME_INDEX,     "GEOM_TRANSFER_DATA_NAMES");
+  aDatumName->SetValue(DATUM_MATERIAL_INDEX, "GEOM_TRANSFER_DATA_MATERIALS");
+
+  for (i = 1; i <= aNbShapes; ++i) {
+    const TopoDS_Shape      &aSource   = anIndices1.FindKey(i);
+    TCollection_AsciiString  aName     = aTD1.GetName(aSource);
+    TCollection_AsciiString  aMaterial = aTD1.GetMaterial(aSource);
+
+    // Transfer name
+    if (!aName.IsEmpty()) {
+      aDatumMaxVal->ChangeValue(DATUM_NAME_INDEX)++;
+
+      if (aMapSoDest.Contains(aSource)) {
+        aDatumVal->ChangeValue(DATUM_NAME_INDEX)++;
+
+        // Copy name to the list of subshapes of the second shape.
+        const TopTools_ListOfShape         &aListDest =
+          aMapSoDest.FindFromKey(aSource);
+        TopTools_ListIteratorOfListOfShape  anIt(aListDest);
+
+        for (; anIt.More(); anIt.Next()) {
+          const TopoDS_Shape &aShapeDest = anIt.Value();
+
+          if (aMapFence.Add(aShapeDest)) {
+            aTD2.SetName(aShapeDest, aName);
+          }
+        }
+      }
+    }
+
+    // Transfer Material
+    if (!aMaterial.IsEmpty()) {
+      aDatumMaxVal->ChangeValue(DATUM_MATERIAL_INDEX)++;
+
+      if (aMapSoDest.Contains(aSource)) {
+        aDatumVal->ChangeValue(DATUM_MATERIAL_INDEX)++;
+
+        // Copy material to the list of subshapes of the second shape.
+        const TopTools_ListOfShape         &aListDest =
+          aMapSoDest.FindFromKey(aSource);
+        TopTools_ListIteratorOfListOfShape  anIt(aListDest);
+
+        for (; anIt.More(); anIt.Next()) {
+          const TopoDS_Shape &aShapeDest = anIt.Value();
+
+          if (aMapFence.Add(aShapeDest)) {
+            aTD2.SetMaterial(aShapeDest, aMaterial);
+          }
+        }
+      }
+    }
+  }
+
+  // Store results.
+  aTD.SetDatumName(aDatumName);
+  aTD.SetDatumMaxVal(aDatumMaxVal);
+  aTD.SetDatumVal(aDatumVal);
+
+  return 1;
+}
+
+//================================================================================
+/*!
+ * \brief For each subshape of the source shape compute coinsident sub-shapes
+ *        of the destination shape using GetInPlace method.
+ */
+//================================================================================
+
+Standard_Boolean GEOMImpl_CopyDriver::getInPlace
+    (const TopoDS_Shape                              &theSourceShape,
+     const TopTools_IndexedMapOfShape                &theSourceIndices,
+     const TopoDS_Shape                              &theDestinationShape,
+           TopTools_IndexedDataMapOfShapeListOfShape &theMapSourceDest) const
+{
+  // Searching for the sub-shapes inside theDestinationShape shape
+  GEOMAlgo_GetInPlace aGIP;
+
+  if (!GEOMAlgo_GetInPlaceAPI::GetInPlace
+          (theDestinationShape, theSourceShape, aGIP)) {
+    return Standard_False;
+  }
+
+  const GEOMAlgo_DataMapOfShapeMapOfShape &aShapesIn = aGIP.ShapesIn();
+  const GEOMAlgo_DataMapOfShapeMapOfShape &aShapesOn = aGIP.ShapesOn();
+  Standard_Integer                         i;
+  Standard_Integer                         j;
+  Standard_Integer                         aNbShapes = theSourceIndices.Extent();
+
+  for (i = 1; i <= aNbShapes; ++i) {
+    const TopoDS_Shape   &aSource = theSourceIndices.FindKey(i);
+    TopTools_ListOfShape  aListShapes2;
+    TopTools_MapOfShape   aMapShapes2;
+
+    for (j = 0; j < 2; ++j) {
+      const GEOMAlgo_DataMapOfShapeMapOfShape &aShapes2 =
+                    j == 0 ? aShapesIn : aShapesOn;
+
+      if (aShapes2.IsBound(aSource)) {
+        const TopTools_MapOfShape &aMapShapesDest =
+          aShapes2.Find(aSource);
+        TopTools_MapIteratorOfMapOfShape aMapIter(aMapShapesDest);
+
+        for (; aMapIter.More(); aMapIter.Next()) {
+          const TopoDS_Shape &aShapeDest = aMapIter.Key();
+
+          if (aMapShapes2.Add(aShapeDest)) {
+            aListShapes2.Append(aShapeDest);
+          }
+        }
+      }
+    }
+
+    if (!aListShapes2.IsEmpty()) {
+      theMapSourceDest.Add(aSource, aListShapes2);
+    }
+  }
+
+  return Standard_True;
+}
+
+//================================================================================
+/*!
+ * \brief For each subshape of the source shape compute coinsident sub-shapes
+ *        of the destination shape using an old implementation
+ *        of GetInPlace algorithm.
+ */
+//================================================================================
+
+Standard_Boolean GEOMImpl_CopyDriver::getInPlaceOld
+    (const Handle(GEOM_Function)                     &theSourceRef,
+     const TopTools_IndexedMapOfShape                &theSourceIndices,
+     const TopoDS_Shape                              &theDestinationShape,
+           TopTools_IndexedDataMapOfShapeListOfShape &theMapSourceDest) const
 {
-  Handle(GEOMImpl_CopyDriver) _anOtherObject;
+  const Standard_Integer aNbShapes = theSourceIndices.Extent();
+  Standard_Integer       i;
+  Standard_Integer       iErr;
+  TopTools_ListOfShape   aModifiedList;
+  GEOMImpl_ITransferData aTDSource(theSourceRef);
+
+  for (i = 1; i <= aNbShapes; ++i) {
+    const TopoDS_Shape      &aSource   = theSourceIndices.FindKey(i);
+    TCollection_AsciiString  aName     = aTDSource.GetName(aSource);
+    TCollection_AsciiString  aMaterial = aTDSource.GetMaterial(aSource);
+
+    if (aName.IsEmpty() && aMaterial.IsEmpty()) {
+      continue;
+    }
+
+    // Call old GetInPlace.
+    iErr = GEOMAlgo_GetInPlaceAPI::GetInPlaceOld
+      (theDestinationShape, aSource, aModifiedList);
+
+    if (iErr == 3) {
+      // Nothing is found. Skip.
+      continue;
+    }
 
-  if (!AnObject.IsNull()) {
-     if (AnObject->IsKind(STANDARD_TYPE(GEOMImpl_CopyDriver))) {
-       _anOtherObject = Handle(GEOMImpl_CopyDriver)((Handle(GEOMImpl_CopyDriver)&)AnObject);
-     }
+    if (iErr) {
+      // Error.
+      return Standard_False;
+    }
+
+    theMapSourceDest.Add(aSource, aModifiedList);
   }
 
-  return _anOtherObject ;
+  return Standard_True;
 }
+
+//================================================================================
+/*!
+ * \brief For each subshape of the source shape compute coinsident sub-shapes
+ *        of the destination shape using GetInPlaceByHistory algorithm.
+ */
+//================================================================================
+
+Standard_Boolean GEOMImpl_CopyDriver::getInPlaceByHistory
+    (const Handle(GEOM_Function)                     &theSourceRef,
+     const TopTools_IndexedMapOfShape                &theSourceIndices,
+     const TopoDS_Shape                              &theDestinationShape,
+     const Handle(GEOM_Function)                     &theDestinationRef,
+           TopTools_IndexedDataMapOfShapeListOfShape &theMapSourceDest) const
+{
+  const Standard_Integer aNbShapes = theSourceIndices.Extent();
+  Standard_Integer       i;
+  GEOMImpl_ITransferData aTDSource(theSourceRef);
+  TopTools_IndexedMapOfShape aDestIndices;
+
+  TopExp::MapShapes(theDestinationShape, aDestIndices);
+
+  for (i = 1; i <= aNbShapes; ++i) {
+    const TopoDS_Shape      &aSource   = theSourceIndices.FindKey(i);
+    TCollection_AsciiString  aName     = aTDSource.GetName(aSource);
+    TCollection_AsciiString  aMaterial = aTDSource.GetMaterial(aSource);
+
+    if (aName.IsEmpty() && aMaterial.IsEmpty()) {
+      continue;
+    }
+
+    // Call GetInPlaceByHistory.
+    TopTools_ListOfShape aModifiedList;
+    const Standard_Boolean isFound = GEOMAlgo_GetInPlaceAPI::GetInPlaceByHistory
+      (theDestinationRef, aDestIndices, aSource, aModifiedList);
+
+    if (isFound && !aModifiedList.IsEmpty()) {
+      theMapSourceDest.Add(aSource, aModifiedList);
+    }
+  }
+
+  return Standard_True;
+}
+
+IMPLEMENT_STANDARD_HANDLE (GEOMImpl_CopyDriver,GEOM_BaseDriver);
+
+IMPLEMENT_STANDARD_RTTIEXT (GEOMImpl_CopyDriver,GEOM_BaseDriver);