From 7b575e65da4aaf7e4cbf41ccf7d61b83c5842b7f Mon Sep 17 00:00:00 2001 From: dbv Date: Thu, 4 Jun 2015 16:21:16 +0300 Subject: [PATCH] Revolution tests. --- src/FeaturesPlugin/CMakeLists.txt | 1 + .../FeaturesPlugin_Revolution.cpp | 2 +- src/FeaturesPlugin/Test/TestRevolution.py | 120 ++++++++++++++++++ src/GeomAPI/CMakeLists.txt | 2 + src/GeomAPI/GeomAPI.i | 3 + src/GeomAPI/GeomAPI_Ax1.h | 6 +- src/GeomAPI/GeomAPI_Shape.h | 8 ++ src/GeomAPI/GeomAPI_ShapeExplorer.cpp | 84 ++++++++++++ src/GeomAPI/GeomAPI_ShapeExplorer.h | 64 ++++++++++ src/GeomAlgoAPI/GeomAlgoAPI.i | 6 + 10 files changed, 292 insertions(+), 4 deletions(-) create mode 100644 src/FeaturesPlugin/Test/TestRevolution.py create mode 100644 src/GeomAPI/GeomAPI_ShapeExplorer.cpp create mode 100644 src/GeomAPI/GeomAPI_ShapeExplorer.h diff --git a/src/FeaturesPlugin/CMakeLists.txt b/src/FeaturesPlugin/CMakeLists.txt index 4aa8619f0..b16c2b7ca 100644 --- a/src/FeaturesPlugin/CMakeLists.txt +++ b/src/FeaturesPlugin/CMakeLists.txt @@ -60,5 +60,6 @@ INSTALL(FILES ${XML_RESOURCES} DESTINATION plugins) ADD_UNIT_TESTS(TestExtrusion.py TestBoolean.py + TestRevolution.py TestGroup.py TestMultiBoolean.py) diff --git a/src/FeaturesPlugin/FeaturesPlugin_Revolution.cpp b/src/FeaturesPlugin/FeaturesPlugin_Revolution.cpp index 63341f8c4..b0a2a4606 100644 --- a/src/FeaturesPlugin/FeaturesPlugin_Revolution.cpp +++ b/src/FeaturesPlugin/FeaturesPlugin_Revolution.cpp @@ -62,7 +62,7 @@ void FeaturesPlugin_Revolution::execute() std::shared_ptr anAxis; std::shared_ptr anEdge; std::shared_ptr anObjRef = selection(FeaturesPlugin_Revolution::AXIS_OBJECT_ID()); - if(anObjRef && anObjRef->value()->isEdge()) { + if(anObjRef && anObjRef->value() && anObjRef->value()->isEdge()) { anEdge = std::shared_ptr(new GeomAPI_Edge(anObjRef->value())); } if(anEdge) { diff --git a/src/FeaturesPlugin/Test/TestRevolution.py b/src/FeaturesPlugin/Test/TestRevolution.py new file mode 100644 index 000000000..f0806e666 --- /dev/null +++ b/src/FeaturesPlugin/Test/TestRevolution.py @@ -0,0 +1,120 @@ +""" + TestRevolution.py + Unit test of FeaturesPlugin_Revolution class + + class FeaturesPlugin_Revolution : public ModelAPI_Feature + static const std::string MY_REVOLUTION_ID("Revolution"); + static const std::string MY_GROUP_LIST_ID("base"); + static const std::string MY_TO_OBJECT_ID("axis_object"); + static const std::string MY_TO_ANGLE_ID("to_angle"); + static const std::string MY_FROM_ANGLE_ID("from_angle"); + static const std::string MY_TO_OBJECT_ID("to_object"); + static const std::string MY_FROM_OBJECT_ID("from_object"); + + data()->addAttribute(FeaturesPlugin_Revolution::LIST_ID(), ModelAPI_AttributeSelectionList::typeId()); + data()->addAttribute(FeaturesPlugin_Revolution::AXIS_OBJECT_ID(), ModelAPI_AttributeSelection::typeId()); + data()->addAttribute(FeaturesPlugin_Revolution::FROM_OBJECT_ID(), ModelAPI_AttributeSelection::typeId()); + data()->addAttribute(FeaturesPlugin_Revolution::FROM_ANGLE_ID(), ModelAPI_AttributeDouble::typeId()); + data()->addAttribute(FeaturesPlugin_Revolution::TO_OBJECT_ID(), ModelAPI_AttributeSelection::typeId()); + data()->addAttribute(FeaturesPlugin_Revolution::TO_ANGLE_ID(), ModelAPI_AttributeDouble::typeId()); +""" +#========================================================================= +# Initialization of the test +#========================================================================= +from ModelAPI import * +from GeomDataAPI import * +from GeomAlgoAPI import * +from GeomAPI import * +import math + +aSession = ModelAPI_Session.get() +aDocument = aSession.moduleDocument() +# Create a part for revol +aSession.startOperation() +aPartFeature = aDocument.addFeature("Part") +aSession.finishOperation() +assert (len(aPartFeature.results()) == 1) +# Another way is: +# aPart = aSession.activeDocument() +aPartResult = modelAPI_ResultPart(aPartFeature.firstResult()) +aPart = aPartResult.partDoc() + +#========================================================================= +# Create a sketch circle to revol +#========================================================================= +aSession.startOperation() +aCircleSketchFeature = featureToCompositeFeature(aPart.addFeature("Sketch")) +origin = geomDataAPI_Point(aCircleSketchFeature.attribute("Origin")) +origin.setValue(0, 0, 0) +dirx = geomDataAPI_Dir(aCircleSketchFeature.attribute("DirX")) +dirx.setValue(1, 0, 0) +norm = geomDataAPI_Dir(aCircleSketchFeature.attribute("Norm")) +norm.setValue(0, 0, 1) + +# Create circle +aSketchCircle = aCircleSketchFeature.addFeature("SketchCircle") +anCircleCentr = geomDataAPI_Point2D(aSketchCircle.attribute("CircleCenter")) +aCircleRadius = aSketchCircle.real("CircleRadius") +anCircleCentr.setValue(0., 0.) +aCircleRadius.setValue(30.) +aSession.finishOperation() + +# Build shape from sketcher results +aCircleSketchResult = aCircleSketchFeature.firstResult() +aCircleSketchEdges = modelAPI_ResultConstruction(aCircleSketchResult).shape() +origin = geomDataAPI_Point(aCircleSketchFeature.attribute("Origin")).pnt() +dirX = geomDataAPI_Dir(aCircleSketchFeature.attribute("DirX")).dir() +norm = geomDataAPI_Dir(aCircleSketchFeature.attribute("Norm")).dir() +aCircleSketchFaces = ShapeList() +GeomAlgoAPI_SketchBuilder.createFaces( + origin, dirX, norm, aCircleSketchEdges, aCircleSketchFaces) +assert (len(aCircleSketchFaces) > 0) +assert (aCircleSketchFaces[0] is not None) + +#========================================================================= +# Create a sketch line to revol +#========================================================================= +aSession.startOperation() +aLineSketchFeature = featureToCompositeFeature(aPart.addFeature("Sketch")) +origin = geomDataAPI_Point(aLineSketchFeature.attribute("Origin")) +origin.setValue(0, 0, 0) +dirx = geomDataAPI_Dir(aLineSketchFeature.attribute("DirX")) +dirx.setValue(1, 0, 0) +norm = geomDataAPI_Dir(aLineSketchFeature.attribute("Norm")) +norm.setValue(0, 0, 1) + +aSketchLine = aLineSketchFeature.addFeature("SketchLine") +aLineStartPoint = geomDataAPI_Point2D(aSketchLine.attribute("StartPoint")) +aLineEndPoint = geomDataAPI_Point2D(aSketchLine.attribute("EndPoint")) +aLineStartPoint.setValue(-100., -100.) +aLineEndPoint.setValue(100., -100.) +aSession.finishOperation() + +# Build shape from sketcher results +aLineSketchResult = aLineSketchFeature.firstResult() +aLineSketchShape = modelAPI_ResultConstruction(aLineSketchResult).shape() +aShapeExplorer = GeomAPI_ShapeExplorer(aLineSketchShape, GeomAPI_Shape.EDGE) +aLineEdge = aShapeExplorer.current() + +#========================================================================= +# Test revol between from and to angles +#========================================================================= +aSession.startOperation() +aRevolFt = aPart.addFeature("Revolution") +assert (aRevolFt.getKind() == "Revolution") +# selection type FACE=4 +aRevolFt.selectionList("base").append( + aCircleSketchResult, aCircleSketchFaces[0]) +aRevolFt.selection("axis_object").setValue(aLineSketchResult, aLineEdge) +aRevolFt.real("from_angle").setValue(10) +aRevolFt.real("to_angle").setValue(10) +aRevolFt.execute() +aSession.finishOperation() +assert (aRevolFt.real("from_angle").value() == 10.0) +assert (aRevolFt.real("to_angle").value() == 10.0) + +# Check revol results +assert (len(aRevolFt.results()) > 0) +aRevolResult = modelAPI_ResultBody(aRevolFt.firstResult()) +assert (aRevolResult is not None) + diff --git a/src/GeomAPI/CMakeLists.txt b/src/GeomAPI/CMakeLists.txt index 2be8c4af2..afe2bd4ac 100644 --- a/src/GeomAPI/CMakeLists.txt +++ b/src/GeomAPI/CMakeLists.txt @@ -20,6 +20,7 @@ SET(PROJECT_HEADERS GeomAPI_Dir2d.h GeomAPI_Pln.h GeomAPI_Shape.h + GeomAPI_ShapeExplorer.h GeomAPI_Edge.h GeomAPI_Face.h GeomAPI_PlanarEdges.h @@ -47,6 +48,7 @@ SET(PROJECT_SOURCES GeomAPI_Dir2d.cpp GeomAPI_Pln.cpp GeomAPI_Shape.cpp + GeomAPI_ShapeExplorer.cpp GeomAPI_Edge.cpp GeomAPI_Face.cpp GeomAPI_PlanarEdges.cpp diff --git a/src/GeomAPI/GeomAPI.i b/src/GeomAPI/GeomAPI.i index 25c752b61..8fff6a79f 100644 --- a/src/GeomAPI/GeomAPI.i +++ b/src/GeomAPI/GeomAPI.i @@ -4,6 +4,7 @@ #include "GeomAPI.h" #include "GeomAPI_Interface.h" #include "GeomAPI_Shape.h" + #include "GeomAPI_ShapeExplorer.h" #include "GeomAPI_AISObject.h" #include "GeomAPI_Circ2d.h" #include "GeomAPI_Circ.h" @@ -52,12 +53,14 @@ %shared_ptr(GeomAPI_Pnt2d) %shared_ptr(GeomAPI_Pnt) %shared_ptr(GeomAPI_Shape) +%shared_ptr(GeomAPI_ShapeExplorer) %shared_ptr(GeomAPI_XY) %shared_ptr(GeomAPI_XYZ) // all supported interfaces %include "GeomAPI_Interface.h" %include "GeomAPI_Shape.h" +%include "GeomAPI_ShapeExplorer.h" %include "GeomAPI_AISObject.h" %include "GeomAPI_Circ2d.h" %include "GeomAPI_Circ.h" diff --git a/src/GeomAPI/GeomAPI_Ax1.h b/src/GeomAPI/GeomAPI_Ax1.h index d65d8e83d..dbd9bd539 100644 --- a/src/GeomAPI/GeomAPI_Ax1.h +++ b/src/GeomAPI/GeomAPI_Ax1.h @@ -21,9 +21,9 @@ public: GeomAPI_Ax1(); /** \brief Ñonstructor. - * \param[in] theOrigin point of origin. - * \param[in] theDir direction of axis. - */ + * \param[in] theOrigin point of origin. + * \param[in] theDir direction of axis. + */ GeomAPI_Ax1(std::shared_ptr theOrigin, std::shared_ptr theDir); diff --git a/src/GeomAPI/GeomAPI_Shape.h b/src/GeomAPI/GeomAPI_Shape.h index 6f61d9f0f..08281bb29 100644 --- a/src/GeomAPI/GeomAPI_Shape.h +++ b/src/GeomAPI/GeomAPI_Shape.h @@ -17,6 +17,14 @@ */ class GEOMAPI_EXPORT GeomAPI_Shape : public GeomAPI_Interface { +public: + /// Shape type enum + enum ShapeType { + COMPOUND, COMPSOLID, SOLID, SHELL, + FACE, WIRE, EDGE, VERTEX, + SHAPE + }; + public: /// Creation of empty (null) shape GeomAPI_Shape(); diff --git a/src/GeomAPI/GeomAPI_ShapeExplorer.cpp b/src/GeomAPI/GeomAPI_ShapeExplorer.cpp new file mode 100644 index 000000000..3732d5afe --- /dev/null +++ b/src/GeomAPI/GeomAPI_ShapeExplorer.cpp @@ -0,0 +1,84 @@ +// Copyright (C) 2014-20xx CEA/DEN, EDF R&D + +// File: GeomAPI_ShapeExplorer.cpp +// Created: 5 June 2015 +// Author: Dmitry Bobylev + +#include + +#include +#include + +#define MY_EXPLORER static_cast(myImpl) + +//================================================================================================= +GeomAPI_ShapeExplorer::GeomAPI_ShapeExplorer() +: GeomAPI_Interface(new TopExp_Explorer()) +{ +} + +//================================================================================================= +GeomAPI_ShapeExplorer::GeomAPI_ShapeExplorer(const std::shared_ptr& theShape, + const GeomAPI_Shape::ShapeType toFind, + const GeomAPI_Shape::ShapeType toAvoid) +: GeomAPI_Interface(new TopExp_Explorer(theShape->impl(), + (TopAbs_ShapeEnum)toFind, + (TopAbs_ShapeEnum)toAvoid)) +{ +} + +//================================================================================================= +void GeomAPI_ShapeExplorer::init(const std::shared_ptr& theShape, + const GeomAPI_Shape::ShapeType toFind, + const GeomAPI_Shape::ShapeType toAvoid) +{ + MY_EXPLORER->Init(theShape->impl(), + (TopAbs_ShapeEnum)toFind, + (TopAbs_ShapeEnum)toAvoid); +} + +//================================================================================================= +bool GeomAPI_ShapeExplorer::more() const +{ + return MY_EXPLORER->More() == Standard_True; +} + +//================================================================================================= +void GeomAPI_ShapeExplorer::next() +{ + try { + MY_EXPLORER->Next(); + } catch (Standard_NoMoreObject) { + } +} + +//================================================================================================= +std::shared_ptr GeomAPI_ShapeExplorer::current() +{ + try { + const TopoDS_Shape& aShape = MY_EXPLORER->Current(); + std::shared_ptr aGeomShape(new GeomAPI_Shape()); + aGeomShape->setImpl(new TopoDS_Shape(aShape)); + return aGeomShape; + } catch (Standard_NoMoreObject) { + return std::shared_ptr(); + } +} + +//================================================================================================= +void GeomAPI_ShapeExplorer::reinit() +{ + MY_EXPLORER->ReInit(); +} + +//================================================================================================= +int GeomAPI_ShapeExplorer::depth() const +{ + return MY_EXPLORER->Depth(); +} + +//================================================================================================= +void GeomAPI_ShapeExplorer::clear() +{ + MY_EXPLORER->Clear(); +} diff --git a/src/GeomAPI/GeomAPI_ShapeExplorer.h b/src/GeomAPI/GeomAPI_ShapeExplorer.h new file mode 100644 index 000000000..f83d4c6f5 --- /dev/null +++ b/src/GeomAPI/GeomAPI_ShapeExplorer.h @@ -0,0 +1,64 @@ +// Copyright (C) 2014-20xx CEA/DEN, EDF R&D + +// File: GeomAPI_ShapeExplorer.h +// Created: 5 June 2015 +// Author: Dmitry Bobylev + +#ifndef GeomAPI_ShapeExplorer_H_ +#define GeomAPI_ShapeExplorer_H_ + +#include +#include + +/** \class GeomAPI_ShapeExplorer + * \ingroup DataModel + * \brief This class is used to explore subshapes on shape. + */ + +class GEOMAPI_EXPORT GeomAPI_ShapeExplorer : public GeomAPI_Interface +{ +public: + /// Default constructor. Creates an empty explorer, becomes usefull after Init. + GeomAPI_ShapeExplorer(); + + /** \brief Constructs an explorer to search on theShape, for shapes of type toFind, + * that are not part of a shape toAvoid. If the shape toAvoid is equal to GeomAPI_SHape::SHAPE, + * or if it is the same as, or less complex than the shape toFind it has no effect on the search. + \param[in] toFind shape type to find. + \param[in] toAvoid shape type to avoid. + */ + GeomAPI_ShapeExplorer(const std::shared_ptr& theShape, + const GeomAPI_Shape::ShapeType toFind, + const GeomAPI_Shape::ShapeType toAvoid = GeomAPI_Shape::SHAPE); + + /** \brief Resets this explorer. It is initialized to search on theShape, for shapes of type toFind, + * that are not part of a shape toAvoid. If the shape toAvoid is equal to GeomAPI_SHape::SHAPE, + * or if it is the same as, or less complex than the shape toFind it has no effect on the search. + \param[in] toFind shape type to find. + \param[in] toAvoid shape type to avoid. + */ + void init(const std::shared_ptr& theShape, + const GeomAPI_Shape::ShapeType toFind, + const GeomAPI_Shape::ShapeType toAvoid = GeomAPI_Shape::SHAPE); + + /// \return true if there are more shapes in the exploration. + bool more() const; + + /// Moves to the next Shape in the exploration or do nothing if there are no more shapes to explore. + void next(); + + /// Returns the current shape in the exploration or empty pointer if this explorer has no more shapes to explore. + std::shared_ptr current(); + + /// Reinitialize the exploration with the original arguments. + void reinit(); + + /// Returns the current depth of the exploration. 0 is the shape to explore itself. + int depth() const; + + /// Clears the content of the explorer. It will return False on more(). + void clear(); + +}; + +#endif \ No newline at end of file diff --git a/src/GeomAlgoAPI/GeomAlgoAPI.i b/src/GeomAlgoAPI/GeomAlgoAPI.i index f53434b4c..3778f6034 100644 --- a/src/GeomAlgoAPI/GeomAlgoAPI.i +++ b/src/GeomAlgoAPI/GeomAlgoAPI.i @@ -9,8 +9,11 @@ #include "GeomAlgoAPI_Extrusion.h" #include "GeomAlgoAPI_FaceBuilder.h" #include "GeomAlgoAPI_MakeShape.h" + #include "GeomAlgoAPI_MakeShapeList.h" #include "GeomAlgoAPI_PointBuilder.h" #include "GeomAlgoAPI_Prism.h" + #include "GeomAlgoAPI_Revolution.h" + #include "GeomAlgoAPI_Rotation.h" #include "GeomAlgoAPI_ShapeProps.h" #include "GeomAlgoAPI_SketchBuilder.h" @@ -36,8 +39,11 @@ %include "GeomAlgoAPI_Extrusion.h" %include "GeomAlgoAPI_FaceBuilder.h" %include "GeomAlgoAPI_MakeShape.h" +%include "GeomAlgoAPI_MakeShapeList.h" %include "GeomAlgoAPI_PointBuilder.h" %include "GeomAlgoAPI_Prism.h" +%include "GeomAlgoAPI_Revolution.h" +%include "GeomAlgoAPI_Rotation.h" %include "GeomAlgoAPI_ShapeProps.h" %include "GeomAlgoAPI_SketchBuilder.h" -- 2.39.2