From: Jérôme Date: Sun, 4 Oct 2020 15:07:30 +0000 (+0200) Subject: Implementation of fillet multi-Radius (Working progress) X-Git-Url: http://git.salome-platform.org/gitweb/?a=commitdiff_plain;h=4ea512aa999fae93f4c05ec29d04b0bbed42974d;p=modules%2Fshaper.git Implementation of fillet multi-Radius (Working progress) --- diff --git a/src/ConnectorAPI/Test/TestExportSTL.py b/src/ConnectorAPI/Test/TestExportSTL.py new file mode 100644 index 000000000..edc7eaf01 --- /dev/null +++ b/src/ConnectorAPI/Test/TestExportSTL.py @@ -0,0 +1,159 @@ +# Copyright (C) 2014-2020 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 +# + +""" + TestExport.py + Unit test of ExchangePlugin_TestExport class +""" +#========================================================================= +# Initialization of the test +#========================================================================= + +import salome + +import os +import math +from tempfile import TemporaryDirectory + +import GEOM + +from ModelAPI import * + +from salome.shaper import model + +from salome.geom import geomBuilder + +from GeomAlgoAPI import * + +__updated__ = "2015-05-22" + +salome.salome_init(1) +geompy = geomBuilder.New() + +#========================================================================= +# Help functions +#========================================================================= +def removeFile(theFileName): + try: os.remove(theFileName) + except OSError: pass + assert not os.path.exists(theFileName), \ + "Can not remove file {0}".format(theFileName) + +#========================================================================= +# test Export STL +#========================================================================= +def testExportSTL(theFile, theDelta, theErrorExpected = False): + + model.begin() + partSet = model.moduleDocument() + Part_1 = model.addPart(partSet) + Part_1_doc = Part_1.document() + Box_1 = model.addBox(Part_1_doc, 10, 10, 10) + Box_2 = model.addBox(Part_1_doc, 20, 20, 20) + model.do() + + # First export to GEOM + model.exportToGEOM(Part_1_doc) + model.end() + + theSurface = 600 + + print("theFile=",theFile) + + # deflection relative 0.0001 et Ascii + model.exportToSTL(Part_1_doc, theFile, model.selection("SOLID","Box_1_1"),0.0001, 0.5, True,False) + + #== assert os.path.exists(theFile) + + # Check results + test_stl_1 = geompy.ImportSTL(theFile) + Props = geompy.BasicProperties(test_stl_1) + print("\nBasic Properties:") + print(" Wires length: ", Props[0]) + print(" Surface area: ", Props[1]) + print(" Volume : ", Props[2]) + + aRefSurface = theSurface + aResSurface = Props[1] + assert (math.fabs(aResSurface - aRefSurface) < theDelta), "The volume is wrong: expected = {0}, real = {1}".format(aRefSurface, aResSurface) + + removeFile(theFile) + + theSurface = 600 + # deflection relative 0.0001 et binaire + model.exportToSTL(Part_1_doc, theFile, model.selection("SOLID", "Box_1_1" ),0.0001, 0.5, True,True) + + # Check results + test_stl_1 = geompy.ImportSTL(theFile) + Props = geompy.BasicProperties(test_stl_1) + print("\nBasic Properties:") + print(" Wires length: ", Props[0]) + print(" Surface area: ", Props[1]) + print(" Volume : ", Props[2]) + + aRefSurface = theSurface + aResSurface = Props[1] + assert (math.fabs(aResSurface - aRefSurface) < theDelta), "The volume is wrong: expected = {0}, real = {1}".format(aRefSurface, aResSurface) + + removeFile(theFile) + + theSurface = 600 + # deflection absolue et AScii + model.exportToSTL(Part_1_doc, theFile, model.selection("SOLID", "Box_1_1" ),0.0001, 0.5, False, False) + + # Check results + test_stl_1 = geompy.ImportSTL(theFile) + Props = geompy.BasicProperties(test_stl_1) + print("\nBasic Properties:") + print(" Wires length: ", Props[0]) + print(" Surface area: ", Props[1]) + print(" Volume : ", Props[2]) + + aRefSurface = theSurface + aResSurface = Props[1] + assert (math.fabs(aResSurface - aRefSurface) < theDelta), "The volume is wrong: expected = {0}, real = {1}".format(aRefSurface, aResSurface) + + theSurface = 600 + # deflection absolue et binaire + model.exportToSTL(Part_1_doc, theFile, model.selection("SOLID", "Box_1_1" ),0.0001, 0.5, False,True) + + # Check results + test_stl_1 = geompy.ImportSTL(theFile) + Props = geompy.BasicProperties(test_stl_1) + print("\nBasic Properties:") + print(" Wires length: ", Props[0]) + print(" Surface area: ", Props[1]) + print(" Volume : ", Props[2]) + + aRefSurface = theSurface + aResSurface = Props[1] + assert (math.fabs(aResSurface - aRefSurface) < theDelta), "The volume is wrong: expected = {0}, real = {1}".format(aRefSurface, aResSurface) + + model.end() + +if __name__ == '__main__': + with TemporaryDirectory() as tmp_dir: + aRealSurface = 0.00192878 + #========================================================================= + # Export a shape into STL + #========================================================================= + testExportSTL(os.path.join(tmp_dir, "export.stl"), 10 ** -5, True) + #========================================================================= + # End of test + #========================================================================= diff --git a/src/ConnectorAPI/Test/TestImportSTEP.py b/src/ConnectorAPI/Test/TestImportSTEP.py new file mode 100644 index 000000000..f6094c1d2 --- /dev/null +++ b/src/ConnectorAPI/Test/TestImportSTEP.py @@ -0,0 +1,124 @@ +# Copyright (C) 2014-2020 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 +# + +""" + TestImportStep.py + Unit test of ExchangePlugin_ImportFeature class for STEP +""" +#========================================================================= +# Initialization of the test +#========================================================================= + +import salome + +import os +import math +from tempfile import TemporaryDirectory + +import GEOM + +from ModelAPI import * + +from salome.shaper import model + +from salome.geom import geomBuilder + +from GeomAPI import GeomAPI_Shape + +from GeomAlgoAPI import * + +__updated__ = "2015-05-22" + +salome.salome_init(1) +geompy = geomBuilder.New() + +#========================================================================= +# Help functions +#========================================================================= +def removeFile(theFileName): + try: os.remove(theFileName) + except OSError: pass + assert not os.path.exists(theFileName), \ + "Can not remove file {0}".format(theFileName) + +#========================================================================= +# test Import STEP +#========================================================================= +def testImportSTEP(): + + model.begin() + partSet = model.moduleDocument() + Part_1 = model.addPart(partSet) + Part_1_doc = Part_1.document() + aShapePath = os.path.join(os.getenv("DATA_DIR"), "Shapes", "Step", "black_and_white.step") + print("aShapePath=",aShapePath) + Import_1 = model.addImportStep(Part_1_doc,aShapePath, True, True, True) + + model.do() + + # Check results + Import_1_Feature = Import_1.feature() + assert Import_1_Feature.error() == '' + assert Import_1_Feature.name() == "black_and_white" + assert len(Import_1_Feature.results()) == 1 + model.testNbSubShapes(Import_1, GeomAPI_Shape.SOLID, [2]) + + aCompositeFeature = featureToCompositeFeature(Import_1_Feature) + assert aCompositeFeature.numberOfSubs(False) == 2 + + aFeature1 = aCompositeFeature.subFeature(0, False) + assert aFeature1.getKind() == "Group" + assert aFeature1.name() == "Color_1" + + aSelectionList = aFeature1.selectionList("group_list") + assert aSelectionList.size() == 1 + + aFeature1 = aCompositeFeature.subFeature(1, False) + assert aFeature1.getKind() == "Group" + assert aFeature1.name() == "Color_2" + + aSelectionList = aFeature1.selectionList("group_list") + assert aSelectionList.size() == 1 + + aFeature1 = aCompositeFeature.subFeature(2, False) + assert aFeature1.getKind() == "Group" + assert aFeature1.name() == "Material_black" + + aSelectionList = aFeature1.selectionList("group_list") + assert aSelectionList.size() == 1 + + + aFeature1 = aCompositeFeature.subFeature(3, False) + assert aFeature1.getKind() == "Group" + assert aFeature1.name() == "Material_white" + + aSelectionList = aFeature1.selectionList("group_list") + assert aSelectionList.size() == 1 + + model.end() + +if __name__ == '__main__': + with TemporaryDirectory() as tmp_dir: + #========================================================================= + # Export a shape into STL + #========================================================================= + testImportSTEP() + #========================================================================= + # End of test + #========================================================================= diff --git a/src/ExchangeAPI/CMakeLists.txt b/src/ExchangeAPI/CMakeLists.txt index bdf5bcb34..b61f22ce9 100644 --- a/src/ExchangeAPI/CMakeLists.txt +++ b/src/ExchangeAPI/CMakeLists.txt @@ -33,12 +33,14 @@ SET(PROJECT_SOURCES SET(PROJECT_LIBRARIES ModelAPI ModelHighAPI + GeomAlgoAPI ) INCLUDE_DIRECTORIES( ${PROJECT_SOURCE_DIR}/src/Events ${PROJECT_SOURCE_DIR}/src/ModelAPI ${PROJECT_SOURCE_DIR}/src/ModelHighAPI + ${PROJECT_SOURCE_DIR}/src/GeomAlgoAPI ) # Plugin headers dependency diff --git a/src/ExchangeAPI/ExchangeAPI_Export.cpp b/src/ExchangeAPI/ExchangeAPI_Export.cpp index 000e178ab..4e9b4b9c3 100644 --- a/src/ExchangeAPI/ExchangeAPI_Export.cpp +++ b/src/ExchangeAPI/ExchangeAPI_Export.cpp @@ -53,6 +53,51 @@ ExchangeAPI_Export::ExchangeAPI_Export(const std::shared_ptr& apply(); // finish operation to make sure the export is done on the current state of the history } +// Constructor with values for STL of selected result export. +ExchangeAPI_Export::ExchangeAPI_Export(const std::shared_ptr& theFeature, + const std::string & theFilePath, + const ModelHighAPI_Selection& theSelectedShape, + double aDeflectionRelative, + double aDeflectionAbsolute, + const bool anIsRelative, + const bool anIsASCII) + : ModelHighAPI_Interface(theFeature) +{ + initialize(); + fillAttribute("STL", theFeature->string(ExchangePlugin_ExportFeature::EXPORT_TYPE_ID())); + fillAttribute(theFilePath, theFeature->string(ExchangePlugin_ExportFeature::STL_FILE_PATH_ID())); + + if (anIsRelative) { + fillAttribute(ExchangePlugin_ExportFeature::STL_DEFLECTION_TYPE_RELATIVE(), + theFeature->string(ExchangePlugin_ExportFeature::STL_DEFLECTION_TYPE()) ); + fillAttribute(aDeflectionRelative, + theFeature->real(ExchangePlugin_ExportFeature::STL_RELATIVE()) ); + } + else { + fillAttribute(ExchangePlugin_ExportFeature::STL_DEFLECTION_TYPE_ABSOLUTE(), + theFeature->string(ExchangePlugin_ExportFeature::STL_DEFLECTION_TYPE()) ); + fillAttribute(aDeflectionAbsolute, + theFeature->real(ExchangePlugin_ExportFeature::STL_ABSOLUTE()) ); + } + + if(anIsASCII){ + fillAttribute(ExchangePlugin_ExportFeature::STL_FILE_TYPE_ASCII(), + theFeature->string(ExchangePlugin_ExportFeature::STL_FILE_TYPE())); + } + else + { + fillAttribute(ExchangePlugin_ExportFeature::STL_FILE_TYPE_BINARY(), + theFeature->string(ExchangePlugin_ExportFeature::STL_FILE_TYPE())); + } + + fillAttribute(theSelectedShape,theFeature->selection(ExchangePlugin_ExportFeature::STL_OBJECT_SELECTED())); + fillAttribute("STL", theFeature->string(ExchangePlugin_ExportFeature::FILE_FORMAT_ID())); + execute(); + apply(); // finish operation to make sure the export is done on the current state of the history +} + + + ExchangeAPI_Export::ExchangeAPI_Export(const std::shared_ptr& theFeature, const std::string & theFilePath, const ModelHighAPI_Selection& theResult, const std::string & theAuthor, const std::string & theGeometryName) @@ -74,6 +119,7 @@ ExchangeAPI_Export::ExchangeAPI_Export(const std::shared_ptr& } + /// Constructor with values for export in other formats than XAO. ExchangeAPI_Export::ExchangeAPI_Export(const std::shared_ptr& theFeature, const std::string & theFilePath, @@ -144,6 +190,33 @@ void ExchangeAPI_Export::dump(ModelHighAPI_Dumper& theDumper) const theDumper << ", '" << theGeometryName << "'"; theDumper << ")" << std::endl; } + else if (exportType == "STL") { + std::string aTmpSTLFile = + aBase->string(ExchangePlugin_ExportFeature::STL_FILE_PATH_ID())->value(); + correctSeparators(aTmpSTLFile); + theDumper << "exportToSTL(" << aDocName << ", '" << aTmpSTLFile << "'" ; + AttributeSelectionPtr aShapeSelected = + aBase->selection(ExchangePlugin_ExportFeature::STL_OBJECT_SELECTED()); + + theDumper<<","<< aShapeSelected; + + theDumper <<","<< stlabsolute() <<","<< stlrelative(); + + if (stldeflectionType()->value() == ExchangePlugin_ExportFeature::STL_DEFLECTION_TYPE_RELATIVE()) { + theDumper <<","<< "True"; + } + else { + theDumper <<","<< "False"; + } + + if (stlfileType()->value() == ExchangePlugin_ExportFeature::STL_FILE_TYPE_BINARY()) { + theDumper << "False"; + } + else { + theDumper << "True"; + } + theDumper << ")" << std::endl; + } else { std::string aFilePath = aBase->string(ExchangePlugin_ExportFeature::FILE_PATH_ID())->value(); correctSeparators(aFilePath); @@ -179,6 +252,27 @@ ExportPtr exportToXAO(const std::shared_ptr & thePart, return ExportPtr(new ExchangeAPI_Export(aFeature, theFilePath, theAuthor, theGeometryName)); } +ExportPtr exportToSTL(const std::shared_ptr & thePart, + const std::string & theFilePath, + const ModelHighAPI_Selection& theSelectedShape, + double aDeflectionRelative, + double aDeflectionAbsolute, + const bool anIsRelative, + const bool anIsASCII) +{ + apply(); // finish previous operation to make sure all previous operations are done + std::shared_ptr aFeature = + thePart->addFeature(ExchangePlugin_ExportFeature::ID()); + + return ExportPtr(new ExchangeAPI_Export(aFeature, + theFilePath, + theSelectedShape, + aDeflectionRelative, + aDeflectionAbsolute, + anIsRelative, + anIsASCII)); +} + ExportPtr exportToXAO(const std::shared_ptr & thePart, const std::string & theFilePath, const ModelHighAPI_Selection& theSelectedShape, const std::string & /*theAuthor*/, const std::string & /*theGeometryName*/) diff --git a/src/ExchangeAPI/ExchangeAPI_Export.h b/src/ExchangeAPI/ExchangeAPI_Export.h index 24211c9fa..d867da1bf 100644 --- a/src/ExchangeAPI/ExchangeAPI_Export.h +++ b/src/ExchangeAPI/ExchangeAPI_Export.h @@ -51,6 +51,16 @@ public: const std::string & theFilePath, const std::string & theAuthor = std::string(), const std::string & theGeometryName = std::string()); + + /// Constructor with values for STL of selected result export. + EXCHANGEAPI_EXPORT + explicit ExchangeAPI_Export(const std::shared_ptr& theFeature, + const std::string & theFilePath, + const ModelHighAPI_Selection& theSelectedShape, + double aDeflectionRelative , + double aDeflectionAbsolute, + const bool anIsRelative, + const bool anIsASCII); /// Constructor with values for XAO of selected result export. EXCHANGEAPI_EXPORT @@ -71,7 +81,7 @@ public: EXCHANGEAPI_EXPORT virtual ~ExchangeAPI_Export(); - INTERFACE_7(ExchangePlugin_ExportFeature::ID(), + INTERFACE_15(ExchangePlugin_ExportFeature::ID(), exportType, ExchangePlugin_ExportFeature::EXPORT_TYPE_ID(), ModelAPI_AttributeString, /** ExportType */, filePath, ExchangePlugin_ExportFeature::FILE_PATH_ID(), @@ -85,7 +95,23 @@ public: xaoAuthor, ExchangePlugin_ExportFeature::XAO_AUTHOR_ID(), ModelAPI_AttributeString, /** xao author */, xaoGeometryName, ExchangePlugin_ExportFeature::XAO_GEOMETRY_NAME_ID(), - ModelAPI_AttributeString, /** xao geometry name */) + ModelAPI_AttributeString, /** xao geometry name */, + stlFilePath, ExchangePlugin_ExportFeature::STL_FILE_PATH_ID(), + ModelAPI_AttributeString, /** stl_file_path */, + stlobjectselected, ExchangePlugin_ExportFeature::STL_OBJECT_SELECTED(), + ModelAPI_AttributeSelection, /** Object selected to export in stl file*/, + stldeflectionType, ExchangePlugin_ExportFeature::STL_DEFLECTION_TYPE(), + ModelAPI_AttributeString, /** Type of the defelection */, + stlrelative, ExchangePlugin_ExportFeature::STL_RELATIVE(), + ModelAPI_AttributeDouble, /** Relative*/, + stlabsolute, ExchangePlugin_ExportFeature::STL_ABSOLUTE(), + ModelAPI_AttributeDouble, /** Absolute */, + stlfileType, ExchangePlugin_ExportFeature::STL_FILE_TYPE(), + ModelAPI_AttributeString, /** Type of the stl file*/, + stldeflectionTypeabsolute, ExchangePlugin_ExportFeature::STL_DEFLECTION_TYPE_ABSOLUTE(), + ModelAPI_AttributeString, /** Type of the defelection */, + stldeflectionTyperelative, ExchangePlugin_ExportFeature::STL_DEFLECTION_TYPE_RELATIVE(), + ModelAPI_AttributeString, /** Type of the defelection */) /// Dump wrapped feature EXCHANGEAPI_EXPORT @@ -113,6 +139,18 @@ ExportPtr exportToXAO(const std::shared_ptr & thePart, const std::string & theAuthor = std::string(), const std::string & theGeometryName = std::string()); +/**\ingroup CPPHighAPI + * \brief Exports to STL file the result of the current document + */ +EXCHANGEAPI_EXPORT +ExportPtr exportToSTL(const std::shared_ptr & thePart, + const std::string & theFilePath, + const ModelHighAPI_Selection& theSelectedShape, + double aDeflectionRelative, + double aDeflectionAbsolute, + const bool anIsRelative, + const bool anIsASCII); + /**\ingroup CPPHighAPI * \brief Exports to XAO file the selected result with groups parts related to it only. */ diff --git a/src/ExchangeAPI/ExchangeAPI_Import.cpp b/src/ExchangeAPI/ExchangeAPI_Import.cpp index b1a6c832d..d5d7ea2a9 100644 --- a/src/ExchangeAPI/ExchangeAPI_Import.cpp +++ b/src/ExchangeAPI/ExchangeAPI_Import.cpp @@ -28,6 +28,8 @@ #include #include #include +#include + //-------------------------------------------------------------------------------------- #include @@ -47,16 +49,43 @@ ExchangeAPI_Import::ExchangeAPI_Import( setFilePath(theFilePath); } +ExchangeAPI_Import::ExchangeAPI_Import( + const std::shared_ptr & theFeature, + const std::string & theFilePath, + const bool anScalInterUnits, + const bool anMaterials, + const bool anColor) +: ModelHighAPI_Interface(theFeature) +{ + if (initialize()) + setParameters(theFilePath,anScalInterUnits,anMaterials,anColor); +} + ExchangeAPI_Import::~ExchangeAPI_Import() { } +//-------------------------------------------------------------------------------------- +void ExchangeAPI_Import::setParameters(const std::string & theFilePath, + const bool anScalInterUnits, + const bool anMaterials, + const bool anColor) +{ + fillAttribute(theFilePath, mystepfilePath); + fillAttribute("STEP", feature()->string(ExchangePlugin_ImportFeature::IMPORT_TYPE_ID())); + fillAttribute(anScalInterUnits, feature()->boolean(ExchangePlugin_ImportFeature::STEP_SCALE_INTER_UNITS_ID())); + fillAttribute(anMaterials, feature()->boolean(ExchangePlugin_ImportFeature::STEP_MATERIALS_ID())); + fillAttribute(anColor, feature()->boolean(ExchangePlugin_ImportFeature::STEP_COLORS_ID())); + execute(); +} + //-------------------------------------------------------------------------------------- void ExchangeAPI_Import::setFilePath(const std::string & theFilePath) { fillAttribute(theFilePath, myfilePath); - + std::string anExtension = GeomAlgoAPI_Tools::File_Tools::extension(theFilePath); + fillAttribute(anExtension, feature()->string(ExchangePlugin_ImportFeature::IMPORT_TYPE_ID())); execute(); } @@ -66,7 +95,16 @@ void ExchangeAPI_Import::dump(ModelHighAPI_Dumper& theDumper) const FeaturePtr aBase = feature(); std::string aPartName = theDumper.name(aBase->document()); - std::string aFilePath = aBase->string(ExchangePlugin_ImportFeature::FILE_PATH_ID())->value(); + AttributeStringPtr aImportTypeAttr = aBase->string(ExchangePlugin_ImportFeature::IMPORT_TYPE_ID()); + std::string aFormat = aImportTypeAttr->value(); + std::string aFilePath; + if (aFormat == "STEP" || aFormat == "STP") + { + aFilePath = aBase->string(ExchangePlugin_ImportFeature::STEP_FILE_PATH_ID())->value(); + }else{ + aFilePath = aBase->string(ExchangePlugin_ImportFeature::FILE_PATH_ID())->value(); + } + std::string aFrom = "\\"; std::string aTo = "\\\\"; for(std::size_t aPos = aFilePath.find(aFrom); @@ -75,9 +113,19 @@ void ExchangeAPI_Import::dump(ModelHighAPI_Dumper& theDumper) const aFilePath.replace(aPos, aFrom.size(), aTo); aPos += aTo.size(); } - - theDumper << aBase << " = model.addImport(" << aPartName << ", \"" + std::string anExtension = GeomAlgoAPI_Tools::File_Tools::extension(aFilePath); + if( anExtension == "STP" || anExtension == "STEP"){ + theDumper << aBase << " = model.addImportStep(" << aPartName << ", \"" + << aFilePath << "\"" ; + + theDumper << ", " << scalinterunits()->value() + << ", " << materials()->value() + << ", " << colors()->value() << ")"<< std::endl; + }else{ + theDumper << aBase << " = model.addImport(" << aPartName << ", \"" << aFilePath << "\")" << std::endl; + } + // to make import have results theDumper << "model.do()" << std::endl; @@ -102,6 +150,18 @@ ImportPtr addImport( return ImportPtr(new ExchangeAPI_Import(aFeature, theFilePath)); } +ImportPtr addImportStep( + const std::shared_ptr & thePart, + const std::string & theFilePath, + const bool anScalInterUnits, + const bool anMaterials, + const bool anColor ) +{ + std::shared_ptr aFeature = thePart->addFeature(ExchangeAPI_Import::ID()); + return ImportPtr(new ExchangeAPI_Import(aFeature, theFilePath, + anScalInterUnits, anMaterials, anColor)); +} + void importPart(const std::shared_ptr & thePart, const std::string & theFilePath, const ModelHighAPI_Reference & theAfterThis) diff --git a/src/ExchangeAPI/ExchangeAPI_Import.h b/src/ExchangeAPI/ExchangeAPI_Import.h index f38db9bbb..d95a45389 100644 --- a/src/ExchangeAPI/ExchangeAPI_Import.h +++ b/src/ExchangeAPI/ExchangeAPI_Import.h @@ -46,18 +46,43 @@ public: EXCHANGEAPI_EXPORT ExchangeAPI_Import(const std::shared_ptr & theFeature, const std::string & theFilePath); + + /// Constructor with values for Step file + EXCHANGEAPI_EXPORT + ExchangeAPI_Import(const std::shared_ptr & theFeature, + const std::string & theFilePath, + const bool anScalInterUnits, + const bool anMaterials, + const bool anColor); + /// Destructor EXCHANGEAPI_EXPORT virtual ~ExchangeAPI_Import(); - INTERFACE_1(ExchangePlugin_ImportFeature::ID(), + INTERFACE_6(ExchangePlugin_ImportFeature::ID(), filePath, ExchangePlugin_ImportFeature::FILE_PATH_ID(), - ModelAPI_AttributeString, /** File path */ + ModelAPI_AttributeString, /** File path */, + stepimporttype, ExchangePlugin_ImportFeature::IMPORT_TYPE_ID(), + ModelAPI_AttributeString, /**import type */, + stepfilePath, ExchangePlugin_ImportFeature::STEP_FILE_PATH_ID(), + ModelAPI_AttributeString, /**step File path */, + scalinterunits, ExchangePlugin_ImportFeature::STEP_SCALE_INTER_UNITS_ID(), + ModelAPI_AttributeBoolean, /** Scale internationals units */, + materials, ExchangePlugin_ImportFeature::STEP_MATERIALS_ID(), + ModelAPI_AttributeBoolean, /** Materials */, + colors, ExchangePlugin_ImportFeature::STEP_COLORS_ID(), + ModelAPI_AttributeBoolean, /** Colors */ ) /// Set point values EXCHANGEAPI_EXPORT void setFilePath(const std::string & theFilePath); + + EXCHANGEAPI_EXPORT + void setParameters(const std::string & theFilePath, + const bool anScalInterUnits, + const bool anMaterials, + const bool anColor); /// Dump wrapped feature EXCHANGEAPI_EXPORT @@ -74,6 +99,16 @@ EXCHANGEAPI_EXPORT ImportPtr addImport(const std::shared_ptr & thePart, const std::string & theFilePath); +/**\ingroup CPPHighAPI + * \brief Create Import Step feature + */ +EXCHANGEAPI_EXPORT +ImportPtr addImportStep(const std::shared_ptr & thePart, + const std::string & theFilePath, + const bool anScalInterUnits, + const bool anMaterials, + const bool anColor); + /** \ingroup CPPHighAPI * \brief Import features from the file to the document after the current feature (or to the end). */ diff --git a/src/ExchangePlugin/CMakeLists.txt b/src/ExchangePlugin/CMakeLists.txt index 67880c8e6..3df98bece 100644 --- a/src/ExchangePlugin/CMakeLists.txt +++ b/src/ExchangePlugin/CMakeLists.txt @@ -31,6 +31,7 @@ INCLUDE_DIRECTORIES(${PROJECT_SOURCE_DIR}/src/Events ${PROJECT_SOURCE_DIR}/src/XAO ${PROJECT_SOURCE_DIR}/src/ConstructionPlugin ${PROJECT_SOURCE_DIR}/src/PartSetPlugin + ${OpenCASCADE_INCLUDE_DIR} ) SET(PROJECT_HEADERS diff --git a/src/ExchangePlugin/ExchangePlugin_ExportFeature.cpp b/src/ExchangePlugin/ExchangePlugin_ExportFeature.cpp index d898a08e5..6a8f36cb1 100644 --- a/src/ExchangePlugin/ExchangePlugin_ExportFeature.cpp +++ b/src/ExchangePlugin/ExchangePlugin_ExportFeature.cpp @@ -27,6 +27,7 @@ #include #endif + #include #include @@ -34,6 +35,7 @@ #include #include #include +#include #include #include @@ -48,6 +50,7 @@ #include #include #include +#include #include #include #include @@ -68,6 +71,8 @@ #include +#include + ExchangePlugin_ExportFeature::ExchangePlugin_ExportFeature() { } @@ -98,9 +103,27 @@ void ExchangePlugin_ExportFeature::initAttributes() ModelAPI_AttributeString::typeId()); data()->addAttribute(ExchangePlugin_ExportFeature::XAO_SELECTION_LIST_ID(), ModelAPI_AttributeSelectionList::typeId()); + data()->addAttribute(ExchangePlugin_ExportFeature::STL_FILE_PATH_ID(), + ModelAPI_AttributeString::typeId()); + data()->addAttribute(ExchangePlugin_ExportFeature::STL_OBJECT_SELECTED(), + ModelAPI_AttributeSelection::typeId()); + data()->addAttribute(ExchangePlugin_ExportFeature::STL_DEFLECTION_TYPE(), + ModelAPI_AttributeString::typeId()); + data()->addAttribute(ExchangePlugin_ExportFeature::STL_RELATIVE(), + ModelAPI_AttributeDouble::typeId()); + + double defelection = Config_PropManager::real("Visualization", "body_deflection"); + real(ExchangePlugin_ExportFeature::STL_RELATIVE())->setValue(defelection); + + data()->addAttribute(ExchangePlugin_ExportFeature::STL_ABSOLUTE(), + ModelAPI_AttributeDouble::typeId()); + data()->addAttribute(ExchangePlugin_ExportFeature::STL_FILE_TYPE(), + ModelAPI_AttributeString::typeId()); ModelAPI_Session::get()->validators()->registerNotObligatory(getKind(), ExchangePlugin_ExportFeature::XAO_FILE_PATH_ID()); + ModelAPI_Session::get()->validators()->registerNotObligatory(getKind(), + ExchangePlugin_ExportFeature::STL_FILE_PATH_ID()); ModelAPI_Session::get()->validators()->registerNotObligatory(getKind(), ExchangePlugin_ExportFeature::XAO_AUTHOR_ID()); ModelAPI_Session::get()->validators()->registerNotObligatory(getKind(), @@ -128,6 +151,11 @@ void ExchangePlugin_ExportFeature::attributeChanged(const std::string& theID) string(ExchangePlugin_ExportFeature::FILE_PATH_ID())->setValue( string(ExchangePlugin_ExportFeature::XAO_FILE_PATH_ID())->value()); } + else if (theID == STL_FILE_PATH_ID()) { + string(ExchangePlugin_ExportFeature::FILE_PATH_ID())->setValue( + string(ExchangePlugin_ExportFeature::STL_FILE_PATH_ID())->value()); + } + } /* @@ -170,6 +198,9 @@ void ExchangePlugin_ExportFeature::exportFile(const std::string& theFileName, if (aFormatName == "XAO") { exportXAO(theFileName); return; + }else if (aFormatName == "STL") { + exportSTL(theFileName); + return; } // make shape for export from selected shapes @@ -316,6 +347,49 @@ static bool isInResults(AttributeSelectionListPtr theSelection, return false; } +void ExchangePlugin_ExportFeature::exportSTL(const std::string& theFileName) +{ + // Get shape. + AttributeSelectionPtr aSelection = selection(STL_OBJECT_SELECTED()); + GeomShapePtr aShape = aSelection->value(); + if (!aShape.get()) { + aShape = aSelection->context()->shape(); + } + + // Get relative value and percent flag. + double aValue; + bool anIsRelative = false; + bool anIsASCII = false; + + if (string(STL_DEFLECTION_TYPE())->value() == STL_DEFLECTION_TYPE_RELATIVE()) { + aValue = real(STL_RELATIVE())->value(); + anIsRelative = true; + } else { + aValue = real(STL_ABSOLUTE())->value(); + } + + if (string(STL_FILE_TYPE())->value() == STL_FILE_TYPE_ASCII()) { + anIsASCII = true; + } + // Perform the export + std::string anError; + bool aResult = false; + + aResult = STLExport(theFileName, + "STL", + aShape, + aValue, + anIsRelative, + anIsASCII, + anError); + + if (!aResult || !anError.empty()) { + setError("An error occurred while exporting " + theFileName + ": " + anError); + return; + } +} + + void ExchangePlugin_ExportFeature::exportXAO(const std::string& theFileName) { try { diff --git a/src/ExchangePlugin/ExchangePlugin_ExportFeature.h b/src/ExchangePlugin/ExchangePlugin_ExportFeature.h index 1067d99af..bc975ea5b 100644 --- a/src/ExchangePlugin/ExchangePlugin_ExportFeature.h +++ b/src/ExchangePlugin/ExchangePlugin_ExportFeature.h @@ -60,6 +60,66 @@ public: static const std::string MY_XAO_FILE_PATH_ID("xao_file_path"); return MY_XAO_FILE_PATH_ID; } + /// attribute name of stl file path + inline static const std::string& STL_FILE_PATH_ID() + { + static const std::string MY_STL_FILE_PATH_ID("stl_file_path"); + return MY_STL_FILE_PATH_ID; + } + /// Attribute name for selected object to export in stl file path. + inline static const std::string& STL_OBJECT_SELECTED() + { + static const std::string ATTR_ID("stl_object_selected"); + return ATTR_ID; + } + /// Attribute name for deflection type. + inline static const std::string& STL_DEFLECTION_TYPE() + { + static const std::string ATTR_ID("stl_deflection_type"); + return ATTR_ID; + } + /// Attribute name for deflection type relative. + inline static const std::string& STL_DEFLECTION_TYPE_RELATIVE() + { + static const std::string ATTR_ID("stl_deflection_type_relative"); + return ATTR_ID; + } + /// Attribute name for deflection type absolute. + inline static const std::string& STL_DEFLECTION_TYPE_ABSOLUTE() + { + static const std::string ATTR_ID("stl_deflection_type_absolute"); + return ATTR_ID; + } + /// Attribute name for relative. + inline static const std::string& STL_RELATIVE() + { + static const std::string ATTR_ID("stl_relative"); + return ATTR_ID; + } + /// Attribute name for absolute. + inline static const std::string& STL_ABSOLUTE() + { + static const std::string ATTR_ID("stl_absolute"); + return ATTR_ID; + } + /// Attribute name for stl file type. + inline static const std::string& STL_FILE_TYPE() + { + static const std::string ATTR_ID("stl_file_type"); + return ATTR_ID; + } + /// Attribute name for stl file type ascii. + inline static const std::string& STL_FILE_TYPE_ASCII() + { + static const std::string ATTR_ID("stl_file_type_acii"); + return ATTR_ID; + } + /// Attribute name for stl file type binary. + inline static const std::string& STL_FILE_TYPE_BINARY() + { + static const std::string ATTR_ID("stl_file_type_binary"); + return ATTR_ID; + } /// attribute name of file format inline static const std::string& FILE_FORMAT_ID() { @@ -129,6 +189,9 @@ protected: /// Performs export to XAO file EXCHANGEPLUGIN_EXPORT void exportXAO(const std::string& theFileName); + + /// Performs export to STL file + EXCHANGEPLUGIN_EXPORT void exportSTL(const std::string& theFileName); }; #endif /* EXPORT_EXPORTFEATURE_H_ */ diff --git a/src/ExchangePlugin/ExchangePlugin_Import.cpp b/src/ExchangePlugin/ExchangePlugin_Import.cpp index b5a51ff08..304d456d5 100644 --- a/src/ExchangePlugin/ExchangePlugin_Import.cpp +++ b/src/ExchangePlugin/ExchangePlugin_Import.cpp @@ -27,6 +27,7 @@ #include #include #include +#include #include #include #include @@ -81,8 +82,15 @@ ExchangePlugin_Import::~ExchangePlugin_Import() void ExchangePlugin_Import::initAttributes() { data()->addAttribute(FILE_PATH_ID(), ModelAPI_AttributeString::typeId()); + data()->addAttribute(STEP_FILE_PATH_ID(), ModelAPI_AttributeString::typeId()); + data()->addAttribute(IMPORT_TYPE_ID(), ModelAPI_AttributeString::typeId()); data()->addAttribute(TARGET_PART_ID(), ModelAPI_AttributeInteger::typeId()); data()->addAttribute(TARGET_PARTS_LIST_ID(), ModelAPI_AttributeStringArray::typeId()); + data()->addAttribute(STEP_TARGET_PART_ID(), ModelAPI_AttributeInteger::typeId()); + data()->addAttribute(STEP_TARGET_PARTS_LIST_ID(), ModelAPI_AttributeStringArray::typeId()); + data()->addAttribute(STEP_MATERIALS_ID(), ModelAPI_AttributeBoolean::typeId()); + data()->addAttribute(STEP_COLORS_ID(), ModelAPI_AttributeBoolean::typeId()); + data()->addAttribute(STEP_SCALE_INTER_UNITS_ID(), ModelAPI_AttributeBoolean::typeId()); } /* @@ -90,26 +98,61 @@ void ExchangePlugin_Import::initAttributes() */ void ExchangePlugin_Import::execute() { - AttributeStringPtr aFilePathAttr = string(ExchangePlugin_Import::FILE_PATH_ID()); - std::string aFilePath = aFilePathAttr->value(); - if (aFilePath.empty()) { - setError("File path is empty."); - return; + AttributeStringPtr aFormatAttr = + this->string(ExchangePlugin_Import::IMPORT_TYPE_ID()); + std::string aFormat = aFormatAttr->value(); + + AttributeStringPtr aFilePathAttr; + std::string aFilePath; + AttributeStringArrayPtr aPartsAttr; + AttributeIntegerPtr aTargetAttr; + if (aFormat == "STEP" || aFormat == "STP") + { + aFilePathAttr = string(ExchangePlugin_Import::STEP_FILE_PATH_ID()); + aFilePath = aFilePathAttr->value(); + // get the document where to import + aPartsAttr = stringArray(STEP_TARGET_PARTS_LIST_ID()); + aTargetAttr = integer(STEP_TARGET_PART_ID()); + }else{ + aFilePathAttr = string(ExchangePlugin_Import::FILE_PATH_ID()); + aFilePath = aFilePathAttr->value(); + // get the document where to import + aPartsAttr = stringArray(TARGET_PARTS_LIST_ID()); + aTargetAttr = integer(TARGET_PART_ID()); } - // get the document where to import - AttributeStringArrayPtr aPartsAttr = stringArray(TARGET_PARTS_LIST_ID()); - AttributeIntegerPtr aTargetAttr = integer(TARGET_PART_ID()); + if (aFilePath.empty()) { + setError("File path is empty."); + return; + } SessionPtr aSession = ModelAPI_Session::get(); - DocumentPtr aDoc = - findDocument(aSession->moduleDocument(), + DocumentPtr aDoc = findDocument(aSession->moduleDocument(), Locale::Convert::toWString(aPartsAttr->value(aTargetAttr->value()))); if (aDoc.get()) { FeaturePtr aImportFeature = aDoc->addFeature(ExchangePlugin_ImportFeature::ID()); DataPtr aData = aImportFeature->data(); - AttributeStringPtr aPathAttr = aData->string(ExchangePlugin_ImportFeature::FILE_PATH_ID()); + AttributeStringPtr aPathAttr; + if (aFormat == "STEP" || aFormat == "STP") + { + aPathAttr = aData->string(ExchangePlugin_ImportFeature::STEP_FILE_PATH_ID()); + }else + { + aPathAttr = aData->string(ExchangePlugin_ImportFeature::FILE_PATH_ID()); + } + + AttributeStringPtr aImportTypeAttr = aData->string(ExchangePlugin_ImportFeature::IMPORT_TYPE_ID()); + + aData->boolean(ExchangePlugin_ImportFeature::STEP_MATERIALS_ID()) + ->setValue(boolean(ExchangePlugin_Import::STEP_MATERIALS_ID())->value()); + aData->boolean(ExchangePlugin_ImportFeature::STEP_COLORS_ID()) + ->setValue(boolean(ExchangePlugin_Import::STEP_COLORS_ID())->value()); + aData->boolean(ExchangePlugin_ImportFeature::STEP_SCALE_INTER_UNITS_ID()) + ->setValue(boolean(ExchangePlugin_Import::STEP_SCALE_INTER_UNITS_ID())->value()); + aPathAttr->setValue(aFilePathAttr->value()); + aImportTypeAttr->setValue(aFormat); + aImportFeature->execute(); } } @@ -117,14 +160,31 @@ void ExchangePlugin_Import::execute() void ExchangePlugin_Import::attributeChanged(const std::string& theID) { - if (theID == FILE_PATH_ID()) { - AttributeStringPtr aFilePathAttr = string(FILE_PATH_ID()); - if (aFilePathAttr->value().empty()) + AttributeStringPtr aFilePathAttr; + AttributeStringArrayPtr aPartsAttr; + AttributeIntegerPtr aTargetAttr; + + if (theID == FILE_PATH_ID() ||theID == STEP_FILE_PATH_ID() ) { + aFilePathAttr = string(FILE_PATH_ID()); + if (theID == FILE_PATH_ID() && aFilePathAttr->value().empty()) return; + aPartsAttr = stringArray(TARGET_PARTS_LIST_ID()); + aTargetAttr = integer(TARGET_PART_ID()); + + updatePart(aPartsAttr, aTargetAttr); - AttributeStringArrayPtr aPartsAttr = stringArray(TARGET_PARTS_LIST_ID()); - AttributeIntegerPtr aTargetAttr = integer(TARGET_PART_ID()); + aFilePathAttr = string(STEP_FILE_PATH_ID()); + if (theID == STEP_FILE_PATH_ID() && aFilePathAttr->value().empty()) + return; + aPartsAttr = stringArray(STEP_TARGET_PARTS_LIST_ID()); + aTargetAttr = integer(STEP_TARGET_PART_ID()); + updatePart(aPartsAttr, aTargetAttr); + } +} + +void ExchangePlugin_Import::updatePart(AttributeStringArrayPtr &aPartsAttr, AttributeIntegerPtr &aTargetAttr) +{ // update the list of target parts SessionPtr aSession = ModelAPI_Session::get(); DocumentPtr aDoc = document(); @@ -159,5 +219,4 @@ void ExchangePlugin_Import::attributeChanged(const std::string& theID) aTargetAttr->setValue(0); } } - } } diff --git a/src/ExchangePlugin/ExchangePlugin_Import.h b/src/ExchangePlugin/ExchangePlugin_Import.h index c09b3ebab..38d3e05e7 100644 --- a/src/ExchangePlugin/ExchangePlugin_Import.h +++ b/src/ExchangePlugin/ExchangePlugin_Import.h @@ -24,6 +24,8 @@ #include #include +#include +#include #include @@ -43,6 +45,12 @@ class ExchangePlugin_Import : public ModelAPI_Feature static const std::string MY_IMPORT_ID("ImportMacro"); return MY_IMPORT_ID; } + /// Feature kind + inline static const std::string& IMPORT_TYPE_ID() + { + static const std::string MY_IMPORT_TYPE_ID("ImportType"); + return MY_IMPORT_TYPE_ID; + } /// attribute name of file path inline static const std::string& FILE_PATH_ID() { @@ -61,6 +69,42 @@ class ExchangePlugin_Import : public ModelAPI_Feature static const std::string MY_TARGET_PARTS_LIST_ID("target_parts_list"); return MY_TARGET_PARTS_LIST_ID; } + /// attribute name of step file path + inline static const std::string& STEP_FILE_PATH_ID() + { + static const std::string MY_STEP_FILE_PATH_ID("step_file_path"); + return MY_STEP_FILE_PATH_ID; + } + /// attribute name of step target part + inline static const std::string& STEP_TARGET_PART_ID() + { + static const std::string MY_STEP_TARGET_PART_ID("step_target_part"); + return MY_STEP_TARGET_PART_ID; + } + /// attribute name of list ofstep target parts + inline static const std::string& STEP_TARGET_PARTS_LIST_ID() + { + static const std::string MY_STEP_TARGET_PARTS_LIST_ID("step_target_parts_list"); + return MY_STEP_TARGET_PARTS_LIST_ID; + } + /// attribute name of step Scale to International System Units + inline static const std::string& STEP_SCALE_INTER_UNITS_ID() + { + static const std::string MY_STEP_SCALE_INTER_UNITS_ID("step_scale_inter_units"); + return MY_STEP_SCALE_INTER_UNITS_ID; + } + /// attribute name of step materiels + inline static const std::string& STEP_MATERIALS_ID() + { + static const std::string MY_STEP_MATERIALS_ID("step_materials"); + return MY_STEP_MATERIALS_ID; + } + /// attribute name of step colors + inline static const std::string& STEP_COLORS_ID() + { + static const std::string MY_STEP_COLORS_ID("step_colours"); + return MY_STEP_COLORS_ID; + } /// Default constructor EXCHANGEPLUGIN_EXPORT ExchangePlugin_Import(); /// Default destructor @@ -79,6 +123,9 @@ class ExchangePlugin_Import : public ModelAPI_Feature /// \param theID identifier of changed attribute EXCHANGEPLUGIN_EXPORT virtual void attributeChanged(const std::string& theID); + EXCHANGEPLUGIN_EXPORT + void updatePart(AttributeStringArrayPtr &aPartsAttr, AttributeIntegerPtr &aTargetAttr); + /// Computes or recomputes the results EXCHANGEPLUGIN_EXPORT virtual void execute(); diff --git a/src/ExchangePlugin/ExchangePlugin_ImportFeature.cpp b/src/ExchangePlugin/ExchangePlugin_ImportFeature.cpp index ade0a3115..402b660e9 100644 --- a/src/ExchangePlugin/ExchangePlugin_ImportFeature.cpp +++ b/src/ExchangePlugin/ExchangePlugin_ImportFeature.cpp @@ -32,6 +32,7 @@ #include #include +#include #include #include @@ -42,6 +43,8 @@ #include #include #include +#include +#include #include #include #include @@ -60,6 +63,10 @@ #include +#include +#include + + ExchangePlugin_ImportFeature::ExchangePlugin_ImportFeature() { } @@ -77,10 +84,16 @@ void ExchangePlugin_ImportFeature::initAttributes() data()->addAttribute(ExchangePlugin_ImportFeature::FILE_PATH_ID(), ModelAPI_AttributeString::typeId()); AttributePtr aFeaturesAttribute = - data()->addAttribute(ExchangePlugin_ImportFeature::FEATURES_ID(), + data()->addAttribute(ExchangePlugin_ImportFeature::FEATURES_ID(), ModelAPI_AttributeRefList::typeId()); - aFeaturesAttribute->setIsArgument(false); + data()->addAttribute(STEP_FILE_PATH_ID(), ModelAPI_AttributeString::typeId()); + data()->addAttribute(IMPORT_TYPE_ID(), ModelAPI_AttributeString::typeId()); + data()->addAttribute(STEP_MATERIALS_ID(), ModelAPI_AttributeBoolean::typeId()); + data()->addAttribute(STEP_COLORS_ID(), ModelAPI_AttributeBoolean::typeId()); + data()->addAttribute(STEP_SCALE_INTER_UNITS_ID(), ModelAPI_AttributeBoolean::typeId()); + aFeaturesAttribute->setIsArgument(false); + ModelAPI_Session::get()->validators()->registerNotObligatory( getKind(), ExchangePlugin_ImportFeature::FEATURES_ID()); } @@ -90,7 +103,15 @@ void ExchangePlugin_ImportFeature::initAttributes() */ void ExchangePlugin_ImportFeature::execute() { - AttributeStringPtr aFilePathAttr = string(ExchangePlugin_ImportFeature::FILE_PATH_ID()); + AttributeStringPtr aImportTypeAttr = string(ExchangePlugin_ImportFeature::IMPORT_TYPE_ID()); + std::string aFormat = aImportTypeAttr->value(); + AttributeStringPtr aFilePathAttr; + if (aFormat == "STEP" || aFormat == "STP") + { + aFilePathAttr = string(ExchangePlugin_ImportFeature::STEP_FILE_PATH_ID()); + }else{ + aFilePathAttr = string(ExchangePlugin_ImportFeature::FILE_PATH_ID()); + } std::string aFilePath = aFilePathAttr->value(); if (aFilePath.empty()) { setError("File path is empty."); @@ -101,7 +122,7 @@ void ExchangePlugin_ImportFeature::execute() } std::shared_ptr ExchangePlugin_ImportFeature::createResultBody( - std::shared_ptr aGeomShape) + std::shared_ptr aGeomShape) { std::shared_ptr aResultBody = document()->createBody(data()); //LoadNamingDS of the imported shape @@ -122,10 +143,47 @@ void ExchangePlugin_ImportFeature::importFile(const std::string& theFileName) // Perform the import std::string anError; std::shared_ptr aGeomShape; + + std::map< std::wstring, std::list> theMaterialShape; + + std::string anObjectName = GeomAlgoAPI_Tools::File_Tools::name(theFileName); + data()->setName(Locale::Convert::toWString(anObjectName)); + + ResultBodyPtr result = document()->createBody(data()); + + bool anColorGroupSelected = boolean(ExchangePlugin_ImportFeature::STEP_COLORS_ID())->value(); + bool anMaterialsGroupSelected = boolean(ExchangePlugin_ImportFeature::STEP_MATERIALS_ID())->value(); + if (anExtension == "BREP" || anExtension == "BRP") { aGeomShape = BREPImport(theFileName, anExtension, anError); } else if (anExtension == "STEP" || anExtension == "STP") { - aGeomShape = STEPImport(theFileName, anExtension, anError); + bool anScalInterUnits = boolean(ExchangePlugin_ImportFeature::STEP_SCALE_INTER_UNITS_ID())->value(); + + + try{ + + result->clearShapeNameAndColor(); + // Process groups/fields + std::shared_ptr aRefListOfGroups = + std::dynamic_pointer_cast(data()->attribute(FEATURES_ID())); + + // Remove previous groups/fields stored in RefList + std::list anGroupList = aRefListOfGroups->list(); + std::list::iterator anGroupIt = anGroupList.begin(); + for (; anGroupIt != anGroupList.end(); ++anGroupIt) { + std::shared_ptr aFeature = ModelAPI_Feature::feature(*anGroupIt); + if (aFeature) + document()->removeFeature(aFeature); + } + + aGeomShape = STEPImportAttributs(theFileName, result, anScalInterUnits, + anMaterialsGroupSelected, anColorGroupSelected,theMaterialShape,anError); + + } + catch (OSD_Exception& e) { + //Try to load STEP file without colors... + aGeomShape = STEPImport(theFileName, anExtension,anScalInterUnits,anError); + } } else if (anExtension == "IGES" || anExtension == "IGS") { aGeomShape = IGESImport(theFileName, anExtension, anError); } else { @@ -139,12 +197,138 @@ void ExchangePlugin_ImportFeature::importFile(const std::string& theFileName) } // Pass the results into the model - std::string anObjectName = GeomAlgoAPI_Tools::File_Tools::name(theFileName); - data()->setName(Locale::Convert::toWString(anObjectName)); - setResult(createResultBody(aGeomShape)); + loadNamingDS(aGeomShape, result); + + // create color group + if (anColorGroupSelected) + { + setColorGroups(result); + } + + // create Materiel group + if (anMaterialsGroupSelected){ + setMaterielGroup(result,theMaterialShape); + } + + setResult(result); + } +void ExchangePlugin_ImportFeature::setColorGroups(std::shared_ptr theResultBody) +{ + std::vector aColor; + int indice = 1; + std::list< std::vector > aColorsRead; + + + ModelAPI_Tools::getColor(theResultBody, aColor); + if (!aColor.empty() ){ + std::wstringstream colorName; + colorName< allRes; + ModelAPI_Tools::allSubs(theResultBody, allRes); + for(std::list::iterator aRes = allRes.begin(); aRes != allRes.end(); ++aRes) { + ModelAPI_Tools::getColor(*aRes, aColor); + if (!aColor.empty() ){ + auto it = std::find(aColorsRead.begin(), aColorsRead.end(), aColor); + if ( it == aColorsRead.end() ){ + std::wstringstream colorName; + colorName< theResultBody, + std::vector &theColor, + const std::wstring& theName ) +{ + std::vector aColor; + std::shared_ptr aGroupFeature = addFeature("Group"); + + // group name + aGroupFeature->data()->setName(theName); + + // fill selection + AttributeSelectionListPtr aSelectionList = aGroupFeature->selectionList("group_list"); + + ModelAPI_Tools::getColor(theResultBody, aColor); + if (!aColor.empty() ){ + if( aColor == theColor ) { + GeomShapePtr aShape = theResultBody->shape(); + aSelectionList->setSelectionType(aShape->shapeTypeStr() ); + aSelectionList->append(theResultBody,aShape); + } + } + // add element with the same color + std::list allRes; + ModelAPI_Tools::allSubs(theResultBody, allRes); + for(std::list::iterator aRes = allRes.begin(); + aRes != allRes.end(); ++aRes) { + ModelAPI_Tools::getColor(*aRes, aColor); + GeomShapePtr aShape = (*aRes)->shape(); + + if (!aColor.empty() ){ + if( aRes->get() && aColor == theColor ) { + aSelectionList->setSelectionType(aShape->shapeTypeStr() ); + aSelectionList->append(theResultBody,aShape); + } + } + } + + if (aSelectionList->size() == 0 ){ + document()->removeFeature(aGroupFeature); + } +} + +void ExchangePlugin_ImportFeature::setMaterielGroup(std::shared_ptr theResultBody, + std::map< std::wstring, std::list> &theMaterialShape) +{ + int indice = 1; + std::map< std::wstring, std::list>::iterator it; + for( it = theMaterialShape.begin(); it != theMaterialShape.end(); ++it) { + + std::shared_ptr aGroupFeature = addFeature("Group"); + // group name + aGroupFeature->data()->setName((*it).first); + + // fill selection + AttributeSelectionListPtr aSelectionList = aGroupFeature->selectionList("group_list"); + std::string aSelectionType = "solid" ; + aSelectionList->setSelectionType(aSelectionType); + GeomShapePtr aShape = theResultBody->shape(); + + std::list allRes; + ModelAPI_Tools::allSubs(theResultBody, allRes); + for(std::list::iterator aRes = allRes.begin(); aRes != allRes.end(); ++aRes) { + + GeomShapePtr aShape = (*aRes)->shape(); + for(std::list::iterator aResMat = it->second.begin(); + aResMat != it->second.end(); ++aResMat) { + if( aRes->get() && ((*aRes)->data()->name() == (*aResMat))) + { + aSelectionList->append(theResultBody,aShape); + break; + } + } + } + if (aSelectionList->size() == 0){ + document()->removeFeature(aGroupFeature); + } + } +} + + + void ExchangePlugin_ImportFeature::importXAO(const std::string& theFileName) { try { @@ -415,7 +599,6 @@ void ExchangePlugin_ImportFeature::loadNamingDS( { //load result theResultBody->store(theGeomShape); - std::string aNameMS = "Shape"; theResultBody->loadFirstLevel(theGeomShape, aNameMS); } diff --git a/src/ExchangePlugin/ExchangePlugin_ImportFeature.h b/src/ExchangePlugin/ExchangePlugin_ImportFeature.h index c087af2ab..2875d83ab 100644 --- a/src/ExchangePlugin/ExchangePlugin_ImportFeature.h +++ b/src/ExchangePlugin/ExchangePlugin_ImportFeature.h @@ -24,6 +24,7 @@ #include #include +#include #include @@ -43,18 +44,48 @@ class ExchangePlugin_ImportFeature : public ModelAPI_CompositeFeature static const std::string MY_IMPORT_ID("Import"); return MY_IMPORT_ID; } + /// Feature kind + inline static const std::string& IMPORT_TYPE_ID() + { + static const std::string MY_IMPORT_TYPE_ID("ImportType"); + return MY_IMPORT_TYPE_ID; + } /// attribute name of file path inline static const std::string& FILE_PATH_ID() { static const std::string MY_FILE_PATH_ID("file_path"); return MY_FILE_PATH_ID; } + /// attribute name of file path + inline static const std::string& STEP_FILE_PATH_ID() + { + static const std::string MY_STEP_FILE_PATH_ID("step_file_path"); + return MY_STEP_FILE_PATH_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; } + /// attribute name of step Scale to International System Units + inline static const std::string& STEP_SCALE_INTER_UNITS_ID() + { + static const std::string MY_STEP_SCALE_INTER_UNITS_ID("step_scale_inter_units"); + return MY_STEP_SCALE_INTER_UNITS_ID; + } + /// attribute name of step materiels + inline static const std::string& STEP_MATERIALS_ID() + { + static const std::string MY_STEP_MATERIALS_ID("step_materials"); + return MY_STEP_MATERIALS_ID; + } + /// attribute name of step colors + inline static const std::string& STEP_COLORS_ID() + { + static const std::string MY_STEP_COLORS_ID("step_colours"); + return MY_STEP_COLORS_ID; + } /// Default constructor EXCHANGEPLUGIN_EXPORT ExchangePlugin_ImportFeature(); /// Default destructor @@ -108,6 +139,19 @@ private: /// Loads Naming data structure to the document void loadNamingDS(std::shared_ptr theGeomShape, std::shared_ptr theResultBody); + + // Set groups of color + void setColorGroups(std::shared_ptr theResultBody); + + // set a group of color + void setColorGroup(std::shared_ptr theResultBody, + std::vector &aColor, + const std::wstring& theName ); + + // set Materiel group of color + void setMaterielGroup(std::shared_ptr theResultBody, + std::map< std::wstring, std::list> &theMaterialShape); + }; #endif /* IMPORT_IMPORTFEATURE_H_ */ diff --git a/src/ExchangePlugin/ExchangePlugin_msg_fr.ts b/src/ExchangePlugin/ExchangePlugin_msg_fr.ts index 3e4061b1e..110053a1d 100644 --- a/src/ExchangePlugin/ExchangePlugin_msg_fr.ts +++ b/src/ExchangePlugin/ExchangePlugin_msg_fr.ts @@ -134,6 +134,10 @@ XAO XAO + + STL + STL + Export:file_path @@ -193,6 +197,81 @@ Veuillez saisir le nom de la géométrie + + Export:stl_file_path + + Export file + Fichier d'export + + + + Export:stl_file_path:ExchangePlugin_ExportFormat + + %1 is not initialized. + %1 n'est pas initialisé. + + + File name is empty. + Le nom du fichier est vide. + + + + Export:stl_object_selected + + Object + Objet + + + Object to export. + Objet à exporter. + + + + Export:stl_file_type + + File type + type du fichier + + + Binary + Binaire + + + ASCII + ASCII + + + + Export:Deflection + + Deflection + Déflection + + + Relative + Relative + + + Relative value. + Valeur relative + + + Calculate by size of shape + Calcul par rapport à la taille de la shape + + + Absolute + Absolue + + + Value indicate by user + Valeur indiquée par l'utilisateur + + + Absolute value. + Valeur absolue. + + diff --git a/src/ExchangePlugin/export_widget.xml b/src/ExchangePlugin/export_widget.xml index 9e134b805..d77786ee5 100644 --- a/src/ExchangePlugin/export_widget.xml +++ b/src/ExchangePlugin/export_widget.xml @@ -31,5 +31,63 @@ placeholder="Please input the geometry name"> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/ExchangePlugin/plugin-Exchange.xml b/src/ExchangePlugin/plugin-Exchange.xml index 7f240ba69..275ceb69b 100644 --- a/src/ExchangePlugin/plugin-Exchange.xml +++ b/src/ExchangePlugin/plugin-Exchange.xml @@ -4,19 +4,70 @@ - - - + + + + + + + + + + + + + + + + + + + + - + + + + + + + + + + + + + + + + + + + + diff --git a/src/FeaturesAPI/FeaturesAPI.i b/src/FeaturesAPI/FeaturesAPI.i index b76fd2dc4..c5c0c28de 100644 --- a/src/FeaturesAPI/FeaturesAPI.i +++ b/src/FeaturesAPI/FeaturesAPI.i @@ -42,6 +42,8 @@ %feature("kwargs") addCommon; %feature("kwargs") addCut; %feature("kwargs") addFillet; +%feature("kwargs") addFilletMultiRadiusBypoint; +%feature("kwargs") addFilletMultiRadiusByCurv; %feature("kwargs") addFuse; %feature("kwargs") addIntersection; %feature("kwargs") addMultiRotation; diff --git a/src/FeaturesAPI/FeaturesAPI_Fillet.cpp b/src/FeaturesAPI/FeaturesAPI_Fillet.cpp index 332b58208..0f2f5041c 100644 --- a/src/FeaturesAPI/FeaturesAPI_Fillet.cpp +++ b/src/FeaturesAPI/FeaturesAPI_Fillet.cpp @@ -152,6 +152,41 @@ FeaturesAPI_Fillet2D::FeaturesAPI_Fillet2D(const std::shared_ptr& theFeature, + const ModelHighAPI_Selection & theedgeselected, + const std::list& thepoint, + const std::list& theRadius) + : FeaturesAPI_Fillet(theFeature) +{ + if (initialize()) { + fillAttribute(FeaturesPlugin_Fillet::CREATION_METHOD_MULTIPLES_RADIUSES(), mycreationMethod); + fillAttribute(FeaturesPlugin_Fillet::CREATION_METHOD_BY_POINTS(), mycreationMethodmulti); + fillAttribute(theedgeselected, edgeselected()); + fillAttribute(thepoint, myarraypointradiusbypoint); + // JL_CGLB fillAttribute(theRadius, myarrayradiusbypoint); + + execIfBaseNotEmpty(); + } +} + +FeaturesAPI_Fillet2D::FeaturesAPI_Fillet2D(const std::shared_ptr& theFeature, + const ModelHighAPI_Selection & theedgeselected, + const std::list& thepointCurvCood, + const std::list& theRadius) + : FeaturesAPI_Fillet(theFeature) +{ + if (initialize()) { + fillAttribute(FeaturesPlugin_Fillet::CREATION_METHOD_MULTIPLES_RADIUSES(), mycreationMethod); + fillAttribute(FeaturesPlugin_Fillet::CREATION_METHOD_BY_CURVILEAR_ABSCISSA(), mycreationMethodmulti); + fillAttribute(theedgeselected, edgeselected()); + // JL_CGLB fillAttribute(thepointCurvCood, myarraypointradiusbycurv); + // JL_CGLB fillAttribute(theRadius, myarrayradiusbycurv); + + execIfBaseNotEmpty(); + } +} + FeaturesAPI_Fillet2D::~FeaturesAPI_Fillet2D() { } @@ -189,18 +224,44 @@ void FeaturesAPI_Fillet2D::dump(ModelHighAPI_Dumper& theDumper) const AttributeSelectionListPtr anAttrObjects = aBase->selectionList(FeaturesPlugin_Fillet::OBJECT_LIST_ID()); - - theDumper << aBase << " = model.addFillet(" << aDocName << ", " << anAttrObjects; - - std::string aCreationMethod = aBase->string(FeaturesPlugin_Fillet::CREATION_METHOD())->value(); - - if(aCreationMethod == FeaturesPlugin_Fillet::CREATION_METHOD_SINGLE_RADIUS()) { - AttributeDoublePtr anAttrRadius = aBase->real(FeaturesPlugin_Fillet::RADIUS_ID()); - theDumper << ", " << anAttrRadius; - } else if(aCreationMethod == FeaturesPlugin_Fillet::CREATION_METHOD_VARYING_RADIUS()) { - AttributeDoublePtr anAttrRadius1 = aBase->real(FeaturesPlugin_Fillet::START_RADIUS_ID()); - AttributeDoublePtr anAttrRadius2 = aBase->real(FeaturesPlugin_Fillet::END_RADIUS_ID()); - theDumper << ", " << anAttrRadius1 << ", " << anAttrRadius2; + + + if ( aBase->string(FeaturesPlugin_Fillet::CREATION_METHOD())->value() + == FeaturesPlugin_Fillet::CREATION_METHOD_MULTIPLES_RADIUSES() ) + { + AttributeSelectionPtr anAttrEdgeSelec = + aBase->selection(FeaturesPlugin_Fillet::EDGE_SELECTED_ID()); + + if( aBase->string(FeaturesPlugin_Fillet::CREATION_METHOD_MULTIPLES_RADIUSES())->value() + == FeaturesPlugin_Fillet::CREATION_METHOD_BY_POINTS() ) + { + /*AttributeSelectionListPtr anAttrPoint = + aBase->selectionList(FeaturesPlugin_Fillet::ARRAY_POINT_RADIUS_BY_POINTS()); + AttributeDoubleArrayPtr anAttrRadius = + aBase->realArray(FeaturesPlugin_Fillet::ARRAY_RADIUS_BY_POINTS()); + theDumper << aBase << " = model.addFilletMultiRadiusBypoint(" << aDocName << ", " << anAttrEdgeSelec; + theDumper << ", " << anAttrPoint << ", " << anAttrRadius; + }else{ + AttributeSelectionListPtr anAttrPoint = + aBase->selectionList(FeaturesPlugin_Fillet::ARRAY_POINT_RADIUS_BY_CURV()); + AttributeDoubleArrayPtr anAttrRadius = + aBase->realArray(FeaturesPlugin_Fillet::ARRAY_RADIUS_BY_CURV()); + theDumper << aBase << " = model.addFilletMultiRadiusByCurv(" << aDocName << ", " << anAttrEdgeSelec; + theDumper << ", " << anAttrPoint << ", " << anAttrRadius;*/ + } + }else + { theDumper << aBase << " = model.addFillet(" << aDocName << ", " << anAttrObjects; + + std::string aCreationMethod = aBase->string(FeaturesPlugin_Fillet::CREATION_METHOD())->value(); + + if(aCreationMethod == FeaturesPlugin_Fillet::CREATION_METHOD_SINGLE_RADIUS()) { + AttributeDoublePtr anAttrRadius = aBase->real(FeaturesPlugin_Fillet::RADIUS_ID()); + theDumper << ", " << anAttrRadius; + } else if(aCreationMethod == FeaturesPlugin_Fillet::CREATION_METHOD_VARYING_RADIUS()) { + AttributeDoublePtr anAttrRadius1 = aBase->real(FeaturesPlugin_Fillet::START_RADIUS_ID()); + AttributeDoublePtr anAttrRadius2 = aBase->real(FeaturesPlugin_Fillet::END_RADIUS_ID()); + theDumper << ", " << anAttrRadius1 << ", " << anAttrRadius2; + } } if (!aBase->data()->version().empty()) @@ -241,3 +302,39 @@ FilletPtr addFillet(const std::shared_ptr& thePart, aFillet.reset(new FeaturesAPI_Fillet2D(aFeature, theBaseObjects, theRadius1, theRadius2)); return aFillet; } + +FilletPtr addFilletMultiRadiusBypoint(const std::shared_ptr& thePart, + const ModelHighAPI_Selection & theedgeselected, + const std::list& thepoint, + const std::list& theRadius, + const bool keepSubResults) +{ + + FeaturePtr aFeature = thePart->addFeature(FeaturesAPI_Fillet2D::ID()); + if (!keepSubResults) + aFeature->data()->setVersion(""); + + FilletPtr aFillet; + + aFillet.reset(new FeaturesAPI_Fillet2D(aFeature, theedgeselected, thepoint, theRadius)); + + return aFillet; +} + +FilletPtr addFilletMultiRadiusByCurv(const std::shared_ptr& thePart, + const ModelHighAPI_Selection & theedgeselected, + const std::list& thepointCurvCood, + const std::list& theRadius, + const bool keepSubResults) +{ + + FeaturePtr aFeature = thePart->addFeature(FeaturesAPI_Fillet2D::ID()); + if (!keepSubResults) + aFeature->data()->setVersion(""); + + FilletPtr aFillet; + + aFillet.reset(new FeaturesAPI_Fillet2D(aFeature, theedgeselected, thepointCurvCood, theRadius)); + + return aFillet; +} \ No newline at end of file diff --git a/src/FeaturesAPI/FeaturesAPI_Fillet.h b/src/FeaturesAPI/FeaturesAPI_Fillet.h index 7eac5d6c8..2d66f7d6f 100644 --- a/src/FeaturesAPI/FeaturesAPI_Fillet.h +++ b/src/FeaturesAPI/FeaturesAPI_Fillet.h @@ -28,6 +28,7 @@ #include #include #include +#include class ModelHighAPI_Selection; @@ -130,17 +131,39 @@ public: const ModelHighAPI_Double& theRadius1, const ModelHighAPI_Double& theRadius2); + /// Constructor with values. + FEATURESAPI_EXPORT + explicit FeaturesAPI_Fillet2D(const std::shared_ptr& theFeature, + const ModelHighAPI_Selection& theedgeselected, + const std::list& thepoint, + const std::list& theRadius); + + /// Constructor with values. + FEATURESAPI_EXPORT + explicit FeaturesAPI_Fillet2D(const std::shared_ptr& theFeature, + const ModelHighAPI_Selection& theedgeselected, + const std::list& thepointCurvCood, + const std::list& theRadius); /// Destructor. FEATURESAPI_EXPORT virtual ~FeaturesAPI_Fillet2D(); - INTERFACE_5(FeaturesPlugin_Fillet::ID(), + INTERFACE_8(FeaturesPlugin_Fillet::ID(), creationMethod, FeaturesPlugin_Fillet::CREATION_METHOD(), ModelAPI_AttributeString, /** Creation method */, + creationMethodmulti, FeaturesPlugin_Fillet::CREATION_METHOD_MULTIPLES_RADIUSES(), + ModelAPI_AttributeString, + /** Creation method */, baseObjects, FeaturesPlugin_Fillet::OBJECT_LIST_ID(), ModelAPI_AttributeSelectionList, /** Base objects */, + edgeselected, FeaturesPlugin_Fillet::EDGE_SELECTED_ID(), + ModelAPI_AttributeSelection, + /** Base objects */, + arraypointradiusbypoint, FeaturesPlugin_Fillet::ARRAY_POINT_RADIUS_BY_POINTS(), + ModelAPI_AttributeSelectionList, + /** Base objects */, radius, FeaturesPlugin_Fillet::RADIUS_ID(), ModelAPI_AttributeDouble, /** Value of the fixed radius fillet */, @@ -181,4 +204,23 @@ FilletPtr addFillet(const std::shared_ptr& thePart, const ModelHighAPI_Double& theRadius2 = ModelHighAPI_Double(-1.0), const bool keepSubResults = false); +/// \ingroup CPPHighAPI +/// \brief Create Fillet feature. +FEATURESAPI_EXPORT +FilletPtr addFilletMultiRadiusBypoint(const std::shared_ptr& thePart, + const ModelHighAPI_Selection & theedgeselected, + const std::list& thepoint, + const std::list& theRadius, + const bool keepSubResults= false); + + +/// \ingroup CPPHighAPI +/// \brief Create Fillet feature. +FEATURESAPI_EXPORT +FilletPtr addFilletMultiRadiusByCurv(const std::shared_ptr& thePart, + const ModelHighAPI_Selection & theedgeselected, + const std::list& thepointCurvCood, + const std::list& theRadius, + const bool keepSubResults= false); + #endif // FeaturesAPI_Fillet_H_ diff --git a/src/FeaturesPlugin/CMakeLists.txt b/src/FeaturesPlugin/CMakeLists.txt index 7523412b9..5c3ecc45c 100644 --- a/src/FeaturesPlugin/CMakeLists.txt +++ b/src/FeaturesPlugin/CMakeLists.txt @@ -19,6 +19,16 @@ INCLUDE(Common) INCLUDE(UnitTest) +INCLUDE(UseQtExt) + +# additional include directories +INCLUDE_DIRECTORIES( ${PROJECT_SOURCE_DIR}/src/GeomDataAPI + ${PROJECT_SOURCE_DIR}/src/Locale + ${QT_INCLUDES}) + +# additional preprocessor / compiler flags +ADD_DEFINITIONS(${QT_DEFINITIONS}) + SET(PROJECT_HEADERS FeaturesPlugin.h @@ -66,6 +76,12 @@ SET(PROJECT_HEADERS FeaturesPlugin_ImportResult.h FeaturesPlugin_Defeaturing.h FeaturesPlugin_VersionedChFi.h + FeaturesPlugin_WidgetCreator.h + FeaturesPlugin_WidgetFilletMultiRadiuses.h +) + +SET(PROJECT_MOC_HEADERS + FeaturesPlugin_WidgetFilletMultiRadiuses.h ) SET(PROJECT_SOURCES @@ -113,6 +129,8 @@ SET(PROJECT_SOURCES FeaturesPlugin_ImportResult.cpp FeaturesPlugin_Defeaturing.cpp FeaturesPlugin_VersionedChFi.cpp + FeaturesPlugin_WidgetCreator.cpp + FeaturesPlugin_WidgetFilletMultiRadiuses.cpp ) SET(XML_RESOURCES @@ -157,6 +175,12 @@ SET(TEXT_RESOURCES FeaturesPlugin_msg_ru.ts ) +# sources / moc wrappings +QT_WRAP_MOC(PROJECT_AUTOMOC ${PROJECT_MOC_HEADERS}) + +#QT5_ADD_TRANSLATION(QM_RESOURCES ${TEXT_RESOURCES}) + +SOURCE_GROUP ("Generated Files" FILES ${PROJECT_AUTOMOC} ${PROJECT_COMPILED_RESOURCES} ${QM_RESOURCES}) SOURCE_GROUP ("XML Files" FILES ${XML_RESOURCES}) SOURCE_GROUP ("Resource Files" FILES ${TEXT_RESOURCES}) @@ -166,6 +190,7 @@ INCLUDE_DIRECTORIES( ../GeomAPI ../GeomAlgoAPI ../GeomValidators + ../ModuleBase ../Events ../Config ${OpenCASCADE_INCLUDE_DIR} @@ -182,7 +207,12 @@ SET(PROJECT_LIBRARIES ) ADD_DEFINITIONS(-DFEATURESPLUGIN_EXPORTS) -ADD_LIBRARY(FeaturesPlugin MODULE ${PROJECT_SOURCES} ${PROJECT_HEADERS} ${XML_RESOURCES} ${TEXT_RESOURCES}) +ADD_LIBRARY(FeaturesPlugin MODULE + ${PROJECT_SOURCES} + ${PROJECT_HEADERS} + ${XML_RESOURCES} + ${TEXT_RESOURCES} + ${PROJECT_AUTOMOC}) TARGET_LINK_LIBRARIES(FeaturesPlugin ${PROJECT_LIBRARIES}) INSTALL(TARGETS FeaturesPlugin DESTINATION ${SHAPER_INSTALL_PLUGIN_FILES}) @@ -682,5 +712,4 @@ ADD_UNIT_TESTS(TestExtrusion.py TestFillet1D_Wire_3.py TestFillet1D_Wire_4.py TestFillet1D_Wire_5.py - Test19931.py ) diff --git a/src/FeaturesPlugin/FeaturesPlugin_BooleanFuse.cpp b/src/FeaturesPlugin/FeaturesPlugin_BooleanFuse.cpp index 3ab6d589c..4c43be8cc 100644 --- a/src/FeaturesPlugin/FeaturesPlugin_BooleanFuse.cpp +++ b/src/FeaturesPlugin/FeaturesPlugin_BooleanFuse.cpp @@ -41,22 +41,6 @@ #include #include -static void explodeCompound(const GeomShapePtr& theShape, ListOfShape& theResult) -{ - if (theShape->shapeType() == GeomAPI_Shape::COMPOUND) { - GeomAPI_ShapeIterator it(theShape); - for (; it.more(); it.next()) - theResult.push_back(it.current()); - } else - theResult.push_back(theShape); -} - -static void collectSolids(const ListOfShape& theShapes, ListOfShape& theResult) -{ - for (ListOfShape::const_iterator it = theShapes.begin(); it != theShapes.end(); ++it) - explodeCompound(*it, theResult); -} - //================================================================================================== FeaturesPlugin_BooleanFuse::FeaturesPlugin_BooleanFuse() : FeaturesPlugin_Boolean(FeaturesPlugin_Boolean::BOOL_FUSE) @@ -121,13 +105,9 @@ void FeaturesPlugin_BooleanFuse::execute() const std::string aFuseVersion = data()->version(); // Collecting all solids which will be fused. - // We explode the top-level compounds here because of issue #19931. It performs Fuse operation - // on a set of compounds, one of which is treated as self-intersected. - // But this problem is eliminated after the exploding, because in this case, - // the shapes are intersected, but not self-intersected. ListOfShape aSolidsToFuse; - collectSolids(anObjects, aSolidsToFuse); - collectSolids(aTools, aSolidsToFuse); + aSolidsToFuse.insert(aSolidsToFuse.end(), anObjects.begin(), anObjects.end()); + aSolidsToFuse.insert(aSolidsToFuse.end(), aTools.begin(), aTools.end()); // Collecting solids from compsolids which will not be modified // in boolean operation and will be added to result. diff --git a/src/FeaturesPlugin/FeaturesPlugin_CompositeSketch.cpp b/src/FeaturesPlugin/FeaturesPlugin_CompositeSketch.cpp index 0bd58e26c..ab0d12b7d 100644 --- a/src/FeaturesPlugin/FeaturesPlugin_CompositeSketch.cpp +++ b/src/FeaturesPlugin/FeaturesPlugin_CompositeSketch.cpp @@ -32,8 +32,6 @@ #include -static const std::string COMPOSITESKETCH_VERSION_1("v9.6"); - static void storeSubShape(const std::shared_ptr theMakeShape, ResultBodyPtr theResultBody, const GeomShapePtr theShape, @@ -51,15 +49,9 @@ void FeaturesPlugin_CompositeSketch::initCompositeSketchAttribtues(const int the // Initialize selection list. if(theInitFlags & InitBaseObjectsList) { - AttributeSelectionListPtr anObjectsAttr = - std::dynamic_pointer_cast( - data()->addAttribute(BASE_OBJECTS_ID(), ModelAPI_AttributeSelectionList::typeId())); + data()->addAttribute(BASE_OBJECTS_ID(), ModelAPI_AttributeSelectionList::typeId()); myCurrentSelectionType = selectionList(BASE_OBJECTS_ID())->selectionType(); - anObjectsAttr->setWholeResultAllowed(true); - if (!anObjectsAttr->isInitialized()) { - // new feature, specify the version - data()->setVersion(COMPOSITESKETCH_VERSION_1); - } + selectionList(BASE_OBJECTS_ID())->setWholeResultAllowed(true); } } diff --git a/src/FeaturesPlugin/FeaturesPlugin_Fillet.cpp b/src/FeaturesPlugin/FeaturesPlugin_Fillet.cpp index c8c5bf0d5..aafdfacde 100644 --- a/src/FeaturesPlugin/FeaturesPlugin_Fillet.cpp +++ b/src/FeaturesPlugin/FeaturesPlugin_Fillet.cpp @@ -22,6 +22,9 @@ #include #include #include +#include +#include + #include #include @@ -30,6 +33,16 @@ #include #include +#include +#include + +#include +#include +#include +#include +#include +#include + // Extract edges from the list static ListOfShape extractEdges(const ListOfShape& theShapes) @@ -49,21 +62,56 @@ FeaturesPlugin_Fillet::FeaturesPlugin_Fillet() void FeaturesPlugin_Fillet::initAttributes() { data()->addAttribute(CREATION_METHOD(), ModelAPI_AttributeString::typeId()); + data()->addAttribute(CREATION_METHOD_MULTIPLES_RADIUSES(), ModelAPI_AttributeString::typeId()); + AttributePtr aSelectionList = data()->addAttribute(OBJECT_LIST_ID(), ModelAPI_AttributeSelectionList::typeId()); data()->addAttribute(START_RADIUS_ID(), ModelAPI_AttributeDouble::typeId()); data()->addAttribute(END_RADIUS_ID(), ModelAPI_AttributeDouble::typeId()); + data()->addAttribute(VALUES_ID(), ModelAPI_AttributeTables::typeId()); + data()->addAttribute(VALUES_CURV_ID(), ModelAPI_AttributeTables::typeId()); + data()->addAttribute(EDGE_SELECTED_ID(), ModelAPI_AttributeSelection::typeId()); + + data()->addAttribute(ARRAY_POINT_RADIUS_BY_POINTS(), ModelAPI_AttributeSelectionList::typeId()); + + data()->addAttribute(CREATION_METHOD_BY_POINTS(), ModelAPI_AttributeString::typeId()); + data()->addAttribute(CREATION_METHOD_BY_CURVILEAR_ABSCISSA(), ModelAPI_AttributeString::typeId()); + ModelAPI_Session::get()->validators()->registerNotObligatory(getKind(), END_RADIUS_ID()); + ModelAPI_Session::get()->validators()->registerNotObligatory(getKind(), ARRAY_POINT_RADIUS_BY_POINTS()); + ModelAPI_Session::get()->validators()->registerNotObligatory(getKind(), VALUES_ID()); + ModelAPI_Session::get()->validators()->registerNotObligatory(getKind(), VALUES_CURV_ID()); + ModelAPI_Session::get()->validators()->registerNotObligatory(getKind(), CREATION_METHOD_MULTIPLES_RADIUSES()); + ModelAPI_Session::get()->validators()->registerNotObligatory(getKind(), CREATION_METHOD_BY_CURVILEAR_ABSCISSA()); + ModelAPI_Session::get()->validators()->registerNotObligatory(getKind(), CREATION_METHOD_BY_POINTS()); initVersion(aSelectionList); } AttributePtr FeaturesPlugin_Fillet::objectsAttribute() { + return attribute(OBJECT_LIST_ID()); } +void FeaturesPlugin_Fillet::attributeChanged(const std::string& theID) +{ + if (theID == EDGE_SELECTED_ID() + && string(CREATION_METHOD())->value() == CREATION_METHOD_MULTIPLES_RADIUSES()) { + + AttributeSelectionPtr anEdges = + std::dynamic_pointer_cast(attribute(EDGE_SELECTED_ID())); + AttributeSelectionListPtr array = selectionList(OBJECT_LIST_ID()); + //if (array->isInitialized() ) + // array->clear(); + + array->append(anEdges->namingName() ); + + + } +} + const std::string& FeaturesPlugin_Fillet::modifiedShapePrefix() const { static const std::string& THE_PREFIX("Fillet"); @@ -74,31 +122,63 @@ GeomMakeShapePtr FeaturesPlugin_Fillet::performOperation(const GeomShapePtr& the const ListOfShape& theEdges) { AttributeStringPtr aCreationMethod = string(CREATION_METHOD()); - if (!aCreationMethod) - return GeomMakeShapePtr(); + std::string anError; - bool isFixedRadius = aCreationMethod->value() == CREATION_METHOD_SINGLE_RADIUS(); - double aRadius1 = 0.0, aRadius2 = 0.0; - if (isFixedRadius) - aRadius1 = real(RADIUS_ID())->value(); - else { - aRadius1 = real(START_RADIUS_ID())->value(); - aRadius2 = real(END_RADIUS_ID())->value(); + if (!aCreationMethod){ + setError(anError); + return GeomMakeShapePtr(); } - - // Perform fillet operation + std::shared_ptr aFilletBuilder; - std::string anError; - + ListOfShape aFilletEdges = extractEdges(theEdges); - if (isFixedRadius) - aFilletBuilder.reset(new GeomAlgoAPI_Fillet(theSolid, aFilletEdges, aRadius1)); - else - aFilletBuilder.reset(new GeomAlgoAPI_Fillet(theSolid, aFilletEdges, aRadius1, aRadius2)); + + if ( aCreationMethod->value() == CREATION_METHOD_MULTIPLES_RADIUSES() ) + { + + std::list coodCurv; + std::list radiuses; + AttributeTablesPtr aTablesAttr; + + if( string(CREATION_METHOD_MULTIPLES_RADIUSES())->value() == CREATION_METHOD_BY_POINTS() ) + { + aTablesAttr = tables(VALUES_ID()); + + }else{ + aTablesAttr = tables(VALUES_CURV_ID()); + } + + int aRows = aTablesAttr->rows(); + ModelAPI_AttributeTables::Value aVal; + for (int k = 0; k < aRows; k++) { + aVal = aTablesAttr->value(k, 0); + coodCurv.push_back(aVal.myDouble); + aVal = aTablesAttr->value(k, 1); + radiuses.push_back(aVal.myDouble); + } + aFilletBuilder.reset(new GeomAlgoAPI_Fillet(theSolid, aFilletEdges, coodCurv,radiuses)); + + }else + { + bool isFixedRadius = aCreationMethod->value() == CREATION_METHOD_SINGLE_RADIUS(); + double aRadius1 = 0.0, aRadius2 = 0.0; + if (isFixedRadius) + aRadius1 = real(RADIUS_ID())->value(); + else { + aRadius1 = real(START_RADIUS_ID())->value(); + aRadius2 = real(END_RADIUS_ID())->value(); + } + + if (isFixedRadius) + aFilletBuilder.reset(new GeomAlgoAPI_Fillet(theSolid, aFilletEdges, aRadius1)); + else + aFilletBuilder.reset(new GeomAlgoAPI_Fillet(theSolid, aFilletEdges, aRadius1, aRadius2)); + } if (GeomAlgoAPI_Tools::AlgoError::isAlgorithmFailed(aFilletBuilder, getKind(), anError)) { - setError(anError); - return GeomMakeShapePtr(); + setError(anError); + return GeomMakeShapePtr(); } return aFilletBuilder; } + diff --git a/src/FeaturesPlugin/FeaturesPlugin_Fillet.h b/src/FeaturesPlugin/FeaturesPlugin_Fillet.h index 2c1460b95..ff7f2774d 100644 --- a/src/FeaturesPlugin/FeaturesPlugin_Fillet.h +++ b/src/FeaturesPlugin/FeaturesPlugin_Fillet.h @@ -61,6 +61,30 @@ public: return MY_VARYING_RADIUS; } + inline static const std::string CREATION_METHOD_MULTIPLES_RADIUSES() + { + static std::string MY_METHOD_MULTIPLES_RADIUSES("multiple_radiuses"); + return MY_METHOD_MULTIPLES_RADIUSES; + } + + inline static const std::string CREATION_METHOD_BY_POINTS() + { + static std::string MY_CREATION_METHOD_BY_POINTS("by_point_method"); + return MY_CREATION_METHOD_BY_POINTS; + } + + inline static const std::string ARRAY_POINT_RADIUS_BY_POINTS() + { + static std::string MY_ARRAY_POINT_RADIUS_BY_POINTS("array_point_radius_by_point"); + return MY_ARRAY_POINT_RADIUS_BY_POINTS; + } + + inline static const std::string CREATION_METHOD_BY_CURVILEAR_ABSCISSA() + { + static std::string MY_CREATION_METHOD_BY_CURVILEAR_ABSCISSA("by_curvilinear_abscissa_methode"); + return MY_CREATION_METHOD_BY_CURVILEAR_ABSCISSA; + } + /// Attribute name of main objects. inline static const std::string& OBJECT_LIST_ID() { @@ -75,6 +99,27 @@ public: return MY_START_RADIUS_ID; } + /// Attribute name of edge selected. + inline static const std::string& EDGE_SELECTED_ID() + { + static const std::string MY_EDGE_SELECTED_ID("edge_selected"); + return MY_EDGE_SELECTED_ID; + } + + /// attribute name of list of tables that contain deafult values (row 0) and the custom values + inline static const std::string& VALUES_ID() + { + static const std::string MY_VALUES_ID("values"); + return MY_VALUES_ID; + } + + /// attribute name of list of tables that contain deafult values (row 0) and the custom values + inline static const std::string& VALUES_CURV_ID() + { + static const std::string MY_VALUES_ID("values_curv"); + return MY_VALUES_ID; + } + /// Attribute name of end radius. inline static const std::string& END_RADIUS_ID() { @@ -91,6 +136,8 @@ public: /// Request for initialization of data model of the feature: adding all attributes. FEATURESPLUGIN_EXPORT virtual void initAttributes(); + FEATURESPLUGIN_EXPORT void attributeChanged(const std::string& theID); + /// Use plugin manager for features creation. FeaturesPlugin_Fillet(); diff --git a/src/FeaturesPlugin/FeaturesPlugin_Plugin.cpp b/src/FeaturesPlugin/FeaturesPlugin_Plugin.cpp index 0d49dfe08..e68b35d69 100644 --- a/src/FeaturesPlugin/FeaturesPlugin_Plugin.cpp +++ b/src/FeaturesPlugin/FeaturesPlugin_Plugin.cpp @@ -55,6 +55,10 @@ #include #include +#include + +#include "FeaturesPlugin_WidgetCreator.h" + #include #include @@ -66,7 +70,13 @@ static FeaturesPlugin_Plugin* MY_FEATURES_INSTANCE = new FeaturesPlugin_Plugin() FeaturesPlugin_Plugin::FeaturesPlugin_Plugin() { + + WidgetCreatorFactoryPtr aWidgetCreatorFactory = ModuleBase_WidgetCreatorFactory::get(); + aWidgetCreatorFactory->registerCreator( + std::shared_ptr(new FeaturesPlugin_WidgetCreator())); + SessionPtr aMgr = ModelAPI_Session::get(); + ModelAPI_ValidatorsFactory* aFactory = aMgr->validators(); aFactory->registerValidator("FeaturesPlugin_ValidatorTransform", new FeaturesPlugin_ValidatorTransform); diff --git a/src/FeaturesPlugin/FeaturesPlugin_Validators.cpp b/src/FeaturesPlugin/FeaturesPlugin_Validators.cpp index 55bad81ce..9235d933e 100644 --- a/src/FeaturesPlugin/FeaturesPlugin_Validators.cpp +++ b/src/FeaturesPlugin/FeaturesPlugin_Validators.cpp @@ -402,11 +402,7 @@ bool FeaturesPlugin_ValidatorBaseForGeneration::isValidAttribute(const Attribute AttributeSelectionListPtr aListAttr = std::dynamic_pointer_cast(theAttribute); - const std::string& aVersion = theAttribute->owner()->data()->version(); - std::string aSelType; - if (!aVersion.empty()) - aSelType = aListAttr->selectionType(); - + const std::string& aSelType = aListAttr->selectionType(); std::list anApplicableTypes; switch (GeomValidators_ShapeType::shapeType(aSelType)) { case GeomValidators_ShapeType::Vertex: diff --git a/src/FeaturesPlugin/FeaturesPlugin_VersionedChFi.cpp b/src/FeaturesPlugin/FeaturesPlugin_VersionedChFi.cpp index 7dfa2e339..7738cf1fe 100644 --- a/src/FeaturesPlugin/FeaturesPlugin_VersionedChFi.cpp +++ b/src/FeaturesPlugin/FeaturesPlugin_VersionedChFi.cpp @@ -27,6 +27,7 @@ #include +#include static const std::string CHAMFERFILLET_VERSION_1("v9.5"); @@ -81,6 +82,7 @@ void FeaturesPlugin_VersionedChFi::execute() anOriginalSolids.push_back(aSolid); anEdges.insert(anEdges.end(), aSubs.begin(), aSubs.end()); + } // Build results of the operaion. @@ -125,14 +127,28 @@ bool FeaturesPlugin_VersionedChFi::processAttribute(const AttributePtr& theAttri if (aContext.get()) { ResultBodyPtr aCtxOwner = ModelAPI_Tools::bodyOwner(aContext); if (aCtxOwner && aCtxOwner->shape()->shapeType() == GeomAPI_Shape::COMPSOLID) + { aContext = aCtxOwner; + } aParent = aContext->shape(); if (!aParent) return false; // store full shape hierarchy for the corresponding version only - theObjects.addObject(anObject); - theObjects.addParent(anObject, aParent); + if (anObject->shapeType() <= GeomAPI_Shape::SOLID) + { + ListOfShape anEdges; + collectSubs(aParent, anEdges, GeomAPI_Shape::EDGE); + for (ListOfShape::iterator anIt = anEdges.begin(); anIt != anEdges.end(); ++anIt) { + theObjects.addObject(*anIt); + theObjects.addParent(*anIt, aParent); + } + }else + { + theObjects.addObject(anObject); + theObjects.addParent(anObject, aParent); + } + if (isStoreFullHierarchy) ModelAPI_Tools::fillShapeHierarchy(aParent, aContext, theObjects); } else { // get it from a feature diff --git a/src/FeaturesPlugin/FeaturesPlugin_WidgetCreator.cpp b/src/FeaturesPlugin/FeaturesPlugin_WidgetCreator.cpp new file mode 100644 index 000000000..05478d8bc --- /dev/null +++ b/src/FeaturesPlugin/FeaturesPlugin_WidgetCreator.cpp @@ -0,0 +1,56 @@ +// Copyright (C) 2014-2020 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 "FeaturesPlugin_WidgetCreator.h" +#include "FeaturesPlugin_WidgetFilletMultiRadiuses.h" + + +FeaturesPlugin_WidgetCreator::FeaturesPlugin_WidgetCreator() +: ModuleBase_IWidgetCreator() +{ + myPanelTypes.insert("multiradius-panel"); + myPanelTypes.insert("multiradiuscurv-panel"); +} + +void FeaturesPlugin_WidgetCreator::widgetTypes(std::set& theTypes) +{ + theTypes = myPanelTypes; +} + + +ModuleBase_ModelWidget* FeaturesPlugin_WidgetCreator::createWidgetByType( + const std::string& theType, + QWidget* theParent, + Config_WidgetAPI* theWidgetApi, + ModuleBase_IWorkshop* theWorkshop) +{ + ModuleBase_ModelWidget* aWidget = 0; + if (myPanelTypes.find(theType) == myPanelTypes.end()) + return aWidget; + + if (theType == "multiradius-panel") { + aWidget = new FeaturesPlugin_WidgetFilletMultiRadiuses(theParent, theWorkshop, theWidgetApi, true); + }else if (theType == "multiradiuscurv-panel") + { + aWidget = new FeaturesPlugin_WidgetFilletMultiRadiuses(theParent, theWorkshop, theWidgetApi, false); + } + + + return aWidget; +} diff --git a/src/FeaturesPlugin/FeaturesPlugin_WidgetCreator.h b/src/FeaturesPlugin/FeaturesPlugin_WidgetCreator.h new file mode 100644 index 000000000..98ba3b63e --- /dev/null +++ b/src/FeaturesPlugin/FeaturesPlugin_WidgetCreator.h @@ -0,0 +1,64 @@ +// Copyright (C) 2014-2020 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 FeaturesPlugin_WidgetCreator_H +#define FeaturesPlugin_WidgetCreator_H + + +#include "FeaturesPlugin.h" +#include + +#include +#include + +class QWidget; + +/** +* \ingroup GUI +* Interface to WidgetCreator which can create specific widgets by type +*/ +class FeaturesPlugin_WidgetCreator : public ModuleBase_IWidgetCreator +{ +public: + /// Default constructor + FeaturesPlugin_WidgetCreator(); + + /// Virtual destructor + ~FeaturesPlugin_WidgetCreator() {} + + /// Returns a container of possible page types, which this creator can process + /// \param theTypes a list of type names + virtual void widgetTypes(std::set& theTypes); + + /// Create widget by its type + /// The default implementation is empty + /// \param theType a type + /// \param theParent a parent widget + /// \param theData a low-level API for reading xml definitions of widgets + /// \param theWorkshop a current workshop + /// \return a created model widget or null + virtual ModuleBase_ModelWidget* createWidgetByType(const std::string& theType, + QWidget* theParent, + Config_WidgetAPI* theWidgetApi, + ModuleBase_IWorkshop* /*theWorkshop*/); +private: + std::set myPanelTypes; ///< types of panels +}; + +#endif \ No newline at end of file diff --git a/src/FeaturesPlugin/FeaturesPlugin_WidgetFilletMultiRadiuses.cpp b/src/FeaturesPlugin/FeaturesPlugin_WidgetFilletMultiRadiuses.cpp new file mode 100644 index 000000000..3c9f3e3ad --- /dev/null +++ b/src/FeaturesPlugin/FeaturesPlugin_WidgetFilletMultiRadiuses.cpp @@ -0,0 +1,705 @@ +// Copyright (C) 2014-2020 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 "FeaturesPlugin_WidgetFilletMultiRadiuses.h" +#include "FeaturesPlugin_Fillet.h" + +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +const char* MYFirstCol = "Shape"; +const char* MYTrue = "True"; +const char* MYFalse = "False"; + + +DataArrayItemDelegate::DataArrayItemDelegate(bool theTypeMethode) + : QStyledItemDelegate(), myTypeMethodePoint(theTypeMethode) +{ +} + + +QWidget* DataArrayItemDelegate::createEditor(QWidget* theParent, + const QStyleOptionViewItem & theOption, + const QModelIndex& theIndex ) const +{ + QWidget* aEditor = 0; + if ((theIndex.column() == 0) && (theIndex.row() > 0 )) { + QWidget* aWgt = QStyledItemDelegate::createEditor(theParent, theOption, theIndex); + QLineEdit* aEdt = static_cast(aWgt); + aEdt->setReadOnly(true); + aEditor = aEdt; + } else { + QLineEdit* aLineEdt = 0; + + aLineEdt = dynamic_cast(QStyledItemDelegate::createEditor(theParent, + theOption, + theIndex)); + if (aLineEdt) { + if( theIndex.column() == 2 ) + aLineEdt->setValidator(new QDoubleValidator(0.0 , 10000.0, 6, aLineEdt)); + else + aLineEdt->setValidator(new QDoubleValidator(0.00001 , 0.9999, 6, aLineEdt)); + aEditor = aLineEdt; + } + + } + + connect(aEditor, SIGNAL(textEdited(const QString&)), + SLOT(onEditItem(const QString&))); + return aEditor; +} + +void DataArrayItemDelegate::onEditItem(const QString& theText) +{ + QWidget* aWgt = dynamic_cast(sender()); + commitData(aWgt); +} + + +//********************************************************************************** +//********************************************************************************** +//********************************************************************************** +FeaturesPlugin_WidgetFilletMultiRadiuses:: + FeaturesPlugin_WidgetFilletMultiRadiuses(QWidget* theParent, + ModuleBase_IWorkshop* theWorkshop, + const Config_WidgetAPI* theData, + bool TypeMethodeBypoint): +ModuleBase_WidgetSelector(theParent, theWorkshop, theData), myHeaderEditor(0), + myTypeMethodeBypoint(TypeMethodeBypoint),mySetSelection(true) +{ + QVBoxLayout* aMainLayout = new QVBoxLayout(this); + + aMainLayout->addWidget(new QLabel("Raduises", this)); + // Radiuses controls + QFrame* aRadiusesFrame = new QFrame(this); + aRadiusesFrame->setFrameShape(QFrame::Box); + aRadiusesFrame->setFrameStyle(QFrame::StyledPanel); + QVBoxLayout* aRadiusesLayout = new QVBoxLayout(aRadiusesFrame); + aMainLayout->addWidget(aRadiusesFrame); + + myDataTbl = new QTableWidget(2, 3, aRadiusesFrame); + + myDelegate = new DataArrayItemDelegate(myTypeMethodeBypoint); + + myDataTbl->installEventFilter(this); + myDataTbl->setItemDelegate(myDelegate); + + myDataTbl->verticalHeader()->hide(); + myDataTbl->setRowHeight(0, 25); + myDataTbl->setHorizontalScrollMode(QAbstractItemView::ScrollPerPixel); + + if(myTypeMethodeBypoint){ + myfirstRowValue.push_back("Start extremity"); + myfirstRowValue.push_back("0"); + myfirstRowValue.push_back("0.5"); + myLastRowValue.push_back("End extremity"); + myLastRowValue.push_back("1"); + myLastRowValue.push_back("0.5"); + }else{ + myfirstRowValue.push_back("0"); + myfirstRowValue.push_back("0"); + myfirstRowValue.push_back("1"); + myLastRowValue.push_back("1"); + myLastRowValue.push_back("1"); + myLastRowValue.push_back("2"); + } + + + QStringList aHeaders; + aHeaders << "Point"; + aHeaders << "Curvilinear /n Abscissa"; + aHeaders << "Radius"; + + + myDataTbl->setHorizontalHeaderLabels(aHeaders); + + QTableWidgetItem* aItem; + for(int j =0; j<3;j++) + { + aItem = new QTableWidgetItem(myfirstRowValue[j]); + if(j==0 || j== 1) + aItem->setFlags(Qt::NoItemFlags | Qt::ItemIsEnabled); + myDataTbl->setItem(0, j, aItem); + aItem = new QTableWidgetItem(myLastRowValue[j]); + if(j==0 || j== 1) + aItem->setFlags(Qt::NoItemFlags | Qt::ItemIsEnabled); + myDataTbl->setItem(1, j, aItem); + } + + connect(myDataTbl, SIGNAL(cellChanged(int, int)), SLOT(onTableEdited(int, int))); + + myDataTbl->horizontalHeader()->viewport()->installEventFilter(this); + + aRadiusesLayout->addWidget(myDataTbl); + ///======================== + + // Buttons below + QWidget* aBtnWgt = new QWidget(this); + aRadiusesLayout->addWidget(aBtnWgt); + QHBoxLayout* aBtnLayout = new QHBoxLayout(aBtnWgt); + aBtnLayout->setAlignment(Qt::AlignLeft); + aBtnLayout->setContentsMargins(0, 0, 0, 0); + + QPushButton* aAddBtn = new QPushButton(tr("+"), aBtnWgt); + QFont font = aAddBtn->font(); + font.setPointSize(12); + aAddBtn->setFont(font); + aBtnLayout->addWidget(aAddBtn); + aBtnLayout->addStretch(1); + + myRemoveBtn = new QPushButton(tr("-"), aBtnWgt); + font = myRemoveBtn->font(); + font.setPointSize(12); + myRemoveBtn->setFont(font); + aBtnLayout->addWidget(myRemoveBtn); + + connect(aAddBtn, SIGNAL(clicked(bool)), SLOT(onAddStep())); + connect(myRemoveBtn, SIGNAL(clicked(bool)), SLOT(onRemoveStep())); + connect(qApp, SIGNAL(focusChanged(QWidget*, QWidget*)), SLOT(onFocusChanged(QWidget*, QWidget*))); +} + +QList FeaturesPlugin_WidgetFilletMultiRadiuses::getControls() const +{ + QList aControls; + // this control will accept focus and will be highlighted in the Property Panel + aControls.append(myDataTbl); + return aControls; +} + +//********************************************************************************** +QIntList FeaturesPlugin_WidgetFilletMultiRadiuses::shapeTypes() const +{ + QIntList aRes; + + aRes.append(ModuleBase_Tools::shapeType("vertex")); + return aRes; +} + +//********************************************************************************** +void FeaturesPlugin_WidgetFilletMultiRadiuses::deactivate() +{ + + ModuleBase_WidgetSelector::deactivate(); + storeValueCustom(); +} + +//********************************************************************************** +bool FeaturesPlugin_WidgetFilletMultiRadiuses::eventFilter(QObject* theObject, QEvent* theEvent) +{ + QObject* aObject = 0; + + if (myDataTbl->horizontalHeader()->viewport() == theObject) { + aObject = theObject; + } + if (aObject) { + if (theEvent->type() == QEvent::MouseButtonDblClick) { + if (myHeaderEditor) { //delete previous editor + myHeaderEditor->deleteLater(); + myHeaderEditor = 0; + } + QMouseEvent* aMouseEvent = static_cast(theEvent); + QHeaderView* aHeader = static_cast(aObject->parent()); + QTableWidget* aTable = static_cast(aHeader->parentWidget()); + + int aShift = aTable->horizontalScrollBar()->value(); + int aPos = aMouseEvent->x(); + int aIndex = aHeader->logicalIndex(aHeader->visualIndexAt(aPos)); + if (aIndex > 0) { + QRect aRect; + aRect.setLeft(aHeader->sectionPosition(aIndex)); + aRect.setWidth(aHeader->sectionSize(aIndex)); + aRect.setTop(0); + aRect.setHeight(aHeader->height()); + aRect.adjust(1, 1, -1, -1); + aRect.translate(-aShift, 0); + + myHeaderEditor = new QLineEdit(aHeader->viewport()); + myHeaderEditor->move(aRect.topLeft()); + myHeaderEditor->resize(aRect.size()); + myHeaderEditor->setFrame(false); + QString aText = aHeader->model()-> + headerData(aIndex, aHeader->orientation()).toString(); + myHeaderEditor->setText(aText); + myHeaderEditor->setFocus(); + //myEditIndex = aIndex; //save for future use + myHeaderEditor->installEventFilter(this); //catch focus out event + //if user presses Enter it should close editor + connect(myHeaderEditor, SIGNAL(returnPressed()), aTable, SLOT(setFocus())); + myHeaderEditor->show(); + return true; + } + } + } else if (theEvent->type() == QEvent::FocusIn) { + + QTableWidget* aTable = dynamic_cast(theObject); + if (aTable) { + ModuleBase_IPropertyPanel* aPanel = myWorkshop->propertyPanel(); + if (aPanel->activeWidget() != this) { + aPanel->activateWidget(this, false); + } + } + } + else if (theEvent->type() == QEvent::Show ) { + + /* ModuleBase_IPropertyPanel* aPanel = myWorkshop->propertyPanel(); + if (aPanel->activeWidget() != this) { + aPanel->activateWidget(this, false); + }*/ + DataPtr aData = myFeature->data(); + if( myTypeMethodeBypoint ) + aData->string(FeaturesPlugin_Fillet::CREATION_METHOD_MULTIPLES_RADIUSES()) + ->setValue(FeaturesPlugin_Fillet::CREATION_METHOD_BY_POINTS() ); + else + aData->string(FeaturesPlugin_Fillet::CREATION_METHOD_MULTIPLES_RADIUSES()) + ->setValue(FeaturesPlugin_Fillet::CREATION_METHOD_BY_CURVILEAR_ABSCISSA() ); + } + return ModuleBase_WidgetSelector::eventFilter(theObject, theEvent); +} + + + +//********************************************************************************** +bool FeaturesPlugin_WidgetFilletMultiRadiuses::storeValueCustom() +{ + + DataPtr aData = myFeature->data(); + + AttributeTablesPtr aTablesAttr; + + if(myTypeMethodeBypoint) + aTablesAttr = aData->tables(FeaturesPlugin_Fillet::VALUES_ID()); + else + aTablesAttr = aData->tables(FeaturesPlugin_Fillet::VALUES_CURV_ID()); + + // Store data- + int aRows = myDataTbl->rowCount(); + + aTablesAttr->setSize(aRows, 2); + aTablesAttr->setType(ModelAPI_AttributeTables::ValueType::DOUBLE); + + for (int i = 0; i < aRows; i++) { + for (int j = 0; j < 2; j++) { + QString aTblVal = myDataTbl->item(i, j+1)->text(); + aTablesAttr->setValue( getValue( aTblVal ), i, j); + } + } + + return true; +} + +//********************************************************************************** +bool FeaturesPlugin_WidgetFilletMultiRadiuses::restoreValueCustom() +{ + + if ( !mySetSelection) { + mySetSelection = true; + return false; + } + DataPtr aData = myFeature->data(); + + AttributeTablesPtr aTablesAttr; + + if(myTypeMethodeBypoint) + aTablesAttr = aData->tables(FeaturesPlugin_Fillet::VALUES_ID()); + else + aTablesAttr = aData->tables(FeaturesPlugin_Fillet::VALUES_CURV_ID()); + + AttributeSelectionPtr anEdges = + std::dynamic_pointer_cast(aData->attribute(FeaturesPlugin_Fillet::EDGE_SELECTED_ID())); + + if( !anEdges->isInitialized() ) + return; + + std::map> aValuesSort; + + double res; + int aRows = 0; + std::map>::iterator itValuesSort; + if(myTypeMethodeBypoint) + { + GeomEdgePtr anEdge = GeomEdgePtr(new GeomAPI_Edge( anEdges->value())); + GeomPointPtr first = anEdge->firstPoint(); + GeomPointPtr last = anEdge->lastPoint(); + double taille = first->distance(last); + + // Load points + AttributeSelectionListPtr aSelectionListAttr = aData->selectionList(FeaturesPlugin_Fillet::ARRAY_POINT_RADIUS_BY_POINTS()); + AttributeDoubleArrayPtr aArrayAttr; + ListOfShape aPoints; + + std::set aContexts; + for (int anIndex = 0; anIndex < aSelectionListAttr->size(); ++anIndex) { + AttributeSelectionPtr aSelection = aSelectionListAttr->value(anIndex); + GeomShapePtr aShape = aSelection->value(); + + ResultPtr aContext = aSelection->context(); + aContexts.insert(aContext->shape()); + + if (!aShape.get()) { + aShape = aContext->shape(); + } + + aPoints.push_back(aShape); + } + int i =0; + + ListOfShape::const_iterator aPointsIt = aPoints.begin(); + for (; aPointsIt != aPoints.end(); ++aPointsIt) { + AttributeSelectionPtr attsel = aSelectionListAttr->value(i); + std::shared_ptr aPnt = GeomAlgoAPI_PointBuilder::point(*aPointsIt); + res = (aPnt->distance(first) / taille); + QString aName = QString::fromStdWString(attsel->namingName()); + QString aRad = findRadius( QString::number(res) ); + if ( aValuesSort.find( res ) == aValuesSort.end() ) + aValuesSort[ res ] = std::make_pair(aName, aRad ); + i++; + } + + res = 0.0; + aValuesSort[ res ] = std::make_pair (myfirstRowValue[0], findRadius( QString::number(res) )) ; + res = 1.0; + aValuesSort[ res ] = std::make_pair (myLastRowValue[0], findRadius( QString::number(res) )) ; + aRows = aValuesSort.size(); + }else{ + + ModelAPI_AttributeTables::Value aVal; + if (aTablesAttr->isInitialized()){ + + for (int anIndex = 0; anIndex < aTablesAttr->rows(); ++anIndex) { + aVal = aTablesAttr->value(anIndex,0); + double curv = getValueText(aVal).toDouble(); + if ( aValuesSort.find( curv ) == aValuesSort.end() ) + aValuesSort[ curv ] = std::make_pair(getValueText(aVal), findRadius(getValueText(aVal))); + } + aRows = aTablesAttr->rows(); + }else{ + res = 0.0; + aValuesSort[ res ] = std::make_pair (myfirstRowValue[0], myfirstRowValue[2]) ; + res = 1.0; + aValuesSort[ res ] = std::make_pair (myLastRowValue[0], myLastRowValue[2]) ; + aRows = 2; + } + + } + + QTableWidgetItem* aItem = 0; + myDataTbl->blockSignals(true); + aItem = myDataTbl->item( myDataTbl->rowCount() -1, 0 ); + aItem->setFlags(Qt::NoItemFlags | Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemIsEditable); + aItem = myDataTbl->item( myDataTbl->rowCount() -1, 1 ); + aItem->setFlags(Qt::NoItemFlags | Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemIsEditable); + + + myDataTbl->setRowCount(aRows); + + itValuesSort = aValuesSort.begin(); + + for (int k = 0; k < aRows; k++, ++itValuesSort ) { + + std::pair elem = itValuesSort->second; + QString aCurv = QString::number(itValuesSort->first); + + aItem = myDataTbl->item(k, 0); + if (aItem) { + aItem->setText( elem.first); + } else { + aItem = new QTableWidgetItem(elem.first); + myDataTbl->setItem(k, 0, aItem); + } + aItem = myDataTbl->item(k, 1); + if (aItem) { + aItem->setText( aCurv); + } else { + aItem = new QTableWidgetItem(aCurv); + myDataTbl->setItem(k, 1, aItem); + } + aItem = myDataTbl->item(k, 2); + if (aItem) { + aItem->setText( elem.second); + } else { + aItem = new QTableWidgetItem(elem.second); + myDataTbl->setItem(k, 2, aItem); + } + } + aItem = myDataTbl->item(myDataTbl->rowCount()-1, 0 ); + aItem->setFlags(Qt::NoItemFlags | Qt::ItemIsEnabled ); + aItem = myDataTbl->item(myDataTbl->rowCount()-1, 1 ); + aItem->setFlags(Qt::NoItemFlags | Qt::ItemIsEnabled ); + myDataTbl->blockSignals(false); + + return true; +} + + +//********************************************************************************** +void FeaturesPlugin_WidgetFilletMultiRadiuses::onAddStep() +{ + + QModelIndex index = myDataTbl->currentIndex(); + int i = index.row(); + if( i == -1 ) + return false; + + if( !myDataTbl->currentItem()->isSelected() && myDataTbl->rowCount() >2 ) + return false; + + myDataTbl->blockSignals(true); + + if ( i == myDataTbl->rowCount() -1) + i = myDataTbl->rowCount() - 2; + + if ( i == 0) + i =1; + + myDataTbl->model()->insertRow(i); + QTableWidgetItem* aItem =0; + + aItem = myDataTbl->item( i, 0 ); + aItem = new QTableWidgetItem( "New" ); + myDataTbl->setItem(i, 0, aItem); + aItem = new QTableWidgetItem(myfirstRowValue[1]); + myDataTbl->setItem(i, 1, aItem); + aItem = new QTableWidgetItem("-1"); + myDataTbl->setItem(i, 1, aItem); + aItem = new QTableWidgetItem(myfirstRowValue[2]); + myDataTbl->setItem(i, 2, aItem); + aItem = new QTableWidgetItem(myLastRowValue[2]); + myDataTbl->setItem(i, 2, aItem); + + myDataTbl->blockSignals(false); + + emit valuesChanged(); +} + +//********************************************************************************** +void FeaturesPlugin_WidgetFilletMultiRadiuses::onRemoveStep() +{ + QModelIndex index = myDataTbl->currentIndex(); + + if( !myDataTbl->currentItem()->isSelected() && myDataTbl->rowCount() >2 ) + return false; + + myDataTbl->blockSignals(true); + if (index.row() == -1 + || index.row() == 0 + || index.row() == myDataTbl->rowCount() -1) + return; + + if (myTypeMethodeBypoint) + { + QTableWidgetItem* aItem = 0; + + QString aName = myDataTbl->item( index.row() , 0 )->text(); + AttributeSelectionListPtr aSelList = + myFeature->data()->selectionList(FeaturesPlugin_Fillet::ARRAY_POINT_RADIUS_BY_POINTS()); + + AttributeSelectionPtr aAttr; + for (int i = 0; i < aSelList->size(); i++) { + aAttr = aSelList->value(i); + if( aName == QString::fromStdWString( aAttr->namingName()) ) + { + aSelList->remove({i}); + } + } + } + myDataTbl->model()->removeRow(index.row()); + myDataTbl->blockSignals(false); + + emit valuesChanged(); +} + +//********************************************************************************** +void FeaturesPlugin_WidgetFilletMultiRadiuses::onTableEdited(int theRow, int theCol) +{ + // Do not store here column of names + if (theCol == 0) + return; + + if (!myFeature.get()) + return; + + ModelAPI_AttributeTables::Value aVal = getValue(myDataTbl->item(theRow, theCol)->text()); + + AttributeTablesPtr aTablesAttr; + + if(myTypeMethodeBypoint) + aTablesAttr = myFeature->data()->tables(FeaturesPlugin_Fillet::VALUES_ID()); + else + aTablesAttr = myFeature->data()->tables(FeaturesPlugin_Fillet::VALUES_CURV_ID()); + + if (aTablesAttr->isInitialized()) + { + aTablesAttr->setValue(aVal,theRow, theCol - 1); + emit valuesChanged(); + } +} + +//********************************************************************************** +bool FeaturesPlugin_WidgetFilletMultiRadiuses:: + isValidSelectionCustom(const std::shared_ptr& thePrs) +{ + return true; +} + +//********************************************************************************** +bool FeaturesPlugin_WidgetFilletMultiRadiuses::processEnter() +{ + + return true; +} + +//********************************************************************************** +bool FeaturesPlugin_WidgetFilletMultiRadiuses:: + setSelection(QList>& theValues, const bool theToValidate) +{ + + if ( theValues.size() > 1 || !myTypeMethodeBypoint || theValues.size() == 0 ) + { + mySetSelection = false; + return false; + } + QModelIndex index = myDataTbl->currentIndex(); + if( index.row() == -1 ) + { + mySetSelection = false; + return false; + } + + if( !myDataTbl->currentItem()->isSelected()){ + mySetSelection = false; + return false; + } + + + AttributeSelectionListPtr aSelList = + myFeature->data()->selectionList(FeaturesPlugin_Fillet::ARRAY_POINT_RADIUS_BY_POINTS()); + + ResultPtr aResult; + GeomShapePtr aShape; + int aNbData = 0; + ModuleBase_ViewerPrsPtr aValue = theValues.first(); + aResult = std::dynamic_pointer_cast(aValue->object()); + aShape = aValue->shape(); + + if ( (aResult.get() || aShape.get() ) && !aSelList->isInList(aResult, aShape)) { + aSelList->append(aResult, aShape); + onRemoveStep(); + }else{ + mySetSelection = false; + return false; + } + + return true; +} + +//********************************************************************************** +QList> + FeaturesPlugin_WidgetFilletMultiRadiuses::getAttributeSelection() const +{ + QList> aList; + if(myFeature) { + DataPtr aData = myFeature->data(); + AttributeSelectionListPtr aSelList = + aData->selectionList(FeaturesPlugin_Fillet::ARRAY_POINT_RADIUS_BY_POINTS()); + AttributeSelectionPtr aAttr; + ObjectPtr anObject; + for (int i = 0; i < aSelList->size(); i++) { + aAttr = aSelList->value(i); + ModuleBase_ViewerPrsPtr + aPrs(new ModuleBase_ViewerPrs(aAttr->context(), aAttr->value(), NULL)); + aList.append(aPrs); + } + } + return aList; +} + +//********************************************************************************** +ModelAPI_AttributeTables::Value FeaturesPlugin_WidgetFilletMultiRadiuses::getValue(QString theStrVal) const +{ + ModelAPI_AttributeTables::Value aVal; + aVal.myDouble = theStrVal.toDouble(); + return aVal; +} + +//********************************************************************************** +QString FeaturesPlugin_WidgetFilletMultiRadiuses::findRadius(QString thename) const +{ + AttributeTablesPtr aTablesAttr; + + if(myTypeMethodeBypoint) + aTablesAttr = myFeature->data()->tables(FeaturesPlugin_Fillet::VALUES_ID()); + else + aTablesAttr = myFeature->data()->tables(FeaturesPlugin_Fillet::VALUES_CURV_ID()); + + for(int i = 0; i < aTablesAttr->rows(); ++i) + { + ModelAPI_AttributeTables::Value aVal = aTablesAttr->value( i, 0) ; + if( getValueText(aVal) == thename ) + { + aVal = aTablesAttr->value( i, 1); + return getValueText(aVal); + } + } + return "0.5"; +} + +//********************************************************************************** +QString FeaturesPlugin_WidgetFilletMultiRadiuses::getValueText(ModelAPI_AttributeTables::Value& theVal) const +{ + + return QString::number(theVal.myDouble); +} diff --git a/src/FeaturesPlugin/FeaturesPlugin_WidgetFilletMultiRadiuses.h b/src/FeaturesPlugin/FeaturesPlugin_WidgetFilletMultiRadiuses.h new file mode 100644 index 000000000..b29b1e23d --- /dev/null +++ b/src/FeaturesPlugin/FeaturesPlugin_WidgetFilletMultiRadiuses.h @@ -0,0 +1,167 @@ +// Copyright (C) 2014-2020 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 FeaturesPlugin_WidgetFilletMultiRadiuses_H +#define FeaturesPlugin_WidgetFilletMultiRadiuses_H + +#include "FeaturesPlugin.h" + +#include +#include +#include + +#include +#include +#include + +class QWidget; +class QLabel; +class QTableWidget; +class QPushButton; +class QTableWidgetItem; +class QLineEdit; + +class DataArrayItemDelegate : public QStyledItemDelegate +{ + Q_OBJECT +public: + DataArrayItemDelegate(bool theTypeMethode); + + virtual QWidget* createEditor(QWidget* theParent, + const QStyleOptionViewItem & theOption, + const QModelIndex& theIndex) const; + +private slots: + void onEditItem(const QString& theText); + +private: + bool myTypeMethodePoint; +}; + + +/*! + * \ingroup GUI + * Represent a content of the property panel to show/modify parameters of a Field feature. + */ +class FeaturesPlugin_WidgetFilletMultiRadiuses : public ModuleBase_WidgetSelector +{ + Q_OBJECT +public: + FeaturesPlugin_WidgetFilletMultiRadiuses(QWidget* theParent, + ModuleBase_IWorkshop* theWorkshop, + const Config_WidgetAPI* theData, + bool TypeMethodeBypoint); + + virtual ~FeaturesPlugin_WidgetFilletMultiRadiuses() {} + + /// Returns true if the event is processed. + virtual bool processEnter(); + + /// The methiod called when widget is deactivated + virtual void deactivate(); + + /// Checks the widget validity. By default, it returns true. + /// \param thePrs a selected presentation in the view + /// \return a boolean value + virtual bool isValidSelectionCustom(const std::shared_ptr& theValue); + +protected: + /// Saves the internal parameters to the given feature + /// \return True in success + virtual bool storeValueCustom(); + + /// Restore value from attribute data to the widget's control + virtual bool restoreValueCustom(); + + /// Redefinition of virtual function + /// \param theObject an object for the event + /// \param theEvent an event + virtual bool eventFilter(QObject* theObject, QEvent* theEvent); + + //virtual void showEvent(QShowEvent* theEvent); + + /// Returns list of widget controls + /// \return a control list + virtual QList getControls() const; + + /// Set the given wrapped value to the current widget + /// This value should be processed in the widget according to the needs + /// \param theValues the wrapped selection values + /// \param theToValidate a validation of the values flag + virtual bool setSelection(QList>& theValues, + const bool theToValidate); + + /// Return the attribute values wrapped in a list of viewer presentations + /// \return a list of viewer presentations, which contains an attribute result and + /// a shape. If the attribute do not uses the shape, it is empty + virtual QList> getAttributeSelection() const; + +private slots: + + /// Slot called on add a step + void onAddStep(); + + /// Slot called on remove a step + void onRemoveStep(); + + /// Retunrs a list of possible shape types + /// \return a list of shapes + virtual QIntList shapeTypes() const; + + /// Slot called on editing of a table cell + /// \param theRow a row of the cell + /// \param theCol a column of the cell + void onTableEdited(int theRow, int theCol); + + +private: + + /// Return a value from the string + /// \param theStrVal a string + ModelAPI_AttributeTables::Value getValue(QString theStrVal) const; + + /// Return a QString from the ModelAPI_AttributeTables + /// \param theStrVal a string + QString getValueText(ModelAPI_AttributeTables::Value& theVal) const; + + /// Return a radii value from the name + /// \param theStrVal a string + QString findRadius(QString thename) const; + + /// tables + QTableWidget* myDataTbl; + + /// Remove button + QPushButton* myRemoveBtn; + + /// Editor for table header + QLineEdit* myHeaderEditor; + + bool myTypeMethodeBypoint; + + bool mySetSelection; + + DataArrayItemDelegate* myDelegate; + + std::vector myfirstRowValue; + std::vector myLastRowValue; + +}; + +#endif \ No newline at end of file diff --git a/src/FeaturesPlugin/FeaturesPlugin_msg_fr.ts b/src/FeaturesPlugin/FeaturesPlugin_msg_fr.ts index 6f821a2e2..aeebd768d 100644 --- a/src/FeaturesPlugin/FeaturesPlugin_msg_fr.ts +++ b/src/FeaturesPlugin/FeaturesPlugin_msg_fr.ts @@ -924,6 +924,10 @@ Fillet:main_objects + + Faces, edges or/and solids + Faces, arêtes ou/et solides + Faces or/and edges Faces ou/et arêtes diff --git a/src/FeaturesPlugin/Test/TestSymmetry_Part.py b/src/FeaturesPlugin/Test/TestSymmetry_Part.py index 478bf3770..e1853ee74 100644 --- a/src/FeaturesPlugin/Test/TestSymmetry_Part.py +++ b/src/FeaturesPlugin/Test/TestSymmetry_Part.py @@ -38,4 +38,4 @@ model.testNbSubShapes(Symmetry_3, GeomAPI_Shape.SOLID, [1, 1]) model.testNbSubShapes(Symmetry_3, GeomAPI_Shape.FACE, [6, 6]) model.testNbSubShapes(Symmetry_3, GeomAPI_Shape.EDGE, [24, 24]) model.testNbSubShapes(Symmetry_3, GeomAPI_Shape.VERTEX, [48, 48]) -model.testResultsVolumes(Symmetry_3, [1000, 1000]) +model.testResultsVolumes(Symmetry_3, [-1000, 1000]) diff --git a/src/FeaturesPlugin/extrusion_widget.xml b/src/FeaturesPlugin/extrusion_widget.xml index df1631146..94a9d4bc3 100644 --- a/src/FeaturesPlugin/extrusion_widget.xml +++ b/src/FeaturesPlugin/extrusion_widget.xml @@ -5,7 +5,7 @@ 1. Planar face of non-sketch object or a plane. Sketch creation will be started.<br /> 2. An existing sketch face or contour. Extrusion will be filled by it.<br /> 3. An existing result shape of kind: wires/edge/vertices. Extrusion will be filled by it." - shape_types="Vertices Edges Faces|Wires" + shape_types="Vertices Edges Faces" type_icons=":/icons/extrusion_vertex32.png :/icons/extrusion_edge32.png :/icons/extrusion_face32.png" default_type = "2" use_choice="true"> @@ -14,7 +14,7 @@ @@ -16,7 +16,7 @@ label="Select a sketch face" icon="icons/Features/sketch.png" tooltip="Select a sketch face" - shape_types="Vertices Edges Faces|Wire" + shape_types="Vertices Edges Faces" type_icons=":/icons/extrusion_vertex32.png :/icons/extrusion_edge32.png :/icons/extrusion_face32.png" default_type = "2" use_choice="true" diff --git a/src/FeaturesPlugin/fillet_widget.xml b/src/FeaturesPlugin/fillet_widget.xml index 7abb4a5df..d4c6fa624 100644 --- a/src/FeaturesPlugin/fillet_widget.xml +++ b/src/FeaturesPlugin/fillet_widget.xml @@ -5,10 +5,10 @@ tooltip="Fillet with fixed radius" icon="icons/Features/fillet_fixed_radius.png"> @@ -51,5 +51,44 @@ + + + + + + + + + + + + + + + + + + + + diff --git a/src/FeaturesPlugin/icons/fillet_multiradius_by_curv.png b/src/FeaturesPlugin/icons/fillet_multiradius_by_curv.png new file mode 100644 index 000000000..015d270bf Binary files /dev/null and b/src/FeaturesPlugin/icons/fillet_multiradius_by_curv.png differ diff --git a/src/FeaturesPlugin/icons/fillet_multiradius_by_point.png b/src/FeaturesPlugin/icons/fillet_multiradius_by_point.png new file mode 100644 index 000000000..53dbb0820 Binary files /dev/null and b/src/FeaturesPlugin/icons/fillet_multiradius_by_point.png differ diff --git a/src/FeaturesPlugin/icons/fillet_var_multiple_radiuses.png b/src/FeaturesPlugin/icons/fillet_var_multiple_radiuses.png new file mode 100644 index 000000000..56e4a78f3 Binary files /dev/null and b/src/FeaturesPlugin/icons/fillet_var_multiple_radiuses.png differ diff --git a/src/FeaturesPlugin/pipe_widget.xml b/src/FeaturesPlugin/pipe_widget.xml index ce17e7cd1..f3ad50514 100644 --- a/src/FeaturesPlugin/pipe_widget.xml +++ b/src/FeaturesPlugin/pipe_widget.xml @@ -2,7 +2,6 @@ diff --git a/src/FeaturesPlugin/plugin-Features.xml b/src/FeaturesPlugin/plugin-Features.xml index ba80beedd..74b60d59a 100644 --- a/src/FeaturesPlugin/plugin-Features.xml +++ b/src/FeaturesPlugin/plugin-Features.xml @@ -126,7 +126,7 @@ + icon="icons/Features/fillet.png" auto_preview="false" helpfile="filletFeature.html"> #include +#include +#include //================================================================================================= GeomAlgoAPI_Fillet::GeomAlgoAPI_Fillet(const GeomShapePtr& theBaseSolid, @@ -41,6 +43,17 @@ GeomAlgoAPI_Fillet::GeomAlgoAPI_Fillet(const GeomShapePtr& theBaseSolid, build(theBaseSolid, theFilletEdges, theStartRadius, theEndRadius); } +//================================================================================================= +GeomAlgoAPI_Fillet::GeomAlgoAPI_Fillet(const GeomShapePtr& theBaseSolid, + const ListOfShape& theFilletEdges, + const std::list& theCurvCoord, + const std::list& theRadiuses) +{ + if (theRadiuses.size()== 0 ) + return; + build(theBaseSolid, theFilletEdges,theCurvCoord, theRadiuses); +} + //================================================================================================= void GeomAlgoAPI_Fillet::build(const GeomShapePtr& theBaseSolid, const ListOfShape& theFilletEdges, @@ -84,3 +97,55 @@ void GeomAlgoAPI_Fillet::build(const GeomShapePtr& theBaseSolid, setShape(aShape); setDone(true); } + +//================================================================================================= +void GeomAlgoAPI_Fillet::build(const GeomShapePtr& theBaseSolid, + const ListOfShape& theFilletEdges, + const std::list& theCurvCoord, + const std::list& theRadiuses) +{ + if (!theBaseSolid || theFilletEdges.empty() || theRadiuses.size() == 0) + return; + + // create fillet builder + BRepFilletAPI_MakeFillet* aFilletBuilder = + new BRepFilletAPI_MakeFillet(theBaseSolid->impl()); + setImpl(aFilletBuilder); + setBuilderType(OCCT_BRepBuilderAPI_MakeShape); + + // assign filleting edges + for (ListOfShape::const_iterator anIt = theFilletEdges.begin(); + anIt != theFilletEdges.end(); ++anIt) { + if ((*anIt)->isEdge()) + aFilletBuilder->Add( (*anIt)->impl() ); + } + + TColgp_Array1OfPnt2d array(1, theRadiuses.size()); + + int i = 1; + std::list::const_iterator itCurv = theCurvCoord.begin(); + std::list::const_iterator itRadius = theRadiuses.begin(); + + for( ; itCurv != theCurvCoord.end(); ++itCurv, ++itRadius ) + { + array.SetValue(i, gp_Pnt2d( (*itCurv) , (*itRadius))); + std::cout << "Value lance " << (*itCurv) << " "<< (*itRadius) << std::endl; + i++; + } + // assign fillet radii for each contour of filleting edges + int aNbContours = aFilletBuilder->NbContours(); + for (int ind = 1; ind <= aNbContours; ++ind) { + aFilletBuilder->SetRadius(array, ind, 1); + } + + // build and get result + aFilletBuilder->Build(); + if (!aFilletBuilder->IsDone()) + return; + TopoDS_Shape aResult = GeomAlgoAPI_DFLoader::refineResult(aFilletBuilder->Shape()); + + std::shared_ptr aShape(new GeomAPI_Shape()); + aShape->setImpl(new TopoDS_Shape(aResult)); + setShape(aShape); + setDone(true); +} \ No newline at end of file diff --git a/src/GeomAlgoAPI/GeomAlgoAPI_Fillet.h b/src/GeomAlgoAPI/GeomAlgoAPI_Fillet.h index f986933df..175a88717 100644 --- a/src/GeomAlgoAPI/GeomAlgoAPI_Fillet.h +++ b/src/GeomAlgoAPI/GeomAlgoAPI_Fillet.h @@ -24,6 +24,7 @@ #include #include +#include /// \class GeomAlgoAPI_Fillet /// \ingroup DataAlgo @@ -48,6 +49,16 @@ public: const ListOfShape& theFilletEdges, const double theStartRadius, const double theEndRadius); + + /// Run fillet operation with variable radius. + /// \param theBaseSolid a changing solid + /// \param theFilletEdges list of edges the fillet is performed on + /// \param theRadiuses theradius of the fillet + GEOMALGOAPI_EXPORT GeomAlgoAPI_Fillet(const GeomShapePtr& theBaseSolid, + const ListOfShape& theFilletEdges, + const std::list& theCurvCoord, + const std::list& theRadiuses); + private: /// Perform fillet operation. @@ -60,6 +71,18 @@ private: const ListOfShape& theFilletEdges, const double theStartRadius, const double theEndRadius = -1.0); + + /// Perform fillet operation. + /// If theEndRadius is less than 0., the fixed radius fillet will be built. + /// \param theBaseSolid a changing solid + /// \param theFilletEdges list of edges the fillet is performed on + /// \param theCurvCoord the coordinate of a point defines a relative parameter on the edge + /// \param theRadiuses the corresponding value of the radius, and the radius evolves + // between the first and last vertices of the contour of index + void build(const GeomShapePtr& theBaseSolid, + const ListOfShape& theFilletEdges, + const std::list& theCurvCoord, + const std::list& theRadiuses); }; #endif diff --git a/src/GeomAlgoAPI/GeomAlgoAPI_STEPImport.cpp b/src/GeomAlgoAPI/GeomAlgoAPI_STEPImport.cpp index 3a824f106..9e20ba201 100644 --- a/src/GeomAlgoAPI/GeomAlgoAPI_STEPImport.cpp +++ b/src/GeomAlgoAPI/GeomAlgoAPI_STEPImport.cpp @@ -54,22 +54,36 @@ #include #include #include -#include +#include +#include +#include +#include +#include +#include +#include +#include +#include #include +#include #include #include // CAREFUL ! position of this file is critic : see Lucien PIGNOLONI / OCC + +// ---------------------------------------------------------------------------- + std::shared_ptr STEPImport(const std::string& theFileName, const std::string& theFormatName, + const bool anScalInterUnits, std::string& theError) { + TopoDS_Shape aResShape; // Set "C" numeric locale to save numbers correctly // Kernel_Utils::Localizer loc; - + STEPControl_Reader aReader; //VSR: 16/09/09: Convert to METERS @@ -89,7 +103,7 @@ std::shared_ptr STEPImport(const std::string& theFileName, if (status == IFSelect_RetDone) { // Regard or not the model units - if (theFormatName == "STEP_SCALE") { + if (!anScalInterUnits) { // set UnitFlag to units from file TColStd_SequenceOfAsciiString anUnitLengthNames; TColStd_SequenceOfAsciiString anUnitAngleNames; @@ -194,3 +208,83 @@ std::shared_ptr STEPImport(const std::string& theFileName, aGeomShape->setImpl(new TopoDS_Shape(aResShape)); return aGeomShape; } + + +std::shared_ptr STEPImportAttributs(const std::string& theFileName, + std::shared_ptr theResultBody, + const bool anScalInterUnits, + const bool anMaterials, + const bool anColor, + std::map< std::wstring, std::list> &theMaterialShape, + std::string& theError) +{ + + STEPControl_Reader aReader; + std::shared_ptr aGeomShape(new GeomAPI_Shape); + //VSR: 16/09/09: Convert to METERS + Interface_Static::SetCVal("xstep.cascade.unit","M"); + Interface_Static::SetIVal("read.step.ideas", 1); + Interface_Static::SetIVal("read.step.nonmanifold", 1); + + try { + OCC_CATCH_SIGNALS; + + IFSelect_ReturnStatus status = aReader.ReadFile(theFileName.c_str()); + + if (status == IFSelect_RetDone) { + + // Regard or not the model units + if (!anScalInterUnits) { + // set UnitFlag to units from file + TColStd_SequenceOfAsciiString anUnitLengthNames; + TColStd_SequenceOfAsciiString anUnitAngleNames; + TColStd_SequenceOfAsciiString anUnitSolidAngleNames; + aReader.FileUnits(anUnitLengthNames, anUnitAngleNames, anUnitSolidAngleNames); + if (anUnitLengthNames.Length() > 0) { + TCollection_AsciiString aLenUnits = anUnitLengthNames.First(); + if (aLenUnits == "millimetre") + Interface_Static::SetCVal("xstep.cascade.unit", "MM"); + else if (aLenUnits == "centimetre") + Interface_Static::SetCVal("xstep.cascade.unit", "CM"); + else if (aLenUnits == "metre" || aLenUnits.IsEmpty()) + Interface_Static::SetCVal("xstep.cascade.unit", "M"); + else if (aLenUnits == "INCH") + Interface_Static::SetCVal("xstep.cascade.unit", "INCH"); + else { + theError = "The file contains not supported units."; + aGeomShape->setImpl(new TopoDS_Shape()); + return aGeomShape; + } + // TODO (for other units than mm, cm, m or inch) + //else if (aLenUnits == "") + // Interface_Static::SetCVal("xstep.cascade.unit", "???"); + } + } + else { + //cout<<"need re-scale a model"<setImpl(new TopoDS_Shape()); + return aGeomShape; + } + + STEPCAFControl_Reader cafreader; + cafreader.SetColorMode(true); + cafreader.SetNameMode(true); + cafreader.SetMatMode(true); + + if(cafreader.ReadFile(theFileName.c_str()) != IFSelect_RetDone) { + theError = "Wrong format of the imported file. Can't import file."; + std::shared_ptr aGeomShape(new GeomAPI_Shape); + aGeomShape->setImpl(new TopoDS_Shape()); + return aGeomShape; + } + + return readAttributes(cafreader,theResultBody,anMaterials, theMaterialShape, "STEP-XCAF"); + } + diff --git a/src/GeomAlgoAPI/GeomAlgoAPI_STEPImport.h b/src/GeomAlgoAPI/GeomAlgoAPI_STEPImport.h index 470791a3b..9433a0a70 100644 --- a/src/GeomAlgoAPI/GeomAlgoAPI_STEPImport.h +++ b/src/GeomAlgoAPI/GeomAlgoAPI_STEPImport.h @@ -23,13 +23,26 @@ #include #include - #include +#include + + /// Implementation of the import STEP files algorithms GEOMALGOAPI_EXPORT std::shared_ptr STEPImport(const std::string& theFileName, const std::string& theFormatName, + const bool anScalInterUnits, std::string& theError); +/// Implementation of the import STEP files algorithms with Attributs (Name, Color, Materials) +GEOMALGOAPI_EXPORT +std::shared_ptr STEPImportAttributs(const std::string& theFileName, + std::shared_ptr theResultBody, + const bool anScalInterUnits, + const bool anMaterials, + const bool anColor, + std::map< std::wstring, std::list> &theMaterialShape, + std::string& theError); + #endif /* GEOMALGOAPI_STEPIMPORT_H_ */ diff --git a/src/GeomAlgoAPI/GeomAlgoAPI_STEPImportXCAF.cpp b/src/GeomAlgoAPI/GeomAlgoAPI_STEPImportXCAF.cpp new file mode 100644 index 000000000..3e2a700cf --- /dev/null +++ b/src/GeomAlgoAPI/GeomAlgoAPI_STEPImportXCAF.cpp @@ -0,0 +1,446 @@ +// Copyright (C) 2014-2020 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 + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include // CAREFUL ! position of this file is critic : see Lucien PIGNOLONI / OCC + + +//============================================================================= +/*! + * GetShape() + */ +//============================================================================= + +TopoDS_Shape GetShape(const Handle(Standard_Transient) &theEnti, + const Handle(Transfer_TransientProcess) &theTP) +{ + TopoDS_Shape aResult; + Handle(Transfer_Binder) aBinder = theTP->Find(theEnti); + + if (aBinder.IsNull()) { + return aResult; + } + + aResult = TransferBRep::ShapeResult(aBinder); + + return aResult; +} + +// ---------------------------------------------------------------------------- + +std::shared_ptr readAttributes( STEPCAFControl_Reader &reader, + std::shared_ptr theResultBody, + const bool anMaterials, + std::map< std::wstring, std::list> &theMaterialShape, + const std::string &format) +{ + // dummy XCAF Application to handle the STEP XCAF Document + Handle(XCAFApp_Application) dummy_app = XCAFApp_Application::GetApplication(); + // XCAF Document to contain the STEP/IGES file itself + Handle(TDocStd_Document) doc; + // check if a file is already open under this handle, if so, close it to + // prevent segfaults when trying to create a new document + if(dummy_app->NbDocuments() > 0) { + dummy_app->GetDocument(1, doc); + dummy_app->Close(doc); + } + + dummy_app->NewDocument( TCollection_ExtendedString("MDTV-CAF"), doc); + // transfer STEP/IGES into the document, and get the main label + reader.Transfer(doc); + TDF_Label mainLabel = doc->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); + // traverse the labels recursively to set attributes on shapes + setShapeAttributes(shapeTool, colorTool, materialTool, mainLabel, + TopLoc_Location(),theResultBody,theMaterialShape,false); + + + std::shared_ptr ageom = setgeom(shapeTool,mainLabel); + + STEPControl_Reader aReader = reader.ChangeReader(); + + // BEGIN: reading materials of sub-shapes from file + if ( anMaterials ) + { + TopTools_IndexedMapOfShape anIndices; + TopExp::MapShapes(ageom->impl(), anIndices); + + Handle(Interface_InterfaceModel) Model = aReader.WS()->Model(); + Handle(XSControl_TransferReader) TR = aReader.WS()->TransferReader(); + if (!TR.IsNull()) { + Handle(Transfer_TransientProcess) TP = TR->TransientProcess(); + + Standard_Integer nb = Model->NbEntities(); + + for (Standard_Integer ie = 1; ie <= nb; ie++) { + Handle(Standard_Transient) enti = Model->Value(ie); + + // Store materials. + StoreMaterial(theResultBody,enti, anIndices, TP, mainLabel,theMaterialShape); + } + } + } + + return ageom; +} + +std::shared_ptr setgeom(const Handle(XCAFDoc_ShapeTool) &shapeTool, + const TDF_Label &label) +{ + BRep_Builder B; + TopoDS_Compound compound; + B.MakeCompound(compound); + + TDF_LabelSequence frshapes; + shapeTool->GetShapes(frshapes); + + std::shared_ptr aGeomShape(new GeomAPI_Shape); + + if (frshapes.Length() == 0) { + aGeomShape->setImpl(new TopoDS_Shape()); + return aGeomShape; + } else if (frshapes.Length() == 1) { + TopoDS_Shape shape = shapeTool->GetShape(frshapes.Value(1)); + aGeomShape->setImpl(new TopoDS_Shape(shape)); + return aGeomShape; + } else { + for (Standard_Integer i=1; iGetShape(frshapes.Value(i)); + + TDF_Label aLabel = shapeTool->FindShape(S, Standard_False); + if ( (!aLabel.IsNull()) && (shapeTool->IsShape(aLabel)) ) { + if (shapeTool->IsFree(aLabel) ) { + if (S.IsNull()) { + continue; + } + else { + B.Add(compound, S); + } + } + } + } + TopoDS_Shape shape = compound; + aGeomShape->setImpl(new TopoDS_Shape(shape)); + return aGeomShape; + } +} + +void setShapeAttributes(const Handle(XCAFDoc_ShapeTool) &shapeTool, + const Handle(XCAFDoc_ColorTool) &colorTool, + const Handle(XCAFDoc_MaterialTool) &materialTool, + const TDF_Label &label, + const TopLoc_Location &loc, + std::shared_ptr theResultBody, + std::map< std::wstring, std::list> &theMaterialShape, + bool isRef) +{ + std::wstring shapeName; + Handle(TDataStd_Name) n; + + if(label.FindAttribute(TDataStd_Name::GetID(), n)) { + TCollection_ExtendedString name = n->Get(); + + shapeName = Locale::Convert::toWString(TCollection_AsciiString(name).ToCString()) ; + } + + TopLoc_Location partLoc = loc; + Handle(XCAFDoc_Location) l; + if(label.FindAttribute(XCAFDoc_Location::GetID(), l)) { + if(isRef) + partLoc = partLoc * l->Get(); + else + partLoc = l->Get(); + } + + TDF_Label ref; + if(shapeTool->IsReference(label) && shapeTool->GetReferredShape(label, ref)) { + + setShapeAttributes( shapeTool, colorTool, materialTool, ref, + partLoc,theResultBody,theMaterialShape,true); + } + + if( shapeTool->IsSimpleShape(label) && (isRef || shapeTool->IsFree(label))) { + + TopoDS_Shape shape = shapeTool->GetShape(label); + + std::shared_ptr aShapeGeom(new GeomAPI_Shape); + if (!loc.IsIdentity()){ + shape.Move(loc); + } + aShapeGeom->setImpl(new TopoDS_Shape(shape)); + shapeName = theResultBody->addShapeName(aShapeGeom, shapeName); + + + shape.Location(isRef ? loc : partLoc); + int dim = + (shape.ShapeType() == TopAbs_VERTEX) ? + 0 : + (shape.ShapeType() == TopAbs_EDGE || shape.ShapeType() == TopAbs_WIRE) ? + 1 : + (shape.ShapeType() == TopAbs_FACE || + shape.ShapeType() == TopAbs_SHELL) ? 2 :3; + + Handle(TCollection_HAsciiString) matName; + Handle(TCollection_HAsciiString) matDescription; + Standard_Real matDensity; + Handle(TCollection_HAsciiString) matDensName; + Handle(TCollection_HAsciiString) matDensValType; + + if(materialTool->GetMaterial(label, matName, matDescription, matDensity, + matDensName, matDensValType)) { + std::wstring nameMaterial = Locale::Convert::toWString(matName->ToCString()); + + theMaterialShape[nameMaterial].push_back(shapeName); + } + + + Quantity_Color col; + if(colorTool->GetColor(label, XCAFDoc_ColorGen, col)) { + double r = col.Red(), g = col.Green(), b = col.Blue(); + std::vector ColRGB = {int(r*255),int(g*255),int(b*255)}; + theResultBody->addShapeColor(shapeName, ColRGB); + } + else if(colorTool->GetColor(label, XCAFDoc_ColorSurf, col)) { + double r = col.Red(), g = col.Green(), b = col.Blue(); + std::vector ColRGB = {int(r*255),int(g*255),int(b*255)}; + theResultBody->addShapeColor(shapeName, ColRGB); + } + else if(colorTool->GetColor(label, XCAFDoc_ColorCurv, col)) { + double r = col.Red(), g = col.Green(), b = col.Blue(); + std::vector ColRGB = {int(r*255),int(g*255),int(b*255)}; + theResultBody->addShapeColor(shapeName, ColRGB); + } + // check explicit coloring of boundary entities + if(dim == 3) { + TopExp_Explorer xp2(shape, TopAbs_FACE); + while(xp2.More()) { + if(colorTool->GetColor(xp2.Current(), XCAFDoc_ColorGen, col) || + colorTool->GetColor(xp2.Current(), XCAFDoc_ColorSurf, col) || + colorTool->GetColor(xp2.Current(), XCAFDoc_ColorCurv, col)) { + double r = col.Red(), g = col.Green(), b = col.Blue(); + TopoDS_Face face = TopoDS::Face(xp2.Current()); + std::vector ColRGB = {int(r*255),int(g*255),int(b*255)}; + std::wstringstream aNameFace; + TopoDS_Shape shapeface = xp2.Current(); + if (!loc.IsIdentity()){ + shapeface.Move(loc); + } + aShapeGeom->setImpl(new TopoDS_Shape(shapeface)); + theResultBody->addShapeColor( + theResultBody->addShapeName(aShapeGeom , aNameFace.str()), ColRGB); + } + xp2.Next(); + } + } + if(dim == 2) { + TopExp_Explorer xp1(shape, TopAbs_EDGE); + while(xp1.More()) { + if(colorTool->GetColor(xp1.Current(), XCAFDoc_ColorGen, col) || + colorTool->GetColor(xp1.Current(), XCAFDoc_ColorSurf, col) || + colorTool->GetColor(xp1.Current(), XCAFDoc_ColorCurv, col)) { + double r = col.Red(), g = col.Green(), b = col.Blue(); + std::vector ColRGB = {int(r*255),int(g*255),int(b*255)}; + std::wstringstream aNameEdge; + aNameEdge << L"Edge_"<< shapeName; + aShapeGeom->setImpl(new TopoDS_Shape(xp1.Current() )); + theResultBody->addShapeColor( + theResultBody->addShapeName(aShapeGeom , aNameEdge.str()), ColRGB); + } + xp1.Next(); + } + } + } + else { + int indiceChild = 1; + + if (!shapeTool->IsReference(label)){ + TopoDS_Shape shape = shapeTool->GetShape(label); + + std::shared_ptr aShapeGeom(new GeomAPI_Shape); + if (!loc.IsIdentity()){ + shape.Move(loc); + } + aShapeGeom->setImpl(new TopoDS_Shape(shape)); + shapeName = theResultBody->addShapeName(aShapeGeom, shapeName); + } + for(TDF_ChildIterator it(label); it.More(); it.Next()) { + + setShapeAttributes( shapeTool, colorTool, materialTool, + it.Value(), partLoc,theResultBody,theMaterialShape, isRef); + indiceChild++; + } + } +} + + +//============================================================================= + /*! + * StoreMaterial() + */ + //============================================================================= + + void StoreMaterial( std::shared_ptr theResultBody, + const Handle(Standard_Transient) &theEnti, + const TopTools_IndexedMapOfShape &theIndices, + const Handle(Transfer_TransientProcess) &theTP, + const TDF_Label &theShapeLabel, + std::map< std::wstring, std::list> &theMaterialShape ) + { + // Treat Product Definition Shape only. + Handle(StepRepr_ProductDefinitionShape) aPDS = + Handle(StepRepr_ProductDefinitionShape)::DownCast(theEnti); + Handle(StepBasic_ProductDefinition) aProdDef; + + if(aPDS.IsNull() == Standard_False) { + // Product Definition Shape ==> Product Definition + aProdDef = aPDS->Definition().ProductDefinition(); + } + + if (aProdDef.IsNull() == Standard_False) { + // Product Definition ==> Property Definition + const Interface_Graph &aGraph = theTP->Graph(); + Interface_EntityIterator aSubs = aGraph.Sharings(aProdDef); + TopoDS_Shape aShape; + + for(aSubs.Start(); aSubs.More(); aSubs.Next()) { + Handle(StepRepr_PropertyDefinition) aPropD = + Handle(StepRepr_PropertyDefinition)::DownCast(aSubs.Value()); + + if(aPropD.IsNull() == Standard_False) { + // Property Definition ==> Representation. + Interface_EntityIterator aSubs1 = aGraph.Sharings(aPropD); + + for(aSubs1.Start(); aSubs1.More(); aSubs1.Next()) { + Handle(StepRepr_PropertyDefinitionRepresentation) aPDR = + Handle(StepRepr_PropertyDefinitionRepresentation):: + DownCast(aSubs1.Value()); + + if(aPDR.IsNull() == Standard_False) { + // Property Definition ==> Material Name. + Handle(StepRepr_Representation) aRepr = aPDR->UsedRepresentation(); + + if(aRepr.IsNull() == Standard_False) { + Standard_Integer ir; + + for(ir = 1; ir <= aRepr->NbItems(); ir++) { + Handle(StepRepr_RepresentationItem) aRI = aRepr->ItemsValue(ir); + Handle(StepRepr_DescriptiveRepresentationItem) aDRI = + Handle(StepRepr_DescriptiveRepresentationItem)::DownCast(aRI); + + if(aDRI.IsNull() == Standard_False) { + // Get shape from Product Definition + Handle(TCollection_HAsciiString) aMatName = aDRI->Name(); + if(aMatName.IsNull() == Standard_False) { + TCollection_ExtendedString + aMatNameExt (aMatName->ToCString()); + + if (aShape.IsNull()) { + //Get the shape. + aShape = GetShape(aProdDef, theTP); + if (aShape.IsNull()) { + return; + } + } + + // as PRODUCT can be included in the main shape + // several times, we look here for all iclusions. + Standard_Integer isub, nbSubs = theIndices.Extent(); + + for (isub = 1; isub <= nbSubs; isub++) { + TopoDS_Shape aSub = theIndices.FindKey(isub); + + if (aSub.IsPartner(aShape)) { + std::shared_ptr aShapeGeom(new GeomAPI_Shape); + aShapeGeom->setImpl(new TopoDS_Shape(aSub)); + std::wstring nom = theResultBody->findShapeName(aShapeGeom); + std::wstring matName= Locale::Convert::toWString(aMatName->ToCString()); + theMaterialShape[matName].push_back(nom); + + } + } + } + } + } + } + } + } + } + } + } + } + diff --git a/src/GeomAlgoAPI/GeomAlgoAPI_STEPImportXCAF.h b/src/GeomAlgoAPI/GeomAlgoAPI_STEPImportXCAF.h new file mode 100644 index 000000000..2955a5308 --- /dev/null +++ b/src/GeomAlgoAPI/GeomAlgoAPI_STEPImportXCAF.h @@ -0,0 +1,74 @@ +// Copyright (C) 2014-2020 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 GEOMALGOAPI_STEPIMPORTXCAF_H_ +#define GEOMALGOAPI_STEPIMPORTXCAF_H_ + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include + + // read Attributs of step file + GEOMALGOAPI_EXPORT + std::shared_ptr readAttributes( STEPCAFControl_Reader &reader, + std::shared_ptr theResultBody, + const bool anMaterials, + std::map< std::wstring, std::list> &theMaterialShape, + const std::string &format); + // read attributs for label + GEOMALGOAPI_EXPORT + void setShapeAttributes(const Handle(XCAFDoc_ShapeTool) &shapeTool, + const Handle(XCAFDoc_ColorTool) &colorTool, + const Handle(XCAFDoc_MaterialTool) &materialTool, + const TDF_Label &label, + const TopLoc_Location &loc, + std::shared_ptr theResultBody, + std::map< std::wstring, std::list> &theMaterialShape, + bool isRef); + +// read geometry +GEOMALGOAPI_EXPORT +std::shared_ptr setgeom(const Handle(XCAFDoc_ShapeTool) &shapeTool, + const TDF_Label &label); + +// store Materiel for theShapeLabel in the map theMaterialShape +GEOMALGOAPI_EXPORT +void StoreMaterial( std::shared_ptr theResultBody, + const Handle(Standard_Transient) &theEnti, + const TopTools_IndexedMapOfShape &theIndices, + const Handle(Transfer_TransientProcess) &theTP, + const TDF_Label &theShapeLabel, + std::map< std::wstring, std::list> &theMaterialShape ); + +#endif /* GEOMALGOAPI_STEPIMPORTXCAF_H_ */ diff --git a/src/GeomAlgoAPI/GeomAlgoAPI_STLExport.cpp b/src/GeomAlgoAPI/GeomAlgoAPI_STLExport.cpp new file mode 100644 index 000000000..e7d82b642 --- /dev/null +++ b/src/GeomAlgoAPI/GeomAlgoAPI_STLExport.cpp @@ -0,0 +1,88 @@ +// Copyright (C) 2014-2020 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 "GeomAlgoAPI_STLExport.h" + +#include "GeomAlgoAPI_Tools.h" + +#include + +// OOCT includes +#include +#include +#include +#include +#include +#include +#include + + + +#define MAX2(X, Y) ( Abs(X) > Abs(Y) ? Abs(X) : Abs(Y) ) +#define MAX3(X, Y, Z) ( MAX2 ( MAX2(X, Y) , Z ) ) + +bool STLExport(const std::string& theFileName, + const std::string& /*theFormatName*/, + const std::shared_ptr& theShape, + const double aDeflection, + const bool anIsRelative, + const bool anIsASCII, + std::string& theError) +{ + #ifdef _DEBUG + std::cout << "Export STl into file " << theFileName << std::endl; + #endif + + if (!theShape.get()) { + theError = "STl Export failed: An invalid argument"; + return false; + } + + try + { + // Set "C" numeric locale to save numbers correctly + GeomAlgoAPI_Tools::Localizer loc; + + double lDeflection = aDeflection; + StlAPI_Writer aWriter; + // copy source shape + BRepBuilderAPI_Copy aCopy( theShape->impl(), Standard_False ); + TopoDS_Shape aCopyShape = aCopy.Shape(); + // ASCII mode + aWriter.ASCIIMode() = anIsASCII; + if ( anIsRelative ) { + Standard_Real aXmin, aYmin, aZmin, aXmax, aYmax, aZmax; + Bnd_Box bndBox; + BRepBndLib::Add( theShape->impl(), bndBox ); + bndBox.Get( aXmin, aYmin, aZmin, aXmax, aYmax, aZmax ); + lDeflection = MAX3( aXmax-aXmin, aYmax-aYmin, aZmax-aZmin ) * aDeflection; + } + //Compute triangulation + BRepTools::Clean( aCopyShape ); + BRepMesh_IncrementalMesh aMesh( aCopyShape, lDeflection ); + aWriter.Write( aCopyShape, theFileName.c_str() ); + + return true; + } + catch( Standard_Failure ) + { + theError = "Exception catched in STlExport"; + } + return false; +} diff --git a/src/GeomAlgoAPI/GeomAlgoAPI_STLExport.h b/src/GeomAlgoAPI/GeomAlgoAPI_STLExport.h new file mode 100644 index 000000000..327dce41e --- /dev/null +++ b/src/GeomAlgoAPI/GeomAlgoAPI_STLExport.h @@ -0,0 +1,39 @@ +// Copyright (C) 2014-2020 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 GEOMALGOAPI_STLEXPORT_H_ +#define GEOMALGOAPI_STLEXPORT_H_ + +#include + +#include + +#include + +/// Implementation of the export STL files algorithms +GEOMALGOAPI_EXPORT +bool STLExport(const std::string& theFileName, + const std::string& /*theFormatName*/, + const std::shared_ptr& theShape, + const double aDeflection, + const bool anIsRelative, + const bool anIsASCII, + std::string& theError); + +#endif /* GEOMALGOAPI_STLEXPORT_H_ */ diff --git a/src/Model/Model_Objects.cpp b/src/Model/Model_Objects.cpp index 2c32988e2..63380e3e2 100644 --- a/src/Model/Model_Objects.cpp +++ b/src/Model/Model_Objects.cpp @@ -1226,7 +1226,8 @@ bool Model_Objects::hasCustomName(DataPtr theFeatureData, void Model_Objects::storeResult(std::shared_ptr theFeatureData, std::shared_ptr theResult, - const int theResultIndex) + const int theResultIndex, + const std::wstring& theNameShape) { theResult->init(); theResult->setDoc(myDoc); @@ -1240,11 +1241,15 @@ void Model_Objects::storeResult(std::shared_ptr theFeatureData, theResult->data()->setName(L""); } else { std::wstringstream aName; - aName << aNewName; - // if there are several results (issue #899: any number of result), - // add unique prefix starting from second - if (theResultIndex > 0 || theResult->groupName() == ModelAPI_ResultBody::group()) - aName << "_" << theResultIndex + 1; + if( theNameShape != L"" ){ + aName << theNameShape; + }else{ + aName << aNewName; + // if there are several results (issue #899: any number of result), + // add unique prefix starting from second + if (theResultIndex > 0 || theResult->groupName() == ModelAPI_ResultBody::group()) + aName << "_" << theResultIndex + 1; + } aNewName = aName.str(); } theResult->data()->setName(aNewName); @@ -1269,7 +1274,7 @@ std::shared_ptr Model_Objects::createConstruction( } std::shared_ptr Model_Objects::createBody( - const std::shared_ptr& theFeatureData, const int theIndex) + const std::shared_ptr& theFeatureData, const int theIndex,const std::wstring& theNameShape ) { TDF_Label aLab = resultLabel(theFeatureData, theIndex); TDataStd_Comment::Set(aLab, ModelAPI_ResultBody::group().c_str()); @@ -1280,7 +1285,7 @@ std::shared_ptr Model_Objects::createBody( } if (!aResult.get()) { aResult = std::shared_ptr(new Model_ResultBody); - storeResult(theFeatureData, aResult, theIndex); + storeResult(theFeatureData, aResult, theIndex,theNameShape); } return aResult; } diff --git a/src/Model/Model_Objects.h b/src/Model/Model_Objects.h index c929be8ce..fe3811543 100644 --- a/src/Model/Model_Objects.h +++ b/src/Model/Model_Objects.h @@ -124,7 +124,8 @@ class Model_Objects const std::shared_ptr& theFeatureData, const int theIndex = 0); /// Creates a body result std::shared_ptr createBody( - const std::shared_ptr& theFeatureData, const int theIndex = 0); + const std::shared_ptr& theFeatureData, const int theIndex = 0, + const std::wstring& theNameShape = L""); /// Creates a part result std::shared_ptr createPart( const std::shared_ptr& theFeatureData, const int theIndex = 0); @@ -219,12 +220,13 @@ class Model_Objects //! Initializes the data fields of the feature void initData(ObjectPtr theObj, TDF_Label theLab, const int theTag); - - //! Allows to store the result in the data tree of the document + + //! Allows to store the result in the data tree of the document //! (attaches 'data' of result to tree) void storeResult(std::shared_ptr theFeatureData, std::shared_ptr theResult, - const int theResultIndex = 0); + const int theResultIndex = 0, + const std::wstring& theNameShape = L""); //! returns the label of result by index; creates this label if it was not created before TDF_Label resultLabel(const std::shared_ptr& theFeatureData, diff --git a/src/Model/Model_ResultBody.cpp b/src/Model/Model_ResultBody.cpp index 7d6918c6a..74b932c81 100644 --- a/src/Model/Model_ResultBody.cpp +++ b/src/Model/Model_ResultBody.cpp @@ -30,6 +30,8 @@ #include #include #include +#include +#include #include #include @@ -233,6 +235,54 @@ void Model_ResultBody::updateConcealment() } } +void Model_ResultBody::addShapeColor( const std::wstring& theName,std::vector& color) { + + if( myColorsShape.find(theName) == myColorsShape.end()) + myColorsShape[ theName ] = color; +} + +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() ){ + aName.str(L""); + aName << theName << L"__" << indice; + indice++; + } + myNamesShape[ aName.str() ] = theshape; + + return aName.str(); +} + +std::wstring Model_ResultBody::findShapeName(std::shared_ptr theshape){ + + TopoDS_Shape aShape = theshape->impl(); + for (std::map< std::wstring, std::shared_ptr >::iterator it = myNamesShape.begin(); + it != myNamesShape.end(); + ++it) + { + TopoDS_Shape curSelectedShape = (*it).second->impl(); + if( (aShape.IsSame(curSelectedShape))) { + return (*it).first; + } + + } + return L"material not found" ; +} + + +void Model_ResultBody::setShapeName(std::map< std::wstring, std::shared_ptr > &theshapename, + std::map< std::wstring, std::vector> & theColorsShape) +{ + myNamesShape = theshapename; + myColorsShape = theColorsShape; +} +void Model_ResultBody::clearShapeNameAndColor(){ + myNamesShape.clear(); + myColorsShape.clear(); +} void Model_ResultBody::updateSubs(const std::shared_ptr& theThisShape, const bool theShapeChanged) { @@ -262,13 +312,31 @@ void Model_ResultBody::updateSubs(const std::shared_ptr& theThisS aShape->setImpl(new TopoDS_Shape(aShapesIter.Value())); ResultBodyPtr aSub; if (mySubs.size() <= aSubIndex) { // it is needed to create a new sub-result - aSub = anObjects->createBody(this->data(), aSubIndex); + std::wstring thenameshape = L""; + // find shape name read + for (std::map< std::wstring, std::shared_ptr >::iterator it = myNamesShape.begin(); + it != myNamesShape.end(); + ++it) + { + TopoDS_Shape curSelectedShape = (*it).second->impl(); + if( !(aShapesIter.Value().IsSame(curSelectedShape))) continue; + thenameshape = (*it).first; + break; + } + aSub = anObjects->createBody(this->data(), aSubIndex,thenameshape); + //finf color read + std::map< std::wstring, std::vector>::iterator itColor = myColorsShape.find(thenameshape); + if(itColor != myColorsShape.end()){ + ModelAPI_Tools::setColor(aSub,(*itColor).second); + } + aSub->setShapeName(myNamesShape,myColorsShape); mySubs.push_back(aSub); mySubsMap[aSub] = int(mySubs.size() - 1); if (isConcealed()) { // for issue #2579 note7 aSub->ModelAPI_ResultBody::setIsConcealed(true); std::dynamic_pointer_cast(aSub)->updateConcealment(); } + } else { // just update shape of this result aSub = mySubs[aSubIndex]; } diff --git a/src/Model/Model_ResultBody.h b/src/Model/Model_ResultBody.h index 94e9d9b7c..fe3987642 100644 --- a/src/Model/Model_ResultBody.h +++ b/src/Model/Model_ResultBody.h @@ -117,7 +117,7 @@ protected: /// Makes a body on the given feature Model_ResultBody(); - /// Updates the sub-bodies if shape of this object is composite-solid +/// Updates the sub-bodies if shape of this object is composite-solid void updateSubs(const std::shared_ptr& theThisShape, const bool theShapeChanged = true); @@ -134,6 +134,23 @@ protected: const std::list& theAllOlds, std::list& theOldForSub); friend class Model_Objects; + + // Add shape Name for read shape in step file + std::wstring addShapeName(std::shared_ptr,const std::wstring& theName) override; + // Add color for shape Name read shape in step file + void addShapeColor( const std::wstring& theName,std::vector& color) override; + // 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; + // find the name of shapp read in step file + std::wstring findShapeName(std::shared_ptr theshape) override; + // Clear the map of name and color read shape in step file + void clearShapeNameAndColor() override; + + // map with the name read in step file and shape + std::map< std::wstring, std::shared_ptr > myNamesShape; + // map with the name contruct and color read + std::map< std::wstring, std::vector> myColorsShape; + }; #endif diff --git a/src/Model/Model_Update.cpp b/src/Model/Model_Update.cpp index 9127a9915..a0dfe058a 100644 --- a/src/Model/Model_Update.cpp +++ b/src/Model/Model_Update.cpp @@ -190,14 +190,13 @@ bool Model_Update::addModified(FeaturePtr theFeature, FeaturePtr theReason) { #endif } // clear processed and fill modified recursively - std::set aRefSet; const std::set >& aRefs = theFeature->data()->refsToMe(); std::set >::const_iterator aRefIter = aRefs.cbegin(); for(; aRefIter != aRefs.cend(); aRefIter++) { if ((*aRefIter)->isArgument()) { FeaturePtr aReferenced = std::dynamic_pointer_cast((*aRefIter)->owner()); if (aReferenced.get()) { - aRefSet.insert(aReferenced); + addModified(aReferenced, theFeature); } } } @@ -212,21 +211,19 @@ bool Model_Update::addModified(FeaturePtr theFeature, FeaturePtr theReason) { if ((*aRIter)->isArgument()) { FeaturePtr aReferenced = std::dynamic_pointer_cast((*aRIter)->owner()); if (aReferenced.get()) { - aRefSet.insert(aReferenced); + addModified(aReferenced, theFeature); } } } } + // also add part feature that contains this feature to the modified if (theFeature->document()->kind() != "PartSet") { FeaturePtr aPart = ModelAPI_Tools::findPartFeature( ModelAPI_Session::get()->moduleDocument(), theFeature->document()); if (aPart.get()) - aRefSet.insert(aPart); + addModified(aPart, theFeature); } - for(std::set::iterator aRef = aRefSet.begin(); aRef != aRefSet.end(); aRef++) - addModified(*aRef, theFeature); - return true; } diff --git a/src/ModelAPI/CMakeLists.txt b/src/ModelAPI/CMakeLists.txt index dd2f4acd9..7b7876165 100644 --- a/src/ModelAPI/CMakeLists.txt +++ b/src/ModelAPI/CMakeLists.txt @@ -117,7 +117,7 @@ SET(PROJECT_SOURCES SET(PROJECT_LIBRARIES Config GeomAPI - Locale + ${OpenCASCADE_ApplicationFramework_LIBRARIES} ) SET(CMAKE_SWIG_FLAGS -threads -w325,321,362,383,302,403,451,473) ADD_DEFINITIONS(-DMODELAPI_EXPORTS) @@ -131,6 +131,10 @@ INCLUDE_DIRECTORIES(${PROJECT_SOURCE_DIR}/src/Config ${PROJECT_SOURCE_DIR}/src/GeomAPI ${PROJECT_SOURCE_DIR}/src/GeomAlgoAPI ${PROJECT_SOURCE_DIR}/src/Locale + ${OpenCASCADE_INCLUDE_DIR} + ${OpenCASCADE_DataExchange_LIBRARIES} + ${OpenCASCADE_ModelingAlgorithms_LIBRARIES} + ${OpenCASCADE_ApplicationFramework_LIBRARIES} ) @@ -265,6 +269,4 @@ ADD_UNIT_TESTS(TestConstants.py Test19707.py Test19726.py Test19912.py - Test19932.py - Test19989.py ) diff --git a/src/ModelAPI/ModelAPI_Feature.h b/src/ModelAPI/ModelAPI_Feature.h index a700139ec..811845db2 100644 --- a/src/ModelAPI/ModelAPI_Feature.h +++ b/src/ModelAPI/ModelAPI_Feature.h @@ -193,6 +193,11 @@ class ModelAPI_Feature : public ModelAPI_Object { return data()->intArray(theID); } + /// Returns the double array attribute by the identifier + inline std::shared_ptr realArray(const std::string& theID) + { + return data()->realArray(theID); + } /// Returns the reference attribute by the identifier inline std::shared_ptr refattr(const std::string& theID) { diff --git a/src/ModelAPI/ModelAPI_ResultBody.h b/src/ModelAPI/ModelAPI_ResultBody.h index c88fb08fc..11fdd2421 100644 --- a/src/ModelAPI/ModelAPI_ResultBody.h +++ b/src/ModelAPI/ModelAPI_ResultBody.h @@ -24,6 +24,8 @@ #include #include #include +#include +#include class ModelAPI_BodyBuilder; class GeomAlgoAPI_MakeShape; @@ -182,11 +184,26 @@ public: /// Cleans cash related to the already stored elements MODELAPI_EXPORT virtual void cleanCash() = 0; + + // Add shape Name for read shape in step file + MODELAPI_EXPORT virtual std::wstring addShapeName(std::shared_ptr,const std::wstring& theName) = 0; + // Add color for shape Name read shape in step file + MODELAPI_EXPORT virtual void addShapeColor(const std::wstring& theName,std::vector& color) = 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, + std::map< std::wstring, std::vector> & theColorsShape) = 0; + // Clear the map of name and color read shape in step file + MODELAPI_EXPORT virtual void clearShapeNameAndColor() = 0; + // find the name of shapp read in step file + MODELAPI_EXPORT virtual std::wstring findShapeName(std::shared_ptr theshape) = 0; + protected: /// Default constructor accessible only from Model_Objects MODELAPI_EXPORT ModelAPI_ResultBody(); + + }; //! Pointer on feature object diff --git a/src/ModelHighAPI/CMakeLists.txt b/src/ModelHighAPI/CMakeLists.txt index 982450580..d94749f5c 100644 --- a/src/ModelHighAPI/CMakeLists.txt +++ b/src/ModelHighAPI/CMakeLists.txt @@ -126,6 +126,4 @@ ADD_UNIT_TESTS( Test2488.py Test18451.py Test19031.py - Test19990_1.py - Test19990_2.py ) diff --git a/src/ModelHighAPI/ModelHighAPI_Dumper.cpp b/src/ModelHighAPI/ModelHighAPI_Dumper.cpp index 9d2c5e5f0..6d8affba8 100644 --- a/src/ModelHighAPI/ModelHighAPI_Dumper.cpp +++ b/src/ModelHighAPI/ModelHighAPI_Dumper.cpp @@ -1505,12 +1505,12 @@ ModelHighAPI_Dumper& ModelHighAPI_Dumper::operator<<( } if(isAdded) { + *myDumpStorage << ", "; // print each attribute on separate line with the appropriate shift if (aNbSpaces > 0) { std::string aSpaces(aNbSpaces + 1, ' '); - *myDumpStorage << ",\n" << aSpaces; - } else - *myDumpStorage << ", "; + *myDumpStorage << "\n" << aSpaces; + } } else { isAdded = true; } diff --git a/src/ModelHighAPI/ModelHighAPI_Macro.h b/src/ModelHighAPI/ModelHighAPI_Macro.h index 333de514e..a372090fe 100644 --- a/src/ModelHighAPI/ModelHighAPI_Macro.h +++ b/src/ModelHighAPI/ModelHighAPI_Macro.h @@ -535,6 +535,59 @@ SET_ATTRIBUTE(N_13, T_13, AN_13) \ END_INIT() \ public: +//-------------------------------------------------------------------------------------- +#define INTERFACE_15(KIND, \ + N_0, AN_0, T_0, C_0, \ + N_1, AN_1, T_1, C_1, \ + N_2, AN_2, T_2, C_2, \ + N_3, AN_3, T_3, C_3, \ + N_4, AN_4, T_4, C_4, \ + N_5, AN_5, T_5, C_5, \ + N_6, AN_6, T_6, C_6, \ + N_7, AN_7, T_7, C_7, \ + N_8, AN_8, T_8, C_8, \ + N_9, AN_9, T_9, C_9, \ + N_10, AN_10, T_10, C_10, \ + N_11, AN_11, T_11, C_11, \ + N_12, AN_12, T_12, C_12, \ + N_13, AN_13, T_13, C_13, \ + N_14, AN_14, T_14, C_14) \ + public: \ + INTERFACE_COMMON(KIND) \ + DEFINE_ATTRIBUTE(N_0, T_0, C_0) \ + DEFINE_ATTRIBUTE(N_1, T_1, C_1) \ + DEFINE_ATTRIBUTE(N_2, T_2, C_2) \ + DEFINE_ATTRIBUTE(N_3, T_3, C_3) \ + DEFINE_ATTRIBUTE(N_4, T_4, C_4) \ + DEFINE_ATTRIBUTE(N_5, T_5, C_5) \ + DEFINE_ATTRIBUTE(N_6, T_6, C_6) \ + DEFINE_ATTRIBUTE(N_7, T_7, C_7) \ + DEFINE_ATTRIBUTE(N_8, T_8, C_8) \ + DEFINE_ATTRIBUTE(N_9, T_9, C_9) \ + DEFINE_ATTRIBUTE(N_10, T_10, C_10) \ + DEFINE_ATTRIBUTE(N_11, T_11, C_11) \ + DEFINE_ATTRIBUTE(N_12, T_12, C_12) \ + DEFINE_ATTRIBUTE(N_13, T_13, C_13) \ + DEFINE_ATTRIBUTE(N_14, T_14, C_14) \ + protected: \ + START_INIT() \ + SET_ATTRIBUTE(N_0, T_0, AN_0) \ + SET_ATTRIBUTE(N_1, T_1, AN_1) \ + SET_ATTRIBUTE(N_2, T_2, AN_2) \ + SET_ATTRIBUTE(N_3, T_3, AN_3) \ + SET_ATTRIBUTE(N_4, T_4, AN_4) \ + SET_ATTRIBUTE(N_5, T_5, AN_5) \ + SET_ATTRIBUTE(N_6, T_6, AN_6) \ + SET_ATTRIBUTE(N_7, T_7, AN_7) \ + SET_ATTRIBUTE(N_8, T_8, AN_8) \ + SET_ATTRIBUTE(N_9, T_9, AN_9) \ + SET_ATTRIBUTE(N_10, T_10, AN_10) \ + SET_ATTRIBUTE(N_11, T_11, AN_11) \ + SET_ATTRIBUTE(N_12, T_12, AN_12) \ + SET_ATTRIBUTE(N_13, T_13, AN_13) \ + SET_ATTRIBUTE(N_14, T_14, AN_14) \ + END_INIT() \ + public: //-------------------------------------------------------------------------------------- #define INTERFACE_16(KIND, \ diff --git a/src/ModuleBase/ModuleBase_WidgetMultiSelector.cpp b/src/ModuleBase/ModuleBase_WidgetMultiSelector.cpp index bb5c6e39d..21df54023 100644 --- a/src/ModuleBase/ModuleBase_WidgetMultiSelector.cpp +++ b/src/ModuleBase/ModuleBase_WidgetMultiSelector.cpp @@ -352,7 +352,7 @@ bool ModuleBase_WidgetMultiSelector::restoreValueCustom() if (aSelectionType.empty()) aSelectionListAttr->setSelectionType(myDefMode); else { - setCurrentShapeType(aSelectionType.c_str()); + setCurrentShapeType(ModuleBase_Tools::shapeType(aSelectionType.c_str())); myDefMode = aSelectionType; myIsFirst = false; } @@ -752,28 +752,23 @@ QIntList ModuleBase_WidgetMultiSelector::shapeTypes() const QIntList aShapeTypes; if (myShapeTypes.length() > 1 && myIsUseChoice) { - QStringList aTypes = myTypeCtrl->textValue().split("|", QString::SkipEmptyParts); - for(QString aType: aTypes) { - aShapeTypes.append(ModuleBase_Tools::shapeType(aType)); - } + aShapeTypes.append(ModuleBase_Tools::shapeType(myTypeCtrl->textValue())); } else { foreach (QString aType, myShapeTypes) { - QStringList aSubTypes = aType.split("|", QString::SkipEmptyParts); - for(QString aSubType: aSubTypes) { - aShapeTypes.append(ModuleBase_Tools::shapeType(aSubType)); - } + aShapeTypes.append(ModuleBase_Tools::shapeType(aType)); } } return aShapeTypes; } //******************************************************************** -void ModuleBase_WidgetMultiSelector::setCurrentShapeType(const QString& theShapeType) +void ModuleBase_WidgetMultiSelector::setCurrentShapeType(const int theShapeType) { int idx = 0; foreach (QString aShapeTypeName, myShapeTypes) { - if(aShapeTypeName == theShapeType && idx != myTypeCtrl->value()) { + int aRefType = ModuleBase_Tools::shapeType(aShapeTypeName); + if(aRefType == theShapeType && idx != myTypeCtrl->value()) { updateSelectionModesAndFilters(false); bool isBlocked = myTypeCtrl->blockSignals(true); myTypeCtrl->setValue(idx); diff --git a/src/ModuleBase/ModuleBase_WidgetMultiSelector.h b/src/ModuleBase/ModuleBase_WidgetMultiSelector.h index 946b46d77..8e788d655 100644 --- a/src/ModuleBase/ModuleBase_WidgetMultiSelector.h +++ b/src/ModuleBase/ModuleBase_WidgetMultiSelector.h @@ -182,7 +182,7 @@ protected: virtual QIntList shapeTypes() const; /// Set current shape type for selection - void setCurrentShapeType(const QString& theShapeType); + void setCurrentShapeType(const int theShapeType); /// Return the attribute values wrapped in a list of viewer presentations /// \return a list of viewer presentations, which contains an attribute result and diff --git a/src/PartSet/PartSet_WidgetPoint2d.cpp b/src/PartSet/PartSet_WidgetPoint2d.cpp index ab8f1791c..c8068e18c 100644 --- a/src/PartSet/PartSet_WidgetPoint2d.cpp +++ b/src/PartSet/PartSet_WidgetPoint2d.cpp @@ -284,22 +284,19 @@ bool PartSet_WidgetPoint2D::setSelection(QList& theValu Handle(V3d_View) aView = myWorkshop->viewer()->activeView(); const TopoDS_Shape& aTDShape = aShape->impl(); GeomPnt2dPtr aPnt = PartSet_Tools::getPnt2d(aView, aTDShape, mySketch); - if (aPnt) { - //isDone = setPoint(aPnt->x(), aPnt->y()); - //setConstraintToPoint(aPnt->x(), aPnt->y(), aValue); - processSelection(aValue, aPnt->x(), aPnt->y()); - isDone = true; + isDone = setPoint(aPnt->x(), aPnt->y()); + setConstraintToPoint(aPnt->x(), aPnt->y(), aValue); } } } return isDone; } -//void PartSet_WidgetPoint2D::selectContent() -//{ -// // myXSpin->selectAll(); -//} +void PartSet_WidgetPoint2D::selectContent() +{ + // myXSpin->selectAll(); +} bool PartSet_WidgetPoint2D::setPoint(double theX, double theY) { @@ -557,36 +554,12 @@ void PartSet_WidgetPoint2D::mouseReleased(ModuleBase_IViewWindow* theWindow, QMo aFirstValue = myPreSelected; } - double aX=0, aY=0; - bool aHasPoint = false; - if (aFirstValue.get()) { - GeomShapePtr aShape = aFirstValue->shape(); - if (aShape->shapeType() == TopAbs_VERTEX) { - const TopoDS_Shape& aTDShape = aShape->impl(); - GeomPnt2dPtr aPnt = PartSet_Tools::getPnt2d(aView, aTDShape, mySketch); - aX = aPnt->x(); - aY = aPnt->y(); - aHasPoint = true; - } - } - if (!aHasPoint) { - gp_Pnt aPoint = PartSet_Tools::convertClickToPoint(theEvent->pos(), aView); - PartSet_Tools::convertTo2D(aPoint, mySketch, aView, aX, aY); - } - processSelection(aFirstValue, aX, aY); -} - -void PartSet_WidgetPoint2D::processSelection(const ModuleBase_ViewerPrsPtr& theValue, - double theX, double theY) -{ - if (!setPoint(theX, theY)) - return; // if we have selection and use it - if (theValue.get() && isValidSelectionCustom(theValue) && theValue->shape().get()) { - /// Trihedron Axis may be selected, but shape is empty - GeomShapePtr aGeomShape = theValue->shape(); + if (aFirstValue.get() && isValidSelectionCustom(aFirstValue) && + aFirstValue->shape().get()) { /// Trihedron Axis may be selected, but shape is empty + GeomShapePtr aGeomShape = aFirstValue->shape(); TopoDS_Shape aShape = aGeomShape->impl(); - ObjectPtr aObject = theValue->object(); + ObjectPtr aObject = aFirstValue->object(); FeaturePtr aSelectedFeature = ModelAPI_Feature::feature(aObject); bool anExternal = false; @@ -612,12 +585,34 @@ void PartSet_WidgetPoint2D::processSelection(const ModuleBase_ViewerPrsPtr& theV } } if (anExternal) { - if (!isFeatureContainsPoint(myFeature, theX, theY)) { - if (aShape.ShapeType() == TopAbs_EDGE) { + GeomPnt2dPtr aPnt = PartSet_Tools::getPnt2d(aView, aShape, mySketch); + double aX = 0, aY = 0; + if (aPnt) { + aX = aPnt->x(); + aY = aPnt->y(); + } + if (aPnt && isFeatureContainsPoint(myFeature, aX, aY)) { + // do not create a constraint to the point, which already used by the feature + // if the feature contains the point, focus is not switched + setPoint(aX, aY); + } + else { + if (aPnt) + setPoint(aX, aY); + else { + if (aShape.ShapeType() == TopAbs_EDGE) { + // point is taken from mouse event and set in attribute. It should be done before set + // coinident constraint to the external line. If a point is created, it should be in + // the mouse clicked point + gp_Pnt aPoint = PartSet_Tools::convertClickToPoint(theEvent->pos(), + theWindow->v3dView()); + PartSet_Tools::convertTo2D(aPoint, mySketch, aView, aX, aY); + setPoint(aX, aY); + } setValueState(Stored); // in case of edge selection, Apply state should also be updated } bool anOrphanPoint = aShape.ShapeType() == TopAbs_VERTEX || - isOrphanPoint(aSelectedFeature, mySketch, theX, theY); + isOrphanPoint(aSelectedFeature, mySketch, aX, aY); if (anExternal) { // we should not stop reentrant operation on external objects because anOrphanPoint = true; @@ -625,7 +620,7 @@ void PartSet_WidgetPoint2D::processSelection(const ModuleBase_ViewerPrsPtr& theV if (aShape.ShapeType() == TopAbs_VERTEX) { FeaturePtr aFixedFeature = ModelAPI_Feature::feature(aFixedObject); if (aFixedFeature.get() && aFixedFeature->getKind() == SketchPlugin_Point::ID()) { - anOrphanPoint = isOrphanPoint(aFixedFeature, mySketch, theX, theY); + anOrphanPoint = isOrphanPoint(aFixedFeature, mySketch, aX, aY); } } } @@ -642,21 +637,33 @@ void PartSet_WidgetPoint2D::processSelection(const ModuleBase_ViewerPrsPtr& theV emit focusOutWidget(this); } } - else { - if (!isFeatureContainsPoint(myFeature, theX, theY)) { + if (!anExternal) { + GeomPnt2dPtr aPnt = PartSet_Tools::getPnt2d(aView, aShape, mySketch); + if (aPnt && isFeatureContainsPoint(myFeature, aPnt->x(), aPnt->y())) { + // when the point is selected, the coordinates of the point should be set into the attribute + // if the feature contains the point, focus is not switched + setPoint(aPnt->x(), aPnt->y()); + } + else { double aX = 0, aY = 0; bool anOrphanPoint = isOrphanPoint(aSelectedFeature, mySketch, aX, aY); // do not set a coincidence constraint in the attribute if the feature contains a point // with the same coordinates. It is important for line creation in order to do not set // the same constraints for the same points, oterwise the result line has zero length. bool isAuxiliaryFeature = false; - if (aShape.ShapeType() == TopAbs_VERTEX) { - setConstraintToPoint(theX, theY, theValue); + if (aPnt) { + aX = aPnt->x(); + aY = aPnt->y(); + setPoint(aX, aY); + setConstraintToPoint(aX, aY, aFirstValue); } else if (aShape.ShapeType() == TopAbs_EDGE) { // point is taken from mouse event and set in attribute. It should be done before setting // coinident constraint to the external line. If a point is created, it should be in // the mouse clicked point + gp_Pnt aPoint = PartSet_Tools::convertClickToPoint(theEvent->pos(), theWindow->v3dView()); + PartSet_Tools::convertTo2D(aPoint, mySketch, aView, aX, aY); + setPoint(aX, aY); setConstraintToObject(aObject); setValueState(Stored); // in case of edge selection, Apply state should also be updated isAuxiliaryFeature = PartSet_Tools::isAuxiliarySketchEntity(aObject); @@ -676,9 +683,9 @@ void PartSet_WidgetPoint2D::processSelection(const ModuleBase_ViewerPrsPtr& theV } } // The selection could be a center of an external circular object - else if (theValue.get() && (!theValue->interactive().IsNull())) { + else if (aFirstValue.get() && (!aFirstValue->interactive().IsNull())) { Handle(PartSet_CenterPrs) aAIS = - Handle(PartSet_CenterPrs)::DownCast(theValue->interactive()); + Handle(PartSet_CenterPrs)::DownCast(aFirstValue->interactive()); if (!aAIS.IsNull()) { gp_Pnt aPntComp = aAIS->Component()->Pnt(); GeomVertexPtr aVertPtr(new GeomAPI_Vertex(aPntComp.X(), aPntComp.Y(), aPntComp.Z())); @@ -698,6 +705,12 @@ void PartSet_WidgetPoint2D::processSelection(const ModuleBase_ViewerPrsPtr& theV // external objects e.g. selection of trihedron axis when input end arc point updateObject(feature()); + GeomPnt2dPtr aPnt = PartSet_Tools::getPnt2d(aView, aShape, mySketch); + if (aPnt) { + // do not create a constraint to the point, which already used by the feature + // if the feature contains the point, focus is not switched + setPoint(aPnt->x(), aPnt->y()); + } emit vertexSelected(); // it stops the reentrant operation myPreSelected.reset(); emit focusOutWidget(this); @@ -705,9 +718,12 @@ void PartSet_WidgetPoint2D::processSelection(const ModuleBase_ViewerPrsPtr& theV } else { // A case when point is taken from mouse event + gp_Pnt aPoint = PartSet_Tools::convertClickToPoint(theEvent->pos(), theWindow->v3dView()); + double aX = 0, aY = 0; + PartSet_Tools::convertTo2D(aPoint, mySketch, aView, aX, aY); // if the feature contains the point, focus is not switched - if (isFeatureContainsPoint(myFeature, theX, theY)) + if (!setPoint(aX, aY) || isFeatureContainsPoint(myFeature, aX, aY)) return; myPreSelected.reset(); diff --git a/src/PartSet/PartSet_WidgetPoint2d.h b/src/PartSet/PartSet_WidgetPoint2d.h index f0a06a8ec..19846bfe7 100644 --- a/src/PartSet/PartSet_WidgetPoint2d.h +++ b/src/PartSet/PartSet_WidgetPoint2d.h @@ -25,7 +25,6 @@ #include #include -#include #include @@ -99,7 +98,7 @@ Q_OBJECT const bool theToValidate); /// Select the internal content if it can be selected. It is empty in the default realization - //virtual void selectContent(); + virtual void selectContent(); /// Returns list of widget controls /// \return a control list @@ -223,13 +222,6 @@ protected: /// \return true if succed bool setConstraintToObject(const ObjectPtr& theObject); - /// Process selected value - /// \param theValue the selected object - /// \param theX X coordinate of clicked point - /// \param theY Y coordinate of clicked point - void processSelection(const ModuleBase_ViewerPrsPtr& theValue, double theX, double theY); - - public: /// Returns if the feature is an orphan point, circle or an arc. Returns true if it /// has no a coincident to other lines. It processes point, circle and arc features diff --git a/src/PartSet/PartSet_WidgetSketchCreator.cpp b/src/PartSet/PartSet_WidgetSketchCreator.cpp index 6d570d985..3fe190981 100644 --- a/src/PartSet/PartSet_WidgetSketchCreator.cpp +++ b/src/PartSet/PartSet_WidgetSketchCreator.cpp @@ -307,17 +307,11 @@ QIntList PartSet_WidgetSketchCreator::shapeTypes() const { QIntList aShapeTypes; if (myShapeTypes.length() > 1 && myIsUseChoice) { - QStringList aTypes = myTypeCtrl->textValue().split("|", QString::SkipEmptyParts); - foreach(QString aType, aTypes) { - aShapeTypes.append(ModuleBase_Tools::shapeType(aType)); - } + aShapeTypes.append(ModuleBase_Tools::shapeType(myTypeCtrl->textValue())); } else { foreach(QString aType, myShapeTypes) { - QStringList aSubTypes = aType.split("|", QString::SkipEmptyParts); - foreach(QString asubType, aSubTypes) { - aShapeTypes.append(ModuleBase_Tools::shapeType(asubType)); - } + aShapeTypes.append(ModuleBase_Tools::shapeType(aType)); } } return aShapeTypes; diff --git a/src/PythonAPI/model/exchange/__init__.py b/src/PythonAPI/model/exchange/__init__.py index a37fdd678..84b62bcc3 100644 --- a/src/PythonAPI/model/exchange/__init__.py +++ b/src/PythonAPI/model/exchange/__init__.py @@ -19,7 +19,7 @@ """Package for Exchange plugin for the Parametric Geometry API of the Modeler. """ -from ExchangeAPI import addImport, exportToFile, exportToXAO +from ExchangeAPI import addImport, addImportStep, exportToFile, exportToXAO, exportToSTL from ExchangeAPI import exportPart, importPart from .tools import *