diff --git a/plugins/alembic/CMakeLists.txt b/plugins/alembic/CMakeLists.txt index a602cf34c5..c675ee8bd6 100644 --- a/plugins/alembic/CMakeLists.txt +++ b/plugins/alembic/CMakeLists.txt @@ -21,7 +21,7 @@ f3d_plugin_declare_reader( NAME Alembic EXTENSIONS abc MIMETYPES application/vnd.abc - VTK_IMPORTER vtkF3DAlembicImporter + VTK_READER vtkF3DAlembicReader FORMAT_DESCRIPTION "Alembic" ) diff --git a/plugins/alembic/module/CMakeLists.txt b/plugins/alembic/module/CMakeLists.txt index 181225b2b6..c0db5e0c86 100644 --- a/plugins/alembic/module/CMakeLists.txt +++ b/plugins/alembic/module/CMakeLists.txt @@ -1,5 +1,5 @@ set(classes - vtkF3DAlembicImporter + vtkF3DAlembicReader ) set(_no_install "") diff --git a/plugins/alembic/module/Testing/CMakeLists.txt b/plugins/alembic/module/Testing/CMakeLists.txt index 1868101625..237323c96e 100644 --- a/plugins/alembic/module/Testing/CMakeLists.txt +++ b/plugins/alembic/module/Testing/CMakeLists.txt @@ -1,5 +1,5 @@ list(APPEND VTKExtensionsPluginAlembic_list - TestF3DAlembicImporter.cxx + TestF3DAlembicReader.cxx ) if(VTK_VERSION VERSION_LESS_EQUAL 9.1.0) diff --git a/plugins/alembic/module/Testing/TestF3DAlembicImporter.cxx b/plugins/alembic/module/Testing/TestF3DAlembicImporter.cxx deleted file mode 100644 index 30f4b3a15b..0000000000 --- a/plugins/alembic/module/Testing/TestF3DAlembicImporter.cxx +++ /dev/null @@ -1,16 +0,0 @@ -#include -#include - -#include "vtkF3DAlembicImporter.h" - -#include - -int TestF3DAlembicImporter(int vtkNotUsed(argc), char* argv[]) -{ - std::string filename = std::string(argv[1]) + "data/suzanne.abc"; - vtkNew importer; - importer->SetFileName(filename); - importer->Update(); - importer->Print(cout); - return importer->GetRenderer() ? EXIT_SUCCESS : EXIT_FAILURE; -} diff --git a/plugins/alembic/module/Testing/TestF3DAlembicReader.cxx b/plugins/alembic/module/Testing/TestF3DAlembicReader.cxx new file mode 100644 index 0000000000..87fa2487e7 --- /dev/null +++ b/plugins/alembic/module/Testing/TestF3DAlembicReader.cxx @@ -0,0 +1,16 @@ +#include +#include + +#include "vtkF3DAlembicReader.h" + +#include + +int TestF3DAlembicReader(int vtkNotUsed(argc), char* argv[]) +{ + std::string filename = std::string(argv[1]) + "data/suzanne.abc"; + vtkNew reader; + reader->SetFileName(filename); + reader->Update(); + reader->Print(cout); + return reader->GetOutput() ? EXIT_SUCCESS : EXIT_FAILURE; +} diff --git a/plugins/alembic/module/vtkF3DAlembicImporter.cxx b/plugins/alembic/module/vtkF3DAlembicImporter.cxx deleted file mode 100644 index eceaaf097c..0000000000 --- a/plugins/alembic/module/vtkF3DAlembicImporter.cxx +++ /dev/null @@ -1,204 +0,0 @@ -#include "vtkF3DAlembicImporter.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#if defined(_MSC_VER) -#pragma warning(push, 0) -#endif -#include -#include -#include -#include -#include -#include -#if defined(_MSC_VER) -#pragma warning(pop) -#endif - -class vtkF3DAlembicImporter::vtkInternals -{ - using PODStringMap = std::map; - using PropertyTypeStringMap = std::map; - -public: - void CreatePODStringMap(PODStringMap& podStringMap) - { - podStringMap[Alembic::AbcGeom::kBooleanPOD] = "kBooleanPOD"; - podStringMap[Alembic::AbcGeom::kUint8POD] = "kUint8POD"; - podStringMap[Alembic::AbcGeom::kInt8POD] = "kInt8POD"; - podStringMap[Alembic::AbcGeom::kUint16POD] = "kUint16POD"; - podStringMap[Alembic::AbcGeom::kInt16POD] = "kInt16POD"; - podStringMap[Alembic::AbcGeom::kUint32POD] = "kUint32POD"; - podStringMap[Alembic::AbcGeom::kInt32POD] = "kInt32POD"; - podStringMap[Alembic::AbcGeom::kUint64POD] = "kUint64POD"; - podStringMap[Alembic::AbcGeom::kInt64POD] = "kInt64POD"; - podStringMap[Alembic::AbcGeom::kFloat16POD] = "kFloat16POD"; - podStringMap[Alembic::AbcGeom::kFloat32POD] = "kFloat32POD"; - podStringMap[Alembic::AbcGeom::kFloat64POD] = "kFloat64POD"; - podStringMap[Alembic::AbcGeom::kStringPOD] = "kStringPOD"; - podStringMap[Alembic::AbcGeom::kWstringPOD] = "kWstringPOD"; - podStringMap[Alembic::AbcGeom::kNumPlainOldDataTypes] = "kNumPlainOldDataTypes"; - podStringMap[Alembic::AbcGeom::kUnknownPOD] = "kUnknownPOD"; - } - - void CreatePropertyTypeStringMap(PropertyTypeStringMap& propertyTypeStringMap) - { - propertyTypeStringMap[Alembic::AbcGeom::kCompoundProperty] = "kCompoundProperty"; - propertyTypeStringMap[Alembic::AbcGeom::kScalarProperty] = "kScalarProperty"; - propertyTypeStringMap[Alembic::AbcGeom::kArrayProperty] = "kArrayProperty"; - } - - void ProcessIPolyMesh(vtkRenderer* renderer, const Alembic::AbcGeom::IPolyMesh& pmesh) - { - vtkNew points; - vtkNew polys; - vtkNew polydata; - - Alembic::AbcGeom::IPolyMeshSchema::Sample samp; - if (pmesh.getSchema().getNumSamples() > 0) - { - pmesh.getSchema().get(samp); - - Alembic::AbcGeom::P3fArraySamplePtr positions = samp.getPositions(); - Alembic::AbcGeom::Int32ArraySamplePtr indices = samp.getFaceIndices(); - Alembic::AbcGeom::Int32ArraySamplePtr counts = samp.getFaceCounts(); - - size_t P_size = positions->size(); - size_t counts_size = counts->size(); - - for (size_t i = 0; i < P_size; i++) - { - points->InsertNextPoint( - positions->get()[i].x, positions->get()[i].y, positions->get()[i].z); - } - - size_t face_index = 0; - for (size_t i = 0; i < counts_size; i++) - { - auto polyface_vertex_count = counts->get()[i]; - polys->InsertNextCell(polyface_vertex_count); - for (auto j = 0; j < polyface_vertex_count; j++) - { - polys->InsertCellPoint(indices->get()[face_index++]); - } - } - } - polydata->SetPoints(points); - polydata->SetPolys(polys); - - vtkNew polyMapper; - polyMapper->SetInputData(polydata); - vtkNew polyActor; - polyActor->SetMapper(polyMapper); - renderer->AddActor(polyActor); - } - - void IterateIObject(vtkRenderer* renderer, const Alembic::Abc::IObject& parent, - const Alembic::Abc::ObjectHeader& ohead) - { - // Set this if we should continue traversing - Alembic::Abc::IObject nextParentObject; - - if (Alembic::AbcGeom::IXform::matches(ohead)) - { - Alembic::AbcGeom::IXform xform(parent, ohead.getName()); - - nextParentObject = xform; - } - else if (Alembic::AbcGeom::IPolyMesh::matches(ohead)) - { - Alembic::AbcGeom::IPolyMesh polymesh(parent, ohead.getName()); - ProcessIPolyMesh(renderer, polymesh); - nextParentObject = polymesh; - } - - // Recursion - if (nextParentObject.valid()) - { - for (size_t i = 0; i < nextParentObject.getNumChildren(); ++i) - { - IterateIObject(renderer, nextParentObject, nextParentObject.getChildHeader(i)); - } - } - } - - void ImportRoot(vtkRenderer* renderer) - { - Alembic::Abc::IObject top = Archive.getTop(); - - for (size_t i = 0; i < top.getNumChildren(); ++i) - { - IterateIObject(renderer, top, top.getChildHeader(i)); - } - } - - void ImportCameras(vtkRenderer* vtkNotUsed(renderer)) {} - - void ImportLights(vtkRenderer* vtkNotUsed(renderer)) {} - - void ReadScene(const std::string& filePath) - { - - Alembic::AbcCoreFactory::IFactory factory; - Alembic::AbcCoreFactory::IFactory::CoreType core_type; - - Archive = factory.getArchive(filePath, core_type); - } - Alembic::Abc::IArchive Archive; -}; - -vtkStandardNewMacro(vtkF3DAlembicImporter); - -//---------------------------------------------------------------------------- -vtkF3DAlembicImporter::vtkF3DAlembicImporter() - : Internals(new vtkF3DAlembicImporter::vtkInternals()) -{ -} - -//---------------------------------------------------------------------------- -vtkF3DAlembicImporter::~vtkF3DAlembicImporter() = default; - -//---------------------------------------------------------------------------- -int vtkF3DAlembicImporter::ImportBegin() -{ - this->Internals->ReadScene(this->FileName); - - return 1; -} - -//---------------------------------------------------------------------------- -void vtkF3DAlembicImporter::ImportActors(vtkRenderer* renderer) -{ - this->Internals->ImportRoot(renderer); -} - -//---------------------------------------------------------------------------- -void vtkF3DAlembicImporter::PrintSelf(ostream& os, vtkIndent indent) -{ - this->Superclass::PrintSelf(os, indent); - os << indent << "FileName: " << this->FileName << "\n"; -} diff --git a/plugins/alembic/module/vtkF3DAlembicImporter.h b/plugins/alembic/module/vtkF3DAlembicImporter.h deleted file mode 100644 index a74f26d4b6..0000000000 --- a/plugins/alembic/module/vtkF3DAlembicImporter.h +++ /dev/null @@ -1,52 +0,0 @@ -/** - * @class vtkF3DAlembicImporter - * @brief Importer using Alembic library - * - * This importer is based on Alembic 1.7 - * Currently, only polygonal points positions are retrieved - * to build polygonal geometries. Vertex normals and texture - * coordinates are not supported yet. - * - * @sa https://github.com/alembic/alembic/blob/master/README.txt - * - */ - -#ifndef vtkF3DAlembicImporter_h -#define vtkF3DAlembicImporter_h - -#include -#include -#include - -#include - -class vtkF3DAlembicImporter : public vtkImporter -{ -public: - static vtkF3DAlembicImporter* New(); - vtkTypeMacro(vtkF3DAlembicImporter, vtkImporter); - void PrintSelf(ostream& os, vtkIndent indent) override; - - /** - * Set the file name. - */ - vtkSetMacro(FileName, std::string); - -protected: - vtkF3DAlembicImporter(); - ~vtkF3DAlembicImporter() override; - - int ImportBegin() override; - void ImportActors(vtkRenderer*) override; - - std::string FileName; - -private: - vtkF3DAlembicImporter(const vtkF3DAlembicImporter&) = delete; - void operator=(const vtkF3DAlembicImporter&) = delete; - - class vtkInternals; - std::unique_ptr Internals; -}; - -#endif diff --git a/plugins/alembic/module/vtkF3DAlembicReader.cxx b/plugins/alembic/module/vtkF3DAlembicReader.cxx new file mode 100644 index 0000000000..444c93558b --- /dev/null +++ b/plugins/alembic/module/vtkF3DAlembicReader.cxx @@ -0,0 +1,154 @@ +#include "vtkF3DAlembicReader.h" + +#include +#include +#include +#include +#include +#include + +#if defined(_MSC_VER) +#pragma warning(push, 0) +#endif +#include +#include +#include +#include +#include +#include +#if defined(_MSC_VER) +#pragma warning(pop) +#endif + +class vtkF3DAlembicReader::vtkInternals +{ +public: + vtkSmartPointer ProcessIPolyMesh(const Alembic::AbcGeom::IPolyMesh& pmesh) + { + vtkNew points; + vtkNew polys; + vtkNew polydata; + + Alembic::AbcGeom::IPolyMeshSchema::Sample samp; + if (pmesh.getSchema().getNumSamples() > 0) + { + pmesh.getSchema().get(samp); + + Alembic::AbcGeom::P3fArraySamplePtr positions = samp.getPositions(); + Alembic::AbcGeom::Int32ArraySamplePtr indices = samp.getFaceIndices(); + Alembic::AbcGeom::Int32ArraySamplePtr counts = samp.getFaceCounts(); + + points->SetNumberOfPoints(positions->size()); + + for (size_t i = 0; i < positions->size(); i++) + { + points->SetPoint(i, positions->get()[i].x, positions->get()[i].y, positions->get()[i].z); + } + + vtkNew offsets; + vtkNew connectivity; + offsets->SetNumberOfTuples(counts->size() + 1); + connectivity->SetNumberOfTuples(indices->size()); + + offsets->SetTypedComponent(0, 0, 0); + for (size_t i = 0; i < counts->size(); i++) + { + offsets->SetTypedComponent(i + 1, 0, offsets->GetTypedComponent(i, 0) + counts->get()[i]); + } + + for (size_t i = 0; i < indices->size(); i++) + { + connectivity->SetTypedComponent(i, 0, indices->get()[i]); + } + + polys->SetData(offsets, connectivity); + } + polydata->SetPoints(points); + polydata->SetPolys(polys); + + return polydata; + } + + void IterateIObject(vtkAppendPolyData* append, const Alembic::Abc::IObject& parent, + const Alembic::Abc::ObjectHeader& ohead) + { + // Set this if we should continue traversing + Alembic::Abc::IObject nextParentObject; + + if (Alembic::AbcGeom::IXform::matches(ohead)) + { + Alembic::AbcGeom::IXform xform(parent, ohead.getName()); + nextParentObject = xform; + } + else if (Alembic::AbcGeom::IPolyMesh::matches(ohead)) + { + Alembic::AbcGeom::IPolyMesh polymesh(parent, ohead.getName()); + append->AddInputData(ProcessIPolyMesh(polymesh)); + nextParentObject = polymesh; + } + + // Recursion + if (nextParentObject.valid()) + { + for (size_t i = 0; i < nextParentObject.getNumChildren(); ++i) + { + this->IterateIObject(append, nextParentObject, nextParentObject.getChildHeader(i)); + } + } + } + + void ImportRoot(vtkAppendPolyData* append) + { + Alembic::Abc::IObject top = this->Archive.getTop(); + + for (size_t i = 0; i < top.getNumChildren(); ++i) + { + this->IterateIObject(append, top, top.getChildHeader(i)); + } + } + + void ReadArchive(const std::string& filePath) + { + Alembic::AbcCoreFactory::IFactory factory; + Alembic::AbcCoreFactory::IFactory::CoreType coreType; + + this->Archive = factory.getArchive(filePath, coreType); + } + Alembic::Abc::IArchive Archive; +}; + +vtkStandardNewMacro(vtkF3DAlembicReader); + +//---------------------------------------------------------------------------- +vtkF3DAlembicReader::vtkF3DAlembicReader() + : Internals(new vtkF3DAlembicReader::vtkInternals()) +{ + this->SetNumberOfInputPorts(0); +} + +//---------------------------------------------------------------------------- +vtkF3DAlembicReader::~vtkF3DAlembicReader() = default; + +//---------------------------------------------------------------------------- +int vtkF3DAlembicReader::RequestData( + vtkInformation*, vtkInformationVector**, vtkInformationVector* outputVector) +{ + vtkPolyData* output = vtkPolyData::GetData(outputVector); + + this->Internals->ReadArchive(this->FileName); + + vtkNew append; + this->Internals->ImportRoot(append); + append->Update(); + + output->ShallowCopy(append->GetOutput()); + + return 1; +} + +//---------------------------------------------------------------------------- +void vtkF3DAlembicReader::PrintSelf(ostream& os, vtkIndent indent) +{ + this->Superclass::PrintSelf(os, indent); + os << indent << "FileName: " << this->FileName << "\n"; +} diff --git a/plugins/alembic/module/vtkF3DAlembicReader.h b/plugins/alembic/module/vtkF3DAlembicReader.h new file mode 100644 index 0000000000..04b1a90873 --- /dev/null +++ b/plugins/alembic/module/vtkF3DAlembicReader.h @@ -0,0 +1,51 @@ +/** + * @class vtkF3DAlembicReader + * @brief Reader using Alembic library + * + * This reader is based on Alembic 1.7 + * Currently, only polygonal points positions are retrieved + * to build polygonal geometries. Vertex normals and texture + * coordinates are not supported yet. + * + * @sa https://github.com/alembic/alembic/blob/master/README.txt + * + */ + +#ifndef vtkF3DAlembicReader_h +#define vtkF3DAlembicReader_h + +#include +#include +#include + +#include + +class vtkF3DAlembicReader : public vtkPolyDataAlgorithm +{ +public: + static vtkF3DAlembicReader* New(); + vtkTypeMacro(vtkF3DAlembicReader, vtkPolyDataAlgorithm); + void PrintSelf(ostream& os, vtkIndent indent) override; + + /** + * Set the file name. + */ + vtkSetMacro(FileName, std::string); + +protected: + vtkF3DAlembicReader(); + ~vtkF3DAlembicReader() override; + + int RequestData(vtkInformation*, vtkInformationVector**, vtkInformationVector*) override; + + std::string FileName; + +private: + vtkF3DAlembicReader(const vtkF3DAlembicReader&) = delete; + void operator=(const vtkF3DAlembicReader&) = delete; + + class vtkInternals; + std::unique_ptr Internals; +}; + +#endif diff --git a/testing/baselines/TestABC.png b/testing/baselines/TestABC.png index 3a7516279f..850cf8286c 100644 --- a/testing/baselines/TestABC.png +++ b/testing/baselines/TestABC.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:264f8b81d0746f0edcd70026ebfdc1018b5d58d32187f04f29faa1c65b22a895 -size 13886 +oid sha256:690c69a095683fcfe7806cded45936f8f2f05e3652e6b86eee450c0a0c722f45 +size 13908 diff --git a/testing/baselines/TestDefaultConfigFileAlembic.png b/testing/baselines/TestDefaultConfigFileAlembic.png index 96e6aded2a..c04e7c6a6f 100644 --- a/testing/baselines/TestDefaultConfigFileAlembic.png +++ b/testing/baselines/TestDefaultConfigFileAlembic.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:758c4800dd31e4e61ff5081be370cc04054d512ef813214dfa72442ac194b680 -size 47355 +oid sha256:894e66cd603e6345fa4eec825ce78947d4cba24beb861948a65847ced26188ec +size 44898 diff --git a/testing/baselines/TestThumbnailConfigFileAlembic.png b/testing/baselines/TestThumbnailConfigFileAlembic.png index db66e4087c..6493e6511e 100644 --- a/testing/baselines/TestThumbnailConfigFileAlembic.png +++ b/testing/baselines/TestThumbnailConfigFileAlembic.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:828c08b833c3f27197e91de8f4366923c80d253b6680260d34f7af0bf49c5340 -size 18879 +oid sha256:bfc3a8d82e424be996ebc57cf0e20438178eac22489a1c04f322303115aca1d4 +size 16044