#include <ModelAPI_AttributeReference.h>
#include <ModelAPI_AttributeBoolean.h>
+#include <GeomAlgoAPI_Extrusion.h>
+
using namespace std;
ConstructionPlugin_Extrusion::ConstructionPlugin_Extrusion()
{
data()->addAttribute(EXTRUSION_FACE, ModelAPI_AttributeReference::type());
data()->addAttribute(EXTRUSION_SIZE, ModelAPI_AttributeDouble::type());
- data()->addAttribute(EXTRUSION_REVERCE, ModelAPI_AttributeBoolean::type());
+ data()->addAttribute(EXTRUSION_REVERSE, ModelAPI_AttributeBoolean::type());
}
-// this is for debug only
-#include <iostream>
-void ConstructionPlugin_Extrusion::execute()
+void ConstructionPlugin_Extrusion::execute()
{
- // TODO: create a real shape for the point using OCC layer
- //cout<<"X="<<data()->real(POINT_ATTR_X)->value()<<" Y="<<data()->real(POINT_ATTR_Y)->value()
- // <<" Z="<<data()->real(POINT_ATTR_Z)->value()<<endl;
+ boost::shared_ptr<ModelAPI_AttributeReference> aFaceRef =
+ boost::dynamic_pointer_cast<ModelAPI_AttributeReference>(data()->attribute(EXTRUSION_FACE));
+ if (!aFaceRef)
+ return;
+ FeaturePtr aFaceFeature = aFaceRef->value();
+ if (!aFaceFeature)
+ return;
+ boost::shared_ptr<GeomAPI_Shape> aFace = aFaceFeature->data()->shape();
+ if (!aFace)
+ return;
+
+ double aSize = data()->real(EXTRUSION_SIZE)->value();
+ if (data()->boolean(EXTRUSION_REVERSE)->value())
+ aSize = -aSize;
+ data()->store(GeomAlgoAPI_Extrusion::makeExtrusion(aFace, aSize));
}
const std::string EXTRUSION_SIZE = "extrusion_size";
/// attribute name of reverce direction
-const std::string EXTRUSION_REVERCE = "extrusion_reverse";
+const std::string EXTRUSION_REVERSE = "extrusion_reverse";
class ConstructionPlugin_Extrusion: public ModelAPI_Feature
GeomAlgoAPI_EdgeBuilder.h
GeomAlgoAPI_PointBuilder.h
GeomAlgoAPI_SketchBuilder.h
+ GeomAlgoAPI_Extrusion.h
)
SET(PROJECT_SOURCES
GeomAlgoAPI_EdgeBuilder.cpp
GeomAlgoAPI_PointBuilder.cpp
GeomAlgoAPI_SketchBuilder.cpp
+ GeomAlgoAPI_Extrusion.cpp
)
ADD_DEFINITIONS(-DGEOMALGOAPI_EXPORTS ${CAS_DEFINITIONS})
${CAS_INCLUDE_DIRS}
)
-TARGET_LINK_LIBRARIES(GeomAlgoAPI ${PROJECT_LIBRARIES} GeomAPI ${CAS_TKBool} ${CAS_TKBO})
+TARGET_LINK_LIBRARIES(GeomAlgoAPI ${PROJECT_LIBRARIES} GeomAPI ${CAS_TKBool} ${CAS_TKBO} ${CAS_TKPrim})
SET(SWIG_SCRIPTS
${CMAKE_CURRENT_BINARY_DIR}/GeomAlgoAPI.py
--- /dev/null
+// File: GeomAlgoAPI_Extrusion.cpp
+// Created: 06 Jun 2014
+// Author: Artem ZHIDKOV
+
+#include <GeomAlgoAPI_Extrusion.h>
+
+#include <gp_Pln.hxx>
+
+#include <BRepPrimAPI_MakePrism.hxx>
+#include <Geom_Plane.hxx>
+#include <Geom_Surface.hxx>
+#include <TopExp_Explorer.hxx>
+
+#include <Precision.hxx>
+const double tolerance = Precision::Angular();
+
+boost::shared_ptr<GeomAPI_Shape> GeomAlgoAPI_Extrusion::makeExtrusion(
+ boost::shared_ptr<GeomAPI_Shape> theShape,
+ boost::shared_ptr<GeomAPI_Dir> theDir,
+ double theSize)
+{
+ const TopoDS_Shape& aShape = theShape->impl<TopoDS_Shape>();
+ gp_Vec aDir(theDir->impl<gp_Dir>().XYZ() * theSize);
+
+ TopoDS_Shape aPrism = BRepPrimAPI_MakePrism(aShape, aDir);
+ if (aPrism.IsNull())
+ return boost::shared_ptr<GeomAPI_Shape>();
+
+ boost::shared_ptr<GeomAPI_Shape> aResult(new GeomAPI_Shape());
+ aResult->setImpl(new TopoDS_Shape(aPrism));
+ return aResult;
+}
+
+boost::shared_ptr<GeomAPI_Shape> GeomAlgoAPI_Extrusion::makeExtrusion(
+ boost::shared_ptr<GeomAPI_Shape> theShape,
+ double theSize)
+{
+ bool isFirstNorm = true;
+ gp_Dir aShapeNormal;
+
+ const TopoDS_Shape& aShape = theShape->impl<TopoDS_Shape>();
+ TopExp_Explorer aFaceExp(aShape, TopAbs_FACE);
+ for ( ; aFaceExp.More(); aFaceExp.Next())
+ {
+ const TopoDS_Face& aFace = (const TopoDS_Face&)aFaceExp.Current();
+ Handle(BRep_TFace) aBFace = Handle(BRep_TFace)::DownCast(aFace.TShape());
+ if (aBFace.IsNull())
+ return boost::shared_ptr<GeomAPI_Shape>();
+
+ Handle(Geom_Plane) aPlane = Handle(Geom_Plane)::DownCast(aBFace->Surface());
+ if (aPlane.IsNull()) // non-planar shapes is not supported for extrusion yet
+ continue;
+
+ const gp_Dir& aNormal = aPlane->Pln().Axis().Direction();
+ if (isFirstNorm)
+ {
+ aShapeNormal = aNormal;
+ isFirstNorm = false;
+ }
+ else if (!aShapeNormal.IsEqual(aNormal, tolerance)) // non-planar shapes is not supported for extrusion yet
+ return boost::shared_ptr<GeomAPI_Shape>();
+ }
+
+ boost::shared_ptr<GeomAPI_Dir> aDir(
+ new GeomAPI_Dir(aShapeNormal.X(), aShapeNormal.Y(), aShapeNormal.Z()));
+
+ return GeomAlgoAPI_Extrusion::makeExtrusion(theShape, aDir, theSize);
+}
--- /dev/null
+// File: GeomAlgoAPI_Extrusion.h
+// Created: 06 Jun 2014
+// Author: Artem ZHIDKOV
+
+#ifndef GeomAlgoAPI_Extrusion_HeaderFile
+#define GeomAlgoAPI_Extrusion_HeaderFile
+
+#include <GeomAlgoAPI.h>
+#include <GeomAPI_Shape.h>
+#include <GeomAPI_Dir.h>
+#include <boost/shared_ptr.hpp>
+
+/**\class GeomAlgoAPI_Extrusion
+ * \ingroup DataAlgo
+ * \brief Allows to create the prism based on a given face and a direction
+ */
+
+class GEOMALGOAPI_EXPORT GeomAlgoAPI_Extrusion
+{
+public:
+ /* \brief Creates extrusion for the given shape
+ * \param[in] theShape face or wire to be extruded
+ * \param[in] theDir direction of extrusion
+ * \param[in] theSize the length of extrusion (if the value is less than 0, the extrusion in opposite direction)
+ * \return a solid or a face which is obtained from specified one
+ */
+ static boost::shared_ptr<GeomAPI_Shape> makeExtrusion(
+ boost::shared_ptr<GeomAPI_Shape> theShape,
+ boost::shared_ptr<GeomAPI_Dir> theDir,
+ double theSize);
+
+ /* \brief Creates extrusion for the given shape along the normal for this shape
+ * \param[in] theShape face or wire to be extruded
+ * \param[in] theSize the length of extrusion (if the value is less than 0, the extrusion in opposite normal)
+ * \return a solid or a face which is obtained from specified one
+ */
+ static boost::shared_ptr<GeomAPI_Shape> makeExtrusion(
+ boost::shared_ptr<GeomAPI_Shape> theShape,
+ double theSize);
+};
+
+#endif
#include <BRep_TVertex.hxx>
#include <BRepAlgoAPI_Cut.hxx>
#include <BRepBuilderAPI_MakeFace.hxx>
+#include <BRepClass_FaceClassifier.hxx>
#include <Geom_Curve.hxx>
#include <TopExp_Explorer.hxx>
#include <TopoDS_Edge.hxx>
#include <TopoDS_Face.hxx>
#include <TopoDS_Vertex.hxx>
#include <TopoDS_Wire.hxx>
-#include <TopOpeBRepTool_ShapeClassifier.hxx>
#include <Precision.hxx>
const double tolerance = Precision::Confusion();
void GeomAlgoAPI_SketchBuilder::fixIntersections(
std::list< boost::shared_ptr<GeomAPI_Shape> >& theFaces)
{
-//// TopOpeBRepTool_ShapeClassifier aClassifier;
-//// const int aSameDomain = 1;
-////
-//// std::list< boost::shared_ptr<GeomAPI_Shape> >::iterator anIter1 = theFaces.begin();
-//// std::list< boost::shared_ptr<GeomAPI_Shape> >::iterator anIter2;
-//// for ( ; anIter1 != theFaces.end(); anIter1++)
-//// {
-//// anIter2 = anIter1;
-//// for (++anIter2; anIter2 != theFaces.end(); anIter2++)
-//// {
-//// TopAbs_State aState = aClassifier.StateShapeShape(
-//// (*anIter1)->impl<TopoDS_Shape>(), (*anIter2)->impl<TopoDS_Shape>(), aSameDomain);
-//// if (aState == TopAbs_IN)
-//// { // second shape should be cut from the first
-//// BRepAlgoAPI_Cut aCut((*anIter1)->impl<TopoDS_Shape>(),
-//// (*anIter2)->impl<TopoDS_Shape>());
-//// (*anIter1)->setImpl(new TopoDS_Shape(aCut.Shape()));
-//// }
-//// else if (aState != TopAbs_OUT)
-//// { // change the shapes order and repeat
-//// aState = aClassifier.StateShapeShape(
-//// (*anIter2)->impl<TopoDS_Shape>(), (*anIter1)->impl<TopoDS_Shape>(), aSameDomain);
-//// if (aState == TopAbs_IN)
-//// { // first shape should be cut from the second
-//// BRepAlgoAPI_Cut aCut((*anIter2)->impl<TopoDS_Shape>(),
-//// (*anIter1)->impl<TopoDS_Shape>());
-//// (*anIter2)->setImpl(new TopoDS_Shape(aCut.Shape()));
-//// }
-//// }
-//// }
-//// }
+ BRepClass_FaceClassifier aClassifier;
+
+ std::list< boost::shared_ptr<GeomAPI_Shape> >::iterator anIter1 = theFaces.begin();
+ std::list< boost::shared_ptr<GeomAPI_Shape> >::iterator anIter2;
+ for ( ; anIter1 != theFaces.end(); anIter1++)
+ {
+ anIter2 = anIter1;
+ for (++anIter2; anIter2 != theFaces.end(); anIter2++)
+ {
+ const TopoDS_Face& aF1 = (*anIter1)->impl<TopoDS_Face>();
+ TopExp_Explorer aVert2((*anIter2)->impl<TopoDS_Shape>(), TopAbs_VERTEX);
+ for ( ; aVert2.More(); aVert2.Next())
+ {
+ Handle(BRep_TVertex) aV = Handle(BRep_TVertex)::DownCast(aVert2.Current().TShape());
+ aClassifier.Perform(aF1, aV->Pnt(), tolerance);
+ if (aClassifier.State() != TopAbs_IN)
+ break;
+ }
+ if (aVert2.More())
+ { // second shape is not inside first, change the shapes order and repeat comparision
+ const TopoDS_Face& aF2 = (*anIter2)->impl<TopoDS_Face>();
+ TopExp_Explorer aVert1((*anIter1)->impl<TopoDS_Shape>(), TopAbs_VERTEX);
+ for ( ; aVert1.More(); aVert1.Next())
+ {
+ Handle(BRep_TVertex) aV = Handle(BRep_TVertex)::DownCast(aVert1.Current().TShape());
+ aClassifier.Perform(aF2, aV->Pnt(), tolerance);
+ if (aClassifier.State() != TopAbs_IN)
+ break;
+ }
+ if (!aVert1.More())
+ { // first shape should be cut from the second
+ BRepAlgoAPI_Cut aCut((*anIter2)->impl<TopoDS_Shape>(),
+ (*anIter1)->impl<TopoDS_Shape>());
+ (*anIter2)->setImpl(new TopoDS_Shape(aCut.Shape()));
+ }
+ }
+ else
+ { // second shape should be cut from the first
+ BRepAlgoAPI_Cut aCut((*anIter1)->impl<TopoDS_Shape>(),
+ (*anIter2)->impl<TopoDS_Shape>());
+ (*anIter1)->setImpl(new TopoDS_Shape(aCut.Shape()));
+ }
+ }
+ }
}
std::list< boost::shared_ptr<GeomAPI_Shape> > aWires;
GeomAlgoAPI_SketchBuilder::createFaces(aDirX->dir(), aDirY->dir(), aNorm->dir(),
aFeaturesPreview, aLoops, aWires);
+
+ aLoops.insert(aLoops.end(), aWires.begin(), aWires.end());
+ boost::shared_ptr<GeomAPI_Shape> aCompound = GeomAlgoAPI_CompoundBuilder::compound(aLoops);
+ data()->store(aCompound);
}
const boost::shared_ptr<GeomAPI_Shape>& SketchPlugin_Sketch::preview()