From 9dbc7bb239ec73b8af08652a2560e53bc211f2a4 Mon Sep 17 00:00:00 2001 From: nds Date: Wed, 28 May 2014 10:48:54 +0400 Subject: [PATCH] Bugs on OCC library. The selected extracted objects are not cleared in the local selection. --- src/PartSet/CMakeLists.txt | 2 + src/PartSet/PartSet_Listener.cpp | 3 +- src/PartSet/PartSet_Module.cpp | 10 +- src/PartSet/PartSet_OperationSketchBase.cpp | 2 +- src/PartSet/PartSet_OperationSketchBase.h | 2 +- src/PartSet/PartSet_OperationSketchLine.h | 16 +- src/PartSet/PartSet_TestOCC.cpp | 213 ++++++++++++++++++++ src/PartSet/PartSet_TestOCC.h | 55 +++++ src/XGUI/XGUI_Displayer.cpp | 38 ++-- src/XGUI/XGUI_Displayer.h | 7 +- 10 files changed, 320 insertions(+), 28 deletions(-) create mode 100644 src/PartSet/PartSet_TestOCC.cpp create mode 100644 src/PartSet/PartSet_TestOCC.h diff --git a/src/PartSet/CMakeLists.txt b/src/PartSet/CMakeLists.txt index 7e4e35034..9ccf4e46b 100644 --- a/src/PartSet/CMakeLists.txt +++ b/src/PartSet/CMakeLists.txt @@ -11,6 +11,7 @@ SET(PROJECT_HEADERS PartSet_OperationSketchBase.h PartSet_OperationSketch.h PartSet_OperationSketchLine.h + PartSet_TestOCC.h PartSet_Tools.h ) @@ -21,6 +22,7 @@ SET(PROJECT_SOURCES PartSet_OperationSketchBase.cpp PartSet_OperationSketch.cpp PartSet_OperationSketchLine.cpp + PartSet_TestOCC.cpp PartSet_Tools.cpp ) diff --git a/src/PartSet/PartSet_Listener.cpp b/src/PartSet/PartSet_Listener.cpp index 355142a31..63eefc0d0 100644 --- a/src/PartSet/PartSet_Listener.cpp +++ b/src/PartSet/PartSet_Listener.cpp @@ -47,7 +47,8 @@ void PartSet_Listener::processEvent(const Events_Message* theMessage) if (myModule->workshop()->displayer()->IsVisible(aFeature) || aType == EVENT_FEATURE_CREATED) { myModule->visualizePreview(aFeature, true, false); - myModule->activateFeature(aFeature, true); + if (aType == EVENT_FEATURE_CREATED) + myModule->activateFeature(aFeature, true); } } myModule->workshop()->displayer()->UpdateViewer(); diff --git a/src/PartSet/PartSet_Module.cpp b/src/PartSet/PartSet_Module.cpp index 94ef5f926..7cd146030 100644 --- a/src/PartSet/PartSet_Module.cpp +++ b/src/PartSet/PartSet_Module.cpp @@ -5,6 +5,7 @@ #include #include #include +#include #include @@ -39,7 +40,6 @@ #include #endif - /*!Create and return new instance of XGUI_Module*/ extern "C" PARTSET_EXPORT XGUI_Module* createModule(XGUI_Workshop* theWshop) { @@ -109,6 +109,12 @@ std::string PartSet_Module::featureFile(const std::string& theFeatureId) */ void PartSet_Module::onFeatureTriggered() { + //PartSet_TestOCC::testSelection_OCC(myWorkshop->viewer()->AISContext(), + // myWorkshop->viewer()->activeView()); + + //PartSet_TestOCC::testErase_OCC(myWorkshop->viewer()->AISContext(), + // myWorkshop->viewer()->activeView()); + QAction* aCmd = dynamic_cast(sender()); //Do nothing on uncheck if(aCmd->isCheckable() && !aCmd->isChecked()) @@ -202,6 +208,8 @@ void PartSet_Module::onPlaneSelected(double theX, double theY, double theZ) { myWorkshop->viewer()->setViewProjection(theX, theY, theZ); myWorkshop->actionsMgr()->update(); + + //PartSet_TestOCC::testSelection(myWorkshop); } void PartSet_Module::onLaunchOperation(std::string theName, boost::shared_ptr theFeature) diff --git a/src/PartSet/PartSet_OperationSketchBase.cpp b/src/PartSet/PartSet_OperationSketchBase.cpp index 0a581c178..46b9a0541 100644 --- a/src/PartSet/PartSet_OperationSketchBase.cpp +++ b/src/PartSet/PartSet_OperationSketchBase.cpp @@ -28,7 +28,7 @@ PartSet_OperationSketchBase::~PartSet_OperationSketchBase() } boost::shared_ptr PartSet_OperationSketchBase::preview( - boost::shared_ptr theFeature) const + boost::shared_ptr theFeature) { boost::shared_ptr aFeature = boost::dynamic_pointer_cast(theFeature); diff --git a/src/PartSet/PartSet_OperationSketchBase.h b/src/PartSet/PartSet_OperationSketchBase.h index f4d01b3a0..4da9b9503 100644 --- a/src/PartSet/PartSet_OperationSketchBase.h +++ b/src/PartSet/PartSet_OperationSketchBase.h @@ -43,7 +43,7 @@ public: /// Returns the feature preview shape /// \param theFeature the feature object to obtain the preview - boost::shared_ptr preview(boost::shared_ptr theFeature) const; + static boost::shared_ptr preview(boost::shared_ptr theFeature); /// Returns the map of the operation previews including the nested feature previews /// \return the map of feature to the feature preview diff --git a/src/PartSet/PartSet_OperationSketchLine.h b/src/PartSet/PartSet_OperationSketchLine.h index 6b78f0369..d0c08e286 100644 --- a/src/PartSet/PartSet_OperationSketchLine.h +++ b/src/PartSet/PartSet_OperationSketchLine.h @@ -75,6 +75,14 @@ public: virtual void keyReleased(std::string theName, QKeyEvent* theEvent); + /// \brief Save the point to the line. + /// \param theFeature the line feature + /// \param theX the horizontal coordinate + /// \param theY the vertical coordinate + /// \param theAttribute the start or end attribute of the line + static void setLinePoint(boost::shared_ptr, double theX, double theY, + const std::string& theAttribute); + protected: /// \brief Virtual method called when operation is started /// Virtual method called when operation started (see start() method for more description) @@ -106,6 +114,7 @@ protected: /// \param theX the horizontal coordnate of the point /// \param theY the vertical coordnate of the point void setConstraints(double theX, double theY); + protected: /// \brief Get the line point 2d coordinates. /// \param theFeature the line feature @@ -122,13 +131,6 @@ protected: double theX, double theY); /// \brief Save the point to the line. - /// \param theFeature the line feature - /// \param theX the horizontal coordinate - /// \param theY the vertical coordinate - /// \param theAttribute the start or end attribute of the line - void setLinePoint(boost::shared_ptr, double theX, double theY, - const std::string& theAttribute); - /// \brief Save the point to the line. /// \param thePoint the 3D point in the viewer /// \param theAttribute the start or end attribute of the line void setLinePoint(const gp_Pnt& thePoint, Handle(V3d_View) theView, const std::string& theAttribute); diff --git a/src/PartSet/PartSet_TestOCC.cpp b/src/PartSet/PartSet_TestOCC.cpp new file mode 100644 index 000000000..846973bca --- /dev/null +++ b/src/PartSet/PartSet_TestOCC.cpp @@ -0,0 +1,213 @@ +// File: PartSet_TestOCC.h +// Created: 28 Apr 2014 +// Author: Natalia ERMOLAEVA + +#include + +#include +#include +#include +#include +#include +#include + +#include + +#include +#include + +static double myTestDelta; +static boost::shared_ptr myTestFeature; + +#include +#include +#include +#include +#include +#include +#include +#include + +void PartSet_TestOCC::testSelection(XGUI_Workshop* theWorkshop) +{ + if (!myTestFeature) { + PartSet_TestOCC::createTestLine(theWorkshop); + PartSet_TestOCC::moveMouse(theWorkshop->viewer()->AISContext(), + theWorkshop->viewer()->activeView()); + PartSet_TestOCC::changeTestLine(theWorkshop); + } + Handle(AIS_InteractiveObject) anIO = theWorkshop->displayer()->GetAISObject(myTestFeature); + if (!anIO.IsNull()) { + theWorkshop->viewer()->AISContext()->MoveTo(0, 0, theWorkshop->viewer()->activeView()); + theWorkshop->viewer()->AISContext()->Select(0, 0, 2500, 2500, theWorkshop->viewer()->activeView()); + } +} + +void PartSet_TestOCC::testSelection_OCC(Handle_AIS_InteractiveContext theContext, + Handle_V3d_View theView) +{ + // 1. Create shape + gp_Pnt aPnt1(100, 100, 0); + gp_Pnt aPnt2(150, 300, 0); + TopoDS_Edge anEdge = BRepBuilderAPI_MakeEdge(aPnt1, aPnt2).Edge(); + + // 2. Display shape and activate it in the local context + Handle(AIS_Shape) anAIS = new AIS_Shape(anEdge); + if (!theContext->HasOpenedContext()) { + theContext->ClearCurrents(false); + theContext->OpenLocalContext(false/*use displayed objects*/, true/*allow shape decomposition*/); + } + theContext->Display(anAIS, false); + theContext->Load(anAIS, -1, true/*allow decomposition*/); + theContext->Activate(anAIS, AIS_Shape::SelectionMode(TopAbs_VERTEX)); + theContext->Activate(anAIS, AIS_Shape::SelectionMode(TopAbs_EDGE)); + + // 3. Change selection in the viewer + // emulate rectangle selection in the viewer + theContext->Select(0, 0, 2500, 2500, theView); + + // 3. Change the shape of AIS presentation + gp_Pnt aPnt3(-100, -100, 0); + gp_Pnt aPnt4(200, 200, 0); + TopoDS_Edge anEdge2 = BRepBuilderAPI_MakeEdge(aPnt3, aPnt4).Edge(); + anAIS->Set(anEdge2); + anAIS->Redisplay(Standard_True); + theContext->RecomputeSelectionOnly(anAIS); + + // 4. Check the current viewer selection + Handle(AIS_InteractiveContext) aContext = theContext; + bool isFirstLinePoint = false; + bool isShapeSelected = false; + for (aContext->InitSelected(); aContext->MoreSelected(); aContext->NextSelected()) { + TopoDS_Shape aShape = aContext->SelectedShape(); + if (aShape.ShapeType() == TopAbs_VERTEX) { + const TopoDS_Vertex& aVertex = TopoDS::Vertex(aShape); + if (!aVertex.IsNull()) { + gp_Pnt aPoint = BRep_Tool::Pnt(aVertex); + double aD_1 = aPoint.Distance(aPnt1); + double aD_2 = aPoint.Distance(aPnt2); + isFirstLinePoint = aD_1 < Precision::Confusion() || aD_2 < Precision::Confusion(); + } + } + } + if (isFirstLinePoint) + std::cout << "Error: The point of the first line should not be selected." << std::endl; +} + +void PartSet_TestOCC::testErase_OCC(Handle_AIS_InteractiveContext theContext, + Handle_V3d_View theView) +{ + // 1. Create shape + gp_Pnt aPnt1(100, 100, 0); + gp_Pnt aPnt2(150, 300, 0); + TopoDS_Edge anEdge = BRepBuilderAPI_MakeEdge(aPnt1, aPnt2).Edge(); + + // 2. Display shape and activate it in the local context + Handle(AIS_Shape) anAIS = new AIS_Shape(anEdge); + if (!theContext->HasOpenedContext()) { + theContext->ClearCurrents(false); + theContext->OpenLocalContext(false/*use displayed objects*/, true/*allow shape decomposition*/); + } + theContext->Display(anAIS, false); + theContext->Load(anAIS, -1, true/*allow decomposition*/); + theContext->Activate(anAIS, AIS_Shape::SelectionMode(TopAbs_VERTEX)); + theContext->Activate(anAIS, AIS_Shape::SelectionMode(TopAbs_EDGE)); + + // 3. Change selection in the viewer + // emulate rectangle selection in the viewer + theContext->Select(0, 0, 2500, 2500, theView); + + theContext->Erase(anAIS); +} + +void PartSet_TestOCC::createTestLine(XGUI_Workshop* theWorkshop) +{ + myTestDelta = 80; + + ModuleBase_Operation* anOperation = theWorkshop->operationMgr()->currentOperation(); + PartSet_OperationSketchBase* aPreviewOp = dynamic_cast(anOperation); + boost::shared_ptr aSketch; + + if (aPreviewOp) { + // create a line + boost::shared_ptr aDoc = ModelAPI_PluginManager::get()->rootDocument(); + boost::shared_ptr aFeature = aDoc->addFeature( + PartSet_OperationSketchLine::Type().c_str()); + if (aFeature) // TODO: generate an error if feature was not created + aFeature->execute(); + + boost::shared_ptr aSketch = + boost::dynamic_pointer_cast(aPreviewOp->sketch()); + aSketch->addSub(aFeature); + + PartSet_OperationSketchLine::setLinePoint(aFeature, 100, 100, LINE_ATTR_START); + PartSet_OperationSketchLine::setLinePoint(aFeature, 150, 300, LINE_ATTR_END); + + boost::shared_ptr aPreview = PartSet_OperationSketchLine::preview(aFeature); + + XGUI_Displayer* aDisplayer = theWorkshop->displayer(); + aDisplayer->Redisplay(aFeature, aPreview ? aPreview->impl() : TopoDS_Shape(), false); + std::list aModes; + aModes.push_back(TopAbs_VERTEX); + aModes.push_back(TopAbs_EDGE); + aDisplayer->ActivateInLocalContext(aFeature, aModes, true); + + // change the line + /*double aDelta = -200; + for (int i = 0; i < 20; i++) { + aDelta = aDelta - i*2; + PartSet_OperationSketchLine::setLinePoint(aFeature, 100+aDelta, 200+aDelta, LINE_ATTR_START); + PartSet_OperationSketchLine::setLinePoint(aFeature, 300+aDelta, 500+aDelta, LINE_ATTR_END); + boost::shared_ptr aPreview = PartSet_OperationSketchLine::preview(aFeature); + + theWorkshop->displayer()->Redisplay(aFeature, aPreview ? aPreview->impl() : TopoDS_Shape(), true); + + int aVal = 90; + for (int j = 0; j < 10000000; j++) + aVal = aVal/aVal+aVal*2; + }*/ + //std::list aModes; + //aModes.clear(); + //aModes.push_back(TopAbs_VERTEX); + //aModes.push_back(TopAbs_EDGE); + //aDisplayer->ActivateInLocalContext(aFeature, aModes, true); + myTestFeature = aFeature; + + std::list aPrs; + aPrs.push_back(XGUI_ViewerPrs(myTestFeature, TopoDS_Shape())); + aDisplayer->SetSelected(aPrs, true); + } +} + +void PartSet_TestOCC::changeTestLine(XGUI_Workshop* theWorkshop) +{ + // change the line + if (!myTestFeature) + return; + boost::shared_ptr aFeature = myTestFeature; + + myTestDelta = myTestDelta - 50; + double aDelta = myTestDelta; + PartSet_OperationSketchLine::setLinePoint(aFeature, -100/*aDelta*/, -100/*aDelta*/, LINE_ATTR_START); + PartSet_OperationSketchLine::setLinePoint(aFeature, 200/*aDelta*2*/, 200/*aDelta*2*/, LINE_ATTR_END); + boost::shared_ptr aPreview = PartSet_OperationSketchLine::preview(aFeature); + + theWorkshop->displayer()->Redisplay(aFeature, aPreview ? aPreview->impl() : TopoDS_Shape(), true); + //std::list aModes; + //aModes.clear(); + //aModes.push_back(TopAbs_VERTEX); + //aModes.push_back(TopAbs_EDGE); + //aDisplayer->ActivateInLocalContext(aFeature, aModes, true); + + /*std::list aPrs; + aPrs.push_back(XGUI_ViewerPrs(myTestFeature, TopoDS_Shape())); + theWorkshop->displayer()->SetSelected(aPrs, true);*/ + + theWorkshop->displayer()->UpdateViewer(); +} + +void PartSet_TestOCC::moveMouse(Handle(AIS_InteractiveContext) theContext, Handle(V3d_View) theView) +{ + theContext->MoveTo(10, 10, theView); + theContext->Select(); +} \ No newline at end of file diff --git a/src/PartSet/PartSet_TestOCC.h b/src/PartSet/PartSet_TestOCC.h new file mode 100644 index 000000000..5de140c30 --- /dev/null +++ b/src/PartSet/PartSet_TestOCC.h @@ -0,0 +1,55 @@ +// File: PartSet_TestOCC.h +// Created: 28 Apr 2014 +// Author: Natalia ERMOLAEVA + +#ifndef PartSet_TestOCC_H +#define PartSet_TestOCC_H + +#include "PartSet.h" + +class XGUI_Workshop; +class Handle_AIS_InteractiveContext; +class Handle_V3d_View; + +/*! + \class PartSet_TestOCC + * \brief The operation to test OCC viewer work +*/ +class PARTSET_EXPORT PartSet_TestOCC +{ +public: + PartSet_TestOCC() {}; + + /// Creates a line feature, select it, modify the line. Check whether the highlight is correct. + /// \param the workshop to provide an access to the application information + static void testSelection(XGUI_Workshop* theWorkshop); + + /// Creates row OCC presentation, activate in the local context, modify it and check selection + /// BUG: The result contains the selection from the first presentation + /// \param theContext a viewer interactive context + /// \param theContext a view + static void testSelection_OCC(Handle_AIS_InteractiveContext theContext, + Handle_V3d_View theView); + + /// Creates row OCC presentation, activate in the local context, select it, erase the presentation + /// BUG: The selected shape are in the viewer even after erase + /// \param theContext a viewer interactive context + /// \param theContext a view + static void testErase_OCC(Handle_AIS_InteractiveContext theContext, + Handle_V3d_View theView); + +private: + + /// Creates a temporary line + /// \param the workshop to get the operation manager and the displayer + static void createTestLine(XGUI_Workshop* theWorkshop); + + /// Changes a temporary line + /// \param the workshop to get the operation manager and the displayer + static void changeTestLine(XGUI_Workshop* theWorkshop); + + /// Emulates the mouse moving in the viewer + static void moveMouse(Handle_AIS_InteractiveContext theContext, Handle_V3d_View theView); +}; + +#endif diff --git a/src/XGUI/XGUI_Displayer.cpp b/src/XGUI/XGUI_Displayer.cpp index 7e5deb50e..d81b6e59f 100644 --- a/src/XGUI/XGUI_Displayer.cpp +++ b/src/XGUI/XGUI_Displayer.cpp @@ -51,7 +51,7 @@ void XGUI_Displayer::Display(boost::shared_ptr theFeature, aContext->Display(anAIS, Standard_False); if (isUpdateViewer) - aContext->UpdateCurrentViewer(); + UpdateViewer(); }*/ @@ -114,7 +114,7 @@ void XGUI_Displayer::Erase(boost::shared_ptr theFeature, myFeature2AISObjectMap.erase(theFeature); if (isUpdateViewer) - aContext->UpdateCurrentViewer(); + UpdateViewer(); } void XGUI_Displayer::Redisplay(boost::shared_ptr theFeature, @@ -140,13 +140,8 @@ void XGUI_Displayer::Redisplay(boost::shared_ptr theFeature, // after. Another workaround to thrown down the selection and reselecting the AIS. // If there was a problem here, try the first solution with close/open local context. anAIS->Set(theShape); - anAIS->Redisplay(); - - /*if (aContext->IsSelected(anAIS)) { - aContext->AddOrRemoveSelected(anAIS, false); - aContext->AddOrRemoveSelected(anAIS, false); - //aContext->SetSelected(anAIS, false); - }*/ + anAIS->Redisplay(Standard_True); + aContext->RecomputeSelectionOnly(anAIS); } } else { @@ -154,6 +149,8 @@ void XGUI_Displayer::Redisplay(boost::shared_ptr theFeature, myFeature2AISObjectMap[theFeature] = anAIS; aContext->Display(anAIS, false); } + if (isUpdateViewer) + UpdateViewer(); } void XGUI_Displayer::ActivateInLocalContext(boost::shared_ptr theFeature, @@ -183,7 +180,7 @@ void XGUI_Displayer::ActivateInLocalContext(boost::shared_ptr } if (isUpdateViewer) - aContext->UpdateCurrentViewer(); + UpdateViewer(); } void XGUI_Displayer::StopSelection(const std::list& theFeatures, const bool isStop, @@ -213,7 +210,7 @@ void XGUI_Displayer::StopSelection(const std::list& theFeatures, } } if (isUpdateViewer) - aContext->UpdateCurrentViewer(); + UpdateViewer(); } void XGUI_Displayer::SetSelected(const std::list& theFeatures, const bool isUpdateViewer) @@ -241,7 +238,7 @@ void XGUI_Displayer::SetSelected(const std::list& theFeatures, c } if (isUpdateViewer) - aContext->UpdateCurrentViewer(); + UpdateViewer(); } void XGUI_Displayer::EraseAll(const bool isUpdateViewer) @@ -261,7 +258,7 @@ void XGUI_Displayer::EraseAll(const bool isUpdateViewer) } myFeature2AISObjectMap.clear(); if (isUpdateViewer) - ic->UpdateCurrentViewer(); + UpdateViewer(); } void XGUI_Displayer::EraseDeletedFeatures(const bool isUpdateViewer) @@ -289,7 +286,7 @@ void XGUI_Displayer::EraseDeletedFeatures(const bool isUpdateViewer) } if (isUpdateViewer) - aContext->UpdateCurrentViewer(); + UpdateViewer(); } void XGUI_Displayer::CloseLocalContexts(const bool isUpdateViewer) @@ -297,7 +294,16 @@ void XGUI_Displayer::CloseLocalContexts(const bool isUpdateViewer) CloseAllContexts(true); } -boost::shared_ptr XGUI_Displayer::GetFeature(Handle(AIS_InteractiveObject) theIO) +Handle(AIS_InteractiveObject) XGUI_Displayer::GetAISObject( + boost::shared_ptr theFeature) const +{ + Handle(AIS_InteractiveObject) anIO; + if (myFeature2AISObjectMap.find(theFeature) != myFeature2AISObjectMap.end()) + anIO = (myFeature2AISObjectMap.find(theFeature))->second; + return anIO; +} + +boost::shared_ptr XGUI_Displayer::GetFeature(Handle(AIS_InteractiveObject) theIO) const { boost::shared_ptr aFeature; FeatureToAISMap::const_iterator aFIt = myFeature2AISObjectMap.begin(), @@ -317,7 +323,7 @@ void XGUI_Displayer::CloseAllContexts(const bool isUpdateViewer) if (!ic.IsNull()) { ic->CloseAllContexts(false); if (isUpdateViewer) - ic->UpdateCurrentViewer(); + UpdateViewer(); } } diff --git a/src/XGUI/XGUI_Displayer.h b/src/XGUI/XGUI_Displayer.h index 4dc28389f..6606ebf06 100644 --- a/src/XGUI/XGUI_Displayer.h +++ b/src/XGUI/XGUI_Displayer.h @@ -116,11 +116,16 @@ public: /// Updates the viewer void UpdateViewer(); + /// Searches the interactive object by feature + /// \param feature the feature or NULL if it not visualized + /// \return theIO an interactive object + Handle(AIS_InteractiveObject) GetAISObject(boost::shared_ptr) const; + protected: /// Searches the feature by interactive object /// \param theIO an interactive object /// \return feature the feature or NULL if it not visualized - boost::shared_ptr GetFeature(Handle(AIS_InteractiveObject) theIO); + boost::shared_ptr GetFeature(Handle(AIS_InteractiveObject) theIO) const; /// Deactivate local selection /// \param isUpdateViewer the state wether the viewer should be updated immediatelly void CloseAllContexts(const bool isUpdateViewer); -- 2.39.2