From 5a164a3520051f4c52642e8bd0baf38c5ed4c4b5 Mon Sep 17 00:00:00 2001 From: nds Date: Mon, 28 Dec 2015 13:58:01 +0300 Subject: [PATCH] Sketch should stop contour in origin point if the contour is closed. Scenario: 1. Start sketch creation in Origin 2. Create contour 3. Finish the contour in Origin. The line creation operation should stop. --- src/PartSet/PartSet_Tools.cpp | 43 ++++++++++++++++++++++++++- src/PartSet/PartSet_Tools.h | 5 +++- src/PartSet/PartSet_WidgetPoint2d.cpp | 34 ++++++++++++++------- 3 files changed, 69 insertions(+), 13 deletions(-) diff --git a/src/PartSet/PartSet_Tools.cpp b/src/PartSet/PartSet_Tools.cpp index 893e692c7..002f148e5 100755 --- a/src/PartSet/PartSet_Tools.cpp +++ b/src/PartSet/PartSet_Tools.cpp @@ -728,8 +728,37 @@ std::shared_ptr PartSet_Tools::getPoint(std::shared_ptr(); } +FeaturePtr findFirstCoincidenceByData(const DataPtr& theData, std::shared_ptr thePoint) +{ + FeaturePtr aCoincident; + + const std::set& aRefsList = theData->refsToMe(); + std::set::const_iterator aIt; + for (aIt = aRefsList.cbegin(); aIt != aRefsList.cend(); ++aIt) { + std::shared_ptr aAttr = (*aIt); + FeaturePtr aConstrFeature = std::dynamic_pointer_cast(aAttr->owner()); + if (aConstrFeature->getKind() == SketchPlugin_ConstraintCoincidence::ID()) { + std::shared_ptr a2dPnt = + PartSet_Tools::getPoint(aConstrFeature, SketchPlugin_ConstraintCoincidence::ENTITY_A()); + if (a2dPnt.get() && thePoint->isEqual(a2dPnt)) { + aCoincident = aConstrFeature; + break; + } else { + a2dPnt = PartSet_Tools::getPoint(aConstrFeature, + SketchPlugin_ConstraintCoincidence::ENTITY_B()); + if (a2dPnt.get() && thePoint->isEqual(a2dPnt)) { + aCoincident = aConstrFeature; + break; + } + } + } + } + return aCoincident; +} + FeaturePtr PartSet_Tools::findFirstCoincidence(const FeaturePtr& theFeature, - std::shared_ptr thePoint) + std::shared_ptr thePoint, + const bool theSearchInResults) { FeaturePtr aCoincident; if (theFeature.get() == NULL) @@ -756,6 +785,18 @@ FeaturePtr PartSet_Tools::findFirstCoincidence(const FeaturePtr& theFeature, } } } + if (theSearchInResults) { + if (!aCoincident.get()) { + std::list aResults = theFeature->results(); + std::list::const_iterator aIt; + for (aIt = aResults.cbegin(); aIt != aResults.cend(); ++aIt) { + ResultPtr aResult = *aIt; + aCoincident = findFirstCoincidenceByData(aResult->data(), thePoint); + if (aCoincident.get()) + break; + } + } + } return aCoincident; } diff --git a/src/PartSet/PartSet_Tools.h b/src/PartSet/PartSet_Tools.h index 195de10b5..b7a31b4ac 100755 --- a/src/PartSet/PartSet_Tools.h +++ b/src/PartSet/PartSet_Tools.h @@ -203,10 +203,13 @@ class PARTSET_EXPORT PartSet_Tools * Gets all references to the feature, take coincidence constraint features, get point 2d attributes * and compare the point value to be equal with the given. Returns the first feature, which has * equal points. + * \param theSearchInResults a flag whether the conicidence feature shoudl be searched in + * references of the feature results. * \return the coincidence feature or null */ static FeaturePtr findFirstCoincidence(const FeaturePtr& theFeature, - std::shared_ptr thePoint); + std::shared_ptr thePoint, + const bool theSearchInResults = false); /** * Returns list of features connected in a councedence feature point diff --git a/src/PartSet/PartSet_WidgetPoint2d.cpp b/src/PartSet/PartSet_WidgetPoint2d.cpp index 477da7ae3..9e380d431 100644 --- a/src/PartSet/PartSet_WidgetPoint2d.cpp +++ b/src/PartSet/PartSet_WidgetPoint2d.cpp @@ -365,17 +365,15 @@ void PartSet_WidgetPoint2D::onMouseRelease(ModuleBase_IViewWindow* theWnd, QMous ObjectPtr aObject = aObjects.front(); FeaturePtr aSelectedFeature = ModelAPI_Feature::feature(aObject); bool anExternal = false; - std::shared_ptr aSPFeature; - if (aSelectedFeature.get() != NULL) - aSPFeature = std::dynamic_pointer_cast(aSelectedFeature); + std::shared_ptr aSPFeature; + if (aSelectedFeature.get() != NULL) + aSPFeature = std::dynamic_pointer_cast(aSelectedFeature); if ((!aSPFeature && !aShape.IsNull()) || (aSPFeature.get() && aSPFeature->isExternal())) { anExternal = true; ResultPtr aFixedObject = PartSet_Tools::findFixedObjectByExternal(aShape, aObject, mySketch); if (!aFixedObject.get()) - aObject = PartSet_Tools::createFixedObjectByExternal(aShape, aObject, mySketch); - else - aObject = aFixedObject; + aFixedObject = PartSet_Tools::createFixedObjectByExternal(aShape, aObject, mySketch); double aX, aY; if (getPoint2d(aView, aShape, aX, aY) && isFeatureContainsPoint(myFeature, aX, aY)) { @@ -390,12 +388,24 @@ void PartSet_WidgetPoint2D::onMouseRelease(ModuleBase_IViewWindow* theWnd, QMous setValueState(Stored); // in case of edge selection, Apply state should also be updated bool anOrphanPoint = aShape.ShapeType() == TopAbs_VERTEX || isOrphanPoint(aSelectedFeature, mySketch, aX, aY); - setConstraintWith(aObject); + if (anExternal) { + anOrphanPoint = true; // we should not stop reentrant operation on external objects because + // they are not participate in the contour creation excepting external vertices + if (aShape.ShapeType() == TopAbs_VERTEX) { + FeaturePtr aFixedFeature = ModelAPI_Feature::feature(aFixedObject); + if (aFixedFeature.get() && aFixedFeature->getKind() == SketchPlugin_Point::ID()) { + anOrphanPoint = isOrphanPoint(aFixedFeature, mySketch, aX, aY, true); + } + } + } + + setConstraintWith(aFixedObject); // fignal updated should be flushed in order to visualize possible created external objects // e.g. selection of trihedron axis when input end arc point updateObject(feature()); - if (!anOrphanPoint && !anExternal) - emit vertexSelected(); + + if (!anOrphanPoint) + emit vertexSelected(); // it stops the reentrant operation emit focusOutWidget(this); } @@ -551,7 +561,7 @@ bool PartSet_WidgetPoint2D::useSelectedShapes() const bool PartSet_WidgetPoint2D::isOrphanPoint(const FeaturePtr& theFeature, const CompositeFeaturePtr& theSketch, - double theX, double theY) + double theX, double theY, const bool theSearchInResults) { bool anOrphanPoint = false; if (theFeature.get()) { @@ -580,7 +590,9 @@ bool PartSet_WidgetPoint2D::isOrphanPoint(const FeaturePtr& theFeature, if (aPointAttr.get()) { std::shared_ptr aPoint = aPointAttr->pnt(); - FeaturePtr aCoincidence = PartSet_Tools::findFirstCoincidence(theFeature, aPoint); + // we need to find coincidence features in results also, because external object(point) + // uses refs to me in another feature. + FeaturePtr aCoincidence = PartSet_Tools::findFirstCoincidence(theFeature, aPoint, theSearchInResults); anOrphanPoint = true; // if there is at least one concident line to the point, the point is not an orphant if (aCoincidence.get()) { -- 2.39.2