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);
517 else if ELEM(G.obedit->type, OB_CURVE, OB_SURF) {
520 if(nu->mat_nr==G.obedit->actcol-1) {
526 if(event==B_MATSEL) {
541 a= nu->pntsu*nu->pntsv;
545 if(event==B_MATSEL) bp->f1 |= SELECT;
546 else bp->f1 &= ~SELECT;
554 BIF_undo_push("Select material index");
556 allqueue(REDRAWIMAGE, 0);
557 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_Fluidsim)) 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_Fluidsim && 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_Boolean) {
1818 } else if (md->type==eModifierType_Array) {
1820 } else if (md->type==eModifierType_MeshDeform) {
1821 MeshDeformModifierData *mmd= (MeshDeformModifierData*)md;
1822 height = (mmd->bindcos)? 73: 93;
1823 } else if (md->type==eModifierType_ParticleSystem) {
1825 } else if (md->type==eModifierType_ParticleInstance) {
1827 } else if (md->type==eModifierType_Explode) {
1829 } else if (md->type==eModifierType_Fluidsim) {
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_Fluidsim && md->type!=eModifierType_Softbody && md->type!=eModifierType_ParticleSystem && (md->type!=eModifierType_Cloth)) {
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_VGROUP, B_MODIFIER_RECALC, "Mirror Vgroups", lx, (cy-=19), buttonWidth,19, &mmd->flag, 1, 2, 0, 0, "Mirror vertex groups (e.g. .R->.L)");
1905 uiDefButBitS(block, TOG, MOD_MIR_MIRROR_U, B_MODIFIER_RECALC,
1907 lx, (cy-=19), buttonWidth/2, 19,
1908 &mmd->flag, 0, 0, 0, 0,
1909 "Mirror the U texture coordinate around "
1911 uiDefButBitS(block, TOG, MOD_MIR_MIRROR_V, B_MODIFIER_RECALC,
1913 lx + buttonWidth/2 + 1, cy, buttonWidth/2, 19,
1914 &mmd->flag, 0, 0, 0, 0,
1915 "Mirror the V texture coordinate around "
1917 uiDefIDPoinBut(block, test_obpoin_but, ID_OB, B_CHANGEDEP,
1918 "Ob: ", lx, (cy -= 19), buttonWidth, 19,
1920 "Object to use as mirror");
1921 } else if (md->type==eModifierType_Bevel) {
1922 BevelModifierData *bmd = (BevelModifierData*) md;
1923 /*uiDefButS(block, ROW, B_MODIFIER_RECALC, "Distance",
1924 lx, (cy -= 19), (buttonWidth/2), 19, &bmd->val_flags,
1926 "Interpret bevel value as a constant distance from each edge");
1927 uiDefButS(block, ROW, B_MODIFIER_RECALC, "Radius",
1928 (lx+buttonWidth/2), cy, (buttonWidth - buttonWidth/2), 19, &bmd->val_flags,
1929 11.0, BME_BEVEL_RADIUS, 0, 0,
1930 "Interpret bevel value as a radius - smaller angles will be beveled more");*/
1931 uiBlockBeginAlign(block);
1932 uiDefButF(block, NUM, B_MODIFIER_RECALC, "Width: ",
1933 lx, (cy -= 19), buttonWidth, 19, &bmd->value,
1935 "Bevel value/amount");
1936 /*uiDefButI(block, NUM, B_MODIFIER_RECALC, "Recurs",
1937 lx, (cy -= 19), buttonWidth, 19, &bmd->res,
1939 "Number of times to bevel");*/
1940 uiDefButBitS(block, TOG, BME_BEVEL_VERT,
1941 B_MODIFIER_RECALC, "Only Vertices",
1942 lx, (cy -= 19), buttonWidth, 19,
1943 &bmd->flags, 0, 0, 0, 0,
1944 "Bevel only verts/corners; not edges");
1945 uiBlockEndAlign(block);
1947 uiDefBut(block, LABEL, 1, "Limit using:", lx, (cy-=25), buttonWidth,19, NULL, 0.0, 0.0, 0, 0, "");
1948 uiBlockBeginAlign(block);
1949 uiDefButS(block, ROW, B_MODIFIER_RECALC, "None",
1950 lx, (cy -= 19), (buttonWidth/3), 19, &bmd->lim_flags,
1952 "Bevel the entire mesh by a constant amount");
1953 uiDefButS(block, ROW, B_MODIFIER_RECALC, "Angle",
1954 (lx+buttonWidth/3), cy, (buttonWidth/3), 19, &bmd->lim_flags,
1955 12.0, BME_BEVEL_ANGLE, 0, 0,
1956 "Only bevel edges with sharp enough angles between faces");
1957 uiDefButS(block, ROW, B_MODIFIER_RECALC, "BevWeight",
1958 lx+(2*buttonWidth/3), cy, buttonWidth-2*(buttonWidth/3), 19, &bmd->lim_flags,
1959 12.0, BME_BEVEL_WEIGHT, 0, 0,
1960 "Use bevel weights to determine how much bevel is applied; apply them separately in vert/edge select mode");
1961 if ((bmd->lim_flags & BME_BEVEL_WEIGHT) && !(bmd->flags & BME_BEVEL_VERT)) {
1962 uiDefButS(block, ROW, B_MODIFIER_RECALC, "Min",
1963 lx, (cy -= 19), (buttonWidth/3), 19, &bmd->e_flags,
1964 13.0, BME_BEVEL_EMIN, 0, 0,
1965 "The sharpest edge's weight is used when weighting a vert");
1966 uiDefButS(block, ROW, B_MODIFIER_RECALC, "Average",
1967 (lx+buttonWidth/3), cy, (buttonWidth/3), 19, &bmd->e_flags,
1969 "The edge weights are averaged when weighting a vert");
1970 uiDefButS(block, ROW, B_MODIFIER_RECALC, "Max",
1971 (lx+2*(buttonWidth/3)), cy, buttonWidth-2*(buttonWidth/3), 19, &bmd->e_flags,
1972 13.0, BME_BEVEL_EMAX, 0, 0,
1973 "The largest edge's wieght is used when weighting a vert");
1975 else if (bmd->lim_flags & BME_BEVEL_ANGLE) {
1976 uiDefButF(block, NUM, B_MODIFIER_RECALC, "Angle:",
1977 lx, (cy -= 19), buttonWidth, 19, &bmd->bevel_angle,
1979 "Angle above which to bevel edges");
1981 } else if (md->type==eModifierType_EdgeSplit) {
1982 EdgeSplitModifierData *emd = (EdgeSplitModifierData*) md;
1983 uiDefButBitI(block, TOG, MOD_EDGESPLIT_FROMANGLE,
1984 B_MODIFIER_RECALC, "From Edge Angle",
1985 lx, (cy -= 19), buttonWidth, 19,
1986 &emd->flags, 0, 0, 0, 0,
1987 "Split edges with high angle between faces");
1988 if(emd->flags & MOD_EDGESPLIT_FROMANGLE) {
1989 uiDefButF(block, NUM, B_MODIFIER_RECALC, "Split Angle:",
1990 lx, (cy -= 19), buttonWidth, 19, &emd->split_angle,
1992 "Angle above which to split edges");
1994 uiDefButBitI(block, TOG, MOD_EDGESPLIT_FROMFLAG,
1995 B_MODIFIER_RECALC, "From Marked As Sharp",
1996 lx, (cy -= 19), buttonWidth, 19,
1997 &emd->flags, 0, 0, 0, 0,
1998 "Split edges that are marked as sharp");
1999 } else if (md->type==eModifierType_Displace) {
2000 DisplaceModifierData *dmd = (DisplaceModifierData*) md;
2001 but = uiDefBut(block, TEX, B_MODIFIER_RECALC, "VGroup: ",
2002 lx, (cy -= 19), buttonWidth, 19,
2003 &dmd->defgrp_name, 0.0, 31.0, 0, 0,
2004 "Name of vertex group to displace"
2005 " (displace whole mesh if blank)");
2006 uiButSetCompleteFunc(but, autocomplete_vgroup, (void *)ob);
2007 uiDefIDPoinBut(block, modifier_testTexture, ID_TE, B_CHANGEDEP,
2008 "Texture: ", lx, (cy -= 19), buttonWidth, 19,
2010 "Texture to use as displacement input");
2011 uiDefButF(block, NUM, B_MODIFIER_RECALC, "Midlevel:",
2012 lx, (cy -= 19), buttonWidth, 19, &dmd->midlevel,
2014 "Material value that gives no displacement");
2015 uiDefButF(block, NUM, B_MODIFIER_RECALC, "Strength:",
2016 lx, (cy -= 19), buttonWidth, 19, &dmd->strength,
2017 -1000, 1000, 10, 0.1,
2018 "Strength of displacement");
2019 sprintf(str, "Direction%%t|Normal%%x%d|RGB -> XYZ%%x%d|"
2020 "Z%%x%d|Y%%x%d|X%%x%d",
2021 MOD_DISP_DIR_NOR, MOD_DISP_DIR_RGB_XYZ,
2022 MOD_DISP_DIR_Z, MOD_DISP_DIR_Y, MOD_DISP_DIR_X);
2023 uiDefButI(block, MENU, B_MODIFIER_RECALC, str,
2024 lx, (cy -= 19), buttonWidth, 19, &dmd->direction,
2025 0.0, 1.0, 0, 0, "Displace direction");
2026 sprintf(str, "Texture Coordinates%%t"
2027 "|Local%%x%d|Global%%x%d|Object%%x%d|UV%%x%d",
2028 MOD_DISP_MAP_LOCAL, MOD_DISP_MAP_GLOBAL,
2029 MOD_DISP_MAP_OBJECT, MOD_DISP_MAP_UV);
2030 uiDefButI(block, MENU, B_MODIFIER_RECALC, str,
2031 lx, (cy -= 19), buttonWidth, 19, &dmd->texmapping,
2033 "Texture coordinates used for displacement input");
2034 if (dmd->texmapping == MOD_DISP_MAP_UV) {
2037 CustomData *fdata = G.obedit ? &G.editMesh->fdata
2038 : &((Mesh*)ob->data)->fdata;
2039 build_uvlayer_menu_vars(fdata, &strtmp, &dmd->uvlayer_tmp,
2041 but = uiDefButI(block, MENU, B_MODIFIER_RECALC, strtmp,
2042 lx, (cy -= 19), buttonWidth, 19, &dmd->uvlayer_tmp,
2043 0.0, 1.0, 0, 0, "Set the UV layer to use");
2045 i = CustomData_get_layer_index(fdata, CD_MTFACE);
2046 uiButSetFunc(but, set_displace_uvlayer, dmd,
2049 if(dmd->texmapping == MOD_DISP_MAP_OBJECT) {
2050 uiDefIDPoinBut(block, test_obpoin_but, ID_OB, B_CHANGEDEP,
2051 "Ob: ", lx, (cy -= 19), buttonWidth, 19,
2053 "Object to get texture coordinates from");
2055 } else if (md->type==eModifierType_UVProject) {
2056 UVProjectModifierData *umd = (UVProjectModifierData *) md;
2059 CustomData *fdata = G.obedit ? &G.editMesh->fdata
2060 : &((Mesh*)ob->data)->fdata;
2061 build_uvlayer_menu_vars(fdata, &strtmp, &umd->uvlayer_tmp,
2063 but = uiDefButI(block, MENU, B_MODIFIER_RECALC, strtmp,
2064 lx, (cy -= 19), buttonWidth, 19, &umd->uvlayer_tmp,
2065 0.0, 1.0, 0, 0, "Set the UV layer to use");
2066 i = CustomData_get_layer_index(fdata, CD_MTFACE);
2067 uiButSetFunc(but, set_uvproject_uvlayer, umd, &fdata->layers[i]);
2069 uiDefButF(block, NUM, B_MODIFIER_RECALC, "AspX:",
2070 lx, (cy -= 19), buttonWidth / 2, 19, &umd->aspectx,
2072 "Horizontal Aspect Ratio");
2073 uiDefButF(block, NUM, B_MODIFIER_RECALC, "AspY:",
2074 lx + (buttonWidth / 2) + 1, cy, buttonWidth / 2, 19,
2077 "Vertical Aspect Ratio");
2078 uiDefButI(block, NUM, B_MODIFIER_RECALC, "Projectors:",
2079 lx, (cy -= 19), buttonWidth, 19, &umd->num_projectors,
2080 1, MOD_UVPROJECT_MAXPROJECTORS, 0, 0,
2081 "Number of objects to use as projectors");
2082 for(i = 0; i < umd->num_projectors; ++i) {
2083 uiDefIDPoinBut(block, test_obpoin_but, ID_OB, B_CHANGEDEP,
2084 "Ob: ", lx, (cy -= 19), buttonWidth, 19,
2085 &umd->projectors[i],
2086 "Object to use as projector");
2088 uiDefIDPoinBut(block, modifier_testImage, ID_IM, B_CHANGEDEP,
2089 "Image: ", lx, (cy -= 19), buttonWidth, 19,
2091 "Image to project (only faces with this image "
2093 uiButSetCompleteFunc(but, autocomplete_image, (void *)ob);
2094 uiDefButBitI(block, TOG, MOD_UVPROJECT_OVERRIDEIMAGE,
2095 B_MODIFIER_RECALC, "Override Image",
2096 lx, (cy -= 19), buttonWidth, 19,
2097 &umd->flags, 0, 0, 0, 0,
2098 "Override faces' current images with the "
2100 } else if (md->type==eModifierType_Decimate) {
2101 DecimateModifierData *dmd = (DecimateModifierData*) md;
2102 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");
2103 sprintf(str, "Face Count: %d", dmd->faceCount);
2104 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");
2105 } else if (md->type==eModifierType_Smooth) {
2106 SmoothModifierData *smd = (SmoothModifierData*) md;
2108 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");
2109 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");
2110 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");
2112 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)");
2113 uiDefButS(block, NUM, B_MODIFIER_RECALC, "Repeat:", lx,(cy-=19),buttonWidth, 19, &smd->repeat, 0.0, 30.0, 1, 0, "Number of smoothing iterations");
2114 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");
2115 } else if (md->type==eModifierType_Cast) {
2116 CastModifierData *cmd = (CastModifierData*) md;
2118 char casttypemenu[]="Projection Type%t|Sphere%x0|Cylinder%x1|Cuboid%x2";
2119 uiDefButS(block, MENU, B_MODIFIER_RECALC, casttypemenu, lx,(cy-=19),buttonWidth - 30,19, &cmd->type, 0, 0, 0, 0, "Projection type to apply");
2120 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");
2121 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");
2122 if (cmd->type != MOD_CAST_TYPE_CYLINDER) {
2123 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");
2125 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");
2126 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)");
2127 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)");
2128 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)");
2129 if (ob->type == OB_MESH) {
2130 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");
2132 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");
2134 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");
2136 } else if (md->type==eModifierType_Wave) {
2137 WaveModifierData *wmd = (WaveModifierData*) md;
2138 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");
2139 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");
2140 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");
2141 uiDefButBitS(block, TOG, MOD_WAVE_NORM, B_MODIFIER_RECALC, "Normals", lx,(cy-=19),buttonWidth,19, &wmd->flag, 0, 0, 0, 0, "Displace along normals");
2142 if (wmd->flag & MOD_WAVE_NORM){
2143 if (ob->type==OB_MESH) {
2144 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");
2145 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");
2146 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");
2149 uiDefBut(block, LABEL, 1, "Meshes Only", lx, (cy-=19), buttonWidth,19, NULL, 0.0, 0.0, 0, 0, "");
2152 uiBlockBeginAlign(block);
2154 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");
2156 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");
2157 uiDefButF(block, NUM, B_MODIFIER_RECALC, "Lifetime:", lx,(cy-=19),buttonWidth,19, &wmd->lifetime, -MAXFRAMEF, MAXFRAMEF, 100, 0, "Specify the lifespan of the wave");
2158 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 uiDefButF(block, NUM, B_MODIFIER_RECALC, "Falloff:", lx,(cy-=19),buttonWidth,19, &wmd->falloff, 0, 100, 100, 0, "Specify the falloff radius of the waves");
2162 uiBlockBeginAlign(block);
2163 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");
2164 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");
2165 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)");
2166 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");
2167 uiDefIDPoinBut(block, modifier_testTexture, ID_TE, B_CHANGEDEP,"Texture: ", lx, (cy -= 19), 220, 19, &wmd->texture,"Texture with which to modulate wave");
2168 sprintf(str, "Texture Coordinates%%t"
2169 "|Local%%x%d|Global%%x%d|Object%%x%d|UV%%x%d",
2170 MOD_WAV_MAP_LOCAL, MOD_WAV_MAP_GLOBAL,
2171 MOD_WAV_MAP_OBJECT, MOD_WAV_MAP_UV);
2172 uiDefButI(block, MENU, B_MODIFIER_RECALC, str,
2173 lx, (cy -= 19), 220, 19, &wmd->texmapping,
2175 "Texture coordinates used for modulation input");
2176 if (wmd->texmapping == MOD_WAV_MAP_UV) {
2179 CustomData *fdata = G.obedit ? &G.editMesh->fdata
2180 : &((Mesh*)ob->data)->fdata;
2181 build_uvlayer_menu_vars(fdata, &strtmp, &wmd->uvlayer_tmp,
2183 but = uiDefButI(block, MENU, B_MODIFIER_RECALC, strtmp,
2184 lx, (cy -= 19), 220, 19, &wmd->uvlayer_tmp,
2185 0.0, 1.0, 0, 0, "Set the UV layer to use");
2187 i = CustomData_get_layer_index(fdata, CD_MTFACE);
2188 uiButSetFunc(but, set_displace_uvlayer, wmd,
2191 if(wmd->texmapping == MOD_DISP_MAP_OBJECT) {
2192 uiDefIDPoinBut(block, test_obpoin_but, ID_OB, B_CHANGEDEP,
2193 "Ob: ", lx, (cy -= 19), 220, 19,
2195 "Object to get texture coordinates from");
2198 uiBlockBeginAlign(block);
2199 uiDefButF(block, NUMSLI, B_MODIFIER_RECALC, "Speed:", lx,(cy-=19),220,19, &wmd->speed, -2.0, 2.0, 0, 0, "Specify the wave speed");
2200 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");
2201 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");
2202 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");
2203 } else if (md->type==eModifierType_Armature) {
2204 ArmatureModifierData *amd = (ArmatureModifierData*) md;
2205 uiDefIDPoinBut(block, modifier_testArmatureObj, ID_OB, B_CHANGEDEP, "Ob: ", lx, (cy-=19), buttonWidth,19, &amd->object, "Armature object to deform with");
2207 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");
2208 uiButSetCompleteFunc(but, autocomplete_vgroup, (void *)ob);
2209 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");
2211 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");
2212 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");
2213 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");
2214 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");
2216 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");
2218 } else if (md->type==eModifierType_Hook) {
2219 HookModifierData *hmd = (HookModifierData*) md;
2220 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");
2221 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");
2222 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");
2223 if(hmd->indexar==NULL) {
2224 but=uiDefBut(block, TEX, B_MODIFIER_RECALC, "VGroup: ", lx, (cy-=19), buttonWidth,19, &hmd->name, 0.0, 31.0, 0, 0, "Vertex Group name");
2225 uiButSetCompleteFunc(but, autocomplete_vgroup, (void *)ob);
2227 uiBlockBeginAlign(block);
2228 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");
2229 uiButSetFunc(but, modifiers_clearHookOffset, ob, md);
2230 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");
2231 uiButSetFunc(but, modifiers_cursorHookCenter, ob, md);
2234 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");
2235 uiButSetFunc(but, modifiers_selectHook, ob, md);
2236 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");
2237 uiButSetFunc(but, modifiers_reassignHook, ob, md);
2239 } else if (md->type==eModifierType_Softbody) {
2240 uiDefBut(block, LABEL, 1, "See Soft Body panel.", lx, (cy-=19), buttonWidth,19, NULL, 0.0, 0.0, 0, 0, "");
2241 } else if (md->type==eModifierType_Cloth) {
2242 uiDefBut(block, LABEL, 1, "See Cloth panel.", lx, (cy-=19), buttonWidth,19, NULL, 0.0, 0.0, 0, 0, "");
2243 } else if (md->type==eModifierType_Collision) {
2244 uiDefBut(block, LABEL, 1, "See Collision panel.", lx, (cy-=19), buttonWidth,19, NULL, 0.0, 0.0, 0, 0, "");
2245 } else if (md->type==eModifierType_Boolean) {
2246 BooleanModifierData *bmd = (BooleanModifierData*) md;
2247 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");
2248 uiDefIDPoinBut(block, modifier_testMeshObj, ID_OB, B_CHANGEDEP, "Ob: ", lx, (cy-=19), buttonWidth,19, &bmd->object, "Mesh object to use for boolean operation");
2249 } else if (md->type==eModifierType_Array) {
2250 ArrayModifierData *amd = (ArrayModifierData*) md;
2251 float range = 10000;
2252 int cytop, halfwidth = (width - 5)/2 - 15;
2253 int halflx = lx + halfwidth + 10;
2255 uiBlockSetEmboss(block, UI_EMBOSSX);
2256 uiBlockEndAlign(block);
2258 /* length parameters */
2259 uiBlockBeginAlign(block);
2260 sprintf(str, "Length Fit%%t|Fixed Count%%x%d|Fixed Length%%x%d"
2261 "|Fit To Curve Length%%x%d",
2262 MOD_ARR_FIXEDCOUNT, MOD_ARR_FITLENGTH, MOD_ARR_FITCURVE);
2263 uiDefButI(block, MENU, B_MODIFIER_RECALC, str,
2264 lx, (cy-=19), buttonWidth, 19, &amd->fit_type,
2265 0.0, 1.0, 0, 0, "Array length calculation method");
2266 switch(amd->fit_type)
2268 case MOD_ARR_FIXEDCOUNT:
2269 uiDefButI(block, NUM, B_MODIFIER_RECALC, "Count:",
2270 lx, (cy -= 19), buttonWidth, 19, &amd->count,
2271 1, 1000, 0, 0, "Number of duplicates to make");
2273 case MOD_ARR_FITLENGTH:
2274 uiDefButF(block, NUM, B_MODIFIER_RECALC, "Length:",
2275 lx, (cy -= 19), buttonWidth, 19, &amd->length,
2277 "Length to fit array within");
2279 case MOD_ARR_FITCURVE:
2280 uiDefIDPoinBut(block, modifier_testCurveObj, ID_OB,
2281 B_CHANGEDEP, "Ob: ",
2282 lx, (cy -= 19), buttonWidth, 19, &amd->curve_ob,
2283 "Curve object to fit array length to");
2286 uiBlockEndAlign(block);
2288 /* offset parameters */
2291 uiBlockBeginAlign(block);
2292 uiDefButBitI(block, TOG, MOD_ARR_OFF_CONST, B_MODIFIER_RECALC,
2293 "Constant Offset", lx, (cy-=19), halfwidth, 19,
2294 &amd->offset_type, 0, 0, 0, 0,
2295 "Constant offset between duplicates "
2296 "(local coordinates)");
2297 uiDefButF(block, NUM, B_MODIFIER_RECALC, "X:",
2298 lx, (cy-=19), halfwidth, 19,
2300 -range, range, 10, 3,
2301 "Constant component for duplicate offsets "
2302 "(local coordinates)");
2303 uiDefButF(block, NUM, B_MODIFIER_RECALC, "Y:",
2304 lx, (cy-=19), halfwidth, 19,
2306 -range, range, 10, 3,
2307 "Constant component for duplicate offsets "
2308 "(local coordinates)");
2309 uiDefButF(block, NUM, B_MODIFIER_RECALC, "Z:",
2310 lx, (cy-=19), halfwidth, 19,
2312 -range, range, 10, 3,
2313 "Constant component for duplicate offsets "
2314 "(local coordinates)");
2315 uiBlockEndAlign(block);
2318 uiBlockBeginAlign(block);
2319 uiDefButBitI(block, TOG, MOD_ARR_OFF_RELATIVE, B_MODIFIER_RECALC,
2320 "Relative Offset", halflx, (cy-=19), halfwidth, 19,
2321 &amd->offset_type, 0, 0, 0, 0,
2322 "Offset between duplicates relative to object width "
2323 "(local coordinates)");
2324 uiDefButF(block, NUM, B_MODIFIER_RECALC, "X:",
2325 halflx, (cy-=19), halfwidth, 19,
2327 -range, range, 10, 3,
2328 "Component for duplicate offsets relative to object "
2329 "width (local coordinates)");
2330 uiDefButF(block, NUM, B_MODIFIER_RECALC, "Y:",
2331 halflx, (cy-=19), halfwidth, 19,
2333 -range, range, 10, 3,
2334 "Component for duplicate offsets relative to object "
2335 "width (local coordinates)");
2336 uiDefButF(block, NUM, B_MODIFIER_RECALC, "Z:",
2337 halflx, (cy-=19), halfwidth, 19,
2339 -range, range, 10, 3,
2340 "Component for duplicate offsets relative to object "
2341 "width (local coordinates)");
2342 uiBlockEndAlign(block);
2344 /* vertex merging parameters */
2348 uiBlockBeginAlign(block);
2349 uiDefButBitI(block, TOG, MOD_ARR_MERGE, B_MODIFIER_RECALC,
2351 lx, (cy-=19), halfwidth/2, 19, &amd->flags,
2353 "Merge vertices in adjacent duplicates");
2354 uiDefButBitI(block, TOG, MOD_ARR_MERGEFINAL, B_MODIFIER_RECALC,
2356 lx + halfwidth/2, cy, (halfwidth+1)/2, 19,
2359 "Merge vertices in first duplicate with vertices"
2360 " in last duplicate");
2361 uiDefButF(block, NUM, B_MODIFIER_RECALC, "Limit:",
2362 lx, (cy-=19), halfwidth, 19, &amd->merge_dist,
2364 "Limit below which to merge vertices");
2368 uiBlockBeginAlign(block);
2369 uiDefButBitI(block, TOG, MOD_ARR_OFF_OBJ, B_MODIFIER_RECALC,
2370 "Object Offset", halflx, (cy -= 19), halfwidth, 19,
2371 &amd->offset_type, 0, 0, 0, 0,
2372 "Add an object transformation to the total offset");
2373 uiDefIDPoinBut(block, test_obpoin_but, ID_OB, B_CHANGEDEP,
2374 "Ob: ", halflx, (cy -= 19), halfwidth, 19,
2376 "Object from which to take offset transformation");
2377 uiBlockEndAlign(block);
2380 but = uiDefIDPoinBut(block, test_meshobpoin_but, ID_OB,
2381 B_CHANGEDEP, "Start cap: ",
2382 lx, (cy -= 19), halfwidth, 19,
2384 "Mesh object to use as start cap");
2385 uiButSetCompleteFunc(but, autocomplete_meshob, (void *)ob);
2386 but = uiDefIDPoinBut(block, test_meshobpoin_but, ID_OB,
2387 B_CHANGEDEP, "End cap: ",
2388 halflx, cy, halfwidth, 19,
2390 "Mesh object to use as end cap");
2391 uiButSetCompleteFunc(but, autocomplete_meshob, (void *)ob);
2392 } else if (md->type==eModifierType_MeshDeform) {
2393 MeshDeformModifierData *mmd = (MeshDeformModifierData*) md;
2395 uiBlockBeginAlign(block);
2396 uiDefIDPoinBut(block, test_meshobpoin_but, ID_OB, B_CHANGEDEP, "Ob: ", lx, (cy-=19), buttonWidth,19, &mmd->object, "Mesh object to be use as cage");
2397 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");
2398 uiButSetCompleteFunc(but, autocomplete_vgroup, (void *)ob);
2399 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");
2401 uiBlockBeginAlign(block);
2403 but= uiDefBut(block, BUT, B_MODIFIER_RECALC, "Unbind", lx,(cy-=24), buttonWidth,19, 0, 0, 0, 0, 0, "Unbind mesh from cage");
2404 uiButSetFunc(but,modifiers_bindMeshDeform,ob,md);
2407 but= uiDefBut(block, BUT, B_MODIFIER_RECALC, "Bind", lx,(cy-=24), buttonWidth,19, 0, 0, 0, 0, 0, "Bind mesh to cage");
2408 uiButSetFunc(but,modifiers_bindMeshDeform,ob,md);
2409 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");
2410 uiDefButBitS(block, TOG, MOD_MDEF_DYNAMIC_BIND, B_MODIFIER_RECALC, "Dynamic", lx+(buttonWidth+1)/2 + 20, (cy-=19), buttonWidth/2 - 20,19, &mmd->flag, 0.0, 31.0, 0, 0, "Recompute binding dynamically on top of other deformers like Shape Keys (slower and more memory consuming!)");
2412 uiBlockEndAlign(block);
2413 } else if (md->type==eModifierType_ParticleSystem) {
2414 uiDefBut(block, LABEL, 1, "See Particle buttons.", lx, (cy-=19), buttonWidth,19, NULL, 0.0, 0.0, 0, 0, "");
2415 } else if (md->type==eModifierType_ParticleInstance) {
2416 ParticleInstanceModifierData *pimd = (ParticleInstanceModifierData*) md;
2417 uiDefIDPoinBut(block, test_obpoin_but, ID_OB, B_CHANGEDEP, "Ob: ", lx, (cy -= 19), buttonWidth, 19, &pimd->ob, "Object that has the particlesystem");
2418 uiDefButS(block, NUM, B_MODIFIER_RECALC, "PSYS:", lx, (cy -= 19), buttonWidth, 19, &pimd->psys, 1, 10, 10, 3, "Particlesystem number in the object");
2419 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");
2420 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");
2421 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");
2422 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");
2423 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");
2424 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");
2425 } else if (md->type==eModifierType_Explode) {
2426 ExplodeModifierData *emd = (ExplodeModifierData*) md;
2428 char *menustr= get_vertexgroup_menustr(ob);
2429 int defCount=BLI_countlist(&ob->defbase);
2430 if(defCount==0) emd->vgroup=0;
2431 uiBlockBeginAlign(block);
2432 but=uiDefButS(block, MENU, B_MODIFIER_RECALC, menustr, lx, (cy-=19), buttonWidth-20,19, &emd->vgroup, 0, defCount, 0, 0, "Protect this vertex group");
2433 uiButSetFunc(but,modifiers_explodeFacepa,emd,0);
2436 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");
2437 uiButSetFunc(but, modifiers_explodeDelVg, (void *)emd, (void *)NULL);
2440 but=uiDefButF(block, NUMSLI, B_MODIFIER_RECALC, "", lx, (cy-=19), buttonWidth,19, &emd->protect, 0.0f, 1.0f, 0, 0, "Clean vertex group edges");
2441 uiButSetFunc(but,modifiers_explodeFacepa,emd,0);
2443 but=uiDefBut(block, BUT, B_MODIFIER_RECALC, "Refresh", lx, (cy-=19), buttonWidth/2,19, 0, 0, 0, 0, 0, "Recalculate faces assigned to particles");
2444 uiButSetFunc(but,modifiers_explodeFacepa,emd,0);
2446 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");
2447 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");
2448 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");
2449 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");
2450 uiBlockEndAlign(block);
2453 uiBlockEndAlign(block);
2461 uiBlockSetCol(block, color);
2462 /* roundbox 4 free variables: corner-rounding, nop, roundbox type, shade */
2463 uiDefBut(block, ROUNDBOX, 0, "", x-10, y, width, 20, NULL, 5.0, 0.0, 15, 40, "");
2464 uiBlockSetCol(block, TH_AUTO);
2466 uiDefIconBut(block,LABEL,B_NOP,ICON_ERROR, x-9, y,19,19, 0,0,0,0,0, "");
2467 uiDefBut(block, LABEL, B_NOP, md->error, x+5, y, width-15, 19, NULL, 0.0, 0.0, 0.0, 0.0, "");
2480 static void editing_panel_modifiers(Object *ob)
2485 int xco, yco, i, lastCageIndex, cageIndex = modifiers_getCageIndex(ob, &lastCageIndex);
2487 block= uiNewBlock(&curarea->uiblocks, "editing_panel_modifiers", UI_EMBOSS, UI_HELV, curarea->win);
2488 if( uiNewPanel(curarea, block, "Modifiers", "Editing", 640, 0, 318, 204)==0) return;
2490 uiSetButLock(object_data_is_libdata(ob), ERROR_LIBDATA_MESSAGE);
2491 uiNewPanelHeight(block, 204);
2493 uiDefBlockBut(block, modifiers_add_menu, ob, "Add Modifier", 0, 190, 130, 20, "Add a new modifier");
2495 sprintf(str, "To: %s", ob->id.name+2);
2496 uiDefBut(block, LABEL, 1, str, 140, 190, 160, 20, NULL, 0.0, 0.0, 0, 0, "Object whose modifier stack is being edited");
2501 md = modifiers_getVirtualModifierList(ob);
2503 for (i=0; md; i++, md=md->next) {
2504 draw_modifier(block, ob, md, &xco, &yco, i, cageIndex, lastCageIndex);
2505 if (md->mode&eModifierMode_Virtual) i--;
2508 if(yco < 0) uiNewPanelHeight(block, 204-yco);
2511 static char *make_key_menu(Key *key, int startindex)
2515 char *str, item[64];
2517 for (kb = key->block.first; kb; kb=kb->next, index++);
2518 str= MEM_mallocN(index*40, "key string");
2522 for (kb = key->block.first; kb; kb=kb->next, index++) {
2523 sprintf (item, "|%s%%x%d", kb->name, index);
2530 static void editing_panel_shapes(Object *ob)
2538 block= uiNewBlock(&curarea->uiblocks, "editing_panel_shapes", UI_EMBOSS, UI_HELV, curarea->win);
2539 uiNewPanelTabbed("Modifiers", "Editing");
2540 if( uiNewPanel(curarea, block, "Shapes", "Editing", 640, 0, 318, 204)==0) return;
2542 /* Todo check data is library here */
2543 uiSetButLock(object_data_is_libdata(ob), ERROR_LIBDATA_MESSAGE);
2545 uiDefBut(block, BUT, B_ADDKEY, "Add Shape Key" , 10, 180, 150, 20, NULL, 0.0, 0.0, 0, 0, "Add new Shape Key");
2547 key= ob_get_key(ob);
2549 /* label aligns add button */
2550 uiDefBut(block, LABEL, 0, "", 170, 180,140,20, NULL, 0, 0, 0, 0, "");
2554 uiDefButS(block, TOG, B_RELKEY, "Relative", 170, 180,140,20, &key->type, 0, 0, 0, 0, "Makes Shape Keys relative");
2556 kb= BLI_findlink(&key->block, ob->shapenr-1);
2559 kb= key->block.first;
2562 uiBlockBeginAlign(block);
2563 if(ob->shapeflag & OB_SHAPE_LOCK) icon= ICON_PIN_HLT; else icon= ICON_PIN_DEHLT;
2564 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");
2565 if(kb->flag & KEYBLOCK_MUTE) icon= ICON_MUTE_IPO_ON; else icon = ICON_MUTE_IPO_OFF;
2566 uiDefIconButBitS(block, TOG, KEYBLOCK_MUTE, B_MODIFIER_RECALC, icon, 35,150,20,20, &kb->flag, 0, 0, 0, 0, "Mute the current Shape");
2567 uiSetButLock(G.obedit==ob, "Unable to perform in EditMode");
2568 uiDefIconBut(block, BUT, B_PREVKEY, ICON_TRIA_LEFT, 55,150,20,20, NULL, 0, 0, 0, 0, "Previous Shape Key");
2569 strp= make_key_menu(key, 1);
2570 uiDefButS(block, MENU, B_SETKEY, strp, 75,150,20,20, &ob->shapenr, 0, 0, 0, 0, "Browse existing choices");
2573 uiDefIconBut(block, BUT, B_NEXTKEY, ICON_TRIA_RIGHT, 95,150,20,20, NULL, 0, 0, 0, 0, "Next Shape Key");
2575 uiDefBut(block, TEX, B_NAMEKEY, "", 115, 150, 170, 20, kb->name, 0.0, 31.0, 0, 0, "Current Shape Key name");
2576 uiDefIconBut(block, BUT, B_DELKEY, ICON_X, 285,150,25,20, 0, 0, 0, 0, 0, "Deletes current Shape Key");
2577 uiBlockEndAlign(block);
2579 if(key->type && (ob->shapeflag & OB_SHAPE_LOCK)==0 && ob->shapenr!=1) {
2580 uiBlockBeginAlign(block);
2581 make_rvk_slider(block, ob, ob->shapenr-1, 10, 120, 150, 20, "Key value, when used it inserts an animation curve point");
2582 uiDefButF(block, NUM, B_REDR, "Min ", 160,120, 75, 20, &kb->slidermin, -10.0, 10.0, 100, 1, "Minumum for slider");
2583 uiDefButF(block, NUM, B_REDR, "Max ", 235,120, 75, 20, &kb->slidermax, -10.0, 10.0, 100, 1, "Maximum for slider");
2584 uiBlockEndAlign(block);
2586 if(key->type && ob->shapenr!=1) {
2587 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");
2589 strp= make_key_menu(key, 0);
2590 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");
2595 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");
2599 /* *************************** FONT ******************************** */
2601 static short give_vfontnr(VFont *vfont)
2606 vf= G.main->vfont.first;
2608 if(vf==vfont) return nr;
2615 static VFont *give_vfontpointer(int nr) /* nr= button */
2620 vf= G.main->vfont.first;
2622 if(tel==nr) return vf;
2626 return G.main->vfont.first;
2629 VFont *exist_vfont(char *str)
2633 vf= G.main->vfont.first;
2635 if(strcmp(vf->name, str)==0) return vf;
2641 static char *give_vfontbutstr(void)
2645 char *str, di[FILE_MAXDIR], fi[FILE_MAXFILE];
2647 vf= G.main->vfont.first;
2649 strcpy(di, vf->name);
2650 BLI_splitdirstring(di, fi);
2655 str= MEM_callocN(len+21, "vfontbutstr");
2656 strcpy(str, "FONTS %t");
2657 vf= G.main->vfont.first;
2660 if(vf->id.us==0) strcat(str, "|0 ");
2661 else strcat(str, "| ");
2663 strcpy(di, vf->name);
2664 BLI_splitdirstring(di, fi);
2672 static void load_buts_vfont(char *name)
2677 if(OBACT && OBACT->type==OB_FONT) cu= OBACT->data;
2680 vf= exist_vfont(name);
2682 vf= load_vfont(name);
2685 else id_us_plus((ID *)vf);
2687 switch(cu->curinfo.flag & CU_STYLE) {
2689 if(cu->vfontb) cu->vfontb->id.us--;
2693 if(cu->vfonti) cu->vfonti->id.us--;
2696 case (CU_BOLD|CU_ITALIC):
2697 if(cu->vfontbi) cu->vfontbi->id.us--;
2701 if(cu->vfont) cu->vfont->id.us--;
2706 DAG_object_flush_update(G.scene, OBACT, OB_RECALC_DATA);
2707 BIF_undo_push("Load vector font");
2708 allqueue(REDRAWVIEW3D, 0);
2709 allqueue(REDRAWBUTSEDIT, 0);
2712 static void set_unicode_text_fs(char *file)
2714 if (file) paste_unicodeText(file);
2717 void do_fontbuts(unsigned short event)
2733 DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA);
2734 allqueue(REDRAWVIEW3D, 0);
2741 case B_STYLETOSELU: style = CU_UNDERLINE; break;
2742 case B_STYLETOSELB: style = CU_BOLD; break;
2743 case B_STYLETOSELI: style = CU_ITALIC; break;
2745 if (style_to_sel(style, ((Curve*)ob->data)->curinfo.flag & style)) {
2746 text_to_curve(ob, 0);
2747 makeDispListCurveTypes(ob, 0);
2748 allqueue(REDRAWVIEW3D, 0);
2750 allqueue(REDRAWBUTSEDIT, 0);
2755 DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA);
2756 allqueue(REDRAWVIEW3D, 0);
2761 if (cu->totbox < 256) {
2762 for (i = cu->totbox; i>cu->actbox; i--) cu->tb[i]= cu->tb[i-1];
2763 cu->tb[cu->actbox]= cu->tb[cu->actbox-1];
2766 allqueue(REDRAWBUTSEDIT, 0);
2767 allqueue(REDRAWVIEW3D, 0);
2768 text_to_curve(ob, 0);
2769 makeDispListCurveTypes(ob, 0);
2772 error("Do you really need that many text frames?");
2777 if (cu->totbox > 1) {
2778 for (i = cu->actbox-1; i < cu->totbox; i++) cu->tb[i]= cu->tb[i+1];
2781 allqueue(REDRAWBUTSEDIT, 0);
2782 allqueue(REDRAWVIEW3D, 0);
2783 text_to_curve(ob, 0);
2784 makeDispListCurveTypes(ob, 0);
2791 vf= give_vfontpointer(G.buts->texnr);
2792 if(vf && vf->id.prev!=vf->id.next) strcpy(str, vf->name);
2793 else strcpy(str, U.fontdir);
2795 sa= closest_bigger_area();
2796 areawinset(sa->win);
2798 activate_fileselect(FILE_LOADFONT, "SELECT FONT", str, load_buts_vfont);
2804 if(cu && cu->vfont) {
2805 if (cu->vfont->packedfile) {
2806 if (G.fileflags & G_AUTOPACK) {
2807 if (okee("Disable AutoPack ?")) {
2808 G.fileflags &= ~G_AUTOPACK;
2812 if ((G.fileflags & G_AUTOPACK) == 0) {
2813 if (unpackVFont(cu->vfont, PF_ASK) == RET_OK) {
2814 DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA);
2815 allqueue(REDRAWVIEW3D, 0);
2819 cu->vfont->packedfile = newPackedFile(cu->vfont->name);
2823 allqueue(REDRAWHEADERS, 0);
2824 allqueue(REDRAWBUTSEDIT, 0);
2828 if (!G.obedit) { error("Only in editmode!"); return; }
2829 if (G.obedit->type != OB_FONT) return;
2830 activate_fileselect(FILE_SPECIAL, "Open Text File", G.sce, load_3dtext_fs);
2834 if (!G.obedit) { error("Only in editmode!"); return; }
2835 if (G.obedit->type != OB_FONT) return;
2844 vf= give_vfontpointer(G.buts->texnr);
2846 id_us_plus((ID *)vf);
2848 switch(cu->curinfo.flag & CU_STYLE) {