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