Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/intern
diff options
context:
space:
mode:
authorSam Kottler <dev@samkottler.net>2020-08-13 17:58:33 +0300
committerSam Kottler <dev@samkottler.net>2020-08-13 17:58:33 +0300
commit7c38d008de5ebdcb96ebdd67b8dc459d5551702f (patch)
tree8fb22f60bc31019e3fe8f5b2bf35159c2e32cda9 /intern
parentcc86e03fd52cd68e66b817590aac80ec2a358d3e (diff)
parent4e103101f7a20eaa2a61306a1070a04b63a69958 (diff)
Merge branch 'blender-v2.90-release' into soc-2020-production-ready-light-tree-2
Diffstat (limited to 'intern')
-rw-r--r--intern/clog/clog.c29
-rw-r--r--intern/cycles/blender/blender_camera.cpp13
-rw-r--r--intern/cycles/blender/blender_session.cpp29
-rw-r--r--intern/cycles/blender/blender_shader.cpp4
-rw-r--r--intern/cycles/blender/blender_sync.cpp10
-rw-r--r--intern/cycles/blender/blender_util.h6
-rw-r--r--intern/cycles/blender/blender_volume.cpp75
-rw-r--r--intern/cycles/kernel/CMakeLists.txt4
-rw-r--r--intern/cycles/kernel/kernel_path.h2
-rw-r--r--intern/cycles/render/geometry.cpp10
-rw-r--r--intern/cycles/render/image.cpp37
-rw-r--r--intern/cycles/render/image.h7
-rw-r--r--intern/cycles/render/image_vdb.cpp12
-rw-r--r--intern/cycles/render/image_vdb.h6
-rw-r--r--intern/cycles/render/mesh_volume.cpp514
-rw-r--r--intern/cycles/render/session.cpp19
-rw-r--r--intern/cycles/test/CMakeLists.txt1
-rw-r--r--intern/cycles/test/util_transform_test.cpp53
-rw-r--r--intern/cycles/util/CMakeLists.txt1
-rw-r--r--intern/cycles/util/util_math_fast.h20
-rw-r--r--intern/cycles/util/util_math_float4.h18
-rw-r--r--intern/cycles/util/util_openvdb.h32
-rw-r--r--intern/cycles/util/util_transform.cpp28
-rw-r--r--intern/cycles/util/util_transform.h11
-rw-r--r--intern/ghost/GHOST_C-api.h5
-rw-r--r--intern/ghost/GHOST_IContext.h5
-rw-r--r--intern/ghost/GHOST_IEvent.h5
-rw-r--r--intern/ghost/GHOST_IEventConsumer.h5
-rw-r--r--intern/ghost/GHOST_ISystem.h5
-rw-r--r--intern/ghost/GHOST_ISystemPaths.h5
-rw-r--r--intern/ghost/GHOST_ITimerTask.h5
-rw-r--r--intern/ghost/GHOST_IWindow.h5
-rw-r--r--intern/ghost/GHOST_IXrContext.h5
-rw-r--r--intern/ghost/GHOST_Path-api.h5
-rw-r--r--intern/ghost/GHOST_Rect.h5
-rw-r--r--intern/ghost/GHOST_Types.h5
-rw-r--r--intern/ghost/intern/GHOST_Buttons.h5
-rw-r--r--intern/ghost/intern/GHOST_CallbackEventConsumer.h5
-rw-r--r--intern/ghost/intern/GHOST_Context.h5
-rw-r--r--intern/ghost/intern/GHOST_ContextCGL.h5
-rw-r--r--intern/ghost/intern/GHOST_ContextD3D.h5
-rw-r--r--intern/ghost/intern/GHOST_ContextEGL.h5
-rw-r--r--intern/ghost/intern/GHOST_ContextGLX.h5
-rw-r--r--intern/ghost/intern/GHOST_ContextNone.h5
-rw-r--r--intern/ghost/intern/GHOST_ContextSDL.h5
-rw-r--r--intern/ghost/intern/GHOST_ContextWGL.h5
-rw-r--r--intern/ghost/intern/GHOST_Debug.h5
-rw-r--r--intern/ghost/intern/GHOST_DisplayManager.h5
-rw-r--r--intern/ghost/intern/GHOST_DisplayManagerCocoa.h5
-rw-r--r--intern/ghost/intern/GHOST_DisplayManagerNULL.h5
-rw-r--r--intern/ghost/intern/GHOST_DisplayManagerSDL.h5
-rw-r--r--intern/ghost/intern/GHOST_DisplayManagerWin32.h5
-rw-r--r--intern/ghost/intern/GHOST_DisplayManagerX11.h5
-rw-r--r--intern/ghost/intern/GHOST_DropTargetWin32.h5
-rw-r--r--intern/ghost/intern/GHOST_DropTargetX11.h5
-rw-r--r--intern/ghost/intern/GHOST_Event.h5
-rw-r--r--intern/ghost/intern/GHOST_EventButton.h5
-rw-r--r--intern/ghost/intern/GHOST_EventCursor.h5
-rw-r--r--intern/ghost/intern/GHOST_EventDragnDrop.h5
-rw-r--r--intern/ghost/intern/GHOST_EventKey.h5
-rw-r--r--intern/ghost/intern/GHOST_EventManager.h5
-rw-r--r--intern/ghost/intern/GHOST_EventNDOF.h5
-rw-r--r--intern/ghost/intern/GHOST_EventPrinter.h5
-rw-r--r--intern/ghost/intern/GHOST_EventString.h5
-rw-r--r--intern/ghost/intern/GHOST_EventTrackpad.h5
-rw-r--r--intern/ghost/intern/GHOST_EventWheel.h5
-rw-r--r--intern/ghost/intern/GHOST_IXrGraphicsBinding.h5
-rw-r--r--intern/ghost/intern/GHOST_IconX11.h5
-rw-r--r--intern/ghost/intern/GHOST_ImeWin32.h4
-rw-r--r--intern/ghost/intern/GHOST_ModifierKeys.h5
-rw-r--r--intern/ghost/intern/GHOST_NDOFManager.h5
-rw-r--r--intern/ghost/intern/GHOST_NDOFManagerCocoa.h5
-rw-r--r--intern/ghost/intern/GHOST_NDOFManagerUnix.h5
-rw-r--r--intern/ghost/intern/GHOST_NDOFManagerWin32.h5
-rw-r--r--intern/ghost/intern/GHOST_System.h5
-rw-r--r--intern/ghost/intern/GHOST_SystemCocoa.h5
-rw-r--r--intern/ghost/intern/GHOST_SystemNULL.h5
-rw-r--r--intern/ghost/intern/GHOST_SystemPaths.h5
-rw-r--r--intern/ghost/intern/GHOST_SystemPathsCocoa.h5
-rw-r--r--intern/ghost/intern/GHOST_SystemPathsUnix.h5
-rw-r--r--intern/ghost/intern/GHOST_SystemPathsWin32.h5
-rw-r--r--intern/ghost/intern/GHOST_SystemSDL.h5
-rw-r--r--intern/ghost/intern/GHOST_SystemWayland.h5
-rw-r--r--intern/ghost/intern/GHOST_SystemWin32.cpp8
-rw-r--r--intern/ghost/intern/GHOST_SystemWin32.h4
-rw-r--r--intern/ghost/intern/GHOST_SystemX11.h5
-rw-r--r--intern/ghost/intern/GHOST_TaskbarWin32.h5
-rw-r--r--intern/ghost/intern/GHOST_TaskbarX11.h5
-rw-r--r--intern/ghost/intern/GHOST_TimerManager.h5
-rw-r--r--intern/ghost/intern/GHOST_TimerTask.h5
-rw-r--r--intern/ghost/intern/GHOST_Window.h5
-rw-r--r--intern/ghost/intern/GHOST_WindowCocoa.h5
-rw-r--r--intern/ghost/intern/GHOST_WindowManager.h5
-rw-r--r--intern/ghost/intern/GHOST_WindowNULL.h5
-rw-r--r--intern/ghost/intern/GHOST_WindowSDL.h5
-rw-r--r--intern/ghost/intern/GHOST_WindowWayland.h5
-rw-r--r--intern/ghost/intern/GHOST_WindowWin32.h5
-rw-r--r--intern/ghost/intern/GHOST_WindowX11.h5
-rw-r--r--intern/ghost/intern/GHOST_XrContext.h5
-rw-r--r--intern/ghost/intern/GHOST_XrException.h5
-rw-r--r--intern/ghost/intern/GHOST_XrSession.h5
-rw-r--r--intern/ghost/intern/GHOST_XrSwapchain.h5
-rw-r--r--intern/ghost/intern/GHOST_Xr_intern.h5
-rw-r--r--intern/ghost/intern/GHOST_Xr_openxr_includes.h5
-rw-r--r--intern/guardedalloc/CMakeLists.txt1
-rw-r--r--intern/guardedalloc/MEM_guardedalloc.h4
-rw-r--r--intern/guardedalloc/intern/leak_detector.cc61
-rw-r--r--intern/guardedalloc/intern/mallocn_guarded_impl.c4
-rw-r--r--intern/guardedalloc/intern/mallocn_inline.h8
-rw-r--r--intern/guardedalloc/intern/mallocn_intern.h11
-rw-r--r--intern/guardedalloc/intern/mallocn_lockfree_impl.c4
-rw-r--r--intern/itasc/Scene.cpp1079
-rw-r--r--intern/mantaflow/intern/MANTA_main.cpp15
-rw-r--r--intern/mantaflow/intern/strings/fluid_script.h15
-rw-r--r--intern/mantaflow/intern/strings/liquid_script.h6
-rw-r--r--intern/mantaflow/intern/strings/smoke_script.h2
-rw-r--r--intern/sky/source/sky_model.cpp12
117 files changed, 1379 insertions, 1185 deletions
diff --git a/intern/clog/clog.c b/intern/clog/clog.c
index 921ee17a672..d384b9a89e6 100644
--- a/intern/clog/clog.c
+++ b/intern/clog/clog.c
@@ -153,7 +153,6 @@ static void clg_str_reserve(CLogStringBuf *cstr, const uint len)
cstr->data = data;
cstr->is_alloc = true;
}
- cstr->len_alloc = len;
}
}
@@ -179,26 +178,34 @@ static void clg_str_vappendf(CLogStringBuf *cstr, const char *fmt, va_list args)
{
/* Use limit because windows may use '-1' for a formatting error. */
const uint len_max = 65535;
- uint len_avail = (cstr->len_alloc - cstr->len);
- if (len_avail == 0) {
- len_avail = CLOG_BUF_LEN_INIT;
- clg_str_reserve(cstr, len_avail);
- }
while (true) {
+ uint len_avail = cstr->len_alloc - cstr->len;
+
va_list args_cpy;
va_copy(args_cpy, args);
int retval = vsnprintf(cstr->data + cstr->len, len_avail, fmt, args_cpy);
va_end(args_cpy);
- if (retval != -1) {
- cstr->len += retval;
+
+ if (retval < 0) {
+ /* Some encoding error happened, not much we can do here, besides skipping/cancelling this
+ * message. */
+ break;
+ }
+ else if ((uint)retval <= len_avail) {
+ /* Copy was successful. */
+ cstr->len += (uint)retval;
break;
}
else {
- len_avail *= 2;
- if (len_avail >= len_max) {
+ /* vsnprintf was not successful, due to lack of allocated space, retval contains expected
+ * length of the formated string, use it to allocate required amount of memory. */
+ uint len_alloc = cstr->len + (uint)retval;
+ if (len_alloc >= len_max) {
+ /* Safe upper-limit, just in case... */
break;
}
- clg_str_reserve(cstr, len_avail);
+ clg_str_reserve(cstr, len_alloc);
+ len_avail = cstr->len_alloc - cstr->len;
}
}
}
diff --git a/intern/cycles/blender/blender_camera.cpp b/intern/cycles/blender/blender_camera.cpp
index 592a69585de..e1ab3b3fbc1 100644
--- a/intern/cycles/blender/blender_camera.cpp
+++ b/intern/cycles/blender/blender_camera.cpp
@@ -76,6 +76,9 @@ struct BlenderCamera {
int full_width;
int full_height;
+ int render_width;
+ int render_height;
+
BoundBox2D border;
BoundBox2D pano_viewplane;
BoundBox2D viewport_camera_border;
@@ -126,8 +129,10 @@ static void blender_camera_init(BlenderCamera *bcam, BL::RenderSettings &b_rende
bcam->matrix = transform_identity();
/* render resolution */
- bcam->full_width = render_resolution_x(b_render);
- bcam->full_height = render_resolution_y(b_render);
+ bcam->render_width = render_resolution_x(b_render);
+ bcam->render_height = render_resolution_y(b_render);
+ bcam->full_width = bcam->render_width;
+ bcam->full_height = bcam->render_height;
}
static float blender_camera_focal_distance(BL::RenderEngine &b_engine,
@@ -398,8 +403,8 @@ static void blender_camera_sync(Camera *cam,
/* panorama sensor */
if (bcam->type == CAMERA_PANORAMA && bcam->panorama_type == PANORAMA_FISHEYE_EQUISOLID) {
- float fit_xratio = (float)bcam->full_width * bcam->pixelaspect.x;
- float fit_yratio = (float)bcam->full_height * bcam->pixelaspect.y;
+ float fit_xratio = (float)bcam->render_width * bcam->pixelaspect.x;
+ float fit_yratio = (float)bcam->render_height * bcam->pixelaspect.y;
bool horizontal_fit;
float sensor_size;
diff --git a/intern/cycles/blender/blender_session.cpp b/intern/cycles/blender/blender_session.cpp
index 391a1b8f473..a06030c8b7d 100644
--- a/intern/cycles/blender/blender_session.cpp
+++ b/intern/cycles/blender/blender_session.cpp
@@ -59,6 +59,7 @@ BlenderSession::BlenderSession(BL::RenderEngine &b_engine,
BL::BlendData &b_data,
bool preview_osl)
: session(NULL),
+ scene(NULL),
sync(NULL),
b_engine(b_engine),
b_userpref(b_userpref),
@@ -88,6 +89,7 @@ BlenderSession::BlenderSession(BL::RenderEngine &b_engine,
int width,
int height)
: session(NULL),
+ scene(NULL),
sync(NULL),
b_engine(b_engine),
b_userpref(b_userpref),
@@ -492,27 +494,15 @@ void BlenderSession::render(BL::Depsgraph &b_depsgraph_)
/* Update denoising parameters. */
session->set_denoising(session_params.denoising);
- bool use_denoising = session_params.denoising.use;
- bool store_denoising_passes = session_params.denoising.store_passes;
-
- buffer_params.denoising_data_pass = use_denoising || store_denoising_passes;
- buffer_params.denoising_clean_pass = (scene->film->denoising_flags & DENOISING_CLEAN_ALL_PASSES);
- buffer_params.denoising_prefiltered_pass = store_denoising_passes &&
- session_params.denoising.type == DENOISER_NLM;
-
- scene->film->denoising_data_pass = buffer_params.denoising_data_pass;
- scene->film->denoising_clean_pass = buffer_params.denoising_clean_pass;
- scene->film->denoising_prefiltered_pass = buffer_params.denoising_prefiltered_pass;
-
- /* Add passes */
+ /* Compute render passes and film settings. */
vector<Pass> passes = sync->sync_render_passes(
b_rlay, b_view_layer, session_params.adaptive_sampling, session_params.denoising);
- buffer_params.passes = passes;
- scene->film->pass_alpha_threshold = b_view_layer.pass_alpha_threshold();
- scene->film->tag_passes_update(scene, passes);
- scene->film->tag_update(scene);
- scene->integrator->tag_update(scene);
+ /* Set buffer params, using film settings from sync_render_passes. */
+ buffer_params.passes = passes;
+ buffer_params.denoising_data_pass = scene->film->denoising_data_pass;
+ buffer_params.denoising_clean_pass = scene->film->denoising_clean_pass;
+ buffer_params.denoising_prefiltered_pass = scene->film->denoising_prefiltered_pass;
BL::RenderResult::views_iterator b_view_iter;
@@ -982,7 +972,8 @@ void BlenderSession::update_status_progress()
remaining_time = (1.0 - (double)progress) * (render_time / (double)progress);
if (background) {
- scene_status += " | " + scene->name;
+ if (scene)
+ scene_status += " | " + scene->name;
if (b_rlay_name != "")
scene_status += ", " + b_rlay_name;
diff --git a/intern/cycles/blender/blender_shader.cpp b/intern/cycles/blender/blender_shader.cpp
index 33e73b5a4b9..ae681432a43 100644
--- a/intern/cycles/blender/blender_shader.cpp
+++ b/intern/cycles/blender/blender_shader.cpp
@@ -678,7 +678,7 @@ static ShaderNode *add_node(Scene *scene,
* builtin names for packed images and movies
*/
int scene_frame = b_scene.frame_current();
- int image_frame = image_user_frame_number(b_image_user, scene_frame);
+ int image_frame = image_user_frame_number(b_image_user, b_image, scene_frame);
image->handle = scene->image_manager->add_image(
new BlenderImageLoader(b_image, image_frame), image->image_params());
}
@@ -713,7 +713,7 @@ static ShaderNode *add_node(Scene *scene,
if (is_builtin) {
int scene_frame = b_scene.frame_current();
- int image_frame = image_user_frame_number(b_image_user, scene_frame);
+ int image_frame = image_user_frame_number(b_image_user, b_image, scene_frame);
env->handle = scene->image_manager->add_image(new BlenderImageLoader(b_image, image_frame),
env->image_params());
}
diff --git a/intern/cycles/blender/blender_sync.cpp b/intern/cycles/blender/blender_sync.cpp
index ee90b4dfbfe..f806569c389 100644
--- a/intern/cycles/blender/blender_sync.cpp
+++ b/intern/cycles/blender/blender_sync.cpp
@@ -709,6 +709,16 @@ vector<Pass> BlenderSync::sync_render_passes(BL::RenderLayer &b_rlay,
}
RNA_END;
+ scene->film->denoising_data_pass = denoising.use || denoising.store_passes;
+ scene->film->denoising_clean_pass = (scene->film->denoising_flags & DENOISING_CLEAN_ALL_PASSES);
+ scene->film->denoising_prefiltered_pass = denoising.store_passes &&
+ denoising.type == DENOISER_NLM;
+
+ scene->film->pass_alpha_threshold = b_view_layer.pass_alpha_threshold();
+ scene->film->tag_passes_update(scene, passes);
+ scene->film->tag_update(scene);
+ scene->integrator->tag_update(scene);
+
return passes;
}
diff --git a/intern/cycles/blender/blender_util.h b/intern/cycles/blender/blender_util.h
index ad90a5f8d52..1ea34b41aa2 100644
--- a/intern/cycles/blender/blender_util.h
+++ b/intern/cycles/blender/blender_util.h
@@ -238,7 +238,7 @@ static inline string image_user_file_path(BL::ImageUser &iuser,
{
char filepath[1024];
iuser.tile(0);
- BKE_image_user_frame_calc(NULL, iuser.ptr.data, cfra);
+ BKE_image_user_frame_calc(ima.ptr.data, iuser.ptr.data, cfra);
BKE_image_user_file_path(iuser.ptr.data, ima.ptr.data, filepath);
string filepath_str = string(filepath);
@@ -248,9 +248,9 @@ static inline string image_user_file_path(BL::ImageUser &iuser,
return filepath_str;
}
-static inline int image_user_frame_number(BL::ImageUser &iuser, int cfra)
+static inline int image_user_frame_number(BL::ImageUser &iuser, BL::Image &ima, int cfra)
{
- BKE_image_user_frame_calc(NULL, iuser.ptr.data, cfra);
+ BKE_image_user_frame_calc(ima.ptr.data, iuser.ptr.data, cfra);
return iuser.frame_current();
}
diff --git a/intern/cycles/blender/blender_volume.cpp b/intern/cycles/blender/blender_volume.cpp
index 80591e0eec8..d0e1e4d6131 100644
--- a/intern/cycles/blender/blender_volume.cpp
+++ b/intern/cycles/blender/blender_volume.cpp
@@ -217,43 +217,29 @@ static void sync_smoke_volume(Scene *scene, BL::Object &b_ob, Mesh *mesh, float
class BlenderVolumeLoader : public VDBImageLoader {
public:
BlenderVolumeLoader(BL::BlendData &b_data, BL::Volume &b_volume, const string &grid_name)
- : VDBImageLoader(grid_name), b_data(b_data), b_volume(b_volume), unload(false)
- {
- }
-
- bool load_metadata(ImageMetaData &metadata) override
+ : VDBImageLoader(grid_name), b_volume(b_volume)
{
b_volume.grids.load(b_data.ptr.data);
- BL::VolumeGrid b_volume_grid = find_grid();
-
- if (!b_volume_grid) {
- return false;
- }
-
- unload = !b_volume_grid.is_loaded();
#ifdef WITH_OPENVDB
- Volume *volume = (Volume *)b_volume.ptr.data;
- VolumeGrid *volume_grid = (VolumeGrid *)b_volume_grid.ptr.data;
- grid = BKE_volume_grid_openvdb_for_read(volume, volume_grid);
-#endif
+ BL::Volume::grids_iterator b_grid_iter;
+ for (b_volume.grids.begin(b_grid_iter); b_grid_iter != b_volume.grids.end(); ++b_grid_iter) {
+ BL::VolumeGrid b_volume_grid(*b_grid_iter);
+ if (b_volume_grid.name() == grid_name) {
+ const bool unload = !b_volume_grid.is_loaded();
- return VDBImageLoader::load_metadata(metadata);
- }
+ Volume *volume = (Volume *)b_volume.ptr.data;
+ VolumeGrid *volume_grid = (VolumeGrid *)b_volume_grid.ptr.data;
+ grid = BKE_volume_grid_openvdb_for_read(volume, volume_grid);
- bool load_pixels(const ImageMetaData &metadata,
- void *pixels,
- const size_t pixel_size,
- const bool associate_alpha) override
- {
- b_volume.grids.load(b_data.ptr.data);
- BL::VolumeGrid b_volume_grid = find_grid();
+ if (unload) {
+ b_volume_grid.unload();
+ }
- if (!b_volume_grid) {
- return false;
+ break;
+ }
}
-
- return VDBImageLoader::load_pixels(metadata, pixels, pixel_size, associate_alpha);
+#endif
}
bool equals(const ImageLoader &other) const override
@@ -263,36 +249,7 @@ class BlenderVolumeLoader : public VDBImageLoader {
return b_volume == other_loader.b_volume && grid_name == other_loader.grid_name;
}
- void cleanup() override
- {
- VDBImageLoader::cleanup();
-
- BL::VolumeGrid b_volume_grid = find_grid();
- if (b_volume_grid && unload) {
- b_volume_grid.unload();
- }
- }
-
- /* Find grid with matching name. Grid point not stored in the class since
- * grids may be unloaded before we load the pixels, for example for motion
- * blur where we move between frames. */
- BL::VolumeGrid find_grid()
- {
-#ifdef WITH_OPENVDB
- BL::Volume::grids_iterator b_grid_iter;
- for (b_volume.grids.begin(b_grid_iter); b_grid_iter != b_volume.grids.end(); ++b_grid_iter) {
- if (b_grid_iter->name() == grid_name) {
- return *b_grid_iter;
- }
- }
-#endif
-
- return BL::VolumeGrid(PointerRNA_NULL);
- }
-
- BL::BlendData b_data;
BL::Volume b_volume;
- bool unload;
};
static void sync_volume_object(BL::BlendData &b_data, BL::Object &b_ob, Scene *scene, Mesh *mesh)
@@ -342,7 +299,7 @@ static void sync_volume_object(BL::BlendData &b_data, BL::Object &b_ob, Scene *s
ImageParams params;
params.frame = b_volume.grids.frame();
- attr->data_voxel() = scene->image_manager->add_image(loader, params);
+ attr->data_voxel() = scene->image_manager->add_image(loader, params, false);
}
}
}
diff --git a/intern/cycles/kernel/CMakeLists.txt b/intern/cycles/kernel/CMakeLists.txt
index 5533eeb006d..db146226dc7 100644
--- a/intern/cycles/kernel/CMakeLists.txt
+++ b/intern/cycles/kernel/CMakeLists.txt
@@ -539,7 +539,7 @@ if(WITH_CYCLES_DEVICE_OPTIX AND WITH_CYCLES_CUDA_BINARIES)
${SRC_UTIL_HEADERS}
COMMAND ${CUBIN_CC_ENV}
"$<TARGET_FILE:cycles_cubin_cc>"
- -target 52
+ -target 50
-ptx
-i ${CMAKE_CURRENT_SOURCE_DIR}/${input}
${cuda_flags}
@@ -563,7 +563,7 @@ if(WITH_CYCLES_DEVICE_OPTIX AND WITH_CYCLES_CUDA_BINARIES)
COMMAND
${CUDA_NVCC_EXECUTABLE}
--ptx
- -arch=sm_52
+ -arch=sm_50
${cuda_flags}
${input}
WORKING_DIRECTORY
diff --git a/intern/cycles/kernel/kernel_path.h b/intern/cycles/kernel/kernel_path.h
index 15cf2e02fdd..2ba3b1c4fdc 100644
--- a/intern/cycles/kernel/kernel_path.h
+++ b/intern/cycles/kernel/kernel_path.h
@@ -695,11 +695,9 @@ ccl_device void kernel_path_trace(
kernel_path_trace_setup(kg, sample, x, y, &rng_hash, &ray);
-# ifndef __KERNEL_OPTIX__
if (ray.t == 0.0f) {
return;
}
-# endif
/* Initialize state. */
float3 throughput = make_float3(1.0f, 1.0f, 1.0f);
diff --git a/intern/cycles/render/geometry.cpp b/intern/cycles/render/geometry.cpp
index 3d1b6e1d865..145b1fa492c 100644
--- a/intern/cycles/render/geometry.cpp
+++ b/intern/cycles/render/geometry.cpp
@@ -1201,9 +1201,13 @@ void GeometryManager::device_update_volume_images(Device *device, Scene *scene,
}
ImageHandle &handle = attr.data_voxel();
- const int slot = handle.svm_slot();
- if (slot != -1) {
- volume_images.insert(slot);
+ /* We can build directly from OpenVDB data structures, no need to
+ * load such images early. */
+ if (!handle.vdb_loader()) {
+ const int slot = handle.svm_slot();
+ if (slot != -1) {
+ volume_images.insert(slot);
+ }
}
}
}
diff --git a/intern/cycles/render/image.cpp b/intern/cycles/render/image.cpp
index 8d187814d64..a5dfcf60d61 100644
--- a/intern/cycles/render/image.cpp
+++ b/intern/cycles/render/image.cpp
@@ -18,6 +18,7 @@
#include "device/device.h"
#include "render/colorspace.h"
#include "render/image_oiio.h"
+#include "render/image_vdb.h"
#include "render/scene.h"
#include "render/stats.h"
@@ -172,6 +173,31 @@ device_texture *ImageHandle::image_memory(const int tile_index) const
return img ? img->mem : NULL;
}
+VDBImageLoader *ImageHandle::vdb_loader(const int tile_index) const
+{
+ if (tile_index >= tile_slots.size()) {
+ return NULL;
+ }
+
+ ImageManager::Image *img = manager->images[tile_slots[tile_index]];
+
+ if (img == NULL) {
+ return NULL;
+ }
+
+ ImageLoader *loader = img->loader;
+
+ if (loader == NULL) {
+ return NULL;
+ }
+
+ if (loader->is_vdb_loader()) {
+ return dynamic_cast<VDBImageLoader *>(loader);
+ }
+
+ return NULL;
+}
+
bool ImageHandle::operator==(const ImageHandle &other) const
{
return manager == other.manager && tile_slots == other.tile_slots;
@@ -258,6 +284,11 @@ bool ImageLoader::equals(const ImageLoader *a, const ImageLoader *b)
}
}
+bool ImageLoader::is_vdb_loader() const
+{
+ return false;
+}
+
/* Image Manager */
ImageManager::ImageManager(const DeviceInfo &info)
@@ -362,9 +393,11 @@ ImageHandle ImageManager::add_image(const string &filename,
return handle;
}
-ImageHandle ImageManager::add_image(ImageLoader *loader, const ImageParams &params)
+ImageHandle ImageManager::add_image(ImageLoader *loader,
+ const ImageParams &params,
+ const bool builtin)
{
- const int slot = add_image_slot(loader, params, true);
+ const int slot = add_image_slot(loader, params, builtin);
ImageHandle handle;
handle.tile_slots.push_back(slot);
diff --git a/intern/cycles/render/image.h b/intern/cycles/render/image.h
index fffe7c5152a..cb059256ce3 100644
--- a/intern/cycles/render/image.h
+++ b/intern/cycles/render/image.h
@@ -39,6 +39,7 @@ class Progress;
class RenderStats;
class Scene;
class ColorSpaceProcessor;
+class VDBImageLoader;
/* Image Parameters */
class ImageParams {
@@ -124,6 +125,8 @@ class ImageLoader {
virtual bool equals(const ImageLoader &other) const = 0;
static bool equals(const ImageLoader *a, const ImageLoader *b);
+ virtual bool is_vdb_loader() const;
+
/* Work around for no RTTI. */
};
@@ -149,6 +152,8 @@ class ImageHandle {
int svm_slot(const int tile_index = 0) const;
device_texture *image_memory(const int tile_index = 0) const;
+ VDBImageLoader *vdb_loader(const int tile_index = 0) const;
+
protected:
vector<int> tile_slots;
ImageManager *manager;
@@ -169,7 +174,7 @@ class ImageManager {
ImageHandle add_image(const string &filename,
const ImageParams &params,
const vector<int> &tiles);
- ImageHandle add_image(ImageLoader *loader, const ImageParams &params);
+ ImageHandle add_image(ImageLoader *loader, const ImageParams &params, const bool builtin = true);
void device_update(Device *device, Scene *scene, Progress &progress);
void device_update_slot(Device *device, Scene *scene, int slot, Progress *progress);
diff --git a/intern/cycles/render/image_vdb.cpp b/intern/cycles/render/image_vdb.cpp
index 500131c2d84..3f7dd45ee88 100644
--- a/intern/cycles/render/image_vdb.cpp
+++ b/intern/cycles/render/image_vdb.cpp
@@ -185,4 +185,16 @@ void VDBImageLoader::cleanup()
#endif
}
+bool VDBImageLoader::is_vdb_loader() const
+{
+ return true;
+}
+
+#ifdef WITH_OPENVDB
+openvdb::GridBase::ConstPtr VDBImageLoader::get_grid()
+{
+ return grid;
+}
+#endif
+
CCL_NAMESPACE_END
diff --git a/intern/cycles/render/image_vdb.h b/intern/cycles/render/image_vdb.h
index 7dec63b11e6..4500cfbfb88 100644
--- a/intern/cycles/render/image_vdb.h
+++ b/intern/cycles/render/image_vdb.h
@@ -43,6 +43,12 @@ class VDBImageLoader : public ImageLoader {
virtual void cleanup() override;
+ virtual bool is_vdb_loader() const override;
+
+#ifdef WITH_OPENVDB
+ openvdb::GridBase::ConstPtr get_grid();
+#endif
+
protected:
string grid_name;
#ifdef WITH_OPENVDB
diff --git a/intern/cycles/render/mesh_volume.cpp b/intern/cycles/render/mesh_volume.cpp
index 607363d01c6..70189ea4812 100644
--- a/intern/cycles/render/mesh_volume.cpp
+++ b/intern/cycles/render/mesh_volume.cpp
@@ -15,34 +15,25 @@
*/
#include "render/attribute.h"
+#include "render/image_vdb.h"
#include "render/mesh.h"
#include "render/scene.h"
+#ifdef WITH_OPENVDB
+# include <openvdb/tools/Dense.h>
+# include <openvdb/tools/GridTransformer.h>
+# include <openvdb/tools/Morphology.h>
+#endif
+
#include "util/util_foreach.h"
#include "util/util_hash.h"
#include "util/util_logging.h"
+#include "util/util_openvdb.h"
#include "util/util_progress.h"
#include "util/util_types.h"
CCL_NAMESPACE_BEGIN
-const int64_t VOXEL_INDEX_NONE = -1;
-
-static int64_t compute_voxel_index(const int3 &resolution, int64_t x, int64_t y, int64_t z)
-{
- if (x < 0 || x >= resolution.x) {
- return VOXEL_INDEX_NONE;
- }
- else if (y < 0 || y >= resolution.y) {
- return VOXEL_INDEX_NONE;
- }
- else if (z < 0 || z >= resolution.z) {
- return VOXEL_INDEX_NONE;
- }
-
- return x + y * resolution.x + z * resolution.x * resolution.y;
-}
-
struct QuadData {
int v0, v1, v2, v3;
@@ -123,122 +114,146 @@ static void create_quad(int3 corners[8],
quads.push_back(quad);
}
-struct VolumeParams {
- int3 resolution;
- float3 cell_size;
- float3 start_point;
- int pad_size;
-};
-
-static const int CUBE_SIZE = 8;
-
/* Create a mesh from a volume.
*
* The way the algorithm works is as follows:
*
- * - The coordinates of active voxels from a dense volume (or 3d image) are
- * gathered inside an auxiliary volume.
- * - Each set of coordinates of an CUBE_SIZE cube are mapped to the same
- * coordinate of the auxiliary volume.
- * - Quads are created between active and non-active voxels in the auxiliary
- * volume to generate a tight mesh around the volume.
+ * - The topologies of input OpenVDB grids are merged into a temporary grid.
+ * - Voxels of the temporary grid are dilated to account for the padding necessary for volume
+ * sampling.
+ * - Quads are created on the boundary between active and inactive leaf nodes of the temporary
+ * grid.
*/
class VolumeMeshBuilder {
- /* Auxiliary volume that is used to check if a node already added. */
- vector<char> grid;
-
- /* The resolution of the auxiliary volume, set to be equal to 1/CUBE_SIZE
- * of the original volume on each axis. */
- int3 res;
-
- size_t number_of_nodes;
-
- /* Offset due to padding in the original grid. Padding will transform the
- * coordinates of the original grid from 0...res to -padding...res+padding,
- * so some coordinates are negative, and we need to properly account for
- * them. */
- int3 pad_offset;
-
- VolumeParams *params;
-
public:
- VolumeMeshBuilder(VolumeParams *volume_params);
+#ifdef WITH_OPENVDB
+ /* use a MaskGrid to store the topology to save memory */
+ openvdb::MaskGrid::Ptr topology_grid;
+ openvdb::CoordBBox bbox;
+#endif
+ bool first_grid;
- void add_node(int x, int y, int z);
+ VolumeMeshBuilder();
- void add_node_with_padding(int x, int y, int z);
+#ifdef WITH_OPENVDB
+ void add_grid(openvdb::GridBase::ConstPtr grid, bool do_clipping, float volume_clipping);
+#endif
- void create_mesh(vector<float3> &vertices, vector<int> &indices, vector<float3> &face_normals);
+ void add_padding(int pad_size);
+
+ void create_mesh(vector<float3> &vertices,
+ vector<int> &indices,
+ vector<float3> &face_normals,
+ const float face_overlap_avoidance);
- private:
void generate_vertices_and_quads(vector<int3> &vertices_is, vector<QuadData> &quads);
- void convert_object_space(const vector<int3> &vertices, vector<float3> &out_vertices);
+ void convert_object_space(const vector<int3> &vertices,
+ vector<float3> &out_vertices,
+ const float face_overlap_avoidance);
void convert_quads_to_tris(const vector<QuadData> &quads,
vector<int> &tris,
vector<float3> &face_normals);
-};
-VolumeMeshBuilder::VolumeMeshBuilder(VolumeParams *volume_params)
-{
- params = volume_params;
- number_of_nodes = 0;
+ bool empty_grid() const;
- const int64_t x = divide_up(params->resolution.x, CUBE_SIZE);
- const int64_t y = divide_up(params->resolution.y, CUBE_SIZE);
- const int64_t z = divide_up(params->resolution.z, CUBE_SIZE);
+#ifdef WITH_OPENVDB
+ template <typename GridType>
+ void merge_grid(openvdb::GridBase::ConstPtr grid, bool do_clipping, float volume_clipping)
+ {
+ typename GridType::ConstPtr typed_grid = openvdb::gridConstPtrCast<GridType>(grid);
- /* Adding 2*pad_size since we pad in both positive and negative directions
- * along the axis. */
- const int64_t px = divide_up(params->resolution.x + 2 * params->pad_size, CUBE_SIZE);
- const int64_t py = divide_up(params->resolution.y + 2 * params->pad_size, CUBE_SIZE);
- const int64_t pz = divide_up(params->resolution.z + 2 * params->pad_size, CUBE_SIZE);
+ if (do_clipping) {
+ using ValueType = typename GridType::ValueType;
+ typename GridType::Ptr copy = typed_grid->deepCopy();
+ typename GridType::ValueOnIter iter = copy->beginValueOn();
- res = make_int3(px, py, pz);
- pad_offset = make_int3(px - x, py - y, pz - z);
+ for (; iter; ++iter) {
+ if (iter.getValue() < ValueType(volume_clipping)) {
+ iter.setValueOff();
+ }
+ }
- grid.resize(px * py * pz, 0);
-}
+ typed_grid = copy;
+ }
-void VolumeMeshBuilder::add_node(int x, int y, int z)
-{
- /* Map coordinates to index space. */
- const int index_x = (x / CUBE_SIZE) + pad_offset.x;
- const int index_y = (y / CUBE_SIZE) + pad_offset.y;
- const int index_z = (z / CUBE_SIZE) + pad_offset.z;
+ topology_grid->topologyUnion(*typed_grid);
+ }
+#endif
+};
- assert((index_x >= 0) && (index_y >= 0) && (index_z >= 0));
+VolumeMeshBuilder::VolumeMeshBuilder()
+{
+ first_grid = true;
+}
- const int64_t index = compute_voxel_index(res, index_x, index_y, index_z);
- if (index == VOXEL_INDEX_NONE) {
- return;
+#ifdef WITH_OPENVDB
+void VolumeMeshBuilder::add_grid(openvdb::GridBase::ConstPtr grid, bool do_clipping, float volume_clipping)
+{
+ /* set the transform of our grid from the first one */
+ if (first_grid) {
+ topology_grid = openvdb::MaskGrid::create();
+ topology_grid->setTransform(grid->transform().copy());
+ first_grid = false;
}
-
- /* We already have a node here. */
- if (grid[index] == 1) {
- return;
+ /* if the transforms do not match, we need to resample one of the grids so that
+ * its index space registers with that of the other, here we resample our mask
+ * grid so memory usage is kept low */
+ else if (topology_grid->transform() != grid->transform()) {
+ openvdb::MaskGrid::Ptr temp_grid = topology_grid->copyWithNewTree();
+ temp_grid->setTransform(grid->transform().copy());
+ openvdb::tools::resampleToMatch<openvdb::tools::BoxSampler>(*topology_grid, *temp_grid);
+ topology_grid = temp_grid;
+ topology_grid->setTransform(grid->transform().copy());
}
- ++number_of_nodes;
-
- grid[index] = 1;
+ if (grid->isType<openvdb::FloatGrid>()) {
+ merge_grid<openvdb::FloatGrid>(grid, do_clipping, volume_clipping);
+ }
+ else if (grid->isType<openvdb::Vec3fGrid>()) {
+ merge_grid<openvdb::Vec3fGrid>(grid, do_clipping, volume_clipping);
+ }
+ else if (grid->isType<openvdb::Vec4fGrid>()) {
+ merge_grid<openvdb::Vec4fGrid>(grid, do_clipping, volume_clipping);
+ }
+ else if (grid->isType<openvdb::BoolGrid>()) {
+ merge_grid<openvdb::BoolGrid>(grid, do_clipping, volume_clipping);
+ }
+ else if (grid->isType<openvdb::DoubleGrid>()) {
+ merge_grid<openvdb::DoubleGrid>(grid, do_clipping, volume_clipping);
+ }
+ else if (grid->isType<openvdb::Int32Grid>()) {
+ merge_grid<openvdb::Int32Grid>(grid, do_clipping, volume_clipping);
+ }
+ else if (grid->isType<openvdb::Int64Grid>()) {
+ merge_grid<openvdb::Int64Grid>(grid, do_clipping, volume_clipping);
+ }
+ else if (grid->isType<openvdb::Vec3IGrid>()) {
+ merge_grid<openvdb::Vec3IGrid>(grid, do_clipping, volume_clipping);
+ }
+ else if (grid->isType<openvdb::Vec3dGrid>()) {
+ merge_grid<openvdb::Vec3dGrid>(grid, do_clipping, volume_clipping);
+ }
+ else if (grid->isType<openvdb::MaskGrid>()) {
+ topology_grid->topologyUnion(*openvdb::gridConstPtrCast<openvdb::MaskGrid>(grid));
+ }
}
+#endif
-void VolumeMeshBuilder::add_node_with_padding(int x, int y, int z)
+void VolumeMeshBuilder::add_padding(int pad_size)
{
- for (int px = x - params->pad_size; px < x + params->pad_size; ++px) {
- for (int py = y - params->pad_size; py < y + params->pad_size; ++py) {
- for (int pz = z - params->pad_size; pz < z + params->pad_size; ++pz) {
- add_node(px, py, pz);
- }
- }
- }
+#ifdef WITH_OPENVDB
+ openvdb::tools::dilateVoxels(topology_grid->tree(), pad_size);
+#else
+ (void)pad_size;
+#endif
}
void VolumeMeshBuilder::create_mesh(vector<float3> &vertices,
vector<int> &indices,
- vector<float3> &face_normals)
+ vector<float3> &face_normals,
+ const float face_overlap_avoidance)
{
/* We create vertices in index space (is), and only convert them to object
* space when done. */
@@ -247,7 +262,7 @@ void VolumeMeshBuilder::create_mesh(vector<float3> &vertices,
generate_vertices_and_quads(vertices_is, quads);
- convert_object_space(vertices_is, vertices);
+ convert_object_space(vertices_is, vertices, face_overlap_avoidance);
convert_quads_to_tris(quads, indices, face_normals);
}
@@ -255,85 +270,97 @@ void VolumeMeshBuilder::create_mesh(vector<float3> &vertices,
void VolumeMeshBuilder::generate_vertices_and_quads(vector<ccl::int3> &vertices_is,
vector<QuadData> &quads)
{
- unordered_map<size_t, int> used_verts;
+#ifdef WITH_OPENVDB
+ const openvdb::MaskGrid::TreeType &tree = topology_grid->tree();
+ tree.evalLeafBoundingBox(bbox);
- for (int z = 0; z < res.z; ++z) {
- for (int y = 0; y < res.y; ++y) {
- for (int x = 0; x < res.x; ++x) {
- int64_t voxel_index = compute_voxel_index(res, x, y, z);
- if (grid[voxel_index] == 0) {
- continue;
- }
+ const int3 resolution = make_int3(bbox.dim().x(), bbox.dim().y(), bbox.dim().z());
- /* Compute min and max coords of the node in index space. */
- int3 min = make_int3((x - pad_offset.x) * CUBE_SIZE,
- (y - pad_offset.y) * CUBE_SIZE,
- (z - pad_offset.z) * CUBE_SIZE);
-
- /* Maximum is just CUBE_SIZE voxels away from minimum on each axis. */
- int3 max = make_int3(min.x + CUBE_SIZE, min.y + CUBE_SIZE, min.z + CUBE_SIZE);
-
- int3 corners[8] = {
- make_int3(min[0], min[1], min[2]),
- make_int3(max[0], min[1], min[2]),
- make_int3(max[0], max[1], min[2]),
- make_int3(min[0], max[1], min[2]),
- make_int3(min[0], min[1], max[2]),
- make_int3(max[0], min[1], max[2]),
- make_int3(max[0], max[1], max[2]),
- make_int3(min[0], max[1], max[2]),
- };
-
- /* Only create a quad if on the border between an active and
- * an inactive node.
- */
-
- voxel_index = compute_voxel_index(res, x - 1, y, z);
- if (voxel_index == VOXEL_INDEX_NONE || grid[voxel_index] == 0) {
- create_quad(corners, vertices_is, quads, res, used_verts, QUAD_X_MIN);
- }
+ unordered_map<size_t, int> used_verts;
- voxel_index = compute_voxel_index(res, x + 1, y, z);
- if (voxel_index == VOXEL_INDEX_NONE || grid[voxel_index] == 0) {
- create_quad(corners, vertices_is, quads, res, used_verts, QUAD_X_MAX);
- }
+ for (auto iter = tree.cbeginLeaf(); iter; ++iter) {
+ openvdb::CoordBBox leaf_bbox = iter->getNodeBoundingBox();
+ /* +1 to convert from exclusive to include bounds. */
+ leaf_bbox.max() = leaf_bbox.max().offsetBy(1);
+
+ int3 min = make_int3(leaf_bbox.min().x(), leaf_bbox.min().y(), leaf_bbox.min().z());
+ int3 max = make_int3(leaf_bbox.max().x(), leaf_bbox.max().y(), leaf_bbox.max().z());
+
+ int3 corners[8] = {
+ make_int3(min[0], min[1], min[2]),
+ make_int3(max[0], min[1], min[2]),
+ make_int3(max[0], max[1], min[2]),
+ make_int3(min[0], max[1], min[2]),
+ make_int3(min[0], min[1], max[2]),
+ make_int3(max[0], min[1], max[2]),
+ make_int3(max[0], max[1], max[2]),
+ make_int3(min[0], max[1], max[2]),
+ };
+
+ /* Only create a quad if on the border between an active and an inactive leaf.
+ *
+ * We verify that a leaf exists by probing a coordinate that is at its center,
+ * to do so we compute the center of the current leaf and offset this coordinate
+ * by the size of a leaf in each direction.
+ */
+ static const int LEAF_DIM = openvdb::MaskGrid::TreeType::LeafNodeType::DIM;
+ auto center = leaf_bbox.min() + openvdb::Coord(LEAF_DIM / 2);
+
+ if (!tree.probeLeaf(openvdb::Coord(center.x() - LEAF_DIM, center.y(), center.z()))) {
+ create_quad(corners, vertices_is, quads, resolution, used_verts, QUAD_X_MIN);
+ }
- voxel_index = compute_voxel_index(res, x, y - 1, z);
- if (voxel_index == VOXEL_INDEX_NONE || grid[voxel_index] == 0) {
- create_quad(corners, vertices_is, quads, res, used_verts, QUAD_Y_MIN);
- }
+ if (!tree.probeLeaf(openvdb::Coord(center.x() + LEAF_DIM, center.y(), center.z()))) {
+ create_quad(corners, vertices_is, quads, resolution, used_verts, QUAD_X_MAX);
+ }
- voxel_index = compute_voxel_index(res, x, y + 1, z);
- if (voxel_index == VOXEL_INDEX_NONE || grid[voxel_index] == 0) {
- create_quad(corners, vertices_is, quads, res, used_verts, QUAD_Y_MAX);
- }
+ if (!tree.probeLeaf(openvdb::Coord(center.x(), center.y() - LEAF_DIM, center.z()))) {
+ create_quad(corners, vertices_is, quads, resolution, used_verts, QUAD_Y_MIN);
+ }
- voxel_index = compute_voxel_index(res, x, y, z - 1);
- if (voxel_index == VOXEL_INDEX_NONE || grid[voxel_index] == 0) {
- create_quad(corners, vertices_is, quads, res, used_verts, QUAD_Z_MIN);
- }
+ if (!tree.probeLeaf(openvdb::Coord(center.x(), center.y() + LEAF_DIM, center.z()))) {
+ create_quad(corners, vertices_is, quads, resolution, used_verts, QUAD_Y_MAX);
+ }
- voxel_index = compute_voxel_index(res, x, y, z + 1);
- if (voxel_index == VOXEL_INDEX_NONE || grid[voxel_index] == 0) {
- create_quad(corners, vertices_is, quads, res, used_verts, QUAD_Z_MAX);
- }
- }
+ if (!tree.probeLeaf(openvdb::Coord(center.x(), center.y(), center.z() - LEAF_DIM))) {
+ create_quad(corners, vertices_is, quads, resolution, used_verts, QUAD_Z_MIN);
+ }
+
+ if (!tree.probeLeaf(openvdb::Coord(center.x(), center.y(), center.z() + LEAF_DIM))) {
+ create_quad(corners, vertices_is, quads, resolution, used_verts, QUAD_Z_MAX);
}
}
+#else
+ (void)vertices_is;
+ (void)quads;
+#endif
}
void VolumeMeshBuilder::convert_object_space(const vector<int3> &vertices,
- vector<float3> &out_vertices)
+ vector<float3> &out_vertices,
+ const float face_overlap_avoidance)
{
+#ifdef WITH_OPENVDB
+ /* compute the offset for the face overlap avoidance */
+ bbox = topology_grid->evalActiveVoxelBoundingBox();
+ openvdb::Coord dim = bbox.dim();
+
+ float3 cell_size = make_float3(1.0f / dim.x(), 1.0f / dim.y(), 1.0f / dim.z());
+ float3 point_offset = cell_size * face_overlap_avoidance;
+
out_vertices.reserve(vertices.size());
for (size_t i = 0; i < vertices.size(); ++i) {
- float3 vertex = make_float3(vertices[i].x, vertices[i].y, vertices[i].z);
- vertex *= params->cell_size;
- vertex += params->start_point;
-
- out_vertices.push_back(vertex);
+ openvdb::math::Vec3d p = topology_grid->indexToWorld(
+ openvdb::math::Vec3d(vertices[i].x, vertices[i].y, vertices[i].z));
+ float3 vertex = make_float3((float)p.x(), (float)p.y(), (float)p.z());
+ out_vertices.push_back(vertex + point_offset);
}
+#else
+ (void)vertices;
+ (void)out_vertices;
+ (void)face_overlap_avoidance;
+#endif
}
void VolumeMeshBuilder::convert_quads_to_tris(const vector<QuadData> &quads,
@@ -359,57 +386,115 @@ void VolumeMeshBuilder::convert_quads_to_tris(const vector<QuadData> &quads,
}
}
-/* ************************************************************************** */
+bool VolumeMeshBuilder::empty_grid() const
+{
+#ifdef WITH_OPENVDB
+ return !topology_grid || topology_grid->tree().leafCount() == 0;
+#else
+ return true;
+#endif
+}
-struct VoxelAttributeGrid {
- float *data;
- int channels;
-};
+#ifdef WITH_OPENVDB
+template<typename GridType>
+static openvdb::GridBase::ConstPtr openvdb_grid_from_device_texture(device_texture *image_memory,
+ float volume_clipping,
+ Transform transform_3d)
+{
+ using ValueType = typename GridType::ValueType;
+
+ openvdb::CoordBBox dense_bbox(0,
+ 0,
+ 0,
+ image_memory->data_width - 1,
+ image_memory->data_height - 1,
+ image_memory->data_depth - 1);
+ openvdb::tools::Dense<ValueType, openvdb::tools::MemoryLayout::LayoutXYZ> dense(
+ dense_bbox, static_cast<ValueType *>(image_memory->host_pointer));
+
+ typename GridType::Ptr sparse = GridType::create(ValueType(0.0f));
+ openvdb::tools::copyFromDense(dense, *sparse, ValueType(volume_clipping));
+
+ /* copyFromDense will remove any leaf node that contains constant data and replace it with a tile,
+ * however, we need to preserve the leaves in order to generate the mesh, so revoxelize the leaves
+ * that were pruned. This should not affect areas that were skipped due to the volume_clipping parameter. */
+ sparse->tree().voxelizeActiveTiles();
+
+ /* Compute index to world matrix. */
+ float3 voxel_size = make_float3(1.0f / image_memory->data_width, 1.0f / image_memory->data_height, 1.0f / image_memory->data_depth);
+
+ transform_3d = transform_inverse(transform_3d);
+
+ openvdb::Mat4R index_to_world_mat((double)(voxel_size.x * transform_3d[0][0]), 0.0, 0.0, 0.0,
+ 0.0, (double)(voxel_size.y * transform_3d[1][1]), 0.0, 0.0,
+ 0.0, 0.0, (double)(voxel_size.z * transform_3d[2][2]), 0.0,
+ (double)transform_3d[0][3], (double)transform_3d[1][3], (double)transform_3d[2][3], 1.0);
+
+ openvdb::math::Transform::Ptr index_to_world_tfm = openvdb::math::Transform::createLinearTransform(index_to_world_mat);
+
+ sparse->setTransform(index_to_world_tfm);
+
+ return sparse;
+}
+#endif
+
+/* ************************************************************************** */
void GeometryManager::create_volume_mesh(Mesh *mesh, Progress &progress)
{
string msg = string_printf("Computing Volume Mesh %s", mesh->name.c_str());
progress.set_status("Updating Mesh", msg);
- vector<VoxelAttributeGrid> voxel_grids;
-
- /* Compute volume parameters. */
- VolumeParams volume_params;
- volume_params.resolution = make_int3(0, 0, 0);
-
- Transform transform = transform_identity();
+ VolumeMeshBuilder builder;
+#ifdef WITH_OPENVDB
foreach (Attribute &attr, mesh->attributes.attributes) {
if (attr.element != ATTR_ELEMENT_VOXEL) {
continue;
}
+ bool do_clipping = false;
+
ImageHandle &handle = attr.data_voxel();
- device_texture *image_memory = handle.image_memory();
- int3 resolution = make_int3(
- image_memory->data_width, image_memory->data_height, image_memory->data_depth);
- if (volume_params.resolution == make_int3(0, 0, 0)) {
- volume_params.resolution = resolution;
- }
- else if (volume_params.resolution != resolution) {
- /* TODO: support this as it's common for OpenVDB. */
- VLOG(1) << "Can't create accurate volume mesh, all voxel grid resolutions must be equal\n";
- continue;
+ /* Try building from OpenVDB grid directly. */
+ VDBImageLoader *vdb_loader = handle.vdb_loader();
+ openvdb::GridBase::ConstPtr grid;
+ if (vdb_loader) {
+ grid = vdb_loader->get_grid();
+
+ /* If building from an OpenVDB grid, we need to manually clip the values. */
+ do_clipping = true;
}
- VoxelAttributeGrid voxel_grid;
- voxel_grid.data = static_cast<float *>(image_memory->host_pointer);
- voxel_grid.channels = image_memory->data_elements;
- voxel_grids.push_back(voxel_grid);
+ /* Else fall back to creating an OpenVDB grid from the dense volume data. */
+ if (!grid) {
+ device_texture *image_memory = handle.image_memory();
- /* TODO: support multiple transforms. */
- if (image_memory->info.use_transform_3d) {
- transform = image_memory->info.transform_3d;
+ if (image_memory->data_elements == 1) {
+ grid = openvdb_grid_from_device_texture<openvdb::FloatGrid>(image_memory,
+ mesh->volume_clipping,
+ handle.metadata().transform_3d);
+ }
+ else if (image_memory->data_elements == 3) {
+ grid = openvdb_grid_from_device_texture<openvdb::Vec3fGrid>(image_memory,
+ mesh->volume_clipping,
+ handle.metadata().transform_3d);
+ }
+ else if (image_memory->data_elements == 4) {
+ grid = openvdb_grid_from_device_texture<openvdb::Vec4fGrid>(image_memory,
+ mesh->volume_clipping,
+ handle.metadata().transform_3d);
+ }
+ }
+
+ if (grid) {
+ builder.add_grid(grid, do_clipping, mesh->volume_clipping);
}
}
+#endif
- if (voxel_grids.empty()) {
+ if (builder.empty_grid()) {
return;
}
@@ -438,56 +523,19 @@ void GeometryManager::create_volume_mesh(Mesh *mesh, Progress &progress)
return;
}
- /* Compute start point and cell size from transform. */
- const int3 resolution = volume_params.resolution;
- float3 start_point = make_float3(0.0f, 0.0f, 0.0f);
- float3 cell_size = make_float3(1.0f / resolution.x, 1.0f / resolution.y, 1.0f / resolution.z);
-
- /* TODO: support arbitrary transforms, not just scale + translate. */
- const Transform itfm = transform_inverse(transform);
- start_point = transform_point(&itfm, start_point);
- cell_size = transform_direction(&itfm, cell_size);
+ builder.add_padding(pad_size);
/* Slightly offset vertex coordinates to avoid overlapping faces with other
* volumes or meshes. The proper solution would be to improve intersection in
* the kernel to support robust handling of multiple overlapping faces or use
* an all-hit intersection similar to shadows. */
- const float3 face_overlap_avoidance = cell_size * 0.1f *
- hash_uint_to_float(hash_string(mesh->name.c_str()));
-
- volume_params.start_point = start_point + face_overlap_avoidance;
- volume_params.cell_size = cell_size;
- volume_params.pad_size = pad_size;
-
- /* Build bounding mesh around non-empty volume cells. */
- VolumeMeshBuilder builder(&volume_params);
- const float clipping = mesh->volume_clipping;
-
- for (int z = 0; z < resolution.z; ++z) {
- for (int y = 0; y < resolution.y; ++y) {
- for (int x = 0; x < resolution.x; ++x) {
- int64_t voxel_index = compute_voxel_index(resolution, x, y, z);
-
- for (size_t i = 0; i < voxel_grids.size(); ++i) {
- const VoxelAttributeGrid &voxel_grid = voxel_grids[i];
- const int channels = voxel_grid.channels;
-
- for (int c = 0; c < channels; c++) {
- if (voxel_grid.data[voxel_index * channels + c] >= clipping) {
- builder.add_node_with_padding(x, y, z);
- break;
- }
- }
- }
- }
- }
- }
+ const float face_overlap_avoidance = 0.1f * hash_uint_to_float(hash_string(mesh->name.c_str()));
/* Create mesh. */
vector<float3> vertices;
vector<int> indices;
vector<float3> face_normals;
- builder.create_mesh(vertices, indices, face_normals);
+ builder.create_mesh(vertices, indices, face_normals, face_overlap_avoidance);
mesh->clear(true);
mesh->reserve_mesh(vertices.size(), indices.size() / 3);
@@ -514,10 +562,6 @@ void GeometryManager::create_volume_mesh(Mesh *mesh, Progress &progress)
indices.size() * sizeof(int)) /
(1024.0 * 1024.0)
<< "Mb.";
-
- VLOG(1) << "Memory usage volume grid: "
- << (resolution.x * resolution.y * resolution.z * sizeof(float)) / (1024.0 * 1024.0)
- << "Mb.";
}
CCL_NAMESPACE_END
diff --git a/intern/cycles/render/session.cpp b/intern/cycles/render/session.cpp
index c5033359c6b..70c4214c684 100644
--- a/intern/cycles/render/session.cpp
+++ b/intern/cycles/render/session.cpp
@@ -945,8 +945,14 @@ void Session::set_pause(bool pause_)
}
}
- if (notify)
- pause_cond.notify_all();
+ if (session_thread) {
+ if (notify) {
+ pause_cond.notify_all();
+ }
+ }
+ else if (pause_) {
+ update_status_time(pause_);
+ }
}
void Session::set_denoising(const DenoiseParams &denoising)
@@ -1150,8 +1156,15 @@ bool Session::render_need_denoise(bool &delayed)
return false;
}
+ /* Immediately denoise when we reach the start sample or last sample. */
+ const int num_samples_finished = tile_manager.state.sample + 1;
+ if (num_samples_finished == params.denoising.start_sample ||
+ num_samples_finished == params.samples) {
+ return true;
+ }
+
/* Do not denoise until the sample at which denoising should start is reached. */
- if (tile_manager.state.sample < min(params.denoising.start_sample, params.samples - 1)) {
+ if (num_samples_finished < params.denoising.start_sample) {
return false;
}
diff --git a/intern/cycles/test/CMakeLists.txt b/intern/cycles/test/CMakeLists.txt
index 6dcc7f7b3dd..07b345baff8 100644
--- a/intern/cycles/test/CMakeLists.txt
+++ b/intern/cycles/test/CMakeLists.txt
@@ -112,3 +112,4 @@ set_source_files_properties(util_avxf_avx_test.cpp PROPERTIES COMPILE_FLAGS "${C
CYCLES_TEST(util_avxf_avx "cycles_util;bf_intern_numaapi;${OPENIMAGEIO_LIBRARIES};${BOOST_LIBRARIES}")
set_source_files_properties(util_avxf_avx2_test.cpp PROPERTIES COMPILE_FLAGS "${CYCLES_AVX2_KERNEL_FLAGS}")
CYCLES_TEST(util_avxf_avx2 "cycles_util;bf_intern_numaapi;${OPENIMAGEIO_LIBRARIES};${BOOST_LIBRARIES}")
+CYCLES_TEST(util_transform "cycles_util;${OPENIMAGEIO_LIBRARIES};${BOOST_LIBRARIES}")
diff --git a/intern/cycles/test/util_transform_test.cpp b/intern/cycles/test/util_transform_test.cpp
new file mode 100644
index 00000000000..58ce0fdfee4
--- /dev/null
+++ b/intern/cycles/test/util_transform_test.cpp
@@ -0,0 +1,53 @@
+/*
+ * Copyright 2011-2020 Blender Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "testing/testing.h"
+
+#include "util/util_transform.h"
+#include "util/util_vector.h"
+
+CCL_NAMESPACE_BEGIN
+
+TEST(transform_motion_decompose, Degenerated)
+{
+ // Simple case: single degenerated matrix.
+ {
+ vector<Transform> motion = {transform_scale(0.0f, 0.0f, 0.0f)};
+ vector<DecomposedTransform> decomp(motion.size());
+ transform_motion_decompose(decomp.data(), motion.data(), motion.size());
+ EXPECT_TRUE(transform_decomposed_isfinite_safe(&decomp[0]));
+ }
+
+ // Copy from previous to current.
+ {
+ vector<Transform> motion = {transform_rotate(M_PI_4_F, make_float3(1.0f, 1.0f, 1.0f)),
+ transform_scale(0.0f, 0.0f, 0.0f)};
+ vector<DecomposedTransform> decomp(motion.size());
+ transform_motion_decompose(decomp.data(), motion.data(), motion.size());
+ EXPECT_NEAR(len(decomp[1].x - decomp[0].x), 0.0f, 1e-6f);
+ }
+
+ // Copy from next to current.
+ {
+ vector<Transform> motion = {transform_scale(0.0f, 0.0f, 0.0f),
+ transform_rotate(M_PI_4_F, make_float3(1.0f, 1.0f, 1.0f))};
+ vector<DecomposedTransform> decomp(motion.size());
+ transform_motion_decompose(decomp.data(), motion.data(), motion.size());
+ EXPECT_NEAR(len(decomp[0].x - decomp[1].x), 0.0f, 1e-6f);
+ }
+}
+
+CCL_NAMESPACE_END
diff --git a/intern/cycles/util/CMakeLists.txt b/intern/cycles/util/CMakeLists.txt
index f5e488d1bd2..a35ec6c7e29 100644
--- a/intern/cycles/util/CMakeLists.txt
+++ b/intern/cycles/util/CMakeLists.txt
@@ -88,6 +88,7 @@ set(SRC_HEADERS
util_murmurhash.h
util_openimagedenoise.h
util_opengl.h
+ util_openvdb.h
util_optimization.h
util_param.h
util_path.h
diff --git a/intern/cycles/util/util_math_fast.h b/intern/cycles/util/util_math_fast.h
index e979bd9e0c0..07b0878e3d5 100644
--- a/intern/cycles/util/util_math_fast.h
+++ b/intern/cycles/util/util_math_fast.h
@@ -87,7 +87,7 @@ ccl_device_inline int fast_rint(float x)
/* Single roundps instruction on SSE4.1+ (for gcc/clang at least). */
return float_to_int(rintf(x));
#else
- /* emulate rounding by adding/substracting 0.5. */
+ /* emulate rounding by adding/subtracting 0.5. */
return float_to_int(x + copysignf(0.5f, x));
#endif
}
@@ -445,12 +445,10 @@ ccl_device_inline float fast_expf(float x)
return fast_exp2f(x / M_LN2_F);
}
-#ifndef __KERNEL_GPU__
-/* MSVC seems to have a code-gen bug here in at least SSE41/AVX
- * see T78047 for details. */
-# ifdef _MSC_VER
-# pragma optimize("", off)
-# endif
+#if defined(__KERNEL_CPU__) && !defined(_MSC_VER)
+/* MSVC seems to have a code-gen bug here in at least SSE41/AVX, see
+ * T78047 and T78869 for details. Just disable for now, it only makes
+ * a small difference in denoising performance. */
ccl_device float4 fast_exp2f4(float4 x)
{
const float4 one = make_float4(1.0f);
@@ -466,14 +464,16 @@ ccl_device float4 fast_exp2f4(float4 x)
r = madd4(x, r, make_float4(1.0f));
return __int4_as_float4(__float4_as_int4(r) + (m << 23));
}
-# ifdef _MSC_VER
-# pragma optimize("", on)
-# endif
ccl_device_inline float4 fast_expf4(float4 x)
{
return fast_exp2f4(x / M_LN2_F);
}
+#else
+ccl_device_inline float4 fast_expf4(float4 x)
+{
+ return make_float4(fast_expf(x.x), fast_expf(x.y), fast_expf(x.z), fast_expf(x.w));
+}
#endif
ccl_device_inline float fast_exp10(float x)
diff --git a/intern/cycles/util/util_math_float4.h b/intern/cycles/util/util_math_float4.h
index cd4b3e3b74c..ec5328adb31 100644
--- a/intern/cycles/util/util_math_float4.h
+++ b/intern/cycles/util/util_math_float4.h
@@ -477,6 +477,24 @@ ccl_device_inline float4 safe_divide_float4_float(const float4 a, const float b)
return (b != 0.0f) ? a / b : make_float4(0.0f, 0.0f, 0.0f, 0.0f);
}
+ccl_device_inline bool isfinite4_safe(float4 v)
+{
+ return isfinite_safe(v.x) && isfinite_safe(v.y) && isfinite_safe(v.z) && isfinite_safe(v.w);
+}
+
+ccl_device_inline float4 ensure_finite4(float4 v)
+{
+ if (!isfinite_safe(v.x))
+ v.x = 0.0f;
+ if (!isfinite_safe(v.y))
+ v.y = 0.0f;
+ if (!isfinite_safe(v.z))
+ v.z = 0.0f;
+ if (!isfinite_safe(v.w))
+ v.w = 0.0f;
+ return v;
+}
+
CCL_NAMESPACE_END
#endif /* __UTIL_MATH_FLOAT4_H__ */
diff --git a/intern/cycles/util/util_openvdb.h b/intern/cycles/util/util_openvdb.h
new file mode 100644
index 00000000000..a3ebb03e5a4
--- /dev/null
+++ b/intern/cycles/util/util_openvdb.h
@@ -0,0 +1,32 @@
+/*
+ * Copyright 2011-2020 Blender Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __UTIL_OPENVDB_H__
+#define __UTIL_OPENVDB_H__
+
+#ifdef WITH_OPENVDB
+# include <openvdb/openvdb.h>
+
+namespace openvdb {
+
+using Vec4fTree = tree::Tree4<Vec4f, 5, 4, 3>::Type;
+using Vec4fGrid = Grid<Vec4fTree>;
+
+}; // namespace openvdb
+
+#endif
+
+#endif /* __UTIL_OPENVDB_H__ */
diff --git a/intern/cycles/util/util_transform.cpp b/intern/cycles/util/util_transform.cpp
index 101122740d7..6417752f704 100644
--- a/intern/cycles/util/util_transform.cpp
+++ b/intern/cycles/util/util_transform.cpp
@@ -269,17 +269,17 @@ static void transform_decompose(DecomposedTransform *decomp, const Transform *tf
/* extract scale and shear first */
float3 scale, shear;
scale.x = len(colx);
- colx /= scale.x;
+ colx = safe_divide_float3_float(colx, scale.x);
shear.z = dot(colx, coly);
coly -= shear.z * colx;
scale.y = len(coly);
- coly /= scale.y;
+ coly = safe_divide_float3_float(coly, scale.y);
shear.y = dot(colx, colz);
colz -= shear.y * colx;
shear.x = dot(coly, colz);
colz -= shear.x * coly;
scale.z = len(colz);
- colz /= scale.z;
+ colz = safe_divide_float3_float(colz, scale.z);
transform_set_column(&M, 0, colx);
transform_set_column(&M, 1, coly);
@@ -300,6 +300,7 @@ static void transform_decompose(DecomposedTransform *decomp, const Transform *tf
void transform_motion_decompose(DecomposedTransform *decomp, const Transform *motion, size_t size)
{
+ /* Decompose and correct rotation. */
for (size_t i = 0; i < size; i++) {
transform_decompose(decomp + i, motion + i);
@@ -310,6 +311,27 @@ void transform_motion_decompose(DecomposedTransform *decomp, const Transform *mo
decomp[i].x = -decomp[i].x;
}
}
+
+ /* Copy rotation to decomposed transform where scale is degenerate. This avoids weird object
+ * rotation interpolation when the scale goes to 0 for a time step.
+ *
+ * Note that this is very simple and naive implementation, which only deals with degenerated
+ * scale happening only on one frame. It is possible to improve it further by interpolating
+ * rotation into s degenerated range using rotation from timesteps from adjacent non-degenerated
+ * time steps. */
+ for (size_t i = 0; i < size; i++) {
+ const float3 scale = make_float3(decomp[i].y.w, decomp[i].z.w, decomp[i].w.w);
+ if (!is_zero(scale)) {
+ continue;
+ }
+
+ if (i > 0) {
+ decomp[i].x = decomp[i - 1].x;
+ }
+ else if (i < size - 1) {
+ decomp[i].x = decomp[i + 1].x;
+ }
+ }
}
Transform transform_from_viewplane(BoundBox2D &viewplane)
diff --git a/intern/cycles/util/util_transform.h b/intern/cycles/util/util_transform.h
index d0a6264d5cf..d8bbd389aa6 100644
--- a/intern/cycles/util/util_transform.h
+++ b/intern/cycles/util/util_transform.h
@@ -466,6 +466,17 @@ ccl_device void transform_motion_array_interpolate(Transform *tfm,
transform_compose(tfm, &decomp);
}
+ccl_device_inline bool transform_isfinite_safe(Transform *tfm)
+{
+ return isfinite4_safe(tfm->x) && isfinite4_safe(tfm->y) && isfinite4_safe(tfm->z);
+}
+
+ccl_device_inline bool transform_decomposed_isfinite_safe(DecomposedTransform *decomp)
+{
+ return isfinite4_safe(decomp->x) && isfinite4_safe(decomp->y) && isfinite4_safe(decomp->z) &&
+ isfinite4_safe(decomp->w);
+}
+
#ifndef __KERNEL_GPU__
class BoundBox2D;
diff --git a/intern/ghost/GHOST_C-api.h b/intern/ghost/GHOST_C-api.h
index 92061f55128..f23742a9166 100644
--- a/intern/ghost/GHOST_C-api.h
+++ b/intern/ghost/GHOST_C-api.h
@@ -21,8 +21,7 @@
* \brief GHOST C-API function and type declarations.
*/
-#ifndef __GHOST_C_API_H__
-#define __GHOST_C_API_H__
+#pragma once
#include "GHOST_Types.h"
@@ -1072,5 +1071,3 @@ GHOST_TSuccess GHOST_XrEventsHandle(GHOST_XrContextHandle xr_context);
#ifdef __cplusplus
}
#endif
-
-#endif
diff --git a/intern/ghost/GHOST_IContext.h b/intern/ghost/GHOST_IContext.h
index 8c24261644a..c6316e90ce4 100644
--- a/intern/ghost/GHOST_IContext.h
+++ b/intern/ghost/GHOST_IContext.h
@@ -22,8 +22,7 @@
* Declaration of GHOST_IContext interface class.
*/
-#ifndef __GHOST_IContext_H__
-#define __GHOST_IContext_H__
+#pragma once
#include "GHOST_Types.h"
@@ -63,5 +62,3 @@ class GHOST_IContext {
MEM_CXX_CLASS_ALLOC_FUNCS("GHOST:GHOST_IContext")
#endif
};
-
-#endif // __GHOST_IContext_H__
diff --git a/intern/ghost/GHOST_IEvent.h b/intern/ghost/GHOST_IEvent.h
index 0d9bfb2c4de..c63064c123a 100644
--- a/intern/ghost/GHOST_IEvent.h
+++ b/intern/ghost/GHOST_IEvent.h
@@ -22,8 +22,7 @@
* Declaration of GHOST_IEvent interface class.
*/
-#ifndef __GHOST_IEVENT_H__
-#define __GHOST_IEVENT_H__
+#pragma once
#include "GHOST_Types.h"
#include <stddef.h>
@@ -78,5 +77,3 @@ class GHOST_IEvent {
MEM_CXX_CLASS_ALLOC_FUNCS("GHOST:GHOST_IEvent")
#endif
};
-
-#endif // __GHOST_IEVENT_H__
diff --git a/intern/ghost/GHOST_IEventConsumer.h b/intern/ghost/GHOST_IEventConsumer.h
index d677a632a4b..b5975068da0 100644
--- a/intern/ghost/GHOST_IEventConsumer.h
+++ b/intern/ghost/GHOST_IEventConsumer.h
@@ -22,8 +22,7 @@
* Declaration of GHOST_IEventConsumer interface class.
*/
-#ifndef __GHOST_IEVENTCONSUMER_H__
-#define __GHOST_IEVENTCONSUMER_H__
+#pragma once
#include "GHOST_IEvent.h"
@@ -56,5 +55,3 @@ class GHOST_IEventConsumer {
MEM_CXX_CLASS_ALLOC_FUNCS("GHOST:GHOST_IEventConsumer")
#endif
};
-
-#endif /* __GHOST_IEVENTCONSUMER_H__ */
diff --git a/intern/ghost/GHOST_ISystem.h b/intern/ghost/GHOST_ISystem.h
index 33600fd1219..04e9d5e4e14 100644
--- a/intern/ghost/GHOST_ISystem.h
+++ b/intern/ghost/GHOST_ISystem.h
@@ -24,8 +24,7 @@
* Contains the doxygen documentation main page.
*/
-#ifndef __GHOST_ISYSTEM_H__
-#define __GHOST_ISYSTEM_H__
+#pragma once
#include <stdlib.h>
@@ -494,5 +493,3 @@ class GHOST_ISystem {
MEM_CXX_CLASS_ALLOC_FUNCS("GHOST:GHOST_ISystem")
#endif
};
-
-#endif // __GHOST_ISYSTEM_H__
diff --git a/intern/ghost/GHOST_ISystemPaths.h b/intern/ghost/GHOST_ISystemPaths.h
index 297f6333a77..b47d14984d8 100644
--- a/intern/ghost/GHOST_ISystemPaths.h
+++ b/intern/ghost/GHOST_ISystemPaths.h
@@ -21,8 +21,7 @@
* \ingroup GHOST
*/
-#ifndef __GHOST_ISYSTEMPATHS_H__
-#define __GHOST_ISYSTEMPATHS_H__
+#pragma once
#include "GHOST_Types.h"
@@ -97,5 +96,3 @@ class GHOST_ISystemPaths {
MEM_CXX_CLASS_ALLOC_FUNCS("GHOST:GHOST_ISystemPaths")
#endif
};
-
-#endif
diff --git a/intern/ghost/GHOST_ITimerTask.h b/intern/ghost/GHOST_ITimerTask.h
index 46f4fdbc303..0f4ac74c466 100644
--- a/intern/ghost/GHOST_ITimerTask.h
+++ b/intern/ghost/GHOST_ITimerTask.h
@@ -22,8 +22,7 @@
* Declaration of GHOST_ITimerTask interface class.
*/
-#ifndef __GHOST_ITIMERTASK_H__
-#define __GHOST_ITIMERTASK_H__
+#pragma once
#include "GHOST_Types.h"
@@ -76,5 +75,3 @@ class GHOST_ITimerTask {
MEM_CXX_CLASS_ALLOC_FUNCS("GHOST:GHOST_ITimerTask")
#endif
};
-
-#endif // __GHOST_ITIMERTASK_H__
diff --git a/intern/ghost/GHOST_IWindow.h b/intern/ghost/GHOST_IWindow.h
index 9c72b6f07f9..6e8b61ae5a1 100644
--- a/intern/ghost/GHOST_IWindow.h
+++ b/intern/ghost/GHOST_IWindow.h
@@ -22,8 +22,7 @@
* Declaration of GHOST_IWindow interface class.
*/
-#ifndef __GHOST_IWINDOW_H__
-#define __GHOST_IWINDOW_H__
+#pragma once
#include "GHOST_Rect.h"
#include "GHOST_Types.h"
@@ -363,5 +362,3 @@ class GHOST_IWindow {
MEM_CXX_CLASS_ALLOC_FUNCS("GHOST:GHOST_IWindow")
#endif
};
-
-#endif // __GHOST_IWINDOW_H__
diff --git a/intern/ghost/GHOST_IXrContext.h b/intern/ghost/GHOST_IXrContext.h
index 3076de96690..dd266a3b6ae 100644
--- a/intern/ghost/GHOST_IXrContext.h
+++ b/intern/ghost/GHOST_IXrContext.h
@@ -18,8 +18,7 @@
* \ingroup GHOST
*/
-#ifndef __GHOST_IXRCONTEXT_H__
-#define __GHOST_IXRCONTEXT_H__
+#pragma once
#include "GHOST_Types.h"
@@ -40,5 +39,3 @@ class GHOST_IXrContext {
virtual bool needsUpsideDownDrawing() const = 0;
};
-
-#endif // __GHOST_IXRCONTEXT_H__
diff --git a/intern/ghost/GHOST_Path-api.h b/intern/ghost/GHOST_Path-api.h
index 53abdf68bb4..4cc232be6b6 100644
--- a/intern/ghost/GHOST_Path-api.h
+++ b/intern/ghost/GHOST_Path-api.h
@@ -21,8 +21,7 @@
* \ingroup GHOST
*/
-#ifndef __GHOST_PATH_API_H__
-#define __GHOST_PATH_API_H__
+#pragma once
#include "GHOST_Types.h"
@@ -71,5 +70,3 @@ extern void GHOST_addToSystemRecentFiles(const char *filename);
#ifdef __cplusplus
}
#endif
-
-#endif
diff --git a/intern/ghost/GHOST_Rect.h b/intern/ghost/GHOST_Rect.h
index 13632a1c03b..fcc9da20197 100644
--- a/intern/ghost/GHOST_Rect.h
+++ b/intern/ghost/GHOST_Rect.h
@@ -22,8 +22,7 @@
* Macro's used in GHOST debug target.
*/
-#ifndef __GHOST_RECT_H__
-#define __GHOST_RECT_H__
+#pragma once
#include "GHOST_Types.h"
@@ -263,5 +262,3 @@ inline bool GHOST_Rect::isInside(GHOST_TInt32 x, GHOST_TInt32 y) const
{
return (x >= m_l) && (x <= m_r) && (y >= m_t) && (y <= m_b);
}
-
-#endif // __GHOST_RECT_H__
diff --git a/intern/ghost/GHOST_Types.h b/intern/ghost/GHOST_Types.h
index b8de31df6c6..5f0516ae121 100644
--- a/intern/ghost/GHOST_Types.h
+++ b/intern/ghost/GHOST_Types.h
@@ -21,8 +21,7 @@
* \ingroup GHOST
*/
-#ifndef __GHOST_TYPES_H__
-#define __GHOST_TYPES_H__
+#pragma once
#ifdef WITH_CXX_GUARDEDALLOC
# include "MEM_guardedalloc.h"
@@ -677,5 +676,3 @@ typedef struct GHOST_XrError {
} GHOST_XrError;
#endif
-
-#endif // __GHOST_TYPES_H__
diff --git a/intern/ghost/intern/GHOST_Buttons.h b/intern/ghost/intern/GHOST_Buttons.h
index 0b824739950..e28fae8870c 100644
--- a/intern/ghost/intern/GHOST_Buttons.h
+++ b/intern/ghost/intern/GHOST_Buttons.h
@@ -22,8 +22,7 @@
* Declaration of GHOST_Buttons struct.
*/
-#ifndef __GHOST_BUTTONS_H__
-#define __GHOST_BUTTONS_H__
+#pragma once
#include "GHOST_Types.h"
@@ -62,5 +61,3 @@ struct GHOST_Buttons {
GHOST_TUns8 m_ButtonMiddle : 1;
GHOST_TUns8 m_ButtonRight : 1;
};
-
-#endif // __GHOST_BUTTONS_H__
diff --git a/intern/ghost/intern/GHOST_CallbackEventConsumer.h b/intern/ghost/intern/GHOST_CallbackEventConsumer.h
index 9c3fc642209..a1664e77717 100644
--- a/intern/ghost/intern/GHOST_CallbackEventConsumer.h
+++ b/intern/ghost/intern/GHOST_CallbackEventConsumer.h
@@ -22,8 +22,7 @@
* Declaration of GHOST_CallbackEventConsumer class.
*/
-#ifndef __GHOST_CALLBACKEVENTCONSUMER_H__
-#define __GHOST_CALLBACKEVENTCONSUMER_H__
+#pragma once
#include "GHOST_C-api.h"
#include "GHOST_IEventConsumer.h"
@@ -66,5 +65,3 @@ class GHOST_CallbackEventConsumer : public GHOST_IEventConsumer {
MEM_CXX_CLASS_ALLOC_FUNCS("GHOST:GHOST_CallbackEventConsumer")
#endif
};
-
-#endif // __GHOST_CALLBACKEVENTCONSUMER_H__
diff --git a/intern/ghost/intern/GHOST_Context.h b/intern/ghost/intern/GHOST_Context.h
index 411a7de5c79..33eeacbb203 100644
--- a/intern/ghost/intern/GHOST_Context.h
+++ b/intern/ghost/intern/GHOST_Context.h
@@ -22,8 +22,7 @@
* Declaration of GHOST_Context class.
*/
-#ifndef __GHOST_CONTEXT_H__
-#define __GHOST_CONTEXT_H__
+#pragma once
#include "GHOST_IContext.h"
#include "GHOST_Types.h"
@@ -160,5 +159,3 @@ bool win32_silent_chk(bool result);
# define WIN32_CHK_SILENT(x, silent) ((silent) ? win32_silent_chk(x) : WIN32_CHK(x))
#endif /* _WIN32 */
-
-#endif // __GHOST_CONTEXT_H__
diff --git a/intern/ghost/intern/GHOST_ContextCGL.h b/intern/ghost/intern/GHOST_ContextCGL.h
index 37c1ac34299..7b1e186dede 100644
--- a/intern/ghost/intern/GHOST_ContextCGL.h
+++ b/intern/ghost/intern/GHOST_ContextCGL.h
@@ -21,8 +21,7 @@
* \ingroup GHOST
*/
-#ifndef __GHOST_CONTEXTCGL_H__
-#define __GHOST_CONTEXTCGL_H__
+#pragma once
#include "GHOST_Context.h"
@@ -137,5 +136,3 @@ class GHOST_ContextCGL : public GHOST_Context {
void metalUpdateFramebuffer();
void metalSwapBuffers();
};
-
-#endif // __GHOST_CONTEXTCGL_H__
diff --git a/intern/ghost/intern/GHOST_ContextD3D.h b/intern/ghost/intern/GHOST_ContextD3D.h
index c482992a6e2..e85516838fc 100644
--- a/intern/ghost/intern/GHOST_ContextD3D.h
+++ b/intern/ghost/intern/GHOST_ContextD3D.h
@@ -18,8 +18,7 @@
* \ingroup GHOST
*/
-#ifndef __GHOST_CONTEXTD3D_H__
-#define __GHOST_CONTEXTD3D_H__
+#pragma once
#ifndef WIN32
# error WIN32 only!
@@ -132,5 +131,3 @@ class GHOST_ContextD3D : public GHOST_Context {
ID3D11Device *m_device;
ID3D11DeviceContext *m_device_ctx;
};
-
-#endif /* __GHOST_CONTEXTD3D_H__ */
diff --git a/intern/ghost/intern/GHOST_ContextEGL.h b/intern/ghost/intern/GHOST_ContextEGL.h
index da5ca7ef93f..e5dae0d22a8 100644
--- a/intern/ghost/intern/GHOST_ContextEGL.h
+++ b/intern/ghost/intern/GHOST_ContextEGL.h
@@ -21,8 +21,7 @@
* \ingroup GHOST
*/
-#ifndef __GHOST_CONTEXTEGL_H__
-#define __GHOST_CONTEXTEGL_H__
+#pragma once
#include "GHOST_Context.h"
@@ -137,5 +136,3 @@ class GHOST_ContextEGL : public GHOST_Context {
static HMODULE s_d3dcompiler;
#endif
};
-
-#endif // __GHOST_CONTEXTEGL_H__
diff --git a/intern/ghost/intern/GHOST_ContextGLX.h b/intern/ghost/intern/GHOST_ContextGLX.h
index 07d2601cd17..e5654b1aed7 100644
--- a/intern/ghost/intern/GHOST_ContextGLX.h
+++ b/intern/ghost/intern/GHOST_ContextGLX.h
@@ -21,8 +21,7 @@
* \ingroup GHOST
*/
-#ifndef __GHOST_CONTEXTGLX_H__
-#define __GHOST_CONTEXTGLX_H__
+#pragma once
#include "GHOST_Context.h"
@@ -128,5 +127,3 @@ class GHOST_ContextGLX : public GHOST_Context {
/* used to get GLX info */
int GHOST_X11_GL_GetAttributes(
int *attribs, int attribs_max, bool is_stereo_visual, bool need_alpha, bool for_fb_config);
-
-#endif // __GHOST_CONTEXTGLX_H__
diff --git a/intern/ghost/intern/GHOST_ContextNone.h b/intern/ghost/intern/GHOST_ContextNone.h
index 2a3c08701b4..b1ac349e4a7 100644
--- a/intern/ghost/intern/GHOST_ContextNone.h
+++ b/intern/ghost/intern/GHOST_ContextNone.h
@@ -23,8 +23,7 @@
* Declaration of GHOST_Context class.
*/
-#ifndef __GHOST_CONTEXTNONE_H__
-#define __GHOST_CONTEXTNONE_H__
+#pragma once
#include "GHOST_Context.h"
@@ -86,5 +85,3 @@ class GHOST_ContextNone : public GHOST_Context {
private:
int m_swapInterval;
};
-
-#endif // __GHOST_CONTEXTNONE_H__
diff --git a/intern/ghost/intern/GHOST_ContextSDL.h b/intern/ghost/intern/GHOST_ContextSDL.h
index 670d930e1e7..ead2e91181c 100644
--- a/intern/ghost/intern/GHOST_ContextSDL.h
+++ b/intern/ghost/intern/GHOST_ContextSDL.h
@@ -21,8 +21,7 @@
* \ingroup GHOST
*/
-#ifndef __GHOST_CONTEXTSDL_H__
-#define __GHOST_CONTEXTSDL_H__
+#pragma once
#include "GHOST_Context.h"
@@ -121,5 +120,3 @@ class GHOST_ContextSDL : public GHOST_Context {
static SDL_GLContext s_sharedContext;
static int s_sharedCount;
};
-
-#endif // __GHOST_CONTEXTSDL_H__
diff --git a/intern/ghost/intern/GHOST_ContextWGL.h b/intern/ghost/intern/GHOST_ContextWGL.h
index a8d2c18b463..087fca100e4 100644
--- a/intern/ghost/intern/GHOST_ContextWGL.h
+++ b/intern/ghost/intern/GHOST_ContextWGL.h
@@ -21,8 +21,7 @@
* \ingroup GHOST
*/
-#ifndef __GHOST_CONTEXTWGL_H__
-#define __GHOST_CONTEXTWGL_H__
+#pragma once
//#define WIN32_COMPOSITING
@@ -130,5 +129,3 @@ class GHOST_ContextWGL : public GHOST_Context {
static HGLRC s_sharedHGLRC;
static int s_sharedCount;
};
-
-#endif // __GHOST_CONTEXTWGL_H__
diff --git a/intern/ghost/intern/GHOST_Debug.h b/intern/ghost/intern/GHOST_Debug.h
index 5b5c2688297..424f95aa573 100644
--- a/intern/ghost/intern/GHOST_Debug.h
+++ b/intern/ghost/intern/GHOST_Debug.h
@@ -22,8 +22,7 @@
* Macro's used in GHOST debug target.
*/
-#ifndef __GHOST_DEBUG_H__
-#define __GHOST_DEBUG_H__
+#pragma once
#ifdef _MSC_VER
# ifdef DEBUG
@@ -79,5 +78,3 @@
#else // WITH_GHOST_DEBUG
# define GHOST_ASSERT(x, info) ((void)0)
#endif // WITH_GHOST_DEBUG
-
-#endif // __GHOST_DEBUG_H__
diff --git a/intern/ghost/intern/GHOST_DisplayManager.h b/intern/ghost/intern/GHOST_DisplayManager.h
index 58b36c0035b..67b9aada55f 100644
--- a/intern/ghost/intern/GHOST_DisplayManager.h
+++ b/intern/ghost/intern/GHOST_DisplayManager.h
@@ -22,8 +22,7 @@
* Declaration of GHOST_DisplayManager class.
*/
-#ifndef __GHOST_DISPLAYMANAGER_H__
-#define __GHOST_DISPLAYMANAGER_H__
+#pragma once
#include "GHOST_Types.h"
@@ -127,5 +126,3 @@ class GHOST_DisplayManager {
MEM_CXX_CLASS_ALLOC_FUNCS("GHOST:GHOST_DisplayManager")
#endif
};
-
-#endif // __GHOST_DISPLAYMANAGER_H__
diff --git a/intern/ghost/intern/GHOST_DisplayManagerCocoa.h b/intern/ghost/intern/GHOST_DisplayManagerCocoa.h
index c99e93279f7..5edd555a78b 100644
--- a/intern/ghost/intern/GHOST_DisplayManagerCocoa.h
+++ b/intern/ghost/intern/GHOST_DisplayManagerCocoa.h
@@ -22,8 +22,7 @@
* Declaration of GHOST_DisplayManagerCocoa class.
*/
-#ifndef __GHOST_DISPLAYMANAGERCOCOA_H__
-#define __GHOST_DISPLAYMANAGERCOCOA_H__
+#pragma once
#ifndef __APPLE__
# error Apple only!
@@ -93,5 +92,3 @@ class GHOST_DisplayManagerCocoa : public GHOST_DisplayManager {
/** Cached display id's for each display. */
// CGDirectDisplayID* m_displayIDs;
};
-
-#endif // __GHOST_DISPLAYMANAGERCOCOA_H__
diff --git a/intern/ghost/intern/GHOST_DisplayManagerNULL.h b/intern/ghost/intern/GHOST_DisplayManagerNULL.h
index 266a3e9a699..4ca06faec12 100644
--- a/intern/ghost/intern/GHOST_DisplayManagerNULL.h
+++ b/intern/ghost/intern/GHOST_DisplayManagerNULL.h
@@ -19,8 +19,7 @@
* Declaration of GHOST_DisplayManagerNULL class.
*/
-#ifndef __GHOST_DISPLAYMANAGERNULL_H__
-#define __GHOST_DISPLAYMANAGERNULL_H__
+#pragma once
#include "GHOST_DisplayManager.h"
#include "GHOST_SystemNULL.h"
@@ -58,5 +57,3 @@ class GHOST_DisplayManagerNULL : public GHOST_DisplayManager {
private:
GHOST_SystemNULL *m_system;
};
-
-#endif /* __GHOST_DISPLAYMANAGERNULL_H__ */
diff --git a/intern/ghost/intern/GHOST_DisplayManagerSDL.h b/intern/ghost/intern/GHOST_DisplayManagerSDL.h
index f7704d57ab0..9a79a842057 100644
--- a/intern/ghost/intern/GHOST_DisplayManagerSDL.h
+++ b/intern/ghost/intern/GHOST_DisplayManagerSDL.h
@@ -19,8 +19,7 @@
* Declaration of GHOST_DisplayManagerSDL class.
*/
-#ifndef __GHOST_DISPLAYMANAGERSDL_H__
-#define __GHOST_DISPLAYMANAGERSDL_H__
+#pragma once
#include "GHOST_DisplayManager.h"
@@ -58,5 +57,3 @@ class GHOST_DisplayManagerSDL : public GHOST_DisplayManager {
GHOST_SystemSDL *m_system;
SDL_DisplayMode m_mode;
};
-
-#endif /* __GHOST_DISPLAYMANAGERSDL_H__ */
diff --git a/intern/ghost/intern/GHOST_DisplayManagerWin32.h b/intern/ghost/intern/GHOST_DisplayManagerWin32.h
index c4ad90b1de7..3392d515c16 100644
--- a/intern/ghost/intern/GHOST_DisplayManagerWin32.h
+++ b/intern/ghost/intern/GHOST_DisplayManagerWin32.h
@@ -22,8 +22,7 @@
* Declaration of GHOST_DisplayManagerWin32 class.
*/
-#ifndef __GHOST_DISPLAYMANAGERWIN32_H__
-#define __GHOST_DISPLAYMANAGERWIN32_H__
+#pragma once
#ifndef WIN32
# error WIN32 only!
@@ -87,5 +86,3 @@ class GHOST_DisplayManagerWin32 : public GHOST_DisplayManager {
protected:
};
-
-#endif // __GHOST_DISPLAYMANAGERWIN32_H__
diff --git a/intern/ghost/intern/GHOST_DisplayManagerX11.h b/intern/ghost/intern/GHOST_DisplayManagerX11.h
index 941152aa034..a36ff8d49f1 100644
--- a/intern/ghost/intern/GHOST_DisplayManagerX11.h
+++ b/intern/ghost/intern/GHOST_DisplayManagerX11.h
@@ -22,8 +22,7 @@
* Declaration of GHOST_DisplayManagerX11 class.
*/
-#ifndef __GHOST_DISPLAYMANAGERX11_H__
-#define __GHOST_DISPLAYMANAGERX11_H__
+#pragma once
#include "GHOST_DisplayManager.h"
@@ -86,5 +85,3 @@ class GHOST_DisplayManagerX11 : public GHOST_DisplayManager {
private:
GHOST_SystemX11 *m_system;
};
-
-#endif //
diff --git a/intern/ghost/intern/GHOST_DropTargetWin32.h b/intern/ghost/intern/GHOST_DropTargetWin32.h
index ee75c017981..ecce3a68835 100644
--- a/intern/ghost/intern/GHOST_DropTargetWin32.h
+++ b/intern/ghost/intern/GHOST_DropTargetWin32.h
@@ -21,8 +21,7 @@
* \ingroup GHOST
*/
-#ifndef __GHOST_DROPTARGETWIN32_H__
-#define __GHOST_DROPTARGETWIN32_H__
+#pragma once
#include "GHOST_SystemWin32.h"
#include "GHOST_WindowWin32.h"
@@ -150,5 +149,3 @@ class GHOST_DropTargetWin32 : public IDropTarget {
MEM_CXX_CLASS_ALLOC_FUNCS("GHOST:GHOST_DropTargetWin32")
#endif
};
-
-#endif // __GHOST_DROPTARGETWIN32_H__
diff --git a/intern/ghost/intern/GHOST_DropTargetX11.h b/intern/ghost/intern/GHOST_DropTargetX11.h
index 9ca12442085..066f2f6bba2 100644
--- a/intern/ghost/intern/GHOST_DropTargetX11.h
+++ b/intern/ghost/intern/GHOST_DropTargetX11.h
@@ -21,8 +21,7 @@
* \ingroup GHOST
*/
-#ifndef __GHOST_DROPTARGETX11_H__
-#define __GHOST_DROPTARGETX11_H__
+#pragma once
#include "GHOST_SystemX11.h"
#include "GHOST_WindowX11.h"
@@ -126,5 +125,3 @@ class GHOST_DropTargetX11 {
MEM_CXX_CLASS_ALLOC_FUNCS("GHOST:GHOST_DropTargetX11")
#endif
};
-
-#endif // __GHOST_DROPTARGETX11_H__
diff --git a/intern/ghost/intern/GHOST_Event.h b/intern/ghost/intern/GHOST_Event.h
index 2c14df7f243..845d62fa810 100644
--- a/intern/ghost/intern/GHOST_Event.h
+++ b/intern/ghost/intern/GHOST_Event.h
@@ -22,8 +22,7 @@
* Declaration of GHOST_Event class.
*/
-#ifndef __GHOST_EVENT_H__
-#define __GHOST_EVENT_H__
+#pragma once
#include "GHOST_IEvent.h"
@@ -90,5 +89,3 @@ class GHOST_Event : public GHOST_IEvent {
/** Pointer to the event data. */
GHOST_TEventDataPtr m_data;
};
-
-#endif // __GHOST_EVENT_H__
diff --git a/intern/ghost/intern/GHOST_EventButton.h b/intern/ghost/intern/GHOST_EventButton.h
index 4247ae150a4..7072e0c5409 100644
--- a/intern/ghost/intern/GHOST_EventButton.h
+++ b/intern/ghost/intern/GHOST_EventButton.h
@@ -22,8 +22,7 @@
* Declaration of GHOST_EventButton class.
*/
-#ifndef __GHOST_EVENTBUTTON_H__
-#define __GHOST_EVENTBUTTON_H__
+#pragma once
#include "GHOST_Event.h"
#include "GHOST_Window.h"
@@ -57,5 +56,3 @@ class GHOST_EventButton : public GHOST_Event {
/** The button event data. */
GHOST_TEventButtonData m_buttonEventData;
};
-
-#endif // __GHOST_EVENTBUTTON_H__
diff --git a/intern/ghost/intern/GHOST_EventCursor.h b/intern/ghost/intern/GHOST_EventCursor.h
index 8ba657fd9fa..ba85cd74723 100644
--- a/intern/ghost/intern/GHOST_EventCursor.h
+++ b/intern/ghost/intern/GHOST_EventCursor.h
@@ -22,8 +22,7 @@
* Declaration of GHOST_EventCursor class.
*/
-#ifndef __GHOST_EVENTCURSOR_H__
-#define __GHOST_EVENTCURSOR_H__
+#pragma once
#include "GHOST_Event.h"
@@ -58,5 +57,3 @@ class GHOST_EventCursor : public GHOST_Event {
/** The x,y-coordinates of the cursor position. */
GHOST_TEventCursorData m_cursorEventData;
};
-
-#endif // __GHOST_EVENTCURSOR_H__
diff --git a/intern/ghost/intern/GHOST_EventDragnDrop.h b/intern/ghost/intern/GHOST_EventDragnDrop.h
index 36291e8a254..10975792993 100644
--- a/intern/ghost/intern/GHOST_EventDragnDrop.h
+++ b/intern/ghost/intern/GHOST_EventDragnDrop.h
@@ -21,8 +21,7 @@
* \ingroup GHOST
*/
-#ifndef __GHOST_EVENTDRAGNDROP_H__
-#define __GHOST_EVENTDRAGNDROP_H__
+#pragma once
#include "GHOST_Event.h"
extern "C" {
@@ -122,5 +121,3 @@ class GHOST_EventDragnDrop : public GHOST_Event {
/** The x,y-coordinates of the cursor position. */
GHOST_TEventDragnDropData m_dragnDropEventData;
};
-
-#endif // __GHOST_EVENTDRAGNDROP_H__
diff --git a/intern/ghost/intern/GHOST_EventKey.h b/intern/ghost/intern/GHOST_EventKey.h
index 8f59c555914..cb71b452d80 100644
--- a/intern/ghost/intern/GHOST_EventKey.h
+++ b/intern/ghost/intern/GHOST_EventKey.h
@@ -22,8 +22,7 @@
* Declaration of GHOST_EventKey class.
*/
-#ifndef __GHOST_EVENTKEY_H__
-#define __GHOST_EVENTKEY_H__
+#pragma once
#include <string.h>
@@ -84,5 +83,3 @@ class GHOST_EventKey : public GHOST_Event {
/** The key event data. */
GHOST_TEventKeyData m_keyEventData;
};
-
-#endif // __GHOST_EVENTKEY_H__
diff --git a/intern/ghost/intern/GHOST_EventManager.h b/intern/ghost/intern/GHOST_EventManager.h
index ada5abda89b..befbdc72a5c 100644
--- a/intern/ghost/intern/GHOST_EventManager.h
+++ b/intern/ghost/intern/GHOST_EventManager.h
@@ -22,8 +22,7 @@
* Declaration of GHOST_EventManager class.
*/
-#ifndef __GHOST_EVENTMANAGER_H__
-#define __GHOST_EVENTMANAGER_H__
+#pragma once
#include <deque>
#include <vector>
@@ -140,5 +139,3 @@ class GHOST_EventManager {
MEM_CXX_CLASS_ALLOC_FUNCS("GHOST:GHOST_EventManager")
#endif
};
-
-#endif // __GHOST_EVENTMANAGER_H__
diff --git a/intern/ghost/intern/GHOST_EventNDOF.h b/intern/ghost/intern/GHOST_EventNDOF.h
index 196d3868ccd..64e67434b74 100644
--- a/intern/ghost/intern/GHOST_EventNDOF.h
+++ b/intern/ghost/intern/GHOST_EventNDOF.h
@@ -18,8 +18,7 @@
* \ingroup GHOST
*/
-#ifndef __GHOST_EVENTNDOF_H__
-#define __GHOST_EVENTNDOF_H__
+#pragma once
#ifndef WITH_INPUT_NDOF
# error NDOF code included in non-NDOF-enabled build
@@ -50,5 +49,3 @@ class GHOST_EventNDOFButton : public GHOST_Event {
m_data = &m_buttonData;
}
};
-
-#endif // __GHOST_EVENTNDOF_H__
diff --git a/intern/ghost/intern/GHOST_EventPrinter.h b/intern/ghost/intern/GHOST_EventPrinter.h
index ead16525ec6..42de4da5ee5 100644
--- a/intern/ghost/intern/GHOST_EventPrinter.h
+++ b/intern/ghost/intern/GHOST_EventPrinter.h
@@ -22,8 +22,7 @@
* Declaration of GHOST_EventPrinter class.
*/
-#ifndef __GHOST_EVENTPRINTER_H__
-#define __GHOST_EVENTPRINTER_H__
+#pragma once
#include "GHOST_IEventConsumer.h"
@@ -48,5 +47,3 @@ class GHOST_EventPrinter : public GHOST_IEventConsumer {
*/
void getKeyString(GHOST_TKey key, char str[32]) const;
};
-
-#endif // __GHOST_EVENTPRINTER_H__
diff --git a/intern/ghost/intern/GHOST_EventString.h b/intern/ghost/intern/GHOST_EventString.h
index f0d3ffb9e91..8cd24a8a78b 100644
--- a/intern/ghost/intern/GHOST_EventString.h
+++ b/intern/ghost/intern/GHOST_EventString.h
@@ -22,8 +22,7 @@
* Declaration of GHOST_EventString class.
*/
-#ifndef __GHOST_EVENTSTRING_H__
-#define __GHOST_EVENTSTRING_H__
+#pragma once
#include "GHOST_Event.h"
@@ -54,5 +53,3 @@ class GHOST_EventString : public GHOST_Event {
free(m_data);
}
};
-
-#endif // __GHOST_EVENTSTRING_H__
diff --git a/intern/ghost/intern/GHOST_EventTrackpad.h b/intern/ghost/intern/GHOST_EventTrackpad.h
index 795e969b16d..a22f8a34fad 100644
--- a/intern/ghost/intern/GHOST_EventTrackpad.h
+++ b/intern/ghost/intern/GHOST_EventTrackpad.h
@@ -22,8 +22,7 @@
* Declaration of GHOST_EventTrackpad class.
*/
-#ifndef __GHOST_EVENTTRACKPAD_H__
-#define __GHOST_EVENTTRACKPAD_H__
+#pragma once
#include "GHOST_Event.h"
@@ -61,5 +60,3 @@ class GHOST_EventTrackpad : public GHOST_Event {
/** The mouse pan data */
GHOST_TEventTrackpadData m_trackpadEventData;
};
-
-#endif // _GHOST_EVENT_PAN_H_
diff --git a/intern/ghost/intern/GHOST_EventWheel.h b/intern/ghost/intern/GHOST_EventWheel.h
index 4d3eeb9cd83..ea62e02d08d 100644
--- a/intern/ghost/intern/GHOST_EventWheel.h
+++ b/intern/ghost/intern/GHOST_EventWheel.h
@@ -22,8 +22,7 @@
* Declaration of GHOST_EventWheel class.
*/
-#ifndef __GHOST_EVENTWHEEL_H__
-#define __GHOST_EVENTWHEEL_H__
+#pragma once
#include "GHOST_Event.h"
@@ -51,5 +50,3 @@ class GHOST_EventWheel : public GHOST_Event {
/** The z-displacement of the mouse wheel. */
GHOST_TEventWheelData m_wheelEventData;
};
-
-#endif // __GHOST_EVENTWHEEL_H__
diff --git a/intern/ghost/intern/GHOST_IXrGraphicsBinding.h b/intern/ghost/intern/GHOST_IXrGraphicsBinding.h
index b199c5f9b28..de8bf9f1a5a 100644
--- a/intern/ghost/intern/GHOST_IXrGraphicsBinding.h
+++ b/intern/ghost/intern/GHOST_IXrGraphicsBinding.h
@@ -18,8 +18,7 @@
* \ingroup GHOST
*/
-#ifndef __GHOST_IXRGRAPHICSBINDING_H__
-#define __GHOST_IXRGRAPHICSBINDING_H__
+#pragma once
#include <memory>
#include <string>
@@ -71,5 +70,3 @@ class GHOST_IXrGraphicsBinding {
std::unique_ptr<GHOST_IXrGraphicsBinding> GHOST_XrGraphicsBindingCreateFromType(
GHOST_TXrGraphicsBinding type, GHOST_Context *ghost_ctx);
-
-#endif /* __GHOST_IXRGRAPHICSBINDING_H__ */
diff --git a/intern/ghost/intern/GHOST_IconX11.h b/intern/ghost/intern/GHOST_IconX11.h
index c5bcf4bedeb..615a7dae6b5 100644
--- a/intern/ghost/intern/GHOST_IconX11.h
+++ b/intern/ghost/intern/GHOST_IconX11.h
@@ -22,8 +22,7 @@
* Icon image data for X11.
*/
-#ifndef __GHOST_ICONX11_H__
-#define __GHOST_ICONX11_H__
+#pragma once
/*
* import bpy
@@ -1013,5 +1012,3 @@ static const unsigned long BLENDER_ICONS_WM_X11[] = {
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
};
-
-#endif // __GHOST_ICONX11_H__
diff --git a/intern/ghost/intern/GHOST_ImeWin32.h b/intern/ghost/intern/GHOST_ImeWin32.h
index 112217023a7..74698d50659 100644
--- a/intern/ghost/intern/GHOST_ImeWin32.h
+++ b/intern/ghost/intern/GHOST_ImeWin32.h
@@ -23,8 +23,7 @@
* \ingroup GHOST
*/
-#ifndef __GHOST_IME_H__
-#define __GHOST_IME_H__
+#pragma once
#ifdef WITH_INPUT_IME
@@ -388,4 +387,3 @@ class GHOST_ImeWin32 {
};
#endif // WITH_INPUT_IME
-#endif // __GHOST_IME_H__
diff --git a/intern/ghost/intern/GHOST_ModifierKeys.h b/intern/ghost/intern/GHOST_ModifierKeys.h
index 27ad4034068..c41ce8b7f39 100644
--- a/intern/ghost/intern/GHOST_ModifierKeys.h
+++ b/intern/ghost/intern/GHOST_ModifierKeys.h
@@ -22,8 +22,7 @@
* Declaration of GHOST_ModifierKeys struct.
*/
-#ifndef __GHOST_MODIFIERKEYS_H__
-#define __GHOST_MODIFIERKEYS_H__
+#pragma once
#include "GHOST_Types.h"
@@ -87,5 +86,3 @@ struct GHOST_ModifierKeys {
/** Bitfield that stores the appropriate key state. */
GHOST_TUns8 m_OS : 1;
};
-
-#endif // __GHOST_MODIFIERKEYS_H__
diff --git a/intern/ghost/intern/GHOST_NDOFManager.h b/intern/ghost/intern/GHOST_NDOFManager.h
index a190607ca66..d0b49bc13c2 100644
--- a/intern/ghost/intern/GHOST_NDOFManager.h
+++ b/intern/ghost/intern/GHOST_NDOFManager.h
@@ -14,8 +14,7 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __GHOST_NDOFMANAGER_H__
-#define __GHOST_NDOFMANAGER_H__
+#pragma once
#ifndef WITH_INPUT_NDOF
# error NDOF code included in non-NDOF-enabled build
@@ -167,5 +166,3 @@ class GHOST_NDOFManager {
bool m_motionEventPending;
float m_deadZone; // discard motion with each component < this
};
-
-#endif
diff --git a/intern/ghost/intern/GHOST_NDOFManagerCocoa.h b/intern/ghost/intern/GHOST_NDOFManagerCocoa.h
index bd1e6903f94..f7c3599502e 100644
--- a/intern/ghost/intern/GHOST_NDOFManagerCocoa.h
+++ b/intern/ghost/intern/GHOST_NDOFManagerCocoa.h
@@ -14,8 +14,7 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __GHOST_NDOFMANAGERCOCOA_H__
-#define __GHOST_NDOFMANAGERCOCOA_H__
+#pragma once
#include "GHOST_NDOFManager.h"
@@ -29,5 +28,3 @@ class GHOST_NDOFManagerCocoa : public GHOST_NDOFManager {
bool available();
};
-
-#endif // #include guard
diff --git a/intern/ghost/intern/GHOST_NDOFManagerUnix.h b/intern/ghost/intern/GHOST_NDOFManagerUnix.h
index 75bd022631a..6dd4289ffac 100644
--- a/intern/ghost/intern/GHOST_NDOFManagerUnix.h
+++ b/intern/ghost/intern/GHOST_NDOFManagerUnix.h
@@ -14,8 +14,7 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __GHOST_NDOFMANAGERUNIX_H__
-#define __GHOST_NDOFMANAGERUNIX_H__
+#pragma once
#include "GHOST_NDOFManager.h"
@@ -32,5 +31,3 @@ class GHOST_NDOFManagerUnix : public GHOST_NDOFManager {
private:
bool m_available;
};
-
-#endif /* __GHOST_NDOFMANAGERUNIX_H__ */
diff --git a/intern/ghost/intern/GHOST_NDOFManagerWin32.h b/intern/ghost/intern/GHOST_NDOFManagerWin32.h
index 9ed5e6ab978..62d9b9207dc 100644
--- a/intern/ghost/intern/GHOST_NDOFManagerWin32.h
+++ b/intern/ghost/intern/GHOST_NDOFManagerWin32.h
@@ -14,8 +14,7 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __GHOST_NDOFMANAGERWIN32_H__
-#define __GHOST_NDOFMANAGERWIN32_H__
+#pragma once
#include "GHOST_NDOFManager.h"
@@ -24,5 +23,3 @@ class GHOST_NDOFManagerWin32 : public GHOST_NDOFManager {
GHOST_NDOFManagerWin32(GHOST_System &);
bool available();
};
-
-#endif // #include guard
diff --git a/intern/ghost/intern/GHOST_System.h b/intern/ghost/intern/GHOST_System.h
index c2d712c11cd..e29a9ba0c29 100644
--- a/intern/ghost/intern/GHOST_System.h
+++ b/intern/ghost/intern/GHOST_System.h
@@ -22,8 +22,7 @@
* Declaration of GHOST_System class.
*/
-#ifndef __GHOST_SYSTEM_H__
-#define __GHOST_SYSTEM_H__
+#pragma once
#include "GHOST_ISystem.h"
@@ -424,5 +423,3 @@ inline GHOST_NDOFManager *GHOST_System::getNDOFManager() const
return m_ndofManager;
}
#endif
-
-#endif // __GHOST_SYSTEM_H__
diff --git a/intern/ghost/intern/GHOST_SystemCocoa.h b/intern/ghost/intern/GHOST_SystemCocoa.h
index bbd6f1d8995..8e36cebb88a 100644
--- a/intern/ghost/intern/GHOST_SystemCocoa.h
+++ b/intern/ghost/intern/GHOST_SystemCocoa.h
@@ -22,8 +22,7 @@
* Declaration of GHOST_SystemCocoa class.
*/
-#ifndef __GHOST_SYSTEMCOCOA_H__
-#define __GHOST_SYSTEMCOCOA_H__
+#pragma once
#ifndef __APPLE__
# error Apple OSX only!
@@ -313,5 +312,3 @@ class GHOST_SystemCocoa : public GHOST_System {
/** Is the scroll wheel event generated by a multitouch trackpad or mouse? */
bool m_multiTouchScroll;
};
-
-#endif // __GHOST_SYSTEMCOCOA_H__
diff --git a/intern/ghost/intern/GHOST_SystemNULL.h b/intern/ghost/intern/GHOST_SystemNULL.h
index 186cb92d1aa..5becf110b15 100644
--- a/intern/ghost/intern/GHOST_SystemNULL.h
+++ b/intern/ghost/intern/GHOST_SystemNULL.h
@@ -19,8 +19,7 @@
* Declaration of GHOST_SystemNULL class.
*/
-#ifndef __GHOST_SYSTEMNULL_H__
-#define __GHOST_SYSTEMNULL_H__
+#pragma once
#include "../GHOST_Types.h"
#include "GHOST_DisplayManagerNULL.h"
@@ -130,5 +129,3 @@ class GHOST_SystemNULL : public GHOST_System {
((glSettings.flags & GHOST_glStereoVisual) != 0));
}
};
-
-#endif /* __GHOST_SYSTEMNULL_H__ */
diff --git a/intern/ghost/intern/GHOST_SystemPaths.h b/intern/ghost/intern/GHOST_SystemPaths.h
index 04180a143cb..ab53b2813cd 100644
--- a/intern/ghost/intern/GHOST_SystemPaths.h
+++ b/intern/ghost/intern/GHOST_SystemPaths.h
@@ -21,8 +21,7 @@
* \ingroup GHOST
*/
-#ifndef __GHOST_SYSTEMPATHS_H__
-#define __GHOST_SYSTEMPATHS_H__
+#pragma once
#include "GHOST_ISystemPaths.h"
@@ -70,5 +69,3 @@ class GHOST_SystemPaths : public GHOST_ISystemPaths {
*/
virtual void addToSystemRecentFiles(const char *filename) const = 0;
};
-
-#endif
diff --git a/intern/ghost/intern/GHOST_SystemPathsCocoa.h b/intern/ghost/intern/GHOST_SystemPathsCocoa.h
index b66379649e7..188f6f02286 100644
--- a/intern/ghost/intern/GHOST_SystemPathsCocoa.h
+++ b/intern/ghost/intern/GHOST_SystemPathsCocoa.h
@@ -21,8 +21,7 @@
* \ingroup GHOST
*/
-#ifndef __GHOST_SYSTEMPATHSCOCOA_H__
-#define __GHOST_SYSTEMPATHSCOCOA_H__
+#pragma once
#ifndef __APPLE__
# error Apple OSX only!
@@ -67,5 +66,3 @@ class GHOST_SystemPathsCocoa : public GHOST_SystemPaths {
*/
void addToSystemRecentFiles(const char *filename) const;
};
-
-#endif // __GHOST_SYSTEMPATHSCOCOA_H__
diff --git a/intern/ghost/intern/GHOST_SystemPathsUnix.h b/intern/ghost/intern/GHOST_SystemPathsUnix.h
index f9f89f6e79b..8d2f26a28aa 100644
--- a/intern/ghost/intern/GHOST_SystemPathsUnix.h
+++ b/intern/ghost/intern/GHOST_SystemPathsUnix.h
@@ -21,8 +21,7 @@
* \ingroup GHOST
*/
-#ifndef __GHOST_SYSTEMPATHSUNIX_H__
-#define __GHOST_SYSTEMPATHSUNIX_H__
+#pragma once
#include "../GHOST_Types.h"
#include "GHOST_SystemPaths.h"
@@ -65,5 +64,3 @@ class GHOST_SystemPathsUnix : public GHOST_SystemPaths {
*/
void addToSystemRecentFiles(const char *filename) const;
};
-
-#endif /* __GHOST_SYSTEMPATHSUNIX_H__ */
diff --git a/intern/ghost/intern/GHOST_SystemPathsWin32.h b/intern/ghost/intern/GHOST_SystemPathsWin32.h
index f1924ea51bc..1a1eab21bad 100644
--- a/intern/ghost/intern/GHOST_SystemPathsWin32.h
+++ b/intern/ghost/intern/GHOST_SystemPathsWin32.h
@@ -21,8 +21,7 @@
* \ingroup GHOST
*/
-#ifndef __GHOST_SYSTEMPATHSWIN32_H__
-#define __GHOST_SYSTEMPATHSWIN32_H__
+#pragma once
#ifndef WIN32
# error WIN32 only!
@@ -74,5 +73,3 @@ class GHOST_SystemPathsWin32 : public GHOST_SystemPaths {
*/
void addToSystemRecentFiles(const char *filename) const;
};
-
-#endif // __GHOST_SYSTEMPATHSWIN32_H__
diff --git a/intern/ghost/intern/GHOST_SystemSDL.h b/intern/ghost/intern/GHOST_SystemSDL.h
index 8feec9de61d..4b2c52f8282 100644
--- a/intern/ghost/intern/GHOST_SystemSDL.h
+++ b/intern/ghost/intern/GHOST_SystemSDL.h
@@ -19,8 +19,7 @@
* Declaration of GHOST_SystemSDL class.
*/
-#ifndef __GHOST_SYSTEMSDL_H__
-#define __GHOST_SYSTEMSDL_H__
+#pragma once
#include "../GHOST_Types.h"
#include "GHOST_DisplayManagerSDL.h"
@@ -102,5 +101,3 @@ class GHOST_SystemSDL : public GHOST_System {
/// The vector of windows that need to be updated.
std::vector<GHOST_WindowSDL *> m_dirty_windows;
};
-
-#endif
diff --git a/intern/ghost/intern/GHOST_SystemWayland.h b/intern/ghost/intern/GHOST_SystemWayland.h
index 89cd3406b69..30ee7679287 100644
--- a/intern/ghost/intern/GHOST_SystemWayland.h
+++ b/intern/ghost/intern/GHOST_SystemWayland.h
@@ -19,8 +19,7 @@
* Declaration of GHOST_SystemWayland class.
*/
-#ifndef __GHOST_SYSTEMWAYLAND_H__
-#define __GHOST_SYSTEMWAYLAND_H__
+#pragma once
#include "../GHOST_Types.h"
#include "GHOST_System.h"
@@ -107,5 +106,3 @@ class GHOST_SystemWayland : public GHOST_System {
struct display_t *d;
std::string selection;
};
-
-#endif /* __GHOST_SYSTEMWAYLAND_H__ */
diff --git a/intern/ghost/intern/GHOST_SystemWin32.cpp b/intern/ghost/intern/GHOST_SystemWin32.cpp
index 849aa5a96f5..f59b106afd6 100644
--- a/intern/ghost/intern/GHOST_SystemWin32.cpp
+++ b/intern/ghost/intern/GHOST_SystemWin32.cpp
@@ -1143,10 +1143,16 @@ GHOST_EventKey *GHOST_SystemWin32::processKeyEvent(GHOST_WindowWin32 *window, RA
BYTE state[256] = {0};
int r;
GetKeyboardState((PBYTE)state);
+ bool ctrl_pressed = state[VK_CONTROL] & 0x80;
+ bool alt_pressed = state[VK_MENU] & 0x80;
+ /* No text with control key pressed (Alt can be used to insert special characters though!). */
+ if (ctrl_pressed && !alt_pressed) {
+ utf8_char[0] = '\0';
+ }
// Don't call ToUnicodeEx on dead keys as it clears the buffer and so won't allow diacritical
// composition.
- if (MapVirtualKeyW(vk, 2) != 0) {
+ else if (MapVirtualKeyW(vk, 2) != 0) {
// todo: ToUnicodeEx can respond with up to 4 utf16 chars (only 2 here).
// Could be up to 24 utf8 bytes.
if ((r = ToUnicodeEx(
diff --git a/intern/ghost/intern/GHOST_SystemWin32.h b/intern/ghost/intern/GHOST_SystemWin32.h
index 6b7901c2ade..24925b9c403 100644
--- a/intern/ghost/intern/GHOST_SystemWin32.h
+++ b/intern/ghost/intern/GHOST_SystemWin32.h
@@ -22,8 +22,7 @@
* Declaration of GHOST_SystemWin32 class.
*/
-#ifndef __GHOST_SYSTEMWIN32_H__
-#define __GHOST_SYSTEMWIN32_H__
+#pragma once
#ifndef WIN32
# error WIN32 only!
@@ -488,4 +487,3 @@ inline void GHOST_SystemWin32::handleKeyboardChange(void)
}
}
}
-#endif // __GHOST_SYSTEMWIN32_H__
diff --git a/intern/ghost/intern/GHOST_SystemX11.h b/intern/ghost/intern/GHOST_SystemX11.h
index 5888605ec95..ad58138d416 100644
--- a/intern/ghost/intern/GHOST_SystemX11.h
+++ b/intern/ghost/intern/GHOST_SystemX11.h
@@ -22,8 +22,7 @@
* Declaration of GHOST_SystemX11 class.
*/
-#ifndef __GHOST_SYSTEMX11_H__
-#define __GHOST_SYSTEMX11_H__
+#pragma once
#include <X11/XKBlib.h> /* allow detectable autorepeate */
#include <X11/Xlib.h>
@@ -392,5 +391,3 @@ class GHOST_SystemX11 : public GHOST_System {
bool generateWindowExposeEvents();
};
-
-#endif
diff --git a/intern/ghost/intern/GHOST_TaskbarWin32.h b/intern/ghost/intern/GHOST_TaskbarWin32.h
index 58641123c24..e6464f5e626 100644
--- a/intern/ghost/intern/GHOST_TaskbarWin32.h
+++ b/intern/ghost/intern/GHOST_TaskbarWin32.h
@@ -17,8 +17,7 @@
/** \file
* \ingroup GHOST
*/
-#ifndef __GHOST_TASKBARWIN32_H__
-#define __GHOST_TASKBARWIN32_H__
+#pragma once
#ifndef WIN32
# error WIN32 only!
@@ -128,5 +127,3 @@ class ITaskbarList3 : public ITaskbarList2 {
virtual HRESULT STDMETHODCALLTYPE SetThumbnailClip(HWND hwnd, RECT *prcClip) = 0;
};
#endif /* ITaskbarList3 */
-
-#endif /*__GHOST_TASKBARWIN32_H__*/
diff --git a/intern/ghost/intern/GHOST_TaskbarX11.h b/intern/ghost/intern/GHOST_TaskbarX11.h
index cd00e25106c..25de5aa9511 100644
--- a/intern/ghost/intern/GHOST_TaskbarX11.h
+++ b/intern/ghost/intern/GHOST_TaskbarX11.h
@@ -17,8 +17,7 @@
/** \file
* \ingroup GHOST
*/
-#ifndef __GHOST_TASKBARX11_H__
-#define __GHOST_TASKBARX11_H__
+#pragma once
class GHOST_TaskBarX11 {
public:
@@ -34,5 +33,3 @@ class GHOST_TaskBarX11 {
private:
void *handle;
};
-
-#endif /*__GHOST_TASKBARX11_H__*/
diff --git a/intern/ghost/intern/GHOST_TimerManager.h b/intern/ghost/intern/GHOST_TimerManager.h
index 039663a7a0e..2e0f5d42230 100644
--- a/intern/ghost/intern/GHOST_TimerManager.h
+++ b/intern/ghost/intern/GHOST_TimerManager.h
@@ -22,8 +22,7 @@
* Declaration of GHOST_TimerManager class.
*/
-#ifndef __GHOST_TIMERMANAGER_H__
-#define __GHOST_TIMERMANAGER_H__
+#pragma once
#include <vector>
@@ -112,5 +111,3 @@ class GHOST_TimerManager {
MEM_CXX_CLASS_ALLOC_FUNCS("GHOST:GHOST_TimerManager")
#endif
};
-
-#endif // __GHOST_TIMERMANAGER_H__
diff --git a/intern/ghost/intern/GHOST_TimerTask.h b/intern/ghost/intern/GHOST_TimerTask.h
index 561d9b3e705..6dc0728e19b 100644
--- a/intern/ghost/intern/GHOST_TimerTask.h
+++ b/intern/ghost/intern/GHOST_TimerTask.h
@@ -22,8 +22,7 @@
* Declaration of GHOST_TimerTask class.
*/
-#ifndef __GHOST_TIMERTASK_H__
-#define __GHOST_TIMERTASK_H__
+#pragma once
#include "GHOST_ITimerTask.h"
@@ -179,5 +178,3 @@ class GHOST_TimerTask : public GHOST_ITimerTask {
/** Auxiliary storage room. */
GHOST_TUns32 m_auxData;
};
-
-#endif // __GHOST_TIMERTASK_H__
diff --git a/intern/ghost/intern/GHOST_Window.h b/intern/ghost/intern/GHOST_Window.h
index 7cfea5110c5..c8c21b2b08f 100644
--- a/intern/ghost/intern/GHOST_Window.h
+++ b/intern/ghost/intern/GHOST_Window.h
@@ -22,8 +22,7 @@
* Declaration of GHOST_Window class.
*/
-#ifndef __GHOST_WINDOW_H__
-#define __GHOST_WINDOW_H__
+#pragma once
#include "GHOST_IWindow.h"
@@ -456,5 +455,3 @@ inline GHOST_TStandardCursor GHOST_Window::getCursorShape() const
{
return m_cursorShape;
}
-
-#endif // _GHOST_WINDOW_H
diff --git a/intern/ghost/intern/GHOST_WindowCocoa.h b/intern/ghost/intern/GHOST_WindowCocoa.h
index 15429eab5db..97486c9e77a 100644
--- a/intern/ghost/intern/GHOST_WindowCocoa.h
+++ b/intern/ghost/intern/GHOST_WindowCocoa.h
@@ -22,8 +22,7 @@
* Declaration of GHOST_WindowCocoa class.
*/
-#ifndef __GHOST_WINDOWCOCOA_H__
-#define __GHOST_WINDOWCOCOA_H__
+#pragma once
#ifndef __APPLE__
# error Apple OSX only!
@@ -327,5 +326,3 @@ class GHOST_WindowCocoa : public GHOST_Window {
bool m_debug_context; // for debug messages during context setup
bool m_is_dialog;
};
-
-#endif // __GHOST_WINDOWCOCOA_H__
diff --git a/intern/ghost/intern/GHOST_WindowManager.h b/intern/ghost/intern/GHOST_WindowManager.h
index 661439191c5..34fdfd30f27 100644
--- a/intern/ghost/intern/GHOST_WindowManager.h
+++ b/intern/ghost/intern/GHOST_WindowManager.h
@@ -22,8 +22,7 @@
* Declaration of GHOST_WindowManager class.
*/
-#ifndef __GHOST_WINDOWMANAGER_H__
-#define __GHOST_WINDOWMANAGER_H__
+#pragma once
#include <vector>
@@ -149,5 +148,3 @@ class GHOST_WindowManager {
MEM_CXX_CLASS_ALLOC_FUNCS("GHOST:GHOST_WindowManager")
#endif
};
-
-#endif // __GHOST_WINDOWMANAGER_H__
diff --git a/intern/ghost/intern/GHOST_WindowNULL.h b/intern/ghost/intern/GHOST_WindowNULL.h
index e1aa0cb7f13..0b5a7ee3450 100644
--- a/intern/ghost/intern/GHOST_WindowNULL.h
+++ b/intern/ghost/intern/GHOST_WindowNULL.h
@@ -19,8 +19,7 @@
* Declaration of GHOST_WindowNULL class.
*/
-#ifndef __GHOST_WINDOWNULL_H__
-#define __GHOST_WINDOWNULL_H__
+#pragma once
#include "GHOST_Window.h"
@@ -177,5 +176,3 @@ class GHOST_WindowNULL : public GHOST_Window {
return NULL;
}
};
-
-#endif // __GHOST_WINDOWNULL_H__
diff --git a/intern/ghost/intern/GHOST_WindowSDL.h b/intern/ghost/intern/GHOST_WindowSDL.h
index 5039c742c9d..643c54c282e 100644
--- a/intern/ghost/intern/GHOST_WindowSDL.h
+++ b/intern/ghost/intern/GHOST_WindowSDL.h
@@ -19,8 +19,7 @@
* Declaration of GHOST_WindowSDL class.
*/
-#ifndef __GHOST_WINDOWSDL_H__
-#define __GHOST_WINDOWSDL_H__
+#pragma once
#include "GHOST_SystemSDL.h"
#include "GHOST_Window.h"
@@ -149,5 +148,3 @@ class GHOST_WindowSDL : public GHOST_Window {
GHOST_TUns16 getDPIHint();
};
-
-#endif // __GHOST_WINDOWSDL_H__
diff --git a/intern/ghost/intern/GHOST_WindowWayland.h b/intern/ghost/intern/GHOST_WindowWayland.h
index ff1eb60e154..1ee41f4d0f6 100644
--- a/intern/ghost/intern/GHOST_WindowWayland.h
+++ b/intern/ghost/intern/GHOST_WindowWayland.h
@@ -20,8 +20,7 @@
* Declaration of GHOST_WindowWayland class.
*/
-#ifndef __GHOST_WINDOWWAYLAND_H__
-#define __GHOST_WINDOWWAYLAND_H__
+#pragma once
#include "GHOST_Window.h"
@@ -124,5 +123,3 @@ class GHOST_WindowWayland : public GHOST_Window {
*/
GHOST_Context *newDrawingContext(GHOST_TDrawingContextType type) override;
};
-
-#endif // __GHOST_WINDOWWAYLAND_H__
diff --git a/intern/ghost/intern/GHOST_WindowWin32.h b/intern/ghost/intern/GHOST_WindowWin32.h
index dbed7c5ee5f..224ff53bf7b 100644
--- a/intern/ghost/intern/GHOST_WindowWin32.h
+++ b/intern/ghost/intern/GHOST_WindowWin32.h
@@ -22,8 +22,7 @@
* Declaration of GHOST_WindowWin32 class.
*/
-#ifndef __GHOST_WINDOWWIN32_H__
-#define __GHOST_WINDOWWIN32_H__
+#pragma once
#ifndef WIN32
# error WIN32 only!
@@ -586,5 +585,3 @@ class GHOST_WindowWin32 : public GHOST_Window {
#endif
bool m_debug_context;
};
-
-#endif // __GHOST_WINDOWWIN32_H__
diff --git a/intern/ghost/intern/GHOST_WindowX11.h b/intern/ghost/intern/GHOST_WindowX11.h
index 4232ff40b52..ef5d1755f1a 100644
--- a/intern/ghost/intern/GHOST_WindowX11.h
+++ b/intern/ghost/intern/GHOST_WindowX11.h
@@ -22,8 +22,7 @@
* Declaration of GHOST_WindowX11 class.
*/
-#ifndef __GHOST_WINDOWX11_H__
-#define __GHOST_WINDOWX11_H__
+#pragma once
#include "GHOST_Window.h"
#include <X11/Xlib.h>
@@ -288,5 +287,3 @@ class GHOST_WindowX11 : public GHOST_Window {
void motifFullScreen(bool set);
bool motifIsFullScreen() const;
};
-
-#endif // __GHOST_WINDOWX11_H__
diff --git a/intern/ghost/intern/GHOST_XrContext.h b/intern/ghost/intern/GHOST_XrContext.h
index 9be57cd90cc..d2edb40c080 100644
--- a/intern/ghost/intern/GHOST_XrContext.h
+++ b/intern/ghost/intern/GHOST_XrContext.h
@@ -18,8 +18,7 @@
* \ingroup GHOST
*/
-#ifndef __GHOST_XRCONTEXT_H__
-#define __GHOST_XRCONTEXT_H__
+#pragma once
#include <memory>
#include <vector>
@@ -131,5 +130,3 @@ class GHOST_XrContext : public GHOST_IXrContext {
GHOST_TXrGraphicsBinding determineGraphicsBindingTypeToEnable(
const GHOST_XrContextCreateInfo *create_info);
};
-
-#endif // __GHOST_XRCONTEXT_H__
diff --git a/intern/ghost/intern/GHOST_XrException.h b/intern/ghost/intern/GHOST_XrException.h
index 9f779961e4f..30c33eaf98f 100644
--- a/intern/ghost/intern/GHOST_XrException.h
+++ b/intern/ghost/intern/GHOST_XrException.h
@@ -18,8 +18,7 @@
* \ingroup GHOST
*/
-#ifndef __GHOST_XREXCEPTION_H__
-#define __GHOST_XREXCEPTION_H__
+#pragma once
#include <exception>
@@ -41,5 +40,3 @@ class GHOST_XrException : public std::exception {
const char *m_msg;
int m_result;
};
-
-#endif // __GHOST_XREXCEPTION_H__
diff --git a/intern/ghost/intern/GHOST_XrSession.h b/intern/ghost/intern/GHOST_XrSession.h
index da0128b2851..74555c0c170 100644
--- a/intern/ghost/intern/GHOST_XrSession.h
+++ b/intern/ghost/intern/GHOST_XrSession.h
@@ -18,8 +18,7 @@
* \ingroup GHOST
*/
-#ifndef __GHOST_XRSESSION_H__
-#define __GHOST_XRSESSION_H__
+#pragma once
#include <map>
#include <memory>
@@ -84,5 +83,3 @@ class GHOST_XrSession {
void beginFrameDrawing();
void endFrameDrawing(std::vector<XrCompositionLayerBaseHeader *> *layers);
};
-
-#endif /* GHOST_XRSESSION_H__ */
diff --git a/intern/ghost/intern/GHOST_XrSwapchain.h b/intern/ghost/intern/GHOST_XrSwapchain.h
index 7a3e7fcea68..33a1c17b993 100644
--- a/intern/ghost/intern/GHOST_XrSwapchain.h
+++ b/intern/ghost/intern/GHOST_XrSwapchain.h
@@ -18,8 +18,7 @@
* \ingroup GHOST
*/
-#ifndef __GHOST_XRSWAPCHAIN_H__
-#define __GHOST_XRSWAPCHAIN_H__
+#pragma once
#include <memory>
@@ -45,5 +44,3 @@ class GHOST_XrSwapchain {
int32_t m_image_width, m_image_height;
bool m_is_srgb_buffer = false;
};
-
-#endif // GHOST_XRSWAPCHAIN_H
diff --git a/intern/ghost/intern/GHOST_Xr_intern.h b/intern/ghost/intern/GHOST_Xr_intern.h
index d59ffd31940..137541c4528 100644
--- a/intern/ghost/intern/GHOST_Xr_intern.h
+++ b/intern/ghost/intern/GHOST_Xr_intern.h
@@ -18,8 +18,7 @@
* \ingroup GHOST
*/
-#ifndef __GHOST_XR_INTERN_H__
-#define __GHOST_XR_INTERN_H__
+#pragma once
#include <memory>
#include <vector>
@@ -46,5 +45,3 @@
(void)_res; \
} \
(void)0
-
-#endif /* __GHOST_XR_INTERN_H__ */
diff --git a/intern/ghost/intern/GHOST_Xr_openxr_includes.h b/intern/ghost/intern/GHOST_Xr_openxr_includes.h
index 9cac43b1549..d1deaeb0d1a 100644
--- a/intern/ghost/intern/GHOST_Xr_openxr_includes.h
+++ b/intern/ghost/intern/GHOST_Xr_openxr_includes.h
@@ -22,8 +22,7 @@
* installed.
*/
-#ifndef __GHOST_XR_SYSTEM_INCLUDES_H__
-#define __GHOST_XR_SYSTEM_INCLUDES_H__
+#pragma once
/* Platform headers */
#ifdef XR_USE_PLATFORM_WIN32
@@ -48,5 +47,3 @@
#include <openxr/openxr.h>
#include <openxr/openxr_platform.h>
-
-#endif /* __GHOST_XR_SYSTEM_INCLUDES_H__ */
diff --git a/intern/guardedalloc/CMakeLists.txt b/intern/guardedalloc/CMakeLists.txt
index cb24df65ba0..1ab365a376a 100644
--- a/intern/guardedalloc/CMakeLists.txt
+++ b/intern/guardedalloc/CMakeLists.txt
@@ -28,6 +28,7 @@ set(INC_SYS
)
set(SRC
+ ./intern/leak_detector.cc
./intern/mallocn.c
./intern/mallocn_guarded_impl.c
./intern/mallocn_lockfree_impl.c
diff --git a/intern/guardedalloc/MEM_guardedalloc.h b/intern/guardedalloc/MEM_guardedalloc.h
index 1318aa10697..604330bd1d3 100644
--- a/intern/guardedalloc/MEM_guardedalloc.h
+++ b/intern/guardedalloc/MEM_guardedalloc.h
@@ -211,6 +211,10 @@ extern size_t (*MEM_get_peak_memory)(void) ATTR_WARN_UNUSED_RESULT;
extern const char *(*MEM_name_ptr)(void *vmemh);
#endif
+/** This should be called as early as possible in the program. When it has been called, information
+ * about memory leaks will be printed on exit. */
+void MEM_initialize_memleak_detection(void);
+
/* Switch allocator to slower but fully guarded mode. */
void MEM_use_guarded_allocator(void);
diff --git a/intern/guardedalloc/intern/leak_detector.cc b/intern/guardedalloc/intern/leak_detector.cc
new file mode 100644
index 00000000000..4b2689ee28c
--- /dev/null
+++ b/intern/guardedalloc/intern/leak_detector.cc
@@ -0,0 +1,61 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+/** \file
+ * \ingroup MEM
+ */
+
+#include "MEM_guardedalloc.h"
+#include "mallocn_intern.h"
+
+bool leak_detector_has_run = false;
+char free_after_leak_detection_message[] =
+ "Freeing memory after the leak detector has run. This can happen when using "
+ "static variables in C++ that are defined outside of functions. To fix this "
+ "error, use the 'construct on first use' idiom.";
+
+namespace {
+class MemLeakPrinter {
+ public:
+ ~MemLeakPrinter()
+ {
+ leak_detector_has_run = true;
+ const uint leaked_blocks = MEM_get_memory_blocks_in_use();
+ if (leaked_blocks == 0) {
+ return;
+ }
+ const size_t mem_in_use = MEM_get_memory_in_use();
+ printf("Error: Not freed memory blocks: %u, total unfreed memory %f MB\n",
+ leaked_blocks,
+ (double)mem_in_use / 1024 / 1024);
+ MEM_printmemlist();
+ }
+};
+} // namespace
+
+void MEM_initialize_memleak_detection(void)
+{
+ /**
+ * This variable is constructed when this function is first called. This should happen as soon as
+ * possible when the program starts.
+ *
+ * It is destructed when the program exits. During destruction, it will print information about
+ * leaked memory blocks. Static variables are destructed in reversed order of their
+ * construction. Therefore, all static variables that own memory have to be constructed after
+ * this function has been called.
+ */
+ static MemLeakPrinter printer;
+}
diff --git a/intern/guardedalloc/intern/mallocn_guarded_impl.c b/intern/guardedalloc/intern/mallocn_guarded_impl.c
index 5e523204020..2c207935e43 100644
--- a/intern/guardedalloc/intern/mallocn_guarded_impl.c
+++ b/intern/guardedalloc/intern/mallocn_guarded_impl.c
@@ -898,6 +898,10 @@ void MEM_guarded_freeN(void *vmemh)
memt = (MemTail *)(((char *)memh) + sizeof(MemHead) + memh->len);
if (memt->tag3 == MEMTAG3) {
+ if (leak_detector_has_run) {
+ MemorY_ErroR(memh->name, free_after_leak_detection_message);
+ }
+
memh->tag1 = MEMFREE;
memh->tag2 = MEMFREE;
memt->tag3 = MEMFREE;
diff --git a/intern/guardedalloc/intern/mallocn_inline.h b/intern/guardedalloc/intern/mallocn_inline.h
index f8bb7861fc9..4e73eb9bad6 100644
--- a/intern/guardedalloc/intern/mallocn_inline.h
+++ b/intern/guardedalloc/intern/mallocn_inline.h
@@ -33,6 +33,10 @@
#ifndef __MALLOCN_INLINE_H__
#define __MALLOCN_INLINE_H__
+#ifdef __cplusplus
+extern "C" {
+#endif
+
MEM_INLINE bool MEM_size_safe_multiply(size_t a, size_t b, size_t *result)
{
/* A size_t with its high-half bits all set to 1. */
@@ -52,4 +56,8 @@ MEM_INLINE bool MEM_size_safe_multiply(size_t a, size_t b, size_t *result)
return ((high_bits & (a | b)) == 0 || (*result / b == a));
}
+#ifdef __cplusplus
+}
+#endif
+
#endif /* __MALLOCN_INLINE_H__ */
diff --git a/intern/guardedalloc/intern/mallocn_intern.h b/intern/guardedalloc/intern/mallocn_intern.h
index ef8845a66b3..8fc3e432157 100644
--- a/intern/guardedalloc/intern/mallocn_intern.h
+++ b/intern/guardedalloc/intern/mallocn_intern.h
@@ -100,11 +100,18 @@ size_t malloc_usable_size(void *ptr);
#include "mallocn_inline.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
#define ALIGNED_MALLOC_MINIMUM_ALIGNMENT sizeof(void *)
void *aligned_malloc(size_t size, size_t alignment);
void aligned_free(void *ptr);
+extern bool leak_detector_has_run;
+extern char free_after_leak_detection_message[];
+
/* Prototypes for counted allocator functions */
size_t MEM_lockfree_allocN_len(const void *vmemh) ATTR_WARN_UNUSED_RESULT;
void MEM_lockfree_freeN(void *vmemh);
@@ -191,4 +198,8 @@ size_t MEM_guarded_get_peak_memory(void) ATTR_WARN_UNUSED_RESULT;
const char *MEM_guarded_name_ptr(void *vmemh);
#endif
+#ifdef __cplusplus
+}
+#endif
+
#endif /* __MALLOCN_INTERN_H__ */
diff --git a/intern/guardedalloc/intern/mallocn_lockfree_impl.c b/intern/guardedalloc/intern/mallocn_lockfree_impl.c
index 205cc688d72..b71e2c963eb 100644
--- a/intern/guardedalloc/intern/mallocn_lockfree_impl.c
+++ b/intern/guardedalloc/intern/mallocn_lockfree_impl.c
@@ -101,6 +101,10 @@ size_t MEM_lockfree_allocN_len(const void *vmemh)
void MEM_lockfree_freeN(void *vmemh)
{
+ if (leak_detector_has_run) {
+ print_error("%s\n", free_after_leak_detection_message);
+ }
+
MemHead *memh = MEMHEAD_FROM_PTR(vmemh);
size_t len = MEM_lockfree_allocN_len(vmemh);
diff --git a/intern/itasc/Scene.cpp b/intern/itasc/Scene.cpp
index 5438a005d7c..0d2486ceac7 100644
--- a/intern/itasc/Scene.cpp
+++ b/intern/itasc/Scene.cpp
@@ -16,532 +16,623 @@
namespace iTaSC {
class SceneLock : public ControlledObject::JointLockCallback {
-private:
- Scene* m_scene;
- Range m_qrange;
-
-public:
- SceneLock(Scene* scene) :
- m_scene(scene), m_qrange(0,0) {}
- virtual ~SceneLock() {}
-
- void setRange(Range& range)
- {
- m_qrange = range;
- }
- // lock a joint, no need to update output
- virtual void lockJoint(unsigned int q_nr, unsigned int ndof)
- {
- q_nr += m_qrange.start;
- project(m_scene->m_Wq, Range(q_nr, ndof), m_qrange).setZero();
- }
- // lock a joint and update output in view of reiteration
- virtual void lockJoint(unsigned int q_nr, unsigned int ndof, double* qdot)
- {
- q_nr += m_qrange.start;
- project(m_scene->m_Wq, Range(q_nr, ndof), m_qrange).setZero();
- // update the output vector so that the movement of this joint will be
- // taken into account and we can put the joint back in its initial position
- // which means that the jacobian doesn't need to be changed
- for (unsigned int i=0 ;i<ndof ; ++i, ++q_nr) {
- m_scene->m_ydot -= m_scene->m_A.col(q_nr)*qdot[i];
- }
- }
+ private:
+ Scene *m_scene;
+ Range m_qrange;
+
+ public:
+ SceneLock(Scene *scene) : m_scene(scene), m_qrange(0, 0)
+ {
+ }
+ virtual ~SceneLock()
+ {
+ }
+
+ void setRange(Range &range)
+ {
+ m_qrange = range;
+ }
+ // lock a joint, no need to update output
+ virtual void lockJoint(unsigned int q_nr, unsigned int ndof)
+ {
+ q_nr += m_qrange.start;
+ project(m_scene->m_Wq, Range(q_nr, ndof), m_qrange).setZero();
+ }
+ // lock a joint and update output in view of reiteration
+ virtual void lockJoint(unsigned int q_nr, unsigned int ndof, double *qdot)
+ {
+ q_nr += m_qrange.start;
+ project(m_scene->m_Wq, Range(q_nr, ndof), m_qrange).setZero();
+ // update the output vector so that the movement of this joint will be
+ // taken into account and we can put the joint back in its initial position
+ // which means that the jacobian doesn't need to be changed
+ for (unsigned int i = 0; i < ndof; ++i, ++q_nr) {
+ m_scene->m_ydot -= m_scene->m_A.col(q_nr) * qdot[i];
+ }
+ }
};
-Scene::Scene():
- m_A(), m_B(), m_Atemp(), m_Wq(), m_Jf(), m_Jq(), m_Ju(), m_Cf(), m_Cq(), m_Jf_inv(),
- m_Vf(),m_Uf(), m_Wy(), m_ydot(), m_qdot(), m_xdot(), m_Sf(),m_tempf(),
- m_ncTotal(0),m_nqTotal(0),m_nuTotal(0),m_nsets(0),
- m_solver(NULL),m_cache(NULL)
+Scene::Scene()
+ : m_A(),
+ m_B(),
+ m_Atemp(),
+ m_Wq(),
+ m_Jf(),
+ m_Jq(),
+ m_Ju(),
+ m_Cf(),
+ m_Cq(),
+ m_Jf_inv(),
+ m_Vf(),
+ m_Uf(),
+ m_Wy(),
+ m_ydot(),
+ m_qdot(),
+ m_xdot(),
+ m_Sf(),
+ m_tempf(),
+ m_ncTotal(0),
+ m_nqTotal(0),
+ m_nuTotal(0),
+ m_nsets(0),
+ m_solver(NULL),
+ m_cache(NULL)
{
- m_minstep = 0.01;
- m_maxstep = 0.06;
+ m_minstep = 0.01;
+ m_maxstep = 0.06;
}
-Scene::~Scene()
+Scene::~Scene()
{
- ConstraintMap::iterator constraint_it;
- while ((constraint_it = constraints.begin()) != constraints.end()) {
- delete constraint_it->second;
- constraints.erase(constraint_it);
- }
- ObjectMap::iterator object_it;
- while ((object_it = objects.begin()) != objects.end()) {
- delete object_it->second;
- objects.erase(object_it);
- }
+ ConstraintMap::iterator constraint_it;
+ while ((constraint_it = constraints.begin()) != constraints.end()) {
+ delete constraint_it->second;
+ constraints.erase(constraint_it);
+ }
+ ObjectMap::iterator object_it;
+ while ((object_it = objects.begin()) != objects.end()) {
+ delete object_it->second;
+ objects.erase(object_it);
+ }
}
bool Scene::setParam(SceneParam paramId, double value)
{
- switch (paramId) {
- case MIN_TIMESTEP:
- m_minstep = value;
- break;
- case MAX_TIMESTEP:
- m_maxstep = value;
- break;
- default:
- return false;
- }
- return true;
+ switch (paramId) {
+ case MIN_TIMESTEP:
+ m_minstep = value;
+ break;
+ case MAX_TIMESTEP:
+ m_maxstep = value;
+ break;
+ default:
+ return false;
+ }
+ return true;
}
-bool Scene::addObject(const std::string& name, Object* object, UncontrolledObject* base, const std::string& baseFrame)
+bool Scene::addObject(const std::string &name,
+ Object *object,
+ UncontrolledObject *base,
+ const std::string &baseFrame)
{
- // finalize the object before adding
- if (!object->finalize())
- return false;
- //Check if Object is controlled or uncontrolled.
- if(object->getType()==Object::Controlled){
- int baseFrameIndex = base->addEndEffector(baseFrame);
- if (baseFrameIndex < 0)
- return false;
- std::pair<ObjectMap::iterator, bool> result;
- if (base->getNrOfCoordinates() == 0) {
- // base is fixed object, no coordinate range
- result = objects.insert(ObjectMap::value_type(
- name, new Object_struct(object,base,baseFrameIndex,
- Range(m_nqTotal,object->getNrOfCoordinates()),
- Range(m_ncTotal,((ControlledObject*)object)->getNrOfConstraints()),
- Range(0,0))));
- } else {
- // base is a moving object, must be in list already
- ObjectMap::iterator base_it;
- for (base_it=objects.begin(); base_it != objects.end(); base_it++) {
- if (base_it->second->object == base)
- break;
- }
- if (base_it == objects.end())
- return false;
- result = objects.insert(ObjectMap::value_type(
- name, new Object_struct(object,base,baseFrameIndex,
- Range(m_nqTotal,object->getNrOfCoordinates()),
- Range(m_ncTotal,((ControlledObject*)object)->getNrOfConstraints()),
- base_it->second->coordinaterange)));
- }
- if (!result.second) {
- return false;
- }
- m_nqTotal+=object->getNrOfCoordinates();
- m_ncTotal+=((ControlledObject*)object)->getNrOfConstraints();
- return true;
+ // finalize the object before adding
+ if (!object->finalize())
+ return false;
+ // Check if Object is controlled or uncontrolled.
+ if (object->getType() == Object::Controlled) {
+ int baseFrameIndex = base->addEndEffector(baseFrame);
+ if (baseFrameIndex < 0)
+ return false;
+ std::pair<ObjectMap::iterator, bool> result;
+ if (base->getNrOfCoordinates() == 0) {
+ // base is fixed object, no coordinate range
+ result = objects.insert(ObjectMap::value_type(
+ name,
+ new Object_struct(object,
+ base,
+ baseFrameIndex,
+ Range(m_nqTotal, object->getNrOfCoordinates()),
+ Range(m_ncTotal, ((ControlledObject *)object)->getNrOfConstraints()),
+ Range(0, 0))));
+ }
+ else {
+ // base is a moving object, must be in list already
+ ObjectMap::iterator base_it;
+ for (base_it = objects.begin(); base_it != objects.end(); base_it++) {
+ if (base_it->second->object == base)
+ break;
+ }
+ if (base_it == objects.end())
+ return false;
+ result = objects.insert(ObjectMap::value_type(
+ name,
+ new Object_struct(object,
+ base,
+ baseFrameIndex,
+ Range(m_nqTotal, object->getNrOfCoordinates()),
+ Range(m_ncTotal, ((ControlledObject *)object)->getNrOfConstraints()),
+ base_it->second->coordinaterange)));
}
- if(object->getType()==Object::UnControlled){
- if ((WorldObject*)base != &Object::world)
- return false;
- std::pair<ObjectMap::iterator,bool> result = objects.insert(ObjectMap::value_type(
- name,new Object_struct(object,base,0,
- Range(0,0),
- Range(0,0),
- Range(m_nuTotal,object->getNrOfCoordinates()))));
- if(!result.second)
- return false;
- m_nuTotal+=object->getNrOfCoordinates();
- return true;
+ if (!result.second) {
+ return false;
}
- return false;
+ m_nqTotal += object->getNrOfCoordinates();
+ m_ncTotal += ((ControlledObject *)object)->getNrOfConstraints();
+ return true;
+ }
+ if (object->getType() == Object::UnControlled) {
+ if ((WorldObject *)base != &Object::world)
+ return false;
+ std::pair<ObjectMap::iterator, bool> result = objects.insert(
+ ObjectMap::value_type(name,
+ new Object_struct(object,
+ base,
+ 0,
+ Range(0, 0),
+ Range(0, 0),
+ Range(m_nuTotal, object->getNrOfCoordinates()))));
+ if (!result.second)
+ return false;
+ m_nuTotal += object->getNrOfCoordinates();
+ return true;
+ }
+ return false;
}
-bool Scene::addConstraintSet(const std::string& name,ConstraintSet* task,const std::string& object1,const std::string& object2, const std::string& ee1, const std::string& ee2)
+bool Scene::addConstraintSet(const std::string &name,
+ ConstraintSet *task,
+ const std::string &object1,
+ const std::string &object2,
+ const std::string &ee1,
+ const std::string &ee2)
{
- //Check if objects exist:
- ObjectMap::iterator object1_it = objects.find(object1);
- ObjectMap::iterator object2_it = objects.find(object2);
- if(object1_it==objects.end()||object2_it==objects.end())
- return false;
- int ee1_index = object1_it->second->object->addEndEffector(ee1);
- int ee2_index = object2_it->second->object->addEndEffector(ee2);
- if (ee1_index < 0 || ee2_index < 0)
- return false;
- std::pair<ConstraintMap::iterator,bool> result =
- constraints.insert(ConstraintMap::value_type(name,new ConstraintSet_struct(
- task,object1_it,ee1_index,object2_it,ee2_index,
- Range(m_ncTotal,task->getNrOfConstraints()),Range(6*m_nsets,6))));
- if(!result.second)
- return false;
- m_ncTotal+=task->getNrOfConstraints();
- m_nsets+=1;
- return true;
+ // Check if objects exist:
+ ObjectMap::iterator object1_it = objects.find(object1);
+ ObjectMap::iterator object2_it = objects.find(object2);
+ if (object1_it == objects.end() || object2_it == objects.end())
+ return false;
+ int ee1_index = object1_it->second->object->addEndEffector(ee1);
+ int ee2_index = object2_it->second->object->addEndEffector(ee2);
+ if (ee1_index < 0 || ee2_index < 0)
+ return false;
+ std::pair<ConstraintMap::iterator, bool> result = constraints.insert(ConstraintMap::value_type(
+ name,
+ new ConstraintSet_struct(task,
+ object1_it,
+ ee1_index,
+ object2_it,
+ ee2_index,
+ Range(m_ncTotal, task->getNrOfConstraints()),
+ Range(6 * m_nsets, 6))));
+ if (!result.second)
+ return false;
+ m_ncTotal += task->getNrOfConstraints();
+ m_nsets += 1;
+ return true;
}
-bool Scene::addSolver(Solver* _solver){
- if(m_solver==NULL){
- m_solver=_solver;
- return true;
- }
- else
- return false;
+bool Scene::addSolver(Solver *_solver)
+{
+ if (m_solver == NULL) {
+ m_solver = _solver;
+ return true;
+ }
+ else
+ return false;
}
-bool Scene::addCache(Cache* _cache){
- if(m_cache==NULL){
- m_cache=_cache;
- return true;
- }
- else
- return false;
+bool Scene::addCache(Cache *_cache)
+{
+ if (m_cache == NULL) {
+ m_cache = _cache;
+ return true;
+ }
+ else
+ return false;
}
-bool Scene::initialize(){
-
- //prepare all matrices:
- if (m_ncTotal == 0 || m_nqTotal == 0 || m_nsets == 0)
- return false;
-
- m_A = e_zero_matrix(m_ncTotal,m_nqTotal);
- if (m_nuTotal > 0) {
- m_B = e_zero_matrix(m_ncTotal,m_nuTotal);
- m_xdot = e_zero_vector(m_nuTotal);
- m_Ju = e_zero_matrix(6*m_nsets,m_nuTotal);
- }
- m_Atemp = e_zero_matrix(m_ncTotal,6*m_nsets);
- m_ydot = e_zero_vector(m_ncTotal);
- m_qdot = e_zero_vector(m_nqTotal);
- m_Wq = e_zero_matrix(m_nqTotal,m_nqTotal);
- m_Wy = e_zero_vector(m_ncTotal);
- m_Jq = e_zero_matrix(6*m_nsets,m_nqTotal);
- m_Jf = e_zero_matrix(6*m_nsets,6*m_nsets);
- m_Jf_inv = m_Jf;
- m_Cf = e_zero_matrix(m_ncTotal,m_Jf.rows());
- m_Cq = e_zero_matrix(m_ncTotal,m_nqTotal);
-
- bool result=true;
- // finalize all objects
- for (ObjectMap::iterator it=objects.begin(); it!=objects.end(); ++it) {
- Object_struct* os = it->second;
-
- os->object->initCache(m_cache);
- if (os->constraintrange.count > 0)
- project(m_Cq,os->constraintrange,os->jointrange) = (((ControlledObject*)(os->object))->getCq());
- }
-
- m_ytask.resize(m_ncTotal);
- bool toggle=true;
- int cnt = 0;
- //Initialize all ConstraintSets:
- for(ConstraintMap::iterator it=constraints.begin();it!=constraints.end();++it){
- //Calculate the external pose:
- ConstraintSet_struct* cs = it->second;
- Frame external_pose;
- getConstraintPose(cs->task, cs, external_pose);
- result&=cs->task->initialise(external_pose);
- cs->task->initCache(m_cache);
- for (int i=0; i<cs->constraintrange.count; i++, cnt++) {
- m_ytask[cnt] = toggle;
- }
- toggle = !toggle;
- project(m_Cf,cs->constraintrange,cs->featurerange)=cs->task->getCf();
- }
+bool Scene::initialize()
+{
- if(m_solver!=NULL)
- m_solver->init(m_nqTotal,m_ncTotal,m_ytask);
- else
- return false;
+ // prepare all matrices:
+ if (m_ncTotal == 0 || m_nqTotal == 0 || m_nsets == 0)
+ return false;
+ m_A = e_zero_matrix(m_ncTotal, m_nqTotal);
+ if (m_nuTotal > 0) {
+ m_B = e_zero_matrix(m_ncTotal, m_nuTotal);
+ m_xdot = e_zero_vector(m_nuTotal);
+ m_Ju = e_zero_matrix(6 * m_nsets, m_nuTotal);
+ }
+ m_Atemp = e_zero_matrix(m_ncTotal, 6 * m_nsets);
+ m_ydot = e_zero_vector(m_ncTotal);
+ m_qdot = e_zero_vector(m_nqTotal);
+ m_Wq = e_zero_matrix(m_nqTotal, m_nqTotal);
+ m_Wy = e_zero_vector(m_ncTotal);
+ m_Jq = e_zero_matrix(6 * m_nsets, m_nqTotal);
+ m_Jf = e_zero_matrix(6 * m_nsets, 6 * m_nsets);
+ m_Jf_inv = m_Jf;
+ m_Cf = e_zero_matrix(m_ncTotal, m_Jf.rows());
+ m_Cq = e_zero_matrix(m_ncTotal, m_nqTotal);
+
+ bool result = true;
+ // finalize all objects
+ for (ObjectMap::iterator it = objects.begin(); it != objects.end(); ++it) {
+ Object_struct *os = it->second;
+
+ os->object->initCache(m_cache);
+ if (os->constraintrange.count > 0)
+ project(m_Cq,
+ os->constraintrange,
+ os->jointrange) = (((ControlledObject *)(os->object))->getCq());
+ }
+
+ m_ytask.resize(m_ncTotal);
+ bool toggle = true;
+ int cnt = 0;
+ // Initialize all ConstraintSets:
+ for (ConstraintMap::iterator it = constraints.begin(); it != constraints.end(); ++it) {
+ // Calculate the external pose:
+ ConstraintSet_struct *cs = it->second;
+ Frame external_pose;
+ getConstraintPose(cs->task, cs, external_pose);
+ result &= cs->task->initialise(external_pose);
+ cs->task->initCache(m_cache);
+ for (int i = 0; i < cs->constraintrange.count; i++, cnt++) {
+ m_ytask[cnt] = toggle;
+ }
+ toggle = !toggle;
+ project(m_Cf, cs->constraintrange, cs->featurerange) = cs->task->getCf();
+ }
- return result;
+ if (m_solver != NULL)
+ m_solver->init(m_nqTotal, m_ncTotal, m_ytask);
+ else
+ return false;
+
+ return result;
}
-bool Scene::getConstraintPose(ConstraintSet* constraint, void *_param, KDL::Frame& _pose)
+bool Scene::getConstraintPose(ConstraintSet *constraint, void *_param, KDL::Frame &_pose)
{
- // function called from constraint when they need to get the external pose
- ConstraintSet_struct* cs = (ConstraintSet_struct*)_param;
- // verification, the pointer MUST match
- assert (constraint == cs->task);
- Object_struct* ob1 = cs->object1->second;
- Object_struct* ob2 = cs->object2->second;
- //Calculate the external pose:
- _pose=(ob1->base->getPose(ob1->baseFrameIndex)*ob1->object->getPose(cs->ee1index)).Inverse()*(ob2->base->getPose(ob2->baseFrameIndex)*ob2->object->getPose(cs->ee2index));
- return true;
+ // function called from constraint when they need to get the external pose
+ ConstraintSet_struct *cs = (ConstraintSet_struct *)_param;
+ // verification, the pointer MUST match
+ assert(constraint == cs->task);
+ Object_struct *ob1 = cs->object1->second;
+ Object_struct *ob2 = cs->object2->second;
+ // Calculate the external pose:
+ _pose =
+ (ob1->base->getPose(ob1->baseFrameIndex) * ob1->object->getPose(cs->ee1index)).Inverse() *
+ (ob2->base->getPose(ob2->baseFrameIndex) * ob2->object->getPose(cs->ee2index));
+ return true;
}
-bool Scene::update(double timestamp, double timestep, unsigned int numsubstep, bool reiterate, bool cache, bool interpolate)
+bool Scene::update(double timestamp,
+ double timestep,
+ unsigned int numsubstep,
+ bool reiterate,
+ bool cache,
+ bool interpolate)
{
- // we must have valid timestep and timestamp
- if (timestamp < KDL::epsilon || timestep < 0.0)
- return false;
- Timestamp ts;
- ts.realTimestamp = timestamp;
- // initially we start with the full timestep to allow velocity estimation over the full interval
- ts.realTimestep = timestep;
- setCacheTimestamp(ts);
- ts.substep = 0;
- // for reiteration don't load cache
- // reiteration=additional iteration with same timestamp if application finds the convergence not good enough
- ts.reiterate = (reiterate) ? 1 : 0;
- ts.interpolate = (interpolate) ? 1 : 0;
- ts.cache = (cache) ? 1 : 0;
- ts.update = 1;
- ts.numstep = (numsubstep & 0xFF);
- bool autosubstep = (numsubstep == 0) ? true : false;
- if (numsubstep < 1)
- numsubstep = 1;
- double timesubstep = timestep/numsubstep;
- double timeleft = timestep;
-
- if (timeleft == 0.0) {
- // this special case correspond to a request to cache data
- for(ObjectMap::iterator it=objects.begin();it!=objects.end();++it){
- it->second->object->pushCache(ts);
- }
- //Update the Constraints
- for(ConstraintMap::iterator it=constraints.begin();it!=constraints.end();++it){
- it->second->task->pushCache(ts);
- }
- return true;
- }
-
- // double maxqdot; // UNUSED
- e_scalar nlcoef;
- SceneLock lockCallback(this);
- Frame external_pose;
- bool locked;
-
- // initially we keep timestep unchanged so that update function compute the velocity over
- while (numsubstep > 0) {
- // get objects
- for(ObjectMap::iterator it=objects.begin();it!=objects.end();++it) {
- Object_struct* os = it->second;
- if (os->object->getType()==Object::Controlled) {
- ((ControlledObject*)(os->object))->updateControlOutput(ts);
- if (os->constraintrange.count > 0) {
- project(m_ydot, os->constraintrange) = ((ControlledObject*)(os->object))->getControlOutput();
- project(m_Wy, os->constraintrange) = ((ControlledObject*)(os->object))->getWy();
- // project(m_Cq,os->constraintrange,os->jointrange) = (((ControlledObject*)(os->object))->getCq());
- }
- if (os->jointrange.count > 0) {
- project(m_Wq,os->jointrange,os->jointrange) = ((ControlledObject*)(os->object))->getWq();
- }
- }
- if (os->object->getType()==Object::UnControlled && ((UncontrolledObject*)os->object)->getNrOfCoordinates() != 0) {
- ((UncontrolledObject*)(os->object))->updateCoordinates(ts);
- if (!ts.substep) {
- // velocity of uncontrolled object remains constant during substepping
- project(m_xdot,os->coordinaterange) = ((UncontrolledObject*)(os->object))->getXudot();
- }
- }
- }
-
- //get new Constraints values
- for(ConstraintMap::iterator it=constraints.begin();it!=constraints.end();++it) {
- ConstraintSet_struct* cs = it->second;
- Object_struct* ob1 = cs->object1->second;
- Object_struct* ob2 = cs->object2->second;
-
- if (ob1->base->updated() || ob1->object->updated() || ob2->base->updated() || ob2->object->updated()) {
- // the object from which the constraint depends have changed position
- // recompute the constraint pose
- getConstraintPose(cs->task, cs, external_pose);
- cs->task->initialise(external_pose);
- }
- cs->task->updateControlOutput(ts);
- project(m_ydot,cs->constraintrange)=cs->task->getControlOutput();
- if (!ts.substep || cs->task->substep()) {
- project(m_Wy,cs->constraintrange)=(cs->task)->getWy();
- //project(m_Cf,cs->constraintrange,cs->featurerange)=cs->task->getCf();
- }
-
- project(m_Jf,cs->featurerange,cs->featurerange)=cs->task->getJf();
- //std::cout << "Jf = " << Jf << std::endl;
- //Transform the reference frame of this jacobian to the world reference frame
- Eigen::Block<e_matrix> Jf_part = project(m_Jf,cs->featurerange,cs->featurerange);
- changeBase(Jf_part,ob1->base->getPose(ob1->baseFrameIndex)*ob1->object->getPose(cs->ee1index));
- //std::cout << "Jf_w = " << Jf << std::endl;
-
- //calculate the inverse of Jf
- KDL::svd_eigen_HH(project(m_Jf,cs->featurerange,cs->featurerange),m_Uf,m_Sf,m_Vf,m_tempf);
- for(unsigned int i=0;i<6;++i)
- if(m_Sf(i)<KDL::epsilon)
- m_Uf.col(i).setConstant(0.0);
- else
- m_Uf.col(i)*=(1/m_Sf(i));
- project(m_Jf_inv,cs->featurerange,cs->featurerange).noalias()=m_Vf*m_Uf.transpose();
-
- //Get the robotjacobian associated with this constraintset
- //Each jacobian is expressed in robot base frame => convert to world reference
- //and negate second robot because it is taken reversed when closing the loop:
- if(ob1->object->getType()==Object::Controlled){
- project(m_Jq,cs->featurerange,ob1->jointrange) = (((ControlledObject*)(ob1->object))->getJq(cs->ee1index));
- //Transform the reference frame of this jacobian to the world reference frame:
- Eigen::Block<e_matrix> Jq_part = project(m_Jq,cs->featurerange,ob1->jointrange);
- changeBase(Jq_part,ob1->base->getPose(ob1->baseFrameIndex));
- // if the base of this object is moving, get the Ju part
- if (ob1->base->getNrOfCoordinates() != 0) {
- // Ju is already computed for world reference frame
- project(m_Ju,cs->featurerange,ob1->coordinaterange)=ob1->base->getJu(ob1->baseFrameIndex);
- }
- } else if (ob1->object->getType() == Object::UnControlled && ((UncontrolledObject*)ob1->object)->getNrOfCoordinates() != 0) {
- // object1 is uncontrolled moving object
- project(m_Ju,cs->featurerange,ob1->coordinaterange)=((UncontrolledObject*)ob1->object)->getJu(cs->ee1index);
- }
- if(ob2->object->getType()==Object::Controlled){
- //Get the robotjacobian associated with this constraintset
- // process a special case where object2 and object1 are equal but using different end effector
- if (ob1->object == ob2->object) {
- // we must create a temporary matrix
- e_matrix JqTemp(((ControlledObject*)(ob2->object))->getJq(cs->ee2index));
- //Transform the reference frame of this jacobian to the world reference frame:
- changeBase(JqTemp,ob2->base->getPose(ob2->baseFrameIndex));
- // substract in place
- project(m_Jq,cs->featurerange,ob2->jointrange) -= JqTemp;
- } else {
- project(m_Jq,cs->featurerange,ob2->jointrange) = -(((ControlledObject*)(ob2->object))->getJq(cs->ee2index));
- //Transform the reference frame of this jacobian to the world reference frame:
- Eigen::Block<e_matrix> Jq_part = project(m_Jq,cs->featurerange,ob2->jointrange);
- changeBase(Jq_part,ob2->base->getPose(ob2->baseFrameIndex));
- }
- if (ob2->base->getNrOfCoordinates() != 0) {
- // if base is the same as first object or first object base,
- // that portion of m_Ju has been set already => substract inplace
- if (ob2->base == ob1->base || ob2->base == ob1->object) {
- project(m_Ju,cs->featurerange,ob2->coordinaterange) -= ob2->base->getJu(ob2->baseFrameIndex);
- } else {
- project(m_Ju,cs->featurerange,ob2->coordinaterange) = -ob2->base->getJu(ob2->baseFrameIndex);
- }
- }
- } else if (ob2->object->getType() == Object::UnControlled && ((UncontrolledObject*)ob2->object)->getNrOfCoordinates() != 0) {
- if (ob2->object == ob1->base || ob2->object == ob1->object) {
- project(m_Ju,cs->featurerange,ob2->coordinaterange) -= ((UncontrolledObject*)ob2->object)->getJu(cs->ee2index);
- } else {
- project(m_Ju,cs->featurerange,ob2->coordinaterange) = -((UncontrolledObject*)ob2->object)->getJu(cs->ee2index);
- }
- }
- }
-
- //Calculate A
- m_Atemp.noalias()=m_Cf*m_Jf_inv;
- m_A.noalias() = m_Cq-(m_Atemp*m_Jq);
- if (m_nuTotal > 0) {
- m_B.noalias()=m_Atemp*m_Ju;
- m_ydot.noalias() += m_B*m_xdot;
- }
-
- //Call the solver with A, Wq, Wy, ydot to solver qdot:
- if(!m_solver->solve(m_A,m_Wy,m_ydot,m_Wq,m_qdot,nlcoef))
- // this should never happen
- return false;
- //send result to the objects
- for(ObjectMap::iterator it=objects.begin();it!=objects.end();++it) {
- Object_struct* os = it->second;
- if(os->object->getType()==Object::Controlled)
- ((ControlledObject*)(os->object))->setJointVelocity(project(m_qdot,os->jointrange));
- }
- // compute the constraint velocity
- for(ConstraintMap::iterator it=constraints.begin();it!=constraints.end();++it){
- ConstraintSet_struct* cs = it->second;
- Object_struct* ob1 = cs->object1->second;
- Object_struct* ob2 = cs->object2->second;
- //Calculate the twist of the world reference frame due to the robots (Jq*qdot+Ju*chiudot):
- e_vector6 external_vel = e_zero_vector(6);
- if (ob1->jointrange.count > 0)
- external_vel.noalias() += (project(m_Jq,cs->featurerange,ob1->jointrange)*project(m_qdot,ob1->jointrange));
- if (ob2->jointrange.count > 0)
- external_vel.noalias() += (project(m_Jq,cs->featurerange,ob2->jointrange)*project(m_qdot,ob2->jointrange));
- if (ob1->coordinaterange.count > 0)
- external_vel.noalias() += (project(m_Ju,cs->featurerange,ob1->coordinaterange)*project(m_xdot,ob1->coordinaterange));
- if (ob2->coordinaterange.count > 0)
- external_vel.noalias() += (project(m_Ju,cs->featurerange,ob2->coordinaterange)*project(m_xdot,ob2->coordinaterange));
- //the twist caused by the constraint must be opposite because of the closed loop
- //estimate the velocity of the joints using the inverse jacobian
- e_vector6 estimated_chidot = project(m_Jf_inv,cs->featurerange,cs->featurerange)*(-external_vel);
- cs->task->setJointVelocity(estimated_chidot);
- }
-
- if (autosubstep) {
- // automatic computing of substep based on maximum joint change
- // and joint limit gain variation
- // We will pass the joint velocity to each object and they will recommend a maximum timestep
- timesubstep = timeleft;
- // get armature max joint velocity to estimate the maximum duration of integration
- // maxqdot = m_qdot.cwise().abs().maxCoeff(); // UNUSED
- double maxsubstep = nlcoef*m_maxstep;
- if (maxsubstep < m_minstep)
- maxsubstep = m_minstep;
- if (timesubstep > maxsubstep)
- timesubstep = maxsubstep;
- for(ObjectMap::iterator it=objects.begin();it!=objects.end();++it){
- Object_struct* os = it->second;
- if(os->object->getType()==Object::Controlled)
- ((ControlledObject*)(os->object))->getMaxTimestep(timesubstep);
- }
- for(ConstraintMap::iterator it=constraints.begin();it!=constraints.end();++it){
- ConstraintSet_struct* cs = it->second;
- cs->task->getMaxTimestep(timesubstep);
- }
- // use substep that are even dividers of timestep for more regularity
- maxsubstep = 2.0*floor(timestep/2.0/timesubstep-0.66666);
- timesubstep = (maxsubstep < 0.0) ? timestep : timestep/(2.0+maxsubstep);
- if (timesubstep >= timeleft-(m_minstep/2.0)) {
- timesubstep = timeleft;
- numsubstep = 1;
- timeleft = 0.;
- } else {
- numsubstep = 2;
- timeleft -= timesubstep;
- }
- }
- if (numsubstep > 1) {
- ts.substep = 1;
- } else {
- // set substep to false for last iteration so that controlled output
- // can be updated in updateKinematics() and model_update)() before next call to Secne::update()
- ts.substep = 0;
- }
- // change timestep so that integration is done correctly
- ts.realTimestep = timesubstep;
-
- do {
- ObjectMap::iterator it;
- Object_struct* os;
- locked = false;
- for(it=objects.begin();it!=objects.end();++it){
- os = it->second;
- if (os->object->getType()==Object::Controlled) {
- lockCallback.setRange(os->jointrange);
- if (((ControlledObject*)os->object)->updateJoint(ts, lockCallback)) {
- // this means one of the joint was locked and we must rerun
- // the solver to update the remaining joints
- locked = true;
- break;
- }
- }
- }
- if (locked) {
- // Some rows of m_Wq have been cleared so that the corresponding joint will not move
- if(!m_solver->solve(m_A,m_Wy,m_ydot,m_Wq,m_qdot,nlcoef))
- // this should never happen
- return false;
-
- //send result to the objects
- for(it=objects.begin();it!=objects.end();++it) {
- os = it->second;
- if(os->object->getType()==Object::Controlled)
- ((ControlledObject*)(os->object))->setJointVelocity(project(m_qdot,os->jointrange));
- }
- }
- } while (locked);
-
- //Update the Objects
- for(ObjectMap::iterator it=objects.begin();it!=objects.end();++it){
- it->second->object->updateKinematics(ts);
- // mark this object not updated since the constraint will be updated anyway
- // this flag is only useful to detect external updates
- it->second->object->updated(false);
- }
- //Update the Constraints
- for(ConstraintMap::iterator it=constraints.begin();it!=constraints.end();++it){
- ConstraintSet_struct* cs = it->second;
- //Calculate the external pose:
- getConstraintPose(cs->task, cs, external_pose);
- cs->task->modelUpdate(external_pose,ts);
- // update the constraint output and cache
- cs->task->updateKinematics(ts);
- }
- numsubstep--;
- }
- return true;
-}
+ // we must have valid timestep and timestamp
+ if (timestamp < KDL::epsilon || timestep < 0.0)
+ return false;
+ Timestamp ts;
+ ts.realTimestamp = timestamp;
+ // initially we start with the full timestep to allow velocity estimation over the full interval
+ ts.realTimestep = timestep;
+ setCacheTimestamp(ts);
+ ts.substep = 0;
+ // for reiteration don't load cache
+ // reiteration=additional iteration with same timestamp if application finds the convergence not
+ // good enough
+ ts.reiterate = (reiterate) ? 1 : 0;
+ ts.interpolate = (interpolate) ? 1 : 0;
+ ts.cache = (cache) ? 1 : 0;
+ ts.update = 1;
+ ts.numstep = (numsubstep & 0xFF);
+ bool autosubstep = (numsubstep == 0) ? true : false;
+ if (numsubstep < 1)
+ numsubstep = 1;
+ double timesubstep = timestep / numsubstep;
+ double timeleft = timestep;
+
+ if (timeleft == 0.0) {
+ // this special case correspond to a request to cache data
+ for (ObjectMap::iterator it = objects.begin(); it != objects.end(); ++it) {
+ it->second->object->pushCache(ts);
+ }
+ // Update the Constraints
+ for (ConstraintMap::iterator it = constraints.begin(); it != constraints.end(); ++it) {
+ it->second->task->pushCache(ts);
+ }
+ return true;
+ }
+
+ // double maxqdot; // UNUSED
+ e_scalar nlcoef;
+ SceneLock lockCallback(this);
+ Frame external_pose;
+ bool locked;
+
+ // initially we keep timestep unchanged so that update function compute the velocity over
+ while (numsubstep > 0) {
+ // get objects
+ for (ObjectMap::iterator it = objects.begin(); it != objects.end(); ++it) {
+ Object_struct *os = it->second;
+ if (os->object->getType() == Object::Controlled) {
+ ((ControlledObject *)(os->object))->updateControlOutput(ts);
+ if (os->constraintrange.count > 0) {
+ project(m_ydot,
+ os->constraintrange) = ((ControlledObject *)(os->object))->getControlOutput();
+ project(m_Wy, os->constraintrange) = ((ControlledObject *)(os->object))->getWy();
+ // project(m_Cq,os->constraintrange,os->jointrange) =
+ // (((ControlledObject*)(os->object))->getCq());
+ }
+ if (os->jointrange.count > 0) {
+ project(
+ m_Wq, os->jointrange, os->jointrange) = ((ControlledObject *)(os->object))->getWq();
+ }
+ }
+ if (os->object->getType() == Object::UnControlled &&
+ ((UncontrolledObject *)os->object)->getNrOfCoordinates() != 0) {
+ ((UncontrolledObject *)(os->object))->updateCoordinates(ts);
+ if (!ts.substep) {
+ // velocity of uncontrolled object remains constant during substepping
+ project(m_xdot, os->coordinaterange) = ((UncontrolledObject *)(os->object))->getXudot();
+ }
+ }
+ }
+
+ // get new Constraints values
+ for (ConstraintMap::iterator it = constraints.begin(); it != constraints.end(); ++it) {
+ ConstraintSet_struct *cs = it->second;
+ Object_struct *ob1 = cs->object1->second;
+ Object_struct *ob2 = cs->object2->second;
+
+ if (ob1->base->updated() || ob1->object->updated() || ob2->base->updated() ||
+ ob2->object->updated()) {
+ // the object from which the constraint depends have changed position
+ // recompute the constraint pose
+ getConstraintPose(cs->task, cs, external_pose);
+ cs->task->initialise(external_pose);
+ }
+ cs->task->updateControlOutput(ts);
+ project(m_ydot, cs->constraintrange) = cs->task->getControlOutput();
+ if (!ts.substep || cs->task->substep()) {
+ project(m_Wy, cs->constraintrange) = (cs->task)->getWy();
+ // project(m_Cf,cs->constraintrange,cs->featurerange)=cs->task->getCf();
+ }
+
+ project(m_Jf, cs->featurerange, cs->featurerange) = cs->task->getJf();
+ // std::cout << "Jf = " << Jf << std::endl;
+ // Transform the reference frame of this jacobian to the world reference frame
+ Eigen::Block<e_matrix> Jf_part = project(m_Jf, cs->featurerange, cs->featurerange);
+ changeBase(Jf_part,
+ ob1->base->getPose(ob1->baseFrameIndex) * ob1->object->getPose(cs->ee1index));
+ // std::cout << "Jf_w = " << Jf << std::endl;
+
+ // calculate the inverse of Jf
+ KDL::svd_eigen_HH(
+ project(m_Jf, cs->featurerange, cs->featurerange), m_Uf, m_Sf, m_Vf, m_tempf);
+ for (unsigned int i = 0; i < 6; ++i)
+ if (m_Sf(i) < KDL::epsilon)
+ m_Uf.col(i).setConstant(0.0);
+ else
+ m_Uf.col(i) *= (1 / m_Sf(i));
+ project(m_Jf_inv, cs->featurerange, cs->featurerange).noalias() = m_Vf * m_Uf.transpose();
+
+ // Get the robotjacobian associated with this constraintset
+ // Each jacobian is expressed in robot base frame => convert to world reference
+ // and negate second robot because it is taken reversed when closing the loop:
+ if (ob1->object->getType() == Object::Controlled) {
+ project(m_Jq,
+ cs->featurerange,
+ ob1->jointrange) = (((ControlledObject *)(ob1->object))->getJq(cs->ee1index));
+ // Transform the reference frame of this jacobian to the world reference frame:
+ Eigen::Block<e_matrix> Jq_part = project(m_Jq, cs->featurerange, ob1->jointrange);
+ changeBase(Jq_part, ob1->base->getPose(ob1->baseFrameIndex));
+ // if the base of this object is moving, get the Ju part
+ if (ob1->base->getNrOfCoordinates() != 0) {
+ // Ju is already computed for world reference frame
+ project(m_Ju, cs->featurerange, ob1->coordinaterange) = ob1->base->getJu(
+ ob1->baseFrameIndex);
+ }
+ }
+ else if (ob1->object->getType() == Object::UnControlled &&
+ ((UncontrolledObject *)ob1->object)->getNrOfCoordinates() != 0) {
+ // object1 is uncontrolled moving object
+ project(m_Ju,
+ cs->featurerange,
+ ob1->coordinaterange) = ((UncontrolledObject *)ob1->object)->getJu(cs->ee1index);
+ }
+ if (ob2->object->getType() == Object::Controlled) {
+ // Get the robotjacobian associated with this constraintset
+ // process a special case where object2 and object1 are equal but using different end
+ // effector
+ if (ob1->object == ob2->object) {
+ // we must create a temporary matrix
+ e_matrix JqTemp(((ControlledObject *)(ob2->object))->getJq(cs->ee2index));
+ // Transform the reference frame of this jacobian to the world reference frame:
+ changeBase(JqTemp, ob2->base->getPose(ob2->baseFrameIndex));
+ // subtract in place
+ project(m_Jq, cs->featurerange, ob2->jointrange) -= JqTemp;
+ }
+ else {
+ project(m_Jq, cs->featurerange, ob2->jointrange) = -(
+ ((ControlledObject *)(ob2->object))->getJq(cs->ee2index));
+ // Transform the reference frame of this jacobian to the world reference frame:
+ Eigen::Block<e_matrix> Jq_part = project(m_Jq, cs->featurerange, ob2->jointrange);
+ changeBase(Jq_part, ob2->base->getPose(ob2->baseFrameIndex));
+ }
+ if (ob2->base->getNrOfCoordinates() != 0) {
+ // if base is the same as first object or first object base,
+ // that portion of m_Ju has been set already => subtract inplace
+ if (ob2->base == ob1->base || ob2->base == ob1->object) {
+ project(m_Ju, cs->featurerange, ob2->coordinaterange) -= ob2->base->getJu(
+ ob2->baseFrameIndex);
+ }
+ else {
+ project(m_Ju, cs->featurerange, ob2->coordinaterange) = -ob2->base->getJu(
+ ob2->baseFrameIndex);
+ }
+ }
+ }
+ else if (ob2->object->getType() == Object::UnControlled &&
+ ((UncontrolledObject *)ob2->object)->getNrOfCoordinates() != 0) {
+ if (ob2->object == ob1->base || ob2->object == ob1->object) {
+ project(m_Ju, cs->featurerange, ob2->coordinaterange) -=
+ ((UncontrolledObject *)ob2->object)->getJu(cs->ee2index);
+ }
+ else {
+ project(m_Ju, cs->featurerange, ob2->coordinaterange) =
+ -((UncontrolledObject *)ob2->object)->getJu(cs->ee2index);
+ }
+ }
+ }
+
+ // Calculate A
+ m_Atemp.noalias() = m_Cf * m_Jf_inv;
+ m_A.noalias() = m_Cq - (m_Atemp * m_Jq);
+ if (m_nuTotal > 0) {
+ m_B.noalias() = m_Atemp * m_Ju;
+ m_ydot.noalias() += m_B * m_xdot;
+ }
+ // Call the solver with A, Wq, Wy, ydot to solver qdot:
+ if (!m_solver->solve(m_A, m_Wy, m_ydot, m_Wq, m_qdot, nlcoef))
+ // this should never happen
+ return false;
+ // send result to the objects
+ for (ObjectMap::iterator it = objects.begin(); it != objects.end(); ++it) {
+ Object_struct *os = it->second;
+ if (os->object->getType() == Object::Controlled)
+ ((ControlledObject *)(os->object))->setJointVelocity(project(m_qdot, os->jointrange));
+ }
+ // compute the constraint velocity
+ for (ConstraintMap::iterator it = constraints.begin(); it != constraints.end(); ++it) {
+ ConstraintSet_struct *cs = it->second;
+ Object_struct *ob1 = cs->object1->second;
+ Object_struct *ob2 = cs->object2->second;
+ // Calculate the twist of the world reference frame due to the robots (Jq*qdot+Ju*chiudot):
+ e_vector6 external_vel = e_zero_vector(6);
+ if (ob1->jointrange.count > 0)
+ external_vel.noalias() += (project(m_Jq, cs->featurerange, ob1->jointrange) *
+ project(m_qdot, ob1->jointrange));
+ if (ob2->jointrange.count > 0)
+ external_vel.noalias() += (project(m_Jq, cs->featurerange, ob2->jointrange) *
+ project(m_qdot, ob2->jointrange));
+ if (ob1->coordinaterange.count > 0)
+ external_vel.noalias() += (project(m_Ju, cs->featurerange, ob1->coordinaterange) *
+ project(m_xdot, ob1->coordinaterange));
+ if (ob2->coordinaterange.count > 0)
+ external_vel.noalias() += (project(m_Ju, cs->featurerange, ob2->coordinaterange) *
+ project(m_xdot, ob2->coordinaterange));
+ // the twist caused by the constraint must be opposite because of the closed loop
+ // estimate the velocity of the joints using the inverse jacobian
+ e_vector6 estimated_chidot = project(m_Jf_inv, cs->featurerange, cs->featurerange) *
+ (-external_vel);
+ cs->task->setJointVelocity(estimated_chidot);
+ }
+
+ if (autosubstep) {
+ // automatic computing of substep based on maximum joint change
+ // and joint limit gain variation
+ // We will pass the joint velocity to each object and they will recommend a maximum timestep
+ timesubstep = timeleft;
+ // get armature max joint velocity to estimate the maximum duration of integration
+ // maxqdot = m_qdot.cwise().abs().maxCoeff(); // UNUSED
+ double maxsubstep = nlcoef * m_maxstep;
+ if (maxsubstep < m_minstep)
+ maxsubstep = m_minstep;
+ if (timesubstep > maxsubstep)
+ timesubstep = maxsubstep;
+ for (ObjectMap::iterator it = objects.begin(); it != objects.end(); ++it) {
+ Object_struct *os = it->second;
+ if (os->object->getType() == Object::Controlled)
+ ((ControlledObject *)(os->object))->getMaxTimestep(timesubstep);
+ }
+ for (ConstraintMap::iterator it = constraints.begin(); it != constraints.end(); ++it) {
+ ConstraintSet_struct *cs = it->second;
+ cs->task->getMaxTimestep(timesubstep);
+ }
+ // use substep that are even dividers of timestep for more regularity
+ maxsubstep = 2.0 * floor(timestep / 2.0 / timesubstep - 0.66666);
+ timesubstep = (maxsubstep < 0.0) ? timestep : timestep / (2.0 + maxsubstep);
+ if (timesubstep >= timeleft - (m_minstep / 2.0)) {
+ timesubstep = timeleft;
+ numsubstep = 1;
+ timeleft = 0.;
+ }
+ else {
+ numsubstep = 2;
+ timeleft -= timesubstep;
+ }
+ }
+ if (numsubstep > 1) {
+ ts.substep = 1;
+ }
+ else {
+ // set substep to false for last iteration so that controlled output
+ // can be updated in updateKinematics() and model_update)() before next call to
+ // Secne::update()
+ ts.substep = 0;
+ }
+ // change timestep so that integration is done correctly
+ ts.realTimestep = timesubstep;
+
+ do {
+ ObjectMap::iterator it;
+ Object_struct *os;
+ locked = false;
+ for (it = objects.begin(); it != objects.end(); ++it) {
+ os = it->second;
+ if (os->object->getType() == Object::Controlled) {
+ lockCallback.setRange(os->jointrange);
+ if (((ControlledObject *)os->object)->updateJoint(ts, lockCallback)) {
+ // this means one of the joint was locked and we must rerun
+ // the solver to update the remaining joints
+ locked = true;
+ break;
+ }
+ }
+ }
+ if (locked) {
+ // Some rows of m_Wq have been cleared so that the corresponding joint will not move
+ if (!m_solver->solve(m_A, m_Wy, m_ydot, m_Wq, m_qdot, nlcoef))
+ // this should never happen
+ return false;
+
+ // send result to the objects
+ for (it = objects.begin(); it != objects.end(); ++it) {
+ os = it->second;
+ if (os->object->getType() == Object::Controlled)
+ ((ControlledObject *)(os->object))->setJointVelocity(project(m_qdot, os->jointrange));
+ }
+ }
+ } while (locked);
+
+ // Update the Objects
+ for (ObjectMap::iterator it = objects.begin(); it != objects.end(); ++it) {
+ it->second->object->updateKinematics(ts);
+ // mark this object not updated since the constraint will be updated anyway
+ // this flag is only useful to detect external updates
+ it->second->object->updated(false);
+ }
+ // Update the Constraints
+ for (ConstraintMap::iterator it = constraints.begin(); it != constraints.end(); ++it) {
+ ConstraintSet_struct *cs = it->second;
+ // Calculate the external pose:
+ getConstraintPose(cs->task, cs, external_pose);
+ cs->task->modelUpdate(external_pose, ts);
+ // update the constraint output and cache
+ cs->task->updateKinematics(ts);
+ }
+ numsubstep--;
+ }
+ return true;
}
+
+} // namespace iTaSC
diff --git a/intern/mantaflow/intern/MANTA_main.cpp b/intern/mantaflow/intern/MANTA_main.cpp
index 676a2fd785e..6e6451be725 100644
--- a/intern/mantaflow/intern/MANTA_main.cpp
+++ b/intern/mantaflow/intern/MANTA_main.cpp
@@ -876,6 +876,7 @@ void MANTA::initializeRNAMap(FluidModifierData *fmd)
mRNAMap["CACHE_DIR"] = cacheDirectory;
mRNAMap["COMPRESSION_OPENVDB"] = vdbCompressionMethod;
mRNAMap["PRECISION_OPENVDB"] = vdbPrecisionHalf;
+ mRNAMap["PP_PARTICLE_MAXIMUM"] = to_string(fds->sys_particle_maximum);
/* Fluid object names. */
mRNAMap["NAME_FLAGS"] = FLUID_NAME_FLAGS;
@@ -1013,7 +1014,7 @@ void MANTA::initializeRNAMap(FluidModifierData *fmd)
mRNAMap["NAME_GUIDEVEL_X"] = FLUID_NAME_GUIDEVEL_X;
mRNAMap["NAME_GUIDEVEL_Y"] = FLUID_NAME_GUIDEVEL_Y;
mRNAMap["NAME_GUIDEVEL_Z"] = FLUID_NAME_GUIDEVEL_Z;
- mRNAMap["NAME_GUIDEVEL"] = FLUID_NAME_GUIDEVEL;
+ mRNAMap["NAME_VELOCITY_GUIDE"] = FLUID_NAME_VELOCITY_GUIDE;
/* Cache file names. */
mRNAMap["NAME_CONFIG"] = FLUID_NAME_CONFIG;
@@ -1538,6 +1539,7 @@ bool MANTA::bakeGuiding(FluidModifierData *fmd, int framenr)
cacheDirGuiding[0] = '\0';
string volume_format = getCacheFileEnding(fds->cache_data_format);
+ string resumable_cache = !(fds->flags & FLUID_DOMAIN_USE_RESUMABLE_CACHE) ? "False" : "True";
BLI_path_join(cacheDirGuiding,
sizeof(cacheDirGuiding),
@@ -1548,7 +1550,7 @@ bool MANTA::bakeGuiding(FluidModifierData *fmd, int framenr)
ss.str("");
ss << "bake_guiding_" << mCurrentID << "('" << escapeSlashes(cacheDirGuiding) << "', " << framenr
- << ", '" << volume_format << "')";
+ << ", '" << volume_format << "', " << resumable_cache << ")";
pythonCommands.push_back(ss.str());
return runPythonString(pythonCommands);
@@ -2189,9 +2191,16 @@ bool MANTA::hasParticles(FluidModifierData *fmd, int framenr)
bool MANTA::hasGuiding(FluidModifierData *fmd, int framenr, bool sourceDomain)
{
string subdirectory = (sourceDomain) ? FLUID_DOMAIN_DIR_DATA : FLUID_DOMAIN_DIR_GUIDE;
- string filename = (sourceDomain) ? FLUID_NAME_VELOCITY : FLUID_NAME_GUIDEVEL;
+ string filename = (sourceDomain) ? FLUID_NAME_DATA : FLUID_NAME_GUIDING;
string extension = getCacheFileEnding(fmd->domain->cache_data_format);
bool exists = BLI_exists(getFile(fmd, subdirectory, filename, extension, framenr).c_str());
+
+ /* Check old file naming. */
+ if (!exists) {
+ filename = (sourceDomain) ? FLUID_NAME_VEL : FLUID_NAME_GUIDEVEL;
+ exists = BLI_exists(getFile(fmd, subdirectory, filename, extension, framenr).c_str());
+ }
+
if (with_debug)
cout << "Fluid: Has Guiding: " << exists << endl;
diff --git a/intern/mantaflow/intern/strings/fluid_script.h b/intern/mantaflow/intern/strings/fluid_script.h
index 4ee3ae59957..83ad201fcbd 100644
--- a/intern/mantaflow/intern/strings/fluid_script.h
+++ b/intern/mantaflow/intern/strings/fluid_script.h
@@ -329,7 +329,7 @@ y_guidevel_s$ID$ = s$ID$.create(RealGrid, name='$NAME_GUIDEVEL_Y$')\n\
z_guidevel_s$ID$ = s$ID$.create(RealGrid, name='$NAME_GUIDEVEL_Z$')\n\
\n\
# Final guide vel grid needs to have independent size\n\
-guidevel_sg$ID$ = sg$ID$.create(MACGrid, name='$NAME_GUIDEVEL$')\n\
+guidevel_sg$ID$ = sg$ID$.create(MACGrid, name='$NAME_VELOCITY_GUIDE$')\n\
\n\
# Keep track of important objects in dict to load them later on\n\
fluid_guiding_dict_s$ID$ = { 'guidevel' : guidevel_sg$ID$ }\n";
@@ -700,14 +700,16 @@ const std::string fluid_load_guiding =
"\n\
def fluid_load_guiding_$ID$(path, framenr, file_format):\n\
mantaMsg('Fluid load guiding, frame ' + str(framenr))\n\
+ guidevel_sg$ID$.setName('$NAME_VELOCITY_GUIDE$')\n\
fluid_file_import_s$ID$(dict=fluid_guiding_dict_s$ID$, path=path, framenr=framenr, file_format=file_format, file_name=file_guiding_s$ID$)\n";
const std::string fluid_load_vel =
"\n\
def fluid_load_vel_$ID$(path, framenr, file_format):\n\
mantaMsg('Fluid load vel, frame ' + str(framenr))\n\
+ guidevel_sg$ID$.setName('$NAME_VELOCITY$') # for loading data the guidevel grid will pretend to be the vel grid\n\
fluid_vel_dict_s$ID$ = { 'vel' : guidevel_sg$ID$ }\n\
- fluid_file_import_s$ID$(dict=fluid_vel_dict_s$ID$, path=path, framenr=framenr, file_format=file_format)\n";
+ fluid_file_import_s$ID$(dict=fluid_vel_dict_s$ID$, path=path, framenr=framenr, file_format=file_format, file_name=file_data_s$ID$)\n";
//////////////////////////////////////////////////////////////////////
// EXPORT
@@ -748,12 +750,13 @@ def fluid_file_export_s$ID$(framenr, file_format, path, dict, file_name=None, mo
const std::string fluid_save_guiding =
"\n\
-def fluid_save_guiding_$ID$(path, framenr, file_format):\n\
+def fluid_save_guiding_$ID$(path, framenr, file_format, resumable):\n\
mantaMsg('Fluid save guiding, frame ' + str(framenr))\n\
+ dict = fluid_guiding_dict_s$ID$\n\
if not withMPSave or isWindows:\n\
- fluid_file_export_s$ID$(dict=fluid_guiding_dict_s$ID$, framenr=framenr, file_format=file_format, path=path, file_name=file_guiding_s$ID$)\n\
+ fluid_file_export_s$ID$(dict=dict, framenr=framenr, file_format=file_format, path=path, file_name=file_guiding_s$ID$)\n\
else:\n\
- fluid_cache_multiprocessing_start_$ID$(function=fluid_file_export_s$ID$, file_name=file_guiding_s$ID$, framenr=framenr, format_data=file_format, path_data=path, dict=fluid_guiding_dict_s$ID$, do_join=False)\n";
+ fluid_cache_multiprocessing_start_$ID$(function=fluid_file_export_s$ID$, file_name=file_guiding_s$ID$, framenr=framenr, format_data=file_format, path_data=path, dict=dict, do_join=False)\n";
//////////////////////////////////////////////////////////////////////
// STANDALONE MODE
@@ -770,8 +773,6 @@ if (GUI):\n\
cache_resumable = $CACHE_RESUMABLE$\n\
cache_dir = '$CACHE_DIR$'\n\
file_format_data = '$CACHE_DATA_FORMAT$'\n\
-file_format_noise = '$CACHE_NOISE_FORMAT$'\n\
-file_format_particles = '$CACHE_PARTICLE_FORMAT$'\n\
file_format_mesh = '$CACHE_MESH_FORMAT$'\n\
\n\
# How many frame to load from cache\n\
diff --git a/intern/mantaflow/intern/strings/liquid_script.h b/intern/mantaflow/intern/strings/liquid_script.h
index 04505206601..08d8dcd7de3 100644
--- a/intern/mantaflow/intern/strings/liquid_script.h
+++ b/intern/mantaflow/intern/strings/liquid_script.h
@@ -48,7 +48,8 @@ meshRadiusFactor_s$ID$ = $MESH_PARTICLE_RADIUS$\n\
smoothenPos_s$ID$ = $MESH_SMOOTHEN_POS$\n\
smoothenNeg_s$ID$ = $MESH_SMOOTHEN_NEG$\n\
randomness_s$ID$ = $PARTICLE_RANDOMNESS$\n\
-surfaceTension_s$ID$ = $LIQUID_SURFACE_TENSION$\n";
+surfaceTension_s$ID$ = $LIQUID_SURFACE_TENSION$\n\
+maxSysParticles_s$ID$ = $PP_PARTICLE_MAXIMUM$\n";
const std::string liquid_variables_particles =
"\n\
@@ -216,6 +217,7 @@ def liquid_adaptive_step_$ID$(framenr):\n\
else:\n\
pVel_pp$ID$.setSource(grid=None, isMAC=False)\n\
\n\
+ pp_s$ID$.maxParticles = maxSysParticles_s$ID$ # remember, 0 means no particle cap\n\
sampleLevelsetWithParticles(phi=phiIn_s$ID$, flags=flags_s$ID$, parts=pp_s$ID$, discretization=particleNumber_s$ID$, randomness=randomness_s$ID$)\n\
flags_s$ID$.updateFromLevelset(phi_s$ID$)\n\
\n\
@@ -477,7 +479,7 @@ const std::string liquid_standalone =
def load(frame, cache_resumable):\n\
liquid_load_data_$ID$(os.path.join(cache_dir, 'data'), frame, file_format_data, cache_resumable)\n\
if using_sndparts_s$ID$:\n\
- liquid_load_particles_$ID$(os.path.join(cache_dir, 'particles'), frame, file_format_particles, cache_resumable)\n\
+ liquid_load_particles_$ID$(os.path.join(cache_dir, 'particles'), frame, file_format_data, cache_resumable)\n\
if using_mesh_s$ID$:\n\
liquid_load_mesh_$ID$(os.path.join(cache_dir, 'mesh'), frame, file_format_mesh)\n\
if using_guiding_s$ID$:\n\
diff --git a/intern/mantaflow/intern/strings/smoke_script.h b/intern/mantaflow/intern/strings/smoke_script.h
index 332aa2342ee..f81259115c5 100644
--- a/intern/mantaflow/intern/strings/smoke_script.h
+++ b/intern/mantaflow/intern/strings/smoke_script.h
@@ -601,7 +601,7 @@ const std::string smoke_standalone =
def load(frame, cache_resumable):\n\
smoke_load_data_$ID$(os.path.join(cache_dir, 'data'), frame, file_format_data, cache_resumable)\n\
if using_noise_s$ID$:\n\
- smoke_load_noise_$ID$(os.path.join(cache_dir, 'noise'), frame, file_format_noise, cache_resumable)\n\
+ smoke_load_noise_$ID$(os.path.join(cache_dir, 'noise'), frame, file_format_data, cache_resumable)\n\
if using_guiding_s$ID$:\n\
fluid_load_guiding_$ID$(os.path.join(cache_dir, 'guiding'), frame, file_format_data)\n\
\n\
diff --git a/intern/sky/source/sky_model.cpp b/intern/sky/source/sky_model.cpp
index 64cf14ec030..e835e04d164 100644
--- a/intern/sky/source/sky_model.cpp
+++ b/intern/sky/source/sky_model.cpp
@@ -178,8 +178,9 @@ static void ArHosekSkyModel_CookConfiguration(ArHosekSkyModel_Dataset dataset,
pow(solar_elevation, 5.0) * elev_matrix[i + 45]);
}
- if (int_turbidity == 10)
+ if (int_turbidity == 10) {
return;
+ }
// alb 0 high turb
elev_matrix = dataset + (9 * 6 * (int_turbidity));
@@ -243,8 +244,9 @@ static double ArHosekSkyModel_CookRadianceConfiguration(ArHosekSkyModel_Radiance
10.0 * pow(1.0 - solar_elevation, 2.0) * pow(solar_elevation, 3.0) * elev_matrix[3] +
5.0 * (1.0 - solar_elevation) * pow(solar_elevation, 4.0) * elev_matrix[4] +
pow(solar_elevation, 5.0) * elev_matrix[5]);
- if (int_turbidity == 10)
+ if (int_turbidity == 10) {
return res;
+ }
// alb 0 high turb
elev_matrix = dataset + (6 * (int_turbidity));
@@ -298,16 +300,18 @@ double SKY_arhosekskymodel_radiance(SKY_ArHosekSkyModelState *state,
{
int low_wl = (int)((wavelength - 320.0) / 40.0);
- if (low_wl < 0 || low_wl >= 11)
+ if (low_wl < 0 || low_wl >= 11) {
return 0.0;
+ }
double interp = fmod((wavelength - 320.0) / 40.0, 1.0);
double val_low = ArHosekSkyModel_GetRadianceInternal(state->configs[low_wl], theta, gamma) *
state->radiances[low_wl] * state->emission_correction_factor_sky[low_wl];
- if (interp < 1e-6)
+ if (interp < 1e-6) {
return val_low;
+ }
double result = (1.0 - interp) * val_low;