From: Clarisse Genrault Date: Tue, 7 Mar 2017 12:55:18 +0000 (+0100) Subject: Added rotation by three points. X-Git-Tag: V_2.7.0~251 X-Git-Url: http://git.salome-platform.org/gitweb/?a=commitdiff_plain;h=6875c6f5fd925c6a340e92d9cda09bbae9d243ee;p=modules%2Fshaper.git Added rotation by three points. --- diff --git a/src/FeaturesAPI/FeaturesAPI_Rotation.cpp b/src/FeaturesAPI/FeaturesAPI_Rotation.cpp index 366a751b4..ef0c55fdb 100644 --- a/src/FeaturesAPI/FeaturesAPI_Rotation.cpp +++ b/src/FeaturesAPI/FeaturesAPI_Rotation.cpp @@ -30,6 +30,20 @@ FeaturesAPI_Rotation::FeaturesAPI_Rotation(const std::shared_ptr& theFeature, + const std::list& theMainObjects, + const ModelHighAPI_Selection& theCenterPoint, + const ModelHighAPI_Selection& theStartPoint, + const ModelHighAPI_Selection& theEndPoint) +: ModelHighAPI_Interface(theFeature) +{ + if(initialize()) { + fillAttribute(theMainObjects, mymainObjects); + setPoints(theCenterPoint, theStartPoint, theEndPoint); + } +} + //================================================================================================== FeaturesAPI_Rotation::~FeaturesAPI_Rotation() { @@ -47,6 +61,7 @@ void FeaturesAPI_Rotation::setMainObjects(const std::listselectionList(FeaturesPlugin_Rotation::OBJECTS_LIST_ID()); - AttributeSelectionPtr anAttrAxis = aBase->selection(FeaturesPlugin_Rotation::AXIS_OBJECT_ID()); - AttributeDoublePtr anAttrAngle = aBase->real(FeaturesPlugin_Rotation::ANGLE_ID()); - theDumper << aBase << " = model.addRotation(" << aDocName << ", " - << anAttrObjects << ", " << anAttrAxis << ", " << anAttrAngle << ")" << std::endl; + theDumper << aBase << " = model.addRotation(" << aDocName << ", " << anAttrObjects; + + std::string aCreationMethod = + aBase->string(FeaturesPlugin_Rotation::CREATION_METHOD())->value(); + + if (aCreationMethod == FeaturesPlugin_Rotation::CREATION_METHOD_BY_ANGLE()) { + AttributeSelectionPtr anAttrAxis = aBase->selection(FeaturesPlugin_Rotation::AXIS_OBJECT_ID()); + AttributeDoublePtr anAttrAngle = aBase->real(FeaturesPlugin_Rotation::ANGLE_ID()); + theDumper << ", " << anAttrAxis << ", " << anAttrAngle; + } else if (aCreationMethod == FeaturesPlugin_Rotation::CREATION_METHOD_BY_THREE_POINTS()) { + AttributeSelectionPtr anAttrCenterPoint = + aBase->selection(FeaturesPlugin_Rotation::CENTER_POINT_ID()); + AttributeSelectionPtr anAttrStartPoint = + aBase->selection(FeaturesPlugin_Rotation::START_POINT_ID()); + AttributeSelectionPtr anAttrEndPoint = + aBase->selection(FeaturesPlugin_Rotation::END_POINT_ID()); + theDumper << ", " << anAttrCenterPoint << ", " << anAttrStartPoint << ", " << anAttrEndPoint; + } + + theDumper << ")" << std::endl; } //================================================================================================== @@ -84,3 +129,15 @@ RotationPtr addRotation(const std::shared_ptr& thePart, std::shared_ptr aFeature = thePart->addFeature(FeaturesAPI_Rotation::ID()); return RotationPtr(new FeaturesAPI_Rotation(aFeature, theMainObjects, theAxisObject, theAngle)); } + +//================================================================================================== +RotationPtr addRotation(const std::shared_ptr& thePart, + const std::list& theMainObjects, + const ModelHighAPI_Selection& theCenterPoint, + const ModelHighAPI_Selection& theStartPoint, + const ModelHighAPI_Selection& theEndPoint) +{ + std::shared_ptr aFeature = thePart->addFeature(FeaturesAPI_Rotation::ID()); + return RotationPtr(new FeaturesAPI_Rotation(aFeature, theMainObjects, theCenterPoint, + theStartPoint, theEndPoint)); +} diff --git a/src/FeaturesAPI/FeaturesAPI_Rotation.h b/src/FeaturesAPI/FeaturesAPI_Rotation.h index 243af921b..c123f02e9 100644 --- a/src/FeaturesAPI/FeaturesAPI_Rotation.h +++ b/src/FeaturesAPI/FeaturesAPI_Rotation.h @@ -35,17 +35,34 @@ public: const ModelHighAPI_Selection& theAxisObject, const ModelHighAPI_Double& theAngle); + /// Constructor with values. + FEATURESAPI_EXPORT + FeaturesAPI_Rotation(const std::shared_ptr& theFeature, + const std::list& theMainObjects, + const ModelHighAPI_Selection& theCenterPoint, + const ModelHighAPI_Selection& theStartPoint, + const ModelHighAPI_Selection& theEndPoint); + /// Destructor. FEATURESAPI_EXPORT virtual ~FeaturesAPI_Rotation(); - INTERFACE_3(FeaturesPlugin_Rotation::ID(), + INTERFACE_7(FeaturesPlugin_Rotation::ID(), + creationMethod, FeaturesPlugin_Rotation::CREATION_METHOD(), + ModelAPI_AttributeString, /** Creation method */, mainObjects, FeaturesPlugin_Rotation::OBJECTS_LIST_ID(), ModelAPI_AttributeSelectionList, /** Main objects */, axisObject, FeaturesPlugin_Rotation::AXIS_OBJECT_ID(), ModelAPI_AttributeSelection, /** Axis object */, angle, FeaturesPlugin_Rotation::ANGLE_ID(), - ModelAPI_AttributeDouble, /** Angle */) + ModelAPI_AttributeDouble, /** Angle */, + centerPoint, FeaturesPlugin_Rotation::CENTER_POINT_ID(), + ModelAPI_AttributeSelection, /** Center point */, + startPoint, FeaturesPlugin_Rotation::START_POINT_ID(), + ModelAPI_AttributeSelection, /** Start point */, + endPoint, FeaturesPlugin_Rotation::END_POINT_ID(), + ModelAPI_AttributeSelection, /** End point */ + ) /// Set main objects. FEATURESAPI_EXPORT @@ -59,6 +76,11 @@ public: FEATURESAPI_EXPORT void setAngle(const ModelHighAPI_Double& theAngle); + /// Set center point, start point and end point + void setPoints(const ModelHighAPI_Selection& theCenterPoint, + const ModelHighAPI_Selection& theStartPoint, + const ModelHighAPI_Selection& theEndPoint); + /// Dump wrapped feature FEATURESAPI_EXPORT virtual void dump(ModelHighAPI_Dumper& theDumper) const; @@ -75,4 +97,13 @@ RotationPtr addRotation(const std::shared_ptr& thePart, const ModelHighAPI_Selection& theAxisObject, const ModelHighAPI_Double& theAngle); +/// \ingroup CPPHighAPI +/// \brief Create Rotation feature. +FEATURESAPI_EXPORT +RotationPtr addRotation(const std::shared_ptr& thePart, + const std::list& theMainObjects, + const ModelHighAPI_Selection& theCenterPoint, + const ModelHighAPI_Selection& theStartPoint, + const ModelHighAPI_Selection& theEndPoint); + #endif // FeaturesAPI_Rotation_H_ diff --git a/src/FeaturesPlugin/FeaturesPlugin_Rotation.cpp b/src/FeaturesPlugin/FeaturesPlugin_Rotation.cpp index 16028546c..41e0468be 100755 --- a/src/FeaturesPlugin/FeaturesPlugin_Rotation.cpp +++ b/src/FeaturesPlugin/FeaturesPlugin_Rotation.cpp @@ -8,9 +8,12 @@ #include #include +#include #include #include +#include + #include #include @@ -24,6 +27,9 @@ FeaturesPlugin_Rotation::FeaturesPlugin_Rotation() //================================================================================================= void FeaturesPlugin_Rotation::initAttributes() { + data()->addAttribute(FeaturesPlugin_Rotation::CREATION_METHOD(), + ModelAPI_AttributeString::typeId()); + AttributeSelectionListPtr aSelection = std::dynamic_pointer_cast(data()->addAttribute( FeaturesPlugin_Rotation::OBJECTS_LIST_ID(), ModelAPI_AttributeSelectionList::typeId())); @@ -31,10 +37,32 @@ void FeaturesPlugin_Rotation::initAttributes() data()->addAttribute(FeaturesPlugin_Rotation::AXIS_OBJECT_ID(), ModelAPI_AttributeSelection::typeId()); data()->addAttribute(FeaturesPlugin_Rotation::ANGLE_ID(), ModelAPI_AttributeDouble::typeId()); + + data()->addAttribute(FeaturesPlugin_Rotation::CENTER_POINT_ID(), + ModelAPI_AttributeSelection::typeId()); + data()->addAttribute(FeaturesPlugin_Rotation::START_POINT_ID(), + ModelAPI_AttributeSelection::typeId()); + data()->addAttribute(FeaturesPlugin_Rotation::END_POINT_ID(), + ModelAPI_AttributeSelection::typeId()); } //================================================================================================= void FeaturesPlugin_Rotation::execute() +{ + AttributeStringPtr aMethodTypeAttr = string(FeaturesPlugin_Rotation::CREATION_METHOD()); + std::string aMethodType = aMethodTypeAttr->value(); + + if (aMethodType == CREATION_METHOD_BY_ANGLE()) { + performTranslationByAxisAndAngle(); + } + + if (aMethodType == CREATION_METHOD_BY_THREE_POINTS()) { + performTranslationByThreePoints(); + } +} + +//================================================================================================= +void FeaturesPlugin_Rotation::performTranslationByAxisAndAngle() { // Getting objects. ListOfShape anObjects; @@ -93,6 +121,13 @@ void FeaturesPlugin_Rotation::execute() } else { GeomAlgoAPI_Rotation aRotationAlgo(aBaseShape, anAxis, anAngle); + if (!aRotationAlgo.check()) { + setError(aRotationAlgo.getError()); + return; + } + + aRotationAlgo.build(); + // Checking that the algorithm worked properly. if(!aRotationAlgo.isDone()) { static const std::string aFeatureError = "Error: Rotation algorithm failed."; @@ -121,6 +156,108 @@ void FeaturesPlugin_Rotation::execute() removeResults(aResultIndex); } +//================================================================================================= +void FeaturesPlugin_Rotation::performTranslationByThreePoints() +{ + // Getting objects. + ListOfShape anObjects; + std::list aContextes; + AttributeSelectionListPtr anObjectsSelList = + selectionList(FeaturesPlugin_Rotation::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()) { + return; + } + anObjects.push_back(anObject); + aContextes.push_back(anObjectAttr->context()); + } + + // Getting the center point and two points (start and end) + std::shared_ptr aCenterPoint; + std::shared_ptr aStartPoint; + std::shared_ptr anEndPoint; + std::shared_ptr aCenterRef = + selection(FeaturesPlugin_Rotation::CENTER_POINT_ID()); + std::shared_ptr aStartPointRef = + selection(FeaturesPlugin_Rotation::START_POINT_ID()); + std::shared_ptr anEndPointRef = + selection(FeaturesPlugin_Rotation::END_POINT_ID()); + if ((aCenterRef.get() != NULL) && (aStartPointRef.get() != NULL) + && (anEndPointRef.get() != NULL)) { + GeomShapePtr aCenterShape = aCenterRef->value(); + if (!aCenterShape.get()) + aCenterShape = aCenterRef->context()->shape(); + GeomShapePtr aStartShape = aStartPointRef->value(); + if (!aStartShape.get()) + aStartShape = aStartPointRef->context()->shape(); + GeomShapePtr anEndShape = anEndPointRef->value(); + if (!anEndShape.get()) + anEndShape = anEndPointRef->context()->shape(); + if (aStartShape && anEndShape && aCenterShape) { + aCenterPoint = GeomAlgoAPI_PointBuilder::point(aCenterShape); + aStartPoint = GeomAlgoAPI_PointBuilder::point(aStartShape); + anEndPoint = GeomAlgoAPI_PointBuilder::point(anEndShape); + } + } + + // Rotating 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->setRotation(aCenterPoint, aStartPoint, anEndPoint); + ResultPartPtr anOrigin = std::dynamic_pointer_cast(*aContext); + ResultPartPtr aResultPart = document()->copyPart(anOrigin, data(), aResultIndex); + aResultPart->setTrsf(*aContext, aTrsf); + setResult(aResultPart, aResultIndex); + } else { + GeomAlgoAPI_Rotation aRotationAlgo(aBaseShape, aCenterPoint, aStartPoint, anEndPoint); + + if (!aRotationAlgo.check()) { + setError(aRotationAlgo.getError()); + return; + } + + aRotationAlgo.build(); + + // Checking that the algorithm worked properly. + if(!aRotationAlgo.isDone()) { + static const std::string aFeatureError = "Error: Rotation algorithm failed."; + setError(aFeatureError); + break; + } + if(aRotationAlgo.shape()->isNull()) { + static const std::string aShapeError = "Error : Resulting shape is Null."; + setError(aShapeError); + break; + } + if(!aRotationAlgo.isValid()) { + std::string aFeatureError = "Error: Resulting shape is not valid."; + setError(aFeatureError); + break; + } + + ResultBodyPtr aResultBody = document()->createBody(data(), aResultIndex); + loadNamingDS(aRotationAlgo, aResultBody, aBaseShape); + setResult(aResultBody, aResultIndex); + } + aResultIndex++; + } +} + +//================================================================================================= void FeaturesPlugin_Rotation::loadNamingDS(GeomAlgoAPI_Rotation& theRotaionAlgo, std::shared_ptr theResultBody, std::shared_ptr theBaseShape) diff --git a/src/FeaturesPlugin/FeaturesPlugin_Rotation.h b/src/FeaturesPlugin/FeaturesPlugin_Rotation.h index 1326e7ac5..6eeea6a18 100755 --- a/src/FeaturesPlugin/FeaturesPlugin_Rotation.h +++ b/src/FeaturesPlugin/FeaturesPlugin_Rotation.h @@ -26,6 +26,27 @@ class FeaturesPlugin_Rotation : public ModelAPI_Feature return MY_ROTATION_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 "ByAxisAndAngle". + inline static const std::string& CREATION_METHOD_BY_ANGLE() + { + static const std::string MY_CREATION_METHOD_ID("ByAxisAndAngle"); + return MY_CREATION_METHOD_ID; + } + + /// Attribute name for creation method "ByThreePoints". + inline static const std::string& CREATION_METHOD_BY_THREE_POINTS() + { + static const std::string MY_CREATION_METHOD_ID("ByThreePoints"); + return MY_CREATION_METHOD_ID; + } + /// Attribute name of referenced objects. inline static const std::string& OBJECTS_LIST_ID() { @@ -47,6 +68,27 @@ class FeaturesPlugin_Rotation : public ModelAPI_Feature return MY_ANGLE_ID; } + /// Attribute name of a 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 a center point. + inline static const std::string& START_POINT_ID() + { + static const std::string MY_START_POINT_ID("start_point"); + return MY_START_POINT_ID; + } + + /// Attribute name of a center point. + inline static const std::string& END_POINT_ID() + { + static const std::string MY_END_POINT_ID("end_point"); + return MY_END_POINT_ID; + } + /// \return the kind of a feature. FEATURESPLUGIN_EXPORT virtual const std::string& getKind() { @@ -64,6 +106,12 @@ class FeaturesPlugin_Rotation : public ModelAPI_Feature FeaturesPlugin_Rotation(); private: + ///Perform the rotation using an axis and an angle. + void performTranslationByAxisAndAngle(); + + ///Perform the rotation using a center and two points. + void performTranslationByThreePoints(); + void loadNamingDS(GeomAlgoAPI_Rotation& theRotaionAlgo, std::shared_ptr theResultBody, std::shared_ptr theBaseShape); diff --git a/src/FeaturesPlugin/icons/SVG/rotation_3pt_32x32.svg b/src/FeaturesPlugin/icons/SVG/rotation_3pt_32x32.svg new file mode 100644 index 000000000..d6fb9dede --- /dev/null +++ b/src/FeaturesPlugin/icons/SVG/rotation_3pt_32x32.svg @@ -0,0 +1,411 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/FeaturesPlugin/icons/SVG/rotation_axis_32x32.svg b/src/FeaturesPlugin/icons/SVG/rotation_axis_32x32.svg new file mode 100644 index 000000000..20e8b8bee --- /dev/null +++ b/src/FeaturesPlugin/icons/SVG/rotation_axis_32x32.svg @@ -0,0 +1,349 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/FeaturesPlugin/icons/rotation_3pt_32x32.png b/src/FeaturesPlugin/icons/rotation_3pt_32x32.png new file mode 100644 index 000000000..e2493da05 Binary files /dev/null and b/src/FeaturesPlugin/icons/rotation_3pt_32x32.png differ diff --git a/src/FeaturesPlugin/icons/rotation_axis_32x32.png b/src/FeaturesPlugin/icons/rotation_axis_32x32.png new file mode 100644 index 000000000..cf443b372 Binary files /dev/null and b/src/FeaturesPlugin/icons/rotation_axis_32x32.png differ diff --git a/src/FeaturesPlugin/rotation_widget.xml b/src/FeaturesPlugin/rotation_widget.xml index a5eddcf7f..1d94eea3c 100755 --- a/src/FeaturesPlugin/rotation_widget.xml +++ b/src/FeaturesPlugin/rotation_widget.xml @@ -1,30 +1,73 @@ + - - - - + + + + + - - - - - \ No newline at end of file + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/GeomAPI/GeomAPI_Trsf.cpp b/src/GeomAPI/GeomAPI_Trsf.cpp index 701e0bdff..7246364f1 100644 --- a/src/GeomAPI/GeomAPI_Trsf.cpp +++ b/src/GeomAPI/GeomAPI_Trsf.cpp @@ -59,6 +59,25 @@ void GeomAPI_Trsf::setRotation(const std::shared_ptr theAxis, MY_TRSF->SetRotation(theAxis->impl(), theAngle / 180.0 * M_PI); } +//================================================================================================= +void GeomAPI_Trsf::setRotation(const std::shared_ptr theCenterPoint, + const std::shared_ptr theStartPoint, + const std::shared_ptr theEndPoint) +{ + gp_Pnt aCenterPoint = theCenterPoint->impl(); + gp_Pnt aStartPoint = theStartPoint->impl(); + gp_Pnt aEndPoint = theEndPoint->impl(); + + gp_Vec aVec1(aCenterPoint, aStartPoint); + gp_Vec aVec2(aCenterPoint, aEndPoint); + gp_Dir aDir(aVec1 ^ aVec2); + gp_Ax1 anAxis(aCenterPoint, aDir); + double anAngle = aVec1.Angle(aVec2); + if (fabs(anAngle) < Precision::Angular()) anAngle += 2.*M_PI; // Taken from old GEOM code + + MY_TRSF->SetRotation(anAxis, anAngle); +} + //================================================================================================= void GeomAPI_Trsf::setSymmetry(const std::shared_ptr thePoint) { diff --git a/src/GeomAPI/GeomAPI_Trsf.h b/src/GeomAPI/GeomAPI_Trsf.h index 9f7a7f811..822afde1d 100644 --- a/src/GeomAPI/GeomAPI_Trsf.h +++ b/src/GeomAPI/GeomAPI_Trsf.h @@ -59,6 +59,15 @@ class GeomAPI_Trsf : public GeomAPI_Interface GEOMAPI_EXPORT void setRotation(const std::shared_ptr theAxis, const double theAngle); + /** \brief Sets a rotation transformation using three points. + * \param[in] theCenterPoint rotation center. + * \param[in] theStartPoint start rotation point. + * \param[in] theEndPoint end rotation point. + */ + GEOMAPI_EXPORT void setRotation(const std::shared_ptr theCenterPoint, + const std::shared_ptr theStartPoint, + const std::shared_ptr theEndPoint); + /** \brief Sets a point symmetry transformation. * \param[in] thePoint symmetry point. */ diff --git a/src/GeomAlgoAPI/GeomAlgoAPI_Rotation.cpp b/src/GeomAlgoAPI/GeomAlgoAPI_Rotation.cpp index c5244788b..e3d52db32 100644 --- a/src/GeomAlgoAPI/GeomAlgoAPI_Rotation.cpp +++ b/src/GeomAlgoAPI/GeomAlgoAPI_Rotation.cpp @@ -6,50 +6,175 @@ #include "GeomAlgoAPI_Rotation.h" +#include + #include +#include +#include +#include + +#include + //================================================================================================= GeomAlgoAPI_Rotation::GeomAlgoAPI_Rotation(std::shared_ptr theSourceShape, std::shared_ptr theAxis, double theAngle) { - build(theSourceShape, theAxis, theAngle); + myMethodType = BY_ANGLE; + mySourceShape = theSourceShape; + myAxis = theAxis; + myAngle = theAngle; } + //================================================================================================= -void GeomAlgoAPI_Rotation::build(std::shared_ptr theSourceShape, - std::shared_ptr theAxis, - double theAngle) +GeomAlgoAPI_Rotation::GeomAlgoAPI_Rotation(std::shared_ptr theSourceShape, + std::shared_ptr theCenterPoint, + std::shared_ptr theStartPoint, + std::shared_ptr theEndPoint) { - if(!theSourceShape || !theAxis) { - return; + myMethodType = BY_POINTS; + mySourceShape = theSourceShape; + myCenterPoint = theCenterPoint; + myStartPoint = theStartPoint; + myEndPoint = theEndPoint; +} + +//================================================================================================= +bool GeomAlgoAPI_Rotation::check() +{ + switch (myMethodType) { + case BY_ANGLE: { + if (!myAxis) { + myError = "Rotation builder :: axis is not valid."; + return false; + } + if (!mySourceShape) { + myError = "Rotation builder :: source shape is not valid."; + return false; + } + if (myAngle < -360.) { + myError = "Rotation builder :: angle smaller than -360 degrees."; + return false; + } + if (myAngle > 360.) { + myError = "Rotation builder :: angle greater than 360 degrees."; + return false; + } + return true; + } + case BY_POINTS: { + if (!myCenterPoint) { + myError = "Rotation builder :: start point is not valid."; + return false; + } + if (!myStartPoint) { + myError = "Rotation builder :: start point is not valid."; + return false; + } + if (!myEndPoint) { + myError = "Rotation builder :: start point is not valid."; + return false; + } + if (!mySourceShape) { + myError = "Rotation builder :: source shape is invalid."; + return false; + } + if(myCenterPoint->distance(myStartPoint) < Precision::Confusion()) { + myError = "Rotation builder :: center point and start point coincide."; + return false; + } + if(myCenterPoint->distance(myEndPoint) < Precision::Confusion()) { + myError = "Rotation builder :: center point and end point coincide."; + return false; + } + if(myStartPoint->distance(myEndPoint) < Precision::Confusion()) { + myError = "Rotation builder :: start point and end point coincide."; + return false; + } + std::shared_ptr aCenterPointXYZ = myCenterPoint->xyz(); + std::shared_ptr aStartPointXYZ = myStartPoint->xyz(); + std::shared_ptr aEndPointXYZ = myEndPoint->xyz(); + std::shared_ptr vectCenterPointStartPoint = + aStartPointXYZ->decreased(aCenterPointXYZ); + std::shared_ptr vectCenterPointEndPoint = + aEndPointXYZ->decreased(aCenterPointXYZ); + std::shared_ptr crossProduct = + vectCenterPointStartPoint->cross(vectCenterPointEndPoint); + std::shared_ptr aOriginPnt = + std::shared_ptr(new GeomAPI_Pnt(0.,0.,0.)); + std::shared_ptr aOriginXYZ = aOriginPnt->xyz(); + + if (crossProduct->distance(aOriginXYZ) < Precision::Confusion()) { + myError = "Rotation builder :: center point, start point and end point are on a line."; + return false; + } + return true; + } + default: { + myError = "Rotation builder :: method not implemented."; + return false; + } } +} + +//================================================================================================= +void GeomAlgoAPI_Rotation::build() +{ + gp_Trsf* aTrsf = new gp_Trsf(); - const TopoDS_Shape& aSourceShape = theSourceShape->impl(); - const gp_Ax1& anAxis = theAxis->impl(); + switch (myMethodType) { + case BY_ANGLE: { + const gp_Ax1& anAxis = myAxis->impl(); + aTrsf->SetRotation(anAxis, myAngle/180.0*M_PI); + break; + } + case BY_POINTS: { + const gp_Pnt& aCenterPoint = myCenterPoint->impl(); + const gp_Pnt& aStartPoint = myStartPoint->impl(); + const gp_Pnt& aEndPoint = myEndPoint->impl(); + gp_Vec aVec1(aCenterPoint, aStartPoint); + gp_Vec aVec2(aCenterPoint, aEndPoint); + gp_Dir aDir(aVec1^aVec2); + gp_Ax1 anAxis(aCenterPoint, aDir); + double anAngle = aVec1.Angle(aVec2); + if (fabs(anAngle) < Precision::Angular()) anAngle += 2.*M_PI; + aTrsf->SetRotation(anAxis, anAngle); + break; + } + default: { + myError = "Rotation builder :: method not supported"; + return; + } + } + + const TopoDS_Shape& aSourceShape = mySourceShape->impl(); if(aSourceShape.IsNull()) { + myError = "Rotation builder :: source shape does not contain any actual shape."; return; } - gp_Trsf* aTrsf = new gp_Trsf(); - aTrsf->SetRotation(anAxis, theAngle / 180.0 * M_PI); - - // Transform the shape with copying it. + // Transform the shape while copying it. BRepBuilderAPI_Transform* aBuilder = new BRepBuilderAPI_Transform(aSourceShape, *aTrsf, true); if(!aBuilder) { + myError = "Rotation builder :: transform initialization failed."; return; } - this->setImpl(aBuilder); - this->setBuilderType(OCCT_BRepBuilderAPI_MakeShape); - if(aBuilder->IsDone() != Standard_True) { + setImpl(aBuilder); + setBuilderType(OCCT_BRepBuilderAPI_MakeShape); + + if(!aBuilder->IsDone()) { + myError = "Rotation builder :: algorithm failed."; return; } + TopoDS_Shape aResult = aBuilder->Shape(); std::shared_ptr aShape(new GeomAPI_Shape()); aShape->setImpl(new TopoDS_Shape(aResult)); - this->setShape(aShape); - this->setDone(true); + setShape(aShape); + setDone(true); } diff --git a/src/GeomAlgoAPI/GeomAlgoAPI_Rotation.h b/src/GeomAlgoAPI/GeomAlgoAPI_Rotation.h index 48f922b04..e5aee67e6 100644 --- a/src/GeomAlgoAPI/GeomAlgoAPI_Rotation.h +++ b/src/GeomAlgoAPI/GeomAlgoAPI_Rotation.h @@ -3,6 +3,8 @@ // File: GeomAlgoAPI_Rotation.h // Created: 12 May 2015 // Author: Dmitry Bobylev +// +// Modified by Clarisse Genrault (CEA) : 03 Mar 2017 #ifndef GeomAlgoAPI_Rotation_H_ #define GeomAlgoAPI_Rotation_H_ @@ -19,7 +21,14 @@ class GeomAlgoAPI_Rotation : public GeomAlgoAPI_MakeShape { public: - /// \brief Creates an object which is obtained from current object by rotating it around the axis. + /// Type of rotation operation + enum MethodType { + BY_ANGLE, ///< Rotation by axis and an angle + BY_POINTS ///< Rotation by a center and two points + }; + + /// \brief Creates an object which is obtained from current object by rotating it around the axis + /// with the angle. /// \param[in] theSourceShape a shape to be rotated. /// \param[in] theAxis rotation axis. /// \param[in] theAngle rotation angle(in degree). @@ -27,11 +36,31 @@ public: std::shared_ptr theAxis, double theAngle); + /// \brief Creates an object which is obtained from current object by rotating it around the axis + /// withe angle using the center and two points. + /// \param[in] theSourceShape a shape to be rotated. + /// \param[in] theCenterPoint center point. + /// \param[in] theStartPoint start point. + /// \param[in] theEndPoint end point. + GEOMALGOAPI_EXPORT GeomAlgoAPI_Rotation(std::shared_ptr theSourceShape, + std::shared_ptr theCenterPoint, + std::shared_ptr theStartPoint, + std::shared_ptr theEndPoint); + + /// Checks if data for the translation execution is OK. + GEOMALGOAPI_EXPORT bool check(); + + /// Execute the translation. + GEOMALGOAPI_EXPORT void build(); + private: - /// Builds resulting shape. - void build(std::shared_ptr theSourceShape, - std::shared_ptr theAxis, - double theAngle); + MethodType myMethodType; /// Type of method used. + std::shared_ptr mySourceShape; /// Shape to be rotated. + std::shared_ptr myAxis; /// Rotation axis. + double myAngle; /// Rotation angle. + std::shared_ptr myCenterPoint; /// Rotation center point. + std::shared_ptr myStartPoint; /// Rotation start point. + std::shared_ptr myEndPoint; /// Rotation end point. }; #endif diff --git a/src/GeomAlgoAPI/GeomAlgoAPI_ShapeAPI.cpp b/src/GeomAlgoAPI/GeomAlgoAPI_ShapeAPI.cpp index b0dabccc9..9c8e9aa6d 100644 --- a/src/GeomAlgoAPI/GeomAlgoAPI_ShapeAPI.cpp +++ b/src/GeomAlgoAPI/GeomAlgoAPI_ShapeAPI.cpp @@ -11,6 +11,7 @@ #include #include #include +#include #include #include #include @@ -261,6 +262,51 @@ namespace GeomAlgoAPI_ShapeAPI return aTranslationAlgo.shape(); } + std::shared_ptr GeomAlgoAPI_ShapeAPI::makeRotation( + std::shared_ptr theSourceShape, + std::shared_ptr theAxis, + const double theAngle) throw (GeomAlgoAPI_Exception) + { + GeomAlgoAPI_Rotation aRotationAlgo(theSourceShape, theAxis, theAngle); + + if (!aRotationAlgo.check()) { + throw GeomAlgoAPI_Exception(aRotationAlgo.getError()); + } + + aRotationAlgo.build(); + + if(!aRotationAlgo.isDone()) { + throw GeomAlgoAPI_Exception(aRotationAlgo.getError()); + } + if (!aRotationAlgo.checkValid("Rotation builder with two points")) { + throw GeomAlgoAPI_Exception(aRotationAlgo.getError()); + } + return aRotationAlgo.shape(); + } + + std::shared_ptr GeomAlgoAPI_ShapeAPI::makeRotation( + std::shared_ptr theSourceShape, + std::shared_ptr theCenterPoint, + std::shared_ptr theStartPoint, + std::shared_ptr theEndPoint) throw (GeomAlgoAPI_Exception) + { + GeomAlgoAPI_Rotation aRotationAlgo(theSourceShape, theCenterPoint, theStartPoint, theEndPoint); + + if (!aRotationAlgo.check()) { + throw GeomAlgoAPI_Exception(aRotationAlgo.getError()); + } + + aRotationAlgo.build(); + + if(!aRotationAlgo.isDone()) { + throw GeomAlgoAPI_Exception(aRotationAlgo.getError()); + } + if (!aRotationAlgo.checkValid("Rotation builder with two points")) { + throw GeomAlgoAPI_Exception(aRotationAlgo.getError()); + } + return aRotationAlgo.shape(); + } + //=============================================================================================== std::shared_ptr GeomAlgoAPI_ShapeAPI::makeSymmetry( std::shared_ptr theSourceShape, diff --git a/src/GeomAlgoAPI/GeomAlgoAPI_ShapeAPI.h b/src/GeomAlgoAPI/GeomAlgoAPI_ShapeAPI.h index 81dbfd705..3f137c4fe 100644 --- a/src/GeomAlgoAPI/GeomAlgoAPI_ShapeAPI.h +++ b/src/GeomAlgoAPI/GeomAlgoAPI_ShapeAPI.h @@ -103,6 +103,28 @@ public: std::shared_ptr theStartPoint, std::shared_ptr theEndPoint) throw (GeomAlgoAPI_Exception); + /// Performs a rotation from an axis and an angle. + /// \param theSourceShape Shape to be rotated + /// \param theAxis Movement axis + /// \param theAngle Movement angle + /// \return a shape + static std::shared_ptr makeRotation( + std::shared_ptr theSourceShape, + std::shared_ptr theAxis, + const double theAngle) throw (GeomAlgoAPI_Exception); + + /// Performs a rotation from three points. + /// \param theSourceShape Shape to be rotated + /// \param theCenterPoint Movement center point + /// \param theStartPoint Movement start point + /// \param theEndPoint Movement end point + /// \return a shape + static std::shared_ptr makeRotation( + std::shared_ptr theSourceShape, + std::shared_ptr theCenterPoint, + std::shared_ptr theStartPoint, + std::shared_ptr theEndPoint) throw (GeomAlgoAPI_Exception); + /// Performs a symmetry by a point. /// \param theSourceShape Shape be symmetrized /// \param thePoint Point of symmetry