From: dbv Date: Thu, 13 Aug 2015 06:13:17 +0000 (+0300) Subject: Compsolid creation in extrusion X-Git-Tag: V_1.4.0_beta4~389 X-Git-Url: http://git.salome-platform.org/gitweb/?a=commitdiff_plain;h=65bd7c71b6eda2cad73adcc3be6c6ad725c26b94;p=modules%2Fshaper.git Compsolid creation in extrusion --- diff --git a/src/FeaturesPlugin/FeaturesPlugin_Boolean.cpp b/src/FeaturesPlugin/FeaturesPlugin_Boolean.cpp index 7f414c613..6393cd42b 100644 --- a/src/FeaturesPlugin/FeaturesPlugin_Boolean.cpp +++ b/src/FeaturesPlugin/FeaturesPlugin_Boolean.cpp @@ -18,7 +18,7 @@ #include #include -#include +#include #define FACE 4 #define _MODIFY_TAG 1 @@ -133,7 +133,7 @@ void FeaturesPlugin_Boolean::execute() return; } - if(GeomAlgoAPI_ShapeProps::volume(aBoolAlgo.shape()) > 1.e-7) { + if(GeomAlgoAPI_ShapeTools::volume(aBoolAlgo.shape()) > 1.e-7) { std::shared_ptr aResultBody = document()->createBody(data(), aResultIndex); LoadNamingDS(aResultBody, anObject, aTools, aBoolAlgo); setResult(aResultBody, aResultIndex); diff --git a/src/FeaturesPlugin/FeaturesPlugin_CompositeBoolean.cpp b/src/FeaturesPlugin/FeaturesPlugin_CompositeBoolean.cpp index 6bc4ae5d0..9d59c3c37 100644 --- a/src/FeaturesPlugin/FeaturesPlugin_CompositeBoolean.cpp +++ b/src/FeaturesPlugin/FeaturesPlugin_CompositeBoolean.cpp @@ -14,7 +14,7 @@ #include #include -#include +#include //================================================================================================= void FeaturesPlugin_CompositeBoolean::initAttributes() @@ -162,7 +162,7 @@ void FeaturesPlugin_CompositeBoolean::execute() return; } - if(GeomAlgoAPI_ShapeProps::volume(aBoolAlgo.shape()) > 1.e-7) { + if(GeomAlgoAPI_ShapeTools::volume(aBoolAlgo.shape()) > 1.e-7) { std::shared_ptr aResultBody = document()->createBody(data(), aResultIndex); loadNamingDS(aResultBody, anObject, aSketchFacesList, theSolidsAlgos, aBooleanTools, aBoolAlgo); setResult(aResultBody, aResultIndex); @@ -237,8 +237,9 @@ void FeaturesPlugin_CompositeBoolean::loadNamingDS(std::shared_ptrmapOfShapes(); aResultBuilder->loadAndOrientGeneratedShapes(aPrismAlgo->makeShape().get(), *aFaceIter, GeomAPI_Shape::EDGE, aGenTag, aLatName, *aSubShapes.get()); - aFromFace = aPrismAlgo->firstShape(); - aToFace = aPrismAlgo->lastShape(); + //TODO:fix + //aFromFace = aPrismAlgo->firstShape(); + //aToFace = aPrismAlgo->lastShape(); } else if(std::dynamic_pointer_cast(*aSolidsAlgosIter)) { std::shared_ptr aRevolAlgo = std::dynamic_pointer_cast(*aSolidsAlgosIter); aSubShapes = aRevolAlgo->mapOfShapes(); diff --git a/src/FeaturesPlugin/FeaturesPlugin_Extrusion.cpp b/src/FeaturesPlugin/FeaturesPlugin_Extrusion.cpp index 26cb739e9..a6372cf9a 100644 --- a/src/FeaturesPlugin/FeaturesPlugin_Extrusion.cpp +++ b/src/FeaturesPlugin/FeaturesPlugin_Extrusion.cpp @@ -22,14 +22,7 @@ #include #include - -#define _LATERAL_TAG 1 -#define _FIRST_TAG 2 -#define _LAST_TAG 3 -#define EDGE 6 - -//#define DEBUG_COMPSOLID -//#define DEBUG_COMPSOLID_SHAPE +#include //================================================================================================= FeaturesPlugin_Extrusion::FeaturesPlugin_Extrusion() @@ -63,7 +56,43 @@ void FeaturesPlugin_Extrusion::initAttributes() //================================================================================================= void FeaturesPlugin_Extrusion::execute() { - AttributeSelectionListPtr aFaceRefs = selectionList(LIST_ID()); + // Getting faces. + ListOfShape aFacesList; + AttributeSelectionListPtr aFacesSelectionList = selectionList(LIST_ID()); + for(int anIndex = 0; anIndex < aFacesSelectionList->size(); anIndex++) { + std::shared_ptr aFaceSel = aFacesSelectionList->value(anIndex); + ResultPtr aContext = aFaceSel->context(); + std::shared_ptr aContextShape = aContext->shape(); + if(!aContextShape.get()) { + static const std::string aContextError = "The selection context is bad"; + setError(aContextError); + break; + } + + std::shared_ptr aFaceShape = aFaceSel->value(); + int aFacesNum = -1; // this mean that "aFace" is used + ResultConstructionPtr aConstruction = + std::dynamic_pointer_cast(aContext); + if(!aFaceShape.get()) { // this may be the whole sketch result selected, check and get faces + if (aConstruction.get()) { + aFacesNum = aConstruction->facesNum(); + } else { + static const std::string aFaceError = "Can not find basis for extrusion"; + setError(aFaceError); + break; + } + } + for(int aFaceIndex = 0; aFaceIndex < aFacesNum || aFacesNum == -1; aFaceIndex++) { + std::shared_ptr aBaseShape; + if (aFacesNum == -1) { + aFacesList.push_back(aFaceShape); + break; + } else { + aFaceShape = std::dynamic_pointer_cast(aConstruction->face(aFaceIndex)); + aFacesList.push_back(aFaceShape); + } + } + } // Getting sizes. double aToSize = 0.0; @@ -98,133 +127,88 @@ void FeaturesPlugin_Extrusion::execute() } } - // for each selected face generate a result + // Searching faces with common edges. + ListOfShape aShells; + ListOfShape aFreeFaces; + GeomAlgoAPI_ShapeTools::combineFacesToShells(aFacesList, aShells, aFreeFaces); + aShells.merge(aFreeFaces); + + // Generating result for each shell and face. int anIndex = 0, aResultIndex = 0; -#ifdef DEBUG_COMPSOLID - ResultCompSolidPtr aCompSolidResult = document()->createCompSolid(data(), aResultIndex); - setResult(aCompSolidResult, aResultIndex); - aResultIndex++; -#endif -#ifdef DEBUG_COMPSOLID_SHAPE - bool aFirstShapeInCompsolid = aFaceRefs->size() > 0; - if (aFirstShapeInCompsolid) - aResultIndex--; -#endif - for(; anIndex < aFaceRefs->size(); anIndex++) { - std::shared_ptr aFaceRef = aFaceRefs->value(anIndex); - ResultPtr aContextRes = aFaceRef->context(); - std::shared_ptr aContext = aContextRes->shape(); - if (!aContext.get()) { - static const std::string aContextError = "The selection context is bad"; - setError(aContextError); + for(ListOfShape::const_iterator anIter = aShells.cbegin(); anIter != aShells.cend(); anIter++) { + std::shared_ptr aBaseShape = *anIter; + + GeomAlgoAPI_Prism aPrismAlgo(aBaseShape, aToShape, aToSize, aFromShape, aFromSize); + if(!aPrismAlgo.isDone()) { + static const std::string aPrismAlgoError = "Extrusion algorithm failed"; + setError(aPrismAlgoError); + aResultIndex = 0; break; } - std::shared_ptr aValueFace = aFaceRef->value(); - int aFacesNum = -1; // this mean that "aFace" is used - ResultConstructionPtr aConstruction = - std::dynamic_pointer_cast(aContextRes); - if (!aValueFace.get()) { // this may be the whole sketch result selected, check and get faces - if (aConstruction.get()) { - aFacesNum = aConstruction->facesNum(); - } else { - static const std::string aFaceError = "Can not find basis for extrusion"; - setError(aFaceError); - break; - } + // Check if shape is valid + if(!aPrismAlgo.shape().get() || aPrismAlgo.shape()->isNull()) { + static const std::string aShapeError = "Resulting shape is Null"; + setError(aShapeError); + aResultIndex = 0; + break; } - for(int aFaceIndex = 0; aFaceIndex < aFacesNum || aFacesNum == -1; aFaceIndex++) { - ResultBodyPtr aResultBody; - -#ifdef DEBUG_COMPSOLID_SHAPE - if (aFirstShapeInCompsolid && anIndex == 0) - aResultBody = aCompSolidResult; - else { -#endif - -#ifdef DEBUG_COMPSOLID - aResultBody = aCompSolidResult->addResult(aResultIndex); -#else - aResultBody = document()->createBody(data(), aResultIndex); -#endif - -#ifdef DEBUG_COMPSOLID_SHAPE - } -#endif - std::shared_ptr aBaseShape; - if (aFacesNum == -1) { - aBaseShape = aValueFace; - } else { - aBaseShape = std::dynamic_pointer_cast(aConstruction->face(aFaceIndex)); - } - - GeomAlgoAPI_Prism aFeature(aBaseShape, aToShape, aToSize, aFromShape, aFromSize); - if(!aFeature.isDone()) { - static const std::string aFeatureError = "Extrusion algorithm failed"; - setError(aFeatureError); - break; - } - - // Check if shape is valid - if(!aFeature.shape().get() || aFeature.shape()->isNull()) { - static const std::string aShapeError = "Resulting shape is Null"; - setError(aShapeError); - break; - } - if(!aFeature.isValid()) { - std::string aFeatureError = "Warning: resulting shape is not valid"; - setError(aFeatureError); - break; - } - //LoadNamingDS - LoadNamingDS(aFeature, aResultBody, aBaseShape, aContext); - setResult(aResultBody, aResultIndex); - aResultIndex++; - - if (aFacesNum == -1) - break; + if(!aPrismAlgo.isValid()) { + std::string aPrismAlgoError = "Warning: resulting shape is not valid"; + setError(aPrismAlgoError); + aResultIndex = 0; + break; } + + ResultBodyPtr aResultBody = document()->createBody(data(), aResultIndex); + loadNamingDS(aPrismAlgo, aResultBody, aBaseShape); + setResult(aResultBody, aResultIndex); + aResultIndex++; } - // remove the rest results if there were produced in the previous pass + removeResults(aResultIndex); } //================================================================================================= -void FeaturesPlugin_Extrusion::LoadNamingDS(GeomAlgoAPI_Prism& theFeature, +void FeaturesPlugin_Extrusion::loadNamingDS(GeomAlgoAPI_Prism& thePrismAlgo, std::shared_ptr theResultBody, - std::shared_ptr theBasis, - std::shared_ptr theContext) + std::shared_ptr theBasis) { //load result ModelAPI_BodyBuilder* aResultBuilder = theResultBody->getBodyBuilder(); - if(theBasis->isEqual(theContext)) - aResultBuilder->store(theFeature.shape()); - else - aResultBuilder->storeGenerated(theBasis, theFeature.shape()); + if(thePrismAlgo.shape()->shapeType() == GeomAPI_Shape::COMPSOLID) { + int a = 1; + } + aResultBuilder->storeGenerated(theBasis, thePrismAlgo.shape()); - std::shared_ptr aSubShapes = theFeature.mapOfShapes(); + std::shared_ptr aSubShapes = thePrismAlgo.mapOfShapes(); //Insert lateral face : Face from Edge std::string aLatName = "LateralFace"; - aResultBuilder->loadAndOrientGeneratedShapes(theFeature.makeShape().get(), theBasis, EDGE,_LATERAL_TAG, aLatName, *aSubShapes); - - //Insert bottom face - std::string aBotName = "BottomFace"; - std::shared_ptr aBottomFace = theFeature.firstShape(); - if(!aBottomFace->isNull()) { - if(aSubShapes->isBound(aBottomFace)) { - aBottomFace = aSubShapes->find(aBottomFace); + const int aLatTag = 1; + aResultBuilder->loadAndOrientGeneratedShapes(thePrismAlgo.makeShape().get(), theBasis, GeomAPI_Shape::EDGE, aLatTag, aLatName, *aSubShapes); + + //Insert to faces + std::string aToName = "ToFace"; + const int aToTag = 2; + const ListOfShape& aToFaces = thePrismAlgo.toFaces(); + for(ListOfShape::const_iterator anIt = aToFaces.cbegin(); anIt != aToFaces.cend(); anIt++) { + std::shared_ptr aToFace = *anIt; + if(aSubShapes->isBound(aToFace)) { + aToFace = aSubShapes->find(aToFace); } - aResultBuilder->generated(aBottomFace, aBotName, _FIRST_TAG); + aResultBuilder->generated(aToFace, aToName, aToTag); } - //Insert top face - std::string aTopName = "TopFace"; - std::shared_ptr aTopFace = theFeature.lastShape(); - if (!aTopFace->isNull()) { - if (aSubShapes->isBound(aTopFace)) { - aTopFace = aSubShapes->find(aTopFace); + //Insert from faces + std::string aFromName = "FromFace"; + const int aFromTag = 3; + const ListOfShape& aFromFaces = thePrismAlgo.fromFaces(); + for(ListOfShape::const_iterator anIt = aFromFaces.cbegin(); anIt != aFromFaces.cend(); anIt++) { + std::shared_ptr aFromFace = *anIt; + if(aSubShapes->isBound(aFromFace)) { + aFromFace = aSubShapes->find(aFromFace); } - aResultBuilder->generated(aTopFace, aTopName, _LAST_TAG); + aResultBuilder->generated(aFromFace, aFromName, aFromTag); } } diff --git a/src/FeaturesPlugin/FeaturesPlugin_Extrusion.h b/src/FeaturesPlugin/FeaturesPlugin_Extrusion.h index 965463691..98c9af7c9 100644 --- a/src/FeaturesPlugin/FeaturesPlugin_Extrusion.h +++ b/src/FeaturesPlugin/FeaturesPlugin_Extrusion.h @@ -113,9 +113,9 @@ class FeaturesPlugin_Extrusion : public ModelAPI_Feature FeaturesPlugin_Extrusion(); private: /// Load Naming data structure of the feature to the document - void LoadNamingDS(GeomAlgoAPI_Prism& theFeature, std::shared_ptr theResultBody, - std::shared_ptr theBasis, - std::shared_ptr theContext); + void loadNamingDS(GeomAlgoAPI_Prism& thePrismAlgo, + std::shared_ptr theResultBody, + std::shared_ptr theBasis); }; #endif diff --git a/src/FeaturesPlugin/Test/TestExtrusion.py b/src/FeaturesPlugin/Test/TestExtrusion.py index 2e8e6312d..cd204d7ed 100644 --- a/src/FeaturesPlugin/Test/TestExtrusion.py +++ b/src/FeaturesPlugin/Test/TestExtrusion.py @@ -148,7 +148,7 @@ assert (anExtrusionResult is not None) # Check extrusion volume aRefVolume = 100530.96491487337 -aResVolume = GeomAlgoAPI_ShapeProps_volume(anExtrusionResult.shape()) +aResVolume = GeomAlgoAPI_ShapeTools_volume(anExtrusionResult.shape()) assert (math.fabs(aResVolume - aRefVolume) < 10 ** -5) #========================================================================= diff --git a/src/FeaturesPlugin/extrusion_widget.xml b/src/FeaturesPlugin/extrusion_widget.xml index 95bc4841b..d028dcfa6 100644 --- a/src/FeaturesPlugin/extrusion_widget.xml +++ b/src/FeaturesPlugin/extrusion_widget.xml @@ -14,7 +14,6 @@ (); + return (ShapeType)aShape.ShapeType(); +} + bool GeomAPI_Shape::computeSize(double& theXmin, double& theYmin, double& theZmin, double& theXmax, double& theYmax, double& theZmax) const { diff --git a/src/GeomAPI/GeomAPI_Shape.h b/src/GeomAPI/GeomAPI_Shape.h index 22362e710..13f000fa8 100644 --- a/src/GeomAPI/GeomAPI_Shape.h +++ b/src/GeomAPI/GeomAPI_Shape.h @@ -62,6 +62,10 @@ public: GEOMAPI_EXPORT virtual bool isSolid() const; + /// Returns the shape type + GEOMAPI_EXPORT + virtual ShapeType shapeType() const; + /// Computes boundary dimensions of the shape /// Returns False if it is not possible GEOMAPI_EXPORT diff --git a/src/GeomAlgoAPI/CMakeLists.txt b/src/GeomAlgoAPI/CMakeLists.txt index 6d14a195d..5b986ce0a 100644 --- a/src/GeomAlgoAPI/CMakeLists.txt +++ b/src/GeomAlgoAPI/CMakeLists.txt @@ -21,7 +21,6 @@ SET(PROJECT_HEADERS GeomAlgoAPI_Movement.h GeomAlgoAPI_MakeShape.h GeomAlgoAPI_MakeShapeList.h - GeomAlgoAPI_ShapeProps.h GeomAlgoAPI_DFLoader.h GeomAlgoAPI_Placement.h GeomAlgoAPI_BREPImport.h @@ -31,6 +30,7 @@ SET(PROJECT_HEADERS GeomAlgoAPI_STEPExport.h GeomAlgoAPI_IGESExport.h GeomAlgoAPI_Transform.h + GeomAlgoAPI_ShapeTools.h ) SET(PROJECT_SOURCES @@ -48,7 +48,6 @@ SET(PROJECT_SOURCES GeomAlgoAPI_Movement.cpp GeomAlgoAPI_MakeShape.cpp GeomAlgoAPI_MakeShapeList.cpp - GeomAlgoAPI_ShapeProps.cpp GeomAlgoAPI_DFLoader.cpp GeomAlgoAPI_Placement.cpp GeomAlgoAPI_BREPImport.cpp @@ -58,6 +57,7 @@ SET(PROJECT_SOURCES GeomAlgoAPI_STEPExport.cpp GeomAlgoAPI_IGESExport.cpp GeomAlgoAPI_Transform.cpp + GeomAlgoAPI_ShapeTools.cpp ) SET(PROJECT_LIBRARIES @@ -76,7 +76,8 @@ SET(PROJECT_LIBRARIES ${CAS_TKSTEPBase} ${CAS_TKIGES} ${CAS_TKTopAlgo} - ${CAS_TKXSBase} + ${CAS_TKXSBase} + ${CAS_TKOffset} ) ADD_DEFINITIONS(-DGEOMALGOAPI_EXPORTS ${CAS_DEFINITIONS}) diff --git a/src/GeomAlgoAPI/GeomAlgoAPI.i b/src/GeomAlgoAPI/GeomAlgoAPI.i index 5d102832a..01c3b71d8 100644 --- a/src/GeomAlgoAPI/GeomAlgoAPI.i +++ b/src/GeomAlgoAPI/GeomAlgoAPI.i @@ -16,7 +16,7 @@ #include "GeomAlgoAPI_Prism.h" #include "GeomAlgoAPI_Revolution.h" #include "GeomAlgoAPI_Rotation.h" - #include "GeomAlgoAPI_ShapeProps.h" + #include "GeomAlgoAPI_ShapeTools.h" #include "GeomAlgoAPI_SketchBuilder.h" #include "GeomAlgoAPI_BREPExport.h" #include "GeomAlgoAPI_IGESExport.h" @@ -56,7 +56,7 @@ %include "GeomAlgoAPI_Prism.h" %include "GeomAlgoAPI_Revolution.h" %include "GeomAlgoAPI_Rotation.h" -%include "GeomAlgoAPI_ShapeProps.h" +%include "GeomAlgoAPI_ShapeTools.h" %include "GeomAlgoAPI_SketchBuilder.h" %include "GeomAlgoAPI_BREPExport.h" %include "GeomAlgoAPI_IGESExport.h" diff --git a/src/GeomAlgoAPI/GeomAlgoAPI_MakeShape.cpp b/src/GeomAlgoAPI/GeomAlgoAPI_MakeShape.cpp index 22bde17c0..b1affac1c 100644 --- a/src/GeomAlgoAPI/GeomAlgoAPI_MakeShape.cpp +++ b/src/GeomAlgoAPI/GeomAlgoAPI_MakeShape.cpp @@ -6,14 +6,25 @@ #include #include +#include +#include #include #include + GeomAlgoAPI_MakeShape::GeomAlgoAPI_MakeShape(void* theMkShape) : GeomAPI_Interface(theMkShape),myShape(new GeomAPI_Shape()) { myShape->setImpl(new TopoDS_Shape(implPtr()->Shape())); } +GeomAlgoAPI_MakeShape::GeomAlgoAPI_MakeShape(void* theMkShape, const std::shared_ptr theWire) +: GeomAPI_Interface(theMkShape), + myShape(new GeomAPI_Shape()), + myWire(theWire) +{ + myShape->setImpl(new TopoDS_Shape(implPtr()->Shape())); +} + GeomAlgoAPI_MakeShape::GeomAlgoAPI_MakeShape() : GeomAPI_Interface(),myShape(new GeomAPI_Shape()) {} @@ -26,14 +37,27 @@ const std::shared_ptr GeomAlgoAPI_MakeShape::shape() const void GeomAlgoAPI_MakeShape::generated( const std::shared_ptr theShape, ListOfShape& theHistory) { - BRepBuilderAPI_MakeShape* aBuilder = implPtr(); - if(aBuilder) { - const TopTools_ListOfShape& aList = aBuilder->Generated(theShape->impl()); - TopTools_ListIteratorOfListOfShape it(aList); - for(;it.More();it.Next()) { - std::shared_ptr aShape(new GeomAPI_Shape()); - aShape->setImpl(new TopoDS_Shape(it.Value())); - theHistory.push_back(aShape); + if(!myWire.get()) { + BRepBuilderAPI_MakeShape* aBuilder = implPtr(); + if(aBuilder) { + const TopTools_ListOfShape& aList = aBuilder->Generated(theShape->impl()); + TopTools_ListIteratorOfListOfShape it(aList); + for(;it.More();it.Next()) { + std::shared_ptr aShape(new GeomAPI_Shape()); + aShape->setImpl(new TopoDS_Shape(it.Value())); + theHistory.push_back(aShape); + } + } + } else { // Pipe builder + BRepOffsetAPI_MakePipe* aPipeBuilder = implPtr(); + if(aPipeBuilder) { + TopExp_Explorer aShapeExplorer(myWire->impl(), TopAbs_EDGE); + for (; aShapeExplorer.More(); aShapeExplorer.Next ()) { + const TopoDS_Shape& aGeneratedShape = aPipeBuilder->Generated(aShapeExplorer.Current(), theShape->impl()); + std::shared_ptr aShape(new GeomAPI_Shape()); + aShape->setImpl(new TopoDS_Shape(aGeneratedShape)); + theHistory.push_back(aShape); + } } } } diff --git a/src/GeomAlgoAPI/GeomAlgoAPI_MakeShape.h b/src/GeomAlgoAPI/GeomAlgoAPI_MakeShape.h index 38519b03f..f028855ed 100644 --- a/src/GeomAlgoAPI/GeomAlgoAPI_MakeShape.h +++ b/src/GeomAlgoAPI/GeomAlgoAPI_MakeShape.h @@ -24,6 +24,9 @@ public: /// Constructor by the already stored builder in the interface GEOMALGOAPI_EXPORT GeomAlgoAPI_MakeShape(void* theBuilder); + /// Constructor by the builder and wire. Used for pipe builder. + GEOMALGOAPI_EXPORT GeomAlgoAPI_MakeShape(void* theBuilder, const std::shared_ptr theWire); + /// Returns a shape built by the shape construction algorithm GEOMALGOAPI_EXPORT const std::shared_ptr shape() const; @@ -40,7 +43,8 @@ public: protected: /// The resulting shape - std::shared_ptr myShape; + std::shared_ptr myShape; + std::shared_ptr myWire; }; typedef std::list > ListOfMakeShape; diff --git a/src/GeomAlgoAPI/GeomAlgoAPI_MakeShapeList.cpp b/src/GeomAlgoAPI/GeomAlgoAPI_MakeShapeList.cpp index 58518ea49..b6270b594 100644 --- a/src/GeomAlgoAPI/GeomAlgoAPI_MakeShapeList.cpp +++ b/src/GeomAlgoAPI/GeomAlgoAPI_MakeShapeList.cpp @@ -79,25 +79,28 @@ void GeomAlgoAPI_MakeShapeList::result(const std::shared_ptr theS aResultShapes.Add(theShape->impl()); for(ListOfMakeShape::iterator aBuilderIt = myListOfMakeShape.begin(); aBuilderIt != myListOfMakeShape.end(); aBuilderIt++) { - BRepBuilderAPI_MakeShape* aBuilder = (*aBuilderIt)->implPtr(); + std::shared_ptr aMakeShape = *aBuilderIt; NCollection_Map aTempShapes; bool hasResults = false; for(NCollection_Map::Iterator aShapeIt(anAlgoShapes); aShapeIt.More(); aShapeIt.Next()) { - const TopoDS_Shape& aShape = aShapeIt.Value(); - const TopTools_ListOfShape& aGeneratedList = aBuilder->Generated(aShape); - for(TopTools_ListIteratorOfListOfShape anIt(aGeneratedList); anIt.More(); anIt.Next()) { - aTempShapes.Add(anIt.Value()); - aResultShapes.Add(anIt.Value()); + std::shared_ptr aShape(new GeomAPI_Shape); + aShape->setImpl(new TopoDS_Shape(aShapeIt.Value())); + ListOfShape aGeneratedShapes; + aMakeShape->generated(aShape, aGeneratedShapes); + for(ListOfShape::const_iterator anIt = aGeneratedShapes.cbegin(); anIt != aGeneratedShapes.cend(); anIt++) { + aTempShapes.Add((*anIt)->impl()); + aResultShapes.Add((*anIt)->impl()); hasResults = true; } - const TopTools_ListOfShape& aModifiedList = aBuilder->Modified(aShape); - for(TopTools_ListIteratorOfListOfShape anIt(aModifiedList); anIt.More(); anIt.Next()) { - aTempShapes.Add(anIt.Value()); - aResultShapes.Add(anIt.Value()); + ListOfShape aModifiedShapes; + aMakeShape->modified(aShape, aModifiedShapes); + for(ListOfShape::const_iterator anIt = aModifiedShapes.cbegin(); anIt != aModifiedShapes.cend(); anIt++) { + aTempShapes.Add((*anIt)->impl()); + aResultShapes.Add((*anIt)->impl()); hasResults = true; } if(hasResults) { - aResultShapes.Remove(aShape); + aResultShapes.Remove(aShape->impl()); } } anAlgoShapes.Unite(aTempShapes); diff --git a/src/GeomAlgoAPI/GeomAlgoAPI_Movement.cpp b/src/GeomAlgoAPI/GeomAlgoAPI_Movement.cpp index 48073be5f..ab9b43fc2 100644 --- a/src/GeomAlgoAPI/GeomAlgoAPI_Movement.cpp +++ b/src/GeomAlgoAPI/GeomAlgoAPI_Movement.cpp @@ -6,7 +6,7 @@ #include -#include +#include #include #include @@ -92,7 +92,7 @@ const bool GeomAlgoAPI_Movement::isValid() const const bool GeomAlgoAPI_Movement::hasVolume() const { bool hasVolume(false); - if(isValid() && (GeomAlgoAPI_ShapeProps::volume(myShape) > Precision::Confusion())) { + if(isValid() && (GeomAlgoAPI_ShapeTools::volume(myShape) > Precision::Confusion())) { hasVolume = true; } return hasVolume; diff --git a/src/GeomAlgoAPI/GeomAlgoAPI_Prism.cpp b/src/GeomAlgoAPI/GeomAlgoAPI_Prism.cpp index 0677d7fc6..c084b60a6 100644 --- a/src/GeomAlgoAPI/GeomAlgoAPI_Prism.cpp +++ b/src/GeomAlgoAPI/GeomAlgoAPI_Prism.cpp @@ -9,19 +9,37 @@ #include #include #include +#include #include #include #include +#include +#include +#include +#include #include +#include +#include +#include +#include +#include #include -#include +#include #include +#include +#include #include #include #include +#include #include #include +#include +#include +#include +#include +#include //================================================================================================= GeomAlgoAPI_Prism::GeomAlgoAPI_Prism(std::shared_ptr theBasis, @@ -52,12 +70,24 @@ void GeomAlgoAPI_Prism::build(const std::shared_ptr& theBasis, { if(!theBasis || (((!theFromShape && !theToShape) || (theFromShape && theToShape && theFromShape->isEqual(theToShape))) - && (theFromSize == 0.0 && theToSize == 0.0))) { + && (theFromSize == -theToSize))) { return; } // If bounding faces was not set creating them. - std::shared_ptr aBaseFace(new GeomAPI_Face(theBasis)); + std::shared_ptr aBaseFace; + if(theBasis->shapeType() == GeomAPI_Shape::SHELL) { + GeomAPI_ShapeExplorer anExp(theBasis, GeomAPI_Shape::FACE); + if(anExp.more()) { + std::shared_ptr aFaceOnShell = anExp.current(); + aBaseFace = std::shared_ptr(new GeomAPI_Face(aFaceOnShell)); + } + } else { + aBaseFace = std::shared_ptr(new GeomAPI_Face(theBasis)); + } + if(!aBaseFace.get()) { + return; + } std::shared_ptr aBasePln = aBaseFace->getPlane(); std::shared_ptr aBaseDir = aBasePln->direction(); std::shared_ptr aBaseLoc = aBasePln->location(); @@ -87,46 +117,165 @@ void GeomAlgoAPI_Prism::build(const std::shared_ptr& theBasis, aSign ? -theToSize : theToSize)))); aBoundingToShape = GeomAlgoAPI_FaceBuilder::planarFace(aToPnt, aToDir); - TopoDS_Face aBasis = TopoDS::Face(theBasis->impl()); - Handle(Geom_Plane) aPlane = Handle(Geom_Plane)::DownCast(BRep_Tool::Surface(aBasis)); - if(aPlane.IsNull()) { // non-planar shapes is not supported for extrusion yet + // Getting bounding box for base shape. + const TopoDS_Shape& aBasisShape = theBasis->impl(); + Bnd_Box aBndBox; + BRepBndLib::Add(aBasisShape, aBndBox); + Standard_Real aXArr[2] = {aBndBox.CornerMin().X(), aBndBox.CornerMax().X()}; + Standard_Real aYArr[2] = {aBndBox.CornerMin().Y(), aBndBox.CornerMax().Y()}; + Standard_Real aZArr[2] = {aBndBox.CornerMin().Z(), aBndBox.CornerMax().Z()}; + gp_Pnt aPoints[8]; + int aNum = 0; + for(int i = 0; i < 2; i++) { + for(int j = 0; j < 2; j++) { + for(int k = 0; k < 2; k++) { + aPoints[aNum] = gp_Pnt(aXArr[i], aYArr[j], aZArr[k]); + aNum++; + } + } + } + + // Project points to bounding planes. Search max distance to them. + const TopoDS_Shape& aBndToShape = aBoundingToShape->impl(); + const TopoDS_Shape& aBndFromShape = aBoundingFromShape->impl(); + Standard_Real aMaxToDist = 0, aMaxFromDist = 0; + gp_Vec aNormal(aBaseDir->impl()); + for(int i = 0; i < 8; i++) { + gp_Lin aLine(aPoints[i], aNormal); + TopoDS_Edge anEdge = BRepBuilderAPI_MakeEdge(aLine).Edge(); + BRepExtrema_ExtCF aToExt(anEdge, TopoDS::Face(aBndToShape)); + BRepExtrema_ExtCF aFromExt(anEdge, TopoDS::Face(aBndFromShape)); + if(aToExt.NbExt() == 0 || aFromExt.NbExt() == 0) { + return; + } + const gp_Pnt& aPntOnToFace = aToExt.PointOnFace(1); + const gp_Pnt& aPntOnFromFace = aFromExt.PointOnFace(1); + if(aPoints[i].Distance(aPntOnToFace) > aMaxToDist) { + aMaxToDist = aPoints[i].Distance(aPntOnToFace); + } + if(aPoints[i].Distance(aPntOnFromFace) > aMaxFromDist) { + aMaxFromDist = aPoints[i].Distance(aPntOnFromFace); + } + } + Standard_Real aPipeLength = aMaxToDist + aMaxFromDist; + + // Making wire for pipe. + std::shared_ptr aCentreOfMass = GeomAlgoAPI_ShapeTools::centreOfMass(theBasis); + const gp_Pnt aCentrePnt = aCentreOfMass->impl(); + TopoDS_Face aFace = TopoDS::Face(aBaseFace->impl()); + gp_Pnt aPipeStartPnt = aCentrePnt.Translated(aNormal.Scaled(aPipeLength)); + gp_Pnt aPipeEndPnt = aCentrePnt.Translated(aNormal.Scaled(-aPipeLength)); + TopoDS_Edge aPipeEdge = BRepBuilderAPI_MakeEdge(aPipeStartPnt, aPipeEndPnt); + TopoDS_Wire aPipeWire = BRepBuilderAPI_MakeWire(aPipeEdge).Wire(); + + // Making pipe. + ListOfMakeShape aListOfMakeShape; + BRepOffsetAPI_MakePipe* aPipeBuilder = new BRepOffsetAPI_MakePipe(aPipeWire, aBasisShape); + if(!aPipeBuilder) { return; } + std::shared_ptr aWire(new GeomAPI_Shape); + aWire->setImpl(new TopoDS_Shape(aPipeWire)); + aListOfMakeShape.push_back(std::make_shared(aPipeBuilder, aWire)); + TopoDS_Shape aResult = aPipeBuilder->Shape(); - const gp_Dir& aNormal = aPlane->Pln().Axis().Direction(); - BRepFeat_MakePrism* aBuilder = new BRepFeat_MakePrism(aBasis, aBasis, aBasis, aNormal, 2, Standard_True); - - if(aBuilder) { - const TopoDS_Shape& aFromShape = aBoundingFromShape->impl(); - const TopoDS_Shape& aToShape = aBoundingToShape->impl(); - aBuilder->Perform(aFromShape, aToShape); - myDone = aBuilder->IsDone() == Standard_True; - if(myDone){ - TopoDS_Shape aResult = aBuilder->Shape(); - TopExp_Explorer anExp(aResult, TopAbs_SOLID); - if(!anExp.More()) { - return; - } - if(aResult.ShapeType() == TopAbs_COMPOUND) { - aResult = GeomAlgoAPI_DFLoader::refineResult(aResult); - } - // fill data map to keep correct orientation of sub-shapes - myMap = std::shared_ptr(new GeomAPI_DataMapOfShapeShape()); - for (TopExp_Explorer Exp(aResult,TopAbs_FACE); Exp.More(); Exp.Next()) { - std::shared_ptr aCurrentShape(new GeomAPI_Shape()); - aCurrentShape->setImpl(new TopoDS_Shape(Exp.Current())); - myMap->bind(aCurrentShape, aCurrentShape); - } - myShape = std::shared_ptr(new GeomAPI_Shape()); - myShape->setImpl(new TopoDS_Shape(aResult)); - myFirst = std::shared_ptr(new GeomAPI_Shape()); - myFirst->setImpl(new TopoDS_Shape(aBuilder->Modified(aFromShape).First())); - myLast = std::shared_ptr(new GeomAPI_Shape()); - myLast->setImpl(new TopoDS_Shape(aBuilder->Modified(aToShape).First())); - myMkShape = std::shared_ptr(new GeomAlgoAPI_MakeShape()); - myMkShape->setImpl(aBuilder); + // Orienting bounding planes. + gp_Lin aLine(aCentrePnt, aNormal); + TopoDS_Edge anEdge = BRepBuilderAPI_MakeEdge(aLine).Edge(); + BRepExtrema_ExtCF aToExt(anEdge, TopoDS::Face(aBndToShape)); + BRepExtrema_ExtCF aFromExt(anEdge, TopoDS::Face(aBndFromShape)); + Standard_Real aToParameter = aToExt.ParameterOnEdge(1); + Standard_Real aFromParameter = aFromExt.ParameterOnEdge(1); + if(aToParameter > aFromParameter) { + gp_Vec aVec = aToDir->impl(); + if((aVec * aNormal) > 0) { + aToDir->setImpl(new gp_Dir(aVec.Reversed())); + aBoundingToShape = GeomAlgoAPI_FaceBuilder::planarFace(aToPnt, aToDir); + } + aVec = aFromDir->impl(); + if((aVec * aNormal) < 0) { + aFromDir->setImpl(new gp_Dir(aVec.Reversed())); + aBoundingFromShape = GeomAlgoAPI_FaceBuilder::planarFace(aFromPnt, aFromDir); + } + } else { + gp_Vec aVec = aToDir->impl(); + if((aVec * aNormal) < 0) { + aToDir->setImpl(new gp_Dir(aVec.Reversed())); + aBoundingToShape = GeomAlgoAPI_FaceBuilder::planarFace(aToPnt, aToDir); } + aVec = aFromDir->impl(); + if((aVec * aNormal) > 0) { + aFromDir->setImpl(new gp_Dir(aVec.Reversed())); + aBoundingFromShape = GeomAlgoAPI_FaceBuilder::planarFace(aFromPnt, aFromDir); + } + } + + // Making solids from bounding planes. + TopoDS_Shell aToShell, aFromShell; + TopoDS_Solid aToSolid, aFromSolid; + const TopoDS_Shape& aToShape = aBoundingToShape->impl(); + const TopoDS_Shape& aFromShape = aBoundingFromShape->impl(); + BRep_Builder aBoundingBuilder; + aBoundingBuilder.MakeShell(aToShell); + aBoundingBuilder.MakeShell(aFromShell); + aBoundingBuilder.Add(aToShell, aToShape); + aBoundingBuilder.Add(aFromShell, aFromShape); + aBoundingBuilder.MakeSolid(aToSolid); + aBoundingBuilder.MakeSolid(aFromSolid); + aBoundingBuilder.Add(aToSolid, aToShell); + aBoundingBuilder.Add(aFromSolid, aFromShell); + + // Cutting with to plane. + BRepAlgoAPI_Cut* aToCutBuilder = new BRepAlgoAPI_Cut(aResult, aToSolid); + aToCutBuilder->Build(); + if(!aToCutBuilder->IsDone()) { + return; + } + aListOfMakeShape.push_back(std::make_shared(aToCutBuilder)); + const TopTools_ListOfShape& aToShapes = aToCutBuilder->Modified(aToShape); + for(TopTools_ListIteratorOfListOfShape anIt(aToShapes); anIt.More(); anIt.Next()) { + std::shared_ptr aShape(new GeomAPI_Shape()); + aShape->setImpl(new TopoDS_Shape(anIt.Value())); + myToFaces.push_back(aShape); + } + aResult = aToCutBuilder->Shape(); + + // Cutting with from plane. + BRepAlgoAPI_Cut* aFromCutBuilder = new BRepAlgoAPI_Cut(aResult, aFromSolid); + aFromCutBuilder->Build(); + if(!aFromCutBuilder->IsDone()) { + return; } + aListOfMakeShape.push_back(std::make_shared(aFromCutBuilder)); + const TopTools_ListOfShape& aFromShapes = aFromCutBuilder->Modified(aFromShape); + for(TopTools_ListIteratorOfListOfShape anIt(aFromShapes); anIt.More(); anIt.Next()) { + std::shared_ptr aShape(new GeomAPI_Shape()); + aShape->setImpl(new TopoDS_Shape(anIt.Value())); + myFromFaces.push_back(aShape); + } + aResult = aFromCutBuilder->Shape(); + + TopExp_Explorer anExp(aResult, TopAbs_SOLID); + if(!anExp.More()) { + return; + } + if(aResult.ShapeType() == TopAbs_COMPOUND) { + aResult = GeomAlgoAPI_DFLoader::refineResult(aResult); + } + + myShape = std::shared_ptr(new GeomAPI_Shape); + myShape->setImpl(new TopoDS_Shape(aResult)); + + // Fill data map to keep correct orientation of sub-shapes. + myMap = std::shared_ptr(new GeomAPI_DataMapOfShapeShape); + for (TopExp_Explorer Exp(aResult,TopAbs_FACE); Exp.More(); Exp.Next()) { + std::shared_ptr aCurrentShape(new GeomAPI_Shape()); + aCurrentShape->setImpl(new TopoDS_Shape(Exp.Current())); + myMap->bind(aCurrentShape, aCurrentShape); + } + + myMkShape = std::shared_ptr(new GeomAlgoAPI_MakeShapeList(aListOfMakeShape)); + myDone = true; } //================================================================================================= @@ -163,15 +312,15 @@ std::shared_ptr GeomAlgoAPI_Prism::shape() const } //================================================================================================= -std::shared_ptr GeomAlgoAPI_Prism::firstShape() const +const ListOfShape& GeomAlgoAPI_Prism::fromFaces() const { - return myFirst; + return myFromFaces; } //================================================================================================= -std::shared_ptr GeomAlgoAPI_Prism::lastShape() const +const ListOfShape& GeomAlgoAPI_Prism::toFaces() const { - return myLast; + return myToFaces; } //================================================================================================= diff --git a/src/GeomAlgoAPI/GeomAlgoAPI_Prism.h b/src/GeomAlgoAPI/GeomAlgoAPI_Prism.h index 9a5cf59cb..cb0747181 100644 --- a/src/GeomAlgoAPI/GeomAlgoAPI_Prism.h +++ b/src/GeomAlgoAPI/GeomAlgoAPI_Prism.h @@ -56,11 +56,11 @@ public: /// \return result of the Prism algorithm. GEOMALGOAPI_EXPORT std::shared_ptr shape() const; - /// \returns the first shape. - GEOMALGOAPI_EXPORT std::shared_ptr firstShape() const; + /// \returns the list of from faces. + GEOMALGOAPI_EXPORT const ListOfShape& fromFaces() const; - /// \return the last shape. - GEOMALGOAPI_EXPORT std::shared_ptr lastShape() const; + /// \return the list of to faces. + GEOMALGOAPI_EXPORT const ListOfShape& toFaces() const; /// \return map of sub-shapes of the result. To be used for History keeping. GEOMALGOAPI_EXPORT std::shared_ptr mapOfShapes() const; @@ -80,8 +80,8 @@ private: /// Fields. bool myDone; std::shared_ptr myShape; - std::shared_ptr myFirst; - std::shared_ptr myLast; + ListOfShape myFromFaces; + ListOfShape myToFaces; std::shared_ptr myMap; std::shared_ptr myMkShape; }; diff --git a/src/GeomAlgoAPI/GeomAlgoAPI_Revolution.cpp b/src/GeomAlgoAPI/GeomAlgoAPI_Revolution.cpp index f47d8a06f..11c8091b0 100644 --- a/src/GeomAlgoAPI/GeomAlgoAPI_Revolution.cpp +++ b/src/GeomAlgoAPI/GeomAlgoAPI_Revolution.cpp @@ -9,7 +9,7 @@ #include #include #include -#include +#include #include #include @@ -173,7 +173,7 @@ void GeomAlgoAPI_Revolution::build(const std::shared_ptr& theBasi // Orienting bounding planes properly so that the center of mass of the base face stays // on the result shape after cut. - gp_Pnt aBasisCentr = GeomAlgoAPI_ShapeProps::centreOfMass(theBasis)->impl(); + gp_Pnt aBasisCentr = GeomAlgoAPI_ShapeTools::centreOfMass(theBasis)->impl(); aFromFace = makeFaceFromPlane(aFromPln, aBasisCentr); aToFace = makeFaceFromPlane(aToPln, aBasisCentr); @@ -255,7 +255,7 @@ void GeomAlgoAPI_Revolution::build(const std::shared_ptr& theBasi // Orienting bounding plane properly so that the center of mass of the base face stays // on the result shape after cut. - gp_Pnt aBasisCentr = GeomAlgoAPI_ShapeProps::centreOfMass(theBasis)->impl(); + gp_Pnt aBasisCentr = GeomAlgoAPI_ShapeTools::centreOfMass(theBasis)->impl(); aBoundingFace = makeFaceFromPlane(aBoundingPln, aBasisCentr); // Making solid from bounding plane. @@ -362,7 +362,7 @@ void GeomAlgoAPI_Revolution::build(const std::shared_ptr& theBasi } myShape = std::shared_ptr(new GeomAPI_Shape()); myShape->setImpl(new TopoDS_Shape(aResult)); - myMkShape = std::shared_ptr(new GeomAlgoAPI_MakeShapeList()); + myMkShape = std::shared_ptr(new GeomAlgoAPI_MakeShapeList(aListOfMakeShape)); myDone = true; return; } diff --git a/src/GeomAlgoAPI/GeomAlgoAPI_Rotation.cpp b/src/GeomAlgoAPI/GeomAlgoAPI_Rotation.cpp index 17c88e408..3b24af85b 100644 --- a/src/GeomAlgoAPI/GeomAlgoAPI_Rotation.cpp +++ b/src/GeomAlgoAPI/GeomAlgoAPI_Rotation.cpp @@ -6,7 +6,7 @@ #include -#include +#include #include #include @@ -90,7 +90,7 @@ const bool GeomAlgoAPI_Rotation::isValid() const const bool GeomAlgoAPI_Rotation::hasVolume() const { bool hasVolume(false); - if(isValid() && (GeomAlgoAPI_ShapeProps::volume(myShape) > Precision::Confusion())) { + if(isValid() && (GeomAlgoAPI_ShapeTools::volume(myShape) > Precision::Confusion())) { hasVolume = true; } return hasVolume; diff --git a/src/GeomAlgoAPI/GeomAlgoAPI_ShapeProps.cpp b/src/GeomAlgoAPI/GeomAlgoAPI_ShapeProps.cpp deleted file mode 100644 index fcec98202..000000000 --- a/src/GeomAlgoAPI/GeomAlgoAPI_ShapeProps.cpp +++ /dev/null @@ -1,42 +0,0 @@ -// Copyright (C) 2014-20xx CEA/DEN, EDF R&D - -// File: GeomAlgoAPI_ShapeProps.cpp -// Created: 8 May 2015 -// Author: Dmitry Bobylev - -#include - -#include -#include -#include - -//================================================================================================= -double GeomAlgoAPI_ShapeProps::volume(std::shared_ptr theShape) -{ - GProp_GProps aGProps; - if(!theShape) { - return 0.0; - } - const TopoDS_Shape& aShape = theShape->impl(); - if(aShape.IsNull()) { - return 0.0; - } - BRepGProp::VolumeProperties(aShape, aGProps); - return aGProps.Mass(); -} - -//================================================================================================= -std::shared_ptr GeomAlgoAPI_ShapeProps::centreOfMass(std::shared_ptr theShape) -{ - GProp_GProps aGProps; - if(!theShape) { - return std::shared_ptr(); - } - const TopoDS_Shape& aShape = theShape->impl(); - if(aShape.IsNull()) { - return std::shared_ptr(); - } - BRepGProp::SurfaceProperties(aShape, aGProps); - gp_Pnt aCentre = aGProps.CentreOfMass(); - return std::shared_ptr(new GeomAPI_Pnt(aCentre.X(), aCentre.Y(), aCentre.Z())); -} diff --git a/src/GeomAlgoAPI/GeomAlgoAPI_ShapeProps.h b/src/GeomAlgoAPI/GeomAlgoAPI_ShapeProps.h deleted file mode 100644 index d802840db..000000000 --- a/src/GeomAlgoAPI/GeomAlgoAPI_ShapeProps.h +++ /dev/null @@ -1,31 +0,0 @@ -// Copyright (C) 2014-20xx CEA/DEN, EDF R&D - -// File: GeomAlgoAPI_ShapeProps.h -// Created: 8 May 2015 -// Author: Dmitry Bobylev - -#ifndef GeomAlgoAPI_ShapeProps_H_ -#define GeomAlgoAPI_ShapeProps_H_ - -#include - -#include -#include - -/** \class GeomAlgoAPI_ShapeProps - * \ingroup DataAlgo - * \brief Allows to compute different shape props. - */ -class GEOMALGOAPI_EXPORT GeomAlgoAPI_ShapeProps -{ -public: - /// \return the total volume of the solids of the current shape or 0.0 if it can be computed. - static double volume(std::shared_ptr theShape); - - /// \return the centre of mass of the current face. The coordinates returned for the center of mass - /// are expressed in the absolute Cartesian coordinate system. (This function works only for surfaces). - static std::shared_ptr centreOfMass(std::shared_ptr theShape); -}; - -#endif - diff --git a/src/GeomAlgoAPI/GeomAlgoAPI_ShapeTools.cpp b/src/GeomAlgoAPI/GeomAlgoAPI_ShapeTools.cpp new file mode 100644 index 000000000..aa5486888 --- /dev/null +++ b/src/GeomAlgoAPI/GeomAlgoAPI_ShapeTools.cpp @@ -0,0 +1,142 @@ +// Copyright (C) 2014-20xx CEA/DEN, EDF R&D + +// File: GeomAlgoAPI_ShapeTools.h +// Created: 3 August 2015 +// Author: Dmitry Bobylev + +#include + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +//================================================================================================= +double GeomAlgoAPI_ShapeTools::volume(std::shared_ptr theShape) +{ + GProp_GProps aGProps; + if(!theShape) { + return 0.0; + } + const TopoDS_Shape& aShape = theShape->impl(); + if(aShape.IsNull()) { + return 0.0; + } + BRepGProp::VolumeProperties(aShape, aGProps); + return aGProps.Mass(); +} + +//================================================================================================= +std::shared_ptr GeomAlgoAPI_ShapeTools::centreOfMass(std::shared_ptr theShape) +{ + GProp_GProps aGProps; + if(!theShape) { + return std::shared_ptr(); + } + const TopoDS_Shape& aShape = theShape->impl(); + if(aShape.IsNull()) { + return std::shared_ptr(); + } + BRepGProp::SurfaceProperties(aShape, aGProps); + gp_Pnt aCentre = aGProps.CentreOfMass(); + return std::shared_ptr(new GeomAPI_Pnt(aCentre.X(), aCentre.Y(), aCentre.Z())); +} + +//================================================================================================= +void GeomAlgoAPI_ShapeTools::combineFacesToShells(const ListOfShape& theFacesList, + ListOfShape& theShells, + ListOfShape& theFreeFaces) +{ + if(theFacesList.empty()) { + return; + } + + // Adding all faces to compoud. + std::shared_ptr aFacesCompound = GeomAlgoAPI_CompoundBuilder::compound(theFacesList); + if(!aFacesCompound.get()) { + return; + } + + // Map edges and faces. + const TopoDS_Shape& aFacesComp = aFacesCompound->impl(); + BOPCol_IndexedDataMapOfShapeListOfShape aMapEF; + BOPTools::MapShapesAndAncestors(aFacesComp, TopAbs_EDGE, TopAbs_FACE, aMapEF); + if(aMapEF.IsEmpty()) { + return; + } + + // Get all faces with common edges and free faces. + NCollection_Map aFreeFaces; + NCollection_Vector> aFacesWithCommonEdges; + for(BOPCol_IndexedDataMapOfShapeListOfShape::Iterator anIter(aMapEF); anIter.More(); anIter.Next()) { + const TopoDS_Shape& aShape = anIter.Key(); + BOPCol_ListOfShape& aListOfShape = anIter.ChangeValue(); + if(aListOfShape.IsEmpty()) { + continue; + } + else if(aListOfShape.Size() == 1) { + aFreeFaces.Add(aListOfShape.First()); + aListOfShape.Clear(); + } else { + NCollection_Map aTempMap; + aTempMap.Add(aListOfShape.First()); + aTempMap.Add(aListOfShape.Last()); + aFreeFaces.Remove(aListOfShape.First()); + aFreeFaces.Remove(aListOfShape.Last()); + aListOfShape.Clear(); + for(NCollection_Map::Iterator aTempIter(aTempMap); aTempIter.More(); aTempIter.Next()) { + const TopoDS_Shape& aTempShape = aTempIter.Value(); + for(BOPCol_IndexedDataMapOfShapeListOfShape::Iterator anIter(aMapEF); anIter.More(); anIter.Next()) { + BOPCol_ListOfShape& aTempListOfShape = anIter.ChangeValue(); + if(aTempListOfShape.IsEmpty()) { + continue; + } else if(aTempListOfShape.Size() == 1 && aTempListOfShape.First() == aTempShape) { + aTempListOfShape.Clear(); + } else if(aTempListOfShape.Size() > 1) { + if(aTempListOfShape.First() == aTempShape) { + aTempMap.Add(aTempListOfShape.Last()); + aFreeFaces.Remove(aTempListOfShape.Last()); + aTempListOfShape.Clear(); + } else if(aTempListOfShape.Last() == aTempShape) { + aTempMap.Add(aTempListOfShape.First()); + aFreeFaces.Remove(aTempListOfShape.First()); + aTempListOfShape.Clear(); + } + } + } + } + aFacesWithCommonEdges.Append(aTempMap); + } + } + + // Make shells from faces with common edges. + NCollection_Vector aShells; + for(NCollection_Vector>::Iterator anIter(aFacesWithCommonEdges); anIter.More(); anIter.Next()) { + TopoDS_Shell aShell; + TopoDS_Builder aBuilder; + aBuilder.MakeShell(aShell); + const NCollection_Map& aShapesMap = anIter.Value(); + for(NCollection_Map::Iterator aShIter(aShapesMap); aShIter.More(); aShIter.Next()) { + const TopoDS_Shape& aFace = aShIter.Value(); + aBuilder.Add(aShell, aFace); + } + std::shared_ptr aGeomShell(std::make_shared()); + aGeomShell->setImpl(new TopoDS_Shape(aShell)); + theShells.push_back(aGeomShell); + } + + // Adding free faces. + for(NCollection_Map::Iterator aShIter(aFreeFaces); aShIter.More(); aShIter.Next()) { + const TopoDS_Shape& aFace = aShIter.Value(); + std::shared_ptr aGeomFace(std::make_shared()); + aGeomFace->setImpl(new TopoDS_Shape(aFace)); + theFreeFaces.push_back(aGeomFace); + } +} diff --git a/src/GeomAlgoAPI/GeomAlgoAPI_ShapeTools.h b/src/GeomAlgoAPI/GeomAlgoAPI_ShapeTools.h new file mode 100644 index 000000000..9dce03c2d --- /dev/null +++ b/src/GeomAlgoAPI/GeomAlgoAPI_ShapeTools.h @@ -0,0 +1,40 @@ +// Copyright (C) 2014-20xx CEA/DEN, EDF R&D + +// File: GeomAlgoAPI_ShapeTools.h +// Created: 3 August 2015 +// Author: Dmitry Bobylev + +#ifndef GeomAlgoAPI_ShapeTools_H_ +#define GeomAlgoAPI_ShapeTools_H_ + +#include +#include +#include + +#include + +/** \class GeomAlgoAPI_ShapeTools + * \ingroup DataAlgo + * \brief + */ +class GEOMALGOAPI_EXPORT GeomAlgoAPI_ShapeTools +{ +public: + /// \return the total volume of the solids of the current shape or 0.0 if it can be computed. + static double volume(std::shared_ptr theShape); + + /// \return the centre of mass of the current face. The coordinates returned for the center of mass + /// are expressed in the absolute Cartesian coordinate system. (This function works only for surfaces). + static std::shared_ptr centreOfMass(std::shared_ptr theShape); + + /** \brief Combines faces with common edges to shells + * \param[in] theFacesList list of faces to be combined. + * \param[out] theShells resulting shells. + * \param[out] theFreeFaces faces that does not have common edges. + */ + static void combineFacesToShells(const ListOfShape& theFacesList, + ListOfShape& theShells, + ListOfShape& theFreeFaces); +}; + +#endif diff --git a/src/GeomAlgoAPI/GeomAlgoAPI_Transform.cpp b/src/GeomAlgoAPI/GeomAlgoAPI_Transform.cpp index 65840c273..e5409c49e 100644 --- a/src/GeomAlgoAPI/GeomAlgoAPI_Transform.cpp +++ b/src/GeomAlgoAPI/GeomAlgoAPI_Transform.cpp @@ -6,7 +6,7 @@ #include -#include +#include #include #include @@ -74,7 +74,7 @@ const bool GeomAlgoAPI_Transform::isValid() const const bool GeomAlgoAPI_Transform::hasVolume() const { bool hasVolume(false); - if(isValid() && (GeomAlgoAPI_ShapeProps::volume(myShape) > Precision::Confusion())) { + if(isValid() && (GeomAlgoAPI_ShapeTools::volume(myShape) > Precision::Confusion())) { hasVolume = true; } return hasVolume; diff --git a/src/GeomValidators/GeomValidators_ZeroOffset.cpp b/src/GeomValidators/GeomValidators_ZeroOffset.cpp index 63e6d5f89..f2857f935 100644 --- a/src/GeomValidators/GeomValidators_ZeroOffset.cpp +++ b/src/GeomValidators/GeomValidators_ZeroOffset.cpp @@ -43,7 +43,7 @@ bool GeomValidators_ZeroOffset::isValid(const std::shared_ptr& anIt++; if(aSelectedMethod == aCreationMethod) { - if(aToSize == 0.0 && aFromSize == 0.0) { + if(aToSize == -aFromSize) { return false; } else { return true; @@ -83,7 +83,7 @@ bool GeomValidators_ZeroOffset::isValid(const std::shared_ptr& } if(((!aFromShape && !aToShape) || ((aFromShape && aToShape) && aFromShape->isEqual(aToShape))) - && (aFromSize == 0.0 && aToSize == 0.0)) { + && (aFromSize == -aToSize)) { return false; } diff --git a/src/PartSet/PartSet_WidgetSketchLabel.cpp b/src/PartSet/PartSet_WidgetSketchLabel.cpp index f0bfdc8a2..b2883760d 100644 --- a/src/PartSet/PartSet_WidgetSketchLabel.cpp +++ b/src/PartSet/PartSet_WidgetSketchLabel.cpp @@ -26,7 +26,7 @@ #include #include -#include +#include #include #include #include @@ -155,7 +155,7 @@ void PartSet_WidgetSketchLabel::updateByPlaneSelected(const ModuleBase_ViewerPrs // orienting projection if(aBaseShape.get() != NULL) { - std::shared_ptr aCenterPnt = GeomAlgoAPI_ShapeProps::centreOfMass(aGShape); + std::shared_ptr aCenterPnt = GeomAlgoAPI_ShapeTools::centreOfMass(aGShape); gp_Pnt aPnt = aCenterPnt->impl(); aPnt.Translate(aDir->impl().XYZ() * (10 * Precision::Confusion()));