From: Clarisse Genrault Date: Tue, 21 Jun 2016 13:23:48 +0000 (+0200) Subject: Add the primitive 3D "Box". X-Git-Tag: V_2.5.0~231 X-Git-Url: http://git.salome-platform.org/gitweb/?a=commitdiff_plain;h=114b72cd99a3a4be9e851be1c4b271b554808897;p=modules%2Fshaper.git Add the primitive 3D "Box". --- diff --git a/src/GeomAlgoAPI/CMakeLists.txt b/src/GeomAlgoAPI/CMakeLists.txt index 7d05409ac..ee42e2a90 100644 --- a/src/GeomAlgoAPI/CMakeLists.txt +++ b/src/GeomAlgoAPI/CMakeLists.txt @@ -39,6 +39,10 @@ SET(PROJECT_HEADERS GeomAlgoAPI_WireBuilder.h GeomAlgoAPI_Sewing.h GeomAlgoAPI_ShapeBuilder.h + GeomAlgoAPI_DirectAPI.h + GeomAlgoAPI_Exception.h + GeomAlgoAPI_Box.h + GeomAlgoAPI_BoxPoints.h GeomAlgoAPI_XAOExport.h GeomAlgoAPI_XAOImport.h ) @@ -76,6 +80,10 @@ SET(PROJECT_SOURCES GeomAlgoAPI_WireBuilder.cpp GeomAlgoAPI_Sewing.cpp GeomAlgoAPI_ShapeBuilder.cpp + GeomAlgoAPI_DirectAPI.cpp + GeomAlgoAPI_Exception.cpp + GeomAlgoAPI_Box.cpp + GeomAlgoAPI_BoxPoints.cpp GeomAlgoAPI_XAOExport.cpp GeomAlgoAPI_XAOImport.cpp ) diff --git a/src/GeomAlgoAPI/GeomAlgoAPI.i b/src/GeomAlgoAPI/GeomAlgoAPI.i index c6d4d7953..9391a720c 100644 --- a/src/GeomAlgoAPI/GeomAlgoAPI.i +++ b/src/GeomAlgoAPI/GeomAlgoAPI.i @@ -33,6 +33,8 @@ %shared_ptr(GeomAlgoAPI_ShapeBuilder) %shared_ptr(GeomAlgoAPI_Translation) %shared_ptr(GeomAlgoAPI_Transform) +%shared_ptr(GeomAlgoAPI_Box) +%shared_ptr(GeomAlgoAPI_BoxPoints) // all supported interfaces %include "GeomAlgoAPI_MakeShape.h" @@ -66,6 +68,8 @@ %include "GeomAlgoAPI_WireBuilder.h" %include "GeomAlgoAPI_Sewing.h" %include "GeomAlgoAPI_ShapeBuilder.h" +%include "GeomAlgoAPI_Exception.h" +%include "GeomAlgoAPI_DirectAPI.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..ee03a2224 --- /dev/null +++ b/src/GeomAlgoAPI/GeomAlgoAPI_Box.cpp @@ -0,0 +1,94 @@ +// 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; + } + + 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..dcfd835c5 --- /dev/null +++ b/src/GeomAlgoAPI/GeomAlgoAPI_BoxPoints.cpp @@ -0,0 +1,65 @@ +// 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; + } + + 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_swig.h b/src/GeomAlgoAPI/GeomAlgoAPI_swig.h index 226338bf4..b742d88e8 100644 --- a/src/GeomAlgoAPI/GeomAlgoAPI_swig.h +++ b/src/GeomAlgoAPI/GeomAlgoAPI_swig.h @@ -40,7 +40,11 @@ #include "GeomAlgoAPI_Pipe.h" #include "GeomAlgoAPI_WireBuilder.h" #include "GeomAlgoAPI_Sewing.h" - #include "GeomAlgoAPI_ShapeBuilder.h" + #include "GeomAlgoAPI_ShapeBuilder.h" + #include "GeomAlgoAPI_Exception.h" + #include "GeomAlgoAPI_DirectAPI.h" + #include "GeomAlgoAPI_Box.h" + #include "GeomAlgoAPI_BoxPoints.h" #include #include diff --git a/src/PrimitivesPlugin/CMakeLists.txt b/src/PrimitivesPlugin/CMakeLists.txt new file mode 100644 index 000000000..86a5f1683 --- /dev/null +++ b/src/PrimitivesPlugin/CMakeLists.txt @@ -0,0 +1,50 @@ +# Copyright (C) 2015-2016 CEA/DEN, EDF R&D + +# File: CMakeLists.txt +# Created: 07 Apr 2016 +# Author: CEA (delegation to Alyotech) + +INCLUDE(UnitTest) + +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}) +INSTALL(DIRECTORY icons/ DESTINATION ${SHAPER_INSTALL_XML_RESOURCES}/icons/Primitives) + +ADD_UNIT_TESTS(UnitTestBox.py + APIDirectTestBox.py +) + 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..734d87d8f --- /dev/null +++ b/src/PrimitivesPlugin/PrimitivesPlugin_Box.cpp @@ -0,0 +1,153 @@ +// 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 + +//================================================================================================= +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; + } + if(!aBoxAlgo->checkValid("Box builder with dimensions")) { + 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 message console. + setError(aBoxAlgo->getError(), false); + return; + } + + // Build the box + aBoxAlgo->build(); + + // Check if the creation of the box + if(!aBoxAlgo->isDone()) { + // The error is not displayed in a popup window. It must be in the message console. + setError(aBoxAlgo->getError(), false); + return; + } + if(!aBoxAlgo->checkValid("Box builder with two points")) { + // The error is not displayed in a popup window. It must be in the message console. + setError(aBoxAlgo->getError(), false); + 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++); + } +} + diff --git a/src/PrimitivesPlugin/PrimitivesPlugin_Box.h b/src/PrimitivesPlugin/PrimitivesPlugin_Box.h new file mode 100644 index 000000000..7672d2fb8 --- /dev/null +++ b/src/PrimitivesPlugin/PrimitivesPlugin_Box.h @@ -0,0 +1,108 @@ +// 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; + +/**\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(); + +}; + + +#endif diff --git a/src/PrimitivesPlugin/PrimitivesPlugin_Plugin.cpp b/src/PrimitivesPlugin/PrimitivesPlugin_Plugin.cpp new file mode 100644 index 000000000..b4281ea41 --- /dev/null +++ b/src/PrimitivesPlugin/PrimitivesPlugin_Plugin.cpp @@ -0,0 +1,37 @@ +// Copyright (C) 2014-2016 CEA/DEN, EDF R&D --> + +// File: PrimitivesPlugin_Plugin.hxx +// Created: 29 Mar 2016 +// Author: Clarisse Genrault (CEA) + +#include + +#include + +#include + +#include + +#include + +#include + +using namespace std; + +// 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..819913bfd --- /dev/null +++ b/src/PrimitivesPlugin/PrimitivesPlugin_Plugin.h @@ -0,0 +1,29 @@ +// Copyright (C) 2014-2016 CEA/DEN, EDF R&D --> + +// File: PrimitivesPlugin_Plugin.hxx +// Created: 29 Mar 2016 +// Author: Clarisse Genrault (CEA) + +#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..247a3f82e --- /dev/null +++ b/src/PrimitivesPlugin/Test/APIDirectTestBox.py @@ -0,0 +1,27 @@ +from GeomAlgoAPI import GeomAlgoAPI_DirectAPI as shaperpy +from GeomAlgoAPI import GeomAlgoAPI_Exception as myExcept +from GeomAPI import GeomAPI_Pnt as pnt + +# Create a box with dimensions +try : + box1 = shaperpy.makeBox(5.,15.,5.) + +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) + +except myExcept,ec: + print ec.what() + + +# Create a box with null dimensions +try : + box3 = shaperpy.makeBox(0.,0.,0.) + +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..3245a09c6 --- /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("BoxByDimensions") +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/box_widget.xml b/src/PrimitivesPlugin/box_widget.xml new file mode 100644 index 000000000..9da6966c1 --- /dev/null +++ b/src/PrimitivesPlugin/box_widget.xml @@ -0,0 +1,55 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/PrimitivesPlugin/icons/box.png b/src/PrimitivesPlugin/icons/box.png new file mode 100644 index 000000000..104a1edde Binary files /dev/null and b/src/PrimitivesPlugin/icons/box.png differ diff --git a/src/PrimitivesPlugin/icons/box_2pt_32x32.png b/src/PrimitivesPlugin/icons/box_2pt_32x32.png new file mode 100644 index 000000000..874d20c5d Binary files /dev/null and b/src/PrimitivesPlugin/icons/box_2pt_32x32.png differ diff --git a/src/PrimitivesPlugin/icons/box_dxyz_32x32.png b/src/PrimitivesPlugin/icons/box_dxyz_32x32.png new file mode 100644 index 000000000..26ce8aa6d Binary files /dev/null and b/src/PrimitivesPlugin/icons/box_dxyz_32x32.png differ diff --git a/src/PrimitivesPlugin/icons/point.png b/src/PrimitivesPlugin/icons/point.png new file mode 100755 index 000000000..96149ebf3 Binary files /dev/null and b/src/PrimitivesPlugin/icons/point.png differ diff --git a/src/PrimitivesPlugin/plugin-Primitives.xml b/src/PrimitivesPlugin/plugin-Primitives.xml new file mode 100644 index 000000000..22a4b366a --- /dev/null +++ b/src/PrimitivesPlugin/plugin-Primitives.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + +