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 943ae448d3
commit b491afb604
5 changed files with 117 additions and 2 deletions

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();
}