Salome HOME
Moving features to a folder has been implemented (Task 2.3. Ability to put consecutiv...
[modules/shaper.git] / src / Model / Model_AttributeSelection.cpp
index 344ee30ee36009e59b2dea139d2c2b92d3b907ac..c29cca22998cc6c335de633a089f0a77f9eb0baa 100644 (file)
@@ -90,25 +90,26 @@ Standard_GUID kELLIPSE_CENTER2("1395ae73-8e02-4cf8-b204-06ff35873a32");
 // 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
-void Model_AttributeSelection::setValue(const ResultPtr& theContext,
+bool Model_AttributeSelection::setValue(const ResultPtr& theContext,
   const std::shared_ptr<GeomAPI_Shape>& theSubShape, const bool theTemporarily)
 {
   if (theTemporarily) { // just keep the stored without DF update
     myTmpContext = theContext;
     myTmpSubShape = theSubShape;
     owner()->data()->sendAttributeUpdated(this);
-    return;
+    return true;
   } else {
     myTmpContext.reset();
     myTmpSubShape.reset();
     myTmpCenterType = NOT_CENTER;
   }
 
-  const std::shared_ptr<GeomAPI_Shape>& anOldShape = value();
+  CenterType aType;
+  const std::shared_ptr<GeomAPI_Shape>& anOldShape = internalValue(aType);
   bool isOldContext = theContext == myRef.value();
   bool isOldShape = isOldContext &&
     (theSubShape == anOldShape || (theSubShape && anOldShape && theSubShape->isEqual(anOldShape)));
-  if (isOldShape) return; // shape is the same, so context is also unchanged
+  if (isOldShape) return false; // shape is the same, so context is also unchanged
   // update the referenced object if needed
   if (!isOldContext) {
       myRef.setValue(theContext);
@@ -134,7 +135,7 @@ void Model_AttributeSelection::setValue(const ResultPtr& theContext,
     TDF_Label aRefLab = myRef.myRef->Label();
     aSelLab.ForgetAllAttributes(true);
     myRef.myRef = TDF_Reference::Set(aSelLab.Father(), aSelLab.Father());
-    return;
+    return false;
   }
   if (theContext->groupName() == ModelAPI_ResultBody::group()) {
     // do not select the whole shape for body:it is already must be in the data framework
@@ -153,6 +154,12 @@ void Model_AttributeSelection::setValue(const ResultPtr& theContext,
     std::shared_ptr<GeomAPI_Shape> aSubShape;
     if (theSubShape.get() && !theContext->shape()->isEqual(theSubShape))
       aSubShape = theSubShape; // the whole context
+    if (aConstruction->isInfinite()) {
+      // For correct naming selection, put the shape into the naming structure.
+      // It seems sub-shapes are not needed: only this shape is (and can be ) selected.
+      TNaming_Builder aBuilder(aSelLab);
+      aBuilder.Generated(theContext->shape()->impl<TopoDS_Shape>());
+    }
     int anIndex = aConstruction->select(theSubShape, owner()->document());
     TDataStd_Integer::Set(aSelLab, anIndex);
   } else if (theContext->groupName() == ModelAPI_ResultPart::group()) {
@@ -162,32 +169,54 @@ void Model_AttributeSelection::setValue(const ResultPtr& theContext,
   }
 
   owner()->data()->sendAttributeUpdated(this);
+  return true;
 }
 
 void Model_AttributeSelection::setValueCenter(
     const ResultPtr& theContext, const std::shared_ptr<GeomAPI_Edge>& theEdge,
     const CenterType theCenterType, const bool theTemporarily)
 {
-  setValue(theContext, theEdge, theTemporarily);
+  bool anUpdated = setValue(theContext, theEdge, theTemporarily);
   if (theTemporarily) {
     myTmpCenterType = theCenterType;
   } else { // store in the data structure
     TDF_Label aSelLab = selectionLabel();
     switch(theCenterType) {
     case CIRCLE_CENTER:
+      if (!anUpdated)
+        anUpdated = !aSelLab.IsAttribute(kCIRCLE_CENTER);
       TDataStd_UAttribute::Set(aSelLab, kCIRCLE_CENTER);
       break;
     case ELLIPSE_FIRST_FOCUS:
+      if (!anUpdated)
+        anUpdated = !aSelLab.IsAttribute(kELLIPSE_CENTER1);
       TDataStd_UAttribute::Set(aSelLab, kELLIPSE_CENTER1);
       break;
     case ELLIPSE_SECOND_FOCUS:
+      if (!anUpdated)
+        anUpdated = !aSelLab.IsAttribute(kELLIPSE_CENTER2);
       TDataStd_UAttribute::Set(aSelLab, kELLIPSE_CENTER2);
       break;
     }
-    owner()->data()->sendAttributeUpdated(this);
+    if (anUpdated)
+      owner()->data()->sendAttributeUpdated(this);
   }
 }
 
+void Model_AttributeSelection::selectValue(
+    const std::shared_ptr<ModelAPI_AttributeSelection>& theSource)
+{
+  CenterType aType;
+  std::shared_ptr<GeomAPI_Shape> aValue =
+    std::dynamic_pointer_cast<Model_AttributeSelection>(theSource)->internalValue(aType);
+  if (!aValue.get() || aType == NOT_CENTER) {
+    setValue(theSource->context(), aValue);
+  } else {
+    std::shared_ptr<GeomAPI_Edge> anEdge(new GeomAPI_Edge);
+    anEdge->setImpl(new TopoDS_Shape(aValue->impl<TopoDS_Shape>()));
+    setValueCenter(theSource->context(), anEdge, aType);
+  }
+}
 
 void Model_AttributeSelection::removeTemporaryValues()
 {
@@ -298,21 +327,23 @@ std::shared_ptr<GeomAPI_Shape> Model_AttributeSelection::internalValue(CenterTyp
       }
     }
 
+    std::shared_ptr<Model_ResultConstruction> aConstr =
+      std::dynamic_pointer_cast<Model_ResultConstruction>(context());
+    if (aConstr) {
+      if (aConstr->isInfinite())
+        return aResult; // empty result
+    }
     Handle(TNaming_NamedShape) aSelection;
     if (aSelLab.FindAttribute(TNaming_NamedShape::GetID(), aSelection)) {
       TopoDS_Shape aSelShape = aSelection->Get();
       aResult = std::shared_ptr<GeomAPI_Shape>(new GeomAPI_Shape);
       aResult->setImpl(new TopoDS_Shape(aSelShape));
-    } else { // for simple construction element: just shape of this construction element
-      std::shared_ptr<Model_ResultConstruction> aConstr =
-        std::dynamic_pointer_cast<Model_ResultConstruction>(context());
-      if (aConstr) {
-        Handle(TDataStd_Integer) anIndex;
-        if (aSelLab.FindAttribute(TDataStd_Integer::GetID(), anIndex)) {
-          if (anIndex->Get() == 0) // it is just reference to construction, nothing is in value
-            return aResult;
-          return aConstr->shape(anIndex->Get(), owner()->document());
-        }
+    } else if (aConstr) { // simple construction element: just shape of this construction element
+      Handle(TDataStd_Integer) anIndex;
+      if (aSelLab.FindAttribute(TDataStd_Integer::GetID(), anIndex)) {
+        if (anIndex->Get() == 0) // it is just reference to construction, nothing is in value
+          return aResult;
+        return aConstr->shape(anIndex->Get(), owner()->document());
       }
     }
   }
@@ -552,6 +583,11 @@ bool Model_AttributeSelection::update()
       bool aModified = true;
       bool aValid = aConstructionContext->update(anIndex->Get(), owner()->document(), aModified);
       setInvalidIfFalse(aSelLab, aValid);
+      if (aConstructionContext->isInfinite()) {
+        // Update the selected shape.
+        TNaming_Builder aBuilder(aSelLab);
+        aBuilder.Generated(aConstructionContext->shape()->impl<TopoDS_Shape>());
+      }
       if (aModified)
         owner()->data()->sendAttributeUpdated(this);
       return aValid;