点云构网时,程序崩溃bug,经排查是pcl库问题,重新编译源代码,取消avx see 等CPU特异化指令,然后重新编译PCL。子线程调用主线程实例,子线程销毁时,销毁主线程实例调用函数栈,回调函数地址为nullptr,内存泄露,程序崩溃。

pull/1/head
剑古敛锋 2024-05-13 09:12:04 +08:00
parent 2044867fe6
commit 6aec508c62
34 changed files with 2586 additions and 1867 deletions

View File

@ -1,7 +1,11 @@
<component name="ProjectCodeStyleConfiguration"> <component name="ProjectCodeStyleConfiguration">
<code_scheme name="Project" version="173"> <code_scheme name="Project" version="173">
<option name="RIGHT_MARGIN" value="1000" />
<clangFormatSettings> <clangFormatSettings>
<option name="ENABLED" value="true" /> <option name="ENABLED" value="true" />
</clangFormatSettings> </clangFormatSettings>
<codeStyleSettings language="ObjectiveC">
<option name="RIGHT_MARGIN" value="1000" />
</codeStyleSettings>
</code_scheme> </code_scheme>
</component> </component>

View File

@ -31,6 +31,25 @@ set(CMAKE_AUTOMOC ON)
set(CMAKE_AUTOUIC ON) set(CMAKE_AUTOUIC ON)
set(CMAKE_AUTORCC ON) set(CMAKE_AUTORCC ON)
#if(MSVC)
## add_definitions(-DPCL_NO_PRECOMPILE)
# # Visual Studio
# add_compile_options(/arch:AVX) # AVX
# # SSE2
## add_compile_options(/arch:SSE)
#
# # MARCH_NATIVE
# add_compile_options(/arch:AVX)
#elseif(CMAKE_COMPILER_IS_GNUCC OR CMAKE_COMPILER_IS_GNUCXX)
# # GCC Clang
# add_compile_options(-mavx) # AVX
# # SSE
## set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -msse")
#
# # MARCH_NATIVE
# set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -march=native")
#endif()
#----------------------------------------------------------------------------- #-----------------------------------------------------------------------------
# #
@ -234,6 +253,8 @@ find_package(GDAL CONFIG REQUIRED)
# sqlite3 # sqlite3
find_package(unofficial-sqlite3 CONFIG REQUIRED) find_package(unofficial-sqlite3 CONFIG REQUIRED)
# QGIS # QGIS
find_package(QGIS REQUIRED) find_package(QGIS REQUIRED)
@ -253,6 +274,7 @@ include_directories(SYSTEM C:/PCL/include/pcl-1.14)
set(CMAKE_INCLUDE_CURRENT_DIR ON) set(CMAKE_INCLUDE_CURRENT_DIR ON)
find_package(Qt5 REQUIRED COMPONENTS Test Core Quick Sql Core Xml Opengl Gui Svg Xmlpatterns Uitools Widgets Qml Printsupport Sensors Quickwidgets Quick Concurrent Openglextensions Charts Datavisualization Network) find_package(Qt5 REQUIRED COMPONENTS Test Core Quick Sql Core Xml Opengl Gui Svg Xmlpatterns Uitools Widgets Qml Printsupport Sensors Quickwidgets Quick Concurrent Openglextensions Charts Datavisualization Network)
# PCL
find_package(PCL) find_package(PCL)
include_directories(${PCL_INCLUDE_DIRS}) include_directories(${PCL_INCLUDE_DIRS})
include_directories(${VCGLIB_INCLUDE_DIRS}) include_directories(${VCGLIB_INCLUDE_DIRS})

View File

@ -22,7 +22,9 @@ namespace MainWidget {
DialogSelectMeshDataComponents::DialogSelectMeshDataComponents(GUI::MainWindow* parent) DialogSelectMeshDataComponents::DialogSelectMeshDataComponents(GUI::MainWindow* parent)
: QFDialog(parent) : QFDialog(parent)
,_ui(new Ui::DialogSelectMeshDataComponents)
{ {
_ui->setupUi(this); _ui->setupUi(this);
setWindowTitle(tr("Select Components")); setWindowTitle(tr("Select Components"));

View File

@ -368,7 +368,9 @@ namespace GUI {
connect(this, SIGNAL(openPlot()), _signalHandler, SLOT(openPlotFile())); connect(this, SIGNAL(openPlot()), _signalHandler, SLOT(openPlotFile()));
// 点云模块 // 点云模块
connect(this, SIGNAL(importMeshSIGN(QString ,QString ,int )),this, SLOT(importMesh(QString ,QString ,int )));
/// 导入点云
connect(this, SIGNAL(importPclSIGN(QString ,QString ,int )),this, SLOT(importPcl(QString ,QString ,int )));
} }
@ -616,6 +618,26 @@ namespace GUI {
} }
} }
void MainWindow::importMesh(QString fileName,QString aSuffix,int modelID){
if(fileName.isEmpty())
return;
QString pyCode = QString("MainWindow.importMesh(\"%1\",\"%2\",%3)")
.arg(fileName)
.arg(aSuffix)
.arg(modelID);
Py::PythonAgent::getInstance()->submit(pyCode);
}
void MainWindow::importPcl(QString fileName,QString aSuffix,int modelID){
if(fileName.isEmpty())
return;
QString pyCode = QString("MainWindow.importPcl(\"%1\",\"%2\",%3)")
.arg(fileName)
.arg(aSuffix)
.arg(modelID);
Py::PythonAgent::getInstance()->submit(pyCode);
}
void MainWindow::on_importMesh() void MainWindow::on_importMesh()
{ {
QStringList suffixlist = IO::IOConfigure::getMeshImporters(); QStringList suffixlist = IO::IOConfigure::getMeshImporters();

View File

@ -153,6 +153,11 @@ namespace GUI {
// Ribbon Customize // Ribbon Customize
SARibbonActionsManager* getActionManager(); SARibbonActionsManager* getActionManager();
signals: signals:
/*更新注册接口*/ /*更新注册接口*/
void updateInterfaces(); void updateInterfaces();
@ -322,6 +327,12 @@ namespace GUI {
// Tool Show // Tool Show
void on_actionAttriutionDBShow(GUI::MainWindow* m); void on_actionAttriutionDBShow(GUI::MainWindow* m);
// 导入网格
void importMeshSIGN(QString filepath,QString aSuffix,int modelID);
/// 导入点云
void importPclSIGN(QString filepath,QString aSuffix,int modelID);
public slots: public slots:
/*状态栏显示信息 */ /*状态栏显示信息 */
void setStatusBarInfo(QString); void setStatusBarInfo(QString);
@ -373,6 +384,14 @@ namespace GUI {
// feko 设置 // feko 设置
void on_AttriutionDBShow(); void on_AttriutionDBShow();
// 导入mesh
void importMesh(QString filepath,QString aSuffix,int modelID);
/// 导入点云
void importPcl(QString filepath,QString aSuffix,int modelID);
private slots: private slots:
/*关闭主窗口 */ /*关闭主窗口 */
void closeWindow(); void closeWindow();

View File

@ -1648,6 +1648,8 @@
<addaction name="separator"/> <addaction name="separator"/>
<addaction name="actionFEKO2csv"/> <addaction name="actionFEKO2csv"/>
<addaction name="actionScatterExport"/> <addaction name="actionScatterExport"/>
<addaction name="separator"/>
<addaction name="actionAttriutionDBShow"/>
</widget> </widget>
<widget class="QMenu" name="MenuCropTargetBackscatteringCharacteristicsCalculationModule"> <widget class="QMenu" name="MenuCropTargetBackscatteringCharacteristicsCalculationModule">
<property name="title"> <property name="title">
@ -1657,6 +1659,8 @@
<addaction name="separator"/> <addaction name="separator"/>
<addaction name="actionFEKO2csv"/> <addaction name="actionFEKO2csv"/>
<addaction name="actionScatterExport"/> <addaction name="actionScatterExport"/>
<addaction name="separator"/>
<addaction name="actionAttriutionDBShow"/>
</widget> </widget>
<widget class="QMenu" name="MenuGrasslandTargetBackscatteringCharacteristicsCalculationModule"> <widget class="QMenu" name="MenuGrasslandTargetBackscatteringCharacteristicsCalculationModule">
<property name="title"> <property name="title">
@ -1666,6 +1670,8 @@
<addaction name="separator"/> <addaction name="separator"/>
<addaction name="actionFEKO2csv"/> <addaction name="actionFEKO2csv"/>
<addaction name="actionScatterExport"/> <addaction name="actionScatterExport"/>
<addaction name="separator"/>
<addaction name="actionAttriutionDBShow"/>
</widget> </widget>
<widget class="QMenu" name="MenuWaterBodyTargetBackscatteringCharacteristicsCalculationModule"> <widget class="QMenu" name="MenuWaterBodyTargetBackscatteringCharacteristicsCalculationModule">
<property name="title"> <property name="title">
@ -1675,6 +1681,8 @@
<addaction name="separator"/> <addaction name="separator"/>
<addaction name="actionFEKO2csv"/> <addaction name="actionFEKO2csv"/>
<addaction name="actionScatterExport"/> <addaction name="actionScatterExport"/>
<addaction name="separator"/>
<addaction name="actionAttriutionDBShow"/>
</widget> </widget>
<widget class="QMenu" name="MenuSoilTargetBackscatteringCharacteristicsCalculationModule"> <widget class="QMenu" name="MenuSoilTargetBackscatteringCharacteristicsCalculationModule">
<property name="title"> <property name="title">
@ -1684,6 +1692,8 @@
<addaction name="separator"/> <addaction name="separator"/>
<addaction name="actionFEKO2csv"/> <addaction name="actionFEKO2csv"/>
<addaction name="actionScatterExport"/> <addaction name="actionScatterExport"/>
<addaction name="separator"/>
<addaction name="actionAttriutionDBShow"/>
</widget> </widget>
<widget class="QMenu" name="MenuDynamicWaterBodyTargetBackscatteringCharacteristicsCalculationModule"> <widget class="QMenu" name="MenuDynamicWaterBodyTargetBackscatteringCharacteristicsCalculationModule">
<property name="title"> <property name="title">
@ -1693,6 +1703,8 @@
<addaction name="separator"/> <addaction name="separator"/>
<addaction name="actionFEKO2csv"/> <addaction name="actionFEKO2csv"/>
<addaction name="actionScatterExport"/> <addaction name="actionScatterExport"/>
<addaction name="separator"/>
<addaction name="actionAttriutionDBShow"/>
</widget> </widget>
<widget class="QMenu" name="MenuRoadTargetBackscatteringCharacteristicsCalculationModule"> <widget class="QMenu" name="MenuRoadTargetBackscatteringCharacteristicsCalculationModule">
<property name="title"> <property name="title">
@ -1702,6 +1714,8 @@
<addaction name="separator"/> <addaction name="separator"/>
<addaction name="actionFEKO2csv"/> <addaction name="actionFEKO2csv"/>
<addaction name="actionScatterExport"/> <addaction name="actionScatterExport"/>
<addaction name="separator"/>
<addaction name="actionAttriutionDBShow"/>
</widget> </widget>
<widget class="QMenu" name="MenuArtificialTargetBackscatteringCharacteristicsCalculationModule"> <widget class="QMenu" name="MenuArtificialTargetBackscatteringCharacteristicsCalculationModule">
<property name="title"> <property name="title">
@ -1711,6 +1725,8 @@
<addaction name="separator"/> <addaction name="separator"/>
<addaction name="actionFEKO2csv"/> <addaction name="actionFEKO2csv"/>
<addaction name="actionScatterExport"/> <addaction name="actionScatterExport"/>
<addaction name="separator"/>
<addaction name="actionAttriutionDBShow"/>
</widget> </widget>
<widget class="QMenu" name="MenuGeometricCorrectionSceneBackscatteringCharacteristicsCalculationModule"> <widget class="QMenu" name="MenuGeometricCorrectionSceneBackscatteringCharacteristicsCalculationModule">
<property name="title"> <property name="title">
@ -1720,6 +1736,8 @@
<addaction name="separator"/> <addaction name="separator"/>
<addaction name="actionFEKO2csv"/> <addaction name="actionFEKO2csv"/>
<addaction name="actionScatterExport"/> <addaction name="actionScatterExport"/>
<addaction name="separator"/>
<addaction name="actionAttriutionDBShow"/>
</widget> </widget>
<widget class="QMenu" name="MenuRadiometricCorrectionSceneBackscatteringCharacteristicsCalculationModule"> <widget class="QMenu" name="MenuRadiometricCorrectionSceneBackscatteringCharacteristicsCalculationModule">
<property name="title"> <property name="title">
@ -1729,6 +1747,8 @@
<addaction name="separator"/> <addaction name="separator"/>
<addaction name="actionFEKO2csv"/> <addaction name="actionFEKO2csv"/>
<addaction name="actionScatterExport"/> <addaction name="actionScatterExport"/>
<addaction name="separator"/>
<addaction name="actionAttriutionDBShow"/>
</widget> </widget>
<widget class="QMenu" name="MenuLandSurfaceSceneBackscatteringCharacteristicsCalculationModule"> <widget class="QMenu" name="MenuLandSurfaceSceneBackscatteringCharacteristicsCalculationModule">
<property name="title"> <property name="title">
@ -1738,6 +1758,8 @@
<addaction name="separator"/> <addaction name="separator"/>
<addaction name="actionFEKO2csv"/> <addaction name="actionFEKO2csv"/>
<addaction name="actionScatterExport"/> <addaction name="actionScatterExport"/>
<addaction name="separator"/>
<addaction name="actionAttriutionDBShow"/>
</widget> </widget>
<widget class="QMenu" name="MenuWaterBodySceneBackscatteringCharacteristicsCalculationModule"> <widget class="QMenu" name="MenuWaterBodySceneBackscatteringCharacteristicsCalculationModule">
<property name="title"> <property name="title">
@ -1747,6 +1769,8 @@
<addaction name="separator"/> <addaction name="separator"/>
<addaction name="actionFEKO2csv"/> <addaction name="actionFEKO2csv"/>
<addaction name="actionScatterExport"/> <addaction name="actionScatterExport"/>
<addaction name="separator"/>
<addaction name="actionAttriutionDBShow"/>
</widget> </widget>
<widget class="QMenu" name="MenuVegetationSceneBackscatteringCharacteristicsCalculationModule"> <widget class="QMenu" name="MenuVegetationSceneBackscatteringCharacteristicsCalculationModule">
<property name="title"> <property name="title">
@ -1756,6 +1780,8 @@
<addaction name="separator"/> <addaction name="separator"/>
<addaction name="actionFEKO2csv"/> <addaction name="actionFEKO2csv"/>
<addaction name="actionScatterExport"/> <addaction name="actionScatterExport"/>
<addaction name="separator"/>
<addaction name="actionAttriutionDBShow"/>
</widget> </widget>
<addaction name="MenuForestTargetBackscatteringCharacteristicsCalculationModule"/> <addaction name="MenuForestTargetBackscatteringCharacteristicsCalculationModule"/>
<addaction name="MenuCropTargetBackscatteringCharacteristicsCalculationModule"/> <addaction name="MenuCropTargetBackscatteringCharacteristicsCalculationModule"/>

View File

@ -1670,7 +1670,7 @@ namespace GUI {
meshSet = meshData->getMeshSetByID(compontId.toInt()); meshSet = meshData->getMeshSetByID(compontId.toInt());
if(!meshSet) if(!meshSet)
continue; continue;
//meshSet->generateDisplayDataSet();
vtkRela.SetData(meshSet->getDisplayDataSet()); vtkRela.SetData(meshSet->getDisplayDataSet());
vtkSmartPointer<vtkDataSet> transformed = vtkRela.StartTransform(); vtkSmartPointer<vtkDataSet> transformed = vtkRela.StartTransform();
@ -1679,7 +1679,7 @@ namespace GUI {
meshKernal->setName(kernalName); meshKernal->setName(kernalName);
meshKernal->setMeshData(transformed); meshKernal->setMeshData(transformed);
meshData->appendMeshKernal(meshKernal); meshData->appendMeshKernal(meshKernal);
qDebug()<<"transfrom kernalName :\t "<<kernalName;
transformedName = transformedName =
QString(meshSet->getName() + "_transform%1").arg(meshSet->getMaxID() + 1); QString(meshSet->getName() + "_transform%1").arg(meshSet->getMaxID() + 1);
setType = MeshData::MeshSet::setTypeToString(meshSet->getSetType()); setType = MeshData::MeshSet::setTypeToString(meshSet->getSetType());

View File

@ -35,6 +35,18 @@
#include <vtkAreaPicker.h> #include <vtkAreaPicker.h>
#include <vtkProperty2D.h> #include <vtkProperty2D.h>
#include <vtkAppendFilter.h> #include <vtkAppendFilter.h>
#include <vtkRenderer.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkRenderWindow.h>
#include <vtkSmartPointer.h>
#include <vtkProperty.h>
#include <vtkCubeAxesActor2D.h>
#include <vtkInteractorStyleTrackballCamera.h>
#include <vtkCubeAxesActor.h>
#include "PreWindowInteractorStyle.h" #include "PreWindowInteractorStyle.h"
#include "MainWindow/MainWindow.h" #include "MainWindow/MainWindow.h"
#include "MeshData/meshSet.h" #include "MeshData/meshSet.h"
@ -86,8 +98,11 @@ namespace ModuleBase
_renderWindow = _ui->qvtkWidget->renderWindow(); _renderWindow = _ui->qvtkWidget->renderWindow();
#endif #endif
_render = vtkSmartPointer<vtkRenderer>::New(); _render = vtkSmartPointer<vtkOpenGLRenderer>::New();
_render->SetGradientBackground(true); _render->SetGradientBackground(true);
// 开启硬件加速特性
_render->UseDepthPeelingOn();
_render->SetUseFXAA(true);
// _render->SetBackground2(0.0, 0.333, 1.0); // _render->SetBackground2(0.0, 0.333, 1.0);
// _render->SetBackground(1.0, 1.0, 1.0); // _render->SetBackground(1.0, 1.0, 1.0);
_interactor = _renderWindow->GetInteractor(); _interactor = _renderWindow->GetInteractor();
@ -98,6 +113,10 @@ namespace ModuleBase
_viewer->setupInteractor(_interactor, _renderWindow); _viewer->setupInteractor(_interactor, _renderWindow);
_viewer->setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_COLOR, 3); // 初始化为点云颜色 _viewer->setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_COLOR, 3); // 初始化为点云颜色
// 创建立方体网格坐标系
_cubeAxesActor = vtkSmartPointer<vtkCubeAxesActor>::New();
createCubeAxes();
if (_graphWindowType == PreWindows) if (_graphWindowType == PreWindows)
{ {
PropPickerInteractionStyle *style = PropPickerInteractionStyle::New(); PropPickerInteractionStyle *style = PropPickerInteractionStyle::New();
@ -470,4 +489,63 @@ namespace ModuleBase
double h = this->getWorldHight(); double h = this->getWorldHight();
emit showGraphRange(w, h); emit showGraphRange(w, h);
} }
void Graph3DWindow::createCubeAxes(double minx, double maxx, double miny, double maxy,
double minz, double maxz)
{
_cubeAxesActor->SetCamera(_render->GetActiveCamera());
//
//轴的设置
//设置x、y、z轴的起始和终止值
_cubeAxesActor->SetXAxisRange(minx, maxx);
_cubeAxesActor->SetYAxisRange(miny, maxy);
_cubeAxesActor->SetZAxisRange(minz, maxz);
//设置坐标轴线的宽度
_cubeAxesActor->GetXAxesLinesProperty()->SetLineWidth(0.5);
_cubeAxesActor->GetYAxesLinesProperty()->SetLineWidth(0.5);
_cubeAxesActor->GetZAxesLinesProperty()->SetLineWidth(0.5);
//设置标题和标签文本的屏幕大小。默认值为10.0。
_cubeAxesActor->SetScreenSize(6);
//指定标签与轴之间的距离。默认值为20.0。
_cubeAxesActor->SetLabelOffset(5);
//显示坐标轴
_cubeAxesActor->SetVisibility(true);
//指定一种模式来控制轴的绘制方式
_cubeAxesActor->SetFlyMode(0);
//设置惯性因子,该惯性因子控制轴切换位置的频率(从一个轴跳到另一个轴)
//m_cubeAxesActor->SetInertia(1);
//
//网格设置
//开启x、y、z轴的网格线绘制
_cubeAxesActor->DrawXGridlinesOn();
_cubeAxesActor->DrawYGridlinesOn();
_cubeAxesActor->DrawZGridlinesOn();
//设置x、y、z轴的内部网格线不绘制
_cubeAxesActor->SetDrawXInnerGridlines(false);
_cubeAxesActor->SetDrawYInnerGridlines(false);
_cubeAxesActor->SetDrawZInnerGridlines(false);
//设置x、y、z轴网格线的颜色
_cubeAxesActor->GetXAxesGridlinesProperty()->SetColor(0.5, 0.5, 0.5);
_cubeAxesActor->GetYAxesGridlinesProperty()->SetColor(0.5, 0.5, 0.5);
_cubeAxesActor->GetZAxesGridlinesProperty()->SetColor(0.5, 0.5, 0.5);
//指定网格线呈现的样式
_cubeAxesActor->SetGridLineLocation(2);
//
//刻度的设置
//不显示x、y、z轴的次刻度
_cubeAxesActor->XAxisMinorTickVisibilityOff();
_cubeAxesActor->YAxisMinorTickVisibilityOff();
_cubeAxesActor->ZAxisMinorTickVisibilityOff();
//设置刻度标签的显示方式(参数1为false刻度标签按0-200000显示为true时按0-200显示)
_cubeAxesActor->SetLabelScaling(false, 0, 0, 0);
//设置刻度线显示的位置(内部、外部、两侧)
_cubeAxesActor->SetTickLocation(1);
//
_render->AddActor(_cubeAxesActor);
_render->ResetCamera();
_render->ResetCameraClippingRange();
_renderWindow->Render();
}
} }

View File

@ -1,6 +1,6 @@
#ifndef _GRAPH3DWINDOW_H_ #ifndef _GRAPH3DWINDOW_H_
#define _GRAPH3DWINDOW_H_ #define _GRAPH3DWINDOW_H_
//#define PCL_NO_PRECOMPILE
#include <QWidget> #include <QWidget>
#include <vtkSmartPointer.h> #include <vtkSmartPointer.h>
#include <vtkAutoInit.h> #include <vtkAutoInit.h>
@ -9,11 +9,12 @@
#include "ModuleType.h" #include "ModuleType.h"
#include <QString> #include <QString>
#include <QStringList> #include <QStringList>
#include <vtkOpenGLRenderer.h>
// Point Cloud Library // Point Cloud Library
#include <QColorDialog> #include <QColorDialog>
#include <iostream> #include <iostream>
#include <pcl/common/common.h> #include <pcl/common/common.h>
#include <pcl/console/time.h> // TicToc #include <pcl/console/time.h> // TicToc
#include <pcl/console/time.h> #include <pcl/console/time.h>
@ -34,29 +35,12 @@
#include <iostream> #include <iostream>
#include <pcl/console/time.h> // TicToc #include <pcl/console/time.h> // TicToc
#include <pcl/features/normal_3d.h> #include <pcl/features/normal_3d.h>
#include <pcl/filters/bilateral.h>
#include <pcl/filters/extract_indices.h>
#include <pcl/filters/fast_bilateral.h>
#include <pcl/filters/fast_bilateral_omp.h>
#include <pcl/filters/passthrough.h>
#include <pcl/filters/voxel_grid.h>
#include <pcl/io/pcd_io.h> #include <pcl/io/pcd_io.h>
#include <pcl/io/ply_io.h> #include <pcl/io/ply_io.h>
#include <pcl/kdtree/kdtree.h>
#include <pcl/kdtree/kdtree_flann.h>
#include <pcl/point_cloud.h> #include <pcl/point_cloud.h>
#include <pcl/point_types.h> #include <pcl/point_types.h>
#include <pcl/registration/ia_fpcs.h> // 4PCS算法
#include <pcl/registration/ia_kfpcs.h> //K4PCS算法头文件
#include <pcl/registration/icp.h>
#include <pcl/registration/registration.h> #include <pcl/registration/registration.h>
#include <pcl/search/flann_search.h>
#include <pcl/surface/concave_hull.h>
#include <pcl/surface/gp3.h> //贪婪投影三角化算法类定义的头文件
#include <pcl/surface/marching_cubes_hoppe.h> //移动立方体
#include <pcl/surface/marching_cubes_rbf.h>
#include <pcl/surface/mls.h> //MLS
#include <pcl/surface/poisson.h> //泊松重建
#include <pcl/visualization/cloud_viewer.h> #include <pcl/visualization/cloud_viewer.h>
#include <pcl/visualization/pcl_visualizer.h> #include <pcl/visualization/pcl_visualizer.h>
#include <string> #include <string>
@ -64,15 +48,11 @@
#include <vtkOutputWindow.h> #include <vtkOutputWindow.h>
#include <pcl/console/time.h> // TicToc #include <pcl/console/time.h> // TicToc
#include <pcl/filters/approximate_voxel_grid.h> // 体素滤波
#include <pcl/filters/voxel_grid.h> // 体素滤波
#include <vtkOutputWindow.h> #include <vtkOutputWindow.h>
#include <boost/thread/thread.hpp> #include <boost/thread/thread.hpp>
#include <pcl/ModelCoefficients.h> #include <pcl/ModelCoefficients.h>
#include <pcl/filters/extract_indices.h> #include <pcl/filters/extract_indices.h>
#include <pcl/io/pcd_io.h>
#include <pcl/point_types.h>
#include <pcl/sample_consensus/method_types.h> //随机参数估计方法 #include <pcl/sample_consensus/method_types.h> //随机参数估计方法
#include <pcl/sample_consensus/model_types.h> //模型定义 #include <pcl/sample_consensus/model_types.h> //模型定义
#include <pcl/segmentation/sac_segmentation.h> //RANSAC分割 #include <pcl/segmentation/sac_segmentation.h> //RANSAC分割
@ -89,7 +69,6 @@
#include <pcl/common/common.h> #include <pcl/common/common.h>
#include <pcl/common/transforms.h> #include <pcl/common/transforms.h>
#include <pcl/features/moment_of_inertia_estimation.h> #include <pcl/features/moment_of_inertia_estimation.h>
#include <pcl/filters/voxel_grid.h>
#include <pcl/io/io.h> #include <pcl/io/io.h>
#include <pcl/io/pcd_io.h> #include <pcl/io/pcd_io.h>
#include <pcl/point_cloud.h> #include <pcl/point_cloud.h>
@ -111,10 +90,7 @@
#include <vtkRenderer.h> #include <vtkRenderer.h>
// Boost // Boost
#include <boost/math/special_functions/round.hpp> #include <boost/math/special_functions/round.hpp>
#include <vtkCubeAxesActor.h>
VTK_MODULE_INIT(vtkRenderingOpenGL2); VTK_MODULE_INIT(vtkRenderingOpenGL2);
VTK_MODULE_INIT(vtkInteractionStyle); VTK_MODULE_INIT(vtkInteractionStyle);
@ -199,6 +175,9 @@ namespace ModuleBase
double getWorldHight(); double getWorldHight();
//获取窗体世界坐标系下宽度 //获取窗体世界坐标系下宽度
double getWorldWidth(); double getWorldWidth();
// 创建立方体网格坐标系
void createCubeAxes(double minx=-1000,double maxx=1000,double miny=-1000,double maxy=1000,double minz=-1000,double maxz=1000);
public slots: public slots:
//重绘 //重绘
@ -249,7 +228,9 @@ namespace ModuleBase
Ui::Graph3DWindow* _ui{}; Ui::Graph3DWindow* _ui{};
// QStringList m_ltFilePath = QStringList(); // QStringList m_ltFilePath = QStringList();
vtkSmartPointer<vtkRenderer> _render{}; //vtkSmartPointer<vtkRenderer> _render{};
vtkSmartPointer<vtkOpenGLRenderer> _render{};
vtkSmartPointer<vtkCubeAxesActor> _cubeAxesActor{};
vtkSmartPointer<vtkRenderWindow> _renderWindow{}; vtkSmartPointer<vtkRenderWindow> _renderWindow{};
vtkSmartPointer< vtkRenderWindowInteractor > _interactor{}; vtkSmartPointer< vtkRenderWindowInteractor > _interactor{};
@ -266,8 +247,6 @@ namespace ModuleBase
/*** 点云处理***/ /*** 点云处理***/
pcl::visualization::PCLVisualizer::Ptr _viewer; // 点云显示共享指针 pcl::visualization::PCLVisualizer::Ptr _viewer; // 点云显示共享指针
}; };
} }

View File

@ -1,7 +1,7 @@
#pragma once #pragma once
#ifndef ALLHEAD_H #ifndef ALLHEAD_H
#define ALLHEAD_H #define ALLHEAD_H
//#define PCL_NO_PRECOMPILE 1
#include "WBFZExchangePluginAPI.h" #include "WBFZExchangePluginAPI.h"
#include "Common/DebugLogger.h" #include "Common/DebugLogger.h"
#include "Geometry/geometryData.h" #include "Geometry/geometryData.h"
@ -42,6 +42,7 @@
#include "OCCTBase.h" #include "OCCTBase.h"
#include "FEKOFarFieldFileClass.h" #include "FEKOFarFieldFileClass.h"
//===================================================== //=====================================================
// 内部库 SharedModuleLib // 内部库 SharedModuleLib
//===================================================== //=====================================================

View File

@ -202,11 +202,11 @@ WBFZ::PCLBilateralFilter::PCLBilateralFilter(const QString& fileName,
{ {
} }
vtkDataSet* WBFZ::PCLBilateralFilter::filter() bool WBFZ::PCLBilateralFilter::filter()
{ {
return PCLBilateralFilterAlg( _componentIds, _sigmaR, _sigmaS); return PCLBilateralFilterAlg( _componentIds, _sigmaR, _sigmaS);
} }
vtkDataSet* WBFZ::PCLBilateralFilter::PCLBilateralFilterAlg(QString componentIds, double sigmaR, bool WBFZ::PCLBilateralFilter::PCLBilateralFilterAlg(QString componentIds, double sigmaR,
double sigmaS) double sigmaS)
{ {
emit _mainwindow->printMessage(Common::Message::Normal,"PCLBilateralFilterAlg"); emit _mainwindow->printMessage(Common::Message::Normal,"PCLBilateralFilterAlg");
@ -260,32 +260,12 @@ vtkDataSet* WBFZ::PCLBilateralFilter::PCLBilateralFilterAlg(QString componentIds
vtkDataSet* dataset= vtkDataSet::SafeDownCast(polydata); // 默认完成 vtkpolydata --> vtkdataset vtkDataSet* dataset= vtkDataSet::SafeDownCast(polydata); // 默认完成 vtkpolydata --> vtkdataset
size_t pointCount = dataset->GetNumberOfPoints(); size_t pointCount = dataset->GetNumberOfPoints();
if(pointCount==0){ if(pointCount==0){
return nullptr; return false;
} }
emit _mainwindow->printMessage(Common::Message::Normal,"PCLBilateralFilterAlg successfully!! Point Count : "+QString::number(pointCount)); emit _mainwindow->printMessage(Common::Message::Normal,"PCLBilateralFilterAlg successfully!! Point Count : "+QString::number(pointCount));
outpolyData->Delete(); // 释放指针 outpolyData->Delete(); // 释放指针
QString filepath=_fileName; return this->saveFilterResultFile(cloud_filtered);
// 加载文件
QFileInfo info(filepath);
QString name = info.fileName();
QString path = info.filePath();
QString suffix = info.suffix().toLower();
QTextCodec *codec = QTextCodec::codecForName("GB18030");
QByteArray ba = codec->fromUnicode(filepath);
std::string outFileName=ba.data();
if (suffix == "pcd")
{
pcl::io::savePCDFileBinary(outFileName,*cloud_filtered);
}
else if (suffix == "ply")
{
pcl::io::savePLYFileBinary(outFileName,*cloud_filtered);
}
else{}
return dataset;
} }
WBFZ::PCLBilateralFilter::~PCLBilateralFilter() {} WBFZ::PCLBilateralFilter::~PCLBilateralFilter() {}

View File

@ -41,8 +41,8 @@ namespace WBFZ{
PCLBilateralFilter(const QString &fileName, PointCloudOperation operation, GUI::MainWindow *mw, QString componentIds, double sigmaR,double sigmaS); PCLBilateralFilter(const QString &fileName, PointCloudOperation operation, GUI::MainWindow *mw, QString componentIds, double sigmaR,double sigmaS);
~PCLBilateralFilter(); ~PCLBilateralFilter();
private: private:
vtkDataSet* filter() override; bool filter() override;
vtkDataSet* PCLBilateralFilterAlg(QString componentIds,double sigmaR,double sigmaS); bool PCLBilateralFilterAlg(QString componentIds,double sigmaR,double sigmaS);
private: private:
QString _fileName; QString _fileName;
PointCloudOperation _operation; PointCloudOperation _operation;

View File

@ -51,240 +51,239 @@
// auto meshData = MeshData::MeshData::getInstance(); // auto meshData = MeshData::MeshData::getInstance();
namespace MainWidget { namespace MainWidget {
DialogPCLGPMesh::DialogPCLGPMesh(GUI::MainWindow* parent) DialogPCLGPMesh::DialogPCLGPMesh(GUI::MainWindow *parent)
: QFDialog(parent) : QFDialog(parent), _ui(new Ui::DialogPCLGPMesh), _mw(parent), _selectdlg(new DialogSelectComponents(parent)) {
, _ui(new Ui::DialogPCLGPMesh) _ui->setupUi(this);
, _mw(parent) _ui->geoSelectPoint->setToolTip(tr("Clicked Button Selected Components"));
, _selectdlg(new DialogSelectComponents(parent)) setWindowTitle(tr("GP Meshing"));
{ _ui->listWidget->setContextMenuPolicy(Qt::CustomContextMenu);
_ui->setupUi(this);
_ui->geoSelectPoint->setToolTip(tr("Clicked Button Selected Components"));
setWindowTitle(tr("GP Meshing"));
_ui->listWidget->setContextMenuPolicy(Qt::CustomContextMenu);
connect(_ui->geoSelectPoint, &QPushButton::clicked, [=]() { connect(_ui->geoSelectPoint, &QPushButton::clicked, [=]() {
_selectdlg->clearSelectItems(); _selectdlg->clearSelectItems();
_selectdlg->exec(); _selectdlg->exec();
}); });
connect(_selectdlg, SIGNAL(selectedComponentsSig(QList<MeshData::MeshSet*>)), this, connect(_selectdlg, SIGNAL(selectedComponentsSig(QList<MeshData::MeshSet *>)), this,
SLOT(selectedComponentsSlot(QList<MeshData::MeshSet*>))); SLOT(selectedComponentsSlot(QList<MeshData::MeshSet *>)));
connect(_ui->listWidget, SIGNAL(customContextMenuRequested(const QPoint&)), this, connect(_ui->listWidget, SIGNAL(customContextMenuRequested(const QPoint&)), this,
SLOT(customContextMenuRequestedSlot(const QPoint&))); SLOT(customContextMenuRequestedSlot(const QPoint&)));
} }
DialogPCLGPMesh::~DialogPCLGPMesh() DialogPCLGPMesh::~DialogPCLGPMesh() {
{ delete _ui;
delete _ui; _ui = NULL;
_ui = NULL; delete _selectdlg;
delete _selectdlg; _selectdlg = NULL;
_selectdlg = NULL; }
}
void DialogPCLGPMesh::accept() void DialogPCLGPMesh::accept() {
{ if (_components.size() == 0)
if(_components.size() == 0) return;
return;
QString componentIds; QString componentIds;
for(auto component : _components) for (auto component: _components)
componentIds.append(QString(",%1").arg(component->getID())); componentIds.append(QString(",%1").arg(component->getID()));
componentIds.remove(0, 1); componentIds.remove(0, 1);
double SearchRadius = _ui->SearchRadius->value(); double SearchRadius = _ui->SearchRadius->value();
double Mu = _ui->Mu->value(); double Mu = _ui->Mu->value();
int MaximumNearestNeighbors = _ui->MaximumNearestNeighbors->value(); int MaximumNearestNeighbors = _ui->MaximumNearestNeighbors->value();
double MaximumSurfaceAngle = _ui->MaximumSurfaceAngle->value(); double MaximumSurfaceAngle = _ui->MaximumSurfaceAngle->value();
double MaximumAngle = _ui->MaximumAngle->value(); double MaximumAngle = _ui->MaximumAngle->value();
double MinimumAngle = _ui->MinimumAngle->value(); double MinimumAngle = _ui->MinimumAngle->value();
QString outfilename = "filter"; QString outfilename = "filter";
for(auto component : _components) for (auto component: _components)
outfilename.append(QString("_%1").arg(component->getName())); outfilename.append(QString("_%1").arg(component->getName()));
// 确定是否保存结果文件 // 确定是否保存结果文件
QMessageBox::StandardButton result = QMessageBox::StandardButton result =
QMessageBox::critical(this, "info", "save as result ?"); QMessageBox::critical(this, "info", "save as result ?");
QString filepath = QString filepath =
JoinPath(Setting::BusAPI::instance()->getWorkingDir(), outfilename + "_tmep.pcd"); JoinPath(Setting::BusAPI::instance()->getWorkingDir(), outfilename + "_tmep.pcd");
QString AbFileName = filepath; QString AbFileName = filepath;
if(result == QMessageBox::StandardButton::Ok if (result == QMessageBox::StandardButton::Ok
|| result == QMessageBox::StandardButton::Yes) { || result == QMessageBox::StandardButton::Yes) {
DebugInfo("outfilename ok ok \n"); DebugInfo("outfilename ok ok \n");
QStringList suffixlist = IO::IOConfigure::getMeshExporters(); QStringList suffixlist = IO::IOConfigure::getMeshExporters();
if(suffixlist.isEmpty()) { if (suffixlist.isEmpty()) {
QMessageBox::warning(this, tr("Warning"), tr("The MeshPlugin is not installed !")); QMessageBox::warning(this, tr("Warning"), tr("The MeshPlugin is not installed !"));
return; return;
} }
QStringList meshsuffix = ConfigOption::ConfigOption::getInstance() QStringList meshsuffix = ConfigOption::ConfigOption::getInstance()
->getMeshConfig() ->getMeshConfig()
->getExportSuffix(ConfigOption::MeshDataType::vtkMesh) ->getExportSuffix(ConfigOption::MeshDataType::vtkMesh)
.split(";"); .split(";");
QStringList list; QStringList list;
for(QString s : meshsuffix) { for (QString s: meshsuffix) {
for(int i = 0; i < suffixlist.size(); i++) { for (int i = 0; i < suffixlist.size(); i++) {
QString suffix = suffixlist.at(i); QString suffix = suffixlist.at(i);
if(suffix.contains(s)) if (suffix.contains(s))
list.append(suffix); list.append(suffix);
} }
} }
std::sort(list.begin(), list.end()); std::sort(list.begin(), list.end());
QString suffixes = list.join(";;"); QString suffixes = list.join(";;");
QString workDir = Setting::BusAPI::instance()->getWorkingDir(); QString workDir = Setting::BusAPI::instance()->getWorkingDir();
QFileDialog dlg(this, tr("Export mesh"), workDir, suffixes); QFileDialog dlg(this, tr("Export mesh"), workDir, suffixes);
dlg.setAcceptMode(QFileDialog::AcceptSave); dlg.setAcceptMode(QFileDialog::AcceptSave);
if(dlg.exec() != QFileDialog::FileName) if (dlg.exec() != QFileDialog::FileName)
return; return;
QString aSuffix = dlg.selectedNameFilter(); QString aSuffix = dlg.selectedNameFilter();
QString aFileName = dlg.selectedFiles().join(","); QString aFileName = dlg.selectedFiles().join(",");
if(!(aFileName.isEmpty())) { if (!(aFileName.isEmpty())) {
filepath = aFileName; filepath = aFileName;
} else { } else {
} }
AbFileName = filepath; AbFileName = filepath;
} else { // 不保存成点云数据 } else { // 不保存成点云数据
} }
DebugInfo("outfilename %s \n", AbFileName.toStdString().c_str()); DebugInfo("outfilename %s \n", AbFileName.toStdString().c_str());
// 启动线程 // 启动线程
auto pclremesh = auto pclremesh =
new WBFZ::PCLGPMesh(AbFileName, WBFZ::PointCloudOperation::POINTCLOUD_MESH, _mainWindow, new WBFZ::PCLGPMesh(AbFileName, WBFZ::PointCloudOperation::POINTCLOUD_MESH, _mainWindow,
componentIds, SearchRadius, Mu, MaximumNearestNeighbors, componentIds, SearchRadius, Mu, MaximumNearestNeighbors,
MaximumSurfaceAngle, MaximumAngle, MinimumAngle); MaximumSurfaceAngle, MaximumAngle, MinimumAngle);
ModuleBase::ThreadControl* tc = new ModuleBase::ThreadControl(pclremesh); ModuleBase::ThreadControl *tc = new ModuleBase::ThreadControl(pclremesh);
emit tc->threadStart(); // emit MSHwriter->start(); emit tc->threadStart(); // emit MSHwriter->start();
DebugInfo("tc overing %s \n", AbFileName.toStdString().c_str()); DebugInfo("tc overing %s \n", AbFileName.toStdString().c_str());
QFDialog::accept(); QFDialog::accept();
DebugInfo("QFDialog::accept() \n"); DebugInfo("QFDialog::accept() \n");
} }
void DialogPCLGPMesh::selectedComponentsSlot(QList<MeshData::MeshSet*> components) void DialogPCLGPMesh::selectedComponentsSlot(QList<MeshData::MeshSet *> components) {
{ for (MeshData::MeshSet *set: components) {
for(MeshData::MeshSet* set : components) { if (_components.contains(set))
if(_components.contains(set)) continue;
continue; _components.append(set);
_components.append(set); _ui->listWidget->addItem(set->getName());
_ui->listWidget->addItem(set->getName()); }
} }
}
void DialogPCLGPMesh::customContextMenuRequestedSlot(const QPoint& point) void DialogPCLGPMesh::customContextMenuRequestedSlot(const QPoint &point) {
{ QListWidgetItem *curItem = _ui->listWidget->itemAt(point);
QListWidgetItem* curItem = _ui->listWidget->itemAt(point); if (!curItem)
if(!curItem) return;
return;
QMenu* menu = new QMenu(this); QMenu *menu = new QMenu(this);
QAction* deleteItem = new QAction(tr("delete this item")); QAction *deleteItem = new QAction(tr("delete this item"));
menu->addAction(deleteItem); menu->addAction(deleteItem);
connect(menu, &QMenu::triggered, [=]() { removeCurrentItem(curItem); }); connect(menu, &QMenu::triggered, [=]() { removeCurrentItem(curItem); });
menu->exec(QCursor::pos()); menu->exec(QCursor::pos());
} }
void DialogPCLGPMesh::removeCurrentItem(QListWidgetItem* curItem) void DialogPCLGPMesh::removeCurrentItem(QListWidgetItem *curItem) {
{ auto meshData = MeshData::MeshData::getInstance();
auto meshData = MeshData::MeshData::getInstance(); auto meshSet = meshData->getMeshSetByName(curItem->text());
auto meshSet = meshData->getMeshSetByName(curItem->text()); if (!meshSet)
if(!meshSet) return;
return; _components.removeOne(meshSet);
_components.removeOne(meshSet); _ui->listWidget->removeItemWidget(curItem);
_ui->listWidget->removeItemWidget(curItem); delete curItem;
delete curItem; }
}
} // namespace MainWidget } // namespace MainWidget
namespace WBFZ { namespace WBFZ {
PCLGPMesh::PCLGPMesh(const QString& fileName, WBFZ::PointCloudOperation operation, PCLGPMesh::PCLGPMesh(const QString &fileName, WBFZ::PointCloudOperation operation,
GUI::MainWindow* mw, QString componentIds, double SearchRadius, double Mu, GUI::MainWindow *mw, QString componentIds, double SearchRadius, double Mu,
int MaximumNearestNeighbors, double MaximumSurfaceAngle, int MaximumNearestNeighbors, double MaximumSurfaceAngle,
double MaximumAngle, double MinimumAngle) double MaximumAngle, double MinimumAngle)
: ModuleBase::ThreadTask(mw) : ModuleBase::ThreadTask(mw), _operation(operation), _fileName(fileName), _componentIds(componentIds), _SearchRadius(SearchRadius), _Mu(Mu), _MaximumNearestNeighbors(MaximumNearestNeighbors), _MaximumSurfaceAngle(MaximumSurfaceAngle), _MaximumAngle(MaximumAngle), _MinimumAngle(MinimumAngle) {
, _operation(operation) }
, _fileName(fileName)
, _componentIds(componentIds)
, _SearchRadius(SearchRadius)
, _Mu(Mu)
, _MaximumNearestNeighbors(MaximumNearestNeighbors)
, _MaximumSurfaceAngle(MaximumSurfaceAngle)
, _MaximumAngle(MaximumAngle)
, _MinimumAngle(MinimumAngle)
{
}
PCLGPMesh::~PCLGPMesh() {} PCLGPMesh::~PCLGPMesh() {}
void PCLGPMesh::defaultMeshFinished() void PCLGPMesh::defaultMeshFinished() {
{ ModuleBase::ThreadTask::threadTaskFinished();
if(_threadRuning) {
QString information{};
ModuleBase::Message msg;
if(_operation == POINTCLOUD_FILTER || _operation == POINTCLOUD_MESH) {
if(_success) {
// emit _mainwindow->updateMeshTreeSig();
// emit _mainwindow->updateSetTreeSig();
// emit _mainwindow->updateActionStatesSig();
// emit _mainwindow->updateActionsStatesSig();
// emit _mainwindow->getSubWindowManager()->openPreWindowSig();
// emit _mainwindow->updatePreMeshActorSig();
information = QString("Successful Import Mesh From \"%1\"").arg(_fileName);
msg.type = Common::Message::Normal;
msg.message = information;
qDebug()<<"Successful Import Mesh From "<<_fileName;
// auto meshdata = MeshData::MeshData::getInstance();
// // meshdata->generateDisplayDataSet();
// const int nk = meshdata->getKernalCount();
// if(nk <= 0)
// return;
// auto k = meshdata->getKernalAt(nk - 1);
// if(k != nullptr)
// k->setPath(_fileName);
} else {
information = QString("Failed Filter From \"%1\"").arg(_fileName);
msg.type = Common::Message::Error;
msg.message = information;
qDebug()<<"Failed Import Mesh From "<<_fileName;
}
} else {
}
emit showInformation(information);
emit _mainwindow->printMessageToMessageWindow(msg);
}
// ModuleBase::ThreadTask::threadTaskFinished();
this->threadTaskFinished();
Py::PythonAgent::getInstance()->unLock(); Py::PythonAgent::getInstance()->unLock();
} if (_threadRuning) {
void PCLGPMesh::setThreadRunState(bool flag) QString information{};
{ ModuleBase::Message msg;
_success = flag; if (_operation == POINTCLOUD_FILTER || _operation == POINTCLOUD_MESH) {
} if (_success) {
// emit _mainwindow->updateMeshTreeSig();
// emit _mainwindow->updateSetTreeSig();
// emit _mainwindow->updateActionStatesSig();
// emit _mainwindow->updateActionsStatesSig();
// emit _mainwindow->getSubWindowManager()->openPreWindowSig();
// emit _mainwindow->updatePreMeshActorSig();
information = QString("Successful resurface Mesh From \"%1\"").arg(_fileName);
msg.type = Common::Message::Normal;
msg.message = information;
qDebug() << "Successful Import Mesh From " << _fileName;
void PCLGPMesh::run() QFileInfo info(_fileName);
{ QString name = info.fileName();
ModuleBase::ThreadTask::run(); QString path = info.filePath();
bool result = false; QString suffix = info.suffix().toLower();
switch(_operation) {
case POINTCLOUD_MESH:
emit showInformation(tr("POINTCLOUD_MESH From \"%1\"").arg(_fileName));
result = remeshtaskProcess();
setThreadRunState(result);
break;
default:
break;
}
DebugInfo("run ok _success %d _threadRuning %d \n", _success, _threadRuning);
defaultMeshFinished();
}
bool PCLGPMesh::remeshtaskProcess() if(info.exists()){
{
QString componentIds = _componentIds; if(suffix.toLower().contains("stl")){
suffix="STL(*.stl)";
emit _mainwindow->importMeshSIGN(_fileName,suffix,-1);
}else if(suffix.toLower().contains("vtk")){
suffix="VTK(*.vtk)";
emit _mainwindow->importMeshSIGN(_fileName,suffix,-1);
}else if(suffix.toLower().contains("neu")){
suffix="Gambit(*.neu)";
emit _mainwindow->importMeshSIGN(_fileName,suffix,-1);
}else{
information = QString("Failed Filter From \"%1\"").arg(_fileName);
msg.type = Common::Message::Error;
msg.message = information;
qDebug() << "Failed Import Mesh From " << _fileName;
}
}
} else {
information = QString("Failed resurface From \"%1\"").arg(_fileName);
msg.type = Common::Message::Error;
msg.message = information;
qDebug() << "Failed resurface Mesh From " << _fileName;
}
} else {
}
emit showInformation(information);
emit _mainwindow->printMessageToMessageWindow(msg);
}
qDebug()<<"PCLGPMesh::defaultMeshFinished ModuleBase::ThreadTask::threadTaskFinished";
// Py::PythonAgent::getInstance()->unLock();
}
void PCLGPMesh::setThreadRunState(bool flag) {
_success = flag;
}
void PCLGPMesh::run() {
ModuleBase::ThreadTask::run();
bool result = false;
switch (_operation) {
case POINTCLOUD_MESH:
emit showInformation(tr("POINTCLOUD_MESH From \"%1\"").arg(_fileName));
result = remeshtaskProcess();
setThreadRunState(result);
break;
default:
break;
}
DebugInfo("run ok _success %d _threadRuning %d \n", _success, _threadRuning);
defaultMeshFinished();
}
bool PCLGPMesh::GP(vtkSmartPointer<vtkPolyData>& inpolygon,vtkSmartPointer<vtkPolyData>& polydata) { // 点云处理模块
// 可用变量
double SearchRadius = _SearchRadius; double SearchRadius = _SearchRadius;
double Mu = _Mu; double Mu = _Mu;
int MaximumNearestNeighbors = _MaximumNearestNeighbors; int MaximumNearestNeighbors = _MaximumNearestNeighbors;
@ -292,156 +291,153 @@ namespace WBFZ {
double MaximumAngle = _MaximumAngle; double MaximumAngle = _MaximumAngle;
double MinimumAngle = _MinimumAngle; double MinimumAngle = _MinimumAngle;
emit _mainwindow->printMessage(Common::Message::Normal, "PCLGPMeshAlg");
// 获取vtdataset pcl::PointCloud<pcl::PointXYZRGBA>::Ptr cloud_with_rgba(new pcl::PointCloud<pcl::PointXYZRGBA>);
pcl::PointCloud<pcl::PointXYZRGBA>::Ptr cloud_filtered( new pcl::PointCloud<pcl::PointXYZRGBA>);
pcl::PointCloud<pcl::PointXYZRGBA>::Ptr output( new pcl::PointCloud<pcl::PointXYZRGBA>); // 输出结果
pcl::PointCloud<pcl::PointNormal>::Ptr cloud_with_normals(new pcl::PointCloud<pcl::PointNormal>); // 法线向量
pcl::search::KdTree<pcl::PointNormal>::Ptr tree2(new pcl::search::KdTree<pcl::PointNormal>);
pcl::io::vtkPolyDataToPointCloud(inpolygon, *cloud_with_rgba);
PointCloudOperator::PointCloudCommon::NormalEstimation(cloud_with_rgba, cloud_with_normals);
tree2->setInputCloud(cloud_with_normals); // 构建搜索树
std::shared_ptr<pcl::PolygonMesh> mesh (new pcl::PolygonMesh); // 非智能指针,需要释放
pcl::GreedyProjectionTriangulation<pcl::PointNormal> gp3; // 定义三角化对象
gp3.setSearchRadius(SearchRadius); // 设置连接点之间的最大距离(即三角形的最大边长)
gp3.setMu(Mu); // 设置被样本点搜索其临近点的最远距离,为了适应点云密度的变化
gp3.setMaximumNearestNeighbors(MaximumNearestNeighbors); // 设置样本点可搜索的邻域个数
gp3.setMaximumSurfaceAngle(MaximumSurfaceAngle); // 设置某点法线方向偏离样本点法线方向的最大角度
gp3.setMinimumAngle(MinimumAngle); // 设置三角化后得到三角形内角的最小角度
gp3.setMaximumAngle(MaximumAngle); // 设置三角化后得到三角形内角的最大角度
gp3.setNormalConsistency(false); // 设置该参数保证法线朝向一致
gp3.setInputCloud(cloud_with_normals); // 设置输入点云为有向点云
gp3.setSearchMethod(tree2); // 设置搜索方式
gp3.reconstruct(*mesh); // 重建提取三角化 -- 这里会导致程序崩溃,可能存在内存泄露,
// DebugInfo("remesh over GP \n");
// return false;
size_t pointcount = PointCloudOperator::PointCloudCommon::mesh2vtk(*mesh, polydata);
DebugInfo("remesh over ,conver init %d \n", mesh->polygons.size());
//delete mesh;
return true;
}
bool PCLGPMesh::remeshtaskProcess() {
QString componentIds = _componentIds;
emit _mainwindow->printMessage(Common::Message::Normal, "PCLGPMeshAlg");
// 获取vtdataset
QStringList qCompontIds = QString(componentIds).split(','); QStringList qCompontIds = QString(componentIds).split(',');
MeshData::MeshSet* meshSet = NULL; MeshData::MeshSet* meshSet = NULL;
MeshData::MeshKernal* meshKernal = NULL; MeshData::MeshKernal* meshKernal = NULL;
MeshData::MeshData* meshData = MeshData::MeshData::getInstance(); MeshData::MeshData* meshData = MeshData::MeshData::getInstance();
QString kernalName, transformedName, setType, ids; QString kernalName, transformedName, setType, ids;
// 筛选其中的点云数据
// 创建 vtkCellDataToPointData 过滤器 // 创建 vtkCellDataToPointData 过滤器
vtkSmartPointer<vtkGeometryFilter> cellToPointFilter = vtkSmartPointer<vtkGeometryFilter> cellToPointFilter = vtkSmartPointer<vtkGeometryFilter>::New();
vtkSmartPointer<vtkGeometryFilter>::New(); vtkSmartPointer<vtkPolyData> inpolyData=vtkSmartPointer<vtkPolyData>::New();
vtkSmartPointer<vtkPolyData> polydata = vtkSmartPointer<vtkPolyData>::New();
QString outfilename; for (QString compontId: qCompontIds) {
for(QString compontId : qCompontIds) { meshSet = meshData->getMeshSetByID(compontId.toInt());
meshSet = meshData->getMeshSetByID(compontId.toInt()); DebugInfo("point count %d : %d \n", compontId.toInt(), meshSet == nullptr);
DebugInfo("point count %d : %d \n", compontId.toInt(), meshSet == nullptr); if (!meshSet)
if(!meshSet) continue;
continue; QString outfilename = meshSet->getName();
outfilename = meshSet->getName(); cellToPointFilter->SetInputData(PointCloudOperator::PointCloudCommon::meshSetToVtkDataset(meshSet));
vtkPolyData* temppolyData = DebugInfo("point count %d \n", compontId.toInt());
PointCloudOperator::PointCloudCommon::meshSetToVtkDataset(meshSet); }
cellToPointFilter->SetInputData(temppolyData);
DebugInfo("point count %d : %d \n", compontId.toInt(), temppolyData == nullptr);
}
// 执行过滤操作 // 执行过滤操作
cellToPointFilter->Update(); cellToPointFilter->Update();
DebugInfo("cellToPointFilter \n"); DebugInfo("cellToPointFilter \n");
// 获取过滤后的 vtkPolyData // 获取过滤后的 vtkPolyData
vtkPolyData* outpolyData = cellToPointFilter->GetOutput(); inpolyData = cellToPointFilter->GetOutput();
DebugInfo("outpolyData "); if(this->GP(inpolyData,polydata)){
pcl::PointCloud<pcl::PointXYZRGBA>::Ptr cloud_with_rgba(
new pcl::PointCloud<pcl::PointXYZRGBA>);
pcl::PointCloud<pcl::PointXYZRGBA>::Ptr cloud_filtered(
new pcl::PointCloud<pcl::PointXYZRGBA>);
pcl::io::vtkPolyDataToPointCloud(outpolyData, *cloud_with_rgba);
// 创建滤波器对象
// 计算点云滤波结果
pcl::PointCloud<pcl::PointXYZRGBA>::Ptr output(
new pcl::PointCloud<pcl::PointXYZRGBA>); // 输出结果
pcl::PointCloud<pcl::PointNormal>::Ptr cloud_with_normals(
new pcl::PointCloud<pcl::PointNormal>);
pcl::PolygonMesh* mesh = new pcl::PolygonMesh;
// 估计法线
PointCloudOperator::PointCloudCommon::NormalEstimation(cloud_with_rgba, cloud_with_normals);
//------------------定义搜索树对象------------------------
pcl::search::KdTree<pcl::PointNormal>::Ptr tree2(new pcl::search::KdTree<pcl::PointNormal>);
tree2->setInputCloud(cloud_with_normals);
pcl::GreedyProjectionTriangulation<pcl::PointNormal> gp3; // 定义三角化对象
gp3.setSearchRadius(SearchRadius); // 设置连接点之间的最大距离(即三角形的最大边长)
gp3.setMu(Mu); // 设置被样本点搜索其临近点的最远距离,为了适应点云密度的变化
gp3.setMaximumNearestNeighbors(MaximumNearestNeighbors); // 设置样本点可搜索的邻域个数
gp3.setMaximumSurfaceAngle(
MaximumSurfaceAngle); // 设置某点法线方向偏离样本点法线方向的最大角度
gp3.setMinimumAngle(MinimumAngle); // 设置三角化后得到三角形内角的最小角度
gp3.setMaximumAngle(MaximumAngle); // 设置三角化后得到三角形内角的最大角度
gp3.setNormalConsistency(false); // 设置该参数保证法线朝向一致
// qDebug() << "[GP] start reconstruct :" << cloud_in->points.size();
// Get result
DebugInfo("setInputCloud point count : %d \n", cloud_with_normals->size());
gp3.setInputCloud(cloud_with_normals); // 设置输入点云为有向点云
gp3.setSearchMethod(tree2); // 设置搜索方式
gp3.reconstruct(*mesh); // 重建提取三角化
emit _mainwindow->printMessageToMessageWindow(
QString("edge count %1 ").arg(QString::number(mesh->polygons.size())));
DebugInfo("remesh over ,conver init %d \n", mesh->polygons.size());
// 转换处理结果
vtkSmartPointer<vtkPolyData> polydata= vtkSmartPointer<vtkPolyData>::New();
// vtkPolyData* polydata = vtkPolyData::New(); // 创建新的指针,智能指针会释放
size_t pointcount = PointCloudOperator::PointCloudCommon::mesh2vtk(*mesh, polydata);
DebugInfo("remesh over ,conver over polydata %d , pointcount %d\n", polydata == nullptr, pointcount);
vtkSmartPointer<vtkDataSet> dataset=vtkDataSet::SafeDownCast(polydata);
// dataset =vtkDataSet::SafeDownCast(polydata); // 默认完成 vtkpolydata --> vtkdataset
// outpolyData->Delete(); // 释放指针 ,
// 千万不能释放这个指针,不然程序回调时,会直接内存崩溃
DebugInfo("PCLGPMeshAlg successfully!! wait for writing file \n");
// vtkDataSet*
// dataset=PCLGPMeshAlg(_componentIds,_SearchRadius,_Mu,_MaximumNearestNeighbors,_MaximumSurfaceAngle,_MaximumAngle,_MinimumAngle);
DebugInfo("remesh \n");
QString filepath = _fileName;
QFile outfile_presave(_fileName);
if(outfile_presave.exists()){ // 如果存在文件,就删除
outfile_presave.remove();
}
// 加载文件
QFileInfo info(filepath);
QString name = info.fileName();
QString path = info.filePath();
QString suffix = info.suffix().toLower();
QTextCodec* codec = QTextCodec::codecForName("GB18030");
QByteArray ba = codec->fromUnicode(filepath);
std::string outFileName = ba.data();
DebugInfo("writing %s suffix %s !! \n", ba.data(), suffix.toStdString().c_str());
if(suffix == "vtk") {
vtkSmartPointer<vtkUnstructuredGridWriter> writer =
vtkSmartPointer<vtkUnstructuredGridWriter>::New();
writer->SetInputData(dataset);
writer->SetFileTypeToBinary();
writer->SetFileName(ba);
writer->Write();
DebugInfo("writing vtk !! \n");
} else if(suffix == "stl") {
QTextCodec* codec = QTextCodec::codecForName("GB18030");
QByteArray ba = codec->fromUnicode(_fileName);
vtkSmartPointer<vtkSTLWriter> writer = vtkSmartPointer<vtkSTLWriter>::New();
writer->SetInputData(dataset);
writer->SetFileTypeToBinary();
writer->SetFileName(ba);
writer->Write();
DebugInfo("writing stl !! \n");
} else {
}
DebugInfo("writing finish !! %d \n", dataset == nullptr);
// 回调函数
DebugInfo("remeshtaskProcess !! %d \n", dataset == nullptr);
// QFileInfo info(_fileName);
// QString name = info.fileName();
// QString path = info.filePath();
// QString suffix = info.suffix().toLower();
DebugInfo("dataset %d _fileName %s \n", dataset == nullptr, _fileName.toStdString().c_str());
if(nullptr==dataset){
}else{ }else{
dataset=nullptr;
}
QFile outfile(_fileName);
if(outfile.exists()){
DebugInfo("GP main process sucessfully !! \n");
return true;
}else{
DebugInfo("GP main process fail !! \n");
return false; return false;
} }
DebugInfo("GP main process fail !! \n");
return false; DebugInfo("outpolyData ");
} //vtkDataSet* dataset = vtkDataSet::SafeDownCast(polydata); // dataset =vtkDataSet::SafeDownCast(polydata); // 默认完成 vtkpolydata --> vtkdataset
// outpolyData->Delete(); // 释放指针 ,
// 千万不能释放这个指针,不然程序回调时,会直接内存崩溃
DebugInfo("PCLGPMeshAlg successfully!! wait for writing file dataset : %d \n",nullptr==polydata);
// vtkDataSet*
// dataset=PCLGPMeshAlg(_componentIds,_SearchRadius,_Mu,_MaximumNearestNeighbors,_MaximumSurfaceAngle,_MaximumAngle,_MinimumAngle);
if(nullptr!=polydata){
DebugInfo("PCLGPMeshAlg successfully!! wait for writing file dataset : %d %d\n",polydata->GetNumberOfPoints(),polydata->GetNumberOfCells());
}
QString filepath = _fileName;
QFile outfile_presave(_fileName);
if (outfile_presave.exists()) { // 如果存在文件,就删除
outfile_presave.remove();
}
// 手动释放所有的变量
//return false;
{ // 写出到文件中
// 加载文件
QFileInfo info(filepath);
QString name = info.fileName();
QString path = info.filePath();
QString suffix = info.suffix().toLower();
QTextCodec* codec = QTextCodec::codecForName("GB18030");
QByteArray ba = codec->fromUnicode(filepath);
std::string outFileName = ba.data();
DebugInfo("writing %s suffix %s !! \n", ba.data(), suffix.toStdString().c_str());
if(suffix == "vtk") {
vtkSmartPointer<vtkUnstructuredGridWriter> writer =
vtkSmartPointer<vtkUnstructuredGridWriter>::New();
writer->SetInputData(polydata);
writer->SetFileTypeToBinary();
writer->SetFileName(ba);
writer->Write();
DebugInfo("writing vtk !! \n");
} else if(suffix == "stl") {
QTextCodec* codec = QTextCodec::codecForName("GB18030");
QByteArray ba = codec->fromUnicode(_fileName);
vtkSmartPointer<vtkSTLWriter> writer = vtkSmartPointer<vtkSTLWriter>::New();
writer->SetInputData(polydata);
writer->SetFileTypeToBinary();
writer->SetFileName(ba);
writer->Write();
DebugInfo("writing stl !! \n");
} else {
}
}
// QFileInfo info(_fileName);
// QString name = info.fileName();
// QString path = info.filePath();
// QString suffix = info.suffix().toLower();
DebugInfo("dataset %d _fileName %s \n", nullptr==polydata, _fileName.toStdString().c_str());
if (nullptr == polydata) { } else {
DebugInfo("GP variable start release !! \n");
//dataset->Delete();
//dataset=nullptr;
DebugInfo("GP variable finish release!! \n");
}
QFile outfile(_fileName);
if (outfile.exists()) {
DebugInfo("GP main process sucessfully !! \n");
return true;
} else {
DebugInfo("GP main process fail !! \n");
return false;
}
DebugInfo("GP main process fail !! \n");
return false;
}
} // namespace WBFZ } // namespace WBFZ

View File

@ -10,6 +10,7 @@
#ifndef LAMPCAE_DIALOGPCLGPMESH_H #ifndef LAMPCAE_DIALOGPCLGPMESH_H
#define LAMPCAE_DIALOGPCLGPMESH_H #define LAMPCAE_DIALOGPCLGPMESH_H
#include <vtkPolyData.h>
#include "WBFZExchangePluginAPI.h" #include "WBFZExchangePluginAPI.h"
#include "SelfDefObject/QFDialog.h" #include "SelfDefObject/QFDialog.h"
#include "MainWidgets/DialogVTKTransform.h" #include "MainWidgets/DialogVTKTransform.h"
@ -51,6 +52,7 @@ namespace WBFZ{
void defaultMeshFinished(); void defaultMeshFinished();
void setThreadRunState(bool); void setThreadRunState(bool);
bool remeshtaskProcess(); bool remeshtaskProcess();
bool GP(vtkSmartPointer<vtkPolyData>& inpolygon,vtkSmartPointer<vtkPolyData>& polydata);
// vtkDataSet* remesh() ; // vtkDataSet* remesh() ;
// vtkDataSet* PCLGPMeshAlg(QString componentIds , double SearchRadius, double Mu,int MaximumNearestNeighbors,double MaximumSurfaceAngle,double MaximumAngle,double MinimumAngle); // vtkDataSet* PCLGPMeshAlg(QString componentIds , double SearchRadius, double Mu,int MaximumNearestNeighbors,double MaximumSurfaceAngle,double MaximumAngle,double MinimumAngle);
private: private:

View File

@ -204,11 +204,11 @@ WBFZ::PCLGuassFilter::PCLGuassFilter(const QString& fileName, WBFZ::PointCloudOp
, _radius(radius) , _radius(radius)
{ {
} }
vtkDataSet* WBFZ::PCLGuassFilter::filter() bool WBFZ::PCLGuassFilter::filter()
{ {
return PointCloudThreadBase::filter(); return PointCloudThreadBase::filter();
} }
vtkDataSet* WBFZ::PCLGuassFilter::PCLGuassFilterAlg(QString componentIds, double sigma, bool WBFZ::PCLGuassFilter::PCLGuassFilterAlg(QString componentIds, double sigma,
double threshold,double radius) double threshold,double radius)
{ {
emit _mainwindow->printMessage(Common::Message::Normal,"PCLGuassFilterAlg"); emit _mainwindow->printMessage(Common::Message::Normal,"PCLGuassFilterAlg");
@ -290,32 +290,12 @@ vtkDataSet* WBFZ::PCLGuassFilter::PCLGuassFilterAlg(QString componentIds, double
vtkDataSet* dataset= vtkDataSet::SafeDownCast(polydata); // 默认完成 vtkpolydata --> vtkdataset vtkDataSet* dataset= vtkDataSet::SafeDownCast(polydata); // 默认完成 vtkpolydata --> vtkdataset
size_t pointCount = dataset->GetNumberOfPoints(); size_t pointCount = dataset->GetNumberOfPoints();
if(pointCount==0){ if(pointCount==0){
return nullptr; return false;
} }
emit _mainwindow->printMessage(Common::Message::Normal,"PCLGuassFilterAlg successfully!! Point Count : "+QString::number(pointCount)); emit _mainwindow->printMessage(Common::Message::Normal,"PCLGuassFilterAlg successfully!! Point Count : "+QString::number(pointCount));
outpolyData->Delete(); // 释放指针 outpolyData->Delete(); // 释放指针
QString filepath=_fileName; return this->saveFilterResultFile(cloud_filtered);
// 加载文件
QFileInfo info(filepath);
QString name = info.fileName();
QString path = info.filePath();
QString suffix = info.suffix().toLower();
QTextCodec *codec = QTextCodec::codecForName("GB18030");
QByteArray ba = codec->fromUnicode(filepath);
std::string outFileName=ba.data();
if (suffix == "pcd")
{
pcl::io::savePCDFileBinary(outFileName,*cloud_filtered);
}
else if (suffix == "ply")
{
pcl::io::savePLYFileBinary(outFileName,*cloud_filtered);
}
else{}
return dataset;
} }
WBFZ::PCLGuassFilter::~PCLGuassFilter() {} WBFZ::PCLGuassFilter::~PCLGuassFilter() {}

View File

@ -39,8 +39,8 @@ namespace WBFZ{
PCLGuassFilter(const QString &fileName, PointCloudOperation operation, GUI::MainWindow *mw, QString componentIds, double sigma,double threshold,double radius); PCLGuassFilter(const QString &fileName, PointCloudOperation operation, GUI::MainWindow *mw, QString componentIds, double sigma,double threshold,double radius);
~PCLGuassFilter(); ~PCLGuassFilter();
private: private:
vtkDataSet* filter() override; bool filter() override;
vtkDataSet* PCLGuassFilterAlg(QString componentIds,double sigmaR,double sigmaS,double radius); bool PCLGuassFilterAlg(QString componentIds,double sigmaR,double sigmaS,double radius);
private: private:
QString _fileName; QString _fileName;
PointCloudOperation _operation; PointCloudOperation _operation;

View File

@ -203,7 +203,7 @@ namespace WBFZ{
} }
vtkDataSet* WBFZ::PCLRadiusOutlierRemoval::PCLRadiusOutlierRemovalAlg(QString componentIds, double RadiusSearch, bool WBFZ::PCLRadiusOutlierRemoval::PCLRadiusOutlierRemovalAlg(QString componentIds, double RadiusSearch,
double MinNeighborsInRadius) double MinNeighborsInRadius)
{ {
emit _mainwindow->printMessage(Common::Message::Normal,"PCLRadiusOutlierRemovalAlg"); emit _mainwindow->printMessage(Common::Message::Normal,"PCLRadiusOutlierRemovalAlg");
@ -259,35 +259,14 @@ namespace WBFZ{
vtkDataSet* dataset= vtkDataSet::SafeDownCast(polydata); // 默认完成 vtkpolydata --> vtkdataset vtkDataSet* dataset= vtkDataSet::SafeDownCast(polydata); // 默认完成 vtkpolydata --> vtkdataset
size_t pointCount = dataset->GetNumberOfPoints(); size_t pointCount = dataset->GetNumberOfPoints();
if(pointCount==0){ if(pointCount==0){
return nullptr; return false;
} }
emit _mainwindow->printMessage(Common::Message::Normal,"PCLRadiusOutlierRemovalAlg successfully!! Point Count : "+QString::number(pointCount)); emit _mainwindow->printMessage(Common::Message::Normal,"PCLRadiusOutlierRemovalAlg successfully!! Point Count : "+QString::number(pointCount));
outpolyData->Delete(); // 释放指针 outpolyData->Delete(); // 释放指针
return this->saveFilterResultFile(cloud_filtered);
QString filepath=_fileName;
// 加载文件
QFileInfo info(filepath);
QString name = info.fileName();
QString path = info.filePath();
QString suffix = info.suffix().toLower();
QTextCodec *codec = QTextCodec::codecForName("GB18030");
QByteArray ba = codec->fromUnicode(filepath);
std::string outFileName=ba.data();
if (suffix == "pcd")
{
pcl::io::savePCDFileBinary(outFileName,*cloud_filtered);
}
else if (suffix == "ply")
{
pcl::io::savePLYFileBinary(outFileName,*cloud_filtered);
}
else{}
return dataset;
} }
vtkDataSet* PCLRadiusOutlierRemoval::filter() bool PCLRadiusOutlierRemoval::filter()
{ {
return PCLRadiusOutlierRemovalAlg( _componentIds, _RadiusSearch,_MinNeighborsInRadius); return PCLRadiusOutlierRemovalAlg( _componentIds, _RadiusSearch,_MinNeighborsInRadius);
} }

View File

@ -38,8 +38,8 @@ namespace WBFZ{
PCLRadiusOutlierRemoval(const QString &fileName, PointCloudOperation operation, GUI::MainWindow *mw, QString componentIds, double RadiusSearch,double MinNeighborsInRadius); PCLRadiusOutlierRemoval(const QString &fileName, PointCloudOperation operation, GUI::MainWindow *mw, QString componentIds, double RadiusSearch,double MinNeighborsInRadius);
~PCLRadiusOutlierRemoval(); ~PCLRadiusOutlierRemoval();
private: private:
vtkDataSet* filter() override; bool filter() override;
vtkDataSet* PCLRadiusOutlierRemovalAlg(QString componentIds,double RadiusSearch,double MinNeighborsInRadius); bool PCLRadiusOutlierRemovalAlg(QString componentIds,double RadiusSearch,double MinNeighborsInRadius);
private: private:
QString _fileName; QString _fileName;
PointCloudOperation _operation; PointCloudOperation _operation;

View File

@ -207,7 +207,7 @@ namespace WBFZ{
} }
vtkDataSet* WBFZ::PCLStatisticalRemoveFilter::PCLStatisticalRemoveFilterAlg(QString componentIds, double MeanK, bool WBFZ::PCLStatisticalRemoveFilter::PCLStatisticalRemoveFilterAlg(QString componentIds, double MeanK,
double StddevThresh) double StddevThresh)
{ {
emit _mainwindow->printMessage(Common::Message::Normal,"PCLStatisticalRemoveFilterAlg"); emit _mainwindow->printMessage(Common::Message::Normal,"PCLStatisticalRemoveFilterAlg");
@ -260,35 +260,15 @@ namespace WBFZ{
vtkDataSet* dataset= vtkDataSet::SafeDownCast(polydata); // 默认完成 vtkpolydata --> vtkdataset vtkDataSet* dataset= vtkDataSet::SafeDownCast(polydata); // 默认完成 vtkpolydata --> vtkdataset
size_t pointCount = dataset->GetNumberOfPoints(); size_t pointCount = dataset->GetNumberOfPoints();
if(pointCount==0){ if(pointCount==0){
return nullptr; return false;
} }
emit _mainwindow->printMessage(Common::Message::Normal,"PCLStatisticalRemoveFilterAlg successfully!! Point Count : "+QString::number(pointCount)); emit _mainwindow->printMessage(Common::Message::Normal,"PCLStatisticalRemoveFilterAlg successfully!! Point Count : "+QString::number(pointCount));
outpolyData->Delete(); // 释放指针 outpolyData->Delete(); // 释放指针
QString filepath=_fileName; return this->saveFilterResultFile(cloud_filtered);
// 加载文件
QFileInfo info(filepath);
QString name = info.fileName();
QString path = info.filePath();
QString suffix = info.suffix().toLower();
QTextCodec *codec = QTextCodec::codecForName("GB18030");
QByteArray ba = codec->fromUnicode(filepath);
std::string outFileName=ba.data();
if (suffix == "pcd")
{
pcl::io::savePCDFileBinary(outFileName,*cloud_filtered);
}
else if (suffix == "ply")
{
pcl::io::savePLYFileBinary(outFileName,*cloud_filtered);
}
else{}
return dataset;
} }
vtkDataSet* PCLStatisticalRemoveFilter::filter() bool PCLStatisticalRemoveFilter::filter()
{ {
return PCLStatisticalRemoveFilterAlg( _componentIds, _MeanK,_StddevThresh); return PCLStatisticalRemoveFilterAlg( _componentIds, _MeanK,_StddevThresh);
} }

View File

@ -37,8 +37,8 @@ namespace WBFZ{
PCLStatisticalRemoveFilter(const QString &fileName, PointCloudOperation operation, GUI::MainWindow *mw, QString componentIds, double MeanK,double StddevThresh); PCLStatisticalRemoveFilter(const QString &fileName, PointCloudOperation operation, GUI::MainWindow *mw, QString componentIds, double MeanK,double StddevThresh);
~PCLStatisticalRemoveFilter(); ~PCLStatisticalRemoveFilter();
private: private:
vtkDataSet* filter() override; bool filter() override;
vtkDataSet* PCLStatisticalRemoveFilterAlg(QString componentIds,double MeanK,double stddev); bool PCLStatisticalRemoveFilterAlg(QString componentIds,double MeanK,double stddev);
private: private:
QString _fileName; QString _fileName;
PointCloudOperation _operation; PointCloudOperation _operation;

View File

@ -258,58 +258,126 @@ void EchoTableEditWindow::on_actionEchoSplitExport_triggered()
this->ui->statusbar->showMessage(u8"正在分析回波文件"); this->ui->statusbar->showMessage(u8"正在分析回波文件");
this->statusprogressBar->setRange(0,100); this->statusprogressBar->setRange(0,100);
this->statusprogressBar->setValue(10); this->statusprogressBar->setValue(10);
FEKOBase::NearFieldEchoCSVParser nearfilePraseclass;
QString echocsvfilepath = this->model->getCSVPath(); // 检查是否远场回波
if (!nearfilePraseclass.parseCSV(echocsvfilepath)) { bool isfar=false;
bool isnear=false;
//this->model;
//判断指针
std::shared_ptr<FEKOResultCsvTableModel> echoTableModel(new FEKOResultCsvTableModel);
echoTableModel->loadCSVFilePath(this->model->getCSVPath());
if(echoTableModel->rowCount()<=0||echoTableModel->colCount()<=0){
QMessageBox::warning(this, u8"警告", u8"回波文件结构解析错误,请检查文件"); QMessageBox::warning(this, u8"警告", u8"回波文件结构解析错误,请检查文件");
return; return ;
}else{}
if(echoTableModel){
QStringList colnames=echoTableModel->getColumnNames();
for(size_t i=0;i<colnames.count();i++){
if(colnames[i].toLower().contains("file type")||colnames[i]=="File Type"){
size_t colidx=echoTableModel->getColumnIdxByColumName(colnames[i]);
QString filetypeStr=echoTableModel->itemText(0,colidx);
if(filetypeStr.toLower().contains("far field")||filetypeStr.contains("Far Field")||filetypeStr=="Far Field"){
isfar=true;
}else{}
if(filetypeStr.toLower().contains("near field")||filetypeStr=="Electric near field"){
isnear= true;
}else{}
}
}
}else{
QMessageBox::warning(this, u8"警告", u8"回波文件结构解析错误,请检查文件");
return ;
} }
this->statusprogressBar->setValue(25); // ---------------------- 远场结果 --------------------------------------------------
QMessageBox::information(this, u8"信息", u8"请分别为theta极化、phi极化、R极化分量回波指定保存路径"); if(isfar){
FEKOBase::FarFieldEchoCSVParser farfilePraseclass;
QString echocsvfilepath = this->model->getCSVPath();
if(!farfilePraseclass.parseCSV(echocsvfilepath)) {
QMessageBox::warning(this, u8"警告", u8"回波文件结构解析错误,请检查文件");
return;
}
this->statusprogressBar->setValue(25);
QMessageBox::information(this, u8"信息",
u8"请分别为theta极化、phi极化、R极化分量回波指定保存路径");
QString thetafilepath = getSaveFilePath( QString thetafilepath = getSaveFilePath(
this, this, QString::fromUtf8(u8"另存为"),
QString::fromUtf8(u8"另存为"), QString::fromUtf8(u8"theta文件 (*.theta)")); // 多组扩展名用双分号";;"隔开
QString::fromUtf8(u8"theta文件 (*.theta)"));//多组扩展名用双分号";;"隔开
QString phifilepath = getSaveFilePath(
this,
QString::fromUtf8(u8"另存为"),
QString::fromUtf8(u8"phi文件 (*.phi)"));//多组扩展名用双分号";;"隔开
QString Rfilepath = getSaveFilePath( QString phifilepath =
this, getSaveFilePath(this, QString::fromUtf8(u8"另存为"),
QString::fromUtf8(u8"另存为"), QString::fromUtf8(u8"phi文件 (*.phi)")); // 多组扩展名用双分号";;"隔开
QString::fromUtf8(u8"R文件 (*.R)"));//多组扩展名用双分号";;"隔开
// QString Rfilepath =
// getSaveFilePath(this, QString::fromUtf8(u8"另存为"),
// QString::fromUtf8(u8"R文件 (*.R)")); // 多组扩展名用双分号";;"隔开
this->ui->statusbar->showMessage(u8"正在导出theta极化"); this->ui->statusbar->showMessage(u8"正在导出theta极化");
nearfilePraseclass.toThetapolar(thetafilepath); farfilePraseclass.toThetapolar(thetafilepath);
this->statusprogressBar->setValue(50); this->statusprogressBar->setValue(50);
this->ui->statusbar->showMessage(u8"正在导出phi极化"); this->ui->statusbar->showMessage(u8"正在导出phi极化");
nearfilePraseclass.toPhiPolar(phifilepath); farfilePraseclass.toPhiPolar(phifilepath);
this->statusprogressBar->setValue(75); this->statusprogressBar->setValue(75);
QMessageBox::information(this, u8"信息", u8"极化回波已经保存完毕");
}else{};
// ---------------------- 近场结果 --------------------------------------------------
if(isnear) {
FEKOBase::NearFieldEchoCSVParser nearfilePraseclass;
QString echocsvfilepath = this->model->getCSVPath();
if(!nearfilePraseclass.parseCSV(echocsvfilepath)) {
QMessageBox::warning(this, u8"警告", u8"回波文件结构解析错误,请检查文件");
return;
}
this->statusprogressBar->setValue(25);
QMessageBox::information(this, u8"信息",
u8"请分别为theta极化、phi极化、R极化分量回波指定保存路径");
this->ui->statusbar->showMessage(u8"正在导出R极化"); QString thetafilepath = getSaveFilePath(
nearfilePraseclass.toRPolar(Rfilepath); this, QString::fromUtf8(u8"另存为"),
this->statusprogressBar->setValue(99); QString::fromUtf8(u8"theta文件 (*.theta)")); // 多组扩展名用双分号";;"隔开
QMessageBox::information(this, u8"信息", u8"极化回波已经保存完毕");
QString phifilepath =
getSaveFilePath(this, QString::fromUtf8(u8"另存为"),
QString::fromUtf8(u8"phi文件 (*.phi)")); // 多组扩展名用双分号";;"隔开
QString Rfilepath =
getSaveFilePath(this, QString::fromUtf8(u8"另存为"),
QString::fromUtf8(u8"R文件 (*.R)")); // 多组扩展名用双分号";;"隔开
this->ui->statusbar->showMessage(u8"正在导出theta极化");
nearfilePraseclass.toThetapolar(thetafilepath);
this->statusprogressBar->setValue(50);
this->ui->statusbar->showMessage(u8"正在导出phi极化");
nearfilePraseclass.toPhiPolar(phifilepath);
this->statusprogressBar->setValue(75);
this->ui->statusbar->showMessage(u8"正在导出R极化");
nearfilePraseclass.toRPolar(Rfilepath);
this->statusprogressBar->setValue(99);
QMessageBox::information(this, u8"信息", u8"极化回波已经保存完毕");
}else{}
// 询问用户是否关闭窗口 // 询问用户是否关闭窗口
this->statusprogressBar->setValue(100);
reply = QMessageBox::question(this, u8"提示", u8"是否直接进行成像?",QMessageBox::Yes | QMessageBox::No); if(isfar || isnear) {
if (reply == QMessageBox::Yes) { reply = QMessageBox::question(this, u8"提示", u8"是否直接进行成像?",
LAMPImageCreateClass* imagewindows = new LAMPImageCreateClass; QMessageBox::Yes | QMessageBox::No);
imagewindows->show(); if(reply == QMessageBox::Yes) {
} LAMPImageCreateClass* imagewindows = new LAMPImageCreateClass;
else { imagewindows->show();
return; } else {
return;
}
} else {
QMessageBox::information(this, u8"信息", u8"文件格式读取错误");
} }
} }
void EchoTableEditWindow::on_actionCalibrationConst_triggered() void EchoTableEditWindow::on_actionCalibrationConst_triggered()
{ {
// 补充定标软件功能
} }

File diff suppressed because it is too large Load Diff

View File

@ -43,6 +43,12 @@ namespace FEKOBase {
FEKOBase::FEKOCoordinateSystem FEKOCoordinateSystemString2Enum(QString str); FEKOBase::FEKOCoordinateSystem FEKOCoordinateSystemString2Enum(QString str);
QString QString2FEKOCoordinateSystem(FEKOBase::FEKOCoordinateSystem mode); QString QString2FEKOCoordinateSystem(FEKOBase::FEKOCoordinateSystem mode);
enum FEKORESULTFIELDTYPE {
NEARFIELD, // 球坐标系
FARFIELD, // 笛卡尔坐标系
UNKONWFIELD // 必须为最后一个表示未知
};
//========================================================== //==========================================================
// FEKO成像模式枚举 // FEKO成像模式枚举
@ -179,9 +185,15 @@ namespace FEKOBase {
QString fileFormat; QString fileFormat;
QString source; QString source;
QString date; QString date;
QString radiusStr;
QString thetaStr;
QString phiStr;
double radius; double radius;
double theta; double theta;
double phi; double phi;
double reEr; double reEr;
double imEr; double imEr;
double reEtheta; double reEtheta;
@ -208,7 +220,7 @@ namespace FEKOBase {
size_t freqpoints; size_t freqpoints;
double px, py, pz; double px, py, pz;
//double theta, phi; double theta, phi;
//double incidence, azangle; //double incidence, azangle;
//std::vector<double> freqlist; //std::vector<double> freqlist;
std::vector<ElectricFieldData> electricFieldDataList; // 单频点信息 std::vector<ElectricFieldData> electricFieldDataList; // 单频点信息
@ -217,6 +229,13 @@ namespace FEKOBase {
bool compareElectricFieldDataInFreq(const ElectricFieldData& a, const ElectricFieldData& b); bool compareElectricFieldDataInFreq(const ElectricFieldData& a, const ElectricFieldData& b);
bool comparePRFPluseDataInPRFIdx(const PRFPluseData& a, const PRFPluseData& b); bool comparePRFPluseDataInPRFIdx(const PRFPluseData& a, const PRFPluseData& b);
// 近场
class NearFieldEchoCSVParser { class NearFieldEchoCSVParser {
public: public:
NearFieldEchoCSVParser(); NearFieldEchoCSVParser();
@ -246,11 +265,44 @@ namespace FEKOBase {
}; };
// 远场
class FarFieldEchoCSVParser {
public:
FarFieldEchoCSVParser();
~FarFieldEchoCSVParser();
private:
bool usePRFCountMode = true;
//std::vector<ElectricFieldData> electricFieldDataList;
QMap<QString, std::vector<ElectricFieldData>> electricFieldDataList; // 电场数据
//QMap<QString, PRFPluseData> prfPluseMap;
std::vector<PRFPluseData> prfData;
size_t freqPoints;
double freqStart;
double freqEnd;
// 频率参数
private: // 内部检查函数
bool checkPRFModel();
bool resizePRFPluse(); //回波整理
public:
bool parseCSV(const QString& filePath); // 读取回波数据文件
void toThetapolar(const QString& filePath);// 输出theta 极化
void toPhiPolar(const QString& filePath);// 输出phi 极化
//void toRPolar(const QString& filePath);// 输出phi 极化
void saveCSV(const QString& filePath);// 输出csv文件
private:
void toEchoData(const QString& filePath, size_t outDataName);// 输出回波数据
};
//======================================================================== //========================================================================
// 成像回波格式 // 成像回波格式
// file type: // file type:
// fieldtype 0: 近场1远场
// freqStart,freqEnd,freqPoint,isRight, // freqStart,freqEnd,freqPoint,isRight,
// PRF1,Pos,incidenceAngle,AzAngle,echoDatalist // PRF1,Pos,incidenceAngle,AzAngle,echoDatalist
// PRF2,Pos,incidenceAngle,AzAngle,echoDatalist // PRF2,Pos,incidenceAngle,AzAngle,echoDatalist
@ -266,7 +318,7 @@ namespace FEKOBase {
double freqStart; // 起始频率 double freqStart; // 起始频率
double freqEnd; // 终止频率 double freqEnd; // 终止频率
int freqpoints; // 频率点数 int freqpoints; // 频率点数
FEKOBase::FEKORESULTFIELDTYPE datafieldtype; // 判断是否为近远场
public: public:
EchoDataClass(const FEKOBase::EchoDataClass& inecho); EchoDataClass(const FEKOBase::EchoDataClass& inecho);
EchoDataClass(); EchoDataClass();
@ -284,6 +336,9 @@ namespace FEKOBase {
void setFreqpoints(int freqpoints); void setFreqpoints(int freqpoints);
int getFreqpoints() const; int getFreqpoints() const;
void setDataFieldType(FEKOBase::FEKORESULTFIELDTYPE fieldtype);
FEKOBase::FEKORESULTFIELDTYPE getDataFieldType() const;
void loadEchoData(const QString& filePath); // 加载回波数据文件 void loadEchoData(const QString& filePath); // 加载回波数据文件
void SaveEchoData(const QString& filePath); // 保存回波数据文件 void SaveEchoData(const QString& filePath); // 保存回波数据文件
}; };
@ -332,11 +387,8 @@ namespace FEKOBase {
ImageAlgWindowFun String2ImageAlgWindowFun(QString str); ImageAlgWindowFun String2ImageAlgWindowFun(QString str);
QString ImageAlgWindowFun2String(ImageAlgWindowFun alg); QString ImageAlgWindowFun2String(ImageAlgWindowFun alg);
bool BPImage_TIME(QString& restiffpath, Eigen::MatrixXcd& echoData, Eigen::MatrixXd& antPos, Eigen::MatrixXd& freqmatrix, Eigen::MatrixXd& X, Eigen::MatrixXd& Y, Eigen::MatrixXd& Z, ImageAlgWindowFun winfun = ImageAlgWindowFun::HANMMING,FEKOBase::FEKORESULTFIELDTYPE EchoMode=FEKOBase::FEKORESULTFIELDTYPE::NEARFIELD ); // BP成像
bool BPImage_TIME(QString& restiffpath, Eigen::MatrixXcd& echoData, Eigen::MatrixXd& antPos, Eigen::MatrixXd& freqmatrix, Eigen::MatrixXd& X, Eigen::MatrixXd& Y, Eigen::MatrixXd& Z, ImageAlgWindowFun winfun = ImageAlgWindowFun::HANMMING); // BP成像 bool FBPImage_FREQ(QString& restiffpath, Eigen::MatrixXcd& echoData, Eigen::MatrixXd& antPos, Eigen::MatrixXd& freqmatrix, Eigen::MatrixXd& X, Eigen::MatrixXd& Y, Eigen::MatrixXd& Z, ImageAlgWindowFun winfun = ImageAlgWindowFun::HANMMING,FEKOBase::FEKORESULTFIELDTYPE EchoMode=FEKOBase::FEKORESULTFIELDTYPE::NEARFIELD); // FBP成像
bool FBPImage_FREQ(QString& restiffpath, Eigen::MatrixXcd& echoData, Eigen::MatrixXd& antPos, Eigen::MatrixXd& freqmatrix, Eigen::MatrixXd& X, Eigen::MatrixXd& Y, Eigen::MatrixXd& Z, ImageAlgWindowFun winfun = ImageAlgWindowFun::HANMMING); // FBP成像
} }

File diff suppressed because it is too large Load Diff

View File

@ -32,9 +32,9 @@ struct Landpoint // 点 SAR影像的像素坐标
double ati; // 高程z ati pixel_time double ati; // 高程z ati pixel_time
}; };
struct Point_3d { struct Point_3d {
double x; double x=0;
double y; double y=0;
double z; double z=0;
}; };
/// <summary> /// <summary>

View File

@ -3,6 +3,7 @@
ImageShowDialogClass ::ImageShowDialogClass(QWidget *parent) ImageShowDialogClass ::ImageShowDialogClass(QWidget *parent)
: QDialog(parent) : QDialog(parent)
{ {
ui=new Ui::ImageShowDialogClass;
ui->setupUi(this); ui->setupUi(this);
ui->m_plot->setInteractions(QCP::iRangeDrag | QCP::iRangeZoom); ui->m_plot->setInteractions(QCP::iRangeDrag | QCP::iRangeZoom);
connect(this->ui->m_plot, SIGNAL(mouseMove(QMouseEvent*)), this, SLOT(updateCursor(QMouseEvent*))); connect(this->ui->m_plot, SIGNAL(mouseMove(QMouseEvent*)), this, SLOT(updateCursor(QMouseEvent*)));

View File

@ -96,7 +96,7 @@ void LAMPDataShowClass::on_action_openfile_envi_complex_triggered()
void LAMPDataShowClass::load_complex_data(QString path) void LAMPDataShowClass::load_complex_data(QString path)
{ {
DebugInfo("LAMPDataShowClass::load_complex_data"); DebugInfo("LAMPDataShowClass::load_complex_data\n");
ComplexDataShowNode* node = new ComplexDataShowNode(); ComplexDataShowNode* node = new ComplexDataShowNode();
node->bangdindWindows(this); node->bangdindWindows(this);
node->TaskXmlPath = path; node->TaskXmlPath = path;
@ -105,7 +105,7 @@ void LAMPDataShowClass::load_complex_data(QString path)
} }
else {} else {}
node->OpenData(node->TaskXmlPath); node->OpenData(node->TaskXmlPath);
this->add_DataTree(node); this->add_DataTree(node); DebugInfo("this->add_DataTree(node)\n");
node->ExcuteTask(); node->ExcuteTask();
} }

View File

@ -107,12 +107,14 @@ void LAMPImageCreateClass::on_pushButton_OK_clicked()
QString theta_tiff_filepath=this->ui->lineEdit_thetaimagepath->text().trimmed(); QString theta_tiff_filepath=this->ui->lineEdit_thetaimagepath->text().trimmed();
FEKOBase::EchoDataClass data; FEKOBase::EchoDataClass data;
qDebug()<<"theta EchoData loading start !!! EchoData File : "<<thetafileptah;
data.loadEchoData(thetafileptah); data.loadEchoData(thetafileptah);
qDebug()<<"theta EchoData loading finish !!! EchoData File : "<<thetafileptah;
if (this->simulationparams&&(this->simulationparams->imagemode==FEKOBase::FEKOImageMode::Strip|| this->simulationparams->imagemode == FEKOBase::FEKOImageMode::Scane)) { if (this->simulationparams&&(this->simulationparams->imagemode==FEKOBase::FEKOImageMode::Strip|| this->simulationparams->imagemode == FEKOBase::FEKOImageMode::Scane)) {
FEKOBase::FEKOImageProcess(data, imageparams, theta_tiff_filepath,FEKOBase::FEKOImageAlgorithm::TBP_FREQ,FEKOBase::ImageAlgWindowFun::HANMMING); FEKOBase::FEKOImageProcess(data, imageparams, theta_tiff_filepath,FEKOBase::FEKOImageAlgorithm::TBP_FREQ,FEKOBase::ImageAlgWindowFun::HANMMING);
} }
else { else {
FEKOBase::FEKOImageProcess(data, imageparams, theta_tiff_filepath); FEKOBase::FEKOImageProcess(data, imageparams, theta_tiff_filepath,FEKOBase::FEKOImageAlgorithm::TBP_FREQ);
} }
} }
else { else {
@ -125,13 +127,15 @@ void LAMPImageCreateClass::on_pushButton_OK_clicked()
QString phi_tiff_filepath = this->ui->lineEdit_phiimagepath->text().trimmed(); QString phi_tiff_filepath = this->ui->lineEdit_phiimagepath->text().trimmed();
FEKOBase::EchoDataClass data; FEKOBase::EchoDataClass data;
qDebug()<<"theta EchoData loading start !!! EchoData File : "<<phifileptah;
data.loadEchoData(phifileptah); data.loadEchoData(phifileptah);
qDebug()<<"phi EchoData loading finish !!! EchoData File : "<<phifileptah;
//FEKOBase::FEKOImageProcess(data, imageparams, phi_tiff_filepath); //FEKOBase::FEKOImageProcess(data, imageparams, phi_tiff_filepath);
if (this->simulationparams && (this->simulationparams->imagemode == FEKOBase::FEKOImageMode::Strip || this->simulationparams->imagemode == FEKOBase::FEKOImageMode::Scane)) { if (this->simulationparams && (this->simulationparams->imagemode == FEKOBase::FEKOImageMode::Strip || this->simulationparams->imagemode == FEKOBase::FEKOImageMode::Scane)) {
FEKOBase::FEKOImageProcess(data, imageparams, phi_tiff_filepath, FEKOBase::FEKOImageAlgorithm::TBP_FREQ, FEKOBase::ImageAlgWindowFun::HANMMING); FEKOBase::FEKOImageProcess(data, imageparams, phi_tiff_filepath, FEKOBase::FEKOImageAlgorithm::TBP_FREQ, FEKOBase::ImageAlgWindowFun::HANMMING);
} }
else { else {
FEKOBase::FEKOImageProcess(data, imageparams, phi_tiff_filepath); FEKOBase::FEKOImageProcess(data, imageparams, phi_tiff_filepath,FEKOBase::FEKOImageAlgorithm::TBP_FREQ);
} }
} }
else { else {

View File

@ -31,6 +31,8 @@ namespace WBFZ
void PointCloudThreadBase::defaultMeshFinished() void PointCloudThreadBase::defaultMeshFinished()
{ {
ModuleBase::ThreadTask::threadTaskFinished();
Py::PythonAgent::getInstance()->unLock();
if (_threadRuning) if (_threadRuning)
{ {
@ -40,23 +42,42 @@ namespace WBFZ
{ {
if (_success) if (_success)
{ {
emit _mainwindow->updateMeshTreeSig(); // emit _mainwindow->updateMeshTreeSig();
emit _mainwindow->updateSetTreeSig(); // emit _mainwindow->updateSetTreeSig();
emit _mainwindow->updateActionStatesSig(); // emit _mainwindow->updateActionStatesSig();
// emit _mainwindow->updateActionsStatesSig(); // // emit _mainwindow->updateActionsStatesSig();
emit _mainwindow->getSubWindowManager()->openPreWindowSig(); // emit _mainwindow->getSubWindowManager()->openPreWindowSig();
emit _mainwindow->updatePreMeshActorSig(); // emit _mainwindow->updatePreMeshActorSig();
information = QString("Successful Import Mesh From \"%1\"").arg(_fileName); information = QString("Successful Import Mesh From \"%1\"").arg(_fileName);
msg.type = Common::Message::Normal; msg.type = Common::Message::Normal;
msg.message = information; msg.message = information;
auto meshdata = MeshData::MeshData::getInstance();
// meshdata->generateDisplayDataSet(); QFileInfo info(_fileName);
const int nk = meshdata->getKernalCount(); QString name = info.fileName();
if (nk <= 0) QString path = info.filePath();
return; QString suffix = info.suffix().toLower();
auto k = meshdata->getKernalAt(nk - 1); if(info.exists()){
if (k != nullptr) if(suffix.toLower().contains("pcd")){
k->setPath(_fileName); suffix="Point Cloud Data(*.pcd)";
emit _mainwindow->importPclSIGN(_fileName,suffix,-1);
}else if(suffix.toLower().contains("ply")){
suffix="Polygon File Format(*.ply)";
emit _mainwindow->importPclSIGN(_fileName,suffix,-1);
}else{
information = QString("Failed Filter From \"%1\"").arg(_fileName);
msg.type = Common::Message::Error;
msg.message = information;
}
}
// auto meshdata = MeshData::MeshData::getInstance();
// // meshdata->generateDisplayDataSet();
// const int nk = meshdata->getKernalCount();
// if (nk <= 0)
// return;
// auto k = meshdata->getKernalAt(nk - 1);
// if (k != nullptr)
// k->setPath(_fileName);
} }
else else
{ {
@ -65,11 +86,11 @@ namespace WBFZ
msg.message = information; msg.message = information;
} }
}else{} }else{}
emit showInformation(information);
emit _mainwindow->printMessageToMessageWindow(msg);
} }
// emit showInformation(information); // emit showInformation(information);
// emit _mainwindow->printMessageToMessageWindow(msg); // emit _mainwindow->printMessageToMessageWindow(msg);
ModuleBase::ThreadTask::threadTaskFinished();
Py::PythonAgent::getInstance()->unLock();
} }
void PointCloudThreadBase::setThreadRunState(bool flag){ void PointCloudThreadBase::setThreadRunState(bool flag){
_success= flag; _success= flag;
@ -100,39 +121,11 @@ namespace WBFZ
} }
bool PointCloudThreadBase::filtertaskProcess() bool PointCloudThreadBase::filtertaskProcess()
{ {
vtkDataSet* dataset=filter(); return filter();
QFileInfo info(_fileName);
QString name = info.fileName();
QString path = info.filePath();
QString suffix = info.suffix().toLower();
DebugInfo("dataset %d \n",dataset== nullptr);
// 保存流程文件
if (dataset != nullptr) {
MeshData::MeshKernal* k = new MeshData::MeshKernal;
k->setName(name);
k->setPath(path);
auto meshData =MeshData::MeshData::getInstance();
int nKernal = meshData->getKernalCount();
for(int iKernal = 0; iKernal < nKernal; ++iKernal) {
MeshData::MeshKernal* temp = meshData->getKernalAt(iKernal);
if(temp->getPath() == path) { ///< MG same file update
meshData->removeKernalAt(iKernal);
break;
}
}
k->setMeshData(dataset);
meshData->appendMeshKernal(k);
return true;
}else{
return false;
}
return false;
} }
vtkDataSet* PointCloudThreadBase::filter() bool PointCloudThreadBase::filter()
{ {
return nullptr; return false;
} }
vtkDataSet* PointCloudThreadBase::remesh() vtkDataSet* PointCloudThreadBase::remesh()
{ {
@ -171,5 +164,38 @@ namespace WBFZ
return false; return false;
} }
bool PointCloudThreadBase::saveFilterResultFile(pcl::PointCloud<pcl::PointXYZRGBA>::Ptr cloud_filtered)
{
QString filepath=_fileName;
// 加载文件
QFile infile(_fileName);
if(infile.exists()){
infile.remove();
}
QFileInfo info(_fileName);
QString name = info.fileName();
QString path = info.filePath();
QString suffix = info.suffix().toLower();
QTextCodec *codec = QTextCodec::codecForName("GB18030");
QByteArray ba = codec->fromUnicode(filepath);
std::string outFileName=ba.data();
if (suffix == "pcd")
{
pcl::io::savePCDFileBinary(outFileName,*cloud_filtered);
QFile outfile(filepath);
return outfile.exists();
}
else if (suffix == "ply")
{
pcl::io::savePLYFileBinary(outFileName,*cloud_filtered);
QFile outfile(filepath);
return outfile.exists();
}
else{}
return false;
}
} }

View File

@ -1,6 +1,8 @@
#ifndef _MESHTHREADBASE_H_ #ifndef _MESHTHREADBASE_H_
#define _MESHTHREADBASE_H_ #define _MESHTHREADBASE_H_
#include <pcl/point_cloud.h>
#include <pcl/impl/point_types.hpp>
#include "ModuleBase/ThreadTask.h" #include "ModuleBase/ThreadTask.h"
#include "WBFZExchangePluginAPI.h" #include "WBFZExchangePluginAPI.h"
#include "WBFZExchangePlugin.h" #include "WBFZExchangePlugin.h"
@ -30,8 +32,9 @@ namespace WBFZ
virtual void run(); virtual void run();
void defaultMeshFinished(); void defaultMeshFinished();
void setThreadRunState(bool); void setThreadRunState(bool);
bool saveFilterResultFile(pcl::PointCloud<pcl::PointXYZRGBA>::Ptr cloud_filtered);
public: public:
virtual vtkDataSet* filter(); virtual bool filter();
virtual bool filtertaskProcess(); virtual bool filtertaskProcess();
public: public:

View File

@ -9,8 +9,20 @@
#include <QDebug> #include <QDebug>
#include "SharedModuleLib/ProcessOn.h" #include "SharedModuleLib/ProcessOn.h"
AbstractTableModel::AbstractTableModel(QObject* parent ):QAbstractTableModel(parent)
{}
AbstractTableModel::~AbstractTableModel(){
}
FEKOResultCsvTableModel::FEKOResultCsvTableModel(QObject* parent) FEKOResultCsvTableModel::FEKOResultCsvTableModel(QObject* parent)
:AbstractTableModel(parent)
{ {
} }
FEKOResultCsvTableModel::~FEKOResultCsvTableModel() FEKOResultCsvTableModel::~FEKOResultCsvTableModel()

View File

@ -8,82 +8,83 @@
#include <QStringList> #include <QStringList>
#include <QVector> #include <QVector>
class AbstractTableModel :public QAbstractTableModel { class AbstractTableModel : public QAbstractTableModel {
Q_OBJECT; Q_OBJECT;
public: public:
virtual void loadFilePath(QString csvPath); // 加载csv数据 AbstractTableModel(QObject* parent = nullptr);
virtual void saveFilePath(); ~AbstractTableModel();
virtual void saveAsFilePath(QString csvpath);
virtual QString getCSVPath(); public:
virtual void loadFilePath(QString csvPath); // 加载csv数据
virtual void saveFilePath();
virtual void saveAsFilePath(QString csvpath);
virtual QString getCSVPath();
}; };
// FKEOResult.csv 表格对应类 2023.07.25 重写类 // FKEOResult.csv 表格对应类 2023.07.25 重写类
class FEKOResultCsvTableModel :public AbstractTableModel { class FEKOResultCsvTableModel : public AbstractTableModel {
Q_OBJECT; Q_OBJECT;
private: private:
QStringList m_hor_hedlbls; // headerlabels QStringList m_hor_hedlbls; // headerlabels
QStringList m_vec_hedlbls; // oids - map.keys() QStringList m_vec_hedlbls; // oids - map.keys()
QVector<QVector<QVariant>> m_data_map; QVector<QVector<QVariant>> m_data_map;
QVector<QPair<int, int> > m_highlight_indexs; // 背景高亮的indexs QVector<QPair<int, int>> m_highlight_indexs; // 背景高亮的indexs
QVector<QVector<QColor>> colorData; QVector<QVector<QColor>> colorData;
QString csvPath; QString csvPath;
public: public:
explicit FEKOResultCsvTableModel(QObject* parent = nullptr);
explicit FEKOResultCsvTableModel(QObject* parent = NULL);
~FEKOResultCsvTableModel(); ~FEKOResultCsvTableModel();
virtual void loadFilePath(QString csvPath); // 加载csv数据
virtual void saveFilePath();
virtual void saveAsFilePath(QString csvpath);
void loadCSVFilePath(QString csvPath); // 加载csv数据 virtual void loadFilePath(QString csvPath); // 加载csv数据
void saveCSVFilePath(QString csvpath); virtual void saveFilePath();
virtual void saveAsFilePath(QString csvpath);
QStringList getColumnNames(); void loadCSVFilePath(QString csvPath); // 加载csv数据
QStringList getItemDataByColumn(int colidx); void saveCSVFilePath(QString csvpath);
int getColumnIdxByColumName(QString ColumnName);
virtual QString getCSVPath();
// tableview 表格模型操作 QStringList getColumnNames();
void SetData(const QVector<QVector<QVariant>>& map, QStringList& colnames, QStringList& rowIds); QStringList getItemDataByColumn(int colidx);
int getColumnIdxByColumName(QString ColumnName);
virtual QString getCSVPath();
void setHignlightIndex(QVector< QPair<int, int> > vec_index); // tableview 表格模型操作
void SetData(const QVector<QVector<QVariant>>& map, QStringList& colnames, QStringList& rowIds);
virtual Qt::ItemFlags flags(const QModelIndex& index) const; void setHignlightIndex(QVector<QPair<int, int>> vec_index);
virtual QVariant headerData(int section, Qt::Orientation orientation, int role) const;
virtual int rowCount(const QModelIndex& parent) const; virtual Qt::ItemFlags flags(const QModelIndex& index) const;
virtual int columnCount(const QModelIndex& parent) const; virtual QVariant headerData(int section, Qt::Orientation orientation, int role) const;
virtual QVariant data(const QModelIndex& index, int role) const; virtual int rowCount(const QModelIndex& parent) const;
virtual bool setData(const QModelIndex& index, const QVariant& value, int role=2); virtual int columnCount(const QModelIndex& parent) const;
QString itemText(int row, int column) const; virtual QVariant data(const QModelIndex& index, int role) const;
QString itemText(const QModelIndex& index) const; virtual bool setData(const QModelIndex& index, const QVariant& value, int role = 2);
void setItemText(const QModelIndex& index, const QString& str);
void setItemText(int row, int column, const QString& str);
QVariant ItemData(const QModelIndex& index) const; QString itemText(int row, int column) const;
QVariant ItemData(int row, int column) const; QString itemText(const QModelIndex& index) const;
void SetItemData(const QModelIndex& index, const QVariant& data); void setItemText(const QModelIndex& index, const QString& str);
void SetItemData(int row, int column, const QVariant& data); void setItemText(int row, int column, const QString& str);
size_t rowCount(); QVariant ItemData(const QModelIndex& index) const;
size_t colCount(); QVariant ItemData(int row, int column) const;
void SetItemData(const QModelIndex& index, const QVariant& data);
void SetItemData(int row, int column, const QVariant& data);
void isNeedExtendTable(size_t row, size_t col); size_t rowCount();
size_t colCount();
void clear(); void isNeedExtendTable(size_t row, size_t col);
QVariant* getVariantPtr(size_t row, size_t col); void clear();
QVariant* getVariantPtr(size_t row, size_t col);
signals: signals:
void itemChanged(const QModelIndex& index, const QVariant& value); void itemChanged(const QModelIndex& index, const QVariant& value);
}; };
#endif #endif

View File

@ -27,7 +27,7 @@ namespace WBFZ {
{ {
_describe = "WBFZExchangePlugin Installed Successfully"; _describe = "WBFZExchangePlugin Installed Successfully";
_mainwindow = m; _mainwindow = m;
// 点云操作
connect(_mainwindow, SIGNAL(on_pclStatisticalRemoveFilter(GUI::MainWindow*)), this, connect(_mainwindow, SIGNAL(on_pclStatisticalRemoveFilter(GUI::MainWindow*)), this,
SLOT(pclStatisticalRemoveFilter(GUI::MainWindow*))); SLOT(pclStatisticalRemoveFilter(GUI::MainWindow*)));
connect(_mainwindow, SIGNAL(on_pclRadiusOutlierRemoval(GUI::MainWindow*)), this, connect(_mainwindow, SIGNAL(on_pclRadiusOutlierRemoval(GUI::MainWindow*)), this,

View File

@ -3,6 +3,8 @@
#include <QtCore/QtGlobal> #include <QtCore/QtGlobal>
// 定义 远场条件下的默认参考斜距
#define CIRCLESARREFRANGE 90000
#if defined(WBFZ_API) #if defined(WBFZ_API)
#define WBFZAPI Q_DECL_EXPORT #define WBFZAPI Q_DECL_EXPORT