Import: fixes #8666: Enable support to read glTF files

This commit is contained in:
wmayer
2023-09-25 12:23:53 +02:00
committed by wwmayer
parent 0aa9ea99b4
commit 37e477d3e7
5 changed files with 117 additions and 2 deletions

View File

@@ -73,6 +73,7 @@
#include <Mod/Part/App/encodeFilename.h>
#include "ImportOCAF2.h"
#include "ReaderGltf.h"
#include "WriterGltf.h"
namespace Import
@@ -248,6 +249,10 @@ private:
pcDoc->recompute();
}
}
else if (file.hasExtension({"glb", "gltf"})) {
Import::ReaderGltf reader(file);
reader.read(hDoc);
}
else {
throw Py::Exception(PyExc_IOError, "no supported file format");
}

View File

@@ -24,9 +24,89 @@
#include "PreCompiled.h"
#ifndef _PreComp_
#include <sstream>
#include <Standard_Version.hxx>
#include <TDF_Label.hxx>
#include <TDF_TagSource.hxx>
#include <XCAFDoc_DocumentTool.hxx>
#include <XCAFDoc_ShapeTool.hxx>
#if OCC_VERSION_HEX >= 0x070500
#include <Message_ProgressRange.hxx>
#include <RWGltf_CafReader.hxx>
#endif
#endif
#include "ReaderGltf.h"
#include <Base/Exception.h>
#include <Mod/Part/App/TopoShape.h>
#include <Mod/Part/App/Tools.h>
using namespace Import;
ReaderGltf::ReaderGltf(const Base::FileInfo& file) // NOLINT
: file {file}
{}
void ReaderGltf::read(Handle(TDocStd_Document) hDoc) // NOLINT
{
#if OCC_VERSION_HEX >= 0x070500
const double unit = 0.001; // mm
RWGltf_CafReader aReader;
aReader.SetSystemLengthUnit(unit);
aReader.SetSystemCoordinateSystem(RWMesh_CoordinateSystem_Zup);
aReader.SetDocument(hDoc);
aReader.SetParallel(true);
TCollection_AsciiString filename(file.filePath().c_str());
Standard_Boolean ret = aReader.Perform(filename, Message_ProgressRange());
if (!ret) {
std::stringstream str;
str << "Cannot read from file '"
<< "" << file.filePath() << "'";
}
Handle(XCAFDoc_ShapeTool) aShapeTool = XCAFDoc_DocumentTool::ShapeTool(hDoc->Main());
TDF_LabelSequence labels;
aShapeTool->GetShapes(labels);
for (Standard_Integer i = 1; i <= labels.Length(); i++) {
auto label = labels.Value(i);
TopoDS_Shape shape = aShapeTool->GetShape(label);
if (!shape.IsNull()) {
aShapeTool->SetShape(label, fixShape(shape));
}
}
#else
throw Base::RuntimeError("gITF support requires OCCT 7.5.0 or later");
#endif
}
bool ReaderGltf::cleanup() const
{
return clean;
}
void ReaderGltf::setCleanup(bool value)
{
clean = value;
}
TopoDS_Shape ReaderGltf::fixShape(TopoDS_Shape shape) // NOLINT
{
// The glTF reader creates a compound of faces that only contains the triangulation
// but not the underlying surfaces. This leads to faces without boundaries.
// The triangulation is used to create a valid shape.
const double tolerance = 0.5;
std::vector<Base::Vector3d> points;
std::vector<Data::ComplexGeoData::Facet> facets;
Part::TopoShape sh(shape);
sh.getFaces(points, facets, tolerance);
sh.setFaces(points, facets, tolerance);
if (cleanup()) {
sh.sewShape();
return sh.removeSplitter();
}
return sh.getShape();
}

View File

@@ -24,9 +24,31 @@
#ifndef IMPORT_READER_GLTF_H
#define IMPORT_READER_GLTF_H
#include <Mod/Import/ImportGlobal.h>
#include <Base/FileInfo.h>
#include <TDocStd_Document.hxx>
#include <TopoDS_Shape.hxx>
namespace Import
{
}
class ImportExport ReaderGltf
{
public:
explicit ReaderGltf(const Base::FileInfo& file);
void read(Handle(TDocStd_Document) hDoc);
bool cleanup() const;
void setCleanup(bool);
private:
TopoDS_Shape fixShape(TopoDS_Shape);
private:
Base::FileInfo file;
bool clean = true;
};
} // namespace Import
#endif // IMPORT_READER_GLTF_H

View File

@@ -104,6 +104,7 @@
#include <Gui/MainWindow.h>
#include <Gui/ViewProviderLink.h>
#include <Mod/Import/App/ImportOCAF2.h>
#include <Mod/Import/App/ReaderGltf.h>
#include <Mod/Import/App/WriterGltf.h>
#include <Mod/Part/App/ImportIges.h>
#include <Mod/Part/App/ImportStep.h>
@@ -523,6 +524,10 @@ private:
pcDoc->recompute();
}
}
else if (file.hasExtension({"glb", "gltf"})) {
Import::ReaderGltf reader(file);
reader.read(hDoc);
}
else {
throw Py::Exception(PyExc_IOError, "no supported file format");
}
@@ -537,7 +542,9 @@ private:
if (useLinkGroup != Py_None) {
ocaf.setUseLinkGroup(Base::asBoolean(useLinkGroup));
}
ocaf.setMode(mode);
if (mode >= 0) {
ocaf.setMode(mode);
}
auto ret = ocaf.loadShapes();
hApp->Close(hDoc);
FC_DURATION_PLUS(d2, t);

View File

@@ -31,5 +31,6 @@
# FreeCAD.addExportType("IGES files (*.iges *.igs)","ImportGui")
FreeCAD.addImportType("PLMXML files (*.plmxml)", "PlmXmlParser")
FreeCAD.addImportType("STEPZ Zip File Type (*.stpZ *.stpz)", "stepZ")
FreeCAD.addImportType("glTF (*.gltf *.glb)", "ImportGui")
FreeCAD.addExportType("STEPZ zip File Type (*.stpZ *.stpz)", "stepZ")
FreeCAD.addExportType("glTF (*.gltf *.glb)", "ImportGui")