赞
踩
首先,到官网下载[coin3d/coin]
我是Qt5.15.2+vs2019的,因此我选择这个coin-4.0.2-msvc17-x64.zip
到官网下载Coin3D在Qt中的封装库【quarter】
我是Qt5.15.2+vs2019的,因此我选择这个quarter-1.2.1-Qt5.15-msvc17-x64.zip
将这两个压缩包放在在同一个文件夹中,先解压coin-4.0.2-msvc17-x64.zip,然后再解压
quarter-1.2.1-Qt5.15-msvc17-x64.zip,此时,我们利用Qt编程所需要的东西全在Coin3D这个文件夹里面了:
在Qt工程的pro文件中添加以下语句,路径要根据你的实际路径进行更改
QT += opengl
INCLUDEPATH += C:\Users\Administrator\Desktop\plc\Qt\Coin3D\include
LIBS += -LC:\Users\Administrator\Desktop\plc\Qt\Coin3D\lib \
-lQuarter1
LIBS += -LC:\Users\Administrator\Desktop\plc\Qt\Coin3D\bin
DEFINES += QUARTER_DLL
程序的话,可以参考以下这个【a small, completely stand-alone usage example】
参考这篇文章【OpenInventor实现场景索引线集管理之SoIndexedLineSet】,弄了个绘制网格的例子:
#include "mainwindow.h" #include <QApplication> #include <QDebug> #include <Inventor/nodes/SoBaseColor.h> #include <Inventor/nodes/SoCone.h> #include <Inventor/nodes/SoSeparator.h> #include <Inventor/VRMLnodes/SoVRMLGroup.h> #include <Inventor/nodes/SoPointSet.h> #include <Inventor/nodes/SoCoordinate3.h> #include <Inventor/nodes/SoIndexedLineSet.h> #include <Inventor/nodes/SoLineSet.h> #include <Inventor/nodes/SoMaterial.h> #include <Inventor/nodes/SoMaterialBinding.h> #include <Inventor/nodes/SoTransform.h> #include <Inventor/nodes/SoMatrixTransform.h> #include <Quarter/Quarter.h> #include <Quarter/QuarterWidget.h> #include <QtMath> using namespace SIM::Coin3D::Quarter; int main(int argc, char *argv[]) { QApplication a(argc, argv); // MainWindow w; // w.show(); // Initializes Quarter library (and implicitly also the Coin and Qt // libraries). Quarter::init(); // Make a dead simple scene graph by using the Coin library, only // containing a single yellow cone under the scene graph root. SoSeparator * root = new SoSeparator; root->ref(); // 绘制网格 { // 根节点 SoSeparator * lineRoot = new SoSeparator(); lineRoot->ref(); // 线段集 SoIndexedLineSet *iLineSet = new SoIndexedLineSet(); int gridRows = 10; int gridCols = 10; // 存放点数据的结构 SbVec3f *points = new SbVec3f[2 * (gridCols + gridCols)]; // 填充横线 for(int i = 0; i < gridRows; i++) { points[i * 2].setValue(0, i, 0); points[i * 2 + 1].setValue(gridCols - 1, i, 0); } // 填充竖线 for(int i = 0; i < gridCols; i++) { points[gridRows * 2 + i * 2].setValue(i, 0, 0); points[gridRows * 2 + i * 2 + 1].setValue(i, gridRows - 1, 0); } // 坐标系 SoCoordinate3 *coord = new SoCoordinate3(); // 将各个点填充至坐标系中 coord->point.setValues(0, 2 * (gridCols + gridCols), points); // 保存线的索引 int32_t *nLineSets = new int32_t[3 * (gridCols + gridRows)]; // 每条线需要三个索引:起点、终点、结束符 for(int i = 0; i < (gridCols + gridRows); i++) { nLineSets[3 * i] = i * 2; nLineSets[3 * i + 1] = i * 2 + 1; // SO_END_LINE_INDEX的值是-1,-1代表一条索引线结束!!! nLineSets[3 * i + 2] = SO_END_LINE_INDEX; } iLineSet->coordIndex.setValues(0, 3 * (gridCols + gridRows), nLineSets); // 默认颜色为绿色,被选中的红色显示 SbColor *color = new SbColor[2]; color[0].setValue(1,0,0); color[1].setValue(0,1,0); SoMaterial *mat = new SoMaterial(); mat->diffuseColor.setValues(0, 2, color); SoMaterialBinding *mb = new SoMaterialBinding; // 索引绑定材质!!! mb->value = SoMaterialBinding::PER_PART_INDEXED; // mb->value = SoMaterialBinding::PER_PART; // mb->value = SoMaterialBinding::OVERALL; // 设置线段的颜色 for(int i = 0; i < (gridCols + gridRows); i++) { // 这里的索引.第一个参数指的是第条线,第二个参数指的是mat->diffuseColor中的第几种材质 iLineSet->materialIndex.set1Value(i, 0); // 第i个线段的颜色/ } iLineSet->materialIndex.set1Value(0, 1); // 第i个线段的颜色/ // 整体变换 SbMatrix sbMatrix, tmpMat, tmpMat1; sbMatrix.makeIdentity(); // 变成单位矩阵 // 平移、旋转、缩放需要单独进行,然后相乘 tmpMat.makeIdentity(); // tmpMat.setTranslate(SbVec3f(1, 0, 0)); tmpMat.setRotate(SbRotation(SbVec3f(1, 0, 0), qDegreesToRadians(90.0))); tmpMat1.makeIdentity(); tmpMat1.setScale(0.1); sbMatrix = tmpMat1 * tmpMat; // 越在右边的矩阵,逻辑上是越先被使用的 SoMatrixTransform *matrix = new SoMatrixTransform; // matrix->matrix.setValue(sbMatrix); lineRoot->addChild(matrix); lineRoot->addChild(coord); // 组成线的点 lineRoot->addChild(mat); // 线的材质 lineRoot->addChild(mb); // 绑定材质 lineRoot->addChild(iLineSet); // 线 root->addChild(lineRoot); } // Create a QuarterWidget for displaying a Coin scene graph QuarterWidget * viewer = new QuarterWidget; viewer->setSceneGraph(root); viewer->viewAll(); // make the viewer react to input events similar to the good old // ExaminerViewer viewer->setNavigationModeFile(QUrl("coin:///scxml/navigation/examiner.xml")); // viewer->setNavigationModeFile(QUrl("coin:///scxml/navigation/common.xml")); viewer->resize(640, 480); // Pop up the QuarterWidget viewer->show(); // return a.exec(); a.exec(); // Clean up resources. root->unref(); delete viewer; Quarter::clean(); return a.exec(); }
参考【FengJungle /QtCoin3D_Robot 】,可以加载自己的wrl模型
// 加载模型 SoVRMLGroup *model = nullptr; { SoInput * myInput = new SoInput; if(myInput->openFile("lr4-r560.wrl")) { model = SoDB::readAllVRML(myInput); myInput->closeFile(); delete myInput; } else { myInput->closeFile(); delete myInput; } } if(model != nullptr) { qDebug() << "num of children:" << model->getNumChildren(); root->addChild(model); }
// 绘制锤子 { // 创建一个组合节点,作为锤子的根节点 SoSeparator* hammerRoot = new SoSeparator; // 创建一个旋转节点,用于绕圆柱体的末端旋转锤子 SoRotation* rotation = new SoRotation; rotation->rotation.setValue(SbVec3f(1, 0, 0), M_PI * 0); // 将旋转节点添加到组合节点中 hammerRoot->addChild(rotation); QSlider *slider = new QSlider(Qt::Horizontal); slider->resize(300, 20); QObject::connect(slider, &QSlider::valueChanged, [=](){ rotation->rotation.setValue(SbVec3f(1, 0, 0), M_PI * ((double)slider->value()) / 100.0); // 绕Z轴旋转45度 }); slider->show(); // 将手柄的位置调整一下,使得旋转中心在手柄末端 SoTranslation* handleTranslation = new SoTranslation; handleTranslation->translation.setValue(0, 5, 0); hammerRoot->addChild(handleTranslation); // 创建圆柱体节点,作为锤子的手柄 SoCylinder* handle = new SoCylinder; handle->radius = 0.5; handle->height = 10; hammerRoot->addChild(handle); // 将长方体放置在圆柱体的末端 SoTranslation* headTranslation = new SoTranslation; headTranslation->translation.setValue(0, 5, 0); hammerRoot->addChild(headTranslation); // 创建长方体节点,作为锤子的头部 SoCube* head = new SoCube; head->width = 2; head->height = 2; head->depth = 2; hammerRoot->addChild(head); root->addChild(hammerRoot); }
QString exePath = QDir::currentPath();
QString filePath = QString("file:///%1/examiner.xml").arg(exePath);
viewer->setNavigationModeFile(QUrl(filePath));
更加具体的其他操作还得研究研究。
参考:
【OpenInventor官方文档】
【coin3d】
【FengJungle /QtCoin3D_Robot 】
【OpenInventor实现场景索引线集管理之SoIndexedLineSet】
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。