Salome HOME
Implementation of naming parametrisation of sketch result
authormpv <mikhail.ponikarov@opencascade.com>
Thu, 23 Oct 2014 13:18:58 +0000 (17:18 +0400)
committermpv <mikhail.ponikarov@opencascade.com>
Thu, 23 Oct 2014 13:18:58 +0000 (17:18 +0400)
15 files changed:
src/GeomAPI/GeomAPI_Wire.h
src/Model/CMakeLists.txt
src/Model/Model_AttributeSelection.cpp
src/Model/Model_AttributeSelection.h
src/Model/Model_Data.cpp
src/Model/Model_Data.h
src/Model/Model_Update.cpp
src/ModelAPI/ModelAPI_AttributeSelection.h
src/ModelAPI/ModelAPI_CompositeFeature.h
src/ModelAPI/ModelAPI_Data.h
src/PartSet/PartSet_OperationFeatureEdit.cpp
src/SketchPlugin/SketchPlugin_Feature.cpp
src/SketchPlugin/SketchPlugin_Feature.h
src/SketchPlugin/SketchPlugin_Sketch.cpp
src/SketchPlugin/SketchPlugin_Sketch.h

index 4bc0e0cd9060ee1eb577f51c6d9505514adcffb7..86a4578307fb44c8ba9c1a3e1b1d7958be385523 100644 (file)
  * \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<GeomAPI_Shape> theEdge);
-  std::list<boost::shared_ptr<GeomAPI_Shape> > getEdges();
+  GEOMAPI_EXPORT void addEdge(boost::shared_ptr<GeomAPI_Shape> theEdge);
+  GEOMAPI_EXPORT std::list<boost::shared_ptr<GeomAPI_Shape> > 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<GeomAPI_Pnt>& theOrigin) { myOrigin = theOrigin; }
-  boost::shared_ptr<GeomAPI_Pnt> origin() const { return myOrigin; }
+  GEOMAPI_EXPORT void setOrigin(const boost::shared_ptr<GeomAPI_Pnt>& theOrigin) 
+  { myOrigin = theOrigin; }
+  GEOMAPI_EXPORT boost::shared_ptr<GeomAPI_Pnt> origin() const { return myOrigin; }
 
   /// Set/Get X direction vector
-  void setDirX(const boost::shared_ptr<GeomAPI_Dir>& theDirX) { myDirX = theDirX; }
-  boost::shared_ptr<GeomAPI_Dir> dirX() const { return myDirX; }
+  GEOMAPI_EXPORT void setDirX(const boost::shared_ptr<GeomAPI_Dir>& theDirX) { myDirX = theDirX; }
+  GEOMAPI_EXPORT boost::shared_ptr<GeomAPI_Dir> dirX() const { return myDirX; }
 
   /// Set/Get Y direction vector
-  void setDirY(const boost::shared_ptr<GeomAPI_Dir>& theDirY) { myDirY = theDirY; }
-  boost::shared_ptr<GeomAPI_Dir> dirY() const { return myDirY; }
+  GEOMAPI_EXPORT void setDirY(const boost::shared_ptr<GeomAPI_Dir>& theDirY) { myDirY = theDirY; }
+  GEOMAPI_EXPORT boost::shared_ptr<GeomAPI_Dir> dirY() const { return myDirY; }
 
   /// Set/Get Normal direction vector
-  void setNorm(const boost::shared_ptr<GeomAPI_Dir>& theNorm) { myNorm = theNorm; }
-  boost::shared_ptr<GeomAPI_Dir> norm() const { return myNorm; }
+  GEOMAPI_EXPORT void setNorm(const boost::shared_ptr<GeomAPI_Dir>& theNorm) { myNorm = theNorm; }
+  GEOMAPI_EXPORT boost::shared_ptr<GeomAPI_Dir> norm() const { return myNorm; }
 
 private:
   boost::shared_ptr<GeomAPI_Pnt> myOrigin;
index 25626636a6b84efb703e177012b6a97e7e2e0a29..1656a618f50738db0746fba46fc4ff0b86b23908 100644 (file)
@@ -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}
 )
index f55ee9f5e685e305a7dd8794b0e77bc01bd74467..f919cecd6e0d3ef9f75d6ecda22548d997f9a18b 100644 (file)
 #include <ModelAPI_ResultConstruction.h>
 #include <ModelAPI_CompositeFeature.h>
 #include <GeomAPI_Shape.h>
+#include <GeomAPI_Wire.h>
+#include <GeomAlgoAPI_SketchBuilder.h>
 
 #include <TNaming_Selector.hxx>
 #include <TNaming_NamedShape.hxx>
 #include <TNaming_Tool.hxx>
 #include <TNaming_Builder.hxx>
 #include <TopoDS_Shape.hxx>
-#include <TDataStd_ReferenceList.hxx>
+#include <TDataStd_IntPackedMap.hxx>
 #include <TopTools_MapOfShape.hxx>
 #include <TopExp_Explorer.hxx>
+#include <TDF_LabelMap.hxx>
+#include <BRep_Tool.hxx>
+#include <TopoDS_Edge.hxx>
+#include <TopoDS.hxx>
+#include <TColStd_MapOfTransient.hxx>
 
 using namespace std;
 
@@ -75,6 +82,101 @@ void Model_AttributeSelection::setObject(const boost::shared_ptr<ModelAPI_Object
   myRef.setObject(theObject);
 }
 
+bool Model_AttributeSelection::update()
+{
+  ResultPtr aContext = context();
+  if (aContext->groupName() == 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<GeomAPI_Wire> aWirePtr = boost::dynamic_pointer_cast<GeomAPI_Wire>(
+      boost::dynamic_pointer_cast<ModelAPI_ResultConstruction>(aContext)->shape());
+    if (aWirePtr && aWirePtr->hasPlane()) {
+        // If this is a wire with plane defined thin it is a sketch-like object
+      std::list<boost::shared_ptr<GeomAPI_Shape> > 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<Model_Data> aData = 
+        boost::dynamic_pointer_cast<Model_Data>(owner()->data());
+      TDF_Label aLab = aData->label();
+      Handle(TDataStd_IntPackedMap) aSubIds;
+      boost::shared_ptr<GeomAPI_Shape> 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<ModelAPI_CompositeFeature>(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<boost::shared_ptr<ModelAPI_Result> >& aResults = aSub->results();
+            std::list<boost::shared_ptr<ModelAPI_Result> >::const_iterator aRes = aResults.cbegin();
+            for(; aRes != aResults.cend(); aRes++) {
+              ResultConstructionPtr aConstr = 
+                boost::dynamic_pointer_cast<ModelAPI_ResultConstruction>(*aRes);
+              if (aConstr->shape()) {
+                const TopoDS_Shape& aResShape = aConstr->shape()->impl<TopoDS_Shape>();
+                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<boost::shared_ptr<GeomAPI_Shape> >::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<TopoDS_Shape>(), 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<GeomAPI_Shape>& 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<TopoDS_Shape>();
-  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<ModelAPI_ResultConstruction>(*aRes);
       if (aConstr->shape()) {
         const TopoDS_Shape& aResShape = aConstr->shape()->impl<TopoDS_Shape>();
-        if (allEdges.Contains(aResShape)) {
-          boost::shared_ptr<Model_Data> aSubData = boost::dynamic_pointer_cast<Model_Data>(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<Model_Data> aSubData = boost::dynamic_pointer_cast<Model_Data>(aSub->data());
+            TDF_Label aSubLab = aSubData->label();
+            aRefs->Add(aComposite->subFeatureId(a));
+          }
         }
       }
     }
index 2e71baea1c1406510278abcce44fdf12118a74ef..79ce151daf2fd6cd10c683f167cc15914e76a846 100644 (file)
@@ -31,6 +31,10 @@ public:
   /// Sets the feature object
   MODEL_EXPORT virtual void setObject(const boost::shared_ptr<ModelAPI_Object>& 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);
index 7b25cb2402ade82d8c1f59edd252cb414188cc11..b293bd3f9af914a6cf302e57f57d0325da9a53ff 100644 (file)
@@ -387,3 +387,8 @@ bool Model_Data::referencesTo(const boost::shared_ptr<ModelAPI_Feature>& theFeat
   }
   return false;
 }
+
+int Model_Data::featureId() const
+{
+  return myLab.Father().Tag(); // tag of the feature label
+}
index c923d79aff29905090c06d7c5044bb2ffe270a31..d61ddd6c2ca45302e1ef062982c815abf8302f63 100644 (file)
@@ -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<ModelAPI_Feature>& theFeature);
+
+  /// Returns the identifier of feature-owner, unique in this document
+  MODEL_EXPORT virtual int featureId() const;
+
 };
 
 #endif
index 7c3633aa78bb78c9b3f0ece80b194676a3aaa0dd..6d50871d74fe01702deec3174c9fbb0f811e3825 100644 (file)
@@ -11,6 +11,7 @@
 #include <ModelAPI_AttributeReference.h>
 #include <ModelAPI_AttributeRefList.h>
 #include <ModelAPI_AttributeRefAttr.h>
+#include <ModelAPI_AttributeSelection.h>
 #include <ModelAPI_Result.h>
 #include <ModelAPI_Validator.h>
 #include <ModelAPI_CompositeFeature.h>
@@ -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<ModelAPI_AttributeSelection> aSel =
+        boost::dynamic_pointer_cast<ModelAPI_AttributeSelection>(*aRefsIter);
+      if (updateObject(aSel->context())) {
+        aMustbeUpdated = true;
+        aSel->update();
+      }
+    }
+
 
     // execute feature if it must be updated
     if (aMustbeUpdated) {
index 08f5f6e5d85248b1f32e7f4b029bc4d79b479c56..40882dde44a8871b1ee8ec21e7afc328db6c53b7 100644 (file)
@@ -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()
   {
index 3c822e66e85f86c8db87c255c993c2c08f9a6dc8..28c4d6d2a4847523a0e7ebe6da0b52d253d53382 100644 (file)
@@ -24,6 +24,9 @@ public:
 
   /// Returns the sub-feature by zero-base index
   virtual boost::shared_ptr<ModelAPI_Feature> 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
index e9852e6e26a6936d70ab8e2eace6e1135eed5555..85c65cbd5fbab26156409800dcb267504ddff955 100644 (file)
@@ -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<ModelAPI_Feature>& 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()
index 70898eaf4798e7e27d78628aa9d1bf43c76a3243..16e2b44370ae89345e43b8faf42c09064ad472c9 100644 (file)
@@ -114,9 +114,12 @@ void PartSet_OperationFeatureEdit::mouseMoved(QMouseEvent* theEvent, Handle(V3d_
 
     boost::shared_ptr<SketchPlugin_Feature> 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();
 
index 9fd9ee2f662ab59ab4db0ec8ecd6d4ba1cb77106..da25c09994581e44f9153dc447b05979ad525c63 100644 (file)
@@ -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<ModelAPI_Result> theRes,
                                                    AISObjectPtr thePrevious)
index 24b856b1fd37dc3cd9be5f27cd05687a7dbcfb96..49bcc1320cc138cf75e76fcc8c81197631f83111 100644 (file)
@@ -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();
 
index 19715af301878f9e0bc47cb25cebcef8a7071d07..5efa1f77e9c4fb9ac3d01c764eed37cb57d0ca6e 100644 (file)
@@ -126,6 +126,11 @@ boost::shared_ptr<ModelAPI_Feature> SketchPlugin_Sketch::subFeature(const int th
   return boost::dynamic_pointer_cast<ModelAPI_Feature>(anObj);
 }
 
+int SketchPlugin_Sketch::subFeatureId(const int theIndex) const
+{
+  return subFeature(theIndex)->data()->featureId();
+}
+
 boost::shared_ptr<GeomAPI_Pnt> SketchPlugin_Sketch::to3D(const double theX, const double theY)
 {
   boost::shared_ptr<GeomDataAPI_Point> aC = boost::dynamic_pointer_cast<GeomDataAPI_Point>(
index b655ebe9a09dc9512253f49233c18ef71198d413..79b478f7cb1df43f693d667e37760ffb293de962 100644 (file)
@@ -123,6 +123,9 @@ class SketchPlugin_Sketch : public ModelAPI_CompositeFeature, public GeomAPI_IPr
   SKETCHPLUGIN_EXPORT virtual boost::shared_ptr<ModelAPI_Feature> 
     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;}