1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117
|
// SPDX-FileCopyrightText: Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
// SPDX-License-Identifier: BSD-3-Clause
#include "vtkGLTFWriterUtils.h"
#include "vtkBase64OutputStream.h"
#include "vtkCellArray.h"
#include "vtkFloatArray.h"
#include "vtkUnsignedIntArray.h"
#include "vtksys/FStream.hxx"
#include "vtksys/SystemTools.hxx"
#include <sstream>
#include <string>
VTK_ABI_NAMESPACE_BEGIN
void vtkGLTFWriterUtils::WriteValues(vtkDataArray* ca, ostream& myFile)
{
myFile.write(reinterpret_cast<char*>(ca->GetVoidPointer(0)),
ca->GetNumberOfTuples() * ca->GetNumberOfComponents() * ca->GetElementComponentSize());
}
void vtkGLTFWriterUtils::WriteValues(vtkDataArray* ca, vtkBase64OutputStream* ostr)
{
ostr->Write(reinterpret_cast<char*>(ca->GetVoidPointer(0)),
ca->GetNumberOfTuples() * ca->GetNumberOfComponents() * ca->GetElementComponentSize());
}
void vtkGLTFWriterUtils::WriteBufferAndView(vtkDataArray* inda, const char* fileName,
bool inlineData, nlohmann::json& buffers, nlohmann::json& bufferViews, int bufferViewTarget)
{
vtkDataArray* da = inda;
// gltf does not support doubles so handle that
if (inda->GetDataType() == VTK_DOUBLE)
{
da = vtkFloatArray::New();
da->DeepCopy(inda);
}
// if inline then base64 encode the data
std::string result;
if (inlineData)
{
result = "data:application/octet-stream;base64,";
std::ostringstream toString;
vtkNew<vtkBase64OutputStream> ostr;
ostr->SetStream(&toString);
ostr->StartWriting();
WriteValues(da, ostr);
ostr->EndWriting();
result += toString.str();
}
else
{
// otherwise write binary files
std::ostringstream toString;
toString << "buffer" << da->GetMTime() << ".bin";
result = toString.str();
std::string fullPath = vtksys::SystemTools::GetFilenamePath(fileName);
if (!fullPath.empty())
{
fullPath += "/";
}
fullPath += result;
// now write the data
vtksys::ofstream myFile(fullPath.c_str(), ios::out | ios::binary);
WriteValues(da, myFile);
myFile.close();
}
nlohmann::json buffer;
nlohmann::json view;
unsigned int count = da->GetNumberOfTuples() * da->GetNumberOfComponents();
unsigned int byteLength = da->GetElementComponentSize() * count;
buffer["byteLength"] = byteLength;
buffer["uri"] = result;
buffers.emplace_back(buffer);
// write the buffer views
view["buffer"] = buffers.size() - 1;
view["byteOffset"] = 0;
view["byteLength"] = byteLength;
view["target"] = bufferViewTarget;
bufferViews.emplace_back(view);
// delete double to float conversion array
if (da != inda)
{
da->Delete();
}
}
void vtkGLTFWriterUtils::WriteCellBufferAndView(vtkCellArray* ca, const char* fileName,
bool inlineData, nlohmann::json& buffers, nlohmann::json& bufferViews)
{
vtkUnsignedIntArray* ia = vtkUnsignedIntArray::New();
vtkIdType npts;
const vtkIdType* indx;
for (ca->InitTraversal(); ca->GetNextCell(npts, indx);)
{
for (int j = 0; j < npts; ++j)
{
unsigned int value = static_cast<unsigned int>(indx[j]);
ia->InsertNextValue(value);
}
}
WriteBufferAndView(ia, fileName, inlineData, buffers, bufferViews, GLTF_ELEMENT_ARRAY_BUFFER);
ia->Delete();
}
VTK_ABI_NAMESPACE_END
|