From 1937728eb351f6be6e8c0578bdec33914dbdb765 Mon Sep 17 00:00:00 2001 From: azv Date: Thu, 24 Dec 2015 08:32:26 +0300 Subject: [PATCH] Update SketchPlugin_Point and external features processing in PlaneGCSSolver (issue #1167) --- .../PlaneGCSSolver/PlaneGCSSolver_Builder.cpp | 39 ++++++---- .../PlaneGCSSolver/PlaneGCSSolver_Storage.cpp | 78 ++++++++++++------- 2 files changed, 78 insertions(+), 39 deletions(-) diff --git a/src/SketchSolver/PlaneGCSSolver/PlaneGCSSolver_Builder.cpp b/src/SketchSolver/PlaneGCSSolver/PlaneGCSSolver_Builder.cpp index 135eebd94..9d7d63f2f 100644 --- a/src/SketchSolver/PlaneGCSSolver/PlaneGCSSolver_Builder.cpp +++ b/src/SketchSolver/PlaneGCSSolver/PlaneGCSSolver_Builder.cpp @@ -183,25 +183,32 @@ std::list PlaneGCSSolver_Builder::createConstraint( { ConstraintWrapperPtr aResult; ParameterWrapperPtr anIntermediate; + + std::shared_ptr aPoint1 = GCS_POINT_WRAPPER(thePoint1); + if (!aPoint1 && thePoint1->type() == ENTITY_POINT) + aPoint1 = GCS_POINT_WRAPPER( GCS_ENTITY_WRAPPER(thePoint1)->subEntities().front() ); + std::shared_ptr aPoint2 = GCS_POINT_WRAPPER(thePoint2); + if (!aPoint2 && thePoint2->type() == ENTITY_POINT) + aPoint2 = GCS_POINT_WRAPPER( GCS_ENTITY_WRAPPER(thePoint2)->subEntities().front() ); + switch (theType) { case CONSTRAINT_PT_PT_COINCIDENT: - aResult = createConstraintCoincidence(theConstraint, theGroupID, - GCS_POINT_WRAPPER(thePoint1), GCS_POINT_WRAPPER(thePoint2)); + aResult = createConstraintCoincidence(theConstraint, theGroupID, aPoint1, aPoint2); break; case CONSTRAINT_PT_ON_LINE: case CONSTRAINT_PT_ON_CIRCLE: aResult = createConstraintPointOnEntity(theConstraint, theGroupID, theType, - GCS_POINT_WRAPPER(thePoint1), GCS_ENTITY_WRAPPER(theEntity1)); + aPoint1, GCS_ENTITY_WRAPPER(theEntity1)); break; case CONSTRAINT_PT_PT_DISTANCE: aResult = createConstraintDistancePointPoint(theConstraint, theGroupID, GCS_PARAMETER_WRAPPER(createParameter(GID_OUTOFGROUP, theValue)), - GCS_POINT_WRAPPER(thePoint1), GCS_POINT_WRAPPER(thePoint2)); + aPoint1, aPoint2); break; case CONSTRAINT_PT_LINE_DISTANCE: aResult = createConstraintDistancePointLine(theConstraint, theGroupID, GCS_PARAMETER_WRAPPER(createParameter(GID_OUTOFGROUP, theValue)), - GCS_POINT_WRAPPER(thePoint1), GCS_ENTITY_WRAPPER(theEntity1)); + aPoint1, GCS_ENTITY_WRAPPER(theEntity1)); break; case CONSTRAINT_RADIUS: aResult = createConstraintRadius(theConstraint, theGroupID, @@ -304,10 +311,12 @@ std::list PlaneGCSSolver_Builder::createMirror( if (theEntity2->group() == theGroupID) // theEntity2 is not fixed makeMirrorPoints(theEntity1, theEntity2, theMirrorLine); - std::shared_ptr aPoint1 = - std::dynamic_pointer_cast(theEntity1); - std::shared_ptr aPoint2 = - std::dynamic_pointer_cast(theEntity2); + std::shared_ptr aPoint1 = GCS_POINT_WRAPPER(theEntity1); + if (!aPoint1 && theEntity1->type() == ENTITY_POINT) + aPoint1 = GCS_POINT_WRAPPER( GCS_ENTITY_WRAPPER(theEntity1)->subEntities().front() ); + std::shared_ptr aPoint2 = GCS_POINT_WRAPPER(theEntity2); + if (!aPoint2 && theEntity2->type() == ENTITY_POINT) + aPoint2 = GCS_POINT_WRAPPER( GCS_ENTITY_WRAPPER(theEntity2)->subEntities().front() ); std::shared_ptr aMirrorLine = std::dynamic_pointer_cast(theMirrorLine); @@ -476,10 +485,14 @@ EntityWrapperPtr PlaneGCSSolver_Builder::createFeature( return createArc(theFeature, theAttributes, theGroupID); // Point (it has low probability to be an attribute of constraint, so it is checked at the end) else if (aFeatureKind == SketchPlugin_Point::ID()) { - AttributePtr aPoint = theFeature->attribute(SketchPlugin_Point::COORD_ID()); - if (!aPoint->isInitialized()) - return aDummy; - EntityWrapperPtr aSub = createAttribute(aPoint, theGroupID); + EntityWrapperPtr aSub; + if (theAttributes.size() == 1) + aSub = theAttributes.front(); + else { + AttributePtr aPoint = theFeature->attribute(SketchPlugin_Point::COORD_ID()); + if (aPoint->isInitialized()) + aSub = createAttribute(aPoint, theGroupID); + } if (!aSub) return aDummy; diff --git a/src/SketchSolver/PlaneGCSSolver/PlaneGCSSolver_Storage.cpp b/src/SketchSolver/PlaneGCSSolver/PlaneGCSSolver_Storage.cpp index 0d12d6d47..5e530e951 100644 --- a/src/SketchSolver/PlaneGCSSolver/PlaneGCSSolver_Storage.cpp +++ b/src/SketchSolver/PlaneGCSSolver/PlaneGCSSolver_Storage.cpp @@ -160,6 +160,10 @@ bool PlaneGCSSolver_Storage::update(EntityWrapperPtr theEntity) if (theEntity->type() == ENTITY_POINT) { std::shared_ptr aPoint = std::dynamic_pointer_cast(theEntity); + if (!aPoint) { + aPoint = std::dynamic_pointer_cast( + theEntity->subEntities().front()); + } aPoint->setId(++myEntityLastID); } else if (theEntity->type() == ENTITY_SCALAR) { std::shared_ptr aScalar = @@ -260,16 +264,27 @@ void PlaneGCSSolver_Storage::addCoincidentPoints( if (theMaster->type() != ENTITY_POINT || theSlave->type() != ENTITY_POINT) return; + std::shared_ptr aMaster = + std::dynamic_pointer_cast(theMaster); + if (!aMaster) + aMaster = std::dynamic_pointer_cast( + std::dynamic_pointer_cast(theMaster)->subEntities().front()); + std::shared_ptr aSlave = + std::dynamic_pointer_cast(theSlave); + if (!aSlave) + aSlave = std::dynamic_pointer_cast( + std::dynamic_pointer_cast(theSlave)->subEntities().front()); + // Search available coincidence - CoincidentPointsMap::iterator aMasterFound = myCoincidentPoints.find(theMaster); - CoincidentPointsMap::iterator aSlaveFound = myCoincidentPoints.find(theSlave); + CoincidentPointsMap::iterator aMasterFound = myCoincidentPoints.find(aMaster); + CoincidentPointsMap::iterator aSlaveFound = myCoincidentPoints.find(aSlave); if (aMasterFound == myCoincidentPoints.end() && aSlaveFound == myCoincidentPoints.end()) { // try to find master and slave points in the lists of slaves of already existent coincidences CoincidentPointsMap::iterator anIt = myCoincidentPoints.begin(); for (; anIt != myCoincidentPoints.end(); ++anIt) { - if (anIt->second.find(theMaster) != anIt->second.end()) + if (anIt->second.find(aMaster) != anIt->second.end()) aMasterFound = anIt; - else if (anIt->second.find(theSlave) != anIt->second.end()) + else if (anIt->second.find(aSlave) != anIt->second.end()) aSlaveFound = anIt; if (aMasterFound != myCoincidentPoints.end() && aSlaveFound != myCoincidentPoints.end()) @@ -279,8 +294,8 @@ void PlaneGCSSolver_Storage::addCoincidentPoints( if (aMasterFound == myCoincidentPoints.end()) { // create new group - myCoincidentPoints[theMaster] = std::set(); - aMasterFound = myCoincidentPoints.find(theMaster); + myCoincidentPoints[aMaster] = std::set(); + aMasterFound = myCoincidentPoints.find(aMaster); } else if (aMasterFound == aSlaveFound) return; // already coincident @@ -292,17 +307,17 @@ void PlaneGCSSolver_Storage::addCoincidentPoints( std::set::const_iterator aSlIt = aNewSlaves.begin(); for (; aSlIt != aNewSlaves.end(); ++aSlIt) - addCoincidentPoints(theMaster, *aSlIt); + addCoincidentPoints(aMaster, *aSlIt); } else { -//// std::list aSlaveParams = theSlave->parameters(); -//// theSlave->setParameters(theMaster->parameters()); -//// -//// // Remove slave's parameters -//// std::list::iterator aParIt = aSlaveParams.begin(); -//// for (; aParIt != aSlaveParams.end(); ++aParIt) -//// remove(*aParIt); + //std::list aSlaveParams = aSlave->parameters(); + //aSlave->setParameters(aMaster->parameters()); + + //// Remove slave's parameters + //std::list::iterator aParIt = aSlaveParams.begin(); + //for (; aParIt != aSlaveParams.end(); ++aParIt) + // remove(*aParIt); - aMasterFound->second.insert(theSlave); + aMasterFound->second.insert(aSlave); } } @@ -1019,11 +1034,12 @@ void PlaneGCSSolver_Storage::refresh(bool theFixedOnly) const for (; anIt != myAttributeMap.end(); ++anIt) { // the external feature always should keep the up to date values, so, // refresh from the solver is never needed + bool isExternal = false; if (anIt->first.get()) { std::shared_ptr aSketchFeature = std::dynamic_pointer_cast(anIt->first->owner()); if (aSketchFeature.get() && aSketchFeature->isExternal()) - continue; + isExternal = true; } // update parameter wrappers and obtain values of attributes @@ -1032,7 +1048,8 @@ void PlaneGCSSolver_Storage::refresh(bool theFixedOnly) const bool isUpd[3] = {false}; int i = 0; for (aParIt = aParams.begin(); i < 3 && aParIt != aParams.end(); ++aParIt, ++i) { - if (!theFixedOnly || (*aParIt)->group() == GID_OUTOFGROUP || (*aParIt)->isParametric()) { + if (!theFixedOnly || isExternal || + (*aParIt)->group() == GID_OUTOFGROUP || (*aParIt)->isParametric()) { aCoords[i] = (*aParIt)->value(); isUpd[i] = true; } @@ -1044,24 +1061,33 @@ void PlaneGCSSolver_Storage::refresh(bool theFixedOnly) const std::dynamic_pointer_cast(anIt->first); if (aPoint2D) { if ((isUpd[0] && fabs(aPoint2D->x() - aCoords[0]) > tolerance) || - (isUpd[1] && fabs(aPoint2D->y() - aCoords[1]) > tolerance)) { - if (!isUpd[0]) aCoords[0] = aPoint2D->x(); - if (!isUpd[1]) aCoords[1] = aPoint2D->y(); + (isUpd[1] && fabs(aPoint2D->y() - aCoords[1]) > tolerance) || isExternal) { + if (!isUpd[0] || isExternal) aCoords[0] = aPoint2D->x(); + if (!isUpd[1] || isExternal) aCoords[1] = aPoint2D->y(); aPoint2D->setValue(aCoords[0], aCoords[1]); // Find points coincident with this one (probably not in GID_OUTOFGROUP) - std::map::const_iterator aLocIt = - theFixedOnly ? myAttributeMap.begin() : anIt; - for (++aLocIt; aLocIt != myAttributeMap.end(); ++aLocIt) - if (anIt->second->id() == aLocIt->second->id()) { - aPoint2D = std::dynamic_pointer_cast(aLocIt->first); + CoincidentPointsMap::const_iterator aCoincIt = myCoincidentPoints.begin(); + for (; aCoincIt != myCoincidentPoints.end(); ++aCoincIt) + if (aCoincIt->first == anIt->second || + aCoincIt->second.find(anIt->second) != aCoincIt->second.end()) + break; + if (aCoincIt != myCoincidentPoints.end()) { + aPoint2D = std::dynamic_pointer_cast( + aCoincIt->first->baseAttribute()); + if (aPoint2D) + aPoint2D->setValue(aCoords[0], aCoords[1]); + std::set::const_iterator aSlaveIt = aCoincIt->second.begin(); + for (; aSlaveIt != aCoincIt->second.end(); ++aSlaveIt) { + aPoint2D = std::dynamic_pointer_cast((*aSlaveIt)->baseAttribute()); if (aPoint2D) aPoint2D->setValue(aCoords[0], aCoords[1]); } + } } continue; } AttributeDoublePtr aScalar = std::dynamic_pointer_cast(anIt->first); - if (aScalar) { + if (aScalar && !isExternal) { if (isUpd[0] && fabs(aScalar->value() - aCoords[0]) > tolerance) aScalar->setValue(aCoords[0]); continue; -- 2.39.2