Salome HOME
updated copyright message
[modules/shaper.git] / src / PartSet / PartSet_Module.cpp
index 3999ae85e8778acfb834a6fbd78cec5f635ddcfd..c4dc84c15c976b86d033e98574fd530843e7a47e 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2014-2021  CEA/DEN, EDF R&D
+// Copyright (C) 2014-2023  CEA, EDF
 //
 // This library is free software; you can redistribute it and/or
 // modify it under the terms of the GNU Lesser General Public
@@ -69,6 +69,7 @@
 #include <ModuleBase_OperationDescription.h>
 #include <ModuleBase_ViewerPrs.h>
 #include <ModuleBase_ResultPrs.h>
+#include <ModuleBase_Preferences.h>
 
 #include <ModelAPI_ResultField.h>
 #include <ModelAPI_Object.h>
@@ -82,7 +83,9 @@
 #include <ModelAPI_Tools.h>
 #include <ModelAPI_ResultConstruction.h>
 #include <ModelAPI_AttributeIntArray.h>
+#include <ModelAPI_AttributeImage.h>
 #include <ModelAPI_ResultGroup.h>
+#include <ModelAPI_ResultParameter.h>
 
 #include <GeomDataAPI_Point2D.h>
 #include <GeomDataAPI_Point.h>
 #include <SketcherPrs_Tools.h>
 
 #include <Events_Loop.h>
+#include <Events_MessageBool.h>
 #include <Config_PropManager.h>
 #include <Config_Keywords.h>
 
-#include <AIS_Dimension.hxx>
 #include <AIS_InteractiveObject.hxx>
+#include <PrsDim_Dimension.hxx>
 #include <StdSelect_TypeOfFace.hxx>
 #include <TopoDS_Vertex.hxx>
 #include <TopoDS.hxx>
 #include <SelectMgr_ListIteratorOfListOfFilter.hxx>
 #include <Graphic3d_Texture2Dmanual.hxx>
 
-#ifdef HAVE_SALOME
-#include <OCCViewer_Utilities.h>
-#endif
+#include <SUIT_ResourceMgr.h>
+
+#include <Basics_OCCTVersion.hxx>
 
 #define FEATURE_ITEM_COLOR "0,0,225"
 
@@ -186,7 +190,9 @@ PartSet_Module::PartSet_Module(ModuleBase_IWorkshop* theWshop)
 
   Events_Loop* aLoop = Events_Loop::loop();
   aLoop->registerListener(this, Events_Loop::eventByName(EVENT_DOCUMENT_CHANGED));
+  aLoop->registerListener(this, Events_Loop::eventByName(EVENT_DOCUMENTS_CLOSED));
   aLoop->registerListener(this, Events_Loop::eventByName(EVENT_OBJECT_TO_REDISPLAY));
+  aLoop->registerListener(this, Events_Loop::eventByName(EVENT_FEATURE_LICENSE_VALID));
 
   registerSelectionFilter(SF_GlobalFilter, new PartSet_GlobalFilter(myWorkshop));
   registerSelectionFilter(SF_FilterInfinite, new PartSet_FilterInfinite(myWorkshop));
@@ -204,9 +210,10 @@ PartSet_Module::PartSet_Module(ModuleBase_IWorkshop* theWshop)
   Config_PropManager::registerProp("Visualization", "result_group_color", "Group color",
     Config_Prop::Color, ModelAPI_ResultGroup::DEFAULT_COLOR());
 
-  Config_PropManager::registerProp("Visualization",
-    ModelAPI_ResultConstruction::RESULT_COLOR_NAME(),
-    "Construction color", Config_Prop::Color, ModelAPI_ResultConstruction::DEFAULT_COLOR());
+  Config_PropManager::registerProp("Visualization", "result_construction_color",
+    "Construction color",
+    Config_Prop::Color,
+    ModelAPI_ResultConstruction::DEFAULT_COLOR());
 
   Config_PropManager::registerProp("Visualization", "result_part_color", "Part color",
     Config_Prop::Color, ModelAPI_ResultPart::DEFAULT_COLOR());
@@ -283,8 +290,16 @@ PartSet_Module::~PartSet_Module()
 void PartSet_Module::createFeatures()
 {
   ModuleBase_IModule::createFeatures();
+
+  // send signal to initialization plugin about the state of the preferences: to create part or not
+  bool aCreate = ModuleBase_Preferences::resourceMgr()->booleanValue(
+    ModuleBase_Preferences::GENERAL_SECTION, "create_init_part", true);
+  Events_MessageBool aCreateMsg(Events_Loop::eventByName(EVENT_CREATE_PART_ON_START), aCreate);
+  aCreateMsg.send();
+
   myRoot = new PartSet_RootNode();
   myRoot->setWorkshop(workshop());
+  ModuleBase_IModule::loadProprietaryPlugins();
 }
 
 
@@ -1140,10 +1155,9 @@ void PartSet_Module::onViewTransformed(int theTrsfType)
   Handle(V3d_Viewer) aV3dViewer = aContext->CurrentViewer();
   Handle(V3d_View) aView;
   double aScale = 0;
-  for (aV3dViewer->InitDefinedViews();
-       aV3dViewer->MoreDefinedViews();
-       aV3dViewer->NextDefinedViews()) {
-    Handle(V3d_View) aV = aV3dViewer->DefinedView();
+  V3d_ListOfView::Iterator aDefinedViews(aV3dViewer->DefinedViews());
+  for (; aDefinedViews.More(); aDefinedViews.Next()) {
+    Handle(V3d_View) aV = aDefinedViews.Value();
     double aS = aV->Scale();
     if (aS > aScale) {
       aScale = aS;
@@ -1172,7 +1186,7 @@ void PartSet_Module::onViewTransformed(int theTrsfType)
     foreach(AISObjectPtr aAIS, aPrsList) {
       Handle(AIS_InteractiveObject) aAisObj = aAIS->impl<Handle(AIS_InteractiveObject)>();
 #endif
-      Handle(AIS_Dimension) aDim = Handle(AIS_Dimension)::DownCast(aAisObj);
+      Handle(PrsDim_Dimension) aDim = Handle(PrsDim_Dimension)::DownCast(aAisObj);
       if (!aDim.IsNull()) {
         aDim->DimensionAspect()->ArrowAspect()->SetLength(aLen);
         aContext->Redisplay(aDim, false);
@@ -1404,13 +1418,46 @@ double getResultTransparency(const ResultPtr& theResult)
   return aTransparency;
 }
 
+static AttributeImagePtr findImage(const ObjectPtr& theResult)
+{
+  AttributeImagePtr anImageAttr;
+
+  if (theResult.get()) {
+    ResultBodyPtr aResultBody =
+      std::dynamic_pointer_cast<ModelAPI_ResultBody>(theResult);
+    if (aResultBody.get()) {
+      anImageAttr = aResultBody->data()->image(ModelAPI_ResultBody::IMAGE_ID());
+      if (!anImageAttr.get() || !anImageAttr->hasTexture()) {
+        // try to find an image attribute in parents
+        ObjectPtr aParent = theResult->document()->parent(theResult);
+        anImageAttr = findImage(aParent);
+      }
+    }
+  }
+
+  return anImageAttr;
+}
+
 //******************************************************
-void PartSet_Module::setTexture(const std::string & theTextureFile, const AISObjectPtr& thePrs)
+void PartSet_Module::setTexture(const AISObjectPtr& thePrs,
+                                const ResultPtr& theResult)
 {
-#ifdef HAVE_SALOME
+  ResultBodyPtr aResultBody =
+    std::dynamic_pointer_cast<ModelAPI_ResultBody>(theResult);
+  if (!aResultBody.get())
+    return;
+
+  AttributeImagePtr anImageAttr = findImage(theResult);
+  if (!anImageAttr.get() || !anImageAttr->hasTexture())
+    return;
+
+  int aWidth, aHeight;
+  std::string aFormat;
+  std::list<unsigned char> aByteList;
+  anImageAttr->texture(aWidth, aHeight, aByteList, aFormat);
+
   Handle(AIS_InteractiveObject) anAIS = thePrs->impl<Handle(AIS_InteractiveObject)>();
-  if (!anAIS.IsNull())
-  {
+  if (!anAIS.IsNull()) {
     /// set color to white and change material aspect,
     /// in order to keep a natural apect of the image.
     thePrs->setColor(255, 255, 255);
@@ -1427,11 +1474,25 @@ void PartSet_Module::setTexture(const std::string & theTextureFile, const AISObj
       myDrawer->ShadingAspect()->Aspect()->SetFrontMaterial(aMatAspect);
       myDrawer->ShadingAspect()->Aspect()->SetBackMaterial(aMatAspect);
 
-      Handle(Image_PixMap) aPixmap;
-      QPixmap px(theTextureFile.c_str());
-
-      if (!px.isNull() )
-        aPixmap = OCCViewer_Utilities::imageToPixmap( px.toImage());
+      //aPixmap = OCCViewer_Utilities::imageToPixmap( px.toImage());
+      Handle(Image_PixMap) aPixmap = new Image_PixMap();
+#if OCC_VERSION_LARGE < 0x07070000
+      aPixmap->InitTrash(Image_PixMap::ImgBGRA, aWidth, aHeight);
+#else
+      aPixmap->InitTrash(Image_Format_BGRA, aWidth, aHeight);
+#endif
+      std::list<unsigned char>::iterator aByteIter = aByteList.begin();
+      for (int aLine = 0; aLine < aHeight; ++aLine) {
+        // convert pixels from ARGB to renderer-compatible RGBA
+        for (int aByte = 0; aByte < aWidth; ++aByte) {
+          Image_ColorBGRA& aPixmapBytes = aPixmap->ChangeValue<Image_ColorBGRA>(aLine, aByte);
+
+          aPixmapBytes.b() = (Standard_Byte) *aByteIter++;
+          aPixmapBytes.g() = (Standard_Byte) *aByteIter++;
+          aPixmapBytes.r() = (Standard_Byte) *aByteIter++;
+          aPixmapBytes.a() = (Standard_Byte) *aByteIter++;
+        }
+      }
 
       anAISShape->Attributes()->ShadingAspect()->Aspect()->SetTextureMap
           (new Graphic3d_Texture2Dmanual(aPixmap));
@@ -1440,7 +1501,6 @@ void PartSet_Module::setTexture(const std::string & theTextureFile, const AISObj
       anAISShape->SetDisplayMode(AIS_Shaded);
     }
   }
-#endif
 }
 
 //******************************************************
@@ -1485,10 +1545,8 @@ void PartSet_Module::customizePresentation(const ObjectPtr& theObject,
       thePrs->setDeflection(getResultDeflection(aResult));
       thePrs->setTransparency(getResultTransparency(aResult));
 
-      /// set texture  parameters
-      if(aResult->hasTextureFile()) {
-        setTexture(aResult->getTextureFile(), thePrs);
-      }
+      /// set texture parameters, if any
+      setTexture(thePrs, aResult);
     }
     if (aFeature.get() && (aFeature->getKind() == SketchPlugin_Sketch::ID())) {
         thePrs->setWidth(2);
@@ -1546,8 +1604,9 @@ void PartSet_Module::addObjectBrowserMenu(QMenu* theMenu) const
   bool hasCompositeOwner = false;
   bool hasResultInHistory = false;
   bool hasFolder = false;
+  bool hasGroupsOnly = false;
   ModuleBase_Tools::checkObjects(aObjects, hasResult, hasFeature, hasParameter,
-                                  hasCompositeOwner, hasResultInHistory, hasFolder);
+                                  hasCompositeOwner, hasResultInHistory, hasFolder, hasGroupsOnly);
 
   ModuleBase_Operation* aCurrentOp = myWorkshop->currentOperation();
   if (aSelected == 1) {
@@ -1570,11 +1629,29 @@ void PartSet_Module::addObjectBrowserMenu(QMenu* theMenu) const
 
       } else if (aObject->document() == aMgr->activeDocument()) {
         if (hasParameter || hasFeature) {
-          myMenuMgr->action("EDIT_CMD")->setEnabled(true);
-          theMenu->addAction(myMenuMgr->action("EDIT_CMD"));
-          if (aCurrentOp && aFeature.get()) {
-            if (aCurrentOp->id().toStdString() == aFeature->getKind())
+
+          // disable Edit menu for groups under ImportResult feature
+          bool isEnabled = true;
+          if (aFeature.get() && aFeature->getKind() == "Group")
+          {
+            std::shared_ptr<ModelAPI_CompositeFeature> anOwner =
+              ModelAPI_Tools::compositeOwner (aFeature);
+
+            if (anOwner.get() && anOwner->getKind() == "ImportResult")
+            {
               myMenuMgr->action("EDIT_CMD")->setEnabled(false);
+              isEnabled = false;
+            }
+          }
+
+          if (isEnabled)
+          {
+            myMenuMgr->action("EDIT_CMD")->setEnabled(true);
+            theMenu->addAction(myMenuMgr->action("EDIT_CMD"));
+            if (aCurrentOp && aFeature.get()) {
+              if (aCurrentOp->id().toStdString() == aFeature->getKind())
+                myMenuMgr->action("EDIT_CMD")->setEnabled(false);
+            }
           }
         }
       }
@@ -1605,7 +1682,9 @@ if (aObjIndex.isValid()) { \
 //******************************************************
 void PartSet_Module::processEvent(const std::shared_ptr<Events_Message>& theMessage)
 {
-  if (theMessage->eventID() == Events_Loop::loop()->eventByName(EVENT_DOCUMENT_CHANGED)) {
+  if (theMessage->eventID() == Events_Loop::loop()->eventByName(EVENT_DOCUMENTS_CLOSED)) {
+    closeDocument();
+  } else if (theMessage->eventID() == Events_Loop::loop()->eventByName(EVENT_DOCUMENT_CHANGED)) {
     SessionPtr aMgr = ModelAPI_Session::get();
     if (!aMgr->hasModuleDocument()) // if document is closed, do not call the document creation
       return;
@@ -1709,6 +1788,12 @@ void PartSet_Module::processEvent(const std::shared_ptr<Events_Message>& theMess
         mySketchMgr->previewSketchPlane()->createSketchPlane(aSketch, myWorkshop);
     }
   }
+  else if (theMessage->eventID() == Events_Loop::loop()->eventByName(EVENT_FEATURE_LICENSE_VALID)) {
+    std::shared_ptr<ModelAPI_FeaturesLicenseValidMessage> aMsg =
+      std::dynamic_pointer_cast<ModelAPI_FeaturesLicenseValidMessage>(theMessage);
+    myFeaturesValidLicense.insert(aMsg->features().begin(), aMsg->features().end());
+    processProprietaryFeatures();
+  }
 }
 
 //******************************************************
@@ -1738,6 +1823,25 @@ void PartSet_Module::onTreeViewDoubleClick(const QModelIndex& theIndex)
     if (aPartFeature.get() && (aPartFeature->getKind() == PartSetPlugin_Part::ID())) {
       aPart = std::dynamic_pointer_cast<ModelAPI_ResultPart>(aPartFeature->firstResult());
     }
+    if (aObj.get())
+    {
+      if (!aPart.get() && aObj->groupName() == ModelAPI_ResultParameter::group())
+      {
+        QObjectPtrList aSelectedObjects = aWorkshop->objectBrowser()->selectedObjects();
+        FeaturePtr aFeature;
+        ResultParameterPtr aParam;
+        foreach(ObjectPtr aSelected, aSelectedObjects) {
+          aParam = std::dynamic_pointer_cast<ModelAPI_ResultParameter>(aSelected);
+          if (aParam.get())
+            break;
+        }
+        if (aParam.get())
+          aFeature = ModelAPI_Feature::feature(aParam);
+
+        if (aFeature.get())
+          editFeature(aFeature);
+      }
+    }
   }
   if (aPart.get()) { // if this is a part
     if (aPart->partDoc() == aMgr->activeDocument()) {
@@ -1898,28 +2002,54 @@ void PartSet_Module::enableCustomModes() {
 }
 
 //******************************************************
-void PartSet_Module::onConflictingConstraints()
+void PartSet_Module::onRemoveConflictingConstraints()
 {
-  const std::set<ObjectPtr>& aConstraints = myOverconstraintListener->conflictingObjects();
-  QObjectPtrList aObjectsList;
-  std::set<ObjectPtr>::const_iterator aIt;
-  for (aIt = aConstraints.cbegin(); aIt != aConstraints.cend(); aIt++) {
-    if (mySketchReentrantMgr->isLastAutoConstraint(*aIt))
-      aObjectsList.append(*aIt);
+  const std::set<ObjectPtr>& aConstraints = myOverconstraintListener->objectsToRemove();
+  std::set<ObjectPtr>::const_iterator anIt;
+
+  XGUI_Workshop* aWorkshop = getWorkshop();
+  XGUI_OperationMgr* anOpMgr = aWorkshop->operationMgr();
+
+  bool isAllowToNotify = ModuleBase_Preferences::resourceMgr()->booleanValue(SKETCH_TAB_NAME,
+    "notify_change_constraint");
+
+  if (isAllowToNotify) {
+    anIt = aConstraints.begin();
+    std::string aText("Conflict in constraints: \n");
+
+    for (; anIt != aConstraints.end(); anIt++)
+    {
+      ObjectPtr anObject = *anIt;
+      FeaturePtr aFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(anObject);
+      TCollection_AsciiString aStr(aFeature->name().c_str());
+      std::string aName(aStr.ToCString());
+      aText += aName + "\n";
+    }
+
+    XGUI_ModuleConnector* aConnector = dynamic_cast<XGUI_ModuleConnector*>(myWorkshop);
+    ModuleBase_Tools::warningAboutConflict(aConnector->desktop(),
+      aText);
   }
-  if (aObjectsList.size() > 0) {
-    XGUI_Workshop* aWorkshop = getWorkshop();
+
+  ModuleBase_Operation* anOp = anOpMgr->currentOperation();
+  if (sketchMgr()->isNestedSketchOperation(anOp)) {
+    std::set<FeaturePtr> aFeatures;
+    for (anIt = aConstraints.cbegin(); anIt != aConstraints.cend(); anIt++)
+      aFeatures.insert(ModelAPI_Feature::feature(*anIt));
+
+    ModelAPI_Tools::removeFeaturesAndReferences(aFeatures);
+  }
+  else {
+    QObjectPtrList anObjectsList;
+    for (anIt = aConstraints.cbegin(); anIt != aConstraints.cend(); anIt++)
+      anObjectsList.append(*anIt);
+
     QString aDescription = aWorkshop->contextMenuMgr()->action("DELETE_CMD")->text();
     ModuleBase_Operation* anOpAction = new ModuleBase_Operation(aDescription);
-    XGUI_OperationMgr* anOpMgr = aWorkshop->operationMgr();
-
-    ModuleBase_Operation* anOp = anOpMgr->currentOperation();
-    if (sketchMgr()->isNestedSketchOperation(anOp))
-      anOp->abort();
 
     anOpMgr->startOperation(anOpAction);
-    aWorkshop->deleteFeatures(aObjectsList);
+    aWorkshop->deleteFeatures(anObjectsList);
     anOpMgr->commitOperation();
-    ModuleBase_Tools::flushUpdated(sketchMgr()->activeSketch());
   }
+  ModuleBase_Tools::flushUpdated(sketchMgr()->activeSketch());
 }