4 * ***** BEGIN GPL LICENSE BLOCK *****
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version 2
9 * of the License, or (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software Foundation,
18 * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20 * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
21 * All rights reserved.
23 * The Original Code is: all of this file.
25 * Contributor(s): none yet.
27 * ***** END GPL LICENSE BLOCK *****
38 #define snprintf _snprintf
42 #include "MEM_guardedalloc.h"
43 #include "DNA_screen_types.h"
44 #include "DNA_space_types.h"
45 #include "DNA_scene_types.h"
47 #include "DNA_action_types.h"
48 #include "DNA_armature_types.h"
49 #include "DNA_brush_types.h"
50 #include "DNA_camera_types.h"
51 #include "DNA_cloth_types.h"
52 #include "DNA_color_types.h"
53 #include "DNA_constraint_types.h"
54 #include "DNA_curve_types.h"
55 #include "DNA_effect_types.h"
56 #include "DNA_group_types.h"
57 #include "DNA_key_types.h"
58 #include "DNA_lamp_types.h"
59 #include "DNA_lattice_types.h"
60 #include "DNA_material_types.h"
61 #include "DNA_meta_types.h"
62 #include "DNA_mesh_types.h"
63 #include "DNA_meshdata_types.h"
64 #include "DNA_modifier_types.h"
65 #include "DNA_nla_types.h"
66 #include "DNA_object_types.h"
67 #include "DNA_object_force.h"
68 #include "DNA_particle_types.h"
69 #include "DNA_radio_types.h"
70 #include "DNA_screen_types.h"
71 #include "DNA_texture_types.h"
72 #include "DNA_userdef_types.h"
73 #include "DNA_vfont_types.h"
74 #include "DNA_view3d_types.h"
75 #include "DNA_world_types.h"
76 #include "DNA_packedFile_types.h"
78 #include "BKE_blender.h"
79 #include "BKE_brush.h"
80 #include "BKE_cloth.h"
81 #include "BKE_curve.h"
82 #include "BKE_customdata.h"
83 #include "BKE_colortools.h"
84 #include "BKE_deform.h"
85 #include "BKE_depsgraph.h"
86 #include "BKE_global.h"
88 #include "BKE_library.h"
91 #include "BKE_modifier.h"
92 #include "BKE_multires.h"
93 #include "BKE_packedFile.h"
94 #include "BKE_particle.h"
95 #include "BKE_scene.h"
96 #include "BKE_bmesh.h"
98 #include "BLI_blenlib.h"
99 #include "BLI_arithb.h"
100 #include "BLI_vfontdata.h"
101 #include "BLI_editVert.h"
102 #include "BLI_dynstr.h"
104 #include "BSE_filesel.h"
107 #include "BIF_editaction.h"
108 #include "BIF_editarmature.h"
109 #include "BIF_editconstraint.h"
110 #include "BIF_editdeform.h"
111 #include "BIF_editfont.h"
112 #include "BIF_editkey.h"
113 #include "BIF_editmesh.h"
114 #include "BIF_editparticle.h"
115 #include "BIF_imasel.h"
116 #include "BIF_interface.h"
117 #include "BIF_meshtools.h"
118 #include "BIF_mywindow.h"
119 #include "BIF_poselib.h"
120 #include "BIF_poseobject.h"
121 #include "BIF_renderwin.h"
122 #include "BIF_resources.h"
123 #include "BIF_retopo.h"
124 #include "BIF_screen.h"
125 #include "BIF_scrarea.h"
126 #include "BIF_space.h"
127 #include "BIF_toets.h"
128 #include "BIF_toolbox.h"
129 #include "BIF_previewrender.h"
130 #include "BIF_butspace.h"
133 #include "BIF_verse.h"
136 #include "mydevice.h"
139 #include "BKE_action.h"
140 #include "BKE_anim.h"
141 #include "BKE_armature.h"
142 #include "BKE_constraint.h"
143 #include "BKE_curve.h"
144 #include "BKE_displist.h"
145 #include "BKE_DerivedMesh.h"
146 #include "BKE_effect.h"
147 #include "BKE_font.h"
148 #include "BKE_icons.h"
149 #include "BKE_image.h"
151 #include "BKE_lattice.h"
152 #include "BKE_material.h"
153 #include "BKE_mball.h"
154 #include "BKE_mesh.h"
155 #include "BKE_object.h"
156 #include "BKE_texture.h"
157 #include "BKE_utildefines.h"
159 #include "BIF_poseobject.h"
161 #include "BDR_drawobject.h"
162 #include "BDR_editcurve.h"
163 #include "BDR_editface.h"
164 #include "BDR_editobject.h"
165 #include "BDR_sculptmode.h"
166 #include "BDR_vpaint.h"
167 #include "BDR_unwrapper.h"
169 #include "BSE_drawview.h"
170 #include "BSE_editipo.h"
171 #include "BSE_edit.h"
172 #include "BSE_filesel.h"
173 #include "BSE_headerbuttons.h"
174 #include "BSE_trans_types.h"
175 #include "BSE_view.h"
176 #include "BSE_seqaudio.h"
178 #include "RE_render_ext.h" // make_sticky
180 #include "butspace.h" // own module
181 #include "multires.h"
185 static float editbutweight= 1.0;
186 float editbutvweight= 1;
187 static int actmcol= 0, acttface= 0, acttface_rnd = 0, acttface_clone = 0, acttface_mask = 0, actmcol_rnd = 0;
189 extern ListBase editNurb;
191 /* *************************** Unicode Character Groups ****************** */
192 unicodect uctabname[125] = {
193 {"All", "All", 0x0000, 0xffff},
194 {"Basic Latin", "Basic Latin", 0x0000, 0x007f},
195 {"Latin 1 Supp", "Latin-1 Supplement", 0x0080, 0x00ff},
197 {"Latin Ext. A.", "Latin Extended-A", 0x0100, 0x017F},
198 {"Latin Ext. B.", "Latin Extended-B", 0x0180,0x024F},
199 {"Latin Ext. Add.", "Latin Extended Additional", 0x1e00, 0x1eff},
201 {"IPA Ext", "IPA Extensions", 0x0250, 0x02AF},
202 {"Spacing Mod.", "Spacing Modifier Letters", 0x02b0, 0x02ff},
204 {"Comb. Dia.", "Combining Diacritical Marks", 0x0300, 0x036F},
205 {"Greek, Coptic", "Greek and Coptic", 0x0370, 0x03ff},
206 {"Greek Ext.", "Greek Extended", 0x1f00, 0x1fff},
208 {"Cyrillic", "Cyrillic", 0x0400, 0x04ff},
209 {"Cyrillic Supp.", "Cyrillic Supplementary", 0x0500, 0x052f},
211 {"Armenian", "Armenian", 0x0530, 0x058f},
212 {"Hebrew", "Hebrew", 0x0590, 0x05ff},
215 {"Arabic", "Arabic", 0x0600, 0x06ff},
216 {"Syriac", "Syriac", 0x0700, 0x074f},
218 {"Thaana", "Thaana", 0x0780, 0x07bf},
219 {"Devanagari", "Devanagari", 0x0900, 0x097f},
221 {"Bengali", "Bengali", 0x0980, 0x09ff},
222 {"Gurmukhi", "Gurmukhi", 0x0a00, 0x0a7f},
224 {"Gujarati", "Gujarati", 0x0a80, 0x0aff},
225 {"Oriya", "Oriya", 0x0b00, 0x0b7f},
227 {"Tamil", "Tamil", 0x0b80, 0x0bff},
228 {"Tegulu", "Tegulu", 0x0c00, 0x0c7f},
230 {"Kannada", "Kannada", 0x0c80, 0x0cff},
231 {"Malayalam", "Malayalam", 0x0d00, 0x0d7f},
233 {"Sinhala", "Sinhala", 0x0d80, 0x0dff},
234 {"Thai", "Thai", 0x0e00, 0x0e7f},
236 {"Lao", "Lao", 0x0e80, 0x0eff},
237 {"Tibetan", "Tibetan", 0x0f00, 0x0fff},
239 {"Myanmar", "Myanmar", 0x1000, 0x109f},
240 {"Georgian", "Georgian", 0x10a0, 0x10ff},
242 {"Ethiopic", "Ethiopic", 0x1200, 0x137f},
244 {"Cherokee", "Cherokee", 0x13a0, 0x13ff},
245 {"Unif. Canadian", "Unified Canadian Aboriginal Syllabics", 0x1400, 0x167f},
247 {"Ogham", "Ogham", 0x1680, 0x169f},
248 {"Runic", "Runic", 0x16a0, 0x16ff},
250 {"Tagalog", "Tagalog", 0x1700, 0x171f},
251 {"Hanunoo", "Hanunoo", 0x1720, 0x173f},
253 {"Buhid", "Buhid", 0x1740, 0x175f},
254 {"Tagbanwa", "Tagbanwa", 0x1760, 0x177f},
256 {"Khmer", "Khmer", 0x1780, 0x17ff},
257 {"Khmer Symb", "Khmer Symbols", 0x19e0, 0x19ff},
259 {"Mongolian", "Mongolian", 0x1800, 0x18af},
261 {"Limbu", "Limbu", 0x1900, 0x194f},
262 {"Tai Le", "Tai Le", 0x1950, 0x197f},
264 {"Phon. Ext.", "Phonetic Extensions", 0x1d00, 0x1d7f},
267 {"Gen. Punct.", "General Punctutation", 0x2000, 0x206f},
268 {"Super, Sub", "Superscripts and Subscripts", 0x2070, 0x209f},
270 {"Curr. Symb.", "Currency Symbols", 0x20a0, 0x20cf},
271 {"Comb. Diacrit.", "Combining Diacritical Marks for Symbols", 0x20d0, 0x20ff},
273 {"Letter Symb", "Letterlike Symbols", 0x2100, 0x214f},
274 {"Numb. Forms", "Number Forms", 0x2150, 0x218f},
276 {"Arrows", "Arrows", 0x2190, 0x21ff},
277 {"Math Oper.", "Mathematical Operators", 0x2200, 0x22ff},
279 {"Misc. Tech.", "Miscellaneous Technical", 0x2300, 0x23ff},
280 {"Ctrl. Pict.", "Control Pictures", 0x2400, 0x243f},
282 {"OCR", "Optical Character Recognition", 0x2440, 0x245f},
283 {"Enc. Alpha", "Enclosed Alphanumerics", 0x2460, 0x24ff},
285 {"Bow Drawing", "Box Drawing", 0x2500, 0x257f},
286 {"BLock Elem.", "Block Elements", 0x2580, 0x259f},
288 {"Geom. Shapes", "Geometric Shapes", 0x25a0, 0x25ff},
289 {"Misc. Symb.", "Miscellaneous Symbols", 0x2600, 0x26ff},
291 {"Dingbats", "Dingbats", 0x2700, 0x27bf},
292 {"Misc. Math A", "Miscellaneous Mathematical Symbols-A", 0x27c0, 0x27ef},
294 {"Supp. Arrows-A", "Supplemental Arrows-A", 0x27f0, 0x27ff},
295 {"Braille Pat.", "Braille Patterns", 0x2800, 0x28ff},
297 {"Supp. Arrows-B", "Supplemental Arrows-B", 0x2900, 0x297f},
298 {"Misc. Math B", "Miscellaneous Mathematical Symbols-B", 0x2980, 0x29ff},
300 {"Supp. Math Op.", "Supplemental Mathematical Operators", 0x2a00, 0x2aff},
301 {"Misc. Symb.", "Miscellaneous Symbols and Arrows", 0x2b00, 0x2bff},
303 {"Kangxi Rad.", "Kangxi Radicals", 0x2f00, 0x2fdf},
305 {"Ideographic", "Ideographic Description Characters", 0x2ff0, 0x2fff},
307 {"Hiragana", "Hiragana", 0x3040, 0x309f},
308 {"Katakana", "Katakana", 0x30a0, 0x30ff},
309 {"Katakana Ext.", "Katakana Phonetic Extensions", 0x31f0, 0x31ff},
311 {"Bopomofo", "Bopomofo", 0x3100, 0x312f},
312 {"Bopomofo Ext.", "Bopomofo Extended", 0x31a0, 0x31bf},
314 {"Hangul", "Hangul Jamo", 0x1100, 0x11ff},
315 {"Hangul Comp.", "Hangul Compatibility Jamo", 0x3130, 0x318f},
316 {"Hangul Syll.", "Hangul Syllables", 0xac00, 0xd7af},
318 {"Kanbun", "Kanbun", 0x3190, 0x319f},
322 {"Yijing Hex.", "Yijing Hexagram Symbols", 0x4dc0, 0x4dff},
324 {"Yi Syllables", "Yi Syllables", 0xa000, 0xa48f},
325 {"Yi Radicals", "Yi Radicals", 0xa490, 0xa4cf},
327 {"High Surr.", "High Surrogate Area", 0xd800, 0xdbff},
329 {"Low Surr.", "Low Surrogates", 0xdc00, 0xdfff},
330 {"Priv. Use Area", "Private Use Area", 0xe000, 0xf8ff},
332 {"CJK Rad. Supp.", "CJK Radicals Supplement", 0x2e80, 0x2eff},
333 {"CJK Ideographs", "CJK Unified Ideographs", 0x4e00, 0x9faf},
334 {"CJK Ideog. Ext. A", "CJK Unified Ideographs Extension A", 0x3400, 0x4dbf},
335 {"CJK Ideog. Ext. B", "CJK Unified Ideographs Extension B", 0x20000, 0x2a6df},
336 {"CJK Symbols.", "CJK Symbols and Punctuation", 0x3000, 0x303f},
337 {"Enclosed CJK", "Enclosed CJK Letters and Months", 0x3200, 0x32ff},
338 {"CJK Comp.", "CJK Compatibility", 0x3300, 0x33ff},
339 {"CJK Comp. Ideog.", "CJK Compatibility Ideographs", 0xf900, 0xfaff},
340 {"CJK Comp. Forms", "CJK Compatibility Forms", 0xfe30, 0xfe4f},
341 {"CJK Comp. Supp.", "CJK Compatibility Ideographs Supplement", 0x2f800, 0x2fa1f},
343 {"Alpha. Pres. Forms", "Alphabetic Presentation Forms", 0xfb00, 0xfb4f},
345 {"Arabic Pres. A", "Arabic Presentation Forms-A", 0xfb50, 0xfdff},
346 {"Arabic Pres. B", "Arabic Presentation Forms-B", 0xfe70, 0xfeff},
348 {"Var. Sel.", "Variation Selectors", 0xfe00, 0xfe0f},
350 {"Comb. Half", "Combining Half Marks", 0xfe20, 0xfe2f},
352 {"Sml. From Var.", "Small Form Variants", 0xfe50, 0xfe6f},
354 {"Half, Full Forms", "Halfwidth and Fullwidth Forms", 0xff00, 0xffef},
355 {"Specials", "Specials", 0xfff0, 0xffff},
357 {"Lin. B Syllab.", "Linear B Syllabary", 0x10000, 0x1007f},
358 {"Lin. B Idog.", "Linear B Ideograms", 0x10080, 0x100ff},
360 {"Aegean Num.", "Aegean Numbers", 0x10100, 0x1013f},
361 {"Old Italic", "Old Italic", 0x10300, 0x1032f},
363 {"Gothic", "Gothic", 0x10330, 0x1034f},
364 {"Ugaritic", "Ugaritic", 0x10380, 0x1039f},
366 {"Deseret", "Deseret", 0x10400, 0x1044f},
367 {"Shavian", "Shavian", 0x10450, 0x1047f},
369 {"Osmanya", "Osmanya", 0x10480, 0x104af},
370 {"Cypriot Syll", "Cypriot Syllabary", 0x10800, 0x1083f},
372 {"Bysantine Mus.", "Bysantine Musical Symbols", 0x1d000, 0x1d0ff},
373 {"Music Symb.", "Musical Symbols", 0x1d100, 0x1d1ff},
375 {"Tai Xuan Symb", "Tai Xuan Jing Symbols", 0x1d300, 0x1d35f},
376 {"Math. Alpha Symb.", "Mathematical Alpanumeric Symbols", 0x1d400, 0x1d7ff},
379 {"Tags", "Tags", 0xe0000, 0xe007f},
380 {"Var. Supp", "Variation Selectors Supplement", 0xe0100, 0xe01ef},
382 {"Supp. Priv. A", "Supplementary Private Use Area-A", 0xf0000, 0xffffd},
383 {"Supp. Priv. B", "Supplementary Private Use Area-B", 0x100000, 0x10fffd}
387 /* *************************** static functions prototypes ****************** */
388 VFont *exist_vfont(char *str);
390 /* *************** */
392 void do_common_editbuts(unsigned short event) // old name, is a mix of object and editing events....
394 EditMesh *em = G.editMesh;
404 int a, bit, index= -1;
409 if(G.obedit && G.obedit->actcol>0) {
410 if(G.obedit->type == OB_MESH) {
411 for(efa= em->faces.first; efa; efa= efa->next) {
412 if(efa->f & SELECT) {
413 if(index== -1) index= efa->mat_nr;
414 else if(index!=efa->mat_nr) {
415 error("Mixed colors");
421 else if ELEM(G.obedit->type, OB_CURVE, OB_SURF) {
424 if( isNurbsel(nu) ) {
425 if(index== -1) index= nu->mat_nr;
426 else if(index!=nu->mat_nr) {
427 error("Mixed colors");
435 G.obedit->actcol= index+1;
436 scrarea_queue_winredraw(curarea);
441 new_material_to_objectdata(ob);
442 scrarea_queue_winredraw(curarea);
443 BIF_undo_push("New material");
444 allqueue(REDRAWBUTSSHADING, 0);
445 allqueue(REDRAWVIEW3D_Z, 0);
446 allqueue(REDRAWOOPS, 0);
449 delete_material_index();
450 scrarea_queue_winredraw(curarea);
451 BIF_undo_push("Delete material index");
452 allqueue(REDRAWBUTSSHADING, 0);
453 allqueue(REDRAWVIEW3D_Z, 0);
454 allqueue(REDRAWOOPS, 0);
457 if(G.obedit && G.obedit->actcol>0) {
458 if(G.obedit->type == OB_MESH) {
459 efa= em->faces.first;
462 efa->mat_nr= G.obedit->actcol-1;
466 else if ELEM(G.obedit->type, OB_CURVE, OB_SURF) {
470 nu->mat_nr= nu->charidx= G.obedit->actcol-1;
474 else if (G.obedit->type == OB_FONT) {
476 allqueue(REDRAWVIEW3D, 0);
479 allqueue(REDRAWVIEW3D_Z, 0);
480 DAG_object_flush_update(G.scene, G.obedit, OB_RECALC_DATA);
481 shade_buttons_change_3d();
482 BIF_undo_push("Assign material index");
485 case B_MATASS_BROWSE:
486 /* if slot available, make that index active, and assign */
487 /* else, make new slot, and assign */
488 ma= BLI_findlink(&G.main->mat, G.buts->menunr-1);
490 ob->actcol= find_material_index(ob, ma);
492 assign_material(ob, ma, ob->totcol+1);
493 ob->actcol= ob->totcol;
497 do_common_editbuts(B_MATNEW);
499 do_common_editbuts(B_MATASS);
503 ma= give_current_material(ob, ob->actcol);
504 BKE_icon_changed(BKE_icon_getid((ID *)ma));
505 allqueue(REDRAWVIEW3D, 0);
506 allqueue(REDRAWBUTSEDIT, 0);
512 if(G.obedit->type == OB_MESH) {
513 if (event==B_MATSEL) {
514 editmesh_select_by_material(G.obedit->actcol-1);
516 editmesh_deselect_by_material(G.obedit->actcol-1);
519 else if ELEM(G.obedit->type, OB_CURVE, OB_SURF) {
522 if(nu->mat_nr==G.obedit->actcol-1) {
528 if(event==B_MATSEL) {
543 a= nu->pntsu*nu->pntsv;
547 if(event==B_MATSEL) bp->f1 |= SELECT;
548 else bp->f1 &= ~SELECT;
556 BIF_undo_push("Select material index");
558 allqueue(REDRAWIMAGE, 0);
559 allqueue(REDRAWVIEW3D, 0);
565 if(G.obedit->type == OB_MESH) hide_mesh(0);
566 else if ELEM(G.obedit->type, OB_CURVE, OB_SURF) hideNurb(0);
571 if(G.obedit->type == OB_MESH) reveal_mesh();
572 else if ELEM(G.obedit->type, OB_CURVE, OB_SURF) revealNurb();
574 else if(FACESEL_PAINT_TEST) reveal_tface();
579 if(G.obedit->type == OB_MESH) selectswap_mesh();
580 else if ELEM(G.obedit->type, OB_CURVE, OB_SURF) selectswapNurb();
584 if(ob && G.obedit==0) {
585 if(ELEM3(ob->type, OB_CURVE, OB_SURF, OB_FONT)) tex_space_curve(ob->data);
594 case B_DOCENTERCURSOR:
600 if(G.obedit->type == OB_MESH) {
601 mesh_set_smooth_faces((event==B_SETSMOOTH));
604 nurb_set_smooth((event==B_SETSMOOTH));
610 if(TESTBASELIB(base)) {
611 if(base->object->type==OB_MESH) {
612 mesh_set_smooth_flag(base->object, (event==B_SETSMOOTH));
614 else if ELEM(base->object->type, OB_SURF, OB_CURVE) {
615 cu= base->object->data;
618 if(event==B_SETSMOOTH) nu->flag |= ME_SMOOTH;
619 else nu->flag &= ~ME_SMOOTH;
622 makeDispListCurveTypes(base->object, 0);
627 allqueue(REDRAWVIEW3D, 0);
629 if(event == B_SETSMOOTH) BIF_undo_push("Set Smooth");
630 else BIF_undo_push("Set Solid");
634 DAG_scene_sort(G.scene); // makes new dag
635 if(ob) ob->recalc |= OB_RECALC;
636 allqueue(REDRAWVIEW3D, 0);
643 ob->shapeflag |= OB_SHAPE_TEMPLOCK;
644 DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA);
645 allqueue(REDRAWVIEW3D, 0);
646 allqueue(REDRAWIPO, 0);
647 allqueue(REDRAWBUTSEDIT, 0);
650 ob->shapeflag &= ~OB_SHAPE_TEMPLOCK;
651 DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA);
652 allqueue(REDRAWVIEW3D, 0);
653 allqueue(REDRAWIPO, 0);
654 allqueue(REDRAWBUTSEDIT, 0);
658 Key *key= ob_get_key(ob);
659 if(ob->shapenr == BLI_countlist(&key->block))
662 do_common_editbuts(B_SETKEY);
667 Key *key= ob_get_key(ob);
669 ob->shapenr= BLI_countlist(&key->block);
671 do_common_editbuts(B_SETKEY);
675 allspace(REMAKEIPO, 0);
676 allqueue (REDRAWIPO, 0);
680 allqueue(REDRAWACTION, 0);
688 if(event>=B_OBLAY && event<=B_OBLAY+31) {
689 local= BASACT->lay & 0xFF000000;
690 BASACT->lay -= local;
691 if(BASACT->lay==0 || (G.qual & LR_SHIFTKEY)==0) {
694 scrarea_queue_winredraw(curarea);
696 BASACT->lay += local;
698 if( (ob->lay & G.vd->lay) && (BASACT->lay & G.vd->lay) );
699 else if( (ob->lay & G.vd->lay)==0 && (BASACT->lay & G.vd->lay)==0 );
701 allqueue(REDRAWVIEW3D, 0);
702 DAG_scene_sort(G.scene);
704 ob->lay= BASACT->lay;
710 /* *************************** MESH ******************************** */
712 static void verify_customdata_name_func(void *data1, void *data2)
714 CustomData *data= (CustomData*)data1;
715 CustomDataLayer *layer= (CustomDataLayer*)data2;
717 CustomData_set_layer_unique_name(data, layer - data->layers);
720 static void delete_customdata_layer(void *data1, void *data2)
722 Mesh *me= (Mesh*)data1;
723 CustomData *data= (G.obedit)? &G.editMesh->fdata: &me->fdata;
724 CustomDataLayer *layer= (CustomDataLayer*)data2;
725 void *actlayerdata, *rndlayerdata, *clonelayerdata, *masklayerdata, *layerdata=layer->data;
726 int type= layer->type;
727 int index= CustomData_get_layer_index(data, type);
728 int i, actindex, rndindex, cloneindex, maskindex;
730 /*ok, deleting a non-active layer needs to preserve the active layer indices.
731 to do this, we store a pointer to the .data member of both layer and the active layer,
732 (to detect if we're deleting the active layer or not), then use the active
733 layer data pointer to find where the active layer has ended up.
735 this is necassary because the deletion functions only support deleting the active
737 actlayerdata = data->layers[CustomData_get_active_layer_index(data, type)].data;
738 rndlayerdata = data->layers[CustomData_get_render_layer_index(data, type)].data;
739 clonelayerdata = data->layers[CustomData_get_clone_layer_index(data, type)].data;
740 masklayerdata = data->layers[CustomData_get_mask_layer_index(data, type)].data;
741 CustomData_set_layer_active(data, type, layer - &data->layers[index]);
743 /* Multires is handled seperately because the display data is separate
744 from the data stored in multires */
746 multires_delete_layer(me, &me->mr->fdata, type, layer - &data->layers[index]);
747 multires_level_to_editmesh(OBACT, me, 0);
748 multires_finish_mesh_update(OBACT);
751 EM_free_data_layer(data, type);
754 CustomData_free_layer_active(data, type, me->totface);
755 mesh_update_customdata_pointers(me);
758 if(!CustomData_has_layer(data, type)) {
759 if(type == CD_MCOL && (G.f & G_VERTEXPAINT))
760 G.f &= ~G_VERTEXPAINT; /* get out of vertexpaint mode */
763 /*reconstruct active layer*/
764 if (actlayerdata != layerdata) {
766 actindex = CustomData_get_layer_index(data, type);
767 for (i=actindex; i<data->totlayer; i++) {
768 if (data->layers[i].data == actlayerdata) {
769 actindex = i - actindex;
775 CustomData_set_layer_active(data, type, actindex);
778 if (rndlayerdata != layerdata) {
780 rndindex = CustomData_get_layer_index(data, type);
781 for (i=rndindex; i<data->totlayer; i++) {
782 if (data->layers[i].data == rndlayerdata) {
783 rndindex = i - rndindex;
789 CustomData_set_layer_render(data, type, rndindex);
792 if (clonelayerdata != layerdata) {
794 cloneindex = CustomData_get_layer_index(data, type);
795 for (i=cloneindex; i<data->totlayer; i++) {
796 if (data->layers[i].data == clonelayerdata) {
797 cloneindex = i - cloneindex;
803 CustomData_set_layer_clone(data, type, cloneindex);
806 if (masklayerdata != layerdata) {
808 maskindex = CustomData_get_layer_index(data, type);
809 for (i=maskindex; i<data->totlayer; i++) {
810 if (data->layers[i].data == masklayerdata) {
811 maskindex = i - maskindex;
817 CustomData_set_layer_mask(data, type, maskindex);
820 DAG_object_flush_update(G.scene, OBACT, OB_RECALC_DATA);
822 if(type == CD_MTFACE)
823 BIF_undo_push("Delete UV Texture");
824 else if(type == CD_MCOL)
825 BIF_undo_push("Delete Vertex Color");
827 allqueue(REDRAWVIEW3D, 0);
828 allqueue(REDRAWIMAGE, 0);
829 allqueue(REDRAWBUTSEDIT, 0);
832 static int customdata_buttons(
833 uiBlock *block, Mesh *me, CustomData *data,
834 int type, int *activep, int *renderp, int *clonep, int *maskp,
835 int setevt, int setevt_rnd, int setevt_clone, int setevt_mask, int newevt,
836 char *label, char *shortlabel, char *browsetip, char *browsetip_rnd, char *browsetip_clone, char *browsetip_mask,
837 char *newtip, char *deltip, int x, int y)
839 CustomDataLayer *layer;
841 int i, count= CustomData_number_of_layers(data, type);
843 if(count >= MAX_MTFACE) {
844 uiDefBut(block, LABEL, 0, label, x,y,220,19, 0, 0.0, 0, 0, 0, "");
847 uiDefBut(block, LABEL, 0, label, x,y,140,19, 0, 0.0, 0, 0, 0, "");
848 uiBlockBeginAlign(block);
849 uiDefBut(block, BUT, newevt, "New", x+140,y,80,19, 0,0,0,0,0, newtip);
850 uiBlockEndAlign(block);
853 y -= (count)? 24: 19;
855 uiBlockBeginAlign(block);
856 for (count=1, i=0; i<data->totlayer; i++) {
857 layer= &data->layers[i];
859 if(layer->type == type) {
861 *activep= layer->active + 1;
862 *renderp= layer->active_rnd + 1;
863 if (clonep) *clonep= layer->active_clone + 1;
864 if (maskp) *maskp= layer->active_mask + 1;
867 uiDefIconButI(block, ROW, setevt, ICON_VIEW3D, x,y,25,19, activep, 1.0, count, 0, 0, browsetip);
868 uiDefIconButI(block, ROW, setevt_rnd, ICON_SCENE, x+25,y,25,19, renderp, 1.0, count, 0, 0, browsetip_rnd);
871 uiDefIconButI(block, ROW, setevt_clone, ICON_TEXTURE, x+50,y,25,19, clonep, 1.0, count, 0, 0, browsetip_clone);
876 uiDefIconButI(block, ROW, setevt_mask, ICON_PAINT, x+50+xi,y,25,19, maskp, 1.0, count, 0, 0, browsetip_mask);
880 but=uiDefBut(block, TEX, setevt, "", x+50+xi,y,145-xi,19, layer->name, 0.0, 31.0, 0, 0, label);
881 uiButSetFunc(but, verify_customdata_name_func, data, layer);
882 but= uiDefIconBut(block, BUT, B_NOP, VICON_X, x+195,y,25,19, NULL, 0.0, 0.0, 0.0, 0.0, deltip);
883 uiButSetFunc(but, delete_customdata_layer, me, layer);
890 uiBlockEndAlign(block);
895 static void editing_panel_mesh_type(Object *ob, Mesh *me)
903 block= uiNewBlock(&curarea->uiblocks, "editing_panel_mesh_type", UI_EMBOSS, UI_HELV, curarea->win);
904 if( uiNewPanel(curarea, block, "Mesh", "Editing", 320, 0, 318, 204)==0) return;
905 uiSetButLock(object_data_is_libdata(ob), ERROR_LIBDATA_MESSAGE);
907 uiBlockBeginAlign(block);
908 uiDefButBitS(block, TOG, ME_AUTOSMOOTH, REDRAWVIEW3D, "Auto Smooth",10,180,170,19, &me->flag, 0, 0, 0, 0, "Treats all set-smoothed faces with angles less than Degr: as 'smooth' during render");
909 uiDefButS(block, NUM, B_DIFF, "Degr:", 10,160,170,19, &me->smoothresh, 1, 80, 0, 0, "Defines maximum angle between face normals that 'Auto Smooth' will operate on");
910 uiBlockEndAlign(block);
914 uiBlockBeginAlign(block);
915 but= uiDefButBitC(block,TOG,RETOPO,B_NOP, "Retopo", 10,130,170,19, &G.scene->toolsettings->retopo_mode, 0,0,0,0, "Turn on the re-topology tool");
916 uiButSetFunc(but,retopo_toggle,ob,me);
917 if(G.scene->toolsettings->retopo_mode) {
918 but= uiDefButBitC(block,TOG,RETOPO_PAINT,B_NOP,"Paint", 10,110,55,19, &G.scene->toolsettings->retopo_mode,0,0,0,0, "Draw intersecting lines in the 3d view, ENTER creates quad or tri faces, wrapped onto other objects in the 3d view.");
919 uiButSetFunc(but,retopo_paint_toggle,ob,me);
920 but= uiDefBut(block,BUT,B_NOP,"Retopo All", 65,110,115,19, 0,0,0,0,0, "Apply the re-topology tool to all selected vertices");
921 uiButSetFunc(but,retopo_do_all_cb,ob,me);
923 uiBlockEndAlign(block);
926 uiBlockBeginAlign(block);
927 uiDefBut(block, BUT,B_DOCENTER, "Center", 10, 80, 65, 19, 0, 0, 0, 0, 0, "Shifts object data to be centered about object's origin");
928 uiDefBut(block, BUT,B_DOCENTERNEW, "Center New", 75, 80, 105, 19, 0, 0, 0, 0, 0, "Shifts object's origin to center of object data");
929 uiDefBut(block, BUT,B_DOCENTERCURSOR, "Center Cursor", 10, 60, 170, 19, 0, 0, 0, 0, 0, "Shifts object's origin to cursor location");
930 uiBlockEndAlign(block);
932 uiBlockBeginAlign(block);
933 uiDefButBitS(block, TOG, ME_TWOSIDED, REDRAWVIEW3D, "Double Sided", 10,30,170,19, &me->flag, 0, 0, 0, 0, "Render/display the mesh with double or single sided lighting");
934 uiDefButBitS(block, TOG, ME_NOPUNOFLIP, REDRAWVIEW3D, "No V.Normal Flip", 10,10,170,19, &me->flag, 0, 0, 0, 0, "Disables flipping of vertexnormals during render");
935 uiBlockEndAlign(block);
937 uiDefIDPoinBut(block, test_meshpoin_but, ID_ME, B_REDR, "TexMesh: ", 190,180,220,19, &me->texcomesh, "Derive texture coordinates from another mesh.");
939 if(me->msticky) val= 1.0; else val= 0.0;
940 uiDefBut(block, LABEL, 0, "Sticky", 190,155,140,19, 0, val, 0, 0, 0, "");
941 uiBlockBeginAlign(block);
942 if(me->msticky==NULL) {
943 uiDefBut(block, BUT, B_MAKESTICKY, "Make", 330,155, 80,19, 0, 0, 0, 0, 0, "Creates Sticky coordinates from the current camera view background picture");
945 else uiDefBut(block, BUT, B_DELSTICKY, "Delete", 330,155, 80,19, 0, 0, 0, 0, 0, "Deletes Sticky texture coordinates");
946 uiBlockEndAlign(block);
948 fdata= (G.obedit)? &G.editMesh->fdata: &me->fdata;
949 yco= customdata_buttons(block, me, fdata, CD_MTFACE, &acttface, &acttface_rnd, (G.f & G_TEXTUREPAINT ? &acttface_clone : NULL), (G.f & G_TEXTUREPAINT ? &acttface_mask : NULL),
950 B_SETTFACE, B_SETTFACE_RND, B_SETTFACE_CLONE, B_SETTFACE_MASK, B_NEWTFACE, "UV Texture", "UV Texture:",
951 "Set active UV texture", "Set rendering UV texture", "Set the layer used for texturepaint cloning", "Set the layer used for texturepaint masking", "Creates a new UV texture layer",
952 "Removes the current UV texture layer", 190, 130);
954 yco= customdata_buttons(block, me, fdata, CD_MCOL, &actmcol, &actmcol_rnd, NULL, NULL,
955 B_SETMCOL, B_SETMCOL_RND, B_NOP, B_NOP, B_NEWMCOL, "Vertex Color", "Vertex Color:",
956 "Sets active vertex color layer", "Sets rendering vertex color layer", "", "", "Creates a new vertex color layer",
957 "Removes the current vertex color layer", 190, yco-5);
960 uiNewPanelHeight(block, 204 - yco);
963 /* *************************** MODIFIERS ******************************** */
965 void do_modifier_panels(unsigned short event)
970 case B_MODIFIER_REDRAW:
971 allqueue(REDRAWBUTSEDIT, 0);
972 allqueue(REDRAWOOPS, 0);
975 case B_MODIFIER_RECALC:
976 allqueue(REDRAWBUTSEDIT, 0);
977 allqueue(REDRAWVIEW3D, 0);
978 allqueue(REDRAWIMAGE, 0);
979 allqueue(REDRAWOOPS, 0);
980 DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA);
981 object_handle_update(ob);
987 static void modifiers_add(void *ob_v, int type)
990 ModifierTypeInfo *mti = modifierType_getInfo(type);
992 if (mti->flags&eModifierTypeFlag_RequiresOriginalData) {
993 ModifierData *md = ob->modifiers.first;
995 while (md && modifierType_getInfo(md->type)->type==eModifierTypeType_OnlyDeform) {
999 BLI_insertlinkbefore(&ob->modifiers, md, modifier_new(type));
1001 BLI_addtail(&ob->modifiers, modifier_new(type));
1003 BIF_undo_push("Add modifier");
1006 typedef struct MenuEntry {
1011 static int menuEntry_compare_names(const void *entry1, const void *entry2)
1013 return strcmp(((MenuEntry *)entry1)->name, ((MenuEntry *)entry2)->name);
1016 static uiBlock *modifiers_add_menu(void *ob_v)
1022 MenuEntry entries[NUM_MODIFIER_TYPES];
1024 block= uiNewBlock(&curarea->uiblocks, "modifier_add_menu",
1025 UI_EMBOSSP, UI_HELV, curarea->win);
1026 uiBlockSetButmFunc(block, modifiers_add, ob);
1028 for (i=eModifierType_None+1; i<NUM_MODIFIER_TYPES; i++) {
1029 ModifierTypeInfo *mti = modifierType_getInfo(i);
1031 /* Only allow adding through appropriate other interfaces */
1032 if(ELEM3(i, eModifierType_Softbody, eModifierType_Hook, eModifierType_ParticleSystem)) continue;
1034 if(ELEM3(i, eModifierType_Cloth, eModifierType_Collision, eModifierType_Fluidsim)) continue;
1036 if((mti->flags&eModifierTypeFlag_AcceptsCVs) ||
1037 (ob->type==OB_MESH && (mti->flags&eModifierTypeFlag_AcceptsMesh))) {
1038 entries[numEntries].name = mti->name;
1039 entries[numEntries].ID = i;
1045 qsort(entries, numEntries, sizeof(*entries), menuEntry_compare_names);
1048 for(i = 0; i < numEntries; ++i)
1049 uiDefBut(block, BUTM, B_MODIFIER_RECALC, entries[i].name,
1050 0, yco -= 20, 160, 19, NULL, 0, 0, 1, entries[i].ID, "");
1052 uiTextBoundsBlock(block, 50);
1053 uiBlockSetDirection(block, UI_DOWN);
1058 static void modifiers_del(void *ob_v, void *md_v)
1063 /* It seems on rapid delete it is possible to
1064 * get called twice on same modifier, so make
1065 * sure it is in list.
1067 for (md=ob->modifiers.first; md; md=md->next)
1074 if(md->type==eModifierType_ParticleSystem){
1075 ParticleSystemModifierData *psmd=(ParticleSystemModifierData*)md;
1076 BLI_remlink(&ob->particlesystem, psmd->psys);
1077 psys_free(ob,psmd->psys);
1080 BLI_remlink(&ob->modifiers, md_v);
1082 modifier_free(md_v);
1084 BIF_undo_push("Del modifier");
1087 int mod_moveUp(void *ob_v, void *md_v)
1090 ModifierData *md = md_v;
1093 ModifierTypeInfo *mti = modifierType_getInfo(md->type);
1095 if (mti->type!=eModifierTypeType_OnlyDeform) {
1096 ModifierTypeInfo *nmti = modifierType_getInfo(md->prev->type);
1098 if (nmti->flags&eModifierTypeFlag_RequiresOriginalData)
1102 BLI_remlink(&ob->modifiers, md);
1103 BLI_insertlink(&ob->modifiers, md->prev->prev, md);
1109 static void modifiers_moveUp(void *ob_v, void *md_v)
1111 if( mod_moveUp( ob_v, md_v ) )
1112 error("Cannot move above a modifier requiring original data.");
1114 BIF_undo_push("Move modifier");
1117 int mod_moveDown(void *ob_v, void *md_v)
1120 ModifierData *md = md_v;
1123 ModifierTypeInfo *mti = modifierType_getInfo(md->type);
1125 if (mti->flags&eModifierTypeFlag_RequiresOriginalData) {
1126 ModifierTypeInfo *nmti = modifierType_getInfo(md->next->type);
1128 if (nmti->type!=eModifierTypeType_OnlyDeform)
1132 BLI_remlink(&ob->modifiers, md);
1133 BLI_insertlink(&ob->modifiers, md->next, md);
1139 static void modifiers_moveDown(void *ob_v, void *md_v)
1141 if( mod_moveDown( ob_v, md_v ) )
1142 error("Cannot move beyond a non-deforming modifier.");
1144 BIF_undo_push("Move modifier");
1147 static void modifier_testLatticeObj(char *name, ID **idpp)
1151 for (id= G.main->object.first; id; id= id->next) {
1152 if( strcmp(name, id->name+2)==0 ) {
1153 if (((Object *)id)->type != OB_LATTICE) {
1154 error ("Lattice deform object must be a lattice");
1164 static void modifier_testCurveObj(char *name, ID **idpp)
1168 for (id= G.main->object.first; id; id= id->next) {
1169 if( strcmp(name, id->name+2)==0 ) {
1170 if (((Object *)id)->type != OB_CURVE) {
1171 error ("Curve deform object must be a curve");
1181 static void modifier_testMeshObj(char *name, ID **idpp)
1185 for (id= G.main->object.first; id; id= id->next) {
1186 /* no boolean on its own object */
1187 if(id != (ID *)OBACT) {
1188 if( strcmp(name, id->name+2)==0 ) {
1189 if (((Object *)id)->type != OB_MESH) {
1190 error ("Boolean modifier object must be a mesh");
1201 static void modifier_testArmatureObj(char *name, ID **idpp)
1205 for (id= G.main->object.first; id; id= id->next) {
1206 if( strcmp(name, id->name+2)==0 ) {
1207 if (((Object *)id)->type != OB_ARMATURE) {
1208 error ("Armature deform object must be an armature");
1218 static void modifier_testTexture(char *name, ID **idpp)
1222 for(id = G.main->tex.first; id; id = id->next) {
1223 if(strcmp(name, id->name + 2) == 0) {
1225 /* texture gets user, objects not: delete object = clear modifier */
1233 #if 0 /* this is currently unused, but could be useful in the future */
1234 static void modifier_testMaterial(char *name, ID **idpp)
1238 for(id = G.main->mat.first; id; id = id->next) {
1239 if(strcmp(name, id->name + 2) == 0) {
1248 static void modifier_testImage(char *name, ID **idpp)
1252 for(id = G.main->image.first; id; id = id->next) {
1253 if(strcmp(name, id->name + 2) == 0) {
1261 /* autocomplete callback for ID buttons */
1262 void autocomplete_image(char *str, void *arg_v)
1264 /* search if str matches the beginning of an ID struct */
1266 AutoComplete *autocpl = autocomplete_begin(str, 22);
1269 for(id = G.main->image.first; id; id = id->next)
1270 autocomplete_do_name(autocpl, id->name+2);
1272 autocomplete_end(autocpl, str);
1276 /* autocomplete callback for ID buttons */
1277 void autocomplete_meshob(char *str, void *arg_v)
1279 /* search if str matches the beginning of an ID struct */
1281 AutoComplete *autocpl = autocomplete_begin(str, 22);
1284 for(id = G.main->object.first; id; id = id->next)
1285 if(((Object *)id)->type == OB_MESH)
1286 autocomplete_do_name(autocpl, id->name+2);
1288 autocomplete_end(autocpl, str);
1291 static void modifiers_convertParticles(void *obv, void *mdv)
1294 ModifierData *md = mdv;
1295 ParticleSystem *psys;
1296 ParticleCacheKey *key, **cache;
1297 ParticleSettings *part;
1302 int totvert=0, totedge=0, cvert=0;
1303 int totpart=0, totchild=0;
1305 if(md->type != eModifierType_ParticleSystem) return;
1307 if(G.f & G_PARTICLEEDIT) return;
1309 psys=((ParticleSystemModifierData *)md)->psys;
1312 if(part->draw_as == PART_DRAW_GR || part->draw_as == PART_DRAW_OB) {
1313 make_object_duplilist_real(NULL);
1316 if(part->draw_as != PART_DRAW_PATH || psys->pathcache == 0)
1319 totpart= psys->totcached;
1320 totchild= psys->totchildcache;
1322 if(totchild && (part->draw&PART_DRAW_PARENT)==0)
1326 cache= psys->pathcache;
1327 for(a=0; a<totpart; a++) {
1329 totvert+= key->steps+1;
1330 totedge+= key->steps;
1333 cache= psys->childcache;
1334 for(a=0; a<totchild; a++) {
1336 totvert+= key->steps+1;
1337 totedge+= key->steps;
1340 if(totvert==0) return;
1343 obn= add_object(OB_MESH);
1346 me->totvert= totvert;
1347 me->totedge= totedge;
1349 me->mvert= CustomData_add_layer(&me->vdata, CD_MVERT, CD_CALLOC, NULL, totvert);
1350 me->medge= CustomData_add_layer(&me->edata, CD_MEDGE, CD_CALLOC, NULL, totedge);
1351 me->mface= CustomData_add_layer(&me->fdata, CD_MFACE, CD_CALLOC, NULL, 0);
1356 /* copy coordinates */
1357 cache= psys->pathcache;
1358 for(a=0; a<totpart; a++) {
1361 for(k=0; k<=kmax; k++,key++,cvert++,mvert++) {
1362 VECCOPY(mvert->co,key->co);
1366 medge->flag= ME_EDGEDRAW|ME_EDGERENDER|ME_LOOSEEDGE;
1372 cache=psys->childcache;
1373 for(a=0; a<totchild; a++) {
1376 for(k=0; k<=kmax; k++,key++,cvert++,mvert++) {
1377 VECCOPY(mvert->co,key->co);
1381 medge->flag= ME_EDGEDRAW|ME_EDGERENDER|ME_LOOSEEDGE;
1388 DAG_scene_sort(G.scene);
1390 allqueue(REDRAWVIEW3D, 0);
1391 allqueue(REDRAWOOPS, 0);
1393 BIF_undo_push("Convert particles to mesh object(s).");
1396 static void modifiers_applyModifier(void *obv, void *mdv)
1399 ModifierData *md = mdv;
1401 Mesh *me = ob->data;
1405 error("Modifiers cannot be applied in editmode");
1407 } else if (((ID*) ob->data)->us>1) {
1408 error("Modifiers cannot be applied to multi-user data");
1412 if (md!=ob->modifiers.first) {
1413 if (!okee("Modifier is not first"))
1417 if (ob->type==OB_MESH) {
1418 if(me->mr && multires_modifier_warning()) {
1419 error("Modifier changes topology; cannot apply with multires active");
1423 error("Modifier cannot be applied to Mesh with Shape Keys");
1427 mesh_pmv_off(ob, me);
1429 dm = mesh_create_derived_for_modifier(ob, md);
1431 error("Modifier is disabled or returned error, skipping apply");
1440 else if (ELEM(ob->type, OB_CURVE, OB_SURF)) {
1441 ModifierTypeInfo *mti = modifierType_getInfo(md->type);
1442 Curve *cu = ob->data;
1444 float (*vertexCos)[3];
1446 if (!okee("Apply will only change CV points, not tesselated/bevel vertices"))
1449 if (!(md->mode&eModifierMode_Realtime) || (mti->isDisabled && mti->isDisabled(md))) {
1450 error("Modifier is disabled, skipping apply");
1454 vertexCos = curve_getVertexCos(cu, &cu->nurb, &numVerts);
1455 mti->deformVerts(md, ob, NULL, vertexCos, numVerts);
1456 curve_applyVertexCos(cu, &cu->nurb, vertexCos);
1460 MEM_freeN(vertexCos);
1462 DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA);
1465 error("Cannot apply modifier for this object type");
1470 BLI_remlink(&ob->modifiers, md);
1473 BIF_undo_push("Apply modifier");
1477 static void modifiers_copyModifier(void *ob_v, void *md_v)
1480 ModifierData *md = md_v;
1481 ModifierData *nmd = modifier_new(md->type);
1483 modifier_copyData(md, nmd);
1485 BLI_insertlink(&ob->modifiers, md, nmd);
1487 BIF_undo_push("Copy modifier");
1490 static void modifiers_setOnCage(void *ob_v, void *md_v)
1495 int i, cageIndex = modifiers_getCageIndex(ob, NULL );
1497 for( i = 0, md=ob->modifiers.first; md; ++i, md=md->next )
1499 if( i >= cageIndex )
1500 md->mode ^= eModifierMode_OnCage;
1505 static void modifiers_clearHookOffset(void *ob_v, void *md_v)
1508 ModifierData *md = md_v;
1509 HookModifierData *hmd = (HookModifierData*) md;
1512 Mat4Invert(hmd->object->imat, hmd->object->obmat);
1513 Mat4MulSerie(hmd->parentinv, hmd->object->imat, ob->obmat, NULL, NULL, NULL, NULL, NULL, NULL);
1514 BIF_undo_push("Clear hook offset");
1518 static void modifiers_cursorHookCenter(void *ob_v, void *md_v)
1521 ModifierData *md = md_v;
1522 HookModifierData *hmd = (HookModifierData*) md;
1525 float *curs = give_cursor();
1526 float bmat[3][3], imat[3][3];
1528 where_is_object(ob);
1530 Mat3CpyMat4(bmat, ob->obmat);
1531 Mat3Inv(imat, bmat);
1533 curs= give_cursor();
1534 hmd->cent[0]= curs[0]-ob->obmat[3][0];
1535 hmd->cent[1]= curs[1]-ob->obmat[3][1];
1536 hmd->cent[2]= curs[2]-ob->obmat[3][2];
1537 Mat3MulVecfl(imat, hmd->cent);
1539 BIF_undo_push("Hook cursor center");
1543 static void modifiers_selectHook(void *ob_v, void *md_v)
1545 ModifierData *md = md_v;
1546 HookModifierData *hmd = (HookModifierData*) md;
1551 static void modifiers_reassignHook(void *ob_v, void *md_v)
1553 ModifierData *md = md_v;
1554 HookModifierData *hmd = (HookModifierData*) md;
1556 int *indexar, tot, ok;
1559 ok= hook_getIndexArray(&tot, &indexar, name, cent);
1562 error("Requires selected vertices or active Vertex Group");
1565 MEM_freeN(hmd->indexar);
1568 VECCOPY(hmd->cent, cent);
1569 hmd->indexar = indexar;
1570 hmd->totindex = tot;
1574 static void modifiers_convertToReal(void *ob_v, void *md_v)
1577 ModifierData *md = md_v;
1578 ModifierData *nmd = modifier_new(md->type);
1580 modifier_copyData(md, nmd);
1581 nmd->mode &= ~eModifierMode_Virtual;
1583 BLI_addhead(&ob->modifiers, nmd);
1585 ob->partype = PAROBJECT;
1587 BIF_undo_push("Modifier convert to real");
1590 static void build_uvlayer_menu_vars(CustomData *data, char **menu_string,
1591 int *uvlayer_tmp, char *uvlayer_name)
1595 CustomDataLayer *layer
1596 = &data->layers[CustomData_get_layer_index(data, CD_MTFACE)];
1600 totuv = CustomData_number_of_layers(data, CD_MTFACE);
1602 *menu_string = MEM_callocN(sizeof(**menu_string) * (totuv * 38 + 10),
1604 sprintf(*menu_string, "UV Layer%%t");
1605 for(i = 0; i < totuv; i++) {
1606 /* assign first layer as uvlayer_name if uvlayer_name is null. */
1607 if(strcmp(layer->name, uvlayer_name) == 0) *uvlayer_tmp = i + 1;
1608 sprintf(strtmp, "|%s%%x%d", layer->name, i + 1);
1609 strcat(*menu_string, strtmp);
1613 /* there is no uvlayer defined, or else it was deleted. Assign active
1614 * layer, then recalc modifiers.
1616 if(*uvlayer_tmp == -1) {
1617 if(CustomData_get_active_layer_index(data, CD_MTFACE) != -1) {
1619 layer = data->layers;
1620 for(i = 0; i < CustomData_get_active_layer_index(data, CD_MTFACE);
1622 if(layer->type == CD_MTFACE) (*uvlayer_tmp)++;
1624 strcpy(uvlayer_name, layer->name);
1626 /* update the modifiers */
1627 do_modifier_panels(B_MODIFIER_RECALC);
1629 /* ok we have no uv layers, so make sure menu button knows that.*/
1635 void set_wave_uvlayer(void *arg1, void *arg2)
1637 WaveModifierData *wmd=arg1;
1638 CustomDataLayer *layer = arg2;
1640 /*check we have UV layers*/
1641 if (wmd->uvlayer_tmp < 1) return;
1642 layer = layer + (wmd->uvlayer_tmp-1);
1644 strcpy(wmd->uvlayer_name, layer->name);
1647 void set_displace_uvlayer(void *arg1, void *arg2)
1649 DisplaceModifierData *dmd=arg1;
1650 CustomDataLayer *layer = arg2;
1652 /*check we have UV layers*/
1653 if (dmd->uvlayer_tmp < 1) return;
1654 layer = layer + (dmd->uvlayer_tmp-1);
1656 strcpy(dmd->uvlayer_name, layer->name);
1659 void set_uvproject_uvlayer(void *arg1, void *arg2)
1661 UVProjectModifierData *umd=arg1;
1662 CustomDataLayer *layer = arg2;
1664 /*check we have UV layers*/
1665 if (umd->uvlayer_tmp < 1) return;
1666 layer = layer + (umd->uvlayer_tmp-1);
1668 strcpy(umd->uvlayer_name, layer->name);
1671 static void modifiers_bindMeshDeform(void *ob_v, void *md_v)
1673 MeshDeformModifierData *mmd = (MeshDeformModifierData*) md_v;
1674 Object *ob = (Object*)ob_v;
1677 if(mmd->bindweights) MEM_freeN(mmd->bindweights);
1678 if(mmd->bindcos) MEM_freeN(mmd->bindcos);
1679 if(mmd->dyngrid) MEM_freeN(mmd->dyngrid);
1680 if(mmd->dyninfluences) MEM_freeN(mmd->dyninfluences);
1681 if(mmd->dynverts) MEM_freeN(mmd->dynverts);
1682 mmd->bindweights= NULL;
1685 mmd->dyninfluences= NULL;
1686 mmd->dynverts= NULL;
1688 mmd->totcagevert= 0;
1689 mmd->totinfluence= 0;
1693 int mode= mmd->modifier.mode;
1695 /* force modifier to run, it will call binding routine */
1697 mmd->modifier.mode |= eModifierMode_Realtime;
1699 if(ob->type == OB_MESH) {
1700 dm= mesh_create_derived_view(ob, 0);
1703 else if(ob->type == OB_LATTICE) {
1704 lattice_calc_modifiers(ob);
1706 else if(ob->type==OB_MBALL) {
1707 makeDispListMBall(ob);
1709 else if(ELEM3(ob->type, OB_CURVE, OB_SURF, OB_FONT)) {
1710 makeDispListCurveTypes(ob, 0);
1714 mmd->modifier.mode= mode;
1718 void modifiers_explodeFacepa(void *arg1, void *arg2)
1720 ExplodeModifierData *emd=arg1;
1722 emd->flag |= eExplodeFlag_CalcFaces;
1725 void modifiers_explodeDelVg(void *arg1, void *arg2)
1727 ExplodeModifierData *emd=arg1;
1731 static int modifier_is_fluid_particles(ModifierData *md) {
1732 if(md->type == eModifierType_ParticleSystem) {
1733 if(((ParticleSystemModifierData *)md)->psys->part->type == PART_FLUID)
1738 static void draw_modifier(uiBlock *block, Object *ob, ModifierData *md, int *xco, int *yco, int index, int cageIndex, int lastCageIndex)
1740 ModifierTypeInfo *mti = modifierType_getInfo(md->type);
1742 int isVirtual = md->mode&eModifierMode_Virtual;
1743 int x = *xco, y = *yco, color = md->error?TH_REDALERT:TH_BUT_NEUTRAL;
1744 int editing = (G.obedit==ob);
1745 short height=26, width = 295, buttonWidth = width-120-10;
1748 /* rounded header */
1749 uiBlockSetCol(block, color);
1750 /* roundbox 4 free variables: corner-rounding, nop, roundbox type, shade */
1751 uiDefBut(block, ROUNDBOX, 0, "", x-10, y-4, width, 25, NULL, 7.0, 0.0,
1752 (!isVirtual && (md->mode&eModifierMode_Expanded))?3:15, 20, "");
1753 uiBlockSetCol(block, TH_AUTO);
1755 /* open/close icon */
1757 uiBlockSetEmboss(block, UI_EMBOSSN);
1758 uiDefIconButBitI(block, ICONTOG, eModifierMode_Expanded, B_MODIFIER_REDRAW, VICON_DISCLOSURE_TRI_RIGHT, x-10, y-2, 20, 20, &md->mode, 0.0, 0.0, 0.0, 0.0, "Collapse/Expand Modifier");
1761 uiBlockSetEmboss(block, UI_EMBOSS);
1764 sprintf(str, "%s parent deform", md->name);
1765 uiDefBut(block, LABEL, 0, str, x+10, y-1, width-110, 19, NULL, 0.0, 0.0, 0.0, 0.0, "Modifier name");
1767 but = uiDefBut(block, BUT, B_MODIFIER_RECALC, "Make Real", x+width-100, y, 80, 16, NULL, 0.0, 0.0, 0.0, 0.0, "Convert virtual modifier to a real modifier");
1768 uiButSetFunc(but, modifiers_convertToReal, ob, md);
1770 uiBlockBeginAlign(block);
1771 uiDefBut(block, TEX, B_MODIFIER_REDRAW, "", x+10, y-1, buttonWidth-60, 19, md->name, 0.0, sizeof(md->name)-1, 0.0, 0.0, "Modifier name");
1773 /* Softbody not allowed in this situation, enforce! */
1774 if ((md->type!=eModifierType_Softbody && md->type!=eModifierType_Collision) || !(ob->pd && ob->pd->deflect)) {
1775 uiDefIconButBitI(block, TOG, eModifierMode_Render, B_MODIFIER_RECALC, ICON_SCENE, x+10+buttonWidth-60, y-1, 19, 19,&md->mode, 0, 0, 1, 0, "Enable modifier during rendering");
1776 but= uiDefIconButBitI(block, TOG, eModifierMode_Realtime, B_MODIFIER_RECALC, VICON_VIEW3D, x+10+buttonWidth-40, y-1, 19, 19,&md->mode, 0, 0, 1, 0, "Enable modifier during interactive display");
1777 if (mti->flags&eModifierTypeFlag_SupportsEditmode) {
1778 uiDefIconButBitI(block, TOG, eModifierMode_Editmode, B_MODIFIER_RECALC, VICON_EDIT, x+10+buttonWidth-20, y-1, 19, 19,&md->mode, 0, 0, 1, 0, "Enable modifier during Editmode (only if enabled for display)");
1781 uiBlockEndAlign(block);
1783 uiBlockSetEmboss(block, UI_EMBOSSR);
1785 if (ob->type==OB_MESH && modifier_couldBeCage(md) && index<=lastCageIndex) {
1788 if (index==cageIndex) {
1789 color = TH_BUT_SETTING;
1790 icon = VICON_EDITMODE_HLT;
1791 } else if (index<cageIndex) {
1792 color = TH_BUT_NEUTRAL;
1793 icon = VICON_EDITMODE_DEHLT;
1795 color = TH_BUT_NEUTRAL;
1798 uiBlockSetCol(block, color);
1799 but = uiDefIconBut(block, BUT, B_MODIFIER_RECALC, icon, x+width-105, y, 16, 16, NULL, 0.0, 0.0, 0.0, 0.0, "Apply modifier to editing cage during Editmode");
1800 uiButSetFunc(but, modifiers_setOnCage, ob, md);
1801 uiBlockSetCol(block, TH_AUTO);
1804 uiBlockSetCol(block, TH_BUT_ACTION);
1806 but = uiDefIconBut(block, BUT, B_MODIFIER_RECALC, VICON_MOVE_UP, x+width-75, y, 16, 16, NULL, 0.0, 0.0, 0.0, 0.0, "Move modifier up in stack");
1807 uiButSetFunc(but, modifiers_moveUp, ob, md);
1809 but = uiDefIconBut(block, BUT, B_MODIFIER_RECALC, VICON_MOVE_DOWN, x+width-75+20, y, 16, 16, NULL, 0.0, 0.0, 0.0, 0.0, "Move modifier down in stack");
1810 uiButSetFunc(but, modifiers_moveDown, ob, md);
1812 uiBlockSetEmboss(block, UI_EMBOSSN);
1814 // deletion over the deflection panel
1815 // fluid particle modifier can't be deleted here
1816 if(md->type!=eModifierType_Fluidsim && md->type!=eModifierType_Collision && !modifier_is_fluid_particles(md))
1818 but = uiDefIconBut(block, BUT, B_MODIFIER_RECALC, VICON_X, x+width-70+40, y, 16, 16, NULL, 0.0, 0.0, 0.0, 0.0, "Delete modifier");
1819 uiButSetFunc(but, modifiers_del, ob, md);
1821 uiBlockSetCol(block, TH_AUTO);
1824 uiBlockSetEmboss(block, UI_EMBOSS);
1826 if (isVirtual || !(md->mode&eModifierMode_Expanded)) {
1830 int lx = x + width - 60 - 15;
1832 if (md->type==eModifierType_Subsurf) {
1834 } else if (md->type==eModifierType_Lattice) {
1836 } else if (md->type==eModifierType_Curve) {
1838 } else if (md->type==eModifierType_Build) {
1840 } else if (md->type==eModifierType_Mirror) {
1842 } else if (md->type==eModifierType_Bevel) {
1843 BevelModifierData *bmd = (BevelModifierData*) md;
1844 height = 105; /* height = 124; */
1845 if ((bmd->lim_flags & BME_BEVEL_ANGLE) || ((bmd->lim_flags & BME_BEVEL_WEIGHT) && !(bmd->flags & BME_BEVEL_VERT))) height += 19;
1846 } else if (md->type==eModifierType_EdgeSplit) {
1847 EdgeSplitModifierData *emd = (EdgeSplitModifierData*) md;
1849 if(emd->flags & MOD_EDGESPLIT_FROMANGLE) height += 19;
1850 } else if (md->type==eModifierType_Displace) {
1851 DisplaceModifierData *dmd = (DisplaceModifierData *)md;
1853 if(dmd->texmapping == MOD_DISP_MAP_OBJECT ||
1854 dmd->texmapping == MOD_DISP_MAP_UV)
1856 } else if (md->type==eModifierType_UVProject) {
1857 height = 114 + ((UVProjectModifierData *)md)->num_projectors * 19;
1858 } else if (md->type==eModifierType_Decimate) {
1860 } else if (md->type==eModifierType_Smooth) {
1862 } else if (md->type==eModifierType_Cast) {
1864 } else if (md->type==eModifierType_Wave) {
1865 WaveModifierData *wmd = (WaveModifierData *)md;
1867 if(wmd->texmapping == MOD_WAV_MAP_OBJECT ||
1868 wmd->texmapping == MOD_WAV_MAP_UV)
1870 if(wmd->flag & MOD_WAVE_NORM)
1872 } else if (md->type==eModifierType_Armature) {
1874 } else if (md->type==eModifierType_Hook) {
1875 HookModifierData *hmd = (HookModifierData*) md;
1879 if(hmd->indexar==NULL)
1881 } else if (md->type==eModifierType_Softbody) {
1883 } else if (md->type==eModifierType_Cloth) {
1885 } else if (md->type==eModifierType_Collision) {
1887 } else if (md->type==eModifierType_Fluidsim) {
1889 } else if (md->type==eModifierType_Boolean) {
1891 } else if (md->type==eModifierType_Array) {
1893 } else if (md->type==eModifierType_MeshDeform) {
1894 MeshDeformModifierData *mmd= (MeshDeformModifierData*)md;
1895 height = (mmd->bindcos)? 73: 93;
1896 } else if (md->type==eModifierType_ParticleSystem) {
1898 } else if (md->type==eModifierType_ParticleInstance) {
1900 } else if (md->type==eModifierType_Explode) {
1902 } else if (md->type==eModifierType_Shrinkwrap) {
1903 ShrinkwrapModifierData *smd = (ShrinkwrapModifierData*) md;
1905 if (smd->shrinkType == MOD_SHRINKWRAP_PROJECT)
1908 if(smd->projAxis == 0) height += 19;
1910 else if (smd->shrinkType == MOD_SHRINKWRAP_NEAREST_SURFACE)
1912 } else if (md->type == eModifierType_Mask) {
1914 } else if (md->type==eModifierType_SimpleDeform) {
1915 SimpleDeformModifierData *smd = (SimpleDeformModifierData*) md;
1917 if(smd->origin != NULL) height += 19;
1918 if(smd->mode == MOD_SIMPLEDEFORM_MODE_STRETCH
1919 || smd->mode == MOD_SIMPLEDEFORM_MODE_TAPER )
1922 /* roundbox 4 free variables: corner-rounding, nop, roundbox type, shade */
1923 uiDefBut(block, ROUNDBOX, 0, "", x-10, y-height-2, width, height-2, NULL, 5.0, 0.0, 12, 40, "");
1927 if (!isVirtual && (md->type!=eModifierType_Collision)) {
1928 uiSetButLock(object_data_is_libdata(ob), ERROR_LIBDATA_MESSAGE); /* only here obdata, the rest of modifiers is ob level */
1930 uiBlockBeginAlign(block);
1931 if (md->type==eModifierType_ParticleSystem) {
1932 ParticleSystem *psys;
1933 psys= ((ParticleSystemModifierData *)md)->psys;
1935 if(!(G.f & G_PARTICLEEDIT)) {
1936 if(ELEM3(psys->part->draw_as, PART_DRAW_PATH, PART_DRAW_GR, PART_DRAW_OB) && psys->pathcache) {
1937 but = uiDefBut(block, BUT, B_MODIFIER_RECALC, "Convert", lx,(cy-=19),60,19, 0, 0, 0, 0, 0, "Convert the current particles to a mesh object");
1938 uiButSetFunc(but, modifiers_convertParticles, ob, md);
1943 but = uiDefBut(block, BUT, B_MODIFIER_RECALC, "Apply", lx,(cy-=19),60,19, 0, 0, 0, 0, 0, "Apply the current modifier and remove from the stack");
1944 uiButSetFunc(but, modifiers_applyModifier, ob, md);
1947 if (md->type!=eModifierType_Fluidsim && md->type!=eModifierType_Softbody && md->type!=eModifierType_ParticleSystem && (md->type!=eModifierType_Cloth)) {
1948 but = uiDefBut(block, BUT, B_MODIFIER_RECALC, "Copy", lx,(cy-=19),60,19, 0, 0, 0, 0, 0, "Duplicate the current modifier at the same position in the stack");
1949 uiButSetFunc(but, modifiers_copyModifier, ob, md);
1951 uiBlockEndAlign(block);
1953 uiSetButLock(ob && ob->id.lib, ERROR_LIBDATA_MESSAGE);
1958 uiBlockBeginAlign(block);
1959 if (md->type==eModifierType_Subsurf) {
1960 SubsurfModifierData *smd = (SubsurfModifierData*) md;
1961 char subsurfmenu[]="Subsurf Type%t|Catmull-Clark%x0|Simple Subdiv.%x1";
1962 uiDefButS(block, MENU, B_MODIFIER_RECALC, subsurfmenu, lx,(cy-=19),buttonWidth,19, &smd->subdivType, 0, 0, 0, 0, "Selects type of subdivision algorithm.");
1963 uiDefButS(block, NUM, B_MODIFIER_RECALC, "Levels:", lx, (cy-=19), buttonWidth,19, &smd->levels, 1, 6, 0, 0, "Number subdivisions to perform");
1964 uiDefButS(block, NUM, B_MODIFIER_REDRAW, "Render Levels:", lx, (cy-=19), buttonWidth,19, &smd->renderLevels, 1, 6, 0, 0, "Number subdivisions to perform when rendering");
1966 /* Disabled until non-EM DerivedMesh implementation is complete */
1969 uiDefButBitS(block, TOG, eSubsurfModifierFlag_Incremental, B_MODIFIER_RECALC, "Incremental", lx, (cy-=19),90,19,&smd->flags, 0, 0, 0, 0, "Use incremental calculation, even outside of mesh mode");
1970 uiDefButBitS(block, TOG, eSubsurfModifierFlag_DebugIncr, B_MODIFIER_RECALC, "Debug", lx+90, cy,buttonWidth-90,19,&smd->flags, 0, 0, 0, 0, "Visualize the subsurf incremental calculation, for debugging effect of other modifiers");
1973 uiDefButBitS(block, TOG, eSubsurfModifierFlag_ControlEdges, B_MODIFIER_RECALC, "Optimal Draw", lx, (cy-=19), buttonWidth,19,&smd->flags, 0, 0, 0, 0, "Skip drawing/rendering of interior subdivided edges");
1974 uiDefButBitS(block, TOG, eSubsurfModifierFlag_SubsurfUv, B_MODIFIER_RECALC, "Subsurf UV", lx, (cy-=19),buttonWidth,19,&smd->flags, 0, 0, 0, 0, "Use subsurf to subdivide UVs");
1975 } else if (md->type==eModifierType_Lattice) {
1976 LatticeModifierData *lmd = (LatticeModifierData*) md;
1977 uiDefIDPoinBut(block, modifier_testLatticeObj, ID_OB, B_CHANGEDEP, "Ob: ", lx, (cy-=19), buttonWidth,19, &lmd->object, "Lattice object to deform with");
1978 but=uiDefBut(block, TEX, B_MODIFIER_RECALC, "VGroup: ", lx, (cy-=19), buttonWidth,19, &lmd->name, 0.0, 31.0, 0, 0, "Vertex Group name");
1979 uiButSetCompleteFunc(but, autocomplete_vgroup, (void *)ob);
1980 } else if (md->type==eModifierType_Curve) {
1981 CurveModifierData *cmd = (CurveModifierData*) md;
1982 uiDefIDPoinBut(block, modifier_testCurveObj, ID_OB, B_CHANGEDEP, "Ob: ", lx, (cy-=19), buttonWidth,19, &cmd->object, "Curve object to deform with");
1983 but=uiDefBut(block, TEX, B_MODIFIER_RECALC, "VGroup: ", lx, (cy-=19), buttonWidth,19, &cmd->name, 0.0, 31.0, 0, 0, "Vertex Group name");
1984 uiButSetCompleteFunc(but, autocomplete_vgroup, (void *)ob);
1986 uiDefButS(block, ROW,B_MODIFIER_RECALC,"X", lx, (cy-=19), 19,19, &cmd->defaxis, 12.0, MOD_CURVE_POSX, 0, 0, "The axis that the curve deforms along");
1987 uiDefButS(block, ROW,B_MODIFIER_RECALC,"Y", (lx+buttonWidth/6), cy, 19,19, &cmd->defaxis, 12.0, MOD_CURVE_POSY, 0, 0, "The axis that the curve deforms along");
1988 uiDefButS(block, ROW,B_MODIFIER_RECALC,"Z", (lx+2*buttonWidth/6), cy, 19,19, &cmd->defaxis, 12.0, MOD_CURVE_POSZ, 0, 0, "The axis that the curve deforms along");
1989 uiDefButS(block, ROW,B_MODIFIER_RECALC,"-X", (lx+3*buttonWidth/6), cy, 24,19, &cmd->defaxis, 12.0, MOD_CURVE_NEGX, 0, 0, "The axis that the curve deforms along");
1990 uiDefButS(block, ROW,B_MODIFIER_RECALC,"-Y", (lx+4*buttonWidth/6), cy, 24,19, &cmd->defaxis, 12.0, MOD_CURVE_NEGY, 0, 0, "The axis that the curve deforms along");
1991 uiDefButS(block, ROW,B_MODIFIER_RECALC,"-Z", (lx+buttonWidth-buttonWidth/6), cy, 24,19, &cmd->defaxis, 12.0, MOD_CURVE_NEGZ, 0, 0, "The axis that the curve deforms along");
1992 } else if (md->type==eModifierType_Build) {
1993 BuildModifierData *bmd = (BuildModifierData*) md;
1994 uiDefButF(block, NUM, B_MODIFIER_RECALC, "Start:", lx, (cy-=19), buttonWidth,19, &bmd->start, 1.0, MAXFRAMEF, 100, 0, "Specify the start frame of the effect");
1995 uiDefButF(block, NUM, B_MODIFIER_RECALC, "Length:", lx, (cy-=19), buttonWidth,19, &bmd->length, 1.0, MAXFRAMEF, 100, 0, "Specify the total time the build effect requires");
1996 uiDefButI(block, TOG, B_MODIFIER_RECALC, "Randomize", lx, (cy-=19), buttonWidth,19, &bmd->randomize, 0, 0, 1, 0, "Randomize the faces or edges during build.");
1997 uiDefButI(block, NUM, B_MODIFIER_RECALC, "Seed:", lx, (cy-=19), buttonWidth,19, &bmd->seed, 1.0, MAXFRAMEF, 100, 0, "Specify the seed for random if used.");
1998 } else if (md->type==eModifierType_Mirror) {
1999 MirrorModifierData *mmd = (MirrorModifierData*) md;
2000 uiDefButF(block, NUM, B_MODIFIER_RECALC, "Merge Limit:", lx, (cy-=19), buttonWidth,19, &mmd->tolerance, 0.0, 1.0, 10, 10, "Distance from axis within which mirrored vertices are merged");
2001 uiDefButBitS(block, TOG, MOD_MIR_AXIS_X, B_MODIFIER_RECALC, "X", lx,(cy-=19),20,19, &mmd->flag, 0, 0, 0, 0, "Enable X axis mirror");
2002 uiDefButBitS(block, TOG, MOD_MIR_AXIS_Y, B_MODIFIER_RECALC, "Y", lx+20,cy,20,19, &mmd->flag, 0, 0, 0, 0, "Enable Y axis mirror");
2003 uiDefButBitS(block, TOG, MOD_MIR_AXIS_Z, B_MODIFIER_RECALC, "Z", lx+40,cy,20,19, &mmd->flag, 0, 0, 0, 0, "Enable Z axis mirror");
2004 uiDefButBitS(block, TOG, MOD_MIR_CLIPPING, B_MODIFIER_RECALC, "Do Clipping", lx+60, cy, buttonWidth-60,19, &mmd->flag, 1, 2, 0, 0, "Prevents during Transform vertices to go through Mirror");
2005 uiDefButBitS(block, TOG, MOD_MIR_VGROUP, B_MODIFIER_RECALC, "Mirror Vgroups", lx, (cy-=19), buttonWidth,19, &mmd->flag, 1, 2, 0, 0, "Mirror vertex groups (e.g. .R->.L)");
2006 uiDefButBitS(block, TOG, MOD_MIR_MIRROR_U, B_MODIFIER_RECALC,
2008 lx, (cy-=19), buttonWidth/2, 19,
2009 &mmd->flag, 0, 0, 0, 0,
2010 "Mirror the U texture coordinate around "
2012 uiDefButBitS(block, TOG, MOD_MIR_MIRROR_V, B_MODIFIER_RECALC,
2014 lx + buttonWidth/2 + 1, cy, buttonWidth/2, 19,
2015 &mmd->flag, 0, 0, 0, 0,
2016 "Mirror the V texture coordinate around "
2018 uiDefIDPoinBut(block, test_obpoin_but, ID_OB, B_CHANGEDEP,
2019 "Ob: ", lx, (cy -= 19), buttonWidth, 19,
2021 "Object to use as mirror");
2022 } else if (md->type==eModifierType_Bevel) {
2023 BevelModifierData *bmd = (BevelModifierData*) md;
2024 /*uiDefButS(block, ROW, B_MODIFIER_RECALC, "Distance",
2025 lx, (cy -= 19), (buttonWidth/2), 19, &bmd->val_flags,
2027 "Interpret bevel value as a constant distance from each edge");
2028 uiDefButS(block, ROW, B_MODIFIER_RECALC, "Radius",
2029 (lx+buttonWidth/2), cy, (buttonWidth - buttonWidth/2), 19, &bmd->val_flags,
2030 11.0, BME_BEVEL_RADIUS, 0, 0,
2031 "Interpret bevel value as a radius - smaller angles will be beveled more");*/
2032 uiBlockBeginAlign(block);
2033 uiDefButF(block, NUM, B_MODIFIER_RECALC, "Width: ",
2034 lx, (cy -= 19), buttonWidth, 19, &bmd->value,
2036 "Bevel value/amount");
2037 /*uiDefButI(block, NUM, B_MODIFIER_RECALC, "Recurs",
2038 lx, (cy -= 19), buttonWidth, 19, &bmd->res,
2040 "Number of times to bevel");*/
2041 uiDefButBitS(block, TOG, BME_BEVEL_VERT,
2042 B_MODIFIER_RECALC, "Only Vertices",
2043 lx, (cy -= 19), buttonWidth, 19,
2044 &bmd->flags, 0, 0, 0, 0,
2045 "Bevel only verts/corners; not edges");
2046 uiBlockEndAlign(block);
2048 uiDefBut(block, LABEL, 1, "Limit using:", lx, (cy-=25), buttonWidth,19, NULL, 0.0, 0.0, 0, 0, "");
2049 uiBlockBeginAlign(block);
2050 uiDefButS(block, ROW, B_MODIFIER_RECALC, "None",
2051 lx, (cy -= 19), (buttonWidth/3), 19, &bmd->lim_flags,
2053 "Bevel the entire mesh by a constant amount");
2054 uiDefButS(block, ROW, B_MODIFIER_RECALC, "Angle",
2055 (lx+buttonWidth/3), cy, (buttonWidth/3), 19, &bmd->lim_flags,
2056 12.0, BME_BEVEL_ANGLE, 0, 0,
2057 "Only bevel edges with sharp enough angles between faces");
2058 uiDefButS(block, ROW, B_MODIFIER_RECALC, "BevWeight",
2059 lx+(2*buttonWidth/3), cy, buttonWidth-2*(buttonWidth/3), 19, &bmd->lim_flags,
2060 12.0, BME_BEVEL_WEIGHT, 0, 0,
2061 "Use bevel weights to determine how much bevel is applied; apply them separately in vert/edge select mode");
2062 if ((bmd->lim_flags & BME_BEVEL_WEIGHT) && !(bmd->flags & BME_BEVEL_VERT)) {
2063 uiDefButS(block, ROW, B_MODIFIER_RECALC, "Min",
2064 lx, (cy -= 19), (buttonWidth/3), 19, &bmd->e_flags,
2065 13.0, BME_BEVEL_EMIN, 0, 0,
2066 "The sharpest edge's weight is used when weighting a vert");
2067 uiDefButS(block, ROW, B_MODIFIER_RECALC, "Average",
2068 (lx+buttonWidth/3), cy, (buttonWidth/3), 19, &bmd->e_flags,
2070 "The edge weights are averaged when weighting a vert");
2071 uiDefButS(block, ROW, B_MODIFIER_RECALC, "Max",
2072 (lx+2*(buttonWidth/3)), cy, buttonWidth-2*(buttonWidth/3), 19, &bmd->e_flags,
2073 13.0, BME_BEVEL_EMAX, 0, 0,
2074 "The largest edge's wieght is used when weighting a vert");
2076 else if (bmd->lim_flags & BME_BEVEL_ANGLE) {
2077 uiDefButF(block, NUM, B_MODIFIER_RECALC, "Angle:",
2078 lx, (cy -= 19), buttonWidth, 19, &bmd->bevel_angle,
2080 "Angle above which to bevel edges");
2082 } else if (md->type==eModifierType_EdgeSplit) {
2083 EdgeSplitModifierData *emd = (EdgeSplitModifierData*) md;
2084 uiDefButBitI(block, TOG, MOD_EDGESPLIT_FROMANGLE,
2085 B_MODIFIER_RECALC, "From Edge Angle",
2086 lx, (cy -= 19), buttonWidth, 19,
2087 &emd->flags, 0, 0, 0, 0,
2088 "Split edges with high angle between faces");
2089 if(emd->flags & MOD_EDGESPLIT_FROMANGLE) {
2090 uiDefButF(block, NUM, B_MODIFIER_RECALC, "Split Angle:",
2091 lx, (cy -= 19), buttonWidth, 19, &emd->split_angle,
2093 "Angle above which to split edges");
2095 uiDefButBitI(block, TOG, MOD_EDGESPLIT_FROMFLAG,
2096 B_MODIFIER_RECALC, "From Marked As Sharp",
2097 lx, (cy -= 19), buttonWidth, 19,
2098 &emd->flags, 0, 0, 0, 0,
2099 "Split edges that are marked as sharp");
2100 } else if (md->type==eModifierType_Displace) {
2101 DisplaceModifierData *dmd = (DisplaceModifierData*) md;
2102 but = uiDefBut(block, TEX, B_MODIFIER_RECALC, "VGroup: ",
2103 lx, (cy -= 19), buttonWidth, 19,
2104 &dmd->defgrp_name, 0.0, 31.0, 0, 0,
2105 "Name of vertex group to displace"
2106 " (displace whole mesh if blank)");
2107 uiButSetCompleteFunc(but, autocomplete_vgroup, (void *)ob);
2108 uiDefIDPoinBut(block, modifier_testTexture, ID_TE, B_CHANGEDEP,
2109 "Texture: ", lx, (cy -= 19), buttonWidth, 19,
2111 "Texture to use as displacement input");
2112 uiDefButF(block, NUM, B_MODIFIER_RECALC, "Midlevel:",
2113 lx, (cy -= 19), buttonWidth, 19, &dmd->midlevel,
2115 "Material value that gives no displacement");
2116 uiDefButF(block, NUM, B_MODIFIER_RECALC, "Strength:",
2117 lx, (cy -= 19), buttonWidth, 19, &dmd->strength,
2118 -1000, 1000, 10, 0.1,
2119 "Strength of displacement");
2120 sprintf(str, "Direction%%t|Normal%%x%d|RGB -> XYZ%%x%d|"
2121 "Z%%x%d|Y%%x%d|X%%x%d",
2122 MOD_DISP_DIR_NOR, MOD_DISP_DIR_RGB_XYZ,
2123 MOD_DISP_DIR_Z, MOD_DISP_DIR_Y, MOD_DISP_DIR_X);
2124 uiDefButI(block, MENU, B_MODIFIER_RECALC, str,
2125 lx, (cy -= 19), buttonWidth, 19, &dmd->direction,
2126 0.0, 1.0, 0, 0, "Displace direction");
2127 sprintf(str, "Texture Coordinates%%t"
2128 "|Local%%x%d|Global%%x%d|Object%%x%d|UV%%x%d",
2129 MOD_DISP_MAP_LOCAL, MOD_DISP_MAP_GLOBAL,
2130 MOD_DISP_MAP_OBJECT, MOD_DISP_MAP_UV);
2131 uiDefButI(block, MENU, B_MODIFIER_RECALC, str,
2132 lx, (cy -= 19), buttonWidth, 19, &dmd->texmapping,
2134 "Texture coordinates used for displacement input");
2135 if (dmd->texmapping == MOD_DISP_MAP_UV) {
2138 CustomData *fdata = G.obedit ? &G.editMesh->fdata
2139 : &((Mesh*)ob->data)->fdata;
2140 build_uvlayer_menu_vars(fdata, &strtmp, &dmd->uvlayer_tmp,
2142 but = uiDefButI(block, MENU, B_MODIFIER_RECALC, strtmp,
2143 lx, (cy -= 19), buttonWidth, 19, &dmd->uvlayer_tmp,
2144 0.0, 1.0, 0, 0, "Set the UV layer to use");
2146 i = CustomData_get_layer_index(fdata, CD_MTFACE);
2147 uiButSetFunc(but, set_displace_uvlayer, dmd,
2150 if(dmd->texmapping == MOD_DISP_MAP_OBJECT) {
2151 uiDefIDPoinBut(block, test_obpoin_but, ID_OB, B_CHANGEDEP,
2152 "Ob: ", lx, (cy -= 19), buttonWidth, 19,
2154 "Object to get texture coordinates from");
2156 } else if (md->type==eModifierType_UVProject) {
2157 UVProjectModifierData *umd = (UVProjectModifierData *) md;
2160 CustomData *fdata = G.obedit ? &G.editMesh->fdata
2161 : &((Mesh*)ob->data)->fdata;
2162 build_uvlayer_menu_vars(fdata, &strtmp, &umd->uvlayer_tmp,
2164 but = uiDefButI(block, MENU, B_MODIFIER_RECALC, strtmp,
2165 lx, (cy -= 19), buttonWidth, 19, &umd->uvlayer_tmp,
2166 0.0, 1.0, 0, 0, "Set the UV layer to use");
2167 i = CustomData_get_layer_index(fdata, CD_MTFACE);
2168 uiButSetFunc(but, set_uvproject_uvlayer, umd, &fdata->layers[i]);
2170 uiDefButF(block, NUM, B_MODIFIER_RECALC, "AspX:",
2171 lx, (cy -= 19), buttonWidth / 2, 19, &umd->aspectx,
2173 "Horizontal Aspect Ratio");
2174 uiDefButF(block, NUM, B_MODIFIER_RECALC, "AspY:",
2175 lx + (buttonWidth / 2) + 1, cy, buttonWidth / 2, 19,
2178 "Vertical Aspect Ratio");
2179 uiDefButI(block, NUM, B_MODIFIER_RECALC, "Projectors:",
2180 lx, (cy -= 19), buttonWidth, 19, &umd->num_projectors,
2181 1, MOD_UVPROJECT_MAXPROJECTORS, 0, 0,
2182 "Number of objects to use as projectors");
2183 for(i = 0; i < umd->num_projectors; ++i) {
2184 uiDefIDPoinBut(block, test_obpoin_but, ID_OB, B_CHANGEDEP,
2185 "Ob: ", lx, (cy -= 19), buttonWidth, 19,
2186 &umd->projectors[i],
2187 "Object to use as projector");
2189 uiDefIDPoinBut(block, modifier_testImage, ID_IM, B_CHANGEDEP,
2190 "Image: ", lx, (cy -= 19), buttonWidth, 19,
2192 "Image to project (only faces with this image "
2194 uiButSetCompleteFunc(but, autocomplete_image, (void *)ob);
2195 uiDefButBitI(block, TOG, MOD_UVPROJECT_OVERRIDEIMAGE,
2196 B_MODIFIER_RECALC, "Override Image",
2197 lx, (cy -= 19), buttonWidth, 19,
2198 &umd->flags, 0, 0, 0, 0,
2199 "Override faces' current images with the "
2201 } else if (md->type==eModifierType_Decimate) {
2202 DecimateModifierData *dmd = (DecimateModifierData*) md;
2203 uiDefButF(block, NUM, B_MODIFIER_RECALC, "Ratio:", lx,(cy-=19),buttonWidth,19, &dmd->percent, 0.0, 1.0, 10, 0, "Defines the percentage of triangles to reduce to");
2204 sprintf(str, "Face Count: %d", dmd->faceCount);
2205 uiDefBut(block, LABEL, 1, str, lx, (cy-=19), 160,19, NULL, 0.0, 0.0, 0, 0, "Displays the current number of faces in the decimated mesh");
2206 } else if (md->type==eModifierType_Mask) {
2207 MaskModifierData *mmd = (MaskModifierData *)md;
2209 sprintf(str, "Mask Mode%%t|Vertex Group%%x%d|Selected Bones%%x%d|",
2210 MOD_MASK_MODE_VGROUP,MOD_MASK_MODE_ARM);
2211 uiDefButI(block, MENU, B_MODIFIER_RECALC, str,
2212 lx, (cy -= 19), buttonWidth, 19, &mmd->mode,
2213 0.0, 1.0, 0, 0, "How masking region is defined");
2215 if (mmd->mode == MOD_MASK_MODE_ARM) {
2216 uiDefIDPoinBut(block, modifier_testArmatureObj, ID_OB, B_CHANGEDEP,
2217 "Ob: ", lx, (cy -= 19), buttonWidth, 19, &mmd->ob_arm,
2218 "Armature to use as source of bones to mask");
2221 but=uiDefBut(block, TEX, B_MODIFIER_RECALC, "VGroup: ",
2222 lx, (cy-=19), buttonWidth, 19, &mmd->vgroup,
2223 0.0, 31.0, 0, 0, "Vertex Group name");
2224 uiButSetCompleteFunc(but, autocomplete_vgroup, (void *)ob);
2227 uiDefButBitI(block, TOG, MOD_MASK_INV, B_MODIFIER_RECALC, "Inverse",
2228 lx, (cy-=19), buttonWidth, 19, &mmd->flag,
2229 0, 0, 0, 0, "Use vertices that are not part of region defined");
2230 } else if (md->type==eModifierType_Smooth) {
2231 SmoothModifierData *smd = (SmoothModifierData*) md;
2233 uiDefButBitS(block, TOG, MOD_SMOOTH_X, B_MODIFIER_RECALC, "X", lx,(cy-=19),45,19, &smd->flag, 0, 0, 0, 0, "Enable X axis smoothing");
2234 uiDefButBitS(block, TOG, MOD_SMOOTH_Y, B_MODIFIER_RECALC, "Y", lx+45,cy,45,19, &smd->flag, 0, 0, 0, 0, "Enable Y axis smoothing");
2235 uiDefButBitS(block, TOG, MOD_SMOOTH_Z, B_MODIFIER_RECALC, "Z", lx+90,cy,45,19, &smd->flag, 0, 0, 0, 0, "Enable Z axis smoothing");
2237 uiDefButF(block, NUM, B_MODIFIER_RECALC, "Factor:", lx,(cy-=19),buttonWidth, 19, &smd->fac, -10.0, 10.0, 0.5, 0, "Define the amount of smoothing, from 0.0 to 1.0 (lower / higher values can deform the mesh)");
2238 uiDefButS(block, NUM, B_MODIFIER_RECALC, "Repeat:", lx,(cy-=19),buttonWidth, 19, &smd->repeat, 0.0, 30.0, 1, 0, "Number of smoothing iterations");
2239 but=uiDefBut(block, TEX, B_MODIFIER_RECALC, "VGroup: ", lx, (cy-=19), buttonWidth,19, &smd->defgrp_name, 0.0, 31.0, 0, 0, "Vertex Group name to define which vertices are affected");
2240 } else if (md->type==eModifierType_Cast) {
2241 CastModifierData *cmd = (CastModifierData*) md;
2243 char casttypemenu[]="Projection Type%t|Sphere%x0|Cylinder%x1|Cuboid%x2";
2244 uiDefButS(block, MENU, B_MODIFIER_RECALC, casttypemenu, lx,(cy-=19),buttonWidth - 30,19, &cmd->type, 0, 0, 0, 0, "Projection type to apply");
2245 uiDefButBitS(block, TOG, MOD_CAST_X, B_MODIFIER_RECALC, "X", lx,(cy-=19),45,19, &cmd->flag, 0, 0, 0, 0, "Enable (local) X axis deformation");
2246 uiDefButBitS(block, TOG, MOD_CAST_Y, B_MODIFIER_RECALC, "Y", lx+45,cy,45,19, &cmd->flag, 0, 0, 0, 0, "Enable (local) Y axis deformation");
2247 if (cmd->type != MOD_CAST_TYPE_CYLINDER) {
2248 uiDefButBitS(block, TOG, MOD_CAST_Z, B_MODIFIER_RECALC, "Z", lx+90,cy,45,19, &cmd->flag, 0, 0, 0, 0, "Enable (local) Z axis deformation");
2250 uiDefButF(block, NUM, B_MODIFIER_RECALC, "Factor:", lx,(cy-=19),buttonWidth, 19, &cmd->fac, -10.0, 10.0, 5, 0, "Define the amount of deformation");
2251 uiDefButF(block, NUM, B_MODIFIER_RECALC, "Radius:", lx,(cy-=19),buttonWidth, 19, &cmd->radius, 0.0, 100.0, 10.0, 0, "Only deform vertices within this distance from the center of the effect (leave as 0 for infinite)");
2252 uiDefButF(block, NUM, B_MODIFIER_RECALC, "Size:", lx,(cy-=19),buttonWidth, 19, &cmd->size, 0.0, 100.0, 10.0, 0, "Size of projection shape (leave as 0 for auto)");
2253 uiDefButBitS(block, TOG, MOD_CAST_SIZE_FROM_RADIUS, B_MODIFIER_RECALC, "From radius", lx+buttonWidth,cy,80,19, &cmd->flag, 0, 0, 0, 0, "Use radius as size of projection shape (0 = auto)");
2254 if (ob->type == OB_MESH) {
2255 but=uiDefBut(block, TEX, B_MODIFIER_RECALC, "VGroup: ", lx, (cy-=19), buttonWidth,19, &cmd->defgrp_name, 0.0, 31.0, 0, 0, "Vertex Group name to define which vertices are affected");
2257 uiDefIDPoinBut(block, test_obpoin_but, ID_OB, B_CHANGEDEP, "Ob: ", lx,(cy-=19), buttonWidth,19, &cmd->object, "Control object: if available, its location determines the center of the effect");
2259 uiDefButBitS(block, TOG, MOD_CAST_USE_OB_TRANSFORM, B_MODIFIER_RECALC, "Use transform", lx+buttonWidth,cy,80,19, &cmd->flag, 0, 0, 0, 0, "Use object transform to control projection shape");
2261 } else if (md->type==eModifierType_Wave) {
2262 WaveModifierData *wmd = (WaveModifierData*) md;
2263 uiDefButBitS(block, TOG, MOD_WAVE_X, B_MODIFIER_RECALC, "X", lx,(cy-=19),45,19, &wmd->flag, 0, 0, 0, 0, "Enable X axis motion");
2264 uiDefButBitS(block, TOG, MOD_WAVE_Y, B_MODIFIER_RECALC, "Y", lx+45,cy,45,19, &wmd->flag, 0, 0, 0, 0, "Enable Y axis motion");
2265 uiDefButBitS(block, TOG, MOD_WAVE_CYCL, B_MODIFIER_RECALC, "Cycl", lx+90,cy,buttonWidth-90,19, &wmd->flag, 0, 0, 0, 0, "Enable cyclic wave effect");
2266 uiDefButBitS(block, TOG, MOD_WAVE_NORM, B_MODIFIER_RECALC, "Normals", lx,(cy-=19),buttonWidth,19, &wmd->flag, 0, 0, 0, 0, "Displace along normals");
2267 if (wmd->flag & MOD_WAVE_NORM){
2268 if (ob->type==OB_MESH) {
2269 uiDefButBitS(block, TOG, MOD_WAVE_NORM_X, B_MODIFIER_RECALC, "X", lx,(cy-=19),buttonWidth/3,19, &wmd->flag, 0, 0, 0, 0, "Enable displacement along the X normal");
2270 uiDefButBitS(block, TOG, MOD_WAVE_NORM_Y, B_MODIFIER_RECALC, "Y", lx+(buttonWidth/3),cy,buttonWidth/3,19, &wmd->flag, 0, 0, 0, 0, "Enable displacement along the Y normal");
2271 uiDefButBitS(block, TOG, MOD_WAVE_NORM_Z, B_MODIFIER_RECALC, "Z", lx+(buttonWidth/3)*2,cy,buttonWidth/3,19, &wmd->flag, 0, 0, 0, 0, "Enable displacement along the Z normal");
2274 uiDefBut(block, LABEL, 1, "Meshes Only", lx, (cy-=19), buttonWidth,19, NULL, 0.0, 0.0, 0, 0, "");
2277 uiBlockBeginAlign(block);
2279 uiDefButF(block, NUM, B_MODIFIER_RECALC, "Time sta:", lx,(cy-=19),buttonWidth,19, &wmd->timeoffs, -MAXFRAMEF, MAXFRAMEF, 100, 0, "Specify starting frame of the wave");
2281 uiDefButF(block, NUM, B_MODIFIER_RECALC, "Time end:", lx,(cy-=19),buttonWidth,19, &wmd->timeoffs, -MAXFRAMEF, MAXFRAMEF, 100, 0, "Specify ending frame of the wave");
2282 uiDefButF(block, NUM, B_MODIFIER_RECALC, "Lifetime:", lx,(cy-=19),buttonWidth,19, &wmd->lifetime, -MAXFRAMEF, MAXFRAMEF, 100, 0, "Specify the lifespan of the wave");
2283 uiDefButF(block, NUM, B_MODIFIER_RECALC, "Damptime:", lx,(cy-=19),buttonWidth,19, &wmd->damp, -MAXFRAMEF, MAXFRAMEF, 100, 0, "Specify the dampingtime of the wave");
2284 uiDefButF(block, NUM, B_MODIFIER_RECALC, "Falloff:", lx,(cy-=19),buttonWidth,19, &wmd->falloff, 0, 100, 100, 0, "Specify the falloff radius of the waves");
2287 uiBlockBeginAlign(block);
2288 uiDefButF(block, NUM, B_MODIFIER_RECALC, "Sta x:", lx,(cy-=19),113,19, &wmd->startx, -100.0, 100.0, 100, 0, "Starting position for the X axis");
2289 uiDefButF(block, NUM, B_MODIFIER_RECALC, "Sta y:", lx+115,cy,105,19, &wmd->starty, -100.0, 100.0, 100, 0, "Starting position for the Y axis");
2290 uiDefIDPoinBut(block, test_obpoin_but, ID_OB, B_MODIFIER_RECALC, "Ob: ", lx, (cy-=19), 220,19, &wmd->objectcenter, "Object to use as Starting Position (leave blank to disable)");
2291 uiDefBut(block, TEX, B_MODIFIER_RECALC, "VGroup: ",lx, (cy -= 19), 220, 19,&wmd->defgrp_name, 0.0, 31.0, 0, 0, "Name of vertex group with which to modulate displacement");
2292 uiDefIDPoinBut(block, modifier_testTexture, ID_TE, B_CHANGEDEP,"Texture: ", lx, (cy -= 19), 220, 19, &wmd->texture,"Texture with which to modulate wave");
2293 sprintf(str, "Texture Coordinates%%t"
2294 "|Local%%x%d|Global%%x%d|Object%%x%d|UV%%x%d",
2295 MOD_WAV_MAP_LOCAL, MOD_WAV_MAP_GLOBAL,
2296 MOD_WAV_MAP_OBJECT, MOD_WAV_MAP_UV);
2297 uiDefButI(block, MENU, B_MODIFIER_RECALC, str,
2298 lx, (cy -= 19), 220, 19, &wmd->texmapping,
2300 "Texture coordinates used for modulation input");
2301 if (wmd->texmapping == MOD_WAV_MAP_UV) {
2304 CustomData *fdata = G.obedit ? &G.editMesh->fdata
2305 : &((Mesh*)ob->data)->fdata;
2306 build_uvlayer_menu_vars(fdata, &strtmp, &wmd->uvlayer_tmp,
2308 but = uiDefButI(block, MENU, B_MODIFIER_RECALC, strtmp,
2309 lx, (cy -= 19), 220, 19, &wmd->uvlayer_tmp,
2310 0.0, 1.0, 0, 0, "Set the UV layer to use");
2312 i = CustomData_get_layer_index(fdata, CD_MTFACE);
2313 uiButSetFunc(but, set_wave_uvlayer, wmd,
2316 if(wmd->texmapping == MOD_DISP_MAP_OBJECT) {
2317 uiDefIDPoinBut(block, test_obpoin_but, ID_OB, B_CHANGEDEP,
2318 "Ob: ", lx, (cy -= 19), 220, 19,
2320 "Object to get texture coordinates from");
2323 uiBlockBeginAlign(block);
2324 uiDefButF(block, NUMSLI, B_MODIFIER_RECALC, "Speed:", lx,(cy-=19),220,19, &wmd->speed, -2.0, 2.0, 0, 0, "Specify the wave speed");
2325 uiDefButF(block, NUMSLI, B_MODIFIER_RECALC, "Height:", lx,(cy-=19),220,19, &wmd->height, -2.0, 2.0, 0, 0, "Specify the amplitude of the wave");
2326 uiDefButF(block, NUMSLI, B_MODIFIER_RECALC, "Width:", lx,(cy-=19),220,19, &wmd->width, 0.0, 5.0, 0, 0, "Specify the width of the wave");
2327 uiDefButF(block, NUMSLI, B_MODIFIER_RECALC, "Narrow:", lx,(cy-=19),220,19, &wmd->narrow, 0.0, 10.0, 0, 0, "Specify how narrow the wave follows");
2328 } else if (md->type==eModifierType_Armature) {
2329 ArmatureModifierData *amd = (ArmatureModifierData*) md;
2330 uiDefIDPoinBut(block, modifier_testArmatureObj, ID_OB, B_CHANGEDEP, "Ob: ", lx, (cy-=19), buttonWidth,19, &amd->object, "Armature object to deform with");
2332 but=uiDefBut(block, TEX, B_MODIFIER_RECALC, "VGroup: ", lx, (cy-=19), buttonWidth-40,19, &amd->defgrp_name, 0.0, 31.0, 0, 0, "Vertex Group name to control overall armature influence");
2333 uiButSetCompleteFunc(but, autocomplete_vgroup, (void *)ob);
2334 uiDefButBitS(block, TOG, ARM_DEF_INVERT_VGROUP, B_ARM_RECALCDATA, "Inv", lx+buttonWidth-40,cy, 40, 20, &amd->deformflag, 0, 0, 0, 0, "Invert vertex group influence");
2336 uiDefButBitS(block, TOG, ARM_DEF_VGROUP, B_ARM_RECALCDATA, "Vert.Groups", lx,cy-=19,buttonWidth/2,20, &amd->deformflag, 0, 0, 0, 0, "Enable VertexGroups defining deform");
2337 uiDefButBitS(block, TOG, ARM_DEF_ENVELOPE, B_ARM_RECALCDATA, "Envelopes", lx+buttonWidth/2,cy,(buttonWidth + 1)/2,20, &amd->deformflag, 0, 0, 0, 0, "Enable Bone Envelopes defining deform");
2338 uiDefButBitS(block, TOG, ARM_DEF_QUATERNION, B_ARM_RECALCDATA, "Quaternion", lx,(cy-=19),buttonWidth/2,20, &amd->deformflag, 0, 0, 0, 0, "Enable deform rotation interpolation with Quaternions");
2339 uiDefButBitS(block, TOG, ARM_DEF_B_BONE_REST, B_ARM_RECALCDATA, "B-Bone Rest", lx+buttonWidth/2,cy,(buttonWidth + 1)/2,20, &amd->deformflag, 0, 0, 0, 0, "Make B-Bones deform already in rest position");
2341 uiDefButS(block, TOG, B_ARM_RECALCDATA, "MultiModifier", lx,cy-=19, buttonWidth, 20, &amd->multi, 0, 0, 0, 0, "Use same input as previous modifier, and mix results using overall vgroup");
2343 } else if (md->type==eModifierType_Hook) {
2344 HookModifierData *hmd = (HookModifierData*) md;
2345 uiDefButF(block, NUM, B_MODIFIER_RECALC, "Falloff: ", lx, (cy-=19), buttonWidth,19, &hmd->falloff, 0.0, 100.0, 100, 0, "If not zero, the distance from hook where influence ends");
2346 uiDefButF(block, NUMSLI, B_MODIFIER_RECALC, "Force: ", lx, (cy-=19), buttonWidth,19, &hmd->force, 0.0, 1.0, 100, 0, "Set relative force of hook");
2347 uiDefIDPoinBut(block, test_obpoin_but, ID_OB, B_CHANGEDEP, "Ob: ", lx, (cy-=19), buttonWidth,19, &hmd->object, "Parent Object for hook, also recalculates and clears offset");
2348 if(hmd->indexar==NULL) {
2349 but=uiDefBut(block, TEX, B_MODIFIER_RECALC, "VGroup: ", lx, (cy-=19), buttonWidth,19, &hmd->name, 0.0, 31.0, 0, 0, "Vertex Group name");
2350 uiButSetCompleteFunc(but, autocomplete_vgroup, (void *)ob);
2352 uiBlockBeginAlign(block);
2353 but = uiDefBut(block, BUT, B_MODIFIER_RECALC, "Reset", lx, (cy-=19), 80,19, NULL, 0.0, 0.0, 0, 0, "Recalculate and clear offset (transform) of hook");
2354 uiButSetFunc(but, modifiers_clearHookOffset, ob, md);
2355 but = uiDefBut(block, BUT, B_MODIFIER_RECALC, "Recenter", lx+80, cy, buttonWidth-80,19, NULL, 0.0, 0.0, 0, 0, "Sets hook center to cursor position");
2356 uiButSetFunc(but, modifiers_cursorHookCenter, ob, md);
2359 but = uiDefBut(block, BUT, B_MODIFIER_RECALC, "Select", lx, (cy-=19), 80,19, NULL, 0.0, 0.0, 0, 0, "Selects effected vertices on mesh");
2360 uiButSetFunc(but, modifiers_selectHook, ob, md);
2361 but = uiDefBut(block, BUT, B_MODIFIER_RECALC, "Reassign", lx+80, cy, buttonWidth-80,19, NULL, 0.0, 0.0, 0, 0, "Reassigns selected vertices to hook");
2362 uiButSetFunc(but, modifiers_reassignHook, ob, md);
2364 } else if (md->type==eModifierType_Softbody) {
2365 uiDefBut(block, LABEL, 1, "See Soft Body panel.", lx, (cy-=19), buttonWidth,19, NULL, 0.0, 0.0, 0, 0, "");
2366 } else if (md->type==eModifierType_Cloth) {
2367 uiDefBut(block, LABEL, 1, "See Cloth panel.", lx, (cy-=19), buttonWidth,19, NULL, 0.0, 0.0, 0, 0, "");
2369 } else if (md->type==eModifierType_Collision) {
2370 uiDefBut(block, LABEL, 1, "See Collision panel.", lx, (cy-=19), buttonWidth,19, NULL, 0.0, 0.0, 0, 0, "");
2371 } else if (md->type==eModifierType_Fluidsim) {
2372 uiDefBut(block, LABEL, 1, "See Fluidsim panel.", lx, (cy-=19), buttonWidth,19, NULL, 0.0, 0.0, 0, 0, "");
2373 } else if (md->type==eModifierType_Boolean) {
2374 BooleanModifierData *bmd = (BooleanModifierData*) md;
2375 uiDefButI(block, MENU, B_MODIFIER_RECALC, "Operation%t|Intersect%x0|Union%x1|Difference%x2", lx,(cy-=19),buttonWidth,19, &bmd->operation, 0.0, 1.0, 0, 0, "Boolean operation to perform");
2376 uiDefIDPoinBut(block, modifier_testMeshObj, ID_OB, B_CHANGEDEP, "Ob: ", lx, (cy-=19), buttonWidth,19, &bmd->object, "Mesh object to use for boolean operation");
2377 } else if (md->type==eModifierType_Array) {
2378 ArrayModifierData *amd = (ArrayModifierData*) md;
2379 float range = 10000;
2380 int cytop, halfwidth = (width - 5)/2 - 15;
2381 int halflx = lx + halfwidth + 10;
2383 uiBlockSetEmboss(block, UI_EMBOSSX);
2384 uiBlockEndAlign(block);
2386 /* length parameters */
2387 uiBlockBeginAlign(block);
2388 sprintf(str, "Length Fit%%t|Fixed Count%%x%d|Fixed Length%%x%d"
2389 "|Fit To Curve Length%%x%d",
2390 MOD_ARR_FIXEDCOUNT, MOD_ARR_FITLENGTH, MOD_ARR_FITCURVE);
2391 uiDefButI(block, MENU, B_MODIFIER_RECALC, str,
2392 lx, (cy-=19), buttonWidth, 19, &amd->fit_type,
2393 0.0, 1.0, 0, 0, "Array length calculation method");
2394 switch(amd->fit_type)
2396 case MOD_ARR_FIXEDCOUNT:
2397 uiDefButI(block, NUM, B_MODIFIER_RECALC, "Count:",
2398 lx, (cy -= 19), buttonWidth, 19, &amd->count,
2399 1, 1000, 0, 0, "Number of duplicates to make");
2401 case MOD_ARR_FITLENGTH:
2402 uiDefButF(block, NUM, B_MODIFIER_RECALC, "Length:",
2403 lx, (cy -= 19), buttonWidth, 19, &amd->length,
2405 "Length to fit array within");
2407 case MOD_ARR_FITCURVE:
2408 uiDefIDPoinBut(block, modifier_testCurveObj, ID_OB,
2409 B_CHANGEDEP, "Ob: ",
2410 lx, (cy -= 19), buttonWidth, 19, &amd->curve_ob,
2411 "Curve object to fit array length to");
2414 uiBlockEndAlign(block);
2416 /* offset parameters */
2419 uiBlockBeginAlign(block);
2420 uiDefButBitI(block, TOG, MOD_ARR_OFF_CONST, B_MODIFIER_RECALC,
2421 "Constant Offset", lx, (cy-=19), halfwidth, 19,
2422 &amd->offset_type, 0, 0, 0, 0,
2423 "Constant offset between duplicates "
2424 "(local coordinates)");
2425 uiDefButF(block, NUM, B_MODIFIER_RECALC, "X:",
2426 lx, (cy-=19), halfwidth, 19,
2428 -range, range, 10, 3,
2429 "Constant component for duplicate offsets "
2430 "(local coordinates)");
2431 uiDefButF(block, NUM, B_MODIFIER_RECALC, "Y:",
2432 lx, (cy-=19), halfwidth, 19,
2434 -range, range, 10, 3,
2435 "Constant component for duplicate offsets "
2436 "(local coordinates)");
2437 uiDefButF(block, NUM, B_MODIFIER_RECALC, "Z:",
2438 lx, (cy-=19), halfwidth, 19,
2440 -range, range, 10, 3,
2441 "Constant component for duplicate offsets "
2442 "(local coordinates)");
2443 uiBlockEndAlign(block);
2446 uiBlockBeginAlign(block);
2447 uiDefButBitI(block, TOG, MOD_ARR_OFF_RELATIVE, B_MODIFIER_RECALC,
2448 "Relative Offset", halflx, (cy-=19), halfwidth, 19,
2449 &amd->offset_type, 0, 0, 0, 0,
2450 "Offset between duplicates relative to object width "
2451 "(local coordinates)");
2452 uiDefButF(block, NUM, B_MODIFIER_RECALC, "X:",
2453 halflx, (cy-=19), halfwidth, 19,
2455 -range, range, 10, 3,
2456 "Component for duplicate offsets relative to object "
2457 "width (local coordinates)");
2458 uiDefButF(block, NUM, B_MODIFIER_RECALC, "Y:",
2459 halflx, (cy-=19), halfwidth, 19,
2461 -range, range, 10, 3,
2462 "Component for duplicate offsets relative to object "
2463 "width (local coordinates)");
2464 uiDefButF(block, NUM, B_MODIFIER_RECALC, "Z:",
2465 halflx, (cy-=19), halfwidth, 19,
2467 -range, range, 10, 3,
2468 "Component for duplicate offsets relative to object "
2469 "width (local coordinates)");
2470 uiBlockEndAlign(block);
2472 /* vertex merging parameters */
2476 uiBlockBeginAlign(block);
2477 uiDefButBitI(block, TOG, MOD_ARR_MERGE, B_MODIFIER_RECALC,
2479 lx, (cy-=19), halfwidth/2, 19, &amd->flags,
2481 "Merge vertices in adjacent duplicates");
2482 uiDefButBitI(block, TOG, MOD_ARR_MERGEFINAL, B_MODIFIER_RECALC,
2484 lx + halfwidth/2, cy, (halfwidth+1)/2, 19,
2487 "Merge vertices in first duplicate with vertices"
2488 " in last duplicate");
2489 uiDefButF(block, NUM, B_MODIFIER_RECALC, "Limit:",
2490 lx, (cy-=19), halfwidth, 19, &amd->merge_dist,
2492 "Limit below which to merge vertices");
2496 uiBlockBeginAlign(block);
2497 uiDefButBitI(block, TOG, MOD_ARR_OFF_OBJ, B_MODIFIER_RECALC,
2498 "Object Offset", halflx, (cy -= 19), halfwidth, 19,
2499 &amd->offset_type, 0, 0, 0, 0,
2500 "Add an object transformation to the total offset");
2501 uiDefIDPoinBut(block, test_obpoin_but, ID_OB, B_CHANGEDEP,
2502 "Ob: ", halflx, (cy -= 19), halfwidth, 19,
2504 "Object from which to take offset transformation");
2505 uiBlockEndAlign(block);
2508 but = uiDefIDPoinBut(block, test_meshobpoin_but, ID_OB,
2509 B_CHANGEDEP, "Start cap: ",
2510 lx, (cy -= 19), halfwidth, 19,
2512 "Mesh object to use as start cap");
2513 uiButSetCompleteFunc(but, autocomplete_meshob, (void *)ob);
2514 but = uiDefIDPoinBut(block, test_meshobpoin_but, ID_OB,
2515 B_CHANGEDEP, "End cap: ",
2516 halflx, cy, halfwidth, 19,
2518 "Mesh object to use as end cap");
2519 uiButSetCompleteFunc(but, autocomplete_meshob, (void *)ob);
2520 } else if (md->type==eModifierType_MeshDeform) {
2521 MeshDeformModifierData *mmd = (MeshDeformModifierData*) md;
2523 uiBlockBeginAlign(block);
2524 uiDefIDPoinBut(block, test_meshobpoin_but, ID_OB, B_CHANGEDEP, "Ob: ", lx, (cy-=19), buttonWidth,19, &mmd->object, "Mesh object to be use as cage");
2525 but=uiDefBut(block, TEX, B_MODIFIER_RECALC, "VGroup: ", lx, (cy-19), buttonWidth-40,19, &mmd->defgrp_name, 0.0, 31.0, 0, 0, "Vertex Group name to control overall meshdeform influence");
2526 uiButSetCompleteFunc(but, autocomplete_vgroup, (void *)ob);
2527 uiDefButBitS(block, TOG, MOD_MDEF_INVERT_VGROUP, B_MODIFIER_RECALC, "Inv", lx+buttonWidth-40, (cy-=19), 40,19, &mmd->flag, 0.0, 31.0, 0, 0, "Invert vertex group influence");
2529 uiBlockBeginAlign(block);
2531 but= uiDefBut(block, BUT, B_MODIFIER_RECALC, "Unbind", lx,(cy-=24), buttonWidth,19, 0, 0, 0, 0, 0, "Unbind mesh from cage");
2532 uiButSetFunc(but,modifiers_bindMeshDeform,ob,md);
2535 but= uiDefBut(block, BUT, B_MODIFIER_RECALC, "Bind", lx,(cy-=24), buttonWidth,19, 0, 0, 0, 0, 0, "Bind mesh to cage");
2536 uiButSetFunc(but,modifiers_bindMeshDeform,ob,md);
2537 uiDefButS(block, NUM, B_NOP, "Precision:", lx,(cy-19), buttonWidth/2 + 20,19, &mmd->gridsize, 2, 10, 0.5, 0, "The grid size for binding");
2538 uiDefButBitS(block, TOG, MOD_MDEF_DYNAMIC_BIND, B_MODIFIER_RECALC, "Dynamic", lx+(buttonWidth+1)/2 + 20, (cy-=19), buttonWidth/2 - 20,19, &mmd->flag, 0.0, 31.0, 0, 0, "Recompute binding dynamically on top of other deformers like Shape Keys (slower and more memory consuming!)");
2540 uiBlockEndAlign(block);
2541 } else if (md->type==eModifierType_ParticleSystem) {
2542 uiDefBut(block, LABEL, 1, "See Particle buttons.", lx, (cy-=19), buttonWidth,19, NULL, 0.0, 0.0, 0, 0, "");
2543 } else if (md->type==eModifierType_ParticleInstance) {
2544 ParticleInstanceModifierData *pimd = (ParticleInstanceModifierData*) md;
2545 uiDefIDPoinBut(block, test_obpoin_but, ID_OB, B_CHANGEDEP, "Ob: ", lx, (cy -= 19), buttonWidth, 19, &pimd->ob, "Object that has the particlesystem");
2546 uiDefButS(block, NUM, B_MODIFIER_RECALC, "PSYS:", lx, (cy -= 19), buttonWidth, 19, &pimd->psys, 1, 10, 10, 3, "Particlesystem number in the object");
2547 uiDefButBitS(block, TOG, eParticleInstanceFlag_Parents, B_MODIFIER_RECALC, "Normal", lx, (cy -= 19), buttonWidth/3,19, &pimd->flag, 0, 0, 0, 0, "Create instances from normal particles");
2548 uiDefButBitS(block, TOG, eParticleInstanceFlag_Children, B_MODIFIER_RECALC, "Children", lx+buttonWidth/3, cy, buttonWidth/3,19, &pimd->flag, 0, 0, 0, 0, "Create instances from child particles");
2549 uiDefButBitS(block, TOG, eParticleInstanceFlag_Path, B_MODIFIER_RECALC, "Path", lx+buttonWidth*2/3, cy, buttonWidth/3,19, &pimd->flag, 0, 0, 0, 0, "Create instances along particle paths");
2550 uiDefButBitS(block, TOG, eParticleInstanceFlag_Unborn, B_MODIFIER_RECALC, "Unborn", lx, (cy -= 19), buttonWidth/3,19, &pimd->flag, 0, 0, 0, 0, "Show instances when particles are unborn");
2551 uiDefButBitS(block, TOG, eParticleInstanceFlag_Alive, B_MODIFIER_RECALC, "Alive", lx+buttonWidth/3, cy, buttonWidth/3,19, &pimd->flag, 0, 0, 0, 0, "Show instances when particles are alive");
2552 uiDefButBitS(block, TOG, eParticleInstanceFlag_Dead, B_MODIFIER_RECALC, "Dead", lx+buttonWidth*2/3, cy, buttonWidth/3,19, &pimd->flag, 0, 0, 0, 0, "Show instances when particles are dead");
2553 } else if (md->type==eModifierType_Explode) {
2554 ExplodeModifierData *emd = (ExplodeModifierData*) md;
2556 char *menustr= get_vertexgroup_menustr(ob);
2557 int defCount=BLI_countlist(&ob->defbase);
2558 if(defCount==0) emd->vgroup=0;
2559 uiBlockBeginAlign(block);
2560 but=uiDefButS(block, MENU, B_MODIFIER_RECALC, menustr, lx, (cy-=19), buttonWidth-20,19, &emd->vgroup, 0, defCount, 0, 0, "Protect this vertex group");
2561 uiButSetFunc(but,modifiers_explodeFacepa,emd,0);
2564 but=uiDefIconBut(block, BUT, B_MODIFIER_RECALC, ICON_X, (lx+buttonWidth)-20, cy, 20,19, 0, 0, 0, 0, 0, "Disable use of vertex group");
2565 uiButSetFunc(but, modifiers_explodeDelVg, (void *)emd, (void *)NULL);
2568 but=uiDefButF(block, NUMSLI, B_MODIFIER_RECALC, "", lx, (cy-=19), buttonWidth,19, &emd->protect, 0.0f, 1.0f, 0, 0, "Clean vertex group edges");
2569 uiButSetFunc(but,modifiers_explodeFacepa,emd,0);
2571 but=uiDefBut(block, BUT, B_MODIFIER_RECALC, "Refresh", lx, (cy-=19), buttonWidth/2,19, 0, 0, 0, 0, 0, "Recalculate faces assigned to particles");
2572 uiButSetFunc(but,modifiers_explodeFacepa,emd,0);
2574 uiDefButBitS(block, TOG, eExplodeFlag_EdgeSplit, B_MODIFIER_RECALC, "Split Edges", lx+buttonWidth/2, cy, buttonWidth/2,19, &emd->flag, 0, 0, 0, 0, "Split face edges for nicer shrapnel");
2575 uiDefButBitS(block, TOG, eExplodeFlag_Unborn, B_MODIFIER_RECALC, "Unborn", lx, (cy-=19), buttonWidth/3,19, &emd->flag, 0, 0, 0, 0, "Show mesh when particles are unborn");
2576 uiDefButBitS(block, TOG, eExplodeFlag_Alive, B_MODIFIER_RECALC, "Alive", lx+buttonWidth/3, cy, buttonWidth/3,19, &emd->flag, 0, 0, 0, 0, "Show mesh when particles are alive");
2577 uiDefButBitS(block, TOG, eExplodeFlag_Dead, B_MODIFIER_RECALC, "Dead", lx+buttonWidth*2/3, cy, buttonWidth/3,19, &emd->flag, 0, 0, 0, 0, "Show mesh when particles are dead");
2578 uiBlockEndAlign(block);
2579 } else if (md->type==eModifierType_Shrinkwrap) {
2580 ShrinkwrapModifierData *smd = (ShrinkwrapModifierData*) md;
2582 char shrinktypemenu[]="Shrinkwrap type%t|nearest surface point %x0|projection %x1|nearest vertex %x2";
2584 uiDefIDPoinBut(block, modifier_testMeshObj, ID_OB, B_CHANGEDEP, "Ob: ", lx, (cy-=19), buttonWidth,19, &smd->target, "Target to shrink to");
2586 but=uiDefBut(block, TEX, B_MODIFIER_RECALC, "VGroup: ", lx, (cy-=19), buttonWidth,19, &smd->vgroup_name, 0, 31, 0, 0, "Vertex Group name");
2587 uiButSetCompleteFunc(but, autocomplete_vgroup, (void *)ob);
2589 uiDefButF(block, NUM, B_MODIFIER_RECALC, "Offset:", lx,(cy-=19),buttonWidth,19, &smd->keepDist, 0.0f, 100.0f, 1.0f, 0, "Specify distance to keep from the target");
2592 uiDefButS(block, MENU, B_MODIFIER_RECALC, shrinktypemenu, lx,(cy-=19),buttonWidth,19, &smd->shrinkType, 0, 0, 0, 0, "Selects type of shrinkwrap algorithm for target position.");
2594 if (smd->shrinkType == MOD_SHRINKWRAP_PROJECT){
2597 /* UI for projection axis */
2598 uiBlockBeginAlign(block);
2599 uiDefButC(block, ROW, B_MODIFIER_RECALC, "Normal" , lx,(cy-=19),buttonWidth,19, &smd->projAxis, 18.0, MOD_SHRINKWRAP_PROJECT_OVER_NORMAL, 0, 0, "Projection over X axis");
2600 if(smd->projAxis == 0)
2602 uiDefButC(block, NUM, B_MODIFIER_RECALC, "SS Levels:", lx, (cy-=19), buttonWidth,19, &smd->subsurfLevels, 0, 6, 0, 0, "This indicates the number of CCSubdivisions that must be performed before extracting vertexs positions and normals");
2605 uiDefButBitC(block, TOG, MOD_SHRINKWRAP_PROJECT_OVER_X_AXIS, B_MODIFIER_RECALC, "X", lx+buttonWidth/3*0,(cy-=19),buttonWidth/3,19, &smd->projAxis, 0, 0, 0, 0, "Projection over X axis");
2606 uiDefButBitC(block, TOG, MOD_SHRINKWRAP_PROJECT_OVER_Y_AXIS, B_MODIFIER_RECALC, "Y", lx+buttonWidth/3*1,cy,buttonWidth/3,19, &smd->projAxis, 0, 0, 0, 0, "Projection over Y axis");
2607 uiDefButBitC(block, TOG, MOD_SHRINKWRAP_PROJECT_OVER_Z_AXIS, B_MODIFIER_RECALC, "Z", lx+buttonWidth/3*2,cy,buttonWidth/3,19, &smd->projAxis, 0, 0, 0, 0, "Projection over Z axis");
2610 /* allowed directions of projection axis */
2611 uiDefButBitS(block, TOG, MOD_SHRINKWRAP_PROJECT_ALLOW_NEG_DIR, B_MODIFIER_RECALC, "Negative", lx,(cy-=19),buttonWidth/2,19, &smd->shrinkOpts, 0, 0, 0, 0, "Allows to move the vertex in the negative direction of axis");
2612 uiDefButBitS(block, TOG, MOD_SHRINKWRAP_PROJECT_ALLOW_POS_DIR, B_MODIFIER_RECALC, "Positive", lx + buttonWidth/2,cy,buttonWidth/2,19, &smd->shrinkOpts, 0, 0, 0, 0, "Allows to move the vertex in the positive direction of axis");
2614 uiDefButBitS(block, TOG, MOD_SHRINKWRAP_CULL_TARGET_FRONTFACE, B_MODIFIER_RECALC, "Cull frontfaces",lx,(cy-=19),buttonWidth/2,19, &smd->shrinkOpts, 0, 0, 0, 0, "Controls whether a vertex can be projected to a front face on target");
2615 uiDefButBitS(block, TOG, MOD_SHRINKWRAP_CULL_TARGET_BACKFACE, B_MODIFIER_RECALC, "Cull backfaces", lx+buttonWidth/2,cy,buttonWidth/2,19, &smd->shrinkOpts, 0, 0, 0, 0, "Controls whether a vertex can be projected to a back face on target");
2616 uiDefIDPoinBut(block, modifier_testMeshObj, ID_OB, B_CHANGEDEP, "Ob2: ", lx, (cy-=19), buttonWidth,19, &smd->auxTarget, "Aditional mesh to project over");
2618 else if (smd->shrinkType == MOD_SHRINKWRAP_NEAREST_SURFACE){
2619 uiDefButBitS(block, TOG, MOD_SHRINKWRAP_KEEP_ABOVE_SURFACE, B_MODIFIER_RECALC, "Above surface", lx,(cy-=19),buttonWidth,19, &smd->shrinkOpts, 0, 0, 0, 0, "Vertices are kept on the front side of faces");
2622 uiBlockEndAlign(block);
2624 } else if (md->type==eModifierType_SimpleDeform) {
2625 SimpleDeformModifierData *smd = (SimpleDeformModifierData*) md;
2626 char simpledeform_modemenu[] = "Deform type%t|Twist %x1|Bend %x2|Taper %x3|Strech %x4";
2628 uiDefButC(block, MENU, B_MODIFIER_RECALC, simpledeform_modemenu, lx,(cy-=19),buttonWidth,19, &smd->mode, 0, 0, 0, 0, "Selects type of deform to apply to object.");
2630 but=uiDefBut(block, TEX, B_MODIFIER_RECALC, "VGroup: ", lx, (cy-=19), buttonWidth,19, &smd->vgroup_name, 0, 31, 0, 0, "Vertex Group name");
2631 uiButSetCompleteFunc(but, autocomplete_vgroup, (void *)ob);
2633 uiDefIDPoinBut(block, test_obpoin_but, ID_OB, B_CHANGEDEP, "Ob: ", lx, (cy-=19), buttonWidth,19, &smd->origin, "Origin of modifier space coordinates");
2634 if(smd->origin != NULL)
2635 uiDefButBitC(block, TOG, MOD_SIMPLEDEFORM_ORIGIN_LOCAL, B_MODIFIER_RECALC, "Relative",lx,(cy-=19),buttonWidth,19, &smd->originOpts, 0, 0, 0, 0, "Sets the origin of deform space to be relative to the object");
2637 uiDefButF(block, NUM, B_MODIFIER_RECALC, "Factor:", lx,(cy-=19),buttonWidth,19, &smd->factor, -10.0f, 10.0f, 0.5f, 0, "Deform Factor");
2639 uiDefButF(block, NUM, B_MODIFIER_RECALC, "Upper Limit:", lx,(cy-=19),buttonWidth,19, &smd->limit[1], 0.0f, 1.0f, 5.0f, 0, "Upper Limit for deform");
2640 uiDefButF(block, NUM, B_MODIFIER_RECALC, "Lower Limit:", lx,(cy-=19),buttonWidth,19, &smd->limit[0], 0.0f, 1.0f, 5.0f, 0, "Lower Limit for deform");
2642 if(smd->mode == MOD_SIMPLEDEFORM_MODE_STRETCH
2643 || smd->mode == MOD_SIMPLEDEFORM_MODE_TAPER )
2645 uiDefButBitC(block, TOG, MOD_SIMPLEDEFORM_LOCK_AXIS_X, B_MODIFIER_RECALC, "Loc X", lx, (cy-=19),buttonWidth/2,19, &smd->axis, 0, 0, 0, 0, "Disallow changes on the X coordinate");
2646 uiDefButBitC(block, TOG, MOD_SIMPLEDEFORM_LOCK_AXIS_Y, B_MODIFIER_RECALC, "Loc Y", lx+(buttonWidth/2), (cy),buttonWidth/2,19, &smd->axis, 0, 0, 0, 0, "Disallow changes on the Y coordinate");
2650 uiBlockEndAlign(block);
2658 uiBlockSetCol(block, color);
2659 /* roundbox 4 free variables: corner-rounding, nop, roundbox type, shade */
2660 uiDefBut(block, ROUNDBOX, 0, "", x-10, y, width, 20, NULL, 5.0, 0.0, 15, 40, "");
2661 uiBlockSetCol(block, TH_AUTO);
2663 uiDefIconBut(block,LABEL,B_NOP,ICON_ERROR, x-9, y,19,19, 0,0,0,0,0, "");
2664 uiDefBut(block, LABEL, B_NOP, md->error, x+5, y, width-15, 19, NULL, 0.0, 0.0, 0.0, 0.0, "");
2677 static void editing_panel_modifiers(Object *ob)
2682 int xco, yco, i, lastCageIndex, cageIndex = modifiers_getCageIndex(ob, &lastCageIndex);
2684 block= uiNewBlock(&curarea->uiblocks, "editing_panel_modifiers", UI_EMBOSS, UI_HELV, curarea->win);
2685 if( uiNewPanel(curarea, block, "Modifiers", "Editing", 640, 0, 318, 204)==0) return;
2687 uiSetButLock((ob && ob->id.lib), ERROR_LIBDATA_MESSAGE);
2688 uiNewPanelHeight(block, 204);
2690 uiDefBlockBut(block, modifiers_add_menu, ob, "Add Modifier", 0, 190, 130, 20, "Add a new modifier");
2692 sprintf(str, "To: %s", ob->id.name+2);
2693 uiDefBut(block, LABEL, 1, str, 140, 190, 160, 20, NULL, 0.0, 0.0, 0, 0, "Object whose modifier stack is being edited");
2698 md = modifiers_getVirtualModifierList(ob);
2700 for (i=0; md; i++, md=md->next) {
2701 draw_modifier(block, ob, md, &xco, &yco, i, cageIndex, lastCageIndex);
2702 if (md->mode&eModifierMode_Virtual) i--;
2705 if(yco < 0) uiNewPanelHeight(block, 204-yco);
2708 static char *make_key_menu(Key *key, int startindex)
2712 char *str, item[64];
2714 for (kb = key->block.first; kb; kb=kb->next, index++);
2715 str= MEM_mallocN(index*40, "key string");
2719 for (kb = key->block.first; kb; kb=kb->next, index++) {
2720 sprintf (item, "|%s%%x%d", kb->name, index);
2727 static void editing_panel_shapes(Object *ob)
2735 block= uiNewBlock(&curarea->uiblocks, "editing_panel_shapes", UI_EMBOSS, UI_HELV, curarea->win);
2736 uiNewPanelTabbed("Modifiers", "Editing");
2737 if( uiNewPanel(curarea, block, "Shapes", "Editing", 640, 0, 318, 204)==0) return;
2739 /* Todo check data is library here */
2740 uiSetButLock(object_data_is_libdata(ob), ERROR_LIBDATA_MESSAGE);
2742 uiDefBut(block, BUT, B_ADDKEY, "Add Shape Key" , 10, 180, 150, 20, NULL, 0.0, 0.0, 0, 0, "Add new Shape Key");
2744 key= ob_get_key(ob);
2746 /* label aligns add button */
2747 uiDefBut(block, LABEL, 0, "", 170, 180,140,20, NULL, 0, 0, 0, 0, "");
2751 uiDefButS(block, TOG, B_RELKEY, "Relative", 170, 180,140,20, &key->type, 0, 0, 0, 0, "Makes Shape Keys relative");
2753 kb= BLI_findlink(&key->block, ob->shapenr-1);
2756 kb= key->block.first;
2759 uiBlockBeginAlign(block);
2760 if(ob->shapeflag & OB_SHAPE_LOCK) icon= ICON_PIN_HLT; else icon= ICON_PIN_DEHLT;
2761 uiDefIconButBitS(block, TOG, OB_SHAPE_LOCK, B_LOCKKEY, icon, 10,150,25,20, &ob->shapeflag, 0, 0, 0, 0, "Always show the current Shape for this Object");
2762 if(kb->flag & KEYBLOCK_MUTE) icon= ICON_MUTE_IPO_ON; else icon = ICON_MUTE_IPO_OFF;
2763 uiDefIconButBitS(block, TOG, KEYBLOCK_MUTE, B_MODIFIER_RECALC, icon, 35,150,20,20, &kb->flag, 0, 0, 0, 0, "Mute the current Shape");
2764 uiSetButLock(G.obedit==ob, "Unable to perform in EditMode");
2765 uiDefIconBut(block, BUT, B_PREVKEY, ICON_TRIA_LEFT, 55,150,20,20, NULL, 0, 0, 0, 0, "Previous Shape Key");
2766 strp= make_key_menu(key, 1);
2767 uiDefButS(block, MENU, B_SETKEY, strp, 75,150,20,20, &ob->shapenr, 0, 0, 0, 0, "Browse existing choices");
2770 uiDefIconBut(block, BUT, B_NEXTKEY, ICON_TRIA_RIGHT, 95,150,20,20, NULL, 0, 0, 0, 0, "Next Shape Key");
2772 uiDefBut(block, TEX, B_NAMEKEY, "", 115, 150, 170, 20, kb->name, 0.0, 31.0, 0, 0, "Current Shape Key name");
2773 uiDefIconBut(block, BUT, B_DELKEY, ICON_X, 285,150,25,20, 0, 0, 0, 0, 0, "Deletes current Shape Key");
2774 uiBlockEndAlign(block);
2776 if(key->type && (ob->shapeflag & OB_SHAPE_LOCK)==0 && ob->shapenr!=1) {
2777 uiBlockBeginAlign(block);
2778 make_rvk_slider(block, ob, ob->shapenr-1, 10, 120, 150, 20, "Key value, when used it inserts an animation curve point");
2779 uiDefButF(block, NUM, B_REDR, "Min ", 160,120, 75, 20, &kb->slidermin, -10.0, 10.0, 100, 1, "Minumum for slider");
2780 uiDefButF(block, NUM, B_REDR, "Max ", 235,120, 75, 20, &kb->slidermax, -10.0, 10.0, 100, 1, "Maximum for slider");
2781 uiBlockEndAlign(block);
2783 if(key->type && ob->shapenr!=1) {
2784 uiDefBut(block, TEX, B_MODIFIER_RECALC, "VGroup: ", 10, 90, 150,19, &kb->vgroup, 0.0, 31.0, 0, 0, "Vertex Weight Group name, to blend with Basis Shape");
2786 strp= make_key_menu(key, 0);
2787 uiDefButS(block, MENU, B_MODIFIER_RECALC, strp, 160, 90, 150,19, &kb->relative, 0.0, 0.0, 0, 0, "Shape used as a relative key");