]> SALOME platform Git repositories - modules/shaper.git/commitdiff
Salome HOME
[bos #35154][EDF](2023-T1) Edge thickness.
authordish <dmitrii.shvydkoi@opencascade.com>
Mon, 29 Jan 2024 13:43:50 +0000 (13:43 +0000)
committerdish <dmitrii.shvydkoi@opencascade.com>
Wed, 5 Jun 2024 12:39:03 +0000 (12:39 +0000)
Add edge thickness option for individual edges.

18 files changed:
src/Model/Model_Document.cpp
src/Model/Model_Document.h
src/Model/Model_Objects.cpp
src/Model/Model_Objects.h
src/Model/Model_ResultBody.cpp
src/Model/Model_ResultBody.h
src/Model/Model_ResultPart.cpp
src/Model/Model_ResultPart.h
src/ModelAPI/ModelAPI_Document.h
src/ModelAPI/ModelAPI_ResultBody.h
src/ModelAPI/ModelAPI_ResultPart.h
src/ModelAPI/ModelAPI_Tools.cpp
src/ModelAPI/ModelAPI_Tools.h
src/PartSet/PartSet_Module.cpp
src/XGUI/XGUI_Selection.cpp
src/XGUI/XGUI_Selection.h
src/XGUI/XGUI_Workshop.cpp
src/XGUI/XGUI_Workshop.h

index 5f313a85519112845c586862b6ada79476d43b7b..986213a3c7f9cf8fbc1be11ae4d030c5d11a1b1b 100644 (file)
@@ -1375,6 +1375,13 @@ const int Model_Document::index(std::shared_ptr<ModelAPI_Object> theObject,
   return myObjs->index(theObject, theAllowFolder);
 }
 
+const int Model_Document::index(std::shared_ptr<ModelAPI_Result> theResult,
+  std::shared_ptr<GeomAPI_Shape> theShape,
+  const bool theAllowFolder)
+{
+  return myObjs->index(theResult, theShape, theAllowFolder);
+}
+
 int Model_Document::size(const std::string& theGroupID, const bool theAllowFolder)
 {
   if (myObjs == 0) // may be on close
@@ -2120,6 +2127,47 @@ AttributeSelectionListPtr Model_Document::selectionInPartFeature()
   return mySelectionFeature->selectionList("selection");
 }
 
+/// Feature that is used for use selection attribute
+class Model_SelectionInResult : public ModelAPI_Feature
+{
+public:
+  /// Nothing to do in constructor
+  Model_SelectionInResult() : ModelAPI_Feature() {}
+
+  /// Returns the unique kind of a feature
+  virtual const std::string& getKind()
+  {
+    static std::string MY_KIND("InternalSelectionInResult");
+    return MY_KIND;
+  }
+  /// Request for initialization of data model of the object: adding all attributes
+  virtual void initAttributes()
+  {
+    data()->addAttribute("selection", ModelAPI_AttributeSelection::typeId());
+  }
+  /// Nothing to do in the execution function
+  virtual void execute() {}
+};
+
+AttributeSelectionPtr Model_Document::selectionInResult()
+{
+  FeaturePtr aFeatureNameGen = FeaturePtr(new Model_SelectionInResult);
+
+  TDF_Label aFeatureLab = generalLabel().FindChild(TAG_SELECTION_FEATURE);
+  std::shared_ptr<Model_Data> aData(new Model_Data);
+  aData->setLabel(aFeatureLab.FindChild(1));
+  aData->setObject(aFeatureNameGen);
+  aFeatureNameGen->setDoc(myObjs->owner());
+  aFeatureNameGen->setData(aData);
+  std::wstring aName = id() + L"_Part";
+  aFeatureNameGen->data()->setName(aName);
+  aFeatureNameGen->setDoc(myObjs->owner());
+  aFeatureNameGen->initAttributes();
+  aFeatureNameGen->init();
+
+  return aFeatureNameGen->selection("selection");
+}
+
 FeaturePtr Model_Document::lastFeature()
 {
   if (myObjs)
@@ -2290,6 +2338,17 @@ void Model_Document::storeNodesState(const std::list<bool>& theStates)
   }
 }
 
+void Model_Document::storeShape(const std::shared_ptr<ModelAPI_Data> theData,
+  const std::shared_ptr<ModelAPI_Result> theResult,
+  const std::shared_ptr<GeomAPI_Shape> theShape)
+{
+  if (index(theData->owner()) == -1)
+    return;
+  int anIndex = index(theResult, theShape);
+  if (anIndex == -1)
+    myObjs->storeShape(theData, theResult, theShape);
+}
+
 void Model_Document::restoreNodesState(std::list<bool>& theStates) const
 {
   TDF_Label aLab = generalLabel().FindChild(TAG_NODES_STATE);
index 0017589196a7ca69e9475d5951634b6c60e8169b..e54310864bb41747e194f1e88a442bdf1bd8b70d 100644 (file)
@@ -33,6 +33,7 @@
 class Handle_Model_Document;
 class Model_Objects;
 class ModelAPI_AttributeSelectionList;
+class TopoDS_Shape;
 
 /**\class Model_Document
  * \ingroup DataModel
@@ -146,6 +147,14 @@ class Model_Document : public ModelAPI_Document
   MODEL_EXPORT virtual const int index(std::shared_ptr<ModelAPI_Object> theObject,
                                        const bool theAllowFolder = false);
 
+  //! Returns the shape index in the result.
+  //! \param theResult result
+  //! \param theShape result subshape
+  //! \returns index started from zero, or -1 if shape is not stored or is not a subshape of the result
+  MODEL_EXPORT virtual const int index(std::shared_ptr<ModelAPI_Result> theResult,
+    std::shared_ptr<GeomAPI_Shape> theShape,
+    const bool theAllowFolder = false);
+
   //! Internal sub-document by ID
   MODEL_EXPORT virtual std::shared_ptr<Model_Document> subDoc(int theDocID);
 
@@ -385,10 +394,18 @@ class Model_Document : public ModelAPI_Document
   //! for calculation of selection externally from the document
   std::shared_ptr<ModelAPI_AttributeSelectionList> selectionInPartFeature();
 
+  //! Returns the selection attribute that is used
+  std::shared_ptr<ModelAPI_AttributeSelection> selectionInResult();
+
   /// Stores in the document boolean flags: states of the nodes in the object browser.
   /// Normally is called outside of the transaction, just before "save".
   virtual void storeNodesState(const std::list<bool>& theStates);
 
+  /// Store Shape from Result to document
+  virtual void storeShape(const std::shared_ptr<ModelAPI_Data> theData,
+    const std::shared_ptr<ModelAPI_Result> theResult,
+    const std::shared_ptr<GeomAPI_Shape> theShape);
+
   /// Returns the stored nodes states. Normally it is called just after "open".
   /// Appends the values to theStates list.
   virtual void restoreNodesState(std::list<bool>& theStates) const;
@@ -424,6 +441,7 @@ class Model_Document : public ModelAPI_Document
   friend class Model_ResultPart;
   friend class Model_ResultBody;
   friend class Model_ResultConstruction;
+  friend class Model_SelectionInResult;
   friend class Model_SelectionNaming;
   friend class Model_BodyBuilder;
   friend class DFBrowser;
index 544b5bef8bba5879774fbbc71db22b6de98cccef..bbce6b42dfcfb8f25f75dce9a0c99844850762ef 100644 (file)
 #include <TDataStd_Integer.hxx>
 #include <TDataStd_Comment.hxx>
 #include <TDF_ChildIDIterator.hxx>
+#include <TDataStd_IntegerArray.hxx>
 #include <TDataStd_ReferenceArray.hxx>
 #include <TDataStd_HLabelArray1.hxx>
 #include <TDF_Reference.hxx>
 #include <TDF_ChildIDIterator.hxx>
 #include <TDF_LabelMap.hxx>
+#include <TDF_CopyLabel.hxx>
 #include <TDF_ListIteratorOfLabelList.hxx>
 
-#if OCC_VERSION_LARGE < 0x07080000
+#include <TNaming_Builder.hxx>
+#include <TNaming_NamedShape.hxx>
 
+#if OCC_VERSION_LARGE < 0x07080000
 #include <TDF_LabelMapHasher.hxx>
 // for TDF_Label map usage
 static Standard_Integer HashCode(const TDF_Label& theLab, const Standard_Integer theUpper);
@@ -97,11 +101,13 @@ static const int TAG_OBJECTS = 2;  // tag of the objects sub-tree (features, res
 // feature sub-labels
 static const int TAG_FEATURE_ARGUMENTS = 1;  ///< where the arguments are located
 static const int TAG_FEATURE_RESULTS = 2;  ///< where the results are located
+static const int TAG_RESULT_SHAPES = 2;  ///< where the shapes are located
 
 ///
 /// 0:1:2 - where features are located
 /// 0:1:2:N:1 - data of the feature N
 /// 0:1:2:N:2:K:1 - data of the K result of the feature N
+/// 0:1:2:N:2:K:2:M:1 - data of the M shape of the K result of the feature N
 
 Model_Objects::Model_Objects(TDF_Label theMainLab) : myMain(theMainLab)
 {
@@ -689,6 +695,39 @@ const int Model_Objects::index(std::shared_ptr<ModelAPI_Object> theObject,
   return -1;
 }
 
+const int Model_Objects::index(std::shared_ptr<ModelAPI_Result> theResult,
+  std::shared_ptr<GeomAPI_Shape> theShape,
+  const bool theAllowFolder)
+{
+  ResultBodyPtr aMain = std::dynamic_pointer_cast<ModelAPI_ResultBody>(theResult);
+  aMain = ModelAPI_Tools::mainBody(aMain);
+
+  int anIndex = -1;
+  if (aMain.get())
+    anIndex = index(aMain, theAllowFolder);
+  else
+    anIndex = index(theResult, theAllowFolder);
+
+  if (anIndex == -1)
+    return -1; // Object not store to document
+  TDF_Label aShapesLabel = shapesFromResult(resultLabel(theResult->data(), anIndex));
+
+  int aShapesIndex = 0;
+  for (TDF_ChildIterator anIt(aShapesLabel); anIt.More(); anIt.Next(), ++aShapesIndex)
+  {
+    Handle(TNaming_NamedShape) aCurShape;
+    if (anIt.Value().FindAttribute(TNaming_NamedShape::GetID(), aCurShape))
+    {
+      if (aCurShape->Get().IsSame(theShape->impl<TopoDS_Shape>()))
+      {
+        return aShapesIndex;
+      }
+    }
+  }
+  //not found
+  return -1;
+}
+
 int Model_Objects::size(const std::string& theGroupID, const bool theAllowFolder)
 {
   createHistory(theGroupID);
@@ -740,6 +779,135 @@ TDF_Label Model_Objects::featuresLabel() const
   return myMain.FindChild(TAG_OBJECTS);
 }
 
+TDF_Label Model_Objects::shapesFromResult(TDF_Label theResult) const
+{
+  return theResult.Father().FindChild(TAG_RESULT_SHAPES);
+}
+
+void Model_Objects::setAttribute(const Handle(TDF_Attribute)& theAttribute,
+  std::shared_ptr<ModelAPI_Result> theResult,
+  std::shared_ptr<GeomAPI_Shape> theShape)
+{
+  ResultBodyPtr aMain = std::dynamic_pointer_cast<ModelAPI_ResultBody>(theResult);
+  aMain = ModelAPI_Tools::mainBody(aMain);
+  TDF_Label aResultLabel;
+  if (aMain.get())
+    aResultLabel = resultLabel(theResult->data(), index(aMain));
+  else
+    aResultLabel = resultLabel(theResult->data(), index(theResult));
+  TDF_Label anAttributeLabel = subShapeLabel(aResultLabel, index(theResult, theShape)).FindChild(TAG_FEATURE_ARGUMENTS);
+
+  if (Standard_GUID::IsEqual(theAttribute->ID(), TDataStd_IntegerArray::GetID()))
+  {
+    Handle(TDataStd_IntegerArray) anColor;
+    Handle(TDataStd_IntegerArray) anAttr =
+      Handle(TDataStd_IntegerArray)::DownCast(theAttribute);
+
+    if (anAttributeLabel.FindAttribute(TDataStd_IntegerArray::GetID(), anColor))
+    {
+      anAttributeLabel.ForgetAttribute(TDataStd_IntegerArray::GetID());
+    }
+    anAttributeLabel.AddAttribute(anAttr);
+    static const Events_ID anEvent = Events_Loop::eventByName(EVENT_OBJECT_UPDATED);
+    ModelAPI_EventCreator::get()->sendUpdated(theResult, anEvent);
+  }
+  else if (Standard_GUID::IsEqual(theAttribute->ID(), TDataStd_Integer::GetID())) {
+    Handle(TDataStd_Integer) aThicknessAttr;
+    Handle(TDataStd_Integer) anAttr = Handle(TDataStd_Integer)::DownCast(theAttribute);
+
+    if (anAttributeLabel.FindAttribute(TDataStd_Integer::GetID(), aThicknessAttr))
+      anAttributeLabel.ForgetAttribute(TDataStd_Integer::GetID());
+
+    anAttributeLabel.AddAttribute(anAttr);
+    static const Events_ID anEvent = Events_Loop::eventByName(EVENT_OBJECT_UPDATED);
+    ModelAPI_EventCreator::get()->sendUpdated(theResult, anEvent);
+  }
+}
+
+Handle(TDF_Attribute) Model_Objects::getAttribute(const Standard_GUID& theID,
+  std::shared_ptr<ModelAPI_Result> theResult,
+  std::shared_ptr<GeomAPI_Shape> theShape)
+{
+  ResultBodyPtr aMain = std::dynamic_pointer_cast<ModelAPI_ResultBody>(theResult);
+  aMain = ModelAPI_Tools::mainBody(aMain);
+
+  int anIndex = index(theResult, theShape);
+  if (anIndex == -1) {
+    return opencascade::handle<TDF_Attribute>(nullptr);
+  }
+
+  TDF_Label aResultLabel;
+  if (aMain.get())
+    aResultLabel = resultLabel(theResult->data(), index(aMain));
+  else
+    aResultLabel = resultLabel(theResult->data(), index(theResult));
+
+  TDF_Label anAttributeLabel = subShapeLabel(aResultLabel, anIndex).FindChild(TAG_FEATURE_ARGUMENTS);
+
+  Handle(TDF_Attribute) anAttr;
+  anAttributeLabel.FindAttribute(theID, anAttr);
+  return anAttr;
+}
+
+void Model_Objects::getSubShapesWithEdgeThickness(
+  const std::shared_ptr<ModelAPI_Result> theResult,
+  std::map<std::shared_ptr<GeomAPI_Shape>, int>& oShapes
+) const {
+  ResultBodyPtr aMainBody = std::dynamic_pointer_cast<ModelAPI_ResultBody>(theResult);
+  aMainBody = ModelAPI_Tools::mainBody(aMainBody);
+  TDF_Label aShapesLabel;
+  if (aMainBody.get())
+    aShapesLabel = shapesFromResult(resultLabel(theResult->data(), index(aMainBody)));
+  else
+    aShapesLabel = shapesFromResult(resultLabel(theResult->data(), index(theResult)));
+
+  for (TDF_ChildIterator aChilds(aShapesLabel); aChilds.More(); aChilds.Next())
+  {
+    TDF_Label aCurSubShape = aChilds.Value();
+    Handle(TNaming_NamedShape) aNamedShape;
+    aCurSubShape.FindAttribute(TNaming_NamedShape::GetID(), aNamedShape);
+    if (aNamedShape.IsNull())
+      continue;
+
+    std::shared_ptr<GeomAPI_Shape> aSub(new GeomAPI_Shape);
+    aSub->setImpl(new TopoDS_Shape(aNamedShape->Get()));
+
+    Handle(TDataStd_Integer) aEdgeThicknessAttr;
+    aCurSubShape.FindChild(TAG_FEATURE_ARGUMENTS).FindAttribute(TDataStd_Integer::GetID(), aEdgeThicknessAttr);
+    if (aEdgeThicknessAttr.IsNull())
+      continue;
+
+    oShapes[aSub] = aEdgeThicknessAttr->Get();
+  }
+}
+
+void Model_Objects::removeSubShapeEdgeThickness(const std::shared_ptr<ModelAPI_Result> theResult) const
+{
+  ResultBodyPtr aMainBody = std::dynamic_pointer_cast<ModelAPI_ResultBody>(theResult);
+  aMainBody = ModelAPI_Tools::mainBody(aMainBody);
+
+  TDF_Label aShapesLabel;
+  if (aMainBody.get())
+    aShapesLabel = shapesFromResult(resultLabel(theResult->data(), index(aMainBody)));
+  else
+  {
+    ResultPartPtr aResPart = std::dynamic_pointer_cast<ModelAPI_ResultPart>(theResult);
+    if (!aResPart.get())
+      return;
+    aShapesLabel = shapesFromResult(resultLabel(theResult->data(), index(aResPart)));
+  }
+  for (TDF_ChildIterator aChilds(aShapesLabel); aChilds.More(); aChilds.Next())
+  {
+    TDF_Label aCurSubShape = aChilds.Value();
+    Handle(TNaming_NamedShape) aNamedShape;
+    aCurSubShape.FindAttribute(TNaming_NamedShape::GetID(), aNamedShape);
+    if (aNamedShape.IsNull())
+      continue;
+
+    aCurSubShape.FindChild(TAG_FEATURE_ARGUMENTS).ForgetAttribute(TDataStd_Integer::GetID());
+  }
+}
+
 static std::wstring composeName(const std::string& theFeatureKind, const int theIndex)
 {
   std::stringstream aNameStream;
@@ -1194,6 +1362,12 @@ TDF_Label Model_Objects::resultLabel(
   return aData->label().Father().FindChild(TAG_FEATURE_RESULTS).FindChild(theResultIndex + 1);
 }
 
+TDF_Label Model_Objects::subShapeLabel(TDF_Label& theResultLabel,
+  const int theResultIndex)
+{
+  return theResultLabel.Father().FindChild(TAG_RESULT_SHAPES).FindChild(theResultIndex + 1);
+}
+
 bool Model_Objects::hasCustomName(DataPtr theFeatureData,
                                   ResultPtr theResult,
                                   int /*theResultIndex*/,
@@ -1263,6 +1437,28 @@ void Model_Objects::storeResult(std::shared_ptr<ModelAPI_Data> theFeatureData,
   }
 }
 
+void Model_Objects::storeShape(std::shared_ptr<ModelAPI_Data> theData,
+  std::shared_ptr<ModelAPI_Result> theResult,
+  std::shared_ptr<GeomAPI_Shape> theShape,
+  const int theResultIndex)
+{
+  std::shared_ptr<Model_Data> aResultData =
+    std::dynamic_pointer_cast<Model_Data>(theResult->data());
+  TDF_Label aResultLabel = resultLabel(aResultData, index(theData->owner()));
+  TDF_Label aShapesLabel = shapesFromResult(aResultLabel);
+
+  int anIndex = aShapesLabel.NbChildren();
+  TDF_Label aSubShapeLabel = subShapeLabel(aResultLabel, anIndex);
+
+  Handle(TNaming_NamedShape) aNS;
+  if (aSubShapeLabel.FindAttribute(TNaming_NamedShape::GetID(), aNS))
+    return;
+
+  // GeomAPI_Shape -> TNaming_NamedShape
+  TNaming_Builder aBuilder(aSubShapeLabel);
+  aBuilder.Select(theShape->impl<TopoDS_Shape>(), theShape->impl<TopoDS_Shape>());
+}
+
 std::shared_ptr<ModelAPI_ResultConstruction> Model_Objects::createConstruction(
     const std::shared_ptr<ModelAPI_Data>& theFeatureData, const int theIndex)
 {
@@ -1293,7 +1489,7 @@ std::shared_ptr<ModelAPI_ResultBody> Model_Objects::createBody(
     aResult = std::dynamic_pointer_cast<ModelAPI_ResultBody>(anOldObject);
   }
   if (!aResult.get()) {
-    aResult = std::shared_ptr<ModelAPI_ResultBody>(new Model_ResultBody);
+    aResult = std::shared_ptr<ModelAPI_ResultBody>(new Model_ResultBody());
     storeResult(theFeatureData, aResult, theIndex, theNameShape);
   }
   return aResult;
@@ -2046,7 +2242,7 @@ FeaturePtr Model_Objects::lastFeature()
 
 bool Model_Objects::isLater(FeaturePtr theLater, FeaturePtr theCurrent) const
 {
-  if (theLater->getKind() == "InternalSelectionInPartFeature")
+  if (theLater->getKind() == "InternalSelectionInPartFeature" || theLater->getKind() == "InternalSelectionInResult")
     return true;
   std::shared_ptr<Model_Data> aLaterD = std::static_pointer_cast<Model_Data>(theLater->data());
   std::shared_ptr<Model_Data> aCurrentD = std::static_pointer_cast<Model_Data>(theCurrent->data());
index e810e10add7338a202a31f488b2cc9361e0bb17c..b0ce8b4fe798f772fe143979ca2a225a261e3ff2 100644 (file)
@@ -92,6 +92,14 @@ class Model_Objects
   const int index(std::shared_ptr<ModelAPI_Object> theObject,
                   const bool theAllowFolder = false);
 
+  //! Returns the shape index in the result.
+  //! \param theResult result
+  //! \param theShape result subshape
+  //! \returns index started from zero, or -1 if shape is not stored or is not a subshape of the result
+  const int index(std::shared_ptr<ModelAPI_Result> theResult,
+    std::shared_ptr<GeomAPI_Shape> theShape,
+    const bool theAllowFolder = false);
+
   //! Returns the feature in the group by the index (started from zero)
   //! \param theGroupID group that contains a feature
   //! \param theIndex zero-based index of feature in the group
@@ -181,6 +189,23 @@ class Model_Objects
   bool removeFromFolder(const std::list<std::shared_ptr<ModelAPI_Feature> >& theFeatures,
                         const bool theBefore = true);
 
+  //! set attribute to subShape
+  void setAttribute(const Handle(TDF_Attribute)& theAttribute,
+    std::shared_ptr<ModelAPI_Result> theResult,
+    std::shared_ptr<GeomAPI_Shape> theShape);
+
+  //! get attribute from subshape
+  Handle(TDF_Attribute) getAttribute(const Standard_GUID& theID,
+    std::shared_ptr<ModelAPI_Result> theResult,
+    std::shared_ptr<GeomAPI_Shape> theShape);
+
+  void getSubShapesWithEdgeThickness(
+    const std::shared_ptr<ModelAPI_Result> theResult,
+    std::map<std::shared_ptr<GeomAPI_Shape>, int>& oShapes
+  ) const;
+
+  void removeSubShapeEdgeThickness(const std::shared_ptr<ModelAPI_Result> theResult) const;
+
   //! Sets the owner of this manager
   void setOwner(DocumentPtr theDoc);
 
@@ -195,6 +220,9 @@ class Model_Objects
   //! Returns (creates if needed) the features label
   TDF_Label featuresLabel() const;
 
+  //! Returns (creates if needed) the shapes label from result label
+  TDF_Label shapesFromResult(TDF_Label theResult) const;
+
   //! Initializes feature with a unique name in this group (unique name is generated as
   //! feature type + "_" + index
   void setUniqueName(FeaturePtr theFeature);
@@ -227,10 +255,20 @@ class Model_Objects
                    const int theResultIndex = 0,
                    const std::wstring& theNameShape = L"");
 
+  //! Allows to store the shape from result in the data tree of the document
+  void storeShape(std::shared_ptr<ModelAPI_Data> theData,
+    std::shared_ptr<ModelAPI_Result> theResult,
+    std::shared_ptr<GeomAPI_Shape> theShape,
+    const int theResultIndex = 0);
+
   //! returns the label of result by index; creates this label if it was not created before
   TDF_Label resultLabel(const std::shared_ptr<ModelAPI_Data>& theFeatureData,
                         const int theResultIndex);
 
+  //! Returns the label of result subshapes by index; creates this label if it was not created before
+  TDF_Label subShapeLabel(TDF_Label& theResultLabel,
+    const int theResultIndex);
+
   //! Updates the results list of the feature basing on the current data tree
   //! theProcessed is used to avoid update twice (since the function is recursive)
   void updateResults(FeaturePtr theFeature, std::set<FeaturePtr>& theProcessed);
index f6bc7d31a6154e3a4064b34baa34b5b867300c22..c3915e4283957e5aca0f7aba3f438361f7c592ac 100644 (file)
 #include <TopExp_Explorer.hxx>
 #include <TopTools_MapOfShape.hxx>
 #include <TDataStd_UAttribute.hxx>
+#include <TDataStd_Integer.hxx>
+#include <TNaming_Tool.hxx>
+#include <TDF_Reference.hxx>
+
 
 // if this attribute exists, the shape is connected topology
 Standard_GUID kIsConnectedTopology("e51392e0-3a4d-405d-8e36-bbfe19858ef5");
@@ -249,6 +253,49 @@ void Model_ResultBody::updateConcealment()
   }
 }
 
+void Model_ResultBody::setSubShapeEdgeThickness(
+  const std::shared_ptr<ModelAPI_Result> theResult,
+  const std::shared_ptr<GeomAPI_Shape> theSubShape,
+  int theEdgeThickness
+)
+{
+  TopoDS_Shape aShape = shape()->impl<TopoDS_Shape>();
+  TopoDS_Shape aSubShape = theSubShape->impl<TopoDS_Shape>();
+  if (!shape()->isSubShape(theSubShape))
+    return;
+
+  Model_Objects* anObjects = std::dynamic_pointer_cast<Model_Document>(document())->objects();
+  document()->storeShape(data(), theResult, theSubShape);
+
+  Handle(TDataStd_Integer) aThickness = new TDataStd_Integer();
+  aThickness->Set(theEdgeThickness);
+  anObjects->setAttribute(aThickness, theResult, theSubShape);
+}
+
+int Model_ResultBody::getSubShapeEdgeThickness(const std::shared_ptr<ModelAPI_Result> theResult, const std::shared_ptr<GeomAPI_Shape> theSubShape) const
+{
+  TopoDS_Shape aShape = shape()->impl<TopoDS_Shape>();
+  TopoDS_Shape aSubShape = theSubShape->impl<TopoDS_Shape>();
+  if (!shape()->isSubShape(theSubShape))
+    return -1;
+
+  Model_Objects* anObjects = std::dynamic_pointer_cast<Model_Document>(document())->objects();
+  auto anAttr = Handle(TDataStd_Integer)::DownCast(anObjects->getAttribute(TDataStd_Integer::GetID(), theResult, theSubShape));
+  if (anAttr.IsNull())
+    return;
+
+  return anAttr->Get();
+}
+
+void Model_ResultBody::getSubShapesWithEdgeThickness(
+  const std::shared_ptr<ModelAPI_Result> theResult,
+  std::map<std::shared_ptr<GeomAPI_Shape>, int>& oShapes
+) const
+{
+  Model_Objects* anObjects = std::dynamic_pointer_cast<Model_Document>(document())->objects();
+  anObjects->getSubShapesWithEdgeThickness(theResult, oShapes);
+}
+
 void Model_ResultBody::addShapeColor( const std::wstring& theName,std::vector<int>& color) {
 
   if (myColorsShape.find(theName) == myColorsShape.end())
@@ -497,6 +544,12 @@ static void collectSubs(
   }
 }
 
+void Model_ResultBody::removeSubShapeEdgeThickness(const std::shared_ptr<ModelAPI_Result> theResult)
+{
+  Model_Objects* anObjects = std::dynamic_pointer_cast<Model_Document>(document())->objects();
+  anObjects->removeSubShapeEdgeThickness(theResult);
+}
+
 void Model_ResultBody::computeOldForSub(const GeomShapePtr& theSub,
   const std::list<GeomShapePtr>& theAllOlds, std::list<GeomShapePtr>& theOldForSub)
 {
index bda42cdf5a33b8be02050ab5df5c295b84086aa1..3157489136efb77f12dcbe1c1ceada847c0a2d37 100644 (file)
@@ -139,6 +139,21 @@ protected:
   /// Checks the state of children and parents to send events of creation/erase when needed
   void updateConcealment();
 
+  void setSubShapeEdgeThickness(
+    const std::shared_ptr<ModelAPI_Result> theResult,
+    const std::shared_ptr<GeomAPI_Shape> theSubShape,
+    int theEdgeThickness
+  );
+
+  int getSubShapeEdgeThickness(const std::shared_ptr<ModelAPI_Result> theResult, const std::shared_ptr<GeomAPI_Shape> theSubShape) const;
+
+  void getSubShapesWithEdgeThickness(
+    const std::shared_ptr<ModelAPI_Result> theResult,
+    std::map<std::shared_ptr<GeomAPI_Shape>, int>& oSubShapes
+  ) const;
+
+  void removeSubShapeEdgeThickness(const std::shared_ptr<ModelAPI_Result> theResult);
+
   /// Adds to theOldForSub only old shapes that where used for theSub creation
   void computeOldForSub(const GeomShapePtr& theSub,
     const std::list<GeomShapePtr>& theAllOlds, std::list<GeomShapePtr>& theOldForSub);
index 43bc45c12996f53a62ab683e11daa7b519bed353..91fdda8b54749b0799b3296ee38652590345f59b 100644 (file)
 #include <ModelAPI_Session.h>
 #include <ModelAPI_Feature.h>
 #include <ModelAPI_ResultBody.h>
+#include <ModelAPI_AttributeInteger.h>
 #include <ModelAPI_AttributeIntArray.h>
 #include <ModelAPI_AttributeSelectionList.h>
 #include <ModelAPI_AttributeReference.h>
 #include <ModelAPI_AttributeDouble.h>
 #include <Model_Document.h>
 #include <Model_Application.h>
+#include <Model_Objects.h>
 #include <Events_Loop.h>
 #include <ModelAPI_Events.h>
 #include <ModelAPI_Tools.h>
@@ -44,6 +46,7 @@
 #include <TNaming_Tool.hxx>
 #include <TNaming_NamedShape.hxx>
 #include <TDataStd_Name.hxx>
+#include <TDataStd_Integer.hxx>
 #include <TopoDS_Compound.hxx>
 #include <BRep_Builder.hxx>
 #include <TopExp_Explorer.hxx>
@@ -431,6 +434,48 @@ std::shared_ptr<GeomAPI_Shape> Model_ResultPart::shapeInPart(
   return aResult;
 }
 
+void Model_ResultPart::setSubShapeEdgeThickness(const std::shared_ptr<GeomAPI_Shape>& theSubShape, int theThickness)
+{
+  TopoDS_Shape aShape = shape()->impl<TopoDS_Shape>();
+  TopoDS_Shape aSubShape = theSubShape->impl<TopoDS_Shape>();
+  if (!shape()->isSubShape(theSubShape))
+    return;
+
+  Model_Objects* anObjects = std::dynamic_pointer_cast<Model_Document>(document())->objects();
+
+  document()->storeShape(data(), original(), theSubShape);
+  Handle(TDataStd_Integer) aThickness = new TDataStd_Integer();
+  aThickness->Set(theThickness);
+  anObjects->setAttribute(aThickness, original(), theSubShape);
+}
+
+int Model_ResultPart::getSubShapeEdgeThickness(const std::shared_ptr<GeomAPI_Shape>& theSubShape) const
+{
+  TopoDS_Shape aShape = shape()->impl<TopoDS_Shape>();
+  TopoDS_Shape aSubShape = theSubShape->impl<TopoDS_Shape>();
+  if (!shape()->isSubShape(theSubShape))
+    return;
+
+  Model_Objects* anObjects = std::dynamic_pointer_cast<Model_Document>(document())->objects();
+  Handle(TDataStd_Integer) anAttr = Handle(TDataStd_Integer)::DownCast(anObjects->getAttribute(TDataStd_Integer::GetID(), original(), theSubShape));
+  if (anAttr.IsNull())
+    return;
+
+  return anAttr->Get();
+}
+
+void Model_ResultPart::getSubShapesWithEdgeThickness(std::map<std::shared_ptr<GeomAPI_Shape>, int>& oShapes)
+{
+  Model_Objects* anObjects = std::dynamic_pointer_cast<Model_Document>(document())->objects();
+  anObjects->getSubShapesWithEdgeThickness(original(), oShapes);
+}
+
+void Model_ResultPart::removeSubShapeEdgeThickness()
+{
+  Model_Objects* anObjects = std::dynamic_pointer_cast<Model_Document>(document())->objects();
+  anObjects->removeSubShapeEdgeThickness(original());
+}
+
 std::shared_ptr<GeomAPI_Shape> Model_ResultPart::selectionValue(const int theIndex)
 {
   std::shared_ptr<GeomAPI_Shape> aResult;
index 172bf8bed5ed36df08376f38e28d3790808d0000..7c1d2551ff6a6068897dbcd9676052aa2a0fca1e 100644 (file)
@@ -78,6 +78,15 @@ class Model_ResultPart : public ModelAPI_ResultPart
   /// Returns the shape by the name in the part
   MODEL_EXPORT virtual std::shared_ptr<GeomAPI_Shape> shapeInPart(
     const std::wstring& theName, const std::string& theType, int& theIndex);
+
+  MODEL_EXPORT virtual void setSubShapeEdgeThickness(const std::shared_ptr<GeomAPI_Shape>& theSubShape, int theThickness);
+
+  MODEL_EXPORT virtual int getSubShapeEdgeThickness(const std::shared_ptr<GeomAPI_Shape>& theSubShape) const;
+
+  MODEL_EXPORT virtual void getSubShapesWithEdgeThickness(std::map<std::shared_ptr<GeomAPI_Shape>, int>& oSubShapes);
+
+  MODEL_EXPORT virtual void removeSubShapeEdgeThickness();
+
   /// Updates the selection inside of the part as a geometrical selection
   MODEL_EXPORT virtual bool combineGeometrical(const int theIndex, std::wstring& theNewName);
   /// Updates the shape-result of the part (called on Part feature execution)
index acec2b808c16bce4a39f42c46b9697bff251fc6e..f07b86c5d064e02bef6efa8c0f878ae6a3115ca0 100644 (file)
@@ -109,6 +109,14 @@ public:
   virtual const int index(std::shared_ptr<ModelAPI_Object> theObject,
                           const bool theAllowFolder = false) = 0;
 
+  //! Returns the shape index in the result.
+  //! \param theResult result
+  //! \param theShape result subshape
+  //! \returns index started from zero, or -1 if shape is not stored or is not a subshape of the result
+  virtual const int index(std::shared_ptr<ModelAPI_Result> theResult,
+    std::shared_ptr<GeomAPI_Shape> theShape,
+    const bool theAllowFolder = false) = 0;
+
   //! Returns the number of objects in the group of objects
   //! \param theGroupID group of objects
   //! \param theAllowFolder take into account grouping feature by folders
@@ -251,6 +259,11 @@ public:
   /// Appends the values to theStates list.
   MODELAPI_EXPORT virtual void restoreNodesState(std::list<bool>& theStates) const = 0;
 
+  /// Store Shape from Result to document
+  MODELAPI_EXPORT virtual void storeShape(const std::shared_ptr<ModelAPI_Data> theData,
+    const std::shared_ptr<ModelAPI_Result> theResult,
+    const std::shared_ptr<GeomAPI_Shape> theShape) = 0;
+
   /// Just removes all features without touching the document data (to be able undo)
   MODELAPI_EXPORT virtual void eraseAllFeatures() = 0;
 
index 223c91d55ea72936d20677622fd33d4ddf6270af..a9d1068207feeb4fa67b0b24ca57e8293d9c7d1d 100644 (file)
@@ -216,6 +216,24 @@ public:
   MODELAPI_EXPORT virtual const std::vector<int>& findShapeColor(
     const std::wstring& theShapeName) = 0;
 
+  MODELAPI_EXPORT virtual void setSubShapeEdgeThickness(
+    const std::shared_ptr<ModelAPI_Result> theResult,
+    const std::shared_ptr<GeomAPI_Shape> theSubShape,
+    int theEdgeThickness
+  ) = 0;
+
+  MODELAPI_EXPORT virtual int getSubShapeEdgeThickness(
+    const std::shared_ptr<ModelAPI_Result> theResult,
+    const std::shared_ptr<GeomAPI_Shape> theSubShape
+  ) const = 0;
+
+  MODELAPI_EXPORT virtual void getSubShapesWithEdgeThickness(
+    const std::shared_ptr<ModelAPI_Result> theResult,
+    std::map<std::shared_ptr<GeomAPI_Shape>, int>& oSubShapes
+  ) const = 0;
+
+  MODELAPI_EXPORT virtual void removeSubShapeEdgeThickness(const std::shared_ptr<ModelAPI_Result> theResult) = 0;
+
 
 protected:
   /// Default constructor accessible only from Model_Objects
index 148315a5f89492e837c5b597a0b30e240c8671e5..2b23383f98b3534f875cfab6ba1166dcf54b5e07 100644 (file)
@@ -24,6 +24,8 @@
 class GeomAPI_Trsf;
 
 #include <string>
+#include <map>
+#include <vector>
 
 /**\class ModelAPI_ResultPart
  * \ingroup DataModel
@@ -89,6 +91,14 @@ class ModelAPI_ResultPart : public ModelAPI_Result
   virtual std::shared_ptr<GeomAPI_Shape> shapeInPart(
     const std::wstring& theName, const std::string& theType, int& theIndex) = 0;
 
+  virtual void setSubShapeEdgeThickness(const std::shared_ptr<GeomAPI_Shape>& theSubShape, int theThickness) = 0;
+
+  virtual int getSubShapeEdgeThickness(const std::shared_ptr<GeomAPI_Shape>& theSubShape) const = 0;
+
+  virtual void getSubShapesWithEdgeThickness(std::map<std::shared_ptr<GeomAPI_Shape>, int>& oSubShapes) = 0;
+
+  virtual void removeSubShapeEdgeThickness() = 0;
+
   /// Updates the selection inside of the part as a geometrical selection
   virtual bool combineGeometrical(const int theIndex, std::wstring& theNewName) = 0;
 
index 76af01b4853bbc1679bc55d6e69c527e9225ad91..ee7afe9a1be83c565b5bea2db53fe542b0bf7634 100644 (file)
@@ -519,6 +519,19 @@ ResultBodyPtr bodyOwner(const ResultPtr& theSub, const bool theRoot)
   return ResultBodyPtr(); // not found
 }
 
+std::shared_ptr<ModelAPI_ResultBody> mainBody(const std::shared_ptr<ModelAPI_ResultBody> theSubBody)
+{
+  ResultBodyPtr aBody = theSubBody;
+  while (aBody.get())
+  { // get the top-most main
+    ResultBodyPtr aNextBody = bodyOwner(aBody);
+    if (aNextBody.get())
+      aBody = aNextBody;
+    else break;
+  }
+  return aBody;
+}
+
 int bodyIndex(const ResultPtr& theSub)
 {
   int anIndex = -1;
@@ -1208,14 +1221,118 @@ int getEdgeThickness(const std::shared_ptr<ModelAPI_Result>& theResult)
   return aThickness;
 }
 
-void setEdgeThickness(ResultPtr theResult, int theEdgeThickness)
+int getSubShapeEdgeThickness(const std::shared_ptr<ModelAPI_Result> theResult, const std::shared_ptr<GeomAPI_Shape> theSubShape)
+{
+  if (!theResult || theSubShape->isNull())
+    return -1;
+
+  if (!theResult->shape()->isSubShape(theSubShape))
+    return -1;
+
+  auto resultBody = std::dynamic_pointer_cast<ModelAPI_ResultBody>(theResult);
+  if (resultBody) {
+    resultBody = mainBody(resultBody);
+    return resultBody->getSubShapeEdgeThickness(theResult, theSubShape);
+  }
+  else {
+    const auto resultPart = std::dynamic_pointer_cast<ModelAPI_ResultPart>(theResult);
+    if (!resultPart)
+      return -1;
+
+    return resultPart->getSubShapeEdgeThickness(theSubShape);
+  }
+}
+
+void getSubShapesWithEdgeThickness(
+  const std::shared_ptr<ModelAPI_Result> theResult,
+  std::map<std::shared_ptr<GeomAPI_Shape>, int>& oShapes,
+  bool theGetSubResults
+) {
+  if (!theResult)
+    return;
+
+  const auto resultBody = std::dynamic_pointer_cast<ModelAPI_ResultBody>(theResult);
+  if (resultBody) {
+    ResultBodyPtr mainBody = ModelAPI_Tools::mainBody(resultBody);
+    if (!mainBody)
+      return;
+
+    if (theGetSubResults) {
+      std::list<ResultPtr> subResults;
+      allSubs(resultBody, subResults);
+      for (auto itSubRes = subResults.begin(); itSubRes != subResults.end(); ++itSubRes) {
+        mainBody->getSubShapesWithEdgeThickness(*itSubRes, oShapes);
+      }
+    }
+
+    mainBody->getSubShapesWithEdgeThickness(theResult, oShapes);
+  }
+  else {
+    const auto resultPart = std::dynamic_pointer_cast<ModelAPI_ResultPart>(theResult);
+    if (!resultPart)
+      return;
+
+    resultPart->getSubShapesWithEdgeThickness(oShapes);
+  }
+}
+
+void removeSubShapeEdgeThickness(const std::shared_ptr<ModelAPI_Result> theResult)
+{
+  if (!theResult)
+    return;
+
+  auto resultBody = std::dynamic_pointer_cast<ModelAPI_ResultBody>(theResult);
+  if (resultBody) {
+    resultBody = mainBody(resultBody);
+    resultBody->removeSubShapeEdgeThickness(theResult);
+  }
+  else {
+    auto resultPart = std::dynamic_pointer_cast<ModelAPI_ResultPart>(theResult);
+    if (!resultPart)
+      return;
+
+    resultPart->removeSubShapeEdgeThickness();
+  }
+}
+
+void setEdgeThickness(std::shared_ptr<ModelAPI_Result> theResult, int theEdgeThickness)
 {
   if (!theResult)
     return;
 
-  AttributeIntegerPtr anAttribute = theResult->data()->integer(ModelAPI_Result::EDGE_THICKNESS_ID());
-  if (anAttribute)
+  const AttributeIntegerPtr anAttribute = theResult->data()->integer(ModelAPI_Result::EDGE_THICKNESS_ID());
+  if (anAttribute) {
     anAttribute->setValue(theEdgeThickness);
+    removeSubShapeEdgeThickness(theResult);
+  }
+}
+
+void setSubShapeEdgeThickness(
+  std::shared_ptr<ModelAPI_Result> theResult,
+  std::shared_ptr<GeomAPI_Shape> theSubShape,
+  int theEdgeThickness
+) {
+  if (!theResult || theSubShape->isNull())
+    return;
+
+  if (!theResult->shape()->isSubShape(theSubShape))
+    return;
+
+  auto resultBody = std::dynamic_pointer_cast<ModelAPI_ResultBody>(theResult);
+  if (resultBody) {
+    resultBody = mainBody(resultBody);
+    resultBody->setSubShapeEdgeThickness(theResult, theSubShape, theEdgeThickness);
+  }
+  else {
+    const auto resultPart = std::dynamic_pointer_cast<ModelAPI_ResultPart>(theResult);
+    if (!resultPart)
+      return;
+
+    resultPart->setSubShapeEdgeThickness(theSubShape, theEdgeThickness);
+  }
+
+  static const Events_ID EVENT = Events_Loop::eventByName(EVENT_OBJECT_TO_REDISPLAY);
+  ModelAPI_EventCreator::get()->sendUpdated(theResult, EVENT);
 }
 
 //******************************************************
index f7eac8c7fbd078a283c486aea96102cda1d8fc86..56b2a5d32435cd3ed88fb7f3d24dffac2bba0c8e 100644 (file)
@@ -139,6 +139,10 @@ MODELAPI_EXPORT std::shared_ptr<ModelAPI_CompositeFeature> compositeOwner(
  */
 MODELAPI_EXPORT std::shared_ptr<ModelAPI_ResultBody>
   bodyOwner(const std::shared_ptr<ModelAPI_Result>& theSub, const bool theRoot = false);
+
+/*! \returns Root result body. */
+MODELAPI_EXPORT std::shared_ptr<ModelAPI_ResultBody> mainBody(const std::shared_ptr<ModelAPI_ResultBody> theSubBody);
+
 /*!
  * Returns index of this result in parent (if parent exists, returned by bodyOwner)
  * \returns zero-base index, or -1 if not found
@@ -312,18 +316,31 @@ MODELAPI_EXPORT void showEdgesDirection(std::shared_ptr<ModelAPI_Result> theResu
 
 MODELAPI_EXPORT bool isShowEdgesDirection(std::shared_ptr<ModelAPI_Result> theResult);
 
-/*! Returns current edge thickness in the given result
-* \param theResult a result object
-* \return an egde thickness value or -1 if it was not defined
-*/
+/*! \returns -1, if edge thickness is not defined. */
 MODELAPI_EXPORT int getEdgeThickness(const std::shared_ptr<ModelAPI_Result>& theResult);
 
-/*! Set edge thickness for the given result
-* \param theResult a result object
-* \param theEdgeThickness edge thickness value
-*/
-MODELAPI_EXPORT void setEdgeThickness(std::shared_ptr<ModelAPI_Result> theResult,
-  int theEdgeThickness);
+/*! \returns -1, if edge thickness is not defined. */
+MODELAPI_EXPORT int getSubShapeEdgeThickness(const std::shared_ptr<ModelAPI_Result> theResult, const std::shared_ptr<GeomAPI_Shape> theSubShape);
+
+/*! \returns theResult subshapes with defined edge thickness.
+* \param theSubResults - true, to include subshapes of subresults. */
+MODELAPI_EXPORT void getSubShapesWithEdgeThickness(
+  const std::shared_ptr<ModelAPI_Result> theResult,
+  std::map<std::shared_ptr<GeomAPI_Shape>,int>& oShapes,
+  bool theGetSubResults = false
+);
+
+/*! \brief Removes edge thickness data of result subshapes. */
+MODELAPI_EXPORT void removeSubShapeEdgeThickness(const std::shared_ptr<ModelAPI_Result> theResult);
+
+MODELAPI_EXPORT void setEdgeThickness(std::shared_ptr<ModelAPI_Result> theResult, int theEdgeThickness);
+
+/*! \param theShape belongs to theResult. */
+MODELAPI_EXPORT void setSubShapeEdgeThickness(
+  std::shared_ptr<ModelAPI_Result> theResult,
+  std::shared_ptr<GeomAPI_Shape> theSubShape,
+  int theEdgeThickness
+);
 
 /*! Set flag to bring result in front of other results
 * \param[in] theResult a result object
index efc79517164858128f90545408d964e51ac29d05..0ed547e9562b572d78b3ce872be6dbc41da50fd6 100644 (file)
@@ -273,6 +273,9 @@ PartSet_Module::PartSet_Module(ModuleBase_IWorkshop* theWshop)
   Config_PropManager::registerProp("Visualization", "axis_arrow_size",
     "Trihedron arrows constant size", Config_Prop::IntSpin, "10");
 
+  Config_PropManager::registerProp("Visualization", "result_subshape_with_edge_thickness",
+    "Set edge thickness of subshape of result", Config_Prop::Boolean, "true");
+
   Config_PropManager::registerProp("Windows", "use_hide_faces_panel",
     "Use HideFaces panel in operations", Config_Prop::Boolean, "false");
 }
index 7a80eb0a9c8bcf3b5017ac250aa91fe19333591d..6e2ad3f7eb3768bc604c7454929afe46aa4eb896 100644 (file)
@@ -400,6 +400,46 @@ QObjectPtrList XGUI_Selection::selectedPresentations() const
   return aSelectedList;
 }
 
+QMap<ResultPtr, QList<GeomShapePtr>> XGUI_Selection::selectedObjectsAndSubObjects() const
+{
+  QMap<ResultPtr, QList<GeomShapePtr>> aSelectedObjects;
+
+  // Add all objects, which selected in Viewer
+  QList<ModuleBase_ViewerPrsPtr> aValues = getSelected(ModuleBase_ISelection::Viewer);
+  foreach(ModuleBase_ViewerPrsPtr aPrs, aValues)
+  {
+    ResultPtr aResult = std::dynamic_pointer_cast<ModelAPI_Result>(aPrs->object());
+    GeomShapePtr aShape = aPrs->shape();
+
+    aSelectedObjects[aResult].push_back(aShape);
+  }
+
+  // Add object, which selected in browser, but not selected in Viewer
+  QObjectPtrList anObjects = selectedObjects();
+  foreach(ObjectPtr anObject, anObjects)
+  {
+    ResultBodyPtr aResultBody = std::dynamic_pointer_cast<ModelAPI_ResultBody>(anObject);
+    if (!aResultBody.get())
+      continue;
+    GeomShapePtr aBodyShape = aResultBody->shape();
+
+    if (aSelectedObjects.contains(aResultBody))
+      continue;
+    bool isContains = false;
+    foreach(GeomShapePtr aCurShape, aSelectedObjects[aResultBody])
+    {
+      if (aCurShape->impl<TopoDS_Shape>().IsEqual(aBodyShape->impl<TopoDS_Shape>()))
+      {
+        isContains = true;
+        break;
+      }
+    }
+    if (!isContains)
+      aSelectedObjects[aResultBody].push_back(aBodyShape);
+  }
+  return aSelectedObjects;
+}
+
 //**************************************************************
 QModelIndexList XGUI_Selection::selectedIndexes() const
 {
index 9cf5ea963e68670632a3c326082643c7706cb5d0..4056cd11dbf15d55082cf6587caad99850958da6 100644 (file)
@@ -66,6 +66,9 @@ class XGUI_EXPORT XGUI_Selection : public ModuleBase_ISelection
   /// Returns list of currently selected results
   virtual QObjectPtrList selectedPresentations() const;
 
+  /// Returns selected results and their selected subobjects.
+  virtual QMap<ResultPtr, QList<GeomShapePtr>> selectedObjectsAndSubObjects() const;
+
   /// Returns list of currently selected QModelIndexes
   virtual QModelIndexList selectedIndexes() const;
 
index 3932c53a1cd44fe7aa49e3029c983e58f68a2c05..ff3149b52887d0dbc8b3dca957c426bf3d2c18b8 100644 (file)
@@ -1786,6 +1786,7 @@ ModuleBase_IViewer* XGUI_Workshop::salomeViewer() const
 void XGUI_Workshop::onContextMenuCommand(const QString& theId, bool isChecked)
 {
   QObjectPtrList anObjects = mySelector->selection()->selectedObjects();
+  QMap<ResultPtr, QList<GeomShapePtr>> aSelectedObjects = mySelector->selection()->selectedObjectsAndSubObjects();
   if (theId == "DELETE_CMD")
     deleteObjects();
   else if (theId == "CLEAN_HISTORY_CMD")
@@ -1814,7 +1815,7 @@ void XGUI_Workshop::onContextMenuCommand(const QString& theId, bool isChecked)
   else if (theId == "TRANSPARENCY_CMD")
     changeTransparency(anObjects);
   else if (theId == "EDGE_THICKNESS_CMD")
-    changeEdgeThickness(anObjects);
+    changeEdgeThickness(aSelectedObjects);
   else if (theId == "SHOW_CMD") {
     showObjects(anObjects, true);
     mySelector->updateSelectionBy(ModuleBase_ISelection::Browser);
@@ -2898,52 +2899,95 @@ void setEdgeThickness(int theThickness, const QObjectPtrList& theObjects)
 }
 
 //**************************************************************
-void XGUI_Workshop::changeEdgeThickness(const QObjectPtrList& theObjects)
+void XGUI_Workshop::changeEdgeThickness(const QMap<ResultPtr, QList<GeomShapePtr>>& theSelectedObjects)
 {
-  // 1. Get current value.
-  int currentValue = -1;
-  foreach(ObjectPtr object, theObjects) {
-    ResultPtr result = std::dynamic_pointer_cast<ModelAPI_Result>(object);
+  // 1. Find current thickness - thickness of AIS presentation.
+  // The objects are iterated until a first valid thickness is found.
+  int thickness;
+  const bool isSubShapeWithEdgeThickness = Config_PropManager::boolean("Visualization", "result_subshape_with_edge_thickness");
+  foreach(ResultPtr result, theSelectedObjects.keys()) {
     if (!result)
       continue;
 
-    currentValue = ModelAPI_Tools::getEdgeThickness(result);
-    if (currentValue < 0)
-      currentValue = getDefaultEdgeThickness();
+    foreach(GeomShapePtr shape, theSelectedObjects[result]) {
+      if (result->shape()->impl<TopoDS_Shape>().IsEqual(shape->impl<TopoDS_Shape>()) || !isSubShapeWithEdgeThickness)
+        thickness = ModelAPI_Tools::getEdgeThickness(result);
+      else if (!shape->isNull()) {
+        thickness = ModelAPI_Tools::getSubShapeEdgeThickness(result, shape);
+        if (thickness < 0)
+          thickness = ModelAPI_Tools::getEdgeThickness(result);
+      }
+
+      if (thickness < 0) {
+        AISObjectPtr anAISObj = myDisplayer->getAISObject(result);
+        if (anAISObj)
+          thickness = anAISObj->width();
+      }
+
+      if (thickness < 0)
+        thickness = getDefaultEdgeThickness();
+
+      if (thickness >= 0 || !isSubShapeWithEdgeThickness)
+        break;
+    }
 
-    if (currentValue > 0)
+    if (thickness >= 0)
       break;
   }
-  if (currentValue < 0)
+
+  if (thickness < 0)
     return;
 
   if (!abortAllOperations())
     return;
 
-  // 2. Show the dialog.
   const auto dialog = new XGUI_PropertyDialog(desktop());
   dialog->setWindowTitle(tr("Edge Thickness"));
   XGUI_EdgeThicknessWidget* edgeThicknessWidget = new XGUI_EdgeThicknessWidget(dialog);
   connect(edgeThicknessWidget, SIGNAL(thicknessValueChanged()), this, SLOT(onEdgeThicknessValueChanged()));
   dialog->setContent(edgeThicknessWidget);
-  aEdgeThicknessWidget->setValue(currentValue);
+  edgeThicknessWidget->setValue(thickness);
+
+  if (dialog->exec() != QDialog::Accepted)
+    return;
 
-  // 3. Abort the previous operation and start a new one.
+  // 3. Abort previous operation and start a new one.
   SessionPtr session = ModelAPI_Session::get();
   QString description = contextMenuMgr()->action("EDGE_THICKNESS_CMD")->text();
   session->startOperation(description.toStdString());
 
-  if (dialog->exec() == QDialog::Accepted) {
-    // 4. Set the value to all results.
-    currentValue = edgeThicknessWidget->getValue();
-    setEdgeThickness(currentValue, theObjects);
-    session->finishOperation();
-  } else {
-    session->abortOperation();
-    Events_Loop::loop()->flush(Events_Loop::eventByName(EVENT_OBJECT_TO_REDISPLAY));
+  // 4. Set new value to all results and subshapes of results.
+  int newThickness = edgeThicknessWidget->getValue();
+  foreach(ResultPtr result, theSelectedObjects.keys()) {
+    if (!result)
+      continue;
+
+    ResultBodyPtr bodyResult = std::dynamic_pointer_cast<ModelAPI_ResultBody>(result);
+    foreach(GeomShapePtr shape, theSelectedObjects[result]) {
+      if (result->shape()->impl<TopoDS_Shape>().IsEqual(shape->impl<TopoDS_Shape>()) || !isSubShapeWithEdgeThickness) {
+        if (result) {
+          // Change edge thickness for all sub-solids.
+          std::list<ResultPtr> allSubResults;
+          ModelAPI_Tools::allSubs(bodyResult, allSubResults);
+          for (auto itSubRes = allSubResults.begin(); itSubRes != allSubResults.end(); itSubRes++) {
+            ModelAPI_Tools::setEdgeThickness(*itSubRes, newThickness);
+          }
+
+          ModelAPI_Tools::setEdgeThickness(result, newThickness);
+        }
+
+        if (!isSubShapeWithEdgeThickness)
+          break;
+      }
+      else if (!shape->isNull())
+        ModelAPI_Tools::setSubShapeEdgeThickness(result, shape, newThickness);
+    }
   }
 
+  Events_Loop::loop()->flush(Events_Loop::eventByName(EVENT_OBJECT_TO_REDISPLAY));
+  session->finishOperation();
   updateCommandStatus();
+  myViewerProxy->update();
 }
 
 //**************************************************************
@@ -2955,8 +2999,7 @@ void XGUI_Workshop::onEdgeThicknessValueChanged()
 
   QObjectPtrList anObjects = mySelector->selection()->selectedObjects();
   setEdgeThickness(aWidget->getValue(), anObjects);
-  static const Events_ID kRedisplayEvent =
-    Events_Loop::loop()->eventByName(EVENT_OBJECT_TO_REDISPLAY);
+  static const Events_ID kRedisplayEvent = Events_Loop::loop()->eventByName(EVENT_OBJECT_TO_REDISPLAY);
   Events_Loop::loop()->flush(kRedisplayEvent);
 
   myViewerProxy->update();
index 213e09275a2fdf3bef8bb55fb1f991ef8afa70a8..09ea4c266d4cb192aa76499034ca0a29c4996381 100644 (file)
@@ -224,7 +224,7 @@ Q_OBJECT
   /// Change edge thickness of the results if it is possible.
   /// The operation is available for construction, body and group results.
   /// \param theObjects refers to selected objects.
-  void changeEdgeThickness(const QObjectPtrList& theObjects);
+  void changeEdgeThickness(const QMap<ResultPtr, QList<GeomShapePtr>>& theObjects);
 
   /// Change number of iso-lines for the given objects
   /// theObjects a list of selected objects
@@ -457,7 +457,7 @@ signals:
 
   /// Apply the current transparency value if preview in transparency dialog is switched on
   void onTransparencyValueChanged();
-  
+
   void onEdgeThicknessValueChanged();
 
  protected: