From: szy Date: Mon, 27 Oct 2014 15:45:40 +0000 (+0300) Subject: 27.10.2014. Naming data structure for Extrusion feature. X-Git-Tag: V_0.5~69^2^2~4 X-Git-Url: http://git.salome-platform.org/gitweb/?a=commitdiff_plain;h=5f2ce61eb2866c9b2d119f0ad4c8301f765304ee;p=modules%2Fshaper.git 27.10.2014. Naming data structure for Extrusion feature. --- diff --git a/src/FeaturesPlugin/CMakeLists.txt b/src/FeaturesPlugin/CMakeLists.txt index 4d2b643d5..ab966dff6 100644 --- a/src/FeaturesPlugin/CMakeLists.txt +++ b/src/FeaturesPlugin/CMakeLists.txt @@ -26,9 +26,12 @@ INCLUDE_DIRECTORIES( ../ModelAPI ../GeomAPI ../GeomAlgoAPI + ../Events + ${CAS_INCLUDE_DIRS} ) SET(PROJECT_LIBRARIES + Events ModelAPI GeomAPI GeomAlgoAPI diff --git a/src/FeaturesPlugin/FeaturesPlugin_Extrusion.cpp b/src/FeaturesPlugin/FeaturesPlugin_Extrusion.cpp index 60ee2b689..737a563b3 100644 --- a/src/FeaturesPlugin/FeaturesPlugin_Extrusion.cpp +++ b/src/FeaturesPlugin/FeaturesPlugin_Extrusion.cpp @@ -11,11 +11,20 @@ #include #include #include - +#include #include - +#include +#include +#include +#include using namespace std; - +#define _LATERAL_TAG 1 +#define _FIRST_TAG 2 +#define _LAST_TAG 3 +#ifdef _DEBUG +#include +#include +#endif FeaturesPlugin_Extrusion::FeaturesPlugin_Extrusion() { } @@ -33,14 +42,110 @@ void FeaturesPlugin_Extrusion::execute() ModelAPI_AttributeSelection>(data()->attribute(FeaturesPlugin_Extrusion::FACE_ID())); if (!aFaceRef) return; + boost::shared_ptr aFace = boost::dynamic_pointer_cast(aFaceRef->value()); + boost::shared_ptr aContext = + boost::dynamic_pointer_cast(aFaceRef->context()); + double aSize = data()->real(FeaturesPlugin_Extrusion::SIZE_ID())->value(); if (data()->boolean(FeaturesPlugin_Extrusion::REVERSE_ID())->value()) aSize = -aSize; - boost::shared_ptr aResult = document()->createBody(data()); - aResult->store(GeomAlgoAPI_Extrusion::makeExtrusion(aFace, aSize)); - setResult(aResult); + boost::shared_ptr aResultBody = document()->createBody(data()); + //TCollection_AsciiString anError; + GeomAlgoAPI_Extrusion aFeature(aFace, aSize); + if(!aFeature.isDone()) { + std::string aFeatureError = "Extrusion algorithm failed"; + Events_Error::send(aFeatureError, this); + return; + } + + // Check if shape is valid + if (!aFeature.shape()->impl().IsNull()) { + std::string aShapeError = "Resulting shape is Null"; + Events_Error::send(aShapeError, this); + #ifdef _DEBUG + std::cerr << aShapeError << std::endl; + #endif + return; + } + if(!aFeature.isValid()) { + std::string aFeatureError = "Warning: resulting shape is not valid"; + Events_Error::send(aFeatureError, this); + return; + } + //LoadNamingDS + LoadNamingDS(aFeature, aResultBody, aFace, aContext); + + setResult(aResultBody); } + + //============================================================================ +void FeaturesPlugin_Extrusion::LoadNamingDS(GeomAlgoAPI_Extrusion& theFeature, + boost::shared_ptr theResultBody, + boost::shared_ptr theBasis, + boost::shared_ptr theContext) +{ + + + //load result + if(theBasis->impl().IsEqual(theContext->impl())) + theResultBody->store(theFeature.shape()); + else + theResultBody->storeGenerated(theContext, theFeature.shape()); + + TopTools_DataMapOfShapeShape aSubShapes; + for (TopExp_Explorer Exp(theFeature.shape()->impl(),TopAbs_FACE); Exp.More(); Exp.Next()) { + aSubShapes.Bind(Exp.Current(),Exp.Current()); + } + + //Insert lateral face : Face from Edge + //GeomAlgoAPI_DFLoader::loadAndOrientGeneratedShapes(*myBuilder, myBasis, TopAbs_EDGE, aLateralFaceBuilder, aSubShapes); + + + TopTools_MapOfShape aView; + TopExp_Explorer aShapeExplorer (theFeature.shape()->impl(), TopAbs_EDGE); + for (; aShapeExplorer.More(); aShapeExplorer.Next ()) { + const TopoDS_Shape& aRoot = aShapeExplorer.Current (); + if (!aView.Add(aRoot)) continue; + boost::shared_ptr aRootG(new GeomAPI_Shape()); + aRootG->setImpl((void *)&aRoot); + const ListOfShape& aShapes = theFeature.generated(aRootG); + std::list >::const_iterator anIt = aShapes.begin(), aLast = aShapes.end(); + for (; anIt != aLast; anIt++) { + TopoDS_Shape aNewShape = (*anIt)->impl(); + if (aSubShapes.IsBound(aNewShape)) { + aNewShape.Orientation((aSubShapes(aNewShape)).Orientation()); + } + + if (!aRoot.IsSame (aNewShape)) { + boost::shared_ptr aNew(new GeomAPI_Shape()); + aNew->setImpl((void *)&aNewShape); + theResultBody->generated(aRootG, aNew,_LATERAL_TAG); + } + } + } + + //Insert bottom face + const boost::shared_ptr& aBottomFace = theFeature.firstShape(); + if (!aBottomFace->impl().IsNull()) { + if (aSubShapes.IsBound(aBottomFace->impl())) { + aBottomFace->setImpl((void *)&aSubShapes(aBottomFace->impl())); + } + theResultBody->generated(aBottomFace, _FIRST_TAG); + } + + + + //Insert top face + boost::shared_ptr aTopFace = theFeature.lastShape(); + if (!aTopFace->impl().IsNull()) { + if (aSubShapes.IsBound(aTopFace->impl())) { + aTopFace->setImpl((void *)&aSubShapes(aTopFace->impl())); + } + theResultBody->generated(aTopFace, _FIRST_TAG); + } + +} \ No newline at end of file diff --git a/src/FeaturesPlugin/FeaturesPlugin_Extrusion.h b/src/FeaturesPlugin/FeaturesPlugin_Extrusion.h index 13a8c226e..d136c8491 100644 --- a/src/FeaturesPlugin/FeaturesPlugin_Extrusion.h +++ b/src/FeaturesPlugin/FeaturesPlugin_Extrusion.h @@ -7,7 +7,8 @@ #include "FeaturesPlugin.h" #include - +#include +#include class FeaturesPlugin_Extrusion : public ModelAPI_Feature { public: @@ -51,6 +52,11 @@ class FeaturesPlugin_Extrusion : public ModelAPI_Feature /// Use plugin manager for features creation FeaturesPlugin_Extrusion(); + + /// Load Naming data structure of the feature to the document + void LoadNamingDS(GeomAlgoAPI_Extrusion& theFeature, boost::shared_ptr theResultBody, + boost::shared_ptr theBasis, + boost::shared_ptr theContext); }; #endif diff --git a/src/GeomAPI/GeomAPI_Shape.h b/src/GeomAPI/GeomAPI_Shape.h index 3aa0987f7..acd39c6ec 100644 --- a/src/GeomAPI/GeomAPI_Shape.h +++ b/src/GeomAPI/GeomAPI_Shape.h @@ -7,6 +7,7 @@ #include #include +#include /**\class GeomAPI_Shape * \ingroup DataModel @@ -31,4 +32,5 @@ class GEOMAPI_EXPORT GeomAPI_Shape : public GeomAPI_Interface }; +typedef std::list> ListOfShape; #endif diff --git a/src/GeomAlgoAPI/CMakeLists.txt b/src/GeomAlgoAPI/CMakeLists.txt index 05e91eb61..5656a0ad8 100644 --- a/src/GeomAlgoAPI/CMakeLists.txt +++ b/src/GeomAlgoAPI/CMakeLists.txt @@ -12,6 +12,8 @@ SET(PROJECT_HEADERS GeomAlgoAPI_SketchBuilder.h GeomAlgoAPI_Extrusion.h GeomAlgoAPI_Boolean.h + GeomAlgoAPI_MakeShape.h + GeomAlgoAPI_DFLoader.h ) SET(PROJECT_SOURCES @@ -22,14 +24,18 @@ SET(PROJECT_SOURCES GeomAlgoAPI_SketchBuilder.cpp GeomAlgoAPI_Extrusion.cpp GeomAlgoAPI_Boolean.cpp + GeomAlgoAPI_MakeShape.cpp + GeomAlgoAPI_DFLoader.cpp ) SET(PROJECT_LIBRARIES - GeomAPI + GeomAPI + ModelAPI ${CAS_TKBool} ${CAS_TKBO} ${CAS_TKPrim} ${CAS_SHAPE} + ${CAS_TKTopAlgo} ) ADD_DEFINITIONS(-DGEOMALGOAPI_EXPORTS ${CAS_DEFINITIONS}) @@ -42,6 +48,7 @@ SET_SOURCE_FILES_PROPERTIES(GeomAlgoAPI.i PROPERTIES SWIG_DEFINITIONS "-shadow") INCLUDE_DIRECTORIES( ../GeomAPI + ../ModelAPI ${CAS_INCLUDE_DIRS} ) diff --git a/src/GeomAlgoAPI/GeomAlgoAPI_DFLoader.cpp b/src/GeomAlgoAPI/GeomAlgoAPI_DFLoader.cpp new file mode 100644 index 000000000..d309de4a2 --- /dev/null +++ b/src/GeomAlgoAPI/GeomAlgoAPI_DFLoader.cpp @@ -0,0 +1,103 @@ +// File: GeomAlgoAPI_DFLoader.cpp +// Created: 23 October 2014 +// Author: Sergey Zaritchny + +#include +#include +#include +#include +#include +//======================================================================= +//function : refineResult +//purpose : +//======================================================================= +const TopoDS_Shape GeomAlgoAPI_DFLoader::refineResult(const TopoDS_Shape& theResult) +{ + TopoDS_Shape aResult; + if (theResult.ShapeType() == TopAbs_COMPOUND) { + Standard_Integer nbSubResults = 0; + TopoDS_Iterator itr(theResult); + for (; itr.More(); itr.Next()) nbSubResults++; + if (nbSubResults == 1) { + itr.Initialize(theResult); + if (itr.More()) aResult = itr.Value(); + } + } + return aResult; +} +/* +//======================================================================= +//function : loadDeletedShapes +//purpose : load deleted shapes in DF +//======================================================================= +void GeomAlgoAPI_DFLoader::loadDeletedShapes (BRepBuilderAPI_MakeShape& theMS, + const TopoDS_Shape& theShapeIn, + const TopAbs_ShapeEnum theKindOfShape, + TNaming_Builder& theBuilder) +{ + TopTools_MapOfShape aView; + TopExp_Explorer ShapeExplorer (theShapeIn, theKindOfShape); + for (; ShapeExplorer.More(); ShapeExplorer.Next ()) { + const TopoDS_Shape& aRoot = ShapeExplorer.Current (); + if (!aView.Add(aRoot)) continue; + if (theMS.IsDeleted (aRoot)) { + theBuilder.Delete (aRoot); + } + } +} + +//======================================================================= +//function : loadAndOrientModifiedShapes +//purpose : load modified shapes in DF with preliminary orientation adjustment +//======================================================================= +void GeomAlgoAPI_DFLoader::loadAndOrientModifiedShapes (BRepBuilderAPI_MakeShape& theMS, + const TopoDS_Shape& theShapeIn, + const TopAbs_ShapeEnum theKindOfShape, + TNaming_Builder& theBuilder, + const TopTools_DataMapOfShapeShape& theSubShapes) +{ + TopTools_MapOfShape aView; + TopExp_Explorer aShapeExplorer (theShapeIn, theKindOfShape); + for (; aShapeExplorer.More(); aShapeExplorer.Next ()) { + const TopoDS_Shape& aRoot = aShapeExplorer.Current (); + if (!aView.Add(aRoot)) continue; + const TopTools_ListOfShape& aShapes = theMS.Modified (aRoot); + TopTools_ListIteratorOfListOfShape aShapesIterator (aShapes); + for (;aShapesIterator.More (); aShapesIterator.Next ()) { + TopoDS_Shape aNewShape = aShapesIterator.Value (); + if (theSubShapes.IsBound(aNewShape)) { + aNewShape.Orientation((theSubShapes(aNewShape)).Orientation()); + } + if (!aRoot.IsSame (aNewShape)) theBuilder.Modify (aRoot, aNewShape ); + } + } +} + +//======================================================================= +//function : loadAndOrientGeneratedShapes +//purpose : load generated shapes in DF with preliminary orientation adjustment +//======================================================================= + +void GeomAlgoAPI_DFLoader::loadAndOrientGeneratedShapes (BRepBuilderAPI_MakeShape& theMS, + const TopoDS_Shape& theShapeIn, + const TopAbs_ShapeEnum theKindOfShape, + TNaming_Builder& theBuilder, + const TopTools_DataMapOfShapeShape& theSubShapes) +{ + TopTools_MapOfShape aView; + TopExp_Explorer aShapeExplorer (theShapeIn, theKindOfShape); + for (; aShapeExplorer.More(); aShapeExplorer.Next ()) { + const TopoDS_Shape& aRoot = aShapeExplorer.Current (); + if (!aView.Add(aRoot)) continue; + const TopTools_ListOfShape& aShapes = theMS.Generated (aRoot); + TopTools_ListIteratorOfListOfShape aShapesIterator (aShapes); + for (;aShapesIterator.More (); aShapesIterator.Next ()) { + TopoDS_Shape aNewShape = aShapesIterator.Value (); + if (theSubShapes.IsBound(aNewShape)) { + aNewShape.Orientation((theSubShapes(aNewShape)).Orientation()); + } + if (!aRoot.IsSame (aNewShape)) theBuilder.Generated (aRoot,aNewShape ); + } + } +} +*/ \ No newline at end of file diff --git a/src/GeomAlgoAPI/GeomAlgoAPI_DFLoader.h b/src/GeomAlgoAPI/GeomAlgoAPI_DFLoader.h new file mode 100644 index 000000000..815b8cbee --- /dev/null +++ b/src/GeomAlgoAPI/GeomAlgoAPI_DFLoader.h @@ -0,0 +1,44 @@ +// File: GeomAlgoAPI_DFLoader.h +// Created: 23 October 2014 +// Author: Sergey Zaritchny + +#ifndef GeomAlgoAPI_DFLoader_H_ +#define GeomAlgoAPI_DFLoader_H_ +#include +//#include +#include +#include +#include +#include +#include + +/**\class GeomAlgoAPI_DFLoader + * \ingroup DataAlgo + * \brief Defines several static methods useful for Data Framework filling + */ +class GEOMALGOAPI_EXPORT GeomAlgoAPI_DFLoader +{ + public: + /* + /// Loads to DF deleted shapes + static void loadDeletedShapes (BRepBuilderAPI_MakeShape& theMS, const TopoDS_Shape& theShapeIn, + const TopAbs_ShapeEnum KindOfShape, TNaming_Builder& theBuilder); + + /// Loads to DF generated shapes + static void loadAndOrientGeneratedShapes (BRepBuilderAPI_MakeShape& theMS, + const TopoDS_Shape& theShapeIn, + const TopAbs_ShapeEnum theKindOfShape, + TNaming_Builder& theBuilder, + const TopTools_DataMapOfShapeShape& theSubShapes); + /// Loads to DF modified shapes + static void loadAndOrientModifiedShapes (BRepBuilderAPI_MakeShape& theMS, + const TopoDS_Shape& theShapeIn, + const TopAbs_ShapeEnum theKindOfShape, + TNaming_Builder& theBuilder, + const TopTools_DataMapOfShapeShape& theSubShapes); + */ + /// Refine result + static const TopoDS_Shape refineResult(const TopoDS_Shape& theShape); +}; + +#endif \ No newline at end of file diff --git a/src/GeomAlgoAPI/GeomAlgoAPI_Extrusion.cpp b/src/GeomAlgoAPI/GeomAlgoAPI_Extrusion.cpp index a236fc8bb..d5f2c4379 100644 --- a/src/GeomAlgoAPI/GeomAlgoAPI_Extrusion.cpp +++ b/src/GeomAlgoAPI/GeomAlgoAPI_Extrusion.cpp @@ -3,66 +3,190 @@ // Author: Artem ZHIDKOV #include - +#include +#include +#include #include - #include +#include #include #include #include -#include - +#include +#include +#include +#include +#include #include +#include +#include + const double tolerance = Precision::Angular(); + // Constructor +GeomAlgoAPI_Extrusion::GeomAlgoAPI_Extrusion (boost::shared_ptr theBasis, double theSize) + : mySize(theSize), myBuilder(NULL), myDone(false), myShape(new GeomAPI_Shape()) + { + myBasis = theBasis->impl(); + build(); + } -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); + //============================================================================ + void GeomAlgoAPI_Extrusion::build() + { + bool isFirstNorm = true; + gp_Dir aShapeNormal; - TopoDS_Shape aPrism = BRepPrimAPI_MakePrism(aShape, aDir); - if (aPrism.IsNull()) - return boost::shared_ptr(); + //const TopoDS_Shape& aShape = theShape->impl(); + Handle(Geom_Plane) aPlane = Handle(Geom_Plane)::DownCast(BRep_Tool::Surface(TopoDS::Face(myBasis))); + if (aPlane.IsNull()) // non-planar shapes is not supported for extrusion yet + return; - boost::shared_ptr aResult(new GeomAPI_Shape()); - aResult->setImpl(new TopoDS_Shape(aPrism)); - return aResult; -} + const gp_Dir& aNormal = aPlane->Pln().Axis().Direction(); + gp_Vec aVec(aNormal); + aVec = aVec * mySize; -boost::shared_ptr GeomAlgoAPI_Extrusion::makeExtrusion( - boost::shared_ptr theShape, double theSize) + myBuilder = new BRepPrimAPI_MakePrism(myBasis, aVec); + if(myBuilder != NULL) { + myDone = myBuilder->IsDone(); + if(myDone) { + if(myBuilder->Shape().ShapeType() == TopAbs_COMPOUND) + myResult = GeomAlgoAPI_DFLoader::refineResult(myBuilder->Shape()); + else + myResult = myBuilder->Shape(); + myShape->setImpl((void *)&myResult); + myFirst->setImpl((void *)&(myBuilder->FirstShape())); + myLast->setImpl((void *)&(myBuilder-> LastShape())); + } + } + } + + //============================================================================ +const bool GeomAlgoAPI_Extrusion::isDone() const +{return myDone;} + + //============================================================================ +const bool GeomAlgoAPI_Extrusion::isValid() const { - bool isFirstNorm = true; - gp_Dir aShapeNormal; - - const TopoDS_Shape& aShape = theShape->impl(); - TopExp_Explorer aFaceExp(aShape, TopAbs_FACE); - TopoDS_Compound aFaces; // use only faces from the shape: make compound for this - BRep_Builder aBuilder; - aBuilder.MakeCompound(aFaces); - for (; aFaceExp.More(); aFaceExp.Next()) { - const TopoDS_Face& aFace = (const TopoDS_Face&) aFaceExp.Current(); - Handle(Geom_Plane) aPlane = Handle(Geom_Plane)::DownCast(BRep_Tool::Surface(aFace)); - 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(); - aBuilder.Add(aFaces, aFace); + bool isValid(false); + if(myDone && !myBuilder->Shape().IsNull()) { + BRepCheck_Analyzer aChecker(myBuilder->Shape()); + isValid = aChecker.IsValid(); + } + return isValid; + } + + //============================================================================ + const bool GeomAlgoAPI_Extrusion::hasVolume() const + { + bool hasVolume(false); + if(isValid()) { + const TopoDS_Shape& aRShape = myBuilder->Shape(); + GProp_GProps aGProp; + BRepGProp::VolumeProperties(aRShape, aGProp); + if(aGProp.Mass() > Precision::Confusion()) + hasVolume = true; + } + return hasVolume; } - if (aFaces.IsNull()) - return boost::shared_ptr(); - boost::shared_ptr aDir( - new GeomAPI_Dir(aShapeNormal.X(), aShapeNormal.Y(), aShapeNormal.Z())); + //============================================================================ +const boost::shared_ptr& GeomAlgoAPI_Extrusion::shape () const +{return myShape;} - boost::shared_ptr aFacesShape(new (GeomAPI_Shape)); - aFacesShape->setImpl(new TopoDS_Shape(aFaces)); - return GeomAlgoAPI_Extrusion::makeExtrusion(aFacesShape, aDir, theSize); -} + //============================================================================ + const ListOfShape& GeomAlgoAPI_Extrusion::generated(const boost::shared_ptr theShape) + { + myHistory.clear(); + if(myDone) { + const TopTools_ListOfShape& aList = myBuilder->Generated(theShape->impl()); + TopTools_ListIteratorOfListOfShape it(aList); + for(;it.More();it.Next()) { + boost::shared_ptr aShape(new GeomAPI_Shape()); + aShape->setImpl(&(it.Value())); + myHistory.push_back(aShape); + } + } + return myHistory; + } + + //============================================================================ + const boost::shared_ptr& GeomAlgoAPI_Extrusion::firstShape() + { + return myFirst; + } + + //============================================================================ + const boost::shared_ptr& GeomAlgoAPI_Extrusion::lastShape() + { + return myLast; + } + + //============================================================================ + /* + void GeomAlgoAPI_Extrusion::LoadNamingDS(boost::shared_ptr theResultBody, + boost::shared_ptr theContext) +{ + if(isValid()) { + const TopoDS_Shape& aShape = myBuilder->Shape(); + TopoDS_Shape aResult = GeomAlgoAPI_DFLoader::refineResult(aShape); + boost::shared_ptr aData = boost::dynamic_pointer_cast(theResultBody->data()); + if (aData) { + const TDF_Label& aShapeLab = aData->shapeLab(); + const Handle(TDF_TagSource)& Tagger = TDF_TagSource::Set(aShapeLab); + if (Tagger.IsNull()) return; + Tagger->Set(0); + + TNaming_Builder aBuilder (aShapeLab); + if(myBasis.IsEqual(theContext->impl())) + aBuilder.Generated(aResult); + else + aBuilder.Generated(theContext->impl(), aResult); + + TopTools_DataMapOfShapeShape aSubShapes; + for (TopExp_Explorer Exp(aResult,TopAbs_FACE); Exp.More(); Exp.Next()) { + aSubShapes.Bind(Exp.Current(),Exp.Current()); + } + + //Insert lateral face : Face from Edge + TNaming_Builder aLateralFaceBuilder(aShapeLab.NewChild()); + GeomAlgoAPI_DFLoader::loadAndOrientGeneratedShapes(*myBuilder, myBasis, TopAbs_EDGE, aLateralFaceBuilder, aSubShapes); + + //Insert bottom face + TopoDS_Shape aBottomFace = myBuilder->FirstShape(); + if (!aBottomFace.IsNull()) { + if (aBottomFace.ShapeType() != TopAbs_COMPOUND) { + TNaming_Builder aBottomBuilder(aShapeLab.NewChild()); //2 + if (aSubShapes.IsBound(aBottomFace)) { + aBottomFace = aSubShapes(aBottomFace); + } + aBottomBuilder.Generated(aBottomFace); + } else { + TopoDS_Iterator itr(aBottomFace); + for (; itr.More(); itr.Next()) { + TNaming_Builder aBottomBuilder(aShapeLab.NewChild()); + aBottomBuilder.Generated(itr.Value()); + } + } + + } + + //Insert top face + TopoDS_Shape aTopFace = myBuilder->LastShape(); + if (!aTopFace.IsNull()) { + if (aTopFace.ShapeType() != TopAbs_COMPOUND) { + TNaming_Builder aTopBuilder(aShapeLab.NewChild()); //3 + if (aSubShapes.IsBound(aTopFace)) { + aTopFace = aSubShapes(aTopFace); + } + aTopBuilder.Generated(aTopFace); + } else { + TopoDS_Iterator itr(aTopFace); + for (; itr.More(); itr.Next()) { + TNaming_Builder aTopBuilder(aShapeLab.NewChild()); + aTopBuilder.Generated(itr.Value()); + } + } + } + } + } + */ \ No newline at end of file diff --git a/src/GeomAlgoAPI/GeomAlgoAPI_Extrusion.h b/src/GeomAlgoAPI/GeomAlgoAPI_Extrusion.h index 31b3d4406..03d704d5d 100644 --- a/src/GeomAlgoAPI/GeomAlgoAPI_Extrusion.h +++ b/src/GeomAlgoAPI/GeomAlgoAPI_Extrusion.h @@ -1,6 +1,6 @@ // File: GeomAlgoAPI_Extrusion.h -// Created: 06 Jun 2014 -// Author: Artem ZHIDKOV +// Created: 22 October 2014 +// Author: Sergey Zaritchny #ifndef GeomAlgoAPI_Extrusion_H_ #define GeomAlgoAPI_Extrusion_H_ @@ -8,33 +8,65 @@ #include #include #include +#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 +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); + + static boost::shared_ptr makeExtrusion(boost::shared_ptr theResult, + boost::shared_ptr theBasis, + boost::shared_ptr theContext, + double theSize); */ + /// Constructor + GeomAlgoAPI_Extrusion (boost::shared_ptr theBasis, double theSize); + + /// Returns True if algorithm succeed + const bool isDone() const; + + /// Returns True if resulting shape is valid + const bool isValid() const; + + /// Returns True if resulting shape has volume + const bool hasVolume() const; + + /// Returns result of the Extrusion algorithm which may be a Solid or a Face + const boost::shared_ptr& shape () const; + + /// Returns list of shapes generated from theShape + const ListOfShape& generated(const boost::shared_ptr theShape); + + /// Returns the first shape + const boost::shared_ptr& firstShape(); + + /// returns last shape + const boost::shared_ptr& lastShape(); + +private: + /// builds resulting shape + void build(); + + BRepPrimAPI_MakePrism * myBuilder; + TopoDS_Shape myBasis; + double mySize; + bool myDone; + TopoDS_Shape myResult; + ListOfShape myHistory; + boost::shared_ptr myShape; + boost::shared_ptr myFirst; + boost::shared_ptr myLast; }; #endif diff --git a/src/GeomAlgoAPI/GeomAlgoAPI_MakeShape.cpp b/src/GeomAlgoAPI/GeomAlgoAPI_MakeShape.cpp new file mode 100644 index 000000000..d743b567a --- /dev/null +++ b/src/GeomAlgoAPI/GeomAlgoAPI_MakeShape.cpp @@ -0,0 +1,58 @@ +// File: GeomAlgoAPI_MakeShape.cpp +// Created: 20 Oct 2014 +// Author: Sergey ZARITCHNY + +#include +#include +#include +GeomAlgoAPI_MakeShape::GeomAlgoAPI_MakeShape(BRepBuilderAPI_MakeShape * theMkShape) +{ myBuilder = theMkShape;} + +const boost::shared_ptr GeomAlgoAPI_MakeShape::shape() const +{ + boost::shared_ptr aShape(new GeomAPI_Shape()); + if(myBuilder != NULL) + aShape->setImpl(new TopoDS_Shape(myBuilder->Shape())); + return aShape; +} + + /// Returns the list of shapes generated from the shape +const ListOfShape& GeomAlgoAPI_MakeShape::generated(const boost::shared_ptr theShape) +{ + myHistory.clear(); + if(myBuilder != NULL) { + const TopTools_ListOfShape& aList = myBuilder->Generated(theShape->impl()); + TopTools_ListIteratorOfListOfShape it(aList); + for(;it.More();it.Next()) { + boost::shared_ptr aShape(new GeomAPI_Shape()); + aShape->setImpl(&(it.Value())); + myHistory.push_back(aShape); + } + } + return myHistory; +} + + /// Returns the list of shapes modified from the shape +const ListOfShape& GeomAlgoAPI_MakeShape::modified(const boost::shared_ptr theShape) +{ + myHistory.clear(); + if(myBuilder != NULL) { + const TopTools_ListOfShape& aList = myBuilder->Modified(theShape->impl()); + TopTools_ListIteratorOfListOfShape it(aList); + for(;it.More();it.Next()) { + boost::shared_ptr aShape(new GeomAPI_Shape()); + aShape->setImpl(&(it.Value())); + myHistory.push_back(aShape); + } + } + return myHistory; +} + + /// Returns whether the shape is an edge +bool GeomAlgoAPI_MakeShape::isDeleted(const boost::shared_ptr theShape) +{ + bool isDeleted(false); + if (myBuilder != NULL) + isDeleted = (bool) myBuilder->IsDeleted(theShape->impl()); + return isDeleted; +} \ No newline at end of file diff --git a/src/GeomAlgoAPI/GeomAlgoAPI_MakeShape.h b/src/GeomAlgoAPI/GeomAlgoAPI_MakeShape.h new file mode 100644 index 000000000..9357ff432 --- /dev/null +++ b/src/GeomAlgoAPI/GeomAlgoAPI_MakeShape.h @@ -0,0 +1,38 @@ +// File: GeomAlgoAPI_MakeShape.h +// Created: 17 Oct 2014 +// Author: Sergey ZARITCHNY +#ifndef GeomAlgoAPI_MakeShape_H_ +#define GeomAlgoAPI_MakeShape_H_ + +#include +#include +#include +#include +/**\class GeomAlgoAPI_MakeShape + * \ingroup DataModel + * \Interface to the root class of all topological shapes constructions + */ +class GEOMALGOAPI_EXPORT GeomAlgoAPI_MakeShape +{ + public: + /// Constructor + GeomAlgoAPI_MakeShape(BRepBuilderAPI_MakeShape * theBuilder); + /// Returns a shape built by the shape construction algorithm + const boost::shared_ptr shape() const; + + /// Returns the list of shapes generated from the shape + virtual const ListOfShape& generated(const boost::shared_ptr theShape); + + /// Returns the list of shapes modified from the shape + virtual const ListOfShape& modified(const boost::shared_ptr theShape); + + /// Returns whether the shape is an edge + virtual bool isDeleted(const boost::shared_ptr theShape); + + protected: + boost::shared_ptr myShape; + ListOfShape myHistory; + BRepBuilderAPI_MakeShape * myBuilder; +}; + +#endif \ No newline at end of file diff --git a/src/Model/Model_ResultBody.cpp b/src/Model/Model_ResultBody.cpp index f5c8cb223..090de2d9e 100644 --- a/src/Model/Model_ResultBody.cpp +++ b/src/Model/Model_ResultBody.cpp @@ -19,12 +19,8 @@ void Model_ResultBody::store(const boost::shared_ptr& theShape) boost::shared_ptr aData = boost::dynamic_pointer_cast(data()); if (aData) { TDF_Label& aShapeLab = aData->shapeLab(); - // remove the previous history - clean(); - aShapeLab.ForgetAttribute(TNaming_NamedShape::GetID()); - for(TDF_ChildIterator anIter(aShapeLab); anIter.More(); anIter.Next()) { - anIter.Value().ForgetAllAttributes(); - } + // clean builders + clean(); // store the new shape as primitive TNaming_Builder aBuilder(aShapeLab); if (!theShape) @@ -37,6 +33,50 @@ void Model_ResultBody::store(const boost::shared_ptr& theShape) } } +void Model_ResultBody::storeGenerated(const boost::shared_ptr& theFromShape, + const boost::shared_ptr& theToShape) +{ + boost::shared_ptr aData = boost::dynamic_pointer_cast(data()); + if (aData) { + TDF_Label& aShapeLab = aData->shapeLab(); + // clean builders + clean(); + // store the new shape as primitive + TNaming_Builder aBuilder(aShapeLab); + if (!theFromShape || !theToShape) + return; // bad shape + TopoDS_Shape aShapeBasis = theFromShape->impl(); + if (aShapeBasis.IsNull()) + return; // null shape inside + TopoDS_Shape aShapeNew = theToShape->impl(); + if (aShapeNew.IsNull()) + return; // null shape inside + aBuilder.Generated(aShapeBasis, aShapeNew); + } +} + +void Model_ResultBody::storeModified(const boost::shared_ptr& theOldShape, + const boost::shared_ptr& theNewShape) +{ + boost::shared_ptr aData = boost::dynamic_pointer_cast(data()); + if (aData) { + TDF_Label& aShapeLab = aData->shapeLab(); + // clean builders + clean(); + // store the new shape as primitive + TNaming_Builder aBuilder(aShapeLab); + if (!theOldShape || !theNewShape) + return; // bad shape + TopoDS_Shape aShapeOld = theOldShape->impl(); + if (aShapeOld.IsNull()) + return; // null shape inside + TopoDS_Shape aShapeNew = theNewShape->impl(); + if (aShapeNew.IsNull()) + return; // null shape inside + aBuilder.Generated(aShapeOld, aShapeNew); + } +} + boost::shared_ptr Model_ResultBody::shape() { boost::shared_ptr aData = boost::dynamic_pointer_cast(data()); diff --git a/src/Model/Model_ResultBody.h b/src/Model/Model_ResultBody.h index c4ffbea31..f6174cdee 100644 --- a/src/Model/Model_ResultBody.h +++ b/src/Model/Model_ResultBody.h @@ -28,6 +28,15 @@ class Model_ResultBody : public ModelAPI_ResultBody public: /// Stores the shape (called by the execution method). MODEL_EXPORT virtual void store(const boost::shared_ptr& theShape); + + /// Stores the generated shape (called by the execution method). + MODEL_EXPORT virtual void storeGenerated(const boost::shared_ptr& theFromShape, + const boost::shared_ptr& theToShape); + + /// Stores the modified shape (called by the execution method). + MODEL_EXPORT virtual void storeModified(const boost::shared_ptr& theOldShape, + const boost::shared_ptr& theNewShape); + /// Returns the shape-result produced by this feature MODEL_EXPORT virtual boost::shared_ptr shape(); /// Returns the source feature of this result diff --git a/src/ModelAPI/ModelAPI_ResultBody.h b/src/ModelAPI/ModelAPI_ResultBody.h index bcd45b354..361547441 100644 --- a/src/ModelAPI/ModelAPI_ResultBody.h +++ b/src/ModelAPI/ModelAPI_ResultBody.h @@ -36,6 +36,15 @@ public: /// Stores the shape (called by the execution method). virtual void store(const boost::shared_ptr& theShape) = 0; + + /// Stores the generated shape (called by the execution method). + virtual void storeGenerated(const boost::shared_ptr& theFromShape, + const boost::shared_ptr& theToShape) = 0; + + /// Stores the modified shape (called by the execution method). + virtual void storeModified(const boost::shared_ptr& theOldShape, + const boost::shared_ptr& theNewShape) = 0; + /// Returns the shape-result produced by this feature virtual boost::shared_ptr shape() = 0;