X-Git-Url: http://git.salome-platform.org/gitweb/?a=blobdiff_plain;f=src%2FFeaturesPlugin%2FFeaturesPlugin_Validators.cpp;h=83ab5ed7515e82e4bd397422b2d8465bb47812ab;hb=658fccce59f75b0cfa7c3f3d45f1ffb295ed24be;hp=40c1197db3424471f59a58c588cd88633dc88dbf;hpb=5315361b0c34c6e603474413024db5485c850d80;p=modules%2Fshaper.git diff --git a/src/FeaturesPlugin/FeaturesPlugin_Validators.cpp b/src/FeaturesPlugin/FeaturesPlugin_Validators.cpp index 40c1197db..83ab5ed75 100644 --- a/src/FeaturesPlugin/FeaturesPlugin_Validators.cpp +++ b/src/FeaturesPlugin/FeaturesPlugin_Validators.cpp @@ -9,9 +9,21 @@ #include #include #include +#include +#include + +#include + +#include +#include + +#include +#include +#include +#include //================================================================================================= -bool FeaturesPlugin_PipeLocationsValidator::isValid(const std::shared_ptr& theFeature, +bool FeaturesPlugin_ValidatorPipeLocations::isValid(const std::shared_ptr& theFeature, const std::list& theArguments, std::string& theError) const { @@ -19,7 +31,6 @@ bool FeaturesPlugin_PipeLocationsValidator::isValid(const std::shared_ptrgetKind() != "Pipe") { theError = "Feature \"" + theFeature->getKind() + "\" does not supported by this validator."; return false; @@ -56,10 +67,393 @@ bool FeaturesPlugin_PipeLocationsValidator::isValid(const std::shared_ptr& theArguments, + std::string& theError) const +{ + if(theArguments.empty()) { + theError = "Validator parameters is empty."; + return false; + } + + // Checking attribute. + if(!isValidAttribute(theAttribute, theArguments, theError)) { + if(theError.empty()) { + theError = "Attribute contains unacceptable shape."; + } + return false; + } + + std::set aSelectedSketches; + std::set aSelectedSketchesFromObjects; + GeomAPI_DataMapOfShapeShape aSelectedWiresFromObjects; + std::string anAttributeType = theAttribute->attributeType(); + if(anAttributeType == ModelAPI_AttributeSelectionList::typeId()) { + AttributeSelectionListPtr aListAttr = std::dynamic_pointer_cast(theAttribute); + for(int anIndex = 0; anIndex < aListAttr->size(); ++anIndex) { + AttributeSelectionPtr aSelectionAttr = aListAttr->value(anIndex); + ResultConstructionPtr aContext = std::dynamic_pointer_cast(aSelectionAttr->context()); + if(!aContext.get()) { + // It is not a result construction, continue. + continue; + } + + GeomShapePtr aShape = aSelectionAttr->value(); + GeomShapePtr aContextShape = aContext->shape(); + if(!aShape.get()) { + // Whole sketch selected. + if(aSelectedSketchesFromObjects.find(aContext) != aSelectedSketchesFromObjects.cend()) { + theError = "Object from this sketch is already selected. Sketch is not allowed for selection."; + return false; + } + + aSelectedSketches.insert(aContext); + } else { + // Object from sketch selected. + if(aSelectedSketches.find(aContext) != aSelectedSketches.cend()) { + theError = "Whole sketch with this object is already selected. Don't allow to select this object."; + return false; + } + + for(GeomAPI_ShapeExplorer anExp(aShape, GeomAPI_Shape::WIRE); anExp.more(); anExp.next()) { + GeomShapePtr aWire = anExp.current(); + if(aWire->orientation() != GeomAPI_Shape::FORWARD) { + theError = "Wire with wrong orientation selected."; + return false; + } + + if(aSelectedWiresFromObjects.isBound(aWire)) { + theError = "Objects with such wire already selected. Don't allow to select this object."; + return false; + } + + aSelectedWiresFromObjects.bind(aWire, aWire); + aSelectedSketchesFromObjects.insert(aContext); + } + } + } + } + + return true; +} + +//================================================================================================= +bool FeaturesPlugin_ValidatorBaseForGeneration::isValidAttribute(const AttributePtr& theAttribute, + const std::list& theArguments, + std::string& theError) const +{ + if(!theAttribute.get()) { + theError = "Empty attribute."; + return false; + } + + std::string anAttributeType = theAttribute->attributeType(); + if(anAttributeType == ModelAPI_AttributeSelectionList::typeId()) { + AttributeSelectionListPtr aListAttr = std::dynamic_pointer_cast(theAttribute); + for(int anIndex = 0; anIndex < aListAttr->size(); ++anIndex) { + // If at least one attribute is invalid, the result is false. + if(!isValidAttribute(aListAttr->value(anIndex), theArguments, theError)) { + return false; + } + } + } else if(anAttributeType == ModelAPI_AttributeSelection::typeId()) { + // Getting context. + AttributeSelectionPtr anAttr = std::dynamic_pointer_cast(theAttribute); + ResultPtr aContext = anAttr->context(); + if(!aContext.get()) { + theError = "Attribute have empty context."; + return false; + } + + GeomShapePtr aShape = anAttr->value(); + GeomShapePtr aContextShape = aContext->shape(); + if(!aShape.get()) { + aShape = aContextShape; + } + if(!aShape.get()) { + theError = "Empty shape selected"; + return false; + } + + ResultConstructionPtr aConstruction = std::dynamic_pointer_cast(aContext); + if(aConstruction.get()) { + // Construciotn selected. Check that is is not infinite. + if(aConstruction->isInfinite()) { + theError = "Infinite constructions is not allowed as base."; + return false; + } + + if(aShape->isEqual(aContextShape)) { + // Whole construction selected. Check that it have faces. + if(aConstruction->facesNum() > 0) { + return true; + } + } else { + // Shape on construction selected. Check that it is a face or wire. + if(aShape->shapeType() == GeomAPI_Shape::WIRE || aShape->shapeType() == GeomAPI_Shape::FACE) { + return true; + } + } + + return false; + } + + if(!aShape->isEqual(aContextShape)) { + // Local selection on body does not allowed. + theError = "Selected shape is in the local selection. Only global selection is allowed."; + return false; + } + + // Check that object is a shape with allowed type. + GeomValidators_ShapeType aShapeTypeValidator; + if(!aShapeTypeValidator.isValid(anAttr, theArguments, theError)) { + theError = "Selected shape has unacceptable type. Acceptable types are: faces or wires on sketch, " + "whole sketch(if it has at least one face), and whole objects with shape types: "; + std::list::const_iterator anIt = theArguments.cbegin(); + theError += *anIt; + for(++anIt; anIt != theArguments.cend(); ++anIt) { + theError += ", " + *anIt; + } + return false; + } + + } else { + theError = "Following attribute does not supported: " + anAttributeType + "."; + return false; + } + + return true; +} + +//================================================================================================= +bool FeaturesPlugin_ValidatorCompositeLauncher::isValid(const AttributePtr& theAttribute, + const std::list& theArguments, + std::string& theError) const +{ + if (theAttribute->attributeType() != ModelAPI_AttributeReference::typeId()) { + theError = "The attribute with the " + theAttribute->attributeType() + " type is not processed"; + return false; + } + if (theArguments.size() != 2) { + theError = "Wrong parameters in XML definition for " + theAttribute->attributeType() + " type"; + return false; + } + // first argument is for the base attribute, second - for skipping feature kind + std::list::const_iterator anIt = theArguments.begin(); + std::string aBaseAttributeId = *anIt; + FeaturePtr aFeature = ModelAPI_Feature::feature(theAttribute->owner()); + AttributePtr aBaseAttribute = aFeature->attribute(aBaseAttributeId); + if (!aBaseAttribute.get()) { + theError = "Wrong parameters in XML definition for " + theAttribute->attributeType() + " type"; + return false; + } + if (aBaseAttribute->isInitialized()) // when base list of composite feature is already filled, + // this validator is not necessary anymore + return true; + + anIt++; + std::string aFeatureAttributeKind = *anIt; + GeomValidators_FeatureKind* aValidator = new GeomValidators_FeatureKind(); + // check whether the selection is on the sketch + std::list anArguments; + anArguments.push_back(aFeatureAttributeKind); + + bool aFeatureKind = aValidator->isValid(theAttribute, theArguments, theError); + bool aPlanarFace = false; + // check if selection has Face selected + GeomValidators_ShapeType* aShapeType = new GeomValidators_ShapeType(); + anArguments.clear(); + anArguments.push_back("face"); + aPlanarFace = aShapeType->isValid(theAttribute, anArguments, theError); + + bool aValid = !aFeatureKind && aPlanarFace; + return aValid; +} + +//================================================================================================= +bool FeaturesPlugin_ValidatorCanBeEmpty::isValid(const std::shared_ptr& theFeature, + const std::list& theArguments, + std::string& theError) const { - if(theFeature == "Pipe" && theAttribute == "locations") { + if(theArguments.size() != 2) { + theError = "Validator should be used with 2 parameters for extrusion."; + return false; + } + + std::list::const_iterator anArgsIt = theArguments.begin(), aLast = theArguments.end(); + + AttributePtr aCheckAttribute = theFeature->attribute(*anArgsIt); + ++anArgsIt; + + if(isShapesCanBeEmpty(aCheckAttribute, theError)) { return true; } + + AttributeSelectionPtr aSelAttr = theFeature->selection(*anArgsIt); + if(!aSelAttr.get()) { + theError = "Could not get selection attribute \"" + *anArgsIt + "\"."; + return false; + } + + GeomShapePtr aShape = aSelAttr->value(); + if(!aShape.get()) { + ResultPtr aContext = aSelAttr->context(); + if(!aContext.get()) { + theError = "Base objects list contains vertex or edge, so attribute \"" + *anArgsIt + + "\" can not be used with default value. Select direction for extrusion."; + return false; + } + + aShape = aContext->shape(); + } + + if(!aShape.get()) { + theError = "Base objects list contains vertex or edge, so attribute \"" + *anArgsIt + + "\" can not be used with default value. Select direction for extrusion."; + return false; + } + + return true; +} + +//================================================================================================= +bool FeaturesPlugin_ValidatorCanBeEmpty::isNotObligatory(std::string theFeature, std::string theAttribute) +{ return false; +} + +//================================================================================================= +bool FeaturesPlugin_ValidatorCanBeEmpty::isShapesCanBeEmpty(const AttributePtr& theAttribute, + std::string& theError) const +{ + if(!theAttribute.get()) { + return true; + } + + std::string anAttributeType = theAttribute->attributeType(); + if(anAttributeType == ModelAPI_AttributeSelectionList::typeId()) { + AttributeSelectionListPtr aListAttr = std::dynamic_pointer_cast(theAttribute); + for(int anIndex = 0; anIndex < aListAttr->size(); ++anIndex) { + // If at least one attribute is invalid, the result is false. + if(!isShapesCanBeEmpty(aListAttr->value(anIndex), theError)) { + return false; + } + } + } else if(anAttributeType == ModelAPI_AttributeSelection::typeId()) { + // Getting context. + AttributeSelectionPtr anAttr = std::dynamic_pointer_cast(theAttribute); + ResultPtr aContext = anAttr->context(); + if(!aContext.get()) { + return false; + } + + GeomShapePtr aShape = anAttr->value(); + GeomShapePtr aContextShape = aContext->shape(); + if(!aShape.get()) { + aShape = aContextShape; + } + if(!aShape.get()) { + return false; + } + + if(aShape->shapeType() == GeomAPI_Shape::VERTEX || + aShape->shapeType() == GeomAPI_Shape::EDGE || + !aShape->isPlanar()) { + return false; + } + } else { + return false; + } + + return true; +} + +//================================================================================================= +bool FeaturesPlugin_ValidatorBaseForWire::isValid(const AttributePtr& theAttribute, + const std::list& theArguments, + std::string& theError) const +{ + // Get base objects list. + if(theAttribute->attributeType() != ModelAPI_AttributeSelectionList::typeId()) { + Events_Error::send("Validator does not support attribute type \"" + theAttribute->attributeType() + + "\"\n Only \"" + ModelAPI_AttributeSelectionList::typeId() + "\" supported."); + return false; + } + AttributeSelectionListPtr aSelectionList = std::dynamic_pointer_cast(theAttribute); + if(!aSelectionList.get()) { + theError = "Could not get selection list."; + return false; + } + if(aSelectionList->size() == 0) { + theError = "Empty selection list."; + return false; + } + + // Collect base shapes. + ListOfShape aListOfShapes; + for(int anIndex = 0; anIndex < aSelectionList->size(); ++anIndex) { + AttributeSelectionPtr aSelection = aSelectionList->value(anIndex); + if(!aSelection.get()) { + theError = "Could not get selection."; + return false; + } + ResultPtr aContext = aSelection->context(); + if(!aContext.get()) { + theError = "Attribute have empty context."; + return false; + } + + GeomShapePtr aShape = aSelection->value(); + GeomShapePtr aContextShape = aContext->shape(); + if(!aShape.get()) { + aShape = aContextShape; + } + if(!aShape.get()) { + theError = "Empty shape selected."; + return false; + } + + // Check that shape has acceptable type. + if(aShape->shapeType() != GeomAPI_Shape::EDGE && aShape->shapeType() != GeomAPI_Shape::WIRE) { + theError = "Selected shape has wrong type. Only edges and wires acceptable."; + return false; + } + + // Check that it is edge on sketch. + ResultConstructionPtr aConstruction = std::dynamic_pointer_cast(aContext); + if(aConstruction.get()) { + if(aConstruction->isInfinite()) { + theError = "Inifinte objects not acceptable."; + return false; + } + + std::shared_ptr anEdges = std::dynamic_pointer_cast(aContextShape); + if(!anEdges.get()) { + // It is not an edge on the sketch. + // Check that it is not local selection. + if(!aShape->isEqual(aContextShape)) { + // Local selection on body does not allowed. + theError = "Selected shape is in the local selection. Only global selection is allowed."; + return false; + } + } + } + + aListOfShapes.push_back(aShape); + } + + // Create wire. + GeomShapePtr aWire = GeomAlgoAPI_WireBuilder::wire(aListOfShapes); + if(!aWire.get()) { + theError = "Result wire empty. Probably it has disconnected edges or non-manifold."; + return false; + } + + return true; } \ No newline at end of file