From b9eb347a63532ac4c1266b75a44a51c3ec2d6ee0 Mon Sep 17 00:00:00 2001 From: mpv Date: Thu, 23 Oct 2014 17:18:58 +0400 Subject: [PATCH] Implementation of naming parametrisation of sketch result --- src/GeomAPI/GeomAPI_Wire.h | 31 ++--- src/Model/CMakeLists.txt | 2 + src/Model/Model_AttributeSelection.cpp | 126 +++++++++++++++++-- src/Model/Model_AttributeSelection.h | 4 + src/Model/Model_Data.cpp | 5 + src/Model/Model_Data.h | 4 + src/Model/Model_Update.cpp | 12 ++ src/ModelAPI/ModelAPI_AttributeSelection.h | 4 + src/ModelAPI/ModelAPI_CompositeFeature.h | 3 + src/ModelAPI/ModelAPI_Data.h | 3 + src/PartSet/PartSet_OperationFeatureEdit.cpp | 9 +- src/SketchPlugin/SketchPlugin_Feature.cpp | 3 +- src/SketchPlugin/SketchPlugin_Feature.h | 4 +- src/SketchPlugin/SketchPlugin_Sketch.cpp | 5 + src/SketchPlugin/SketchPlugin_Sketch.h | 3 + 15 files changed, 189 insertions(+), 29 deletions(-) diff --git a/src/GeomAPI/GeomAPI_Wire.h b/src/GeomAPI/GeomAPI_Wire.h index 4bc0e0cd9..86a457830 100644 --- a/src/GeomAPI/GeomAPI_Wire.h +++ b/src/GeomAPI/GeomAPI_Wire.h @@ -19,44 +19,45 @@ * \brief Interface to the edge object */ -class GEOMAPI_EXPORT GeomAPI_Wire : public GeomAPI_Shape +class GeomAPI_Wire : public GeomAPI_Shape { public: /// Creation of empty (null) shape - GeomAPI_Wire(); + GEOMAPI_EXPORT GeomAPI_Wire(); - virtual bool isVertex() const + GEOMAPI_EXPORT virtual bool isVertex() const { return false; } /// Returns whether the shape is an edge - virtual bool isEdge() const + GEOMAPI_EXPORT virtual bool isEdge() const { return false; } - void addEdge(boost::shared_ptr theEdge); - std::list > getEdges(); + GEOMAPI_EXPORT void addEdge(boost::shared_ptr theEdge); + GEOMAPI_EXPORT std::list > getEdges(); /// Returns True if the wire is defined in a plane - bool hasPlane() const { return myOrigin && myNorm && myDirX && myDirY; } + GEOMAPI_EXPORT bool hasPlane() const { return myOrigin && myNorm && myDirX && myDirY; } /// Set/Get origin point - void setOrigin(const boost::shared_ptr& theOrigin) { myOrigin = theOrigin; } - boost::shared_ptr origin() const { return myOrigin; } + GEOMAPI_EXPORT void setOrigin(const boost::shared_ptr& theOrigin) + { myOrigin = theOrigin; } + GEOMAPI_EXPORT boost::shared_ptr origin() const { return myOrigin; } /// Set/Get X direction vector - void setDirX(const boost::shared_ptr& theDirX) { myDirX = theDirX; } - boost::shared_ptr dirX() const { return myDirX; } + GEOMAPI_EXPORT void setDirX(const boost::shared_ptr& theDirX) { myDirX = theDirX; } + GEOMAPI_EXPORT boost::shared_ptr dirX() const { return myDirX; } /// Set/Get Y direction vector - void setDirY(const boost::shared_ptr& theDirY) { myDirY = theDirY; } - boost::shared_ptr dirY() const { return myDirY; } + GEOMAPI_EXPORT void setDirY(const boost::shared_ptr& theDirY) { myDirY = theDirY; } + GEOMAPI_EXPORT boost::shared_ptr dirY() const { return myDirY; } /// Set/Get Normal direction vector - void setNorm(const boost::shared_ptr& theNorm) { myNorm = theNorm; } - boost::shared_ptr norm() const { return myNorm; } + GEOMAPI_EXPORT void setNorm(const boost::shared_ptr& theNorm) { myNorm = theNorm; } + GEOMAPI_EXPORT boost::shared_ptr norm() const { return myNorm; } private: boost::shared_ptr myOrigin; diff --git a/src/Model/CMakeLists.txt b/src/Model/CMakeLists.txt index 25626636a..1656a618f 100644 --- a/src/Model/CMakeLists.txt +++ b/src/Model/CMakeLists.txt @@ -55,6 +55,7 @@ SET(PROJECT_LIBRARIES Config GeomData GeomAPI + GeomAlgoAPI ${CAS_OCAF} ${CAS_TKCAF} ${CAS_SHAPE} @@ -73,6 +74,7 @@ INCLUDE_DIRECTORIES( ../Config ../GeomData ../GeomDataAPI + ../GeomAlgoAPI ../GeomAPI ${CAS_INCLUDE_DIRS} ) diff --git a/src/Model/Model_AttributeSelection.cpp b/src/Model/Model_AttributeSelection.cpp index f55ee9f5e..f919cecd6 100644 --- a/src/Model/Model_AttributeSelection.cpp +++ b/src/Model/Model_AttributeSelection.cpp @@ -11,15 +11,22 @@ #include #include #include +#include +#include #include #include #include #include #include -#include +#include #include #include +#include +#include +#include +#include +#include using namespace std; @@ -75,6 +82,101 @@ void Model_AttributeSelection::setObject(const boost::shared_ptrgroupName() == ModelAPI_ResultBody::group()) { + // body: just a named shape, use selection mechanism from OCCT + TNaming_Selector aSelector(myRef.myRef->Label()); + TDF_LabelMap aScope; // empty means the whole document + return aSelector.Solve(aScope) == Standard_True; + + } else if (aContext->groupName() == ModelAPI_ResultConstruction::group()) { + // construction: identification by the results indexes, recompute faces and + // take the face that more close by the indexes + boost::shared_ptr aWirePtr = boost::dynamic_pointer_cast( + boost::dynamic_pointer_cast(aContext)->shape()); + if (aWirePtr && aWirePtr->hasPlane()) { + // If this is a wire with plane defined thin it is a sketch-like object + std::list > aFaces; + GeomAlgoAPI_SketchBuilder::createFaces(aWirePtr->origin(), aWirePtr->dirX(), + aWirePtr->dirY(), aWirePtr->norm(), aWirePtr, aFaces); + if (aFaces.empty()) // no faces, update can not work correctly + return false; + // if there is no edges indexes, any face can be used: take the first + boost::shared_ptr aData = + boost::dynamic_pointer_cast(owner()->data()); + TDF_Label aLab = aData->label(); + Handle(TDataStd_IntPackedMap) aSubIds; + boost::shared_ptr aNewSelected; + if (!aLab.FindAttribute(TDataStd_IntPackedMap::GetID(), aSubIds) || aSubIds->Extent() == 0) { + aNewSelected = *(aFaces.begin()); + } else { // searching for most looks-like initial face by the indexes + // prepare edges of the current resut for the fast searching + TColStd_MapOfTransient allCurves; + FeaturePtr aContextFeature = owner()->document()->feature(aContext); + CompositeFeaturePtr aComposite = + boost::dynamic_pointer_cast(aContextFeature); + if (!aComposite) // must be composite at least for the current implementation + return false; + const int aSubNum = aComposite->numberOfSubs(); + for(int a = 0; a < aSubNum; a++) { + if (aSubIds->Contains(aComposite->subFeatureId(a))) { + FeaturePtr aSub = aComposite->subFeature(a); + const std::list >& aResults = aSub->results(); + std::list >::const_iterator aRes = aResults.cbegin(); + for(; aRes != aResults.cend(); aRes++) { + ResultConstructionPtr aConstr = + boost::dynamic_pointer_cast(*aRes); + if (aConstr->shape()) { + const TopoDS_Shape& aResShape = aConstr->shape()->impl(); + TopoDS_Edge anEdge = TopoDS::Edge(aResShape); + if (!anEdge.IsNull()) { + Standard_Real aFirst, aLast; + Handle(Geom_Curve) aCurve = BRep_Tool::Curve(anEdge, aFirst, aLast); + allCurves.Add(aCurve); + } + } + } + } + } + // iterate new result faces and searching for these edges + std::list >::iterator aFacesIter = aFaces.begin(); + double aBestFound = 0; // best percentage of found edges + for(; aFacesIter != aFaces.end(); aFacesIter++) { + int aFound = 0, aNotFound = 0; + TopExp_Explorer anEdgesExp((*aFacesIter)->impl(), TopAbs_EDGE); + for(; anEdgesExp.More(); anEdgesExp.Next()) { + TopoDS_Edge anEdge = TopoDS::Edge(anEdgesExp.Current()); + if (!anEdge.IsNull()) { + Standard_Real aFirst, aLast; + Handle(Geom_Curve) aCurve = BRep_Tool::Curve(anEdge, aFirst, aLast); + if (allCurves.Contains(aCurve)) { + aFound++; + } else { + aNotFound++; + } + } + } + if (aFound + aNotFound != 0) { + double aPercentage = double(aFound) / double(aFound + aNotFound); + if (aPercentage > aBestFound) { + aBestFound = aPercentage; + aNewSelected = *aFacesIter; + } + } + } + if (aNewSelected) { // store this new selection + selectConstruction(aContext, aNewSelected); + return true; + } + } + } + } + return false; // unknown case +} + + void Model_AttributeSelection::selectBody( const ResultPtr& theContext, const boost::shared_ptr& theSubShape) { @@ -112,12 +214,15 @@ void Model_AttributeSelection::selectConstruction( 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; + TColStd_MapOfTransient allCurves; for(TopExp_Explorer anEdgeExp(aSubShape, TopAbs_EDGE); anEdgeExp.More(); anEdgeExp.Next()) { - allEdges.Add(anEdgeExp.Current()); + TopoDS_Edge anEdge = TopoDS::Edge(anEdgeExp.Current()); + Standard_Real aFirst, aLast; + Handle(Geom_Curve) aCurve = BRep_Tool::Curve(anEdge, aFirst, aLast); + allCurves.Add(aCurve); } // iterate and store the result ids of sub-elements - Handle(TDataStd_ReferenceList) aRefs = TDataStd_ReferenceList::Set(aLab); + Handle(TDataStd_IntPackedMap) aRefs = TDataStd_IntPackedMap::Set(aLab); const int aSubNum = aComposite->numberOfSubs(); for(int a = 0; a < aSubNum; a++) { FeaturePtr aSub = aComposite->subFeature(a); @@ -129,10 +234,15 @@ void Model_AttributeSelection::selectConstruction( boost::dynamic_pointer_cast(*aRes); if (aConstr->shape()) { const TopoDS_Shape& aResShape = aConstr->shape()->impl(); - if (allEdges.Contains(aResShape)) { - boost::shared_ptr aSubData = boost::dynamic_pointer_cast(aSub->data()); - TDF_Label aSubLab = aSubData->label(); - aRefs->Append(aSubLab); + TopoDS_Edge anEdge = TopoDS::Edge(aResShape); + if (!anEdge.IsNull()) { + Standard_Real aFirst, aLast; + Handle(Geom_Curve) aCurve = BRep_Tool::Curve(anEdge, aFirst, aLast); + if (allCurves.Contains(aCurve)) { + boost::shared_ptr aSubData = boost::dynamic_pointer_cast(aSub->data()); + TDF_Label aSubLab = aSubData->label(); + aRefs->Add(aComposite->subFeatureId(a)); + } } } } diff --git a/src/Model/Model_AttributeSelection.h b/src/Model/Model_AttributeSelection.h index 2e71baea1..79ce151da 100644 --- a/src/Model/Model_AttributeSelection.h +++ b/src/Model/Model_AttributeSelection.h @@ -31,6 +31,10 @@ public: /// Sets the feature object MODEL_EXPORT virtual void setObject(const boost::shared_ptr& theObject); + /// Updates the underlied selection due to the changes in the referenced objects + /// \returns false if update is failed + MODEL_EXPORT virtual bool update(); + protected: /// Objects are created for features automatically MODEL_EXPORT Model_AttributeSelection(TDF_Label& theLabel); diff --git a/src/Model/Model_Data.cpp b/src/Model/Model_Data.cpp index 7b25cb240..b293bd3f9 100644 --- a/src/Model/Model_Data.cpp +++ b/src/Model/Model_Data.cpp @@ -387,3 +387,8 @@ bool Model_Data::referencesTo(const boost::shared_ptr& theFeat } return false; } + +int Model_Data::featureId() const +{ + return myLab.Father().Tag(); // tag of the feature label +} diff --git a/src/Model/Model_Data.h b/src/Model/Model_Data.h index c923d79af..d61ddd6c2 100644 --- a/src/Model/Model_Data.h +++ b/src/Model/Model_Data.h @@ -146,6 +146,10 @@ class Model_Data : public ModelAPI_Data /// Returns true if this data attributes are referenced to the given feature or its results MODEL_EXPORT virtual bool referencesTo(const boost::shared_ptr& theFeature); + + /// Returns the identifier of feature-owner, unique in this document + MODEL_EXPORT virtual int featureId() const; + }; #endif diff --git a/src/Model/Model_Update.cpp b/src/Model/Model_Update.cpp index 7c3633aa7..6d50871d7 100644 --- a/src/Model/Model_Update.cpp +++ b/src/Model/Model_Update.cpp @@ -11,6 +11,7 @@ #include #include #include +#include #include #include #include @@ -179,6 +180,17 @@ bool Model_Update::updateFeature(FeaturePtr theFeature) } } } + // selection attributes: must be called "update" methods if needed + aRefs = theFeature->data()->attributes(ModelAPI_AttributeSelection::type()); + for (aRefsIter = aRefs.begin(); aRefsIter != aRefs.end(); aRefsIter++) { + boost::shared_ptr aSel = + boost::dynamic_pointer_cast(*aRefsIter); + if (updateObject(aSel->context())) { + aMustbeUpdated = true; + aSel->update(); + } + } + // execute feature if it must be updated if (aMustbeUpdated) { diff --git a/src/ModelAPI/ModelAPI_AttributeSelection.h b/src/ModelAPI/ModelAPI_AttributeSelection.h index 08f5f6e5d..40882dde4 100644 --- a/src/ModelAPI/ModelAPI_AttributeSelection.h +++ b/src/ModelAPI/ModelAPI_AttributeSelection.h @@ -26,6 +26,10 @@ class ModelAPI_AttributeSelection : public ModelAPI_Attribute /// Returns the context of the selection (the whole shape owner) virtual ResultPtr context() = 0; + /// Updates the underlied selection due to the changes in the referenced objects + /// \returns false if update is failed + virtual bool update() = 0; + /// Returns the type of this class of attributes static std::string type() { diff --git a/src/ModelAPI/ModelAPI_CompositeFeature.h b/src/ModelAPI/ModelAPI_CompositeFeature.h index 3c822e66e..28c4d6d2a 100644 --- a/src/ModelAPI/ModelAPI_CompositeFeature.h +++ b/src/ModelAPI/ModelAPI_CompositeFeature.h @@ -24,6 +24,9 @@ public: /// Returns the sub-feature by zero-base index virtual boost::shared_ptr subFeature(const int theIndex) const = 0; + + /// Returns the sub-feature unique identifier in this composite feature by zero-base index + virtual int subFeatureId(const int theIndex) const = 0; }; //! Pointer on the composite feature object diff --git a/src/ModelAPI/ModelAPI_Data.h b/src/ModelAPI/ModelAPI_Data.h index e9852e6e2..85c65cbd5 100644 --- a/src/ModelAPI/ModelAPI_Data.h +++ b/src/ModelAPI/ModelAPI_Data.h @@ -109,6 +109,9 @@ class MODELAPI_EXPORT ModelAPI_Data /// Returns true if this data attributes are referenced to the given feature or its results virtual bool referencesTo(const boost::shared_ptr& theFeature) = 0; + /// Returns the identifier of feature-owner, unique in this document + virtual int featureId() const = 0; + protected: /// Objects are created for features automatically ModelAPI_Data() diff --git a/src/PartSet/PartSet_OperationFeatureEdit.cpp b/src/PartSet/PartSet_OperationFeatureEdit.cpp index 70898eaf4..16e2b4437 100644 --- a/src/PartSet/PartSet_OperationFeatureEdit.cpp +++ b/src/PartSet/PartSet_OperationFeatureEdit.cpp @@ -114,9 +114,12 @@ void PartSet_OperationFeatureEdit::mouseMoved(QMouseEvent* theEvent, Handle(V3d_ boost::shared_ptr aSketchFeature = boost::dynamic_pointer_cast< SketchPlugin_Feature>(feature()); - aSketchFeature->move(aDeltaX, aDeltaY); - static Events_ID anEvent = Events_Loop::eventByName(EVENT_OBJECT_TO_REDISPLAY); - ModelAPI_EventCreator::get()->sendUpdated(feature(), anEvent); + // MPV: added condition because it could be external edge of some object, not sketch + if (aSketchFeature && aSketchFeature->sketch() == sketch().get()) { + aSketchFeature->move(aDeltaX, aDeltaY); + static Events_ID anEvent = Events_Loop::eventByName(EVENT_OBJECT_TO_REDISPLAY); + ModelAPI_EventCreator::get()->sendUpdated(feature(), anEvent); + } } sendFeatures(); diff --git a/src/SketchPlugin/SketchPlugin_Feature.cpp b/src/SketchPlugin/SketchPlugin_Feature.cpp index 9fd9ee2f6..da25c0999 100644 --- a/src/SketchPlugin/SketchPlugin_Feature.cpp +++ b/src/SketchPlugin/SketchPlugin_Feature.cpp @@ -11,6 +11,7 @@ SketchPlugin_Feature::SketchPlugin_Feature() mySketch = 0; } +/* SketchPlugin_Sketch* SketchPlugin_Feature::sketch() { if (!mySketch) { @@ -34,7 +35,7 @@ SketchPlugin_Sketch* SketchPlugin_Feature::sketch() } } return mySketch; -} +}*/ AISObjectPtr SketchPlugin_Feature::simpleAISObject(boost::shared_ptr theRes, AISObjectPtr thePrevious) diff --git a/src/SketchPlugin/SketchPlugin_Feature.h b/src/SketchPlugin/SketchPlugin_Feature.h index 24b856b1f..49bcc1320 100644 --- a/src/SketchPlugin/SketchPlugin_Feature.h +++ b/src/SketchPlugin/SketchPlugin_Feature.h @@ -45,14 +45,14 @@ class SketchPlugin_Feature : public ModelAPI_Feature /// Construction result is allways recomuted on the fly SKETCHPLUGIN_EXPORT virtual bool isPersistentResult() {return false;} + /// Returns the sketch of this feature + inline SketchPlugin_Sketch* sketch() {return mySketch;} protected: /// Sets the higher-level feature for the sub-feature (sketch for line) void setSketch(SketchPlugin_Sketch* theSketch) { mySketch = theSketch; } - /// Returns the sketch of this feature - SketchPlugin_Sketch* sketch(); /// initializes mySketch SketchPlugin_Feature(); diff --git a/src/SketchPlugin/SketchPlugin_Sketch.cpp b/src/SketchPlugin/SketchPlugin_Sketch.cpp index 19715af30..5efa1f77e 100644 --- a/src/SketchPlugin/SketchPlugin_Sketch.cpp +++ b/src/SketchPlugin/SketchPlugin_Sketch.cpp @@ -126,6 +126,11 @@ boost::shared_ptr SketchPlugin_Sketch::subFeature(const int th return boost::dynamic_pointer_cast(anObj); } +int SketchPlugin_Sketch::subFeatureId(const int theIndex) const +{ + return subFeature(theIndex)->data()->featureId(); +} + boost::shared_ptr SketchPlugin_Sketch::to3D(const double theX, const double theY) { boost::shared_ptr aC = boost::dynamic_pointer_cast( diff --git a/src/SketchPlugin/SketchPlugin_Sketch.h b/src/SketchPlugin/SketchPlugin_Sketch.h index b655ebe9a..79b478f7c 100644 --- a/src/SketchPlugin/SketchPlugin_Sketch.h +++ b/src/SketchPlugin/SketchPlugin_Sketch.h @@ -123,6 +123,9 @@ class SketchPlugin_Sketch : public ModelAPI_CompositeFeature, public GeomAPI_IPr SKETCHPLUGIN_EXPORT virtual boost::shared_ptr subFeature(const int theIndex) const; + /// Returns the sub-feature unique identifier in this composite feature by zero-base index + SKETCHPLUGIN_EXPORT virtual int subFeatureId(const int theIndex) const; + /// Construction result is allways recomuted on the fly SKETCHPLUGIN_EXPORT virtual bool isPersistentResult() {return false;} -- 2.39.2