Skip to content

Commit

Permalink
feat(PointSet): initial C++ addition
Browse files Browse the repository at this point in the history
  • Loading branch information
thewtex committed Jul 21, 2024
1 parent 60ef538 commit 65ad083
Show file tree
Hide file tree
Showing 15 changed files with 1,400 additions and 2 deletions.
113 changes: 113 additions & 0 deletions include/itkInputPointSet.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
/*=========================================================================
*
* Copyright NumFOCUS
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0.txt
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*=========================================================================*/
#ifndef itkInputPointSet_h
#define itkInputPointSet_h

#include "itkPipeline.h"

#ifndef ITK_WASM_NO_MEMORY_IO
#include "itkWasmExports.h"
#include "itkWasmPointSet.h"
#include "itkWasmPointSetToPointSetFilter.h"
#endif
#ifndef ITK_WASM_NO_FILESYSTEM_IO
#include "itkMesh.h"
#include "itkMeshFileReader.h"
#endif

namespace itk
{
namespace wasm
{

/**
*\class InputPointSet
* \brief Input pointSet for an itk::wasm::Pipeline
*
* This point set is read from the filesystem or memory when ITK_WASM_PARSE_ARGS is called.
*
* Call `Get()` to get the TPointSet * to use an input to a pipeline.
*
* \ingroup WebAssemblyInterface
*/
template <typename TPointSet>
class ITK_TEMPLATE_EXPORT InputPointSet
{
public:
using PointSetType = TPointSet;

void Set(const PointSetType * pointSet) {
this->m_PointSet = pointSet;
}

const PointSetType * Get() const {
return this->m_PointSet.GetPointer();
}

InputPointSet() = default;
~InputPointSet() = default;
protected:
typename TPointSet::ConstPointer m_PointSet;
};


template <typename TPointSet>
bool lexical_cast(const std::string &input, InputPointSet<TPointSet> &inputPointSet)
{
if (input.empty())
{
return false;
}

if (wasm::Pipeline::get_use_memory_io())
{
#ifndef ITK_WASM_NO_MEMORY_IO
using WasmPointSetToPointSetFilterType = WasmPointSetToPointSetFilter<TPointSet>;
auto wasmPointSetToPointSetFilter = WasmPointSetToPointSetFilterType::New();
auto wasmPointSet = WasmPointSetToPointSetFilterType::WasmPointSetType::New();
const unsigned int index = std::stoi(input);
auto json = getMemoryStoreInputJSON(0, index);
wasmPointSet->SetJSON(json);
wasmPointSetToPointSetFilter->SetInput(wasmPointSet);
wasmPointSetToPointSetFilter->Update();
inputPointSet.Set(wasmPointSetToPointSetFilter->GetOutput());
#else
return false;
#endif
}
else
{
#ifndef ITK_WASM_NO_FILESYSTEM_IO
using MeshType = Mesh<typename TPointSet::PixelType, TPointSet::PointDimension>;
using ReaderType = MeshFileReader<MeshType>;
auto reader = ReaderType::New();
reader->SetFileName(input);
reader->Update();
auto pointSet = reader->GetOutput();
inputPointSet.Set(pointSet);
#else
return false;
#endif
}
return true;
}

} // end namespace wasm
} // end namespace itk

#endif
145 changes: 145 additions & 0 deletions include/itkOutputPointSet.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,145 @@
/*=========================================================================
*
* Copyright NumFOCUS
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0.txt
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*=========================================================================*/
#ifndef itkOutputPointSet_h
#define itkOutputPointSet_h

#include "itkPipeline.h"
#include "itkMeshConvertPixelTraits.h"

#ifndef ITK_WASM_NO_MEMORY_IO
#include "itkWasmExports.h"
#include "itkWasmPointSet.h"
#include "itkPointSetToWasmPointSetFilter.h"
#endif
#ifndef ITK_WASM_NO_FILESYSTEM_IO
#include "itkMesh.h"
#include "itkMeshFileWriter.h"
#endif

namespace itk
{
namespace wasm
{
/**
*\class OutputPointSet
* \brief Output point set for an itk::wasm::Pipeline
*
* This point set is written to the filesystem or memory when it goes out of scope.
*
* Call `GetPointSet()` to get the TPointSet * to use an input to a pipeline.
*
* \ingroup WebAssemblyInterface
*/
template <typename TPointSet>
class ITK_TEMPLATE_EXPORT OutputPointSet
{
public:
using PointSetType = TPointSet;

void Set(const PointSetType * pointSet) {
this->m_PointSet = pointSet;
}

const PointSetType * Get() const {
return this->m_PointSet.GetPointer();
}

/** FileName or output index. */
void SetIdentifier(const std::string & identifier)
{
this->m_Identifier = identifier;
}
const std::string & GetIdentifier() const
{
return this->m_Identifier;
}

OutputPointSet() = default;
~OutputPointSet() {
if(wasm::Pipeline::get_use_memory_io())
{
#ifndef ITK_WASM_NO_MEMORY_IO
if (!this->m_PointSet.IsNull() && !this->m_Identifier.empty())
{
using PointSetToWasmPointSetFilterType = PointSetToWasmPointSetFilter<PointSetType>;
auto pointSetToWasmPointSetFilter = PointSetToWasmPointSetFilterType::New();
pointSetToWasmPointSetFilter->SetInput(this->m_PointSet);
pointSetToWasmPointSetFilter->Update();
auto wasmPointSet = pointSetToWasmPointSetFilter->GetOutput();
const auto index = std::stoi(this->m_Identifier);
setMemoryStoreOutputDataObject(0, index, wasmPointSet);

if (this->m_PointSet->GetNumberOfPoints() > 0)
{
const auto pointsAddress = reinterpret_cast< size_t >( &(wasmPointSet->GetPointSet()->GetPoints()->at(0)) );
const auto pointsSize = wasmPointSet->GetPointSet()->GetPoints()->Size() * sizeof(typename PointSetType::CoordRepType) * PointSetType::PointDimension;
setMemoryStoreOutputArray(0, index, 0, pointsAddress, pointsSize);
}

if (this->m_PointSet->GetPointData() != nullptr && this->m_PointSet->GetPointData()->Size() > 0)
{
using PointPixelType = typename PointSetType::PixelType;
using ConvertPointPixelTraits = MeshConvertPixelTraits<PointPixelType>;
const auto pointDataAddress = reinterpret_cast< size_t >( &(wasmPointSet->GetPointSet()->GetPointData()->at(0)) );
const auto pointDataSize = wasmPointSet->GetPointSet()->GetPointData()->Size() * sizeof(typename ConvertPointPixelTraits::ComponentType) * ConvertPointPixelTraits::GetNumberOfComponents();
setMemoryStoreOutputArray(0, index, 1, pointDataAddress, pointDataSize);
}
}
#else
std::cerr << "Memory IO not supported" << std::endl;
abort();
#endif
}
else
{
#ifndef ITK_WASM_NO_FILESYSTEM_IO
if (!this->m_PointSet.IsNull() && !this->m_Identifier.empty())
{
using MeshType = Mesh<typename TPointSet::PixelType, TPointSet::PointDimension>;
using PointSetWriterType = itk::MeshFileWriter<MeshType>;
auto pointSetWriter = PointSetWriterType::New();
pointSetWriter->SetFileName(this->m_Identifier);
typename MeshType::Pointer mesh = MeshType::New();
mesh->SetPoints(const_cast<typename MeshType::PointsContainer *>(this->m_PointSet->GetPoints()));
mesh->SetPointData(const_cast<typename MeshType::PointDataContainer *>(this->m_PointSet->GetPointData()));
pointSetWriter->SetInput(mesh);
pointSetWriter->Update();
}
#else
std::cerr << "Filesystem IO not supported" << std::endl;
abort();
#endif
}
}
protected:
typename TPointSet::ConstPointer m_PointSet;

std::string m_Identifier;
};

template <typename TPointSet>
bool lexical_cast(const std::string &input, OutputPointSet<TPointSet> &outputPointSet)
{
outputPointSet.SetIdentifier(input);
return true;
}

} // namespace wasm
} // namespace itk

#endif
128 changes: 128 additions & 0 deletions include/itkPointSetJSON.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
/*=========================================================================
*
* Copyright NumFOCUS
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0.txt
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*=========================================================================*/
#ifndef itkPointSetJSON_h
#define itkPointSetJSON_h

#include "itkMeshConvertPixelTraits.h"

#include "itkWasmMapComponentType.h"
#include "itkWasmMapPixelType.h"
#include "itkIntTypesJSON.h"
#include "itkFloatTypesJSON.h"
#include "itkPixelTypesJSON.h"
#include "itkWasmPointSet.h"
#include "itkMetaDataDictionaryJSON.h"

#include "glaze/glaze.hpp"

namespace itk
{
/** \class PointSetTypeJSON
*
* \brief PointSet type JSON representation data structure.
*
* \ingroup WebAssemblyInterface
*/
struct PointSetTypeJSON
{
unsigned int dimension { 2 };
JSONFloatTypesEnum pointComponentType { JSONFloatTypesEnum::float32 };
JSONComponentTypesEnum pointPixelComponentType { JSONComponentTypesEnum::float32 };
JSONPixelTypesEnum pointPixelType { JSONPixelTypesEnum::Scalar };
unsigned int pointPixelComponents { 1 };
};

/** \class PointSetJSON
*
* \brief PointSet JSON representation data structure.
*
* \ingroup WebAssemblyInterface
*/
struct PointSetJSON
{
PointSetTypeJSON pointSetType;

std::string name { "PointSet"};

size_t numberOfPoints{ 0 };
std::string points;

size_t numberOfPointPixels{ 0 };
std::string pointData;

MetadataJSON metadata;
};

template<typename TPointSet>
auto pointSetToPointSetJSON(const TPointSet * pointSet, const WasmPointSet<TPointSet> * wasmPointSet, bool inMemory) -> PointSetJSON
{
using PointSetType = TPointSet;

PointSetJSON pointSetJSON;

pointSetJSON.pointSetType.dimension = PointSetType::PointDimension;

pointSetJSON.pointSetType.pointComponentType = wasm::MapComponentType<typename PointSetType::CoordRepType>::JSONFloatTypeEnum;
using PointPixelType = typename TPointSet::PixelType;
using ConvertPointPixelTraits = MeshConvertPixelTraits<PointPixelType>;
pointSetJSON.pointSetType.pointPixelComponentType = wasm::MapComponentType<typename ConvertPointPixelTraits::ComponentType>::JSONComponentEnum;
pointSetJSON.pointSetType.pointPixelType = wasm::MapPixelType<PointPixelType>::JSONPixelEnum;
pointSetJSON.pointSetType.pointPixelComponents = ConvertPointPixelTraits::GetNumberOfComponents();

pointSetJSON.name = pointSet->GetObjectName();
pointSetJSON.numberOfPoints = pointSet->GetNumberOfPoints();
if (pointSet->GetPointData() == nullptr)
{
pointSetJSON.numberOfPointPixels = 0;
}
else
{
pointSetJSON.numberOfPointPixels = pointSet->GetPointData()->Size();
}
if (inMemory)
{
const auto pointsAddress = reinterpret_cast< size_t >( &(pointSet->GetPoints()->at(0)) );
std::ostringstream pointsStream;
pointsStream << "data:application/vnd.itk.address,0:";
pointsStream << pointsAddress;
pointSetJSON.points = pointsStream.str();

size_t pointDataAddress = 0;
if (pointSet->GetPointData() != nullptr && pointSet->GetPointData()->Size() > 0)
{
pointDataAddress = reinterpret_cast< size_t >( &(pointSet->GetPointData()->at(0)) );
}
std::ostringstream pointDataStream;
pointDataStream << "data:application/vnd.itk.address,0:";
pointDataStream << pointDataAddress;
pointSetJSON.pointData = pointDataStream.str();
}
else
{
pointSetJSON.points = "data:application/vnd.itk.path,data/points.raw";
pointSetJSON.pointData = "data:application/vnd.itk.path,data/point-data.raw";
}

auto dictionary = pointSet->GetMetaDataDictionary();
metaDataDictionaryToJSON(dictionary, pointSetJSON.metadata);

return pointSetJSON;
}
} // end namespace itk

#endif // itkPointSetJSON_h
Loading

0 comments on commit 65ad083

Please sign in to comment.