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