From 417d68795a489d77f81650584dab4f8282304081 Mon Sep 17 00:00:00 2001 From: azv Date: Thu, 9 Jan 2020 13:07:08 +0300 Subject: [PATCH] Issue #17347: B-Splines in Sketcher Moving B-spline or its extremity points. --- src/GeomData/GeomData_Point2DArray.cpp | 3 + src/PartSet/PartSet_Module.cpp | 13 ++-- src/PartSet/PartSet_SketcherMgr.cpp | 33 +++++---- src/PartSet/PartSet_SketcherMgr.h | 3 +- src/PartSet/PartSet_Tools.cpp | 74 ++++++++++++++----- src/PartSet/PartSet_Tools.h | 6 +- .../SketchSolver_ConstraintFixed.cpp | 10 +++ 7 files changed, 98 insertions(+), 44 deletions(-) diff --git a/src/GeomData/GeomData_Point2DArray.cpp b/src/GeomData/GeomData_Point2DArray.cpp index 27376b988..4f18c7f76 100644 --- a/src/GeomData/GeomData_Point2DArray.cpp +++ b/src/GeomData/GeomData_Point2DArray.cpp @@ -49,6 +49,9 @@ bool GeomData_Point2DArray::assign(std::shared_ptr the setSize(anOther->size()); myArray->ChangeArray(anOther->myArray->Array(), false); + owner()->data()->sendAttributeUpdated(this); + + return true; } int GeomData_Point2DArray::size() diff --git a/src/PartSet/PartSet_Module.cpp b/src/PartSet/PartSet_Module.cpp index 9c70d7e9f..26a02f0d9 100644 --- a/src/PartSet/PartSet_Module.cpp +++ b/src/PartSet/PartSet_Module.cpp @@ -805,12 +805,12 @@ bool PartSet_Module::createWidgets(const FeaturePtr& theFeature, const QString& return aProcessed; } const TopoDS_Shape& aTDShape = aShape->impl(); - AttributePtr anAttribute = PartSet_Tools::findAttributeBy2dPoint(anObject, aTDShape, - mySketchMgr->activeSketch()); - if (anAttribute.get()) { + std::pair anAttribute = + PartSet_Tools::findAttributeBy2dPoint(anObject, aTDShape, mySketchMgr->activeSketch()); + if (anAttribute.first.get()) { ModuleBase_WidgetFactory aFactory(theXmlRepr.toStdString(), workshop()); - const std::string anAttributeId = anAttribute->id(); + const std::string anAttributeId = anAttribute.first->id(); aFactory.createWidget(aPropertyPanel->contentWidget(), anAttributeId); theWidgets = aFactory.getModelWidgets(); @@ -1735,8 +1735,9 @@ AttributePtr PartSet_Module::findAttribute(const ObjectPtr& theObject, if (aGeomShape.get()) { TopoDS_Shape aTDSShape = aGeomShape->impl(); - return PartSet_Tools::findAttributeBy2dPoint(theObject, aTDSShape, - mySketchMgr->activeSketch()); + std::pair anAttrAndIndex = + PartSet_Tools::findAttributeBy2dPoint(theObject, aTDSShape, mySketchMgr->activeSketch()); + return anAttrAndIndex.first; } return anAttribute; } diff --git a/src/PartSet/PartSet_SketcherMgr.cpp b/src/PartSet/PartSet_SketcherMgr.cpp index 04eec8924..78237ef7f 100644 --- a/src/PartSet/PartSet_SketcherMgr.cpp +++ b/src/PartSet/PartSet_SketcherMgr.cpp @@ -60,6 +60,7 @@ #include #include +#include #include @@ -142,7 +143,7 @@ void getAttributesOrResults(const Handle(SelectMgr_EntityOwner)& theOwner, const FeaturePtr& theFeature, const FeaturePtr& theSketch, const ResultPtr& theResult, - std::set& theSelectedAttributes, + std::map& theSelectedAttributes, std::set& theSelectedResults, TopTools_MapOfShape& theShapes) { @@ -156,10 +157,10 @@ void getAttributesOrResults(const Handle(SelectMgr_EntityOwner)& theOwner, theShapes.Add(aShape); TopAbs_ShapeEnum aShapeType = aShape.ShapeType(); if (aShapeType == TopAbs_VERTEX) { - AttributePtr aPntAttr = PartSet_Tools::findAttributeBy2dPoint(theFeature, - aShape, theSketch); - if (aPntAttr.get() != NULL) - theSelectedAttributes.insert(aPntAttr); + std::pair aPntAttrIndex = + PartSet_Tools::findAttributeBy2dPoint(theFeature, aShape, theSketch); + if (aPntAttrIndex.first.get() != NULL) + theSelectedAttributes[aPntAttrIndex.first] = aPntAttrIndex.second; } else if (aShapeType == TopAbs_EDGE && theSelectedResults.find(theResult) == theSelectedResults.end()) { @@ -640,26 +641,26 @@ void PartSet_SketcherMgr::onMouseMoved(ModuleBase_IViewWindow* theWnd, QMouseEve for (; anIt != aLast; anIt++) { FeaturePtr aFeature = anIt.key(); - std::set anAttributes = anIt.value().myAttributes; + std::map anAttributes = anIt.value().myAttributes; // Process selection by attribute: the priority to the attribute if (!anAttributes.empty()) { - std::set::const_iterator anAttIt = anAttributes.begin(), + std::map::const_iterator anAttIt = anAttributes.begin(), anAttLast = anAttributes.end(); for (; anAttIt != anAttLast; anAttIt++) { - AttributePtr anAttr = *anAttIt; + AttributePtr anAttr = anAttIt->first; if (anAttr.get() == NULL) continue; std::string aAttrId = anAttr->id(); DataPtr aData = aFeature->data(); if (aData->isValid()) { - std::shared_ptr aPoint = - std::dynamic_pointer_cast(aData->attribute(aAttrId)); - if (aPoint.get() != NULL) { + AttributePtr aPoint = aData->attribute(aAttrId); + if (aPoint->attributeType() == GeomDataAPI_Point2D::typeId() || + aPoint->attributeType() == GeomDataAPI_Point2DArray::typeId()) { bool isImmutable = aPoint->setImmutable(true); std::shared_ptr aMessage = std::shared_ptr (new ModelAPI_ObjectMovedMessage(this)); - aMessage->setMovedAttribute(aPoint); + aMessage->setMovedAttribute(aPoint, anAttIt->second); aMessage->setOriginalPosition(anOriginalPosition); aMessage->setCurrentPosition(aCurrentPosition); Events_Loop::loop()->send(aMessage); @@ -1685,7 +1686,7 @@ void PartSet_SketcherMgr::getSelectionOwners(const FeaturePtr& theFeature, FeatureToSelectionMap::const_iterator anIt = theSelection.find(theFeature); SelectionInfo anInfo = anIt.value(); - std::set aSelectedAttributes = anInfo.myAttributes; + std::map aSelectedAttributes = anInfo.myAttributes; std::set aSelectedResults = anInfo.myResults; ModuleBase_IViewer* aViewer = theWorkshop->viewer(); @@ -1737,10 +1738,10 @@ void PartSet_SketcherMgr::getSelectionOwners(const FeaturePtr& theFeature, const TopoDS_Shape& aShape = anOwner->Shape(); TopAbs_ShapeEnum aShapeType = aShape.ShapeType(); if (aShapeType == TopAbs_VERTEX) { - AttributePtr aPntAttr = + std::pair aPntAttrIndex = PartSet_Tools::findAttributeBy2dPoint(theFeature, aShape, theSketch); - if (aPntAttr.get() != NULL && - aSelectedAttributes.find(aPntAttr) != aSelectedAttributes.end()) + if (aPntAttrIndex.first.get() != NULL && + aSelectedAttributes.find(aPntAttrIndex.first) != aSelectedAttributes.end()) theOwnersToSelect.Add(anOwner); else if (isSameShape && anInfo.myLocalSelectedShapes.Contains(aShape)) { theOwnersToSelect.Add(anOwner); diff --git a/src/PartSet/PartSet_SketcherMgr.h b/src/PartSet/PartSet_SketcherMgr.h index 20ee6e659..defc3465b 100644 --- a/src/PartSet/PartSet_SketcherMgr.h +++ b/src/PartSet/PartSet_SketcherMgr.h @@ -137,7 +137,8 @@ public: /// Struct to define selection model information to store/restore selection struct SelectionInfo { - std::set myAttributes; /// the selected attributes + /// the selected attributes and indices of points if array + std::map myAttributes; std::set myResults; /// the selected results TopoDS_Shape myFirstResultShape; /// the first shape of feature result TopTools_MapOfShape myLocalSelectedShapes; /// shapes of local selection diff --git a/src/PartSet/PartSet_Tools.cpp b/src/PartSet/PartSet_Tools.cpp index 759f45bea..50f9efa2e 100644 --- a/src/PartSet/PartSet_Tools.cpp +++ b/src/PartSet/PartSet_Tools.cpp @@ -49,6 +49,7 @@ #include #include #include +#include #include #include #include @@ -443,9 +444,9 @@ GeomShapePtr PartSet_Tools::findShapeBy2DPoint(const AttributePtr& theAttribute, // attribute, returns the shape PartSet_Module* aModule = dynamic_cast(theWorkshop->module()); PartSet_SketcherMgr* aSketchMgr = aModule->sketchMgr(); - AttributePtr aPntAttr = PartSet_Tools::findAttributeBy2dPoint(anAttributeFeature, - aBRepShape, aSketchMgr->activeSketch()); - if (aPntAttr.get() != NULL && aPntAttr == theAttribute) { + std::pair aPntAttrIndex = PartSet_Tools::findAttributeBy2dPoint( + anAttributeFeature, aBRepShape, aSketchMgr->activeSketch()); + if (aPntAttrIndex.first.get() != NULL && aPntAttrIndex.first == theAttribute) { aShape = std::shared_ptr(new GeomAPI_Shape); aShape->setImpl(new TopoDS_Shape(aBRepShape)); break; @@ -648,12 +649,44 @@ std::shared_ptr PartSet_Tools::getCoincedencePoint(FeaturePtr the return aPnt; } -AttributePtr PartSet_Tools::findAttributeBy2dPoint(ObjectPtr theObj, - const TopoDS_Shape theShape, - FeaturePtr theSketch) +class PointWrapper +{ +public: + PointWrapper(AttributePtr theAttribute) + : myPoint(std::dynamic_pointer_cast(theAttribute)), + myArray(std::dynamic_pointer_cast(theAttribute)) + {} + + int size() const { return myPoint.get() ? 1 : (myArray.get() ? myArray->size() : 0); } + + GeomPointPtr point(int theIndex, FeaturePtr theSketch) + { + GeomPnt2dPtr aP2d; + if (myPoint.get()) + aP2d = myPoint->pnt(); + else if (myArray.get()) + aP2d = myArray->pnt(theIndex); + + GeomPointPtr aP3d; + if (aP2d.get()) + aP3d = PartSet_Tools::convertTo3D(aP2d->x(), aP2d->y(), theSketch); + return aP3d; + } + + bool isArray() const { return myArray.get(); } + +private: + AttributePoint2DPtr myPoint; + AttributePoint2DArrayPtr myArray; +}; + +std::pair PartSet_Tools::findAttributeBy2dPoint(ObjectPtr theObj, + const TopoDS_Shape theShape, + FeaturePtr theSketch) { AttributePtr anAttribute; + int aPointIndex = -1; FeaturePtr aFeature = ModelAPI_Feature::feature(theObj); if (aFeature) { if (theShape.ShapeType() == TopAbs_VERTEX) { @@ -666,29 +699,32 @@ AttributePtr PartSet_Tools::findAttributeBy2dPoint(ObjectPtr theObj, // find the given point in the feature attributes std::list anAttiributes = aFeature->data()->attributes(GeomDataAPI_Point2D::typeId()); + std::list anArrays = + aFeature->data()->attributes(GeomDataAPI_Point2DArray::typeId()); + anAttiributes.insert(anAttiributes.end(), anArrays.begin(), anArrays.end()); + std::list::const_iterator anIt = anAttiributes.begin(), aLast = anAttiributes.end(); double aMinDistance = 1.e-6; // searching for point with minimal distance and < 1.e-6 for (; anIt != aLast && !anAttribute; anIt++) { - std::shared_ptr aCurPoint = - std::dynamic_pointer_cast(*anIt); - if (!aCurPoint->isInitialized()) - continue; - - std::shared_ptr aPnt = - convertTo3D(aCurPoint->x(), aCurPoint->y(), theSketch); - if (aPnt) { - double aDistance = aPnt->distance(aValue); - if (aDistance < aMinDistance) { - anAttribute = aCurPoint; - aMinDistance = aPnt->distance(aValue); + PointWrapper aWrapper(*anIt); + for (int anIndex = 0, aSize = aWrapper.size(); anIndex < aSize; ++anIndex) { + std::shared_ptr aPnt = aWrapper.point(anIndex, theSketch); + if (aPnt) { + double aDistance = aPnt->distance(aValue); + if (aDistance < aMinDistance) { + anAttribute = *anIt; + if (aWrapper.isArray()) + aPointIndex = anIndex; + aMinDistance = aPnt->distance(aValue); + } } } } } } } - return anAttribute; + return std::pair(anAttribute, aPointIndex); } void PartSet_Tools::sendSubFeaturesEvent(const CompositeFeaturePtr& theComposite, diff --git a/src/PartSet/PartSet_Tools.h b/src/PartSet/PartSet_Tools.h index 742de4f59..4e82cb451 100644 --- a/src/PartSet/PartSet_Tools.h +++ b/src/PartSet/PartSet_Tools.h @@ -192,9 +192,11 @@ public: * \param theObj - an object * \param theShape - a Shape * \param theSketch - a Sketch to get a plane of converting to 2d + * \return Found attribute and index of point if the attribute is an array */ - static AttributePtr findAttributeBy2dPoint(ObjectPtr theObj, const TopoDS_Shape theShape, - FeaturePtr theSketch); + static std::pair findAttributeBy2dPoint(ObjectPtr theObj, + const TopoDS_Shape theShape, + FeaturePtr theSketch); /** * Finds an attribute value in attribute reference attribute value diff --git a/src/SketchSolver/SketchSolver_ConstraintFixed.cpp b/src/SketchSolver/SketchSolver_ConstraintFixed.cpp index a32e1966f..a56004115 100644 --- a/src/SketchSolver/SketchSolver_ConstraintFixed.cpp +++ b/src/SketchSolver/SketchSolver_ConstraintFixed.cpp @@ -163,6 +163,16 @@ GCS::VEC_pD toParameters(const EntityWrapperPtr& theEntity) aParameters.push_back(anEllArc->endAngle); break; } + case ENTITY_BSPLINE: { + std::shared_ptr aBSpline = + std::dynamic_pointer_cast(anEntity->entity()); + for (GCS::VEC_P::iterator anIt = aBSpline->poles.begin(); + anIt != aBSpline->poles.end(); ++anIt) { + aParameters.push_back(anIt->x); + aParameters.push_back(anIt->y); + } + break; + } default: break; } -- 2.39.2