]> SALOME platform Git repositories - modules/shaper.git/commitdiff
Salome HOME
Merge branch 'master' into Dev_1.1.0
authorsbh <sergey.belash@opencascade.com>
Thu, 26 Mar 2015 09:55:05 +0000 (12:55 +0300)
committersbh <sergey.belash@opencascade.com>
Thu, 26 Mar 2015 09:55:05 +0000 (12:55 +0300)
Conflicts:
CMakeLists.txt
src/Config/Config_FeatureReader.cpp
src/Config/Config_FeatureReader.h
src/ConstructionPlugin/ConstructionPlugin_Axis.cpp
src/ConstructionPlugin/ConstructionPlugin_Plane.cpp
src/ConstructionPlugin/ConstructionPlugin_Point.cpp
src/FeaturesPlugin/FeaturesPlugin_Extrusion.cpp
src/FeaturesPlugin/FeaturesPlugin_Placement.cpp
src/FeaturesPlugin/Test/TestMultiBoolean.py
src/Model/Model_AttributeSelection.cpp
src/Model/Model_Update.cpp
src/ModelAPI/ModelAPI_RefAttrValidator.h
src/ModelAPI/ModelAPI_ShapeValidator.cpp
src/ModuleBase/ModuleBase_WidgetShapeSelector.cpp
src/PartSet/CMakeLists.txt
src/PartSet/PartSet_Validators.cpp
src/PartSet/PartSet_Validators.h
src/PartSet/PartSet_WidgetShapeSelector.cpp
src/SketchPlugin/CMakeLists.txt
src/SketchPlugin/SketchPlugin_Arc.cpp
src/SketchPlugin/SketchPlugin_Circle.cpp
src/SketchPlugin/SketchPlugin_ConstraintParallel.cpp
src/SketchPlugin/SketchPlugin_Line.cpp
src/SketchPlugin/SketchPlugin_Plugin.cpp
src/SketchPlugin/SketchPlugin_Point.cpp
src/SketchPlugin/SketchPlugin_Sketch.cpp
src/SketchPlugin/SketchPlugin_Validators.cpp
src/SketchPlugin/SketchPlugin_Validators.h
src/SketchPlugin/plugin-Sketch.xml

72 files changed:
1  2 
CMakeLists.txt
doc/CMakeLists.txt
src/Config/Config_FeatureReader.cpp
src/Config/Config_FeatureReader.h
src/Config/Config_ModuleReader.cpp
src/Config/Config_XMLReader.cpp
src/Config/Config_XMLReader.h
src/Config/plugins.xml
src/ConstructionPlugin/ConstructionPlugin_Axis.cpp
src/ConstructionPlugin/ConstructionPlugin_Plane.cpp
src/ConstructionPlugin/ConstructionPlugin_Point.cpp
src/ExchangePlugin/ExchangePlugin_ImportFeature.cpp
src/FeaturesPlugin/FeaturesPlugin_Extrusion.cpp
src/FeaturesPlugin/FeaturesPlugin_Placement.cpp
src/FeaturesPlugin/Test/TestBoolean.py
src/FeaturesPlugin/Test/TestExtrusion.py
src/FeaturesPlugin/Test/TestGroup.py
src/FeaturesPlugin/Test/TestMultiBoolean.py
src/GeomDataAPI/GeomDataAPI_Dir.h
src/GeomValidators/GeomValidators_EdgeOrVertex.cpp
src/GeomValidators/GeomValidators_Tools.cpp
src/Model/Model_AttributeSelection.cpp
src/Model/Model_Data.cpp
src/Model/Model_ResultBody.cpp
src/Model/Model_ResultConstruction.cpp
src/Model/Model_ResultGroup.cpp
src/Model/Model_Session.cpp
src/Model/Model_Update.cpp
src/ModelAPI/ModelAPI_AttributeIntArray.cpp
src/ModelAPI/ModelAPI_AttributeIntArray.h
src/ModelAPI/ModelAPI_AttributeSelectionList.h
src/ModelAPI/ModelAPI_Feature.cpp
src/ModelAPI/ModelAPI_ShapeValidator.cpp
src/ModuleBase/ModuleBase_Operation.cpp
src/ModuleBase/ModuleBase_WidgetShapeSelector.cpp
src/ParametersPlugin/ParametersPlugin_Parameter.cpp
src/PartSet/CMakeLists.txt
src/PartSet/PartSet_Tools.cpp
src/PartSet/PartSet_Validators.cpp
src/PartSet/PartSet_Validators.h
src/PartSet/PartSet_WidgetShapeSelector.cpp
src/SketchPlugin/CMakeLists.txt
src/SketchPlugin/SketchPlugin_Arc.cpp
src/SketchPlugin/SketchPlugin_Circle.cpp
src/SketchPlugin/SketchPlugin_ConstraintCoincidence.cpp
src/SketchPlugin/SketchPlugin_ConstraintDistance.cpp
src/SketchPlugin/SketchPlugin_ConstraintEqual.cpp
src/SketchPlugin/SketchPlugin_ConstraintFillet.cpp
src/SketchPlugin/SketchPlugin_ConstraintHorizontal.cpp
src/SketchPlugin/SketchPlugin_ConstraintLength.cpp
src/SketchPlugin/SketchPlugin_ConstraintMirror.cpp
src/SketchPlugin/SketchPlugin_ConstraintParallel.cpp
src/SketchPlugin/SketchPlugin_ConstraintPerpendicular.cpp
src/SketchPlugin/SketchPlugin_ConstraintRadius.cpp
src/SketchPlugin/SketchPlugin_ConstraintRigid.cpp
src/SketchPlugin/SketchPlugin_ConstraintTangent.cpp
src/SketchPlugin/SketchPlugin_ConstraintVertical.cpp
src/SketchPlugin/SketchPlugin_Line.cpp
src/SketchPlugin/SketchPlugin_Plugin.cpp
src/SketchPlugin/SketchPlugin_Point.cpp
src/SketchPlugin/SketchPlugin_Sketch.cpp
src/SketchPlugin/SketchPlugin_SketchEntity.cpp
src/SketchPlugin/SketchPlugin_Validators.cpp
src/SketchPlugin/SketchPlugin_Validators.h
src/SketchPlugin/Test/TestConstraintEqual.py
src/SketchPlugin/Test/TestConstraintHorizontal.py
src/SketchPlugin/Test/TestConstraintMirror.py
src/SketchPlugin/Test/TestConstraintTangent.py
src/SketchPlugin/Test/TestConstraintVertical.py
src/SketchPlugin/plugin-Sketch.xml
src/SketchSolver/SketchSolver_Constraint.cpp
src/SketchSolver/SketchSolver_ConstraintGroup.cpp

diff --cc CMakeLists.txt
index bb42d8b4a6480861724889642a7b0d689e5dc0af,ce89f8361c5956861c7c2635e92acb2eb88c7edd..0cf7163c24bdc1fd8fef768eb1a502ecb4bc26cd
@@@ -54,7 -54,7 +54,8 @@@ ADD_SUBDIRECTORY (src/GeomDataAPI
  ADD_SUBDIRECTORY (src/PartSetPlugin)
  ADD_SUBDIRECTORY (src/ConstructionPlugin)
  ADD_SUBDIRECTORY (src/FeaturesPlugin)
 +ADD_SUBDIRECTORY (src/SketcherPrs)
+ ADD_SUBDIRECTORY (src/PythonFeaturesPlugin)
  ADD_SUBDIRECTORY (src/SketchPlugin)
  ADD_SUBDIRECTORY (src/SketchSolver)
  ADD_SUBDIRECTORY (src/ModuleBase)
Simple merge
index dea07dfc7420203fffaa8da699e8ddd36fc3220d,48f091aa32c9b76caa5e14e75da40e46a9588331..2b024061a5335aa2ee405d36c6ddaca7726516e1
@@@ -61,35 -61,18 +61,35 @@@ void Config_FeatureReader::processNode(
    } else if (isNode(theNode, NODE_WORKBENCH, NODE_GROUP, NULL)) {
      storeAttribute(theNode, _ID);
      storeAttribute(theNode, WORKBENCH_DOC);
 -  } else if (myIsProcessWidgets && isWidgetNode(theNode)) {
 -    std::shared_ptr<Config_AttributeMessage> aMessage(new Config_AttributeMessage(aMenuItemEvent, this));
 -    aMessage->setFeatureId(restoreAttribute(NODE_FEATURE, _ID));
 -    std::string anAttributeID = getProperty(theNode, _ID);
 -    if (!anAttributeID.empty()) {
 -      aMessage->setAttributeId(anAttributeID);
 -      aMessage->setObligatory(getBooleanAttribute(theNode, ATTR_OBLIGATORY, true));
 -      aMessage->setConcealment(getBooleanAttribute(theNode, ATTR_CONCEALMENT, false));
 -      Events_Loop::loop()->send(aMessage);
 +  } else if (myIsProcessWidgets) {
 +    // widgets, like shape_selector or containers, like toolbox
 +    if (isAttributeNode(theNode)) {
 +      std::shared_ptr<Config_AttributeMessage> aMessage(new Config_AttributeMessage(aMenuItemEvent, this));
 +      aMessage->setFeatureId(restoreAttribute(NODE_FEATURE, _ID));
 +      std::string anAttributeID = getProperty(theNode, _ID);
 +      if (!anAttributeID.empty()) {
 +        aMessage->setAttributeId(anAttributeID);
 +        aMessage->setObligatory(getBooleanAttribute(theNode, ATTR_OBLIGATORY, true));
 +        aMessage->setConcealment(getBooleanAttribute(theNode, ATTR_CONCEALMENT, false));
 +        // nested "paged" widgets are not allowed, this issue may be resolved here:
 +        if (hasParent(theNode, WDG_SWITCH_CASE, WDG_TOOLBOX_BOX, NULL)) {
 +          const char* kWdgCase = hasParent(theNode, WDG_SWITCH_CASE, NULL)
 +                                 ? WDG_SWITCH_CASE
 +                                 : WDG_TOOLBOX_BOX;
 +          const char* kWdgSwitch = hasParent(theNode, WDG_SWITCH_CASE, NULL)
 +                                   ? WDG_SWITCH
 +                                   : WDG_TOOLBOX;
 +          aMessage->setCaseId(restoreAttribute(kWdgCase, _ID));
 +          aMessage->setSwitchId(restoreAttribute(kWdgSwitch, _ID));
 +        }
 +        Events_Loop::loop()->send(aMessage);
 +      }
 +    // container pages, like "case" or "box"
 +    } else if (isNode(theNode, WDG_SWITCH, WDG_SWITCH_CASE, WDG_TOOLBOX, WDG_TOOLBOX_BOX, NULL)) {
 +      storeAttribute(theNode, _ID); // save case:caseId (or box:boxId)
      }
    }
-   //Process SOURCE, VALIDATOR nodes.
+   //Process SOURCE nodes.
    Config_XMLReader::processNode(theNode);
  }
  
Simple merge
Simple merge
index 768232b7457e05006f7e9b44caf1ba726fb124bd,ab15f3621e1a43ea35caf6a4a9e9ad298a3f85c4..c0a0a2ee0a0e4beac70cd5f8fec2f7ea4d2e8004
@@@ -150,45 -138,26 +144,43 @@@ std::string Config_XMLReader::getNodeNa
    return result;
  }
  
- void Config_XMLReader::processValidator(xmlNodePtr theNode)
+ void Config_XMLReader::storeAttribute(xmlNodePtr theNode, const char* theAttribute)
  {
-   Events_ID aValidatoEvent = Events_Loop::eventByName(EVENT_VALIDATOR_LOADED);
-   Events_Loop* aEvLoop = Events_Loop::loop();
-   std::shared_ptr<Config_ValidatorMessage> 
-     aMessage(new Config_ValidatorMessage(aValidatoEvent, this));
-   std::string aValidatorId;
-   std::list<std::string> aParameters;
-   getParametersInfo(theNode, aValidatorId, aParameters);
-   aMessage->setValidatorId(aValidatorId);
-   aMessage->setValidatorParameters(aParameters);
-   xmlNodePtr aFeatureOrWdgNode = theNode->parent;
-   if (isNode(aFeatureOrWdgNode, NODE_FEATURE, NULL)) {
-     aMessage->setFeatureId(getProperty(aFeatureOrWdgNode, _ID));
-   } else {
-     aMessage->setAttributeId(getProperty(aFeatureOrWdgNode, _ID));
-     aMessage->setFeatureId(myCurrentFeature);
+   std::string aKey = getNodeName(theNode) + ":" + std::string(theAttribute);
+   std::string aValue = getProperty(theNode, theAttribute);
+   if(!aValue.empty()) {
+     myCachedAttributes[aKey] = aValue;
    }
-   aEvLoop->send(aMessage);
  }
  
void Config_XMLReader::processSelectionFilter(xmlNodePtr theNode)
std::string Config_XMLReader::restoreAttribute(xmlNodePtr theNode, const char* theAttribute)
  {
-   Events_ID aFilterEvent = Events_Loop::eventByName(EVENT_SELFILTER_LOADED);
-   Events_Loop* aEvLoop = Events_Loop::loop();
-   std::shared_ptr<Config_SelectionFilterMessage> aMessage =
-       std::make_shared<Config_SelectionFilterMessage>(aFilterEvent, this);
-   std::string aSelectionFilterId;
-   std::list<std::string> aParameters;
-   getParametersInfo(theNode, aSelectionFilterId, aParameters);
-   aMessage->setSelectionFilterId(aSelectionFilterId);
-   aMessage->setFilterParameters(aParameters);
-   xmlNodePtr aFeatureOrWdgNode = theNode->parent;
-   if (isNode(aFeatureOrWdgNode, NODE_FEATURE, NULL)) {
-     aMessage->setFeatureId(getProperty(aFeatureOrWdgNode, _ID));
-   } else {
-     aMessage->setAttributeId(getProperty(aFeatureOrWdgNode, _ID));
-     aMessage->setFeatureId(myCurrentFeature);
+   return restoreAttribute(getNodeName(theNode).c_str(), theAttribute);
+ }
+ std::string Config_XMLReader::restoreAttribute(const char* theNodeName, const char* theAttribute)
+ {
+   std::string aKey = std::string(theNodeName) + ":" + std::string(theAttribute);
+   std::string result = "";
+   if(myCachedAttributes.find(aKey) != myCachedAttributes.end()) {
+     result = myCachedAttributes[aKey];
    }
-   aEvLoop->send(aMessage);
+   return result;
+ }
++
++bool Config_XMLReader::cleanupAttribute(xmlNodePtr theNode, const char* theNodeAttribute)
++{
++  return cleanupAttribute(getNodeName(theNode).c_str(), theNodeAttribute);
++}
++
++bool Config_XMLReader::cleanupAttribute(const char* theNodeName, const char* theNodeAttribute)
++{
++  std::string aKey = std::string(theNodeName) + ":" + std::string(theNodeAttribute);
++  bool result = false;
++  std::map<std::string, std::string>::iterator anEntry = myCachedAttributes.find(aKey);
++  if( anEntry != myCachedAttributes.end()) {
++    myCachedAttributes.erase(anEntry);
++    result = true;
++  }
++  return result;
 +}
index 603ce7d1faea03605dcebf388af0af69105f8bc3,8b6f963d1b6bc5e24809285964d2a07e1859cdde..d19bd8467a482517d7602cb4b33e0bc595593ef7
@@@ -84,21 -79,20 +85,22 @@@ class Config_XMLReade
    xmlNodePtr node(void* theNode);
    /// Gets xml node name
    std::string getNodeName(xmlNodePtr theNode);
-   /*!
-    * \brief Retrieves all the necessary info from the validator node.
-    * Sends ValidatorLoaded event
-    */
-   void processValidator(xmlNodePtr theNode);
-   /*!
-    * \brief Retrieves all the necessary info from the SelectionFilter node.
-    * Sends SelectionFilterLoaded event
-    */
-   void processSelectionFilter(xmlNodePtr theNode);
+   /// Stores an attribute in internal map for later use.
+   /// Key is "Node_Name:Node_Attribute" and value is getProperty(theNodeAttribute)
+   void storeAttribute(xmlNodePtr theNode, const char* theNodeAttribute);
+   /// Restores an attribute from internal map.
+   std::string restoreAttribute(xmlNodePtr theNode, const char* theNodeAttribute);
+   /// Restores an attribute from internal map.
+   std::string restoreAttribute(const char* theNodeName, const char* theNodeAttribute);
++  bool cleanupAttribute(xmlNodePtr theNode, const char* theNodeAttribute);
++  bool cleanupAttribute(const char* theNodeName, const char* theNodeAttribute);
  
   protected:
-   std::string myCurrentFeature; ///< Name of currently processed feature
    std::string myDocumentPath; ///< Path to the xml document
    xmlDocPtr myXmlDoc; ///< Root of the xml document
+   /// A map to store all parent's attributes.
+   /// The key has from "Node_Name:Node_Attribute"
+   std::map<std::string, std::string> myCachedAttributes;
  };
  
  #endif /* CONFIG_XMLREADER_H_ */
index 623b8097394293d4479c6302bf8282185a5b657b,bf95bc97c3f353b7ec5df0f734ca915d4e0c56a9..65cdd3beee68d3a7d196b6a5bc1e4c2bed0ab1d1
@@@ -8,8 -6,8 +8,9 @@@
    <plugin library="ConstructionPlugin" configuration="plugin-Construction.xml"/>
    <plugin library="FeaturesPlugin" configuration="plugin-Features.xml"/>
    <plugin library="ExchangePlugin" configuration="plugin-Exchange.xml"/>
+   <plugin script="PythonFeaturesPlugin" configuration="plugin-PythonFeatures.xml"/>
    <plugin script="ConnectorPlugin" configuration="plugin-Connector.xml" dependency="Geometry"/>
 +  <plugin library="ParametersPlugin" configuration="plugin-Parameters.xml"/>
    <plugin library="SketchSolver"/>
    <plugin library="GeomValidators"/>
    <plugin library="DFBrowser" internal="true"/>
index 5017f496a97af4842da4c557aa6a65478f362dfa,78de925dcae942f6780ebc1806b97a7069286a5b..e3d7eb34c4f58e7f2edf07b540e17386bf62c61a
@@@ -28,20 -23,14 +28,20 @@@ ConstructionPlugin_Axis::ConstructionPl
  
  void ConstructionPlugin_Axis::initAttributes()
  {
 -  data()->addAttribute(POINT_ATTR_FIRST,  ModelAPI_AttributeSelection::typeId());
 -  data()->addAttribute(POINT_ATTR_SECOND, ModelAPI_AttributeSelection::typeId());
 +  data()->addAttribute(ConstructionPlugin_Axis::METHOD(),
-                        ModelAPI_AttributeString::type());
++                       ModelAPI_AttributeString::typeId());
 +  data()->addAttribute(ConstructionPlugin_Axis::POINT_FIRST(),
-                        ModelAPI_AttributeSelection::type());
++                       ModelAPI_AttributeSelection::typeId());
 +  data()->addAttribute(ConstructionPlugin_Axis::POINT_SECOND(),
-                        ModelAPI_AttributeSelection::type());
++                       ModelAPI_AttributeSelection::typeId());
 +  data()->addAttribute(ConstructionPlugin_Axis::CYLINDRICAL_FACE(),
-                        ModelAPI_AttributeSelection::type());
++                       ModelAPI_AttributeSelection::typeId());
  }
  
 -void ConstructionPlugin_Axis::execute()
 +void ConstructionPlugin_Axis::createAxisByTwoPoints()
  {
 -  AttributeSelectionPtr aRef1 = data()->selection(POINT_ATTR_FIRST);
 -  AttributeSelectionPtr aRef2 = data()->selection(POINT_ATTR_SECOND);
 +  AttributeSelectionPtr aRef1 = data()->selection(ConstructionPlugin_Axis::POINT_FIRST());
 +  AttributeSelectionPtr aRef2 = data()->selection(ConstructionPlugin_Axis::POINT_SECOND());
    if ((aRef1.get() != NULL) && (aRef2.get() != NULL)) {
      GeomShapePtr aShape1 = aRef1->value();
      GeomShapePtr aShape2 = aRef2->value();
index 7448f5a7e5aa62f5d8bc70b9b403f8593c0fcbdc,07d3d24bc65fa7725ccd7a870ea21d477dcd0314..c206ff4d55b1a24f7aee3ba87fcf686966f10815
@@@ -23,15 -22,8 +23,15 @@@ ConstructionPlugin_Plane::ConstructionP
  
  void ConstructionPlugin_Plane::initAttributes()
  {
-   data()->addAttribute(ConstructionPlugin_Plane::METHOD(), ModelAPI_AttributeString::type());
 -  data()->addAttribute(FACE_ATTR,  ModelAPI_AttributeSelection::typeId());
 -  data()->addAttribute(DISTANCE_ATTR, ModelAPI_AttributeDouble::typeId());
++  data()->addAttribute(ConstructionPlugin_Plane::METHOD(), ModelAPI_AttributeString::typeId());
 +  // Face & Distance
-   data()->addAttribute(ConstructionPlugin_Plane::FACE(),  ModelAPI_AttributeSelection::type());
-   data()->addAttribute(ConstructionPlugin_Plane::DISTANCE(), ModelAPI_AttributeDouble::type());
++  data()->addAttribute(ConstructionPlugin_Plane::FACE(),  ModelAPI_AttributeSelection::typeId());
++  data()->addAttribute(ConstructionPlugin_Plane::DISTANCE(), ModelAPI_AttributeDouble::typeId());
 +  // General equation
-   data()->addAttribute(ConstructionPlugin_Plane::A(),  ModelAPI_AttributeDouble::type());
-   data()->addAttribute(ConstructionPlugin_Plane::B(),  ModelAPI_AttributeDouble::type());
-   data()->addAttribute(ConstructionPlugin_Plane::C(),  ModelAPI_AttributeDouble::type());
-   data()->addAttribute(ConstructionPlugin_Plane::D(),  ModelAPI_AttributeDouble::type());
++  data()->addAttribute(ConstructionPlugin_Plane::A(),  ModelAPI_AttributeDouble::typeId());
++  data()->addAttribute(ConstructionPlugin_Plane::B(),  ModelAPI_AttributeDouble::typeId());
++  data()->addAttribute(ConstructionPlugin_Plane::C(),  ModelAPI_AttributeDouble::typeId());
++  data()->addAttribute(ConstructionPlugin_Plane::D(),  ModelAPI_AttributeDouble::typeId());
  }
  
  void ConstructionPlugin_Plane::execute()
index 671a38cd7a1daf72a4d802470e5f3e60d2f02bdd,7a9d66b2d6eedd161ea362b427cbc5793a21877b..b31b3b55217d0b0bd94b538207392dc58d90ba14
@@@ -21,17 -19,11 +21,17 @@@ ConstructionPlugin_Point::ConstructionP
  {
  }
  
 +const std::string& ConstructionPlugin_Point::getKind()
 +{
 +  static std::string MY_KIND = ConstructionPlugin_Point::ID();
 +  return MY_KIND;
 +}
 +
  void ConstructionPlugin_Point::initAttributes()
  {
-   data()->addAttribute(ConstructionPlugin_Point::X(), ModelAPI_AttributeDouble::type());
-   data()->addAttribute(ConstructionPlugin_Point::Y(), ModelAPI_AttributeDouble::type());
-   data()->addAttribute(ConstructionPlugin_Point::Z(), ModelAPI_AttributeDouble::type());
 -  data()->addAttribute(POINT_ATTR_X, ModelAPI_AttributeDouble::typeId());
 -  data()->addAttribute(POINT_ATTR_Y, ModelAPI_AttributeDouble::typeId());
 -  data()->addAttribute(POINT_ATTR_Z, ModelAPI_AttributeDouble::typeId());
++  data()->addAttribute(ConstructionPlugin_Point::X(), ModelAPI_AttributeDouble::typeId());
++  data()->addAttribute(ConstructionPlugin_Point::Y(), ModelAPI_AttributeDouble::typeId());
++  data()->addAttribute(ConstructionPlugin_Point::Z(), ModelAPI_AttributeDouble::typeId());
  }
  
  void ConstructionPlugin_Point::execute()
index 873753a8cf44bca3be2d580c85217b98e77e2478,042ee8e2157974b835e93ab8f3ea808cb4cc350e..3d8c5bbc842d2fb14bebc33d78070df9bb22f284
@@@ -28,13 -27,9 +28,13 @@@ FeaturesPlugin_Extrusion::FeaturesPlugi
  
  void FeaturesPlugin_Extrusion::initAttributes()
  {
 -  data()->addAttribute(FeaturesPlugin_Extrusion::FACE_ID(), ModelAPI_AttributeSelection::typeId());
 +  AttributeSelectionListPtr aSelection = 
 +    std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(data()->addAttribute(
-     FeaturesPlugin_Extrusion::LIST_ID(), ModelAPI_AttributeSelectionList::type()));
++    FeaturesPlugin_Extrusion::LIST_ID(), ModelAPI_AttributeSelectionList::typeId()));
 +  // extrusion works with faces always
 +  aSelection->setSelectionType("FACE");
-   data()->addAttribute(FeaturesPlugin_Extrusion::SIZE_ID(), ModelAPI_AttributeDouble::type());
-   data()->addAttribute(FeaturesPlugin_Extrusion::REVERSE_ID(), ModelAPI_AttributeBoolean::type());
+   data()->addAttribute(FeaturesPlugin_Extrusion::SIZE_ID(), ModelAPI_AttributeDouble::typeId());
+   data()->addAttribute(FeaturesPlugin_Extrusion::REVERSE_ID(), ModelAPI_AttributeBoolean::typeId());
  }
  
  void FeaturesPlugin_Extrusion::execute()
@@@ -150,12 -131,3 +150,12 @@@ void FeaturesPlugin_Extrusion::LoadNami
    }
    
  }
- }
 +
 +//============================================================================
 +void FeaturesPlugin_Extrusion::clearResult()
 +{
 +  std::shared_ptr<ModelAPI_ResultBody> aResultBody = document()->createBody(data());
 +  std::shared_ptr<GeomAPI_Shape> anEmptyShape(new GeomAPI_Shape);
 +  aResultBody->store(anEmptyShape);
 +  setResult(aResultBody);
++}
index f97b3248d112e95131995ef81d7cc5a9ec3429bd,ae772bd442c1943e95708bde3960e5cf55828c21..3ba02779f5b5a7cdb10b849ae6676bb742986070
@@@ -26,10 -24,8 +26,10 @@@ FeaturesPlugin_Placement::FeaturesPlugi
  
  void FeaturesPlugin_Placement::initAttributes()
  {
-   data()->addAttribute(FeaturesPlugin_Placement::BASE_OBJECT_ID(), ModelAPI_AttributeSelection::type());
-   data()->addAttribute(FeaturesPlugin_Placement::ATTRACT_OBJECT_ID(), ModelAPI_AttributeSelection::type());
-   data()->addAttribute(FeaturesPlugin_Placement::REVERSE_ID(), ModelAPI_AttributeBoolean::type());
-   data()->addAttribute(FeaturesPlugin_Placement::CENTERING_ID(), ModelAPI_AttributeBoolean::type());
 -  data()->addAttribute(FeaturesPlugin_Placement::BASE_FACE_ID(), ModelAPI_AttributeSelection::typeId());
 -  data()->addAttribute(FeaturesPlugin_Placement::ATTRACT_FACE_ID(), ModelAPI_AttributeSelection::typeId());
++  data()->addAttribute(FeaturesPlugin_Placement::BASE_OBJECT_ID(), ModelAPI_AttributeSelection::typeId());
++  data()->addAttribute(FeaturesPlugin_Placement::ATTRACT_OBJECT_ID(), ModelAPI_AttributeSelection::typeId());
++  data()->addAttribute(FeaturesPlugin_Placement::REVERSE_ID(), ModelAPI_AttributeBoolean::typeId());
++  data()->addAttribute(FeaturesPlugin_Placement::CENTERING_ID(), ModelAPI_AttributeBoolean::typeId());
  }
  
  void FeaturesPlugin_Placement::execute()
Simple merge
index 594c3af72a88068cb7c417781e5a794c26a0fdfd,0b7a6390365abe9f44bb3258f8c141fae84dcd66..953ffc4ee0c3e4d15bb0b8f8d7afaa0c135412d0
@@@ -4,13 -4,13 +4,13 @@@
        
        class FeaturesPlugin_Extrusion : public ModelAPI_Feature
          static const std::string MY_EXTRUSION_ID("Extrusion");
 -        static const std::string MY_FACE_ID("extrusion_face");
 -        static const std::string MY_SIZE_ID("extrusion_size");
 -        static const std::string MY_REVERSE_ID("extrusion_reverse");
 +        static const std::string MY_FACE_ID("base");
 +        static const std::string MY_SIZE_ID("size");
 +        static const std::string MY_REVERSE_ID("reverse");
            
--        data()->addAttribute(FeaturesPlugin_Extrusion::FACE_ID(), ModelAPI_AttributeSelection::type());
--        data()->addAttribute(FeaturesPlugin_Extrusion::SIZE_ID(), ModelAPI_AttributeDouble::type());
--        data()->addAttribute(FeaturesPlugin_Extrusion::REVERSE_ID(), ModelAPI_AttributeBoolean::type());
++        data()->addAttribute(FeaturesPlugin_Extrusion::FACE_ID(), ModelAPI_AttributeSelection::typeId());
++        data()->addAttribute(FeaturesPlugin_Extrusion::SIZE_ID(), ModelAPI_AttributeDouble::typeId());
++        data()->addAttribute(FeaturesPlugin_Extrusion::REVERSE_ID(), ModelAPI_AttributeBoolean::typeId());
  """
  
  # Number rows and columns of cylinders that cuts the big box. Number of Boolena operations is N*N
@@@ -19,12 -19,12 +19,13 @@@ N = 
  #=========================================================================
  # Initialization of the test
  #=========================================================================
--from ModelAPI import *
--from GeomDataAPI import *
--from GeomAlgoAPI import *
  from GeomAPI import *
- __updated__ = "2015-02-25"
++from GeomAlgoAPI import *
++from GeomDataAPI import *
++from ModelAPI import *
 +
 -__updated__ = "2015-02-25"
++__updated__ = "2015-03-26"
  
  aSession = ModelAPI_Session.get()
  aDocument = aSession.moduleDocument()
@@@ -47,23 -47,23 +48,23 @@@ radius = 95. / N / 2
  aSession.startOperation()
  aSketchFeatures = []
  for i in xrange(0, N):
--  for j in xrange(0, N):
--    # Create circle
--    aSketchFeature = modelAPI_CompositeFeature(aPart.addFeature("Sketch"))
--    origin = geomDataAPI_Point(aSketchFeature.attribute("Origin"))
--    origin.setValue(0, 0, 0)
--    dirx = geomDataAPI_Dir(aSketchFeature.attribute("DirX"))
--    dirx.setValue(1, 0, 0)
--    diry = geomDataAPI_Dir(aSketchFeature.attribute("DirY"))
--    diry.setValue(0, 1, 0)
--    norm = geomDataAPI_Dir(aSketchFeature.attribute("Norm"))
--    norm.setValue(0, 0, 1)
--    aSketchCircle = aSketchFeature.addFeature("SketchCircle")
--    anCircleCentr = geomDataAPI_Point2D(aSketchCircle.attribute("CircleCenter"))
--    aCircleRadius = aSketchCircle.real("CircleRadius")
--    anCircleCentr.setValue(0.5 + step * (0.5 + i), 0.5 + step * (0.5 + j))
--    aCircleRadius.setValue(radius)
--    aSketchFeatures.append(aSketchFeature)
++    for j in xrange(0, N):
++        # Create circle
++        aSketchFeature = modelAPI_CompositeFeature(aPart.addFeature("Sketch"))
++        origin = geomDataAPI_Point(aSketchFeature.attribute("Origin"))
++        origin.setValue(0, 0, 0)
++        dirx = geomDataAPI_Dir(aSketchFeature.attribute("DirX"))
++        dirx.setValue(1, 0, 0)
++        diry = geomDataAPI_Dir(aSketchFeature.attribute("DirY"))
++        diry.setValue(0, 1, 0)
++        norm = geomDataAPI_Dir(aSketchFeature.attribute("Norm"))
++        norm.setValue(0, 0, 1)
++        aSketchCircle = aSketchFeature.addFeature("SketchCircle")
++        anCircleCentr = geomDataAPI_Point2D(aSketchCircle.attribute("CircleCenter"))
++        aCircleRadius = aSketchCircle.real("CircleRadius")
++        anCircleCentr.setValue(0.5 + step * (0.5 + i), 0.5 + step * (0.5 + j))
++        aCircleRadius.setValue(radius)
++        aSketchFeatures.append(aSketchFeature)
  
  aSession.finishOperation()
  
@@@ -77,24 -77,23 +78,29 @@@ aSession.startOperation(
  
  anExtrusions = []
  for i in xrange(0, N * N):
--  aSketchResult = aSketchFeatures[i].firstResult()
--  aSketchEdges = modelAPI_ResultConstruction(aSketchResult).shape()
--  origin = geomDataAPI_Point(aSketchFeatures[i].attribute("Origin")).pnt()
--  dirX = geomDataAPI_Dir(aSketchFeatures[i].attribute("DirX")).dir()
--  dirY = geomDataAPI_Dir(aSketchFeatures[i].attribute("DirY")).dir()
--  norm = geomDataAPI_Dir(aSketchFeatures[i].attribute("Norm")).dir()
--  aSketchFaces = ShapeList()
--  GeomAlgoAPI_SketchBuilder.createFaces(
--      origin, dirX, dirY, norm, aSketchEdges, aSketchFaces)
--
--  anExtrusionFt = aPart.addFeature("Extrusion")
--  assert (anExtrusionFt.getKind() == "Extrusion")
-   anExtrusionFt.selectionList("base").append(
 -  anExtrusionFt.selection("extrusion_face").setValue(
--      aSketchResult, aSketchFaces[0])
-   anExtrusionFt.real("size").setValue(10)
-   anExtrusionFt.boolean("reverse").setValue(False)
 -  anExtrusionFt.real("extrusion_size").setValue(10)
 -  anExtrusionFt.boolean("extrusion_reverse").setValue(False)
--  anExtrusions.append(anExtrusionFt)
++    aSketchResult = aSketchFeatures[i].firstResult()
++    aSketchEdges = modelAPI_ResultConstruction(aSketchResult).shape()
++    origin = geomDataAPI_Point(aSketchFeatures[i].attribute("Origin")).pnt()
++    dirX = geomDataAPI_Dir(aSketchFeatures[i].attribute("DirX")).dir()
++    dirY = geomDataAPI_Dir(aSketchFeatures[i].attribute("DirY")).dir()
++    norm = geomDataAPI_Dir(aSketchFeatures[i].attribute("Norm")).dir()
++    aSketchFaces = ShapeList()
++    GeomAlgoAPI_SketchBuilder.createFaces(
++        origin, dirX, dirY, norm, aSketchEdges, aSketchFaces)
++
++    anExtrusionFt = aPart.addFeature("Extrusion")
++    assert (anExtrusionFt.getKind() == "Extrusion")
++
++    anExtrusionFt.selectionList("base").append(
++        aSketchResult, aSketchFaces[0])
++    anExtrusionFt.real("size").setValue(10)
++    anExtrusionFt.boolean("reverse").setValue(False)
++    # v1.0.2 from master
++    # anExtrusionFt.selection("extrusion_face").setValue(
++    #    aSketchResult, aSketchFaces[0])
++    # anExtrusionFt.real("extrusion_size").setValue(10)
++    # anExtrusionFt.boolean("extrusion_reverse").setValue(False)
++    anExtrusions.append(anExtrusionFt)
  
  aSession.finishOperation()
  
@@@ -149,27 -148,28 +155,33 @@@ GeomAlgoAPI_SketchBuilder.createFaces
      origin, dirX, dirY, norm, aSketchEdges, aSketchFaces)
  # Create extrusion on them
  aBox = aPart.addFeature("Extrusion")
 -aBox.selection("extrusion_face").setValue(
 +aBox.selectionList("base").append(
      aSketchResult, aSketchFaces[0])
 -aBox.real("extrusion_size").setValue(10)
 -aBox.boolean("extrusion_reverse").setValue(False)
 +aBox.real("size").setValue(10)
 +aBox.boolean("reverse").setValue(False)
++# v 1.0.2 from master
++# aBox.selection("extrusion_face").setValue(
++#     aSketchResult, aSketchFaces[0])
++# aBox.real("extrusion_size").setValue(10)
++# aBox.boolean("extrusion_reverse").setValue(False)
  aSession.finishOperation()
  
  
  #=========================================================================
--# Create a boolean cut of cylinders from the box: 
++# Create a boolean cut of cylinders from the box:
  # result of Boolean is the first argument of the next Boolean
  #=========================================================================
  aCurrentResult = aBox.firstResult()
  aSession.startOperation()
  for i in xrange(0, N * N):
--  aBooleanFt = aPart.addFeature("Boolean")
--  aBooleanFt.reference("main_object").setValue(modelAPI_ResultBody(aCurrentResult))
--  aBooleanFt.reference("tool_object").setValue(modelAPI_ResultBody(anExtrusions[i].firstResult()))
--  kBooleanTypeCut = 0
--  aBooleanFt.integer("bool_type").setValue(kBooleanTypeCut)
--  aBooleanFt.execute()
--  aCurrentResult = aBooleanFt.firstResult()
++    aBooleanFt = aPart.addFeature("Boolean")
++    aBooleanFt.reference("main_object").setValue(modelAPI_ResultBody(aCurrentResult))
++    aBooleanFt.reference("tool_object").setValue(modelAPI_ResultBody(anExtrusions[i].firstResult()))
++    kBooleanTypeCut = 0
++    aBooleanFt.integer("bool_type").setValue(kBooleanTypeCut)
++    aBooleanFt.execute()
++    aCurrentResult = aBooleanFt.firstResult()
  aSession.finishOperation()
  
  #=========================================================================
index 85d4b3a8c433706c41f92d0fb9580b719664c364,85a3cc031d3a7a365f5bb6676b3b19399c17ef76..4e61cd8f072ace18a6caa6561712e71bcf9f5339
@@@ -34,11 -33,9 +34,11 @@@ class GeomDataAPI_Dir : public ModelAPI
    virtual double z() const = 0;
    /// Returns the direction of this attribute
    virtual std::shared_ptr<GeomAPI_Dir> dir() = 0;
 +  /// Returns the coordinates of this attribute
 +  virtual std::shared_ptr<GeomAPI_XYZ> xyz() = 0;
  
    /// Returns the type of this class of attributes
-   static inline std::string type()
+   static std::string typeId()
    {
      return std::string("Dir");
    }
index 642d1cde9c0a493705b05f703ea61d423c36c40c,0000000000000000000000000000000000000000..cfd78c994b3ac8100e45e033af3313433ae3d4bb
mode 100644,000000..100644
--- /dev/null
@@@ -1,62 -1,0 +1,62 @@@
-         aValid = aRefAttr.get() != NULL && aRefAttr->attributeType() == GeomDataAPI_Point2D::type();
 +// Copyright (C) 2014-20xx CEA/DEN, EDF R&D
 +
 +
 +#include "GeomValidators_EdgeOrVertex.h"
 +#include "GeomValidators_Tools.h"
 +#include "GeomValidators_Edge.h"
 +
 +#include "ModelAPI_AttributeRefAttr.h"
 +#include "ModelAPI_Result.h"
 +
 +#include <ModelAPI_Session.h>
 +
 +#include <GeomAPI_Curve.h>
 +#include <GeomDataAPI_Point2D.h>
 +
 +#include <Events_Error.h>
 +
 +#include <StdSelect_TypeOfEdge.hxx>
 +
 +#include <QString>
 +#include <QMap>
 +
 +
 +bool GeomValidators_EdgeOrVertex::isValid(const AttributePtr& theAttribute,
 +                                          const std::list<std::string>& theArguments) const
 +{
 +  bool aValid = false;
 +
 +  // 1. check whether the attribute is a linear edge
 +    // there is a check whether the feature contains a point and a linear edge or two point values
 +  SessionPtr aMgr = ModelAPI_Session::get();
 +  ModelAPI_ValidatorsFactory* aFactory = aMgr->validators();
 +
 +  const GeomValidators_Edge* aLinearEdgeValidator =
 +    dynamic_cast<const GeomValidators_Edge*>(aFactory->validator("GeomValidators_Edge"));
 +
 +  std::list<std::string> anArguments;
 +  anArguments.push_back("line");
 +  aValid = aLinearEdgeValidator->isValid(theAttribute, anArguments);
 +  if (!aValid) {
 +    //2. check whether the attribute is a vertex
 +    ObjectPtr anObject = GeomValidators_Tools::getObject(theAttribute);
 +    if (anObject.get() != NULL) {
 +      FeaturePtr aFeature = ModelAPI_Feature::feature(anObject);
 +      ResultPtr aResult = std::dynamic_pointer_cast<ModelAPI_Result>(anObject);
 +      if (aResult.get() != NULL) {
 +        GeomShapePtr aShape = aResult->shape();
 +        if (aShape.get() != NULL) {
 +          aValid = aShape->isVertex();
 +        }
 +      }
 +    }
 +    else {
 +      AttributeRefAttrPtr anAttr = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(theAttribute);
 +      if (anAttr.get() != NULL) {
 +        AttributePtr aRefAttr = anAttr->attr();
++        aValid = aRefAttr.get() != NULL && aRefAttr->attributeType() == GeomDataAPI_Point2D::typeId();
 +      }
 +    }
 +  }
 +  return aValid;
 +}
index f98088ed3b17f4059b46cbfc430d9838032497ae,0000000000000000000000000000000000000000..898296961797985cb3289a1a3bb066020a559a0b
mode 100644,000000..100644
--- /dev/null
@@@ -1,36 -1,0 +1,36 @@@
-     if (anAttrType == ModelAPI_AttributeRefAttr::type()) {
 +// Copyright (C) 2014-20xx CEA/DEN, EDF R&D
 +
 +// File:        GeomValidators_Tools.cpp
 +// Created:     06 Aug 2014
 +// Author:      Vitaly Smetannikov
 +
 +#include "GeomValidators_Tools.h"
 +
 +#include "ModelAPI_AttributeRefAttr.h"
 +#include "ModelAPI_AttributeSelection.h"
 +#include "ModelAPI_AttributeReference.h"
 +
 +namespace GeomValidators_Tools {
 +
 +  ObjectPtr getObject(const AttributePtr& theAttribute)
 +  {
 +    ObjectPtr anObject;
 +    std::string anAttrType = theAttribute->attributeType();
-     if (anAttrType == ModelAPI_AttributeSelection::type()) {
++    if (anAttrType == ModelAPI_AttributeRefAttr::typeId()) {
 +      AttributeRefAttrPtr anAttr = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(theAttribute);
 +      if (anAttr != NULL && anAttr->isObject())
 +        anObject = anAttr->object();
 +    }
-     if (anAttrType == ModelAPI_AttributeReference::type()) {
++    if (anAttrType == ModelAPI_AttributeSelection::typeId()) {
 +      AttributeSelectionPtr anAttr = std::dynamic_pointer_cast<ModelAPI_AttributeSelection>(theAttribute);
 +      if (anAttr != NULL && anAttr->isInitialized())
 +        anObject = anAttr->context();
 +    }
++    if (anAttrType == ModelAPI_AttributeReference::typeId()) {
 +      AttributeReferencePtr anAttr = std::dynamic_pointer_cast<ModelAPI_AttributeReference>(theAttribute);
 +      if (anAttr.get() != NULL && anAttr->isInitialized())
 +        anObject = anAttr->value();
 +    }
 +    return anObject;
 +  }
 +}
index 9133794ae94460375cf53c75b966de982345e221,d19f2d6d1e377239b856bbd4c858c84e85f7329b..003fb28e9912227a90e23a41680f331e8ab7b333
@@@ -655,149 -644,130 +673,149 @@@ std::string Model_AttributeSelection::n
    aName = GetShapeName(aDoc, aSubShape, selectionLabel());
    if(aName.empty() ) { // not in the document!
      TopAbs_ShapeEnum aType = aSubShape.ShapeType();
-       switch (aType) {
-         case TopAbs_FACE:
+     switch (aType) {
+     case TopAbs_FACE:
        // the Face should be in DF. If it is not the case, it is an error ==> to be debugged           
 -      break;
 -    case TopAbs_EDGE:
 -      {
 -        // name structure: F1 | F2 [| F3 | F4], where F1 & F2 the faces which gives the Edge in trivial case
 -        // if it is not atrivial case we use localization by neighbours. F3 & F4 - neighbour faces             
 -        TopTools_IndexedDataMapOfShapeListOfShape aMap;
 -        TopExp::MapShapesAndAncestors(aContext, TopAbs_EDGE, TopAbs_FACE, aMap);
 -        TopTools_IndexedMapOfShape aSMap; // map for ancestors of the sub-shape
 -        bool isTrivialCase(true);
 -        /*              for (int i = 1; i <= aMap.Extent(); i++) {
 -        const TopoDS_Shape& aKey = aMap.FindKey(i);
 -        //if (aKey.IsNotEqual(aSubShape)) continue; // find exactly the selected key
 -        if (aKey.IsSame(aSubShape)) continue;
 -        const TopTools_ListOfShape& anAncestors = aMap.FindFromIndex(i);
 -        // check that it is not a trivial case (F1 & F2: aNumber = 1)
 -        isTrivialCase = isTrivial(anAncestors, aSMap);                        
 -        break;
 -        }*/
 -        if(aMap.Contains(aSubShape)) {
 -          const TopTools_ListOfShape& anAncestors = aMap.FindFromKey(aSubShape);
 -          // check that it is not a trivial case (F1 & F2: aNumber = 1)
 -          isTrivialCase = isTrivial(anAncestors, aSMap);              
 -        } else 
 -          break;
 -        TopTools_ListOfShape aListOfNbs;
 -        if(!isTrivialCase) { // find Neighbors
 -          TNaming_Localizer aLocalizer;
 -          TopTools_MapOfShape aMap3;
 -          aLocalizer.FindNeighbourg(aContext, aSubShape, aMap3);
 -          //int n = aMap3.Extent();
 -          TopTools_MapIteratorOfMapOfShape it(aMap3);
 -          for(;it.More();it.Next()) {
 -            const TopoDS_Shape& aNbShape = it.Key(); // neighbor edge
 -            //TopAbs_ShapeEnum aType = aNbShape.ShapeType();
 -            const TopTools_ListOfShape& aList  = aMap.FindFromKey(aNbShape);
 -            TopTools_ListIteratorOfListOfShape it2(aList);
 -            for(;it2.More();it2.Next()) {
 -              if(aSMap.Contains(it2.Value())) continue; // skip this Face
 -              aListOfNbs.Append(it2.Value());
 -            }
 -          }
 -        }  // else a trivial case
 -
 -        // build name of the sub-shape Edge
 -        for(int i=1; i <= aSMap.Extent(); i++) {
 -          const TopoDS_Shape& aFace = aSMap.FindKey(i);
 -          std::string aFaceName = GetShapeName(aDoc, aFace, selectionLabel());
 -          if(i == 1)
 -            aName = aFaceName;
 -          else 
 -            aName += "|" + aFaceName;
 -        }
 -        TopTools_ListIteratorOfListOfShape itl(aListOfNbs);
 -        for (;itl.More();itl.Next()) {
 -          std::string aFaceName = GetShapeName(aDoc, itl.Value(), selectionLabel());
 -          aName += "|" + aFaceName;
 -        }               
 -      }
 -      break;
 +              break;
 +        case TopAbs_EDGE:
 +                {
 +                // name structure: F1 | F2 [| F3 | F4], where F1 & F2 the faces which gives the Edge in trivial case
 +                // if it is not atrivial case we use localization by neighbours. F3 & F4 - neighbour faces    
 +                if (BRep_Tool::Degenerated(TopoDS::Edge(aSubShape))) {
 +                        aName = "Degenerated_Edge";
 +                        break;
 +                }    
 +                TopTools_IndexedDataMapOfShapeListOfShape aMap;
 +                TopExp::MapShapesAndAncestors(aContext, TopAbs_EDGE, TopAbs_FACE, aMap);
 +                TopTools_IndexedMapOfShape aSMap; // map for ancestors of the sub-shape
 +                bool isTrivialCase(true);
 +/*              for (int i = 1; i <= aMap.Extent(); i++) {
 +                      const TopoDS_Shape& aKey = aMap.FindKey(i);
 +                      //if (aKey.IsNotEqual(aSubShape)) continue; // find exactly the selected key
 +                      if (aKey.IsSame(aSubShape)) continue;
 +            const TopTools_ListOfShape& anAncestors = aMap.FindFromIndex(i);
 +                      // check that it is not a trivial case (F1 & F2: aNumber = 1)
 +                      isTrivialCase = isTrivial(anAncestors, aSMap);                  
 +                      break;
 +                }*/
 +                if(aMap.Contains(aSubShape)) {
 +                      const TopTools_ListOfShape& anAncestors = aMap.FindFromKey(aSubShape);
 +                      // check that it is not a trivial case (F1 & F2: aNumber = 1)
 +                      isTrivialCase = isTrivial(anAncestors, aSMap);          
 +                } else 
 +                        break;
 +                TopTools_ListOfShape aListOfNbs;
 +                if(!isTrivialCase) { // find Neighbors
 +                      TNaming_Localizer aLocalizer;
 +                      TopTools_MapOfShape aMap3;
 +                      aLocalizer.FindNeighbourg(aContext, aSubShape, aMap3);
 +                      //int n = aMap3.Extent();
 +                      TopTools_MapIteratorOfMapOfShape it(aMap3);
 +                      for(;it.More();it.Next()) {
 +                        const TopoDS_Shape& aNbShape = it.Key(); // neighbor edge
 +                        //TopAbs_ShapeEnum aType = aNbShape.ShapeType();
 +                        const TopTools_ListOfShape& aList  = aMap.FindFromKey(aNbShape);
 +                        TopTools_ListIteratorOfListOfShape it2(aList);
 +                        for(;it2.More();it2.Next()) {
 +                              if(aSMap.Contains(it2.Value())) continue; // skip this Face
 +                              aListOfNbs.Append(it2.Value());
 +                        }
 +                      }
 +                }  // else a trivial case
 +                
 +                // build name of the sub-shape Edge
 +                for(int i=1; i <= aSMap.Extent(); i++) {
 +                      const TopoDS_Shape& aFace = aSMap.FindKey(i);
 +                      std::string aFaceName = GetShapeName(aDoc, aFace, selectionLabel());
 +                      if(i == 1)
 +                        aName = aFaceName;
 +                      else 
 +                        aName += "|" + aFaceName;
 +                }
 +                TopTools_ListIteratorOfListOfShape itl(aListOfNbs);
 +                for (;itl.More();itl.Next()) {
 +                      std::string aFaceName = GetShapeName(aDoc, itl.Value(), selectionLabel());
 +                      aName += "|" + aFaceName;
 +                }               
 +                }
 +                break;
  
-         case TopAbs_VERTEX:
-                 // name structure (Monifold Topology): 
-                 // 1) F1 | F2 | F3 - intersection of 3 faces defines a vertex - trivial case.
-                 // 2) F1 | F2 | F3 [|F4 [|Fn]] - redundant definition, but it should be kept as is to obtain safe recomputation
-                 // 2) F1 | F2      - intersection of 2 faces definses a vertex - applicable for case
-                 //                   when 1 faces is cylindrical, conical, spherical or revolution and etc.
-                 // 3) E1 | E2 | E3 - intersection of 3 edges defines a vertex - when we have case of a shell
-                 //                   or compound of 2 open faces.
-                 // 4) E1 | E2      - intesection of 2 edges defines a vertex - when we have a case of 
-                 //                   two independent edges (wire or compound)
-                 // implemented 2 first cases
-                 {
-                       TopTools_IndexedDataMapOfShapeListOfShape aMap;
-                   TopExp::MapShapesAndAncestors(aContext, TopAbs_VERTEX, TopAbs_FACE, aMap);
-                       const TopTools_ListOfShape& aList2  = aMap.FindFromKey(aSubShape);
-                       TopTools_ListOfShape aList;
-                       TopTools_MapOfShape aFMap;
+     case TopAbs_VERTEX:
+       // name structure (Monifold Topology): 
+       // 1) F1 | F2 | F3 - intersection of 3 faces defines a vertex - trivial case.
+       // 2) F1 | F2 | F3 [|F4 [|Fn]] - redundant definition, but it should be kept as is to obtain safe recomputation
+       // 2) F1 | F2      - intersection of 2 faces definses a vertex - applicable for case
+       //                   when 1 faces is cylindrical, conical, spherical or revolution and etc.
+       // 3) E1 | E2 | E3 - intersection of 3 edges defines a vertex - when we have case of a shell
+       //                   or compound of 2 open faces.
+       // 4) E1 | E2      - intesection of 2 edges defines a vertex - when we have a case of 
+       //                   two independent edges (wire or compound)
+       // implemented 2 first cases
+       {
+         TopTools_IndexedDataMapOfShapeListOfShape aMap;
+         TopExp::MapShapesAndAncestors(aContext, TopAbs_VERTEX, TopAbs_FACE, aMap);
+         const TopTools_ListOfShape& aList2  = aMap.FindFromKey(aSubShape);
+         TopTools_ListOfShape aList;
+         TopTools_MapOfShape aFMap;
  #ifdef FIX_BUG1
-                       //int n = aList2.Extent(); //bug! duplication
-                       // fix is below
-                       TopTools_ListIteratorOfListOfShape itl2(aList2);
-                   for (int i = 1;itl2.More();itl2.Next(),i++) {
-                         if(aFMap.Add(itl2.Value()))
-                               aList.Append(itl2.Value());
-                       }
-                       //n = aList.Extent();
+         //int n = aList2.Extent(); //bug! duplication
+         // fix is below
+         TopTools_ListIteratorOfListOfShape itl2(aList2);
+         for (int i = 1;itl2.More();itl2.Next(),i++) {
+           if(aFMap.Add(itl2.Value()))
+             aList.Append(itl2.Value());
+         }
+         //n = aList.Extent();
  #endif
-                       int n = aList.Extent();
-                       if(n < 3) { // open topology case or Compound case => via edges
-                         TopTools_IndexedDataMapOfShapeListOfShape aMap;
-                     TopExp::MapShapesAndAncestors(aContext, TopAbs_VERTEX, TopAbs_EDGE, aMap);
-                         const TopTools_ListOfShape& aList22  = aMap.FindFromKey(aSubShape);
-                         if(aList22.Extent() >= 2)  { // regular solution
+         int n = aList.Extent();
 -        if(n < 3) { // open topology case => via edges
++        if(n < 3) { // open topology case or Compound case => via edges
+           TopTools_IndexedDataMapOfShapeListOfShape aMap;
+           TopExp::MapShapesAndAncestors(aContext, TopAbs_VERTEX, TopAbs_EDGE, aMap);
 -          const TopTools_ListOfShape& aList2  = aMap.FindFromKey(aSubShape);
 -          if(aList2.Extent() >= 2)  { // regular solution
 -            TopTools_ListIteratorOfListOfShape itl(aList2);
++          const TopTools_ListOfShape& aList22  = aMap.FindFromKey(aSubShape);
++          if(aList22.Extent() >= 2)  { // regular solution
 +#ifdef FIX_BUG1
-                       
-                           // bug! duplication; fix is below
-                           aFMap.Clear();
-                           TopTools_ListOfShape aListE;
-                           TopTools_ListIteratorOfListOfShape itl2(aList22);
-                       for (int i = 1;itl2.More();itl2.Next(),i++) {
-                           if(aFMap.Add(itl2.Value()))
-                                 aListE.Append(itl2.Value());
-                               }
-                           n = aListE.Extent();
++
++            // bug! duplication; fix is below
++            aFMap.Clear();
++            TopTools_ListOfShape aListE;
++            TopTools_ListIteratorOfListOfShape itl2(aList22);
++            for (int i = 1;itl2.More();itl2.Next(),i++) {
++              if(aFMap.Add(itl2.Value()))
++                aListE.Append(itl2.Value());
++            }
++            n = aListE.Extent();
 +#endif
-                               TopTools_ListIteratorOfListOfShape itl(aListE);
-                       for (int i = 1;itl.More();itl.Next(),i++) {
-                             const TopoDS_Shape& anEdge = itl.Value();
-                             std::string anEdgeName = GetShapeName(aDoc, anEdge, selectionLabel());
-                             if(i == 1)
-                               aName = anEdgeName;
-                             else 
-                               aName += "|" + anEdgeName;
-                               }
-                         }//reg
-                         else { // dangle vertex: if(aList22.Extent() == 1)
-                                 //it should be already in DF
-                         }
-                       } 
-                       else {
-                         TopTools_ListIteratorOfListOfShape itl(aList);
-                     for (int i = 1;itl.More();itl.Next(),i++) {
-                           const TopoDS_Shape& aFace = itl.Value();
-                           std::string aFaceName = GetShapeName(aDoc, aFace, selectionLabel());
-                           if(i == 1)
-                             aName = aFaceName;
-                           else 
-                             aName += "|" + aFaceName;
-                         }
-                       }
-                 }
-                 break;
-       }
++            TopTools_ListIteratorOfListOfShape itl(aListE);
+             for (int i = 1;itl.More();itl.Next(),i++) {
+               const TopoDS_Shape& anEdge = itl.Value();
+               std::string anEdgeName = GetShapeName(aDoc, anEdge, selectionLabel());
+               if(i == 1)
+                 aName = anEdgeName;
+               else 
+                 aName += "|" + anEdgeName;
+             }
++          }//reg
++          else { // dangle vertex: if(aList22.Extent() == 1)
++            //it should be already in DF
+           }
+         } 
+         else {
+           TopTools_ListIteratorOfListOfShape itl(aList);
+           for (int i = 1;itl.More();itl.Next(),i++) {
+             const TopoDS_Shape& aFace = itl.Value();
+             std::string aFaceName = GetShapeName(aDoc, aFace, selectionLabel());
+             if(i == 1)
+               aName = aFaceName;
+             else 
+               aName += "|" + aFaceName;
+           }
+         }
+       }
+       break;
+     }
      // register name                  
      // aDoc->addNamingName(selectionLabel(), aName);
-       // the selected sub-shape will not be shared and as result it will not require registration
+     // the selected sub-shape will not be shared and as result it will not require registration
    }
    return aName;
  }
index 82cc259187f241baf8d61af17ecd4be53b79251a,f280f8fc6f3670e3709a5ca9eabb77a504c627e5..d537db894aa04f9a905c4a8339b9c7ddfbaa555f
@@@ -70,40 -66,37 +70,40 @@@ void Model_Data::setName(const std::str
    }
  }
  
 -void Model_Data::addAttribute(const std::string& theID, const std::string theAttrType)
 +AttributePtr Model_Data::addAttribute(const std::string& theID, const std::string theAttrType)
  {
 +  AttributePtr aResult;
    TDF_Label anAttrLab = myLab.FindChild(myAttrs.size() + 1);
    ModelAPI_Attribute* anAttr = 0;
-   if (theAttrType == ModelAPI_AttributeDocRef::type()) {
+   if (theAttrType == ModelAPI_AttributeDocRef::typeId()) {
      anAttr = new Model_AttributeDocRef(anAttrLab);
-   } else if (theAttrType == Model_AttributeInteger::type()) {
+   } else if (theAttrType == Model_AttributeInteger::typeId()) {
      anAttr = new Model_AttributeInteger(anAttrLab);
-   } else if (theAttrType == ModelAPI_AttributeDouble::type()) {
+   } else if (theAttrType == ModelAPI_AttributeDouble::typeId()) {
      anAttr = new Model_AttributeDouble(anAttrLab);
-   } else if (theAttrType == Model_AttributeBoolean::type()) {
+   } else if (theAttrType == Model_AttributeBoolean::typeId()) {
      anAttr = new Model_AttributeBoolean(anAttrLab);
-   } else if (theAttrType == Model_AttributeString::type()) {
+   } else if (theAttrType == Model_AttributeString::typeId()) {
      anAttr = new Model_AttributeString(anAttrLab);
-   } else if (theAttrType == ModelAPI_AttributeReference::type()) {
+   } else if (theAttrType == ModelAPI_AttributeReference::typeId()) {
      anAttr = new Model_AttributeReference(anAttrLab);
-   } else if (theAttrType == ModelAPI_AttributeSelection::type()) {
+   } else if (theAttrType == ModelAPI_AttributeSelection::typeId()) {
      anAttr = new Model_AttributeSelection(anAttrLab);
-   } else if (theAttrType == ModelAPI_AttributeSelectionList::type()) {
+   } else if (theAttrType == ModelAPI_AttributeSelectionList::typeId()) {
      anAttr = new Model_AttributeSelectionList(anAttrLab);
-   } else if (theAttrType == ModelAPI_AttributeRefAttr::type()) {
+   } else if (theAttrType == ModelAPI_AttributeRefAttr::typeId()) {
      anAttr = new Model_AttributeRefAttr(anAttrLab);
-   } else if (theAttrType == ModelAPI_AttributeRefList::type()) {
+   } else if (theAttrType == ModelAPI_AttributeRefList::typeId()) {
      anAttr = new Model_AttributeRefList(anAttrLab);
-   } else if (theAttrType == ModelAPI_AttributeIntArray::type()) {
++  } else if (theAttrType == ModelAPI_AttributeIntArray::typeId()) {
 +    anAttr = new Model_AttributeIntArray(anAttrLab);
    } 
    // create also GeomData attributes here because only here the OCAF strucure is known
-   else if (theAttrType == GeomData_Point::type()) {
+   else if (theAttrType == GeomData_Point::typeId()) {
      anAttr = new GeomData_Point(anAttrLab);
-   } else if (theAttrType == GeomData_Dir::type()) {
+   } else if (theAttrType == GeomData_Dir::typeId()) {
      anAttr = new GeomData_Dir(anAttrLab);
-   } else if (theAttrType == GeomData_Point2D::type()) {
+   } else if (theAttrType == GeomData_Point2D::typeId()) {
      anAttr = new GeomData_Point2D(anAttrLab);
    }
    if (anAttr) {
index 2bdea7f5f30bdf54fbd2db814dccdc2b16615f1e,7d3fa0b8219b24d5b70540ad72362f489d24fbbe..7708c92cfbda5f6707876e72b6e6e49db579d23f
@@@ -42,21 -40,6 +42,21 @@@ Model_ResultBody::Model_ResultBody(
    setIsConcealed(false);
  }
  
-   aData->addAttribute(COLOR_ID(), ModelAPI_AttributeIntArray::type());
 +void Model_ResultBody::initAttributes()
 +{
 +  // append the color attribute. It is empty, the attribute will be filled by a request
 +  DataPtr aData = data();
++  aData->addAttribute(COLOR_ID(), ModelAPI_AttributeIntArray::typeId());
 +}
 +
 +void Model_ResultBody::colorConfigInfo(std::string& theSection, std::string& theName,
 +                                       std::string& theDefault)
 +{
 +  theSection = "Visualization";
 +  theName = "result_body_color";
 +  theDefault = DEFAULT_COLOR();
 +}
 +
  void Model_ResultBody::store(const std::shared_ptr<GeomAPI_Shape>& theShape)
  {
    std::shared_ptr<Model_Data> aData = std::dynamic_pointer_cast<Model_Data>(data());
index 2998e9f2db8a4879186ed9cbb458051d027100d1,aaade70ff23d3364b2fb930b5c1bc61081d5eac2..1e2021c42637615880d9a35fa48c299f9c77e1e5
@@@ -6,35 -6,9 +6,35 @@@
  
  #include <Model_ResultConstruction.h>
  
-   aData->addAttribute(COLOR_ID(), ModelAPI_AttributeIntArray::type());
 +#include <ModelAPI_AttributeIntArray.h>
 +#include <Config_PropManager.h>
 +#include <GeomAPI_PlanarEdges.h>
 +#include <GeomAlgoAPI_SketchBuilder.h>
 +
 +void Model_ResultConstruction::initAttributes()
 +{
 +  // append the color attribute. It is empty, the attribute will be filled by a request
 +  DataPtr aData = data();
++  aData->addAttribute(COLOR_ID(), ModelAPI_AttributeIntArray::typeId());
 +}
 +
 +void Model_ResultConstruction::colorConfigInfo(std::string& theSection, std::string& theName,
 +                                       std::string& theDefault)
 +{
 +  theSection = "Visualization";
 +  theName = "result_construction_color";
 +  theDefault = DEFAULT_COLOR();
 +}
 +
  void Model_ResultConstruction::setShape(std::shared_ptr<GeomAPI_Shape> theShape)
  {
 -  myShape = theShape;
 +  if (myShape != theShape && (!theShape.get() || !theShape->isEqual(myShape))) {
 +    myShape = theShape;
 +    if (theShape.get()) {
 +      myFacesUpToDate = false;
 +      myFaces.clear();
 +    }
 +  }
  }
  
  std::shared_ptr<GeomAPI_Shape> Model_ResultConstruction::shape()
index dd4ee732b7091f9823036048d326bef3f3d6f1af,ebcdb9b437ff4915e0bfe66b11856f4efb0b16f3..39809bade0444a0a964855077dd8926599024119
@@@ -18,21 -14,6 +18,21 @@@ Model_ResultGroup::Model_ResultGroup(st
    myOwnerData = theOwnerData;
  }
  
-   aData->addAttribute(COLOR_ID(), ModelAPI_AttributeIntArray::type());
 +void Model_ResultGroup::initAttributes()
 +{
 +  // append the color attribute. It is empty, the attribute will be filled by a request
 +  DataPtr aData = data();
++  aData->addAttribute(COLOR_ID(), ModelAPI_AttributeIntArray::typeId());
 +}
 +
 +void Model_ResultGroup::colorConfigInfo(std::string& theSection, std::string& theName,
 +                                       std::string& theDefault)
 +{
 +  theSection = "Visualization";
 +  theName = "result_group_color";
 +  theDefault = DEFAULT_COLOR();
 +}
 +
  std::shared_ptr<GeomAPI_Shape> Model_ResultGroup::shape()
  {
    std::shared_ptr<GeomAPI_Shape> aResult;
Simple merge
Simple merge
index 0e0304c46eea0234ca6a9424e76a483c0e99e105,0000000000000000000000000000000000000000..52d870d57478d3179859de5766fb6b36934a1a8a
mode 100644,000000..100644
--- /dev/null
@@@ -1,22 -1,0 +1,22 @@@
-   return type();
 +// Copyright (C) 2014-20xx CEA/DEN, EDF R&D
 +
 +// File:        ModelAPI_AttributeIntArray.cpp
 +// Created:     6 Mar 2015
 +// Author:      Natalia ERMOLAEVA
 +
 +#include <ModelAPI_AttributeIntArray.h>
 +
 +
 +std::string ModelAPI_AttributeIntArray::attributeType()
 +{
++  return typeId();
 +}
 +
 +/// To virtually destroy the fields of successors
 +ModelAPI_AttributeIntArray::~ModelAPI_AttributeIntArray()
 +{
 +}
 +
 +ModelAPI_AttributeIntArray::ModelAPI_AttributeIntArray()
 +{
 +}
index 177db0422378aae8e002e44da6690ce32f9fbb32,0000000000000000000000000000000000000000..8b319a16d48ca75c8f6237a8f65071cb6157eb34
mode 100644,000000..100644
--- /dev/null
@@@ -1,59 -1,0 +1,59 @@@
-   MODELAPI_EXPORT static std::string type()
 +// Copyright (C) 2014-20xx CEA/DEN, EDF R&D
 +
 +// File:        ModelAPI_AttributeIntArray.h
 +// Created:     6 Mar 2015
 +// Author:      Natalia ERMOLAEVA
 +
 +#ifndef ModelAPI_AttributeIntArray_H_
 +#define ModelAPI_AttributeIntArray_H_
 +
 +#include <ModelAPI.h>
 +#include <ModelAPI_Attribute.h>
 +
 +#include <string>
 +
 +
 +/**\class ModelAPI_AttributeIntArray
 + * \ingroup DataModel
 + * \brief API for the attribute that contains several integers in the array inside.
 + * Used for RGB color storage for an example. By default size is one, zero-based.
 + */
 +
 +class ModelAPI_AttributeIntArray : public ModelAPI_Attribute
 +{
 + public:
 +
 +  /// Returns the size of the array (zero means that it is empty)
 +  MODELAPI_EXPORT virtual int size() = 0;
 +
 +  /// Sets the new size of the array. The previous data is erased.
 +  MODELAPI_EXPORT virtual void setSize(const int theSize) = 0;
 +
 +  /// Defines the value of the array by index [0; size-1]
 +  MODELAPI_EXPORT virtual void setValue(const int theIndex,
 +                                         const int theValue) = 0;
 +
 +  /// Returns the value by the index
 +  MODELAPI_EXPORT virtual int value(const int theIndex) = 0;
 +
 +  /// Returns the type of this class of attributes
++  MODELAPI_EXPORT static std::string typeId()
 +  {
 +    return "IntArray";
 +  }
 +
 +  /// Returns the type of this class of attributes, not static method
 +  MODELAPI_EXPORT virtual std::string attributeType();
 +
 +  /// To virtually destroy the fields of successors
 +  MODELAPI_EXPORT virtual ~ModelAPI_AttributeIntArray();
 +
 + protected:
 +  /// Objects are created for features automatically
 +  MODELAPI_EXPORT ModelAPI_AttributeIntArray();
 +};
 +
 +//! Pointer on double attribute
 +typedef std::shared_ptr<ModelAPI_AttributeIntArray> AttributeIntArrayPtr;
 +
 +#endif
Simple merge
index 0ef625cd74f04ea4831d65016c0857947b64c292,8de8d27679c530607eba6f4c06ffc619891a6e65..fb03f459fbacc878155c6b552d2a9c37d3f0898f
@@@ -20,8 -16,8 +20,8 @@@ bool ModelAPI_ShapeValidator::isValid(c
    std::string aCurrentAttributeId = theAttribute->id();
    // get all feature attributes
    std::list<AttributePtr> anAttrs = 
-                    aFeature->data()->attributes(ModelAPI_AttributeSelection::type());
 -                   theFeature->data()->attributes(ModelAPI_AttributeSelection::typeId());
 -  if (anAttrs.size() > 0 && theShape.get() != NULL) {
++      aFeature->data()->attributes(ModelAPI_AttributeSelection::typeId());
 +  if (anAttrs.size() > 0 && aShape.get() != NULL) {
      std::list<AttributePtr>::iterator anAttr = anAttrs.begin();
      for(; anAttr != anAttrs.end(); anAttr++) {
        AttributePtr anAttribute = *anAttr;
index 4b8c7d34bec1db0259ad11036dc3dffed806e207,63a3e1e6af1baac05b0ef81fad8a93d1fe11cbc1..ff2780957fc336c22171175d85433ee26ea824c0
@@@ -127,16 -137,28 +127,25 @@@ bool ModuleBase_Operation::hasObject(Ob
    return false;
  }
  
 -
 -std::shared_ptr<ModelAPI_Document> ModuleBase_Operation::document() const
 -{
 -  return ModelAPI_Session::get()->moduleDocument();
 -}
 -
 -
  void ModuleBase_Operation::start()
  {
 -  ModelAPI_Session::get()->startOperation();
 +  QString anId = getDescription()->operationId();
 +  if (myIsEditing) {
 +      anId = anId.append(EditSuffix());
 +  }
 +  ModelAPI_Session::get()->startOperation(anId.toStdString());
  
-   if (!myIsEditing)
-     createFeature();
+   if (!myIsEditing) {
+     FeaturePtr aFeature = createFeature();
+     // if the feature is not created, there is no sense to start the operation
+     if (aFeature.get() == NULL) {
+       // it is necessary to abor the operation in the session and emit the aborted signal
+       // in order to update commands status in the workshop, to be exact the feature action
+       // to be unchecked
+       abort();
+       return;
+     }
+   }
  
    startOperation();
    emit started();
index ef46fa06220feb56ad5b131594aab1b1d19ae299,74bd7f61aa2b07a82c43e7b2fc32adb5f966a2b5..c0e4faacff2ee5aa7af6fc1c1af5024f157dd20d
@@@ -387,72 -467,53 +387,81 @@@ void ModuleBase_WidgetShapeSelector::st
  }
  
  //********************************************************************
 -bool ModuleBase_WidgetShapeSelector::isValid(ObjectPtr theObj, std::shared_ptr<GeomAPI_Shape> theShape)
 +void ModuleBase_WidgetShapeSelector::restoreAttributeValue(bool theValid)
  {
 -  SessionPtr aMgr = ModelAPI_Session::get();
 -  ModelAPI_ValidatorsFactory* aFactory = aMgr->validators();
 -  std::list<ModelAPI_Validator*> aValidators;
 -  std::list<std::list<std::string> > anArguments;
 -  aFactory->validators(parentID(), attributeID(), aValidators, anArguments);
 -
 -  // Check the type of selected object
 -  std::list<ModelAPI_Validator*>::iterator aValidator = aValidators.begin();
 -  bool isValid = true;
 -  for (; aValidator != aValidators.end(); aValidator++) {
 -    const ModelAPI_ResultValidator* aResValidator =
 -        dynamic_cast<const ModelAPI_ResultValidator*>(*aValidator);
 -    if (aResValidator) {
 -      isValid = false;
 -      if (aResValidator->isValid(theObj)) {
 -        isValid = true;
 -        break;
 -      }
 -    }
 +  DataPtr aData = myFeature->data();
 +  AttributePtr anAttribute = myFeature->attribute(attributeID());
 +
 +  setObject(myObject, myShape);
 +  AttributeRefAttrPtr aRefAttr = aData->refattr(attributeID());
 +  if (aRefAttr) {
 +    if (!myIsObject)
 +      aRefAttr->setAttr(myRefAttribute);
    }
 -  if (!isValid)
 +}
 +
 +//********************************************************************
 +bool ModuleBase_WidgetShapeSelector::setSelection(const Handle_SelectMgr_EntityOwner& theOwner)
 +{
 +  bool isDone = false;
 +
 +  ModuleBase_ViewerPrs aPrs;
 +  myWorkshop->selection()->fillPresentation(aPrs, theOwner);
 +  ObjectPtr aObject = aPrs.object();
 +  ObjectPtr aCurrentObject = GeomValidators_Tools::getObject(myFeature->attribute(attributeID()));
 +  if ((!aCurrentObject) && (!aObject))
 +    return false;
 +
 +  // Check that the selected object is result (others can not be accepted)
 +  ResultPtr aRes = std::dynamic_pointer_cast<ModelAPI_Result>(aObject);
 +  if (!aRes)
      return false;
  
 -  // Check the acceptability of the object as attribute
 -  aValidator = aValidators.begin();
 -  std::list<std::list<std::string> >::iterator aArgs = anArguments.begin();
 -  for (; aValidator != aValidators.end(); aValidator++, aArgs++) {
 -    const ModelAPI_RefAttrValidator* aAttrValidator =
 -        dynamic_cast<const ModelAPI_RefAttrValidator*>(*aValidator);
 -    if (aAttrValidator) {
 -      if (!aAttrValidator->isValid(myFeature, *aArgs, theObj, theShape)) {
 +  if (myFeature) {
 +    // We can not select a result of our feature
 +    const std::list<std::shared_ptr<ModelAPI_Result>>& aResList = myFeature->results();
 +    std::list<std::shared_ptr<ModelAPI_Result> >::const_iterator aIt;
 +    for (aIt = aResList.cbegin(); aIt != aResList.cend(); ++aIt) {
 +      if ((*aIt) == aRes)
++// TODO(nds): v1.0.2 (master)
++//  // Check the acceptability of the object as attribute
++//  aValidator = aValidators.begin();
++//  std::list<std::list<std::string> >::iterator aArgs = anArguments.begin();
++//  for (; aValidator != aValidators.end(); aValidator++, aArgs++) {
++//    const ModelAPI_RefAttrValidator* aAttrValidator =
++//        dynamic_cast<const ModelAPI_RefAttrValidator*>(*aValidator);
++//    if (aAttrValidator) {
++//      if (!aAttrValidator->isValid(myFeature, *aArgs, theObj, theShape)) {
          return false;
 -      }
 -    }
 -    else {
 -      const ModelAPI_ShapeValidator* aShapeValidator = 
 -                               dynamic_cast<const ModelAPI_ShapeValidator*>(*aValidator);
 -      if (aShapeValidator) {
 -        DataPtr aData = myFeature->data();
 -        AttributeSelectionPtr aSelectAttr = aData->selection(attributeID());
 -        if (!aShapeValidator->isValid(myFeature, aSelectAttr, theShape)) {
 -          return false;
 -        }
 -      }
      }
    }
 +  // Check that object belongs to active document or PartSet
 +  DocumentPtr aDoc = aRes->document();
 +  SessionPtr aMgr = ModelAPI_Session::get();
 +  if (!(aDoc == aMgr->activeDocument()) && !(aDoc == aMgr->moduleDocument()))
 +    return false;
 +
 +  // Check that the result has a shape
 +  GeomShapePtr aShape = ModelAPI_Tools::shape(aRes);
 +  if (!aShape)
 +    return false;
 +
 +  // Get sub-shapes from local selection
 +  if (!aPrs.shape().IsNull()) {
 +    aShape = std::shared_ptr<GeomAPI_Shape>(new GeomAPI_Shape());
 +    aShape->setImpl(new TopoDS_Shape(aPrs.shape()));
 +  }
 +  // Check that the selection corresponds to selection type
 +  if (!acceptSubShape(aShape))
 +    return false;
 +
 +  setObject(aObject, aShape);
    return true;
 -}
 +}
 +
 +//********************************************************************
 +void ModuleBase_WidgetShapeSelector::deactivate()
 +{
 +  activateSelection(false);
 +  disconnect(myWorkshop, SIGNAL(selectionChanged()), this, SLOT(onSelectionChanged()));
 +}
index 498b83d9a65c1583aa2766838d52635d17f6e64d,0000000000000000000000000000000000000000..c3d72d272cb2997402be0256a4283f7f1e6d54d8
mode 100644,000000..100644
--- /dev/null
@@@ -1,22 -1,0 +1,22 @@@
-   data()->addAttribute(ParametersPlugin_Parameter::VARIABLE_ID(), ModelAPI_AttributeString::type());
-   data()->addAttribute(ParametersPlugin_Parameter::EXPRESSION_ID(), ModelAPI_AttributeString::type());
 +// Copyright (C) 2014-20xx CEA/DEN, EDF R&D -->
 +
 +// File:        ParametersPlugin_Parameter.cpp
 +// Created:     23 MArch 2015
 +// Author:      sbh
 +
 +#include "ParametersPlugin_Parameter.h"
 +#include <ModelAPI_AttributeString.h>
 +
 +ParametersPlugin_Parameter::ParametersPlugin_Parameter()
 +{
 +}
 +
 +void ParametersPlugin_Parameter::initAttributes()
 +{
++  data()->addAttribute(ParametersPlugin_Parameter::VARIABLE_ID(), ModelAPI_AttributeString::typeId());
++  data()->addAttribute(ParametersPlugin_Parameter::EXPRESSION_ID(), ModelAPI_AttributeString::typeId());
 +}
 +
 +void ParametersPlugin_Parameter::execute()
 +{
 +}
index bdbc48c5208fccb1cd8dc26216aa923d43269dc8,f919c05fdb09f0506ecdeae3051f5548921ddca8..486a87511a898f1940ee9577138051bf1f42774d
@@@ -46,7 -42,7 +46,8 @@@ SET(PROJECT_LIBRARIE
      ModuleBase
      Config
      GeomAPI
 +    GeomValidators
+     GeomDataAPI
      ${QT_LIBRARIES}
      ${CAS_KERNEL}
      ${CAS_SHAPE}
index f7c4ab57f0c6fde0261324b1410766d0acf8a20b,9157938f1fbb2e37928d7173ae094eb1acd5c5dd..a92364d0594b30c0c7d950c77e94bfc4995f720a
@@@ -363,10 -361,8 +363,10 @@@ void PartSet_Tools::setConstraints(Comp
        new GeomAPI_Pnt2d(theClickedX, theClickedY));
    for (; anIt != aLast; anIt++) {
      FeaturePtr aFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(*anIt);
 +    if (theFeature == aFeature)
 +      continue;
      // find the given point in the feature attributes
-     anAttiributes = aFeature->data()->attributes(GeomDataAPI_Point2D::type());
+     anAttiributes = aFeature->data()->attributes(GeomDataAPI_Point2D::typeId());
      std::list<std::shared_ptr<ModelAPI_Attribute> >::const_iterator anIt = anAttiributes.begin(),
          aLast = anAttiributes.end();
      std::shared_ptr<GeomDataAPI_Point2D> aFPoint;
index 85b0dd3eca700f983f09cbb2d8d32fabdfe70932,f92793f71974c2e9f34d9cf8274ec30226d99a28..0e2ca6f20592abd11060e753f01e1273f1cf504a
@@@ -113,54 -110,86 +113,132 @@@ bool PartSet_RigidValidator::isValid(co
    return (aCount > 0) && (aCount < 2);
  }
  
 -bool PartSet_DifferentObjectsValidator::isValid(const FeaturePtr& theFeature, 
 -                                                const std::list<std::string>& theArguments,
 -                                                const ObjectPtr& theObject,
 -                                                const GeomShapePtr& theShape) const
 +bool PartSet_DifferentObjectsValidator::isValid(const AttributePtr& theAttribute, 
 +                                                const std::list<std::string>& theArguments) const
  {
 -  // Check RefAttr attributes
 -  std::list<std::shared_ptr<ModelAPI_Attribute> > anAttrs = 
 -    theFeature->data()->attributes(ModelAPI_AttributeRefAttr::typeId());
 -  if (anAttrs.size() > 0) {
 -    std::list<std::shared_ptr<ModelAPI_Attribute> >::iterator anAttr = anAttrs.begin();
 -    for(; anAttr != anAttrs.end(); anAttr++) {
 -      if (*anAttr) {
 -        std::shared_ptr<ModelAPI_AttributeRefAttr> aRef = 
 -          std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(*anAttr);
 -        // check the object is already presented
 -        if (aRef->isObject() && aRef->object() == theObject)
 -          return false;
 -      }
 +  FeaturePtr aFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(theAttribute->owner());
 +
 +  // 1. check whether the object of the attribute is not among the feature attributes
 +  // find the attribute's object
 +  ObjectPtr anObject =  GeomValidators_Tools::getObject(theAttribute);
 +
 +  // check whether the object is not among other feature attributes
 +  if (anObject.get() != NULL) {
 +    // Check RefAttr attributes
 +    std::list<std::shared_ptr<ModelAPI_Attribute> > anAttrs = aFeature->data()->attributes("");
 +    //if (anAttrs.size() > 0) {
 +    std::list<std::shared_ptr<ModelAPI_Attribute> >::iterator anIt = anAttrs.begin();
 +    for(; anIt != anAttrs.end(); anIt++) {
 +      AttributePtr anAttr = *anIt;
 +      // the function parameter attribute should be skipped
 +      if (anAttr.get() == NULL || anAttr->id() == theAttribute->id())
 +        continue;
 +      ObjectPtr aCurObject =  GeomValidators_Tools::getObject(anAttr);
 +      if (aCurObject  && aCurObject == anObject)
 +        return false;
      }
    }
 -  // Check selection attributes
 -  anAttrs = theFeature->data()->attributes(ModelAPI_AttributeSelection::typeId());
 -  if (anAttrs.size() > 0) {
 -    std::list<std::shared_ptr<ModelAPI_Attribute> >::iterator anAttr = anAttrs.begin();
 -    for(; anAttr != anAttrs.end(); anAttr++) {
 -      if (*anAttr) {
 -        std::shared_ptr<ModelAPI_AttributeSelection> aRef = 
 -          std::dynamic_pointer_cast<ModelAPI_AttributeSelection>(*anAttr);
 -        // check the object is already presented
 -        if (aRef->isInitialized() && aRef->context() == theObject) {
 -          if (theShape.get() != NULL) {
 -            if (aRef->value()->isEqual(theShape))
 -              return false;
 -          } else
 +  else {
 +    // 2. collect object referenced by theAttribute and ...
 +    if (featureHasReferences(theAttribute)) {
 +      // 3. check whether the attribute value is not among other feature attributes
 +      std::list<std::shared_ptr<ModelAPI_Attribute> > anAttrs = 
-         aFeature->data()->attributes(ModelAPI_AttributeRefAttr::type());
++        aFeature->data()->attributes(ModelAPI_AttributeRefAttr::typeId());
 +      std::list<std::shared_ptr<ModelAPI_Attribute> >::iterator anAttr = anAttrs.begin();
 +      for(; anAttr != anAttrs.end(); anAttr++) {
 +        if (*anAttr) {
 +          std::shared_ptr<ModelAPI_AttributeRefAttr> aRef = 
 +            std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(*anAttr);
 +          // check the object is already presented
 +          if (!aRef->isObject() && aRef->attr() == theAttribute)
              return false;
          }
++// TODO(nds) v1.0.2 master
++//bool PartSet_DifferentObjectsValidator::isValid(const FeaturePtr& theFeature,
++//                                                const std::list<std::string>& theArguments,
++//                                                const ObjectPtr& theObject,
++//                                                const GeomShapePtr& theShape) const
++//{
++//  // Check RefAttr attributes
++//  std::list<std::shared_ptr<ModelAPI_Attribute> > anAttrs =
++//    theFeature->data()->attributes(ModelAPI_AttributeRefAttr::typeId());
++//  if (anAttrs.size() > 0) {
++//    std::list<std::shared_ptr<ModelAPI_Attribute> >::iterator anAttr = anAttrs.begin();
++//    for(; anAttr != anAttrs.end(); anAttr++) {
++//      if (*anAttr) {
++//        std::shared_ptr<ModelAPI_AttributeRefAttr> aRef =
++//          std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(*anAttr);
++//        // check the object is already presented
++//        if (aRef->isObject() && aRef->object() == theObject)
++//          return false;
++//      }
++//    }
++//  }
++//  // Check selection attributes
++//  anAttrs = theFeature->data()->attributes(ModelAPI_AttributeSelection::typeId());
++//  if (anAttrs.size() > 0) {
++//    std::list<std::shared_ptr<ModelAPI_Attribute> >::iterator anAttr = anAttrs.begin();
++//    for(; anAttr != anAttrs.end(); anAttr++) {
++//      if (*anAttr) {
++//        std::shared_ptr<ModelAPI_AttributeSelection> aRef =
++//          std::dynamic_pointer_cast<ModelAPI_AttributeSelection>(*anAttr);
++//        // check the object is already presented
++//        if (aRef->isInitialized() && aRef->context() == theObject) {
++//          if (theShape.get() != NULL) {
++//            if (aRef->value()->isEqual(theShape))
++//              return false;
++//          } else
++//            return false;
++//        }
++//      }
++//    }
++//  }
++//  // Check selection attributes
++//  anAttrs = theFeature->data()->attributes(ModelAPI_AttributeReference::typeId());
++//  if (anAttrs.size() > 0) {
++//    std::list<std::shared_ptr<ModelAPI_Attribute> >::iterator anAttr = anAttrs.begin();
++//    for(; anAttr != anAttrs.end(); anAttr++) {
++//      if (*anAttr) {
++//        std::shared_ptr<ModelAPI_AttributeReference> aRef =
++//          std::dynamic_pointer_cast<ModelAPI_AttributeReference>(*anAttr);
++//        // check the object is already presented
++//        if (aRef->isInitialized() && aRef->value() == theObject)
++//          return false;
++// ======= end of todo
        }
 -    }
 -  }
 -  // Check selection attributes
 -  anAttrs = theFeature->data()->attributes(ModelAPI_AttributeReference::typeId());
 -  if (anAttrs.size() > 0) {
 -    std::list<std::shared_ptr<ModelAPI_Attribute> >::iterator anAttr = anAttrs.begin();
 -    for(; anAttr != anAttrs.end(); anAttr++) {
 -      if (*anAttr) {
 -        std::shared_ptr<ModelAPI_AttributeReference> aRef = 
 -          std::dynamic_pointer_cast<ModelAPI_AttributeReference>(*anAttr);
 -        // check the object is already presented
 -        if (aRef->isInitialized() && aRef->value() == theObject)
 -          return false;
 -      }
 +      return true;
      }
    }
    return true;
  }
  
 -bool PartSet_DifferentObjectsValidator::isValid(const FeaturePtr& theFeature, 
 -                                                const std::list<std::string>& theArguments,
 -                                                const AttributePtr& theAttribute) const
 -{
 -  if (PartSet_DifferentObjectsValidator::isValid(theAttribute, theArguments)) {
 -    std::list<std::shared_ptr<ModelAPI_Attribute> > anAttrs = 
 -      theFeature->data()->attributes(ModelAPI_AttributeRefAttr::typeId());
 -    std::list<std::shared_ptr<ModelAPI_Attribute> >::iterator anAttr = anAttrs.begin();
 -    for(; anAttr != anAttrs.end(); anAttr++) {
 -      if (*anAttr) {
 -        std::shared_ptr<ModelAPI_AttributeRefAttr> aRef = 
 -          std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(*anAttr);
 -        // check the object is already presented
 -        if (!aRef->isObject() && aRef->attr() == theAttribute)
 -          return false;
 -      }
 -    }
 -    return true;
 -  }
 -  return false;
 -}
 -
 -bool PartSet_DifferentObjectsValidator::isValid(const AttributePtr& theAttribute, 
 -                                                const std::list<std::string>& theArguments) const
 +bool PartSet_DifferentObjectsValidator::featureHasReferences(const AttributePtr& theAttribute) const
++// TODO(nds) v1.0.2 master
++//bool PartSet_DifferentObjectsValidator::isValid(const FeaturePtr& theFeature,
++//                                                const std::list<std::string>& theArguments,
++//                                                const AttributePtr& theAttribute) const
++//{
++//  if (PartSet_DifferentObjectsValidator::isValid(theAttribute, theArguments)) {
++//    std::list<std::shared_ptr<ModelAPI_Attribute> > anAttrs =
++//      theFeature->data()->attributes(ModelAPI_AttributeRefAttr::typeId());
++//    std::list<std::shared_ptr<ModelAPI_Attribute> >::iterator anAttr = anAttrs.begin();
++//    for(; anAttr != anAttrs.end(); anAttr++) {
++//      if (*anAttr) {
++//        std::shared_ptr<ModelAPI_AttributeRefAttr> aRef =
++//          std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(*anAttr);
++//        // check the object is already presented
++//        if (!aRef->isObject() && aRef->attr() == theAttribute)
++//          return false;
++//      }
++//    }
++//    return true;
++//  }
++//  return false;
++//}
++//
++//bool PartSet_DifferentObjectsValidator::isValid(const AttributePtr& theAttribute,
++//                                                const std::list<std::string>& theArguments) const
++// ======= end of todo
  {
    std::list<std::pair<std::string, std::list<ObjectPtr> > > allRefs;
    if (theAttribute->owner().get() && theAttribute->owner()->data().get())
    return true;
  }
  
 -bool PartSet_SketchValidator::isValid(const ObjectPtr theObject) const
 +bool PartSet_SketchEntityValidator::isValid(const AttributePtr& theAttribute,
 +                                            const std::list<std::string>& theArguments) const
  {
 -  FeaturePtr aFeature = ModelAPI_Feature::feature(theObject);
 -  return aFeature->getKind() == SketchPlugin_Sketch::ID();
 +  bool isSketchEntities = true;
 +  std::set<std::string> anEntityKinds;
 +  std::list<std::string>::const_iterator anIt = theArguments.begin(), aLast = theArguments.end();
 +  for (; anIt != aLast; anIt++) {
 +    anEntityKinds.insert(*anIt);
 +  }
 +
 +  std::string anAttributeType = theAttribute->attributeType();
-   if (anAttributeType == ModelAPI_AttributeSelectionList::type()) {
++  if (anAttributeType == ModelAPI_AttributeSelectionList::typeId()) {
 +    AttributeSelectionListPtr aSelectionListAttr = 
 +                      std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(theAttribute);
 +    // it filters only selection list attributes
 +    std::string aType = aSelectionListAttr->selectionType().c_str();
 +    // all context objects should be sketch entities
 +    int aSize = aSelectionListAttr->size();
 +    for (int i = 0; i < aSelectionListAttr->size() && isSketchEntities; i++) {
 +      AttributeSelectionPtr aSelectAttr = aSelectionListAttr->value(i);
 +      ObjectPtr anObject = aSelectAttr->context();
 +      FeaturePtr aFeature = ModelAPI_Feature::feature(anObject);
 +      isSketchEntities = anEntityKinds.find(aFeature->getKind()) != anEntityKinds.end();
 +    }
 +  }
-   if (anAttributeType == ModelAPI_AttributeRefAttr::type()) {
++  if (anAttributeType == ModelAPI_AttributeRefAttr::typeId()) {
 +    std::shared_ptr<ModelAPI_AttributeRefAttr> aRef = 
 +                     std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(theAttribute);
 +    isSketchEntities = false;
 +    if (aRef->isObject()) {
 +      ObjectPtr anObject = aRef->object();
 +      if (anObject.get() != NULL) {
 +        FeaturePtr aFeature = ModelAPI_Feature::feature(anObject);
 +        if (aFeature.get() != NULL)
 +          isSketchEntities = anEntityKinds.find(aFeature->getKind()) != anEntityKinds.end();
 +      }
 +    }
 +  }
 +
 +  return isSketchEntities;
  }
index 389cc4fa20def49b2048b0aa4707063d680465a1,6c3fc1897c330b743e04e3b79466b9f06c3233f3..02e73de5fd0308875f827dcb3d1c4a14dd1ffdca
@@@ -69,9 -70,24 +69,25 @@@ class PartSet_RigidValidator : public M
  * \ingroup Validators
  * A validator which checks that objects selected for feature attributes are different (not the same)
  */
 -class PartSet_DifferentObjectsValidator : public ModelAPI_RefAttrValidator
 +class PartSet_DifferentObjectsValidator : public ModelAPI_AttributeValidator
  {
   public:
 -   /// Returns True if the feature is valid
 -   /// \param theFeature a feature to check
 -   /// \param theArguments a list of arguments (names of attributes to check)
 -   /// \param theObject a selected object
 -   /// \param theShape a selected sub-shape
 -  virtual bool isValid(const FeaturePtr& theFeature, const std::list<std::string>& theArguments,
 -                       const ObjectPtr& theObject, const GeomShapePtr& theShape) const;
 -
 -  //! Returns true if the attribute is good for the feature attribute
 -  //! \param theFeature a feature to check
 -  //! \param theArguments a list of arguments (names of attributes to check)
 -  //! \param theAttribute an attribute
 -  virtual bool isValid(const FeaturePtr& theFeature, const std::list<std::string>& theArguments,
 -                       const AttributePtr& theAttribute) const;
 -
++// TODO(nds) v1.0.2 master
++//   /// Returns True if the feature is valid
++//   /// \param theFeature a feature to check
++//   /// \param theArguments a list of arguments (names of attributes to check)
++//   /// \param theObject a selected object
++//   /// \param theShape a selected sub-shape
++//  virtual bool isValid(const FeaturePtr& theFeature, const std::list<std::string>& theArguments,
++//                       const ObjectPtr& theObject, const GeomShapePtr& theShape) const;
++//
++//  //! Returns true if the attribute is good for the feature attribute
++//  //! \param theFeature a feature to check
++//  //! \param theArguments a list of arguments (names of attributes to check)
++//  //! \param theAttribute an attribute
++//  virtual bool isValid(const FeaturePtr& theFeature, const std::list<std::string>& theArguments,
++//                       const AttributePtr& theAttribute) const;
++  // ======= end of todo
    //! Returns true if the attribute is good for the feature attribute
    //! \param theAttribute an attribute
    //! \param theArguments a list of arguments (names of attributes to check)
@@@ -92,16 -97,15 +108,16 @@@ protected
  
  /**
  * \ingroup Validators
 -* A Validator which validates tha selected object is a Sketch
 +* A validator which checks that objects selected for feature attributes are different (not the same)
  */
 -class PartSet_SketchValidator : public ModelAPI_ResultValidator
 +class PartSet_SketchEntityValidator : public ModelAPI_AttributeValidator
  {
   public:
 -   /// Returns True if the given object is a sketch
 -   /// \param theObject an object
 -  virtual bool isValid(const ObjectPtr theObject) const;
 +  //! Returns true if the attribute is good for the feature attribute
 +  //! \param theAttribute an attribute
 +  //! \param theArguments a list of arguments (names of attributes to check)
 +  virtual bool isValid(const AttributePtr& theAttribute,
 +                       const std::list<std::string>& theArguments) const;
  };
  
- #endif
 -
+ #endif
index 578e1cdf9b7a7e7bc38d7919e96ce9d038635bd2,d0b1f8bc1a6abcd85d2c2066d93b70d727fedbb9..98c25d47b1dc4eda49d7e3e2af954673bc2ad324
@@@ -77,52 -63,84 +77,86 @@@ bool PartSet_WidgetShapeSelector::setOb
  }
  
  //********************************************************************
 -bool PartSet_WidgetShapeSelector::isValid(ObjectPtr theObj, std::shared_ptr<GeomAPI_Shape> theShape)
 +void PartSet_WidgetShapeSelector::storeAttributeValue()
  {
 -  // the method is redefined to analize the selected shape in validators
 -  SessionPtr aMgr = ModelAPI_Session::get();
 -  ModelAPI_ValidatorsFactory* aFactory = aMgr->validators();
 -  std::list<ModelAPI_Validator*> aValidators;
 -  std::list<std::list<std::string> > anArguments;
 -  aFactory->validators(parentID(), attributeID(), aValidators, anArguments);
 +  /// this is a temporary code, will be removed when master is merged to this branch
 +  /*XGUI_ModuleConnector* aConnector = dynamic_cast<XGUI_ModuleConnector*>(myWorkshop);
 +  XGUI_Workshop* aWorkshop = aConnector->workshop();
 +  aWorkshop->displayer()->enableUpdateViewer(false);
 +  */
 +  ModuleBase_WidgetShapeSelector::storeAttributeValue();
 +}
  
 -  // Check the type of selected object
 -  std::list<ModelAPI_Validator*>::iterator aValidator = aValidators.begin();
 -  bool isValid = true;
 -  for (; aValidator != aValidators.end(); aValidator++) {
 -    const ModelAPI_ResultValidator* aResValidator =
 -        dynamic_cast<const ModelAPI_ResultValidator*>(*aValidator);
 -    if (aResValidator) {
 -      isValid = false;
 -      if (aResValidator->isValid(theObj)) {
 -        isValid = true;
 -        break;
 -      }
 -    }
 -  }
 -  if (!isValid)
 -    return false;
 +//********************************************************************
 +void PartSet_WidgetShapeSelector::restoreAttributeValue(const bool theValid)
 +{
 +  ModuleBase_WidgetShapeSelector::restoreAttributeValue(theValid);
 +  /// this is a temporary code, will be removed when master is merged to this branch
 +  /// after merge, the external edge should be removed always, without flag checking
 +  if (!theValid)
 +    removeExternal();
 +  /*
 +  XGUI_ModuleConnector* aConnector = dynamic_cast<XGUI_ModuleConnector*>(myWorkshop);
 +  XGUI_Workshop* aWorkshop = aConnector->workshop();
 +  aWorkshop->displayer()->enableUpdateViewer(false);//->erase(myExternalObject);
 +  aWorkshop->displayer()->enableUpdateViewer(true);*/
 +}
  
 -  // Check the acceptability of the object and shape as validator attribute
 -  AttributePtr aPntAttr;
 -  DataPtr aData = myFeature->data();
 -  if (theShape.get() != NULL) {
 -    AttributePtr aAttr = aData->attribute(attributeID());
 -    AttributeRefAttrPtr aRefAttr = 
 -      std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(aAttr);
 -    if (aRefAttr) {
 -      TopoDS_Shape aShape = theShape->impl<TopoDS_Shape>();
 -      aPntAttr = PartSet_Tools::findAttributeBy2dPoint(theObj, aShape, mySketch);
 -    }
 -  }
 -  // Check the acceptability of the object as attribute
 -  aValidator = aValidators.begin();
 -  std::list<std::list<std::string> >::iterator aArgs = anArguments.begin();
 -  for (; aValidator != aValidators.end(); aValidator++, aArgs++) {
 -    const ModelAPI_RefAttrValidator* aAttrValidator =
 -        dynamic_cast<const ModelAPI_RefAttrValidator*>(*aValidator);
 -    if (aAttrValidator) {
 -      if (aPntAttr.get() != NULL)
 -      {
 -        if (!aAttrValidator->isValid(myFeature, *aArgs, aPntAttr)) {
 -          return false;
 -        }
 -      }
 -      else
 -      {
 -        if (!aAttrValidator->isValid(myFeature, *aArgs, theObj, theShape)) {
 -          return false;
 -        }
 -      }
 -    }
 +//********************************************************************
 +void PartSet_WidgetShapeSelector::createExternal(ObjectPtr theSelectedObject,
 +                                                 GeomShapePtr theShape)
 +{
 +  ObjectPtr aObj = PartSet_Tools::createFixedObjectByExternal(theShape->impl<TopoDS_Shape>(),
 +                                                              theSelectedObject, mySketch);
 +  if (aObj != myExternalObject) {
 +    removeExternal();
 +    myExternalObject = aObj;
++// TODO(nds) v1.0.2 master
++//  // Check the acceptability of the object and shape as validator attribute
++//  AttributePtr aPntAttr;
++//  DataPtr aData = myFeature->data();
++//  if (theShape.get() != NULL) {
++//    AttributePtr aAttr = aData->attribute(attributeID());
++//    AttributeRefAttrPtr aRefAttr =
++//      std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(aAttr);
++//    if (aRefAttr) {
++//      TopoDS_Shape aShape = theShape->impl<TopoDS_Shape>();
++//      aPntAttr = PartSet_Tools::findAttributeBy2dPoint(theObj, aShape, mySketch);
++//    }
++//  }
++//  // Check the acceptability of the object as attribute
++//  aValidator = aValidators.begin();
++//  std::list<std::list<std::string> >::iterator aArgs = anArguments.begin();
++//  for (; aValidator != aValidators.end(); aValidator++, aArgs++) {
++//    const ModelAPI_RefAttrValidator* aAttrValidator =
++//        dynamic_cast<const ModelAPI_RefAttrValidator*>(*aValidator);
++//    if (aAttrValidator) {
++//      if (aPntAttr.get() != NULL)
++//      {
++//        if (!aAttrValidator->isValid(myFeature, *aArgs, aPntAttr)) {
++//          return false;
++//        }
++//      }
++//      else
++//      {
++//        if (!aAttrValidator->isValid(myFeature, *aArgs, theObj, theShape)) {
++//          return false;
++//        }
++//      }
++//    }
++// ======= end of todo
    }
 -  return true;
  }
  
 -//*********************************************
 -bool PartSet_WidgetConstraintShapeSelector::storeValue() const
 +//********************************************************************
 +void PartSet_WidgetShapeSelector::removeExternal()
  {
 -  FeaturePtr aFeature = ModelAPI_Feature::feature(mySelectedObject);
 -  if (aFeature) {
 -    std::shared_ptr<SketchPlugin_Feature> aSPFeature = 
 -            std::dynamic_pointer_cast<SketchPlugin_Feature>(aFeature);
 -    if ((!aSPFeature) && (!myShape->isNull())) {
 -      ObjectPtr aObj = PartSet_Tools::createFixedObjectByEdge(myShape->impl<TopoDS_Shape>(),
 -                                                              mySelectedObject, mySketch);
 -      if (aObj) {
 -        PartSet_WidgetConstraintShapeSelector* that = (PartSet_WidgetConstraintShapeSelector*) this;
 -        that->mySelectedObject = aObj;
 -      } else 
 -        return false;
 +  if (myExternalObject.get()) {
 +    DocumentPtr aDoc = myExternalObject->document();
 +    FeaturePtr aFeature = ModelAPI_Feature::feature(myExternalObject);
 +    if (aFeature.get() != NULL) {
 +      aDoc->removeFeature(aFeature);
      }
 +    myExternalObject = NULL;
    }
 -  return ModuleBase_WidgetShapeSelector::storeValue();
  }
index 22ce7d27eda3dce82e05a8039a73bad2c22198c1,9d14f6b4c09a609f4f570e8f6d764d2288849f0d..d6a7d77ac49a5281895e779b9bdd02dc6aa26e6f
@@@ -63,9 -49,8 +63,10 @@@ SET(PROJECT_LIBRARIE
      Config
      GeomAPI
      GeomAlgoAPI
 +    GeomValidators
      ModelAPI
 +    SketcherPrs
+     GeomDataAPI
      ${CAS_KERNEL}
      ${CAS_SHAPE}
  )
index 27e3512ba0271294e165b54cf2566b7366146b82,6295057977b2fc058736979d944cdfb1f3797114..026266a30d164a160208039d0a0c8c3f809d50fe
@@@ -31,12 -31,10 +31,12 @@@ SketchPlugin_Arc::SketchPlugin_Arc(
  
  void SketchPlugin_Arc::initAttributes()
  {
-   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());
 +  SketchPlugin_SketchEntity::initAttributes();
 +
+   data()->addAttribute(CENTER_ID(), GeomDataAPI_Point2D::typeId());
+   data()->addAttribute(START_ID(), GeomDataAPI_Point2D::typeId());
+   data()->addAttribute(END_ID(), GeomDataAPI_Point2D::typeId());
+   data()->addAttribute(EXTERNAL_ID(), ModelAPI_AttributeSelection::typeId());
    ModelAPI_Session::get()->validators()->registerNotObligatory(getKind(), EXTERNAL_ID());
  }
  
index 934f40a04eb331cf8a0fb0a37ba044140e29b9c7,c92948bd2d711ad4081b2c06e0a218d2f6fc0114..623b6c62549757eaf2b35f54ff9ddb38437baebf
@@@ -28,11 -28,9 +28,11 @@@ SketchPlugin_Circle::SketchPlugin_Circl
  
  void SketchPlugin_Circle::initAttributes()
  {
-   data()->addAttribute(CENTER_ID(), GeomDataAPI_Point2D::type());
-   data()->addAttribute(RADIUS_ID(), ModelAPI_AttributeDouble::type());
-   data()->addAttribute(EXTERNAL_ID(), ModelAPI_AttributeSelection::type());
 +  SketchPlugin_SketchEntity::initAttributes();
 +
+   data()->addAttribute(CENTER_ID(), GeomDataAPI_Point2D::typeId());
+   data()->addAttribute(RADIUS_ID(), ModelAPI_AttributeDouble::typeId());
+   data()->addAttribute(EXTERNAL_ID(), ModelAPI_AttributeSelection::typeId());
    ModelAPI_Session::get()->validators()->registerNotObligatory(getKind(), EXTERNAL_ID());
  }
  
index 358158325fc9b4da8f49f9a60ca6efae1e14a66c,02cf66ca06415735860e72076d76f67c2a3f8f03..a78e1b4efc2d0b7b0aeddfc959586679345ecb63
@@@ -28,15 -24,3 +28,15 @@@ void SketchPlugin_ConstraintCoincidence
  {
  }
  
- }
 +AISObjectPtr SketchPlugin_ConstraintCoincidence::getAISObject(AISObjectPtr thePrevious)
 +{
 +  if (!sketch())
 +    return thePrevious;
 +
 +  AISObjectPtr anAIS = thePrevious;
 +  if (!anAIS) {
 +    anAIS = SketcherPrs_Factory::coincidentConstraint(this, sketch()->coordinatePlane());
 +    anAIS->setColor(0, 0, 255);
 +  }
 +  return anAIS;
++}
index efd034fea2ce18faa18d74b64d1790ef13b68e69,0000000000000000000000000000000000000000..1b80c0c6b050e16088bea1b496c263716c60a5f0
mode 100644,000000..100644
--- /dev/null
@@@ -1,46 -1,0 +1,46 @@@
-   data()->addAttribute(SketchPlugin_Constraint::ENTITY_A(), ModelAPI_AttributeRefAttr::type());
-   data()->addAttribute(SketchPlugin_Constraint::ENTITY_B(), ModelAPI_AttributeRefAttr::type());
 +// Copyright (C) 2014-20xx CEA/DEN, EDF R&D -->
 +
 +// File:    SketchPlugin_ConstraintEqual.cpp
 +// Created: 16 Mar 2015
 +// Author:  Artem ZHIDKOV
 +
 +#include "SketchPlugin_ConstraintEqual.h"
 +
 +#include <ModelAPI_AttributeDouble.h>
 +#include <ModelAPI_Data.h>
 +#include <ModelAPI_ResultConstruction.h>
 +
 +#include <SketchPlugin_Line.h>
 +#include <SketchPlugin_Sketch.h>
 +
 +#include <SketcherPrs_Factory.h>
 +
 +#include <Config_PropManager.h>
 +
 +SketchPlugin_ConstraintEqual::SketchPlugin_ConstraintEqual()
 +{
 +}
 +
 +void SketchPlugin_ConstraintEqual::initAttributes()
 +{
++  data()->addAttribute(SketchPlugin_Constraint::ENTITY_A(), ModelAPI_AttributeRefAttr::typeId());
++  data()->addAttribute(SketchPlugin_Constraint::ENTITY_B(), ModelAPI_AttributeRefAttr::typeId());
 +}
 +
 +void SketchPlugin_ConstraintEqual::execute()
 +{
 +}
 +
 +AISObjectPtr SketchPlugin_ConstraintEqual::getAISObject(AISObjectPtr thePrevious)
 +{
 +  if (!sketch())
 +    return thePrevious;
 +
 +  AISObjectPtr anAIS = thePrevious;
 +  if (!anAIS) {
 +    anAIS = SketcherPrs_Factory::equalConstraint(this, sketch()->coordinatePlane());
 +  }
 +  return anAIS;
 +}
 +
 +
index 4b7b4cff7319ffad820915122ee8e1764e03cf00,0000000000000000000000000000000000000000..22bc2541a224c8f24f04ab4ae12f7a39a0483d2a
mode 100644,000000..100644
--- /dev/null
@@@ -1,91 -1,0 +1,91 @@@
-   data()->addAttribute(SketchPlugin_Constraint::VALUE(), ModelAPI_AttributeDouble::type());
-   data()->addAttribute(SketchPlugin_Constraint::ENTITY_A(), ModelAPI_AttributeRefAttr::type());
-   data()->addAttribute(SketchPlugin_Constraint::ENTITY_B(), ModelAPI_AttributeRefAttr::type());
-   data()->addAttribute(SketchPlugin_Constraint::ENTITY_C(), ModelAPI_AttributeRefList::type());
 +// Copyright (C) 2014-20xx CEA/DEN, EDF R&D -->
 +
 +// File:    SketchPlugin_ConstraintFillet.cpp
 +// Created: 19 Mar 2015
 +// Author:  Artem ZHIDKOV
 +
 +#include "SketchPlugin_ConstraintFillet.h"
 +
 +#include <ModelAPI_AttributeDouble.h>
 +#include <ModelAPI_Data.h>
 +#include <ModelAPI_ResultConstruction.h>
 +#include <ModelAPI_AttributeRefAttr.h>
 +#include <ModelAPI_AttributeRefList.h>
 +#include <ModelAPI_Session.h>
 +
 +#include <SketchPlugin_Arc.h>
 +#include <SketchPlugin_Sketch.h>
 +
 +#include <SketcherPrs_Factory.h>
 +
 +#include <Config_PropManager.h>
 +
 +SketchPlugin_ConstraintFillet::SketchPlugin_ConstraintFillet()
 +{
 +}
 +
 +void SketchPlugin_ConstraintFillet::initAttributes()
 +{
++  data()->addAttribute(SketchPlugin_Constraint::VALUE(), ModelAPI_AttributeDouble::typeId());
++  data()->addAttribute(SketchPlugin_Constraint::ENTITY_A(), ModelAPI_AttributeRefAttr::typeId());
++  data()->addAttribute(SketchPlugin_Constraint::ENTITY_B(), ModelAPI_AttributeRefAttr::typeId());
++  data()->addAttribute(SketchPlugin_Constraint::ENTITY_C(), ModelAPI_AttributeRefList::typeId());
 +  // initialize attribute not applicable for user
 +  data()->attribute(SketchPlugin_Constraint::ENTITY_C())->setInitialized();
 +}
 +
 +void SketchPlugin_ConstraintFillet::execute()
 +{
 +  std::shared_ptr<ModelAPI_Data> aData = data();
 +  // Check the base objects are initialized
 +  AttributeRefAttrPtr aBaseA = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(
 +      aData->attribute(SketchPlugin_Constraint::ENTITY_A()));
 +  AttributeRefAttrPtr aBaseB = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(
 +      aData->attribute(SketchPlugin_Constraint::ENTITY_B()));
 +  if (!aBaseA->isInitialized() || !aBaseB->isInitialized() ||
 +      !aBaseA->isObject() || !aBaseB->isObject())
 +    return;
 +  // Check the fillet shapes is not initialized yet
 +  AttributeRefListPtr aRefListOfFillet = std::dynamic_pointer_cast<ModelAPI_AttributeRefList>(
 +      aData->attribute(SketchPlugin_Constraint::ENTITY_C()));
 +  if (aRefListOfFillet->size() > 0)
 +    return;
 +  // Obtain features for the base objects
 +  FeaturePtr aFeatureA, aFeatureB;
 +  ResultConstructionPtr aRC =
 +      std::dynamic_pointer_cast<ModelAPI_ResultConstruction>(aBaseA->object());
 +  if (aRC) aFeatureA = aRC->document()->feature(aRC);
 +  aRC = std::dynamic_pointer_cast<ModelAPI_ResultConstruction>(aBaseB->object());
 +  if (aRC) aFeatureB = aRC->document()->feature(aRC);
 +  if (!aFeatureA || !aFeatureB)
 +    return;
 +
 +  // Create list of objects composing a fillet
 +  // copy aFeatureA
 +  FeaturePtr aNewFeature = sketch()->addFeature(aFeatureA->getKind());
 +  aFeatureA->data()->copyTo(aNewFeature->data());
 +  aRefListOfFillet->append(aNewFeature);
 +  // copy aFeatureB
 +  aNewFeature = sketch()->addFeature(aFeatureB->getKind());
 +  aFeatureB->data()->copyTo(aNewFeature->data());
 +  aRefListOfFillet->append(aNewFeature);
 +  // create filleting arc
 +  aNewFeature = sketch()->addFeature(SketchPlugin_Arc::ID());
 +  aNewFeature->attribute(SketchPlugin_Arc::CENTER_ID())->setInitialized();
 +  aNewFeature->attribute(SketchPlugin_Arc::START_ID())->setInitialized();
 +  aNewFeature->attribute(SketchPlugin_Arc::END_ID())->setInitialized();
 +  aRefListOfFillet->append(aNewFeature);
 +  aRefListOfFillet->setInitialized();
 +}
 +
 +AISObjectPtr SketchPlugin_ConstraintFillet::getAISObject(AISObjectPtr thePrevious)
 +{
 +  if (!sketch())
 +    return thePrevious;
 +
 +  AISObjectPtr anAIS = thePrevious;
 +  /// TODO: Equal constraint presentation should be put here
 +  return anAIS;
 +}
 +
 +
index 175715d28afd30f5f4a3694d6aa942753a81895c,0000000000000000000000000000000000000000..9fe7e5188793955e98975860a063f0acaf706abf
mode 100644,000000..100644
--- /dev/null
@@@ -1,45 -1,0 +1,45 @@@
-   data()->addAttribute(SketchPlugin_Constraint::ENTITY_A(), ModelAPI_AttributeRefAttr::type());
 +// Copyright (C) 2014-20xx CEA/DEN, EDF R&D -->
 +
 +// File:    SketchPlugin_ConstraintHorizontal.cpp
 +// Created: 16 Mar 2015
 +// Author:  Artem ZHIDKOV
 +
 +#include "SketchPlugin_ConstraintHorizontal.h"
 +
 +#include <ModelAPI_AttributeDouble.h>
 +#include <ModelAPI_Data.h>
 +#include <ModelAPI_ResultConstruction.h>
 +
 +#include <SketchPlugin_Line.h>
 +#include <SketchPlugin_Sketch.h>
 +
 +#include <SketcherPrs_Factory.h>
 +
 +#include <Config_PropManager.h>
 +
 +SketchPlugin_ConstraintHorizontal::SketchPlugin_ConstraintHorizontal()
 +{
 +}
 +
 +void SketchPlugin_ConstraintHorizontal::initAttributes()
 +{
++  data()->addAttribute(SketchPlugin_Constraint::ENTITY_A(), ModelAPI_AttributeRefAttr::typeId());
 +}
 +
 +void SketchPlugin_ConstraintHorizontal::execute()
 +{
 +}
 +
 +AISObjectPtr SketchPlugin_ConstraintHorizontal::getAISObject(AISObjectPtr thePrevious)
 +{
 +  if (!sketch())
 +    return thePrevious;
 +
 +  AISObjectPtr anAIS = thePrevious;
 +  if (!anAIS) {
 +    anAIS = SketcherPrs_Factory::horisontalConstraint(this, sketch()->coordinatePlane());
 +  }
 +  return anAIS;
 +}
 +
 +
index 8479e107da7c3563772defdd61145c6b9c977d3b,0000000000000000000000000000000000000000..f0da5515fa7a63ee32484a78dcfb5d5f2437f3bd
mode 100644,000000..100644
--- /dev/null
@@@ -1,113 -1,0 +1,113 @@@
-   data()->addAttribute(SketchPlugin_Constraint::ENTITY_A(), ModelAPI_AttributeRefAttr::type());
-   data()->addAttribute(SketchPlugin_Constraint::ENTITY_B(), ModelAPI_AttributeRefList::type());
-   data()->addAttribute(SketchPlugin_Constraint::ENTITY_C(), ModelAPI_AttributeRefList::type());
 +// Copyright (C) 2014-20xx CEA/DEN, EDF R&D -->
 +
 +// File:    SketchPlugin_ConstraintMirror.cpp
 +// Created: 17 Mar 2015
 +// Author:  Artem ZHIDKOV
 +
 +#include "SketchPlugin_ConstraintMirror.h"
 +
 +#include <ModelAPI_AttributeDouble.h>
 +#include <ModelAPI_Data.h>
 +#include <ModelAPI_ResultConstruction.h>
 +#include <ModelAPI_AttributeRefList.h>
 +#include <ModelAPI_Session.h>
 +
 +#include <SketchPlugin_Line.h>
 +#include <SketchPlugin_Sketch.h>
 +
 +#include <SketcherPrs_Factory.h>
 +
 +#include <Config_PropManager.h>
 +
 +SketchPlugin_ConstraintMirror::SketchPlugin_ConstraintMirror()
 +{
 +}
 +
 +void SketchPlugin_ConstraintMirror::initAttributes()
 +{
++  data()->addAttribute(SketchPlugin_Constraint::ENTITY_A(), ModelAPI_AttributeRefAttr::typeId());
++  data()->addAttribute(SketchPlugin_Constraint::ENTITY_B(), ModelAPI_AttributeRefList::typeId());
++  data()->addAttribute(SketchPlugin_Constraint::ENTITY_C(), ModelAPI_AttributeRefList::typeId());
 +}
 +
 +void SketchPlugin_ConstraintMirror::execute()
 +{
 +  // Objects to be mirrored will be created here
 +  std::shared_ptr<ModelAPI_Data> aData = data();
 +  AttributeRefListPtr aRefListOfShapes = std::dynamic_pointer_cast<ModelAPI_AttributeRefList>(
 +      aData->attribute(SketchPlugin_Constraint::ENTITY_B()));
 +  if (!aRefListOfShapes->isInitialized())
 +    return ;
 +
 +  AttributeRefListPtr aRefListOfMirrored = std::dynamic_pointer_cast<ModelAPI_AttributeRefList>(
 +      aData->attribute(SketchPlugin_Constraint::ENTITY_C()));
 +  // Check consistency of initial list and mirrored list
 +  std::list<ObjectPtr> anInitialList =  aRefListOfShapes->list();
 +  std::list<ObjectPtr> aMirroredList =  aRefListOfMirrored->list();
 +  std::list<ObjectPtr>::iterator anInitIter = anInitialList.begin();
 +  std::list<ObjectPtr>::iterator aMirrorIter = aMirroredList.begin();
 +  int indFirstWrong = 0; // index of element starts difference in the lists
 +  std::set<int> anInvalidInd; // list of indices of removed features
 +  std::shared_ptr<SketchPlugin_Feature> aFeatureIn, aFeatureOut;
 +  for ( ; anInitIter != anInitialList.end(); anInitIter++, indFirstWrong++) {
 +    // Add features and store indices of objects to remove
 +    aFeatureIn = std::dynamic_pointer_cast<SketchPlugin_Feature>(*anInitIter);
 +    aFeatureOut = aMirrorIter != aMirroredList.end() ? 
 +        std::dynamic_pointer_cast<SketchPlugin_Feature>(*aMirrorIter) :
 +        std::shared_ptr<SketchPlugin_Feature>();
 +    if (!aFeatureIn) {
 +      if (aFeatureOut)
 +        break; // the lists are inconsistent
 +      continue;
 +    }
 +    if (!aFeatureOut) {
 +      if (aMirrorIter != aMirroredList.end())
 +        break; // the lists are inconsistent
 +      // There is no mirrored object yet, create it
 +      FeaturePtr aNewFeature = sketch()->addFeature(aFeatureIn->getKind());
 +      aFeatureIn->data()->copyTo(aNewFeature->data());
 +      aRefListOfMirrored->append(aNewFeature);
 +      continue;
 +    }
 +    if (aFeatureIn->getKind() != aFeatureOut->getKind())
 +      break; // the lists are inconsistent
 +    if (!aFeatureIn->data()->isValid()) {
 +      // initial feature was removed, delete it from lists
 +      anInvalidInd.insert(indFirstWrong);
 +    }
 +    aMirrorIter++;
 +  }
 +  // Remove from the list objects already deleted before
 +  std::set<int>::reverse_iterator anIt = anInvalidInd.rbegin();
 +  for ( ; anIt != anInvalidInd.rend(); anIt++) {
 +    if (*anIt < indFirstWrong) indFirstWrong--;
 +    aRefListOfShapes->remove(aRefListOfShapes->object(*anIt));
 +    aRefListOfMirrored->remove(aRefListOfMirrored->object(*anIt));
 +  }
 +  // If the lists inconsistent, remove all objects from mirrored list starting from indFirstWrong
 +  if (anInitIter != anInitialList.end()) {
 +    while (aRefListOfMirrored->size() > indFirstWrong)
 +      aRefListOfMirrored->remove(aRefListOfMirrored->object(indFirstWrong));
 +    // Create mirrored features instead of removed
 +    anInitialList =  aRefListOfShapes->list();
 +    anInitIter = anInitialList.begin();
 +    for (int i = 0; i < indFirstWrong; i++) anInitIter++;
 +    for ( ; anInitIter != anInitialList.end(); anInitIter++) {
 +      aFeatureIn = std::dynamic_pointer_cast<SketchPlugin_Feature>(*anInitIter);
 +      FeaturePtr aNewFeature = aFeatureIn->document()->addFeature(aFeatureIn->getKind());
 +      aRefListOfMirrored->append(aNewFeature);
 +    }
 +  }
 +}
 +
 +AISObjectPtr SketchPlugin_ConstraintMirror::getAISObject(AISObjectPtr thePrevious)
 +{
 +  if (!sketch())
 +    return thePrevious;
 +
 +  AISObjectPtr anAIS = thePrevious;
 +  /// TODO: Equal constraint presentation should be put here
 +  return anAIS;
 +}
 +
 +
index 29a7f0a25c1c6da37e19c10a514b0ad0ee9687ff,f222602474584b52cc7571bbcf041bff61969307..42ce74b78572f01ad5a9af1544e639eca8544320
@@@ -29,9 -25,9 +29,9 @@@ SketchPlugin_ConstraintParallel::Sketch
  
  void SketchPlugin_ConstraintParallel::initAttributes()
  {
-   data()->addAttribute(SketchPlugin_Constraint::ENTITY_A(), ModelAPI_AttributeRefAttr::type());
-   data()->addAttribute(SketchPlugin_Constraint::ENTITY_B(), ModelAPI_AttributeRefAttr::type());
-   //data()->addAttribute(SketchPlugin_Constraint::FLYOUT_VALUE_PNT(), GeomDataAPI_Point2D::type());
+   data()->addAttribute(SketchPlugin_Constraint::ENTITY_A(), ModelAPI_AttributeRefAttr::typeId());
+   data()->addAttribute(SketchPlugin_Constraint::ENTITY_B(), ModelAPI_AttributeRefAttr::typeId());
 -  data()->addAttribute(SketchPlugin_Constraint::FLYOUT_VALUE_PNT(), GeomDataAPI_Point2D::typeId());
++  //data()->addAttribute(SketchPlugin_Constraint::FLYOUT_VALUE_PNT(), GeomDataAPI_Point2D::typeId());
  }
  
  void SketchPlugin_ConstraintParallel::execute()
index c979d8939ac74d1a45dbe903ad7a75761fa5557d,0000000000000000000000000000000000000000..9d7256c18aef20b54139ab02501caa55b4159c6e
mode 100644,000000..100644
--- /dev/null
@@@ -1,46 -1,0 +1,46 @@@
-   data()->addAttribute(SketchPlugin_Constraint::ENTITY_A(), ModelAPI_AttributeRefAttr::type());
-   data()->addAttribute(SketchPlugin_Constraint::ENTITY_B(), ModelAPI_AttributeRefAttr::type());
 +// Copyright (C) 2014-20xx CEA/DEN, EDF R&D -->
 +
 +// File:    SketchPlugin_ConstraintTangent.cpp
 +// Created: 16 Mar 2015
 +// Author:  Artem ZHIDKOV
 +
 +#include "SketchPlugin_ConstraintTangent.h"
 +
 +#include <ModelAPI_AttributeDouble.h>
 +#include <ModelAPI_Data.h>
 +#include <ModelAPI_ResultConstruction.h>
 +
 +#include <SketchPlugin_Line.h>
 +#include <SketchPlugin_Sketch.h>
 +
 +#include <SketcherPrs_Factory.h>
 +
 +#include <Config_PropManager.h>
 +
 +SketchPlugin_ConstraintTangent::SketchPlugin_ConstraintTangent()
 +{
 +}
 +
 +void SketchPlugin_ConstraintTangent::initAttributes()
 +{
++  data()->addAttribute(SketchPlugin_Constraint::ENTITY_A(), ModelAPI_AttributeRefAttr::typeId());
++  data()->addAttribute(SketchPlugin_Constraint::ENTITY_B(), ModelAPI_AttributeRefAttr::typeId());
 +}
 +
 +void SketchPlugin_ConstraintTangent::execute()
 +{
 +}
 +
 +AISObjectPtr SketchPlugin_ConstraintTangent::getAISObject(AISObjectPtr thePrevious)
 +{
 +  if (!sketch())
 +    return thePrevious;
 +
 +  AISObjectPtr anAIS = thePrevious;
 +  if (!anAIS) {
 +    anAIS = SketcherPrs_Factory::tangentConstraint(this, sketch()->coordinatePlane());
 +  }
 +  return anAIS;
 +}
 +
 +
index bb824715ad5b91f22e6b7ac696cbdfbafd725f2c,0000000000000000000000000000000000000000..d5865e6ab3c14aafc6e2bb7da8fd13b75c992cd2
mode 100644,000000..100644
--- /dev/null
@@@ -1,45 -1,0 +1,45 @@@
-   data()->addAttribute(SketchPlugin_Constraint::ENTITY_A(), ModelAPI_AttributeRefAttr::type());
 +// Copyright (C) 2014-20xx CEA/DEN, EDF R&D -->
 +
 +// File:    SketchPlugin_ConstraintVertical.cpp
 +// Created: 16 Mar 2015
 +// Author:  Artem ZHIDKOV
 +
 +#include "SketchPlugin_ConstraintVertical.h"
 +
 +#include <ModelAPI_AttributeDouble.h>
 +#include <ModelAPI_Data.h>
 +#include <ModelAPI_ResultConstruction.h>
 +
 +#include <SketchPlugin_Line.h>
 +#include <SketchPlugin_Sketch.h>
 +
 +#include <SketcherPrs_Factory.h>
 +
 +#include <Config_PropManager.h>
 +
 +SketchPlugin_ConstraintVertical::SketchPlugin_ConstraintVertical()
 +{
 +}
 +
 +void SketchPlugin_ConstraintVertical::initAttributes()
 +{
++  data()->addAttribute(SketchPlugin_Constraint::ENTITY_A(), ModelAPI_AttributeRefAttr::typeId());
 +}
 +
 +void SketchPlugin_ConstraintVertical::execute()
 +{
 +}
 +
 +AISObjectPtr SketchPlugin_ConstraintVertical::getAISObject(AISObjectPtr thePrevious)
 +{
 +  if (!sketch())
 +    return thePrevious;
 +
 +  AISObjectPtr anAIS = thePrevious;
 +  if (!anAIS) {
 +    anAIS = SketcherPrs_Factory::verticalConstraint(this, sketch()->coordinatePlane());
 +  }
 +  return anAIS;
 +}
 +
 +
index ea5d0a42b1e57039053e2a7ff2c63b1d0b34d0c5,2525b642e17fe79d688fffa813b3d466f2400c7f..ed07e4079bd6bd7eba234a943289ec1d97b6539e
@@@ -28,11 -27,9 +28,11 @@@ SketchPlugin_Line::SketchPlugin_Line(
  
  void SketchPlugin_Line::initAttributes()
  {
-   data()->addAttribute(START_ID(), GeomDataAPI_Point2D::type());
-   data()->addAttribute(END_ID(), GeomDataAPI_Point2D::type());
-   data()->addAttribute(EXTERNAL_ID(), ModelAPI_AttributeSelection::type());
 +  SketchPlugin_SketchEntity::initAttributes();
 +
+   data()->addAttribute(START_ID(), GeomDataAPI_Point2D::typeId());
+   data()->addAttribute(END_ID(), GeomDataAPI_Point2D::typeId());
+   data()->addAttribute(EXTERNAL_ID(), ModelAPI_AttributeSelection::typeId());
    ModelAPI_Session::get()->validators()->registerNotObligatory(getKind(), EXTERNAL_ID());
  }
  
index 04347759e5655848a0831c73ab5977e2abbc211d,21f74bc637d296c989f26d7159acada465de565c..35ff48c6ab8101d120185aa8db6e6ec22343d364
@@@ -53,9 -45,9 +53,7 @@@ SketchPlugin_Plugin::SketchPlugin_Plugi
                                new SketchPlugin_DistanceAttrValidator);  
    //aFactory->registerValidator("SketchPlugin_DifferentObjects",
    //                            new SketchPlugin_DifferentObjectsValidator);
-   aFactory->registerValidator("SketchPlugin_ShapeValidator",
-                               new SketchPlugin_ShapeValidator);
 -  aFactory->registerValidator("SketchPlugin_ResultPoint", new SketchPlugin_ResultPointValidator);
 -  aFactory->registerValidator("SketchPlugin_ResultLine", new SketchPlugin_ResultLineValidator);
 -  aFactory->registerValidator("SketchPlugin_ResultArc", new SketchPlugin_ResultArcValidator);
++  aFactory->registerValidator("SketchPlugin_ShapeValidator", new SketchPlugin_ShapeValidator);
  
    // register this plugin
    ModelAPI_Session::get()->registerPlugin(this);
index 036fde19db093340f6a632a0b73b2f860e7e26a7,cb2cad6de12cb3e4265aa7664737a340e9348736..6fe1e2cfab638557a3c481b138ad00bbc603fdb6
@@@ -27,10 -26,8 +27,10 @@@ SketchPlugin_Point::SketchPlugin_Point(
  
  void SketchPlugin_Point::initAttributes()
  {
-   data()->addAttribute(SketchPlugin_Point::COORD_ID(), GeomDataAPI_Point2D::type());
-   data()->addAttribute(EXTERNAL_ID(), ModelAPI_AttributeSelection::type());
 +  SketchPlugin_SketchEntity::initAttributes();
 +
+   data()->addAttribute(SketchPlugin_Point::COORD_ID(), GeomDataAPI_Point2D::typeId());
+   data()->addAttribute(EXTERNAL_ID(), ModelAPI_AttributeSelection::typeId());
    ModelAPI_Session::get()->validators()->registerNotObligatory(getKind(), EXTERNAL_ID());
  }
  
index b57c1e3ba21e7b587c0a4fd950c6a516fa3d082b,b85b3d209d0b1692b9836f970ee9aa5bab30fc3f..377fc0beddf6fc491423951a2417c3ca474e0a2e
@@@ -44,14 -43,15 +44,14 @@@ SketchPlugin_Sketch::SketchPlugin_Sketc
  
  void SketchPlugin_Sketch::initAttributes()
  {
-   data()->addAttribute(SketchPlugin_Sketch::ORIGIN_ID(), GeomDataAPI_Point::type());
-   data()->addAttribute(SketchPlugin_Sketch::DIRX_ID(), GeomDataAPI_Dir::type());
-   data()->addAttribute(SketchPlugin_Sketch::NORM_ID(), GeomDataAPI_Dir::type());
-   data()->addAttribute(SketchPlugin_Sketch::FEATURES_ID(), ModelAPI_AttributeRefList::type());
+   data()->addAttribute(SketchPlugin_Sketch::ORIGIN_ID(), GeomDataAPI_Point::typeId());
+   data()->addAttribute(SketchPlugin_Sketch::DIRX_ID(), GeomDataAPI_Dir::typeId());
 -  data()->addAttribute(SketchPlugin_Sketch::DIRY_ID(), GeomDataAPI_Dir::typeId());
+   data()->addAttribute(SketchPlugin_Sketch::NORM_ID(), GeomDataAPI_Dir::typeId());
+   data()->addAttribute(SketchPlugin_Sketch::FEATURES_ID(), ModelAPI_AttributeRefList::typeId());
    // the selected face, base for the sketcher plane, not obligatory
-   data()->addAttribute(SketchPlugin_SketchEntity::EXTERNAL_ID(), ModelAPI_AttributeSelection::type());
 -  data()->addAttribute(SketchPlugin_Feature::EXTERNAL_ID(), ModelAPI_AttributeSelection::typeId());
++  data()->addAttribute(SketchPlugin_SketchEntity::EXTERNAL_ID(), ModelAPI_AttributeSelection::typeId());
    ModelAPI_Session::get()->validators()->registerNotObligatory(
 -    getKind(), SketchPlugin_Feature::EXTERNAL_ID());
 +    getKind(), SketchPlugin_SketchEntity::EXTERNAL_ID());
  }
  
  void SketchPlugin_Sketch::execute()
index 39cc06a67d08c52d0ee42838df99aab293bd1e0c,0000000000000000000000000000000000000000..9e95496ef455fa95572ba3c4f53c1a0c82b3ac47
mode 100644,000000..100644
--- /dev/null
@@@ -1,18 -1,0 +1,18 @@@
-   data()->addAttribute(AUXILIARY_ID(), ModelAPI_AttributeBoolean::type());
 +// Copyright (C) 2014-20xx CEA/DEN, EDF R&D -->
 +
 +#include "SketchPlugin_SketchEntity.h"
 +
 +#include <ModelAPI_Session.h>
 +#include <ModelAPI_Validator.h>
 +#include <ModelAPI_AttributeIntArray.h>
 +
 +SketchPlugin_SketchEntity::SketchPlugin_SketchEntity()
 +: SketchPlugin_Feature()
 +{
 +}
 +
 +void SketchPlugin_SketchEntity::initAttributes()
 +{
++  data()->addAttribute(AUXILIARY_ID(), ModelAPI_AttributeBoolean::typeId());
 +  ModelAPI_Session::get()->validators()->registerNotObligatory(getKind(), AUXILIARY_ID());
 +}
index 32a0b30b57cc3028c1311c8b1c5935d5c46841c8,43186329b9ea56e7f6e811899bfb4c2bea1b06b5..ca7df854dcdf26bcbf700b5da88ef40ad542951e
  #include <ModelAPI_AttributeDouble.h>
  #include <ModelAPI_AttributeRefAttr.h>
  #include <ModelAPI_Session.h>
 +
 +#include <GeomValidators_Edge.h>
 +
  #include <GeomDataAPI_Point2D.h>
  
 -bool SketchPlugin_DistanceAttrValidator::isValid(const FeaturePtr& theFeature,
 -                                                 const std::list<std::string>& theArguments,
 -                                                 const ObjectPtr& theObject,
 -                                                 const GeomShapePtr& theShape) const
 +bool SketchPlugin_DistanceAttrValidator::isValid(
 +  const AttributePtr& theAttribute, const std::list<std::string>& theArguments ) const
++//bool SketchPlugin_DistanceAttrValidator::isValid(const FeaturePtr& theFeature,
++//                                                 const std::list<std::string>& theArguments,
++//                                                 const ObjectPtr& theObject,
++//                                                 const GeomShapePtr& theShape) const
++// ======= end of todo master
  {
 +  // there is a check whether the feature contains a point and a linear edge or two point values
    std::string aParamA = theArguments.front();
    SessionPtr aMgr = ModelAPI_Session::get();
    ModelAPI_ValidatorsFactory* aFactory = aMgr->validators();
  
 -  const ModelAPI_ResultValidator* anArcValidator =
 -      dynamic_cast<const ModelAPI_ResultValidator*>(aFactory->validator("SketchPlugin_ResultArc"));
 -  bool anArcValid = anArcValidator->isValid(theObject);
 -  if (anArcValid)
 +  AttributeRefAttrPtr aRefAttr = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(theAttribute);
 +  if (!aRefAttr)
      return false;
  
 -
 -  // If the object is not a line then it is accepted
 -  const ModelAPI_ResultValidator* aLineValidator =
 -      dynamic_cast<const ModelAPI_ResultValidator*>(aFactory->validator("SketchPlugin_ResultLine"));
 -  bool aLineValid = aLineValidator->isValid(theObject);
 -  if (!aLineValid)
 +  bool isObject = aRefAttr->isObject();
 +  if (!isObject) {
 +    // an attribute is a point. A point value is valid always for the distance
      return true;
 +  } else {
 +    // 1. check whether the references object is a linear
 +    ObjectPtr anObject = aRefAttr->object();
  
 -  // If it is a line then we have to check that first attribute id not a line
 -  std::shared_ptr<GeomDataAPI_Point2D> aPoint = getFeaturePoint(theFeature->data(), aParamA);
 -  if (aPoint)
 -    return true;
 -  return false;
 -}
 +    const ModelAPI_AttributeValidator* anEdgeValidator = 
 +      dynamic_cast<const GeomValidators_Edge*>(aFactory->validator("GeomValidators_Edge"));
 +    std::list<std::string> anArguments;
 +    anArguments.push_back("circle");
 +    bool anEdgeValid = anEdgeValidator->isValid(aRefAttr, anArguments);
 +    // the circle line is not a valid case
 +    if (anEdgeValid)
 +      return false;
 +      
 +    anArguments.clear();
 +    anArguments.push_back("line");
 +    anEdgeValid = anEdgeValidator->isValid(aRefAttr, anArguments);
 +    // if the attribute value is not a line, that means it is a vertex. A vertex is always valid
 +    if (!anEdgeValid)
 +      return true;
  
 -bool SketchPlugin_DistanceAttrValidator::isValid(
 -  const AttributePtr& theAttribute, const std::list<std::string>& theArguments ) const
 -{
 -  // any point attribute is acceptable for the distance operation
 -  return true;
 +    FeaturePtr aFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(theAttribute->owner());
 +    // If it is a line then we have to check that first attribute id not a line
 +    std::shared_ptr<GeomDataAPI_Point2D> aPoint = getFeaturePoint(aFeature->data(), aParamA);
 +    if (aPoint)
 +      return true;
 +  }
 +  return false;
  }
 -bool SketchPlugin_DistanceAttrValidator::isValid(const FeaturePtr& theFeature,
 -                                                 const std::list<std::string>& theArguments,
 -                                                 const AttributePtr& theAttribute) const
 -{
 -  return isValid(theAttribute, theArguments);
 -}
++// TODO(nds) v1.0.2, master
++//  return false;
++//}
++//bool SketchPlugin_DistanceAttrValidator::isValid(
++//  const AttributePtr& theAttribute, const std::list<std::string>& theArguments ) const
++//{
++//  // any point attribute is acceptable for the distance operation
++//  return true;
++//}
++//
++//bool SketchPlugin_DistanceAttrValidator::isValid(const FeaturePtr& theFeature,
++//                                                 const std::list<std::string>& theArguments,
++//                                                 const AttributePtr& theAttribute) const
++//{
++//  return isValid(theAttribute, theArguments);
++//}
++// commented in v1.0.2, master:
+ //bool SketchPlugin_DifferentObjectsValidator::isValid(const FeaturePtr& theFeature,
+ //                                                 const std::list<std::string>& theArguments,
+ //                                                 const ObjectPtr& theObject) const
+ //{
+ //  std::list<std::shared_ptr<ModelAPI_Attribute> > anAttrs = 
+ //    theFeature->data()->attributes(ModelAPI_AttributeRefAttr::typeId());
+ //  std::list<std::shared_ptr<ModelAPI_Attribute> >::iterator anAttr = anAttrs.begin();
+ //  for(; anAttr != anAttrs.end(); anAttr++) {
+ //    if (*anAttr) {
+ //      std::shared_ptr<ModelAPI_AttributeRefAttr> aRef = 
+ //        std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(*anAttr);
+ //      // check the object is already presented
+ //      if (aRef->isObject() && aRef->object() == theObject)
+ //        return false;
+ //    }
+ //  }
+ //  return true;
+ //}
+ //bool SketchPlugin_DifferentObjectsValidator::isValid(
+ //  const AttributePtr& theAttribute, const std::list<std::string>& theArguments ) const
+ //{
+ //  std::shared_ptr<ModelAPI_AttributeRefAttr> anOrigAttr = 
+ //    std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(theAttribute);
+ //  if (anOrigAttr && anOrigAttr->isObject()) {
+ //    const ObjectPtr& anObj = theAttribute->owner();
+ //    const FeaturePtr aFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(anObj);
+ //
+ //    std::list<std::shared_ptr<ModelAPI_Attribute> > anAttrs = 
+ //      aFeature->data()->attributes(ModelAPI_AttributeRefAttr::typeId());
+ //    std::list<std::shared_ptr<ModelAPI_Attribute> >::iterator anAttr = anAttrs.begin();
+ //    for(; anAttr != anAttrs.end(); anAttr++) {
+ //      if (*anAttr && *anAttr != theAttribute) {
+ //        std::shared_ptr<ModelAPI_AttributeRefAttr> aRef = 
+ //          std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(*anAttr);
+ //        // check the object is already presented
+ //        if (aRef->isObject() && aRef->object() == anOrigAttr->object())
+ //          return false;
+ //      }
+ //    }
+ //  }
+ //  return true;
+ //}
+ //bool SketchPlugin_DifferentObjectsValidator::isValid(const FeaturePtr& theFeature,
+ //  const std::list<std::string>& theArguments, const AttributePtr& theAttribute) const
+ //{
+ //  std::list<std::shared_ptr<ModelAPI_Attribute> > anAttrs = 
+ //    theFeature->data()->attributes(ModelAPI_AttributeRefAttr::typeId());
+ //  std::list<std::shared_ptr<ModelAPI_Attribute> >::iterator anAttr = anAttrs.begin();
+ //  for(; anAttr != anAttrs.end(); anAttr++) {
+ //    if (*anAttr) {
+ //      std::shared_ptr<ModelAPI_AttributeRefAttr> aRef = 
+ //        std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(*anAttr);
+ //      // check the object is already presented
+ //      if (!aRef->isObject() && aRef->attr() == theAttribute)
+ //        return false;
+ //    }
+ //  }
+ //  return true;
+ //}
++// =========== end of todo
index f686d3e6ebe97a5e75cefcee21b313b3fd2b7f04,88c8d3a485fbff2b39924377124d68b71d5a8973..6259c2bd682f82bbdb028c69b7bd71c69e4ce3f3
@@@ -22,8 -22,39 +22,44 @@@ class SketchPlugin_DistanceAttrValidato
    //! returns true if attribute is valid
    //! \param theAttribute the checked attribute
    //! \param theArguments arguments of the attribute
 -  virtual bool isValid(const AttributePtr& theAttribute, 
 +  virtual bool isValid(const AttributePtr& theAttribute,
                         const std::list<std::string>& theArguments) const;
 -
 -  //! Returns true if object is good for the feature attribute
 -  virtual bool isValid(const FeaturePtr& theFeature, const std::list<std::string>& theArguments,
 -                       const ObjectPtr& theObject, const GeomShapePtr& theShape) const;
 -
 -  //! Returns true if the attribute is good for the feature attribute
 -  virtual bool isValid(const FeaturePtr& theFeature, const std::list<std::string>& theArguments,
 -                       const AttributePtr& theAttribute) const;
  };
++//  virtual bool isValid(const AttributePtr& theAttribute,
++//                       const std::list<std::string>& theArguments) const;
++//
++//  //! Returns true if object is good for the feature attribute
++//  virtual bool isValid(const FeaturePtr& theFeature, const std::list<std::string>& theArguments,
++//                       const ObjectPtr& theObject, const GeomShapePtr& theShape) const;
++//
++//  //! Returns true if the attribute is good for the feature attribute
++//  virtual bool isValid(const FeaturePtr& theFeature, const std::list<std::string>& theArguments,
++//                       const AttributePtr& theAttribute) const;
++//};
++// commented in v1.0.2, master:
+ /**\class SketchPlugin_DifferentObjectsValidator
+  * \ingroup Validators
+  *
+  * Check that there is no same object was already selected in the feature.
+  * For an example: to avoid perpendicularity on line and the same line.
+  */
+ // Use PartSet_DifferentObjectsValidator instead
+ //class SketchPlugin_DifferentObjectsValidator : public ModelAPI_RefAttrValidator
+ //{
+ // public:
+ //  //! returns true if attribute is valid
+ //  //! \param theAttribute the checked attribute
+ //  //! \param theArguments arguments of the attribute
+ //  virtual bool isValid(
+ //    const AttributePtr& theAttribute, const std::list<std::string>& theArguments) const;
+ //  //! Returns true if object is good for the feature attribute
+ //  virtual bool isValid(const FeaturePtr& theFeature, const std::list<std::string>& theArguments,
+ //                       const ObjectPtr& theObject) const;
+ //  //! Returns true if the attribute is good for the feature attribute
+ //  virtual bool isValid(const FeaturePtr& theFeature, const std::list<std::string>& theArguments,
+ //                       const AttributePtr& theAttribute) const;
+ //};
++// ======= end of todo
  
  #endif
index 09f8f076d4207e3cdb5c4308541c411b1f5da69b,0000000000000000000000000000000000000000..5e99e051250f9e883848dcd6fe634dd08d581a50
mode 100644,000000..100644
--- /dev/null
@@@ -1,120 -1,0 +1,120 @@@
-         data()->addAttribute(SketchPlugin_Constraint::ENTITY_A(), ModelAPI_AttributeRefAttr::type());
-         data()->addAttribute(SketchPlugin_Constraint::ENTITY_B(), ModelAPI_AttributeRefAttr::type());
 +"""
 +    TestConstraintEqual.py
 +    Unit test of SketchPlugin_ConstraintEqual class
 +        
 +    SketchPlugin_ConstraintEqual
 +        static const std::string MY_CONSTRAINT_EQAUL_ID("SketchConstraintEqual");
++        data()->addAttribute(SketchPlugin_Constraint::ENTITY_A(), ModelAPI_AttributeRefAttr::typeId());
++        data()->addAttribute(SketchPlugin_Constraint::ENTITY_B(), ModelAPI_AttributeRefAttr::typeId());
 +
 +"""
 +from GeomDataAPI import *
 +from ModelAPI import *
 +import math
 +#=========================================================================
 +# Initialization of the test
 +#=========================================================================
 +
 +__updated__ = "2015-03-16"
 +
 +aSession = ModelAPI_Session.get()
 +aDocument = aSession.moduleDocument()
 +#=========================================================================
 +# Creation of a sketch
 +#=========================================================================
 +aSession.startOperation()
 +aSketchCommonFeature = aDocument.addFeature("Sketch")
 +aSketchFeature = modelAPI_CompositeFeature(aSketchCommonFeature)
 +origin = geomDataAPI_Point(aSketchFeature.attribute("Origin"))
 +origin.setValue(0, 0, 0)
 +dirx = geomDataAPI_Dir(aSketchFeature.attribute("DirX"))
 +dirx.setValue(1, 0, 0)
 +diry = geomDataAPI_Dir(aSketchFeature.attribute("DirY"))
 +diry.setValue(0, 1, 0)
 +norm = geomDataAPI_Dir(aSketchFeature.attribute("Norm"))
 +norm.setValue(0, 0, 1)
 +aSession.finishOperation()
 +#=========================================================================
 +# Creation of an arc and a circle
 +#=========================================================================
 +aSession.startOperation()
 +aSketchArc = aSketchFeature.addFeature("SketchArc")
 +anArcCentr = geomDataAPI_Point2D(aSketchArc.attribute("ArcCenter"))
 +anArcCentr.setValue(10., 10.)
 +anArcStartPoint = geomDataAPI_Point2D(aSketchArc.attribute("ArcStartPoint"))
 +anArcStartPoint.setValue(0., 50.)
 +anArcEndPoint = geomDataAPI_Point2D(aSketchArc.attribute("ArcEndPoint"))
 +anArcEndPoint.setValue(50., 0.)
 +aSession.finishOperation()
 +# Circle
 +aSession.startOperation()
 +aSketchCircle = aSketchFeature.addFeature("SketchCircle")
 +anCircleCentr = geomDataAPI_Point2D(aSketchCircle.attribute("CircleCenter"))
 +aCircleRadius = aSketchCircle.real("CircleRadius")
 +anCircleCentr.setValue(-25., -25)
 +aCircleRadius.setValue(25.)
 +aSession.finishOperation()
 +#=========================================================================
 +# A constraint to make equal radii of arc and circle
 +#=========================================================================
 +aSession.startOperation()
 +aConstraintEqRad = aSketchFeature.addFeature("SketchConstraintEqual")
 +aRefObjectA = aConstraintEqRad.refattr("ConstraintEntityA")
 +aRefObjectB = aConstraintEqRad.refattr("ConstraintEntityB")
 +aResultA = modelAPI_ResultConstruction(aSketchArc.lastResult())
 +aResultB = modelAPI_ResultConstruction(aSketchCircle.lastResult())
 +assert (aResultA is not None)
 +assert (aResultB is not None)
 +aRefObjectA.setObject(aResultA)
 +aRefObjectB.setObject(aResultB)
 +aConstraintEqRad.execute()
 +aSession.finishOperation()
 +aCircRadius = aCircleRadius.value();
 +anArcVecX = anArcStartPoint.x() - anArcCentr.x();
 +anArcVecY = anArcStartPoint.y() - anArcCentr.y();
 +anArcRadius = math.sqrt(anArcVecX**2 + anArcVecY**2)
 +assert (math.fabs(aCircRadius - anArcRadius) <= 1.e-10)
 +#=========================================================================
 +# Creation of two different lines
 +#=========================================================================
 +# First Line
 +aSession.startOperation()
 +aSketchLine1 = aSketchFeature.addFeature("SketchLine")
 +aLine1StartPoint = geomDataAPI_Point2D(aSketchLine1.attribute("StartPoint"))
 +aLine1EndPoint = geomDataAPI_Point2D(aSketchLine1.attribute("EndPoint"))
 +aLine1StartPoint.setValue(0., 15.)
 +aLine1EndPoint.setValue(20., 25.)
 +aSession.finishOperation()
 +# Second Line
 +aSession.startOperation()
 +aSketchLine2 = aSketchFeature.addFeature("SketchLine")
 +aLine2StartPoint = geomDataAPI_Point2D(aSketchLine2.attribute("StartPoint"))
 +aLine2EndPoint = geomDataAPI_Point2D(aSketchLine2.attribute("EndPoint"))
 +aLine2StartPoint.setValue(0., 0.)
 +aLine2EndPoint.setValue(-1., 10.)
 +aSession.finishOperation()
 +#=========================================================================
 +# A constraint to make equal lengths of lines
 +#=========================================================================
 +aSession.startOperation()
 +aConstraintEqLen = aSketchFeature.addFeature("SketchConstraintEqual")
 +aRefObjectA = aConstraintEqLen.refattr("ConstraintEntityA")
 +aRefObjectB = aConstraintEqLen.refattr("ConstraintEntityB")
 +aResultA = modelAPI_ResultConstruction(aSketchLine1.firstResult())
 +aResultB = modelAPI_ResultConstruction(aSketchLine2.firstResult())
 +assert (aResultA is not None)
 +assert (aResultB is not None)
 +aRefObjectA.setObject(aResultA)
 +aRefObjectB.setObject(aResultB)
 +aConstraintEqLen.execute()
 +aSession.finishOperation()
 +aVecX = aLine1StartPoint.x() - aLine1EndPoint.x();
 +aVecY = aLine1StartPoint.y() - aLine1EndPoint.y();
 +aLine1Len = math.sqrt(anArcVecX * anArcVecX + anArcVecY * anArcVecY)
 +aVecX = aLine2StartPoint.x() - aLine2EndPoint.x();
 +aVecY = aLine2StartPoint.y() - aLine2EndPoint.y();
 +aLine2Len = math.sqrt(anArcVecX**2 + anArcVecY**2)
 +assert (aLine1Len == aLine2Len)
 +#=========================================================================
 +# End of test
 +#=========================================================================
index 337315858e173b5c95ad02c8d5e252ffb106ee31,0000000000000000000000000000000000000000..050c60f249e7084053c6cad865e887c80661c520
mode 100644,000000..100644
--- /dev/null
@@@ -1,78 -1,0 +1,78 @@@
-         data()->addAttribute(SketchPlugin_Constraint::ENTITY_A(), ModelAPI_AttributeRefAttr::type());
 +"""
 +    TestConstraintHorizontal.py
 +    Unit test of SketchPlugin_ConstraintHorizontal class
 +        
 +    SketchPlugin_ConstraintHorizontal
 +        static const std::string MY_CONSTRAINT_HORIZONTAL_ID("SketchConstraintHorizontal");
++        data()->addAttribute(SketchPlugin_Constraint::ENTITY_A(), ModelAPI_AttributeRefAttr::typeId());
 +
 +"""
 +from GeomDataAPI import *
 +from ModelAPI import *
 +#=========================================================================
 +# Initialization of the test
 +#=========================================================================
 +
 +__updated__ = "2015-03-16"
 +
 +aSession = ModelAPI_Session.get()
 +aDocument = aSession.moduleDocument()
 +#=========================================================================
 +# Creation of a sketch
 +#=========================================================================
 +aSession.startOperation()
 +aSketchCommonFeature = aDocument.addFeature("Sketch")
 +aSketchFeature = modelAPI_CompositeFeature(aSketchCommonFeature)
 +origin = geomDataAPI_Point(aSketchFeature.attribute("Origin"))
 +origin.setValue(0, 0, 0)
 +dirx = geomDataAPI_Dir(aSketchFeature.attribute("DirX"))
 +dirx.setValue(1, 0, 0)
 +diry = geomDataAPI_Dir(aSketchFeature.attribute("DirY"))
 +diry.setValue(0, 1, 0)
 +norm = geomDataAPI_Dir(aSketchFeature.attribute("Norm"))
 +norm.setValue(0, 0, 1)
 +aSession.finishOperation()
 +#=========================================================================
 +# Create non-horizontal line
 +#=========================================================================
 +aSession.startOperation()
 +aSketchLine = aSketchFeature.addFeature("SketchLine")
 +aLineStartPoint = geomDataAPI_Point2D(aSketchLine.attribute("StartPoint"))
 +aLineEndPoint = geomDataAPI_Point2D(aSketchLine.attribute("EndPoint"))
 +aLineStartPoint.setValue(0., 15.)
 +aLineEndPoint.setValue(20., 25.)
 +aSession.finishOperation()
 +#=========================================================================
 +# Assign horizontal constraint for a line
 +#=========================================================================
 +aSession.startOperation()
 +aHorizontalConstraint = aSketchFeature.addFeature("SketchConstraintHorizontal")
 +refattrA = aHorizontalConstraint.refattr("ConstraintEntityA")
 +aResult = modelAPI_ResultConstruction(aSketchLine.firstResult())
 +assert (aResult is not None)
 +refattrA.setObject(aResult)
 +aHorizontalConstraint.execute()
 +aSession.finishOperation()
 +assert(aLineStartPoint.y() == aLineEndPoint.y())
 +#=========================================================================
 +# Move one of boundary points of a line
 +#=========================================================================
 +deltaX = deltaY = 10.
 +aSession.startOperation()
 +aLineStartPoint.setValue(aLineStartPoint.x() + deltaX,
 +                         aLineStartPoint.y() + deltaY)
 +aSession.finishOperation()
 +assert(aLineStartPoint.y() == aLineEndPoint.y())
 +#=========================================================================
 +# Move other boundary point of a line
 +#=========================================================================
 +deltaX = -3.
 +deltaY = -10.
 +aSession.startOperation()
 +aLineEndPoint.setValue(aLineEndPoint.x() + deltaX,
 +                       aLineEndPoint.y() + deltaY)
 +aSession.finishOperation()
 +assert(aLineStartPoint.y() == aLineEndPoint.y())
 +#=========================================================================
 +# End of test
 +#=========================================================================
index 3c3c2d05288fa382ca68257de98e8e577695d0bf,0000000000000000000000000000000000000000..4f85ec44ecf22a0c97f9dcfcb387c1b36aab02eb
mode 100644,000000..100644
--- /dev/null
@@@ -1,158 -1,0 +1,158 @@@
-         data()->addAttribute(SketchPlugin_Constraint::ENTITY_A(), ModelAPI_AttributeRefAttr::type());
-         data()->addAttribute(SketchPlugin_Constraint::ENTITY_B(), ModelAPI_AttributeRefListAttr::type());
-         data()->addAttribute(SketchPlugin_Constraint::ENTITY_C(), ModelAPI_AttributeRefListAttr::type());
 +"""
 +    TestConstraintMirror.py
 +    Unit test of SketchPlugin_ConstraintMirror class
 +        
 +    SketchPlugin_ConstraintMirror
 +        static const std::string MY_CONSTRAINT_MIRROR_ID("SketchConstraintMirror");
++        data()->addAttribute(SketchPlugin_Constraint::ENTITY_A(), ModelAPI_AttributeRefAttr::typeId());
++        data()->addAttribute(SketchPlugin_Constraint::ENTITY_B(), ModelAPI_AttributeRefListAttr::typeId());
++        data()->addAttribute(SketchPlugin_Constraint::ENTITY_C(), ModelAPI_AttributeRefListAttr::typeId());
 +
 +"""
 +from GeomDataAPI import *
 +from ModelAPI import *
 +import math
 +#=========================================================================
 +# Initialization of the test
 +#=========================================================================
 +
 +__updated__ = "2015-03-17"
 +
 +aSession = ModelAPI_Session.get()
 +aDocument = aSession.moduleDocument()
 +#=========================================================================
 +# Creation of a sketch
 +#=========================================================================
 +aSession.startOperation()
 +aSketchCommonFeature = aDocument.addFeature("Sketch")
 +aSketchFeature = modelAPI_CompositeFeature(aSketchCommonFeature)
 +origin = geomDataAPI_Point(aSketchFeature.attribute("Origin"))
 +origin.setValue(0, 0, 0)
 +dirx = geomDataAPI_Dir(aSketchFeature.attribute("DirX"))
 +dirx.setValue(1, 0, 0)
 +diry = geomDataAPI_Dir(aSketchFeature.attribute("DirY"))
 +diry.setValue(0, 1, 0)
 +norm = geomDataAPI_Dir(aSketchFeature.attribute("Norm"))
 +norm.setValue(0, 0, 1)
 +aSession.finishOperation()
 +#=========================================================================
 +# Creation of an arc and two lines
 +#=========================================================================
 +# Arc
 +aSession.startOperation()
 +aSketchArc1 = aSketchFeature.addFeature("SketchArc")
 +anArcCentr = geomDataAPI_Point2D(aSketchArc1.attribute("ArcCenter"))
 +anArcCentr.setValue(10., 10.)
 +anArcStartPoint = geomDataAPI_Point2D(aSketchArc1.attribute("ArcStartPoint"))
 +anArcStartPoint.setValue(0., 50.)
 +anArcEndPoint = geomDataAPI_Point2D(aSketchArc1.attribute("ArcEndPoint"))
 +anArcEndPoint.setValue(50., 0.)
 +aSession.finishOperation()
 +# Line 1
 +aSession.startOperation()
 +aSketchLine1 = aSketchFeature.addFeature("SketchLine")
 +aLine1StartPoint = geomDataAPI_Point2D(aSketchLine1.attribute("StartPoint"))
 +aLine1EndPoint = geomDataAPI_Point2D(aSketchLine1.attribute("EndPoint"))
 +aLine1StartPoint.setValue(0., 50.)
 +aLine1EndPoint.setValue(0., 100.)
 +aSession.finishOperation()
 +# Line 2
 +aSession.startOperation()
 +aSketchLine2 = aSketchFeature.addFeature("SketchLine")
 +aLine2StartPoint = geomDataAPI_Point2D(aSketchLine2.attribute("StartPoint"))
 +aLine2EndPoint = geomDataAPI_Point2D(aSketchLine2.attribute("EndPoint"))
 +aLine2StartPoint.setValue(50., 0.)
 +aLine2EndPoint.setValue(100., 0.)
 +aSession.finishOperation()
 +#=========================================================================
 +# Link arc points and lines points by the coincidence constraint
 +#=========================================================================
 +aSession.startOperation()
 +aConstraint = aSketchFeature.addFeature("SketchConstraintCoincidence")
 +reflistA = aConstraint.refattr("ConstraintEntityA")
 +reflistB = aConstraint.refattr("ConstraintEntityB")
 +reflistA.setAttr(anArcStartPoint)
 +reflistB.setAttr(aLine1StartPoint)
 +aConstraint.execute()
 +aSession.finishOperation()
 +aSession.startOperation()
 +aConstraint = aSketchFeature.addFeature("SketchConstraintCoincidence")
 +reflistA = aConstraint.refattr("ConstraintEntityA")
 +reflistB = aConstraint.refattr("ConstraintEntityB")
 +reflistA.setAttr(anArcEndPoint)
 +reflistB.setAttr(aLine2StartPoint)
 +aConstraint.execute()
 +aSession.finishOperation()
 +#=========================================================================
 +# Add tangency constraint and check correctness
 +#=========================================================================
 +aSession.startOperation()
 +aTangency = aSketchFeature.addFeature("SketchConstraintTangent")
 +aRefObjectA = aTangency.refattr("ConstraintEntityA")
 +aRefObjectB = aTangency.refattr("ConstraintEntityB")
 +anObjectA = modelAPI_ResultConstruction(aSketchArc1.lastResult())
 +anObjectB = modelAPI_ResultConstruction(aSketchLine1.firstResult())
 +assert (anObjectA is not None)
 +assert (anObjectB is not None)
 +aRefObjectA.setObject(anObjectA)
 +aRefObjectB.setObject(anObjectB)
 +aTangency.execute()
 +aSession.finishOperation()
 +#=========================================================================
 +# Create mirror line
 +#=========================================================================
 +aSession.startOperation()
 +aMirrorLine = aSketchFeature.addFeature("SketchLine")
 +aLineStartPoint = geomDataAPI_Point2D(aMirrorLine.attribute("StartPoint"))
 +aLineEndPoint = geomDataAPI_Point2D(aMirrorLine.attribute("EndPoint"))
 +aLineStartPoint.setValue(100., 0.)
 +aLineEndPoint.setValue(100., 100.)
 +aSession.finishOperation()
 +#=========================================================================
 +# Make mirror for objects created above
 +#=========================================================================
 +aSession.startOperation()
 +aMirror = aSketchFeature.addFeature("SketchConstraintMirror")
 +aRefObjectA = aMirror.refattr("ConstraintEntityA")
 +aRefObjectA.setObject(modelAPI_ResultConstruction(aMirrorLine.firstResult()))
 +aRefListB = aMirror.reflist("ConstraintEntityB")
 +aRefListB.append(aSketchArc1)
 +aRefListB.append(aSketchLine1)
 +aRefListB.append(aSketchLine2)
 +aMirror.execute()
 +aSession.finishOperation()
 +#=========================================================================
 +# Verify the simmetricity of all mirrored objects
 +#=========================================================================
 +aRefListC = aMirror.reflist("ConstraintEntityC")
 +aListSize = aRefListB.size()
 +aLineDirX = aLineEndPoint.x() - aLineStartPoint.x()
 +aLineDirY = aLineEndPoint.y() - aLineStartPoint.y()
 +
 +for ind in range(0, aListSize):
 +  aFeatureB = modelAPI_Feature(aRefListB.object(ind))
 +  aFeatureC = modelAPI_Feature(aRefListC.object(ind))
 +  assert(aFeatureB is not None)
 +  assert(aFeatureC is not None)
 +  assert(aFeatureB.getKind() == aFeatureC.getKind())
 +  anAttributes = {}
 +  print aFeatureB.getKind()
 +  if (aFeatureB.getKind() == "SketchLine"):
 +    anAttributes = {'StartPoint':'StartPoint', 'EndPoint':'EndPoint'}
 +  elif (aFeatureB.getKind() == "SketchArc"):
 +    anAttributes = {'ArcCenter':'ArcCenter', 'ArcStartPoint':'ArcEndPoint', 'ArcEndPoint':'ArcStartPoint'}
 +
 +  for key in anAttributes:
 +    aPointB = geomDataAPI_Point2D(aFeatureB.attribute(key))
 +    aPointC = geomDataAPI_Point2D(aFeatureC.attribute(anAttributes[key]))
 +    aDirX = aPointC.x() - aPointB.x()
 +    aDirY = aPointC.y() - aPointB.y()
 +    aDot = aLineDirX * aDirX + aLineDirY * aDirY
 +    assert(math.fabs(aDot) < 1.e-10)
 +    aDirX = aLineEndPoint.x() - 0.5 * (aPointB.x() + aPointC.x())
 +    aDirY = aLineEndPoint.y() - 0.5 * (aPointB.y() + aPointC.y())
 +    aCross = aLineDirX * aDirY - aLineDirY * aDirX
 +    assert(math.fabs(aCross) < 1.e-10)
 +#=========================================================================
 +# End of test
 +#=========================================================================
index df753488a2de9e413569e09498bdcf21c98543c4,0000000000000000000000000000000000000000..a64b8a3a8c3db4293fa4bdbf982901ec5feaf90a
mode 100644,000000..100644
--- /dev/null
@@@ -1,226 -1,0 +1,226 @@@
-         data()->addAttribute(SketchPlugin_Constraint::ENTITY_A(), ModelAPI_AttributeRefAttr::type());
-         data()->addAttribute(SketchPlugin_Constraint::ENTITY_B(), ModelAPI_AttributeRefAttr::type());
 +"""
 +    TestConstraintTangent.py
 +    Unit test of SketchPlugin_ConstraintTangent class
 +        
 +    SketchPlugin_ConstraintTangent
 +        static const std::string MY_CONSTRAINT_TANGENT_ID("SketchConstraintTangent");
++        data()->addAttribute(SketchPlugin_Constraint::ENTITY_A(), ModelAPI_AttributeRefAttr::typeId());
++        data()->addAttribute(SketchPlugin_Constraint::ENTITY_B(), ModelAPI_AttributeRefAttr::typeId());
 +
 +"""
 +from GeomDataAPI import *
 +from GeomAPI import *
 +from ModelAPI import *
 +import math
 +#=========================================================================
 +# Initialization of the test
 +#=========================================================================
 +
 +__updated__ = "2015-03-17"
 +
 +aSession = ModelAPI_Session.get()
 +aDocument = aSession.moduleDocument()
 +#=========================================================================
 +# Creation of a sketch
 +#=========================================================================
 +aSession.startOperation()
 +aSketchCommonFeature = aDocument.addFeature("Sketch")
 +aSketchFeature = modelAPI_CompositeFeature(aSketchCommonFeature)
 +origin = geomDataAPI_Point(aSketchFeature.attribute("Origin"))
 +origin.setValue(0, 0, 0)
 +dirx = geomDataAPI_Dir(aSketchFeature.attribute("DirX"))
 +dirx.setValue(1, 0, 0)
 +diry = geomDataAPI_Dir(aSketchFeature.attribute("DirY"))
 +diry.setValue(0, 1, 0)
 +norm = geomDataAPI_Dir(aSketchFeature.attribute("Norm"))
 +norm.setValue(0, 0, 1)
 +aSession.finishOperation()
 +#=========================================================================
 +# TEST 1. Arc-line tangency
 +#=========================================================================
 +# Creation of an arc and two lines
 +#=========================================================================
 +# Arc
 +aSession.startOperation()
 +aSketchArc1 = aSketchFeature.addFeature("SketchArc")
 +anArcCentr = geomDataAPI_Point2D(aSketchArc1.attribute("ArcCenter"))
 +anArcCentr.setValue(10., 10.)
 +anArcStartPoint = geomDataAPI_Point2D(aSketchArc1.attribute("ArcStartPoint"))
 +anArcStartPoint.setValue(0., 50.)
 +anArcEndPoint = geomDataAPI_Point2D(aSketchArc1.attribute("ArcEndPoint"))
 +anArcEndPoint.setValue(50., 0.)
 +aSession.finishOperation()
 +# Line 1
 +aSession.startOperation()
 +aSketchLine1 = aSketchFeature.addFeature("SketchLine")
 +aLine1StartPoint = geomDataAPI_Point2D(aSketchLine1.attribute("StartPoint"))
 +aLine1EndPoint = geomDataAPI_Point2D(aSketchLine1.attribute("EndPoint"))
 +aLine1StartPoint.setValue(0., 50.)
 +aLine1EndPoint.setValue(0., 100.)
 +aSession.finishOperation()
 +# Line 2
 +aSession.startOperation()
 +aSketchLine2 = aSketchFeature.addFeature("SketchLine")
 +aLine2StartPoint = geomDataAPI_Point2D(aSketchLine2.attribute("StartPoint"))
 +aLine2EndPoint = geomDataAPI_Point2D(aSketchLine2.attribute("EndPoint"))
 +aLine2StartPoint.setValue(50., 0.)
 +aLine2EndPoint.setValue(100., 0.)
 +aSession.finishOperation()
 +#=========================================================================
 +# Link arc points and lines points by the coincidence constraint
 +#=========================================================================
 +aSession.startOperation()
 +aConstraint = aSketchFeature.addFeature("SketchConstraintCoincidence")
 +reflistA = aConstraint.refattr("ConstraintEntityA")
 +reflistB = aConstraint.refattr("ConstraintEntityB")
 +reflistA.setAttr(anArcStartPoint)
 +reflistB.setAttr(aLine1StartPoint)
 +aConstraint.execute()
 +aSession.finishOperation()
 +aSession.startOperation()
 +aConstraint = aSketchFeature.addFeature("SketchConstraintCoincidence")
 +reflistA = aConstraint.refattr("ConstraintEntityA")
 +reflistB = aConstraint.refattr("ConstraintEntityB")
 +reflistA.setAttr(anArcEndPoint)
 +reflistB.setAttr(aLine2StartPoint)
 +aConstraint.execute()
 +aSession.finishOperation()
 +#=========================================================================
 +# Add tangency constraint and check correctness
 +#=========================================================================
 +aSession.startOperation()
 +aTangency = aSketchFeature.addFeature("SketchConstraintTangent")
 +aRefObjectA = aTangency.refattr("ConstraintEntityA")
 +aRefObjectB = aTangency.refattr("ConstraintEntityB")
 +anObjectA = modelAPI_ResultConstruction(aSketchArc1.lastResult())
 +anObjectB = modelAPI_ResultConstruction(aSketchLine1.firstResult())
 +assert (anObjectA is not None)
 +assert (anObjectB is not None)
 +aRefObjectA.setObject(anObjectA)
 +aRefObjectB.setObject(anObjectB)
 +aTangency.execute()
 +aSession.finishOperation()
 +anArcVecX = anArcStartPoint.x() - anArcCentr.x()
 +anArcVecY = anArcStartPoint.y() - anArcCentr.y()
 +aLineVecX = aLine1EndPoint.x() - aLine1StartPoint.x()
 +aLineVecY = aLine1EndPoint.y() - aLine1StartPoint.y()
 +aDot = anArcVecX * aLineVecX + anArcVecY * aLineVecY
 +assert(math.fabs(aDot) <= 1.e-12)
 +#=========================================================================
 +# Add tangency constraint for arc and second line and check correctness
 +#=========================================================================
 +aSession.startOperation()
 +aTangency = aSketchFeature.addFeature("SketchConstraintTangent")
 +aRefObjectA = aTangency.refattr("ConstraintEntityA")
 +aRefObjectB = aTangency.refattr("ConstraintEntityB")
 +anObjectA = modelAPI_ResultConstruction(aSketchArc1.lastResult())
 +anObjectB = modelAPI_ResultConstruction(aSketchLine2.firstResult())
 +assert (anObjectA is not None)
 +assert (anObjectB is not None)
 +aRefObjectA.setObject(anObjectA)
 +aRefObjectB.setObject(anObjectB)
 +aTangency.execute()
 +aSession.finishOperation()
 +anArcVecX = anArcEndPoint.x() - anArcCentr.x()
 +anArcVecY = anArcEndPoint.y() - anArcCentr.y()
 +aLineVecX = aLine2EndPoint.x() - aLine2StartPoint.x()
 +aLineVecY = aLine2EndPoint.y() - aLine2StartPoint.y()
 +aDot = anArcVecX * aLineVecX + anArcVecY * aLineVecY
 +assert(math.fabs(aDot) <= 1.e-12)
 +
 +#=========================================================================
 +# TEST 2. Arc-arc tangency
 +#=========================================================================
 +# Creation of arcs
 +#=========================================================================
 +# Arc 1
 +aSession.startOperation()
 +aSketchArc1 = aSketchFeature.addFeature("SketchArc")
 +anArc1Centr = geomDataAPI_Point2D(aSketchArc1.attribute("ArcCenter"))
 +anArc1Centr.setValue(10., 10.)
 +anArc1StartPoint = geomDataAPI_Point2D(aSketchArc1.attribute("ArcStartPoint"))
 +anArc1StartPoint.setValue(50., 0.)
 +anArc1EndPoint = geomDataAPI_Point2D(aSketchArc1.attribute("ArcEndPoint"))
 +anArc1EndPoint.setValue(0., 50.)
 +aSession.finishOperation()
 +# Arc 2
 +aSession.startOperation()
 +aSketchArc2 = aSketchFeature.addFeature("SketchArc")
 +anArc2Centr = geomDataAPI_Point2D(aSketchArc2.attribute("ArcCenter"))
 +anArc2Centr.setValue(-10., 10.)
 +anArc2StartPoint = geomDataAPI_Point2D(aSketchArc2.attribute("ArcStartPoint"))
 +anArc2StartPoint.setValue(0., 50.)
 +anArc2EndPoint = geomDataAPI_Point2D(aSketchArc2.attribute("ArcEndPoint"))
 +anArc2EndPoint.setValue(-50., 0.)
 +aSession.finishOperation()
 +#=========================================================================
 +# Link points of arcs by the coincidence constraint
 +#=========================================================================
 +aSession.startOperation()
 +aConstraint = aSketchFeature.addFeature("SketchConstraintCoincidence")
 +reflistA = aConstraint.refattr("ConstraintEntityA")
 +reflistB = aConstraint.refattr("ConstraintEntityB")
 +reflistA.setAttr(anArc1EndPoint)
 +reflistB.setAttr(anArc2StartPoint)
 +aConstraint.execute()
 +aSession.finishOperation()
 +#=========================================================================
 +# Add tangency constraint and check correctness
 +#=========================================================================
 +aSession.startOperation()
 +aTangency = aSketchFeature.addFeature("SketchConstraintTangent")
 +aRefObjectA = aTangency.refattr("ConstraintEntityA")
 +aRefObjectB = aTangency.refattr("ConstraintEntityB")
 +anObjectA = modelAPI_ResultConstruction(aSketchArc1.lastResult())
 +anObjectB = modelAPI_ResultConstruction(aSketchArc2.lastResult())
 +assert (anObjectA is not None)
 +assert (anObjectB is not None)
 +aRefObjectA.setObject(anObjectA)
 +aRefObjectB.setObject(anObjectB)
 +aTangency.execute()
 +aSession.finishOperation()
 +anArc1VecX = anArc1EndPoint.x() - anArc1Centr.x()
 +anArc1VecY = anArc1EndPoint.y() - anArc1Centr.y()
 +anArc2VecX = anArc2StartPoint.x() - anArc2Centr.x()
 +anArc2VecY = anArc2StartPoint.y() - anArc2Centr.y()
 +aCross = anArc1VecX * anArc2VecY - anArc1VecY * anArc2VecX
 +assert(math.fabs(aCross) <= 1.e-12)
 +
 +#=========================================================================
 +# TEST 3. Tangency between non-connected objects should be wrong
 +#=========================================================================
 +# Store data
 +aLine2StartPointPrev = (aLine2StartPoint.x(), aLine2StartPoint.y())
 +aLine2EndPointPrev = (aLine2EndPoint.x(), aLine2EndPoint.y())
 +anArc2CenterPrev = (anArc2Centr.x(), anArc2Centr.y())
 +anArc2StartPointPrev = (anArc2StartPoint.x(), anArc2StartPoint.y())
 +anArc2EndPointPrev = (anArc2EndPoint.x(), anArc2EndPoint.y())
 +#=========================================================================
 +# Add tangency between arc2 and line2
 +#=========================================================================
 +aSession.startOperation()
 +aTangency = aSketchFeature.addFeature("SketchConstraintTangent")
 +aRefObjectA = aTangency.refattr("ConstraintEntityA")
 +aRefObjectB = aTangency.refattr("ConstraintEntityB")
 +anObjectA = modelAPI_ResultConstruction(aSketchArc2.lastResult())
 +anObjectB = modelAPI_ResultConstruction(aSketchLine2.firstResult())
 +assert (anObjectA is not None)
 +assert (anObjectB is not None)
 +aRefObjectA.setObject(anObjectA)
 +aRefObjectB.setObject(anObjectB)
 +aTangency.execute()
 +aSession.finishOperation()
 +# Check that nothing is changed
 +aLine2StartPointNew = (aLine2StartPoint.x(), aLine2StartPoint.y())
 +aLine2EndPointNew = (aLine2EndPoint.x(), aLine2EndPoint.y())
 +anArc2CenterNew = (anArc2Centr.x(), anArc2Centr.y())
 +anArc2StartPointNew = (anArc2StartPoint.x(), anArc2StartPoint.y())
 +anArc2EndPointNew = (anArc2EndPoint.x(), anArc2EndPoint.y())
 +assert(aLine2StartPointNew == aLine2StartPointPrev)
 +assert(aLine2EndPointNew == aLine2EndPointPrev)
 +assert(anArc2CenterNew == anArc2CenterPrev)
 +assert(anArc2StartPointNew == anArc2StartPointPrev)
 +assert(anArc2EndPointNew == anArc2EndPointPrev)
 +#=========================================================================
 +# End of test
 +#=========================================================================
index 87ba28f970d8a8a232310e8467ceb6f280271d32,0000000000000000000000000000000000000000..9272b21ec1384559cc4890505d1c75b7e9eebc16
mode 100644,000000..100644
--- /dev/null
@@@ -1,78 -1,0 +1,78 @@@
-         data()->addAttribute(SketchPlugin_Constraint::ENTITY_A(), ModelAPI_AttributeRefAttr::type());
 +"""
 +    TestConstraintVertical.py
 +    Unit test of SketchPlugin_ConstraintVertical class
 +        
 +    SketchPlugin_ConstraintVertical
 +        static const std::string MY_CONSTRAINT_VERTICAL_ID("SketchConstraintVertical");
++        data()->addAttribute(SketchPlugin_Constraint::ENTITY_A(), ModelAPI_AttributeRefAttr::typeId());
 +
 +"""
 +from GeomDataAPI import *
 +from ModelAPI import *
 +#=========================================================================
 +# Initialization of the test
 +#=========================================================================
 +
 +__updated__ = "2015-03-16"
 +
 +aSession = ModelAPI_Session.get()
 +aDocument = aSession.moduleDocument()
 +#=========================================================================
 +# Creation of a sketch
 +#=========================================================================
 +aSession.startOperation()
 +aSketchCommonFeature = aDocument.addFeature("Sketch")
 +aSketchFeature = modelAPI_CompositeFeature(aSketchCommonFeature)
 +origin = geomDataAPI_Point(aSketchFeature.attribute("Origin"))
 +origin.setValue(0, 0, 0)
 +dirx = geomDataAPI_Dir(aSketchFeature.attribute("DirX"))
 +dirx.setValue(1, 0, 0)
 +diry = geomDataAPI_Dir(aSketchFeature.attribute("DirY"))
 +diry.setValue(0, 1, 0)
 +norm = geomDataAPI_Dir(aSketchFeature.attribute("Norm"))
 +norm.setValue(0, 0, 1)
 +aSession.finishOperation()
 +#=========================================================================
 +# Create non-vertical line
 +#=========================================================================
 +aSession.startOperation()
 +aSketchLine = aSketchFeature.addFeature("SketchLine")
 +aLineStartPoint = geomDataAPI_Point2D(aSketchLine.attribute("StartPoint"))
 +aLineEndPoint = geomDataAPI_Point2D(aSketchLine.attribute("EndPoint"))
 +aLineStartPoint.setValue(0., 15.)
 +aLineEndPoint.setValue(20., 25.)
 +aSession.finishOperation()
 +#=========================================================================
 +# Assign vertical constraint for a line
 +#=========================================================================
 +aSession.startOperation()
 +aVerticalConstraint = aSketchFeature.addFeature("SketchConstraintVertical")
 +refattrA = aVerticalConstraint.refattr("ConstraintEntityA")
 +aResult = modelAPI_ResultConstruction(aSketchLine.firstResult())
 +assert (aResult is not None)
 +refattrA.setObject(aResult)
 +aVerticalConstraint.execute()
 +aSession.finishOperation()
 +assert(aLineStartPoint.x() == aLineEndPoint.x())
 +#=========================================================================
 +# Move one of boundary points of a line
 +#=========================================================================
 +deltaX = deltaY = 10.
 +aSession.startOperation()
 +aLineStartPoint.setValue(aLineStartPoint.x() + deltaX,
 +                         aLineStartPoint.y() + deltaY)
 +aSession.finishOperation()
 +assert(aLineStartPoint.x() == aLineEndPoint.x())
 +#=========================================================================
 +# Move other boundary point of a line
 +#=========================================================================
 +deltaX = -3.
 +deltaY = -10.
 +aSession.startOperation()
 +aLineEndPoint.setValue(aLineEndPoint.x() + deltaX,
 +                       aLineEndPoint.y() + deltaY)
 +aSession.finishOperation()
 +assert(aLineStartPoint.x() == aLineEndPoint.x())
 +#=========================================================================
 +# End of test
 +#=========================================================================
index f1bc36d9b27c41994d0a79f142c99c07659b778b,81c396a779e844a8e6eb2345786d218b3a022fc5..af51a5dd6164706a677181ba402fd625d2910d1c
            id="ConstraintEntityB" 
            label="Last object" 
            tooltip="Select point, line end point, line, center of circle or arc." 
-                 shape_types="edge vertex">
++          shape_types="edge vertex">
 +          <validator id="PartSet_DifferentObjects"/>
 +          <validator id="SketchPlugin_DistanceAttr" parameters="ConstraintEntityA"/>
 +          <validator id="SketchPlugin_ShapeValidator" parameters="ConstraintEntityA"/>
 +          <validator id="GeomValidators_EdgeOrVertex"/>
 +        </sketch_shape_selector>
++ <!--
++ TODO(nds): v1.0.2, master  
+                           shape_types="edge vertex">
+                       <validator id="PartSet_DifferentObjects"/>
+       <validator id="SketchPlugin_DistanceAttr" parameters="ConstraintEntityA"/>
+       <selection_filter id="MultiFilter" parameters="line,vertex"/>
+     </sketch_shape_selector>
+               
+         <sketch-2dpoint_selector id="ConstraintFlyoutValuePnt" internal="1" obligatory="0"/>
++ -->
          
 -              <doublevalue_editor label="Value" tooltip="Distance" id="ConstraintValue" default="computed" min="0">
 +        <sketch-2dpoint_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"/>
          </doublevalue_editor>
          
          <doublevalue_editor label="Value" tooltip="Radius" id="ConstraintValue" default="computed"/>
          <validator id="PartSet_RadiusValidator"/>
        </feature>
 -      <!--  SketchConstraintParallel  -->
 +    <!--  SketchConstraintParallel  -->
        <feature id="SketchConstraintParallel" title="Parallel" tooltip="Create constraint defining two parallel lines" icon=":icons/parallel.png">
 +        <sketch_constraint_shape_selector id="ConstraintEntityA" 
 +            label="First line" tooltip="Select a line" shape_types="edge">
 +            <validator id="GeomValidators_Edge" parameters="line"/>
 +            <validator id="SketchPlugin_ShapeValidator" parameters="ConstraintEntityB"/>
 +        </sketch_constraint_shape_selector>
 +        
 +        <sketch_constraint_shape_selector id="ConstraintEntityB" label="Last line" tooltip="Select a line" 
 +            shape_types="edge">
 +            <validator id="GeomValidators_Edge" parameters="line"/>
 +            <validator id="PartSet_DifferentObjects"/>
 +            <validator id="SketchPlugin_ShapeValidator" parameters="ConstraintEntityA"/>
 +        </sketch_constraint_shape_selector>
 +        
++<!--  
++  TODO(nds): v1.0.2, master  
+               <sketch_constraint_shape_selector id="ConstraintEntityA" 
+                       label="First line" tooltip="Select a line" shape_types="edge">
+                       <selection_filter id="EdgeFilter" parameters="line"/>
+               </sketch_constraint_shape_selector>
+               
+               <sketch_constraint_shape_selector id="ConstraintEntityB" label="Last line" tooltip="Select a line" 
+                       shape_types="edge">
+                       <selection_filter id="EdgeFilter" parameters="line"/>
+                       <validator id="PartSet_DifferentObjects"/>
+               </sketch_constraint_shape_selector>
+               
+         <sketch-2dpoint_selector id="ConstraintFlyoutValuePnt" internal="1" obligatory="0"/>
++-->
          <validator id="PartSet_ParallelValidator"/>
        </feature>
 -      <!--  SketchConstraintPerpendicular  -->
 -      <feature id="SketchConstraintPerpendicular" title="Perpendicular" tooltip="Create constraint defining two perpendicular lines" icon=":icons/perpendicular.png">
 +    <!--  SketchConstraintPerpendicular  -->
-       <feature id="SketchConstraintPerpendicular" title="Perpendicular" tooltip="Create constraint defining two perpendicular lines" icon=":icons/perpendicular.png">
++      <feature id="SketchConstraintPerpendicular" title="Perpendicular" 
++        tooltip="Create constraint defining two perpendicular lines" 
++        icon=":icons/perpendicular.png">
 +        <sketch_constraint_shape_selector id="ConstraintEntityA" 
 +            label="First line" tooltip="Select an line" 
 +            shape_types="edge">
 +          <validator id="SketchPlugin_ShapeValidator" parameters="ConstraintEntityB"/>
 +            <validator id="GeomValidators_Edge" parameters="line"/>
 +        </sketch_constraint_shape_selector>
 +        
 +        <sketch_constraint_shape_selector id="ConstraintEntityB" 
 +            label="Last line" tooltip="Select an line" 
 +            shape_types="edge">
 +            <validator id="PartSet_DifferentObjects"/>
 +          <validator id="SketchPlugin_ShapeValidator" parameters="ConstraintEntityA"/>
 +            <validator id="GeomValidators_Edge" parameters="line"/>
 +        </sketch_constraint_shape_selector>
++<!--  
++  TODO(nds): v1.0.2, master
+               <sketch_constraint_shape_selector id="ConstraintEntityA" 
+                       label="First line" tooltip="Select an line" 
+                       shape_types="edge">
+       <selection_filter id="EdgeFilter" parameters="line"/>
+     </sketch_constraint_shape_selector>
+               
+               <sketch_constraint_shape_selector id="ConstraintEntityB" 
+                       label="Last line" tooltip="Select an line" 
+                       shape_types="edge">
+                       <validator id="PartSet_DifferentObjects"/>
+       <selection_filter id="EdgeFilter" parameters="line"/>
+     </sketch_constraint_shape_selector>
++-->
          <validator id="PartSet_PerpendicularValidator"/>
        </feature>
 -      <!--  SketchConstraintRigid  -->
 +    <!--  SketchConstraintRigid  -->
        <feature id="SketchConstraintRigid" title="Fixed" tooltip="Fix an object" icon=":icons/fixed.png">
          <shape_selector id="ConstraintEntityA" label="Object" tooltip="Select an object" 
 -                      shape_types="edge vertex">
 -                  <validator id="SketchPlugin_ResultPoint"/>
 -                      <validator id="SketchPlugin_ResultLine"/>
 -                      <validator id="SketchPlugin_ResultArc"/>
 -              </shape_selector>
 -          <validator id="PartSet_RigidValidator"/>
 +            shape_types="edge vertex">
 +          <validator id="PartSet_SketchEntityValidator" parameters="SketchPoint,SketchLine,SketchCircle,SketchArc"/>
 +        </shape_selector>
 +        <validator id="PartSet_RigidValidator"/>
 +      </feature>
 +    <!--  SketchConstraintHorizontal  -->
 +      <feature id="SketchConstraintHorizontal" title="Horizontal" tooltip="Create constraint defining horizontal line" icon=":icons/horisontal.png">
 +        <sketch_constraint_shape_selector id="ConstraintEntityA" 
 +            label="Line" tooltip="Select a line" shape_types="edge">
 +            <validator id="GeomValidators_Edge" parameters="line"/>
 +        </sketch_constraint_shape_selector>
 +      </feature>
 +    <!--  SketchConstraintVertical  -->
 +      <feature id="SketchConstraintVertical" title="Vertical" tooltip="Create constraint defining vertical line" icon=":icons/vertical.png">
 +        <sketch_constraint_shape_selector id="ConstraintEntityA" 
 +            label="Line" tooltip="Select a line" shape_types="edge">
 +            <validator id="GeomValidators_Edge" parameters="line"/>
 +        </sketch_constraint_shape_selector>
 +      </feature>
 +    <!--  SketchConstraintEqual  -->
 +      <feature id="SketchConstraintEqual" title="Equal" tooltip="Create constraint defining equality of two objects" icon=":icons/equal.png">
 +        <sketch_constraint_shape_selector id="ConstraintEntityA" 
 +            label="First object" tooltip="Select line, circle or arc" shape_types="edge">
 +        </sketch_constraint_shape_selector>
 +        
 +        <sketch_constraint_shape_selector id="ConstraintEntityB"
 +            label="Last object" tooltip="Select line, circle or arc" shape_types="edge">
 +        </sketch_constraint_shape_selector>
 +      </feature>
 +    <!--  SketchConstraintTangent  -->
 +      <feature id="SketchConstraintTangent" title="Tangent" tooltip="Create constraint defining tangency of two objects" icon=":icons/tangent.png">
 +        <sketch_constraint_shape_selector id="ConstraintEntityA" 
 +            label="First object" tooltip="Select line or arc" shape_types="edge">
 +        </sketch_constraint_shape_selector>
 +        
 +        <sketch_constraint_shape_selector id="ConstraintEntityB"
 +            label="Last object" tooltip="Select line or arc" shape_types="edge">
 +        </sketch_constraint_shape_selector>
 +      </feature>
 +    <!--  SketchConstraintMirror  -->
 +      <feature
 +        id="SketchConstraintMirror"
 +        title="Mirror"
 +        tooltip="Create constraint mirroring group of objects"
 +        internal="1" />
 +    </group>
 +    <group id="Edit">
 +      <!--  SketchConstraintFillet  -->
 +      <feature id="SketchConstraintFillet" title="Fillet" tooltip="Create constraint defining fillet between two objects" icon=":icons/fillet.png">
 +        <sketch_constraint_shape_selector id="ConstraintEntityA" 
 +            label="First object" tooltip="Select line or arc" shape_types="edge">
 +        </sketch_constraint_shape_selector>
 +
 +        <sketch_constraint_shape_selector id="ConstraintEntityB"
 +            label="Last object" tooltip="Select line or arc" shape_types="edge">
 +        </sketch_constraint_shape_selector>
 +
 +        <doublevalue_editor label="Value" tooltip="Fillet radius" id="ConstraintValue" default="0" min="0">
 +          <validator id="GeomValidators_Positive"/>
 +        </doublevalue_editor>
        </feature>
      </group>
    </workbench>
index b650cbdabee544b8d56a85a3242adaf72f912dda,3cb51724764bb3d49f163e25583e4cb04aa9a209..05171749b3acb6ac241f6e57aada2fa2994e468d
@@@ -603,492 -540,6 +603,492 @@@ bool SketchSolver_ConstraintGroup::chan
    return true;
  }
  
-       std::list<AttributePtr> aPoints = aBaseFeature->data()->attributes(GeomDataAPI_Point2D::type());
 +// ============================================================================
 +//  Function: changeMirrorConstraint
 +//  Class:    SketchSolver_ConstraintGroup
 +//  Purpose:  create/update the "Mirror" constraint in the group
 +// ============================================================================
 +bool SketchSolver_ConstraintGroup::changeMirrorConstraint(
 +    std::shared_ptr<SketchPlugin_Constraint> theConstraint)
 +{
 +  DataPtr aConstrData = theConstraint->data();
 +
 +  // Search this constraint in the current group to update it
 +  ConstraintMap::const_iterator aConstrMapIter = myConstraintMap.find(theConstraint);
 +  std::vector<Slvs_Constraint>::iterator aConstrIter;
 +  if (aConstrMapIter != myConstraintMap.end()) {
 +    int aConstrPos = Search(aConstrMapIter->second.front(), myConstraints);
 +    aConstrIter = myConstraints.begin() + aConstrPos;
 +  }
 +
 +  // Get constraint type and verify the constraint parameters are correct
 +  SketchSolver_Constraint aConstraint(theConstraint);
 +  int aConstrType = aConstraint.getType();
 +  if (aConstrType == SLVS_C_UNKNOWN
 +      || (aConstrMapIter != myConstraintMap.end() && aConstrIter->type != aConstrType))
 +    return false;
 +  const std::vector<std::string>& aConstraintAttributes = aConstraint.getAttributes();
 +
 +  Slvs_hEntity aMirrorLineEnt = SLVS_E_UNKNOWN;
 +  AttributeRefAttrPtr aConstrAttr = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(
 +      aConstrData->attribute(aConstraintAttributes[0]));
 +  if (!aConstrAttr)
 +    return false;
 +
 +  // Convert the object of the attribute to the feature
 +  FeaturePtr aMirrorLineFeat;
 +  if (aConstrAttr->isObject() && aConstrAttr->object()) {
 +    ResultConstructionPtr aRC = std::dynamic_pointer_cast<ModelAPI_ResultConstruction>(
 +        aConstrAttr->object());
 +    if (!aRC)
 +      return false;
 +    std::shared_ptr<ModelAPI_Document> aDoc = aRC->document();
 +    aMirrorLineFeat = aDoc->feature(aRC);
 +  }
 +  aMirrorLineEnt = aConstrAttr->isObject() ?
 +      changeEntityFeature(aMirrorLineFeat) : changeEntity(aConstrAttr->attr());
 +
 +  if (aConstrMapIter == myConstraintMap.end()) { // Add new constraint
 +    // Append symmetric constraint for each point of mirroring features
 +    AttributeRefListPtr aBaseRefList = std::dynamic_pointer_cast<ModelAPI_AttributeRefList>(
 +        aConstrData->attribute(aConstraintAttributes[1]));
 +    AttributeRefListPtr aMirroredRefList = std::dynamic_pointer_cast<ModelAPI_AttributeRefList>(
 +        aConstrData->attribute(aConstraintAttributes[2]));
 +    if (!aBaseRefList || !aMirroredRefList)
 +      return false;
 +
 +    std::list<ObjectPtr> aBaseList = aBaseRefList->list();
 +    std::list<ObjectPtr> aMirroredList = aMirroredRefList->list();
 +    if (aBaseList.size() != aMirroredList.size())
 +      return false;
 +
 +    myConstraintMap[theConstraint] = std::vector<Slvs_hConstraint>();
 +
 +    FeaturePtr aBaseFeature, aMirrorFeature;
 +    ResultConstructionPtr aRC;
 +    std::list<ObjectPtr>::iterator aBaseIter = aBaseList.begin();
 +    std::list<ObjectPtr>::iterator aMirIter = aMirroredList.begin();
 +    for ( ; aBaseIter != aBaseList.end(); aBaseIter++, aMirIter++) {
 +      aRC = std::dynamic_pointer_cast<ModelAPI_ResultConstruction>(*aBaseIter);
 +      aBaseFeature = aRC ? aRC->document()->feature(aRC) :
 +          std::dynamic_pointer_cast<SketchPlugin_Feature>(*aBaseIter);
 +      aRC = std::dynamic_pointer_cast<ModelAPI_ResultConstruction>(*aMirIter);
 +      aMirrorFeature = aRC ? aRC->document()->feature(aRC) :
 +          std::dynamic_pointer_cast<SketchPlugin_Feature>(*aMirIter);
 +
 +      if (!aBaseFeature || !aMirrorFeature || 
 +          aBaseFeature->getKind() != aMirrorFeature->getKind())
 +        return false;
 +      Slvs_hEntity aBaseEnt = changeEntityFeature(aBaseFeature);
 +      Slvs_hEntity aMirrorEnt = changeEntityFeature(aMirrorFeature);
 +      // Make aMirrorEnt parameters to be symmetric with aBaseEnt
 +      makeMirrorEntity(aBaseEnt, aMirrorEnt, aMirrorLineEnt);
 +
 +      if (aBaseFeature->getKind() == SketchPlugin_Point::ID()) {
 +        Slvs_Constraint aConstraint = Slvs_MakeConstraint(++myConstrMaxID, myID, aConstrType,
 +            myWorkplane.h, 0.0, aBaseEnt, aMirrorEnt, aMirrorLineEnt, SLVS_E_UNKNOWN);
 +        myConstraints.push_back(aConstraint);
 +        myConstraintMap[theConstraint].push_back(aConstraint.h);
 +      } else {
 +        int aBasePos = Search(aBaseEnt, myEntities);
 +        int aMirrorPos = Search(aMirrorEnt, myEntities);
 +        if (aBaseFeature->getKind() == SketchPlugin_Line::ID()) {
 +          for (int ind = 0; ind < 2; ind++) {
 +            Slvs_Constraint aConstraint = Slvs_MakeConstraint(
 +                ++myConstrMaxID, myID, aConstrType, myWorkplane.h, 0.0,
 +                myEntities[aBasePos].point[ind], myEntities[aMirrorPos].point[ind],
 +                aMirrorLineEnt, SLVS_E_UNKNOWN);
 +            myConstraints.push_back(aConstraint);
 +            myConstraintMap[theConstraint].push_back(aConstraint.h);
 +          }
 +        } else if (aBaseFeature->getKind() == SketchPlugin_Circle::ID()) {
 +          Slvs_Constraint aConstraint = Slvs_MakeConstraint(
 +              ++myConstrMaxID, myID, aConstrType, myWorkplane.h, 0.0,
 +              myEntities[aBasePos].point[0], myEntities[aMirrorPos].point[0],
 +              aMirrorLineEnt, SLVS_E_UNKNOWN);
 +          myConstraints.push_back(aConstraint);
 +          myConstraintMap[theConstraint].push_back(aConstraint.h);
 +          // Additional constraint for equal radii
 +          Slvs_Constraint anEqRadConstr = Slvs_MakeConstraint(
 +              ++myConstrMaxID, myID, SLVS_C_EQUAL_RADIUS, myWorkplane.h, 0.0,
 +              SLVS_E_UNKNOWN, SLVS_E_UNKNOWN, aBaseEnt, aMirrorEnt);
 +          myConstraints.push_back(anEqRadConstr);
 +          myConstraintMap[theConstraint].push_back(anEqRadConstr.h);
 +        } else if (aBaseFeature->getKind() == SketchPlugin_Arc::ID()) {
 +          // Workaround to avoid problems in SolveSpace.
 +          // The symmetry of two arcs will be done using symmetry of three points on these arcs:
 +          // start point, end point, and any other point on the arc
 +          Slvs_hEntity aBaseArcPoints[3] = {
 +              myEntities[aBasePos].point[1],
 +              myEntities[aBasePos].point[2],
 +              SLVS_E_UNKNOWN};
 +          Slvs_hEntity aMirrorArcPoints[3] = { // indices of points of arc, center corresponds center, first point corresponds last point
 +              myEntities[aMirrorPos].point[2],
 +              myEntities[aMirrorPos].point[1],
 +              SLVS_E_UNKNOWN};
 +          Slvs_hEntity aBothArcs[2] = {aBaseEnt, aMirrorEnt};
 +          Slvs_hEntity aBothMiddlePoints[2];
 +          for (int i = 0; i < 2; i++) {
 +            double x, y;
 +            calculateMiddlePoint(aBothArcs[i], x, y);
 +            std::vector<Slvs_Param>::iterator aParamIter = myParams.end();
 +            Slvs_hParam u = changeParameter(x, aParamIter);
 +            Slvs_hParam v = changeParameter(y, aParamIter);
 +            Slvs_Entity aPoint = Slvs_MakePoint2d(++myEntityMaxID, myID, myWorkplane.h, u, v);
 +            myEntities.push_back(aPoint);
 +            aBothMiddlePoints[i] = aPoint.h;
 +            // additional constraint point-on-curve
 +            Slvs_Constraint aPonCircConstr = Slvs_MakeConstraint(
 +                ++myConstrMaxID, myID, SLVS_C_PT_ON_CIRCLE, myWorkplane.h, 0.0,
 +                aPoint.h, SLVS_E_UNKNOWN, aBothArcs[i], SLVS_E_UNKNOWN);
 +            myConstraints.push_back(aPonCircConstr);
 +            myConstraintMap[theConstraint].push_back(aPonCircConstr.h);
 +          }
 +
 +          aBaseArcPoints[2] = aBothMiddlePoints[0];
 +          aMirrorArcPoints[2] = aBothMiddlePoints[1];
 +          for (int ind = 0; ind < 3; ind++) {
 +            Slvs_Constraint aConstraint = Slvs_MakeConstraint(
 +                ++myConstrMaxID, myID, aConstrType, myWorkplane.h, 0.0,
 +                aBaseArcPoints[ind], aMirrorArcPoints[ind], aMirrorLineEnt, SLVS_E_UNKNOWN);
 +            myConstraints.push_back(aConstraint);
 +            myConstraintMap[theConstraint].push_back(aConstraint.h);
 +          }
 +        }
 +      }
 +    }
 +
 +    // Set the mirror line unchanged during constraint recalculation
 +    int aMirrorLinePos = Search(aMirrorLineEnt, myEntities);
 +    Slvs_Constraint aRigidStart = Slvs_MakeConstraint(
 +        ++myConstrMaxID, myID, SLVS_C_WHERE_DRAGGED, myWorkplane.h, 0,
 +        myEntities[aMirrorLinePos].point[0], SLVS_E_UNKNOWN, SLVS_E_UNKNOWN, SLVS_E_UNKNOWN);
 +    myConstraints.push_back(aRigidStart);
 +    myConstraintMap[theConstraint].push_back(aRigidStart.h);
 +    Slvs_Constraint aRigidEnd = Slvs_MakeConstraint(
 +        ++myConstrMaxID, myID, SLVS_C_WHERE_DRAGGED, myWorkplane.h, 0,
 +        myEntities[aMirrorLinePos].point[1], SLVS_E_UNKNOWN, SLVS_E_UNKNOWN, SLVS_E_UNKNOWN);
 +    myConstraints.push_back(aRigidEnd);
 +    myConstraintMap[theConstraint].push_back(aRigidEnd.h);
 +
 +    // Add temporary constraints for initial objects to be unchanged
 +    for (aBaseIter = aBaseList.begin(); aBaseIter != aBaseList.end(); aBaseIter++) {
 +      aRC = std::dynamic_pointer_cast<ModelAPI_ResultConstruction>(*aBaseIter);
 +      aBaseFeature = aRC ? aRC->document()->feature(aRC) :
 +          std::dynamic_pointer_cast<SketchPlugin_Feature>(*aBaseIter);
 +      if (!aBaseFeature) continue;
-         aBaseFeature[indAttr]->data()->attributes(GeomDataAPI_Point2D::type());
++      std::list<AttributePtr> aPoints = aBaseFeature->data()->attributes(GeomDataAPI_Point2D::typeId());
 +      std::list<AttributePtr>::iterator anIt = aPoints.begin();
 +      for ( ; anIt != aPoints.end(); anIt++) {
 +        // Arcs are fixed by center and start points only (to avoid solving errors in SolveSpace)
 +        if (aBaseFeature->getKind() == SketchPlugin_Arc::ID() &&
 +            (*anIt)->id() == SketchPlugin_Arc::END_ID())
 +          continue;
 +        addTemporaryConstraintWhereDragged(*anIt);
 +      }
 +    }
 +  }
 +  return true;
 +}
 +
 +// ============================================================================
 +//  Function: changeFilletConstraint
 +//  Class:    SketchSolver_ConstraintGroup
 +//  Purpose:  create/update the "Fillet" constraint in the group
 +// ============================================================================
 +bool SketchSolver_ConstraintGroup::changeFilletConstraint(
 +    std::shared_ptr<SketchPlugin_Constraint> theConstraint)
 +{
 +  DataPtr aConstrData = theConstraint->data();
 +
 +  // Search this constraint in the current group to update it
 +  ConstraintMap::const_iterator aConstrMapIter = myConstraintMap.find(theConstraint);
 +  std::vector<Slvs_Constraint>::iterator aConstrIter;
 +  if (aConstrMapIter != myConstraintMap.end()) {
 +    int aConstrPos = Search(aConstrMapIter->second.front(), myConstraints);
 +    aConstrIter = myConstraints.begin() + aConstrPos;
 +  }
 +
 +  // Get constraint type and verify the constraint parameters are correct
 +  SketchSolver_Constraint aConstraint(theConstraint);
 +  int aConstrType = aConstraint.getType();
 +  if (aConstrType == SLVS_C_UNKNOWN)
 +    return false;
 +  const std::vector<std::string>& aConstraintAttributes = aConstraint.getAttributes();
 +
 +  // Obtain hEntity for basic objects of fillet
 +  Slvs_hEntity aBaseObject[2];
 +  FeaturePtr aBaseFeature[2];
 +  for (unsigned int indAttr = 0; indAttr < 2; indAttr++) {
 +    AttributeRefAttrPtr aConstrAttr = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(
 +        aConstrData->attribute(aConstraintAttributes[indAttr]));
 +    if (!aConstrAttr)
 +      return false;
 +    if (aConstrAttr->isObject() && aConstrAttr->object()) {
 +      ResultConstructionPtr aRC = std::dynamic_pointer_cast<ModelAPI_ResultConstruction>(
 +          aConstrAttr->object());
 +      if (!aRC)
 +        return false;
 +      std::shared_ptr<ModelAPI_Document> aDoc = aRC->document();
 +      aBaseFeature[indAttr] = aDoc->feature(aRC);
 +    }
 +    aBaseObject[indAttr] = aConstrAttr->isObject() ?
 +        changeEntityFeature(aBaseFeature[indAttr]) : changeEntity(aConstrAttr->attr());
 +  }
 +  // Check the base entities have a coincident point
 +  int aBaseObjInd[2] = {
 +      Search(aBaseObject[0], myEntities),
 +      Search(aBaseObject[1], myEntities)
 +    };
 +  int aShift[2] = { // shift for calculating correct start and end points for different types of objects
 +      myEntities[aBaseObjInd[0]].type == SLVS_E_ARC_OF_CIRCLE ? 1 : 0,
 +      myEntities[aBaseObjInd[1]].type == SLVS_E_ARC_OF_CIRCLE ? 1 : 0,
 +    };
 +  Slvs_hEntity aFirstObjPoints[2] = { // indices of start and end point of first object
 +      myEntities[aBaseObjInd[0]].point[aShift[0]],
 +      myEntities[aBaseObjInd[0]].point[1+aShift[0]]
 +    };
 +  Slvs_hEntity aSecondObjPoints[2] = { // indices of start and end point of second object
 +      myEntities[aBaseObjInd[1]].point[aShift[1]],
 +      myEntities[aBaseObjInd[1]].point[1+aShift[1]]
 +    };
 +  bool isCoincidentFound = false;
 +  int aBaseCoincInd[2] = {0, 0}; // indices in aFirstObjPoint and aSecondObjPoint identifying coincident points
 +  std::vector<std::set<Slvs_hEntity> >::iterator aCPIter = myCoincidentPoints.begin();
 +  for ( ; aCPIter != myCoincidentPoints.end() && !isCoincidentFound; aCPIter++)
 +    for (int ind1 = 0; ind1 < 2 && !isCoincidentFound; ind1++)
 +      for (int ind2 = 0; ind2 < 2 && !isCoincidentFound; ind2++)
 +        if (aCPIter->find(aFirstObjPoints[ind1]) != aCPIter->end() &&
 +            aCPIter->find(aSecondObjPoints[ind2]) != aCPIter->end()) {
 +          aBaseCoincInd[0] = ind1;
 +          aBaseCoincInd[1] = ind2;
 +          isCoincidentFound = true;
 +        }
 +  if (!isCoincidentFound) {
 +    // There is no coincident points between objects. Generate error message
 +    Events_Error::send(SketchSolver_Error::NO_COINCIDENT_POINTS(), this);
 +    return false;
 +  }
 +
 +  // Create fillet entities
 +  // - first object is placed on the first base 
 +  // - second object is on the second base 
 +  // - third object is a filleting arc
 +  static const int aNbFilletEnt = 3;
 +  Slvs_hEntity aFilletEnt[aNbFilletEnt];
 +  int aFilletObjInd[aNbFilletEnt];
 +  AttributeRefListPtr aFilletRefList = std::dynamic_pointer_cast<ModelAPI_AttributeRefList>(
 +      aConstrData->attribute(aConstraintAttributes[2]));
 +  if (!aFilletRefList)
 +    return false;
 +  std::list<ObjectPtr> aFilletList = aFilletRefList->list();
 +  if (aFilletList.size() < aNbFilletEnt)
 +    return false;
 +  FeaturePtr aFilletFeature;
 +  ResultConstructionPtr aRC;
 +  std::list<ObjectPtr>::iterator aFilIter = aFilletList.begin();
 +  for (int indEnt = 0; aFilIter != aFilletList.end(); aFilIter++, indEnt++) {
 +    aRC = std::dynamic_pointer_cast<ModelAPI_ResultConstruction>(*aFilIter);
 +    aFilletFeature = aRC ? aRC->document()->feature(aRC) :
 +        std::dynamic_pointer_cast<SketchPlugin_Feature>(*aFilIter);
 +    if (!aFilletFeature)
 +      return false;
 +    aFilletEnt[indEnt] = changeEntityFeature(aFilletFeature);
 +    aFilletObjInd[indEnt] = Search(aFilletEnt[indEnt], myEntities);
 +  }
 +  // At first time, for correct result, move floating points of fillet on the middle points of base objects
 +  if (myConstraintMap.find(theConstraint) == myConstraintMap.end()) {
 +    double anArcPoints[6];
 +    for (int indEnt = 0; indEnt < aNbFilletEnt - 1; indEnt++) {
 +      int anIndShift = myEntities[aFilletObjInd[indEnt]].type == SLVS_E_ARC_OF_CIRCLE ? 1 : 0;
 +      int aPointsPos[2] = {
 +          Search(myEntities[aFilletObjInd[indEnt]].point[anIndShift], myEntities),
 +          Search(myEntities[aFilletObjInd[indEnt]].point[1+anIndShift], myEntities)
 +        };
 +      int aParamPos[2] = {
 +          Search(myEntities[aPointsPos[0]].param[0], myParams),
 +          Search(myEntities[aPointsPos[1]].param[0], myParams)
 +        };
 +      int anIndex = aParamPos[aBaseCoincInd[indEnt]];
 +      if (anIndShift == 0) {
 +        myParams[anIndex].val =
 +            0.5 * (myParams[aParamPos[0]].val + myParams[aParamPos[1]].val);
 +        myParams[1 + anIndex].val =
 +            0.5 * (myParams[1 + aParamPos[0]].val + myParams[1 + aParamPos[1]].val);
 +      } else { // place the changed point on the arc
 +        double x = 0, y = 0;
 +        calculateMiddlePoint(aFilletEnt[indEnt], x, y);
 +        myParams[anIndex].val = x;
 +        myParams[1 + anIndex].val = y;
 +      }
 +      anArcPoints[indEnt*2+2] = myParams[anIndex].val;
 +      anArcPoints[indEnt*2+3] = myParams[1 + anIndex].val;
 +    }
 +    anArcPoints[0] = 0.5 * (anArcPoints[2] + anArcPoints[4]);
 +    anArcPoints[1] = 0.5 * (anArcPoints[3] + anArcPoints[5]);
 +    for (int indArcPt = 0; indArcPt < 3; indArcPt++) {
 +      int aPtPos = Search(myEntities[aFilletObjInd[2]].point[indArcPt], myEntities);
 +      int aParamPos = Search(myEntities[aPtPos].param[0], myParams);
 +      myParams[aParamPos].val = anArcPoints[indArcPt * 2];
 +      myParams[aParamPos + 1].val = anArcPoints[indArcPt * 2 + 1];
 +    }
 +  }
 +
 +  // Check the fillet arc which point to be connected to
 +  bool isArcInversed = false; // indicates that start and end points of arc should be connected to second and first object respectively
 +  Slvs_hEntity hEnt = myEntities[aFilletObjInd[2]].point[1];
 +  int aPos = Search(hEnt, myEntities);
 +  Slvs_hParam anArcStartPoint = myEntities[aPos].param[0];
 +  aPos = Search(anArcStartPoint, myParams);
 +  double anArcPtCoord[2] = {myParams[aPos].val, myParams[aPos+1].val};
 +  double aSqDistances[2];
 +  int aPtInd;
 +  for (int indEnt = 0; indEnt < aNbFilletEnt - 1; indEnt++) {
 +    aPtInd = aBaseCoincInd[indEnt]+aShift[indEnt];
 +    hEnt = myEntities[aFilletObjInd[indEnt]].point[aPtInd];
 +    aPos = Search(hEnt, myEntities);
 +    Slvs_hParam anObjectPoint = myEntities[aPos].param[0];
 +    aPos = Search(anObjectPoint, myParams);
 +    double aPtCoord[2] = {myParams[aPos].val, myParams[aPos+1].val};
 +    aSqDistances[indEnt] = 
 +        (anArcPtCoord[0] - aPtCoord[0]) * (anArcPtCoord[0] - aPtCoord[0]) +
 +        (anArcPtCoord[1] - aPtCoord[1]) * (anArcPtCoord[1] - aPtCoord[1]);
 +  }
 +  if (aSqDistances[1] < aSqDistances[0])
 +    isArcInversed = true;
 +
 +  // Create list of constraints to generate fillet
 +  std::vector<Slvs_hConstraint> aConstrList;
 +  bool isExists = myConstraintMap.find(theConstraint) != myConstraintMap.end(); // constraint already exists
 +  std::vector<Slvs_hConstraint>::iterator aCMapIter =
 +    isExists ? myConstraintMap[theConstraint].begin() : aConstrList.begin();
 +  int aCurConstrPos = isExists ? Search(*aCMapIter, myConstraints) : 0;
 +  for (int indEnt = 0; indEnt < aNbFilletEnt - 1; indEnt++) {
 +    // one point of fillet object should be coincident with the point on base, non-coincident with another base object
 +    aPtInd = 1-aBaseCoincInd[indEnt]+aShift[indEnt]; // (1-aBaseCoincInd[indEnt]) = index of non-coincident point, aShift is used to process all types of shapes
 +    Slvs_hEntity aPtBase = myEntities[aBaseObjInd[indEnt]].point[aPtInd];
 +    Slvs_hEntity aPtFillet = myEntities[aFilletObjInd[indEnt]].point[aPtInd];
 +    if (isExists) {
 +      myConstraints[aCurConstrPos].ptA = aPtBase;
 +      myConstraints[aCurConstrPos].ptB = aPtFillet;
 +      aCMapIter++;
 +      aCurConstrPos = Search(*aCMapIter, myConstraints);
 +    } else {
 +      Slvs_Constraint aCoincConstr = Slvs_MakeConstraint(
 +          ++myConstrMaxID, myID, SLVS_C_POINTS_COINCIDENT, myWorkplane.h,
 +          0, aPtBase, aPtFillet, SLVS_E_UNKNOWN, SLVS_E_UNKNOWN);
 +      myConstraints.push_back(aCoincConstr);
 +      aConstrList.push_back(aCoincConstr.h);
 +    }
 +
 +    // another point of fillet object should be placed on the base object
 +    Slvs_Constraint aPonCurveConstr;
 +    int aTangentType;
 +    if (myEntities[aFilletObjInd[indEnt]].type == SLVS_E_ARC_OF_CIRCLE) {
 +      // centers of arcs should be coincident
 +      aPtBase = myEntities[aBaseObjInd[indEnt]].point[0];
 +      aPtFillet = myEntities[aFilletObjInd[indEnt]].point[0];
 +      if (isExists) {
 +        myConstraints[aCurConstrPos].ptA = aPtBase;
 +        myConstraints[aCurConstrPos].ptB = aPtFillet;
 +        aCMapIter++;
 +        aCurConstrPos = Search(*aCMapIter, myConstraints);
 +      } else {
 +        aPonCurveConstr = Slvs_MakeConstraint(
 +            ++myConstrMaxID, myID, SLVS_C_POINTS_COINCIDENT, myWorkplane.h,
 +            0, aPtBase, aPtFillet, SLVS_E_UNKNOWN, SLVS_E_UNKNOWN);
 +      }
 +      aPtFillet = myEntities[aFilletObjInd[indEnt]].point[1+aBaseCoincInd[indEnt]]; // !!! will be used below
 +      aTangentType = SLVS_C_CURVE_CURVE_TANGENT;
 +    } else {
 +      aPtInd = aBaseCoincInd[indEnt];
 +      aPtFillet = myEntities[aFilletObjInd[indEnt]].point[aPtInd];
 +      if (isExists) {
 +        myConstraints[aCurConstrPos].ptA = aPtFillet;
 +        aCMapIter++;
 +        aCurConstrPos = Search(*aCMapIter, myConstraints);
 +      } else {
 +        aPonCurveConstr = Slvs_MakeConstraint(
 +            ++myConstrMaxID, myID, SLVS_C_PT_ON_LINE, myWorkplane.h,
 +            0, aPtFillet, SLVS_E_UNKNOWN, aBaseObject[indEnt], SLVS_E_UNKNOWN);
 +      }
 +      aTangentType = SLVS_C_ARC_LINE_TANGENT;
 +    }
 +    if (!isExists) {
 +      myConstraints.push_back(aPonCurveConstr);
 +      aConstrList.push_back(aPonCurveConstr.h);
 +    }
 +
 +    // Bound point of fillet arc should be tangently coincident with a bound point of fillet object
 +    aPtInd = 1 + (isArcInversed ? 1-indEnt : indEnt);
 +    Slvs_hEntity aPtArc = myEntities[aFilletObjInd[2]].point[aPtInd];
 +    if (isExists) {
 +      myConstraints[aCurConstrPos].ptA = aPtArc;
 +      myConstraints[aCurConstrPos].ptB = aPtFillet;
 +      aCMapIter++;
 +      aCurConstrPos = Search(*aCMapIter, myConstraints);
 +      myConstraints[aCurConstrPos].entityA = aFilletEnt[2];
 +      myConstraints[aCurConstrPos].entityB = aFilletEnt[indEnt];
 +      myConstraints[aCurConstrPos].other = (isArcInversed ? 1-indEnt : indEnt);
 +      aCMapIter++;
 +      aCurConstrPos = Search(*aCMapIter, myConstraints);
 +    } else {
 +      Slvs_Constraint aCoincConstr = Slvs_MakeConstraint(
 +          ++myConstrMaxID, myID, SLVS_C_POINTS_COINCIDENT, myWorkplane.h,
 +          0, aPtArc, aPtFillet, SLVS_E_UNKNOWN, SLVS_E_UNKNOWN);
 +      myConstraints.push_back(aCoincConstr);
 +      aConstrList.push_back(aCoincConstr.h);
 +      Slvs_Constraint aTangency = Slvs_MakeConstraint(
 +          ++myConstrMaxID, myID, aTangentType, myWorkplane.h,
 +          0, SLVS_E_UNKNOWN, SLVS_E_UNKNOWN, aFilletEnt[2], aFilletEnt[indEnt]);
 +      aTangency.other = (isArcInversed ? 1-indEnt : indEnt);
 +      aTangency.other2 = aTangentType == SLVS_C_CURVE_CURVE_TANGENT ? aBaseCoincInd[indEnt] : 0;
 +      myConstraints.push_back(aTangency);
 +      aConstrList.push_back(aTangency.h);
 +    }
 +  }
 +
 +  // Additional constraint for fillet diameter
 +  double aRadius = 0.0;  // scalar value of the constraint
 +  AttributeDoublePtr aDistAttr = std::dynamic_pointer_cast<ModelAPI_AttributeDouble>(
 +      aConstrData->attribute(SketchPlugin_Constraint::VALUE()));
 +  aRadius = aDistAttr->value();
 +  if (isExists) {
 +    myConstraints[aCurConstrPos].entityA = aFilletEnt[2];
 +    myConstraints[aCurConstrPos].valA = aRadius * 2.0;
 +    aCMapIter++;
 +  } else {
 +    Slvs_Constraint aDiamConstr = Slvs_MakeConstraint(
 +        ++myConstrMaxID, myID, SLVS_C_DIAMETER, myWorkplane.h, aRadius * 2.0,
 +        SLVS_E_UNKNOWN, SLVS_E_UNKNOWN, aFilletEnt[2], SLVS_E_UNKNOWN);
 +    myConstraints.push_back(aDiamConstr);
 +    aConstrList.push_back(aDiamConstr.h);
 +
 +    myConstraintMap[theConstraint] = aConstrList;
 +  }
 +
 +  // Additional temporary constraints for base objects to be fixed
 +  for (unsigned int indAttr = 0; indAttr < 2; indAttr++) {
 +    if (!aBaseFeature[indAttr]) {
 +      AttributeRefAttrPtr aConstrAttr = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(
 +          aConstrData->attribute(aConstraintAttributes[indAttr]));
 +      addTemporaryConstraintWhereDragged(aConstrAttr->attr());
 +      continue;
 +    }
 +    std::list<AttributePtr> anAttributes =
++        aBaseFeature[indAttr]->data()->attributes(GeomDataAPI_Point2D::typeId());
 +    std::list<AttributePtr>::iterator anIt = anAttributes.begin();
 +    for ( ; anIt != anAttributes.end(); anIt++) {
 +      // Arc should be fixed by center and start points only (to avoid "conflicting constraints" message)
 +      if (aBaseFeature[indAttr]->getKind() == SketchPlugin_Arc::ID() &&
 +          (*anIt)->id() == SketchPlugin_Arc::END_ID())
 +        continue;
 +      addTemporaryConstraintWhereDragged(*anIt);
 +    }
 +  }
 +  return true;
 +}
 +
  // ============================================================================
  //  Function: changeEntity
  //  Class:    SketchSolver_ConstraintGroup