From 59d8f084644a30cab1ce8aa90cf4555d59a64c0a Mon Sep 17 00:00:00 2001 From: nds Date: Mon, 25 Jul 2016 20:45:00 +0300 Subject: [PATCH] Issue #1664: In the Sketcher, add the function Split a segment. Validator for selection, selection of segments on arc/circle. --- src/Model/Model_AttributeReference.cpp | 1 + src/ModelGeomAlgo/ModelGeomAlgo_Point2D.cpp | 52 ++++++++++++++----- src/ModelGeomAlgo/ModelGeomAlgo_Point2D.h | 15 ++++-- .../PartSet_WidgetSubShapeSelector.cpp | 10 ++-- src/PartSet/PartSet_WidgetSubShapeSelector.h | 16 +++++- .../SketchPlugin_ConstraintSplit.cpp | 4 +- src/SketchPlugin/SketchPlugin_Validators.cpp | 46 +++++++++------- 7 files changed, 99 insertions(+), 45 deletions(-) diff --git a/src/Model/Model_AttributeReference.cpp b/src/Model/Model_AttributeReference.cpp index d63b4e373..b1707c006 100644 --- a/src/Model/Model_AttributeReference.cpp +++ b/src/Model/Model_AttributeReference.cpp @@ -25,6 +25,7 @@ void Model_AttributeReference::setValue(ObjectPtr theObject) // return; ObjectPtr aValue = value(); if (!myIsInitialized || aValue != theObject) { + myIsInitialized = true; REMOVE_BACK_REF(aValue); TDF_Label anObjLab; diff --git a/src/ModelGeomAlgo/ModelGeomAlgo_Point2D.cpp b/src/ModelGeomAlgo/ModelGeomAlgo_Point2D.cpp index e7a360e78..5621684a4 100755 --- a/src/ModelGeomAlgo/ModelGeomAlgo_Point2D.cpp +++ b/src/ModelGeomAlgo/ModelGeomAlgo_Point2D.cpp @@ -19,6 +19,7 @@ #include #include #include +#include namespace ModelGeomAlgo_Point2D { std::shared_ptr getPointOfRefAttr(ModelAPI_Feature* theFeature, @@ -55,9 +56,12 @@ namespace ModelGeomAlgo_Point2D { const std::string& theReferenceFeatureKind, std::set >& theAttributes, const std::string& theObjectFeatureKind, - const std::string& theObjectFeatureAttribute) + const std::string& theObjectFeatureAttribute, + const bool isSkipFeatureAttributes) { // find by feature + FeaturePtr aSourceFeature = ModelAPI_Feature::feature(theObject); + const std::set& aRefsList = theObject->data()->refsToMe(); std::set::const_iterator aIt; for (aIt = aRefsList.cbegin(); aIt != aRefsList.cend(); ++aIt) { @@ -66,15 +70,32 @@ namespace ModelGeomAlgo_Point2D { if (aRefFeature->getKind() == theReferenceFeatureKind) { std::list anAttributes = aRefFeature->data()->attributes(ModelAPI_AttributeRefAttr::typeId()); - std::list::iterator anIter = anAttributes.begin(); + std::list::iterator anIter = anAttributes.begin(), aLast = anAttributes.end(); + bool isSkippedAttribute = false; + if (isSkipFeatureAttributes) { + for(anIter = anAttributes.begin(); anIter != aLast && !isSkippedAttribute; anIter++) { + AttributeRefAttrPtr aRefAttribute = + std::dynamic_pointer_cast(*anIter); + if (aRefAttribute.get() && !aRefAttribute->isObject()) { + std::shared_ptr aPointAttr = + std::dynamic_pointer_cast(aRefAttribute->attr()); + FeaturePtr anAttributeFeature = ModelAPI_Feature::feature(aPointAttr->owner()); + isSkippedAttribute = aSourceFeature == anAttributeFeature; + } + } + } + if (isSkippedAttribute) + continue; + // it searches the first point of AttributeRefAtt std::shared_ptr aPointAttr; - for(; anIter != anAttributes.end() && !aPointAttr.get(); anIter++) { + for(anIter = anAttributes.begin(); anIter != aLast && !aPointAttr.get(); anIter++) { AttributeRefAttrPtr aRefAttribute = std::dynamic_pointer_cast(*anIter); - if (aRefAttribute.get()) + if (aRefAttribute.get()) { aPointAttr = getPointOfRefAttr(aRefFeature.get(), aRefAttribute->id(), - theObjectFeatureKind, theObjectFeatureAttribute); + theObjectFeatureKind, theObjectFeatureAttribute); + } } if (aPointAttr.get()) { theAttributes.insert(aPointAttr); @@ -119,13 +140,20 @@ namespace ModelGeomAlgo_Point2D { { bool isInside = false; if (theBaseShape->shapeType() == GeomAPI_Shape::EDGE) { - std::shared_ptr aLineEdge(new GeomAPI_Edge(theBaseShape)); - std::shared_ptr aLine = aLineEdge->line(); - theProjectedPoint = aLine->project(thePoint); - - std::shared_ptr aVertexShape(new GeomAPI_Vertex(theProjectedPoint->x(), - theProjectedPoint->y(), theProjectedPoint->z())); - isInside = GeomAlgoAPI_ShapeTools::isSubShapeInsideShape(aVertexShape, theBaseShape); + std::shared_ptr anEdge(new GeomAPI_Edge(theBaseShape)); + if (anEdge->isLine()) { + std::shared_ptr aLine = anEdge->line(); + theProjectedPoint = aLine->project(thePoint); + } + else if (anEdge->isCircle() || anEdge->isArc()) { + std::shared_ptr aCircle = anEdge->circle(); + theProjectedPoint = aCircle->project(thePoint); + } + if (theProjectedPoint.get()) { + std::shared_ptr aVertexShape(new GeomAPI_Vertex(theProjectedPoint->x(), + theProjectedPoint->y(), theProjectedPoint->z())); + isInside = GeomAlgoAPI_ShapeTools::isSubShapeInsideShape(aVertexShape, theBaseShape); + } } return isInside; } diff --git a/src/ModelGeomAlgo/ModelGeomAlgo_Point2D.h b/src/ModelGeomAlgo/ModelGeomAlgo_Point2D.h index b70ef961e..be1521bdc 100755 --- a/src/ModelGeomAlgo/ModelGeomAlgo_Point2D.h +++ b/src/ModelGeomAlgo/ModelGeomAlgo_Point2D.h @@ -8,6 +8,7 @@ #define ModelGeomAlgo_Point2D_H #include "ModelGeomAlgo.h" +#include "ModelAPI_Feature.h" class ModelAPI_Feature; class ModelAPI_Object; @@ -29,12 +30,13 @@ namespace ModelGeomAlgo_Point2D { /// \param theAttribute a name of AttributeRefAttr on the given feature /// \param theObjectFeatureKind a feature kind in object of attribute that satisfies the search /// \param theObjectFeatureAttribute a feature attribute in object that satisfies the search + /// \param isSkipFeatureAttributes a boolean value if coincidences to the feature attributes /// \returns found point attribute or NULL MODELGEOMALGO_EXPORT std::shared_ptr getPointOfRefAttr( - ModelAPI_Feature* theFeature, - const std::string& theAttribute, - const std::string& theObjectFeatureKind = "", - const std::string& theObjectFeatureAttribute = ""); + ModelAPI_Feature* theFeature, + const std::string& theAttribute, + const std::string& theObjectFeatureKind = "", + const std::string& theObjectFeatureAttribute = ""); /// Fills container of point 2D attributes, which refer to the feature through the references /// features with the given kind @@ -43,12 +45,15 @@ namespace ModelGeomAlgo_Point2D { /// \param theAttributes a container of found point 2D attributes /// \param theObjectFeatureKind a feature kind in object of attribute that satisfies the search /// \param theObjectFeatureAttribute a feature attribute in object that satisfies the search + /// \param isSkipFeatureAttributes a boolean value if coincidences to the feature attributes + /// should be skipped /// \returns found point attribute or NULL MODELGEOMALGO_EXPORT void getPointsOfReference(const std::shared_ptr& theObject, const std::string& theReferenceFeatureKind, std::set >& theAttributes, const std::string& theObjectFeatureKind = "", - const std::string& theObjectFeatureAttribute = ""); + const std::string& theObjectFeatureAttribute = "", + const bool isSkipFeatureAttributes = true); /// Removes attributes which points are out of the base shape /// \param theBaseShape a shape of check diff --git a/src/PartSet/PartSet_WidgetSubShapeSelector.cpp b/src/PartSet/PartSet_WidgetSubShapeSelector.cpp index f73d61e98..bdb039aad 100755 --- a/src/PartSet/PartSet_WidgetSubShapeSelector.cpp +++ b/src/PartSet/PartSet_WidgetSubShapeSelector.cpp @@ -40,22 +40,20 @@ PartSet_WidgetSubShapeSelector::PartSet_WidgetSubShapeSelector(QWidget* theParent, ModuleBase_IWorkshop* theWorkshop, const Config_WidgetAPI* theData) -: PartSet_WidgetShapeSelector(theParent, theWorkshop, theData) +: ModuleBase_WidgetShapeSelector(theParent, theWorkshop, theData) { myCurrentSubShape = std::shared_ptr(new ModuleBase_ViewerPrs()); - - //myUseSketchPlane = theData->getBooleanAttribute("use_sketch_plane", true); - //myExternalObjectMgr = new PartSet_ExternalObjectsMgr(theData->getProperty("use_external"), true); } PartSet_WidgetSubShapeSelector::~PartSet_WidgetSubShapeSelector() { + myCashedShapes.clear(); } //******************************************************************** void PartSet_WidgetSubShapeSelector::activateCustom() { - PartSet_WidgetShapeSelector::activateCustom(); + ModuleBase_WidgetShapeSelector::activateCustom(); myWorkshop->module()->activateCustomPrs(myFeature, ModuleBase_IModule::CustomizeHighlightedObjects, true); @@ -64,7 +62,7 @@ void PartSet_WidgetSubShapeSelector::activateCustom() //******************************************************************** void PartSet_WidgetSubShapeSelector::deactivate() { - PartSet_WidgetShapeSelector::deactivate(); + ModuleBase_WidgetShapeSelector::deactivate(); myWorkshop->module()->deactivateCustomPrs(ModuleBase_IModule::CustomizeHighlightedObjects, true); } diff --git a/src/PartSet/PartSet_WidgetSubShapeSelector.h b/src/PartSet/PartSet_WidgetSubShapeSelector.h index 34e7b371a..feee61b01 100644 --- a/src/PartSet/PartSet_WidgetSubShapeSelector.h +++ b/src/PartSet/PartSet_WidgetSubShapeSelector.h @@ -10,9 +10,11 @@ #include "PartSet.h" -#include +#include #include +#include + #include #include @@ -32,7 +34,7 @@ class QMouseEvent; * by mouse move over shape in the viewer. Split of the object is performed by * coincident points to the object. Segment between nearest coincidence is highlighted */ -class PARTSET_EXPORT PartSet_WidgetSubShapeSelector: public PartSet_WidgetShapeSelector, +class PARTSET_EXPORT PartSet_WidgetSubShapeSelector: public ModuleBase_WidgetShapeSelector, public PartSet_MouseProcessor { Q_OBJECT @@ -46,6 +48,13 @@ Q_OBJECT virtual ~PartSet_WidgetSubShapeSelector(); + /// Set sketcher + /// \param theSketch a sketcher object + void setSketcher(CompositeFeaturePtr theSketch) { mySketch = theSketch; } + + /// Retrurns installed sketcher + CompositeFeaturePtr sketch() const { return mySketch; } + /// The methiod called when widget is deactivated virtual void deactivate(); @@ -80,6 +89,9 @@ protected: protected: std::shared_ptr myCurrentSubShape; std::map > myCashedShapes; + + /// Pointer to a sketch + CompositeFeaturePtr mySketch; }; #endif \ No newline at end of file diff --git a/src/SketchPlugin/SketchPlugin_ConstraintSplit.cpp b/src/SketchPlugin/SketchPlugin_ConstraintSplit.cpp index b029f638e..472cf8725 100755 --- a/src/SketchPlugin/SketchPlugin_ConstraintSplit.cpp +++ b/src/SketchPlugin/SketchPlugin_ConstraintSplit.cpp @@ -13,7 +13,7 @@ //#include //#include //#include -#include +#include //#include //#include //#include @@ -70,7 +70,7 @@ SketchPlugin_ConstraintSplit::SketchPlugin_ConstraintSplit() void SketchPlugin_ConstraintSplit::initAttributes() { - data()->addAttribute(SketchPlugin_Constraint::ENTITY_A(), ModelAPI_AttributeSelection::typeId()); + data()->addAttribute(SketchPlugin_Constraint::ENTITY_A(), ModelAPI_AttributeReference::typeId()); //data()->addAttribute(SketchPlugin_Constraint::VALUE(), ModelAPI_AttributeDouble::typeId()); //data()->addAttribute(SketchPlugin_Constraint::ENTITY_A(), ModelAPI_AttributeRefAttrList::typeId()); diff --git a/src/SketchPlugin/SketchPlugin_Validators.cpp b/src/SketchPlugin/SketchPlugin_Validators.cpp index b488d4fa0..bbb3bdc50 100755 --- a/src/SketchPlugin/SketchPlugin_Validators.cpp +++ b/src/SketchPlugin/SketchPlugin_Validators.cpp @@ -856,15 +856,15 @@ bool SketchPlugin_SplitValidator::isValid(const AttributePtr& theAttribute, { bool aValid = false; - if (theAttribute->attributeType() != ModelAPI_AttributeSelection::typeId()) { + if (theAttribute->attributeType() != ModelAPI_AttributeReference::typeId()) { theError = "The attribute with the %1 type is not processed"; theError.arg(theAttribute->attributeType()); return aValid; } - AttributeSelectionPtr aFeatureAttr = - std::dynamic_pointer_cast(theAttribute); + AttributeReferencePtr aFeatureAttr = + std::dynamic_pointer_cast(theAttribute); - ObjectPtr anAttrObject = aFeatureAttr->context(); + ObjectPtr anAttrObject = aFeatureAttr->value(); FeaturePtr anAttrFeature = ModelAPI_Feature::feature(anAttrObject); if (!anAttrFeature) return aValid; @@ -876,28 +876,38 @@ bool SketchPlugin_SplitValidator::isValid(const AttributePtr& theAttribute, std::set anEdgeShapes; ModelAPI_Tools::shapesOfType(anAttrFeature, GeomAPI_Shape::EDGE, anEdgeShapes); - if (anEdgeShapes.empty()) + if (anEdgeShapes.empty() || anEdgeShapes.size() > 1 /*there case has not existed yet*/) return aValid; - GeomShapePtr anAttrShape = *anEdgeShapes.begin(); - - //std::shared_ptr aPointAttr = ModelGeomAlgo_Point2D::getPointOfRefAttr( - // anAttrFeature, theAttribute, SketchPlugin_Point::ID(), SketchPlugin_Point::COORD_ID()); - + // coincidences to the feature std::set > aRefAttributes; - //ModelGeomAlgo_Point2D::getPointsOfReference(anAttrFeature.get(), SketchPlugin_ConstraintCoincidence::ID(), - // aRefAttributes, SketchPlugin_Point::ID(), SketchPlugin_Point::COORD_ID()); - - //ModelGeomAlgo_Point2D::filterPointsToBeInsideShape(anAttrShape, aRefAttributes, ); + ModelGeomAlgo_Point2D::getPointsOfReference(anAttrFeature, SketchPlugin_ConstraintCoincidence::ID(), + aRefAttributes, SketchPlugin_Point::ID(), SketchPlugin_Point::COORD_ID()); - int aCoincidentToFeature = aRefAttributes.size(); + GeomShapePtr anAttrShape = *anEdgeShapes.begin(); + std::shared_ptr aSFeature = + std::dynamic_pointer_cast(anAttrFeature); + SketchPlugin_Sketch* aSketch = aSFeature->sketch(); + std::shared_ptr aData = aSketch->data(); + std::shared_ptr aC = std::dynamic_pointer_cast( + aData->attribute(SketchPlugin_Sketch::ORIGIN_ID())); + std::shared_ptr aX = std::dynamic_pointer_cast( + aData->attribute(SketchPlugin_Sketch::DIRX_ID())); + std::shared_ptr aNorm = std::dynamic_pointer_cast( + aData->attribute(SketchPlugin_Sketch::NORM_ID())); + std::shared_ptr aY(new GeomAPI_Dir(aNorm->dir()->cross(aX->dir()))); + std::set > aPoints; + ModelGeomAlgo_Point2D::getPointsInsideShape(anAttrShape, aRefAttributes, aC->pnt(), + aX->dir(), aY, aPoints); + + int aCoincidentToFeature = aPoints.size(); if (aKind == SketchPlugin_Circle::ID()) - aValid = aCoincidentToFeature > 2; + aValid = aCoincidentToFeature >= 2; else - aValid = aCoincidentToFeature > 1; + aValid = aCoincidentToFeature >= 1; } - return true; + return aValid; } bool SketchPlugin_ProjectionValidator::isValid(const AttributePtr& theAttribute, -- 2.39.2