First new particle code:
-Many things not yet working properly :) -Experimental new (hopefully more logical) categorization of buttons, feedback on this is very welcome. -Separate render & draw types, for example now there is actually a render option "halo" instead of all the different point draw types. -Particles get recalculated only from buttons that actually change something that has to be recalculated, for example changing visualization doesn't reset particles any more. -Boid physics buttons are still missing as I'm currently redoing the whole boids code. -Point caching is still very wip, so baking is not possible for example, but I added a few cache baking flags for rna that were/will be needed for particle buttons logic.
This commit is contained in:
parent
8cea65a323
commit
880c43ad5a
|
@ -1,25 +1,589 @@
|
|||
|
||||
import bpy
|
||||
|
||||
def particle_panel_enabled(psys):
|
||||
return psys.point_cache.baked==False and psys.editable==False
|
||||
|
||||
def particle_panel_poll(context):
|
||||
psys = context.particle_system
|
||||
type = psys.settings.type
|
||||
return psys != None and (type=='EMITTER' or type=='REACTOR'or type=='HAIR')
|
||||
|
||||
class ParticleButtonsPanel(bpy.types.Panel):
|
||||
__space_type__ = "BUTTONS_WINDOW"
|
||||
__region_type__ = "WINDOW"
|
||||
__context__ = "particle"
|
||||
|
||||
def poll(self, context):
|
||||
return (context.particle_system != None)
|
||||
psys = context.particle_system
|
||||
type = psys.settings.type
|
||||
return psys != None and (type=='EMITTER' or type=='REACTOR'or type=='HAIR')
|
||||
|
||||
class PARTICLE_PT_particles(ParticleButtonsPanel):
|
||||
__idname__= "PARTICLE_PT_particles"
|
||||
__label__ = "Particles"
|
||||
__label__ = "ParticleSystem"
|
||||
|
||||
def poll(self, context):
|
||||
return (context.particle_system != None)
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
||||
psys = context.particle_system
|
||||
part = psys.settings
|
||||
|
||||
#row = layout.row()
|
||||
#row.itemL(text="Particle system datablock")
|
||||
#row.itemL(text="Viewport")
|
||||
#row.itemL(text="Render")
|
||||
|
||||
type = psys.settings.type
|
||||
|
||||
if(type!='EMITTER' and type!='REACTOR' and type!='HAIR'):
|
||||
layout.itemL(text="No settings for fluid particles")
|
||||
return
|
||||
|
||||
row = layout.row()
|
||||
row.enabled = particle_panel_enabled(psys)
|
||||
row.itemR(part, "type")
|
||||
row.itemR(psys, "seed")
|
||||
|
||||
row = layout.row()
|
||||
if part.type=='HAIR':
|
||||
if psys.editable==True:
|
||||
row.itemO("PARTICLE_OT_editable_set", text="Free Edit")
|
||||
else:
|
||||
row.itemO("PARTICLE_OT_editable_set", text="Make Editable")
|
||||
subrow = row.row()
|
||||
subrow.enabled = particle_panel_enabled(psys)
|
||||
subrow.itemR(part, "hair_step")
|
||||
elif part.type=='REACTOR':
|
||||
row.itemR(psys, "reactor_target_object")
|
||||
row.itemR(psys, "reactor_target_particle_system", text="Particle System")
|
||||
|
||||
class PARTICLE_PT_emission(ParticleButtonsPanel):
|
||||
__idname__= "PARTICLE_PT_emission"
|
||||
__label__ = "Emission"
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
||||
psys = context.particle_system
|
||||
part = psys.settings
|
||||
|
||||
layout.enabled = particle_panel_enabled(psys)
|
||||
|
||||
row = layout.row()
|
||||
#col.itemL(text="TODO: Rate instead of amount")
|
||||
row.itemR(part, "amount")
|
||||
row.itemL(text="")
|
||||
|
||||
split = layout.split()
|
||||
|
||||
col = split.column(align=True)
|
||||
col.itemR(part, "start")
|
||||
col.itemR(part, "end")
|
||||
|
||||
col = split.column(align=True)
|
||||
col.itemR(part, "lifetime")
|
||||
col.itemR(part, "random_lifetime", slider=True)
|
||||
|
||||
class PARTICLE_PT_cache(ParticleButtonsPanel):
|
||||
__idname__= "PARTICLE_PT_cache"
|
||||
__label__ = "Cache"
|
||||
|
||||
def poll(self, context):
|
||||
psys = context.particle_system
|
||||
type = psys.settings.type
|
||||
return psys != None and (type=='EMITTER' or type== 'REACTOR')
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
||||
psys = context.particle_system
|
||||
part = psys.settings
|
||||
cache = psys.point_cache
|
||||
|
||||
#if cache.baked==True:
|
||||
#layout.itemO("PARTICLE_OT_free_bake", text="BAKE")
|
||||
#else:
|
||||
row = layout.row()
|
||||
#row.itemO("PARTICLE_OT_bake", text="BAKE")
|
||||
row.itemR(cache, "start_frame")
|
||||
row.itemR(cache, "end_frame")
|
||||
|
||||
#layout.row().itemL(text="No simulation frames in disk cache.")
|
||||
|
||||
|
||||
class PARTICLE_PT_initial(ParticleButtonsPanel):
|
||||
__idname__= "PARTICLE_PT_initial"
|
||||
__label__ = "Initial values"
|
||||
|
||||
layout.itemR(part, "amount")
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
||||
psys = context.particle_system
|
||||
part = psys.settings
|
||||
|
||||
layout.enabled = particle_panel_enabled(psys)
|
||||
|
||||
layout.row().itemL(text="Location from:")
|
||||
|
||||
box = layout.box()
|
||||
row = box.row()
|
||||
row.itemR(part, "trand")
|
||||
|
||||
col = row.column()
|
||||
col.row().itemR(part, "emit_from", expand=True)
|
||||
|
||||
if part.emit_from=='FACE' or part.emit_from=='VOLUME':
|
||||
row = box.row()
|
||||
|
||||
if part.distribution!='GRID':
|
||||
row.itemR(part, "even_distribution")
|
||||
else:
|
||||
row.itemL(text="")
|
||||
|
||||
row.itemR(part, "distribution", expand=True)
|
||||
|
||||
row = box.row()
|
||||
|
||||
if part.distribution=='JIT':
|
||||
row.itemR(part, "userjit", text="Particles/Face")
|
||||
row.itemR(part, "jitter_factor", text="Jittering Amount", slider=True)
|
||||
elif part.distribution=='GRID':
|
||||
row.itemR(part, "grid_resolution")
|
||||
|
||||
#layout.row().itemL(text="")
|
||||
|
||||
layout.row().itemL(text="Velocity:")
|
||||
box = layout.box()
|
||||
row = box.row()
|
||||
col = row.column()
|
||||
col.itemR(part, "normal_factor")
|
||||
if part.emit_from=='PARTICLE':
|
||||
col.itemR(part, "particle_factor")
|
||||
else:
|
||||
col.itemR(part, "object_factor", slider=True)
|
||||
col.itemR(part, "random_factor")
|
||||
|
||||
col = row.column(align=True)
|
||||
col.itemL(text="TODO:")
|
||||
col.itemL(text="Object aligned")
|
||||
col.itemL(text="direction: X, Y, Z")
|
||||
|
||||
row = box.row()
|
||||
col = row.column(align=True)
|
||||
col.itemR(part, "tangent_factor")
|
||||
col.itemR(part, "tangent_phase", slider=True)
|
||||
|
||||
col = row.column(align=True)
|
||||
if part.type=='REACTOR':
|
||||
col.itemR(part, "reactor_factor")
|
||||
col.itemR(part, "reaction_shape", slider=True)
|
||||
else:
|
||||
col.itemL(text="")
|
||||
|
||||
layout.row().itemL(text="Rotation:")
|
||||
box = layout.box()
|
||||
box.row().itemR(part, "rotation_dynamic")
|
||||
|
||||
row = box.row()
|
||||
col = row.column(align=True)
|
||||
col.itemR(part, "rotation_mode", text="")
|
||||
col.itemR(part, "random_rotation_factor", slider=True)
|
||||
col = row.column(align=True)
|
||||
col.itemR(part, "phase_factor", slider=True)
|
||||
col.itemR(part, "random_phase_factor", text="Random", slider=True)
|
||||
|
||||
|
||||
layout.row().itemL(text="Angular velocity:")
|
||||
|
||||
box = layout.box()
|
||||
row = box.row()
|
||||
row.itemR(part, "angular_velocity_mode", expand=True)
|
||||
row.itemR(part, "angular_velocity_factor", text="")
|
||||
|
||||
class PARTICLE_PT_physics(ParticleButtonsPanel):
|
||||
__idname__= "PARTICLE_PT_physics"
|
||||
__label__ = "Physics"
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
||||
psys = context.particle_system
|
||||
part = psys.settings
|
||||
|
||||
layout.enabled = layout.enabled = particle_panel_enabled(psys)
|
||||
|
||||
layout.itemR(part, "effector_group")
|
||||
|
||||
layout.itemL(text="General:")
|
||||
box = layout.box()
|
||||
row = box.row()
|
||||
col = row.column(align=True)
|
||||
col.itemR(part, "particle_size")
|
||||
col.itemR(part, "random_size", slider=True)
|
||||
col = row.column(align=True)
|
||||
col.itemR(part, "mass")
|
||||
col.itemR(part, "sizemass", text="Multiply mass with size")
|
||||
|
||||
layout.row().itemL(text="")
|
||||
|
||||
row = layout.row()
|
||||
row.itemL(text="Physics Type:")
|
||||
row.itemR(part, "physics_type", expand=True)
|
||||
|
||||
if part.physics_type != 'NO':
|
||||
box = layout.box()
|
||||
row = box.row()
|
||||
|
||||
if part.physics_type == 'NEWTON':
|
||||
row.itemR(part, "integrator")
|
||||
row = box.row()
|
||||
col = row.column(align=True)
|
||||
col.itemL(text="Forces:")
|
||||
col.itemR(part, "brownian_factor")
|
||||
col.itemR(part, "drag_factor", slider=True)
|
||||
col.itemR(part, "damp_factor", slider=True)
|
||||
|
||||
row.column().itemR(part, "acceleration")
|
||||
elif part.physics_type == 'KEYED':
|
||||
row.itemR(psys, "keyed_first")
|
||||
if psys.keyed_first==True:
|
||||
row.itemR(psys, "timed_keys", text="Key timing")
|
||||
else:
|
||||
row.itemR(part, "keyed_time")
|
||||
|
||||
row = box.row()
|
||||
row.itemL(text="Next key from object:")
|
||||
row.itemR(psys, "keyed_object", text="")
|
||||
row.itemR(psys, "keyed_particle_system")
|
||||
|
||||
if part.physics_type=='NEWTON' or part.physics_type=='BOIDS':
|
||||
row = box.row()
|
||||
row.itemR(part, "size_deflect")
|
||||
row.itemR(part, "die_on_collision")
|
||||
row.itemR(part, "sticky")
|
||||
|
||||
class PARTICLE_PT_render(ParticleButtonsPanel):
|
||||
__idname__= "PARTICLE_PT_render"
|
||||
__label__ = "Render"
|
||||
|
||||
def poll(self, context):
|
||||
return (context.particle_system != None)
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
||||
psys = context.particle_system
|
||||
part = psys.settings
|
||||
|
||||
row = layout.row()
|
||||
row.itemR(part, "material")
|
||||
col = row.column()
|
||||
col.itemR(part, "emitter");
|
||||
col.itemR(part, "parent");
|
||||
col = row.column()
|
||||
col.itemR(part, "unborn");
|
||||
col.itemR(part, "died");
|
||||
|
||||
row = layout.row()
|
||||
row.itemR(part, "ren_as", expand=True)
|
||||
|
||||
row = layout.row(align=True)
|
||||
|
||||
if part.ren_as == 'LINE':
|
||||
row.itemR(part, "line_length_tail")
|
||||
row.itemR(part, "line_length_head")
|
||||
row.itemR(part, "velocity_length")
|
||||
elif part.ren_as == 'PATH':
|
||||
|
||||
if (part.type!='HAIR' and psys.point_cache.baked==False):
|
||||
box = layout.box()
|
||||
box.itemL(text="Baked or keyed particles needed for correct rendering.")
|
||||
return
|
||||
|
||||
row.itemR(part, "hair_bspline")
|
||||
row.itemR(part, "render_step", text="Steps")
|
||||
|
||||
row = layout.row()
|
||||
row.itemR(part, "abs_length")
|
||||
col = row.column(align=True)
|
||||
col.itemR(part, "absolute_length")
|
||||
col.itemR(part, "random_length", slider=True)
|
||||
|
||||
#row = layout.row()
|
||||
#row.itemR(part, "timed_path")
|
||||
#col = row.column(align=True)
|
||||
#col.active = part.timed_path == True
|
||||
#col.itemR(part, "line_length_tail", text="Start")
|
||||
#col.itemR(part, "line_length_head", text="End")
|
||||
|
||||
row = layout.row()
|
||||
col = row.column()
|
||||
col.itemR(part, "render_strand")
|
||||
|
||||
subrow = col.row()
|
||||
subrow.active = part.render_strand == False
|
||||
subrow.itemR(part, "render_adaptive")
|
||||
col = row.column(align=True)
|
||||
subrow = col.row()
|
||||
subrow.active = part.render_adaptive or part.render_strand == True
|
||||
subrow.itemR(part, "adaptive_angle")
|
||||
subrow = col.row()
|
||||
subrow.active = part.render_adaptive == True and part.render_strand == False
|
||||
subrow.itemR(part, "adaptive_pix")
|
||||
|
||||
if part.type=='HAIR' and part.render_strand==True and part.child_type=='FACES':
|
||||
layout.itemR(part, "enable_simplify")
|
||||
if part.enable_simplify==True:
|
||||
box = layout.box()
|
||||
row = box.row()
|
||||
row.itemR(part, "simplify_refsize")
|
||||
row.itemR(part, "simplify_rate")
|
||||
row.itemR(part, "simplify_transition")
|
||||
row = box.row()
|
||||
row.itemR(part, "viewport")
|
||||
subrow = row.row()
|
||||
subrow.active = part.viewport==True
|
||||
subrow.itemR(part, "simplify_viewport")
|
||||
|
||||
|
||||
elif part.ren_as == 'OBJECT':
|
||||
row.itemR(part, "dupli_object")
|
||||
elif part.ren_as == 'GROUP':
|
||||
split = layout.split()
|
||||
col = split.column()
|
||||
row = col.row()
|
||||
row.itemR(part, "whole_group")
|
||||
subcol = row.column()
|
||||
subcol.active = part.whole_group == False
|
||||
subcol.itemR(part, "rand_group")
|
||||
split.column().itemR(part, "dupli_group", text="")
|
||||
elif part.ren_as == 'BILLBOARD':
|
||||
row.itemL(text="Align:")
|
||||
row.itemR(part, "billboard_lock", text="Lock")
|
||||
row = layout.row()
|
||||
row.itemR(part, "billboard_align", expand=True)
|
||||
row = layout.row()
|
||||
row.itemR(part, "billboard_object")
|
||||
|
||||
row = layout.row()
|
||||
col = row.column(align=True)
|
||||
col.itemL(text="Tilt:")
|
||||
col.itemR(part, "billboard_tilt", text="Angle", slider=True)
|
||||
col.itemR(part, "billboard_random_tilt", slider=True)
|
||||
col = row.column()
|
||||
col.itemR(part, "billboard_offset")
|
||||
|
||||
row = layout.row()
|
||||
row.itemR(psys, "billboard_normal_uv")
|
||||
row = layout.row()
|
||||
row.itemR(psys, "billboard_time_index_uv")
|
||||
|
||||
row = layout.row()
|
||||
row.itemL(text="Split uv's:")
|
||||
row.itemR(part, "billboard_uv_split", text="Number of splits")
|
||||
row = layout.row()
|
||||
row.itemR(psys, "billboard_split_uv")
|
||||
row = layout.row()
|
||||
row.itemL(text="Animate:")
|
||||
row.itemR(part, "billboard_animation", expand=True)
|
||||
row.itemL(text="Offset:")
|
||||
row.itemR(part, "billboard_split_offset", expand=True)
|
||||
|
||||
class PARTICLE_PT_draw(ParticleButtonsPanel):
|
||||
__idname__= "PARTICLE_PT_draw"
|
||||
__label__ = "Draw"
|
||||
|
||||
def poll(self, context):
|
||||
return (context.particle_system != None)
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
||||
psys = context.particle_system
|
||||
part = psys.settings
|
||||
|
||||
row = layout.row()
|
||||
row.itemR(part, "draw_as", expand=True)
|
||||
|
||||
if part.draw_as=='NONE' or (part.ren_as=='NONE' and part.draw_as=='RENDER'):
|
||||
return
|
||||
|
||||
path = (part.ren_as=='PATH' and part.draw_as=='RENDER') or part.draw_as=='PATH'
|
||||
|
||||
if path and part.type!='HAIR' and psys.point_cache.baked==False:
|
||||
box = layout.box()
|
||||
box.itemL(text="Baked or keyed particles needed for correct drawing.")
|
||||
return
|
||||
|
||||
row = layout.row()
|
||||
row.itemR(part, "display", slider=True)
|
||||
if part.draw_as!='RENDER' or part.ren_as=='HALO':
|
||||
row.itemR(part, "draw_size")
|
||||
else:
|
||||
row.itemL(text="")
|
||||
|
||||
row = layout.row()
|
||||
col = row.column()
|
||||
col.itemR(part, "show_size")
|
||||
col.itemR(part, "velocity")
|
||||
col.itemR(part, "num")
|
||||
if part.physics_type == 'BOIDS':
|
||||
col.itemR(part, "draw_health")
|
||||
|
||||
col = row.column()
|
||||
if (path):
|
||||
box = col.box()
|
||||
box.itemR(part, "draw_step")
|
||||
else:
|
||||
col.itemR(part, "material_color", text="Use material color")
|
||||
subcol = col.column()
|
||||
subcol.active = part.material_color==False
|
||||
#subcol.itemL(text="color")
|
||||
#subcol.itemL(text="Override material color")
|
||||
|
||||
|
||||
class PARTICLE_PT_children(ParticleButtonsPanel):
|
||||
__idname__= "PARTICLE_PT_children"
|
||||
__label__ = "Children"
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
||||
psys = context.particle_system
|
||||
part = psys.settings
|
||||
|
||||
layout.row().itemR(part, "child_type", expand=True)
|
||||
|
||||
if part.child_type=='NONE':
|
||||
return
|
||||
|
||||
row = layout.row()
|
||||
|
||||
col = row.column(align=True)
|
||||
col.itemR(part, "child_nbr", text="Draw")
|
||||
col.itemR(part, "rendered_child_nbr", text="Render")
|
||||
|
||||
col = row.column(align=True)
|
||||
|
||||
if part.child_type=='FACES':
|
||||
col.itemR(part, "virtual_parents", slider=True)
|
||||
else:
|
||||
col.itemR(part, "child_radius", text="Radius")
|
||||
col.itemR(part, "child_roundness", text="Roundness", slider=True)
|
||||
|
||||
col = row.column(align=True)
|
||||
col.itemR(part, "child_size", text="Size")
|
||||
col.itemR(part, "child_random_size", text="Random")
|
||||
|
||||
layout.row().itemL(text="Effects:")
|
||||
|
||||
row = layout.row()
|
||||
|
||||
col = row.column(align=True)
|
||||
col.itemR(part, "clump_factor", slider=True)
|
||||
col.itemR(part, "clumppow", slider=True)
|
||||
|
||||
col = row.column(align=True)
|
||||
col.itemR(part, "rough_endpoint")
|
||||
col.itemR(part, "rough_end_shape")
|
||||
|
||||
row = layout.row()
|
||||
|
||||
col = row.column(align=True)
|
||||
col.itemR(part, "rough1")
|
||||
col.itemR(part, "rough1_size")
|
||||
|
||||
col = row.column(align=True)
|
||||
col.itemR(part, "rough2")
|
||||
col.itemR(part, "rough2_size")
|
||||
col.itemR(part, "rough2_thres", slider=True)
|
||||
|
||||
layout.row().itemL(text="Kink:")
|
||||
layout.row().itemR(part, "kink", expand=True)
|
||||
|
||||
row = layout.row()
|
||||
row.itemR(part, "kink_amplitude")
|
||||
row.itemR(part, "kink_frequency")
|
||||
row.itemR(part, "kink_shape", slider=True)
|
||||
|
||||
|
||||
|
||||
class PARTICLE_PT_vertexgroups(ParticleButtonsPanel):
|
||||
__idname__= "PARTICLE_PT_vertexgroups"
|
||||
__label__ = "Vertexgroups"
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
||||
psys = context.particle_system
|
||||
part = psys.settings
|
||||
|
||||
layout.itemL(text="Nothing here yet.")
|
||||
|
||||
#row = layout.row()
|
||||
#row.itemL(text="Vertex Group")
|
||||
#row.itemL(text="Negate")
|
||||
|
||||
|
||||
#row = layout.row()
|
||||
#row.itemR(psys, "vertex_group_density")
|
||||
#row.itemR(psys, "vertex_group_density_negate", text="")
|
||||
|
||||
#row = layout.row()
|
||||
#row.itemR(psys, "vertex_group_velocity")
|
||||
#row.itemR(psys, "vertex_group_velocity_negate", text="")
|
||||
|
||||
#row = layout.row()
|
||||
#row.itemR(psys, "vertex_group_length")
|
||||
#row.itemR(psys, "vertex_group_length_negate", text="")
|
||||
|
||||
#row = layout.row()
|
||||
#row.itemR(psys, "vertex_group_clump")
|
||||
#row.itemR(psys, "vertex_group_clump_negate", text="")
|
||||
|
||||
#row = layout.row()
|
||||
#row.itemR(psys, "vertex_group_kink")
|
||||
#row.itemR(psys, "vertex_group_kink_negate", text="")
|
||||
|
||||
#row = layout.row()
|
||||
#row.itemR(psys, "vertex_group_roughness1")
|
||||
#row.itemR(psys, "vertex_group_roughness1_negate", text="")
|
||||
|
||||
#row = layout.row()
|
||||
#row.itemR(psys, "vertex_group_roughness2")
|
||||
#row.itemR(psys, "vertex_group_roughness2_negate", text="")
|
||||
|
||||
#row = layout.row()
|
||||
#row.itemR(psys, "vertex_group_roughness_end")
|
||||
#row.itemR(psys, "vertex_group_roughness_end_negate", text="")
|
||||
|
||||
#row = layout.row()
|
||||
#row.itemR(psys, "vertex_group_size")
|
||||
#row.itemR(psys, "vertex_group_size_negate", text="")
|
||||
|
||||
#row = layout.row()
|
||||
#row.itemR(psys, "vertex_group_tangent")
|
||||
#row.itemR(psys, "vertex_group_tangent_negate", text="")
|
||||
|
||||
#row = layout.row()
|
||||
#row.itemR(psys, "vertex_group_rotation")
|
||||
#row.itemR(psys, "vertex_group_rotation_negate", text="")
|
||||
|
||||
#row = layout.row()
|
||||
#row.itemR(psys, "vertex_group_field")
|
||||
#row.itemR(psys, "vertex_group_field_negate", text="")
|
||||
|
||||
bpy.types.register(PARTICLE_PT_particles)
|
||||
bpy.types.register(PARTICLE_PT_cache)
|
||||
bpy.types.register(PARTICLE_PT_emission)
|
||||
bpy.types.register(PARTICLE_PT_initial)
|
||||
bpy.types.register(PARTICLE_PT_physics)
|
||||
bpy.types.register(PARTICLE_PT_render)
|
||||
bpy.types.register(PARTICLE_PT_draw)
|
||||
bpy.types.register(PARTICLE_PT_children)
|
||||
bpy.types.register(PARTICLE_PT_vertexgroups)
|
||||
|
||||
|
|
|
@ -251,7 +251,7 @@ struct ParticleSystemModifierData *psys_get_modifier(struct Object *ob, struct P
|
|||
|
||||
struct ParticleSettings *psys_new_settings(char *name, struct Main *main);
|
||||
struct ParticleSettings *psys_copy_settings(struct ParticleSettings *part);
|
||||
void psys_flush_settings(struct Scene *scene, struct ParticleSettings *part, int event, int hair_recalc);
|
||||
void psys_flush_particle_settings(struct Scene *scene, struct ParticleSettings *part, int recalc);
|
||||
void make_local_particlesettings(struct ParticleSettings *part);
|
||||
|
||||
struct LinkNode *psys_using_settings(struct Scene *scene, struct ParticleSettings *part, int flush_update);
|
||||
|
|
|
@ -6347,8 +6347,7 @@ static void particleSystemModifier_deformVerts(
|
|||
psmd->dm->getNumFaces(psmd->dm)!=psmd->totdmface){
|
||||
/* in file read dm hasn't really changed but just wasn't saved in file */
|
||||
|
||||
psys->recalc |= PSYS_RECALC_HAIR;
|
||||
psys->recalc |= PSYS_DISTR;
|
||||
psys->recalc |= PSYS_RECALC_RESET;
|
||||
psmd->flag |= eParticleSystemFlag_DM_changed;
|
||||
|
||||
psmd->totdmvert= psmd->dm->getNumVerts(psmd->dm);
|
||||
|
|
|
@ -348,8 +348,17 @@ void free_hair(ParticleSystem *psys, int softbody)
|
|||
}
|
||||
void free_keyed_keys(ParticleSystem *psys)
|
||||
{
|
||||
if(psys->particles && psys->particles->keys)
|
||||
if(psys->particles && psys->particles->keys) {
|
||||
ParticleData *pa;
|
||||
int i, totpart=psys->totpart;
|
||||
|
||||
MEM_freeN(psys->particles->keys);
|
||||
|
||||
for(i=0, pa=psys->particles; i<totpart; i++,pa++){
|
||||
pa->keys = NULL;
|
||||
pa->totkey = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
void free_child_path_cache(ParticleSystem *psys)
|
||||
{
|
||||
|
@ -1739,12 +1748,12 @@ static void do_path_effectors(Scene *scene, Object *ob, ParticleSystem *psys, in
|
|||
|
||||
Normalize(force);
|
||||
|
||||
VECADDFAC(ca->co, (ca-1)->co, force, *length);
|
||||
|
||||
if(k < steps) {
|
||||
VecSubf(vec, (ca+1)->co, ca->co);
|
||||
*length = VecLength(vec);
|
||||
}
|
||||
|
||||
VECADDFAC(ca->co, (ca-1)->co, force, *length);
|
||||
}
|
||||
static int check_path_length(int k, ParticleCacheKey *keys, ParticleCacheKey *state, float max_length, float *cur_length, float length, float *dvec)
|
||||
{
|
||||
|
@ -3052,42 +3061,22 @@ void make_local_particlesettings(ParticleSettings *part)
|
|||
}
|
||||
}
|
||||
|
||||
/* should be integrated to depgraph signals */
|
||||
void psys_flush_settings(struct Scene *scene, ParticleSettings *part, int event, int hair_recalc)
|
||||
void psys_flush_particle_settings(Scene *scene, ParticleSettings *part, int recalc)
|
||||
{
|
||||
Base *base;
|
||||
Object *ob, *tob;
|
||||
Base *base = scene->base.first;
|
||||
ParticleSystem *psys;
|
||||
int flush;
|
||||
|
||||
/* update all that have same particle settings */
|
||||
for(base = scene->base.first; base; base= base->next) {
|
||||
if(base->object->particlesystem.first) {
|
||||
ob=base->object;
|
||||
flush=0;
|
||||
for(psys=ob->particlesystem.first; psys; psys=psys->next){
|
||||
if(psys->part==part){
|
||||
psys->recalc |= event;
|
||||
if(hair_recalc)
|
||||
psys->recalc |= PSYS_RECALC_HAIR;
|
||||
flush++;
|
||||
}
|
||||
else if(psys->part->type==PART_REACTOR){
|
||||
ParticleSystem *tpsys;
|
||||
tob=psys->target_ob;
|
||||
if(tob==0)
|
||||
tob=ob;
|
||||
tpsys=BLI_findlink(&tob->particlesystem,psys->target_psys-1);
|
||||
|
||||
if(tpsys && tpsys->part==part){
|
||||
psys->recalc |= event;
|
||||
flush++;
|
||||
}
|
||||
}
|
||||
for(base = scene->base.first; base; base = base->next) {
|
||||
flush = 0;
|
||||
for(psys = base->object->particlesystem.first; psys; psys=psys->next) {
|
||||
if(psys->part == part) {
|
||||
psys->recalc |= recalc;
|
||||
flush++;
|
||||
}
|
||||
if(flush)
|
||||
DAG_object_flush_update(scene, ob, OB_RECALC_DATA);
|
||||
}
|
||||
if(flush)
|
||||
DAG_object_flush_update(scene, base->object, OB_RECALC_DATA);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -4173,10 +4173,10 @@ static void psys_update_path_cache(Scene *scene, Object *ob, ParticleSystemModif
|
|||
ParticleEditSettings *pset=&scene->toolsettings->particle;
|
||||
int distr=0,alloc=0;
|
||||
|
||||
if((psys->part->childtype && psys->totchild != get_psys_tot_child(scene, psys)) || psys->recalc&PSYS_ALLOC)
|
||||
if((psys->part->childtype && psys->totchild != get_psys_tot_child(scene, psys)) || psys->recalc&PSYS_RECALC_RESET)
|
||||
alloc=1;
|
||||
|
||||
if(alloc || psys->recalc&PSYS_DISTR || (psys->vgroup[PSYS_VG_DENSITY] && (G.f & G_WEIGHTPAINT)))
|
||||
if(alloc || psys->recalc&PSYS_RECALC_RESET || (psys->vgroup[PSYS_VG_DENSITY] && (G.f & G_WEIGHTPAINT)))
|
||||
distr=1;
|
||||
|
||||
if(distr){
|
||||
|
@ -4194,8 +4194,9 @@ static void psys_update_path_cache(Scene *scene, Object *ob, ParticleSystemModif
|
|||
}
|
||||
}
|
||||
|
||||
if((part->type==PART_HAIR || psys->flag&PSYS_KEYED) && (psys_in_edit_mode(scene, psys)
|
||||
|| (part->type==PART_HAIR || part->draw_as==PART_DRAW_PATH))){
|
||||
if((part->type==PART_HAIR || psys->flag&PSYS_KEYED) && ( psys_in_edit_mode(scene, psys) || (part->type==PART_HAIR
|
||||
|| (part->ren_as == PART_DRAW_PATH && (part->draw_as == PART_DRAW_REND || psys->renderdata))))){
|
||||
|
||||
psys_cache_paths(scene, ob, psys, cfra, 0);
|
||||
|
||||
/* for render, child particle paths are computed on the fly */
|
||||
|
@ -4247,7 +4248,7 @@ static void hair_step(Scene *scene, Object *ob, ParticleSystemModifierData *psmd
|
|||
pa->flag &= ~PARS_NO_DISP;
|
||||
}
|
||||
|
||||
if(psys->recalc & PSYS_DISTR)
|
||||
if(psys->recalc & PSYS_RECALC_RESET)
|
||||
/* need this for changing subsurf levels */
|
||||
psys_calc_dmcache(ob, psmd->dm, psys);
|
||||
|
||||
|
@ -4367,16 +4368,14 @@ void psys_changed_type(ParticleSystem *psys)
|
|||
psys->flag &= ~PSYS_KEYED;
|
||||
|
||||
if(part->type == PART_HAIR) {
|
||||
part->draw_as = PART_DRAW_PATH;
|
||||
part->rotfrom = PART_ROT_IINCR;
|
||||
}
|
||||
else {
|
||||
free_hair(psys, 1);
|
||||
if(ELEM4(part->ren_as, PART_DRAW_NOT, PART_DRAW_PATH, PART_DRAW_OB, PART_DRAW_GR)==0)
|
||||
part->ren_as = PART_DRAW_PATH;
|
||||
|
||||
if(part->draw_as == PART_DRAW_PATH)
|
||||
if(psys->part->phystype != PART_PHYS_KEYED)
|
||||
part->draw_as = PART_DRAW_DOT;
|
||||
if(ELEM3(part->draw_as, PART_DRAW_NOT, PART_DRAW_REND, PART_DRAW_PATH)==0)
|
||||
part->draw_as = PART_DRAW_REND;
|
||||
}
|
||||
else
|
||||
free_hair(psys, 1);
|
||||
|
||||
psys->softflag= 0;
|
||||
|
||||
|
@ -4574,7 +4573,7 @@ static void system_step(Scene *scene, Object *ob, ParticleSystem *psys, Particle
|
|||
init= 1;
|
||||
}
|
||||
|
||||
if(psys->recalc & PSYS_DISTR) {
|
||||
if(psys->recalc & PSYS_RECALC_RESET) {
|
||||
distr= 1;
|
||||
init= 1;
|
||||
}
|
||||
|
@ -4594,6 +4593,8 @@ static void system_step(Scene *scene, Object *ob, ParticleSystem *psys, Particle
|
|||
}
|
||||
|
||||
if(only_children_changed==0) {
|
||||
free_keyed_keys(psys);
|
||||
|
||||
initialize_all_particles(ob, psys, psmd);
|
||||
|
||||
if(alloc)
|
||||
|
@ -4747,8 +4748,8 @@ static void psys_to_softbody(Scene *scene, Object *ob, ParticleSystem *psys)
|
|||
static int hair_needs_recalc(ParticleSystem *psys)
|
||||
{
|
||||
if((psys->flag & PSYS_EDITED)==0 &&
|
||||
((psys->flag & PSYS_HAIR_DONE)==0 || psys->recalc & PSYS_RECALC_HAIR)) {
|
||||
psys->recalc &= ~PSYS_RECALC_HAIR;
|
||||
((psys->flag & PSYS_HAIR_DONE)==0 || psys->recalc & PSYS_RECALC_REDO)) {
|
||||
psys->recalc &= ~PSYS_RECALC_REDO;
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -4778,6 +4779,9 @@ void particle_system_update(Scene *scene, Object *ob, ParticleSystem *psys)
|
|||
if(!psmd->dm)
|
||||
return;
|
||||
|
||||
if(psys->recalc & PSYS_RECALC_TYPE)
|
||||
psys_changed_type(psys);
|
||||
|
||||
/* (re-)create hair */
|
||||
if(psys->part->type==PART_HAIR && hair_needs_recalc(psys)) {
|
||||
float hcfra=0.0f;
|
||||
|
|
|
@ -492,6 +492,8 @@ int BKE_ptcache_object_reset(Object *ob, int mode)
|
|||
else
|
||||
skip = 1;
|
||||
}
|
||||
else if((psys->recalc & PSYS_RECALC_RESET)==0)
|
||||
skip = 1;
|
||||
|
||||
if(skip == 0) {
|
||||
BKE_ptcache_id_from_particles(&pid, ob, psys);
|
||||
|
|
|
@ -8406,7 +8406,7 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
|
|||
|
||||
part->draw_as = PART_DRAW_PATH;
|
||||
part->type = PART_HAIR;
|
||||
psys->recalc |= PSYS_RECALC_HAIR;
|
||||
psys->recalc |= PSYS_RECALC_REDO;
|
||||
|
||||
part->normfac *= fac;
|
||||
part->randfac *= fac;
|
||||
|
@ -8872,6 +8872,7 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
|
|||
Mesh *me;
|
||||
Scene *sce;
|
||||
Tex *tx;
|
||||
ParticleSettings *part;
|
||||
|
||||
for(screen= main->screen.first; screen; screen= screen->id.next) {
|
||||
do_versions_windowmanager_2_50(screen);
|
||||
|
@ -8913,6 +8914,23 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
|
|||
for(me= main->mesh.first; me; me= me->id.next) {
|
||||
me->drawflag= ME_DRAWEDGES|ME_DRAWFACES|ME_DRAWCREASES;
|
||||
}
|
||||
|
||||
/* particle settings conversion */
|
||||
for(part= main->particle.first; part; part= part->id.next) {
|
||||
if(part->draw_as) {
|
||||
if(part->draw_as == PART_DRAW_DOT) {
|
||||
part->ren_as = PART_DRAW_HALO;
|
||||
part->draw_as = PART_DRAW_REND;
|
||||
}
|
||||
else if(part->draw_as <= PART_DRAW_AXIS) {
|
||||
part->ren_as = PART_DRAW_HALO;
|
||||
}
|
||||
else {
|
||||
part->ren_as = part->draw_as;
|
||||
part->draw_as = PART_DRAW_REND;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* TODO: should be moved into one of the version blocks once this branch moves to trunk and we can
|
||||
|
|
|
@ -3759,7 +3759,7 @@ static int set_editable_exec(bContext *C, wmOperator *op)
|
|||
PE_free_particle_edit(psys);
|
||||
|
||||
psys->flag &= ~PSYS_EDITED;
|
||||
psys->recalc |= PSYS_RECALC_HAIR;
|
||||
psys->recalc |= PSYS_RECALC_RESET;
|
||||
|
||||
DAG_object_flush_update(scene, ob, OB_RECALC_DATA);
|
||||
}
|
||||
|
|
|
@ -1274,7 +1274,7 @@ static void wpaint_exit(bContext *C, wmOperator *op)
|
|||
for(psys= ob->particlesystem.first; psys; psys= psys->next) {
|
||||
for(i=0; i<PSYS_TOT_VG; i++) {
|
||||
if(psys->vgroup[i]==ob->actdef) {
|
||||
psys->recalc |= PSYS_RECALC_HAIR;
|
||||
psys->recalc |= PSYS_RECALC_RESET;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3042,7 +3042,11 @@ static void draw_new_particle_system(Scene *scene, View3D *v3d, RegionView3D *rv
|
|||
}
|
||||
|
||||
totpart=psys->totpart;
|
||||
draw_as=part->draw_as;
|
||||
|
||||
if(part->draw_as==PART_DRAW_REND)
|
||||
draw_as = part->ren_as;
|
||||
else
|
||||
draw_as = part->draw_as;
|
||||
|
||||
if(part->flag&PART_GLOB_TIME)
|
||||
cfra=bsystem_time(scene, 0, (float)CFRA, 0.0f);
|
||||
|
@ -3489,7 +3493,6 @@ static void draw_new_particle_system(Scene *scene, View3D *v3d, RegionView3D *rv
|
|||
glColorPointer(3, GL_FLOAT, 0, cdata);
|
||||
}
|
||||
|
||||
|
||||
/* draw created data arrays */
|
||||
switch(draw_as){
|
||||
case PART_DRAW_AXIS:
|
||||
|
|
|
@ -395,6 +395,7 @@ static void view3d_main_area_listener(ARegion *ar, wmNotifier *wmn)
|
|||
case ND_MODIFIER:
|
||||
case ND_CONSTRAINT:
|
||||
case ND_KEYS:
|
||||
case ND_PARTICLE:
|
||||
ED_region_tag_redraw(ar);
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -106,6 +106,7 @@ typedef struct ParticleSettings {
|
|||
/* physics modes */
|
||||
short phystype, rotmode, avemode, reactevent;
|
||||
short draw, draw_as, draw_size, childtype;
|
||||
short ren_as, rt2[3];
|
||||
/* number of path segments, power of 2 except */
|
||||
short draw_step, ren_step;
|
||||
short hair_step, keys_step;
|
||||
|
@ -302,12 +303,12 @@ typedef struct ParticleSystem{ /* note, make sure all (runtime) are NULL's in
|
|||
|
||||
/* part->draw */
|
||||
#define PART_DRAW_VEL 1
|
||||
#define PART_DRAW_ANG 2
|
||||
//#define PART_DRAW_PATH_LEN 2
|
||||
#define PART_DRAW_SIZE 4
|
||||
#define PART_DRAW_EMITTER 8 /* render emitter also */
|
||||
//#define PART_DRAW_KEYS 16 /* not used anywhere */
|
||||
#define PART_DRAW_ADAPT 32
|
||||
#define PART_DRAW_COS 64
|
||||
//#define PART_DRAW_HEALTH 16
|
||||
//#define PART_DRAW_TIMED_PATH 32
|
||||
//#define PART_DRAW_CACHED_PATH 64
|
||||
#define PART_DRAW_BB_LOCK 128
|
||||
#define PART_DRAW_PARENT 256
|
||||
#define PART_DRAW_NUM 512
|
||||
|
@ -341,9 +342,11 @@ typedef struct ParticleSystem{ /* note, make sure all (runtime) are NULL's in
|
|||
#define PART_BB_OFF_LINEAR 1
|
||||
#define PART_BB_OFF_RANDOM 2
|
||||
|
||||
/* part->draw as */
|
||||
/* part->draw_as */
|
||||
/* part->ren_as*/
|
||||
#define PART_DRAW_NOT 0
|
||||
#define PART_DRAW_DOT 1
|
||||
#define PART_DRAW_HALO 1
|
||||
#define PART_DRAW_CIRC 2
|
||||
#define PART_DRAW_CROSS 3
|
||||
#define PART_DRAW_AXIS 4
|
||||
|
@ -352,6 +355,7 @@ typedef struct ParticleSystem{ /* note, make sure all (runtime) are NULL's in
|
|||
#define PART_DRAW_OB 7
|
||||
#define PART_DRAW_GR 8
|
||||
#define PART_DRAW_BB 9
|
||||
#define PART_DRAW_REND 10
|
||||
|
||||
/* part->integrator */
|
||||
#define PART_INT_EULER 0
|
||||
|
@ -382,11 +386,10 @@ typedef struct ParticleSystem{ /* note, make sure all (runtime) are NULL's in
|
|||
#define PART_CHILD_FACES 2
|
||||
|
||||
/* psys->recalc */
|
||||
#define PSYS_INIT 1
|
||||
#define PSYS_DISTR 2
|
||||
#define PSYS_ALLOC 4
|
||||
#define PSYS_TYPE 8
|
||||
#define PSYS_RECALC_HAIR 16
|
||||
#define PSYS_RECALC_REDO 1 /* only do pathcache etc */
|
||||
#define PSYS_RECALC_RESET 2 /* reset everything including pointcache */
|
||||
#define PSYS_RECALC_TYPE 4 /* handle system type change */
|
||||
#define PSYS_RECALC_CHILD 16 /* only child settings changed */
|
||||
|
||||
/* psys->flag */
|
||||
#define PSYS_CURRENT 1
|
||||
|
|
|
@ -53,6 +53,13 @@ static void rna_def_pointcache(BlenderRNA *brna)
|
|||
RNA_def_property_int_sdna(prop, NULL, "endframe");
|
||||
RNA_def_property_range(prop, 1, 300000);
|
||||
RNA_def_property_ui_text(prop, "End", "Frame on which the simulation stops.");
|
||||
|
||||
/* flags */
|
||||
prop= RNA_def_property(srna, "baked", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_sdna(prop, NULL, "flag", PTCACHE_BAKED);
|
||||
|
||||
prop= RNA_def_property(srna, "baking", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_sdna(prop, NULL, "flag", PTCACHE_BAKING);
|
||||
}
|
||||
|
||||
static void rna_def_collision(BlenderRNA *brna)
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1459,7 +1459,7 @@ static int render_new_particle_system(Render *re, ObjectRen *obr, ParticleSystem
|
|||
if(part==NULL || pars==NULL || !psys_check_enabled(ob, psys))
|
||||
return 0;
|
||||
|
||||
if(part->draw_as==PART_DRAW_OB || part->draw_as==PART_DRAW_GR || part->draw_as==PART_DRAW_NOT)
|
||||
if(part->ren_as==PART_DRAW_OB || part->ren_as==PART_DRAW_GR || part->ren_as==PART_DRAW_NOT)
|
||||
return 1;
|
||||
|
||||
/* 2. start initialising things */
|
||||
|
@ -1522,7 +1522,7 @@ static int render_new_particle_system(Render *re, ObjectRen *obr, ParticleSystem
|
|||
sd.mcol = MEM_callocN(sd.totcol * sizeof(MCol), "particle_mcols");
|
||||
|
||||
/* 2.2 setup billboards */
|
||||
if(part->draw_as == PART_DRAW_BB) {
|
||||
if(part->ren_as == PART_DRAW_BB) {
|
||||
int first_uv = CustomData_get_layer_index(&psmd->dm->faceData, CD_MTFACE);
|
||||
|
||||
bb.uv[0] = CustomData_get_named_layer_index(&psmd->dm->faceData, CD_MTFACE, psys->bb_uvname[0]);
|
||||
|
@ -1577,7 +1577,7 @@ static int render_new_particle_system(Render *re, ObjectRen *obr, ParticleSystem
|
|||
Mat3Transp(nmat);
|
||||
|
||||
/* 2.6 setup strand rendering */
|
||||
if(part->draw_as == PART_DRAW_PATH && psys->pathcache){
|
||||
if(part->ren_as == PART_DRAW_PATH && psys->pathcache){
|
||||
path_nbr=(int)pow(2.0,(double) part->ren_step);
|
||||
|
||||
if(path_nbr) {
|
||||
|
@ -1884,10 +1884,10 @@ static int render_new_particle_system(Render *re, ObjectRen *obr, ParticleSystem
|
|||
continue;
|
||||
|
||||
VECCOPY(loc,state.co);
|
||||
if(part->draw_as!=PART_DRAW_BB)
|
||||
if(part->ren_as!=PART_DRAW_BB)
|
||||
MTC_Mat4MulVecfl(re->viewmat,loc);
|
||||
|
||||
switch(part->draw_as) {
|
||||
switch(part->ren_as) {
|
||||
case PART_DRAW_LINE:
|
||||
sd.line = 1;
|
||||
sd.time = 0.0f;
|
||||
|
@ -4379,7 +4379,7 @@ static int allow_render_dupli_instance(Render *re, DupliObject *dob, Object *obd
|
|||
}
|
||||
|
||||
for(psys=obd->particlesystem.first; psys; psys=psys->next)
|
||||
if(!ELEM5(psys->part->draw_as, PART_DRAW_BB, PART_DRAW_LINE, PART_DRAW_PATH, PART_DRAW_OB, PART_DRAW_GR))
|
||||
if(!ELEM5(psys->part->ren_as, PART_DRAW_BB, PART_DRAW_LINE, PART_DRAW_PATH, PART_DRAW_OB, PART_DRAW_GR))
|
||||
return 0;
|
||||
|
||||
/* don't allow lamp, animated duplis, or radio render */
|
||||
|
@ -4402,7 +4402,7 @@ static void dupli_render_particle_set(Render *re, Object *ob, int timeoffset, in
|
|||
|
||||
if(ob->transflag & OB_DUPLIPARTS) {
|
||||
for(psys=ob->particlesystem.first; psys; psys=psys->next) {
|
||||
if(ELEM(psys->part->draw_as, PART_DRAW_OB, PART_DRAW_GR)) {
|
||||
if(ELEM(psys->part->ren_as, PART_DRAW_OB, PART_DRAW_GR)) {
|
||||
if(enable)
|
||||
psys_render_set(ob, psys, re->viewmat, re->winmat, re->winx, re->winy, timeoffset);
|
||||
else
|
||||
|
|
|
@ -197,6 +197,7 @@ typedef struct wmNotifier {
|
|||
#define ND_KEYS (24<<16)
|
||||
#define ND_GEOM_DATA (25<<16)
|
||||
#define ND_CONSTRAINT (26<<16)
|
||||
#define ND_PARTICLE (27<<16)
|
||||
|
||||
/* NC_MATERIAL Material */
|
||||
#define ND_SHADING (30<<16)
|
||||
|
|
Loading…
Reference in New Issue