A PIC/FLIP fluid simulation based on the methods found in Robert Bridson's "Fluid Simulation for Computer Graphics"

Overview

GridFluidSim3d

This program is an implementation of a PIC/FLIP liquid fluid simulation written in C++11 based on methods described in Robert Bridson's "Fluid Simulation for Computer Graphics" textbook. The fluid simulation program outputs the surface of the fluid as a sequence of triangle meshes stored in the Stanford .PLY file format which can then be imported into your renderer of choice.

Visit http://rlguy.com/gridfluidsim/ for more information about the program.

Gallery

The following screencaps are of animations that were simulated within the program and rendered using Blender. Animations created with the fluid simulation program can be viewed on YouTube.

alt tag

alt tag alt tag

alt tag alt tag

alt tag alt tag

alt tag alt tag

alt tag alt tag

Features

Below is a list of features implemented in the simulator.

  • Isotropic and anisotropic particle to mesh conversion
  • Spray, bubble, and foam particle simulation
  • 'LEGO' brick surface reconstruction
  • Save and load state of a simulation
  • GPU accelerated fourth-order Runge-Kutta integration using OpenCL
  • GPU accelerated velocity advection using OpenCL
  • Python bindings

Dependencies

There are three dependencies that are required to build this program:

  1. OpenCL headers (can be found at khronos.org)
  2. An OpenCL SDK specific to your GPU vender (AMD, NVIDIA, Intel, etc.)
  3. A compiler that supports C++11

Installation

This program uses the CMake utility to generate the appropriate solution, project, or Makefiles for your system. The following commands can be executed in the root directory of the project to generate a build system for your machine:

mkdir build && cd build
cmake ..

The first line creates a new directory named build and changes the working directory to the newly created build directory. The second line runs the CMake utility and passes it the parent directory which contains the CMakeLists.txt file.

The type of build system generated by CMake can be specified with the -G [generator] parameter. For example:

cmake .. -G "MinGW Makefiles"

will generate Makefiles for the MinGW compiler which can then be built using the GNU Make utility with the command make. A list of CMake generators can be found here.

Once successfully built, the program will be located in the build/fluidsim/ directory with the following directory structure:

fluidsim
│   fluidsim.a      - Runs program configured in main.cpp     
│
└───output          - Stores data output by the simulation program
│   └───bakefiles       - meshes
│   └───logs            - logfiles
│   └───savestates      - simulation save states
│   └───temp            - temporary files created by the simulation program
│    
└───pyfluid         - The pyfluid Python package
    └───examples        - pyfluid example usage
    └───lib             - C++ library files

Configuring the Fluid Simulator

The fluid simulator can be configured by manipulating a FluidSimulation object in the function main() located in the file src/main.cpp. After building the project, the fluid simulation exectuable will be located in the fluidsim/ directory. Example configurations are located in the src/examples/cpp/ directory. Some documentation on the public methods for the FluidSimulation class is provided in the fluidsimulation.h header.

A fluid simulation can also be configured and run within a Python script by importing the pyfluid package, which will be located in the fluidsim/ directory after building the project. Example scripts are located in the src/examples/python/ directory.

The following two sections will demonstrate how to program a simple "Hello World" simulation using either C++ or Python.

Hello World (C++)

This is a very basic example of how to use the FluidSimulation class to run a simulation. The simulation in this example will drop a ball of fluid in the center of a cube shaped fluid domain. This example is relatively quick to compute and can be used to test if the simulation program is running correctly.

The fluid simulator performs its computations on a 3D grid, and because of this the simulation domain is shaped like a rectangular prism. The FluidSimulation class can be initialized with four parameters: the number of grid cells in each direction x, y, and z, and the width of a grid cell.

int xsize = 32;
int ysize = 32;
int zsize = 32;
double cellsize = 0.25;
FluidSimulation fluidsim(xsize, ysize, zsize, cellsize);

We want to add a ball of fluid to the center of the fluid domain, so we will need to get the dimensions of the domain by calling getSimulationDimensions and passing it pointers to store the width, height, and depth values. Alternatively, the dimensions can be calculated by multiplying the cell width by the corresponding number of cells in a direction (e.g. width = dx*isize).

double width, height, depth;
fluidsim.getSimulationDimensions(&width, &height, &depth);

Now that we have the dimensions of the simulation domain, we can calculate the center, and add a ball of fluid by calling addImplicitFluidPoint which takes the x, y, and z position and radius as parameters.

double centerx = width / 2;
double centery = height / 2;
double centerz = depth / 2;
double radius = 6.0;
fluidsim.addImplicitFluidPoint(centerx, centery, centerz, radius);

An important note to make about addImplicitFluidPoint is that it will not add a sphere with the specified radius, it will add a sphere with half of the specified radius. An implicit fluid point is represented as a field of values on the simulation grid. The strength of the field values are 1 at the point center and falls off towards 0 as distance from the point increases. When the simulation is initialized, fluid particles will be created in regions where the field values are greater than 0.5. This means that if you add a fluid point with a radius of 6.0, the ball of fluid in the simulation will actually be of radius 3.0 since field values will be less than 0.5 at a distance greater than half of the specified radius.

The FluidSimulation object now has a domain containing some fluid, but the current simulation will not be very interesting as there are no forces acting upon the fluid. We can add the force of gravity by making a call to addBodyForce which takes three values representing a force vector as parameters. We will set the force of gravity to point downwards with a value of 25.0.

double gx = 0.0;
double gy = -25.0;
double gz = 0.0;
fluidsim.addBodyForce(gx, gy, gz);

Now we have a simulation domain with some fluid, and a force acting on the fluid. Before we run the simulation, a call to initialize must be made. Note that any calls to addImplicitFluidPoint must be made before initialize is called.

fluidsim.initialize();

We will now run the simulation for a total of 30 animation frames at a rate of 30 frames per second by repeatedly making calls to the update function. The update function advances the state of the simulation by a specified period of time. To update the simulation at a rate of 30 frames per second, each call to update will need to be supplied with a time value of 1.0/30.0. Each call to update will generate a triangle mesh that represents the fluid surface. The mesh files will be saved in the output/bakefiles/ directory as a numbered sequence of files stored in the Stanford .PLY file format.

double timestep = 1.0 / 30.0;
int numframes = 30;
for (int i = 0; i < numframes; i++) {
    fluidsim.update(timestep);
}

As this loop runs, the program should output simulation stats and timing metrics to the terminal. After the loop completes, the output/bakefiles/ directory should contain 30 .PLY triangle meshes numbered in sequence from 0 to 29: 000000.ply, 000001.ply, 000002.ply, ..., 000028.ply, 000029.ply.

If you open the 000029.ply mesh file in a 3D modelling package such as Blender, the mesh should look similar to this image.

The fluid simulation in this example is quick to compute, but of low quality due to the low resolution of the simulation grid. The quality of this simulation can be improved by increasing the simulation dimensions while decreasing the cell size. For example, try simulating on a grid of resolution 64 x 64 x 64 with a cell size of 0.125, or even better, on a grid of resolution 128 x 128 x 128 with a cell size of 0.0625.

Hello World (Python)

The following Python script will run the equivalent simulation described in the previous section.

from pyfluid import FluidSimulation

fluidsim = FluidSimulation(32, 32, 32, 0.25)

width, height, depth = fluidsim.get_simulation_dimensions()
fluidsim.add_implicit_fluid_point(width / 2, height / 2, depth / 2, 6.0)
fluidsim.add_body_force(0.0, -25.0, 0.0)
fluidsim.initialize();

for i in range(30):
    fluidsim.update(1.0 / 30)
Comments
  • Building on OSX

    Building on OSX

    Sorry, total noob here. I'm really exited to use the program (I use blender a lot and the ancient lattice-Boltzmann fluid simulator built in leaves much to be desired). Can you please help me build and run this on OS X? I hope you can turn this into a blender plugin in the future. The results look really great. Does it use open VDB?

    opened by rtolps 28
  • OpenCL error -37 (CL_INVALID_HOST_PTR)

    OpenCL error -37 (CL_INVALID_HOST_PTR)

    Hello Ryan,

    I compiled successfully, but when I run I get the following error:

    Frame: 0 StepTime: 0.0333

    Update Fluid Cells: 0 Num Fluid Cells: 95767 Num Marker Particles: 735903 Reconstruct Fluid Surface: 0 Update Level set: 0 Reconstruct Output Surface: 0 ERROR: Creating position data buffer (-37) fluidsim: src/clscalarfield.cpp:423: void CLScalarField::_checkError(cl_int, const char*): Assertion `err == 0' failed. Aborted (core dumped)

    I compiled on Ubuntu 15.10 with nvidia opencl 352

    Unfortunately that is all the info I can give.

    opened by GottfriedHofmann 7
  • unable to load library

    unable to load library

    Can anyone give me some insight, why I receive the 'unable to load library" error ? I followed the instructions for installing fluidsim. However, I'm missing the "lib" directory under "pyfluid". Might this be the reason, and if so, how come the "lib" directory isn't there although the build was successful ?

    Many thanks in advance !

    h:\python27\python example_hello_world.py ../../../../build2/fluidsim/ Traceback (most recent call last): File "example_hello_world.py", line 30, in import pyfluid File "H:\GridFluidSim3D-master\build2\fluidsim\pyfluid_init_.py", line 1, in from .aabb import AABB, AABB_t File "H:\GridFluidSim3D-master\build2\fluidsim\pyfluid\aabb.py", line 3, in from . import method_decorators as decorators File "H:\GridFluidSim3D-master\build2\fluidsim\pyfluid\method_decorators.py", line 3, in from .fluidsimulationsavestate import FluidSimulationSaveState File "H:\GridFluidSim3D-master\build2\fluidsim\pyfluid\fluidsimulationsavestate.py", line 4, in from .pyfluid import pyfluid as lib File "H:\GridFluidSim3D-master\build2\fluidsim\pyfluid\pyfluid.py", line 45, in pyfluid = __load_library("pyfluid") File "H:\GridFluidSim3D-master\build2\fluidsim\pyfluid\pyfluid.py", line 26, in __load_library raise LibraryLoadError("Unable to load library: " + name) pyfluid.pyfluid.LibraryLoadError: 'Unable to load library: pyfluid'

    opened by KimMura 6
  • Is it possible to generate particle map instead of meshes?

    Is it possible to generate particle map instead of meshes?

    I have been working on Lego particle maps and am wondering if this could output that instead of a mesh. That is, my meshes are already created and I position them based on particle maps. The particle maps just have an xyz coordinate for each particle. I don't know if this makes sense but this simulator should already have that data internally, so it's just a matter of saving that instead of the 3d mesh data.

    opened by magnusviri 6
  • Addition of a build system generator

    Addition of a build system generator

    opened by elfring 3
  • How can i define a scene?

    How can i define a scene?

    Hello! Sorry if this is inapropriate place to ask i've built your code with mingw64 on windows7 Application starts fine, and it's baking .ply files in bake folder, but what is it baking? How can i create my own scene and bake it?

    opened by vitos1k 3
  • issues with compilation

    issues with compilation

    hey when trying to make i get this Documents/GridFluidSim3D/build master ✗ 850d ◒ ▶ make Scanning dependencies of target objects [ 2%] Building CXX object CMakeFiles/objects.dir/src/aabb.cpp.o [ 4%] Building CXX object CMakeFiles/objects.dir/src/anisotropicparticlemesher.cpp.o [ 6%] Building CXX object CMakeFiles/objects.dir/src/c_bindings/cbindings.cpp.o [ 9%] Building CXX object CMakeFiles/objects.dir/src/c_bindings/config_c.cpp.o [ 11%] Building CXX object CMakeFiles/objects.dir/src/c_bindings/cuboidfluidsource_c.cpp.o [ 13%] Building CXX object CMakeFiles/objects.dir/src/c_bindings/fluidsimulation_c.cpp.o In file included from /home/jacos/Documents/GridFluidSim3D/src/c_bindings/../clscalarfield.h:37, from /home/jacos/Documents/GridFluidSim3D/src/c_bindings/../fluidsimulation.h:32, from /home/jacos/Documents/GridFluidSim3D/src/c_bindings/fluidsimulation_c.cpp:1: /opt/cuda/include/CL/cl.hpp:5085:28: warning: ignoring attributes on template argument ‘cl_int’ {aka ‘int’} [-Wignored-attributes] 5085 | VECTOR_CLASS<cl_int>* binaryStatus = NULL, | ^ In file included from /home/jacos/Documents/GridFluidSim3D/src/c_bindings/../clscalarfield.h:56, from /home/jacos/Documents/GridFluidSim3D/src/c_bindings/../fluidsimulation.h:32, from /home/jacos/Documents/GridFluidSim3D/src/c_bindings/fluidsimulation_c.cpp:1: /home/jacos/Documents/GridFluidSim3D/src/c_bindings/../arrayview3d.h: In member function ‘void ArrayView3d<T>::getViewAsArray3d(Array3d<T>&)’: /home/jacos/Documents/GridFluidSim3D/src/c_bindings/../arrayview3d.h:192:16: error: return-statement with a value, in function returning ‘void’ [-fpermissive] 192 | return view; | ^~~~ make[2]: *** [CMakeFiles/objects.dir/build.make:128: CMakeFiles/objects.dir/src/c_bindings/fluidsimulation_c.cpp.o] Error 1 make[1]: *** [CMakeFiles/Makefile2:107: CMakeFiles/objects.dir/all] Error 2 make: *** [Makefile:84: all] Error 2

    opened by cyrstem 2
  • The drop ball excample works not good

    The drop ball excample works not good

    Hi, I followed the "Hello World" excample about drop a ball of fluid in the center of the fluid simulation domain, however the 29.ply model is not same as the given one. image (the model generated by my excample ) image (the model in the readme example) image (the code in my test)

    opened by mingweiLIU 2
  • Vector subscript out of range when running the basic example

    Vector subscript out of range when running the basic example

    I built the project with VS2015 x64, when running the basic example (image1) it crashed, error shows that the vector subscript out of range. I watched the stack it shows that the error is acurred by the function of what I showed in image2 and seems it caused by the variable buffer.pointDataH[0] since the size of the pointDataH is 0. I don't know how to fix it, could you help me? image image1 code of basic example code image image2 error loaction

    opened by mingweiLIU 2
  • Python mode?

    Python mode?

    I tried to run this simulation, but I have no knowledge of C and compiling. I tried copy paste the pyfluid folder into Blender and load it inside Blender, but it gives me error.

    How to actually run this sims?

    opened by enzyme69 2
  • cannot import name FluidSimulation

    cannot import name FluidSimulation

    build worked fine, so not sure if I am missing something? image

    In the mean time I can try to use C++, but I'm not too sure how to compile that. What I attempted:

    g++ example_hello_world.h -o hello-world
    

    which gave errors.

    Edit nvm, figured out how to use main.cpp :)

    opened by thejmazz 2
  • Building for windows!

    Building for windows!

    Hello there! I'm trying to create a similar project to yours and am trying to test out your project for inspiration!

    I am having trouble building for windows. The program itself builds but the bakefiles of the frames only contain the headers, not the actual mesh information. Is this anything you've run into? Is the latest push to github working properly? Thank you for any insights, would love to try and recreate your effect for use in Blender! :)

    Looking at the code and doing some printouts shows that the meshes have 0 vertices in them, implying something has gone awry. Testing using NVIDIA graphics card (GeForce RTX 2080 SUPER) and CUDA toolkit for openCL library and header.

    Gorgeous work! Hopefully creating an issue here doesn't bug you too much.

    Here is a printout when trying to run the lego dambreak:


    26-Mar-2021 11h33m37s

    Initializing Simulation Grids: Grid Dimensions: 128 x 128 x 128 Cell Size: 0.0625 Constructing MACVelocityField: 0.125 Constructing FluidMaterialGrid: 0.031 Constructing LevelSet: 0.0629 26-Mar-2021 11h33m37s disableIsotropicSurfaceReconstruction 26-Mar-2021 11h33m37s enableBrickOutput: 0.1875 0.225 0.1875 26-Mar-2021 11h33m37s addImplicitFluidPoint: 4 4 4 5 26-Mar-2021 11h33m37s addFluidCuboid: 0 0 0 8 1 8 26-Mar-2021 11h33m37s addBodyForce: 0 -25 0 26-Mar-2021 11h33m37s initialize

    Initializing Simulation: Initializing Solid Cells: 0 Initializing Fluid Material: 1.5629 Initializing OpenCL Objects: 1.359


    OpenCL ParticleAdvector Device Info: CL_DEVICE_NAME: Intel(R) UHD Graphics 630 CL_DEVICE_VENDOR: Intel(R) Corporation CL_DEVICE_VERSION: OpenCL 2.1 NEO CL_DRIVER_VERSION: 27.20.100.8681 CL_DEVICE_OPENCL_C_VERSION: OpenCL C 2.0 CL_DEVICE_TYPE: GPU CL_DEVICE_MAX_CLOCK_FREQUENCY: 1200MHz CL_DEVICE_GLOBAL_MEM_SIZE: 1717985280 CL_DEVICE_LOCAL_MEM_SIZE: 65536 CL_DEVICE_MAX_MEM_ALLOC_SIZE: 858992640 CL_DEVICE_MAX_WORK_GROUP_SIZE: 256 CL_DEVICE_MAX_WORK_ITEM_SIZES: 256 x 256 x 256

    OpenCL ParticleAdvector Kernel Info: CL_KERNEL_FUNCTION_NAME: tricubic_interpolate_kernel CL_KERNEL_ATTRIBUTES: CL_KERNEL_NUM_ARGS: 3611970751797657605 CL_KERNEL_WORK_GROUP_SIZE: 256 CL_KERNEL_LOCAL_MEM_SIZE: 0 CL_KERNEL_PRIVATE_MEM_SIZE: 0 CL_KERNEL_PREFERRED_WORK_GROUP_SIZE_MULTIPLE: 8


    OpenCL CLScalarField Device Info: CL_DEVICE_NAME: Intel(R) UHD Graphics 630 CL_DEVICE_VENDOR: Intel(R) Corporation CL_DEVICE_VERSION: OpenCL 2.1 NEO CL_DRIVER_VERSION: 27.20.100.8681 CL_DEVICE_OPENCL_C_VERSION: OpenCL C 2.0 CL_DEVICE_TYPE: GPU CL_DEVICE_MAX_CLOCK_FREQUENCY: 1200MHz CL_DEVICE_GLOBAL_MEM_SIZE: 1717985280 CL_DEVICE_LOCAL_MEM_SIZE: 65536 CL_DEVICE_MAX_MEM_ALLOC_SIZE: 858992640 CL_DEVICE_MAX_WORK_GROUP_SIZE: 256 CL_DEVICE_MAX_WORK_ITEM_SIZES: 256 x 256 x 256

    OpenCL CLScalarField Kernel Info: CL_KERNEL_FUNCTION_NAME: compute_scalar_field_points CL_KERNEL_ATTRIBUTES: CL_KERNEL_NUM_ARGS: 3611970751797657608 CL_KERNEL_WORK_GROUP_SIZE: 256 CL_KERNEL_LOCAL_MEM_SIZE: 0 CL_KERNEL_PRIVATE_MEM_SIZE: 0 CL_KERNEL_PREFERRED_WORK_GROUP_SIZE_MULTIPLE: 32

    CL_KERNEL_FUNCTION_NAME: compute_scalar_field_point_values CL_KERNEL_ATTRIBUTES: CL_KERNEL_NUM_ARGS: 3611970751797657608 CL_KERNEL_WORK_GROUP_SIZE: 256 CL_KERNEL_LOCAL_MEM_SIZE: 0 CL_KERNEL_PRIVATE_MEM_SIZE: 0 CL_KERNEL_PREFERRED_WORK_GROUP_SIZE_MULTIPLE: 32

    CL_KERNEL_FUNCTION_NAME: compute_scalar_weight_field_point_values CL_KERNEL_ATTRIBUTES: CL_KERNEL_NUM_ARGS: 3611970751797657608 CL_KERNEL_WORK_GROUP_SIZE: 256 CL_KERNEL_LOCAL_MEM_SIZE: 0 CL_KERNEL_PRIVATE_MEM_SIZE: 0 CL_KERNEL_PREFERRED_WORK_GROUP_SIZE_MULTIPLE: 32

    opened by alvinhager 2
Owner
Ryan Guy
Developer of the FLIP Fluids addon for Blender
Ryan Guy
The FLIP Fluids addon is a tool that helps you set up, run, and render high quality liquid fluid effects all within Blender, the free and open source 3D creation suite.

FLIP Fluids The FLIP Fluids addon is a tool that helps you set up, run, and render liquid simulation effects. Our custom built fluid engine is based a

Ryan Guy 1.4k Dec 22, 2022
Offline fluid simulation solver adopted from https://github.com/doyubkim/fluid-engine-dev.

FluidEngine This is a fluid simulation engine for computer graphics applications. I adopt it from Doyub Kim's fluid-engine-dev. It's built on C++11 an

YangWC 55 Oct 26, 2022
PIC lsass dumper using cloned handles

HandleKatz This tool was implemented as part of our Brucon2021 conference talk and demonstrates the usage of cloned handles to Lsass in order to creat

CODE WHITE GmbH 485 Dec 28, 2022
Design and firmware for a stepper motor retrofit to the often-failed AC synchronous flip clock motors

StepperFlipClock Design and firmware for a stepper motor retrofit to the often-failed AC synchronous flip clock motors. Flip clocks, perhaps most icon

Dan Ellis 3 Oct 13, 2022
A wireless control for an RGB LED based on emotions found in discord messages.

Sample project (See the README.md file in the upper level 'examples' directory for more information about examples.) This is the simplest buildable ex

Fernando Mendoza 2 Dec 1, 2021
fluid simulation

二维流体模拟demo 编译 g++ -O2 -fopenmp -o test test.cpp SPH结果 线程测试 测试平台Windows Intel(R)core(TM)[email protected] 物理线程6 逻辑线程12 加速比分析 加速比维持在6左右,在线程达到6(物理线程数量

null 1 Oct 22, 2021
Fluid simulation engine for computer graphics applications

Fluid Engine Dev - Jet Jet framework is a fluid simulation engine SDK for computer graphics applications that was created by Doyub Kim as part of the

Doyub Kim 1.5k Dec 31, 2022
Stuff I've made/found for reversing/modding/extracting NieR:Replicant v1.224...

NieR:Replicant ver.1.22474487139 Tools Archive (.arc) Files Hex Signature: 28 B5 2F FD Can contain one or multiple compressed files. Files are compres

Woeful_Wolf 8 Jul 30, 2022
I Found these Xenomai 3 exercises I completed and wrote up for a project a few years ago

I Found these Xenomai 3 exercises I completed and wrote up for a project a few years ago. Decided to put it up onto git in case anyone else finds this useful

null 3 Apr 24, 2022
Vulkan and other GPU API bugs I found.

GPU-my-list-of-bugs what is it - list of bugs I found writing shaders, mostly shader bugs. Maybe this is my code bug or/and shader bugs, but this code

Danil 14 Dec 26, 2022
swhid is an OCaml library to work with persistent identifiers found in Software Heritage, also known as swhid

swhid_compute swhid_compute is an OCaml library to work with persistent identifiers found in Software Heritage, also known as swhid. This library only

OCamlPro 2 Jun 21, 2022
(R) Efficient methods and operators for the sparse matrix classes in 'Matrix' (esp. CSR format or "RsparseMatrix")

MatrixExtra MatrixExtra is an R package which extends the sparse matrix and sparse vector types in the Matrix package, particularly the CSR or Rsparse

null 15 Aug 29, 2022
A C++17 library of computationally efficient methods for calculating sample statistics

Vectorized statistics using SIMD primitives Introduction is a C++17 library of computationally efficient methods for calculating sample statistics (me

HEAL 12 Nov 20, 2022
Mobile platform for analysis of localization methods using the Intel RealSense T265 sensor

OptiBot Mobile platform for analysis of localization methods using the Intel RealSense T265 sensor About | Content | Implementation | License | Author

Kamil Goś 2 Feb 17, 2022
Fast and Light-weight path smoothing methods for vehicles

path_smoother About Fast and Light-weight path smoothing methods for vehicles Denpendencies This project has been tested on Ubuntu 18.04. sudo apt-get

MingwangZhao 4 Dec 1, 2021
OptimLib: a lightweight C++ library of numerical optimization methods for nonlinear functions

OptimLib OptimLib is a lightweight C++ library of numerical optimization methods for nonlinear functions. Features: A C++11 library of local and globa

Keith O'Hara 618 Dec 27, 2022
A gazebo actor plugin that utilizes the map of the environment and graph search methods to generate random actor trajectories that don't pass through walls, furniture, etc.

Gazebo-Map-Actor-Plugin A gazebo actor plugin that utilizes the map of the environment and graph search methods to generate random actor trajectories

Yasin Sonmez 11 Dec 23, 2022
Injection - Windows process injection methods

Windows Process Injection Here are some popular methods used for process injection on the windows operating system. Conhost ExtraBytes PROPagate Servi

null 1.4k Dec 28, 2022
std::tuple like methods for user defined types without any macro or boilerplate code

Boost.PFR This is a C++14 library for very basic reflection that gives you access to structure elements by index and provides other std::tuple like me

Boost.org 1.1k Dec 23, 2022