catch_dz.cpp

本文展示了一个使用C++编写的简单程序,该程序通过异常处理机制来避免除数为零的情况。当用户输入的除数为零时,程序会捕获并处理这个异常,输出错误信息。

  name="google_ads_frame" marginwidth="0" marginheight="0" src="http://pagead2.googlesyndication.com/pagead/ads?client=ca-pub-5572165936844014&dt=1194442938015&lmt=1194190197&format=336x280_as&output=html&correlator=1194442937843&url=file%3A%2F%2F%2FC%3A%2FDocuments%2520and%2520Settings%2Flhh1%2F%E6%A1%8C%E9%9D%A2%2FCLanguage.htm&color_bg=FFFFFF&color_text=000000&color_link=000000&color_url=FFFFFF&color_border=FFFFFF&ad_type=text&ga_vid=583001034.1194442938&ga_sid=1194442938&ga_hid=1942779085&flash=9&u_h=768&u_w=1024&u_ah=740&u_aw=1024&u_cd=32&u_tz=480&u_java=true" frameborder="0" width="336" scrolling="no" height="280" allowtransparency="allowtransparency"> #include <iostream.h>

void divide(double a, double b)
 {
   try {
      if(!b) throw b;            // checks for divide-by-zero
      cout << "Result: " << a/b << endl;
    }
   catch(double b) {
      cout << "Can't divide by zero." << endl;
    }
 }


void main(void)
 {
   double i, j;

   do {
      cout << "Enter numerator (0 to stop):" << endl;
      cin >> i;
      cout << "Enter denominator: " << endl;
      cin >> j;
      divide (i,j);
    }
   while (i !=0);
  
 }


#include "PointCloudProjection.h" #include <pcl/filters/extract_indices.h> #include <pcl/common/transforms.h> #include <pcl/io/pcd_io.h> #include <fstream> #include <stdexcept> #include <cmath> #include <algorithm> #include <iostream> #include "json.hpp" using json = nlohmann::json; // 移除 using namespace Internal; 避免作用域冲突 // 内部类方法实现(保持不变) std::vector<int> Internal::OrientedBBox::get_points_in_box(const pcl::PointCloud<pcl::PointXYZ>::ConstPtr& cloud) const { std::vector<int> inside_indices; pcl::PointCloud<pcl::PointXYZ>::Ptr transformed_cloud(new pcl::PointCloud<pcl::PointXYZ>()); pcl::transformPointCloud(*cloud, *transformed_cloud, this->transform); constexpr float n = 2.0f; const float half_x = this->extent[0] / 2.0f * n; const float half_y = this->extent[1] / 2.0f * n; const float half_z = this->extent[2] / 2.0f * n; for (size_t i = 0; i < transformed_cloud->points.size(); ++i) { const auto& pt = transformed_cloud->points[i]; if (std::fabs(pt.x) <= half_x && std::fabs(pt.y) <= half_y && std::fabs(pt.z) <= half_z) { inside_indices.push_back(static_cast<int>(i)); } } std::cout << "------------------------》OBB内筛选到的点数量:" << inside_indices.size() << std::endl; return inside_indices; } std::vector<Eigen::Vector3f> Internal::OrientedBBox::get_corners() const { std::vector<Eigen::Vector3f> corners; const Eigen::Vector3f half_ext = this->extent / 2.0f; std::vector<Eigen::Vector3f> local_corners = { {half_ext.x(), half_ext.y(), half_ext.z()}, {half_ext.x(), half_ext.y(), -half_ext.z()}, {half_ext.x(), -half_ext.y(), half_ext.z()}, {half_ext.x(), -half_ext.y(), -half_ext.z()}, {-half_ext.x(), half_ext.y(), half_ext.z()}, {-half_ext.x(), half_ext.y(), -half_ext.z()}, {-half_ext.x(), -half_ext.y(), half_ext.z()}, {-half_ext.x(), -half_ext.y(), -half_ext.z()} }; const Eigen::Affine3f local_to_global = this->transform.inverse(); for (const auto& lc : local_corners) { corners.push_back(local_to_global * lc); } return corners; } Eigen::Matrix3f Internal::OrientedBBox::get_axes() const { return this->transform.inverse().linear(); } Eigen::Affine3f Internal::OrientedBBox::get_global_to_local() const { return this->transform; } Eigen::Affine3f Internal::OrientedBBox::get_local_to_global() const { return this->transform.inverse(); } // 获取指定面的顶点和中心(全局坐标) bool Internal::OrientedBBox::get_face_info(FaceType face, std::vector<Eigen::Vector3f>& out_vertices, Eigen::Vector3f& out_center) const { out_vertices.reserve(4); Eigen::Vector3f half_ext = extent / 2.0f; Eigen::Affine3f local_to_global = get_local_to_global(); // 局部→全局变换 // 局部坐标系下的面顶点(顺时针顺序) std::vector<Eigen::Vector3f> local_vertices; switch (face) { case FaceType::X_POS: local_vertices = { {half_ext.x(), half_ext.y(), half_ext.z()}, {half_ext.x(), half_ext.y(), -half_ext.z()}, {half_ext.x(), -half_ext.y(), -half_ext.z()}, {half_ext.x(), -half_ext.y(), half_ext.z()} }; out_center = local_to_global * Eigen::Vector3f(half_ext.x(), 0, 0); break; case FaceType::Y_POS: local_vertices = { {half_ext.x(), half_ext.y(), half_ext.z()}, {half_ext.x(), half_ext.y(), -half_ext.z()}, {-half_ext.x(), half_ext.y(), -half_ext.z()}, {-half_ext.x(), half_ext.y(), half_ext.z()} }; out_center = local_to_global * Eigen::Vector3f(0, half_ext.y(), 0); break; case FaceType::Z_POS: local_vertices = { {half_ext.x(), half_ext.y(), half_ext.z()}, {half_ext.x(), -half_ext.y(), half_ext.z()}, {-half_ext.x(), -half_ext.y(), half_ext.z()}, {-half_ext.x(), half_ext.y(), half_ext.z()} }; out_center = local_to_global * Eigen::Vector3f(0, 0, half_ext.z()); break; default: return false; } // 转换到全局坐标 for (const auto& lv : local_vertices) { out_vertices.push_back(local_to_global * lv); } return true; } // 获取面的局部坐标系(u:面内X轴, v:面内Y轴, n:法向量)- 内联实现 bool Internal::OrientedBBox::get_face_local_axes(FaceType face, Eigen::Vector3f& out_u, Eigen::Vector3f& out_v, Eigen::Vector3f& out_n) const { std::vector<Eigen::Vector3f> vertices; Eigen::Vector3f face_center; if (!get_face_info(face, vertices, face_center)) { return false; } // 计算法向量n(面的外法线,单位向量) Eigen::Vector3f v1 = vertices[1] - vertices[0]; Eigen::Vector3f v2 = vertices[2] - vertices[0]; out_n = v1.cross(v2).normalized(); if (out_n.norm() < 1e-6f) { return false; // 面退化(非平面) } // 计算面内X轴u(从面中心到第一个顶点,投影到面内) Eigen::Vector3f center_to_v0 = vertices[0] - face_center; out_u = center_to_v0 - (center_to_v0.dot(out_n)) * out_n; // 去除法向分量 out_u.normalize(); if (out_u.norm() < 1e-6f) { // 退化处理 out_u = Eigen::Vector3f::UnitX(); if (std::fabs(out_u.dot(out_n)) > 0.9f) { out_u = Eigen::Vector3f::UnitY(); } out_u -= (out_u.dot(out_n)) * out_n; // 确保在面内 out_u.normalize(); } // 计算面内Y轴v(n × u,确保正交) out_v = out_n.cross(out_u).normalized(); return true; } // 绕面的法向量旋转(左旋转为正角度,右旋转为负角度)- 内联实现 Internal::OrientedBBox Internal::OrientedBBox::rotate_around_face_normal(FaceType face, float theta_deg) const { Eigen::Vector3f u, v, n; if (!get_face_local_axes(face, u, v, n)) { throw std::runtime_error("获取面坐标系失败,无法旋转"); } // 角度转换(左旋转+θ,右旋转-θ) float theta = theta_deg * M_PI / 180.0f; // 构建局部→全局转换矩阵M(u, v, n为列向量) Eigen::Matrix3f M; M.col(0) = u; M.col(1) = v; M.col(2) = n; // 局部坐标系下绕Z轴旋转的矩阵(显式转换为旋转矩阵) Eigen::Vector3f z_axis(0.0f, 0.0f, 1.0f); // Z轴向量 Eigen::AngleAxisf angle_axis(theta, z_axis); // 角度轴 Eigen::Matrix3f Rz = angle_axis.toRotationMatrix(); // 显式转换为3x3旋转矩阵 // 全局旋转矩阵 = M * Rz * M^T Eigen::Matrix3f R = M * Rz * M.transpose(); // 计算新的旋转矩阵 Eigen::Matrix3f current_rot = transform.inverse().linear(); Eigen::Matrix3f new_rot = R * current_rot; // 构建新的变换矩阵 Eigen::Affine3f new_local_to_global = Eigen::Affine3f::Identity(); new_local_to_global.rotate(new_rot); new_local_to_global.translate(center); // 新的全局→局部变换矩阵 Eigen::Affine3f new_transform = new_local_to_global.inverse(); // 打印new_transform的内容(旋转矩阵 + 平移向量) std::cout << "===== 新的全局→局部变换矩阵 (new_transform) =====" << std::endl; std::cout << "旋转部分(线性矩阵):" << std::endl << new_transform.linear() << std::endl; std::cout << "平移部分:" << new_transform.translation().transpose() << std::endl << std::endl; return OrientedBBox(center, extent, new_transform.inverse()); } // 内部工具函数实现(显式指定Internal::命名空间) Internal::OrientedBBox Internal::parse_obb(const std::vector<ObbData>& obb_data) { Internal::OrientedBBox obb; for (const auto& data : obb_data) { if (data.obj_type == "负防区") { continue; } const Eigen::Vector3f center(data.pos_x, data.pos_y, data.pos_z); const Eigen::Vector3f dimensions( std::fabs(data.scale_x), std::fabs(data.scale_y), std::fabs(data.scale_z) ); Eigen::Affine3f transform_to_local = Eigen::Affine3f::Identity(); transform_to_local.rotate(Eigen::AngleAxisf(data.rot_x, Eigen::Vector3f::UnitX())); transform_to_local.rotate(Eigen::AngleAxisf(data.rot_y, Eigen::Vector3f::UnitY())); transform_to_local.rotate(Eigen::AngleAxisf(data.rot_z, Eigen::Vector3f::UnitZ())); obb = Internal::OrientedBBox(center, dimensions, transform_to_local); break; } return obb; } cv::Mat Internal::gen_proj_internal( const pcl::PointCloud<pcl::PointXYZ>::ConstPtr& local_cloud, const Internal::OrientedBBox& obb, const Eigen::Vector3f& cam_pos, std::vector<cv::Point>& out_corners, cv::Point& out_center, float cam_rot_deg) { const cv::Size img_size(1280, 640); cv::Mat img(img_size, CV_8UC3, cv::Scalar(0, 0, 0)); const Eigen::Vector3f local_obb_center(0.0f, 0.0f, 0.0f); // OBB在局部坐标系的中心 // 1. 计算投影方向和相机坐标系 Eigen::Vector3f proj_dir = local_obb_center - cam_pos; const float dir_len = proj_dir.norm(); if (dir_len < 1e-6f) { proj_dir = Eigen::Vector3f::UnitZ(); // 避免除以零 } else { proj_dir.normalize(); } const Eigen::Vector3f world_up(0.0f, 0.0f, 1.0f); Eigen::Vector3f proj_x = world_up.cross(proj_dir); if (proj_x.norm() < 1e-6f) { proj_x = Eigen::Vector3f::UnitX(); // 避免退化 } else { proj_x.normalize(); } Eigen::Vector3f proj_y = proj_dir.cross(proj_x); proj_y.normalize(); // 2. 计算点云的投影坐标(用于绘制点) std::vector<Eigen::Vector3f> proj_pts; proj_pts.reserve(local_cloud->size()); Eigen::Matrix3f rotation = Eigen::Matrix3f::Identity(); if (std::fabs(cam_rot_deg) > 1e-6f) { const float angle_rad = cam_rot_deg * M_PI / 180.0f; rotation << std::cos(angle_rad), -std::sin(angle_rad), 0.0f, std::sin(angle_rad), std::cos(angle_rad), 0.0f, 0.0f, 0.0f, 1.0f; } for (const auto& pt : local_cloud->points) { const Eigen::Vector3f pt_eigen(pt.x, pt.y, pt.z); const Eigen::Vector3f pt_cam = pt_eigen - cam_pos; Eigen::Vector3f temp_point( pt_cam.dot(proj_x), pt_cam.dot(proj_y), pt_cam.dot(proj_dir) ); if (std::fabs(cam_rot_deg) > 1e-6f) { temp_point = rotation * temp_point; } proj_pts.push_back(temp_point); } // 3. 计算OBB角点的投影坐标(用于计算缩放比例和绘制边框) const Eigen::Vector3f half_ext = obb.extent / 2.0f; std::vector<Eigen::Vector3f> local_corners = { {half_ext.x(), half_ext.y(), half_ext.z()}, {half_ext.x(), half_ext.y(), -half_ext.z()}, {half_ext.x(), -half_ext.y(), half_ext.z()}, {half_ext.x(), -half_ext.y(), -half_ext.z()}, {-half_ext.x(), half_ext.y(), half_ext.z()}, {-half_ext.x(), half_ext.y(), -half_ext.z()}, {-half_ext.x(), -half_ext.y(), half_ext.z()}, {-half_ext.x(), -half_ext.y(), -half_ext.z()} }; std::vector<Eigen::Vector3f> corner_proj; for (const auto& corner : local_corners) { const Eigen::Vector3f corner_cam = corner - cam_pos; Eigen::Vector3f temp_point( corner_cam.dot(proj_x), corner_cam.dot(proj_y), corner_cam.dot(proj_dir) ); if (std::fabs(cam_rot_deg) > 1e-6f) { temp_point = rotation * temp_point; } corner_proj.push_back(temp_point); } // 4. 关键修改:用OBB角点的投影范围计算缩放比例(确保同一OBB大小一致) float obb_x_min = 1e9f, obb_x_max = -1e9f; float obb_y_min = 1e9f, obb_y_max = -1e9f; for (const auto& cp : corner_proj) { obb_x_min = std::min(obb_x_min, cp.x()); obb_x_max = std::max(obb_x_max, cp.x()); obb_y_min = std::min(obb_y_min, cp.y()); obb_y_max = std::max(obb_y_max, cp.y()); } const float obb_max_range = std::max(obb_x_max - obb_x_min, obb_y_max - obb_y_min); const float safe_obb_range = (obb_max_range < 1e-6f) ? 1e-6f : obb_max_range; const float scale = std::min(img_size.width, img_size.height) * 0.8f / safe_obb_range; // 0.8是预留边距(避免OBB边缘超出图像),可根据需要调整 // 5. 投影中心与OBB中心对齐(确保OBB在图像中居中) Eigen::Vector3f center_cam = local_obb_center - cam_pos; Eigen::Vector3f proj_center( center_cam.dot(proj_x), center_cam.dot(proj_y), center_cam.dot(proj_dir) ); if (std::fabs(cam_rot_deg) > 1e-6f) { proj_center = rotation * proj_center; } const cv::Point img_center(img_size.width / 2, img_size.height / 2); // 6. 绘制点云 for (const auto& p : proj_pts) { const int x = static_cast<int>(img_center.x + (p.x() - proj_center.x()) * scale); const int y = static_cast<int>(img_center.y - (p.y() - proj_center.y()) * scale); const int clamped_x = std::clamp(x, 0, img_size.width - 1); const int clamped_y = std::clamp(y, 0, img_size.height - 1); cv::drawMarker(img, cv::Point(clamped_x, clamped_y), cv::Scalar(255, 255, 255), 1, // marker大小 1); // 线宽 } // 7. 处理OBB角点并绘制边框 std::vector<int> corner_indices = {0, 1, 2, 3, 4, 5, 6, 7}; // 按Z轴(深度)排序,只保留前4个可见角点 std::sort(corner_indices.begin(), corner_indices.end(), [&](int a, int b) { return corner_proj[a].z() > corner_proj[b].z(); }); corner_indices.resize(4); // 按角度排序,确保边框绘制顺序正确 Eigen::Vector3f centroid(0.0f, 0.0f, 0.0f); for (int idx : corner_indices) { centroid += corner_proj[idx]; } centroid /= 4.0f; std::sort(corner_indices.begin(), corner_indices.end(), [&](int a, int b) { const float ang_a = std::atan2(corner_proj[a].y() - centroid.y(), corner_proj[a].x() - centroid.x()); const float ang_b = std::atan2(corner_proj[b].y() - centroid.y(), corner_proj[b].x() - centroid.x()); return ang_a < ang_b; }); // 映射角点到图像坐标 out_corners.clear(); for (int idx : corner_indices) { const int x = static_cast<int>(img_center.x + (corner_proj[idx].x() - proj_center.x()) * scale); const int y = static_cast<int>(img_center.y - (corner_proj[idx].y() - proj_center.y()) * scale); out_corners.emplace_back(std::clamp(x, 0, img_size.width - 1), std::clamp(y, 0, img_size.height - 1)); } // 绘制OBB边框 for (size_t i = 0; i < 4; ++i) { cv::line(img, out_corners[i], out_corners[(i + 1) % 4], cv::Scalar(0, 255, 0), 2, cv::LINE_AA); } // 8. 绘制OBB中心点(红点) Eigen::Vector3f temp_center = proj_center; // 已与OBB中心对齐 const int cx = static_cast<int>(img_center.x + (temp_center.x() - proj_center.x()) * scale); const int cy = static_cast<int>(img_center.y - (temp_center.y() - proj_center.y()) * scale); out_center = cv::Point(std::clamp(cx, 0, img_size.width - 1), std::clamp(cy, 0, img_size.height - 1)); cv::circle(img, out_center, 5, cv::Scalar(0, 0, 255), -1); return img; } // 内存级接口实现(调用内部函数时显式指定Internal::) int get_proj_results( const pcl::PointCloud<pcl::PointXYZ>::ConstPtr& cloud, const std::vector<ObbData>& obb_data, ProjResult* results, bool use_all_points) { try { if (!cloud || cloud->empty()) return -1; if (obb_data.empty()) return -2; if (!results) return -3; // 显式调用Internal::parse_obb const Internal::OrientedBBox obb = Internal::parse_obb(obb_data); if (obb.extent.norm() < 1e-6f) return -4; pcl::PointCloud<pcl::PointXYZ>::Ptr processed_cloud; if (use_all_points) { processed_cloud = cloud->makeShared(); } else { const std::vector<int> in_obb_indices = obb.get_points_in_box(cloud); std::cout << "------------------------???" << in_obb_indices.size() << std::endl; if (in_obb_indices.empty()) return -5; pcl::PointCloud<pcl::PointXYZ>::Ptr in_obb_pcd(new pcl::PointCloud<pcl::PointXYZ>()); pcl::ExtractIndices<pcl::PointXYZ> extractor; pcl::PointIndices::Ptr inliers(new pcl::PointIndices()); inliers->indices = in_obb_indices; extractor.setInputCloud(cloud); extractor.setIndices(inliers); extractor.setNegative(false); extractor.filter(*in_obb_pcd); processed_cloud = in_obb_pcd; } pcl::PointCloud<pcl::PointXYZ>::Ptr local_cloud(new pcl::PointCloud<pcl::PointXYZ>()); pcl::transformPointCloud(*processed_cloud, *local_cloud, obb.get_global_to_local()); const Eigen::Vector3f half_ext = obb.extent / 2.0f; const float cam_distance = 15.0f; const std::vector<Eigen::Vector3f> cam_positions = { {half_ext.x() + cam_distance, 0.0f, 0.0f}, {0.0f, half_ext.y() + cam_distance, 0.0f}, {0.0f, 0.0f, half_ext.z() + cam_distance} }; const float cam_rotations[] = {0.0f, 0.0f, 90.0f}; for (size_t i = 0; i < 3; ++i) { std::vector<cv::Point> obb_corners; cv::Point obb_center; // 显式调用Internal::gen_proj_internal const cv::Mat proj_img = Internal::gen_proj_internal( local_cloud, obb, cam_positions[i], obb_corners, obb_center, cam_rotations[i] ); if (proj_img.empty()) return -6; results[i].img = proj_img.clone(); results[i].obb_corners = obb_corners; results[i].obb_center = obb_center; } return 0; } catch (...) { return -99; } } // 文件级接口实现 int gen_proj_images( const char* pcd_path, const char* json_path, bool use_all_points) { try { if (!pcd_path || !json_path || strlen(pcd_path) == 0 || strlen(json_path) == 0) return -1; if (!std::ifstream(pcd_path).good()) return -2; if (!std::ifstream(json_path).good()) return -3; pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZ>()); if (pcl::io::loadPCDFile<pcl::PointXYZ>(pcd_path, *cloud) == -1) return -4; if (cloud->empty()) return -5; std::vector<ObbData> obb_data_list; json j; std::ifstream json_file(json_path); json_file >> j; json obb_json_array; if (j.is_object()) { obb_json_array.push_back(j); } else if (j.is_array()) { obb_json_array = j; } else { return -6; } for (const auto& item : obb_json_array) { ObbData obb_data; obb_data.pos_x = item.at("position").at("x").get<float>(); obb_data.pos_y = item.at("position").at("y").get<float>(); obb_data.pos_z = item.at("position").at("z").get<float>(); obb_data.rot_x = item.at("rotation").at("x").get<float>(); obb_data.rot_y = item.at("rotation").at("y").get<float>(); obb_data.rot_z = item.at("rotation").at("z").get<float>(); obb_data.scale_x = item.at("scale").at("x").get<float>(); obb_data.scale_y = item.at("scale").at("y").get<float>(); obb_data.scale_z = item.at("scale").at("z").get<float>(); obb_data.obj_type = item.value("obj_type", ""); obb_data_list.push_back(obb_data); } ProjResult results[3]; int ret = get_proj_results(cloud, obb_data_list, results, use_all_points); if (ret != 0) return ret; const std::string save_paths[3] = { "OBB_Local_X+_View_Original.png", "OBB_Local_Y+_View_Original.png", "OBB_Local_Z+_View_Rotated90deg.png" }; for (size_t i = 0; i < 3; ++i) { if (!cv::imwrite(save_paths[i], results[i].img)) { free_proj_results(results); return -7; } } free_proj_results(results); return 0; } catch (...) { return -99; } } // 内存释放接口 void free_proj_results(ProjResult* results) { if (results) { for (int i = 0; i < 3; ++i) { results[i].img.release(); results[i].obb_corners.clear(); } } } 这个代码还是会导致boxwidget 变形
10-26
#include <rclcpp/rclcpp.hpp> #include <sensor_msgs/msg/point_cloud2.hpp> #include <visualization_msgs/msg/marker_array.hpp> #include <pcl_conversions/pcl_conversions.h> #include <pcl/point_cloud.h> #include <pcl/point_types.h> #include <pcl/common/common.h> #include <pcl/search/kdtree.h> #include <pcl/filters/filter.h> #include <pcl/filters/voxel_grid.h> #include <pcl/filters/passthrough.h> #include <chrono> #include <iostream> #include <vector> #include <cmath> #include <iomanip> #include <sstream> #include <memory> #include <queue> #include <unordered_set> // 边界框结构体 struct Box { float x_min; float y_min; float z_min; float x_max; float y_max; float z_max; }; // 锥桶信息结构体 struct Cone { pcl::PointXYZ center; float height; float width; float confidence; int id; std::string type; }; // 自定义点云有效性检查函数 template<typename PointT> bool isPointFinite(const PointT& point) { return std::isfinite(point.x) && std::isfinite(point.y) && std::isfinite(point.z); } // 点云处理模板类 template<typename PointT> class ProcessPointClouds { public: // 自定义欧式距离聚类算法 std::vector<typename pcl::PointCloud<PointT>::Ptr> EuclideanClustering(typename pcl::PointCloud<PointT>::Ptr cloud, float clusterTolerance, int minSize, int maxSize) { auto startTime = std::chrono::steady_clock::now(); std::vector<typename pcl::PointCloud<PointT>::Ptr> clusters; std::cout << "=== 欧式距离聚类开始 ===" << std::endl; std::cout << "输入点云数量: " << cloud->size() << std::endl; std::cout << "聚类参数: 距离容忍度=" << clusterTolerance << ", 最小尺寸=" << minSize << ", 最大尺寸=" << maxSize << std::endl; // 检查点云是否为空 if (cloud->empty()) { std::cout << "点云为空,无法进行聚类" << std::endl; return clusters; } // 创建KdTree用于加速近邻搜索 typename pcl::search::KdTree<PointT>::Ptr tree(new pcl::search::KdTree<PointT>); try { auto filtered_cloud = RemoveNaNPoints(cloud); tree->setInputCloud(filtered_cloud); std::cout << "KdTree构建成功" << std::endl; } catch (const std::exception& e) { std::cout << "KdTree构建失败: " << e.what() << std::endl; return clusters; } // 标记已访问的点 std::vector<bool> processed(cloud->points.size(), false); int total_clusters_found = 0; int skipped_clusters = 0; // 对每个点进行聚类 for (size_t i = 0; i < cloud->points.size(); ++i) { // 跳过已处理或无效的点 if (processed[i] || !isPointFinite(cloud->points[i])) { continue; } // 创建新的聚类 std::vector<int> cluster_indices; std::queue<int> points_queue; // 将当前点加入队列 points_queue.push(i); processed[i] = true; // 区域生长聚类 while (!points_queue.empty()) { // 获取队列中的点 int current_index = points_queue.front(); points_queue.pop(); cluster_indices.push_back(current_index); // 搜索近邻点 std::vector<int> neighbor_indices; std::vector<float> neighbor_distances; if (tree->radiusSearch(cloud->points[current_index], clusterTolerance, neighbor_indices, neighbor_distances) > 0) { for (const auto& neighbor_index : neighbor_indices) { if (!processed[neighbor_index] && isPointFinite(cloud->points[neighbor_index])) { processed[neighbor_index] = true; points_queue.push(neighbor_index); } } } } // 检查聚类尺寸是否在范围内 size_t cluster_size = cluster_indices.size(); total_clusters_found++; if (cluster_size >= static_cast<size_t>(minSize) && cluster_size <= static_cast<size_t>(maxSize)) { // 创建聚类点云 typename pcl::PointCloud<PointT>::Ptr cluster_cloud(new pcl::PointCloud<PointT>); for (const auto& index : cluster_indices) { cluster_cloud->points.push_back(cloud->points[index]); } cluster_cloud->width = cluster_cloud->points.size(); cluster_cloud->height = 1; cluster_cloud->is_dense = true; clusters.push_back(cluster_cloud); std::cout << "聚类 " << clusters.size() << ": " << cluster_cloud->size() << " 个点" << std::endl; } else { skipped_clusters++; if (cluster_size < static_cast<size_t>(minSize)) { std::cout << "跳过小聚类: " << cluster_size << " 个点 (小于 " << minSize << ")" << std::endl; } else { std::cout << "跳过大聚类: " << cluster_size << " 个点 (大于 " << maxSize << ")" << std::endl; } } } auto endTime = std::chrono::steady_clock::now(); auto elapsedTime = std::chrono::duration_cast<std::chrono::milliseconds>(endTime - startTime); std::cout << "欧式距离聚类完成,耗时 " << elapsedTime.count() << " 毫秒,找到 " << clusters.size() << " 个有效聚类 (" << skipped_clusters << " 个被跳过,总共 " << total_clusters_found << " 个聚类)" << std::endl; return clusters; } // 计算两个点之间的欧式距离 float EuclideanDistance(const PointT& point1, const PointT& point2) { float dx = point1.x - point2.x; float dy = point1.y - point2.y; float dz = point1.z - point2.z; return std::sqrt(dx*dx + dy*dy + dz*dz); } // 计算边界框 Box BoundingBox(typename pcl::PointCloud<PointT>::Ptr cluster) { PointT minPoint, maxPoint; pcl::getMinMax3D(*cluster, minPoint, maxPoint); Box box; box.x_min = minPoint.x; box.y_min = minPoint.y; box.z_min = minPoint.z; box.x_max = maxPoint.x; box.y_max = maxPoint.y; box.z_max = maxPoint.z; return box; } // 过滤无效点 typename pcl::PointCloud<PointT>::Ptr RemoveNaNPoints(typename pcl::PointCloud<PointT>::Ptr cloud) { typename pcl::PointCloud<PointT>::Ptr filtered_cloud(new pcl::PointCloud<PointT>); std::vector<int> indices; pcl::removeNaNFromPointCloud(*cloud, *filtered_cloud, indices); std::cout << "过滤掉 " << (cloud->size() - filtered_cloud->size()) << " 个无效点,剩余 " << filtered_cloud->size() << " 个有效点" << std::endl; return filtered_cloud; } // 降采样点云 typename pcl::PointCloud<PointT>::Ptr DownsampleCloud(typename pcl::PointCloud<PointT>::Ptr cloud, float leaf_size) { typename pcl::PointCloud<PointT>::Ptr downsampled_cloud(new pcl::PointCloud<PointT>); pcl::VoxelGrid<PointT> voxel_grid; voxel_grid.setInputCloud(cloud); voxel_grid.setLeafSize(leaf_size, leaf_size, leaf_size); voxel_grid.filter(*downsampled_cloud); std::cout << "降采样后点云: " << cloud->size() << " -> " << downsampled_cloud->size() << " 个点" << std::endl; return downsampled_cloud; } // 直通滤波 typename pcl::PointCloud<PointT>::Ptr PassThroughFilter(typename pcl::PointCloud<PointT>::Ptr cloud, const std::string& field, float min_limit, float max_limit) { typename pcl::PointCloud<PointT>::Ptr filtered_cloud(new pcl::PointCloud<PointT>); pcl::PassThrough<PointT> pass; pass.setInputCloud(cloud); pass.setFilterFieldName(field); pass.setFilterLimits(min_limit, max_limit); pass.filter(*filtered_cloud); std::cout << "直通滤波(" << field << "): " << cloud->size() << " -> " << filtered_cloud->size() << " 个点, 范围[" << min_limit << ", " << max_limit << "]" << std::endl; return filtered_cloud; } // 锥桶识别函数 std::vector<Cone> DetectCones(typename pcl::PointCloud<PointT>::Ptr cloud, float min_height = 0.05, float max_height = 0.5, float min_width = 0.05, float max_width = 0.25, float height_to_width_ratio_min = 0.8, float height_to_width_ratio_max = 5.0) { std::vector<Cone> cones; std::cout << "=== 锥桶识别开始 ===" << std::endl; std::cout << "锥桶识别参数: 高度[" << min_height << ", " << max_height << "], 宽度[" << min_width << ", " << max_width << "], 高宽比[" << height_to_width_ratio_min << ", " << height_to_width_ratio_max << "]" << std::endl; // 使用欧式距离聚类 auto clusters = EuclideanClustering(cloud, 0.15, 10, 1000); int cone_id = 0; int potential_cones = 0; for (size_t i = 0; i < clusters.size(); ++i) { auto cluster = clusters[i]; // 计算边界框 Box box = BoundingBox(cluster); float height = box.z_max - box.z_min; float width_x = box.x_max - box.x_min; float width_y = box.y_max - box.y_min; float width = std::max(width_x, width_y); // 计算高度与宽度的比例 float height_to_width_ratio = (width > 0) ? height / width : 0; // 计算中心点 pcl::PointXYZ center; center.x = (box.x_min + box.x_max) / 2.0; center.y = (box.y_min + box.y_max) / 2.0; center.z = (box.z_min + box.z_max) / 2.0; // 计算置信度 float confidence = 0.0; // 检查尺寸是否符合锥桶特征 bool height_ok = (height >= min_height && height <= max_height); bool width_ok = (width >= min_width && width <= max_width); bool ratio_ok = (height_to_width_ratio >= height_to_width_ratio_min && height_to_width_ratio <= height_to_width_ratio_max); std::cout << "聚类 " << i << " 分析: " << std::endl; std::cout << " - 位置: (" << std::fixed << std::setprecision(2) << center.x << ", " << center.y << ", " << center.z << ")" << std::endl; std::cout << " - 尺寸: 高度=" << height << "m, 宽度=" << width << "m, 高宽比=" << height_to_width_ratio << std::endl; std::cout << " - 检查结果: 高度" << (height_ok ? "✓" : "✗") << " 宽度" << (width_ok ? "✓" : "✗") << " 高宽比" << (ratio_ok ? "✓" : "✗") << std::endl; if (height_ok && width_ok && ratio_ok) { potential_cones++; // 计算置信度 confidence = 0.7f; // 基础置信度 if (height_ok) confidence += 0.1f; if (width_ok) confidence += 0.1f; if (ratio_ok) confidence += 0.1f; // 确保置信度不超过1.0 confidence = std::min(confidence, 1.0f); Cone cone; cone.center = center; cone.height = height; cone.width = width; cone.confidence = confidence; cone.id = cone_id++; cone.type = "unknown"; cones.push_back(cone); std::cout << ">>> 识别为锥桶 #" << cone.id << " 置信度: " << confidence << std::endl; } else { std::cout << ">>> 未识别为锥桶" << std::endl; } } std::cout << "锥桶识别完成,共检测到 " << cones.size() << " 个锥桶 (" << potential_cones << " 个潜在锥桶)" << std::endl; return cones; } }; // 主要的ROS2节点类 class EuclideanClusteringNode : public rclcpp::Node { public: EuclideanClusteringNode() : Node("euclidean_clustering_node") { // 声明参数 - 使用更宽松的默认值 this->declare_parameter("cluster_tolerance", 0.09); this->declare_parameter("min_cluster_size", 10); this->declare_parameter("max_cluster_size", 200); this->declare_parameter("downsample_leaf_size", 0.03f); this->declare_parameter("enable_downsampling", false); // 锥桶识别参数 - 放宽条件 this->declare_parameter("cone_min_height", 0.0); this->declare_parameter("cone_max_height", 0.8); this->declare_parameter("cone_min_width", 0.0); this->declare_parameter("cone_max_width", 6.0); this->declare_parameter("cone_min_ratio", 0.0); this->declare_parameter("cone_max_ratio", 6.0); this->declare_parameter("cone_confidence_threshold", 0.3); // 直通滤波参数 this->declare_parameter("enable_passthrough", false); this->declare_parameter("passthrough_x_min", -10.0); this->declare_parameter("passthrough_x_max", 10.0); this->declare_parameter("passthrough_y_min", -10.0); this->declare_parameter("passthrough_y_max", 10.0); this->declare_parameter("passthrough_z_min", -0.5); this->declare_parameter("passthrough_z_max", 2.0); // 创建订阅者 subscription_ = this->create_subscription<sensor_msgs::msg::PointCloud2>( "/filtered_pointcloud", 10, std::bind(&EuclideanClusteringNode::pointcloud_callback, this, std::placeholders::_1)); // 创建发布者 cluster_pub_ = this->create_publisher<sensor_msgs::msg::PointCloud2>("clustering_results/clusters", 10); cone_pub_ = this->create_publisher<sensor_msgs::msg::PointCloud2>("clustering_results/cones", 10); marker_pub_ = this->create_publisher<visualization_msgs::msg::MarkerArray>("clustering_results/markers", 10); marker_id_counter_ = 0; RCLCPP_INFO(this->get_logger(), "欧式距离聚类节点已初始化"); } private: void debug_pointcloud_stats(pcl::PointCloud<pcl::PointXYZ>::Ptr cloud, const std::string& name) { if (cloud->empty()) { std::cout << name << ": 空点云" << std::endl; return; } pcl::PointXYZ min_pt, max_pt; pcl::getMinMax3D(*cloud, min_pt, max_pt); std::cout << name << "统计:" << std::endl; std::cout << " - 点数: " << cloud->size() << std::endl; std::cout << " - 范围 X: " << min_pt.x << " 到 " << max_pt.x << std::endl; std::cout << " - 范围 Y: " << min_pt.y << " 到 " << max_pt.y << std::endl; std::cout << " - 范围 Z: " << min_pt.z << " 到 " << max_pt.z << std::endl; // 统计有效点 int valid_points = 0; for (const auto& point : cloud->points) { if (isPointFinite(point)) valid_points++; } std::cout << " - 有效点: " << valid_points << "/" << cloud->size() << std::endl; } void pointcloud_callback(const sensor_msgs::msg::PointCloud2::SharedPtr msg) { auto start_time = std::chrono::steady_clock::now(); std::cout << "\n\n=== 收到新点云 ===" << std::endl; std::cout << "时间戳: " << msg->header.stamp.sec << "." << msg->header.stamp.nanosec << std::endl; std::cout << "坐标系: " << msg->header.frame_id << std::endl; // 转换点云格式 pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZ>); pcl::fromROSMsg(*msg, *cloud); debug_pointcloud_stats(cloud, "原始点云"); if (cloud->empty()) { RCLCPP_WARN(this->get_logger(), "收到空点云"); return; } // 获取参数 float cluster_tolerance = this->get_parameter("cluster_tolerance").as_double(); int min_cluster_size = this->get_parameter("min_cluster_size").as_int(); int max_cluster_size = this->get_parameter("max_cluster_size").as_int(); float downsample_leaf_size = this->get_parameter("downsample_leaf_size").as_double(); bool enable_downsampling = this->get_parameter("enable_downsampling").as_bool(); // 获取锥桶识别参数 float cone_min_height = this->get_parameter("cone_min_height").as_double(); float cone_max_height = this->get_parameter("cone_max_height").as_double(); float cone_min_width = this->get_parameter("cone_min_width").as_double(); float cone_max_width = this->get_parameter("cone_max_width").as_double(); float cone_min_ratio = this->get_parameter("cone_min_ratio").as_double(); float cone_max_ratio = this->get_parameter("cone_max_ratio").as_double(); float cone_confidence_threshold = this->get_parameter("cone_confidence_threshold").as_double(); // 获取直通滤波参数 bool enable_passthrough = this->get_parameter("enable_passthrough").as_bool(); float passthrough_x_min = this->get_parameter("passthrough_x_min").as_double(); float passthrough_x_max = this->get_parameter("passthrough_x_max").as_double(); float passthrough_y_min = this->get_parameter("passthrough_y_min").as_double(); float passthrough_y_max = this->get_parameter("passthrough_y_max").as_double(); float passthrough_z_min = this->get_parameter("passthrough_z_min").as_double(); float passthrough_z_max = this->get_parameter("passthrough_z_max").as_double(); // 打印实际使用的参数 std::cout << "使用参数:" << std::endl; std::cout << " - 聚类: 容差=" << cluster_tolerance << ", 最小=" << min_cluster_size << ", 最大=" << max_cluster_size << std::endl; std::cout << " - 锥桶: 高度[" << cone_min_height << ", " << cone_max_height << "], 宽度[" << cone_min_width << ", " << cone_max_width << "], 高宽比[" << cone_min_ratio << ", " << cone_max_ratio << "]" << std::endl; // 创建点云处理器 ProcessPointClouds<pcl::PointXYZ> processor; // 1. 预处理:移除无效点 auto filtered_cloud = processor.RemoveNaNPoints(cloud); debug_pointcloud_stats(filtered_cloud, "过滤后点云"); if (filtered_cloud->empty()) { RCLCPP_WARN(this->get_logger(), "过滤后点云为空"); return; } // 2. 可选:直通滤波(限制感兴趣区域) pcl::PointCloud<pcl::PointXYZ>::Ptr processed_cloud = filtered_cloud; if (enable_passthrough) { std::cout << "应用直通滤波..." << std::endl; // X方向滤波 processed_cloud = processor.PassThroughFilter(processed_cloud, "x", passthrough_x_min, passthrough_x_max); debug_pointcloud_stats(processed_cloud, "X方向滤波后"); // Y方向滤波 processed_cloud = processor.PassThroughFilter(processed_cloud, "y", passthrough_y_min, passthrough_y_max); debug_pointcloud_stats(processed_cloud, "Y方向滤波后"); // Z方向滤波 processed_cloud = processor.PassThroughFilter(processed_cloud, "z", passthrough_z_min, passthrough_z_max); debug_pointcloud_stats(processed_cloud, "Z方向滤波后"); } // 3. 可选:降采样点云 if (enable_downsampling) { processed_cloud = processor.DownsampleCloud(processed_cloud, downsample_leaf_size); debug_pointcloud_stats(processed_cloud, "降采样后点云"); } if (processed_cloud->empty()) { RCLCPP_WARN(this->get_logger(), "处理后的点云为空"); return; } // 4. 欧式距离聚类 auto clusters = processor.EuclideanClustering(processed_cloud, cluster_tolerance, min_cluster_size, max_cluster_size); std::cout << "聚类结果: " << clusters.size() << " 个聚类" << std::endl; for (size_t i = 0; i < clusters.size(); ++i) { Box box = processor.BoundingBox(clusters[i]); std::cout << " 聚类 " << i << ": " << clusters[i]->size() << " 个点, " << "位置(" << std::fixed << std::setprecision(2) << (box.x_min + box.x_max)/2 << ", " << (box.y_min + box.y_max)/2 << ", " << (box.z_min + box.z_max)/2 << ")" << std::endl; } // 5. 锥桶识别 auto cones = processor.DetectCones(processed_cloud, cone_min_height, cone_max_height, cone_min_width, cone_max_width, cone_min_ratio, cone_max_ratio); // 6. 创建可视化结果 visualization_msgs::msg::MarkerArray all_markers; pcl::PointCloud<pcl::PointXYZRGB>::Ptr colored_clusters_cloud(new pcl::PointCloud<pcl::PointXYZRGB>); pcl::PointCloud<pcl::PointXYZRGB>::Ptr cone_cloud(new pcl::PointCloud<pcl::PointXYZRGB>); // 预定义颜色 - 紫色用于聚类点云 std::vector<uint8_t> purple_color = {128, 0, 128}; // 紫色 std::vector<uint8_t> green_color = {0, 255, 0}; // 绿色用于标记 // 处理聚类结果 for (size_t i = 0; i < clusters.size(); ++i) { bool is_cone = false; Cone matched_cone; if (!clusters[i]->empty()) { Box cluster_box = processor.BoundingBox(clusters[i]); pcl::PointXYZ cluster_center; cluster_center.x = (cluster_box.x_min + cluster_box.x_max) / 2.0; cluster_center.y = (cluster_box.y_min + cluster_box.y_max) / 2.0; cluster_center.z = (cluster_box.z_min + cluster_box.z_max) / 2.0; // 匹配锥桶 for (const auto& cone : cones) { float dist = processor.EuclideanDistance(cluster_center, cone.center); if (dist < 0.2 && cone.confidence >= cone_confidence_threshold) { is_cone = true; matched_cone = cone; break; } } } // 分配颜色 - cluster_pub_使用紫色,cone_pub_使用橙色 std::vector<uint8_t> cluster_color = purple_color; // 聚类点云使用紫色 std::vector<uint8_t> cone_color = {255, 165, 0}; // 锥桶点云使用橙色 // 创建彩色点云 for (const auto& point : clusters[i]->points) { if (isPointFinite(point)) { // 为cluster_pub_创建紫色点云 pcl::PointXYZRGB colored_point; colored_point.x = point.x; colored_point.y = point.y; colored_point.z = point.z; colored_point.r = cluster_color[0]; colored_point.g = cluster_color[1]; colored_point.b = cluster_color[2]; colored_clusters_cloud->points.push_back(colored_point); // 如果是锥桶,为cone_pub_创建橙色点云 if (is_cone) { pcl::PointXYZRGB cone_colored_point; cone_colored_point.x = point.x; cone_colored_point.y = point.y; cone_colored_point.z = point.z; cone_colored_point.r = cone_color[0]; cone_colored_point.g = cone_color[1]; cone_colored_point.b = cone_color[2]; cone_cloud->points.push_back(cone_colored_point); } } } // 创建边界框标记 - 使用绿色 Box box = processor.BoundingBox(clusters[i]); visualization_msgs::msg::Marker bbox_marker; bbox_marker.header = msg->header; bbox_marker.ns = "bounding_boxes"; bbox_marker.id = marker_id_counter_++; bbox_marker.type = visualization_msgs::msg::Marker::CUBE; bbox_marker.action = visualization_msgs::msg::Marker::ADD; bbox_marker.pose.position.x = (box.x_min + box.x_max) / 2.0; bbox_marker.pose.position.y = (box.y_min + box.y_max) / 2.0; bbox_marker.pose.position.z = (box.z_min + box.z_max) / 2.0; bbox_marker.pose.orientation.w = 1.0; bbox_marker.scale.x = box.x_max - box.x_min; bbox_marker.scale.y = box.y_max - box.y_min; bbox_marker.scale.z = box.z_max - box.z_min; // 标记使用绿色 bbox_marker.color.r = green_color[0] / 255.0; bbox_marker.color.g = green_color[1] / 255.0; bbox_marker.color.b = green_color[2] / 255.0; bbox_marker.color.a = 0.3; bbox_marker.lifetime = rclcpp::Duration::from_seconds(0.5); all_markers.markers.push_back(bbox_marker); } // 创建锥桶文本标记 - 使用绿色 for (size_t i = 0; i < cones.size(); ++i) { const auto& cone = cones[i]; if (cone.confidence >= cone_confidence_threshold) { visualization_msgs::msg::Marker text_marker; text_marker.header = msg->header; text_marker.ns = "cone_text"; text_marker.id = marker_id_counter_++; text_marker.type = visualization_msgs::msg::Marker::TEXT_VIEW_FACING; text_marker.action = visualization_msgs::msg::Marker::ADD; text_marker.pose.position.x = cone.center.x; text_marker.pose.position.y = cone.center.y; text_marker.pose.position.z = cone.center.z + cone.height + 0.15; text_marker.scale.z = 0.15; // 文本标记使用绿色 text_marker.color.r = green_color[0] / 255.0; text_marker.color.g = green_color[1] / 255.0; text_marker.color.b = green_color[2] / 255.0; text_marker.color.a = 1.0; std::stringstream coord_stream; coord_stream << std::fixed << std::setprecision(2); coord_stream << "x: " << cone.center.x << "\n"; coord_stream << "y: " << cone.center.y << "\n"; coord_stream << "z: " << cone.center.z; text_marker.text = "Cone " + std::to_string(cone.id) + " (" + std::to_string(static_cast<int>(cone.confidence * 100)) + "%)\n" + coord_stream.str(); text_marker.lifetime = rclcpp::Duration::from_seconds(0.5); all_markers.markers.push_back(text_marker); } } // 发布所有结果 publish_colored_pointcloud(colored_clusters_cloud, msg->header, cluster_pub_); publish_colored_pointcloud(cone_cloud, msg->header, cone_pub_); marker_pub_->publish(all_markers); auto end_time = std::chrono::steady_clock::now(); auto elapsed_time = std::chrono::duration_cast<std::chrono::milliseconds>(end_time - start_time); RCLCPP_INFO(this->get_logger(), "处理完成: %lu 个聚类, %lu 个锥桶, 耗时 %ld ms", clusters.size(), cones.size(), elapsed_time.count()); // 重置标记ID计数器 if (marker_id_counter_ > 10000) { marker_id_counter_ = 0; } } void publish_pointcloud(const pcl::PointCloud<pcl::PointXYZ>::Ptr& cloud, const std_msgs::msg::Header& header, rclcpp::Publisher<sensor_msgs::msg::PointCloud2>::SharedPtr publisher) { if (cloud->empty()) return; sensor_msgs::msg::PointCloud2 output; pcl::toROSMsg(*cloud, output); output.header = header; output.header.frame_id = header.frame_id.empty() ? "rslidar" : header.frame_id; output.header.stamp = this->now(); publisher->publish(output); } void publish_colored_pointcloud(const pcl::PointCloud<pcl::PointXYZRGB>::Ptr& cloud, const std_msgs::msg::Header& header, rclcpp::Publisher<sensor_msgs::msg::PointCloud2>::SharedPtr publisher) { if (cloud->empty()) return; sensor_msgs::msg::PointCloud2 output; pcl::toROSMsg(*cloud, output); output.header = header; output.header.frame_id = header.frame_id.empty() ? "rslidar" : header.frame_id; output.header.stamp = this->now(); publisher->publish(output); } // 订阅者和发布者 rclcpp::Subscription<sensor_msgs::msg::PointCloud2>::SharedPtr subscription_; rclcpp::Publisher<sensor_msgs::msg::PointCloud2>::SharedPtr cluster_pub_; rclcpp::Publisher<sensor_msgs::msg::PointCloud2>::SharedPtr cone_pub_; rclcpp::Publisher<visualization_msgs::msg::MarkerArray>::SharedPtr marker_pub_; int marker_id_counter_; }; int main(int argc, char** argv) { rclcpp::init(argc, argv); auto node = std::make_shared<EuclideanClusteringNode>(); RCLCPP_INFO(node->get_logger(), "启动欧式距离聚类节点"); rclcpp::spin(node); rclcpp::shutdown(); return 0; } 这个代码存在那些问题
11-13
严重性 代码 说明 项目 文件 行 禁止显示状态 错误(活动) E0020 未定义标识符 "evaluator" caotudaoR D:\NXopen\BaiduSyncdisk\studio\caotudaoR\caotudaoR.cpp 404 错误(活动) E0020 未定义标识符 "FindApproximateIntersection" caotudaoR D:\NXopen\BaiduSyncdisk\studio\caotudaoR\caotudaoR.cpp 282 错误(活动) E0020 未定义标识符 "evaluator" caotudaoR D:\NXopen\BaiduSyncdisk\studio\caotudaoR\caotudaoR.cpp 388 错误(活动) E0020 未定义标识符 "evaluator" caotudaoR D:\NXopen\BaiduSyncdisk\studio\caotudaoR\caotudaoR.cpp 464 错误(活动) E0020 未定义标识符 "curveEval" caotudaoR D:\NXopen\BaiduSyncdisk\studio\caotudaoR\caotudaoR.cpp 412 错误(活动) E1696 无法打开 源 文件 "NXOpen/Evaluator.hxx" caotudaoR D:\NXopen\BaiduSyncdisk\studio\caotudaoR\caotudaoR.hpp 81 错误(活动) E1696 无法打开 源 文件 "NXOpen/CurveEvaluator.hxx" caotudaoR D:\NXopen\BaiduSyncdisk\studio\caotudaoR\caotudaoR.hpp 82 错误(活动) E0135 namespace "NXOpen" 没有成员 "Evaluator" caotudaoR D:\NXopen\BaiduSyncdisk\studio\caotudaoR\caotudaoR.cpp 388 错误(活动) E0135 namespace "NXOpen" 没有成员 "Evaluator" caotudaoR D:\NXopen\BaiduSyncdisk\studio\caotudaoR\caotudaoR.cpp 404 错误(活动) E0135 namespace "NXOpen" 没有成员 "Evaluator" caotudaoR D:\NXopen\BaiduSyncdisk\studio\caotudaoR\caotudaoR.cpp 464 错误(活动) E0135 namespace "NXOpen" 没有成员 "CurveEvaluator" caotudaoR D:\NXopen\BaiduSyncdisk\studio\caotudaoR\caotudaoR.cpp 412 错误(活动) E0135 class "NXOpen::Curve" 没有成员 "IntersectCurve" caotudaoR D:\NXopen\BaiduSyncdisk\studio\caotudaoR\caotudaoR.cpp 443 错误(活动) E0135 class "NXOpen::Curve" 没有成员 "CreateEvaluator" caotudaoR D:\NXopen\BaiduSyncdisk\studio\caotudaoR\caotudaoR.cpp 388 错误(活动) E0135 class "NXOpen::Curve" 没有成员 "CreateEvaluator" caotudaoR D:\NXopen\BaiduSyncdisk\studio\caotudaoR\caotudaoR.cpp 404 错误(活动) E0135 class "NXOpen::Curve" 没有成员 "CreateEvaluator" caotudaoR D:\NXopen\BaiduSyncdisk\studio\caotudaoR\caotudaoR.cpp 464 错误(活动) E0135 class "NXOpen::Curve" 没有成员 "CreateCurveEvaluator" caotudaoR D:\NXopen\BaiduSyncdisk\studio\caotudaoR\caotudaoR.cpp 412
09-09
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值