Salome HOME
Task 2.3: Creation of Intersection
[modules/shaper.git] / src / PartSet / PartSet_Validators.cpp
index 6922bb6b484bd819f93e13dba14a236261e284c5..49f89d9c033ac2a308aade1b1a558a10846ac122 100755 (executable)
@@ -1,8 +1,22 @@
-// Copyright (C) 2014-20xx CEA/DEN, EDF R&D
-
-// File:        PartSet_Validators.cpp
-// Created:     09 July 2014
-// Author:      Vitaly SMETANNIKOV
+// Copyright (C) 2014-2017  CEA/DEN, EDF R&D
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.salome-platform.org/ or
+// email : webmaster.salome@opencascade.com<mailto:webmaster.salome@opencascade.com>
+//
 
 #include "PartSet_Validators.h"
 
@@ -19,6 +33,9 @@
 #include <ModuleBase_OperationFeature.h>
 #include <ModuleBase_ViewerPrs.h>
 
+#include <GeomDataAPI_Point2D.h>
+#include <GeomAPI_Pnt2d.h>
+
 #include <Events_InfoMessage.h>
 
 #include <ModelAPI_AttributeRefAttr.h>
 #include <ModelAPI_AttributeSelectionList.h>
 #include <ModelAPI_AttributeRefList.h>
 #include <ModelAPI_Object.h>
+#include <ModelAPI_ResultCompSolid.h>
 #include <ModelAPI_Session.h>
 #include <ModelAPI_Tools.h>
 
 #include <SketchPlugin_Sketch.h>
 #include <SketchPlugin_ConstraintCoincidence.h>
 #include <SketchPlugin_Arc.h>
+#include <SketchPlugin_Point.h>
 #include <GeomAPI_Edge.h>
 
 #include <list>
@@ -82,21 +101,23 @@ std::shared_ptr<GeomAPI_Pln> sketcherPlane(ModuleBase_Operation* theOperation)
 {
   std::shared_ptr<GeomAPI_Pln> aEmptyPln;
   if (theOperation) {
-    ModuleBase_OperationFeature* aFeatureOp = dynamic_cast<ModuleBase_OperationFeature*>(theOperation);
+    ModuleBase_OperationFeature* aFeatureOp =
+      dynamic_cast<ModuleBase_OperationFeature*>(theOperation);
     if (aFeatureOp) {
-      CompositeFeaturePtr aFeature = 
+      CompositeFeaturePtr aFeature =
         std::dynamic_pointer_cast<ModelAPI_CompositeFeature>(aFeatureOp->feature());
       if (aFeature && (aFeature->getKind() == SketchPlugin_Sketch::ID()))
         return PartSet_Tools::sketchPlane(aFeature);
     }
   }
-  return aEmptyPln; 
+  return aEmptyPln;
 }
 
 
 bool isEmptySelectionValid(ModuleBase_Operation* theOperation)
 {
-  ModuleBase_OperationFeature* aFeatureOp = dynamic_cast<ModuleBase_OperationFeature*>(theOperation);
+  ModuleBase_OperationFeature* aFeatureOp =
+    dynamic_cast<ModuleBase_OperationFeature*>(theOperation);
   // during the create operation empty selection is always valid
   if (!aFeatureOp->isEditOperation()) {
     return true;
@@ -106,15 +127,17 @@ bool isEmptySelectionValid(ModuleBase_Operation* theOperation)
       std::shared_ptr<GeomAPI_Pln> aPlane = sketcherPlane(theOperation);
       if (aPlane.get())
         return true;
-      else 
+      else
         return false;
     }
-    else// in edit operation an empty selection is always valid, performed for re-entrant operrations
+    else
+      // in edit operation an empty selection is always valid, performed for re-entrant operrations
       return true;
   }
 }
 
-bool PartSet_DistanceSelection::isValid(const ModuleBase_ISelection* theSelection, ModuleBase_Operation* theOperation) const
+bool PartSet_DistanceSelection::isValid(const ModuleBase_ISelection* theSelection,
+                                        ModuleBase_Operation* theOperation) const
 {
   if (theSelection->getSelected(ModuleBase_ISelection::Viewer).size() == 0) {
     return isEmptySelectionValid(theOperation);
@@ -124,7 +147,8 @@ bool PartSet_DistanceSelection::isValid(const ModuleBase_ISelection* theSelectio
   }
 }
 
-bool PartSet_LengthSelection::isValid(const ModuleBase_ISelection* theSelection, ModuleBase_Operation* theOperation) const
+bool PartSet_LengthSelection::isValid(const ModuleBase_ISelection* theSelection,
+                                      ModuleBase_Operation* theOperation) const
 {
   if (theSelection->getSelected(ModuleBase_ISelection::Viewer).size() == 0) {
     return isEmptySelectionValid(theOperation);
@@ -134,7 +158,8 @@ bool PartSet_LengthSelection::isValid(const ModuleBase_ISelection* theSelection,
   }
 }
 
-bool PartSet_PerpendicularSelection::isValid(const ModuleBase_ISelection* theSelection, ModuleBase_Operation* theOperation) const
+bool PartSet_PerpendicularSelection::isValid(const ModuleBase_ISelection* theSelection,
+                                             ModuleBase_Operation* theOperation) const
 {
   if (theSelection->getSelected(ModuleBase_ISelection::Viewer).size() == 0) {
     return isEmptySelectionValid(theOperation);
@@ -144,7 +169,8 @@ bool PartSet_PerpendicularSelection::isValid(const ModuleBase_ISelection* theSel
   }
 }
 
-bool PartSet_ParallelSelection::isValid(const ModuleBase_ISelection* theSelection, ModuleBase_Operation* theOperation) const
+bool PartSet_ParallelSelection::isValid(const ModuleBase_ISelection* theSelection,
+                                        ModuleBase_Operation* theOperation) const
 {
   if (theSelection->getSelected(ModuleBase_ISelection::Viewer).size() == 0) {
     return isEmptySelectionValid(theOperation);
@@ -154,12 +180,14 @@ bool PartSet_ParallelSelection::isValid(const ModuleBase_ISelection* theSelectio
   }
 }
 
-bool PartSet_RadiusSelection::isValid(const ModuleBase_ISelection* theSelection, ModuleBase_Operation* theOperation) const
+bool PartSet_RadiusSelection::isValid(const ModuleBase_ISelection* theSelection,
+                                      ModuleBase_Operation* theOperation) const
 {
   if (theSelection->getSelected(ModuleBase_ISelection::Viewer).size() == 0) {
     return isEmptySelectionValid(theOperation);
   } else {
-    QList<ModuleBase_ViewerPrsPtr> aList = theSelection->getSelected(ModuleBase_ISelection::Viewer);
+    QList<ModuleBase_ViewerPrsPtr> aList =
+      theSelection->getSelected(ModuleBase_ISelection::Viewer);
     int aCount = 0;
     foreach (ModuleBase_ViewerPrsPtr aPrs, aList) {
       const GeomShapePtr& aShape = aPrs->shape();
@@ -179,18 +207,33 @@ bool PartSet_RadiusSelection::isValid(const ModuleBase_ISelection* theSelection,
   }
 }
 
-bool PartSet_RigidSelection::isValid(const ModuleBase_ISelection* theSelection, ModuleBase_Operation* theOperation) const
+bool PartSet_RigidSelection::isValid(const ModuleBase_ISelection* theSelection,
+                                     ModuleBase_Operation* theOperation) const
 {
   if (theSelection->getSelected(ModuleBase_ISelection::Viewer).size() == 0) {
     return isEmptySelectionValid(theOperation);
   } else {
-    QList<ModuleBase_ViewerPrsPtr> aList = theSelection->getSelected(ModuleBase_ISelection::Viewer);
-    return (aList.count() == 1);
+    QList<ModuleBase_ViewerPrsPtr> aList =
+      theSelection->getSelected(ModuleBase_ISelection::Viewer);
+    int aCount = 0;
+    foreach (ModuleBase_ViewerPrsPtr aPrs, aList) {
+      ObjectPtr aObj = aPrs->object();
+      if (aObj.get()) {
+        FeaturePtr aFeature = ModelAPI_Feature::feature(aObj);
+        if (aFeature.get()) {
+          CompositeFeaturePtr aComp = ModelAPI_Tools::compositeOwner(aFeature);
+          if (aComp.get() && (aComp->getKind() == SketchPlugin_Sketch::ID()))
+            aCount++;
+        }
+      }
+    }
+    return (aCount == 1);
   }
 }
 
 
-bool PartSet_CoincidentSelection::isValid(const ModuleBase_ISelection* theSelection, ModuleBase_Operation* theOperation) const
+bool PartSet_CoincidentSelection::isValid(const ModuleBase_ISelection* theSelection,
+                                          ModuleBase_Operation* theOperation) const
 {
   if (theSelection->getSelected(ModuleBase_ISelection::Viewer).size() == 0) {
     return isEmptySelectionValid(theOperation);
@@ -202,7 +245,8 @@ bool PartSet_CoincidentSelection::isValid(const ModuleBase_ISelection* theSelect
   }
 }
 
-bool PartSet_HVDirSelection::isValid(const ModuleBase_ISelection* theSelection, ModuleBase_Operation* theOperation) const
+bool PartSet_HVDirSelection::isValid(const ModuleBase_ISelection* theSelection,
+                                     ModuleBase_Operation* theOperation) const
 {
   if (theSelection->getSelected(ModuleBase_ISelection::Viewer).size() == 0) {
     return isEmptySelectionValid(theOperation);
@@ -212,7 +256,8 @@ bool PartSet_HVDirSelection::isValid(const ModuleBase_ISelection* theSelection,
   }
 }
 
-bool PartSet_FilletSelection::isValid(const ModuleBase_ISelection* theSelection, ModuleBase_Operation* theOperation) const
+bool PartSet_FilletSelection::isValid(const ModuleBase_ISelection* theSelection,
+                                      ModuleBase_Operation* theOperation) const
 {
   if (theSelection->getSelected(ModuleBase_ISelection::Viewer).size() == 0) {
     return isEmptySelectionValid(theOperation);
@@ -222,7 +267,8 @@ bool PartSet_FilletSelection::isValid(const ModuleBase_ISelection* theSelection,
   }
 }
 
-bool PartSet_TangentSelection::isValid(const ModuleBase_ISelection* theSelection, ModuleBase_Operation* theOperation) const
+bool PartSet_TangentSelection::isValid(const ModuleBase_ISelection* theSelection,
+                                       ModuleBase_Operation* theOperation) const
 {
   if (theSelection->getSelected(ModuleBase_ISelection::Viewer).size() == 0) {
     return isEmptySelectionValid(theOperation);
@@ -259,7 +305,8 @@ bool PartSet_TangentSelection::isValid(const ModuleBase_ISelection* theSelection
   }
 }
 
-bool PartSet_AngleSelection::isValid(const ModuleBase_ISelection* theSelection, ModuleBase_Operation* theOperation) const
+bool PartSet_AngleSelection::isValid(const ModuleBase_ISelection* theSelection,
+                                     ModuleBase_Operation* theOperation) const
 {
   if (theSelection->getSelected(ModuleBase_ISelection::Viewer).size() == 0) {
     return isEmptySelectionValid(theOperation);
@@ -269,12 +316,14 @@ bool PartSet_AngleSelection::isValid(const ModuleBase_ISelection* theSelection,
   }
 }
 
-bool PartSet_EqualSelection::isValid(const ModuleBase_ISelection* theSelection, ModuleBase_Operation* theOperation) const
+bool PartSet_EqualSelection::isValid(const ModuleBase_ISelection* theSelection,
+                                     ModuleBase_Operation* theOperation) const
 {
   if (theSelection->getSelected(ModuleBase_ISelection::Viewer).size() == 0) {
     return isEmptySelectionValid(theOperation);
   } else {
-    QList<ModuleBase_ViewerPrsPtr> aList = theSelection->getSelected(ModuleBase_ISelection::Viewer);
+    QList<ModuleBase_ViewerPrsPtr> aList =
+      theSelection->getSelected(ModuleBase_ISelection::Viewer);
     int aCount = 0;
     int aType = 0;
     foreach (ModuleBase_ViewerPrsPtr aPrs, aList) {
@@ -305,7 +354,8 @@ bool PartSet_EqualSelection::isValid(const ModuleBase_ISelection* theSelection,
   }
 }
 
-bool PartSet_CollinearSelection::isValid(const ModuleBase_ISelection* theSelection, ModuleBase_Operation* theOperation) const
+bool PartSet_CollinearSelection::isValid(const ModuleBase_ISelection* theSelection,
+                                         ModuleBase_Operation* theOperation) const
 {
   if (theSelection->getSelected(ModuleBase_ISelection::Viewer).size() == 0) {
     return isEmptySelectionValid(theOperation);
@@ -315,12 +365,57 @@ bool PartSet_CollinearSelection::isValid(const ModuleBase_ISelection* theSelecti
   }
 }
 
-bool PartSet_MiddlePointSelection::isValid(const ModuleBase_ISelection* theSelection, ModuleBase_Operation* theOperation) const
+bool PartSet_MiddlePointSelection::isValid(const ModuleBase_ISelection* theSelection,
+                                           ModuleBase_Operation* theOperation) const
 {
   if (theSelection->getSelected(ModuleBase_ISelection::Viewer).size() == 0)
     return isEmptySelectionValid(theOperation);
   else
-    return shapesNbLines(theSelection) == 1 && shapesNbPoints(theSelection) == 1;
+    return shapesNbLines(theSelection) == 1 || shapesNbPoints(theSelection) == 1;
+}
+
+bool PartSet_MultyTranslationSelection::isValid(const ModuleBase_ISelection* theSelection,
+                                     ModuleBase_Operation* theOperation) const
+{
+  if (theSelection->getSelected(ModuleBase_ISelection::Viewer).size() == 0) {
+    return isEmptySelectionValid(theOperation);
+  } else {
+    int aCount = shapesNbLines(theSelection);
+    return aCount > 0;
+  }
+}
+
+bool PartSet_SplitSelection::isValid(const ModuleBase_ISelection* theSelection,
+                                     ModuleBase_Operation* theOperation) const
+{
+  if (theSelection->getSelected(ModuleBase_ISelection::Viewer).size() == 0) {
+    return isEmptySelectionValid(theOperation);
+  } else {
+    int aCount = shapesNbLines(theSelection);
+    return aCount > 0;
+  }
+}
+
+bool PartSet_ProjectionSelection::isValid(const ModuleBase_ISelection* theSelection,
+                                     ModuleBase_Operation* theOperation) const
+{
+  if (theSelection->getSelected(ModuleBase_ISelection::Viewer).size() == 0) {
+    return isEmptySelectionValid(theOperation);
+  } else {
+    int aCount = shapesNbLines(theSelection);
+    return aCount > 0;
+  }
+}
+
+bool PartSet_IntersectionSelection::isValid(const ModuleBase_ISelection* theSelection,
+                                     ModuleBase_Operation* theOperation) const
+{
+  if (theSelection->getSelected(ModuleBase_ISelection::Viewer).size() == 0) {
+    return isEmptySelectionValid(theOperation);
+  } else {
+    int aCount = shapesNbLines(theSelection);
+    return aCount == 0;
+  }
 }
 
 
@@ -354,19 +449,21 @@ std::string PartSet_DifferentObjectsValidator::errorMessage(
   return anError;
 }
 
-bool PartSet_DifferentObjectsValidator::isValid(const AttributePtr& theAttribute, 
+bool PartSet_DifferentObjectsValidator::isValid(const AttributePtr& theAttribute,
                                                 const std::list<std::string>& theArguments,
                                                 Events_InfoMessage& theError) const
 {
   FeaturePtr aFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(theAttribute->owner());
 
-  // the type of validated attributes should be equal, attributes with different types are not validated
+  // the type of validated attributes should be equal, attributes with
+  // different types are not validated
   // Check RefAttr attributes
   std::string anAttrType = theAttribute->attributeType();
   std::list<std::shared_ptr<ModelAPI_Attribute> > anAttrs;
 
   if (anAttrType == ModelAPI_AttributeRefAttr::typeId()) {
-    AttributeRefAttrPtr anAttr = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(theAttribute);
+    AttributeRefAttrPtr anAttr =
+      std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(theAttribute);
     bool isObject = anAttr->isObject();
     ObjectPtr anObject = anAttr->object();
 
@@ -376,7 +473,7 @@ bool PartSet_DifferentObjectsValidator::isValid(const AttributePtr& theAttribute
       for(; anAttrIter != anAttrs.end(); anAttrIter++) {
       if ((*anAttrIter).get() && (*anAttrIter)->id() != theAttribute->id()) {
           std::shared_ptr<ModelAPI_AttributeRefAttr> aRef =
-                                      std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(*anAttrIter);
+                              std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(*anAttrIter);
           if (aRef->isObject() != isObject)
             continue;
           if (isObject) {
@@ -400,7 +497,8 @@ bool PartSet_DifferentObjectsValidator::isValid(const AttributePtr& theAttribute
     }
   }
   else if (anAttrType == ModelAPI_AttributeSelection::typeId()) {
-    AttributeSelectionPtr anAttr = std::dynamic_pointer_cast<ModelAPI_AttributeSelection>(theAttribute);
+    AttributeSelectionPtr anAttr =
+      std::dynamic_pointer_cast<ModelAPI_AttributeSelection>(theAttribute);
     ResultPtr aContext = anAttr->context();
     GeomShapePtr aShape = anAttr->value();
 
@@ -411,7 +509,7 @@ bool PartSet_DifferentObjectsValidator::isValid(const AttributePtr& theAttribute
       for(; anAttr != anAttrs.end(); anAttr++) {
         if ((*anAttr).get() && (*anAttr)->id() != theAttribute->id()) {
           std::shared_ptr<ModelAPI_AttributeSelection> aRef =
-                                        std::dynamic_pointer_cast<ModelAPI_AttributeSelection>(*anAttr);
+                              std::dynamic_pointer_cast<ModelAPI_AttributeSelection>(*anAttr);
           // check the object is already presented
           if (aRef->context() == aContext) {
             bool aHasShape = aShape.get() != NULL;
@@ -425,7 +523,8 @@ bool PartSet_DifferentObjectsValidator::isValid(const AttributePtr& theAttribute
     }
   }
   else if (anAttrType == ModelAPI_AttributeReference::typeId()) {
-    AttributeReferencePtr anAttr = std::dynamic_pointer_cast<ModelAPI_AttributeReference>(theAttribute);
+    AttributeReferencePtr anAttr =
+      std::dynamic_pointer_cast<ModelAPI_AttributeReference>(theAttribute);
     ObjectPtr anObject = anAttr->value();
     // Check selection attributes
     anAttrs = aFeature->data()->attributes(ModelAPI_AttributeReference::typeId());
@@ -447,14 +546,14 @@ bool PartSet_DifferentObjectsValidator::isValid(const AttributePtr& theAttribute
     }
   }
   else if(anAttrType == ModelAPI_AttributeSelectionList::typeId()) {
-    std::shared_ptr<ModelAPI_AttributeSelectionList> aCurSelList = 
+    std::shared_ptr<ModelAPI_AttributeSelectionList> aCurSelList =
             std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(theAttribute);
     anAttrs = aFeature->data()->attributes(ModelAPI_AttributeSelectionList::typeId());
     if(anAttrs.size() > 0) {
       std::list<std::shared_ptr<ModelAPI_Attribute>>::iterator anAttrItr = anAttrs.begin();
       for(; anAttrItr != anAttrs.end(); anAttrItr++){
         if ((*anAttrItr).get() && (*anAttrItr)->id() != theAttribute->id()){
-          std::shared_ptr<ModelAPI_AttributeSelectionList> aRefSelList = 
+          std::shared_ptr<ModelAPI_AttributeSelectionList> aRefSelList =
             std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(*anAttrItr);
           for(int i = 0; i < aCurSelList->size(); i++) {
             std::shared_ptr<ModelAPI_AttributeSelection> aCurSel = aCurSelList->value(i);
@@ -467,7 +566,8 @@ bool PartSet_DifferentObjectsValidator::isValid(const AttributePtr& theAttribute
             for(int j = 0; j < aRefSelList->size(); j++) {
               std::shared_ptr<ModelAPI_AttributeSelection> aRefSel = aRefSelList->value(j);
               ResultPtr aRefSelContext = aRefSel->context();
-              ResultCompSolidPtr aRefSelCompSolidPtr = ModelAPI_Tools::compSolidOwner(aRefSelContext);
+              ResultCompSolidPtr aRefSelCompSolidPtr =
+                ModelAPI_Tools::compSolidOwner(aRefSelContext);
               std::shared_ptr<GeomAPI_Shape> aRefSelCompSolid;
               if(aRefSelCompSolidPtr.get()) {
                 aRefSelCompSolid = aRefSelCompSolidPtr->shape();
@@ -524,7 +624,57 @@ bool PartSet_DifferentObjectsValidator::isValid(const AttributePtr& theAttribute
   return true;
 }
 
-bool PartSet_CoincidentAttr::isValid(const AttributePtr& theAttribute, 
+bool PartSet_DifferentPointsValidator::isValid(const AttributePtr& theAttribute,
+                                               const std::list<std::string>& theArguments,
+                                               Events_InfoMessage& theError) const
+{
+  FeaturePtr aFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(theAttribute->owner());
+
+  // the type of validated attributes should be equal, attributes with
+  // different types are not validated
+  // Check RefAttr attributes
+  std::string anAttrType = theAttribute->attributeType();
+  std::list<std::shared_ptr<ModelAPI_Attribute> > anAttrs;
+  if (anAttrType != ModelAPI_AttributeRefAttr::typeId())
+    return true;
+
+  // obtain point of the given attribute
+  AttributePoint2DPtr anAttributePoint = getRefPointAttribute(theAttribute);
+  if (!anAttributePoint.get() || !anAttributePoint->isInitialized())
+    return true;
+
+  // obtain point of the parameter attribute
+  AttributePoint2DPtr anArgumentPoint = getRefPointAttribute
+                                              (aFeature->attribute(theArguments.front()));
+
+  if (!anArgumentPoint.get() || !anArgumentPoint->isInitialized())
+    return true;
+
+  return !anAttributePoint->pnt()->isEqual(anArgumentPoint->pnt());
+}
+
+AttributePoint2DPtr PartSet_DifferentPointsValidator::getRefPointAttribute
+                                                     (const AttributePtr& theAttribute) const
+{
+  AttributeRefAttrPtr anAttr = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(theAttribute);
+
+  AttributePoint2DPtr aPointAttribute;
+  if (anAttr->isObject()) {
+    ObjectPtr anObject  = anAttr->object();
+    if (anObject.get()) {
+      FeaturePtr aFeature = ModelAPI_Feature::feature(anObject);
+      if (aFeature->getKind() == SketchPlugin_Point::ID())
+        aPointAttribute = std::dynamic_pointer_cast<GeomDataAPI_Point2D>
+                                          (aFeature->attribute(SketchPlugin_Point::COORD_ID()));
+    }
+  }
+  else {
+    aPointAttribute = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(anAttr->attr());
+  }
+  return aPointAttribute;
+}
+
+bool PartSet_CoincidentAttr::isValid(const AttributePtr& theAttribute,
                                      const std::list<std::string>& theArguments,
                                      Events_InfoMessage& theError) const
 {
@@ -568,10 +718,13 @@ bool PartSet_CoincidentAttr::isValid(const AttributePtr& theAttribute,
         AttributePtr aAR = aRAttr->attr();
         if (aAR->id() != SketchPlugin_Arc::CENTER_ID()) // ignore constraint to center of arc
           aCoinList.insert(aConstrFeature);
+          QList<bool> anIsAttributes;
           PartSet_Tools::findCoincidences(aConstrFeature, aCoinsideLines, aCoins,
-                                          SketchPlugin_ConstraintCoincidence::ENTITY_A());
+                                          SketchPlugin_ConstraintCoincidence::ENTITY_A(),
+                                          anIsAttributes);
           PartSet_Tools::findCoincidences(aConstrFeature, aCoinsideLines, aCoins,
-                                          SketchPlugin_ConstraintCoincidence::ENTITY_B());
+                                          SketchPlugin_ConstraintCoincidence::ENTITY_B(),
+                                          anIsAttributes);
       }
     }
     // if there is no coincidence then it is not valid
@@ -588,4 +741,3 @@ bool PartSet_CoincidentAttr::isValid(const AttributePtr& theAttribute,
   theError = "There is no a common coincident point.";
   return false;
 }
-