From bd1b8c8100e2b2cffd30ee0b4d73836b13d518ae Mon Sep 17 00:00:00 2001 From: Clarisse Genrault Date: Thu, 26 Jan 2017 08:03:16 +0100 Subject: [PATCH] Adding Scale feature. --- src/FeaturesAPI/CMakeLists.txt | 5 +- src/FeaturesAPI/FeaturesAPI.i | 2 + src/FeaturesAPI/FeaturesAPI_Scale.cpp | 144 ++++++++ src/FeaturesAPI/FeaturesAPI_Scale.h | 112 ++++++ src/FeaturesAPI/FeaturesAPI_swig.h | 1 + src/FeaturesAPI/Test/APIParam_Scale.py | 37 ++ src/FeaturesPlugin/CMakeLists.txt | 3 + src/FeaturesPlugin/FeaturesPlugin_Plugin.cpp | 5 +- src/FeaturesPlugin/FeaturesPlugin_Scale.cpp | 267 ++++++++++++++ src/FeaturesPlugin/FeaturesPlugin_Scale.h | 122 +++++++ src/FeaturesPlugin/icons/SVG/scale.svg | 332 ++++++++++++++++++ .../icons/SVG/scale_dimensions_32x32.svg | 102 ++++++ .../icons/SVG/scale_factor_32x32.svg | 101 ++++++ src/FeaturesPlugin/icons/scale.png | Bin 0 -> 583 bytes .../icons/scale_dimensions_32x32.png | Bin 0 -> 1278 bytes .../icons/scale_factor_32x32.png | Bin 0 -> 1296 bytes src/FeaturesPlugin/plugin-Features.xml | 3 + src/FeaturesPlugin/scale_widget.xml | 76 ++++ src/GeomAlgoAPI/CMakeLists.txt | 3 + src/GeomAlgoAPI/GeomAlgoAPI_Scale.cpp | 184 ++++++++++ src/GeomAlgoAPI/GeomAlgoAPI_Scale.h | 68 ++++ src/GeomAlgoAPI/GeomAlgoAPI_ShapeAPI.cpp | 50 +++ src/GeomAlgoAPI/GeomAlgoAPI_ShapeAPI.h | 22 ++ src/GeomAlgoAPI/Test/TestAPI_Scale.py | 32 ++ src/PythonAPI/model/features/__init__.py | 2 +- 25 files changed, 1670 insertions(+), 3 deletions(-) create mode 100644 src/FeaturesAPI/FeaturesAPI_Scale.cpp create mode 100644 src/FeaturesAPI/FeaturesAPI_Scale.h create mode 100644 src/FeaturesAPI/Test/APIParam_Scale.py create mode 100644 src/FeaturesPlugin/FeaturesPlugin_Scale.cpp create mode 100644 src/FeaturesPlugin/FeaturesPlugin_Scale.h create mode 100644 src/FeaturesPlugin/icons/SVG/scale.svg create mode 100644 src/FeaturesPlugin/icons/SVG/scale_dimensions_32x32.svg create mode 100644 src/FeaturesPlugin/icons/SVG/scale_factor_32x32.svg create mode 100644 src/FeaturesPlugin/icons/scale.png create mode 100644 src/FeaturesPlugin/icons/scale_dimensions_32x32.png create mode 100644 src/FeaturesPlugin/icons/scale_factor_32x32.png create mode 100644 src/FeaturesPlugin/scale_widget.xml create mode 100644 src/GeomAlgoAPI/GeomAlgoAPI_Scale.cpp create mode 100644 src/GeomAlgoAPI/GeomAlgoAPI_Scale.h create mode 100644 src/GeomAlgoAPI/Test/TestAPI_Scale.py diff --git a/src/FeaturesAPI/CMakeLists.txt b/src/FeaturesAPI/CMakeLists.txt index e10949900..af088777a 100644 --- a/src/FeaturesAPI/CMakeLists.txt +++ b/src/FeaturesAPI/CMakeLists.txt @@ -17,6 +17,7 @@ SET(PROJECT_HEADERS FeaturesAPI_Revolution.h FeaturesAPI_RevolutionBoolean.h FeaturesAPI_Rotation.h + FeaturesAPI_Scale.h FeaturesAPI_Symmetry.h FeaturesAPI_Translation.h FeaturesAPI_Union.h @@ -35,6 +36,7 @@ SET(PROJECT_SOURCES FeaturesAPI_Revolution.cpp FeaturesAPI_RevolutionBoolean.cpp FeaturesAPI_Rotation.cpp + FeaturesAPI_Scale.cpp FeaturesAPI_Symmetry.cpp FeaturesAPI_Translation.cpp FeaturesAPI_Union.cpp @@ -94,5 +96,6 @@ INSTALL(TARGETS _FeaturesAPI DESTINATION ${SHAPER_INSTALL_SWIG}) INSTALL(TARGETS FeaturesAPI DESTINATION ${SHAPER_INSTALL_BIN}) INSTALL(FILES ${CMAKE_CURRENT_BINARY_DIR}/FeaturesAPI.py DESTINATION ${SHAPER_INSTALL_SWIG}) -ADD_UNIT_TESTS(APIParam_Symmetry.py +ADD_UNIT_TESTS(APIParam_Scale.py + APIParam_Symmetry.py APIParam_Translation.py) \ No newline at end of file diff --git a/src/FeaturesAPI/FeaturesAPI.i b/src/FeaturesAPI/FeaturesAPI.i index 68817ec5f..9a0ff26be 100644 --- a/src/FeaturesAPI/FeaturesAPI.i +++ b/src/FeaturesAPI/FeaturesAPI.i @@ -35,6 +35,7 @@ %shared_ptr(FeaturesAPI_RevolutionCut) %shared_ptr(FeaturesAPI_RevolutionFuse) %shared_ptr(FeaturesAPI_Rotation) +%shared_ptr(FeaturesAPI_Scale) %shared_ptr(FeaturesAPI_Symmetry) %shared_ptr(FeaturesAPI_Translation) %shared_ptr(FeaturesAPI_Union) @@ -52,6 +53,7 @@ %include "FeaturesAPI_Revolution.h" %include "FeaturesAPI_RevolutionBoolean.h" %include "FeaturesAPI_Rotation.h" +%include "FeaturesAPI_Scale.h" %include "FeaturesAPI_Symmetry.h" %include "FeaturesAPI_Translation.h" %include "FeaturesAPI_Union.h" diff --git a/src/FeaturesAPI/FeaturesAPI_Scale.cpp b/src/FeaturesAPI/FeaturesAPI_Scale.cpp new file mode 100644 index 000000000..e80f3b4cf --- /dev/null +++ b/src/FeaturesAPI/FeaturesAPI_Scale.cpp @@ -0,0 +1,144 @@ +// Copyright (C) 2014-201x CEA/DEN, EDF R&D --> + +// File: FeaturesAPI_Scale.cpp +// Created: 24 Jan 2017 +// Author: Clarisse Genrault (CEA) + +#include "FeaturesAPI_Scale.h" + +#include +#include + +//================================================================================================== +FeaturesAPI_Scale::FeaturesAPI_Scale(const std::shared_ptr& theFeature) +: ModelHighAPI_Interface(theFeature) +{ + initialize(); +} + +//================================================================================================== +FeaturesAPI_Scale::FeaturesAPI_Scale(const std::shared_ptr& theFeature, + const std::list& theMainObjects, + const ModelHighAPI_Selection& theCenterPoint, + const ModelHighAPI_Double& theScaleFactor) +: ModelHighAPI_Interface(theFeature) +{ + if (initialize()) { + fillAttribute(theMainObjects, mainObjects()); + fillAttribute(theCenterPoint, centerPoint()); + setScaleFactor(theScaleFactor); + } +} + +//================================================================================================== +FeaturesAPI_Scale::FeaturesAPI_Scale(const std::shared_ptr& theFeature, + const std::list& theMainObjects, + const ModelHighAPI_Selection& theCenterPoint, + const ModelHighAPI_Double& theScaleFactorX, + const ModelHighAPI_Double& theScaleFactorY, + const ModelHighAPI_Double& theScaleFactorZ) +: ModelHighAPI_Interface(theFeature) +{ + if (initialize()) { + fillAttribute(theMainObjects, mainObjects()); + fillAttribute(theCenterPoint, centerPoint()); + setDimensions(theScaleFactorX, theScaleFactorY, theScaleFactorZ); + } +} + +//================================================================================================== +FeaturesAPI_Scale::~FeaturesAPI_Scale() +{ +} + +//================================================================================================== +void FeaturesAPI_Scale::setMainObjects(const std::list& theMainObjects) +{ + fillAttribute(theMainObjects, mainObjects()); + execute(); +} + +//================================================================================================== +void FeaturesAPI_Scale::setCenterPoint(const ModelHighAPI_Selection& theCenterPoint) +{ + fillAttribute(theCenterPoint, centerPoint()); + execute(); +} + +//================================================================================================== +void FeaturesAPI_Scale::setScaleFactor(const ModelHighAPI_Double& theScaleFactor) +{ + fillAttribute(FeaturesPlugin_Scale::CREATION_METHOD_BY_FACTOR(), creationMethod()); + fillAttribute(theScaleFactor, scaleFactor()); + execute(); +} + +//================================================================================================== +void FeaturesAPI_Scale::setDimensions(const ModelHighAPI_Double& theScaleFactorX, + const ModelHighAPI_Double& theScaleFactorY, + const ModelHighAPI_Double& theScaleFactorZ) +{ + fillAttribute(FeaturesPlugin_Scale::CREATION_METHOD_BY_DIMENSIONS(), creationMethod()); + fillAttribute(theScaleFactorX, scaleFactorX()); + fillAttribute(theScaleFactorY, scaleFactorY()); + fillAttribute(theScaleFactorZ, scaleFactorZ()); + execute(); +} + +//================================================================================================== +void FeaturesAPI_Scale::dump(ModelHighAPI_Dumper& theDumper) const +{ + FeaturePtr aBase = feature(); + const std::string& aDocName = theDumper.name(aBase->document()); + + AttributeSelectionListPtr anAttrObjects = + aBase->selectionList(FeaturesPlugin_Scale::OBJECTS_LIST_ID()); + theDumper << aBase << " = model.addScale(" << aDocName << ", " << anAttrObjects; + + AttributeSelectionPtr anAttrPoint = + aBase->selection(FeaturesPlugin_Scale::CENTER_POINT_ID()); + theDumper << " , " << anAttrPoint; + + std::string aCreationMethod = + aBase->string(FeaturesPlugin_Scale::CREATION_METHOD())->value(); + + if (aCreationMethod == FeaturesPlugin_Scale::CREATION_METHOD_BY_FACTOR()) { + AttributeDoublePtr anAttrScaleFactor = + aBase->real(FeaturesPlugin_Scale::SCALE_FACTOR_ID()); + theDumper << ", " << anAttrScaleFactor; + } else if (aCreationMethod == FeaturesPlugin_Scale::CREATION_METHOD_BY_DIMENSIONS()) { + AttributeDoublePtr anAttrScaleFactorX = + aBase->real(FeaturesPlugin_Scale::SCALE_FACTOR_X_ID()); + AttributeDoublePtr anAttrScaleFactorY = + aBase->real(FeaturesPlugin_Scale::SCALE_FACTOR_Y_ID()); + AttributeDoublePtr anAttrScaleFactorZ = + aBase->real(FeaturesPlugin_Scale::SCALE_FACTOR_Z_ID()); + theDumper << ", " << anAttrScaleFactorX << " , " << anAttrScaleFactorY; + theDumper << ", " << anAttrScaleFactorZ; + } + + theDumper << ")" << std::endl; +} + +//================================================================================================== +ScalePtr addScale(const std::shared_ptr& thePart, + const std::list& theMainObjects, + const ModelHighAPI_Selection& theCenterPoint, + const ModelHighAPI_Double& theScaleFactor) +{ + std::shared_ptr aFeature = thePart->addFeature(FeaturesAPI_Scale::ID()); + return ScalePtr(new FeaturesAPI_Scale(aFeature, theMainObjects, theCenterPoint, theScaleFactor)); +} + +//================================================================================================== +ScalePtr addScale(const std::shared_ptr& thePart, + const std::list& theMainObjects, + const ModelHighAPI_Selection& theCenterPoint, + const ModelHighAPI_Double& theScaleFactorX, + const ModelHighAPI_Double& theScaleFactorY, + const ModelHighAPI_Double& theScaleFactorZ) +{ + std::shared_ptr aFeature = thePart->addFeature(FeaturesAPI_Scale::ID()); + return ScalePtr(new FeaturesAPI_Scale(aFeature, theMainObjects, theCenterPoint, + theScaleFactorX, theScaleFactorY, theScaleFactorZ)); +} \ No newline at end of file diff --git a/src/FeaturesAPI/FeaturesAPI_Scale.h b/src/FeaturesAPI/FeaturesAPI_Scale.h new file mode 100644 index 000000000..d53ff1777 --- /dev/null +++ b/src/FeaturesAPI/FeaturesAPI_Scale.h @@ -0,0 +1,112 @@ +// Copyright (C) 2014-201x CEA/DEN, EDF R&D --> + +// File: FeaturesAPI_Scale.h +// Created: 24 Jan 2017 +// Author: Clarisse Genrault (CEA) + +#ifndef FEATURESAPI_SCALE_H_ +#define FEATURESAPI_SCALE_H_ + +#include "FeaturesAPI.h" + +#include + +#include +#include + +class ModelHighAPI_Double; +class ModelHighAPI_Dumper; +class ModelHighAPI_Selection; + +/// \class FeaturesAPI_Scale +/// \ingroup CPPHighAPI +/// \brief Interface for Scale feature. +class FeaturesAPI_Scale: public ModelHighAPI_Interface +{ +public: + /// Constructor without values. + FEATURESAPI_EXPORT + explicit FeaturesAPI_Scale(const std::shared_ptr& theFeature); + + /// Constructor with values. + FEATURESAPI_EXPORT + explicit FeaturesAPI_Scale(const std::shared_ptr& theFeature, + const std::list& theMainObjects, + const ModelHighAPI_Selection& theCenterPoint, + const ModelHighAPI_Double& theScaleFactor); + + /// Constructor with values. + FEATURESAPI_EXPORT + explicit FeaturesAPI_Scale(const std::shared_ptr& theFeature, + const std::list& theMainObjects, + const ModelHighAPI_Selection& theCenterPoint, + const ModelHighAPI_Double& theScaleFactorX, + const ModelHighAPI_Double& theScaleFactorY, + const ModelHighAPI_Double& theScaleFactorZ); + + /// Destructor. + FEATURESAPI_EXPORT + virtual ~FeaturesAPI_Scale(); + + INTERFACE_7(FeaturesPlugin_Scale::ID(), + creationMethod, FeaturesPlugin_Scale::CREATION_METHOD(), + ModelAPI_AttributeString, /** Creation method */, + mainObjects, FeaturesPlugin_Scale::OBJECTS_LIST_ID(), + ModelAPI_AttributeSelectionList, /** Main objects */, + centerPoint, FeaturesPlugin_Scale::CENTER_POINT_ID(), + ModelAPI_AttributeSelection, /** Center point */, + scaleFactor, FeaturesPlugin_Scale::SCALE_FACTOR_ID(), + ModelAPI_AttributeDouble, /** Scale factor */, + scaleFactorX, FeaturesPlugin_Scale::SCALE_FACTOR_X_ID(), + ModelAPI_AttributeDouble, /** Scale factor in X */, + scaleFactorY, FeaturesPlugin_Scale::SCALE_FACTOR_Y_ID(), + ModelAPI_AttributeDouble, /** Scale factor in Y */, + scaleFactorZ, FeaturesPlugin_Scale::SCALE_FACTOR_Z_ID(), + ModelAPI_AttributeDouble, /** Scale factor in Z */) + + /// Set main objects. + FEATURESAPI_EXPORT + void setMainObjects(const std::list& theMainObjects); + + /// Modify center_point attribute of the feature. + FEATURESAPI_EXPORT + void setCenterPoint(const ModelHighAPI_Selection& theCenterPoint); + + /// Modify Creation Method and scale_factor attribute of the feature. + FEATURESAPI_EXPORT + void setScaleFactor(const ModelHighAPI_Double& theScaleFactor); + + /// Modify Creation Method and scale_factor_x, scale_factor_y and scale_factor_z + /// attributes of the feature. + FEATURESAPI_EXPORT + void setDimensions(const ModelHighAPI_Double& theScaleFactorX, + const ModelHighAPI_Double& theScaleFactorY, + const ModelHighAPI_Double& theScaleFactorZ); + + /// Dump wrapped feature + FEATURESAPI_EXPORT + virtual void dump(ModelHighAPI_Dumper& theDumper) const; +}; + +/// Pointer on Scale object. +typedef std::shared_ptr ScalePtr; + +/// \ingroup CPPHighAPI +/// \brief Create Scale feature. +FEATURESAPI_EXPORT +ScalePtr addScale(const std::shared_ptr& thePart, + const std::list& theMainObjects, + const ModelHighAPI_Selection& theCenterPoint, + const ModelHighAPI_Double& theScaleFactor); + +/// \ingroup CPPHighAPI +/// \brief Create Scale feature. +FEATURESAPI_EXPORT +ScalePtr addScale(const std::shared_ptr& thePart, + const std::list& theMainObjects, + const ModelHighAPI_Selection& theCenterPoint, + const ModelHighAPI_Double& theScaleFactorX, + const ModelHighAPI_Double& theScaleFactorY, + const ModelHighAPI_Double& theScaleFactorZ); + +#endif // FEATURESAPI_SCALE_H_ \ No newline at end of file diff --git a/src/FeaturesAPI/FeaturesAPI_swig.h b/src/FeaturesAPI/FeaturesAPI_swig.h index cb100d4c4..35a794d38 100644 --- a/src/FeaturesAPI/FeaturesAPI_swig.h +++ b/src/FeaturesAPI/FeaturesAPI_swig.h @@ -22,6 +22,7 @@ #include "FeaturesAPI_Revolution.h" #include "FeaturesAPI_RevolutionBoolean.h" #include "FeaturesAPI_Rotation.h" + #include "FeaturesAPI_Scale.h" #include "FeaturesAPI_Symmetry.h" #include "FeaturesAPI_Translation.h" #include "FeaturesAPI_Union.h" diff --git a/src/FeaturesAPI/Test/APIParam_Scale.py b/src/FeaturesAPI/Test/APIParam_Scale.py new file mode 100644 index 000000000..f0a33e077 --- /dev/null +++ b/src/FeaturesAPI/Test/APIParam_Scale.py @@ -0,0 +1,37 @@ +""" +Test case for Scale feature. +Written on High API. +""" +from ModelAPI import * +from GeomAPI import * + +from salome.shaper import model + +# Get session +aSession = ModelAPI_Session.get() + +# Create a part +aDocument = aSession.activeDocument() +aSession.startOperation() +model.addPart(aDocument) +aDocument = aSession.activeDocument() +aSession.finishOperation() + +# Create a box +aSession.startOperation() +aCenterPoint = model.addPoint(aDocument, 20, 20, 0).result() +aBox1 = model.addBox(aDocument, 10, 10, 10) +aBox2 = model.addBox(aDocument, 10, 10, 10) +aSession.finishOperation() + +# Perform a symmetry by a point +aSession.startOperation() +aScale1 = model.addScale(aDocument, [model.selection("SOLID", "Box_1_1")], aCenterPoint, 2.0).result() +aSession.finishOperation() +assert (aScale1 is not None) + +# Perform a symmetry by an axis +aSession.startOperation() +aScale2 = model.addScale(aDocument, [model.selection("SOLID", "Box_2_1")], aCenterPoint, -0.5, 2, 3.7).result() +aSession.finishOperation() +assert (aScale2 is not None) \ No newline at end of file diff --git a/src/FeaturesPlugin/CMakeLists.txt b/src/FeaturesPlugin/CMakeLists.txt index 42e4c363b..f04d203ab 100644 --- a/src/FeaturesPlugin/CMakeLists.txt +++ b/src/FeaturesPlugin/CMakeLists.txt @@ -30,6 +30,7 @@ SET(PROJECT_HEADERS FeaturesPlugin_RemoveSubShapes.h FeaturesPlugin_Tools.h FeaturesPlugin_Symmetry.h + FeaturesPlugin_Scale.h ) SET(PROJECT_SOURCES @@ -58,6 +59,7 @@ SET(PROJECT_SOURCES FeaturesPlugin_RemoveSubShapes.cpp FeaturesPlugin_Tools.cpp FeaturesPlugin_Symmetry.cpp + FeaturesPlugin_Scale.cpp ) SET(XML_RESOURCES @@ -79,6 +81,7 @@ SET(XML_RESOURCES remove_subshapes_widget.xml union_widget.xml symmetry_widget.xml + scale_widget.xml ) SET(TEXT_RESOURCES diff --git a/src/FeaturesPlugin/FeaturesPlugin_Plugin.cpp b/src/FeaturesPlugin/FeaturesPlugin_Plugin.cpp index 89f735cf1..4f1344b1d 100644 --- a/src/FeaturesPlugin/FeaturesPlugin_Plugin.cpp +++ b/src/FeaturesPlugin/FeaturesPlugin_Plugin.cpp @@ -17,10 +17,11 @@ #include #include #include +#include +#include #include #include #include -#include #include @@ -102,6 +103,8 @@ FeaturePtr FeaturesPlugin_Plugin::createFeature(std::string theFeatureID) return FeaturePtr(new FeaturesPlugin_Union); } else if (theFeatureID == FeaturesPlugin_Symmetry::ID()) { return FeaturePtr(new FeaturesPlugin_Symmetry); + } else if (theFeatureID == FeaturesPlugin_Scale::ID()) { + return FeaturePtr(new FeaturesPlugin_Scale); } // feature of such kind is not found diff --git a/src/FeaturesPlugin/FeaturesPlugin_Scale.cpp b/src/FeaturesPlugin/FeaturesPlugin_Scale.cpp new file mode 100644 index 000000000..ee82f611d --- /dev/null +++ b/src/FeaturesPlugin/FeaturesPlugin_Scale.cpp @@ -0,0 +1,267 @@ +// Copyright (C) 2014-201x CEA/DEN, EDF R&D + +// File: FeaturesPlugin_Scale.cpp +// Created: 13 Jan 2017 +// Author: Clarisse Genrault (CEA) + +#include + +#include + +#include +#include +#include +#include +#include + +//================================================================================================= +FeaturesPlugin_Scale::FeaturesPlugin_Scale() +{ +} + +//================================================================================================= +void FeaturesPlugin_Scale::initAttributes() +{ + data()->addAttribute(FeaturesPlugin_Scale::CREATION_METHOD(), + ModelAPI_AttributeString::typeId()); + + AttributeSelectionListPtr aSelection = + std::dynamic_pointer_cast(data()->addAttribute( + FeaturesPlugin_Scale::OBJECTS_LIST_ID(), ModelAPI_AttributeSelectionList::typeId())); + + data()->addAttribute(FeaturesPlugin_Scale::CENTER_POINT_ID(), + ModelAPI_AttributeSelection::typeId()); + + data()->addAttribute(FeaturesPlugin_Scale::SCALE_FACTOR_ID(), + ModelAPI_AttributeDouble::typeId()); + + data()->addAttribute(FeaturesPlugin_Scale::SCALE_FACTOR_X_ID(), + ModelAPI_AttributeDouble::typeId()); + data()->addAttribute(FeaturesPlugin_Scale::SCALE_FACTOR_Y_ID(), + ModelAPI_AttributeDouble::typeId()); + data()->addAttribute(FeaturesPlugin_Scale::SCALE_FACTOR_Z_ID(), + ModelAPI_AttributeDouble::typeId()); +} + +//================================================================================================= +void FeaturesPlugin_Scale::execute() +{ + AttributeStringPtr aMethodTypeAttr = string(FeaturesPlugin_Scale::CREATION_METHOD()); + std::string aMethodType = aMethodTypeAttr->value(); + + if (aMethodType == FeaturesPlugin_Scale::CREATION_METHOD_BY_FACTOR()) { + performScaleByFactor(); + } + + if (aMethodType == FeaturesPlugin_Scale::CREATION_METHOD_BY_DIMENSIONS()) { + performScaleByDimensions(); + } +} + +//================================================================================================= +void FeaturesPlugin_Scale::performScaleByFactor() +{ + // Getting objects. + ListOfShape anObjects; + std::list aContextes; + AttributeSelectionListPtr anObjectsSelList = + selectionList(FeaturesPlugin_Scale::OBJECTS_LIST_ID()); + if (anObjectsSelList->size() == 0) { + return; + } + for(int anObjectsIndex = 0; anObjectsIndex < anObjectsSelList->size(); anObjectsIndex++) { + std::shared_ptr anObjectAttr = + anObjectsSelList->value(anObjectsIndex); + std::shared_ptr anObject = anObjectAttr->value(); + if(!anObject.get()) { // may be for not-activated parts + eraseResults(); + return; + } + anObjects.push_back(anObject); + aContextes.push_back(anObjectAttr->context()); + } + + // Getting the center point + std::shared_ptr aCenterPoint; + std::shared_ptr anObjRef = + selection(FeaturesPlugin_Scale::CENTER_POINT_ID()); + if (anObjRef.get() != NULL) { + GeomShapePtr aShape = anObjRef->value(); + if (!aShape.get()) { + aShape = anObjRef->context()->shape(); + } + if (aShape) { + aCenterPoint = GeomAlgoAPI_PointBuilder::point(aShape); + } + } + + // Getting scale factor + double aScaleFactor = real(FeaturesPlugin_Scale::SCALE_FACTOR_ID())->value(); + + // Moving each object. + int aResultIndex = 0; + std::list::iterator aContext = aContextes.begin(); + for(ListOfShape::iterator anObjectsIt = anObjects.begin(); anObjectsIt != anObjects.end(); + anObjectsIt++, aContext++) { + std::shared_ptr aBaseShape = *anObjectsIt; + bool isPart = (*aContext)->groupName() == ModelAPI_ResultPart::group(); + + // Setting result. + if (isPart) { + std::shared_ptr aTrsf(new GeomAPI_Trsf()); + //aTrsf->setSymmetry(anAxis); + ResultPartPtr anOrigin = std::dynamic_pointer_cast(*aContext); + ResultPartPtr aResultPart = document()->copyPart(anOrigin, data(), aResultIndex); + aResultPart->setTrsf(*aContext, aTrsf); + setResult(aResultPart, aResultIndex); + } else { + GeomAlgoAPI_Scale aScaleAlgo(aBaseShape, aCenterPoint, aScaleFactor); + + if (!aScaleAlgo.check()) { + setError(aScaleAlgo.getError()); + return; + } + + aScaleAlgo.build(); + + // Checking that the algorithm worked properly. + if(!aScaleAlgo.isDone()) { + static const std::string aFeatureError = "Error: Symmetry algorithm failed."; + setError(aFeatureError); + break; + } + if(aScaleAlgo.shape()->isNull()) { + static const std::string aShapeError = "Error: Resulting shape is Null."; + setError(aShapeError); + break; + } + if(!aScaleAlgo.isValid()) { + std::string aFeatureError = "Error: Resulting shape is not valid."; + setError(aFeatureError); + break; + } + + ResultBodyPtr aResultBody = document()->createBody(data(), aResultIndex); + loadNamingDS(aScaleAlgo, aResultBody, aBaseShape); + setResult(aResultBody, aResultIndex); + } + aResultIndex++; + } + + // Remove the rest results if there were produced in the previous pass. + removeResults(aResultIndex); +} + +//================================================================================================= +void FeaturesPlugin_Scale::performScaleByDimensions() +{ + // Getting objects. + ListOfShape anObjects; + std::list aContextes; + AttributeSelectionListPtr anObjectsSelList = + selectionList(FeaturesPlugin_Scale::OBJECTS_LIST_ID()); + if (anObjectsSelList->size() == 0) { + return; + } + for(int anObjectsIndex = 0; anObjectsIndex < anObjectsSelList->size(); anObjectsIndex++) { + std::shared_ptr anObjectAttr = + anObjectsSelList->value(anObjectsIndex); + std::shared_ptr anObject = anObjectAttr->value(); + if(!anObject.get()) { // may be for not-activated parts + eraseResults(); + return; + } + anObjects.push_back(anObject); + aContextes.push_back(anObjectAttr->context()); + } + + // Getting the center point + std::shared_ptr aCenterPoint; + std::shared_ptr anObjRef = + selection(FeaturesPlugin_Scale::CENTER_POINT_ID()); + if (anObjRef.get() != NULL) { + GeomShapePtr aShape = anObjRef->value(); + if (!aShape.get()) { + aShape = anObjRef->context()->shape(); + } + if (aShape) { + aCenterPoint = GeomAlgoAPI_PointBuilder::point(aShape); + } + } + + // Getting dimensions + double aScaleFactorX = real(FeaturesPlugin_Scale::SCALE_FACTOR_X_ID())->value(); + double aScaleFactorY = real(FeaturesPlugin_Scale::SCALE_FACTOR_Y_ID())->value(); + double aScaleFactorZ = real(FeaturesPlugin_Scale::SCALE_FACTOR_Z_ID())->value(); + + // Moving each object. + int aResultIndex = 0; + std::list::iterator aContext = aContextes.begin(); + for(ListOfShape::iterator anObjectsIt = anObjects.begin(); anObjectsIt != anObjects.end(); + anObjectsIt++, aContext++) { + std::shared_ptr aBaseShape = *anObjectsIt; + bool isPart = (*aContext)->groupName() == ModelAPI_ResultPart::group(); + + // Setting result. + if (isPart) { + std::shared_ptr aTrsf(new GeomAPI_Trsf()); + //aTrsf->setSymmetry(anAxis); + ResultPartPtr anOrigin = std::dynamic_pointer_cast(*aContext); + ResultPartPtr aResultPart = document()->copyPart(anOrigin, data(), aResultIndex); + aResultPart->setTrsf(*aContext, aTrsf); + setResult(aResultPart, aResultIndex); + } else { + GeomAlgoAPI_Scale aScaleAlgo(aBaseShape, aCenterPoint, + aScaleFactorX, aScaleFactorY, aScaleFactorZ); + + if (!aScaleAlgo.check()) { + setError(aScaleAlgo.getError()); + return; + } + + aScaleAlgo.build(); + + // Checking that the algorithm worked properly. + if(!aScaleAlgo.isDone()) { + static const std::string aFeatureError = "Error: Symmetry algorithm failed."; + setError(aFeatureError); + break; + } + if(aScaleAlgo.shape()->isNull()) { + static const std::string aShapeError = "Error: Resulting shape is Null."; + setError(aShapeError); + break; + } + if(!aScaleAlgo.isValid()) { + std::string aFeatureError = "Error: Resulting shape is not valid."; + setError(aFeatureError); + break; + } + + ResultBodyPtr aResultBody = document()->createBody(data(), aResultIndex); + loadNamingDS(aScaleAlgo, aResultBody, aBaseShape); + setResult(aResultBody, aResultIndex); + } + aResultIndex++; + } + + // Remove the rest results if there were produced in the previous pass. + removeResults(aResultIndex); +} + +//================================================================================================= +void FeaturesPlugin_Scale::loadNamingDS(GeomAlgoAPI_Scale& theScaleAlgo, + std::shared_ptr theResultBody, + std::shared_ptr theBaseShape) +{ + // Store and name the result. + theResultBody->storeModified(theBaseShape, theScaleAlgo.shape()); + + // Name the faces + std::shared_ptr aSubShapes = theScaleAlgo.mapOfSubShapes(); + int aReflectedTag = 1; + std::string aReflectedName = "Scaled"; + theResultBody->loadAndOrientModifiedShapes(&theScaleAlgo, + theBaseShape, GeomAPI_Shape::FACE, + aReflectedTag, aReflectedName, *aSubShapes.get()); +} \ No newline at end of file diff --git a/src/FeaturesPlugin/FeaturesPlugin_Scale.h b/src/FeaturesPlugin/FeaturesPlugin_Scale.h new file mode 100644 index 000000000..71bf032a2 --- /dev/null +++ b/src/FeaturesPlugin/FeaturesPlugin_Scale.h @@ -0,0 +1,122 @@ +// Copyright (C) 2014-201x CEA/DEN, EDF R&D + +// File: FeaturesPlugin_Scale.h +// Created: 13 Jan 2017 +// Author: Clarisse Genrault (CEA) + +#ifndef FEATURESPLUGIN_SCALE_H_ +#define FEATURESPLUGIN_SCALE_H_ + +#include + +#include + +#include + +/** \class FeaturesPlugin_Scale + * \ingroup Plugins + * \brief Feature for changing the scale of an object. + */ +class FeaturesPlugin_Scale : public ModelAPI_Feature +{ + public: + /// Scale kind. + inline static const std::string& ID() + { + static const std::string MY_SCALE_ID("Scale"); + return MY_SCALE_ID; + } + + /// Attribute name for creation method. + inline static const std::string& CREATION_METHOD() + { + static const std::string MY_CREATION_METHOD_ID("CreationMethod"); + return MY_CREATION_METHOD_ID; + } + + /// Attribute name for creation method "ByFactor". + inline static const std::string& CREATION_METHOD_BY_FACTOR() + { + static const std::string MY_CREATION_METHOD_ID("ByFactor"); + return MY_CREATION_METHOD_ID; + } + + /// Attribute name for creation method "ByFactor". + inline static const std::string& CREATION_METHOD_BY_DIMENSIONS() + { + static const std::string MY_CREATION_METHOD_ID("ByDimensions"); + return MY_CREATION_METHOD_ID; + } + + /// Attribute name of referenced objects. + inline static const std::string& OBJECTS_LIST_ID() + { + static const std::string MY_OBJECTS_LIST_ID("main_objects"); + return MY_OBJECTS_LIST_ID; + } + + /// Attribute name of center point. + inline static const std::string& CENTER_POINT_ID() + { + static const std::string MY_CENTER_POINT_ID("center_point"); + return MY_CENTER_POINT_ID; + } + + /// Attribute name of scale factor. + inline static const std::string& SCALE_FACTOR_ID() + { + static const std::string MY_SCALE_FACTOR_ID("scale_factor"); + return MY_SCALE_FACTOR_ID; + } + + /// Attribute name of scale factor in X. + inline static const std::string& SCALE_FACTOR_X_ID() + { + static const std::string MY_SCALE_FACTOR_X_ID("scale_factor_x"); + return MY_SCALE_FACTOR_X_ID; + } + + /// Attribute name of scale factor in Y. + inline static const std::string& SCALE_FACTOR_Y_ID() + { + static const std::string MY_SCALE_FACTOR_Y_ID("scale_factor_y"); + return MY_SCALE_FACTOR_Y_ID; + } + + /// Attribute name of scale factor in Z. + inline static const std::string& SCALE_FACTOR_Z_ID() + { + static const std::string MY_SCALE_FACTOR_Z_ID("scale_factor_z"); + return MY_SCALE_FACTOR_Z_ID; + } + + /// \return the kind of a feature. + FEATURESPLUGIN_EXPORT virtual const std::string& getKind() + { + static std::string MY_KIND = FeaturesPlugin_Scale::ID(); + return MY_KIND; + } + + /// Creates a new part document if needed. + FEATURESPLUGIN_EXPORT virtual void execute(); + + /// Request for initialization of data model of the feature: adding all attributes. + FEATURESPLUGIN_EXPORT virtual void initAttributes(); + + /// Use plugin manager for features creation. + FeaturesPlugin_Scale(); + +private: + /// Perform scale using a central point and a value of the scale. + void performScaleByFactor(); + + /// Perform symmetry using a central point and three dimensions + void performScaleByDimensions(); + + /// Perform the naming + void loadNamingDS(GeomAlgoAPI_Scale& theScaleAlgo, + std::shared_ptr theResultBody, + std::shared_ptr theBaseShape); +}; + +#endif // FEATURESPLUGIN_SCALE_H_ \ No newline at end of file diff --git a/src/FeaturesPlugin/icons/SVG/scale.svg b/src/FeaturesPlugin/icons/SVG/scale.svg new file mode 100644 index 000000000..6e8d4c0f3 --- /dev/null +++ b/src/FeaturesPlugin/icons/SVG/scale.svg @@ -0,0 +1,332 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/FeaturesPlugin/icons/SVG/scale_dimensions_32x32.svg b/src/FeaturesPlugin/icons/SVG/scale_dimensions_32x32.svg new file mode 100644 index 000000000..f017244d4 --- /dev/null +++ b/src/FeaturesPlugin/icons/SVG/scale_dimensions_32x32.svg @@ -0,0 +1,102 @@ + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + diff --git a/src/FeaturesPlugin/icons/SVG/scale_factor_32x32.svg b/src/FeaturesPlugin/icons/SVG/scale_factor_32x32.svg new file mode 100644 index 000000000..39c7bc733 --- /dev/null +++ b/src/FeaturesPlugin/icons/SVG/scale_factor_32x32.svg @@ -0,0 +1,101 @@ + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + diff --git a/src/FeaturesPlugin/icons/scale.png b/src/FeaturesPlugin/icons/scale.png new file mode 100644 index 0000000000000000000000000000000000000000..156659c3fc760b9a55e668284025688172c42bc1 GIT binary patch literal 583 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`EX7WqAsj$Z!;#Vf2?p zUk71ECym(^Ktah8*NBqf{Irtt#G+J&^73-M%)IR4Mw#W&X$|IdGw{%8OEYwN!=#!j3$v2)?XeGmOpHU_8r#m?EEv{Ev7 zg?4a$mcZh>SEl}7K5y5r`$18TFRj~dOG?g+h>W-~(U4nP+Zg1$)2p}t|0ed`_+!51 zr~Q)cmp?L1yDg-s_$ac%kk!Q%v}Q2LEn8-v8g=Px_D73)S{bZ){{#-gTj| zeHOEGWCOFC*Oy5jxqcr2fgk_tFFk&{`nsSIM_$9$l{059?BfGDtlm5R`_b+1?`;yi z)RV-(&CSg$uP+ahU^W*1oS$T3Y~b+e5I-AR+x!zV=1>2wX>9yiG>M0SL3mg1i!@Q= RG+?ANc)I$ztaD0e0sz4c`~Uy| literal 0 HcmV?d00001 diff --git a/src/FeaturesPlugin/icons/scale_dimensions_32x32.png b/src/FeaturesPlugin/icons/scale_dimensions_32x32.png new file mode 100644 index 0000000000000000000000000000000000000000..b5204f9e886d3f73fbd14fcc134bdbe462d1174a GIT binary patch literal 1278 zcmVY>c(r5W~>H_zK$?^0je6 z0tpKdL5+z)(fECXVP0usVvKs@1;!h_KoWuI{3hrC0|uuM7eYV?u#OFs+LpnzY;AXF zPaiMZ;lOUJ`{21b=Y8Mjd4B)*Ie9;hVhmQX=5b$2H>(gS5>$bPa)RWg6gGuK6{;@< z5v3#wmX3fkb&-}9Gg~e-3Z5!ow|SMInv{|yBFqB{bJT1A=Ri)OwC|Nu_FZXdiQiQ~ z`PxSoh|+cei-z{QoKAdR9|f*_9CkZ4yB)jDhHlX@41*$Zsc4 z(0%z507_)FWw@ZvqP@Fs=+>GG#nX7fF@#nTr7OfN2>x~hsYuMcmjmol#xXP$FJa3YZ;7!DE) z2MGj2_`5o}*xk*>E8VEX7kxA|$BhQsb4 zZ;At(-HvY2iN)g#48$>R8YB|Q+x!(!)fX{bX7bn8(z3UkJAXfxwE_YQfjtVU0oc6R z;)_YWO7W0_xuVoOgt>rg#1cS4fnSt5YcT7u1ZUDaC{~h}e9neKf zJrA^J{Of@Iz|$)I%-OU%+Ed@EoWB#GqOAND9AJL+ytK#^b29L)z#qWsvBI+n*s`tb zTs=S__!s@r=&gYZet-H!sm{!Q3cQo0zeFG; z@aUv~hk%yK;05HrzUKs%3wS3Lo`LNa*fONOLEwVGtVxGwfZGLT3rxuzC|&{2WOMZl zJP+to;1~Fi^hwsM(tk9QYXZ#zFAH=D91|#z(fzVbn1B@m5dl-+-FpVkm_~ZGCeQ~Q oyw?JBU@5RM)2;&!-%A1i0x2!Er`kGsT>t<807*qoM6N<$fRlvNbRe`lC>TDEp-h0e5<2Fem1D4IyI#j+Fv z6e=ndEfO9yHHKBAL{JmU10*VjB_u>N1T-}06pZYPAX1hg|eV|g&116Cz&OMHj z);jsG;DoH4S*m;i*gHrw5G{~qS>)XBsOt*2But+1xgs9`Bq#MJBW)Ce2M#2BldX|hDYwWteodkh67+yCIkgnNMA5~#GztqEcQ5C z&|rXgo2_N7egVT3!hmmw+`nfBu!Mz&1dp&-TBbdNao!X7YHLE$X@I-;?}Y@fyK}c? zdea<;z~_1$kf+GAf>K&`IVAX{a<5L5KLT|=8;BKXs7f7r5~!)Jxk=fT@}R(~%C9Gm z0brQ)r%vGtW?%=92S9$lA;>C#g6$66Zg;@&W2a7V?Ro`()6_$@2I71UuvXyDN0FYo z7PwS-!^wut8v`of+=cUODg43vAo9M`;dt2T4X02DtP(ixACJ#^Z4hdl1Y#27y` zhe62$AJaEHY+(1neH{GdFor6Mepa=&a0zsBy(**u6^U6nV^n!v!6xvVA2y>j>W=M!>rB6%PS6@3qH6XBo7_*+%Rx!y4cjuh>S?d5T=1_}hU zGkDB}-qFh@rcan>2@hxX%v_0&v$6NkL5k0wL4+db9>*gWz5uvwtCJ%jC?_BVjOx5F(i0K?FK7gt5Sk7|mDP#@5uFjwI_zzO6D zeAy8gyx(wZ*JfZBa70n7AjXknMH2UPAF2P!d761i!59b=+_CB`7 zZH>paUExh&oOo|F;wQ~qf#_2IoG6dGZtTsfsq0Eke+twAiv<1(1lSpTJFrsVL`%$` zHDj8n0`vofDO^!_ z(JwYYVWq-T3d + + + diff --git a/src/FeaturesPlugin/scale_widget.xml b/src/FeaturesPlugin/scale_widget.xml new file mode 100644 index 000000000..3f6f8122d --- /dev/null +++ b/src/FeaturesPlugin/scale_widget.xml @@ -0,0 +1,76 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/GeomAlgoAPI/CMakeLists.txt b/src/GeomAlgoAPI/CMakeLists.txt index 68048d8e9..352e5738d 100644 --- a/src/GeomAlgoAPI/CMakeLists.txt +++ b/src/GeomAlgoAPI/CMakeLists.txt @@ -49,6 +49,7 @@ SET(PROJECT_HEADERS GeomAlgoAPI_Copy.h GeomAlgoAPI_ConeSegment.h GeomAlgoAPI_Symmetry.h + GeomAlgoAPI_Scale.h ) SET(PROJECT_SOURCES @@ -93,6 +94,7 @@ SET(PROJECT_SOURCES GeomAlgoAPI_Copy.cpp GeomAlgoAPI_ConeSegment.cpp GeomAlgoAPI_Symmetry.cpp + GeomAlgoAPI_Scale.cpp ) SET(PROJECT_LIBRARIES @@ -161,6 +163,7 @@ INSTALL(FILES ${SWIG_SCRIPTS} DESTINATION ${SHAPER_INSTALL_SWIG}) ADD_UNIT_TESTS(TestAPI_Box.py TestAPI_Cylinder.py TestAPI_GDMLConeSegment.py + TestAPI_Scale.py TestAPI_Symmetry.py TestAPI_Translation.py) diff --git a/src/GeomAlgoAPI/GeomAlgoAPI_Scale.cpp b/src/GeomAlgoAPI/GeomAlgoAPI_Scale.cpp new file mode 100644 index 000000000..bfdd1d0a4 --- /dev/null +++ b/src/GeomAlgoAPI/GeomAlgoAPI_Scale.cpp @@ -0,0 +1,184 @@ +// Copyright (C) 2014-201x CEA/DEN, EDF R&D + +// File: GeomAlgoAPI_Scale.cpp +// Created: 23 Jan 2017 +// Author: Clarisse Genrault (CEA) + +#include "GeomAlgoAPI_Scale.h" + +#include +#include + +//================================================================================================= +GeomAlgoAPI_Scale::GeomAlgoAPI_Scale(std::shared_ptr theSourceShape, + std::shared_ptr theCenterPoint, + double theScaleFactor) +{ + myMethodType = BY_FACTOR; + mySourceShape = theSourceShape; + myCenterPoint = theCenterPoint; + myScaleFactor = theScaleFactor; +} + +//================================================================================================= +GeomAlgoAPI_Scale::GeomAlgoAPI_Scale(std::shared_ptr theSourceShape, + std::shared_ptr theCenterPoint, + double theScaleFactorX, + double theScaleFactorY, + double theScaleFactorZ) +{ + myMethodType = BY_DIMENSIONS; + mySourceShape = theSourceShape; + myCenterPoint = theCenterPoint; + myScaleFactorX = theScaleFactorX; + myScaleFactorY = theScaleFactorY; + myScaleFactorZ = theScaleFactorZ; +} + +//================================================================================================= +bool GeomAlgoAPI_Scale::check() +{ + if (!mySourceShape) { + myError = "Scale builder :: source shape is invalid."; + return false; + } + if (!myCenterPoint) { + myError = "Scale builder :: center point is invalid."; + return false; + } + switch (myMethodType) { + case BY_FACTOR: { + if (fabs(myScaleFactor) < Precision::Confusion()) { + myError = "Scale builder :: the scale factor is null."; + return false; + } + return true; + } + case BY_DIMENSIONS: { + if (fabs(myScaleFactorX) < Precision::Confusion()) { + myError = "Scale builder :: the scale factor in X is null."; + return false; + } + if (fabs(myScaleFactorY) < Precision::Confusion()) { + myError = "Scale builder :: the scale factor in Y is null."; + return false; + } + if (fabs(myScaleFactorZ) < Precision::Confusion()) { + myError = "Scale builder :: the scale factor in Z is null."; + return false; + } + return true; + } + default: { + myError = "Scale builder :: method not implemented."; + return false; + } + } +} + +//================================================================================================= +void GeomAlgoAPI_Scale::build() +{ + switch (myMethodType) { + case BY_FACTOR : { + buildByFactor(); + break; + } + case BY_DIMENSIONS : { + buildByDimensions(); + break; + } + default : { + myError = "Scale builder :: method not yet implemented"; + return; + } + } +} + +//================================================================================================= +void GeomAlgoAPI_Scale::buildByFactor() +{ + const gp_Pnt& aCenterPoint = myCenterPoint->impl(); + gp_Trsf* aTrsf = new gp_Trsf(); + aTrsf->SetScale(aCenterPoint, myScaleFactor); + + const TopoDS_Shape& aSourceShape = mySourceShape->impl(); + + if(aSourceShape.IsNull()) { + myError = "Scale builder :: source shape does not contain any actual shape."; + return; + } + + // Transform the shape while copying it. + BRepBuilderAPI_Transform* aBuilder = new BRepBuilderAPI_Transform(aSourceShape, *aTrsf, true); + if(!aBuilder) { + myError = "Scale builder :: transform initialization failed."; + return; + } + + setImpl(aBuilder); + setBuilderType(OCCT_BRepBuilderAPI_MakeShape); + + if(!aBuilder->IsDone()) { + myError = "Scale builder :: algorithm failed."; + return; + } + + TopoDS_Shape aResult = aBuilder->Shape(); + + std::shared_ptr aShape(new GeomAPI_Shape()); + aShape->setImpl(new TopoDS_Shape(aResult)); + setShape(aShape); + setDone(true); +} + +//================================================================================================= +void GeomAlgoAPI_Scale::buildByDimensions() +{ + const gp_Pnt& aCenterPoint = myCenterPoint->impl(); + + // Perform the rotation matrix + gp_Mat aMatRot(myScaleFactorX, 0., 0., + 0., myScaleFactorY, 0., + 0., 0., myScaleFactorZ); + + // Perform the tranformation + gp_Pnt anOriginPnt(0., 0., 0.); + gp_GTrsf aGTrsf; + gp_GTrsf aGTrsfP0; + gp_GTrsf aGTrsf0P; + aGTrsfP0.SetTranslationPart(anOriginPnt.XYZ() - aCenterPoint.XYZ()); + aGTrsf0P.SetTranslationPart(aCenterPoint.XYZ()); + aGTrsf.SetVectorialPart(aMatRot); + aGTrsf = aGTrsf0P.Multiplied(aGTrsf); + aGTrsf = aGTrsf.Multiplied(aGTrsfP0); + + const TopoDS_Shape& aSourceShape = mySourceShape->impl(); + + if(aSourceShape.IsNull()) { + myError = "Scale builder :: source shape does not contain any actual shape."; + return; + } + + // Transform the shape while copying it. + BRepBuilderAPI_GTransform* aBuilder = new BRepBuilderAPI_GTransform(aSourceShape, aGTrsf, true); + if(!aBuilder) { + myError = "Scale builder :: transform initialization failed."; + return; + } + + setImpl(aBuilder); + setBuilderType(OCCT_BRepBuilderAPI_MakeShape); + + if(!aBuilder->IsDone()) { + myError = "Scale builder :: algorithm failed."; + return; + } + + TopoDS_Shape aResult = aBuilder->Shape(); + + std::shared_ptr aShape(new GeomAPI_Shape()); + aShape->setImpl(new TopoDS_Shape(aResult)); + setShape(aShape); + setDone(true); +} diff --git a/src/GeomAlgoAPI/GeomAlgoAPI_Scale.h b/src/GeomAlgoAPI/GeomAlgoAPI_Scale.h new file mode 100644 index 000000000..3fcb1c486 --- /dev/null +++ b/src/GeomAlgoAPI/GeomAlgoAPI_Scale.h @@ -0,0 +1,68 @@ +// Copyright (C) 2014-201x CEA/DEN, EDF R&D + +// File: GeomAlgoAPI_Scale.h +// Created: 23 Jan 2017 +// Author: Clarisse Genrault (CEA) + +#ifndef GEOMALGOAPI_SCALE_H_ +#define GEOMALGOAPI_SCALE_H_ + +#include + +#include + +/// \class GeomAlgoAPI_Scale +/// \ingroup DataAlgo +/// \brief Creates a copy of the object by performing a scale operation by a factor or +/// by dimensions. +class GeomAlgoAPI_Scale : public GeomAlgoAPI_MakeShape +{ +public: + /// Type of scale operation + enum MethodType { + BY_FACTOR, ///< Scale by factor. + BY_DIMENSIONS, ///< Scale by dimensions. + }; + + /// \brief Creates an object which is obtained from current object by performing + /// a scale operation by a factor. + /// \param[in] theSourceShape the shape to be moved. + /// \param[in] theCenterPoint the center point. + /// \param[in] theFactor the scale factor. + GEOMALGOAPI_EXPORT GeomAlgoAPI_Scale(std::shared_ptr theSourceShape, + std::shared_ptr theCenterPoint, + double theScaleFactor); + + /// \brief Creates an object which is obtained from current object by performing + /// a scale operation by dimensions. + /// \param[in] theSourceShape the shape to be moved. + /// \param[in] theCenterPoint the center point. + /// \param[in] theFactorX the scale factor in X. + /// \param[in] theFactorY the scale factor in Y. + /// \param[in] theFactorZ the scale factor in Z. + GEOMALGOAPI_EXPORT GeomAlgoAPI_Scale(std::shared_ptr theSourceShape, + std::shared_ptr theCenterPoint, + double theScaleFactorX, + double theScaleFactorY, + double theScaleFactorZ); + + /// Checks if data for the scale transform is OK. + GEOMALGOAPI_EXPORT bool check(); + + /// Execute the scale transform. + GEOMALGOAPI_EXPORT void build(); + +private: + MethodType myMethodType; /// Type of method used. + std::shared_ptr mySourceShape; /// Shape to be moved. + std::shared_ptr myCenterPoint; /// Center point. + double myScaleFactor; /// Scale factor. + double myScaleFactorX; /// Scale factor in X. + double myScaleFactorY; /// Scale factor in Y. + double myScaleFactorZ; /// Scale factor in Z. + + void buildByFactor(); + void buildByDimensions(); +}; + +#endif // GEOMALGOAPI_SCALE_H_ \ No newline at end of file diff --git a/src/GeomAlgoAPI/GeomAlgoAPI_ShapeAPI.cpp b/src/GeomAlgoAPI/GeomAlgoAPI_ShapeAPI.cpp index 223517a4a..faba77138 100644 --- a/src/GeomAlgoAPI/GeomAlgoAPI_ShapeAPI.cpp +++ b/src/GeomAlgoAPI/GeomAlgoAPI_ShapeAPI.cpp @@ -10,6 +10,7 @@ #include #include #include +#include #include #include @@ -305,6 +306,55 @@ namespace GeomAlgoAPI_ShapeAPI return aSymmetryAlgo.shape(); } + //=============================================================================================== + std::shared_ptr GeomAlgoAPI_ShapeAPI::makeScale( + std::shared_ptr theSourceShape, + std::shared_ptr theCenterPoint, + const double theScaleFactor) throw (GeomAlgoAPI_Exception) + { + GeomAlgoAPI_Scale aScaleAlgo(theSourceShape, theCenterPoint, theScaleFactor); + + if (!aScaleAlgo.check()) { + throw GeomAlgoAPI_Exception(aScaleAlgo.getError()); + } + + aScaleAlgo.build(); + + if(!aScaleAlgo.isDone()) { + throw GeomAlgoAPI_Exception(aScaleAlgo.getError()); + } + if (!aScaleAlgo.checkValid("Scale builder by a scale factor")) { + throw GeomAlgoAPI_Exception(aScaleAlgo.getError()); + } + return aScaleAlgo.shape(); + } + + //=============================================================================================== + std::shared_ptr GeomAlgoAPI_ShapeAPI::makeScale( + std::shared_ptr theSourceShape, + std::shared_ptr theCenterPoint, + const double theScaleFactorX, + const double theScaleFactorY, + const double theScaleFactorZ) throw (GeomAlgoAPI_Exception) + { + GeomAlgoAPI_Scale aScaleAlgo(theSourceShape, theCenterPoint, + theScaleFactorX, theScaleFactorY, theScaleFactorZ); + + if (!aScaleAlgo.check()) { + throw GeomAlgoAPI_Exception(aScaleAlgo.getError()); + } + + aScaleAlgo.build(); + + if(!aScaleAlgo.isDone()) { + throw GeomAlgoAPI_Exception(aScaleAlgo.getError()); + } + if (!aScaleAlgo.checkValid("Scale builder by dimensions")) { + throw GeomAlgoAPI_Exception(aScaleAlgo.getError()); + } + return aScaleAlgo.shape(); + } + //=============================================================================================== std::shared_ptr GeomAlgoAPI_ShapeAPI::makeConeSegment( const double theRMin1, const double theRMax1, diff --git a/src/GeomAlgoAPI/GeomAlgoAPI_ShapeAPI.h b/src/GeomAlgoAPI/GeomAlgoAPI_ShapeAPI.h index 454f88495..2f478373b 100644 --- a/src/GeomAlgoAPI/GeomAlgoAPI_ShapeAPI.h +++ b/src/GeomAlgoAPI/GeomAlgoAPI_ShapeAPI.h @@ -124,6 +124,28 @@ public: std::shared_ptr theSourceShape, std::shared_ptr thePlane) throw (GeomAlgoAPI_Exception); + /// Performs a scale by a scale factor. + /// \param theSourceShape Shape be scaled + /// \param theCenterPoint Point of scale + /// \param theScaleFactor Factor of scale + static std::shared_ptr makeScale( + std::shared_ptr theSourceShape, + std::shared_ptr theCenterPoint, + const double theScaleFactor) throw (GeomAlgoAPI_Exception); + + /// Performs a scale by dimensions. + /// \param theSourceShape Shape be scaled + /// \param theCenterPoint Point of scale + /// \param theScaleFactorX Factor of scale in X + /// \param theScaleFactorY Factor of scale in Y + /// \param theScaleFactorZ Factor of scale in Z + static std::shared_ptr makeScale( + std::shared_ptr theSourceShape, + std::shared_ptr theCenterPoint, + const double theScaleFactorX, + const double theScaleFactorY, + const double theScaleFactorZ) throw (GeomAlgoAPI_Exception); + /// Creates a cone segment using standard GDML parameters. /// \param theRMin1 Inner radius at base of cone /// \param theRMax1 Outer radius at base of cone diff --git a/src/GeomAlgoAPI/Test/TestAPI_Scale.py b/src/GeomAlgoAPI/Test/TestAPI_Scale.py new file mode 100644 index 000000000..a60134807 --- /dev/null +++ b/src/GeomAlgoAPI/Test/TestAPI_Scale.py @@ -0,0 +1,32 @@ +# Copyright (C) 2014-201x CEA/DEN, EDF R&D + +# File: TestAPI_Scale.py +# Created: 25 Jan 2017 +# Author: Clarisse Genrault (CEA) + +from GeomAlgoAPI import GeomAlgoAPI_ShapeAPI as shaperpy +from GeomAlgoAPI import GeomAlgoAPI_Exception as myExcept +from GeomAPI import GeomAPI_Pnt as pnt + +# Create a box +try : + box1 = shaperpy.makeBox(10.,10.,10.) + box2 = shaperpy.makeBox(10.,10.,10.) + centerPoint = pnt(20.,20.,0.) + +except myExcept, ec: + print ec.what() + +# Perfom a scale by a factor. +try : + scale1 = shaperpy.makeScale(box1,centerPoint, -1.6) + +except myExcept, ec: + print ec.what() + +# Perfom a scale by dimensions. +try : + scale2 = shaperpy.makeScale(box2,centerPoint, 2, -0.5, 1.3) + +except myExcept, ec: + print ec.what() diff --git a/src/PythonAPI/model/features/__init__.py b/src/PythonAPI/model/features/__init__.py index 07471e912..4632e171a 100644 --- a/src/PythonAPI/model/features/__init__.py +++ b/src/PythonAPI/model/features/__init__.py @@ -1,7 +1,7 @@ """Package for Features plugin for the Parametric Geometry API of the Modeler. """ -from FeaturesAPI import addPlacement, addRotation, addSymmetry, addTranslation +from FeaturesAPI import addPlacement, addRotation, addScale, addSymmetry, addTranslation from FeaturesAPI import addExtrusion, addExtrusionCut, addExtrusionFuse from FeaturesAPI import addRevolution, addRevolutionCut, addRevolutionFuse from FeaturesAPI import addPipe -- 2.39.2