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"
183 static float editbutweight= 1.0;
184 float editbutvweight= 1;
185 static int actmcol= 0, acttface= 0, acttface_rnd = 0, actmcol_rnd = 0;
187 extern ListBase editNurb;
189 /* *************************** Unicode Character Groups ****************** */
190 unicodect uctabname[125] = {
191 {"All", "All", 0x0000, 0xffff},
192 {"Basic Latin", "Basic Latin", 0x0000, 0x007f},
193 {"Latin 1 Supp", "Latin-1 Supplement", 0x0080, 0x00ff},
195 {"Latin Ext. A.", "Latin Extended-A", 0x0100, 0x017F},
196 {"Latin Ext. B.", "Latin Extended-B", 0x0180,0x024F},
197 {"Latin Ext. Add.", "Latin Extended Additional", 0x1e00, 0x1eff},
199 {"IPA Ext", "IPA Extensions", 0x0250, 0x02AF},
200 {"Spacing Mod.", "Spacing Modifier Letters", 0x02b0, 0x02ff},
202 {"Comb. Dia.", "Combining Diacritical Marks", 0x0300, 0x036F},
203 {"Greek, Coptic", "Greek and Coptic", 0x0370, 0x03ff},
204 {"Greek Ext.", "Greek Extended", 0x1f00, 0x1fff},
206 {"Cyrillic", "Cyrillic", 0x0400, 0x04ff},
207 {"Cyrillic Supp.", "Cyrillic Supplementary", 0x0500, 0x052f},
209 {"Armenian", "Armenian", 0x0530, 0x058f},
210 {"Hebrew", "Hebrew", 0x0590, 0x05ff},
213 {"Arabic", "Arabic", 0x0600, 0x06ff},
214 {"Syriac", "Syriac", 0x0700, 0x074f},
216 {"Thaana", "Thaana", 0x0780, 0x07bf},
217 {"Devanagari", "Devanagari", 0x0900, 0x097f},
219 {"Bengali", "Bengali", 0x0980, 0x09ff},
220 {"Gurmukhi", "Gurmukhi", 0x0a00, 0x0a7f},
222 {"Gujarati", "Gujarati", 0x0a80, 0x0aff},
223 {"Oriya", "Oriya", 0x0b00, 0x0b7f},
225 {"Tamil", "Tamil", 0x0b80, 0x0bff},
226 {"Tegulu", "Tegulu", 0x0c00, 0x0c7f},
228 {"Kannada", "Kannada", 0x0c80, 0x0cff},
229 {"Malayalam", "Malayalam", 0x0d00, 0x0d7f},
231 {"Sinhala", "Sinhala", 0x0d80, 0x0dff},
232 {"Thai", "Thai", 0x0e00, 0x0e7f},
234 {"Lao", "Lao", 0x0e80, 0x0eff},
235 {"Tibetan", "Tibetan", 0x0f00, 0x0fff},
237 {"Myanmar", "Myanmar", 0x1000, 0x109f},
238 {"Georgian", "Georgian", 0x10a0, 0x10ff},
240 {"Ethiopic", "Ethiopic", 0x1200, 0x137f},
242 {"Cherokee", "Cherokee", 0x13a0, 0x13ff},
243 {"Unif. Canadian", "Unified Canadian Aboriginal Syllabics", 0x1400, 0x167f},
245 {"Ogham", "Ogham", 0x1680, 0x169f},
246 {"Runic", "Runic", 0x16a0, 0x16ff},
248 {"Tagalog", "Tagalog", 0x1700, 0x171f},
249 {"Hanunoo", "Hanunoo", 0x1720, 0x173f},
251 {"Buhid", "Buhid", 0x1740, 0x175f},
252 {"Tagbanwa", "Tagbanwa", 0x1760, 0x177f},
254 {"Khmer", "Khmer", 0x1780, 0x17ff},
255 {"Khmer Symb", "Khmer Symbols", 0x19e0, 0x19ff},
257 {"Mongolian", "Mongolian", 0x1800, 0x18af},
259 {"Limbu", "Limbu", 0x1900, 0x194f},
260 {"Tai Le", "Tai Le", 0x1950, 0x197f},
262 {"Phon. Ext.", "Phonetic Extensions", 0x1d00, 0x1d7f},
265 {"Gen. Punct.", "General Punctutation", 0x2000, 0x206f},
266 {"Super, Sub", "Superscripts and Subscripts", 0x2070, 0x209f},
268 {"Curr. Symb.", "Currency Symbols", 0x20a0, 0x20cf},
269 {"Comb. Diacrit.", "Combining Diacritical Marks for Symbols", 0x20d0, 0x20ff},
271 {"Letter Symb", "Letterlike Symbols", 0x2100, 0x214f},
272 {"Numb. Forms", "Number Forms", 0x2150, 0x218f},
274 {"Arrows", "Arrows", 0x2190, 0x21ff},
275 {"Math Oper.", "Mathematical Operators", 0x2200, 0x22ff},
277 {"Misc. Tech.", "Miscellaneous Technical", 0x2300, 0x23ff},
278 {"Ctrl. Pict.", "Control Pictures", 0x2400, 0x243f},
280 {"OCR", "Optical Character Recognition", 0x2440, 0x245f},
281 {"Enc. Alpha", "Enclosed Alphanumerics", 0x2460, 0x24ff},
283 {"Bow Drawing", "Box Drawing", 0x2500, 0x257f},
284 {"BLock Elem.", "Block Elements", 0x2580, 0x259f},
286 {"Geom. Shapes", "Geometric Shapes", 0x25a0, 0x25ff},
287 {"Misc. Symb.", "Miscellaneous Symbols", 0x2600, 0x26ff},
289 {"Dingbats", "Dingbats", 0x2700, 0x27bf},
290 {"Misc. Math A", "Miscellaneous Mathematical Symbols-A", 0x27c0, 0x27ef},
292 {"Supp. Arrows-A", "Supplemental Arrows-A", 0x27f0, 0x27ff},
293 {"Braille Pat.", "Braille Patterns", 0x2800, 0x28ff},
295 {"Supp. Arrows-B", "Supplemental Arrows-B", 0x2900, 0x297f},
296 {"Misc. Math B", "Miscellaneous Mathematical Symbols-B", 0x2980, 0x29ff},
298 {"Supp. Math Op.", "Supplemental Mathematical Operators", 0x2a00, 0x2aff},
299 {"Misc. Symb.", "Miscellaneous Symbols and Arrows", 0x2b00, 0x2bff},
301 {"Kangxi Rad.", "Kangxi Radicals", 0x2f00, 0x2fdf},
303 {"Ideographic", "Ideographic Description Characters", 0x2ff0, 0x2fff},
305 {"Hiragana", "Hiragana", 0x3040, 0x309f},
306 {"Katakana", "Katakana", 0x30a0, 0x30ff},
307 {"Katakana Ext.", "Katakana Phonetic Extensions", 0x31f0, 0x31ff},
309 {"Bopomofo", "Bopomofo", 0x3100, 0x312f},
310 {"Bopomofo Ext.", "Bopomofo Extended", 0x31a0, 0x31bf},
312 {"Hangul", "Hangul Jamo", 0x1100, 0x11ff},
313 {"Hangul Comp.", "Hangul Compatibility Jamo", 0x3130, 0x318f},
314 {"Hangul Syll.", "Hangul Syllables", 0xac00, 0xd7af},
316 {"Kanbun", "Kanbun", 0x3190, 0x319f},
320 {"Yijing Hex.", "Yijing Hexagram Symbols", 0x4dc0, 0x4dff},
322 {"Yi Syllables", "Yi Syllables", 0xa000, 0xa48f},
323 {"Yi Radicals", "Yi Radicals", 0xa490, 0xa4cf},
325 {"High Surr.", "High Surrogate Area", 0xd800, 0xdbff},
327 {"Low Surr.", "Low Surrogates", 0xdc00, 0xdfff},
328 {"Priv. Use Area", "Private Use Area", 0xe000, 0xf8ff},
330 {"CJK Rad. Supp.", "CJK Radicals Supplement", 0x2e80, 0x2eff},
331 {"CJK Ideographs", "CJK Unified Ideographs", 0x4e00, 0x9faf},
332 {"CJK Ideog. Ext. A", "CJK Unified Ideographs Extension A", 0x3400, 0x4dbf},
333 {"CJK Ideog. Ext. B", "CJK Unified Ideographs Extension B", 0x20000, 0x2a6df},
334 {"CJK Symbols.", "CJK Symbols and Punctuation", 0x3000, 0x303f},
335 {"Enclosed CJK", "Enclosed CJK Letters and Months", 0x3200, 0x32ff},
336 {"CJK Comp.", "CJK Compatibility", 0x3300, 0x33ff},
337 {"CJK Comp. Ideog.", "CJK Compatibility Ideographs", 0xf900, 0xfaff},
338 {"CJK Comp. Forms", "CJK Compatibility Forms", 0xfe30, 0xfe4f},
339 {"CJK Comp. Supp.", "CJK Compatibility Ideographs Supplement", 0x2f800, 0x2fa1f},
341 {"Alpha. Pres. Forms", "Alphabetic Presentation Forms", 0xfb00, 0xfb4f},
343 {"Arabic Pres. A", "Arabic Presentation Forms-A", 0xfb50, 0xfdff},
344 {"Arabic Pres. B", "Arabic Presentation Forms-B", 0xfe70, 0xfeff},
346 {"Var. Sel.", "Variation Selectors", 0xfe00, 0xfe0f},
348 {"Comb. Half", "Combining Half Marks", 0xfe20, 0xfe2f},
350 {"Sml. From Var.", "Small Form Variants", 0xfe50, 0xfe6f},
352 {"Half, Full Forms", "Halfwidth and Fullwidth Forms", 0xff00, 0xffef},
353 {"Specials", "Specials", 0xfff0, 0xffff},
355 {"Lin. B Syllab.", "Linear B Syllabary", 0x10000, 0x1007f},
356 {"Lin. B Idog.", "Linear B Ideograms", 0x10080, 0x100ff},
358 {"Aegean Num.", "Aegean Numbers", 0x10100, 0x1013f},
359 {"Old Italic", "Old Italic", 0x10300, 0x1032f},
361 {"Gothic", "Gothic", 0x10330, 0x1034f},
362 {"Ugaritic", "Ugaritic", 0x10380, 0x1039f},
364 {"Deseret", "Deseret", 0x10400, 0x1044f},
365 {"Shavian", "Shavian", 0x10450, 0x1047f},
367 {"Osmanya", "Osmanya", 0x10480, 0x104af},
368 {"Cypriot Syll", "Cypriot Syllabary", 0x10800, 0x1083f},
370 {"Bysantine Mus.", "Bysantine Musical Symbols", 0x1d000, 0x1d0ff},
371 {"Music Symb.", "Musical Symbols", 0x1d100, 0x1d1ff},
373 {"Tai Xuan Symb", "Tai Xuan Jing Symbols", 0x1d300, 0x1d35f},
374 {"Math. Alpha Symb.", "Mathematical Alpanumeric Symbols", 0x1d400, 0x1d7ff},
377 {"Tags", "Tags", 0xe0000, 0xe007f},
378 {"Var. Supp", "Variation Selectors Supplement", 0xe0100, 0xe01ef},
380 {"Supp. Priv. A", "Supplementary Private Use Area-A", 0xf0000, 0xffffd},
381 {"Supp. Priv. B", "Supplementary Private Use Area-B", 0x100000, 0x10fffd}
385 /* *************************** static functions prototypes ****************** */
386 VFont *exist_vfont(char *str);
388 /* *************** */
390 void do_common_editbuts(unsigned short event) // old name, is a mix of object and editing events....
392 EditMesh *em = G.editMesh;
402 int a, bit, index= -1;
407 if(G.obedit && G.obedit->actcol>0) {
408 if(G.obedit->type == OB_MESH) {
409 for(efa= em->faces.first; efa; efa= efa->next) {
410 if(efa->f & SELECT) {
411 if(index== -1) index= efa->mat_nr;
412 else if(index!=efa->mat_nr) {
413 error("Mixed colors");
419 else if ELEM(G.obedit->type, OB_CURVE, OB_SURF) {
422 if( isNurbsel(nu) ) {
423 if(index== -1) index= nu->mat_nr;
424 else if(index!=nu->mat_nr) {
425 error("Mixed colors");
433 G.obedit->actcol= index+1;
434 scrarea_queue_winredraw(curarea);
439 new_material_to_objectdata(ob);
440 scrarea_queue_winredraw(curarea);
441 BIF_undo_push("New material");
442 allqueue(REDRAWBUTSSHADING, 0);
443 allqueue(REDRAWVIEW3D_Z, 0);
444 allqueue(REDRAWOOPS, 0);
447 delete_material_index();
448 scrarea_queue_winredraw(curarea);
449 BIF_undo_push("Delete material index");
450 allqueue(REDRAWBUTSSHADING, 0);
451 allqueue(REDRAWVIEW3D_Z, 0);
452 allqueue(REDRAWOOPS, 0);
455 if(G.obedit && G.obedit->actcol>0) {
456 if(G.obedit->type == OB_MESH) {
457 efa= em->faces.first;
460 efa->mat_nr= G.obedit->actcol-1;
464 else if ELEM(G.obedit->type, OB_CURVE, OB_SURF) {
468 nu->mat_nr= nu->charidx= G.obedit->actcol-1;
472 else if (G.obedit->type == OB_FONT) {
474 allqueue(REDRAWVIEW3D, 0);
477 allqueue(REDRAWVIEW3D_Z, 0);
478 DAG_object_flush_update(G.scene, G.obedit, OB_RECALC_DATA);
479 shade_buttons_change_3d();
480 BIF_undo_push("Assign material index");
483 case B_MATASS_BROWSE:
484 /* if slot available, make that index active, and assign */
485 /* else, make new slot, and assign */
486 ma= BLI_findlink(&G.main->mat, G.buts->menunr-1);
488 ob->actcol= find_material_index(ob, ma);
490 assign_material(ob, ma, ob->totcol+1);
491 ob->actcol= ob->totcol;
495 do_common_editbuts(B_MATNEW);
497 do_common_editbuts(B_MATASS);
501 ma= give_current_material(ob, ob->actcol);
502 BKE_icon_changed(BKE_icon_getid((ID *)ma));
503 allqueue(REDRAWVIEW3D, 0);
504 allqueue(REDRAWBUTSEDIT, 0);
510 if(G.obedit->type == OB_MESH) {
511 if (event==B_MATSEL) {
512 editmesh_select_by_material(G.obedit->actcol-1);
514 editmesh_deselect_by_material(G.obedit->actcol-1);
516 allqueue(REDRAWVIEW3D, 0);
518 else if ELEM(G.obedit->type, OB_CURVE, OB_SURF) {
521 if(nu->mat_nr==G.obedit->actcol-1) {
527 if(event==B_MATSEL) {
542 a= nu->pntsu*nu->pntsv;
546 if(event==B_MATSEL) bp->f1 |= SELECT;
547 else bp->f1 &= ~SELECT;
555 BIF_undo_push("Select material index");
556 allqueue(REDRAWVIEW3D, 0);
563 if(G.obedit->type == OB_MESH) hide_mesh(0);
564 else if ELEM(G.obedit->type, OB_CURVE, OB_SURF) hideNurb(0);
569 if(G.obedit->type == OB_MESH) reveal_mesh();
570 else if ELEM(G.obedit->type, OB_CURVE, OB_SURF) revealNurb();
572 else if(FACESEL_PAINT_TEST) reveal_tface();
577 if(G.obedit->type == OB_MESH) selectswap_mesh();
578 else if ELEM(G.obedit->type, OB_CURVE, OB_SURF) selectswapNurb();
582 if(ob && G.obedit==0) {
583 if(ELEM3(ob->type, OB_CURVE, OB_SURF, OB_FONT)) tex_space_curve(ob->data);
592 case B_DOCENTERCURSOR:
598 if(G.obedit->type == OB_MESH) {
599 mesh_set_smooth_faces((event==B_SETSMOOTH));
602 nurb_set_smooth((event==B_SETSMOOTH));
608 if(TESTBASELIB(base)) {
609 if(base->object->type==OB_MESH) {
610 mesh_set_smooth_flag(base->object, (event==B_SETSMOOTH));
612 else if ELEM(base->object->type, OB_SURF, OB_CURVE) {
613 cu= base->object->data;
616 if(event==B_SETSMOOTH) nu->flag |= ME_SMOOTH;
617 else nu->flag &= ~ME_SMOOTH;
620 makeDispListCurveTypes(base->object, 0);
625 allqueue(REDRAWVIEW3D, 0);
627 if(event == B_SETSMOOTH) BIF_undo_push("Set Smooth");
628 else BIF_undo_push("Set Solid");
632 DAG_scene_sort(G.scene); // makes new dag
633 if(ob) ob->recalc |= OB_RECALC;
634 allqueue(REDRAWVIEW3D, 0);
641 ob->shapeflag |= OB_SHAPE_TEMPLOCK;
642 DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA);
643 allqueue(REDRAWVIEW3D, 0);
644 allqueue(REDRAWIPO, 0);
645 allqueue(REDRAWBUTSEDIT, 0);
648 ob->shapeflag &= ~OB_SHAPE_TEMPLOCK;
649 DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA);
650 allqueue(REDRAWVIEW3D, 0);
651 allqueue(REDRAWIPO, 0);
652 allqueue(REDRAWBUTSEDIT, 0);
656 Key *key= ob_get_key(ob);
657 if(ob->shapenr == BLI_countlist(&key->block))
660 do_common_editbuts(B_SETKEY);
665 Key *key= ob_get_key(ob);
667 ob->shapenr= BLI_countlist(&key->block);
669 do_common_editbuts(B_SETKEY);
673 allspace(REMAKEIPO, 0);
674 allqueue (REDRAWIPO, 0);
678 allqueue(REDRAWACTION, 0);
686 if(event>=B_OBLAY && event<=B_OBLAY+31) {
687 local= BASACT->lay & 0xFF000000;
688 BASACT->lay -= local;
689 if(BASACT->lay==0 || (G.qual & LR_SHIFTKEY)==0) {
692 scrarea_queue_winredraw(curarea);
694 BASACT->lay += local;
696 if( (ob->lay & G.vd->lay) && (BASACT->lay & G.vd->lay) );
697 else if( (ob->lay & G.vd->lay)==0 && (BASACT->lay & G.vd->lay)==0 );
699 allqueue(REDRAWVIEW3D, 0);
700 DAG_scene_sort(G.scene);
702 ob->lay= BASACT->lay;
708 /* *************************** MESH ******************************** */
710 static void verify_customdata_name_func(void *data1, void *data2)
712 CustomData *data= (CustomData*)data1;
713 CustomDataLayer *layer= (CustomDataLayer*)data2;
715 CustomData_set_layer_unique_name(data, layer - data->layers);
718 static void delete_customdata_layer(void *data1, void *data2)
720 Mesh *me= (Mesh*)data1;
721 CustomData *data= (G.obedit)? &G.editMesh->fdata: &me->fdata;
722 CustomDataLayer *layer= (CustomDataLayer*)data2;
723 void *actlayerdata, *rndlayerdata, *layerdata=layer->data;
724 int type= layer->type;
725 int index= CustomData_get_layer_index(data, type);
726 int i, actindex, rndindex;
728 /*ok, deleting a non-active layer needs to preserve the active layer indices.
729 to do this, we store a pointer to the .data member of both layer and the active layer,
730 (to detect if we're deleting the active layer or not), then use the active
731 layer data pointer to find where the active layer has ended up.
733 this is necassary because the deletion functions only support deleting the active
735 actlayerdata = data->layers[CustomData_get_active_layer_index(data, type)].data;
736 rndlayerdata = data->layers[CustomData_get_render_layer_index(data, type)].data;
737 CustomData_set_layer_active(data, type, layer - &data->layers[index]);
739 /* Multires is handled seperately because the display data is separate
740 from the data stored in multires */
742 multires_delete_layer(me, &me->mr->fdata, type, layer - &data->layers[index]);
743 multires_level_to_editmesh(OBACT, me, 0);
744 multires_finish_mesh_update(OBACT);
747 EM_free_data_layer(data, type);
750 CustomData_free_layer_active(data, type, me->totface);
751 mesh_update_customdata_pointers(me);
754 if(!CustomData_has_layer(data, type)) {
755 if(type == CD_MCOL && (G.f & G_VERTEXPAINT))
756 G.f &= ~G_VERTEXPAINT; /* get out of vertexpaint mode */
759 /*reconstruct active layer*/
760 if (actlayerdata != layerdata) {
762 actindex = CustomData_get_layer_index(data, type);
763 for (i=actindex; i<data->totlayer; i++) {
764 if (data->layers[i].data == actlayerdata) {
765 actindex = i - actindex;
771 CustomData_set_layer_active(data, type, actindex);
774 if (rndlayerdata != layerdata) {
776 rndindex = CustomData_get_layer_index(data, type);
777 for (i=rndindex; i<data->totlayer; i++) {
778 if (data->layers[i].data == rndlayerdata) {
779 rndindex = i - rndindex;
785 CustomData_set_layer_render(data, type, rndindex);
789 DAG_object_flush_update(G.scene, OBACT, OB_RECALC_DATA);
791 if(type == CD_MTFACE)
792 BIF_undo_push("Delete UV Texture");
793 else if(type == CD_MCOL)
794 BIF_undo_push("Delete Vertex Color");
796 allqueue(REDRAWVIEW3D, 0);
797 allqueue(REDRAWIMAGE, 0);
798 allqueue(REDRAWBUTSEDIT, 0);
801 static int customdata_buttons(
802 uiBlock *block, Mesh *me, CustomData *data,
803 int type, int *activep, int *renderp,
804 int setevt, int setevt_rnd, int newevt,
805 char *label, char *shortlabel, char *browsetip, char *browsetip_rnd,
806 char *newtip, char *deltip, int x, int y)
808 CustomDataLayer *layer;
810 int i, count= CustomData_number_of_layers(data, type);
812 if(count >= MAX_MTFACE) {
813 uiDefBut(block, LABEL, 0, label, x,y,220,19, 0, 0.0, 0, 0, 0, "");
816 uiDefBut(block, LABEL, 0, label, x,y,140,19, 0, 0.0, 0, 0, 0, "");
817 uiBlockBeginAlign(block);
818 uiDefBut(block, BUT, newevt, "New", x+140,y,80,19, 0,0,0,0,0, newtip);
819 uiBlockEndAlign(block);
822 y -= (count)? 24: 19;
824 uiBlockBeginAlign(block);
825 for (count=1, i=0; i<data->totlayer; i++) {
826 layer= &data->layers[i];
828 if(layer->type == type) {
829 *activep= layer->active + 1;
830 *renderp= layer->active_rnd + 1;
832 uiDefIconButI(block, ROW, setevt, ICON_VIEW3D, x,y,25,19, activep, 1.0, count, 0, 0, browsetip);
833 uiDefIconButI(block, ROW, setevt_rnd, ICON_SCENE, x+25,y,25,19, renderp, 1.0, count, 0, 0, browsetip_rnd);
834 but=uiDefBut(block, TEX, setevt, "", x+50,y,145,19, layer->name, 0.0, 31.0, 0, 0, label);
835 uiButSetFunc(but, verify_customdata_name_func, data, layer);
836 but= uiDefIconBut(block, BUT, B_NOP, VICON_X, x+195,y,25,19, NULL, 0.0, 0.0, 0.0, 0.0, deltip);
837 uiButSetFunc(but, delete_customdata_layer, me, layer);
844 uiBlockEndAlign(block);
849 static void editing_panel_mesh_type(Object *ob, Mesh *me)
857 block= uiNewBlock(&curarea->uiblocks, "editing_panel_mesh_type", UI_EMBOSS, UI_HELV, curarea->win);
858 if( uiNewPanel(curarea, block, "Mesh", "Editing", 320, 0, 318, 204)==0) return;
859 uiSetButLock(object_data_is_libdata(ob), ERROR_LIBDATA_MESSAGE);
861 uiBlockBeginAlign(block);
862 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");
863 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");
864 uiBlockEndAlign(block);
868 uiBlockBeginAlign(block);
869 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");
870 uiButSetFunc(but,retopo_toggle,ob,me);
871 if(G.scene->toolsettings->retopo_mode) {
872 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.");
873 uiButSetFunc(but,retopo_paint_toggle,ob,me);
874 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");
875 uiButSetFunc(but,retopo_do_all_cb,ob,me);
877 uiBlockEndAlign(block);
880 uiBlockBeginAlign(block);
881 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");
882 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");
883 uiDefBut(block, BUT,B_DOCENTERCURSOR, "Center Cursor", 10, 60, 170, 19, 0, 0, 0, 0, 0, "Shifts object's origin to cursor location");
884 uiBlockEndAlign(block);
886 uiBlockBeginAlign(block);
887 uiDefButBitS(block, TOG, ME_TWOSIDED, REDRAWVIEW3D, "Double Sided", 10,30,170,19, &me->flag, 0, 0, 0, 0, "Render/display the mesh as double or single sided");
888 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");
889 uiBlockEndAlign(block);
891 uiDefIDPoinBut(block, test_meshpoin_but, ID_ME, B_REDR, "TexMesh: ", 190,180,220,19, &me->texcomesh, "Derive texture coordinates from another mesh.");
893 if(me->msticky) val= 1.0; else val= 0.0;
894 uiDefBut(block, LABEL, 0, "Sticky", 190,155,140,19, 0, val, 0, 0, 0, "");
895 uiBlockBeginAlign(block);
896 if(me->msticky==NULL) {
897 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");
899 else uiDefBut(block, BUT, B_DELSTICKY, "Delete", 330,155, 80,19, 0, 0, 0, 0, 0, "Deletes Sticky texture coordinates");
900 uiBlockEndAlign(block);
902 fdata= (G.obedit)? &G.editMesh->fdata: &me->fdata;
903 yco= customdata_buttons(block, me, fdata, CD_MTFACE, &acttface, &acttface_rnd,
904 B_SETTFACE, B_SETTFACE_RND, B_NEWTFACE, "UV Texture", "UV Texture:",
905 "Set active UV texture", "Set rendering UV texture", "Creates a new UV texture layer",
906 "Removes the current UV texture layer", 190, 130);
908 yco= customdata_buttons(block, me, fdata, CD_MCOL, &actmcol, &actmcol_rnd,
909 B_SETMCOL, B_SETMCOL_RND, B_NEWMCOL, "Vertex Color", "Vertex Color:",
910 "Sets active vertex color layer", "Sets rendering vertex color layer", "Creates a new vertex color layer",
911 "Removes the current vertex color layer", 190, yco-5);
914 uiNewPanelHeight(block, 204 - yco);
917 /* *************************** MODIFIERS ******************************** */
919 void do_modifier_panels(unsigned short event)
924 case B_MODIFIER_REDRAW:
925 allqueue(REDRAWBUTSEDIT, 0);
926 allqueue(REDRAWOOPS, 0);
929 case B_MODIFIER_RECALC:
930 allqueue(REDRAWBUTSEDIT, 0);
931 allqueue(REDRAWVIEW3D, 0);
932 allqueue(REDRAWIMAGE, 0);
933 allqueue(REDRAWOOPS, 0);
934 DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA);
935 object_handle_update(ob);
941 static void modifiers_add(void *ob_v, int type)
944 ModifierTypeInfo *mti = modifierType_getInfo(type);
946 if (mti->flags&eModifierTypeFlag_RequiresOriginalData) {
947 ModifierData *md = ob->modifiers.first;
949 while (md && modifierType_getInfo(md->type)->type==eModifierTypeType_OnlyDeform) {
953 BLI_insertlinkbefore(&ob->modifiers, md, modifier_new(type));
955 BLI_addtail(&ob->modifiers, modifier_new(type));
957 BIF_undo_push("Add modifier");
960 typedef struct MenuEntry {
965 static int menuEntry_compare_names(const void *entry1, const void *entry2)
967 return strcmp(((MenuEntry *)entry1)->name, ((MenuEntry *)entry2)->name);
970 static uiBlock *modifiers_add_menu(void *ob_v)
976 MenuEntry entries[NUM_MODIFIER_TYPES];
978 block= uiNewBlock(&curarea->uiblocks, "modifier_add_menu",
979 UI_EMBOSSP, UI_HELV, curarea->win);
980 uiBlockSetButmFunc(block, modifiers_add, ob);
982 for (i=eModifierType_None+1; i<NUM_MODIFIER_TYPES; i++) {
983 ModifierTypeInfo *mti = modifierType_getInfo(i);
985 /* Only allow adding through appropriate other interfaces */
986 if(ELEM3(i, eModifierType_Softbody, eModifierType_Hook, eModifierType_ParticleSystem)) continue;
988 if(ELEM3(i, eModifierType_Cloth, eModifierType_Collision, eModifierType_Sph)) continue;
990 if((mti->flags&eModifierTypeFlag_AcceptsCVs) ||
991 (ob->type==OB_MESH && (mti->flags&eModifierTypeFlag_AcceptsMesh))) {
992 entries[numEntries].name = mti->name;
993 entries[numEntries].ID = i;
999 qsort(entries, numEntries, sizeof(*entries), menuEntry_compare_names);
1002 for(i = 0; i < numEntries; ++i)
1003 uiDefBut(block, BUTM, B_MODIFIER_RECALC, entries[i].name,
1004 0, yco -= 20, 160, 19, NULL, 0, 0, 1, entries[i].ID, "");
1006 uiTextBoundsBlock(block, 50);
1007 uiBlockSetDirection(block, UI_DOWN);
1012 static void modifiers_del(void *ob_v, void *md_v)
1017 /* It seems on rapid delete it is possible to
1018 * get called twice on same modifier, so make
1019 * sure it is in list.
1021 for (md=ob->modifiers.first; md; md=md->next)
1028 if(md->type==eModifierType_ParticleSystem){
1029 ParticleSystemModifierData *psmd=(ParticleSystemModifierData*)md;
1030 BLI_remlink(&ob->particlesystem, psmd->psys);
1031 psys_free(ob,psmd->psys);
1034 BLI_remlink(&ob->modifiers, md_v);
1036 modifier_free(md_v);
1038 BIF_undo_push("Del modifier");
1041 int mod_moveUp(void *ob_v, void *md_v)
1044 ModifierData *md = md_v;
1047 ModifierTypeInfo *mti = modifierType_getInfo(md->type);
1049 if (mti->type!=eModifierTypeType_OnlyDeform) {
1050 ModifierTypeInfo *nmti = modifierType_getInfo(md->prev->type);
1052 if (nmti->flags&eModifierTypeFlag_RequiresOriginalData)
1056 BLI_remlink(&ob->modifiers, md);
1057 BLI_insertlink(&ob->modifiers, md->prev->prev, md);
1063 static void modifiers_moveUp(void *ob_v, void *md_v)
1065 if( mod_moveUp( ob_v, md_v ) )
1066 error("Cannot move above a modifier requiring original data.");
1068 BIF_undo_push("Move modifier");
1071 int mod_moveDown(void *ob_v, void *md_v)
1074 ModifierData *md = md_v;
1077 ModifierTypeInfo *mti = modifierType_getInfo(md->type);
1079 if (mti->flags&eModifierTypeFlag_RequiresOriginalData) {
1080 ModifierTypeInfo *nmti = modifierType_getInfo(md->next->type);
1082 if (nmti->type!=eModifierTypeType_OnlyDeform)
1086 BLI_remlink(&ob->modifiers, md);
1087 BLI_insertlink(&ob->modifiers, md->next, md);
1093 static void modifiers_moveDown(void *ob_v, void *md_v)
1095 if( mod_moveDown( ob_v, md_v ) )
1096 error("Cannot move beyond a non-deforming modifier.");
1098 BIF_undo_push("Move modifier");
1101 static void modifier_testLatticeObj(char *name, ID **idpp)
1105 for (id= G.main->object.first; id; id= id->next) {
1106 if( strcmp(name, id->name+2)==0 ) {
1107 if (((Object *)id)->type != OB_LATTICE) {
1108 error ("Lattice deform object must be a lattice");
1118 static void modifier_testCurveObj(char *name, ID **idpp)
1122 for (id= G.main->object.first; id; id= id->next) {
1123 if( strcmp(name, id->name+2)==0 ) {
1124 if (((Object *)id)->type != OB_CURVE) {
1125 error ("Curve deform object must be a curve");
1135 static void modifier_testMeshObj(char *name, ID **idpp)
1139 for (id= G.main->object.first; id; id= id->next) {
1140 /* no boolean on its own object */
1141 if(id != (ID *)OBACT) {
1142 if( strcmp(name, id->name+2)==0 ) {
1143 if (((Object *)id)->type != OB_MESH) {
1144 error ("Boolean modifier object must be a mesh");
1155 static void modifier_testArmatureObj(char *name, ID **idpp)
1159 for (id= G.main->object.first; id; id= id->next) {
1160 if( strcmp(name, id->name+2)==0 ) {
1161 if (((Object *)id)->type != OB_ARMATURE) {
1162 error ("Armature deform object must be an armature");
1172 static void modifier_testTexture(char *name, ID **idpp)
1176 for(id = G.main->tex.first; id; id = id->next) {
1177 if(strcmp(name, id->name + 2) == 0) {
1179 /* texture gets user, objects not: delete object = clear modifier */
1187 #if 0 /* this is currently unused, but could be useful in the future */
1188 static void modifier_testMaterial(char *name, ID **idpp)
1192 for(id = G.main->mat.first; id; id = id->next) {
1193 if(strcmp(name, id->name + 2) == 0) {
1202 static void modifier_testImage(char *name, ID **idpp)
1206 for(id = G.main->image.first; id; id = id->next) {
1207 if(strcmp(name, id->name + 2) == 0) {
1215 /* autocomplete callback for ID buttons */
1216 void autocomplete_image(char *str, void *arg_v)
1218 /* search if str matches the beginning of an ID struct */
1220 AutoComplete *autocpl = autocomplete_begin(str, 22);
1223 for(id = G.main->image.first; id; id = id->next)
1224 autocomplete_do_name(autocpl, id->name+2);
1226 autocomplete_end(autocpl, str);
1230 /* autocomplete callback for ID buttons */
1231 void autocomplete_meshob(char *str, void *arg_v)
1233 /* search if str matches the beginning of an ID struct */
1235 AutoComplete *autocpl = autocomplete_begin(str, 22);
1238 for(id = G.main->object.first; id; id = id->next)
1239 if(((Object *)id)->type == OB_MESH)
1240 autocomplete_do_name(autocpl, id->name+2);
1242 autocomplete_end(autocpl, str);
1245 static void modifiers_convertParticles(void *obv, void *mdv)
1248 ModifierData *md = mdv;
1249 ParticleSystem *psys;
1250 ParticleCacheKey *key, **cache;
1255 int totvert=0, totedge=0, cvert=0;
1256 int totpart=0, totchild=0;
1258 if(md->type != eModifierType_ParticleSystem) return;
1260 if(G.f & G_PARTICLEEDIT) return;
1262 psys=((ParticleSystemModifierData *)md)->psys;
1264 if(psys->part->draw_as != PART_DRAW_PATH || psys->pathcache == 0) return;
1266 totpart= psys->totcached;
1267 totchild= psys->totchildcache;
1269 if(totchild && (psys->part->draw&PART_DRAW_PARENT)==0)
1273 cache= psys->pathcache;
1274 for(a=0; a<totpart; a++) {
1276 totvert+= key->steps+1;
1277 totedge+= key->steps;
1280 cache= psys->childcache;
1281 for(a=0; a<totchild; a++) {
1283 totvert+= key->steps+1;
1284 totedge+= key->steps;
1287 if(totvert==0) return;
1290 obn= add_object(OB_MESH);
1293 me->totvert= totvert;
1294 me->totedge= totedge;
1296 me->mvert= CustomData_add_layer(&me->vdata, CD_MVERT, CD_CALLOC, NULL, totvert);
1297 me->medge= CustomData_add_layer(&me->edata, CD_MEDGE, CD_CALLOC, NULL, totedge);
1298 me->mface= CustomData_add_layer(&me->fdata, CD_MFACE, CD_CALLOC, NULL, 0);
1303 /* copy coordinates */
1304 cache= psys->pathcache;
1305 for(a=0; a<totpart; a++) {
1308 for(k=0; k<=kmax; k++,key++,cvert++,mvert++) {
1309 VECCOPY(mvert->co,key->co);
1313 medge->flag= ME_EDGEDRAW|ME_EDGERENDER|ME_LOOSEEDGE;
1319 cache=psys->childcache;
1320 for(a=0; a<totchild; a++) {
1323 for(k=0; k<=kmax; k++,key++,cvert++,mvert++) {
1324 VECCOPY(mvert->co,key->co);
1328 medge->flag= ME_EDGEDRAW|ME_EDGERENDER|ME_LOOSEEDGE;
1334 DAG_scene_sort(G.scene);
1337 static void modifiers_applyModifier(void *obv, void *mdv)
1340 ModifierData *md = mdv;
1342 Mesh *me = ob->data;
1346 error("Modifiers cannot be applied in editmode");
1348 } else if (((ID*) ob->data)->us>1) {
1349 error("Modifiers cannot be applied to multi-user data");
1353 if (md!=ob->modifiers.first) {
1354 if (!okee("Modifier is not first"))
1358 if (ob->type==OB_MESH) {
1359 if(me->mr && multires_modifier_warning()) {
1360 error("Modifier changes topology; cannot apply with multires active");
1364 error("Modifier cannot be applied to Mesh with Shape Keys");
1368 mesh_pmv_off(ob, me);
1370 dm = mesh_create_derived_for_modifier(ob, md);
1372 error("Modifier is disabled or returned error, skipping apply");
1381 else if (ELEM(ob->type, OB_CURVE, OB_SURF)) {
1382 ModifierTypeInfo *mti = modifierType_getInfo(md->type);
1383 Curve *cu = ob->data;
1385 float (*vertexCos)[3];
1387 if (!okee("Apply will only change CV points, not tesselated/bevel vertices"))
1390 if (!(md->mode&eModifierMode_Realtime) || (mti->isDisabled && mti->isDisabled(md))) {
1391 error("Modifier is disabled, skipping apply");
1395 vertexCos = curve_getVertexCos(cu, &cu->nurb, &numVerts);
1396 mti->deformVerts(md, ob, NULL, vertexCos, numVerts);
1397 curve_applyVertexCos(cu, &cu->nurb, vertexCos);
1401 MEM_freeN(vertexCos);
1403 DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA);
1406 error("Cannot apply modifier for this object type");
1411 BLI_remlink(&ob->modifiers, md);
1414 BIF_undo_push("Apply modifier");
1418 static void modifiers_copyModifier(void *ob_v, void *md_v)
1421 ModifierData *md = md_v;
1422 ModifierData *nmd = modifier_new(md->type);
1424 modifier_copyData(md, nmd);
1426 BLI_insertlink(&ob->modifiers, md, nmd);
1428 BIF_undo_push("Copy modifier");
1431 static void modifiers_setOnCage(void *ob_v, void *md_v)
1436 int i, cageIndex = modifiers_getCageIndex(ob, NULL );
1438 for( i = 0, md=ob->modifiers.first; md; ++i, md=md->next )
1440 if( i >= cageIndex )
1441 md->mode ^= eModifierMode_OnCage;
1446 static void modifiers_clearHookOffset(void *ob_v, void *md_v)
1449 ModifierData *md = md_v;
1450 HookModifierData *hmd = (HookModifierData*) md;
1453 Mat4Invert(hmd->object->imat, hmd->object->obmat);
1454 Mat4MulSerie(hmd->parentinv, hmd->object->imat, ob->obmat, NULL, NULL, NULL, NULL, NULL, NULL);
1455 BIF_undo_push("Clear hook offset");
1459 static void modifiers_cursorHookCenter(void *ob_v, void *md_v)
1462 ModifierData *md = md_v;
1463 HookModifierData *hmd = (HookModifierData*) md;
1466 float *curs = give_cursor();
1467 float bmat[3][3], imat[3][3];
1469 where_is_object(ob);
1471 Mat3CpyMat4(bmat, ob->obmat);
1472 Mat3Inv(imat, bmat);
1474 curs= give_cursor();
1475 hmd->cent[0]= curs[0]-ob->obmat[3][0];
1476 hmd->cent[1]= curs[1]-ob->obmat[3][1];
1477 hmd->cent[2]= curs[2]-ob->obmat[3][2];
1478 Mat3MulVecfl(imat, hmd->cent);
1480 BIF_undo_push("Hook cursor center");
1484 static void modifiers_selectHook(void *ob_v, void *md_v)
1486 ModifierData *md = md_v;
1487 HookModifierData *hmd = (HookModifierData*) md;
1492 static void modifiers_reassignHook(void *ob_v, void *md_v)
1494 ModifierData *md = md_v;
1495 HookModifierData *hmd = (HookModifierData*) md;
1497 int *indexar, tot, ok;
1500 ok= hook_getIndexArray(&tot, &indexar, name, cent);
1503 error("Requires selected vertices or active Vertex Group");
1506 MEM_freeN(hmd->indexar);
1509 VECCOPY(hmd->cent, cent);
1510 hmd->indexar = indexar;
1511 hmd->totindex = tot;
1515 static void modifiers_convertToReal(void *ob_v, void *md_v)
1518 ModifierData *md = md_v;
1519 ModifierData *nmd = modifier_new(md->type);
1521 modifier_copyData(md, nmd);
1522 nmd->mode &= ~eModifierMode_Virtual;
1524 BLI_addhead(&ob->modifiers, nmd);
1526 ob->partype = PAROBJECT;
1528 BIF_undo_push("Modifier convert to real");
1531 static void build_uvlayer_menu_vars(CustomData *data, char **menu_string,
1532 int *uvlayer_tmp, char *uvlayer_name)
1536 CustomDataLayer *layer
1537 = &data->layers[CustomData_get_layer_index(data, CD_MTFACE)];
1541 totuv = CustomData_number_of_layers(data, CD_MTFACE);
1543 *menu_string = MEM_callocN(sizeof(**menu_string) * (totuv * 38 + 10),
1545 sprintf(*menu_string, "UV Layer%%t");
1546 for(i = 0; i < totuv; i++) {
1547 /* assign first layer as uvlayer_name if uvlayer_name is null. */
1548 if(strcmp(layer->name, uvlayer_name) == 0) *uvlayer_tmp = i + 1;
1549 sprintf(strtmp, "|%s%%x%d", layer->name, i + 1);
1550 strcat(*menu_string, strtmp);
1554 /* there is no uvlayer defined, or else it was deleted. Assign active
1555 * layer, then recalc modifiers.
1557 if(*uvlayer_tmp == -1) {
1558 if(CustomData_get_active_layer_index(data, CD_MTFACE) != -1) {
1560 layer = data->layers;
1561 for(i = 0; i < CustomData_get_active_layer_index(data, CD_MTFACE);
1563 if(layer->type == CD_MTFACE) (*uvlayer_tmp)++;
1565 strcpy(uvlayer_name, layer->name);
1567 /* update the modifiers */
1568 do_modifier_panels(B_MODIFIER_RECALC);
1570 /* ok we have no uv layers, so make sure menu button knows that.*/
1576 void set_displace_uvlayer(void *arg1, void *arg2)
1578 DisplaceModifierData *dmd=arg1;
1579 CustomDataLayer *layer = arg2;
1581 /*check we have UV layers*/
1582 if (dmd->uvlayer_tmp < 1) return;
1583 layer = layer + (dmd->uvlayer_tmp-1);
1585 strcpy(dmd->uvlayer_name, layer->name);
1588 void set_uvproject_uvlayer(void *arg1, void *arg2)
1590 UVProjectModifierData *umd=arg1;
1591 CustomDataLayer *layer = arg2;
1593 /*check we have UV layers*/
1594 if (umd->uvlayer_tmp < 1) return;
1595 layer = layer + (umd->uvlayer_tmp-1);
1597 strcpy(umd->uvlayer_name, layer->name);
1600 static void modifiers_bindMeshDeform(void *ob_v, void *md_v)
1602 MeshDeformModifierData *mmd = (MeshDeformModifierData*) md_v;
1603 Object *ob = (Object*)ob_v;
1606 if(mmd->bindweights) MEM_freeN(mmd->bindweights);
1607 if(mmd->bindcos) MEM_freeN(mmd->bindcos);
1608 if(mmd->dyngrid) MEM_freeN(mmd->dyngrid);
1609 if(mmd->dyninfluences) MEM_freeN(mmd->dyninfluences);
1610 if(mmd->dynverts) MEM_freeN(mmd->dynverts);
1611 mmd->bindweights= NULL;
1614 mmd->dyninfluences= NULL;
1615 mmd->dynverts= NULL;
1617 mmd->totcagevert= 0;
1618 mmd->totinfluence= 0;
1622 int mode= mmd->modifier.mode;
1624 /* force modifier to run, it will call binding routine */
1626 mmd->modifier.mode |= eModifierMode_Realtime;
1628 if(ob->type == OB_MESH) {
1629 dm= mesh_create_derived_view(ob, 0);
1632 else if(ob->type == OB_LATTICE) {
1633 lattice_calc_modifiers(ob);
1635 else if(ob->type==OB_MBALL) {
1636 makeDispListMBall(ob);
1638 else if(ELEM3(ob->type, OB_CURVE, OB_SURF, OB_FONT)) {
1639 makeDispListCurveTypes(ob, 0);
1643 mmd->modifier.mode= mode;
1647 void modifiers_explodeFacepa(void *arg1, void *arg2)
1649 ExplodeModifierData *emd=arg1;
1651 emd->flag |= eExplodeFlag_CalcFaces;
1654 void modifiers_explodeDelVg(void *arg1, void *arg2)
1656 ExplodeModifierData *emd=arg1;
1660 static int modifier_is_fluid_particles(ModifierData *md) {
1661 if(md->type == eModifierType_ParticleSystem) {
1662 if(((ParticleSystemModifierData *)md)->psys->part->type == PART_FLUID)
1667 static void draw_modifier(uiBlock *block, Object *ob, ModifierData *md, int *xco, int *yco, int index, int cageIndex, int lastCageIndex)
1669 ModifierTypeInfo *mti = modifierType_getInfo(md->type);
1671 int isVirtual = md->mode&eModifierMode_Virtual;
1672 int x = *xco, y = *yco, color = md->error?TH_REDALERT:TH_BUT_NEUTRAL;
1673 int editing = (G.obedit==ob);
1674 short height=26, width = 295, buttonWidth = width-120-10;
1677 /* rounded header */
1678 uiBlockSetCol(block, color);
1679 /* roundbox 4 free variables: corner-rounding, nop, roundbox type, shade */
1680 uiDefBut(block, ROUNDBOX, 0, "", x-10, y-4, width, 25, NULL, 7.0, 0.0,
1681 (!isVirtual && (md->mode&eModifierMode_Expanded))?3:15, 20, "");
1682 uiBlockSetCol(block, TH_AUTO);
1684 /* open/close icon */
1686 uiBlockSetEmboss(block, UI_EMBOSSN);
1687 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");
1690 uiBlockSetEmboss(block, UI_EMBOSS);
1693 sprintf(str, "%s parent deform", md->name);
1694 uiDefBut(block, LABEL, 0, str, x+10, y-1, width-110, 19, NULL, 0.0, 0.0, 0.0, 0.0, "Modifier name");
1696 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");
1697 uiButSetFunc(but, modifiers_convertToReal, ob, md);
1699 uiBlockBeginAlign(block);
1700 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");
1702 /* Softbody not allowed in this situation, enforce! */
1703 if ((md->type!=eModifierType_Softbody && md->type!=eModifierType_Collision) || !(ob->pd && ob->pd->deflect)) {
1704 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");
1705 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");
1706 if (mti->flags&eModifierTypeFlag_SupportsEditmode) {
1707 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)");
1710 uiBlockEndAlign(block);
1712 uiBlockSetEmboss(block, UI_EMBOSSR);
1714 if (ob->type==OB_MESH && modifier_couldBeCage(md) && index<=lastCageIndex) {
1717 if (index==cageIndex) {
1718 color = TH_BUT_SETTING;
1719 icon = VICON_EDITMODE_HLT;
1720 } else if (index<cageIndex) {
1721 color = TH_BUT_NEUTRAL;
1722 icon = VICON_EDITMODE_DEHLT;
1724 color = TH_BUT_NEUTRAL;
1727 uiBlockSetCol(block, color);
1728 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");
1729 uiButSetFunc(but, modifiers_setOnCage, ob, md);
1730 uiBlockSetCol(block, TH_AUTO);
1733 uiBlockSetCol(block, TH_BUT_ACTION);
1735 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");
1736 uiButSetFunc(but, modifiers_moveUp, ob, md);
1738 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");
1739 uiButSetFunc(but, modifiers_moveDown, ob, md);
1741 uiBlockSetEmboss(block, UI_EMBOSSN);
1743 // deletion over the deflection panel
1744 // fluid particle modifier can't be deleted here
1745 if(md->type!=eModifierType_Collision && !modifier_is_fluid_particles(md))
1747 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");
1748 uiButSetFunc(but, modifiers_del, ob, md);
1750 uiBlockSetCol(block, TH_AUTO);
1753 uiBlockSetEmboss(block, UI_EMBOSS);
1755 if (isVirtual || !(md->mode&eModifierMode_Expanded)) {
1759 int lx = x + width - 60 - 15;
1761 if (md->type==eModifierType_Subsurf) {
1763 } else if (md->type==eModifierType_Lattice) {
1765 } else if (md->type==eModifierType_Curve) {
1767 } else if (md->type==eModifierType_Build) {
1769 } else if (md->type==eModifierType_Mirror) {
1771 } else if (md->type==eModifierType_Bevel) {
1772 BevelModifierData *bmd = (BevelModifierData*) md;
1773 height = 105; /* height = 124; */
1774 if ((bmd->lim_flags & BME_BEVEL_ANGLE) || ((bmd->lim_flags & BME_BEVEL_WEIGHT) && !(bmd->flags & BME_BEVEL_VERT))) height += 19;
1775 } else if (md->type==eModifierType_EdgeSplit) {
1776 EdgeSplitModifierData *emd = (EdgeSplitModifierData*) md;
1778 if(emd->flags & MOD_EDGESPLIT_FROMANGLE) height += 19;
1779 } else if (md->type==eModifierType_Displace) {
1780 DisplaceModifierData *dmd = (DisplaceModifierData *)md;
1782 if(dmd->texmapping == MOD_DISP_MAP_OBJECT ||
1783 dmd->texmapping == MOD_DISP_MAP_UV)
1785 } else if (md->type==eModifierType_UVProject) {
1786 height = 114 + ((UVProjectModifierData *)md)->num_projectors * 19;
1787 } else if (md->type==eModifierType_Decimate) {
1789 } else if (md->type==eModifierType_Smooth) {
1791 } else if (md->type==eModifierType_Cast) {
1793 } else if (md->type==eModifierType_Wave) {
1794 WaveModifierData *wmd = (WaveModifierData *)md;
1796 if(wmd->texmapping == MOD_WAV_MAP_OBJECT ||
1797 wmd->texmapping == MOD_WAV_MAP_UV)
1799 if(wmd->flag & MOD_WAVE_NORM)
1801 } else if (md->type==eModifierType_Armature) {
1803 } else if (md->type==eModifierType_Hook) {
1804 HookModifierData *hmd = (HookModifierData*) md;
1808 if(hmd->indexar==NULL)
1810 } else if (md->type==eModifierType_Softbody) {
1812 } else if (md->type==eModifierType_Cloth) {
1814 } else if (md->type==eModifierType_Collision) {
1816 } else if (md->type==eModifierType_Sph) {
1818 } else if (md->type==eModifierType_Boolean) {
1820 } else if (md->type==eModifierType_Array) {
1822 } else if (md->type==eModifierType_MeshDeform) {
1823 MeshDeformModifierData *mmd= (MeshDeformModifierData*)md;
1824 height = (mmd->bindcos)? 73: 93;
1825 } else if (md->type==eModifierType_ParticleSystem) {
1827 } else if (md->type==eModifierType_ParticleInstance) {
1829 } else if (md->type==eModifierType_Explode) {
1832 /* roundbox 4 free variables: corner-rounding, nop, roundbox type, shade */
1833 uiDefBut(block, ROUNDBOX, 0, "", x-10, y-height-2, width, height-2, NULL, 5.0, 0.0, 12, 40, "");
1837 if (!isVirtual && (md->type!=eModifierType_Collision)) {
1838 uiBlockBeginAlign(block);
1839 if (md->type==eModifierType_ParticleSystem) {
1840 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");
1841 uiButSetFunc(but, modifiers_convertParticles, ob, md);
1844 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");
1845 uiButSetFunc(but, modifiers_applyModifier, ob, md);
1848 if (md->type!=eModifierType_Softbody && md->type!=eModifierType_ParticleSystem && (md->type!=eModifierType_Cloth) && (md->type!=eModifierType_Sph)) {
1849 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");
1850 uiButSetFunc(but, modifiers_copyModifier, ob, md);
1852 uiBlockEndAlign(block);
1857 uiBlockBeginAlign(block);
1858 if (md->type==eModifierType_Subsurf) {
1859 SubsurfModifierData *smd = (SubsurfModifierData*) md;
1860 char subsurfmenu[]="Subsurf Type%t|Catmull-Clark%x0|Simple Subdiv.%x1";
1861 uiDefButS(block, MENU, B_MODIFIER_RECALC, subsurfmenu, lx,(cy-=19),buttonWidth,19, &smd->subdivType, 0, 0, 0, 0, "Selects type of subdivision algorithm.");
1862 uiDefButS(block, NUM, B_MODIFIER_RECALC, "Levels:", lx, (cy-=19), buttonWidth,19, &smd->levels, 1, 6, 0, 0, "Number subdivisions to perform");
1863 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");
1865 /* Disabled until non-EM DerivedMesh implementation is complete */
1868 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");
1869 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");
1872 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");
1873 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");
1874 } else if (md->type==eModifierType_Lattice) {
1875 LatticeModifierData *lmd = (LatticeModifierData*) md;
1876 uiDefIDPoinBut(block, modifier_testLatticeObj, ID_OB, B_CHANGEDEP, "Ob: ", lx, (cy-=19), buttonWidth,19, &lmd->object, "Lattice object to deform with");
1877 but=uiDefBut(block, TEX, B_MODIFIER_RECALC, "VGroup: ", lx, (cy-=19), buttonWidth,19, &lmd->name, 0.0, 31.0, 0, 0, "Vertex Group name");
1878 uiButSetCompleteFunc(but, autocomplete_vgroup, (void *)ob);
1879 } else if (md->type==eModifierType_Curve) {
1880 CurveModifierData *cmd = (CurveModifierData*) md;
1881 uiDefIDPoinBut(block, modifier_testCurveObj, ID_OB, B_CHANGEDEP, "Ob: ", lx, (cy-=19), buttonWidth,19, &cmd->object, "Curve object to deform with");
1882 but=uiDefBut(block, TEX, B_MODIFIER_RECALC, "VGroup: ", lx, (cy-=19), buttonWidth,19, &cmd->name, 0.0, 31.0, 0, 0, "Vertex Group name");
1883 uiButSetCompleteFunc(but, autocomplete_vgroup, (void *)ob);
1885 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");
1886 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");
1887 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");
1888 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");
1889 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");
1890 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");
1891 } else if (md->type==eModifierType_Build) {
1892 BuildModifierData *bmd = (BuildModifierData*) md;
1893 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");
1894 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");
1895 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.");
1896 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.");
1897 } else if (md->type==eModifierType_Mirror) {
1898 MirrorModifierData *mmd = (MirrorModifierData*) md;
1899 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");
1900 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");
1901 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");
1902 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");
1903 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");
1904 uiDefButBitS(block, TOG, MOD_MIR_MIRROR_U, B_MODIFIER_RECALC,
1906 lx, (cy-=19), buttonWidth/2, 19,
1907 &mmd->flag, 0, 0, 0, 0,
1908 "Mirror the U texture coordinate around "
1910 uiDefButBitS(block, TOG, MOD_MIR_MIRROR_V, B_MODIFIER_RECALC,
1912 lx + buttonWidth/2 + 1, cy, buttonWidth/2, 19,
1913 &mmd->flag, 0, 0, 0, 0,
1914 "Mirror the V texture coordinate around "
1916 uiDefIDPoinBut(block, test_obpoin_but, ID_OB, B_CHANGEDEP,
1917 "Ob: ", lx, (cy -= 19), buttonWidth, 19,
1919 "Object to use as mirror");
1920 } else if (md->type==eModifierType_Bevel) {
1921 BevelModifierData *bmd = (BevelModifierData*) md;
1922 /*uiDefButS(block, ROW, B_MODIFIER_RECALC, "Distance",
1923 lx, (cy -= 19), (buttonWidth/2), 19, &bmd->val_flags,
1925 "Interpret bevel value as a constant distance from each edge");
1926 uiDefButS(block, ROW, B_MODIFIER_RECALC, "Radius",
1927 (lx+buttonWidth/2), cy, (buttonWidth - buttonWidth/2), 19, &bmd->val_flags,
1928 11.0, BME_BEVEL_RADIUS, 0, 0,
1929 "Interpret bevel value as a radius - smaller angles will be beveled more");*/
1930 uiBlockBeginAlign(block);
1931 uiDefButF(block, NUM, B_MODIFIER_RECALC, "Width: ",
1932 lx, (cy -= 19), buttonWidth, 19, &bmd->value,
1934 "Bevel value/amount");
1935 /*uiDefButI(block, NUM, B_MODIFIER_RECALC, "Recurs",
1936 lx, (cy -= 19), buttonWidth, 19, &bmd->res,
1938 "Number of times to bevel");*/
1939 uiDefButBitS(block, TOG, BME_BEVEL_VERT,
1940 B_MODIFIER_RECALC, "Only Vertices",
1941 lx, (cy -= 19), buttonWidth, 19,
1942 &bmd->flags, 0, 0, 0, 0,
1943 "Bevel only verts/corners; not edges");
1944 uiBlockEndAlign(block);
1946 uiDefBut(block, LABEL, 1, "Limit using:", lx, (cy-=25), buttonWidth,19, NULL, 0.0, 0.0, 0, 0, "");
1947 uiBlockBeginAlign(block);
1948 uiDefButS(block, ROW, B_MODIFIER_RECALC, "None",
1949 lx, (cy -= 19), (buttonWidth/3), 19, &bmd->lim_flags,
1951 "Bevel the entire mesh by a constant amount");
1952 uiDefButS(block, ROW, B_MODIFIER_RECALC, "Angle",
1953 (lx+buttonWidth/3), cy, (buttonWidth/3), 19, &bmd->lim_flags,
1954 12.0, BME_BEVEL_ANGLE, 0, 0,
1955 "Only bevel edges with sharp enough angles between faces");
1956 uiDefButS(block, ROW, B_MODIFIER_RECALC, "BevWeight",
1957 lx+(2*buttonWidth/3), cy, buttonWidth-2*(buttonWidth/3), 19, &bmd->lim_flags,
1958 12.0, BME_BEVEL_WEIGHT, 0, 0,
1959 "Use bevel weights to determine how much bevel is applied; apply them separately in vert/edge select mode");
1960 if ((bmd->lim_flags & BME_BEVEL_WEIGHT) && !(bmd->flags & BME_BEVEL_VERT)) {
1961 uiDefButS(block, ROW, B_MODIFIER_RECALC, "Min",
1962 lx, (cy -= 19), (buttonWidth/3), 19, &bmd->e_flags,
1963 13.0, BME_BEVEL_EMIN, 0, 0,
1964 "The sharpest edge's weight is used when weighting a vert");
1965 uiDefButS(block, ROW, B_MODIFIER_RECALC, "Average",
1966 (lx+buttonWidth/3), cy, (buttonWidth/3), 19, &bmd->e_flags,
1968 "The edge weights are averaged when weighting a vert");
1969 uiDefButS(block, ROW, B_MODIFIER_RECALC, "Max",
1970 (lx+2*(buttonWidth/3)), cy, buttonWidth-2*(buttonWidth/3), 19, &bmd->e_flags,
1971 13.0, BME_BEVEL_EMAX, 0, 0,
1972 "The largest edge's wieght is used when weighting a vert");
1974 else if (bmd->lim_flags & BME_BEVEL_ANGLE) {
1975 uiDefButF(block, NUM, B_MODIFIER_RECALC, "Angle:",
1976 lx, (cy -= 19), buttonWidth, 19, &bmd->bevel_angle,
1978 "Angle above which to bevel edges");
1980 } else if (md->type==eModifierType_EdgeSplit) {
1981 EdgeSplitModifierData *emd = (EdgeSplitModifierData*) md;
1982 uiDefButBitI(block, TOG, MOD_EDGESPLIT_FROMANGLE,
1983 B_MODIFIER_RECALC, "From Edge Angle",
1984 lx, (cy -= 19), buttonWidth, 19,
1985 &emd->flags, 0, 0, 0, 0,
1986 "Split edges with high angle between faces");
1987 if(emd->flags & MOD_EDGESPLIT_FROMANGLE) {
1988 uiDefButF(block, NUM, B_MODIFIER_RECALC, "Split Angle:",
1989 lx, (cy -= 19), buttonWidth, 19, &emd->split_angle,
1991 "Angle above which to split edges");
1993 uiDefButBitI(block, TOG, MOD_EDGESPLIT_FROMFLAG,
1994 B_MODIFIER_RECALC, "From Marked As Sharp",
1995 lx, (cy -= 19), buttonWidth, 19,
1996 &emd->flags, 0, 0, 0, 0,
1997 "Split edges that are marked as sharp");
1998 } else if (md->type==eModifierType_Displace) {
1999 DisplaceModifierData *dmd = (DisplaceModifierData*) md;
2000 but = uiDefBut(block, TEX, B_MODIFIER_RECALC, "VGroup: ",
2001 lx, (cy -= 19), buttonWidth, 19,
2002 &dmd->defgrp_name, 0.0, 31.0, 0, 0,
2003 "Name of vertex group to displace"
2004 " (displace whole mesh if blank)");
2005 uiButSetCompleteFunc(but, autocomplete_vgroup, (void *)ob);
2006 uiDefIDPoinBut(block, modifier_testTexture, ID_TE, B_CHANGEDEP,
2007 "Texture: ", lx, (cy -= 19), buttonWidth, 19,
2009 "Texture to use as displacement input");
2010 uiDefButF(block, NUM, B_MODIFIER_RECALC, "Midlevel:",
2011 lx, (cy -= 19), buttonWidth, 19, &dmd->midlevel,
2013 "Material value that gives no displacement");
2014 uiDefButF(block, NUM, B_MODIFIER_RECALC, "Strength:",
2015 lx, (cy -= 19), buttonWidth, 19, &dmd->strength,
2016 -1000, 1000, 10, 0.1,
2017 "Strength of displacement");
2018 sprintf(str, "Direction%%t|Normal%%x%d|RGB -> XYZ%%x%d|"
2019 "Z%%x%d|Y%%x%d|X%%x%d",
2020 MOD_DISP_DIR_NOR, MOD_DISP_DIR_RGB_XYZ,
2021 MOD_DISP_DIR_Z, MOD_DISP_DIR_Y, MOD_DISP_DIR_X);
2022 uiDefButI(block, MENU, B_MODIFIER_RECALC, str,
2023 lx, (cy -= 19), buttonWidth, 19, &dmd->direction,
2024 0.0, 1.0, 0, 0, "Displace direction");
2025 sprintf(str, "Texture Coordinates%%t"
2026 "|Local%%x%d|Global%%x%d|Object%%x%d|UV%%x%d",
2027 MOD_DISP_MAP_LOCAL, MOD_DISP_MAP_GLOBAL,
2028 MOD_DISP_MAP_OBJECT, MOD_DISP_MAP_UV);
2029 uiDefButI(block, MENU, B_MODIFIER_RECALC, str,
2030 lx, (cy -= 19), buttonWidth, 19, &dmd->texmapping,
2032 "Texture coordinates used for displacement input");
2033 if (dmd->texmapping == MOD_DISP_MAP_UV) {
2036 CustomData *fdata = G.obedit ? &G.editMesh->fdata
2037 : &((Mesh*)ob->data)->fdata;
2038 build_uvlayer_menu_vars(fdata, &strtmp, &dmd->uvlayer_tmp,
2040 but = uiDefButI(block, MENU, B_MODIFIER_RECALC, strtmp,
2041 lx, (cy -= 19), buttonWidth, 19, &dmd->uvlayer_tmp,
2042 0.0, 1.0, 0, 0, "Set the UV layer to use");
2044 i = CustomData_get_layer_index(fdata, CD_MTFACE);
2045 uiButSetFunc(but, set_displace_uvlayer, dmd,
2048 if(dmd->texmapping == MOD_DISP_MAP_OBJECT) {
2049 uiDefIDPoinBut(block, test_obpoin_but, ID_OB, B_CHANGEDEP,
2050 "Ob: ", lx, (cy -= 19), buttonWidth, 19,
2052 "Object to get texture coordinates from");
2054 } else if (md->type==eModifierType_UVProject) {
2055 UVProjectModifierData *umd = (UVProjectModifierData *) md;
2058 CustomData *fdata = G.obedit ? &G.editMesh->fdata
2059 : &((Mesh*)ob->data)->fdata;
2060 build_uvlayer_menu_vars(fdata, &strtmp, &umd->uvlayer_tmp,
2062 but = uiDefButI(block, MENU, B_MODIFIER_RECALC, strtmp,
2063 lx, (cy -= 19), buttonWidth, 19, &umd->uvlayer_tmp,
2064 0.0, 1.0, 0, 0, "Set the UV layer to use");
2065 i = CustomData_get_layer_index(fdata, CD_MTFACE);
2066 uiButSetFunc(but, set_uvproject_uvlayer, umd, &fdata->layers[i]);
2068 uiDefButF(block, NUM, B_MODIFIER_RECALC, "AspX:",
2069 lx, (cy -= 19), buttonWidth / 2, 19, &umd->aspectx,
2071 "Horizontal Aspect Ratio");
2072 uiDefButF(block, NUM, B_MODIFIER_RECALC, "AspY:",
2073 lx + (buttonWidth / 2) + 1, cy, buttonWidth / 2, 19,
2076 "Vertical Aspect Ratio");
2077 uiDefButI(block, NUM, B_MODIFIER_RECALC, "Projectors:",
2078 lx, (cy -= 19), buttonWidth, 19, &umd->num_projectors,
2079 1, MOD_UVPROJECT_MAXPROJECTORS, 0, 0,
2080 "Number of objects to use as projectors");
2081 for(i = 0; i < umd->num_projectors; ++i) {
2082 uiDefIDPoinBut(block, test_obpoin_but, ID_OB, B_CHANGEDEP,
2083 "Ob: ", lx, (cy -= 19), buttonWidth, 19,
2084 &umd->projectors[i],
2085 "Object to use as projector");
2087 uiDefIDPoinBut(block, modifier_testImage, ID_IM, B_CHANGEDEP,
2088 "Image: ", lx, (cy -= 19), buttonWidth, 19,
2090 "Image to project (only faces with this image "
2092 uiButSetCompleteFunc(but, autocomplete_image, (void *)ob);
2093 uiDefButBitI(block, TOG, MOD_UVPROJECT_OVERRIDEIMAGE,
2094 B_MODIFIER_RECALC, "Override Image",
2095 lx, (cy -= 19), buttonWidth, 19,
2096 &umd->flags, 0, 0, 0, 0,
2097 "Override faces' current images with the "
2099 } else if (md->type==eModifierType_Decimate) {
2100 DecimateModifierData *dmd = (DecimateModifierData*) md;
2101 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");
2102 sprintf(str, "Face Count: %d", dmd->faceCount);
2103 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");
2104 } else if (md->type==eModifierType_Smooth) {
2105 SmoothModifierData *smd = (SmoothModifierData*) md;
2107 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");
2108 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");
2109 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");
2111 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)");
2112 uiDefButS(block, NUM, B_MODIFIER_RECALC, "Repeat:", lx,(cy-=19),buttonWidth, 19, &smd->repeat, 0.0, 30.0, 1, 0, "Number of smoothing iterations");
2113 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");
2114 } else if (md->type==eModifierType_Cast) {
2115 CastModifierData *cmd = (CastModifierData*) md;
2117 char casttypemenu[]="Projection Type%t|Sphere%x0|Cylinder%x1|Cuboid%x2";
2118 uiDefButS(block, MENU, B_MODIFIER_RECALC, casttypemenu, lx,(cy-=19),buttonWidth - 30,19, &cmd->type, 0, 0, 0, 0, "Projection type to apply");
2119 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");
2120 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");
2121 if (cmd->type != MOD_CAST_TYPE_CYLINDER) {
2122 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");
2124 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");
2125 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)");
2126 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)");
2127 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)");
2128 if (ob->type == OB_MESH) {
2129 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");
2131 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");
2133 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");
2135 } else if (md->type==eModifierType_Wave) {
2136 WaveModifierData *wmd = (WaveModifierData*) md;
2137 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");
2138 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");
2139 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");
2140 uiDefButBitS(block, TOG, MOD_WAVE_NORM, B_MODIFIER_RECALC, "Normals", lx,(cy-=19),buttonWidth,19, &wmd->flag, 0, 0, 0, 0, "Displace along normals");
2141 if (wmd->flag & MOD_WAVE_NORM){
2142 if (ob->type==OB_MESH) {
2143 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");
2144 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");
2145 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");
2148 uiDefBut(block, LABEL, 1, "Meshes Only", lx, (cy-=19), buttonWidth,19, NULL, 0.0, 0.0, 0, 0, "");
2151 uiBlockBeginAlign(block);
2153 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");
2155 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");
2156 uiDefButF(block, NUM, B_MODIFIER_RECALC, "Lifetime:", lx,(cy-=19),buttonWidth,19, &wmd->lifetime, -MAXFRAMEF, MAXFRAMEF, 100, 0, "Specify the lifespan of the wave");
2157 uiDefButF(block, NUM, B_MODIFIER_RECALC, "Damptime:", lx,(cy-=19),buttonWidth,19, &wmd->damp, -MAXFRAMEF, MAXFRAMEF, 100, 0, "Specify the dampingtime of the wave");
2159 uiBlockBeginAlign(block);
2160 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");
2161 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");
2162 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)");
2163 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");
2164 uiDefIDPoinBut(block, modifier_testTexture, ID_TE, B_CHANGEDEP,"Texture: ", lx, (cy -= 19), 220, 19, &wmd->texture,"Texture with which to modulate wave");
2165 sprintf(str, "Texture Coordinates%%t"
2166 "|Local%%x%d|Global%%x%d|Object%%x%d|UV%%x%d",
2167 MOD_WAV_MAP_LOCAL, MOD_WAV_MAP_GLOBAL,
2168 MOD_WAV_MAP_OBJECT, MOD_WAV_MAP_UV);
2169 uiDefButI(block, MENU, B_MODIFIER_RECALC, str,
2170 lx, (cy -= 19), 220, 19, &wmd->texmapping,
2172 "Texture coordinates used for modulation input");
2173 if (wmd->texmapping == MOD_WAV_MAP_UV) {
2176 CustomData *fdata = G.obedit ? &G.editMesh->fdata
2177 : &((Mesh*)ob->data)->fdata;
2178 build_uvlayer_menu_vars(fdata, &strtmp, &wmd->uvlayer_tmp,
2180 but = uiDefButI(block, MENU, B_MODIFIER_RECALC, strtmp,
2181 lx, (cy -= 19), 220, 19, &wmd->uvlayer_tmp,
2182 0.0, 1.0, 0, 0, "Set the UV layer to use");
2184 i = CustomData_get_layer_index(fdata, CD_MTFACE);
2185 uiButSetFunc(but, set_displace_uvlayer, wmd,
2188 if(wmd->texmapping == MOD_DISP_MAP_OBJECT) {
2189 uiDefIDPoinBut(block, test_obpoin_but, ID_OB, B_CHANGEDEP,
2190 "Ob: ", lx, (cy -= 19), 220, 19,
2192 "Object to get texture coordinates from");
2195 uiBlockBeginAlign(block);
2196 uiDefButF(block, NUMSLI, B_MODIFIER_RECALC, "Speed:", lx,(cy-=19),220,19, &wmd->speed, -2.0, 2.0, 0, 0, "Specify the wave speed");
2197 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");
2198 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");
2199 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");
2200 } else if (md->type==eModifierType_Armature) {
2201 ArmatureModifierData *amd = (ArmatureModifierData*) md;
2202 uiDefIDPoinBut(block, modifier_testArmatureObj, ID_OB, B_CHANGEDEP, "Ob: ", lx, (cy-=19), buttonWidth,19, &amd->object, "Armature object to deform with");
2204 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");
2205 uiButSetCompleteFunc(but, autocomplete_vgroup, (void *)ob);
2206 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");
2208 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");
2209 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");
2210 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");
2211 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");
2213 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");
2215 } else if (md->type==eModifierType_Hook) {
2216 HookModifierData *hmd = (HookModifierData*) md;
2217 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");
2218 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");
2219 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");
2220 if(hmd->indexar==NULL) {
2221 but=uiDefBut(block, TEX, B_MODIFIER_RECALC, "VGroup: ", lx, (cy-=19), buttonWidth,19, &hmd->name, 0.0, 31.0, 0, 0, "Vertex Group name");
2222 uiButSetCompleteFunc(but, autocomplete_vgroup, (void *)ob);
2224 uiBlockBeginAlign(block);
2225 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");
2226 uiButSetFunc(but, modifiers_clearHookOffset, ob, md);
2227 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");
2228 uiButSetFunc(but, modifiers_cursorHookCenter, ob, md);
2231 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");
2232 uiButSetFunc(but, modifiers_selectHook, ob, md);
2233 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");
2234 uiButSetFunc(but, modifiers_reassignHook, ob, md);
2236 } else if (md->type==eModifierType_Softbody) {
2237 uiDefBut(block, LABEL, 1, "See Soft Body panel.", lx, (cy-=19), buttonWidth,19, NULL, 0.0, 0.0, 0, 0, "");
2238 } else if (md->type==eModifierType_Cloth) {
2239 uiDefBut(block, LABEL, 1, "See Cloth panel.", lx, (cy-=19), buttonWidth,19, NULL, 0.0, 0.0, 0, 0, "");
2240 } else if (md->type==eModifierType_Sph) {
2241 uiDefBut(block, LABEL, 1, "See Sph panel.", lx, (cy-=19), buttonWidth,19, NULL, 0.0, 0.0, 0, 0, "");
2242 } else if (md->type==eModifierType_Collision) {
2243 uiDefBut(block, LABEL, 1, "See Collision panel.", lx, (cy-=19), buttonWidth,19, NULL, 0.0, 0.0, 0, 0, "");
2244 } else if (md->type==eModifierType_Boolean) {
2245 BooleanModifierData *bmd = (BooleanModifierData*) md;
2246 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");
2247 uiDefIDPoinBut(block, modifier_testMeshObj, ID_OB, B_CHANGEDEP, "Ob: ", lx, (cy-=19), buttonWidth,19, &bmd->object, "Mesh object to use for boolean operation");
2248 } else if (md->type==eModifierType_Array) {
2249 ArrayModifierData *amd = (ArrayModifierData*) md;
2250 float range = 10000;
2251 int cytop, halfwidth = (width - 5)/2 - 15;
2252 int halflx = lx + halfwidth + 10;
2254 uiBlockSetEmboss(block, UI_EMBOSSX);
2255 uiBlockEndAlign(block);
2257 /* length parameters */
2258 uiBlockBeginAlign(block);
2259 sprintf(str, "Length Fit%%t|Fixed Count%%x%d|Fixed Length%%x%d"
2260 "|Fit To Curve Length%%x%d",
2261 MOD_ARR_FIXEDCOUNT, MOD_ARR_FITLENGTH, MOD_ARR_FITCURVE);
2262 uiDefButI(block, MENU, B_MODIFIER_RECALC, str,
2263 lx, (cy-=19), buttonWidth, 19, &amd->fit_type,
2264 0.0, 1.0, 0, 0, "Array length calculation method");
2265 switch(amd->fit_type)
2267 case MOD_ARR_FIXEDCOUNT:
2268 uiDefButI(block, NUM, B_MODIFIER_RECALC, "Count:",
2269 lx, (cy -= 19), buttonWidth, 19, &amd->count,
2270 1, 1000, 0, 0, "Number of duplicates to make");
2272 case MOD_ARR_FITLENGTH:
2273 uiDefButF(block, NUM, B_MODIFIER_RECALC, "Length:",
2274 lx, (cy -= 19), buttonWidth, 19, &amd->length,
2276 "Length to fit array within");
2278 case MOD_ARR_FITCURVE:
2279 uiDefIDPoinBut(block, modifier_testCurveObj, ID_OB,
2280 B_CHANGEDEP, "Ob: ",
2281 lx, (cy -= 19), buttonWidth, 19, &amd->curve_ob,
2282 "Curve object to fit array length to");
2285 uiBlockEndAlign(block);
2287 /* offset parameters */
2290 uiBlockBeginAlign(block);
2291 uiDefButBitI(block, TOG, MOD_ARR_OFF_CONST, B_MODIFIER_RECALC,
2292 "Constant Offset", lx, (cy-=19), halfwidth, 19,
2293 &amd->offset_type, 0, 0, 0, 0,
2294 "Constant offset between duplicates "
2295 "(local coordinates)");
2296 uiDefButF(block, NUM, B_MODIFIER_RECALC, "X:",
2297 lx, (cy-=19), halfwidth, 19,
2299 -range, range, 10, 3,
2300 "Constant component for duplicate offsets "
2301 "(local coordinates)");
2302 uiDefButF(block, NUM, B_MODIFIER_RECALC, "Y:",
2303 lx, (cy-=19), halfwidth, 19,
2305 -range, range, 10, 3,
2306 "Constant component for duplicate offsets "
2307 "(local coordinates)");
2308 uiDefButF(block, NUM, B_MODIFIER_RECALC, "Z:",
2309 lx, (cy-=19), halfwidth, 19,
2311 -range, range, 10, 3,
2312 "Constant component for duplicate offsets "
2313 "(local coordinates)");
2314 uiBlockEndAlign(block);
2317 uiBlockBeginAlign(block);
2318 uiDefButBitI(block, TOG, MOD_ARR_OFF_RELATIVE, B_MODIFIER_RECALC,
2319 "Relative Offset", halflx, (cy-=19), halfwidth, 19,
2320 &amd->offset_type, 0, 0, 0, 0,
2321 "Offset between duplicates relative to object width "
2322 "(local coordinates)");
2323 uiDefButF(block, NUM, B_MODIFIER_RECALC, "X:",
2324 halflx, (cy-=19), halfwidth, 19,
2326 -range, range, 10, 3,
2327 "Component for duplicate offsets relative to object "
2328 "width (local coordinates)");
2329 uiDefButF(block, NUM, B_MODIFIER_RECALC, "Y:",
2330 halflx, (cy-=19), halfwidth, 19,
2332 -range, range, 10, 3,
2333 "Component for duplicate offsets relative to object "
2334 "width (local coordinates)");
2335 uiDefButF(block, NUM, B_MODIFIER_RECALC, "Z:",
2336 halflx, (cy-=19), halfwidth, 19,
2338 -range, range, 10, 3,
2339 "Component for duplicate offsets relative to object "
2340 "width (local coordinates)");
2341 uiBlockEndAlign(block);
2343 /* vertex merging parameters */
2347 uiBlockBeginAlign(block);
2348 uiDefButBitI(block, TOG, MOD_ARR_MERGE, B_MODIFIER_RECALC,
2350 lx, (cy-=19), halfwidth/2, 19, &amd->flags,
2352 "Merge vertices in adjacent duplicates");
2353 uiDefButBitI(block, TOG, MOD_ARR_MERGEFINAL, B_MODIFIER_RECALC,
2355 lx + halfwidth/2, cy, (halfwidth+1)/2, 19,
2358 "Merge vertices in first duplicate with vertices"
2359 " in last duplicate");
2360 uiDefButF(block, NUM, B_MODIFIER_RECALC, "Limit:",
2361 lx, (cy-=19), halfwidth, 19, &amd->merge_dist,
2363 "Limit below which to merge vertices");
2367 uiBlockBeginAlign(block);
2368 uiDefButBitI(block, TOG, MOD_ARR_OFF_OBJ, B_MODIFIER_RECALC,
2369 "Object Offset", halflx, (cy -= 19), halfwidth, 19,
2370 &amd->offset_type, 0, 0, 0, 0,
2371 "Add an object transformation to the total offset");
2372 uiDefIDPoinBut(block, test_obpoin_but, ID_OB, B_CHANGEDEP,
2373 "Ob: ", halflx, (cy -= 19), halfwidth, 19,
2375 "Object from which to take offset transformation");
2376 uiBlockEndAlign(block);
2379 but = uiDefIDPoinBut(block, test_meshobpoin_but, ID_OB,
2380 B_CHANGEDEP, "Start cap: ",
2381 lx, (cy -= 19), halfwidth, 19,
2383 "Mesh object to use as start cap");
2384 uiButSetCompleteFunc(but, autocomplete_meshob, (void *)ob);
2385 but = uiDefIDPoinBut(block, test_meshobpoin_but, ID_OB,
2386 B_CHANGEDEP, "End cap: ",
2387 halflx, cy, halfwidth, 19,
2389 "Mesh object to use as end cap");
2390 uiButSetCompleteFunc(but, autocomplete_meshob, (void *)ob);
2391 } else if (md->type==eModifierType_MeshDeform) {
2392 MeshDeformModifierData *mmd = (MeshDeformModifierData*) md;
2394 uiBlockBeginAlign(block);
2395 uiDefIDPoinBut(block, test_meshobpoin_but, ID_OB, B_CHANGEDEP, "Ob: ", lx, (cy-=19), buttonWidth,19, &mmd->object, "Mesh object to be use as cage");
2396 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");
2397 uiButSetCompleteFunc(but, autocomplete_vgroup, (void *)ob);
2398 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");
2400 uiBlockBeginAlign(block);
2402 but= uiDefBut(block, BUT, B_MODIFIER_RECALC, "Unbind", lx,(cy-=24), buttonWidth,19, 0, 0, 0, 0, 0, "Unbind mesh from cage");
2403 uiButSetFunc(but,modifiers_bindMeshDeform,ob,md);
2406 but= uiDefBut(block, BUT, B_MODIFIER_RECALC, "Bind", lx,(cy-=24), buttonWidth,19, 0, 0, 0, 0, 0, "Bind mesh to cage");
2407 uiButSetFunc(but,modifiers_bindMeshDeform,ob,md);
2408 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");
2409 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, "Invert vertex group influence");
2411 uiBlockEndAlign(block);
2412 } else if (md->type==eModifierType_ParticleSystem) {
2413 uiDefBut(block, LABEL, 1, "See Particle buttons.", lx, (cy-=19), buttonWidth,19, NULL, 0.0, 0.0, 0, 0, "");
2414 } else if (md->type==eModifierType_ParticleInstance) {
2415 ParticleInstanceModifierData *pimd = (ParticleInstanceModifierData*) md;
2416 uiDefIDPoinBut(block, test_obpoin_but, ID_OB, B_CHANGEDEP, "Ob: ", lx, (cy -= 19), buttonWidth, 19, &pimd->ob, "Object that has the particlesystem");
2417 uiDefButS(block, NUM, B_MODIFIER_RECALC, "PSYS:", lx, (cy -= 19), buttonWidth, 19, &pimd->psys, 1, 10, 10, 3, "Particlesystem number in the object");
2418 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");
2419 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");
2420 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");
2421 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");
2422 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");
2423 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");
2424 } else if (md->type==eModifierType_Explode) {
2425 ExplodeModifierData *emd = (ExplodeModifierData*) md;
2427 char *menustr= get_vertexgroup_menustr(ob);
2428 int defCount=BLI_countlist(&ob->defbase);
2429 if(defCount==0) emd->vgroup=0;
2430 uiBlockBeginAlign(block);
2431 but=uiDefButS(block, MENU, B_MODIFIER_RECALC, menustr, lx, (cy-=19), buttonWidth-20,19, &emd->vgroup, 0, defCount, 0, 0, "Protect this vertex group");
2432 uiButSetFunc(but,modifiers_explodeFacepa,emd,0);
2435 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");
2436 uiButSetFunc(but, modifiers_explodeDelVg, (void *)emd, (void *)NULL);
2439 but=uiDefButF(block, NUMSLI, B_MODIFIER_RECALC, "", lx, (cy-=19), buttonWidth,19, &emd->protect, 0.0f, 1.0f, 0, 0, "Clean vertex group edges");
2440 uiButSetFunc(but,modifiers_explodeFacepa,emd,0);
2442 but=uiDefBut(block, BUT, B_MODIFIER_RECALC, "Refresh", lx, (cy-=19), buttonWidth/2,19, 0, 0, 0, 0, 0, "Recalculate faces assigned to particles");
2443 uiButSetFunc(but,modifiers_explodeFacepa,emd,0);
2445 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");
2446 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");
2447 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");
2448 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");
2449 uiBlockEndAlign(block);
2452 uiBlockEndAlign(block);
2460 uiBlockSetCol(block, color);
2461 /* roundbox 4 free variables: corner-rounding, nop, roundbox type, shade */
2462 uiDefBut(block, ROUNDBOX, 0, "", x-10, y, width, 20, NULL, 5.0, 0.0, 15, 40, "");
2463 uiBlockSetCol(block, TH_AUTO);
2465 uiDefIconBut(block,LABEL,B_NOP,ICON_ERROR, x-9, y,19,19, 0,0,0,0,0, "");
2466 uiDefBut(block, LABEL, B_NOP, md->error, x+5, y, width-15, 19, NULL, 0.0, 0.0, 0.0, 0.0, "");
2479 static void editing_panel_modifiers(Object *ob)
2484 int xco, yco, i, lastCageIndex, cageIndex = modifiers_getCageIndex(ob, &lastCageIndex);
2486 block= uiNewBlock(&curarea->uiblocks, "editing_panel_modifiers", UI_EMBOSS, UI_HELV, curarea->win);
2487 if( uiNewPanel(curarea, block, "Modifiers", "Editing", 640, 0, 318, 204)==0) return;
2489 uiSetButLock(object_data_is_libdata(ob), ERROR_LIBDATA_MESSAGE);
2490 uiNewPanelHeight(block, 204);
2492 uiDefBlockBut(block, modifiers_add_menu, ob, "Add Modifier", 0, 190, 130, 20, "Add a new modifier");
2494 sprintf(str, "To: %s", ob->id.name+2);
2495 uiDefBut(block, LABEL, 1, str, 140, 190, 160, 20, NULL, 0.0, 0.0, 0, 0, "Object whose modifier stack is being edited");
2500 md = modifiers_getVirtualModifierList(ob);
2502 for (i=0; md; i++, md=md->next) {
2503 draw_modifier(block, ob, md, &xco, &yco, i, cageIndex, lastCageIndex);
2504 if (md->mode&eModifierMode_Virtual) i--;
2507 if(yco < 0) uiNewPanelHeight(block, 204-yco);
2510 static char *make_key_menu(Key *key, int startindex)
2514 char *str, item[64];
2516 for (kb = key->block.first; kb; kb=kb->next, index++);
2517 str= MEM_mallocN(index*40, "key string");
2521 for (kb = key->block.first; kb; kb=kb->next, index++) {
2522 sprintf (item, "|%s%%x%d", kb->name, index);
2529 static void editing_panel_shapes(Object *ob)
2537 block= uiNewBlock(&curarea->uiblocks, "editing_panel_shapes", UI_EMBOSS, UI_HELV, curarea->win);
2538 uiNewPanelTabbed("Modifiers", "Editing");
2539 if( uiNewPanel(curarea, block, "Shapes", "Editing", 640, 0, 318, 204)==0) return;
2541 /* Todo check data is library here */
2542 uiSetButLock(object_data_is_libdata(ob), ERROR_LIBDATA_MESSAGE);
2544 uiDefBut(block, BUT, B_ADDKEY, "Add Shape Key" , 10, 180, 150, 20, NULL, 0.0, 0.0, 0, 0, "Add new Shape Key");
2546 key= ob_get_key(ob);
2548 /* label aligns add button */
2549 uiDefBut(block, LABEL, 0, "", 170, 180,140,20, NULL, 0, 0, 0, 0, "");
2553 uiDefButS(block, TOG, B_RELKEY, "Relative", 170, 180,140,20, &key->type, 0, 0, 0, 0, "Makes Shape Keys relative");
2555 kb= BLI_findlink(&key->block, ob->shapenr-1);
2558 kb= key->block.first;
2561 uiBlockBeginAlign(block);
2562 if(ob->shapeflag & OB_SHAPE_LOCK) icon= ICON_PIN_HLT; else icon= ICON_PIN_DEHLT;
2563 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");
2564 if(kb->flag & KEYBLOCK_MUTE) icon= ICON_MUTE_IPO_ON; else icon = ICON_MUTE_IPO_OFF;
2565 uiDefIconButBitS(block, TOG, KEYBLOCK_MUTE, B_MODIFIER_RECALC, icon, 35,150,20,20, &kb->flag, 0, 0, 0, 0, "Mute the current Shape");
2566 uiSetButLock(G.obedit==ob, "Unable to perform in EditMode");
2567 uiDefIconBut(block, BUT, B_PREVKEY, ICON_TRIA_LEFT, 55,150,20,20, NULL, 0, 0, 0, 0, "Previous Shape Key");
2568 strp= make_key_menu(key, 1);
2569 uiDefButS(block, MENU, B_SETKEY, strp, 75,150,20,20, &ob->shapenr, 0, 0, 0, 0, "Browse existing choices");
2572 uiDefIconBut(block, BUT, B_NEXTKEY, ICON_TRIA_RIGHT, 95,150,20,20, NULL, 0, 0, 0, 0, "Next Shape Key");
2574 uiDefBut(block, TEX, B_NAMEKEY, "", 115, 150, 170, 20, kb->name, 0.0, 31.0, 0, 0, "Current Shape Key name");
2575 uiDefIconBut(block, BUT, B_DELKEY, ICON_X, 285,150,25,20, 0, 0, 0, 0, 0, "Deletes current Shape Key");
2576 uiBlockEndAlign(block);
2578 if(key->type && (ob->shapeflag & OB_SHAPE_LOCK)==0 && ob->shapenr!=1) {
2579 uiBlockBeginAlign(block);
2580 make_rvk_slider(block, ob, ob->shapenr-1, 10, 120, 150, 20, "Key value, when used it inserts an animation curve point");
2581 uiDefButF(block, NUM, B_REDR, "Min ", 160,120, 75, 20, &kb->slidermin, -10.0, 10.0, 100, 1, "Minumum for slider");
2582 uiDefButF(block, NUM, B_REDR, "Max ", 235,120, 75, 20, &kb->slidermax, -10.0, 10.0, 100, 1, "Maximum for slider");
2583 uiBlockEndAlign(block);
2585 if(key->type && ob->shapenr!=1) {
2586 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");
2588 strp= make_key_menu(key, 0);
2589 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");
2594 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");
2598 /* *************************** FONT ******************************** */
2600 static short give_vfontnr(VFont *vfont)
2605 vf= G.main->vfont.first;
2607 if(vf==vfont) return nr;
2614 static VFont *give_vfontpointer(int nr) /* nr= button */
2619 vf= G.main->vfont.first;
2621 if(tel==nr) return vf;
2625 return G.main->vfont.first;
2628 VFont *exist_vfont(char *str)
2632 vf= G.main->vfont.first;
2634 if(strcmp(vf->name, str)==0) return vf;
2640 static char *give_vfontbutstr(void)
2644 char *str, di[FILE_MAXDIR], fi[FILE_MAXFILE];
2646 vf= G.main->vfont.first;
2648 strcpy(di, vf->name);
2649 BLI_splitdirstring(di, fi);
2654 str= MEM_callocN(len+21, "vfontbutstr");
2655 strcpy(str, "FONTS %t");
2656 vf= G.main->vfont.first;
2659 if(vf->id.us==0) strcat(str, "|0 ");
2660 else strcat(str, "| ");
2662 strcpy(di, vf->name);
2663 BLI_splitdirstring(di, fi);
2671 static void load_buts_vfont(char *name)
2676 if(OBACT && OBACT->type==OB_FONT) cu= OBACT->data;
2679 vf= exist_vfont(name);
2681 vf= load_vfont(name);
2684 else id_us_plus((ID *)vf);
2686 switch(cu->curinfo.flag & CU_STYLE) {
2688 if(cu->vfontb) cu->vfontb->id.us--;
2692 if(cu->vfonti) cu->vfonti->id.us--;
2695 case (CU_BOLD|CU_ITALIC):
2696 if(cu->vfontbi) cu->vfontbi->id.us--;
2700 if(cu->vfont) cu->vfont->id.us--;
2705 DAG_object_flush_update(G.scene, OBACT, OB_RECALC_DATA);
2706 BIF_undo_push("Load vector font");
2707 allqueue(REDRAWVIEW3D, 0);
2708 allqueue(REDRAWBUTSEDIT, 0);
2711 static void set_unicode_text_fs(char *file)
2713 if (file) paste_unicodeText(file);
2716 void do_fontbuts(unsigned short event)
2732 DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA);
2733 allqueue(REDRAWVIEW3D, 0);
2740 case B_STYLETOSELU: style = CU_UNDERLINE; break;
2741 case B_STYLETOSELB: style = CU_BOLD; break;
2742 case B_STYLETOSELI: style = CU_ITALIC; break;
2744 if (style_to_sel(style, ((Curve*)ob->data)->curinfo.flag & style)) {
2745 text_to_curve(ob, 0);
2746 makeDispListCurveTypes(ob, 0);
2747 allqueue(REDRAWVIEW3D, 0);
2749 allqueue(REDRAWBUTSEDIT, 0);
2754 DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA);
2755 allqueue(REDRAWVIEW3D, 0);
2760 if (cu->totbox < 256) {
2761 for (i = cu->totbox; i>cu->actbox; i--) cu->tb[i]= cu->tb[i-1];
2762 cu->tb[cu->actbox]= cu->tb[cu->actbox-1];
2765 allqueue(REDRAWBUTSEDIT, 0);
2766 allqueue(REDRAWVIEW3D, 0);
2767 text_to_curve(ob, 0);
2768 makeDispListCurveTypes(ob, 0);
2771 error("Do you really need that many text frames?");
2776 if (cu->totbox > 1) {
2777 for (i = cu->actbox-1; i < cu->totbox; i++) cu->tb[i]= cu->tb[i+1];
2780 allqueue(REDRAWBUTSEDIT, 0);
2781 allqueue(REDRAWVIEW3D, 0);
2782 text_to_curve(ob, 0);
2783 makeDispListCurveTypes(ob, 0);
2790 vf= give_vfontpointer(G.buts->texnr);
2791 if(vf && vf->id.prev!=vf->id.next) strcpy(str, vf->name);
2792 else strcpy(str, U.fontdir);
2794 sa= closest_bigger_area();
2795 areawinset(sa->win);
2797 activate_fileselect(FILE_LOADFONT, "SELECT FONT", str, load_buts_vfont);
2803 if(cu && cu->vfont) {
2804 if (cu->vfont->packedfile) {
2805 if (G.fileflags & G_AUTOPACK) {
2806 if (okee("Disable AutoPack ?")) {
2807 G.fileflags &= ~G_AUTOPACK;
2811 if ((G.fileflags & G_AUTOPACK) == 0) {
2812 if (unpackVFont(cu->vfont, PF_ASK) == RET_OK) {
2813 DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA);
2814 allqueue(REDRAWVIEW3D, 0);
2818 cu->vfont->packedfile = newPackedFile(cu->vfont->name);
2822 allqueue(REDRAWHEADERS, 0);
2823 allqueue(REDRAWBUTSEDIT, 0);
2827 if (!G.obedit) { error("Only in editmode!"); return; }
2828 if (G.obedit->type != OB_FONT) return;
2829 activate_fileselect(FILE_SPECIAL, "Open Text File", G.sce, load_3dtext_fs);
2833 if (!G.obedit) { error("Only in editmode!"); return; }
2834 if (G.obedit->type != OB_FONT) return;
2843 vf= give_vfontpointer(G.buts->texnr);
2845 id_us_plus((ID *)vf);
2847 switch(cu->curinfo.flag & CU_STYLE) {
2849 cu->vfontb->id.us--;