QT -CloudViewer工具

发布时间:2023年12月17日


一、演示效果

在这里插入图片描述
在这里插入图片描述

二、关键程序

void CloudViewer::doOpen(const QStringList& filePathList) {
  // Open point cloud file one by one
  for (int i = 0; i != filePathList.size(); i++) {
    timeStart(); // time start
    mycloud.cloud.reset(new PointCloudT); // Reset cloud
    QFileInfo fileInfo(filePathList[i]);
    std::string filePath = fromQString(fileInfo.filePath());
    std::string fileName = fromQString(fileInfo.fileName());

    // begin loading
    ui.statusBar->showMessage(
      fileInfo.fileName() + ": " + QString::number(i) + "/" + QString::number(filePathList.size())
      + " point cloud loading..."
    );

    mycloud = fileIO.load(fileInfo);
    if (!mycloud.isValid) {
      // TODO: deal with the error, print error info in console?
      debug("invalid cloud.");
      continue;
    }
    mycloud.viewer = viewer;
    mycloud_vec.push_back(mycloud);

    timeCostSecond = timeOff(); // time off

    consoleLog(
      "Open",
      toQString(mycloud.fileName),
      toQString(mycloud.filePath),
      "Time cost: " + timeCostSecond + " s, Points: " + QString::number(mycloud.cloud->points.size())
    );

    // update tree widget
    QTreeWidgetItem *cloudName = new QTreeWidgetItem(QStringList()
      << toQString(mycloud.fileName));
    cloudName->setIcon(0, QIcon(":/Resources/images/icon.png"));
    ui.dataTree->addTopLevelItem(cloudName);

    total_points += mycloud.cloud->points.size();
  }
  ui.statusBar->showMessage("");
  showPointcloudAdd();
  setPropertyTable();
}

// Open point cloud
void CloudViewer::open() {
  QStringList filePathList = QFileDialog::getOpenFileNames(
    this,
    tr("Open point cloud file"),
    toQString(mycloud.fileDir),
    toQString(fileIO.getInputFormatsStr())
  );
  if (filePathList.isEmpty()) return;

  // Clear cache
  // TODO: abstract a function
  mycloud_vec.clear();
  total_points = 0;
  ui.dataTree->clear();
  viewer->removeAllPointClouds();

  doOpen(filePathList);
}

// Add Point Cloud
void CloudViewer::add() {
  QStringList filePathList = QFileDialog::getOpenFileNames(
    this,
    tr("Add point cloud file"),
    toQString(mycloud.fileDir),
    toQString(fileIO.getInputFormatsStr())
  );
  if (filePathList.isEmpty()) return;

  doOpen(filePathList);
}

// Clear all point clouds
void CloudViewer::clear() {
  mycloud_vec.clear();  // 从点云容器中移除所有点云
  viewer->removeAllPointClouds();  // 从viewer中移除所有点云
  viewer->removeAllShapes(); // 这个remove更彻底
  ui.dataTree->clear();  // 将dataTree清空

  ui.propertyTable->clear();  // 清空属性窗口propertyTable
  QStringList header;
  header << "Property" << "Value";
  ui.propertyTable->setHorizontalHeaderLabels(header);

  // 输出窗口
  consoleLog("Clear", "All point clouds", "", "");

  setWindowTitle("CloudViewer");  // 更新窗口标题
  showPointcloud();  // 更新显示
}

// Save point cloud
void CloudViewer::save() {
  if (!mycloud.isValid) {
    QMessageBox::critical(this, tr("Saving file error"),
      tr("There is no point cloud to save"));
    return;
  }

  // get binary flag from sender()
  QAction *action = qobject_cast<QAction *>(sender());
  QVariant v = action->data();
  bool isSaveBinary = (bool)v.value<bool>();

  QString selectedFilter = toQString(fileIO.outputFiltersMap.at(mycloud.fileSuffix));
  QString saveFilePath = QFileDialog::getSaveFileName(
    this,                                    // parent
    toQString("Save point cloud" + string(isSaveBinary ? " (binary)": "")), // caption
    toQString(mycloud.filePath),             // dir
    toQString(fileIO.getOutputFormatsStr()), // filter
    &selectedFilter                          // selected filter
  );
  if (saveFilePath.isEmpty()) return;

  QFileInfo fileInfo(saveFilePath);
  QString saveFileName = fileInfo.fileName();
  string saveFilePathStd = fromQString(saveFilePath);
  string saveFileNameStd = fromQString(saveFileName);

  if (mycloud_vec.size() > 1) {
    savemulti(fileInfo, isSaveBinary);
    return;
  }

  bool saveStatus = fileIO.save(mycloud, fileInfo, isSaveBinary);
  if (!saveStatus) {
    QMessageBox::critical(this, tr("Saving file error"),
      tr("We can not save the file"));
    return;
  }

  consoleLog("Save", saveFileName, saveFilePath, "Single save");

  setWindowTitle(saveFilePath + " - CloudViewer");
  QMessageBox::information(this, tr("save point cloud file"),
    toQString("Save " + saveFileNameStd + " successfully!"));
}

// Save multi point cloud
void CloudViewer::savemulti(const QFileInfo& fileInfo, bool isSaveBinary) {
  string subname = fromQString(fileInfo.fileName());
  QString saveFilePath = fileInfo.filePath();
  PointCloudT::Ptr multi_cloud;
  multi_cloud.reset(new PointCloudT);
  multi_cloud->height = 1;
  int sum = 0;
  for (auto c : mycloud_vec) {
    sum += c.cloud->points.size();
  }
  multi_cloud->width = sum;
  multi_cloud->resize(multi_cloud->height * multi_cloud->width);
  int k = 0;
  for (int i = 0; i != mycloud_vec.size(); ++i) {
    // 注意cloudvec[i]->points.size()和cloudvec[i]->size()的区别
    for (int j = 0; j != mycloud_vec[i].cloud->points.size(); ++j) {
      multi_cloud->points[k].x = mycloud_vec[i].cloud->points[j].x;
      multi_cloud->points[k].y = mycloud_vec[i].cloud->points[j].y;
      multi_cloud->points[k].z = mycloud_vec[i].cloud->points[j].z;
      multi_cloud->points[k].r = mycloud_vec[i].cloud->points[j].r;
      multi_cloud->points[k].g = mycloud_vec[i].cloud->points[j].g;
      multi_cloud->points[k].b = mycloud_vec[i].cloud->points[j].b;
      k++;
    }
  }

  MyCloud multiMyCloud;
  multiMyCloud.cloud = multi_cloud;
  multiMyCloud.isValid = true;

  // save multi_cloud
  bool saveStatus = fileIO.save(multiMyCloud, fileInfo, isSaveBinary);
  if (!saveStatus) {
    QMessageBox::critical(this, tr("Saving file error"),
      tr("We can not save the file"));
    return;
  }

  if (isSaveBinary) {
    consoleLog("Save as binary", QString::fromLocal8Bit(subname.c_str()), saveFilePath, "Multi save (binary)");
  } else {
    consoleLog("Save", QString::fromLocal8Bit(subname.c_str()), saveFilePath, "Multi save");
  }

  // 将保存后的 multi_cloud 设置为当前 mycloud,以便保存之后直接进行操作
  mycloud.cloud = multi_cloud;
  mycloud.filePath = fromQString(saveFilePath);
  mycloud.fileName = subname;

  setWindowTitle(saveFilePath + " - CloudViewer");
  QMessageBox::information(this, tr("save point cloud file"), toQString("Save " + subname + " successfully!"));
}

三、程序下载

https://download.csdn.net/download/u013083044/88628664

文章来源:https://blog.csdn.net/u013083044/article/details/134993772
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。