Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
56 commits
Select commit Hold shift + click to select a range
1e274d7
feat(mesh-filters): geogram conversion test pipeline
thewtex Dec 11, 2024
11db76c
feat(WasmMeshToMeshFilter): add QuadEdgeMesh specialization
thewtex Dec 12, 2024
04c33be
feat(MeshToWasmMeshFilter): add QuadEdgeMesh specialization
thewtex Dec 13, 2024
855a6ea
feat(mesh-filters): start meshtoGeogramMesh
thewtex Dec 13, 2024
b734fa8
feat(meshToGeogramMesh): transfer point data, cell data
thewtex Dec 13, 2024
40b286f
feat(mesh-filters): geogramMeshToMesh
thewtex Dec 13, 2024
0922728
feat(mesh-filters): add repair pipeline
thewtex Dec 14, 2024
47e1ca5
feat(mesh-filters): add smooth-remesh
thewtex Dec 14, 2024
f5a2063
fix(WasmMeshToMeshFilter): add PolyLine cell support
thewtex Dec 14, 2024
6c1da13
feat(mesh-filters): add slice-mesh pipeline
thewtex Dec 15, 2024
20ee7ec
feat(mesh-filters): add keep-largest-component
thewtex Dec 16, 2024
910a0d9
test(mesh-filters): update test data
thewtex Dec 16, 2024
8b1a4b7
docs(options-module): indicate unexpected parameter type error source
thewtex Dec 17, 2024
dcf1f0f
fix(pnpm-script): quote packageDescription
thewtex Dec 17, 2024
4ecff1b
build(mesh-filters): contrain geogram build
thewtex Dec 17, 2024
15ca8ca
build(mesh-filters): fix wasi OFF module dependency
thewtex Dec 17, 2024
e147367
fix(mesh-filters): update geogram-conversion pipeline name
thewtex Dec 17, 2024
5ece2ed
build(mesh-filters): wasi patches for pmp, geogram
thewtex Dec 17, 2024
46d8489
fix(mesh-filters): use add_flag in repair for boolean option
thewtex Dec 17, 2024
a1c7e49
WIP: test(mesh-filters): add node tests
thewtex Dec 17, 2024
80d13dd
test(mesh-filters): add node tests
thewtex Dec 18, 2024
93abe22
feat(compare-meshes): support more pixel types
thewtex Dec 18, 2024
645a1ea
chore(compare-meshes): bump version to 0.5.0
thewtex Dec 18, 2024
a010c8d
chore(compare-meshes): update pixi.lock
thewtex Dec 18, 2024
5eae02f
feat(mesh-filters): support more pixel types
thewtex Dec 20, 2024
163a1f9
test(mesh-filters): update test data
thewtex Dec 20, 2024
53eb193
chore(mesh-filters): bump version to 0.2.0
thewtex Dec 20, 2024
18572f5
Merge branch 'wasi-ci' into mesh-filters
thewtex Jan 3, 2025
8055478
Merge branch 'main' into mesh-filters
thewtex Jan 28, 2025
ba25b2e
feat(itk-wasm-cli): Update default Docker image for 20250128-80554789
thewtex Jan 28, 2025
3236bde
docs(docker): update docker image update process
thewtex Jan 28, 2025
aac71be
build(mesh-filters): bypass geogram-related warnings
thewtex Jan 28, 2025
c0f467b
build(MeshToPolyData): pass toolchain flags
thewtex Jan 28, 2025
ad7e804
build(glaze): bypass static_assert warnings
thewtex Jan 28, 2025
660258a
Merge branch 'main' into mesh-filters
thewtex Jan 28, 2025
74c373d
feat(itk-wasm-cli): Update default Docker image for 20250128-660258ac
thewtex Jan 28, 2025
e081756
build(mesh-filters): bump geogram to latest
thewtex Jan 29, 2025
ee3adcb
build(mesh-filters): address wasi build
thewtex Jan 29, 2025
8170a0c
build(mesh-filters): add pixi configuration
thewtex Jan 29, 2025
91e3eb9
chore(mesh-filters): add typescript generated files
thewtex Jan 29, 2025
7d55516
chore(mesh-filters): add pixi.lock
thewtex Jan 29, 2025
60f054a
test(mesh-filters): define test_repair.py
thewtex Jan 29, 2025
285d970
test(mesh-filters): keep_largest_component wasi test
thewtex Jan 29, 2025
aa820ea
test(mesh-filters): define test_smooth_remesh
thewtex Jan 29, 2025
3241977
test(mesh-filters): add test_slice_mesh.py
thewtex Jan 29, 2025
bd46618
chore(mesh-filters): add test data to .gitignore
thewtex Jan 29, 2025
109eb0a
chore(mesh-filters): bump version to 1.6.0
thewtex Jan 29, 2025
06e63d4
test(image-io): exclude wasi gdcm write tests
thewtex Jan 29, 2025
9b2765f
build(mesh-filters): add wasi emulated process clocks flags
thewtex Jan 29, 2025
aed9348
build(mesh-filters): add -msimd128, -flto
thewtex Jan 29, 2025
c282133
build(docker): ensure WASI CMake variable is set
thewtex Jan 30, 2025
c78034a
build(mesh-filters): add geogram WASI flags via VORPALINE_PLATFORM
thewtex Jan 30, 2025
1cafe9f
build(docker): overwrite dockcross wasi CMake toolchain file with our…
thewtex Jan 30, 2025
11f6cb1
build(docker): pass CMAKE_TOOLCHAIN_FILE in web-build
thewtex Jan 30, 2025
5b470fe
feat(itk-wasm-cli): Update default Docker image for 20250130-11f6cb11
thewtex Jan 30, 2025
d9af7c1
test(mesh-filters): use off for slice-mesh outputs
thewtex Jan 30, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
95 changes: 95 additions & 0 deletions include/itkMeshJSON.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
#include "itkPixelTypesJSON.h"
#include "itkWasmMesh.h"
#include "itkMetaDataDictionaryJSON.h"
#include "itkQuadEdge.h"

#include "glaze/glaze.hpp"

Expand Down Expand Up @@ -172,6 +173,100 @@ auto meshToMeshJSON(const TMesh * mesh, const WasmMesh<TMesh> * wasmMesh, bool i

return meshJSON;
}

template <typename TPixel, unsigned int VDimension>
auto meshToMeshJSON(const QuadEdgeMesh<TPixel, VDimension> * mesh, const WasmMesh<QuadEdgeMesh<TPixel, VDimension>> * wasmMesh, bool inMemory) -> MeshJSON
{
using MeshType = QuadEdgeMesh<TPixel, VDimension>;

MeshJSON meshJSON;

meshJSON.meshType.dimension = MeshType::PointDimension;

meshJSON.meshType.pointComponentType = wasm::MapComponentType<typename MeshType::CoordRepType>::JSONFloatTypeEnum;
using PointPixelType = typename MeshType::PixelType;
using ConvertPointPixelTraits = MeshConvertPixelTraits<PointPixelType>;
meshJSON.meshType.pointPixelComponentType = wasm::MapComponentType<typename ConvertPointPixelTraits::ComponentType>::JSONComponentEnum;
meshJSON.meshType.pointPixelType = wasm::MapPixelType<PointPixelType>::JSONPixelEnum;
meshJSON.meshType.pointPixelComponents = ConvertPointPixelTraits::GetNumberOfComponents();
meshJSON.meshType.cellComponentType = wasm::MapComponentType<typename MeshType::CellIdentifier>::JSONIntTypeEnum;
using CellPixelType = typename MeshType::CellPixelType;
using ConvertCellPixelTraits = MeshConvertPixelTraits<CellPixelType>;
meshJSON.meshType.cellPixelComponentType = wasm::MapComponentType<typename ConvertPointPixelTraits::ComponentType>::JSONComponentEnum;
meshJSON.meshType.cellPixelType = wasm::MapPixelType<CellPixelType>::JSONPixelEnum;
meshJSON.meshType.cellPixelComponents = ConvertCellPixelTraits::GetNumberOfComponents();

meshJSON.name = mesh->GetObjectName();
meshJSON.numberOfPoints = mesh->GetNumberOfPoints();
if (mesh->GetPointData() == nullptr)
{
meshJSON.numberOfPointPixels = 0;
}
else
{
meshJSON.numberOfPointPixels = mesh->GetPointData()->Size();
}
meshJSON.numberOfCells = mesh->GetNumberOfCells();
if (mesh->GetCellData() == nullptr)
{
meshJSON.numberOfCellPixels = 0;
}
else
{
meshJSON.numberOfCellPixels = mesh->GetCellData()->Size();
}
if (inMemory)
{
meshJSON.cellBufferSize = wasmMesh->GetCellBuffer()->Size();

const auto pointsAddress = reinterpret_cast< size_t >( &(wasmMesh->GetPointsBuffer().at(0)) );
std::ostringstream pointsStream;
pointsStream << "data:application/vnd.itk.address,0:";
pointsStream << pointsAddress;
meshJSON.points = pointsStream.str();
size_t cellsAddress = 0;
if (mesh->GetNumberOfCells() > 0)
{
cellsAddress = reinterpret_cast< size_t >( &(wasmMesh->GetCellBuffer()->at(0)) );
}
std::ostringstream cellsStream;
cellsStream << "data:application/vnd.itk.address,0:";
cellsStream << cellsAddress;
meshJSON.cells = cellsStream.str();

size_t pointDataAddress = 0;
if (mesh->GetPointData() != nullptr && mesh->GetPointData()->Size() > 0)
{
pointDataAddress = reinterpret_cast< size_t >( &(wasmMesh->GetPointDataBuffer().at(0)) );
}
std::ostringstream pointDataStream;
pointDataStream << "data:application/vnd.itk.address,0:";
pointDataStream << pointDataAddress;
meshJSON.pointData = pointDataStream.str();

size_t cellDataAddress = 0;
if (mesh->GetCellData() != nullptr && mesh->GetCellData()->Size() > 0)
{
cellDataAddress = reinterpret_cast< size_t >( &(wasmMesh->GetCellDataBuffer().at(0)) );
}
std::ostringstream cellDataStream;
cellDataStream << "data:application/vnd.itk.address,0:";
cellDataStream << cellDataAddress;
meshJSON.cellData = cellDataStream.str();
}
else
{
meshJSON.points = "data:application/vnd.itk.path,data/points.raw";
meshJSON.cells = "data:application/vnd.itk.path,data/cells.raw";
meshJSON.pointData = "data:application/vnd.itk.path,data/point-data.raw";
meshJSON.cellData = "data:application/vnd.itk.path,data/cell-data.raw";
}

auto dictionary = mesh->GetMetaDataDictionary();
metaDataDictionaryToJSON(dictionary, meshJSON.metadata);

return meshJSON;
}
} // end namespace itk

#endif // itkMeshJSON_h
66 changes: 66 additions & 0 deletions include/itkMeshToWasmMeshFilter.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
#include "itkProcessObject.h"
#include "itkWasmMesh.h"
#include "itkMeshJSON.h"
#include "itkQuadEdgeMesh.h"

namespace itk
{
Expand Down Expand Up @@ -76,6 +77,71 @@ class ITK_TEMPLATE_EXPORT MeshToWasmMeshFilter : public ProcessObject
WasmMeshType *
GetOutput(unsigned int idx);

protected:
MeshToWasmMeshFilter();
~MeshToWasmMeshFilter() override = default;

ProcessObject::DataObjectPointer
MakeOutput(ProcessObject::DataObjectPointerArraySizeType idx) override;
ProcessObject::DataObjectPointer
MakeOutput(const ProcessObject::DataObjectIdentifierType &) override;

void
GenerateOutputInformation() override
{} // do nothing
void
GenerateData() override;

void
PrintSelf(std::ostream & os, Indent indent) const override;
};

template <typename TPixel, unsigned int VDimension>
class ITK_TEMPLATE_EXPORT MeshToWasmMeshFilter<QuadEdgeMesh<TPixel, VDimension>> : public ProcessObject
{
public:
ITK_DISALLOW_COPY_AND_MOVE(MeshToWasmMeshFilter);

/** Standard class type aliases. */
using Self = MeshToWasmMeshFilter;
using Superclass = ProcessObject;
using Pointer = SmartPointer<Self>;
using ConstPointer = SmartPointer<const Self>;

/** Method for creation through the object factory. */
itkNewMacro(Self);

/** Run-time type information (and related methods). */
itkTypeMacro(MeshToWasmMeshFilter, ProcessObject);

using DataObjectIdentifierType = Superclass::DataObjectIdentifierType;
using DataObjectPointerArraySizeType = Superclass::DataObjectPointerArraySizeType;

using MeshType = QuadEdgeMesh<TPixel, VDimension>;
using WasmMeshType = WasmMesh<MeshType>;

/** Set/Get the path input of this process object. */
using Superclass::SetInput;
virtual void
SetInput(const MeshType * mesh);

virtual void
SetInput(unsigned int, const MeshType * mesh);

const MeshType *
GetInput();

const MeshType *
GetInput(unsigned int idx);

WasmMeshType *
GetOutput();
const WasmMeshType *
GetOutput() const;

WasmMeshType *
GetOutput(unsigned int idx);

protected:
MeshToWasmMeshFilter();
~MeshToWasmMeshFilter() override = default;
Expand Down
124 changes: 124 additions & 0 deletions include/itkMeshToWasmMeshFilter.hxx
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,130 @@ MeshToWasmMeshFilter<TMesh>
{
Superclass::PrintSelf(os, indent);
}

template <typename TPixel, unsigned int VDimension>
MeshToWasmMeshFilter<QuadEdgeMesh<TPixel, VDimension>>
::MeshToWasmMeshFilter()
{
this->SetNumberOfRequiredInputs(1);

typename WasmMeshType::Pointer output = static_cast<WasmMeshType *>(this->MakeOutput(0).GetPointer());
this->ProcessObject::SetNumberOfRequiredOutputs(1);
this->ProcessObject::SetNthOutput(0, output.GetPointer());
}

template <typename TPixel, unsigned int VDimension>
ProcessObject::DataObjectPointer
MeshToWasmMeshFilter<QuadEdgeMesh<TPixel, VDimension>>
::MakeOutput(ProcessObject::DataObjectPointerArraySizeType)
{
return WasmMeshType::New().GetPointer();
}

template <typename TPixel, unsigned int VDimension>
ProcessObject::DataObjectPointer
MeshToWasmMeshFilter<QuadEdgeMesh<TPixel, VDimension>>
::MakeOutput(const ProcessObject::DataObjectIdentifierType &)
{
return WasmMeshType::New().GetPointer();
}

template <typename TPixel, unsigned int VDimension>
auto
MeshToWasmMeshFilter<QuadEdgeMesh<TPixel, VDimension>>
::GetOutput() -> WasmMeshType *
{
// we assume that the first output is of the templated type
return itkDynamicCastInDebugMode<WasmMeshType *>(this->GetPrimaryOutput());
}

template <typename TPixel, unsigned int VDimension>
auto
MeshToWasmMeshFilter<QuadEdgeMesh<TPixel, VDimension>>
::GetOutput() const -> const WasmMeshType *
{
// we assume that the first output is of the templated type
return itkDynamicCastInDebugMode<const WasmMeshType *>(this->GetPrimaryOutput());
}

template <typename TPixel, unsigned int VDimension>
auto
MeshToWasmMeshFilter<QuadEdgeMesh<TPixel, VDimension>>
::GetOutput(unsigned int idx) -> WasmMeshType *
{
auto * out = dynamic_cast<WasmMeshType *>(this->ProcessObject::GetOutput(idx));

if (out == nullptr && this->ProcessObject::GetOutput(idx) != nullptr)
{
itkWarningMacro(<< "Unable to convert output number " << idx << " to type " << typeid(WasmMeshType).name());
}
return out;
}

template <typename TPixel, unsigned int VDimension>
void
MeshToWasmMeshFilter<QuadEdgeMesh<TPixel, VDimension>>
::SetInput(const MeshType * input)
{
// Process object is not const-correct so the const_cast is required here
this->ProcessObject::SetNthInput(0, const_cast<MeshType *>(input));
}

template <typename TPixel, unsigned int VDimension>
void
MeshToWasmMeshFilter<QuadEdgeMesh<TPixel, VDimension>>
::SetInput(unsigned int index, const MeshType * mesh)
{
// Process object is not const-correct so the const_cast is required here
this->ProcessObject::SetNthInput(index, const_cast<MeshType *>(mesh));
}

template <typename TPixel, unsigned int VDimension>
const typename MeshToWasmMeshFilter<QuadEdgeMesh<TPixel, VDimension>>::MeshType *
MeshToWasmMeshFilter<QuadEdgeMesh<TPixel, VDimension>>
::GetInput()
{
return itkDynamicCastInDebugMode<const MeshType *>(this->GetPrimaryInput());
}

template <typename TPixel, unsigned int VDimension>
const typename MeshToWasmMeshFilter<QuadEdgeMesh<TPixel, VDimension>>::MeshType *
MeshToWasmMeshFilter<QuadEdgeMesh<TPixel, VDimension>>
::GetInput(unsigned int idx)
{
return itkDynamicCastInDebugMode<const MeshType *>(this->ProcessObject::GetInput(idx));
}

template <typename TPixel, unsigned int VDimension>
void
MeshToWasmMeshFilter<QuadEdgeMesh<TPixel, VDimension>>
::GenerateData()
{
// Get the input and output pointers
const MeshType * mesh = this->GetInput();
WasmMeshType * wasmMesh = this->GetOutput();

wasmMesh->SetMesh(mesh);
constexpr bool inMemory = true;
const auto meshJSON = meshToMeshJSON<TPixel, VDimension>(mesh, wasmMesh, inMemory);
std::string serialized{};
auto ec = glz::write<glz::opts{ .prettify = true }>(meshJSON, serialized);
if (ec)
{
itkExceptionMacro("Failed to serialize MeshJSON");
}

wasmMesh->SetJSON(serialized);
}

template <typename TPixel, unsigned int VDimension>
void
MeshToWasmMeshFilter<QuadEdgeMesh<TPixel, VDimension>>
::PrintSelf(std::ostream & os, Indent indent) const
{
Superclass::PrintSelf(os, indent);
}

} // end namespace itk

#endif
Loading
Loading