X-Git-Url: http://git.salome-platform.org/gitweb/?a=blobdiff_plain;f=src%2FPartSet%2FPartSet_Validators.cpp;h=f8d05fe0a6c011c731d314ee19bc06739368b871;hb=cfeb101356ed62a533474075cb22853a0e1f30d1;hp=613e41f3bf855d887194767f89e6ed4ed20e363f;hpb=efb98074554bc1f6c5dca3fd0de838b066c8bbef;p=modules%2Fshaper.git diff --git a/src/PartSet/PartSet_Validators.cpp b/src/PartSet/PartSet_Validators.cpp old mode 100755 new mode 100644 index 613e41f3b..f8d05fe0a --- a/src/PartSet/PartSet_Validators.cpp +++ b/src/PartSet/PartSet_Validators.cpp @@ -1,21 +1,41 @@ -// Copyright (C) 2014-20xx CEA/DEN, EDF R&D - -// File: PartSet_Validators.cpp -// Created: 09 July 2014 -// Author: Vitaly SMETANNIKOV +// Copyright (C) 2014-2019 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 +// #include "PartSet_Validators.h" #include "PartSet_Tools.h" +#include "PartSet_SketcherMgr.h" #include #include #include #include #include -#include #include #include +#include +#include + +#include +#include + +#include #include #include @@ -23,11 +43,14 @@ #include #include #include +#include #include +#include #include #include #include +#include #include #include @@ -37,12 +60,14 @@ int shapesNbPoints(const ModuleBase_ISelection* theSelection) { - QList aList = theSelection->getSelected(ModuleBase_ISelection::Viewer); + QList aList = theSelection->getSelected(ModuleBase_ISelection::Viewer); + ModuleBase_ISelection::filterSelectionOnEqualPoints(aList); + int aCount = 0; - foreach (ModuleBase_ViewerPrs aPrs, aList) { - const TopoDS_Shape& aShape = aPrs.shape(); - if (!aShape.IsNull()) { - if (aShape.ShapeType() == TopAbs_VERTEX) + foreach (ModuleBase_ViewerPrsPtr aPrs, aList) { + const GeomShapePtr& aShape = aPrs->shape(); + if (aShape.get() && !aShape->isNull()) { + if (aShape->shapeType() == GeomAPI_Shape::VERTEX) aCount++; } } @@ -51,13 +76,14 @@ int shapesNbPoints(const ModuleBase_ISelection* theSelection) int shapesNbLines(const ModuleBase_ISelection* theSelection) { - QList aList = theSelection->getSelected(ModuleBase_ISelection::Viewer); + QList aList = theSelection->getSelected(ModuleBase_ISelection::Viewer); int aCount = 0; - foreach(ModuleBase_ViewerPrs aPrs, aList) { - const TopoDS_Shape& aShape = aPrs.shape(); - if (!aShape.IsNull()) { - if (aShape.ShapeType() == TopAbs_EDGE) { - TopoDS_Edge aEdge = TopoDS::Edge(aShape); + foreach(ModuleBase_ViewerPrsPtr aPrs, aList) { + const GeomShapePtr& aShape = aPrs->shape(); + if (aShape.get() && !aShape->isNull()) { + if (aShape->shapeType() == GeomAPI_Shape::EDGE) { + const TopoDS_Shape& aTDShape = aShape->impl(); + TopoDS_Edge aEdge = TopoDS::Edge(aTDShape); Standard_Real aStart, aEnd; Handle(Geom_Curve) aCurve = BRep_Tool::Curve(aEdge, aStart, aEnd); GeomAdaptor_Curve aAdaptor(aCurve); @@ -69,170 +95,404 @@ int shapesNbLines(const ModuleBase_ISelection* theSelection) return aCount; } -bool PartSet_DistanceSelection::isValid(const ModuleBase_ISelection* theSelection) const + +std::shared_ptr sketcherPlane(ModuleBase_Operation* theOperation) { - int aCount = shapesNbPoints(theSelection) + shapesNbLines(theSelection); - return (aCount > 0) && (aCount < 3); + std::shared_ptr aEmptyPln; + if (theOperation) { + ModuleBase_OperationFeature* aFeatureOp = + dynamic_cast(theOperation); + if (aFeatureOp) { + CompositeFeaturePtr aFeature = + std::dynamic_pointer_cast(aFeatureOp->feature()); + if (aFeature && (aFeature->getKind() == SketchPlugin_Sketch::ID())) + return PartSet_Tools::sketchPlane(aFeature); + } + } + return aEmptyPln; } -bool PartSet_LengthSelection::isValid(const ModuleBase_ISelection* theSelection) const + +bool isEmptySelectionValid(ModuleBase_Operation* theOperation) { - int aCount = shapesNbLines(theSelection); - return (aCount == 1); + ModuleBase_OperationFeature* aFeatureOp = + dynamic_cast(theOperation); + // during the create operation empty selection is always valid + if (!aFeatureOp->isEditOperation()) { + return true; + } + else { + if (PartSet_SketcherMgr::isSketchOperation(aFeatureOp)) { + std::shared_ptr aPlane = sketcherPlane(theOperation); + if (aPlane.get()) + return true; + else + return false; + } + else + // in edit operation an empty selection is always valid, performed for re-entrant operrations + return true; + } } -bool PartSet_PerpendicularSelection::isValid(const ModuleBase_ISelection* theSelection) const +bool PartSet_DistanceSelection::isValid(const ModuleBase_ISelection* theSelection, + ModuleBase_Operation* theOperation) const { - int aCount = shapesNbLines(theSelection); - return (aCount > 0) && (aCount < 3); + if (theSelection->getSelected(ModuleBase_ISelection::Viewer).size() == 0) { + return isEmptySelectionValid(theOperation); + } else { + int aCount = shapesNbPoints(theSelection) + shapesNbLines(theSelection); + return (aCount > 0) && (aCount < 3); + } } -bool PartSet_ParallelSelection::isValid(const ModuleBase_ISelection* theSelection) const +bool PartSet_LengthSelection::isValid(const ModuleBase_ISelection* theSelection, + ModuleBase_Operation* theOperation) const { - int aCount = shapesNbLines(theSelection); - return (aCount > 0) && (aCount < 3); + if (theSelection->getSelected(ModuleBase_ISelection::Viewer).size() == 0) { + return isEmptySelectionValid(theOperation); + } else { + int aCount = shapesNbLines(theSelection); + return (aCount == 1); + } } -bool PartSet_RadiusSelection::isValid(const ModuleBase_ISelection* theSelection) const +bool PartSet_PerpendicularSelection::isValid(const ModuleBase_ISelection* theSelection, + ModuleBase_Operation* theOperation) const { - QList aList = theSelection->getSelected(ModuleBase_ISelection::Viewer); - ModuleBase_ViewerPrs aPrs; - int aCount = 0; - foreach (ModuleBase_ViewerPrs aPrs, aList) { - const TopoDS_Shape& aShape = aPrs.shape(); - if (!aShape.IsNull()) { - if (aShape.ShapeType() == TopAbs_EDGE) { - TopoDS_Edge aEdge = TopoDS::Edge(aShape); - Standard_Real aStart, aEnd; - Handle(Geom_Curve) aCurve = BRep_Tool::Curve(aEdge, aStart, aEnd); - GeomAdaptor_Curve aAdaptor(aCurve); - if (aAdaptor.GetType() == GeomAbs_Circle) - aCount++; + if (theSelection->getSelected(ModuleBase_ISelection::Viewer).size() == 0) { + return isEmptySelectionValid(theOperation); + } else { + int aCount = shapesNbLines(theSelection); + return (aCount > 0) && (aCount < 3); + } +} + +bool PartSet_ParallelSelection::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) && (aCount < 3); + } +} + +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 aList = + theSelection->getSelected(ModuleBase_ISelection::Viewer); + int aCount = 0; + foreach (ModuleBase_ViewerPrsPtr aPrs, aList) { + const GeomShapePtr& aShape = aPrs->shape(); + if (aShape.get() && !aShape->isNull()) { + if (aShape->shapeType() == GeomAPI_Shape::EDGE) { + const TopoDS_Shape& aTDShape = aShape->impl(); + TopoDS_Edge aEdge = TopoDS::Edge(aTDShape); + Standard_Real aStart, aEnd; + Handle(Geom_Curve) aCurve = BRep_Tool::Curve(aEdge, aStart, aEnd); + GeomAdaptor_Curve aAdaptor(aCurve); + if (aAdaptor.GetType() == GeomAbs_Circle) + aCount++; + } } } + return (aCount == 1); } - return (aCount == 1); } -bool PartSet_RigidSelection::isValid(const ModuleBase_ISelection* theSelection) const +bool PartSet_RigidSelection::isValid(const ModuleBase_ISelection* theSelection, + ModuleBase_Operation* theOperation) const { - QList aList = theSelection->getSelected(ModuleBase_ISelection::Viewer); - return (aList.count() == 1); + if (theSelection->getSelected(ModuleBase_ISelection::Viewer).size() == 0) { + return isEmptySelectionValid(theOperation); + } else { + QList 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) const +bool PartSet_CoincidentSelection::isValid(const ModuleBase_ISelection* theSelection, + ModuleBase_Operation* theOperation) const { - // Coincident can be applied to points and to lines - int aCount = shapesNbPoints(theSelection); - aCount += shapesNbLines(theSelection); - return (aCount > 0) && (aCount < 3); + if (theSelection->getSelected(ModuleBase_ISelection::Viewer).size() == 0) { + return isEmptySelectionValid(theOperation); + } else { + // Coincident can be applied to points and to lines + int aCount = shapesNbPoints(theSelection); + aCount += shapesNbLines(theSelection); + return (aCount > 0) && (aCount < 3); + } } -bool PartSet_HVDirSelection::isValid(const ModuleBase_ISelection* theSelection) const +bool PartSet_HVDirSelection::isValid(const ModuleBase_ISelection* theSelection, + ModuleBase_Operation* theOperation) const { - int aCount = shapesNbLines(theSelection); - return (aCount == 1); + if (theSelection->getSelected(ModuleBase_ISelection::Viewer).size() == 0) { + return isEmptySelectionValid(theOperation); + } else { + int aCount = shapesNbLines(theSelection); + return (aCount == 1); + } } -bool PartSet_FilletSelection::isValid(const ModuleBase_ISelection* theSelection) const +bool PartSet_FilletSelection::isValid(const ModuleBase_ISelection* theSelection, + ModuleBase_Operation* theOperation) const { - int aCount = shapesNbLines(theSelection); - return (aCount > 0) && (aCount < 3); + if (theSelection->getSelected(ModuleBase_ISelection::Viewer).size() == 0) { + return isEmptySelectionValid(theOperation); + } else { + int aCount = shapesNbPoints(theSelection); + return aCount > 1; + } } -bool PartSet_TangentSelection::isValid(const ModuleBase_ISelection* theSelection) const +bool PartSet_TangentSelection::isValid(const ModuleBase_ISelection* theSelection, + ModuleBase_Operation* theOperation) const { - QList aList = theSelection->getSelected(ModuleBase_ISelection::Viewer); - if ((aList.size() == 0) || (aList.size() > 2)) - return false; - - ModuleBase_ViewerPrs aPrs = aList.first(); - const TopoDS_Shape& aShape = aPrs.shape(); - if (aShape.IsNull()) - return false; - - if (aShape.ShapeType() != TopAbs_EDGE) - return false; + if (theSelection->getSelected(ModuleBase_ISelection::Viewer).size() == 0) { + return isEmptySelectionValid(theOperation); + } else { + QList aList = theSelection->getSelected(ModuleBase_ISelection::Viewer); + if ((aList.size() == 0) || (aList.size() > 2)) + return false; - std::shared_ptr aShapePtr(new GeomAPI_Shape); - aShapePtr->setImpl(new TopoDS_Shape(aShape)); - GeomAPI_Edge aEdge1(aShapePtr); + ModuleBase_ViewerPrsPtr aPrs = aList.first(); + const GeomShapePtr& aShape = aPrs->shape(); + if (!aShape.get() || aShape->isNull() || aShape->shapeType() != GeomAPI_Shape::EDGE) + return false; + GeomAPI_Edge aEdge1(aShape); - if (aEdge1.isLine() || aEdge1.isArc()) { if (aList.size() == 2) { // Check second selection aPrs = aList.last(); - const TopoDS_Shape& aShape2 = aPrs.shape(); - if (aShape2.IsNull()) + const GeomShapePtr& aShape2 = aPrs->shape(); + if (!aShape2.get() || aShape2->isNull() || aShape2->shapeType() != GeomAPI_Shape::EDGE) return false; + GeomAPI_Edge aEdge2(aShape2); - if (aShape2.ShapeType() != TopAbs_EDGE) + if (aEdge1.isLine() && aEdge2.isLine()) return false; + } + } + return true; +} - std::shared_ptr aShapePtr2(new GeomAPI_Shape); - aShapePtr2->setImpl(new TopoDS_Shape(aShape2)); - GeomAPI_Edge aEdge2(aShapePtr2); - if (aEdge1.isLine() && aEdge2.isArc()) - return true; - else if (aEdge1.isArc() && aEdge2.isLine()) - return true; - else +bool PartSet_AngleSelection::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) && (aCount < 3); + } +} + +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 aList = + theSelection->getSelected(ModuleBase_ISelection::Viewer); + int aCount = 0; + int aType = 0; + foreach (ModuleBase_ViewerPrsPtr aPrs, aList) { + GeomShapePtr aShape = aPrs->shape(); + if (aShape.get() && aShape->isEdge()) { + aCount++; + GeomAPI_Edge aEdge(aShape); + if (aEdge.isLine()) { + if (aCount == 1) + aType = 1; + else if (aType != 1) + return false; + } else if (aEdge.isCircle() || aEdge.isArc()) { + if (aCount == 1) + aType = 2; + else if (aType != 2) + return false; + } else if (aEdge.isEllipse()) { + if (aCount == 1) + aType = 3; + else if (aType != 3) + return false; + } + } else return false; - } else - return true; + } + return (aCount > 0) && (aCount < 3); + } +} + +bool PartSet_CollinearSelection::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) && (aCount < 3); + } +} + +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; +} + +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; } - return false; } -bool PartSet_AngleSelection::isValid(const ModuleBase_ISelection* theSelection) const +bool PartSet_ProjectionSelection::isValid(const ModuleBase_ISelection* theSelection, + ModuleBase_Operation* theOperation) const { - int aCount = shapesNbLines(theSelection); - return (aCount > 0) && (aCount < 3); + 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; + } } -bool PartSet_DifferentObjectsValidator::isValid(const AttributePtr& theAttribute, +std::string PartSet_DifferentObjectsValidator::errorMessage( + const PartSet_DifferentObjectsValidator::ErrorType& theType, + const std::string& thEqualObject, const std::string& theFirstAttribute, + const std::string& theSecondAttribute) const +{ + std::string anError; + switch (theType) { + case EqualObjects: + anError = "The feature uses one " + thEqualObject + " object in " + + theFirstAttribute + " and " + theSecondAttribute + " attributes."; + break; + case EqualAttributes: + anError = "The feature uses reference to one " + thEqualObject + " attribute in " + + theFirstAttribute + " and " + theSecondAttribute + " attributes."; + break; + case EqualShapes: + anError = "The feature uses one shape in " + + theFirstAttribute + " and " + theSecondAttribute + " attributes."; + break; + case EmptyShapes: + anError = "The feature uses empty shapes in " + + theFirstAttribute + " and " + theSecondAttribute + " attributes."; + break; + break; + default: + break; + } + return anError; +} + +bool PartSet_DifferentObjectsValidator::isValid(const AttributePtr& theAttribute, const std::list& theArguments, - std::string& theError) const + Events_InfoMessage& theError) const { FeaturePtr aFeature = std::dynamic_pointer_cast(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 > anAttrs; if (anAttrType == ModelAPI_AttributeRefAttr::typeId()) { - AttributeRefAttrPtr anAttr = std::dynamic_pointer_cast(theAttribute); + AttributeRefAttrPtr anAttr = + std::dynamic_pointer_cast(theAttribute); bool isObject = anAttr->isObject(); ObjectPtr anObject = anAttr->object(); - AttributePtr anAttributeAttr = anAttr->attr(); anAttrs = aFeature->data()->attributes(ModelAPI_AttributeRefAttr::typeId()); if (anAttrs.size() > 0) { - std::list >::iterator anAttr = anAttrs.begin(); - for(; anAttr != anAttrs.end(); anAttr++) { - if ((*anAttr).get() && (*anAttr)->id() != theAttribute->id()) { + std::list >::iterator anAttrIter = anAttrs.begin(); + for(; anAttrIter != anAttrs.end(); anAttrIter++) { + if ((*anAttrIter).get() && (*anAttrIter)->id() != theAttribute->id()) { std::shared_ptr aRef = - std::dynamic_pointer_cast(*anAttr); + std::dynamic_pointer_cast(*anAttrIter); if (aRef->isObject() != isObject) continue; if (isObject) { - if (aRef->object() == anObject) + if (aRef->object() == anObject) { + theError = errorMessage(EqualObjects, anObject.get() ? anObject->data()->name() : "", + theAttribute->id(), aRef->id()); return false; + } } else { // the attribute reference - if (aRef->attr() == anAttributeAttr) + AttributePtr anAttributeAttr = anAttr->attr(); + if (aRef->attr() == anAttributeAttr) { + theError = errorMessage(EqualAttributes, + anAttributeAttr.get() ? anAttributeAttr->id() : "", + theAttribute->id(), aRef->id()); return false; + } } } } } } else if (anAttrType == ModelAPI_AttributeSelection::typeId()) { - AttributeSelectionPtr anAttr = std::dynamic_pointer_cast(theAttribute); + AttributeSelectionPtr anAttr = + std::dynamic_pointer_cast(theAttribute); ResultPtr aContext = anAttr->context(); + FeaturePtr aContextFeature = anAttr->contextFeature(); GeomShapePtr aShape = anAttr->value(); // Check selection attributes @@ -242,19 +502,40 @@ bool PartSet_DifferentObjectsValidator::isValid(const AttributePtr& theAttribute for(; anAttr != anAttrs.end(); anAttr++) { if ((*anAttr).get() && (*anAttr)->id() != theAttribute->id()) { std::shared_ptr aRef = - std::dynamic_pointer_cast(*anAttr); + std::dynamic_pointer_cast(*anAttr); // check the object is already presented if (aRef->context() == aContext) { bool aHasShape = aShape.get() != NULL; - if (!aHasShape || aRef->value()->isEqual(aShape)) + if (!aHasShape || aRef->value()->isEqual(aShape)) { + theError = errorMessage(EqualShapes, "", theAttribute->id(), aRef->id()); + return false; + } + } + // check the whole selected feature contains the result + if (aContextFeature.get()) { + if (aRef->contextFeature().get()) { + if (aContextFeature == aRef->contextFeature()) { + theError = errorMessage(EqualShapes, "", theAttribute->id(), aRef->id()); + return false; + } + } else if (aRef->context().get() && + aRef->context()->document()->feature(aRef->context()) == aContextFeature) { + theError = errorMessage(EqualShapes, "", theAttribute->id(), aRef->id()); + return false; + } + } else if (aRef->contextFeature().get() && aContext.get()) { + if (aContext->document()->feature(aContext) == aRef->contextFeature()) { + theError = errorMessage(EqualShapes, "", theAttribute->id(), aRef->id()); return false; + } } } } } } else if (anAttrType == ModelAPI_AttributeReference::typeId()) { - AttributeReferencePtr anAttr = std::dynamic_pointer_cast(theAttribute); + AttributeReferencePtr anAttr = + std::dynamic_pointer_cast(theAttribute); ObjectPtr anObject = anAttr->value(); // Check selection attributes anAttrs = aFeature->data()->attributes(ModelAPI_AttributeReference::typeId()); @@ -265,31 +546,80 @@ bool PartSet_DifferentObjectsValidator::isValid(const AttributePtr& theAttribute std::shared_ptr aRef = std::dynamic_pointer_cast(*anAttr); // check the object is already presented - if (aRef->value() == anObject) + if (aRef->value() == anObject) { + theError = errorMessage(EqualObjects, anObject.get() ? anObject->data()->name() : "", + theAttribute->id(), aRef->id()); return false; + } } return true; } } } else if(anAttrType == ModelAPI_AttributeSelectionList::typeId()) { - std::shared_ptr aCurSelList = + std::shared_ptr aCurSelList = std::dynamic_pointer_cast(theAttribute); anAttrs = aFeature->data()->attributes(ModelAPI_AttributeSelectionList::typeId()); if(anAttrs.size() > 0) { std::list>::iterator anAttrItr = anAttrs.begin(); for(; anAttrItr != anAttrs.end(); anAttrItr++){ if ((*anAttrItr).get() && (*anAttrItr)->id() != theAttribute->id()){ - std::shared_ptr aRefSelList = + std::shared_ptr aRefSelList = std::dynamic_pointer_cast(*anAttrItr); for(int i = 0; i < aCurSelList->size(); i++) { std::shared_ptr aCurSel = aCurSelList->value(i); + ResultPtr aCurSelContext = aCurSel->context(); + FeaturePtr aCurSelFeature = aCurSel->contextFeature(); + ResultBodyPtr aCurSelCompSolidPtr = ModelAPI_Tools::bodyOwner(aCurSelContext); + std::shared_ptr aCurSelCompSolid; + if(aCurSelCompSolidPtr.get()) { + aCurSelCompSolid = aCurSelCompSolidPtr->shape(); + } for(int j = 0; j < aRefSelList->size(); j++) { std::shared_ptr aRefSel = aRefSelList->value(j); - if(aCurSel->context() == aRefSel->context()) { - if(aCurSel->value().get() == NULL || aRefSel->value().get() == NULL - || aCurSel->value()->isEqual(aRefSel->value())) { + ResultPtr aRefSelContext = aRefSel->context(); + FeaturePtr aRefSelFeature = aRefSel->contextFeature(); + ResultBodyPtr aRefSelCompSolidPtr = + ModelAPI_Tools::bodyOwner(aRefSelContext); + std::shared_ptr aRefSelCompSolid; + if (aRefSelCompSolidPtr.get()) { + aRefSelCompSolid = aRefSelCompSolidPtr->shape(); + } + if ((aCurSelCompSolid.get() && aCurSelCompSolid->isEqual(aRefSel->value())) + || (aRefSelCompSolid.get() && aRefSelCompSolid->isEqual(aCurSel->value()))) { + theError = errorMessage(EqualShapes, "", theAttribute->id(), + aRefSel->id()); + return false; + } + if (aCurSelContext == aRefSelContext) { + if (aCurSel->value().get() == NULL || aRefSel->value().get() == NULL) { + theError = errorMessage(EmptyShapes, "", theAttribute->id(), aRefSel->id()); + return false; + } + if (aCurSel->value()->isEqual(aRefSel->value())) { + theError = errorMessage(EqualShapes, "", theAttribute->id(), aRefSel->id()); + return false; + } + } + + // check the whole selected feature contains the result + if (aCurSelFeature.get()) { + if (aRefSelFeature.get()) { + if (aCurSelFeature == aRefSelFeature) { + theError = errorMessage(EqualShapes, "", theAttribute->id(), aRefSel->id()); return false; + } + } + else if (aRefSelContext.get() && + aRefSelContext->document()->feature(aRefSelContext) == aCurSelFeature) { + theError = errorMessage(EqualShapes, "", theAttribute->id(), aRefSel->id()); + return false; + } + } + else if (aRefSelFeature.get() && aCurSelContext.get()) { + if (aCurSelContext->document()->feature(aCurSelContext) == aRefSelFeature) { + theError = errorMessage(EqualShapes, "", theAttribute->id(), aRefSel->id()); + return false; } } } @@ -312,6 +642,9 @@ bool PartSet_DifferentObjectsValidator::isValid(const AttributePtr& theAttribute ObjectPtr aCurSelObject = aCurSelList->object(i); for (int j = 0; j < aRefSelList->size(); j++) { if (aCurSelObject == aRefSelList->object(j)) { + theError = errorMessage(EqualObjects, + aCurSelObject.get() ? aCurSelObject->data()->name() : "", + theAttribute->id(), aCurSelList->id()); return false; } } @@ -323,105 +656,66 @@ bool PartSet_DifferentObjectsValidator::isValid(const AttributePtr& theAttribute return true; } -bool PartSet_SketchEntityValidator::isValid(const AttributePtr& theAttribute, - const std::list& theArguments, - std::string& theError) const +bool PartSet_DifferentPointsValidator::isValid(const AttributePtr& theAttribute, + const std::list& theArguments, + Events_InfoMessage& theError) const { - bool isSketchEntities = true; - std::set anEntityKinds; - std::list::const_iterator anIt = theArguments.begin(), aLast = theArguments.end(); - for (; anIt != aLast; anIt++) { - anEntityKinds.insert(*anIt); - } - - std::string anAttributeType = theAttribute->attributeType(); - if (anAttributeType == ModelAPI_AttributeSelectionList::typeId()) { - AttributeSelectionListPtr aSelectionListAttr = - std::dynamic_pointer_cast(theAttribute); - // all context objects should be sketch entities - for (int i = 0, aSize = aSelectionListAttr->size(); i < aSize && isSketchEntities; i++) { - AttributeSelectionPtr aSelectAttr = aSelectionListAttr->value(i); - ObjectPtr anObject = aSelectAttr->context(); - // a context of the selection attribute is a feature result. It can be a case when the result - // of the feature is null, e.g. the feature is modified and has not been executed yet. - // The validator returns an invalid result here. The case is an extrusion built on a sketch - // feature. A new sketch element creation leads to an empty result. - if (!anObject.get()) - isSketchEntities = false; - else { - FeaturePtr aFeature = ModelAPI_Feature::feature(anObject); - isSketchEntities = anEntityKinds.find(aFeature->getKind()) != anEntityKinds.end(); - } - } - } - if (anAttributeType == ModelAPI_AttributeRefList::typeId()) { - AttributeRefListPtr aRefListAttr = - std::dynamic_pointer_cast(theAttribute); - // all context objects should be sketch entities - for (int i = 0, aSize = aRefListAttr->size(); i < aSize && isSketchEntities; i++) { - ObjectPtr anObject = aRefListAttr->object(i); - // a context of the selection attribute is a feature result. It can be a case when the result - // of the feature is null, e.g. the feature is modified and has not been executed yet. - // The validator returns an invalid result here. The case is an extrusion built on a sketch - // feature. A new sketch element creation leads to an empty result. - if (!anObject.get()) - isSketchEntities = false; - else { - FeaturePtr aFeature = ModelAPI_Feature::feature(anObject); - isSketchEntities = anEntityKinds.find(aFeature->getKind()) != anEntityKinds.end(); - } - } - } - if (anAttributeType == ModelAPI_AttributeRefAttr::typeId()) { - std::shared_ptr aRef = - std::dynamic_pointer_cast(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; -} + FeaturePtr aFeature = std::dynamic_pointer_cast(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 > 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; -bool PartSet_SameTypeAttrValidator::isValid(const AttributePtr& theAttribute, - const std::list& theArguments, - std::string& theError ) const -{ - // 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(); + // obtain point of the parameter attribute + AttributePoint2DPtr anArgumentPoint = getRefPointAttribute + (aFeature->attribute(theArguments.front())); - FeaturePtr aFeature = std::dynamic_pointer_cast(theAttribute->owner()); - AttributeRefAttrPtr aRefAttr = std::dynamic_pointer_cast(theAttribute); - if (!aRefAttr) - return false; + if (!anArgumentPoint.get() || !anArgumentPoint->isInitialized()) + return true; - bool isObject = aRefAttr->isObject(); - ObjectPtr anObject = aRefAttr->object(); - if (isObject && anObject) { - FeaturePtr aRefFea = ModelAPI_Feature::feature(anObject); + return !anAttributePoint->pnt()->isEqual(anArgumentPoint->pnt()); +} - AttributeRefAttrPtr aOtherAttr = aFeature->data()->refattr(aParamA); - ObjectPtr aOtherObject = aOtherAttr->object(); - FeaturePtr aOtherFea = ModelAPI_Feature::feature(aOtherObject); - return aRefFea->getKind() == aOtherFea->getKind(); +AttributePoint2DPtr PartSet_DifferentPointsValidator::getRefPointAttribute + (const AttributePtr& theAttribute) const +{ + AttributeRefAttrPtr anAttr = std::dynamic_pointer_cast(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 + (aFeature->attribute(SketchPlugin_Point::COORD_ID())); + } } - return false; + else { + aPointAttribute = std::dynamic_pointer_cast(anAttr->attr()); + } + return aPointAttribute; } -bool PartSet_CoincidentAttr::isValid(const AttributePtr& theAttribute, +bool PartSet_CoincidentAttr::isValid(const AttributePtr& theAttribute, const std::list& theArguments, - std::string& theError) const + Events_InfoMessage& theError) const { + if (theAttribute->attributeType() != ModelAPI_AttributeRefAttr::typeId()) { + theError = "The attribute with the %1 type is not processed"; + theError.arg(theAttribute->attributeType()); + return false; + } + // 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(); @@ -429,10 +723,8 @@ bool PartSet_CoincidentAttr::isValid(const AttributePtr& theAttribute, FeaturePtr aFeature = std::dynamic_pointer_cast(theAttribute->owner()); AttributeRefAttrPtr aRefAttr = std::dynamic_pointer_cast(theAttribute); - if (!aRefAttr) - return false; - QList aCoinsideLines; + QList aCoins; bool isObject = aRefAttr->isObject(); ObjectPtr anObject = aRefAttr->object(); @@ -458,24 +750,26 @@ 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); - PartSet_Tools::findCoincidences(aConstrFeature, aCoinsideLines, - SketchPlugin_ConstraintCoincidence::ENTITY_A()); - PartSet_Tools::findCoincidences(aConstrFeature, aCoinsideLines, - SketchPlugin_ConstraintCoincidence::ENTITY_B()); + QList anIsAttributes; + PartSet_Tools::findCoincidences(aConstrFeature, aCoinsideLines, aCoins, + SketchPlugin_ConstraintCoincidence::ENTITY_A(), + anIsAttributes); + PartSet_Tools::findCoincidences(aConstrFeature, aCoinsideLines, aCoins, + SketchPlugin_ConstraintCoincidence::ENTITY_B(), + anIsAttributes); } } // if there is no coincidence then it is not valid - if (aCoinList.size() == 0) - return false; - - QList::const_iterator anIt = aCoinsideLines.begin(), aLast = aCoinsideLines.end(); - bool aValid = false; - for (; anIt != aLast && !aValid; anIt++) { - aValid = *anIt == aOtherFea; + if (aCoinList.size() > 0) { + QList::const_iterator anIt = aCoinsideLines.begin(), aLast = aCoinsideLines.end(); + bool aValid = false; + for (; anIt != aLast && !aValid; anIt++) { + aValid = *anIt == aOtherFea; + } + if (aValid) + return true; } - if (aValid) - return true; } + theError = "There is no a common coincident point."; return false; } -