From b408cb51f90858ed96f182df1e6cd3c4d75cb614 Mon Sep 17 00:00:00 2001 From: nds Date: Thu, 5 Nov 2015 18:53:52 +0300 Subject: [PATCH] #1017 Can build lines through several created points #1035 Sketcher : polyline creation through existing points --- src/PartSet/PartSet_MenuMgr.cpp | 23 +------------ src/PartSet/PartSet_Tools.cpp | 29 ++++++++++++++++ src/PartSet/PartSet_Tools.h | 9 +++++ src/PartSet/PartSet_WidgetPoint2d.cpp | 48 +++++++++++++++++++++++++-- src/PartSet/PartSet_WidgetPoint2d.h | 7 ++++ 5 files changed, 92 insertions(+), 24 deletions(-) diff --git a/src/PartSet/PartSet_MenuMgr.cpp b/src/PartSet/PartSet_MenuMgr.cpp index 28013c9df..b840d7b37 100644 --- a/src/PartSet/PartSet_MenuMgr.cpp +++ b/src/PartSet/PartSet_MenuMgr.cpp @@ -149,28 +149,7 @@ bool PartSet_MenuMgr::addViewerMenu(QMenu* theMenu, const QMap& aRefsList = aFeature->data()->refsToMe(); - std::set::const_iterator aIt; - FeaturePtr aCoincident; - 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() && aSelPnt->isEqual(a2dPnt)) { - aCoincident = aConstrFeature; - break; - } else { - a2dPnt = PartSet_Tools::getPoint(aConstrFeature, - SketchPlugin_ConstraintCoincidence::ENTITY_B()); - if (a2dPnt.get() && aSelPnt->isEqual(a2dPnt)) { - aCoincident = aConstrFeature; - break; - } - } - } - } + FeaturePtr aCoincident = PartSet_Tools::findFirstCoincidence(aFeature, aSelPnt); // If we have coincidence then add Detach menu if (aCoincident.get() != NULL) { mySelectedFeature = aCoincident; diff --git a/src/PartSet/PartSet_Tools.cpp b/src/PartSet/PartSet_Tools.cpp index ed69af84a..f9dfb6c0b 100755 --- a/src/PartSet/PartSet_Tools.cpp +++ b/src/PartSet/PartSet_Tools.cpp @@ -728,6 +728,35 @@ std::shared_ptr PartSet_Tools::getPoint(std::shared_ptr(); } +FeaturePtr PartSet_Tools::findFirstCoincidence(const FeaturePtr& theFeature, + std::shared_ptr thePoint) +{ + FeaturePtr aCoincident; + + const std::set& aRefsList = theFeature->data()->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; +} + void PartSet_Tools::findCoincidences(FeaturePtr theStartCoin, QList& theList, std::string theAttr) { diff --git a/src/PartSet/PartSet_Tools.h b/src/PartSet/PartSet_Tools.h index 438135840..195de10b5 100755 --- a/src/PartSet/PartSet_Tools.h +++ b/src/PartSet/PartSet_Tools.h @@ -199,6 +199,15 @@ class PARTSET_EXPORT PartSet_Tools static std::shared_ptr getPoint(std::shared_ptr& theFeature, const std::string& theAttribute); + /** + * 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. + * \return the coincidence feature or null + */ + static FeaturePtr findFirstCoincidence(const FeaturePtr& theFeature, + std::shared_ptr thePoint); + /** * Returns list of features connected in a councedence feature point * \param theStartCoin the coincidence feature diff --git a/src/PartSet/PartSet_WidgetPoint2d.cpp b/src/PartSet/PartSet_WidgetPoint2d.cpp index 66a67efc4..53b403e60 100644 --- a/src/PartSet/PartSet_WidgetPoint2d.cpp +++ b/src/PartSet/PartSet_WidgetPoint2d.cpp @@ -336,8 +336,10 @@ void PartSet_WidgetPoint2D::onMouseRelease(ModuleBase_IViewWindow* theWnd, QMous else { if (getPoint2d(aView, aShape, aX, aY)) setPoint(aX, aY); + bool anOrphanPoint = isOrphanPoint(aSelectedFeature, mySketch); setConstraintWith(aObject); - emit vertexSelected(); + if (!anOrphanPoint) + emit vertexSelected(); emit focusOutWidget(this); } } @@ -351,6 +353,7 @@ void PartSet_WidgetPoint2D::onMouseRelease(ModuleBase_IViewWindow* theWnd, QMous setPoint(aX, aY); } else { + bool anOrphanPoint = isOrphanPoint(aSelectedFeature, mySketch); // do not set a coincidence constraint in the attribute if the feature contains a point // with the same coordinates. It is important for line creation in order to do not set // the same constraints for the same points, oterwise the result line has zero length. @@ -369,7 +372,8 @@ void PartSet_WidgetPoint2D::onMouseRelease(ModuleBase_IViewWindow* theWnd, QMous // points of the line becomes less than the tolerance. Validator of the line returns // false, the line will be aborted, but sketch stays valid. updateObject(feature()); - emit vertexSelected(); + if (!anOrphanPoint) + emit vertexSelected(); emit focusOutWidget(this); } } @@ -476,3 +480,43 @@ bool PartSet_WidgetPoint2D::processEnter() } return isModified; } + +bool PartSet_WidgetPoint2D::isOrphanPoint(const FeaturePtr& theFeature, + const CompositeFeaturePtr& theSketch) +{ + bool anOrphanPoint = false; + if (theFeature.get()) { + std::shared_ptr aPointAttr; + std::string aFeatureKind = theFeature->getKind(); + if (aFeatureKind == SketchPlugin_Point::ID()) + aPointAttr = std::dynamic_pointer_cast( + theFeature->attribute(SketchPlugin_Point::COORD_ID())); + else if (aFeatureKind == SketchPlugin_Circle::ID()) + aPointAttr = std::dynamic_pointer_cast( + theFeature->attribute(SketchPlugin_Circle::CENTER_ID())); + + else if (aFeatureKind == SketchPlugin_Arc::ID()) + aPointAttr = std::dynamic_pointer_cast( + theFeature->attribute(SketchPlugin_Arc::CENTER_ID())); + + if (aPointAttr.get()) { + std::shared_ptr aPoint = aPointAttr->pnt(); + FeaturePtr aCoincidence = PartSet_Tools::findFirstCoincidence(theFeature, aPoint); + anOrphanPoint = true; + // if there is at least one concident line to the point, the point is not an orphant + if (aCoincidence.get()) { + QList aCoinsideLines; + PartSet_Tools::findCoincidences(aCoincidence, aCoinsideLines, + SketchPlugin_ConstraintCoincidence::ENTITY_A()); + PartSet_Tools::findCoincidences(aCoincidence, aCoinsideLines, + SketchPlugin_ConstraintCoincidence::ENTITY_B()); + QList::const_iterator anIt = aCoinsideLines.begin(), + aLast = aCoinsideLines.end(); + for (; anIt != aLast && anOrphanPoint; anIt++) { + anOrphanPoint = (*anIt)->getKind() != SketchPlugin_Line::ID(); + } + } + } + } + return anOrphanPoint; +} diff --git a/src/PartSet/PartSet_WidgetPoint2d.h b/src/PartSet/PartSet_WidgetPoint2d.h index a2dd6673c..eb277a883 100755 --- a/src/PartSet/PartSet_WidgetPoint2d.h +++ b/src/PartSet/PartSet_WidgetPoint2d.h @@ -141,6 +141,13 @@ protected: /// \theObject a result object void setConstraintWith(const ObjectPtr& theObject); + /// Returns if the feature is an orphan point, circle or an arc. Returns true if it + /// has no a coincident to other lines. In Circle and arc only center points are processed. + /// \param theFeature a checked feature + /// \param theSketch a sketch + /// \return boolean result + static bool isOrphanPoint(const FeaturePtr& theFeature, const CompositeFeaturePtr& theSketch); + protected: ModuleBase_IWorkshop* myWorkshop; ///< workshop -- 2.39.2