From: Clarisse Genrault Date: Tue, 19 Apr 2016 08:46:36 +0000 (+0200) Subject: => Adding Box primitive X-Git-Url: http://git.salome-platform.org/gitweb/?a=commitdiff_plain;h=1abc133f615fb5fd016aaf689dfec9b26b9f3150;p=modules%2Fshaper.git => Adding Box primitive => Implementing the "geompy" API direct => Adding in the API direct : * error handling * preparation for naming --- diff --git a/CMakeLists.txt b/CMakeLists.txt index 4f430b1c6..b8a7af679 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -80,6 +80,7 @@ ADD_SUBDIRECTORY (src/PartSetPlugin) ADD_SUBDIRECTORY (src/ConstructionPlugin) ADD_SUBDIRECTORY (src/BuildPlugin) ADD_SUBDIRECTORY (src/FeaturesPlugin) +ADD_SUBDIRECTORY (src/PrimitivesPlugin) ADD_SUBDIRECTORY (src/SamplePanelPlugin) ADD_SUBDIRECTORY (src/SketcherPrs) ADD_SUBDIRECTORY (src/SketchPlugin) diff --git a/src/Config/plugins.xml.in b/src/Config/plugins.xml.in index a1d2354cb..54df1efa3 100644 --- a/src/Config/plugins.xml.in +++ b/src/Config/plugins.xml.in @@ -8,6 +8,7 @@ + diff --git a/src/GeomAlgoAPI/CMakeLists.txt b/src/GeomAlgoAPI/CMakeLists.txt index 84105385f..d4b6972dc 100644 --- a/src/GeomAlgoAPI/CMakeLists.txt +++ b/src/GeomAlgoAPI/CMakeLists.txt @@ -37,6 +37,10 @@ SET(PROJECT_HEADERS GeomAlgoAPI_Intersection.h GeomAlgoAPI_Pipe.h GeomAlgoAPI_WireBuilder.h + GeomAlgoAPI_Box.h + GeomAlgoAPI_BoxPoints.h + GeomAlgoAPI_DirectAPI.h + GeomAlgoAPI_Exception.h ) SET(PROJECT_SOURCES @@ -70,6 +74,10 @@ SET(PROJECT_SOURCES GeomAlgoAPI_Intersection.cpp GeomAlgoAPI_Pipe.cpp GeomAlgoAPI_WireBuilder.cpp + GeomAlgoAPI_Box.cpp + GeomAlgoAPI_BoxPoints.cpp + GeomAlgoAPI_DirectAPI.cpp + GeomAlgoAPI_Exception.cpp ) SET(PROJECT_LIBRARIES diff --git a/src/GeomAlgoAPI/GeomAlgoAPI.i b/src/GeomAlgoAPI/GeomAlgoAPI.i index 8c9279226..2e4860d14 100644 --- a/src/GeomAlgoAPI/GeomAlgoAPI.i +++ b/src/GeomAlgoAPI/GeomAlgoAPI.i @@ -43,6 +43,10 @@ %include "GeomAlgoAPI_Intersection.h" %include "GeomAlgoAPI_Pipe.h" %include "GeomAlgoAPI_WireBuilder.h" +%include "GeomAlgoAPI_Box.h" +%include "GeomAlgoAPI_BoxPoints.h" +%include "GeomAlgoAPI_DirectAPI.h" +%include "GeomAlgoAPI_Exception.h" %typemap(out) std::list< std::shared_ptr< GeomAPI_Shape > >::value_type & { $result = SWIG_NewPointerObj(SWIG_as_voidptr(new std::shared_ptr(*$1)), $descriptor(std::shared_ptr *), SWIG_POINTER_OWN | 0 ); diff --git a/src/GeomAlgoAPI/GeomAlgoAPI_Box.cpp b/src/GeomAlgoAPI/GeomAlgoAPI_Box.cpp new file mode 100644 index 000000000..e129146cb --- /dev/null +++ b/src/GeomAlgoAPI/GeomAlgoAPI_Box.cpp @@ -0,0 +1,98 @@ +// Copyright (C) 2014-2016 CEA/DEN, EDF R&D + +// File: GeomAlgoAPI_Box.cpp +// Created: 10 Mar 2016 +// Author: Clarisse Genrault (CEA) + +#include + +#include +#include + +//================================================================================================= +GeomAlgoAPI_Box::GeomAlgoAPI_Box() +{ +} + +//================================================================================================= +GeomAlgoAPI_Box::GeomAlgoAPI_Box(const double theDx, const double theDy, const double theDz) +{ + myDx = theDx; + myDy = theDy; + myDz = theDz; +} + +//================================================================================================= +bool GeomAlgoAPI_Box::check() +{ + if (myDx < Precision::Confusion()) { + myError = "Box builder with dimensions :: Dx is null."; + return false; + } else if (myDy < Precision::Confusion()) { + myError = "Box builder with dimensions :: Dy is null."; + return false; + } else if (myDz < Precision::Confusion()) { + myError = "Box builder with dimensions :: Dz is null."; + return false; + } + return true; +} + +//================================================================================================= +void GeomAlgoAPI_Box::build() +{ + myCreatedFaces.clear(); + + // Construct the box + BRepPrimAPI_MakeBox *aBoxMaker = new BRepPrimAPI_MakeBox(myDx, myDy, myDz); + aBoxMaker->Build(); + + // Test the algorithm + if (!aBoxMaker->IsDone()) { + myError = "Box builder with dimensions :: algorithm failed."; + return; + } + + TopoDS_Shape aResult = aBoxMaker->Shape(); + std::shared_ptr aShape(new GeomAPI_Shape()); + aShape->setImpl(new TopoDS_Shape(aResult)); + setShape(aShape); + + // Test on the shapes + if (!aShape.get() || aShape->isNull()) { + myError = "Box builder with dimensions :: resulting shape is null."; + return; + } + if (!isValid()) { + myError = "Box builder with dimensions :: resulting shape is not valid."; + return; + } + + setImpl(aBoxMaker); + + setDone(true); +} + +//================================================================================================= +void GeomAlgoAPI_Box::prepareNamingFaces() +{ + BRepPrimAPI_MakeBox aBoxMaker = impl(); + std::shared_ptr aShapeFront(new GeomAPI_Shape); + aShapeFront->setImpl(new TopoDS_Shape(aBoxMaker.FrontFace())); + myCreatedFaces["Front"] = aShapeFront; + std::shared_ptr aShapeBack(new GeomAPI_Shape); + aShapeBack->setImpl(new TopoDS_Shape(aBoxMaker.BackFace())); + myCreatedFaces["Back"] = aShapeBack; + std::shared_ptr aShapeTop(new GeomAPI_Shape); + aShapeTop->setImpl(new TopoDS_Shape(aBoxMaker.TopFace())); + myCreatedFaces["Top"] = aShapeTop; + std::shared_ptr aShapeBottom(new GeomAPI_Shape); + aShapeBottom->setImpl(new TopoDS_Shape(aBoxMaker.BottomFace())); + myCreatedFaces["Bottom"] = aShapeBottom; + std::shared_ptr aShapeLeft(new GeomAPI_Shape); + aShapeLeft->setImpl(new TopoDS_Shape(aBoxMaker.LeftFace())); + myCreatedFaces["Left"] = aShapeLeft; + std::shared_ptr aShapeRight(new GeomAPI_Shape); + aShapeRight->setImpl(new TopoDS_Shape(aBoxMaker.RightFace())); + myCreatedFaces["Right"] = aShapeRight; +} diff --git a/src/GeomAlgoAPI/GeomAlgoAPI_Box.h b/src/GeomAlgoAPI/GeomAlgoAPI_Box.h new file mode 100644 index 000000000..23bcb8d35 --- /dev/null +++ b/src/GeomAlgoAPI/GeomAlgoAPI_Box.h @@ -0,0 +1,44 @@ +// Copyright (C) 2014-2016 CEA/DEN, EDF R&D + +// File: GeomAlgoAPI_Box.h +// Created: 17 Mar 2016 +// Author: Clarisse Genrault (CEA) + +#ifndef GeomAlgoAPI_Box_H_ +#define GeomAlgoAPI_Box_H_ + +#include +#include + +/**\class GeomAlgoAPI_Box + * \ingroup DataAlgo + * \brief Allows to create Box Primitives + */ +class GeomAlgoAPI_Box : public GeomAlgoAPI_MakeShape +{ + public: + GEOMALGOAPI_EXPORT GeomAlgoAPI_Box(); + + /// Creates a box using the dimensions. + /// \param theDx The dimension on X + /// \param theDy The dimension on Y + /// \param theDz The dimension on Z + GEOMALGOAPI_EXPORT GeomAlgoAPI_Box(const double theDx, const double theDy, const double theDz); + + /// Checks if each dimension "Dx", Dy" and "Dz" for the box construction is OK. + GEOMALGOAPI_EXPORT bool check(); + + /// Builds the box with the dimensions "Dx", "Dy" and "Dz". + GEOMALGOAPI_EXPORT void build(); + + /// Prepare the naming (redifined because it is specific for a box). + GEOMALGOAPI_EXPORT void prepareNamingFaces(); + + private: + double myDx; /// Dimension on X to create a box. + double myDy; /// Dimension on Y to create a box. + double myDz; /// Dimension Z to create a box. +}; + + +#endif diff --git a/src/GeomAlgoAPI/GeomAlgoAPI_BoxPoints.cpp b/src/GeomAlgoAPI/GeomAlgoAPI_BoxPoints.cpp new file mode 100644 index 000000000..f6b601086 --- /dev/null +++ b/src/GeomAlgoAPI/GeomAlgoAPI_BoxPoints.cpp @@ -0,0 +1,69 @@ +// Copyright (C) 2014-2016 CEA/DEN, EDF R&D + +// File: GeomAlgoAPI_BoxPoints.cpp +// Created: 17 Mar 2016 +// Author: Clarisse Genrault (CEA) + +#include + +#include +#include + +#include + +//================================================================================================= +GeomAlgoAPI_BoxPoints::GeomAlgoAPI_BoxPoints(std::shared_ptr theFirstPoint, + std::shared_ptr theSecondPoint) +:GeomAlgoAPI_Box() +{ + myFirstPoint = theFirstPoint; + mySecondPoint = theSecondPoint; +} + +//================================================================================================= +bool GeomAlgoAPI_BoxPoints::check() +{ + // The distance between myFirstPoint and mySecondPoint must not be null. + if (myFirstPoint->distance(mySecondPoint) < Precision::Confusion()) + return false; + return true; +} + +//================================================================================================= +void GeomAlgoAPI_BoxPoints::build() +{ + myCreatedFaces.clear(); + + const gp_Pnt& aFirstPoint = myFirstPoint->impl(); + const gp_Pnt& aSecondPoint = mySecondPoint->impl(); + + // Construct the box + BRepPrimAPI_MakeBox *aBoxMaker = new BRepPrimAPI_MakeBox(aFirstPoint, aSecondPoint); + aBoxMaker->Build(); + + // Test the algorithm + if(!aBoxMaker->IsDone()) { + myError = "Box builder with two points :: algorithm failed."; + return; + } + + TopoDS_Shape aResult = aBoxMaker->Shape(); + + std::shared_ptr aShape(new GeomAPI_Shape()); + aShape->setImpl(new TopoDS_Shape(aResult)); + setShape(aShape); + + // Tests on the shape + if (!aShape.get() || aShape->isNull()) { + myError = "Box builder with two points :: resulting shape is null."; + return; + } + if (!isValid()) { + myError = "Box builder with two points :: resulting shape is not valid."; + return; + } + + setImpl(aBoxMaker); + + setDone(true); +} diff --git a/src/GeomAlgoAPI/GeomAlgoAPI_BoxPoints.h b/src/GeomAlgoAPI/GeomAlgoAPI_BoxPoints.h new file mode 100644 index 000000000..159715f21 --- /dev/null +++ b/src/GeomAlgoAPI/GeomAlgoAPI_BoxPoints.h @@ -0,0 +1,38 @@ +// Copyright (C) 2014-2016 CEA/DEN, EDF R&D + +// File: GeomAlgoAPI_BoxPoints.h +// Created: 17 Mar 2016 +// Author: Clarisse Genrault (CEA) + +#ifndef GeomAlgoAPI_BoxPoints_H_ +#define GeomAlgoAPI_BoxPoints_H_ + +#include +#include + +/**\class GeomAlgoAPI_BoxPoints + * \ingroup DataAlgo + * \brief Allows to create Box Primitives using the two points that defined a diagonal. + */ +class GeomAlgoAPI_BoxPoints : public GeomAlgoAPI_Box +{ + public: + /// Creates a box using the two points that defined a diagonal. + /// \param theFirstPoint One extermity of the diagonal + /// \param theSecondPoint The other extremity of the diagonal + GEOMALGOAPI_EXPORT GeomAlgoAPI_BoxPoints(std::shared_ptr theFirstPoint, + std::shared_ptr theSecondPoint); + + /// \return true if the data of the construction of the box were correct. + GEOMALGOAPI_EXPORT bool check(); + + /// Builds the box. + GEOMALGOAPI_EXPORT void build(); + + private: + std::shared_ptr myFirstPoint; /// First point to create a box. + std::shared_ptr mySecondPoint; /// Second point to create a box. +}; + + +#endif diff --git a/src/GeomAlgoAPI/GeomAlgoAPI_DirectAPI.cpp b/src/GeomAlgoAPI/GeomAlgoAPI_DirectAPI.cpp new file mode 100644 index 000000000..6e7e75ab4 --- /dev/null +++ b/src/GeomAlgoAPI/GeomAlgoAPI_DirectAPI.cpp @@ -0,0 +1,50 @@ +// Copyright (C) 2014-2016 CEA/DEN, EDF R&D + +// File: GeomAlgoAPI_DirectAPI.cpp +// Created: 17 Mar 2016 +// Author: Clarisse Genrault (CEA) + +#include "GeomAlgoAPI_DirectAPI.h" +#include +#include + +#include + +namespace GeomAlgoAPI_DirectAPI +{ + //========================================================================================================= + std::shared_ptr GeomAlgoAPI_DirectAPI::MakeBox(const double theDx, const double theDy, + const double theDz) throw (GeomAlgoAPI_Exception) + { + GeomAlgoAPI_Box aBoxAlgo(theDx,theDy,theDz); + + if (!aBoxAlgo.check()) { + throw GeomAlgoAPI_Exception(aBoxAlgo.getError()); + } + + aBoxAlgo.build(); + + if(!aBoxAlgo.isDone()) { + throw GeomAlgoAPI_Exception(aBoxAlgo.getError()); + } + return aBoxAlgo.shape(); + } + + //========================================================================================================= + std::shared_ptr GeomAlgoAPI_DirectAPI::MakeBox(std::shared_ptr theFirstPoint, + std::shared_ptr theSecondPoint) throw (GeomAlgoAPI_Exception) + { + GeomAlgoAPI_BoxPoints aBoxAlgo(theFirstPoint, theSecondPoint); + + if (!aBoxAlgo.check()) { + throw GeomAlgoAPI_Exception(aBoxAlgo.getError()); + } + + aBoxAlgo.build(); + + if(!aBoxAlgo.isDone()) { + throw GeomAlgoAPI_Exception(aBoxAlgo.getError()); + } + return aBoxAlgo.shape(); + } +} \ No newline at end of file diff --git a/src/GeomAlgoAPI/GeomAlgoAPI_DirectAPI.h b/src/GeomAlgoAPI/GeomAlgoAPI_DirectAPI.h new file mode 100644 index 000000000..cfdf62ef0 --- /dev/null +++ b/src/GeomAlgoAPI/GeomAlgoAPI_DirectAPI.h @@ -0,0 +1,39 @@ +// Copyright (C) 2014-2016 CEA/DEN, EDF R&D + +// File: GeomAlgoAPI_DirectAPI.h +// Created: 17 Mar 2016 +// Author: Clarisse Genrault (CEA) + +#ifndef GEOMALGOAPI_DIRECTAPI_H +#define GEOMALGOAPI_DIRECTAPI_H + +#include +#include + +#include + +namespace GeomAlgoAPI_DirectAPI +{ +/**\class GeomAlgoAPI_DirectAPI + * \ingroup DataAlgo + * \brief Allows to access the direct API + */ +class GeomAlgoAPI_DirectAPI +{ +public: + /// Creates a box using the dimensions. + /// \param theDx The dimension on X + /// \param theDy The dimension on Y + /// \param theDz The dimension on Z + /// \return a shape + static std::shared_ptr MakeBox(const double theDx, const double theDy, const double theDz) throw (GeomAlgoAPI_Exception); + + /// Creates a box using the two points that defined a diagonal. + /// \param theFirstPoint One extermity of the diagonal + /// \param theSecondPoint The other extremity of the diagonal + /// \return a shape + static std::shared_ptr MakeBox(std::shared_ptr theFirstPoint, + std::shared_ptr theSecondPoint)throw (GeomAlgoAPI_Exception); +}; +} +#endif \ No newline at end of file diff --git a/src/GeomAlgoAPI/GeomAlgoAPI_Exception.cpp b/src/GeomAlgoAPI/GeomAlgoAPI_Exception.cpp new file mode 100644 index 000000000..53338dae7 --- /dev/null +++ b/src/GeomAlgoAPI/GeomAlgoAPI_Exception.cpp @@ -0,0 +1,24 @@ +// Copyright (C) 2014-2016 CEA/DEN, EDF R&D + +// File: GeomAlgoAPI_Exception.cpp +// Created: 14 April 2016 +// Author: Clarisse Genrault (CEA) + +#include + +//================================================================================================= +GeomAlgoAPI_Exception::GeomAlgoAPI_Exception(std::string theMessageError) +: myMessageError(theMessageError) +{ +} + +//================================================================================================= +GeomAlgoAPI_Exception::~GeomAlgoAPI_Exception() throw() +{ +} + +//================================================================================================= +const char* GeomAlgoAPI_Exception::what() const throw() +{ + return myMessageError.c_str(); +} \ No newline at end of file diff --git a/src/GeomAlgoAPI/GeomAlgoAPI_Exception.h b/src/GeomAlgoAPI/GeomAlgoAPI_Exception.h new file mode 100644 index 000000000..8bdeaa3f3 --- /dev/null +++ b/src/GeomAlgoAPI/GeomAlgoAPI_Exception.h @@ -0,0 +1,28 @@ +#ifndef GeomAlgoAPI_Exception_H_ +#define GeomAlgoAPI_Exception_H_ + +#include + +#include + +/**\class GeomAlgoAPI_Exception + * \ingroup DataAlgo + * \brief Manage exceptions + */ +class GeomAlgoAPI_Exception : public std::exception +{ + public: + /// Create an exception + /// \param theMessageError Error message to be displayed + GEOMALGOAPI_EXPORT GeomAlgoAPI_Exception(std::string theMessageError); + /// Destroyer + GEOMALGOAPI_EXPORT ~GeomAlgoAPI_Exception() throw(); + /// Allows to collet the error + GEOMALGOAPI_EXPORT const char* what() const throw(); + +private: + std::string myMessageError; /// Error message to be displayed. +}; + + +#endif \ No newline at end of file diff --git a/src/GeomAlgoAPI/GeomAlgoAPI_MakeShape.cpp b/src/GeomAlgoAPI/GeomAlgoAPI_MakeShape.cpp index e7d5165ce..1172e0e06 100644 --- a/src/GeomAlgoAPI/GeomAlgoAPI_MakeShape.cpp +++ b/src/GeomAlgoAPI/GeomAlgoAPI_MakeShape.cpp @@ -3,6 +3,8 @@ // File: GeomAlgoAPI_MakeShape.cpp // Created: 20 Oct 2014 // Author: Sergey ZARITCHNY +// +// Modified by Clarisse Genrault (CEA) : 17 Mar 2016 #include "GeomAlgoAPI_MakeShape.h" @@ -15,6 +17,7 @@ #include #include #include +#include //================================================================================================= GeomAlgoAPI_MakeShape::GeomAlgoAPI_MakeShape() @@ -193,3 +196,14 @@ void GeomAlgoAPI_MakeShape::initialize() { myMap->bind(aCurrentShape, aCurrentShape); } } + +//================================================================================================= +void GeomAlgoAPI_MakeShape::prepareNamingFaces() +{ + int index = 1; + GeomAPI_ShapeExplorer anExp(shape(), GeomAPI_Shape::FACE); + for(GeomAPI_ShapeExplorer anExp(shape(), GeomAPI_Shape::FACE); anExp.more(); anExp.next()) { + std::shared_ptr aFace = anExp.current(); + myCreatedFaces["Face_" + std::to_string(index++)] = aFace; + } +} diff --git a/src/GeomAlgoAPI/GeomAlgoAPI_MakeShape.h b/src/GeomAlgoAPI/GeomAlgoAPI_MakeShape.h index 0131da446..faed955fc 100644 --- a/src/GeomAlgoAPI/GeomAlgoAPI_MakeShape.h +++ b/src/GeomAlgoAPI/GeomAlgoAPI_MakeShape.h @@ -3,6 +3,8 @@ // File: GeomAlgoAPI_MakeShape.h // Created: 17 Oct 2014 // Author: Sergey ZARITCHNY +// +// Modified by Clarisse Genrault (CEA) : 17 Mar 2016 #ifndef GeomAlgoAPI_MakeShape_H_ #define GeomAlgoAPI_MakeShape_H_ @@ -11,6 +13,7 @@ #include #include +#include /// \class GeomAlgoAPI_MakeShape /// \ingroup DataAlgo @@ -80,6 +83,18 @@ public: /// \param[in] theShape base shape. GEOMALGOAPI_EXPORT virtual bool isDeleted(const std::shared_ptr theShape); + /// \return true if the data were correct. + GEOMALGOAPI_EXPORT virtual bool check() { return true; }; + + /// \return the list of created faces. + GEOMALGOAPI_EXPORT std::map< std::string, std::shared_ptr > getCreatedFaces() {return myCreatedFaces;} + + /// \return the error. + GEOMALGOAPI_EXPORT std::string getError() { return myError; } + + /// \brief Prepare the naming of faces. + GEOMALGOAPI_EXPORT virtual void prepareNamingFaces(); + protected: /// \brief Sets builder type. /// \param[in] theBuilderType new builder type. @@ -93,6 +108,9 @@ protected: /// \param[in] theShape new shape. void setShape(const std::shared_ptr theShape); + std::string myError; /// Error occurred during the execution of an algorithm. + std::map< std::string, std::shared_ptr > myCreatedFaces; /// Map of created faces with their name for naming. + protected: std::shared_ptr myMap; ///< Data map to keep correct orientation of sub-shapes. diff --git a/src/GeomAlgoAPI/GeomAlgoAPI_swig.h b/src/GeomAlgoAPI/GeomAlgoAPI_swig.h index 92327a03d..217ef14cd 100644 --- a/src/GeomAlgoAPI/GeomAlgoAPI_swig.h +++ b/src/GeomAlgoAPI/GeomAlgoAPI_swig.h @@ -37,6 +37,10 @@ #include "GeomAlgoAPI_Intersection.h" #include "GeomAlgoAPI_Pipe.h" #include "GeomAlgoAPI_WireBuilder.h" + #include "GeomAlgoAPI_Box.h" + #include "GeomAlgoAPI_BoxPoints.h" + #include "GeomAlgoAPI_DirectAPI.h" + #include "GeomAlgoAPI_Exception.h" #include #include diff --git a/src/PartSet/PartSet_icons.qrc b/src/PartSet/PartSet_icons.qrc index 270a9428f..0dc7ccf6f 100644 --- a/src/PartSet/PartSet_icons.qrc +++ b/src/PartSet/PartSet_icons.qrc @@ -2,6 +2,9 @@ icons/activate.png icons/angle_32x32.png + icons/box.png + icons/box_2pt_32x32.png + icons/box_dxyz_32x32.png icons/color.png icons/deactivate.png icons/edit.png diff --git a/src/PartSet/icons/box.png b/src/PartSet/icons/box.png new file mode 100644 index 000000000..104a1edde Binary files /dev/null and b/src/PartSet/icons/box.png differ diff --git a/src/PartSet/icons/box_2pt_32x32.png b/src/PartSet/icons/box_2pt_32x32.png new file mode 100644 index 000000000..874d20c5d Binary files /dev/null and b/src/PartSet/icons/box_2pt_32x32.png differ diff --git a/src/PartSet/icons/box_dxyz_32x32.png b/src/PartSet/icons/box_dxyz_32x32.png new file mode 100644 index 000000000..26ce8aa6d Binary files /dev/null and b/src/PartSet/icons/box_dxyz_32x32.png differ diff --git a/src/PrimitivesPlugin/CMakeLists.txt b/src/PrimitivesPlugin/CMakeLists.txt new file mode 100644 index 000000000..2203b6201 --- /dev/null +++ b/src/PrimitivesPlugin/CMakeLists.txt @@ -0,0 +1,39 @@ +SET(PROJECT_HEADERS + PrimitivesPlugin.h + PrimitivesPlugin_Plugin.h + PrimitivesPlugin_Box.h +) + +SET(PROJECT_SOURCES + PrimitivesPlugin_Plugin.cpp + PrimitivesPlugin_Box.cpp +) + +SET(XML_RESOURCES + plugin-Primitives.xml + box_widget.xml +) + +INCLUDE_DIRECTORIES( + ../ModelAPI + ../GeomAPI + ../GeomAlgoAPI + ../Events +) + +SET(PROJECT_LIBRARIES + Events + ModelAPI + GeomAPI + GeomAlgoAPI +) + +ADD_DEFINITIONS(-DPRIMITIVESPLUGIN_EXPORTS) +ADD_LIBRARY(PrimitivesPlugin MODULE ${PROJECT_SOURCES} ${PROJECT_HEADERS} ${XML_RESOURCES}) +TARGET_LINK_LIBRARIES(PrimitivesPlugin ${PROJECT_LIBRARIES}) + +INSTALL(TARGETS PrimitivesPlugin DESTINATION ${SHAPER_INSTALL_PLUGIN_FILES}) +INSTALL(FILES ${XML_RESOURCES} DESTINATION ${SHAPER_INSTALL_XML_RESOURCES}) + +ADD_UNIT_TESTS(UnitTestBox.py + UseTestBox.py) \ No newline at end of file diff --git a/src/PrimitivesPlugin/PrimitivesPlugin.h b/src/PrimitivesPlugin/PrimitivesPlugin.h new file mode 100644 index 000000000..a2996d38d --- /dev/null +++ b/src/PrimitivesPlugin/PrimitivesPlugin.h @@ -0,0 +1,20 @@ +// Copyright (C) 2014-20xx CEA/DEN, EDF R&D --> + +#ifndef PRIMITIVESPLUGIN_H +#define PRIMITIVESPLUGIN_H + +#if defined PRIMITIVESPLUGIN_EXPORTS +#if defined WIN32 +#define PRIMITIVESPLUGIN_EXPORT __declspec( dllexport ) +#else +#define PRIMITIVESPLUGIN_EXPORT +#endif +#else +#if defined WIN32 +#define PRIMITIVESPLUGIN_EXPORT __declspec( dllimport ) +#else +#define PRIMITIVESPLUGIN_EXPORT +#endif +#endif + +#endif diff --git a/src/PrimitivesPlugin/PrimitivesPlugin_Box.cpp b/src/PrimitivesPlugin/PrimitivesPlugin_Box.cpp new file mode 100644 index 000000000..efa28d995 --- /dev/null +++ b/src/PrimitivesPlugin/PrimitivesPlugin_Box.cpp @@ -0,0 +1,146 @@ +// Copyright (C) 2014-2016 CEA/DEN, EDF R&D + +// File: PrimitivesPlugin_Box.cpp +// Created: 10 Mar 2016 +// Author: Clarisse Genrault (CEA) + +#include + +#include +#include +#include +#include +#include + +#include + +#include + +namespace ParametricAPI +{ +//================================================================================================= +PrimitivesPlugin_Box::PrimitivesPlugin_Box() // Nothing to do during instantiation +{ +} + +//================================================================================================= +void PrimitivesPlugin_Box::initAttributes() +{ + data()->addAttribute(PrimitivesPlugin_Box::METHOD(), ModelAPI_AttributeString::typeId()); + + data()->addAttribute(PrimitivesPlugin_Box::DX(), ModelAPI_AttributeDouble::typeId()); + data()->addAttribute(PrimitivesPlugin_Box::DY(), ModelAPI_AttributeDouble::typeId()); + data()->addAttribute(PrimitivesPlugin_Box::DZ(), ModelAPI_AttributeDouble::typeId()); + + data()->addAttribute(PrimitivesPlugin_Box::POINT_FIRST(), ModelAPI_AttributeSelection::typeId()); + data()->addAttribute(PrimitivesPlugin_Box::POINT_SECOND(), ModelAPI_AttributeSelection::typeId()); +} + +//================================================================================================= +void PrimitivesPlugin_Box::execute() +{ + AttributeStringPtr aMethodTypeAttr = string(PrimitivesPlugin_Box::METHOD()); + std::string aMethodType = aMethodTypeAttr->value(); + + if (aMethodType == "BoxByDimensions") + createBoxByDimensions(); + + if (aMethodType == "BoxByTwoPoints") + createBoxByTwoPoints(); +} + +//================================================================================================= +void PrimitivesPlugin_Box::createBoxByDimensions() +{ + double aDx = real(PrimitivesPlugin_Box::DX())->value(); + double aDy = real(PrimitivesPlugin_Box::DY())->value(); + double aDz = real(PrimitivesPlugin_Box::DZ())->value(); + + std::shared_ptr aBoxAlgo(new GeomAlgoAPI_Box(aDx,aDy,aDz)); + + // These checks should be made to the GUI for the feature but the corresponding validator does not exist yet. + if (!aBoxAlgo->check()) { + // The error is not displayed in a popup window. It must be in the status bar. + setError(aBoxAlgo->getError(), false); + return; + } + + // Build the box + aBoxAlgo->build(); + + // Check if the creation of the box + if(!aBoxAlgo->isDone()) { + setError(aBoxAlgo->getError()); + return; + } + + int aResultIndex = 0; + ResultBodyPtr aResultBox = document()->createBody(data(), aResultIndex); + loadNamingDS(aBoxAlgo, aResultBox); + setResult(aResultBox, aResultIndex); +} + +//================================================================================================= +void PrimitivesPlugin_Box::createBoxByTwoPoints() +{ + AttributeSelectionPtr aRef1 = data()->selection(PrimitivesPlugin_Box::POINT_FIRST()); + AttributeSelectionPtr aRef2 = data()->selection(PrimitivesPlugin_Box::POINT_SECOND()); + + std::shared_ptr aBoxAlgo; + + if ((aRef1.get() != NULL) && (aRef2.get() != NULL)) { + GeomShapePtr aShape1 = aRef1->value(); + if (!aShape1.get()) //If we can't get the points directly, try getting them from the context + aShape1 = aRef1->context()->shape(); + GeomShapePtr aShape2 = aRef2->value(); + if (!aShape2.get()) + aShape2 = aRef2->context()->shape(); + if (aShape1 && aShape2){ + std::shared_ptr aFirstPoint = GeomAlgoAPI_PointBuilder::point(aShape1); + std::shared_ptr aSecondPoint = GeomAlgoAPI_PointBuilder::point(aShape2); + aBoxAlgo = std::shared_ptr(new GeomAlgoAPI_BoxPoints(aFirstPoint,aSecondPoint)); + } + } + + // These checks should be made to the GUI for the feature but the corresponding validator does not exist yet. + if (!aBoxAlgo->check()) { + // The error is not displayed in a popup window. It must be in the status bar. + setError(aBoxAlgo->getError(),false); + return; + } + + // Build the box + aBoxAlgo->build(); + + // Check if the creation of the box + if(!aBoxAlgo->isDone()) { + setError(aBoxAlgo->getError()); + return; + } + + int aResultIndex = 0; + ResultBodyPtr aResultBox = document()->createBody(data(), aResultIndex); + loadNamingDS(aBoxAlgo, aResultBox); + setResult(aResultBox, aResultIndex); +} + +//================================================================================================= +void PrimitivesPlugin_Box::loadNamingDS(std::shared_ptr theBoxAlgo, + std::shared_ptr theResultBox) +{ + // Load the result + theResultBox->store(theBoxAlgo->shape()); + + // Prepare the naming + theBoxAlgo->prepareNamingFaces(); + + // Insert to faces + int num = 1; + std::map< std::string, std::shared_ptr > listOfFaces = theBoxAlgo->getCreatedFaces(); + for (std::map< std::string, std::shared_ptr >::iterator it=listOfFaces.begin(); it!=listOfFaces.end(); ++it) { + std::shared_ptr aFace = (*it).second; + theResultBox->generated(aFace, (*it).first, num++); + } +} + +} //namespace ParametricAPI diff --git a/src/PrimitivesPlugin/PrimitivesPlugin_Box.h b/src/PrimitivesPlugin/PrimitivesPlugin_Box.h new file mode 100644 index 000000000..86df5e048 --- /dev/null +++ b/src/PrimitivesPlugin/PrimitivesPlugin_Box.h @@ -0,0 +1,111 @@ +// Copyright (C) 2014-2016 CEA/DEN, EDF R&D + +// File: PrimitivesPlugin_Box.h +// Created: 10 Mar 2016 +// Author: Clarisse Genrault (CEA) + +#ifndef PrimitivesPlugin_Box_H_ +#define PrimitivesPlugin_Box_H_ + +#include +#include +#include +#include + +class GeomAPI_Shape; +class ModelAPI_ResultBody; + +namespace ParametricAPI +{ +/**\class PrimitivesPlugin_Box + * \ingroup Plugins + * \brief Feature for creation of a box primitive using various methods. + * + * Box creates a cuboid - Parallelepiped with 6 rectangular faces. It can be built via two + * methods : using two points that define a diagonal, or using 3 lengths that define the + * rectangular dimensions. + */ +class PrimitivesPlugin_Box : public ModelAPI_Feature +{ + public: + /// Box kind + inline static const std::string& ID() + { + static const std::string MY_BOX_ID("Box"); + return MY_BOX_ID; + } + + /// attribute name for creation method + inline static const std::string& METHOD() + { + static const std::string METHOD_ATTR("CreationMethod"); + return METHOD_ATTR; + } + + /// attribute name of first point + inline static const std::string& POINT_FIRST() + { + static const std::string MY_POINT_FIRST("FirstPoint"); + return MY_POINT_FIRST; + } + + /// attribute name of second point + inline static const std::string& POINT_SECOND() + { + static const std::string MY_POINT_SECOND("SecondPoint"); + return MY_POINT_SECOND; + } + + /// attribute first coordinate + inline static const std::string& DX() + { + static const std::string MY_DX("dx"); + return MY_DX; + } + + /// attribute second coordinate + inline static const std::string& DY() + { + static const std::string MY_DY("dy"); + return MY_DY; + } + + /// attribute third coordinate + inline static const std::string& DZ() + { + static const std::string MY_DZ("dz"); + return MY_DZ; + } + + /// Returns the kind of a feature + PRIMITIVESPLUGIN_EXPORT virtual const std::string& getKind() + { + static std::string MY_KIND = PrimitivesPlugin_Box::ID(); + return MY_KIND; + } + + /// Creates a new part document if needed + PRIMITIVESPLUGIN_EXPORT virtual void execute(); + + /// Request for initialization of data model of the feature: adding all attributes + PRIMITIVESPLUGIN_EXPORT virtual void initAttributes(); + + /// Use plugin manager for features creation + PrimitivesPlugin_Box(); + + private: + /// Load Naming data structure of the feature to the document + void loadNamingDS(std::shared_ptr theBoxAlgo, + std::shared_ptr theResultBox); + + ///Perform the creation of the box using two points defining a diagonal + void createBoxByTwoPoints(); + + ///Perform the creation of the box using three cordinates + void createBoxByDimensions(); + +}; + +} //namespace ParametricAPI + +#endif diff --git a/src/PrimitivesPlugin/PrimitivesPlugin_Plugin.cpp b/src/PrimitivesPlugin/PrimitivesPlugin_Plugin.cpp new file mode 100644 index 000000000..efa59bdc7 --- /dev/null +++ b/src/PrimitivesPlugin/PrimitivesPlugin_Plugin.cpp @@ -0,0 +1,34 @@ +// Copyright (C) 2014-20xx CEA/DEN, EDF R&D --> + +#include + +#include + +#include + +#include + +#include + +#include + +using namespace std; +using namespace ParametricAPI; + +// the only created instance of this plugin +static PrimitivesPlugin_Plugin* MY_PRIMITIVES_INSTANCE = new PrimitivesPlugin_Plugin(); + +PrimitivesPlugin_Plugin::PrimitivesPlugin_Plugin() +{ + // register this plugin + ModelAPI_Session::get()->registerPlugin(this); +} + +FeaturePtr PrimitivesPlugin_Plugin::createFeature(string theFeatureID) +{ + if (theFeatureID == PrimitivesPlugin_Box::ID()) { + return FeaturePtr(new PrimitivesPlugin_Box); + } + // feature of such kind is not found + return FeaturePtr(); +} diff --git a/src/PrimitivesPlugin/PrimitivesPlugin_Plugin.h b/src/PrimitivesPlugin/PrimitivesPlugin_Plugin.h new file mode 100644 index 000000000..5cfbf37d4 --- /dev/null +++ b/src/PrimitivesPlugin/PrimitivesPlugin_Plugin.h @@ -0,0 +1,29 @@ +// Copyright (C) 2014-20xx CEA/DEN, EDF R&D --> + +// File: PrimitivesPlugin_Plugin.hxx +// Created: 07 July 2014 +// Author: Vitaly SMETANNIKOV + +#ifndef PrimitivesPlugin_Plugin_H_ +#define PrimitivesPlugin_Plugin_H_ + +#include "PrimitivesPlugin.h" +#include +#include + +/**\class PrimitivesPlugin_Plugin + * \ingroup Plugins + * \brief The main class managing Primitive Features as plugins. + */ +class PRIMITIVESPLUGIN_EXPORT PrimitivesPlugin_Plugin : public ModelAPI_Plugin +{ + public: + /// Creates the feature object of this plugin by the feature string ID + virtual FeaturePtr createFeature(std::string theFeatureID); + + public: + /// Default constructor + PrimitivesPlugin_Plugin(); +}; + +#endif diff --git a/src/PrimitivesPlugin/Test/APIDirectTestBox.py b/src/PrimitivesPlugin/Test/APIDirectTestBox.py new file mode 100644 index 000000000..2789aa568 --- /dev/null +++ b/src/PrimitivesPlugin/Test/APIDirectTestBox.py @@ -0,0 +1,41 @@ +from GeomAlgoAPI import GeomAlgoAPI_DirectAPI as shaperpy +from GeomAlgoAPI import GeomAlgoAPI_Exception as myExcept +from GeomAPI import GeomAPI_Pnt as pnt + +import GEOM +import salome +from salome.geom import geomBuilder +geompy = geomBuilder.New(salome.myStudy) + +# Create a box with dimensions +try : + box1 = shaperpy.MakeBox(5.,15.,5.) + aDump1 = box1.getShapeStream() + aBrep1 = geompy.RestoreShape(aDump1) + geompy.addToStudy(aBrep1, "box1") + +except myExcept,ec: + print ec.what() + +# Create a box with two points defining the diagonal +try : + pnt1 = pnt(0.,0.,0.) + pnt2 = pnt(10.,10.,10.) + box2 = shaperpy.MakeBox(pnt1,pnt2) + aDump2 = box2.getShapeStream() + aBrep2 = geompy.RestoreShape(aDump2) + geompy.addToStudy(aBrep2, "box2") + +except myExcept,ec: + print ec.what() + + +# Create a box with null dimensions +try : + box3 = shaperpy.MakeBox(0.,0.,0.) + aDump3 = box1.getShapeStream() + aBrep3 = geompy.RestoreShape(aDump3) + geompy.addToStudy(aBrep1, "box3") + +except myExcept,ec: + print ec.what() \ No newline at end of file diff --git a/src/PrimitivesPlugin/Test/UnitTestBox.py b/src/PrimitivesPlugin/Test/UnitTestBox.py new file mode 100644 index 000000000..6753153ce --- /dev/null +++ b/src/PrimitivesPlugin/Test/UnitTestBox.py @@ -0,0 +1,150 @@ +""" + UnitTestBox.py + Unit Test of PrimitivesPlugin_Box class + +class PrimitivesPlugin_Box : public ModelAPI_Feature + static const std::string MY_BOX_ID("Box"); + static const std::string METHOD_ATTR("CreationMethod"); + static const std::string MY_POINT_FIRST("FirstPoint"); + static const std::string MY_POINT_SECOND("SecondPoint"); + static const std::string MY_DX("dx"); + static const std::string MY_DY("dy"); + static const std::string MY_DZ("dz"); + + data()->addAttribute(METHOD(), ModelAPI_AttributeString::typeId()); + data()->addAttribute(POINT_FIRST(), ModelAPI_AttributeSelection::typeId()); + data()->addAttribute(POINT_SECOND(), ModelAPI_AttributeSelection::typeId()); + data()->addAttribute(DX(), ModelAPI_AttributeDouble::typeId()); + data()->addAttribute(DY(), ModelAPI_AttributeDouble::typeId()); + data()->addAttribute(DZ(), ModelAPI_AttributeDouble::typeId()); + +""" + +#========================================================================= +# Initialization of the test +#========================================================================= +from ModelAPI import * +from GeomDataAPI import * +from GeomAlgoAPI import * +from GeomAPI import * +import math + +__updated__ = "2016-01-04" + +aSession = ModelAPI_Session.get() +aDocument = aSession.moduleDocument() +# Create a part for creation of a box +aSession.startOperation() +aPartFeature = aDocument.addFeature("Part") +aSession.finishOperation() +assert (len(aPartFeature.results()) == 1) + +aPartResult = modelAPI_ResultPart(aPartFeature.firstResult()) +aPart = aPartResult.partDoc() +#========================================================================= +# Creation of a Box by coordinates +#========================================================================= +aSession.startOperation() +aBoxBy3Dims = aPart.addFeature("Box") +assert (aBoxBy3Dims.getKind() == "Box") + +aBoxBy3Dims.string("CreationMethod").setValue("BoxByCoordinates") +aBoxBy3Dims.real("dx").setValue(1.6) +aBoxBy3Dims.real("dy").setValue(1.6) +aBoxBy3Dims.real("dz").setValue(1.6) +aBoxBy3Dims.execute() + +# Check box results +assert (len(aBoxBy3Dims.results()) > 0) +aBoxResult = modelAPI_ResultBody(aBoxBy3Dims.firstResult()) +assert (aBoxResult is not None) + +# Check box volume +aRefVolume = 1.6 * 1.6 * 1.6 +aResVolume = GeomAlgoAPI_ShapeTools_volume(aBoxResult.shape()) +assert (math.fabs(aResVolume - aRefVolume) < 10 ** -5) + + +#Check the naming by selecting a face and making a plane out of it +aPlaneTop = aPart.addFeature("Plane") +assert(aPlaneTop.getKind() == "Plane") +aPlaneTop.string("CreationMethod").setValue("PlaneByFaceAndDistance") +aSelectionAttr = aPlaneTop.selection("planeFace") +aSelectionAttr.selectSubShape("face", "Box_1_1/Top_1") +aPlaneTop.real("distance").setValue(0.4) +aPlaneTop.execute() + +#The face should be at 1.6, so the plane should be at 1.6 + 0.4 = 2. +aRefPlaneTopLocation = 2. + +#location() is a method from GeomAPI_Face that returns a GeomAPI_Pnt, from which we can extract the z coordinate +aPlaneTopResult = aPlaneTop.firstResult() +aPlaneTopFace = GeomAPI_Face(aPlaneTopResult.shape()) +aPlaneTestLocation = aPlaneTopFace.getPlane() +aPlaneLocation = aPlaneTestLocation.location().z() +assert(math.fabs(aPlaneLocation - aRefPlaneTopLocation) < 10 ** -5) + +aSession.finishOperation() + +#========================================================================= +# Creation of a Box by two points +#========================================================================= + +aSession.startOperation() + +#Create two points +aPoint1 = aPart.addFeature("Point") +aPoint2 = aPart.addFeature("Point") +assert(aPoint1.getKind() == "Point") +assert(aPoint2.getKind() == "Point") +aPoint1.real("x").setValue(2.0) +aPoint1.real("y").setValue(2.0) +aPoint1.real("z").setValue(2.0) +aPoint2.real("x").setValue(2.5) +aPoint2.real("y").setValue(2.5) +aPoint2.real("z").setValue(2.5) +aPoint1.execute() +aPoint2.execute() +aPoint1Result = aPoint1.firstResult() +aPoint2Result = aPoint2.firstResult() +aPoint1Vertex = aPoint1Result.shape() +aPoint2Vertex = aPoint2Result.shape() + +aBoxBy2Pts = aPart.addFeature("Box") +assert (aBoxBy2Pts.getKind() == "Box") +aBoxBy2Pts.string("CreationMethod").setValue("BoxByTwoPoints") +aBoxBy2Pts.selection("FirstPoint").setValue(aPoint1Result, aPoint1Vertex) +aBoxBy2Pts.selection("SecondPoint").setValue(aPoint2Result, aPoint2Vertex) +aBoxBy2Pts.execute() + +# Check box volume +aBoxResult2 = modelAPI_ResultBody(aBoxBy2Pts.firstResult()) +aRefVolume2 = 0.5 * 0.5 * 0.5 +aResVolume2 = GeomAlgoAPI_ShapeTools_volume(aBoxResult2.shape()) +assert (math.fabs(aResVolume2 - aRefVolume2) < 10 ** -5) + +#Check the naming by selecting a face and making a plane out of it +aPlaneRight = aPart.addFeature("Plane") +assert(aPlaneRight.getKind() == "Plane") +aPlaneRight.string("CreationMethod").setValue("PlaneByFaceAndDistance") +aSelectionAttr = aPlaneRight.selection("planeFace") +aSelectionAttr.selectSubShape("face", "Box_2_1/Right_1") +aPlaneRight.real("distance").setValue(0.5) +aPlaneRight.execute() + +#The face should be at 2.5, so the plane should be at 2.5 + 0.5 = 3. +aRefPlaneRightLocation = 3. + +#location() is a method from GeomAPI_Face that returns a GeomAPI_Pnt, +#from which we can extract the y coordinate +aPlaneRightResult = aPlaneRight.firstResult() +aPlaneRightFace = GeomAPI_Face(aPlaneRightResult.shape()) +aPlaneTestLocation = aPlaneRightFace.getPlane() +aPlaneLocation = aPlaneTestLocation.location().y() +assert(math.fabs(aPlaneLocation - aRefPlaneRightLocation) < 10 ** -5) + +aSession.finishOperation() + +#========================================================================= +# End of test +#========================================================================= diff --git a/src/PrimitivesPlugin/Test/UseTestBox.py b/src/PrimitivesPlugin/Test/UseTestBox.py new file mode 100644 index 000000000..e69de29bb diff --git a/src/PrimitivesPlugin/box_widget.xml b/src/PrimitivesPlugin/box_widget.xml new file mode 100644 index 000000000..9034c482a --- /dev/null +++ b/src/PrimitivesPlugin/box_widget.xml @@ -0,0 +1,52 @@ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/PrimitivesPlugin/plugin-Primitives.xml b/src/PrimitivesPlugin/plugin-Primitives.xml new file mode 100644 index 000000000..f26ce3a3a --- /dev/null +++ b/src/PrimitivesPlugin/plugin-Primitives.xml @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/src/PythonAddons/macros/box/feature.py b/src/PythonAddons/macros/box/feature.py index 1d3f02f07..165c8bcc3 100644 --- a/src/PythonAddons/macros/box/feature.py +++ b/src/PythonAddons/macros/box/feature.py @@ -22,7 +22,7 @@ class BoxFeature(model.Feature): @staticmethod def ID(): """Return Id of the feature.""" - return "Box" + return "Box_script" @staticmethod def WIDTH_ID(): diff --git a/src/PythonAddons/macros/box/widget.xml b/src/PythonAddons/macros/box/widget.xml index e977b3e8c..1bd4a648b 100644 --- a/src/PythonAddons/macros/box/widget.xml +++ b/src/PythonAddons/macros/box/widget.xml @@ -2,7 +2,7 @@ - +