Import: fixes #8666: Enable support to read glTF files
This commit is contained in:
@@ -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");
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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")
|
||||
|
||||
Reference in New Issue
Block a user