From: azv Date: Fri, 6 Jun 2014 14:01:53 +0000 (+0400) Subject: Implemented extrusion for sketch X-Git-Tag: V_0.4.4~303^2^2^2~1 X-Git-Url: http://git.salome-platform.org/gitweb/?a=commitdiff_plain;h=4d0f8c49e8334bffe836ce17c518c6bd39c7a100;p=modules%2Fshaper.git Implemented extrusion for sketch --- diff --git a/src/ConstructionPlugin/ConstructionPlugin_Extrusion.cpp b/src/ConstructionPlugin/ConstructionPlugin_Extrusion.cpp index 8b5dc2d60..0af9cad3b 100644 --- a/src/ConstructionPlugin/ConstructionPlugin_Extrusion.cpp +++ b/src/ConstructionPlugin/ConstructionPlugin_Extrusion.cpp @@ -10,6 +10,8 @@ #include #include +#include + using namespace std; ConstructionPlugin_Extrusion::ConstructionPlugin_Extrusion() @@ -20,14 +22,24 @@ void ConstructionPlugin_Extrusion::initAttributes() { 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 -void ConstructionPlugin_Extrusion::execute() +void ConstructionPlugin_Extrusion::execute() { - // TODO: create a real shape for the point using OCC layer - //cout<<"X="<real(POINT_ATTR_X)->value()<<" Y="<real(POINT_ATTR_Y)->value() - // <<" Z="<real(POINT_ATTR_Z)->value()< aFaceRef = + boost::dynamic_pointer_cast(data()->attribute(EXTRUSION_FACE)); + if (!aFaceRef) + return; + FeaturePtr aFaceFeature = aFaceRef->value(); + if (!aFaceFeature) + return; + boost::shared_ptr 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)); } diff --git a/src/ConstructionPlugin/ConstructionPlugin_Extrusion.h b/src/ConstructionPlugin/ConstructionPlugin_Extrusion.h index 5270d2d89..5933929b8 100644 --- a/src/ConstructionPlugin/ConstructionPlugin_Extrusion.h +++ b/src/ConstructionPlugin/ConstructionPlugin_Extrusion.h @@ -18,7 +18,7 @@ const std::string EXTRUSION_FACE = "extrusion_face"; 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 diff --git a/src/GeomAlgoAPI/CMakeLists.txt b/src/GeomAlgoAPI/CMakeLists.txt index 5822d61fb..135d27470 100644 --- a/src/GeomAlgoAPI/CMakeLists.txt +++ b/src/GeomAlgoAPI/CMakeLists.txt @@ -10,6 +10,7 @@ SET(PROJECT_HEADERS GeomAlgoAPI_EdgeBuilder.h GeomAlgoAPI_PointBuilder.h GeomAlgoAPI_SketchBuilder.h + GeomAlgoAPI_Extrusion.h ) SET(PROJECT_SOURCES @@ -18,6 +19,7 @@ SET(PROJECT_SOURCES GeomAlgoAPI_EdgeBuilder.cpp GeomAlgoAPI_PointBuilder.cpp GeomAlgoAPI_SketchBuilder.cpp + GeomAlgoAPI_Extrusion.cpp ) ADD_DEFINITIONS(-DGEOMALGOAPI_EXPORTS ${CAS_DEFINITIONS}) @@ -33,7 +35,7 @@ INCLUDE_DIRECTORIES( ${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 diff --git a/src/GeomAlgoAPI/GeomAlgoAPI_Extrusion.cpp b/src/GeomAlgoAPI/GeomAlgoAPI_Extrusion.cpp new file mode 100644 index 000000000..d5affc094 --- /dev/null +++ b/src/GeomAlgoAPI/GeomAlgoAPI_Extrusion.cpp @@ -0,0 +1,68 @@ +// File: GeomAlgoAPI_Extrusion.cpp +// Created: 06 Jun 2014 +// Author: Artem ZHIDKOV + +#include + +#include + +#include +#include +#include +#include + +#include +const double tolerance = Precision::Angular(); + +boost::shared_ptr GeomAlgoAPI_Extrusion::makeExtrusion( + boost::shared_ptr theShape, + boost::shared_ptr theDir, + double theSize) +{ + const TopoDS_Shape& aShape = theShape->impl(); + gp_Vec aDir(theDir->impl().XYZ() * theSize); + + TopoDS_Shape aPrism = BRepPrimAPI_MakePrism(aShape, aDir); + if (aPrism.IsNull()) + return boost::shared_ptr(); + + boost::shared_ptr aResult(new GeomAPI_Shape()); + aResult->setImpl(new TopoDS_Shape(aPrism)); + return aResult; +} + +boost::shared_ptr GeomAlgoAPI_Extrusion::makeExtrusion( + boost::shared_ptr theShape, + double theSize) +{ + bool isFirstNorm = true; + gp_Dir aShapeNormal; + + const TopoDS_Shape& aShape = theShape->impl(); + 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(); + + 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(); + } + + boost::shared_ptr aDir( + new GeomAPI_Dir(aShapeNormal.X(), aShapeNormal.Y(), aShapeNormal.Z())); + + return GeomAlgoAPI_Extrusion::makeExtrusion(theShape, aDir, theSize); +} diff --git a/src/GeomAlgoAPI/GeomAlgoAPI_Extrusion.h b/src/GeomAlgoAPI/GeomAlgoAPI_Extrusion.h new file mode 100644 index 000000000..f2a098cea --- /dev/null +++ b/src/GeomAlgoAPI/GeomAlgoAPI_Extrusion.h @@ -0,0 +1,42 @@ +// File: GeomAlgoAPI_Extrusion.h +// Created: 06 Jun 2014 +// Author: Artem ZHIDKOV + +#ifndef GeomAlgoAPI_Extrusion_HeaderFile +#define GeomAlgoAPI_Extrusion_HeaderFile + +#include +#include +#include +#include + +/**\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 makeExtrusion( + boost::shared_ptr theShape, + boost::shared_ptr 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 makeExtrusion( + boost::shared_ptr theShape, + double theSize); +}; + +#endif diff --git a/src/GeomAlgoAPI/GeomAlgoAPI_SketchBuilder.cpp b/src/GeomAlgoAPI/GeomAlgoAPI_SketchBuilder.cpp index 01cc99bff..1828a7193 100644 --- a/src/GeomAlgoAPI/GeomAlgoAPI_SketchBuilder.cpp +++ b/src/GeomAlgoAPI/GeomAlgoAPI_SketchBuilder.cpp @@ -18,13 +18,13 @@ #include #include #include +#include #include #include #include #include #include #include -#include #include const double tolerance = Precision::Confusion(); @@ -298,37 +298,50 @@ void GeomAlgoAPI_SketchBuilder::createFaces( void GeomAlgoAPI_SketchBuilder::fixIntersections( std::list< boost::shared_ptr >& theFaces) { -//// TopOpeBRepTool_ShapeClassifier aClassifier; -//// const int aSameDomain = 1; -//// -//// std::list< boost::shared_ptr >::iterator anIter1 = theFaces.begin(); -//// std::list< boost::shared_ptr >::iterator anIter2; -//// for ( ; anIter1 != theFaces.end(); anIter1++) -//// { -//// anIter2 = anIter1; -//// for (++anIter2; anIter2 != theFaces.end(); anIter2++) -//// { -//// TopAbs_State aState = aClassifier.StateShapeShape( -//// (*anIter1)->impl(), (*anIter2)->impl(), aSameDomain); -//// if (aState == TopAbs_IN) -//// { // second shape should be cut from the first -//// BRepAlgoAPI_Cut aCut((*anIter1)->impl(), -//// (*anIter2)->impl()); -//// (*anIter1)->setImpl(new TopoDS_Shape(aCut.Shape())); -//// } -//// else if (aState != TopAbs_OUT) -//// { // change the shapes order and repeat -//// aState = aClassifier.StateShapeShape( -//// (*anIter2)->impl(), (*anIter1)->impl(), aSameDomain); -//// if (aState == TopAbs_IN) -//// { // first shape should be cut from the second -//// BRepAlgoAPI_Cut aCut((*anIter2)->impl(), -//// (*anIter1)->impl()); -//// (*anIter2)->setImpl(new TopoDS_Shape(aCut.Shape())); -//// } -//// } -//// } -//// } + BRepClass_FaceClassifier aClassifier; + + std::list< boost::shared_ptr >::iterator anIter1 = theFaces.begin(); + std::list< boost::shared_ptr >::iterator anIter2; + for ( ; anIter1 != theFaces.end(); anIter1++) + { + anIter2 = anIter1; + for (++anIter2; anIter2 != theFaces.end(); anIter2++) + { + const TopoDS_Face& aF1 = (*anIter1)->impl(); + TopExp_Explorer aVert2((*anIter2)->impl(), 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(); + TopExp_Explorer aVert1((*anIter1)->impl(), 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(), + (*anIter1)->impl()); + (*anIter2)->setImpl(new TopoDS_Shape(aCut.Shape())); + } + } + else + { // second shape should be cut from the first + BRepAlgoAPI_Cut aCut((*anIter1)->impl(), + (*anIter2)->impl()); + (*anIter1)->setImpl(new TopoDS_Shape(aCut.Shape())); + } + } + } } diff --git a/src/SketchPlugin/SketchPlugin_Sketch.cpp b/src/SketchPlugin/SketchPlugin_Sketch.cpp index bc9d72735..850058e8c 100644 --- a/src/SketchPlugin/SketchPlugin_Sketch.cpp +++ b/src/SketchPlugin/SketchPlugin_Sketch.cpp @@ -64,6 +64,10 @@ void SketchPlugin_Sketch::execute() std::list< boost::shared_ptr > aWires; GeomAlgoAPI_SketchBuilder::createFaces(aDirX->dir(), aDirY->dir(), aNorm->dir(), aFeaturesPreview, aLoops, aWires); + + aLoops.insert(aLoops.end(), aWires.begin(), aWires.end()); + boost::shared_ptr aCompound = GeomAlgoAPI_CompoundBuilder::compound(aLoops); + data()->store(aCompound); } const boost::shared_ptr& SketchPlugin_Sketch::preview()