Skip to content

Commit 3c6c0d4

Browse files
authored
Merge pull request #129 from MaximeHerpin/release-2.8.1
Release 2.8.1
2 parents eaf2cba + 6bc65dc commit 3c6c0d4

File tree

5 files changed

+229
-97
lines changed

5 files changed

+229
-97
lines changed

__init__.py

Lines changed: 74 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@
3535
bl_info = {
3636
"name": "Modular trees",
3737
"author": "Herpin Maxime, Jake Dube",
38-
"version": (2, 8, 0),
38+
"version": (2, 8, 1),
3939
"blender": (2, 77, 0),
4040
"location": "View3D > Tools > Tree > Make Tree",
4141
"description": "Generates an organic tree with correctly modeled branching.",
@@ -256,6 +256,13 @@ def draw(self, context):
256256
box.prop_search(mtree_props, "obstacle", scene, "objects")
257257
if bpy.data.objects.get(mtree_props.obstacle) is not None:
258258
box.prop(mtree_props, 'obstacle_strength')
259+
col1 = box.column()
260+
col1.prop(mtree_props, 'use_force_field')
261+
if mtree_props.use_force_field:
262+
col1.prop(mtree_props, 'fields_point_strength')
263+
col1.prop(mtree_props, 'fields_point_strength')
264+
col1.prop(mtree_props, 'fields_strength_limit')
265+
col1.prop(mtree_props, 'fields_radius_factor')
259266

260267

261268
class AdvancedSettingsPanel(Panel):
@@ -270,6 +277,7 @@ class AdvancedSettingsPanel(Panel):
270277
def draw(self, context):
271278
mtree_props = context.scene.mtree_props
272279
layout = self.layout
280+
scene = context.scene
273281

274282
box = layout.box()
275283
box.prop(mtree_props, 'mat')
@@ -284,6 +292,8 @@ def draw(self, context):
284292
if mtree_props.particle:
285293
box.prop(mtree_props, 'number')
286294
box.prop(mtree_props, 'display')
295+
box.prop_search(mtree_props, "twig_particle", scene, "objects")
296+
box.prop(mtree_props, 'particle_size')
287297

288298

289299
class WindAnimationPanel(Panel):
@@ -325,6 +335,7 @@ class MakeTwigPanel(Panel):
325335
def draw(self, context):
326336
mtree_props = context.scene.mtree_props
327337
layout = self.layout
338+
scene = context.scene
328339

329340
row = layout.row()
330341
row.scale_y = 1.5
@@ -337,11 +348,12 @@ def draw(self, context):
337348
box = layout.box()
338349
box.label("Twig Options")
339350
box.prop(mtree_props, "leaf_size")
351+
box.prop_search(mtree_props, "leaf_object", scene, "objects")
340352
box.prop(mtree_props, "leaf_chance")
353+
box.prop(mtree_props, "leaf_weight")
341354
box.prop(mtree_props, "TwigSeedProp")
342355
box.prop(mtree_props, "twig_iteration")
343356
box.prop_search(mtree_props, "twig_bark_material", bpy.data, "materials")
344-
box.prop_search(mtree_props, "twig_leaf_material", bpy.data, "materials")
345357

346358

347359
class MakeTreePresetsPanel(Panel):
@@ -541,10 +553,10 @@ class ModularTreePropertyGroup(PropertyGroup):
541553
description="randomize the rotation of branches angle")
542554

543555
branch_min_radius = FloatProperty(
544-
name = "Branches minimum radius",
545-
default = .04,
546-
min = 0,
547-
description = "radius at which a branch breaks for being to small")
556+
name="Branches minimum radius",
557+
default=.04,
558+
min=0,
559+
description="radius at which a branch breaks for being to small")
548560

549561
particle = BoolProperty(
550562
name="Configure Particle System",
@@ -558,6 +570,15 @@ class ModularTreePropertyGroup(PropertyGroup):
558570
name="Particles in Viewport",
559571
default=500)
560572

573+
twig_particle = StringProperty(
574+
name='twig or leaf object',
575+
default='')
576+
577+
particle_size = FloatProperty(
578+
name="twig/leaf size",
579+
min=0,
580+
default=1.5)
581+
561582
break_chance = FloatProperty(
562583
name="Break Chance",
563584
default=0.02)
@@ -575,8 +596,11 @@ class ModularTreePropertyGroup(PropertyGroup):
575596
min=0,
576597
default=.5)
577598

578-
twig_leaf_material = StringProperty(
579-
name="Leaf Material")
599+
leaf_weight = FloatProperty(
600+
name="Leaf Weight",
601+
min=0,
602+
max=1,
603+
default=.2)
580604

581605
twig_bark_material = StringProperty(
582606
name="Twig Bark Material")
@@ -591,6 +615,11 @@ class ModularTreePropertyGroup(PropertyGroup):
591615
soft_max=10,
592616
default=9)
593617

618+
leaf_object = StringProperty(
619+
name="leaf object",
620+
default="",
621+
description="The object used for the leaves. \nThe leaf must be on Y axis and the rotation must be applied")
622+
594623
tree_number = IntProperty(
595624
name="Tree Number",
596625
min=2,
@@ -630,21 +659,48 @@ class ModularTreePropertyGroup(PropertyGroup):
630659
description="The distance from the terrain that the wind effect is at its highest")
631660

632661
use_grease_pencil = BoolProperty(
633-
name = "Use Grease Pencil",
634-
default = False)
662+
name="Use Grease Pencil",
663+
default=False)
635664

636665
smooth_stroke = FloatProperty(
637-
name = "Smooth Iterations",
638-
min = 0.0,
639-
max = 1,
640-
default = .2)
666+
name="Smooth Iterations",
667+
min=0.0,
668+
max=1,
669+
default=.2)
641670

642671
stroke_step_size = FloatProperty(
643-
name = "Step Size",
644-
min = 0,
645-
default = .5)
672+
name="Step Size",
673+
min=0,
674+
default=.5)
675+
676+
use_force_field = BoolProperty(
677+
name="Use Force Field",
678+
default=False)
679+
680+
fields_point_strength = FloatProperty(
681+
name="Point Force Strength",
682+
min=0.0,
683+
default=1)
684+
685+
fields_wind_strength = FloatProperty(
686+
name="Wind Force Strength",
687+
min=0.0,
688+
default=1)
689+
690+
fields_strength_limit = FloatProperty(
691+
name="Strength Limit",
692+
min=0,
693+
default=10,
694+
description="limits the force so that it can't approaches infinity")
695+
696+
fields_radius_factor = FloatProperty(
697+
name="Radius Factor",
698+
min=0,
699+
max=1,
700+
default=.5,
701+
description="How the branch radius affects the force strength. "
702+
"\n0 means big branches are as affected as small ones.")
646703

647-
648704
clear_mods = BoolProperty(name="Clear Modifiers", default=True)
649705

650706
wind_strength = FloatProperty(name="Wind Strength", default=1)

generator_operators.py

Lines changed: 24 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -101,19 +101,19 @@ class MakeTwigOperator(Operator):
101101
bl_options = {"REGISTER", "UNDO"}
102102

103103
def execute(self, context):
104+
scene = context.scene
105+
mtree_props = scene.mtree_props
106+
104107
# this block saves everything and cancels operator if something goes wrong
105108
display_logo()
106-
messages, message_lvls, status = save_everything()
109+
messages, message_lvls, status = save_everything(twig=True)
107110
for i, message in enumerate(messages):
108111
self.report({message_lvls[i]}, message)
109112
return {status}
110113

111-
scene = context.scene
112-
mtree_props = scene.mtree_props
113114

114115
seed(mtree_props.TwigSeedProp)
115116
save_preserve_trunk = mtree_props.preserve_trunk
116-
save_trunk_split_angle = mtree_props.split_angle # This variable is never used! Should it be?
117117
save_randomangle = mtree_props.randomangle
118118
save_trunk_variation = mtree_props.trunk_variation
119119
save_radius = mtree_props.radius
@@ -146,6 +146,7 @@ def execute(self, context):
146146
save_number = mtree_props.number
147147
save_display = mtree_props.display
148148
save_break_chance = mtree_props.break_chance
149+
save_use_grease_pencil = mtree_props.use_grease_pencil
149150

150151
mtree_props.preserve_trunk = False
151152
mtree_props.trunk_split_angle = 0
@@ -180,6 +181,7 @@ def execute(self, context):
180181
mtree_props.number = 0
181182
mtree_props.display = 0
182183
mtree_props.break_chance = 0
184+
mtree_props.use_grease_pencil = False
183185

184186
if bpy.data.materials.get("twig bark") is None:
185187
build_bark_material("twig bark")
@@ -191,16 +193,23 @@ def execute(self, context):
191193

192194
twig = bpy.context.active_object
193195
twig.name = 'twig'
196+
leafs = []
194197
twig.active_material = bpy.data.materials.get(mtree_props.twig_bark_material)
195-
for (position, direction, rotation) in twig_leafs:
196-
for i in range(randint(1, 3)):
197-
if random() < mtree_props.leaf_chance:
198-
add_leaf(position + direction * .5 * random(), direction + Vector((random(), random(), random())),
199-
rotation + random() * 5, (1 + random()) * mtree_props.leaf_size)
200-
bpy.context.active_object.active_material = bpy.data.materials.get(mtree_props.twig_leaf_material)
201-
twig.select = True
202-
scene.objects.active = twig
203-
198+
for (position, direction) in twig_leafs:
199+
if random() < mtree_props.leaf_chance:
200+
for i in range(randint(1, 3)):
201+
if random() < mtree_props.leaf_chance:
202+
add_leaf(position+direction*random(), direction+Vector((random()-.5, random()-.5, 0))*.2, mtree_props.leaf_size*(2+random()), mtree_props.leaf_object, mtree_props.leaf_weight)
203+
leafs.append(bpy.context.active_object)
204+
if not bpy.context.active_object.data.materials.items():
205+
mat = bpy.data.materials.get("leaf_mat")
206+
if mat is None:
207+
mat = bpy.data.materials.new(name="leaf_mat")
208+
bpy.context.active_object.active_material = mat
209+
twig.select = True
210+
scene.objects.active = twig
211+
for i in leafs:
212+
i.select = True
204213
bpy.ops.object.join()
205214
bpy.ops.transform.rotate(value=-1.5708, axis=(1, 0, 0))
206215
bpy.ops.transform.resize(value=(0.25, 0.25, 0.25))
@@ -240,6 +249,7 @@ def execute(self, context):
240249
mtree_props.number = save_number
241250
mtree_props.display = save_display
242251
mtree_props.break_chance = save_break_chance
252+
mtree_props.use_grease_pencil = save_use_grease_pencil
243253

244254
return {'FINISHED'}
245255

@@ -315,7 +325,7 @@ class UpdateTwigOperator(Operator):
315325
def execute(self, context):
316326
# this block saves everything and cancels operator if something goes wrong
317327
display_logo()
318-
messages, message_lvls, status = save_everything()
328+
messages, message_lvls, status = save_everything(twig=True)
319329
for i, message in enumerate(messages):
320330
self.report({message_lvls[i]}, message)
321331
return {status}
@@ -332,7 +342,6 @@ def execute(self, context):
332342
return {'CANCELLED'}
333343

334344
if is_tree_prop:
335-
pos = obj.location # this is never used...should it be?
336345
scale = obj.scale
337346
rot = obj.rotation_euler
338347
bpy.ops.mod_tree.add_twig()

particle_configurator.py

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,10 @@
1717
# along with Modular Tree. If not, see <http://www.gnu.org/licenses/>.
1818
# ##### END GPL LICENSE BLOCK #####
1919

20+
import bpy
2021

21-
def create_system(ob, number, display, vertex_group):
22+
23+
def create_system(ob, number, display, vertex_group, object_name, size):
2224
""" Creates a particle system
2325
2426
Args:
@@ -31,7 +33,7 @@ def create_system(ob, number, display, vertex_group):
3133
g = vertex_group
3234

3335
# customize the particle system
34-
leaf = ob.modifiers.new("psys name", 'PARTICLE_SYSTEM')
36+
leaf = ob.modifiers.new("leafs", 'PARTICLE_SYSTEM')
3537
part = ob.particle_systems[0]
3638
part.vertex_group_density = g.name
3739
settings = leaf.particle_system.settings
@@ -46,7 +48,9 @@ def create_system(ob, number, display, vertex_group):
4648
settings.use_rotations = True
4749
settings.phase_factor = 1
4850
settings.phase_factor_random = 1
49-
settings.particle_size = 0.015
51+
settings.particle_size = 0.1 * size
5052
settings.size_random = 0.25
5153
settings.brownian_factor = 1
5254
settings.render_type = "OBJECT"
55+
if bpy.data.objects.get(object_name) is not None:
56+
settings.dupli_object = bpy.context.scene.objects[object_name]

prep_manager.py

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -85,11 +85,21 @@ def always_save():
8585
return "SUCCESS", None
8686

8787

88-
def save_everything():
89-
# save files
90-
save_return, bad_file = always_save()
88+
def save_everything(twig=False):
9189
messages = []
9290
message_lvls = []
91+
scene = bpy.context.scene
92+
mtree_props = scene.mtree_props
93+
94+
if twig:
95+
# do illegal settings checks here
96+
if mtree_props.leaf_object not in scene.objects:
97+
messages += ["Requires a valid leaf object! Add one with the object selector in the twig UI."]
98+
message_lvls += ['ERROR']
99+
return messages, message_lvls, 'CANCELLED'
100+
101+
# save files
102+
save_return, bad_file = always_save()
93103
if save_return == "BLEND_ERROR":
94104
messages += ["Save file or disable always save " + "in user prefs."]
95105
message_lvls += ['ERROR']

0 commit comments

Comments
 (0)