From a6b5300a8b356e933d4778d93bb78f3cc9d7b9cb Mon Sep 17 00:00:00 2001 From: mpv Date: Mon, 20 Oct 2014 12:23:27 +0400 Subject: [PATCH] Composite Feature implementation. Sketch now is Composite. --- .../FeaturesPlugin_Extrusion.cpp | 2 + src/Model/Model_AttributeRefList.cpp | 17 +++- src/Model/Model_AttributeRefList.h | 5 +- src/Model/Model_AttributeSelection.cpp | 94 +++++++++++++++---- src/Model/Model_AttributeSelection.h | 8 ++ src/Model/Model_Data.h | 1 + src/ModelAPI/CMakeLists.txt | 1 + src/ModelAPI/ModelAPI_AttributeRefList.h | 5 +- src/ModelAPI/ModelAPI_CompositeFeature.h | 32 +++++++ src/ModelAPI/ModelAPI_Object.h | 2 +- src/ModuleBase/ModuleBase_Operation.cpp | 11 ++- src/ModuleBase/ModuleBase_Operation.h | 8 +- src/PartSet/PartSet_Module.cpp | 2 +- src/PartSet/PartSet_OperationFeatureBase.cpp | 4 +- src/PartSet/PartSet_OperationFeatureBase.h | 6 +- .../PartSet_OperationFeatureCreate.cpp | 13 +-- src/PartSet/PartSet_OperationFeatureCreate.h | 6 +- src/PartSet/PartSet_OperationFeatureEdit.cpp | 5 +- src/PartSet/PartSet_OperationFeatureEdit.h | 5 +- .../PartSet_OperationFeatureEditMulti.cpp | 4 +- .../PartSet_OperationFeatureEditMulti.h | 6 +- src/PartSet/PartSet_OperationSketch.cpp | 4 +- src/PartSet/PartSet_OperationSketch.h | 2 +- src/PartSet/PartSet_OperationSketchBase.h | 2 +- src/PartSet/PartSet_Tools.cpp | 19 ++-- src/PartSet/PartSet_Tools.h | 10 +- src/SketchPlugin/SketchPlugin_Feature.cpp | 5 +- src/SketchPlugin/SketchPlugin_Feature.h | 9 +- src/SketchPlugin/SketchPlugin_Sketch.cpp | 23 ++++- src/SketchPlugin/SketchPlugin_Sketch.h | 15 ++- .../SketchSolver_ConstraintGroup.cpp | 6 +- .../SketchSolver_ConstraintGroup.h | 10 +- .../SketchSolver_ConstraintManager.cpp | 18 ++-- .../SketchSolver_ConstraintManager.h | 4 +- 34 files changed, 255 insertions(+), 109 deletions(-) create mode 100644 src/ModelAPI/ModelAPI_CompositeFeature.h diff --git a/src/FeaturesPlugin/FeaturesPlugin_Extrusion.cpp b/src/FeaturesPlugin/FeaturesPlugin_Extrusion.cpp index 60ee2b689..0e997edaf 100644 --- a/src/FeaturesPlugin/FeaturesPlugin_Extrusion.cpp +++ b/src/FeaturesPlugin/FeaturesPlugin_Extrusion.cpp @@ -35,6 +35,8 @@ void FeaturesPlugin_Extrusion::execute() return; boost::shared_ptr aFace = boost::dynamic_pointer_cast(aFaceRef->value()); + if (!aFace) + return; double aSize = data()->real(FeaturesPlugin_Extrusion::SIZE_ID())->value(); if (data()->boolean(FeaturesPlugin_Extrusion::REVERSE_ID())->value()) diff --git a/src/Model/Model_AttributeRefList.cpp b/src/Model/Model_AttributeRefList.cpp index 3d3af3467..014592f0d 100644 --- a/src/Model/Model_AttributeRefList.cpp +++ b/src/Model/Model_AttributeRefList.cpp @@ -26,7 +26,7 @@ void Model_AttributeRefList::remove(ObjectPtr theObject) owner()->data()->sendAttributeUpdated(this); } -int Model_AttributeRefList::size() +int Model_AttributeRefList::size() const { return myRef->Extent(); } @@ -46,6 +46,21 @@ list Model_AttributeRefList::list() return aResult; } +ObjectPtr Model_AttributeRefList::object(const int theIndex) const +{ + boost::shared_ptr aDoc = boost::dynamic_pointer_cast( + owner()->document()); + if (aDoc) { + const TDF_LabelList& aList = myRef->List(); + int anIndex = 0; + for (TDF_ListIteratorOfLabelList aLIter(aList); aLIter.More(); aLIter.Next(), anIndex++) { + if (anIndex == theIndex) + return aDoc->object(aLIter.Value()); + } + } + return ObjectPtr(); +} + Model_AttributeRefList::Model_AttributeRefList(TDF_Label& theLabel) { myIsInitialized = theLabel.FindAttribute(TDataStd_ReferenceList::GetID(), myRef) == Standard_True; diff --git a/src/Model/Model_AttributeRefList.h b/src/Model/Model_AttributeRefList.h index d784769e6..2b0edac1f 100644 --- a/src/Model/Model_AttributeRefList.h +++ b/src/Model/Model_AttributeRefList.h @@ -27,11 +27,14 @@ class Model_AttributeRefList : public ModelAPI_AttributeRefList MODEL_EXPORT virtual void remove(ObjectPtr theObject); /// Returns number of features in the list - MODEL_EXPORT virtual int size(); + MODEL_EXPORT virtual int size() const; /// Returns the list of features MODEL_EXPORT virtual std::list list(); + /// Returns the list of features + MODEL_EXPORT virtual ObjectPtr object(const int theIndex) const; + protected: /// Objects are created for features automatically MODEL_EXPORT Model_AttributeRefList(TDF_Label& theLabel); diff --git a/src/Model/Model_AttributeSelection.cpp b/src/Model/Model_AttributeSelection.cpp index 62659de6c..901686539 100644 --- a/src/Model/Model_AttributeSelection.cpp +++ b/src/Model/Model_AttributeSelection.cpp @@ -9,11 +9,16 @@ #include #include #include +#include #include #include #include +#include #include +#include +#include +#include using namespace std; @@ -29,24 +34,12 @@ void Model_AttributeSelection::setValue(const ResultPtr& theContext, if (!isOldContext) myRef.setValue(theContext); - // perform the selection - TNaming_Selector aSel(myRef.myRef->Label()); - TopoDS_Shape aNewShape = theSubShape ? theSubShape->impl() : TopoDS_Shape(); - TopoDS_Shape aContext; + if (theContext->groupName() == ModelAPI_ResultBody::group()) + selectBody(theContext, theSubShape); + else if (theContext->groupName() == ModelAPI_ResultConstruction::group()) + selectConstruction(theContext, theSubShape); - ResultBodyPtr aBody = boost::dynamic_pointer_cast(myRef.value()); - if (aBody) - aContext = aBody->shape()->impl(); - else { - ResultConstructionPtr aConstr = boost::dynamic_pointer_cast(myRef.value()); - if (aConstr) - aContext = aConstr->shape()->impl(); - else - throw std::invalid_argument("a result with shape is expected"); - } - aSel.Select(aNewShape, aContext); myIsInitialized = true; - owner()->data()->sendAttributeUpdated(this); } @@ -76,5 +69,74 @@ ResultPtr Model_AttributeSelection::context() { void Model_AttributeSelection::setObject(const boost::shared_ptr& theObject) { + ModelAPI_AttributeSelection::setObject(theObject); myRef.setObject(theObject); } + +void Model_AttributeSelection::selectBody( + const ResultPtr& theContext, const boost::shared_ptr& theSubShape) +{ + // perform the selection + TNaming_Selector aSel(myRef.myRef->Label()); + TopoDS_Shape aNewShape = theSubShape ? theSubShape->impl() : TopoDS_Shape(); + TopoDS_Shape aContext; + + ResultBodyPtr aBody = boost::dynamic_pointer_cast(myRef.value()); + if (aBody) + aContext = aBody->shape()->impl(); + else { + ResultConstructionPtr aConstr = boost::dynamic_pointer_cast(myRef.value()); + if (aConstr) + aContext = aConstr->shape()->impl(); + else + throw std::invalid_argument("a result with shape is expected"); + } + Handle(TNaming_NamedShape) aNS = TNaming_Tool::NamedShape(aNewShape, myRef.myRef->Label()); + TDF_Label aLab = aNS->Label(); + + aSel.Select(aNewShape, aContext); +} + +#include + +void Model_AttributeSelection::selectConstruction( + const ResultPtr& theContext, const boost::shared_ptr& theSubShape) +{ + FeaturePtr aContextFeature = owner()->document()->feature(theContext); + CompositeFeaturePtr aComposite = + boost::dynamic_pointer_cast(aContextFeature); + if (!aComposite || aComposite->numberOfSubs() == 0) { + return; // saving of context is enough: result construction contains exactly the needed shape + } + boost::shared_ptr aData = boost::dynamic_pointer_cast(owner()->data()); + TDF_Label aLab = aData->label(); + // identify the reuslts of sub-object of the composite by edges + const TopoDS_Shape& aSubShape = theSubShape->impl(); + TopTools_MapOfShape allEdges; + for(TopExp_Explorer anEdgeExp(aSubShape, TopAbs_EDGE); anEdgeExp.More(); anEdgeExp.Next()) { + BRepTools::Write(anEdgeExp.Current(), "D:\\selected.brep"); + allEdges.Add(anEdgeExp.Current()); + } + // iterate and store the result ids of sub-elements + Handle(TDataStd_ReferenceList) aRefs = TDataStd_ReferenceList::Set(aLab); + const int aSubNum = aComposite->numberOfSubs(); + for(int a = 0; a < aSubNum; a++) { + FeaturePtr aSub = aComposite->subFeature(a); + const std::list >& aResults = aSub->results(); + std::list >::const_iterator aRes = aResults.cbegin(); + // there may be many shapes (circle and center): register if at least one is in selection + for(; aRes != aResults.cend(); aRes++) { + ResultConstructionPtr aConstr = + boost::dynamic_pointer_cast(*aRes); + if (aConstr->shape()) { + const TopoDS_Shape& aResShape = aConstr->shape()->impl(); + BRepTools::Write(aResShape, "D:\\sub.brep"); + if (allEdges.Contains(aResShape)) { + boost::shared_ptr aSubData = boost::dynamic_pointer_cast(aSub->data()); + TDF_Label aSubLab = aSubData->label(); + aRefs->Append(aSubLab); + } + } + } + } +} diff --git a/src/Model/Model_AttributeSelection.h b/src/Model/Model_AttributeSelection.h index b380fef83..b41c4dffc 100644 --- a/src/Model/Model_AttributeSelection.h +++ b/src/Model/Model_AttributeSelection.h @@ -33,6 +33,14 @@ public: protected: /// Objects are created for features automatically MODEL_EXPORT Model_AttributeSelection(TDF_Label& theLabel); + /// Performs the selection for the body result (TNaming Selection) + + /// Performs the selection for the body result (TNaming selection) + virtual void selectBody( + const ResultPtr& theContext, const boost::shared_ptr& theSubShape); + /// Performs the selection for the construction result (selection by index) + virtual void selectConstruction( + const ResultPtr& theContext, const boost::shared_ptr& theSubShape); friend class Model_Data; }; diff --git a/src/Model/Model_Data.h b/src/Model/Model_Data.h index 45360d1a8..8aead1b5b 100644 --- a/src/Model/Model_Data.h +++ b/src/Model/Model_Data.h @@ -56,6 +56,7 @@ class Model_Data : public ModelAPI_Data friend class Model_AttributeReference; friend class Model_AttributeRefAttr; friend class Model_AttributeRefList; + friend class Model_AttributeSelection; public: /// Returns the name of the feature visible by the user in the object browser diff --git a/src/ModelAPI/CMakeLists.txt b/src/ModelAPI/CMakeLists.txt index b0299b5cf..13e4ee12e 100644 --- a/src/ModelAPI/CMakeLists.txt +++ b/src/ModelAPI/CMakeLists.txt @@ -8,6 +8,7 @@ SET(PROJECT_HEADERS ModelAPI_Session.h ModelAPI_Plugin.h ModelAPI_Feature.h + ModelAPI_CompositeFeature.h ModelAPI_Data.h ModelAPI_Object.h ModelAPI_Document.h diff --git a/src/ModelAPI/ModelAPI_AttributeRefList.h b/src/ModelAPI/ModelAPI_AttributeRefList.h index b8b5c700b..abb39beb6 100644 --- a/src/ModelAPI/ModelAPI_AttributeRefList.h +++ b/src/ModelAPI/ModelAPI_AttributeRefList.h @@ -36,11 +36,14 @@ class ModelAPI_AttributeRefList : public ModelAPI_Attribute MODELAPI_EXPORT virtual void remove(ObjectPtr theObject) = 0; /// Returns number of features in the list - MODELAPI_EXPORT virtual int size() = 0; + MODELAPI_EXPORT virtual int size() const = 0; /// Returns the list of features MODELAPI_EXPORT virtual std::list list() = 0; + /// Returns the referenced object by the zero-based index + MODELAPI_EXPORT virtual ObjectPtr object(const int theIndex) const = 0; + protected: /// Objects are created for features automatically MODELAPI_EXPORT ModelAPI_AttributeRefList() diff --git a/src/ModelAPI/ModelAPI_CompositeFeature.h b/src/ModelAPI/ModelAPI_CompositeFeature.h new file mode 100644 index 000000000..3c822e66e --- /dev/null +++ b/src/ModelAPI/ModelAPI_CompositeFeature.h @@ -0,0 +1,32 @@ +// File: ModelAPI_CompositeFeature.hxx +// Created: 20 Oct 2014 +// Author: Mikhail PONIKAROV + +#ifndef ModelAPI_CompositeFeature_H_ +#define ModelAPI_CompositeFeature_H_ + +#include "ModelAPI_Feature.h" + +/**\class ModelAPI_CompositeFeature + * \ingroup DataModel + * \brief Feature that consists of other features: like sketcher + * with edges inside. It just allows t oadd a feature to this feature only + * instead of adding in both document and this feature. + */ +class ModelAPI_CompositeFeature : public ModelAPI_Feature +{ +public: + /// Adds feature to the sketch and to its document + virtual boost::shared_ptr addFeature(std::string theID) = 0; + + /// Returns the number of sub-elements + virtual int numberOfSubs() const = 0; + + /// Returns the sub-feature by zero-base index + virtual boost::shared_ptr subFeature(const int theIndex) const = 0; +}; + +//! Pointer on the composite feature object +typedef boost::shared_ptr CompositeFeaturePtr; + +#endif diff --git a/src/ModelAPI/ModelAPI_Object.h b/src/ModelAPI/ModelAPI_Object.h index a00d6e3b8..7c539d7d5 100644 --- a/src/ModelAPI/ModelAPI_Object.h +++ b/src/ModelAPI/ModelAPI_Object.h @@ -34,7 +34,7 @@ class ModelAPI_Object } /// Returns the data manager of this object: attributes - virtual boost::shared_ptr data() + virtual boost::shared_ptr data() const { return myData; } diff --git a/src/ModuleBase/ModuleBase_Operation.cpp b/src/ModuleBase/ModuleBase_Operation.cpp index d55bdc3f0..19876df75 100644 --- a/src/ModuleBase/ModuleBase_Operation.cpp +++ b/src/ModuleBase/ModuleBase_Operation.cpp @@ -121,10 +121,15 @@ void ModuleBase_Operation::flushCreated() Events_Loop::loop()->flush(Events_Loop::eventByName(EVENT_OBJECT_CREATED)); } -FeaturePtr ModuleBase_Operation::createFeature(const bool theFlushMessage) +FeaturePtr ModuleBase_Operation::createFeature( + const bool theFlushMessage, CompositeFeaturePtr theCompositeFeature) { - boost::shared_ptr aDoc = document(); - myFeature = aDoc->addFeature(getDescription()->operationId().toStdString()); + if (theCompositeFeature) { + myFeature = theCompositeFeature->addFeature(getDescription()->operationId().toStdString()); + } else { + boost::shared_ptr aDoc = document(); + myFeature = aDoc->addFeature(getDescription()->operationId().toStdString()); + } if (myFeature) { // TODO: generate an error if feature was not created myIsModified = true; // Model update should call "execute" of a feature. diff --git a/src/ModuleBase/ModuleBase_Operation.h b/src/ModuleBase/ModuleBase_Operation.h index dbf2b3406..80cab9e12 100644 --- a/src/ModuleBase/ModuleBase_Operation.h +++ b/src/ModuleBase/ModuleBase_Operation.h @@ -11,7 +11,7 @@ #include #include -#include +#include #include #include @@ -192,8 +192,10 @@ signals: /// Creates an operation new feature /// \param theFlushMessage the flag whether the create message should be flushed - /// \returns the created feature - virtual FeaturePtr createFeature(const bool theFlushMessage = true); + /// \param theCompositeFeature the feature that must be used for adding the created object or null + /// \returns the created + virtual FeaturePtr createFeature(const bool theFlushMessage = true, + CompositeFeaturePtr theCompositeFeature = CompositeFeaturePtr()); /// Verifies whether this operator can be commited. /// \return Returns TRUE if current operation can be committed, e.g. all parameters are filled diff --git a/src/PartSet/PartSet_Module.cpp b/src/PartSet/PartSet_Module.cpp index a44256ea7..15742d1b9 100644 --- a/src/PartSet/PartSet_Module.cpp +++ b/src/PartSet/PartSet_Module.cpp @@ -421,7 +421,7 @@ ModuleBase_Operation* PartSet_Module::createOperation(const std::string& theCmdI anOperation = new PartSet_OperationSketch(theCmdId.c_str(), this); } else { ModuleBase_Operation* aCurOperation = myWorkshop->currentOperation(); - FeaturePtr aSketch; + CompositeFeaturePtr aSketch; PartSet_OperationSketchBase* aPrevOp = dynamic_cast(aCurOperation); if (aPrevOp) { aSketch = aPrevOp->sketch(); diff --git a/src/PartSet/PartSet_OperationFeatureBase.cpp b/src/PartSet/PartSet_OperationFeatureBase.cpp index 3e0c412ec..9955fa5f0 100644 --- a/src/PartSet/PartSet_OperationFeatureBase.cpp +++ b/src/PartSet/PartSet_OperationFeatureBase.cpp @@ -44,7 +44,7 @@ using namespace std; PartSet_OperationFeatureBase::PartSet_OperationFeatureBase(const QString& theId, QObject* theParent, - FeaturePtr theFeature) + CompositeFeaturePtr theFeature) : PartSet_OperationSketchBase(theId, theParent), mySketch(theFeature) { @@ -54,7 +54,7 @@ PartSet_OperationFeatureBase::~PartSet_OperationFeatureBase() { } -FeaturePtr PartSet_OperationFeatureBase::sketch() const +CompositeFeaturePtr PartSet_OperationFeatureBase::sketch() const { return mySketch; } diff --git a/src/PartSet/PartSet_OperationFeatureBase.h b/src/PartSet/PartSet_OperationFeatureBase.h index baef75f9f..a9651e6f8 100644 --- a/src/PartSet/PartSet_OperationFeatureBase.h +++ b/src/PartSet/PartSet_OperationFeatureBase.h @@ -29,13 +29,13 @@ Q_OBJECT /// \param theId the feature identifier /// \param theParent the operation parent /// \param theSketch the parent feature - PartSet_OperationFeatureBase(const QString& theId, QObject* theParent, FeaturePtr theSketch); + PartSet_OperationFeatureBase(const QString& theId, QObject* theParent, CompositeFeaturePtr theSketch); /// Destructor virtual ~PartSet_OperationFeatureBase(); /// Returns the operation sketch feature /// \returns the sketch instance - virtual FeaturePtr sketch() const; + virtual CompositeFeaturePtr sketch() const; /// Gives the current selected objects to be processed by the operation /// \param theEvent the mouse event @@ -56,7 +56,7 @@ Q_OBJECT //bool setWidgetValue(ObjectPtr theFeature, double theX, double theY); protected: - FeaturePtr mySketch; ///< the sketch of the feature + CompositeFeaturePtr mySketch; ///< the sketch of the feature }; #endif diff --git a/src/PartSet/PartSet_OperationFeatureCreate.cpp b/src/PartSet/PartSet_OperationFeatureCreate.cpp index fe4b73858..0bc2d9238 100644 --- a/src/PartSet/PartSet_OperationFeatureCreate.cpp +++ b/src/PartSet/PartSet_OperationFeatureCreate.cpp @@ -46,7 +46,7 @@ using namespace std; PartSet_OperationFeatureCreate::PartSet_OperationFeatureCreate(const QString& theId, QObject* theParent, - FeaturePtr theFeature) + CompositeFeaturePtr theFeature) : PartSet_OperationFeatureBase(theId, theParent, theFeature) { } @@ -176,15 +176,10 @@ void PartSet_OperationFeatureCreate::afterCommitOperation() emit featureConstructed(feature(), FM_Deactivation); } -FeaturePtr PartSet_OperationFeatureCreate::createFeature(const bool theFlushMessage) +FeaturePtr PartSet_OperationFeatureCreate::createFeature(const bool theFlushMessage, + CompositeFeaturePtr theCompositeFeature) { - FeaturePtr aNewFeature = ModuleBase_Operation::createFeature(false); - if (sketch()) { - boost::shared_ptr aFeature = boost::dynamic_pointer_cast< - SketchPlugin_Feature>(sketch()); - - aFeature->addSub(aNewFeature); - } + FeaturePtr aNewFeature = ModuleBase_Operation::createFeature(false, sketch()); if (theFlushMessage) flushCreated(); diff --git a/src/PartSet/PartSet_OperationFeatureCreate.h b/src/PartSet/PartSet_OperationFeatureCreate.h index 531b4ff22..b13b8ece5 100644 --- a/src/PartSet/PartSet_OperationFeatureCreate.h +++ b/src/PartSet/PartSet_OperationFeatureCreate.h @@ -34,7 +34,8 @@ Q_OBJECT /// \param theId the feature identifier /// \param theParent the operation parent /// \param theSketch the parent feature - PartSet_OperationFeatureCreate(const QString& theId, QObject* theParent, FeaturePtr theSketch); + PartSet_OperationFeatureCreate( + const QString& theId, QObject* theParent, CompositeFeaturePtr theSketch); /// Destructor virtual ~PartSet_OperationFeatureCreate(); @@ -85,7 +86,8 @@ Q_OBJECT /// the sketch feature /// \param theFlushMessage the flag whether the create message should be flushed /// \returns the created feature - virtual FeaturePtr createFeature(const bool theFlushMessage = true); + virtual FeaturePtr createFeature(const bool theFlushMessage = true, + CompositeFeaturePtr theCompositeFeature = CompositeFeaturePtr()); /// Verifies whether this operator can be commited. /// \return Returns TRUE if current operation can be committed, e.g. all parameters are filled diff --git a/src/PartSet/PartSet_OperationFeatureEdit.cpp b/src/PartSet/PartSet_OperationFeatureEdit.cpp index 1e0932280..ecc1f0b1e 100644 --- a/src/PartSet/PartSet_OperationFeatureEdit.cpp +++ b/src/PartSet/PartSet_OperationFeatureEdit.cpp @@ -40,7 +40,7 @@ using namespace std; PartSet_OperationFeatureEdit::PartSet_OperationFeatureEdit(const QString& theId, QObject* theParent, - FeaturePtr theFeature) + CompositeFeaturePtr theFeature) : PartSet_OperationFeatureBase(theId, theParent, theFeature), myIsBlockedSelection(false) { @@ -196,7 +196,8 @@ void PartSet_OperationFeatureEdit::blockSelection(bool isBlocked, const bool isR } } -FeaturePtr PartSet_OperationFeatureEdit::createFeature(const bool /*theFlushMessage*/) +FeaturePtr PartSet_OperationFeatureEdit::createFeature(const bool theFlushMessage, + CompositeFeaturePtr theCompositeFeature) { // do nothing in order to do not create a new feature return FeaturePtr(); diff --git a/src/PartSet/PartSet_OperationFeatureEdit.h b/src/PartSet/PartSet_OperationFeatureEdit.h index 67223fce6..1b741a56a 100644 --- a/src/PartSet/PartSet_OperationFeatureEdit.h +++ b/src/PartSet/PartSet_OperationFeatureEdit.h @@ -66,7 +66,7 @@ Q_OBJECT /// \param theId the feature identifier /// \param theParent the operation parent /// \param theFeature the parent feature - PartSet_OperationFeatureEdit(const QString& theId, QObject* theParent, FeaturePtr theFeature); + PartSet_OperationFeatureEdit(const QString& theId, QObject* theParent, CompositeFeaturePtr theFeature); /// Destructor virtual ~PartSet_OperationFeatureEdit(); @@ -114,7 +114,8 @@ Q_OBJECT /// Returns NULL feature. This is an operation of edition, not creation. /// \param theFlushMessage the flag whether the create message should be flushed /// \returns the created feature - virtual FeaturePtr createFeature(const bool theFlushMessage = true); + virtual FeaturePtr createFeature(const bool theFlushMessage = true, + CompositeFeaturePtr theCompositeFeature = CompositeFeaturePtr()); protected: /// Emits a signal about the selection blocking. Emits a signal to change the selection. diff --git a/src/PartSet/PartSet_OperationFeatureEditMulti.cpp b/src/PartSet/PartSet_OperationFeatureEditMulti.cpp index b36e16ca2..9c9805860 100644 --- a/src/PartSet/PartSet_OperationFeatureEditMulti.cpp +++ b/src/PartSet/PartSet_OperationFeatureEditMulti.cpp @@ -34,7 +34,7 @@ using namespace std; PartSet_OperationFeatureEditMulti::PartSet_OperationFeatureEditMulti(const QString& theId, QObject* theParent, - FeaturePtr theFeature) + CompositeFeaturePtr theFeature) : PartSet_OperationSketchBase(theId, theParent), mySketch(theFeature), myIsBlockedSelection(false) @@ -96,7 +96,7 @@ void PartSet_OperationFeatureEditMulti::initSelection( } } -FeaturePtr PartSet_OperationFeatureEditMulti::sketch() const +CompositeFeaturePtr PartSet_OperationFeatureEditMulti::sketch() const { return mySketch; } diff --git a/src/PartSet/PartSet_OperationFeatureEditMulti.h b/src/PartSet/PartSet_OperationFeatureEditMulti.h index b34b638ad..44de5817b 100644 --- a/src/PartSet/PartSet_OperationFeatureEditMulti.h +++ b/src/PartSet/PartSet_OperationFeatureEditMulti.h @@ -66,7 +66,7 @@ Q_OBJECT /// \param theParent the operation parent /// \param theFeature the parent feature PartSet_OperationFeatureEditMulti(const QString& theId, QObject* theParent, - FeaturePtr theFeature); + CompositeFeaturePtr theFeature); /// Destructor virtual ~PartSet_OperationFeatureEditMulti(); @@ -78,7 +78,7 @@ Q_OBJECT /// Returns the operation sketch feature /// \returns the sketch instance - virtual FeaturePtr sketch() const; + virtual CompositeFeaturePtr sketch() const; /// Processes the mouse pressed in the point /// \param theEvent the mouse event @@ -122,7 +122,7 @@ Q_OBJECT void sendFeatures(); private: - FeaturePtr mySketch; ///< the sketch feature + CompositeFeaturePtr mySketch; ///< the sketch feature std::list myFeatures; ///< the features to apply the edit operation Point myCurPoint; ///< the current 3D point clicked or moved bool myIsBlockedSelection; ///< the state of the last state of selection blocked signal diff --git a/src/PartSet/PartSet_OperationSketch.cpp b/src/PartSet/PartSet_OperationSketch.cpp index b98436a07..6deab5b28 100644 --- a/src/PartSet/PartSet_OperationSketch.cpp +++ b/src/PartSet/PartSet_OperationSketch.cpp @@ -48,9 +48,9 @@ PartSet_OperationSketch::~PartSet_OperationSketch() { } -FeaturePtr PartSet_OperationSketch::sketch() const +CompositeFeaturePtr PartSet_OperationSketch::sketch() const { - return feature(); + return boost::dynamic_pointer_cast(feature()); } void PartSet_OperationSketch::mousePressed(QMouseEvent* theEvent, Handle_V3d_View theView, diff --git a/src/PartSet/PartSet_OperationSketch.h b/src/PartSet/PartSet_OperationSketch.h index 92d2c4fa1..d3ede8b3d 100644 --- a/src/PartSet/PartSet_OperationSketch.h +++ b/src/PartSet/PartSet_OperationSketch.h @@ -43,7 +43,7 @@ Q_OBJECT /// Returns the operation sketch feature /// \returns the sketch instance - virtual FeaturePtr sketch() const; + virtual CompositeFeaturePtr sketch() const; /// Processes the mouse pressed in the point /// \param theEvent the mouse event diff --git a/src/PartSet/PartSet_OperationSketchBase.h b/src/PartSet/PartSet_OperationSketchBase.h index 39fbaf082..c7d639348 100644 --- a/src/PartSet/PartSet_OperationSketchBase.h +++ b/src/PartSet/PartSet_OperationSketchBase.h @@ -62,7 +62,7 @@ Q_OBJECT /// Returns the operation sketch feature /// \returns the sketch instance - virtual FeaturePtr sketch() const = 0; + virtual CompositeFeaturePtr sketch() const = 0; /// Processes the mouse pressed in the point /// \param theEvent the mouse event diff --git a/src/PartSet/PartSet_Tools.cpp b/src/PartSet/PartSet_Tools.cpp index ea47cde21..892f610a0 100644 --- a/src/PartSet/PartSet_Tools.cpp +++ b/src/PartSet/PartSet_Tools.cpp @@ -235,17 +235,16 @@ FeaturePtr PartSet_Tools::feature(FeaturePtr theFeature, const std::string& theA return aFeature; } -void PartSet_Tools::createConstraint(FeaturePtr theSketch, +void PartSet_Tools::createConstraint(CompositeFeaturePtr theSketch, boost::shared_ptr thePoint1, boost::shared_ptr thePoint2) { - boost::shared_ptr aDoc = document(); - FeaturePtr aFeature = aDoc->addFeature(SketchPlugin_ConstraintCoincidence::ID()); - + FeaturePtr aFeature; if (theSketch) { - boost::shared_ptr aSketch = boost::dynamic_pointer_cast< - SketchPlugin_Feature>(theSketch); - aSketch->addSub(aFeature); + aFeature = theSketch->addFeature(SketchPlugin_ConstraintCoincidence::ID()); + } else { + boost::shared_ptr aDoc = document(); + aFeature = aDoc->addFeature(SketchPlugin_ConstraintCoincidence::ID()); } boost::shared_ptr aData = aFeature->data(); @@ -262,7 +261,7 @@ void PartSet_Tools::createConstraint(FeaturePtr theSketch, aFeature->execute(); } -void PartSet_Tools::setConstraints(FeaturePtr theSketch, FeaturePtr theFeature, +void PartSet_Tools::setConstraints(CompositeFeaturePtr theSketch, FeaturePtr theFeature, const std::string& theAttribute, double theClickedX, double theClickedY) { @@ -302,7 +301,7 @@ void PartSet_Tools::setConstraints(FeaturePtr theSketch, FeaturePtr theFeature, } } -boost::shared_ptr PartSet_Tools::sketchPlane(FeaturePtr theSketch) +boost::shared_ptr PartSet_Tools::sketchPlane(CompositeFeaturePtr theSketch) { boost::shared_ptr aPlane; double aA, aB, aC, aD; @@ -322,7 +321,7 @@ boost::shared_ptr PartSet_Tools::sketchPlane(FeaturePtr theSketch) } boost::shared_ptr PartSet_Tools::point3D(boost::shared_ptr thePoint2D, - FeaturePtr theSketch) + CompositeFeaturePtr theSketch) { boost::shared_ptr aPoint; if (!theSketch || !thePoint2D) diff --git a/src/PartSet/PartSet_Tools.h b/src/PartSet/PartSet_Tools.h index d1b5b4d5c..160814747 100644 --- a/src/PartSet/PartSet_Tools.h +++ b/src/PartSet/PartSet_Tools.h @@ -11,7 +11,7 @@ #include -#include +#include #include @@ -97,7 +97,7 @@ class PARTSET_EXPORT PartSet_Tools /// Creates a constraint on two points /// \param thePoint1 the first point /// \param thePoint1 the second point - static void createConstraint(FeaturePtr theSketch, + static void createConstraint(CompositeFeaturePtr theSketch, boost::shared_ptr thePoint1, boost::shared_ptr thePoint2); @@ -107,21 +107,21 @@ class PARTSET_EXPORT PartSet_Tools /// \param theAttribute a name of the requried attribute attribute /// \param theClickedX the horizontal coordnate of the point /// \param theClickedY the vertical coordnate of the point - static void setConstraints(FeaturePtr theSketch, FeaturePtr theFeature, + static void setConstraints(CompositeFeaturePtr theSketch, FeaturePtr theFeature, const std::string& theAttribute, double theClickedX, double theClickedY); /// Create a sketch plane instance /// \param theSketch a sketch feature /// \return API object of geom plane - static boost::shared_ptr sketchPlane(FeaturePtr theSketch); + static boost::shared_ptr sketchPlane(CompositeFeaturePtr theSketch); /// Create a point 3D on a basis of point 2D and sketch feature /// \param thePoint2D a point on a sketch /// \param theSketch a sketch feature /// \return API object of point 3D static boost::shared_ptr point3D(boost::shared_ptr thePoint2D, - FeaturePtr theSketch); + CompositeFeaturePtr theSketch); /// Check whether there is a constraint with the feature kind given /// \param theKind a feature kind /// \return the boolean value diff --git a/src/SketchPlugin/SketchPlugin_Feature.cpp b/src/SketchPlugin/SketchPlugin_Feature.cpp index c3c800bd9..9fd9ee2f6 100644 --- a/src/SketchPlugin/SketchPlugin_Feature.cpp +++ b/src/SketchPlugin/SketchPlugin_Feature.cpp @@ -17,8 +17,9 @@ SketchPlugin_Sketch* SketchPlugin_Feature::sketch() // find sketch that references to this feature int aSketches = document()->size(ModelAPI_Feature::group()); for (int a = 0; a < aSketches && !mySketch; a++) { - boost::shared_ptr aSketch = boost::dynamic_pointer_cast< - SketchPlugin_Sketch>(document()->object(ModelAPI_Feature::group(), a)); + ObjectPtr anObj = document()->object(ModelAPI_Feature::group(), a); + boost::shared_ptr aSketch = + boost::dynamic_pointer_cast(anObj); if (aSketch) { std::list aList = aSketch->data()->reflist(SketchPlugin_Sketch::FEATURES_ID()) ->list(); diff --git a/src/SketchPlugin/SketchPlugin_Feature.h b/src/SketchPlugin/SketchPlugin_Feature.h index d51301880..24b856b1f 100644 --- a/src/SketchPlugin/SketchPlugin_Feature.h +++ b/src/SketchPlugin/SketchPlugin_Feature.h @@ -6,7 +6,7 @@ #define SketchPlugin_Feature_H_ #include "SketchPlugin.h" -#include +#include #include #include #include @@ -27,13 +27,6 @@ class SketchPlugin_Feature : public ModelAPI_Feature static AISObjectPtr simpleAISObject(boost::shared_ptr theRes, AISObjectPtr thePrevious); - /// Adds sub-feature of the higher level feature (sub-element of the sketch) - /// \param theFeature sub-feature - SKETCHPLUGIN_EXPORT virtual const void addSub(const FeaturePtr& theFeature) - { - } - ; - /// Returns true if this feature must be displayed in the history (top level of Part tree) SKETCHPLUGIN_EXPORT virtual bool isInHistory() { diff --git a/src/SketchPlugin/SketchPlugin_Sketch.cpp b/src/SketchPlugin/SketchPlugin_Sketch.cpp index 0bbcfe2a7..a8fef3263 100644 --- a/src/SketchPlugin/SketchPlugin_Sketch.cpp +++ b/src/SketchPlugin/SketchPlugin_Sketch.cpp @@ -100,10 +100,25 @@ void SketchPlugin_Sketch::execute() setResult(aConstr); } -const void SketchPlugin_Sketch::addSub(const FeaturePtr& theFeature) +boost::shared_ptr SketchPlugin_Sketch::addFeature(std::string theID) { - boost::dynamic_pointer_cast(theFeature)->setSketch(this); - data()->reflist(SketchPlugin_Sketch::FEATURES_ID())->append(theFeature); + boost::shared_ptr aNew = document()->addFeature(theID); + if (aNew) { + boost::dynamic_pointer_cast(aNew)->setSketch(this); + data()->reflist(SketchPlugin_Sketch::FEATURES_ID())->append(aNew); + } + return aNew; +} + +int SketchPlugin_Sketch::numberOfSubs() const +{ + return data()->reflist(SketchPlugin_Sketch::FEATURES_ID())->size(); +} + +boost::shared_ptr SketchPlugin_Sketch::subFeature(const int theIndex) const +{ + ObjectPtr anObj = data()->reflist(SketchPlugin_Sketch::FEATURES_ID())->object(theIndex); + return boost::dynamic_pointer_cast(anObj); } boost::shared_ptr SketchPlugin_Sketch::to3D(const double theX, const double theY) @@ -195,5 +210,5 @@ void SketchPlugin_Sketch::erase() document()->removeFeature(aFeature, false); } } - SketchPlugin_Feature::erase(); + ModelAPI_CompositeFeature::erase(); } diff --git a/src/SketchPlugin/SketchPlugin_Sketch.h b/src/SketchPlugin/SketchPlugin_Sketch.h index 07f8ae269..c35b37ce1 100644 --- a/src/SketchPlugin/SketchPlugin_Sketch.h +++ b/src/SketchPlugin/SketchPlugin_Sketch.h @@ -25,7 +25,7 @@ * \ingroup DataModel * \brief Feature for creation of the new part in PartSet. */ -class SketchPlugin_Sketch : public SketchPlugin_Feature, public GeomAPI_IPresentable +class SketchPlugin_Sketch : public ModelAPI_CompositeFeature, public GeomAPI_IPresentable { public: /// Sketch feature kind @@ -78,10 +78,6 @@ class SketchPlugin_Sketch : public SketchPlugin_Feature, public GeomAPI_IPresent /// Request for initialization of data model of the feature: adding all attributes SKETCHPLUGIN_EXPORT virtual void initAttributes(); - /// Adds sub-feature of the higher level feature (sub-element of the sketch) - /// \param theFeature sub-feature - SKETCHPLUGIN_EXPORT virtual const void addSub(const FeaturePtr& theFeature); - /// Moves the feature /// \param theDeltaX the delta for X coordinate is moved /// \param theDeltaY the delta for Y coordinate is moved @@ -118,6 +114,15 @@ class SketchPlugin_Sketch : public SketchPlugin_Feature, public GeomAPI_IPresent /// removes also all sub-sketch elements SKETCHPLUGIN_EXPORT virtual void erase(); + SKETCHPLUGIN_EXPORT virtual boost::shared_ptr addFeature(std::string theID); + + /// Returns the number of sub-elements + SKETCHPLUGIN_EXPORT virtual int numberOfSubs() const; + + /// Returns the sub-feature by zero-base index + SKETCHPLUGIN_EXPORT virtual boost::shared_ptr + subFeature(const int theIndex) const; + protected: /// Creates a plane and append it to the list /// \param theX the X normal value diff --git a/src/SketchSolver/SketchSolver_ConstraintGroup.cpp b/src/SketchSolver/SketchSolver_ConstraintGroup.cpp index 1ef8518dc..20158ab6e 100644 --- a/src/SketchSolver/SketchSolver_ConstraintGroup.cpp +++ b/src/SketchSolver/SketchSolver_ConstraintGroup.cpp @@ -68,7 +68,7 @@ static int Search(const uint32_t& theEntityID, const std::vector& theEntities // ======================================================== SketchSolver_ConstraintGroup::SketchSolver_ConstraintGroup( - boost::shared_ptr theWorkplane) + boost::shared_ptr theWorkplane) : myID(++myGroupIndexer), myParamMaxID(0), myEntityMaxID(0), @@ -116,7 +116,7 @@ SketchSolver_ConstraintGroup::~SketchSolver_ConstraintGroup() // Purpose: verify the group is based on the given workplane // ============================================================================ bool SketchSolver_ConstraintGroup::isBaseWorkplane( - boost::shared_ptr theWorkplane) const + boost::shared_ptr theWorkplane) const { return theWorkplane == mySketch; } @@ -776,7 +776,7 @@ Slvs_hEntity SketchSolver_ConstraintGroup::changeNormal( // Class: SketchSolver_ConstraintGroup // Purpose: create workplane for the group // ============================================================================ -bool SketchSolver_ConstraintGroup::addWorkplane(boost::shared_ptr theSketch) +bool SketchSolver_ConstraintGroup::addWorkplane(boost::shared_ptr theSketch) { if (myWorkplane.h || theSketch->getKind().compare(SketchPlugin_Sketch::ID()) != 0) return false; // the workplane already exists or the function parameter is not Sketch diff --git a/src/SketchSolver/SketchSolver_ConstraintGroup.h b/src/SketchSolver/SketchSolver_ConstraintGroup.h index 2337f5187..c8a673029 100644 --- a/src/SketchSolver/SketchSolver_ConstraintGroup.h +++ b/src/SketchSolver/SketchSolver_ConstraintGroup.h @@ -30,7 +30,7 @@ class SketchSolver_ConstraintGroup * Throws an exception if theWorkplane is not an object of SketchPlugin_Sketch type * \remark Type of theSketch is not verified inside */ - SketchSolver_ConstraintGroup(boost::shared_ptr theWorkplane); + SketchSolver_ConstraintGroup(boost::shared_ptr theWorkplane); ~SketchSolver_ConstraintGroup(); @@ -69,9 +69,9 @@ class SketchSolver_ConstraintGroup * \param[in] theWorkplane the feature to be compared with base workplane * \return \c true if workplanes are the same */ - bool isBaseWorkplane(boost::shared_ptr theWorkplane) const; + bool isBaseWorkplane(boost::shared_ptr theWorkplane) const; - boost::shared_ptr getWorkplane() const + boost::shared_ptr getWorkplane() const { return mySketch; } @@ -188,7 +188,7 @@ protected: * \param[in] theSketch parameters of workplane are the attributes of this sketch * \return \c true if success, \c false if workplane parameters are not consistent */ - bool addWorkplane(boost::shared_ptr theSketch); + bool addWorkplane(boost::shared_ptr theSketch); /** \brief Add the entities of constraint for points coincidence into the appropriate list * \param[in] thePoint1 identifier of the first point @@ -224,7 +224,7 @@ protected: std::list myTempConstraints; ///< The list of identifiers of temporary constraints (SLVS_C_WHERE_DRAGGED) applied for all other points moved by user // SketchPlugin entities - boost::shared_ptr mySketch; ///< Equivalent to workplane + boost::shared_ptr mySketch; ///< Equivalent to workplane ConstraintMap myConstraintMap; ///< The map between SketchPlugin and SolveSpace constraints std::map, Slvs_hEntity> myEntityAttrMap; ///< The map between "attribute" parameters of constraints and their equivalent SolveSpace entities std::map myEntityFeatMap; ///< The map between "feature" parameters of constraints and their equivalent SolveSpace entities diff --git a/src/SketchSolver/SketchSolver_ConstraintManager.cpp b/src/SketchSolver/SketchSolver_ConstraintManager.cpp index c0ade33a7..ebc25b1fa 100644 --- a/src/SketchSolver/SketchSolver_ConstraintManager.cpp +++ b/src/SketchSolver/SketchSolver_ConstraintManager.cpp @@ -88,8 +88,8 @@ void SketchSolver_ConstraintManager::processEvent( // Only sketches and constraints can be added by Create event const std::string& aFeatureKind = aFeature->getKind(); if (aFeatureKind.compare(SketchPlugin_Sketch::ID()) == 0) { - boost::shared_ptr aSketch = boost::dynamic_pointer_cast< - SketchPlugin_Feature>(aFeature); + boost::shared_ptr aSketch = boost::dynamic_pointer_cast< + ModelAPI_CompositeFeature>(aFeature); if (aSketch) changeWorkplane(aSketch); continue; @@ -144,7 +144,7 @@ void SketchSolver_ConstraintManager::processEvent( // Purpose: update workplane by given parameters of the sketch // ============================================================================ bool SketchSolver_ConstraintManager::changeWorkplane( - boost::shared_ptr theSketch) + boost::shared_ptr theSketch) { bool aResult = true; // changed when a workplane wrongly updated bool isUpdated = false; @@ -189,7 +189,7 @@ bool SketchSolver_ConstraintManager::changeConstraintOrEntity( // There are no groups applicable for this constraint => create new one // The group will be created only for constraints, not for features if (!aConstraint) return false; - boost::shared_ptr aWP = findWorkplane(aConstraint); + boost::shared_ptr aWP = findWorkplane(aConstraint); if (!aWP) return false; SketchSolver_ConstraintGroup* aGroup = new SketchSolver_ConstraintGroup(aWP); @@ -309,7 +309,7 @@ void SketchSolver_ConstraintManager::findGroups( boost::shared_ptr theFeature, std::set& theGroupIDs) const { - boost::shared_ptr aWP = findWorkplane(theFeature); + boost::shared_ptr aWP = findWorkplane(theFeature); SketchSolver_ConstraintGroup* anEmptyGroup = 0; // appropriate empty group for specified constraint std::vector::const_iterator aGroupIter; @@ -331,15 +331,15 @@ void SketchSolver_ConstraintManager::findGroups( // Class: SketchSolver_Session // Purpose: search workplane containing given feature // ============================================================================ -boost::shared_ptr SketchSolver_ConstraintManager::findWorkplane( +boost::shared_ptr SketchSolver_ConstraintManager::findWorkplane( boost::shared_ptr theFeature) const { // Already verified workplanes - std::set > aVerified; + std::set > aVerified; std::vector::const_iterator aGroupIter; for (aGroupIter = myGroups.begin(); aGroupIter != myGroups.end(); aGroupIter++) { - boost::shared_ptr aWP = (*aGroupIter)->getWorkplane(); + boost::shared_ptr aWP = (*aGroupIter)->getWorkplane(); if (aVerified.find(aWP) != aVerified.end()) continue; @@ -353,7 +353,7 @@ boost::shared_ptr SketchSolver_ConstraintManager::findWork aVerified.insert(aWP); } - return boost::shared_ptr(); + return boost::shared_ptr(); } // ============================================================================ diff --git a/src/SketchSolver/SketchSolver_ConstraintManager.h b/src/SketchSolver/SketchSolver_ConstraintManager.h index b0aefd196..b13a67182 100644 --- a/src/SketchSolver/SketchSolver_ConstraintManager.h +++ b/src/SketchSolver/SketchSolver_ConstraintManager.h @@ -65,7 +65,7 @@ class SketchSolver_ConstraintManager : public Events_Listener * \return \c true if the workplane changed successfully * \remark Type of theSketch is not verified inside */ - bool changeWorkplane(boost::shared_ptr theSketch); + bool changeWorkplane(boost::shared_ptr theSketch); /** \brief Removes a workplane from the manager. * All groups based on such workplane will be removed too. @@ -95,7 +95,7 @@ class SketchSolver_ConstraintManager : public Events_Listener * \param[in] theFeature object to be found * \return workplane containing the feature */ - boost::shared_ptr findWorkplane( + boost::shared_ptr findWorkplane( boost::shared_ptr theFeature) const; private: -- 2.39.2