Skip to content

Commit 7bf5480

Browse files
committed
new emitter concept for variable velocity
1 parent d6de341 commit 7bf5480

10 files changed

Lines changed: 246 additions & 454 deletions

File tree

SPlisHSPlasH/Emitter.cpp

Lines changed: 173 additions & 372 deletions
Large diffs are not rendered by default.

SPlisHSPlasH/Emitter.h

Lines changed: 12 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -11,26 +11,25 @@ namespace SPH
1111
class Emitter
1212
{
1313
public:
14-
Emitter(FluidModel *model,
15-
const unsigned int width, const unsigned int height,
16-
const Vector3r &pos, const Matrix3r & rotation,
17-
const Real velocity,
18-
const unsigned int type = 0);
19-
virtual ~Emitter();
14+
Emitter(FluidModel* model, const unsigned int width, const unsigned int height, const Vector3r& pos,
15+
const Matrix3r& rotation, const Real velocity, const unsigned int type = 0, const bool useBoundary = false);
16+
virtual ~Emitter();
2017

2118
protected:
2219
FluidModel *m_model;
2320
unsigned int m_width;
2421
unsigned int m_height;
22+
unsigned int m_depth;
23+
Vector3r m_size{0, 0, 0};
2524
Vector3r m_x;
2625
Matrix3r m_rotation;
2726
Real m_velocity;
2827
unsigned int m_type;
29-
Real m_nextEmitTime;
30-
Real m_emitStartTime;
31-
Real m_emitEndTime;
32-
unsigned int m_emitCounter;
28+
Real m_emitStartTime{0};
29+
Real m_emitEndTime{std::numeric_limits<Real>::max()};
30+
unsigned int m_emitCounter{0};
3331
unsigned int m_objectId;
32+
bool m_useBoundary;
3433

3534
FORCE_INLINE bool inBox(const Vector3r &x, const Vector3r &xBox, const Matrix3r &rotBox, const Vector3r &scaleBox)
3635
{
@@ -53,12 +52,11 @@ namespace SPH
5352

5453
public:
5554
void emitParticles(std::vector <unsigned int> &reusedParticles, unsigned int &indexReuse, unsigned int &numEmittedParticles);
56-
void emitParticlesCircle(std::vector <unsigned int> &reusedParticles, unsigned int &indexReuse, unsigned int &numEmittedParticles);
57-
Real getNextEmitTime() const { return m_nextEmitTime; }
58-
void setNextEmitTime(Real val) { m_nextEmitTime = val; }
59-
void setEmitStartTime(Real val) { m_emitStartTime = val; setNextEmitTime(val); }
55+
void setEmitStartTime(Real val) { m_emitStartTime = val; }
6056
void setEmitEndTime(Real val) { m_emitEndTime = val; }
57+
static int getDepth();
6158
static Vector3r getSize(const Real width, const Real height, const int type);
59+
static Vector3r getSizeExtraMargin(const Real width, const Real height, const int type);
6260

6361
void step(std::vector <unsigned int> &reusedParticles, unsigned int &indexReuse, unsigned int &numEmittedParticles);
6462
virtual void reset();

SPlisHSPlasH/EmitterSystem.cpp

Lines changed: 4 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -59,17 +59,6 @@ void EmitterSystem::step()
5959
// reset particle state
6060
Simulation *sim = Simulation::getCurrent();
6161
const unsigned int nModels = sim->numberOfFluidModels();
62-
for (unsigned int m = 0; m < nModels; m++)
63-
{
64-
FluidModel *fm = sim->getFluidModel(m);
65-
const unsigned int numParticles = fm->numActiveParticles();
66-
#pragma omp parallel for schedule(static) default(shared)
67-
for (int i = 0; i < (int)numParticles; i++)
68-
{
69-
if (fm->getParticleState(i) == ParticleState::AnimatedByEmitter)
70-
fm->setParticleState(i, ParticleState::Active);
71-
}
72-
}
7362

7463
reuseParticles();
7564
unsigned int indexReuse = 0;
@@ -93,16 +82,11 @@ void EmitterSystem::reset()
9382
}
9483
}
9584

96-
void EmitterSystem::addEmitter(const unsigned int width, const unsigned int height,
97-
const Vector3r &pos, const Matrix3r & rotation,
98-
const Real velocity,
99-
const unsigned int type)
85+
void EmitterSystem::addEmitter(const unsigned int width, const unsigned int height, const Vector3r& pos,
86+
const Matrix3r& rotation, const Real velocity, const unsigned int type,
87+
const bool useBoundary)
10088
{
101-
m_emitters.push_back(new Emitter(m_model,
102-
width, height,
103-
pos, rotation,
104-
velocity,
105-
type));
89+
m_emitters.push_back(new Emitter(m_model, width, height, pos, rotation, velocity, type, useBoundary));
10690
}
10791

10892
void EmitterSystem::enableReuseParticles(const Vector3r &boxMin /*= Vector3r(-1, -1, -1)*/, const Vector3r &boxMax /*= Vector3r(1, 1, 1)*/)

SPlisHSPlasH/EmitterSystem.h

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -32,10 +32,8 @@ namespace SPH
3232
public:
3333
void enableReuseParticles(const Vector3r &boxMin = Vector3r(-1, -1, -1), const Vector3r &boxMax = Vector3r(1, 1, 1));
3434
void disableReuseParticles();
35-
void addEmitter(const unsigned int width, const unsigned int height,
36-
const Vector3r &pos, const Matrix3r & rotation,
37-
const Real velocity,
38-
const unsigned int type);
35+
void addEmitter(const unsigned int width, const unsigned int height, const Vector3r& pos, const Matrix3r& rotation,
36+
const Real velocity, const unsigned int type, const bool useBoundary = false);
3937
unsigned int numEmitters() const { return static_cast<unsigned int>(m_emitters.size()); }
4038
std::vector<Emitter*> &getEmitters() { return m_emitters; }
4139

SPlisHSPlasH/Utilities/SceneParameterObjects.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ int FluidBlockParameterObject::FLUID_BLOCK_VISMESH = -1;
1717
int FluidBlockParameterObject::FLUID_BLOCK_MODE = -1;
1818
int FluidBlockParameterObject::FLUID_BLOCK_INITIAL_VEL = -1;
1919
int FluidBlockParameterObject::FLUID_BLOCK_INITIAL_ANGVEL = -1;
20+
int EmitterParameterObject::EMITTER_USEBOUNDARY = -1;
2021

2122
void FluidBlockParameterObject::initParameters()
2223
{
@@ -180,6 +181,10 @@ void EmitterParameterObject::initParameters()
180181
EMITTER_TYPE = createNumericParameter<unsigned int>("type", "Emitter type", &type);
181182
setGroup(EMITTER_TYPE, "Emitter");
182183
setDescription(EMITTER_TYPE, "Defines the shape of the emitter: 0: box, 1: circle.");
184+
185+
EMITTER_USEBOUNDARY = createBoolParameter("useBoundary", "Use Boundary", &useBoundary);
186+
setGroup(EMITTER_USEBOUNDARY, "Emitter");
187+
setDescription(EMITTER_USEBOUNDARY, "Creates a boundary model around the emitter if defined");
183188
}
184189

185190

SPlisHSPlasH/Utilities/SceneParameterObjects.h

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,7 @@ namespace Utilities
144144
Real emitStartTime;
145145
Real emitEndTime;
146146
unsigned int type; // type: 0 = rectangular, 1 = circle
147+
bool useBoundary;
147148

148149
EmitterParameterObject()
149150
{
@@ -158,10 +159,12 @@ namespace Utilities
158159
emitStartTime = 0.0;
159160
emitEndTime = std::numeric_limits<Real>::max();
160161
type = 0;
162+
useBoundary = false;
161163
}
162164

163-
EmitterParameterObject(std::string id_, unsigned int width_, unsigned int height_, Vector3r x_, Real velocity_, Vector3r axis_,
164-
Real angle_, Real emitStartTime_, Real emitEndTime_, unsigned int type_)
165+
EmitterParameterObject(std::string id_, unsigned int width_, unsigned int height_, Vector3r x_, Real velocity_,
166+
Vector3r axis_, Real angle_, Real emitStartTime_, Real emitEndTime_, unsigned int type_,
167+
bool useBoundary_)
165168
{
166169
id = id_;
167170
width = width_;
@@ -173,6 +176,7 @@ namespace Utilities
173176
emitStartTime = emitStartTime_;
174177
emitEndTime = emitEndTime_;
175178
type = type_;
179+
useBoundary = useBoundary_;
176180
}
177181

178182
static int EMITTER_ID;
@@ -185,6 +189,7 @@ namespace Utilities
185189
static int EMITTER_STARTTIME;
186190
static int EMITTER_ENDTIME;
187191
static int EMITTER_TYPE;
192+
static int EMITTER_USEBOUNDARY;
188193

189194
virtual void initParameters();
190195
};

Simulator/PositionBasedDynamicsWrapper/PBDBoundarySimulator.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ void PBDBoundarySimulator::initBoundaryData()
7070
PBDWrapper::RBData rb;
7171
rb.x = ed->x;
7272
rb.R = AngleAxisr(ed->angle, ed->axis).toRotationMatrix();
73-
rb.scale = Emitter::getSize(static_cast<Real>(ed->width), static_cast<Real>(ed->height), ed->type);
73+
rb.scale = Emitter::getSizeExtraMargin(static_cast<Real>(ed->width), static_cast<Real>(ed->height), ed->type);
7474
rb.restitution = 0.6;
7575
rb.friction = 0.1;
7676
if (ed->type == 0)

Simulator/SimulatorBase.cpp

Lines changed: 35 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1314,39 +1314,41 @@ void SimulatorBase::createEmitters()
13141314
ed->width = 1;
13151315
ed->type = 0;
13161316
}
1317-
Matrix3r rot = AngleAxisr(ed->angle, ed->axis).toRotationMatrix();
1318-
model->getEmitterSystem()->addEmitter(
1319-
ed->width, ed->height,
1320-
ed->x, rot,
1321-
ed->velocity,
1322-
ed->type);
1323-
1324-
// Generate boundary geometry around emitters
1325-
Emitter *emitter = model->getEmitterSystem()->getEmitters().back();
1326-
BoundaryParameterObject *emitterBoundary = new BoundaryParameterObject();
1327-
emitterBoundary->dynamic = false;
1328-
emitterBoundary->isWall = false;
1329-
emitterBoundary->color = { 0.2f, 0.2f, 0.2f, 1.0f };
1330-
emitterBoundary->axis = ed->axis;
1331-
emitterBoundary->angle = ed->angle;
1332-
const Real supportRadius = sim->getSupportRadius();
1333-
const Vector3r & emitDir = rot.col(0);
1334-
emitterBoundary->scale = Emitter::getSize(static_cast<Real>(ed->width), static_cast<Real>(ed->height), ed->type);
1335-
const Vector3r pos = ed->x;
1336-
emitterBoundary->translation = pos;
1337-
emitterBoundary->samplesFile = "";
1338-
emitterBoundary->mapInvert = false;
1339-
emitterBoundary->mapResolution = Eigen::Matrix<unsigned int, 3, 1, Eigen::DontAlign>(20, 20, 20);
1340-
emitterBoundary->mapThickness = 0.0;
1341-
1342-
if (sim->is2DSimulation())
1343-
emitterBoundary->scale[2] = 2 * supportRadius;
1344-
1345-
if (ed->type == 0)
1346-
emitterBoundary->meshFile = FileSystem::normalizePath(getExePath() + "/resources/emitter_boundary/EmitterBox.obj");
1347-
else if (ed->type == 1)
1348-
emitterBoundary->meshFile = FileSystem::normalizePath(getExePath() + "/resources/emitter_boundary/EmitterCylinder.obj");
1349-
scene.boundaryModels.push_back(emitterBoundary);
1317+
Matrix3r rot = AngleAxisr(ed->angle, ed->axis.normalized()).toRotationMatrix();
1318+
model->getEmitterSystem()->addEmitter(ed->width, ed->height, ed->x, rot, ed->velocity, ed->type,
1319+
ed->useBoundary);
1320+
1321+
Emitter* emitter = model->getEmitterSystem()->getEmitters().back();
1322+
if (ed->useBoundary) {
1323+
// Generate boundary geometry around emitters
1324+
BoundaryParameterObject* emitterBoundary = new BoundaryParameterObject();
1325+
emitterBoundary->dynamic = false;
1326+
emitterBoundary->isWall = false;
1327+
emitterBoundary->color = {0.2f, 0.2f, 0.2f, 1.0f};
1328+
emitterBoundary->axis = ed->axis;
1329+
emitterBoundary->angle = ed->angle;
1330+
const Real supportRadius = sim->getSupportRadius();
1331+
const Vector3r& emitDir = rot.col(0);
1332+
emitterBoundary->scale =
1333+
Emitter::getSizeExtraMargin(static_cast<Real>(ed->width), static_cast<Real>(ed->height), ed->type);
1334+
const Vector3r pos = ed->x;
1335+
emitterBoundary->translation = pos;
1336+
emitterBoundary->samplesFile = "";
1337+
emitterBoundary->mapInvert = false;
1338+
emitterBoundary->mapResolution = Eigen::Matrix<unsigned int, 3, 1, Eigen::DontAlign>(20, 20, 20);
1339+
emitterBoundary->mapThickness = 0.0;
1340+
1341+
if (sim->is2DSimulation())
1342+
emitterBoundary->scale[2] = 2 * supportRadius;
1343+
1344+
if (ed->type == 0)
1345+
emitterBoundary->meshFile =
1346+
FileSystem::normalizePath(getExePath() + "/resources/emitter_boundary/EmitterBox.obj");
1347+
else if (ed->type == 1)
1348+
emitterBoundary->meshFile =
1349+
FileSystem::normalizePath(getExePath() + "/resources/emitter_boundary/EmitterCylinder.obj");
1350+
scene.boundaryModels.push_back(emitterBoundary);
1351+
}
13501352

13511353
// reuse particles if they are outside of a bounding box
13521354
bool emitterReuseParticles = false;

pySPlisHSPlasH/EmitterModule.cpp

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,9 +28,6 @@ void EmitterModule(py::module m_sub){
2828
return SPH::Emitter(model, width, height, pos, rotation, velocity, type);
2929
}))
3030
.def("emitParticles", &SPH::Emitter::emitParticles)
31-
.def("emitParticlesCircle", &SPH::Emitter::emitParticlesCircle)
32-
.def("getNextEmitTime", &SPH::Emitter::getNextEmitTime)
33-
.def("setNextEmitTime", &SPH::Emitter::setNextEmitTime)
3431
.def("setEmitStartTime", &SPH::Emitter::setEmitStartTime)
3532
.def("setEmitEndTime", &SPH::Emitter::setEmitEndTime)
3633
.def("getPosition", &SPH::Emitter::getPosition)

pySPlisHSPlasH/UtilitiesModule.cpp

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -339,10 +339,11 @@ void UtilitiesModule(py::module m) {
339339

340340
py::class_<Utilities::EmitterParameterObject, GenParam::ParameterObject>(m_sub_sub, "EmitterData")
341341
.def(py::init<>())
342-
.def(py::init<std::string, unsigned int, unsigned int, Vector3r, Real, Vector3r, Real, Real, Real, unsigned int>(),
343-
"id"_a="Fluid", "width"_a=5, "height"_a=5, "x"_a=Vector3r::Zero(),
344-
"velocity"_a=1, "axis"_a = Vector3r(1, 0, 0), "angle"_a = 0.0, "emitStartTime"_a=0,
345-
"emitEndTime"_a=std::numeric_limits<Real>::max(), "type"_a=0)
342+
.def(py::init<std::string, unsigned int, unsigned int, Vector3r, Real, Vector3r, Real, Real, Real, unsigned int,
343+
bool>(),
344+
"id"_a = "Fluid", "width"_a = 5, "height"_a = 5, "x"_a = Vector3r::Zero(), "velocity"_a = 1,
345+
"axis"_a = Vector3r(1, 0, 0), "angle"_a = 0.0, "emitStartTime"_a = 0,
346+
"emitEndTime"_a = std::numeric_limits<Real>::max(), "type"_a = 0, "useBoundary"_a = false)
346347
.def_readwrite("id", &Utilities::EmitterParameterObject::id)
347348
.def_readwrite("width", &Utilities::EmitterParameterObject::width)
348349
.def_readwrite("height", &Utilities::EmitterParameterObject::height)
@@ -352,7 +353,8 @@ void UtilitiesModule(py::module m) {
352353
.def_readwrite("angle", &Utilities::EmitterParameterObject::angle)
353354
.def_readwrite("emitStartTime", &Utilities::EmitterParameterObject::emitStartTime)
354355
.def_readwrite("emitEndTime", &Utilities::EmitterParameterObject::emitEndTime)
355-
.def_readwrite("type", &Utilities::EmitterParameterObject::type);
356+
.def_readwrite("type", &Utilities::EmitterParameterObject::type)
357+
.def_readwrite("useBoundary", &Utilities::EmitterParameterObject::useBoundary);
356358

357359
py::class_<Utilities::AnimationFieldParameterObject, GenParam::ParameterObject>(m_sub_sub, "AnimationFieldData")
358360
.def(py::init<>())

0 commit comments

Comments
 (0)