Salome HOME
Merge with Dev_1.5.0
authorspo <sergey.pokhodenko@opencascade.com>
Tue, 3 Nov 2015 14:12:45 +0000 (17:12 +0300)
committerspo <sergey.pokhodenko@opencascade.com>
Tue, 3 Nov 2015 14:12:45 +0000 (17:12 +0300)
1  2 
env_linux.sh
src/Model/Model_AttributeSelection.cpp
src/ModelAPI/ModelAPI_AttributeSelectionList.h
src/ModelAPI/ModelAPI_Document.h
src/ModelAPI/ModelAPI_Feature.h
src/PythonAddons/addons_Features.py
src/PythonAddons/macros/box/feature.py
src/SketchPlugin/plugin-Sketch.xml

diff --combined env_linux.sh
index 39157d4728f97769a8135aff3dec76f1e29e2399,379bdd24c0acdb28eaccf2fd6166be3170dcb83a..8d6cdc892908ecdd31b2699d5cedd5c405102274
@@@ -1,7 -1,20 +1,20 @@@
  #!/bin/bash
  
+ # This script uses:
+ #
+ # INST_ROOT - path of SALOME (env_products.sh)
+ # NEWGEOM_PDIR - path of PRODUCTS for NEWGEOM (SolveSpace, lcov)
+ # NEWGEOM_ROOT_DIR - path of NEWGEOM installation
+ for path in INST_ROOT NEWGEOM_PDIR NEWGEOM_ROOT_DIR; do
+   if [[ -z ${!path+x} ]]; then
+     echo "${path} not found."; exit 1
+   else
+     echo "Found ${path}: ${!path}"
+   fi
+ done
  set +u
- echo "Export SALOME from ${INST_ROOT}..."
  source ${INST_ROOT}/env_products.sh
  set -u
  
@@@ -25,9 -38,8 +38,8 @@@ export PATH=${CASROOT}:${PATH
  ##
  
  #------ NewGEOM ------
- export NEWGEOM_ROOT_DIR=${INSTALL_DIR}
  export PATH=${NEWGEOM_ROOT_DIR}/bin:${NEWGEOM_ROOT_DIR}/plugins:${PATH}
 -export PYTHONPATH=${NEWGEOM_ROOT_DIR}/swig:${NEWGEOM_ROOT_DIR}/plugins:${NEWGEOM_ROOT_DIR}/addons:${NEWGEOM_ROOT_DIR}/pythonAPI:${PYTHONPATH}
 +export PYTHONPATH=${NEWGEOM_ROOT_DIR}/swig:${NEWGEOM_ROOT_DIR}/plugins:${NEWGEOM_ROOT_DIR}/addons:${NEWGEOM_ROOT_DIR}/PythonAPI:${PYTHONPATH}
  export LD_LIBRARY_PATH=${NEWGEOM_ROOT_DIR}/bin:${NEWGEOM_ROOT_DIR}/swig:${NEWGEOM_ROOT_DIR}/plugins:${LD_LIBRARY_PATH}
  export NEW_GEOM_CONFIG_FILE=${NEWGEOM_ROOT_DIR}/plugins
  export NewGeomResources=${NEWGEOM_ROOT_DIR}/resources
index 6751da78cc0c64a68908772a5d1bd80dbd89ad04,232ff61b558ead55e47049e9d23208513d06c975..d8fbc9878a5b3bb5c5164558499c75ee41a50296
@@@ -61,7 -61,7 +61,7 @@@ using namespace std
  #ifdef DEB_NAMING
  #include <BRepTools.hxx>
  #endif
 -/// adeed to the index in the packed map to signalize that the vertex of edge is seleted
 +/// added to the index in the packed map to signalize that the vertex of edge is selected
  /// (multiplied by the index of the edge)
  static const int kSTART_VERTEX_DELTA = 1000000;
  // identifier that there is simple reference: selection equals to context
@@@ -200,7 -200,6 +200,6 @@@ std::shared_ptr<GeomAPI_Shape> Model_At
          return aResult; // empty result
      }
      if (aSelLab.IsAttribute(kPART_REF_ID)) {
-       /* TODO: implement used text here
        ResultPartPtr aPart = std::dynamic_pointer_cast<ModelAPI_ResultPart>(context());
        if (!aPart.get() || !aPart->isActivated())
          return std::shared_ptr<GeomAPI_Shape>(); // postponed naming needed
        if (selectionLabel().FindAttribute(TDataStd_Integer::GetID(), anIndex)) {
          return aPart->selectionValue(anIndex->Get());
        }
+       /*
        Handle(TDataStd_Name) aName;
        if (!selectionLabel().FindAttribute(TDataStd_Name::GetID(), aName)) {
          return std::shared_ptr<GeomAPI_Shape>(); // something is wrong
        }
-       return aPart->shapeInPart(TCollection_AsciiString(aName).ToCString());
+       return aPart->shapeInPart(TCollection_AsciiString(aName->Get()).ToCString());
        */
      }
  
@@@ -239,7 -239,7 +239,7 @@@ bool Model_AttributeSelection::isInvali
  
  bool Model_AttributeSelection::isInitialized()
  {
 -  if (ModelAPI_AttributeSelection::isInitialized()) { // additional checkings if it is initialized
 +  if (ModelAPI_AttributeSelection::isInitialized()) { // additional checks if it is initialized
      std::shared_ptr<GeomAPI_Shape> aResult;
      if (myRef.isInitialized()) {
        TDF_Label aSelLab = selectionLabel();
@@@ -312,7 -312,7 +312,7 @@@ void Model_AttributeSelection::setObjec
  TDF_LabelMap& Model_AttributeSelection::scope()
  {
    if (myScope.IsEmpty()) { // create a new scope if not yet done
 -    // gets all featueres with named shapes that are bofore this feature label (before in history)
 +    // gets all features with named shapes that are before this feature label (before in history)
      DocumentPtr aMyDoc = owner()->document();
      std::list<std::shared_ptr<ModelAPI_Feature> > allFeatures = aMyDoc->allFeatures();
      std::list<std::shared_ptr<ModelAPI_Feature> >::iterator aFIter = allFeatures.begin();
@@@ -458,7 -458,7 +458,7 @@@ bool Model_AttributeSelection::update(
          if (aNoIndexes) {
            aNewSelected = aConstructionContext->face(0);
          } else { // searching for most looks-like initial face by the indexes
 -          // prepare edges of the current resut for the fast searching
 +          // prepare edges of the current result for the fast searching
            NCollection_DataMap<Handle(Geom_Curve), int> allCurves; // curves and orientations of edges
            const int aSubNum = aComposite->numberOfSubs();
            for(int a = 0; a < aSubNum; a++) {
                }
              }
            }
-           double aBestFound = 0; // best percentage of found edges
+           int aBestFound = 0; // best number of found edges (not percentage: issue 1019)
            int aBestOrient = 0; // for the equal "BestFound" additional parameter is orientation
            for(int aFaceIndex = 0; aFaceIndex < aConstructionContext->facesNum(); aFaceIndex++) {
              int aFound = 0, aNotFound = 0, aSameOrientation = 0;
                }
              }
              if (aFound + aNotFound != 0) {
-               double aSum = aFound + aNotFound;
-                // aSameOrientation: if edges are same, take where orientation is better
-               double aPercentage = double(aFound) / double(aFound + aNotFound);
-               if (aPercentage > aBestFound || 
-                   (aPercentage == aBestFound && aSameOrientation > aBestOrient)) {
-                 aBestFound = aPercentage;
+               if (aFound > aBestFound || 
+                   (aFound == aBestFound && aSameOrientation > aBestOrient)) {
+                 aBestFound = aFound;
                  aBestOrient = aSameOrientation;
                  aNewSelected = aConstructionContext->face(aFaceIndex);
                }
@@@ -673,7 -670,7 +670,7 @@@ static void registerSubShape(TDF_Label 
        aName<<"f";
      else if (theOrientation == -1)
        aName<<"r";
 -  } else { // make a compisite name from all sub-elements indexes: "1_2_3_4"
 +  } else { // make a composite name from all sub-elements indexes: "1_2_3_4"
      TColStd_MapIteratorOfPackedMapOfInteger aRef(theRefs->GetMap());
      for(; aRef.More(); aRef.Next()) {
        aName<<"-"<<aRef.Key();
@@@ -709,7 -706,7 +706,7 @@@ void Model_AttributeSelection::selectCo
    }
    std::shared_ptr<Model_Data> aData = std::dynamic_pointer_cast<Model_Data>(owner()->data());
    TDF_Label aLab = myRef.myRef->Label();
 -  // identify the reuslts of sub-object of the composite by edges
 +  // identify the results of sub-object of the composite by edges
    // save type of the selected shape in integer attribute
    TopAbs_ShapeEnum aShapeType = aSubShape.ShapeType();
    TDataStd_Integer::Set(aLab, (int)aShapeType);
@@@ -829,7 -826,7 +826,7 @@@ bool Model_AttributeSelection::selectPa
      }
      return true; // nothing to do, referencing just by name
    }
 -  // store the shape (in case part is not loaded it should be usefull
 +  // store the shape (in case part is not loaded it should be useful
    TopoDS_Shape aShape;
    std::string aName = theContext->data()->name();
    if (!theSubShape.get() || theSubShape->isNull()) {// the whole part shape is selected
@@@ -876,6 -873,24 +873,24 @@@ void Model_AttributeSelection::selectSu
  {
    if(theSubShapeName.empty() || theType.empty()) return;
  
+   // check this is Part-name: 2 delimiters in the name
+   std::size_t aPartEnd = theSubShapeName.find('/');
+   if (aPartEnd != string::npos && aPartEnd != theSubShapeName.rfind('/')) {
+     std::string aPartName = theSubShapeName.substr(0, aPartEnd);
+     ObjectPtr aFound = owner()->document()->objectByName(ModelAPI_ResultPart::group(), aPartName);
+     if (aFound.get()) { // found such part, so asking it for the name
+       ResultPartPtr aPart = std::dynamic_pointer_cast<ModelAPI_ResultPart>(aFound);
+       string aNameInPart = theSubShapeName.substr(aPartEnd + 1);
+       int anIndex;
+       std::shared_ptr<GeomAPI_Shape> aSelected = aPart->shapeInPart(aNameInPart, theType, anIndex);
+       if (aSelected.get()) {
+         setValue(aPart, aSelected);
+         TDataStd_Integer::Set(selectionLabel(), anIndex);
+         return;
+       }
+     }
+   }
    Model_SelectionNaming aSelNaming(selectionLabel());
    std::shared_ptr<Model_Document> aDoc = 
      std::dynamic_pointer_cast<Model_Document>(owner()->document());
index c94062ba3e29ac664e929ac51a97355a25d40b52,e2cad1e1f7404176c8209cf3ecc6b91f0aaa1740..52eec8ca15ab35acd71cbb4cffacd4a53d133b53
@@@ -23,14 -23,14 +23,14 @@@ class ModelAPI_AttributeSelectionList 
    /// \param theContext object where the sub-shape was selected
    /// \param theSubShape selected sub-shape (if null, the whole context is selected)
    /// \param theTemporarily if it is true, do not store and name the added in the data framework
 -  ///           (used to remove immideately, without the following updates)
 +  ///           (used to remove immediately, without the following updates)
    virtual void append(const ResultPtr& theContext,
                        const GeomShapePtr& theSubShape,
                        const bool theTemporarily = false) = 0;
  
    /// Adds the new reference to the end of the list by the naming name of the selected shape
-   /// The type of shape is taken from the current selection type
-   virtual void append(std::string theNamingName) = 0;
+   /// The type of shape is taken from the current selection type if the given is empty
+   virtual void append(const std::string theNamingName, const std::string& theType = "") = 0;
  
    /// Removes the last element in the list
    virtual void removeLast() = 0;
index a56fd64bf35e26934296f056872095335dca0522,4edc005c95ef320cd3cbb13d242d89116ac723a9..abf679546fa7ffdf410cfced299d96af3fdbbb58
@@@ -103,9 -103,8 +103,8 @@@ public
    //! will be appended after this one.
    //! \param theCurrent the selected feature as current: blow it everythin become disabled
    //! \param theVisible use visible features only: flag is true for Object Browser functionality
-   //! \param theFlushUpdates if it is true (default) it flashes creation/redisplay/delete messages
    virtual void setCurrentFeature(std::shared_ptr<ModelAPI_Feature> theCurrent,
-     const bool theVisible, const bool theFlushUpdates = true) = 0;
+     const bool theVisible) = 0;
    //! Makes the current feature one feature upper
    virtual void setCurrentFeatureUp() = 0;
  
    //! To virtually destroy the fields of successors
    MODELAPI_EXPORT virtual ~ModelAPI_Document();
  
 -  //! Creates a construction cresult
 +  //! Creates a construction result
    virtual std::shared_ptr<ModelAPI_ResultConstruction> createConstruction(
        const std::shared_ptr<ModelAPI_Data>& theFeatureData, const int theIndex = 0) = 0;
    //! Creates a body result
index 6cc9c8b50a5561ad1f0dbea3adb6648bb2fb22a0,af55636cb58e7b573d2f5cf1235e16d5bff53f22..8a648e7c53c21616a7260ed5ad29ec0d11f2628c
@@@ -28,6 -28,9 +28,9 @@@ class ModelAPI_Feature : public ModelAP
    std::list<std::shared_ptr<ModelAPI_Result> > myResults;
    ///< is feature disabled or not
    bool myIsDisabled;
+   ///< is feature is stable (not editing)
+   bool myIsStable;
   public:
    /// Returns the unique kind of a feature (like "Point")
    virtual const std::string& getKind() = 0;
@@@ -82,7 -85,7 +85,7 @@@
                                   const int theIndex);
    /// removes the result from the feature
    MODELAPI_EXPORT void removeResult(const std::shared_ptr<ModelAPI_Result>& theResult);
 -  /// removes all results starting from the gived index (zero-based)
 +  /// removes all results starting from the given index (zero-based)
    /// \param theSinceIndex - index of the deleted result and all after also will be deleted
    /// \param theFlush - if it is false, REDISPLAY message is not flushed
    MODELAPI_EXPORT void removeResults(const int theSinceIndex, const bool theFlush = true);
    /// Returns the feature by the object (result).
    MODELAPI_EXPORT static std::shared_ptr<ModelAPI_Feature> feature(ObjectPtr theObject);
  
+   /// Set the stable feature flag. If feature is currently editing then it is not stable.
+   /// \returns true if state is really changed
+   MODELAPI_EXPORT virtual bool setStable(const bool theFlag);
+   /// Returns the feature is stable or not.
+   MODELAPI_EXPORT virtual bool isStable();
   //
   // Helper methods, aliases for data()->method()
   // -----------------------------------------------------------------------------------------------
index 3ff9f26ddfa2648a0c765a5bf2c051759d88b5d4,0c92f1be1b77f1f6bb466e7a0625e92adf1b791e..3fef980a8e2638086adb4f5c53d4310b8a042bd6
@@@ -6,20 -6,17 +6,20 @@@ from macros.box.feature      import Box
  
  
  class PythonFeaturesPlugin(ModelAPI.ModelAPI_Plugin):
-     """Class for Python features plugin.
 -"""Implementation of features plugin"""
++    """Implementation of features plugin.
 +
 +    PythonFeaturesPlugin() -> plugin object
 +    """
  
      def __init__(self):
 -        """Constructor"""
 +        """x.__init__(...) initializes x; see x.__class__.__doc__ for signature"""
          ModelAPI.ModelAPI_Plugin.__init__(self)
          aSession = ModelAPI.ModelAPI_Session.get()
          aSession.registerPlugin(self)
          pass
  
      def createFeature(self, theFeatureID):
 -        """Create a feature by its Id"""
 +        """Override ModelAPI_Plugin.createFeature()"""
          aFeature = None
  
          if theFeatureID == BoxFeature.ID():
@@@ -30,6 -27,6 +30,6 @@@
  
          return aFeature
  
 -### The plugin object
++# The plugin object
  plugin = PythonFeaturesPlugin()
  plugin.__disown__()
index 8c6687c77701b6efb0e2027bb41395cc4965b915,1f581be4aafb04b7d0ae67871f1469c18c08749c..ca037ba1f14d813a64c592e984bfce370ec610e4
@@@ -3,104 -3,100 +3,107 @@@ Authors: Renaud Nedelec - Daniel Brunie
  Copyright (C) 2014-20xx CEA/DEN, EDF R&D
  """
  
 -import modeler
 +import model
  import geom
  
  
 -class BoxFeature(modeler.Feature):
 -  """An example of Box feature implementation"""
 +class BoxFeature(model.Feature):
-     """Box feature.
++    """An example of Box feature implementation.
 +
 +    BoxFeature() -> Box
 +    """
  
  # Initializations
  
 -  def __init__(self):
 -    """Constructor"""
 -    modeler.Feature.__init__(self)
 +    def __init__(self):
 +        """x.__init__(...) initializes x; see x.__class__.__doc__ for signature"""
 +        model.Feature.__init__(self)
 +
 +    @staticmethod
 +    def ID():
-         """String constant."""
++        """Return Id of the feature."""
 +        return "Box"
  
 -  @staticmethod
 -  def ID():
 -    """Return Id of the feature"""
 -    return "Box"
 +    @staticmethod
 +    def WIDTH_ID():
-         """String constant."""
++        """Returns ID of Width parameter."""
 +        return "width"
  
 -  @staticmethod
 -  def WIDTH_ID():
 -    """Returns ID of Width parameter"""
 -    return "width"
 +    @staticmethod
 +    def LENGTH_ID():
-         """String constant."""
++        """Returns ID of Length parameter."""
 +        return "length"
  
 -  @staticmethod
 -  def LENGTH_ID():
 -    """Returns ID of Length parameter"""
 -    return "length"
 +    @staticmethod
 +    def HEIGHT_ID():
-         """String constant."""
++        """Returns ID of Height parameter."""
 +        return "height"
  
 -  @staticmethod
 -  def HEIGHT_ID():
 -    """Returns ID of Height parameter"""
 -    return "height"
 +    def getKind(self):
 +        """Override Feature.getKind()"""
 +        return BoxFeature.ID()
  
 -  def getKind(self):
 -    """Returns ID of еру ауфегку"""
 -    return BoxFeature.ID()
  
 -      
  # Creation of the box at default size
  
 -  def initAttributes(self):
 -    """Initialise attributes of the feature"""
 -    # Creating the input arguments of the feature
 -    self.addRealInput( self.WIDTH_ID() )
 -    self.addRealInput( self.LENGTH_ID() )
 -    self.addRealInput( self.HEIGHT_ID() )
 +    def initAttributes(self):
 +        """Override Feature.initAttributes()"""
 +        # Creating the input arguments of the feature
 +        self.addRealInput(self.WIDTH_ID())
 +        self.addRealInput(self.LENGTH_ID())
 +        self.addRealInput(self.HEIGHT_ID())
  
 -    # Creating the base of the box with unit values
 -    mypart = modeler.activeDocument()
 -    xoy    = modeler.defaultPlane("XOY")
 +        # Creating the base of the box with unit values
 +        mypart = model.activeDocument()
 +        xoy = model.defaultPlane("XOY")
  
 -    ### A base of the geometry
 -    self.base = modeler.addSketch( mypart, xoy )
++        # A base of the geometry
 +        self.base = model.addSketch(mypart, xoy)
  
 -    p1 = geom.Pnt2d( 0, 0 )
 -    p2 = geom.Pnt2d( 0, 1 )
 -    p3 = geom.Pnt2d( 1, 1 )
 -    p4 = geom.Pnt2d( 1, 0 )
 +        p1 = geom.Pnt2d(0, 0)
 +        p2 = geom.Pnt2d(0, 1)
 +        p3 = geom.Pnt2d(1, 1)
 +        p4 = geom.Pnt2d(1, 0)
  
 -    line = self.base.addPolygon(p1, p2, p3, p4)
 +        line = self.base.addPolygon(p1, p2, p3, p4)
  
 -    self.base.setParallel( line[0].result(), line[2].result() )
 -    self.base.setParallel( line[1].result(), line[3].result() )
 -    self.base.setPerpendicular( line[0].result(), line[3].result() )
 +        self.base.setParallel(line[0].result(), line[2].result())
 +        self.base.setParallel(line[1].result(), line[3].result())
 +        self.base.setPerpendicular(line[0].result(), line[3].result())
  
 -    # Setting the size of the base with default values
 -    ### Width
 -    self.width  = self.base.setLength( line[0].result(), 50 )   # Keeps the constraint for edition
 -    ### Length
 -    self.length = self.base.setLength( line[3].result(), 50 )   # Keeps the constraint for edition
 +        # Setting the size of the base with default values
++        # Width
 +        self.width = self.base.setLength(line[0].result(), 50)  # Keeps the constraint for edition
++        # Length
 +        self.length = self.base.setLength(line[3].result(), 50)  # Keeps the constraint for edition
  
 -    # Creating the extrusion (the box) at default size
 -    ### A box result
 -    self.box = modeler.addExtrusion( mypart, self.base.selectFace(), 50 )
 +        # Creating the extrusion (the box) at default size
++        # A box result
 +        self.box = model.addExtrusion(mypart, self.base.selectFace(), 50)
  
 -      
  # Edition of the box at user size
  
 -  def execute(self):
 -    """Compute the feature result"""
 -    # Retrieving the user inputs
 -    width  = self.getRealInput( self.WIDTH_ID() )
 -    length = self.getRealInput( self.LENGTH_ID() )
 -    height = self.getRealInput( self.HEIGHT_ID() )
 -
 -    # Editing the box
 -    self.base.setValue( self.width,  width )
 -    self.base.setValue( self.length, length )
 -    self.box.setSize( height )
 -
 -    # Publishing the result: not needed for Macro feature
 -    #self.addResult( self.box.result() )
 -  
 -  def isMacro(self):
 -    """Returns True"""
 -    # Box feature is macro: removes itself on the creation transaction finish
 -    return True
 +    def execute(self):
 +        """F.execute() -- execute the feature"""
 +        # Retrieving the user inputs
 +        width = self.getRealInput(self.WIDTH_ID())
 +        length = self.getRealInpuut(self.WIDTH_ID())
 +        length = self.getRealInt(self.LENGTH_ID())
 +        height = self.getRealInput(self.HEIGHT_ID())
 +
 +        # Editing the box
 +        self.base.setValue(self.width, width)
 +        self.base.setValue(self.length, length)
 +        self.box.setSize(height)
 +
 +        # Publishing the result: not needed for Macro feature
 +        # self.addResult( self.box.result() )
 +
 +    def isMacro(self):
 +        """Override Feature.initAttributes().
 +        F.isMacro() -> True
 +
 +        Box feature is macro: removes itself on the creation transaction
 +        finish.
 +        """
 +        return True
index 1e3c29cd7b47b07ddfa70d722986caecb9f597f6,3891315ef09cb141d9000fe39864c018da3bee43..26e7c2989f7ef66debc89fdac31b28635c02f5f2
@@@ -18,7 -18,7 +18,7 @@@
        <!--icon=":pictures/x_point.png"-->
        </feature>
        <feature id="SketchPoint" title="Point" tooltip="Create point" icon=":icons/point.png">
 -        <sketch-2dpoint_selector id="PointCoordindates" title="Point" tooltip="Point coordinates"/>
 +        <sketch-2dpoint_selector id="PointCoordinates" title="Point" tooltip="Point coordinates"/>
          <boolvalue id="Auxiliary" label="Auxiliary" default="false" tooltip="Construction element" obligatory="0"/>
        </feature>
        <feature id="SketchLine" title="Line" tooltip="Create line" icon=":icons/line.png">
          <boolvalue id="Auxiliary" label="Auxiliary" default="false" tooltip="Construction element" obligatory="0"/>
          <validator id="GeomValidators_Different" parameters="ArcCenter,ArcStartPoint,ArcEndPoint"/>
        </feature>
+       <!--  SketchConstraintFillet  -->
+       <feature id="SketchConstraintFillet" title="Fillet" tooltip="Create constraint defining fillet between two objects" icon=":icons/fillet.png">
+         <sketch_shape_selector id="ConstraintEntityA"
+             label="Point" tooltip="Select point for fillet (should be shared by two entities only)" shape_types="vertex">
+           <validator id="SketchPlugin_FilletVertexValidator"/>
+         </sketch_shape_selector>
+         <doublevalue label="Radius" tooltip="Fillet arc radius" id="ConstraintValue" min="0" default="1" use_reset="false">
+           <validator id="GeomValidators_Positive"/>
+         </doublevalue>
+       </feature>
      </group>
        
      <group id="Constraints">
@@@ -70,7 -80,7 +80,7 @@@
            <validator id="SketchPlugin_ExternalValidator" parameters="ConstraintEntityA"/>
            <validator id="GeomValidators_ShapeType" parameters="vertex,line"/>
          </sketch_shape_selector>
-         <sketch-2dpoint_selector id="ConstraintFlyoutValuePnt"  default="computed" internal="1" obligatory="0"/>
+         <sketch-2dpoint_flyout_selector id="ConstraintFlyoutValuePnt"  default="computed" internal="1" obligatory="0"/>
          
          <doublevalue_editor label="Value" tooltip="Distance" id="ConstraintValue" default="computed" min="0">
            <validator id="GeomValidators_Positive"/>
@@@ -85,7 -95,7 +95,7 @@@
          <shape_selector id="ConstraintEntityA" label="Line" tooltip="Select an line" shape_types="edge" >
            <validator id="GeomValidators_ShapeType" parameters="line"/>
          </shape_selector>
-         <sketch-2dpoint_selector id="ConstraintFlyoutValuePnt" default="computed" internal="1" obligatory="0"/>
+         <sketch-2dpoint_flyout_selector id="ConstraintFlyoutValuePnt" default="computed" internal="1" obligatory="0"/>
          <doublevalue_editor label="Value" tooltip="Length" id="ConstraintValue" default="computed">
            <validator id="GeomValidators_Positive"/>
          </doublevalue_editor>
              shape_types="edge">
              <validator id="GeomValidators_ShapeType" parameters="circle"/>
          </shape_selector>
-         <sketch-2dpoint_selector id="ConstraintFlyoutValuePnt"  default="computed" internal="1" obligatory="0"/>
+         <sketch-2dpoint_flyout_selector id="ConstraintFlyoutValuePnt"  default="computed" internal="1" obligatory="0"/>
          <doublevalue_editor label="Value" tooltip="Radius" id="ConstraintValue" default="computed">
            <validator id="GeomValidators_Positive"/>
          </doublevalue_editor>
            <validator id="PartSet_DifferentObjects"/>
            <validator id="SketchPlugin_ExternalValidator" parameters="ConstraintEntityA"/>
          </shape_selector>
-         <sketch-2dpoint_selector id="ConstraintFlyoutValuePnt"  default="computed" internal="1" obligatory="0"/>
+         <sketch-2dpoint_flyout_selector id="ConstraintFlyoutValuePnt"  default="computed" internal="1" obligatory="0"/>
          <doublevalue_editor label="Value" tooltip="Angle" id="ConstraintValue" default="computed" min="0" max="180" />
          <validator id="PartSet_AngleSelection"/>
        </feature>
            <validator id="PartSet_DifferentObjects"/>
            <validator id="SketchPlugin_ExternalValidator" parameters="ConstraintEntityA"/>
          </sketch_shape_selector>
+         <validator id="PartSet_EqualSelection"/>
        </feature>
        
      <!--  SketchConstraintTangent  -->
      </group>
      
      <group id="Edit">
-       <!--  SketchConstraintFillet  -->
-       <feature id="SketchConstraintFillet" title="Fillet" tooltip="Create constraint defining fillet between two objects" icon=":icons/fillet.png">
-         <sketch_shape_selector id="ConstraintEntityA" 
-             label="First object" tooltip="Select line or arc" shape_types="edge">
-           <validator id="PartSet_DifferentObjects"/>
-           <validator id="PartSet_CoincidentAttr" parameters="ConstraintEntityB"/>
-         </sketch_shape_selector>
-         <sketch_shape_selector id="ConstraintEntityB"
-             label="Second object" tooltip="Select line or arc" shape_types="edge">
-           <validator id="PartSet_DifferentObjects"/>
-           <validator id="PartSet_CoincidentAttr" parameters="ConstraintEntityA"/>
-         </sketch_shape_selector>
-         <doublevalue label="Value" tooltip="Fillet radius" id="ConstraintValue" min="0" default="1" use_reset="false">
-           <validator id="GeomValidators_Positive"/>
-         </doublevalue>
-         <validator id="PartSet_FilletSelection"/>
-       </feature>
-       
        <!--  SketchConstraintMirror  -->
        <feature
          id="SketchConstraintMirror"