INCLUDE(${SWIG_USE_FILE})
INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR})
+INCLUDE(UnitTest)
SET(PROJECT_HEADERS
GeomAlgoAPI.h
GeomAlgoAPI_ShapeAPI.h
GeomAlgoAPI_Exception.h
GeomAlgoAPI_Box.h
+ GeomAlgoAPI_Sphere.h
GeomAlgoAPI_XAOExport.h
GeomAlgoAPI_XAOImport.h
GeomAlgoAPI_Copy.h
GeomAlgoAPI_ShapeAPI.cpp
GeomAlgoAPI_Exception.cpp
GeomAlgoAPI_Box.cpp
+ GeomAlgoAPI_Sphere.cpp
GeomAlgoAPI_XAOExport.cpp
GeomAlgoAPI_XAOImport.cpp
GeomAlgoAPI_Copy.cpp
INSTALL(TARGETS _GeomAlgoAPI DESTINATION ${SHAPER_INSTALL_SWIG})
INSTALL(TARGETS GeomAlgoAPI DESTINATION ${SHAPER_INSTALL_BIN})
INSTALL(FILES ${SWIG_SCRIPTS} DESTINATION ${SHAPER_INSTALL_SWIG})
+
+ADD_UNIT_TESTS(TestAPI_Box.py
+ TestAPI_Sphere.py
+)
%shared_ptr(GeomAlgoAPI_Translation)
%shared_ptr(GeomAlgoAPI_Transform)
%shared_ptr(GeomAlgoAPI_Box)
-%shared_ptr(GeomAlgoAPI_BoxPoints)
+%shared_ptr(GeomAlgoAPI_Sphere)
%shared_ptr(GeomAlgoAPI_Copy)
// all supported interfaces
#include "GeomAlgoAPI_ShapeAPI.h"
#include <GeomAlgoAPI_Box.h>
+#include <GeomAlgoAPI_Sphere.h>
#include <GeomAPI_Pnt.h>
#include <GeomAPI_Edge.h>
}
return aBoxAlgo.shape();
}
+
+ //=========================================================================================================
+ std::shared_ptr<GeomAPI_Shape> GeomAlgoAPI_ShapeAPI::makeSphere(const double theRadius) throw (GeomAlgoAPI_Exception)
+ {
+ std::shared_ptr<GeomAPI_Pnt> anOrigin = std::shared_ptr<GeomAPI_Pnt>(new GeomAPI_Pnt(0., 0., 0.));
+ GeomAlgoAPI_Sphere aSphereAlgo(anOrigin, theRadius);
+
+ if (!aSphereAlgo.check()) {
+ throw GeomAlgoAPI_Exception(aSphereAlgo.getError());
+ }
+
+ aSphereAlgo.build();
+
+ if(!aSphereAlgo.isDone()) {
+ throw GeomAlgoAPI_Exception(aSphereAlgo.getError());
+ }
+ if (!aSphereAlgo.checkValid("Sphere builder with radius at origin")) {
+ throw GeomAlgoAPI_Exception(aSphereAlgo.getError());
+ }
+ return aSphereAlgo.shape();
+ }
+
+ //=========================================================================================================
+ std::shared_ptr<GeomAPI_Shape> GeomAlgoAPI_ShapeAPI::makeSphere(std::shared_ptr<GeomAPI_Pnt> theCenterPoint,
+ const double theRadius) throw (GeomAlgoAPI_Exception)
+ {
+ GeomAlgoAPI_Sphere aSphereAlgo(theCenterPoint, theRadius);
+
+ if (!aSphereAlgo.check()) {
+ throw GeomAlgoAPI_Exception(aSphereAlgo.getError());
+ }
+
+ aSphereAlgo.build();
+
+ if(!aSphereAlgo.isDone()) {
+ throw GeomAlgoAPI_Exception(aSphereAlgo.getError());
+ }
+ if (!aSphereAlgo.checkValid("Sphere builder with center and radius")) {
+ throw GeomAlgoAPI_Exception(aSphereAlgo.getError());
+ }
+ return aSphereAlgo.shape();
+ }
}
/// \return a shape
static std::shared_ptr<GeomAPI_Shape> makeBox(std::shared_ptr<GeomAPI_Pnt> theFirstPoint,
std::shared_ptr<GeomAPI_Pnt> theSecondPoint) throw (GeomAlgoAPI_Exception);
+
+ /// Creates a sphere centered around the origin using a radius.
+ /// \param theRadius Radius of the sphere
+ /// \return a shape
+ static std::shared_ptr<GeomAPI_Shape> makeSphere(const double theRadius) throw (GeomAlgoAPI_Exception);
+
+ /// Creates a sphere using a center and a radius.
+ /// \param theCenterPoint Center of the sphere
+ /// \param theRadius Radius of the sphere
+ /// \return a shape
+ static std::shared_ptr<GeomAPI_Shape> makeSphere(std::shared_ptr<GeomAPI_Pnt> theCenterPoint,
+ const double theRadius) throw (GeomAlgoAPI_Exception);
};
}
#endif
--- /dev/null
+// Copyright (C) 2014-2016 CEA/DEN, EDF R&D
+
+// File: GeomAlgoAPI_Sphere.cpp
+// Created: 29 Mar 2016
+// Author: CEA (delegation to Alyotech)
+
+#include <GeomAlgoAPI_Sphere.h>
+
+#include <BRepPrimAPI_MakeSphere.hxx>
+#include <TopoDS_Shape.hxx>
+
+//=================================================================================================
+GeomAlgoAPI_Sphere::GeomAlgoAPI_Sphere()
+{
+}
+
+
+//=================================================================================================
+GeomAlgoAPI_Sphere::GeomAlgoAPI_Sphere(std::shared_ptr<GeomAPI_Pnt> theCenter, const double theRadius)
+{
+ myCenter = theCenter;
+ myRadius = theRadius;
+}
+
+//=================================================================================================
+bool GeomAlgoAPI_Sphere::check()
+{
+ if (myRadius < Precision::Confusion()) {
+ myError = "Sphere builder with center and radius :: radius is less than or equal to zero.";
+ return false;
+ }
+ return true;
+}
+
+//=================================================================================================
+void GeomAlgoAPI_Sphere::build()
+{
+ myCreatedFaces.clear();
+
+ // Convert the point given as argument to OCCT object
+ const gp_Pnt& aCenter = myCenter->impl<gp_Pnt>();
+
+ // We need the OCCT sphere-making engine. And we need it as a regular pointer so we can add it to the list of MakeShape
+ BRepPrimAPI_MakeSphere *aSphereMaker = new BRepPrimAPI_MakeSphere(aCenter, myRadius);
+ aSphereMaker->Build(); //Let the OCCT sphere-maker make the sphere
+
+ // Test the algorithm
+ if (!aSphereMaker->IsDone()) {
+ return;
+ }
+
+ TopoDS_Shape aResult = aSphereMaker->Shape();
+ std::shared_ptr<GeomAPI_Shape> aShape(new GeomAPI_Shape());
+ aShape->setImpl(new TopoDS_Shape(aResult));
+ setShape(aShape);
+
+// Test on the shapes
+ if (!aShape.get() || aShape->isNull()) {
+ myError = "Sphere builder with center and radius :: resulting shape is null.";
+ return;
+ }
+
+ setImpl(aSphereMaker);
+ setBuilderType(OCCT_BRepBuilderAPI_MakeShape);
+
+ setDone(true);
+}
--- /dev/null
+// Copyright (C) 2014-2016 CEA/DEN, EDF R&D
+
+// File: GeomAlgoAPI_Sphere.h
+// Created: 29 Mar 2016
+// Author: CEA (delegation to Alyotech)
+
+#ifndef GeomAlgoAPI_Sphere_H_
+#define GeomAlgoAPI_Sphere_H_
+
+#include <GeomAPI_Pnt.h>
+#include <GeomAlgoAPI_MakeShape.h>
+
+/**\class GeomAlgoAPI_Sphere
+ * \ingroup DataAlgo
+ * \brief Allows to create Sphere Primitives
+ */
+class GeomAlgoAPI_Sphere : public GeomAlgoAPI_MakeShape
+{
+ public:
+ GEOMALGOAPI_EXPORT GeomAlgoAPI_Sphere();
+
+ /// Creates a Sphere using a center and a radius
+ /// \param theCenter the center
+ /// \param theRadius the radius of the sphere
+ GEOMALGOAPI_EXPORT GeomAlgoAPI_Sphere(std::shared_ptr<GeomAPI_Pnt> theCenter, const double theRadius);
+
+ /// Checks if the center myCenter and radius myRadius are OK.
+ GEOMALGOAPI_EXPORT bool check();
+
+ /// Builds the sphere with the center myCenter and radius myRadius
+ GEOMALGOAPI_EXPORT void build();
+
+ private:
+ std::shared_ptr<GeomAPI_Pnt> myCenter; /// attribute point defining the center of the sphere
+ double myRadius; /// attribute radius of the sphere
+};
+
+
+#endif
#include "GeomAlgoAPI_Exception.h"
#include "GeomAlgoAPI_ShapeAPI.h"
#include "GeomAlgoAPI_Box.h"
+ #include "GeomAlgoAPI_Sphere.h"
#include "GeomAlgoAPI_Copy.h"
#include <memory>
--- /dev/null
+# Copyright (C) 2014-2016 CEA/DEN, EDF R&D
+
+# File: APIDirectTestSphere.py
+# Created: 15 Apr 2016
+# Author: CEA (delegation to Alyotech)
+
+from GeomAlgoAPI import GeomAlgoAPI_ShapeAPI as shaperpy
+from GeomAlgoAPI import GeomAlgoAPI_Exception as myExcept
+from GeomAPI import GeomAPI_Pnt as pnt
+
+# Create a sphere with radius 5. at origin
+try :
+ sphere1 = shaperpy.makeSphere(5.)
+
+except myExcept,ec:
+ print ec.what()
+
+# Create a sphere with a point defining the center and radius 8.
+try :
+ center = pnt(10.,0.,0.)
+ sphere2 = shaperpy.makeSphere(center, 8.)
+
+except myExcept,ec:
+ print ec.what()
+
+
+# Create a sphere with null radius
+try :
+ sphere3 = shaperpy.makeSphere(0.)
+
+except myExcept,ec:
+ print ec.what()
PrimitivesPlugin.h
PrimitivesPlugin_Plugin.h
PrimitivesPlugin_Box.h
+ PrimitivesPlugin_Sphere.h
)
SET(PROJECT_SOURCES
PrimitivesPlugin_Plugin.cpp
PrimitivesPlugin_Box.cpp
+ PrimitivesPlugin_Sphere.cpp
)
SET(XML_RESOURCES
plugin-Primitives.xml
box_widget.xml
+ sphere_widget.xml
)
INCLUDE_DIRECTORIES(
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
+ADD_UNIT_TESTS(TestBox.py
+ TestSphere.py
)
#include <PrimitivesPlugin_Plugin.h>
#include <PrimitivesPlugin_Box.h>
+#include <PrimitivesPlugin_Sphere.h>
#include <ModelAPI_Session.h>
{
if (theFeatureID == PrimitivesPlugin_Box::ID()) {
return FeaturePtr(new PrimitivesPlugin_Box);
+ } else if (theFeatureID == PrimitivesPlugin_Sphere::ID()) {
+ return FeaturePtr(new PrimitivesPlugin_Sphere);
}
// feature of such kind is not found
return FeaturePtr();
--- /dev/null
+// Copyright (C) 2014-2016 CEA/DEN, EDF R&D
+
+// File: PrimitivesPlugin_Sphere.cpp
+// Created: 29 Mar 2016
+// Author: CEA (delegation to Alyotech)
+
+#include <PrimitivesPlugin_Sphere.h>
+
+#include <ModelAPI_Data.h>
+#include <ModelAPI_Session.h>
+#include <ModelAPI_ResultBody.h>
+#include <ModelAPI_ResultConstruction.h>
+#include <ModelAPI_AttributeDouble.h>
+#include <ModelAPI_AttributeSelection.h>
+#include <ModelAPI_AttributeString.h>
+
+#include <GeomAlgoAPI_PointBuilder.h>
+
+#include <memory>
+
+//=================================================================================================
+PrimitivesPlugin_Sphere::PrimitivesPlugin_Sphere() // Nothing to do during instantiation
+{
+}
+
+//=================================================================================================
+void PrimitivesPlugin_Sphere::initAttributes()
+{
+
+ // The center of the sphere
+ data()->addAttribute(CENTER(), ModelAPI_AttributeSelection::typeId());
+ AttributeSelectionPtr aBase = data()->selection(CENTER());
+ if (!aBase->isInitialized()) { // on restore (undo, open), this may be already defined
+ ObjectPtr aPointObj = ModelAPI_Session::get()->moduleDocument()->objectByName(ModelAPI_ResultConstruction::group(), "Origin");
+ if (aPointObj.get()) { // if initialization plugin performed well
+ ResultPtr aPointRes = std::dynamic_pointer_cast<ModelAPI_Result>(aPointObj);
+ // second argument is null: just point result, without sub-shape selection
+ aBase->setValue(aPointRes, std::shared_ptr<GeomAPI_Shape>());
+ }
+ }
+
+ // The radius needed to create a sphere by radius at origin and by the center
+ data()->addAttribute(RADIUS(), ModelAPI_AttributeDouble::typeId());
+}
+
+//=================================================================================================
+void PrimitivesPlugin_Sphere::execute(){
+
+//Get the point and the radius from the input parameters, check their soudness, then instantiate a sphere builder with these elements
+ AttributeSelectionPtr aRef = data()->selection(CENTER());
+ double aRadius = real(RADIUS())->value();
+
+ std::shared_ptr<GeomAPI_Pnt> aCenter = GeomAlgoAPI_PointBuilder::point(aRef->context()->shape());
+
+ std::shared_ptr<GeomAlgoAPI_Sphere> aSphereAlgo;
+
+ if ((aRef.get() != NULL)) {
+ GeomShapePtr aShape = aRef->value();
+ if (!aShape.get()) //If we can't get the points directly, try getting them from the context
+ aShape = aRef->context()->shape();
+ if (aShape){
+ std::shared_ptr<GeomAPI_Pnt> aCenter = GeomAlgoAPI_PointBuilder::point(aShape);
+ aSphereAlgo = std::shared_ptr<GeomAlgoAPI_Sphere>(new GeomAlgoAPI_Sphere(aCenter, aRadius));
+ }
+ }
+
+ // We need to check that everything went smoothly with GeomAlgoAPI_Sphere
+ if (!aSphereAlgo->check()){
+ setError(aSphereAlgo->getError(), false);
+ return;
+ }
+
+ // Build the sphere
+ aSphereAlgo->build();
+
+ // Check if the creation of the sphere went well
+ if(!aSphereAlgo->isDone()) {
+ setError(aSphereAlgo->getError());
+ return;
+ }
+ if(!aSphereAlgo->checkValid("Sphere builder")) {
+ setError(aSphereAlgo->getError());
+ return;
+ }
+
+ int aResultIndex = 0; // There's only going to be one result : the sphere
+ ResultBodyPtr aResultSphere = document()->createBody(data(), aResultIndex);
+ loadNamingDS(aSphereAlgo, aResultSphere);
+ setResult(aResultSphere, aResultIndex);
+}
+
+//=================================================================================================
+ void PrimitivesPlugin_Sphere::loadNamingDS(std::shared_ptr<GeomAlgoAPI_Sphere> theSphereAlgo,
+ std::shared_ptr<ModelAPI_ResultBody> theResultSphere)
+{
+ // Load the result
+ theResultSphere->store(theSphereAlgo->shape());
+
+ // Prepare the naming
+ theSphereAlgo->prepareNamingFaces();
+
+ // Insert to faces
+ int num = 1;
+ std::map< std::string, std::shared_ptr<GeomAPI_Shape> > listOfFaces = theSphereAlgo->getCreatedFaces();
+ for (std::map< std::string, std::shared_ptr<GeomAPI_Shape> >::iterator it=listOfFaces.begin(); it!=listOfFaces.end(); ++it){
+ std::shared_ptr<GeomAPI_Shape> aFace = (*it).second;
+ theResultSphere->generated(aFace, (*it).first, num++);
+ }
+}
--- /dev/null
+// Copyright (C) 2014-2016 CEA/DEN, EDF R&D
+
+// File: PrimitivesPlugin_Sphere.h
+// Created: 29 Mar 2016
+// Author: CEA (delegation to Alyotech)
+
+#ifndef PrimitivesPlugin_Sphere_H_
+#define PrimitivesPlugin_Sphere_H_
+
+#include <PrimitivesPlugin.h>
+#include <ModelAPI_Feature.h>
+#include <GeomAlgoAPI_Sphere.h>
+
+class GeomAPI_Shape;
+class ModelAPI_ResultBody;
+
+/**\class PrimitivesPlugin_Sphere
+ * \ingroup Plugins
+ * \brief Feature for creation of a sphere.
+ *
+ * Sphere creates a sphere from a radius and a center point, defaulting to
+ * the origin.
+ */
+class PrimitivesPlugin_Sphere : public ModelAPI_Feature
+{
+ public:
+ /// Sphere kind
+ inline static const std::string& ID()
+ {
+ static const std::string MY_SPHERE_ID("Sphere");
+ return MY_SPHERE_ID;
+ }
+
+ /// attribute name of the center
+ inline static const std::string& CENTER()
+ {
+ static const std::string MY_CENTER("center");
+ return MY_CENTER;
+ }
+
+ /// attribute name of the radius
+ inline static const std::string& RADIUS()
+ {
+ static const std::string MY_RADIUS("radius");
+ return MY_RADIUS;
+ }
+
+ /// Returns the kind of a feature
+ PRIMITIVESPLUGIN_EXPORT virtual const std::string& getKind()
+ {
+ static std::string MY_KIND = PrimitivesPlugin_Sphere::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_Sphere();
+
+ private:
+ /// Load Naming data structure of the feature to the document
+ void loadNamingDS(std::shared_ptr<GeomAlgoAPI_Sphere> theSphereAlgo,
+ std::shared_ptr<ModelAPI_ResultBody> theResultSphere);
+
+};
+
+#endif
--- /dev/null
+# Copyright (C) 2014-2016 CEA/DEN, EDF R&D
+
+# File: UnitTestSphere.py
+# Created: 31 Mar 2016
+# Author: CEA (delegation to Alyotech)
+
+"""
+ UnitTestSphere.py
+ Unit Test of PrimitivesPlugin_Sphere class
+
+class PrimitivesPlugin_Sphere : public ModelAPI_Feature
+ static const std::string MY_SPHERE_ID("Sphere");
+ static const std::string METHOD_ATTR("CreationMethod");
+ static const std::string MY_CENTER("center");
+ static const std::string MY_RADIUS("radius");
+
+
+ data()->addAttribute(METHOD(), ModelAPI_AttributeString::typeId());
+ data()->addAttribute(CENTER(), ModelAPI_AttributeSelection::typeId());
+ data()->addAttribute(RADIUS(), 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 sphere
+aSession.startOperation()
+aPartFeature = aDocument.addFeature("Part")
+aSession.finishOperation()
+assert (len(aPartFeature.results()) == 1)
+
+aPartResult = modelAPI_ResultPart(aPartFeature.firstResult())
+aPart = aPartResult.partDoc()
+
+#=========================================================================
+# Creation of a Sphere by a point and a radius
+#=========================================================================
+
+aSession.startOperation()
+
+#Create the center
+aCenter = aPart.addFeature("Point")
+assert(aCenter.getKind() == "Point")
+aCenter.real("x").setValue(10.0)
+aCenter.real("y").setValue(10.0)
+aCenter.real("z").setValue(10.0)
+aCenter.execute()
+aCenterResult = aCenter.firstResult()
+aCenterVertex = aCenterResult.shape()
+
+aSphereByCenter = aPart.addFeature("Sphere")
+assert (aSphereByCenter.getKind() == "Sphere")
+aSphereByCenter.selection("center").setValue(aCenterResult, aCenterVertex)
+aSphereByCenter.real("radius").setValue(5.)
+aSphereByCenter.execute()
+
+# Check sphere results
+assert (len(aSphereByCenter.results()) > 0)
+aSphereCenterResult = modelAPI_ResultBody(aSphereByCenter.firstResult())
+assert (aSphereCenterResult is not None)
+
+# Check sphere volume
+aRefVolumeSphereCenter = (4. * math.pi * 5. ** 3 ) / 3.
+aResVolumeSphereCenter = GeomAlgoAPI_ShapeTools_volume(aSphereCenterResult.shape())
+assert (math.fabs(aResVolumeSphereCenter - aRefVolumeSphereCenter) < 10. ** -5)
+
+aSession.finishOperation()
+
+#=========================================================================
+# End of test
+#=========================================================================
<feature id="Box" title="Box" tooltip="Create a box" icon="icons/Primitives/box.png">
<source path="box_widget.xml"/>
</feature>
+ <feature id="Sphere" title="Sphere" tooltip="Create a Sphere" icon="icons/Primitives/sphere.png">
+ <source path="sphere_widget.xml"/>
+ </feature>
</group>
</workbench>
</plugin>
--- /dev/null
+<!-- Copyright (C) 2015-2016 CEA/DEN, EDF R&D -->
+
+<source>
+ <shape_selector
+ id="center"
+ label="center"
+ default=""
+ shape_types="vertex"
+ icon="icons/Primitives/point.png"
+ tooltip="Select a center">
+ <validator id="GeomValidators_ConstructionComposite"/>
+ <validator id="GeomValidators_ShapeType" parameters="vertex"/>
+ </shape_selector>
+ <doublevalue
+ id="radius"
+ label="radius"
+ step="1."
+ default="10."
+ min="0."
+ icon="icons/Primitives/radius.png"
+ tooltip="Enter a radius">
+ </doublevalue>
+</source>