]> SALOME platform Git repositories - modules/shaper.git/commitdiff
Salome HOME
Merge branch 'master' of newgeom:newgeom
authornds <natalia.donis@opencascade.com>
Fri, 24 Oct 2014 10:09:52 +0000 (14:09 +0400)
committernds <natalia.donis@opencascade.com>
Fri, 24 Oct 2014 10:09:52 +0000 (14:09 +0400)
42 files changed:
src/FeaturesPlugin/FeaturesPlugin_Group.cpp
src/FeaturesPlugin/FeaturesPlugin_Group.h
src/FeaturesPlugin/group_widget.xml
src/GeomAPI/GeomAPI_AISObject.cpp
src/GeomAPI/GeomAPI_AISObject.h
src/GeomAPI/GeomAPI_Shape.h
src/GeomAPI/GeomAPI_Wire.h
src/Model/CMakeLists.txt
src/Model/Model_AttributeSelection.cpp
src/Model/Model_AttributeSelection.h
src/Model/Model_AttributeSelectionList.cpp
src/Model/Model_Data.cpp
src/Model/Model_Data.h
src/Model/Model_Update.cpp
src/ModelAPI/ModelAPI_AttributeSelection.h
src/ModelAPI/ModelAPI_AttributeSelectionList.h
src/ModelAPI/ModelAPI_CompositeFeature.h
src/ModelAPI/ModelAPI_Data.h
src/ModuleBase/ModuleBase_ISelection.h
src/ModuleBase/ModuleBase_WidgetMultiSelector.cpp
src/ModuleBase/ModuleBase_WidgetMultiSelector.h
src/ModuleBase/ModuleBase_WidgetShapeSelector.cpp
src/PartSet/PartSet_OperationFeatureEdit.cpp
src/PartSet/PartSet_icons.qrc
src/PartSet/icons/fixed.png [new file with mode: 0644]
src/SketchPlugin/SketchPlugin_Arc.cpp
src/SketchPlugin/SketchPlugin_Arc.h
src/SketchPlugin/SketchPlugin_Circle.cpp
src/SketchPlugin/SketchPlugin_Circle.h
src/SketchPlugin/SketchPlugin_ConstraintRigid.cpp
src/SketchPlugin/SketchPlugin_ConstraintRigid.h
src/SketchPlugin/SketchPlugin_Feature.cpp
src/SketchPlugin/SketchPlugin_Feature.h
src/SketchPlugin/SketchPlugin_Line.cpp
src/SketchPlugin/SketchPlugin_Line.h
src/SketchPlugin/SketchPlugin_Point.cpp
src/SketchPlugin/SketchPlugin_Point.h
src/SketchPlugin/SketchPlugin_Sketch.cpp
src/SketchPlugin/SketchPlugin_Sketch.h
src/SketchPlugin/plugin-Sketch.xml
src/XGUI/XGUI_Selection.cpp
src/XGUI/XGUI_Selection.h

index 4a5a34bc21f8077f78054ef9108b6d7c3d63da3b..dad22dbf60b9ec8b537c3aa1b2bc2e2f82cc206d 100644 (file)
@@ -8,6 +8,8 @@
 #include <ModelAPI_Document.h>
 #include <ModelAPI_AttributeInteger.h>
 #include <ModelAPI_AttributeString.h>
+#include <ModelAPI_AttributeSelectionList.h>
+
 
 using namespace std;
 
@@ -17,16 +19,16 @@ FeaturesPlugin_Group::FeaturesPlugin_Group()
 
 void FeaturesPlugin_Group::initAttributes()
 {
-  data()->addAttribute(FeaturesPlugin_Group::NAME_ID(), ModelAPI_AttributeString::type());
-  data()->addAttribute(FeaturesPlugin_Group::LIST_ID(), ModelAPI_AttributeString::type());
+  //data()->addAttribute(FeaturesPlugin_Group::NAME_ID(), ModelAPI_AttributeString::type());
+  data()->addAttribute(FeaturesPlugin_Group::LIST_ID(), ModelAPI_AttributeSelectionList::type());
 }
 
 void FeaturesPlugin_Group::execute()
 {
-  AttributeStringPtr aNameAttr = boost::dynamic_pointer_cast<ModelAPI_AttributeString>(
-      data()->attribute(FeaturesPlugin_Group::NAME_ID()));
-  if (!aNameAttr)
-    return;
-  std::string aName = aNameAttr->value();
-  data()->setName(aName);
+  //AttributeStringPtr aNameAttr = boost::dynamic_pointer_cast<ModelAPI_AttributeString>(
+  //    data()->attribute(FeaturesPlugin_Group::NAME_ID()));
+  //if (!aNameAttr)
+  //  return;
+  //std::string aName = aNameAttr->value();
+  //data()->setName(aName);
 }
index 34385caab13d67ea3f679f5882011ef9be8f2576..23078ae675c99b4b299724592b471d1930c182f3 100644 (file)
@@ -19,11 +19,11 @@ class FeaturesPlugin_Group : public ModelAPI_Feature
     return MY_GROUP_ID;
   }
   /// attribute name of group name
-  inline static const std::string& NAME_ID()
-  {
-    static const std::string MY_GROUP_NAME_ID("group_name");
-    return MY_GROUP_NAME_ID;
-  }
+  //inline static const std::string& NAME_ID()
+  //{
+  //  static const std::string MY_GROUP_NAME_ID("group_name");
+  //  return MY_GROUP_NAME_ID;
+  //}
   /// attribute name of selected entities list
   inline static const std::string& LIST_ID()
   {
index 5d8ad7565a8d812dcb66cdc6726e6fed19c6e79c..d4288b638b250c23bb6e971c411cd1aec1112c02 100644 (file)
@@ -1,8 +1,4 @@
 <source>
-  <stringvalue
-    id="group_name"
-    label="Name"
-    tooltip="Name of the group" />
   <multi_selector id="group_list" 
     tooltip="List of selected objects" 
     type_choice="Vertices Edges Faces Solids" /> 
index 22863757e8a855bdd25058438d88c99c827d74f4..de00d5a436b33a88144ec9e07bca6a0b11ce77f5 100644 (file)
@@ -22,6 +22,7 @@
 #include <AIS_PerpendicularRelation.hxx>
 #include <AIS_RadiusDimension.hxx>
 #include <AIS_Shape.hxx>
+#include <AIS_FixRelation.hxx>
 
 const double tolerance = 1e-7;
 
@@ -219,6 +220,30 @@ void GeomAPI_AISObject::createPerpendicular(boost::shared_ptr<GeomAPI_Shape> the
   }
 }
 
+
+void GeomAPI_AISObject::createFixed(boost::shared_ptr<GeomAPI_Shape> theShape,
+                                    boost::shared_ptr<GeomAPI_Pln> thePlane)
+{
+  Handle(Geom_Plane) aPlane = new Geom_Plane(thePlane->impl<gp_Pln>());
+  Handle(AIS_InteractiveObject) anAIS = impl<Handle(AIS_InteractiveObject)>();
+  if (anAIS.IsNull()) {
+    Handle(AIS_FixRelation) aFixPrs = 
+      new AIS_FixRelation(theShape->impl<TopoDS_Shape>(), aPlane);
+
+    setImpl(new Handle(AIS_InteractiveObject)(aFixPrs));
+  } else {
+    Handle(AIS_PerpendicularRelation) aFixPrs = 
+      Handle(AIS_PerpendicularRelation)::DownCast(anAIS);
+    if (!aFixPrs.IsNull()) {
+      aFixPrs->SetFirstShape(theShape->impl<TopoDS_Shape>());
+      aFixPrs->SetPlane(aPlane);
+      aFixPrs->Redisplay(Standard_True);
+    }
+  }
+}
+
+
+
 void GeomAPI_AISObject::setColor(const int& theColor)
 {
   Handle(AIS_InteractiveObject) anAIS = impl<Handle(AIS_InteractiveObject)>();
index 574d39f137c26ed6688c73c77f830cc077eea80e..0c8034d0dd8038875e1baefb3053c96bf7c03bb3 100644 (file)
@@ -77,6 +77,13 @@ class GEOMAPI_EXPORT GeomAPI_AISObject : public GeomAPI_Interface
                            boost::shared_ptr<GeomAPI_Shape> theLine2,
                            boost::shared_ptr<GeomAPI_Pln> thePlane);
 
+  /** \brief Creates AIS_FixedRelation object for an object
+   *  \param[in] theShape       the object
+   *  \param[in] thePlane       the plane which contains the lines
+   */
+  void createFixed(boost::shared_ptr<GeomAPI_Shape> theShape,
+                   boost::shared_ptr<GeomAPI_Pln> thePlane);
+
   /** \brief Assigns the color for the shape
    *  \param[in] theColor index of the color
    */
index 3aa0987f7e2fbaca01552535628838c75ace50f7..96db714562f42983e3730546629d62bb049c306e 100644 (file)
@@ -31,4 +31,7 @@ class GEOMAPI_EXPORT GeomAPI_Shape : public GeomAPI_Interface
 
 };
 
+//! Pointer on attribute object
+typedef boost::shared_ptr<GeomAPI_Shape> GeomShapePtr;
+
 #endif
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..9c71730a021a647bef420f490b566f0c6cdb8c29 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,102 @@ void Model_AttributeSelection::setObject(const boost::shared_ptr<ModelAPI_Object
   myRef.setObject(theObject);
 }
 
+bool Model_AttributeSelection::update()
+{
+  ResultPtr aContext = context();
+  if (!aContext) return false;
+  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 +215,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 +235,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 848341184cbb452fe03d9b38ff17e288976bb158..31a2e6473fac8d178f86dc21c3fcad510c595558 100644 (file)
@@ -17,9 +17,16 @@ void Model_AttributeSelectionList::append(
 {
   int aNewTag = mySize->Get() + 1;
   TDF_Label aNewLab = mySize->Label().FindChild(aNewTag);
-  mySubs.push_back(boost::shared_ptr<Model_AttributeSelection>(
-    new Model_AttributeSelection(aNewLab)));
+
+  boost::shared_ptr<Model_AttributeSelection> aNewAttr = 
+    boost::shared_ptr<Model_AttributeSelection>(new Model_AttributeSelection(aNewLab));
+  if (owner()) {
+    aNewAttr->setObject(owner());
+  }
+  mySubs.push_back(aNewAttr);
   mySize->Set(aNewTag);
+  aNewAttr->setValue(theContext, theSubShape);
+  owner()->data()->sendAttributeUpdated(this);
 }
 
 int Model_AttributeSelectionList::size()
@@ -35,10 +42,13 @@ boost::shared_ptr<ModelAPI_AttributeSelection>
 
 void Model_AttributeSelectionList::clear()
 {
-  mySubs.clear();
-  TDF_ChildIterator aSubIter(mySize->Label());
-  for(; aSubIter.More(); aSubIter.Next()) {
-    aSubIter.Value().ForgetAllAttributes(Standard_True);
+  if (!mySubs.empty()) {
+    mySubs.clear();
+    TDF_ChildIterator aSubIter(mySize->Label());
+    for(; aSubIter.More(); aSubIter.Next()) {
+      aSubIter.Value().ForgetAllAttributes(Standard_True);
+    }
+    owner()->data()->sendAttributeUpdated(this);
   }
 }
 
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..5ef4a8f098d65d9383f74425ca700e106a6c14df 100644 (file)
@@ -11,6 +11,8 @@
 #include <ModelAPI_AttributeReference.h>
 #include <ModelAPI_AttributeRefList.h>
 #include <ModelAPI_AttributeRefAttr.h>
+#include <ModelAPI_AttributeSelection.h>
+#include <ModelAPI_AttributeSelectionList.h>
 #include <ModelAPI_Result.h>
 #include <ModelAPI_Validator.h>
 #include <ModelAPI_CompositeFeature.h>
@@ -179,6 +181,27 @@ 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(); // this must be done on execution since it may be long operation
+      }
+    }
+    // lists of selection attributes: must be called "update" methods if needed
+    aRefs = theFeature->data()->attributes(ModelAPI_AttributeSelectionList::type());
+    for (aRefsIter = aRefs.begin(); aRefsIter != aRefs.end(); aRefsIter++) {
+      boost::shared_ptr<ModelAPI_AttributeSelectionList> aSel =
+        boost::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(*aRefsIter);
+      for(int a = aSel->size() - 1; a >= 0; a--) {
+        if (updateObject(aSel->value(a)->context())) {
+          aMustbeUpdated = true;
+        }
+      }
+    }
 
     // execute feature if it must be updated
     if (aMustbeUpdated) {
@@ -188,7 +211,24 @@ bool Model_Update::updateFeature(FeaturePtr theFeature)
         ModelAPI_ValidatorsFactory* aFactory = ModelAPI_Session::get()->validators();
         if (aFactory->validate(theFeature)) {
           if (isAutomatic || (myJustCreatedOrUpdated.find(theFeature) != myJustCreatedOrUpdated.end()) ||
-            !theFeature->isPersistentResult() /* execute quick, not persistent results */) {
+            !theFeature->isPersistentResult() /* execute quick, not persistent results */) 
+          {
+            // before execution update the selection attributes if any
+            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);
+              aSel->update(); // this must be done on execution since it may be long operation
+            }
+            aRefs = theFeature->data()->attributes(ModelAPI_AttributeSelectionList::type());
+            for (aRefsIter = aRefs.begin(); aRefsIter != aRefs.end(); aRefsIter++) {
+              boost::shared_ptr<ModelAPI_AttributeSelectionList> aSel =
+                boost::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(*aRefsIter);
+              for(int a = aSel->size() - 1; a >= 0; a--) {
+                aSel->value(a)->update();
+              }
+            }
+            // execute in try-catch to avoid internal problems of the feature
             try {
               theFeature->execute();
             } catch(...) {
index 98d4af7d625254d2b76c55303a811ad808c51008..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()
   {
@@ -50,4 +54,7 @@ class ModelAPI_AttributeSelection : public ModelAPI_Attribute
   }
 };
 
+//! Pointer on double attribute
+typedef boost::shared_ptr<ModelAPI_AttributeSelection> AttributeSelectionPtr;
+
 #endif
index 4305471d3c655a9be795a976732b010a1557952c..6dc13dd3a6b35c9a8467b16af7efe4e010c8c8e1 100644 (file)
@@ -54,4 +54,7 @@ class ModelAPI_AttributeSelectionList : public ModelAPI_Attribute
   }
 };
 
+//! Pointer on double attribute
+typedef boost::shared_ptr<ModelAPI_AttributeSelectionList> AttributeSelectionListPtr;
+
 #endif
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 43bd0ea86650863887c248c69ac603b3059a73ff..72845616b89eea80aad2a15e2175a7d42a506a31 100644 (file)
@@ -47,7 +47,8 @@ class ModuleBase_ISelection
   virtual void selectedAISObjects(AIS_ListOfInteractive& theList) const = 0;
 
   //! Returns list of currently selected shapes
-  virtual void selectedShapes(NCollection_List<TopoDS_Shape>& theList) const = 0;
+  virtual void selectedShapes(NCollection_List<TopoDS_Shape>& theList, 
+    std::list<ObjectPtr>& theOwners) const = 0;
 
 };
 
index 189b659c4d2f89a281b1f8e895fb608f9d2ac8b9..ed40ee20434af9d1fb022043a90e13be7f2f84f2 100644 (file)
 #include <ModuleBase_IWorkshop.h>
 #include <ModuleBase_Tools.h>
 
-#include <ModelAPI_AttributeString.h>
 #include <ModelAPI_Data.h>
 #include <ModelAPI_Object.h>
-#include <ModelAPI_Validator.h>
+#include <ModelAPI_AttributeSelectionList.h>
 
 #include <Config_WidgetAPI.h>
 
 #include <QGridLayout>
 #include <QLabel>
-#include <QTextEdit>
+#include <QListWidget>
 #include <QObject>
 #include <QString>
 #include <QComboBox>
@@ -39,17 +38,21 @@ ModuleBase_WidgetMultiSelector::ModuleBase_WidgetMultiSelector(QWidget* theParen
   myMainWidget = new QWidget(theParent);
   QGridLayout* aMainLay = new QGridLayout(myMainWidget);
   ModuleBase_Tools::adjustMargins(aMainLay);
+
   QLabel* aTypeLabel = new QLabel(tr("Type"), myMainWidget);
   aMainLay->addWidget(aTypeLabel, 0, 0);
+
   myTypeCombo = new QComboBox(myMainWidget);
-  std::string aTypes = theData->getProperty("type_choice");
-  myShapeTypes = QString::fromStdString(aTypes).split(' ');
+  // There is no sence to paramerize list of types while we can not parametrize selection mode
+  QString aTypesStr("Vertices Edges Faces Solids");
+  myShapeTypes = aTypesStr.split(' ');
   myTypeCombo->addItems(myShapeTypes);
   aMainLay->addWidget(myTypeCombo, 0, 1);
+
   QLabel* aListLabel = new QLabel(tr("Selected objects:"), myMainWidget);
   aMainLay->addWidget(aListLabel, 1, 0, 1, -1);
-  myListControl = new QTextEdit(myMainWidget);
-  myListControl->setReadOnly(true);
+
+  myListControl = new QListWidget(myMainWidget);
   aMainLay->addWidget(myListControl, 2, 0, 2, -1);
   aMainLay->setColumnStretch(1, 1);
   myMainWidget->setLayout(aMainLay);
@@ -66,40 +69,56 @@ ModuleBase_WidgetMultiSelector::~ModuleBase_WidgetMultiSelector()
   activateSelection(false);
 }
 
+//********************************************************************
 bool ModuleBase_WidgetMultiSelector::storeValue() const
 {
   // A rare case when plugin was not loaded. 
   if(!myFeature)
     return false;
   DataPtr aData = myFeature->data();
-  AttributeStringPtr aStringAttr = aData->string(attributeID());
-  QString aWidgetValue = myListControl->toPlainText();
-  aStringAttr->setValue(aWidgetValue.toStdString());
-  updateObject(myFeature);
-  return true;
+  AttributeSelectionListPtr aSelectionListAttr = 
+    boost::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(aData->attribute(attributeID()));
+
+  if (aSelectionListAttr && (mySelection.size() > 0)) {
+    aSelectionListAttr->clear();
+    foreach (GeomSelection aSelec, mySelection) {
+      aSelectionListAttr->append(aSelec.first, aSelec.second);
+    }
+    updateObject(myFeature);
+    return true;
+  }
+  return false;
 }
 
+//********************************************************************
 bool ModuleBase_WidgetMultiSelector::restoreValue()
 {
-  return false;
   // A rare case when plugin was not loaded. 
   if(!myFeature)
     return false;
   DataPtr aData = myFeature->data();
-  AttributeStringPtr aStringAttr = aData->string(attributeID());
-
-  bool isBlocked = myListControl->blockSignals(true);
-  myListControl->setText(QString::fromStdString(aStringAttr->value()));
-  myListControl->blockSignals(isBlocked);
-
-  return true;
+  AttributeSelectionListPtr aSelectionListAttr = 
+    boost::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(aData->attribute(attributeID()));
+
+  if (aSelectionListAttr) {
+    mySelection.clear();
+    for (int i = 0; i < aSelectionListAttr->size(); i++) {
+      AttributeSelectionPtr aSelectAttr = aSelectionListAttr->value(i);
+      mySelection.append(GeomSelection(aSelectAttr->context(), aSelectAttr->value()));
+    }
+    updateSelectionList();
+    return true;
+  }
+  return false;
 }
 
+//********************************************************************
 QWidget* ModuleBase_WidgetMultiSelector::getControl() const
 {
   return myMainWidget;
 }
 
+//********************************************************************
 QList<QWidget*> ModuleBase_WidgetMultiSelector::getControls() const
 {
   QList<QWidget*> result;
@@ -118,19 +137,55 @@ bool ModuleBase_WidgetMultiSelector::eventFilter(QObject* theObj, QEvent* theEve
   return ModuleBase_ModelWidget::eventFilter(theObj, theEvent);
 }
 
+//********************************************************************
 void ModuleBase_WidgetMultiSelector::onSelectionChanged()
 {
   ModuleBase_ISelection* aSelection = myWorkshop->selection();
-  NCollection_List<TopoDS_Shape> aSelectedShapes, aFilteredShapes;
-  aSelection->selectedShapes(aSelectedShapes);
-  QString aText;
-  if (!aSelectedShapes.IsEmpty()) {
-    filterShapes(aSelectedShapes, aFilteredShapes);
-    aText = QString("Items selected: %1").arg(aFilteredShapes.Size());
+  NCollection_List<TopoDS_Shape> aSelectedShapes; //, aFilteredShapes;
+  std::list<ObjectPtr> aOwnersList;
+  aSelection->selectedShapes(aSelectedShapes, aOwnersList);
+
+  mySelection.clear();
+  std::list<ObjectPtr>::const_iterator aIt;
+  NCollection_List<TopoDS_Shape>::Iterator aShpIt(aSelectedShapes);
+  GeomShapePtr aShape;
+  for (aIt = aOwnersList.cbegin(); aIt != aOwnersList.cend(); aShpIt.Next(), aIt++) {
+    ResultPtr aResult = boost::dynamic_pointer_cast<ModelAPI_Result>(*aIt);
+    aShape = boost::shared_ptr<GeomAPI_Shape>(new GeomAPI_Shape());
+    aShape->setImpl(new TopoDS_Shape(aShpIt.Value()));
+    mySelection.append(GeomSelection(aResult, aShape));
   }
-  myListControl->setText(aText);
+  updateSelectionList();
+  storeValue();
+  emit valuesChanged();
 }
 
+
+//********************************************************************
+void ModuleBase_WidgetMultiSelector::updateSelectionList()
+{
+  QString aType;
+  if (myTypeCombo->currentText().toLower() == "vertices")
+    aType = "vertex";
+  else if (myTypeCombo->currentText().toLower() == "edges")
+    aType = "edge";
+  else if (myTypeCombo->currentText().toLower() == "faces")
+    aType = "face";
+  else if (myTypeCombo->currentText().toLower() == "solids")
+    aType = "solid";
+  myListControl->clear();
+  int i = 1;
+  foreach (GeomSelection aSel, mySelection) {
+    QString aName(aSel.first->data()->name().c_str());
+    aName += ":" + aType + QString("_%1").arg(i);
+    myListControl->addItem(aName);
+    i++;
+  }
+}
+
+
+//********************************************************************
 void ModuleBase_WidgetMultiSelector::filterShapes(const NCollection_List<TopoDS_Shape>& theShapesToFilter,
                                                   NCollection_List<TopoDS_Shape>& theResult)
 {
@@ -147,6 +202,7 @@ void ModuleBase_WidgetMultiSelector::filterShapes(const NCollection_List<TopoDS_
   }
 }
 
+//********************************************************************
 void ModuleBase_WidgetMultiSelector::activateSelection(bool toActivate)
 {
   myIsActive = toActivate;
@@ -159,6 +215,7 @@ void ModuleBase_WidgetMultiSelector::activateSelection(bool toActivate)
   }
 }
 
+//********************************************************************
 void ModuleBase_WidgetMultiSelector::onSelectionTypeChanged()
 {
   QString aNewType = myTypeCombo->currentText();
index bc184d5e57323fb3c08d0f289e634a232434e130..c141c87e97d77fd96dddae7147473173afc8a547 100644 (file)
 #include <ModuleBase.h>
 #include <ModuleBase_ModelWidget.h>
 
+#include <GeomAPI_Shape.h>
+#include <ModelAPI_Result.h>
+
 #include <NCollection_List.hxx>
 #include <TopoDS_Shape.hxx>
 
 #include <QList>
 #include <QString>
 #include <QStringList>
+#include <QPair>
 
 class QWidget;
-class QTextEdit;
+class QListWidget;
 class QComboBox;
 class ModuleBase_IWorkshop;
 
@@ -59,7 +63,9 @@ class MODULEBASE_EXPORT ModuleBase_WidgetMultiSelector : public ModuleBase_Model
                     NCollection_List<TopoDS_Shape>& theResult);
 
  private:
-  QTextEdit* myListControl;
+   void updateSelectionList();
+
+  QListWidget* myListControl;
   QComboBox* myTypeCombo;
   QWidget* myMainWidget;
 
@@ -70,6 +76,9 @@ class MODULEBASE_EXPORT ModuleBase_WidgetMultiSelector : public ModuleBase_Model
   QStringList myShapeTypes;
   bool myUseSubShapes;
   bool myIsActive;
+
+  typedef QPair<ResultPtr, GeomShapePtr> GeomSelection;
+  QList<GeomSelection> mySelection;
 };
 
 #endif /* MODULEBASE_WIDGETFILESELECTOR_H_ */
index d68309a4f6defcdc2d0790500e3c8b8f69d5961f..47045007066d2890123230111f8352465ea8efc1 100644 (file)
@@ -194,7 +194,8 @@ void ModuleBase_WidgetShapeSelector::onSelectionChanged()
     boost::shared_ptr<GeomAPI_Shape> aShape;
     if (myUseSubShapes) {
       NCollection_List<TopoDS_Shape> aShapeList;
-      myWorkshop->selection()->selectedShapes(aShapeList);
+      std::list<ObjectPtr> aOwners;
+      myWorkshop->selection()->selectedShapes(aShapeList, aOwners);
       if (aShapeList.Extent() > 0) {
         aShape = boost::shared_ptr<GeomAPI_Shape>(new GeomAPI_Shape());
         aShape->setImpl(new TopoDS_Shape(aShapeList.First()));
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 63e9b6e5e49f22dc03e871a8a354e5c2f5ac0dfd..d0985d40c5d7573a235bb9a03823ae65bdd2bda7 100644 (file)
@@ -26,5 +26,6 @@
      <file>icons/distance.png</file>
      <file>icons/radius_constr.png</file>
      <file>icons/shape_group.png</file>
+     <file>icons/fixed.png</file>
  </qresource>
  </RCC>
diff --git a/src/PartSet/icons/fixed.png b/src/PartSet/icons/fixed.png
new file mode 100644 (file)
index 0000000..0a64532
Binary files /dev/null and b/src/PartSet/icons/fixed.png differ
index 21e616aef9b61b0e7fc846ede607cab03787eac6..ec9d227deec81d97d63e91b2eec985cee2d73a7b 100644 (file)
@@ -6,6 +6,8 @@
 #include "SketchPlugin_Sketch.h"
 #include <ModelAPI_Data.h>
 #include <ModelAPI_ResultConstruction.h>
+#include <ModelAPI_AttributeSelection.h>
+#include <ModelAPI_Validator.h>
 
 #include <GeomAPI_Circ2d.h>
 #include <GeomAPI_Pnt2d.h>
@@ -24,9 +26,11 @@ SketchPlugin_Arc::SketchPlugin_Arc()
 
 void SketchPlugin_Arc::initAttributes()
 {
-  data()->addAttribute(SketchPlugin_Arc::CENTER_ID(), GeomDataAPI_Point2D::type());
-  data()->addAttribute(SketchPlugin_Arc::START_ID(), GeomDataAPI_Point2D::type());
-  data()->addAttribute(SketchPlugin_Arc::END_ID(), GeomDataAPI_Point2D::type());
+  data()->addAttribute(CENTER_ID(), GeomDataAPI_Point2D::type());
+  data()->addAttribute(START_ID(), GeomDataAPI_Point2D::type());
+  data()->addAttribute(END_ID(), GeomDataAPI_Point2D::type());
+  data()->addAttribute(EXTERNAL_ID(), ModelAPI_AttributeSelection::type());
+  ModelAPI_Session::get()->validators()->registerNotObligatory(getKind(), EXTERNAL_ID());
 }
 
 void SketchPlugin_Arc::execute()
@@ -138,3 +142,7 @@ double SketchPlugin_Arc::distanceToPoint(const boost::shared_ptr<GeomAPI_Pnt2d>&
 
   return aDelta;
 }
+
+bool SketchPlugin_Arc::isFixed() {
+  return data()->selection(EXTERNAL_ID())->context();
+}
index 00ada99b0c1f797dd497c6834a99521af2bf460d..3ee2ba8e714c0bfa2a271d89fea9ae1eb104d114 100644 (file)
@@ -50,6 +50,9 @@ class SketchPlugin_Arc : public SketchPlugin_Feature  //, public GeomAPI_IPresen
     return MY_KIND;
   }
 
+  /// Returns true is sketch element is under the rigid constraint
+  SKETCHPLUGIN_EXPORT virtual bool isFixed();
+
   /// Creates an arc-shape
   SKETCHPLUGIN_EXPORT virtual void execute();
 
index 635214f42fa39c3b70a7b92fcc0ce11aee90397e..4828a0f7b91a7b247e6e833caa30d6abaf493664 100644 (file)
@@ -6,6 +6,8 @@
 #include "SketchPlugin_Sketch.h"
 #include <ModelAPI_Data.h>
 #include <ModelAPI_ResultConstruction.h>
+#include <ModelAPI_AttributeSelection.h>
+#include <ModelAPI_Validator.h>
 
 #include <GeomAPI_Pnt2d.h>
 #include <GeomDataAPI_Point2D.h>
@@ -24,6 +26,8 @@ void SketchPlugin_Circle::initAttributes()
 {
   data()->addAttribute(SketchPlugin_Circle::CENTER_ID(), GeomDataAPI_Point2D::type());
   data()->addAttribute(SketchPlugin_Circle::RADIUS_ID(), ModelAPI_AttributeDouble::type());
+  data()->addAttribute(EXTERNAL_ID(), ModelAPI_AttributeSelection::type());
+  ModelAPI_Session::get()->validators()->registerNotObligatory(getKind(), EXTERNAL_ID());
 }
 
 void SketchPlugin_Circle::execute()
@@ -98,3 +102,7 @@ double SketchPlugin_Circle::distanceToPoint(const boost::shared_ptr<GeomAPI_Pnt2
 
   return aPoint->pnt()->distance(thePoint);
 }
+
+bool SketchPlugin_Circle::isFixed() {
+  return data()->selection(EXTERNAL_ID())->context();
+}
index c489f1014c45c8c6c5ad7320881a717240c6ba51..11311dcb0da8c230e74ce32ee5623e8797ea2841 100644 (file)
@@ -45,6 +45,9 @@ class SketchPlugin_Circle : public SketchPlugin_Feature  //, public GeomAPI_IPre
     return MY_KIND;
   }
 
+  /// Returns true is sketch element is under the rigid constraint
+  SKETCHPLUGIN_EXPORT virtual bool isFixed();
+
   /// Creates a new part document if needed
   SKETCHPLUGIN_EXPORT virtual void execute();
 
index b1cd1708bfbab8a93da24c2f25707b3c4748fdee..c9763327e2b6f23f97452473eef478a45c902b2a 100644 (file)
@@ -4,6 +4,8 @@
 
 #include "SketchPlugin_ConstraintRigid.h"
 
+#include <ModelAPI_ResultConstruction.h>
+
 SketchPlugin_ConstraintRigid::SketchPlugin_ConstraintRigid()
 {
 }
@@ -16,3 +18,37 @@ void SketchPlugin_ConstraintRigid::initAttributes()
 void SketchPlugin_ConstraintRigid::execute()
 {
 }
+
+AISObjectPtr SketchPlugin_ConstraintRigid::getAISObject(AISObjectPtr thePrevious)
+{
+  if (!sketch())
+    return thePrevious;
+
+  boost::shared_ptr<ModelAPI_Data> aData = data();
+  boost::shared_ptr<ModelAPI_AttributeRefAttr> anAttr = boost::dynamic_pointer_cast<
+      ModelAPI_AttributeRefAttr>(aData->attribute(SketchPlugin_Constraint::ENTITY_A()));
+  if (!anAttr || !anAttr->isObject())
+    return thePrevious;
+
+  boost::shared_ptr<ModelAPI_ResultConstruction> aConst = 
+    boost::dynamic_pointer_cast<ModelAPI_ResultConstruction>(anAttr->object());
+  if (!aConst) 
+    return thePrevious;
+
+  boost::shared_ptr<GeomAPI_Shape> aShape;
+  aShape = aConst->shape();
+
+  AISObjectPtr anAIS = thePrevious;
+  if (!anAIS)
+    anAIS = AISObjectPtr(new GeomAPI_AISObject);
+
+  boost::shared_ptr<GeomAPI_Pln> aPlane = sketch()->plane();
+  anAIS->createFixed(aShape, aPlane);
+
+  // Set color from preferences
+  //std::vector<int> aRGB = Config_PropManager::color("Visualization", "perpendicular_color",
+  //                                                  PERPENDICULAR_COLOR);
+  //anAIS->setColor(aRGB[0], aRGB[1], aRGB[2]);
+
+  return anAIS;
+}
\ No newline at end of file
index dd66a6f636f4f2b734f976ffedce5a131673d42b..8816ea4b632d9658bb38748db79b24e0a3e3fade 100644 (file)
@@ -33,6 +33,9 @@ class SketchPlugin_ConstraintRigid : public SketchPlugin_ConstraintBase
     return MY_KIND;
   }
 
+  /// Returns the AIS preview
+  SKETCHPLUGIN_EXPORT virtual AISObjectPtr getAISObject(AISObjectPtr thePrevious);
+
   /// \brief Creates a new part document if needed
   SKETCHPLUGIN_EXPORT virtual void execute();
 
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..97a2d423bd605102a579461c1774ac305baff60e 100644 (file)
@@ -27,6 +27,13 @@ class SketchPlugin_Feature : public ModelAPI_Feature
   static AISObjectPtr simpleAISObject(boost::shared_ptr<ModelAPI_Result> theRes,
                                       AISObjectPtr thePrevious);
 
+  /// Reference to the external edge or vertex as a AttributeSelection
+  inline static const std::string& EXTERNAL_ID()
+  {
+    static const std::string MY_EXTERNAL_ID("External");
+    return MY_EXTERNAL_ID;
+  }
+
   /// Returns true if this feature must be displayed in the history (top level of Part tree)
   SKETCHPLUGIN_EXPORT virtual bool isInHistory()
   {
@@ -45,14 +52,17 @@ class SketchPlugin_Feature : public ModelAPI_Feature
   /// Construction result is allways recomuted on the fly
   SKETCHPLUGIN_EXPORT virtual bool isPersistentResult() {return false;}
 
+  /// Returns true is sketch element is under the rigid constraint
+  SKETCHPLUGIN_EXPORT virtual bool isFixed() {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 8ae5384bb42cbf8bf057472fe2e64534a6502ce1..72a20f8618db061541c325f0ca7162a8f8d992ff 100644 (file)
@@ -6,6 +6,8 @@
 #include "SketchPlugin_Sketch.h"
 #include <ModelAPI_Data.h>
 #include <ModelAPI_ResultConstruction.h>
+#include <ModelAPI_AttributeSelection.h>
+#include <ModelAPI_Validator.h>
 
 #include <GeomAPI_Pnt.h>
 #include <GeomAPI_Lin2d.h>
@@ -25,6 +27,8 @@ void SketchPlugin_Line::initAttributes()
 {
   data()->addAttribute(SketchPlugin_Line::START_ID(), GeomDataAPI_Point2D::type());
   data()->addAttribute(SketchPlugin_Line::END_ID(), GeomDataAPI_Point2D::type());
+  data()->addAttribute(EXTERNAL_ID(), ModelAPI_AttributeSelection::type());
+  ModelAPI_Session::get()->validators()->registerNotObligatory(getKind(), EXTERNAL_ID());
 }
 
 void SketchPlugin_Line::execute()
@@ -88,3 +92,7 @@ double SketchPlugin_Line::distanceToPoint(const boost::shared_ptr<GeomAPI_Pnt2d>
 
   return aDelta;
 }
+
+bool SketchPlugin_Line::isFixed() {
+  return data()->selection(EXTERNAL_ID())->context();
+}
index d2656e5d83ec89dfaa0360aa6a2b618947a3b8c7..d24f1af52701f79fe25d0ee6b9f6136fcd033f92 100644 (file)
@@ -43,6 +43,9 @@ class SketchPlugin_Line : public SketchPlugin_Feature
     return MY_KIND;
   }
 
+  /// Returns true is sketch element is under the rigid constraint
+  SKETCHPLUGIN_EXPORT virtual bool isFixed();
+
   /// Creates a new part document if needed
   SKETCHPLUGIN_EXPORT virtual void execute();
 
index 5e8f2a65ebd45761393ef070c5b0e8d4ef9c9410..c198e9b90fd22c44e7c066ea30ee88a022aa2df1 100644 (file)
@@ -7,6 +7,8 @@
 
 #include <ModelAPI_Data.h>
 #include <ModelAPI_ResultConstruction.h>
+#include <ModelAPI_AttributeSelection.h>
+#include <ModelAPI_Validator.h>
 
 #include <GeomAPI_Pnt2d.h>
 
@@ -22,6 +24,8 @@ SketchPlugin_Point::SketchPlugin_Point()
 void SketchPlugin_Point::initAttributes()
 {
   data()->addAttribute(SketchPlugin_Point::COORD_ID(), GeomDataAPI_Point2D::type());
+  data()->addAttribute(EXTERNAL_ID(), ModelAPI_AttributeSelection::type());
+  ModelAPI_Session::get()->validators()->registerNotObligatory(getKind(), EXTERNAL_ID());
 }
 
 void SketchPlugin_Point::execute()
@@ -61,3 +65,7 @@ double SketchPlugin_Point::distanceToPoint(const boost::shared_ptr<GeomAPI_Pnt2d
 
   return aPoint->pnt()->distance(thePoint);
 }
+
+bool SketchPlugin_Point::isFixed() {
+  return data()->selection(EXTERNAL_ID())->context();
+}
index 14f58740248eed1215cf5c980e688d4fa48483d8..48415b18ccf83a6b3592aa9c226b6b83c6f8dcb9 100644 (file)
@@ -36,6 +36,9 @@ class SketchPlugin_Point : public SketchPlugin_Feature
     return MY_KIND;
   }
 
+  /// Returns true is sketch element is under the rigid constraint
+  SKETCHPLUGIN_EXPORT virtual bool isFixed();
+
   /// Creates a new part document if needed
   SKETCHPLUGIN_EXPORT virtual void execute();
 
index 19098b784e60b19f057bd9d27061ca147df93884..d0ebbbf8e0957c752c1cfb19c5ceafe627efc57f 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;}
 
index 9bcc261fda21d6bf68b8adb8fc9024938d390f6c..9e212a4fabc9cd972e63e994dd1d87c288cc8685 100644 (file)
@@ -93,7 +93,7 @@
         <validator id="PartSet_PerpendicularValidator"/>
       </feature>
 
-      <feature id="SketchConstraintRigid" title="Rigid" tooltip="Create constraint defining fixed object" icon="">
+      <feature id="SketchConstraintRigid" title="Fixed" tooltip="Create constraint defining fixed object" icon=":icons/fixed.png">
         <feature_selector id="ConstraintEntityA" label="Object" tooltip="Select any object in the viewer">
           <validator id="SketchPlugin_ResultPoint"/>
           <validator id="SketchPlugin_ResultLine"/>
index d39e31359aff576cb559a684bc691afbb432a15c..1b91cb3dccad3b2dc905d617c40f91ebf8b16474 100644 (file)
@@ -111,13 +111,20 @@ void XGUI_Selection::selectedAISObjects(AIS_ListOfInteractive& theList) const
 }
 
 //**************************************************************
-void XGUI_Selection::selectedShapes(NCollection_List<TopoDS_Shape>& theList) const
+void XGUI_Selection::selectedShapes(NCollection_List<TopoDS_Shape>& theList, 
+                                    std::list<ObjectPtr>& theOwners) const
 {
   theList.Clear();
   Handle(AIS_InteractiveContext) aContext = myWorkshop->viewer()->AISContext();
   for (aContext->InitSelected(); aContext->MoreSelected(); aContext->NextSelected()) {
     TopoDS_Shape aShape = aContext->SelectedShape();
-    if (!aShape.IsNull())
+    if (!aShape.IsNull()) {
       theList.Append(aShape);
+      Handle(SelectMgr_EntityOwner) aEO = aContext->SelectedOwner();
+      Handle(AIS_InteractiveObject) anObj = 
+        Handle(AIS_InteractiveObject)::DownCast(aEO->Selectable());
+      ObjectPtr anObject = myWorkshop->displayer()->getObject(anObj);
+      theOwners.push_back(anObject);
+    }
   }
 }
index b67adbc52e34b5da5b71e46f1ea32eadae53d7de..5f399a7ee32450f7ba0d3258a3d35b283d2c0154 100644 (file)
@@ -52,7 +52,8 @@ class XGUI_EXPORT XGUI_Selection : public ModuleBase_ISelection
   virtual void selectedAISObjects(AIS_ListOfInteractive& theList) const;
 
   //! Returns list of currently selected shapes
-  virtual void selectedShapes(NCollection_List<TopoDS_Shape>& theList) const;
+  virtual void selectedShapes(NCollection_List<TopoDS_Shape>& theShapes, 
+    std::list<ObjectPtr>& theOwners) const;
 
  private:
   XGUI_Workshop* myWorkshop;