From bb77698cb96e6ea848443bab051b4e9ea885fee0 Mon Sep 17 00:00:00 2001 From: nds Date: Fri, 8 Apr 2016 14:10:37 +0300 Subject: [PATCH] Issue #1393 Angle constraint : incorrect angle displayed. solution: arc's passed point correction --- src/GeomAlgoAPI/GeomAlgoAPI_EdgeBuilder.cpp | 5 +- src/ModuleBase/ModuleBase_WidgetValidated.cpp | 2 +- src/ModuleBase/ModuleBase_WidgetValidator.cpp | 72 ++++++++++++-- src/ModuleBase/ModuleBase_WidgetValidator.h | 17 ++++ src/PartSet/PartSet_WidgetPoint2d.cpp | 95 ++++++++++++++++--- src/PartSet/PartSet_WidgetPoint2d.h | 8 ++ src/SketchPlugin/SketchPlugin_Arc.cpp | 29 +++--- 7 files changed, 183 insertions(+), 45 deletions(-) diff --git a/src/GeomAlgoAPI/GeomAlgoAPI_EdgeBuilder.cpp b/src/GeomAlgoAPI/GeomAlgoAPI_EdgeBuilder.cpp index 9089c195a..97e62158a 100644 --- a/src/GeomAlgoAPI/GeomAlgoAPI_EdgeBuilder.cpp +++ b/src/GeomAlgoAPI/GeomAlgoAPI_EdgeBuilder.cpp @@ -147,10 +147,7 @@ std::shared_ptr GeomAlgoAPI_EdgeBuilder::lineCircleArc( const gp_Pnt& anEnd = theEndPoint->impl(); BRepBuilderAPI_MakeEdge anEdgeBuilder; - if (aStart.IsEqual(anEnd, Precision::Confusion())) - anEdgeBuilder = BRepBuilderAPI_MakeEdge(aCircle); - else - anEdgeBuilder = BRepBuilderAPI_MakeEdge(aCircle, aStart, anEnd); + anEdgeBuilder = BRepBuilderAPI_MakeEdge(aCircle, aStart, anEnd); anEdgeBuilder.Build(); diff --git a/src/ModuleBase/ModuleBase_WidgetValidated.cpp b/src/ModuleBase/ModuleBase_WidgetValidated.cpp index c2ad49c1c..7e85bce2e 100644 --- a/src/ModuleBase/ModuleBase_WidgetValidated.cpp +++ b/src/ModuleBase/ModuleBase_WidgetValidated.cpp @@ -48,7 +48,7 @@ ObjectPtr ModuleBase_WidgetValidated::findPresentedObject(const AISObjectPtr& th void ModuleBase_WidgetValidated::clearValidatedCash() { #ifdef DEBUG_VALID_STATE - qDebug("clearValidatedState"); + qDebug("clearValidatedCash"); #endif myValidPrs.clear(); myInvalidPrs.clear(); diff --git a/src/ModuleBase/ModuleBase_WidgetValidator.cpp b/src/ModuleBase/ModuleBase_WidgetValidator.cpp index 330b4c468..191a277ee 100755 --- a/src/ModuleBase/ModuleBase_WidgetValidator.cpp +++ b/src/ModuleBase/ModuleBase_WidgetValidator.cpp @@ -20,17 +20,14 @@ ModuleBase_WidgetValidator::~ModuleBase_WidgetValidator() //******************************************************************** bool ModuleBase_WidgetValidator::isValidSelection(const ModuleBase_ViewerPrsPtr& theValue) { - return myModelWidget->isValidSelectionCustom(theValue); -} + bool aValid = false; + if (getValidState(theValue, aValid)) + return aValid; -bool ModuleBase_WidgetValidator::isFilterActivated() const -{ - bool isActivated = false; + aValid = myModelWidget->isValidSelectionCustom(theValue); - Handle(SelectMgr_Filter) aSelFilter = myWorkshop->validatorFilter(); - ModuleBase_IViewer* aViewer = myWorkshop->viewer(); - - return aViewer->hasSelectionFilter(aSelFilter); + storeValidState(theValue, aValid); + return aValid; } bool ModuleBase_WidgetValidator::activateFilters(const bool toActivate) @@ -44,8 +41,63 @@ bool ModuleBase_WidgetValidator::activateFilters(const bool toActivate) aViewer->addSelectionFilter(aSelFilter); else { aViewer->removeSelectionFilter(aSelFilter); - //clearValidatedCash(); + clearValidatedCash(); } return aHasSelectionFilter; } + +bool ModuleBase_WidgetValidator::isFilterActivated() const +{ + bool isActivated = false; + + Handle(SelectMgr_Filter) aSelFilter = myWorkshop->validatorFilter(); + ModuleBase_IViewer* aViewer = myWorkshop->viewer(); + + return aViewer->hasSelectionFilter(aSelFilter); +} + +void ModuleBase_WidgetValidator::clearValidatedCash() +{ + myValidPrs.clear(); + myInvalidPrs.clear(); +} + +bool ModuleBase_WidgetValidator::getValidState(const ModuleBase_ViewerPrsPtr& theValue, bool& theValid) +{ + bool aValidPrs = myValidPrs.contains(theValue); + bool anInvalidPrs = myInvalidPrs.contains(theValue); + + if (aValidPrs) + theValid = true; + else if (anInvalidPrs) + theValid = false; + + return aValidPrs || anInvalidPrs; +} + +//******************************************************************** +void ModuleBase_WidgetValidator::storeValidState(const ModuleBase_ViewerPrsPtr& theValue, const bool theValid) +{ + bool aValidPrs = myInvalidPrs.contains(theValue); + bool anInvalidPrs = myInvalidPrs.contains(theValue); + + if (theValid) { + if (!aValidPrs) + myValidPrs.append(theValue); + // the commented code will be useful when the valid state of the presentation + // will be changable between activate/deactivate. Currently it does not happen. + //if (anInvalidPrs) + // myInvalidPrs.removeOne(theValue); + } + else { // !theValid + if (!anInvalidPrs) + myInvalidPrs.append(theValue); + //if (!aValidPrs) + // myValidPrs.removeOne(theValue); + } +#ifdef DEBUG_VALID_STATE + qDebug(QString("storeValidState: myValidPrs.size() = %1, myInvalidPrs.size() = %2").arg(myValidPrs.count()) + .arg(myInvalidPrs.count()).toStdString().c_str()); +#endif +} diff --git a/src/ModuleBase/ModuleBase_WidgetValidator.h b/src/ModuleBase/ModuleBase_WidgetValidator.h index 942e9bc93..ead80e794 100755 --- a/src/ModuleBase/ModuleBase_WidgetValidator.h +++ b/src/ModuleBase/ModuleBase_WidgetValidator.h @@ -10,6 +10,7 @@ #include +#include #include class ModuleBase_ModelWidget; @@ -48,10 +49,26 @@ private: /// \return boolean value bool isFilterActivated() const; + //! Clear all validated cash in the widget + void clearValidatedCash(); + + /// Gets the validity state of the presentation in an internal map. Returns true if the valid state of value is stored + /// \param theValue a viewer presentation + /// \param theValid a valid state + bool getValidState(const std::shared_ptr& theValue, bool& theValid); + + /// Store the validity state of the presentation in an internal map + /// \param theValue a viewer presentation + /// \param theValid a valid state + void storeValidState(const std::shared_ptr& theValue, const bool theValid); + protected: /// Reference to workshop ModuleBase_ModelWidget* myModelWidget; ///< the current widget to be validated ModuleBase_IWorkshop* myWorkshop; ///< the active workshop + + QList> myValidPrs; /// cash of valid selection presentations + QList> myInvalidPrs; /// cash of invalid selection presentations }; #endif /* ModuleBase_WidgetValidator_H_ */ diff --git a/src/PartSet/PartSet_WidgetPoint2d.cpp b/src/PartSet/PartSet_WidgetPoint2d.cpp index a2c024503..f259ca6af 100644 --- a/src/PartSet/PartSet_WidgetPoint2d.cpp +++ b/src/PartSet/PartSet_WidgetPoint2d.cpp @@ -7,6 +7,7 @@ #include "PartSet_WidgetPoint2d.h" #include #include +#include #include #include @@ -33,6 +34,9 @@ #include #include +#include +#include + #include #include #include @@ -124,15 +128,51 @@ PartSet_WidgetPoint2D::PartSet_WidgetPoint2D(QWidget* theParent, bool PartSet_WidgetPoint2D::isValidSelectionCustom(const ModuleBase_ViewerPrsPtr& theValue) { bool aValid = true; - /*if (getValidState(theValue, aValid)) { - return aValid; - } - aValid = isValidSelectionCustom(theValue); - if (aValid) - aValid = isValidSelectionForAttribute(theValue, attribute()); - storeValidState(theValue, aValid); - */return aValid; + PartSet_Module* aModule = dynamic_cast(myWorkshop->module()); + if (aModule->sketchReentranceMgr()->isInternalEditActive()) + return true; /// when internal edit is started a new feature is created. I has not results, AIS + + // workaround for feature, where there is no results + //if (myFeature->getKind() == "SketchRectangle") + // return true; + + /// the selection is not possible if the current feature has no presentation for the current + /// attribute not in AIS not in results. If so, no object in current feature where make + /// coincidence, so selection is not necessary + std::shared_ptr aData = myFeature->data(); + std::shared_ptr aPointAttr = std::dynamic_pointer_cast( + aData->attribute(attributeID())); + std::shared_ptr aPoint = aPointAttr->pnt(); + + bool aFoundPoint = false; + GeomShapePtr anAISShape; + GeomPresentablePtr aPrs = std::dynamic_pointer_cast(myFeature); + if (aPrs.get()) { + AISObjectPtr anAIS; + anAIS = aPrs->getAISObject(anAIS); + if (anAIS.get()) { + anAISShape = anAIS->getShape(); + } + } + const std::list >& aResults = myFeature->results(); + if (!anAISShape.get() && aResults.empty()) + return true; + + /// analysis of AIS + if (anAISShape.get()) + aFoundPoint = shapeContainsPoint(anAISShape, aPoint, mySketch); + + /// analysis of results + std::list >::const_iterator aRIter = aResults.cbegin(); + for (; aRIter != aResults.cend() && !aFoundPoint; aRIter++) { + ResultPtr aResult = *aRIter; + if (aResult.get() && aResult->shape().get()) { + GeomShapePtr aShape = aResult->shape(); + aFoundPoint = shapeContainsPoint(aShape, aPoint, mySketch); + } + } + return aFoundPoint; } bool PartSet_WidgetPoint2D::resetCustom() @@ -450,14 +490,22 @@ void PartSet_WidgetPoint2D::onMouseRelease(ModuleBase_IViewWindow* theWnd, QMous ModuleBase_ISelection* aSelection = myWorkshop->selection(); Handle(V3d_View) aView = theWnd->v3dView(); - // TODO: This fragment doesn't work because bug in OCC Viewer. It can be used after fixing. - NCollection_List aShapes; - std::list aObjects; - aSelection->selectedShapes(aShapes, aObjects); + + QList aList = aSelection->getSelected(ModuleBase_ISelection::Viewer); + ModuleBase_ViewerPrsPtr aFirstValue = aList.size() > 0 ? aList.first() : ModuleBase_ViewerPrsPtr(); + //NCollection_List aShapes; + //std::list aObjects; + //aSelection->selectedShapes(aShapes, aObjects); // if we have selection and use it - if (aShapes.Extent() > 0 && useSelectedShapes()) { - TopoDS_Shape aShape = aShapes.First(); - ObjectPtr aObject = aObjects.front(); + //if (/*aShapes.Extent() > 0 && useSelectedShapes() &&*/ isValidSelectionCustom() { + if (aFirstValue.get() && isValidSelectionCustom(aFirstValue)) { + //TopoDS_Shape aShape = aShapes.First(); + //ObjectPtr aObject = aObjects.front(); + + GeomShapePtr aGeomShape = aFirstValue->shape(); + TopoDS_Shape aShape = aGeomShape->impl(); /// to find axis shape + ObjectPtr aObject = aFirstValue->object(); /// to find owner + FeaturePtr aSelectedFeature = ModelAPI_Feature::feature(aObject); bool anExternal = false; std::shared_ptr aSPFeature; @@ -714,3 +762,20 @@ bool PartSet_WidgetPoint2D::isOrphanPoint(const FeaturePtr& theFeature, } return anOrphanPoint; } + +bool PartSet_WidgetPoint2D::shapeContainsPoint(const GeomShapePtr& theShape, + const std::shared_ptr& thePoint, + const CompositeFeaturePtr& theSketch) +{ + std::shared_ptr aPoint = PartSet_Tools::point3D(thePoint, theSketch); + + bool aContainPoint = false; + GeomAPI_ShapeExplorer anExp(theShape, GeomAPI_Shape::VERTEX); + for(; anExp.more() && !aContainPoint; anExp.next()) { + std::shared_ptr aVertexInCompSolid = anExp.current(); + std::shared_ptr aVertex(new GeomAPI_Vertex(aVertexInCompSolid)); + if (aVertex.get()) + aContainPoint = aPoint->isEqual(aVertex->point()); + } + return aContainPoint; +} diff --git a/src/PartSet/PartSet_WidgetPoint2d.h b/src/PartSet/PartSet_WidgetPoint2d.h index 449b890f3..b04dfc776 100755 --- a/src/PartSet/PartSet_WidgetPoint2d.h +++ b/src/PartSet/PartSet_WidgetPoint2d.h @@ -182,6 +182,14 @@ protected: static bool isOrphanPoint(const FeaturePtr& theFeature, const CompositeFeaturePtr& theSketch, double theX, double theY); + /// Explode the given shape by vertices and found closed to the point vertes + /// \param theShape a shape to be exploded + /// \param thePoint a point + /// \return boolean value + static bool shapeContainsPoint(const std::shared_ptr& theShape, + const std::shared_ptr& thePoint, + const CompositeFeaturePtr& theSketch); + protected: ModuleBase_IWorkshop* myWorkshop; ///< workshop diff --git a/src/SketchPlugin/SketchPlugin_Arc.cpp b/src/SketchPlugin/SketchPlugin_Arc.cpp index f6d4ec763..365fcb7af 100644 --- a/src/SketchPlugin/SketchPlugin_Arc.cpp +++ b/src/SketchPlugin/SketchPlugin_Arc.cpp @@ -219,8 +219,13 @@ AISObjectPtr SketchPlugin_Arc::getAISObject(AISObjectPtr thePrevious) // compute a circle point in 3D view std::shared_ptr aCenterAttr = std::dynamic_pointer_cast< GeomDataAPI_Point2D>(data()->attribute(CENTER_ID())); + + std::list > aShapes; if (aCenterAttr->isInitialized()) { std::shared_ptr aCenter(aSketch->to3D(aCenterAttr->x(), aCenterAttr->y())); + // make a visible point + std::shared_ptr aCenterPointShape = GeomAlgoAPI_PointBuilder::point(aCenter); + aShapes.push_back(aCenterPointShape); std::shared_ptr aStartAttr = std::dynamic_pointer_cast< GeomDataAPI_Point2D>(data()->attribute(SketchPlugin_Arc::START_ID())); @@ -242,28 +247,22 @@ AISObjectPtr SketchPlugin_Arc::getAISObject(AISObjectPtr thePrevious) aTypeAttr->value() == ARC_TYPE_THREE_POINTS() && aEndAttr->isInitialized()) aEndPoint = aSketch->to3D(aEndAttr->x(), aEndAttr->y()); - std::list > aShapes; - // make a visible point - std::shared_ptr aCenterPointShape = GeomAlgoAPI_PointBuilder::point(aCenter); - aShapes.push_back(aCenterPointShape); - std::shared_ptr aCircleShape = GeomAlgoAPI_EdgeBuilder::lineCircleArc( aCenter, aStartPoint, aEndPoint, aNormal); if (aCircleShape) aShapes.push_back(aCircleShape); - - if (!aShapes.empty()) { - std::shared_ptr aCompound = GeomAlgoAPI_CompoundBuilder::compound(aShapes); - AISObjectPtr anAIS = thePrevious; - if (!anAIS) - anAIS = AISObjectPtr(new GeomAPI_AISObject); - anAIS->createShape(aCompound); - anAIS->setWidth(3); - return anAIS; - } } } } + if (!aShapes.empty()) { + std::shared_ptr aCompound = GeomAlgoAPI_CompoundBuilder::compound(aShapes); + AISObjectPtr anAIS = thePrevious; + if (!anAIS) + anAIS = AISObjectPtr(new GeomAPI_AISObject); + anAIS->createShape(aCompound); + anAIS->setWidth(3); + return anAIS; + } } } return AISObjectPtr(); -- 2.39.2