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, 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, *layerdata=layer->data;
726 int type= layer->type;
727 int index= CustomData_get_layer_index(data, type);
728 int i, actindex, rndindex;
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 CustomData_set_layer_active(data, type, layer - &data->layers[index]);
741 /* Multires is handled seperately because the display data is separate
742 from the data stored in multires */
744 multires_delete_layer(me, &me->mr->fdata, type, layer - &data->layers[index]);
745 multires_level_to_editmesh(OBACT, me, 0);
746 multires_finish_mesh_update(OBACT);
749 EM_free_data_layer(data, type);
752 CustomData_free_layer_active(data, type, me->totface);
753 mesh_update_customdata_pointers(me);
756 if(!CustomData_has_layer(data, type)) {
757 if(type == CD_MCOL && (G.f & G_VERTEXPAINT))
758 G.f &= ~G_VERTEXPAINT; /* get out of vertexpaint mode */
761 /*reconstruct active layer*/
762 if (actlayerdata != layerdata) {
764 actindex = CustomData_get_layer_index(data, type);
765 for (i=actindex; i<data->totlayer; i++) {
766 if (data->layers[i].data == actlayerdata) {
767 actindex = i - actindex;
773 CustomData_set_layer_active(data, type, actindex);
776 if (rndlayerdata != layerdata) {
778 rndindex = CustomData_get_layer_index(data, type);
779 for (i=rndindex; i<data->totlayer; i++) {
780 if (data->layers[i].data == rndlayerdata) {
781 rndindex = i - rndindex;
787 CustomData_set_layer_render(data, type, rndindex);
791 DAG_object_flush_update(G.scene, OBACT, OB_RECALC_DATA);
793 if(type == CD_MTFACE)
794 BIF_undo_push("Delete UV Texture");
795 else if(type == CD_MCOL)
796 BIF_undo_push("Delete Vertex Color");
798 allqueue(REDRAWVIEW3D, 0);
799 allqueue(REDRAWIMAGE, 0);
800 allqueue(REDRAWBUTSEDIT, 0);
803 static int customdata_buttons(
804 uiBlock *block, Mesh *me, CustomData *data,
805 int type, int *activep, int *renderp,
806 int setevt, int setevt_rnd, int newevt,
807 char *label, char *shortlabel, char *browsetip, char *browsetip_rnd,
808 char *newtip, char *deltip, int x, int y)
810 CustomDataLayer *layer;
812 int i, count= CustomData_number_of_layers(data, type);
814 if(count >= MAX_MTFACE) {
815 uiDefBut(block, LABEL, 0, label, x,y,220,19, 0, 0.0, 0, 0, 0, "");
818 uiDefBut(block, LABEL, 0, label, x,y,140,19, 0, 0.0, 0, 0, 0, "");
819 uiBlockBeginAlign(block);
820 uiDefBut(block, BUT, newevt, "New", x+140,y,80,19, 0,0,0,0,0, newtip);
821 uiBlockEndAlign(block);
824 y -= (count)? 24: 19;
826 uiBlockBeginAlign(block);
827 for (count=1, i=0; i<data->totlayer; i++) {
828 layer= &data->layers[i];
830 if(layer->type == type) {
831 *activep= layer->active + 1;
832 *renderp= layer->active_rnd + 1;
834 uiDefIconButI(block, ROW, setevt, ICON_VIEW3D, x,y,25,19, activep, 1.0, count, 0, 0, browsetip);
835 uiDefIconButI(block, ROW, setevt_rnd, ICON_SCENE, x+25,y,25,19, renderp, 1.0, count, 0, 0, browsetip_rnd);
836 but=uiDefBut(block, TEX, setevt, "", x+50,y,145,19, layer->name, 0.0, 31.0, 0, 0, label);
837 uiButSetFunc(but, verify_customdata_name_func, data, layer);
838 but= uiDefIconBut(block, BUT, B_NOP, VICON_X, x+195,y,25,19, NULL, 0.0, 0.0, 0.0, 0.0, deltip);
839 uiButSetFunc(but, delete_customdata_layer, me, layer);
846 uiBlockEndAlign(block);
851 static void editing_panel_mesh_type(Object *ob, Mesh *me)
859 block= uiNewBlock(&curarea->uiblocks, "editing_panel_mesh_type", UI_EMBOSS, UI_HELV, curarea->win);
860 if( uiNewPanel(curarea, block, "Mesh", "Editing", 320, 0, 318, 204)==0) return;
861 uiSetButLock(object_data_is_libdata(ob), ERROR_LIBDATA_MESSAGE);
863 uiBlockBeginAlign(block);
864 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");
865 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");
866 uiBlockEndAlign(block);
870 uiBlockBeginAlign(block);
871 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");
872 uiButSetFunc(but,retopo_toggle,ob,me);
873 if(G.scene->toolsettings->retopo_mode) {
874 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.");
875 uiButSetFunc(but,retopo_paint_toggle,ob,me);
876 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");
877 uiButSetFunc(but,retopo_do_all_cb,ob,me);
879 uiBlockEndAlign(block);
882 uiBlockBeginAlign(block);
883 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");
884 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");
885 uiDefBut(block, BUT,B_DOCENTERCURSOR, "Center Cursor", 10, 60, 170, 19, 0, 0, 0, 0, 0, "Shifts object's origin to cursor location");
886 uiBlockEndAlign(block);
888 uiBlockBeginAlign(block);
889 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");
890 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");
891 uiBlockEndAlign(block);
893 uiDefIDPoinBut(block, test_meshpoin_but, ID_ME, B_REDR, "TexMesh: ", 190,180,220,19, &me->texcomesh, "Derive texture coordinates from another mesh.");
895 if(me->msticky) val= 1.0; else val= 0.0;
896 uiDefBut(block, LABEL, 0, "Sticky", 190,155,140,19, 0, val, 0, 0, 0, "");
897 uiBlockBeginAlign(block);
898 if(me->msticky==NULL) {
899 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");
901 else uiDefBut(block, BUT, B_DELSTICKY, "Delete", 330,155, 80,19, 0, 0, 0, 0, 0, "Deletes Sticky texture coordinates");
902 uiBlockEndAlign(block);
904 fdata= (G.obedit)? &G.editMesh->fdata: &me->fdata;
905 yco= customdata_buttons(block, me, fdata, CD_MTFACE, &acttface, &acttface_rnd,
906 B_SETTFACE, B_SETTFACE_RND, B_NEWTFACE, "UV Texture", "UV Texture:",
907 "Set active UV texture", "Set rendering UV texture", "Creates a new UV texture layer",
908 "Removes the current UV texture layer", 190, 130);
910 yco= customdata_buttons(block, me, fdata, CD_MCOL, &actmcol, &actmcol_rnd,
911 B_SETMCOL, B_SETMCOL_RND, B_NEWMCOL, "Vertex Color", "Vertex Color:",
912 "Sets active vertex color layer", "Sets rendering vertex color layer", "Creates a new vertex color layer",
913 "Removes the current vertex color layer", 190, yco-5);
916 uiNewPanelHeight(block, 204 - yco);
919 /* *************************** MODIFIERS ******************************** */
921 void do_modifier_panels(unsigned short event)
926 case B_MODIFIER_REDRAW:
927 allqueue(REDRAWBUTSEDIT, 0);
928 allqueue(REDRAWOOPS, 0);
931 case B_MODIFIER_RECALC:
932 allqueue(REDRAWBUTSEDIT, 0);
933 allqueue(REDRAWVIEW3D, 0);
934 allqueue(REDRAWIMAGE, 0);
935 allqueue(REDRAWOOPS, 0);
936 DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA);
937 object_handle_update(ob);
943 static void modifiers_add(void *ob_v, int type)
946 ModifierTypeInfo *mti = modifierType_getInfo(type);
948 if (mti->flags&eModifierTypeFlag_RequiresOriginalData) {
949 ModifierData *md = ob->modifiers.first;
951 while (md && modifierType_getInfo(md->type)->type==eModifierTypeType_OnlyDeform) {
955 BLI_insertlinkbefore(&ob->modifiers, md, modifier_new(type));
957 BLI_addtail(&ob->modifiers, modifier_new(type));
959 BIF_undo_push("Add modifier");
962 typedef struct MenuEntry {
967 static int menuEntry_compare_names(const void *entry1, const void *entry2)
969 return strcmp(((MenuEntry *)entry1)->name, ((MenuEntry *)entry2)->name);
972 static uiBlock *modifiers_add_menu(void *ob_v)
978 MenuEntry entries[NUM_MODIFIER_TYPES];
980 block= uiNewBlock(&curarea->uiblocks, "modifier_add_menu",
981 UI_EMBOSSP, UI_HELV, curarea->win);
982 uiBlockSetButmFunc(block, modifiers_add, ob);
984 for (i=eModifierType_None+1; i<NUM_MODIFIER_TYPES; i++) {
985 ModifierTypeInfo *mti = modifierType_getInfo(i);
987 /* Only allow adding through appropriate other interfaces */
988 if(ELEM3(i, eModifierType_Softbody, eModifierType_Hook, eModifierType_ParticleSystem)) continue;
990 if(ELEM3(i, eModifierType_Cloth, eModifierType_Collision, eModifierType_Fluidsim)) continue;
992 if((mti->flags&eModifierTypeFlag_AcceptsCVs) ||
993 (ob->type==OB_MESH && (mti->flags&eModifierTypeFlag_AcceptsMesh))) {
994 entries[numEntries].name = mti->name;
995 entries[numEntries].ID = i;
1001 qsort(entries, numEntries, sizeof(*entries), menuEntry_compare_names);
1004 for(i = 0; i < numEntries; ++i)
1005 uiDefBut(block, BUTM, B_MODIFIER_RECALC, entries[i].name,
1006 0, yco -= 20, 160, 19, NULL, 0, 0, 1, entries[i].ID, "");
1008 uiTextBoundsBlock(block, 50);
1009 uiBlockSetDirection(block, UI_DOWN);
1014 static void modifiers_del(void *ob_v, void *md_v)
1019 /* It seems on rapid delete it is possible to
1020 * get called twice on same modifier, so make
1021 * sure it is in list.
1023 for (md=ob->modifiers.first; md; md=md->next)
1030 if(md->type==eModifierType_ParticleSystem){
1031 ParticleSystemModifierData *psmd=(ParticleSystemModifierData*)md;
1032 BLI_remlink(&ob->particlesystem, psmd->psys);
1033 psys_free(ob,psmd->psys);
1036 BLI_remlink(&ob->modifiers, md_v);
1038 modifier_free(md_v);
1040 BIF_undo_push("Del modifier");
1043 int mod_moveUp(void *ob_v, void *md_v)
1046 ModifierData *md = md_v;
1049 ModifierTypeInfo *mti = modifierType_getInfo(md->type);
1051 if (mti->type!=eModifierTypeType_OnlyDeform) {
1052 ModifierTypeInfo *nmti = modifierType_getInfo(md->prev->type);
1054 if (nmti->flags&eModifierTypeFlag_RequiresOriginalData)
1058 BLI_remlink(&ob->modifiers, md);
1059 BLI_insertlink(&ob->modifiers, md->prev->prev, md);
1065 static void modifiers_moveUp(void *ob_v, void *md_v)
1067 if( mod_moveUp( ob_v, md_v ) )
1068 error("Cannot move above a modifier requiring original data.");
1070 BIF_undo_push("Move modifier");
1073 int mod_moveDown(void *ob_v, void *md_v)
1076 ModifierData *md = md_v;
1079 ModifierTypeInfo *mti = modifierType_getInfo(md->type);
1081 if (mti->flags&eModifierTypeFlag_RequiresOriginalData) {
1082 ModifierTypeInfo *nmti = modifierType_getInfo(md->next->type);
1084 if (nmti->type!=eModifierTypeType_OnlyDeform)
1088 BLI_remlink(&ob->modifiers, md);
1089 BLI_insertlink(&ob->modifiers, md->next, md);
1095 static void modifiers_moveDown(void *ob_v, void *md_v)
1097 if( mod_moveDown( ob_v, md_v ) )
1098 error("Cannot move beyond a non-deforming modifier.");
1100 BIF_undo_push("Move modifier");
1103 static void modifier_testLatticeObj(char *name, ID **idpp)
1107 for (id= G.main->object.first; id; id= id->next) {
1108 if( strcmp(name, id->name+2)==0 ) {
1109 if (((Object *)id)->type != OB_LATTICE) {
1110 error ("Lattice deform object must be a lattice");
1120 static void modifier_testCurveObj(char *name, ID **idpp)
1124 for (id= G.main->object.first; id; id= id->next) {
1125 if( strcmp(name, id->name+2)==0 ) {
1126 if (((Object *)id)->type != OB_CURVE) {
1127 error ("Curve deform object must be a curve");
1137 static void modifier_testMeshObj(char *name, ID **idpp)
1141 for (id= G.main->object.first; id; id= id->next) {
1142 /* no boolean on its own object */
1143 if(id != (ID *)OBACT) {
1144 if( strcmp(name, id->name+2)==0 ) {
1145 if (((Object *)id)->type != OB_MESH) {
1146 error ("Boolean modifier object must be a mesh");
1157 static void modifier_testArmatureObj(char *name, ID **idpp)
1161 for (id= G.main->object.first; id; id= id->next) {
1162 if( strcmp(name, id->name+2)==0 ) {
1163 if (((Object *)id)->type != OB_ARMATURE) {
1164 error ("Armature deform object must be an armature");
1174 static void modifier_testTexture(char *name, ID **idpp)
1178 for(id = G.main->tex.first; id; id = id->next) {
1179 if(strcmp(name, id->name + 2) == 0) {
1181 /* texture gets user, objects not: delete object = clear modifier */
1189 #if 0 /* this is currently unused, but could be useful in the future */
1190 static void modifier_testMaterial(char *name, ID **idpp)
1194 for(id = G.main->mat.first; id; id = id->next) {
1195 if(strcmp(name, id->name + 2) == 0) {
1204 static void modifier_testImage(char *name, ID **idpp)
1208 for(id = G.main->image.first; id; id = id->next) {
1209 if(strcmp(name, id->name + 2) == 0) {
1217 /* autocomplete callback for ID buttons */
1218 void autocomplete_image(char *str, void *arg_v)
1220 /* search if str matches the beginning of an ID struct */
1222 AutoComplete *autocpl = autocomplete_begin(str, 22);
1225 for(id = G.main->image.first; id; id = id->next)
1226 autocomplete_do_name(autocpl, id->name+2);
1228 autocomplete_end(autocpl, str);
1232 /* autocomplete callback for ID buttons */
1233 void autocomplete_meshob(char *str, void *arg_v)
1235 /* search if str matches the beginning of an ID struct */
1237 AutoComplete *autocpl = autocomplete_begin(str, 22);
1240 for(id = G.main->object.first; id; id = id->next)
1241 if(((Object *)id)->type == OB_MESH)
1242 autocomplete_do_name(autocpl, id->name+2);
1244 autocomplete_end(autocpl, str);
1247 static void modifiers_convertParticles(void *obv, void *mdv)
1250 ModifierData *md = mdv;
1251 ParticleSystem *psys;
1252 ParticleCacheKey *key, **cache;
1253 ParticleSettings *part;
1258 int totvert=0, totedge=0, cvert=0;
1259 int totpart=0, totchild=0;
1261 if(md->type != eModifierType_ParticleSystem) return;
1263 if(G.f & G_PARTICLEEDIT) return;
1265 psys=((ParticleSystemModifierData *)md)->psys;
1268 if(part->draw_as == PART_DRAW_GR || part->draw_as == PART_DRAW_OB) {
1269 make_object_duplilist_real(NULL);
1272 if(part->draw_as != PART_DRAW_PATH || psys->pathcache == 0)
1275 totpart= psys->totcached;
1276 totchild= psys->totchildcache;
1278 if(totchild && (part->draw&PART_DRAW_PARENT)==0)
1282 cache= psys->pathcache;
1283 for(a=0; a<totpart; a++) {
1285 totvert+= key->steps+1;
1286 totedge+= key->steps;
1289 cache= psys->childcache;
1290 for(a=0; a<totchild; a++) {
1292 totvert+= key->steps+1;
1293 totedge+= key->steps;
1296 if(totvert==0) return;
1299 obn= add_object(OB_MESH);
1302 me->totvert= totvert;
1303 me->totedge= totedge;
1305 me->mvert= CustomData_add_layer(&me->vdata, CD_MVERT, CD_CALLOC, NULL, totvert);
1306 me->medge= CustomData_add_layer(&me->edata, CD_MEDGE, CD_CALLOC, NULL, totedge);
1307 me->mface= CustomData_add_layer(&me->fdata, CD_MFACE, CD_CALLOC, NULL, 0);
1312 /* copy coordinates */
1313 cache= psys->pathcache;
1314 for(a=0; a<totpart; a++) {
1317 for(k=0; k<=kmax; k++,key++,cvert++,mvert++) {
1318 VECCOPY(mvert->co,key->co);
1322 medge->flag= ME_EDGEDRAW|ME_EDGERENDER|ME_LOOSEEDGE;
1328 cache=psys->childcache;
1329 for(a=0; a<totchild; a++) {
1332 for(k=0; k<=kmax; k++,key++,cvert++,mvert++) {
1333 VECCOPY(mvert->co,key->co);
1337 medge->flag= ME_EDGEDRAW|ME_EDGERENDER|ME_LOOSEEDGE;
1344 DAG_scene_sort(G.scene);
1346 allqueue(REDRAWVIEW3D, 0);
1347 allqueue(REDRAWOOPS, 0);
1349 BIF_undo_push("Convert particles to mesh object(s).");
1352 static void modifiers_applyModifier(void *obv, void *mdv)
1355 ModifierData *md = mdv;
1357 Mesh *me = ob->data;
1361 error("Modifiers cannot be applied in editmode");
1363 } else if (((ID*) ob->data)->us>1) {
1364 error("Modifiers cannot be applied to multi-user data");
1368 if (md!=ob->modifiers.first) {
1369 if (!okee("Modifier is not first"))
1373 if (ob->type==OB_MESH) {
1374 if(me->mr && multires_modifier_warning()) {
1375 error("Modifier changes topology; cannot apply with multires active");
1379 error("Modifier cannot be applied to Mesh with Shape Keys");
1383 mesh_pmv_off(ob, me);
1385 dm = mesh_create_derived_for_modifier(ob, md);
1387 error("Modifier is disabled or returned error, skipping apply");
1396 else if (ELEM(ob->type, OB_CURVE, OB_SURF)) {
1397 ModifierTypeInfo *mti = modifierType_getInfo(md->type);
1398 Curve *cu = ob->data;
1400 float (*vertexCos)[3];
1402 if (!okee("Apply will only change CV points, not tesselated/bevel vertices"))
1405 if (!(md->mode&eModifierMode_Realtime) || (mti->isDisabled && mti->isDisabled(md))) {
1406 error("Modifier is disabled, skipping apply");
1410 vertexCos = curve_getVertexCos(cu, &cu->nurb, &numVerts);
1411 mti->deformVerts(md, ob, NULL, vertexCos, numVerts);
1412 curve_applyVertexCos(cu, &cu->nurb, vertexCos);
1416 MEM_freeN(vertexCos);
1418 DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA);
1421 error("Cannot apply modifier for this object type");
1426 BLI_remlink(&ob->modifiers, md);
1429 BIF_undo_push("Apply modifier");
1433 static void modifiers_copyModifier(void *ob_v, void *md_v)
1436 ModifierData *md = md_v;
1437 ModifierData *nmd = modifier_new(md->type);
1439 modifier_copyData(md, nmd);
1441 BLI_insertlink(&ob->modifiers, md, nmd);
1443 BIF_undo_push("Copy modifier");
1446 static void modifiers_setOnCage(void *ob_v, void *md_v)
1451 int i, cageIndex = modifiers_getCageIndex(ob, NULL );
1453 for( i = 0, md=ob->modifiers.first; md; ++i, md=md->next )
1455 if( i >= cageIndex )
1456 md->mode ^= eModifierMode_OnCage;
1461 static void modifiers_clearHookOffset(void *ob_v, void *md_v)
1464 ModifierData *md = md_v;
1465 HookModifierData *hmd = (HookModifierData*) md;
1468 Mat4Invert(hmd->object->imat, hmd->object->obmat);
1469 Mat4MulSerie(hmd->parentinv, hmd->object->imat, ob->obmat, NULL, NULL, NULL, NULL, NULL, NULL);
1470 BIF_undo_push("Clear hook offset");
1474 static void modifiers_cursorHookCenter(void *ob_v, void *md_v)
1477 ModifierData *md = md_v;
1478 HookModifierData *hmd = (HookModifierData*) md;
1481 float *curs = give_cursor();
1482 float bmat[3][3], imat[3][3];
1484 where_is_object(ob);
1486 Mat3CpyMat4(bmat, ob->obmat);
1487 Mat3Inv(imat, bmat);
1489 curs= give_cursor();
1490 hmd->cent[0]= curs[0]-ob->obmat[3][0];
1491 hmd->cent[1]= curs[1]-ob->obmat[3][1];
1492 hmd->cent[2]= curs[2]-ob->obmat[3][2];
1493 Mat3MulVecfl(imat, hmd->cent);
1495 BIF_undo_push("Hook cursor center");
1499 static void modifiers_selectHook(void *ob_v, void *md_v)
1501 ModifierData *md = md_v;
1502 HookModifierData *hmd = (HookModifierData*) md;
1507 static void modifiers_reassignHook(void *ob_v, void *md_v)
1509 ModifierData *md = md_v;
1510 HookModifierData *hmd = (HookModifierData*) md;
1512 int *indexar, tot, ok;
1515 ok= hook_getIndexArray(&tot, &indexar, name, cent);
1518 error("Requires selected vertices or active Vertex Group");
1521 MEM_freeN(hmd->indexar);
1524 VECCOPY(hmd->cent, cent);
1525 hmd->indexar = indexar;
1526 hmd->totindex = tot;
1530 static void modifiers_convertToReal(void *ob_v, void *md_v)
1533 ModifierData *md = md_v;
1534 ModifierData *nmd = modifier_new(md->type);
1536 modifier_copyData(md, nmd);
1537 nmd->mode &= ~eModifierMode_Virtual;
1539 BLI_addhead(&ob->modifiers, nmd);
1541 ob->partype = PAROBJECT;
1543 BIF_undo_push("Modifier convert to real");
1546 static void build_uvlayer_menu_vars(CustomData *data, char **menu_string,
1547 int *uvlayer_tmp, char *uvlayer_name)
1551 CustomDataLayer *layer
1552 = &data->layers[CustomData_get_layer_index(data, CD_MTFACE)];
1556 totuv = CustomData_number_of_layers(data, CD_MTFACE);
1558 *menu_string = MEM_callocN(sizeof(**menu_string) * (totuv * 38 + 10),
1560 sprintf(*menu_string, "UV Layer%%t");
1561 for(i = 0; i < totuv; i++) {
1562 /* assign first layer as uvlayer_name if uvlayer_name is null. */
1563 if(strcmp(layer->name, uvlayer_name) == 0) *uvlayer_tmp = i + 1;
1564 sprintf(strtmp, "|%s%%x%d", layer->name, i + 1);
1565 strcat(*menu_string, strtmp);
1569 /* there is no uvlayer defined, or else it was deleted. Assign active
1570 * layer, then recalc modifiers.
1572 if(*uvlayer_tmp == -1) {
1573 if(CustomData_get_active_layer_index(data, CD_MTFACE) != -1) {
1575 layer = data->layers;
1576 for(i = 0; i < CustomData_get_active_layer_index(data, CD_MTFACE);
1578 if(layer->type == CD_MTFACE) (*uvlayer_tmp)++;
1580 strcpy(uvlayer_name, layer->name);
1582 /* update the modifiers */
1583 do_modifier_panels(B_MODIFIER_RECALC);
1585 /* ok we have no uv layers, so make sure menu button knows that.*/
1591 void set_wave_uvlayer(void *arg1, void *arg2)
1593 WaveModifierData *wmd=arg1;
1594 CustomDataLayer *layer = arg2;
1596 /*check we have UV layers*/
1597 if (wmd->uvlayer_tmp < 1) return;
1598 layer = layer + (wmd->uvlayer_tmp-1);
1600 strcpy(wmd->uvlayer_name, layer->name);
1603 void set_displace_uvlayer(void *arg1, void *arg2)
1605 DisplaceModifierData *dmd=arg1;
1606 CustomDataLayer *layer = arg2;
1608 /*check we have UV layers*/
1609 if (dmd->uvlayer_tmp < 1) return;
1610 layer = layer + (dmd->uvlayer_tmp-1);
1612 strcpy(dmd->uvlayer_name, layer->name);
1615 void set_uvproject_uvlayer(void *arg1, void *arg2)
1617 UVProjectModifierData *umd=arg1;
1618 CustomDataLayer *layer = arg2;
1620 /*check we have UV layers*/
1621 if (umd->uvlayer_tmp < 1) return;
1622 layer = layer + (umd->uvlayer_tmp-1);
1624 strcpy(umd->uvlayer_name, layer->name);
1627 static void modifiers_bindMeshDeform(void *ob_v, void *md_v)
1629 MeshDeformModifierData *mmd = (MeshDeformModifierData*) md_v;
1630 Object *ob = (Object*)ob_v;
1633 if(mmd->bindweights) MEM_freeN(mmd->bindweights);
1634 if(mmd->bindcos) MEM_freeN(mmd->bindcos);
1635 if(mmd->dyngrid) MEM_freeN(mmd->dyngrid);
1636 if(mmd->dyninfluences) MEM_freeN(mmd->dyninfluences);
1637 if(mmd->dynverts) MEM_freeN(mmd->dynverts);
1638 mmd->bindweights= NULL;
1641 mmd->dyninfluences= NULL;
1642 mmd->dynverts= NULL;
1644 mmd->totcagevert= 0;
1645 mmd->totinfluence= 0;
1649 int mode= mmd->modifier.mode;
1651 /* force modifier to run, it will call binding routine */
1653 mmd->modifier.mode |= eModifierMode_Realtime;
1655 if(ob->type == OB_MESH) {
1656 dm= mesh_create_derived_view(ob, 0);
1659 else if(ob->type == OB_LATTICE) {
1660 lattice_calc_modifiers(ob);
1662 else if(ob->type==OB_MBALL) {
1663 makeDispListMBall(ob);
1665 else if(ELEM3(ob->type, OB_CURVE, OB_SURF, OB_FONT)) {
1666 makeDispListCurveTypes(ob, 0);
1670 mmd->modifier.mode= mode;
1674 void modifiers_explodeFacepa(void *arg1, void *arg2)
1676 ExplodeModifierData *emd=arg1;
1678 emd->flag |= eExplodeFlag_CalcFaces;
1681 void modifiers_explodeDelVg(void *arg1, void *arg2)
1683 ExplodeModifierData *emd=arg1;
1687 static int modifier_is_fluid_particles(ModifierData *md) {
1688 if(md->type == eModifierType_ParticleSystem) {
1689 if(((ParticleSystemModifierData *)md)->psys->part->type == PART_FLUID)
1694 static void draw_modifier(uiBlock *block, Object *ob, ModifierData *md, int *xco, int *yco, int index, int cageIndex, int lastCageIndex)
1696 ModifierTypeInfo *mti = modifierType_getInfo(md->type);
1698 int isVirtual = md->mode&eModifierMode_Virtual;
1699 int x = *xco, y = *yco, color = md->error?TH_REDALERT:TH_BUT_NEUTRAL;
1700 int editing = (G.obedit==ob);
1701 short height=26, width = 295, buttonWidth = width-120-10;
1704 /* rounded header */
1705 uiBlockSetCol(block, color);
1706 /* roundbox 4 free variables: corner-rounding, nop, roundbox type, shade */
1707 uiDefBut(block, ROUNDBOX, 0, "", x-10, y-4, width, 25, NULL, 7.0, 0.0,
1708 (!isVirtual && (md->mode&eModifierMode_Expanded))?3:15, 20, "");
1709 uiBlockSetCol(block, TH_AUTO);
1711 /* open/close icon */
1713 uiBlockSetEmboss(block, UI_EMBOSSN);
1714 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");
1717 uiBlockSetEmboss(block, UI_EMBOSS);
1720 sprintf(str, "%s parent deform", md->name);
1721 uiDefBut(block, LABEL, 0, str, x+10, y-1, width-110, 19, NULL, 0.0, 0.0, 0.0, 0.0, "Modifier name");
1723 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");
1724 uiButSetFunc(but, modifiers_convertToReal, ob, md);
1726 uiBlockBeginAlign(block);
1727 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");
1729 /* Softbody not allowed in this situation, enforce! */
1730 if ((md->type!=eModifierType_Softbody && md->type!=eModifierType_Collision) || !(ob->pd && ob->pd->deflect)) {
1731 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");
1732 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");
1733 if (mti->flags&eModifierTypeFlag_SupportsEditmode) {
1734 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)");
1737 uiBlockEndAlign(block);
1739 uiBlockSetEmboss(block, UI_EMBOSSR);
1741 if (ob->type==OB_MESH && modifier_couldBeCage(md) && index<=lastCageIndex) {
1744 if (index==cageIndex) {
1745 color = TH_BUT_SETTING;
1746 icon = VICON_EDITMODE_HLT;
1747 } else if (index<cageIndex) {
1748 color = TH_BUT_NEUTRAL;
1749 icon = VICON_EDITMODE_DEHLT;
1751 color = TH_BUT_NEUTRAL;
1754 uiBlockSetCol(block, color);
1755 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");
1756 uiButSetFunc(but, modifiers_setOnCage, ob, md);
1757 uiBlockSetCol(block, TH_AUTO);
1760 uiBlockSetCol(block, TH_BUT_ACTION);
1762 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");
1763 uiButSetFunc(but, modifiers_moveUp, ob, md);
1765 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");
1766 uiButSetFunc(but, modifiers_moveDown, ob, md);
1768 uiBlockSetEmboss(block, UI_EMBOSSN);
1770 // deletion over the deflection panel
1771 // fluid particle modifier can't be deleted here
1772 if(md->type!=eModifierType_Fluidsim && md->type!=eModifierType_Collision && !modifier_is_fluid_particles(md))
1774 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");
1775 uiButSetFunc(but, modifiers_del, ob, md);
1777 uiBlockSetCol(block, TH_AUTO);
1780 uiBlockSetEmboss(block, UI_EMBOSS);
1782 if (isVirtual || !(md->mode&eModifierMode_Expanded)) {
1786 int lx = x + width - 60 - 15;
1788 if (md->type==eModifierType_Subsurf) {
1790 } else if (md->type==eModifierType_Lattice) {
1792 } else if (md->type==eModifierType_Curve) {
1794 } else if (md->type==eModifierType_Build) {
1796 } else if (md->type==eModifierType_Mirror) {
1798 } else if (md->type==eModifierType_Bevel) {
1799 BevelModifierData *bmd = (BevelModifierData*) md;
1800 height = 105; /* height = 124; */
1801 if ((bmd->lim_flags & BME_BEVEL_ANGLE) || ((bmd->lim_flags & BME_BEVEL_WEIGHT) && !(bmd->flags & BME_BEVEL_VERT))) height += 19;
1802 } else if (md->type==eModifierType_EdgeSplit) {
1803 EdgeSplitModifierData *emd = (EdgeSplitModifierData*) md;
1805 if(emd->flags & MOD_EDGESPLIT_FROMANGLE) height += 19;
1806 } else if (md->type==eModifierType_Displace) {
1807 DisplaceModifierData *dmd = (DisplaceModifierData *)md;
1809 if(dmd->texmapping == MOD_DISP_MAP_OBJECT ||
1810 dmd->texmapping == MOD_DISP_MAP_UV)
1812 } else if (md->type==eModifierType_UVProject) {
1813 height = 114 + ((UVProjectModifierData *)md)->num_projectors * 19;
1814 } else if (md->type==eModifierType_Decimate) {
1816 } else if (md->type==eModifierType_Smooth) {
1818 } else if (md->type==eModifierType_Cast) {
1820 } else if (md->type==eModifierType_Wave) {
1821 WaveModifierData *wmd = (WaveModifierData *)md;
1823 if(wmd->texmapping == MOD_WAV_MAP_OBJECT ||
1824 wmd->texmapping == MOD_WAV_MAP_UV)
1826 if(wmd->flag & MOD_WAVE_NORM)
1828 } else if (md->type==eModifierType_Armature) {
1830 } else if (md->type==eModifierType_Hook) {
1831 HookModifierData *hmd = (HookModifierData*) md;
1835 if(hmd->indexar==NULL)
1837 } else if (md->type==eModifierType_Softbody) {
1839 } else if (md->type==eModifierType_Cloth) {
1841 } else if (md->type==eModifierType_Collision) {
1843 } else if (md->type==eModifierType_Fluidsim) {
1845 } else if (md->type==eModifierType_Boolean) {
1847 } else if (md->type==eModifierType_Array) {
1849 } else if (md->type==eModifierType_MeshDeform) {
1850 MeshDeformModifierData *mmd= (MeshDeformModifierData*)md;
1851 height = (mmd->bindcos)? 73: 93;
1852 } else if (md->type==eModifierType_ParticleSystem) {
1854 } else if (md->type==eModifierType_ParticleInstance) {
1856 } else if (md->type==eModifierType_Explode) {
1858 } else if (md->type==eModifierType_Shrinkwrap) {
1859 ShrinkwrapModifierData *smd = (ShrinkwrapModifierData*) md;
1861 if (smd->shrinkType == MOD_SHRINKWRAP_PROJECT)
1864 if(smd->projAxis == 0) height += 19;
1866 else if (smd->shrinkType == MOD_SHRINKWRAP_NEAREST_SURFACE)
1868 } else if (md->type == eModifierType_Mask) {
1870 } else if (md->type==eModifierType_SimpleDeform) {
1871 SimpleDeformModifierData *smd = (SimpleDeformModifierData*) md;
1873 if(smd->origin != NULL) height += 19;
1874 if(smd->mode == MOD_SIMPLEDEFORM_MODE_STRETCH
1875 || smd->mode == MOD_SIMPLEDEFORM_MODE_TAPER )
1878 /* roundbox 4 free variables: corner-rounding, nop, roundbox type, shade */
1879 uiDefBut(block, ROUNDBOX, 0, "", x-10, y-height-2, width, height-2, NULL, 5.0, 0.0, 12, 40, "");
1883 if (!isVirtual && (md->type!=eModifierType_Collision)) {
1884 uiSetButLock(object_data_is_libdata(ob), ERROR_LIBDATA_MESSAGE); /* only here obdata, the rest of modifiers is ob level */
1886 uiBlockBeginAlign(block);
1887 if (md->type==eModifierType_ParticleSystem) {
1888 ParticleSystem *psys;
1889 psys= ((ParticleSystemModifierData *)md)->psys;
1891 if(!(G.f & G_PARTICLEEDIT)) {
1892 if(ELEM3(psys->part->draw_as, PART_DRAW_PATH, PART_DRAW_GR, PART_DRAW_OB) && psys->pathcache) {
1893 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");
1894 uiButSetFunc(but, modifiers_convertParticles, ob, md);
1899 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");
1900 uiButSetFunc(but, modifiers_applyModifier, ob, md);
1903 if (md->type!=eModifierType_Fluidsim && md->type!=eModifierType_Softbody && md->type!=eModifierType_ParticleSystem && (md->type!=eModifierType_Cloth)) {
1904 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");
1905 uiButSetFunc(but, modifiers_copyModifier, ob, md);
1907 uiBlockEndAlign(block);
1909 uiSetButLock(ob && ob->id.lib, ERROR_LIBDATA_MESSAGE);
1914 uiBlockBeginAlign(block);
1915 if (md->type==eModifierType_Subsurf) {
1916 SubsurfModifierData *smd = (SubsurfModifierData*) md;
1917 char subsurfmenu[]="Subsurf Type%t|Catmull-Clark%x0|Simple Subdiv.%x1";
1918 uiDefButS(block, MENU, B_MODIFIER_RECALC, subsurfmenu, lx,(cy-=19),buttonWidth,19, &smd->subdivType, 0, 0, 0, 0, "Selects type of subdivision algorithm.");
1919 uiDefButS(block, NUM, B_MODIFIER_RECALC, "Levels:", lx, (cy-=19), buttonWidth,19, &smd->levels, 1, 6, 0, 0, "Number subdivisions to perform");
1920 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");
1922 /* Disabled until non-EM DerivedMesh implementation is complete */
1925 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");
1926 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");
1929 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");
1930 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");
1931 } else if (md->type==eModifierType_Lattice) {
1932 LatticeModifierData *lmd = (LatticeModifierData*) md;
1933 uiDefIDPoinBut(block, modifier_testLatticeObj, ID_OB, B_CHANGEDEP, "Ob: ", lx, (cy-=19), buttonWidth,19, &lmd->object, "Lattice object to deform with");
1934 but=uiDefBut(block, TEX, B_MODIFIER_RECALC, "VGroup: ", lx, (cy-=19), buttonWidth,19, &lmd->name, 0.0, 31.0, 0, 0, "Vertex Group name");
1935 uiButSetCompleteFunc(but, autocomplete_vgroup, (void *)ob);
1936 } else if (md->type==eModifierType_Curve) {
1937 CurveModifierData *cmd = (CurveModifierData*) md;
1938 uiDefIDPoinBut(block, modifier_testCurveObj, ID_OB, B_CHANGEDEP, "Ob: ", lx, (cy-=19), buttonWidth,19, &cmd->object, "Curve object to deform with");
1939 but=uiDefBut(block, TEX, B_MODIFIER_RECALC, "VGroup: ", lx, (cy-=19), buttonWidth,19, &cmd->name, 0.0, 31.0, 0, 0, "Vertex Group name");
1940 uiButSetCompleteFunc(but, autocomplete_vgroup, (void *)ob);
1942 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");
1943 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");
1944 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");
1945 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");
1946 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");
1947 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");
1948 } else if (md->type==eModifierType_Build) {
1949 BuildModifierData *bmd = (BuildModifierData*) md;
1950 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");
1951 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");
1952 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.");
1953 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.");
1954 } else if (md->type==eModifierType_Mirror) {
1955 MirrorModifierData *mmd = (MirrorModifierData*) md;
1956 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");
1957 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");
1958 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");
1959 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");
1960 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");
1961 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)");
1962 uiDefButBitS(block, TOG, MOD_MIR_MIRROR_U, B_MODIFIER_RECALC,
1964 lx, (cy-=19), buttonWidth/2, 19,
1965 &mmd->flag, 0, 0, 0, 0,
1966 "Mirror the U texture coordinate around "
1968 uiDefButBitS(block, TOG, MOD_MIR_MIRROR_V, B_MODIFIER_RECALC,
1970 lx + buttonWidth/2 + 1, cy, buttonWidth/2, 19,
1971 &mmd->flag, 0, 0, 0, 0,
1972 "Mirror the V texture coordinate around "
1974 uiDefIDPoinBut(block, test_obpoin_but, ID_OB, B_CHANGEDEP,
1975 "Ob: ", lx, (cy -= 19), buttonWidth, 19,
1977 "Object to use as mirror");
1978 } else if (md->type==eModifierType_Bevel) {
1979 BevelModifierData *bmd = (BevelModifierData*) md;
1980 /*uiDefButS(block, ROW, B_MODIFIER_RECALC, "Distance",
1981 lx, (cy -= 19), (buttonWidth/2), 19, &bmd->val_flags,
1983 "Interpret bevel value as a constant distance from each edge");
1984 uiDefButS(block, ROW, B_MODIFIER_RECALC, "Radius",
1985 (lx+buttonWidth/2), cy, (buttonWidth - buttonWidth/2), 19, &bmd->val_flags,
1986 11.0, BME_BEVEL_RADIUS, 0, 0,
1987 "Interpret bevel value as a radius - smaller angles will be beveled more");*/
1988 uiBlockBeginAlign(block);
1989 uiDefButF(block, NUM, B_MODIFIER_RECALC, "Width: ",
1990 lx, (cy -= 19), buttonWidth, 19, &bmd->value,
1992 "Bevel value/amount");
1993 /*uiDefButI(block, NUM, B_MODIFIER_RECALC, "Recurs",
1994 lx, (cy -= 19), buttonWidth, 19, &bmd->res,
1996 "Number of times to bevel");*/
1997 uiDefButBitS(block, TOG, BME_BEVEL_VERT,
1998 B_MODIFIER_RECALC, "Only Vertices",
1999 lx, (cy -= 19), buttonWidth, 19,
2000 &bmd->flags, 0, 0, 0, 0,
2001 "Bevel only verts/corners; not edges");
2002 uiBlockEndAlign(block);
2004 uiDefBut(block, LABEL, 1, "Limit using:", lx, (cy-=25), buttonWidth,19, NULL, 0.0, 0.0, 0, 0, "");
2005 uiBlockBeginAlign(block);
2006 uiDefButS(block, ROW, B_MODIFIER_RECALC, "None",
2007 lx, (cy -= 19), (buttonWidth/3), 19, &bmd->lim_flags,
2009 "Bevel the entire mesh by a constant amount");
2010 uiDefButS(block, ROW, B_MODIFIER_RECALC, "Angle",
2011 (lx+buttonWidth/3), cy, (buttonWidth/3), 19, &bmd->lim_flags,
2012 12.0, BME_BEVEL_ANGLE, 0, 0,
2013 "Only bevel edges with sharp enough angles between faces");
2014 uiDefButS(block, ROW, B_MODIFIER_RECALC, "BevWeight",
2015 lx+(2*buttonWidth/3), cy, buttonWidth-2*(buttonWidth/3), 19, &bmd->lim_flags,
2016 12.0, BME_BEVEL_WEIGHT, 0, 0,
2017 "Use bevel weights to determine how much bevel is applied; apply them separately in vert/edge select mode");
2018 if ((bmd->lim_flags & BME_BEVEL_WEIGHT) && !(bmd->flags & BME_BEVEL_VERT)) {
2019 uiDefButS(block, ROW, B_MODIFIER_RECALC, "Min",
2020 lx, (cy -= 19), (buttonWidth/3), 19, &bmd->e_flags,
2021 13.0, BME_BEVEL_EMIN, 0, 0,
2022 "The sharpest edge's weight is used when weighting a vert");
2023 uiDefButS(block, ROW, B_MODIFIER_RECALC, "Average",
2024 (lx+buttonWidth/3), cy, (buttonWidth/3), 19, &bmd->e_flags,
2026 "The edge weights are averaged when weighting a vert");
2027 uiDefButS(block, ROW, B_MODIFIER_RECALC, "Max",
2028 (lx+2*(buttonWidth/3)), cy, buttonWidth-2*(buttonWidth/3), 19, &bmd->e_flags,
2029 13.0, BME_BEVEL_EMAX, 0, 0,
2030 "The largest edge's wieght is used when weighting a vert");
2032 else if (bmd->lim_flags & BME_BEVEL_ANGLE) {
2033 uiDefButF(block, NUM, B_MODIFIER_RECALC, "Angle:",
2034 lx, (cy -= 19), buttonWidth, 19, &bmd->bevel_angle,
2036 "Angle above which to bevel edges");
2038 } else if (md->type==eModifierType_EdgeSplit) {
2039 EdgeSplitModifierData *emd = (EdgeSplitModifierData*) md;
2040 uiDefButBitI(block, TOG, MOD_EDGESPLIT_FROMANGLE,
2041 B_MODIFIER_RECALC, "From Edge Angle",
2042 lx, (cy -= 19), buttonWidth, 19,
2043 &emd->flags, 0, 0, 0, 0,
2044 "Split edges with high angle between faces");
2045 if(emd->flags & MOD_EDGESPLIT_FROMANGLE) {
2046 uiDefButF(block, NUM, B_MODIFIER_RECALC, "Split Angle:",
2047 lx, (cy -= 19), buttonWidth, 19, &emd->split_angle,
2049 "Angle above which to split edges");
2051 uiDefButBitI(block, TOG, MOD_EDGESPLIT_FROMFLAG,
2052 B_MODIFIER_RECALC, "From Marked As Sharp",
2053 lx, (cy -= 19), buttonWidth, 19,
2054 &emd->flags, 0, 0, 0, 0,
2055 "Split edges that are marked as sharp");
2056 } else if (md->type==eModifierType_Displace) {
2057 DisplaceModifierData *dmd = (DisplaceModifierData*) md;
2058 but = uiDefBut(block, TEX, B_MODIFIER_RECALC, "VGroup: ",
2059 lx, (cy -= 19), buttonWidth, 19,
2060 &dmd->defgrp_name, 0.0, 31.0, 0, 0,
2061 "Name of vertex group to displace"
2062 " (displace whole mesh if blank)");
2063 uiButSetCompleteFunc(but, autocomplete_vgroup, (void *)ob);
2064 uiDefIDPoinBut(block, modifier_testTexture, ID_TE, B_CHANGEDEP,
2065 "Texture: ", lx, (cy -= 19), buttonWidth, 19,
2067 "Texture to use as displacement input");
2068 uiDefButF(block, NUM, B_MODIFIER_RECALC, "Midlevel:",
2069 lx, (cy -= 19), buttonWidth, 19, &dmd->midlevel,
2071 "Material value that gives no displacement");
2072 uiDefButF(block, NUM, B_MODIFIER_RECALC, "Strength:",
2073 lx, (cy -= 19), buttonWidth, 19, &dmd->strength,
2074 -1000, 1000, 10, 0.1,
2075 "Strength of displacement");
2076 sprintf(str, "Direction%%t|Normal%%x%d|RGB -> XYZ%%x%d|"
2077 "Z%%x%d|Y%%x%d|X%%x%d",
2078 MOD_DISP_DIR_NOR, MOD_DISP_DIR_RGB_XYZ,
2079 MOD_DISP_DIR_Z, MOD_DISP_DIR_Y, MOD_DISP_DIR_X);
2080 uiDefButI(block, MENU, B_MODIFIER_RECALC, str,
2081 lx, (cy -= 19), buttonWidth, 19, &dmd->direction,
2082 0.0, 1.0, 0, 0, "Displace direction");
2083 sprintf(str, "Texture Coordinates%%t"
2084 "|Local%%x%d|Global%%x%d|Object%%x%d|UV%%x%d",
2085 MOD_DISP_MAP_LOCAL, MOD_DISP_MAP_GLOBAL,
2086 MOD_DISP_MAP_OBJECT, MOD_DISP_MAP_UV);
2087 uiDefButI(block, MENU, B_MODIFIER_RECALC, str,
2088 lx, (cy -= 19), buttonWidth, 19, &dmd->texmapping,
2090 "Texture coordinates used for displacement input");
2091 if (dmd->texmapping == MOD_DISP_MAP_UV) {
2094 CustomData *fdata = G.obedit ? &G.editMesh->fdata
2095 : &((Mesh*)ob->data)->fdata;
2096 build_uvlayer_menu_vars(fdata, &strtmp, &dmd->uvlayer_tmp,
2098 but = uiDefButI(block, MENU, B_MODIFIER_RECALC, strtmp,
2099 lx, (cy -= 19), buttonWidth, 19, &dmd->uvlayer_tmp,
2100 0.0, 1.0, 0, 0, "Set the UV layer to use");
2102 i = CustomData_get_layer_index(fdata, CD_MTFACE);
2103 uiButSetFunc(but, set_displace_uvlayer, dmd,
2106 if(dmd->texmapping == MOD_DISP_MAP_OBJECT) {
2107 uiDefIDPoinBut(block, test_obpoin_but, ID_OB, B_CHANGEDEP,
2108 "Ob: ", lx, (cy -= 19), buttonWidth, 19,
2110 "Object to get texture coordinates from");
2112 } else if (md->type==eModifierType_UVProject) {
2113 UVProjectModifierData *umd = (UVProjectModifierData *) md;
2116 CustomData *fdata = G.obedit ? &G.editMesh->fdata
2117 : &((Mesh*)ob->data)->fdata;
2118 build_uvlayer_menu_vars(fdata, &strtmp, &umd->uvlayer_tmp,
2120 but = uiDefButI(block, MENU, B_MODIFIER_RECALC, strtmp,
2121 lx, (cy -= 19), buttonWidth, 19, &umd->uvlayer_tmp,
2122 0.0, 1.0, 0, 0, "Set the UV layer to use");
2123 i = CustomData_get_layer_index(fdata, CD_MTFACE);
2124 uiButSetFunc(but, set_uvproject_uvlayer, umd, &fdata->layers[i]);
2126 uiDefButF(block, NUM, B_MODIFIER_RECALC, "AspX:",
2127 lx, (cy -= 19), buttonWidth / 2, 19, &umd->aspectx,
2129 "Horizontal Aspect Ratio");
2130 uiDefButF(block, NUM, B_MODIFIER_RECALC, "AspY:",
2131 lx + (buttonWidth / 2) + 1, cy, buttonWidth / 2, 19,
2134 "Vertical Aspect Ratio");
2135 uiDefButI(block, NUM, B_MODIFIER_RECALC, "Projectors:",
2136 lx, (cy -= 19), buttonWidth, 19, &umd->num_projectors,
2137 1, MOD_UVPROJECT_MAXPROJECTORS, 0, 0,
2138 "Number of objects to use as projectors");
2139 for(i = 0; i < umd->num_projectors; ++i) {
2140 uiDefIDPoinBut(block, test_obpoin_but, ID_OB, B_CHANGEDEP,
2141 "Ob: ", lx, (cy -= 19), buttonWidth, 19,
2142 &umd->projectors[i],
2143 "Object to use as projector");
2145 uiDefIDPoinBut(block, modifier_testImage, ID_IM, B_CHANGEDEP,
2146 "Image: ", lx, (cy -= 19), buttonWidth, 19,
2148 "Image to project (only faces with this image "
2150 uiButSetCompleteFunc(but, autocomplete_image, (void *)ob);
2151 uiDefButBitI(block, TOG, MOD_UVPROJECT_OVERRIDEIMAGE,
2152 B_MODIFIER_RECALC, "Override Image",
2153 lx, (cy -= 19), buttonWidth, 19,
2154 &umd->flags, 0, 0, 0, 0,
2155 "Override faces' current images with the "
2157 } else if (md->type==eModifierType_Decimate) {
2158 DecimateModifierData *dmd = (DecimateModifierData*) md;
2159 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");
2160 sprintf(str, "Face Count: %d", dmd->faceCount);
2161 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");
2162 } else if (md->type==eModifierType_Mask) {
2163 MaskModifierData *mmd = (MaskModifierData *)md;
2165 sprintf(str, "Mask Mode%%t|Vertex Group%%x%d|Selected Bones%%x%d|",
2166 MOD_MASK_MODE_VGROUP,MOD_MASK_MODE_ARM);
2167 uiDefButI(block, MENU, B_MODIFIER_RECALC, str,
2168 lx, (cy -= 19), buttonWidth, 19, &mmd->mode,
2169 0.0, 1.0, 0, 0, "How masking region is defined");
2171 if (mmd->mode == MOD_MASK_MODE_ARM) {
2172 uiDefIDPoinBut(block, modifier_testArmatureObj, ID_OB, B_CHANGEDEP,
2173 "Ob: ", lx, (cy -= 19), buttonWidth, 19, &mmd->ob_arm,
2174 "Armature to use as source of bones to mask");
2177 but=uiDefBut(block, TEX, B_MODIFIER_RECALC, "VGroup: ",
2178 lx, (cy-=19), buttonWidth, 19, &mmd->vgroup,
2179 0.0, 31.0, 0, 0, "Vertex Group name");
2180 uiButSetCompleteFunc(but, autocomplete_vgroup, (void *)ob);
2183 uiDefButBitI(block, TOG, MOD_MASK_INV, B_MODIFIER_RECALC, "Inverse",
2184 lx, (cy-=19), buttonWidth, 19, &mmd->flag,
2185 0, 0, 0, 0, "Use vertices that are not part of region defined");
2186 } else if (md->type==eModifierType_Smooth) {
2187 SmoothModifierData *smd = (SmoothModifierData*) md;
2189 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");
2190 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");
2191 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");
2193 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)");
2194 uiDefButS(block, NUM, B_MODIFIER_RECALC, "Repeat:", lx,(cy-=19),buttonWidth, 19, &smd->repeat, 0.0, 30.0, 1, 0, "Number of smoothing iterations");
2195 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");
2196 } else if (md->type==eModifierType_Cast) {
2197 CastModifierData *cmd = (CastModifierData*) md;
2199 char casttypemenu[]="Projection Type%t|Sphere%x0|Cylinder%x1|Cuboid%x2";
2200 uiDefButS(block, MENU, B_MODIFIER_RECALC, casttypemenu, lx,(cy-=19),buttonWidth - 30,19, &cmd->type, 0, 0, 0, 0, "Projection type to apply");
2201 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");
2202 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");
2203 if (cmd->type != MOD_CAST_TYPE_CYLINDER) {
2204 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");
2206 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");
2207 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)");
2208 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)");
2209 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)");
2210 if (ob->type == OB_MESH) {
2211 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");
2213 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");
2215 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");
2217 } else if (md->type==eModifierType_Wave) {
2218 WaveModifierData *wmd = (WaveModifierData*) md;
2219 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");
2220 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");
2221 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");
2222 uiDefButBitS(block, TOG, MOD_WAVE_NORM, B_MODIFIER_RECALC, "Normals", lx,(cy-=19),buttonWidth,19, &wmd->flag, 0, 0, 0, 0, "Displace along normals");
2223 if (wmd->flag & MOD_WAVE_NORM){
2224 if (ob->type==OB_MESH) {
2225 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");
2226 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");
2227 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");
2230 uiDefBut(block, LABEL, 1, "Meshes Only", lx, (cy-=19), buttonWidth,19, NULL, 0.0, 0.0, 0, 0, "");
2233 uiBlockBeginAlign(block);
2235 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");
2237 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");
2238 uiDefButF(block, NUM, B_MODIFIER_RECALC, "Lifetime:", lx,(cy-=19),buttonWidth,19, &wmd->lifetime, -MAXFRAMEF, MAXFRAMEF, 100, 0, "Specify the lifespan of the wave");
2239 uiDefButF(block, NUM, B_MODIFIER_RECALC, "Damptime:", lx,(cy-=19),buttonWidth,19, &wmd->damp, -MAXFRAMEF, MAXFRAMEF, 100, 0, "Specify the dampingtime of the wave");
2240 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");
2243 uiBlockBeginAlign(block);
2244 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");
2245 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");
2246 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)");
2247 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");
2248 uiDefIDPoinBut(block, modifier_testTexture, ID_TE, B_CHANGEDEP,"Texture: ", lx, (cy -= 19), 220, 19, &wmd->texture,"Texture with which to modulate wave");
2249 sprintf(str, "Texture Coordinates%%t"
2250 "|Local%%x%d|Global%%x%d|Object%%x%d|UV%%x%d",
2251 MOD_WAV_MAP_LOCAL, MOD_WAV_MAP_GLOBAL,
2252 MOD_WAV_MAP_OBJECT, MOD_WAV_MAP_UV);
2253 uiDefButI(block, MENU, B_MODIFIER_RECALC, str,
2254 lx, (cy -= 19), 220, 19, &wmd->texmapping,
2256 "Texture coordinates used for modulation input");
2257 if (wmd->texmapping == MOD_WAV_MAP_UV) {
2260 CustomData *fdata = G.obedit ? &G.editMesh->fdata
2261 : &((Mesh*)ob->data)->fdata;
2262 build_uvlayer_menu_vars(fdata, &strtmp, &wmd->uvlayer_tmp,
2264 but = uiDefButI(block, MENU, B_MODIFIER_RECALC, strtmp,
2265 lx, (cy -= 19), 220, 19, &wmd->uvlayer_tmp,
2266 0.0, 1.0, 0, 0, "Set the UV layer to use");
2268 i = CustomData_get_layer_index(fdata, CD_MTFACE);
2269 uiButSetFunc(but, set_wave_uvlayer, wmd,
2272 if(wmd->texmapping == MOD_DISP_MAP_OBJECT) {
2273 uiDefIDPoinBut(block, test_obpoin_but, ID_OB, B_CHANGEDEP,
2274 "Ob: ", lx, (cy -= 19), 220, 19,
2276 "Object to get texture coordinates from");
2279 uiBlockBeginAlign(block);
2280 uiDefButF(block, NUMSLI, B_MODIFIER_RECALC, "Speed:", lx,(cy-=19),220,19, &wmd->speed, -2.0, 2.0, 0, 0, "Specify the wave speed");
2281 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");
2282 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");
2283 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");
2284 } else if (md->type==eModifierType_Armature) {
2285 ArmatureModifierData *amd = (ArmatureModifierData*) md;
2286 uiDefIDPoinBut(block, modifier_testArmatureObj, ID_OB, B_CHANGEDEP, "Ob: ", lx, (cy-=19), buttonWidth,19, &amd->object, "Armature object to deform with");
2288 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");
2289 uiButSetCompleteFunc(but, autocomplete_vgroup, (void *)ob);
2290 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");
2292 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");
2293 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");
2294 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");
2295 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");
2297 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");
2299 } else if (md->type==eModifierType_Hook) {
2300 HookModifierData *hmd = (HookModifierData*) md;
2301 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");
2302 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");
2303 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");
2304 if(hmd->indexar==NULL) {
2305 but=uiDefBut(block, TEX, B_MODIFIER_RECALC, "VGroup: ", lx, (cy-=19), buttonWidth,19, &hmd->name, 0.0, 31.0, 0, 0, "Vertex Group name");
2306 uiButSetCompleteFunc(but, autocomplete_vgroup, (void *)ob);
2308 uiBlockBeginAlign(block);
2309 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");
2310 uiButSetFunc(but, modifiers_clearHookOffset, ob, md);
2311 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");
2312 uiButSetFunc(but, modifiers_cursorHookCenter, ob, md);
2315 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");
2316 uiButSetFunc(but, modifiers_selectHook, ob, md);
2317 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");
2318 uiButSetFunc(but, modifiers_reassignHook, ob, md);
2320 } else if (md->type==eModifierType_Softbody) {
2321 uiDefBut(block, LABEL, 1, "See Soft Body panel.", lx, (cy-=19), buttonWidth,19, NULL, 0.0, 0.0, 0, 0, "");
2322 } else if (md->type==eModifierType_Cloth) {
2323 uiDefBut(block, LABEL, 1, "See Cloth panel.", lx, (cy-=19), buttonWidth,19, NULL, 0.0, 0.0, 0, 0, "");
2325 } else if (md->type==eModifierType_Collision) {
2326 uiDefBut(block, LABEL, 1, "See Collision panel.", lx, (cy-=19), buttonWidth,19, NULL, 0.0, 0.0, 0, 0, "");
2327 } else if (md->type==eModifierType_Fluidsim) {
2328 uiDefBut(block, LABEL, 1, "See Fluidsim panel.", lx, (cy-=19), buttonWidth,19, NULL, 0.0, 0.0, 0, 0, "");
2329 } else if (md->type==eModifierType_Boolean) {
2330 BooleanModifierData *bmd = (BooleanModifierData*) md;
2331 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");
2332 uiDefIDPoinBut(block, modifier_testMeshObj, ID_OB, B_CHANGEDEP, "Ob: ", lx, (cy-=19), buttonWidth,19, &bmd->object, "Mesh object to use for boolean operation");
2333 } else if (md->type==eModifierType_Array) {
2334 ArrayModifierData *amd = (ArrayModifierData*) md;
2335 float range = 10000;
2336 int cytop, halfwidth = (width - 5)/2 - 15;
2337 int halflx = lx + halfwidth + 10;
2339 uiBlockSetEmboss(block, UI_EMBOSSX);
2340 uiBlockEndAlign(block);
2342 /* length parameters */
2343 uiBlockBeginAlign(block);
2344 sprintf(str, "Length Fit%%t|Fixed Count%%x%d|Fixed Length%%x%d"
2345 "|Fit To Curve Length%%x%d",
2346 MOD_ARR_FIXEDCOUNT, MOD_ARR_FITLENGTH, MOD_ARR_FITCURVE);
2347 uiDefButI(block, MENU, B_MODIFIER_RECALC, str,
2348 lx, (cy-=19), buttonWidth, 19, &amd->fit_type,
2349 0.0, 1.0, 0, 0, "Array length calculation method");
2350 switch(amd->fit_type)
2352 case MOD_ARR_FIXEDCOUNT:
2353 uiDefButI(block, NUM, B_MODIFIER_RECALC, "Count:",
2354 lx, (cy -= 19), buttonWidth, 19, &amd->count,
2355 1, 1000, 0, 0, "Number of duplicates to make");
2357 case MOD_ARR_FITLENGTH:
2358 uiDefButF(block, NUM, B_MODIFIER_RECALC, "Length:",
2359 lx, (cy -= 19), buttonWidth, 19, &amd->length,
2361 "Length to fit array within");
2363 case MOD_ARR_FITCURVE:
2364 uiDefIDPoinBut(block, modifier_testCurveObj, ID_OB,
2365 B_CHANGEDEP, "Ob: ",
2366 lx, (cy -= 19), buttonWidth, 19, &amd->curve_ob,
2367 "Curve object to fit array length to");
2370 uiBlockEndAlign(block);
2372 /* offset parameters */
2375 uiBlockBeginAlign(block);
2376 uiDefButBitI(block, TOG, MOD_ARR_OFF_CONST, B_MODIFIER_RECALC,
2377 "Constant Offset", lx, (cy-=19), halfwidth, 19,
2378 &amd->offset_type, 0, 0, 0, 0,
2379 "Constant offset between duplicates "
2380 "(local coordinates)");
2381 uiDefButF(block, NUM, B_MODIFIER_RECALC, "X:",
2382 lx, (cy-=19), halfwidth, 19,
2384 -range, range, 10, 3,
2385 "Constant component for duplicate offsets "
2386 "(local coordinates)");
2387 uiDefButF(block, NUM, B_MODIFIER_RECALC, "Y:",
2388 lx, (cy-=19), halfwidth, 19,
2390 -range, range, 10, 3,
2391 "Constant component for duplicate offsets "
2392 "(local coordinates)");
2393 uiDefButF(block, NUM, B_MODIFIER_RECALC, "Z:",
2394 lx, (cy-=19), halfwidth, 19,
2396 -range, range, 10, 3,
2397 "Constant component for duplicate offsets "
2398 "(local coordinates)");
2399 uiBlockEndAlign(block);
2402 uiBlockBeginAlign(block);
2403 uiDefButBitI(block, TOG, MOD_ARR_OFF_RELATIVE, B_MODIFIER_RECALC,
2404 "Relative Offset", halflx, (cy-=19), halfwidth, 19,
2405 &amd->offset_type, 0, 0, 0, 0,
2406 "Offset between duplicates relative to object width "
2407 "(local coordinates)");
2408 uiDefButF(block, NUM, B_MODIFIER_RECALC, "X:",
2409 halflx, (cy-=19), halfwidth, 19,
2411 -range, range, 10, 3,
2412 "Component for duplicate offsets relative to object "
2413 "width (local coordinates)");
2414 uiDefButF(block, NUM, B_MODIFIER_RECALC, "Y:",
2415 halflx, (cy-=19), halfwidth, 19,
2417 -range, range, 10, 3,
2418 "Component for duplicate offsets relative to object "
2419 "width (local coordinates)");
2420 uiDefButF(block, NUM, B_MODIFIER_RECALC, "Z:",
2421 halflx, (cy-=19), halfwidth, 19,
2423 -range, range, 10, 3,
2424 "Component for duplicate offsets relative to object "
2425 "width (local coordinates)");
2426 uiBlockEndAlign(block);
2428 /* vertex merging parameters */
2432 uiBlockBeginAlign(block);
2433 uiDefButBitI(block, TOG, MOD_ARR_MERGE, B_MODIFIER_RECALC,
2435 lx, (cy-=19), halfwidth/2, 19, &amd->flags,
2437 "Merge vertices in adjacent duplicates");
2438 uiDefButBitI(block, TOG, MOD_ARR_MERGEFINAL, B_MODIFIER_RECALC,
2440 lx + halfwidth/2, cy, (halfwidth+1)/2, 19,
2443 "Merge vertices in first duplicate with vertices"
2444 " in last duplicate");
2445 uiDefButF(block, NUM, B_MODIFIER_RECALC, "Limit:",
2446 lx, (cy-=19), halfwidth, 19, &amd->merge_dist,
2448 "Limit below which to merge vertices");
2452 uiBlockBeginAlign(block);
2453 uiDefButBitI(block, TOG, MOD_ARR_OFF_OBJ, B_MODIFIER_RECALC,
2454 "Object Offset", halflx, (cy -= 19), halfwidth, 19,
2455 &amd->offset_type, 0, 0, 0, 0,
2456 "Add an object transformation to the total offset");
2457 uiDefIDPoinBut(block, test_obpoin_but, ID_OB, B_CHANGEDEP,
2458 "Ob: ", halflx, (cy -= 19), halfwidth, 19,
2460 "Object from which to take offset transformation");
2461 uiBlockEndAlign(block);
2464 but = uiDefIDPoinBut(block, test_meshobpoin_but, ID_OB,
2465 B_CHANGEDEP, "Start cap: ",
2466 lx, (cy -= 19), halfwidth, 19,
2468 "Mesh object to use as start cap");
2469 uiButSetCompleteFunc(but, autocomplete_meshob, (void *)ob);
2470 but = uiDefIDPoinBut(block, test_meshobpoin_but, ID_OB,
2471 B_CHANGEDEP, "End cap: ",
2472 halflx, cy, halfwidth, 19,
2474 "Mesh object to use as end cap");
2475 uiButSetCompleteFunc(but, autocomplete_meshob, (void *)ob);
2476 } else if (md->type==eModifierType_MeshDeform) {
2477 MeshDeformModifierData *mmd = (MeshDeformModifierData*) md;
2479 uiBlockBeginAlign(block);
2480 uiDefIDPoinBut(block, test_meshobpoin_but, ID_OB, B_CHANGEDEP, "Ob: ", lx, (cy-=19), buttonWidth,19, &mmd->object, "Mesh object to be use as cage");
2481 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");
2482 uiButSetCompleteFunc(but, autocomplete_vgroup, (void *)ob);
2483 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");
2485 uiBlockBeginAlign(block);
2487 but= uiDefBut(block, BUT, B_MODIFIER_RECALC, "Unbind", lx,(cy-=24), buttonWidth,19, 0, 0, 0, 0, 0, "Unbind mesh from cage");
2488 uiButSetFunc(but,modifiers_bindMeshDeform,ob,md);
2491 but= uiDefBut(block, BUT, B_MODIFIER_RECALC, "Bind", lx,(cy-=24), buttonWidth,19, 0, 0, 0, 0, 0, "Bind mesh to cage");
2492 uiButSetFunc(but,modifiers_bindMeshDeform,ob,md);
2493 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");
2494 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!)");
2496 uiBlockEndAlign(block);
2497 } else if (md->type==eModifierType_ParticleSystem) {
2498 uiDefBut(block, LABEL, 1, "See Particle buttons.", lx, (cy-=19), buttonWidth,19, NULL, 0.0, 0.0, 0, 0, "");
2499 } else if (md->type==eModifierType_ParticleInstance) {
2500 ParticleInstanceModifierData *pimd = (ParticleInstanceModifierData*) md;
2501 uiDefIDPoinBut(block, test_obpoin_but, ID_OB, B_CHANGEDEP, "Ob: ", lx, (cy -= 19), buttonWidth, 19, &pimd->ob, "Object that has the particlesystem");
2502 uiDefButS(block, NUM, B_MODIFIER_RECALC, "PSYS:", lx, (cy -= 19), buttonWidth, 19, &pimd->psys, 1, 10, 10, 3, "Particlesystem number in the object");
2503 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");
2504 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");
2505 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");
2506 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");
2507 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");
2508 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");
2509 } else if (md->type==eModifierType_Explode) {
2510 ExplodeModifierData *emd = (ExplodeModifierData*) md;
2512 char *menustr= get_vertexgroup_menustr(ob);
2513 int defCount=BLI_countlist(&ob->defbase);
2514 if(defCount==0) emd->vgroup=0;
2515 uiBlockBeginAlign(block);
2516 but=uiDefButS(block, MENU, B_MODIFIER_RECALC, menustr, lx, (cy-=19), buttonWidth-20,19, &emd->vgroup, 0, defCount, 0, 0, "Protect this vertex group");
2517 uiButSetFunc(but,modifiers_explodeFacepa,emd,0);
2520 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");
2521 uiButSetFunc(but, modifiers_explodeDelVg, (void *)emd, (void *)NULL);
2524 but=uiDefButF(block, NUMSLI, B_MODIFIER_RECALC, "", lx, (cy-=19), buttonWidth,19, &emd->protect, 0.0f, 1.0f, 0, 0, "Clean vertex group edges");
2525 uiButSetFunc(but,modifiers_explodeFacepa,emd,0);
2527 but=uiDefBut(block, BUT, B_MODIFIER_RECALC, "Refresh", lx, (cy-=19), buttonWidth/2,19, 0, 0, 0, 0, 0, "Recalculate faces assigned to particles");
2528 uiButSetFunc(but,modifiers_explodeFacepa,emd,0);
2530 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");
2531 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");
2532 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");
2533 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");
2534 uiBlockEndAlign(block);
2535 } else if (md->type==eModifierType_Shrinkwrap) {
2536 ShrinkwrapModifierData *smd = (ShrinkwrapModifierData*) md;
2538 char shrinktypemenu[]="Shrinkwrap type%t|nearest surface point %x0|projection %x1|nearest vertex %x2";
2540 uiDefIDPoinBut(block, modifier_testMeshObj, ID_OB, B_CHANGEDEP, "Ob: ", lx, (cy-=19), buttonWidth,19, &smd->target, "Target to shrink to");
2542 but=uiDefBut(block, TEX, B_MODIFIER_RECALC, "VGroup: ", lx, (cy-=19), buttonWidth,19, &smd->vgroup_name, 0, 31, 0, 0, "Vertex Group name");
2543 uiButSetCompleteFunc(but, autocomplete_vgroup, (void *)ob);
2545 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");
2548 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.");
2550 if (smd->shrinkType == MOD_SHRINKWRAP_PROJECT){
2553 /* UI for projection axis */
2554 uiBlockBeginAlign(block);
2555 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");
2556 if(smd->projAxis == 0)
2558 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");
2561 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");
2562 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");
2563 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");
2566 /* allowed directions of projection axis */
2567 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");
2568 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");
2570 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");
2571 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");
2572 uiDefIDPoinBut(block, modifier_testMeshObj, ID_OB, B_CHANGEDEP, "Ob2: ", lx, (cy-=19), buttonWidth,19, &smd->auxTarget, "Aditional mesh to project over");
2574 else if (smd->shrinkType == MOD_SHRINKWRAP_NEAREST_SURFACE){
2575 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");
2578 uiBlockEndAlign(block);
2580 } else if (md->type==eModifierType_SimpleDeform) {
2581 SimpleDeformModifierData *smd = (SimpleDeformModifierData*) md;
2582 char simpledeform_modemenu[] = "Deform type%t|Twist %x1|Bend %x2|Taper %x3|Strech %x4";
2584 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.");
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 uiDefIDPoinBut(block, test_obpoin_but, ID_OB, B_CHANGEDEP, "Ob: ", lx, (cy-=19), buttonWidth,19, &smd->origin, "Origin of modifier space coordinates");
2590 if(smd->origin != NULL)
2591 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");
2593 uiDefButF(block, NUM, B_MODIFIER_RECALC, "Factor:", lx,(cy-=19),buttonWidth,19, &smd->factor, -10.0f, 10.0f, 0.5f, 0, "Deform Factor");
2595 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");
2596 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");
2598 if(smd->mode == MOD_SIMPLEDEFORM_MODE_STRETCH
2599 || smd->mode == MOD_SIMPLEDEFORM_MODE_TAPER )
2601 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");
2602 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");
2606 uiBlockEndAlign(block);
2614 uiBlockSetCol(block, color);
2615 /* roundbox 4 free variables: corner-rounding, nop, roundbox type, shade */
2616 uiDefBut(block, ROUNDBOX, 0, "", x-10, y, width, 20, NULL, 5.0, 0.0, 15, 40, "");
2617 uiBlockSetCol(block, TH_AUTO);
2619 uiDefIconBut(block,LABEL,B_NOP,ICON_ERROR, x-9, y,19,19, 0,0,0,0,0, "");
2620 uiDefBut(block, LABEL, B_NOP, md->error, x+5, y, width-15, 19, NULL, 0.0, 0.0, 0.0, 0.0, "");
2633 static void editing_panel_modifiers(Object *ob)
2638 int xco, yco, i, lastCageIndex, cageIndex = modifiers_getCageIndex(ob, &lastCageIndex);
2640 block= uiNewBlock(&curarea->uiblocks, "editing_panel_modifiers", UI_EMBOSS, UI_HELV, curarea->win);
2641 if( uiNewPanel(curarea, block, "Modifiers", "Editing", 640, 0, 318, 204)==0) return;
2643 uiSetButLock((ob && ob->id.lib), ERROR_LIBDATA_MESSAGE);
2644 uiNewPanelHeight(block, 204);
2646 uiDefBlockBut(block, modifiers_add_menu, ob, "Add Modifier", 0, 190, 130, 20, "Add a new modifier");
2648 sprintf(str, "To: %s", ob->id.name+2);
2649 uiDefBut(block, LABEL, 1, str, 140, 190, 160, 20, NULL, 0.0, 0.0, 0, 0, "Object whose modifier stack is being edited");
2654 md = modifiers_getVirtualModifierList(ob);
2656 for (i=0; md; i++, md=md->next) {
2657 draw_modifier(block, ob, md, &xco, &yco, i, cageIndex, lastCageIndex);
2658 if (md->mode&eModifierMode_Virtual) i--;
2661 if(yco < 0) uiNewPanelHeight(block, 204-yco);
2664 static char *make_key_menu(Key *key, int startindex)
2668 char *str, item[64];
2670 for (kb = key->block.first; kb; kb=kb->next, index++);
2671 str= MEM_mallocN(index*40, "key string");
2675 for (kb = key->block.first; kb; kb=kb->next, index++) {
2676 sprintf (item, "|%s%%x%d", kb->name, index);
2683 static void editing_panel_shapes(Object *ob)
2691 block= uiNewBlock(&curarea->uiblocks, "editing_panel_shapes", UI_EMBOSS, UI_HELV, curarea->win);
2692 uiNewPanelTabbed("Modifiers", "Editing");
2693 if( uiNewPanel(curarea, block, "Shapes", "Editing", 640, 0, 318, 204)==0) return;
2695 /* Todo check data is library here */
2696 uiSetButLock(object_data_is_libdata(ob), ERROR_LIBDATA_MESSAGE);
2698 uiDefBut(block, BUT, B_ADDKEY, "Add Shape Key" , 10, 180, 150, 20, NULL, 0.0, 0.0, 0, 0, "Add new Shape Key");
2700 key= ob_get_key(ob);
2702 /* label aligns add button */
2703 uiDefBut(block, LABEL, 0, "", 170, 180,140,20, NULL, 0, 0, 0, 0, "");
2707 uiDefButS(block, TOG, B_RELKEY, "Relative", 170, 180,140,20, &key->type, 0, 0, 0, 0, "Makes Shape Keys relative");
2709 kb= BLI_findlink(&key->block, ob->shapenr-1);
2712 kb= key->block.first;
2715 uiBlockBeginAlign(block);
2716 if(ob->shapeflag & OB_SHAPE_LOCK) icon= ICON_PIN_HLT; else icon= ICON_PIN_DEHLT;
2717 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");
2718 if(kb->flag & KEYBLOCK_MUTE) icon= ICON_MUTE_IPO_ON; else icon = ICON_MUTE_IPO_OFF;
2719 uiDefIconButBitS(block, TOG, KEYBLOCK_MUTE, B_MODIFIER_RECALC, icon, 35,150,20,20, &kb->flag, 0, 0, 0, 0, "Mute the current Shape");
2720 uiSetButLock(G.obedit==ob, "Unable to perform in EditMode");
2721 uiDefIconBut(block, BUT, B_PREVKEY, ICON_TRIA_LEFT, 55,150,20,20, NULL, 0, 0, 0, 0, "Previous Shape Key");
2722 strp= make_key_menu(key, 1);
2723 uiDefButS(block, MENU, B_SETKEY, strp, 75,150,20,20, &ob->shapenr, 0, 0, 0, 0, "Browse existing choices");
2726 uiDefIconBut(block, BUT, B_NEXTKEY, ICON_TRIA_RIGHT, 95,150,20,20, NULL, 0, 0, 0, 0, "Next Shape Key");
2728 uiDefBut(block, TEX, B_NAMEKEY, "", 115, 150, 170, 20, kb->name, 0.0, 31.0, 0, 0, "Current Shape Key name");
2729 uiDefIconBut(block, BUT, B_DELKEY, ICON_X, 285,150,25,20, 0, 0, 0, 0, 0, "Deletes current Shape Key");
2730 uiBlockEndAlign(block);
2732 if(key->type && (ob->shapeflag & OB_SHAPE_LOCK)==0 && ob->shapenr!=1) {
2733 uiBlockBeginAlign(block);
2734 make_rvk_slider(block, ob, ob->shapenr-1, 10, 120, 150, 20, "Key value, when used it inserts an animation curve point");
2735 uiDefButF(block, NUM, B_REDR, "Min ", 160,120, 75, 20, &kb->slidermin, -10.0, 10.0, 100, 1, "Minumum for slider");
2736 uiDefButF(block, NUM, B_REDR, "Max ", 235,120, 75, 20, &kb->slidermax, -10.0, 10.0, 100, 1, "Maximum for slider");
2737 uiBlockEndAlign(block);
2739 if(key->type && ob->shapenr!=1) {
2740 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");
2742 strp= make_key_menu(key, 0);
2743 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");
2748 uiDefButS(block, NUM, B_DIFF, "Slurph:", 10, 60, 150, 19, &(key->slurph), -500.0, 500.0, 0, 0, "Creates a delay in amount of frames in applying keypositions, first vertex goes first");
2752 /* *************************** FONT ******************************** */
2754 static short give_vfontnr(VFont *vfont)
2759 vf= G.main->vfont.first;
2761 if(vf==vfont) return nr;
2768 static VFont *give_vfontpointer(int nr) /* nr= button */
2773 vf= G.main->vfont.first;
2775 if(tel==nr) return vf;
2779 return G.main->vfont.first;
2782 VFont *exist_vfont(char *str)
2786 vf= G.main->vfont.first;
2788 if(strcmp(vf->name, str)==0) return vf;
2794 static char *give_vfontbutstr(void)
2798 char *str, di[FILE_MAXDIR], fi[FILE_MAXFILE];
2800 vf= G.main->vfont.first;
2802 strcpy(di, vf->name);
2803 BLI_splitdirstring(di, fi);
2808 str= MEM_callocN(len+21, "vfontbutstr");
2809 strcpy(str, "FONTS %t");
2810 vf= G.main->vfont.first;
2813 if(vf->id.us==0) strcat(str, "|0 ");
2814 else strcat(str, "| ");
2816 strcpy(di, vf->name);
2817 BLI_splitdirstring(di, fi);
2825 static void load_buts_vfont(char *name)
2830 if(OBACT && OBACT->type==OB_FONT) cu= OBACT->data;
2833 vf= exist_vfont(name);
2835 vf= load_vfont(name);
2838 else id_us_plus((ID *)vf);
2840 switch(cu->curinfo.flag & CU_STYLE) {
2842 if(cu->vfontb) cu->vfontb->id.us--;
2846 if(cu->vfonti) cu->vfonti->id.us--;
2849 case (CU_BOLD|CU_ITALIC):
2850 if(cu->vfontbi) cu->vfontbi->id.us--;
2854 if(cu->vfont) cu->vfont->id.us--;
2859 DAG_object_flush_update(G.scene, OBACT, OB_RECALC_DATA);
2860 BIF_undo_push("Load vector font");
2861 allqueue(REDRAWVIEW3D, 0);
2862 allqueue(REDRAWBUTSEDIT, 0);
2865 static void set_unicode_text_fs(char *file)
2867 if (file) paste_unicodeText(file);
2870 void do_fontbuts(unsigned short event)