Skip to main content
  • Home
  • Development
  • Documentation
  • Donate
  • Operational login
  • Browse the archive

swh logo
SoftwareHeritage
Software
Heritage
Archive
Features
  • Search

  • Downloads

  • Save code now

  • Add forge now

  • Help

Raw File Download

To reference or cite the objects present in the Software Heritage archive, permalinks based on SoftWare Hash IDentifiers (SWHIDs) must be used.
Select below a type of object currently browsed in order to display its associated SWHID and permalink.

  • content
content badge Iframe embedding
swh:1:cnt:aff4a566eb5cf27a5be58a70a70e6ff589c01e3e

This interface enables to generate software citations, provided that the root directory of browsed objects contains a citation.cff or codemeta.json file.
Select below a type of object currently browsed in order to generate citations for them.

  • content
Generate software citation in BibTex format (requires biblatex-software package)
Generating citation ...
//
// Created by sjeske on 1/22/20.
//
#include "common.h"

#include <vector>
#include <array>
#include <iostream>

#include <pybind11/pybind11.h>
#include <pybind11/eigen.h>
#include <pybind11/stl.h>
#include <pybind11/stl_bind.h>
#include <pybind11/chrono.h>
#include <Utilities/BinaryFileReaderWriter.h>
#include <Utilities/Counting.h>
#include <Utilities/FileSystem.h>
#include <Utilities/OBJLoader.h>
#include <Utilities/PartioReaderWriter.h>
#include <SPlisHSPlasH/Utilities/GaussQuadrature.h>
#include <SPlisHSPlasH/Utilities/MathFunctions.h>
#include <SPlisHSPlasH/Utilities/MatrixFreeSolver.h>
#include <SPlisHSPlasH/Utilities/PoissonDiskSampling.h>
#include <SPlisHSPlasH/Utilities/RegularSampling2D.h>
#include <SPlisHSPlasH/Utilities/RegularTriangleSampling.h>
#include <SPlisHSPlasH/Utilities/SceneLoader.h>
#include <SPlisHSPlasH/Utilities/SDFFunctions.h>
#include <SPlisHSPlasH/Utilities/SimpleQuadrature.h>
#include <SPlisHSPlasH/Utilities/SurfaceSampling.h>
#include <SPlisHSPlasH/Utilities/VolumeSampling.h>
#include <SPlisHSPlasH/Utilities/WindingNumbers.h>

#include "bind_pointer_vector.h"


template<typename... Args>
using overload_cast_ = pybind11::detail::overload_cast_impl<Args...>;


namespace py = pybind11;

using namespace pybind11::literals;

void UtilitiesModule(py::module m) {
    // Utilities submodule
    auto m_sub = m.def_submodule("Utilities");

    // ---------------------------------------
    // Binary File reader and writer
    // ---------------------------------------
    py::class_<SPH::BinaryFileWriter>(m_sub, "BinaryFileWriter")
            .def(py::init<>())
            .def("openFile", &SPH::BinaryFileWriter::openFile)
            .def("closeFile", &SPH::BinaryFileWriter::closeFile);

    py::class_<SPH::BinaryFileReader>(m_sub, "BinaryFileReader")
            .def(py::init<>())
            .def("openFile", &SPH::BinaryFileReader::openFile)
            .def("closeFile", &SPH::BinaryFileReader::closeFile);

    // ---------------------------------------
    // Counting class
    // ---------------------------------------
    py::class_<Utilities::AverageCount>(m_sub, "AverageCount")
            .def(py::init<>())
            .def_readwrite("sum", &Utilities::AverageCount::sum)
            .def_readwrite("numberOfCalls", &Utilities::AverageCount::numberOfCalls);

    py::class_<Utilities::Counting>(m_sub, "Counting")
            .def(py::init<>())
            .def_readwrite_static("m_averageCounts", &Utilities::Counting::m_averageCounts)
            .def_static("reset", &Utilities::Counting::reset)
            .def_static("increaseCounter", &Utilities::Counting::increaseCounter)
            .def_static("printAverageCounts", &Utilities::Counting::printAverageCounts)
            .def_static("printCounterSums", &Utilities::Counting::printCounterSums);

    // TODO: check if init counting need to be implemented
    m_sub.def("INCREASE_COUNTER", &Utilities::Counting::increaseCounter);

    // ---------------------------------------
    // File System utilities
    // ---------------------------------------
    py::class_<Utilities::FileSystem>(m_sub, "FileSystem")
            .def(py::init<>())
            .def_static("getFilePath", Utilities::FileSystem::getFilePath)
            .def_static("getFileName", Utilities::FileSystem::getFileName)
            .def_static("getFileNameWithExt", Utilities::FileSystem::getFileNameWithExt)
            .def_static("getFileExt", Utilities::FileSystem::getFileExt)
            .def_static("isRelativePath", Utilities::FileSystem::isRelativePath)
            .def_static("makeDir", Utilities::FileSystem::makeDir)
            .def_static("makeDirs", Utilities::FileSystem::makeDirs)
            .def_static("normalizePath", Utilities::FileSystem::normalizePath)
            .def_static("fileExists", Utilities::FileSystem::fileExists)
            .def_static("getProgramPath", Utilities::FileSystem::getProgramPath)
            .def_static("copyFile", Utilities::FileSystem::copyFile)
            .def_static("isFile", Utilities::FileSystem::isFile)
            .def_static("isDirectory", Utilities::FileSystem::isDirectory)
            .def_static("getFilesInDirectory", Utilities::FileSystem::getFilesInDirectory)
            .def_static("getFileMD5", Utilities::FileSystem::getFileMD5)
            .def_static("writeMD5File", Utilities::FileSystem::writeMD5File)
            .def_static("checkMD5", Utilities::FileSystem::checkMD5);

    // ---------------------------------------
    // Logger
    // ---------------------------------------
    py::enum_<Utilities::LogLevel>(m_sub, "LogLevel")
            .value("DEBUG", Utilities::LogLevel::DEBUG)
            .value("INFO", Utilities::LogLevel::INFO)
            .value("WARN", Utilities::LogLevel::WARN)
            .value("ERR", Utilities::LogLevel::ERR);

    py::class_<Utilities::ConsoleSink>(m_sub, "ConsoleSink")
            .def(py::init<>([](const Utilities::LogLevel minLevel) {
                return Utilities::ConsoleSink(minLevel);
            }))
            .def("write", &Utilities::ConsoleSink::write);

    // TODO: check if it is okay to use shared pointer and implement the actual logger functions
    py::class_<Utilities::FileSink, std::shared_ptr<Utilities::FileSink>>(m_sub, "FileSink")
            .def(py::init<>([](const Utilities::LogLevel minLevel, const std::string &fileName) {
                return std::make_shared<Utilities::FileSink>(minLevel, fileName);
            }))
            .def("write", &Utilities::FileSink::write);

    // ---------------------------------------
    // Object loader necessary vector types
    // ---------------------------------------
    py::bind_vector<std::vector<std::array<float, 3>>>(m_sub, "VecVec3f");
    py::bind_vector<std::vector<std::array<float, 2>>>(m_sub, "VecVec2f");
    py::bind_vector<std::vector<Utilities::MeshFaceIndices>>(m_sub, "VecMeshFaceIndices");

    // Todo: Bind missing attributes
    py::class_<Utilities::MeshFaceIndices>(m_sub, "MeshFaceIndices")
            .def(py::init<>())
            .def("__repr__", [](const Utilities::MeshFaceIndices &m) {
                std::stringstream s;
                s << "posIndices\n" << m.posIndices[0] << " " << m.posIndices[1] << " " << m.posIndices[2] << "\n";
                s << "texIndices\n" << m.texIndices[0] << " " << m.texIndices[1] << " " << m.texIndices[2] << "\n";
                s << "normalIndices\n" << m.normalIndices[0] << " " << m.normalIndices[1] << " " << m.normalIndices[2]
                  << "\n";
                return s.str();
            });

    py::class_<Utilities::OBJLoader>(m_sub, "OBJLoader")
            .def(py::init<>())
            .def_static("loadObj", &Utilities::OBJLoader::loadObj);

    // ---------------------------------------
    // Partio reader and writer
    // ---------------------------------------
    py::bind_vector<std::vector<Vector3r>>(m_sub, "VecVector3r", "std::vector<Vector3r> not to be confused with"
                                                                 "VecVec3f which ist std::vector<std::array<float,3>>");

    py::class_<Utilities::PartioReaderWriter>(m_sub, "PartioReaderWriter")
            .def(py::init<>())
            .def_static("readParticle", overload_cast_<const std::string &, const Vector3r &, const Matrix3r &,
                    const Real, std::vector<Vector3r> &>()(&Utilities::PartioReaderWriter::readParticles))
            .def_static("readParticle", overload_cast_<const std::string &, const Vector3r &, const Matrix3r &,
                    const Real, std::vector<Vector3r> &, std::vector<Vector3r> &>()(
                    &Utilities::PartioReaderWriter::readParticles))
            .def_static("readParticle", overload_cast_<const std::string &, const Vector3r &, const Matrix3r &,
                    const Real, std::vector<Vector3r> &, std::vector<Vector3r> &, Real &>()(
                    &Utilities::PartioReaderWriter::readParticles))
            .def_static("writeParticle", &Utilities::PartioReaderWriter::writeParticles);

    // ---------------------------------------
    // String tools
    // ---------------------------------------
    // TODO: String tools are omitted, because python is basically one big string tool


    // ---------------------------------------
    // System Info
    // ---------------------------------------
    // TODO: System info is also omitted. Will add if explicitly required by other classes

    // ---------------------------------------
    // Timing
    // ---------------------------------------
    // TODO: Timing and find a way for everything to be actually printed
    py::class_<Utilities::TimingHelper>(m_sub, "TimingHelper")
            .def(py::init<>())
            .def_readwrite("start", &Utilities::TimingHelper::start)
            .def_readwrite("name", &Utilities::TimingHelper::name);

    py::class_<Utilities::AverageTime>(m_sub, "AverageTime")
            .def(py::init<>())
            .def_readwrite("totalTime", &Utilities::AverageTime::totalTime)
            .def_readwrite("counter", &Utilities::AverageTime::counter)
            .def_readwrite("name", &Utilities::AverageTime::name);

    py::class_<Utilities::IDFactory>(m_sub, "IDFactory")
            .def(py::init<>())
            .def_static("getId", &Utilities::IDFactory::getId);

    py::class_<Utilities::Timing>(m_sub, "Timing")
            .def(py::init<>())
            .def_readwrite_static("m_dontPrintTimes", &Utilities::Timing::m_dontPrintTimes)
            .def_readwrite_static("m_startCounter", &Utilities::Timing::m_startCounter)
            .def_readwrite_static("m_stopCounter", &Utilities::Timing::m_stopCounter)
            .def_readwrite_static("m_timingStack", &Utilities::Timing::m_timingStack)
            .def_readwrite_static("m_averageTimes", &Utilities::Timing::m_averageTimes)
            .def_static("reset", &Utilities::Timing::reset)
            .def_static("startTiming", &Utilities::Timing::startTiming)
            .def_static("stopTiming", overload_cast_<bool>()(&Utilities::Timing::stopTiming))
            .def_static("stopTiming", overload_cast_<bool, int &>()(&Utilities::Timing::stopTiming))
            .def_static("printAverageTimes", &Utilities::Timing::printAverageTimes)
            .def_static("printTimeSums", &Utilities::Timing::printTimeSums);

    // ---------------------------------------
    // Gauss Quadrature
    // ---------------------------------------
    py::class_<SPH::GaussQuadrature>(m_sub, "GaussQuadrature")
            .def_static("integrate", &SPH::GaussQuadrature::integrate)
            .def_static("exportSamples", &SPH::GaussQuadrature::exportSamples);

    // ---------------------------------------
    // Math Functions
    // ---------------------------------------
    py::class_<SPH::MathFunctions>(m_sub, "MathFunctions")
            .def_static("extractRotation", &SPH::MathFunctions::extractRotation)
            .def_static("pseudoInverse", &SPH::MathFunctions::pseudoInverse)
            .def_static("svdWithInversionHandling", &SPH::MathFunctions::svdWithInversionHandling)
            .def_static("eigenDecomposition", &SPH::MathFunctions::eigenDecomposition)
            .def_static("jacobiRotate", &SPH::MathFunctions::jacobiRotate)
            .def_static("getOrthogonalVectors", &SPH::MathFunctions::getOrthogonalVectors);

    // ---------------------------------------
    // Matrix Replacement TODO: Pretty sure the user doesnt need the matrix replacement solved in the python API
    // ---------------------------------------
    py::class_<SPH::MatrixReplacement>(m_sub, "MatrixReplacement");

    // ---------------------------------------
    // Poisson Disk Sampling
    // ---------------------------------------
    py::class_<SPH::PoissonDiskSampling>(m_sub, "PoissonDiskSampling")
            .def(py::init<>())
            .def_static("floor", &SPH::PoissonDiskSampling::floor)
            .def("sampleMesh", &SPH::PoissonDiskSampling::sampleMesh);

    using CellPos = Eigen::Matrix<int, 3, 1, Eigen::DontAlign>;
    py::class_<SPH::PoissonDiskSampling::InitialPointInfo>(m_sub, "InitialPointInfo")
            .def(py::init<>())
            .def(py::init<CellPos, Vector3r, unsigned int>())
            .def_readwrite("cP", &SPH::PoissonDiskSampling::InitialPointInfo::cP)
            .def_readwrite("pos", &SPH::PoissonDiskSampling::InitialPointInfo::pos)
            .def_readwrite("ID", &SPH::PoissonDiskSampling::InitialPointInfo::ID);

    py::class_<SPH::PoissonDiskSampling::HashEntry>(m_sub, "HashEntry")
            .def(py::init<>())
            .def_readwrite("samples", &SPH::PoissonDiskSampling::HashEntry::samples)
            .def_readwrite("startIndex", &SPH::PoissonDiskSampling::HashEntry::startIndex);

    // ---------------------------------------
    // Regular Sampling 2D
    // ---------------------------------------
    py::class_<SPH::RegularSampling2D>(m_sub, "RegularSampling2D")
            .def_static("sampleMesh", &SPH::RegularSampling2D::sampleMesh);

    // ---------------------------------------
    // Scene Loader
    // ---------------------------------------
    py::class_<Utilities::SceneLoader>(m_sub, "SceneLoader")
            .def(py::init<>())
            .def("readScene", &Utilities::SceneLoader::readScene);

    auto m_sub_sub = m_sub.def_submodule("SceneLoaderStructs");
    using SceneInfo = Utilities::SceneLoader;
    py::class_<SceneInfo::Box>(m_sub_sub, "Box")
            .def(py::init<Vector3r, Vector3r>(), "minX"_a=Vector3r::Zero(), "maxX"_a=Vector3r::Ones())
            .def_readwrite("m_minX", &SceneInfo::Box::m_minX)
            .def_readwrite("m_maxX", &SceneInfo::Box::m_maxX);

    py::class_<SceneInfo::BoundaryData>(m_sub_sub, "BoundaryData")
            // .def(py::init<>())
            .def(py::init<std::string, std::string, Vector3r, Matrix3r, Vector3r, Real, bool, bool,
                         Eigen::Matrix<float, 4, 1, Eigen::DontAlign>, void *, std::string, bool, Real,
                         Eigen::Matrix<unsigned int, 3, 1, Eigen::DontAlign>, unsigned int, bool>(),
                 "samplesFile"_a = "", "meshFile"_a = "", "translation"_a = Vector3r::Zero(),
                 "rotation"_a = Matrix3r::Identity(), "scale"_a = Vector3r::Ones(),
                 "density"_a = 1000., "isDynamic"_a = false, "isWall"_a = false,
                 "color"_a = Eigen::Vector4f(1.f, 0.f, 0.f, 0.f), "rigidBody"_a = nullptr,
                 "mapFile"_a = "", "mapInvert"_a = false, "mapThickness"_a = 0.0,
                 "mapResolution"_a = Eigen::Matrix<unsigned int, 3, 1>(20, 20, 20),
                 "samplingMode"_a = 0, "isAnimated"_a = false)
            .def_readwrite("samplesFile", &SceneInfo::BoundaryData::samplesFile)
            .def_readwrite("meshFile", &SceneInfo::BoundaryData::meshFile)
            .def_readwrite("translation", &SceneInfo::BoundaryData::translation)
            .def_readwrite("rotation", &SceneInfo::BoundaryData::rotation)
            .def_readwrite("scale", &SceneInfo::BoundaryData::scale)
            .def_readwrite("density", &SceneInfo::BoundaryData::density)
            .def_readwrite("dynamic", &SceneInfo::BoundaryData::dynamic)
            .def_readwrite("isWall", &SceneInfo::BoundaryData::isWall)
            .def_readwrite("color", &SceneInfo::BoundaryData::color)
            .def_readwrite("rigidBody",
                           &SceneInfo::BoundaryData::rigidBody) // TODO: find out if void pointer is problem
            .def_readwrite("mapFile", &SceneInfo::BoundaryData::mapFile)
            .def_readwrite("mapInvert", &SceneInfo::BoundaryData::mapInvert)
            .def_readwrite("mapThickness", &SceneInfo::BoundaryData::mapThickness)
            .def_readwrite("mapResolution", &SceneInfo::BoundaryData::mapResolution)
            .def_readwrite("samplingMode", &SceneInfo::BoundaryData::samplingMode)
            .def_readwrite("isAnimated", &SceneInfo::BoundaryData::isAnimated);

    py::class_<SceneInfo::FluidData>(m_sub_sub, "FluidData")
            .def(py::init<std::string, std::string, Vector3r, Matrix3r, Vector3r, Vector3r, Vector3r, unsigned char,
                    bool, std::array<unsigned int, 3>>(),
                    "id"_a="Fluid", "samplesFile"_a, "translation"_a=Vector3r::Zero(), // TODO: samples file here has no default because it needs to be provided
                    "rotation"_a=Matrix3r::Identity(), "scale"_a=Vector3r::Ones(),
                    "initialVelocity"_a=Vector3r::Zero(), "initialAngularVelocity"_a = Vector3r::Zero(), "mode"_a=0, "invert"_a=false,
                    "resolutionSDF"_a=std::array<unsigned int, 3>({20, 20, 20}))
            .def_readwrite("id", &SceneInfo::FluidData::id)
            .def_readwrite("samplesFile", &SceneInfo::FluidData::samplesFile)
            .def_readwrite("translation", &SceneInfo::FluidData::translation)
            .def_readwrite("rotation", &SceneInfo::FluidData::rotation)
            .def_readwrite("scale", &SceneInfo::FluidData::scale)
            .def_readwrite("initialVelocity", &SceneInfo::FluidData::initialVelocity)
            .def_readwrite("initialAngularVelocity", &SceneInfo::FluidData::initialAngularVelocity)
            .def_readwrite("mode", &SceneInfo::FluidData::mode)
            .def_readwrite("invert", &SceneInfo::FluidData::invert)
            .def_readwrite("resolutionSDF", &SceneInfo::FluidData::resolutionSDF);

    py::class_<SceneInfo::FluidBlock>(m_sub_sub, "FluidBlock")
            .def(py::init<std::string, SceneInfo::Box, unsigned char, Vector3r, Vector3r>(),
                    "id"_a="Fluid", "box"_a=SceneInfo::Box({Vector3r::Zero(), Vector3r::Ones()}),
                    "mode"_a=0, "initialVelocity"_a=Vector3r::Zero(), "initialVelocity"_a = Vector3r::Zero())
            .def_readwrite("id", &SceneInfo::FluidBlock::id)
            .def_readwrite("box", &SceneInfo::FluidBlock::box)
            .def_readwrite("mode", &SceneInfo::FluidBlock::mode)
            .def_readwrite("initialVelocity", &SceneInfo::FluidBlock::initialVelocity)
            .def_readwrite("initialAngularVelocity", &SceneInfo::FluidBlock::initialAngularVelocity);

    py::class_<SceneInfo::EmitterData>(m_sub_sub, "EmitterData")
            .def(py::init<std::string, unsigned int, unsigned int, Vector3r, Real, Matrix3r, Real, Real, unsigned int>(),
                    "id"_a="Fluid", "width"_a=5, "height"_a=5, "x"_a=Vector3r::Zero(),
                    "velocity"_a=1, "rotation"_a=Matrix3r::Identity(), "emitStartTime"_a=0,
                    "emitEndTime"_a=std::numeric_limits<Real>::max(), "type"_a=0)
            .def_readwrite("id", &SceneInfo::EmitterData::id)
            .def_readwrite("width", &SceneInfo::EmitterData::width)
            .def_readwrite("height", &SceneInfo::EmitterData::height)
            .def_readwrite("x", &SceneInfo::EmitterData::x)
            .def_readwrite("velocity", &SceneInfo::EmitterData::velocity)
            .def_readwrite("rotation", &SceneInfo::EmitterData::rotation)
            .def_readwrite("emitStartTime", &SceneInfo::EmitterData::emitStartTime)
            .def_readwrite("emitEndTime", &SceneInfo::EmitterData::emitEndTime)
            .def_readwrite("type", &SceneInfo::EmitterData::type);

    py::class_<SceneInfo::AnimationFieldData>(m_sub_sub, "AnimationFieldData")
            .def(py::init<std::string, std::string, std::string, std::string, unsigned int, Vector3r, Matrix3r, Vector3r, Real, Real>(),
                    "particleFieldName"_a="", "expressionX"_a="", "expressionY"_a="",
                    "expressionZ"_a="", "shapeType"_a=0, "x"_a=Vector3r::Zero(),
                    "rotation"_a=Matrix3r::Identity(), "scale"_a=Vector3r::Ones(), "startTime"_a=0,
                    "endTime"_a=std::numeric_limits<Real>::max())
            .def_readwrite("particleFieldName", &SceneInfo::AnimationFieldData::particleFieldName)
                    // .def_readwrite("expression", &SceneInfo::AnimationFieldData::expression) // TODO: bind this type manually
            .def_readwrite("shapeType", &SceneInfo::AnimationFieldData::shapeType)
            .def_readwrite("x", &SceneInfo::AnimationFieldData::x)
            .def_readwrite("rotation", &SceneInfo::AnimationFieldData::rotation)
            .def_readwrite("scale", &SceneInfo::AnimationFieldData::scale)
            .def_readwrite("startTime", &SceneInfo::AnimationFieldData::startTime)
            .def_readwrite("endTime", &SceneInfo::AnimationFieldData::endTime);

    py::class_<SceneInfo::MaterialData>(m_sub_sub, "MaterialData")
            .def(py::init<>())
            .def(py::init<std::string, std::string, unsigned int, Real, Real, unsigned int, bool, Vector3r, Vector3r>(),
                    "id"_a, "colorField"_a="velocity", "colorMapType"_a=1, "minVal"_a=0.0, "maxVal"_a=10.0, //TODO: an id has to be provided
                    "maxEmitterParticles"_a=10000, "emitterReuseParticles"_a=false, "emitterBoxMin"_a=Vector3r(-1.0, -1.0, -1.0),
                    "emitterBoxMax"_a=Vector3r(1.0, 1.0, 1.0))
            .def_readwrite("id", &SceneInfo::MaterialData::id)
            .def_readwrite("colorField", &SceneInfo::MaterialData::colorField)
            .def_readwrite("colorMapType", &SceneInfo::MaterialData::colorMapType)
            .def_readwrite("minVal", &SceneInfo::MaterialData::minVal)
            .def_readwrite("maxVal", &SceneInfo::MaterialData::maxVal)
            .def_readwrite("maxEmitterParticles", &SceneInfo::MaterialData::maxEmitterParticles)
            .def_readwrite("emitterReuseParticles", &SceneInfo::MaterialData::emitterReuseParticles)
            .def_readwrite("emitterBoxMin", &SceneInfo::MaterialData::emitterBoxMin)
            .def_readwrite("emitterBoxMax", &SceneInfo::MaterialData::emitterBoxMax);

    py::bind_pointer_vector<std::vector<Utilities::SceneLoader::BoundaryData *>>(m_sub, "BoundaryDataVector");
    py::bind_pointer_vector<std::vector<Utilities::SceneLoader::FluidData *>>(m_sub, "FluidDataVector");
    py::bind_pointer_vector<std::vector<Utilities::SceneLoader::FluidBlock *>>(m_sub, "FluidBlockVector");
    py::bind_pointer_vector<std::vector<Utilities::SceneLoader::EmitterData *>>(m_sub, "EmitterDataVector");
    py::bind_pointer_vector<std::vector<Utilities::SceneLoader::AnimationFieldData *>>(m_sub, "AnimationFieldDataVector");
    py::bind_pointer_vector<std::vector<Utilities::SceneLoader::MaterialData *>>(m_sub, "MaterialData");

    py::class_<SceneInfo::Scene>(m_sub_sub, "Scene")
            .def(py::init<>())
            .def_readwrite("boundaryModels", &SceneInfo::Scene::boundaryModels)
            .def_readwrite("fluidModels", &SceneInfo::Scene::fluidModels)
            .def_readwrite("fluidBlocks", &SceneInfo::Scene::fluidBlocks)
            .def_readwrite("emitters", &SceneInfo::Scene::emitters)
            .def_readwrite("animatedFields", &SceneInfo::Scene::animatedFields)
            .def_readwrite("materials", &SceneInfo::Scene::materials)
            .def_readwrite("particleRadius", &SceneInfo::Scene::particleRadius)
            .def_readwrite("sim2D", &SceneInfo::Scene::sim2D)
            .def_readwrite("timeStepSize", &SceneInfo::Scene::timeStepSize)
            .def_readwrite("camPosition", &SceneInfo::Scene::camPosition)
            .def_readwrite("camLookat", &SceneInfo::Scene::camLookat);

    // ---------------------------------------
    // SDF Functions TODO: implement discregrid
    // ---------------------------------------
    py::class_<Discregrid::CubicLagrangeDiscreteGrid>(m_sub, "DiscreteGrid");

    py::class_<Utilities::SDFFunctions>(m_sub, "SDFFunctions")
            .def_static("generateSDF", &Utilities::SDFFunctions::generateSDF)
            .def_static("computeBoundingBox", &Utilities::SDFFunctions::computeBoundingBox)
            .def_static("distance",
                        overload_cast_<Discregrid::CubicLagrangeDiscreteGrid *, const Vector3r &, const Real, Vector3r &, Vector3r &>()(
                                &Utilities::SDFFunctions::distance))
            .def_static("distance",
                        overload_cast_<Discregrid::CubicLagrangeDiscreteGrid *, const Vector3r &, const Real>()(
                                &Utilities::SDFFunctions::distance));

    // ---------------------------------------
    // Simple Quadrature
    // ---------------------------------------
    py::class_<SPH::SimpleQuadrature>(m_sub, "SimpleQuadrature")
            .def_readwrite_static("m_samplePoints", &SPH::SimpleQuadrature::m_samplePoints)
            .def_readwrite_static("m_volume", &SPH::SimpleQuadrature::m_volume)

            .def_static("determineSamplePointsInSphere", &SPH::SimpleQuadrature::determineSamplePointsInSphere)
            .def_static("determineSamplePointsInCircle", &SPH::SimpleQuadrature::determineSamplePointsInCircle)
            .def_static("integrate", &SPH::SimpleQuadrature::integrate);

    // ---------------------------------------
    // Surface Sampling Modes
    // ---------------------------------------
    py::enum_<SPH::SurfaceSamplingMode>(m_sub, "SurfaceSamplingMode")
            .value("PoissonDisk", SPH::SurfaceSamplingMode::PoissonDisk)
            .value("RegularTriangle", SPH::SurfaceSamplingMode::RegularTriangle)
            .value("Regular2D", SPH::SurfaceSamplingMode::Regular2D);

    // ---------------------------------------
    // Volume Sampling
    // ---------------------------------------
    py::class_<Utilities::VolumeSampling>(m_sub, "VolumeSampling")
            .def_static("sampleMesh", Utilities::VolumeSampling::sampleMesh);

    // ---------------------------------------
    // Winding Numbers
    // ---------------------------------------
    py::class_<Utilities::WindingNumbers>(m_sub, "WindingNumbers")
            .def_static("computeGeneralizedWindingNumber",
                        overload_cast_<const Vector3r &, const Vector3r &, const Vector3r &, const Vector3r &>()(
                                &Utilities::WindingNumbers::computeGeneralizedWindingNumber))
            .def_static("computeGeneralizedWindingNumber",
                        overload_cast_<const Vector3r &, const SPH::TriangleMesh &>()(
                                &Utilities::WindingNumbers::computeGeneralizedWindingNumber));
}

back to top

Software Heritage — Copyright (C) 2015–2025, The Software Heritage developers. License: GNU AGPLv3+.
The source code of Software Heritage itself is available on our development forge.
The source code files archived by Software Heritage are available under their own copyright and licenses.
Terms of use: Archive access, API— Content policy— Contact— JavaScript license information— Web API