SPH
RenderJobs.cpp
Go to the documentation of this file.
2 #include "gravity/BarnesHut.h"
3 #include "gravity/Moments.h"
4 #include "gui/Factory.h"
5 #include "gui/Project.h"
6 #include "gui/objects/Camera.h"
8 #include "gui/objects/Movie.h"
9 #include "run/IRun.h"
10 #include "run/VirtualSettings.h"
11 #include "run/jobs/IoJobs.h"
12 #include "system/Factory.h"
13 #include "system/Timer.h"
14 
15 #ifdef SPH_USE_VDB
16 #include <openvdb/openvdb.h>
17 #endif
18 
19 
21 
22 //-----------------------------------------------------------------------------------------------------------
23 // AnimationJob
24 //-----------------------------------------------------------------------------------------------------------
25 
26 static RegisterEnum<AnimationType> sAnimation({
27  { AnimationType::SINGLE_FRAME, "single_frame", "Renders only single frame." },
28  { AnimationType::ORBIT, "orbit", "Make animation by orbiting camera around specified center point." },
29  { AnimationType::FILE_SEQUENCE, "file_sequence", "Make animation from saved files." },
30 });
31 
32 static RegisterEnum<ColorizerFlag> sColorizers({
33  { ColorizerFlag::VELOCITY, "velocity", "Particle velocities" },
34  { ColorizerFlag::ENERGY, "energy", "Specific internal energy" },
35  { ColorizerFlag::BOUND_COMPONENT_ID, "bound components", "Components" },
36  { ColorizerFlag::MASS, "clay", "Clay" },
37  { ColorizerFlag::BEAUTY, "beauty", "Beauty" },
38  { ColorizerFlag::GRAVITY, "gravity", "Gravity" },
39  { ColorizerFlag::DAMAGE, "damage", "Damage" },
40 });
41 
42 AnimationJob::AnimationJob(const std::string& name)
43  : INullJob(name) {
46 }
47 
49  VirtualSettings connector;
50  addGenericCategory(connector, instName);
51 
52  VirtualSettings::Category& outputCat = connector.addCategory("Output");
53  outputCat.connect<Path>("Directory", gui, GuiSettingsId::IMAGES_PATH)
55  outputCat.connect<std::string>("File mask", gui, GuiSettingsId::IMAGES_NAME);
56 
57  auto particleEnabler = [this] {
59  };
60  auto raymarcherEnabler = [this] {
62  };
63  auto surfaceEnabler = [this] {
64  const RendererEnum type = gui.get<RendererEnum>(GuiSettingsId::RENDERER);
65  return type == RendererEnum::RAYMARCHER || type == RendererEnum::MESH;
66  };
67  auto volumeEnabler = [this] {
69  };
70 
71  VirtualSettings::Category& rendererCat = connector.addCategory("Rendering");
72  rendererCat.connect<EnumWrapper>("Renderer", gui, GuiSettingsId::RENDERER);
73  rendererCat.connect("Quantities", "quantities", colorizers);
74  rendererCat.connect("Include surface gravity", "surface_gravity", addSurfaceGravity)
75  .setEnabler([this] { return colorizers.has(ColorizerFlag::GRAVITY); })
76  .setTooltip("Include the surface gravity of the particle itself.");
77  rendererCat.connect<bool>("Transparent background", "transparent", transparentBackground);
78  rendererCat.connect<EnumWrapper>("Color mapping", gui, GuiSettingsId::COLORMAP_TYPE);
79  rendererCat.connect<Float>("Logarithmic factor", gui, GuiSettingsId::COLORMAP_LOGARITHMIC_FACTOR)
80  .setEnabler(
82  rendererCat.connect<Float>("Particle radius", gui, GuiSettingsId::PARTICLE_RADIUS)
83  .setEnabler(particleEnabler);
84  rendererCat.connect<bool>("Antialiasing", gui, GuiSettingsId::ANTIALIASED).setEnabler(particleEnabler);
85  rendererCat.connect<bool>("Show key", gui, GuiSettingsId::SHOW_KEY).setEnabler(particleEnabler);
86  rendererCat.connect<int>("Interation count", gui, GuiSettingsId::RAYTRACE_ITERATION_LIMIT)
87  .setEnabler([&] {
88  const RendererEnum type = gui.get<RendererEnum>(GuiSettingsId::RENDERER);
89  return type == RendererEnum::RAYMARCHER || type == RendererEnum::VOLUME;
90  });
91  rendererCat.connect<Float>("Surface level", gui, GuiSettingsId::SURFACE_LEVEL).setEnabler(surfaceEnabler);
92  rendererCat.connect<Vector>("Sun position", gui, GuiSettingsId::SURFACE_SUN_POSITION)
93  .setEnabler(surfaceEnabler);
94  rendererCat.connect<Float>("Sunlight intensity", gui, GuiSettingsId::SURFACE_SUN_INTENSITY)
95  .setEnabler(surfaceEnabler);
96  rendererCat.connect<Float>("Ambient intensity", gui, GuiSettingsId::SURFACE_AMBIENT)
97  .setEnabler(surfaceEnabler);
98  rendererCat.connect<Float>("Surface emission", gui, GuiSettingsId::SURFACE_EMISSION)
99  .setEnabler(raymarcherEnabler);
100  rendererCat.connect<EnumWrapper>("BRDF", gui, GuiSettingsId::RAYTRACE_BRDF).setEnabler(raymarcherEnabler);
101  rendererCat.connect<bool>("Render as spheres", gui, GuiSettingsId::RAYTRACE_SPHERES)
102  .setEnabler(raymarcherEnabler);
103  rendererCat.connect<bool>("Enable shadows", gui, GuiSettingsId::RAYTRACE_SHADOWS)
104  .setEnabler(raymarcherEnabler);
105  rendererCat.connect<Float>("Medium emission [km^-1]", gui, GuiSettingsId::VOLUME_EMISSION)
106  .setUnits(1.e-3_f)
107  .setEnabler(volumeEnabler);
108  rendererCat.connect<Float>("Medium absorption [km^-1]", gui, GuiSettingsId::VOLUME_ABSORPTION)
109  .setUnits(1.e-3_f)
110  .setEnabler(volumeEnabler);
111  rendererCat.connect<Float>("Cell size", gui, GuiSettingsId::SURFACE_RESOLUTION).setEnabler([this] {
113  });
114 
115  VirtualSettings::Category& textureCat = connector.addCategory("Texture paths");
116  textureCat.connect<Path>("Background", gui, GuiSettingsId::RAYTRACE_HDRI)
117  .setEnabler([this] {
119  return id == RendererEnum::VOLUME || id == RendererEnum::RAYMARCHER;
120  })
122 
123  auto orbitEnabler = [this] { return AnimationType(animationType) == AnimationType::ORBIT; };
124 
125  VirtualSettings::Category& animationCat = connector.addCategory("Animation");
126  animationCat.connect<EnumWrapper>("Animation type", "animation_type", animationType);
127  animationCat.connect<Float>("Angular step", "step", orbit.step)
128  .setUnits(DEG_TO_RAD)
129  .setEnabler(orbitEnabler);
130  animationCat.connect<Float>("Final angle", "final_angle", orbit.finalAngle)
131  .setUnits(DEG_TO_RAD)
132  .setEnabler(orbitEnabler);
133  animationCat.connect<Path>("First file", "first_file", sequence.firstFile)
135  .setFileFormats(getInputFormats())
136  .setEnabler([this] { return AnimationType(animationType) == AnimationType::FILE_SEQUENCE; });
137 
138  return connector;
139 }
140 
141 class GravityColorizer : public TypedColorizer<Float> {
142 private:
143  SharedPtr<IScheduler> scheduler;
144  BarnesHut gravity;
145  Array<Float> acc;
146  Float G;
147  bool addSurfaceGravity;
148 
149 public:
151  const Palette& palette,
152  const Float G,
153  const bool addSurfaceGravity)
155  , scheduler(scheduler)
156  , gravity(0.8_f, MultipoleOrder::OCTUPOLE, 25, 50, G)
157  , G(G)
158  , addSurfaceGravity(addSurfaceGravity) {}
159 
160  virtual void initialize(const Storage& storage, const RefEnum UNUSED(ref)) override {
161  acc.resize(storage.getParticleCnt());
162  acc.fill(0._f);
163 
164  // gravitation acceleration from other particles
165  gravity.build(*scheduler, storage);
166 
167  Array<Vector> dv(storage.getParticleCnt());
168  dv.fill(Vector(0._f));
169  Statistics stats;
170  gravity.evalAll(*scheduler, dv, stats);
171  for (Size i = 0; i < dv.size(); ++i) {
172  acc[i] = getLength(dv[i]);
173  }
174 
175  if (addSurfaceGravity) {
176  // add surface gravity of each particle
179  for (Size i = 0; i < r.size(); ++i) {
180  acc[i] += G * m[i] / sqr(r[i][H]);
181  }
182  }
183  }
184 
185  virtual bool isInitialized() const override {
186  return !acc.empty();
187  }
188 
189  virtual Rgba evalColor(const Size idx) const override {
190  return palette(acc[idx]);
191  }
192 
193  virtual Optional<Vector> evalVector(const Size UNUSED(idx)) const override {
194  return NOTHING;
195  }
196 
197  virtual std::string name() const override {
198  return "Gravity";
199  }
200 };
201 
202 static Array<AutoPtr<IColorizer>> getColorizers(const RunSettings& global,
203  const GuiSettings& gui,
204  const Flags<ColorizerFlag> colorizers,
205  const Float G,
206  const bool addSurfaceGravity) {
207  SharedPtr<IScheduler> scheduler = Factory::getScheduler(global);
208  Project project = Project::getInstance().clone();
209  project.getGuiSettings() = gui;
210  Array<AutoPtr<IColorizer>> colorizerArray;
211  if (colorizers.has(ColorizerFlag::VELOCITY)) {
212  colorizerArray.push(Factory::getColorizer(project, ColorizerId::VELOCITY));
213  }
214  if (colorizers.has(ColorizerFlag::ENERGY)) {
215  colorizerArray.push(Factory::getColorizer(project, QuantityId::ENERGY));
216  }
217  if (colorizers.has(ColorizerFlag::BOUND_COMPONENT_ID)) {
219  }
220  if (colorizers.has(ColorizerFlag::MASS)) {
221  colorizerArray.push(Factory::getColorizer(project, QuantityId::MASS));
222  }
223  if (colorizers.has(ColorizerFlag::BEAUTY)) {
224  colorizerArray.push(Factory::getColorizer(project, ColorizerId::BEAUTY));
225  }
226  if (colorizers.has(ColorizerFlag::GRAVITY)) {
227  Palette palette;
228  if (!project.getPalette("Acceleration", palette)) {
230  }
231  colorizerArray.push(makeAuto<GravityColorizer>(scheduler, palette, G, addSurfaceGravity));
232  }
233  if (colorizers.has(ColorizerFlag::DAMAGE)) {
234  colorizerArray.push(Factory::getColorizer(project, QuantityId::DAMAGE));
235  }
236  return colorizerArray;
237 }
238 
240  SharedPtr<CameraData> camera = getInput<CameraData>("camera");
241  RenderParams params;
242  params.camera = camera->camera->clone();
243  params.tracker = std::move(camera->tracker);
244  GuiSettings paramGui = gui;
245  paramGui.addEntries(camera->overrides);
246  params.initialize(paramGui);
247  return params;
248 }
249 
250 void AnimationJob::evaluate(const RunSettings& global, IRunCallbacks& callbacks) {
252  gui.set(GuiSettingsId::BACKGROUND_COLOR, Rgba(0.f, 0.f, 0.f, transparentBackground ? 0.f : 1.f));
254 
255  SharedPtr<IScheduler> scheduler = Factory::getScheduler(global);
256  AutoPtr<IRenderer> renderer = Factory::getRenderer(scheduler, gui);
257  RenderParams params = getRenderParams();
258  Array<AutoPtr<IColorizer>> colorizerArray =
259  getColorizers(global, gui, colorizers, Constants::gravity, addSurfaceGravity);
260 
261  if (AnimationType(animationType) == AnimationType::FILE_SEQUENCE) {
262  Optional<Size> firstIndex = OutputFile::getDumpIdx(sequence.firstFile);
263  if (firstIndex) {
264  gui.set(GuiSettingsId::IMAGES_FIRST_INDEX, int(firstIndex.value()));
265  }
266  }
267 
268  Movie movie(gui, std::move(renderer), std::move(colorizerArray), std::move(params));
269  Timer renderTimer;
270  switch (AnimationType(animationType)) {
272  SharedPtr<ParticleData> data = this->getInput<ParticleData>("particles");
273  movie.save(data->storage, data->stats);
274  break;
275  }
276  case AnimationType::ORBIT: {
277  SharedPtr<ParticleData> data = this->getInput<ParticleData>("particles");
278  const Vector target = gui.get<Vector>(GuiSettingsId::CAMERA_TARGET);
280  const Float orbitRadius = getLength(target - position);
281 
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) +
284  sin(phi) * Vector(1._f, 0._f, 0._f));
285  params.camera->setPosition(newPosition);
286  movie.setCamera(params.camera->clone());
287  movie.save(data->storage, data->stats);
288 
289  data->stats.set(StatisticsId::RELATIVE_PROGRESS, phi / orbit.finalAngle);
291  callbacks.onTimeStep(Storage{}, data->stats);
292 
293  if (callbacks.shouldAbortRun()) {
294  break;
295  }
296  }
297 
298  // reset the position
300  break;
301  }
303  FlatMap<Size, Path> fileMap = getFileSequence(sequence.firstFile);
304  if (fileMap.empty()) {
305  throw InvalidSetup("No files to render.");
306  }
307  const Size firstKey = fileMap.begin()->key;
308 
309  AutoPtr<IInput> input = Factory::getInput(sequence.firstFile);
310  for (auto& element : fileMap) {
311  Storage storage;
312  Statistics stats;
313  const Outcome result = input->load(element.value, storage, stats);
314  if (!result) {
316  }
317 
318  stats.set(StatisticsId::RELATIVE_PROGRESS, Float(element.key - firstKey) / fileMap.size());
320  if (element.key == firstKey) {
321  callbacks.onSetUp(storage, stats);
322  }
323  callbacks.onTimeStep(storage, stats);
324 
325  if (callbacks.shouldAbortRun()) {
326  break;
327  }
328 
329  movie.save(storage, stats);
330  }
331  break;
332  }
333  default:
335  }
336 }
337 
339 private:
340  RenderParams params;
341  AutoPtr<IRenderer> renderer;
342  AutoPtr<IColorizer> colorizer;
344  std::atomic_bool cancelled;
345 
346 public:
348  AutoPtr<IRenderer>&& renderer,
349  AutoPtr<IColorizer>&& colorizer,
350  const SharedPtr<ParticleData>& data)
351  : params(std::move(params))
352  , renderer(std::move(renderer))
353  , colorizer(std::move(colorizer))
354  , data(data)
355  , cancelled(false) {}
356 
357  virtual void render(const Pixel resolution, IRenderOutput& output) override {
358  cancelled = false;
359 
360  // lazy init
361  if (!colorizer->isInitialized()) {
362  colorizer->initialize(data->storage, RefEnum::WEAK);
363  }
364  if (cancelled) {
365  return;
366  }
367  if (!renderer->isInitialized()) {
368  renderer->initialize(data->storage, *colorizer, *params.camera);
369  }
370  if (cancelled) {
371  return;
372  }
373 
374  Pixel size = params.camera->getSize();
375  size = correctAspectRatio(resolution, float(size.x) / float(size.y));
376  params.camera->resize(size);
377  Statistics dummy;
378  renderer->render(params, dummy, output);
379  }
380 
381  virtual void update(RenderParams&& newParams) override {
382  AutoPtr<ICamera> camera = std::move(params.camera);
383  params = std::move(newParams);
384  params.camera = std::move(camera);
385  }
386 
387  virtual void update(AutoPtr<ICamera>&& newCamera) override {
388  params.camera = std::move(newCamera);
389  }
390 
391  virtual void update(AutoPtr<IColorizer>&& newColorizer) override {
392  colorizer = std::move(newColorizer);
393  }
394 
395  virtual void update(AutoPtr<IRenderer>&& newRenderer) override {
396  renderer = std::move(newRenderer);
397  }
398 
399  virtual void cancel() override {
400  cancelled = true;
401  renderer->cancelRender();
402  }
403 
404 private:
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);
409  } else {
410  return Pixel(resolution.x, resolution.y * current / aspect);
411  }
412  }
413 };
414 
416  if (AnimationType(animationType) != AnimationType::SINGLE_FRAME) {
417  throw InvalidSetup("Only enabled for single-frame renders");
418  }
419 
420  if (!inputs.contains("particles")) {
421  throw InvalidSetup("Paritcles not connected");
422  }
423 
424  SharedPtr<ParticleData> data = this->getInput<ParticleData>("particles");
425  /*Float G = Constants::gravity;
426  if (data->overrides.has(RunSettingsId::GRAVITY_CONSTANT)) {
427  G = data->overrides.get<Float>(RunSettingsId::GRAVITY_CONSTANT);
428  }*/
429 
430  RenderParams params = this->getRenderParams();
431  params.background = Rgba(0.f, 0.f, 0.f, transparentBackground ? 0.f : 1.f);
432  params.showKey = false;
433 
434  AutoPtr<IColorizer> colorizer = this->getColorizer(global);
435  if (!colorizer) {
436  throw InvalidSetup("No quantity selected");
437  }
438  AutoPtr<IRenderer> renderer = this->getRenderer(global);
439 
440  return makeAuto<RenderPreview>(std::move(params), std::move(renderer), std::move(colorizer), data);
441 }
442 
446  Array<AutoPtr<IColorizer>> colorizer = getColorizers(global, gui, colorizers, G, addSurfaceGravity);
447  if (!colorizer.empty()) {
448  return std::move(colorizer.front());
449  } else {
450  return nullptr;
451  }
452 }
453 
455  SharedPtr<IScheduler> scheduler = Factory::getScheduler(global);
456  GuiSettings previewGui = gui;
458  AutoPtr<IRenderer> renderer = Factory::getRenderer(scheduler, previewGui);
459  return renderer;
460 }
461 
463  "render animation",
464  "animation",
465  "rendering",
466  [](const std::string& name) { return makeAuto<AnimationJob>(name); },
467  "Renders an image or a sequence of images from given particle input(s)");
468 
469 //-----------------------------------------------------------------------------------------------------------
470 // VdbJob
471 //-----------------------------------------------------------------------------------------------------------
472 
473 #ifdef SPH_USE_VDB
474 
475 
476 INLINE openvdb::Vec3R vectorToVec3R(const Vector& v) {
477  return openvdb::Vec3R(v[X], v[Y], v[Z]);
478 }
479 
480 INLINE Vector worldToRelative(const Vector& r, const Box& box, const Indices& dims) {
481  return (r - box.lower()) / box.size() * Vector(dims);
482 }
483 
484 INLINE Vector relativeToWorld(const Vector& r, const Box& box, const Indices& dims) {
485  return r * box.size() / Vector(dims) + box.lower();
486 }
487 
488 Tuple<Indices, Indices> getParticleBox(const Vector& r, const Box& box, const Indices& dims) {
489  const Vector from = worldToRelative(r - Vector(2._f * r[H]), box, dims);
490  const Vector to = worldToRelative(r + Vector(2._f * r[H]), box, dims);
491  const Indices fromIdxs(ceil(from[X]), ceil(from[Y]), ceil(from[Z]));
492  const Indices toIdxs(floor(to[X]), floor(to[Y]), floor(to[Z]));
493  return { max(fromIdxs, Indices(0._f)), min(toIdxs, dims - Indices(1)) };
494 }
495 
497  VirtualSettings connector;
498  addGenericCategory(connector, instName);
499 
500  VirtualSettings::Category& gridCat = connector.addCategory("Grid parameters");
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);
505 
506  VirtualSettings::Category& inputCat = connector.addCategory("Input files");
507  inputCat.connect("Enable", "enable_sequence", sequence.enabled);
508  inputCat.connect("First file", "first_file", sequence.firstFile)
511  .setEnabler([this] { return sequence.enabled; });
512 
513  VirtualSettings::Category& outputCat = connector.addCategory("Output");
514  outputCat.connect("VDB File", "file", path)
516  .setFileFormats({ { "OpenVDB grid file", "vdb" } })
517  .setEnabler([this] { return !sequence.enabled; });
518 
519  return connector;
520 }
521 
522 void VdbJob::evaluate(const RunSettings& global, IRunCallbacks& callbacks) {
523  openvdb::initialize();
524  auto deinit = finally([] { openvdb::uninitialize(); });
525 
526  if (sequence.enabled) {
527  FlatMap<Size, Path> fileMap = getFileSequence(sequence.firstFile);
528  if (fileMap.empty()) {
529  throw InvalidSetup("No files to render.");
530  }
531  const Size firstKey = fileMap.begin()->key;
532 
533  AutoPtr<IInput> input = Factory::getInput(sequence.firstFile);
534  for (auto& element : fileMap) {
535  Storage storage;
536  Statistics stats;
537  const Outcome result = input->load(element.value, storage, stats);
538  if (!result) {
540  }
541 
542  Path outputPath = element.value;
543  outputPath.replaceExtension("vdb");
544  this->generate(storage, global, outputPath);
545 
547  stats.set(StatisticsId::RELATIVE_PROGRESS, Float(element.key - firstKey) / fileMap.size());
548  if (element.key == firstKey) {
549  callbacks.onSetUp(storage, stats);
550  }
551  callbacks.onTimeStep(storage, stats);
552 
553  if (callbacks.shouldAbortRun()) {
554  break;
555  }
556  }
557  } else {
558  Storage& storage = getInput<ParticleData>("particles")->storage;
559  this->generate(storage, global, path);
560  }
561 }
562 
563 void VdbJob::generate(Storage& storage, const RunSettings& global, const Path& outputPath) {
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);
567 
568  colorField->setName("Density");
569  velocityField->setName("Velocity");
570  energyField->setName("Emission");
571 
573  // ArrayView<const Vector> v = storage.getDt<Vector>(QuantityId::POSITION);
576 
577 
578  const Box box(gridStart, gridEnd);
579  const Size gridSize = 1 << dimPower;
580  const Indices gridIdxs(gridSize);
581 
582  LutKernel<3> kernel = Factory::getKernel<3>(global);
583 
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) {
588  Indices from, to;
589  tieToTuple(from, to) = getParticleBox(r[i], box, gridIdxs);
590  const Float rho = storage.getMaterialOfParticle(i)->getParam<Float>(BodySettingsId::DENSITY);
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) {
594  const Indices idxs(x, y, z);
595  const Vector pos = relativeToWorld(idxs, box, gridIdxs);
596  const Float w = kernel.value(r[i] - pos, r[i][H]);
597  const Float p = m[i] / rho;
598 
599 
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]; });
604  /*velocityAccessor.modifyValue(coord,
605  [p, w, &v, i](openvdb::Vec3R& velocity) { velocity += vectorToVec3R(p * w * v[i]);
606  });*/
607  }
608  }
609  }
610  }
611 
612  openvdb::GridPtrVec vdbGrids;
613  vdbGrids.push_back(colorField);
614  // vdbGrids.push_back(velocityField);
615  vdbGrids.push_back(energyField);
616 
617  Path vdbPath = outputPath;
618  vdbPath.replaceExtension("vdb");
619  openvdb::io::File vdbFile(vdbPath.native());
620  vdbFile.write(vdbGrids);
621  vdbFile.close();
622 }
623 
624 JobRegistrar sRegisterVdb(
625  "save VDB grid",
626  "grid",
627  "rendering",
628  [](const std::string& name) { return makeAuto<VdbJob>(name); },
629  "Converts the particle data into a volumetric grid in OpenVDB format.");
630 
631 #endif
632 
RefEnum
Definition: ArrayRef.h:7
#define NOT_IMPLEMENTED
Helper macro marking missing implementation.
Definition: Assert.h:100
NAMESPACE_SPH_BEGIN
Definition: BarnesHut.cpp:13
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).
Definition: Globals.h:16
double Float
Precision used withing the code. Use Float instead of float or double where precision is important.
Definition: Globals.h:13
Basic interface defining a single run.
FlatMap< Size, Path > getFileSequence(const Path &firstFile)
Definition: IoJobs.cpp:107
VirtualSettings::Category & addGenericCategory(VirtualSettings &connector, std::string &instanceName)
Adds a common settings category, used by all jobs.
Definition: Job.cpp:43
constexpr INLINE T max(const T &f1, const T &f2)
Definition: MathBasic.h:20
NAMESPACE_SPH_BEGIN constexpr INLINE T min(const T &f1, const T &f2)
Minimum & Maximum value.
Definition: MathBasic.h:15
constexpr INLINE T sqr(const T &f) noexcept
Return a squared value.
Definition: MathUtils.h:67
INLINE T sin(const T f)
Definition: MathUtils.h:296
INLINE auto floor(const T &f)
Definition: MathUtils.h:346
INLINE T cos(const T f)
Definition: MathUtils.h:291
constexpr Float DEG_TO_RAD
Definition: MathUtils.h:369
INLINE auto ceil(const T &f)
Definition: MathUtils.h:351
MultipoleOrder
Definition: Moments.h:309
Periodically saves rendered images to disk.
#define INLINE
Macros for conditional compilation based on selected compiler.
Definition: Object.h:31
#define UNUSED(x)
Definition: Object.h:37
#define NAMESPACE_SPH_END
Definition: Object.h:12
const NothingType NOTHING
Definition: Optional.h:16
@ POSITION
Positions of particles, always a vector quantity.
QuantityId
Unique IDs of basic quantities of SPH particles.
Definition: QuantityIds.h:19
@ DAMAGE
Damage.
@ 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)")
AnimationType
Definition: RenderJobs.h:24
Tuple< Indices, Indices > getParticleBox(const Vector &r, const VdbParams &params)
Definition: SsfToVdb.cpp:47
Vector worldToRelative(const Vector &r, const VdbParams &params)
Definition: SsfToVdb.cpp:39
INLINE openvdb::Vec3R vectorToVec3R(const Vector &v)
Definition: SsfToVdb.cpp:26
Vector relativeToWorld(const Vector &r, const VdbParams &params)
Definition: SsfToVdb.cpp:43
@ 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.
Definition: Tuple.h:304
INLINE Float getLength(const Vector &v)
Returns the length of the vector. Enabled only for vectors of floating-point precision.
Definition: Vector.h:579
BasicVector< Float > Vector
Definition: Vector.h:539
@ H
Definition: Vector.h:25
@ Y
Definition: Vector.h:23
@ X
Definition: Vector.h:22
@ Z
Definition: Vector.h:24
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
Definition: RenderJobs.cpp:250
AutoPtr< IRenderPreview > getRenderPreview(const RunSettings &global) const
Definition: RenderJobs.cpp:415
AnimationJob(const std::string &name)
Definition: RenderJobs.cpp:42
AutoPtr< IRenderer > getRenderer(const RunSettings &global) const
Definition: RenderJobs.cpp:454
AutoPtr< IColorizer > getColorizer(const RunSettings &global) const
Definition: RenderJobs.cpp:443
virtual VirtualSettings getSettings() override
Returns a settings object which allows to query and modify the state of the job.
Definition: RenderJobs.cpp:48
RenderParams getRenderParams() const
Definition: RenderJobs.cpp:239
INLINE TCounter size() const
Definition: ArrayView.h:101
void resize(const TCounter newSize)
Resizes the array to new size.
Definition: Array.h:215
INLINE void push(U &&u)
Adds new element to the end of the array, resizing the array if necessary.
Definition: Array.h:306
void fill(const T &t)
Sets all elements of the array to given value.
Definition: Array.h:187
INLINE TCounter size() const noexcept
Definition: Array.h:193
INLINE T & front() noexcept
Definition: Array.h:166
INLINE bool empty() const noexcept
Definition: Array.h:201
Multipole approximation of distance particle.
Definition: BarnesHut.h:43
Helper object defining three-dimensional interval (box).
Definition: Box.h:17
INLINE const Vector & lower() const
Returns lower bounds of the box.
Definition: Box.h:82
INLINE Vector size() const
Returns box dimensions.
Definition: Box.h:106
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.
Definition: Flags.h:77
Container of key-value pairs.
Definition: FlatMap.h:19
INLINE Size empty() const
Returns true if the map contains no elements, false otherwise.
Definition: FlatMap.h:150
INLINE Iterator< Element > begin()
Returns the iterator pointing to the first element.
Definition: FlatMap.h:155
INLINE Size size() const
Returns the number of elements in the map.
Definition: FlatMap.h:145
virtual Optional< Vector > evalVector(const Size UNUSED(idx)) const override
Returns the vector representation of the colorized quantity for idx-th particle.
Definition: RenderJobs.cpp:193
virtual Rgba evalColor(const Size idx) const override
Returns the color of idx-th particle.
Definition: RenderJobs.cpp:189
virtual std::string name() const override
Returns the name of the colorizer.
Definition: RenderJobs.cpp:197
virtual void initialize(const Storage &storage, const RefEnum UNUSED(ref)) override
Definition: RenderJobs.cpp:160
virtual bool isInitialized() const override
Checks if the colorizer has been initialized.
Definition: RenderJobs.cpp:185
GravityColorizer(const SharedPtr< IScheduler > &scheduler, const Palette &palette, const Float G, const bool addSurfaceGravity)
Definition: RenderJobs.cpp:150
INLINE TValue get(const GuiSettingsId id) const
Definition: Settings.h:245
INLINE GuiSettings & set(const GuiSettingsId id, const TValue &value)
Definition: Settings.h:250
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.
std::string instName
Definition: Job.h:100
UnorderedMap< std::string, JobContext > inputs
Contains all input data, identified by names of input slots.
Definition: Job.h:103
Base class for jobs providing no data.
Definition: Job.h:322
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 &params, 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.
Definition: IRun.h:27
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.
Definition: Indices.h:16
Thrown when components of the run are mutually incompatible.
Definition: Exceptions.h:24
INLINE Float value(const Vector &r, const Float h) const noexcept
Definition: Kernel.h:26
Object managing periodic rendering of images and saving them to given paths.
Definition: Movie.h:22
void save(const Storage &storage, Statistics &stats)
Manually saves the images.
Definition: Movie.cpp:112
void setCamera(AutoPtr< ICamera > &&camera)
Definition: Movie.cpp:157
Wrapper of type value of which may or may not be present.
Definition: Optional.h:23
INLINE Type & value()
Returns the reference to the stored value.
Definition: Optional.h:172
static Optional< Size > getDumpIdx(const Path &path)
Extracts the dump index from given path generated by OutputFile.
Definition: Output.cpp:49
Represents a color palette, used for mapping arbitrary number to a color.
Definition: Palette.h:25
Object representing a path on a filesystem.
Definition: Path.h:17
Path & replaceExtension(const std::string &newExtension)
Changes the extension of the file.
Definition: Path.cpp:76
std::string native() const
Returns the native version of the path.
Definition: Path.cpp:71
Project clone() const
Definition: Project.h:30
bool getPalette(const std::string &name, Palette &palette) const
Definition: Project.h:41
GuiSettings & getGuiSettings()
Definition: Project.h:51
static Project & getInstance()
Definition: Project.h:25
virtual void update(RenderParams &&newParams) override
Definition: RenderJobs.cpp:381
virtual void update(AutoPtr< IRenderer > &&newRenderer) override
Definition: RenderJobs.cpp:395
virtual void render(const Pixel resolution, IRenderOutput &output) override
Definition: RenderJobs.cpp:357
virtual void update(AutoPtr< IColorizer > &&newColorizer) override
Definition: RenderJobs.cpp:391
virtual void cancel() override
Definition: RenderJobs.cpp:399
virtual void update(AutoPtr< ICamera > &&newCamera) override
Definition: RenderJobs.cpp:387
RenderPreview(RenderParams &&params, AutoPtr< IRenderer > &&renderer, AutoPtr< IColorizer > &&colorizer, const SharedPtr< ParticleData > &data)
Definition: RenderJobs.cpp:347
Definition: Color.h:8
void addEntries(const Settings &settings)
Adds entries from different Settings object into this one, overriding current entries.
Definition: Settings.h:297
Object holding various statistics about current run.
Definition: Statistics.h:22
Statistics & set(const StatisticsId idx, TValue &&value)
Sets new values of a statistic.
Definition: Statistics.h:52
Container storing all quantities used within the simulations.
Definition: Storage.h:230
MaterialView getMaterialOfParticle(const Size particleIdx) const
Returns material view for material of given particle.
Definition: Storage.cpp:372
Size getParticleCnt() const
Returns the number of particles.
Definition: Storage.cpp:445
Array< TValue > & getValue(const QuantityId key)
Retrieves a quantity values from the storage, given its key and value type.
Definition: Storage.cpp:191
Basic time-measuring tool. Starts automatically when constructed.
Definition: Timer.h:27
int64_t elapsed(const TimerUnit unit) const
Returns elapsed time in timer units. Does not reset the timer.
Definition: Timer.cpp:55
Heterogeneous container capable of storing a fixed number of values.
Definition: Tuple.h:146
Default colorizer simply converting quantity value to color using defined palette.
Definition: Colorizer.h:169
INLINE bool contains(const TKey &key) const
Returns true if the map contains element of given key.
Definition: UnorderedMap.h:126
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.
ColorMapEnum
Definition: Settings.h:85
RendererEnum
Definition: Settings.h:14
@ 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)
Definition: Constants.h:29
AutoPtr< IColorizer > getColorizer(const Project &project, const ExtColorizerId id)
Definition: Factory.cpp:198
Palette getPalette(const ExtColorizerId id)
Definition: Factory.cpp:261
AutoPtr< IRenderer > getRenderer(const GuiSettings &settings)
Definition: Factory.cpp:58
SharedPtr< IScheduler > getScheduler(const RunSettings &settings=RunSettings::getDefaults())
Definition: Factory.cpp:178
AutoPtr< IInput > getInput(const Path &path)
Definition: Factory.cpp:601
Vector position(const Float a, const Float e, const Float u)
Computes the position on the elliptic trajectory.
Definition: TwoBody.cpp:82
Overload of std::swap for Sph::Array.
Definition: Array.h:578
GuiSettings overrides
Definition: CameraJobs.h:19
AutoPtr< ITracker > tracker
Definition: CameraJobs.h:17
AutoPtr< ICamera > camera
Definition: CameraJobs.h:16
Wrapper of an enum.
Definition: Settings.h:37
Helper class, allowing to register job into the global list of jobs.
Definition: Job.h:203
Storage storage
Holds all particle positions and other quantities.
Definition: Job.h:35
Statistics stats
Final statistics of the simulation.
Definition: Job.h:38
Definition: Point.h:101
Helper class for adding individual enums to the enum map.
Definition: EnumMap.h:175
Parameters of the rendered image.
Definition: IRenderer.h:60
Rgba background
Background color of the rendered image.
Definition: IRenderer.h:71
AutoPtr< ICamera > camera
Camera used for rendering.
Definition: IRenderer.h:63
bool showKey
If true, a color palette and a distance scale is included in the image.
Definition: IRenderer.h:74
AutoPtr< ITracker > tracker
Tracker used for camera motion.
Definition: IRenderer.h:68
void initialize(const GuiSettings &gui)
Sets up parameters using values stored in settings.
Definition: IRenderer.cpp:11