From: asozinov Date: Fri, 17 Feb 2023 00:16:09 +0000 (+0000) Subject: Set colors on subshape: X-Git-Url: http://git.salome-platform.org/gitweb/?a=commitdiff_plain;h=7c5f94f9ec8a6f64ad00f3899feae48c87630e52;p=modules%2Fshaper.git Set colors on subshape: - Added: Added ability to assign colors on subshape of shape. This work for Part and for PartSet - Modified Python dump: can dump colored objects to python script: For object inside part: Cylinder_1.result().setColor(model.selection("FACE", "Cylinder_1_1/Face_2"), 85, 170, 0) For PartSet: Part_1.result().setColor(model.selection("FACE", "Part_1/Sphere_1_1/Face_1"), 249, 225, 104) - In Preferences -> Shaper -> Visualization: Added checkbox for enable/disable this functionality - Set color on subshape of result --- diff --git a/src/ExchangePlugin/ExchangePlugin_ExportFeature.cpp b/src/ExchangePlugin/ExchangePlugin_ExportFeature.cpp index b536f54ef..9fb5a8a22 100644 --- a/src/ExchangePlugin/ExchangePlugin_ExportFeature.cpp +++ b/src/ExchangePlugin/ExchangePlugin_ExportFeature.cpp @@ -223,6 +223,9 @@ void ExchangePlugin_ExportFeature::exportFile(const std::string& theFileName, } else if (aFormatName == "STL") { exportSTL(theFileName); return; + }else if (aFormatName == "STEP") { + exportSTEP(theFileName); + return; } // make shape for export from selected shapes @@ -258,10 +261,11 @@ void ExchangePlugin_ExportFeature::exportFile(const std::string& theFileName, bool aResult = false; if (aFormatName == "BREP") { aResult = BREPExport(theFileName, aFormatName, aShape, anError); - } else if (aFormatName == "STEP") { - aResult = STEPExport(theFileName, aShapes, aContexts, anError); } else if (aFormatName.substr(0, 4) == "IGES") { aResult = IGESExport(theFileName, aFormatName, aShape, anError); + } else if (aFormatName == "STEP") + { + aResult = STEPExport(theFileName, aShapes, aContexts, anError); } else { anError = "Unsupported format: " + aFormatName; } @@ -643,6 +647,49 @@ void ExchangePlugin_ExportFeature::exportXAO(const std::string& theFileName, // LCOV_EXCL_STOP } +void ExchangePlugin_ExportFeature::exportSTEP(const std::string & theFileName) +{ + AttributeSelectionListPtr aSelectionList = + selectionList(ExchangePlugin_ExportFeature::SELECTION_LIST_ID()); + + std::list aShapeList; + std::string anError; + std::map> aColoredShapes; + for (int anIndex = 0; anIndex < aSelectionList->size(); ++anIndex) + { + AttributeSelectionPtr anAttrSelection = aSelectionList->value(anIndex); + std::shared_ptr aCurShape = anAttrSelection->value(); + if (!aCurShape.get()) + aCurShape = anAttrSelection->context()->shape(); + if (!aCurShape.get()) + continue; + //#ifndef HAVE_SALOME + ResultPtr aRes = anAttrSelection->context(); + std::vector aColor; + ModelAPI_Tools::getColor(aRes, aColor); + ModelAPI_Tools::getColoredShapes(aRes, aColoredShapes); + if (aColor.size() == 3) + { + aColoredShapes[aCurShape] = aColor; + } + //#endif + aShapeList.push_back(aCurShape); + } + std::shared_ptr aShape = + aShapeList.size() == 1 ? aShapeList.front() : GeomAlgoAPI_CompoundBuilder::compound(aShapeList); + #ifndef HAVE_SALOME + bool aRes = true;// STEPExport(theFileName, aShape, aColoredShapes, anError); + #else + bool aRes = STEPExport(theFileName, aShape, aColoredShapes, anError); + #endif + + if (!anError.empty() || !aRes) + { + setError("An error occurred while exporting " + theFileName + ": " + anError); + return; + } + } + bool ExchangePlugin_ExportFeature::isMacro() const { if (!data().get() || !data()->isValid()) diff --git a/src/ExchangePlugin/ExchangePlugin_ExportFeature.h b/src/ExchangePlugin/ExchangePlugin_ExportFeature.h index 295aa7618..e87ad47c1 100644 --- a/src/ExchangePlugin/ExchangePlugin_ExportFeature.h +++ b/src/ExchangePlugin/ExchangePlugin_ExportFeature.h @@ -214,6 +214,9 @@ protected: /// Performs export to STL file EXCHANGEPLUGIN_EXPORT void exportSTL(const std::string& theFileName); + + /// Performs export to STEP file + EXCHANGEPLUGIN_EXPORT void exportSTEP(const std::string & theFileName); }; #endif /* EXPORT_EXPORTFEATURE_H_ */ diff --git a/src/GeomAPI/GeomAPI_AISObject.cpp b/src/GeomAPI/GeomAPI_AISObject.cpp index fba0ed2ff..3d18fb85e 100644 --- a/src/GeomAPI/GeomAPI_AISObject.cpp +++ b/src/GeomAPI/GeomAPI_AISObject.cpp @@ -32,6 +32,7 @@ #include #include +#include #include #include #include @@ -387,6 +388,19 @@ bool GeomAPI_AISObject::setColor(int theR, int theG, int theB) return true; } +bool GeomAPI_AISObject::setColor(const std::shared_ptr& theSubShape, + int theR, int theG, int theB) +{ + Handle(AIS_InteractiveObject) anAIS = impl(); + if (anAIS.IsNull()) + return false; + Quantity_Color aColor(theR / 255., theG / 255., theB / 255., Quantity_TOC_RGB); + + Handle(AIS_ColoredShape) aShape = Handle(AIS_ColoredShape)::DownCast(anAIS); + aShape->SetCustomColor(theSubShape->impl(), aColor); + return true; +} + void GeomAPI_AISObject::getColor(int& theR, int& theG, int& theB) { Handle(AIS_InteractiveObject) anAIS = impl(); diff --git a/src/GeomAPI/GeomAPI_AISObject.h b/src/GeomAPI/GeomAPI_AISObject.h index 2812845b3..7e9bd5742 100644 --- a/src/GeomAPI/GeomAPI_AISObject.h +++ b/src/GeomAPI/GeomAPI_AISObject.h @@ -127,6 +127,16 @@ class GeomAPI_AISObject : public GeomAPI_Interface GEOMAPI_EXPORT bool setColor(int theR, int theG, int theB); + /** \brief Assigns the color for the subshape + * \param[in] theSubShape subshape that belongs to shape + * \param[in] theR value of the red component + * \param[in] theG value of the green component + * \param[in] theB value of the blue component + */ + GEOMAPI_EXPORT + bool setColor(const std::shared_ptr& theSubShape, + int theR, int theG, int theB); + /** \brief Returns the color for the shape * \param[in] theR value of the red component * \param[in] theG value of the green component diff --git a/src/GeomAlgoAPI/GeomAlgoAPI_STEPExport.cpp b/src/GeomAlgoAPI/GeomAlgoAPI_STEPExport.cpp index 651b1b401..890813a69 100644 --- a/src/GeomAlgoAPI/GeomAlgoAPI_STEPExport.cpp +++ b/src/GeomAlgoAPI/GeomAlgoAPI_STEPExport.cpp @@ -35,6 +35,8 @@ #include #include #include +#include +#include #include @@ -184,3 +186,146 @@ bool STEPExport(const std::string& theFileName, } return theError.empty(); } + +bool STEPExport(const std::string& theFileName, + const std::shared_ptr& theShape, + std::map, std::vector>& theColoredShapes, + std::string& theError) +{ + Handle(TDocStd_Document) aDoc = new TDocStd_Document("MDTV-CAF"); +#ifdef _DEBUG + std::cout << "Export STEP into file " << theFileName << std::endl; +#endif + GeomAlgoAPI_Tools::Localizer loc; + + Handle(XSControl_WorkSession) aWS = new XSControl_WorkSession(); + STEPCAFControl_Writer aWriter(aWS, false); + aWriter.SetColorMode(true); + aWriter.SetNameMode(true); + + IFSelect_ReturnStatus aStatus; + //VRV: OCC 4.0 migration + Interface_Static::SetCVal("xstep.cascade.unit", "M"); + Interface_Static::SetCVal("write.step.unit", "M"); + Interface_Static::SetIVal("write.step.nonmanifold", 1); + + TopoDS_Shape aShape = theShape->impl(); + Handle(XCAFDoc_ShapeTool) aShapeTool = XCAFDoc_DocumentTool::ShapeTool(aDoc->Main()); + Handle(XCAFDoc_ColorTool) aColorTool = XCAFDoc_DocumentTool::ColorTool(aDoc->Main()); + + TDF_Label aShapeLabel = aShapeTool->AddShape(aShape, false); + TDF_Label aRefShapeLab; + if (aShapeTool->GetReferredShape(aShapeLabel, aRefShapeLab)) + aShapeLabel = aRefShapeLab; + + if (theColoredShapes.find(theShape) != theColoredShapes.end()) + { + std::vector aColor = theColoredShapes.find(theShape)->second; + Quantity_Color aQColor(aColor[0] / 255., + aColor[1] / 255., + aColor[2] / 255., + Quantity_TOC_RGB); + aColorTool->SetColor(aShapeLabel, aQColor, XCAFDoc_ColorGen); + theColoredShapes.erase(theShape); + } + + for (std::map>::iterator anIter(theColoredShapes.begin()); + anIter != theColoredShapes.end(); ++anIter) + { + TopoDS_Shape aSubShape = (anIter->first)->impl(); + if (aSubShape.IsNull()) + continue; + bool sub = theShape->isSubShape(anIter->first); + Quantity_Color aColor(anIter->second.at(0) / 255., + anIter->second.at(1) / 255., + anIter->second.at(2) / 255., + Quantity_TOC_RGB); + TDF_Label aSubShapeLabel; + aShapeTool->Search(aShape, aSubShapeLabel); + if (!aSubShapeLabel.IsNull()) + { + aColorTool->SetColor(aSubShapeLabel, aColor, XCAFDoc_ColorSurf); + } + } + /*for (TopExp_Explorer aFaceExp(aShape, TopAbs_FACE); aFaceExp.More(); aFaceExp.Next()) + { + TDF_Label aSubShapeLabel; + std::shared_ptr aFace(new GeomAPI_Shape); + aFace->setImpl(new TopoDS_Shape(aFaceExp.Value())); + if (theColoredShapes.find(theShape) == theColoredShapes.end()) + continue; + aShapeTool->Search(aFaceExp.Value(), aSubShapeLabel); + if (!aSubShapeLabel.IsNull()) + { + std::vector aColor = theColoredShapes.find(theShape)->second; + Quantity_Color aQColor(aColor[0] / 255., + aColor[1] / 255., + aColor[2] / 255., + Quantity_TOC_RGB); + aColorTool->SetColor(aSubShapeLabel, aQColor, XCAFDoc_ColorSurf); + } + }*/ + /*for (std::map>::const_iterator anIter(theColoredShapes.cbegin()); + anIter != theColoredShapes.cend(); ++anIter) + { + TopoDS_Shape aSubShape = (anIter->first)->impl(); + if (aSubShape.IsNull()) + continue; + bool sub = theShape->isSubShape(anIter->first); + Quantity_Color aColor(anIter->second.at(0) / 255., + anIter->second.at(1) / 255., + anIter->second.at(2) / 255., + Quantity_TOC_RGB); + //TDF_Label aColorLabel = aColorTool->AddColor(aColor); + TDF_Label aSubShapeLabel = aShape.IsEqual(aSubShape) ? + aShapeLabel : aShapeTool->AddSubShape(aShapeLabel, aSubShape); + aColorTool->SetColor(aSubShapeLabel, aColor, + aShape.IsEqual(aSubShape) ? XCAFDoc_ColorGen : XCAFDoc_ColorSurf); + }*/ + + ///////////////// + TDF_LabelSequence aLabels; + aColorTool->GetColors(aLabels); + Standard_Integer i, nbc = aLabels.Length(); + for (i = 1; i <= nbc; ++i) + { + Quantity_Color aColorQ; + TDF_Label aLabel = aLabels.Value(i); + aColorTool->GetColor(aLabel, aColorQ); + int a = 0; + } + TDF_LabelSequence aShapesL; + aShapeTool->GetFreeShapes(aShapesL); + nbc = aShapesL.Length(); + for (i = 1; i <= nbc; ++i) + { + Quantity_Color aColorR; + TDF_LabelSequence aSubShapesL; + TopoDS_Shape aShape2; + aShapeTool->GetShape(aShapesL.Value(i), aShape2); + TDF_Label aShapeLabel = aShapeTool->FindShape(aShape2); + aColorTool->GetColor(aShapeLabel, XCAFDoc_ColorGen, aColorR); + aShapeTool->GetSubShapes(aShapesL.Value(i), aSubShapesL); + for (TDF_LabelSequence::Iterator aLabIt(aSubShapesL); aLabIt.More(); aLabIt.Next()) + { + const TDF_Label& aSubShapeLab = aLabIt.Value(); + TopoDS_Shape aSubShape = aShapeTool->GetShape(aSubShapeLab); + aColorTool->GetColor(aSubShapeLab, XCAFDoc_ColorSurf, aColorR); + } + } + ///////////////////// + bool aaaaaa = aWriter.GetColorMode(); + if (!aWriter.Transfer(aDoc, STEPControl_AsIs)) + { + theError = "Error: Failed transfer to file."; + return false; + } + aStatus = aWriter.Write(theFileName.c_str()); + if (aStatus != IFSelect_RetDone) + { + + theError = "Error: Failed write to file."; + return false; + } + return true; +} diff --git a/src/GeomAlgoAPI/GeomAlgoAPI_STEPExport.h b/src/GeomAlgoAPI/GeomAlgoAPI_STEPExport.h index d56d7d083..ca6edab4d 100644 --- a/src/GeomAlgoAPI/GeomAlgoAPI_STEPExport.h +++ b/src/GeomAlgoAPI/GeomAlgoAPI_STEPExport.h @@ -23,6 +23,8 @@ #include #include +#include +#include #include #include @@ -38,4 +40,10 @@ bool STEPExport(const std::string& theFileName, const std::list >& theResults, std::string& theError); +GEOMALGOAPI_EXPORT +bool STEPExport(const std::string& theFileName, + const std::shared_ptr& theShape, + std::map, std::vector>& theColoredShapes, + std::string& theError); + #endif /* GEOMALGOAPI_STEPEXPORT_H_ */ diff --git a/src/GeomAlgoAPI/GeomAlgoAPI_STEPImportXCAF.cpp b/src/GeomAlgoAPI/GeomAlgoAPI_STEPImportXCAF.cpp index f6dc6595d..bb44bb7a0 100644 --- a/src/GeomAlgoAPI/GeomAlgoAPI_STEPImportXCAF.cpp +++ b/src/GeomAlgoAPI/GeomAlgoAPI_STEPImportXCAF.cpp @@ -104,13 +104,39 @@ std::shared_ptr readAttributes(STEPCAFControl_Reader &theReader, // XCAF Document to contain the STEP/IGES file itself Handle(TDocStd_Document) adoc; - dummy_app->NewDocument( TCollection_ExtendedString("MDTV-CAF"), adoc); + dummy_app->NewDocument( TCollection_ExtendedString("BinSTEP"), adoc); // transfer STEP/IGES into the document, and get the main label theReader.Transfer(adoc); TDF_Label mainLabel = adoc->Main(); Handle_XCAFDoc_ShapeTool shapeTool = XCAFDoc_DocumentTool::ShapeTool(mainLabel); Handle_XCAFDoc_ColorTool colorTool = XCAFDoc_DocumentTool::ColorTool(mainLabel); Handle(XCAFDoc_MaterialTool) materialTool = XCAFDoc_DocumentTool::MaterialTool(mainLabel); + TDF_LabelSequence aLabels, aLabelSS; + colorTool->GetColors(aLabels); + Standard_Integer i, nbc = aLabels.Length(); + for (i = 1; i <= nbc; ++i) + { + Quantity_Color aColorQ; + TDF_Label aLabel = aLabels.Value(i); + colorTool->GetColor(aLabel, aColorQ); + } + + shapeTool->GetShapes(aLabels); + Quantity_Color aColorR; + for (TDF_LabelSequence::Iterator aLabIt(aLabels); aLabIt.More(); aLabIt.Next()) + { + const TDF_Label& aShapeLabel = aLabIt.Value(); + TopoDS_Shape aSubShape = shapeTool->GetShape(aShapeLabel); + shapeTool->GetSubShapes(aShapeLabel, aLabelSS); + colorTool->GetColor(aShapeLabel, XCAFDoc_ColorGen, aColorR); + for (TDF_LabelSequence::Iterator aLabIt2(aLabelSS); aLabIt2.More(); aLabIt2.Next()) + { + const TDF_Label& aSubShapeLab = aLabIt.Value(); + TopoDS_Shape aSubShape = shapeTool->GetShape(aSubShapeLab); + colorTool->GetColor(aSubShapeLab, XCAFDoc_ColorSurf, aColorR); + } + } + // traverse the labels recursively to set attributes on shapes setShapeAttributes(shapeTool, colorTool, materialTool, mainLabel, TopLoc_Location(),theResultBody,theMaterialShape,false); @@ -297,8 +323,7 @@ void setShapeAttributes(const Handle(XCAFDoc_ShapeTool) &theShapeTool, aShapeface.Move(theLoc); } aShapeGeom->setImpl(new TopoDS_Shape(aShapeface)); - theResultBody->addShapeColor( - theResultBody->addShapeName(aShapeGeom , aNameFace.str()), aColRGB); + theResultBody->addShapeColor(theResultBody->addShapeName(aShapeGeom, aNameFace.str()), aColRGB); } aXp2.Next(); } diff --git a/src/Model/Model_Data.cpp b/src/Model/Model_Data.cpp index 28237c24e..9feeb2239 100644 --- a/src/Model/Model_Data.cpp +++ b/src/Model/Model_Data.cpp @@ -121,6 +121,29 @@ std::wstring Model_Data::name() return L""; // not defined } +std::wstring Model_Data::name(std::shared_ptr theSubShape) +{ + std::wstring aShapeName = L""; + std::wstring aResultName = name(); + if (aResultName == L"") + return aShapeName; + + AttributeSelectionPtr aSelectionAttribute; + ResultBodyPtr aResBody = std::dynamic_pointer_cast(myObject); + if (aResBody.get()) + aSelectionAttribute = aResBody->selection(); + else + { + ResultPartPtr aPart = std::dynamic_pointer_cast(myObject); + aSelectionAttribute = aPart->selection(); + } + aSelectionAttribute->setValue(myObject, theSubShape); + aShapeName = aSelectionAttribute->namingName(); + aSelectionAttribute->reset(); + + return aShapeName; +} + void Model_Data::setName(const std::wstring& theName) { bool isModified = false; diff --git a/src/Model/Model_Data.h b/src/Model/Model_Data.h index 82703d70c..241bf1d3b 100644 --- a/src/Model/Model_Data.h +++ b/src/Model/Model_Data.h @@ -47,6 +47,7 @@ #include #include #include +#include #include class ModelAPI_Attribute; @@ -104,6 +105,8 @@ class Model_Data : public ModelAPI_Data Model_Data(); /// Returns the name of the feature visible by the user in the object browser MODEL_EXPORT virtual std::wstring name(); + /// Returns the name of the shape + MODEL_EXPORT virtual std::wstring name(std::shared_ptr theSubShape); /// Defines the name of the feature visible by the user in the object browser MODEL_EXPORT virtual void setName(const std::wstring& theName); /// Return \c true if the object has been renamed by the user diff --git a/src/Model/Model_Document.cpp b/src/Model/Model_Document.cpp index 5f313a855..c608f3421 100644 --- a/src/Model/Model_Document.cpp +++ b/src/Model/Model_Document.cpp @@ -50,6 +50,7 @@ #include #include #include +#include #include #include #include @@ -1375,6 +1376,13 @@ const int Model_Document::index(std::shared_ptr theObject, return myObjs->index(theObject, theAllowFolder); } +const int Model_Document::index(std::shared_ptr theResult, + std::shared_ptr theShape, + const bool theAllowFolder) +{ + return myObjs->index(theResult, theShape, theAllowFolder); +} + int Model_Document::size(const std::string& theGroupID, const bool theAllowFolder) { if (myObjs == 0) // may be on close @@ -2120,6 +2128,47 @@ AttributeSelectionListPtr Model_Document::selectionInPartFeature() return mySelectionFeature->selectionList("selection"); } +/// Feature that is used for use selection attribute +class Model_SelectionInResult : public ModelAPI_Feature +{ +public: + /// Nothing to do in constructor + Model_SelectionInResult() : ModelAPI_Feature() {} + + /// Returns the unique kind of a feature + virtual const std::string& getKind() + { + static std::string MY_KIND("InternalSelectionInResult"); + return MY_KIND; + } + /// Request for initialization of data model of the object: adding all attributes + virtual void initAttributes() + { + data()->addAttribute("selection", ModelAPI_AttributeSelection::typeId()); + } + /// Nothing to do in the execution function + virtual void execute() {} +}; + +AttributeSelectionPtr Model_Document::selectionInResult() +{ + FeaturePtr aFeatureNameGen = FeaturePtr(new Model_SelectionInResult); + + TDF_Label aFeatureLab = generalLabel().FindChild(TAG_SELECTION_FEATURE); + std::shared_ptr aData(new Model_Data); + aData->setLabel(aFeatureLab.FindChild(1)); + aData->setObject(aFeatureNameGen); + aFeatureNameGen->setDoc(myObjs->owner()); + aFeatureNameGen->setData(aData); + std::wstring aName = id() + L"_Part"; + aFeatureNameGen->data()->setName(aName); + aFeatureNameGen->setDoc(myObjs->owner()); + aFeatureNameGen->initAttributes(); + aFeatureNameGen->init(); + + return aFeatureNameGen->selection("selection"); +} + FeaturePtr Model_Document::lastFeature() { if (myObjs) @@ -2290,6 +2339,17 @@ void Model_Document::storeNodesState(const std::list& theStates) } } +void Model_Document::storeShape(const std::shared_ptr theData, + const std::shared_ptr theResult, + const std::shared_ptr theShape) +{ + if (index(theData->owner()) == -1) + return; + int anIndex = index(theResult, theShape); + if (anIndex == -1) + myObjs->storeShape(theData, theResult, theShape); +} + void Model_Document::restoreNodesState(std::list& theStates) const { TDF_Label aLab = generalLabel().FindChild(TAG_NODES_STATE); diff --git a/src/Model/Model_Document.h b/src/Model/Model_Document.h index 001758919..f8e40c760 100644 --- a/src/Model/Model_Document.h +++ b/src/Model/Model_Document.h @@ -33,6 +33,7 @@ class Handle_Model_Document; class Model_Objects; class ModelAPI_AttributeSelectionList; +class TopoDS_Shape; /**\class Model_Document * \ingroup DataModel @@ -145,6 +146,13 @@ class Model_Document : public ModelAPI_Document //! \returns index started from zero, or -1 if object is invisible or belongs to another document MODEL_EXPORT virtual const int index(std::shared_ptr theObject, const bool theAllowFolder = false); + //! Returns the shape index in the result. + //! \param theResult result + //! \param theShape result subshape + //! \returns index started from zero, or -1 if shape is not stored or is not a subshape of the result + MODEL_EXPORT virtual const int index(std::shared_ptr theResult, + std::shared_ptr theShape, + const bool theAllowFolder = false); //! Internal sub-document by ID MODEL_EXPORT virtual std::shared_ptr subDoc(int theDocID); @@ -385,10 +393,18 @@ class Model_Document : public ModelAPI_Document //! for calculation of selection externally from the document std::shared_ptr selectionInPartFeature(); + //! Returns the selection attribute that is used + std::shared_ptr selectionInResult(); + /// Stores in the document boolean flags: states of the nodes in the object browser. /// Normally is called outside of the transaction, just before "save". virtual void storeNodesState(const std::list& theStates); + /// Store Shape from Result to document + virtual void storeShape(const std::shared_ptr theData, + const std::shared_ptr theResult, + const std::shared_ptr theShape); + /// Returns the stored nodes states. Normally it is called just after "open". /// Appends the values to theStates list. virtual void restoreNodesState(std::list& theStates) const; @@ -424,6 +440,7 @@ class Model_Document : public ModelAPI_Document friend class Model_ResultPart; friend class Model_ResultBody; friend class Model_ResultConstruction; + friend class Model_SelectionInResult; friend class Model_SelectionNaming; friend class Model_BodyBuilder; friend class DFBrowser; diff --git a/src/Model/Model_Objects.cpp b/src/Model/Model_Objects.cpp index 544b5bef8..7fc1ba3c1 100644 --- a/src/Model/Model_Objects.cpp +++ b/src/Model/Model_Objects.cpp @@ -46,16 +46,23 @@ #include #include #include +#include #include #include #include #include #include +#include #include +// relocate to other file +#include +#include + #if OCC_VERSION_LARGE < 0x07080000 #include + // for TDF_Label map usage static Standard_Integer HashCode(const TDF_Label& theLab, const Standard_Integer theUpper); static Standard_Boolean IsEqual(const TDF_Label& theLab1, const TDF_Label& theLab2); @@ -97,11 +104,13 @@ static const int TAG_OBJECTS = 2; // tag of the objects sub-tree (features, res // feature sub-labels static const int TAG_FEATURE_ARGUMENTS = 1; ///< where the arguments are located static const int TAG_FEATURE_RESULTS = 2; ///< where the results are located +static const int TAG_RESULT_SHAPES = 2; ///< where the shapes are located /// /// 0:1:2 - where features are located /// 0:1:2:N:1 - data of the feature N /// 0:1:2:N:2:K:1 - data of the K result of the feature N +/// 0:1:2:N:2:K:2:M:1 - data of the M shape of the K result of the feature N Model_Objects::Model_Objects(TDF_Label theMainLab) : myMain(theMainLab) { @@ -689,6 +698,39 @@ const int Model_Objects::index(std::shared_ptr theObject, return -1; } +const int Model_Objects::index(std::shared_ptr theResult, + std::shared_ptr theShape, + const bool theAllowFolder) +{ + ResultBodyPtr aMain = std::dynamic_pointer_cast(theResult); + aMain = ModelAPI_Tools::mainBody(aMain); + + int anIndex = -1; + if (aMain.get()) + anIndex = index(aMain, theAllowFolder); + else + anIndex = index(theResult, theAllowFolder); + + if (anIndex == -1) + return -1; // Object not store to document + TDF_Label aShapesLabel = shapesFromResult(resultLabel(theResult->data(), anIndex)); + + int aShapesIndex = 0; + for (TDF_ChildIterator anIt(aShapesLabel); anIt.More(); anIt.Next(), ++aShapesIndex) + { + Handle(TNaming_NamedShape) aCurShape; + if (anIt.Value().FindAttribute(TNaming_NamedShape::GetID(), aCurShape)) + { + if (aCurShape->Get().IsSame(theShape->impl())) + { + return aShapesIndex; + } + } + } + //not found + return -1; +} + int Model_Objects::size(const std::string& theGroupID, const bool theAllowFolder) { createHistory(theGroupID); @@ -740,6 +782,127 @@ TDF_Label Model_Objects::featuresLabel() const return myMain.FindChild(TAG_OBJECTS); } +TDF_Label Model_Objects::shapesFromResult(TDF_Label theResult) const +{ + return theResult.Father().FindChild(TAG_RESULT_SHAPES); +} + +void Model_Objects::setAttribute(const Handle(TDF_Attribute)& theAttribute, + std::shared_ptr theResult, + std::shared_ptr theShape) +{ + ResultBodyPtr aMain = std::dynamic_pointer_cast(theResult); + aMain = ModelAPI_Tools::mainBody(aMain); + TDF_Label aResultLabel; + if (aMain.get()) + aResultLabel = resultLabel(theResult->data(), index(aMain)); + else + aResultLabel = resultLabel(theResult->data(), index(theResult)); + TDF_Label anAttributeLabel = subShapeLabel(aResultLabel, index(theResult, theShape)).FindChild(TAG_FEATURE_ARGUMENTS); + + if (Standard_GUID::IsEqual(theAttribute->ID(), TDataStd_IntegerArray::GetID())) + { + Handle(TDataStd_IntegerArray) anColor; + Handle(TDataStd_IntegerArray) anAttr = + Handle(TDataStd_IntegerArray)::DownCast(theAttribute); + + if (anAttributeLabel.FindAttribute(TDataStd_IntegerArray::GetID(), anColor)) + { + anAttributeLabel.ForgetAttribute(TDataStd_IntegerArray::GetID()); + } + anAttributeLabel.AddAttribute(anAttr); + static const Events_ID anEvent = Events_Loop::eventByName(EVENT_OBJECT_UPDATED); + ModelAPI_EventCreator::get()->sendUpdated(theResult, anEvent); + } +} + +Handle(TDF_Attribute) Model_Objects::getAttribute(const Standard_GUID& theID, + std::shared_ptr theResult, + std::shared_ptr theShape) +{ + ResultBodyPtr aMain = std::dynamic_pointer_cast(theResult); + aMain = ModelAPI_Tools::mainBody(aMain); + + int anIndex = index(theResult, theShape); + Handle(TDataStd_IntegerArray) anColor; + + if (anIndex != -1) + { + TDF_Label aResultLabel; + if (aMain.get()) + aResultLabel = resultLabel(theResult->data(), index(aMain)); + else + aResultLabel = resultLabel(theResult->data(), index(theResult)); + + TDF_Label anAttributeLabel = subShapeLabel(aResultLabel, anIndex).FindChild(TAG_FEATURE_ARGUMENTS); + anAttributeLabel.FindAttribute(TDataStd_IntegerArray::GetID(), anColor); + } + return anColor; +} + +void Model_Objects::getColoredShapes(const std::shared_ptr theResult, + std::map, std::vector>& theColoredShapes) +{ + ResultBodyPtr aMainBody = std::dynamic_pointer_cast(theResult); + aMainBody = ModelAPI_Tools::mainBody(aMainBody); + TDF_Label aShapesLabel; + if (aMainBody.get()) + aShapesLabel = shapesFromResult(resultLabel(theResult->data(), index(aMainBody))); + else + aShapesLabel = shapesFromResult(resultLabel(theResult->data(), index(theResult))); + + for (TDF_ChildIterator aChilds(aShapesLabel); aChilds.More(); aChilds.Next()) + { + TDF_Label aCurSubShape = aChilds.Value(); + Handle(TNaming_NamedShape) aNamedShape; + aCurSubShape.FindAttribute(TNaming_NamedShape::GetID(), aNamedShape); + if (aNamedShape.IsNull()) + continue; + + std::shared_ptr aSub(new GeomAPI_Shape); + aSub->setImpl(new TopoDS_Shape(aNamedShape->Get())); + + Handle(TDataStd_IntegerArray) aColorAttr; + std::vector aColor; + aCurSubShape.FindChild(TAG_FEATURE_ARGUMENTS).FindAttribute(TDataStd_IntegerArray::GetID(), aColorAttr); + if (aColorAttr.IsNull()) + continue; + for (int anIndex = aColorAttr->Lower(); anIndex <= aColorAttr->Upper(); ++anIndex) + aColor.push_back(aColorAttr->Value(anIndex)); + if (aColor.size() != 3) + continue; + + theColoredShapes[aSub] = aColor; + } +} + +void Model_Objects::removeShapeColors(const std::shared_ptr theResult) +{ + ResultBodyPtr aMainBody = std::dynamic_pointer_cast(theResult); + aMainBody = ModelAPI_Tools::mainBody(aMainBody); + + TDF_Label aShapesLabel; + if (aMainBody.get()) + aShapesLabel = shapesFromResult(resultLabel(theResult->data(), index(aMainBody))); + else + { + ResultPartPtr aResPart = std::dynamic_pointer_cast(theResult); + if (!aResPart.get()) + return; + aShapesLabel = shapesFromResult(resultLabel(theResult->data(), index(aResPart))); + } + for (TDF_ChildIterator aChilds(aShapesLabel); aChilds.More(); aChilds.Next()) + { + TDF_Label aCurSubShape = aChilds.Value(); + Handle(TNaming_NamedShape) aNamedShape; + aCurSubShape.FindAttribute(TNaming_NamedShape::GetID(), aNamedShape); + if (aNamedShape.IsNull()) + continue; + + aCurSubShape.FindChild(TAG_FEATURE_ARGUMENTS).ForgetAttribute(TDataStd_IntegerArray::GetID()); + } +} + static std::wstring composeName(const std::string& theFeatureKind, const int theIndex) { std::stringstream aNameStream; @@ -1194,6 +1357,12 @@ TDF_Label Model_Objects::resultLabel( return aData->label().Father().FindChild(TAG_FEATURE_RESULTS).FindChild(theResultIndex + 1); } +TDF_Label Model_Objects::subShapeLabel(TDF_Label& theResultLabel, + const int theResultIndex) +{ + return theResultLabel.Father().FindChild(TAG_RESULT_SHAPES).FindChild(theResultIndex + 1); +} + bool Model_Objects::hasCustomName(DataPtr theFeatureData, ResultPtr theResult, int /*theResultIndex*/, @@ -1263,6 +1432,28 @@ void Model_Objects::storeResult(std::shared_ptr theFeatureData, } } +void Model_Objects::storeShape(std::shared_ptr theData, + std::shared_ptr theResult, + std::shared_ptr theShape, + const int theResultIndex) +{ + std::shared_ptr aResultData = + std::dynamic_pointer_cast(theResult->data()); + TDF_Label aResultLabel = resultLabel(aResultData, index(theData->owner())); + TDF_Label aShapesLabel = shapesFromResult(aResultLabel); + + int anIndex = aShapesLabel.NbChildren(); + TDF_Label aSubShapeLabel = subShapeLabel(aResultLabel, anIndex); + + Handle(TNaming_NamedShape) aNS; + if (aSubShapeLabel.FindAttribute(TNaming_NamedShape::GetID(), aNS)) + return; + + // GeomAPI_Shape -> TNaming_NamedShape + TNaming_Builder aBuilder(aSubShapeLabel); + aBuilder.Select(theShape->impl(), theShape->impl()); +} + std::shared_ptr Model_Objects::createConstruction( const std::shared_ptr& theFeatureData, const int theIndex) { @@ -2046,7 +2237,7 @@ FeaturePtr Model_Objects::lastFeature() bool Model_Objects::isLater(FeaturePtr theLater, FeaturePtr theCurrent) const { - if (theLater->getKind() == "InternalSelectionInPartFeature") + if (theLater->getKind() == "InternalSelectionInPartFeature" || theLater->getKind() == "InternalSelectionInResult") return true; std::shared_ptr aLaterD = std::static_pointer_cast(theLater->data()); std::shared_ptr aCurrentD = std::static_pointer_cast(theCurrent->data()); diff --git a/src/Model/Model_Objects.h b/src/Model/Model_Objects.h index e810e10ad..364a3dddd 100644 --- a/src/Model/Model_Objects.h +++ b/src/Model/Model_Objects.h @@ -92,6 +92,14 @@ class Model_Objects const int index(std::shared_ptr theObject, const bool theAllowFolder = false); + //! Returns the shape index in the result. + //! \param theResult result + //! \param theShape result subshape + //! \returns index started from zero, or -1 if shape is not stored or is not a subshape of the result + const int index(std::shared_ptr theResult, + std::shared_ptr theShape, + const bool theAllowFolder = false); + //! Returns the feature in the group by the index (started from zero) //! \param theGroupID group that contains a feature //! \param theIndex zero-based index of feature in the group @@ -181,6 +189,23 @@ class Model_Objects bool removeFromFolder(const std::list >& theFeatures, const bool theBefore = true); + //! set attribute to subShape + void setAttribute(const Handle(TDF_Attribute)& theAttribute, + std::shared_ptr theResult, + std::shared_ptr theShape); + + //! get attribute from subshape + Handle(TDF_Attribute) getAttribute(const Standard_GUID& theID, + std::shared_ptr theResult, + std::shared_ptr theShape); + + //! Get colored shapes from result + void getColoredShapes(const std::shared_ptr theResult, + std::map, std::vector>& theColoredShapes); + + //! Forget subshape colors + void removeShapeColors(const std::shared_ptr theResult); + //! Sets the owner of this manager void setOwner(DocumentPtr theDoc); @@ -195,6 +220,9 @@ class Model_Objects //! Returns (creates if needed) the features label TDF_Label featuresLabel() const; + //! Returns (creates if needed) the shapes label from result label + TDF_Label shapesFromResult(TDF_Label theResult) const; + //! Initializes feature with a unique name in this group (unique name is generated as //! feature type + "_" + index void setUniqueName(FeaturePtr theFeature); @@ -227,10 +255,20 @@ class Model_Objects const int theResultIndex = 0, const std::wstring& theNameShape = L""); + //! Allows to store the shape from result in the data tree of the document + void storeShape(std::shared_ptr theData, + std::shared_ptr theResult, + std::shared_ptr theShape, + const int theResultIndex = 0); + //! returns the label of result by index; creates this label if it was not created before TDF_Label resultLabel(const std::shared_ptr& theFeatureData, const int theResultIndex); + //! Returns the label of result subshapes by index; creates this label if it was not created before + TDF_Label subShapeLabel(TDF_Label& theResultLabel, + const int theResultIndex); + //! Updates the results list of the feature basing on the current data tree //! theProcessed is used to avoid update twice (since the function is recursive) void updateResults(FeaturePtr theFeature, std::set& theProcessed); diff --git a/src/Model/Model_ResultBody.cpp b/src/Model/Model_ResultBody.cpp index f6bc7d31a..52869c664 100644 --- a/src/Model/Model_ResultBody.cpp +++ b/src/Model/Model_ResultBody.cpp @@ -26,6 +26,7 @@ #include #include #include +#include #include #include #include @@ -38,6 +39,9 @@ #include #include #include +#include +#include +#include // if this attribute exists, the shape is connected topology Standard_GUID kIsConnectedTopology("e51392e0-3a4d-405d-8e36-bbfe19858ef5"); @@ -255,13 +259,75 @@ void Model_ResultBody::addShapeColor( const std::wstring& theName,std::vector theResult, + const std::shared_ptr theShape, + const std::vector& theColor) +{ + TopoDS_Shape aShape = this->shape()->impl(); + TopoDS_Shape aSubShape = theShape->impl(); + if (!this->shape()->isSubShape(theShape)) + return; + + Model_Objects* anObjects = std::dynamic_pointer_cast(document())->objects(); + document()->storeShape(data(), theResult, theShape); + + Handle(TDataStd_IntegerArray) aColor = new TDataStd_IntegerArray(); + aColor->Init(0, 2); + aColor->SetValue(0, theColor[0]); + aColor->SetValue(1, theColor[1]); + aColor->SetValue(2, theColor[2]); + anObjects->setAttribute(aColor, theResult, theShape); +} + +void Model_ResultBody::getSubShapeColor(const std::shared_ptr theResult, const std::shared_ptr theShape, std::vector& theColor) +{ + TopoDS_Shape aShape = this->shape()->impl(); + TopoDS_Shape aSubShape = theShape->impl(); + if (!this->shape()->isSubShape(theShape)) + return; + + Model_Objects* anObjects = std::dynamic_pointer_cast(document())->objects(); + Handle(TDataStd_IntegerArray) anAttr = Handle(TDataStd_IntegerArray)::DownCast( + anObjects->getAttribute(TDataStd_IntegerArray::GetID(), theResult, theShape)); + if (anAttr.IsNull()) + return; + for (int anIndex = anAttr->Lower(); anIndex <= anAttr->Upper(); ++anIndex) + theColor.push_back(anAttr->Value(anIndex)); + if (theColor.size() != 3) + theColor.clear(); +} + +void Model_ResultBody::getColoredShapes(const std::shared_ptr theResult, + std::map>& theColoredShapes) +{ + Model_Objects* anObjects = std::dynamic_pointer_cast(document())->objects(); + anObjects->getColoredShapes(theResult, theColoredShapes); +} + +void Model_ResultBody::removeShapeColors(const std::shared_ptr theResult) +{ + Model_Objects* anObjects = std::dynamic_pointer_cast(document())->objects(); + anObjects->removeShapeColors(theResult); +} + +std::shared_ptr Model_ResultBody::selection() +{ + AttributeSelectionPtr aSelAttr = std::dynamic_pointer_cast + (document())->selectionInResult(); + return aSelAttr; +} + std::wstring Model_ResultBody::addShapeName(std::shared_ptr theshape, const std::wstring& theName ){ int indice = 1; std::wstringstream aName; aName << theName; - while(myNamesShape.find(aName.str()) != myNamesShape.end() ){ +#if 1 + while (myNamesShape.find(aName.str()) != myNamesShape.end()) { +#else + while (aName.str().empty() || myNamesShape.find(aName.str()) != myNamesShape.end()) { +#endif aName.str(L""); aName << theName << L"__" << indice; indice++; @@ -399,6 +465,45 @@ void Model_ResultBody::updateSubs(const std::shared_ptr& theThisS aECreator->sendUpdated(data()->owner(), EVENT_DISP); } cleanCash(); + } + else if (!aThisShape.IsNull() && (aThisShape.ShapeType() == TopAbs_SOLID || + aThisShape.ShapeType() == TopAbs_SHELL)) { + //std::cout << ".....subshape is a SOLID or SHELL" << std::endl; + // Iterate on all faces + //MBS: + ResultBodyPtr anOwner = std::dynamic_pointer_cast(data()->owner()); + TopExp_Explorer aExp(aThisShape, TopAbs_FACE); + for (; aExp.More(); aExp.Next()) { + TopoDS_Shape aFace = aExp.Current(); + if (!aFace.IsNull()) { + GeomShapePtr aGeomFace(new GeomAPI_Shape); + aGeomFace->setImpl(new TopoDS_Shape(aFace)); + std::wstring aName = findShapeName(aGeomFace); + /// + for (std::map< std::wstring, std::shared_ptr >::iterator it = + myNamesShape.begin(); + it != myNamesShape.end(); + ++it) + { + TopoDS_Shape curSelectedShape = (*it).second->impl(); + if (curSelectedShape.TShape().IsNull()) + continue; + if (aFace.TShape() == curSelectedShape.TShape()) + { + aName = (*it).first; // Find necessary shape, + // but it NOT correct because result shape contains anothet location. WHY? + break; + } + } + /// + if (!aName.empty()) { + const std::vector &aColor = findShapeColor(aName); + if (!aColor.empty()) { + ModelAPI_Tools::setColor(anOwner, aGeomFace, aColor); + } + } + } + } } else if (!mySubs.empty()) { // erase all subs while(!mySubs.empty()) { ResultBodyPtr anErased = *(mySubs.rbegin()); diff --git a/src/Model/Model_ResultBody.h b/src/Model/Model_ResultBody.h index bda42cdf5..3f5727e5d 100644 --- a/src/Model/Model_ResultBody.h +++ b/src/Model/Model_ResultBody.h @@ -151,12 +151,32 @@ protected: /// Add color for shape Name read shape in step file void addShapeColor( const std::wstring& theName,std::vector& color) override; + /// Add color to sub shape + void setSubShapeColor(const std::shared_ptr theResult, + const std::shared_ptr theShape, + const std::vector& theColor); + + /// Get color from sub shape + void getSubShapeColor(const std::shared_ptr theResult, + const std::shared_ptr theShape, + std::vector& theColor); + + /// Get colored shapes from result + void getColoredShapes(const std::shared_ptr theResult, + std::map, std::vector>& theColoredShapes); + + /// Forget subshape colors + void removeShapeColors(const std::shared_ptr theResult); + /// Set the map of name and color read shape in step file void setShapeName(std::map< std::wstring, std::shared_ptr>& theShapeName, std::map< std::wstring, std::vector>& theColorsShape) override; + /// Return Attribute selection + MODELAPI_EXPORT virtual std::shared_ptr selection(); + /// Find the name of shape read in step file std::wstring findShapeName(std::shared_ptr theShape) override; diff --git a/src/Model/Model_ResultPart.cpp b/src/Model/Model_ResultPart.cpp index 4712ab625..5f46da178 100644 --- a/src/Model/Model_ResultPart.cpp +++ b/src/Model/Model_ResultPart.cpp @@ -21,6 +21,7 @@ #include #include +#include #include #include #include @@ -44,6 +45,7 @@ #include #include #include +#include #include #include #include @@ -369,6 +371,13 @@ bool Model_ResultPart::updateInPart(const int theIndex) return false; // something is wrong } +std::shared_ptr Model_ResultPart::selection() +{ + AttributeSelectionPtr aSelAttr = std::dynamic_pointer_cast + (document())->selectionInResult(); + return aSelAttr; +} + gp_Trsf Model_ResultPart::sumTrsf() { gp_Trsf aResult; if (myTrsf) { @@ -430,6 +439,57 @@ std::shared_ptr Model_ResultPart::shapeInPart( return aResult; } +void Model_ResultPart::setSubShapeColor(const std::shared_ptr& theShape, + const std::vector& theColor) +{ + TopoDS_Shape aShape = this->shape()->impl(); + TopoDS_Shape aSubShape = theShape->impl(); + if (!this->shape()->isSubShape(theShape)) + return; + + Model_Objects* anObjects = std::dynamic_pointer_cast(document())->objects(); + + document()->storeShape(data(), original(), theShape); + Handle(TDataStd_IntegerArray) aColor = new TDataStd_IntegerArray(); + aColor->Init(0, 2); + aColor->SetValue(0, theColor[0]); + aColor->SetValue(1, theColor[1]); + aColor->SetValue(2, theColor[2]); + anObjects->setAttribute(aColor, original(), theShape); +} + +void Model_ResultPart::getSubShapeColor(const std::shared_ptr& theShape, + std::vector& theColor) +{ + TopoDS_Shape aShape = this->shape()->impl(); + TopoDS_Shape aSubShape = theShape->impl(); + if (!this->shape()->isSubShape(theShape)) + return; + + Model_Objects* anObjects = std::dynamic_pointer_cast(document())->objects(); + Handle(TDataStd_IntegerArray) anAttr = Handle(TDataStd_IntegerArray)::DownCast( + anObjects->getAttribute(TDataStd_IntegerArray::GetID(), original(), theShape)); + if (anAttr.IsNull()) + return; + for (int anIndex = anAttr->Lower(); anIndex <= anAttr->Upper(); ++anIndex) + theColor.push_back(anAttr->Value(anIndex)); + if (theColor.size() != 3) + theColor.clear(); +} + +void Model_ResultPart::getColoredShapes(std::map, + std::vector>&theColoredShapes) +{ + Model_Objects* anObjects = std::dynamic_pointer_cast(document())->objects(); + anObjects->getColoredShapes(original(), theColoredShapes); +} + +void Model_ResultPart::removeShapeColors() +{ + Model_Objects* anObjects = std::dynamic_pointer_cast(document())->objects(); + anObjects->removeShapeColors(original()); +} + std::shared_ptr Model_ResultPart::selectionValue(const int theIndex) { std::shared_ptr aResult; diff --git a/src/Model/Model_ResultPart.h b/src/Model/Model_ResultPart.h index 172bf8bed..2ba7d9ac9 100644 --- a/src/Model/Model_ResultPart.h +++ b/src/Model/Model_ResultPart.h @@ -24,6 +24,7 @@ #include #include #include +#include /**\class Model_ResultPart * \ingroup DataModel @@ -77,7 +78,21 @@ class Model_ResultPart : public ModelAPI_ResultPart MODEL_EXPORT virtual bool updateInPart(const int theIndex); /// Returns the shape by the name in the part MODEL_EXPORT virtual std::shared_ptr shapeInPart( - const std::wstring& theName, const std::string& theType, int& theIndex); + const std::wstring& theName, const std::string& theType, int& theIndex); /// Set color on subshape + MODEL_EXPORT virtual void setSubShapeColor(const std::shared_ptr& theShape, + const std::vector& theColor); + + /// Get color on subshape + MODEL_EXPORT virtual void getSubShapeColor(const std::shared_ptr& theShape, + std::vector& theColor); + + /// Get colored shapes from result + MODEL_EXPORT virtual void getColoredShapes(std::map, + std::vector>&theColoredShapes); + + /// Forget subshape colors + MODEL_EXPORT virtual void removeShapeColors(); + /// Updates the selection inside of the part as a geometrical selection MODEL_EXPORT virtual bool combineGeometrical(const int theIndex, std::wstring& theNewName); /// Updates the shape-result of the part (called on Part feature execution) @@ -98,6 +113,9 @@ class Model_ResultPart : public ModelAPI_ResultPart /// Loading the part from file MODEL_EXPORT virtual void loadPart(); + /// Return Attribute selection + MODEL_EXPORT virtual std::shared_ptr selection(); + protected: /// makes a result on a temporary feature (an action) Model_ResultPart(); diff --git a/src/ModelAPI/ModelAPI_Data.h b/src/ModelAPI/ModelAPI_Data.h index 8518d284d..09dd7343f 100644 --- a/src/ModelAPI/ModelAPI_Data.h +++ b/src/ModelAPI/ModelAPI_Data.h @@ -26,6 +26,7 @@ #include "ModelAPI.h" #include +#include #include #include #include @@ -74,6 +75,8 @@ class MODELAPI_EXPORT ModelAPI_Data /// Returns the name of the feature visible by the user in the object browser virtual std::wstring name() = 0; + /// Returns the name of the shape + virtual std::wstring name(std::shared_ptr theSubShape) = 0; /// Defines the name of the feature visible by the user in the object browser virtual void setName(const std::wstring& theName) = 0; /// Return \c true if the object has been renamed by the user diff --git a/src/ModelAPI/ModelAPI_Document.h b/src/ModelAPI/ModelAPI_Document.h index acec2b808..64f638942 100644 --- a/src/ModelAPI/ModelAPI_Document.h +++ b/src/ModelAPI/ModelAPI_Document.h @@ -28,6 +28,7 @@ #include #include #include +#include class ModelAPI_Feature; class ModelAPI_Folder; @@ -108,6 +109,13 @@ public: //! \returns index started from zero, or -1 if object is invisible or belongs to another document virtual const int index(std::shared_ptr theObject, const bool theAllowFolder = false) = 0; + //! Returns the shape index in the result. + //! \param theResult result + //! \param theShape result subshape + //! \returns index started from zero, or -1 if shape is not stored or is not a subshape of the result + virtual const int index(std::shared_ptr theResult, + std::shared_ptr theShape, + const bool theAllowFolder = false) = 0; //! Returns the number of objects in the group of objects //! \param theGroupID group of objects @@ -251,6 +259,11 @@ public: /// Appends the values to theStates list. MODELAPI_EXPORT virtual void restoreNodesState(std::list& theStates) const = 0; + /// Store Shape from Result to document + MODELAPI_EXPORT virtual void storeShape(const std::shared_ptr theData, + const std::shared_ptr theResult, + const std::shared_ptr theShape) = 0; + /// Just removes all features without touching the document data (to be able undo) MODELAPI_EXPORT virtual void eraseAllFeatures() = 0; diff --git a/src/ModelAPI/ModelAPI_ResultBody.h b/src/ModelAPI/ModelAPI_ResultBody.h index 223c91d55..3d1df1837 100644 --- a/src/ModelAPI/ModelAPI_ResultBody.h +++ b/src/ModelAPI/ModelAPI_ResultBody.h @@ -200,6 +200,26 @@ public: MODELAPI_EXPORT virtual void addShapeColor (const std::wstring& theName, std::vector& theColor) = 0; + /// Add color to sub shape + MODELAPI_EXPORT virtual void setSubShapeColor(const std::shared_ptr theResult, + const std::shared_ptr theShape, + const std::vector& theColor) = 0; + + /// Get color from sub shape + MODELAPI_EXPORT virtual void getSubShapeColor(const std::shared_ptr theResult, + const std::shared_ptr theShape, + std::vector& theColor) = 0; + + /// Get colored shapes from result + MODELAPI_EXPORT virtual void getColoredShapes(const std::shared_ptr theResult, + std::map, std::vector>& theColoredShapes) = 0; + + /// Forget subshape colors + MODELAPI_EXPORT virtual void removeShapeColors(const std::shared_ptr theResult) = 0; + + /// Return Attribute selection + MODELAPI_EXPORT virtual std::shared_ptr selection() = 0; + /// Set the map of name and color read shape in step file MODELAPI_EXPORT virtual void setShapeName (std::map< std::wstring, std::shared_ptr > &theShapeName, diff --git a/src/ModelAPI/ModelAPI_ResultPart.h b/src/ModelAPI/ModelAPI_ResultPart.h index 148315a5f..8dcd85723 100644 --- a/src/ModelAPI/ModelAPI_ResultPart.h +++ b/src/ModelAPI/ModelAPI_ResultPart.h @@ -24,6 +24,7 @@ class GeomAPI_Trsf; #include +#include /**\class ModelAPI_ResultPart * \ingroup DataModel @@ -88,6 +89,20 @@ class ModelAPI_ResultPart : public ModelAPI_Result /// Returns the shape by the name in the part virtual std::shared_ptr shapeInPart( const std::wstring& theName, const std::string& theType, int& theIndex) = 0; + /// Set color on subshape + virtual void setSubShapeColor(const std::shared_ptr& theShape, + const std::vector& theColor) = 0; + + /// Get subshape color + virtual void getSubShapeColor(const std::shared_ptr& theShape, + std::vector& theColor) = 0; + + /// Get colored shapes from result + virtual void getColoredShapes(std::map, + std::vector>&theColoredShapes) = 0; + + /// Forget subshape colors + virtual void removeShapeColors() = 0; /// Updates the selection inside of the part as a geometrical selection virtual bool combineGeometrical(const int theIndex, std::wstring& theNewName) = 0; @@ -98,6 +113,9 @@ class ModelAPI_ResultPart : public ModelAPI_Result /// Updates the shape-result of the part (called on Part feature execution) virtual void updateShape() = 0; + /// Return Attribute selection + virtual std::shared_ptr selection() = 0; + /// Loading the part from file virtual void loadPart() = 0; }; diff --git a/src/ModelAPI/ModelAPI_Tools.cpp b/src/ModelAPI/ModelAPI_Tools.cpp index 508ca38e8..f7d7a5699 100644 --- a/src/ModelAPI/ModelAPI_Tools.cpp +++ b/src/ModelAPI/ModelAPI_Tools.cpp @@ -518,6 +518,19 @@ ResultBodyPtr bodyOwner(const ResultPtr& theSub, const bool theRoot) return ResultBodyPtr(); // not found } +ResultBodyPtr mainBody(const ResultBodyPtr theSubBody) +{ + ResultBodyPtr aBody = theSubBody; + while (aBody.get()) + { // get the top-most main + ResultBodyPtr aNextBody = bodyOwner(aBody); + if (aNextBody.get()) + aBody = aNextBody; + else break; + } + return aBody; +} + int bodyIndex(const ResultPtr& theSub) { int anIndex = -1; @@ -1081,9 +1094,36 @@ void setColor(ResultPtr theResult, const std::vector& theColor) aColorAttr->setValue(0, theColor[0]); aColorAttr->setValue(1, theColor[1]); aColorAttr->setValue(2, theColor[2]); + removeShapeColors(theResult); } } +void setColor(ResultPtr theResult, GeomShapePtr theShape, const std::vector& theColor) +{ + if (!theResult.get() || theShape->isNull()) + return; + if (!theResult->shape()->isSubShape(theShape)) + return; + + ResultBodyPtr aBody = std::dynamic_pointer_cast(theResult); + if (aBody.get()) + { + aBody = mainBody(aBody); + aBody->setSubShapeColor(theResult, theShape, theColor); + } + else + { + ResultPartPtr aResPart = std::dynamic_pointer_cast(theResult); + if (!aResPart.get()) + return; + aResPart->setSubShapeColor(theShape, theColor); + } + + static const Events_ID anEvent = Events_Loop::eventByName(EVENT_OBJECT_TO_REDISPLAY); + ModelAPI_EventCreator::get()->sendUpdated(theResult, anEvent); +} + + void getColor(const std::shared_ptr& theResult, std::vector& theColor) { theColor.clear(); @@ -1099,6 +1139,84 @@ void getColor(const std::shared_ptr& theResult, std::vector& theColor) +{ + theColor.clear(); + if (!theResult.get() || theShape->isNull()) + return; + if (!theResult->shape()->isSubShape(theShape)) + return; + + ResultBodyPtr aBody = std::dynamic_pointer_cast(theResult); + if (aBody.get()) + { + aBody = mainBody(aBody); + aBody->getSubShapeColor(theResult, theShape, theColor); + } + else + { + ResultPartPtr aResPart = std::dynamic_pointer_cast(theResult); + if (!aResPart.get()) + return; + aResPart->getSubShapeColor(theShape, theColor); + } +} + +void getColoredShapes(const ResultPtr theResult, + std::map>& theColoredShapes, + bool theGetSubResults) +{ + if (!theResult.get()) + return; + + ResultBodyPtr aBody = std::dynamic_pointer_cast(theResult); + if (aBody.get()) + { + ResultBodyPtr aMainBody = mainBody(aBody); + if (!aMainBody.get()) + return; + if (theGetSubResults) + { + std::list aSubResults; + allSubs(aBody, aSubResults); + for (std::list::iterator anIt = aSubResults.begin(); + anIt != aSubResults.end(); ++anIt) + { + aMainBody->getColoredShapes(*anIt, theColoredShapes); + } + } + + aMainBody->getColoredShapes(theResult, theColoredShapes); + } + else + { + ResultPartPtr aResPart = std::dynamic_pointer_cast(theResult); + if (!aResPart.get()) + return; + aResPart->getColoredShapes(theColoredShapes); + } +} + +void removeShapeColors(const std::shared_ptr theResult) +{ + if (!theResult.get()) + return; + + ResultBodyPtr aBody = std::dynamic_pointer_cast(theResult); + if (aBody.get()) + { + aBody = mainBody(aBody); + aBody->removeShapeColors(theResult); + } + else + { + ResultPartPtr aResPart = std::dynamic_pointer_cast(theResult); + if (!aResPart.get()) + return; + aResPart->removeShapeColors(); + } +} + //****************************************************** void getIsoLines(const std::shared_ptr& theResult, bool& isVisible, std::vector& theNbLines) diff --git a/src/ModelAPI/ModelAPI_Tools.h b/src/ModelAPI/ModelAPI_Tools.h index beb380f86..dcb62e0d3 100644 --- a/src/ModelAPI/ModelAPI_Tools.h +++ b/src/ModelAPI/ModelAPI_Tools.h @@ -139,6 +139,14 @@ MODELAPI_EXPORT std::shared_ptr compositeOwner( */ MODELAPI_EXPORT std::shared_ptr bodyOwner(const std::shared_ptr& theSub, const bool theRoot = false); + +/* +* Returns the result - main parent of this result. +* \param theSubBody the sub-element of composit result +* \returns Root resultBody +*/ +MODELAPI_EXPORT std::shared_ptr mainBody(const std::shared_ptr theSubBody); + /*! * Returns index of this result in parent (if parent exists, returned by bodyOwner) * \returns zero-base index, or -1 if not found @@ -275,6 +283,31 @@ MODELAPI_EXPORT void setDeflection(std::shared_ptr theResult, MODELAPI_EXPORT void getColor(const std::shared_ptr& theResult, std::vector& theColor); +/*! Returns current color of the current subShape +* \param[in] theResult a result object +* \param[in] theShape a shape that belongs result object +* \param[out] theColor a color values if it is defined +*/ +MODELAPI_EXPORT void getColor(const std::shared_ptr theResult, + const std::shared_ptr theShape, + std::vector& theColor); + +/*! Returns colored shapes of the result +* \param[in] theResult a result object +* \param[out] theColoredShapes a set which contans all colored shapes of the result +* \param[in] theSubResult true - get colored shapes from subresults, +* else - get colored shaped only from result +*/ +MODELAPI_EXPORT void getColoredShapes(const std::shared_ptr theResult, + std::map, std::vector>& theColoredShapes, + bool theGetSubResults = false); + +/*! Remove all subshape color from result +* Need, when we set color on result +* \param[in] theResult a result object +*/ +MODELAPI_EXPORT void removeShapeColors(const std::shared_ptr theResult); + /*! Set color of the result * \param[in] theResult a result object * \param[in] theColor a color values @@ -282,6 +315,15 @@ MODELAPI_EXPORT void getColor(const std::shared_ptr& theResult, MODELAPI_EXPORT void setColor(std::shared_ptr theResult, const std::vector& theColor); +/*! Set color of the shape from result +* \param[in] theResult a result object +* \param[in] theShape a shape that belongs result object +* \param[in] theColor a color values +*/ +MODELAPI_EXPORT void setColor(std::shared_ptr theResult, + std::shared_ptr theShape, + const std::vector& theColor); + /*! Returns number of iso-lines of the current result * \param[in] theResult a result object * \param[out] theNbLines values of iso-lines diff --git a/src/ModelHighAPI/ModelHighAPI_Dumper.cpp b/src/ModelHighAPI/ModelHighAPI_Dumper.cpp index cc22e0d1c..f7cd5b96c 100644 --- a/src/ModelHighAPI/ModelHighAPI_Dumper.cpp +++ b/src/ModelHighAPI/ModelHighAPI_Dumper.cpp @@ -782,6 +782,21 @@ bool ModelHighAPI_Dumper::process(const std::shared_ptr> aColoredShapes; + ModelAPI_Tools::getColoredShapes(aPartResult, aColoredShapes, true); + if (!aColoredShapes.empty()) + *this << "\n"; + for (std::map>::const_iterator anIter(aColoredShapes.cbegin()); + anIter != aColoredShapes.cend(); ++anIter) + { + GeomShapePtr aShape = anIter->first; + + *this << aPartName << ".result()"; + *this << ".setColor(model.selection(\"" << aShape->shapeTypeStr() << "\", \"" + << Locale::Convert::toString((aPartResult)->data()->name(aShape)) << "\"), " + << anIter->second.at(0) << ", " << anIter->second.at(1) + << ", " << anIter->second.at(2) << ")\n"; + } *this << std::endl; return aRes; } @@ -934,6 +949,24 @@ void ModelHighAPI_Dumper::dumpEntitySetName() << ", " << aColor->value(2) << ")\n"; } } + // set subresult color + if ((isParentResult(*aResIt)) && hasColoredShape(*aResIt, true)) + { + std::map> aColoredShapes; + ModelAPI_Tools::getColoredShapes(*aResIt, aColoredShapes, true); + + for (std::map>::const_iterator anIter(aColoredShapes.cbegin()); + anIter != aColoredShapes.cend(); ++anIter) + { + GeomShapePtr aShape = anIter->first; + + *this << *aResIt; + *myDumpStorage << ".setColor(model.selection(\"" << aShape->shapeTypeStr() << "\", \"" + << Locale::Convert::toString((*aResIt)->data()->name(aShape)) << "\"), " + << anIter->second.at(0) << ", " << anIter->second.at(1) + << ", " << anIter->second.at(2) << ")\n"; + } + } // set result deflection if (!isDefaultDeflection(*aResIt)) { AttributeDoublePtr aDeflectionAttr = @@ -1011,6 +1044,24 @@ static bool isSketchSub(const FeaturePtr& theFeature) return anOwner && anOwner->getKind() == SKETCH; } +bool ModelHighAPI_Dumper::hasColoredShape(const ResultPtr& theResult, bool theGetSubResults) const +{ + std::map> aColoredShapes; + ModelAPI_Tools::getColoredShapes(theResult, aColoredShapes, theGetSubResults); + return !aColoredShapes.empty(); +} + +bool ModelHighAPI_Dumper::isParentResult(const ResultPtr& theResult) const +{ + ResultBodyPtr aResBody = std::dynamic_pointer_cast(theResult); + ResultBodyPtr aMainBody = ModelAPI_Tools::mainBody(aResBody); + + if (aMainBody.get() && aResBody == aMainBody) + return true; + + return false; +} + bool ModelHighAPI_Dumper::isDefaultColor(const ResultPtr& theResult) const { AttributeIntArrayPtr aColor = theResult->data()->intArray(ModelAPI_Result::COLOR_ID()); @@ -1322,7 +1373,8 @@ ModelHighAPI_Dumper& ModelHighAPI_Dumper::operator<<(const FeaturePtr& theEntity ModelAPI_Tools::allResults(theEntity, allRes); for(std::list::iterator aRes = allRes.begin(); aRes != allRes.end(); aRes++) { if(!myNames[*aRes].myIsDefault || !isDefaultColor(*aRes) || - !isDefaultDeflection(*aRes) || !isDefaultTransparency(*aRes)) + !isDefaultDeflection(*aRes) || !isDefaultTransparency(*aRes) || + (isParentResult(*aRes) && hasColoredShape(*aRes, true))) aResultsWithNameOrColor.push_back(*aRes); } // store just dumped entity to stack diff --git a/src/ModelHighAPI/ModelHighAPI_Dumper.h b/src/ModelHighAPI/ModelHighAPI_Dumper.h index c7286289c..3c85b9ac1 100644 --- a/src/ModelHighAPI/ModelHighAPI_Dumper.h +++ b/src/ModelHighAPI/ModelHighAPI_Dumper.h @@ -403,6 +403,12 @@ private: /// Stores names of results for the given feature void saveResultNames(const FeaturePtr& theFeature); + /// Check the result feature has colored shape + bool hasColoredShape(const ResultPtr& theResult, bool theGetSubResults = false) const; + + /// Check the result is parent result int the feature + bool isParentResult(const ResultPtr& theResult) const; + /// Check the result feature has default color bool isDefaultColor(const ResultPtr& theResult) const; diff --git a/src/ModelHighAPI/ModelHighAPI_Selection.cpp b/src/ModelHighAPI/ModelHighAPI_Selection.cpp index 160925e8b..e2d07d5f3 100644 --- a/src/ModelHighAPI/ModelHighAPI_Selection.cpp +++ b/src/ModelHighAPI/ModelHighAPI_Selection.cpp @@ -25,6 +25,7 @@ #include #include #include +#include #include #include @@ -233,6 +234,37 @@ void ModelHighAPI_Selection::setColor(int theRed, int theGreen, int theBlue, boo } } +void ModelHighAPI_Selection::setColor(const ModelHighAPI_Selection& theShape, + int theRed, int theGreen, int theBlue) +{ + if (myVariantType != VT_ResultSubShapePair || !myResultSubShapePair.first.get()) + return; + std::vector aColor({ theRed, theGreen, theBlue }); + std::shared_ptr aShape = myResultSubShapePair.second; + ResultBodyPtr aResBody = std::dynamic_pointer_cast( + myResultSubShapePair.first); + + ResultPtr aRes; + AttributeSelectionPtr aSelAttr; + if (aResBody.get()) + { + aSelAttr = aResBody->selection(); + theShape.fillAttribute(aSelAttr); + } + else + { + std::wstring aSubShapeName = theShape.myTypeSubShapeNamePair.second; + aSubShapeName = changePartName(theShape, aSubShapeName); + ResultPartPtr aPart = std::dynamic_pointer_cast(myResultSubShapePair.first); + aSelAttr = aPart->selection(); + aSelAttr->selectSubShape(myTypeSubShapeNamePair.first, aSubShapeName); + } + aRes = aSelAttr->context(); + aShape = aSelAttr->value(); + if (aRes.get() && aShape.get() && !aShape->isNull()) + ModelAPI_Tools::setColor(aRes, aShape, aColor); +} + void ModelHighAPI_Selection::setDeflection(double theValue) { if (myVariantType != VT_ResultSubShapePair || !myResultSubShapePair.first.get()) @@ -283,3 +315,17 @@ ModelHighAPI_Selection ModelHighAPI_Selection::subResult(int theIndex) const ResultBodyPtr aResult = aBody->subResult(theIndex); return ModelHighAPI_Selection(aResult, aResult->shape()); } + +std::wstring ModelHighAPI_Selection::changePartName(const ModelHighAPI_Selection& theShape, const std::wstring& theName) +{ + std::shared_ptr aShape; + int index; + ResultPartPtr aPart = std::dynamic_pointer_cast(myResultSubShapePair.first); + + std::size_t aPartEnd = theName.find(L'/'); + if (aPartEnd == std::wstring::npos) + return std::wstring(); + aShape = aPart->shapeInPart(theName.substr(aPartEnd + 1), theShape.myTypeSubShapeNamePair.first, index); + std::wstring name = aPart->data()->name(aShape); + return name; +} \ No newline at end of file diff --git a/src/ModelHighAPI/ModelHighAPI_Selection.h b/src/ModelHighAPI/ModelHighAPI_Selection.h index dc27c474f..bffa214aa 100644 --- a/src/ModelHighAPI/ModelHighAPI_Selection.h +++ b/src/ModelHighAPI/ModelHighAPI_Selection.h @@ -136,6 +136,10 @@ public: MODELHIGHAPI_EXPORT void setColor(int theRed = 0, int theGreen = 0, int theBlue = 0, bool random = false); + /// Change subShape' color + MODELHIGHAPI_EXPORT + void setColor(const ModelHighAPI_Selection& theShape, int theRed, int theGreen, int theBlue); + /// Change result's deflection MODELHIGHAPI_EXPORT void setDeflection(double theValue); @@ -152,6 +156,11 @@ public: MODELHIGHAPI_EXPORT ModelHighAPI_Selection subResult(int theIndex) const; +private: + /// Returns new part for shape + MODELHIGHAPI_EXPORT + std::wstring changePartName(const ModelHighAPI_Selection& theShape, const std::wstring& theName); + protected: VariantType myVariantType; ResultSubShapePair myResultSubShapePair; diff --git a/src/ModuleBase/ModuleBase_ISelection.h b/src/ModuleBase/ModuleBase_ISelection.h index f816f5b7f..7f0429e98 100644 --- a/src/ModuleBase/ModuleBase_ISelection.h +++ b/src/ModuleBase/ModuleBase_ISelection.h @@ -76,6 +76,9 @@ public: /// Returns list of currently selected results virtual QObjectPtrList selectedPresentations() const = 0; + /// Returns map of selected results and their selected subobjects + virtual QMap> selectedObjectsAndSubObjects() const = 0; + /// Returns list of currently selected QModelIndexes virtual QModelIndexList selectedIndexes() const = 0; diff --git a/src/ModuleBase/ModuleBase_ResultPrs.cpp b/src/ModuleBase/ModuleBase_ResultPrs.cpp index 3331b2865..bda0fbc82 100644 --- a/src/ModuleBase/ModuleBase_ResultPrs.cpp +++ b/src/ModuleBase/ModuleBase_ResultPrs.cpp @@ -65,6 +65,7 @@ #include #include #include +#include #if OCC_VERSION_HEX > 0x070400 #include @@ -299,7 +300,7 @@ void ModuleBase_ResultPrs::Compute( } // change deviation coefficient to provide more precise circle try { - AIS_Shape::Compute(thePresentationManager, thePresentation, theMode); + ViewerData_AISShape::Compute(thePresentationManager, thePresentation, theMode); } catch (...) { return; diff --git a/src/ModuleBase/ModuleBase_msg_fr.ts b/src/ModuleBase/ModuleBase_msg_fr.ts index ec1b6b2fd..be21c0edd 100644 --- a/src/ModuleBase/ModuleBase_msg_fr.ts +++ b/src/ModuleBase/ModuleBase_msg_fr.ts @@ -346,5 +346,9 @@ No visualization Aucune visualisation + + Set color on subshape of result + Définir la couleur sur la sous - forme du résultat + diff --git a/src/PartSet/PartSet_Module.cpp b/src/PartSet/PartSet_Module.cpp index efc795171..825d5a254 100644 --- a/src/PartSet/PartSet_Module.cpp +++ b/src/PartSet/PartSet_Module.cpp @@ -273,6 +273,13 @@ PartSet_Module::PartSet_Module(ModuleBase_IWorkshop* theWshop) Config_PropManager::registerProp("Visualization", "axis_arrow_size", "Trihedron arrows constant size", Config_Prop::IntSpin, "10"); + Config_PropManager::registerProp("Visualization", "color_subshape_result", + "Set color on subshape of result", Config_Prop::Boolean, "true"); + + Config_PropManager::registerProp("Shortcuts", "add_parameter_shortcut", + "Add parameter in parameters manager dialog", + Config_Prop::Shortcut, "Ctrl+A"); + Config_PropManager::registerProp("Windows", "use_hide_faces_panel", "Use HideFaces panel in operations", Config_Prop::Boolean, "false"); } @@ -1530,6 +1537,16 @@ void PartSet_Module::customizePresentation(const ObjectPtr& theObject, PartSet_Tools::getDefaultColor(aResult, false, aColor); } thePrs->setColor(aColor[0], aColor[1], aColor[2]); + + std::map> aColoredShapes; + ModelAPI_Tools::getColoredShapes(aResult, aColoredShapes); + if (!aColoredShapes.empty()) { + for (std::map>::const_iterator anIter(aColoredShapes.cbegin()); + anIter != aColoredShapes.cend(); ++anIter) { + thePrs->setColor(anIter->first, anIter->second.at(0), + anIter->second.at(1), anIter->second.at(2)); + } + } } } else { @@ -1553,7 +1570,6 @@ void PartSet_Module::customizePresentation(const ObjectPtr& theObject, } } - //****************************************************** ObjectPtr PartSet_Module::findPresentedObject(const AISObjectPtr& theAIS) const { diff --git a/src/XGUI/XGUI_ColorDialog.cpp b/src/XGUI/XGUI_ColorDialog.cpp index 184b56c68..a915292ee 100644 --- a/src/XGUI/XGUI_ColorDialog.cpp +++ b/src/XGUI/XGUI_ColorDialog.cpp @@ -25,6 +25,7 @@ #include #include +#include #include #include #include @@ -65,7 +66,7 @@ namespace }; } -XGUI_ColorDialog::XGUI_ColorDialog(QWidget* theParent) +XGUI_ColorDialog::XGUI_ColorDialog(QWidget* theParent, bool theCheckBoxNeed) : QDialog(theParent, Qt::Dialog | Qt::CustomizeWindowHint | Qt::WindowTitleHint) { setWindowTitle(tr("Color")); @@ -84,16 +85,20 @@ XGUI_ColorDialog::XGUI_ColorDialog(QWidget* theParent) myButtonGroup->addButton(aColorChoiceBtn, 0); myButtonGroup->addButton(aRandomChoiceBtn, 1); + if (theCheckBoxNeed) + myTargetSetCheck = new QCheckBox(tr("Set on selected face"), this); + aLay->addWidget(aColorChoiceBtn, 0, 0); aLay->addWidget(myColorButton, 0, 1); aLay->addWidget(aRandomChoiceBtn, 1, 0); aLay->addWidget(aRandomLabel, 1, 1); + aLay->addWidget(myTargetSetCheck, 2, 0, 1, 2); QDialogButtonBox* aButtons = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel, Qt::Horizontal, this); connect(aButtons, SIGNAL(accepted()), this, SLOT(accept())); connect(aButtons, SIGNAL(rejected()), this, SLOT(reject())); - aLay->addWidget(aButtons, 2, 0, 1, 2); + aLay->addWidget(aButtons, 3, 0, 1, 2); } bool XGUI_ColorDialog::isRandomColor() const @@ -101,6 +106,11 @@ bool XGUI_ColorDialog::isRandomColor() const return myButtonGroup->checkedId() == 1; } +bool XGUI_ColorDialog::isSetOnSubShape() const +{ + return myTargetSetCheck && myTargetSetCheck->isChecked(); +} + void XGUI_ColorDialog::setColor(const std::vector& theValue) { if (theValue.size() != 3) diff --git a/src/XGUI/XGUI_ColorDialog.h b/src/XGUI/XGUI_ColorDialog.h index 2bd94e2a7..bc4e2f722 100644 --- a/src/XGUI/XGUI_ColorDialog.h +++ b/src/XGUI/XGUI_ColorDialog.h @@ -25,6 +25,7 @@ #include class QButtonGroup; +class QCheckBox; class QtxColorButton; /** @@ -39,7 +40,7 @@ class XGUI_ColorDialog : public QDialog public: /// Constructor /// \param theParent a parent widget for the dialog - XGUI_EXPORT XGUI_ColorDialog(QWidget* theParent); + XGUI_EXPORT XGUI_ColorDialog(QWidget* theParent, bool theCheckBoxNeed = true); XGUI_EXPORT virtual ~XGUI_ColorDialog() {}; @@ -47,6 +48,10 @@ public: /// \return a boolean value bool isRandomColor() const; + /// Returns whether the need set color on subshape only + /// \return a boolean value + bool isSetOnSubShape() const; + /// Initializes the dialog with the given value. Set choice on certain value and fill it by. /// \param theValue an RGB components value void setColor(const std::vector& theValue); @@ -67,6 +72,7 @@ public: private: QButtonGroup* myButtonGroup; /// a group, contained random and certain color radio button choice QtxColorButton* myColorButton; /// a control to select a color + QCheckBox* myTargetSetCheck; /// a target shape for assign }; #endif diff --git a/src/XGUI/XGUI_Displayer.cpp b/src/XGUI/XGUI_Displayer.cpp index 477544490..96386fe08 100644 --- a/src/XGUI/XGUI_Displayer.cpp +++ b/src/XGUI/XGUI_Displayer.cpp @@ -92,6 +92,7 @@ #include #include #include +#include #include @@ -382,6 +383,31 @@ bool XGUI_Displayer::redisplay(ObjectPtr theObject, bool theUpdateViewer) aCol(aColor[0] / 255., aColor[1] / 255., aColor[2] / 255., Quantity_TOC_RGB); aAISIO->SetColor(aCol); } + // Set color on subshape from result + std::map> aColoredShapes; + ModelAPI_Tools::getColoredShapes(aResult, aColoredShapes); + Handle(AIS_ColoredShape) aResShape = Handle(AIS_ColoredShape)::DownCast(aAISIO); + Handle(ModuleBase_ResultPrs) aResPrsShape = Handle(ModuleBase_ResultPrs)::DownCast(aResShape); + + if (!aColoredShapes.empty() && !aResPrsShape.IsNull()) + { + for (std::map>::const_iterator anIter(aColoredShapes.cbegin()); + anIter != aColoredShapes.cend(); ++anIter) + { + if (aAISObj->getShape()->isSubShape(anIter->first)) + { + Quantity_Color aColorQ(anIter->second.at(0) / 255., + anIter->second.at(1) / 255., + anIter->second.at(2) / 255., + Quantity_TOC_RGB); + aResPrsShape->SetCustomColor(anIter->first->impl(), aColorQ); + } + } + } + else + { + aResShape->ClearCustomAspects(); + } // Set deflection double aDeflection = ModelAPI_Tools::getDeflection(aResult); if ((aDeflection >= 0) && (aDeflection != aAISObj->getDeflection())) diff --git a/src/XGUI/XGUI_Selection.cpp b/src/XGUI/XGUI_Selection.cpp index 7a80eb0a9..6e2ad3f7e 100644 --- a/src/XGUI/XGUI_Selection.cpp +++ b/src/XGUI/XGUI_Selection.cpp @@ -400,6 +400,46 @@ QObjectPtrList XGUI_Selection::selectedPresentations() const return aSelectedList; } +QMap> XGUI_Selection::selectedObjectsAndSubObjects() const +{ + QMap> aSelectedObjects; + + // Add all objects, which selected in Viewer + QList aValues = getSelected(ModuleBase_ISelection::Viewer); + foreach(ModuleBase_ViewerPrsPtr aPrs, aValues) + { + ResultPtr aResult = std::dynamic_pointer_cast(aPrs->object()); + GeomShapePtr aShape = aPrs->shape(); + + aSelectedObjects[aResult].push_back(aShape); + } + + // Add object, which selected in browser, but not selected in Viewer + QObjectPtrList anObjects = selectedObjects(); + foreach(ObjectPtr anObject, anObjects) + { + ResultBodyPtr aResultBody = std::dynamic_pointer_cast(anObject); + if (!aResultBody.get()) + continue; + GeomShapePtr aBodyShape = aResultBody->shape(); + + if (aSelectedObjects.contains(aResultBody)) + continue; + bool isContains = false; + foreach(GeomShapePtr aCurShape, aSelectedObjects[aResultBody]) + { + if (aCurShape->impl().IsEqual(aBodyShape->impl())) + { + isContains = true; + break; + } + } + if (!isContains) + aSelectedObjects[aResultBody].push_back(aBodyShape); + } + return aSelectedObjects; +} + //************************************************************** QModelIndexList XGUI_Selection::selectedIndexes() const { diff --git a/src/XGUI/XGUI_Selection.h b/src/XGUI/XGUI_Selection.h index 9cf5ea963..3dbb3ba90 100644 --- a/src/XGUI/XGUI_Selection.h +++ b/src/XGUI/XGUI_Selection.h @@ -66,6 +66,9 @@ class XGUI_EXPORT XGUI_Selection : public ModuleBase_ISelection /// Returns list of currently selected results virtual QObjectPtrList selectedPresentations() const; + /// Returns map of selected results and their selected subobjects + virtual QMap> selectedObjectsAndSubObjects() const; + /// Returns list of currently selected QModelIndexes virtual QModelIndexList selectedIndexes() const; diff --git a/src/XGUI/XGUI_Workshop.cpp b/src/XGUI/XGUI_Workshop.cpp index 0df895c85..3d128ef70 100644 --- a/src/XGUI/XGUI_Workshop.cpp +++ b/src/XGUI/XGUI_Workshop.cpp @@ -1785,6 +1785,7 @@ ModuleBase_IViewer* XGUI_Workshop::salomeViewer() const void XGUI_Workshop::onContextMenuCommand(const QString& theId, bool isChecked) { QObjectPtrList anObjects = mySelector->selection()->selectedObjects(); + QMap> aSelectedObjects = mySelector->selection()->selectedObjectsAndSubObjects(); if (theId == "DELETE_CMD") deleteObjects(); else if (theId == "CLEAN_HISTORY_CMD") @@ -1794,9 +1795,9 @@ void XGUI_Workshop::onContextMenuCommand(const QString& theId, bool isChecked) else if (theId == "RECOVER_CMD") recoverFeature(); else if (theId == "COLOR_CMD") - changeColor(anObjects); + changeColor(aSelectedObjects); else if (theId == "AUTOCOLOR_CMD") - changeAutoColor(anObjects); + changeAutoColor(aSelectedObjects); else if (theId == "ISOLINES_CMD") changeIsoLines(anObjects); else if (theId == "SHOW_ISOLINES_CMD") { @@ -2564,29 +2565,52 @@ void getDefaultColor(ObjectPtr theObject, const bool isEmptyColorValid, } //************************************************************** -void XGUI_Workshop::changeColor(const QObjectPtrList& theObjects) +void XGUI_Workshop::changeColor(const QMap>& theSelectedObjects) { AttributeIntArrayPtr aColorAttr; // 1. find the current color of the object. This is a color of AIS presentation // The objects are iterated until a first valid color is found std::vector aColor; - foreach(ObjectPtr anObject, theObjects) { - ResultPtr aResult = std::dynamic_pointer_cast(anObject); - if (aResult.get()) { - ModelAPI_Tools::getColor(aResult, aColor); + QList aValues = mySelector->selection()->getSelected(ModuleBase_ISelection::Viewer); + const bool isColorOnSubShape = Config_PropManager::boolean("Visualization", "color_subshape_result"); + foreach(ResultPtr aResult, theSelectedObjects.keys()) + { + if (!aResult.get()) + continue; + + foreach(GeomShapePtr aShape, theSelectedObjects[aResult]) + { + if (aResult->shape()->impl().IsEqual(aShape->impl()) || !isColorOnSubShape) + { + ModelAPI_Tools::getColor(aResult, aColor); + } + else if (!aShape->isNull()) + { + ModelAPI_Tools::getColor(aResult, aShape, aColor); + if (aColor.empty()) + { + ModelAPI_Tools::getColor(aResult, aColor); + } + } + if (aColor.empty()) { - AISObjectPtr anAISObj = myDisplayer->getAISObject(anObject); + AISObjectPtr anAISObj = myDisplayer->getAISObject(aResult); if (anAISObj.get()) { aColor.resize(3); anAISObj->getColor(aColor[0], aColor[1], aColor[2]); } } - if (aColor.empty()) { + if (aColor.empty()) getDefaultColor(aResult, false, aColor); - } + if (!aColor.empty() || !isColorOnSubShape) + break; } + + if (!aColor.empty()) + break; } + if (aColor.size() != 3) return; @@ -2601,6 +2625,7 @@ void XGUI_Workshop::changeColor(const QObjectPtrList& theObjects) return; bool isRandomColor = aDlg->isRandomColor(); + bool isSetToShape = aDlg->isSetOnSubShape(); // 3. abort the previous operation and start a new one SessionPtr aMgr = ModelAPI_Session::get(); @@ -2608,22 +2633,38 @@ void XGUI_Workshop::changeColor(const QObjectPtrList& theObjects) aMgr->startOperation(aDescription.toStdString()); - // 4. set the value to all results + // 4. set the value to all results and subshapes from result (if was select subshape of result) std::vector aColorResult = aDlg->getColor(); - foreach(ObjectPtr anObj, theObjects) { - ResultPtr aResult = std::dynamic_pointer_cast(anObj); - if (aResult.get() != NULL) { - ResultBodyPtr aBodyResult = std::dynamic_pointer_cast(aResult); - if (aBodyResult.get() != NULL) { // change colors for all sub-solids - std::list allRes; - ModelAPI_Tools::allSubs(aBodyResult, allRes); - for(std::list::iterator aRes = allRes.begin(); aRes != allRes.end(); aRes++) { - ModelAPI_Tools::setColor(*aRes, !isRandomColor ? aColorResult : aDlg->getRandomColor()); + foreach(ResultPtr aResult, theSelectedObjects.keys()) + { + if (!aResult.get()) + continue; + ResultBodyPtr aBodyResult = std::dynamic_pointer_cast(aResult); + foreach(GeomShapePtr aShape, theSelectedObjects[aResult]) + { + if (aResult->shape()->impl().IsEqual(aShape->impl()) || !isColorOnSubShape || !isSetToShape) + { + if (aResult.get() != NULL) + { + // change colors for all sub-solids + std::list allRes; + ModelAPI_Tools::allSubs(aBodyResult, allRes); + for (std::list::iterator aRes = allRes.begin(); aRes != allRes.end(); aRes++) + { + ModelAPI_Tools::setColor(*aRes, !isRandomColor ? aColorResult : aDlg->getRandomColor()); + } + ModelAPI_Tools::setColor(aResult, !isRandomColor ? aColorResult : aDlg->getRandomColor()); } + if (!isColorOnSubShape) + break; + } + else if (!aShape->isNull()) + { + ModelAPI_Tools::setColor(aResult, aShape, !isRandomColor ? aColorResult : aDlg->getRandomColor()); } - ModelAPI_Tools::setColor(aResult, !isRandomColor ? aColorResult : aDlg->getRandomColor()); } } + Events_Loop::loop()->flush(Events_Loop::eventByName(EVENT_OBJECT_TO_REDISPLAY)); aMgr->finishOperation(); updateCommandStatus(); @@ -2631,7 +2672,7 @@ void XGUI_Workshop::changeColor(const QObjectPtrList& theObjects) } //************************************************************** -void XGUI_Workshop::changeAutoColor(const QObjectPtrList& theObjects) +void XGUI_Workshop::changeAutoColor(const QMap>& theSelectedObjects) { if (!abortAllOperations()) return; @@ -2648,29 +2689,40 @@ void XGUI_Workshop::changeAutoColor(const QObjectPtrList& theObjects) Config_PropManager::setAutoColorStatus(false); ModelAPI_Tools::findRandomColor(aColor, true); } else { - // set the value to all results - foreach (ObjectPtr anObj, theObjects) { - DocumentPtr aDocument = anObj->document(); + QList aValues = mySelector->selection()->getSelected(ModuleBase_ISelection::Viewer); + const bool isColorOnSubShape = Config_PropManager::boolean("Visualization", "color_subshape_result"); + foreach(ResultPtr aResult, theSelectedObjects.keys()) + { + if (!aResult.get()) + continue; + + DocumentPtr aDocument = aResult->document(); std::list anAllFeatures = allFeatures(aDocument); - // find the object iterator - std::list::iterator anObjectIt = anAllFeatures.begin(); - for (; anObjectIt != anAllFeatures.end(); ++ anObjectIt) { - FeaturePtr aFeature = *anObjectIt; - if (aFeature.get()) { - std::list aResults; - ModelAPI_Tools::allResults(aFeature, aResults); - std::list >::const_iterator aIt; - for (aIt = aResults.cbegin(); aIt != aResults.cend(); aIt++) { - ResultPtr aGroupResult = *aIt; - if (aGroupResult.get() && + foreach(GeomShapePtr aShape, theSelectedObjects[aResult]) + { + std::list::iterator anObjectIt = anAllFeatures.begin(); + for (; anObjectIt != anAllFeatures.end(); ++anObjectIt) { + FeaturePtr aFeature = *anObjectIt; + if (aFeature.get()) { + std::list aResults; + ModelAPI_Tools::allResults(aFeature, aResults); + std::list >::const_iterator aIt; + for (aIt = aResults.cbegin(); aIt != aResults.cend(); aIt++) { + ResultPtr aGroupResult = *aIt; + if (aGroupResult.get() && aGroupResult->groupName() == ModelAPI_ResultGroup::group()) { - ModelAPI_Tools::findRandomColor(aColor); - ModelAPI_Tools::setColor(aGroupResult, aColor); + ModelAPI_Tools::findRandomColor(aColor); + ModelAPI_Tools::setColor(aGroupResult, aColor); + } } } } } + + if (!aColor.empty()) + break; } + Events_Loop::loop()->flush(Events_Loop::eventByName(EVENT_OBJECT_TO_REDISPLAY)); aMgr->finishOperation(); updateCommandStatus(); diff --git a/src/XGUI/XGUI_Workshop.h b/src/XGUI/XGUI_Workshop.h index e0d97cbae..e3d949a7e 100644 --- a/src/XGUI/XGUI_Workshop.h +++ b/src/XGUI/XGUI_Workshop.h @@ -201,15 +201,15 @@ Q_OBJECT /// \return boolean value bool canChangeProperty(const QString& theActionName) const; - /// Change color of the results if it is possible - /// The operation is available for construction, body and group results - /// theObjects a list of selected objects - void changeColor(const QObjectPtrList& theObjects); + /// Change color of the selected objects (result and subshape of result) if it is possible + /// The operation is available for subshape of result, construction, body and group results + /// theSelectedObjects a list of selected objects + void changeColor(const QMap>& theSelectedObjects); /// Change Autocolor of the results if it is possible /// The operation is available for group results /// theObjects a list of selected objects - void changeAutoColor(const QObjectPtrList& theObjects); + void changeAutoColor(const QMap>& theSelectedObjects); /// Change deflection of the results if it is possible /// The operation is available for construction, body and group results