Salome HOME
Fix for the issue #2808 : Documentation on the "Groups" panel. Added description...
[modules/shaper.git] / src / Model / Model_AttributeSelection.cpp
index b58e29461ef82fdd19d35a937feafab6803b77c8..5b382b22100a121cc88f7ba40c9777ad6cdb37d2 100644 (file)
@@ -178,18 +178,6 @@ bool Model_AttributeSelection::setValue(const ObjectPtr& theContext,
     std::shared_ptr<GeomAPI_Shape> aSubShape;
     if (theSubShape.get() && !aConstruction->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(aConstruction->shape()->impl<TopoDS_Shape>());
-      std::string anInfinitiveName = contextName(aConstruction);
-      TDataStd_Name::Set(aSelLab, anInfinitiveName.c_str());
-      std::dynamic_pointer_cast<Model_Document>(owner()->document())
-        ->addNamingName(aSelLab, anInfinitiveName.c_str());
-        */
-    }
   } else if (theContext->groupName() == ModelAPI_ResultPart::group()) {
     aSelLab.ForgetAllAttributes(true);
     TDataStd_UAttribute::Set(aSelLab, kPART_REF_ID);
@@ -592,16 +580,10 @@ bool Model_AttributeSelection::update()
     if (aSelLab.FindAttribute(TNaming_NamedShape::GetID(), aNS))
       anOldShape = aNS->Get();
 
-    Selector_Selector aSelector(aSelLab);
-    if (ModelAPI_Session::get()->moduleDocument() != owner()->document()) {
-      aSelector.setBaseDocument(std::dynamic_pointer_cast<Model_Document>
-        (ModelAPI_Session::get()->moduleDocument())->extConstructionsLabel());
-    }
-    if (aSelector.restore()) { // it is stored in old OCCT format, use TNaming_Selector
-      TopoDS_Shape aContextShape = aContext->shape()->impl<TopoDS_Shape>();
-      aResult = aSelector.solve(aContextShape);
-    }
-    aResult = setInvalidIfFalse(aSelLab, aResult);
+    TopoDS_Shape aContextShape = aContext->shape()->impl<TopoDS_Shape>();
+    Selector_Selector aSelector(aSelLab, baseDocumentLab());
+    aResult = aSelector.restore(aContextShape);
+    setInvalidIfFalse(aSelLab, aResult);
 
     TopoDS_Shape aNewShape;
     if (aSelLab.FindAttribute(TNaming_NamedShape::GetID(), aNS))
@@ -625,19 +607,11 @@ bool Model_AttributeSelection::update()
     std::shared_ptr<Model_ResultConstruction> aConstructionContext =
       std::dynamic_pointer_cast<Model_ResultConstruction>(aContext);
     if (!aConstructionContext->isInfinite()) {
-      Selector_Selector aSelector(aSelLab);
-      if (ModelAPI_Session::get()->moduleDocument() != owner()->document()) {
-        aSelector.setBaseDocument(std::dynamic_pointer_cast<Model_Document>
-          (ModelAPI_Session::get()->moduleDocument())->extConstructionsLabel());
-      }
-
-      aResult = aSelector.restore();
+      TopoDS_Shape aContextShape = aContext->shape()->impl<TopoDS_Shape>();
+      Selector_Selector aSelector(aSelLab, baseDocumentLab());
       TopoDS_Shape anOldShape = aSelector.value();
-      if (aResult) {
-        TopoDS_Shape aContextShape = aContext->shape()->impl<TopoDS_Shape>();
-        aResult = aSelector.solve(aContextShape);
-      }
-      aResult = setInvalidIfFalse(aSelLab, aResult);
+      aResult = aSelector.restore(aContextShape);
+      setInvalidIfFalse(aSelLab, aResult);
       if (aResult && !anOldShape.IsEqual(aSelector.value()))
         owner()->data()->sendAttributeUpdated(this);  // send updated if shape is changed
     } else {
@@ -673,30 +647,20 @@ void Model_AttributeSelection::selectBody(
     TopoDS_Shape aNewSub = theSubShape->impl<TopoDS_Shape>();
 
     bool aSelectorOk = true;
-    Selector_Selector aSel(aSelLab);
-    if (ModelAPI_Session::get()->moduleDocument() != owner()->document()) {
-      aSel.setBaseDocument(std::dynamic_pointer_cast<Model_Document>
-        (ModelAPI_Session::get()->moduleDocument())->extConstructionsLabel());
-    }
+    Selector_Selector aSelector(aSelLab, baseDocumentLab());
     try {
-      aSelectorOk = aSel.select(aContext, aNewSub, myIsGeometricalSelection);
+      aSelectorOk = aSelector.select(aContext, aNewSub, myIsGeometricalSelection);
       if (aSelectorOk) {
-        aSel.store();
-        aSelectorOk = aSel.solve(aContext);
+        aSelectorOk = aSelector.store(aContext);
       }
     } catch(...) {
       aSelectorOk = false;
     }
-    Handle(TNaming_NamedShape) aSelectorShape;
-    if (aSelectorOk && aSelLab.FindAttribute(TNaming_NamedShape::GetID(), aSelectorShape))
-    {
-      TopoDS_Shape aShape = aSelectorShape->Get();
-      if (aShape.IsNull() || aShape.ShapeType() != aNewSub.ShapeType())
-        aSelectorOk = false;
-    }
-    if (!aSelectorOk) {
-      setInvalidIfFalse(aSelLab, false);
+    if (aSelectorOk) {
+      TopoDS_Shape aShape = aSelector.value();
+      aSelectorOk = !aShape.IsNull() && aShape.ShapeType() == aNewSub.ShapeType();
     }
+    setInvalidIfFalse(aSelLab, aSelectorOk);
   }
 }
 
@@ -803,13 +767,9 @@ std::string Model_AttributeSelection::namingName(const std::string& theDefaultNa
     }
   }
 
-  Selector_Selector aSelector(aSelLab);
-  if (ModelAPI_Session::get()->moduleDocument() != owner()->document()) {
-    aSelector.setBaseDocument(std::dynamic_pointer_cast<Model_Document>
-      (ModelAPI_Session::get()->moduleDocument())->extConstructionsLabel());
-  }
+  Selector_Selector aSelector(aSelLab, baseDocumentLab());
   std::string aResult;
-  if (aSelector.restore())
+  if (aCont->shape().get() && aSelector.restore(aCont->shape()->impl<TopoDS_Shape>()))
     aResult = aSelector.name(this);
   if (aCenterType != NOT_CENTER) {
     aResult += centersMap()[aCenterType];
@@ -915,11 +875,7 @@ void Model_AttributeSelection::selectSubShape(
       }
     }
 
-    Selector_Selector aSelector(selectionLabel());
-    if (ModelAPI_Session::get()->moduleDocument() != owner()->document()) {
-      aSelector.setBaseDocument(std::dynamic_pointer_cast<Model_Document>
-        (ModelAPI_Session::get()->moduleDocument())->extConstructionsLabel());
-    }
+    Selector_Selector aSelector(selectionLabel(), baseDocumentLab());
     myRestoreDocument = aDoc;
     TDF_Label aContextLabel = aSelector.restoreByName(
       aSubShapeName, aShapeType, this, myIsGeometricalSelection);
@@ -934,25 +890,22 @@ void Model_AttributeSelection::selectSubShape(
           aShapeToBeSelected->setImpl<TopoDS_Shape>(new TopoDS_Shape(aSelectorShape));
           // make the context result the latest existing
           aContext = newestContext(aContext, aShapeToBeSelected);
-          if (myIsGeometricalSelection) { // store the currently generated name
+          if (myIsGeometricalSelection || aCenterType == NOT_CENTER) {
+            // store the currently generated name
             selectionLabel().ForgetAllAttributes(true);
             bool aToUnblock = false;
             aToUnblock = !owner()->data()->blockSendAttributeUpdated(true);
             myRef.setValue(aContext);
-            aSelector.store();
+            aSelector.store(aContextShape);
             owner()->data()->sendAttributeUpdated(this);
             if (aToUnblock)
               owner()->data()->blockSendAttributeUpdated(false);
             return;
-          } else { // re-select by context and value
-            if (aCenterType != NOT_CENTER) {
-              if (!aShapeToBeSelected->isEdge())
-                continue;
-              std::shared_ptr<GeomAPI_Edge> aSelectedEdge(new GeomAPI_Edge(aShapeToBeSelected));
-              setValueCenter(aContext, aSelectedEdge, aCenterType);
-            }
-            else
-              setValue(aContext, aShapeToBeSelected);
+          } else { // re-select center of circle/arc by context and value
+            if (!aShapeToBeSelected->isEdge())
+              continue;
+            std::shared_ptr<GeomAPI_Edge> aSelectedEdge(new GeomAPI_Edge(aShapeToBeSelected));
+            setValueCenter(aContext, aSelectedEdge, aCenterType);
           }
           return;
         }
@@ -1442,7 +1395,7 @@ void Model_AttributeSelection::updateInHistory()
       if (aValueShape.get()) {
         aShapeShapeType = aValueShape->shapeType();
       } else {
-        (*aNewCont)->shape()->shapeType();
+        aShapeShapeType = (*aNewCont)->shape()->shapeType();
       }
       if (aListShapeType != GeomAPI_Shape::SHAPE && aListShapeType != aShapeShapeType) {
         continue;
@@ -1738,14 +1691,44 @@ ResultPtr Model_AttributeSelection::newestContext(
             aResults.push_back(aBody);
         }
         std::list<std::shared_ptr<ModelAPI_Result> >::iterator aResIter = aResults.begin();
-        for (; aResIter != aResults.end(); aResIter++) {
-          if (!aResIter->get() || !(*aResIter)->data()->isValid() || (*aResIter)->isDisabled())
-            continue;
-          GeomShapePtr aShape = (*aResIter)->shape();
-          if (aShape.get() && (theAnyValue || aShape->isSubShape(aSelectedShape, false))) {
-            aResult = *aResIter; // found new context (produced from this) with same subshape
-            aFindNewContext = true; // continue searching further
-            break;
+
+        if (theAnyValue) { // searching the best sub-result by maximum number of references to orig
+          int aReferencesCount = 0;
+          ResultPtr aBestResult;
+          for (; aResIter != aResults.end(); aResIter++) {
+            if (!aResIter->get() || !(*aResIter)->data()->isValid() || (*aResIter)->isDisabled())
+              continue;
+            TDF_Label aCandidateLab =
+              std::dynamic_pointer_cast<Model_Data>((*aResIter)->data())->shapeLab();
+            Handle(TDF_Reference) aRef;
+            if (aCandidateLab.FindAttribute(TDF_Reference::GetID(), aRef)) {
+              TDF_Label aRefLab = aRef->Get();
+              ResultPtr aRefRes = aDoc->resultByLab(aRefLab);
+              if (aRefRes.get() && aRefRes->shape().get() &&
+                  aRefRes->shape()->isEqual(aResult->shape())) {// it directly references to result
+                aResult = *aResIter; // found new context (produced from this) with same subshape
+                aFindNewContext = true; // continue searching further
+                break;
+              }
+            } else {
+              if (!aBestResult.get())
+                aBestResult = *aResIter;
+            }
+          }
+          if (aBestResult.get() && !aFindNewContext) { // the first good result for now
+            aResult = aBestResult; // found new context
+            aFindNewContext = true;
+          }
+        } else { // searching by sub-shape
+          for (; aResIter != aResults.end(); aResIter++) {
+            if (!aResIter->get() || !(*aResIter)->data()->isValid() || (*aResIter)->isDisabled())
+              continue;
+            GeomShapePtr aShape = (*aResIter)->shape();
+            if (aShape.get() && (theAnyValue || aShape->isSubShape(aSelectedShape, false))) {
+              aResult = *aResIter; // found new context (produced from this) with same subshape
+              aFindNewContext = true; // continue searching further
+              break;
+            }
           }
         }
       }
@@ -1772,3 +1755,54 @@ ResultPtr Model_AttributeSelection::newestContext(
     aResult = theCurrent;
   return aResult;
 }
+
+void Model_AttributeSelection::combineGeometrical()
+{
+  if (myTmpContext.get() || myTmpSubShape.get())
+    return;
+  TDF_Label aSelLab = selectionLabel();
+  if (aSelLab.IsAttribute(kINVALID_SELECTION) || !myRef.isInitialized())
+    return;
+
+  if (aSelLab.IsAttribute(kCIRCLE_CENTER) || aSelLab.IsAttribute(kELLIPSE_CENTER1) ||
+      aSelLab.IsAttribute(kELLIPSE_CENTER2) || aSelLab.IsAttribute(kSIMPLE_REF_ID))
+    return;
+
+  if (aSelLab.IsAttribute(kPART_REF_ID)) {
+    ResultPartPtr aPart = std::dynamic_pointer_cast<ModelAPI_ResultPart>(context());
+    if (!aPart.get() || !aPart->isActivated())
+      return; // postponed naming needed
+    Handle(TDataStd_Integer) anIndex;
+    if (aSelLab.FindAttribute(TDataStd_Integer::GetID(), anIndex)) {
+      if (anIndex->Get()) { // special selection attribute was created, use it
+        std::string aNewName;
+        aPart->combineGeometrical(anIndex->Get(), aNewName);
+        TDataStd_Name::Set(aSelLab, aNewName.c_str());
+      }
+    }
+    return;
+  }
+
+  std::shared_ptr<Model_ResultConstruction> aConstr =
+    std::dynamic_pointer_cast<Model_ResultConstruction>(context());
+  if (aConstr.get())
+    return;
+  FeaturePtr aFeature = contextFeature();
+  if (aFeature.get())
+    return;
+
+  Selector_Selector aSelector(aSelLab, baseDocumentLab());
+  TopoDS_Shape aContextShape = context()->shape()->impl<TopoDS_Shape>();
+  if (aSelector.restore(aContextShape)) {
+    aSelector.combineGeometrical(aContextShape);
+  }
+}
+
+TDF_Label Model_AttributeSelection::baseDocumentLab()
+{
+  if (ModelAPI_Session::get()->moduleDocument() != owner()->document())
+    return std::dynamic_pointer_cast<Model_Document>
+      (ModelAPI_Session::get()->moduleDocument())->extConstructionsLabel();
+  static TDF_Label anEmpty;
+  return anEmpty;
+}