Skip to content

Commit c78e738

Browse files
committed
- added rigid body export
- added VTK file export (enables the data import in ParaView) - added file dialog for Windows - added a Python plugin for Maya to model scenes in Maya and export them to SPlisHSPlasH - added animation fields to animate particles in an area using a math script - improved fluid emitters - added option to simulate without GUI
1 parent 2cb56ef commit c78e738

106 files changed

Lines changed: 7166 additions & 911 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

CMakeLists.txt

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,12 +30,14 @@ if (WIN32)
3030
extern/zlib
3131
extern/partio
3232
extern/MD5
33+
extern/tinyexpr
3334
SPlisHSPlasH Utilities)
3435
else()
3536
subdirs(
3637
extern/zlib
3738
extern/partio
3839
extern/md5
40+
extern/tinyexpr
3941
SPlisHSPlasH Utilities)
4042
endif()
4143

@@ -56,7 +58,7 @@ ExternalProject_Add(
5658
Ext_PBD
5759
PREFIX "${CMAKE_SOURCE_DIR}/extern/PositionBasedDynamics"
5860
GIT_REPOSITORY https://github.com/InteractiveComputerGraphics/PositionBasedDynamics.git
59-
GIT_TAG "2abd7737de08915a780c546216bb9d5fbaadf3bd"
61+
GIT_TAG "1adf52eb23cdd73c7d9db725d09256fc8ed7f395"
6062
INSTALL_DIR ${ExternalInstallDir}/PositionBasedDynamics
6163
CMAKE_ARGS -DCMAKE_BUILD_TYPE=${EXT_CMAKE_BUILD_TYPE} -DCMAKE_INSTALL_PREFIX:PATH=${ExternalInstallDir}/PositionBasedDynamics -DPBD_NO_DEMOS:BOOL=1 -DPBD_EXTERNALINSTALLDIR:PATH=${ExternalInstallDir} -DUSE_DOUBLE_PRECISION:BOOL=${USE_DOUBLE_PRECISION}
6264
)
@@ -70,3 +72,13 @@ ExternalProject_Add(
7072
INSTALL_DIR ${ExternalInstallDir}/GenericParameters
7173
CMAKE_ARGS -DCMAKE_BUILD_TYPE=${EXT_CMAKE_BUILD_TYPE} -DCMAKE_INSTALL_PREFIX:PATH=${ExternalInstallDir}/GenericParameters -DGENERICPARAMETERS_NO_TESTS:BOOL=1
7274
)
75+
76+
## Discregrid
77+
ExternalProject_Add(
78+
Ext_Discregrid
79+
PREFIX "${CMAKE_SOURCE_DIR}/extern/Discregrid"
80+
GIT_REPOSITORY https://github.com/InteractiveComputerGraphics/Discregrid.git
81+
GIT_TAG "c0fb5aeac4c8a83e9f37c720315f13a834409b81"
82+
INSTALL_DIR ${ExternalInstallDir}/Discregrid
83+
CMAKE_ARGS -DCMAKE_BUILD_TYPE:STRING=${EXT_CMAKE_BUILD_TYPE} -DCMAKE_INSTALL_PREFIX:PATH=${ExternalInstallDir}/Discregrid -DBUILD_CMD_EXECUTABLE:BOOL=0 -DEIGEN3_INCLUDE_DIR:PATH=${EIGEN3_INCLUDE_DIR}
84+
)

Changelog.txt

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,11 @@
1+
2.4.0
2+
- added rigid body export
3+
- added VTK file export (enables the data import in ParaView)
4+
- added file dialog for Windows
5+
- added a Python plugin for Maya to model scenes in Maya and export them to SPlisHSPlasH
6+
- added animation fields to animate particles in an area using a math script
7+
- improved fluid emitters
8+
- added option to simulate without GUI
19
- added GPU neighborhood search (cuNSearch) which can be selected in CMake
210

311
2.3.0

Doxyfile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ PROJECT_NAME = SPlisHSPlasH
3838
# could be handy for archiving the generated documentation or if some version
3939
# control system is used.
4040

41-
PROJECT_NUMBER = 2.0.0
41+
PROJECT_NUMBER = 2.4.0
4242

4343
# Using the PROJECT_BRIEF tag one can provide an optional one line description
4444
# for a project that appears at the top of each page and should give viewer a

README.md

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33

44
SPlisHSPlasH is an open-source library for the physically-based simulation of fluids. The simulation in this library is based on the Smoothed Particle Hydrodynamics (SPH) method which is a popular meshless Lagrangian approach to simulate complex fluid effects. The SPH formalism allows an efficient computation of a certain quantity of a fluid particle by considering only a finite set of neighboring particles. One of the most important research topics in the field of SPH methods is the simulation of incompressible fluids. SPlisHSPlasH implements current state-of-the-art pressure solvers (WCSPH, PCISPH, PBF, IISPH, DFSPH, PF) to simulate incompressibility. Moreover, the library provides different methods to simulate viscosity, surface tension and vorticity.
55

6-
The library uses the following external libraries: [Eigen](http://eigen.tuxfamily.org/), [json](https://github.com/nlohmann/json/), [partio](https://github.com/wdas/partio/), [zlib](https://github.com/madler/zlib), [cxxopts](https://github.com/jarro2783/cxxopts), [glew](http://glew.sourceforge.net/) and [AntTweakBar](http://anttweakbar.sourceforge.net/) (only for the demos). All external dependencies are included.
6+
The library uses the following external libraries: [Eigen](http://eigen.tuxfamily.org/), [json](https://github.com/nlohmann/json/), [partio](https://github.com/wdas/partio/), [zlib](https://github.com/madler/zlib), [cxxopts](https://github.com/jarro2783/cxxopts), [tinyexpr](https://github.com/codeplea/tinyexpr), [noc](https://github.com/guillaumechereau/noc), [glew](http://glew.sourceforge.net/) and [AntTweakBar](http://anttweakbar.sourceforge.net/) (only for the demos). All external dependencies are included.
77

88
Furthermore we use our own libraries:
99
- [PositionBasedDynamics](https://github.com/InteractiveComputerGraphics/PositionBasedDynamics/) to simulate dynamic rigid bodies
@@ -48,10 +48,14 @@ SPlisHSPlasH implements:
4848
* rigid-fluid coupling with static and dynamic bodies
4949
* two-way coupling with deformable solids
5050
* fluid emitters
51+
* scripted animation fields
5152
* a json-based scene file importer
5253
* automatic surface sampling
5354
* a tool for volume sampling of closed geometries
5455
* partio file export of all particle data
56+
* VTK file export of all particle data (enables the data import in ParaView)
57+
* rigid body export
58+
* a Maya plugin to model and generate scene files
5559

5660
## Pressure Solvers
5761

SPlisHSPlasH/AnimationField.cpp

Lines changed: 135 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,135 @@
1+
#include "AnimationField.h"
2+
#include "SPHKernels.h"
3+
#include <iostream>
4+
#include "TimeManager.h"
5+
#include "TimeStep.h"
6+
#include "FluidModel.h"
7+
#include "Simulation.h"
8+
#include "extern/tinyexpr/tinyexpr.h"
9+
#include "Utilities/Logger.h"
10+
11+
using namespace SPH;
12+
13+
AnimationField::AnimationField(
14+
const std::string &particleFieldName,
15+
const Vector3r &pos, const Matrix3r & rotation, const Vector3r &scale,
16+
const std::string expression[3], const unsigned int type)
17+
: m_particleFieldName(particleFieldName)
18+
, m_x(pos)
19+
, m_rotation(rotation)
20+
, m_scale(scale)
21+
, m_type(type)
22+
, m_startTime(0)
23+
, m_endTime(REAL_MAX)
24+
{
25+
for (int i = 0; i < 3; i++)
26+
m_expression[i] = expression[i];
27+
}
28+
29+
AnimationField::~AnimationField(void)
30+
{
31+
}
32+
33+
void AnimationField::reset()
34+
{
35+
}
36+
37+
double getTime()
38+
{
39+
return TimeManager::getCurrent()->getTime();
40+
}
41+
42+
void AnimationField::step()
43+
{
44+
Simulation *sim = Simulation::getCurrent();
45+
TimeManager *tm = TimeManager::getCurrent();
46+
const Real t = tm->getTime();
47+
const Real dt = tm->getTimeStepSize();
48+
49+
if (t >= m_startTime && t <= m_endTime)
50+
{
51+
// animate particles
52+
const unsigned int nModels = sim->numberOfFluidModels();
53+
for (unsigned int m = 0; m < nModels; m++)
54+
{
55+
FluidModel *fm = sim->getFluidModel(m);
56+
const unsigned int numParticles = fm->numActiveParticles();
57+
58+
// find angular velocity field
59+
const FieldDescription *particleField = nullptr;
60+
for (unsigned int j = 0; j < fm->numberOfFields(); j++)
61+
{
62+
const FieldDescription &field = fm->getField(j);
63+
if (field.name == m_particleFieldName)
64+
{
65+
particleField = &field;
66+
break;
67+
}
68+
}
69+
70+
if (particleField == nullptr)
71+
continue;
72+
73+
#pragma omp parallel for schedule(static) default(shared)
74+
for (int i = 0; i < (int)numParticles; i++)
75+
{
76+
const Vector3r &xi = fm->getPosition(i);
77+
const Vector3r &vi = fm->getVelocity(i);
78+
if (inShape(m_type, xi, m_x, m_rotation, m_scale))
79+
{
80+
Eigen::Map<Vector3r> value(particleField->getFct(i));
81+
te_variable vars[] = { {"t", &t}, {"dt", &dt},
82+
{"x", &xi[0]}, {"y", &xi[1]}, {"z", &xi[2]},
83+
{"vx", &vi[0]}, {"vy", &vi[1]}, {"vz", &vi[2]},
84+
{"valuex", &value[0]}, {"valuey", &value[1]}, {"valuez", &value[2]},
85+
};
86+
const int numVars = 11;
87+
int err;
88+
89+
//////////////////////////////////////////////////////////////////////////
90+
// v_x
91+
//////////////////////////////////////////////////////////////////////////
92+
if (m_expression[0] != "")
93+
{
94+
te_expr *expr_vx = te_compile(m_expression[0].c_str(), vars, numVars, &err);
95+
if (expr_vx)
96+
value[0] = te_eval(expr_vx);
97+
te_free(expr_vx);
98+
99+
if (err != 0)
100+
LOG_ERR << "Animation field: expression for x is wrong.";
101+
}
102+
103+
//////////////////////////////////////////////////////////////////////////
104+
// v_y
105+
//////////////////////////////////////////////////////////////////////////
106+
if (m_expression[1] != "")
107+
{
108+
te_expr *expr_vy = te_compile(m_expression[1].c_str(), vars, numVars, &err);
109+
if (expr_vy)
110+
value[1] = te_eval(expr_vy);
111+
te_free(expr_vy);
112+
113+
if (err != 0)
114+
LOG_ERR << "Animation field: expression for y is wrong.";
115+
}
116+
117+
//////////////////////////////////////////////////////////////////////////
118+
// v_z
119+
//////////////////////////////////////////////////////////////////////////
120+
if (m_expression[2] != "")
121+
{
122+
te_expr *expr_vz = te_compile(m_expression[2].c_str(), vars, numVars, &err);
123+
if (expr_vz)
124+
value[2] = te_eval(expr_vz);
125+
te_free(expr_vz);
126+
127+
if (err != 0)
128+
LOG_ERR << "Animation field: expression for z is wrong.";
129+
}
130+
}
131+
}
132+
}
133+
}
134+
}
135+

SPlisHSPlasH/AnimationField.h

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
#ifndef __AnimationField_h__
2+
#define __AnimationField_h__
3+
4+
#include "Common.h"
5+
#include <vector>
6+
#include "FluidModel.h"
7+
8+
9+
namespace SPH
10+
{
11+
class AnimationField
12+
{
13+
public:
14+
AnimationField(
15+
const std::string &particleFieldName,
16+
const Vector3r &pos, const Matrix3r & rotation, const Vector3r &scale,
17+
const std::string expression[3], const unsigned int type = 0);
18+
virtual ~AnimationField();
19+
20+
protected:
21+
std::string m_particleFieldName;
22+
Vector3r m_x;
23+
Matrix3r m_rotation;
24+
Vector3r m_scale;
25+
std::string m_expression[3];
26+
unsigned int m_type;
27+
Real m_startTime;
28+
Real m_endTime;
29+
30+
FORCE_INLINE bool inBox(const Vector3r &x, const Vector3r &xBox, const Matrix3r &rotBox, const Vector3r &scaleBox)
31+
{
32+
const Vector3r xlocal = rotBox.transpose() * (x - xBox);
33+
// for a box shape, m_scale stores the half-size of the box
34+
// inside box if closer than half-size on all axes
35+
return (xlocal.array().abs() < scaleBox.array()).all();
36+
}
37+
38+
FORCE_INLINE bool inCylinder(const Vector3r &x, const Vector3r &xCyl, const Matrix3r &rotCyl, const Real h, const Real r2)
39+
{
40+
const Vector3r xlocal = rotCyl.transpose() * (x - xCyl);
41+
// inside cylinder if distance to x-axis is less than r
42+
// and projection on x-axis is between 0 and h
43+
const Real proj = xlocal.x();
44+
const Real d2 = Vector2r(xlocal.y(), xlocal.z()).squaredNorm();
45+
const Real hHalf = 0.5*h;
46+
return (proj > -hHalf) && (proj < hHalf) && (d2 < r2);
47+
}
48+
49+
FORCE_INLINE bool inSphere(const Vector3r &x, const Vector3r &pos, const Matrix3r &rot, const Real radius)
50+
{
51+
const Vector3r xlocal = rot.transpose() * (x - pos);
52+
return (xlocal.norm() < radius);
53+
}
54+
55+
FORCE_INLINE bool inShape(const int type, const Vector3r &x, const Vector3r &pos, const Matrix3r &rot, const Vector3r &scale)
56+
{
57+
if (type == 1)
58+
return inSphere(x, pos, rot, scale[0]);
59+
else if (type == 2)
60+
{
61+
const Real h = scale[0];
62+
const Real r = scale[1];
63+
return inCylinder(x, pos, rot, h, r*r);
64+
}
65+
else
66+
return inBox(x, pos, rot, 0.5*scale);
67+
}
68+
69+
public:
70+
void setStartTime(Real val) { m_startTime = val; }
71+
void setEndTime(Real val) { m_endTime = val; }
72+
73+
void step();
74+
virtual void reset();
75+
76+
};
77+
}
78+
79+
#endif
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
#include "AnimationFieldSystem.h"
2+
#include "FluidModel.h"
3+
#include "TimeStep.h"
4+
#include "Utilities/Logger.h"
5+
#include "Simulation.h"
6+
7+
8+
using namespace SPH;
9+
10+
11+
AnimationFieldSystem::AnimationFieldSystem() :
12+
m_fields()
13+
{
14+
}
15+
16+
AnimationFieldSystem::~AnimationFieldSystem(void)
17+
{
18+
for (size_t i = 0; i < m_fields.size(); i++)
19+
delete m_fields[i];
20+
}
21+
22+
void AnimationFieldSystem::step()
23+
{
24+
for (size_t i = 0; i < m_fields.size(); i++)
25+
{
26+
m_fields[i]->step();
27+
}
28+
}
29+
30+
void AnimationFieldSystem::reset()
31+
{
32+
for (size_t i = 0; i < m_fields.size(); i++)
33+
{
34+
m_fields[i]->reset();
35+
}
36+
}
37+
38+
void AnimationFieldSystem::addAnimationField(
39+
const std::string &particleFieldName,
40+
const Vector3r &pos, const Matrix3r & rotation, const Vector3r &scale,
41+
const std::string expression[3], const unsigned int type)
42+
{
43+
m_fields.push_back(new AnimationField(
44+
particleFieldName,
45+
pos, rotation, scale,
46+
expression, type));
47+
}
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
#ifndef __AnimationFieldSystem_h__
2+
#define __AnimationFieldSystem_h__
3+
4+
#include "Common.h"
5+
#include <vector>
6+
#include "AnimationField.h"
7+
8+
namespace SPH
9+
{
10+
class TimeStep;
11+
class FluidModel;
12+
13+
class AnimationFieldSystem
14+
{
15+
public:
16+
AnimationFieldSystem();
17+
virtual ~AnimationFieldSystem();
18+
19+
protected:
20+
std::vector<AnimationField*> m_fields;
21+
22+
//void resetState();
23+
24+
public:
25+
void addAnimationField(const std::string &particleFieldName, const Vector3r &pos, const Matrix3r & rotation, const Vector3r &scale,
26+
const std::string expression[3], const unsigned int type);
27+
unsigned int numAnimationFields() const { return static_cast<unsigned int>(m_fields.size()); }
28+
std::vector<AnimationField*> &getAnimationFields() { return m_fields; }
29+
30+
void step();
31+
void reset();
32+
};
33+
}
34+
35+
#endif

0 commit comments

Comments
 (0)