From 03d22d0d9b892bba8efadf8fd02cc5bd2c6da40f Mon Sep 17 00:00:00 2001 From: Arnaud Billon <arnaud.billon@kitware.com> Date: Mon, 20 Dec 2021 17:26:21 +0100 Subject: [PATCH 1/7] [refactor] Replace old settings reset mechanism --- Application/vvMainWindow.cxx | 7 ------- 1 file changed, 7 deletions(-) diff --git a/Application/vvMainWindow.cxx b/Application/vvMainWindow.cxx index ddaccd266..130395daf 100644 --- a/Application/vvMainWindow.cxx +++ b/Application/vvMainWindow.cxx @@ -148,10 +148,6 @@ vvMainWindow::vvMainWindow() } // ParaView Init END - // Persistent Settings Restore // WIP TO rework is this verbatim PV ? - // Better instantiated before any widget instantiation / outputWidget connection - lqLidarViewManager::instance()->persistentSettingsRestore(); - // Setup ParaView Base GUI this->setupPVGUI(); @@ -170,9 +166,6 @@ vvMainWindow::vvMainWindow() // Schedule Python Init late otherwise startup is slow, WIP to investigate (related to window creation timing) lqLidarViewManager::instance()->schedulePythonStartup(); - // Save Original State if first time or invalid and discarded - lqLidarViewManager::instance()->persistentSettingsSaveOriginal(); - // Force Show App this->show(); this->raise(); -- GitLab From af737b9b73ccdc19efb7fe612ba69c2135642c57 Mon Sep 17 00:00:00 2001 From: Arnaud Billon <arnaud.billon@kitware.com> Date: Mon, 20 Dec 2021 17:30:02 +0100 Subject: [PATCH 2/7] [refactor] Add ViewDecoration toggle button --- Application/vvMainWindow.cxx | 14 ++++++++++++++ Application/vvMainWindow.h | 2 ++ Application/vvMainWindow.ui | 16 ++++++++++++++++ 3 files changed, 32 insertions(+) diff --git a/Application/vvMainWindow.cxx b/Application/vvMainWindow.cxx index 130395daf..4d8544cdf 100644 --- a/Application/vvMainWindow.cxx +++ b/Application/vvMainWindow.cxx @@ -401,6 +401,12 @@ void vvMainWindow::setupGUICustom() connect(this->Internals->actionMeasurement_Grid, SIGNAL(toggled(bool)), lqLidarViewManager::instance(), SLOT(onMeasurementGrid(bool))); + // Ruler Menu + connect( + this->Internals->actionMeasure, SIGNAL(triggered()), + this, SLOT(toggleMVDecoration()) + ); + new lqOpenSensorReaction(this->Internals->actionOpen_Sensor_Stream); new lqOpenPcapReaction(this->Internals->actionOpenPcap); @@ -569,3 +575,11 @@ void vvMainWindow::handleMessage(const QString &, int type) dock->raise(); } } + +//----------------------------------------------------------------------------- +void vvMainWindow::toggleMVDecoration() +{ + //pqTabbedMultiViewWidget::setDecorationsVisibility() + pqTabbedMultiViewWidget* mv = qobject_cast<pqTabbedMultiViewWidget*>(this->centralWidget()) ; + mv->setDecorationsVisibility(!mv->decorationsVisibility()); +} diff --git a/Application/vvMainWindow.h b/Application/vvMainWindow.h index 05431ea40..169ebea94 100644 --- a/Application/vvMainWindow.h +++ b/Application/vvMainWindow.h @@ -39,6 +39,8 @@ protected Q_SLOTS: //void showWelcomeDialog(); //void updateFontSize(); + void toggleMVDecoration(); // Toggle Multiview decorations + private: Q_DISABLE_COPY(vvMainWindow); diff --git a/Application/vvMainWindow.ui b/Application/vvMainWindow.ui index feb76a8d9..e7d52d49b 100644 --- a/Application/vvMainWindow.ui +++ b/Application/vvMainWindow.ui @@ -195,6 +195,7 @@ <bool>true</bool> </attribute> <addaction name="actionToggleProjection"/> + <addaction name="actionMeasure"/> <addaction name="actionPlaneFit"/> <addaction name="separator"/> </widget> @@ -639,6 +640,21 @@ <string>Toggle between projective and orthogonal view</string> </property> </action> + <action name="actionMeasure"> + <property name="checkable"> + <bool>false</bool> + </property> + <property name="icon"> + <iconset resource="vvResources.qrc"> + <normaloff>:/vvResources/Icons/Measurements.png</normaloff>:/vvResources/Icons/Measurements.png</iconset> + </property> + <property name="text"> + <string>Advanced Selection and Measurement options</string> + </property> + <property name="toolTip"> + <string>Advanced Selection and Measurement options</string> + </property> + </action> <action name="actionPlaneFit"> <property name="icon"> <iconset resource="vvResources.qrc"> -- GitLab From bfab6f2f6953349d5c50853270f93bcc485c3377 Mon Sep 17 00:00:00 2001 From: Arnaud Billon <arnaud.billon@kitware.com> Date: Mon, 20 Dec 2021 17:57:42 +0100 Subject: [PATCH 3/7] [refactor] Simplify Planefit --- Application/Ui/python/lidarview/planefit.py | 206 ++++++++++---------- 1 file changed, 103 insertions(+), 103 deletions(-) diff --git a/Application/Ui/python/lidarview/planefit.py b/Application/Ui/python/lidarview/planefit.py index 6fdd2ab17..477907099 100644 --- a/Application/Ui/python/lidarview/planefit.py +++ b/Application/Ui/python/lidarview/planefit.py @@ -4,119 +4,119 @@ # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # -# http://www.apache.org/licenses/LICENSE-2.0 +# http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. -from __future__ import print_function -#import VelodynePlugin.VelodyneLidar as vpmod #do we need this ? -import paraview.simple as smp -from paraview import vtk - -# Clean last planefitting source and the spreadsheet view -def cleanStats(): - planeFitter1 = smp.FindSource('PlaneFitter1') - if planeFitter1 is not None: - smp.Delete(planeFitter1) - del planeFitter1 - PVTrivialProducer1 = smp.FindSource('PVTrivialProducer1') - if PVTrivialProducer1 is not None: - smp.Delete(PVTrivialProducer1) - del PVTrivialProducer1 +# Imports +import paraview.simple as smp +from paraview import vtk, servermanager + +# Use Named filters +planefitter_name = 'PlaneFitter' # PlaneFitter Instance +selection_copy_name = 'SelectedPointsCopy' # Trivial copy of the selected points + +# Clean planefitter's state +def cleanState(): + # Remove PlaneFitter + planefitter = smp.FindSource(planefitter_name) + if planefitter is not None: + smp.Delete(planefitter) + del planefitter + + # Remove Selection copy TrivialProducer + trivialproducer = smp.FindSource(selection_copy_name) + if trivialproducer is not None: + smp.Delete(trivialproducer) + del trivialproducer # Find or create a 'SpreadSheet View' to display plane fitting statistics -def showStats(actionSpreadsheet=None): - if actionSpreadsheet is None: - print("Unable to display stats : SpreadSheet action is not defined") - return - - planeFitter1 = smp.FindSource('PlaneFitter1') - if planeFitter1 is None: - print("Unable to create spreadsheet view : PlaneFitter1 source missing") - return - - renderView1 = smp.FindView('RenderView1') - if renderView1 is None: - print("Unable to find main renderView") - return - - # Check if main spreadsheet view exist or can be created +def showStats(planefitter, actionSpreadsheet=None): + + # Check for SpreadSheetReaction + if actionSpreadsheet is None: + print("Unable to display stats : SpreadSheet action is not defined") + return + + # Check if main spreadsheet view exist or can be created + spreadSheetView1 = smp.FindView('main spreadsheet view') + if spreadSheetView1 is None: + # try to trigger actionSpreadsheet to display main spreadsheet view + actionSpreadsheet.trigger() spreadSheetView1 = smp.FindView('main spreadsheet view') if spreadSheetView1 is None: - # try to trigger actionSpreadsheet to display main spreadsheet view - actionSpreadsheet.trigger() - spreadSheetView1 = smp.FindView('main spreadsheet view') - if spreadSheetView1 is None: - print("Unable to get main spreadsheet view") - return - - # display stats in main spreadsheet view - spreadSheetView1.ColumnToSort = '' - spreadSheetView1.BlockSize = 1024 - spreadSheetView1.FieldAssociation = 'Row Data' - smp.Show(planeFitter1, spreadSheetView1) + print("Unable to get main spreadsheet view") + return + # Display stats in main spreadsheet view + spreadSheetView1.ColumnToSort = '' + spreadSheetView1.BlockSize = 1024 + spreadSheetView1.FieldAssociation = 'Row Data' + smp.Show(planefitter, spreadSheetView1) + +# Main Method def fitPlane(actionSpreadsheet=None): - src = smp.GetActiveSource() - if src is None: - print("A source need to be selected before running plane fitting") - return - - selection = src.GetSelectionInput(src.Port) - - if selection is None: - print("A selection has to be defined to run plane fitting") - return - - extracter = smp.ExtractSelection() - extracter.Selection = selection - extracter.Input = src - smp.Show(extracter) - - # Clean last plane fitting stats before processing a new one - cleanStats() - - try: - pd = extracter.GetClientSideObject().GetOutput() - if not pd.GetNumberOfPoints(): - print("An empty selection is defined") - return - - # Append data from each block - if pd.IsTypeOf("vtkMultiBlockDataSet"): - if not pd.GetNumberOfBlocks(): - print("An empty selection is defined") - return - - appendFilter = vtk.vtkAppendFilter() - for i in range(pd.GetNumberOfBlocks()): - appendFilter.AddInputData(pd.GetBlock(i)) - appendFilter.Update() - pd = appendFilter.GetOutput() - - # Create a data source from selected points - PVTrivialProducer1 = smp.PVTrivialProducer() - PVTrivialProducer1Client = PVTrivialProducer1.GetClientSideObject() - PVTrivialProducer1Client.SetOutput(pd) - - # Create and apply plane fitter filter - planeFitter1 = smp.PlaneFitter(Input=PVTrivialProducer1) - - # if laser_id is the name of the array in Legacy and Special Velarray mode - # LCN is the name of the array in APF mode - if pd.GetPointData().GetArray("laser_id") : - planeFitter1.laserIDArray = "laser_id" - elif pd.GetPointData().GetArray("LCN"): - planeFitter1.laserIDArray = "LCN" - planeFitter1.UpdatePipeline() - - # Display results on the main spreadsheet view - showStats(actionSpreadsheet) - - finally: - smp.Delete(extracter) - smp.SetActiveSource(src) + # Get Selected Source + src = smp.GetActiveSource() + if src is None: + print("A source need to be selected before running plane fitting") + return + + # Clean plane fitting state before processing a new one + cleanState() + + # Check Selection + selection = src.GetSelectionInput(src.Port) + if selection is None: + print("A selection has to be defined to run plane fitting") + return + + # Extract Selection - vtkMultiBlockDataSet(vtkUnstructuredGrid) + extractor = smp.ExtractSelection() + extractor.Selection = selection + extractor.Input = src + + # Extract first Block - vtkUnstructuredGrid + merger = smp.MergeBlocks(Input=extractor) + + # Convert to polydata - vtkPolyData + extractsurf = smp.ExtractSurface(Input=merger) + extractsurf.UpdatePipeline() + + # Create a Trivial Producer HardCopy of selected points + trivialproducer = smp.PVTrivialProducer() + smp.RenameSource(selection_copy_name, trivialproducer) + trivialproducer.GetClientSideObject().SetOutput(extractsurf.GetClientSideObject().GetOutput()) + + # PlaneFitter - Using a fixed input + planefitter = smp.PlaneFitter(Input=trivialproducer) + smp.RenameSource(planefitter_name, planefitter) + + # Determine Laser ID Array Name + try: + # if laser_id is the name of the array in Legacy and Special Velarray mode + # LCN is the name of the array in APF mode + for arr in extractor.PointData: + if arr.Name == "laser_id": + planefitter.laserIDArray = "laser_id" + elif arr.Name == "LCN": + planefitter.laserIDArray = "LCN" + planefitter.UpdatePipeline() + + # Display results on the main spreadsheet view + showStats(planefitter, actionSpreadsheet) + + # Show Model + smp.Show(servermanager.OutputPort(planefitter, outputPort=1)) + except : + print("PlaneFit error: Unable to select appropriate laserIDArray") + finally: + smp.Delete(extractsurf) + smp.Delete(merger) + smp.Delete(extractor) + smp.SetActiveSource(src) # Restore Active Source + -- GitLab From 7497172eeee595fdb382a64730252050c9b3efca Mon Sep 17 00:00:00 2001 From: Arnaud Billon <arnaud.billon@kitware.com> Date: Tue, 4 Jan 2022 10:09:55 +0100 Subject: [PATCH 4/7] [submodule] Bump LVCore lv-sb common-sb --- LVCore | 2 +- Plugins/VelodynePlugin | 2 +- Superbuild/lidarview-superbuild | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/LVCore b/LVCore index 9399696df..8952a3e8c 160000 --- a/LVCore +++ b/LVCore @@ -1 +1 @@ -Subproject commit 9399696dfa00d03145af65e8427fa8082191f5e7 +Subproject commit 8952a3e8c68a2f856624547e92a3e17155a4ada8 diff --git a/Plugins/VelodynePlugin b/Plugins/VelodynePlugin index dd3a98533..2a6fa5b2d 160000 --- a/Plugins/VelodynePlugin +++ b/Plugins/VelodynePlugin @@ -1 +1 @@ -Subproject commit dd3a98533809647574616aeedc92b6fc6fcac448 +Subproject commit 2a6fa5b2d25a60b530448e6162326249840a30fa diff --git a/Superbuild/lidarview-superbuild b/Superbuild/lidarview-superbuild index 0d2592634..9c8a9a3f1 160000 --- a/Superbuild/lidarview-superbuild +++ b/Superbuild/lidarview-superbuild @@ -1 +1 @@ -Subproject commit 0d259263460fc8c9f4529c58d2837d853d80acdd +Subproject commit 9c8a9a3f1d9919d5d06326250a06b4a6063a8610 -- GitLab From ed334148df8bef0a4aecdfced52062f60723f520 Mon Sep 17 00:00:00 2001 From: Arnaud Billon <arnaud.billon@kitware.com> Date: Tue, 4 Jan 2022 10:38:00 +0100 Subject: [PATCH 5/7] [fix] calibrationReaction Add additional warnings --- Application/Ui/lqUpdateCalibrationReaction.cxx | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/Application/Ui/lqUpdateCalibrationReaction.cxx b/Application/Ui/lqUpdateCalibrationReaction.cxx index ae6000b80..7dec467b3 100644 --- a/Application/Ui/lqUpdateCalibrationReaction.cxx +++ b/Application/Ui/lqUpdateCalibrationReaction.cxx @@ -45,7 +45,17 @@ void lqUpdateCalibrationReaction::setTransform(vtkSMProxy * proxy, vtkSMSessionProxyManager* pxm = pqActiveObjects::instance().proxyManager(); vtkSMProperty * interpreterProp = proxy->GetProperty("PacketInterpreter"); + if(!interpreterProp) + { + qWarning("lqUpdateCalibrationReaction::setTransform: Null PacketInterpreter"); + return; + } vtkSMProxy * interpreterProxy = vtkSMPropertyHelper(interpreterProp).GetAsProxy(); + if(!interpreterProxy) + { + qWarning("lqUpdateCalibrationReaction::setTransform: Null PacketInterpreter Proxy"); + return; + } // Create a transform proxy // For Transform2 : name "Position" = label "Translate -- GitLab From dfe6f76b3c9eb2b2690db0dd0e9a1520741aa70f Mon Sep 17 00:00:00 2001 From: Arnaud Billon <arnaud.billon@kitware.com> Date: Tue, 4 Jan 2022 10:39:07 +0100 Subject: [PATCH 6/7] [fix] Correct OSX rpath handling --- Superbuild/Projects/lidarview.cmake | 1 + 1 file changed, 1 insertion(+) diff --git a/Superbuild/Projects/lidarview.cmake b/Superbuild/Projects/lidarview.cmake index ffe2b260b..407f21bf2 100644 --- a/Superbuild/Projects/lidarview.cmake +++ b/Superbuild/Projects/lidarview.cmake @@ -6,6 +6,7 @@ superbuild_add_project(lidarview #LidarView base configuration -DBUILD_SHARED_LIBS:BOOL=ON -DBUILD_TESTING:BOOL=OFF + -DCMAKE_MACOSX_RPATH:BOOL=OFF -DLV_BUILD_PLATFORM=${LV_BUILD_PLATFORM} -Dsuperbuild_python_version=${superbuild_python_version} -DParaView_DIR:PATH=${SuperBuild_BINARY_DIR}/common-superbuild/paraview/build -- GitLab From b007d9ece432729fbeb436f98032ea384b5d2c23 Mon Sep 17 00:00:00 2001 From: Arnaud Billon <arnaud.billon@kitware.com> Date: Tue, 4 Jan 2022 10:47:59 +0100 Subject: [PATCH 7/7] [fix] Enable showRPM --- Application/Ui/python/lidarview/applogic.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/Application/Ui/python/lidarview/applogic.py b/Application/Ui/python/lidarview/applogic.py index 82cf70dc8..f9376ca1b 100644 --- a/Application/Ui/python/lidarview/applogic.py +++ b/Application/Ui/python/lidarview/applogic.py @@ -1201,18 +1201,19 @@ def createRPMBehaviour(): # create and customize a label to display the rpm rpm = smp.Text(guiName="RPM", Text="No RPM") representation = smp.GetRepresentation(rpm) - representation.FontSize = 8 + representation.FontSize = 16 representation.Color = [1,1,0] # create an python animation cue to update the rpm value in the label PythonAnimationCue1 = smp.PythonAnimationCue() PythonAnimationCue1.Script= """ import paraview.simple as smp +import lidarview.applogic as lv def start_cue(self): pass def tick(self): rpm = smp.FindSource("RPM") - lidar = smp.FindSource("Data") + lidar = lv.getLidar() #smp.FindSource("Data") if (lidar): value = int(lidar.Interpreter.GetClientSideObject().GetFrequency()) rpm.Text = str(value) + " RPM" @@ -1225,6 +1226,7 @@ def end_cue(self): smp.GetAnimationScene().Cues.append(PythonAnimationCue1) # force to be consistant with the UI toggleRPM() + smp.SetActiveSource(None) def updateUIwithNewLidar(): -- GitLab