From 05a0f11e3b7c1060b8aee2e34f83235461861183 Mon Sep 17 00:00:00 2001 From: dbv Date: Wed, 29 Jul 2015 15:26:44 +0300 Subject: [PATCH] Multiple selection in placement --- .../FeaturesPlugin_Placement.cpp | 202 ++++++++++-------- src/FeaturesPlugin/FeaturesPlugin_Placement.h | 26 +-- src/FeaturesPlugin/placement_widget.xml | 29 ++- src/GeomAlgoAPI/CMakeLists.txt | 2 + src/GeomAlgoAPI/GeomAlgoAPI.i | 2 + src/GeomAlgoAPI/GeomAlgoAPI_Transform.cpp | 105 +++++++++ src/GeomAlgoAPI/GeomAlgoAPI_Transform.h | 66 ++++++ 7 files changed, 308 insertions(+), 124 deletions(-) create mode 100644 src/GeomAlgoAPI/GeomAlgoAPI_Transform.cpp create mode 100644 src/GeomAlgoAPI/GeomAlgoAPI_Transform.h diff --git a/src/FeaturesPlugin/FeaturesPlugin_Placement.cpp b/src/FeaturesPlugin/FeaturesPlugin_Placement.cpp index 28ae85234..ee954f593 100644 --- a/src/FeaturesPlugin/FeaturesPlugin_Placement.cpp +++ b/src/FeaturesPlugin/FeaturesPlugin_Placement.cpp @@ -17,6 +17,7 @@ #include #include #include +#include #define _MODIFIEDF_TAG 1 #define _MODIFIEDE_TAG 2 @@ -28,144 +29,155 @@ FeaturesPlugin_Placement::FeaturesPlugin_Placement() void FeaturesPlugin_Placement::initAttributes() { - /* Modification for specification of 1.3.0 + AttributeSelectionListPtr aSelection = std::dynamic_pointer_cast(data()->addAttribute( - FeaturesPlugin_Placement::LIST_ID(), ModelAPI_AttributeSelectionList::typeId())); + OBJECTS_LIST_ID(), ModelAPI_AttributeSelectionList::typeId())); // extrusion works with faces always aSelection->setSelectionType("SOLID"); - */ - data()->addAttribute(FeaturesPlugin_Placement::BASE_OBJECT_ID(), ModelAPI_AttributeSelection::typeId()); - data()->addAttribute(FeaturesPlugin_Placement::ATTRACT_OBJECT_ID(), ModelAPI_AttributeSelection::typeId()); - data()->addAttribute(FeaturesPlugin_Placement::REVERSE_ID(), ModelAPI_AttributeBoolean::typeId()); - data()->addAttribute(FeaturesPlugin_Placement::CENTERING_ID(), ModelAPI_AttributeBoolean::typeId()); + + data()->addAttribute(START_FACE_ID(), ModelAPI_AttributeSelection::typeId()); + data()->addAttribute(END_FACE_ID(), ModelAPI_AttributeSelection::typeId()); + data()->addAttribute(REVERSE_ID(), ModelAPI_AttributeBoolean::typeId()); + data()->addAttribute(CENTERING_ID(), ModelAPI_AttributeBoolean::typeId()); } void FeaturesPlugin_Placement::execute() { - // Verify the base face - std::shared_ptr anObjRef = std::dynamic_pointer_cast< - ModelAPI_AttributeSelection>(data()->attribute(FeaturesPlugin_Placement::BASE_OBJECT_ID())); - if (!anObjRef) + // Getting objects. + ListOfShape anObjects; + std::list aContextes; + AttributeSelectionListPtr anObjectsSelList = selectionList(OBJECTS_LIST_ID()); + if(anObjectsSelList->size() == 0) { return; + } + for(int anObjectsIndex = 0; anObjectsIndex < anObjectsSelList->size(); anObjectsIndex++) { + std::shared_ptr anObjectAttr = anObjectsSelList->value(anObjectsIndex); + std::shared_ptr anObject = anObjectAttr->value(); + if(!anObject.get()) { + return; + } + anObjects.push_back(anObject); + aContextes.push_back(anObjectAttr->context()); + } - std::shared_ptr aBaseShape = - std::dynamic_pointer_cast(anObjRef->value()); - if (!aBaseShape) + // Verify the start face + AttributeSelectionPtr anObjRef = selection(START_FACE_ID()); + if(!anObjRef) { + return; + } + std::shared_ptr aStartFace = anObjRef->value(); + if(!aStartFace || !GeomAPI_Face(aStartFace).isPlanar()) { + static const std::string aSelectionError = "The start face selection is bad"; + setError(aSelectionError); return; + } - std::shared_ptr aBaseObject; + + std::shared_ptr aStartShape; ResultPtr aContextRes = anObjRef->context(); if (aContextRes.get()) { - aBaseObject = aContextRes->shape(); + aStartShape = aContextRes->shape(); } - if (!aBaseObject.get()) { - static const std::string aContextError = "The base selection context is bad"; + if(!aStartShape.get()) { + static const std::string aContextError = "The start face selection context is bad"; setError(aContextError); return; } - // Verify the attractive face - anObjRef = std::dynamic_pointer_cast( - data()->attribute(FeaturesPlugin_Placement::ATTRACT_OBJECT_ID())); - - std::shared_ptr aSlaveShape = - std::dynamic_pointer_cast(anObjRef->value()); - if (!aSlaveShape) + // Verify the end face + anObjRef = selection(END_FACE_ID()); + std::shared_ptr anEndFace = anObjRef->value(); + if(!anEndFace || !GeomAPI_Face(anEndFace).isPlanar()) { + static const std::string aSelectionError = "The end face selection is bad"; + setError(aSelectionError); return; + } - std::shared_ptr aSlaveObject; + std::shared_ptr anEndShape; aContextRes = anObjRef->context(); - if (aContextRes.get()) { - aSlaveObject = aContextRes->shape(); + if(aContextRes.get()) { + anEndShape = aContextRes->shape(); } - if (!aSlaveObject.get()) { - static const std::string aContextError = "The tool selection context is bad"; + if(!anEndShape.get()) { + static const std::string aContextError = "The end face selection context is bad"; setError(aContextError); return; } - // Verify planarity of faces and linearity of edges - std::shared_ptr aShapes[2] = {aBaseShape, aSlaveShape}; - for (int i = 0; i < 2; i++) { - if (aShapes[i]->isFace()) { - std::shared_ptr aFace(new GeomAPI_Face(aShapes[i])); - if (!aFace->isPlanar()) { - static const std::string aPlanarityError = "One of selected faces is not planar"; - setError(aPlanarityError); - return; - } - } - else if (aShapes[i]->isEdge()) { - std::shared_ptr anEdge(new GeomAPI_Edge(aShapes[i])); - if (!anEdge->isLine()) { - static const std::string aLinearityError = "One of selected endges is not linear"; - setError(aLinearityError); - return; - } - } - } - // Flags of the Placement - AttributeBooleanPtr aBoolAttr = std::dynamic_pointer_cast( - data()->attribute(FeaturesPlugin_Placement::REVERSE_ID())); - bool isReverse = aBoolAttr->value(); - aBoolAttr = std::dynamic_pointer_cast( - data()->attribute(FeaturesPlugin_Placement::CENTERING_ID())); - bool isCentering = aBoolAttr->value(); + bool isReverse = boolean(REVERSE_ID())->value(); + bool isCentering = boolean(CENTERING_ID())->value(); bool isPart = aContextRes->groupName() == ModelAPI_ResultPart::group(); - std::shared_ptr aResultBody; - if (!isPart) - aResultBody = document()->createBody(data()); - GeomAlgoAPI_Placement aFeature( - aSlaveObject, aBaseObject, aSlaveShape, aBaseShape, isReverse, isCentering, isPart); - if(!aFeature.isDone()) { + // Getting transformation. + GeomAlgoAPI_Placement aPlacementAlgo( + aStartShape, anEndShape, aStartFace, anEndFace, isReverse, isCentering, true); + if(!aPlacementAlgo.isDone()) { static const std::string aFeatureError = "Placement algorithm failed"; setError(aFeatureError); return; } + std::shared_ptr aTrsf = aPlacementAlgo.transformation(); + + // Applying transformation to each object. + int aResultIndex = 0; + std::list::iterator aContext = aContextes.begin(); + for(ListOfShape::iterator anObjectsIt = anObjects.begin(); anObjectsIt != anObjects.end(); + anObjectsIt++, aContext++) { + + if (isPart) { // for part results just set transformation + ResultPartPtr anOrigin = std::dynamic_pointer_cast(aContextRes); + ResultPartPtr aResultPart = document()->copyPart(firstResult(), anOrigin); + aResultPart->setTrsf(aContextRes, aTrsf); + setResult(aResultPart); + } else { + std::shared_ptr aBaseShape = *anObjectsIt; + GeomAlgoAPI_Transform aTransformAlgo(aBaseShape, aTrsf); + + // Checking that the algorithm worked properly. + if(!aTransformAlgo.isDone()) { + static const std::string aFeatureError = "Transform algorithm failed"; + setError(aFeatureError); + break; + } + if(aTransformAlgo.shape()->isNull()) { + static const std::string aShapeError = "Resulting shape is Null"; + setError(aShapeError); + break; + } + if(!aTransformAlgo.isValid()) { + std::string aFeatureError = "Warning: resulting shape is not valid"; + setError(aFeatureError); + break; + } - // Check if shape is valid - if (aFeature.shape()->isNull()) { - static const std::string aShapeError = "Resulting shape is Null"; - setError(aShapeError); - return; - } - if(!aFeature.isValid()) { - std::string aFeatureError = "Warning: resulting shape is not valid"; - setError(aFeatureError); - return; - } - - if (isPart) { // for part results just set transformation - ResultPartPtr anOrigin = std::dynamic_pointer_cast(aContextRes); - ResultPartPtr aResultPart = document()->copyPart(firstResult(), anOrigin); - aResultPart->setTrsf(aContextRes, aFeature.transformation()); - setResult(aResultPart); - } else { - //LoadNamingDS - LoadNamingDS(aFeature, aResultBody, aSlaveObject); - - setResult(aResultBody); + //LoadNamingDS + std::shared_ptr aResultBody = document()->createBody(data(), aResultIndex); + LoadNamingDS(aTransformAlgo, aResultBody, aBaseShape); + setResult(aResultBody, aResultIndex); + } + aResultIndex++; } + + // Remove the rest results if there were produced in the previous pass. + removeResults(aResultIndex); } //============================================================================ -void FeaturesPlugin_Placement::LoadNamingDS( - GeomAlgoAPI_Placement& theFeature, - std::shared_ptr theResultBody, - std::shared_ptr theSlaveObject) +void FeaturesPlugin_Placement::LoadNamingDS(GeomAlgoAPI_Transform& theTransformAlgo, + std::shared_ptr theResultBody, + std::shared_ptr theSlaveObject) { //load result - theResultBody->storeModified(theSlaveObject, theFeature.shape()); // the initial Slave, the resulting Slave + theResultBody->storeModified(theSlaveObject, theTransformAlgo.shape()); // the initial Slave, the resulting Slave + + std::shared_ptr aSubShapes = theTransformAlgo.mapOfShapes(); - GeomAPI_DataMapOfShapeShape* aSubShapes = new GeomAPI_DataMapOfShapeShape(); - theFeature.mapOfShapes(*aSubShapes); - // put modifed faces in DF std::string aModName = "Modified"; - theResultBody->loadAndOrientModifiedShapes(theFeature.makeShape(), theSlaveObject, _FACE, _MODIFIEDF_TAG, aModName, *aSubShapes); - + theResultBody->loadAndOrientModifiedShapes(theTransformAlgo.makeShape().get(), + theSlaveObject, _FACE, + _MODIFIEDF_TAG, aModName, *aSubShapes.get()); } diff --git a/src/FeaturesPlugin/FeaturesPlugin_Placement.h b/src/FeaturesPlugin/FeaturesPlugin_Placement.h index b83d07e95..46acd79e2 100644 --- a/src/FeaturesPlugin/FeaturesPlugin_Placement.h +++ b/src/FeaturesPlugin/FeaturesPlugin_Placement.h @@ -10,6 +10,7 @@ #include "FeaturesPlugin.h" #include #include +#include class ModelAPI_ResultBody; class GeomAPI_Shape; @@ -31,25 +32,26 @@ class FeaturesPlugin_Placement : public ModelAPI_Feature static const std::string MY_PLACEMENT_ID("Placement"); return MY_PLACEMENT_ID; } + /// attribute name of references sketch entities list, it should contain a sketch result or /// a pair a sketch result to sketch face - /*Modification for specification of 1.3.0 - inline static const std::string& LIST_ID() + inline static const std::string& OBJECTS_LIST_ID() { - static const std::string MY_GROUP_LIST_ID("base"); - return MY_GROUP_LIST_ID; - }*/ + static const std::string MY_OBJECTS_LIST_ID("placement_objects_list"); + return MY_OBJECTS_LIST_ID; + } + /// attribute name of referenced object - inline static const std::string& BASE_OBJECT_ID() + inline static const std::string& START_FACE_ID() { - static const std::string MY_BASE_OBJECT_ID("placement_base_object"); - return MY_BASE_OBJECT_ID; + static const std::string MY_START_FACE_ID("placement_start_face"); + return MY_START_FACE_ID; } /// attribute name of attractable face - inline static const std::string& ATTRACT_OBJECT_ID() + inline static const std::string& END_FACE_ID() { - static const std::string MY_ATTRACT_OBJECT_ID("placement_attractable_object"); - return MY_ATTRACT_OBJECT_ID; + static const std::string MY_END_FACE_ID("placement_end_face"); + return MY_END_FACE_ID; } /// attribute name of flag of reverse direction inline static const std::string& REVERSE_ID() @@ -81,7 +83,7 @@ class FeaturesPlugin_Placement : public ModelAPI_Feature FeaturesPlugin_Placement(); private: /// Load Naming data structure of the feature to the document - void LoadNamingDS(GeomAlgoAPI_Placement& theFeature, + void LoadNamingDS(GeomAlgoAPI_Transform& theTransformAlgo, std::shared_ptr theResultBody, std::shared_ptr theSlaveObject); }; diff --git a/src/FeaturesPlugin/placement_widget.xml b/src/FeaturesPlugin/placement_widget.xml index 2e6b8f237..ec6f228b0 100644 --- a/src/FeaturesPlugin/placement_widget.xml +++ b/src/FeaturesPlugin/placement_widget.xml @@ -1,28 +1,23 @@ - - - + - - diff --git a/src/GeomAlgoAPI/CMakeLists.txt b/src/GeomAlgoAPI/CMakeLists.txt index 3bc403732..6d14a195d 100644 --- a/src/GeomAlgoAPI/CMakeLists.txt +++ b/src/GeomAlgoAPI/CMakeLists.txt @@ -30,6 +30,7 @@ SET(PROJECT_HEADERS GeomAlgoAPI_BREPExport.h GeomAlgoAPI_STEPExport.h GeomAlgoAPI_IGESExport.h + GeomAlgoAPI_Transform.h ) SET(PROJECT_SOURCES @@ -56,6 +57,7 @@ SET(PROJECT_SOURCES GeomAlgoAPI_BREPExport.cpp GeomAlgoAPI_STEPExport.cpp GeomAlgoAPI_IGESExport.cpp + GeomAlgoAPI_Transform.cpp ) SET(PROJECT_LIBRARIES diff --git a/src/GeomAlgoAPI/GeomAlgoAPI.i b/src/GeomAlgoAPI/GeomAlgoAPI.i index 6a49f1fae..5d102832a 100644 --- a/src/GeomAlgoAPI/GeomAlgoAPI.i +++ b/src/GeomAlgoAPI/GeomAlgoAPI.i @@ -25,6 +25,7 @@ #include "GeomAlgoAPI_IGESImport.h" #include "GeomAlgoAPI_STEPImport.h" #include "GeomAlgoAPI_Tools.h" + #include "GeomAlgoAPI_Transform.h" #include #include @@ -64,6 +65,7 @@ %include "GeomAlgoAPI_IGESImport.h" %include "GeomAlgoAPI_STEPImport.h" %include "GeomAlgoAPI_Tools.h" +%include "GeomAlgoAPI_Transform.h" %typemap(out) std::list< std::shared_ptr< GeomAPI_Shape > >::value_type & { $result = SWIG_NewPointerObj(SWIG_as_voidptr(new std::shared_ptr(*$1)), $descriptor(std::shared_ptr *), SWIG_POINTER_OWN | 0 ); diff --git a/src/GeomAlgoAPI/GeomAlgoAPI_Transform.cpp b/src/GeomAlgoAPI/GeomAlgoAPI_Transform.cpp new file mode 100644 index 000000000..65840c273 --- /dev/null +++ b/src/GeomAlgoAPI/GeomAlgoAPI_Transform.cpp @@ -0,0 +1,105 @@ +// Copyright (C) 2014-20xx CEA/DEN, EDF R&D + +// File: GeomAlgoAPI_Transform.cpp +// Created: 29 July 2015 +// Author: Dmitry Bobylev + +#include + +#include + +#include +#include +#include +#include + +//================================================================================================= +GeomAlgoAPI_Transform::GeomAlgoAPI_Transform(std::shared_ptr theSourceShape, + std::shared_ptr theTrsf) +: myDone(false), + myTrsf(theTrsf), + myShape(new GeomAPI_Shape()), + myMap(new GeomAPI_DataMapOfShapeShape()), + myMkShape(new GeomAlgoAPI_MakeShape()) +{ + build(theSourceShape, theTrsf); +} + +//================================================================================================= +void GeomAlgoAPI_Transform::build(std::shared_ptr theSourceShape, + std::shared_ptr theTrsf) +{ + if(!theSourceShape || !theTrsf) { + return; + } + + const TopoDS_Shape& aSourceShape = theSourceShape->impl(); + const gp_Trsf& aTrsf = theTrsf->impl(); + + if(aSourceShape.IsNull()) { + return; + } + + BRepBuilderAPI_Transform* aBuilder = new BRepBuilderAPI_Transform(aSourceShape, aTrsf, true); + if(!aBuilder) { + return; + } + + myDone = aBuilder->IsDone() == Standard_True; + if(!myDone) { + return; + } + + TopoDS_Shape aResult = aBuilder->Shape(); + + // Fill data map to keep correct orientation of sub-shapes. + for(TopExp_Explorer anExp(aResult, TopAbs_FACE); anExp.More(); anExp.Next()) { + std::shared_ptr aCurrentShape(new GeomAPI_Shape()); + aCurrentShape->setImpl(new TopoDS_Shape(anExp.Current())); + myMap->bind(aCurrentShape, aCurrentShape); + } + + myMkShape->setImpl(aBuilder); + myShape->setImpl(new TopoDS_Shape(aResult)); +} + +//================================================================================================= +const bool GeomAlgoAPI_Transform::isValid() const +{ + BRepCheck_Analyzer aChecker(myShape->impl()); + return (aChecker.IsValid() == Standard_True); +} + +//================================================================================================= +const bool GeomAlgoAPI_Transform::hasVolume() const +{ + bool hasVolume(false); + if(isValid() && (GeomAlgoAPI_ShapeProps::volume(myShape) > Precision::Confusion())) { + hasVolume = true; + } + return hasVolume; +} + +//================================================================================================= +const std::shared_ptr& GeomAlgoAPI_Transform::shape() const +{ + return myShape; +} + +//================================================================================================= +std::shared_ptr GeomAlgoAPI_Transform::mapOfShapes() const +{ + return myMap; +} + +//================================================================================================= +std::shared_ptr GeomAlgoAPI_Transform::makeShape() const +{ + return myMkShape; +} + +//================================================================================================= +std::shared_ptr GeomAlgoAPI_Transform::transformation() const +{ + return myTrsf; +} diff --git a/src/GeomAlgoAPI/GeomAlgoAPI_Transform.h b/src/GeomAlgoAPI/GeomAlgoAPI_Transform.h new file mode 100644 index 000000000..aeb085ad3 --- /dev/null +++ b/src/GeomAlgoAPI/GeomAlgoAPI_Transform.h @@ -0,0 +1,66 @@ +// Copyright (C) 2014-20xx CEA/DEN, EDF R&D + +// File: GeomAlgoAPI_Transform.h +// Created: 29 July 2015 +// Author: Dmitry Bobylev + +#ifndef GeomAlgoAPI_Transform_H_ +#define GeomAlgoAPI_Transform_H_ + +#include +#include +#include +#include +#include + +/** \class GeomAlgoAPI_Transform + * \ingroup DataAlgo + * \brief Creates a copy of the object by transformating it. + */ +class GeomAlgoAPI_Transform : public GeomAPI_Interface +{ +public: + /** \brief Creates an object which is obtained from current object by transformating it. + * \param[in] theSourceShape a shape to be transformed. + * \param[in] theTrsf transformation. + */ + GEOMALGOAPI_EXPORT GeomAlgoAPI_Transform(std::shared_ptr theSourceShape, + std::shared_ptr theTrsf); + + /// \return true if algorithm succeed. + GEOMALGOAPI_EXPORT const bool isDone() const + { return myDone; } + + /// \return true if resulting shape is valid. + GEOMALGOAPI_EXPORT const bool isValid() const; + + /// \return true if resulting shape has volume. + GEOMALGOAPI_EXPORT const bool hasVolume() const; + + /// \return result of the transformation algorithm. + GEOMALGOAPI_EXPORT const std::shared_ptr& shape() const; + + /// \return map of sub-shapes of the result. To be used for History keeping. + GEOMALGOAPI_EXPORT std::shared_ptr mapOfShapes() const; + + /// \return interface for for History processing. + GEOMALGOAPI_EXPORT std::shared_ptr makeShape() const; + + /// \return the transformation. + GEOMALGOAPI_EXPORT std::shared_ptr transformation() const; + +private: + /// Builds resulting shape. + void build(std::shared_ptr theSourceShape, + std::shared_ptr theTrsf); + +private: + /// Fields. + bool myDone; + std::shared_ptr myTrsf; + std::shared_ptr myShape; + std::shared_ptr myMap; + std::shared_ptr myMkShape; +}; + +#endif -- 2.39.2