16 #include <openvdb/openvdb.h>
28 {
AnimationType::ORBIT,
"orbit",
"Make animation by orbiting camera around specified center point." },
57 auto particleEnabler = [
this] {
60 auto raymarcherEnabler = [
this] {
63 auto surfaceEnabler = [
this] {
67 auto volumeEnabler = [
this] {
73 rendererCat.
connect(
"Quantities",
"quantities", colorizers);
74 rendererCat.
connect(
"Include surface gravity",
"surface_gravity", addSurfaceGravity)
76 .setTooltip(
"Include the surface gravity of the particle itself.");
77 rendererCat.
connect<
bool>(
"Transparent background",
"transparent", transparentBackground);
83 .setEnabler(particleEnabler);
93 .setEnabler(surfaceEnabler);
95 .setEnabler(surfaceEnabler);
97 .setEnabler(surfaceEnabler);
99 .setEnabler(raymarcherEnabler);
102 .setEnabler(raymarcherEnabler);
104 .setEnabler(raymarcherEnabler);
127 animationCat.
connect<
Float>(
"Angular step",
"step", orbit.step)
130 animationCat.
connect<
Float>(
"Final angle",
"final_angle", orbit.finalAngle)
133 animationCat.
connect<
Path>(
"First file",
"first_file", sequence.firstFile)
147 bool addSurfaceGravity;
153 const bool addSurfaceGravity)
155 , scheduler(scheduler)
158 , addSurfaceGravity(addSurfaceGravity) {}
165 gravity.build(*scheduler, storage);
170 gravity.evalAll(*scheduler, dv, stats);
171 for (
Size i = 0; i < dv.
size(); ++i) {
175 if (addSurfaceGravity) {
179 for (
Size i = 0; i < r.size(); ++i) {
180 acc[i] += G * m[i] /
sqr(r[i][
H]);
197 virtual std::string
name()
const override {
206 const bool addSurfaceGravity) {
228 if (!project.
getPalette(
"Acceleration", palette)) {
231 colorizerArray.
push(makeAuto<GravityColorizer>(scheduler, palette, G, addSurfaceGravity));
236 return colorizerArray;
268 Movie movie(gui, std::move(renderer), std::move(colorizerArray), std::move(params));
282 for (
Float phi = 0._f; phi < orbit.finalAngle; phi += orbit.step) {
283 const Vector newPosition = target + orbitRadius * (
cos(phi) *
Vector(0._f, 0._f, 1._f) +
304 if (fileMap.
empty()) {
307 const Size firstKey = fileMap.
begin()->key;
310 for (
auto& element : fileMap) {
313 const Outcome result = input->load(element.value, storage, stats);
320 if (element.key == firstKey) {
321 callbacks.
onSetUp(storage, stats);
329 movie.
save(storage, stats);
344 std::atomic_bool cancelled;
351 : params(
std::move(params))
352 , renderer(
std::move(renderer))
353 , colorizer(
std::move(colorizer))
355 , cancelled(false) {}
375 size = correctAspectRatio(resolution,
float(size.
x) /
float(size.
y));
378 renderer->
render(params, dummy, output);
383 params = std::move(newParams);
384 params.
camera = std::move(camera);
388 params.
camera = std::move(newCamera);
392 colorizer = std::move(newColorizer);
396 renderer = std::move(newRenderer);
405 Pixel correctAspectRatio(
const Pixel resolution,
const float aspect)
const {
406 const float current = float(resolution.
x) / float(resolution.
y);
407 if (current > aspect) {
408 return Pixel(resolution.
x * aspect / current, resolution.
y);
410 return Pixel(resolution.
x, resolution.
y * current / aspect);
417 throw InvalidSetup(
"Only enabled for single-frame renders");
431 params.
background =
Rgba(0.f, 0.f, 0.f, transparentBackground ? 0.f : 1.f);
440 return makeAuto<RenderPreview>(std::move(params), std::move(renderer), std::move(colorizer), data);
447 if (!colorizer.
empty()) {
448 return std::move(colorizer.
front());
466 [](
const std::string& name) {
return makeAuto<AnimationJob>(name); },
467 "Renders an image or a sequence of images from given particle input(s)");
477 return openvdb::Vec3R(v[
X], v[
Y], v[
Z]);
501 gridCat.
connect(
"Grid start",
"grid_start", gridStart);
502 gridCat.
connect(
"Grid end",
"grid_end", gridEnd);
503 gridCat.
connect(
"Resolution power",
"power", dimPower);
504 gridCat.
connect(
"Surface level",
"surface_level", surfaceLevel);
507 inputCat.
connect(
"Enable",
"enable_sequence", sequence.enabled);
508 inputCat.
connect(
"First file",
"first_file", sequence.firstFile)
511 .
setEnabler([
this] {
return sequence.enabled; });
514 outputCat.
connect(
"VDB File",
"file", path)
517 .setEnabler([
this] {
return !sequence.enabled; });
523 openvdb::initialize();
524 auto deinit =
finally([] { openvdb::uninitialize(); });
526 if (sequence.enabled) {
528 if (fileMap.
empty()) {
531 const Size firstKey = fileMap.
begin()->key;
534 for (
auto& element : fileMap) {
537 const Outcome result = input->load(element.value, storage, stats);
542 Path outputPath = element.value;
544 this->generate(storage, global, outputPath);
548 if (element.key == firstKey) {
549 callbacks.
onSetUp(storage, stats);
558 Storage& storage = getInput<ParticleData>(
"particles")->storage;
559 this->generate(storage, global, path);
564 openvdb::FloatGrid::Ptr colorField = openvdb::FloatGrid::create(-surfaceLevel);
565 openvdb::Vec3SGrid::Ptr velocityField = openvdb::Vec3SGrid::create(
vectorToVec3R(
Vector(0._f)));
566 openvdb::FloatGrid::Ptr energyField = openvdb::FloatGrid::create(0._f);
568 colorField->setName(
"Density");
569 velocityField->setName(
"Velocity");
570 energyField->setName(
"Emission");
578 const Box box(gridStart, gridEnd);
579 const Size gridSize = 1 << dimPower;
580 const Indices gridIdxs(gridSize);
584 typename openvdb::FloatGrid::Accessor colorAccessor = colorField->getAccessor();
585 typename openvdb::Vec3SGrid::Accessor velocityAccessor = velocityField->getAccessor();
586 typename openvdb::FloatGrid::Accessor energyAccessor = energyField->getAccessor();
587 for (
Size i = 0; i < r.
size(); ++i) {
591 for (
int x = from[
X]; x <= to[
X]; ++x) {
592 for (
int y = from[
Y]; y <= to[
Y]; ++y) {
593 for (
int z = from[
Z]; z <= to[
Z]; ++z) {
597 const Float p = m[i] / rho;
600 const openvdb::Coord coord(x, y, z);
601 colorAccessor.modifyValue(coord, [p, w](
float& color) { color += p * w; });
602 energyAccessor.modifyValue(
603 coord, [p, w, &u, i](
float& energy) { energy += p * w * u[i]; });
612 openvdb::GridPtrVec vdbGrids;
613 vdbGrids.push_back(colorField);
615 vdbGrids.push_back(energyField);
617 Path vdbPath = outputPath;
619 openvdb::io::File vdbFile(vdbPath.
native());
620 vdbFile.write(vdbGrids);
628 [](
const std::string& name) {
return makeAuto<VdbJob>(name); },
629 "Converts the particle data into a volumetric grid in OpenVDB format.");
#define NOT_IMPLEMENTED
Helper macro marking missing implementation.
Barnes-Hut algorithm for computation of gravitational acceleration.
Defines projection transforming 3D particles onto 2D screen.
Object converting quantity values of particles into colors.
@ VELOCITY
Particle velocities.
@ BOUND_COMPONENT_ID
Color assigned to each group of gravitationally bound particles.
@ ACCELERATION
Acceleration of particles.
@ BEAUTY
Attempts to show the real-world look.
uint32_t Size
Integral type used to index arrays (by default).
double Float
Precision used withing the code. Use Float instead of float or double where precision is important.
Basic interface defining a single run.
FlatMap< Size, Path > getFileSequence(const Path &firstFile)
VirtualSettings::Category & addGenericCategory(VirtualSettings &connector, std::string &instanceName)
Adds a common settings category, used by all jobs.
constexpr INLINE T max(const T &f1, const T &f2)
NAMESPACE_SPH_BEGIN constexpr INLINE T min(const T &f1, const T &f2)
Minimum & Maximum value.
constexpr INLINE T sqr(const T &f) noexcept
Return a squared value.
INLINE auto floor(const T &f)
constexpr Float DEG_TO_RAD
INLINE auto ceil(const T &f)
Periodically saves rendered images to disk.
#define INLINE
Macros for conditional compilation based on selected compiler.
#define NAMESPACE_SPH_END
const NothingType NOTHING
@ POSITION
Positions of particles, always a vector quantity.
QuantityId
Unique IDs of basic quantities of SPH particles.
@ POSITION
Positions (velocities, accelerations) of particles, always a vector quantity,.
@ ENERGY
Specific internal energy, always a scalar quantity.
@ MASS
Paricles masses, always a scalar quantity.
JobRegistrar sRegisterAnimation("render animation", "animation", "rendering", [](const std::string &name) { return makeAuto< AnimationJob >(name);}, "Renders an image or a sequence of images from given particle input(s)")
Tuple< Indices, Indices > getParticleBox(const Vector &r, const VdbParams ¶ms)
Vector worldToRelative(const Vector &r, const VdbParams ¶ms)
INLINE openvdb::Vec3R vectorToVec3R(const Vector &v)
Vector relativeToWorld(const Vector &r, const VdbParams ¶ms)
@ WALLCLOCK_TIME
Current wallclock duration of the simulation.
Measuring time intervals and executing periodic events.
INLINE Tuple< TArgs &... > tieToTuple(TArgs &... args)
Creates a tuple of l-value references. Use IGNORE placeholder to omit one or more parameters.
INLINE Float getLength(const Vector &v)
Returns the length of the vector. Enabled only for vectors of floating-point precision.
BasicVector< Float > Vector
Array< IVirtualEntry::FileFormat > getInputFormats()
Convenience function, returning the list of input file formats defined by IoEnum.
Object providing connection between component parameters and values exposed to the user.
virtual void evaluate(const RunSettings &global, IRunCallbacks &UNUSED(callbacks)) override
AutoPtr< IRenderPreview > getRenderPreview(const RunSettings &global) const
AnimationJob(const std::string &name)
AutoPtr< IRenderer > getRenderer(const RunSettings &global) const
AutoPtr< IColorizer > getColorizer(const RunSettings &global) const
virtual VirtualSettings getSettings() override
Returns a settings object which allows to query and modify the state of the job.
RenderParams getRenderParams() const
INLINE TCounter size() const
void resize(const TCounter newSize)
Resizes the array to new size.
INLINE void push(U &&u)
Adds new element to the end of the array, resizing the array if necessary.
void fill(const T &t)
Sets all elements of the array to given value.
INLINE TCounter size() const noexcept
INLINE T & front() noexcept
INLINE bool empty() const noexcept
Multipole approximation of distance particle.
Helper object defining three-dimensional interval (box).
INLINE const Vector & lower() const
Returns lower bounds of the box.
INLINE Vector size() const
Returns box dimensions.
EntryControl & setEnabler(const Enabler &newEnabler)
Adds or replaces the enabler functor of the entry.
EntryControl & setPathType(const PathType &newType)
Sets the type of the path.
EntryControl & setFileFormats(Array< FileFormat > &&formats)
Sets the allowed file formats.
constexpr INLINE bool has(const TEnum flag) const
Checks if the object has a given flag.
Container of key-value pairs.
INLINE Size empty() const
Returns true if the map contains no elements, false otherwise.
INLINE Iterator< Element > begin()
Returns the iterator pointing to the first element.
INLINE Size size() const
Returns the number of elements in the map.
virtual Optional< Vector > evalVector(const Size UNUSED(idx)) const override
Returns the vector representation of the colorized quantity for idx-th particle.
virtual Rgba evalColor(const Size idx) const override
Returns the color of idx-th particle.
virtual std::string name() const override
Returns the name of the colorizer.
virtual void initialize(const Storage &storage, const RefEnum UNUSED(ref)) override
virtual bool isInitialized() const override
Checks if the colorizer has been initialized.
GravityColorizer(const SharedPtr< IScheduler > &scheduler, const Palette &palette, const Float G, const bool addSurfaceGravity)
INLINE TValue get(const GuiSettingsId id) const
INLINE GuiSettings & set(const GuiSettingsId id, const TValue &value)
virtual Pixel getSize() const =0
Returns the current resolution of the camera.
virtual AutoPtr< ICamera > clone() const =0
virtual void resize(const Pixel newSize)=0
Changes the image size.
virtual void setPosition(const Vector &newPosition)=0
Moves the camera to new position in world space.
virtual void initialize(const Storage &storage, const RefEnum ref)=0
Initialize the colorizer before by getting necessary quantities from storage.
virtual bool isInitialized() const =0
Checks if the colorizer has been initialized.
UnorderedMap< std::string, JobContext > inputs
Contains all input data, identified by names of input slots.
Base class for jobs providing no data.
virtual void initialize(const Storage &storage, const IColorizer &colorizer, const ICamera &camera)=0
Prepares the objects for rendering and updates its data.
virtual void render(const RenderParams ¶ms, Statistics &stats, IRenderOutput &output) const =0
Draws particles into the bitmap, given the data provided in initialize.
virtual void cancelRender()=0
Stops the rendering if it is currently in progress.
virtual bool isInitialized() const =0
Checks if the renderer has been initialized.
Callbacks executed by the simulation to provide feedback to the user.
virtual bool shouldAbortRun() const =0
Returns whether current run should be aborted or not.
virtual void onSetUp(const Storage &storage, Statistics &stats)=0
Called right before the run starts, i.e. after initial conditions are set up.
virtual void onTimeStep(const Storage &storage, Statistics &stats)=0
Called every timestep.
Helper object for storing three (possibly four) int or bool values.
Thrown when components of the run are mutually incompatible.
INLINE Float value(const Vector &r, const Float h) const noexcept
Object managing periodic rendering of images and saving them to given paths.
void save(const Storage &storage, Statistics &stats)
Manually saves the images.
void setCamera(AutoPtr< ICamera > &&camera)
Wrapper of type value of which may or may not be present.
INLINE Type & value()
Returns the reference to the stored value.
static Optional< Size > getDumpIdx(const Path &path)
Extracts the dump index from given path generated by OutputFile.
Represents a color palette, used for mapping arbitrary number to a color.
Object representing a path on a filesystem.
Path & replaceExtension(const std::string &newExtension)
Changes the extension of the file.
std::string native() const
Returns the native version of the path.
bool getPalette(const std::string &name, Palette &palette) const
GuiSettings & getGuiSettings()
static Project & getInstance()
virtual void update(RenderParams &&newParams) override
virtual void update(AutoPtr< IRenderer > &&newRenderer) override
virtual void render(const Pixel resolution, IRenderOutput &output) override
virtual void update(AutoPtr< IColorizer > &&newColorizer) override
virtual void cancel() override
virtual void update(AutoPtr< ICamera > &&newCamera) override
RenderPreview(RenderParams &¶ms, AutoPtr< IRenderer > &&renderer, AutoPtr< IColorizer > &&colorizer, const SharedPtr< ParticleData > &data)
void addEntries(const Settings &settings)
Adds entries from different Settings object into this one, overriding current entries.
Object holding various statistics about current run.
Statistics & set(const StatisticsId idx, TValue &&value)
Sets new values of a statistic.
Container storing all quantities used within the simulations.
MaterialView getMaterialOfParticle(const Size particleIdx) const
Returns material view for material of given particle.
Size getParticleCnt() const
Returns the number of particles.
Array< TValue > & getValue(const QuantityId key)
Retrieves a quantity values from the storage, given its key and value type.
Basic time-measuring tool. Starts automatically when constructed.
int64_t elapsed(const TimerUnit unit) const
Returns elapsed time in timer units. Does not reset the timer.
Heterogeneous container capable of storing a fixed number of values.
Default colorizer simply converting quantity value to color using defined palette.
INLINE bool contains(const TKey &key) const
Returns true if the map contains element of given key.
virtual void evaluate(const RunSettings &global, IRunCallbacks &UNUSED(callbacks)) override
virtual VirtualSettings getSettings() override
Returns a settings object which allows to query and modify the state of the job.
EntryControl & connect(const std::string &name, const std::string &key, TValue &value)
Connects to given reference.
Holds a map of virtual entries, associated with a unique name.
Category & addCategory(const std::string &name)
Creates a new category of entries.
Creating code components based on values from settings.
@ DENSITY
Density at zero pressure.
@ COLORMAP_LOGARITHMIC_FACTOR
@ RAYTRACE_ITERATION_LIMIT
@ IMAGES_NAME
Mask of the image names, having d where the output number will be placed.
@ PARTICLE_RADIUS
Displayed radius of particle in units of smoothing length.
@ SURFACE_RESOLUTION
Size of the grid used in MarchingCubes (in code units, not h).
@ IMAGES_PATH
Path of directory where the rendered images will be saved.
@ RENDERER
Selected renderer.
@ SURFACE_LEVEL
Value of iso-surface being constructed; lower value means larget bodies.
@ SURFACE_SUN_INTENSITY
Intentity of the sun.
@ IMAGES_SAVE
If true, rendered images are saved to disk.
@ SURFACE_SUN_POSITION
Direction to the sun used for shading.
@ SURFACE_AMBIENT
Ambient color for surface renderer.
@ PARTICLE
2D section showing particles as points
@ MESH
Surfaces of bodies are meshed using Marching cubes and drawed as triangles.
@ RAYMARCHER
Raymarcher that computes intersections with implicit surface.
@ VOLUME
Volumetric renderer.
constexpr Float gravity
Gravitational constant (CODATA 2014)
AutoPtr< IColorizer > getColorizer(const Project &project, const ExtColorizerId id)
Palette getPalette(const ExtColorizerId id)
AutoPtr< IRenderer > getRenderer(const GuiSettings &settings)
SharedPtr< IScheduler > getScheduler(const RunSettings &settings=RunSettings::getDefaults())
AutoPtr< IInput > getInput(const Path &path)
Vector position(const Float a, const Float e, const Float u)
Computes the position on the elliptic trajectory.
Overload of std::swap for Sph::Array.
AutoPtr< ITracker > tracker
AutoPtr< ICamera > camera
Helper class, allowing to register job into the global list of jobs.
Storage storage
Holds all particle positions and other quantities.
Statistics stats
Final statistics of the simulation.
Helper class for adding individual enums to the enum map.
Parameters of the rendered image.
Rgba background
Background color of the rendered image.
AutoPtr< ICamera > camera
Camera used for rendering.
bool showKey
If true, a color palette and a distance scale is included in the image.
AutoPtr< ITracker > tracker
Tracker used for camera motion.
void initialize(const GuiSettings &gui)
Sets up parameters using values stored in settings.