feat:博清焊缝算法更新; 应用做点云预处理,扫描结束进行最终检测
This commit is contained in:
parent
a27176fd9d
commit
379782908a
@ -1,6 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <QString>
|
||||
#include <mutex>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
@ -16,6 +17,14 @@ public:
|
||||
DetectPresenter();
|
||||
static QString GetAlgoVersion();
|
||||
|
||||
void ResetIncrementalData();
|
||||
bool ProcessDetectionLine(EVzResultDataType dataType,
|
||||
const SVzLaserLineData& lineData,
|
||||
const VrAlgorithmParams& algorithmParams,
|
||||
const SSG_planeCalibPara& groundCalibParam,
|
||||
LaserDataLoader& dataLoader);
|
||||
bool HasIncrementalData() const;
|
||||
|
||||
int DetectWeldSeam(
|
||||
int cameraIndex,
|
||||
std::vector<std::pair<EVzResultDataType, SVzLaserLineData>>& laserLines,
|
||||
@ -24,4 +33,9 @@ public:
|
||||
const VrDebugParam& debugParam,
|
||||
LaserDataLoader& dataLoader,
|
||||
DetectionResult& detectionResult);
|
||||
|
||||
private:
|
||||
mutable std::mutex m_incrementalMutex;
|
||||
std::vector<std::vector<SVzNL3DPosition>> m_incrementalScanLines;
|
||||
std::vector<std::vector<SSG_basicFeatureGap>> m_incrementalLineValleys;
|
||||
};
|
||||
|
||||
@ -58,6 +58,10 @@ protected:
|
||||
int InitAlgoParams() override;
|
||||
int ProcessAlgoDetection(
|
||||
std::vector<std::pair<EVzResultDataType, SVzLaserLineData>>& detectionDataCache) override;
|
||||
bool OnDetectionData(EVzResultDataType dataType,
|
||||
SVzLaserLineData* laserData) override;
|
||||
bool HasPendingDetectionData() const override;
|
||||
void ClearDetectionDataCache() override;
|
||||
EVzResultDataType GetDetectionDataType() override { return keResultDataType_Position; }
|
||||
VzNL_OnNotifyStatusCBEx GetCameraStatusCallback() override;
|
||||
void OnCameraStatusChanged(int cameraIndex, bool isConnected) override;
|
||||
|
||||
@ -2,6 +2,7 @@
|
||||
|
||||
#include "AlgorithmParamConverter.h"
|
||||
#include "PointCloudImageUtils.h"
|
||||
#include "SG_baseAlgo_Export.h"
|
||||
#include "SX_lapWeldDetection_Export.h"
|
||||
#include "VrDateUtils.h"
|
||||
#include "VrError.h"
|
||||
@ -13,19 +14,6 @@
|
||||
#include <QDir>
|
||||
#include <algorithm>
|
||||
|
||||
SG_APISHARED_EXPORT void wd_getLineVFlaws(
|
||||
std::vector<SVzNL3DPosition>& line,
|
||||
int lineIndex,
|
||||
SWD_valleyParam valleyParam,
|
||||
std::vector<SSG_basicFeatureGap>& valleys);
|
||||
|
||||
SG_APISHARED_EXPORT void sg_lineGapsGrowing(
|
||||
int lineIndex,
|
||||
bool isLastLine,
|
||||
std::vector<SSG_basicFeatureGap>& features,
|
||||
std::vector<SSG_gapFeatureTree>& trees,
|
||||
SSG_treeGrowParam growParam);
|
||||
|
||||
namespace {
|
||||
|
||||
int ValidPointCount(const std::vector<SVzNL3DPosition>& line)
|
||||
@ -105,6 +93,49 @@ DetectPresenter::DetectPresenter()
|
||||
LOG_INFO("lapWeldDetection version: %s\n", wd_weldSeamAlgoVersion());
|
||||
}
|
||||
|
||||
void DetectPresenter::ResetIncrementalData()
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(m_incrementalMutex);
|
||||
m_incrementalScanLines.clear();
|
||||
m_incrementalLineValleys.clear();
|
||||
}
|
||||
|
||||
bool DetectPresenter::HasIncrementalData() const
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(m_incrementalMutex);
|
||||
return !m_incrementalScanLines.empty();
|
||||
}
|
||||
|
||||
bool DetectPresenter::ProcessDetectionLine(
|
||||
EVzResultDataType dataType,
|
||||
const SVzLaserLineData& lineData,
|
||||
const VrAlgorithmParams& algorithmParams,
|
||||
const SSG_planeCalibPara& groundCalibParam,
|
||||
LaserDataLoader& dataLoader)
|
||||
{
|
||||
std::vector<std::pair<EVzResultDataType, SVzLaserLineData>> oneLine;
|
||||
oneLine.emplace_back(dataType, lineData);
|
||||
std::vector<std::vector<SVzNL3DPosition>> converted;
|
||||
if (dataLoader.ConvertToSVzNL3DPosition(oneLine, converted) != SUCCESS ||
|
||||
converted.empty() || converted.front().empty() ||
|
||||
ValidPointCount(converted.front()) == 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
std::vector<SVzNL3DPosition> scanLine = std::move(converted.front());
|
||||
sx_lineDataR(scanLine, groundCalibParam.planeCalib, -1.0);
|
||||
const WeldSeamAlgorithmParams params =
|
||||
AlgorithmParamConverter::ToAlgorithmParams(algorithmParams);
|
||||
std::vector<SSG_basicFeatureGap> valleys;
|
||||
std::lock_guard<std::mutex> lock(m_incrementalMutex);
|
||||
const int lineIndex = static_cast<int>(m_incrementalScanLines.size());
|
||||
wd_getLineVFlaws(scanLine, lineIndex, params.valleyParam,
|
||||
params.detectFlawType, valleys);
|
||||
m_incrementalScanLines.push_back(std::move(scanLine));
|
||||
m_incrementalLineValleys.push_back(std::move(valleys));
|
||||
return true;
|
||||
}
|
||||
|
||||
QString DetectPresenter::GetAlgoVersion()
|
||||
{
|
||||
return QString::fromUtf8(wd_weldSeamAlgoVersion());
|
||||
@ -119,17 +150,24 @@ int DetectPresenter::DetectWeldSeam(
|
||||
LaserDataLoader& dataLoader,
|
||||
DetectionResult& detectionResult)
|
||||
{
|
||||
if (laserLines.empty()) {
|
||||
detectionResult.message = QStringLiteral("扫描数据为空");
|
||||
return ERR_CODE(DEV_DATA_INVALID);
|
||||
}
|
||||
|
||||
std::vector<std::vector<SVzNL3DPosition>> scanLines;
|
||||
const int convertResult = dataLoader.ConvertToSVzNL3DPosition(laserLines, scanLines);
|
||||
RemoveEmptyEdgeLines(scanLines);
|
||||
if (convertResult != SUCCESS || scanLines.empty()) {
|
||||
detectionResult.message = QStringLiteral("扫描数据转换失败");
|
||||
return ERR_CODE(DEV_DATA_INVALID);
|
||||
std::vector<std::vector<SSG_basicFeatureGap>> preprocessedValleys;
|
||||
const bool useIncrementalData = HasIncrementalData();
|
||||
if (useIncrementalData) {
|
||||
std::lock_guard<std::mutex> lock(m_incrementalMutex);
|
||||
scanLines = m_incrementalScanLines;
|
||||
preprocessedValleys = m_incrementalLineValleys;
|
||||
if (scanLines.empty() || scanLines.size() != preprocessedValleys.size()) {
|
||||
detectionResult.message = QStringLiteral("扫描数据为空");
|
||||
return ERR_CODE(DEV_DATA_INVALID);
|
||||
}
|
||||
} else {
|
||||
const int convertResult = dataLoader.ConvertToSVzNL3DPosition(laserLines, scanLines);
|
||||
RemoveEmptyEdgeLines(scanLines);
|
||||
if (convertResult != SUCCESS || scanLines.empty()) {
|
||||
detectionResult.message = QStringLiteral("扫描数据转换失败");
|
||||
return ERR_CODE(DEV_DATA_INVALID);
|
||||
}
|
||||
}
|
||||
|
||||
const WeldSeamAlgorithmParams params = AlgorithmParamConverter::ToAlgorithmParams(algorithmParams);
|
||||
@ -157,16 +195,22 @@ int DetectPresenter::DetectWeldSeam(
|
||||
}
|
||||
|
||||
CVrTimeUtils timer;
|
||||
for (auto& line : scanLines) {
|
||||
sx_lineDataR(line, groundCalibParam.planeCalib, -1.0);
|
||||
if (!useIncrementalData) {
|
||||
for (auto& line : scanLines) {
|
||||
sx_lineDataR(line, groundCalibParam.planeCalib, -1.0);
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<SSG_gapFeatureTree> trees;
|
||||
trees.reserve(scanLines.size());
|
||||
for (size_t lineIndex = 0; lineIndex < scanLines.size(); ++lineIndex) {
|
||||
std::vector<SSG_basicFeatureGap> lineValleys;
|
||||
wd_getLineVFlaws(scanLines[lineIndex], static_cast<int>(lineIndex),
|
||||
params.valleyParam, lineValleys);
|
||||
if (useIncrementalData) {
|
||||
lineValleys = preprocessedValleys[lineIndex];
|
||||
} else {
|
||||
wd_getLineVFlaws(scanLines[lineIndex], static_cast<int>(lineIndex),
|
||||
params.valleyParam, params.detectFlawType, lineValleys);
|
||||
}
|
||||
const bool isLastLine = lineIndex + 1 == scanLines.size();
|
||||
sg_lineGapsGrowing(static_cast<int>(lineIndex), isLastLine,
|
||||
lineValleys, trees, params.treeGrowParam);
|
||||
|
||||
@ -85,6 +85,8 @@ int WeldSeamPresenter::InitAlgoParams()
|
||||
p.treeGrowParam.maxLineSkipNum, p.treeGrowParam.yDeviationMax,
|
||||
p.treeGrowParam.maxSkipDistance, p.treeGrowParam.zDeviationMax,
|
||||
p.treeGrowParam.minLTypeTreeLen, p.treeGrowParam.minVTypeTreeLen);
|
||||
LOG_INFO("WeldSeam flaw type=%d\n",
|
||||
static_cast<int>(p.weldSeamParam.detectFlawType));
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
@ -179,7 +181,7 @@ QString WeldSeamPresenter::StopDynamicScanAndDetect()
|
||||
|
||||
// StopDetect 成功后才检查缓存。空扫描仍属于已受理的 STOP 请求:
|
||||
// 先让调用方返回 STOP_ACK,再在 Presenter 线程异步发布 RESULT_NG。
|
||||
if (GetDetectionDataCacheSize() <= 0) {
|
||||
if (!HasPendingDetectionData()) {
|
||||
UpdateModbusStatus(2);
|
||||
OnStatusUpdate("动态扫描已结束,未采集到有效数据");
|
||||
QMetaObject::invokeMethod(this, [this]() {
|
||||
@ -240,6 +242,13 @@ int WeldSeamPresenter::ProcessAlgoDetection(
|
||||
int code = ERR_CODE(DEV_NOT_FIND);
|
||||
if (m_pDetectPresenter && m_pConfigManager) {
|
||||
const ConfigResult config = m_pConfigManager->GetConfigResult();
|
||||
// Live WeldSeam scans are preprocessed line-by-line. The base cache is
|
||||
// only populated in debug mode for persistence, so release that copy
|
||||
// before asking DetectPresenter to consume its incremental data.
|
||||
if (m_pDetectPresenter->HasIncrementalData() && !detectionDataCache.empty()) {
|
||||
m_dataLoader.FreeLaserScanData(detectionDataCache);
|
||||
detectionDataCache.clear();
|
||||
}
|
||||
code = m_pDetectPresenter->DetectWeldSeam(
|
||||
m_currentCameraIndex, detectionDataCache, config.algorithmParams,
|
||||
GetCameraCalibParam(m_currentCameraIndex), config.debugParam, m_dataLoader, result);
|
||||
@ -264,6 +273,39 @@ int WeldSeamPresenter::ProcessAlgoDetection(
|
||||
return code;
|
||||
}
|
||||
|
||||
bool WeldSeamPresenter::OnDetectionData(EVzResultDataType dataType,
|
||||
SVzLaserLineData* laserData)
|
||||
{
|
||||
if (!laserData || !m_pDetectPresenter || !m_pConfigManager ||
|
||||
dataType != keResultDataType_Position) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const ConfigResult config = m_pConfigManager->GetConfigResult();
|
||||
const bool processed = m_pDetectPresenter->ProcessDetectionLine(
|
||||
dataType, *laserData, config.algorithmParams,
|
||||
GetCameraCalibParam(m_currentCameraIndex), m_dataLoader);
|
||||
if (!processed) {
|
||||
LOG_WARNING("WeldSeam failed to preprocess one point-cloud line\n");
|
||||
return true;
|
||||
}
|
||||
|
||||
// Keep the original line only when debug persistence is enabled. In the
|
||||
// normal path BasePresenter immediately drops its temporary callback data.
|
||||
return !config.debugParam.enableDebug;
|
||||
}
|
||||
|
||||
bool WeldSeamPresenter::HasPendingDetectionData() const
|
||||
{
|
||||
return m_pDetectPresenter && m_pDetectPresenter->HasIncrementalData();
|
||||
}
|
||||
|
||||
void WeldSeamPresenter::ClearDetectionDataCache()
|
||||
{
|
||||
BasePresenter::ClearDetectionDataCache();
|
||||
if (m_pDetectPresenter) m_pDetectPresenter->ResetIncrementalData();
|
||||
}
|
||||
|
||||
int WeldSeamPresenter::LoadAndDetect(const QString& fileName)
|
||||
{
|
||||
ScanState expected = ScanState::Ready;
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
#define WELDSEAM_VERSION_H
|
||||
|
||||
#define WELDSEAM_APP_NAME "焊缝定位"
|
||||
#define WELDSEAM_VERSION_STRING "1.0.0"
|
||||
#define WELDSEAM_VERSION_STRING "1.0.1"
|
||||
#define WELDSEAM_BUILD_STRING "1"
|
||||
#define WELDSEAM_FULL_VERSION_STRING "V" WELDSEAM_VERSION_STRING "_" WELDSEAM_BUILD_STRING
|
||||
|
||||
|
||||
@ -1,6 +1,8 @@
|
||||
# WeldSeam 版本记录
|
||||
# 1.0.1
|
||||
## build_1
|
||||
1. 更新算法版本,增加了焊缝类型
|
||||
|
||||
## 1.0.0
|
||||
# 1.0.0
|
||||
|
||||
- 使用 VzNLSDK 非摆动动态扫描模式。
|
||||
- 实现 `START_SCAN` / `STOP_SCAN` TCP 交互流程。
|
||||
|
||||
@ -4,7 +4,8 @@ QT += core gui network serialport
|
||||
|
||||
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
|
||||
|
||||
CONFIG += c++17
|
||||
# OpenCV 3.2 still uses std::random_shuffle, which was removed in C++17.
|
||||
CONFIG += c++14
|
||||
|
||||
# 项目名称
|
||||
TARGET = WeldSeamApp
|
||||
@ -148,6 +149,8 @@ else:unix:!macx: {
|
||||
|
||||
# 焊缝检测算法(lapWeldDetection)
|
||||
INCLUDEPATH += ../../../AppAlgo/lapWeldDetection/Inc
|
||||
# OpenCV 3.2 headers required by SG_baseAlgo_Export.h
|
||||
INCLUDEPATH += $$PWD/../../../SDK/OpenCV320/include
|
||||
|
||||
win32:CONFIG(release, debug|release): {
|
||||
LIBS += -L$$PWD/../../../AppAlgo/lapWeldDetection/Windows/x64/Release -llapWeldDetection -lbaseAlgorithm
|
||||
|
||||
@ -11,6 +11,7 @@
|
||||
#include <QIntValidator>
|
||||
#include <QLineEdit>
|
||||
#include <QMessageBox>
|
||||
#include <QComboBox>
|
||||
|
||||
#include <cmath>
|
||||
#include <cstring>
|
||||
@ -34,6 +35,10 @@ DialogAlgoArg::DialogAlgoArg(QWidget* parent)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
setWindowTitle(QStringLiteral("焊缝定位 - 算法参数设置"));
|
||||
ui->comboDetectFlawType->addItem(QStringLiteral("未知/全部"), 0);
|
||||
ui->comboDetectFlawType->addItem(QStringLiteral("凹陷"), 1);
|
||||
ui->comboDetectFlawType->addItem(QStringLiteral("凸起"), 2);
|
||||
ui->comboDetectFlawType->addItem(QStringLiteral("凹陷+凸起"), 3);
|
||||
InitNumericEditors();
|
||||
InitCommunicationWidgets();
|
||||
}
|
||||
@ -149,6 +154,9 @@ void DialogAlgoArg::Load()
|
||||
SetDoubleText(ui->editMinLTypeTreeLen, p.treeGrowParam.minLTypeTreeLen);
|
||||
SetDoubleText(ui->editMinVTypeTreeLen, p.treeGrowParam.minVTypeTreeLen);
|
||||
SetIntText(ui->editWeldRefPoints, p.weldSeamParam.weldRefPoints);
|
||||
const int flawType = static_cast<int>(p.weldSeamParam.detectFlawType);
|
||||
const int flawTypeIndex = ui->comboDetectFlawType->findData(flawType);
|
||||
ui->comboDetectFlawType->setCurrentIndex(flawTypeIndex >= 0 ? flawTypeIndex : 0);
|
||||
SetIntText(ui->editTcpPort, config.tcpPort);
|
||||
LoadCommunicationConfig();
|
||||
}
|
||||
@ -225,6 +233,14 @@ bool DialogAlgoArg::Save()
|
||||
p.treeGrowParam.minVTypeTreeLen)) return false;
|
||||
if (!TryGetInt(ui->editWeldRefPoints, QStringLiteral("焊缝中间参考点数"),
|
||||
p.weldSeamParam.weldRefPoints)) return false;
|
||||
const int flawType = ui->comboDetectFlawType->currentData().toInt();
|
||||
if (flawType < static_cast<int>(keWD_FlawType_Uknown) ||
|
||||
flawType > static_cast<int>(keSG_FlawType_Dep_Prot)) {
|
||||
StyledMessageBox::warning(this, QStringLiteral("参数错误"),
|
||||
QStringLiteral("焊缝类型无效。"));
|
||||
return false;
|
||||
}
|
||||
p.weldSeamParam.detectFlawType = static_cast<EWD_FlawType>(flawType);
|
||||
|
||||
int tcpPort = 0;
|
||||
if (!TryGetInt(ui->editTcpPort, QStringLiteral("TCP 服务端口"), tcpPort)) return false;
|
||||
|
||||
@ -140,6 +140,23 @@ QGroupBox::title { subcontrol-origin: margin; left: 10px; padding: 0 3px 0 3px;
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="label_detectFlawType">
|
||||
<property name="text">
|
||||
<string>焊缝类型:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QComboBox" name="comboDetectFlawType">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>200</width>
|
||||
<height>35</height>
|
||||
</size>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
|
||||
@ -9,6 +9,7 @@ struct WeldSeamAlgorithmParams
|
||||
SWD_valleyParam valleyParam{};
|
||||
SSG_treeGrowParam treeGrowParam{};
|
||||
int weldRefPoints = 3;
|
||||
EWD_FlawType detectFlawType = keWD_FlawType_Uknown;
|
||||
};
|
||||
|
||||
class AlgorithmParamConverter
|
||||
|
||||
@ -7,6 +7,7 @@
|
||||
|
||||
#include "VrCommonConfig.h"
|
||||
#include "VrHandEyeCalibConfig.h"
|
||||
#include "SG_baseDataType.h"
|
||||
|
||||
// 参数默认值与 AppAlgo/lapWeldDetection/lapWeldDetection_test.cpp
|
||||
// 中 BQ_thinWeldSeamTest 的 BQ_getWeldSeamPose 调用保持一致。
|
||||
@ -30,6 +31,7 @@ struct VrTreeGrowParam
|
||||
struct VrWeldSeamParam
|
||||
{
|
||||
int weldRefPoints = 3;
|
||||
EWD_FlawType detectFlawType = keWD_FlawType_Uknown;
|
||||
};
|
||||
|
||||
struct VrAlgorithmParams
|
||||
|
||||
@ -14,5 +14,6 @@ WeldSeamAlgorithmParams AlgorithmParamConverter::ToAlgorithmParams(const VrAlgor
|
||||
result.treeGrowParam.minLTypeTreeLen = params.treeGrowParam.minLTypeTreeLen;
|
||||
result.treeGrowParam.minVTypeTreeLen = params.treeGrowParam.minVTypeTreeLen;
|
||||
result.weldRefPoints = params.weldSeamParam.weldRefPoints;
|
||||
result.detectFlawType = params.weldSeamParam.detectFlawType;
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -33,6 +33,12 @@ void LoadAlgorithmParams(XMLElement* algoElement, VrAlgorithmParams& params)
|
||||
|
||||
if (XMLElement* e = algoElement->FirstChildElement("WeldSeamParam")) {
|
||||
e->QueryIntAttribute("weldRefPoints", ¶ms.weldSeamParam.weldRefPoints);
|
||||
int detectFlawType = static_cast<int>(params.weldSeamParam.detectFlawType);
|
||||
if (e->QueryIntAttribute("detectFlawType", &detectFlawType) == XML_SUCCESS &&
|
||||
detectFlawType >= static_cast<int>(keWD_FlawType_Uknown) &&
|
||||
detectFlawType <= static_cast<int>(keSG_FlawType_Dep_Prot)) {
|
||||
params.weldSeamParam.detectFlawType = static_cast<EWD_FlawType>(detectFlawType);
|
||||
}
|
||||
}
|
||||
|
||||
// 解析多相机平面校准参数
|
||||
@ -58,6 +64,8 @@ void SaveAlgorithmParams(XMLDocument& doc, XMLElement* algoElement, const VrAlgo
|
||||
|
||||
XMLElement* weldElement = doc.NewElement("WeldSeamParam");
|
||||
weldElement->SetAttribute("weldRefPoints", params.weldSeamParam.weldRefPoints);
|
||||
weldElement->SetAttribute("detectFlawType",
|
||||
static_cast<int>(params.weldSeamParam.detectFlawType));
|
||||
algoElement->InsertEndChild(weldElement);
|
||||
|
||||
// 多相机平面校准参数
|
||||
|
||||
@ -9,7 +9,7 @@
|
||||
<TreeGrowParam maxLineSkipNum="50" yDeviationMax="1"
|
||||
maxSkipDistance="30" zDeviationMax="5"
|
||||
minLTypeTreeLen="50" minVTypeTreeLen="50"/>
|
||||
<WeldSeamParam weldRefPoints="3"/>
|
||||
<WeldSeamParam weldRefPoints="3" detectFlawType="0"/>
|
||||
<PlaneCalibParams/>
|
||||
</AlgorithmParams>
|
||||
|
||||
|
||||
Binary file not shown.
Binary file not shown.
1137
AppAlgo/lapWeldDetection/Inc/SG_baseAlgo_Export.h
Normal file
1137
AppAlgo/lapWeldDetection/Inc/SG_baseAlgo_Export.h
Normal file
File diff suppressed because it is too large
Load Diff
@ -6,6 +6,14 @@
|
||||
|
||||
#define PI 3.14159265358979323846
|
||||
|
||||
typedef enum
|
||||
{
|
||||
keWD_FlawType_Uknown = 0,
|
||||
keWD_FlawType_Depression, //凹陷
|
||||
keWD_FlawType_Protrusion, //凸起
|
||||
keSG_FlawType_Dep_Prot, //凹陷和凸起混合
|
||||
} EWD_FlawType;
|
||||
|
||||
// 定义欧拉角结构体(单位:度)
|
||||
typedef struct{
|
||||
double roll; // 绕X轴旋转(横滚)
|
||||
@ -90,6 +98,12 @@ typedef struct
|
||||
int end;
|
||||
}SWD_Interval; //区间
|
||||
|
||||
typedef struct SWD_IndexedValue
|
||||
{
|
||||
int idx;
|
||||
double value;
|
||||
}SWD_IndexedValue;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
bool validFlag; //指示结果是否有效
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Loading…
x
Reference in New Issue
Block a user