原文链接:https://www.yuque.com/softdev/qt/txv1lx
class Qui3DView{
private:
struct date_struct{
QPointer<Qt3DWindow> m_windowOn3D = new Qt3DWindow();
QPointer<QtEntity> m_rootEntity = new QtEntity();
QPointer<QtMaterial> m_material = new QtMaterial();
}db;
}
//没有找到相关资料
//Qt3d还是比较复杂的,很难考虑全面
//这里简单使用一个
bool Qui3DView::saveObj(const QString& filePath)
{
using QAttribute = Qt3DRender::QAttribute;
QFile file(filePath);
if (!file.open(QIODevice::WriteOnly | QIODevice::Text))
{
return false;
}
QTextStream stream(&file);
int filePntSize = 0; //文件中已经存的点个数
auto comps = db.m_rootEntity->components();
for (QComponent* comp : comps)
{
QMesh* mesh = dynamic_cast<QMesh*>(comp);
uint pntSize = 0; //此mesh的点个数
if (!mesh)
{
continue;
}
QGeometry* geom = mesh->geometry();
auto attris = geom->attributes();
for (QAttribute* attri : attris)
{
auto type = attri->attributeType();
switch (type)
{
case Qt3DRender::QAttribute::VertexAttribute:
{
pntSize = attri->count();
auto buf = attri->buffer();
auto bufferBytes = buf->data();
const quint32 stride = bufferBytes.size() / pntSize;
const quint32 elementSize = stride / sizeof(float);
float* fptr = reinterpret_cast<float*>(bufferBytes.data());
for (decltype(pntSize) i = 0; i < pntSize; ++i)
{
auto x = *fptr;
auto y = *(fptr + 1);
auto z = *(fptr + 2);
stream << "v " << x << " " << y << " " << z << endl;
fptr += elementSize;
}
stream.flush();
break;
}
case Qt3DRender::QAttribute::IndexAttribute:
{
auto buf = attri->buffer();
auto indexBytes = buf->data();
auto faceSize = indexBytes.size() / sizeof(quint16) / 3;
quint16* usptr = reinterpret_cast<quint16*>(indexBytes.data());
for (decltype(faceSize) i = 0; i < faceSize; ++i)
{
auto idx1 = *usptr++;
auto idx2 = *usptr++;
auto idx3 = *usptr++;
stream << "f " << idx1 + filePntSize + 1 << " " << idx2 + filePntSize + 1 << " " << idx3 + filePntSize + 1 << endl;
//+1是因为obj里的索引是从1开始的
}
stream.flush();
break;
}
case Qt3DRender::QAttribute::DrawIndirectAttribute:
break;
default:
break;
}
}
filePntSize += pntSize; //偏移量
}
stream.flush();
file.close();
return true;
}