From 517e702f8072ad116543beaf90a69b3f4fc05220 Mon Sep 17 00:00:00 2001 From: Clarisse Genrault Date: Thu, 16 Feb 2017 15:51:30 +0100 Subject: [PATCH] Added the scale with deformation. --- src/FeaturesAPI/FeaturesAPI_Scale.cpp | 58 ++++++- src/FeaturesAPI/FeaturesAPI_Scale.h | 38 ++++- src/FeaturesAPI/Test/APIParam_Scale.py | 9 +- src/FeaturesPlugin/FeaturesPlugin_Scale.cpp | 180 +++++++++++++++----- src/FeaturesPlugin/FeaturesPlugin_Scale.h | 48 ++++++ src/FeaturesPlugin/scale_widget.xml | 95 ++++++++--- src/GeomAPI/GeomAPI_Trsf.cpp | 7 - src/GeomAPI/GeomAPI_Trsf.h | 7 - src/GeomAlgoAPI/GeomAlgoAPI_Scale.cpp | 119 ++++++++++++- src/GeomAlgoAPI/GeomAlgoAPI_Scale.h | 26 +++ src/GeomAlgoAPI/Test/TestAPI_Scale.py | 8 + 11 files changed, 508 insertions(+), 87 deletions(-) diff --git a/src/FeaturesAPI/FeaturesAPI_Scale.cpp b/src/FeaturesAPI/FeaturesAPI_Scale.cpp index d402713bc..e80f3b4cf 100644 --- a/src/FeaturesAPI/FeaturesAPI_Scale.cpp +++ b/src/FeaturesAPI/FeaturesAPI_Scale.cpp @@ -30,6 +30,22 @@ FeaturesAPI_Scale::FeaturesAPI_Scale(const std::shared_ptr& th } } +//================================================================================================== +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() { @@ -52,10 +68,23 @@ void FeaturesAPI_Scale::setCenterPoint(const ModelHighAPI_Selection& theCenterPo //================================================================================================== 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 { @@ -70,9 +99,23 @@ void FeaturesAPI_Scale::dump(ModelHighAPI_Dumper& theDumper) const aBase->selection(FeaturesPlugin_Scale::CENTER_POINT_ID()); theDumper << " , " << anAttrPoint; - AttributeDoublePtr anAttrScaleFactor = + 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; } @@ -85,4 +128,17 @@ ScalePtr addScale(const std::shared_ptr& thePart, { 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 index 137763c62..d53ff1777 100644 --- a/src/FeaturesAPI/FeaturesAPI_Scale.h +++ b/src/FeaturesAPI/FeaturesAPI_Scale.h @@ -35,17 +35,34 @@ public: 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_3(FeaturesPlugin_Scale::ID(), + 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 */) + 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 @@ -59,6 +76,13 @@ public: 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; @@ -75,4 +99,14 @@ ScalePtr addScale(const std::shared_ptr& thePart, 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/Test/APIParam_Scale.py b/src/FeaturesAPI/Test/APIParam_Scale.py index ea6895052..f0a33e077 100644 --- a/src/FeaturesAPI/Test/APIParam_Scale.py +++ b/src/FeaturesAPI/Test/APIParam_Scale.py @@ -21,10 +21,17 @@ aSession.finishOperation() 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) \ No newline at end of file +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/FeaturesPlugin_Scale.cpp b/src/FeaturesPlugin/FeaturesPlugin_Scale.cpp index e216dc452..2584cc786 100644 --- a/src/FeaturesPlugin/FeaturesPlugin_Scale.cpp +++ b/src/FeaturesPlugin/FeaturesPlugin_Scale.cpp @@ -24,6 +24,9 @@ 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())); @@ -33,10 +36,32 @@ void FeaturesPlugin_Scale::initAttributes() 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; @@ -81,47 +106,120 @@ void FeaturesPlugin_Scale::execute() 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->setScale(aCenterPoint, aScaleFactor); - 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); + 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; + 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++; } @@ -144,4 +242,4 @@ void FeaturesPlugin_Scale::loadNamingDS(GeomAlgoAPI_Scale& theScaleAlgo, 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 index 9c01fb670..71bf032a2 100644 --- a/src/FeaturesPlugin/FeaturesPlugin_Scale.h +++ b/src/FeaturesPlugin/FeaturesPlugin_Scale.h @@ -27,6 +27,27 @@ class FeaturesPlugin_Scale : public ModelAPI_Feature 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() { @@ -48,6 +69,27 @@ class FeaturesPlugin_Scale : public ModelAPI_Feature 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() { @@ -65,6 +107,12 @@ class FeaturesPlugin_Scale : public ModelAPI_Feature 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, diff --git a/src/FeaturesPlugin/scale_widget.xml b/src/FeaturesPlugin/scale_widget.xml index 45ffe043c..cbfa18244 100644 --- a/src/FeaturesPlugin/scale_widget.xml +++ b/src/FeaturesPlugin/scale_widget.xml @@ -1,27 +1,76 @@ - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/GeomAPI/GeomAPI_Trsf.cpp b/src/GeomAPI/GeomAPI_Trsf.cpp index 627459963..701e0bdff 100644 --- a/src/GeomAPI/GeomAPI_Trsf.cpp +++ b/src/GeomAPI/GeomAPI_Trsf.cpp @@ -76,10 +76,3 @@ void GeomAPI_Trsf::setSymmetry(const std::shared_ptr thePlane) { MY_TRSF->SetMirror(thePlane->impl()); } - -//================================================================================================= -void GeomAPI_Trsf::setScale(const std::shared_ptr theCenterPoint, - const double theScaleFactor) -{ - MY_TRSF->SetScale(theCenterPoint->impl(), theScaleFactor); -} diff --git a/src/GeomAPI/GeomAPI_Trsf.h b/src/GeomAPI/GeomAPI_Trsf.h index a49ce81c6..9f7a7f811 100644 --- a/src/GeomAPI/GeomAPI_Trsf.h +++ b/src/GeomAPI/GeomAPI_Trsf.h @@ -73,13 +73,6 @@ class GeomAPI_Trsf : public GeomAPI_Interface * \param[in] thePlane symmetry plane. */ GEOMAPI_EXPORT void setSymmetry(const std::shared_ptr thePlane); - - /** \brief Sets a scale transformation using a factor. - * \param[in] theCenterPoint center point. - * \param[in] theScaleFactor scale factor. - */ - GEOMAPI_EXPORT void setScale(const std::shared_ptr theCenterPoint, - const double theScaleFactor); }; #endif diff --git a/src/GeomAlgoAPI/GeomAlgoAPI_Scale.cpp b/src/GeomAlgoAPI/GeomAlgoAPI_Scale.cpp index 28484c4d4..bfdd1d0a4 100644 --- a/src/GeomAlgoAPI/GeomAlgoAPI_Scale.cpp +++ b/src/GeomAlgoAPI/GeomAlgoAPI_Scale.cpp @@ -7,18 +7,34 @@ #include "GeomAlgoAPI_Scale.h" #include -#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() { @@ -30,15 +46,57 @@ bool GeomAlgoAPI_Scale::check() myError = "Scale builder :: center point is invalid."; return false; } - if (fabs(myScaleFactor) < Precision::Confusion()) { - myError = "Scale builder :: the scale factor is null."; - 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; + } } - return true; } //================================================================================================= 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(); @@ -73,3 +131,54 @@ void GeomAlgoAPI_Scale::build() 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 index b78a84f09..3fcb1c486 100644 --- a/src/GeomAlgoAPI/GeomAlgoAPI_Scale.h +++ b/src/GeomAlgoAPI/GeomAlgoAPI_Scale.h @@ -18,6 +18,12 @@ 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. @@ -27,6 +33,19 @@ public: 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(); @@ -34,9 +53,16 @@ public: 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/Test/TestAPI_Scale.py b/src/GeomAlgoAPI/Test/TestAPI_Scale.py index 791a9c047..a60134807 100644 --- a/src/GeomAlgoAPI/Test/TestAPI_Scale.py +++ b/src/GeomAlgoAPI/Test/TestAPI_Scale.py @@ -11,6 +11,7 @@ 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: @@ -22,3 +23,10 @@ try : 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() -- 2.39.2