# Versioning
# ===========
-SALOME_SETUP_VERSION(9.8.0)
+SALOME_SETUP_VERSION(9.8.0 DEVELOPMENT)
MESSAGE(STATUS "Building ${PROJECT_NAME} ${${PROJECT_NAME}_VERSION} from \"${${PROJECT_NAME}_GIT_SHA1}\"")
SET(COMPONENT_NAME SHAPER)
SHAPER preferences contains the following tabs:
+- :ref:`general_preferences`;
- :ref:`visualization_preferences`;
- :ref:`plugins_preferences`;
- :ref:`shortcuts_preferences`;
- :ref:`sketch_preferences`.
- :ref:`viewer_preferences`.
-Visualization tab is activated by default when **Preferences** dialog box is opened in the active SHAPER module.
+General tab is activated by default when **Preferences** dialog box is opened in the active SHAPER module.
Other tabs are activated by click on tab header.
+.. _general_preferences:
+
+General tab
+^^^^^^^^^^^
+
+This tab defines what parts to be activated and what elements to be visible after opening a study or a script.
+
+.. figure:: /images/general_preferences.png
+ :align: center
+
+ **Preferences**: General tab
+
+**Input fields**:
+
+- **Activate** relates to activation of part when opening a HDF document. Its could be one of the following:
+
+ - "Last part" - activate last part in the document (**default value**);
+ - "All parts" - activate all parts within the document;
+ - "No activation" - do not activate any part.
+
+- **Display** in "Opening a study". It specifies the shapes, which should be visualized when activating a part. It could be one of the following:
+
+ - "As stored in HDF" - display only the shapes visible before the document is saved (**default value**);
+ - "Last item in each folder" - show only the last result in each folder of the part: Constructions, Results, Groups, Fields;
+ - "All items" - show all shapes from each folder;
+ - "No visualization" - do not display any shape.
+
+- **Display** in "Launching a python script". It specifies the shapes, which should be visualized when loading a script using "File -> Load Script..." menu. It could be one of the following:
+
+ - "Last item in each folder" - show only the last result in each folder of the part: Constructions, Results, Groups, Fields;
+ - "All items" - show all shapes from each folder(**default value**);
+ - "No visualization" - do not display any shape.
+
.. _visualization_preferences:
Visualization tab
{
// Handle Python exception
// Reuse code from KERNEL module
-
typedef struct
{
PyObject_HEAD
for aResIndex in range(self.Part.size(aResultType)):
anObject = self.Part.object(aResultType, aResIndex)
aResult = model.objectToResult(anObject)
- # do nt export picture
- if aResult.hasTextureFile() is True:
+ # do not export picture
+ if aResult.hasTexture() is True:
continue
if not aResult is None:
if (not aResult.shape() or aResult.shape().isNull()) and isPart:
aResObject = aPartDoc.object(model.ModelAPI_ResultBody_group(), aResId)
aRes = model.objectToResult(aResObject)
#do not export images
- if aRes.hasTextureFile() is True:
+ if aRes.hasTexture() is True:
continue
aResFeatureId = str(aPartDoc.feature(aRes).data().featureId())
if aResFeatureId in aFeaturesIndices:
{
// TODO(spo): check that thePart is not empty
std::shared_ptr<ModelAPI_Feature> aFeature = thePart->addFeature(ConstructionAPI_Plane::ID());
- return PlanePtr(new ConstructionAPI_Plane(aFeature, theFace, theDistance, theIsReverse, theNbCopies));
+ return PlanePtr(new ConstructionAPI_Plane(aFeature, theFace, theDistance,
+ theIsReverse, theNbCopies));
}
//==================================================================================================
#
INCLUDE(Common)
+INCLUDE(UseQtExt)
SET(PROJECT_HEADERS
ExchangeAPI.h
ModelAPI
ModelHighAPI
GeomAlgoAPI
+ ${QT_LIBRARIES}
)
INCLUDE_DIRECTORIES(
${PROJECT_SOURCE_DIR}/src/ModelAPI
${PROJECT_SOURCE_DIR}/src/ModelHighAPI
${PROJECT_SOURCE_DIR}/src/GeomAlgoAPI
+ ${QT_INCLUDES}
)
# Plugin headers dependency
${PROJECT_SOURCE_DIR}/src/ExchangePlugin
)
+# additional preprocessor / compiler flags
+ADD_DEFINITIONS(${QT_DEFINITIONS})
+
#TODO(spo): is ${OpenCASCADE_DEFINITIONS} necessary?
ADD_DEFINITIONS(-DEXCHANGEAPI_EXPORTS ${OpenCASCADE_DEFINITIONS})
ADD_LIBRARY(ExchangeAPI SHARED ${PROJECT_SOURCES} ${PROJECT_HEADERS})
#include <ModelHighAPI_Tools.h>
//--------------------------------------------------------------------------------------
#include <ModelAPI_AttributeStringArray.h>
+#include <ModelAPI_AttributeImage.h>
#include <ModelAPI_Session.h>
#include <ModelAPI_Tools.h>
#include <GeomAlgoAPI_Tools.h>
//--------------------------------------------------------------------------------------
#include <algorithm>
+//--------------------------------------------------------------------------------------
+#include <QPixmap>
+#include <QDir>
+#include <QFile>
+#include <QFileInfo>
ExchangeAPI_Import::ExchangeAPI_Import(
const std::shared_ptr<ModelAPI_Feature> & theFeature)
std::string aPartName = theDumper.name(aBase->document());
std::string aFilePath =
- aBase->string(ExchangePlugin_Import_ImageFeature::FILE_PATH_ID())->value();
+ aBase->string(ExchangePlugin_Import_ImageFeature::FILE_PATH_ID())->value();
+
+ // store image into a new file near the dumped python script
+ ResultPtr aResult = aBase->firstResult();
+ std::string aNewImageDir = theDumper.getDumpDir();
+ if (aResult.get() && aResult->hasTexture()) {
+ // get image data
+ int aWidth, aHeight;
+ std::string aFormat;
+ std::list<unsigned char> aByteList;
+ AttributeImagePtr anImageAttr =
+ aResult->data()->image(ModelAPI_ResultBody::IMAGE_ID());
+ anImageAttr->texture(aWidth, aHeight, aByteList, aFormat);
+
+ // convert image data to QPixmap
+ uchar* arr = new uchar[aByteList.size()];
+ std::copy(aByteList.begin(), aByteList.end(), arr);
+ QImage image (arr, aWidth, aHeight, QImage::Format_ARGB32);
+ QPixmap pixmap = QPixmap::fromImage( image );
+
+ // get new file name
+ std::wstring aName = aBase->name();
+ std::string anImageName (aName.begin(), aName.end());
+ std::string aNewImageFile = anImageName + "." + aFormat;
+ QFileInfo aNewFileInfo (QDir(aNewImageDir.c_str()), aNewImageFile.c_str());
+ for (int ii = 1; QFile::exists(aNewFileInfo.absoluteFilePath()); ii++) {
+ // construct the new file name by adding the unique number
+ aNewImageFile = anImageName + "_" + std::to_string(ii) + "." + aFormat;
+ aNewFileInfo.setFile(QDir(aNewImageDir.c_str()), aNewImageFile.c_str());
+ }
+
+ // write image to a new file
+ if (pixmap.save(aNewFileInfo.absoluteFilePath())) {
+ // to dump new file name
+ aFilePath = aNewFileInfo.absoluteFilePath().toStdString();
+ }
+ delete [] arr;
+ }
theDumper << aBase << " = model.addImportImage(" << aPartName << ", \""
<< aFilePath << "\")" << std::endl;
INCLUDE(Common)
INCLUDE(UnitTest)
+INCLUDE(UseQtExt)
INCLUDE_DIRECTORIES(${PROJECT_SOURCE_DIR}/src/Events
${PROJECT_SOURCE_DIR}/src/Config
${PROJECT_SOURCE_DIR}/src/ConstructionPlugin
${PROJECT_SOURCE_DIR}/src/PartSetPlugin
${OpenCASCADE_INCLUDE_DIR}
+ ${QT_INCLUDES}
)
+# additional preprocessor / compiler flags
+ADD_DEFINITIONS(${QT_DEFINITIONS})
+
SET(PROJECT_HEADERS
ExchangePlugin.h
ExchangePlugin_Plugin.h
GeomAlgoAPI
GeomValidators
XAOShaper
+ ${QT_LIBRARIES}
)
# default dump approaches (will be set if not initialized)
#include <ModelAPI_Document.h>
#include <ModelAPI_Session.h>
#include <ModelAPI_ResultPart.h>
+#include <ModelAPI_Validator.h>
#include <ModelHighAPI_Dumper.h>
#include <Config_ModuleReader.h>
+#include <GeomAlgoAPI_Tools.h>
+
#ifdef EXCHANGEPLUGIN_DUMP_NAMING
static const bool THE_DUMP_NAMING = true;
#else
data()->addAttribute(EXPORT_VARIABLES_ID(), ModelAPI_AttributeBoolean::typeId());
+ data()->addAttribute(DUMP_DIR_ID(), ModelAPI_AttributeString::typeId());
+
// default values
boolean(TOPOLOGICAL_NAMING_DUMP_ID())->setValue(THE_DUMP_NAMING);
boolean(GEOMETRIC_DUMP_ID())->setValue(THE_DUMP_GEO);
boolean(WEAK_NAMING_DUMP_ID())->setValue(THE_DUMP_WEAK);
boolean(EXPORT_VARIABLES_ID())->setValue(false);
+
+ ModelAPI_Session::get()->validators()->registerNotObligatory(getKind(), DUMP_DIR_ID());
}
void ExchangePlugin_Dump::execute()
aDumper->addCustomStorage(aWeakNamingStorage);
}
+ // pass dump directory to the dumper
+ AttributeStringPtr aDumpDirAttr =
+ this->string(ExchangePlugin_Dump::DUMP_DIR_ID());
+ std::string aDumpDir;
+ if (aDumpDirAttr.get() && aDumpDirAttr->isInitialized())
+ aDumpDir = aDumpDirAttr->value();
+ else
+ aDumpDir = GeomAlgoAPI_Tools::File_Tools::path(theFileName);
+ aDumper->setDumpDir(aDumpDir);
+
if (!aDumper->process(aDoc, theFileName)) {
setError("An error occurred while dumping to " + theFileName);
} else {
static const std::string MY_DUMP_ID("Dump");
return MY_DUMP_ID;
}
+ /// attribute name of true dumping directory
+ inline static const std::string& DUMP_DIR_ID()
+ {
+ static const std::string MY_DUMP_DIR_ID("dump_dir");
+ return MY_DUMP_DIR_ID;
+ }
/// attribute name of file path
inline static const std::string& FILE_PATH_ID()
{
/// do not export pictures
ResultPtr aBodyContext =
std::dynamic_pointer_cast<ModelAPI_Result>(anAttrSelection->context());
- if(aBodyContext->hasTextureFile())
+ if (aBodyContext.get() && aBodyContext->hasTexture())
continue;
std::shared_ptr<GeomAPI_Shape> aCurShape = anAttrSelection->value();
return aStr.str();
}
-/// Returns true if something in selection is presented in the results list
-static bool isInResults(AttributeSelectionListPtr theSelection,
- const std::list<ResultPtr>& theResults,
- std::set<ResultPtr>& theCashedResults)
-{
- // collect all results into a cashed set
- if (theCashedResults.empty()) {
- std::list<ResultPtr>::const_iterator aRes = theResults.cbegin();
- for(; aRes != theResults.cend(); aRes++) {
- if (theCashedResults.count(*aRes))
- continue;
- else
- theCashedResults.insert(*aRes);
- if ((*aRes)->groupName() == ModelAPI_ResultBody::group()) {
- ResultBodyPtr aResBody = std::dynamic_pointer_cast<ModelAPI_ResultBody>(*aRes);
- std::list<ResultPtr> aResults;
- ModelAPI_Tools::allSubs(aResBody, aResults, false);
- for(std::list<ResultPtr>::iterator aR = aResults.begin(); aR != aResults.end(); aR++) {
- theCashedResults.insert(std::dynamic_pointer_cast<ModelAPI_ResultBody>(*aR));
- }
- } else if ((*aRes)->groupName() == ModelAPI_ResultPart::group()) { // all results of the part
- ResultPartPtr aResPart = std::dynamic_pointer_cast<ModelAPI_ResultPart>(*aRes);
- DocumentPtr aPartDoc = aResPart->partDoc();
- if (!aPartDoc.get() || !aPartDoc->isOpened()) { // document is not accessible
- return false;
- }
- int aBodyCount = aPartDoc->size(ModelAPI_ResultBody::group());
- for (int aBodyIndex = 0; aBodyIndex < aBodyCount; ++aBodyIndex) {
- ResultBodyPtr aResBody =
- std::dynamic_pointer_cast<ModelAPI_ResultBody>(
- aPartDoc->object(ModelAPI_ResultBody::group(), aBodyIndex));
- if (aResBody.get()) {
- theCashedResults.insert(aResBody);
- std::list<ResultPtr> aResults;
- ModelAPI_Tools::allSubs(aResBody, aResults, false);
- for(std::list<ResultPtr>::iterator aR = aResults.begin(); aR != aResults.end(); aR++) {
- theCashedResults.insert(std::dynamic_pointer_cast<ModelAPI_ResultBody>(*aR));
- }
- }
- }
- }
- }
- }
- // if context is in results, return true
- for(int a = 0; a < theSelection->size(); a++) {
- AttributeSelectionPtr anAttr = theSelection->value(a);
- ResultPtr aContext = anAttr->context();
- // check is it group selected for groups BOP
- if (aContext.get() && aContext->groupName() == ModelAPI_ResultGroup::group()) {
- // it is impossible by used results check which result is used in this group result,
- // so check the results shapes is it in results of this document or not
- FeaturePtr aSelFeature =
- std::dynamic_pointer_cast<ModelAPI_Feature>(theSelection->owner());
- if (!aSelFeature.get() || aSelFeature->results().empty())
- continue;
- GeomShapePtr aGroupResShape = aSelFeature->firstResult()->shape();
-
- std::set<ResultPtr>::iterator allResultsIter = theCashedResults.begin();
- for(; allResultsIter != theCashedResults.end(); allResultsIter++) {
- GeomShapePtr aResultShape = (*allResultsIter)->shape();
-
- GeomAPI_Shape::ShapeType aType =
- GeomAPI_Shape::shapeTypeByStr(theSelection->selectionType());
- GeomAPI_ShapeExplorer aGroupResExp(aGroupResShape, aType);
- for(; aGroupResExp.more(); aGroupResExp.next()) {
- if (aResultShape->isSubShape(aGroupResExp.current(), false))
- return true; // at least one shape of the group is in the used results
- }
- }
- }
- ResultBodyPtr aSelected = std::dynamic_pointer_cast<ModelAPI_ResultBody>(anAttr->context());
- if (!aSelected.get()) { // try to get selected feature and all its results
- FeaturePtr aContextFeature = anAttr->contextFeature();
- if (aContextFeature.get() && !aContextFeature->results().empty()) {
- const std::list<ResultPtr>& allResluts = aContextFeature->results();
- std::list<ResultPtr>::const_iterator aResIter = allResluts.cbegin();
- for(; aResIter != allResluts.cend(); aResIter++) {
- if (aResIter->get() && theCashedResults.count(*aResIter))
- return true;
- }
- }
- } else if (aSelected.get() && theCashedResults.count(aSelected))
- return true;
- }
- return false;
-}
-
void ExchangePlugin_ExportFeature::exportSTL(const std::string& theFileName)
{
// Get shape.
AttributeSelectionListPtr aSelection = selectionList(XAO_SELECTION_LIST_ID());
bool aIsSelection = aSelection->isInitialized() && aSelection->size() > 0;
if (aIsSelection) { // a mode for export to geom result by result
- for(int a = 0; a < aSelection->size(); a++) {
+ for (int a = 0; a < aSelection->size(); a++) {
AttributeSelectionPtr anAttr = aSelection->value(a);
ResultPtr aBodyContext =
std::dynamic_pointer_cast<ModelAPI_Result>(anAttr->context());
if (aBodyContext.get() && !aBodyContext->isDisabled() && aBodyContext->shape().get()) {
/// do not export pictures
- if(aBodyContext->hasTextureFile()){
+ if (aBodyContext->hasTexture()){
anExCludedIsImage = true;
continue;
}
AttributeSelectionListPtr aSelectionList =
aGroupFeature->selectionList("group_list");
- if (!isInResults(aSelectionList, aResults, allResultsCashed))// skip group not used in result
+ if (!ModelAPI_Tools::isInResults(aSelectionList,
+ aResults,
+ allResultsCashed))// skip group not used in result
continue;
// conversion of dimension
std::string aSelectionType = aSelectionList->selectionType();
bool isWholePart = aSelectionType == "part";
// skip field not used in results
- if (!isWholePart && !isInResults(aSelectionList, aResults, allResultsCashed))
+ if (!isWholePart &&
+ !ModelAPI_Tools::isInResults(aSelectionList, aResults, allResultsCashed))
continue;
// conversion of dimension
void ExchangePlugin_Import_Image::execute()
{
- AttributeStringPtr aFilePathAttr = string(ExchangePlugin_ImportBase::FILE_PATH_ID());
+ AttributeStringPtr aFilePathAttr = string(ExchangePlugin_ImportBase::FILE_PATH_ID());
std::string aFilePath = aFilePathAttr->value();
if (aFilePath.empty()) {
setError("File path is empty.");
#include <ModelAPI_AttributeString.h>
#include <ModelAPI_AttributeStringArray.h>
#include <ModelAPI_AttributeIntArray.h>
+#include <ModelAPI_AttributeImage.h>
#include <ModelAPI_AttributeTables.h>
#include <ModelAPI_AttributeBoolean.h>
#include <ModelAPI_AttributeInteger.h>
#include <ExchangePlugin_Tools.h>
+#include <QPixmap>
/*
* Request for initialization of data model of the feature: adding all attributes
void ExchangePlugin_Import_ImageFeature::importFile(const std::string& theFileName)
{
-
std::string anExtension = GeomAlgoAPI_Tools::File_Tools::extension(theFileName);
- std::string theTextureFileName = "";
- // Perform the import
std::string anError;
- std::shared_ptr<GeomAPI_Shape> aGeomShape;
- if (anExtension == "PNG" || anExtension == "GIF" ||
- anExtension == "TIFF" || anExtension == "JPE" ||
- anExtension == "JPG" || anExtension == "JPEG" ||
- anExtension == "BMP"|| anExtension == "PPM"
- ) {
- aGeomShape = ImageImport(theFileName, anError);
- if(anError == "")
- theTextureFileName = theFileName;
- } else {
- anError = "Unsupported format: " + anExtension;
- }
- // Check if shape is valid
- if (!anError.empty()) {
- setError("An error occurred while importing " + theFileName + ": " + anError);
- return;
- }
+ if (anExtension == "PNG" || anExtension == "GIF" ||
+ anExtension == "TIFF" || anExtension == "JPE" ||
+ anExtension == "JPEG" || anExtension == "JPG" ||
+ anExtension == "BMP" || anExtension == "PPM"
+ ) {
+ // Perform the import
+ QPixmap px (theFileName.c_str());
+ int aWidth = px.width();
+ int aHeight = px.height();
+ if (aWidth < 1 || aHeight < 1) {
+ setError("An error occurred while importing " + theFileName + ": invalid image");
+ return;
+ }
- // Pass the results into the model
- std::string anObjectName = GeomAlgoAPI_Tools::File_Tools::name(theFileName);
- data()->setName(Locale::Convert::toWString(anObjectName));
+ std::shared_ptr<GeomAPI_Shape> aGeomShape = ImageImport(aWidth, aHeight, anError);
+
+ // Check if shape is valid
+ if (!anError.empty()) {
+ setError("An error occurred while importing " + theFileName + ": " + anError);
+ return;
+ }
+
+ // Pass the results into the model
+ std::string anObjectName = GeomAlgoAPI_Tools::File_Tools::name(theFileName);
+ data()->setName(Locale::Convert::toWString(anObjectName));
+
+ auto resultBody = createResultBody(aGeomShape);
- auto resultBody = createResultBody(aGeomShape);
- resultBody->setTextureFile(theTextureFileName);
- setResult(resultBody);
+ // Store image in result body attribute
+ AttributeImagePtr anImageAttr = resultBody->data()->image(ModelAPI_ResultBody::IMAGE_ID());
+ if (anImageAttr.get() != NULL) {
+ QImage aQImage = px.toImage();
+ const uchar* aImageBytes = aQImage.bits();
+ std::list<unsigned char> aByteArray (aImageBytes, aImageBytes + aQImage.sizeInBytes());
+ anImageAttr->setTexture(aWidth, aHeight, aByteArray, anExtension);
+ }
+
+ setResult(resultBody);
+ }
+ else {
+ anError = "Unsupported format: " + anExtension;
+ setError("An error occurred while importing " + theFileName + ": " + anError);
+ }
}
assert(abs(dx-400) <= tol)
assert(abs(dy-258.5) <= tol)
assert(abs(dz-0) <= tol)
+assert(ImportImage_1.result().resultSubShapePair()[0].hasTexture())
+assert(Translation_1.result().resultSubShapePair()[0].hasTexture())
+assert(Scale_1.result().resultSubShapePair()[0].hasTexture())
#=============================================================================
# Change the image :
assert(abs(dx-448) <= tol)
assert(abs(dy-296.8) <= tol)
assert(abs(dz-0) <= tol)
+assert(ImportImage_1.result().resultSubShapePair()[0].hasTexture())
+assert(Translation_1.result().resultSubShapePair()[0].hasTexture())
+assert(Scale_1.result().resultSubShapePair()[0].hasTexture())
+assert(model.checkPythonDump())
# Close SALOME GUI
import salome_utils
assert(abs(dx-400) <= tol)
assert(abs(dy-258.5) <= tol)
assert(abs(dz-0) <= tol)
+assert(ImportImage_1.result().resultSubShapePair()[0].hasTexture())
+assert(Translation_1.result().resultSubShapePair()[0].hasTexture())
+assert(Scale_1.result().resultSubShapePair()[0].hasTexture())
#=============================================================================
# Change the image :
assert(abs(dx-560) <= tol)
assert(abs(dy-361.9) <= tol)
assert(abs(dz-0) <= tol)
+assert(ImportImage_1.result().resultSubShapePair()[0].hasTexture())
+assert(Translation_1.result().resultSubShapePair()[0].hasTexture())
+assert(Scale_1.result().resultSubShapePair()[0].hasTexture())
# Close SALOME GUI
--- /dev/null
+# Copyright (C) 2021 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
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+#
+
+import os, inspect
+from salome.shaper import model
+
+from PyQt5.Qt import QApplication
+
+import salome
+salome.salome_init_without_session()
+salome.salome_init(1)
+if QApplication.instance() is None:
+ app = QApplication([])
+
+from tempfile import TemporaryDirectory
+from ModelAPI import *
+
+data_dir = os.path.join(os.path.dirname(inspect.getfile(lambda: None)), "data")
+
+model.begin()
+partSet = model.moduleDocument()
+
+### Create Part
+Part_1 = model.addPart(partSet)
+Part_1_doc = Part_1.document()
+
+### Create ImportImage
+ImportImage_1 = model.addImportImage(Part_1_doc, os.path.join(data_dir, "1.jpg"))
+model.do()
+ImportImage_1.setName("drawing")
+ImportImage_1.result().setName("drawing")
+
+### Create Translation
+Translation_1 = model.addTranslation(Part_1_doc, [model.selection("FACE", "drawing")], startPoint = model.selection("VERTEX", "[drawing/Shape_1]e[drawing/Shape_4]e"), endPoint = model.selection("VERTEX", "PartSet/Origin"), keepSubResults = True)
+Translation_1.setName("translation")
+
+### Create Scale
+Scale_1 = model.addScale(Part_1_doc, [model.selection("FACE", "drawing")] , model.selection("VERTEX", "PartSet/Origin"), 0.5, keepSubResults = True)
+Scale_1.setName("scale")
+
+model.end()
+
+#=============================================================================
+# Tests :
+#=============================================================================
+model.checkResult(Scale_1, model, 1, [0], [0], [1], [4], [8])
+r=Scale_1.defaultResult()
+s=r.shape()
+dim=s.computeSize()
+dim=dim[1:]
+dx=abs(dim[3]-dim[0])
+dy=abs(dim[4]-dim[1])
+dz=abs(dim[5]-dim[2])
+tol=1e-06
+assert(abs(dx-400) <= tol)
+assert(abs(dy-258.5) <= tol)
+assert(abs(dz-0) <= tol)
+assert(ImportImage_1.result().resultSubShapePair()[0].hasTexture())
+assert(Translation_1.result().resultSubShapePair()[0].hasTexture())
+assert(Scale_1.result().resultSubShapePair()[0].hasTexture())
+
+aDr = objectToFeature(Part_1_doc.objectByName("Features", "drawing"))
+assert(aDr.firstResult().hasTexture())
+
+# check save/load document with an image
+with TemporaryDirectory() as tmp_dir:
+ aSession = ModelAPI_Session.get()
+ aFiles = StringList()
+ aSession.save(tmp_dir, aFiles)
+ aSession.closeAll()
+ assert(aSession.load(tmp_dir))
+ model.begin()
+ partSet = model.moduleDocument()
+ assert(partSet.size("Features") == 1)
+ aPart = objectToFeature(partSet.object("Features", 0))
+ aPartResult = modelAPI_ResultPart(aPart.results()[0])
+ aPartResult.activate()
+ aPartDoc = aPartResult.partDoc()
+ aSession.setActiveDocument(aPartDoc, True)
+ model.end()
+ aDr = objectToFeature(aPartDoc.objectByName("Features", "drawing"))
+ aTr = objectToFeature(aPartDoc.objectByName("Features", "translation"))
+ aSc = objectToFeature(aPartDoc.objectByName("Features", "scale"))
+ assert(aDr.firstResult().hasTexture())
+ assert(aTr.firstResult().hasTexture())
+ assert(aSc.firstResult().hasTexture())
+
+# Close SALOME GUI
+import salome_utils
+import subprocess
+port = salome_utils.getPortNumber()
+proc = subprocess.Popen(["killSalomeWithPort.py", "{}".format(port)])
SET(TEST_WITH_GUI_NAMES
TestImportImage_1.py
TestImportImage_2.py
+ TestImportImage_3.py
)
\ No newline at end of file
AttributeSelectionListPtr anObjects =
aBase->selectionList(FeaturesPlugin_ImportResult::OBJECTS());
+ CompositeFeaturePtr aCompositeFeature =
+ std::dynamic_pointer_cast<ModelAPI_CompositeFeature>(aBase);
+ int aNbOfSubs = aCompositeFeature->numberOfSubs();
+ for (int anIndex = 0; anIndex < aNbOfSubs; anIndex++) {
+ FeaturePtr aSubFeature = aCompositeFeature->subFeature(anIndex);
+ theDumper.name(aSubFeature, false, false, true); //mark as not to dump
+ }
+
theDumper << aBase << " = model.addImportResult("
<< aDocName << ", " << anObjects << ")" << std::endl;
}
#include "FeaturesPlugin_ImportResult.h"
#include <ModelAPI_AttributeSelectionList.h>
+#include <ModelAPI_AttributeRefList.h>
#include <ModelAPI_ResultBody.h>
+#include <ModelAPI_ResultGroup.h>
#include <ModelAPI_Session.h>
#include <ModelAPI_ResultPart.h>
+#include <ModelAPI_Tools.h>
#include <Events_InfoMessage.h>
+#include <GeomAPI_ShapeExplorer.h>
void FeaturesPlugin_ImportResult::initAttributes()
{
data()->addAttribute(OBJECTS(), ModelAPI_AttributeSelectionList::typeId());
+
+ AttributePtr aFeaturesAttribute =
+ data()->addAttribute(FEATURES_ID(),
+ ModelAPI_AttributeRefList::typeId());
+ aFeaturesAttribute->setIsArgument(false);
+
+ ModelAPI_Session::get()->validators()->registerNotObligatory(
+ getKind(), FEATURES_ID());
}
void FeaturesPlugin_ImportResult::execute()
{
+ // Process groups/fields
+ std::shared_ptr<ModelAPI_AttributeRefList> aRefListOfGroups =
+ std::dynamic_pointer_cast<ModelAPI_AttributeRefList>(data()->attribute(FEATURES_ID()));
+
+ // Remove previous groups/fields stored in RefList
+ //std::list<ObjectPtr> anGroupList = aRefListOfGroups->list();
+ //std::list<ObjectPtr>::iterator anGroupIt = anGroupList.begin();
+ const std::list<ObjectPtr>& anGroupList = aRefListOfGroups->list();
+ std::list<ObjectPtr>::const_iterator anGroupIt = anGroupList.begin();
+ for (; anGroupIt != anGroupList.end(); ++anGroupIt) {
+ std::shared_ptr<ModelAPI_Feature> aFeature = ModelAPI_Feature::feature(*anGroupIt);
+ if (aFeature)
+ document()->removeFeature(aFeature);
+ }
+
+ aRefListOfGroups->clear();
+
+ std::set<ResultPtr> aGlobalResultsCashed; // cash to speed up searching in all results selected
+ std::list<ResultGroupPtr> aGroups;
+
+ std::list<ResultPtr> aResults;
+
AttributeSelectionListPtr aList = selectionList(OBJECTS());
int aResultIndex = 0;
- for (int aSelIndex = 0; aSelIndex < aList->size(); aSelIndex++) {
+ for (int aSelIndex = 0; aSelIndex < aList->size(); aSelIndex++)
+ {
AttributeSelectionPtr aSel = aList->value(aSelIndex);
+
ResultPtr aContext = aSel->context();
- if (!aContext.get())
- continue;
- GeomShapePtr aShape = aContext->shape();
+ if (aContext.get())
+ aResults.push_back (aContext);
+ else
+ {
+ FeaturePtr aFeature = aSel->contextFeature();
+ if (aFeature.get())
+ {
+ const std::list<ResultPtr>& aResList = aFeature->results();
+ aResults.assign (aResList.begin(), aResList.end());
+ }
+ }
+ }
+
+ std::list<ResultPtr>::iterator aResIter = aResults.begin();
+ for(; aResIter != aResults.end(); aResIter++)
+ {
+ GeomShapePtr aShape = (*aResIter)->shape();
if (!aShape.get() || aShape->isNull())
continue;
+
std::shared_ptr<ModelAPI_ResultBody> aResultBody = document()->createBody(data(), aResultIndex);
aResultBody->store(aShape);
aResultBody->loadFirstLevel(aShape, "ImportResult");
setResult(aResultBody, aResultIndex++);
+
+ std::set<ResultPtr> allResultsCashed; // cash to speed up searching in all results selected
+ std::list<ResultPtr> aLocalResults;
+ aLocalResults.push_back (*aResIter);
+
+ std::list<DocumentPtr> aDocuments; /// documents of Parts
+ aDocuments.push_back ((*aResIter)->document());
+ std::list<DocumentPtr>::iterator aDoc = aDocuments.begin();
+ for(; aDoc != aDocuments.end(); aDoc++)
+ {
+ // groups
+ int aGroupCount = (*aDoc)->size(ModelAPI_ResultGroup::group());
+ for (int aGroupIndex = 0; aGroupIndex < aGroupCount; ++aGroupIndex)
+ {
+ ResultGroupPtr aResultGroup =
+ std::dynamic_pointer_cast<ModelAPI_ResultGroup>((*aDoc)->object(ModelAPI_ResultGroup::group(), aGroupIndex));
+
+ if (!aResultGroup.get() || !aResultGroup->shape().get())
+ continue;
+
+ FeaturePtr aGroupFeature = (*aDoc)->feature(aResultGroup);
+
+ AttributeSelectionListPtr aSelectionList =
+ aGroupFeature->selectionList("group_list");
+
+ if (!ModelAPI_Tools::isInResults(aSelectionList,
+ aLocalResults,
+ allResultsCashed))// skip group not used in result
+ continue;
+
+ aGlobalResultsCashed.insert (allResultsCashed.begin(), allResultsCashed.end());
+
+ //Check: may be this group already exists in the list
+ bool anIsFound = false;
+ std::list<ResultGroupPtr>::iterator anIter = aGroups.begin();
+ for (; anIter != aGroups.end(); anIter++)
+ {
+ if (*anIter == aResultGroup)
+ {
+ anIsFound = true;
+ break;
+ }
+ }
+ if (!anIsFound)
+ aGroups.push_back (aResultGroup);
+ }
+ }
+ }
+
+ std::list<ResultGroupPtr>::iterator anIter = aGroups.begin();
+ for (; anIter != aGroups.end(); anIter++)
+ {
+ DocumentPtr aDoc = (*anIter)->document();
+
+ FeaturePtr aGroupFeature = aDoc->feature(*anIter);
+
+ AttributeSelectionListPtr aSelectionList =
+ aGroupFeature->selectionList("group_list");
+
+ std::shared_ptr<ModelAPI_Feature> aNewGroupFeature = addFeature("Group");
+ aNewGroupFeature->data()->setName(aGroupFeature->name());
+
+ AttributeSelectionListPtr aNewSelectionList = aNewGroupFeature->selectionList("group_list");
+ aNewSelectionList->setSelectionType (aSelectionList->selectionType());
+ GeomAPI_Shape::ShapeType aTypeOfShape = GeomAPI_Shape::shapeTypeByStr (aSelectionList->selectionType());
+
+ for (int aLocalSelIndex = 0; aLocalSelIndex < aSelectionList->size(); aLocalSelIndex++) {
+
+ AttributeSelectionPtr aLocalSel = aSelectionList->value(aLocalSelIndex);
+ ResultPtr aLocalContext = aLocalSel->context();
+ ResultGroupPtr aLocalGroup = std::dynamic_pointer_cast<ModelAPI_ResultGroup> (aLocalContext);
+ if (aLocalGroup.get())
+ {
+ GeomShapePtr aLocalShape = aGroupFeature->firstResult()->shape();
+ GeomAPI_ShapeExplorer anExplo (aLocalShape, aTypeOfShape);
+ for (; anExplo.more(); anExplo.next())
+ {
+ GeomShapePtr anExploredShape = anExplo.current();
+ std::set<ResultPtr>::iterator aResultIter = aGlobalResultsCashed.begin();
+ for (; aResultIter != aGlobalResultsCashed.end(); aResultIter++)
+ {
+ GeomShapePtr aCashedShape = (*aResultIter)->shape();
+ if (aCashedShape->isSubShape(anExploredShape))
+ aNewSelectionList->append((*aResultIter), anExploredShape);
+ }
+ }
+ break;
+ }
+ else
+ {
+ GeomShapePtr aLocalShape = aLocalSel->value();
+
+ if (aLocalContext.get() && aGlobalResultsCashed.count(aLocalContext))
+ aNewSelectionList->append(aLocalContext, aLocalShape);
+ }
+ }
}
+
removeResults(aResultIndex);
}
}
return true;
}
+
+//============================================================================
+std::shared_ptr<ModelAPI_Feature> FeaturesPlugin_ImportResult::addFeature(
+ std::string theID)
+{
+ std::shared_ptr<ModelAPI_Feature> aNew = document()->addFeature(theID, false);
+ if (aNew)
+ data()->reflist(FEATURES_ID())->append(aNew);
+ // set as current also after it becomes sub to set correctly enabled for other subs
+ //document()->setCurrentFeature(aNew, false);
+ return aNew;
+}
+
+//=================================================================================================
+int FeaturesPlugin_ImportResult::numberOfSubs(bool /*forTree*/) const
+{
+ return data()->reflist(FEATURES_ID())->size(true);
+}
+
+//=================================================================================================
+std::shared_ptr<ModelAPI_Feature> FeaturesPlugin_ImportResult::subFeature(const int theIndex,
+ bool /*forTree*/)
+{
+ ObjectPtr anObj = data()->reflist(FEATURES_ID())->object(theIndex, false);
+ FeaturePtr aRes = std::dynamic_pointer_cast<ModelAPI_Feature>(anObj);
+ return aRes;
+}
+
+//=================================================================================================
+int FeaturesPlugin_ImportResult::subFeatureId(const int theIndex) const
+{
+ std::shared_ptr<ModelAPI_AttributeRefList> aRefList = std::dynamic_pointer_cast<
+ ModelAPI_AttributeRefList>(data()->attribute(FEATURES_ID()));
+ std::list<ObjectPtr> aFeatures = aRefList->list();
+ std::list<ObjectPtr>::const_iterator anIt = aFeatures.begin();
+ int aResultIndex = 1; // number of the counted (created) features, started from 1
+ int aFeatureIndex = -1; // number of the not-empty features in the list
+ for (; anIt != aFeatures.end(); anIt++) {
+ if (anIt->get())
+ aFeatureIndex++;
+ if (aFeatureIndex == theIndex)
+ break;
+ aResultIndex++;
+ }
+ return aResultIndex;
+}
+
+//=================================================================================================
+bool FeaturesPlugin_ImportResult::isSub(ObjectPtr theObject) const
+{
+ // check is this feature of result
+ FeaturePtr aFeature = ModelAPI_Feature::feature(theObject);
+ if (aFeature)
+ return data()->reflist(FEATURES_ID())->isInList(aFeature);
+ return false;
+}
+
+//=================================================================================================
+void FeaturesPlugin_ImportResult::removeFeature(
+ std::shared_ptr<ModelAPI_Feature> theFeature)
+{
+ if (!data()->isValid())
+ return;
+ AttributeRefListPtr aList = reflist(FEATURES_ID());
+ aList->remove(theFeature);
+}
#include "FeaturesPlugin.h"
-#include <ModelAPI_Feature.h>
+#include <ModelAPI_CompositeFeature.h>
#include <ModelAPI_AttributeValidator.h>
/// \class FeaturesPlugin_ImportResult
/// \brief The Import Result feature allows the user to import one or several results
/// from another Part.
-class FeaturesPlugin_ImportResult : public ModelAPI_Feature
+class FeaturesPlugin_ImportResult : public ModelAPI_CompositeFeature
{
public:
/// Feature kind.
static const std::string MY_ID("ImportResult");
return MY_ID;
}
+ /// All features (list of references)
+ inline static const std::string& FEATURES_ID()
+ {
+ static const std::string MY_FEATURES_ID("Features");
+ return MY_FEATURES_ID;
+ }
/// \return the kind of a feature.
FEATURESPLUGIN_EXPORT virtual const std::string& getKind()
/// Request for initialization of data model of the feature: adding all attributes.
FEATURESPLUGIN_EXPORT virtual void initAttributes();
+ /// Appends a feature
+ FEATURESPLUGIN_EXPORT virtual std::shared_ptr<ModelAPI_Feature> addFeature(std::string theID);
+
+ /// \return the number of sub-elements.
+ FEATURESPLUGIN_EXPORT virtual int numberOfSubs(bool forTree = false) const;
+
+ /// \return the sub-feature by zero-base index.
+ FEATURESPLUGIN_EXPORT virtual
+ std::shared_ptr<ModelAPI_Feature> subFeature(const int theIndex, bool forTree = false);
+
+ /// \return the sub-feature unique identifier in this composite feature by zero-base index.
+ FEATURESPLUGIN_EXPORT virtual int subFeatureId(const int theIndex) const;
+
+ /// \return true if feature or result belong to this composite feature as subs.
+ FEATURESPLUGIN_EXPORT virtual bool isSub(ObjectPtr theObject) const;
+
+ /// This method to inform that sub-feature is removed and must be removed from the internal data
+ /// structures of the owner (the remove from the document will be done outside just after).
+ FEATURESPLUGIN_EXPORT virtual void removeFeature(std::shared_ptr<ModelAPI_Feature> theFeature);
+
/// Use plugin manager for features creation.
FeaturesPlugin_ImportResult() {}
};
GeomAPI_ShapeHierarchy anObjects;
std::list<ResultPtr> aParts;
- std::string theTextureFile;
- if (!FeaturesPlugin_Tools::shapesFromSelectionList(
- anObjectsSelList, isKeepSubShapes, anObjects, aParts, theTextureFile))
+ ResultPtr aTextureSource;
+ if (!FeaturesPlugin_Tools::shapesFromSelectionList
+ (anObjectsSelList, isKeepSubShapes, anObjects, aParts, aTextureSource))
return;
// Parameters of rotation.
ResultBodyPtr aResultBody = document()->createBody(data(), aResultIndex);
ModelAPI_Tools::loadModifiedShapes(aResultBody, anOriginalShapes, ListOfShape(),
aMakeShapeList, *anIt, "Rotated");
- aResultBody->setTextureFile(theTextureFile);
+ // Copy image data, if any
+ ModelAPI_Tools::copyImageAttribute(aTextureSource, aResultBody);
setResult(aResultBody, aResultIndex++);
}
GeomAPI_ShapeHierarchy anObjects;
std::list<ResultPtr> aParts;
- std::string theTextureFile;
- if (!FeaturesPlugin_Tools::shapesFromSelectionList(
- anObjectsSelList, isKeepSubShapes, anObjects, aParts, theTextureFile))
+ ResultPtr aTextureSource;
+ if (!FeaturesPlugin_Tools::shapesFromSelectionList
+ (anObjectsSelList, isKeepSubShapes, anObjects, aParts, aTextureSource))
return;
std::shared_ptr<GeomAPI_Dir> aFirstDir, aSecondDir;
ResultBodyPtr aResultBody = document()->createBody(data(), aResultIndex);
ModelAPI_Tools::loadModifiedShapes(aResultBody, anOriginalShapes, ListOfShape(),
aMakeShapeList, *anIt, "Translated");
- aResultBody->setTextureFile(theTextureFile);
+ // Copy image data, if any
+ ModelAPI_Tools::copyImageAttribute(aTextureSource, aResultBody);
setResult(aResultBody, aResultIndex++);
}
// Getting objects.
GeomAPI_ShapeHierarchy anObjects;
std::list<ResultPtr> aParts;
- std::string theTextureFile;
+ ResultPtr aTextureSource;
AttributeSelectionListPtr anObjectsSelList = selectionList(OBJECTS_LIST_ID());
- if (!FeaturesPlugin_Tools::shapesFromSelectionList(
- anObjectsSelList, isKeepSubShapes, anObjects, aParts, theTextureFile))
+ if (!FeaturesPlugin_Tools::shapesFromSelectionList
+ (anObjectsSelList, isKeepSubShapes, anObjects, aParts, aTextureSource))
return;
// Verify the start shape
ResultBodyPtr aResultBody = document()->createBody(data(), aResultIndex);
ModelAPI_Tools::loadModifiedShapes(aResultBody, anOriginalShapes, ListOfShape(),
aMakeShapeList, *anIt, "Placed");
- aResultBody->setTextureFile(theTextureFile);
+ // Copy image data, if any
+ ModelAPI_Tools::copyImageAttribute(aTextureSource, aResultBody);
setResult(aResultBody, aResultIndex++);
}
// Getting objects.
GeomAPI_ShapeHierarchy anObjects;
std::list<ResultPtr> aParts;
- std::string theTextureFile;
+ ResultPtr aTextureSource;
AttributeSelectionListPtr anObjSelList = selectionList(OBJECTS_LIST_ID());
if (!FeaturesPlugin_Tools::shapesFromSelectionList(
- anObjSelList, isKeepSubShapes, anObjects, aParts, theTextureFile))
+ anObjSelList, isKeepSubShapes, anObjects, aParts, aTextureSource))
return;
std::string anError;
ResultBodyPtr aResultBody = document()->createBody(data(), aResultIndex);
ModelAPI_Tools::loadModifiedShapes(aResultBody, anOriginalShapes, ListOfShape(),
aMakeShapeList, *anIt, "Rotated");
- aResultBody->setTextureFile(theTextureFile);
+ // Copy image data, if any
+ ModelAPI_Tools::copyImageAttribute(aTextureSource, aResultBody);
setResult(aResultBody, aResultIndex++);
}
// Getting objects.
GeomAPI_ShapeHierarchy anObjects;
std::list<ResultPtr> aParts;
- std::string theTextureFile;
+ ResultPtr aTextureSource;
AttributeSelectionListPtr anObjSelList = selectionList(OBJECTS_LIST_ID());
if (!FeaturesPlugin_Tools::shapesFromSelectionList(
- anObjSelList, isKeepSubShapes, anObjects, aParts, theTextureFile))
+ anObjSelList, isKeepSubShapes, anObjects, aParts, aTextureSource))
return;
// Getting the center point
ResultBodyPtr aResultBody = document()->createBody(data(), aResultIndex);
ModelAPI_Tools::loadModifiedShapes(aResultBody, anOriginalShapes, ListOfShape(),
aMakeShapeList, *anIt, "Scaled");
- aResultBody->setTextureFile(theTextureFile);
+ // Copy image data, if any
+ ModelAPI_Tools::copyImageAttribute(aTextureSource, aResultBody);
setResult(aResultBody, aResultIndex++);
}
// Getting objects.
GeomAPI_ShapeHierarchy anObjects;
std::list<ResultPtr> aParts;
- std::string theTextureFile;
+ ResultPtr aTextureSource;
AttributeSelectionListPtr anObjSelList = selectionList(OBJECTS_LIST_ID());
if (!FeaturesPlugin_Tools::shapesFromSelectionList(
- anObjSelList, isKeepSubShapes, anObjects, aParts, theTextureFile))
+ anObjSelList, isKeepSubShapes, anObjects, aParts, aTextureSource))
return;
// Getting the center point
ResultBodyPtr aResultBody = document()->createBody(data(), aResultIndex);
ModelAPI_Tools::loadModifiedShapes(aResultBody, anOriginalShapes, ListOfShape(),
aMakeShapeList, *anIt, "Scaled");
- aResultBody->setTextureFile(theTextureFile);
+ // Copy image data, if any
+ ModelAPI_Tools::copyImageAttribute(aTextureSource, aResultBody);
setResult(aResultBody, aResultIndex++);
}
const std::shared_ptr<GeomAlgoAPI_MakeShapeList>& theAlgo,
const std::list<std::shared_ptr<GeomAPI_Shape> >& theOriginalShapes,
std::shared_ptr<GeomAPI_Shape> theTargetShape, int& theResultIndex,
- std::string & theTextureFile)
+ const ResultPtr& theTextureSource)
{
// Store and name the result.
ResultBodyPtr aResultBody = document()->createBody(data(), theResultIndex);
ModelAPI_Tools::loadModifiedShapes(aResultBody, theOriginalShapes, ListOfShape(),
theAlgo, theTargetShape, "Symmetried");
- aResultBody->setTextureFile(theTextureFile);
+ // Copy image data, if any
+ ModelAPI_Tools::copyImageAttribute(theTextureSource, aResultBody);
setResult(aResultBody, theResultIndex++);
}
// Getting objects.
GeomAPI_ShapeHierarchy anObjects;
std::list<ResultPtr> aParts;
- std::string theTextureFile;
+ ResultPtr aTextureSource;
AttributeSelectionListPtr anObjSelList = selectionList(OBJECTS_LIST_ID());
if (!FeaturesPlugin_Tools::shapesFromSelectionList(
- anObjSelList, isKeepSubShapes, anObjects, aParts, theTextureFile))
+ anObjSelList, isKeepSubShapes, anObjects, aParts, aTextureSource))
return;
std::string anError;
ListOfShape aTopLevel;
anObjects.topLevelObjects(aTopLevel);
for (ListOfShape::iterator anIt = aTopLevel.begin(); anIt != aTopLevel.end(); ++anIt)
- buildResult(aMakeShapeList, anOriginalShapes, *anIt, aResultIndex, theTextureFile);
+ buildResult(aMakeShapeList, anOriginalShapes, *anIt, aResultIndex, aTextureSource);
// Remove the rest results if there were produced in the previous pass.
removeResults(aResultIndex);
#include <FeaturesPlugin.h>
#include <ModelAPI_Feature.h>
+#include <ModelAPI_Result.h>
class GeomAPI_Trsf;
class GeomAlgoAPI_MakeShapeList;
void buildResult(const std::shared_ptr<GeomAlgoAPI_MakeShapeList>& theAlgo,
const std::list<std::shared_ptr<GeomAPI_Shape> >& theOriginalShapes,
std::shared_ptr<GeomAPI_Shape> theTargetShape,
- int& theResultIndex, std::string &theTextureFile);
+ int& theResultIndex,
+ const ResultPtr& theTextureSource);
/// Create new result for the given part and transformation
void buildResult(std::shared_ptr<ModelAPI_ResultPart> theOriginal,
const std::shared_ptr<ModelAPI_AttributeSelectionList> theSelectionList,
const bool theStoreFullHierarchy,
GeomAPI_ShapeHierarchy& theHierarchy,
- std::list<ResultPtr>& theParts, std::string &theTextureFile)
+ std::list<ResultPtr>& theParts, ResultPtr& theTextureSource)
{
int aSize = theSelectionList->size();
- if(aSize == 1)
- {
+ if (aSize == 1) {
auto anObjectAttr = theSelectionList->value(0);
- if(anObjectAttr.get())
- {
+ if (anObjectAttr.get()) {
FeaturePtr aFeature = anObjectAttr->contextFeature();
- if(aFeature.get() && aFeature->results().size() == 1)
- {
- theTextureFile = aFeature->firstResult()->getTextureFile();
+ if (aFeature.get() && aFeature->results().size() == 1) {
+ theTextureSource = aFeature->firstResult();
}
- else
- {
- if(!aFeature.get())
- {
- auto aResult = anObjectAttr->context();
- if(aResult.get())
- {
- theTextureFile = aResult->getTextureFile();
+ else {
+ if (!aFeature.get()) {
+ auto aResult = anObjectAttr->context();
+ if (aResult.get()) {
+ theTextureSource = aResult;
}
}
}
const std::shared_ptr<ModelAPI_AttributeSelectionList> theSelectionList,
const bool theStoreFullHierarchy,
GeomAPI_ShapeHierarchy& theHierarchy,
- std::list<ResultPtr>& theParts, std::string& theTextureFile);
+ std::list<ResultPtr>& theParts,
+ ResultPtr& theTextureSource);
};
#endif /* FeaturesPlugin_Tools_H_ */
// Getting objects.
GeomAPI_ShapeHierarchy anObjects;
std::list<ResultPtr> aParts;
- std::string theTextureFile;
+ ResultPtr aTextureSource;
AttributeSelectionListPtr anObjectsSelList = selectionList(OBJECTS_LIST_ID());
- if (!FeaturesPlugin_Tools::shapesFromSelectionList(
- anObjectsSelList, isKeepSubShapes, anObjects, aParts, theTextureFile))
+ if (!FeaturesPlugin_Tools::shapesFromSelectionList
+ (anObjectsSelList, isKeepSubShapes, anObjects, aParts, aTextureSource))
return;
std::string anError;
ResultBodyPtr aResultBody = document()->createBody(data(), aResultIndex);
ModelAPI_Tools::loadModifiedShapes(aResultBody, anOriginalShapes, ListOfShape(),
aMakeShapeList, *anIt, "Translated");
- aResultBody->setTextureFile(theTextureFile);
+ // Copy image data, if any
+ ModelAPI_Tools::copyImageAttribute(aTextureSource, aResultBody);
setResult(aResultBody, aResultIndex++);
}
theError = "Error: Not all selected shapes are sub-shapes of solids.";
return false;
}
+
+ ResultBodyPtr aResRootPtr = ModelAPI_Tools::bodyOwner(aContext, true);
+ if (aResRootPtr.get() && aResRootPtr->shape().get()) {
+ if (!aResRootPtr->shape()->isCollectionOfSolids()) {
+ theError = "Error: The main shape should be a collection of solids";
+ return false;
+ }
+ }
}
return true;
--- /dev/null
+# Copyright (C) 2021 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
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+#
+
+from salome.shaper import model
+
+model.begin()
+partSet = model.moduleDocument()
+
+### Create Part 1
+Part_1 = model.addPart(partSet)
+Part_1_doc = Part_1.document()
+Box_1 = model.addBox(Part_1_doc, 10, 10, 10)
+### Create Groups
+Group_1 = model.addGroup(Part_1_doc, "Faces", [model.selection("FACE", "Box_1_1/Left"), model.selection("FACE", "Box_1_1/Top")])
+Group_2 = model.addGroup(Part_1_doc, "Faces", [model.selection("FACE", "Box_1_1/Front"), model.selection("FACE", "Box_1_1/Top")])
+GroupAddition_1 = model.addGroupAddition(Part_1_doc, [model.selection("COMPOUND", "Group_1"), model.selection("COMPOUND", "Group_2")])
+
+model.do()
+
+### Create Part 2
+Part_2 = model.addPart(partSet)
+Part_2_doc = Part_2.document()
+ImportResult_1 = model.addImportResult(Part_2_doc, [model.selection("SOLID", "Part_1/Box_1_1")])
+
+model.end()
+
+from GeomAPI import *
+from ModelAPI import *
+import math
+
+TOLERANCE = 1.e-7
+
+assert(ImportResult_1.feature().error() == "")
+model.testNbResults(ImportResult_1, 1)
+model.testNbSubResults(ImportResult_1, [0])
+model.testNbSubShapes(ImportResult_1, GeomAPI_Shape.SOLID, [1])
+model.testNbSubShapes(ImportResult_1, GeomAPI_Shape.FACE, [6])
+model.testNbSubShapes(ImportResult_1, GeomAPI_Shape.EDGE, [24])
+model.testNbSubShapes(ImportResult_1, GeomAPI_Shape.VERTEX, [48])
+model.testResultsVolumes(ImportResult_1, [1000])
+model.testResultsAreas(ImportResult_1, [600])
+
+# check groups are the same in both parts
+assert(Part_1_doc.size("Groups") == Part_2_doc.size("Groups"))
+for ind in range(0, Part_1_doc.size("Groups")):
+ res1 = objectToResult(Part_1_doc.object("Groups", ind))
+ res2 = objectToResult(Part_2_doc.object("Groups", ind))
+ assert(res1 is not None)
+ assert(res2 is not None)
+ res1It = GeomAPI_ShapeExplorer(res1.shape(), GeomAPI_Shape.FACE)
+ res2It = GeomAPI_ShapeExplorer(res2.shape(), GeomAPI_Shape.FACE)
+ while res1It.more() and res2It.more():
+ shape1 = res1It.current()
+ shape2 = res2It.current()
+ assert(shape1.shapeType() == shape2.shapeType())
+ res1It.next()
+ res2It.next()
+ p1 = res1.shape().middlePoint()
+ p2 = res2.shape().middlePoint()
+ assert(math.fabs(p1.x() - p2.x()) <= TOLERANCE and math.fabs(p1.y() - p2.y()) <= TOLERANCE and math.fabs(p1.z() - p2.z()) <= TOLERANCE), "({}, {}, {}) != ({}, {}, {})".format(p1.x(), p1.y(), p1.z(), p2.x(), p2.y(), p2.z())
+
+assert(model.checkPythonDump())
--- /dev/null
+# Copyright (C) 2021 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
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+#
+
+from salome.shaper import model
+
+model.begin()
+partSet = model.moduleDocument()
+
+### Create Part 1
+Part_1 = model.addPart(partSet)
+Part_1_doc = Part_1.document()
+
+Box_1 = model.addBox(Part_1_doc, 10, 10, 10)
+Group_1 = model.addGroup(Part_1_doc, "Faces", [model.selection("FACE", "Box_1_1/Left"), model.selection("FACE", "Box_1_1/Top")])
+
+Cylinder_1 = model.addCylinder(Part_1_doc, model.selection("VERTEX", "PartSet/Origin"), model.selection("EDGE", "PartSet/OZ"), 5, 10)
+Group_2 = model.addGroup(Part_1_doc, "Faces", [model.selection("FACE", "Cylinder_1_1/Face_1"), model.selection("FACE", "Box_1_1/Front")])
+Group_3 = model.addGroup(Part_1_doc, "Faces", [model.selection("FACE", "Cylinder_1_1/Face_1")])
+GroupAddition_1 = model.addGroupAddition(Part_1_doc, [model.selection("COMPOUND", "Group_1"), model.selection("COMPOUND", "Group_2")])
+GroupSubstraction_1 = model.addGroupSubstraction(Part_1_doc, [model.selection("COMPOUND", "GroupAddition_1")], [model.selection("COMPOUND", "Group_3")])
+
+model.do()
+
+### Create Part 2
+Part_2 = model.addPart(partSet)
+Part_2_doc = Part_2.document()
+
+### Create ImportResult
+ImportResult_1 = model.addImportResult(Part_2_doc, [model.selection("SOLID", "Part_1/Box_1_1"), model.selection("SOLID", "Part_1/Cylinder_1_1")])
+
+model.end()
+
+from GeomAPI import *
+from ModelAPI import *
+import math
+
+TOLERANCE = 1.e-7
+
+assert(ImportResult_1.feature().error() == "")
+model.testNbResults(ImportResult_1, 2)
+model.testNbSubResults(ImportResult_1, [0, 0])
+model.testNbSubShapes(ImportResult_1, GeomAPI_Shape.SOLID, [1, 1])
+model.testNbSubShapes(ImportResult_1, GeomAPI_Shape.FACE, [6, 3])
+model.testNbSubShapes(ImportResult_1, GeomAPI_Shape.EDGE, [24, 6])
+model.testNbSubShapes(ImportResult_1, GeomAPI_Shape.VERTEX, [48, 12])
+model.testResultsVolumes(ImportResult_1, [1000, 785.3981634])
+model.testResultsAreas(ImportResult_1, [600, 471.238898])
+
+# check groups are the same in both parts
+assert(Part_1_doc.size("Groups") == Part_2_doc.size("Groups"))
+REFIND = [0, 1, 3, 4, 2]
+for ind in range(0, Part_1_doc.size("Groups")):
+ res1 = objectToResult(Part_1_doc.object("Groups", REFIND[ind]))
+ res2 = objectToResult(Part_2_doc.object("Groups", ind))
+ assert(res1 is not None)
+ assert(res2 is not None)
+ res1It = GeomAPI_ShapeExplorer(res1.shape(), GeomAPI_Shape.FACE)
+ res2It = GeomAPI_ShapeExplorer(res2.shape(), GeomAPI_Shape.FACE)
+ while res1It.more() and res2It.more():
+ shape1 = res1It.current()
+ shape2 = res2It.current()
+ assert(shape1.shapeType() == shape2.shapeType())
+ res1It.next()
+ res2It.next()
+ p1 = res1.shape().middlePoint()
+ p2 = res2.shape().middlePoint()
+ assert(math.fabs(p1.x() - p2.x()) <= TOLERANCE and math.fabs(p1.y() - p2.y()) <= TOLERANCE and math.fabs(p1.z() - p2.z()) <= TOLERANCE), "({}, {}, {}) != ({}, {}, {})".format(p1.x(), p1.y(), p1.z(), p2.x(), p2.y(), p2.z())
+
+assert(model.checkPythonDump())
--- /dev/null
+# Copyright (C) 2021 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
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+#
+
+from salome.shaper import model
+
+model.begin()
+partSet = model.moduleDocument()
+
+### Create Part 1
+Part_1 = model.addPart(partSet)
+Part_1_doc = Part_1.document()
+
+Box_1 = model.addBox(Part_1_doc, 10, 10, 10)
+Group_1 = model.addGroup(Part_1_doc, "Faces", [model.selection("FACE", "Box_1_1/Left"), model.selection("FACE", "Box_1_1/Top")])
+
+Cylinder_1 = model.addCylinder(Part_1_doc, model.selection("VERTEX", "PartSet/Origin"), model.selection("EDGE", "PartSet/OZ"), 5, 10)
+Group_2 = model.addGroup(Part_1_doc, "Faces", [model.selection("FACE", "Cylinder_1_1/Face_1"), model.selection("FACE", "Box_1_1/Front")])
+Group_3 = model.addGroup(Part_1_doc, "Faces", [model.selection("FACE", "Cylinder_1_1/Face_1")])
+GroupAddition_1 = model.addGroupAddition(Part_1_doc, [model.selection("COMPOUND", "Group_1"), model.selection("COMPOUND", "Group_2")])
+GroupSubstraction_1 = model.addGroupSubstraction(Part_1_doc, [model.selection("COMPOUND", "GroupAddition_1")], [model.selection("COMPOUND", "Group_3")])
+
+model.do()
+
+### Create Part 2
+Part_2 = model.addPart(partSet)
+Part_2_doc = Part_2.document()
+
+### Create ImportResult
+ImportResult_1 = model.addImportResult(Part_2_doc, [model.selection("SOLID", "Part_1/Box_1_1")])
+
+model.end()
+
+from GeomAPI import *
+from ModelAPI import *
+import math
+
+TOLERANCE = 1.e-7
+
+assert(ImportResult_1.feature().error() == "")
+model.testNbResults(ImportResult_1, 1)
+model.testNbSubResults(ImportResult_1, [0])
+model.testNbSubShapes(ImportResult_1, GeomAPI_Shape.SOLID, [1])
+model.testNbSubShapes(ImportResult_1, GeomAPI_Shape.FACE, [6])
+model.testNbSubShapes(ImportResult_1, GeomAPI_Shape.EDGE, [24])
+model.testNbSubShapes(ImportResult_1, GeomAPI_Shape.VERTEX, [48])
+model.testResultsVolumes(ImportResult_1, [1000])
+model.testResultsAreas(ImportResult_1, [600])
+
+# check imported groups are correct
+assert(Part_1_doc.size("Groups") == 5)
+assert(Part_2_doc.size("Groups") == 4)
+REFERENCE = [(2, 5.0, 5.0, 5.0),
+ (1, 10.0, 5.0, 5.0),
+ (3, 5.0, 5.0, 5.0),
+ (3, 5.0, 5.0, 5.0)]
+for ind in range(0, Part_2_doc.size("Groups")):
+ res = objectToResult(Part_2_doc.object("Groups", ind))
+ assert(res is not None)
+ nbShapes = 0
+ it = GeomAPI_ShapeExplorer(res.shape(), GeomAPI_Shape.FACE)
+ while it.more():
+ nbShapes += 1
+ it.next()
+ assert(nbShapes == REFERENCE[ind][0])
+ p = res.shape().middlePoint()
+ x = REFERENCE[ind][1]
+ y = REFERENCE[ind][2]
+ z = REFERENCE[ind][3]
+ assert(math.fabs(p.x() - x) <= TOLERANCE and math.fabs(p.y() - y) <= TOLERANCE and math.fabs(p.z() - z) <= TOLERANCE), "({}, {}, {}) != ({}, {}, {})".format(p.x(), p.y(), p.z(), x, y, z)
+
+assert(model.checkPythonDump())
copy-shape, so, even the document was opened and the source-part was not activated (loaded), the part with copy-feature works well
with this result-shape.
+If the source-part contains one or several groups, which refer to sub-shapes of source results, then these groups are mutually imported
+as a sub-features of the Import Result feature. The copied groups contain only the elements referring to the imported results.
+
It may be necessary for the user to load the other parts before using this feature otherwise the content of the **Results** folders will be empty.
To create a Copy in the active part:
Result
""""""
-The Result of the operation will be copy of one or several results selected in another part located in the same place:
+The Result of the operation will be copy of one or several results selected and groups referring to these results in another part located in the same place:
.. figure:: images/CreatedImportResult.png
:align: center
TestCopySubShapes.py
TestCopyWholeFeature.py
TestImportResult.py
+ TestImportResultWithGroups1.py
+ TestImportResultWithGroups2.py
+ TestImportResultWithGroups3.py
TestDefeaturing_ErrorMsg.py
TestDefeaturing_OnSolid1.py
TestDefeaturing_OnSolid2.py
#include <BOPAlgo_CheckerSI.hxx>
#include <BOPDS_DS.hxx>
+#include <BOPTools_AlgoTools.hxx>
#include <sstream>
#include <algorithm> // for std::transform
return !aShape.IsNull() && aShape.ShapeType() == TopAbs_COMPOUND;
}
+bool GeomAPI_Shape::isCollectionOfSolids() const
+{
+ const TopoDS_Shape& aShape = const_cast<GeomAPI_Shape*>(this)->impl<TopoDS_Shape>();
+ if (aShape.IsNull())
+ return false;
+
+ if (aShape.ShapeType() == TopAbs_SOLID ||
+ aShape.ShapeType() == TopAbs_COMPSOLID)
+ return true;
+
+ if (aShape.ShapeType() != TopAbs_COMPOUND)
+ return false;
+
+ TopTools_ListOfShape aLS;
+ TopTools_MapOfShape aMFence;
+ BOPTools_AlgoTools::TreatCompound(aShape, aLS, &aMFence);
+ TopTools_ListOfShape::Iterator it(aLS);
+ for (; it.More(); it.Next()) {
+ const TopoDS_Shape& aSx = it.Value();
+ if (aSx.ShapeType() != TopAbs_SOLID &&
+ aSx.ShapeType() != TopAbs_COMPSOLID)
+ return false;
+ }
+ return true;
+}
+
bool GeomAPI_Shape::isCompoundOfSolids() const
{
const TopoDS_Shape& aShape = const_cast<GeomAPI_Shape*>(this)->impl<TopoDS_Shape>();
GEOMAPI_EXPORT
virtual bool isCompoundOfSolids() const;
+ /// Returns true, if the shape contains only solids, compsolids
+ /// and compounds of solids and compsolids of any nesting depth
+ GEOMAPI_EXPORT
+ virtual bool isCollectionOfSolids() const;
+
/// Returns whether the shape is a compound where all elements are topologically connected
GEOMAPI_EXPORT
virtual bool isConnectedTopology() const;
${OpenCASCADE_DataExchange_LIBRARIES}
${OpenCASCADE_ModelingAlgorithms_LIBRARIES}
${OpenCASCADE_ApplicationFramework_LIBRARIES}
- ${QT_LIBRARIES}
)
ADD_DEFINITIONS(-DGEOMALGOAPI_EXPORTS ${OpenCASCADE_DEFINITIONS})
SET_SOURCE_FILES_PROPERTIES(GeomAlgoAPI.i PROPERTIES CPLUSPLUS ON)
SET_SOURCE_FILES_PROPERTIES(GeomAlgoAPI.i PROPERTIES SWIG_DEFINITIONS "-shadow")
-INCLUDE(UseQtExt)
# additional include directories
-INCLUDE_DIRECTORIES(${QT_INCLUDES})
-
INCLUDE_DIRECTORIES(
../GeomAPI
../GeomAlgoImpl
#include <GeomAlgoAPI_ImageImport.h>
-#include <QPixmap>
#include <BRep_Builder.hxx>
#include <BRepBuilderAPI_MakeFace.hxx>
#include <BRepBuilderAPI_MakePolygon.hxx>
#include <TopoDS_Vertex.hxx>
#include <TopoDS_Wire.hxx>
-std::shared_ptr<GeomAPI_Shape> ImageImport(const std::string& theFileName,
- std::string& theError)
+std::shared_ptr<GeomAPI_Shape> ImageImport(const int width,
+ const int height,
+ std::string& theError)
{
TopoDS_Shape aResShape;
try
{
- QPixmap* pixmap = new QPixmap(theFileName.c_str());
- int height = pixmap->height();
- int width = pixmap->width();
-
- delete pixmap;
-
TopoDS_Vertex aTriVertexes[4];
gp_Pnt aPnt1( -0.5*width, -0.5*height, 0);
gp_Pnt aPnt2( 0.5*width, -0.5*height, 0);
#include <GeomAPI_Shape.h>
#include <string>
-#include <QPixmap>
+
/// Implementation of the import STL files algorithms
GEOMALGOAPI_EXPORT
-std::shared_ptr<GeomAPI_Shape> ImageImport(const std::string& theFileName,
- std::string& theError);
+std::shared_ptr<GeomAPI_Shape> ImageImport(const int theWidth,
+ const int theHeight,
+ std::string& theError);
#endif /* GEOMALGOAPI_IMAGEIMPORT_H_ */
return aPath.Name().ToCString();
}
+std::string File_Tools::path(const std::string& theFileName)
+{
+ OSD_Path aPath (theFileName.c_str());
+ Standard_Integer aTrekLen =
+ theFileName.size() - aPath.Extension().Length() - aPath.Name().Length();
+ return theFileName.substr(0, aTrekLen);
+}
+
bool AlgoError::isAlgorithmFailed(const GeomMakeShapePtr& theAlgorithm,
const std::string& theFeature,
std::string& theError)
* Returns a name of theFileName
*/
GEOMALGOAPI_EXPORT static std::string name(const std::string& theFileName);
+ /**
+ * Returns a directory path of theFileName
+ */
+ GEOMALGOAPI_EXPORT static std::string path(const std::string& theFileName);
};
/** \class AlgoError
Model_AttributeRefList.h
Model_AttributeRefAttrList.h
Model_AttributeBoolean.h
+ Model_AttributeImage.h
Model_AttributeIntArray.h
Model_AttributeString.h
Model_AttributeStringArray.h
Model_AttributeRefList.cpp
Model_AttributeRefAttrList.cpp
Model_AttributeBoolean.cpp
+ Model_AttributeImage.cpp
Model_AttributeIntArray.cpp
Model_AttributeString.cpp
Model_AttributeStringArray.cpp
--- /dev/null
+// Copyright (C) 2014-2021 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
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
+#include <Model_AttributeImage.h>
+#include <ModelAPI_AttributeString.h>
+#include <ModelAPI_Attribute.h>
+#include <ModelAPI_Data.h>
+#include <ModelAPI_Object.h>
+
+#include <Standard_TypeDef.hxx>
+#include <TCollection_AsciiString.hxx>
+#include <TCollection_ExtendedString.hxx>
+
+#include <TDataStd_IntegerArray.hxx>
+#include <TDataStd_ByteArray.hxx>
+#include <TDataStd_Comment.hxx>
+#include <TDF_CopyLabel.hxx>
+
+void Model_AttributeImage::setTexture(const int theWidth,
+ const int theHeight,
+ const std::list<unsigned char>& theByteArray,
+ const std::string& theFormat,
+ const bool sendUpdated)
+{
+ if (theWidth > 0 && theHeight > 0 && theByteArray.size() > 0) { // set new data
+ // Find or create attributes
+ Handle_TDataStd_ByteArray aByteArray =
+ TDataStd_ByteArray::Set(myLab, 0, theByteArray.size() - 1);
+ Handle_TDataStd_IntegerArray aDimensions =
+ TDataStd_IntegerArray::Set(myLab, 0, 1);
+ Handle_TDataStd_Comment aFormat = TDataStd_Comment::Set(myLab, theFormat.c_str());
+
+ // Dimensions
+ aDimensions->SetValue(0, theWidth);
+ aDimensions->SetValue(1, theHeight);
+
+ // Texture
+ Handle(TColStd_HArray1OfByte) aNewArray =
+ new TColStd_HArray1OfByte(0, theByteArray.size() - 1);
+ std::list<unsigned char>::const_iterator itBA = theByteArray.begin();
+ for (int j = 0; itBA != theByteArray.end(); ++itBA, ++j) {
+ aNewArray->SetValue(j, (Standard_Byte)(*itBA));
+ }
+ aByteArray->ChangeArray(aNewArray);
+
+ if (sendUpdated)
+ owner()->data()->sendAttributeUpdated(this);
+ }
+ else { // size is zero => arrays must be erased
+ bool isForgotten1 = myLab.ForgetAttribute(TDataStd_ByteArray::GetID());
+ bool isForgotten2 = myLab.ForgetAttribute(TDataStd_IntegerArray::GetID());
+ bool isForgotten3 = myLab.ForgetAttribute(TDataStd_Comment::GetID());
+
+ if (sendUpdated && (isForgotten1 || isForgotten2 || isForgotten3))
+ owner()->data()->sendAttributeUpdated(this);
+ }
+}
+
+bool Model_AttributeImage::hasTexture()
+{
+ Handle_TDataStd_ByteArray aByteArray;
+ Handle_TDataStd_IntegerArray aDimensions;
+ if (myLab.FindAttribute(TDataStd_ByteArray::GetID(), aByteArray) == Standard_True &&
+ myLab.FindAttribute(TDataStd_IntegerArray::GetID(), aDimensions) == Standard_True) {
+
+ // Dimensions
+ if (aDimensions->Value(0) > 0 && aDimensions->Value(1) > 0)
+ // Byte array
+ return aByteArray->Length() > 0;
+ }
+ return false;
+}
+
+bool Model_AttributeImage::texture(int& theWidth,
+ int& theHeight,
+ std::list<unsigned char>& theByteArray,
+ std::string& theFormat)
+{
+ // Init return values
+ theWidth = 0;
+ theHeight = 0;
+ theByteArray.clear();
+ theFormat = "";
+
+ Handle_TDataStd_ByteArray aByteArray;
+ Handle_TDataStd_IntegerArray aDimensions;
+ Handle_TDataStd_Comment aFormat;
+ if (myLab.FindAttribute(TDataStd_ByteArray::GetID(), aByteArray) == Standard_True &&
+ myLab.FindAttribute(TDataStd_IntegerArray::GetID(), aDimensions) == Standard_True &&
+ myLab.FindAttribute(TDataStd_Comment::GetID(), aFormat) == Standard_True) {
+
+ // Dimensions
+ theWidth = aDimensions->Value(0);
+ theHeight = aDimensions->Value(1);
+
+ // Texture
+ const Handle(TColStd_HArray1OfByte) byteArray = aByteArray->InternalArray();
+ for (int j = byteArray->Lower(); j <= byteArray->Upper(); j++) {
+ theByteArray.push_back((unsigned char)byteArray->Value( j ));
+ }
+
+ // Format
+ theFormat = TCollection_AsciiString(aFormat->Get()).ToCString();
+ return true;
+ }
+
+ return false;
+}
+
+void Model_AttributeImage::copyTo(AttributeImagePtr theTarget) const
+{
+ std::shared_ptr<Model_AttributeImage> aTarget =
+ std::dynamic_pointer_cast<Model_AttributeImage>(theTarget);
+ if (aTarget) {
+ //Model_AttributeSelectionList::copyAttrs(myLab, aTarget->myLab);
+ TDF_CopyLabel aCopyAlgo (myLab, aTarget->myLab);
+ aCopyAlgo.Perform();
+ aTarget->reinit();
+ }
+}
+
+Model_AttributeImage::Model_AttributeImage(TDF_Label& theLabel)
+{
+ myLab = theLabel;
+ reinit();
+}
+
+void Model_AttributeImage::reinit()
+{
+ myIsInitialized = myLab.IsAttribute(TDataStd_ByteArray::GetID());
+}
--- /dev/null
+// Copyright (C) 2014-2021 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
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
+#ifndef MODEL_ATTRIBUTEIMAGE_H_
+#define MODEL_ATTRIBUTEIMAGE_H_
+
+#include <Model.h>
+#include <ModelAPI_AttributeImage.h>
+
+#include <TDF_Label.hxx>
+
+#include <string>
+
+/**\class Model_AttributeImage
+ * \ingroup DataModel
+ * \brief API for the attribute that contains image inside.
+ * Represented as the following OCCT attributes:
+ * TDataStd_ByteArray for the pixmap texture data,
+ * TDataStd_IntArray(2) for image dimensions (widht and height),
+ * TDataStd_String for image format.
+ */
+
+class Model_AttributeImage : public ModelAPI_AttributeImage
+{
+ /// Stores the label as the only reference to all data
+ TDF_Label myLab;
+
+ public:
+ /// Defines the value of the image attribute
+ MODEL_EXPORT virtual void setTexture(const int theWidth,
+ const int theHeight,
+ const std::list<unsigned char>& theByteArray,
+ const std::string& theFormat,
+ const bool sendUpdated = true);
+
+ /// Returns true, if texture width and height are non-zero
+ MODEL_EXPORT virtual bool hasTexture();
+
+ /// Returns the value of the image attribute
+ MODEL_EXPORT virtual bool texture(int& theWidth,
+ int& theHeight,
+ std::list<unsigned char>& theByteArray,
+ std::string& theFormat);
+
+ /// Copy the image data to the destination attribute
+ virtual void copyTo(std::shared_ptr<ModelAPI_AttributeImage> theTarget) const;
+
+ protected:
+ /// Initializes attibutes
+ Model_AttributeImage(TDF_Label& theLabel);
+ /// Reinitializes the internal state of the attribute (may be needed on undo/redo, abort, etc)
+ virtual void reinit();
+
+ friend class Model_Data;
+};
+
+#endif
#include <Model_AttributeSelection.h>
#include <Model_AttributeSelectionList.h>
#include <Model_AttributeIntArray.h>
+#include <Model_AttributeImage.h>
#include <Model_AttributeTables.h>
#include <Model_Events.h>
#include <Model_Expression.h>
anAttr = new Model_AttributeDoubleArray(anAttrLab);
} else if (theAttrType == ModelAPI_AttributeTables::typeId()) {
anAttr = new Model_AttributeTables(anAttrLab);
+ } else if (theAttrType == ModelAPI_AttributeImage::typeId()) {
+ anAttr = new Model_AttributeImage(anAttrLab);
}
// create also GeomData attributes here because only here the OCAF structure is known
else if (theAttrType == GeomData_Point::typeId()) {
GET_ATTRIBUTE_BY_ID(ModelAPI_AttributeIntArray, intArray);
GET_ATTRIBUTE_BY_ID(ModelAPI_AttributeDoubleArray, realArray);
GET_ATTRIBUTE_BY_ID(ModelAPI_AttributeTables, tables);
+GET_ATTRIBUTE_BY_ID(ModelAPI_AttributeImage, image);
std::shared_ptr<ModelAPI_Attribute> Model_Data::attribute(const std::string& theID)
{
#include <ModelAPI_AttributeString.h>
#include <ModelAPI_AttributeStringArray.h>
#include <ModelAPI_AttributeIntArray.h>
+#include <ModelAPI_AttributeImage.h>
#include <ModelAPI_Data.h>
#include <ModelAPI_Feature.h>
#include <ModelAPI_Folder.h>
/// Returns the attribute that contains string values array
MODEL_EXPORT virtual std::shared_ptr<ModelAPI_AttributeTables>
tables(const std::string& theID);
+ /// Returns the attribute that contains image
+ MODEL_EXPORT virtual std::shared_ptr<ModelAPI_AttributeImage>
+ image(const std::string& theID);
/// Returns the generic attribute by identifier
/// \param theID identifier of the attribute
#include <ModelAPI_Object.h>
#include <ModelAPI_Events.h>
#include <ModelAPI_Tools.h>
+#include <ModelAPI_AttributeImage.h>
#include <Model_Data.h>
#include <Events_Loop.h>
#include <GeomAPI_ShapeIterator.h>
delete myBuilder;
}
+void Model_ResultBody::initAttributes()
+{
+ ModelAPI_Result::initAttributes();
+ // append the image attribute. It is empty, the attribute will be filled by a request
+ data()->addAttribute(IMAGE_ID(), ModelAPI_AttributeImage::typeId())->setIsArgument(false);
+}
+
bool Model_ResultBody::generated(const GeomShapePtr& theNewShape,
const std::string& theName, const bool theCheckIsInResult)
{
myHistoryCash.Clear();
}
-void Model_ResultBody::setTextureFile(const std::string & theTextureFile)
-{
- ModelAPI_Result::setTextureFile(theTextureFile);
- for( auto sub : mySubs){
- sub->setTextureFile(theTextureFile);
- }
- for(auto map : mySubsMap){
- map.first->setTextureFile(theTextureFile);
- }
-}
-
bool Model_ResultBody::isConnectedTopology()
{
TDF_Label aDataLab = std::dynamic_pointer_cast<Model_Data>(data())->label();
}
}
+bool Model_ResultBody::hasTexture()
+{
+ AttributeImagePtr anImageAttr =
+ data()->image(ModelAPI_ResultBody::IMAGE_ID());
+ if (anImageAttr.get()) {
+ return anImageAttr->hasTexture();
+ }
+ return false;
+}
+
// adds to the theSubSubs map all sub-shapes of theSub if it is compound of compsolid
static void collectSubs(
const GeomShapePtr theSub, TopTools_MapOfShape& theSubSubs, const bool theOneLevelMore)
/// Removes the stored builders
MODEL_EXPORT virtual ~Model_ResultBody();
+ /// Request for initialization of data model of the result body: adding all attributes
+ virtual void initAttributes();
+
/// Records the subshape newShape which was generated during a topological construction.
/// As an example, consider the case of a face generated in construction of a box.
MODEL_EXPORT virtual bool generated(const GeomShapePtr& theNewShape,
MODEL_EXPORT virtual void cleanCash() override;
/// sets the texture file
- MODEL_EXPORT virtual void setTextureFile(const std::string & theTextureFile) override;
+ MODEL_EXPORT virtual bool hasTexture() override;
protected:
ModelAPI.h
ModelAPI_Attribute.h
ModelAPI_AttributeBoolean.h
+ ModelAPI_AttributeImage.h
ModelAPI_AttributeIntArray.h
ModelAPI_AttributeDocRef.h
ModelAPI_AttributeDouble.h
SET(PROJECT_SOURCES
ModelAPI_Attribute.cpp
ModelAPI_AttributeBoolean.cpp
+ ModelAPI_AttributeImage.cpp
ModelAPI_AttributeIntArray.cpp
ModelAPI_AttributeDocRef.cpp
ModelAPI_AttributeDouble.cpp
--- /dev/null
+// Copyright (C) 2014-2021 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
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
+#include <ModelAPI_AttributeImage.h>
+
+
+std::string ModelAPI_AttributeImage::attributeType()
+{
+ return typeId();
+}
+
+/// To virtually destroy the fields of successors
+ModelAPI_AttributeImage::~ModelAPI_AttributeImage()
+{
+}
+
+ModelAPI_AttributeImage::ModelAPI_AttributeImage()
+{
+}
--- /dev/null
+// Copyright (C) 2014-2021 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
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
+#ifndef ModelAPI_AttributeImage_H_
+#define ModelAPI_AttributeImage_H_
+
+#include <ModelAPI.h>
+#include <ModelAPI_Attribute.h>
+
+#include <string>
+#include <list>
+
+
+/**\class ModelAPI_AttributeImage
+ * \ingroup DataModel
+ * \brief API for the attribute that contains binary data.
+ * Used for images storage for an example. By default size is one, zero-based.
+ */
+
+class ModelAPI_AttributeImage : public ModelAPI_Attribute
+{
+ public:
+ /// Defines the value of the image attribute
+ MODELAPI_EXPORT virtual void setTexture(const int theWidth,
+ const int theHeight,
+ const std::list<unsigned char>& theByteArray,
+ const std::string& theFormat,
+ const bool sendUpdated = true) = 0;
+
+ /// Returns true, if texture width and height are non-zero
+ MODELAPI_EXPORT virtual bool hasTexture() = 0;
+
+ /// Returns the value of the image attribute
+ MODELAPI_EXPORT virtual bool texture(int& theWidth,
+ int& theHeight,
+ std::list<unsigned char>& theByteArray,
+ std::string& theFormat) = 0;
+
+ /// Copy the image data to the destination attribute
+ virtual void copyTo(std::shared_ptr<ModelAPI_AttributeImage> theTarget) const = 0;
+
+ /// Returns the type of this class of attributes
+ MODELAPI_EXPORT static std::string typeId()
+ {
+ return "Image";
+ }
+
+ /// Returns the type of this class of attributes, not static method
+ MODELAPI_EXPORT virtual std::string attributeType();
+
+ /// To virtually destroy the fields of successors
+ MODELAPI_EXPORT virtual ~ModelAPI_AttributeImage();
+
+ protected:
+ /// Objects are created for features automatically
+ MODELAPI_EXPORT ModelAPI_AttributeImage();
+};
+
+//! Pointer on image attribute
+typedef std::shared_ptr<ModelAPI_AttributeImage> AttributeImagePtr;
+
+#endif
class ModelAPI_AttributeSelection;
class ModelAPI_AttributeSelectionList;
class ModelAPI_AttributeIntArray;
+class ModelAPI_AttributeImage;
class ModelAPI_AttributeTables;
class ModelAPI_Object;
class GeomAPI_Shape;
virtual std::shared_ptr<ModelAPI_AttributeIntArray> intArray(const std::string& theID) = 0;
/// Returns the attribute that contains string values array
virtual std::shared_ptr<ModelAPI_AttributeStringArray> stringArray(const std::string& theID) = 0;
+ /// Returns the attribute that contains image
+ virtual std::shared_ptr<ModelAPI_AttributeImage> image(const std::string& theID) = 0;
/// Returns the attribute that contains tables
virtual std::shared_ptr<ModelAPI_AttributeTables> tables(const std::string& theID) = 0;
}
/// Creates an empty message
-ModelAPI_ImportParametersMessage::ModelAPI_ImportParametersMessage(const Events_ID theID, const void* theSender)
+ModelAPI_ImportParametersMessage::ModelAPI_ImportParametersMessage(const Events_ID theID,
+ const void* theSender)
:Events_Message(theID, theSender)
{
}
/// Creates an empty message
- MODELAPI_EXPORT ModelAPI_ImportParametersMessage(const Events_ID theID, const void* theSender = 0);
+ MODELAPI_EXPORT ModelAPI_ImportParametersMessage(const Events_ID theID,
+ const void* theSender = 0);
/// The virtual destructor
MODELAPI_EXPORT virtual ~ModelAPI_ImportParametersMessage();
{
std::shared_ptr<ModelAPI_Data> myData; ///< manager of the data model of a feature
std::shared_ptr<ModelAPI_Document> myDoc; ///< document this object belongs to
- std::string textureFile = "";
public:
#ifdef DEBUG_NAMES
std::wstring myName; // name of this object
/// signal.
MODELAPI_EXPORT virtual void setDisplayed(const bool theDisplay);
- MODELAPI_EXPORT bool hasTextureFile()
+ MODELAPI_EXPORT virtual bool hasTexture()
{
- return (textureFile != "");
- }
-
- MODELAPI_EXPORT virtual void setTextureFile(const std::string & theTextureFile)
- {
- textureFile = theTextureFile;
- }
-
- MODELAPI_EXPORT const std::string & getTextureFile()
- {
- return textureFile;
+ return false;
}
protected:
public:
/// Reference to the color of the result.
- /// The integer array is used. It contains tree values for red green and blue values.
+ /// The integer array is used. It contains three values for red, green and blue values.
/// The values are in [0, 255] range
inline static const std::string& COLOR_ID()
{
public:
MODELAPI_EXPORT virtual ~ModelAPI_ResultBody();
+ /// Reference to the image attribute of the result body.
+ inline static const std::string& IMAGE_ID()
+ {
+ static const std::string MY_IMAGE_ID("Image");
+ return MY_IMAGE_ID;
+ }
+
/// Returns the group identifier of this result
MODELAPI_EXPORT virtual std::string groupName();
#include <ModelAPI_AttributeBoolean.h>
#include <ModelAPI_AttributeDocRef.h>
#include <ModelAPI_AttributeDouble.h>
+#include <ModelAPI_AttributeImage.h>
#include <ModelAPI_AttributeIntArray.h>
#include <ModelAPI_AttributeSelectionList.h>
#include <ModelAPI_CompositeFeature.h>
#include <GeomAlgoAPI_MakeShape.h>
#include <GeomAPI_ShapeHierarchy.h>
#include <GeomAPI_ShapeIterator.h>
+#include <GeomAPI_ShapeExplorer.h>
#include <algorithm>
#include <iostream>
return false;
}
+static void cacheSubresults(const ResultBodyPtr& theTopLevelResult,
+ std::set<ResultPtr>& theCashedResults)
+{
+ std::list<ResultPtr> aResults;
+ ModelAPI_Tools::allSubs(theTopLevelResult, aResults, false);
+ for (std::list<ResultPtr>::iterator aR = aResults.begin(); aR != aResults.end(); ++aR) {
+ theCashedResults.insert(*aR);
+ }
+}
+
+bool isInResults(AttributeSelectionListPtr theSelection,
+ const std::list<ResultPtr>& theResults,
+ std::set<ResultPtr>& theCashedResults)
+{
+ // collect all results into a cashed set
+ if (theCashedResults.empty()) {
+ std::list<ResultPtr>::const_iterator aRes = theResults.cbegin();
+ for(; aRes != theResults.cend(); aRes++) {
+ if (theCashedResults.count(*aRes))
+ continue;
+ else
+ theCashedResults.insert(*aRes);
+
+ if ((*aRes)->groupName() == ModelAPI_ResultBody::group()) {
+ ResultBodyPtr aResBody = std::dynamic_pointer_cast<ModelAPI_ResultBody>(*aRes);
+ cacheSubresults(aResBody, theCashedResults);
+ } else if ((*aRes)->groupName() == ModelAPI_ResultPart::group()) { // all results of the part
+ ResultPartPtr aResPart = std::dynamic_pointer_cast<ModelAPI_ResultPart>(*aRes);
+ DocumentPtr aPartDoc = aResPart->partDoc();
+ if (!aPartDoc.get() || !aPartDoc->isOpened()) { // document is not accessible
+ return false;
+ }
+ int aBodyCount = aPartDoc->size(ModelAPI_ResultBody::group());
+ for (int aBodyIndex = 0; aBodyIndex < aBodyCount; ++aBodyIndex) {
+ ResultBodyPtr aResBody =
+ std::dynamic_pointer_cast<ModelAPI_ResultBody>(
+ aPartDoc->object(ModelAPI_ResultBody::group(), aBodyIndex));
+ if (aResBody.get()) {
+ theCashedResults.insert(aResBody);
+ cacheSubresults(aResBody, theCashedResults);
+ }
+ }
+ }
+ }
+ }
+ // if context is in results, return true
+ for(int a = 0; a < theSelection->size(); a++) {
+ AttributeSelectionPtr anAttr = theSelection->value(a);
+ ResultPtr aContext = anAttr->context();
+ // check is it group selected for groups BOP
+ if (aContext.get() && aContext->groupName() == ModelAPI_ResultGroup::group()) {
+ // it is impossible by used results check which result is used in this group result,
+ // so check the results shapes is it in results of this document or not
+ FeaturePtr aSelFeature =
+ std::dynamic_pointer_cast<ModelAPI_Feature>(theSelection->owner());
+ if (!aSelFeature.get() || aSelFeature->results().empty())
+ continue;
+ GeomShapePtr aGroupResShape = aSelFeature->firstResult()->shape();
+
+ std::set<ResultPtr>::iterator allResultsIter = theCashedResults.begin();
+ for(; allResultsIter != theCashedResults.end(); allResultsIter++) {
+ GeomShapePtr aResultShape = (*allResultsIter)->shape();
+
+ GeomAPI_Shape::ShapeType aType =
+ GeomAPI_Shape::shapeTypeByStr(theSelection->selectionType());
+ GeomAPI_ShapeExplorer aGroupResExp(aGroupResShape, aType);
+ for(; aGroupResExp.more(); aGroupResExp.next()) {
+ if (aResultShape->isSubShape(aGroupResExp.current(), false))
+ return true; // at least one shape of the group is in the used results
+ }
+ }
+ }
+ ResultBodyPtr aSelected = std::dynamic_pointer_cast<ModelAPI_ResultBody>(anAttr->context());
+ if (!aSelected.get()) { // try to get selected feature and all its results
+ FeaturePtr aContextFeature = anAttr->contextFeature();
+ if (aContextFeature.get() && !aContextFeature->results().empty()) {
+ const std::list<ResultPtr>& allResluts = aContextFeature->results();
+ std::list<ResultPtr>::const_iterator aResIter = allResluts.cbegin();
+ for(; aResIter != allResluts.cend(); aResIter++) {
+ if (aResIter->get() && theCashedResults.count(*aResIter))
+ return true;
+ }
+ }
+ } else if (aSelected.get() && theCashedResults.count(aSelected))
+ return true;
+ }
+ return false;
+}
+
ResultPtr findPartResult(const DocumentPtr& theMain, const DocumentPtr& theSub)
{
// to optimize and avoid of crash on partset document close
}
}
+
+void copyImageAttribute (std::shared_ptr<ModelAPI_Result> theSource,
+ std::shared_ptr<ModelAPI_Result> theDest)
+{
+ if (!theSource.get() || !theDest.get())
+ return;
+
+ // images allowed only for ResultBody
+ ResultBodyPtr aSourceBody = std::dynamic_pointer_cast<ModelAPI_ResultBody>(theSource);
+ ResultBodyPtr aDestBody = std::dynamic_pointer_cast<ModelAPI_ResultBody>(theDest);
+ if (!aSourceBody.get() || !aDestBody.get())
+ return;
+
+ AttributeImagePtr aSourceImage =
+ theSource->data()->image(ModelAPI_ResultBody::IMAGE_ID());
+ if (aSourceImage.get() && aSourceImage->hasTexture()) {
+ AttributeImagePtr aDestImage =
+ theDest->data()->image(ModelAPI_ResultBody::IMAGE_ID());
+ if (aDestImage.get()) {
+ aSourceImage->copyTo(aDestImage);
+ }
+ }
+}
+
std::list<FeaturePtr> referencedFeatures(
std::shared_ptr<ModelAPI_Result> theTarget, const std::string& theFeatureKind,
const bool theSortResults)
#define ModelAPI_Tools_HeaderFile
#include "ModelAPI.h"
+#include <ModelAPI_AttributeSelectionList.h>
class ModelAPI_CompositeFeature;
class ModelAPI_Document;
MODELAPI_EXPORT void copyVisualizationAttrs(std::shared_ptr<ModelAPI_Result> theSource,
std::shared_ptr<ModelAPI_Result> theDest);
+/*! Copies image attribute from one result to another.
+* \param theSource a result that contains the image data
+* \param theDest a destination result that takes the image data
+*/
+MODELAPI_EXPORT void copyImageAttribute(std::shared_ptr<ModelAPI_Result> theSource,
+ std::shared_ptr<ModelAPI_Result> theDest);
+
/*! Produces list of features that reference to the given target (directly or through sub-results)
* \param theTarget the referenced result
* \param theFeatureKind the resulting features filter: the feature kind or all for the empty string
std::shared_ptr<ModelAPI_Result> theTarget, const std::string& theFeatureKind,
const bool theSortResults);
+/*!
+ * Returns true if something in selection is presented in the results list
+ */
+MODELAPI_EXPORT bool isInResults(AttributeSelectionListPtr theSelection,
+ const std::list<ResultPtr>& theResults,
+ std::set<ResultPtr>& theCashedResults);
/*! Returns a container with the current color value.
* These are tree int values for RGB definition.
Locale
ModelAPI
ModelGeomAlgo
+ ModuleBase
)
ADD_DEFINITIONS(-DMODELHIGHAPI_EXPORTS -DWNT)
${PROJECT_SOURCE_DIR}/src/Locale
${PROJECT_SOURCE_DIR}/src/ModelAPI
${PROJECT_SOURCE_DIR}/src/ModelGeomAlgo
+ ${PROJECT_SOURCE_DIR}/src/ModuleBase
${PROJECT_SOURCE_DIR}/src/PartSetPlugin
${OpenCASCADE_INCLUDE_DIR}
)
MODELHIGHAPI_EXPORT
bool process(const std::shared_ptr<ModelAPI_Document>& theDoc, const std::string& theFileName);
+ /// Keep path to the true dumping directory.
+ /// It is used to store image files or any other external files
+ /// \param theDumpDir path to the true dumping directory
+ MODELHIGHAPI_EXPORT
+ void setDumpDir(const std::string& theDumpDir) { myDumpDir = theDumpDir; }
+ /// Return path to the true dumping directory
+ MODELHIGHAPI_EXPORT std::string getDumpDir() const { return myDumpDir; }
+
/// Add module to list of imported modules
/// \param theModuleName name of the module to be imported
MODELHIGHAPI_EXPORT
std::list<EntityPtr> myPostponed; ///< list of postponed entities (sketch constraints or folders)
bool myDumpPostponedInProgress; ///< processing postponed is in progress
+ std::string myDumpDir;
+
protected:
/// list of entities, used by other features but not dumped yet
std::set<EntityPtr> myNotDumpedEntities;
} else if (aType == ModelAPI_AttributeString::typeId()) {
AttributeStringPtr anAttr = std::dynamic_pointer_cast<ModelAPI_AttributeString>(theAttr);
// do not dump solver DOF for sketch as it may be changed unexpectedly
- if(anAttr->id() == "SolverDOF") {
+ if (anAttr->id() == "SolverDOF") {
+ return "";
+ }
+ // do not dump file path for Image as it is changed after DumpPython
+ if (aFeatOwner->getKind() == "ImportImage" &&
+ anAttr->id() == "file_path") {
return "";
}
aResult<<anAttr->value();
Events_Loop* aLoop = Events_Loop::loop();
aLoop->flush(Events_Loop::eventByName(EVENT_OBJECT_CREATED));
aLoop->flush(Events_Loop::eventByName(EVENT_OBJECT_UPDATED));
- //aLoop->flush(Events_Loop::eventByName(EVENT_OBJECT_TO_REDISPLAY));
+ aLoop->flush(Events_Loop::eventByName(EVENT_OBJECT_TO_REDISPLAY));
//aLoop->flush(Events_Loop::eventByName(EVENT_OBJECT_DELETED));
}
void ModelHighAPI_Selection::setDeflection(double theValue)
{
- if (myVariantType != VT_ResultSubShapePair)
+ if (myVariantType != VT_ResultSubShapePair || !myResultSubShapePair.first.get())
return;
AttributeDoublePtr aDeflectionAttr =
// LCOV_EXCL_START
void ModelHighAPI_Selection::setTransparency(double theValue)
{
- if (myVariantType != VT_ResultSubShapePair)
+ if (myVariantType != VT_ResultSubShapePair || !myResultSubShapePair.first.get())
return;
AttributeDoublePtr aTransparencyAttr =
#include <ModelAPI_ResultConstruction.h>
#include <ModelAPI_Events.h>
+#include <ModuleBase_Tools.h>
+
#include <cmath>
#include <sstream>
aNbTransactions = aNbUndo;
++aTransactionID;
}
+ static std::string anOperationPrefix(ModuleBase_Tools::translate("", "Operation").toStdString());
std::ostringstream aTransactionName;
- aTransactionName << "Operation_" << aTransactionID;
+ aTransactionName << anOperationPrefix << "_" << aTransactionID;
ModelAPI_Session::get()->startOperation(aTransactionName.str());
}
#include <GeomDataAPI_Point2D.h>
#include <GeomDataAPI_Point2DArray.h>
//--------------------------------------------------------------------------------------
+#include <GeomAlgoAPI_Tools.h>
+//--------------------------------------------------------------------------------------
#include <Locale_Convert.h>
//--------------------------------------------------------------------------------------
#include <ModelAPI_AttributeBoolean.h>
if (aDump.get()) {
aDump->string("file_path")->setValue(theFilename);
aDump->string("file_format")->setValue("py");
+ std::string aTrek = GeomAlgoAPI_Tools::File_Tools::path(theFilename);
+ aDump->string("dump_dir")->setValue(aTrek);
aDump->boolean("topological_naming")->setValue((theSelectionType & CHECK_NAMING) != 0);
aDump->boolean("geometric_selection")->setValue((theSelectionType & CHECK_GEOMETRICAL) != 0);
aDump->boolean("weak_naming")->setValue((theSelectionType & CHECK_WEAK) != 0);
const QString ModuleBase_Preferences::VIEWER_SECTION = "Viewer";
const QString ModuleBase_Preferences::MENU_SECTION = "Menu";
+const QString ModuleBase_Preferences::GENERAL_SECTION = "General";
SUIT_ResourceMgr* ModuleBase_Preferences::myResourceMgr = 0;
void ModuleBase_Preferences::createEditContent(ModuleBase_IPrefMgr* thePref, int thePage)
{
thePref->prefMgr()->setItemIcon(thePage, QIcon(":pictures/module.png"));
+ createGeneralTab(thePref, thePage);
createCustomPage(thePref, thePage);
}
}
}
+void ModuleBase_Preferences::createGeneralTab(ModuleBase_IPrefMgr* thePref, int thePageId)
+{
+ int generalTab = thePref->addPreference(QObject::tr("General"), thePageId,
+ SUIT_PreferenceMgr::Auto, QString(), QString());
+ thePref->setItemProperty("columns", 2, generalTab);
+
+ QStringList actItemList;
+ actItemList << QObject::tr("Last part")
+ << QObject::tr("All parts")
+ << QObject::tr("No activation");
+
+ QList<QVariant> actIdList;
+ actIdList << 0 << 1 << 2;
+
+ // Group related to opening a study
+ int group = thePref->addPreference(QObject::tr("Opening a study"), generalTab,
+ SUIT_PreferenceMgr::Auto, QString(), QString());
+
+ int actId = thePref->addPreference(QObject::tr("Activate"), group, SUIT_PreferenceMgr::Selector,
+ ModuleBase_Preferences::GENERAL_SECTION,
+ "part_activation_study");
+ thePref->setItemProperty("strings", actItemList, actId);
+ thePref->setItemProperty("indexes", actIdList, actId);
+
+ QStringList visuItemList;
+ visuItemList << QObject::tr("As stored in HDF")
+ << QObject::tr("Last item in each folder")
+ << QObject::tr("All items")
+ << QObject::tr("No visualization");
+
+ QList<QVariant> visuIdList;
+ visuIdList << 0 << 1 << 2 << 3;
+
+ int visuId = thePref->addPreference(QObject::tr("Display"), group, SUIT_PreferenceMgr::Selector,
+ ModuleBase_Preferences::GENERAL_SECTION,
+ "part_visualization_study");
+ thePref->setItemProperty("strings", visuItemList, visuId);
+ thePref->setItemProperty("indexes", visuIdList, visuId);
+
+ // Group related to running a python script
+ group = thePref->addPreference(QObject::tr("Launching a python script"), generalTab,
+ SUIT_PreferenceMgr::Auto, QString(), QString());
+
+ visuItemList.clear();
+ visuItemList << QObject::tr("Last item in each folder")
+ << QObject::tr("All items")
+ << QObject::tr("No visualization");
+
+ visuIdList.clear();
+ visuIdList << 0 << 1 << 2;
+
+ visuId = thePref->addPreference(QObject::tr("Display"), group, SUIT_PreferenceMgr::Selector,
+ ModuleBase_Preferences::GENERAL_SECTION,
+ "part_visualization_script");
+ thePref->setItemProperty("strings", visuItemList, visuId);
+ thePref->setItemProperty("indexes", visuIdList, visuId);
+}
+
void ModuleBase_Preferences::createCustomPage(ModuleBase_IPrefMgr* thePref, int thePageId)
{
SUIT_ResourceMgr* aResMgr = ModuleBase_Preferences::resourceMgr();
/// Name of preferences of menu section
static const QString MENU_SECTION;
+ /// Name of preferences of general section
+ static const QString GENERAL_SECTION;
+
/// Shows a dialog box to edit preferences
/// \param theModified a list of modified preferences
static bool editPreferences(ModuleBase_Prefs& theModified);
/// Set default values to the Config_PropManager properties
static void resetConfig();
+ /// Creates a content for General tab, which defines behavior of loading parts and displaying shapes
+ static void createGeneralTab(ModuleBase_IPrefMgr* thePref, int thePageId);
+
/// Creates content of preferences editing widget
static void createCustomPage(ModuleBase_IPrefMgr* thePref, int thePageId);
#include <ModuleBase_ParamIntSpinBox.h>
#include <ModuleBase_ParamSpinBox.h>
+#include <ModuleBase_Preferences.h>
#include <ModuleBase_WidgetFactory.h>
#include <ModuleBase_IWorkshop.h>
#include <ModuleBase_IModule.h>
#include <ModelAPI_AttributeSelectionList.h>
#include <ModelAPI_AttributeRefList.h>
#include <ModelAPI_AttributeRefAttrList.h>
+#include <ModelAPI_ResultGroup.h>
#include <ModelAPI_ResultPart.h>
#include <ModelAPI_ResultConstruction.h>
#include <ModelAPI_AttributeString.h>
#include <ModelGeomAlgo_Point2D.h>
+#ifdef HAVE_SALOME
+#include <SUIT_Application.h>
+#include <SUIT_ResourceMgr.h>
+#include <SUIT_Session.h>
+#endif
+
#include <StdSelect_BRepOwner.hxx>
#include <TopoDS_Iterator.hxx>
#include <AIS_InteractiveContext.hxx>
//******************************************************************
+ //! Waits for REDISPLAY message and set the Visible flag to the entities
+ //! according to Preferences choice.
+ class ModuleBase_RedisplayListener : public Events_Listener
+ {
+ public:
+ static std::shared_ptr<ModuleBase_RedisplayListener> instance()
+ {
+ static std::shared_ptr<ModuleBase_RedisplayListener>
+ anInstance(new ModuleBase_RedisplayListener);
+ return anInstance;
+ }
+
+ void processEvent(const std::shared_ptr<Events_Message>& theMessage)
+ {
+ if (theMessage->eventID() == Events_Loop::eventByName(EVENT_OBJECT_TO_REDISPLAY))
+ {
+#if HAVE_SALOME
+ // If the python script is being loaded now, the preferences should be used
+ // to display the required object
+ SUIT_Session* aSession = SUIT_Session::session();
+ if (!aSession)
+ return;
+ SUIT_Application * anApp = aSession->activeApplication();
+ if (!anApp)
+ return;
+ QVariant aVar = anApp->property("IsLoadedScript");
+ if (!aVar.isNull() && aVar.toBool()) {
+ DocumentPtr aRootDoc = ModelAPI_Session::get()->moduleDocument();
+ int aSize = aRootDoc->size(ModelAPI_ResultPart::group());
+ if (aSize > 0) {
+ ObjectPtr anPartObject = aRootDoc->object(ModelAPI_ResultPart::group(), aSize - 1);
+ ResultPartPtr aPart = std::dynamic_pointer_cast<ModelAPI_ResultPart>(anPartObject);
+ ModuleBase_Tools::setDisplaying(aPart, true);
+ }
+ }
+#endif
+ }
+ }
+
+ private:
+ ModuleBase_RedisplayListener()
+ {
+ Events_Loop::loop()->registerListener(this,
+ Events_Loop::eventByName(EVENT_OBJECT_TO_REDISPLAY));
+ }
+ };
+
+ static std::shared_ptr<ModuleBase_RedisplayListener>
+ RL = ModuleBase_RedisplayListener::instance();
+
//******************************************************************
void adjustMargins(QWidget* theWidget)
}
+// Set displaying status to every element on group
+static void setDisplayingByLoop(DocumentPtr theDoc, int theSize,
+ std::string theGroup, bool theDisplayFromScript)
+{
+ int aDisplayingId = -1;
+ if (theDisplayFromScript) {
+ aDisplayingId = ModuleBase_Preferences::resourceMgr()->integerValue("General",
+ "part_visualization_script", -1);
+ // Increase ID to prevert using "As stored in HDF"
+ ++aDisplayingId;
+ }
+ else {
+ aDisplayingId = ModuleBase_Preferences::resourceMgr()->integerValue("General",
+ "part_visualization_study", -1);
+
+ // if chosen "As stored in HDF" then don't change displaying
+ if (aDisplayingId == 0)
+ return;
+ }
+
+ for (int anIndex = theSize - 1; anIndex >= 0; --anIndex) {
+ ObjectPtr anObject = theDoc->object(theGroup, anIndex);
+ anObject->setDisplayed((aDisplayingId == 1 && anIndex == theSize - 1) || aDisplayingId == 2);
+ }
+}
+
+void setDisplaying(ResultPartPtr thePart, bool theDisplayFromScript)
+{
+ DocumentPtr aDoc = thePart->partDoc();
+ int aConstructionSize = aDoc->size(ModelAPI_ResultConstruction::group());
+ int aGroupSize = aDoc->size(ModelAPI_ResultGroup::group());
+ int aFieldSize = aDoc->size(ModelAPI_ResultField::group());
+ int aResultSize = aDoc->size(ModelAPI_ResultBody::group());
+ setDisplayingByLoop(aDoc, aConstructionSize,
+ ModelAPI_ResultConstruction::group(), theDisplayFromScript);
+ setDisplayingByLoop(aDoc, aGroupSize, ModelAPI_ResultGroup::group(), theDisplayFromScript);
+ setDisplayingByLoop(aDoc, aFieldSize, ModelAPI_ResultField::group(), theDisplayFromScript);
+ setDisplayingByLoop(aDoc, aResultSize, ModelAPI_ResultBody::group(), theDisplayFromScript);
+}
+
} // namespace ModuleBase_Tools
/// Returns pixel ratio of a screen where main window is displayed
qreal MODULEBASE_EXPORT currentPixelRatio();
+
+/// Set displaying status for elements from part depending on the settings
+/// \param thePart a pointer of part
+void MODULEBASE_EXPORT setDisplaying(std::shared_ptr<ModelAPI_ResultPart> thePart,
+ bool theDisplayFromScript = false);
}
#endif
<source>Replace</source>
<translation>Remplacer</translation>
</message>
- <message>
- <source>Trihedron arrows constant size</source>
- <translation>Flèche trièdre de taille constante</translation>
- </message>
+ <message>
+ <source>Trihedron arrows constant size</source>
+ <translation>Flèche trièdre de taille constante</translation>
+ </message>
<message>
<source>Keep trihedron arrows view size constant</source>
<translation>Maintenir la taille de la vue des flèches trièdres constante</translation>
</message>
+ <message>
+ <source>General</source>
+ <translation>Général</translation>
+ </message>
+ <message>
+ <source>Opening a study</source>
+ <translation>Ouverture d'une étude</translation>
+ </message>
+ <message>
+ <source>Launching a python script</source>
+ <translation>Lancement d'un script python</translation>
+ </message>
+ <message>
+ <source>Activate</source>
+ <translation>Activation</translation>
+ </message>
+ <message>
+ <source>Display</source>
+ <translation>Visualisation</translation>
+ </message>
+ <message>
+ <source>Last part</source>
+ <translation>Dernière pièce</translation>
+ </message>
+ <message>
+ <source>All parts</source>
+ <translation>Toutes les pièces</translation>
+ </message>
+ <message>
+ <source>No activation</source>
+ <translation>Aucune</translation>
+ </message>
+ <message>
+ <source>As stored in HDF</source>
+ <translation>Comme dans le HDF</translation>
+ </message>
+ <message>
+ <source>Last item in each folder</source>
+ <translation>Le dernier élément de chaque dossier</translation>
+ </message>
+ <message>
+ <source>All items</source>
+ <translation>Tous les éléments</translation>
+ </message>
+ <message>
+ <source>No visualization</source>
+ <translation>Aucune visualisation</translation>
+ </message>
</context>
</TS>
isModified = true;
}
else {
- if (myFeature->firstResult().get() && myFeature->firstResult()->hasTextureFile())
- {
- PartSet_Module::setTexture( myFeature->firstResult()->getTextureFile(), aPresentation);
+ if (myFeature->firstResult().get()) {
+ PartSet_Module::setTexture(aPresentation, myFeature->firstResult());
}
anOperationPrs->Redisplay();
isModified = true;
#include <XGUI_DataModel.h>
#include <XGUI_OperationMgr.h>
#include <XGUI_ObjectsBrowser.h>
+#include <XGUI_Tools.h>
#include <XGUI_ViewerProxy.h>
#include <Events_Loop.h>
void PartSet_MenuMgr::activatePart(ResultPartPtr thePart) const
{
bool isFirstLoad = !thePart->partDoc().get();
+ ModuleBase_Tools::blockUpdateViewer(true);
thePart->activate();
if (isFirstLoad) {
XGUI_Workshop* aWorkshop = myModule->getWorkshop();
XGUI_ObjectsBrowser* aObjBrowser = aWorkshop->objectBrowser();
+ ModuleBase_Tools::setDisplaying(thePart);
+ Events_Loop::loop()->flush(Events_Loop::eventByName(EVENT_OBJECT_TO_REDISPLAY));
+ aObjBrowser->onSelectionChanged();
DocumentPtr aDoc = thePart->partDoc();
std::list<bool> aStates;
aDoc->restoreNodesState(aStates);
aObjBrowser->setStateForDoc(aDoc, aStates);
}
+ ModuleBase_Tools::blockUpdateViewer(false);
}
void PartSet_MenuMgr::onActivateAllParts()
#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 <SelectMgr_ListIteratorOfListOfFilter.hxx>
#include <Graphic3d_Texture2Dmanual.hxx>
-#ifdef HAVE_SALOME
-#include <OCCViewer_Utilities.h>
-#endif
#define FEATURE_ITEM_COLOR "0,0,225"
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);
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();
+ aPixmap->InitTrash(Image_PixMap::ImgBGRA, aWidth, aHeight);
+ 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));
anAISShape->SetDisplayMode(AIS_Shaded);
}
}
-#endif
}
//******************************************************
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);
} 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);
+ }
}
}
}
virtual void createFeatures();
/// add texture
- static void setTexture(const std::string &theTextureFile, const AISObjectPtr& thePrs);
+ static void setTexture(const AISObjectPtr& thePrs, const ResultPtr& theResult);
public slots:
/// Slolt called on object display
} else {
DocumentPtr aDoc = myObject->document();
SessionPtr aSession = ModelAPI_Session::get();
+
+ FeaturePtr aFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(myObject);
+ if (aFeature.get() && aFeature->getKind() == "Group")
+ {
+ std::shared_ptr<ModelAPI_CompositeFeature> anOwner =
+ ModelAPI_Tools::compositeOwner (aFeature);
+
+ if (anOwner.get() && anOwner->getKind() == "ImportResult")
+ return aDefaultFlag;
+ }
+
if (aSession->activeDocument() == aDoc)
return aEditingFlag;
}
ModelAPI_Session::get()->startOperation(ExchangePlugin_Dump::ID());
FeaturePtr aFeature = aDoc->addFeature(ExchangePlugin_Dump::ID());
if (aFeature.get()) {
+ // keep path to the true dumping directory for external files dumping
+ AttributeStringPtr aAttr = aFeature->string(ExchangePlugin_Dump::DUMP_DIR_ID());
+ if (aAttr.get()) {
+ QString aDirPath = QFileInfo(thePath).path();
+ aAttr->setValue(aDirPath.toStdString());
+ }
+
+ // tmp path to write the script
std::string aTmpDir = aStudy->GetTmpDir(thePath.toStdString().c_str(), isMultiFile);
std::string aFileName = aTmpDir + DUMP_NAME;
QFile::remove(aFileName.c_str());
}
- AttributeStringPtr aAttr = aFeature->string(ExchangePlugin_Dump::FILE_PATH_ID());
+ aAttr = aFeature->string(ExchangePlugin_Dump::FILE_PATH_ID());
if (aAttr.get())
aAttr->setValue(aFileName);
ModelAPI_Session::get()->finishOperation();
if (QFile::exists(aFileName.c_str())) {
- QFile aInFile(aFileName.c_str());
+ QFile aInFile(aFileName.c_str());
if (!aInFile.open(QIODevice::ReadOnly | QIODevice::Text))
return false;
QTextStream aText(&aInFile);
<parameter name="PartSet" value="%SHAPER_ROOT_DIR%/share/salome/resources/shaper"/>
<parameter name="XGUI" value="%SHAPER_ROOT_DIR%/share/salome/resources/shaper"/>
</section>
+ <section name="General">
+ <!-- Common settings of part's activation and visualization -->
+ <parameter name="part_activation_study" value="0"/>
+ <parameter name="part_visualization_study" value="0"/>
+ <parameter name="part_visualization_script" value="1"/>
+ </section>
<section name="Viewer" >
<!-- Viewer preferences -->
<parameter name="face-selection" value="true" />
<parameter name="language" value="en"/>
<parameter name="locale" value="true"/>
</section>
+ <section name="General">
+ <!-- Common settings of part's activation and visualization -->
+ <parameter name="part_activation_study" value="0"/>
+ <parameter name="part_visualization_study" value="0"/>
+ <parameter name="part_visualization_script" value="1"/>
+ </section>
<section name="Viewer" >
<!-- Viewer preferences -->
<parameter name="background" value="bt=2;fn=;tm=0;ts=false;c1=#cddbff;c2=#698fff;gt=1;gr=" />
}
#endif
+ int anActivationId =
+ ModuleBase_Preferences::resourceMgr()->integerValue("General", "part_activation_study", -1);
+ int aSize = aRootDoc->size(ModelAPI_ResultPart::group());
+
+ if (anActivationId == 0 && aSize > 0) {
+ ObjectPtr anObject = aRootDoc->object(ModelAPI_ResultPart::group(), aSize - 1);
+ ResultPartPtr aPart = std::dynamic_pointer_cast<ModelAPI_ResultPart>(anObject);
+ if (aPart.get()) {
+ aPart->activate();
+ ModuleBase_Tools::setDisplaying(aPart);
+ }
+ }
+ else if (anActivationId == 1) {
+ for (int anIndex = 0; anIndex < aSize; ++anIndex) {
+ ObjectPtr anObject = aRootDoc->object(ModelAPI_ResultPart::group(), anIndex);
+ ResultPartPtr aPart = std::dynamic_pointer_cast<ModelAPI_ResultPart>(anObject);
+ if (aPart.get()) {
+ aPart->activate();
+ ModuleBase_Tools::setDisplaying(aPart);
+
+ if (anIndex < aSize - 1) {
+ SessionPtr aMgr = ModelAPI_Session::get();
+ aMgr->startOperation("Activation");
+ aMgr->setActiveDocument(aMgr->moduleDocument());
+ aMgr->finishOperation();
+ updateCommandStatus();
+ viewer()->update();
+ }
+ }
+ }
+ }
QApplication::restoreOverrideCursor();
}
#include <ModuleBase_Tools.h>
#include <ModuleBase_WidgetSelector.h>
+#ifdef HAVE_SALOME
+#include <SUIT_Application.h>
+#include <SUIT_Session.h>
+#endif
+
#include "XGUI_ActionsMgr.h"
#include "XGUI_Displayer.h"
#include "XGUI_ErrorMgr.h"
#include "XGUI_OperationMgr.h"
#include "XGUI_ModuleConnector.h"
#include "XGUI_PropertyPanel.h"
-
#include "XGUI_QtEvents.h"
#include "XGUI_SalomeConnector.h"
#include "XGUI_SelectionMgr.h"
}
}
}
+
// this processing should be moved in another place in order to do not cause problems in
// flush messages chain
//if (aHiddenObjects.size() > 0)
void XGUI_WorkshopListener::
onFeatureCreatedMsg(const std::shared_ptr<ModelAPI_ObjectUpdatedMessage>& theMsg)
{
+ SUIT_Application * app = SUIT_Session::session()->activeApplication();
+
+ QVariant aVar = app->property("IsLoadedScript");
+
std::set<ObjectPtr> anObjects = theMsg->objects();
std::set<ObjectPtr>::const_iterator aIt;
#ifdef DEBUG_FEATURE_CREATED
//bool aHasPart = false;
bool aDisplayed = false;
- for (aIt = anObjects.begin(); aIt != anObjects.end(); ++aIt) {
- ObjectPtr anObject = *aIt;
+ if (aVar.isNull() || !aVar.toBool()) {
+ for (aIt = anObjects.begin(); aIt != anObjects.end(); ++aIt) {
+ ObjectPtr anObject = *aIt;
#ifdef DEBUG_RESULT_COMPSOLID
- ResultPtr aRes = std::dynamic_pointer_cast<ModelAPI_Result>(anObject);
- if (aRes.get()) {
- ResultCompSolidPtr aCompSolidRes = std::dynamic_pointer_cast<ModelAPI_ResultCompSolid>(aRes);
- if (aCompSolidRes.get()) {
- qDebug(QString("COMPSOLID, numberOfSubs = %1")
- .arg(aCompSolidRes->numberOfSubs()).toStdString().c_str());
+ ResultPtr aRes = std::dynamic_pointer_cast<ModelAPI_Result>(anObject);
+ if (aRes.get()) {
+ ResultCompSolidPtr aCompSolidRes = std::dynamic_pointer_cast<ModelAPI_ResultCompSolid>(aRes);
+ if (aCompSolidRes.get()) {
+ qDebug(QString("COMPSOLID, numberOfSubs = %1")
+ .arg(aCompSolidRes->numberOfSubs()).toStdString().c_str());
+ }
+ if (ModelAPI_Tools::compSolidOwner(aRes))
+ qDebug("COMPSOLID sub-object");
}
- if (ModelAPI_Tools::compSolidOwner(aRes))
- qDebug("COMPSOLID sub-object");
- }
#endif
- // the validity of the data should be checked here in order to avoid display of the objects,
- // which were created, then deleted, but flush for the creation event happens after that
- // we should not display disabled objects
- bool aHide = !anObject->data()->isValid() ||
- anObject->isDisabled() ||
- !anObject->isDisplayed();
- if (!aHide) { // check that this is not hidden result
- ResultPtr aRes = std::dynamic_pointer_cast<ModelAPI_Result>(anObject);
- aHide = aRes && aRes->isConcealed();
- // Hide the presentation with an empty shape. But isDisplayed state of the object should not
- // be changed to the object becomes visible when the shape becomes not empty
- if (!aHide && aRes.get())
- aHide = !aRes->shape().get() || aRes->shape()->isNull();
- }
- if (!aHide) {
- // setDisplayed has to be called in order to synchronize internal state of the object
- // with list of displayed objects
- if (myWorkshop->module()->canDisplayObject(anObject)) {
- anObject->setDisplayed(true);
- aDisplayed = displayObject(anObject);
- } else
- anObject->setDisplayed(false);
+
+ ResultBodyPtr aRes = std::dynamic_pointer_cast<ModelAPI_ResultBody>(anObject);
+
+ if (aRes.get() && aRes->numberOfSubs() > 0)
+ for (int anIndex = 0; anIndex < aRes->numberOfSubs(); ++anIndex)
+ setDisplayed(aRes->subResult(anIndex), aDisplayed);
+ else
+ setDisplayed(anObject, aDisplayed);
}
}
-
MAYBE_UNUSED bool isCustomized = customizeFeature(anObjects, aDisplayed);
//if (myObjectBrowser)
{
return myWorkshop;
}
+
+
+void XGUI_WorkshopListener::setDisplayed(ObjectPtr theObject, bool& theDisplayed)
+{
+ // the validity of the data should be checked here in order to avoid display of the objects,
+ // which were created, then deleted, but flush for the creation event happens after that
+ // we should not display disabled objects
+ bool aHide = !theObject->data()->isValid() ||
+ theObject->isDisabled() ||
+ !theObject->isDisplayed();
+ if (!aHide) { // check that this is not hidden result
+ ResultPtr aRes = std::dynamic_pointer_cast<ModelAPI_Result>(theObject);
+ aHide = aRes && aRes->isConcealed();
+ // Hide the presentation with an empty shape. But isDisplayed state of the object should not
+ // be changed to the object becomes visible when the shape becomes not empty
+ if (!aHide && aRes.get())
+ aHide = !aRes->shape().get() || aRes->shape()->isNull();
+ }
+ if (!aHide) {
+ // setDisplayed has to be called in order to synchronize internal state of the object
+ // with list of displayed objects
+ if (myWorkshop->module()->canDisplayObject(theObject)) {
+ theObject->setDisplayed(true);
+ theDisplayed = displayObject(theObject);
+ }
+ else
+ theObject->setDisplayed(false);
+ }
+}
XGUI_Workshop* workshop() const;
private:
+
+ void setDisplayed(ObjectPtr theObject, bool& theDisplayed);
+
XGUI_Workshop* myWorkshop; // the current workshop
bool myUpdatePrefs;