From 705438fb7ab16ba1608b6b1aeddd546d6311cb77 Mon Sep 17 00:00:00 2001 From: nds Date: Tue, 30 Jun 2015 18:27:31 +0300 Subject: [PATCH] Issue #698 - Distance constraint on circle - crash --- src/PartSet/PartSet_Tools.cpp | 8 +- src/PartSet/PartSet_Tools.h | 8 +- src/PartSet/PartSet_WidgetShapeSelector.cpp | 17 +++- .../SketchPlugin_ConstraintDistance.cpp | 22 +++--- .../SketchPlugin_ConstraintDistance.h | 2 +- src/SketchPlugin/SketchPlugin_Sketch.cpp | 14 ++++ src/SketchPlugin/SketchPlugin_Sketch.h | 4 + src/SketchPlugin/SketchPlugin_Validators.cpp | 7 +- .../SketcherPrs_LengthDimension.cpp | 6 +- src/SketcherPrs/SketcherPrs_LengthDimension.h | 2 +- src/SketcherPrs/SketcherPrs_Tools.cpp | 79 ++++++++++++++++--- src/SketcherPrs/SketcherPrs_Tools.h | 3 +- 12 files changed, 137 insertions(+), 35 deletions(-) diff --git a/src/PartSet/PartSet_Tools.cpp b/src/PartSet/PartSet_Tools.cpp index 7fdc816a3..f5dbff318 100644 --- a/src/PartSet/PartSet_Tools.cpp +++ b/src/PartSet/PartSet_Tools.cpp @@ -233,7 +233,7 @@ std::shared_ptr PartSet_Tools::document() return ModelAPI_Session::get()->moduleDocument(); } -std::shared_ptr PartSet_Tools::getFeaturePoint(FeaturePtr theFeature, +/*std::shared_ptr PartSet_Tools::getFeaturePoint(FeaturePtr theFeature, double theX, double theY) { std::shared_ptr aClickedPoint = std::shared_ptr( @@ -251,7 +251,7 @@ std::shared_ptr PartSet_Tools::getFeaturePoint(FeaturePtr t } return aFPoint; -} +}*/ void PartSet_Tools::setFeatureValue(FeaturePtr theFeature, double theValue, const std::string& theAttribute) @@ -327,7 +327,7 @@ void PartSet_Tools::createConstraint(CompositeFeaturePtr theSketch, aFeature->execute(); } -std::shared_ptr PartSet_Tools:: +/*std::shared_ptr PartSet_Tools:: findAttributePoint(CompositeFeaturePtr theSketch, double theX, double theY, double theTolerance, const QList& theIgnore) { @@ -353,7 +353,7 @@ std::shared_ptr PartSet_Tools:: } } return std::shared_ptr(); -} +}*/ void PartSet_Tools::setConstraints(CompositeFeaturePtr theSketch, FeaturePtr theFeature, diff --git a/src/PartSet/PartSet_Tools.h b/src/PartSet/PartSet_Tools.h index 84b2311a6..1aaf66401 100644 --- a/src/PartSet/PartSet_Tools.h +++ b/src/PartSet/PartSet_Tools.h @@ -89,15 +89,15 @@ class PARTSET_EXPORT PartSet_Tools /// \param theY Y coordinate /// \param theTolerance tolerance /// \param theIgnore list of features which has to be ignored - static std::shared_ptr findAttributePoint(CompositeFeaturePtr theSketch, - double theX, double theY, double theTolerance, const QList& theIgnore = QList()); + //static std::shared_ptr findAttributePoint(CompositeFeaturePtr theSketch, + // double theX, double theY, double theTolerance, const QList& theIgnore = QList()); /// Returns a point attribute of the feature by the coordinates if it is /// \param theFeature the feature /// \param theX the horizontal coordinate /// \param theY the vertical coordinate - static std::shared_ptr getFeaturePoint(FeaturePtr theFeature, - double theX, double theY); + //static std::shared_ptr getFeaturePoint(FeaturePtr theFeature, + // double theX, double theY); /// \brief Save the double to the feature. If the attribute is double, it is filled. /// \param theFeature the feature diff --git a/src/PartSet/PartSet_WidgetShapeSelector.cpp b/src/PartSet/PartSet_WidgetShapeSelector.cpp index 431f1e8a8..ae4a29512 100644 --- a/src/PartSet/PartSet_WidgetShapeSelector.cpp +++ b/src/PartSet/PartSet_WidgetShapeSelector.cpp @@ -28,6 +28,8 @@ #include #include +//#define DEBUG_EMPTY_SHAPE + PartSet_WidgetShapeSelector::PartSet_WidgetShapeSelector(QWidget* theParent, ModuleBase_IWorkshop* theWorkshop, const Config_WidgetAPI* theData, @@ -61,8 +63,21 @@ void PartSet_WidgetShapeSelector::setObject(ObjectPtr theSelectedObject, GeomSha std::shared_ptr aSPFeature = std::dynamic_pointer_cast(aSelectedFeature); // Processing of sketch object - if (aSPFeature.get() != NULL && theShape.get()) +#ifdef DEBUG_EMPTY_SHAPE + if (aSPFeature.get() != NULL && theShape.get()) { setPointAttribute(theSelectedObject, theShape); +#else + if (aSPFeature.get() != NULL) { + GeomShapePtr aShape = theShape; + if (!aShape.get()) { + ResultPtr aResult = std::dynamic_pointer_cast(theSelectedObject); + if (aResult.get()) { + aShape = aResult->shape(); + } + } + setPointAttribute(theSelectedObject, aShape); +#endif + } else ModuleBase_WidgetShapeSelector::setObject(theSelectedObject, theShape); } diff --git a/src/SketchPlugin/SketchPlugin_ConstraintDistance.cpp b/src/SketchPlugin/SketchPlugin_ConstraintDistance.cpp index 11672f77a..a119433d3 100644 --- a/src/SketchPlugin/SketchPlugin_ConstraintDistance.cpp +++ b/src/SketchPlugin/SketchPlugin_ConstraintDistance.cpp @@ -80,10 +80,11 @@ bool SketchPlugin_ConstraintDistance::compute(const std::string& theAttributeId) return false; DataPtr aData = data(); + std::shared_ptr aPlane = SketchPlugin_Sketch::plane(sketch()); std::shared_ptr aPoint_A = SketcherPrs_Tools::getFeaturePoint( - aData, SketchPlugin_Constraint::ENTITY_A()); + aData, SketchPlugin_Constraint::ENTITY_A(), aPlane); std::shared_ptr aPoint_B = SketcherPrs_Tools::getFeaturePoint( - aData, SketchPlugin_Constraint::ENTITY_B()); + aData, SketchPlugin_Constraint::ENTITY_B(), aPlane); std::shared_ptr aPnt_A; std::shared_ptr aPnt_B; @@ -145,10 +146,11 @@ void SketchPlugin_ConstraintDistance::move(double theDeltaX, double theDeltaY) // Recalculate a shift of flyout point in terms of local coordinates std::shared_ptr aDir(new GeomAPI_XY(theDeltaX, theDeltaY)); + std::shared_ptr aPlane = SketchPlugin_Sketch::plane(sketch()); std::shared_ptr aPointA = SketcherPrs_Tools::getFeaturePoint( - data(), SketchPlugin_Constraint::ENTITY_A()); + data(), SketchPlugin_Constraint::ENTITY_A(), aPlane); std::shared_ptr aPointB = SketcherPrs_Tools::getFeaturePoint( - data(), SketchPlugin_Constraint::ENTITY_B()); + data(), SketchPlugin_Constraint::ENTITY_B(), aPlane); std::shared_ptr aStartPnt; std::shared_ptr aEndPnt; @@ -185,15 +187,16 @@ void SketchPlugin_ConstraintDistance::move(double theDeltaX, double theDeltaY) myFlyoutUpdate = false; } -double SketchPlugin_ConstraintDistance::calculateCurrentDistance() const +double SketchPlugin_ConstraintDistance::calculateCurrentDistance() { double aDistance = -1.; std::shared_ptr aData = data(); + std::shared_ptr aPlane = SketchPlugin_Sketch::plane(sketch()); std::shared_ptr aPointA = - SketcherPrs_Tools::getFeaturePoint(aData, SketchPlugin_Constraint::ENTITY_A()); + SketcherPrs_Tools::getFeaturePoint(aData, SketchPlugin_Constraint::ENTITY_A(), aPlane); std::shared_ptr aPointB = - SketcherPrs_Tools::getFeaturePoint(aData, SketchPlugin_Constraint::ENTITY_B()); + SketcherPrs_Tools::getFeaturePoint(aData, SketchPlugin_Constraint::ENTITY_B(), aPlane); if (aPointA.get() && aPointB.get()) { // both points aDistance = aPointA->pnt()->distance(aPointB->pnt()); @@ -241,10 +244,11 @@ void SketchPlugin_ConstraintDistance::attributeChanged(const std::string& theID) attribute(SketchPlugin_Constraint::FLYOUT_VALUE_PNT())); std::shared_ptr aFlyoutPnt = aFlyoutAttr->pnt(); + std::shared_ptr aPlane = SketchPlugin_Sketch::plane(sketch()); std::shared_ptr aPointA = SketcherPrs_Tools::getFeaturePoint( - data(), SketchPlugin_Constraint::ENTITY_A()); + data(), SketchPlugin_Constraint::ENTITY_A(), aPlane); std::shared_ptr aPointB = SketcherPrs_Tools::getFeaturePoint( - data(), SketchPlugin_Constraint::ENTITY_B()); + data(), SketchPlugin_Constraint::ENTITY_B(), aPlane); std::shared_ptr aStartPnt; std::shared_ptr aEndPnt; diff --git a/src/SketchPlugin/SketchPlugin_ConstraintDistance.h b/src/SketchPlugin/SketchPlugin_ConstraintDistance.h index 370519bda..a1e315d2b 100644 --- a/src/SketchPlugin/SketchPlugin_ConstraintDistance.h +++ b/src/SketchPlugin/SketchPlugin_ConstraintDistance.h @@ -68,7 +68,7 @@ class SketchPlugin_ConstraintDistance : public SketchPlugin_ConstraintBase, publ SKETCHPLUGIN_EXPORT virtual void attributeChanged(const std::string& theID); /// Returns the current distance between the feature attributes - double calculateCurrentDistance() const; + double calculateCurrentDistance(); /// Customize presentation of the feature virtual bool customisePresentation(ResultPtr theResult, AISObjectPtr thePrs, diff --git a/src/SketchPlugin/SketchPlugin_Sketch.cpp b/src/SketchPlugin/SketchPlugin_Sketch.cpp index 4c957c648..362e7f56f 100644 --- a/src/SketchPlugin/SketchPlugin_Sketch.cpp +++ b/src/SketchPlugin/SketchPlugin_Sketch.cpp @@ -290,3 +290,17 @@ FeaturePtr SketchPlugin_Sketch::addUniqueNamedCopiedFeature(FeaturePtr theFeatur return aNewFeature; } + +std::shared_ptr SketchPlugin_Sketch::plane(SketchPlugin_Sketch* theSketch) +{ + std::shared_ptr aData = theSketch->data(); + + std::shared_ptr anOrigin = std::dynamic_pointer_cast( + aData->attribute(SketchPlugin_Sketch::ORIGIN_ID())); + std::shared_ptr aDirX = std::dynamic_pointer_cast( + aData->attribute(SketchPlugin_Sketch::DIRX_ID())); + std::shared_ptr aNorm = std::dynamic_pointer_cast( + aData->attribute(SketchPlugin_Sketch::NORM_ID())); + + return std::shared_ptr(new GeomAPI_Ax3(anOrigin->pnt(), aDirX->dir(), aNorm->dir())); +} diff --git a/src/SketchPlugin/SketchPlugin_Sketch.h b/src/SketchPlugin/SketchPlugin_Sketch.h index 2043f33f5..d4117c093 100644 --- a/src/SketchPlugin/SketchPlugin_Sketch.h +++ b/src/SketchPlugin/SketchPlugin_Sketch.h @@ -211,6 +211,10 @@ class SketchPlugin_Sketch : public ModelAPI_CompositeFeature, public GeomAPI_ICu static FeaturePtr addUniqueNamedCopiedFeature(FeaturePtr aFeature, SketchPlugin_Sketch* theSketch); + /// Creates a plane of the sketch. + /// \param theSketch a sketch intance + static std::shared_ptr plane(SketchPlugin_Sketch* theSketch); + /// Customize presentation of the feature virtual bool customisePresentation(ResultPtr theResult, AISObjectPtr thePrs, std::shared_ptr theDefaultPrs) diff --git a/src/SketchPlugin/SketchPlugin_Validators.cpp b/src/SketchPlugin/SketchPlugin_Validators.cpp index 9dfdb5171..597f17d47 100644 --- a/src/SketchPlugin/SketchPlugin_Validators.cpp +++ b/src/SketchPlugin/SketchPlugin_Validators.cpp @@ -66,7 +66,12 @@ bool SketchPlugin_DistanceAttrValidator::isValid( FeaturePtr aFeature = std::dynamic_pointer_cast(theAttribute->owner()); // If it is a line then we have to check that first attribute id not a line - std::shared_ptr aPoint = SketcherPrs_Tools::getFeaturePoint(aFeature->data(), aParamA); + std::shared_ptr aSFeature = + std::dynamic_pointer_cast(theAttribute->owner()); + SketchPlugin_Sketch* aSketch = aSFeature->sketch(); + std::shared_ptr aPlane = SketchPlugin_Sketch::plane(aSketch); + std::shared_ptr aPoint = SketcherPrs_Tools::getFeaturePoint( + aFeature->data(), aParamA, aPlane); if (aPoint) return true; } diff --git a/src/SketcherPrs/SketcherPrs_LengthDimension.cpp b/src/SketcherPrs/SketcherPrs_LengthDimension.cpp index 39d5cfcd7..6e3db9291 100644 --- a/src/SketcherPrs/SketcherPrs_LengthDimension.cpp +++ b/src/SketcherPrs/SketcherPrs_LengthDimension.cpp @@ -90,7 +90,7 @@ void SketcherPrs_LengthDimension::Compute(const Handle(PrsMgr_PresentationManage AIS_LengthDimension::Compute(thePresentationManager, thePresentation, theMode); } -bool SketcherPrs_LengthDimension::getPoints(gp_Pnt& thePnt1, gp_Pnt& thePnt2) const +bool SketcherPrs_LengthDimension::getPoints(gp_Pnt& thePnt1, gp_Pnt& thePnt2) { DataPtr aData = myConstraint->data(); if (myConstraint->getKind() == SketchPlugin_ConstraintLength::ID()) { @@ -117,9 +117,9 @@ bool SketcherPrs_LengthDimension::getPoints(gp_Pnt& thePnt1, gp_Pnt& thePnt2) co } else if (myConstraint->getKind() == SketchPlugin_ConstraintDistance::ID()) { std::shared_ptr aPoint_A = SketcherPrs_Tools::getFeaturePoint( - aData, SketchPlugin_Constraint::ENTITY_A()); + aData, SketchPlugin_Constraint::ENTITY_A(), myPlane); std::shared_ptr aPoint_B = SketcherPrs_Tools::getFeaturePoint( - aData, SketchPlugin_Constraint::ENTITY_B()); + aData, SketchPlugin_Constraint::ENTITY_B(), myPlane); std::shared_ptr aPnt_A; std::shared_ptr aPnt_B; diff --git a/src/SketcherPrs/SketcherPrs_LengthDimension.h b/src/SketcherPrs/SketcherPrs_LengthDimension.h index 5fde8d7aa..703dc9577 100644 --- a/src/SketcherPrs/SketcherPrs_LengthDimension.h +++ b/src/SketcherPrs/SketcherPrs_LengthDimension.h @@ -43,7 +43,7 @@ protected: const Standard_Integer aMode); private: - bool getPoints(gp_Pnt& thePnt1, gp_Pnt& thePnt2) const; + bool getPoints(gp_Pnt& thePnt1, gp_Pnt& thePnt2); /// Constraint feature ModelAPI_Feature* myConstraint; diff --git a/src/SketcherPrs/SketcherPrs_Tools.cpp b/src/SketcherPrs/SketcherPrs_Tools.cpp index 72cc8beee..912ea1446 100644 --- a/src/SketcherPrs/SketcherPrs_Tools.cpp +++ b/src/SketcherPrs/SketcherPrs_Tools.cpp @@ -19,6 +19,12 @@ #include #include +#include +#include +#include + +#include +#include namespace SketcherPrs_Tools { @@ -66,9 +72,49 @@ std::shared_ptr getPoint(ModelAPI_Feature* theFeature, return std::shared_ptr(); } +//************************************************************************************* +std::shared_ptr findGeomPoint(ObjectPtr theObject, + const TopoDS_Shape& theShape, + const std::shared_ptr& thePlane) +{ + std::shared_ptr aGeomPoint; + + FeaturePtr anObjectFeature = ModelAPI_Feature::feature(theObject); + if (anObjectFeature) { + if (theShape.ShapeType() == TopAbs_VERTEX) { + const TopoDS_Vertex& aShapeVertex = TopoDS::Vertex(theShape); + if (!aShapeVertex.IsNull()) { + gp_Pnt aShapePoint = BRep_Tool::Pnt(aShapeVertex); + std::shared_ptr aShapeGeomPnt = std::shared_ptr( + new GeomAPI_Pnt(aShapePoint.X(), aShapePoint.Y(), aShapePoint.Z())); + + // find the given point in the feature attributes + std::list anObjectAttiributes = + anObjectFeature->data()->attributes(GeomDataAPI_Point2D::typeId()); + std::list::const_iterator anIt = anObjectAttiributes.begin(), + aLast = anObjectAttiributes.end(); + for (; anIt != aLast && !aGeomPoint; anIt++) { + std::shared_ptr anAttributePoint = + std::dynamic_pointer_cast(*anIt); + + std::shared_ptr anAttributePnt = thePlane->to3D(anAttributePoint->x(), + anAttributePoint->y()); + if (anAttributePnt.get() && + anAttributePnt->distance(aShapeGeomPnt) < Precision::Confusion()) { + aGeomPoint = anAttributePoint; + break; + } + } + } + } + } + return aGeomPoint; +} + //************************************************************************************* std::shared_ptr getFeaturePoint(DataPtr theData, - const std::string& theAttribute) + const std::string& theAttribute, + const std::shared_ptr& thePlane) { std::shared_ptr aPointAttr; @@ -78,15 +124,28 @@ std::shared_ptr getFeaturePoint(DataPtr theData, FeaturePtr aFeature; std::shared_ptr anAttr = std::dynamic_pointer_cast< ModelAPI_AttributeRefAttr>(theData->attribute(theAttribute)); - if (anAttr) - aFeature = ModelAPI_Feature::feature(anAttr->object()); - - if (aFeature && aFeature->getKind() == SketchPlugin_Point::ID()) - aPointAttr = std::dynamic_pointer_cast( - aFeature->data()->attribute(SketchPlugin_Point::COORD_ID())); - - else if (anAttr->attr()) { - aPointAttr = std::dynamic_pointer_cast(anAttr->attr()); + if (anAttr) { + if (anAttr->isObject()) { + ObjectPtr anObject = anAttr->object(); + aFeature = ModelAPI_Feature::feature(anObject); + if (aFeature && aFeature->getKind() == SketchPlugin_Point::ID()) { + aPointAttr = std::dynamic_pointer_cast( + aFeature->data()->attribute(SketchPlugin_Point::COORD_ID())); + } + else { + ResultPtr aRes = std::dynamic_pointer_cast(anObject); + if (aRes.get()) { + GeomShapePtr aShape = aRes->shape(); + if (aShape.get()) { + TopoDS_Shape aTDSShape = aShape->impl(); + aPointAttr = findGeomPoint(anObject, aTDSShape, thePlane); + } + } + } + } + else if (anAttr->attr()) { + aPointAttr = std::dynamic_pointer_cast(anAttr->attr()); + } } return aPointAttr; } diff --git a/src/SketcherPrs/SketcherPrs_Tools.h b/src/SketcherPrs/SketcherPrs_Tools.h index ac014267e..481e7d96d 100644 --- a/src/SketcherPrs/SketcherPrs_Tools.h +++ b/src/SketcherPrs/SketcherPrs_Tools.h @@ -56,7 +56,8 @@ enum SelectionModes { /// Obtain the point object from specified constraint parameter SKETCHERPRS_EXPORT std::shared_ptr getFeaturePoint(DataPtr theData, - const std::string& theAttribute); + const std::string& theAttribute, + const std::shared_ptr& thePlane); SKETCHERPRS_EXPORT double getArrowSize(); -- 2.39.2