Salome HOME
oubli
[modules/shaper.git] / src / ModelAPI / ModelAPI_Tools.cpp
index 282a40de4e74c423ab8ba172ca5c74005c9c1706..84c5de685d83c7cbd6a5c7ba02dbd1f12639865b 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2014-2021  CEA/DEN, EDF R&D
+// Copyright (C) 2014-2022  CEA/DEN, EDF R&D
 //
 // This library is free software; you can redistribute it and/or
 // modify it under the terms of the GNU Lesser General Public
@@ -1169,6 +1169,31 @@ bool isShownIsoLines(std::shared_ptr<ModelAPI_Result> theResult)
   return false;
 }
 
+//******************************************************
+void showEdgesDirection(std::shared_ptr<ModelAPI_Result> theResult, bool theShow)
+{
+  if (!theResult.get())
+    return;
+
+  AttributeBooleanPtr aAttr = theResult->data()->boolean(ModelAPI_Result::SHOW_EDGES_DIRECTION_ID());
+  if (aAttr.get() != NULL) {
+    aAttr->setValue(theShow);
+  }
+}
+
+//******************************************************
+bool isShowEdgesDirection(std::shared_ptr<ModelAPI_Result> theResult)
+{
+  if (!theResult.get())
+    return false;
+
+  AttributeBooleanPtr aAttr = theResult->data()->boolean(ModelAPI_Result::SHOW_EDGES_DIRECTION_ID());
+  if (aAttr.get() != NULL) {
+    return aAttr->value();
+  }
+  return false;
+}
+
 //**************************************************************
 void setTransparency(ResultPtr theResult, double theTransparency)
 {
@@ -1441,4 +1466,127 @@ void findRandomColor(std::vector<int>& theValues, bool theReset)
 
 // LCOV_EXCL_STOP
 
+/// Returns name of the higher level feature (Part or feature of PartSet).
+static FeaturePtr topOwner(const FeaturePtr& theFeature)
+{
+  FeaturePtr anOwner = theFeature;
+  while (anOwner.get())
+  {
+    FeaturePtr aNextOwner = compositeOwner(anOwner);
+    if (aNextOwner.get())
+      anOwner = aNextOwner;
+    else
+      break;
+  }
+  if (anOwner->document() != ModelAPI_Session::get()->moduleDocument()) // the part-owner name
+    anOwner = findPartFeature(ModelAPI_Session::get()->moduleDocument(), anOwner->document());
+  return anOwner;
+}
+
+std::wstring validateMovement(const FeaturePtr& theAfter, const std::list<FeaturePtr> theMoved)
+{
+  std::wstring aResult;
+  if (theMoved.empty())
+    return aResult; // nothing to move, nothing to check, ok
+  DocumentPtr aDoc = theAfter.get() ? theAfter->document() : (*(theMoved.cbegin()))->document();
+  std::set<FeaturePtr> aMoved(theMoved.begin(), theMoved.end()); // fast access to moved
+  std::set<FeaturePtr> aPassed, aPassedMoved; // all features and all moved before the current one
+  std::set<FeaturePtr> aPassedAfter; // all passed features after theAfter
+  bool anAfterIsPassed = theAfter.get() == 0; // flag that iterator already passed theAfter
+  std::list<FeaturePtr> allFeat = aDoc->allFeatures();
+  for (std::list<FeaturePtr>::iterator aFeat = allFeat.begin(); aFeat != allFeat.end(); aFeat++)
+  {
+    if (!anAfterIsPassed)
+    {
+      if (aMoved.count(*aFeat))
+        aPassedMoved.insert(*aFeat);
+      else // check aPassedMoved are not referenced by the current feature
+        aPassed.insert(*aFeat);
+
+      anAfterIsPassed = *aFeat == theAfter;
+      if (anAfterIsPassed && !aPassedMoved.empty())
+      { // check dependencies of moved relatively to the passed
+        std::map<FeaturePtr, std::set<FeaturePtr> > aReferences;
+        findAllReferences(aPassedMoved, aReferences);
+        std::map<FeaturePtr, std::set<FeaturePtr> >::iterator aRefIter = aReferences.begin();
+        for (; aRefIter != aReferences.end(); aRefIter++)
+        {
+          if (aPassed.count(aRefIter->first))
+          {
+            aResult += topOwner(aRefIter->first)->name() + L" -> ";
+            // iterate all passed moved to check is it referenced by described feature or not
+            std::set<FeaturePtr>::iterator aMovedIter = aPassedMoved.begin();
+            for (; aMovedIter != aPassedMoved.end(); aMovedIter++)
+            {
+              std::map<FeaturePtr, std::set<FeaturePtr> > aPassedRefs;
+              std::set<FeaturePtr> aMovedOne;
+              aMovedOne.insert(*aMovedIter);
+              findAllReferences(aMovedOne, aPassedRefs);
+              if (aPassedRefs.count(aRefIter->first))
+                aResult += topOwner(*aMovedIter)->name() + L" ";
+            }
+            aResult += L"\n";
+          }
+        }
+      }
+    }
+    else // iteration after theAfter
+    {
+      if (aMoved.count(*aFeat)) { // check dependencies of moved relatively to ones after theAfter
+        std::map<FeaturePtr, std::set<FeaturePtr> > aReferences;
+        findAllReferences(aPassedAfter, aReferences);
+        bool aFoundRef = aReferences.find(*aFeat) != aReferences.end();
+        if (!aFoundRef && !(*aFeat)->results().empty()) // reference may be a feature in moved part
+        {
+          ResultPartPtr aFeatPart =
+            std::dynamic_pointer_cast<ModelAPI_ResultPart>((*aFeat)->firstResult());
+          if (aFeatPart.get() && aFeatPart->partDoc().get())
+          {
+            std::map<FeaturePtr, std::set<FeaturePtr> >::iterator aRef = aReferences.begin();
+            for (; aRef != aReferences.end() && !aFoundRef; aRef++)
+              aFoundRef = aRef->first->document() == aFeatPart->partDoc();
+          }
+        }
+
+        if (aFoundRef)
+        {
+          aResult += topOwner(*aFeat)->name() + L" -> ";
+          std::set<FeaturePtr> aReferencedCount; // to avoid duplicates in the displayed references
+          // iterate all passed after theAfter to check refers it described feature or not
+          FeaturePtr aFeatTop = topOwner(*aFeat);
+          std::set<FeaturePtr>::iterator aPassedIter = aPassedAfter.begin();
+          for (; aPassedIter != aPassedAfter.end(); aPassedIter++)
+          {
+            FeaturePtr aPassedTop = topOwner(*aPassedIter);
+            if (aReferencedCount.count(aPassedTop))
+              continue;
+            std::map<FeaturePtr, std::set<FeaturePtr> > aPassedRefs;
+            std::set<FeaturePtr> aPassedOne;
+            aPassedOne.insert(*aPassedIter);
+            findAllReferences(aPassedOne, aPassedRefs);
+            std::map<FeaturePtr, std::set<FeaturePtr> >::iterator aPRIter = aPassedRefs.begin();
+            for (; aPRIter != aPassedRefs.end(); aPRIter++)
+            {
+              FeaturePtr aPRTop = topOwner(aPRIter->first);
+              if (aPRIter->first == *aFeat || aPRIter->first == aFeatTop ||
+                  aPRTop == *aFeat || aPRTop == aFeatTop)
+              {
+                aResult += aPassedTop->name() + L" ";
+                aReferencedCount.insert(aPassedTop);
+                break;
+              }
+            }
+          }
+          aResult += L"\n";
+        }
+      }
+      else {
+        aPassedAfter.insert(*aFeat);
+      }
+    }
+
+  }
+  return aResult;
+}
+
 } // namespace ModelAPI_Tools