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:
Diffstat (limited to 'intern')
-rw-r--r--intern/CMakeLists.txt1
-rw-r--r--intern/cycles/blender/addon/ui.py252
-rw-r--r--intern/dualcon/dualcon.h2
-rw-r--r--intern/dualcon/intern/octree.cpp2
-rw-r--r--intern/ghost/CMakeLists.txt180
-rw-r--r--intern/ghost/GHOST_IContext.h1
-rw-r--r--intern/ghost/GHOST_ISystem.h4
-rw-r--r--intern/ghost/GHOST_IWindow.h8
-rw-r--r--intern/ghost/intern/GHOST_C-api.cpp11
-rw-r--r--intern/ghost/intern/GHOST_Debug.h18
-rw-r--r--intern/ghost/intern/GHOST_DisplayManagerWin32.cpp12
-rw-r--r--intern/ghost/intern/GHOST_DropTargetWin32.cpp24
-rw-r--r--intern/ghost/intern/GHOST_EventKey.h2
-rw-r--r--intern/ghost/intern/GHOST_EventPrinter.h2
-rw-r--r--intern/ghost/intern/GHOST_ISystem.cpp57
-rw-r--r--intern/ghost/intern/GHOST_IXrGraphicsBinding.h2
-rw-r--r--intern/ghost/intern/GHOST_NDOFManager.cpp2
-rw-r--r--intern/ghost/intern/GHOST_System.cpp6
-rw-r--r--intern/ghost/intern/GHOST_System.h8
-rw-r--r--intern/ghost/intern/GHOST_SystemCocoa.h2
-rw-r--r--intern/ghost/intern/GHOST_SystemCocoa.mm2
-rw-r--r--intern/ghost/intern/GHOST_SystemNULL.h2
-rw-r--r--intern/ghost/intern/GHOST_SystemSDL.cpp2
-rw-r--r--intern/ghost/intern/GHOST_SystemSDL.h2
-rw-r--r--intern/ghost/intern/GHOST_SystemWayland.cpp1654
-rw-r--r--intern/ghost/intern/GHOST_SystemWayland.h111
-rw-r--r--intern/ghost/intern/GHOST_SystemWin32.cpp2
-rw-r--r--intern/ghost/intern/GHOST_SystemWin32.h2
-rw-r--r--intern/ghost/intern/GHOST_SystemX11.cpp8
-rw-r--r--intern/ghost/intern/GHOST_SystemX11.h2
-rw-r--r--intern/ghost/intern/GHOST_Window.h5
-rw-r--r--intern/ghost/intern/GHOST_WindowCocoa.h8
-rw-r--r--intern/ghost/intern/GHOST_WindowCocoa.mm9
-rw-r--r--intern/ghost/intern/GHOST_WindowNULL.h9
-rw-r--r--intern/ghost/intern/GHOST_WindowSDL.cpp10
-rw-r--r--intern/ghost/intern/GHOST_WindowSDL.h7
-rw-r--r--intern/ghost/intern/GHOST_WindowWayland.cpp406
-rw-r--r--intern/ghost/intern/GHOST_WindowWayland.h121
-rw-r--r--intern/ghost/intern/GHOST_WindowWin32.cpp15
-rw-r--r--intern/ghost/intern/GHOST_WindowWin32.h8
-rw-r--r--intern/ghost/intern/GHOST_WindowX11.cpp19
-rw-r--r--intern/ghost/intern/GHOST_WindowX11.h7
-rw-r--r--intern/ghost/intern/GHOST_XrGraphicsBinding.cpp6
-rw-r--r--intern/ghost/intern/GHOST_Xr_openxr_includes.h2
-rw-r--r--intern/ghost/test/CMakeLists.txt3
-rw-r--r--intern/ghost/test/gears/GHOST_Test.cpp11
-rw-r--r--intern/libmv/intern/camera_intrinsics.cc53
-rw-r--r--intern/libmv/intern/camera_intrinsics.h4
-rw-r--r--intern/libmv/libmv/simple_pipeline/bundle.cc527
-rw-r--r--intern/libmv/libmv/simple_pipeline/camera_intrinsics.cc63
-rw-r--r--intern/libmv/libmv/simple_pipeline/camera_intrinsics.h58
-rw-r--r--intern/libmv/libmv/simple_pipeline/distortion_models.cc92
-rw-r--r--intern/libmv/libmv/simple_pipeline/distortion_models.h78
-rw-r--r--intern/mantaflow/intern/MANTA_main.cpp1669
-rw-r--r--intern/mantaflow/intern/MANTA_main.h109
-rw-r--r--intern/mantaflow/intern/strings/fluid_script.h54
-rw-r--r--intern/mantaflow/intern/strings/liquid_script.h8
-rw-r--r--intern/mantaflow/intern/strings/smoke_script.h4
-rw-r--r--intern/string/CMakeLists.txt38
-rw-r--r--intern/string/STR_String.h366
-rw-r--r--intern/string/intern/STR_String.cpp637
61 files changed, 4233 insertions, 2556 deletions
diff --git a/intern/CMakeLists.txt b/intern/CMakeLists.txt
index 4e780dc9f0f..fa18f4d793a 100644
--- a/intern/CMakeLists.txt
+++ b/intern/CMakeLists.txt
@@ -20,7 +20,6 @@
# add_subdirectory(atomic) # header only
add_subdirectory(clog)
-add_subdirectory(string)
add_subdirectory(ghost)
add_subdirectory(guardedalloc)
add_subdirectory(libmv)
diff --git a/intern/cycles/blender/addon/ui.py b/intern/cycles/blender/addon/ui.py
index 7cf615620a3..08641c05941 100644
--- a/intern/cycles/blender/addon/ui.py
+++ b/intern/cycles/blender/addon/ui.py
@@ -500,8 +500,9 @@ class CYCLES_RENDER_PT_light_paths_caustics(CyclesButtonsPanel, Panel):
col = layout.column()
col.prop(cscene, "blur_glossy")
- col.prop(cscene, "caustics_reflective")
- col.prop(cscene, "caustics_refractive")
+ col = layout.column(heading="Caustics", align=True)
+ col.prop(cscene, "caustics_reflective", text="Reflective")
+ col.prop(cscene, "caustics_refractive", text="Refractive")
class CYCLES_RENDER_PT_motion_blur(CyclesButtonsPanel, Panel):
@@ -762,22 +763,16 @@ class CYCLES_RENDER_PT_filter(CyclesButtonsPanel, Panel):
rd = scene.render
view_layer = context.view_layer
- flow = layout.grid_flow(row_major=True, columns=0, even_columns=True, even_rows=False, align=False)
-
- col = flow.column()
+ col = layout.column(heading="Include")
col.prop(view_layer, "use_sky", text="Environment")
- col = flow.column()
col.prop(view_layer, "use_ao", text="Ambient Occlusion")
- col = flow.column()
col.prop(view_layer, "use_solid", text="Surfaces")
- col = flow.column()
col.prop(view_layer, "use_strand", text="Hair")
- col = flow.column()
col.prop(view_layer, "use_volumes", text="Volumes")
if with_freestyle:
- col = flow.column()
- col.prop(view_layer, "use_freestyle", text="Freestyle")
- col.active = rd.use_freestyle
+ sub = col.row(align=True)
+ sub.prop(view_layer, "use_freestyle", text="Freestyle")
+ sub.active = rd.use_freestyle
class CYCLES_RENDER_PT_override(CyclesButtonsPanel, Panel):
@@ -819,36 +814,27 @@ class CYCLES_RENDER_PT_passes_data(CyclesButtonsPanel, Panel):
view_layer = context.view_layer
cycles_view_layer = view_layer.cycles
- flow = layout.grid_flow(row_major=True, columns=0, even_columns=True, even_rows=False, align=False)
- col = flow.column()
+ col = layout.column(heading="Include", align=True)
col.prop(view_layer, "use_pass_combined")
- col = flow.column()
col.prop(view_layer, "use_pass_z")
- col = flow.column()
col.prop(view_layer, "use_pass_mist")
- col = flow.column()
col.prop(view_layer, "use_pass_normal")
- col = flow.column()
- col.prop(view_layer, "use_pass_vector")
- col.active = not rd.use_motion_blur
- col = flow.column()
+ sub = col.column()
+ sub.active = not rd.use_motion_blur
+ sub.prop(view_layer, "use_pass_vector")
col.prop(view_layer, "use_pass_uv")
- col = flow.column()
+
+ col.prop(cycles_view_layer, "denoising_store_passes", text="Denoising Data")
+
+ col = layout.column(heading="Indexes", align=True)
col.prop(view_layer, "use_pass_object_index")
- col = flow.column()
col.prop(view_layer, "use_pass_material_index")
- layout.separator()
-
- flow = layout.grid_flow(row_major=True, columns=0, even_columns=True, even_rows=False, align=False)
- col = flow.column()
- col.prop(cycles_view_layer, "denoising_store_passes", text="Denoising Data")
- col = flow.column()
+ col = layout.column(heading="Debug", align=True)
col.prop(cycles_view_layer, "pass_debug_render_time", text="Render Time")
- col = flow.column()
col.prop(cycles_view_layer, "pass_debug_sample_count", text="Sample Count")
- layout.separator()
+
layout.prop(view_layer, "pass_alpha_threshold")
@@ -866,38 +852,26 @@ class CYCLES_RENDER_PT_passes_light(CyclesButtonsPanel, Panel):
view_layer = context.view_layer
cycles_view_layer = view_layer.cycles
- split = layout.split(factor=0.35)
- split.use_property_split = False
- split.label(text="Diffuse")
- row = split.row(align=True)
- row.prop(view_layer, "use_pass_diffuse_direct", text="Direct", toggle=True)
- row.prop(view_layer, "use_pass_diffuse_indirect", text="Indirect", toggle=True)
- row.prop(view_layer, "use_pass_diffuse_color", text="Color", toggle=True)
-
- split = layout.split(factor=0.35)
- split.use_property_split = False
- split.label(text="Glossy")
- row = split.row(align=True)
- row.prop(view_layer, "use_pass_glossy_direct", text="Direct", toggle=True)
- row.prop(view_layer, "use_pass_glossy_indirect", text="Indirect", toggle=True)
- row.prop(view_layer, "use_pass_glossy_color", text="Color", toggle=True)
-
- split = layout.split(factor=0.35)
- split.use_property_split = False
- split.label(text="Transmission")
- row = split.row(align=True)
- row.prop(view_layer, "use_pass_transmission_direct", text="Direct", toggle=True)
- row.prop(view_layer, "use_pass_transmission_indirect", text="Indirect", toggle=True)
- row.prop(view_layer, "use_pass_transmission_color", text="Color", toggle=True)
-
- split = layout.split(factor=0.35)
- split.use_property_split = False
- split.label(text="Volume")
- row = split.row(align=True)
- row.prop(cycles_view_layer, "use_pass_volume_direct", text="Direct", toggle=True)
- row.prop(cycles_view_layer, "use_pass_volume_indirect", text="Indirect", toggle=True)
+ col = layout.column(heading="Diffuse", align=True)
+ col.prop(view_layer, "use_pass_diffuse_direct", text="Direct")
+ col.prop(view_layer, "use_pass_diffuse_indirect", text="Indirect")
+ col.prop(view_layer, "use_pass_diffuse_color", text="Color")
- col = layout.column(align=True)
+ col = layout.column(heading="Glossy", align=True)
+ col.prop(view_layer, "use_pass_glossy_direct", text="Direct")
+ col.prop(view_layer, "use_pass_glossy_indirect", text="Indirect")
+ col.prop(view_layer, "use_pass_glossy_color", text="Color")
+
+ col = layout.column(heading="Transmission", align=True)
+ col.prop(view_layer, "use_pass_transmission_direct", text="Direct")
+ col.prop(view_layer, "use_pass_transmission_indirect", text="Indirect")
+ col.prop(view_layer, "use_pass_transmission_color", text="Color")
+
+ col = layout.column(heading="Volume", align=True)
+ col.prop(cycles_view_layer, "use_pass_volume_direct", text="Direct")
+ col.prop(cycles_view_layer, "use_pass_volume_indirect", text="Indirect")
+
+ col = layout.column(heading="Other", align=True)
col.prop(view_layer, "use_pass_emit", text="Emission")
col.prop(view_layer, "use_pass_environment")
col.prop(view_layer, "use_pass_shadow")
@@ -918,11 +892,10 @@ class CYCLES_RENDER_PT_passes_crypto(CyclesButtonsPanel, Panel):
cycles_view_layer = context.view_layer.cycles
- row = layout.row(align=True)
- row.use_property_split = False
- row.prop(cycles_view_layer, "use_pass_crypto_object", text="Object", toggle=True)
- row.prop(cycles_view_layer, "use_pass_crypto_material", text="Material", toggle=True)
- row.prop(cycles_view_layer, "use_pass_crypto_asset", text="Asset", toggle=True)
+ col = layout.column(heading="Include", align=True)
+ col.prop(cycles_view_layer, "use_pass_crypto_object", text="Object")
+ col.prop(cycles_view_layer, "use_pass_crypto_material", text="Material")
+ col.prop(cycles_view_layer, "use_pass_crypto_asset", text="Asset")
layout.prop(cycles_view_layer, "pass_crypto_depth", text="Levels")
@@ -1012,10 +985,9 @@ class CYCLES_RENDER_PT_denoising(CyclesButtonsPanel, Panel):
view_layer = context.view_layer
cycles_view_layer = view_layer.cycles
- split = layout.split()
- split.active = cycles_view_layer.use_denoising
+ layout.active = cycles_view_layer.use_denoising
- col = split.column(align=True)
+ col = layout.column()
if show_optix_denoising(context):
col.prop(cycles_view_layer, "use_optix_denoising")
@@ -1026,51 +998,29 @@ class CYCLES_RENDER_PT_denoising(CyclesButtonsPanel, Panel):
return
col.prop(cycles_view_layer, "denoising_radius", text="Radius")
+
+ col = layout.column()
col.prop(cycles_view_layer, "denoising_strength", slider=True, text="Strength")
col.prop(cycles_view_layer, "denoising_feature_strength", slider=True, text="Feature Strength")
col.prop(cycles_view_layer, "denoising_relative_pca")
layout.separator()
- split = layout.split(factor=0.5)
- split.active = cycles_view_layer.use_denoising or cycles_view_layer.denoising_store_passes
-
- col = split.column()
- col.alignment = 'RIGHT'
- col.label(text="Diffuse")
+ col = layout.column()
+ col.active = cycles_view_layer.use_denoising or cycles_view_layer.denoising_store_passes
- row = split.row(align=True)
- row.use_property_split = False
+ row = col.row(heading="Diffuse", align=True)
row.prop(cycles_view_layer, "denoising_diffuse_direct", text="Direct", toggle=True)
row.prop(cycles_view_layer, "denoising_diffuse_indirect", text="Indirect", toggle=True)
- split = layout.split(factor=0.5)
- split.active = cycles_view_layer.use_denoising or cycles_view_layer.denoising_store_passes
-
- col = split.column()
- col.alignment = 'RIGHT'
- col.label(text="Glossy")
-
- row = split.row(align=True)
- row.use_property_split = False
+ row = col.row(heading="Glossy", align=True)
row.prop(cycles_view_layer, "denoising_glossy_direct", text="Direct", toggle=True)
row.prop(cycles_view_layer, "denoising_glossy_indirect", text="Indirect", toggle=True)
- split = layout.split(factor=0.5)
- split.active = cycles_view_layer.use_denoising or cycles_view_layer.denoising_store_passes
-
- col = split.column()
- col.alignment = 'RIGHT'
- col.label(text="Transmission")
-
- row = split.row(align=True)
- row.use_property_split = False
+ row = col.row(heading="Transmission", align=True)
row.prop(cycles_view_layer, "denoising_transmission_direct", text="Direct", toggle=True)
row.prop(cycles_view_layer, "denoising_transmission_indirect", text="Indirect", toggle=True)
- split = layout.split(factor=0.5)
- split.active = cycles_view_layer.use_denoising or cycles_view_layer.denoising_store_passes
-
class CYCLES_PT_post_processing(CyclesButtonsPanel, Panel):
bl_label = "Post Processing"
@@ -1084,7 +1034,7 @@ class CYCLES_PT_post_processing(CyclesButtonsPanel, Panel):
rd = context.scene.render
- col = layout.column(align=True)
+ col = layout.column(align=True, heading="Pipeline")
col.prop(rd, "use_compositing")
col.prop(rd, "use_sequencer")
@@ -1273,22 +1223,18 @@ class CYCLES_OBJECT_PT_visibility(CyclesButtonsPanel, Panel):
layout = self.layout
layout.use_property_split = True
- flow = layout.grid_flow(row_major=False, columns=0, even_columns=True, even_rows=False, align=False)
- layout = self.layout
ob = context.object
- col = flow.column()
- col.prop(ob, "hide_viewport", text="Show in Viewports", invert_checkbox=True, toggle=False)
- col = flow.column()
- col.prop(ob, "hide_render", text="Show in Renders", invert_checkbox=True, toggle=False)
- col = flow.column()
- col.prop(ob, "hide_select", text="Selectable", invert_checkbox=True, toggle=False)
+ layout.prop(ob, "hide_select", text="Selectable", invert_checkbox=True, toggle=False)
+
+ col = layout.column(heading="Show in")
+ col.prop(ob, "hide_viewport", text="Viewports", invert_checkbox=True, toggle=False)
+ col.prop(ob, "hide_render", text="Renders", invert_checkbox=True, toggle=False)
if has_geometry_visibility(ob):
cob = ob.cycles
- col = flow.column()
+ col = layout.column(heading="Mask")
col.prop(cob, "is_shadow_catcher")
- col = flow.column()
col.prop(cob, "is_holdout")
@@ -1312,24 +1258,16 @@ class CYCLES_OBJECT_PT_visibility_ray_visibility(CyclesButtonsPanel, Panel):
cob = ob.cycles
visibility = ob.cycles_visibility
- flow = layout.grid_flow(row_major=True, columns=0, even_columns=True, even_rows=False, align=False)
-
- col = flow.column()
+ col = layout.column()
col.prop(visibility, "camera")
- col = flow.column()
col.prop(visibility, "diffuse")
- col = flow.column()
col.prop(visibility, "glossy")
- col = flow.column()
col.prop(visibility, "transmission")
- col = flow.column()
col.prop(visibility, "scatter")
if ob.type != 'LIGHT':
- col = flow.column()
- col.prop(visibility, "shadow")
-
- layout.separator()
+ sub = col.column()
+ sub.prop(visibility, "shadow")
class CYCLES_OBJECT_PT_visibility_culling(CyclesButtonsPanel, Panel):
@@ -1352,15 +1290,13 @@ class CYCLES_OBJECT_PT_visibility_culling(CyclesButtonsPanel, Panel):
ob = context.object
cob = ob.cycles
- flow = layout.grid_flow(row_major=True, columns=0, even_columns=True, even_rows=False, align=False)
-
- col = flow.column()
- col.active = scene.render.use_simplify and cscene.use_camera_cull
- col.prop(cob, "use_camera_cull")
+ row = layout.row()
+ row.active = scene.render.use_simplify and cscene.use_camera_cull
+ row.prop(cob, "use_camera_cull")
- col = flow.column()
- col.active = scene.render.use_simplify and cscene.use_distance_cull
- col.prop(cob, "use_distance_cull")
+ row = layout.row()
+ row.active = scene.render.use_simplify and cscene.use_distance_cull
+ row.prop(cob, "use_distance_cull")
def panel_node_draw(layout, id_data, output_type, input_name):
@@ -1474,6 +1410,8 @@ class CYCLES_LIGHT_PT_nodes(CyclesButtonsPanel, Panel):
def draw(self, context):
layout = self.layout
+ layout.use_property_split = True
+
light = context.light
panel_node_draw(layout, light, 'OUTPUT_LIGHT', 'Surface')
@@ -1523,6 +1461,8 @@ class CYCLES_WORLD_PT_surface(CyclesButtonsPanel, Panel):
def draw(self, context):
layout = self.layout
+ layout.use_property_split = True
+
world = context.world
if not panel_node_draw(layout, world, 'OUTPUT_WORLD', 'Surface'):
@@ -1542,6 +1482,8 @@ class CYCLES_WORLD_PT_volume(CyclesButtonsPanel, Panel):
def draw(self, context):
layout = self.layout
+ layout.use_property_split = True
+
world = context.world
panel_node_draw(layout, world, 'OUTPUT_WORLD', 'Volume')
@@ -1729,6 +1671,8 @@ class CYCLES_MATERIAL_PT_surface(CyclesButtonsPanel, Panel):
def draw(self, context):
layout = self.layout
+ layout.use_property_split = True
+
mat = context.material
if not panel_node_draw(layout, mat, 'OUTPUT_MATERIAL', 'Surface'):
layout.prop(mat, "diffuse_color")
@@ -1747,6 +1691,8 @@ class CYCLES_MATERIAL_PT_volume(CyclesButtonsPanel, Panel):
def draw(self, context):
layout = self.layout
+ layout.use_property_split = True
+
mat = context.material
# cmat = mat.cycles
@@ -1765,6 +1711,8 @@ class CYCLES_MATERIAL_PT_displacement(CyclesButtonsPanel, Panel):
def draw(self, context):
layout = self.layout
+ layout.use_property_split = True
+
mat = context.material
panel_node_draw(layout, mat, 'OUTPUT_MATERIAL', 'Displacement')
@@ -1906,26 +1854,24 @@ class CYCLES_RENDER_PT_bake_influence(CyclesButtonsPanel, Panel):
sub.prop(cbk, "normal_b", text="B")
elif cscene.bake_type == 'COMBINED':
- row = col.row(align=True)
- row.use_property_split = False
- row.prop(cbk, "use_pass_direct", toggle=True)
- row.prop(cbk, "use_pass_indirect", toggle=True)
- flow = col.grid_flow(row_major=False, columns=0, even_columns=False, even_rows=False, align=True)
+ col = layout.column(heading="Lighting", align=True)
+ col.prop(cbk, "use_pass_direct")
+ col.prop(cbk, "use_pass_indirect")
- flow.active = cbk.use_pass_direct or cbk.use_pass_indirect
- flow.prop(cbk, "use_pass_diffuse")
- flow.prop(cbk, "use_pass_glossy")
- flow.prop(cbk, "use_pass_transmission")
- flow.prop(cbk, "use_pass_ambient_occlusion")
- flow.prop(cbk, "use_pass_emit")
+ col = layout.column(heading="Contributions", align=True)
+ col.active = cbk.use_pass_direct or cbk.use_pass_indirect
+ col.prop(cbk, "use_pass_diffuse")
+ col.prop(cbk, "use_pass_glossy")
+ col.prop(cbk, "use_pass_transmission")
+ col.prop(cbk, "use_pass_ambient_occlusion")
+ col.prop(cbk, "use_pass_emit")
elif cscene.bake_type in {'DIFFUSE', 'GLOSSY', 'TRANSMISSION'}:
- row = col.row(align=True)
- row.use_property_split = False
- row.prop(cbk, "use_pass_direct", toggle=True)
- row.prop(cbk, "use_pass_indirect", toggle=True)
- row.prop(cbk, "use_pass_color", toggle=True)
+ col = layout.column(heading="Contributions", align=True)
+ col.prop(cbk, "use_pass_direct")
+ col.prop(cbk, "use_pass_indirect")
+ col.prop(cbk, "use_pass_color")
class CYCLES_RENDER_PT_bake_selected_to_active(CyclesButtonsPanel, Panel):
@@ -2131,17 +2077,17 @@ class CYCLES_RENDER_PT_simplify_culling(CyclesButtonsPanel, Panel):
layout.active = rd.use_simplify
- col = layout.column()
- col.prop(cscene, "use_camera_cull")
- sub = col.column()
+ row = layout.row(heading="Camera Culling")
+ row.prop(cscene, "use_camera_cull", text="")
+ sub = row.column()
sub.active = cscene.use_camera_cull
- sub.prop(cscene, "camera_cull_margin")
+ sub.prop(cscene, "camera_cull_margin", text="")
- col = layout.column()
- col.prop(cscene, "use_distance_cull")
- sub = col.column()
+ row = layout.row(heading="Distance Culling")
+ row.prop(cscene, "use_distance_cull", text="")
+ sub = row.column()
sub.active = cscene.use_distance_cull
- sub.prop(cscene, "distance_cull_margin", text="Distance")
+ sub.prop(cscene, "distance_cull_margin", text="")
class CYCLES_VIEW3D_PT_shading_render_pass(Panel):
diff --git a/intern/dualcon/dualcon.h b/intern/dualcon/dualcon.h
index e9bff72a1ce..60cec101545 100644
--- a/intern/dualcon/dualcon.h
+++ b/intern/dualcon/dualcon.h
@@ -29,7 +29,7 @@ typedef float (*DualConCo)[3];
typedef unsigned int (*DualConTri)[3];
-typedef unsigned int(*DualConLoop);
+typedef unsigned int *DualConLoop;
typedef struct DualConInput {
DualConLoop mloop;
diff --git a/intern/dualcon/intern/octree.cpp b/intern/dualcon/intern/octree.cpp
index 70b3b8bb457..c9d5639cb5d 100644
--- a/intern/dualcon/intern/octree.cpp
+++ b/intern/dualcon/intern/octree.cpp
@@ -480,7 +480,7 @@ void Octree::trace()
if (chdpath != NULL) {
dc_printf("there are incomplete rings.\n");
printPaths(chdpath);
- };
+ }
}
Node *Octree::trace(Node *newnode, int *st, int len, int depth, PathList *&paths)
diff --git a/intern/ghost/CMakeLists.txt b/intern/ghost/CMakeLists.txt
index 68fc9637e02..699ac4afe88 100644
--- a/intern/ghost/CMakeLists.txt
+++ b/intern/ghost/CMakeLists.txt
@@ -21,7 +21,6 @@
set(INC
.
../glew-mx
- ../string
../../source/blender/imbuf
../../source/blender/makesdna
)
@@ -86,7 +85,6 @@ set(SRC
set(LIB
bf_intern_glew_mx
- bf_intern_string
${GLEW_LIBRARY}
)
@@ -151,7 +149,7 @@ if(WITH_HEADLESS OR WITH_GHOST_SDL)
endif()
endif()
-elseif(APPLE AND NOT WITH_X11)
+elseif(APPLE AND NOT WITH_GHOST_X11)
list(APPEND SRC
intern/GHOST_DisplayManagerCocoa.mm
intern/GHOST_SystemCocoa.mm
@@ -179,73 +177,143 @@ elseif(APPLE AND NOT WITH_X11)
)
endif()
-elseif(WITH_X11)
- list(APPEND INC_SYS
- ${X11_X11_INCLUDE_PATH}
- )
-
- list(APPEND SRC
- intern/GHOST_DisplayManagerX11.cpp
- intern/GHOST_SystemX11.cpp
- intern/GHOST_TaskbarX11.cpp
- intern/GHOST_WindowX11.cpp
-
- intern/GHOST_DisplayManagerX11.h
- intern/GHOST_IconX11.h
- intern/GHOST_SystemX11.h
- intern/GHOST_TaskbarX11.h
- intern/GHOST_WindowX11.h
- )
+elseif(WITH_GHOST_X11 OR WITH_GHOST_WAYLAND)
+ if(WITH_GHOST_X11)
+ list(APPEND INC_SYS
+ ${X11_X11_INCLUDE_PATH}
+ )
- if(NOT WITH_GL_EGL)
list(APPEND SRC
- intern/GHOST_ContextGLX.cpp
-
- intern/GHOST_ContextGLX.h
+ intern/GHOST_DisplayManagerX11.cpp
+ intern/GHOST_SystemX11.cpp
+ intern/GHOST_TaskbarX11.cpp
+ intern/GHOST_WindowX11.cpp
+
+ intern/GHOST_DisplayManagerX11.h
+ intern/GHOST_IconX11.h
+ intern/GHOST_SystemX11.h
+ intern/GHOST_TaskbarX11.h
+ intern/GHOST_WindowX11.h
)
- endif()
- if(WITH_GHOST_XDND)
- add_definitions(-DWITH_XDND)
+ if(NOT WITH_GL_EGL)
+ list(APPEND SRC
+ intern/GHOST_ContextGLX.cpp
- list(APPEND LIB
- extern_xdnd
- )
+ intern/GHOST_ContextGLX.h
+ )
+ endif()
- list(APPEND INC
- ../../extern/xdnd
- )
+ if(WITH_GHOST_XDND)
+ add_definitions(-DWITH_XDND)
- list(APPEND SRC
- intern/GHOST_DropTargetX11.cpp
+ list(APPEND LIB
+ extern_xdnd
+ )
- intern/GHOST_DropTargetX11.h
- )
+ list(APPEND INC
+ ../../extern/xdnd
+ )
+
+ list(APPEND SRC
+ intern/GHOST_DropTargetX11.cpp
+
+ intern/GHOST_DropTargetX11.h
+ )
+ endif()
+
+ if(X11_XF86keysym_INCLUDE_PATH)
+ add_definitions(-DWITH_XF86KEYSYM)
+ list(APPEND INC_SYS
+ ${X11_XF86keysym_INCLUDE_PATH}
+ )
+ endif()
+
+ if(WITH_X11_XF86VMODE)
+ add_definitions(-DWITH_X11_XF86VMODE)
+ list(APPEND INC_SYS
+ ${X11_xf86vmode_INCLUDE_PATH}
+ )
+ endif()
+
+ if(WITH_X11_XFIXES)
+ add_definitions(-DWITH_X11_XFIXES)
+ list(APPEND INC_SYS
+ ${X11_Xfixes_INCLUDE_PATH}
+ )
+ endif()
+
+ if(WITH_X11_ALPHA)
+ add_definitions(-DWITH_X11_ALPHA)
+ endif()
+
+ if(WITH_X11_XINPUT)
+ add_definitions(-DWITH_X11_XINPUT)
+ list(APPEND INC_SYS
+ ${X11_Xinput_INCLUDE_PATH}
+ )
+ endif()
+
+ add_definitions(-DWITH_GHOST_X11)
endif()
- if(X11_XF86keysym_INCLUDE_PATH)
- add_definitions(-DWITH_XF86KEYSYM)
+ if(WITH_GHOST_WAYLAND)
list(APPEND INC_SYS
- ${X11_XF86keysym_INCLUDE_PATH}
+ ${wayland-client_INCLUDE_DIRS}
+ ${wayland-egl_INCLUDE_DIRS}
+ ${xkbcommon_INCLUDE_DIRS}
+ ${wayland-cursor_INCLUDE_DIRS}
)
- endif()
- if(WITH_X11_XF86VMODE)
- add_definitions(-DWITH_X11_XF86VMODE)
- list(APPEND INC_SYS
- ${X11_xf86vmode_INCLUDE_PATH}
+ list(APPEND SRC
+ intern/GHOST_SystemWayland.cpp
+ intern/GHOST_WindowWayland.cpp
+
+ intern/GHOST_SystemWayland.h
+ intern/GHOST_WindowWayland.h
)
- endif()
- if(WITH_X11_XFIXES)
- add_definitions(-DWITH_X11_XFIXES)
+ pkg_get_variable(WAYLAND_SCANNER wayland-scanner wayland_scanner)
+ pkg_get_variable(WAYLAND_PROTOCOLS_DIR wayland-protocols pkgdatadir)
+
+ # Generate protocols bindings.
+ macro(generate_protocol_bindings NAME PROT_DEF)
+ add_custom_command(
+ OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${NAME}-client-protocol.h
+ COMMAND ${WAYLAND_SCANNER} client-header ${PROT_DEF} ${NAME}-client-protocol.h
+ )
+ add_custom_command(
+ OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${NAME}-client-protocol.c
+ COMMAND ${WAYLAND_SCANNER} private-code ${PROT_DEF} ${NAME}-client-protocol.c
+ DEPENDS ${NAME}-client-protocol.h
+ )
+ list(APPEND SRC
+ ${CMAKE_CURRENT_BINARY_DIR}/${NAME}-client-protocol.c
+ ${CMAKE_CURRENT_BINARY_DIR}/${NAME}-client-protocol.h
+ )
+ endmacro()
+
list(APPEND INC_SYS
- ${X11_Xfixes_INCLUDE_PATH}
+ ${CMAKE_CURRENT_BINARY_DIR}
+ )
+
+ # xdg-shell.
+ generate_protocol_bindings(
+ xdg-shell
+ "${WAYLAND_PROTOCOLS_DIR}/stable/xdg-shell/xdg-shell.xml"
+ )
+ # Pointer-constraints.
+ generate_protocol_bindings(
+ pointer-constraints
+ "${WAYLAND_PROTOCOLS_DIR}/unstable/pointer-constraints/pointer-constraints-unstable-v1.xml"
+ )
+ # Relative-pointer.
+ generate_protocol_bindings(
+ relative-pointer
+ "${WAYLAND_PROTOCOLS_DIR}/unstable/relative-pointer/relative-pointer-unstable-v1.xml"
)
- endif()
- if(WITH_X11_ALPHA)
- add_definitions(-DWITH_X11_ALPHA)
+ add_definitions(-DWITH_GHOST_WAYLAND)
endif()
if(WITH_INPUT_NDOF)
@@ -260,14 +328,6 @@ elseif(WITH_X11)
add_definitions(-DPREFIX="${CMAKE_INSTALL_PREFIX}")
endif()
- if(WITH_X11_XINPUT)
- add_definitions(-DWITH_X11_XINPUT)
- list(APPEND INC_SYS
- ${X11_Xinput_INCLUDE_PATH}
- )
- endif()
-
- add_definitions(-DWITH_X11)
elseif(WIN32)
# # Warnings as errors, this is too strict!
diff --git a/intern/ghost/GHOST_IContext.h b/intern/ghost/GHOST_IContext.h
index 1225262a908..8c24261644a 100644
--- a/intern/ghost/GHOST_IContext.h
+++ b/intern/ghost/GHOST_IContext.h
@@ -26,7 +26,6 @@
#define __GHOST_IContext_H__
#include "GHOST_Types.h"
-#include "STR_String.h"
/**
* Interface for GHOST context.
diff --git a/intern/ghost/GHOST_ISystem.h b/intern/ghost/GHOST_ISystem.h
index 58d1a08da74..9b619f5c684 100644
--- a/intern/ghost/GHOST_ISystem.h
+++ b/intern/ghost/GHOST_ISystem.h
@@ -27,6 +27,8 @@
#ifndef __GHOST_ISYSTEM_H__
#define __GHOST_ISYSTEM_H__
+#include <stdlib.h>
+
#include "GHOST_IContext.h"
#include "GHOST_ITimerTask.h"
#include "GHOST_IWindow.h"
@@ -240,7 +242,7 @@ class GHOST_ISystem {
* \param parentWindow: Parent (embedder) window
* \return The new window (or 0 if creation failed).
*/
- virtual GHOST_IWindow *createWindow(const STR_String &title,
+ virtual GHOST_IWindow *createWindow(const char *title,
GHOST_TInt32 left,
GHOST_TInt32 top,
GHOST_TUns32 width,
diff --git a/intern/ghost/GHOST_IWindow.h b/intern/ghost/GHOST_IWindow.h
index daf07b81e01..62290d20f1c 100644
--- a/intern/ghost/GHOST_IWindow.h
+++ b/intern/ghost/GHOST_IWindow.h
@@ -27,7 +27,9 @@
#include "GHOST_Rect.h"
#include "GHOST_Types.h"
-#include "STR_String.h"
+
+#include <stdlib.h>
+#include <string>
/**
* Interface for GHOST windows.
@@ -81,13 +83,13 @@ class GHOST_IWindow {
* Sets the title displayed in the title bar.
* \param title The title to display in the title bar.
*/
- virtual void setTitle(const STR_String &title) = 0;
+ virtual void setTitle(const char *title) = 0;
/**
* Returns the title displayed in the title bar.
* \param title The title displayed in the title bar.
*/
- virtual void getTitle(STR_String &title) const = 0;
+ virtual std::string getTitle() const = 0;
/**
* Returns the window rectangle dimensions.
diff --git a/intern/ghost/intern/GHOST_C-api.cpp b/intern/ghost/intern/GHOST_C-api.cpp
index db9fd2e3bf9..843684b6d2e 100644
--- a/intern/ghost/intern/GHOST_C-api.cpp
+++ b/intern/ghost/intern/GHOST_C-api.cpp
@@ -24,6 +24,7 @@
*/
#include <stdlib.h>
+#include <string.h>
#include "GHOST_C-api.h"
#include "GHOST_IEvent.h"
@@ -527,17 +528,15 @@ void GHOST_SetTitle(GHOST_WindowHandle windowhandle, const char *title)
char *GHOST_GetTitle(GHOST_WindowHandle windowhandle)
{
GHOST_IWindow *window = (GHOST_IWindow *)windowhandle;
- STR_String title;
+ std::string title = window->getTitle();
- window->getTitle(title);
-
- char *ctitle = (char *)malloc(title.Length() + 1);
+ char *ctitle = (char *)malloc(title.size() + 1);
if (ctitle == NULL) {
return NULL;
}
- strcpy(ctitle, title.Ptr());
+ strcpy(ctitle, title.c_str());
return ctitle;
}
@@ -678,7 +677,7 @@ GHOST_TSuccess GHOST_ActivateOpenGLContext(GHOST_ContextHandle contexthandle)
return context->activateDrawingContext();
}
else {
- GHOST_PRINT("GHOST_ActivateOpenGLContext: Context not valid");
+ GHOST_PRINTF("%s: Context not valid\n", __func__);
return GHOST_kFailure;
}
}
diff --git a/intern/ghost/intern/GHOST_Debug.h b/intern/ghost/intern/GHOST_Debug.h
index 0163197e14a..5b5c2688297 100644
--- a/intern/ghost/intern/GHOST_Debug.h
+++ b/intern/ghost/intern/GHOST_Debug.h
@@ -33,15 +33,11 @@
#endif
#ifdef WITH_GHOST_DEBUG
-# define GHOST_DEBUG // spit ghost events to stdout
-#endif // WITH_GHOST_DEBUG
-
-#ifdef GHOST_DEBUG
# include <iostream>
# include <stdio.h> //for printf()
-#endif // GHOST_DEBUG
+#endif // WITH_GHOST_DEBUG
-#ifdef GHOST_DEBUG
+#ifdef WITH_GHOST_DEBUG
# define GHOST_PRINT(x) \
{ \
std::cout << x; \
@@ -52,10 +48,10 @@
printf(x, __VA_ARGS__); \
} \
(void)0
-#else // GHOST_DEBUG
+#else // WITH_GHOST_DEBUG
# define GHOST_PRINT(x)
# define GHOST_PRINTF(x, ...)
-#endif // GHOST_DEBUG
+#endif // WITH_GHOST_DEBUG
#ifdef WITH_ASSERT_ABORT
# include <stdio.h> //for fprintf()
@@ -70,7 +66,7 @@
} \
} \
(void)0
-#elif defined(GHOST_DEBUG)
+#elif defined(WITH_GHOST_DEBUG)
# define GHOST_ASSERT(x, info) \
{ \
if (!(x)) { \
@@ -80,8 +76,8 @@
} \
} \
(void)0
-#else // GHOST_DEBUG
+#else // WITH_GHOST_DEBUG
# define GHOST_ASSERT(x, info) ((void)0)
-#endif // GHOST_DEBUG
+#endif // WITH_GHOST_DEBUG
#endif // __GHOST_DEBUG_H__
diff --git a/intern/ghost/intern/GHOST_DisplayManagerWin32.cpp b/intern/ghost/intern/GHOST_DisplayManagerWin32.cpp
index aabaffc7732..3557c4cd0c5 100644
--- a/intern/ghost/intern/GHOST_DisplayManagerWin32.cpp
+++ b/intern/ghost/intern/GHOST_DisplayManagerWin32.cpp
@@ -80,13 +80,13 @@ GHOST_TSuccess GHOST_DisplayManagerWin32::getDisplaySetting(GHOST_TUns8 display,
GHOST_TSuccess success;
DEVMODE dm;
if (::EnumDisplaySettings(display_device.DeviceName, index, &dm)) {
-#ifdef GHOST_DEBUG
+#ifdef WITH_GHOST_DEBUG
printf("display mode: width=%d, height=%d, bpp=%d, frequency=%d\n",
dm.dmPelsWidth,
dm.dmPelsHeight,
dm.dmBitsPerPel,
dm.dmDisplayFrequency);
-#endif // GHOST_DEBUG
+#endif // WITH_GHOST_DEBUG
setting.xPixels = dm.dmPelsWidth;
setting.yPixels = dm.dmPelsHeight;
setting.bpp = dm.dmBitsPerPel;
@@ -142,16 +142,16 @@ GHOST_TSuccess GHOST_DisplayManagerWin32::setCurrentDisplaySetting(
* dm.dmSize = sizeof(DEVMODE);
* dm.dmDriverExtra = 0;
*/
-#ifdef GHOST_DEBUG
+#ifdef WITH_GHOST_DEBUG
printf("display change: Requested settings:\n");
printf(" dmBitsPerPel=%d\n", dm.dmBitsPerPel);
printf(" dmPelsWidth=%d\n", dm.dmPelsWidth);
printf(" dmPelsHeight=%d\n", dm.dmPelsHeight);
printf(" dmDisplayFrequency=%d\n", dm.dmDisplayFrequency);
-#endif // GHOST_DEBUG
+#endif // WITH_GHOST_DEBUG
LONG status = ::ChangeDisplaySettings(&dm, CDS_FULLSCREEN);
-#ifdef GHOST_DEBUG
+#ifdef WITH_GHOST_DEBUG
switch (status) {
case DISP_CHANGE_SUCCESSFUL:
printf("display change: The settings change was successful.\n");
@@ -182,6 +182,6 @@ GHOST_TSuccess GHOST_DisplayManagerWin32::setCurrentDisplaySetting(
printf("display change: Return value invalid\n");
break;
}
-#endif // GHOST_DEBUG
+#endif // WITH_GHOST_DEBUG
return status == DISP_CHANGE_SUCCESSFUL ? GHOST_kSuccess : GHOST_kFailure;
}
diff --git a/intern/ghost/intern/GHOST_DropTargetWin32.cpp b/intern/ghost/intern/GHOST_DropTargetWin32.cpp
index 9f8ce3b5095..fe11d9a28f2 100644
--- a/intern/ghost/intern/GHOST_DropTargetWin32.cpp
+++ b/intern/ghost/intern/GHOST_DropTargetWin32.cpp
@@ -28,10 +28,10 @@
#include "utf_winfunc.h"
#include "utfconv.h"
-#ifdef GHOST_DEBUG
+#ifdef WITH_GHOST_DEBUG
// utility
void printLastError(void);
-#endif // GHOST_DEBUG
+#endif // WITH_GHOST_DEBUG
GHOST_DropTargetWin32::GHOST_DropTargetWin32(GHOST_WindowWin32 *window, GHOST_SystemWin32 *system)
: m_window(window), m_system(system)
@@ -209,9 +209,9 @@ void *GHOST_DropTargetWin32::getGhostData(IDataObject *pDataObject)
// return getDropDataAsBitmap(pDataObject);
break;
default:
-#ifdef GHOST_DEBUG
+#ifdef WITH_GHOST_DEBUG
::printf("\nGHOST_kDragnDropTypeUnknown");
-#endif // GHOST_DEBUG
+#endif // WITH_GHOST_DEBUG
return NULL;
break;
}
@@ -284,10 +284,10 @@ void *GHOST_DropTargetWin32::getDropDataAsString(IDataObject *pDataObject)
// Free memory
::GlobalUnlock(stgmed.hGlobal);
::ReleaseStgMedium(&stgmed);
-#ifdef GHOST_DEBUG
+#ifdef WITH_GHOST_DEBUG
::printf("\n<converted droped unicode string>\n%s\n</droped converted unicode string>\n",
tmp_string);
-#endif // GHOST_DEBUG
+#endif // WITH_GHOST_DEBUG
return tmp_string;
}
}
@@ -336,9 +336,9 @@ int GHOST_DropTargetWin32::WideCharToANSI(LPCWSTR in, char *&out)
NULL);
if (!size) {
-#ifdef GHOST_DEBUG
+#ifdef WITH_GHOST_DEBUG
::printLastError();
-#endif // GHOST_DEBUG
+#endif // WITH_GHOST_DEBUG
return 0;
}
@@ -351,16 +351,16 @@ int GHOST_DropTargetWin32::WideCharToANSI(LPCWSTR in, char *&out)
size = ::WideCharToMultiByte(CP_ACP, 0x00000400, in, -1, (LPSTR)out, size, NULL, NULL);
if (!size) {
-#ifdef GHOST_DEBUG
+#ifdef WITH_GHOST_DEBUG
::printLastError();
-#endif // GHOST_DEBUG
+#endif // WITH_GHOST_DEBUG
::free(out);
out = NULL;
}
return size;
}
-#ifdef GHOST_DEBUG
+#ifdef WITH_GHOST_DEBUG
void printLastError(void)
{
LPTSTR s;
@@ -378,4 +378,4 @@ void printLastError(void)
LocalFree(s);
}
}
-#endif // GHOST_DEBUG
+#endif // WITH_GHOST_DEBUG
diff --git a/intern/ghost/intern/GHOST_EventKey.h b/intern/ghost/intern/GHOST_EventKey.h
index 24e20b20659..8f59c555914 100644
--- a/intern/ghost/intern/GHOST_EventKey.h
+++ b/intern/ghost/intern/GHOST_EventKey.h
@@ -25,6 +25,8 @@
#ifndef __GHOST_EVENTKEY_H__
#define __GHOST_EVENTKEY_H__
+#include <string.h>
+
#include "GHOST_Event.h"
/**
diff --git a/intern/ghost/intern/GHOST_EventPrinter.h b/intern/ghost/intern/GHOST_EventPrinter.h
index fad9ec3cc69..ead16525ec6 100644
--- a/intern/ghost/intern/GHOST_EventPrinter.h
+++ b/intern/ghost/intern/GHOST_EventPrinter.h
@@ -27,8 +27,6 @@
#include "GHOST_IEventConsumer.h"
-#include "STR_String.h"
-
/**
* An Event consumer that prints all the events to standard out.
* Really useful when debugging.
diff --git a/intern/ghost/intern/GHOST_ISystem.cpp b/intern/ghost/intern/GHOST_ISystem.cpp
index 914f6712676..7c12bfe0306 100644
--- a/intern/ghost/intern/GHOST_ISystem.cpp
+++ b/intern/ghost/intern/GHOST_ISystem.cpp
@@ -27,20 +27,22 @@
#include "GHOST_ISystem.h"
-#ifdef WITH_X11
+#if defined(WITH_HEADLESS)
+# include "GHOST_SystemNULL.h"
+#elif defined(WITH_GHOST_X11) && defined(WITH_GHOST_WAYLAND)
+# include "GHOST_SystemWayland.h"
# include "GHOST_SystemX11.h"
-#else
-# ifdef WITH_HEADLESS
-# include "GHOST_SystemNULL.h"
-# elif defined(WITH_GHOST_SDL)
-# include "GHOST_SystemSDL.h"
-# elif defined(WIN32)
-# include "GHOST_SystemWin32.h"
-# else
-# ifdef __APPLE__
-# include "GHOST_SystemCocoa.h"
-# endif
-# endif
+# include <stdexcept>
+#elif defined(WITH_GHOST_X11)
+# include "GHOST_SystemX11.h"
+#elif defined(WITH_GHOST_WAYLAND)
+# include "GHOST_SystemWayland.h"
+#elif defined(WITH_GHOST_SDL)
+# include "GHOST_SystemSDL.h"
+#elif defined(WIN32)
+# include "GHOST_SystemWin32.h"
+#elif defined(__APPLE__)
+# include "GHOST_SystemCocoa.h"
#endif
GHOST_ISystem *GHOST_ISystem::m_system = NULL;
@@ -49,20 +51,29 @@ GHOST_TSuccess GHOST_ISystem::createSystem()
{
GHOST_TSuccess success;
if (!m_system) {
-#ifdef WITH_X11
- m_system = new GHOST_SystemX11();
-#else
-# ifdef WITH_HEADLESS
+#if defined(WITH_HEADLESS)
m_system = new GHOST_SystemNULL();
-# elif defined(WITH_GHOST_SDL)
+#elif defined(WITH_GHOST_X11) && defined(WITH_GHOST_WAYLAND)
+ /* Special case, try Wayland, fall back to X11. */
+ try {
+ m_system = new GHOST_SystemWayland();
+ }
+ catch (const std::runtime_error &) {
+ /* fallback to X11. */
+ }
+ if (!m_system) {
+ m_system = new GHOST_SystemX11();
+ }
+#elif defined(WITH_GHOST_X11)
+ m_system = new GHOST_SystemX11();
+#elif defined(WITH_GHOST_WAYLAND)
+ m_system = new GHOST_SystemWayland();
+#elif defined(WITH_GHOST_SDL)
m_system = new GHOST_SystemSDL();
-# elif defined(WIN32)
+#elif defined(WIN32)
m_system = new GHOST_SystemWin32();
-# else
-# ifdef __APPLE__
+#elif defined(__APPLE__)
m_system = new GHOST_SystemCocoa();
-# endif
-# endif
#endif
success = m_system != NULL ? GHOST_kSuccess : GHOST_kFailure;
}
diff --git a/intern/ghost/intern/GHOST_IXrGraphicsBinding.h b/intern/ghost/intern/GHOST_IXrGraphicsBinding.h
index cddb557d163..5794a682023 100644
--- a/intern/ghost/intern/GHOST_IXrGraphicsBinding.h
+++ b/intern/ghost/intern/GHOST_IXrGraphicsBinding.h
@@ -33,7 +33,7 @@ class GHOST_IXrGraphicsBinding {
public:
union {
-#if defined(WITH_X11)
+#if defined(WITH_GHOST_X11)
XrGraphicsBindingOpenGLXlibKHR glx;
#elif defined(WIN32)
XrGraphicsBindingOpenGLWin32KHR wgl;
diff --git a/intern/ghost/intern/GHOST_NDOFManager.cpp b/intern/ghost/intern/GHOST_NDOFManager.cpp
index a9fbadab37a..dda78c0ac5b 100644
--- a/intern/ghost/intern/GHOST_NDOFManager.cpp
+++ b/intern/ghost/intern/GHOST_NDOFManager.cpp
@@ -19,6 +19,8 @@
#include "GHOST_EventKey.h"
#include "GHOST_EventNDOF.h"
#include "GHOST_WindowManager.h"
+
+#include <limits.h>
#include <math.h>
#include <stdio.h> // for error/info reporting
#include <string.h> // for memory functions
diff --git a/intern/ghost/intern/GHOST_System.cpp b/intern/ghost/intern/GHOST_System.cpp
index 85eb6d58679..587e4c28102 100644
--- a/intern/ghost/intern/GHOST_System.cpp
+++ b/intern/ghost/intern/GHOST_System.cpp
@@ -309,12 +309,12 @@ GHOST_TSuccess GHOST_System::init()
m_windowManager = new GHOST_WindowManager();
m_eventManager = new GHOST_EventManager();
-#ifdef GHOST_DEBUG
+#ifdef WITH_GHOST_DEBUG
if (m_eventManager) {
m_eventPrinter = new GHOST_EventPrinter();
m_eventManager->addConsumer(m_eventPrinter);
}
-#endif // GHOST_DEBUG
+#endif // WITH_GHOST_DEBUG
if (m_timerManager && m_windowManager && m_eventManager) {
return GHOST_kSuccess;
@@ -367,7 +367,7 @@ GHOST_TSuccess GHOST_System::createFullScreenWindow(GHOST_Window **window,
GHOST_ASSERT(m_displayManager,
"GHOST_System::createFullScreenWindow(): invalid display manager");
// GHOST_PRINT("GHOST_System::createFullScreenWindow(): creating full-screen window\n");
- *window = (GHOST_Window *)createWindow(STR_String(""),
+ *window = (GHOST_Window *)createWindow("",
0,
0,
settings.xPixels,
diff --git a/intern/ghost/intern/GHOST_System.h b/intern/ghost/intern/GHOST_System.h
index eaaa2ff6ee6..0f58be49dff 100644
--- a/intern/ghost/intern/GHOST_System.h
+++ b/intern/ghost/intern/GHOST_System.h
@@ -31,9 +31,9 @@
#include "GHOST_Debug.h"
#include "GHOST_EventManager.h"
#include "GHOST_ModifierKeys.h"
-#ifdef GHOST_DEBUG
+#ifdef WITH_GHOST_DEBUG
# include "GHOST_EventPrinter.h"
-#endif // GHOST_DEBUG
+#endif // WITH_GHOST_DEBUG
class GHOST_DisplayManager;
class GHOST_Event;
@@ -390,9 +390,9 @@ class GHOST_System : public GHOST_ISystem {
#endif
/** Prints all the events. */
-#ifdef GHOST_DEBUG
+#ifdef WITH_GHOST_DEBUG
GHOST_EventPrinter *m_eventPrinter;
-#endif // GHOST_DEBUG
+#endif // WITH_GHOST_DEBUG
/** Settings of the display before the display went fullscreen. */
GHOST_DisplaySetting m_preFullScreenSetting;
diff --git a/intern/ghost/intern/GHOST_SystemCocoa.h b/intern/ghost/intern/GHOST_SystemCocoa.h
index 1e44c3e31d4..d058697470a 100644
--- a/intern/ghost/intern/GHOST_SystemCocoa.h
+++ b/intern/ghost/intern/GHOST_SystemCocoa.h
@@ -100,7 +100,7 @@ class GHOST_SystemCocoa : public GHOST_System {
* \param parentWindow Parent (embedder) window
* \return The new window (or 0 if creation failed).
*/
- GHOST_IWindow *createWindow(const STR_String &title,
+ GHOST_IWindow *createWindow(const char *title,
GHOST_TInt32 left,
GHOST_TInt32 top,
GHOST_TUns32 width,
diff --git a/intern/ghost/intern/GHOST_SystemCocoa.mm b/intern/ghost/intern/GHOST_SystemCocoa.mm
index 3d6d187587c..2b6a2902757 100644
--- a/intern/ghost/intern/GHOST_SystemCocoa.mm
+++ b/intern/ghost/intern/GHOST_SystemCocoa.mm
@@ -698,7 +698,7 @@ void GHOST_SystemCocoa::getAllDisplayDimensions(GHOST_TUns32 &width, GHOST_TUns3
getMainDisplayDimensions(width, height);
}
-GHOST_IWindow *GHOST_SystemCocoa::createWindow(const STR_String &title,
+GHOST_IWindow *GHOST_SystemCocoa::createWindow(const char *title,
GHOST_TInt32 left,
GHOST_TInt32 top,
GHOST_TUns32 width,
diff --git a/intern/ghost/intern/GHOST_SystemNULL.h b/intern/ghost/intern/GHOST_SystemNULL.h
index 68a726f2be8..186cb92d1aa 100644
--- a/intern/ghost/intern/GHOST_SystemNULL.h
+++ b/intern/ghost/intern/GHOST_SystemNULL.h
@@ -106,7 +106,7 @@ class GHOST_SystemNULL : public GHOST_System {
return GHOST_kFailure;
}
- GHOST_IWindow *createWindow(const STR_String &title,
+ GHOST_IWindow *createWindow(const char *title,
GHOST_TInt32 left,
GHOST_TInt32 top,
GHOST_TUns32 width,
diff --git a/intern/ghost/intern/GHOST_SystemSDL.cpp b/intern/ghost/intern/GHOST_SystemSDL.cpp
index 97a75d7a0f5..b32ec4306e8 100644
--- a/intern/ghost/intern/GHOST_SystemSDL.cpp
+++ b/intern/ghost/intern/GHOST_SystemSDL.cpp
@@ -49,7 +49,7 @@ GHOST_SystemSDL::~GHOST_SystemSDL()
SDL_Quit();
}
-GHOST_IWindow *GHOST_SystemSDL::createWindow(const STR_String &title,
+GHOST_IWindow *GHOST_SystemSDL::createWindow(const char *title,
GHOST_TInt32 left,
GHOST_TInt32 top,
GHOST_TUns32 width,
diff --git a/intern/ghost/intern/GHOST_SystemSDL.h b/intern/ghost/intern/GHOST_SystemSDL.h
index 1994781530b..8feec9de61d 100644
--- a/intern/ghost/intern/GHOST_SystemSDL.h
+++ b/intern/ghost/intern/GHOST_SystemSDL.h
@@ -80,7 +80,7 @@ class GHOST_SystemSDL : public GHOST_System {
private:
GHOST_TSuccess init();
- GHOST_IWindow *createWindow(const STR_String &title,
+ GHOST_IWindow *createWindow(const char *title,
GHOST_TInt32 left,
GHOST_TInt32 top,
GHOST_TUns32 width,
diff --git a/intern/ghost/intern/GHOST_SystemWayland.cpp b/intern/ghost/intern/GHOST_SystemWayland.cpp
new file mode 100644
index 00000000000..666515ed088
--- /dev/null
+++ b/intern/ghost/intern/GHOST_SystemWayland.cpp
@@ -0,0 +1,1654 @@
+/*
+ * 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 GHOST
+ */
+
+#include "GHOST_SystemWayland.h"
+#include "GHOST_Event.h"
+#include "GHOST_EventButton.h"
+#include "GHOST_EventCursor.h"
+#include "GHOST_EventDragnDrop.h"
+#include "GHOST_EventKey.h"
+#include "GHOST_EventWheel.h"
+#include "GHOST_WindowManager.h"
+
+#include "GHOST_ContextEGL.h"
+
+#include <EGL/egl.h>
+#include <wayland-egl.h>
+
+#include <algorithm>
+#include <atomic>
+#include <exception>
+#include <thread>
+#include <unordered_map>
+#include <unordered_set>
+
+#include <pointer-constraints-client-protocol.h>
+#include <relative-pointer-client-protocol.h>
+#include <wayland-cursor.h>
+#include <xkbcommon/xkbcommon.h>
+
+#include <fcntl.h>
+#include <linux/input-event-codes.h>
+#include <sys/mman.h>
+#include <unistd.h>
+
+#include <cstring>
+
+struct output_t {
+ struct wl_output *output;
+ int32_t width, height;
+ int transform;
+ int scale;
+ std::string make;
+ std::string model;
+};
+
+struct buffer_t {
+ void *data;
+ size_t size;
+};
+
+struct cursor_t {
+ bool visible;
+ struct wl_surface *surface = nullptr;
+ struct wl_buffer *buffer;
+ struct wl_cursor_image image;
+ struct buffer_t *file_buffer = nullptr;
+};
+
+struct data_offer_t {
+ std::unordered_set<std::string> types;
+ uint32_t source_actions;
+ uint32_t dnd_action;
+ struct wl_data_offer *id;
+ std::atomic<bool> in_use;
+ struct {
+ int x, y;
+ } dnd;
+};
+
+struct data_source_t {
+ struct wl_data_source *data_source;
+ /** Last device that was active. */
+ uint32_t source_serial;
+ char *buffer_out;
+};
+
+struct input_t {
+ GHOST_SystemWayland *system;
+
+ std::string name;
+ struct wl_seat *seat;
+ struct wl_pointer *pointer = nullptr;
+ struct wl_keyboard *keyboard = nullptr;
+
+ uint32_t pointer_serial;
+ int x, y;
+ GHOST_Buttons buttons;
+ struct cursor_t cursor;
+
+ struct zwp_relative_pointer_v1 *relative_pointer;
+ struct zwp_locked_pointer_v1 *locked_pointer;
+
+ struct xkb_context *xkb_context;
+ struct xkb_state *xkb_state;
+
+ struct wl_data_device *data_device = nullptr;
+ struct data_offer_t *data_offer_dnd; /* Drag & Drop. */
+ struct data_offer_t *data_offer_copy_paste; /* Copy & Paste. */
+
+ struct data_source_t *data_source;
+};
+
+struct display_t {
+ GHOST_SystemWayland *system;
+
+ struct wl_display *display;
+ struct wl_registry *registry;
+ struct wl_compositor *compositor = nullptr;
+ struct xdg_wm_base *xdg_shell = nullptr;
+ struct wl_shm *shm = nullptr;
+ std::vector<output_t *> outputs;
+ std::vector<input_t *> inputs;
+ struct wl_cursor_theme *cursor_theme = nullptr;
+ struct wl_data_device_manager *data_device_manager = nullptr;
+ struct zwp_relative_pointer_manager_v1 *relative_pointer_manager = nullptr;
+ struct zwp_pointer_constraints_v1 *pointer_constraints = nullptr;
+
+ std::vector<struct wl_surface *> os_surfaces;
+ std::vector<struct wl_egl_window *> os_egl_windows;
+};
+
+static void display_destroy(display_t *d)
+{
+ if (d->data_device_manager) {
+ wl_data_device_manager_destroy(d->data_device_manager);
+ }
+
+ for (output_t *output : d->outputs) {
+ wl_output_destroy(output->output);
+ delete output;
+ }
+
+ for (input_t *input : d->inputs) {
+ if (input->data_source) {
+ free(input->data_source->buffer_out);
+ if (input->data_source->data_source) {
+ wl_data_source_destroy(input->data_source->data_source);
+ }
+ delete input->data_source;
+ }
+ if (input->data_offer_copy_paste) {
+ wl_data_offer_destroy(input->data_offer_copy_paste->id);
+ delete input->data_offer_copy_paste;
+ }
+ if (input->data_device) {
+ wl_data_device_release(input->data_device);
+ }
+ if (input->pointer) {
+ if (input->cursor.file_buffer) {
+ munmap(input->cursor.file_buffer->data, input->cursor.file_buffer->size);
+ delete input->cursor.file_buffer;
+ }
+ if (input->cursor.surface) {
+ wl_surface_destroy(input->cursor.surface);
+ }
+ if (input->pointer) {
+ wl_pointer_destroy(input->pointer);
+ }
+ }
+ if (input->keyboard) {
+ wl_keyboard_destroy(input->keyboard);
+ }
+ if (input->xkb_state) {
+ xkb_state_unref(input->xkb_state);
+ }
+ if (input->xkb_context) {
+ xkb_context_unref(input->xkb_context);
+ }
+ wl_seat_destroy(input->seat);
+ delete input;
+ }
+
+ if (d->cursor_theme) {
+ wl_cursor_theme_destroy(d->cursor_theme);
+ }
+
+ if (d->shm) {
+ wl_shm_destroy(d->shm);
+ }
+
+ if (d->relative_pointer_manager) {
+ zwp_relative_pointer_manager_v1_destroy(d->relative_pointer_manager);
+ }
+
+ if (d->pointer_constraints) {
+ zwp_pointer_constraints_v1_destroy(d->pointer_constraints);
+ }
+
+ for (wl_egl_window *os_egl_window : d->os_egl_windows) {
+ wl_egl_window_destroy(os_egl_window);
+ }
+
+ for (wl_surface *os_surface : d->os_surfaces) {
+ wl_surface_destroy(os_surface);
+ }
+
+ if (d->compositor) {
+ wl_compositor_destroy(d->compositor);
+ }
+
+ if (d->xdg_shell) {
+ xdg_wm_base_destroy(d->xdg_shell);
+ }
+
+ if (eglGetDisplay) {
+ ::eglTerminate(eglGetDisplay(EGLNativeDisplayType(d->display)));
+ }
+
+ if (d->display) {
+ wl_display_disconnect(d->display);
+ }
+
+ delete d;
+}
+
+static GHOST_TKey xkb_map_gkey(const xkb_keysym_t &sym)
+{
+
+ GHOST_TKey gkey;
+ if (sym >= XKB_KEY_0 && sym <= XKB_KEY_9) {
+ gkey = GHOST_TKey(sym);
+ }
+ else if (sym >= XKB_KEY_KP_0 && sym <= XKB_KEY_KP_9) {
+ gkey = GHOST_TKey(GHOST_kKeyNumpad0 + sym - XKB_KEY_KP_0);
+ }
+ else if (sym >= XKB_KEY_A && sym <= XKB_KEY_Z) {
+ gkey = GHOST_TKey(sym);
+ }
+ else if (sym >= XKB_KEY_a && sym <= XKB_KEY_z) {
+ gkey = GHOST_TKey(sym - XKB_KEY_a + XKB_KEY_A);
+ }
+ else if (sym >= XKB_KEY_F1 && sym <= XKB_KEY_F24) {
+ gkey = GHOST_TKey(GHOST_kKeyF1 + sym - XKB_KEY_F1);
+ }
+ else {
+
+#define GXMAP(k, x, y) \
+ case x: \
+ k = y; \
+ break
+
+ switch (sym) {
+ GXMAP(gkey, XKB_KEY_BackSpace, GHOST_kKeyBackSpace);
+ GXMAP(gkey, XKB_KEY_Tab, GHOST_kKeyTab);
+ GXMAP(gkey, XKB_KEY_Linefeed, GHOST_kKeyLinefeed);
+ GXMAP(gkey, XKB_KEY_Clear, GHOST_kKeyClear);
+ GXMAP(gkey, XKB_KEY_Return, GHOST_kKeyEnter);
+
+ GXMAP(gkey, XKB_KEY_Escape, GHOST_kKeyEsc);
+ GXMAP(gkey, XKB_KEY_space, GHOST_kKeySpace);
+ GXMAP(gkey, XKB_KEY_comma, GHOST_kKeyComma);
+ GXMAP(gkey, XKB_KEY_minus, GHOST_kKeyMinus);
+ GXMAP(gkey, XKB_KEY_plus, GHOST_kKeyPlus);
+ GXMAP(gkey, XKB_KEY_period, GHOST_kKeyPeriod);
+ GXMAP(gkey, XKB_KEY_slash, GHOST_kKeySlash);
+
+ GXMAP(gkey, XKB_KEY_semicolon, GHOST_kKeySemicolon);
+ GXMAP(gkey, XKB_KEY_equal, GHOST_kKeyEqual);
+
+ GXMAP(gkey, XKB_KEY_bracketleft, GHOST_kKeyLeftBracket);
+ GXMAP(gkey, XKB_KEY_bracketright, GHOST_kKeyRightBracket);
+ GXMAP(gkey, XKB_KEY_backslash, GHOST_kKeyBackslash);
+ GXMAP(gkey, XKB_KEY_grave, GHOST_kKeyAccentGrave);
+
+ GXMAP(gkey, XKB_KEY_Shift_L, GHOST_kKeyLeftShift);
+ GXMAP(gkey, XKB_KEY_Shift_R, GHOST_kKeyRightShift);
+ GXMAP(gkey, XKB_KEY_Control_L, GHOST_kKeyLeftControl);
+ GXMAP(gkey, XKB_KEY_Control_R, GHOST_kKeyRightControl);
+ GXMAP(gkey, XKB_KEY_Alt_L, GHOST_kKeyLeftAlt);
+ GXMAP(gkey, XKB_KEY_Alt_R, GHOST_kKeyRightAlt);
+ GXMAP(gkey, XKB_KEY_Super_L, GHOST_kKeyOS);
+ GXMAP(gkey, XKB_KEY_Super_R, GHOST_kKeyOS);
+ GXMAP(gkey, XKB_KEY_Menu, GHOST_kKeyApp);
+
+ GXMAP(gkey, XKB_KEY_Caps_Lock, GHOST_kKeyCapsLock);
+ GXMAP(gkey, XKB_KEY_Num_Lock, GHOST_kKeyNumLock);
+ GXMAP(gkey, XKB_KEY_Scroll_Lock, GHOST_kKeyScrollLock);
+
+ GXMAP(gkey, XKB_KEY_Left, GHOST_kKeyLeftArrow);
+ GXMAP(gkey, XKB_KEY_KP_Left, GHOST_kKeyLeftArrow);
+ GXMAP(gkey, XKB_KEY_Right, GHOST_kKeyRightArrow);
+ GXMAP(gkey, XKB_KEY_KP_Right, GHOST_kKeyRightArrow);
+ GXMAP(gkey, XKB_KEY_Up, GHOST_kKeyUpArrow);
+ GXMAP(gkey, XKB_KEY_KP_Up, GHOST_kKeyUpArrow);
+ GXMAP(gkey, XKB_KEY_Down, GHOST_kKeyDownArrow);
+ GXMAP(gkey, XKB_KEY_KP_Down, GHOST_kKeyDownArrow);
+
+ GXMAP(gkey, XKB_KEY_Print, GHOST_kKeyPrintScreen);
+ GXMAP(gkey, XKB_KEY_Pause, GHOST_kKeyPause);
+
+ GXMAP(gkey, XKB_KEY_Insert, GHOST_kKeyInsert);
+ GXMAP(gkey, XKB_KEY_KP_Insert, GHOST_kKeyInsert);
+ GXMAP(gkey, XKB_KEY_Delete, GHOST_kKeyDelete);
+ GXMAP(gkey, XKB_KEY_KP_Delete, GHOST_kKeyDelete);
+ GXMAP(gkey, XKB_KEY_Home, GHOST_kKeyHome);
+ GXMAP(gkey, XKB_KEY_KP_Home, GHOST_kKeyHome);
+ GXMAP(gkey, XKB_KEY_End, GHOST_kKeyEnd);
+ GXMAP(gkey, XKB_KEY_KP_End, GHOST_kKeyEnd);
+ GXMAP(gkey, XKB_KEY_Page_Up, GHOST_kKeyUpPage);
+ GXMAP(gkey, XKB_KEY_KP_Page_Up, GHOST_kKeyUpPage);
+ GXMAP(gkey, XKB_KEY_Page_Down, GHOST_kKeyDownPage);
+ GXMAP(gkey, XKB_KEY_KP_Page_Down, GHOST_kKeyDownPage);
+
+ GXMAP(gkey, XKB_KEY_KP_Decimal, GHOST_kKeyNumpadPeriod);
+ GXMAP(gkey, XKB_KEY_KP_Enter, GHOST_kKeyNumpadEnter);
+ GXMAP(gkey, XKB_KEY_KP_Add, GHOST_kKeyNumpadPlus);
+ GXMAP(gkey, XKB_KEY_KP_Subtract, GHOST_kKeyNumpadMinus);
+ GXMAP(gkey, XKB_KEY_KP_Multiply, GHOST_kKeyNumpadAsterisk);
+ GXMAP(gkey, XKB_KEY_KP_Divide, GHOST_kKeyNumpadSlash);
+
+ GXMAP(gkey, XKB_KEY_XF86AudioPlay, GHOST_kKeyMediaPlay);
+ GXMAP(gkey, XKB_KEY_XF86AudioStop, GHOST_kKeyMediaStop);
+ GXMAP(gkey, XKB_KEY_XF86AudioPrev, GHOST_kKeyMediaFirst);
+ GXMAP(gkey, XKB_KEY_XF86AudioNext, GHOST_kKeyMediaLast);
+ default:
+ GHOST_PRINT("unhandled key: " << sym << std::endl);
+ gkey = GHOST_kKeyUnknown;
+ }
+#undef GXMAP
+ }
+
+ return gkey;
+}
+
+static const int default_cursor_size = 24;
+
+static const std::unordered_map<GHOST_TStandardCursor, std::string> cursors = {
+ {GHOST_kStandardCursorDefault, "left_ptr"},
+ {GHOST_kStandardCursorRightArrow, "right_ptr"},
+ {GHOST_kStandardCursorLeftArrow, "left_ptr"},
+ {GHOST_kStandardCursorInfo, ""},
+ {GHOST_kStandardCursorDestroy, ""},
+ {GHOST_kStandardCursorHelp, "question_arrow"},
+ {GHOST_kStandardCursorWait, "watch"},
+ {GHOST_kStandardCursorText, "xterm"},
+ {GHOST_kStandardCursorCrosshair, "crosshair"},
+ {GHOST_kStandardCursorCrosshairA, ""},
+ {GHOST_kStandardCursorCrosshairB, ""},
+ {GHOST_kStandardCursorCrosshairC, ""},
+ {GHOST_kStandardCursorPencil, ""},
+ {GHOST_kStandardCursorUpArrow, "sb_up_arrow"},
+ {GHOST_kStandardCursorDownArrow, "sb_down_arrow"},
+ {GHOST_kStandardCursorVerticalSplit, ""},
+ {GHOST_kStandardCursorHorizontalSplit, ""},
+ {GHOST_kStandardCursorEraser, ""},
+ {GHOST_kStandardCursorKnife, ""},
+ {GHOST_kStandardCursorEyedropper, ""},
+ {GHOST_kStandardCursorZoomIn, ""},
+ {GHOST_kStandardCursorZoomOut, ""},
+ {GHOST_kStandardCursorMove, "move"},
+ {GHOST_kStandardCursorNSEWScroll, ""},
+ {GHOST_kStandardCursorNSScroll, ""},
+ {GHOST_kStandardCursorEWScroll, ""},
+ {GHOST_kStandardCursorStop, ""},
+ {GHOST_kStandardCursorUpDown, "sb_v_double_arrow"},
+ {GHOST_kStandardCursorLeftRight, "sb_h_double_arrow"},
+ {GHOST_kStandardCursorTopSide, "top_side"},
+ {GHOST_kStandardCursorBottomSide, "bottom_side"},
+ {GHOST_kStandardCursorLeftSide, "left_side"},
+ {GHOST_kStandardCursorRightSide, "right_side"},
+ {GHOST_kStandardCursorTopLeftCorner, "top_left_corner"},
+ {GHOST_kStandardCursorTopRightCorner, "top_right_corner"},
+ {GHOST_kStandardCursorBottomRightCorner, "bottom_right_corner"},
+ {GHOST_kStandardCursorBottomLeftCorner, "bottom_left_corner"},
+ {GHOST_kStandardCursorCopy, "copy"},
+};
+
+static constexpr const char *mime_text_plain = "text/plain";
+static constexpr const char *mime_text_utf8 = "text/plain;charset=utf-8";
+static constexpr const char *mime_text_uri = "text/uri-list";
+
+static const std::unordered_map<std::string, GHOST_TDragnDropTypes> mime_dnd = {
+ {mime_text_plain, GHOST_kDragnDropTypeString},
+ {mime_text_utf8, GHOST_kDragnDropTypeString},
+ {mime_text_uri, GHOST_kDragnDropTypeFilenames},
+};
+
+static const std::vector<std::string> mime_preference_order = {
+ mime_text_uri,
+ mime_text_utf8,
+ mime_text_plain,
+};
+
+static const std::vector<std::string> mime_send = {
+ "UTF8_STRING",
+ "COMPOUND_TEXT",
+ "TEXT",
+ "STRING",
+ "text/plain;charset=utf-8",
+ "text/plain",
+};
+
+/* -------------------------------------------------------------------- */
+/** \name Interface Callbacks
+ *
+ * These callbacks are registered for Wayland interfaces and called when
+ * an event is received from the compositor.
+ * \{ */
+
+static void relative_pointer_relative_motion(
+ void *data,
+ struct zwp_relative_pointer_v1 * /*zwp_relative_pointer_v1*/,
+ uint32_t /*utime_hi*/,
+ uint32_t /*utime_lo*/,
+ wl_fixed_t dx,
+ wl_fixed_t dy,
+ wl_fixed_t /*dx_unaccel*/,
+ wl_fixed_t /*dy_unaccel*/)
+{
+ input_t *input = static_cast<input_t *>(data);
+
+ input->x += wl_fixed_to_int(dx);
+ input->y += wl_fixed_to_int(dy);
+
+ input->system->pushEvent(
+ new GHOST_EventCursor(input->system->getMilliSeconds(),
+ GHOST_kEventCursorMove,
+ input->system->getWindowManager()->getActiveWindow(),
+ input->x,
+ input->y,
+ GHOST_TABLET_DATA_NONE));
+}
+
+static const zwp_relative_pointer_v1_listener relative_pointer_listener = {
+ relative_pointer_relative_motion};
+
+static void dnd_events(const input_t *const input, const GHOST_TEventType event)
+{
+ const GHOST_TUns64 time = input->system->getMilliSeconds();
+ GHOST_IWindow *const window = input->system->getWindowManager()->getActiveWindow();
+ for (const std::string &type : mime_preference_order) {
+ input->system->pushEvent(new GHOST_EventDragnDrop(time,
+ event,
+ mime_dnd.at(type),
+ window,
+ input->data_offer_dnd->dnd.x,
+ input->data_offer_dnd->dnd.y,
+ nullptr));
+ }
+}
+
+static std::string read_pipe(data_offer_t *data_offer, const std::string mime_receive)
+{
+ int pipefd[2];
+ pipe(pipefd);
+ wl_data_offer_receive(data_offer->id, mime_receive.c_str(), pipefd[1]);
+ close(pipefd[1]);
+
+ std::string data;
+ ssize_t len;
+ char buffer[4096];
+ while ((len = read(pipefd[0], buffer, sizeof(buffer))) > 0) {
+ data.insert(data.end(), buffer, buffer + len);
+ }
+ close(pipefd[0]);
+ data_offer->in_use.store(false);
+
+ return data;
+}
+
+/**
+ * A target accepts an offered mime type.
+ *
+ * Sent when a target accepts pointer_focus or motion events. If
+ * a target does not accept any of the offered types, type is NULL.
+ */
+static void data_source_target(void * /*data*/,
+ struct wl_data_source * /*wl_data_source*/,
+ const char * /*mime_type*/)
+{
+ /* pass */
+}
+
+static void data_source_send(void *data,
+ struct wl_data_source * /*wl_data_source*/,
+ const char * /*mime_type*/,
+ int32_t fd)
+{
+ const char *const buffer = static_cast<char *>(data);
+ write(fd, buffer, strlen(buffer) + 1);
+ close(fd);
+}
+
+static void data_source_cancelled(void * /*data*/, struct wl_data_source *wl_data_source)
+{
+ wl_data_source_destroy(wl_data_source);
+}
+
+/**
+ * The drag-and-drop operation physically finished.
+ *
+ * The user performed the drop action. This event does not
+ * indicate acceptance, #wl_data_source.cancelled may still be
+ * emitted afterwards if the drop destination does not accept any mime type.
+ */
+static void data_source_dnd_drop_performed(void * /*data*/,
+ struct wl_data_source * /*wl_data_source*/)
+{
+ /* pass */
+}
+
+/**
+ * The drag-and-drop operation concluded.
+ *
+ * The drop destination finished interoperating with this data
+ * source, so the client is now free to destroy this data source
+ * and free all associated data.
+ */
+static void data_source_dnd_finished(void * /*data*/, struct wl_data_source * /*wl_data_source*/)
+{
+ /* pass */
+}
+
+/**
+ * Notify the selected action.
+ *
+ * This event indicates the action selected by the compositor
+ * after matching the source/destination side actions. Only one
+ * action (or none) will be offered here.
+ */
+static void data_source_action(void * /*data*/,
+ struct wl_data_source * /*wl_data_source*/,
+ uint32_t /*dnd_action*/)
+{
+ /* pass */
+}
+
+static const struct wl_data_source_listener data_source_listener = {
+ data_source_target,
+ data_source_send,
+ data_source_cancelled,
+ data_source_dnd_drop_performed,
+ data_source_dnd_finished,
+ data_source_action,
+};
+
+static void data_offer_offer(void *data,
+ struct wl_data_offer * /*wl_data_offer*/,
+ const char *mime_type)
+{
+ static_cast<data_offer_t *>(data)->types.insert(mime_type);
+}
+
+static void data_offer_source_actions(void *data,
+ struct wl_data_offer * /*wl_data_offer*/,
+ uint32_t source_actions)
+{
+ static_cast<data_offer_t *>(data)->source_actions = source_actions;
+}
+
+static void data_offer_action(void *data,
+ struct wl_data_offer * /*wl_data_offer*/,
+ uint32_t dnd_action)
+{
+ static_cast<data_offer_t *>(data)->dnd_action = dnd_action;
+}
+
+static const struct wl_data_offer_listener data_offer_listener = {
+ data_offer_offer,
+ data_offer_source_actions,
+ data_offer_action,
+};
+
+static void data_device_data_offer(void * /*data*/,
+ struct wl_data_device * /*wl_data_device*/,
+ struct wl_data_offer *id)
+{
+ data_offer_t *data_offer = new data_offer_t;
+ data_offer->id = id;
+ wl_data_offer_add_listener(id, &data_offer_listener, data_offer);
+}
+
+static void data_device_enter(void *data,
+ struct wl_data_device * /*wl_data_device*/,
+ uint32_t serial,
+ struct wl_surface * /*surface*/,
+ wl_fixed_t x,
+ wl_fixed_t y,
+ struct wl_data_offer *id)
+{
+ input_t *input = static_cast<input_t *>(data);
+ input->data_offer_dnd = static_cast<data_offer_t *>(wl_data_offer_get_user_data(id));
+ data_offer_t *data_offer = input->data_offer_dnd;
+
+ data_offer->in_use.store(true);
+ data_offer->dnd.x = wl_fixed_to_int(x);
+ data_offer->dnd.y = wl_fixed_to_int(y);
+
+ wl_data_offer_set_actions(id,
+ WL_DATA_DEVICE_MANAGER_DND_ACTION_COPY |
+ WL_DATA_DEVICE_MANAGER_DND_ACTION_MOVE,
+ WL_DATA_DEVICE_MANAGER_DND_ACTION_COPY);
+
+ for (const std::string &type : mime_preference_order) {
+ wl_data_offer_accept(id, serial, type.c_str());
+ }
+
+ dnd_events(input, GHOST_kEventDraggingEntered);
+}
+
+static void data_device_leave(void *data, struct wl_data_device * /*wl_data_device*/)
+{
+ input_t *input = static_cast<input_t *>(data);
+
+ dnd_events(input, GHOST_kEventDraggingExited);
+
+ if (input->data_offer_dnd && !input->data_offer_dnd->in_use.load()) {
+ wl_data_offer_destroy(input->data_offer_dnd->id);
+ delete input->data_offer_dnd;
+ input->data_offer_dnd = nullptr;
+ }
+}
+
+static void data_device_motion(void *data,
+ struct wl_data_device * /*wl_data_device*/,
+ uint32_t /*time*/,
+ wl_fixed_t x,
+ wl_fixed_t y)
+{
+ input_t *input = static_cast<input_t *>(data);
+ input->data_offer_dnd->dnd.x = wl_fixed_to_int(x);
+ input->data_offer_dnd->dnd.y = wl_fixed_to_int(y);
+ dnd_events(input, GHOST_kEventDraggingUpdated);
+}
+
+static void data_device_drop(void *data, struct wl_data_device * /*wl_data_device*/)
+{
+ input_t *input = static_cast<input_t *>(data);
+ data_offer_t *data_offer = input->data_offer_dnd;
+
+ const std::string mime_receive = *std::find_first_of(mime_preference_order.begin(),
+ mime_preference_order.end(),
+ data_offer->types.begin(),
+ data_offer->types.end());
+
+ auto read_uris = [](GHOST_SystemWayland *const system,
+ data_offer_t *data_offer,
+ const std::string mime_receive) {
+ const int x = data_offer->dnd.x;
+ const int y = data_offer->dnd.y;
+
+ const std::string data = read_pipe(data_offer, mime_receive);
+
+ wl_data_offer_finish(data_offer->id);
+ wl_data_offer_destroy(data_offer->id);
+
+ delete data_offer;
+ data_offer = nullptr;
+
+ if (mime_receive == mime_text_uri) {
+ static constexpr const char *file_proto = "file://";
+ static constexpr const char *crlf = "\r\n";
+
+ std::vector<std::string> uris;
+
+ size_t pos = 0;
+ while (true) {
+ pos = data.find(file_proto, pos);
+ const size_t start = pos + sizeof(file_proto) - 1;
+ pos = data.find(crlf, pos);
+ const size_t end = pos;
+
+ if (pos == std::string::npos) {
+ break;
+ }
+ uris.push_back(data.substr(start, end - start));
+ }
+
+ GHOST_TStringArray *flist = static_cast<GHOST_TStringArray *>(
+ malloc(sizeof(GHOST_TStringArray)));
+ flist->count = int(uris.size());
+ flist->strings = static_cast<GHOST_TUns8 **>(malloc(uris.size() * sizeof(GHOST_TUns8 *)));
+ for (size_t i = 0; i < uris.size(); i++) {
+ flist->strings[i] = static_cast<GHOST_TUns8 *>(
+ malloc((uris[i].size() + 1) * sizeof(GHOST_TUns8)));
+ memcpy(flist->strings[i], uris[i].data(), uris[i].size() + 1);
+ }
+ system->pushEvent(new GHOST_EventDragnDrop(system->getMilliSeconds(),
+ GHOST_kEventDraggingDropDone,
+ GHOST_kDragnDropTypeFilenames,
+ system->getWindowManager()->getActiveWindow(),
+ x,
+ y,
+ flist));
+ }
+ else if (mime_receive == mime_text_plain || mime_receive == mime_text_utf8) {
+ /* TODO: enable use of internal functions 'txt_insert_buf' and
+ * 'text_update_edited' to behave like dropped text was pasted. */
+ }
+ wl_display_roundtrip(system->display());
+ };
+
+ std::thread read_thread(read_uris, input->system, data_offer, mime_receive);
+ read_thread.detach();
+}
+
+static void data_device_selection(void *data,
+ struct wl_data_device * /*wl_data_device*/,
+ struct wl_data_offer *id)
+{
+ input_t *input = static_cast<input_t *>(data);
+ data_offer_t *data_offer = input->data_offer_copy_paste;
+
+ /* Delete old data offer. */
+ if (data_offer != nullptr) {
+ wl_data_offer_destroy(data_offer->id);
+ delete data_offer;
+ data_offer = nullptr;
+ }
+
+ if (id == nullptr) {
+ return;
+ }
+
+ /* Get new data offer. */
+ data_offer = static_cast<data_offer_t *>(wl_data_offer_get_user_data(id));
+ input->data_offer_copy_paste = data_offer;
+
+ std::string mime_receive;
+ for (const std::string &type : {mime_text_utf8, mime_text_plain}) {
+ if (data_offer->types.count(type)) {
+ mime_receive = type;
+ break;
+ }
+ }
+
+ auto read_selection = [](GHOST_SystemWayland *const system,
+ data_offer_t *data_offer,
+ const std::string mime_receive) {
+ const std::string data = read_pipe(data_offer, mime_receive);
+ system->setSelection(data);
+ };
+
+ std::thread read_thread(read_selection, input->system, data_offer, mime_receive);
+ read_thread.detach();
+}
+
+static const struct wl_data_device_listener data_device_listener = {
+ data_device_data_offer,
+ data_device_enter,
+ data_device_leave,
+ data_device_motion,
+ data_device_drop,
+ data_device_selection,
+};
+
+static void buffer_release(void * /*data*/, struct wl_buffer *wl_buffer)
+{
+ wl_buffer_destroy(wl_buffer);
+}
+
+const struct wl_buffer_listener buffer_listener = {
+ buffer_release,
+};
+
+static void pointer_enter(void *data,
+ struct wl_pointer * /*wl_pointer*/,
+ uint32_t serial,
+ struct wl_surface *surface,
+ wl_fixed_t surface_x,
+ wl_fixed_t surface_y)
+{
+ if (!surface) {
+ return;
+ }
+ input_t *input = static_cast<input_t *>(data);
+ input->pointer_serial = serial;
+ input->x = wl_fixed_to_int(surface_x);
+ input->y = wl_fixed_to_int(surface_y);
+
+ static_cast<GHOST_WindowWayland *>(wl_surface_get_user_data(surface))->activate();
+}
+
+static void pointer_leave(void * /*data*/,
+ struct wl_pointer * /*wl_pointer*/,
+ uint32_t /*serial*/,
+ struct wl_surface *surface)
+{
+ if (surface != nullptr) {
+ static_cast<GHOST_WindowWayland *>(wl_surface_get_user_data(surface))->deactivate();
+ }
+}
+
+static void pointer_motion(void *data,
+ struct wl_pointer * /*wl_pointer*/,
+ uint32_t /*time*/,
+ wl_fixed_t surface_x,
+ wl_fixed_t surface_y)
+{
+ input_t *input = static_cast<input_t *>(data);
+
+ input->x = wl_fixed_to_int(surface_x);
+ input->y = wl_fixed_to_int(surface_y);
+
+ input->system->pushEvent(
+ new GHOST_EventCursor(input->system->getMilliSeconds(),
+ GHOST_kEventCursorMove,
+ input->system->getWindowManager()->getActiveWindow(),
+ wl_fixed_to_int(surface_x),
+ wl_fixed_to_int(surface_y),
+ GHOST_TABLET_DATA_NONE));
+}
+
+static void pointer_button(void *data,
+ struct wl_pointer * /*wl_pointer*/,
+ uint32_t serial,
+ uint32_t /*time*/,
+ uint32_t button,
+ uint32_t state)
+{
+ GHOST_TEventType etype = GHOST_kEventUnknown;
+ switch (state) {
+ case WL_POINTER_BUTTON_STATE_RELEASED:
+ etype = GHOST_kEventButtonUp;
+ break;
+ case WL_POINTER_BUTTON_STATE_PRESSED:
+ etype = GHOST_kEventButtonDown;
+ break;
+ }
+
+ GHOST_TButtonMask ebutton = GHOST_kButtonMaskLeft;
+ switch (button) {
+ case BTN_LEFT:
+ ebutton = GHOST_kButtonMaskLeft;
+ break;
+ case BTN_MIDDLE:
+ ebutton = GHOST_kButtonMaskMiddle;
+ break;
+ case BTN_RIGHT:
+ ebutton = GHOST_kButtonMaskRight;
+ break;
+ }
+
+ input_t *input = static_cast<input_t *>(data);
+ input->data_source->source_serial = serial;
+ input->buttons.set(ebutton, state == WL_POINTER_BUTTON_STATE_PRESSED);
+ input->system->pushEvent(
+ new GHOST_EventButton(input->system->getMilliSeconds(),
+ etype,
+ input->system->getWindowManager()->getActiveWindow(),
+ ebutton,
+ GHOST_TABLET_DATA_NONE));
+}
+
+static void pointer_axis(void *data,
+ struct wl_pointer * /*wl_pointer*/,
+ uint32_t /*time*/,
+ uint32_t axis,
+ wl_fixed_t value)
+{
+ if (axis != WL_POINTER_AXIS_VERTICAL_SCROLL) {
+ return;
+ }
+ input_t *input = static_cast<input_t *>(data);
+ input->system->pushEvent(
+ new GHOST_EventWheel(input->system->getMilliSeconds(),
+ input->system->getWindowManager()->getActiveWindow(),
+ std::signbit(value) ? +1 : -1));
+}
+
+static const struct wl_pointer_listener pointer_listener = {
+ pointer_enter,
+ pointer_leave,
+ pointer_motion,
+ pointer_button,
+ pointer_axis,
+};
+
+static void keyboard_keymap(
+ void *data, struct wl_keyboard * /*wl_keyboard*/, uint32_t format, int32_t fd, uint32_t size)
+{
+ input_t *input = static_cast<input_t *>(data);
+
+ if ((!data) || (format != WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1)) {
+ close(fd);
+ return;
+ }
+
+ char *map_str = static_cast<char *>(mmap(nullptr, size, PROT_READ, MAP_PRIVATE, fd, 0));
+ if (map_str == MAP_FAILED) {
+ close(fd);
+ throw std::runtime_error("keymap mmap failed: " + std::string(std::strerror(errno)));
+ }
+
+ struct xkb_keymap *keymap = xkb_keymap_new_from_string(
+ input->xkb_context, map_str, XKB_KEYMAP_FORMAT_TEXT_V1, XKB_KEYMAP_COMPILE_NO_FLAGS);
+ munmap(map_str, size);
+ close(fd);
+
+ if (!keymap) {
+ return;
+ }
+
+ input->xkb_state = xkb_state_new(keymap);
+
+ xkb_keymap_unref(keymap);
+}
+
+/**
+ * Enter event.
+ *
+ * Notification that this seat's keyboard focus is on a certain
+ * surface.
+ */
+static void keyboard_enter(void * /*data*/,
+ struct wl_keyboard * /*wl_keyboard*/,
+ uint32_t /*serial*/,
+ struct wl_surface * /*surface*/,
+ struct wl_array * /*keys*/)
+{
+ /* pass */
+}
+
+/**
+ * Leave event.
+ *
+ * Notification that this seat's keyboard focus is no longer on a
+ * certain surface.
+ */
+static void keyboard_leave(void * /*data*/,
+ struct wl_keyboard * /*wl_keyboard*/,
+ uint32_t /*serial*/,
+ struct wl_surface * /*surface*/)
+{
+ /* pass */
+}
+
+static void keyboard_key(void *data,
+ struct wl_keyboard * /*wl_keyboard*/,
+ uint32_t serial,
+ uint32_t /*time*/,
+ uint32_t key,
+ uint32_t state)
+{
+ input_t *input = static_cast<input_t *>(data);
+
+ GHOST_TEventType etype = GHOST_kEventUnknown;
+ switch (state) {
+ case WL_KEYBOARD_KEY_STATE_RELEASED:
+ etype = GHOST_kEventKeyUp;
+ break;
+ case WL_KEYBOARD_KEY_STATE_PRESSED:
+ etype = GHOST_kEventKeyDown;
+ break;
+ }
+
+ const xkb_keysym_t sym = xkb_state_key_get_one_sym(input->xkb_state, key + 8);
+ if (sym == XKB_KEY_NoSymbol) {
+ return;
+ }
+ const GHOST_TKey gkey = xkb_map_gkey(sym);
+
+ GHOST_TEventKeyData key_data;
+
+ if (etype == GHOST_kEventKeyDown) {
+ xkb_state_key_get_utf8(
+ input->xkb_state, key + 8, key_data.utf8_buf, sizeof(GHOST_TEventKeyData::utf8_buf));
+ }
+ else {
+ key_data.utf8_buf[0] = '\0';
+ }
+
+ input->data_source->source_serial = serial;
+ input->system->pushEvent(new GHOST_EventKey(input->system->getMilliSeconds(),
+ etype,
+ input->system->getWindowManager()->getActiveWindow(),
+ gkey,
+ '\0',
+ key_data.utf8_buf,
+ false));
+}
+
+static void keyboard_modifiers(void *data,
+ struct wl_keyboard * /*wl_keyboard*/,
+ uint32_t /*serial*/,
+ uint32_t mods_depressed,
+ uint32_t mods_latched,
+ uint32_t mods_locked,
+ uint32_t group)
+{
+ xkb_state_update_mask(static_cast<input_t *>(data)->xkb_state,
+ mods_depressed,
+ mods_latched,
+ mods_locked,
+ 0,
+ 0,
+ group);
+}
+
+static const struct wl_keyboard_listener keyboard_listener = {
+ keyboard_keymap,
+ keyboard_enter,
+ keyboard_leave,
+ keyboard_key,
+ keyboard_modifiers,
+};
+
+static void seat_capabilities(void *data, struct wl_seat *wl_seat, uint32_t capabilities)
+{
+ input_t *input = static_cast<input_t *>(data);
+ input->pointer = nullptr;
+ input->keyboard = nullptr;
+
+ if (capabilities & WL_SEAT_CAPABILITY_POINTER) {
+ input->pointer = wl_seat_get_pointer(wl_seat);
+ input->cursor.surface = wl_compositor_create_surface(input->system->compositor());
+ input->cursor.visible = true;
+ input->cursor.buffer = nullptr;
+ input->cursor.file_buffer = new buffer_t;
+ wl_pointer_add_listener(input->pointer, &pointer_listener, data);
+ }
+
+ if (capabilities & WL_SEAT_CAPABILITY_KEYBOARD) {
+ input->keyboard = wl_seat_get_keyboard(wl_seat);
+ wl_keyboard_add_listener(input->keyboard, &keyboard_listener, data);
+ }
+}
+
+static void seat_name(void *data, struct wl_seat * /*wl_seat*/, const char *name)
+{
+ static_cast<input_t *>(data)->name = std::string(name);
+}
+
+static const struct wl_seat_listener seat_listener = {
+ seat_capabilities,
+ seat_name,
+};
+
+static void output_geometry(void *data,
+ struct wl_output * /*wl_output*/,
+ int32_t /*x*/,
+ int32_t /*y*/,
+ int32_t /*physical_width*/,
+ int32_t /*physical_height*/,
+ int32_t /*subpixel*/,
+ const char *make,
+ const char *model,
+ int32_t transform)
+{
+ output_t *output = static_cast<output_t *>(data);
+ output->transform = transform;
+ output->make = std::string(make);
+ output->model = std::string(model);
+}
+
+static void output_mode(void *data,
+ struct wl_output * /*wl_output*/,
+ uint32_t /*flags*/,
+ int32_t width,
+ int32_t height,
+ int32_t /*refresh*/)
+{
+ output_t *output = static_cast<output_t *>(data);
+ output->width = width;
+ output->height = height;
+}
+
+/**
+ * Sent all information about output.
+ *
+ * This event is sent after all other properties have been sent
+ * after binding to the output object and after any other property
+ * changes done after that. This allows changes to the output
+ * properties to be seen as atomic, even if they happen via multiple events.
+ */
+static void output_done(void * /*data*/, struct wl_output * /*wl_output*/)
+{
+}
+
+static void output_scale(void *data, struct wl_output * /*wl_output*/, int32_t factor)
+{
+ static_cast<output_t *>(data)->scale = factor;
+}
+
+static const struct wl_output_listener output_listener = {
+ output_geometry,
+ output_mode,
+ output_done,
+ output_scale,
+};
+
+static void shell_ping(void * /*data*/, struct xdg_wm_base *xdg_wm_base, uint32_t serial)
+{
+ xdg_wm_base_pong(xdg_wm_base, serial);
+}
+
+static const struct xdg_wm_base_listener shell_listener = {
+ shell_ping,
+};
+
+static void global_add(void *data,
+ struct wl_registry *wl_registry,
+ uint32_t name,
+ const char *interface,
+ uint32_t /*version*/)
+{
+ struct display_t *display = static_cast<struct display_t *>(data);
+ if (!strcmp(interface, wl_compositor_interface.name)) {
+ display->compositor = static_cast<wl_compositor *>(
+ wl_registry_bind(wl_registry, name, &wl_compositor_interface, 1));
+ }
+ else if (!strcmp(interface, xdg_wm_base_interface.name)) {
+ display->xdg_shell = static_cast<xdg_wm_base *>(
+ wl_registry_bind(wl_registry, name, &xdg_wm_base_interface, 1));
+ xdg_wm_base_add_listener(display->xdg_shell, &shell_listener, nullptr);
+ }
+ else if (!strcmp(interface, wl_output_interface.name)) {
+ output_t *output = new output_t;
+ output->scale = 1;
+ output->output = static_cast<wl_output *>(
+ wl_registry_bind(wl_registry, name, &wl_output_interface, 2));
+ display->outputs.push_back(output);
+ wl_output_add_listener(output->output, &output_listener, output);
+ }
+ else if (!strcmp(interface, wl_seat_interface.name)) {
+ input_t *input = new input_t;
+ input->system = display->system;
+ input->xkb_context = xkb_context_new(XKB_CONTEXT_NO_FLAGS);
+ input->xkb_state = nullptr;
+ input->data_offer_dnd = nullptr;
+ input->data_offer_copy_paste = nullptr;
+ input->data_source = new data_source_t;
+ input->data_source->data_source = nullptr;
+ input->data_source->buffer_out = nullptr;
+ input->relative_pointer = nullptr;
+ input->locked_pointer = nullptr;
+ input->seat = static_cast<wl_seat *>(
+ wl_registry_bind(wl_registry, name, &wl_seat_interface, 2));
+ display->inputs.push_back(input);
+ wl_seat_add_listener(input->seat, &seat_listener, input);
+ }
+ else if (!strcmp(interface, wl_shm_interface.name)) {
+ display->shm = static_cast<wl_shm *>(
+ wl_registry_bind(wl_registry, name, &wl_shm_interface, 1));
+ }
+ else if (!strcmp(interface, wl_data_device_manager_interface.name)) {
+ display->data_device_manager = static_cast<wl_data_device_manager *>(
+ wl_registry_bind(wl_registry, name, &wl_data_device_manager_interface, 1));
+ }
+ else if (!strcmp(interface, zwp_relative_pointer_manager_v1_interface.name)) {
+ display->relative_pointer_manager = static_cast<zwp_relative_pointer_manager_v1 *>(
+ wl_registry_bind(wl_registry, name, &zwp_relative_pointer_manager_v1_interface, 1));
+ }
+ else if (!strcmp(interface, zwp_pointer_constraints_v1_interface.name)) {
+ display->pointer_constraints = static_cast<zwp_pointer_constraints_v1 *>(
+ wl_registry_bind(wl_registry, name, &zwp_pointer_constraints_v1_interface, 1));
+ }
+}
+
+/**
+ * Announce removal of global object.
+ *
+ * Notify the client of removed global objects.
+ *
+ * This event notifies the client that the global identified by
+ * name is no longer available. If the client bound to the global
+ * using the bind request, the client should now destroy that object.
+ */
+static void global_remove(void * /*data*/, struct wl_registry * /*wl_registry*/, uint32_t /*name*/)
+{
+}
+
+static const struct wl_registry_listener registry_listener = {
+ global_add,
+ global_remove,
+};
+
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Ghost Implementation
+ *
+ * Wayland specific implementation of the GHOST_System interface.
+ * \{ */
+
+GHOST_SystemWayland::GHOST_SystemWayland() : GHOST_System(), d(new display_t)
+{
+ d->system = this;
+ /* Connect to the Wayland server. */
+ d->display = wl_display_connect(nullptr);
+ if (!d->display) {
+ display_destroy(d);
+ throw std::runtime_error("Wayland: unable to connect to display!");
+ }
+
+ /* Register interfaces. */
+ struct wl_registry *registry = wl_display_get_registry(d->display);
+ wl_registry_add_listener(registry, &registry_listener, d);
+ /* Call callback for registry listener. */
+ wl_display_roundtrip(d->display);
+ /* Call callbacks for registered listeners. */
+ wl_display_roundtrip(d->display);
+ wl_registry_destroy(registry);
+
+ if (!d->xdg_shell) {
+ display_destroy(d);
+ throw std::runtime_error("Wayland: unable to access xdg_shell!");
+ }
+
+ /* Register data device per seat for IPC between Wayland clients. */
+ if (d->data_device_manager) {
+ for (input_t *input : d->inputs) {
+ input->data_device = wl_data_device_manager_get_data_device(d->data_device_manager,
+ input->seat);
+ wl_data_device_add_listener(input->data_device, &data_device_listener, input);
+ }
+ }
+
+ const char *theme = std::getenv("XCURSOR_THEME");
+ const char *size = std::getenv("XCURSOR_SIZE");
+ const int sizei = size ? std::stoi(size) : default_cursor_size;
+
+ d->cursor_theme = wl_cursor_theme_load(theme, sizei, d->shm);
+ if (!d->cursor_theme) {
+ display_destroy(d);
+ throw std::runtime_error("Wayland: unable to access cursor themes!");
+ }
+}
+
+GHOST_SystemWayland::~GHOST_SystemWayland()
+{
+ display_destroy(d);
+}
+
+bool GHOST_SystemWayland::processEvents(bool /*waitForEvent*/)
+{
+ wl_display_dispatch(d->display);
+ return true;
+}
+
+int GHOST_SystemWayland::toggleConsole(int /*action*/)
+{
+ return 0;
+}
+
+GHOST_TSuccess GHOST_SystemWayland::getModifierKeys(GHOST_ModifierKeys &keys) const
+{
+ if (!d->inputs.empty()) {
+ static const xkb_state_component mods_all = xkb_state_component(
+ XKB_STATE_MODS_DEPRESSED | XKB_STATE_MODS_LATCHED | XKB_STATE_MODS_LOCKED |
+ XKB_STATE_MODS_EFFECTIVE);
+
+ keys.set(GHOST_kModifierKeyLeftShift,
+ xkb_state_mod_name_is_active(d->inputs[0]->xkb_state, XKB_MOD_NAME_SHIFT, mods_all) ==
+ 1);
+ keys.set(GHOST_kModifierKeyRightShift,
+ xkb_state_mod_name_is_active(d->inputs[0]->xkb_state, XKB_MOD_NAME_SHIFT, mods_all) ==
+ 1);
+ keys.set(GHOST_kModifierKeyLeftAlt,
+ xkb_state_mod_name_is_active(d->inputs[0]->xkb_state, "LAlt", mods_all) == 1);
+ keys.set(GHOST_kModifierKeyRightAlt,
+ xkb_state_mod_name_is_active(d->inputs[0]->xkb_state, "RAlt", mods_all) == 1);
+ keys.set(GHOST_kModifierKeyLeftControl,
+ xkb_state_mod_name_is_active(d->inputs[0]->xkb_state, "LControl", mods_all) == 1);
+ keys.set(GHOST_kModifierKeyRightControl,
+ xkb_state_mod_name_is_active(d->inputs[0]->xkb_state, "RControl", mods_all) == 1);
+ keys.set(GHOST_kModifierKeyOS,
+ xkb_state_mod_name_is_active(d->inputs[0]->xkb_state, "Super", mods_all) == 1);
+ keys.set(GHOST_kModifierKeyNumMasks,
+ xkb_state_mod_name_is_active(d->inputs[0]->xkb_state, "NumLock", mods_all) == 1);
+
+ return GHOST_kSuccess;
+ }
+ return GHOST_kFailure;
+}
+
+GHOST_TSuccess GHOST_SystemWayland::getButtons(GHOST_Buttons &buttons) const
+{
+ if (!d->inputs.empty()) {
+ buttons = d->inputs[0]->buttons;
+ return GHOST_kSuccess;
+ }
+ return GHOST_kFailure;
+}
+
+GHOST_TUns8 *GHOST_SystemWayland::getClipboard(bool /*selection*/) const
+{
+ GHOST_TUns8 *clipboard = static_cast<GHOST_TUns8 *>(malloc((selection.size() + 1)));
+ memcpy(clipboard, selection.data(), selection.size() + 1);
+ return clipboard;
+}
+
+void GHOST_SystemWayland::putClipboard(GHOST_TInt8 *buffer, bool /*selection*/) const
+{
+ if (!d->data_device_manager || d->inputs.empty()) {
+ return;
+ }
+
+ data_source_t *data_source = d->inputs[0]->data_source;
+
+ /* Copy buffer. */
+ data_source->buffer_out = static_cast<char *>(malloc(strlen(buffer) + 1));
+ std::strcpy(data_source->buffer_out, buffer);
+
+ data_source->data_source = wl_data_device_manager_create_data_source(d->data_device_manager);
+
+ wl_data_source_add_listener(
+ data_source->data_source, &data_source_listener, data_source->buffer_out);
+
+ for (const std::string &type : mime_send) {
+ wl_data_source_offer(data_source->data_source, type.c_str());
+ }
+
+ if (!d->inputs.empty() && d->inputs[0]->data_device) {
+ wl_data_device_set_selection(
+ d->inputs[0]->data_device, data_source->data_source, data_source->source_serial);
+ }
+}
+
+GHOST_TUns8 GHOST_SystemWayland::getNumDisplays() const
+{
+ return d ? GHOST_TUns8(d->outputs.size()) : 0;
+}
+
+GHOST_TSuccess GHOST_SystemWayland::getCursorPosition(GHOST_TInt32 &x, GHOST_TInt32 &y) const
+{
+ if (getWindowManager()->getActiveWindow() != nullptr && !d->inputs.empty()) {
+ x = d->inputs[0]->x;
+ y = d->inputs[0]->y;
+ return GHOST_kSuccess;
+ }
+ else {
+ return GHOST_kFailure;
+ }
+}
+
+GHOST_TSuccess GHOST_SystemWayland::setCursorPosition(GHOST_TInt32 /*x*/, GHOST_TInt32 /*y*/)
+{
+ return GHOST_kFailure;
+}
+
+void GHOST_SystemWayland::getMainDisplayDimensions(GHOST_TUns32 &width, GHOST_TUns32 &height) const
+{
+ if (getNumDisplays() > 0) {
+ /* We assume first output as main. */
+ width = uint32_t(d->outputs[0]->width);
+ height = uint32_t(d->outputs[0]->height);
+ }
+}
+
+void GHOST_SystemWayland::getAllDisplayDimensions(GHOST_TUns32 &width, GHOST_TUns32 &height) const
+{
+ getMainDisplayDimensions(width, height);
+}
+
+GHOST_IContext *GHOST_SystemWayland::createOffscreenContext()
+{
+ /* Create new off-screen window. */
+ wl_surface *os_surface = wl_compositor_create_surface(compositor());
+ wl_egl_window *os_egl_window = wl_egl_window_create(os_surface, int(1), int(1));
+
+ d->os_surfaces.push_back(os_surface);
+ d->os_egl_windows.push_back(os_egl_window);
+
+ GHOST_Context *context = new GHOST_ContextEGL(false,
+ EGLNativeWindowType(os_egl_window),
+ EGLNativeDisplayType(d->display),
+ EGL_CONTEXT_OPENGL_CORE_PROFILE_BIT,
+ 3,
+ 3,
+ GHOST_OPENGL_EGL_CONTEXT_FLAGS,
+ GHOST_OPENGL_EGL_RESET_NOTIFICATION_STRATEGY,
+ EGL_OPENGL_API);
+
+ if (context->initializeDrawingContext()) {
+ return context;
+ }
+ else {
+ delete context;
+ }
+
+ GHOST_PRINT("Cannot create off-screen EGL context" << std::endl);
+
+ return nullptr;
+}
+
+GHOST_TSuccess GHOST_SystemWayland::disposeContext(GHOST_IContext *context)
+{
+ delete context;
+ return GHOST_kSuccess;
+}
+
+GHOST_IWindow *GHOST_SystemWayland::createWindow(const char *title,
+ GHOST_TInt32 left,
+ GHOST_TInt32 top,
+ GHOST_TUns32 width,
+ GHOST_TUns32 height,
+ GHOST_TWindowState state,
+ GHOST_TDrawingContextType type,
+ GHOST_GLSettings glSettings,
+ const bool exclusive,
+ const bool /*is_dialog*/,
+ const GHOST_IWindow *parentWindow)
+{
+ GHOST_WindowWayland *window = new GHOST_WindowWayland(
+ this,
+ title,
+ left,
+ top,
+ width,
+ height,
+ state,
+ parentWindow,
+ type,
+ ((glSettings.flags & GHOST_glStereoVisual) != 0),
+ exclusive);
+
+ if (window) {
+ if (window->getValid()) {
+ m_windowManager->addWindow(window);
+ m_windowManager->setActiveWindow(window);
+ pushEvent(new GHOST_Event(getMilliSeconds(), GHOST_kEventWindowSize, window));
+ }
+ else {
+ delete window;
+ window = nullptr;
+ }
+ }
+
+ return window;
+}
+
+wl_display *GHOST_SystemWayland::display()
+{
+ return d->display;
+}
+
+wl_compositor *GHOST_SystemWayland::compositor()
+{
+ return d->compositor;
+}
+
+xdg_wm_base *GHOST_SystemWayland::shell()
+{
+ return d->xdg_shell;
+}
+
+void GHOST_SystemWayland::setSelection(const std::string &selection)
+{
+ this->selection = selection;
+}
+
+static void set_cursor_buffer(input_t *input, wl_buffer *buffer)
+{
+ input->cursor.visible = (buffer != nullptr);
+
+ wl_surface_attach(input->cursor.surface, buffer, 0, 0);
+ wl_surface_commit(input->cursor.surface);
+
+ if (input->cursor.visible) {
+ wl_surface_damage(input->cursor.surface,
+ 0,
+ 0,
+ int32_t(input->cursor.image.width),
+ int32_t(input->cursor.image.height));
+ wl_pointer_set_cursor(input->pointer,
+ input->pointer_serial,
+ input->cursor.surface,
+ int32_t(input->cursor.image.hotspot_x),
+ int32_t(input->cursor.image.hotspot_y));
+ }
+}
+
+GHOST_TSuccess GHOST_SystemWayland::setCursorShape(GHOST_TStandardCursor shape)
+{
+ if (d->inputs.empty()) {
+ return GHOST_kFailure;
+ }
+ const std::string cursor_name = cursors.count(shape) ? cursors.at(shape) :
+ cursors.at(GHOST_kStandardCursorDefault);
+
+ wl_cursor *cursor = wl_cursor_theme_get_cursor(d->cursor_theme, cursor_name.c_str());
+
+ if (!cursor) {
+ GHOST_PRINT("cursor '" << cursor_name << "' does not exist" << std::endl);
+ return GHOST_kFailure;
+ }
+
+ struct wl_cursor_image *image = cursor->images[0];
+ struct wl_buffer *buffer = wl_cursor_image_get_buffer(image);
+ if (!buffer) {
+ return GHOST_kFailure;
+ }
+ cursor_t *c = &d->inputs[0]->cursor;
+ c->buffer = buffer;
+ c->image = *image;
+
+ set_cursor_buffer(d->inputs[0], buffer);
+
+ return GHOST_kSuccess;
+}
+
+GHOST_TSuccess GHOST_SystemWayland::hasCursorShape(GHOST_TStandardCursor cursorShape)
+{
+ return GHOST_TSuccess(cursors.count(cursorShape) && !cursors.at(cursorShape).empty());
+}
+
+GHOST_TSuccess GHOST_SystemWayland::setCustomCursorShape(GHOST_TUns8 *bitmap,
+ GHOST_TUns8 *mask,
+ int sizex,
+ int sizey,
+ int hotX,
+ int hotY,
+ bool /*canInvertColor*/)
+{
+ if (d->inputs.empty()) {
+ return GHOST_kFailure;
+ }
+
+ cursor_t *cursor = &d->inputs[0]->cursor;
+
+ static const int32_t stride = sizex * 4; /* ARGB */
+ cursor->file_buffer->size = size_t(stride * sizey);
+
+ const int fd = memfd_create("blender-cursor-custom", MFD_CLOEXEC | MFD_ALLOW_SEALING);
+ fcntl(fd, F_ADD_SEALS, F_SEAL_SHRINK);
+ posix_fallocate(fd, 0, int32_t(cursor->file_buffer->size));
+
+ cursor->file_buffer->data = mmap(
+ nullptr, cursor->file_buffer->size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
+
+ struct wl_shm_pool *pool = wl_shm_create_pool(d->shm, fd, int32_t(cursor->file_buffer->size));
+
+ wl_buffer *buffer = wl_shm_pool_create_buffer(
+ pool, 0, sizex, sizey, stride, WL_SHM_FORMAT_ARGB8888);
+
+ wl_shm_pool_destroy(pool);
+ close(fd);
+
+ wl_buffer_add_listener(buffer, &buffer_listener, nullptr);
+
+ static constexpr uint32_t black = 0xFF000000;
+ static constexpr uint32_t white = 0xFFFFFFFF;
+ static constexpr uint32_t transparent = 0x00000000;
+
+ uint8_t datab = 0, maskb = 0;
+ uint32_t *pixel;
+
+ for (int y = 0; y < sizey; ++y) {
+ pixel = &static_cast<uint32_t *>(cursor->file_buffer->data)[y * sizex];
+ for (int x = 0; x < sizex; ++x) {
+ if ((x % 8) == 0) {
+ datab = *bitmap++;
+ maskb = *mask++;
+
+ /* Reverse bit order. */
+ datab = uint8_t((datab * 0x0202020202ULL & 0x010884422010ULL) % 1023);
+ maskb = uint8_t((maskb * 0x0202020202ULL & 0x010884422010ULL) % 1023);
+ }
+
+ if (maskb & 0x80) {
+ *pixel++ = (datab & 0x80) ? white : black;
+ }
+ else {
+ *pixel++ = (datab & 0x80) ? white : transparent;
+ }
+ datab <<= 1;
+ maskb <<= 1;
+ }
+ }
+
+ cursor->buffer = buffer;
+ cursor->image.width = uint32_t(sizex);
+ cursor->image.height = uint32_t(sizey);
+ cursor->image.hotspot_x = uint32_t(hotX);
+ cursor->image.hotspot_y = uint32_t(hotY);
+
+ set_cursor_buffer(d->inputs[0], buffer);
+
+ return GHOST_kSuccess;
+}
+
+GHOST_TSuccess GHOST_SystemWayland::setCursorVisibility(bool visible)
+{
+ if (d->inputs.empty()) {
+ return GHOST_kFailure;
+ }
+
+ cursor_t *cursor = &d->inputs[0]->cursor;
+ if (visible) {
+ if (!cursor->visible) {
+ set_cursor_buffer(d->inputs[0], d->inputs[0]->cursor.buffer);
+ }
+ }
+ else {
+ if (cursor->visible) {
+ set_cursor_buffer(d->inputs[0], nullptr);
+ }
+ }
+
+ return GHOST_kSuccess;
+}
+
+GHOST_TSuccess GHOST_SystemWayland::setCursorGrab(const GHOST_TGrabCursorMode mode,
+ wl_surface *surface)
+{
+ if (d->inputs.empty()) {
+ return GHOST_kFailure;
+ }
+
+ input_t *input = d->inputs[0];
+
+ switch (mode) {
+ case GHOST_kGrabDisable:
+ if (input->relative_pointer) {
+ zwp_relative_pointer_v1_destroy(input->relative_pointer);
+ input->relative_pointer = nullptr;
+ }
+ if (input->locked_pointer) {
+ zwp_locked_pointer_v1_destroy(input->locked_pointer);
+ input->locked_pointer = nullptr;
+ }
+ break;
+
+ case GHOST_kGrabNormal:
+ case GHOST_kGrabWrap:
+ input->relative_pointer = zwp_relative_pointer_manager_v1_get_relative_pointer(
+ d->relative_pointer_manager, input->pointer);
+ zwp_relative_pointer_v1_add_listener(
+ input->relative_pointer, &relative_pointer_listener, input);
+ input->locked_pointer = zwp_pointer_constraints_v1_lock_pointer(
+ d->pointer_constraints,
+ surface,
+ input->pointer,
+ nullptr,
+ ZWP_POINTER_CONSTRAINTS_V1_LIFETIME_PERSISTENT);
+ break;
+
+ case GHOST_kGrabHide:
+ setCursorVisibility(false);
+ break;
+ }
+
+ return GHOST_kSuccess;
+}
+
+/** \} */
diff --git a/intern/ghost/intern/GHOST_SystemWayland.h b/intern/ghost/intern/GHOST_SystemWayland.h
new file mode 100644
index 00000000000..89cd3406b69
--- /dev/null
+++ b/intern/ghost/intern/GHOST_SystemWayland.h
@@ -0,0 +1,111 @@
+/*
+ * 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 GHOST
+ * Declaration of GHOST_SystemWayland class.
+ */
+
+#ifndef __GHOST_SYSTEMWAYLAND_H__
+#define __GHOST_SYSTEMWAYLAND_H__
+
+#include "../GHOST_Types.h"
+#include "GHOST_System.h"
+#include "GHOST_WindowWayland.h"
+
+#include <wayland-client.h>
+#include <xdg-shell-client-protocol.h>
+
+#include <string>
+
+class GHOST_WindowWayland;
+
+struct display_t;
+
+class GHOST_SystemWayland : public GHOST_System {
+ public:
+ GHOST_SystemWayland();
+
+ ~GHOST_SystemWayland() override;
+
+ bool processEvents(bool waitForEvent) override;
+
+ int toggleConsole(int action) override;
+
+ GHOST_TSuccess getModifierKeys(GHOST_ModifierKeys &keys) const override;
+
+ GHOST_TSuccess getButtons(GHOST_Buttons &buttons) const override;
+
+ GHOST_TUns8 *getClipboard(bool selection) const override;
+
+ void putClipboard(GHOST_TInt8 *buffer, bool selection) const override;
+
+ GHOST_TUns8 getNumDisplays() const override;
+
+ GHOST_TSuccess getCursorPosition(GHOST_TInt32 &x, GHOST_TInt32 &y) const override;
+
+ GHOST_TSuccess setCursorPosition(GHOST_TInt32 x, GHOST_TInt32 y) override;
+
+ void getMainDisplayDimensions(GHOST_TUns32 &width, GHOST_TUns32 &height) const override;
+
+ void getAllDisplayDimensions(GHOST_TUns32 &width, GHOST_TUns32 &height) const override;
+
+ GHOST_IContext *createOffscreenContext() override;
+
+ GHOST_TSuccess disposeContext(GHOST_IContext *context) override;
+
+ GHOST_IWindow *createWindow(const char *title,
+ GHOST_TInt32 left,
+ GHOST_TInt32 top,
+ GHOST_TUns32 width,
+ GHOST_TUns32 height,
+ GHOST_TWindowState state,
+ GHOST_TDrawingContextType type,
+ GHOST_GLSettings glSettings,
+ const bool exclusive,
+ const bool is_dialog,
+ const GHOST_IWindow *parentWindow) override;
+
+ wl_display *display();
+
+ wl_compositor *compositor();
+
+ xdg_wm_base *shell();
+
+ void setSelection(const std::string &selection);
+
+ GHOST_TSuccess setCursorShape(GHOST_TStandardCursor shape);
+
+ GHOST_TSuccess hasCursorShape(GHOST_TStandardCursor cursorShape);
+
+ GHOST_TSuccess setCustomCursorShape(GHOST_TUns8 *bitmap,
+ GHOST_TUns8 *mask,
+ int sizex,
+ int sizey,
+ int hotX,
+ int hotY,
+ bool canInvertColor);
+
+ GHOST_TSuccess setCursorVisibility(bool visible);
+
+ GHOST_TSuccess setCursorGrab(const GHOST_TGrabCursorMode mode, wl_surface *surface);
+
+ private:
+ 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 fdd022e44ac..849aa5a96f5 100644
--- a/intern/ghost/intern/GHOST_SystemWin32.cpp
+++ b/intern/ghost/intern/GHOST_SystemWin32.cpp
@@ -282,7 +282,7 @@ void GHOST_SystemWin32::getAllDisplayDimensions(GHOST_TUns32 &width, GHOST_TUns3
height = ::GetSystemMetrics(SM_CYVIRTUALSCREEN);
}
-GHOST_IWindow *GHOST_SystemWin32::createWindow(const STR_String &title,
+GHOST_IWindow *GHOST_SystemWin32::createWindow(const char *title,
GHOST_TInt32 left,
GHOST_TInt32 top,
GHOST_TUns32 width,
diff --git a/intern/ghost/intern/GHOST_SystemWin32.h b/intern/ghost/intern/GHOST_SystemWin32.h
index c6d810d2a38..b23f907608c 100644
--- a/intern/ghost/intern/GHOST_SystemWin32.h
+++ b/intern/ghost/intern/GHOST_SystemWin32.h
@@ -126,7 +126,7 @@ class GHOST_SystemWin32 : public GHOST_System {
* \param parentWindow Parent window
* \return The new window (or 0 if creation failed).
*/
- GHOST_IWindow *createWindow(const STR_String &title,
+ GHOST_IWindow *createWindow(const char *title,
GHOST_TInt32 left,
GHOST_TInt32 top,
GHOST_TUns32 width,
diff --git a/intern/ghost/intern/GHOST_SystemX11.cpp b/intern/ghost/intern/GHOST_SystemX11.cpp
index 825b93de36f..91c63a3fb76 100644
--- a/intern/ghost/intern/GHOST_SystemX11.cpp
+++ b/intern/ghost/intern/GHOST_SystemX11.cpp
@@ -338,7 +338,7 @@ void GHOST_SystemX11::getAllDisplayDimensions(GHOST_TUns32 &width, GHOST_TUns32
* \param parentWindow Parent window
* \return The new window (or 0 if creation failed).
*/
-GHOST_IWindow *GHOST_SystemX11::createWindow(const STR_String &title,
+GHOST_IWindow *GHOST_SystemX11::createWindow(const char *title,
GHOST_TInt32 left,
GHOST_TInt32 top,
GHOST_TUns32 width,
@@ -1881,7 +1881,7 @@ static GHOST_TKey ghost_key_from_keysym(const KeySym key)
# endif
#endif
default:
-#ifdef GHOST_DEBUG
+#ifdef WITH_GHOST_DEBUG
printf("%s: unknown key: %lu / 0x%lx\n", __func__, key, key);
#endif
type = GHOST_kKeyUnknown;
@@ -1905,7 +1905,7 @@ static GHOST_TKey ghost_key_from_keycode(const XkbDescPtr xkb_descr, const KeyCo
switch (id) {
case MAKE_ID('T', 'L', 'D', 'E'):
return GHOST_kKeyAccentGrave;
-#ifdef GHOST_DEBUG
+#ifdef WITH_GHOST_DEBUG
default:
printf("%s unhandled keycode: %.*s\n", __func__, XkbKeyNameLength, id_str);
break;
@@ -2456,7 +2456,7 @@ GHOST_TSuccess GHOST_SystemX11::showMessageBox(const char *title,
string cmd = "xdg-open \"" + string(link) + "\"";
if (system(cmd.c_str()) != 0) {
GHOST_PRINTF("GHOST_SystemX11::showMessageBox: Unable to run system command [%s]",
- cmd);
+ cmd.c_str());
}
}
break;
diff --git a/intern/ghost/intern/GHOST_SystemX11.h b/intern/ghost/intern/GHOST_SystemX11.h
index d0e0506e77b..bb01ef7e0cc 100644
--- a/intern/ghost/intern/GHOST_SystemX11.h
+++ b/intern/ghost/intern/GHOST_SystemX11.h
@@ -137,7 +137,7 @@ class GHOST_SystemX11 : public GHOST_System {
* \param parentWindow Parent (embedder) window
* \return The new window (or 0 if creation failed).
*/
- GHOST_IWindow *createWindow(const STR_String &title,
+ GHOST_IWindow *createWindow(const char *title,
GHOST_TInt32 left,
GHOST_TInt32 top,
GHOST_TUns32 width,
diff --git a/intern/ghost/intern/GHOST_Window.h b/intern/ghost/intern/GHOST_Window.h
index 553a7d89df4..472149148e6 100644
--- a/intern/ghost/intern/GHOST_Window.h
+++ b/intern/ghost/intern/GHOST_Window.h
@@ -27,7 +27,6 @@
#include "GHOST_IWindow.h"
-class STR_String;
class GHOST_Context;
/**
@@ -61,8 +60,8 @@ class GHOST_Window : public GHOST_IWindow {
* \section Interface inherited from GHOST_IWindow left for derived class
* implementation.
* virtual bool getValid() const = 0;
- * virtual void setTitle(const STR_String& title) = 0;
- * virtual void getTitle(STR_String& title) const = 0;
+ * virtual void setTitle(const char * title) = 0;
+ * virtual std::string getTitle() const = 0;
* virtual void getWindowBounds(GHOST_Rect& bounds) const = 0;
* virtual void getClientBounds(GHOST_Rect& bounds) const = 0;
* virtual GHOST_TSuccess setClientWidth(GHOST_TUns32 width) = 0;
diff --git a/intern/ghost/intern/GHOST_WindowCocoa.h b/intern/ghost/intern/GHOST_WindowCocoa.h
index efa418deee2..15429eab5db 100644
--- a/intern/ghost/intern/GHOST_WindowCocoa.h
+++ b/intern/ghost/intern/GHOST_WindowCocoa.h
@@ -30,7 +30,6 @@
#endif // __APPLE__
#include "GHOST_Window.h"
-#include "STR_String.h"
@class CAMetalLayer;
@class CocoaMetalView;
@@ -58,7 +57,7 @@ class GHOST_WindowCocoa : public GHOST_Window {
* \param stereoVisual Stereo visual for quad buffered stereo.
*/
GHOST_WindowCocoa(GHOST_SystemCocoa *systemCocoa,
- const STR_String &title,
+ const char *title,
GHOST_TInt32 left,
GHOST_TInt32 bottom,
GHOST_TUns32 width,
@@ -92,13 +91,12 @@ class GHOST_WindowCocoa : public GHOST_Window {
* Sets the title displayed in the title bar.
* \param title The title to display in the title bar.
*/
- void setTitle(const STR_String &title);
-
+ void setTitle(const char *title);
/**
* Returns the title displayed in the title bar.
* \param title The title displayed in the title bar.
*/
- void getTitle(STR_String &title) const;
+ std::string getTitle() const;
/**
* Returns the window rectangle dimensions.
diff --git a/intern/ghost/intern/GHOST_WindowCocoa.mm b/intern/ghost/intern/GHOST_WindowCocoa.mm
index 10ab05a0de1..05adc41cb8e 100644
--- a/intern/ghost/intern/GHOST_WindowCocoa.mm
+++ b/intern/ghost/intern/GHOST_WindowCocoa.mm
@@ -291,7 +291,7 @@
/* clang-format on */
GHOST_WindowCocoa::GHOST_WindowCocoa(GHOST_SystemCocoa *systemCocoa,
- const STR_String &title,
+ const char *title,
GHOST_TInt32 left,
GHOST_TInt32 bottom,
GHOST_TUns32 width,
@@ -482,7 +482,7 @@ void *GHOST_WindowCocoa::getOSWindow() const
return (void *)m_window;
}
-void GHOST_WindowCocoa::setTitle(const STR_String &title)
+void GHOST_WindowCocoa::setTitle(const char *title)
{
GHOST_ASSERT(getValid(), "GHOST_WindowCocoa::setTitle(): window invalid");
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
@@ -524,7 +524,7 @@ void GHOST_WindowCocoa::setTitle(const STR_String &title)
[pool drain];
}
-void GHOST_WindowCocoa::getTitle(STR_String &title) const
+std::string GHOST_WindowCocoa::getTitle() const
{
GHOST_ASSERT(getValid(), "GHOST_WindowCocoa::getTitle(): window invalid");
@@ -532,11 +532,14 @@ void GHOST_WindowCocoa::getTitle(STR_String &title) const
NSString *windowTitle = [m_window title];
+ std::string title;
if (windowTitle != nil) {
title = [windowTitle UTF8String];
}
[pool drain];
+
+ return title;
}
void GHOST_WindowCocoa::getWindowBounds(GHOST_Rect &bounds) const
diff --git a/intern/ghost/intern/GHOST_WindowNULL.h b/intern/ghost/intern/GHOST_WindowNULL.h
index db40075e6ca..e1aa0cb7f13 100644
--- a/intern/ghost/intern/GHOST_WindowNULL.h
+++ b/intern/ghost/intern/GHOST_WindowNULL.h
@@ -26,7 +26,6 @@
#include <map>
-class STR_String;
class GHOST_SystemNULL;
class GHOST_WindowNULL : public GHOST_Window {
@@ -37,7 +36,7 @@ class GHOST_WindowNULL : public GHOST_Window {
}
GHOST_WindowNULL(GHOST_SystemNULL *system,
- const STR_String &title,
+ const char *title,
GHOST_TInt32 left,
GHOST_TInt32 top,
GHOST_TUns32 width,
@@ -83,12 +82,12 @@ class GHOST_WindowNULL : public GHOST_Window {
{
return true;
}
- void setTitle(const STR_String &title)
+ void setTitle(const char *title)
{ /* nothing */
}
- void getTitle(STR_String &title) const
+ std::string getTitle() const
{
- title = "untitled";
+ return "untitled";
}
void getWindowBounds(GHOST_Rect &bounds) const
{
diff --git a/intern/ghost/intern/GHOST_WindowSDL.cpp b/intern/ghost/intern/GHOST_WindowSDL.cpp
index e8d129f45fe..dcb1ab8c78c 100644
--- a/intern/ghost/intern/GHOST_WindowSDL.cpp
+++ b/intern/ghost/intern/GHOST_WindowSDL.cpp
@@ -27,7 +27,7 @@
#include <assert.h>
GHOST_WindowSDL::GHOST_WindowSDL(GHOST_SystemSDL *system,
- const STR_String &title,
+ const char *title,
GHOST_TInt32 left,
GHOST_TInt32 top,
GHOST_TUns32 width,
@@ -148,14 +148,14 @@ bool GHOST_WindowSDL::getValid() const
return GHOST_Window::getValid() && m_valid_setup;
}
-void GHOST_WindowSDL::setTitle(const STR_String &title)
+void GHOST_WindowSDL::setTitle(const char *title)
{
- SDL_SetWindowTitle(m_sdl_win, title.ReadPtr());
+ SDL_SetWindowTitle(m_sdl_win, title);
}
-void GHOST_WindowSDL::getTitle(STR_String &title) const
+std::string GHOST_WindowSDL::getTitle() const
{
- title = SDL_GetWindowTitle(m_sdl_win);
+ return SDL_GetWindowTitle(m_sdl_win);
}
void GHOST_WindowSDL::getWindowBounds(GHOST_Rect &bounds) const
diff --git a/intern/ghost/intern/GHOST_WindowSDL.h b/intern/ghost/intern/GHOST_WindowSDL.h
index eadd1b7df9d..5039c742c9d 100644
--- a/intern/ghost/intern/GHOST_WindowSDL.h
+++ b/intern/ghost/intern/GHOST_WindowSDL.h
@@ -35,7 +35,6 @@ extern "C" {
# error "SDL 2.0 or newer is needed to build with Ghost"
#endif
-class STR_String;
class GHOST_SystemSDL;
class GHOST_WindowSDL : public GHOST_Window {
@@ -49,7 +48,7 @@ class GHOST_WindowSDL : public GHOST_Window {
public:
GHOST_WindowSDL(GHOST_SystemSDL *system,
- const STR_String &title,
+ const char *title,
GHOST_TInt32 left,
GHOST_TInt32 top,
GHOST_TUns32 width,
@@ -107,9 +106,9 @@ class GHOST_WindowSDL : public GHOST_Window {
GHOST_TSuccess setWindowCursorVisibility(bool visible);
- void setTitle(const STR_String &title);
+ void setTitle(const char *title);
- void getTitle(STR_String &title) const;
+ std::string getTitle() const;
GHOST_TSuccess setClientWidth(GHOST_TUns32 width);
diff --git a/intern/ghost/intern/GHOST_WindowWayland.cpp b/intern/ghost/intern/GHOST_WindowWayland.cpp
new file mode 100644
index 00000000000..0ea6f5f8ecb
--- /dev/null
+++ b/intern/ghost/intern/GHOST_WindowWayland.cpp
@@ -0,0 +1,406 @@
+/*
+ * 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 GHOST
+ */
+
+#include "GHOST_WindowWayland.h"
+#include "GHOST_SystemWayland.h"
+#include "GHOST_WindowManager.h"
+
+#include "GHOST_Event.h"
+
+#include "GHOST_ContextEGL.h"
+#include "GHOST_ContextNone.h"
+
+#include <wayland-egl.h>
+
+struct window_t {
+ GHOST_WindowWayland *w;
+ wl_surface *surface;
+ struct xdg_surface *xdg_surface;
+ struct xdg_toplevel *xdg_toplevel;
+ wl_egl_window *egl_window;
+ int32_t pending_width, pending_height;
+ bool is_maximised;
+ bool is_fullscreen;
+ bool is_active;
+ int32_t width, height;
+};
+
+/* -------------------------------------------------------------------- */
+/** \name Wayland Interface Callbacks
+ *
+ * These callbacks are registered for Wayland interfaces and called when
+ * an event is received from the compositor.
+ * \{ */
+
+static void toplevel_configure(
+ void *data, xdg_toplevel * /*xdg_toplevel*/, int32_t width, int32_t height, wl_array *states)
+{
+ window_t *win = static_cast<window_t *>(data);
+ win->pending_width = width;
+ win->pending_height = height;
+
+ win->is_maximised = false;
+ win->is_fullscreen = false;
+ win->is_active = false;
+
+ /* Note that the macro 'wl_array_for_each' would typically be used to simplify this logic,
+ * however it's not compatible with C++, so perform casts instead.
+ * If this needs to be done more often we could define our own C++ compatible macro. */
+ for (enum xdg_toplevel_state *state = static_cast<xdg_toplevel_state *>(states->data);
+ reinterpret_cast<uint8_t *>(state) < (static_cast<uint8_t *>(states->data) + states->size);
+ state++) {
+ switch (*state) {
+ case XDG_TOPLEVEL_STATE_MAXIMIZED:
+ win->is_maximised = true;
+ break;
+ case XDG_TOPLEVEL_STATE_FULLSCREEN:
+ win->is_fullscreen = true;
+ break;
+ case XDG_TOPLEVEL_STATE_ACTIVATED:
+ win->is_active = true;
+ break;
+ default:
+ break;
+ }
+ }
+}
+
+static void toplevel_close(void *data, xdg_toplevel * /*xdg_toplevel*/)
+{
+ static_cast<window_t *>(data)->w->close();
+}
+
+static const xdg_toplevel_listener toplevel_listener = {
+ toplevel_configure,
+ toplevel_close,
+};
+
+static void surface_configure(void *data, xdg_surface *xdg_surface, uint32_t serial)
+{
+ window_t *win = static_cast<window_t *>(data);
+
+ int w, h;
+ wl_egl_window_get_attached_size(win->egl_window, &w, &h);
+ if (win->pending_width != 0 && win->pending_height != 0 && win->pending_width != w &&
+ win->pending_height != h) {
+ win->width = win->pending_width;
+ win->height = win->pending_height;
+ wl_egl_window_resize(win->egl_window, win->pending_width, win->pending_height, 0, 0);
+ win->pending_width = 0;
+ win->pending_height = 0;
+ win->w->notify_size();
+ }
+
+ if (win->is_active) {
+ win->w->activate();
+ }
+ else {
+ win->w->deactivate();
+ }
+
+ xdg_surface_ack_configure(xdg_surface, serial);
+}
+
+static const xdg_surface_listener surface_listener = {
+ surface_configure,
+};
+
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Ghost Implementation
+ *
+ * Wayland specific implementation of the GHOST_Window interface.
+ * \{ */
+
+GHOST_TSuccess GHOST_WindowWayland::hasCursorShape(GHOST_TStandardCursor cursorShape)
+{
+ return m_system->hasCursorShape(cursorShape);
+}
+
+GHOST_WindowWayland::GHOST_WindowWayland(GHOST_SystemWayland *system,
+ const char *title,
+ GHOST_TInt32 /*left*/,
+ GHOST_TInt32 /*top*/,
+ GHOST_TUns32 width,
+ GHOST_TUns32 height,
+ GHOST_TWindowState state,
+ const GHOST_IWindow *parentWindow,
+ GHOST_TDrawingContextType type,
+ const bool stereoVisual,
+ const bool exclusive)
+ : GHOST_Window(width, height, state, stereoVisual, exclusive),
+ m_system(system),
+ w(new window_t)
+{
+ w->w = this;
+
+ w->width = int32_t(width);
+ w->height = int32_t(height);
+
+ /* Window surfaces. */
+ w->surface = wl_compositor_create_surface(m_system->compositor());
+ w->egl_window = wl_egl_window_create(w->surface, int(width), int(height));
+
+ w->xdg_surface = xdg_wm_base_get_xdg_surface(m_system->shell(), w->surface);
+ w->xdg_toplevel = xdg_surface_get_toplevel(w->xdg_surface);
+
+ wl_surface_set_user_data(w->surface, this);
+
+ xdg_surface_add_listener(w->xdg_surface, &surface_listener, w);
+ xdg_toplevel_add_listener(w->xdg_toplevel, &toplevel_listener, w);
+
+ if (parentWindow) {
+ xdg_toplevel_set_parent(
+ w->xdg_toplevel, dynamic_cast<const GHOST_WindowWayland *>(parentWindow)->w->xdg_toplevel);
+ }
+
+ /* Call top-level callbacks. */
+ wl_surface_commit(w->surface);
+ wl_display_roundtrip(m_system->display());
+
+ setState(state);
+
+ setTitle(title);
+
+ /* EGL context. */
+ if (setDrawingContextType(type) == GHOST_kFailure) {
+ GHOST_PRINT("Failed to create EGL context" << std::endl);
+ }
+}
+
+GHOST_TSuccess GHOST_WindowWayland::close()
+{
+ return m_system->pushEvent(
+ new GHOST_Event(m_system->getMilliSeconds(), GHOST_kEventWindowClose, this));
+}
+
+GHOST_TSuccess GHOST_WindowWayland::activate()
+{
+ if (m_system->getWindowManager()->setActiveWindow(this) == GHOST_kFailure) {
+ return GHOST_kFailure;
+ }
+ return m_system->pushEvent(
+ new GHOST_Event(m_system->getMilliSeconds(), GHOST_kEventWindowActivate, this));
+}
+
+GHOST_TSuccess GHOST_WindowWayland::deactivate()
+{
+ m_system->getWindowManager()->setWindowInactive(this);
+ return m_system->pushEvent(
+ new GHOST_Event(m_system->getMilliSeconds(), GHOST_kEventWindowDeactivate, this));
+}
+
+GHOST_TSuccess GHOST_WindowWayland::notify_size()
+{
+ return m_system->pushEvent(
+ new GHOST_Event(m_system->getMilliSeconds(), GHOST_kEventWindowSize, this));
+}
+
+GHOST_TSuccess GHOST_WindowWayland::setWindowCursorGrab(GHOST_TGrabCursorMode mode)
+{
+ return m_system->setCursorGrab(mode, w->surface);
+}
+
+GHOST_TSuccess GHOST_WindowWayland::setWindowCursorShape(GHOST_TStandardCursor shape)
+{
+ const GHOST_TSuccess ok = m_system->setCursorShape(shape);
+ m_cursorShape = (ok == GHOST_kSuccess) ? shape : GHOST_kStandardCursorDefault;
+ return ok;
+}
+
+GHOST_TSuccess GHOST_WindowWayland::setWindowCustomCursorShape(GHOST_TUns8 *bitmap,
+ GHOST_TUns8 *mask,
+ int sizex,
+ int sizey,
+ int hotX,
+ int hotY,
+ bool canInvertColor)
+{
+ return m_system->setCustomCursorShape(bitmap, mask, sizex, sizey, hotX, hotY, canInvertColor);
+}
+
+void GHOST_WindowWayland::setTitle(const char *title)
+{
+ xdg_toplevel_set_title(w->xdg_toplevel, title);
+ xdg_toplevel_set_app_id(w->xdg_toplevel, title);
+ this->title = title;
+}
+
+std::string GHOST_WindowWayland::getTitle() const
+{
+ return this->title.empty() ? "untitled" : this->title;
+}
+
+void GHOST_WindowWayland::getWindowBounds(GHOST_Rect &bounds) const
+{
+ getClientBounds(bounds);
+}
+
+void GHOST_WindowWayland::getClientBounds(GHOST_Rect &bounds) const
+{
+ bounds.set(0, 0, w->width, w->height);
+}
+
+GHOST_TSuccess GHOST_WindowWayland::setClientWidth(GHOST_TUns32 width)
+{
+ return setClientSize(width, GHOST_TUns32(w->height));
+}
+
+GHOST_TSuccess GHOST_WindowWayland::setClientHeight(GHOST_TUns32 height)
+{
+ return setClientSize(GHOST_TUns32(w->width), height);
+}
+
+GHOST_TSuccess GHOST_WindowWayland::setClientSize(GHOST_TUns32 width, GHOST_TUns32 height)
+{
+ wl_egl_window_resize(w->egl_window, int(width), int(height), 0, 0);
+ return GHOST_kSuccess;
+}
+
+void GHOST_WindowWayland::screenToClient(GHOST_TInt32 inX,
+ GHOST_TInt32 inY,
+ GHOST_TInt32 &outX,
+ GHOST_TInt32 &outY) const
+{
+ outX = inX;
+ outY = inY;
+}
+
+void GHOST_WindowWayland::clientToScreen(GHOST_TInt32 inX,
+ GHOST_TInt32 inY,
+ GHOST_TInt32 &outX,
+ GHOST_TInt32 &outY) const
+{
+ outX = inX;
+ outY = inY;
+}
+
+GHOST_WindowWayland::~GHOST_WindowWayland()
+{
+ releaseNativeHandles();
+
+ wl_egl_window_destroy(w->egl_window);
+ xdg_toplevel_destroy(w->xdg_toplevel);
+ xdg_surface_destroy(w->xdg_surface);
+ wl_surface_destroy(w->surface);
+
+ delete w;
+}
+
+GHOST_TSuccess GHOST_WindowWayland::setWindowCursorVisibility(bool visible)
+{
+ return m_system->setCursorVisibility(visible);
+}
+
+GHOST_TSuccess GHOST_WindowWayland::setState(GHOST_TWindowState state)
+{
+ switch (state) {
+ case GHOST_kWindowStateNormal:
+ /* Unset states. */
+ switch (getState()) {
+ case GHOST_kWindowStateMaximized:
+ xdg_toplevel_unset_maximized(w->xdg_toplevel);
+ break;
+ case GHOST_kWindowStateFullScreen:
+ xdg_toplevel_unset_fullscreen(w->xdg_toplevel);
+ break;
+ default:
+ break;
+ }
+ break;
+ case GHOST_kWindowStateMaximized:
+ xdg_toplevel_set_maximized(w->xdg_toplevel);
+ break;
+ case GHOST_kWindowStateMinimized:
+ xdg_toplevel_set_minimized(w->xdg_toplevel);
+ break;
+ case GHOST_kWindowStateFullScreen:
+ xdg_toplevel_set_fullscreen(w->xdg_toplevel, nullptr);
+ break;
+ case GHOST_kWindowStateEmbedded:
+ return GHOST_kFailure;
+ }
+ return GHOST_kSuccess;
+}
+
+GHOST_TWindowState GHOST_WindowWayland::getState() const
+{
+ if (w->is_fullscreen) {
+ return GHOST_kWindowStateFullScreen;
+ }
+ else if (w->is_maximised) {
+ return GHOST_kWindowStateMaximized;
+ }
+ else {
+ return GHOST_kWindowStateNormal;
+ }
+}
+
+GHOST_TSuccess GHOST_WindowWayland::invalidate()
+{
+ return GHOST_kSuccess;
+}
+
+GHOST_TSuccess GHOST_WindowWayland::setOrder(GHOST_TWindowOrder /*order*/)
+{
+ return GHOST_kSuccess;
+}
+
+GHOST_TSuccess GHOST_WindowWayland::beginFullScreen() const
+{
+ xdg_toplevel_set_fullscreen(w->xdg_toplevel, nullptr);
+ return GHOST_kSuccess;
+}
+
+GHOST_TSuccess GHOST_WindowWayland::endFullScreen() const
+{
+ xdg_toplevel_unset_fullscreen(w->xdg_toplevel);
+ return GHOST_kSuccess;
+}
+
+/**
+ * \param type The type of rendering context create.
+ * \return Indication of success.
+ */
+GHOST_Context *GHOST_WindowWayland::newDrawingContext(GHOST_TDrawingContextType type)
+{
+ GHOST_Context *context;
+ switch (type) {
+ case GHOST_kDrawingContextTypeNone:
+ context = new GHOST_ContextNone(m_wantStereoVisual);
+ break;
+ case GHOST_kDrawingContextTypeOpenGL:
+ context = new GHOST_ContextEGL(m_wantStereoVisual,
+ EGLNativeWindowType(w->egl_window),
+ EGLNativeDisplayType(m_system->display()),
+ EGL_CONTEXT_OPENGL_CORE_PROFILE_BIT,
+ 3,
+ 3,
+ GHOST_OPENGL_EGL_CONTEXT_FLAGS,
+ GHOST_OPENGL_EGL_RESET_NOTIFICATION_STRATEGY,
+ EGL_OPENGL_API);
+ break;
+ }
+
+ return (context->initializeDrawingContext() == GHOST_kSuccess) ? context : nullptr;
+}
+
+/** \} */
diff --git a/intern/ghost/intern/GHOST_WindowWayland.h b/intern/ghost/intern/GHOST_WindowWayland.h
new file mode 100644
index 00000000000..39c35f77d7d
--- /dev/null
+++ b/intern/ghost/intern/GHOST_WindowWayland.h
@@ -0,0 +1,121 @@
+/*
+ * 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 GHOST
+ *
+ * Declaration of GHOST_WindowWayland class.
+ */
+
+#ifndef __GHOST_WINDOWWAYLAND_H__
+#define __GHOST_WINDOWWAYLAND_H__
+
+#include "GHOST_Window.h"
+
+class GHOST_SystemWayland;
+
+struct window_t;
+
+class GHOST_WindowWayland : public GHOST_Window {
+ public:
+ GHOST_TSuccess hasCursorShape(GHOST_TStandardCursor cursorShape) override;
+
+ GHOST_WindowWayland(GHOST_SystemWayland *system,
+ const char *title,
+ GHOST_TInt32 left,
+ GHOST_TInt32 top,
+ GHOST_TUns32 width,
+ GHOST_TUns32 height,
+ GHOST_TWindowState state,
+ const GHOST_IWindow *parentWindow,
+ GHOST_TDrawingContextType type,
+ const bool stereoVisual,
+ const bool exclusive);
+
+ ~GHOST_WindowWayland() override;
+
+ GHOST_TSuccess close();
+
+ GHOST_TSuccess activate();
+
+ GHOST_TSuccess deactivate();
+
+ GHOST_TSuccess notify_size();
+
+ protected:
+ GHOST_TSuccess setWindowCursorGrab(GHOST_TGrabCursorMode mode) override;
+
+ GHOST_TSuccess setWindowCursorShape(GHOST_TStandardCursor shape) override;
+
+ GHOST_TSuccess setWindowCustomCursorShape(GHOST_TUns8 *bitmap,
+ GHOST_TUns8 *mask,
+ int sizex,
+ int sizey,
+ int hotX,
+ int hotY,
+ bool canInvertColor) override;
+
+ void setTitle(const char *title) override;
+
+ std::string getTitle() const override;
+
+ void getWindowBounds(GHOST_Rect &bounds) const override;
+
+ void getClientBounds(GHOST_Rect &bounds) const override;
+
+ GHOST_TSuccess setClientWidth(GHOST_TUns32 width) override;
+
+ GHOST_TSuccess setClientHeight(GHOST_TUns32 height) override;
+
+ GHOST_TSuccess setClientSize(GHOST_TUns32 width, GHOST_TUns32 height) override;
+
+ void screenToClient(GHOST_TInt32 inX,
+ GHOST_TInt32 inY,
+ GHOST_TInt32 &outX,
+ GHOST_TInt32 &outY) const override;
+
+ void clientToScreen(GHOST_TInt32 inX,
+ GHOST_TInt32 inY,
+ GHOST_TInt32 &outX,
+ GHOST_TInt32 &outY) const override;
+
+ GHOST_TSuccess setWindowCursorVisibility(bool visible) override;
+
+ GHOST_TSuccess setState(GHOST_TWindowState state) override;
+
+ GHOST_TWindowState getState() const override;
+
+ GHOST_TSuccess invalidate() override;
+
+ GHOST_TSuccess setOrder(GHOST_TWindowOrder order) override;
+
+ GHOST_TSuccess beginFullScreen() const override;
+
+ GHOST_TSuccess endFullScreen() const override;
+
+ private:
+ GHOST_SystemWayland *m_system;
+ struct window_t *w;
+ std::string title;
+
+ /**
+ * \param type The type of rendering context create.
+ * \return Indication of success.
+ */
+ GHOST_Context *newDrawingContext(GHOST_TDrawingContextType type) override;
+};
+
+#endif // __GHOST_WINDOWWAYLAND_H__
diff --git a/intern/ghost/intern/GHOST_WindowWin32.cpp b/intern/ghost/intern/GHOST_WindowWin32.cpp
index 8b95cdd6351..55525157753 100644
--- a/intern/ghost/intern/GHOST_WindowWin32.cpp
+++ b/intern/ghost/intern/GHOST_WindowWin32.cpp
@@ -59,7 +59,7 @@ __declspec(dllexport) DWORD NvOptimusEnablement = 0x00000001;
}
GHOST_WindowWin32::GHOST_WindowWin32(GHOST_SystemWin32 *system,
- const STR_String &title,
+ const char *title,
GHOST_TInt32 left,
GHOST_TInt32 top,
GHOST_TUns32 width,
@@ -158,7 +158,7 @@ GHOST_WindowWin32::GHOST_WindowWin32(GHOST_SystemWin32 *system,
height = rect.bottom - rect.top;
}
- wchar_t *title_16 = alloc_utf16_from_8((char *)(const char *)title, 0);
+ wchar_t *title_16 = alloc_utf16_from_8((char *)title, 0);
m_hWnd = ::CreateWindowW(s_windowClassName, // pointer to registered class name
title_16, // pointer to window name
wintype, // window style
@@ -173,7 +173,7 @@ GHOST_WindowWin32::GHOST_WindowWin32(GHOST_SystemWin32 *system,
free(title_16);
}
else {
- wchar_t *title_16 = alloc_utf16_from_8((char *)(const char *)title, 0);
+ wchar_t *title_16 = alloc_utf16_from_8((char *)title, 0);
m_hWnd = ::CreateWindowW(s_windowClassName, // pointer to registered class name
title_16, // pointer to window name
WS_MAXIMIZE, // window style
@@ -430,19 +430,18 @@ HWND GHOST_WindowWin32::getHWND() const
return m_hWnd;
}
-void GHOST_WindowWin32::setTitle(const STR_String &title)
+void GHOST_WindowWin32::setTitle(const char *title)
{
- wchar_t *title_16 = alloc_utf16_from_8((char *)(const char *)title, 0);
+ wchar_t *title_16 = alloc_utf16_from_8((char *)title, 0);
::SetWindowTextW(m_hWnd, (wchar_t *)title_16);
free(title_16);
}
-void GHOST_WindowWin32::getTitle(STR_String &title) const
+std::string GHOST_WindowWin32::getTitle() const
{
char buf[s_maxTitleLength]; /*CHANGE + never used yet*/
::GetWindowText(m_hWnd, buf, s_maxTitleLength);
- STR_String temp(buf);
- title = buf;
+ return std::string(buf);
}
void GHOST_WindowWin32::getWindowBounds(GHOST_Rect &bounds) const
diff --git a/intern/ghost/intern/GHOST_WindowWin32.h b/intern/ghost/intern/GHOST_WindowWin32.h
index 489d3032552..dbed7c5ee5f 100644
--- a/intern/ghost/intern/GHOST_WindowWin32.h
+++ b/intern/ghost/intern/GHOST_WindowWin32.h
@@ -261,7 +261,7 @@ class GHOST_WindowWin32 : public GHOST_Window {
* \param parentWindowHwnd
*/
GHOST_WindowWin32(GHOST_SystemWin32 *system,
- const STR_String &title,
+ const char *title,
GHOST_TInt32 left,
GHOST_TInt32 top,
GHOST_TUns32 width,
@@ -296,13 +296,13 @@ class GHOST_WindowWin32 : public GHOST_Window {
* Sets the title displayed in the title bar.
* \param title The title to display in the title bar.
*/
- void setTitle(const STR_String &title);
+ void setTitle(const char *title);
/**
* Returns the title displayed in the title bar.
- * \param title The title displayed in the title bar.
+ * \return The title displayed in the title bar.
*/
- void getTitle(STR_String &title) const;
+ std::string getTitle() const;
/**
* Returns the window rectangle dimensions.
diff --git a/intern/ghost/intern/GHOST_WindowX11.cpp b/intern/ghost/intern/GHOST_WindowX11.cpp
index db9f6846b11..691f1790a2d 100644
--- a/intern/ghost/intern/GHOST_WindowX11.cpp
+++ b/intern/ghost/intern/GHOST_WindowX11.cpp
@@ -33,7 +33,6 @@
#include "GHOST_IconX11.h"
#include "GHOST_SystemX11.h"
#include "GHOST_WindowX11.h"
-#include "STR_String.h"
#ifdef WITH_XDND
# include "GHOST_DropTargetX11.h"
@@ -61,6 +60,7 @@
#include <unistd.h>
#include <algorithm>
+#include <limits.h>
#include <math.h>
#include <string>
@@ -212,7 +212,7 @@ static XVisualInfo *x11_visualinfo_from_glx(Display *display,
GHOST_WindowX11::GHOST_WindowX11(GHOST_SystemX11 *system,
Display *display,
- const STR_String &title,
+ const char *title,
GHOST_TInt32 left,
GHOST_TInt32 top,
GHOST_TUns32 width,
@@ -414,9 +414,9 @@ GHOST_WindowX11::GHOST_WindowX11(GHOST_SystemX11 *system,
/* XClassHint, title */
{
XClassHint *xclasshint = XAllocClassHint();
- const int len = title.Length() + 1;
+ const int len = strlen(title) + 1;
char *wmclass = (char *)malloc(sizeof(char) * len);
- memcpy(wmclass, title.ReadPtr(), len * sizeof(char));
+ memcpy(wmclass, title, len * sizeof(char));
xclasshint->res_name = wmclass;
xclasshint->res_class = wmclass;
XSetClassHint(m_display, m_window, xclasshint);
@@ -617,7 +617,7 @@ bool GHOST_WindowX11::getValid() const
return GHOST_Window::getValid() && m_valid_setup;
}
-void GHOST_WindowX11::setTitle(const STR_String &title)
+void GHOST_WindowX11::setTitle(const char *title)
{
Atom name = XInternAtom(m_display, "_NET_WM_NAME", 0);
Atom utf8str = XInternAtom(m_display, "UTF8_STRING", 0);
@@ -627,8 +627,8 @@ void GHOST_WindowX11::setTitle(const STR_String &title)
utf8str,
8,
PropModeReplace,
- (const unsigned char *)title.ReadPtr(),
- title.Length());
+ (const unsigned char *)title,
+ strlen(title));
/* This should convert to valid x11 string
* and getTitle would need matching change */
@@ -637,13 +637,14 @@ void GHOST_WindowX11::setTitle(const STR_String &title)
XFlush(m_display);
}
-void GHOST_WindowX11::getTitle(STR_String &title) const
+std::string GHOST_WindowX11::getTitle() const
{
char *name = NULL;
XFetchName(m_display, m_window, &name);
- title = name ? name : "untitled";
+ std::string title = name ? name : "untitled";
XFree(name);
+ return title;
}
void GHOST_WindowX11::getWindowBounds(GHOST_Rect &bounds) const
diff --git a/intern/ghost/intern/GHOST_WindowX11.h b/intern/ghost/intern/GHOST_WindowX11.h
index 4704cb45e58..4232ff40b52 100644
--- a/intern/ghost/intern/GHOST_WindowX11.h
+++ b/intern/ghost/intern/GHOST_WindowX11.h
@@ -37,7 +37,6 @@
#include <map>
-class STR_String;
class GHOST_SystemX11;
#ifdef WITH_XDND
@@ -69,7 +68,7 @@ class GHOST_WindowX11 : public GHOST_Window {
*/
GHOST_WindowX11(GHOST_SystemX11 *system,
Display *display,
- const STR_String &title,
+ const char *title,
GHOST_TInt32 left,
GHOST_TInt32 top,
GHOST_TUns32 width,
@@ -85,9 +84,9 @@ class GHOST_WindowX11 : public GHOST_Window {
bool getValid() const;
- void setTitle(const STR_String &title);
+ void setTitle(const char *title);
- void getTitle(STR_String &title) const;
+ std::string getTitle() const;
void getWindowBounds(GHOST_Rect &bounds) const;
diff --git a/intern/ghost/intern/GHOST_XrGraphicsBinding.cpp b/intern/ghost/intern/GHOST_XrGraphicsBinding.cpp
index 60b3b06f6a8..5e30502f7ff 100644
--- a/intern/ghost/intern/GHOST_XrGraphicsBinding.cpp
+++ b/intern/ghost/intern/GHOST_XrGraphicsBinding.cpp
@@ -22,7 +22,7 @@
#include <list>
#include <sstream>
-#if defined(WITH_X11)
+#if defined(WITH_GHOST_X11)
# include "GHOST_ContextGLX.h"
#elif defined(WIN32)
# include "GHOST_ContextD3D.h"
@@ -68,7 +68,7 @@ class GHOST_XrGraphicsBindingOpenGL : public GHOST_IXrGraphicsBinding {
XrSystemId system_id,
std::string *r_requirement_info) const override
{
-#if defined(WITH_X11)
+#if defined(WITH_GHOST_X11)
GHOST_ContextGLX *ctx_gl = static_cast<GHOST_ContextGLX *>(ghost_ctx);
#else
GHOST_ContextWGL *ctx_gl = static_cast<GHOST_ContextWGL *>(ghost_ctx);
@@ -107,7 +107,7 @@ class GHOST_XrGraphicsBindingOpenGL : public GHOST_IXrGraphicsBinding {
void initFromGhostContext(GHOST_Context *ghost_ctx) override
{
-#if defined(WITH_X11)
+#if defined(WITH_GHOST_X11)
GHOST_ContextGLX *ctx_glx = static_cast<GHOST_ContextGLX *>(ghost_ctx);
XVisualInfo *visual_info = glXGetVisualFromFBConfig(ctx_glx->m_display, ctx_glx->m_fbconfig);
diff --git a/intern/ghost/intern/GHOST_Xr_openxr_includes.h b/intern/ghost/intern/GHOST_Xr_openxr_includes.h
index 925d6037750..9cac43b1549 100644
--- a/intern/ghost/intern/GHOST_Xr_openxr_includes.h
+++ b/intern/ghost/intern/GHOST_Xr_openxr_includes.h
@@ -42,7 +42,7 @@
#ifdef XR_USE_GRAPHICS_API_D3D12
# include <d3d12.h>
#endif
-#ifdef WITH_X11
+#ifdef WITH_GHOST_X11
# include <GL/glxew.h>
#endif
diff --git a/intern/ghost/test/CMakeLists.txt b/intern/ghost/test/CMakeLists.txt
index eda41eb9c1a..b6e3c0ecf5f 100644
--- a/intern/ghost/test/CMakeLists.txt
+++ b/intern/ghost/test/CMakeLists.txt
@@ -85,8 +85,9 @@ endif()
# Libraries
if(UNIX AND NOT APPLE)
- set(WITH_X11 ON)
+ set(WITH_GHOST_X11 ON)
endif()
+
# for now... default to this
add_definitions(-DWITH_GL_PROFILE_COMPAT)
# BLF needs this to ignore GPU library
diff --git a/intern/ghost/test/gears/GHOST_Test.cpp b/intern/ghost/test/gears/GHOST_Test.cpp
index a554bfeebef..c9c497aacb4 100644
--- a/intern/ghost/test/gears/GHOST_Test.cpp
+++ b/intern/ghost/test/gears/GHOST_Test.cpp
@@ -27,6 +27,7 @@
#include <iostream>
#include <math.h>
+#include <string>
#if defined(WIN32) || defined(__APPLE__)
# ifdef WIN32
@@ -43,7 +44,6 @@
#endif // defined(WIN32) || defined(__APPLE__)
#include "GHOST_Rect.h"
-#include "STR_String.h"
#include "GHOST_IEvent.h"
#include "GHOST_IEventConsumer.h"
@@ -427,8 +427,7 @@ Application::Application(GHOST_ISystem *system)
fApp = this;
// Create the main window
- STR_String title1("gears - main window");
- m_mainWindow = system->createWindow(title1,
+ m_mainWindow = system->createWindow("gears - main window",
10,
64,
320,
@@ -443,8 +442,7 @@ Application::Application(GHOST_ISystem *system)
}
// Create a secondary window
- STR_String title2("gears - secondary window");
- m_secondaryWindow = system->createWindow(title2,
+ m_secondaryWindow = system->createWindow("gears - secondary window",
340,
64,
320,
@@ -598,8 +596,7 @@ bool Application::processEvent(GHOST_IEvent *event)
case GHOST_kKeyW:
if (m_mainWindow) {
- STR_String title;
- m_mainWindow->getTitle(title);
+ std::string title = m_mainWindow->getTitle();
title += "-";
m_mainWindow->setTitle(title);
}
diff --git a/intern/libmv/intern/camera_intrinsics.cc b/intern/libmv/intern/camera_intrinsics.cc
index 89e3d0d1178..554c4350b0a 100644
--- a/intern/libmv/intern/camera_intrinsics.cc
+++ b/intern/libmv/intern/camera_intrinsics.cc
@@ -24,6 +24,7 @@
using libmv::CameraIntrinsics;
using libmv::DivisionCameraIntrinsics;
using libmv::PolynomialCameraIntrinsics;
+using libmv::NukeCameraIntrinsics;
libmv_CameraIntrinsics *libmv_cameraIntrinsicsNew(
const libmv_CameraIntrinsicsOptions* libmv_camera_intrinsics_options) {
@@ -55,6 +56,14 @@ libmv_CameraIntrinsics *libmv_cameraIntrinsicsCopy(
*division_intrinsics);
break;
}
+ case libmv::DISTORTION_MODEL_NUKE:
+ {
+ const NukeCameraIntrinsics *nuke_intrinsics =
+ static_cast<const NukeCameraIntrinsics*>(orig_intrinsics);
+ new_intrinsics = LIBMV_OBJECT_NEW(NukeCameraIntrinsics,
+ *nuke_intrinsics);
+ break;
+ }
default:
assert(!"Unknown distortion model");
}
@@ -136,6 +145,25 @@ void libmv_cameraIntrinsicsUpdate(
break;
}
+ case LIBMV_DISTORTION_MODEL_NUKE:
+ {
+ assert(camera_intrinsics->GetDistortionModelType() ==
+ libmv::DISTORTION_MODEL_NUKE);
+
+ NukeCameraIntrinsics *nuke_intrinsics =
+ (NukeCameraIntrinsics *) camera_intrinsics;
+
+ double k1 = libmv_camera_intrinsics_options->nuke_k1;
+ double k2 = libmv_camera_intrinsics_options->nuke_k2;
+
+ if (nuke_intrinsics->k1() != k1 ||
+ nuke_intrinsics->k2() != k2) {
+ nuke_intrinsics->SetDistortion(k1, k2);
+ }
+
+ break;
+ }
+
default:
assert(!"Unknown distortion model");
}
@@ -189,6 +217,17 @@ void libmv_cameraIntrinsicsExtractOptions(
break;
}
+ case libmv::DISTORTION_MODEL_NUKE:
+ {
+ const NukeCameraIntrinsics *nuke_intrinsics =
+ static_cast<const NukeCameraIntrinsics *>(camera_intrinsics);
+ camera_intrinsics_options->distortion_model =
+ LIBMV_DISTORTION_MODEL_NUKE;
+ camera_intrinsics_options->nuke_k1 = nuke_intrinsics->k1();
+ camera_intrinsics_options->nuke_k2 = nuke_intrinsics->k2();
+ break;
+ }
+
default:
assert(!"Unknown distortion model");
}
@@ -316,6 +355,17 @@ static void libmv_cameraIntrinsicsFillFromOptions(
break;
}
+ case LIBMV_DISTORTION_MODEL_NUKE:
+ {
+ NukeCameraIntrinsics *nuke_intrinsics =
+ static_cast<NukeCameraIntrinsics*>(camera_intrinsics);
+
+ nuke_intrinsics->SetDistortion(
+ camera_intrinsics_options->nuke_k1,
+ camera_intrinsics_options->nuke_k2);
+ break;
+ }
+
default:
assert(!"Unknown distortion model");
}
@@ -331,6 +381,9 @@ CameraIntrinsics* libmv_cameraIntrinsicsCreateFromOptions(
case LIBMV_DISTORTION_MODEL_DIVISION:
camera_intrinsics = LIBMV_OBJECT_NEW(DivisionCameraIntrinsics);
break;
+ case LIBMV_DISTORTION_MODEL_NUKE:
+ camera_intrinsics = LIBMV_OBJECT_NEW(NukeCameraIntrinsics);
+ break;
default:
assert(!"Unknown distortion model");
}
diff --git a/intern/libmv/intern/camera_intrinsics.h b/intern/libmv/intern/camera_intrinsics.h
index 40a5826a9c4..b3d259893bd 100644
--- a/intern/libmv/intern/camera_intrinsics.h
+++ b/intern/libmv/intern/camera_intrinsics.h
@@ -29,6 +29,7 @@ typedef struct libmv_CameraIntrinsics libmv_CameraIntrinsics;
enum {
LIBMV_DISTORTION_MODEL_POLYNOMIAL = 0,
LIBMV_DISTORTION_MODEL_DIVISION = 1,
+ LIBMV_DISTORTION_MODEL_NUKE = 2,
};
typedef struct libmv_CameraIntrinsicsOptions {
@@ -45,6 +46,9 @@ typedef struct libmv_CameraIntrinsicsOptions {
// Division distortion model.
double division_k1, division_k2;
+
+ // Nuke distortion model.
+ double nuke_k1, nuke_k2;
} libmv_CameraIntrinsicsOptions;
libmv_CameraIntrinsics *libmv_cameraIntrinsicsNew(
diff --git a/intern/libmv/libmv/simple_pipeline/bundle.cc b/intern/libmv/libmv/simple_pipeline/bundle.cc
index e61650fb371..a70fdbc9888 100644
--- a/intern/libmv/libmv/simple_pipeline/bundle.cc
+++ b/intern/libmv/libmv/simple_pipeline/bundle.cc
@@ -66,18 +66,221 @@ enum {
namespace {
-// Cost functor which computes reprojection error of 3D point X
-// on camera defined by angle-axis rotation and it's translation
-// (which are in the same block due to optimization reasons).
+bool NeedUseInvertIntrinsicsPipeline(const CameraIntrinsics *intrinsics) {
+ const DistortionModelType distortion_model =
+ intrinsics->GetDistortionModelType();
+ return (distortion_model == DISTORTION_MODEL_NUKE);
+}
+
+// Apply distortion model (distort the input) on the input point in the
+// normalized space to get distorted coordinate in the image space.
+//
+// Using intrinsics values from the parameter block, which makes this function
+// suitable for use from a cost functor.
+//
+// Only use for distortion models which are analytically defined for their
+// Apply() function.
+//
+// The invariant_intrinsics are used to access intrinsics which are never
+// packed into parameter block: for example, distortion model type and image
+// dimension.
+template<typename T>
+void ApplyDistortionModelUsingIntrinsicsBlock(
+ const CameraIntrinsics *invariant_intrinsics,
+ const T* const intrinsics_block,
+ const T& normalized_x, const T& normalized_y,
+ T* distorted_x, T* distorted_y) {
+ // Unpack the intrinsics.
+ const T& focal_length = intrinsics_block[OFFSET_FOCAL_LENGTH];
+ const T& principal_point_x = intrinsics_block[OFFSET_PRINCIPAL_POINT_X];
+ const T& principal_point_y = intrinsics_block[OFFSET_PRINCIPAL_POINT_Y];
+
+ // TODO(keir): Do early bailouts for zero distortion; these are expensive
+ // jet operations.
+ switch (invariant_intrinsics->GetDistortionModelType()) {
+ case DISTORTION_MODEL_POLYNOMIAL:
+ {
+ const T& k1 = intrinsics_block[OFFSET_K1];
+ const T& k2 = intrinsics_block[OFFSET_K2];
+ const T& k3 = intrinsics_block[OFFSET_K3];
+ const T& p1 = intrinsics_block[OFFSET_P1];
+ const T& p2 = intrinsics_block[OFFSET_P2];
+
+ ApplyPolynomialDistortionModel(focal_length,
+ focal_length,
+ principal_point_x,
+ principal_point_y,
+ k1, k2, k3,
+ p1, p2,
+ normalized_x, normalized_y,
+ distorted_x, distorted_y);
+ return;
+ }
+
+ case DISTORTION_MODEL_DIVISION:
+ {
+ const T& k1 = intrinsics_block[OFFSET_K1];
+ const T& k2 = intrinsics_block[OFFSET_K2];
+
+ ApplyDivisionDistortionModel(focal_length,
+ focal_length,
+ principal_point_x,
+ principal_point_y,
+ k1, k2,
+ normalized_x, normalized_y,
+ distorted_x, distorted_y);
+ return;
+ }
+
+ case DISTORTION_MODEL_NUKE:
+ {
+ LOG(FATAL) << "Unsupported distortion model.";
+ return;
+ }
+ }
+
+ LOG(FATAL) << "Unknown distortion model.";
+}
+
+// Invert distortion model (undistort the input) on the input point in the
+// image space to get undistorted coordinate in the normalized space.
+//
+// Using intrinsics values from the parameter block, which makes this function
+// suitable for use from a cost functor.
+//
+// Only use for distortion models which are analytically defined for their
+// Invert() function.
+//
+// The invariant_intrinsics are used to access intrinsics which are never
+// packed into parameter block: for example, distortion model type and image
+// dimension.
+template<typename T>
+void InvertDistortionModelUsingIntrinsicsBlock(
+ const CameraIntrinsics *invariant_intrinsics,
+ const T* const intrinsics_block,
+ const T& image_x, const T& image_y,
+ T* normalized_x, T* normalized_y) {
+ // Unpack the intrinsics.
+ const T& focal_length = intrinsics_block[OFFSET_FOCAL_LENGTH];
+ const T& principal_point_x = intrinsics_block[OFFSET_PRINCIPAL_POINT_X];
+ const T& principal_point_y = intrinsics_block[OFFSET_PRINCIPAL_POINT_Y];
+
+ // TODO(keir): Do early bailouts for zero distortion; these are expensive
+ // jet operations.
+ switch (invariant_intrinsics->GetDistortionModelType()) {
+ case DISTORTION_MODEL_POLYNOMIAL:
+ case DISTORTION_MODEL_DIVISION:
+ LOG(FATAL) << "Unsupported distortion model.";
+ return;
+
+ case DISTORTION_MODEL_NUKE:
+ {
+ const T& k1 = intrinsics_block[OFFSET_K1];
+ const T& k2 = intrinsics_block[OFFSET_K2];
+
+ InvertNukeDistortionModel(focal_length,
+ focal_length,
+ principal_point_x,
+ principal_point_y,
+ invariant_intrinsics->image_width(),
+ invariant_intrinsics->image_height(),
+ k1, k2,
+ image_x, image_y,
+ normalized_x, normalized_y);
+ return;
+ }
+ }
+
+ LOG(FATAL) << "Unknown distortion model.";
+}
+
+template<typename T>
+void NormalizedToImageSpace(const T* const intrinsics_block,
+ const T& normalized_x, const T& normalized_y,
+ T* image_x, T* image_y) {
+ // Unpack the intrinsics.
+ const T& focal_length = intrinsics_block[OFFSET_FOCAL_LENGTH];
+ const T& principal_point_x = intrinsics_block[OFFSET_PRINCIPAL_POINT_X];
+ const T& principal_point_y = intrinsics_block[OFFSET_PRINCIPAL_POINT_Y];
+
+ *image_x = normalized_x * focal_length + principal_point_x;
+ *image_y = normalized_y * focal_length + principal_point_y;
+}
+
+// Cost functor which computes reprojection error of 3D point X on camera
+// defined by angle-axis rotation and it's translation (which are in the same
+// block due to optimization reasons).
+//
+// This functor can only be used for distortion models which have analytically
+// defined Apply() function.
+struct ReprojectionErrorApplyIntrinsics {
+ ReprojectionErrorApplyIntrinsics(
+ const CameraIntrinsics *invariant_intrinsics,
+ const double observed_distorted_x,
+ const double observed_distorted_y,
+ const double weight)
+ : invariant_intrinsics_(invariant_intrinsics),
+ observed_distorted_x_(observed_distorted_x),
+ observed_distorted_y_(observed_distorted_y),
+ weight_(weight) {}
+
+ template <typename T>
+ bool operator()(const T* const intrinsics,
+ const T* const R_t, // Rotation denoted by angle axis
+ // followed with translation
+ const T* const X, // Point coordinates 3x1.
+ T* residuals) const {
+ // Compute projective coordinates: x = RX + t.
+ T x[3];
+
+ ceres::AngleAxisRotatePoint(R_t, X, x);
+ x[0] += R_t[3];
+ x[1] += R_t[4];
+ x[2] += R_t[5];
+
+ // Prevent points from going behind the camera.
+ if (x[2] < T(0)) {
+ return false;
+ }
+
+ // Compute normalized coordinates: x /= x[2].
+ T xn = x[0] / x[2];
+ T yn = x[1] / x[2];
+
+ T predicted_distorted_x, predicted_distorted_y;
+ ApplyDistortionModelUsingIntrinsicsBlock(
+ invariant_intrinsics_,
+ intrinsics,
+ xn, yn,
+ &predicted_distorted_x, &predicted_distorted_y);
+
+ // The error is the difference between the predicted and observed position.
+ residuals[0] = (predicted_distorted_x - T(observed_distorted_x_)) * weight_;
+ residuals[1] = (predicted_distorted_y - T(observed_distorted_y_)) * weight_;
+ return true;
+ }
+
+ const CameraIntrinsics *invariant_intrinsics_;
+ const double observed_distorted_x_;
+ const double observed_distorted_y_;
+ const double weight_;
+};
+
+// Cost functor which computes reprojection error of 3D point X on camera
+// defined by angle-axis rotation and it's translation (which are in the same
+// block due to optimization reasons).
//
-// This functor uses a radial distortion model.
-struct OpenCVReprojectionError {
- OpenCVReprojectionError(const DistortionModelType distortion_model,
- const double observed_x,
- const double observed_y,
- const double weight)
- : distortion_model_(distortion_model),
- observed_x_(observed_x), observed_y_(observed_y),
+// This functor can only be used for distortion models which have analytically
+// defined Invert() function.
+struct ReprojectionErrorInvertIntrinsics {
+ ReprojectionErrorInvertIntrinsics(
+ const CameraIntrinsics *invariant_intrinsics,
+ const double observed_distorted_x,
+ const double observed_distorted_y,
+ const double weight)
+ : invariant_intrinsics_(invariant_intrinsics),
+ observed_distorted_x_(observed_distorted_x),
+ observed_distorted_y_(observed_distorted_y),
weight_(weight) {}
template <typename T>
@@ -108,63 +311,37 @@ struct OpenCVReprojectionError {
T xn = x[0] / x[2];
T yn = x[1] / x[2];
- T predicted_x, predicted_y;
-
- // Apply distortion to the normalized points to get (xd, yd).
- // TODO(keir): Do early bailouts for zero distortion; these are expensive
- // jet operations.
- switch (distortion_model_) {
- case DISTORTION_MODEL_POLYNOMIAL:
- {
- const T& k1 = intrinsics[OFFSET_K1];
- const T& k2 = intrinsics[OFFSET_K2];
- const T& k3 = intrinsics[OFFSET_K3];
- const T& p1 = intrinsics[OFFSET_P1];
- const T& p2 = intrinsics[OFFSET_P2];
-
- ApplyPolynomialDistortionModel(focal_length,
- focal_length,
- principal_point_x,
- principal_point_y,
- k1, k2, k3,
- p1, p2,
- xn, yn,
- &predicted_x,
- &predicted_y);
- break;
- }
- case DISTORTION_MODEL_DIVISION:
- {
- const T& k1 = intrinsics[OFFSET_K1];
- const T& k2 = intrinsics[OFFSET_K2];
+ // Compute image space coordinate from normalized.
+ T predicted_x = focal_length * xn + principal_point_x;
+ T predicted_y = focal_length * yn + principal_point_y;
- ApplyDivisionDistortionModel(focal_length,
- focal_length,
- principal_point_x,
- principal_point_y,
- k1, k2,
- xn, yn,
- &predicted_x,
- &predicted_y);
- break;
- }
- default:
- LOG(FATAL) << "Unknown distortion model";
- }
+ T observed_undistorted_normalized_x, observed_undistorted_normalized_y;
+ InvertDistortionModelUsingIntrinsicsBlock(
+ invariant_intrinsics_,
+ intrinsics,
+ T(observed_distorted_x_), T(observed_distorted_y_),
+ &observed_undistorted_normalized_x, &observed_undistorted_normalized_y);
+
+ T observed_undistorted_image_x, observed_undistorted_image_y;
+ NormalizedToImageSpace(
+ intrinsics,
+ observed_undistorted_normalized_x, observed_undistorted_normalized_y,
+ &observed_undistorted_image_x, &observed_undistorted_image_y);
// The error is the difference between the predicted and observed position.
- residuals[0] = (predicted_x - T(observed_x_)) * weight_;
- residuals[1] = (predicted_y - T(observed_y_)) * weight_;
+ residuals[0] = (predicted_x - observed_undistorted_image_x) * weight_;
+ residuals[1] = (predicted_y - observed_undistorted_image_y) * weight_;
+
return true;
}
- const DistortionModelType distortion_model_;
- const double observed_x_;
- const double observed_y_;
+ const CameraIntrinsics *invariant_intrinsics_;
+ const double observed_distorted_x_;
+ const double observed_distorted_y_;
const double weight_;
};
-// Print a message to the log which camera intrinsics are gonna to be optimixed.
+// Print a message to the log which camera intrinsics are gonna to be optimized.
void BundleIntrinsicsLogMessage(const int bundle_intrinsics) {
if (bundle_intrinsics == BUNDLE_NO_INTRINSICS) {
LOG(INFO) << "Bundling only camera positions.";
@@ -193,29 +370,29 @@ void BundleIntrinsicsLogMessage(const int bundle_intrinsics) {
// Pack intrinsics from object to an array for easier
// and faster minimization.
void PackIntrinisicsIntoArray(const CameraIntrinsics &intrinsics,
- double ceres_intrinsics[OFFSET_MAX]) {
- ceres_intrinsics[OFFSET_FOCAL_LENGTH] = intrinsics.focal_length();
- ceres_intrinsics[OFFSET_PRINCIPAL_POINT_X] = intrinsics.principal_point_x();
- ceres_intrinsics[OFFSET_PRINCIPAL_POINT_Y] = intrinsics.principal_point_y();
+ double intrinsics_block[OFFSET_MAX]) {
+ intrinsics_block[OFFSET_FOCAL_LENGTH] = intrinsics.focal_length();
+ intrinsics_block[OFFSET_PRINCIPAL_POINT_X] = intrinsics.principal_point_x();
+ intrinsics_block[OFFSET_PRINCIPAL_POINT_Y] = intrinsics.principal_point_y();
int num_distortion_parameters = intrinsics.num_distortion_parameters();
assert(num_distortion_parameters <= NUM_DISTORTION_COEFFICIENTS);
const double *distortion_parameters = intrinsics.distortion_parameters();
for (int i = 0; i < num_distortion_parameters; ++i) {
- ceres_intrinsics[FIRST_DISTORTION_COEFFICIENT + i] =
+ intrinsics_block[FIRST_DISTORTION_COEFFICIENT + i] =
distortion_parameters[i];
}
}
// Unpack intrinsics back from an array to an object.
-void UnpackIntrinsicsFromArray(const double ceres_intrinsics[OFFSET_MAX],
+void UnpackIntrinsicsFromArray(const double intrinsics_block[OFFSET_MAX],
CameraIntrinsics *intrinsics) {
- intrinsics->SetFocalLength(ceres_intrinsics[OFFSET_FOCAL_LENGTH],
- ceres_intrinsics[OFFSET_FOCAL_LENGTH]);
+ intrinsics->SetFocalLength(intrinsics_block[OFFSET_FOCAL_LENGTH],
+ intrinsics_block[OFFSET_FOCAL_LENGTH]);
- intrinsics->SetPrincipalPoint(ceres_intrinsics[OFFSET_PRINCIPAL_POINT_X],
- ceres_intrinsics[OFFSET_PRINCIPAL_POINT_Y]);
+ intrinsics->SetPrincipalPoint(intrinsics_block[OFFSET_PRINCIPAL_POINT_X],
+ intrinsics_block[OFFSET_PRINCIPAL_POINT_Y]);
int num_distortion_parameters = intrinsics->num_distortion_parameters();
assert(num_distortion_parameters <= NUM_DISTORTION_COEFFICIENTS);
@@ -223,7 +400,7 @@ void UnpackIntrinsicsFromArray(const double ceres_intrinsics[OFFSET_MAX],
double *distortion_parameters = intrinsics->distortion_parameters();
for (int i = 0; i < num_distortion_parameters; ++i) {
distortion_parameters[i] =
- ceres_intrinsics[FIRST_DISTORTION_COEFFICIENT + i];
+ intrinsics_block[FIRST_DISTORTION_COEFFICIENT + i];
}
}
@@ -302,68 +479,117 @@ void EuclideanBundlerPerformEvaluation(const Tracks &tracks,
vector<Vec6> *all_cameras_R_t,
ceres::Problem *problem,
BundleEvaluation *evaluation) {
- int max_track = tracks.MaxTrack();
- // Number of camera rotations equals to number of translation,
- int num_cameras = all_cameras_R_t->size();
- int num_points = 0;
-
- vector<EuclideanPoint*> minimized_points;
- for (int i = 0; i <= max_track; i++) {
- EuclideanPoint *point = reconstruction->PointForTrack(i);
- if (point) {
- // We need to know whether the track is constant zero weight,
- // and it so it wouldn't have parameter block in the problem.
- //
- // Getting all markers for track is not so bac currently since
- // this code is only used by keyframe selection when there are
- // not so much tracks and only 2 frames anyway.
- vector<Marker> markera_of_track = tracks.MarkersForTrack(i);
- for (int j = 0; j < markera_of_track.size(); j++) {
- if (markera_of_track.at(j).weight != 0.0) {
- minimized_points.push_back(point);
- num_points++;
- break;
- }
+ int max_track = tracks.MaxTrack();
+ // Number of camera rotations equals to number of translation,
+ int num_cameras = all_cameras_R_t->size();
+ int num_points = 0;
+
+ vector<EuclideanPoint*> minimized_points;
+ for (int i = 0; i <= max_track; i++) {
+ EuclideanPoint *point = reconstruction->PointForTrack(i);
+ if (point) {
+ // We need to know whether the track is a constant zero weight.
+ // If it is so it wouldn't have a parameter block in the problem.
+ //
+ // Usually getting all markers of a track is considered slow, but this
+ // code is only used by the keyframe selection code where there aren't
+ // that many tracks in the storage and there are only 2 frames for each
+ // of the tracks.
+ vector<Marker> markera_of_track = tracks.MarkersForTrack(i);
+ for (int j = 0; j < markera_of_track.size(); j++) {
+ if (markera_of_track.at(j).weight != 0.0) {
+ minimized_points.push_back(point);
+ num_points++;
+ break;
}
}
}
+ }
- LG << "Number of cameras " << num_cameras;
- LG << "Number of points " << num_points;
+ LG << "Number of cameras " << num_cameras;
+ LG << "Number of points " << num_points;
- evaluation->num_cameras = num_cameras;
- evaluation->num_points = num_points;
+ evaluation->num_cameras = num_cameras;
+ evaluation->num_points = num_points;
- if (evaluation->evaluate_jacobian) { // Evaluate jacobian matrix.
- ceres::CRSMatrix evaluated_jacobian;
- ceres::Problem::EvaluateOptions eval_options;
+ if (evaluation->evaluate_jacobian) { // Evaluate jacobian matrix.
+ ceres::CRSMatrix evaluated_jacobian;
+ ceres::Problem::EvaluateOptions eval_options;
- // Cameras goes first in the ordering.
- int max_image = tracks.MaxImage();
- for (int i = 0; i <= max_image; i++) {
- const EuclideanCamera *camera = reconstruction->CameraForImage(i);
- if (camera) {
- double *current_camera_R_t = &(*all_cameras_R_t)[i](0);
+ // Cameras goes first in the ordering.
+ int max_image = tracks.MaxImage();
+ for (int i = 0; i <= max_image; i++) {
+ const EuclideanCamera *camera = reconstruction->CameraForImage(i);
+ if (camera) {
+ double *current_camera_R_t = &(*all_cameras_R_t)[i](0);
- // All cameras are variable now.
- problem->SetParameterBlockVariable(current_camera_R_t);
+ // All cameras are variable now.
+ problem->SetParameterBlockVariable(current_camera_R_t);
- eval_options.parameter_blocks.push_back(current_camera_R_t);
- }
+ eval_options.parameter_blocks.push_back(current_camera_R_t);
}
+ }
- // Points goes at the end of ordering,
- for (int i = 0; i < minimized_points.size(); i++) {
- EuclideanPoint *point = minimized_points.at(i);
- eval_options.parameter_blocks.push_back(&point->X(0));
- }
+ // Points goes at the end of ordering,
+ for (int i = 0; i < minimized_points.size(); i++) {
+ EuclideanPoint *point = minimized_points.at(i);
+ eval_options.parameter_blocks.push_back(&point->X(0));
+ }
- problem->Evaluate(eval_options,
- NULL, NULL, NULL,
- &evaluated_jacobian);
+ problem->Evaluate(eval_options,
+ NULL, NULL, NULL,
+ &evaluated_jacobian);
- CRSMatrixToEigenMatrix(evaluated_jacobian, &evaluation->jacobian);
- }
+ CRSMatrixToEigenMatrix(evaluated_jacobian, &evaluation->jacobian);
+ }
+}
+
+template<typename CostFunction>
+void AddResidualBlockToProblemImpl(const CameraIntrinsics *invariant_intrinsics,
+ double observed_x, double observed_y,
+ double weight,
+ double intrinsics_block[OFFSET_MAX],
+ double *camera_R_t,
+ EuclideanPoint *point,
+ ceres::Problem* problem) {
+ problem->AddResidualBlock(new ceres::AutoDiffCostFunction<
+ CostFunction, 2, OFFSET_MAX, 6, 3>(
+ new CostFunction(
+ invariant_intrinsics,
+ observed_x, observed_y,
+ weight)),
+ NULL,
+ intrinsics_block,
+ camera_R_t,
+ &point->X(0));
+}
+
+void AddResidualBlockToProblem(const CameraIntrinsics *invariant_intrinsics,
+ const Marker &marker,
+ double marker_weight,
+ double intrinsics_block[OFFSET_MAX],
+ double *camera_R_t,
+ EuclideanPoint *point,
+ ceres::Problem* problem) {
+ if (NeedUseInvertIntrinsicsPipeline(invariant_intrinsics)) {
+ AddResidualBlockToProblemImpl<ReprojectionErrorInvertIntrinsics>(
+ invariant_intrinsics,
+ marker.x, marker.y,
+ marker_weight,
+ intrinsics_block,
+ camera_R_t,
+ point,
+ problem);
+ } else {
+ AddResidualBlockToProblemImpl<ReprojectionErrorApplyIntrinsics>(
+ invariant_intrinsics,
+ marker.x, marker.y,
+ marker_weight,
+ intrinsics_block,
+ camera_R_t,
+ point,
+ problem);
+ }
}
// This is an utility function to only bundle 3D position of
@@ -375,10 +601,10 @@ void EuclideanBundlerPerformEvaluation(const Tracks &tracks,
//
// At this point we only need to bundle points positions, cameras
// are to be totally still here.
-void EuclideanBundlePointsOnly(const DistortionModelType distortion_model,
+void EuclideanBundlePointsOnly(const CameraIntrinsics *invariant_intrinsics,
const vector<Marker> &markers,
vector<Vec6> &all_cameras_R_t,
- double ceres_intrinsics[OFFSET_MAX],
+ double intrinsics_block[OFFSET_MAX],
EuclideanReconstruction *reconstruction) {
ceres::Problem::Options problem_options;
ceres::Problem problem(problem_options);
@@ -392,20 +618,16 @@ void EuclideanBundlePointsOnly(const DistortionModelType distortion_model,
}
// Rotation of camera denoted in angle axis followed with
- // camera translaiton.
+ // camera translation.
double *current_camera_R_t = &all_cameras_R_t[camera->image](0);
- problem.AddResidualBlock(new ceres::AutoDiffCostFunction<
- OpenCVReprojectionError, 2, OFFSET_MAX, 6, 3>(
- new OpenCVReprojectionError(
- distortion_model,
- marker.x,
- marker.y,
- 1.0)),
- NULL,
- ceres_intrinsics,
- current_camera_R_t,
- &point->X(0));
+ AddResidualBlockToProblem(invariant_intrinsics,
+ marker,
+ 1.0,
+ intrinsics_block,
+ current_camera_R_t,
+ point,
+ &problem);
problem.SetParameterBlockConstant(current_camera_R_t);
num_residuals++;
@@ -417,7 +639,7 @@ void EuclideanBundlePointsOnly(const DistortionModelType distortion_model,
return;
}
- problem.SetParameterBlockConstant(ceres_intrinsics);
+ problem.SetParameterBlockConstant(intrinsics_block);
// Configure the solver.
ceres::Solver::Options options;
@@ -438,7 +660,6 @@ void EuclideanBundlePointsOnly(const DistortionModelType distortion_model,
ceres::Solve(options, &problem, &summary);
LG << "Final report:\n" << summary.FullReport();
-
}
} // namespace
@@ -464,14 +685,14 @@ void EuclideanBundleCommonIntrinsics(
LG << "Original intrinsics: " << *intrinsics;
vector<Marker> markers = tracks.AllMarkers();
- // N-th element denotes whether track N is a constant zero-weigthed track.
+ // N-th element denotes whether track N is a constant zero-weighted track.
vector<bool> zero_weight_tracks_flags(tracks.MaxTrack() + 1, true);
// Residual blocks with 10 parameters are unwieldly with Ceres, so pack the
// intrinsics into a single block and rely on local parameterizations to
// control which intrinsics are allowed to vary.
- double ceres_intrinsics[OFFSET_MAX];
- PackIntrinisicsIntoArray(*intrinsics, ceres_intrinsics);
+ double intrinsics_block[OFFSET_MAX];
+ PackIntrinisicsIntoArray(*intrinsics, intrinsics_block);
// Convert cameras rotations to angle axis and merge with translation
// into single parameter block for maximal minimization speed.
@@ -509,24 +730,20 @@ void EuclideanBundleCommonIntrinsics(
}
// Rotation of camera denoted in angle axis followed with
- // camera translaiton.
+ // camera translation.
double *current_camera_R_t = &all_cameras_R_t[camera->image](0);
// Skip residual block for markers which does have absolutely
// no affect on the final solution.
// This way ceres is not gonna to go crazy.
if (marker.weight != 0.0) {
- problem.AddResidualBlock(new ceres::AutoDiffCostFunction<
- OpenCVReprojectionError, 2, OFFSET_MAX, 6, 3>(
- new OpenCVReprojectionError(
- intrinsics->GetDistortionModelType(),
- marker.x,
- marker.y,
- marker.weight)),
- NULL,
- ceres_intrinsics,
- current_camera_R_t,
- &point->X(0));
+ AddResidualBlockToProblem(intrinsics,
+ marker,
+ marker.weight,
+ intrinsics_block,
+ current_camera_R_t,
+ point,
+ &problem);
// We lock the first camera to better deal with scene orientation ambiguity.
if (!have_locked_camera) {
@@ -561,7 +778,7 @@ void EuclideanBundleCommonIntrinsics(
if (bundle_intrinsics == BUNDLE_NO_INTRINSICS) {
// No camera intrinsics are being refined,
// set the whole parameter block as constant for best performance.
- problem.SetParameterBlockConstant(ceres_intrinsics);
+ problem.SetParameterBlockConstant(intrinsics_block);
} else {
// Set the camera intrinsics that are not to be bundled as
// constant using some macro trickery.
@@ -586,7 +803,7 @@ void EuclideanBundleCommonIntrinsics(
ceres::SubsetParameterization *subset_parameterization =
new ceres::SubsetParameterization(OFFSET_MAX, constant_intrinsics);
- problem.SetParameterization(ceres_intrinsics, subset_parameterization);
+ problem.SetParameterization(intrinsics_block, subset_parameterization);
}
// Configure the solver.
@@ -616,7 +833,7 @@ void EuclideanBundleCommonIntrinsics(
// Copy intrinsics back.
if (bundle_intrinsics != BUNDLE_NO_INTRINSICS)
- UnpackIntrinsicsFromArray(ceres_intrinsics, intrinsics);
+ UnpackIntrinsicsFromArray(intrinsics_block, intrinsics);
LG << "Final intrinsics: " << *intrinsics;
@@ -641,10 +858,10 @@ void EuclideanBundleCommonIntrinsics(
if (zero_weight_markers.size()) {
LG << "Refining position of constant zero-weighted tracks";
- EuclideanBundlePointsOnly(intrinsics->GetDistortionModelType(),
+ EuclideanBundlePointsOnly(intrinsics,
zero_weight_markers,
all_cameras_R_t,
- ceres_intrinsics,
+ intrinsics_block,
reconstruction);
}
}
diff --git a/intern/libmv/libmv/simple_pipeline/camera_intrinsics.cc b/intern/libmv/libmv/simple_pipeline/camera_intrinsics.cc
index 5e4e07b3c4c..a95b394ad06 100644
--- a/intern/libmv/libmv/simple_pipeline/camera_intrinsics.cc
+++ b/intern/libmv/libmv/simple_pipeline/camera_intrinsics.cc
@@ -131,6 +131,8 @@ void CameraIntrinsics::ResetLookupGrids() {
undistort_.Reset();
}
+// Polynomial model.
+
PolynomialCameraIntrinsics::PolynomialCameraIntrinsics()
: CameraIntrinsics() {
SetRadialDistortion(0.0, 0.0, 0.0);
@@ -193,6 +195,8 @@ void PolynomialCameraIntrinsics::InvertIntrinsics(
normalized_y);
}
+// Division model.
+
DivisionCameraIntrinsics::DivisionCameraIntrinsics()
: CameraIntrinsics() {
SetDistortion(0.0, 0.0);
@@ -241,6 +245,57 @@ void DivisionCameraIntrinsics::InvertIntrinsics(double image_x,
normalized_y);
}
+// Nuke model.
+
+NukeCameraIntrinsics::NukeCameraIntrinsics()
+ : CameraIntrinsics() {
+ SetDistortion(0.0, 0.0);
+}
+
+NukeCameraIntrinsics::NukeCameraIntrinsics(
+ const NukeCameraIntrinsics &from)
+ : CameraIntrinsics(from) {
+ SetDistortion(from.k1(), from.k1());
+}
+
+void NukeCameraIntrinsics::SetDistortion(double k1, double k2) {
+ parameters_[OFFSET_K1] = k1;
+ parameters_[OFFSET_K2] = k2;
+ ResetLookupGrids();
+}
+
+void NukeCameraIntrinsics::ApplyIntrinsics(double normalized_x,
+ double normalized_y,
+ double *image_x,
+ double *image_y) const {
+ ApplyNukeDistortionModel(focal_length_x(),
+ focal_length_y(),
+ principal_point_x(),
+ principal_point_y(),
+ image_width(), image_height(),
+ k1(), k2(),
+ normalized_x,
+ normalized_y,
+ image_x,
+ image_y);
+}
+
+void NukeCameraIntrinsics::InvertIntrinsics(double image_x,
+ double image_y,
+ double *normalized_x,
+ double *normalized_y) const {
+ InvertNukeDistortionModel(focal_length_x(),
+ focal_length_y(),
+ principal_point_x(),
+ principal_point_y(),
+ image_width(), image_height(),
+ k1(), k2(),
+ image_x,
+ image_y,
+ normalized_x,
+ normalized_y);
+}
+
std::ostream& operator <<(std::ostream &os,
const CameraIntrinsics &intrinsics) {
if (intrinsics.focal_length_x() == intrinsics.focal_length_x()) {
@@ -281,6 +336,14 @@ std::ostream& operator <<(std::ostream &os,
PRINT_NONZERO_COEFFICIENT(division_intrinsics, k2);
break;
}
+ case DISTORTION_MODEL_NUKE:
+ {
+ const NukeCameraIntrinsics *nuke_intrinsics =
+ static_cast<const NukeCameraIntrinsics *>(&intrinsics);
+ PRINT_NONZERO_COEFFICIENT(nuke_intrinsics, k1);
+ PRINT_NONZERO_COEFFICIENT(nuke_intrinsics, k2);
+ break;
+ }
default:
LOG(FATAL) << "Unknown distortion model.";
}
diff --git a/intern/libmv/libmv/simple_pipeline/camera_intrinsics.h b/intern/libmv/libmv/simple_pipeline/camera_intrinsics.h
index 6a3ade81089..782fd56c54c 100644
--- a/intern/libmv/libmv/simple_pipeline/camera_intrinsics.h
+++ b/intern/libmv/libmv/simple_pipeline/camera_intrinsics.h
@@ -276,7 +276,7 @@ class CameraIntrinsics {
class PolynomialCameraIntrinsics : public CameraIntrinsics {
public:
// This constants defines an offset of corresponding coefficients
- // in the arameters_ array.
+ // in the parameters_ array.
enum {
OFFSET_K1,
OFFSET_K2,
@@ -342,7 +342,7 @@ class PolynomialCameraIntrinsics : public CameraIntrinsics {
class DivisionCameraIntrinsics : public CameraIntrinsics {
public:
// This constants defines an offset of corresponding coefficients
- // in the arameters_ array.
+ // in the parameters_ array.
enum {
OFFSET_K1,
OFFSET_K2,
@@ -393,6 +393,60 @@ class DivisionCameraIntrinsics : public CameraIntrinsics {
double parameters_[NUM_PARAMETERS];
};
+class NukeCameraIntrinsics : public CameraIntrinsics {
+ public:
+ // This constants defines an offset of corresponding coefficients
+ // in the parameters_ array.
+ enum {
+ OFFSET_K1,
+ OFFSET_K2,
+
+ // This defines the size of array which we need to have in order
+ // to store all the coefficients.
+ NUM_PARAMETERS,
+ };
+
+ NukeCameraIntrinsics();
+ NukeCameraIntrinsics(const NukeCameraIntrinsics &from);
+
+ DistortionModelType GetDistortionModelType() const {
+ return DISTORTION_MODEL_NUKE;
+ }
+
+ int num_distortion_parameters() const { return NUM_PARAMETERS; }
+ double *distortion_parameters() { return parameters_; };
+ const double *distortion_parameters() const { return parameters_; };
+
+ double k1() const { return parameters_[OFFSET_K1]; }
+ double k2() const { return parameters_[OFFSET_K2]; }
+
+ // Set radial distortion coeffcients.
+ void SetDistortion(double k1, double k2);
+
+ // Apply camera intrinsics to the normalized point to get image coordinates.
+ //
+ // This applies the lens distortion to a point which is in normalized
+ // camera coordinates (i.e. the principal point is at (0, 0)) to get image
+ // coordinates in pixels.
+ void ApplyIntrinsics(double normalized_x,
+ double normalized_y,
+ double *image_x,
+ double *image_y) const;
+
+ // Invert camera intrinsics on the image point to get normalized coordinates.
+ //
+ // This reverses the effect of lens distortion on a point which is in image
+ // coordinates to get normalized camera coordinates.
+ void InvertIntrinsics(double image_x,
+ double image_y,
+ double *normalized_x,
+ double *normalized_y) const;
+
+ private:
+ // Double-parameter division distortion model.
+ double parameters_[NUM_PARAMETERS];
+};
+
/// A human-readable representation of the camera intrinsic parameters.
std::ostream& operator <<(std::ostream &os,
const CameraIntrinsics &intrinsics);
diff --git a/intern/libmv/libmv/simple_pipeline/distortion_models.cc b/intern/libmv/libmv/simple_pipeline/distortion_models.cc
index 9b6dca2678a..c069fc6f623 100644
--- a/intern/libmv/libmv/simple_pipeline/distortion_models.cc
+++ b/intern/libmv/libmv/simple_pipeline/distortion_models.cc
@@ -194,4 +194,96 @@ void InvertDivisionDistortionModel(const double focal_length_x,
*normalized_y = normalized(1);
}
+struct ApplyNukeIntrinsicsCostFunction {
+ public:
+ typedef Vec2 FMatrixType;
+ typedef Vec2 XMatrixType;
+
+ ApplyNukeIntrinsicsCostFunction(const double focal_length_x,
+ const double focal_length_y,
+ const double principal_point_x,
+ const double principal_point_y,
+ const int image_width,
+ const int image_height,
+ const double k1,
+ const double k2,
+ const double expected_normalized_x,
+ const double expected_normalized_y)
+ : focal_length_x_(focal_length_x),
+ focal_length_y_(focal_length_y),
+ principal_point_x_(principal_point_x),
+ principal_point_y_(principal_point_y),
+ image_width_(image_width),
+ image_height_(image_height),
+ k1_(k1), k2_(k2),
+ expected_normalized_x_(expected_normalized_x),
+ expected_normalized_y_(expected_normalized_y) {}
+
+ Vec2 operator()(const Vec2 &image_coordinate) const {
+ double actual_normalized_x, actual_normalized_y;
+
+ InvertNukeDistortionModel(focal_length_x_,
+ focal_length_y_,
+ principal_point_x_,
+ principal_point_y_,
+ image_width_, image_height_,
+ k1_, k2_,
+ image_coordinate(0), image_coordinate(1),
+ &actual_normalized_x, &actual_normalized_y);
+
+ Vec2 fx;
+ fx << (actual_normalized_x - expected_normalized_x_),
+ (actual_normalized_y - expected_normalized_y_);
+ return fx;
+ }
+ double focal_length_x_;
+ double focal_length_y_;
+ double principal_point_x_;
+ double principal_point_y_;
+ int image_width_;
+ int image_height_;
+ double k1_, k2_;
+ double expected_normalized_x_, expected_normalized_y_;
+};
+
+void ApplyNukeDistortionModel(const double focal_length_x,
+ const double focal_length_y,
+ const double principal_point_x,
+ const double principal_point_y,
+ const int image_width,
+ const int image_height,
+ const double k1,
+ const double k2,
+ const double normalized_x,
+ const double normalized_y,
+ double *image_x,
+ double *image_y) {
+ // Compute the initial guess. For a camera with no distortion, this will also
+ // be the final answer; the LM iteration will terminate immediately.
+ Vec2 image;
+ image(0) = normalized_x * focal_length_x + principal_point_x;
+ image(1) = normalized_y * focal_length_y + principal_point_y;
+
+ // TODO(sergey): Use Ceres minimizer instead.
+ typedef LevenbergMarquardt<ApplyNukeIntrinsicsCostFunction> Solver;
+
+ ApplyNukeIntrinsicsCostFunction intrinsics_cost(focal_length_x,
+ focal_length_y,
+ principal_point_x,
+ principal_point_y,
+ image_width,
+ image_height,
+ k1, k2,
+ normalized_x, normalized_y);
+ Solver::SolverParameters params;
+ Solver solver(intrinsics_cost);
+
+ /*Solver::Results results =*/ solver.minimize(params, &image);
+
+ // TODO(keir): Better error handling.
+
+ *image_x = image(0);
+ *image_y = image(1);
+}
+
} // namespace libmv
diff --git a/intern/libmv/libmv/simple_pipeline/distortion_models.h b/intern/libmv/libmv/simple_pipeline/distortion_models.h
index 4f8e2295a0e..6ba351d729d 100644
--- a/intern/libmv/libmv/simple_pipeline/distortion_models.h
+++ b/intern/libmv/libmv/simple_pipeline/distortion_models.h
@@ -21,11 +21,14 @@
#ifndef LIBMV_SIMPLE_PIPELINE_DISTORTION_MODELS_H_
#define LIBMV_SIMPLE_PIPELINE_DISTORTION_MODELS_H_
+#include <algorithm>
+
namespace libmv {
enum DistortionModelType {
DISTORTION_MODEL_POLYNOMIAL,
- DISTORTION_MODEL_DIVISION
+ DISTORTION_MODEL_DIVISION,
+ DISTORTION_MODEL_NUKE,
};
// Invert camera intrinsics on the image point to get normalized coordinates.
@@ -126,6 +129,79 @@ inline void ApplyDivisionDistortionModel(const T &focal_length_x,
*image_y = focal_length_y * yd + principal_point_y;
}
+// Invert camera intrinsics on the image point to get normalized coordinates.
+// This inverts the radial lens distortion to a point which is in image pixel
+// coordinates to get normalized coordinates.
+//
+// Uses Nuke distortion model.
+template <typename T>
+void InvertNukeDistortionModel(const T &focal_length_x,
+ const T &focal_length_y,
+ const T &principal_point_x,
+ const T &principal_point_y,
+ const int image_width,
+ const int image_height,
+ const T &k1,
+ const T &k2,
+ const T &image_x,
+ const T &image_y,
+ T *normalized_x,
+ T *normalized_y) {
+ // According to the documentation:
+ //
+ // xu = xd / (1 + k0 * rd^2 + k1 * rd^4)
+ // yu = yd / (1 + k0 * rd^2 + k1 * rd^4)
+ //
+ // Legend:
+ // (xd, yd) are the distorted cartesian coordinates,
+ // (rd, phid) are the distorted polar coordinates,
+ // (xu, yu) are the undistorted cartesian coordinates,
+ // (ru, phiu) are the undistorted polar coordinates,
+ // the k-values are the distortion coefficients.
+ //
+ // The coordinate systems are relative to the distortion centre.
+
+ const int max_image_size = std::max(image_width, image_height);
+ const double max_half_image_size = max_image_size * 0.5;
+
+ if (max_half_image_size == 0.0) {
+ *normalized_x = image_x * max_half_image_size / focal_length_x;
+ *normalized_y = image_y * max_half_image_size / focal_length_y;
+ return;
+ }
+
+ const T xd = (image_x - principal_point_x) / max_half_image_size;
+ const T yd = (image_y - principal_point_y) / max_half_image_size;
+
+ T rd2 = xd*xd + yd*yd;
+ T rd4 = rd2 * rd2;
+ T r_coeff = T(1) / (T(1) + k1*rd2 + k2*rd4);
+ T xu = xd * r_coeff;
+ T yu = yd * r_coeff;
+
+ *normalized_x = xu * max_half_image_size / focal_length_x;
+ *normalized_y = yu * max_half_image_size / focal_length_y;
+}
+
+// Apply camera intrinsics to the normalized point to get image coordinates.
+// This applies the radial lens distortion to a point which is in normalized
+// camera coordinates (i.e. the principal point is at (0, 0)) to get image
+// coordinates in pixels. Templated for use with autodifferentiation.
+//
+// Uses Nuke distortion model.
+void ApplyNukeDistortionModel(const double focal_length_x,
+ const double focal_length_y,
+ const double principal_point_x,
+ const double principal_point_y,
+ const int image_width,
+ const int image_height,
+ const double k1,
+ const double k2,
+ const double normalized_x,
+ const double normalized_y,
+ double *image_x,
+ double *image_y);
+
} // namespace libmv
#endif // LIBMV_SIMPLE_PIPELINE_DISTORTION_MODELS_H_
diff --git a/intern/mantaflow/intern/MANTA_main.cpp b/intern/mantaflow/intern/MANTA_main.cpp
index d6c1d05e0da..58d49622597 100644
--- a/intern/mantaflow/intern/MANTA_main.cpp
+++ b/intern/mantaflow/intern/MANTA_main.cpp
@@ -48,7 +48,16 @@
#include "MEM_guardedalloc.h"
-std::atomic<int> MANTA::solverID(0);
+using std::cerr;
+using std::cout;
+using std::endl;
+using std::ifstream;
+using std::istringstream;
+using std::ofstream;
+using std::ostringstream;
+using std::to_string;
+
+atomic<int> MANTA::solverID(0);
int MANTA::with_debug(0);
/* Number of particles that the cache reads at once (with zlib). */
@@ -61,29 +70,30 @@ int MANTA::with_debug(0);
MANTA::MANTA(int *res, FluidModifierData *mmd) : mCurrentID(++solverID)
{
if (with_debug)
- std::cout << "FLUID: " << mCurrentID << " with res(" << res[0] << ", " << res[1] << ", "
- << res[2] << ")" << std::endl;
-
- mmd->domain->fluid = this;
-
- mUsingLiquid = (mmd->domain->type == FLUID_DOMAIN_TYPE_LIQUID);
- mUsingSmoke = (mmd->domain->type == FLUID_DOMAIN_TYPE_GAS);
- mUsingNoise = (mmd->domain->flags & FLUID_DOMAIN_USE_NOISE) && mUsingSmoke;
- mUsingFractions = (mmd->domain->flags & FLUID_DOMAIN_USE_FRACTIONS) && mUsingLiquid;
- mUsingMesh = (mmd->domain->flags & FLUID_DOMAIN_USE_MESH) && mUsingLiquid;
- mUsingMVel = (mmd->domain->flags & FLUID_DOMAIN_USE_SPEED_VECTORS) && mUsingLiquid;
- mUsingGuiding = (mmd->domain->flags & FLUID_DOMAIN_USE_GUIDE);
- mUsingDrops = (mmd->domain->particle_type & FLUID_DOMAIN_PARTICLE_SPRAY) && mUsingLiquid;
- mUsingBubbles = (mmd->domain->particle_type & FLUID_DOMAIN_PARTICLE_BUBBLE) && mUsingLiquid;
- mUsingFloats = (mmd->domain->particle_type & FLUID_DOMAIN_PARTICLE_FOAM) && mUsingLiquid;
- mUsingTracers = (mmd->domain->particle_type & FLUID_DOMAIN_PARTICLE_TRACER) && mUsingLiquid;
-
- mUsingHeat = (mmd->domain->active_fields & FLUID_DOMAIN_ACTIVE_HEAT) && mUsingSmoke;
- mUsingFire = (mmd->domain->active_fields & FLUID_DOMAIN_ACTIVE_FIRE) && mUsingSmoke;
- mUsingColors = (mmd->domain->active_fields & FLUID_DOMAIN_ACTIVE_COLORS) && mUsingSmoke;
- mUsingObstacle = (mmd->domain->active_fields & FLUID_DOMAIN_ACTIVE_OBSTACLE);
- mUsingInvel = (mmd->domain->active_fields & FLUID_DOMAIN_ACTIVE_INVEL);
- mUsingOutflow = (mmd->domain->active_fields & FLUID_DOMAIN_ACTIVE_OUTFLOW);
+ cout << "FLUID: " << mCurrentID << " with res(" << res[0] << ", " << res[1] << ", " << res[2]
+ << ")" << endl;
+
+ FluidDomainSettings *mds = mmd->domain;
+ mds->fluid = this;
+
+ mUsingLiquid = (mds->type == FLUID_DOMAIN_TYPE_LIQUID);
+ mUsingSmoke = (mds->type == FLUID_DOMAIN_TYPE_GAS);
+ mUsingNoise = (mds->flags & FLUID_DOMAIN_USE_NOISE) && mUsingSmoke;
+ mUsingFractions = (mds->flags & FLUID_DOMAIN_USE_FRACTIONS) && mUsingLiquid;
+ mUsingMesh = (mds->flags & FLUID_DOMAIN_USE_MESH) && mUsingLiquid;
+ mUsingMVel = (mds->flags & FLUID_DOMAIN_USE_SPEED_VECTORS) && mUsingLiquid;
+ mUsingGuiding = (mds->flags & FLUID_DOMAIN_USE_GUIDE);
+ mUsingDrops = (mds->particle_type & FLUID_DOMAIN_PARTICLE_SPRAY) && mUsingLiquid;
+ mUsingBubbles = (mds->particle_type & FLUID_DOMAIN_PARTICLE_BUBBLE) && mUsingLiquid;
+ mUsingFloats = (mds->particle_type & FLUID_DOMAIN_PARTICLE_FOAM) && mUsingLiquid;
+ mUsingTracers = (mds->particle_type & FLUID_DOMAIN_PARTICLE_TRACER) && mUsingLiquid;
+
+ mUsingHeat = (mds->active_fields & FLUID_DOMAIN_ACTIVE_HEAT) && mUsingSmoke;
+ mUsingFire = (mds->active_fields & FLUID_DOMAIN_ACTIVE_FIRE) && mUsingSmoke;
+ mUsingColors = (mds->active_fields & FLUID_DOMAIN_ACTIVE_COLORS) && mUsingSmoke;
+ mUsingObstacle = (mds->active_fields & FLUID_DOMAIN_ACTIVE_OBSTACLE);
+ mUsingInvel = (mds->active_fields & FLUID_DOMAIN_ACTIVE_INVEL);
+ mUsingOutflow = (mds->active_fields & FLUID_DOMAIN_ACTIVE_OUTFLOW);
// Simulation constants
mTempAmb = 0; // TODO: Maybe use this later for buoyancy calculation
@@ -91,10 +101,8 @@ MANTA::MANTA(int *res, FluidModifierData *mmd) : mCurrentID(++solverID)
mResY = res[1];
mResZ = res[2];
mMaxRes = MAX3(mResX, mResY, mResZ);
- mConstantScaling = 64.0f / mMaxRes;
- mConstantScaling = (mConstantScaling < 1.0f) ? 1.0f : mConstantScaling;
mTotalCells = mResX * mResY * mResZ;
- mResGuiding = mmd->domain->res;
+ mResGuiding = mds->res;
// Smoke low res grids
mDensity = nullptr;
@@ -184,86 +192,89 @@ MANTA::MANTA(int *res, FluidModifierData *mmd) : mCurrentID(++solverID)
// Setup Mantaflow in Python
initializeMantaflow();
+ // Initializa RNA map with values that Python will need
+ initializeRNAMap(mmd);
+
// Initialize Mantaflow variables in Python
// Liquid
if (mUsingLiquid) {
- initDomain(mmd);
- initLiquid(mmd);
+ initDomain();
+ initLiquid();
if (mUsingObstacle)
- initObstacle(mmd);
+ initObstacle();
if (mUsingInvel)
- initInVelocity(mmd);
+ initInVelocity();
if (mUsingOutflow)
- initOutflow(mmd);
+ initOutflow();
if (mUsingDrops || mUsingBubbles || mUsingFloats || mUsingTracers) {
- mUpresParticle = mmd->domain->particle_scale;
+ mUpresParticle = mds->particle_scale;
mResXParticle = mUpresParticle * mResX;
mResYParticle = mUpresParticle * mResY;
mResZParticle = mUpresParticle * mResZ;
mTotalCellsParticles = mResXParticle * mResYParticle * mResZParticle;
- initSndParts(mmd);
- initLiquidSndParts(mmd);
+ initSndParts();
+ initLiquidSndParts();
}
if (mUsingMesh) {
- mUpresMesh = mmd->domain->mesh_scale;
+ mUpresMesh = mds->mesh_scale;
mResXMesh = mUpresMesh * mResX;
mResYMesh = mUpresMesh * mResY;
mResZMesh = mUpresMesh * mResZ;
mTotalCellsMesh = mResXMesh * mResYMesh * mResZMesh;
// Initialize Mantaflow variables in Python
- initMesh(mmd);
- initLiquidMesh(mmd);
+ initMesh();
+ initLiquidMesh();
}
if (mUsingGuiding) {
- mResGuiding = (mmd->domain->guide_parent) ? mmd->domain->guide_res : mmd->domain->res;
- initGuiding(mmd);
+ mResGuiding = (mds->guide_parent) ? mds->guide_res : mds->res;
+ initGuiding();
}
if (mUsingFractions) {
- initFractions(mmd);
+ initFractions();
}
}
// Smoke
if (mUsingSmoke) {
- initDomain(mmd);
- initSmoke(mmd);
+ initDomain();
+ initSmoke();
if (mUsingHeat)
- initHeat(mmd);
+ initHeat();
if (mUsingFire)
- initFire(mmd);
+ initFire();
if (mUsingColors)
- initColors(mmd);
+ initColors();
if (mUsingObstacle)
- initObstacle(mmd);
+ initObstacle();
if (mUsingInvel)
- initInVelocity(mmd);
+ initInVelocity();
if (mUsingOutflow)
- initOutflow(mmd);
+ initOutflow();
if (mUsingGuiding) {
- mResGuiding = (mmd->domain->guide_parent) ? mmd->domain->guide_res : mmd->domain->res;
- initGuiding(mmd);
+ mResGuiding = (mds->guide_parent) ? mds->guide_res : mds->res;
+ initGuiding();
}
if (mUsingNoise) {
- int amplify = mmd->domain->noise_scale;
+ int amplify = mds->noise_scale;
mResXNoise = amplify * mResX;
mResYNoise = amplify * mResY;
mResZNoise = amplify * mResZ;
mTotalCellsHigh = mResXNoise * mResYNoise * mResZNoise;
// Initialize Mantaflow variables in Python
- initNoise(mmd);
- initSmokeNoise(mmd);
+ initNoise();
+ initSmokeNoise();
if (mUsingFire)
- initFireHigh(mmd);
+ initFireHigh();
if (mUsingColors)
- initColorsHigh(mmd);
+ initColorsHigh();
}
}
updatePointers();
@@ -272,32 +283,32 @@ MANTA::MANTA(int *res, FluidModifierData *mmd) : mCurrentID(++solverID)
void MANTA::initDomain(FluidModifierData *mmd)
{
// Vector will hold all python commands that are to be executed
- std::vector<std::string> pythonCommands;
+ vector<string> pythonCommands;
// Set manta debug level first
pythonCommands.push_back(manta_import + manta_debuglevel);
- std::ostringstream ss;
+ ostringstream ss;
ss << "set_manta_debuglevel(" << with_debug << ")";
pythonCommands.push_back(ss.str());
// Now init basic fluid domain
- std::string tmpString = fluid_variables + fluid_solver + fluid_alloc + fluid_cache_helper +
- fluid_bake_multiprocessing + fluid_bake_data + fluid_bake_noise +
- fluid_bake_mesh + fluid_bake_particles + fluid_bake_guiding +
- fluid_file_import + fluid_file_export + fluid_save_data +
- fluid_load_data + fluid_pre_step + fluid_post_step +
- fluid_adapt_time_step + fluid_time_stepping;
- std::string finalString = parseScript(tmpString, mmd);
+ string tmpString = fluid_variables + fluid_solver + fluid_alloc + fluid_cache_helper +
+ fluid_bake_multiprocessing + fluid_bake_data + fluid_bake_noise +
+ fluid_bake_mesh + fluid_bake_particles + fluid_bake_guiding +
+ fluid_file_import + fluid_file_export + fluid_save_data + fluid_load_data +
+ fluid_pre_step + fluid_post_step + fluid_adapt_time_step +
+ fluid_time_stepping;
+ string finalString = parseScript(tmpString, mmd);
pythonCommands.push_back(finalString);
runPythonString(pythonCommands);
}
void MANTA::initNoise(FluidModifierData *mmd)
{
- std::vector<std::string> pythonCommands;
- std::string tmpString = fluid_variables_noise + fluid_solver_noise;
- std::string finalString = parseScript(tmpString, mmd);
+ vector<string> pythonCommands;
+ string tmpString = fluid_variables_noise + fluid_solver_noise;
+ string finalString = parseScript(tmpString, mmd);
pythonCommands.push_back(finalString);
runPythonString(pythonCommands);
@@ -305,10 +316,10 @@ void MANTA::initNoise(FluidModifierData *mmd)
void MANTA::initSmoke(FluidModifierData *mmd)
{
- std::vector<std::string> pythonCommands;
- std::string tmpString = smoke_variables + smoke_alloc + smoke_adaptive_step + smoke_save_data +
- smoke_load_data + smoke_step;
- std::string finalString = parseScript(tmpString, mmd);
+ vector<string> pythonCommands;
+ string tmpString = smoke_variables + smoke_alloc + smoke_adaptive_step + smoke_save_data +
+ smoke_load_data + smoke_step;
+ string finalString = parseScript(tmpString, mmd);
pythonCommands.push_back(finalString);
runPythonString(pythonCommands);
@@ -316,10 +327,10 @@ void MANTA::initSmoke(FluidModifierData *mmd)
void MANTA::initSmokeNoise(FluidModifierData *mmd)
{
- std::vector<std::string> pythonCommands;
- std::string tmpString = smoke_variables_noise + smoke_alloc_noise + smoke_wavelet_noise +
- smoke_save_noise + smoke_load_noise + smoke_step_noise;
- std::string finalString = parseScript(tmpString, mmd);
+ vector<string> pythonCommands;
+ string tmpString = smoke_variables_noise + smoke_alloc_noise + smoke_wavelet_noise +
+ smoke_save_noise + smoke_load_noise + smoke_step_noise;
+ string finalString = parseScript(tmpString, mmd);
pythonCommands.push_back(finalString);
runPythonString(pythonCommands);
@@ -329,9 +340,9 @@ void MANTA::initSmokeNoise(FluidModifierData *mmd)
void MANTA::initHeat(FluidModifierData *mmd)
{
if (!mHeat) {
- std::vector<std::string> pythonCommands;
- std::string tmpString = smoke_alloc_heat + smoke_with_heat;
- std::string finalString = parseScript(tmpString, mmd);
+ vector<string> pythonCommands;
+ string tmpString = smoke_alloc_heat + smoke_with_heat;
+ string finalString = parseScript(tmpString, mmd);
pythonCommands.push_back(finalString);
runPythonString(pythonCommands);
@@ -342,9 +353,9 @@ void MANTA::initHeat(FluidModifierData *mmd)
void MANTA::initFire(FluidModifierData *mmd)
{
if (!mFuel) {
- std::vector<std::string> pythonCommands;
- std::string tmpString = smoke_alloc_fire + smoke_with_fire;
- std::string finalString = parseScript(tmpString, mmd);
+ vector<string> pythonCommands;
+ string tmpString = smoke_alloc_fire + smoke_with_fire;
+ string finalString = parseScript(tmpString, mmd);
pythonCommands.push_back(finalString);
runPythonString(pythonCommands);
@@ -355,9 +366,9 @@ void MANTA::initFire(FluidModifierData *mmd)
void MANTA::initFireHigh(FluidModifierData *mmd)
{
if (!mFuelHigh) {
- std::vector<std::string> pythonCommands;
- std::string tmpString = smoke_alloc_fire_noise + smoke_with_fire;
- std::string finalString = parseScript(tmpString, mmd);
+ vector<string> pythonCommands;
+ string tmpString = smoke_alloc_fire_noise + smoke_with_fire;
+ string finalString = parseScript(tmpString, mmd);
pythonCommands.push_back(finalString);
runPythonString(pythonCommands);
@@ -368,9 +379,9 @@ void MANTA::initFireHigh(FluidModifierData *mmd)
void MANTA::initColors(FluidModifierData *mmd)
{
if (!mColorR) {
- std::vector<std::string> pythonCommands;
- std::string tmpString = smoke_alloc_colors + smoke_init_colors + smoke_with_colors;
- std::string finalString = parseScript(tmpString, mmd);
+ vector<string> pythonCommands;
+ string tmpString = smoke_alloc_colors + smoke_init_colors + smoke_with_colors;
+ string finalString = parseScript(tmpString, mmd);
pythonCommands.push_back(finalString);
runPythonString(pythonCommands);
@@ -381,9 +392,9 @@ void MANTA::initColors(FluidModifierData *mmd)
void MANTA::initColorsHigh(FluidModifierData *mmd)
{
if (!mColorRHigh) {
- std::vector<std::string> pythonCommands;
- std::string tmpString = smoke_alloc_colors_noise + smoke_init_colors_noise + smoke_with_colors;
- std::string finalString = parseScript(tmpString, mmd);
+ vector<string> pythonCommands;
+ string tmpString = smoke_alloc_colors_noise + smoke_init_colors_noise + smoke_with_colors;
+ string finalString = parseScript(tmpString, mmd);
pythonCommands.push_back(finalString);
runPythonString(pythonCommands);
@@ -394,10 +405,10 @@ void MANTA::initColorsHigh(FluidModifierData *mmd)
void MANTA::initLiquid(FluidModifierData *mmd)
{
if (!mPhiIn) {
- std::vector<std::string> pythonCommands;
- std::string tmpString = liquid_variables + liquid_alloc + liquid_init_phi + liquid_save_data +
- liquid_load_data + liquid_adaptive_step + liquid_step;
- std::string finalString = parseScript(tmpString, mmd);
+ vector<string> pythonCommands;
+ string tmpString = liquid_variables + liquid_alloc + liquid_init_phi + liquid_save_data +
+ liquid_load_data + liquid_adaptive_step + liquid_step;
+ string finalString = parseScript(tmpString, mmd);
pythonCommands.push_back(finalString);
runPythonString(pythonCommands);
@@ -407,9 +418,9 @@ void MANTA::initLiquid(FluidModifierData *mmd)
void MANTA::initMesh(FluidModifierData *mmd)
{
- std::vector<std::string> pythonCommands;
- std::string tmpString = fluid_variables_mesh + fluid_solver_mesh + liquid_load_mesh;
- std::string finalString = parseScript(tmpString, mmd);
+ vector<string> pythonCommands;
+ string tmpString = fluid_variables_mesh + fluid_solver_mesh + liquid_load_mesh;
+ string finalString = parseScript(tmpString, mmd);
pythonCommands.push_back(finalString);
runPythonString(pythonCommands);
@@ -418,9 +429,9 @@ void MANTA::initMesh(FluidModifierData *mmd)
void MANTA::initLiquidMesh(FluidModifierData *mmd)
{
- std::vector<std::string> pythonCommands;
- std::string tmpString = liquid_alloc_mesh + liquid_step_mesh + liquid_save_mesh;
- std::string finalString = parseScript(tmpString, mmd);
+ vector<string> pythonCommands;
+ string tmpString = liquid_alloc_mesh + liquid_step_mesh + liquid_save_mesh;
+ string finalString = parseScript(tmpString, mmd);
pythonCommands.push_back(finalString);
runPythonString(pythonCommands);
@@ -430,9 +441,9 @@ void MANTA::initLiquidMesh(FluidModifierData *mmd)
void MANTA::initObstacle(FluidModifierData *mmd)
{
if (!mPhiObsIn) {
- std::vector<std::string> pythonCommands;
- std::string tmpString = fluid_alloc_obstacle + fluid_with_obstacle;
- std::string finalString = parseScript(tmpString, mmd);
+ vector<string> pythonCommands;
+ string tmpString = fluid_alloc_obstacle + fluid_with_obstacle;
+ string finalString = parseScript(tmpString, mmd);
pythonCommands.push_back(finalString);
runPythonString(pythonCommands);
@@ -443,10 +454,10 @@ void MANTA::initObstacle(FluidModifierData *mmd)
void MANTA::initGuiding(FluidModifierData *mmd)
{
if (!mPhiGuideIn) {
- std::vector<std::string> pythonCommands;
- std::string tmpString = fluid_variables_guiding + fluid_solver_guiding + fluid_alloc_guiding +
- fluid_save_guiding + fluid_load_vel + fluid_load_guiding;
- std::string finalString = parseScript(tmpString, mmd);
+ vector<string> pythonCommands;
+ string tmpString = fluid_variables_guiding + fluid_solver_guiding + fluid_alloc_guiding +
+ fluid_save_guiding + fluid_load_vel + fluid_load_guiding;
+ string finalString = parseScript(tmpString, mmd);
pythonCommands.push_back(finalString);
runPythonString(pythonCommands);
@@ -456,9 +467,9 @@ void MANTA::initGuiding(FluidModifierData *mmd)
void MANTA::initFractions(FluidModifierData *mmd)
{
- std::vector<std::string> pythonCommands;
- std::string tmpString = fluid_alloc_fractions + fluid_with_fractions;
- std::string finalString = parseScript(tmpString, mmd);
+ vector<string> pythonCommands;
+ string tmpString = fluid_alloc_fractions + fluid_with_fractions;
+ string finalString = parseScript(tmpString, mmd);
pythonCommands.push_back(finalString);
runPythonString(pythonCommands);
@@ -468,9 +479,9 @@ void MANTA::initFractions(FluidModifierData *mmd)
void MANTA::initInVelocity(FluidModifierData *mmd)
{
if (!mInVelocityX) {
- std::vector<std::string> pythonCommands;
- std::string tmpString = fluid_alloc_invel + fluid_with_invel;
- std::string finalString = parseScript(tmpString, mmd);
+ vector<string> pythonCommands;
+ string tmpString = fluid_alloc_invel + fluid_with_invel;
+ string finalString = parseScript(tmpString, mmd);
pythonCommands.push_back(finalString);
runPythonString(pythonCommands);
@@ -481,9 +492,9 @@ void MANTA::initInVelocity(FluidModifierData *mmd)
void MANTA::initOutflow(FluidModifierData *mmd)
{
if (!mPhiOutIn) {
- std::vector<std::string> pythonCommands;
- std::string tmpString = fluid_alloc_outflow + fluid_with_outflow;
- std::string finalString = parseScript(tmpString, mmd);
+ vector<string> pythonCommands;
+ string tmpString = fluid_alloc_outflow + fluid_with_outflow;
+ string finalString = parseScript(tmpString, mmd);
pythonCommands.push_back(finalString);
runPythonString(pythonCommands);
@@ -493,9 +504,9 @@ void MANTA::initOutflow(FluidModifierData *mmd)
void MANTA::initSndParts(FluidModifierData *mmd)
{
- std::vector<std::string> pythonCommands;
- std::string tmpString = fluid_variables_particles + fluid_solver_particles;
- std::string finalString = parseScript(tmpString, mmd);
+ vector<string> pythonCommands;
+ string tmpString = fluid_variables_particles + fluid_solver_particles;
+ string finalString = parseScript(tmpString, mmd);
pythonCommands.push_back(finalString);
runPythonString(pythonCommands);
@@ -504,11 +515,11 @@ void MANTA::initSndParts(FluidModifierData *mmd)
void MANTA::initLiquidSndParts(FluidModifierData *mmd)
{
if (!mSndParticleData) {
- std::vector<std::string> pythonCommands;
- std::string tmpString = liquid_alloc_particles + liquid_variables_particles +
- liquid_step_particles + fluid_with_sndparts + liquid_load_particles +
- liquid_save_particles;
- std::string finalString = parseScript(tmpString, mmd);
+ vector<string> pythonCommands;
+ string tmpString = liquid_alloc_particles + liquid_variables_particles +
+ liquid_step_particles + fluid_with_sndparts + liquid_load_particles +
+ liquid_save_particles;
+ string finalString = parseScript(tmpString, mmd);
pythonCommands.push_back(finalString);
runPythonString(pythonCommands);
@@ -518,19 +529,22 @@ void MANTA::initLiquidSndParts(FluidModifierData *mmd)
MANTA::~MANTA()
{
if (with_debug)
- std::cout << "~FLUID: " << mCurrentID << " with res(" << mResX << ", " << mResY << ", "
- << mResZ << ")" << std::endl;
+ cout << "~FLUID: " << mCurrentID << " with res(" << mResX << ", " << mResY << ", " << mResZ
+ << ")" << endl;
// Destruction string for Python
- std::string tmpString = "";
- std::vector<std::string> pythonCommands;
+ string tmpString = "";
+ vector<string> pythonCommands;
bool result = false;
tmpString += manta_import;
tmpString += fluid_delete_all;
+ // Initializa RNA map with values that Python will need
+ initializeRNAMap();
+
// Leave out mmd argument in parseScript since only looking up IDs
- std::string finalString = parseScript(tmpString);
+ string finalString = parseScript(tmpString);
pythonCommands.push_back(finalString);
result = runPythonString(pythonCommands);
@@ -538,12 +552,12 @@ MANTA::~MANTA()
(void)result; // not needed in release
}
-bool MANTA::runPythonString(std::vector<std::string> commands)
+bool MANTA::runPythonString(vector<string> commands)
{
int success = -1;
PyGILState_STATE gilstate = PyGILState_Ensure();
- for (std::vector<std::string>::iterator it = commands.begin(); it != commands.end(); ++it) {
- std::string command = *it;
+ for (vector<string>::iterator it = commands.begin(); it != commands.end(); ++it) {
+ string command = *it;
#ifdef WIN32
// special treatment for windows when running python code
@@ -568,10 +582,10 @@ bool MANTA::runPythonString(std::vector<std::string> commands)
void MANTA::initializeMantaflow()
{
if (with_debug)
- std::cout << "Fluid: Initializing Mantaflow framework" << std::endl;
+ cout << "Fluid: Initializing Mantaflow framework" << endl;
- std::string filename = "manta_scene_" + std::to_string(mCurrentID) + ".py";
- std::vector<std::string> fill = std::vector<std::string>();
+ string filename = "manta_scene_" + to_string(mCurrentID) + ".py";
+ vector<string> fill = vector<string>();
// Initialize extension classes and wrappers
srand(0);
@@ -583,17 +597,17 @@ void MANTA::initializeMantaflow()
void MANTA::terminateMantaflow()
{
if (with_debug)
- std::cout << "Fluid: Releasing Mantaflow framework" << std::endl;
+ cout << "Fluid: Releasing Mantaflow framework" << endl;
PyGILState_STATE gilstate = PyGILState_Ensure();
Pb::finalize(); // Namespace from Mantaflow (registry)
PyGILState_Release(gilstate);
}
-static std::string getCacheFileEnding(char cache_format)
+static string getCacheFileEnding(char cache_format)
{
if (MANTA::with_debug)
- std::cout << "MANTA::getCacheFileEnding()" << std::endl;
+ cout << "MANTA::getCacheFileEnding()" << endl;
switch (cache_format) {
case FLUID_DOMAIN_FILE_UNI:
@@ -607,409 +621,237 @@ static std::string getCacheFileEnding(char cache_format)
case FLUID_DOMAIN_FILE_OBJECT:
return FLUID_DOMAIN_EXTENSION_OBJ;
default:
- std::cerr << "Fluid Error -- Could not find file extension. Using default file extension."
- << std::endl;
+ cerr << "Fluid Error -- Could not find file extension. Using default file extension."
+ << endl;
return FLUID_DOMAIN_EXTENSION_UNI;
}
}
-std::string MANTA::getRealValue(const std::string &varName, FluidModifierData *mmd)
+static string getBooleanString(int value)
{
- std::ostringstream ss;
- bool is2D = false;
- int tmpVar;
- float tmpFloat;
+ return (value) ? "True" : "False";
+}
- if (varName == "ID") {
- ss << mCurrentID;
- return ss.str();
- }
+void MANTA::initializeRNAMap(FluidModifierData *mmd)
+{
+ if (with_debug)
+ cout << "MANTA::initializeRNAMap()" << endl;
+
+ mRNAMap["ID"] = to_string(mCurrentID);
if (!mmd) {
- std::cerr << "Fluid Error -- Invalid modifier data." << std::endl;
- ss << "ERROR - INVALID MODIFIER DATA";
- return ss.str();
- }
-
- is2D = (mmd->domain->solver_res == 2);
-
- if (varName == "USING_SMOKE")
- ss << ((mmd->domain->type == FLUID_DOMAIN_TYPE_GAS) ? "True" : "False");
- else if (varName == "USING_LIQUID")
- ss << ((mmd->domain->type == FLUID_DOMAIN_TYPE_LIQUID) ? "True" : "False");
- else if (varName == "USING_COLORS")
- ss << (mmd->domain->active_fields & FLUID_DOMAIN_ACTIVE_COLORS ? "True" : "False");
- else if (varName == "USING_HEAT")
- ss << (mmd->domain->active_fields & FLUID_DOMAIN_ACTIVE_HEAT ? "True" : "False");
- else if (varName == "USING_FIRE")
- ss << (mmd->domain->active_fields & FLUID_DOMAIN_ACTIVE_FIRE ? "True" : "False");
- else if (varName == "USING_NOISE")
- ss << (mmd->domain->flags & FLUID_DOMAIN_USE_NOISE ? "True" : "False");
- else if (varName == "USING_OBSTACLE")
- ss << (mmd->domain->active_fields & FLUID_DOMAIN_ACTIVE_OBSTACLE ? "True" : "False");
- else if (varName == "USING_GUIDING")
- ss << (mmd->domain->flags & FLUID_DOMAIN_USE_GUIDE ? "True" : "False");
- else if (varName == "USING_INVEL")
- ss << (mmd->domain->active_fields & FLUID_DOMAIN_ACTIVE_INVEL ? "True" : "False");
- else if (varName == "USING_OUTFLOW")
- ss << (mmd->domain->active_fields & FLUID_DOMAIN_ACTIVE_OUTFLOW ? "True" : "False");
- else if (varName == "USING_LOG_DISSOLVE")
- ss << (mmd->domain->flags & FLUID_DOMAIN_USE_DISSOLVE_LOG ? "True" : "False");
- else if (varName == "USING_DISSOLVE")
- ss << (mmd->domain->flags & FLUID_DOMAIN_USE_DISSOLVE ? "True" : "False");
- else if (varName == "SOLVER_DIM")
- ss << mmd->domain->solver_res;
- else if (varName == "DO_OPEN") {
- tmpVar = (FLUID_DOMAIN_BORDER_BACK | FLUID_DOMAIN_BORDER_FRONT | FLUID_DOMAIN_BORDER_LEFT |
- FLUID_DOMAIN_BORDER_RIGHT | FLUID_DOMAIN_BORDER_BOTTOM | FLUID_DOMAIN_BORDER_TOP);
- ss << (((mmd->domain->border_collisions & tmpVar) == tmpVar) ? "False" : "True");
- }
- else if (varName == "BOUND_CONDITIONS") {
- if (mmd->domain->solver_res == 2) {
- if ((mmd->domain->border_collisions & FLUID_DOMAIN_BORDER_LEFT) == 0)
- ss << "x";
- if ((mmd->domain->border_collisions & FLUID_DOMAIN_BORDER_RIGHT) == 0)
- ss << "X";
- if ((mmd->domain->border_collisions & FLUID_DOMAIN_BORDER_FRONT) == 0)
- ss << "y";
- if ((mmd->domain->border_collisions & FLUID_DOMAIN_BORDER_BACK) == 0)
- ss << "Y";
- }
- if (mmd->domain->solver_res == 3) {
- if ((mmd->domain->border_collisions & FLUID_DOMAIN_BORDER_LEFT) == 0)
- ss << "x";
- if ((mmd->domain->border_collisions & FLUID_DOMAIN_BORDER_RIGHT) == 0)
- ss << "X";
- if ((mmd->domain->border_collisions & FLUID_DOMAIN_BORDER_FRONT) == 0)
- ss << "y";
- if ((mmd->domain->border_collisions & FLUID_DOMAIN_BORDER_BACK) == 0)
- ss << "Y";
- if ((mmd->domain->border_collisions & FLUID_DOMAIN_BORDER_BOTTOM) == 0)
- ss << "z";
- if ((mmd->domain->border_collisions & FLUID_DOMAIN_BORDER_TOP) == 0)
- ss << "Z";
- }
- }
- else if (varName == "BOUNDARY_WIDTH")
- ss << mmd->domain->boundary_width;
- else if (varName == "RES")
- ss << mMaxRes;
- else if (varName == "RESX")
- ss << mResX;
- else if (varName == "RESY")
- if (is2D) {
- ss << mResZ;
- }
- else {
- ss << mResY;
- }
- else if (varName == "RESZ") {
- if (is2D) {
- ss << 1;
- }
- else {
- ss << mResZ;
- }
- }
- else if (varName == "FRAME_LENGTH")
- ss << mmd->domain->frame_length;
- else if (varName == "CFL")
- ss << mmd->domain->cfl_condition;
- else if (varName == "DT")
- ss << mmd->domain->dt;
- else if (varName == "TIMESTEPS_MIN")
- ss << mmd->domain->timesteps_minimum;
- else if (varName == "TIMESTEPS_MAX")
- ss << mmd->domain->timesteps_maximum;
- else if (varName == "TIME_TOTAL")
- ss << mmd->domain->time_total;
- else if (varName == "TIME_PER_FRAME")
- ss << mmd->domain->time_per_frame;
- else if (varName == "VORTICITY")
- ss << mmd->domain->vorticity / mConstantScaling;
- else if (varName == "FLAME_VORTICITY")
- ss << mmd->domain->flame_vorticity / mConstantScaling;
- else if (varName == "NOISE_SCALE")
- ss << mmd->domain->noise_scale;
- else if (varName == "MESH_SCALE")
- ss << mmd->domain->mesh_scale;
- else if (varName == "PARTICLE_SCALE")
- ss << mmd->domain->particle_scale;
- else if (varName == "NOISE_RESX")
- ss << mResXNoise;
- else if (varName == "NOISE_RESY") {
- if (is2D) {
- ss << mResZNoise;
- }
- else {
- ss << mResYNoise;
- }
- }
- else if (varName == "NOISE_RESZ") {
- if (is2D) {
- ss << 1;
- }
- else {
- ss << mResZNoise;
- }
- }
- else if (varName == "MESH_RESX")
- ss << mResXMesh;
- else if (varName == "MESH_RESY") {
- if (is2D) {
- ss << mResZMesh;
- }
- else {
- ss << mResYMesh;
- }
- }
- else if (varName == "MESH_RESZ") {
- if (is2D) {
- ss << 1;
- }
- else {
- ss << mResZMesh;
- }
- }
- else if (varName == "PARTICLE_RESX")
- ss << mResXParticle;
- else if (varName == "PARTICLE_RESY") {
- if (is2D) {
- ss << mResZParticle;
- }
- else {
- ss << mResYParticle;
- }
- }
- else if (varName == "PARTICLE_RESZ") {
- if (is2D) {
- ss << 1;
- }
- else {
- ss << mResZParticle;
- }
- }
- else if (varName == "GUIDING_RESX")
- ss << mResGuiding[0];
- else if (varName == "GUIDING_RESY") {
- if (is2D) {
- ss << mResGuiding[2];
- }
- else {
- ss << mResGuiding[1];
- }
+ if (with_debug)
+ cout << "No modifier data given in RNA map setup - returning early" << endl;
+ return;
}
- else if (varName == "GUIDING_RESZ") {
- if (is2D) {
- ss << 1;
- }
- else {
- ss << mResGuiding[2];
- }
+
+ FluidDomainSettings *mds = mmd->domain;
+ bool is2D = (mds->solver_res == 2);
+
+ string borderCollisions = "";
+ if ((mds->border_collisions & FLUID_DOMAIN_BORDER_LEFT) == 0)
+ borderCollisions += "x";
+ if ((mds->border_collisions & FLUID_DOMAIN_BORDER_RIGHT) == 0)
+ borderCollisions += "X";
+ if ((mds->border_collisions & FLUID_DOMAIN_BORDER_FRONT) == 0)
+ borderCollisions += "y";
+ if ((mds->border_collisions & FLUID_DOMAIN_BORDER_BACK) == 0)
+ borderCollisions += "Y";
+ if ((mds->border_collisions & FLUID_DOMAIN_BORDER_BOTTOM) == 0)
+ borderCollisions += "z";
+ if ((mds->border_collisions & FLUID_DOMAIN_BORDER_TOP) == 0)
+ borderCollisions += "Z";
+
+ string simulationMethod = "";
+ if (mds->simulation_method & FLUID_DOMAIN_METHOD_FLIP)
+ simulationMethod += "'FLIP'";
+ else if (mds->simulation_method & FLUID_DOMAIN_METHOD_APIC)
+ simulationMethod += "'APIC'";
+
+ string particleTypesStr = "";
+ if (mds->particle_type & FLUID_DOMAIN_PARTICLE_SPRAY)
+ particleTypesStr += "PtypeSpray";
+ if (mds->particle_type & FLUID_DOMAIN_PARTICLE_BUBBLE) {
+ if (!particleTypesStr.empty())
+ particleTypesStr += "|";
+ particleTypesStr += "PtypeBubble";
+ }
+ if (mds->particle_type & FLUID_DOMAIN_PARTICLE_FOAM) {
+ if (!particleTypesStr.empty())
+ particleTypesStr += "|";
+ particleTypesStr += "PtypeFoam";
+ }
+ if (mds->particle_type & FLUID_DOMAIN_PARTICLE_TRACER) {
+ if (!particleTypesStr.empty())
+ particleTypesStr += "|";
+ particleTypesStr += "PtypeTracer";
+ }
+ if (particleTypesStr.empty())
+ particleTypesStr = "0";
+
+ int particleTypes = (FLUID_DOMAIN_PARTICLE_SPRAY | FLUID_DOMAIN_PARTICLE_BUBBLE |
+ FLUID_DOMAIN_PARTICLE_FOAM | FLUID_DOMAIN_PARTICLE_TRACER);
+
+ string cacheDirectory(mds->cache_directory);
+
+ float viscosity = mds->viscosity_base * pow(10.0f, -mds->viscosity_exponent);
+ float domainSize = MAX3(mds->global_size[0], mds->global_size[1], mds->global_size[2]);
+
+ mRNAMap["USING_SMOKE"] = getBooleanString(mds->type == FLUID_DOMAIN_TYPE_GAS);
+ mRNAMap["USING_LIQUID"] = getBooleanString(mds->type == FLUID_DOMAIN_TYPE_LIQUID);
+ mRNAMap["USING_COLORS"] = getBooleanString(mds->active_fields & FLUID_DOMAIN_ACTIVE_COLORS);
+ mRNAMap["USING_HEAT"] = getBooleanString(mds->active_fields & FLUID_DOMAIN_ACTIVE_HEAT);
+ mRNAMap["USING_FIRE"] = getBooleanString(mds->active_fields & FLUID_DOMAIN_ACTIVE_FIRE);
+ mRNAMap["USING_NOISE"] = getBooleanString(mds->flags & FLUID_DOMAIN_USE_NOISE);
+ mRNAMap["USING_OBSTACLE"] = getBooleanString(mds->active_fields & FLUID_DOMAIN_ACTIVE_OBSTACLE);
+ mRNAMap["USING_GUIDING"] = getBooleanString(mds->flags & FLUID_DOMAIN_USE_GUIDE);
+ mRNAMap["USING_INVEL"] = getBooleanString(mds->active_fields & FLUID_DOMAIN_ACTIVE_INVEL);
+ mRNAMap["USING_OUTFLOW"] = getBooleanString(mds->active_fields & FLUID_DOMAIN_ACTIVE_OUTFLOW);
+ mRNAMap["USING_LOG_DISSOLVE"] = getBooleanString(mds->flags & FLUID_DOMAIN_USE_DISSOLVE_LOG);
+ mRNAMap["USING_DISSOLVE"] = getBooleanString(mds->flags & FLUID_DOMAIN_USE_DISSOLVE);
+ mRNAMap["DO_OPEN"] = getBooleanString(mds->border_collisions == 0);
+ mRNAMap["CACHE_RESUMABLE"] = getBooleanString(mds->cache_type != FLUID_DOMAIN_CACHE_FINAL);
+ mRNAMap["USING_ADAPTIVETIME"] = getBooleanString(mds->flags & FLUID_DOMAIN_USE_ADAPTIVE_TIME);
+ mRNAMap["USING_SPEEDVECTORS"] = getBooleanString(mds->flags & FLUID_DOMAIN_USE_SPEED_VECTORS);
+ mRNAMap["USING_FRACTIONS"] = getBooleanString(mds->flags & FLUID_DOMAIN_USE_FRACTIONS);
+ mRNAMap["DELETE_IN_OBSTACLE"] = getBooleanString(mds->flags & FLUID_DOMAIN_DELETE_IN_OBSTACLE);
+ mRNAMap["USING_DIFFUSION"] = getBooleanString(mds->flags & FLUID_DOMAIN_USE_DIFFUSION);
+ mRNAMap["USING_MESH"] = getBooleanString(mds->flags & FLUID_DOMAIN_USE_MESH);
+ mRNAMap["USING_IMPROVED_MESH"] = getBooleanString(mds->mesh_generator ==
+ FLUID_DOMAIN_MESH_IMPROVED);
+ mRNAMap["USING_SNDPARTS"] = getBooleanString(mds->particle_type & particleTypes);
+ mRNAMap["SNDPARTICLE_BOUNDARY_DELETE"] = getBooleanString(mds->sndparticle_boundary ==
+ SNDPARTICLE_BOUNDARY_DELETE);
+ mRNAMap["SNDPARTICLE_BOUNDARY_PUSHOUT"] = getBooleanString(mds->sndparticle_boundary ==
+ SNDPARTICLE_BOUNDARY_PUSHOUT);
+
+ mRNAMap["SOLVER_DIM"] = to_string(mds->solver_res);
+ mRNAMap["BOUND_CONDITIONS"] = borderCollisions;
+ mRNAMap["BOUNDARY_WIDTH"] = to_string(mds->boundary_width);
+ mRNAMap["RES"] = to_string(mMaxRes);
+ mRNAMap["RESX"] = to_string(mResX);
+ mRNAMap["RESY"] = (is2D) ? to_string(mResZ) : to_string(mResY);
+ mRNAMap["RESZ"] = (is2D) ? to_string(1) : to_string(mResZ);
+ mRNAMap["TIME_SCALE"] = to_string(mds->time_scale);
+ mRNAMap["FRAME_LENGTH"] = to_string(mds->frame_length);
+ mRNAMap["CFL"] = to_string(mds->cfl_condition);
+ mRNAMap["DT"] = to_string(mds->dt);
+ mRNAMap["TIMESTEPS_MIN"] = to_string(mds->timesteps_minimum);
+ mRNAMap["TIMESTEPS_MAX"] = to_string(mds->timesteps_maximum);
+ mRNAMap["TIME_TOTAL"] = to_string(mds->time_total);
+ mRNAMap["TIME_PER_FRAME"] = to_string(mds->time_per_frame);
+ mRNAMap["VORTICITY"] = to_string(mds->vorticity);
+ mRNAMap["FLAME_VORTICITY"] = to_string(mds->flame_vorticity);
+ mRNAMap["NOISE_SCALE"] = to_string(mds->noise_scale);
+ mRNAMap["MESH_SCALE"] = to_string(mds->mesh_scale);
+ mRNAMap["PARTICLE_SCALE"] = to_string(mds->particle_scale);
+ mRNAMap["NOISE_RESX"] = to_string(mResXNoise);
+ mRNAMap["NOISE_RESY"] = (is2D) ? to_string(mResZNoise) : to_string(mResYNoise);
+ mRNAMap["NOISE_RESZ"] = (is2D) ? to_string(1) : to_string(mResZNoise);
+ mRNAMap["MESH_RESX"] = to_string(mResXMesh);
+ mRNAMap["MESH_RESY"] = (is2D) ? to_string(mResZMesh) : to_string(mResYMesh);
+ mRNAMap["MESH_RESZ"] = (is2D) ? to_string(1) : to_string(mResZMesh);
+ mRNAMap["PARTICLE_RESX"] = to_string(mResXParticle);
+ mRNAMap["PARTICLE_RESY"] = (is2D) ? to_string(mResZParticle) : to_string(mResYParticle);
+ mRNAMap["PARTICLE_RESZ"] = (is2D) ? to_string(1) : to_string(mResZParticle);
+ mRNAMap["GUIDING_RESX"] = to_string(mResGuiding[0]);
+ mRNAMap["GUIDING_RESY"] = (is2D) ? to_string(mResGuiding[2]) : to_string(mResGuiding[1]);
+ mRNAMap["GUIDING_RESZ"] = (is2D) ? to_string(1) : to_string(mResGuiding[2]);
+ mRNAMap["MIN_RESX"] = to_string(mds->res_min[0]);
+ mRNAMap["MIN_RESY"] = to_string(mds->res_min[1]);
+ mRNAMap["MIN_RESZ"] = to_string(mds->res_min[2]);
+ mRNAMap["BASE_RESX"] = to_string(mds->base_res[0]);
+ mRNAMap["BASE_RESY"] = to_string(mds->base_res[1]);
+ mRNAMap["BASE_RESZ"] = to_string(mds->base_res[2]);
+ mRNAMap["WLT_STR"] = to_string(mds->noise_strength);
+ mRNAMap["NOISE_POSSCALE"] = to_string(mds->noise_pos_scale);
+ mRNAMap["NOISE_TIMEANIM"] = to_string(mds->noise_time_anim);
+ mRNAMap["COLOR_R"] = to_string(mds->active_color[0]);
+ mRNAMap["COLOR_G"] = to_string(mds->active_color[1]);
+ mRNAMap["COLOR_B"] = to_string(mds->active_color[2]);
+ mRNAMap["BUOYANCY_ALPHA"] = to_string(mds->alpha);
+ mRNAMap["BUOYANCY_BETA"] = to_string(mds->beta);
+ mRNAMap["DISSOLVE_SPEED"] = to_string(mds->diss_speed);
+ mRNAMap["BURNING_RATE"] = to_string(mds->burning_rate);
+ mRNAMap["FLAME_SMOKE"] = to_string(mds->flame_smoke);
+ mRNAMap["IGNITION_TEMP"] = to_string(mds->flame_ignition);
+ mRNAMap["MAX_TEMP"] = to_string(mds->flame_max_temp);
+ mRNAMap["FLAME_SMOKE_COLOR_X"] = to_string(mds->flame_smoke_color[0]);
+ mRNAMap["FLAME_SMOKE_COLOR_Y"] = to_string(mds->flame_smoke_color[1]);
+ mRNAMap["FLAME_SMOKE_COLOR_Z"] = to_string(mds->flame_smoke_color[2]);
+ mRNAMap["CURRENT_FRAME"] = to_string(mmd->time);
+ mRNAMap["START_FRAME"] = to_string(mds->cache_frame_start);
+ mRNAMap["END_FRAME"] = to_string(mds->cache_frame_end);
+ mRNAMap["CACHE_DATA_FORMAT"] = to_string(mds->cache_data_format);
+ mRNAMap["CACHE_MESH_FORMAT"] = to_string(mds->cache_mesh_format);
+ mRNAMap["CACHE_NOISE_FORMAT"] = to_string(mds->cache_noise_format);
+ mRNAMap["CACHE_PARTICLE_FORMAT"] = to_string(mds->cache_particle_format);
+ mRNAMap["SIMULATION_METHOD"] = simulationMethod;
+ mRNAMap["FLIP_RATIO"] = to_string(mds->flip_ratio);
+ mRNAMap["PARTICLE_RANDOMNESS"] = to_string(mds->particle_randomness);
+ mRNAMap["PARTICLE_NUMBER"] = to_string(mds->particle_number);
+ mRNAMap["PARTICLE_MINIMUM"] = to_string(mds->particle_minimum);
+ mRNAMap["PARTICLE_MAXIMUM"] = to_string(mds->particle_maximum);
+ mRNAMap["PARTICLE_RADIUS"] = to_string(mds->particle_radius);
+ mRNAMap["FRACTIONS_THRESHOLD"] = to_string(mds->fractions_threshold);
+ mRNAMap["MESH_CONCAVE_UPPER"] = to_string(mds->mesh_concave_upper);
+ mRNAMap["MESH_CONCAVE_LOWER"] = to_string(mds->mesh_concave_lower);
+ mRNAMap["MESH_PARTICLE_RADIUS"] = to_string(mds->mesh_particle_radius);
+ mRNAMap["MESH_SMOOTHEN_POS"] = to_string(mds->mesh_smoothen_pos);
+ mRNAMap["MESH_SMOOTHEN_NEG"] = to_string(mds->mesh_smoothen_neg);
+ mRNAMap["PARTICLE_BAND_WIDTH"] = to_string(mds->particle_band_width);
+ mRNAMap["SNDPARTICLE_TAU_MIN_WC"] = to_string(mds->sndparticle_tau_min_wc);
+ mRNAMap["SNDPARTICLE_TAU_MAX_WC"] = to_string(mds->sndparticle_tau_max_wc);
+ mRNAMap["SNDPARTICLE_TAU_MIN_TA"] = to_string(mds->sndparticle_tau_min_ta);
+ mRNAMap["SNDPARTICLE_TAU_MAX_TA"] = to_string(mds->sndparticle_tau_max_ta);
+ mRNAMap["SNDPARTICLE_TAU_MIN_K"] = to_string(mds->sndparticle_tau_min_k);
+ mRNAMap["SNDPARTICLE_TAU_MAX_K"] = to_string(mds->sndparticle_tau_max_k);
+ mRNAMap["SNDPARTICLE_K_WC"] = to_string(mds->sndparticle_k_wc);
+ mRNAMap["SNDPARTICLE_K_TA"] = to_string(mds->sndparticle_k_ta);
+ mRNAMap["SNDPARTICLE_K_B"] = to_string(mds->sndparticle_k_b);
+ mRNAMap["SNDPARTICLE_K_D"] = to_string(mds->sndparticle_k_d);
+ mRNAMap["SNDPARTICLE_L_MIN"] = to_string(mds->sndparticle_l_min);
+ mRNAMap["SNDPARTICLE_L_MAX"] = to_string(mds->sndparticle_l_max);
+ mRNAMap["SNDPARTICLE_POTENTIAL_RADIUS"] = to_string(mds->sndparticle_potential_radius);
+ mRNAMap["SNDPARTICLE_UPDATE_RADIUS"] = to_string(mds->sndparticle_update_radius);
+ mRNAMap["LIQUID_SURFACE_TENSION"] = to_string(mds->surface_tension);
+ mRNAMap["FLUID_VISCOSITY"] = to_string(viscosity);
+ mRNAMap["FLUID_DOMAIN_SIZE"] = to_string(domainSize);
+ mRNAMap["SNDPARTICLE_TYPES"] = particleTypesStr;
+ mRNAMap["GUIDING_ALPHA"] = to_string(mds->guide_alpha);
+ mRNAMap["GUIDING_BETA"] = to_string(mds->guide_beta);
+ mRNAMap["GUIDING_FACTOR"] = to_string(mds->guide_vel_factor);
+ mRNAMap["GRAVITY_X"] = to_string(mds->gravity[0]);
+ mRNAMap["GRAVITY_Y"] = to_string(mds->gravity[1]);
+ mRNAMap["GRAVITY_Z"] = to_string(mds->gravity[2]);
+ mRNAMap["CACHE_DIR"] = cacheDirectory;
+}
+
+string MANTA::getRealValue(const string &varName)
+{
+ if (with_debug)
+ cout << "MANTA::getRealValue()" << endl;
+
+ unordered_map<string, string>::iterator it;
+ it = mRNAMap.find(varName);
+
+ if (it == mRNAMap.end()) {
+ cerr << "Fluid Error -- variable " << varName << " not found in RNA map " << it->second
+ << endl;
+ return "";
}
- else if (varName == "MIN_RESX")
- ss << mmd->domain->res_min[0];
- else if (varName == "MIN_RESY")
- ss << mmd->domain->res_min[1];
- else if (varName == "MIN_RESZ")
- ss << mmd->domain->res_min[2];
- else if (varName == "BASE_RESX")
- ss << mmd->domain->base_res[0];
- else if (varName == "BASE_RESY")
- ss << mmd->domain->base_res[1];
- else if (varName == "BASE_RESZ")
- ss << mmd->domain->base_res[2];
- else if (varName == "WLT_STR")
- ss << mmd->domain->noise_strength;
- else if (varName == "NOISE_POSSCALE")
- ss << mmd->domain->noise_pos_scale;
- else if (varName == "NOISE_TIMEANIM")
- ss << mmd->domain->noise_time_anim;
- else if (varName == "COLOR_R")
- ss << mmd->domain->active_color[0];
- else if (varName == "COLOR_G")
- ss << mmd->domain->active_color[1];
- else if (varName == "COLOR_B")
- ss << mmd->domain->active_color[2];
- else if (varName == "BUOYANCY_ALPHA")
- ss << mmd->domain->alpha;
- else if (varName == "BUOYANCY_BETA")
- ss << mmd->domain->beta;
- else if (varName == "DISSOLVE_SPEED")
- ss << mmd->domain->diss_speed;
- else if (varName == "BURNING_RATE")
- ss << mmd->domain->burning_rate;
- else if (varName == "FLAME_SMOKE")
- ss << mmd->domain->flame_smoke;
- else if (varName == "IGNITION_TEMP")
- ss << mmd->domain->flame_ignition;
- else if (varName == "MAX_TEMP")
- ss << mmd->domain->flame_max_temp;
- else if (varName == "FLAME_SMOKE_COLOR_X")
- ss << mmd->domain->flame_smoke_color[0];
- else if (varName == "FLAME_SMOKE_COLOR_Y")
- ss << mmd->domain->flame_smoke_color[1];
- else if (varName == "FLAME_SMOKE_COLOR_Z")
- ss << mmd->domain->flame_smoke_color[2];
- else if (varName == "CURRENT_FRAME")
- ss << mmd->time;
- else if (varName == "START_FRAME")
- ss << mmd->domain->cache_frame_start;
- else if (varName == "END_FRAME")
- ss << mmd->domain->cache_frame_end;
- else if (varName == "CACHE_DATA_FORMAT")
- ss << getCacheFileEnding(mmd->domain->cache_data_format);
- else if (varName == "CACHE_MESH_FORMAT")
- ss << getCacheFileEnding(mmd->domain->cache_mesh_format);
- else if (varName == "CACHE_NOISE_FORMAT")
- ss << getCacheFileEnding(mmd->domain->cache_noise_format);
- else if (varName == "CACHE_PARTICLE_FORMAT")
- ss << getCacheFileEnding(mmd->domain->cache_particle_format);
- else if (varName == "SIMULATION_METHOD") {
- if (mmd->domain->simulation_method & FLUID_DOMAIN_METHOD_FLIP) {
- ss << "'FLIP'";
- }
- else if (mmd->domain->simulation_method & FLUID_DOMAIN_METHOD_APIC) {
- ss << "'APIC'";
- }
- else {
- ss << "'NONE'";
- }
+ if (with_debug) {
+ cout << "Found variable " << varName << " with value " << it->second << endl;
}
- else if (varName == "FLIP_RATIO")
- ss << mmd->domain->flip_ratio;
- else if (varName == "PARTICLE_RANDOMNESS")
- ss << mmd->domain->particle_randomness;
- else if (varName == "PARTICLE_NUMBER")
- ss << mmd->domain->particle_number;
- else if (varName == "PARTICLE_MINIMUM")
- ss << mmd->domain->particle_minimum;
- else if (varName == "PARTICLE_MAXIMUM")
- ss << mmd->domain->particle_maximum;
- else if (varName == "PARTICLE_RADIUS")
- ss << mmd->domain->particle_radius;
- else if (varName == "FRACTIONS_THRESHOLD")
- ss << mmd->domain->fractions_threshold;
- else if (varName == "MESH_CONCAVE_UPPER")
- ss << mmd->domain->mesh_concave_upper;
- else if (varName == "MESH_CONCAVE_LOWER")
- ss << mmd->domain->mesh_concave_lower;
- else if (varName == "MESH_PARTICLE_RADIUS")
- ss << mmd->domain->mesh_particle_radius;
- else if (varName == "MESH_SMOOTHEN_POS")
- ss << mmd->domain->mesh_smoothen_pos;
- else if (varName == "MESH_SMOOTHEN_NEG")
- ss << mmd->domain->mesh_smoothen_neg;
- else if (varName == "USING_MESH")
- ss << (mmd->domain->flags & FLUID_DOMAIN_USE_MESH ? "True" : "False");
- else if (varName == "USING_IMPROVED_MESH")
- ss << (mmd->domain->mesh_generator == FLUID_DOMAIN_MESH_IMPROVED ? "True" : "False");
- else if (varName == "PARTICLE_BAND_WIDTH")
- ss << mmd->domain->particle_band_width;
- else if (varName == "SNDPARTICLE_TAU_MIN_WC")
- ss << mmd->domain->sndparticle_tau_min_wc;
- else if (varName == "SNDPARTICLE_TAU_MAX_WC")
- ss << mmd->domain->sndparticle_tau_max_wc;
- else if (varName == "SNDPARTICLE_TAU_MIN_TA")
- ss << mmd->domain->sndparticle_tau_min_ta;
- else if (varName == "SNDPARTICLE_TAU_MAX_TA")
- ss << mmd->domain->sndparticle_tau_max_ta;
- else if (varName == "SNDPARTICLE_TAU_MIN_K")
- ss << mmd->domain->sndparticle_tau_min_k;
- else if (varName == "SNDPARTICLE_TAU_MAX_K")
- ss << mmd->domain->sndparticle_tau_max_k;
- else if (varName == "SNDPARTICLE_K_WC")
- ss << mmd->domain->sndparticle_k_wc;
- else if (varName == "SNDPARTICLE_K_TA")
- ss << mmd->domain->sndparticle_k_ta;
- else if (varName == "SNDPARTICLE_K_B")
- ss << mmd->domain->sndparticle_k_b;
- else if (varName == "SNDPARTICLE_K_D")
- ss << mmd->domain->sndparticle_k_d;
- else if (varName == "SNDPARTICLE_L_MIN")
- ss << mmd->domain->sndparticle_l_min;
- else if (varName == "SNDPARTICLE_L_MAX")
- ss << mmd->domain->sndparticle_l_max;
- else if (varName == "SNDPARTICLE_BOUNDARY_DELETE")
- ss << (mmd->domain->sndparticle_boundary == SNDPARTICLE_BOUNDARY_DELETE);
- else if (varName == "SNDPARTICLE_BOUNDARY_PUSHOUT")
- ss << (mmd->domain->sndparticle_boundary == SNDPARTICLE_BOUNDARY_PUSHOUT);
- else if (varName == "SNDPARTICLE_POTENTIAL_RADIUS")
- ss << mmd->domain->sndparticle_potential_radius;
- else if (varName == "SNDPARTICLE_UPDATE_RADIUS")
- ss << mmd->domain->sndparticle_update_radius;
- else if (varName == "LIQUID_SURFACE_TENSION")
- ss << mmd->domain->surface_tension;
- else if (varName == "FLUID_VISCOSITY")
- ss << mmd->domain->viscosity_base * pow(10.0f, -mmd->domain->viscosity_exponent);
- else if (varName == "FLUID_DOMAIN_SIZE") {
- tmpFloat = MAX3(
- mmd->domain->global_size[0], mmd->domain->global_size[1], mmd->domain->global_size[2]);
- ss << tmpFloat;
- }
- else if (varName == "SNDPARTICLE_TYPES") {
- if (mmd->domain->particle_type & FLUID_DOMAIN_PARTICLE_SPRAY) {
- ss << "PtypeSpray";
- }
- if (mmd->domain->particle_type & FLUID_DOMAIN_PARTICLE_BUBBLE) {
- if (!ss.str().empty())
- ss << "|";
- ss << "PtypeBubble";
- }
- if (mmd->domain->particle_type & FLUID_DOMAIN_PARTICLE_FOAM) {
- if (!ss.str().empty())
- ss << "|";
- ss << "PtypeFoam";
- }
- if (mmd->domain->particle_type & FLUID_DOMAIN_PARTICLE_TRACER) {
- if (!ss.str().empty())
- ss << "|";
- ss << "PtypeTracer";
- }
- if (ss.str().empty())
- ss << "0";
- }
- else if (varName == "USING_SNDPARTS") {
- tmpVar = (FLUID_DOMAIN_PARTICLE_SPRAY | FLUID_DOMAIN_PARTICLE_BUBBLE |
- FLUID_DOMAIN_PARTICLE_FOAM | FLUID_DOMAIN_PARTICLE_TRACER);
- ss << (((mmd->domain->particle_type & tmpVar)) ? "True" : "False");
- }
- else if (varName == "GUIDING_ALPHA")
- ss << mmd->domain->guide_alpha;
- else if (varName == "GUIDING_BETA")
- ss << mmd->domain->guide_beta;
- else if (varName == "GUIDING_FACTOR")
- ss << mmd->domain->guide_vel_factor;
- else if (varName == "GRAVITY_X")
- ss << mmd->domain->gravity[0];
- else if (varName == "GRAVITY_Y")
- ss << mmd->domain->gravity[1];
- else if (varName == "GRAVITY_Z")
- ss << mmd->domain->gravity[2];
- else if (varName == "CACHE_DIR")
- ss << mmd->domain->cache_directory;
- else if (varName == "CACHE_RESUMABLE")
- ss << (mmd->domain->cache_type == FLUID_DOMAIN_CACHE_FINAL ? "False" : "True");
- else if (varName == "USING_ADAPTIVETIME")
- ss << (mmd->domain->flags & FLUID_DOMAIN_USE_ADAPTIVE_TIME ? "True" : "False");
- else if (varName == "USING_SPEEDVECTORS")
- ss << (mmd->domain->flags & FLUID_DOMAIN_USE_SPEED_VECTORS ? "True" : "False");
- else if (varName == "USING_FRACTIONS")
- ss << (mmd->domain->flags & FLUID_DOMAIN_USE_FRACTIONS ? "True" : "False");
- else if (varName == "DELETE_IN_OBSTACLE")
- ss << (mmd->domain->flags & FLUID_DOMAIN_DELETE_IN_OBSTACLE ? "True" : "False");
- else if (varName == "USING_DIFFUSION")
- ss << (mmd->domain->flags & FLUID_DOMAIN_USE_DIFFUSION ? "True" : "False");
- else
- std::cerr << "Fluid Error -- Unknown option: " << varName << std::endl;
- return ss.str();
-}
-
-std::string MANTA::parseLine(const std::string &line, FluidModifierData *mmd)
+
+ return it->second;
+}
+
+string MANTA::parseLine(const string &line)
{
if (line.size() == 0)
return "";
- std::string res = "";
+ string res = "";
int currPos = 0, start_del = 0, end_del = -1;
bool readingVar = false;
const char delimiter = '$';
@@ -1022,7 +864,7 @@ std::string MANTA::parseLine(const std::string &line, FluidModifierData *mmd)
else if (line[currPos] == delimiter && readingVar) {
readingVar = false;
end_del = currPos;
- res += getRealValue(line.substr(start_del, currPos - start_del), mmd);
+ res += getRealValue(line.substr(start_del, currPos - start_del));
}
currPos++;
}
@@ -1030,13 +872,21 @@ std::string MANTA::parseLine(const std::string &line, FluidModifierData *mmd)
return res;
}
-std::string MANTA::parseScript(const std::string &setup_string, FluidModifierData *mmd)
+string MANTA::parseScript(const string &setup_string, FluidModifierData *mmd)
{
- std::istringstream f(setup_string);
- std::ostringstream res;
- std::string line = "";
+ if (MANTA::with_debug)
+ cout << "MANTA::parseScript()" << endl;
+
+ istringstream f(setup_string);
+ ostringstream res;
+ string line = "";
+
+ // Update RNA map if modifier data is handed over
+ if (mmd) {
+ initializeRNAMap(mmd);
+ }
while (getline(f, line)) {
- res << parseLine(line, mmd) << "\n";
+ res << parseLine(line) << "\n";
}
return res.str();
}
@@ -1044,13 +894,14 @@ std::string MANTA::parseScript(const std::string &setup_string, FluidModifierDat
bool MANTA::updateFlipStructures(FluidModifierData *mmd, int framenr)
{
if (MANTA::with_debug)
- std::cout << "MANTA::updateFlipStructures()" << std::endl;
+ cout << "MANTA::updateFlipStructures()" << endl;
+ FluidDomainSettings *mds = mmd->domain;
mFlipFromFile = false;
if (!mUsingLiquid)
return false;
- if (BLI_path_is_rel(mmd->domain->cache_directory))
+ if (BLI_path_is_rel(mds->cache_directory))
return false;
int result = 0;
@@ -1063,8 +914,8 @@ bool MANTA::updateFlipStructures(FluidModifierData *mmd, int framenr)
mFlipParticleData->clear();
mFlipParticleVelocity->clear();
- std::string pformat = getCacheFileEnding(mmd->domain->cache_particle_format);
- std::string file = getFile(
+ string pformat = getCacheFileEnding(mds->cache_particle_format);
+ string file = getFile(
mmd, FLUID_DOMAIN_DIR_DATA, FLUID_DOMAIN_FILE_PP, pformat.c_str(), framenr);
expected += 1;
@@ -1086,13 +937,14 @@ bool MANTA::updateFlipStructures(FluidModifierData *mmd, int framenr)
bool MANTA::updateMeshStructures(FluidModifierData *mmd, int framenr)
{
if (MANTA::with_debug)
- std::cout << "MANTA::updateMeshStructures()" << std::endl;
+ cout << "MANTA::updateMeshStructures()" << endl;
+ FluidDomainSettings *mds = mmd->domain;
mMeshFromFile = false;
if (!mUsingMesh)
return false;
- if (BLI_path_is_rel(mmd->domain->cache_directory))
+ if (BLI_path_is_rel(mds->cache_directory))
return false;
int result = 0;
@@ -1108,9 +960,9 @@ bool MANTA::updateMeshStructures(FluidModifierData *mmd, int framenr)
if (mMeshVelocities)
mMeshVelocities->clear();
- std::string mformat = getCacheFileEnding(mmd->domain->cache_mesh_format);
- std::string dformat = getCacheFileEnding(mmd->domain->cache_data_format);
- std::string file = getFile(mmd, FLUID_DOMAIN_DIR_MESH, FLUID_DOMAIN_FILE_MESH, mformat, framenr);
+ string mformat = getCacheFileEnding(mds->cache_mesh_format);
+ string dformat = getCacheFileEnding(mds->cache_data_format);
+ string file = getFile(mmd, FLUID_DOMAIN_DIR_MESH, FLUID_DOMAIN_FILE_MESH, mformat, framenr);
expected += 1;
if (BLI_exists(file.c_str())) {
@@ -1133,13 +985,14 @@ bool MANTA::updateMeshStructures(FluidModifierData *mmd, int framenr)
bool MANTA::updateParticleStructures(FluidModifierData *mmd, int framenr)
{
if (MANTA::with_debug)
- std::cout << "MANTA::updateParticleStructures()" << std::endl;
+ cout << "MANTA::updateParticleStructures()" << endl;
+ FluidDomainSettings *mds = mmd->domain;
mParticlesFromFile = false;
if (!mUsingDrops && !mUsingBubbles && !mUsingFloats && !mUsingTracers)
return false;
- if (BLI_path_is_rel(mmd->domain->cache_directory))
+ if (BLI_path_is_rel(mds->cache_directory))
return false;
int result = 0;
@@ -1153,8 +1006,8 @@ bool MANTA::updateParticleStructures(FluidModifierData *mmd, int framenr)
mSndParticleVelocity->clear();
mSndParticleLife->clear();
- std::string pformat = getCacheFileEnding(mmd->domain->cache_particle_format);
- std::string file = getFile(
+ string pformat = getCacheFileEnding(mds->cache_particle_format);
+ string file = getFile(
mmd, FLUID_DOMAIN_DIR_PARTICLES, FLUID_DOMAIN_FILE_PPSND, pformat, framenr);
expected += 1;
@@ -1183,21 +1036,21 @@ bool MANTA::updateParticleStructures(FluidModifierData *mmd, int framenr)
bool MANTA::updateSmokeStructures(FluidModifierData *mmd, int framenr)
{
if (MANTA::with_debug)
- std::cout << "MANTA::updateGridStructures()" << std::endl;
+ cout << "MANTA::updateGridStructures()" << endl;
+ FluidDomainSettings *mds = mmd->domain;
mSmokeFromFile = false;
if (!mUsingSmoke)
return false;
- if (BLI_path_is_rel(mmd->domain->cache_directory))
+ if (BLI_path_is_rel(mds->cache_directory))
return false;
int result = 0;
int expected = 0; /* Expected number of read successes for this frame. */
- std::string dformat = getCacheFileEnding(mmd->domain->cache_data_format);
- std::string file = getFile(
- mmd, FLUID_DOMAIN_DIR_DATA, FLUID_DOMAIN_FILE_DENSITY, dformat, framenr);
+ string dformat = getCacheFileEnding(mds->cache_data_format);
+ string file = getFile(mmd, FLUID_DOMAIN_DIR_DATA, FLUID_DOMAIN_FILE_DENSITY, dformat, framenr);
expected += 1;
if (BLI_exists(file.c_str())) {
@@ -1273,21 +1126,22 @@ bool MANTA::updateSmokeStructures(FluidModifierData *mmd, int framenr)
bool MANTA::updateNoiseStructures(FluidModifierData *mmd, int framenr)
{
if (MANTA::with_debug)
- std::cout << "MANTA::updateNoiseStructures()" << std::endl;
+ cout << "MANTA::updateNoiseStructures()" << endl;
+ FluidDomainSettings *mds = mmd->domain;
mNoiseFromFile = false;
if (!mUsingSmoke || !mUsingNoise)
return false;
- if (BLI_path_is_rel(mmd->domain->cache_directory))
+ if (BLI_path_is_rel(mds->cache_directory))
return false;
int result = 0;
int expected = 0; /* Expected number of read successes for this frame. */
- std::string dformat = getCacheFileEnding(mmd->domain->cache_data_format);
- std::string nformat = getCacheFileEnding(mmd->domain->cache_noise_format);
- std::string file = getFile(
+ string dformat = getCacheFileEnding(mds->cache_data_format);
+ string nformat = getCacheFileEnding(mds->cache_noise_format);
+ string file = getFile(
mmd, FLUID_DOMAIN_DIR_NOISE, FLUID_DOMAIN_FILE_DENSITYNOISE, nformat, framenr);
expected += 1;
@@ -1353,10 +1207,10 @@ bool MANTA::updateNoiseStructures(FluidModifierData *mmd, int framenr)
}
/* Dirty hack: Needed to format paths from python code that is run via PyRun_SimpleString */
-static std::string escapeSlashes(std::string const &s)
+static string escapeSlashes(string const &s)
{
- std::string result = "";
- for (std::string::const_iterator i = s.begin(), end = s.end(); i != end; ++i) {
+ string result = "";
+ for (string::const_iterator i = s.begin(), end = s.end(); i != end; ++i) {
unsigned char c = *i;
if (c == '\\')
result += "\\\\";
@@ -1369,21 +1223,20 @@ static std::string escapeSlashes(std::string const &s)
bool MANTA::writeConfiguration(FluidModifierData *mmd, int framenr)
{
if (with_debug)
- std::cout << "MANTA::writeConfiguration()" << std::endl;
+ cout << "MANTA::writeConfiguration()" << endl;
FluidDomainSettings *mds = mmd->domain;
- std::string directory = getDirectory(mmd, FLUID_DOMAIN_DIR_CONFIG);
- std::string format = FLUID_DOMAIN_EXTENSION_UNI;
- std::string file = getFile(
- mmd, FLUID_DOMAIN_DIR_CONFIG, FLUID_DOMAIN_FILE_CONFIG, format, framenr);
+ string directory = getDirectory(mmd, FLUID_DOMAIN_DIR_CONFIG);
+ string format = FLUID_DOMAIN_EXTENSION_UNI;
+ string file = getFile(mmd, FLUID_DOMAIN_DIR_CONFIG, FLUID_DOMAIN_FILE_CONFIG, format, framenr);
/* Create 'config' subdir if it does not exist already. */
BLI_dir_create_recursive(directory.c_str());
gzFile gzf = (gzFile)BLI_gzopen(file.c_str(), "wb1"); // do some compression
if (!gzf) {
- std::cerr << "Fluid Error -- Cannot open file " << file << std::endl;
+ cerr << "Fluid Error -- Cannot open file " << file << endl;
return false;
}
@@ -1408,17 +1261,18 @@ bool MANTA::writeConfiguration(FluidModifierData *mmd, int framenr)
bool MANTA::writeData(FluidModifierData *mmd, int framenr)
{
if (with_debug)
- std::cout << "MANTA::writeData()" << std::endl;
+ cout << "MANTA::writeData()" << endl;
- std::ostringstream ss;
- std::vector<std::string> pythonCommands;
+ ostringstream ss;
+ vector<string> pythonCommands;
+ FluidDomainSettings *mds = mmd->domain;
- std::string directory = getDirectory(mmd, FLUID_DOMAIN_DIR_DATA);
- std::string dformat = getCacheFileEnding(mmd->domain->cache_data_format);
- std::string pformat = getCacheFileEnding(mmd->domain->cache_particle_format);
+ string directory = getDirectory(mmd, FLUID_DOMAIN_DIR_DATA);
+ string dformat = getCacheFileEnding(mds->cache_data_format);
+ string pformat = getCacheFileEnding(mds->cache_particle_format);
- bool final_cache = (mmd->domain->cache_type == FLUID_DOMAIN_CACHE_FINAL);
- std::string resumable_cache = (final_cache) ? "False" : "True";
+ bool final_cache = (mds->cache_type == FLUID_DOMAIN_CACHE_FINAL);
+ string resumable_cache = (final_cache) ? "False" : "True";
ss.str("");
ss << "fluid_save_data_" << mCurrentID << "('" << escapeSlashes(directory) << "', " << framenr
@@ -1443,16 +1297,17 @@ bool MANTA::writeData(FluidModifierData *mmd, int framenr)
bool MANTA::writeNoise(FluidModifierData *mmd, int framenr)
{
if (with_debug)
- std::cout << "MANTA::writeNoise()" << std::endl;
+ cout << "MANTA::writeNoise()" << endl;
- std::ostringstream ss;
- std::vector<std::string> pythonCommands;
+ ostringstream ss;
+ vector<string> pythonCommands;
+ FluidDomainSettings *mds = mmd->domain;
- std::string directory = getDirectory(mmd, FLUID_DOMAIN_DIR_NOISE);
- std::string nformat = getCacheFileEnding(mmd->domain->cache_noise_format);
+ string directory = getDirectory(mmd, FLUID_DOMAIN_DIR_NOISE);
+ string nformat = getCacheFileEnding(mds->cache_noise_format);
- bool final_cache = (mmd->domain->cache_type == FLUID_DOMAIN_CACHE_FINAL);
- std::string resumable_cache = (final_cache) ? "False" : "True";
+ bool final_cache = (mds->cache_type == FLUID_DOMAIN_CACHE_FINAL);
+ string resumable_cache = (final_cache) ? "False" : "True";
if (mUsingSmoke && mUsingNoise) {
ss.str("");
@@ -1466,22 +1321,21 @@ bool MANTA::writeNoise(FluidModifierData *mmd, int framenr)
bool MANTA::readConfiguration(FluidModifierData *mmd, int framenr)
{
if (with_debug)
- std::cout << "MANTA::readConfiguration()" << std::endl;
+ cout << "MANTA::readConfiguration()" << endl;
FluidDomainSettings *mds = mmd->domain;
float dummy;
- std::string directory = getDirectory(mmd, FLUID_DOMAIN_DIR_CONFIG);
- std::string format = FLUID_DOMAIN_EXTENSION_UNI;
- std::string file = getFile(
- mmd, FLUID_DOMAIN_DIR_CONFIG, FLUID_DOMAIN_FILE_CONFIG, format, framenr);
+ string directory = getDirectory(mmd, FLUID_DOMAIN_DIR_CONFIG);
+ string format = FLUID_DOMAIN_EXTENSION_UNI;
+ string file = getFile(mmd, FLUID_DOMAIN_DIR_CONFIG, FLUID_DOMAIN_FILE_CONFIG, format, framenr);
if (!hasConfig(mmd, framenr))
return false;
gzFile gzf = (gzFile)BLI_gzopen(file.c_str(), "rb"); // do some compression
if (!gzf) {
- std::cerr << "Fluid Error -- Cannot open file " << file << std::endl;
+ cerr << "Fluid Error -- Cannot open file " << file << endl;
return false;
}
@@ -1507,21 +1361,22 @@ bool MANTA::readConfiguration(FluidModifierData *mmd, int framenr)
bool MANTA::readData(FluidModifierData *mmd, int framenr)
{
if (with_debug)
- std::cout << "MANTA::readData()" << std::endl;
+ cout << "MANTA::readData()" << endl;
if (!mUsingSmoke && !mUsingLiquid)
return false;
- std::ostringstream ss;
- std::vector<std::string> pythonCommands;
+ ostringstream ss;
+ vector<string> pythonCommands;
+ FluidDomainSettings *mds = mmd->domain;
bool result = true;
- std::string directory = getDirectory(mmd, FLUID_DOMAIN_DIR_DATA);
- std::string dformat = getCacheFileEnding(mmd->domain->cache_data_format);
- std::string pformat = getCacheFileEnding(mmd->domain->cache_particle_format);
+ string directory = getDirectory(mmd, FLUID_DOMAIN_DIR_DATA);
+ string dformat = getCacheFileEnding(mds->cache_data_format);
+ string pformat = getCacheFileEnding(mds->cache_particle_format);
- bool final_cache = (mmd->domain->cache_type == FLUID_DOMAIN_CACHE_FINAL);
- std::string resumable_cache = (final_cache) ? "False" : "True";
+ bool final_cache = (mds->cache_type == FLUID_DOMAIN_CACHE_FINAL);
+ string resumable_cache = (final_cache) ? "False" : "True";
/* Sanity check: Are cache files present? */
if (!hasData(mmd, framenr))
@@ -1552,19 +1407,20 @@ bool MANTA::readData(FluidModifierData *mmd, int framenr)
bool MANTA::readNoise(FluidModifierData *mmd, int framenr)
{
if (with_debug)
- std::cout << "MANTA::readNoise()" << std::endl;
+ cout << "MANTA::readNoise()" << endl;
if (!mUsingSmoke || !mUsingNoise)
return false;
- std::ostringstream ss;
- std::vector<std::string> pythonCommands;
+ ostringstream ss;
+ vector<string> pythonCommands;
+ FluidDomainSettings *mds = mmd->domain;
- std::string directory = getDirectory(mmd, FLUID_DOMAIN_DIR_NOISE);
- std::string nformat = getCacheFileEnding(mmd->domain->cache_noise_format);
+ string directory = getDirectory(mmd, FLUID_DOMAIN_DIR_NOISE);
+ string nformat = getCacheFileEnding(mds->cache_noise_format);
- bool final_cache = (mmd->domain->cache_type == FLUID_DOMAIN_CACHE_FINAL);
- std::string resumable_cache = (final_cache) ? "False" : "True";
+ bool final_cache = (mds->cache_type == FLUID_DOMAIN_CACHE_FINAL);
+ string resumable_cache = (final_cache) ? "False" : "True";
/* Sanity check: Are cache files present? */
if (!hasNoise(mmd, framenr))
@@ -1584,17 +1440,18 @@ bool MANTA::readNoise(FluidModifierData *mmd, int framenr)
bool MANTA::readMesh(FluidModifierData *mmd, int framenr)
{
if (with_debug)
- std::cout << "MANTA::readMesh()" << std::endl;
+ cout << "MANTA::readMesh()" << endl;
if (!mUsingLiquid || !mUsingMesh)
return false;
- std::ostringstream ss;
- std::vector<std::string> pythonCommands;
+ ostringstream ss;
+ vector<string> pythonCommands;
+ FluidDomainSettings *mds = mmd->domain;
- std::string directory = getDirectory(mmd, FLUID_DOMAIN_DIR_MESH);
- std::string mformat = getCacheFileEnding(mmd->domain->cache_mesh_format);
- std::string dformat = getCacheFileEnding(mmd->domain->cache_data_format);
+ string directory = getDirectory(mmd, FLUID_DOMAIN_DIR_MESH);
+ string mformat = getCacheFileEnding(mds->cache_mesh_format);
+ string dformat = getCacheFileEnding(mds->cache_data_format);
/* Sanity check: Are cache files present? */
if (!hasMesh(mmd, framenr))
@@ -1621,21 +1478,22 @@ bool MANTA::readMesh(FluidModifierData *mmd, int framenr)
bool MANTA::readParticles(FluidModifierData *mmd, int framenr)
{
if (with_debug)
- std::cout << "MANTA::readParticles()" << std::endl;
+ cout << "MANTA::readParticles()" << endl;
if (!mUsingLiquid)
return false;
if (!mUsingDrops && !mUsingBubbles && !mUsingFloats && !mUsingTracers)
return false;
- std::ostringstream ss;
- std::vector<std::string> pythonCommands;
+ ostringstream ss;
+ vector<string> pythonCommands;
+ FluidDomainSettings *mds = mmd->domain;
- std::string directory = getDirectory(mmd, FLUID_DOMAIN_DIR_PARTICLES);
- std::string pformat = getCacheFileEnding(mmd->domain->cache_particle_format);
+ string directory = getDirectory(mmd, FLUID_DOMAIN_DIR_PARTICLES);
+ string pformat = getCacheFileEnding(mds->cache_particle_format);
- bool final_cache = (mmd->domain->cache_type == FLUID_DOMAIN_CACHE_FINAL);
- std::string resumable_cache = (final_cache) ? "False" : "True";
+ bool final_cache = (mds->cache_type == FLUID_DOMAIN_CACHE_FINAL);
+ string resumable_cache = (final_cache) ? "False" : "True";
/* Sanity check: Are cache files present? */
if (!hasParticles(mmd, framenr))
@@ -1652,19 +1510,21 @@ bool MANTA::readParticles(FluidModifierData *mmd, int framenr)
bool MANTA::readGuiding(FluidModifierData *mmd, int framenr, bool sourceDomain)
{
if (with_debug)
- std::cout << "MANTA::readGuiding()" << std::endl;
+ cout << "MANTA::readGuiding()" << endl;
+
+ FluidDomainSettings *mds = mmd->domain;
if (!mUsingGuiding)
return false;
- if (!mmd->domain)
+ if (!mds)
return false;
- std::ostringstream ss;
- std::vector<std::string> pythonCommands;
+ ostringstream ss;
+ vector<string> pythonCommands;
- std::string directory = (sourceDomain) ? getDirectory(mmd, FLUID_DOMAIN_DIR_DATA) :
- getDirectory(mmd, FLUID_DOMAIN_DIR_GUIDE);
- std::string gformat = getCacheFileEnding(mmd->domain->cache_data_format);
+ string directory = (sourceDomain) ? getDirectory(mmd, FLUID_DOMAIN_DIR_DATA) :
+ getDirectory(mmd, FLUID_DOMAIN_DIR_GUIDE);
+ string gformat = getCacheFileEnding(mds->cache_data_format);
/* Sanity check: Are cache files present? */
if (!hasGuiding(mmd, framenr, sourceDomain))
@@ -1688,28 +1548,26 @@ bool MANTA::readGuiding(FluidModifierData *mmd, int framenr, bool sourceDomain)
bool MANTA::bakeData(FluidModifierData *mmd, int framenr)
{
if (with_debug)
- std::cout << "MANTA::bakeData()" << std::endl;
+ cout << "MANTA::bakeData()" << endl;
- std::string tmpString, finalString;
- std::ostringstream ss;
- std::vector<std::string> pythonCommands;
+ string tmpString, finalString;
+ ostringstream ss;
+ vector<string> pythonCommands;
+ FluidDomainSettings *mds = mmd->domain;
char cacheDirData[FILE_MAX], cacheDirGuiding[FILE_MAX];
cacheDirData[0] = '\0';
cacheDirGuiding[0] = '\0';
- std::string dformat = getCacheFileEnding(mmd->domain->cache_data_format);
- std::string pformat = getCacheFileEnding(mmd->domain->cache_particle_format);
- std::string gformat = dformat; // Use same data format for guiding format
+ string dformat = getCacheFileEnding(mds->cache_data_format);
+ string pformat = getCacheFileEnding(mds->cache_particle_format);
+ string gformat = dformat; // Use same data format for guiding format
- BLI_path_join(cacheDirData,
- sizeof(cacheDirData),
- mmd->domain->cache_directory,
- FLUID_DOMAIN_DIR_DATA,
- nullptr);
+ BLI_path_join(
+ cacheDirData, sizeof(cacheDirData), mds->cache_directory, FLUID_DOMAIN_DIR_DATA, nullptr);
BLI_path_join(cacheDirGuiding,
sizeof(cacheDirGuiding),
- mmd->domain->cache_directory,
+ mds->cache_directory,
FLUID_DOMAIN_DIR_GUIDE,
nullptr);
BLI_path_make_safe(cacheDirData);
@@ -1727,31 +1585,26 @@ bool MANTA::bakeData(FluidModifierData *mmd, int framenr)
bool MANTA::bakeNoise(FluidModifierData *mmd, int framenr)
{
if (with_debug)
- std::cout << "MANTA::bakeNoise()" << std::endl;
+ cout << "MANTA::bakeNoise()" << endl;
- std::ostringstream ss;
- std::vector<std::string> pythonCommands;
+ ostringstream ss;
+ vector<string> pythonCommands;
+ FluidDomainSettings *mds = mmd->domain;
char cacheDirData[FILE_MAX], cacheDirNoise[FILE_MAX];
cacheDirData[0] = '\0';
cacheDirNoise[0] = '\0';
- std::string dformat = getCacheFileEnding(mmd->domain->cache_data_format);
- std::string nformat = getCacheFileEnding(mmd->domain->cache_noise_format);
+ string dformat = getCacheFileEnding(mds->cache_data_format);
+ string nformat = getCacheFileEnding(mds->cache_noise_format);
- bool final_cache = (mmd->domain->cache_type == FLUID_DOMAIN_CACHE_FINAL);
- std::string resumable_cache = (final_cache) ? "False" : "True";
+ bool final_cache = (mds->cache_type == FLUID_DOMAIN_CACHE_FINAL);
+ string resumable_cache = (final_cache) ? "False" : "True";
- BLI_path_join(cacheDirData,
- sizeof(cacheDirData),
- mmd->domain->cache_directory,
- FLUID_DOMAIN_DIR_DATA,
- nullptr);
- BLI_path_join(cacheDirNoise,
- sizeof(cacheDirNoise),
- mmd->domain->cache_directory,
- FLUID_DOMAIN_DIR_NOISE,
- nullptr);
+ BLI_path_join(
+ cacheDirData, sizeof(cacheDirData), mds->cache_directory, FLUID_DOMAIN_DIR_DATA, nullptr);
+ BLI_path_join(
+ cacheDirNoise, sizeof(cacheDirNoise), mds->cache_directory, FLUID_DOMAIN_DIR_NOISE, nullptr);
BLI_path_make_safe(cacheDirData);
BLI_path_make_safe(cacheDirNoise);
@@ -1767,29 +1620,24 @@ bool MANTA::bakeNoise(FluidModifierData *mmd, int framenr)
bool MANTA::bakeMesh(FluidModifierData *mmd, int framenr)
{
if (with_debug)
- std::cout << "MANTA::bakeMesh()" << std::endl;
+ cout << "MANTA::bakeMesh()" << endl;
- std::ostringstream ss;
- std::vector<std::string> pythonCommands;
+ ostringstream ss;
+ vector<string> pythonCommands;
+ FluidDomainSettings *mds = mmd->domain;
char cacheDirData[FILE_MAX], cacheDirMesh[FILE_MAX];
cacheDirData[0] = '\0';
cacheDirMesh[0] = '\0';
- std::string dformat = getCacheFileEnding(mmd->domain->cache_data_format);
- std::string mformat = getCacheFileEnding(mmd->domain->cache_mesh_format);
- std::string pformat = getCacheFileEnding(mmd->domain->cache_particle_format);
+ string dformat = getCacheFileEnding(mds->cache_data_format);
+ string mformat = getCacheFileEnding(mds->cache_mesh_format);
+ string pformat = getCacheFileEnding(mds->cache_particle_format);
- BLI_path_join(cacheDirData,
- sizeof(cacheDirData),
- mmd->domain->cache_directory,
- FLUID_DOMAIN_DIR_DATA,
- nullptr);
- BLI_path_join(cacheDirMesh,
- sizeof(cacheDirMesh),
- mmd->domain->cache_directory,
- FLUID_DOMAIN_DIR_MESH,
- nullptr);
+ BLI_path_join(
+ cacheDirData, sizeof(cacheDirData), mds->cache_directory, FLUID_DOMAIN_DIR_DATA, nullptr);
+ BLI_path_join(
+ cacheDirMesh, sizeof(cacheDirMesh), mds->cache_directory, FLUID_DOMAIN_DIR_MESH, nullptr);
BLI_path_make_safe(cacheDirData);
BLI_path_make_safe(cacheDirMesh);
@@ -1805,29 +1653,27 @@ bool MANTA::bakeMesh(FluidModifierData *mmd, int framenr)
bool MANTA::bakeParticles(FluidModifierData *mmd, int framenr)
{
if (with_debug)
- std::cout << "MANTA::bakeParticles()" << std::endl;
+ cout << "MANTA::bakeParticles()" << endl;
- std::ostringstream ss;
- std::vector<std::string> pythonCommands;
+ ostringstream ss;
+ vector<string> pythonCommands;
+ FluidDomainSettings *mds = mmd->domain;
char cacheDirData[FILE_MAX], cacheDirParticles[FILE_MAX];
cacheDirData[0] = '\0';
cacheDirParticles[0] = '\0';
- std::string dformat = getCacheFileEnding(mmd->domain->cache_data_format);
- std::string pformat = getCacheFileEnding(mmd->domain->cache_particle_format);
+ string dformat = getCacheFileEnding(mds->cache_data_format);
+ string pformat = getCacheFileEnding(mds->cache_particle_format);
- bool final_cache = (mmd->domain->cache_type == FLUID_DOMAIN_CACHE_FINAL);
- std::string resumable_cache = (final_cache) ? "False" : "True";
+ bool final_cache = (mds->cache_type == FLUID_DOMAIN_CACHE_FINAL);
+ string resumable_cache = (final_cache) ? "False" : "True";
- BLI_path_join(cacheDirData,
- sizeof(cacheDirData),
- mmd->domain->cache_directory,
- FLUID_DOMAIN_DIR_DATA,
- nullptr);
+ BLI_path_join(
+ cacheDirData, sizeof(cacheDirData), mds->cache_directory, FLUID_DOMAIN_DIR_DATA, nullptr);
BLI_path_join(cacheDirParticles,
sizeof(cacheDirParticles),
- mmd->domain->cache_directory,
+ mds->cache_directory,
FLUID_DOMAIN_DIR_PARTICLES,
nullptr);
BLI_path_make_safe(cacheDirData);
@@ -1845,22 +1691,23 @@ bool MANTA::bakeParticles(FluidModifierData *mmd, int framenr)
bool MANTA::bakeGuiding(FluidModifierData *mmd, int framenr)
{
if (with_debug)
- std::cout << "MANTA::bakeGuiding()" << std::endl;
+ cout << "MANTA::bakeGuiding()" << endl;
- std::ostringstream ss;
- std::vector<std::string> pythonCommands;
+ ostringstream ss;
+ vector<string> pythonCommands;
+ FluidDomainSettings *mds = mmd->domain;
char cacheDirGuiding[FILE_MAX];
cacheDirGuiding[0] = '\0';
- std::string gformat = getCacheFileEnding(mmd->domain->cache_data_format);
+ string gformat = getCacheFileEnding(mds->cache_data_format);
- bool final_cache = (mmd->domain->cache_type == FLUID_DOMAIN_CACHE_FINAL);
- std::string resumable_cache = (final_cache) ? "False" : "True";
+ bool final_cache = (mds->cache_type == FLUID_DOMAIN_CACHE_FINAL);
+ string resumable_cache = (final_cache) ? "False" : "True";
BLI_path_join(cacheDirGuiding,
sizeof(cacheDirGuiding),
- mmd->domain->cache_directory,
+ mds->cache_directory,
FLUID_DOMAIN_DIR_GUIDE,
nullptr);
BLI_path_make_safe(cacheDirGuiding);
@@ -1875,8 +1722,8 @@ bool MANTA::bakeGuiding(FluidModifierData *mmd, int framenr)
bool MANTA::updateVariables(FluidModifierData *mmd)
{
- std::string tmpString, finalString;
- std::vector<std::string> pythonCommands;
+ string tmpString, finalString;
+ vector<string> pythonCommands;
tmpString += fluid_variables;
if (mUsingSmoke)
@@ -1906,13 +1753,15 @@ bool MANTA::updateVariables(FluidModifierData *mmd)
void MANTA::exportSmokeScript(FluidModifierData *mmd)
{
if (with_debug)
- std::cout << "MANTA::exportSmokeScript()" << std::endl;
+ cout << "MANTA::exportSmokeScript()" << endl;
char cacheDir[FILE_MAX] = "\0";
char cacheDirScript[FILE_MAX] = "\0";
+ FluidDomainSettings *mds = mmd->domain;
+
BLI_path_join(
- cacheDir, sizeof(cacheDir), mmd->domain->cache_directory, FLUID_DOMAIN_DIR_SCRIPT, nullptr);
+ cacheDir, sizeof(cacheDir), mds->cache_directory, FLUID_DOMAIN_DIR_SCRIPT, nullptr);
BLI_path_make_safe(cacheDir);
/* Create 'script' subdir if it does not exist already */
BLI_dir_create_recursive(cacheDir);
@@ -1920,16 +1769,16 @@ void MANTA::exportSmokeScript(FluidModifierData *mmd)
cacheDirScript, sizeof(cacheDirScript), cacheDir, FLUID_DOMAIN_SMOKE_SCRIPT, nullptr);
BLI_path_make_safe(cacheDir);
- bool noise = mmd->domain->flags & FLUID_DOMAIN_USE_NOISE;
- bool heat = mmd->domain->active_fields & FLUID_DOMAIN_ACTIVE_HEAT;
- bool colors = mmd->domain->active_fields & FLUID_DOMAIN_ACTIVE_COLORS;
- bool fire = mmd->domain->active_fields & FLUID_DOMAIN_ACTIVE_FIRE;
- bool obstacle = mmd->domain->active_fields & FLUID_DOMAIN_ACTIVE_OBSTACLE;
- bool guiding = mmd->domain->active_fields & FLUID_DOMAIN_ACTIVE_GUIDE;
- bool invel = mmd->domain->active_fields & FLUID_DOMAIN_ACTIVE_INVEL;
- bool outflow = mmd->domain->active_fields & FLUID_DOMAIN_ACTIVE_OUTFLOW;
+ bool noise = mds->flags & FLUID_DOMAIN_USE_NOISE;
+ bool heat = mds->active_fields & FLUID_DOMAIN_ACTIVE_HEAT;
+ bool colors = mds->active_fields & FLUID_DOMAIN_ACTIVE_COLORS;
+ bool fire = mds->active_fields & FLUID_DOMAIN_ACTIVE_FIRE;
+ bool obstacle = mds->active_fields & FLUID_DOMAIN_ACTIVE_OBSTACLE;
+ bool guiding = mds->active_fields & FLUID_DOMAIN_ACTIVE_GUIDE;
+ bool invel = mds->active_fields & FLUID_DOMAIN_ACTIVE_INVEL;
+ bool outflow = mds->active_fields & FLUID_DOMAIN_ACTIVE_OUTFLOW;
- std::string manta_script;
+ string manta_script;
// Libraries
manta_script += header_libraries + manta_import;
@@ -2001,10 +1850,10 @@ void MANTA::exportSmokeScript(FluidModifierData *mmd)
manta_script += header_main + smoke_standalone + fluid_standalone;
// Fill in missing variables in script
- std::string final_script = MANTA::parseScript(manta_script, mmd);
+ string final_script = MANTA::parseScript(manta_script, mmd);
// Write script
- std::ofstream myfile;
+ ofstream myfile;
myfile.open(cacheDirScript);
myfile << final_script;
myfile.close();
@@ -2013,13 +1862,15 @@ void MANTA::exportSmokeScript(FluidModifierData *mmd)
void MANTA::exportLiquidScript(FluidModifierData *mmd)
{
if (with_debug)
- std::cout << "MANTA::exportLiquidScript()" << std::endl;
+ cout << "MANTA::exportLiquidScript()" << endl;
char cacheDir[FILE_MAX] = "\0";
char cacheDirScript[FILE_MAX] = "\0";
+ FluidDomainSettings *mds = mmd->domain;
+
BLI_path_join(
- cacheDir, sizeof(cacheDir), mmd->domain->cache_directory, FLUID_DOMAIN_DIR_SCRIPT, nullptr);
+ cacheDir, sizeof(cacheDir), mds->cache_directory, FLUID_DOMAIN_DIR_SCRIPT, nullptr);
BLI_path_make_safe(cacheDir);
/* Create 'script' subdir if it does not exist already */
BLI_dir_create_recursive(cacheDir);
@@ -2027,18 +1878,18 @@ void MANTA::exportLiquidScript(FluidModifierData *mmd)
cacheDirScript, sizeof(cacheDirScript), cacheDir, FLUID_DOMAIN_LIQUID_SCRIPT, nullptr);
BLI_path_make_safe(cacheDirScript);
- bool mesh = mmd->domain->flags & FLUID_DOMAIN_USE_MESH;
- bool drops = mmd->domain->particle_type & FLUID_DOMAIN_PARTICLE_SPRAY;
- bool bubble = mmd->domain->particle_type & FLUID_DOMAIN_PARTICLE_BUBBLE;
- bool floater = mmd->domain->particle_type & FLUID_DOMAIN_PARTICLE_FOAM;
- bool tracer = mmd->domain->particle_type & FLUID_DOMAIN_PARTICLE_TRACER;
- bool obstacle = mmd->domain->active_fields & FLUID_DOMAIN_ACTIVE_OBSTACLE;
- bool fractions = mmd->domain->flags & FLUID_DOMAIN_USE_FRACTIONS;
- bool guiding = mmd->domain->active_fields & FLUID_DOMAIN_ACTIVE_GUIDE;
- bool invel = mmd->domain->active_fields & FLUID_DOMAIN_ACTIVE_INVEL;
- bool outflow = mmd->domain->active_fields & FLUID_DOMAIN_ACTIVE_OUTFLOW;
+ bool mesh = mds->flags & FLUID_DOMAIN_USE_MESH;
+ bool drops = mds->particle_type & FLUID_DOMAIN_PARTICLE_SPRAY;
+ bool bubble = mds->particle_type & FLUID_DOMAIN_PARTICLE_BUBBLE;
+ bool floater = mds->particle_type & FLUID_DOMAIN_PARTICLE_FOAM;
+ bool tracer = mds->particle_type & FLUID_DOMAIN_PARTICLE_TRACER;
+ bool obstacle = mds->active_fields & FLUID_DOMAIN_ACTIVE_OBSTACLE;
+ bool fractions = mds->flags & FLUID_DOMAIN_USE_FRACTIONS;
+ bool guiding = mds->active_fields & FLUID_DOMAIN_ACTIVE_GUIDE;
+ bool invel = mds->active_fields & FLUID_DOMAIN_ACTIVE_INVEL;
+ bool outflow = mds->active_fields & FLUID_DOMAIN_ACTIVE_OUTFLOW;
- std::string manta_script;
+ string manta_script;
// Libraries
manta_script += header_libraries + manta_import;
@@ -2108,10 +1959,10 @@ void MANTA::exportLiquidScript(FluidModifierData *mmd)
manta_script += header_main + liquid_standalone + fluid_standalone;
// Fill in missing variables in script
- std::string final_script = MANTA::parseScript(manta_script, mmd);
+ string final_script = MANTA::parseScript(manta_script, mmd);
// Write script
- std::ofstream myfile;
+ ofstream myfile;
myfile.open(cacheDirScript);
myfile << final_script;
myfile.close();
@@ -2124,14 +1975,12 @@ void MANTA::exportLiquidScript(FluidModifierData *mmd)
*
* Important! Return value: New reference or nullptr
* Caller of this function needs to handle reference count of returned object. */
-static PyObject *callPythonFunction(std::string varName,
- std::string functionName,
- bool isAttribute = false)
+static PyObject *callPythonFunction(string varName, string functionName, bool isAttribute = false)
{
if ((varName == "") || (functionName == "")) {
if (MANTA::with_debug)
- std::cout << "Missing Python variable name and/or function name -- name is: " << varName
- << ", function name is: " << functionName << std::endl;
+ cout << "Missing Python variable name and/or function name -- name is: " << varName
+ << ", function name is: " << functionName << endl;
return nullptr;
}
@@ -2185,8 +2034,8 @@ static void *pyObjectToPointer(PyObject *inputObject)
Py_DECREF(inputObject);
- std::string str(result);
- std::istringstream in(str);
+ string str(result);
+ istringstream in(str);
void *dataPointer = nullptr;
in >> dataPointer;
@@ -2233,11 +2082,11 @@ static long pyObjectToLong(PyObject *inputObject)
int MANTA::getFrame()
{
if (with_debug)
- std::cout << "MANTA::getFrame()" << std::endl;
+ cout << "MANTA::getFrame()" << endl;
- std::string func = "frame";
- std::string id = std::to_string(mCurrentID);
- std::string solver = "s" + id;
+ string func = "frame";
+ string id = to_string(mCurrentID);
+ string solver = "s" + id;
return pyObjectToLong(callPythonFunction(solver, func, true));
}
@@ -2245,11 +2094,11 @@ int MANTA::getFrame()
float MANTA::getTimestep()
{
if (with_debug)
- std::cout << "MANTA::getTimestep()" << std::endl;
+ cout << "MANTA::getTimestep()" << endl;
- std::string func = "timestep";
- std::string id = std::to_string(mCurrentID);
- std::string solver = "s" + id;
+ string func = "timestep";
+ string id = to_string(mCurrentID);
+ string solver = "s" + id;
return (float)pyObjectToDouble(callPythonFunction(solver, func, true));
}
@@ -2263,10 +2112,10 @@ bool MANTA::needsRealloc(FluidModifierData *mmd)
void MANTA::adaptTimestep()
{
if (with_debug)
- std::cout << "MANTA::adaptTimestep()" << std::endl;
+ cout << "MANTA::adaptTimestep()" << endl;
- std::vector<std::string> pythonCommands;
- std::ostringstream ss;
+ vector<string> pythonCommands;
+ ostringstream ss;
ss << "fluid_adapt_time_step_" << mCurrentID << "()";
pythonCommands.push_back(ss.str());
@@ -2274,14 +2123,14 @@ void MANTA::adaptTimestep()
runPythonString(pythonCommands);
}
-bool MANTA::updateMeshFromFile(std::string filename)
+bool MANTA::updateMeshFromFile(string filename)
{
- std::string fname(filename);
- std::string::size_type idx;
+ string fname(filename);
+ string::size_type idx;
idx = fname.rfind('.');
- if (idx != std::string::npos) {
- std::string extension = fname.substr(idx + 1);
+ if (idx != string::npos) {
+ string extension = fname.substr(idx + 1);
if (extension.compare("gz") == 0)
return updateMeshFromBobj(filename);
@@ -2290,27 +2139,25 @@ bool MANTA::updateMeshFromFile(std::string filename)
else if (extension.compare("uni") == 0)
return updateMeshFromUni(filename);
else
- std::cerr << "Fluid Error -- updateMeshFromFile(): Invalid file extension in file: "
- << filename << std::endl;
+ cerr << "Fluid Error -- updateMeshFromFile(): Invalid file extension in file: " << filename
+ << endl;
}
else {
- std::cerr << "Fluid Error -- updateMeshFromFile(): Unable to open file: " << filename
- << std::endl;
+ cerr << "Fluid Error -- updateMeshFromFile(): Unable to open file: " << filename << endl;
}
return false;
}
-bool MANTA::updateMeshFromBobj(std::string filename)
+bool MANTA::updateMeshFromBobj(string filename)
{
if (with_debug)
- std::cout << "MANTA::updateMeshFromBobj()" << std::endl;
+ cout << "MANTA::updateMeshFromBobj()" << endl;
gzFile gzf;
gzf = (gzFile)BLI_gzopen(filename.c_str(), "rb1"); // do some compression
if (!gzf) {
- std::cerr << "Fluid Error -- updateMeshFromBobj(): Unable to open file: " << filename
- << std::endl;
+ cerr << "Fluid Error -- updateMeshFromBobj(): Unable to open file: " << filename << endl;
return false;
}
@@ -2319,15 +2166,14 @@ bool MANTA::updateMeshFromBobj(std::string filename)
// Num vertices
readBytes = gzread(gzf, &numBuffer, sizeof(int));
if (!readBytes) {
- std::cerr
- << "Fluid Error -- updateMeshFromBobj(): Unable to read number of mesh vertices from "
- << filename << std::endl;
+ cerr << "Fluid Error -- updateMeshFromBobj(): Unable to read number of mesh vertices from "
+ << filename << endl;
gzclose(gzf);
return false;
}
if (with_debug)
- std::cout << "read mesh , num verts: " << numBuffer << " , in file: " << filename << std::endl;
+ cout << "read mesh , num verts: " << numBuffer << " , in file: " << filename << endl;
int numChunks = (int)(ceil((float)numBuffer / NODE_CHUNK));
int readLen, readStart, readEnd, k;
@@ -2348,8 +2194,8 @@ bool MANTA::updateMeshFromBobj(std::string filename)
readBytes = gzread(gzf, bufferVerts, readLen * sizeof(float) * 3);
if (!readBytes) {
- std::cerr << "Fluid Error -- updateMeshFromBobj(): Unable to read mesh vertices from "
- << filename << std::endl;
+ cerr << "Fluid Error -- updateMeshFromBobj(): Unable to read mesh vertices from "
+ << filename << endl;
MEM_freeN(bufferVerts);
gzclose(gzf);
return false;
@@ -2361,7 +2207,7 @@ bool MANTA::updateMeshFromBobj(std::string filename)
CLAMP(readEnd, 0, numBuffer);
k = 0;
- for (std::vector<MANTA::Node>::size_type j = readStart; j < readEnd; j++, k += 3) {
+ for (vector<MANTA::Node>::size_type j = readStart; j < readEnd; j++, k += 3) {
mMeshNodes->at(j).pos[0] = bufferVerts[k];
mMeshNodes->at(j).pos[1] = bufferVerts[k + 1];
mMeshNodes->at(j).pos[2] = bufferVerts[k + 2];
@@ -2374,15 +2220,14 @@ bool MANTA::updateMeshFromBobj(std::string filename)
// Num normals
readBytes = gzread(gzf, &numBuffer, sizeof(int));
if (!readBytes) {
- std::cerr << "Fluid Error -- updateMeshFromBobj(): Unable to read number of mesh normals from "
- << filename << std::endl;
+ cerr << "Fluid Error -- updateMeshFromBobj(): Unable to read number of mesh normals from "
+ << filename << endl;
gzclose(gzf);
return false;
}
if (with_debug)
- std::cout << "read mesh , num normals : " << numBuffer << " , in file: " << filename
- << std::endl;
+ cout << "read mesh , num normals : " << numBuffer << " , in file: " << filename << endl;
if (numBuffer) {
// Normals
@@ -2401,8 +2246,8 @@ bool MANTA::updateMeshFromBobj(std::string filename)
readBytes = gzread(gzf, bufferNormals, readLen * sizeof(float) * 3);
if (!readBytes) {
- std::cerr << "Fluid Error -- updateMeshFromBobj(): Unable to read mesh normals from "
- << filename << std::endl;
+ cerr << "Fluid Error -- updateMeshFromBobj(): Unable to read mesh normals from "
+ << filename << endl;
MEM_freeN(bufferNormals);
gzclose(gzf);
return false;
@@ -2414,7 +2259,7 @@ bool MANTA::updateMeshFromBobj(std::string filename)
CLAMP(readEnd, 0, numBuffer);
k = 0;
- for (std::vector<MANTA::Node>::size_type j = readStart; j < readEnd; j++, k += 3) {
+ for (vector<MANTA::Node>::size_type j = readStart; j < readEnd; j++, k += 3) {
mMeshNodes->at(j).normal[0] = bufferNormals[k];
mMeshNodes->at(j).normal[1] = bufferNormals[k + 1];
mMeshNodes->at(j).normal[2] = bufferNormals[k + 2];
@@ -2427,16 +2272,15 @@ bool MANTA::updateMeshFromBobj(std::string filename)
// Num triangles
readBytes = gzread(gzf, &numBuffer, sizeof(int));
if (!readBytes) {
- std::cerr
- << "Fluid Error -- updateMeshFromBobj(): Unable to read number of mesh triangles from "
- << filename << std::endl;
+ cerr << "Fluid Error -- updateMeshFromBobj(): Unable to read number of mesh triangles from "
+ << filename << endl;
gzclose(gzf);
return false;
}
if (with_debug)
- std::cout << "Fluid: Read mesh , num triangles : " << numBuffer << " , in file: " << filename
- << std::endl;
+ cout << "Fluid: Read mesh , num triangles : " << numBuffer << " , in file: " << filename
+ << endl;
numChunks = (int)(ceil((float)numBuffer / TRIANGLE_CHUNK));
@@ -2456,8 +2300,8 @@ bool MANTA::updateMeshFromBobj(std::string filename)
readBytes = gzread(gzf, bufferTriangles, readLen * sizeof(int) * 3);
if (!readBytes) {
- std::cerr << "Fluid Error -- updateMeshFromBobj(): Unable to read mesh triangles from "
- << filename << std::endl;
+ cerr << "Fluid Error -- updateMeshFromBobj(): Unable to read mesh triangles from "
+ << filename << endl;
MEM_freeN(bufferTriangles);
gzclose(gzf);
return false;
@@ -2469,7 +2313,7 @@ bool MANTA::updateMeshFromBobj(std::string filename)
CLAMP(readEnd, 0, numBuffer);
k = 0;
- for (std::vector<MANTA::Triangle>::size_type j = readStart; j < readEnd; j++, k += 3) {
+ for (vector<MANTA::Triangle>::size_type j = readStart; j < readEnd; j++, k += 3) {
mMeshTriangles->at(j).c[0] = bufferTriangles[k];
mMeshTriangles->at(j).c[1] = bufferTriangles[k + 1];
mMeshTriangles->at(j).c[2] = bufferTriangles[k + 2];
@@ -2481,24 +2325,23 @@ bool MANTA::updateMeshFromBobj(std::string filename)
return (gzclose(gzf) == Z_OK);
}
-bool MANTA::updateMeshFromObj(std::string filename)
+bool MANTA::updateMeshFromObj(string filename)
{
if (with_debug)
- std::cout << "MANTA::updateMeshFromObj()" << std::endl;
+ cout << "MANTA::updateMeshFromObj()" << endl;
- std::ifstream ifs(filename);
+ ifstream ifs(filename);
float fbuffer[3];
int ibuffer[3];
int cntVerts = 0, cntNormals = 0, cntTris = 0;
if (!ifs.good()) {
- std::cerr << "Fluid Error -- updateMeshFromObj(): Unable to open file: " << filename
- << std::endl;
+ cerr << "Fluid Error -- updateMeshFromObj(): Unable to open file: " << filename << endl;
return false;
}
while (ifs.good() && !ifs.eof()) {
- std::string id;
+ string id;
ifs >> id;
if (id[0] == '#') {
@@ -2512,8 +2355,8 @@ bool MANTA::updateMeshFromObj(std::string filename)
else if (id == "vn") {
// normals
if (getNumVertices() != cntVerts) {
- std::cerr << "Fluid Error -- updateMeshFromObj(): Invalid number of mesh nodes in file: "
- << filename << std::endl;
+ cerr << "Fluid Error -- updateMeshFromObj(): Invalid number of mesh nodes in file: "
+ << filename << endl;
return false;
}
@@ -2536,20 +2379,20 @@ bool MANTA::updateMeshFromObj(std::string filename)
}
else if (id == "g") {
// group
- std::string group;
+ string group;
ifs >> group;
}
else if (id == "f") {
// face
- std::string face;
+ string face;
for (int i = 0; i < 3; i++) {
ifs >> face;
- if (face.find('/') != std::string::npos)
+ if (face.find('/') != string::npos)
face = face.substr(0, face.find('/')); // ignore other indices
int idx = atoi(face.c_str()) - 1;
if (idx < 0) {
- std::cerr << "Fluid Error -- updateMeshFromObj(): Invalid face encountered in file: "
- << filename << std::endl;
+ cerr << "Fluid Error -- updateMeshFromObj(): Invalid face encountered in file: "
+ << filename << endl;
return false;
}
ibuffer[i] = idx;
@@ -2571,10 +2414,10 @@ bool MANTA::updateMeshFromObj(std::string filename)
return true;
}
-bool MANTA::updateMeshFromUni(std::string filename)
+bool MANTA::updateMeshFromUni(string filename)
{
if (with_debug)
- std::cout << "MANTA::updateMeshFromUni()" << std::endl;
+ cout << "MANTA::updateMeshFromUni()" << endl;
gzFile gzf;
float fbuffer[4];
@@ -2582,8 +2425,7 @@ bool MANTA::updateMeshFromUni(std::string filename)
gzf = (gzFile)BLI_gzopen(filename.c_str(), "rb1"); // do some compression
if (!gzf) {
- std::cerr << "Fluid Error -- updateMeshFromUni(): Unable to open file: " << filename
- << std::endl;
+ cerr << "Fluid Error -- updateMeshFromUni(): Unable to open file: " << filename << endl;
return false;
}
@@ -2591,13 +2433,13 @@ bool MANTA::updateMeshFromUni(std::string filename)
char file_magic[5] = {0, 0, 0, 0, 0};
readBytes = gzread(gzf, file_magic, 4);
if (!readBytes) {
- std::cerr << "Fluid Error -- updateMeshFromUni(): Unable to read header in file: " << filename
- << std::endl;
+ cerr << "Fluid Error -- updateMeshFromUni(): Unable to read header in file: " << filename
+ << endl;
gzclose(gzf);
return false;
}
- std::vector<pVel> *velocityPointer = mMeshVelocities;
+ vector<pVel> *velocityPointer = mMeshVelocities;
// mdata uni header
const int STR_LEN_PDATA = 256;
@@ -2613,19 +2455,18 @@ bool MANTA::updateMeshFromUni(std::string filename)
gzread(gzf, &timestamp, sizeof(unsigned long long));
if (with_debug)
- std::cout << "Fluid: Read " << ibuffer[0] << " vertices in file: " << filename << std::endl;
+ cout << "Fluid: Read " << ibuffer[0] << " vertices in file: " << filename << endl;
// Sanity checks
const int meshSize = sizeof(float) * 3 + sizeof(int);
if (!(bytesPerElement == meshSize) && (elementType == 0)) {
- std::cerr << "Fluid Error -- updateMeshFromUni(): Invalid header in file: " << filename
- << std::endl;
+ cerr << "Fluid Error -- updateMeshFromUni(): Invalid header in file: " << filename << endl;
gzclose(gzf);
return false;
}
if (!ibuffer[0]) { // Any vertices present?
- std::cerr << "Fluid Error -- updateMeshFromUni(): No vertices present in file: " << filename
- << std::endl;
+ cerr << "Fluid Error -- updateMeshFromUni(): No vertices present in file: " << filename
+ << endl;
gzclose(gzf);
return false;
}
@@ -2640,7 +2481,7 @@ bool MANTA::updateMeshFromUni(std::string filename)
velocityPointer->resize(numParticles);
MANTA::pVel *bufferPVel;
- for (std::vector<pVel>::iterator it = velocityPointer->begin(); it != velocityPointer->end();
+ for (vector<pVel>::iterator it = velocityPointer->begin(); it != velocityPointer->end();
++it) {
gzread(gzf, fbuffer, sizeof(float) * 3);
bufferPVel = (MANTA::pVel *)fbuffer;
@@ -2652,44 +2493,42 @@ bool MANTA::updateMeshFromUni(std::string filename)
return (gzclose(gzf) == Z_OK);
}
-bool MANTA::updateParticlesFromFile(std::string filename, bool isSecondarySys, bool isVelData)
+bool MANTA::updateParticlesFromFile(string filename, bool isSecondarySys, bool isVelData)
{
if (with_debug)
- std::cout << "MANTA::updateParticlesFromFile()" << std::endl;
+ cout << "MANTA::updateParticlesFromFile()" << endl;
- std::string fname(filename);
- std::string::size_type idx;
+ string fname(filename);
+ string::size_type idx;
idx = fname.rfind('.');
- if (idx != std::string::npos) {
- std::string extension = fname.substr(idx + 1);
+ if (idx != string::npos) {
+ string extension = fname.substr(idx + 1);
if (extension.compare("uni") == 0)
return updateParticlesFromUni(filename, isSecondarySys, isVelData);
else
- std::cerr << "Fluid Error -- updateParticlesFromFile(): Invalid file extension in file: "
- << filename << std::endl;
+ cerr << "Fluid Error -- updateParticlesFromFile(): Invalid file extension in file: "
+ << filename << endl;
return false;
}
else {
- std::cerr << "Fluid Error -- updateParticlesFromFile(): Unable to open file: " << filename
- << std::endl;
+ cerr << "Fluid Error -- updateParticlesFromFile(): Unable to open file: " << filename << endl;
return false;
}
}
-bool MANTA::updateParticlesFromUni(std::string filename, bool isSecondarySys, bool isVelData)
+bool MANTA::updateParticlesFromUni(string filename, bool isSecondarySys, bool isVelData)
{
if (with_debug)
- std::cout << "MANTA::updateParticlesFromUni()" << std::endl;
+ cout << "MANTA::updateParticlesFromUni()" << endl;
gzFile gzf;
int ibuffer[4];
gzf = (gzFile)BLI_gzopen(filename.c_str(), "rb1"); // do some compression
if (!gzf) {
- std::cerr << "Fluid Error -- updateParticlesFromUni(): Unable to open file: " << filename
- << std::endl;
+ cerr << "Fluid Error -- updateParticlesFromUni(): Unable to open file: " << filename << endl;
return false;
}
@@ -2697,24 +2536,24 @@ bool MANTA::updateParticlesFromUni(std::string filename, bool isSecondarySys, bo
char file_magic[5] = {0, 0, 0, 0, 0};
readBytes = gzread(gzf, file_magic, 4);
if (!readBytes) {
- std::cerr << "Fluid Error -- updateParticlesFromUni(): Unable to read header in file: "
- << filename << std::endl;
+ cerr << "Fluid Error -- updateParticlesFromUni(): Unable to read header in file: " << filename
+ << endl;
gzclose(gzf);
return false;
}
if (!strcmp(file_magic, "PB01")) {
- std::cerr << "Fluid Error -- updateParticlesFromUni(): Particle uni file format v01 not "
- "supported anymore."
- << std::endl;
+ cerr << "Fluid Error -- updateParticlesFromUni(): Particle uni file format v01 not "
+ "supported anymore."
+ << endl;
gzclose(gzf);
return false;
}
// Pointer to FLIP system or to secondary particle system
- std::vector<pData> *dataPointer = nullptr;
- std::vector<pVel> *velocityPointer = nullptr;
- std::vector<float> *lifePointer = nullptr;
+ vector<pData> *dataPointer = nullptr;
+ vector<pVel> *velocityPointer = nullptr;
+ vector<float> *lifePointer = nullptr;
if (isSecondarySys) {
dataPointer = mSndParticleData;
@@ -2740,19 +2579,19 @@ bool MANTA::updateParticlesFromUni(std::string filename, bool isSecondarySys, bo
gzread(gzf, &timestamp, sizeof(unsigned long long));
if (with_debug)
- std::cout << "Fluid: Read " << ibuffer[0] << " particles in file: " << filename << std::endl;
+ cout << "Fluid: Read " << ibuffer[0] << " particles in file: " << filename << endl;
// Sanity checks
const int partSysSize = sizeof(float) * 3 + sizeof(int);
if (!(bytesPerElement == partSysSize) && (elementType == 0)) {
- std::cerr << "Fluid Error -- updateParticlesFromUni(): Invalid header in file: " << filename
- << std::endl;
+ cerr << "Fluid Error -- updateParticlesFromUni(): Invalid header in file: " << filename
+ << endl;
gzclose(gzf);
return false;
}
if (!ibuffer[0]) { // Any particles present?
if (with_debug)
- std::cout << "Fluid: No particles present in file: " << filename << std::endl;
+ cout << "Fluid: No particles present in file: " << filename << endl;
gzclose(gzf);
return true; // return true since having no particles in a cache file is valid
}
@@ -2780,9 +2619,8 @@ bool MANTA::updateParticlesFromUni(std::string filename, bool isSecondarySys, bo
readBytes = gzread(gzf, bufferPData, readLen * sizeof(pData));
if (!readBytes) {
- std::cerr
- << "Fluid Error -- updateParticlesFromUni(): Unable to read particle data in file: "
- << filename << std::endl;
+ cerr << "Fluid Error -- updateParticlesFromUni(): Unable to read particle data in file: "
+ << filename << endl;
MEM_freeN(bufferPData);
gzclose(gzf);
return false;
@@ -2794,7 +2632,7 @@ bool MANTA::updateParticlesFromUni(std::string filename, bool isSecondarySys, bo
CLAMP(readEnd, 0, numParticles);
int k = 0;
- for (std::vector<MANTA::pData>::size_type j = readStart; j < readEnd; j++, k++) {
+ for (vector<MANTA::pData>::size_type j = readStart; j < readEnd; j++, k++) {
dataPointer->at(j).pos[0] = bufferPData[k].pos[0];
dataPointer->at(j).pos[1] = bufferPData[k].pos[1];
dataPointer->at(j).pos[2] = bufferPData[k].pos[2];
@@ -2821,9 +2659,9 @@ bool MANTA::updateParticlesFromUni(std::string filename, bool isSecondarySys, bo
readBytes = gzread(gzf, bufferPVel, readLen * sizeof(pVel));
if (!readBytes) {
- std::cerr << "Fluid Error -- updateParticlesFromUni(): Unable to read particle velocities "
- "in file: "
- << filename << std::endl;
+ cerr << "Fluid Error -- updateParticlesFromUni(): Unable to read particle velocities "
+ "in file: "
+ << filename << endl;
MEM_freeN(bufferPVel);
gzclose(gzf);
return false;
@@ -2835,7 +2673,7 @@ bool MANTA::updateParticlesFromUni(std::string filename, bool isSecondarySys, bo
CLAMP(readEnd, 0, numParticles);
int k = 0;
- for (std::vector<MANTA::pVel>::size_type j = readStart; j < readEnd; j++, k++) {
+ for (vector<MANTA::pVel>::size_type j = readStart; j < readEnd; j++, k++) {
velocityPointer->at(j).pos[0] = bufferPVel[k].pos[0];
velocityPointer->at(j).pos[1] = bufferPVel[k].pos[1];
velocityPointer->at(j).pos[2] = bufferPVel[k].pos[2];
@@ -2860,9 +2698,8 @@ bool MANTA::updateParticlesFromUni(std::string filename, bool isSecondarySys, bo
readBytes = gzread(gzf, bufferPLife, readLen * sizeof(float));
if (!readBytes) {
- std::cerr
- << "Fluid Error -- updateParticlesFromUni(): Unable to read particle life in file: "
- << filename << std::endl;
+ cerr << "Fluid Error -- updateParticlesFromUni(): Unable to read particle life in file: "
+ << filename << endl;
MEM_freeN(bufferPLife);
gzclose(gzf);
return false;
@@ -2874,7 +2711,7 @@ bool MANTA::updateParticlesFromUni(std::string filename, bool isSecondarySys, bo
CLAMP(readEnd, 0, numParticles);
int k = 0;
- for (std::vector<float>::size_type j = readStart; j < readEnd; j++, k++) {
+ for (vector<float>::size_type j = readStart; j < readEnd; j++, k++) {
lifePointer->at(j) = bufferPLife[k];
}
todoParticles -= readLen;
@@ -2884,24 +2721,24 @@ bool MANTA::updateParticlesFromUni(std::string filename, bool isSecondarySys, bo
return (gzclose(gzf) == Z_OK);
}
-bool MANTA::updateGridFromFile(std::string filename, float *grid, bool isNoise)
+bool MANTA::updateGridFromFile(string filename, float *grid, bool isNoise)
{
if (with_debug)
- std::cout << "MANTA::updateGridFromFile()" << std::endl;
+ cout << "MANTA::updateGridFromFile()" << endl;
if (!grid) {
- std::cerr << "Fluid Error -- updateGridFromFile(): Cannot read into uninitialized grid (grid "
- "is null)."
- << std::endl;
+ cerr << "Fluid Error -- updateGridFromFile(): Cannot read into uninitialized grid (grid "
+ "is null)."
+ << endl;
return false;
}
- std::string fname(filename);
- std::string::size_type idx;
+ string fname(filename);
+ string::size_type idx;
idx = fname.rfind('.');
- if (idx != std::string::npos) {
- std::string extension = fname.substr(idx + 1);
+ if (idx != string::npos) {
+ string extension = fname.substr(idx + 1);
if (extension.compare("uni") == 0)
return updateGridFromUni(filename, grid, isNoise);
@@ -2912,29 +2749,27 @@ bool MANTA::updateGridFromFile(std::string filename, float *grid, bool isNoise)
else if (extension.compare("raw") == 0)
return updateGridFromRaw(filename, grid, isNoise);
else
- std::cerr << "Fluid Error -- updateGridFromFile(): Invalid file extension in file: "
- << filename << std::endl;
+ cerr << "Fluid Error -- updateGridFromFile(): Invalid file extension in file: " << filename
+ << endl;
return false;
}
else {
- std::cerr << "Fluid Error -- updateGridFromFile(): Unable to open file: " << filename
- << std::endl;
+ cerr << "Fluid Error -- updateGridFromFile(): Unable to open file: " << filename << endl;
return false;
}
}
-bool MANTA::updateGridFromUni(std::string filename, float *grid, bool isNoise)
+bool MANTA::updateGridFromUni(string filename, float *grid, bool isNoise)
{
if (with_debug)
- std::cout << "MANTA::updateGridFromUni()" << std::endl;
+ cout << "MANTA::updateGridFromUni()" << endl;
gzFile gzf;
int ibuffer[4];
gzf = (gzFile)BLI_gzopen(filename.c_str(), "rb1");
if (!gzf) {
- std::cerr << "Fluid Error -- updateGridFromUni(): Unable to open file: " << filename
- << std::endl;
+ cerr << "Fluid Error -- updateGridFromUni(): Unable to open file: " << filename << endl;
return false;
}
@@ -2942,32 +2777,29 @@ bool MANTA::updateGridFromUni(std::string filename, float *grid, bool isNoise)
char file_magic[5] = {0, 0, 0, 0, 0};
readBytes = gzread(gzf, file_magic, 4);
if (!readBytes) {
- std::cerr << "Fluid Error -- updateGridFromUni(): Unable to read header in file: " << filename
- << std::endl;
+ cerr << "Fluid Error -- updateGridFromUni(): Unable to read header in file: " << filename
+ << endl;
gzclose(gzf);
return false;
}
if (!strcmp(file_magic, "DDF2")) {
- std::cerr
- << "Fluid Error -- updateGridFromUni(): Grid uni file format DDF2 not supported anymore."
- << std::endl;
+ cerr << "Fluid Error -- updateGridFromUni(): Grid uni file format DDF2 not supported anymore."
+ << endl;
gzclose(gzf);
return false;
}
if (!strcmp(file_magic, "MNT1")) {
- std::cerr
- << "Fluid Error -- updateGridFromUni(): Grid uni file format MNT1 not supported anymore."
- << std::endl;
+ cerr << "Fluid Error -- updateGridFromUni(): Grid uni file format MNT1 not supported anymore."
+ << endl;
gzclose(gzf);
return false;
}
if (!strcmp(file_magic, "MNT2")) {
- std::cerr
- << "Fluid Error -- updateGridFromUni(): Grid uni file format MNT2 not supported anymore."
- << std::endl;
+ cerr << "Fluid Error -- updateGridFromUni(): Grid uni file format MNT2 not supported anymore."
+ << endl;
gzclose(gzf);
return false;
}
@@ -2992,13 +2824,12 @@ bool MANTA::updateGridFromUni(std::string filename, float *grid, bool isNoise)
int resZ = (isNoise) ? mResZNoise : mResZ;
if (with_debug)
- std::cout << "Fluid: Read " << ibuffer[3] << " grid type in file: " << filename << std::endl;
+ cout << "Fluid: Read " << ibuffer[3] << " grid type in file: " << filename << endl;
// Sanity checks
if (ibuffer[0] != resX || ibuffer[1] != resY || ibuffer[2] != resZ) {
- std::cout << "Fluid: Grid dim doesn't match, read: (" << ibuffer[0] << ", " << ibuffer[1]
- << ", " << ibuffer[2] << ") vs setup: (" << resX << ", " << resY << ", " << resZ
- << ")" << std::endl;
+ cout << "Fluid: Grid dim doesn't match, read: (" << ibuffer[0] << ", " << ibuffer[1] << ", "
+ << ibuffer[2] << ") vs setup: (" << resX << ", " << resY << ", " << resZ << ")" << endl;
gzclose(gzf);
return false;
}
@@ -3009,16 +2840,16 @@ bool MANTA::updateGridFromUni(std::string filename, float *grid, bool isNoise)
}
if (with_debug)
- std::cout << "Fluid: Read successfully: " << filename << std::endl;
+ cout << "Fluid: Read successfully: " << filename << endl;
return (gzclose(gzf) == Z_OK);
}
#if OPENVDB == 1
-bool MANTA::updateGridFromVDB(std::string filename, float *grid, bool isNoise)
+bool MANTA::updateGridFromVDB(string filename, float *grid, bool isNoise)
{
if (with_debug)
- std::cout << "MANTA::updateGridFromVDB()" << std::endl;
+ cout << "MANTA::updateGridFromVDB()" << endl;
openvdb::initialize();
openvdb::io::File file(filename);
@@ -3026,8 +2857,8 @@ bool MANTA::updateGridFromVDB(std::string filename, float *grid, bool isNoise)
file.open();
}
catch (const openvdb::IoError &) {
- std::cerr << "Fluid Error -- updateGridFromVDB(): IOError, invalid OpenVDB file: " << filename
- << std::endl;
+ cerr << "Fluid Error -- updateGridFromVDB(): IOError, invalid OpenVDB file: " << filename
+ << endl;
return false;
}
@@ -3059,17 +2890,17 @@ bool MANTA::updateGridFromVDB(std::string filename, float *grid, bool isNoise)
}
#endif
-bool MANTA::updateGridFromRaw(std::string filename, float *grid, bool isNoise)
+bool MANTA::updateGridFromRaw(string filename, float *grid, bool isNoise)
{
if (with_debug)
- std::cout << "MANTA::updateGridFromRaw()" << std::endl;
+ cout << "MANTA::updateGridFromRaw()" << endl;
gzFile gzf;
int expectedBytes, readBytes;
gzf = (gzFile)BLI_gzopen(filename.c_str(), "rb");
if (!gzf) {
- std::cout << "MANTA::updateGridFromRaw(): unable to open file" << std::endl;
+ cout << "MANTA::updateGridFromRaw(): unable to open file" << endl;
return false;
}
@@ -3080,8 +2911,7 @@ bool MANTA::updateGridFromRaw(std::string filename, float *grid, bool isNoise)
expectedBytes = sizeof(float) * resX * resY * resZ;
readBytes = gzread(gzf, grid, expectedBytes);
if (!readBytes) {
- std::cerr << "Fluid Error -- updateGridFromRaw(): Unable to read raw file: " << filename
- << std::endl;
+ cerr << "Fluid Error -- updateGridFromRaw(): Unable to read raw file: " << filename << endl;
gzclose(gzf);
return false;
}
@@ -3094,25 +2924,25 @@ bool MANTA::updateGridFromRaw(std::string filename, float *grid, bool isNoise)
void MANTA::updatePointers()
{
if (with_debug)
- std::cout << "MANTA::updatePointers()" << std::endl;
-
- std::string func = "getDataPointer";
- std::string funcNodes = "getNodesDataPointer";
- std::string funcTris = "getTrisDataPointer";
-
- std::string id = std::to_string(mCurrentID);
- std::string solver = "s" + id;
- std::string parts = "pp" + id;
- std::string snd = "sp" + id;
- std::string mesh = "sm" + id;
- std::string mesh2 = "mesh" + id;
- std::string noise = "sn" + id;
- std::string solver_ext = "_" + solver;
- std::string parts_ext = "_" + parts;
- std::string snd_ext = "_" + snd;
- std::string mesh_ext = "_" + mesh;
- std::string mesh_ext2 = "_" + mesh2;
- std::string noise_ext = "_" + noise;
+ cout << "MANTA::updatePointers()" << endl;
+
+ string func = "getDataPointer";
+ string funcNodes = "getNodesDataPointer";
+ string funcTris = "getTrisDataPointer";
+
+ string id = to_string(mCurrentID);
+ string solver = "s" + id;
+ string parts = "pp" + id;
+ string snd = "sp" + id;
+ string mesh = "sm" + id;
+ string mesh2 = "mesh" + id;
+ string noise = "sn" + id;
+ string solver_ext = "_" + solver;
+ string parts_ext = "_" + parts;
+ string snd_ext = "_" + snd;
+ string mesh_ext = "_" + mesh;
+ string mesh_ext2 = "_" + mesh2;
+ string noise_ext = "_" + noise;
mFlags = (int *)pyObjectToPointer(callPythonFunction("flags" + solver_ext, func));
mPhiIn = (float *)pyObjectToPointer(callPythonFunction("phiIn" + solver_ext, func));
@@ -3199,27 +3029,27 @@ void MANTA::updatePointers()
}
if (mUsingLiquid) {
mPhi = (float *)pyObjectToPointer(callPythonFunction("phi" + solver_ext, func));
- mFlipParticleData = (std::vector<pData> *)pyObjectToPointer(
+ mFlipParticleData = (vector<pData> *)pyObjectToPointer(
callPythonFunction("pp" + solver_ext, func));
- mFlipParticleVelocity = (std::vector<pVel> *)pyObjectToPointer(
+ mFlipParticleVelocity = (vector<pVel> *)pyObjectToPointer(
callPythonFunction("pVel" + parts_ext, func));
}
if (mUsingLiquid && mUsingMesh) {
- mMeshNodes = (std::vector<Node> *)pyObjectToPointer(
+ mMeshNodes = (vector<Node> *)pyObjectToPointer(
callPythonFunction("mesh" + mesh_ext, funcNodes));
- mMeshTriangles = (std::vector<Triangle> *)pyObjectToPointer(
+ mMeshTriangles = (vector<Triangle> *)pyObjectToPointer(
callPythonFunction("mesh" + mesh_ext, funcTris));
}
if (mUsingLiquid && mUsingMVel) {
- mMeshVelocities = (std::vector<pVel> *)pyObjectToPointer(
+ mMeshVelocities = (vector<pVel> *)pyObjectToPointer(
callPythonFunction("mVel" + mesh_ext2, func));
}
if (mUsingLiquid && (mUsingDrops | mUsingBubbles | mUsingFloats | mUsingTracers)) {
- mSndParticleData = (std::vector<pData> *)pyObjectToPointer(
+ mSndParticleData = (vector<pData> *)pyObjectToPointer(
callPythonFunction("ppSnd" + snd_ext, func));
- mSndParticleVelocity = (std::vector<pVel> *)pyObjectToPointer(
+ mSndParticleVelocity = (vector<pVel> *)pyObjectToPointer(
callPythonFunction("pVelSnd" + parts_ext, func));
- mSndParticleLife = (std::vector<float> *)pyObjectToPointer(
+ mSndParticleLife = (vector<float> *)pyObjectToPointer(
callPythonFunction("pLifeSnd" + parts_ext, func));
}
@@ -3232,21 +3062,21 @@ void MANTA::updatePointers()
bool MANTA::hasConfig(FluidModifierData *mmd, int framenr)
{
- std::string extension = FLUID_DOMAIN_EXTENSION_UNI;
+ string extension = FLUID_DOMAIN_EXTENSION_UNI;
return BLI_exists(
getFile(mmd, FLUID_DOMAIN_DIR_CONFIG, FLUID_DOMAIN_FILE_CONFIG, extension, framenr).c_str());
}
bool MANTA::hasData(FluidModifierData *mmd, int framenr)
{
- std::string filename = (mUsingSmoke) ? FLUID_DOMAIN_FILE_DENSITY : FLUID_DOMAIN_FILE_PP;
- std::string extension = getCacheFileEnding(mmd->domain->cache_data_format);
+ string filename = (mUsingSmoke) ? FLUID_DOMAIN_FILE_DENSITY : FLUID_DOMAIN_FILE_PP;
+ string extension = getCacheFileEnding(mmd->domain->cache_data_format);
return BLI_exists(getFile(mmd, FLUID_DOMAIN_DIR_DATA, filename, extension, framenr).c_str());
}
bool MANTA::hasNoise(FluidModifierData *mmd, int framenr)
{
- std::string extension = getCacheFileEnding(mmd->domain->cache_noise_format);
+ string extension = getCacheFileEnding(mmd->domain->cache_noise_format);
return BLI_exists(
getFile(mmd, FLUID_DOMAIN_DIR_NOISE, FLUID_DOMAIN_FILE_DENSITYNOISE, extension, framenr)
.c_str());
@@ -3254,14 +3084,14 @@ bool MANTA::hasNoise(FluidModifierData *mmd, int framenr)
bool MANTA::hasMesh(FluidModifierData *mmd, int framenr)
{
- std::string extension = getCacheFileEnding(mmd->domain->cache_mesh_format);
+ string extension = getCacheFileEnding(mmd->domain->cache_mesh_format);
return BLI_exists(
getFile(mmd, FLUID_DOMAIN_DIR_MESH, FLUID_DOMAIN_FILE_MESH, extension, framenr).c_str());
}
bool MANTA::hasParticles(FluidModifierData *mmd, int framenr)
{
- std::string extension = getCacheFileEnding(mmd->domain->cache_particle_format);
+ string extension = getCacheFileEnding(mmd->domain->cache_particle_format);
return BLI_exists(
getFile(mmd, FLUID_DOMAIN_DIR_PARTICLES, FLUID_DOMAIN_FILE_PPSND, extension, framenr)
.c_str());
@@ -3269,13 +3099,13 @@ bool MANTA::hasParticles(FluidModifierData *mmd, int framenr)
bool MANTA::hasGuiding(FluidModifierData *mmd, int framenr, bool sourceDomain)
{
- std::string subdirectory = (sourceDomain) ? FLUID_DOMAIN_DIR_DATA : FLUID_DOMAIN_DIR_GUIDE;
- std::string filename = (sourceDomain) ? FLUID_DOMAIN_FILE_VEL : FLUID_DOMAIN_FILE_GUIDEVEL;
- std::string extension = getCacheFileEnding(mmd->domain->cache_data_format);
+ string subdirectory = (sourceDomain) ? FLUID_DOMAIN_DIR_DATA : FLUID_DOMAIN_DIR_GUIDE;
+ string filename = (sourceDomain) ? FLUID_DOMAIN_FILE_VEL : FLUID_DOMAIN_FILE_GUIDEVEL;
+ string extension = getCacheFileEnding(mmd->domain->cache_data_format);
return BLI_exists(getFile(mmd, subdirectory, filename, extension, framenr).c_str());
}
-std::string MANTA::getDirectory(FluidModifierData *mmd, std::string subdirectory)
+string MANTA::getDirectory(FluidModifierData *mmd, string subdirectory)
{
char directory[FILE_MAX];
BLI_path_join(
@@ -3284,15 +3114,12 @@ std::string MANTA::getDirectory(FluidModifierData *mmd, std::string subdirectory
return directory;
}
-std::string MANTA::getFile(FluidModifierData *mmd,
- std::string subdirectory,
- std::string fname,
- std::string extension,
- int framenr)
+string MANTA::getFile(
+ FluidModifierData *mmd, string subdirectory, string fname, string extension, int framenr)
{
char targetFile[FILE_MAX];
- std::string path = getDirectory(mmd, subdirectory);
- std::string filename = fname + extension;
+ string path = getDirectory(mmd, subdirectory);
+ string filename = fname + extension;
BLI_join_dirfile(targetFile, sizeof(targetFile), path.c_str(), filename.c_str());
BLI_path_frame(targetFile, framenr, 0);
return targetFile;
diff --git a/intern/mantaflow/intern/MANTA_main.h b/intern/mantaflow/intern/MANTA_main.h
index 21946431f28..9b3fd6aa141 100644
--- a/intern/mantaflow/intern/MANTA_main.h
+++ b/intern/mantaflow/intern/MANTA_main.h
@@ -27,8 +27,14 @@
#include <atomic>
#include <cassert>
#include <string>
+#include <unordered_map>
#include <vector>
+using std::atomic;
+using std::string;
+using std::unordered_map;
+using std::vector;
+
struct MANTA {
public:
MANTA(int *res, struct FluidModifierData *mmd);
@@ -58,20 +64,20 @@ struct MANTA {
void step(struct FluidModifierData *mmd, int startFrame);
// Grid initialization functions
- void initHeat(struct FluidModifierData *mmd);
- void initFire(struct FluidModifierData *mmd);
- void initColors(struct FluidModifierData *mmd);
- void initFireHigh(struct FluidModifierData *mmd);
- void initColorsHigh(struct FluidModifierData *mmd);
- void initLiquid(FluidModifierData *mmd);
- void initLiquidMesh(FluidModifierData *mmd);
- void initObstacle(FluidModifierData *mmd);
- void initGuiding(FluidModifierData *mmd);
- void initFractions(FluidModifierData *mmd);
- void initInVelocity(FluidModifierData *mmd);
- void initOutflow(FluidModifierData *mmd);
- void initSndParts(FluidModifierData *mmd);
- void initLiquidSndParts(FluidModifierData *mmd);
+ void initHeat(struct FluidModifierData *mmd = NULL);
+ void initFire(struct FluidModifierData *mmd = NULL);
+ void initColors(struct FluidModifierData *mmd = NULL);
+ void initFireHigh(struct FluidModifierData *mmd = NULL);
+ void initColorsHigh(struct FluidModifierData *mmd = NULL);
+ void initLiquid(FluidModifierData *mmd = NULL);
+ void initLiquidMesh(FluidModifierData *mmd = NULL);
+ void initObstacle(FluidModifierData *mmd = NULL);
+ void initGuiding(FluidModifierData *mmd = NULL);
+ void initFractions(FluidModifierData *mmd = NULL);
+ void initInVelocity(FluidModifierData *mmd = NULL);
+ void initOutflow(FluidModifierData *mmd = NULL);
+ void initSndParts(FluidModifierData *mmd = NULL);
+ void initLiquidSndParts(FluidModifierData *mmd = NULL);
// Pointer transfer: Mantaflow -> Blender
void updatePointers();
@@ -414,7 +420,7 @@ struct MANTA {
return mPhi;
}
- static std::atomic<int> solverID;
+ static atomic<int> solverID;
static int with_debug; // on or off (1 or 0), also sets manta debug level
// Mesh getters
@@ -741,6 +747,8 @@ struct MANTA {
size_t mTotalCellsMesh;
size_t mTotalCellsParticles;
+ unordered_map<string, string> mRNAMap;
+
int mCurrentID;
bool mUsingHeat;
@@ -852,45 +860,46 @@ struct MANTA {
float *mPhi;
// Mesh fields
- std::vector<Node> *mMeshNodes;
- std::vector<Triangle> *mMeshTriangles;
- std::vector<pVel> *mMeshVelocities;
+ vector<Node> *mMeshNodes;
+ vector<Triangle> *mMeshTriangles;
+ vector<pVel> *mMeshVelocities;
// Particle fields
- std::vector<pData> *mFlipParticleData;
- std::vector<pVel> *mFlipParticleVelocity;
-
- std::vector<pData> *mSndParticleData;
- std::vector<pVel> *mSndParticleVelocity;
- std::vector<float> *mSndParticleLife;
-
- void initDomain(struct FluidModifierData *mmd);
- void initNoise(struct FluidModifierData *mmd);
- void initMesh(struct FluidModifierData *mmd);
- void initSmoke(struct FluidModifierData *mmd);
- void initSmokeNoise(struct FluidModifierData *mmd);
+ vector<pData> *mFlipParticleData;
+ vector<pVel> *mFlipParticleVelocity;
+
+ vector<pData> *mSndParticleData;
+ vector<pVel> *mSndParticleVelocity;
+ vector<float> *mSndParticleLife;
+
+ void initializeRNAMap(struct FluidModifierData *mmd = NULL);
+ void initDomain(struct FluidModifierData *mmd = NULL);
+ void initNoise(struct FluidModifierData *mmd = NULL);
+ void initMesh(struct FluidModifierData *mmd = NULL);
+ void initSmoke(struct FluidModifierData *mmd = NULL);
+ void initSmokeNoise(struct FluidModifierData *mmd = NULL);
void initializeMantaflow();
void terminateMantaflow();
- bool runPythonString(std::vector<std::string> commands);
- std::string getRealValue(const std::string &varName, FluidModifierData *mmd);
- std::string parseLine(const std::string &line, FluidModifierData *mmd);
- std::string parseScript(const std::string &setup_string, FluidModifierData *mmd = NULL);
- bool updateMeshFromBobj(std::string filename);
- bool updateMeshFromObj(std::string filename);
- bool updateMeshFromUni(std::string filename);
- bool updateParticlesFromUni(std::string filename, bool isSecondarySys, bool isVelData);
- bool updateGridFromUni(std::string filename, float *grid, bool isNoise);
- bool updateGridFromVDB(std::string filename, float *grid, bool isNoise);
- bool updateGridFromRaw(std::string filename, float *grid, bool isNoise);
- bool updateMeshFromFile(std::string filename);
- bool updateParticlesFromFile(std::string filename, bool isSecondarySys, bool isVelData);
- bool updateGridFromFile(std::string filename, float *grid, bool isNoise);
- std::string getDirectory(struct FluidModifierData *mmd, std::string subdirectory);
- std::string getFile(struct FluidModifierData *mmd,
- std::string subdirectory,
- std::string fname,
- std::string extension,
- int framenr);
+ bool runPythonString(vector<string> commands);
+ string getRealValue(const string &varName);
+ string parseLine(const string &line);
+ string parseScript(const string &setup_string, FluidModifierData *mmd = NULL);
+ bool updateMeshFromBobj(string filename);
+ bool updateMeshFromObj(string filename);
+ bool updateMeshFromUni(string filename);
+ bool updateParticlesFromUni(string filename, bool isSecondarySys, bool isVelData);
+ bool updateGridFromUni(string filename, float *grid, bool isNoise);
+ bool updateGridFromVDB(string filename, float *grid, bool isNoise);
+ bool updateGridFromRaw(string filename, float *grid, bool isNoise);
+ bool updateMeshFromFile(string filename);
+ bool updateParticlesFromFile(string filename, bool isSecondarySys, bool isVelData);
+ bool updateGridFromFile(string filename, float *grid, bool isNoise);
+ string getDirectory(struct FluidModifierData *mmd, string subdirectory);
+ string getFile(struct FluidModifierData *mmd,
+ string subdirectory,
+ string fname,
+ string extension,
+ int framenr);
};
#endif
diff --git a/intern/mantaflow/intern/strings/fluid_script.h b/intern/mantaflow/intern/strings/fluid_script.h
index dd2111db7d7..c0a23f77d7a 100644
--- a/intern/mantaflow/intern/strings/fluid_script.h
+++ b/intern/mantaflow/intern/strings/fluid_script.h
@@ -92,7 +92,7 @@ const std::string fluid_variables =
mantaMsg('Fluid variables')\n\
dim_s$ID$ = $SOLVER_DIM$\n\
res_s$ID$ = $RES$\n\
-gravity_s$ID$ = vec3($GRAVITY_X$, $GRAVITY_Y$, $GRAVITY_Z$)\n\
+gravity_s$ID$ = vec3($GRAVITY_X$, $GRAVITY_Y$, $GRAVITY_Z$) # in SI unit (e.g. m/s^2)\n\
gs_s$ID$ = vec3($RESX$, $RESY$, $RESZ$)\n\
maxVel_s$ID$ = 0\n\
\n\
@@ -115,6 +115,7 @@ using_speedvectors_s$ID$ = $USING_SPEEDVECTORS$\n\
using_diffusion_s$ID$ = $USING_DIFFUSION$\n\
\n\
# Fluid time params\n\
+timeScale_s$ID$ = $TIME_SCALE$\n\
timeTotal_s$ID$ = $TIME_TOTAL$\n\
timePerFrame_s$ID$ = $TIME_PER_FRAME$\n\
frameLength_s$ID$ = $FRAME_LENGTH$\n\
@@ -132,8 +133,29 @@ end_frame_s$ID$ = $END_FRAME$\n\
domainSize_s$ID$ = $FLUID_DOMAIN_SIZE$ # longest domain side in meters\n\
viscosity_s$ID$ = $FLUID_VISCOSITY$ / (domainSize_s$ID$*domainSize_s$ID$) # kinematic viscosity in m^2/s\n\
\n\
-# Factor to convert blender velocities to manta velocities\n\
-toMantaUnitsFac_s$ID$ = (1.0 / (1.0 / res_s$ID$))\n # = dt/dx * 1/dt ";
+# Factors to convert Blender units to Manta units\n\
+ratioMetersToRes_s$ID$ = float(domainSize_s$ID$) / float(res_s$ID$) # [meters / cells]\n\
+mantaMsg('1 Mantaflow cell is ' + str(ratioMetersToRes_s$ID$) + ' Blender length units long.')\n\
+\n\
+ratioResToBLength_s$ID$ = float(res_s$ID$) / float(domainSize_s$ID$) # [cells / blength] (blength: cm, m, or km, ... )\n\
+mantaMsg('1 Blender length unit is ' + str(ratioResToBLength_s$ID$) + ' Mantaflow cells long.')\n\
+\n\
+ratioBTimeToTimstep_s$ID$ = float(1) / float(0.1 * 25 * timeScale_s$ID$) # the time within 1 blender time unit, see also fluid.c\n\
+mantaMsg('1 Blender time unit is ' + str(ratioBTimeToTimstep_s$ID$) + ' Mantaflow time units long.')\n\
+\n\
+ratioFrameToFramelength_s$ID$ = float(1) / float(frameLength_s$ID$) # the time within 1 frame\n\
+mantaMsg('frame / frameLength is ' + str(ratioFrameToFramelength_s$ID$) + ' Mantaflow time units long.')\n\
+\n\
+scaleAcceleration_s$ID$ = ratioResToBLength_s$ID$ * (ratioBTimeToTimstep_s$ID$**2)# [meters/btime^2] to [cells/timestep^2] (btime: sec, min, or h, ...)\n\
+mantaMsg('scaleAcceleration is ' + str(scaleAcceleration_s$ID$))\n\
+\n\
+scaleSpeedFrames_s$ID$ = ratioResToBLength_s$ID$ * ratioFrameToFramelength_s$ID$ # [blength/frame] to [cells/frameLength]\n\
+mantaMsg('scaleSpeed is ' + str(scaleSpeedFrames_s$ID$))\n\
+\n\
+scaleSpeedTime_s$ID$ = ratioResToBLength_s$ID$ * ratioBTimeToTimstep_s$ID$ # [blength/btime] to [cells/frameLength]\n\
+mantaMsg('scaleSpeedTime is ' + str(scaleSpeedTime_s$ID$))\n\
+\n\
+gravity_s$ID$ *= scaleAcceleration_s$ID$ # scale from world acceleration to cell based acceleration\n";
const std::string fluid_variables_noise =
"\n\
@@ -342,17 +364,16 @@ def fluid_pre_step_$ID$():\n\
y_obvel_s$ID$.safeDivide(numObs_s$ID$)\n\
z_obvel_s$ID$.safeDivide(numObs_s$ID$)\n\
\n\
- x_obvel_s$ID$.multConst(toMantaUnitsFac_s$ID$)\n\
- y_obvel_s$ID$.multConst(toMantaUnitsFac_s$ID$)\n\
- z_obvel_s$ID$.multConst(toMantaUnitsFac_s$ID$)\n\
- \n\
+ x_obvel_s$ID$.multConst(scaleSpeedFrames_s$ID$)\n\
+ y_obvel_s$ID$.multConst(scaleSpeedFrames_s$ID$)\n\
+ z_obvel_s$ID$.multConst(scaleSpeedFrames_s$ID$)\n\
copyRealToVec3(sourceX=x_obvel_s$ID$, sourceY=y_obvel_s$ID$, sourceZ=z_obvel_s$ID$, target=obvelC_s$ID$)\n\
\n\
# translate invels (world space) to grid space\n\
if using_invel_s$ID$:\n\
- x_invel_s$ID$.multConst(toMantaUnitsFac_s$ID$)\n\
- y_invel_s$ID$.multConst(toMantaUnitsFac_s$ID$)\n\
- z_invel_s$ID$.multConst(toMantaUnitsFac_s$ID$)\n\
+ x_invel_s$ID$.multConst(scaleSpeedTime_s$ID$)\n\
+ y_invel_s$ID$.multConst(scaleSpeedTime_s$ID$)\n\
+ z_invel_s$ID$.multConst(scaleSpeedTime_s$ID$)\n\
copyRealToVec3(sourceX=x_invel_s$ID$, sourceY=y_invel_s$ID$, sourceZ=z_invel_s$ID$, target=invelC_s$ID$)\n\
\n\
if using_guiding_s$ID$:\n\
@@ -362,9 +383,9 @@ def fluid_pre_step_$ID$():\n\
velT_s$ID$.multConst(vec3(gamma_sg$ID$))\n\
\n\
# translate external forces (world space) to grid space\n\
- x_force_s$ID$.multConst(toMantaUnitsFac_s$ID$)\n\
- y_force_s$ID$.multConst(toMantaUnitsFac_s$ID$)\n\
- z_force_s$ID$.multConst(toMantaUnitsFac_s$ID$)\n\
+ x_force_s$ID$.multConst(scaleSpeedFrames_s$ID$)\n\
+ y_force_s$ID$.multConst(scaleSpeedFrames_s$ID$)\n\
+ z_force_s$ID$.multConst(scaleSpeedFrames_s$ID$)\n\
copyRealToVec3(sourceX=x_force_s$ID$, sourceY=y_force_s$ID$, sourceZ=z_force_s$ID$, target=forces_s$ID$)\n\
\n\
# If obstacle has velocity, i.e. is a moving obstacle, switch to dynamic preconditioner\n\
@@ -598,10 +619,9 @@ def bake_guiding_process_$ID$(framenr, format_guiding, path_guiding, resumable):
y_guidevel_s$ID$.safeDivide(numGuides_s$ID$)\n\
z_guidevel_s$ID$.safeDivide(numGuides_s$ID$)\n\
\n\
- x_guidevel_s$ID$.multConst(Real(toMantaUnitsFac_s$ID$))\n\
- y_guidevel_s$ID$.multConst(Real(toMantaUnitsFac_s$ID$))\n\
- z_guidevel_s$ID$.multConst(Real(toMantaUnitsFac_s$ID$))\n\
- \n\
+ x_guidevel_s$ID$.multConst(scaleSpeedFrames_s$ID$)\n\
+ y_guidevel_s$ID$.multConst(scaleSpeedFrames_s$ID$)\n\
+ z_guidevel_s$ID$.multConst(scaleSpeedFrames_s$ID$)\n\
copyRealToVec3(sourceX=x_guidevel_s$ID$, sourceY=y_guidevel_s$ID$, sourceZ=z_guidevel_s$ID$, target=guidevelC_s$ID$)\n\
\n\
mantaMsg('Extrapolating guiding velocity')\n\
diff --git a/intern/mantaflow/intern/strings/liquid_script.h b/intern/mantaflow/intern/strings/liquid_script.h
index f20b218427c..ee1f0878687 100644
--- a/intern/mantaflow/intern/strings/liquid_script.h
+++ b/intern/mantaflow/intern/strings/liquid_script.h
@@ -68,7 +68,7 @@ c_s_sp$ID$ = 0.4 # classification constant for snd parts\n\
c_b_sp$ID$ = 0.77 # classification constant for snd parts\n\
pot_radius_sp$ID$ = $SNDPARTICLE_POTENTIAL_RADIUS$\n\
update_radius_sp$ID$ = $SNDPARTICLE_UPDATE_RADIUS$\n\
-scaleFromManta_sp$ID$ = $FLUID_DOMAIN_SIZE$ / float(res_s$ID$) # resize factor for snd parts\n";
+using_snd_pushout_sp$ID$ = $SNDPARTICLE_BOUNDARY_PUSHOUT$\n";
//////////////////////////////////////////////////////////////////////
// GRIDS & MESH & PARTICLESYSTEM
@@ -263,7 +263,7 @@ def liquid_step_$ID$():\n\
velOld_s$ID$.copyFrom(vel_s$ID$)\n\
\n\
# forces & pressure solve\n\
- addGravity(flags=flags_s$ID$, vel=vel_s$ID$, gravity=gravity_s$ID$)\n\
+ addGravity(flags=flags_s$ID$, vel=vel_s$ID$, gravity=gravity_s$ID$, scale=False)\n\
\n\
mantaMsg('Adding external forces')\n\
addForceField(flags=flags_s$ID$, vel=vel_s$ID$, force=forces_s$ID$)\n\
@@ -371,10 +371,10 @@ def liquid_step_particles_$ID$():\n\
flags_sp$ID$.updateFromLevelset(levelset=phi_sp$ID$)\n\
\n\
# Actual secondary particle simulation\n\
- flipComputeSecondaryParticlePotentials(potTA=trappedAir_sp$ID$, potWC=waveCrest_sp$ID$, potKE=kineticEnergy_sp$ID$, neighborRatio=neighborRatio_sp$ID$, flags=flags_sp$ID$, v=vel_sp$ID$, normal=normal_sp$ID$, phi=phi_sp$ID$, radius=pot_radius_sp$ID$, tauMinTA=tauMin_ta_sp$ID$, tauMaxTA=tauMax_ta_sp$ID$, tauMinWC=tauMin_wc_sp$ID$, tauMaxWC=tauMax_wc_sp$ID$, tauMinKE=tauMin_k_sp$ID$, tauMaxKE=tauMax_k_sp$ID$, scaleFromManta=scaleFromManta_sp$ID$)\n\
+ flipComputeSecondaryParticlePotentials(potTA=trappedAir_sp$ID$, potWC=waveCrest_sp$ID$, potKE=kineticEnergy_sp$ID$, neighborRatio=neighborRatio_sp$ID$, flags=flags_sp$ID$, v=vel_sp$ID$, normal=normal_sp$ID$, phi=phi_sp$ID$, radius=pot_radius_sp$ID$, tauMinTA=tauMin_ta_sp$ID$, tauMaxTA=tauMax_ta_sp$ID$, tauMinWC=tauMin_wc_sp$ID$, tauMaxWC=tauMax_wc_sp$ID$, tauMinKE=tauMin_k_sp$ID$, tauMaxKE=tauMax_k_sp$ID$, scaleFromManta=ratioMetersToRes_s$ID$)\n\
flipSampleSecondaryParticles(mode='single', flags=flags_sp$ID$, v=vel_sp$ID$, pts_sec=ppSnd_sp$ID$, v_sec=pVelSnd_pp$ID$, l_sec=pLifeSnd_pp$ID$, lMin=lMin_sp$ID$, lMax=lMax_sp$ID$, potTA=trappedAir_sp$ID$, potWC=waveCrest_sp$ID$, potKE=kineticEnergy_sp$ID$, neighborRatio=neighborRatio_sp$ID$, c_s=c_s_sp$ID$, c_b=c_b_sp$ID$, k_ta=k_ta_sp$ID$, k_wc=k_wc_sp$ID$, dt=sp$ID$.timestep)\n\
flipUpdateSecondaryParticles(mode='linear', pts_sec=ppSnd_sp$ID$, v_sec=pVelSnd_pp$ID$, l_sec=pLifeSnd_pp$ID$, f_sec=pForceSnd_pp$ID$, flags=flags_sp$ID$, v=vel_sp$ID$, neighborRatio=neighborRatio_sp$ID$, radius=update_radius_sp$ID$, gravity=gravity_s$ID$, k_b=k_b_sp$ID$, k_d=k_d_sp$ID$, c_s=c_s_sp$ID$, c_b=c_b_sp$ID$, dt=sp$ID$.timestep)\n\
- if $SNDPARTICLE_BOUNDARY_PUSHOUT$:\n\
+ if using_snd_pushout_sp$ID$:\n\
pushOutofObs(parts=ppSnd_sp$ID$, flags=flags_sp$ID$, phiObs=phiObs_sp$ID$, shift=1.0)\n\
flipDeleteParticlesInObstacle(pts=ppSnd_sp$ID$, flags=flags_sp$ID$) # delete particles inside obstacle and outflow cells\n\
\n\
diff --git a/intern/mantaflow/intern/strings/smoke_script.h b/intern/mantaflow/intern/strings/smoke_script.h
index fdb58543cec..ea2b1e9d848 100644
--- a/intern/mantaflow/intern/strings/smoke_script.h
+++ b/intern/mantaflow/intern/strings/smoke_script.h
@@ -376,9 +376,9 @@ def smoke_step_$ID$():\n\
\n\
if using_heat_s$ID$:\n\
mantaMsg('Adding heat buoyancy')\n\
- addBuoyancy(flags=flags_s$ID$, density=heat_s$ID$, vel=vel_s$ID$, gravity=gravity_s$ID$, coefficient=buoyancy_heat_s$ID$)\n\
+ addBuoyancy(flags=flags_s$ID$, density=heat_s$ID$, vel=vel_s$ID$, gravity=gravity_s$ID$, coefficient=buoyancy_heat_s$ID$, scale=False)\n\
mantaMsg('Adding buoyancy')\n\
- addBuoyancy(flags=flags_s$ID$, density=density_s$ID$, vel=vel_s$ID$, gravity=gravity_s$ID$, coefficient=buoyancy_dens_s$ID$)\n\
+ addBuoyancy(flags=flags_s$ID$, density=density_s$ID$, vel=vel_s$ID$, gravity=gravity_s$ID$, coefficient=buoyancy_dens_s$ID$, scale=False)\n\
\n\
mantaMsg('Adding forces')\n\
addForceField(flags=flags_s$ID$, vel=vel_s$ID$, force=forces_s$ID$)\n\
diff --git a/intern/string/CMakeLists.txt b/intern/string/CMakeLists.txt
deleted file mode 100644
index 8c400f320ae..00000000000
--- a/intern/string/CMakeLists.txt
+++ /dev/null
@@ -1,38 +0,0 @@
-# ***** BEGIN GPL LICENSE BLOCK *****
-#
-# 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.
-#
-# The Original Code is Copyright (C) 2006, Blender Foundation
-# All rights reserved.
-# ***** END GPL LICENSE BLOCK *****
-
-set(INC
- .
-)
-
-set(INC_SYS
-
-)
-
-set(SRC
- intern/STR_String.cpp
-
- STR_String.h
-)
-
-set(LIB
-)
-
-blender_add_lib(bf_intern_string "${SRC}" "${INC}" "${INC_SYS}" "${LIB}")
diff --git a/intern/string/STR_String.h b/intern/string/STR_String.h
deleted file mode 100644
index 97b23345f91..00000000000
--- a/intern/string/STR_String.h
+++ /dev/null
@@ -1,366 +0,0 @@
-/*
- * 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.
- *
- * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
- * All rights reserved.
- */
-
-/** \file
- * \ingroup string
- */
-
-#ifndef __STR_STRING_H__
-#define __STR_STRING_H__
-
-#ifndef STR_NO_ASSERTD
-# undef assertd
-# define assertd(exp) ((void)NULL)
-#endif
-
-#include <limits.h>
-#include <vector>
-
-#include <cstdlib>
-#include <cstring>
-
-#ifdef WITH_CXX_GUARDEDALLOC
-# include "MEM_guardedalloc.h"
-#endif
-
-#ifdef _WIN32
-# define stricmp _stricmp
-#endif
-
-class STR_String;
-
-typedef unsigned long dword;
-typedef const STR_String &rcSTR_String;
-typedef unsigned char byte;
-
-/**
- * Smart String Value class. Is used by parser when an expression tree is build containing string.
- */
-
-class STR_String {
- public:
- // Initialization
- STR_String();
- STR_String(char c);
- STR_String(char c, int len);
- STR_String(const char *str);
- STR_String(const char *str, int len);
- STR_String(const STR_String &str);
- STR_String(const STR_String &str, int len);
- STR_String(const char *src1, int src1_len, const char *src2, int src2_len);
- explicit STR_String(int val);
- explicit STR_String(dword val);
- explicit STR_String(float val);
- explicit STR_String(double val);
- inline ~STR_String()
- {
- delete[] this->m_data;
- }
-
- // Operations
- STR_String &Format(const char *fmt, ...) // Set formatted text to string
-#ifdef __GNUC__
- __attribute__((format(printf, 2, 3)))
-#endif
- ;
- STR_String &FormatAdd(const char *fmt, ...) // Add formatted text to string
-#ifdef __GNUC__
- __attribute__((format(printf, 2, 3)))
-#endif
- ;
- inline void Clear()
- {
- this->m_len = this->m_data[0] = 0;
- }
- inline const STR_String &Reverse()
- {
- for (int i1 = 0, i2 = this->m_len - 1; i1 < i2; i1++, i2--) {
- std::swap(this->m_data[i1], this->m_data[i2]);
- }
- return *this;
- }
-
- // Properties
- bool IsUpper() const;
- bool IsLower() const;
- inline bool IsEmpty() const
- {
- return this->m_len == 0;
- }
- inline int Length() const
- {
- return this->m_len;
- }
-
- // Data access
- inline STR_String &SetLength(int len)
- {
- AllocBuffer(len, true);
- this->m_len = len;
- this->m_data[len] = 0;
- return *this;
- }
- inline char GetAt(int pos) const
- {
- assertd(pos < this->m_len);
- return this->m_data[pos];
- }
- inline void SetAt(int pos, char c)
- {
- assertd(pos < this->m_len);
- this->m_data[pos] = c;
- }
- inline void SetAt(int pos, rcSTR_String str);
- inline void SetAt(int pos, int num, rcSTR_String str);
- void Replace(int pos, rcSTR_String str);
- void Replace(int pos, int num, rcSTR_String str);
-
- // Substrings
- inline STR_String Left(int num) const
- {
- num = (num < this->m_len ? num : this->m_len);
- return STR_String(this->m_data, num);
- }
- inline STR_String Right(int num) const
- {
- num = (num < this->m_len ? num : this->m_len);
- return STR_String(this->m_data + this->m_len - num, num);
- }
- inline STR_String Mid(int pos, int num = INT_MAX) const
- {
- pos = (pos < this->m_len ? pos : this->m_len);
- num = (num < (this->m_len - pos) ? num : (this->m_len - pos));
- return STR_String(this->m_data + pos, num);
- }
-
- // Comparison
- int Compare(rcSTR_String rhs) const;
- int CompareNoCase(rcSTR_String rhs) const;
- inline bool IsEqual(rcSTR_String rhs) const
- {
- return (Compare(rhs) == 0);
- }
- inline bool IsEqualNoCase(rcSTR_String rhs) const
- {
- return (CompareNoCase(rhs) == 0);
- }
-
- // Search/replace
- int Find(char c, int pos = 0) const;
- int Find(const char *str, int pos = 0) const;
- int Find(rcSTR_String str, int pos = 0) const;
- int RFind(char c) const;
- int FindOneOf(const char *set, int pos = 0) const;
- int RFindOneOf(const char *set, int pos = 0) const;
-
- std::vector<STR_String> Explode(char c) const;
-
- // Formatting
- STR_String &Upper();
- STR_String &Lower();
- STR_String &Capitalize();
- STR_String &TrimLeft();
- STR_String &TrimLeft(char *set);
- STR_String &TrimRight();
- STR_String &TrimRight(char *set);
- STR_String &Trim();
- STR_String &Trim(char *set);
- STR_String &TrimQuotes();
-
- // Conversions
- // inline operator char*() { return this->m_data; }
- inline operator const char *() const
- {
- return this->m_data;
- }
- inline char *Ptr()
- {
- return this->m_data;
- }
- inline const char *ReadPtr() const
- {
- return this->m_data;
- }
- inline float ToFloat() const
- {
- float x = (float)(atof(this->m_data));
- return x;
- }
- inline int ToInt() const
- {
- return atoi(this->m_data);
- }
-
- // Operators
- inline rcSTR_String operator=(const byte *rhs)
- {
- return Copy((const char *)rhs, strlen((const char *)rhs));
- }
- inline rcSTR_String operator=(rcSTR_String rhs)
- {
- return Copy(rhs.ReadPtr(), rhs.Length());
- }
- inline rcSTR_String operator=(char rhs)
- {
- return Copy(&rhs, 1);
- }
- inline rcSTR_String operator=(const char *rhs)
- {
- return Copy(rhs, strlen(rhs));
- }
-
- inline rcSTR_String operator+=(const char *rhs)
- {
- return Concat(rhs, strlen(rhs));
- }
- inline rcSTR_String operator+=(rcSTR_String rhs)
- {
- return Concat(rhs.ReadPtr(), rhs.Length());
- }
- inline rcSTR_String operator+=(char rhs)
- {
- return Concat(&rhs, 1);
- }
-
- inline friend bool operator<(rcSTR_String lhs, rcSTR_String rhs)
- {
- return (strcmp(lhs, rhs) < 0);
- }
- inline friend bool operator<(rcSTR_String lhs, const char *rhs)
- {
- return (strcmp(lhs, rhs) < 0);
- }
- inline friend bool operator<(const char *lhs, rcSTR_String rhs)
- {
- return (strcmp(lhs, rhs) < 0);
- }
- inline friend bool operator>(rcSTR_String lhs, rcSTR_String rhs)
- {
- return (strcmp(lhs, rhs) > 0);
- }
- inline friend bool operator>(rcSTR_String lhs, const char *rhs)
- {
- return (strcmp(lhs, rhs) > 0);
- }
- inline friend bool operator>(const char *lhs, rcSTR_String rhs)
- {
- return (strcmp(lhs, rhs) > 0);
- }
- inline friend bool operator<=(rcSTR_String lhs, rcSTR_String rhs)
- {
- return (strcmp(lhs, rhs) <= 0);
- }
- inline friend bool operator<=(rcSTR_String lhs, const char *rhs)
- {
- return (strcmp(lhs, rhs) <= 0);
- }
- inline friend bool operator<=(const char *lhs, rcSTR_String rhs)
- {
- return (strcmp(lhs, rhs) <= 0);
- }
- inline friend bool operator>=(rcSTR_String lhs, rcSTR_String rhs)
- {
- return (strcmp(lhs, rhs) >= 0);
- }
- inline friend bool operator>=(rcSTR_String lhs, const char *rhs)
- {
- return (strcmp(lhs, rhs) >= 0);
- }
- inline friend bool operator>=(const char *lhs, rcSTR_String rhs)
- {
- return (strcmp(lhs, rhs) >= 0);
- }
- inline friend bool operator==(rcSTR_String lhs, rcSTR_String rhs)
- {
- return ((lhs.Length() == rhs.Length()) && (memcmp(lhs, rhs, lhs.Length()) == 0));
- }
- inline friend bool operator==(rcSTR_String lhs, const char *rhs)
- {
- return (strncmp(lhs, rhs, lhs.Length() + 1) == 0);
- }
- inline friend bool operator==(const char *lhs, rcSTR_String rhs)
- {
- return (strncmp(lhs, rhs, rhs.Length() + 1) == 0);
- }
- inline friend bool operator!=(rcSTR_String lhs, rcSTR_String rhs)
- {
- return ((lhs.Length() != rhs.Length()) || (memcmp(lhs, rhs, lhs.Length()) != 0));
- }
- inline friend bool operator!=(rcSTR_String lhs, const char *rhs)
- {
- return (strncmp(lhs, rhs, lhs.Length() + 1) != 0);
- }
- inline friend bool operator!=(const char *lhs, rcSTR_String rhs)
- {
- return (strncmp(lhs, rhs, rhs.Length() + 1) != 0);
- }
-
- // serializing
- // int Serialize(pCStream stream);
-
- protected:
- // Implementation
- void AllocBuffer(int len, bool keep_contents);
- rcSTR_String Copy(const char *src, int len);
- rcSTR_String Concat(const char *data, int len);
-
- static bool isLower(char c)
- {
- return !isUpper(c);
- }
- static bool isUpper(char c)
- {
- return (c >= 'A') && (c <= 'Z');
- }
- static bool isSpace(char c)
- {
- return (c == ' ') || (c == '\t');
- }
-
- char *m_data; // -> STR_String data
- int m_len; // z Data length
- int m_max; // Space in data buffer
-
-#ifdef WITH_CXX_GUARDEDALLOC
- MEM_CXX_CLASS_ALLOC_FUNCS("CXX:STR_String")
-#endif
-};
-
-inline STR_String operator+(rcSTR_String lhs, rcSTR_String rhs)
-{
- return STR_String(lhs.ReadPtr(), lhs.Length(), rhs.ReadPtr(), rhs.Length());
-}
-inline STR_String operator+(rcSTR_String lhs, char rhs)
-{
- return STR_String(lhs.ReadPtr(), lhs.Length(), &rhs, 1);
-}
-inline STR_String operator+(char lhs, rcSTR_String rhs)
-{
- return STR_String(&lhs, 1, rhs.ReadPtr(), rhs.Length());
-}
-inline STR_String operator+(rcSTR_String lhs, const char *rhs)
-{
- return STR_String(lhs.ReadPtr(), lhs.Length(), rhs, strlen(rhs));
-}
-inline STR_String operator+(const char *lhs, rcSTR_String rhs)
-{
- return STR_String(lhs, strlen(lhs), rhs.ReadPtr(), rhs.Length());
-}
-
-#endif //__STR_STRING_H__
diff --git a/intern/string/intern/STR_String.cpp b/intern/string/intern/STR_String.cpp
deleted file mode 100644
index 306e786969b..00000000000
--- a/intern/string/intern/STR_String.cpp
+++ /dev/null
@@ -1,637 +0,0 @@
-/*
- * 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.
- *
- * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
- * All rights reserved.
- */
-
-/** \file
- * \ingroup string
- *
- * Copyright (C) 2001 NaN Technologies B.V.
- * This file was formerly known as: GEN_StdString.cpp.
- */
-
-#include "STR_String.h"
-#include <ctype.h>
-#include <stdarg.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-/*-------------------------------------------------------------------------------------------------
- Construction / destruction
--------------------------------------------------------------------------------------------------*/
-
-#define STR_STRING_SIZE_DEFAULT_WORD 32 /* default size for a new word */
-#define STR_STRING_SIZE_DEFAULT_CHAR 9 /* default size for a new char */
-
-//
-// Construct an empty string
-//
-STR_String::STR_String()
- : m_data(new char[STR_STRING_SIZE_DEFAULT_WORD]), m_len(0), m_max(STR_STRING_SIZE_DEFAULT_WORD)
-{
- this->m_data[0] = 0;
-}
-
-//
-// Construct a string of one character
-//
-STR_String::STR_String(char c)
- : m_data(new char[STR_STRING_SIZE_DEFAULT_CHAR]), m_len(1), m_max(STR_STRING_SIZE_DEFAULT_CHAR)
-{
- this->m_data[0] = c;
- this->m_data[1] = 0;
-}
-
-//
-// Construct a string of multiple repeating characters
-//
-STR_String::STR_String(char c, int len) : m_data(new char[len + 8]), m_len(len), m_max(len + 8)
-{
- assertd(this->m_data != NULL);
- memset(this->m_data, c, len);
- this->m_data[len] = 0;
-}
-
-//
-// Construct a string from a pointer-to-ASCIIZ-string
-//
-// MAART: Changed to test for null strings
-STR_String::STR_String(const char *str)
-{
- if (str) {
- this->m_len = ::strlen(str);
- this->m_max = this->m_len + 8;
- this->m_data = new char[this->m_max];
- assertd(this->m_data != NULL);
- ::memcpy(this->m_data, str, this->m_len);
- this->m_data[this->m_len] = 0;
- }
- else {
- this->m_data = NULL;
- this->m_len = 0;
- this->m_max = 8;
- }
-}
-
-//
-// Construct a string from a pointer-to-ASCII-string and a length
-//
-STR_String::STR_String(const char *str, int len)
- : m_data(new char[len + 8]), m_len(len), m_max(len + 8)
-{
- assertd(this->m_data != NULL);
- memcpy(this->m_data, str, len);
- this->m_data[len] = 0;
-}
-
-//
-// Construct a string from another string
-//
-STR_String::STR_String(rcSTR_String str)
- : m_data(new char[str.Length() + 8]), m_len(str.Length()), m_max(str.Length() + 8)
-{
- assertd(this->m_data != NULL);
- assertd(str.this->m_data != NULL);
- memcpy(this->m_data, str.ReadPtr(), str.Length());
- this->m_data[str.Length()] = 0;
-}
-
-//
-// Construct a string from the first number of characters in another string
-//
-STR_String::STR_String(rcSTR_String str, int len)
- : m_data(new char[len + 8]), m_len(len), m_max(len + 8)
-{
- assertd(this->m_data != NULL);
- assertd(str.this->m_data != NULL);
- memcpy(this->m_data, str.ReadPtr(), str.Length());
- this->m_data[str.Length()] = 0;
-}
-
-//
-// Create a string by concatenating two sources
-//
-STR_String::STR_String(const char *src1, int len1, const char *src2, int len2)
- : m_data(new char[len1 + len2 + 8]), m_len(len1 + len2), m_max(len1 + len2 + 8)
-{
- assertd(this->m_data != NULL);
- memcpy(this->m_data, src1, len1);
- memcpy(this->m_data + len1, src2, len2);
- this->m_data[len1 + len2] = 0;
-}
-
-//
-// Create a string with an integer value
-//
-STR_String::STR_String(int val)
- : m_data(new char[STR_STRING_SIZE_DEFAULT_WORD]), m_max(STR_STRING_SIZE_DEFAULT_WORD)
-{
- assertd(this->m_data != NULL);
- this->m_len = sprintf(this->m_data, "%d", val);
-}
-
-//
-// Create a string with a dword value
-//
-STR_String::STR_String(dword val)
- : m_data(new char[STR_STRING_SIZE_DEFAULT_WORD]), m_max(STR_STRING_SIZE_DEFAULT_WORD)
-{
- assertd(this->m_data != NULL);
- this->m_len = sprintf(this->m_data, "%lu", val);
-}
-
-//
-// Create a string with a floating point value
-//
-STR_String::STR_String(float val)
- : m_data(new char[STR_STRING_SIZE_DEFAULT_WORD]), m_max(STR_STRING_SIZE_DEFAULT_WORD)
-{
- assertd(this->m_data != NULL);
- this->m_len = sprintf(this->m_data, "%g", val);
-}
-
-//
-// Create a string with a double value
-//
-STR_String::STR_String(double val)
- : m_data(new char[STR_STRING_SIZE_DEFAULT_WORD]), m_max(STR_STRING_SIZE_DEFAULT_WORD)
-{
- assertd(this->m_data != NULL);
- this->m_len = sprintf(this->m_data, "%g", val);
-}
-
-/*-------------------------------------------------------------------------------------------------
- Buffer management
--------------------------------------------------------------------------------------------------*/
-
-//
-// Make sure that the allocated buffer is at least <len> in size
-//
-void STR_String::AllocBuffer(int len, bool keep_contents)
-{
- // Check if we have enough space
- if (len + 1 <= this->m_max)
- return;
-
- // Reallocate string
- char *new_data = new char[len + 8];
- if (keep_contents) {
- memcpy(new_data, this->m_data, this->m_len);
- }
- delete[] this->m_data;
-
- // Accept new data
- this->m_max = len + 8;
- this->m_data = new_data;
- assertd(this->m_data != NULL);
-}
-
-/*-------------------------------------------------------------------------------------------------
- Basic string operations
--------------------------------------------------------------------------------------------------*/
-
-//
-// Format string (as does sprintf)
-//
-STR_String &STR_String::Format(const char *fmt, ...)
-{
- AllocBuffer(2048, false);
-
- assertd(this->m_data != NULL);
- // Expand arguments and format to string
- va_list args;
- va_start(args, fmt);
- this->m_len = vsprintf(this->m_data, fmt, args);
- assertd(this->m_len <= 2048);
- va_end(args);
-
- return *this;
-}
-
-//
-// Format string (as does sprintf)
-//
-STR_String &STR_String::FormatAdd(const char *fmt, ...)
-{
- AllocBuffer(2048, false);
-
- assertd(this->m_data != NULL);
- // Expand arguments and format to string
- va_list args;
- va_start(args, fmt);
- this->m_len += vsprintf(this->m_data + this->m_len, fmt, args);
- assertd(this->m_len <= 2048);
- va_end(args);
-
- return *this;
-}
-
-/*-------------------------------------------------------------------------------------------------
- Properties
--------------------------------------------------------------------------------------------------*/
-
-//
-// Check if string is entirely in UPPERCase
-//
-bool STR_String::IsUpper() const
-{
- for (int i = 0; i < this->m_len; i++)
- if (isLower(this->m_data[i]))
- return false;
-
- return true;
-}
-
-//
-// Check if string is entirely in lowerCase
-//
-bool STR_String::IsLower() const
-{
- for (int i = 0; i < this->m_len; i++)
- if (isUpper(this->m_data[i]))
- return false;
-
- return true;
-}
-
-/*-------------------------------------------------------------------------------------------------
- Search/Replace
--------------------------------------------------------------------------------------------------*/
-
-//
-// Find the first orccurence of <c> in the string
-//
-int STR_String::Find(char c, int pos) const
-{
- assertd(pos >= 0);
- assertd(this->m_len == 0 || pos < this->m_len);
- assertd(this->m_data != NULL);
- char *find_pos = strchr(this->m_data + pos, c);
- return (find_pos) ? (find_pos - this->m_data) : -1;
-}
-
-//
-// Find the first occurrence of <str> in the string
-//
-int STR_String::Find(const char *str, int pos) const
-{
- assertd(pos >= 0);
- assertd(this->m_len == 0 || pos < this->m_len);
- assertd(this->m_data != NULL);
- char *find_pos = strstr(this->m_data + pos, str);
- return (find_pos) ? (find_pos - this->m_data) : -1;
-}
-
-//
-// Find the first occurrence of <str> in the string
-//
-int STR_String::Find(rcSTR_String str, int pos) const
-{
- assertd(pos >= 0);
- assertd(this->m_len == 0 || pos < this->m_len);
- assertd(this->m_data != NULL);
- char *find_pos = strstr(this->m_data + pos, str.ReadPtr());
- return (find_pos) ? (find_pos - this->m_data) : -1;
-}
-
-//
-// Find the last occurrence of <c> in the string
-//
-int STR_String::RFind(char c) const
-{
- assertd(this->m_data != NULL);
- char *pos = strrchr(this->m_data, c);
- return (pos) ? (pos - this->m_data) : -1;
-}
-
-//
-// Find the first occurrence of any character in character set <set> in the string
-//
-int STR_String::FindOneOf(const char *set, int pos) const
-{
- assertd(pos >= 0);
- assertd(this->m_len == 0 || pos < this->m_len);
- assertd(this->m_data != NULL);
- char *find_pos = strpbrk(this->m_data + pos, set);
- return (find_pos) ? (find_pos - this->m_data) : -1;
-}
-
-//
-// Replace a character in this string with another string
-//
-void STR_String::Replace(int pos, rcSTR_String str)
-{
- // bounds(pos, 0, Length()-1);
-
- if (str.Length() < 1) {
- // Remove one character from the string
- memcpy(this->m_data + pos, this->m_data + pos + 1, this->m_len - pos);
- }
- else {
- // Insert zero or more characters into the string
- AllocBuffer(this->m_len + str.Length() - 1, true);
- if (str.Length() != 1)
- memcpy(this->m_data + pos + str.Length(), this->m_data + pos + 1, Length() - pos);
- memcpy(this->m_data + pos, str.ReadPtr(), str.Length());
- }
-
- this->m_len += str.Length() - 1;
-}
-
-//
-// Replace a substring of this string with another string
-//
-void STR_String::Replace(int pos, int num, rcSTR_String str)
-{
- // bounds(pos, 0, Length()-1);
- // bounds(pos+num, 0, Length());
- assertd(num >= 1);
-
- if (str.Length() < num) {
- // Remove some data from the string by replacement
- memcpy(
- this->m_data + pos + str.Length(), this->m_data + pos + num, this->m_len - pos - num + 1);
- memcpy(this->m_data + pos, str.ReadPtr(), str.Length());
- }
- else {
- // Insert zero or more characters into the string
- AllocBuffer(this->m_len + str.Length() - num, true);
- if (str.Length() != num)
- memcpy(
- this->m_data + pos + str.Length(), this->m_data + pos + num, Length() - pos - num + 1);
- memcpy(this->m_data + pos, str.ReadPtr(), str.Length());
- }
-
- this->m_len += str.Length() - num;
-}
-
-/*-------------------------------------------------------------------------------------------------
- Comparison
--------------------------------------------------------------------------------------------------*/
-
-//
-// Compare two strings and return the result,
-// <0 if *this<rhs, >0 if *this>rhs or 0 if *this==rhs
-//
-int STR_String::Compare(rcSTR_String rhs) const
-{
- return strcmp(this->ReadPtr(), rhs.ReadPtr());
-}
-
-//
-// Compare two strings without respecting case and return the result,
-// <0 if *this<rhs, >0 if *this>rhs or 0 if *this==rhs
-//
-int STR_String::CompareNoCase(rcSTR_String rhs) const
-{
-#ifdef WIN32
- return stricmp(this->ReadPtr(), rhs.ReadPtr());
-#else
- return strcasecmp(this->ReadPtr(), rhs.ReadPtr());
-#endif
-}
-
-/*-------------------------------------------------------------------------------------------------
- Formatting
--------------------------------------------------------------------------------------------------*/
-
-//
-// Capitalize string, "heLLo" -> "HELLO"
-//
-STR_String &STR_String::Upper()
-{
- assertd(this->m_data != NULL);
-#ifdef WIN32
- _strupr(this->m_data);
-#else
- for (int i = 0; i < this->m_len; i++)
- this->m_data[i] = (this->m_data[i] >= 'a' && this->m_data[i] <= 'z') ?
- this->m_data[i] + 'A' - 'a' :
- this->m_data[i];
-#endif
- return *this;
-}
-
-//
-// Lower string, "heLLo" -> "hello"
-//
-STR_String &STR_String::Lower()
-{
- assertd(this->m_data != NULL);
-#ifdef WIN32
- _strlwr(this->m_data);
-#else
- for (int i = 0; i < this->m_len; i++)
- this->m_data[i] = (this->m_data[i] >= 'A' && this->m_data[i] <= 'Z') ?
- this->m_data[i] + 'a' - 'A' :
- this->m_data[i];
-#endif
- return *this;
-}
-
-//
-// Capitalize string, "heLLo" -> "Hello"
-//
-STR_String &STR_String::Capitalize()
-{
- assertd(this->m_data != NULL);
-#ifdef WIN32
- if (this->m_len > 0)
- this->m_data[0] = toupper(this->m_data[0]);
- if (this->m_len > 1)
- _strlwr(this->m_data + 1);
-#else
- if (this->m_len > 0)
- this->m_data[0] = (this->m_data[0] >= 'a' && this->m_data[0] <= 'z') ?
- this->m_data[0] + 'A' - 'a' :
- this->m_data[0];
- for (int i = 1; i < this->m_len; i++)
- this->m_data[i] = (this->m_data[i] >= 'A' && this->m_data[i] <= 'Z') ?
- this->m_data[i] + 'a' - 'A' :
- this->m_data[i];
-#endif
- return *this;
-}
-
-//
-// Trim whitespace from the left side of the string
-//
-STR_String &STR_String::TrimLeft()
-{
- int skip;
- assertd(this->m_data != NULL);
- for (skip = 0; isSpace(this->m_data[skip]); skip++, this->m_len--) {
- /* pass */
- }
- memmove(this->m_data, this->m_data + skip, this->m_len + 1);
- return *this;
-}
-
-//
-// Trim whitespaces from the right side of the string
-//
-STR_String &STR_String::TrimRight()
-{
- assertd(this->m_data != NULL);
- while (this->m_len && isSpace(this->m_data[this->m_len - 1]))
- this->m_len--;
- this->m_data[this->m_len] = 0;
- return *this;
-}
-
-//
-// Trim spaces from both sides of the character set
-//
-STR_String &STR_String::Trim()
-{
- TrimRight();
- TrimLeft();
- return *this;
-}
-
-//
-// Trim characters from the character set <set> from the left side of the string
-//
-STR_String &STR_String::TrimLeft(char *set)
-{
- int skip;
- assertd(this->m_data != NULL);
- for (skip = 0; this->m_len && strchr(set, this->m_data[skip]); skip++, this->m_len--) {
- /* pass */
- }
- memmove(this->m_data, this->m_data + skip, this->m_len + 1);
- return *this;
-}
-
-//
-// Trim characters from the character set <set> from the right side of the string
-//
-STR_String &STR_String::TrimRight(char *set)
-{
- assertd(this->m_data != NULL);
- while (this->m_len && strchr(set, this->m_data[this->m_len - 1]))
- this->m_len--;
- this->m_data[this->m_len] = 0;
- return *this;
-}
-
-//
-// Trim characters from the character set <set> from both sides of the character set
-//
-STR_String &STR_String::Trim(char *set)
-{
- TrimRight(set);
- TrimLeft(set);
- return *this;
-}
-
-//
-// Trim quotes from both sides of the string
-//
-STR_String &STR_String::TrimQuotes()
-{
- // Trim quotes if they are on both sides of the string
- assertd(this->m_data != NULL);
- if ((this->m_len >= 2) && (this->m_data[0] == '\"') && (this->m_data[this->m_len - 1] == '\"')) {
- memmove(this->m_data, this->m_data + 1, this->m_len - 2 + 1);
- this->m_len -= 2;
- }
- return *this;
-}
-
-/*-------------------------------------------------------------------------------------------------
- Assignment/Concatenation
--------------------------------------------------------------------------------------------------*/
-
-//
-// Set the string's conents to a copy of <src> with length <len>
-//
-rcSTR_String STR_String::Copy(const char *src, int len)
-{
- assertd(len >= 0);
- assertd(src);
- assertd(this->m_data != NULL);
-
- AllocBuffer(len, false);
- this->m_len = len;
- memcpy(this->m_data, src, len);
- this->m_data[this->m_len] = 0;
-
- return *this;
-}
-
-//
-// Concate a number of bytes to the current string
-//
-rcSTR_String STR_String::Concat(const char *data, int len)
-{
- assertd(this->m_len >= 0);
- assertd(len >= 0);
- assertd(data);
- assertd(this->m_data != NULL);
-
- AllocBuffer(this->m_len + len, true);
- memcpy(this->m_data + this->m_len, data, len);
- this->m_len += len;
- this->m_data[this->m_len] = 0;
-
- return *this;
-}
-
-std::vector<STR_String> STR_String::Explode(char c) const
-{
- STR_String lcv = *this;
- std::vector<STR_String> uc;
-
- while (lcv.Length()) {
- int pos = lcv.Find(c);
- if (pos < 0) {
- uc.push_back(lcv);
- lcv.Clear();
- }
- else {
- uc.push_back(lcv.Left(pos));
- lcv = lcv.Mid(pos + 1);
- }
- }
-
- // uc. -= STR_String("");
-
- return uc;
-}
-
-#if 0
-
-int STR_String::Serialize(pCStream stream)
-{
- if (stream->GetAccess() == CStream::Access_Read) {
- int ln;
- stream->Read(&ln, sizeof(ln));
- AllocBuffer(ln, false);
- stream->Read(this->m_data, ln);
- this->m_data[ln] = '\0';
- this->m_len = ln;
- }
- else {
- stream->Write(&this->m_len, sizeof(this->m_len));
- stream->Write(this->m_data, this->m_len);
- }
-
- return this->m_len + sizeof(this->m_len);
-}
-#endif