Salome HOME
Make the movement, placement and rotation 3D features may be applied to the Part...
authormpv <mpv@opencascade.com>
Wed, 8 Jul 2015 13:05:43 +0000 (16:05 +0300)
committermpv <mpv@opencascade.com>
Wed, 8 Jul 2015 13:05:43 +0000 (16:05 +0300)
31 files changed:
src/FeaturesPlugin/FeaturesPlugin_Movement.cpp
src/FeaturesPlugin/FeaturesPlugin_Placement.cpp
src/FeaturesPlugin/FeaturesPlugin_Rotation.cpp
src/FeaturesPlugin/plugin-Features.xml
src/GeomAPI/GeomAPI.i
src/GeomAlgoAPI/GeomAlgoAPI_Movement.cpp
src/GeomAlgoAPI/GeomAlgoAPI_Movement.h
src/GeomAlgoAPI/GeomAlgoAPI_Placement.cpp
src/GeomAlgoAPI/GeomAlgoAPI_Placement.h
src/GeomAlgoAPI/GeomAlgoAPI_Rotation.cpp
src/GeomAlgoAPI/GeomAlgoAPI_Rotation.h
src/Model/Model_AttributeSelection.cpp
src/Model/Model_AttributeSelection.h
src/Model/Model_Data.cpp
src/Model/Model_Data.h
src/Model/Model_Document.cpp
src/Model/Model_Document.h
src/Model/Model_Objects.cpp
src/Model/Model_Objects.h
src/Model/Model_ResultPart.cpp
src/Model/Model_ResultPart.h
src/Model/Model_Update.cpp
src/ModelAPI/ModelAPI.i
src/ModelAPI/ModelAPI_Data.h
src/ModelAPI/ModelAPI_Document.h
src/ModelAPI/ModelAPI_Object.cpp
src/ModelAPI/ModelAPI_Object.h
src/ModelAPI/ModelAPI_Result.cpp
src/ModelAPI/ModelAPI_Result.h
src/ModelAPI/ModelAPI_ResultPart.cpp
src/ModelAPI/ModelAPI_ResultPart.h

index 12bced3492af158b35df305ad529a48fd9a9513c..3b6779bc7a38fb2e42c661f6b4a46d4297932921 100644 (file)
@@ -9,6 +9,7 @@
 #include <ModelAPI_AttributeDouble.h>
 #include <ModelAPI_AttributeSelectionList.h>
 #include <ModelAPI_ResultBody.h>
+#include <ModelAPI_ResultPart.h>
 #include <ModelAPI_Session.h>
 
 #include <GeomAPI_Edge.h>
@@ -37,6 +38,7 @@ void FeaturesPlugin_Movement::execute()
 {
   // Getting objects.
   ListOfShape anObjects;
+  std::list<ResultPtr> aContextes;
   AttributeSelectionListPtr anObjectsSelList = selectionList(FeaturesPlugin_Movement::OBJECTS_LIST_ID());
   if (anObjectsSelList->size() == 0) {
     return;
@@ -48,6 +50,7 @@ void FeaturesPlugin_Movement::execute()
       return;
     }
     anObjects.push_back(anObject);
+    aContextes.push_back(anObjectAttr->context());
   }
 
   //Getting axis.
@@ -66,9 +69,12 @@ void FeaturesPlugin_Movement::execute()
 
   // Moving each object.
   int aResultIndex = 0;
-  for(ListOfShape::iterator anObjectsIt = anObjects.begin(); anObjectsIt != anObjects.end(); anObjectsIt++) {
+  std::list<ResultPtr>::iterator aContext = aContextes.begin();
+  for(ListOfShape::iterator anObjectsIt = anObjects.begin(); anObjectsIt != anObjects.end();
+        anObjectsIt++, aContext++) {
     std::shared_ptr<GeomAPI_Shape> aBaseShape = *anObjectsIt;
-    GeomAlgoAPI_Movement aMovementAlgo(aBaseShape, anAxis, aDistance);
+    bool isPart = (*aContext)->groupName() == ModelAPI_ResultPart::group();
+    GeomAlgoAPI_Movement aMovementAlgo(aBaseShape, anAxis, aDistance, isPart);
 
     // Checking that the algorithm worked properly.
     if(!aMovementAlgo.isDone()) {
@@ -88,9 +94,26 @@ void FeaturesPlugin_Movement::execute()
     }
 
     // Setting result.
-    ResultBodyPtr aResultBody = document()->createBody(data(), aResultIndex);
-    LoadNamingDS(aMovementAlgo, aResultBody, aBaseShape);
-    setResult(aResultBody, aResultIndex);
+    if (isPart) {
+      ResultPartPtr anOrigin = std::dynamic_pointer_cast<ModelAPI_ResultPart>(*aContext);
+
+      ResultPartPtr aCurrentResult;
+      const std::list<std::shared_ptr<ModelAPI_Result> >& aResults = results();
+      std::list<std::shared_ptr<ModelAPI_Result> >::const_iterator aResIter = aResults.begin();
+      for(int a = 0; aResIter != aResults.end(); aResIter++, a++)  {
+        if (a == aResultIndex) {
+          aCurrentResult = std::dynamic_pointer_cast<ModelAPI_ResultPart>(*aResIter);
+          break;
+        }
+      }
+      ResultPartPtr aResultPart = document()->copyPart(aCurrentResult, anOrigin, aResultIndex);
+      aResultPart->setShape(*aContext, aMovementAlgo.shape());
+      setResult(aResultPart);
+    } else {
+      ResultBodyPtr aResultBody = document()->createBody(data(), aResultIndex);
+      LoadNamingDS(aMovementAlgo, aResultBody, aBaseShape);
+      setResult(aResultBody, aResultIndex);
+    }
     aResultIndex++;
   }
 
index d069858d45e3c528412516c8e6b3c73911cc7f88..63f25c921c447afb0c3da63fa0f57d214da0000c 100644 (file)
@@ -8,6 +8,7 @@
 
 #include <ModelAPI_ResultConstruction.h>
 #include <ModelAPI_ResultBody.h>
+#include <ModelAPI_ResultPart.h>
 #include <ModelAPI_AttributeSelection.h>
 #include <ModelAPI_AttributeBoolean.h>
 #include <ModelAPI_AttributeSelectionList.h>
@@ -55,14 +56,11 @@ void FeaturesPlugin_Placement::execute()
 
   std::shared_ptr<GeomAPI_Shape> aBaseObject;
   ResultPtr aContextRes = anObjRef->context();
-  if (aContextRes) {
-    if (aContextRes->groupName() == ModelAPI_ResultBody::group())
-      aBaseObject = std::dynamic_pointer_cast<ModelAPI_ResultBody>(aContextRes)->shape();
-    else if (aContextRes->groupName() == ModelAPI_ResultConstruction::group())
-      aBaseObject = std::dynamic_pointer_cast<ModelAPI_ResultConstruction>(aContextRes)->shape();
+  if (aContextRes.get()) {
+    aBaseObject = aContextRes->shape();
   }
-  if (!aBaseObject) {
-    static const std::string aContextError = "The selection context is bad";
+  if (!aBaseObject.get()) {
+    static const std::string aContextError = "The base selection context is bad";
     setError(aContextError);
     return;
   }
@@ -78,14 +76,11 @@ void FeaturesPlugin_Placement::execute()
 
   std::shared_ptr<GeomAPI_Shape> aSlaveObject;
   aContextRes = anObjRef->context();
-  if (aContextRes) {
-    if (aContextRes->groupName() == ModelAPI_ResultBody::group())
-      aSlaveObject = std::dynamic_pointer_cast<ModelAPI_ResultBody>(aContextRes)->shape();
-    else if (aContextRes->groupName() == ModelAPI_ResultConstruction::group())
-      aSlaveObject = std::dynamic_pointer_cast<ModelAPI_ResultConstruction>(aContextRes)->shape();
+  if (aContextRes.get()) {
+    aSlaveObject = aContextRes->shape();
   }
-  if (!aSlaveObject) {
-    static const std::string aContextError = "The selection context is bad";
+  if (!aSlaveObject.get()) {
+    static const std::string aContextError = "The tool selection context is bad";
     setError(aContextError);
     return;
   }
@@ -119,7 +114,11 @@ void FeaturesPlugin_Placement::execute()
       data()->attribute(FeaturesPlugin_Placement::CENTERING_ID()));
   bool isCentering = aBoolAttr->value();
 
-  std::shared_ptr<ModelAPI_ResultBody> aResultBody = document()->createBody(data());
+  bool isPart = aContextRes->groupName() == ModelAPI_ResultPart::group();
+
+  std::shared_ptr<ModelAPI_ResultBody> aResultBody;
+  if (isPart) 
+    aResultBody = document()->createBody(data());
   GeomAlgoAPI_Placement aFeature(aSlaveObject, aBaseObject, aSlaveShape, aBaseShape, isReverse, isCentering);
   if(!aFeature.isDone()) {
     static const std::string aFeatureError = "Placement algorithm failed";
@@ -138,10 +137,18 @@ void FeaturesPlugin_Placement::execute()
     setError(aFeatureError);
     return;
   }  
-  //LoadNamingDS
-  LoadNamingDS(aFeature, aResultBody, aSlaveObject);
 
-  setResult(aResultBody);
+  if (isPart) { // for part results just set transformation
+    ResultPartPtr anOrigin = std::dynamic_pointer_cast<ModelAPI_ResultPart>(aContextRes);
+    ResultPartPtr aResultPart = document()->copyPart(firstResult(), anOrigin);
+    aResultPart->setShape(aContextRes, aFeature.shape());
+    setResult(aResultPart);
+  } else {
+    //LoadNamingDS
+    LoadNamingDS(aFeature, aResultBody, aSlaveObject);
+
+    setResult(aResultBody);
+  }
 }
 
 //============================================================================
index 25faa8dd6897d6a33ebae6969692d296b72a5f40..bbaf84a0ec0d617f457df64fefce286f961f92c7 100755 (executable)
@@ -10,6 +10,7 @@
 #include <ModelAPI_AttributeSelectionList.h>
 #include <ModelAPI_ResultBody.h>
 #include <ModelAPI_Session.h>
+#include <ModelAPI_ResultPart.h>
 
 #include <GeomAPI_Edge.h>
 #include <GeomAPI_Lin.h>
@@ -37,6 +38,7 @@ void FeaturesPlugin_Rotation::execute()
 {
   // Getting objects.
   ListOfShape anObjects;
+  std::list<ResultPtr> aContextes;
   AttributeSelectionListPtr anObjectsSelList = selectionList(FeaturesPlugin_Rotation::OBJECTS_LIST_ID());
   if (anObjectsSelList->size() == 0) {
     return;
@@ -48,6 +50,7 @@ void FeaturesPlugin_Rotation::execute()
       return;
     }
     anObjects.push_back(anObject);
+    aContextes.push_back(anObjectAttr->context());
   }
 
   //Getting axis.
@@ -66,9 +69,12 @@ void FeaturesPlugin_Rotation::execute()
 
   // Rotating each object.
   int aResultIndex = 0;
-  for(ListOfShape::iterator anObjectsIt = anObjects.begin(); anObjectsIt != anObjects.end(); anObjectsIt++) {
+  std::list<ResultPtr>::iterator aContext = aContextes.begin();
+  for(ListOfShape::iterator anObjectsIt = anObjects.begin(); anObjectsIt != anObjects.end(); 
+        anObjectsIt++, aContext++) {
     std::shared_ptr<GeomAPI_Shape> aBaseShape = *anObjectsIt;
-    GeomAlgoAPI_Rotation aRotationAlgo(aBaseShape, anAxis, anAngle);
+    bool isPart = (*aContext)->groupName() == ModelAPI_ResultPart::group();
+    GeomAlgoAPI_Rotation aRotationAlgo(aBaseShape, anAxis, anAngle, isPart);
 
     // Checking that the algorithm worked properly.
     if(!aRotationAlgo.isDone()) {
@@ -88,9 +94,26 @@ void FeaturesPlugin_Rotation::execute()
     }
 
     // Setting result.
-    ResultBodyPtr aResultBody = document()->createBody(data(), aResultIndex);
-    LoadNamingDS(aRotationAlgo, aResultBody, aBaseShape);
-    setResult(aResultBody, aResultIndex);
+    if (isPart) {
+      ResultPartPtr anOrigin = std::dynamic_pointer_cast<ModelAPI_ResultPart>(*aContext);
+
+      ResultPartPtr aCurrentResult;
+      const std::list<std::shared_ptr<ModelAPI_Result> >& aResults = results();
+      std::list<std::shared_ptr<ModelAPI_Result> >::const_iterator aResIter = aResults.begin();
+      for(int a = 0; aResIter != aResults.end(); aResIter++, a++)  {
+        if (a == aResultIndex) {
+          aCurrentResult = std::dynamic_pointer_cast<ModelAPI_ResultPart>(*aResIter);
+          break;
+        }
+      }
+      ResultPartPtr aResultPart = document()->copyPart(aCurrentResult, anOrigin, aResultIndex);
+      aResultPart->setShape(*aContext, aRotationAlgo.shape());
+      setResult(aResultPart);
+    } else {
+      ResultBodyPtr aResultBody = document()->createBody(data(), aResultIndex);
+      LoadNamingDS(aRotationAlgo, aResultBody, aBaseShape);
+      setResult(aResultBody, aResultIndex);
+    }
     aResultIndex++;
   }
 
index 62a41318daba9c9f54802acc15dde71f27379737..d9437f1310f6f372b18b2b4c3c3cfaa7e4b4147a 100644 (file)
@@ -1,6 +1,19 @@
 <!-- Copyright (C) 2014-20xx CEA/DEN, EDF R&D -->
 
 <plugin>
+  <workbench id="Movement">
+    <group id="Basic">
+      <feature id="Placement" title="Placement" tooltip="Perform moving of an object to specified position" icon=":icons/placement.png">
+        <source path="placement_widget.xml"/>
+      </feature>
+      <feature id="Movement" title="Movement" tooltip="Perform movement of an objects along the axis to specified distance" icon=":icons/movement.png">
+        <source path="movement_widget.xml"/>
+      </feature>
+      <feature id="Rotation" title="Rotation" tooltip="Perform rotation of an objects around the axis to specified angle" icon=":icons/rotation.png">
+        <source path="rotation_widget.xml"/>
+      </feature>
+    </group>
+  </workbench>
   <workbench id="Features" document="Part">
     <group id="Extrusion">
       <feature id="Extrusion" title="Extrusion" tooltip="Create a solid by extrusion of a face" icon=":icons/extrusion.png">
           <source path="boolean_widget.xml"/>
       </feature>
     </group>
-    <group id="Basic">
-      <feature id="Placement" title="Placement" tooltip="Perform moving of an object to specified position" icon=":icons/placement.png">
-        <source path="placement_widget.xml"/>
-      </feature>
-      <feature id="Movement" title="Movement" tooltip="Perform movement of an objects along the axis to specified distance" icon=":icons/movement.png">
-        <source path="movement_widget.xml"/>
-      </feature>
-      <feature id="Rotation" title="Rotation" tooltip="Perform rotation of an objects around the axis to specified angle" icon=":icons/rotation.png">
-        <source path="rotation_widget.xml"/>
-      </feature>
-    </group>
     <group id="Collections">
       <feature id="Group"
         title="Group"
index 0d79eec6c8e94814fe36e61c63a7d777101c13c4..ea223aac64330b89a607a524e0a7081601c872df 100644 (file)
@@ -69,6 +69,8 @@
 
 
 // all supported interfaces
+%include "GeomAPI_Interface.h"
+%include "GeomAPI_Shape.h"
 %include "GeomAPI_AISObject.h"
 %include "GeomAPI_Ax1.h"
 %include "GeomAPI_Ax3.h"
@@ -81,7 +83,6 @@
 %include "GeomAPI_Edge.h"
 %include "GeomAPI_Face.h"
 %include "GeomAPI_ICustomPrs.h"
-%include "GeomAPI_Interface.h"
 %include "GeomAPI_IPresentable.h"
 %include "GeomAPI_Lin.h"
 %include "GeomAPI_Lin2d.h"
@@ -89,7 +90,6 @@
 %include "GeomAPI_Pln.h"
 %include "GeomAPI_Pnt.h"
 %include "GeomAPI_Pnt2d.h"
-%include "GeomAPI_Shape.h"
 %include "GeomAPI_ShapeExplorer.h"
 %include "GeomAPI_Vertex.h"
 %include "GeomAPI_XY.h"
index cb043a4ef0d401fb8857e181326936764b962e2d..40a14a5a525bd7eeecf98841e2081e9634a8b4c8 100644 (file)
 //=================================================================================================
 GeomAlgoAPI_Movement::GeomAlgoAPI_Movement(std::shared_ptr<GeomAPI_Shape> theSourceShape,
                                            std::shared_ptr<GeomAPI_Ax1>   theAxis,
-                                           double                         theDistance)
+                                           double                         theDistance,
+                                           bool theSimpleTransform)
 : myDone(false),
   myShape(new GeomAPI_Shape()),
   myMap(new GeomAPI_DataMapOfShapeShape()),
   myMkShape(new GeomAlgoAPI_MakeShape())
 {
-  build(theSourceShape, theAxis, theDistance);
+  build(theSourceShape, theAxis, theDistance, theSimpleTransform);
 }
 
 //=================================================================================================
 void GeomAlgoAPI_Movement::build(std::shared_ptr<GeomAPI_Shape> theSourceShape,
                                  std::shared_ptr<GeomAPI_Ax1>   theAxis,
-                                 double                         theDistance)
+                                 double                         theDistance,
+                                 bool theSimpleTransform)
 {
   if(!theSourceShape || !theAxis) {
     return;
@@ -45,28 +47,35 @@ void GeomAlgoAPI_Movement::build(std::shared_ptr<GeomAPI_Shape> theSourceShape,
   gp_Trsf aTrsf;
   aTrsf.SetTranslation(gp_Vec(anAxis.Direction()) * theDistance);
 
+  TopoDS_Shape aResult;
   // Transform the shape with copying it.
-  BRepBuilderAPI_Transform* aBuilder = new BRepBuilderAPI_Transform(aSourceShape, aTrsf, true);
-  if(!aBuilder) {
-    return;
-  }
-
-  myDone = aBuilder->IsDone() == Standard_True;
-
-  if(!myDone) {
-    return;
-  }
-
-  TopoDS_Shape aResult = aBuilder->Shape();
-  // Fill data map to keep correct orientation of sub-shapes.
-  for(TopExp_Explorer anExp(aResult, TopAbs_FACE); anExp.More(); anExp.Next()) {
-    std::shared_ptr<GeomAPI_Shape> aCurrentShape(new GeomAPI_Shape());
-    aCurrentShape->setImpl(new TopoDS_Shape(anExp.Current()));
-    myMap->bind(aCurrentShape, aCurrentShape);
+  if (theSimpleTransform) {
+    TopLoc_Location aDelta(aTrsf);
+    aResult = aSourceShape.Moved(aDelta);
+    myDone = true; // is OK for sure
+  } else {
+    BRepBuilderAPI_Transform* aBuilder = new BRepBuilderAPI_Transform(aSourceShape, aTrsf, true);
+    if(!aBuilder) {
+      return;
+    }
+
+    myDone = aBuilder->IsDone() == Standard_True;
+
+    if(!myDone) {
+      return;
+    }
+
+    aResult = aBuilder->Shape();
+    // Fill data map to keep correct orientation of sub-shapes.
+    for(TopExp_Explorer anExp(aResult, TopAbs_FACE); anExp.More(); anExp.Next()) {
+      std::shared_ptr<GeomAPI_Shape> aCurrentShape(new GeomAPI_Shape());
+      aCurrentShape->setImpl(new TopoDS_Shape(anExp.Current()));
+      myMap->bind(aCurrentShape, aCurrentShape);
+    }
+    myMkShape->setImpl(aBuilder);
   }
 
   myShape->setImpl(new TopoDS_Shape(aResult));
-  myMkShape->setImpl(aBuilder);
 }
 
 //=================================================================================================
index 2068ec844f10e00436e5c49941028a2bfdd444f2..53eb4f4d118c71dc7121473ee45d110818c6f9ad 100644 (file)
@@ -24,10 +24,12 @@ public:
    *  \param[in] theSourceShape  a shape to be moved.
    *  \param[in] theAxis         movement axis.
    *  \param[in] theDistance     movement distance.
+   *  \param[in] theSimpleTransform makes just transformation of shape without changing of topology or geometry
    */
   GEOMALGOAPI_EXPORT GeomAlgoAPI_Movement(std::shared_ptr<GeomAPI_Shape> theSourceShape,
                                           std::shared_ptr<GeomAPI_Ax1>   theAxis,
-                                          double                         theDistance);
+                                          double                         theDistance,
+                                          bool theSimpleTransform = false);
 
   /// \return true if algorithm succeed.
   GEOMALGOAPI_EXPORT const bool isDone() const
@@ -52,7 +54,8 @@ private:
   /// Builds resulting shape.
   void build(std::shared_ptr<GeomAPI_Shape> theSourceShape,
              std::shared_ptr<GeomAPI_Ax1>   theAxis,
-             double                         theDistance);
+             double                         theDistance,
+             bool theSimpleTransform);
 
 private:
   /// Fields.
index 651e0360120efd4664a8debc614966d81d0683e5..35ea7c186211d35d4fcf1ac43259d087f1d0941a 100644 (file)
@@ -31,11 +31,13 @@ GeomAlgoAPI_Placement::GeomAlgoAPI_Placement(
   std::shared_ptr<GeomAPI_Shape> theSourceShape,
   std::shared_ptr<GeomAPI_Shape> theDestShape,
   bool theIsReverse,
-  bool theIsCentering)
+  bool theIsCentering, 
+  bool theSimpleTransform)
   : myDone(false),
   myShape(new GeomAPI_Shape())
 {
-  build(theSourceSolid, theDestSolid, theSourceShape, theDestShape, theIsReverse, theIsCentering);
+  build(theSourceSolid, theDestSolid, theSourceShape, theDestShape, 
+    theIsReverse, theIsCentering, theSimpleTransform);
 }
 
 void GeomAlgoAPI_Placement::build(
@@ -44,7 +46,8 @@ void GeomAlgoAPI_Placement::build(
   const std::shared_ptr<GeomAPI_Shape>& theSourceShape,
   const std::shared_ptr<GeomAPI_Shape>& theDestShape,
   bool theIsReverse,
-  bool theIsCentering)
+  bool theIsCentering,
+  bool theSimpleTransform)
 {
   // Filling the parameters of the objects
   static const int aNbObjects = 2;
@@ -188,27 +191,33 @@ void GeomAlgoAPI_Placement::build(
   gp_Vec aTrans = aDstLoc - aSrcLoc;
   aTrsf.SetTransformation(aRot, aTrans);
 
-  // Transform the shape with copying it
-  BRepBuilderAPI_Transform* aBuilder = new BRepBuilderAPI_Transform(aSourceShape, aTrsf, true);
-  if(aBuilder) {
-    setImpl(aBuilder);
-    myDone = aBuilder->IsDone() == Standard_True;
-    if (myDone) {
-      TopoDS_Shape aResult = aBuilder->Shape();
-      // fill data map to keep correct orientation of sub-shapes 
-      for (TopExp_Explorer Exp(aResult,TopAbs_FACE); Exp.More(); Exp.Next()) {
-        std::shared_ptr<GeomAPI_Shape> aCurrentShape(new GeomAPI_Shape());
-        aCurrentShape->setImpl(new TopoDS_Shape(Exp.Current()));
-        myMap.bind(aCurrentShape, aCurrentShape);
-      }
-#ifdef DEB_PLACEMENT
-      int aNum = myMap.size();
-      cout << "MAP of Oriented shapes =" << aNum <<endl;
+  if (theSimpleTransform) { // just add transformation
+    TopLoc_Location aDelta(aTrsf);
+    TopoDS_Shape aResult = aSourceShape.Moved(aDelta);
+    myShape->setImpl(new TopoDS_Shape(aResult));
+  } else { // internal rebuild of the shape
+    // Transform the shape with copying it
+    BRepBuilderAPI_Transform* aBuilder = new BRepBuilderAPI_Transform(aSourceShape, aTrsf, true);
+    if(aBuilder) {
+      setImpl(aBuilder);
+      myDone = aBuilder->IsDone() == Standard_True;
+      if (myDone) {
+        TopoDS_Shape aResult = aBuilder->Shape();
+        // fill data map to keep correct orientation of sub-shapes 
+        for (TopExp_Explorer Exp(aResult,TopAbs_FACE); Exp.More(); Exp.Next()) {
+          std::shared_ptr<GeomAPI_Shape> aCurrentShape(new GeomAPI_Shape());
+          aCurrentShape->setImpl(new TopoDS_Shape(Exp.Current()));
+          myMap.bind(aCurrentShape, aCurrentShape);
+        }
+  #ifdef DEB_PLACEMENT
+        int aNum = myMap.size();
+        cout << "MAP of Oriented shapes =" << aNum <<endl;
 
-#endif
+  #endif
 
-      myShape->setImpl(new TopoDS_Shape(aResult));
-      myMkShape = new GeomAlgoAPI_MakeShape (aBuilder);
+        myShape->setImpl(new TopoDS_Shape(aResult));
+        myMkShape = new GeomAlgoAPI_MakeShape (aBuilder);
+      }
     }
   }
 }
@@ -216,8 +225,11 @@ void GeomAlgoAPI_Placement::build(
 //============================================================================
 const bool GeomAlgoAPI_Placement::isValid() const
 {
-  BRepCheck_Analyzer aChecker(myShape->impl<TopoDS_Shape>());
-  return (aChecker.IsValid() == Standard_True);
+  if (myShape.get()) { // only for not-simple transform
+    BRepCheck_Analyzer aChecker(myShape->impl<TopoDS_Shape>());
+    return (aChecker.IsValid() == Standard_True);
+  }
+  return true;
 }
 
 //============================================================================
index 1e1e88e49c1e045a0fb968ce331dec0ec2b4ef95..9d8852b2f1efa40199adcc58869ee1e27b90f1cb 100644 (file)
@@ -30,13 +30,15 @@ public:
    *  \param[in] theDestShape    destination object
    *  \param[in] theIsReverse    indicates that the solid materials should be on the same side against the destination plane
    *  \param[in] theIsCentering  indicates the planes should be centered
+   *  \param[in] theSimpleTransform makes just transformation of shape without changing of topology or geometry
    */
   GEOMALGOAPI_EXPORT GeomAlgoAPI_Placement(std::shared_ptr<GeomAPI_Shape> theSourceSolid,
                                            std::shared_ptr<GeomAPI_Shape> theDestSolid,
                                            std::shared_ptr<GeomAPI_Shape> theSourceShape,
                                            std::shared_ptr<GeomAPI_Shape> theDestShape,
                                            bool theIsReverse = false,
-                                           bool theIsCentering = false);
+                                           bool theIsCentering = false,
+                                           bool theSimpleTransform = false);
 
   /// Returns True if algorithm succeed
   GEOMALGOAPI_EXPORT const bool isDone() const
@@ -67,7 +69,8 @@ private:
              const std::shared_ptr<GeomAPI_Shape>& theSourceShape,
              const std::shared_ptr<GeomAPI_Shape>& theDestShape,
              bool theIsReverse,
-             bool theIsCentering);
+             bool theIsCentering,
+             bool theSimpleTransform);
 
   /// fields
   bool myDone;
index 81c3ca6e334a4437cd96dd53cac39a819636df1b..21815311070d170e47f4c714519a95895bfec868 100644 (file)
 //=================================================================================================
 GeomAlgoAPI_Rotation::GeomAlgoAPI_Rotation(std::shared_ptr<GeomAPI_Shape> theSourceShape,
                                            std::shared_ptr<GeomAPI_Ax1>   theAxis,
-                                           double                         theAngle)
+                                           double                         theAngle,
+                                           bool theSimpleTransform)
 : myDone(false),
   myShape(new GeomAPI_Shape()),
   myMap(new GeomAPI_DataMapOfShapeShape()),
   myMkShape(new GeomAlgoAPI_MakeShape())
 {
-  build(theSourceShape, theAxis, theAngle);
+  build(theSourceShape, theAxis, theAngle, theSimpleTransform);
 }
 
 //=================================================================================================
 void GeomAlgoAPI_Rotation::build(std::shared_ptr<GeomAPI_Shape> theSourceShape,
                                  std::shared_ptr<GeomAPI_Ax1>   theAxis,
-                                 double                         theAngle)
+                                 double                         theAngle,
+                                 bool theSimpleTransform)
 {
   if(!theSourceShape || !theAxis) {
     return;
@@ -44,28 +46,35 @@ void GeomAlgoAPI_Rotation::build(std::shared_ptr<GeomAPI_Shape> theSourceShape,
   gp_Trsf aTrsf;
   aTrsf.SetRotation(anAxis, theAngle / 180.0 * M_PI);
 
+  TopoDS_Shape aResult;
   // Transform the shape with copying it.
-  BRepBuilderAPI_Transform* aBuilder = new BRepBuilderAPI_Transform(aSourceShape, aTrsf, true);
-  if(!aBuilder) {
-    return;
-  }
-
-  myDone = aBuilder->IsDone() == Standard_True;
-
-  if(!myDone) {
-    return;
-  }
-
-  TopoDS_Shape aResult = aBuilder->Shape();
-  // Fill data map to keep correct orientation of sub-shapes.
-  for(TopExp_Explorer anExp(aResult, TopAbs_FACE); anExp.More(); anExp.Next()) {
-    std::shared_ptr<GeomAPI_Shape> aCurrentShape(new GeomAPI_Shape());
-    aCurrentShape->setImpl(new TopoDS_Shape(anExp.Current()));
-    myMap->bind(aCurrentShape, aCurrentShape);
+  if (theSimpleTransform) {
+    TopLoc_Location aDelta(aTrsf);
+    aResult = aSourceShape.Moved(aDelta);
+    myDone = true; // is OK for sure
+  } else {
+    BRepBuilderAPI_Transform* aBuilder = new BRepBuilderAPI_Transform(aSourceShape, aTrsf, true);
+    if(!aBuilder) {
+      return;
+    }
+
+    myDone = aBuilder->IsDone() == Standard_True;
+
+    if(!myDone) {
+      return;
+    }
+
+    aResult = aBuilder->Shape();
+    // Fill data map to keep correct orientation of sub-shapes.
+    for(TopExp_Explorer anExp(aResult, TopAbs_FACE); anExp.More(); anExp.Next()) {
+      std::shared_ptr<GeomAPI_Shape> aCurrentShape(new GeomAPI_Shape());
+      aCurrentShape->setImpl(new TopoDS_Shape(anExp.Current()));
+      myMap->bind(aCurrentShape, aCurrentShape);
+    }
+    myMkShape->setImpl(aBuilder);
   }
 
   myShape->setImpl(new TopoDS_Shape(aResult));
-  myMkShape->setImpl(aBuilder);
 }
 
 //=================================================================================================
index c3a81d54edf62d691375d61eff66b5c9876510d4..5a44625a2e224a3909c7d651e56f2fb2b731852f 100644 (file)
@@ -24,10 +24,12 @@ public:
    *  \param[in] theSourceShape  a shape to be rotated.
    *  \param[in] theAxis         rotation axis.
    *  \param[in] theAngle        rotation angle(in degree).
+   *  \param[in] theSimpleTransform makes just transformation of shape without changing of topology or geometry
    */
   GEOMALGOAPI_EXPORT GeomAlgoAPI_Rotation(std::shared_ptr<GeomAPI_Shape> theSourceShape,
                                           std::shared_ptr<GeomAPI_Ax1>   theAxis,
-                                          double                         theAngle);
+                                          double                         theAngle,
+                                          bool theSimpleTransform = false);
 
   /// \return true if algorithm succeed.
   GEOMALGOAPI_EXPORT const bool isDone() const
@@ -52,7 +54,8 @@ private:
   /// Builds resulting shape.
   void build(std::shared_ptr<GeomAPI_Shape> theSourceShape,
              std::shared_ptr<GeomAPI_Ax1>   theAxis,
-             double                         theAngle);
+             double                         theAngle,
+             bool theSimpleTransform);
 
 private:
   /// Fields.
index df8ea041beeb781f618c5ce0de32a12f1105e2d4..864975b2e420376c6e57cdaf72d97e2de995c274 100644 (file)
@@ -73,7 +73,6 @@ Standard_GUID kPART_REF_ID("635eacb2-a1d6-4dec-8348-471fae17cb27");
 // TDataStd_IntPackedMap - indexes of edges in composite element (for construction)
 // TDataStd_Integer - type of the selected shape (for construction)
 // TDF_Reference - from ReferenceAttribute, the context
-#define DDDD 1
 void Model_AttributeSelection::setValue(const ResultPtr& theContext,
   const std::shared_ptr<GeomAPI_Shape>& theSubShape)
 {
@@ -137,13 +136,6 @@ void Model_AttributeSelection::setValue(const ResultPtr& theContext,
   std::string aSelName = namingName();
   if(!aSelName.empty())
     TDataStd_Name::Set(selectionLabel(), aSelName.c_str()); //set name
-#ifdef DDDD
-  //####
-  //selectSubShape("FACE",  "Extrusion_1/LateralFace_3");
-  //selectSubShape("FACE",  "Extrusion_1/TopFace");
-  //selectSubShape("EDGE", "Extrusion_1/TopFace|Extrusion_1/LateralFace_1");
-  //selectSubShape("EDGE", "Sketch_1/Edge_6");
-#endif
 }
 
 std::shared_ptr<GeomAPI_Shape> Model_AttributeSelection::value()
@@ -160,6 +152,22 @@ std::shared_ptr<GeomAPI_Shape> Model_AttributeSelection::value()
     if (aSelLab.IsAttribute(kCONSTUCTION_SIMPLE_REF_ID)) { // it is just reference to construction, nothing is in value
         return aResult; // empty result
     }
+    if (aSelLab.IsAttribute(kPART_REF_ID)) {
+      /* TODO: implement used text here
+      ResultPartPtr aPart = std::dynamic_pointer_cast<ModelAPI_ResultPart>(context());
+      if (!aPart.get() || !aPart->isActivated())
+        return std::shared_ptr<GeomAPI_Shape>(); // postponed naming needed
+      Handle(TDataStd_Integer) anIndex;
+      if (selectionLabel().FindAttribute(TDataStd_Integer::GetID(), anIndex)) {
+        return aPart->selectionValue(anIndex->Get());
+      }
+      Handle(TDataStd_Name) aName;
+      if (!selectionLabel().FindAttribute(TDataStd_Name::GetID(), aName)) {
+        return std::shared_ptr<GeomAPI_Shape>(); // something is wrong
+      }
+      return aPart->shapeInPart(TCollection_AsciiString(aName).ToCString());
+      */
+    }
 
     Handle(TNaming_NamedShape) aSelection;
     if (selectionLabel().FindAttribute(TNaming_NamedShape::GetID(), aSelection)) {
@@ -264,6 +272,11 @@ bool Model_AttributeSelection::update()
     return aContext->shape() && !aContext->shape()->isNull();
   }
 
+  if (aSelLab.IsAttribute(kPART_REF_ID)) { // it is reference to the part object
+    std::shared_ptr<GeomAPI_Shape> aNoSelection;
+    return selectPart(aContext, aNoSelection, true);
+  }
+
   if (aContext->groupName() == ModelAPI_ResultBody::group()) {
     // body: just a named shape, use selection mechanism from OCCT
     TNaming_Selector aSelector(aSelLab);
@@ -614,9 +627,25 @@ void Model_AttributeSelection::selectConstruction(
   registerSubShape(selectionLabel(), aSubShape, 0, aContextFeature, aMyDoc, "", aRefs);
 }
 
-void Model_AttributeSelection::selectPart(
-  const ResultPtr& theContext, const std::shared_ptr<GeomAPI_Shape>& theSubShape)
+bool Model_AttributeSelection::selectPart(
+  const ResultPtr& theContext, const std::shared_ptr<GeomAPI_Shape>& theSubShape,
+  const bool theUpdate)
 {
+  ResultPartPtr aPart = std::dynamic_pointer_cast<ModelAPI_ResultPart>(theContext);
+  if (!aPart.get() || !aPart->isActivated())
+    return true; // postponed naming
+  if (theUpdate) {
+    Handle(TDataStd_Integer) anIndex;
+    if (selectionLabel().FindAttribute(TDataStd_Integer::GetID(), anIndex)) { // by internal selection
+      if (anIndex->Get() > 0) {
+        // update the selection by index
+        return aPart->updateInPart(anIndex->Get());
+      } else {
+        return true; // nothing to do, referencing just by name
+      }
+    }
+    return true; // nothing to do, referencing just by name
+  }
   // store the shape (in case part is not loaded it should be usefull
   TopoDS_Shape aShape;
   std::string aName = theContext->data()->name();
@@ -624,13 +653,15 @@ void Model_AttributeSelection::selectPart(
     aShape = theContext->shape()->impl<TopoDS_Shape>();
   } else {
     aShape = theSubShape->impl<TopoDS_Shape>();
-    ResultPartPtr aPart = std::dynamic_pointer_cast<ModelAPI_ResultPart>(theContext);
-    aName += "/" + aPart->nameInPart(theSubShape);
+    int anIndex;
+    aName += "/" + aPart->nameInPart(theSubShape, anIndex);
+    TDataStd_Integer::Set(selectionLabel(), anIndex);
   }
   TNaming_Builder aBuilder(selectionLabel());
   aBuilder.Select(aShape, aShape);
   // identify by name in the part
   TDataStd_Name::Set(selectionLabel(), aName.c_str());
+  return !aName.empty();
 }
 
 TDF_Label Model_AttributeSelection::selectionLabel()
index 9e9213f8785a6838689f5bad8a4ddb181e2b0049..91e77e6e81f544da6c8372c21538aaa82e614c05 100644 (file)
@@ -69,8 +69,13 @@ protected:
     const ResultPtr& theContext, const std::shared_ptr<GeomAPI_Shape>& theSubShape);
 
   /// Performs the selection for the part result (selection by name of body result inside of part)
-  virtual void selectPart(
-    const ResultPtr& theContext, const std::shared_ptr<GeomAPI_Shape>& theSubShape);
+  /// \param theContext the result - owner of the selection
+  /// \param theSubShape selected shape
+  /// \param theUpdate flag that shows that it must be just update, theShape is null
+  /// \param returns true if eveything is selected correctly
+  virtual bool selectPart(
+    const ResultPtr& theContext, const std::shared_ptr<GeomAPI_Shape>& theSubShape,
+    const bool theUpdate = false);
 
   /// Returns the label where TNaming_Selection results are stored
   /// Note: there must be no attributes stored at the same label because Selector clears this lab
index 347a21820bcdf626163460c6593d4e3c1f77915a..29a9266a51ff31c74a7e42ad20b6f09c45704199 100644 (file)
@@ -502,3 +502,8 @@ std::shared_ptr<ModelAPI_Data> Model_Data::invalidData()
 {
   return kInvalid;
 }
+
+bool Model_Data::isOwner(ModelAPI_Object* theOwner)
+{
+  return theOwner == myObject.get();
+}
index 5e51c9d506e26316402676362a96689cc3be1876..1a502b4b0ca0f295b3f43c25c0aa4de06f2ea3a4 100644 (file)
@@ -200,6 +200,10 @@ class Model_Data : public ModelAPI_Data
   /// This method is called by the updater.
   MODEL_EXPORT virtual void setUpdateID(const int theID);
 
+  /// Returns true if the given object is owner of this data (needed for correct erase of object
+  /// with duplicated data)
+  MODEL_EXPORT virtual bool isOwner(ModelAPI_Object* theOwner);
+
 protected:
   /// Returns true if "is in history" custom behaviors is defined for the feature
   MODEL_EXPORT virtual bool isInHistory();
index 1c61d4f7c1047ebb53f5e53c48de7556fec1b505..1cdd0bcf190a588d4d80b35d49c42ead042b2adf 100644 (file)
@@ -13,6 +13,7 @@
 #include <ModelAPI_ResultPart.h>
 #include <ModelAPI_Validator.h>
 #include <ModelAPI_CompositeFeature.h>
+#include <ModelAPI_AttributeSelectionList.h>
 
 #include <Events_Loop.h>
 #include <Events_Error.h>
@@ -47,6 +48,7 @@ static const int TAG_GENERAL = 1;  // general properties tag
 // general sub-labels
 static const int TAG_CURRENT_FEATURE = 1; ///< where the reference to the current feature label is located (or no attribute if null feature)
 static const int TAG_CURRENT_TRANSACTION = 2; ///< integer, index of the cransaction
+static const int TAG_SELECTION_FEATURE = 3; ///< integer, tag of the selection feature label
 
 Model_Document::Model_Document(const std::string theID, const std::string theKind)
     : myID(theID), myKind(theKind), myIsActive(false),
@@ -274,6 +276,7 @@ void Model_Document::close(const bool theForever)
     myObjs = 0;
     if (myDoc->CanClose() == CDM_CCS_OK)
       myDoc->Close();
+    mySelectionFeature.reset();
   } else {
     setCurrentFeature(FeaturePtr(), false); // disables all features
   }
@@ -801,6 +804,14 @@ std::shared_ptr<ModelAPI_ResultPart> Model_Document::createPart(
   return myObjs->createPart(theFeatureData, theIndex);
 }
 
+std::shared_ptr<ModelAPI_ResultPart> Model_Document::copyPart(
+      const std::shared_ptr<ModelAPI_Result>& theOldPart, 
+      const std::shared_ptr<ModelAPI_ResultPart>& theOrigin, 
+      const int theIndex)
+{
+  return myObjs->copyPart(theOldPart, theOrigin, theIndex);
+}
+
 std::shared_ptr<ModelAPI_ResultGroup> Model_Document::createGroup(
     const std::shared_ptr<ModelAPI_Data>& theFeatureData, const int theIndex)
 {
@@ -919,3 +930,45 @@ std::shared_ptr<ModelAPI_Feature> Model_Document::internalFeature(const int theI
 {
   return myObjs->internalFeature(theIndex);
 }
+
+// Feature that is used for selection in the Part document by the external request
+class Model_SelectionInPartFeature : public ModelAPI_Feature {
+public:
+  /// Nothing to do in constructor
+  Model_SelectionInPartFeature() : ModelAPI_Feature() {}
+
+  /// Returns the unique kind of a feature
+  virtual const std::string& getKind() {
+    static std::string MY_KIND("InternalSelectionInPartFeature");
+    return MY_KIND;
+  }
+  /// Request for initialization of data model of the object: adding all attributes
+  virtual void initAttributes() {
+    data()->addAttribute("selection", ModelAPI_AttributeSelectionList::typeId());
+  }
+  /// Nothing to do in the execution function
+  virtual void execute() {}
+
+};
+
+//! Returns the feature that is used for calculation of selection externally from the document
+AttributeSelectionListPtr Model_Document::selectionInPartFeature()
+{
+  // return already created, otherwise create
+  if (!mySelectionFeature.get() || !mySelectionFeature->data()->isValid()) {
+    // create a new one
+    mySelectionFeature = FeaturePtr(new Model_SelectionInPartFeature);
+  
+    TDF_Label aFeatureLab = generalLabel().FindChild(TAG_SELECTION_FEATURE);
+    std::shared_ptr<Model_Data> aData(new Model_Data);
+    aData->setLabel(aFeatureLab.FindChild(1));
+    aData->setObject(mySelectionFeature);
+    mySelectionFeature->setDoc(myObjs->owner());
+    mySelectionFeature->setData(aData);
+    std::string aName = id() + "_Part";
+    mySelectionFeature->data()->setName(aName);
+    mySelectionFeature->setDoc(myObjs->owner());
+    mySelectionFeature->initAttributes();
+  }
+  return mySelectionFeature->selectionList("selection");
+}
index 70cfcf6189ab71e0d46ec3fd81be246e29f7e66a..7c757ce074144faef0d53d71ff290feededaca5c 100644 (file)
@@ -19,6 +19,7 @@
 
 class Handle_Model_Document;
 class Model_Objects;
+class ModelAPI_AttributeSelectionList;
 
 /**\class Model_Document
  * \ingroup DataModel
@@ -153,6 +154,11 @@ class Model_Document : public ModelAPI_Document
   /// Creates a part results
   MODEL_EXPORT virtual std::shared_ptr<ModelAPI_ResultPart> createPart(
       const std::shared_ptr<ModelAPI_Data>& theFeatureData, const int theIndex = 0);
+  //! Copies a part result, keeping the same data
+  MODEL_EXPORT virtual std::shared_ptr<ModelAPI_ResultPart> copyPart(
+      const std::shared_ptr<ModelAPI_Result>& theOldPart, 
+      const std::shared_ptr<ModelAPI_ResultPart>& theOrigin, 
+      const int theIndex = 0);
   /// Creates a group results
   MODEL_EXPORT virtual std::shared_ptr<ModelAPI_ResultGroup> createGroup(
       const std::shared_ptr<ModelAPI_Data>& theFeatureData, const int theIndex = 0);
@@ -241,6 +247,9 @@ class Model_Document : public ModelAPI_Document
   //! Returns true if this document is currently active
   virtual bool isActive() const;
 
+  //! Returns the selection attribute that is used for calculation of selection externally from the document
+  std::shared_ptr<ModelAPI_AttributeSelectionList> selectionInPartFeature();
+
   friend class Model_Application;
   friend class Model_Session;
   friend class Model_Update;
@@ -283,6 +292,9 @@ class Model_Document : public ModelAPI_Document
   bool myExecuteFeatures;
 
   bool myIsActive; ///< flag that stores the active/not active state
+
+  //! The selection feature, if needed
+  FeaturePtr mySelectionFeature;
 };
 
 #endif
index 1acc948065e3f26542a67dafc4bbff72bc499c2c..0eab9cf32f8d988b05dc0c321e01f80cbfa253bb 100644 (file)
@@ -774,6 +774,22 @@ std::shared_ptr<ModelAPI_ResultPart> Model_Objects::createPart(
   return aResult;
 }
 
+std::shared_ptr<ModelAPI_ResultPart> Model_Objects::copyPart(
+    const std::shared_ptr<ModelAPI_Result>& theOldPart, 
+    const std::shared_ptr<ModelAPI_ResultPart>& theOrigin, const int theIndex)
+{
+  std::shared_ptr<ModelAPI_ResultPart> aResult;
+  if (theOldPart.get()) {
+    aResult = std::dynamic_pointer_cast<ModelAPI_ResultPart>(theOldPart);
+  }
+  if (!aResult) {
+    aResult = std::shared_ptr<ModelAPI_ResultPart>(new Model_ResultPart);
+    aResult->setDoc(myDoc);
+    aResult->setData(theOrigin->data());
+  }
+  return aResult;
+}
+
 std::shared_ptr<ModelAPI_ResultGroup> Model_Objects::createGroup(
     const std::shared_ptr<ModelAPI_Data>& theFeatureData, const int theIndex)
 {
index 52df4520097e57b15770b8137f0c9d5281b5ad61..ec81a9f6ad1cbfaf9352fa7df0ba4957065bb2a1 100644 (file)
@@ -103,6 +103,10 @@ class Model_Objects
   /// Creates a part results
   std::shared_ptr<ModelAPI_ResultPart> createPart(
       const std::shared_ptr<ModelAPI_Data>& theFeatureData, const int theIndex = 0);
+  /// Copies a part results, keeping the same data
+  std::shared_ptr<ModelAPI_ResultPart> copyPart(
+      const std::shared_ptr<ModelAPI_Result>& theOldPart, 
+      const std::shared_ptr<ModelAPI_ResultPart>& theOrigin, const int theIndex = 0);
   /// Creates a group results
   std::shared_ptr<ModelAPI_ResultGroup> createGroup(
       const std::shared_ptr<ModelAPI_Data>& theFeatureData, const int theIndex = 0);
index 87552e36225d42503329285da811d413344b4977..5023340b1b5f8f6a08a712b665966a4e20921e9d 100644 (file)
@@ -6,12 +6,16 @@
 
 #include <Model_ResultPart.h>
 #include <ModelAPI_Data.h>
+#include <Model_Data.h>
 #include <ModelAPI_AttributeDocRef.h>
 #include <ModelAPI_Session.h>
 #include <ModelAPI_Feature.h>
 #include <ModelAPI_ResultBody.h>
 #include <ModelAPI_AttributeIntArray.h>
+#include <ModelAPI_AttributeSelectionList.h>
 #include <Model_Document.h>
+#include <Events_Loop.h>
+#include <ModelAPI_Events.h>
 
 #include <TNaming_Tool.hxx>
 #include <TNaming_NamedShape.hxx>
@@ -19,6 +23,7 @@
 #include <TDataStd_Name.hxx>
 #include <TopoDS_Compound.hxx>
 #include <BRep_Builder.hxx>
+#include <TopExp_Explorer.hxx>
 
 void Model_ResultPart::initAttributes()
 {
@@ -135,9 +140,34 @@ std::shared_ptr<GeomAPI_Shape> Model_ResultPart::shape()
   return aResult;
 }
 
-std::string Model_ResultPart::nameInPart(const std::shared_ptr<GeomAPI_Shape>& theShape)
+std::string Model_ResultPart::nameInPart(const std::shared_ptr<GeomAPI_Shape>& theShape,
+  int& theIndex)
 {
+  theIndex = 0; // not initialized
   TopoDS_Shape aShape = theShape->impl<TopoDS_Shape>();
+  if (aShape.IsNull())
+    return "";
+  if (data()->isOwner(this)) { // if this is moved copy of part => return the name of original shape
+    FeaturePtr anOrigFeature = 
+      std::dynamic_pointer_cast<ModelAPI_Feature>(data()->attribute(COLOR_ID())->owner());
+    if (anOrigFeature.get()) {
+      if (anOrigFeature->firstResult().get() && anOrigFeature->firstResult()->shape().get()) {
+        TopoDS_Shape anOrigShape = anOrigFeature->firstResult()->shape()->impl<TopoDS_Shape>();
+        if (!anOrigShape.IsNull()) {
+          TopExp_Explorer anExp(anOrigShape, aShape.ShapeType());
+          for(; anExp.More(); anExp.Next()) {
+            if (aShape.IsPartner(anExp.Current())) {
+              std::shared_ptr<GeomAPI_Shape> anOrigGeomShape(new GeomAPI_Shape);
+              anOrigGeomShape->setImpl(new TopoDS_Shape(anExp.Current()));
+
+              return std::dynamic_pointer_cast<Model_ResultPart>(anOrigFeature->firstResult())->
+                nameInPart(theShape, theIndex);
+            }
+          }
+        }
+      }
+    }
+  }
   // getting an access to the document of part
   std::shared_ptr<Model_Document> aDoc = std::dynamic_pointer_cast<Model_Document>(partDoc());
   if (!aDoc.get()) // the part document is not presented for the moment
@@ -166,9 +196,47 @@ std::string Model_ResultPart::nameInPart(const std::shared_ptr<GeomAPI_Shape>& t
       }        
     }
   }
+  if (aName.empty()) { // not found, so use the selection mechanism
+    // for this the context result is needed
+    ResultPtr aContext;
+    const std::string& aBodyGroup = ModelAPI_ResultBody::group();
+    for(int a = aDoc->size(aBodyGroup) - 1; a >= 0; a--) {
+      ResultPtr aBody = std::dynamic_pointer_cast<ModelAPI_Result>(aDoc->object(aBodyGroup, a));
+      if (aBody.get() && aBody->shape().get() && !aBody->isDisabled()) {
+        TopoDS_Shape aBodyShape = *(aBody->shape()->implPtr<TopoDS_Shape>());
+        // check is body contain the selected sub-shape
+        for(TopExp_Explorer anExp(aBodyShape, aShape.ShapeType()); anExp.More(); anExp.Next()) {
+          if (aShape.IsEqual(anExp.Current())) {
+            aContext = aBody;
+            break;
+          }
+        }
+      }
+    }
+    if (aContext.get()) {
+      AttributeSelectionListPtr aSelAttr = aDoc->selectionInPartFeature();
+      aSelAttr->append(aContext, theShape);
+      theIndex = aSelAttr->size();
+      AttributeSelectionPtr aNewAttr = aSelAttr->value(theIndex - 1);
+      return aNewAttr->namingName();
+    }
+  }
   return aName;
 }
 
+bool Model_ResultPart::updateInPart(const int theIndex)
+{
+  std::shared_ptr<Model_Document> aDoc = std::dynamic_pointer_cast<Model_Document>(partDoc());
+  if (aDoc.get()) {
+    AttributeSelectionListPtr aSelAttr = aDoc->selectionInPartFeature();
+    AttributeSelectionPtr aThisAttr = aSelAttr->value(theIndex - 1);
+    if (aThisAttr.get()) {
+      return aThisAttr->update();
+    }
+  }
+  return false; // something is wrong
+}
+
 std::shared_ptr<GeomAPI_Shape> Model_ResultPart::shapeInPart(const std::string& theName)
 {
   /// TODO: not implemented yet
@@ -188,3 +256,13 @@ void Model_ResultPart::updateShape()
 {
   myShape.Nullify();
 }
+
+void Model_ResultPart::setShape(std::shared_ptr<ModelAPI_Result> theThis, 
+    const std::shared_ptr<GeomAPI_Shape>& theTransformed)
+{
+  myShape = theTransformed->impl<TopoDS_Shape>();
+  // the result must be explicitly updated
+  static Events_Loop* aLoop = Events_Loop::loop();
+  static Events_ID EVENT_DISP = aLoop->eventByName(EVENT_OBJECT_TO_REDISPLAY);
+  ModelAPI_EventCreator::get()->sendUpdated(theThis, EVENT_DISP); // flush is in preview-update
+}
index 06c6efdad373c38337b19766a1576804edbfd3fa..1f4ca4946f8d6ee6de67f13b002cf48658c351ea 100644 (file)
@@ -40,11 +40,20 @@ class Model_ResultPart : public ModelAPI_ResultPart
   MODEL_EXPORT virtual std::shared_ptr<GeomAPI_Shape> shape();
 
   /// Returns the name of the shape inside of the part
-  MODEL_EXPORT virtual std::string nameInPart(const std::shared_ptr<GeomAPI_Shape>& theShape);
+  /// \param theShape selected shape in this document
+  /// \param theIndex is returned as one-based index if selection was required, "0" otherwise
+  /// \returns empty name is selection is not correct
+  MODEL_EXPORT virtual std::string nameInPart(const std::shared_ptr<GeomAPI_Shape>& theShape,
+    int& theIndex);
+
+  /// Updates the selection inside of the part by the selection index
+  MODEL_EXPORT virtual bool updateInPart(const int theIndex);
   /// Returns the shape by the name in the part
   MODEL_EXPORT virtual std::shared_ptr<GeomAPI_Shape> shapeInPart(const std::string& theName);
   /// Updates the shape-result of the part (called on Part feature execution)
   MODEL_EXPORT virtual void updateShape();
+  MODEL_EXPORT virtual void setShape(std::shared_ptr<ModelAPI_Result> theThis, 
+    const std::shared_ptr<GeomAPI_Shape>& theTransformed);
 
   /// Returns the parameters of color definition in the resources config manager
   MODEL_EXPORT virtual void colorConfigInfo(std::string& theSection, std::string& theName,
index 1e5bb3fed0a9da0e32f878ab40d0cbbddff24fbc..3262812a5f6beaf1cb61dd446bed284fee3ff75f 100644 (file)
@@ -238,17 +238,37 @@ void Model_Update::updateFeature(FeaturePtr theFeature, std::set<FeaturePtr>& th
   if (myIsAutomatic && theFeature->data()->execState() == ModelAPI_StateMustBeUpdated)
     aJustUpdated = true;
 
+  // On abort, undo or redo execute is not needed: results in document are updated automatically
+  // But redisplay is needed: results are updated, must be also updated in the viewer.
+  if (aJustUpdated && 
+      !std::dynamic_pointer_cast<Model_Document>(theFeature->document())->executeFeatures()) {
+    if (!theFeature->isPersistentResult()) { // not persistent must be re-executed on abort, etc.
+      ModelAPI_ExecState aState = theFeature->data()->execState();
+      if (aFactory->validate(theFeature)) {
+        executeFeature(theFeature);
+      } else {
+        theFeature->eraseResults();
+        redisplayWithResults(theFeature, ModelAPI_StateInvalidArgument); // result also must be updated
+      }
+    } else {
+      redisplayWithResults(theFeature, ModelAPI_StateNothing);
+      if (theFeature->data()->execState() == ModelAPI_StateMustBeUpdated) { // it is done (in the tree)
+        theFeature->data()->execState(ModelAPI_StateDone);
+      }
+    }
+    return;
+  }
+
   // execute feature if it must be updated
   if (theFeature->isPreviewNeeded() || myIsFinish) {
-    if (aJustUpdated &&
-      std::dynamic_pointer_cast<Model_Document>(theFeature->document())->executeFeatures()) {
-        ModelAPI_ExecState aState = theFeature->data()->execState();
-        if (aFactory->validate(theFeature)) {
-          executeFeature(theFeature);
-        } else {
-          theFeature->eraseResults();
-          redisplayWithResults(theFeature, ModelAPI_StateInvalidArgument); // result also must be updated
-        }
+    if (aJustUpdated) {
+      ModelAPI_ExecState aState = theFeature->data()->execState();
+      if (aFactory->validate(theFeature)) {
+        executeFeature(theFeature);
+      } else {
+        theFeature->eraseResults();
+        redisplayWithResults(theFeature, ModelAPI_StateInvalidArgument); // result also must be updated
+      }
     }
   } else { // preview is not needed => make state Done
     if (theFeature->data()->execState() == ModelAPI_StateMustBeUpdated) {
index 5f2a841785ae112251131f4231d1aab47e84ecb4..692cc088180d9d38797358abfec81e192c3ba916 100644 (file)
@@ -38,7 +38,7 @@
   #include "ModelAPI_ResultParameter.h"
   #include "ModelAPI_ResultGroup.h"
   #include "ModelAPI_Tools.h"
-
+  
   #include <memory>
   #include <string>
   
index 0cd4631e60849c3a87bbdc1ce0467707a77c77ce..dfc6ee32af3359791efbc29ccb5ca74c278bd27d 100644 (file)
@@ -154,6 +154,10 @@ class MODELAPI_EXPORT ModelAPI_Data
   /// This method is called by the updater.
   virtual void setUpdateID(const int theID) = 0;
 
+  /// Returns true if the given object is owner of this data (needed for correct erase of object
+  /// with duplicated data)
+  virtual bool isOwner(ModelAPI_Object* theOwner) = 0;
+
  protected:
   /// Objects are created for features automatically
   ModelAPI_Data();
index 4c06461fac45ac6384b899bb1d8f36eb728e968b..9f9297001404e35710b7202ba6b5be1b1520c385 100644 (file)
@@ -124,6 +124,11 @@ public:
   //! Creates a part results
   virtual std::shared_ptr<ModelAPI_ResultPart> createPart(
       const std::shared_ptr<ModelAPI_Data>& theFeatureData, const int theIndex = 0) = 0;
+  //! Copies a part result, keeping the same data
+  virtual std::shared_ptr<ModelAPI_ResultPart> copyPart(
+      const std::shared_ptr<ModelAPI_Result>& theOldPart, 
+      const std::shared_ptr<ModelAPI_ResultPart>& theOrigin, 
+      const int theIndex = 0) = 0;
   //! Creates a group results
   virtual std::shared_ptr<ModelAPI_ResultGroup> createGroup(
       const std::shared_ptr<ModelAPI_Data>& theFeatureData, const int theIndex = 0) = 0;
index dc76a0792dd2d925653ae077e039dc740bce4ec9..9d08a0c3719c3bf8338acdc3b61887ef6c1ee3f5 100644 (file)
@@ -68,7 +68,8 @@ void ModelAPI_Object::setDoc(std::shared_ptr<ModelAPI_Document> theDoc)
 
 void ModelAPI_Object::erase()
 {
-  if (myData->isValid() && myData != myData->invalidPtr()) myData->erase();
+  if (myData->isValid() && myData != myData->invalidPtr() && myData->isOwner(this))
+    myData->erase();
   setData(myData->invalidPtr());
 }
 
index 9d1d04c395f3cfb593370a51ee38a11cd12f2311..fd54a5f2d9f8215ccc95e334a39260c404532011 100644 (file)
@@ -86,6 +86,7 @@ class ModelAPI_Object
   MODELAPI_EXPORT virtual void erase();
 
   friend class Model_Objects;
+  friend class Model_Document;
 
 };
 
index 1816c54d990c9392093afc6958decc215000bf3c..25b97c3a92a98c778a660327c3099fac00e11e78 100644 (file)
@@ -41,6 +41,11 @@ bool ModelAPI_Result::isDisabled() const
   return myIsDisabled;
 }
 
+bool ModelAPI_Result::isConcealed()
+{
+  return myIsConcealed;
+}
+
 void ModelAPI_Result::setIsConcealed(const bool theValue)
 {
   if (myIsConcealed != theValue) {
index 9889e4884d9944dde366728da5b833c9d2ec6702..7922612c68f203e139c9011f9f8aef5161d87bf1 100644 (file)
@@ -35,10 +35,7 @@ class ModelAPI_Result : public ModelAPI_Object
   }
 
   /// Returns true if the result is concealed from the data tree (referenced by other objects)
-  inline bool isConcealed()
-  {
-    return myIsConcealed;
-  }
+  MODELAPI_EXPORT virtual bool isConcealed();
 
   /// Returns true if the result is concealed from the data tree (referenced by other objects)
   MODELAPI_EXPORT void setIsConcealed(const bool theValue);
index 9790051d7d3b7511d6f075452b9eeea9e1e93216..3639c47b1c8c9f5b49958dea7204cc22e83201c5 100644 (file)
@@ -12,3 +12,9 @@ std::string ModelAPI_ResultPart::groupName()
 {
   return ModelAPI_ResultPart::group();
 }
+
+bool ModelAPI_ResultPart::isConcealed()
+{
+  //return false;
+  return ModelAPI_Result::isConcealed(); // the way with different results is applied
+}
index 74d86953f84129e36779bf386484769ac2ab2d4b..6d23fe38bef49da9c51c605f5b27ad8f67faca49 100644 (file)
@@ -45,6 +45,9 @@ class ModelAPI_ResultPart : public ModelAPI_Result
     return RESULT_BODY_COLOR;
   }
 
+  // Part result can not be cencealed, even by the movement features
+  MODELAPI_EXPORT virtual bool isConcealed();
+
   /// Returns the part-document of this result
   virtual std::shared_ptr<ModelAPI_Document> partDoc() = 0;
 
@@ -55,7 +58,15 @@ class ModelAPI_ResultPart : public ModelAPI_Result
   virtual bool isActivated() = 0;
 
   /// Returns the name of the shape inside of the part
-  virtual std::string nameInPart(const std::shared_ptr<GeomAPI_Shape>& theShape) = 0;
+  virtual std::string nameInPart(const std::shared_ptr<GeomAPI_Shape>& theShape,
+    int& theIndex) = 0;
+  /// Updates the selection inside of the part by the selection index
+  virtual bool updateInPart(const int theIndex) = 0;
+
+  /// Applies the additional transformation ofthe part
+  virtual void setShape(std::shared_ptr<ModelAPI_Result> theThis, 
+    const std::shared_ptr<GeomAPI_Shape>& theTransformed) = 0;
+
   /// Returns the shape by the name in the part
   virtual std::shared_ptr<GeomAPI_Shape> shapeInPart(const std::string& theName) = 0;
   /// Updates the shape-result of the part (called on Part feature execution)