2026-02-16
This commit is contained in:
@@ -205,7 +205,12 @@ class FlipFluidAddQuickLiquid(bpy.types.Operator):
|
||||
|
||||
# Domain Settings
|
||||
domain_properties = bpy.context.scene.flip_fluid.get_domain_properties()
|
||||
domain_properties.materials.surface_material = 'FF Water (ocean volumetric)'
|
||||
|
||||
try:
|
||||
# Materials may not be available depending on addon version
|
||||
domain_properties.materials.surface_material = 'FF Water (ocean volumetric)'
|
||||
except:
|
||||
pass
|
||||
|
||||
# Surface Settings
|
||||
domain_properties = bpy.context.scene.flip_fluid.get_domain_properties()
|
||||
@@ -282,9 +287,14 @@ class FlipFluidAddThickViscousLiquid(bpy.types.Operator):
|
||||
domain_props.surface.subdivisions = 2
|
||||
domain_props.world.enable_viscosity = True
|
||||
domain_props.world.viscosity = 15
|
||||
domain_props.materials.surface_material = 'FF Caramel'
|
||||
domain_props.advanced.jitter_surface_particles = True
|
||||
|
||||
try:
|
||||
# Materials may not be available depending on addon version
|
||||
domain_props.materials.surface_material = 'FF Caramel'
|
||||
except:
|
||||
pass
|
||||
|
||||
# Create Inflow
|
||||
bpy.ops.mesh.primitive_cylinder_add(radius=0.25, location=(-0.125, -0.125, 1.25 + z_offset), scale=(0.4, 0.4, 0.25))
|
||||
bl_cylinder = bpy.context.active_object
|
||||
@@ -402,9 +412,14 @@ class FlipFluidAddThinViscousLiquid(bpy.types.Operator):
|
||||
domain_props.world.surface_tension_settings_expaned = True
|
||||
domain_props.world.enable_surface_tension = True
|
||||
domain_props.world.surface_tension = 0.3
|
||||
domain_props.materials.surface_material = 'FF Caramel'
|
||||
domain_props.advanced.jitter_surface_particles = True
|
||||
|
||||
try:
|
||||
# Materials may not be available depending on addon version
|
||||
domain_props.materials.surface_material = 'FF Caramel'
|
||||
except:
|
||||
pass
|
||||
|
||||
# Create Inflow
|
||||
bpy.ops.mesh.primitive_cylinder_add(radius=0.25, location=(-0.5, -0.5, 0.0 + z_offset), scale=(0.4, 0.4, 0.125))
|
||||
bl_cylinder = bpy.context.active_object
|
||||
|
||||
@@ -39,47 +39,42 @@ class FLIPFluidsAlembicImporter(bpy.types.Operator, bpy_extras.io_utils.ImportHe
|
||||
return bl_object
|
||||
|
||||
|
||||
def apply_default_modifier_settings(self, target_object, gn_modifier):
|
||||
gn_modifier["Input_2_use_attribute"] = True
|
||||
gn_modifier["Input_2_attribute_name"] = 'flip_velocity'
|
||||
gn_modifier["Output_3_attribute_name"] = 'velocity'
|
||||
def apply_default_modifier_settings(self, target_object, domain_object, surface_object, gn_modifier):
|
||||
# Apply Simulation Time Scale and Apply Simulation Time Scale should be disabled.
|
||||
# These modifier features require a FLIP Domain and addon scripting to function. If enabled,
|
||||
# motion blur velocity will be set to (0.0, 0.0, 0.0)
|
||||
key_value_pairs_surface = [
|
||||
("Input_6", True), # Enable Motion Blur
|
||||
("Socket_8", False), # Apply Simulation Time Scale - Disable: Requires FLIP Domain and addon scripting
|
||||
("Socket_9", False), # Apply Simulation Time Scale - Disable: Requires FLIP Domain and addon scripting
|
||||
("Socket_7", domain_object), # FLIP Domain Object
|
||||
]
|
||||
|
||||
key_value_pairs_particles = [
|
||||
("Input_8", True), # Enable Motion Blur
|
||||
("Socket_47", False), # Apply Simulation Time Scale - Disable: Requires FLIP Domain and addon scripting
|
||||
("Socket_48", False), # Apply Simulation World Scale - Disable: Requires FLIP Domain and addon scripting
|
||||
("Socket_46", domain_object), # FLIP Domain Object
|
||||
("Socket_49", surface_object), # FLIP Surface Object
|
||||
]
|
||||
|
||||
# Depending on FLIP Fluids version, the GN set up may not
|
||||
# have these inputs.
|
||||
|
||||
gn_name = gn_modifier.name
|
||||
if gn_name.startswith("FF_GeometryNodesSurface"):
|
||||
# Depending on FLIP Fluids version, the GN set up may not
|
||||
# have these inputs. Available in FLIP Fluids 1.7.2 or later.
|
||||
try:
|
||||
# Enable Motion Blur
|
||||
gn_modifier["Input_6"] = True
|
||||
except:
|
||||
pass
|
||||
if gn_name.startswith("FF_GeometryNodesAlembicSurface"):
|
||||
for (key, value) in key_value_pairs_surface:
|
||||
try:
|
||||
gn_modifier[key] = value
|
||||
except:
|
||||
pass
|
||||
|
||||
if gn_name.startswith("FF_GeometryNodesWhitewater") or gn_name.startswith("FF_GeometryNodesFluidParticles"):
|
||||
# Depending on FLIP Fluids version, the GN set up may not
|
||||
# have these inputs. Available in FLIP Fluids 1.7.2 or later.
|
||||
try:
|
||||
# Material
|
||||
gn_modifier["Input_5"] = target_object.active_material
|
||||
except:
|
||||
pass
|
||||
|
||||
try:
|
||||
# Enable Motion Blur
|
||||
gn_modifier["Input_8"] = True
|
||||
except:
|
||||
pass
|
||||
|
||||
try:
|
||||
# Enable Point Cloud
|
||||
gn_modifier["Input_9"] = True
|
||||
except:
|
||||
pass
|
||||
|
||||
try:
|
||||
# Enable Instancing
|
||||
gn_modifier["Input_10"] = False
|
||||
except:
|
||||
pass
|
||||
if gn_name.startswith("FF_GeometryNodesAlembicParticles"):
|
||||
for (key, value) in key_value_pairs_particles:
|
||||
try:
|
||||
gn_modifier[key] = value
|
||||
except:
|
||||
pass
|
||||
|
||||
|
||||
def add_smooth_modifier(self, target_object):
|
||||
@@ -89,11 +84,25 @@ class FLIPFluidsAlembicImporter(bpy.types.Operator, bpy_extras.io_utils.ImportHe
|
||||
return smooth_mod
|
||||
|
||||
|
||||
def toggle_cycles_ray_visibility(self, obj, is_enabled):
|
||||
# Cycles may not be enabled in the user's preferences
|
||||
try:
|
||||
obj.visible_camera = is_enabled
|
||||
obj.visible_diffuse = is_enabled
|
||||
obj.visible_glossy = is_enabled
|
||||
obj.visible_transmission = is_enabled
|
||||
obj.visible_volume_scatter = is_enabled
|
||||
obj.visible_shadow = is_enabled
|
||||
except:
|
||||
pass
|
||||
|
||||
|
||||
def execute(self, context):
|
||||
print("FLIP Fluids Alembic Import: <" + self.filepath + ">")
|
||||
|
||||
bpy.ops.wm.alembic_import(filepath=self.filepath)
|
||||
bpy.ops.wm.alembic_import(filepath=self.filepath, always_add_cache_reader=True)
|
||||
|
||||
bl_domain = self.find_flip_fluids_mesh(bpy.context.selected_objects, "FLIP_Domain")
|
||||
bl_fluid_surface = self.find_flip_fluids_mesh(bpy.context.selected_objects, "fluid_surface")
|
||||
bl_fluid_particles = self.find_flip_fluids_mesh(bpy.context.selected_objects, "fluid_particles")
|
||||
bl_whitewater_foam = self.find_flip_fluids_mesh(bpy.context.selected_objects, "whitewater_foam")
|
||||
@@ -107,46 +116,51 @@ class FLIPFluidsAlembicImporter(bpy.types.Operator, bpy_extras.io_utils.ImportHe
|
||||
|
||||
found_mesh_cache_list = []
|
||||
|
||||
if bl_domain is not None:
|
||||
bl_domain.hide_render = True
|
||||
bl_domain.display_type = 'BOUNDS'
|
||||
self.toggle_cycles_ray_visibility(bl_domain, False)
|
||||
|
||||
if bl_fluid_surface is not None:
|
||||
self.add_smooth_modifier(bl_fluid_surface)
|
||||
helper_operators.add_geometry_node_modifier(bl_fluid_surface, resource_filepath, "FF_AlembicImportSurface")
|
||||
gn_modifier = helper_operators.add_geometry_node_modifier(bl_fluid_surface, resource_filepath, "FF_GeometryNodesSurface")
|
||||
self.apply_default_modifier_settings(bl_fluid_surface, gn_modifier)
|
||||
gn_modifier = helper_operators.add_geometry_node_modifier(bl_fluid_surface, resource_filepath, "FF_GeometryNodesAlembicSurface")
|
||||
self.apply_default_modifier_settings(bl_fluid_surface, bl_domain, bl_fluid_surface, gn_modifier)
|
||||
self.report({'INFO'}, "Found fluid surface cache... Initialized geometry nodes")
|
||||
found_mesh_cache_list.append("Surface")
|
||||
|
||||
if bl_fluid_particles is not None:
|
||||
helper_operators.add_geometry_node_modifier(bl_fluid_particles, resource_filepath, "FF_AlembicImportFluidParticles")
|
||||
gn_modifier = helper_operators.add_geometry_node_modifier(bl_fluid_particles, resource_filepath, "FF_GeometryNodesFluidParticles")
|
||||
self.apply_default_modifier_settings(bl_fluid_particles, gn_modifier)
|
||||
gn_modifier = helper_operators.add_geometry_node_modifier(bl_fluid_particles, resource_filepath, "FF_GeometryNodesAlembicParticles")
|
||||
self.apply_default_modifier_settings(bl_fluid_particles, bl_domain, bl_fluid_surface, gn_modifier)
|
||||
self.report({'INFO'}, "Found fluid particle cache... Initialized geometry nodes")
|
||||
found_mesh_cache_list.append("FluidParticles")
|
||||
|
||||
if bl_whitewater_foam is not None:
|
||||
helper_operators.add_geometry_node_modifier(bl_whitewater_foam, resource_filepath, "FF_AlembicImportWhitewaterFoam")
|
||||
gn_modifier = helper_operators.add_geometry_node_modifier(bl_whitewater_foam, resource_filepath, "FF_GeometryNodesWhitewaterFoam")
|
||||
self.apply_default_modifier_settings(bl_whitewater_foam, gn_modifier)
|
||||
gn_modifier = helper_operators.add_geometry_node_modifier(bl_whitewater_foam, resource_filepath, "FF_GeometryNodesAlembicParticles")
|
||||
self.apply_default_modifier_settings(bl_whitewater_foam, bl_domain, bl_fluid_surface, gn_modifier)
|
||||
self.report({'INFO'}, "Found whitewater foam cache... Initialized geometry nodes")
|
||||
found_mesh_cache_list.append("Foam")
|
||||
|
||||
if bl_whitewater_bubble is not None:
|
||||
helper_operators.add_geometry_node_modifier(bl_whitewater_bubble, resource_filepath, "FF_AlembicImportWhitewaterBubble")
|
||||
gn_modifier = helper_operators.add_geometry_node_modifier(bl_whitewater_bubble, resource_filepath, "FF_GeometryNodesWhitewaterBubble")
|
||||
self.apply_default_modifier_settings(bl_whitewater_bubble, gn_modifier)
|
||||
gn_modifier = helper_operators.add_geometry_node_modifier(bl_whitewater_bubble, resource_filepath, "FF_GeometryNodesAlembicParticles")
|
||||
self.apply_default_modifier_settings(bl_whitewater_bubble, bl_domain, bl_fluid_surface, gn_modifier)
|
||||
self.report({'INFO'}, "Found whitewater bubble cache... Initialized geometry nodes")
|
||||
found_mesh_cache_list.append("Bubble")
|
||||
|
||||
if bl_whitewater_spray is not None:
|
||||
helper_operators.add_geometry_node_modifier(bl_whitewater_spray, resource_filepath, "FF_AlembicImportWhitewaterSpray")
|
||||
gn_modifier = helper_operators.add_geometry_node_modifier(bl_whitewater_spray, resource_filepath, "FF_GeometryNodesWhitewaterSpray")
|
||||
self.apply_default_modifier_settings(bl_whitewater_spray, gn_modifier)
|
||||
gn_modifier = helper_operators.add_geometry_node_modifier(bl_whitewater_spray, resource_filepath, "FF_GeometryNodesAlembicParticles")
|
||||
self.apply_default_modifier_settings(bl_whitewater_spray, bl_domain, bl_fluid_surface, gn_modifier)
|
||||
self.report({'INFO'}, "Found whitewater spray cache... Initialized geometry nodes")
|
||||
found_mesh_cache_list.append("Spray")
|
||||
|
||||
if bl_whitewater_dust is not None:
|
||||
helper_operators.add_geometry_node_modifier(bl_whitewater_dust, resource_filepath, "FF_AlembicImportWhitewaterDust")
|
||||
gn_modifier = helper_operators.add_geometry_node_modifier(bl_whitewater_dust, resource_filepath, "FF_GeometryNodesWhitewaterDust")
|
||||
self.apply_default_modifier_settings(bl_whitewater_dust, gn_modifier)
|
||||
gn_modifier = helper_operators.add_geometry_node_modifier(bl_whitewater_dust, resource_filepath, "FF_GeometryNodesAlembicParticles")
|
||||
self.apply_default_modifier_settings(bl_whitewater_dust, bl_domain, bl_fluid_surface, gn_modifier)
|
||||
self.report({'INFO'}, "Found whitewater dust cache... Initialized geometry nodes")
|
||||
found_mesh_cache_list.append("Dust")
|
||||
|
||||
@@ -177,12 +191,17 @@ class FLIPFluidsAlembicExporter(bpy.types.Operator, bpy_extras.io_utils.ExportHe
|
||||
return context.scene.flip_fluid.get_domain_object() is not None and bool(bpy.data.filepath)
|
||||
|
||||
|
||||
def draw(self, context):
|
||||
def draw_alembic_export_engine_blender(self, context):
|
||||
hprops = context.scene.flip_fluid_helper
|
||||
|
||||
self.layout.use_property_split = True
|
||||
self.layout.use_property_decorate = False
|
||||
|
||||
header, body = self.layout.panel("alembic_export_engine", default_closed=False)
|
||||
header.label(text="Alembic Exporter")
|
||||
if body:
|
||||
column = body.column(align=True)
|
||||
column.prop(hprops, "alembic_export_engine", text="Engine")
|
||||
|
||||
header, body = self.layout.panel("alembic_scene", default_closed=False)
|
||||
header.label(text="Scene")
|
||||
if body:
|
||||
@@ -217,16 +236,116 @@ class FLIPFluidsAlembicExporter(bpy.types.Operator, bpy_extras.io_utils.ExportHe
|
||||
header, body = self.layout.panel("alembic_command", default_closed=True)
|
||||
header.label(text="Command")
|
||||
if body:
|
||||
column = body.column(heading="Attributes", align=True)
|
||||
hprops = context.scene.flip_fluid_helper
|
||||
column = body.column(heading="Command", align=True)
|
||||
column.operator("flip_fluid_operators.helper_cmd_alembic_export_to_clipboard", text="Copy Command to Clipboard", icon='COPYDOWN')
|
||||
|
||||
|
||||
def draw_alembic_export_engine_flip_fluids(self, context):
|
||||
hprops = context.scene.flip_fluid_helper
|
||||
self.layout.use_property_split = True
|
||||
self.layout.use_property_decorate = False
|
||||
|
||||
header, body = self.layout.panel("alembic_export_engine", default_closed=False)
|
||||
header.label(text="Alembic Exporter")
|
||||
if body:
|
||||
column = body.column(align=True)
|
||||
column.prop(hprops, "alembic_export_engine", text="Engine")
|
||||
|
||||
header, body = self.layout.panel("alembic_scene", default_closed=False)
|
||||
header.label(text="Scene")
|
||||
if body:
|
||||
column = body.column(align=True)
|
||||
column.prop(hprops, "alembic_frame_range_mode", text="Frame Range")
|
||||
|
||||
if hprops.alembic_frame_range_mode == 'FRAME_RANGE_TIMELINE':
|
||||
column.prop(context.scene, "frame_start")
|
||||
column.prop(context.scene, "frame_end")
|
||||
else:
|
||||
column.prop(hprops.alembic_frame_range_custom, "value_min")
|
||||
column.prop(hprops.alembic_frame_range_custom, "value_max")
|
||||
|
||||
column.separator()
|
||||
column.prop(hprops, "alembic_global_scale", text="Scale (TODO)")
|
||||
|
||||
header, body = self.layout.panel("alembic_include", default_closed=False)
|
||||
header.label(text="Include")
|
||||
if body:
|
||||
column = body.column(heading="Mesh", align=True)
|
||||
column.prop(hprops, "alembic_export_surface")
|
||||
column.prop(hprops, "alembic_export_surface_preview", text="Surface Preview (TODO)")
|
||||
column.prop(hprops, "alembic_export_fluid_particles", text="Fluid Particles (TODO)")
|
||||
column.prop(hprops, "alembic_export_foam", text="Foam (TODO)")
|
||||
column.prop(hprops, "alembic_export_bubble", text="Bubble (TODO)")
|
||||
column.prop(hprops, "alembic_export_spray", text="Spray (TODO)")
|
||||
column.prop(hprops, "alembic_export_dust", text="Dust (TODO)")
|
||||
|
||||
column = body.column(heading="Attributes", align=True)
|
||||
column.prop(hprops, "alembic_export_velocity", text="Velocity (TODO)")
|
||||
column.prop(hprops, "alembic_export_color", text="Color (TODO)")
|
||||
|
||||
header, body = self.layout.panel("alembic_command", default_closed=True)
|
||||
header.label(text="Command")
|
||||
if body:
|
||||
hprops = context.scene.flip_fluid_helper
|
||||
column = body.column(heading="Command", align=True)
|
||||
column.enabled = False
|
||||
column.operator("flip_fluid_operators.cmd_custom_alembic_export_to_clipboard", text="Copy Command to Clipboard (TODO)", icon='COPYDOWN')
|
||||
|
||||
|
||||
def draw(self, context):
|
||||
hprops = context.scene.flip_fluid_helper
|
||||
if hprops.alembic_export_engine == 'ALEMBIC_EXPORT_ENGINE_FLIP_FLUIDS':
|
||||
self.draw_alembic_export_engine_flip_fluids(context)
|
||||
elif hprops.alembic_export_engine == 'ALEMBIC_EXPORT_ENGINE_BLENDER':
|
||||
self.draw_alembic_export_engine_blender(context)
|
||||
|
||||
|
||||
def alembic_export_engine_flip_fluids(self):
|
||||
hprops = bpy.context.scene.flip_fluid_helper
|
||||
hprops.alembic_output_filepath = self.filepath
|
||||
bpy.ops.flip_fluid_operators.helper_cmd_custom_alembic_export('INVOKE_DEFAULT')
|
||||
|
||||
|
||||
def alembic_export_engine_blender(self):
|
||||
hprops = bpy.context.scene.flip_fluid_helper
|
||||
hprops.alembic_output_filepath = self.filepath
|
||||
bpy.ops.flip_fluid_operators.helper_command_line_alembic_export('INVOKE_DEFAULT')
|
||||
|
||||
|
||||
def check_cache_exists(self, context):
|
||||
dprops = context.scene.flip_fluid.get_domain_properties()
|
||||
cache_directory = dprops.cache.get_cache_abspath()
|
||||
bakefiles_directory = os.path.join(cache_directory, "bakefiles")
|
||||
|
||||
file_count = 0
|
||||
cache_exists = False
|
||||
if os.path.isdir(bakefiles_directory):
|
||||
cache_exists = True
|
||||
file_count = len(os.listdir(bakefiles_directory))
|
||||
|
||||
if not cache_exists or file_count == 0:
|
||||
return False
|
||||
return True
|
||||
|
||||
|
||||
def execute(self, context):
|
||||
if not self.check_cache_exists(context):
|
||||
dprops = context.scene.flip_fluid.get_domain_properties()
|
||||
cache_directory = dprops.cache.get_cache_abspath()
|
||||
self.report({'ERROR'}, "No data in simulation cache. Nothing to export in <" + cache_directory + ">")
|
||||
return {'CANCELLED'}
|
||||
|
||||
print("FLIP Fluids Alembic Export: <" + self.filepath + ">")
|
||||
|
||||
hprops = context.scene.flip_fluid_helper
|
||||
hprops.alembic_output_filepath = self.filepath
|
||||
bpy.ops.flip_fluid_operators.helper_command_line_alembic_export('INVOKE_DEFAULT')
|
||||
if hprops.alembic_export_engine == 'ALEMBIC_EXPORT_ENGINE_FLIP_FLUIDS':
|
||||
self.alembic_export_engine_flip_fluids()
|
||||
elif hprops.alembic_export_engine == 'ALEMBIC_EXPORT_ENGINE_BLENDER':
|
||||
self.alembic_export_engine_blender()
|
||||
else:
|
||||
self.report({'WARNING'}, "Unknown Alembic Export Engine: " + hprops.alembic_export_engine)
|
||||
return {'CANCELLED'}
|
||||
|
||||
return {'FINISHED'}
|
||||
|
||||
|
||||
@@ -429,8 +429,7 @@ class FlipFluidIncreaseDecreaseCacheDirectory(bpy.types.Operator):
|
||||
bl_description = ("Increase or decrease a numbered suffix on the cache directory." +
|
||||
" Note: this will not rename an existing cache directory")
|
||||
|
||||
increment_mode = StringProperty(default="INCREASE")
|
||||
exec(vcu.convert_attribute_to_28("increment_mode"))
|
||||
increment_mode: StringProperty(default="INCREASE")
|
||||
|
||||
|
||||
@classmethod
|
||||
@@ -487,8 +486,7 @@ class FlipFluidIncreaseDecreaseRenderDirectory(bpy.types.Operator):
|
||||
bl_description = ("Increase or decrease a numbered suffix on the render output directory." +
|
||||
" Note: this will not rename an existing render output directory")
|
||||
|
||||
increment_mode = StringProperty(default="INCREASE")
|
||||
exec(vcu.convert_attribute_to_28("increment_mode"))
|
||||
increment_mode: StringProperty(default="INCREASE")
|
||||
|
||||
|
||||
@classmethod
|
||||
@@ -565,8 +563,7 @@ class FlipFluidIncreaseDecreaseCacheRenderVersion(bpy.types.Operator):
|
||||
" directory and render output directory. Note: this will not rename an" +
|
||||
" existing cache our render output directory")
|
||||
|
||||
increment_mode = StringProperty(default="INCREASE")
|
||||
exec(vcu.convert_attribute_to_28("increment_mode"))
|
||||
increment_mode: StringProperty(default="INCREASE")
|
||||
|
||||
|
||||
@classmethod
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import bpy, os, pathlib, stat, subprocess, platform, random, shlex, shutil, traceback
|
||||
import bpy, os, pathlib, stat, subprocess, platform, random, shlex, shutil, traceback, ctypes, json
|
||||
from bpy.props import (
|
||||
BoolProperty,
|
||||
)
|
||||
@@ -470,6 +470,46 @@ def get_command_line_script_filepath(script_filename):
|
||||
return script_path
|
||||
|
||||
|
||||
def get_flip_fluids_alembic_exporter_filepath():
|
||||
executable_name = ""
|
||||
|
||||
system = platform.system()
|
||||
if system == "Windows":
|
||||
executable_name = "ff_alembic_exporter_windows.exe"
|
||||
elif system == "Darwin":
|
||||
executable_name = "ff_alembic_exporter_macos"
|
||||
elif system == "Linux":
|
||||
executable_name = "ff_alembic_exporter_linux"
|
||||
|
||||
executable_path = os.path.dirname(os.path.realpath(__file__))
|
||||
executable_path = os.path.dirname(executable_path)
|
||||
executable_path = os.path.join(executable_path, "ffengine", "lib", executable_name)
|
||||
if not os.path.isfile(executable_path):
|
||||
errmsg = "Unable to locate executable <" + executable_path + ">. Please contact the developers with this error."
|
||||
raise Exception(errmsg)
|
||||
return executable_path
|
||||
|
||||
|
||||
def get_flip_fluids_alembic_exporter_lib_filepath():
|
||||
executable_name = ""
|
||||
|
||||
system = platform.system()
|
||||
if system == "Windows":
|
||||
lib_name = "libffalembicengine.dll"
|
||||
elif system == "Darwin":
|
||||
lib_name = "libffalembicengine.dylib"
|
||||
elif system == "Linux":
|
||||
lib_name = "libffalembicengine.so"
|
||||
|
||||
lib_path = os.path.dirname(os.path.realpath(__file__))
|
||||
lib_path = os.path.dirname(lib_path)
|
||||
lib_path = os.path.join(lib_path, "ffengine", "lib", lib_name)
|
||||
if not os.path.isfile(lib_path):
|
||||
errmsg = "Unable to locate executable <" + lib_path + ">. Please contact the developers with this error."
|
||||
raise Exception(errmsg)
|
||||
return lib_path
|
||||
|
||||
|
||||
def save_blend_file_before_launch(override_preferences=False):
|
||||
prefs = vcu.get_addon_preferences()
|
||||
if prefs.cmd_save_blend_file_before_launch or override_preferences:
|
||||
@@ -539,11 +579,15 @@ def write_scripts_directory_readme():
|
||||
f.write(readme_text)
|
||||
|
||||
|
||||
def launch_command_universal_os(command_text, script_prefix_string, keep_window_open=True, skip_launch=False):
|
||||
def launch_command_universal_os(command_text, script_prefix_string, keep_window_open=True, skip_launch=False, chcp=None):
|
||||
system = platform.system()
|
||||
if system == "Windows":
|
||||
code_page = 65001
|
||||
if chcp:
|
||||
code_page = chcp
|
||||
|
||||
script_extension = ".bat"
|
||||
script_header = "echo off\nchcp 65001\n\n"
|
||||
script_header = "echo off\nchcp " + str(code_page) + "\n\n"
|
||||
script_footer = ""
|
||||
if keep_window_open:
|
||||
script_footer = "\ncmd /k\n"
|
||||
@@ -624,8 +668,7 @@ class FlipFluidHelperCommandLineBake(bpy.types.Operator):
|
||||
" The .blend file will need to be saved for before using" +
|
||||
" this operator for changes to take effect")
|
||||
|
||||
skip_launch = BoolProperty(False)
|
||||
exec(vcu.convert_attribute_to_28("skip_launch"))
|
||||
skip_launch: BoolProperty(False)
|
||||
|
||||
|
||||
@classmethod
|
||||
@@ -764,11 +807,9 @@ class FlipFluidHelperCommandLineRender(bpy.types.Operator):
|
||||
bl_description = ("Launch a new command line window and start rendering the animation." +
|
||||
" The .blend file will need to be saved before using this operator for changes to take effect")
|
||||
|
||||
use_turbo_tools = BoolProperty(False)
|
||||
exec(vcu.convert_attribute_to_28("use_turbo_tools"))
|
||||
use_turbo_tools: BoolProperty(False)
|
||||
|
||||
skip_launch = BoolProperty(False)
|
||||
exec(vcu.convert_attribute_to_28("skip_launch"))
|
||||
skip_launch: BoolProperty(False)
|
||||
|
||||
|
||||
@classmethod
|
||||
@@ -923,8 +964,7 @@ class FlipFluidHelperCommandLineRenderToClipboard(bpy.types.Operator):
|
||||
bl_description = ("Copy command for rendering to your system clipboard." +
|
||||
" The .blend file will need to be saved before running this command for changes to take effect")
|
||||
|
||||
use_turbo_tools = BoolProperty(False)
|
||||
exec(vcu.convert_attribute_to_28("use_turbo_tools"))
|
||||
use_turbo_tools: BoolProperty(False)
|
||||
|
||||
|
||||
@classmethod
|
||||
@@ -951,11 +991,9 @@ class FlipFluidHelperCommandLineRenderFrame(bpy.types.Operator):
|
||||
bl_description = ("Launch a new command line window and start rendering the current timeline frame." +
|
||||
" The .blend file will need to be saved before using this operator for changes to take effect")
|
||||
|
||||
use_turbo_tools = BoolProperty(False)
|
||||
exec(vcu.convert_attribute_to_28("use_turbo_tools"))
|
||||
use_turbo_tools: BoolProperty(False)
|
||||
|
||||
skip_launch = BoolProperty(False)
|
||||
exec(vcu.convert_attribute_to_28("skip_launch"))
|
||||
skip_launch: BoolProperty(False)
|
||||
|
||||
|
||||
@classmethod
|
||||
@@ -1022,14 +1060,13 @@ class FlipFluidHelperCommandLineRenderFrame(bpy.types.Operator):
|
||||
|
||||
|
||||
|
||||
class FlipFluidHelperCmdRenderFrameToClipboard(bpy.types.Operator):
|
||||
class FlipFluidHelperCommandLineRenderFrameToClipboard(bpy.types.Operator):
|
||||
bl_idname = "flip_fluid_operators.helper_cmd_render_frame_to_clipboard"
|
||||
bl_label = "Launch Frame Render"
|
||||
bl_description = ("Copy command for frame rendering to your system clipboard." +
|
||||
" The .blend file will need to be saved before running this command for changes to take effect")
|
||||
|
||||
use_turbo_tools = BoolProperty(False)
|
||||
exec(vcu.convert_attribute_to_28("use_turbo_tools"))
|
||||
use_turbo_tools: BoolProperty(False)
|
||||
|
||||
|
||||
@classmethod
|
||||
@@ -1055,8 +1092,7 @@ class FlipFluidHelperCommandLineAlembicExport(bpy.types.Operator):
|
||||
bl_description = ("Launch a new command line window and start exporting the simulation meshes to the Alembic (.abc) format." +
|
||||
" The .blend file will need to be saved before using this operator for changes to take effect")
|
||||
|
||||
skip_launch = BoolProperty(False)
|
||||
exec(vcu.convert_attribute_to_28("skip_launch"))
|
||||
skip_launch: BoolProperty(False)
|
||||
|
||||
|
||||
@classmethod
|
||||
@@ -1085,7 +1121,7 @@ class FlipFluidHelperCommandLineAlembicExport(bpy.types.Operator):
|
||||
return {'FINISHED'}
|
||||
|
||||
|
||||
class FlipFluidHelperCmdAlembicExportToClipboard(bpy.types.Operator):
|
||||
class FlipFluidHelperCommandLineAlembicExportToClipboard(bpy.types.Operator):
|
||||
bl_idname = "flip_fluid_operators.helper_cmd_alembic_export_to_clipboard"
|
||||
bl_label = "Launch Alembic Export"
|
||||
bl_description = ("Copy command for Alembic export to your system clipboard." +
|
||||
@@ -1109,6 +1145,75 @@ class FlipFluidHelperCmdAlembicExportToClipboard(bpy.types.Operator):
|
||||
return {'FINISHED'}
|
||||
|
||||
|
||||
class FlipFluidHelperCommandLineCustomAlembicExport(bpy.types.Operator):
|
||||
bl_idname = "flip_fluid_operators.helper_cmd_custom_alembic_export"
|
||||
bl_label = "Launch Alembic Export"
|
||||
bl_description = ("Launch a new command line window and start exporting the simulation meshes to the Alembic (.abc) format." +
|
||||
" The .blend file will need to be saved before using this operator for changes to take effect")
|
||||
|
||||
skip_launch: BoolProperty(False)
|
||||
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
return context.scene.flip_fluid.get_domain_object() is not None and bool(bpy.data.filepath)
|
||||
|
||||
|
||||
def get_export_frame_range(self):
|
||||
frame_start = bpy.context.scene.frame_start
|
||||
frame_end = bpy.context.scene.frame_end
|
||||
hprops = bpy.context.scene.flip_fluid_helper
|
||||
if hprops.alembic_frame_range_mode == 'FRAME_RANGE_CUSTOM':
|
||||
frame_start = hprops.alembic_frame_range_custom.value_min
|
||||
frame_end = hprops.alembic_frame_range_custom.value_max
|
||||
return frame_start, frame_end
|
||||
|
||||
|
||||
def execute(self, context):
|
||||
save_blend_file_before_launch(override_preferences=False)
|
||||
restore_blender_original_cwd()
|
||||
|
||||
script_path = get_command_line_script_filepath("flip_fluids_alembic_export.py")
|
||||
command_text = "\"" + bpy.app.binary_path + "\" --background \"" + bpy.data.filepath + "\" --python \"" + script_path + "\""
|
||||
|
||||
script_filepath = launch_command_universal_os(command_text, "FF_ALEMBIC_EXPORT_", keep_window_open=True, skip_launch=self.skip_launch)
|
||||
|
||||
if not self.skip_launch:
|
||||
info_msg = "Launched command line Alembic export window. If the Alembic export process did not begin,"
|
||||
info_msg += " this may be caused by a conflict with another addon or a security feature of your OS that restricts"
|
||||
info_msg += " automatic command execution. You may try running following script file manually:\n\n"
|
||||
info_msg += script_filepath + "\n\n"
|
||||
info_msg += "For more information on command line operators, visit our documentation:\n"
|
||||
info_msg += "https://github.com/rlguy/Blender-FLIP-Fluids/wiki/Helper-Menu-Settings#command-line-alembic-export"
|
||||
self.report({'INFO'}, info_msg)
|
||||
|
||||
return {'FINISHED'}
|
||||
|
||||
|
||||
class FlipFluidHelperCommandLineCustomAlembicExportToClipboard(bpy.types.Operator):
|
||||
bl_idname = "flip_fluid_operators.cmd_custom_alembic_export_to_clipboard"
|
||||
bl_label = "Launch Alembic Export"
|
||||
bl_description = ("Copy command for Alembic export to your system clipboard." +
|
||||
" The .blend file will need to be saved before running this command for changes to take effect")
|
||||
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
return context.scene.flip_fluid.get_domain_object() is not None and bool(bpy.data.filepath)
|
||||
|
||||
|
||||
def execute(self, context):
|
||||
bpy.ops.flip_fluid_operators.helper_cmd_custom_alembic_export('INVOKE_DEFAULT', skip_launch=True)
|
||||
|
||||
info_msg = "Copied the following Alembic export command to your clipboard:\n\n"
|
||||
info_msg += bpy.context.window_manager.clipboard + "\n\n"
|
||||
info_msg += "For more information on command line tools, visit our documentation:\n"
|
||||
info_msg += "https://github.com/rlguy/Blender-FLIP-Fluids/wiki/Helper-Menu-Settings#command-line-alembic-export"
|
||||
self.report({'INFO'}, info_msg)
|
||||
|
||||
return {'FINISHED'}
|
||||
|
||||
|
||||
def get_render_output_info():
|
||||
full_path = bpy.path.abspath(bpy.context.scene.render.filepath)
|
||||
directory_path = full_path
|
||||
@@ -1346,8 +1451,7 @@ class FlipFluidHelperCommandLineRenderPassAnimation(bpy.types.Operator):
|
||||
bl_label = "Launch Render Pass Animation"
|
||||
bl_description = ("Description: todo - launch render pass animation script")
|
||||
|
||||
skip_launch = BoolProperty(False)
|
||||
exec(vcu.convert_attribute_to_28("skip_launch"))
|
||||
skip_launch: BoolProperty(False)
|
||||
|
||||
|
||||
@classmethod
|
||||
@@ -1426,7 +1530,7 @@ class FlipFluidHelperCommandLineRenderPassAnimation(bpy.types.Operator):
|
||||
self.report({'ERROR'}, errmsg)
|
||||
return {'CANCELLED'}
|
||||
|
||||
if context.scene.render.engine == 'BLENDER_EEVEE':
|
||||
if context.scene.render.engine == 'BLENDER_EEVEE' or context.scene.render.engine == 'BLENDER_EEVEE_NEXT':
|
||||
self.report({'ERROR'}, "The EEVEE render engine is not supported for this feature. Set the render engine to Cycles, save, and try again.")
|
||||
return {'CANCELLED'}
|
||||
if context.scene.render.engine == 'BLENDER_WORKBENCH':
|
||||
@@ -1510,8 +1614,7 @@ class FlipFluidHelperCommandLineRenderPassFrame(bpy.types.Operator):
|
||||
bl_label = "Launch Render Pass Frame"
|
||||
bl_description = ("Description: todo - launch render pass animation script")
|
||||
|
||||
skip_launch = BoolProperty(False)
|
||||
exec(vcu.convert_attribute_to_28("skip_launch"))
|
||||
skip_launch: BoolProperty(False)
|
||||
|
||||
|
||||
@classmethod
|
||||
@@ -1566,7 +1669,7 @@ class FlipFluidHelperCommandLineRenderPassFrame(bpy.types.Operator):
|
||||
self.report({'ERROR'}, errmsg)
|
||||
return {'CANCELLED'}
|
||||
|
||||
if context.scene.render.engine == 'BLENDER_EEVEE':
|
||||
if context.scene.render.engine == 'BLENDER_EEVEE' or context.scene.render.engine == 'BLENDER_EEVEE_NEXT':
|
||||
self.report({'ERROR'}, "The EEVEE render engine is not supported for this feature. Set the render engine to Cycles, save, and try again.")
|
||||
return {'CANCELLED'}
|
||||
if context.scene.render.engine == 'BLENDER_WORKBENCH':
|
||||
@@ -1679,9 +1782,11 @@ def register():
|
||||
bpy.utils.register_class(FlipFluidHelperCommandLineRender)
|
||||
bpy.utils.register_class(FlipFluidHelperCommandLineRenderToClipboard)
|
||||
bpy.utils.register_class(FlipFluidHelperCommandLineRenderFrame)
|
||||
bpy.utils.register_class(FlipFluidHelperCmdRenderFrameToClipboard)
|
||||
bpy.utils.register_class(FlipFluidHelperCommandLineRenderFrameToClipboard)
|
||||
bpy.utils.register_class(FlipFluidHelperCommandLineAlembicExport)
|
||||
bpy.utils.register_class(FlipFluidHelperCmdAlembicExportToClipboard)
|
||||
bpy.utils.register_class(FlipFluidHelperCommandLineAlembicExportToClipboard)
|
||||
bpy.utils.register_class(FlipFluidHelperCommandLineCustomAlembicExport)
|
||||
bpy.utils.register_class(FlipFluidHelperCommandLineCustomAlembicExportToClipboard)
|
||||
bpy.utils.register_class(FlipFluidHelperOpenRenderOutputFolder)
|
||||
bpy.utils.register_class(FlipFluidHelperOpenCacheOutputFolder)
|
||||
bpy.utils.register_class(FlipFluidHelperOpenAlembicOutputFolder)
|
||||
@@ -1717,9 +1822,11 @@ def unregister():
|
||||
bpy.utils.unregister_class(FlipFluidHelperCommandLineRender)
|
||||
bpy.utils.unregister_class(FlipFluidHelperCommandLineRenderToClipboard)
|
||||
bpy.utils.unregister_class(FlipFluidHelperCommandLineRenderFrame)
|
||||
bpy.utils.unregister_class(FlipFluidHelperCmdRenderFrameToClipboard)
|
||||
bpy.utils.unregister_class(FlipFluidHelperCommandLineRenderFrameToClipboard)
|
||||
bpy.utils.unregister_class(FlipFluidHelperCommandLineAlembicExport)
|
||||
bpy.utils.unregister_class(FlipFluidHelperCmdAlembicExportToClipboard)
|
||||
bpy.utils.unregister_class(FlipFluidHelperCommandLineAlembicExportToClipboard)
|
||||
bpy.utils.unregister_class(FlipFluidHelperCommandLineCustomAlembicExport)
|
||||
bpy.utils.unregister_class(FlipFluidHelperCommandLineCustomAlembicExportToClipboard)
|
||||
bpy.utils.unregister_class(FlipFluidHelperOpenRenderOutputFolder)
|
||||
bpy.utils.unregister_class(FlipFluidHelperOpenCacheOutputFolder)
|
||||
bpy.utils.unregister_class(FlipFluidHelperOpenAlembicOutputFolder)
|
||||
@@ -1738,5 +1845,9 @@ def unregister():
|
||||
|
||||
# Remove shortcuts
|
||||
for km, kmi in ADDON_KEYMAPS:
|
||||
km.keymap_items.remove(kmi)
|
||||
try:
|
||||
# Keymap may be unavailable depending on context
|
||||
km.keymap_items.remove(kmi)
|
||||
except:
|
||||
pass
|
||||
ADDON_KEYMAPS.clear()
|
||||
@@ -14,7 +14,8 @@
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import bpy, blf, math, colorsys
|
||||
import bpy, blf, math, colorsys, gpu
|
||||
from gpu_extras.batch import batch_for_shader
|
||||
|
||||
from bpy.props import (
|
||||
IntProperty
|
||||
@@ -25,10 +26,6 @@ from ..utils import ui_utils
|
||||
from ..utils import version_compatibility_utils as vcu
|
||||
from .. import render
|
||||
|
||||
if vcu.is_blender_28():
|
||||
import gpu
|
||||
from gpu_extras.batch import batch_for_shader
|
||||
|
||||
|
||||
particle_vertices = []
|
||||
particle_vertex_colors = []
|
||||
@@ -88,51 +85,41 @@ def update_debug_force_field_geometry(context):
|
||||
color_tuple = (color[0], color[1], color[2], 1.0)
|
||||
particle_vertex_colors.append(color_tuple)
|
||||
|
||||
if vcu.is_blender_28():
|
||||
global particle_shader
|
||||
global particle_batch_draw
|
||||
global particle_shader
|
||||
global particle_batch_draw
|
||||
|
||||
vertex_shader = """
|
||||
uniform mat4 ModelViewProjectionMatrix;
|
||||
vertex_shader = """
|
||||
uniform mat4 ModelViewProjectionMatrix;
|
||||
|
||||
in vec3 pos;
|
||||
in vec4 color;
|
||||
in vec3 pos;
|
||||
in vec4 color;
|
||||
|
||||
out vec4 finalColor;
|
||||
out vec4 finalColor;
|
||||
|
||||
void main()
|
||||
{
|
||||
gl_Position = ModelViewProjectionMatrix * vec4(pos, 1.0);
|
||||
finalColor = color;
|
||||
}
|
||||
"""
|
||||
void main()
|
||||
{
|
||||
gl_Position = ModelViewProjectionMatrix * vec4(pos, 1.0);
|
||||
finalColor = color;
|
||||
}
|
||||
"""
|
||||
|
||||
fragment_shader = """
|
||||
in vec4 finalColor;
|
||||
out vec4 fragColor;
|
||||
fragment_shader = """
|
||||
in vec4 finalColor;
|
||||
out vec4 fragColor;
|
||||
|
||||
void main()
|
||||
{
|
||||
fragColor = finalColor;
|
||||
}
|
||||
"""
|
||||
void main()
|
||||
{
|
||||
fragColor = finalColor;
|
||||
}
|
||||
"""
|
||||
|
||||
if vcu.is_blender_35():
|
||||
# Needed for support on MacOS Apple Silicon systems in Blender 3.5 or later
|
||||
# Could possibly be a Blender regression bug why the below method no longer
|
||||
# works in Blender 3.5 or later for MacOS. Should file a report.
|
||||
shader_name = '3D_SMOOTH_COLOR'
|
||||
if vcu.is_blender_40():
|
||||
shader_name = 'SMOOTH_COLOR'
|
||||
|
||||
particle_shader = gpu.shader.from_builtin(shader_name)
|
||||
else:
|
||||
particle_shader = gpu.types.GPUShader(vertex_shader, fragment_shader)
|
||||
shader_name = 'SMOOTH_COLOR'
|
||||
particle_shader = gpu.shader.from_builtin(shader_name)
|
||||
|
||||
particle_batch_draw = batch_for_shader(
|
||||
particle_shader, 'POINTS',
|
||||
{"pos": particle_vertices, "color": particle_vertex_colors},
|
||||
)
|
||||
particle_batch_draw = batch_for_shader(
|
||||
particle_shader, 'POINTS',
|
||||
{"pos": particle_vertices, "color": particle_vertex_colors},
|
||||
)
|
||||
|
||||
|
||||
def _lerp_rgb(minc, maxc, factor, mode='RGB'):
|
||||
@@ -185,50 +172,13 @@ class FlipFluidDrawForceField(bpy.types.Operator):
|
||||
if vcu.get_object_hide_viewport(domain):
|
||||
return
|
||||
|
||||
if not vcu.is_blender_28():
|
||||
dlayers = [i for i,v in enumerate(domain.layers) if v]
|
||||
slayers = [i for i,v in enumerate(context.scene.layers) if v]
|
||||
if not (set(dlayers) & set(slayers)):
|
||||
return
|
||||
|
||||
if vcu.is_blender_28():
|
||||
global particle_shader
|
||||
global particle_batch_draw
|
||||
if vcu.is_blender_35():
|
||||
# Warnings in Blender 3.5 when using bgl module, which is to
|
||||
# be deprecated in Blender 3.7. Use gpu module instead.
|
||||
gpu.state.point_size_set(dprops.debug.force_field_line_size)
|
||||
else:
|
||||
# only attempt to import bgl when necessary (older versions of Blender). In Blender >= 3.5,
|
||||
# importing bgl generates a warning, and possibly an error in Blender >= 4.0.
|
||||
import bgl
|
||||
bgl.glPointSize(dprops.debug.force_field_line_size)
|
||||
|
||||
if vcu.is_blender_35():
|
||||
# Can be drawn with depth in Blender 3.5 or later
|
||||
gpu.state.depth_test_set('LESS_EQUAL')
|
||||
gpu.state.depth_mask_set(True)
|
||||
particle_batch_draw.draw(particle_shader)
|
||||
if vcu.is_blender_35():
|
||||
gpu.state.depth_mask_set(False)
|
||||
|
||||
else:
|
||||
# only attempt to import bgl when necessary (older versions of Blender). In Blender >= 3.5,
|
||||
# importing bgl generates a warning, and possibly an error in Blender >= 4.0.
|
||||
import bgl
|
||||
bgl.glPointSize(dprops.debug.force_field_line_size)
|
||||
bgl.glBegin(bgl.GL_POINTS)
|
||||
|
||||
current_color = None
|
||||
for i in range(len(particle_vertices)):
|
||||
if current_color != particle_vertex_colors[i]:
|
||||
current_color = particle_vertex_colors[i]
|
||||
bgl.glColor4f(current_color[0], current_color[1], current_color[2], 1.0)
|
||||
bgl.glVertex3f(*(particle_vertices[i]))
|
||||
|
||||
bgl.glEnd()
|
||||
bgl.glPointSize(1)
|
||||
bgl.glColor4f(0.0, 0.0, 0.0, 1.0)
|
||||
global particle_shader
|
||||
global particle_batch_draw
|
||||
gpu.state.point_size_set(dprops.debug.force_field_line_size)
|
||||
gpu.state.depth_test_set('LESS_EQUAL')
|
||||
gpu.state.depth_mask_set(True)
|
||||
particle_batch_draw.draw(particle_shader)
|
||||
gpu.state.depth_mask_set(False)
|
||||
|
||||
|
||||
def modal(self, context, event):
|
||||
|
||||
@@ -25,9 +25,8 @@ from ..utils import ui_utils
|
||||
from ..utils import version_compatibility_utils as vcu
|
||||
from .. import render
|
||||
|
||||
if vcu.is_blender_28():
|
||||
import gpu
|
||||
from gpu_extras.batch import batch_for_shader
|
||||
import gpu
|
||||
from gpu_extras.batch import batch_for_shader
|
||||
|
||||
|
||||
x_coords = []
|
||||
@@ -195,33 +194,11 @@ class FlipFluidDrawDebugGrid(bpy.types.Operator):
|
||||
if not dprops.debug.display_simulation_grid:
|
||||
return
|
||||
|
||||
if not vcu.is_blender_28():
|
||||
dlayers = [i for i,v in enumerate(domain.layers) if v]
|
||||
slayers = [i for i,v in enumerate(context.scene.layers) if v]
|
||||
if not (set(dlayers) & set(slayers)):
|
||||
return
|
||||
|
||||
if dprops.debug.grid_display_mode == 'GRID_DISPLAY_SIMULATION':
|
||||
isize, jsize, ksize, viewport_dx = dprops.simulation.get_viewport_grid_dimensions()
|
||||
_, _, _, simulation_dx = dprops.simulation.get_simulation_grid_dimensions()
|
||||
elif dprops.debug.grid_display_mode == 'GRID_DISPLAY_PREVIEW':
|
||||
presolution = dprops.simulation.preview_resolution
|
||||
|
||||
"""
|
||||
|
||||
isize, jsize, ksize, viewport_dx = dprops.simulation.get_viewport_grid_dimensions(resolution=presolution)
|
||||
_, _, _, simulation_dx = dprops.simulation.get_simulation_grid_dimensions(resolution=presolution)
|
||||
else:
|
||||
isize, jsize, ksize, viewport_dx = dprops.simulation.get_viewport_grid_dimensions()
|
||||
_, _, _, simulation_dx = dprops.simulation.get_simulation_grid_dimensions()
|
||||
|
||||
if dprops.debug.grid_display_mode == 'GRID_DISPLAY_MESH':
|
||||
isize *= (dprops.surface.subdivisions + 1)
|
||||
jsize *= (dprops.surface.subdivisions + 1)
|
||||
ksize *= (dprops.surface.subdivisions + 1)
|
||||
viewport_dx /= (dprops.surface.subdivisions + 1)
|
||||
"""
|
||||
|
||||
isize, jsize, ksize, viewport_dx = dprops.simulation.get_viewport_grid_dimensions(resolution=presolution)
|
||||
_, _, _, simulation_dx = dprops.simulation.get_simulation_grid_dimensions(resolution=presolution)
|
||||
elif dprops.debug.grid_display_mode == 'GRID_DISPLAY_MESH':
|
||||
@@ -249,12 +226,8 @@ class FlipFluidDrawDebugGrid(bpy.types.Operator):
|
||||
simulation_dx *= reduction
|
||||
|
||||
width = context.region.width
|
||||
if vcu.is_blender_28():
|
||||
height = 200
|
||||
xstart = context.region.width - 400
|
||||
else:
|
||||
height = context.region.height
|
||||
xstart = 50
|
||||
height = 200
|
||||
xstart = context.region.width - 400
|
||||
|
||||
font_id = 0
|
||||
try:
|
||||
@@ -360,12 +333,6 @@ class FlipFluidDrawDebugGrid(bpy.types.Operator):
|
||||
if vcu.get_object_hide_viewport(domain):
|
||||
return
|
||||
|
||||
if not vcu.is_blender_28():
|
||||
dlayers = [i for i,v in enumerate(domain.layers) if v]
|
||||
slayers = [i for i,v in enumerate(context.scene.layers) if v]
|
||||
if not (set(dlayers) & set(slayers)):
|
||||
return
|
||||
|
||||
x_color = dprops.debug.x_grid_color
|
||||
y_color = dprops.debug.y_grid_color
|
||||
z_color = dprops.debug.z_grid_color
|
||||
@@ -373,86 +340,49 @@ class FlipFluidDrawDebugGrid(bpy.types.Operator):
|
||||
|
||||
# Draw
|
||||
display_grid = dprops.debug.display_simulation_grid
|
||||
if vcu.is_blender_28():
|
||||
line_draw_mode = '3D_UNIFORM_COLOR'
|
||||
if vcu.is_blender_36():
|
||||
# 3D/2D prefix deprecated in recent versions of Blender
|
||||
line_draw_mode = 'UNIFORM_COLOR'
|
||||
if display_grid and dprops.debug.enabled_debug_grids[2]:
|
||||
shader = gpu.shader.from_builtin(line_draw_mode)
|
||||
batch = batch_for_shader(shader, 'LINES', {"pos": z_coords})
|
||||
shader.bind()
|
||||
shader.uniform_float("color", (z_color[0], z_color[1], z_color[2], 1.0))
|
||||
line_draw_mode = 'UNIFORM_COLOR'
|
||||
|
||||
if vcu.is_blender_35():
|
||||
# Can be drawn with depth in Blender 3.5 or later
|
||||
gpu.state.depth_test_set('LESS_EQUAL')
|
||||
gpu.state.depth_mask_set(True)
|
||||
batch.draw(shader)
|
||||
if vcu.is_blender_35():
|
||||
gpu.state.depth_mask_set(False)
|
||||
if display_grid and dprops.debug.enabled_debug_grids[1]:
|
||||
shader = gpu.shader.from_builtin(line_draw_mode)
|
||||
batch = batch_for_shader(shader, 'LINES', {"pos": y_coords})
|
||||
shader.bind()
|
||||
shader.uniform_float("color", (y_color[0], y_color[1], y_color[2], 1.0))
|
||||
if vcu.is_blender_35():
|
||||
# Can be drawn with depth in Blender 3.5 or later
|
||||
gpu.state.depth_test_set('LESS_EQUAL')
|
||||
gpu.state.depth_mask_set(True)
|
||||
batch.draw(shader)
|
||||
if vcu.is_blender_35():
|
||||
gpu.state.depth_mask_set(False)
|
||||
if display_grid and dprops.debug.enabled_debug_grids[0]:
|
||||
shader = gpu.shader.from_builtin(line_draw_mode)
|
||||
batch = batch_for_shader(shader, 'LINES', {"pos": x_coords})
|
||||
shader.bind()
|
||||
shader.uniform_float("color", (x_color[0], x_color[1], x_color[2], 1.0))
|
||||
if vcu.is_blender_35():
|
||||
# Can be drawn with depth in Blender 3.5 or later
|
||||
gpu.state.depth_test_set('LESS_EQUAL')
|
||||
gpu.state.depth_mask_set(True)
|
||||
batch.draw(shader)
|
||||
if vcu.is_blender_35():
|
||||
gpu.state.depth_mask_set(False)
|
||||
if dprops.debug.display_domain_bounds:
|
||||
shader = gpu.shader.from_builtin(line_draw_mode)
|
||||
batch = batch_for_shader(shader, 'LINES', {"pos": bounds_coords})
|
||||
shader.bind()
|
||||
shader.uniform_float("color", (bounds_color[0], bounds_color[1], bounds_color[2], 1.0))
|
||||
if vcu.is_blender_35():
|
||||
# Can be drawn with depth in Blender 3.5 or later
|
||||
gpu.state.depth_test_set('LESS_EQUAL')
|
||||
gpu.state.depth_mask_set(True)
|
||||
batch.draw(shader)
|
||||
if vcu.is_blender_35():
|
||||
gpu.state.depth_mask_set(False)
|
||||
else:
|
||||
import bgl
|
||||
bgl.glLineWidth(1)
|
||||
bgl.glBegin(bgl.GL_LINES)
|
||||
if display_grid and dprops.debug.enabled_debug_grids[2]:
|
||||
shader = gpu.shader.from_builtin(line_draw_mode)
|
||||
batch = batch_for_shader(shader, 'LINES', {"pos": z_coords})
|
||||
shader.bind()
|
||||
shader.uniform_float("color", (z_color[0], z_color[1], z_color[2], 1.0))
|
||||
|
||||
if display_grid and dprops.debug.enabled_debug_grids[2]:
|
||||
bgl.glColor4f(*z_color, 1.0)
|
||||
for c in z_coords:
|
||||
bgl.glVertex3f(*c)
|
||||
if display_grid and dprops.debug.enabled_debug_grids[1]:
|
||||
bgl.glColor4f(*y_color, 1.0)
|
||||
for c in y_coords:
|
||||
bgl.glVertex3f(*c)
|
||||
if display_grid and dprops.debug.enabled_debug_grids[0]:
|
||||
bgl.glColor4f(*x_color, 1.0)
|
||||
for c in x_coords:
|
||||
bgl.glVertex3f(*c)
|
||||
if dprops.debug.display_domain_bounds:
|
||||
bgl.glColor4f(*(bounds_color), 1.0)
|
||||
for c in bounds_coords:
|
||||
bgl.glVertex3f(*c)
|
||||
gpu.state.depth_test_set('LESS_EQUAL')
|
||||
gpu.state.depth_mask_set(True)
|
||||
batch.draw(shader)
|
||||
gpu.state.depth_mask_set(False)
|
||||
|
||||
bgl.glEnd()
|
||||
bgl.glLineWidth(1)
|
||||
bgl.glEnable(bgl.GL_DEPTH_TEST)
|
||||
bgl.glColor4f(0.0, 0.0, 0.0, 1.0)
|
||||
if display_grid and dprops.debug.enabled_debug_grids[1]:
|
||||
shader = gpu.shader.from_builtin(line_draw_mode)
|
||||
batch = batch_for_shader(shader, 'LINES', {"pos": y_coords})
|
||||
shader.bind()
|
||||
shader.uniform_float("color", (y_color[0], y_color[1], y_color[2], 1.0))
|
||||
|
||||
gpu.state.depth_test_set('LESS_EQUAL')
|
||||
gpu.state.depth_mask_set(True)
|
||||
batch.draw(shader)
|
||||
gpu.state.depth_mask_set(False)
|
||||
|
||||
if display_grid and dprops.debug.enabled_debug_grids[0]:
|
||||
shader = gpu.shader.from_builtin(line_draw_mode)
|
||||
batch = batch_for_shader(shader, 'LINES', {"pos": x_coords})
|
||||
shader.bind()
|
||||
shader.uniform_float("color", (x_color[0], x_color[1], x_color[2], 1.0))
|
||||
gpu.state.depth_test_set('LESS_EQUAL')
|
||||
gpu.state.depth_mask_set(True)
|
||||
batch.draw(shader)
|
||||
gpu.state.depth_mask_set(False)
|
||||
|
||||
if dprops.debug.display_domain_bounds:
|
||||
shader = gpu.shader.from_builtin(line_draw_mode)
|
||||
batch = batch_for_shader(shader, 'LINES', {"pos": bounds_coords})
|
||||
shader.bind()
|
||||
shader.uniform_float("color", (bounds_color[0], bounds_color[1], bounds_color[2], 1.0))
|
||||
gpu.state.depth_test_set('LESS_EQUAL')
|
||||
gpu.state.depth_mask_set(True)
|
||||
batch.draw(shader)
|
||||
gpu.state.depth_mask_set(False)
|
||||
|
||||
|
||||
def modal(self, context, event):
|
||||
|
||||
@@ -25,9 +25,8 @@ from ..utils import ui_utils
|
||||
from ..utils import version_compatibility_utils as vcu
|
||||
from .. import render
|
||||
|
||||
if vcu.is_blender_28():
|
||||
import gpu
|
||||
from gpu_extras.batch import batch_for_shader
|
||||
import gpu
|
||||
from gpu_extras.batch import batch_for_shader
|
||||
|
||||
|
||||
particle_vertices = []
|
||||
@@ -87,51 +86,16 @@ def update_debug_particle_geometry(context):
|
||||
particle_vertices.append(particles[pidx])
|
||||
particle_vertex_colors.append(color_tuple)
|
||||
|
||||
if vcu.is_blender_28():
|
||||
global particle_shader
|
||||
global particle_batch_draw
|
||||
global particle_shader
|
||||
global particle_batch_draw
|
||||
|
||||
vertex_shader = """
|
||||
uniform mat4 ModelViewProjectionMatrix;
|
||||
shader_name = 'SMOOTH_COLOR'
|
||||
particle_shader = gpu.shader.from_builtin(shader_name)
|
||||
|
||||
in vec3 pos;
|
||||
in vec4 color;
|
||||
|
||||
out vec4 finalColor;
|
||||
|
||||
void main()
|
||||
{
|
||||
gl_Position = ModelViewProjectionMatrix * vec4(pos, 1.0);
|
||||
finalColor = color;
|
||||
}
|
||||
"""
|
||||
|
||||
fragment_shader = """
|
||||
in vec4 finalColor;
|
||||
out vec4 fragColor;
|
||||
|
||||
void main()
|
||||
{
|
||||
fragColor = finalColor;
|
||||
}
|
||||
"""
|
||||
|
||||
if vcu.is_blender_35():
|
||||
# Needed for support on MacOS Apple Silicon systems in Blender 3.5 or later
|
||||
# Could possibly be a Blender regression bug why the below method no longer
|
||||
# works in Blender 3.5 or later for MacOS. Should file a report.
|
||||
shader_name = '3D_SMOOTH_COLOR'
|
||||
if vcu.is_blender_40():
|
||||
shader_name = 'SMOOTH_COLOR'
|
||||
|
||||
particle_shader = gpu.shader.from_builtin(shader_name)
|
||||
else:
|
||||
particle_shader = gpu.types.GPUShader(vertex_shader, fragment_shader)
|
||||
|
||||
particle_batch_draw = batch_for_shader(
|
||||
particle_shader, 'POINTS',
|
||||
{"pos": particle_vertices, "color": particle_vertex_colors},
|
||||
)
|
||||
particle_batch_draw = batch_for_shader(
|
||||
particle_shader, 'POINTS',
|
||||
{"pos": particle_vertices, "color": particle_vertex_colors},
|
||||
)
|
||||
|
||||
|
||||
def _get_color_ranges(pdata, num_colors):
|
||||
@@ -224,50 +188,13 @@ class FlipFluidDrawGLParticles(bpy.types.Operator):
|
||||
if vcu.get_object_hide_viewport(domain):
|
||||
return
|
||||
|
||||
if not vcu.is_blender_28():
|
||||
dlayers = [i for i,v in enumerate(domain.layers) if v]
|
||||
slayers = [i for i,v in enumerate(context.scene.layers) if v]
|
||||
if not (set(dlayers) & set(slayers)):
|
||||
return
|
||||
|
||||
if vcu.is_blender_28():
|
||||
global particle_shader
|
||||
global particle_batch_draw
|
||||
if vcu.is_blender_35():
|
||||
# Warnings in Blender 3.5 when using bgl module, which is to
|
||||
# be deprecated in Blender 3.7. Use gpu module instead.
|
||||
gpu.state.point_size_set(dprops.debug.particle_size)
|
||||
else:
|
||||
# only attempt to import bgl when necessary (older versions of Blender). In Blender >= 3.5,
|
||||
# importing bgl generates a warning, and possibly an error in Blender >= 4.0.
|
||||
import bgl
|
||||
bgl.glPointSize(dprops.debug.particle_size)
|
||||
|
||||
if vcu.is_blender_35():
|
||||
# Can be drawn with depth in Blender 3.5 or later
|
||||
gpu.state.depth_test_set('LESS_EQUAL')
|
||||
gpu.state.depth_mask_set(True)
|
||||
particle_batch_draw.draw(particle_shader)
|
||||
if vcu.is_blender_35():
|
||||
gpu.state.depth_mask_set(False)
|
||||
|
||||
else:
|
||||
# only attempt to import bgl when necessary (older versions of Blender). In Blender >= 3.5,
|
||||
# importing bgl generates a warning, and possibly an error in Blender >= 4.0.
|
||||
import bgl
|
||||
bgl.glPointSize(dprops.debug.particle_size)
|
||||
bgl.glBegin(bgl.GL_POINTS)
|
||||
|
||||
current_color = None
|
||||
for i in range(len(particle_vertices)):
|
||||
if current_color != particle_vertex_colors[i]:
|
||||
current_color = particle_vertex_colors[i]
|
||||
bgl.glColor4f(current_color[0], current_color[1], current_color[2], 1.0)
|
||||
bgl.glVertex3f(*(particle_vertices[i]))
|
||||
|
||||
bgl.glEnd()
|
||||
bgl.glPointSize(1)
|
||||
bgl.glColor4f(0.0, 0.0, 0.0, 1.0)
|
||||
global particle_shader
|
||||
global particle_batch_draw
|
||||
gpu.state.point_size_set(dprops.debug.particle_size)
|
||||
gpu.state.depth_test_set('LESS_EQUAL')
|
||||
gpu.state.depth_mask_set(True)
|
||||
particle_batch_draw.draw(particle_shader)
|
||||
gpu.state.depth_mask_set(False)
|
||||
|
||||
|
||||
def modal(self, context, event):
|
||||
|
||||
@@ -28,14 +28,9 @@ class FlipFluidDisplayError(bpy.types.Operator):
|
||||
bl_label = ""
|
||||
bl_description = ""
|
||||
|
||||
error_message = StringProperty()
|
||||
exec(vcu.convert_attribute_to_28("error_message"))
|
||||
|
||||
error_description = StringProperty()
|
||||
exec(vcu.convert_attribute_to_28("error_description"))
|
||||
|
||||
popup_width = IntProperty(default=400)
|
||||
exec(vcu.convert_attribute_to_28("popup_width"))
|
||||
error_message: StringProperty()
|
||||
error_description: StringProperty()
|
||||
popup_width: IntProperty(default=400)
|
||||
|
||||
|
||||
def draw(self, context):
|
||||
|
||||
@@ -55,14 +55,11 @@ class FlipFluidHelperRemesh(bpy.types.Operator):
|
||||
" of the input geometry. Use the link next to this operator to view documentation and a video guide" +
|
||||
" for using this feature")
|
||||
|
||||
skip_hide_render_objects = BoolProperty(True)
|
||||
exec(vcu.convert_attribute_to_28("skip_hide_render_objects"))
|
||||
skip_hide_render_objects: BoolProperty(True)
|
||||
|
||||
apply_object_modifiers = BoolProperty(True)
|
||||
exec(vcu.convert_attribute_to_28("apply_object_modifiers"))
|
||||
apply_object_modifiers: BoolProperty(True)
|
||||
|
||||
convert_objects_to_mesh = BoolProperty(True)
|
||||
exec(vcu.convert_attribute_to_28("convert_objects_to_mesh"))
|
||||
convert_objects_to_mesh: BoolProperty(True)
|
||||
|
||||
|
||||
@classmethod
|
||||
@@ -446,8 +443,7 @@ class FlipFluidHelperSelectObjects(bpy.types.Operator):
|
||||
bl_label = "Select Objects"
|
||||
bl_description = "Select all FLIP Fluid objects of this type"
|
||||
|
||||
object_type = StringProperty("TYPE_NONE")
|
||||
exec(vcu.convert_attribute_to_28("object_type"))
|
||||
object_type: StringProperty("TYPE_NONE")
|
||||
|
||||
|
||||
@classmethod
|
||||
@@ -802,8 +798,7 @@ class FlipFluidHelperAddObjects(bpy.types.Operator):
|
||||
bl_label = "Add Objects"
|
||||
bl_description = "Add selected objects as FLIP Fluid objects"
|
||||
|
||||
object_type = StringProperty("TYPE_NONE")
|
||||
exec(vcu.convert_attribute_to_28("object_type"))
|
||||
object_type: StringProperty("TYPE_NONE")
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
@@ -1014,8 +1009,7 @@ class FlipFluidHelperDeleteWhitewaterObjects(bpy.types.Operator):
|
||||
" Warning: deleting these objects will also remove any modifications such as added" +
|
||||
" modifiers and materials")
|
||||
|
||||
whitewater_type = StringProperty("TYPE_ALL")
|
||||
exec(vcu.convert_attribute_to_28("whitewater_type"))
|
||||
whitewater_type: StringProperty("TYPE_ALL")
|
||||
|
||||
|
||||
@classmethod
|
||||
@@ -1053,7 +1047,7 @@ class FlipFluidHelperOrganizeOutliner(bpy.types.Operator):
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
return vcu.is_blender_28()
|
||||
return True
|
||||
|
||||
|
||||
def initialize_child_collection(self, context, child_name, parent_collection):
|
||||
@@ -1159,7 +1153,7 @@ class FlipFluidHelperSeparateFLIPMeshes(bpy.types.Operator):
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
dprops = context.scene.flip_fluid.get_domain_properties()
|
||||
return vcu.is_blender_28() and dprops is not None
|
||||
return dprops is not None
|
||||
|
||||
|
||||
def initialize_child_collection(self, context, child_name, parent_collection):
|
||||
@@ -1237,7 +1231,7 @@ class FlipFluidHelperUndoOrganizeOutliner(bpy.types.Operator):
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
return vcu.is_blender_28()
|
||||
return True
|
||||
|
||||
|
||||
def unlink_collection(self, context, collection_name):
|
||||
@@ -1287,7 +1281,7 @@ class FlipFluidHelperUndoSeparateFLIPMeshes(bpy.types.Operator):
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
dprops = context.scene.flip_fluid.get_domain_properties()
|
||||
return vcu.is_blender_28() and dprops is not None
|
||||
return dprops is not None
|
||||
|
||||
|
||||
def unlink_collection(self, context, collection_name):
|
||||
@@ -1331,8 +1325,7 @@ class FlipFluidHelperSetObjectViewportDisplay(bpy.types.Operator):
|
||||
bl_label = "Object Viewport Display"
|
||||
bl_description = "Set how selected objects are displayed/rendered in the viewport"
|
||||
|
||||
display_mode = StringProperty("TYPE_NONE")
|
||||
exec(vcu.convert_attribute_to_28("display_mode"))
|
||||
display_mode: StringProperty("TYPE_NONE")
|
||||
|
||||
|
||||
@classmethod
|
||||
@@ -1365,8 +1358,7 @@ class FlipFluidHelperSetObjectRenderDisplay(bpy.types.Operator):
|
||||
bl_label = "Object Render Display"
|
||||
bl_description = "Set selected objects visiblility in the render"
|
||||
|
||||
hide_render = BoolProperty(False)
|
||||
exec(vcu.convert_attribute_to_28("hide_render"))
|
||||
hide_render: BoolProperty(False)
|
||||
|
||||
|
||||
@classmethod
|
||||
@@ -1568,7 +1560,7 @@ class FlipFluidEnableColorAttributeTooltip(bpy.types.Operator):
|
||||
class FlipFluidEnableViscosityAttribute(bpy.types.Operator):
|
||||
bl_idname = "flip_fluid_operators.enable_viscosity_attribute"
|
||||
bl_label = "Enable Viscosity Attribute"
|
||||
bl_description = "Enable viscosity solver and variable viscosity attribute in the Domain FLIP Fluid World panel"
|
||||
bl_description = "Enable viscosity solver and variable viscosity attribute in the Domain World panel"
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
@@ -1606,10 +1598,50 @@ class FlipFluidEnableViscosityAttributeTooltip(bpy.types.Operator):
|
||||
return {'FINISHED'}
|
||||
|
||||
|
||||
class FlipFluidEnableDensityAttribute(bpy.types.Operator):
|
||||
bl_idname = "flip_fluid_operators.enable_density_attribute"
|
||||
bl_label = "Enable Density Attribute"
|
||||
bl_description = "Enable variable density solver and attribute in the Domain World panel"
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
return context.scene.flip_fluid.get_domain_object() is not None
|
||||
|
||||
|
||||
def execute(self, context):
|
||||
dprops = context.scene.flip_fluid.get_domain_properties()
|
||||
dprops.world.enable_density_attribute = True
|
||||
return {'FINISHED'}
|
||||
|
||||
|
||||
class FlipFluidEnableDensityAttributeMenu(bpy.types.Menu):
|
||||
bl_label = ""
|
||||
bl_idname = "FLIP_FLUID_MENUS_MT_enable_density_attribute_menu"
|
||||
|
||||
def draw(self, context):
|
||||
self.layout.operator("flip_fluid_operators.enable_density_attribute")
|
||||
|
||||
|
||||
class FlipFluidEnableDensityAttributeTooltip(bpy.types.Operator):
|
||||
bl_idname = "flip_fluid_operators.enable_density_attribute_tooltip"
|
||||
bl_label = "Enable Density Attribute"
|
||||
bl_description = "Click to enable the variable density solver and attribute in the Domain World panel"
|
||||
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
return context.scene.flip_fluid.get_domain_object() is not None
|
||||
|
||||
|
||||
def execute(self, context):
|
||||
bpy.ops.wm.call_menu(name="FLIP_FLUID_MENUS_MT_enable_density_attribute_menu")
|
||||
return {'FINISHED'}
|
||||
|
||||
|
||||
class FlipFluidEnableLifetimeAttribute(bpy.types.Operator):
|
||||
bl_idname = "flip_fluid_operators.enable_lifetime_attribute"
|
||||
bl_label = "Enable Lifetime Attribute"
|
||||
bl_description = "Enable lifetime attribute in the Domain FLIP Fluid Surface and Domain FLIP Fluid Particles panel"
|
||||
bl_description = "Enable lifetime attribute in the Domain Surface and/or Domain Particles panel"
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
@@ -1619,7 +1651,8 @@ class FlipFluidEnableLifetimeAttribute(bpy.types.Operator):
|
||||
def execute(self, context):
|
||||
dprops = context.scene.flip_fluid.get_domain_properties()
|
||||
dprops.surface.enable_lifetime_attribute = True
|
||||
dprops.particles.enable_lifetime_attribute = True
|
||||
dprops.particles.enable_fluid_particle_lifetime_attribute = True
|
||||
dprops.whitewater.enable_lifetime_attribute = True
|
||||
return {'FINISHED'}
|
||||
|
||||
|
||||
@@ -1634,7 +1667,7 @@ class FlipFluidEnableLifetimeAttributeMenu(bpy.types.Menu):
|
||||
class FlipFluidEnableLifetimeAttributeTooltip(bpy.types.Operator):
|
||||
bl_idname = "flip_fluid_operators.enable_lifetime_attribute_tooltip"
|
||||
bl_label = "Enable Lifetime Attribute"
|
||||
bl_description = "Click to enable the lifetime attribute in the Domain FLIP Fluid Surface and Domain FLIP Fluid Particles panel"
|
||||
bl_description = "Click to enable the lifetime attribute in the Domain Surface and/or Domain Particles panel"
|
||||
|
||||
|
||||
@classmethod
|
||||
@@ -1650,7 +1683,7 @@ class FlipFluidEnableLifetimeAttributeTooltip(bpy.types.Operator):
|
||||
class FlipFluidEnableSourceIDAttribute(bpy.types.Operator):
|
||||
bl_idname = "flip_fluid_operators.enable_source_id_attribute"
|
||||
bl_label = "Enable Source ID Attribute"
|
||||
bl_description = "Enable source ID attribute in the Domain FLIP Fluid Surface and FLIP Fluid Particles panel"
|
||||
bl_description = "Enable source ID attribute in the Domain Surface and/or Particles panel"
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
@@ -1675,7 +1708,7 @@ class FlipFluidEnableSourceIDAttributeMenu(bpy.types.Menu):
|
||||
class FlipFluidEnableSourceIDAttributeTooltip(bpy.types.Operator):
|
||||
bl_idname = "flip_fluid_operators.enable_source_id_attribute_tooltip"
|
||||
bl_label = "Enable Source ID Attribute"
|
||||
bl_description = "Click to enable the source ID attribute in the Domain FLIP Fluid Surface and FLIP Fluid Particles panel"
|
||||
bl_description = "Click to enable the source ID attribute in the Domain Surface and/or Domain Particles panel"
|
||||
|
||||
|
||||
@classmethod
|
||||
@@ -1689,9 +1722,6 @@ class FlipFluidEnableSourceIDAttributeTooltip(bpy.types.Operator):
|
||||
|
||||
|
||||
def is_geometry_node_point_cloud_detected(bl_mesh_cache_object=None):
|
||||
if not vcu.is_blender_31():
|
||||
return False
|
||||
|
||||
try:
|
||||
dprops = bpy.context.scene.flip_fluid.get_domain_properties()
|
||||
if bl_mesh_cache_object is None:
|
||||
@@ -1723,7 +1753,7 @@ def is_geometry_node_point_cloud_detected(bl_mesh_cache_object=None):
|
||||
|
||||
|
||||
def update_geometry_node_material(bl_object, resource_name):
|
||||
if not vcu.is_blender_31() or bl_object is None:
|
||||
if bl_object is None:
|
||||
return
|
||||
|
||||
gn_modifier = None
|
||||
@@ -1769,6 +1799,13 @@ def add_geometry_node_modifier(target_object, resource_filepath, resource_name):
|
||||
return gn_modifier
|
||||
|
||||
|
||||
def get_geometry_node_modifier(target_object, resource_name):
|
||||
for mod in target_object.modifiers:
|
||||
if mod.type == 'NODES' and mod.name == resource_name:
|
||||
return mod
|
||||
return None
|
||||
|
||||
|
||||
class FlipFluidHelperInitializeMotionBlur(bpy.types.Operator):
|
||||
bl_idname = "flip_fluid_operators.helper_initialize_motion_blur"
|
||||
bl_label = "Initialize Motion Blur"
|
||||
@@ -1776,8 +1813,7 @@ class FlipFluidHelperInitializeMotionBlur(bpy.types.Operator):
|
||||
" This will be applied to the fluid surface, fluid particles, and whitewater particles if enabled." +
|
||||
" Node groups can be viewed in the geometry nodes editor and modifier")
|
||||
|
||||
resource_prefix = StringProperty(default="FF_GeometryNodes")
|
||||
exec(vcu.convert_attribute_to_28("resource_prefix"))
|
||||
resource_prefix: StringProperty(default="FF_GeometryNodes")
|
||||
|
||||
|
||||
@classmethod
|
||||
@@ -1786,10 +1822,6 @@ class FlipFluidHelperInitializeMotionBlur(bpy.types.Operator):
|
||||
|
||||
|
||||
def apply_modifier_settings(self, target_object, gn_modifier):
|
||||
gn_modifier["Input_2_use_attribute"] = True
|
||||
gn_modifier["Input_2_attribute_name"] = 'flip_velocity'
|
||||
gn_modifier["Output_3_attribute_name"] = 'velocity'
|
||||
|
||||
gn_name = gn_modifier.name
|
||||
if gn_name.startswith("FF_GeometryNodesSurface"):
|
||||
# Depending on FLIP Fluids version, the GN set up may not
|
||||
@@ -1815,30 +1847,15 @@ class FlipFluidHelperInitializeMotionBlur(bpy.types.Operator):
|
||||
except:
|
||||
pass
|
||||
|
||||
try:
|
||||
# Enable Point Cloud
|
||||
gn_modifier["Input_9"] = True
|
||||
except:
|
||||
pass
|
||||
|
||||
try:
|
||||
# Enable Instancing
|
||||
gn_modifier["Input_10"] = False
|
||||
except:
|
||||
pass
|
||||
|
||||
|
||||
def execute(self, context):
|
||||
if not vcu.is_blender_31():
|
||||
self.report({'INFO'}, "Blender 3.1 or later is required for this feature")
|
||||
return {'CANCELLED'}
|
||||
|
||||
if not context.scene.flip_fluid.is_domain_in_active_scene():
|
||||
self.report({"ERROR"},
|
||||
"Active scene must contain domain object to use this operator. Select the scene that contains the domain object and try again.")
|
||||
return {'CANCELLED'}
|
||||
|
||||
if context.scene.render.engine != 'CYCLES':
|
||||
unsupported_render_engines = ['BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH']
|
||||
if context.scene.render.engine in unsupported_render_engines:
|
||||
context.scene.render.engine = 'CYCLES'
|
||||
self.report({'INFO'}, "Setting render engine to Cycles")
|
||||
if not context.scene.render.use_motion_blur:
|
||||
@@ -1848,15 +1865,15 @@ class FlipFluidHelperInitializeMotionBlur(bpy.types.Operator):
|
||||
dprops = context.scene.flip_fluid.get_domain_properties()
|
||||
if not dprops.surface.enable_velocity_vector_attribute:
|
||||
dprops.surface.enable_velocity_vector_attribute = True
|
||||
self.report({'INFO'}, "Enabled generation of fluid surface velocity vector attributes in FLIP Fluid Surface panel (baking required)")
|
||||
self.report({'INFO'}, "Enabled generation of fluid surface velocity vector attributes in Domain Surface panel (baking required)")
|
||||
|
||||
if not dprops.particles.enable_fluid_particle_velocity_vector_attribute:
|
||||
dprops.particles.enable_fluid_particle_velocity_vector_attribute = True
|
||||
self.report({'INFO'}, "Enabled generation of fluid particle velocity vector attributes in FLIP Fluid Particles panel (baking required)")
|
||||
self.report({'INFO'}, "Enabled generation of fluid particle velocity vector attributes in Domain Particles panel (baking required)")
|
||||
|
||||
if not dprops.whitewater.enable_velocity_vector_attribute:
|
||||
dprops.whitewater.enable_velocity_vector_attribute = True
|
||||
self.report({'INFO'}, "Enabled generation of whitewater velocity vector attributes in FLIP Fluid Whitewater (baking required)")
|
||||
self.report({'INFO'}, "Enabled generation of whitewater velocity vector attributes in Domain Whitewater (baking required)")
|
||||
|
||||
blend_filename = "geometry_nodes_library.blend"
|
||||
surface_resource = self.resource_prefix + "Surface"
|
||||
@@ -1943,8 +1960,7 @@ class FlipFluidHelperRemoveMotionBlur(bpy.types.Operator):
|
||||
" operator will not disable the Domain surface/particles/whitewater velocity attribute settings")
|
||||
|
||||
|
||||
resource_prefix = StringProperty(default="FF_GeometryNodes")
|
||||
exec(vcu.convert_attribute_to_28("resource_prefix"))
|
||||
resource_prefix: StringProperty(default="FF_GeometryNodes")
|
||||
|
||||
|
||||
@classmethod
|
||||
@@ -1953,10 +1969,6 @@ class FlipFluidHelperRemoveMotionBlur(bpy.types.Operator):
|
||||
|
||||
|
||||
def execute(self, context):
|
||||
if not vcu.is_blender_31():
|
||||
self.report({'INFO'}, "Blender 3.1 or later is required for this feature")
|
||||
return {'CANCELLED'}
|
||||
|
||||
if not context.scene.flip_fluid.is_domain_in_active_scene():
|
||||
self.report({"ERROR"},
|
||||
"Active scene must contain domain object to use this operator. Select the scene that contains the domain object and try again.")
|
||||
@@ -2019,8 +2031,7 @@ class FlipFluidHelperToggleMotionBlurRendering(bpy.types.Operator):
|
||||
bl_description = ("Toggle motion blur rendering for the simulation meshes on or off. This operator will enable or" +
|
||||
" disable the simulations mesh object and geometry node settings for motion blur rendering")
|
||||
|
||||
enable_motion_blur_rendering = BoolProperty(default=True)
|
||||
exec(vcu.convert_attribute_to_28("enable_motion_blur_rendering"))
|
||||
enable_motion_blur_rendering: BoolProperty(default=True)
|
||||
|
||||
|
||||
@classmethod
|
||||
@@ -2070,13 +2081,207 @@ class FlipFluidHelperToggleMotionBlurRendering(bpy.types.Operator):
|
||||
return {'FINISHED'}
|
||||
|
||||
|
||||
class FlipFluidHelperUpdateGeometryNodeModifiers(bpy.types.Operator):
|
||||
bl_idname = "flip_fluid_operators.helper_update_geometry_node_modifiers"
|
||||
bl_label = "Update Geometry Node Modifiers"
|
||||
bl_description = ("Update the fluid surface, particle, and whitewater geometry nodes modifiers to the current addon version and transfer settings." +
|
||||
" This operator will not delete existing FLIP Fluids modifiers or datablocks. Existing modifiers will be renamed with a" +
|
||||
" BACKUP prefix and disabled in the modifier stack. This backup can be removed if not wanted")
|
||||
|
||||
resource_prefix: StringProperty(default="FF_GeometryNodes")
|
||||
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
return context.scene.flip_fluid.get_domain_object() is not None
|
||||
|
||||
|
||||
def transfer_gn_modifer_settings(self, old_gn_modifier, new_gn_modifier, old_new_key_pairs):
|
||||
for key in old_new_key_pairs:
|
||||
old_key = key[0]
|
||||
new_key = key[1]
|
||||
if old_key in old_gn_modifier:
|
||||
try:
|
||||
new_gn_modifier[new_key] = old_gn_modifier[old_key]
|
||||
except:
|
||||
pass
|
||||
|
||||
|
||||
def transfer_gn_modifier_settings_surface(self, old_gn_modifier, new_gn_modifier):
|
||||
# Old Key, New Key
|
||||
keys = [
|
||||
("Input_6", "Input_6"), # Enable Motion Blur
|
||||
("Input_4", "Input_4"), # Motion Blur Scale
|
||||
]
|
||||
|
||||
self.transfer_gn_modifer_settings(old_gn_modifier, new_gn_modifier, keys)
|
||||
|
||||
|
||||
def transfer_gn_modifier_settings_fluid_particle(self, old_gn_modifier, new_gn_modifier):
|
||||
# Old Key, New Key
|
||||
keys = [
|
||||
("Input_5", "Input_5"), # Material
|
||||
("Input_8", "Input_8"), # Enable Motion Blur
|
||||
("Input_4", "Input_4"), # Motion Blur Scale
|
||||
("Input_6", "Input_6"), # Particle Scale
|
||||
("Socket_2", "Socket_2"), # Particle Scale Random
|
||||
("Socket_1", "Socket_1"), # Fading Width
|
||||
("Socket_0", "Socket_0"), # Fading Strength
|
||||
("Socket_4", "Socket_4"), # Fading Density
|
||||
]
|
||||
|
||||
self.transfer_gn_modifer_settings(old_gn_modifier, new_gn_modifier, keys)
|
||||
|
||||
|
||||
def transfer_gn_modifier_settings_whitewater(self, old_gn_modifier, new_gn_modifier):
|
||||
# Old Key, New Key
|
||||
keys = [
|
||||
("Input_5", "Input_5"), # Material
|
||||
("Input_8", "Input_8"), # Enable Motion Blur
|
||||
("Input_4", "Input_4"), # Motion Blur Scale
|
||||
("Input_6", "Input_6"), # Particle Scale
|
||||
("Socket_2", "Socket_2"), # Particle Scale Random
|
||||
("Socket_1", "Socket_1"), # Fading Width
|
||||
("Socket_0", "Socket_0"), # Fading Strength
|
||||
("Socket_4", "Socket_4"), # Fading Density
|
||||
]
|
||||
|
||||
self.transfer_gn_modifer_settings(old_gn_modifier, new_gn_modifier, keys)
|
||||
|
||||
|
||||
def get_ff_geometry_node_modifiers(self, bl_object):
|
||||
modifiers = []
|
||||
if bl_object is None:
|
||||
return modifiers
|
||||
for mod in bl_object.modifiers:
|
||||
if mod.type == "NODES" and mod.node_group and mod.node_group.name.startswith("FF_GeometryNodes"):
|
||||
modifiers.append(mod)
|
||||
return modifiers
|
||||
|
||||
|
||||
def execute(self, context):
|
||||
if not context.scene.flip_fluid.is_domain_in_active_scene():
|
||||
self.report({"ERROR"},
|
||||
"Active scene must contain domain object to use this operator. Select the scene that contains the domain object and try again.")
|
||||
return {'CANCELLED'}
|
||||
|
||||
dprops = context.scene.flip_fluid.get_domain_properties()
|
||||
|
||||
# Gather Blender cache objects
|
||||
surface_mesh_caches = [dprops.mesh_cache.surface]
|
||||
surface_cache_objects = []
|
||||
for m in surface_mesh_caches:
|
||||
bl_object = m.get_cache_object()
|
||||
if bl_object is not None:
|
||||
surface_cache_objects.append(bl_object)
|
||||
|
||||
fluid_particle_mesh_caches = [dprops.mesh_cache.particles]
|
||||
fluid_particle_cache_objects = []
|
||||
for m in fluid_particle_mesh_caches:
|
||||
bl_object = m.get_cache_object()
|
||||
if bl_object is not None:
|
||||
fluid_particle_cache_objects.append(bl_object)
|
||||
|
||||
whitewater_mesh_caches = [
|
||||
dprops.mesh_cache.foam,
|
||||
dprops.mesh_cache.bubble,
|
||||
dprops.mesh_cache.spray,
|
||||
dprops.mesh_cache.dust
|
||||
]
|
||||
whitewater_cache_objects = []
|
||||
for m in whitewater_mesh_caches:
|
||||
bl_object = m.get_cache_object()
|
||||
if bl_object is not None:
|
||||
whitewater_cache_objects.append(bl_object)
|
||||
|
||||
bl_cache_objects = surface_cache_objects + fluid_particle_cache_objects + whitewater_cache_objects
|
||||
|
||||
# Search for the last FF_GeometryNodes modifier in the stack for each cache object for transferring settings
|
||||
surface_gn_modifiers = []
|
||||
for bl_object in surface_cache_objects:
|
||||
existing_gn_modifiers = self.get_ff_geometry_node_modifiers(bl_object)
|
||||
if existing_gn_modifiers:
|
||||
surface_gn_modifiers.append(existing_gn_modifiers[-1])
|
||||
else:
|
||||
surface_gn_modifiers.append(None)
|
||||
|
||||
fluid_particle_gn_modifiers = []
|
||||
for bl_object in fluid_particle_cache_objects:
|
||||
existing_gn_modifiers = self.get_ff_geometry_node_modifiers(bl_object)
|
||||
if existing_gn_modifiers:
|
||||
fluid_particle_gn_modifiers.append(existing_gn_modifiers[-1])
|
||||
else:
|
||||
fluid_particle_gn_modifiers.append(None)
|
||||
|
||||
whitewater_gn_modifiers = []
|
||||
for bl_object in whitewater_cache_objects:
|
||||
existing_gn_modifiers = self.get_ff_geometry_node_modifiers(bl_object)
|
||||
if existing_gn_modifiers:
|
||||
whitewater_gn_modifiers.append(existing_gn_modifiers[-1])
|
||||
else:
|
||||
whitewater_gn_modifiers.append(None)
|
||||
|
||||
# Disable existing FF_GeometryNode modifiers and rename with BACKUP_ prefix
|
||||
for bl_object in bl_cache_objects:
|
||||
existing_gn_modifiers = self.get_ff_geometry_node_modifiers(bl_object)
|
||||
for mod in existing_gn_modifiers:
|
||||
mod.show_viewport = False
|
||||
mod.show_render = False
|
||||
mod.show_expanded = False
|
||||
mod.name = "BACKUP_" + mod.name
|
||||
mod.node_group.name = "BACKUP_" + mod.node_group.name
|
||||
|
||||
# Initialize current FF_GeometryNode modifiers
|
||||
geometry_nodes_library = "geometry_nodes_library.blend"
|
||||
parent_path = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
|
||||
resource_filepath = os.path.join(parent_path, "resources", "geometry_nodes", geometry_nodes_library)
|
||||
|
||||
surface_resource = self.resource_prefix + "Surface"
|
||||
fluid_particle_resource = self.resource_prefix + "FluidParticles"
|
||||
whitewater_foam_resource = self.resource_prefix + "WhitewaterFoam"
|
||||
whitewater_bubble_resource = self.resource_prefix + "WhitewaterBubble"
|
||||
whitewater_spray_resource = self.resource_prefix + "WhitewaterSpray"
|
||||
whitewater_dust_resource = self.resource_prefix + "WhitewaterDust"
|
||||
|
||||
for idx, bl_surface in enumerate(surface_cache_objects):
|
||||
old_gn_modifier = surface_gn_modifiers[idx]
|
||||
new_gn_modifier = add_geometry_node_modifier(bl_surface, resource_filepath, surface_resource)
|
||||
if old_gn_modifier and new_gn_modifier:
|
||||
self.transfer_gn_modifier_settings_surface(old_gn_modifier, new_gn_modifier)
|
||||
|
||||
for idx, bl_fluid_particle in enumerate(fluid_particle_cache_objects):
|
||||
old_gn_modifier = fluid_particle_gn_modifiers[idx]
|
||||
new_gn_modifier = add_geometry_node_modifier(bl_fluid_particle, resource_filepath, fluid_particle_resource)
|
||||
if old_gn_modifier and new_gn_modifier:
|
||||
self.transfer_gn_modifier_settings_fluid_particle(old_gn_modifier, new_gn_modifier)
|
||||
|
||||
for idx, bl_whitewater in enumerate(whitewater_cache_objects):
|
||||
whitewater_resource = ""
|
||||
if bl_whitewater == dprops.mesh_cache.foam.get_cache_object():
|
||||
whitewater_resource = whitewater_foam_resource
|
||||
elif bl_whitewater == dprops.mesh_cache.bubble.get_cache_object():
|
||||
whitewater_resource = whitewater_bubble_resource
|
||||
elif bl_whitewater == dprops.mesh_cache.spray.get_cache_object():
|
||||
whitewater_resource = whitewater_spray_resource
|
||||
elif bl_whitewater == dprops.mesh_cache.dust.get_cache_object():
|
||||
whitewater_resource = whitewater_dust_resource
|
||||
|
||||
old_gn_modifier = whitewater_gn_modifiers[idx]
|
||||
new_gn_modifier = add_geometry_node_modifier(bl_whitewater, resource_filepath, whitewater_resource)
|
||||
if old_gn_modifier and new_gn_modifier:
|
||||
self.transfer_gn_modifier_settings_whitewater(old_gn_modifier, new_gn_modifier)
|
||||
|
||||
self.report({'INFO'}, "Updated FLIP Fluids Geometry Node Modifiers")
|
||||
|
||||
return {'FINISHED'}
|
||||
|
||||
|
||||
class FlipFluidHelperInitializeCacheObjects(bpy.types.Operator):
|
||||
bl_idname = "flip_fluid_operators.helper_initialize_cache_objects"
|
||||
bl_label = "Initialize Cache Objects"
|
||||
bl_description = ("Initialize simulation meshes, modifiers, and data")
|
||||
|
||||
cache_object_type = StringProperty(default="CACHE_OBJECT_TYPE_NONE")
|
||||
exec(vcu.convert_attribute_to_28("cache_object_type"))
|
||||
cache_object_type: StringProperty(default="CACHE_OBJECT_TYPE_NONE")
|
||||
|
||||
|
||||
@classmethod
|
||||
@@ -2139,8 +2344,7 @@ class FlipFluidHelperStableRendering28(bpy.types.Operator):
|
||||
" during render (Blender > Render > Lock Interface) and is highly"
|
||||
" recommended")
|
||||
|
||||
enable_state = BoolProperty(True)
|
||||
exec(vcu.convert_attribute_to_28("enable_state"))
|
||||
enable_state: BoolProperty(True)
|
||||
|
||||
|
||||
@classmethod
|
||||
@@ -2188,8 +2392,7 @@ class FlipFluidHelperSaveBlendFile(bpy.types.Operator):
|
||||
bl_label = "Save File"
|
||||
bl_description = "Open the Blender file window to save the current .blend file"
|
||||
|
||||
save_as_blend_file = BoolProperty(default=True)
|
||||
exec(vcu.convert_attribute_to_28("save_as_blend_file"))
|
||||
save_as_blend_file: BoolProperty(default=True)
|
||||
|
||||
|
||||
@classmethod
|
||||
@@ -2241,8 +2444,7 @@ class FlipFluidHelperBatchExportAnimatedMesh(bpy.types.Operator):
|
||||
bl_description = "Enable or Disable the 'Export Animated Mesh' option for all objects in list"
|
||||
|
||||
|
||||
enable_state = BoolProperty(True)
|
||||
exec(vcu.convert_attribute_to_28("enable_state"))
|
||||
enable_state: BoolProperty(True)
|
||||
|
||||
|
||||
@classmethod
|
||||
@@ -2265,8 +2467,7 @@ class FlipFluidHelperBatchSkipReexport(bpy.types.Operator):
|
||||
bl_description = "Enable or Disable the 'Skip Re-Export' option for all objects in list"
|
||||
|
||||
|
||||
enable_state = BoolProperty(True)
|
||||
exec(vcu.convert_attribute_to_28("enable_state"))
|
||||
enable_state: BoolProperty(True)
|
||||
|
||||
|
||||
@classmethod
|
||||
@@ -2289,8 +2490,7 @@ class FlipFluidHelperBatchForceReexport(bpy.types.Operator):
|
||||
bl_description = "Enable or Disable the 'Force Re-Export On Next Bake' option for all objects in list"
|
||||
|
||||
|
||||
enable_state = BoolProperty(True)
|
||||
exec(vcu.convert_attribute_to_28("enable_state"))
|
||||
enable_state: BoolProperty(True)
|
||||
|
||||
|
||||
@classmethod
|
||||
@@ -2538,20 +2738,12 @@ class FlipFluidCopySettingsFromActive(bpy.types.Operator):
|
||||
def toggle_cycles_ray_visibility(self, obj, is_enabled):
|
||||
# Cycles may not be enabled in the user's preferences
|
||||
try:
|
||||
if vcu.is_blender_30():
|
||||
obj.visible_camera = is_enabled
|
||||
obj.visible_diffuse = is_enabled
|
||||
obj.visible_glossy = is_enabled
|
||||
obj.visible_transmission = is_enabled
|
||||
obj.visible_volume_scatter = is_enabled
|
||||
obj.visible_shadow = is_enabled
|
||||
else:
|
||||
obj.cycles_visibility.camera = is_enabled
|
||||
obj.cycles_visibility.transmission = is_enabled
|
||||
obj.cycles_visibility.diffuse = is_enabled
|
||||
obj.cycles_visibility.scatter = is_enabled
|
||||
obj.cycles_visibility.glossy = is_enabled
|
||||
obj.cycles_visibility.shadow = is_enabled
|
||||
obj.visible_camera = is_enabled
|
||||
obj.visible_diffuse = is_enabled
|
||||
obj.visible_glossy = is_enabled
|
||||
obj.visible_transmission = is_enabled
|
||||
obj.visible_volume_scatter = is_enabled
|
||||
obj.visible_shadow = is_enabled
|
||||
except:
|
||||
pass
|
||||
|
||||
@@ -4507,11 +4699,7 @@ class FlipFluidPassesImportMedia(bpy.types.Operator):
|
||||
bl_idname = "flip_fluid.passes_import_media"
|
||||
bl_label = "Import Media"
|
||||
|
||||
option_path_supports_blend_relative = set()
|
||||
if vcu.is_blender_45():
|
||||
# required for relative path support in Blender 4.5+
|
||||
# https://docs.blender.org/api/4.5/bpy_types_enum_items/property_flag_items.html#rna-enum-property-flag-items
|
||||
option_path_supports_blend_relative = {'PATH_SUPPORTS_BLEND_RELATIVE'}
|
||||
option_path_supports_blend_relative = {'PATH_SUPPORTS_BLEND_RELATIVE'}
|
||||
|
||||
filter_glob: StringProperty(
|
||||
default="*.png;*.jpg;*.jpeg;*.bmp;*.tiff;*.tif;*.mp4;*.avi;*.mov",
|
||||
@@ -5992,6 +6180,7 @@ def register():
|
||||
FlipFluidHelperInitializeMotionBlur,
|
||||
FlipFluidHelperRemoveMotionBlur,
|
||||
FlipFluidHelperToggleMotionBlurRendering,
|
||||
FlipFluidHelperUpdateGeometryNodeModifiers,
|
||||
FlipFluidHelperInitializeCacheObjects,
|
||||
FlipFluidHelperStableRendering279,
|
||||
FlipFluidHelperStableRendering28,
|
||||
@@ -6013,6 +6202,9 @@ def register():
|
||||
FlipFluidEnableViscosityAttribute,
|
||||
FlipFluidEnableViscosityAttributeMenu,
|
||||
FlipFluidEnableViscosityAttributeTooltip,
|
||||
FlipFluidEnableDensityAttribute,
|
||||
FlipFluidEnableDensityAttributeMenu,
|
||||
FlipFluidEnableDensityAttributeTooltip,
|
||||
FlipFluidEnableLifetimeAttribute,
|
||||
FlipFluidEnableLifetimeAttributeMenu,
|
||||
FlipFluidEnableLifetimeAttributeTooltip,
|
||||
@@ -6103,6 +6295,7 @@ def unregister():
|
||||
bpy.utils.unregister_class(FlipFluidHelperInitializeMotionBlur)
|
||||
bpy.utils.unregister_class(FlipFluidHelperRemoveMotionBlur)
|
||||
bpy.utils.unregister_class(FlipFluidHelperToggleMotionBlurRendering)
|
||||
bpy.utils.unregister_class(FlipFluidHelperUpdateGeometryNodeModifiers)
|
||||
bpy.utils.unregister_class(FlipFluidHelperInitializeCacheObjects)
|
||||
bpy.utils.unregister_class(FlipFluidHelperStableRendering279)
|
||||
bpy.utils.unregister_class(FlipFluidHelperStableRendering28)
|
||||
@@ -6124,6 +6317,9 @@ def unregister():
|
||||
bpy.utils.unregister_class(FlipFluidEnableViscosityAttribute)
|
||||
bpy.utils.unregister_class(FlipFluidEnableViscosityAttributeMenu)
|
||||
bpy.utils.unregister_class(FlipFluidEnableViscosityAttributeTooltip)
|
||||
bpy.utils.unregister_class(FlipFluidEnableDensityAttribute)
|
||||
bpy.utils.unregister_class(FlipFluidEnableDensityAttributeMenu)
|
||||
bpy.utils.unregister_class(FlipFluidEnableDensityAttributeTooltip)
|
||||
bpy.utils.unregister_class(FlipFluidEnableLifetimeAttribute)
|
||||
bpy.utils.unregister_class(FlipFluidEnableLifetimeAttributeMenu)
|
||||
bpy.utils.unregister_class(FlipFluidEnableLifetimeAttributeTooltip)
|
||||
|
||||
@@ -47,8 +47,7 @@ class FLIPFluidPreferencesExportUserData(bpy.types.Operator):
|
||||
bl_description = ("Creates a backup of your user settings and presets as a" +
|
||||
" .zip file. All user data will be lost after uninstalling the addon.")
|
||||
|
||||
filepath = StringProperty(subtype="FILE_PATH")
|
||||
exec(vcu.convert_attribute_to_28("filepath"))
|
||||
filepath: StringProperty(subtype="FILE_PATH")
|
||||
|
||||
|
||||
@classmethod
|
||||
@@ -180,12 +179,11 @@ class FLIPFluidPreferencesImportUserData(bpy.types.Operator, ImportHelper):
|
||||
bl_description = "Load user settings and presets from a previous installation"
|
||||
|
||||
filename_ext = "*.zip"
|
||||
filter_glob = StringProperty(
|
||||
filter_glob: StringProperty(
|
||||
default="*.zip",
|
||||
options={'HIDDEN'},
|
||||
maxlen=255,
|
||||
)
|
||||
exec(vcu.convert_attribute_to_28("filter_glob"))
|
||||
|
||||
|
||||
|
||||
@@ -264,12 +262,11 @@ class FLIPFluidInstallMixboxPlugin(bpy.types.Operator, ImportHelper):
|
||||
" Fluids addon downloads")
|
||||
|
||||
filename_ext = "*.plugin"
|
||||
filter_glob = StringProperty(
|
||||
filter_glob: StringProperty(
|
||||
default="*.plugin;*.zip",
|
||||
options={'HIDDEN'},
|
||||
maxlen=255,
|
||||
)
|
||||
exec(vcu.convert_attribute_to_28("filter_glob"))
|
||||
|
||||
|
||||
@classmethod
|
||||
@@ -377,12 +374,11 @@ class FLIPFluidInstallPresetLibrary(bpy.types.Operator, ImportHelper):
|
||||
" The Preset Scenes file can be found in the FLIP Fluids addon downloads")
|
||||
|
||||
filename_ext = "*.zip"
|
||||
filter_glob = StringProperty(
|
||||
filter_glob: StringProperty(
|
||||
default="*.zip",
|
||||
options={'HIDDEN'},
|
||||
maxlen=255,
|
||||
)
|
||||
exec(vcu.convert_attribute_to_28("filter_glob"))
|
||||
|
||||
|
||||
@classmethod
|
||||
@@ -512,9 +508,7 @@ class FLIPFluidInstallPresetLibrary(bpy.types.Operator, ImportHelper):
|
||||
for lib_entry in bl_filepaths.asset_libraries:
|
||||
if self.is_path_equal(lib_entry.path, preset_library_directory):
|
||||
lib_entry.name = preset_library_name
|
||||
if vcu.is_blender_35():
|
||||
# Only available in Blender >= 3.5
|
||||
lib_entry.import_method = 'APPEND'
|
||||
lib_entry.import_method = 'APPEND'
|
||||
|
||||
installation_utils.update_preset_library_installation_status()
|
||||
success_message = "The Preset Scenes Library has been installed successfully into the Blender Asset Browser."
|
||||
@@ -529,11 +523,9 @@ class FLIPFluidSelectPresetLibraryFolder(bpy.types.Operator):
|
||||
bl_label = "Install Preset Folder"
|
||||
bl_description = ("Select an existing Preset Library installation folder and add it to the Blender Asset Browser")
|
||||
|
||||
directory = bpy.props.StringProperty(name="Directory", options={"HIDDEN"})
|
||||
exec(vcu.convert_attribute_to_28("directory"))
|
||||
directory: bpy.props.StringProperty(name="Directory", options={"HIDDEN"})
|
||||
|
||||
filter_folder = bpy.props.BoolProperty(default=True, options={"HIDDEN"})
|
||||
exec(vcu.convert_attribute_to_28("filter_folder"))
|
||||
filter_folder: bpy.props.BoolProperty(default=True, options={"HIDDEN"})
|
||||
|
||||
|
||||
@classmethod
|
||||
@@ -643,9 +635,7 @@ class FLIPFluidSelectPresetLibraryFolder(bpy.types.Operator):
|
||||
lib_version_str = "v" + str(version[0]) + "." + str(version[1]) + "." + str(version[2])
|
||||
preset_library_name = "FLIP Fluids Addon Presets " + lib_version_str
|
||||
lib_entry.name = preset_library_name
|
||||
if vcu.is_blender_35():
|
||||
# Only available in Blender >= 3.5
|
||||
lib_entry.import_method = 'APPEND'
|
||||
lib_entry.import_method = 'APPEND'
|
||||
|
||||
installation_utils.update_preset_library_installation_status()
|
||||
success_message = "The Preset Scenes Library has been installed successfully into the Blender Asset Browser."
|
||||
@@ -667,8 +657,7 @@ class FLIPFluidPresetLibraryCopyInstallLocation(bpy.types.Operator):
|
||||
bl_description = ("Copy the preset library location to the Install Location field and" +
|
||||
" system clipboard. The install location is the parent directory of the path listed below")
|
||||
|
||||
install_location = StringProperty(default="")
|
||||
exec(vcu.convert_attribute_to_28("install_location"))
|
||||
install_location: StringProperty(default="")
|
||||
|
||||
def execute(self, context):
|
||||
preferences = vcu.get_addon_preferences()
|
||||
@@ -683,8 +672,7 @@ class FLIPFluidUninstallPresetLibrary(bpy.types.Operator):
|
||||
bl_description = ("Uninstall the preset library. The preset library will be removed from" +
|
||||
" the Blender Asset Browser and the files deleted from your system")
|
||||
|
||||
install_info_json_string = StringProperty(default="")
|
||||
exec(vcu.convert_attribute_to_28("install_info_json_string"))
|
||||
install_info_json_string: StringProperty(default="")
|
||||
|
||||
|
||||
def tag_redraw(self, context):
|
||||
@@ -751,8 +739,7 @@ class FLIPFluidUninstallPresetLibrary(bpy.types.Operator):
|
||||
|
||||
|
||||
class VersionDataTextEntry(bpy.types.PropertyGroup):
|
||||
text = StringProperty(default="")
|
||||
exec(vcu.convert_attribute_to_28("text"))
|
||||
text: StringProperty(default="")
|
||||
|
||||
|
||||
def get_gpu_string():
|
||||
@@ -899,12 +886,11 @@ def get_system_info_dict():
|
||||
addons_list = []
|
||||
addons_string = "Unknown"
|
||||
try:
|
||||
if vcu.is_blender_42():
|
||||
for addon in bpy.context.preferences.addons:
|
||||
addon_name = addon.module
|
||||
addon_name = addon_name.split('.')[-1]
|
||||
if addon_name and addon_name not in default_addons:
|
||||
addons_list.append(addon_name)
|
||||
for addon in bpy.context.preferences.addons:
|
||||
addon_name = addon.module
|
||||
addon_name = addon_name.split('.')[-1]
|
||||
if addon_name and addon_name not in default_addons:
|
||||
addons_list.append(addon_name)
|
||||
if addons_list:
|
||||
addons_string = ', '.join(addons_list)
|
||||
else:
|
||||
@@ -913,7 +899,7 @@ def get_system_info_dict():
|
||||
print(traceback.format_exc())
|
||||
print(e)
|
||||
|
||||
developer_tools_string = "Uknown"
|
||||
developer_tools_string = "Unknown"
|
||||
try:
|
||||
preferences = vcu.get_addon_preferences()
|
||||
developer_tools_string = "Enabled" if preferences.enable_extra_features else "Disabled"
|
||||
@@ -1198,6 +1184,7 @@ def get_system_info_dict():
|
||||
d = {}
|
||||
d['blender_version'] = blender_version
|
||||
d['addon_version'] = bl_info.get('description', "Missing Version Label")
|
||||
d['addon_support_license'] = installation_utils.get_support_license_label()
|
||||
d['operating_system'] = platform.platform()
|
||||
d['cpu'] = cpu_string
|
||||
d['threads'] = threads_string
|
||||
@@ -1256,6 +1243,7 @@ class FlipFluidReportBugPrefill(bpy.types.Operator):
|
||||
user_info += "#### System and Blend File Information\n\n"
|
||||
user_info += "**Blender Version:** " + sys_info['blender_version'] + "\n"
|
||||
user_info += "**Addon Version:** " + sys_info['addon_version'] + "\n"
|
||||
user_info += "**Addon Build:** " + sys_info['addon_support_license'] + "\n"
|
||||
user_info += "**OS:** " + sys_info['operating_system'] + "\n"
|
||||
user_info += "**GPU:** " + sys_info['gpu'] + "\n"
|
||||
user_info += "**CPU:** " + sys_info['cpu'] + "\n"
|
||||
@@ -1318,6 +1306,7 @@ def get_system_info_string():
|
||||
user_info = ""
|
||||
user_info += "Blender Version: " + sys_info['blender_version'] + "\n"
|
||||
user_info += "Addon Version: " + sys_info['addon_version'] + "\n"
|
||||
user_info += "Addon Build: " + sys_info['addon_support_license'] + "\n"
|
||||
user_info += "OS: " + sys_info['operating_system'] + "\n"
|
||||
user_info += "GPU: " + sys_info['gpu'] + "\n"
|
||||
user_info += "CPU: " + sys_info['cpu'] + "\n"
|
||||
@@ -1383,8 +1372,7 @@ class FlipFluidOpenPreferences(bpy.types.Operator):
|
||||
bl_label = "FLIP Fluids Preferences"
|
||||
bl_description = ("Open the FLIP Fluids addon preferences menu")
|
||||
|
||||
view_mode = StringProperty(default="NONE")
|
||||
exec(vcu.convert_attribute_to_28("view_mode"))
|
||||
view_mode: StringProperty(default="NONE")
|
||||
|
||||
|
||||
def execute(self, context):
|
||||
@@ -1402,12 +1390,8 @@ class FlipFluidOpenPreferences(bpy.types.Operator):
|
||||
if self.view_mode in valid_view_modes:
|
||||
prefs = vcu.get_addon_preferences()
|
||||
prefs.preferences_menu_view_mode = self.view_mode
|
||||
|
||||
if vcu.is_blender_42():
|
||||
module_name = base_package
|
||||
else:
|
||||
module_name = installation_utils.get_module_name()
|
||||
bpy.ops.preferences.addon_show(module=module_name)
|
||||
|
||||
bpy.ops.preferences.addon_show(module=base_package)
|
||||
return {'FINISHED'}
|
||||
|
||||
|
||||
@@ -1435,9 +1419,7 @@ class FLIPFLUIDS_MT_help_menu(bpy.types.Menu):
|
||||
def draw(self, context):
|
||||
self.layout.operator("flip_fluid_operators.report_bug_prefill", icon="URL")
|
||||
self.layout.operator("flip_fluid_operators.copy_system_info", icon="COPYDOWN")
|
||||
|
||||
if vcu.is_blender_28():
|
||||
self.layout.operator("flip_fluid_operators.open_preferences", icon="PREFERENCES").view_mode = 'NONE'
|
||||
self.layout.operator("flip_fluid_operators.open_preferences", icon="PREFERENCES").view_mode = 'NONE'
|
||||
|
||||
|
||||
def draw_flip_fluids_help_menu(self, context):
|
||||
|
||||
@@ -243,8 +243,7 @@ class FlipFluidPresetCreateNewPresetEnableAll(bpy.types.Operator):
|
||||
bl_label = "Enable All"
|
||||
bl_description = "Enable all preset attributes"
|
||||
|
||||
collection_id = StringProperty(default="")
|
||||
exec(vcu.convert_attribute_to_28("collection_id"))
|
||||
collection_id: StringProperty(default="")
|
||||
|
||||
|
||||
@classmethod
|
||||
@@ -271,8 +270,7 @@ class FlipFluidPresetCreateNewPresetDisableAll(bpy.types.Operator):
|
||||
bl_label = "Disable All"
|
||||
bl_description = "Disable all preset attributes"
|
||||
|
||||
collection_id = StringProperty(default="")
|
||||
exec(vcu.convert_attribute_to_28("collection_id"))
|
||||
collection_id: StringProperty(default="")
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
@@ -299,8 +297,7 @@ class FlipFluidPresetCreateNewPresetEnableAuto(bpy.types.Operator):
|
||||
bl_description = ("Automatically enable/disable preset attributes by" +
|
||||
" comparing to system default settings")
|
||||
|
||||
collection_id = StringProperty(default="")
|
||||
exec(vcu.convert_attribute_to_28("collection_id"))
|
||||
collection_id: StringProperty(default="")
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
@@ -936,8 +933,7 @@ class FlipFluidPresetDisplayInfo(bpy.types.Operator):
|
||||
bl_label = "Preset Info"
|
||||
bl_description = "Display preset information"
|
||||
|
||||
identifier = StringProperty(default="")
|
||||
exec(vcu.convert_attribute_to_28("identifier"))
|
||||
identifier: StringProperty(default="")
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
@@ -1245,12 +1241,11 @@ class SelectPresetPackageZipFile(bpy.types.Operator, ImportHelper):
|
||||
bl_label = "Select Package Zipfile"
|
||||
|
||||
filename_ext = "*.zip"
|
||||
filter_glob = StringProperty(
|
||||
filter_glob: StringProperty(
|
||||
default="*.zip",
|
||||
options={'HIDDEN'},
|
||||
maxlen=255,
|
||||
)
|
||||
exec(vcu.convert_attribute_to_28("filter_glob"))
|
||||
|
||||
|
||||
def execute(self, context):
|
||||
@@ -1691,8 +1686,7 @@ class FlipFluidPresetRemovePresetFromStack(bpy.types.Operator):
|
||||
bl_label = "Remove From Preset Stack"
|
||||
bl_description = "Remove from preset stack"
|
||||
|
||||
stack_index = IntProperty(default=-1)
|
||||
exec(vcu.convert_attribute_to_28("stack_index"))
|
||||
stack_index: IntProperty(default=-1)
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
@@ -1714,8 +1708,7 @@ class FlipFluidPresetMovePresetUpInStack(bpy.types.Operator):
|
||||
bl_label = "Move Up"
|
||||
bl_description = "Move preset up in the stack"
|
||||
|
||||
stack_index = IntProperty(default=-1)
|
||||
exec(vcu.convert_attribute_to_28("stack_index"))
|
||||
stack_index: IntProperty(default=-1)
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
@@ -1737,8 +1730,7 @@ class FlipFluidPresetMovePresetDownInStack(bpy.types.Operator):
|
||||
bl_label = "Move Down"
|
||||
bl_description = "Move preset down in the stack"
|
||||
|
||||
stack_index = IntProperty(default=-1)
|
||||
exec(vcu.convert_attribute_to_28("stack_index"))
|
||||
stack_index: IntProperty(default=-1)
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
@@ -1760,8 +1752,7 @@ class FlipFluidPresetApplyAndRemoveFromStack(bpy.types.Operator):
|
||||
bl_label = "Apply"
|
||||
bl_description = "Apply preset and remove from the stack"
|
||||
|
||||
stack_index = IntProperty(default=-1)
|
||||
exec(vcu.convert_attribute_to_28("stack_index"))
|
||||
stack_index: IntProperty(default=-1)
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
@@ -1804,8 +1795,7 @@ class FlipFluidPresetEditPresetEnableAll(bpy.types.Operator):
|
||||
bl_label = "Enable All"
|
||||
bl_description = "Enable all preset attributes"
|
||||
|
||||
collection_id = StringProperty(default="")
|
||||
exec(vcu.convert_attribute_to_28("collection_id"))
|
||||
collection_id: StringProperty(default="")
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
@@ -1831,8 +1821,7 @@ class FlipFluidPresetEditPresetDisableAll(bpy.types.Operator):
|
||||
bl_label = "Disable All"
|
||||
bl_description = "Disable all preset attributes"
|
||||
|
||||
collection_id = StringProperty(default="")
|
||||
exec(vcu.convert_attribute_to_28("collection_id"))
|
||||
collection_id: StringProperty(default="")
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
|
||||
Reference in New Issue
Block a user