X-Git-Url: http://git.salome-platform.org/gitweb/?a=blobdiff_plain;f=src%2FSketchSolver%2FSketchSolver_Constraint.cpp;h=88f4572a17c05d7e8b20e352b0524cf32045a075;hb=2d309adb3c465a840e8f5ceeba28ec145e5a45a2;hp=05f261a69f11f1033e8773ceb0b81b496260f8cd;hpb=036ba4eb4c2df048fd651a54f68882a01769eb08;p=modules%2Fshaper.git diff --git a/src/SketchSolver/SketchSolver_Constraint.cpp b/src/SketchSolver/SketchSolver_Constraint.cpp index 05f261a69..88f4572a1 100644 --- a/src/SketchSolver/SketchSolver_Constraint.cpp +++ b/src/SketchSolver/SketchSolver_Constraint.cpp @@ -1,3 +1,5 @@ +// Copyright (C) 2014-20xx CEA/DEN, EDF R&D + // File: SketchSolver_Constraint.cpp // Created: 27 May 2014 // Author: Artem ZHIDKOV @@ -9,40 +11,65 @@ #include #include #include +#include #include #include #include #include #include +#include #include #include +#include +#include +#include #include #include +#include +#include + +/// Possible types of attributes (used to determine constraint type) +enum AttrType +{ + UNKNOWN, // Something wrong during type determination + POINT2D, + POINT3D, + LINE, + CIRCLE, + ARC +}; +/// Calculate type of the attribute +static AttrType typeOfAttribute(std::shared_ptr theAttribute); SketchSolver_Constraint::SketchSolver_Constraint() - : myConstraint(boost::shared_ptr()), - myType(SLVS_C_UNKNOWN), - myAttributesList() + : myConstraint(std::shared_ptr()), + myType(SLVS_C_UNKNOWN), + myAttributesList() { } SketchSolver_Constraint::SketchSolver_Constraint( - boost::shared_ptr theConstraint) - : myConstraint(theConstraint), - myAttributesList() + std::shared_ptr theConstraint) + : myConstraint(theConstraint), + myAttributesList() { myType = getType(myConstraint); } -const int& SketchSolver_Constraint::getType(boost::shared_ptr theConstraint) +const int& SketchSolver_Constraint::getType( + std::shared_ptr theConstraint) { myType = SLVS_C_UNKNOWN; if (!theConstraint) return getType(); + DataPtr aConstrData = theConstraint->data(); + if (!aConstrData || !aConstrData->isValid()) + return getType(); + // Assign empty names of attributes myAttributesList.clear(); for (int i = 0; i < CONSTRAINT_ATTR_SIZE; i++) @@ -50,39 +77,29 @@ const int& SketchSolver_Constraint::getType(boost::shared_ptrgetKind(); // Constraint for coincidence of two points - if (aConstraintKind.compare("SketchConstraintCoincidence") == 0) - { + if (aConstraintKind.compare(SketchPlugin_ConstraintCoincidence::ID()) == 0) { int anAttrPos = 0; // Verify the constraint has only two attributes and they are points - int aPt2d = 0; // bit-mapped field, each bit indicates whether the attribute is 2D point - int aPt3d = 0; // bit-mapped field, the same information for 3D points - for (unsigned int indAttr = 0; indAttr < CONSTRAINT_ATTR_SIZE; indAttr++) - { - boost::shared_ptr anAttr = - boost::dynamic_pointer_cast( - theConstraint->data()->attribute(SketchPlugin_Constraint::ATTRIBUTE(indAttr)) - ); - if (!anAttr) continue; - // Verify the attribute is a 2D point - boost::shared_ptr aPoint2D = - boost::dynamic_pointer_cast(anAttr->attr()); - if (aPoint2D) - { - aPt2d |= (1 << indAttr); - myAttributesList[anAttrPos++] = SketchPlugin_Constraint::ATTRIBUTE(indAttr); - continue; - } - // Verify the attribute is a 3D point - boost::shared_ptr aPoint3D = - boost::dynamic_pointer_cast(anAttr->attr()); - if (aPoint3D) - { - aPt3d |= (1 << indAttr); - myAttributesList[anAttrPos++] = SketchPlugin_Constraint::ATTRIBUTE(indAttr); + int aPt2d = 0; // bit-mapped field, each bit indicates whether the attribute is 2D point + int aPt3d = 0; // bit-mapped field, the same information for 3D points + for (unsigned int indAttr = 0; indAttr < CONSTRAINT_ATTR_SIZE; indAttr++) { + std::shared_ptr anAttr = + aConstrData->attribute(SketchPlugin_Constraint::ATTRIBUTE(indAttr)); + if (!anAttr) continue; + switch (typeOfAttribute(anAttr)) { + case POINT2D: // the attribute is a 2D point + aPt2d |= (1 << indAttr); + myAttributesList[anAttrPos++] = SketchPlugin_Constraint::ATTRIBUTE(indAttr); + break; + case POINT3D: // the attribute is a 3D point + aPt3d |= (1 << indAttr); + myAttributesList[anAttrPos++] = SketchPlugin_Constraint::ATTRIBUTE(indAttr); + break; + default: + // Attribute neither 2D nor 3D point is not supported by this type of constraint + return getType(); } - // Attribute neither 2D nor 3D point is not supported by this type of constraint - return getType(); } // The constrained points should be in first and second positions, // so the expected value of aPt2d or aPt3d is 3 @@ -93,80 +110,40 @@ const int& SketchSolver_Constraint::getType(boost::shared_ptr anAttr = - boost::dynamic_pointer_cast( - theConstraint->data()->attribute(SketchPlugin_Constraint::ATTRIBUTE(indAttr)) - ); - if (!anAttr) continue; - if (anAttr->isObject() && anAttr->object()) - { // verify posiible entities - const std::string& aKind = boost::dynamic_pointer_cast - (anAttr->object())->getKind(); - if (aKind.compare(SketchPlugin_Point::ID()) == 0) - { + for (unsigned int indAttr = 0; indAttr < CONSTRAINT_ATTR_SIZE; indAttr++) { + std::shared_ptr anAttr = + aConstrData->attribute(SketchPlugin_Constraint::ATTRIBUTE(indAttr)); + switch (typeOfAttribute(anAttr)) { + case POINT2D: + case POINT3D: myAttributesList[aNbPoints++] = SketchPlugin_Constraint::ATTRIBUTE(indAttr); - continue; - } - else if(aKind.compare(SketchPlugin_Line::ID()) == 0) - { + break; + case LINE: // entities are placed starting from SketchPlugin_Constraint::ENTITY_C() attribute myAttributesList[2 + aNbEntities++] = SketchPlugin_Constraint::ATTRIBUTE(indAttr); myType = SLVS_C_PT_LINE_DISTANCE; - continue; - } - } - else - { // verify points - // Verify the attribute is a 2D point - boost::shared_ptr aPoint2D = - boost::dynamic_pointer_cast(anAttr->attr()); - if (aPoint2D) - { - myAttributesList[aNbPoints++] = SketchPlugin_Constraint::ATTRIBUTE(indAttr); - continue; - } - // Verify the attribute is a 3D point - boost::shared_ptr aPoint3D = - boost::dynamic_pointer_cast(anAttr->attr()); - if (aPoint3D) - { - myAttributesList[aNbPoints++] = SketchPlugin_Constraint::ATTRIBUTE(indAttr); - continue; - } + break; } } // Verify the correctness of constraint arguments - if (aNbPoints == 2 && aNbEntities ==0) + if (aNbPoints == 2 && aNbEntities == 0) myType = SLVS_C_PT_PT_DISTANCE; - else if (aNbPoints == 1 && aNbEntities == 1) + else if (aNbPoints != 1 || aNbEntities != 1) myType = SLVS_C_UNKNOWN; return getType(); } // Constraint for the given length of a line - if (aConstraintKind.compare(SketchPlugin_ConstraintLength::ID()) == 0) - { + if (aConstraintKind.compare(SketchPlugin_ConstraintLength::ID()) == 0) { int aNbLines = 0; - for (unsigned int indAttr = 0; indAttr < CONSTRAINT_ATTR_SIZE; indAttr++) - { - boost::shared_ptr anAttr = - boost::dynamic_pointer_cast( - theConstraint->data()->attribute(SketchPlugin_Constraint::ATTRIBUTE(indAttr)) - ); - if (!anAttr) continue; - if (anAttr->isObject() && anAttr->object() && - boost::dynamic_pointer_cast(anAttr->object())->getKind(). - compare(SketchPlugin_Line::ID()) == 0) - { + for (unsigned int indAttr = 0; indAttr < CONSTRAINT_ATTR_SIZE; indAttr++) { + std::shared_ptr anAttr = + aConstrData->attribute(SketchPlugin_Constraint::ATTRIBUTE(indAttr)); + if (typeOfAttribute(anAttr) == LINE) myAttributesList[aNbLines++] = SketchPlugin_Constraint::ATTRIBUTE(indAttr); - break; - } } if (aNbLines == 1) myType = SLVS_C_PT_PT_DISTANCE; @@ -176,23 +153,13 @@ const int& SketchSolver_Constraint::getType(boost::shared_ptr anAttr = - boost::dynamic_pointer_cast( - theConstraint->data()->attribute(SketchPlugin_Constraint::ATTRIBUTE(indAttr)) - ); - if (!anAttr || !anAttr->isObject() || !anAttr->object()) continue; - const std::string& aKind = boost::dynamic_pointer_cast - (anAttr->object())->getKind(); - if (aKind.compare(SketchPlugin_Line::ID()) == 0) - { + if (isParallel || isPerpendicular) { + int aNbEntities = 2; // lines in SolveSpace constraints should start from SketchPlugin_Constraint::ENTITY_C() attribute + for (unsigned int indAttr = 0; indAttr < CONSTRAINT_ATTR_SIZE; indAttr++) { + std::shared_ptr anAttr = + aConstrData->attribute(SketchPlugin_Constraint::ATTRIBUTE(indAttr)); + if (typeOfAttribute(anAttr) == LINE) myAttributesList[aNbEntities++] = SketchPlugin_Constraint::ATTRIBUTE(indAttr); - continue; - } } if (aNbEntities == 4) myType = isParallel ? SLVS_C_PARALLEL : SLVS_C_PERPENDICULAR; @@ -200,30 +167,75 @@ const int& SketchSolver_Constraint::getType(boost::shared_ptr anAttr = - boost::dynamic_pointer_cast( - theConstraint->data()->attribute(SketchPlugin_Constraint::ATTRIBUTE(indAttr)) - ); - if (!anAttr || !anAttr->isObject() || !anAttr->object()) continue; - const std::string& aKind = boost::dynamic_pointer_cast - (anAttr->object())->getKind(); - if (aKind.compare(SketchPlugin_Circle::ID()) == 0 || aKind.compare(SketchPlugin_Arc::ID()) == 0) - { + if (aConstraintKind.compare(SketchPlugin_ConstraintRadius::ID()) == 0) { + int aNbEntities = 2; // lines in SolveSpace constraints should started from SketchPlugin_Constraint::ENTITY_C() attribute + for (unsigned int indAttr = 0; indAttr < CONSTRAINT_ATTR_SIZE; indAttr++) { + std::shared_ptr anAttr = + aConstrData->attribute(SketchPlugin_Constraint::ATTRIBUTE(indAttr)); + AttrType aType = typeOfAttribute(anAttr); + if (aType == CIRCLE || aType == ARC) myAttributesList[aNbEntities++] = SketchPlugin_Constraint::ATTRIBUTE(indAttr); - continue; - } } if (aNbEntities == 3) myType = SLVS_C_DIAMETER; return getType(); } - /// \todo Implement other kind of constrtaints + // Constraint for fixed entity + if (aConstraintKind.compare(SketchPlugin_ConstraintRigid::ID()) == 0) { + // Verify that only one entity is filled + int aNbAttrs = 0; + for (unsigned int indAttr = 0; indAttr < CONSTRAINT_ATTR_SIZE; indAttr++) { + std::shared_ptr anAttr = + aConstrData->attribute(SketchPlugin_Constraint::ATTRIBUTE(indAttr)); + AttrType aType = typeOfAttribute(anAttr); + if (aType != UNKNOWN) + myAttributesList[aNbAttrs++] = SketchPlugin_Constraint::ATTRIBUTE(indAttr); + } + if (aNbAttrs == 1) + myType = SLVS_C_WHERE_DRAGGED; + return getType(); + } + + /// \todo Implement other kind of constraints return getType(); } + +// ================= Auxiliary functions ============================== +AttrType typeOfAttribute(std::shared_ptr theAttribute) +{ + std::shared_ptr anAttrRef = std::dynamic_pointer_cast< + ModelAPI_AttributeRefAttr>(theAttribute); + if (!anAttrRef) + return UNKNOWN; + + if (anAttrRef->isObject()) { + ResultConstructionPtr aRC = std::dynamic_pointer_cast( + anAttrRef->object()); + if (!aRC || !aRC->shape()) + return UNKNOWN; + + if (aRC->shape()->isVertex()) + return POINT3D; + else if (aRC->shape()->isEdge()) { + std::shared_ptr anEdge = std::dynamic_pointer_cast( + aRC->shape()); + if (anEdge->isLine()) + return LINE; + else if (anEdge->isCircle()) + return CIRCLE; + else if (anEdge->isArc()) + return ARC; + } + } else { + const std::string aType = anAttrRef->attr()->attributeType(); + if (aType == GeomDataAPI_Point2D::type()) + return POINT2D; + if (aType == GeomDataAPI_Point2D::type()) + return POINT2D; + } + + return UNKNOWN; +} +