|

楼主 |
发表于 2025-3-18 14:58:28
|
显示全部楼层
要将 3D 网格路径规划与 VTK 或 Open3D 结合,实现 3D Mesh 和路径可视化,我们可以从以下几个部分展开:
📌 目标
3D Mesh 建模和碰撞检测:生成障碍物和管道的 3D Mesh。
路径规划与弯头调整:结合 A* 算法避障规划路径。
可视化展示:
使用 VTK 或 Open3D 实现 3D Mesh 的渲染与路径展示。
支持 C++ 和 C# 实现。
🔧 方案选择
VTK(Visualization Toolkit)
更适合 C++ 环境,功能丰富,广泛应用于 CAD、医学、BIM 等领域。
Open3D
更适合 Python 和 C#,轻量易用,支持点云、网格的可视化。
📌 方案 1: 使用 VTK 进行 3D Mesh 和路径可视化(C++ 实现)
1. 环境配置
安装 VTK 库:
sudo apt-get install libvtk7-dev
或者在 Windows 上使用 VTK 官方安装包。
CMakeLists.txt 配置:
cmake_minimum_required(VERSION 3.10)
project(BIM_Path_Planning)
find_package(VTK REQUIRED)
include(${VTK_USE_FILE})
add_executable(BIM_Path_Planning main.cpp)
target_link_libraries(BIM_Path_Planning ${VTK_LIBRARIES})
2. 代码实现
main.cpp:包括 3D 网格、A* 路径规划和 VTK 可视化。
#include <vtkSmartPointer.h>
#include <vtkActor.h>
#include <vtkPolyData.h>
#include <vtkPolyDataMapper.h>
#include <vtkRenderer.h>
#include <vtkRenderWindow.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkSphereSource.h>
#include <vtkCubeSource.h>
#include <vtkLineSource.h>
#include <vtkNamedColors.h>
#include <vtkPoints.h>
#include <vtkCellArray.h>
#include <vtkProperty.h>
#include <iostream>
#include <vector>
#include <queue>
#include <cmath>
#include <tuple>
#include <unordered_map>
// 3D 网格路径规划 (A* 实现)
struct Node {
int x, y, z;
double cost, heuristic;
Node *parent;
Node(int _x, int _y, int _z, double _cost, double _heuristic, Node *_parent = nullptr)
: x(_x), y(_y), z(_z), cost(_cost), heuristic(_heuristic), parent(_parent) {}
bool operator<(const Node &other) const {
return (cost + heuristic) > (other.cost + other.heuristic); // 小顶堆
}
};
// 启发式函数(欧氏距离)
double heuristic(int x, int y, int z, int tx, int ty, int tz) {
return std::sqrt(std::pow(tx - x, 2) + std::pow(ty - y, 2) + std::pow(tz - z, 2));
}
// A* 规划路径
std::vector<std::tuple<int, int, int>> a_star_3d(const std::vector<std::vector<std::vector<int>>> &grid,
int sx, int sy, int sz, int gx, int gy, int gz) {
int nx = grid.size(), ny = grid[0].size(), nz = grid[0][0].size();
std::priority_queue<Node> pq;
std::unordered_map<int, Node *> visited;
pq.push(Node(sx, sy, sz, 0, heuristic(sx, sy, sz, gx, gy, gz)));
std::vector<std::tuple<int, int, int>> directions = {
{1, 0, 0}, {-1, 0, 0}, {0, 1, 0}, {0, -1, 0},
{0, 0, 1}, {0, 0, -1}};
while (!pq.empty()) {
Node current = pq.top();
pq.pop();
if (current.x == gx && current.y == gy && current.z == gz) {
std::vector<std::tuple<int, int, int>> path;
Node *node = ¤t;
while (node) {
path.emplace_back(node->x, node->y, node->z);
node = node->parent;
}
std::reverse(path.begin(), path.end());
return path;
}
int index = current.x * ny * nz + current.y * nz + current.z;
visited[index] = new Node(current);
for (const auto &[dx, dy, dz] : directions) {
int nx = current.x + dx;
int ny = current.y + dy;
int nz = current.z + dz;
if (nx < 0 || nx >= grid.size() || ny < 0 || ny >= grid[0].size() ||
nz < 0 || nz >= grid[0][0].size() || grid[nx][ny][nz] == 1)
continue;
double new_cost = current.cost + 1;
double h = heuristic(nx, ny, nz, gx, gy, gz);
if (!visited.count(nx * ny * nz + ny * nz + nz)) {
pq.push(Node(nx, ny, nz, new_cost, h, new Node(current)));
}
}
}
return {};
}
int main() {
vtkSmartPointer<vtkRenderer> renderer = vtkSmartPointer<vtkRenderer>::New();
vtkSmartPointer<vtkRenderWindow> window = vtkSmartPointer<vtkRenderWindow>::New();
window->AddRenderer(renderer);
vtkSmartPointer<vtkRenderWindowInteractor> interactor = vtkSmartPointer<vtkRenderWindowInteractor>::New();
interactor->SetRenderWindow(window);
int nx = 10, ny = 10, nz = 10;
std::vector<std::vector<std::vector<int>>> grid(nx, std::vector<std::vector<int>>(ny, std::vector<int>(nz, 0)));
for (int i = 3; i < 7; ++i)
for (int j = 3; j < 7; ++j)
for (int k = 3; k < 7; ++k)
grid[j][k] = 1;
auto path = a_star_3d(grid, 0, 0, 0, 9, 9, 9);
for (const auto &[x, y, z] : path) {
vtkSmartPointer<vtkSphereSource> sphere = vtkSmartPointer<vtkSphereSource>::New();
sphere->SetCenter(x, y, z);
sphere->SetRadius(0.1);
vtkSmartPointer<vtkPolyDataMapper> mapper = vtkSmartPointer<vtkPolyDataMapper>::New();
mapper->SetInputConnection(sphere->GetOutputPort());
vtkSmartPointer<vtkActor> actor = vtkSmartPointer<vtkActor>::New();
actor->SetMapper(mapper);
actor->GetProperty()->SetColor(0, 1, 0);
renderer->AddActor(actor);
}
renderer->SetBackground(0.1, 0.1, 0.1);
window->Render();
interactor->Start();
return 0;
}
📌 效果展示
绿色小球表示路径点,避开中心障碍。
可调节障碍物大小、起点和终点,实现复杂路径规划。 |
|