Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
559 changes: 187 additions & 372 deletions SPlisHSPlasH/Emitter.cpp

Large diffs are not rendered by default.

28 changes: 14 additions & 14 deletions SPlisHSPlasH/Emitter.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,26 +11,27 @@ namespace SPH
class Emitter
{
public:
Emitter(FluidModel *model,
const unsigned int width, const unsigned int height,
const Vector3r &pos, const Matrix3r & rotation,
const Real velocity,
const unsigned int type = 0);
virtual ~Emitter();
Emitter(FluidModel* model, const unsigned int width, const unsigned int height, const Vector3r& pos,
const Matrix3r& rotation, const Real velocity, const unsigned int type = 0, const bool useBoundary = false,
const unsigned int velocityProfile = 0);
virtual ~Emitter();

protected:
FluidModel *m_model;
unsigned int m_width;
unsigned int m_height;
unsigned int m_depth;
Vector3r m_size{0, 0, 0};
Vector3r m_x;
Matrix3r m_rotation;
Real m_velocity;
unsigned int m_type;
Real m_nextEmitTime;
Real m_emitStartTime;
Real m_emitEndTime;
unsigned int m_emitCounter;
Real m_emitStartTime{0};
Real m_emitEndTime{std::numeric_limits<Real>::max()};
unsigned int m_emitCounter{0};
unsigned int m_objectId;
bool m_useBoundary;
unsigned int m_velocityProfile;// 0: constant, 1: linear, 2: quadratic

FORCE_INLINE bool inBox(const Vector3r &x, const Vector3r &xBox, const Matrix3r &rotBox, const Vector3r &scaleBox)
{
Expand All @@ -53,12 +54,11 @@ namespace SPH

public:
void emitParticles(std::vector <unsigned int> &reusedParticles, unsigned int &indexReuse, unsigned int &numEmittedParticles);
void emitParticlesCircle(std::vector <unsigned int> &reusedParticles, unsigned int &indexReuse, unsigned int &numEmittedParticles);
Real getNextEmitTime() const { return m_nextEmitTime; }
void setNextEmitTime(Real val) { m_nextEmitTime = val; }
void setEmitStartTime(Real val) { m_emitStartTime = val; setNextEmitTime(val); }
void setEmitStartTime(Real val) { m_emitStartTime = val; }
void setEmitEndTime(Real val) { m_emitEndTime = val; }
static int getDepth();
static Vector3r getSize(const Real width, const Real height, const int type);
static Vector3r getSizeExtraMargin(const Real width, const Real height, const int type);

void step(std::vector <unsigned int> &reusedParticles, unsigned int &indexReuse, unsigned int &numEmittedParticles);
virtual void reset();
Expand Down
25 changes: 5 additions & 20 deletions SPlisHSPlasH/EmitterSystem.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -59,17 +59,6 @@ void EmitterSystem::step()
// reset particle state
Simulation *sim = Simulation::getCurrent();
const unsigned int nModels = sim->numberOfFluidModels();
for (unsigned int m = 0; m < nModels; m++)
{
FluidModel *fm = sim->getFluidModel(m);
const unsigned int numParticles = fm->numActiveParticles();
#pragma omp parallel for schedule(static) default(shared)
for (int i = 0; i < (int)numParticles; i++)
{
if (fm->getParticleState(i) == ParticleState::AnimatedByEmitter)
fm->setParticleState(i, ParticleState::Active);
}
}

reuseParticles();
unsigned int indexReuse = 0;
Expand All @@ -93,16 +82,12 @@ void EmitterSystem::reset()
}
}

void EmitterSystem::addEmitter(const unsigned int width, const unsigned int height,
const Vector3r &pos, const Matrix3r & rotation,
const Real velocity,
const unsigned int type)
void EmitterSystem::addEmitter(const unsigned int width, const unsigned int height, const Vector3r& pos,
const Matrix3r& rotation, const Real velocity, const unsigned int type,
const bool useBoundary, const unsigned int velocityProfile)
{
m_emitters.push_back(new Emitter(m_model,
width, height,
pos, rotation,
velocity,
type));
m_emitters.push_back(
new Emitter(m_model, width, height, pos, rotation, velocity, type, useBoundary, velocityProfile));
}

void EmitterSystem::enableReuseParticles(const Vector3r &boxMin /*= Vector3r(-1, -1, -1)*/, const Vector3r &boxMax /*= Vector3r(1, 1, 1)*/)
Expand Down
7 changes: 3 additions & 4 deletions SPlisHSPlasH/EmitterSystem.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,10 +32,9 @@ namespace SPH
public:
void enableReuseParticles(const Vector3r &boxMin = Vector3r(-1, -1, -1), const Vector3r &boxMax = Vector3r(1, 1, 1));
void disableReuseParticles();
void addEmitter(const unsigned int width, const unsigned int height,
const Vector3r &pos, const Matrix3r & rotation,
const Real velocity,
const unsigned int type);
void addEmitter(const unsigned int width, const unsigned int height, const Vector3r& pos, const Matrix3r& rotation,
const Real velocity, const unsigned int type, const bool useBoundary = false,
const unsigned int velocityProfile = 0);
unsigned int numEmitters() const { return static_cast<unsigned int>(m_emitters.size()); }
std::vector<Emitter*> &getEmitters() { return m_emitters; }

Expand Down
11 changes: 11 additions & 0 deletions SPlisHSPlasH/Utilities/SceneParameterObjects.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ int FluidBlockParameterObject::FLUID_BLOCK_VISMESH = -1;
int FluidBlockParameterObject::FLUID_BLOCK_MODE = -1;
int FluidBlockParameterObject::FLUID_BLOCK_INITIAL_VEL = -1;
int FluidBlockParameterObject::FLUID_BLOCK_INITIAL_ANGVEL = -1;
int EmitterParameterObject::EMITTER_USEBOUNDARY = -1;

void FluidBlockParameterObject::initParameters()
{
Expand Down Expand Up @@ -138,6 +139,7 @@ int EmitterParameterObject::EMITTER_ROTANGLE = -1;
int EmitterParameterObject::EMITTER_STARTTIME = -1;
int EmitterParameterObject::EMITTER_ENDTIME = -1;
int EmitterParameterObject::EMITTER_TYPE = -1;
int EmitterParameterObject::EMITTER_VELOCITYPROFILE = -1;

void EmitterParameterObject::initParameters()
{
Expand Down Expand Up @@ -180,6 +182,15 @@ void EmitterParameterObject::initParameters()
EMITTER_TYPE = createNumericParameter<unsigned int>("type", "Emitter type", &type);
setGroup(EMITTER_TYPE, "Emitter");
setDescription(EMITTER_TYPE, "Defines the shape of the emitter: 0: box, 1: circle.");

EMITTER_USEBOUNDARY = createBoolParameter("useBoundary", "Use Boundary", &useBoundary);
setGroup(EMITTER_USEBOUNDARY, "Emitter");
setDescription(EMITTER_USEBOUNDARY, "Creates a boundary model around the emitter if defined");

EMITTER_VELOCITYPROFILE =
createNumericParameter<unsigned int>("velocityProfile", "Velocity Profile", &velocityProfile);
setGroup(EMITTER_VELOCITYPROFILE, "Emitter");
setDescription(EMITTER_VELOCITYPROFILE, "Defines the velocity profile of the emitter.");
}


Expand Down
13 changes: 11 additions & 2 deletions SPlisHSPlasH/Utilities/SceneParameterObjects.h
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,8 @@ namespace Utilities
Real emitStartTime;
Real emitEndTime;
unsigned int type; // type: 0 = rectangular, 1 = circle
bool useBoundary;
unsigned int velocityProfile;

EmitterParameterObject()
{
Expand All @@ -158,10 +160,13 @@ namespace Utilities
emitStartTime = 0.0;
emitEndTime = std::numeric_limits<Real>::max();
type = 0;
useBoundary = false;
velocityProfile = 0;
}

EmitterParameterObject(std::string id_, unsigned int width_, unsigned int height_, Vector3r x_, Real velocity_, Vector3r axis_,
Real angle_, Real emitStartTime_, Real emitEndTime_, unsigned int type_)
EmitterParameterObject(std::string id_, unsigned int width_, unsigned int height_, Vector3r x_, Real velocity_,
Vector3r axis_, Real angle_, Real emitStartTime_, Real emitEndTime_, unsigned int type_,
bool useBoundary_, unsigned int velocityProfile_)
{
id = id_;
width = width_;
Expand All @@ -173,6 +178,8 @@ namespace Utilities
emitStartTime = emitStartTime_;
emitEndTime = emitEndTime_;
type = type_;
useBoundary = useBoundary_;
velocityProfile = velocityProfile_;
}

static int EMITTER_ID;
Expand All @@ -185,6 +192,8 @@ namespace Utilities
static int EMITTER_STARTTIME;
static int EMITTER_ENDTIME;
static int EMITTER_TYPE;
static int EMITTER_USEBOUNDARY;
static int EMITTER_VELOCITYPROFILE;

virtual void initParameters();
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ void PBDBoundarySimulator::initBoundaryData()
PBDWrapper::RBData rb;
rb.x = ed->x;
rb.R = AngleAxisr(ed->angle, ed->axis).toRotationMatrix();
rb.scale = Emitter::getSize(static_cast<Real>(ed->width), static_cast<Real>(ed->height), ed->type);
rb.scale = Emitter::getSizeExtraMargin(static_cast<Real>(ed->width), static_cast<Real>(ed->height), ed->type);
rb.restitution = 0.6;
rb.friction = 0.1;
if (ed->type == 0)
Expand Down
68 changes: 35 additions & 33 deletions Simulator/SimulatorBase.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1314,39 +1314,41 @@ void SimulatorBase::createEmitters()
ed->width = 1;
ed->type = 0;
}
Matrix3r rot = AngleAxisr(ed->angle, ed->axis).toRotationMatrix();
model->getEmitterSystem()->addEmitter(
ed->width, ed->height,
ed->x, rot,
ed->velocity,
ed->type);

// Generate boundary geometry around emitters
Emitter *emitter = model->getEmitterSystem()->getEmitters().back();
BoundaryParameterObject *emitterBoundary = new BoundaryParameterObject();
emitterBoundary->dynamic = false;
emitterBoundary->isWall = false;
emitterBoundary->color = { 0.2f, 0.2f, 0.2f, 1.0f };
emitterBoundary->axis = ed->axis;
emitterBoundary->angle = ed->angle;
const Real supportRadius = sim->getSupportRadius();
const Vector3r & emitDir = rot.col(0);
emitterBoundary->scale = Emitter::getSize(static_cast<Real>(ed->width), static_cast<Real>(ed->height), ed->type);
const Vector3r pos = ed->x;
emitterBoundary->translation = pos;
emitterBoundary->samplesFile = "";
emitterBoundary->mapInvert = false;
emitterBoundary->mapResolution = Eigen::Matrix<unsigned int, 3, 1, Eigen::DontAlign>(20, 20, 20);
emitterBoundary->mapThickness = 0.0;

if (sim->is2DSimulation())
emitterBoundary->scale[2] = 2 * supportRadius;

if (ed->type == 0)
emitterBoundary->meshFile = FileSystem::normalizePath(getExePath() + "/resources/emitter_boundary/EmitterBox.obj");
else if (ed->type == 1)
emitterBoundary->meshFile = FileSystem::normalizePath(getExePath() + "/resources/emitter_boundary/EmitterCylinder.obj");
scene.boundaryModels.push_back(emitterBoundary);
Matrix3r rot = AngleAxisr(ed->angle, ed->axis.normalized()).toRotationMatrix();
model->getEmitterSystem()->addEmitter(ed->width, ed->height, ed->x, rot, ed->velocity, ed->type,
ed->useBoundary, ed->velocityProfile);

Emitter* emitter = model->getEmitterSystem()->getEmitters().back();
if (ed->useBoundary) {
// Generate boundary geometry around emitters
BoundaryParameterObject* emitterBoundary = new BoundaryParameterObject();
emitterBoundary->dynamic = false;
emitterBoundary->isWall = false;
emitterBoundary->color = {0.2f, 0.2f, 0.2f, 1.0f};
emitterBoundary->axis = ed->axis;
emitterBoundary->angle = ed->angle;
const Real supportRadius = sim->getSupportRadius();
const Vector3r& emitDir = rot.col(0);
emitterBoundary->scale =
Emitter::getSizeExtraMargin(static_cast<Real>(ed->width), static_cast<Real>(ed->height), ed->type);
const Vector3r pos = ed->x;
emitterBoundary->translation = pos;
emitterBoundary->samplesFile = "";
emitterBoundary->mapInvert = false;
emitterBoundary->mapResolution = Eigen::Matrix<unsigned int, 3, 1, Eigen::DontAlign>(20, 20, 20);
emitterBoundary->mapThickness = 0.0;

if (sim->is2DSimulation())
emitterBoundary->scale[2] = 2 * supportRadius;

if (ed->type == 0)
emitterBoundary->meshFile =
FileSystem::normalizePath(getExePath() + "/resources/emitter_boundary/EmitterBox.obj");
else if (ed->type == 1)
emitterBoundary->meshFile =
FileSystem::normalizePath(getExePath() + "/resources/emitter_boundary/EmitterCylinder.obj");
scene.boundaryModels.push_back(emitterBoundary);
}

// reuse particles if they are outside of a bounding box
bool emitterReuseParticles = false;
Expand Down
3 changes: 0 additions & 3 deletions pySPlisHSPlasH/EmitterModule.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,6 @@ void EmitterModule(py::module m_sub){
return SPH::Emitter(model, width, height, pos, rotation, velocity, type);
}))
.def("emitParticles", &SPH::Emitter::emitParticles)
.def("emitParticlesCircle", &SPH::Emitter::emitParticlesCircle)
.def("getNextEmitTime", &SPH::Emitter::getNextEmitTime)
.def("setNextEmitTime", &SPH::Emitter::setNextEmitTime)
.def("setEmitStartTime", &SPH::Emitter::setEmitStartTime)
.def("setEmitEndTime", &SPH::Emitter::setEmitEndTime)
.def("getPosition", &SPH::Emitter::getPosition)
Expand Down
13 changes: 8 additions & 5 deletions pySPlisHSPlasH/UtilitiesModule.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -339,10 +339,12 @@ void UtilitiesModule(py::module m) {

py::class_<Utilities::EmitterParameterObject, GenParam::ParameterObject>(m_sub_sub, "EmitterData")
.def(py::init<>())
.def(py::init<std::string, unsigned int, unsigned int, Vector3r, Real, Vector3r, Real, Real, Real, unsigned int>(),
"id"_a="Fluid", "width"_a=5, "height"_a=5, "x"_a=Vector3r::Zero(),
"velocity"_a=1, "axis"_a = Vector3r(1, 0, 0), "angle"_a = 0.0, "emitStartTime"_a=0,
"emitEndTime"_a=std::numeric_limits<Real>::max(), "type"_a=0)
.def(py::init<std::string, unsigned int, unsigned int, Vector3r, Real, Vector3r, Real, Real, Real, unsigned int,
bool, unsigned int>(),
"id"_a = "Fluid", "width"_a = 5, "height"_a = 5, "x"_a = Vector3r::Zero(), "velocity"_a = 1,
"axis"_a = Vector3r(1, 0, 0), "angle"_a = 0.0, "emitStartTime"_a = 0,
"emitEndTime"_a = std::numeric_limits<Real>::max(), "type"_a = 0, "useBoundary"_a = false,
"velocityProfile"_a = 0)
.def_readwrite("id", &Utilities::EmitterParameterObject::id)
.def_readwrite("width", &Utilities::EmitterParameterObject::width)
.def_readwrite("height", &Utilities::EmitterParameterObject::height)
Expand All @@ -352,7 +354,8 @@ void UtilitiesModule(py::module m) {
.def_readwrite("angle", &Utilities::EmitterParameterObject::angle)
.def_readwrite("emitStartTime", &Utilities::EmitterParameterObject::emitStartTime)
.def_readwrite("emitEndTime", &Utilities::EmitterParameterObject::emitEndTime)
.def_readwrite("type", &Utilities::EmitterParameterObject::type);
.def_readwrite("type", &Utilities::EmitterParameterObject::type)
.def_readwrite("useBoundary", &Utilities::EmitterParameterObject::useBoundary);

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