b047bbdcfec7606c5988b0839148ecb5c516b233
[blender.git] / release / scripts / startup / bl_ui / properties_data_modifier.py
1 # ##### BEGIN GPL LICENSE BLOCK #####
2 #
3 #  This program is free software; you can redistribute it and/or
4 #  modify it under the terms of the GNU General Public License
5 #  as published by the Free Software Foundation; either version 2
6 #  of the License, or (at your option) any later version.
7 #
8 #  This program is distributed in the hope that it will be useful,
9 #  but WITHOUT ANY WARRANTY; without even the implied warranty of
10 #  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11 #  GNU General Public License for more details.
12 #
13 #  You should have received a copy of the GNU General Public License
14 #  along with this program; if not, write to the Free Software Foundation,
15 #  Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
16 #
17 # ##### END GPL LICENSE BLOCK #####
18
19 # <pep8 compliant>
20 import bpy
21 from bpy.types import Panel
22 from bpy.app.translations import pgettext_iface as iface_
23
24
25 class ModifierButtonsPanel:
26     bl_space_type = 'PROPERTIES'
27     bl_region_type = 'WINDOW'
28     bl_context = "modifier"
29     bl_options = {'HIDE_HEADER'}
30
31
32 class DATA_PT_modifiers(ModifierButtonsPanel, Panel):
33     bl_label = "Modifiers"
34
35     @classmethod
36     def poll(cls, context):
37         ob = context.object
38         return ob and ob.type != 'GPENCIL'
39
40     def draw(self, context):
41         layout = self.layout
42
43         ob = context.object
44
45         layout.operator_menu_enum("object.modifier_add", "type")
46
47         for md in ob.modifiers:
48             box = layout.template_modifier(md)
49             if box:
50                 # match enum type to our functions, avoids a lookup table.
51                 getattr(self, md.type)(box, ob, md)
52
53     # the mt.type enum is (ab)used for a lookup on function names
54     # ...to avoid lengthy if statements
55     # so each type must have a function here.
56
57     def ARMATURE(self, layout, ob, md):
58         split = layout.split()
59
60         col = split.column()
61         col.label(text="Object:")
62         col.prop(md, "object", text="")
63         col.prop(md, "use_deform_preserve_volume")
64
65         col = split.column()
66         col.label(text="Bind To:")
67         col.prop(md, "use_vertex_groups", text="Vertex Groups")
68         col.prop(md, "use_bone_envelopes", text="Bone Envelopes")
69
70         layout.separator()
71
72         split = layout.split()
73
74         row = split.row(align=True)
75         row.prop_search(md, "vertex_group", ob, "vertex_groups", text="")
76         sub = row.row(align=True)
77         sub.active = bool(md.vertex_group)
78         sub.prop(md, "invert_vertex_group", text="", icon='ARROW_LEFTRIGHT')
79
80         split.prop(md, "use_multi_modifier")
81
82     def ARRAY(self, layout, ob, md):
83         layout.prop(md, "fit_type")
84
85         if md.fit_type == 'FIXED_COUNT':
86             layout.prop(md, "count")
87         elif md.fit_type == 'FIT_LENGTH':
88             layout.prop(md, "fit_length")
89         elif md.fit_type == 'FIT_CURVE':
90             layout.prop(md, "curve")
91
92         layout.separator()
93
94         split = layout.split()
95
96         col = split.column()
97         col.prop(md, "use_constant_offset")
98         sub = col.column()
99         sub.active = md.use_constant_offset
100         sub.prop(md, "constant_offset_displace", text="")
101
102         col.separator()
103
104         col.prop(md, "use_merge_vertices", text="Merge")
105         sub = col.column()
106         sub.active = md.use_merge_vertices
107         sub.prop(md, "use_merge_vertices_cap", text="First Last")
108         sub.prop(md, "merge_threshold", text="Distance")
109
110         col = split.column()
111         col.prop(md, "use_relative_offset")
112         sub = col.column()
113         sub.active = md.use_relative_offset
114         sub.prop(md, "relative_offset_displace", text="")
115
116         col.separator()
117
118         col.prop(md, "use_object_offset")
119         sub = col.column()
120         sub.active = md.use_object_offset
121         sub.prop(md, "offset_object", text="")
122
123         row = layout.row()
124         split = row.split()
125         col = split.column()
126         col.label(text="UVs:")
127         sub = col.column(align=True)
128         sub.prop(md, "offset_u")
129         sub.prop(md, "offset_v")
130         layout.separator()
131
132         layout.prop(md, "start_cap")
133         layout.prop(md, "end_cap")
134
135     def BEVEL(self, layout, ob, md):
136         split = layout.split()
137
138         col = split.column()
139         if md.offset_type == 'PERCENT':
140             col.prop(md, "width_pct")
141         else:
142             col.prop(md, "width")
143         col.prop(md, "segments")
144         col.prop(md, "profile")
145         col.prop(md, "material")
146
147         col = split.column()
148         col.prop(md, "use_only_vertices")
149         col.prop(md, "use_clamp_overlap")
150         col.prop(md, "loop_slide")
151         col.prop(md, "mark_seam")
152         col.prop(md, "mark_sharp")
153         col.prop(md, "harden_normals")
154
155         layout.label(text="Limit Method:")
156         layout.row().prop(md, "limit_method", expand=True)
157         if md.limit_method == 'ANGLE':
158             layout.prop(md, "angle_limit")
159         elif md.limit_method == 'VGROUP':
160             layout.label(text="Vertex Group:")
161             layout.prop_search(md, "vertex_group", ob, "vertex_groups", text="")
162
163         layout.label(text="Width Method:")
164         layout.row().prop(md, "offset_type", expand=True)
165
166         layout.label(text="Set Face Strength Mode")
167         layout.row().prop(md, "face_strength_mode", expand=True)
168
169         layout.label(text="Miter Patterns")
170         layout.row().prop(md, "miter_outer")
171         layout.row().prop(md, "miter_inner")
172         layout.row().prop(md, "spread")
173
174     def BOOLEAN(self, layout, ob, md):
175         split = layout.split()
176
177         col = split.column()
178         col.label(text="Operation:")
179         col.prop(md, "operation", text="")
180
181         col = split.column()
182         col.label(text="Object:")
183         col.prop(md, "object", text="")
184
185         layout.prop(md, "double_threshold")
186
187         if bpy.app.debug:
188             layout.prop(md, "debug_options")
189
190     def BUILD(self, layout, ob, md):
191         split = layout.split()
192
193         col = split.column()
194         col.prop(md, "frame_start")
195         col.prop(md, "frame_duration")
196         col.prop(md, "use_reverse")
197
198         col = split.column()
199         col.prop(md, "use_random_order")
200         sub = col.column()
201         sub.active = md.use_random_order
202         sub.prop(md, "seed")
203
204     def MESH_CACHE(self, layout, ob, md):
205         layout.prop(md, "cache_format")
206         layout.prop(md, "filepath")
207
208         if md.cache_format == 'ABC':
209             layout.prop(md, "sub_object")
210
211         layout.label(text="Evaluation:")
212         layout.prop(md, "factor", slider=True)
213         layout.prop(md, "deform_mode")
214         layout.prop(md, "interpolation")
215
216         layout.label(text="Time Mapping:")
217
218         row = layout.row()
219         row.prop(md, "time_mode", expand=True)
220         row = layout.row()
221         row.prop(md, "play_mode", expand=True)
222         if md.play_mode == 'SCENE':
223             layout.prop(md, "frame_start")
224             layout.prop(md, "frame_scale")
225         else:
226             time_mode = md.time_mode
227             if time_mode == 'FRAME':
228                 layout.prop(md, "eval_frame")
229             elif time_mode == 'TIME':
230                 layout.prop(md, "eval_time")
231             elif time_mode == 'FACTOR':
232                 layout.prop(md, "eval_factor")
233
234         layout.label(text="Axis Mapping:")
235         split = layout.split(factor=0.5, align=True)
236         split.alert = (md.forward_axis[-1] == md.up_axis[-1])
237         split.label(text="Forward/Up Axis:")
238         split.prop(md, "forward_axis", text="")
239         split.prop(md, "up_axis", text="")
240         split = layout.split(factor=0.5)
241         split.label(text="Flip Axis:")
242         row = split.row()
243         row.prop(md, "flip_axis")
244
245     def MESH_SEQUENCE_CACHE(self, layout, ob, md):
246         layout.label(text="Cache File Properties:")
247         box = layout.box()
248         box.template_cache_file(md, "cache_file")
249
250         cache_file = md.cache_file
251
252         layout.label(text="Modifier Properties:")
253         box = layout.box()
254
255         if cache_file is not None:
256             box.prop_search(md, "object_path", cache_file, "object_paths")
257
258         if ob.type == 'MESH':
259             box.row().prop(md, "read_data")
260
261     def CAST(self, layout, ob, md):
262         split = layout.split(factor=0.25)
263
264         split.label(text="Cast Type:")
265         split.prop(md, "cast_type", text="")
266
267         split = layout.split(factor=0.25)
268
269         col = split.column()
270         col.prop(md, "use_x")
271         col.prop(md, "use_y")
272         col.prop(md, "use_z")
273
274         col = split.column()
275         col.prop(md, "factor")
276         col.prop(md, "radius")
277         col.prop(md, "size")
278         col.prop(md, "use_radius_as_size")
279
280         split = layout.split()
281
282         col = split.column()
283         col.label(text="Vertex Group:")
284         col.prop_search(md, "vertex_group", ob, "vertex_groups", text="")
285         col = split.column()
286         col.label(text="Control Object:")
287         col.prop(md, "object", text="")
288         if md.object:
289             col.prop(md, "use_transform")
290
291     def CLOTH(self, layout, ob, md):
292         layout.label(text="Settings are inside the Physics tab")
293
294     def COLLISION(self, layout, ob, md):
295         layout.label(text="Settings are inside the Physics tab")
296
297     def CURVE(self, layout, ob, md):
298         split = layout.split()
299
300         col = split.column()
301         col.label(text="Object:")
302         col.prop(md, "object", text="")
303         col = split.column()
304         col.label(text="Vertex Group:")
305         col.prop_search(md, "vertex_group", ob, "vertex_groups", text="")
306         layout.label(text="Deformation Axis:")
307         layout.row().prop(md, "deform_axis", expand=True)
308
309     def DECIMATE(self, layout, ob, md):
310         decimate_type = md.decimate_type
311
312         row = layout.row()
313         row.prop(md, "decimate_type", expand=True)
314
315         if decimate_type == 'COLLAPSE':
316             has_vgroup = bool(md.vertex_group)
317             layout.prop(md, "ratio")
318
319             split = layout.split()
320
321             col = split.column()
322             row = col.row(align=True)
323             row.prop_search(md, "vertex_group", ob, "vertex_groups", text="")
324             row.prop(md, "invert_vertex_group", text="", icon='ARROW_LEFTRIGHT')
325
326             layout_info = col
327
328             col = split.column()
329             row = col.row()
330             row.active = has_vgroup
331             row.prop(md, "vertex_group_factor")
332
333             col.prop(md, "use_collapse_triangulate")
334             row = col.split(factor=0.75)
335             row.prop(md, "use_symmetry")
336             row.prop(md, "symmetry_axis", text="")
337
338         elif decimate_type == 'UNSUBDIV':
339             layout.prop(md, "iterations")
340             layout_info = layout
341         else:  # decimate_type == 'DISSOLVE':
342             layout.prop(md, "angle_limit")
343             layout.prop(md, "use_dissolve_boundaries")
344             layout.label(text="Delimit:")
345             row = layout.row()
346             row.prop(md, "delimit")
347             layout_info = layout
348
349         layout_info.label(
350             text=iface_("Face Count: {:,}".format(md.face_count)),
351             translate=False,
352         )
353
354     def DISPLACE(self, layout, ob, md):
355         has_texture = (md.texture is not None)
356
357         col = layout.column(align=True)
358         col.label(text="Texture:")
359         col.template_ID(md, "texture", new="texture.new")
360
361         split = layout.split()
362
363         col = split.column(align=True)
364         col.label(text="Direction:")
365         col.prop(md, "direction", text="")
366         if md.direction in {'X', 'Y', 'Z', 'RGB_TO_XYZ'}:
367             col.label(text="Space:")
368             col.prop(md, "space", text="")
369         col.label(text="Vertex Group:")
370         col.prop_search(md, "vertex_group", ob, "vertex_groups", text="")
371
372         col = split.column(align=True)
373         col.active = has_texture
374         col.label(text="Texture Coordinates:")
375         col.prop(md, "texture_coords", text="")
376         if md.texture_coords == 'OBJECT':
377             col.label(text="Object:")
378             col.prop(md, "texture_coords_object", text="")
379         elif md.texture_coords == 'UV' and ob.type == 'MESH':
380             col.label(text="UV Map:")
381             col.prop_search(md, "uv_layer", ob.data, "uv_layers", text="")
382
383         layout.separator()
384
385         row = layout.row()
386         row.prop(md, "mid_level")
387         row.prop(md, "strength")
388
389     def DYNAMIC_PAINT(self, layout, ob, md):
390         layout.label(text="Settings are inside the Physics tab")
391
392     def EDGE_SPLIT(self, layout, ob, md):
393         split = layout.split()
394
395         col = split.column()
396         col.prop(md, "use_edge_angle", text="Edge Angle")
397         sub = col.column()
398         sub.active = md.use_edge_angle
399         sub.prop(md, "split_angle")
400
401         split.prop(md, "use_edge_sharp", text="Sharp Edges")
402
403     def EXPLODE(self, layout, ob, md):
404         split = layout.split()
405
406         col = split.column()
407         col.label(text="Vertex Group:")
408         col.prop_search(md, "vertex_group", ob, "vertex_groups", text="")
409         sub = col.column()
410         sub.active = bool(md.vertex_group)
411         sub.prop(md, "protect")
412         col.label(text="Particle UV")
413         col.prop_search(md, "particle_uv", ob.data, "uv_layers", text="")
414
415         col = split.column()
416         col.prop(md, "use_edge_cut")
417         col.prop(md, "show_unborn")
418         col.prop(md, "show_alive")
419         col.prop(md, "show_dead")
420         col.prop(md, "use_size")
421
422         layout.operator("object.explode_refresh", text="Refresh")
423
424     def FLUID_SIMULATION(self, layout, ob, md):
425         layout.label(text="Settings are inside the Physics tab")
426
427     def HOOK(self, layout, ob, md):
428         use_falloff = (md.falloff_type != 'NONE')
429         split = layout.split()
430
431         col = split.column()
432         col.label(text="Object:")
433         col.prop(md, "object", text="")
434         if md.object and md.object.type == 'ARMATURE':
435             col.label(text="Bone:")
436             col.prop_search(md, "subtarget", md.object.data, "bones", text="")
437         col = split.column()
438         col.label(text="Vertex Group:")
439         col.prop_search(md, "vertex_group", ob, "vertex_groups", text="")
440
441         layout.separator()
442
443         row = layout.row(align=True)
444         if use_falloff:
445             row.prop(md, "falloff_radius")
446         row.prop(md, "strength", slider=True)
447         layout.prop(md, "falloff_type")
448
449         col = layout.column()
450         if use_falloff:
451             if md.falloff_type == 'CURVE':
452                 col.template_curve_mapping(md, "falloff_curve")
453
454         split = layout.split()
455
456         col = split.column()
457         col.prop(md, "use_falloff_uniform")
458
459         if ob.mode == 'EDIT':
460             row = col.row(align=True)
461             row.operator("object.hook_reset", text="Reset")
462             row.operator("object.hook_recenter", text="Recenter")
463
464             row = layout.row(align=True)
465             row.operator("object.hook_select", text="Select")
466             row.operator("object.hook_assign", text="Assign")
467
468     def LAPLACIANDEFORM(self, layout, ob, md):
469         is_bind = md.is_bind
470
471         layout.prop(md, "iterations")
472
473         row = layout.row()
474         row.active = not is_bind
475         row.label(text="Anchors Vertex Group:")
476
477         row = layout.row()
478         row.enabled = not is_bind
479         row.prop_search(md, "vertex_group", ob, "vertex_groups", text="")
480
481         layout.separator()
482
483         row = layout.row()
484         row.enabled = bool(md.vertex_group)
485         row.operator("object.laplaciandeform_bind", text="Unbind" if is_bind else "Bind")
486
487     def LAPLACIANSMOOTH(self, layout, ob, md):
488         layout.prop(md, "iterations")
489
490         split = layout.split(factor=0.25)
491
492         col = split.column()
493         col.label(text="Axis:")
494         col.prop(md, "use_x")
495         col.prop(md, "use_y")
496         col.prop(md, "use_z")
497
498         col = split.column()
499         col.label(text="Lambda:")
500         col.prop(md, "lambda_factor", text="Factor")
501         col.prop(md, "lambda_border", text="Border")
502
503         col.separator()
504         col.prop(md, "use_volume_preserve")
505         col.prop(md, "use_normalized")
506
507         layout.label(text="Vertex Group:")
508         layout.prop_search(md, "vertex_group", ob, "vertex_groups", text="")
509
510     def LATTICE(self, layout, ob, md):
511         split = layout.split()
512
513         col = split.column()
514         col.label(text="Object:")
515         col.prop(md, "object", text="")
516
517         col = split.column()
518         col.label(text="Vertex Group:")
519         col.prop_search(md, "vertex_group", ob, "vertex_groups", text="")
520
521         layout.separator()
522         layout.prop(md, "strength", slider=True)
523
524     def MASK(self, layout, ob, md):
525         split = layout.split()
526
527         col = split.column()
528         col.label(text="Mode:")
529         col.prop(md, "mode", text="")
530
531         col = split.column()
532         if md.mode == 'ARMATURE':
533             col.label(text="Armature:")
534             row = col.row(align=True)
535             row.prop(md, "armature", text="")
536             sub = row.row(align=True)
537             sub.active = (md.armature is not None)
538             sub.prop(md, "invert_vertex_group", text="", icon='ARROW_LEFTRIGHT')
539         elif md.mode == 'VERTEX_GROUP':
540             col.label(text="Vertex Group:")
541             row = col.row(align=True)
542             row.prop_search(md, "vertex_group", ob, "vertex_groups", text="")
543             sub = row.row(align=True)
544             sub.active = bool(md.vertex_group)
545             sub.prop(md, "invert_vertex_group", text="", icon='ARROW_LEFTRIGHT')
546
547         col = layout.column()
548         col.prop(md, "threshold")
549
550     def MESH_DEFORM(self, layout, ob, md):
551         split = layout.split()
552
553         col = split.column()
554         col.enabled = not md.is_bound
555         col.label(text="Object:")
556         col.prop(md, "object", text="")
557
558         col = split.column()
559         col.label(text="Vertex Group:")
560         row = col.row(align=True)
561         row.prop_search(md, "vertex_group", ob, "vertex_groups", text="")
562         sub = row.row(align=True)
563         sub.active = bool(md.vertex_group)
564         sub.prop(md, "invert_vertex_group", text="", icon='ARROW_LEFTRIGHT')
565
566         layout.separator()
567         row = layout.row()
568         row.enabled = not md.is_bound
569         row.prop(md, "precision")
570         row.prop(md, "use_dynamic_bind")
571
572         layout.separator()
573         if md.is_bound:
574             layout.operator("object.meshdeform_bind", text="Unbind")
575         else:
576             layout.operator("object.meshdeform_bind", text="Bind")
577
578     def MIRROR(self, layout, ob, md):
579         axis_text = "XYZ"
580         split = layout.split(factor=0.33)
581
582         col = split.column()
583         col.label(text="Axis:")
584         for i, text in enumerate(axis_text):
585             col.prop(md, "use_axis", text=text, index=i)
586
587         col = split.column()
588         col.label(text="Bisect:")
589         for i, text in enumerate(axis_text):
590             colsub = col.column()
591             colsub.prop(md, "use_bisect_axis", text=text, index=i)
592             colsub.active = md.use_axis[i]
593
594         col = split.column()
595         col.label(text="Flip:")
596         for i, text in enumerate(axis_text):
597             colsub = col.column()
598             colsub.prop(md, "use_bisect_flip_axis", text=text, index=i)
599             colsub.active = md.use_axis[i] and md.use_bisect_axis[i]
600
601         layout.separator()
602
603         col = layout.column()
604         col.label(text="Mirror Object:")
605         col.prop(md, "mirror_object", text="")
606
607         layout.separator()
608
609         col = layout.column()
610         col.label(text="Options:")
611
612         row = layout.row()
613         row.prop(md, "use_mirror_vertex_groups", text="Vertex Groups")
614         row.prop(md, "use_clip", text="Clipping")
615         row = layout.row()
616         row.prop(md, "use_mirror_merge", text="Merge")
617
618         col = layout.column()
619         if md.use_mirror_merge is True:
620             col.prop(md, "merge_threshold")
621
622         layout.separator()
623         col = layout.column()
624
625         col.label(text="Textures:")
626         row = layout.row()
627         row.prop(md, "use_mirror_u", text="Flip U")
628         row.prop(md, "use_mirror_v", text="Flip V")
629
630         col = layout.column(align=True)
631
632         if md.use_mirror_u:
633             col.prop(md, "mirror_offset_u")
634
635         if md.use_mirror_v:
636             col.prop(md, "mirror_offset_v")
637
638         col = layout.column(align=True)
639         col.prop(md, "offset_u")
640         col.prop(md, "offset_v")
641
642     def MULTIRES(self, layout, ob, md):
643         layout.row().prop(md, "subdivision_type", expand=True)
644
645         split = layout.split()
646         col = split.column()
647         col.prop(md, "levels", text="Preview")
648         col.prop(md, "sculpt_levels", text="Sculpt")
649         col.prop(md, "render_levels", text="Render")
650         col.prop(md, "quality")
651
652         col = split.column()
653
654         col.enabled = ob.mode != 'EDIT'
655         col.operator("object.multires_subdivide", text="Subdivide")
656         col.operator("object.multires_higher_levels_delete", text="Delete Higher")
657         col.operator("object.multires_reshape", text="Reshape")
658         col.operator("object.multires_base_apply", text="Apply Base")
659         col.prop(md, "uv_smooth", text="")
660         col.prop(md, "show_only_control_edges")
661
662         layout.separator()
663
664         col = layout.column()
665         row = col.row()
666         if md.is_external:
667             row.operator("object.multires_external_pack", text="Pack External")
668             row.label()
669             row = col.row()
670             row.prop(md, "filepath", text="")
671         else:
672             row.operator("object.multires_external_save", text="Save External...")
673             row.label()
674
675     def OCEAN(self, layout, ob, md):
676         if not bpy.app.build_options.mod_oceansim:
677             layout.label(text="Built without OceanSim modifier")
678             return
679
680         layout.prop(md, "geometry_mode")
681
682         if md.geometry_mode == 'GENERATE':
683             row = layout.row()
684             row.prop(md, "repeat_x")
685             row.prop(md, "repeat_y")
686
687         layout.separator()
688
689         split = layout.split()
690
691         col = split.column()
692         col.prop(md, "time")
693         col.prop(md, "depth")
694         col.prop(md, "random_seed")
695
696         col = split.column()
697         col.prop(md, "resolution")
698         col.prop(md, "size")
699         col.prop(md, "spatial_size")
700
701         layout.label(text="Waves:")
702
703         split = layout.split()
704
705         col = split.column()
706         col.prop(md, "choppiness")
707         col.prop(md, "wave_scale", text="Scale")
708         col.prop(md, "wave_scale_min")
709         col.prop(md, "wind_velocity")
710
711         col = split.column()
712         col.prop(md, "wave_alignment", text="Alignment")
713         sub = col.column()
714         sub.active = (md.wave_alignment > 0.0)
715         sub.prop(md, "wave_direction", text="Direction")
716         sub.prop(md, "damping")
717
718         layout.separator()
719
720         layout.prop(md, "use_normals")
721
722         split = layout.split()
723
724         col = split.column()
725         col.prop(md, "use_foam")
726         sub = col.row()
727         sub.active = md.use_foam
728         sub.prop(md, "foam_coverage", text="Coverage")
729
730         col = split.column()
731         col.active = md.use_foam
732         col.label(text="Foam Data Layer Name:")
733         col.prop(md, "foam_layer_name", text="")
734
735         layout.separator()
736
737         if md.is_cached:
738             layout.operator("object.ocean_bake", text="Delete Bake").free = True
739         else:
740             layout.operator("object.ocean_bake").free = False
741
742         split = layout.split()
743         split.enabled = not md.is_cached
744
745         col = split.column(align=True)
746         col.prop(md, "frame_start", text="Start")
747         col.prop(md, "frame_end", text="End")
748
749         col = split.column(align=True)
750         col.label(text="Cache path:")
751         col.prop(md, "filepath", text="")
752
753         split = layout.split()
754         split.enabled = not md.is_cached
755
756         col = split.column()
757         col.active = md.use_foam
758         col.prop(md, "bake_foam_fade")
759
760         col = split.column()
761
762     def PARTICLE_INSTANCE(self, layout, ob, md):
763         layout.prop(md, "object")
764         if md.object:
765             layout.prop_search(md, "particle_system", md.object, "particle_systems", text="Particle System")
766         else:
767             layout.prop(md, "particle_system_index", text="Particle System")
768
769         split = layout.split()
770         col = split.column()
771         col.label(text="Create From:")
772         layout.prop(md, "space", text="")
773         col.prop(md, "use_normal")
774         col.prop(md, "use_children")
775         col.prop(md, "use_size")
776
777         col = split.column()
778         col.label(text="Show Particles When:")
779         col.prop(md, "show_alive")
780         col.prop(md, "show_unborn")
781         col.prop(md, "show_dead")
782
783         row = layout.row(align=True)
784         row.prop(md, "particle_amount", text="Amount")
785         row.prop(md, "particle_offset", text="Offset")
786
787         row = layout.row(align=True)
788         row.prop(md, "axis", expand=True)
789
790         layout.separator()
791
792         layout.prop(md, "use_path", text="Create Along Paths")
793
794         col = layout.column()
795         col.active = md.use_path
796         col.prop(md, "use_preserve_shape")
797
798         row = col.row(align=True)
799         row.prop(md, "position", slider=True)
800         row.prop(md, "random_position", text="Random", slider=True)
801         row = col.row(align=True)
802         row.prop(md, "rotation", slider=True)
803         row.prop(md, "random_rotation", text="Random", slider=True)
804
805         layout.separator()
806
807         col = layout.column()
808         col.prop_search(md, "index_layer_name", ob.data, "vertex_colors", text="Index Layer")
809         col.prop_search(md, "value_layer_name", ob.data, "vertex_colors", text="Value Layer")
810
811     def PARTICLE_SYSTEM(self, layout, ob, md):
812         layout.label(text="Settings can be found inside the Particle context")
813
814     def SCREW(self, layout, ob, md):
815         split = layout.split()
816
817         col = split.column()
818         col.prop(md, "axis")
819         col.prop(md, "object", text="AxisOb")
820         col.prop(md, "angle")
821         col.prop(md, "steps")
822         col.prop(md, "render_steps")
823         col.prop(md, "use_smooth_shade")
824         col.prop(md, "use_merge_vertices")
825         sub = col.column()
826         sub.active = md.use_merge_vertices
827         sub.prop(md, "merge_threshold")
828
829         col = split.column()
830         row = col.row()
831         row.active = (md.object is None or md.use_object_screw_offset is False)
832         row.prop(md, "screw_offset")
833         row = col.row()
834         row.active = (md.object is not None)
835         row.prop(md, "use_object_screw_offset")
836         col.prop(md, "use_normal_calculate")
837         col.prop(md, "use_normal_flip")
838         col.prop(md, "iterations")
839         col.prop(md, "use_stretch_u")
840         col.prop(md, "use_stretch_v")
841
842     def SHRINKWRAP(self, layout, ob, md):
843         split = layout.split()
844         col = split.column()
845         col.label(text="Target:")
846         col.prop(md, "target", text="")
847         col = split.column()
848         col.label(text="Vertex Group:")
849         row = col.row(align=True)
850         row.prop_search(md, "vertex_group", ob, "vertex_groups", text="")
851         row.prop(md, "invert_vertex_group", text="", icon='ARROW_LEFTRIGHT')
852
853         split = layout.split()
854
855         col = split.column()
856         col.prop(md, "offset")
857
858         col = split.column()
859         col.label(text="Mode:")
860         col.prop(md, "wrap_method", text="")
861
862         if md.wrap_method in {'PROJECT', 'NEAREST_SURFACEPOINT', 'TARGET_PROJECT'}:
863             col.prop(md, "wrap_mode", text="")
864
865         if md.wrap_method == 'PROJECT':
866             split = layout.split()
867             col = split.column()
868             col.prop(md, "subsurf_levels")
869             col = split.column()
870
871             col.prop(md, "project_limit", text="Limit")
872             split = layout.split(factor=0.25)
873
874             col = split.column()
875             col.label(text="Axis:")
876             col.prop(md, "use_project_x")
877             col.prop(md, "use_project_y")
878             col.prop(md, "use_project_z")
879
880             col = split.column()
881             col.label(text="Direction:")
882             col.prop(md, "use_negative_direction")
883             col.prop(md, "use_positive_direction")
884
885             subcol = col.column()
886             subcol.active = md.use_negative_direction and md.cull_face != 'OFF'
887             subcol.prop(md, "use_invert_cull")
888
889             col = split.column()
890             col.label(text="Cull Faces:")
891             col.prop(md, "cull_face", expand=True)
892
893             layout.prop(md, "auxiliary_target")
894
895     def SIMPLE_DEFORM(self, layout, ob, md):
896
897         layout.row().prop(md, "deform_method", expand=True)
898
899         split = layout.split()
900
901         col = split.column()
902         col.label(text="Vertex Group:")
903         row = col.row(align=True)
904         row.prop_search(md, "vertex_group", ob, "vertex_groups", text="")
905         row.prop(md, "invert_vertex_group", text="", icon='ARROW_LEFTRIGHT')
906
907         split = layout.split()
908
909         col = split.column()
910         col.label(text="Axis, Origin:")
911         col.prop(md, "origin", text="")
912
913         col.prop(md, "deform_axis")
914
915         if md.deform_method in {'TAPER', 'STRETCH', 'TWIST'}:
916             row = col.row(align=True)
917             row.label(text="Lock:")
918             deform_axis = md.deform_axis
919             if deform_axis != 'X':
920                 row.prop(md, "lock_x")
921             if deform_axis != 'Y':
922                 row.prop(md, "lock_y")
923             if deform_axis != 'Z':
924                 row.prop(md, "lock_z")
925
926         col = split.column()
927         col.label(text="Deform:")
928         if md.deform_method in {'TAPER', 'STRETCH'}:
929             col.prop(md, "factor")
930         else:
931             col.prop(md, "angle")
932         col.prop(md, "limits", slider=True)
933
934     def SMOKE(self, layout, ob, md):
935         layout.label(text="Settings are inside the Physics tab")
936
937     def SMOOTH(self, layout, ob, md):
938         split = layout.split(factor=0.25)
939
940         col = split.column()
941         col.label(text="Axis:")
942         col.prop(md, "use_x")
943         col.prop(md, "use_y")
944         col.prop(md, "use_z")
945
946         col = split.column()
947         col.prop(md, "factor")
948         col.prop(md, "iterations")
949         col.label(text="Vertex Group:")
950         col.prop_search(md, "vertex_group", ob, "vertex_groups", text="")
951
952     def SOFT_BODY(self, layout, ob, md):
953         layout.label(text="Settings are inside the Physics tab")
954
955     def SOLIDIFY(self, layout, ob, md):
956         split = layout.split()
957
958         col = split.column()
959         col.prop(md, "thickness")
960         col.prop(md, "thickness_clamp")
961
962         col.separator()
963
964         row = col.row(align=True)
965         row.prop_search(md, "vertex_group", ob, "vertex_groups", text="")
966         sub = row.row(align=True)
967         sub.active = bool(md.vertex_group)
968         sub.prop(md, "invert_vertex_group", text="", icon='ARROW_LEFTRIGHT')
969
970         sub = col.row()
971         sub.active = bool(md.vertex_group)
972         sub.prop(md, "thickness_vertex_group", text="Factor")
973
974         col.label(text="Crease:")
975         col.prop(md, "edge_crease_inner", text="Inner")
976         col.prop(md, "edge_crease_outer", text="Outer")
977         col.prop(md, "edge_crease_rim", text="Rim")
978
979         col = split.column()
980
981         col.prop(md, "offset")
982         col.prop(md, "use_flip_normals")
983
984         col.prop(md, "use_even_offset")
985         col.prop(md, "use_quality_normals")
986         col.prop(md, "use_rim")
987         col_rim = col.column()
988         col_rim.active = md.use_rim
989         col_rim.prop(md, "use_rim_only")
990
991         col.separator()
992
993         col.label(text="Material Index Offset:")
994
995         sub = col.column()
996         row = sub.split(factor=0.4, align=True)
997         row.prop(md, "material_offset", text="")
998         row = row.row(align=True)
999         row.active = md.use_rim
1000         row.prop(md, "material_offset_rim", text="Rim")
1001
1002     def SUBSURF(self, layout, ob, md):
1003         from bpy import context
1004         layout.row().prop(md, "subdivision_type", expand=True)
1005
1006         split = layout.split()
1007         col = split.column()
1008
1009         scene = context.scene
1010         engine = context.engine
1011         show_adaptive_options = (
1012             engine == 'CYCLES' and md == ob.modifiers[-1] and
1013             scene.cycles.feature_set == 'EXPERIMENTAL'
1014         )
1015         if show_adaptive_options:
1016             col.label(text="View:")
1017             col.prop(md, "levels", text="Levels")
1018             col.label(text="Render:")
1019             col.prop(ob.cycles, "use_adaptive_subdivision", text="Adaptive")
1020             if ob.cycles.use_adaptive_subdivision:
1021                 col.prop(ob.cycles, "dicing_rate")
1022             else:
1023                 col.prop(md, "render_levels", text="Levels")
1024         else:
1025             col.label(text="Subdivisions:")
1026             col.prop(md, "levels", text="View")
1027             col.prop(md, "render_levels", text="Render")
1028             col.prop(md, "quality")
1029
1030         col = split.column()
1031         col.label(text="Options:")
1032
1033         sub = col.column()
1034         sub.active = (not show_adaptive_options) or (not ob.cycles.use_adaptive_subdivision)
1035         sub.prop(md, "uv_smooth", text="")
1036
1037         col.prop(md, "show_only_control_edges")
1038
1039         if show_adaptive_options and ob.cycles.use_adaptive_subdivision:
1040             col = layout.column(align=True)
1041             col.scale_y = 0.6
1042             col.separator()
1043             col.label(text="Final Dicing Rate:")
1044             col.separator()
1045
1046             render = max(scene.cycles.dicing_rate * ob.cycles.dicing_rate, 0.1)
1047             preview = max(scene.cycles.preview_dicing_rate * ob.cycles.dicing_rate, 0.1)
1048             col.label(text=f"Render {render:.2f} px, Preview {preview:.2f} px")
1049
1050     def SURFACE(self, layout, ob, md):
1051         layout.label(text="Settings are inside the Physics tab")
1052
1053     def SURFACE_DEFORM(self, layout, ob, md):
1054         col = layout.column()
1055         col.active = not md.is_bound
1056
1057         col.prop(md, "target")
1058         col.prop(md, "falloff")
1059
1060         layout.separator()
1061
1062         col = layout.column()
1063
1064         if md.is_bound:
1065             col.operator("object.surfacedeform_bind", text="Unbind")
1066         else:
1067             col.active = md.target is not None
1068             col.operator("object.surfacedeform_bind", text="Bind")
1069
1070     def UV_PROJECT(self, layout, ob, md):
1071         split = layout.split()
1072         col = split.column()
1073         col.prop_search(md, "uv_layer", ob.data, "uv_layers")
1074         col.separator()
1075
1076         col.prop(md, "projector_count", text="Projectors")
1077         for proj in md.projectors:
1078             col.prop(proj, "object", text="")
1079
1080         col = split.column()
1081         sub = col.column(align=True)
1082         sub.prop(md, "aspect_x", text="Aspect X")
1083         sub.prop(md, "aspect_y", text="Aspect Y")
1084
1085         sub = col.column(align=True)
1086         sub.prop(md, "scale_x", text="Scale X")
1087         sub.prop(md, "scale_y", text="Scale Y")
1088
1089     def WARP(self, layout, ob, md):
1090         use_falloff = (md.falloff_type != 'NONE')
1091         split = layout.split()
1092
1093         col = split.column()
1094         col.label(text="From:")
1095         col.prop(md, "object_from", text="")
1096
1097         col.prop(md, "use_volume_preserve")
1098
1099         col = split.column()
1100         col.label(text="To:")
1101         col.prop(md, "object_to", text="")
1102         col.prop_search(md, "vertex_group", ob, "vertex_groups", text="")
1103
1104         col = layout.column()
1105
1106         row = col.row(align=True)
1107         row.prop(md, "strength")
1108         if use_falloff:
1109             row.prop(md, "falloff_radius")
1110
1111         col.prop(md, "falloff_type")
1112         if use_falloff:
1113             if md.falloff_type == 'CURVE':
1114                 col.template_curve_mapping(md, "falloff_curve")
1115
1116         # 2 new columns
1117         split = layout.split()
1118         col = split.column()
1119         col.label(text="Texture:")
1120         col.template_ID(md, "texture", new="texture.new")
1121
1122         col = split.column()
1123         col.label(text="Texture Coordinates:")
1124         col.prop(md, "texture_coords", text="")
1125
1126         if md.texture_coords == 'OBJECT':
1127             layout.prop(md, "texture_coords_object", text="Object")
1128         elif md.texture_coords == 'UV' and ob.type == 'MESH':
1129             layout.prop_search(md, "uv_layer", ob.data, "uv_layers")
1130
1131     def WAVE(self, layout, ob, md):
1132         split = layout.split()
1133
1134         col = split.column()
1135         col.label(text="Motion:")
1136         col.prop(md, "use_x")
1137         col.prop(md, "use_y")
1138         col.prop(md, "use_cyclic")
1139
1140         col = split.column()
1141         col.prop(md, "use_normal")
1142         sub = col.column()
1143         sub.active = md.use_normal
1144         sub.prop(md, "use_normal_x", text="X")
1145         sub.prop(md, "use_normal_y", text="Y")
1146         sub.prop(md, "use_normal_z", text="Z")
1147
1148         split = layout.split()
1149
1150         col = split.column()
1151         col.label(text="Time:")
1152         sub = col.column(align=True)
1153         sub.prop(md, "time_offset", text="Offset")
1154         sub.prop(md, "lifetime", text="Life")
1155         col.prop(md, "damping_time", text="Damping")
1156
1157         col = split.column()
1158         col.label(text="Position:")
1159         sub = col.column(align=True)
1160         sub.prop(md, "start_position_x", text="X")
1161         sub.prop(md, "start_position_y", text="Y")
1162         col.prop(md, "falloff_radius", text="Falloff")
1163
1164         layout.separator()
1165
1166         layout.prop(md, "start_position_object")
1167         layout.prop_search(md, "vertex_group", ob, "vertex_groups")
1168         split = layout.split(factor=0.33)
1169         col = split.column()
1170         col.label(text="Texture")
1171         col = split.column()
1172         col.template_ID(md, "texture", new="texture.new")
1173         layout.prop(md, "texture_coords")
1174         if md.texture_coords == 'UV' and ob.type == 'MESH':
1175             layout.prop_search(md, "uv_layer", ob.data, "uv_layers")
1176         elif md.texture_coords == 'OBJECT':
1177             layout.prop(md, "texture_coords_object")
1178
1179         layout.separator()
1180
1181         split = layout.split()
1182
1183         col = split.column()
1184         col.prop(md, "speed", slider=True)
1185         col.prop(md, "height", slider=True)
1186
1187         col = split.column()
1188         col.prop(md, "width", slider=True)
1189         col.prop(md, "narrowness", slider=True)
1190
1191     def REMESH(self, layout, ob, md):
1192         if not bpy.app.build_options.mod_remesh:
1193             layout.label(text="Built without Remesh modifier")
1194             return
1195
1196         layout.prop(md, "mode")
1197
1198         row = layout.row()
1199         row.prop(md, "octree_depth")
1200         row.prop(md, "scale")
1201
1202         if md.mode == 'SHARP':
1203             layout.prop(md, "sharpness")
1204
1205         layout.prop(md, "use_smooth_shade")
1206         layout.prop(md, "use_remove_disconnected")
1207         row = layout.row()
1208         row.active = md.use_remove_disconnected
1209         row.prop(md, "threshold")
1210
1211     @staticmethod
1212     def vertex_weight_mask(layout, ob, md):
1213         layout.label(text="Influence/Mask Options:")
1214
1215         split = layout.split(factor=0.4)
1216         split.label(text="Global Influence:")
1217         split.prop(md, "mask_constant", text="")
1218
1219         if not md.mask_texture:
1220             split = layout.split(factor=0.4)
1221             split.label(text="Vertex Group Mask:")
1222             split.prop_search(md, "mask_vertex_group", ob, "vertex_groups", text="")
1223
1224         if not md.mask_vertex_group:
1225             split = layout.split(factor=0.4)
1226             split.label(text="Texture Mask:")
1227             split.template_ID(md, "mask_texture", new="texture.new")
1228             if md.mask_texture:
1229                 split = layout.split()
1230
1231                 col = split.column()
1232                 col.label(text="Texture Coordinates:")
1233                 col.prop(md, "mask_tex_mapping", text="")
1234
1235                 col = split.column()
1236                 col.label(text="Use Channel:")
1237                 col.prop(md, "mask_tex_use_channel", text="")
1238
1239                 if md.mask_tex_mapping == 'OBJECT':
1240                     layout.prop(md, "mask_tex_map_object", text="Object")
1241                 elif md.mask_tex_mapping == 'UV' and ob.type == 'MESH':
1242                     layout.prop_search(md, "mask_tex_uv_layer", ob.data, "uv_layers")
1243
1244     def VERTEX_WEIGHT_EDIT(self, layout, ob, md):
1245         split = layout.split()
1246
1247         col = split.column()
1248         col.label(text="Vertex Group:")
1249         col.prop_search(md, "vertex_group", ob, "vertex_groups", text="")
1250
1251         col.label(text="Default Weight:")
1252         col.prop(md, "default_weight", text="")
1253
1254         col = split.column()
1255         col.prop(md, "use_add")
1256         sub = col.column()
1257         sub.active = md.use_add
1258         sub.prop(md, "add_threshold")
1259
1260         col = col.column()
1261         col.prop(md, "use_remove")
1262         sub = col.column()
1263         sub.active = md.use_remove
1264         sub.prop(md, "remove_threshold")
1265
1266         layout.separator()
1267
1268         layout.prop(md, "falloff_type")
1269         if md.falloff_type == 'CURVE':
1270             layout.template_curve_mapping(md, "map_curve")
1271
1272         # Common mask options
1273         layout.separator()
1274         self.vertex_weight_mask(layout, ob, md)
1275
1276     def VERTEX_WEIGHT_MIX(self, layout, ob, md):
1277         split = layout.split()
1278
1279         col = split.column()
1280         col.label(text="Vertex Group A:")
1281         col.prop_search(md, "vertex_group_a", ob, "vertex_groups", text="")
1282         col.label(text="Default Weight A:")
1283         col.prop(md, "default_weight_a", text="")
1284
1285         col.label(text="Mix Mode:")
1286         col.prop(md, "mix_mode", text="")
1287
1288         col = split.column()
1289         col.label(text="Vertex Group B:")
1290         col.prop_search(md, "vertex_group_b", ob, "vertex_groups", text="")
1291         col.label(text="Default Weight B:")
1292         col.prop(md, "default_weight_b", text="")
1293
1294         col.label(text="Mix Set:")
1295         col.prop(md, "mix_set", text="")
1296
1297         # Common mask options
1298         layout.separator()
1299         self.vertex_weight_mask(layout, ob, md)
1300
1301     def VERTEX_WEIGHT_PROXIMITY(self, layout, ob, md):
1302         split = layout.split()
1303
1304         col = split.column()
1305         col.label(text="Vertex Group:")
1306         col.prop_search(md, "vertex_group", ob, "vertex_groups", text="")
1307
1308         col = split.column()
1309         col.label(text="Target Object:")
1310         col.prop(md, "target", text="")
1311
1312         split = layout.split()
1313
1314         col = split.column()
1315         col.label(text="Distance:")
1316         col.prop(md, "proximity_mode", text="")
1317         if md.proximity_mode == 'GEOMETRY':
1318             col.row().prop(md, "proximity_geometry")
1319
1320         col = split.column()
1321         col.label()
1322         col.prop(md, "min_dist")
1323         col.prop(md, "max_dist")
1324
1325         layout.separator()
1326         layout.prop(md, "falloff_type")
1327
1328         # Common mask options
1329         layout.separator()
1330         self.vertex_weight_mask(layout, ob, md)
1331
1332     def SKIN(self, layout, ob, md):
1333         row = layout.row()
1334         row.operator("object.skin_armature_create", text="Create Armature")
1335         row.operator("mesh.customdata_skin_add")
1336
1337         layout.separator()
1338
1339         row = layout.row(align=True)
1340         row.prop(md, "branch_smoothing")
1341         row.prop(md, "use_smooth_shade")
1342
1343         split = layout.split()
1344
1345         col = split.column()
1346         col.label(text="Selected Vertices:")
1347         sub = col.column(align=True)
1348         sub.operator("object.skin_loose_mark_clear", text="Mark Loose").action = 'MARK'
1349         sub.operator("object.skin_loose_mark_clear", text="Clear Loose").action = 'CLEAR'
1350
1351         sub = col.column()
1352         sub.operator("object.skin_root_mark", text="Mark Root")
1353         sub.operator("object.skin_radii_equalize", text="Equalize Radii")
1354
1355         col = split.column()
1356         col.label(text="Symmetry Axes:")
1357         col.prop(md, "use_x_symmetry")
1358         col.prop(md, "use_y_symmetry")
1359         col.prop(md, "use_z_symmetry")
1360
1361     def TRIANGULATE(self, layout, ob, md):
1362         row = layout.row()
1363
1364         col = row.column()
1365         col.label(text="Quad Method:")
1366         col.prop(md, "quad_method", text="")
1367         col.prop(md, "keep_custom_normals")
1368         col = row.column()
1369         col.label(text="Ngon Method:")
1370         col.prop(md, "ngon_method", text="")
1371
1372     def UV_WARP(self, layout, ob, md):
1373         split = layout.split()
1374         col = split.column()
1375         col.prop(md, "center")
1376
1377         col = split.column()
1378         col.label(text="UV Axis:")
1379         col.prop(md, "axis_u", text="")
1380         col.prop(md, "axis_v", text="")
1381
1382         split = layout.split()
1383         col = split.column()
1384         col.label(text="From:")
1385         col.prop(md, "object_from", text="")
1386
1387         col = split.column()
1388         col.label(text="To:")
1389         col.prop(md, "object_to", text="")
1390
1391         split = layout.split()
1392         col = split.column()
1393         obj = md.object_from
1394         if obj and obj.type == 'ARMATURE':
1395             col.label(text="Bone:")
1396             col.prop_search(md, "bone_from", obj.data, "bones", text="")
1397
1398         col = split.column()
1399         obj = md.object_to
1400         if obj and obj.type == 'ARMATURE':
1401             col.label(text="Bone:")
1402             col.prop_search(md, "bone_to", obj.data, "bones", text="")
1403
1404         split = layout.split()
1405
1406         col = split.column()
1407         col.label(text="Vertex Group:")
1408         col.prop_search(md, "vertex_group", ob, "vertex_groups", text="")
1409
1410         col = split.column()
1411         col.label(text="UV Map:")
1412         col.prop_search(md, "uv_layer", ob.data, "uv_layers", text="")
1413
1414     def WIREFRAME(self, layout, ob, md):
1415         has_vgroup = bool(md.vertex_group)
1416
1417         split = layout.split()
1418
1419         col = split.column()
1420         col.prop(md, "thickness", text="Thickness")
1421
1422         row = col.row(align=True)
1423         row.prop_search(md, "vertex_group", ob, "vertex_groups", text="")
1424         sub = row.row(align=True)
1425         sub.active = has_vgroup
1426         sub.prop(md, "invert_vertex_group", text="", icon='ARROW_LEFTRIGHT')
1427         row = col.row(align=True)
1428         row.active = has_vgroup
1429         row.prop(md, "thickness_vertex_group", text="Factor")
1430
1431         col.prop(md, "use_crease", text="Crease Edges")
1432         row = col.row()
1433         row.active = md.use_crease
1434         row.prop(md, "crease_weight", text="Crease Weight")
1435
1436         col = split.column()
1437
1438         col.prop(md, "offset")
1439         col.prop(md, "use_even_offset", text="Even Thickness")
1440         col.prop(md, "use_relative_offset", text="Relative Thickness")
1441         col.prop(md, "use_boundary", text="Boundary")
1442         col.prop(md, "use_replace", text="Replace Original")
1443
1444         col.prop(md, "material_offset", text="Material Offset")
1445
1446     def DATA_TRANSFER(self, layout, ob, md):
1447         row = layout.row(align=True)
1448         row.prop(md, "object")
1449         sub = row.row(align=True)
1450         sub.active = bool(md.object)
1451         sub.prop(md, "use_object_transform", text="", icon='GROUP')
1452
1453         layout.separator()
1454
1455         split = layout.split(factor=0.333)
1456         split.prop(md, "use_vert_data")
1457         use_vert = md.use_vert_data
1458         row = split.row()
1459         row.active = use_vert
1460         row.prop(md, "vert_mapping", text="")
1461         if use_vert:
1462             col = layout.column(align=True)
1463             split = col.split(factor=0.333, align=True)
1464             sub = split.column(align=True)
1465             sub.prop(md, "data_types_verts")
1466             sub = split.column(align=True)
1467             row = sub.row(align=True)
1468             row.prop(md, "layers_vgroup_select_src", text="")
1469             row.label(icon='RIGHTARROW')
1470             row.prop(md, "layers_vgroup_select_dst", text="")
1471             row = sub.row(align=True)
1472             row.label(text="", icon='NONE')
1473
1474         layout.separator()
1475
1476         split = layout.split(factor=0.333)
1477         split.prop(md, "use_edge_data")
1478         use_edge = md.use_edge_data
1479         row = split.row()
1480         row.active = use_edge
1481         row.prop(md, "edge_mapping", text="")
1482         if use_edge:
1483             col = layout.column(align=True)
1484             split = col.split(factor=0.333, align=True)
1485             sub = split.column(align=True)
1486             sub.prop(md, "data_types_edges")
1487
1488         layout.separator()
1489
1490         split = layout.split(factor=0.333)
1491         split.prop(md, "use_loop_data")
1492         use_loop = md.use_loop_data
1493         row = split.row()
1494         row.active = use_loop
1495         row.prop(md, "loop_mapping", text="")
1496         if use_loop:
1497             col = layout.column(align=True)
1498             split = col.split(factor=0.333, align=True)
1499             sub = split.column(align=True)
1500             sub.prop(md, "data_types_loops")
1501             sub = split.column(align=True)
1502             row = sub.row(align=True)
1503             row.label(text="", icon='NONE')
1504             row = sub.row(align=True)
1505             row.prop(md, "layers_vcol_select_src", text="")
1506             row.label(icon='RIGHTARROW')
1507             row.prop(md, "layers_vcol_select_dst", text="")
1508             row = sub.row(align=True)
1509             row.prop(md, "layers_uv_select_src", text="")
1510             row.label(icon='RIGHTARROW')
1511             row.prop(md, "layers_uv_select_dst", text="")
1512             col.prop(md, "islands_precision")
1513
1514         layout.separator()
1515
1516         split = layout.split(factor=0.333)
1517         split.prop(md, "use_poly_data")
1518         use_poly = md.use_poly_data
1519         row = split.row()
1520         row.active = use_poly
1521         row.prop(md, "poly_mapping", text="")
1522         if use_poly:
1523             col = layout.column(align=True)
1524             split = col.split(factor=0.333, align=True)
1525             sub = split.column(align=True)
1526             sub.prop(md, "data_types_polys")
1527
1528         layout.separator()
1529
1530         split = layout.split()
1531         col = split.column()
1532         row = col.row(align=True)
1533         sub = row.row(align=True)
1534         sub.active = md.use_max_distance
1535         sub.prop(md, "max_distance")
1536         row.prop(md, "use_max_distance", text="", icon='STYLUS_PRESSURE')
1537
1538         col = split.column()
1539         col.prop(md, "ray_radius")
1540
1541         layout.separator()
1542
1543         split = layout.split()
1544         col = split.column()
1545         col.prop(md, "mix_mode")
1546         col.prop(md, "mix_factor")
1547
1548         col = split.column()
1549         row = col.row()
1550         row.active = bool(md.object)
1551         row.operator("object.datalayout_transfer", text="Generate Data Layers")
1552         row = col.row(align=True)
1553         row.prop_search(md, "vertex_group", ob, "vertex_groups", text="")
1554         sub = row.row(align=True)
1555         sub.active = bool(md.vertex_group)
1556         sub.prop(md, "invert_vertex_group", text="", icon='ARROW_LEFTRIGHT')
1557
1558     def NORMAL_EDIT(self, layout, ob, md):
1559         has_vgroup = bool(md.vertex_group)
1560         do_polynors_fix = not md.no_polynors_fix
1561         needs_object_offset = (((md.mode == 'RADIAL') and not md.target) or
1562                                ((md.mode == 'DIRECTIONAL') and md.use_direction_parallel))
1563
1564         row = layout.row()
1565         row.prop(md, "mode", expand=True)
1566
1567         split = layout.split()
1568
1569         col = split.column()
1570         col.prop(md, "target", text="")
1571         sub = col.column(align=True)
1572         sub.active = needs_object_offset
1573         sub.prop(md, "offset")
1574         row = col.row(align=True)
1575
1576         col = split.column()
1577         row = col.row()
1578         row.active = (md.mode == 'DIRECTIONAL')
1579         row.prop(md, "use_direction_parallel")
1580
1581         subcol = col.column(align=True)
1582         subcol.label(text="Mix Mode:")
1583         subcol.prop(md, "mix_mode", text="")
1584         subcol.prop(md, "mix_factor")
1585         row = subcol.row(align=True)
1586         row.prop_search(md, "vertex_group", ob, "vertex_groups", text="")
1587         sub = row.row(align=True)
1588         sub.active = has_vgroup
1589         sub.prop(md, "invert_vertex_group", text="", icon='ARROW_LEFTRIGHT')
1590         row = subcol.row(align=True)
1591         row.prop(md, "mix_limit")
1592         row.prop(md, "no_polynors_fix", text="", icon='UNLOCKED' if do_polynors_fix else 'LOCKED')
1593
1594     def CORRECTIVE_SMOOTH(self, layout, ob, md):
1595         is_bind = md.is_bind
1596
1597         layout.prop(md, "factor", text="Factor")
1598         layout.prop(md, "iterations")
1599
1600         row = layout.row()
1601         row.prop(md, "smooth_type")
1602
1603         split = layout.split()
1604
1605         col = split.column()
1606         col.label(text="Vertex Group:")
1607         row = col.row(align=True)
1608         row.prop_search(md, "vertex_group", ob, "vertex_groups", text="")
1609         row.prop(md, "invert_vertex_group", text="", icon='ARROW_LEFTRIGHT')
1610
1611         col = split.column()
1612         col.prop(md, "use_only_smooth")
1613         col.prop(md, "use_pin_boundary")
1614
1615         layout.prop(md, "rest_source")
1616         if md.rest_source == 'BIND':
1617             layout.operator("object.correctivesmooth_bind", text="Unbind" if is_bind else "Bind")
1618
1619     def WEIGHTED_NORMAL(self, layout, ob, md):
1620         layout.label(text="Weighting Mode:")
1621         split = layout.split(align=True)
1622         col = split.column(align=True)
1623         col.prop(md, "mode", text="")
1624         col.prop(md, "weight", text="Weight")
1625         col.prop(md, "keep_sharp")
1626
1627         col = split.column(align=True)
1628         row = col.row(align=True)
1629         row.prop_search(md, "vertex_group", ob, "vertex_groups", text="")
1630         row.active = bool(md.vertex_group)
1631         row.prop(md, "invert_vertex_group", text="", icon='ARROW_LEFTRIGHT')
1632         col.prop(md, "thresh", text="Threshold")
1633         col.prop(md, "face_influence")
1634
1635
1636 class DATA_PT_gpencil_modifiers(ModifierButtonsPanel, Panel):
1637     bl_label = "Modifiers"
1638
1639     def check_conflicts(self, layout, ob):
1640         for md in ob.grease_pencil_modifiers:
1641             if md.type == 'GP_TIME':
1642                 row = layout.row()
1643                 row.label(text="Build and Time Offset modifier not compatible", icon='ERROR')
1644                 break
1645
1646     @classmethod
1647     def poll(cls, context):
1648         ob = context.object
1649         return ob and ob.type == 'GPENCIL'
1650
1651     def draw(self, context):
1652         layout = self.layout
1653
1654         ob = context.object
1655
1656         layout.operator_menu_enum("object.gpencil_modifier_add", "type")
1657
1658         for md in ob.grease_pencil_modifiers:
1659             box = layout.template_greasepencil_modifier(md)
1660             if box:
1661                 # match enum type to our functions, avoids a lookup table.
1662                 getattr(self, md.type)(box, ob, md)
1663
1664     # the mt.type enum is (ab)used for a lookup on function names
1665     # ...to avoid lengthy if statements
1666     # so each type must have a function here.
1667
1668     def GP_NOISE(self, layout, ob, md):
1669         gpd = ob.data
1670         split = layout.split()
1671
1672         col = split.column()
1673         row = col.row(align=True)
1674         row.prop(md, "factor")
1675         row.prop(md, "random", text="", icon='TIME', toggle=True)
1676         row = col.row()
1677         row.enabled = md.random
1678         row.prop(md, "step")
1679         col.prop(md, "full_stroke")
1680         col.prop(md, "move_extreme")
1681
1682         row = layout.row(align=True)
1683         row.label(text="Affect:")
1684         row = layout.row(align=True)
1685         row.prop(md, "use_edit_position", text="Position", icon='MESH_DATA', toggle=True)
1686         row.prop(md, "use_edit_strength", text="Strength", icon='COLOR', toggle=True)
1687         row.prop(md, "use_edit_thickness", text="Thickness", icon='LINE_DATA', toggle=True)
1688         row.prop(md, "use_edit_uv", text="UV", icon='MOD_UVPROJECT', toggle=True)
1689
1690         col = layout.column()
1691         col.separator()
1692         col.label(text="Vertex Group:")
1693         row = col.row(align=True)
1694         row.prop_search(md, "vertex_group", ob, "vertex_groups", text="")
1695         row.prop(md, "invert_vertex", text="", icon='ARROW_LEFTRIGHT')
1696
1697         col.label(text="Material:")
1698         row = col.row(align=True)
1699         row.prop(md, "pass_index", text="Pass")
1700         row.prop(md, "invert_material_pass", text="", icon='ARROW_LEFTRIGHT')
1701
1702         col.label(text="Layer:")
1703         row = col.row(align=True)
1704         row.prop_search(md, "layer", gpd, "layers", text="", icon='GREASEPENCIL')
1705         row.prop(md, "invert_layers", text="", icon='ARROW_LEFTRIGHT')
1706         row = layout.row(align=True)
1707         row.prop(md, "layer_pass", text="Pass")
1708         row.prop(md, "invert_layer_pass", text="", icon='ARROW_LEFTRIGHT')
1709
1710     def GP_SMOOTH(self, layout, ob, md):
1711         gpd = ob.data
1712         col = layout.column()
1713         col.prop(md, "factor")
1714         col.prop(md, "step")
1715
1716         col.label(text="Affect:")
1717         row = col.row(align=True)
1718         row.prop(md, "use_edit_position", text="Position", icon='MESH_DATA', toggle=True)
1719         row.prop(md, "use_edit_strength", text="Strength", icon='COLOR', toggle=True)
1720         row.prop(md, "use_edit_thickness", text="Thickness", icon='LINE_DATA', toggle=True)
1721         row.prop(md, "use_edit_uv", text="UV", icon='MOD_UVPROJECT', toggle=True)
1722
1723         col.separator()
1724         col.label(text="Vertex Group:")
1725         row = col.row(align=True)
1726         row.prop_search(md, "vertex_group", ob, "vertex_groups", text="")
1727         row.prop(md, "invert_vertex", text="", icon='ARROW_LEFTRIGHT')
1728
1729         col.label(text="Material:")
1730         row = col.row(align=True)
1731         row.prop(md, "pass_index", text="Pass")
1732         row.prop(md, "invert_material_pass", text="", icon='ARROW_LEFTRIGHT')
1733
1734         col.label(text="Layer:")
1735         row = col.row(align=True)
1736         row.prop_search(md, "layer", gpd, "layers", text="", icon='GREASEPENCIL')
1737         row.prop(md, "invert_layers", text="", icon='ARROW_LEFTRIGHT')
1738         row = layout.row(align=True)
1739         row.prop(md, "layer_pass", text="Pass")
1740         row.prop(md, "invert_layer_pass", text="", icon='ARROW_LEFTRIGHT')
1741
1742     def GP_SUBDIV(self, layout, ob, md):
1743         gpd = ob.data
1744         split = layout.split()
1745
1746         col = split.column()
1747         row = col.row(align=True)
1748         row.prop(md, "level")
1749         row.prop(md, "simple", text="", icon='PARTICLE_POINT')
1750
1751         col = layout.column()
1752         col.separator()
1753         col.label(text="Material:")
1754         row = col.row(align=True)
1755         row.prop(md, "pass_index", text="Pass")
1756         row.prop(md, "invert_material_pass", text="", icon='ARROW_LEFTRIGHT')
1757
1758         col.label(text="Layer:")
1759         row = col.row(align=True)
1760         row.prop_search(md, "layer", gpd, "layers", text="", icon='GREASEPENCIL')
1761         row.prop(md, "invert_layers", text="", icon='ARROW_LEFTRIGHT')
1762         row = layout.row(align=True)
1763         row.prop(md, "layer_pass", text="Pass")
1764         row.prop(md, "invert_layer_pass", text="", icon='ARROW_LEFTRIGHT')
1765
1766     def GP_SIMPLIFY(self, layout, ob, md):
1767         gpd = ob.data
1768
1769         row = layout.row()
1770         row.prop(md, "mode")
1771
1772         split = layout.split()
1773
1774         col = split.column()
1775         col.label(text="Settings:")
1776         row = col.row(align=True)
1777         row.enabled = md.mode == 'FIXED'
1778         row.prop(md, "step")
1779
1780         row = col.row(align=True)
1781         row.enabled = not md.mode == 'FIXED'
1782         row.prop(md, "factor")
1783
1784         col = layout.column()
1785         col.separator()
1786         col.label(text="Material:")
1787         row = col.row(align=True)
1788         row.prop(md, "pass_index", text="Pass")
1789         row.prop(md, "invert_material_pass", text="", icon='ARROW_LEFTRIGHT')
1790
1791         col.label(text="Layer:")
1792         row = col.row(align=True)
1793         row.prop_search(md, "layer", gpd, "layers", text="", icon='GREASEPENCIL')
1794         row.prop(md, "invert_layers", text="", icon='ARROW_LEFTRIGHT')
1795         row = layout.row(align=True)
1796         row.prop(md, "layer_pass", text="Pass")
1797         row.prop(md, "invert_layer_pass", text="", icon='ARROW_LEFTRIGHT')
1798
1799     def GP_THICK(self, layout, ob, md):
1800         gpd = ob.data
1801         split = layout.split()
1802
1803         col = split.column()
1804         row = col.row(align=True)
1805         row.prop(md, "thickness", text="Thickness Factor")
1806
1807         col.prop(md, "normalize_thickness")
1808
1809         if not md.normalize_thickness:
1810             split = layout.split()
1811             col = split.column()
1812             col.prop(md, "use_custom_curve")
1813
1814             if md.use_custom_curve:
1815                 col.template_curve_mapping(md, "curve")
1816
1817         col = layout.column()
1818         col.separator()
1819         col.label(text="Vertex Group:")
1820         row = col.row(align=True)
1821         row.prop_search(md, "vertex_group", ob, "vertex_groups", text="")
1822         row.prop(md, "invert_vertex", text="", icon='ARROW_LEFTRIGHT')
1823
1824         col.label(text="Material:")
1825         row = col.row(align=True)
1826         row.prop(md, "pass_index", text="Pass")
1827         row.prop(md, "invert_material_pass", text="", icon='ARROW_LEFTRIGHT')
1828
1829         col.label(text="Layer:")
1830         row = col.row(align=True)
1831         row.prop_search(md, "layer", gpd, "layers", text="", icon='GREASEPENCIL')
1832         row.prop(md, "invert_layers", text="", icon='ARROW_LEFTRIGHT')
1833         row = layout.row(align=True)
1834         row.prop(md, "layer_pass", text="Pass")
1835         row.prop(md, "invert_layer_pass", text="", icon='ARROW_LEFTRIGHT')
1836
1837     def GP_TINT(self, layout, ob, md):
1838         gpd = ob.data
1839         split = layout.split()
1840
1841         col = split.column()
1842         col.prop(md, "color")
1843         col.prop(md, "factor")
1844
1845         row = layout.row()
1846         row.prop(md, "create_materials")
1847         row.prop(md, "modify_color")
1848
1849         col = layout.column()
1850         col.separator()
1851         col.label(text="Material:")
1852         row = col.row(align=True)
1853         row.prop(md, "pass_index", text="Pass")
1854         row.prop(md, "invert_material_pass", text="", icon='ARROW_LEFTRIGHT')
1855
1856         col.label(text="Layer:")
1857         row = col.row(align=True)
1858         row.prop_search(md, "layer", gpd, "layers", text="", icon='GREASEPENCIL')
1859         row.prop(md, "invert_layers", text="", icon='ARROW_LEFTRIGHT')
1860         row = layout.row(align=True)
1861         row.prop(md, "layer_pass", text="Pass")
1862         row.prop(md, "invert_layer_pass", text="", icon='ARROW_LEFTRIGHT')
1863
1864     def GP_TIME(self, layout, ob, md):
1865         gpd = ob.data
1866
1867         row = layout.row()
1868         row.prop(md, "mode", text="Mode")
1869
1870         row = layout.row()
1871         if md.mode == 'FIX':
1872             txt = "Frame"
1873         else:
1874             txt = "Frame Offset"
1875         row.prop(md, "offset", text=txt)
1876
1877         row = layout.row()
1878         row.enabled = md.mode != 'FIX'
1879         row.prop(md, "frame_scale")
1880
1881         row = layout.row()
1882         row.separator()
1883
1884         row = layout.row()
1885         row.enabled = md.mode != 'FIX'
1886         row.prop(md, "use_custom_frame_range")
1887
1888         row = layout.row(align=True)
1889         row.enabled = md.mode != 'FIX' and md.use_custom_frame_range is True
1890         row.prop(md, "frame_start")
1891         row.prop(md, "frame_end")
1892
1893         row = layout.row()
1894         row.enabled = md.mode != 'FIX'
1895         row.prop(md, "use_keep_loop")
1896
1897         row = layout.row()
1898         row.label(text="Layer:")
1899         row = layout.row(align=True)
1900         row.prop_search(md, "layer", gpd, "layers", text="", icon='GREASEPENCIL')
1901         row.prop(md, "invert_layers", text="", icon='ARROW_LEFTRIGHT')
1902
1903         row = layout.row(align=True)
1904         row.prop(md, "layer_pass", text="Pass")
1905         row.prop(md, "invert_layer_pass", text="", icon='ARROW_LEFTRIGHT')
1906
1907     def GP_COLOR(self, layout, ob, md):
1908         gpd = ob.data
1909         split = layout.split()
1910
1911         col = split.column()
1912         col.label(text="Color:")
1913         col.prop(md, "hue", text="H")
1914         col.prop(md, "saturation", text="S")
1915         col.prop(md, "value", text="V")
1916
1917         row = layout.row()
1918         row.prop(md, "create_materials")
1919         row.prop(md, "modify_color")
1920
1921         col = layout.column()
1922         col.separator()
1923         col.label(text="Material:")
1924         row = col.row(align=True)
1925         row.prop(md, "pass_index", text="Pass")
1926         row.prop(md, "invert_material_pass", text="", icon='ARROW_LEFTRIGHT')
1927
1928         col.label(text="Layer:")
1929         row = col.row(align=True)
1930         row.prop_search(md, "layer", gpd, "layers", text="", icon='GREASEPENCIL')
1931         row.prop(md, "invert_layers", text="", icon='ARROW_LEFTRIGHT')
1932         row = layout.row(align=True)
1933         row.prop(md, "layer_pass", text="Pass")
1934         row.prop(md, "invert_layer_pass", text="", icon='ARROW_LEFTRIGHT')
1935
1936     def GP_OPACITY(self, layout, ob, md):
1937         gpd = ob.data
1938         split = layout.split()
1939
1940         col = split.column()
1941         col.label(text="Opacity:")
1942         col.prop(md, "factor")
1943
1944         row = layout.row()
1945         row.prop(md, "create_materials")
1946         row.prop(md, "modify_color")
1947
1948         col = layout.column()
1949         col.separator()
1950         col.label(text="Vertex Group:")
1951         row = col.row(align=True)
1952         row.prop_search(md, "vertex_group", ob, "vertex_groups", text="")
1953         row.prop(md, "invert_vertex", text="", icon='ARROW_LEFTRIGHT')
1954
1955         col.label(text="Material:")
1956         row = col.row(align=True)
1957         row.prop(md, "pass_index", text="Pass")
1958         row.prop(md, "invert_material_pass", text="", icon='ARROW_LEFTRIGHT')
1959
1960         col.label(text="Layer:")
1961         row = col.row(align=True)
1962         row.prop_search(md, "layer", gpd, "layers", text="", icon='GREASEPENCIL')
1963         row.prop(md, "invert_layers", text="", icon='ARROW_LEFTRIGHT')
1964         row = layout.row(align=True)
1965         row.prop(md, "layer_pass", text="Pass")
1966         row.prop(md, "invert_layer_pass", text="", icon='ARROW_LEFTRIGHT')
1967
1968     def GP_ARRAY(self, layout, ob, md):
1969         gpd = ob.data
1970
1971         col = layout.column()
1972         col.prop(md, "count")
1973
1974         split = layout.split()
1975         col = split.column()
1976         col.label(text="Offset:")
1977         col.prop(md, "offset", text="")
1978         col.prop(md, "offset_object", text="Object")
1979
1980         col = split.column()
1981         col.label(text="Shift:")
1982         col.prop(md, "shift", text="")
1983
1984         split = layout.split()
1985         col = split.column()
1986         col.label(text="Rotation:")
1987         col.prop(md, "rotation", text="")
1988         col.separator()
1989         row = col.row(align=True)
1990         row.prop(md, "random_rot", text="", icon='TIME', toggle=True)
1991         row.prop(md, "rot_factor", text="")
1992
1993         col = split.column()
1994         col.label(text="Scale:")
1995         col.prop(md, "scale", text="")
1996         col.separator()
1997         row = col.row(align=True)
1998         row.prop(md, "random_scale", text="", icon='TIME', toggle=True)
1999         row.prop(md, "scale_factor", text="")
2000
2001         col = layout.column()
2002         col.prop(md, "replace_material", text="Material")
2003         col.prop(md, "keep_on_top", text="Keep original stroke on top")
2004
2005         col = layout.column()
2006         col.separator()
2007         col.label(text="Material:")
2008         row = col.row(align=True)
2009         row.prop(md, "pass_index", text="Pass")
2010         row.prop(md, "invert_material_pass", text="", icon='ARROW_LEFTRIGHT')
2011
2012         col.label(text="Layer:")
2013         row = col.row(align=True)
2014         row.prop_search(md, "layer", gpd, "layers", text="", icon='GREASEPENCIL')
2015         row.prop(md, "invert_layers", text="", icon='ARROW_LEFTRIGHT')
2016         row = layout.row(align=True)
2017         row.prop(md, "layer_pass", text="Pass")
2018         row.prop(md, "invert_layer_pass", text="", icon='ARROW_LEFTRIGHT')
2019
2020     def GP_BUILD(self, layout, ob, md):
2021         gpd = ob.data
2022
2023         split = layout.split()
2024
2025         col = split.column()
2026         self.check_conflicts(col, ob)
2027
2028         col.prop(md, "mode")
2029         if md.mode == 'CONCURRENT':
2030             col.prop(md, "concurrent_time_alignment")
2031
2032         col.separator()
2033         col.prop(md, "transition")
2034         sub = col.column(align=True)
2035         sub.prop(md, "start_delay")
2036         sub.prop(md, "length")
2037
2038         col = layout.column(align=True)
2039         col.prop(md, "use_restrict_frame_range")
2040         sub = col.column(align=True)
2041         sub.active = md.use_restrict_frame_range
2042         sub.prop(md, "frame_start", text="Start")
2043         sub.prop(md, "frame_end", text="End")
2044
2045         col = layout.column()
2046         col.separator()
2047         col.label(text="Layer:")
2048         row = col.row(align=True)
2049         row.prop_search(md, "layer", gpd, "layers", text="", icon='GREASEPENCIL')
2050         row.prop(md, "invert_layers", text="", icon='ARROW_LEFTRIGHT')
2051         row = layout.row(align=True)
2052         row.prop(md, "layer_pass", text="Pass")
2053         row.prop(md, "invert_layer_pass", text="", icon='ARROW_LEFTRIGHT')
2054
2055     def GP_LATTICE(self, layout, ob, md):
2056         gpd = ob.data
2057         split = layout.split()
2058
2059         col = split.column()
2060         col.label(text="Object:")
2061         col.prop(md, "object", text="")
2062
2063         layout.prop(md, "strength", slider=True)
2064
2065         col = layout.column()
2066         col.separator()
2067         col.label(text="Vertex Group:")
2068         row = col.row(align=True)
2069         row.prop_search(md, "vertex_group", ob, "vertex_groups", text="")
2070         row.prop(md, "invert_vertex", text="", icon='ARROW_LEFTRIGHT')
2071
2072         col.label(text="Material:")
2073         row = col.row(align=True)
2074         row.prop(md, "pass_index", text="Pass")
2075         row.prop(md, "invert_material_pass", text="", icon='ARROW_LEFTRIGHT')
2076
2077         col.label(text="Layer:")
2078         row = col.row(align=True)
2079         row.prop_search(md, "layer", gpd, "layers", text="", icon='GREASEPENCIL')
2080         row.prop(md, "invert_layers", text="", icon='ARROW_LEFTRIGHT')
2081         row = layout.row(align=True)
2082         row.prop(md, "layer_pass", text="Pass")
2083         row.prop(md, "invert_layer_pass", text="", icon='ARROW_LEFTRIGHT')
2084
2085     def GP_MIRROR(self, layout, ob, md):
2086         gpd = ob.data
2087
2088         row = layout.row(align=True)
2089         row.prop(md, "x_axis")
2090         row.prop(md, "y_axis")
2091         row.prop(md, "z_axis")
2092
2093         layout.label(text="Object:")
2094         layout.prop(md, "object", text="")
2095
2096         col = layout.column()
2097         col.separator()
2098         col.label(text="Material:")
2099         row = col.row(align=True)
2100         row.prop(md, "pass_index", text="Pass")
2101         row.prop(md, "invert_material_pass", text="", icon='ARROW_LEFTRIGHT')
2102
2103         col.label(text="Layer:")
2104         row = col.row(align=True)
2105         row.prop_search(md, "layer", gpd, "layers", text="", icon='GREASEPENCIL')
2106         row.prop(md, "invert_layers", text="", icon='ARROW_LEFTRIGHT')
2107         row = layout.row(align=True)
2108         row.prop(md, "layer_pass", text="Pass")
2109         row.prop(md, "invert_layer_pass", text="", icon='ARROW_LEFTRIGHT')
2110
2111     def GP_HOOK(self, layout, ob, md):
2112         gpd = ob.data
2113         split = layout.split()
2114
2115         col = split.column()
2116         col.label(text="Object:")
2117         col.prop(md, "object", text="")
2118         if md.object and md.object.type == 'ARMATURE':
2119             col.label(text="Bone:")
2120             col.prop_search(md, "subtarget", md.object.data, "bones", text="")
2121
2122         use_falloff = (md.falloff_type != 'NONE')
2123
2124         layout.separator()
2125
2126         row = layout.row(align=True)
2127         if use_falloff:
2128             row.prop(md, "falloff_radius")
2129         row.prop(md, "strength", slider=True)
2130         layout.prop(md, "falloff_type")
2131
2132         col = layout.column()
2133         if use_falloff:
2134             if md.falloff_type == 'CURVE':
2135                 col.template_curve_mapping(md, "falloff_curve")
2136
2137         split = layout.split()
2138
2139         col = split.column()
2140         col.prop(md, "use_falloff_uniform")
2141
2142         col = layout.column()
2143         col.separator()
2144         col.label(text="Vertex Group:")
2145         row = col.row(align=True)
2146         row.prop_search(md, "vertex_group", ob, "vertex_groups", text="")
2147         row.prop(md, "invert_vertex", text="", icon='ARROW_LEFTRIGHT')
2148
2149         col.label(text="Material:")
2150         row = col.row(align=True)
2151         row.prop(md, "pass_index", text="Pass")
2152         row.prop(md, "invert_material_pass", text="", icon='ARROW_LEFTRIGHT')
2153
2154         col.label(text="Layer:")
2155         row = col.row(align=True)
2156         row.prop_search(md, "layer", gpd, "layers", text="", icon='GREASEPENCIL')
2157         row.prop(md, "invert_layers", text="", icon='ARROW_LEFTRIGHT')
2158         row = layout.row(align=True)
2159         row.prop(md, "layer_pass", text="Pass")
2160         row.prop(md, "invert_layer_pass", text="", icon='ARROW_LEFTRIGHT')
2161
2162     def GP_OFFSET(self, layout, ob, md):
2163         gpd = ob.data
2164         col = layout.column()
2165
2166         col.prop(md, "location")
2167         col.prop(md, "scale")
2168         col.prop(md, "rotation")
2169
2170         col = layout.column()
2171         col.separator()
2172         col.label(text="Vertex Group:")
2173         row = col.row(align=True)
2174         row.prop_search(md, "vertex_group", ob, "vertex_groups", text="")
2175         row.prop(md, "invert_vertex", text="", icon='ARROW_LEFTRIGHT')
2176
2177         col.label(text="Material:")
2178         row = col.row(align=True)
2179         row.prop(md, "pass_index", text="Pass")
2180         row.prop(md, "invert_material_pass", text="", icon='ARROW_LEFTRIGHT')
2181
2182         col.label(text="Layer:")
2183         row = col.row(align=True)
2184         row.prop_search(md, "layer", gpd, "layers", text="", icon='GREASEPENCIL')
2185         row.prop(md, "invert_layers", text="", icon='ARROW_LEFTRIGHT')
2186         row = layout.row(align=True)
2187         row.prop(md, "layer_pass", text="Pass")
2188         row.prop(md, "invert_layer_pass", text="", icon='ARROW_LEFTRIGHT')
2189
2190     def GP_ARMATURE(self, layout, ob, md):
2191         split = layout.split()
2192
2193         col = split.column()
2194         col.label(text="Object:")
2195         col.prop(md, "object", text="")
2196         # col.prop(md, "use_deform_preserve_volume")
2197
2198         col = split.column()
2199         col.label(text="Bind To:")
2200         col.prop(md, "use_vertex_groups", text="Vertex Groups")
2201         col.prop(md, "use_bone_envelopes", text="Bone Envelopes")
2202
2203         layout.separator()
2204
2205         row = layout.row(align=True)
2206         row.label(text="Vertex Group:")
2207         row = layout.row(align=True)
2208         row.prop_search(md, "vertex_group", ob, "vertex_groups", text="")
2209         sub = row.row(align=True)
2210         sub.active = bool(md.vertex_group)
2211         sub.prop(md, "invert_vertex_group", text="", icon='ARROW_LEFTRIGHT')
2212
2213
2214 classes = (
2215     DATA_PT_modifiers,
2216     DATA_PT_gpencil_modifiers,
2217 )
2218
2219 if __name__ == "__main__":  # only for live edit.
2220     from bpy.utils import register_class
2221     for cls in classes:
2222         register_class(cls)