4 * ***** BEGIN GPL/BL DUAL 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. The Blender
10 * Foundation also sells licenses for use in proprietary software under
11 * the Blender License. See http://www.blender.org/BL/ for information
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software Foundation,
21 * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
23 * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
24 * All rights reserved.
26 * The Original Code is: all of this file.
28 * Contributor(s): none yet.
30 * ***** END GPL/BL DUAL LICENSE BLOCK *****
40 #define snprintf _snprintf
44 #include "MEM_guardedalloc.h"
45 #include "DNA_screen_types.h"
46 #include "DNA_space_types.h"
47 #include "DNA_scene_types.h"
49 #include "DNA_action_types.h"
50 #include "DNA_armature_types.h"
51 #include "DNA_brush_types.h"
52 #include "DNA_camera_types.h"
53 #include "DNA_color_types.h"
54 #include "DNA_constraint_types.h"
55 #include "DNA_curve_types.h"
56 #include "DNA_effect_types.h"
57 #include "DNA_group_types.h"
58 #include "DNA_key_types.h"
59 #include "DNA_lamp_types.h"
60 #include "DNA_lattice_types.h"
61 #include "DNA_material_types.h"
62 #include "DNA_meta_types.h"
63 #include "DNA_mesh_types.h"
64 #include "DNA_meshdata_types.h"
65 #include "DNA_modifier_types.h"
66 #include "DNA_nla_types.h"
67 #include "DNA_object_types.h"
68 #include "DNA_object_force.h"
69 #include "DNA_particle_types.h"
70 #include "DNA_radio_types.h"
71 #include "DNA_screen_types.h"
72 #include "DNA_texture_types.h"
73 #include "DNA_userdef_types.h"
74 #include "DNA_vfont_types.h"
75 #include "DNA_view3d_types.h"
76 #include "DNA_world_types.h"
77 #include "DNA_packedFile_types.h"
79 #include "BKE_blender.h"
80 #include "BKE_brush.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_packedFile.h"
93 #include "BKE_particle.h"
94 #include "BKE_scene.h"
96 #include "BLI_blenlib.h"
97 #include "BLI_arithb.h"
98 #include "BLI_vfontdata.h"
99 #include "BLI_editVert.h"
100 #include "BLI_dynstr.h"
102 #include "BSE_filesel.h"
105 #include "BIF_editarmature.h"
106 #include "BIF_editconstraint.h"
107 #include "BIF_editdeform.h"
108 #include "BIF_editfont.h"
109 #include "BIF_editkey.h"
110 #include "BIF_editmesh.h"
111 #include "BIF_editparticle.h"
112 #include "BIF_imasel.h"
113 #include "BIF_interface.h"
114 #include "BIF_meshtools.h"
115 #include "BIF_mywindow.h"
116 #include "BIF_poseobject.h"
117 #include "BIF_renderwin.h"
118 #include "BIF_resources.h"
119 #include "BIF_retopo.h"
120 #include "BIF_screen.h"
121 #include "BIF_scrarea.h"
122 #include "BIF_space.h"
123 #include "BIF_toets.h"
124 #include "BIF_toolbox.h"
125 #include "BIF_previewrender.h"
126 #include "BIF_butspace.h"
129 #include "BIF_verse.h"
132 #include "mydevice.h"
135 #include "BKE_action.h"
136 #include "BKE_anim.h"
137 #include "BKE_armature.h"
138 #include "BKE_constraint.h"
139 #include "BKE_curve.h"
140 #include "BKE_displist.h"
141 #include "BKE_DerivedMesh.h"
142 #include "BKE_effect.h"
143 #include "BKE_font.h"
144 #include "BKE_icons.h"
145 #include "BKE_image.h"
147 #include "BKE_lattice.h"
148 #include "BKE_material.h"
149 #include "BKE_mball.h"
150 #include "BKE_mesh.h"
151 #include "BKE_object.h"
152 #include "BKE_texture.h"
153 #include "BKE_utildefines.h"
155 #include "BIF_poseobject.h"
157 #include "BDR_drawobject.h"
158 #include "BDR_editcurve.h"
159 #include "BDR_editface.h"
160 #include "BDR_editobject.h"
161 #include "BDR_sculptmode.h"
162 #include "BDR_vpaint.h"
163 #include "BDR_unwrapper.h"
165 #include "BSE_drawview.h"
166 #include "BSE_editipo.h"
167 #include "BSE_edit.h"
168 #include "BSE_filesel.h"
169 #include "BSE_headerbuttons.h"
170 #include "BSE_trans_types.h"
171 #include "BSE_view.h"
172 #include "BSE_seqaudio.h"
174 #include "RE_render_ext.h" // make_sticky
176 #include "butspace.h" // own module
177 #include "multires.h"
179 static float editbutweight= 1.0;
180 float editbutvweight= 1;
181 static int actmcol= 0, acttface= 0, acttface_rnd = 0, actmcol_rnd = 0;
183 extern ListBase editNurb;
185 /* *************************** Unicode Character Groups ****************** */
186 unicodect uctabname[125] = {
187 {"All", "All", 0x0000, 0xffff},
188 {"Basic Latin", "Basic Latin", 0x0000, 0x007f},
189 {"Latin 1 Supp", "Latin-1 Supplement", 0x0080, 0x00ff},
191 {"Latin Ext. A.", "Latin Extended-A", 0x0100, 0x017F},
192 {"Latin Ext. B.", "Latin Extended-B", 0x0180,0x024F},
193 {"Latin Ext. Add.", "Latin Extended Additional", 0x1e00, 0x1eff},
195 {"IPA Ext", "IPA Extensions", 0x0250, 0x02AF},
196 {"Spacing Mod.", "Spacing Modifier Letters", 0x02b0, 0x02ff},
198 {"Comb. Dia.", "Combining Diacritical Marks", 0x0300, 0x036F},
199 {"Greek, Coptic", "Greek and Coptic", 0x0370, 0x03ff},
200 {"Greek Ext.", "Greek Extended", 0x1f00, 0x1fff},
202 {"Cyrillic", "Cyrillic", 0x0400, 0x04ff},
203 {"Cyrillic Supp.", "Cyrillic Supplementary", 0x0500, 0x052f},
205 {"Armenian", "Armenian", 0x0530, 0x058f},
206 {"Hebrew", "Hebrew", 0x0590, 0x05ff},
209 {"Arabic", "Arabic", 0x0600, 0x06ff},
210 {"Syriac", "Syriac", 0x0700, 0x074f},
212 {"Thaana", "Thaana", 0x0780, 0x07bf},
213 {"Devanagari", "Devanagari", 0x0900, 0x097f},
215 {"Bengali", "Bengali", 0x0980, 0x09ff},
216 {"Gurmukhi", "Gurmukhi", 0x0a00, 0x0a7f},
218 {"Gujarati", "Gujarati", 0x0a80, 0x0aff},
219 {"Oriya", "Oriya", 0x0b00, 0x0b7f},
221 {"Tamil", "Tamil", 0x0b80, 0x0bff},
222 {"Tegulu", "Tegulu", 0x0c00, 0x0c7f},
224 {"Kannada", "Kannada", 0x0c80, 0x0cff},
225 {"Malayalam", "Malayalam", 0x0d00, 0x0d7f},
227 {"Sinhala", "Sinhala", 0x0d80, 0x0dff},
228 {"Thai", "Thai", 0x0e00, 0x0e7f},
230 {"Lao", "Lao", 0x0e80, 0x0eff},
231 {"Tibetan", "Tibetan", 0x0f00, 0x0fff},
233 {"Myanmar", "Myanmar", 0x1000, 0x109f},
234 {"Georgian", "Georgian", 0x10a0, 0x10ff},
236 {"Ethiopic", "Ethiopic", 0x1200, 0x137f},
238 {"Cherokee", "Cherokee", 0x13a0, 0x13ff},
239 {"Unif. Canadian", "Unified Canadian Aboriginal Syllabics", 0x1400, 0x167f},
241 {"Ogham", "Ogham", 0x1680, 0x169f},
242 {"Runic", "Runic", 0x16a0, 0x16ff},
244 {"Tagalog", "Tagalog", 0x1700, 0x171f},
245 {"Hanunoo", "Hanunoo", 0x1720, 0x173f},
247 {"Buhid", "Buhid", 0x1740, 0x175f},
248 {"Tagbanwa", "Tagbanwa", 0x1760, 0x177f},
250 {"Khmer", "Khmer", 0x1780, 0x17ff},
251 {"Khmer Symb", "Khmer Symbols", 0x19e0, 0x19ff},
253 {"Mongolian", "Mongolian", 0x1800, 0x18af},
255 {"Limbu", "Limbu", 0x1900, 0x194f},
256 {"Tai Le", "Tai Le", 0x1950, 0x197f},
258 {"Phon. Ext.", "Phonetic Extensions", 0x1d00, 0x1d7f},
261 {"Gen. Punct.", "General Punctutation", 0x2000, 0x206f},
262 {"Super, Sub", "Superscripts and Subscripts", 0x2070, 0x209f},
264 {"Curr. Symb.", "Currency Symbols", 0x20a0, 0x20cf},
265 {"Comb. Diacrit.", "Combining Diacritical Marks for Symbols", 0x20d0, 0x20ff},
267 {"Letter Symb", "Letterlike Symbols", 0x2100, 0x214f},
268 {"Numb. Forms", "Number Forms", 0x2150, 0x218f},
270 {"Arrows", "Arrows", 0x2190, 0x21ff},
271 {"Math Oper.", "Mathematical Operators", 0x2200, 0x22ff},
273 {"Misc. Tech.", "Miscellaneous Technical", 0x2300, 0x23ff},
274 {"Ctrl. Pict.", "Control Pictures", 0x2400, 0x243f},
276 {"OCR", "Optical Character Recognition", 0x2440, 0x245f},
277 {"Enc. Alpha", "Enclosed Alphanumerics", 0x2460, 0x24ff},
279 {"Bow Drawing", "Box Drawing", 0x2500, 0x257f},
280 {"BLock Elem.", "Block Elements", 0x2580, 0x259f},
282 {"Geom. Shapes", "Geometric Shapes", 0x25a0, 0x25ff},
283 {"Misc. Symb.", "Miscellaneous Symbols", 0x2600, 0x26ff},
285 {"Dingbats", "Dingbats", 0x2700, 0x27bf},
286 {"Misc. Math A", "Miscellaneous Mathematical Symbols-A", 0x27c0, 0x27ef},
288 {"Supp. Arrows-A", "Supplemental Arrows-A", 0x27f0, 0x27ff},
289 {"Braille Pat.", "Braille Patterns", 0x2800, 0x28ff},
291 {"Supp. Arrows-B", "Supplemental Arrows-B", 0x2900, 0x297f},
292 {"Misc. Math B", "Miscellaneous Mathematical Symbols-B", 0x2980, 0x29ff},
294 {"Supp. Math Op.", "Supplemental Mathematical Operators", 0x2a00, 0x2aff},
295 {"Misc. Symb.", "Miscellaneous Symbols and Arrows", 0x2b00, 0x2bff},
297 {"Kangxi Rad.", "Kangxi Radicals", 0x2f00, 0x2fdf},
299 {"Ideographic", "Ideographic Description Characters", 0x2ff0, 0x2fff},
301 {"Hiragana", "Hiragana", 0x3040, 0x309f},
302 {"Katakana", "Katakana", 0x30a0, 0x30ff},
303 {"Katakana Ext.", "Katakana Phonetic Extensions", 0x31f0, 0x31ff},
305 {"Bopomofo", "Bopomofo", 0x3100, 0x312f},
306 {"Bopomofo Ext.", "Bopomofo Extended", 0x31a0, 0x31bf},
308 {"Hangul", "Hangul Jamo", 0x1100, 0x11ff},
309 {"Hangul Comp.", "Hangul Compatibility Jamo", 0x3130, 0x318f},
310 {"Hangul Syll.", "Hangul Syllables", 0xac00, 0xd7af},
312 {"Kanbun", "Kanbun", 0x3190, 0x319f},
316 {"Yijing Hex.", "Yijing Hexagram Symbols", 0x4dc0, 0x4dff},
318 {"Yi Syllables", "Yi Syllables", 0xa000, 0xa48f},
319 {"Yi Radicals", "Yi Radicals", 0xa490, 0xa4cf},
321 {"High Surr.", "High Surrogate Area", 0xd800, 0xdbff},
323 {"Low Surr.", "Low Surrogates", 0xdc00, 0xdfff},
324 {"Priv. Use Area", "Private Use Area", 0xe000, 0xf8ff},
326 {"CJK Rad. Supp.", "CJK Radicals Supplement", 0x2e80, 0x2eff},
327 {"CJK Ideographs", "CJK Unified Ideographs", 0x4e00, 0x9faf},
328 {"CJK Ideog. Ext. A", "CJK Unified Ideographs Extension A", 0x3400, 0x4dbf},
329 {"CJK Ideog. Ext. B", "CJK Unified Ideographs Extension B", 0x20000, 0x2a6df},
330 {"CJK Symbols.", "CJK Symbols and Punctuation", 0x3000, 0x303f},
331 {"Enclosed CJK", "Enclosed CJK Letters and Months", 0x3200, 0x32ff},
332 {"CJK Comp.", "CJK Compatibility", 0x3300, 0x33ff},
333 {"CJK Comp. Ideog.", "CJK Compatibility Ideographs", 0xf900, 0xfaff},
334 {"CJK Comp. Forms", "CJK Compatibility Forms", 0xfe30, 0xfe4f},
335 {"CJK Comp. Supp.", "CJK Compatibility Ideographs Supplement", 0x2f800, 0x2fa1f},
337 {"Alpha. Pres. Forms", "Alphabetic Presentation Forms", 0xfb00, 0xfb4f},
339 {"Arabic Pres. A", "Arabic Presentation Forms-A", 0xfb50, 0xfdff},
340 {"Arabic Pres. B", "Arabic Presentation Forms-B", 0xfe70, 0xfeff},
342 {"Var. Sel.", "Variation Selectors", 0xfe00, 0xfe0f},
344 {"Comb. Half", "Combining Half Marks", 0xfe20, 0xfe2f},
346 {"Sml. From Var.", "Small Form Variants", 0xfe50, 0xfe6f},
348 {"Half, Full Forms", "Halfwidth and Fullwidth Forms", 0xff00, 0xffef},
349 {"Specials", "Specials", 0xfff0, 0xffff},
351 {"Lin. B Syllab.", "Linear B Syllabary", 0x10000, 0x1007f},
352 {"Lin. B Idog.", "Linear B Ideograms", 0x10080, 0x100ff},
354 {"Aegean Num.", "Aegean Numbers", 0x10100, 0x1013f},
355 {"Old Italic", "Old Italic", 0x10300, 0x1032f},
357 {"Gothic", "Gothic", 0x10330, 0x1034f},
358 {"Ugaritic", "Ugaritic", 0x10380, 0x1039f},
360 {"Deseret", "Deseret", 0x10400, 0x1044f},
361 {"Shavian", "Shavian", 0x10450, 0x1047f},
363 {"Osmanya", "Osmanya", 0x10480, 0x104af},
364 {"Cypriot Syll", "Cypriot Syllabary", 0x10800, 0x1083f},
366 {"Bysantine Mus.", "Bysantine Musical Symbols", 0x1d000, 0x1d0ff},
367 {"Music Symb.", "Musical Symbols", 0x1d100, 0x1d1ff},
369 {"Tai Xuan Symb", "Tai Xuan Jing Symbols", 0x1d300, 0x1d35f},
370 {"Math. Alpha Symb.", "Mathematical Alpanumeric Symbols", 0x1d400, 0x1d7ff},
373 {"Tags", "Tags", 0xe0000, 0xe007f},
374 {"Var. Supp", "Variation Selectors Supplement", 0xe0100, 0xe01ef},
376 {"Supp. Priv. A", "Supplementary Private Use Area-A", 0xf0000, 0xffffd},
377 {"Supp. Priv. B", "Supplementary Private Use Area-B", 0x100000, 0x10fffd}
381 /* *************************** static functions prototypes ****************** */
382 VFont *exist_vfont(char *str);
384 /* *************** */
386 void do_common_editbuts(unsigned short event) // old name, is a mix of object and editing events....
388 EditMesh *em = G.editMesh;
398 int a, bit, index= -1;
403 if(G.obedit && G.obedit->actcol>0) {
404 if(G.obedit->type == OB_MESH) {
405 for(efa= em->faces.first; efa; efa= efa->next) {
406 if(efa->f & SELECT) {
407 if(index== -1) index= efa->mat_nr;
408 else if(index!=efa->mat_nr) {
409 error("Mixed colors");
415 else if ELEM(G.obedit->type, OB_CURVE, OB_SURF) {
418 if( isNurbsel(nu) ) {
419 if(index== -1) index= nu->mat_nr;
420 else if(index!=nu->mat_nr) {
421 error("Mixed colors");
429 G.obedit->actcol= index+1;
430 scrarea_queue_winredraw(curarea);
435 new_material_to_objectdata(ob);
436 scrarea_queue_winredraw(curarea);
437 BIF_undo_push("New material");
438 allqueue(REDRAWBUTSSHADING, 0);
439 allqueue(REDRAWVIEW3D_Z, 0);
440 allqueue(REDRAWOOPS, 0);
443 delete_material_index();
444 scrarea_queue_winredraw(curarea);
445 BIF_undo_push("Delete material index");
446 allqueue(REDRAWBUTSSHADING, 0);
447 allqueue(REDRAWVIEW3D_Z, 0);
448 allqueue(REDRAWOOPS, 0);
451 if(G.obedit && G.obedit->actcol>0) {
452 if(G.obedit->type == OB_MESH) {
453 efa= em->faces.first;
456 efa->mat_nr= G.obedit->actcol-1;
460 else if ELEM(G.obedit->type, OB_CURVE, OB_SURF) {
464 nu->mat_nr= nu->charidx= G.obedit->actcol-1;
468 else if (G.obedit->type == OB_FONT) {
470 allqueue(REDRAWVIEW3D, 0);
473 allqueue(REDRAWVIEW3D_Z, 0);
474 DAG_object_flush_update(G.scene, G.obedit, OB_RECALC_DATA);
475 shade_buttons_change_3d();
476 BIF_undo_push("Assign material index");
479 case B_MATASS_BROWSE:
480 /* if slot available, make that index active, and assign */
481 /* else, make new slot, and assign */
482 ma= BLI_findlink(&G.main->mat, G.buts->menunr-1);
484 ob->actcol= find_material_index(ob, ma);
486 assign_material(ob, ma, ob->totcol+1);
487 ob->actcol= ob->totcol;
491 do_common_editbuts(B_MATNEW);
493 do_common_editbuts(B_MATASS);
497 ma= give_current_material(ob, ob->actcol);
498 BKE_icon_changed(BKE_icon_getid((ID *)ma));
499 allqueue(REDRAWVIEW3D, 0);
500 allqueue(REDRAWBUTSEDIT, 0);
506 if(G.obedit->type == OB_MESH) {
507 if (event==B_MATSEL) {
508 editmesh_select_by_material(G.obedit->actcol-1);
510 editmesh_deselect_by_material(G.obedit->actcol-1);
512 allqueue(REDRAWVIEW3D, 0);
514 else if ELEM(G.obedit->type, OB_CURVE, OB_SURF) {
517 if(nu->mat_nr==G.obedit->actcol-1) {
523 if(event==B_MATSEL) {
538 a= nu->pntsu*nu->pntsv;
542 if(event==B_MATSEL) bp->f1 |= SELECT;
543 else bp->f1 &= ~SELECT;
551 BIF_undo_push("Select material index");
552 allqueue(REDRAWVIEW3D, 0);
559 if(G.obedit->type == OB_MESH) hide_mesh(0);
560 else if ELEM(G.obedit->type, OB_CURVE, OB_SURF) hideNurb(0);
565 if(G.obedit->type == OB_MESH) reveal_mesh();
566 else if ELEM(G.obedit->type, OB_CURVE, OB_SURF) revealNurb();
568 else if(FACESEL_PAINT_TEST) reveal_tface();
573 if(G.obedit->type == OB_MESH) selectswap_mesh();
574 else if ELEM(G.obedit->type, OB_CURVE, OB_SURF) selectswapNurb();
578 if(ob && G.obedit==0) {
579 if(ELEM3(ob->type, OB_CURVE, OB_SURF, OB_FONT)) tex_space_curve(ob->data);
588 case B_DOCENTERCURSOR:
594 if(G.obedit->type == OB_MESH) {
595 mesh_set_smooth_faces((event==B_SETSMOOTH));
598 nurb_set_smooth((event==B_SETSMOOTH));
604 if(TESTBASELIB(base)) {
605 if(base->object->type==OB_MESH) {
606 mesh_set_smooth_flag(base->object, (event==B_SETSMOOTH));
608 else if ELEM(base->object->type, OB_SURF, OB_CURVE) {
609 cu= base->object->data;
612 if(event==B_SETSMOOTH) nu->flag |= ME_SMOOTH;
613 else nu->flag &= ~ME_SMOOTH;
616 makeDispListCurveTypes(base->object, 0);
621 allqueue(REDRAWVIEW3D, 0);
623 if(event == B_SETSMOOTH) BIF_undo_push("Set Smooth");
624 else BIF_undo_push("Set Solid");
628 DAG_scene_sort(G.scene); // makes new dag
629 if(ob) ob->recalc |= OB_RECALC;
630 allqueue(REDRAWVIEW3D, 0);
637 ob->shapeflag |= OB_SHAPE_TEMPLOCK;
638 DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA);
639 allqueue(REDRAWVIEW3D, 0);
640 allqueue(REDRAWIPO, 0);
641 allqueue(REDRAWBUTSEDIT, 0);
644 ob->shapeflag &= ~OB_SHAPE_TEMPLOCK;
645 DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA);
646 allqueue(REDRAWVIEW3D, 0);
647 allqueue(REDRAWIPO, 0);
648 allqueue(REDRAWBUTSEDIT, 0);
652 Key *key= ob_get_key(ob);
653 if(ob->shapenr == BLI_countlist(&key->block))
656 do_common_editbuts(B_SETKEY);
661 Key *key= ob_get_key(ob);
663 ob->shapenr= BLI_countlist(&key->block);
665 do_common_editbuts(B_SETKEY);
669 allspace(REMAKEIPO, 0);
670 allqueue (REDRAWIPO, 0);
674 allqueue(REDRAWACTION, 0);
682 if(event>=B_OBLAY && event<=B_OBLAY+31) {
683 local= BASACT->lay & 0xFF000000;
684 BASACT->lay -= local;
685 if(BASACT->lay==0 || (G.qual & LR_SHIFTKEY)==0) {
688 scrarea_queue_winredraw(curarea);
690 BASACT->lay += local;
692 if( (ob->lay & G.vd->lay) && (BASACT->lay & G.vd->lay) );
693 else if( (ob->lay & G.vd->lay)==0 && (BASACT->lay & G.vd->lay)==0 );
695 allqueue(REDRAWVIEW3D, 0);
696 DAG_scene_sort(G.scene);
698 ob->lay= BASACT->lay;
704 /* *************************** MESH ******************************** */
706 static void verify_customdata_name_func(void *data1, void *data2)
708 CustomData *data= (CustomData*)data1;
709 CustomDataLayer *layer= (CustomDataLayer*)data2;
711 CustomData_set_layer_unique_name(data, layer - data->layers);
714 static void delete_customdata_layer(void *data1, void *data2)
716 Mesh *me= (Mesh*)data1;
717 CustomData *data= (G.obedit)? &G.editMesh->fdata: &me->fdata;
718 CustomDataLayer *layer= (CustomDataLayer*)data2;
719 void *actlayerdata, *rndlayerdata, *layerdata=layer->data;
720 int type= layer->type;
721 int index= CustomData_get_layer_index(data, type);
722 int i, actindex, rndindex;
724 /*ok, deleting a non-active layer needs to preserve the active layer indices.
725 to do this, we store a pointer to the .data member of both layer and the active layer,
726 (to detect if we're deleting the active layer or not), then use the active
727 layer data pointer to find where the active layer has ended up.
729 this is necassary because the deletion functions only support deleting the active
731 actlayerdata = data->layers[CustomData_get_active_layer_index(data, type)].data;
732 rndlayerdata = data->layers[CustomData_get_render_layer_index(data, type)].data;
733 CustomData_set_layer_active(data, type, layer - &data->layers[index]);
735 /* Multires is handled seperately because the display data is separate
736 from the data stored in multires */
738 multires_delete_layer(me, &me->mr->fdata, type, layer - &data->layers[index]);
741 EM_free_data_layer(data, type);
744 CustomData_free_layer_active(data, type, me->totface);
745 mesh_update_customdata_pointers(me);
748 if(!CustomData_has_layer(data, type)) {
749 if(type == CD_MCOL && (G.f & G_VERTEXPAINT))
750 G.f &= ~G_VERTEXPAINT; /* get out of vertexpaint mode */
753 /*reconstruct active layer*/
754 if (actlayerdata != layerdata) {
756 actindex = CustomData_get_layer_index(data, type);
757 for (i=actindex; i<data->totlayer; i++) {
758 if (data->layers[i].data == actlayerdata) {
759 actindex = i - actindex;
765 CustomData_set_layer_active(data, type, actindex);
768 if (rndlayerdata != layerdata) {
770 rndindex = CustomData_get_layer_index(data, type);
771 for (i=rndindex; i<data->totlayer; i++) {
772 if (data->layers[i].data == rndlayerdata) {
773 rndindex = i - rndindex;
779 CustomData_set_layer_render(data, type, rndindex);
783 DAG_object_flush_update(G.scene, OBACT, OB_RECALC_DATA);
785 if(type == CD_MTFACE)
786 BIF_undo_push("Delete UV Texture");
787 else if(type == CD_MCOL)
788 BIF_undo_push("Delete Vertex Color");
790 allqueue(REDRAWVIEW3D, 0);
791 allqueue(REDRAWIMAGE, 0);
792 allqueue(REDRAWBUTSEDIT, 0);
795 static int customdata_buttons(
796 uiBlock *block, Mesh *me, CustomData *data,
797 int type, int *activep, int *renderp,
798 int setevt, int setevt_rnd, int newevt,
799 char *label, char *shortlabel, char *browsetip, char *browsetip_rnd,
800 char *newtip, char *deltip, int x, int y)
802 CustomDataLayer *layer;
804 int i, count= CustomData_number_of_layers(data, type);
806 if(count >= MAX_MTFACE) {
807 uiDefBut(block, LABEL, 0, label, x,y,220,19, 0, 0.0, 0, 0, 0, "");
810 uiDefBut(block, LABEL, 0, label, x,y,140,19, 0, 0.0, 0, 0, 0, "");
811 uiBlockBeginAlign(block);
812 uiDefBut(block, BUT, newevt, "New", x+140,y,80,19, 0,0,0,0,0, newtip);
813 uiBlockEndAlign(block);
816 y -= (count)? 24: 19;
818 uiBlockBeginAlign(block);
819 for (count=1, i=0; i<data->totlayer; i++) {
820 layer= &data->layers[i];
822 if(layer->type == type) {
823 *activep= layer->active + 1;
824 *renderp= layer->active_rnd + 1;
826 uiDefIconButI(block, ROW, setevt, ICON_VIEW3D, x,y,25,19, activep, 1.0, count, 0, 0, browsetip);
827 uiDefIconButI(block, ROW, setevt_rnd, ICON_SCENE, x+25,y,25,19, renderp, 1.0, count, 0, 0, browsetip_rnd);
828 but=uiDefBut(block, TEX, setevt, "", x+50,y,145,19, layer->name, 0.0, 31.0, 0, 0, label);
829 uiButSetFunc(but, verify_customdata_name_func, data, layer);
830 but= uiDefIconBut(block, BUT, B_NOP, VICON_X, x+195,y,25,19, NULL, 0.0, 0.0, 0.0, 0.0, deltip);
831 uiButSetFunc(but, delete_customdata_layer, me, layer);
838 uiBlockEndAlign(block);
843 static void editing_panel_mesh_type(Object *ob, Mesh *me)
851 block= uiNewBlock(&curarea->uiblocks, "editing_panel_mesh_type", UI_EMBOSS, UI_HELV, curarea->win);
852 if( uiNewPanel(curarea, block, "Mesh", "Editing", 320, 0, 318, 204)==0) return;
853 uiSetButLock(object_data_is_libdata(ob), ERROR_LIBDATA_MESSAGE);
855 uiBlockBeginAlign(block);
856 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");
857 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");
858 uiBlockEndAlign(block);
862 uiBlockBeginAlign(block);
863 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");
864 uiButSetFunc(but,retopo_toggle,ob,me);
865 if(G.scene->toolsettings->retopo_mode) {
866 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.");
867 uiButSetFunc(but,retopo_paint_toggle,ob,me);
868 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");
869 uiButSetFunc(but,retopo_do_all_cb,ob,me);
871 uiBlockEndAlign(block);
874 uiBlockBeginAlign(block);
875 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");
876 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");
877 uiDefBut(block, BUT,B_DOCENTERCURSOR, "Center Cursor", 10, 60, 170, 19, 0, 0, 0, 0, 0, "Shifts object's origin to cursor location");
878 uiBlockEndAlign(block);
880 uiBlockBeginAlign(block);
881 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");
882 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");
883 uiBlockEndAlign(block);
885 uiDefIDPoinBut(block, test_meshpoin_but, ID_ME, B_REDR, "TexMesh: ", 190,180,220,19, &me->texcomesh, "Derive texture coordinates from another mesh.");
887 if(me->msticky) val= 1.0; else val= 0.0;
888 uiDefBut(block, LABEL, 0, "Sticky", 190,155,140,19, 0, val, 0, 0, 0, "");
889 uiBlockBeginAlign(block);
890 if(me->msticky==NULL) {
891 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");
893 else uiDefBut(block, BUT, B_DELSTICKY, "Delete", 330,155, 80,19, 0, 0, 0, 0, 0, "Deletes Sticky texture coordinates");
894 uiBlockEndAlign(block);
896 fdata= (G.obedit)? &G.editMesh->fdata: &me->fdata;
897 yco= customdata_buttons(block, me, fdata, CD_MTFACE, &acttface, &acttface_rnd,
898 B_SETTFACE, B_SETTFACE_RND, B_NEWTFACE, "UV Texture", "UV Texture:",
899 "Set active UV texture", "Set rendering UV texture", "Creates a new UV texture layer",
900 "Removes the current UV texture layer", 190, 130);
902 yco= customdata_buttons(block, me, fdata, CD_MCOL, &actmcol, &actmcol_rnd,
903 B_SETMCOL, B_SETMCOL_RND, B_NEWMCOL, "Vertex Color", "Vertex Color:",
904 "Sets active vertex color layer", "Sets rendering vertex color layer", "Creates a new vertex color layer",
905 "Removes the current vertex color layer", 190, yco-5);
908 uiNewPanelHeight(block, 204 - yco);
911 /* *************************** MODIFIERS ******************************** */
913 void do_modifier_panels(unsigned short event)
918 case B_MODIFIER_REDRAW:
919 allqueue(REDRAWBUTSEDIT, 0);
920 allqueue(REDRAWOOPS, 0);
923 case B_MODIFIER_RECALC:
924 ob->softflag |= OB_SB_RESET;
925 allqueue(REDRAWBUTSEDIT, 0);
926 allqueue(REDRAWVIEW3D, 0);
927 allqueue(REDRAWIMAGE, 0);
928 allqueue(REDRAWOOPS, 0);
929 DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA);
930 object_handle_update(ob);
936 static void modifiers_add(void *ob_v, int type)
939 ModifierTypeInfo *mti = modifierType_getInfo(type);
941 if (mti->flags&eModifierTypeFlag_RequiresOriginalData) {
942 ModifierData *md = ob->modifiers.first;
944 while (md && modifierType_getInfo(md->type)->type==eModifierTypeType_OnlyDeform) {
948 BLI_insertlinkbefore(&ob->modifiers, md, modifier_new(type));
950 BLI_addtail(&ob->modifiers, modifier_new(type));
952 BIF_undo_push("Add modifier");
955 typedef struct MenuEntry {
960 static int menuEntry_compare_names(const void *entry1, const void *entry2)
962 return strcmp(((MenuEntry *)entry1)->name, ((MenuEntry *)entry2)->name);
965 static uiBlock *modifiers_add_menu(void *ob_v)
971 MenuEntry entries[NUM_MODIFIER_TYPES];
973 block= uiNewBlock(&curarea->uiblocks, "modifier_add_menu",
974 UI_EMBOSSP, UI_HELV, curarea->win);
975 uiBlockSetButmFunc(block, modifiers_add, ob);
977 for (i=eModifierType_None+1; i<NUM_MODIFIER_TYPES; i++) {
978 ModifierTypeInfo *mti = modifierType_getInfo(i);
980 /* Only allow adding through appropriate other interfaces */
981 if(ELEM3(i, eModifierType_Softbody, eModifierType_Hook, eModifierType_ParticleSystem)) continue;
983 if((mti->flags&eModifierTypeFlag_AcceptsCVs) ||
984 (ob->type==OB_MESH && (mti->flags&eModifierTypeFlag_AcceptsMesh))) {
985 entries[numEntries].name = mti->name;
986 entries[numEntries].ID = i;
992 qsort(entries, numEntries, sizeof(*entries), menuEntry_compare_names);
995 for(i = 0; i < numEntries; ++i)
996 uiDefBut(block, BUTM, B_MODIFIER_RECALC, entries[i].name,
997 0, yco -= 20, 160, 19, NULL, 0, 0, 1, entries[i].ID, "");
999 uiTextBoundsBlock(block, 50);
1000 uiBlockSetDirection(block, UI_DOWN);
1005 static void modifiers_del(void *ob_v, void *md_v)
1010 /* It seems on rapid delete it is possible to
1011 * get called twice on same modifier, so make
1012 * sure it is in list.
1014 for (md=ob->modifiers.first; md; md=md->next)
1021 if(md->type==eModifierType_ParticleSystem){
1022 ParticleSystemModifierData *psmd=(ParticleSystemModifierData*)md;
1023 BLI_remlink(&ob->particlesystem, psmd->psys);
1024 psys_free(ob,psmd->psys);
1027 BLI_remlink(&ob->modifiers, md_v);
1029 modifier_free(md_v);
1031 BIF_undo_push("Del modifier");
1034 int mod_moveUp(void *ob_v, void *md_v)
1037 ModifierData *md = md_v;
1040 ModifierTypeInfo *mti = modifierType_getInfo(md->type);
1042 if (mti->type!=eModifierTypeType_OnlyDeform) {
1043 ModifierTypeInfo *nmti = modifierType_getInfo(md->prev->type);
1045 if (nmti->flags&eModifierTypeFlag_RequiresOriginalData)
1049 BLI_remlink(&ob->modifiers, md);
1050 BLI_insertlink(&ob->modifiers, md->prev->prev, md);
1056 static void modifiers_moveUp(void *ob_v, void *md_v)
1058 if( mod_moveUp( ob_v, md_v ) )
1059 error("Cannot move above a modifier requiring original data.");
1061 BIF_undo_push("Move modifier");
1064 int mod_moveDown(void *ob_v, void *md_v)
1067 ModifierData *md = md_v;
1070 ModifierTypeInfo *mti = modifierType_getInfo(md->type);
1072 if (mti->flags&eModifierTypeFlag_RequiresOriginalData) {
1073 ModifierTypeInfo *nmti = modifierType_getInfo(md->next->type);
1075 if (nmti->type!=eModifierTypeType_OnlyDeform)
1079 BLI_remlink(&ob->modifiers, md);
1080 BLI_insertlink(&ob->modifiers, md->next, md);
1086 static void modifiers_moveDown(void *ob_v, void *md_v)
1088 if( mod_moveDown( ob_v, md_v ) )
1089 error("Cannot move beyond a non-deforming modifier.");
1091 BIF_undo_push("Move modifier");
1094 static void modifier_testLatticeObj(char *name, ID **idpp)
1098 for (id= G.main->object.first; id; id= id->next) {
1099 if( strcmp(name, id->name+2)==0 ) {
1100 if (((Object *)id)->type != OB_LATTICE) {
1101 error ("Lattice deform object must be a lattice");
1111 static void modifier_testCurveObj(char *name, ID **idpp)
1115 for (id= G.main->object.first; id; id= id->next) {
1116 if( strcmp(name, id->name+2)==0 ) {
1117 if (((Object *)id)->type != OB_CURVE) {
1118 error ("Curve deform object must be a curve");
1128 static void modifier_testMeshObj(char *name, ID **idpp)
1132 for (id= G.main->object.first; id; id= id->next) {
1133 /* no boolean on its own object */
1134 if(id != (ID *)OBACT) {
1135 if( strcmp(name, id->name+2)==0 ) {
1136 if (((Object *)id)->type != OB_MESH) {
1137 error ("Boolean modifier object must be a mesh");
1148 static void modifier_testArmatureObj(char *name, ID **idpp)
1152 for (id= G.main->object.first; id; id= id->next) {
1153 if( strcmp(name, id->name+2)==0 ) {
1154 if (((Object *)id)->type != OB_ARMATURE) {
1155 error ("Armature deform object must be an armature");
1165 static void modifier_testTexture(char *name, ID **idpp)
1169 for(id = G.main->tex.first; id; id = id->next) {
1170 if(strcmp(name, id->name + 2) == 0) {
1172 /* texture gets user, objects not: delete object = clear modifier */
1180 #if 0 /* this is currently unused, but could be useful in the future */
1181 static void modifier_testMaterial(char *name, ID **idpp)
1185 for(id = G.main->mat.first; id; id = id->next) {
1186 if(strcmp(name, id->name + 2) == 0) {
1195 static void modifier_testImage(char *name, ID **idpp)
1199 for(id = G.main->image.first; id; id = id->next) {
1200 if(strcmp(name, id->name + 2) == 0) {
1208 /* autocomplete callback for ID buttons */
1209 void autocomplete_image(char *str, void *arg_v)
1211 /* search if str matches the beginning of an ID struct */
1213 AutoComplete *autocpl = autocomplete_begin(str, 22);
1216 for(id = G.main->image.first; id; id = id->next)
1217 autocomplete_do_name(autocpl, id->name+2);
1219 autocomplete_end(autocpl, str);
1223 /* autocomplete callback for ID buttons */
1224 void autocomplete_meshob(char *str, void *arg_v)
1226 /* search if str matches the beginning of an ID struct */
1228 AutoComplete *autocpl = autocomplete_begin(str, 22);
1231 for(id = G.main->object.first; id; id = id->next)
1232 if(((Object *)id)->type == OB_MESH)
1233 autocomplete_do_name(autocpl, id->name+2);
1235 autocomplete_end(autocpl, str);
1238 static void modifiers_convertParticles(void *obv, void *mdv)
1241 ModifierData *md = mdv;
1242 ParticleSystem *psys;
1243 ParticleCacheKey *key, **cache;
1248 int totvert=0, totface=0, cvert=0;
1249 int totpart=0, totchild=0;
1251 if(md->type != eModifierType_ParticleSystem) return;
1253 if(G.f & G_PARTICLEEDIT) return;
1255 psys=((ParticleSystemModifierData *)md)->psys;
1257 if(psys->part->draw_as != PART_DRAW_PATH || psys->pathcache == 0) return;
1259 totpart= psys->totcached;
1260 totchild= psys->totchildcache;
1262 if(totchild && (psys->part->draw&PART_DRAW_PARENT)==0)
1266 cache= psys->pathcache;
1267 for(a=0; a<totpart; a++) {
1269 totvert+= (int)(key->col[3])+1;
1270 totface+= (int)(key->col[3]);
1273 cache= psys->childcache;
1274 for(a=0; a<totchild; a++) {
1276 totvert+= (int)(key->col[3])+1;
1277 totface+= (int)(key->col[3]);
1280 if(totvert==0) return;
1283 obn= add_object(OB_MESH);
1286 me->totvert= totvert;
1287 me->totface= totface;
1289 me->mvert= CustomData_add_layer(&me->vdata, CD_MVERT, CD_CALLOC, NULL, totvert);
1290 me->mface= CustomData_add_layer(&me->fdata, CD_MFACE, CD_CALLOC, NULL, totface);
1295 /* copy coordinates */
1296 cache= psys->pathcache;
1297 for(a=0; a<totpart; a++){
1299 kmax= (int)(key->col[3]);
1300 for(k=0; k<=kmax; k++,key++,cvert++,mvert++) {
1301 VECCOPY(mvert->co,key->co);
1310 cache=psys->childcache;
1311 for(a=0; a<totchild; a++) {
1313 kmax=(int)(key->col[3]);
1314 for(k=0; k<=kmax; k++,key++,cvert++,mvert++) {
1315 VECCOPY(mvert->co,key->co);
1325 static void modifiers_applyModifier(void *obv, void *mdv)
1328 ModifierData *md = mdv;
1330 Mesh *me = ob->data;
1334 error("Modifiers cannot be applied in editmode");
1336 } else if (((ID*) ob->data)->us>1) {
1337 error("Modifiers cannot be applied to multi-user data");
1341 if (md!=ob->modifiers.first) {
1342 if (!okee("Modifier is not first"))
1346 if (ob->type==OB_MESH) {
1347 if(me->mr && multires_modifier_warning()) {
1348 error("Modifier changes topology; cannot apply with multires active");
1352 error("Modifier cannot be applied to Mesh with Shape Keys");
1356 sculptmode_pmv_off(me);
1358 dm = mesh_create_derived_for_modifier(ob, md);
1360 error("Modifier is disabled or returned error, skipping apply");
1369 else if (ELEM(ob->type, OB_CURVE, OB_SURF)) {
1370 ModifierTypeInfo *mti = modifierType_getInfo(md->type);
1371 Curve *cu = ob->data;
1373 float (*vertexCos)[3];
1375 if (!okee("Apply will only change CV points, not tesselated/bevel vertices"))
1378 if (!(md->mode&eModifierMode_Realtime) || (mti->isDisabled && mti->isDisabled(md))) {
1379 error("Modifier is disabled, skipping apply");
1383 vertexCos = curve_getVertexCos(cu, &cu->nurb, &numVerts);
1384 mti->deformVerts(md, ob, NULL, vertexCos, numVerts);
1385 curve_applyVertexCos(cu, &cu->nurb, vertexCos);
1389 MEM_freeN(vertexCos);
1391 DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA);
1394 error("Cannot apply modifier for this object type");
1399 BLI_remlink(&ob->modifiers, md);
1402 BIF_undo_push("Apply modifier");
1406 static void modifiers_copyModifier(void *ob_v, void *md_v)
1409 ModifierData *md = md_v;
1410 ModifierData *nmd = modifier_new(md->type);
1412 modifier_copyData(md, nmd);
1414 BLI_insertlink(&ob->modifiers, md, nmd);
1416 BIF_undo_push("Copy modifier");
1419 static void modifiers_setOnCage(void *ob_v, void *md_v)
1424 int i, cageIndex = modifiers_getCageIndex(ob, NULL );
1426 for( i = 0, md=ob->modifiers.first; md; ++i, md=md->next )
1428 if( i >= cageIndex )
1429 md->mode ^= eModifierMode_OnCage;
1434 static void modifiers_clearHookOffset(void *ob_v, void *md_v)
1437 ModifierData *md = md_v;
1438 HookModifierData *hmd = (HookModifierData*) md;
1441 Mat4Invert(hmd->object->imat, hmd->object->obmat);
1442 Mat4MulSerie(hmd->parentinv, hmd->object->imat, ob->obmat, NULL, NULL, NULL, NULL, NULL, NULL);
1443 BIF_undo_push("Clear hook offset");
1447 static void modifiers_cursorHookCenter(void *ob_v, void *md_v)
1450 ModifierData *md = md_v;
1451 HookModifierData *hmd = (HookModifierData*) md;
1454 float *curs = give_cursor();
1455 float bmat[3][3], imat[3][3];
1457 where_is_object(ob);
1459 Mat3CpyMat4(bmat, ob->obmat);
1460 Mat3Inv(imat, bmat);
1462 curs= give_cursor();
1463 hmd->cent[0]= curs[0]-ob->obmat[3][0];
1464 hmd->cent[1]= curs[1]-ob->obmat[3][1];
1465 hmd->cent[2]= curs[2]-ob->obmat[3][2];
1466 Mat3MulVecfl(imat, hmd->cent);
1468 BIF_undo_push("Hook cursor center");
1472 static void modifiers_selectHook(void *ob_v, void *md_v)
1474 ModifierData *md = md_v;
1475 HookModifierData *hmd = (HookModifierData*) md;
1480 static void modifiers_reassignHook(void *ob_v, void *md_v)
1482 ModifierData *md = md_v;
1483 HookModifierData *hmd = (HookModifierData*) md;
1485 int *indexar, tot, ok;
1488 ok= hook_getIndexArray(&tot, &indexar, name, cent);
1491 error("Requires selected vertices or active Vertex Group");
1494 MEM_freeN(hmd->indexar);
1497 VECCOPY(hmd->cent, cent);
1498 hmd->indexar = indexar;
1499 hmd->totindex = tot;
1503 static void modifiers_convertToReal(void *ob_v, void *md_v)
1506 ModifierData *md = md_v;
1507 ModifierData *nmd = modifier_new(md->type);
1509 modifier_copyData(md, nmd);
1510 nmd->mode &= ~eModifierMode_Virtual;
1512 BLI_addhead(&ob->modifiers, nmd);
1514 ob->partype = PAROBJECT;
1516 BIF_undo_push("Modifier convert to real");
1519 static void build_uvlayer_menu_vars(CustomData *data, char **menu_string,
1520 int *uvlayer_tmp, char *uvlayer_name)
1524 CustomDataLayer *layer
1525 = &data->layers[CustomData_get_layer_index(data, CD_MTFACE)];
1529 totuv = CustomData_number_of_layers(data, CD_MTFACE);
1531 *menu_string = MEM_callocN(sizeof(**menu_string) * (totuv * 38 + 10),
1533 sprintf(*menu_string, "UV Layer%%t");
1534 for(i = 0; i < totuv; i++) {
1535 /* assign first layer as uvlayer_name if uvlayer_name is null. */
1536 if(strcmp(layer->name, uvlayer_name) == 0) *uvlayer_tmp = i + 1;
1537 sprintf(strtmp, "|%s%%x%d", layer->name, i + 1);
1538 strcat(*menu_string, strtmp);
1542 /* there is no uvlayer defined, or else it was deleted. Assign active
1543 * layer, then recalc modifiers.
1545 if(*uvlayer_tmp == -1) {
1546 if(CustomData_get_active_layer_index(data, CD_MTFACE) != -1) {
1548 layer = data->layers;
1549 for(i = 0; i < CustomData_get_active_layer_index(data, CD_MTFACE);
1551 if(layer->type == CD_MTFACE) (*uvlayer_tmp)++;
1553 strcpy(uvlayer_name, layer->name);
1555 /* update the modifiers */
1556 do_modifier_panels(B_MODIFIER_RECALC);
1558 /* ok we have no uv layers, so make sure menu button knows that.*/
1564 void set_displace_uvlayer(void *arg1, void *arg2)
1566 DisplaceModifierData *dmd=arg1;
1567 CustomDataLayer *layer = arg2;
1569 /*check we have UV layers*/
1570 if (dmd->uvlayer_tmp < 1) return;
1571 layer = layer + (dmd->uvlayer_tmp-1);
1573 strcpy(dmd->uvlayer_name, layer->name);
1576 void set_uvproject_uvlayer(void *arg1, void *arg2)
1578 UVProjectModifierData *umd=arg1;
1579 CustomDataLayer *layer = arg2;
1581 /*check we have UV layers*/
1582 if (umd->uvlayer_tmp < 1) return;
1583 layer = layer + (umd->uvlayer_tmp-1);
1585 strcpy(umd->uvlayer_name, layer->name);
1588 static void modifiers_bindMeshDeform(void *ob_v, void *md_v)
1590 MeshDeformModifierData *mmd = (MeshDeformModifierData*) md_v;
1591 Object *ob = (Object*)ob_v;
1594 if(mmd->bindweights) MEM_freeN(mmd->bindweights);
1595 if(mmd->bindcos) MEM_freeN(mmd->bindcos);
1596 if(mmd->dyngrid) MEM_freeN(mmd->dyngrid);
1597 if(mmd->dyninfluences) MEM_freeN(mmd->dyninfluences);
1598 if(mmd->dynverts) MEM_freeN(mmd->dynverts);
1599 mmd->bindweights= NULL;
1602 mmd->dyninfluences= NULL;
1603 mmd->dynverts= NULL;
1605 mmd->totcagevert= 0;
1606 mmd->totinfluence= 0;
1610 int mode= mmd->modifier.mode;
1612 /* force modifier to run, it will call binding routine */
1614 mmd->modifier.mode |= eModifierMode_Realtime;
1616 if(ob->type == OB_MESH) {
1617 dm= mesh_create_derived_view(ob, 0);
1620 else if(ob->type == OB_LATTICE) {
1621 lattice_calc_modifiers(ob);
1623 else if(ob->type==OB_MBALL) {
1624 makeDispListMBall(ob);
1626 else if(ELEM3(ob->type, OB_CURVE, OB_SURF, OB_FONT)) {
1627 makeDispListCurveTypes(ob, 0);
1631 mmd->modifier.mode= mode;
1635 void modifiers_explodeFacepa(void *arg1, void *arg2)
1637 ExplodeModifierData *emd=arg1;
1639 emd->flag |= eExplodeFlag_CalcFaces;
1642 static void modifiers_psysEnable(void *ob_v, void *md_v)
1644 ParticleSystemModifierData *psmd = (ParticleSystemModifierData*) md_v;
1646 if(psmd->modifier.mode & eModifierMode_Realtime) {
1647 psmd->psys->flag |= PSYS_ENABLED;
1650 psmd->psys->flag &= ~PSYS_ENABLED;
1651 PE_free_particle_edit(psmd->psys);
1655 static void draw_modifier(uiBlock *block, Object *ob, ModifierData *md, int *xco, int *yco, int index, int cageIndex, int lastCageIndex)
1657 ModifierTypeInfo *mti = modifierType_getInfo(md->type);
1659 int isVirtual = md->mode&eModifierMode_Virtual;
1660 int x = *xco, y = *yco, color = md->error?TH_REDALERT:TH_BUT_NEUTRAL;
1661 int editing = (G.obedit==ob);
1662 short height=26, width = 295, buttonWidth = width-120-10;
1665 /* rounded header */
1666 uiBlockSetCol(block, color);
1667 /* roundbox 4 free variables: corner-rounding, nop, roundbox type, shade */
1668 uiDefBut(block, ROUNDBOX, 0, "", x-10, y-4, width, 25, NULL, 7.0, 0.0,
1669 (!isVirtual && (md->mode&eModifierMode_Expanded))?3:15, 20, "");
1670 uiBlockSetCol(block, TH_AUTO);
1672 /* open/close icon */
1674 uiBlockSetEmboss(block, UI_EMBOSSN);
1675 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");
1678 uiBlockSetEmboss(block, UI_EMBOSS);
1681 sprintf(str, "%s parent deform", md->name);
1682 uiDefBut(block, LABEL, 0, str, x+10, y-1, width-110, 19, NULL, 0.0, 0.0, 0.0, 0.0, "Modifier name");
1684 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");
1685 uiButSetFunc(but, modifiers_convertToReal, ob, md);
1687 uiBlockBeginAlign(block);
1688 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");
1690 /* Softbody not allowed in this situation, enforce! */
1691 if (md->type!=eModifierType_Softbody || !(ob->pd && ob->pd->deflect)) {
1692 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");
1693 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");
1694 if (md->type==eModifierType_ParticleSystem)
1695 uiButSetFunc(but, modifiers_psysEnable, ob, md);
1696 if (mti->flags&eModifierTypeFlag_SupportsEditmode) {
1697 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)");
1700 uiBlockEndAlign(block);
1702 uiBlockSetEmboss(block, UI_EMBOSSR);
1704 if (ob->type==OB_MESH && modifier_couldBeCage(md) && index<=lastCageIndex) {
1707 if (index==cageIndex) {
1708 color = TH_BUT_SETTING;
1709 icon = VICON_EDITMODE_HLT;
1710 } else if (index<cageIndex) {
1711 color = TH_BUT_NEUTRAL;
1712 icon = VICON_EDITMODE_DEHLT;
1714 color = TH_BUT_NEUTRAL;
1717 uiBlockSetCol(block, color);
1718 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");
1719 uiButSetFunc(but, modifiers_setOnCage, ob, md);
1720 uiBlockSetCol(block, TH_AUTO);
1723 uiBlockSetCol(block, TH_BUT_ACTION);
1725 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");
1726 uiButSetFunc(but, modifiers_moveUp, ob, md);
1728 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");
1729 uiButSetFunc(but, modifiers_moveDown, ob, md);
1731 uiBlockSetEmboss(block, UI_EMBOSSN);
1733 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");
1734 uiButSetFunc(but, modifiers_del, ob, md);
1735 uiBlockSetCol(block, TH_AUTO);
1738 uiBlockSetEmboss(block, UI_EMBOSS);
1740 if (isVirtual || !(md->mode&eModifierMode_Expanded)) {
1744 int lx = x + width - 60 - 15;
1746 if (md->type==eModifierType_Subsurf) {
1748 } else if (md->type==eModifierType_Lattice) {
1750 } else if (md->type==eModifierType_Curve) {
1752 } else if (md->type==eModifierType_Build) {
1754 } else if (md->type==eModifierType_Mirror) {
1756 } else if (md->type==eModifierType_EdgeSplit) {
1757 EdgeSplitModifierData *emd = (EdgeSplitModifierData*) md;
1759 if(emd->flags & MOD_EDGESPLIT_FROMANGLE) height += 19;
1760 } else if (md->type==eModifierType_Displace) {
1761 DisplaceModifierData *dmd = (DisplaceModifierData *)md;
1763 if(dmd->texmapping == MOD_DISP_MAP_OBJECT ||
1764 dmd->texmapping == MOD_DISP_MAP_UV)
1766 } else if (md->type==eModifierType_UVProject) {
1767 height = 114 + ((UVProjectModifierData *)md)->num_projectors * 19;
1768 } else if (md->type==eModifierType_Decimate) {
1770 } else if (md->type==eModifierType_Smooth) {
1772 } else if (md->type==eModifierType_Cast) {
1774 } else if (md->type==eModifierType_Wave) {
1775 WaveModifierData *wmd = (WaveModifierData *)md;
1777 if(wmd->texmapping == MOD_WAV_MAP_OBJECT ||
1778 wmd->texmapping == MOD_WAV_MAP_UV)
1780 if(wmd->flag & MOD_WAVE_NORM)
1782 } else if (md->type==eModifierType_Armature) {
1784 } else if (md->type==eModifierType_Hook) {
1785 HookModifierData *hmd = (HookModifierData*) md;
1789 if(hmd->indexar==NULL)
1791 } else if (md->type==eModifierType_Softbody) {
1793 } else if (md->type==eModifierType_Boolean) {
1795 } else if (md->type==eModifierType_Array) {
1797 } else if (md->type==eModifierType_MeshDeform) {
1798 MeshDeformModifierData *mmd= (MeshDeformModifierData*)md;
1799 height = (mmd->bindcos)? 73: 93;
1800 } else if (md->type==eModifierType_ParticleSystem) {
1802 } else if (md->type==eModifierType_ParticleInstance) {
1804 } else if (md->type==eModifierType_Explode) {
1808 /* roundbox 4 free variables: corner-rounding, nop, roundbox type, shade */
1809 uiDefBut(block, ROUNDBOX, 0, "", x-10, y-height-2, width, height-2, NULL, 5.0, 0.0, 12, 40, "");
1814 uiBlockBeginAlign(block);
1815 if (md->type==eModifierType_ParticleSystem) {
1816 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");
1817 uiButSetFunc(but, modifiers_convertParticles, ob, md);
1820 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");
1821 uiButSetFunc(but, modifiers_applyModifier, ob, md);
1824 if (md->type!=eModifierType_Softbody && md->type!=eModifierType_ParticleSystem) {
1825 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");
1826 uiButSetFunc(but, modifiers_copyModifier, ob, md);
1828 uiBlockEndAlign(block);
1833 uiBlockBeginAlign(block);
1834 if (md->type==eModifierType_Subsurf) {
1835 SubsurfModifierData *smd = (SubsurfModifierData*) md;
1836 char subsurfmenu[]="Subsurf Type%t|Catmull-Clark%x0|Simple Subdiv.%x1";
1837 uiDefButS(block, MENU, B_MODIFIER_RECALC, subsurfmenu, lx,(cy-=19),buttonWidth,19, &smd->subdivType, 0, 0, 0, 0, "Selects type of subdivision algorithm.");
1838 uiDefButS(block, NUM, B_MODIFIER_RECALC, "Levels:", lx, (cy-=19), buttonWidth,19, &smd->levels, 1, 6, 0, 0, "Number subdivisions to perform");
1839 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");
1841 /* Disabled until non-EM DerivedMesh implementation is complete */
1844 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");
1845 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");
1848 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");
1849 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");
1850 } else if (md->type==eModifierType_Lattice) {
1851 LatticeModifierData *lmd = (LatticeModifierData*) md;
1852 uiDefIDPoinBut(block, modifier_testLatticeObj, ID_OB, B_CHANGEDEP, "Ob: ", lx, (cy-=19), buttonWidth,19, &lmd->object, "Lattice object to deform with");
1853 but=uiDefBut(block, TEX, B_MODIFIER_RECALC, "VGroup: ", lx, (cy-=19), buttonWidth,19, &lmd->name, 0.0, 31.0, 0, 0, "Vertex Group name");
1854 uiButSetCompleteFunc(but, autocomplete_vgroup, (void *)ob);
1855 } else if (md->type==eModifierType_Curve) {
1856 CurveModifierData *cmd = (CurveModifierData*) md;
1857 uiDefIDPoinBut(block, modifier_testCurveObj, ID_OB, B_CHANGEDEP, "Ob: ", lx, (cy-=19), buttonWidth,19, &cmd->object, "Curve object to deform with");
1858 but=uiDefBut(block, TEX, B_MODIFIER_RECALC, "VGroup: ", lx, (cy-=19), buttonWidth,19, &cmd->name, 0.0, 31.0, 0, 0, "Vertex Group name");
1859 uiButSetCompleteFunc(but, autocomplete_vgroup, (void *)ob);
1861 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");
1862 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");
1863 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");
1864 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");
1865 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");
1866 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");
1867 } else if (md->type==eModifierType_Build) {
1868 BuildModifierData *bmd = (BuildModifierData*) md;
1869 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");
1870 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");
1871 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.");
1872 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.");
1873 } else if (md->type==eModifierType_Mirror) {
1874 MirrorModifierData *mmd = (MirrorModifierData*) md;
1875 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");
1876 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");
1877 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");
1878 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");
1879 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");
1880 uiDefButBitS(block, TOG, MOD_MIR_MIRROR_U, B_MODIFIER_RECALC,
1882 lx, (cy-=19), buttonWidth/2, 19,
1883 &mmd->flag, 0, 0, 0, 0,
1884 "Mirror the U texture coordinate around "
1886 uiDefButBitS(block, TOG, MOD_MIR_MIRROR_V, B_MODIFIER_RECALC,
1888 lx + buttonWidth/2 + 1, cy, buttonWidth/2, 19,
1889 &mmd->flag, 0, 0, 0, 0,
1890 "Mirror the V texture coordinate around "
1892 uiDefIDPoinBut(block, test_obpoin_but, ID_OB, B_CHANGEDEP,
1893 "Ob: ", lx, (cy -= 19), buttonWidth, 19,
1895 "Object to use as mirror");
1897 } else if (md->type==eModifierType_EdgeSplit) {
1898 EdgeSplitModifierData *emd = (EdgeSplitModifierData*) md;
1899 uiDefButBitI(block, TOG, MOD_EDGESPLIT_FROMANGLE,
1900 B_MODIFIER_RECALC, "From Edge Angle",
1901 lx, (cy -= 19), buttonWidth, 19,
1902 &emd->flags, 0, 0, 0, 0,
1903 "Split edges with high angle between faces");
1904 if(emd->flags & MOD_EDGESPLIT_FROMANGLE) {
1905 uiDefButF(block, NUM, B_MODIFIER_RECALC, "Split Angle:",
1906 lx, (cy -= 19), buttonWidth, 19, &emd->split_angle,
1908 "Angle above which to split edges");
1910 uiDefButBitI(block, TOG, MOD_EDGESPLIT_FROMFLAG,
1911 B_MODIFIER_RECALC, "From Marked As Sharp",
1912 lx, (cy -= 19), buttonWidth, 19,
1913 &emd->flags, 0, 0, 0, 0,
1914 "Split edges that are marked as sharp");
1915 } else if (md->type==eModifierType_Displace) {
1916 DisplaceModifierData *dmd = (DisplaceModifierData*) md;
1917 but = uiDefBut(block, TEX, B_MODIFIER_RECALC, "VGroup: ",
1918 lx, (cy -= 19), buttonWidth, 19,
1919 &dmd->defgrp_name, 0.0, 31.0, 0, 0,
1920 "Name of vertex group to displace"
1921 " (displace whole mesh if blank)");
1922 uiButSetCompleteFunc(but, autocomplete_vgroup, (void *)ob);
1923 uiDefIDPoinBut(block, modifier_testTexture, ID_TE, B_CHANGEDEP,
1924 "Texture: ", lx, (cy -= 19), buttonWidth, 19,
1926 "Texture to use as displacement input");
1927 uiDefButF(block, NUM, B_MODIFIER_RECALC, "Midlevel:",
1928 lx, (cy -= 19), buttonWidth, 19, &dmd->midlevel,
1930 "Material value that gives no displacement");
1931 uiDefButF(block, NUM, B_MODIFIER_RECALC, "Strength:",
1932 lx, (cy -= 19), buttonWidth, 19, &dmd->strength,
1933 -1000, 1000, 10, 0.1,
1934 "Strength of displacement");
1935 sprintf(str, "Direction%%t|Normal%%x%d|RGB -> XYZ%%x%d|"
1936 "Z%%x%d|Y%%x%d|X%%x%d",
1937 MOD_DISP_DIR_NOR, MOD_DISP_DIR_RGB_XYZ,
1938 MOD_DISP_DIR_Z, MOD_DISP_DIR_Y, MOD_DISP_DIR_X);
1939 uiDefButI(block, MENU, B_MODIFIER_RECALC, str,
1940 lx, (cy -= 19), buttonWidth, 19, &dmd->direction,
1941 0.0, 1.0, 0, 0, "Displace direction");
1942 sprintf(str, "Texture Coordinates%%t"
1943 "|Local%%x%d|Global%%x%d|Object%%x%d|UV%%x%d",
1944 MOD_DISP_MAP_LOCAL, MOD_DISP_MAP_GLOBAL,
1945 MOD_DISP_MAP_OBJECT, MOD_DISP_MAP_UV);
1946 uiDefButI(block, MENU, B_MODIFIER_RECALC, str,
1947 lx, (cy -= 19), buttonWidth, 19, &dmd->texmapping,
1949 "Texture coordinates used for displacement input");
1950 if (dmd->texmapping == MOD_DISP_MAP_UV) {
1953 CustomData *fdata = G.obedit ? &G.editMesh->fdata
1954 : &((Mesh*)ob->data)->fdata;
1955 build_uvlayer_menu_vars(fdata, &strtmp, &dmd->uvlayer_tmp,
1957 but = uiDefButI(block, MENU, B_MODIFIER_RECALC, strtmp,
1958 lx, (cy -= 19), buttonWidth, 19, &dmd->uvlayer_tmp,
1959 0.0, 1.0, 0, 0, "Set the UV layer to use");
1961 i = CustomData_get_layer_index(fdata, CD_MTFACE);
1962 uiButSetFunc(but, set_displace_uvlayer, dmd,
1965 if(dmd->texmapping == MOD_DISP_MAP_OBJECT) {
1966 uiDefIDPoinBut(block, test_obpoin_but, ID_OB, B_CHANGEDEP,
1967 "Ob: ", lx, (cy -= 19), buttonWidth, 19,
1969 "Object to get texture coordinates from");
1971 } else if (md->type==eModifierType_UVProject) {
1972 UVProjectModifierData *umd = (UVProjectModifierData *) md;
1975 CustomData *fdata = G.obedit ? &G.editMesh->fdata
1976 : &((Mesh*)ob->data)->fdata;
1977 build_uvlayer_menu_vars(fdata, &strtmp, &umd->uvlayer_tmp,
1979 but = uiDefButI(block, MENU, B_MODIFIER_RECALC, strtmp,
1980 lx, (cy -= 19), buttonWidth, 19, &umd->uvlayer_tmp,
1981 0.0, 1.0, 0, 0, "Set the UV layer to use");
1982 i = CustomData_get_layer_index(fdata, CD_MTFACE);
1983 uiButSetFunc(but, set_uvproject_uvlayer, umd, &fdata->layers[i]);
1985 uiDefButF(block, NUM, B_MODIFIER_RECALC, "AspX:",
1986 lx, (cy -= 19), buttonWidth / 2, 19, &umd->aspectx,
1988 "Horizontal Aspect Ratio");
1989 uiDefButF(block, NUM, B_MODIFIER_RECALC, "AspY:",
1990 lx + (buttonWidth / 2) + 1, cy, buttonWidth / 2, 19,
1993 "Vertical Aspect Ratio");
1994 uiDefButI(block, NUM, B_MODIFIER_RECALC, "Projectors:",
1995 lx, (cy -= 19), buttonWidth, 19, &umd->num_projectors,
1996 1, MOD_UVPROJECT_MAXPROJECTORS, 0, 0,
1997 "Number of objects to use as projectors");
1998 for(i = 0; i < umd->num_projectors; ++i) {
1999 uiDefIDPoinBut(block, test_obpoin_but, ID_OB, B_CHANGEDEP,
2000 "Ob: ", lx, (cy -= 19), buttonWidth, 19,
2001 &umd->projectors[i],
2002 "Object to use as projector");
2004 uiDefIDPoinBut(block, modifier_testImage, ID_IM, B_CHANGEDEP,
2005 "Image: ", lx, (cy -= 19), buttonWidth, 19,
2007 "Image to project (only faces with this image "
2009 uiButSetCompleteFunc(but, autocomplete_image, (void *)ob);
2010 uiDefButBitI(block, TOG, MOD_UVPROJECT_OVERRIDEIMAGE,
2011 B_MODIFIER_RECALC, "Override Image",
2012 lx, (cy -= 19), buttonWidth, 19,
2013 &umd->flags, 0, 0, 0, 0,
2014 "Override faces' current images with the "
2016 } else if (md->type==eModifierType_Decimate) {
2017 DecimateModifierData *dmd = (DecimateModifierData*) md;
2018 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");
2019 sprintf(str, "Face Count: %d", dmd->faceCount);
2020 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");
2021 } else if (md->type==eModifierType_Smooth) {
2022 SmoothModifierData *smd = (SmoothModifierData*) md;
2024 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");
2025 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");
2026 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");
2028 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)");
2029 uiDefButS(block, NUM, B_MODIFIER_RECALC, "Repeat:", lx,(cy-=19),buttonWidth, 19, &smd->repeat, 0.0, 30.0, 1, 0, "Number of smoothing iterations");
2030 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");
2031 } else if (md->type==eModifierType_Cast) {
2032 CastModifierData *cmd = (CastModifierData*) md;
2034 char casttypemenu[]="Projection Type%t|Sphere%x0|Cylinder%x1|Cuboid%x2";
2035 uiDefButS(block, MENU, B_MODIFIER_RECALC, casttypemenu, lx,(cy-=19),buttonWidth - 30,19, &cmd->type, 0, 0, 0, 0, "Projection type to apply");
2036 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");
2037 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");
2038 if (cmd->type != MOD_CAST_TYPE_CYLINDER) {
2039 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");
2041 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");
2042 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)");
2043 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)");
2044 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)");
2045 if (ob->type == OB_MESH) {
2046 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");
2048 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");
2050 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");
2052 } else if (md->type==eModifierType_Wave) {
2053 WaveModifierData *wmd = (WaveModifierData*) md;
2054 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");
2055 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");
2056 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");
2057 uiDefButBitS(block, TOG, MOD_WAVE_NORM, B_MODIFIER_RECALC, "Normals", lx,(cy-=19),buttonWidth,19, &wmd->flag, 0, 0, 0, 0, "Displace along normals");
2058 if (wmd->flag & MOD_WAVE_NORM){
2059 if (ob->type==OB_MESH) {
2060 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");
2061 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");
2062 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");
2065 uiDefBut(block, LABEL, 1, "Meshes Only", lx, (cy-=19), buttonWidth,19, NULL, 0.0, 0.0, 0, 0, "");
2068 uiBlockBeginAlign(block);
2070 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");
2072 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");
2073 uiDefButF(block, NUM, B_MODIFIER_RECALC, "Lifetime:", lx,(cy-=19),buttonWidth,19, &wmd->lifetime, -MAXFRAMEF, MAXFRAMEF, 100, 0, "Specify the lifespan of the wave");
2074 uiDefButF(block, NUM, B_MODIFIER_RECALC, "Damptime:", lx,(cy-=19),buttonWidth,19, &wmd->damp, -MAXFRAMEF, MAXFRAMEF, 100, 0, "Specify the dampingtime of the wave");
2076 uiBlockBeginAlign(block);
2077 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");
2078 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");
2079 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)");
2080 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");
2081 uiDefIDPoinBut(block, modifier_testTexture, ID_TE, B_CHANGEDEP,"Texture: ", lx, (cy -= 19), 220, 19, &wmd->texture,"Texture with which to modulate wave");
2082 sprintf(str, "Texture Coordinates%%t"
2083 "|Local%%x%d|Global%%x%d|Object%%x%d|UV%%x%d",
2084 MOD_WAV_MAP_LOCAL, MOD_WAV_MAP_GLOBAL,
2085 MOD_WAV_MAP_OBJECT, MOD_WAV_MAP_UV);
2086 uiDefButI(block, MENU, B_MODIFIER_RECALC, str,
2087 lx, (cy -= 19), 220, 19, &wmd->texmapping,
2089 "Texture coordinates used for modulation input");
2090 if (wmd->texmapping == MOD_WAV_MAP_UV) {
2093 CustomData *fdata = G.obedit ? &G.editMesh->fdata
2094 : &((Mesh*)ob->data)->fdata;
2095 build_uvlayer_menu_vars(fdata, &strtmp, &wmd->uvlayer_tmp,
2097 but = uiDefButI(block, MENU, B_MODIFIER_RECALC, strtmp,
2098 lx, (cy -= 19), 220, 19, &wmd->uvlayer_tmp,
2099 0.0, 1.0, 0, 0, "Set the UV layer to use");
2101 i = CustomData_get_layer_index(fdata, CD_MTFACE);
2102 uiButSetFunc(but, set_displace_uvlayer, wmd,
2105 if(wmd->texmapping == MOD_DISP_MAP_OBJECT) {
2106 uiDefIDPoinBut(block, test_obpoin_but, ID_OB, B_CHANGEDEP,
2107 "Ob: ", lx, (cy -= 19), 220, 19,
2109 "Object to get texture coordinates from");
2112 uiBlockBeginAlign(block);
2113 uiDefButF(block, NUMSLI, B_MODIFIER_RECALC, "Speed:", lx,(cy-=19),220,19, &wmd->speed, -2.0, 2.0, 0, 0, "Specify the wave speed");
2114 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");
2115 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");
2116 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");
2117 } else if (md->type==eModifierType_Armature) {
2118 ArmatureModifierData *amd = (ArmatureModifierData*) md;
2119 uiDefIDPoinBut(block, modifier_testArmatureObj, ID_OB, B_CHANGEDEP, "Ob: ", lx, (cy-=19), buttonWidth,19, &amd->object, "Armature object to deform with");
2121 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");
2122 uiButSetCompleteFunc(but, autocomplete_vgroup, (void *)ob);
2123 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");
2125 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");
2126 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");
2127 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");
2128 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");
2130 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");
2132 } else if (md->type==eModifierType_Hook) {
2133 HookModifierData *hmd = (HookModifierData*) md;
2134 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");
2135 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");
2136 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");
2137 if(hmd->indexar==NULL) {
2138 but=uiDefBut(block, TEX, B_MODIFIER_RECALC, "VGroup: ", lx, (cy-=19), buttonWidth,19, &hmd->name, 0.0, 31.0, 0, 0, "Vertex Group name");
2139 uiButSetCompleteFunc(but, autocomplete_vgroup, (void *)ob);
2141 uiBlockBeginAlign(block);
2142 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");
2143 uiButSetFunc(but, modifiers_clearHookOffset, ob, md);
2144 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");
2145 uiButSetFunc(but, modifiers_cursorHookCenter, ob, md);
2148 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");
2149 uiButSetFunc(but, modifiers_selectHook, ob, md);
2150 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");
2151 uiButSetFunc(but, modifiers_reassignHook, ob, md);
2153 } else if (md->type==eModifierType_Softbody) {
2154 uiDefBut(block, LABEL, 1, "See Softbody panel.", lx, (cy-=19), buttonWidth,19, NULL, 0.0, 0.0, 0, 0, "");
2155 } else if (md->type==eModifierType_Boolean) {
2156 BooleanModifierData *bmd = (BooleanModifierData*) md;
2157 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");
2158 uiDefIDPoinBut(block, modifier_testMeshObj, ID_OB, B_CHANGEDEP, "Ob: ", lx, (cy-=19), buttonWidth,19, &bmd->object, "Mesh object to use for boolean operation");
2159 } else if (md->type==eModifierType_Array) {
2160 ArrayModifierData *amd = (ArrayModifierData*) md;
2161 float range = 10000;
2162 int cytop, halfwidth = (width - 5)/2 - 15;
2163 int halflx = lx + halfwidth + 10;
2165 uiBlockSetEmboss(block, UI_EMBOSSX);
2166 uiBlockEndAlign(block);
2168 /* length parameters */
2169 uiBlockBeginAlign(block);
2170 sprintf(str, "Length Fit%%t|Fixed Count%%x%d|Fixed Length%%x%d"
2171 "|Fit To Curve Length%%x%d",
2172 MOD_ARR_FIXEDCOUNT, MOD_ARR_FITLENGTH, MOD_ARR_FITCURVE);
2173 uiDefButI(block, MENU, B_MODIFIER_RECALC, str,
2174 lx, (cy-=19), buttonWidth, 19, &amd->fit_type,
2175 0.0, 1.0, 0, 0, "Array length calculation method");
2176 switch(amd->fit_type)
2178 case MOD_ARR_FIXEDCOUNT:
2179 uiDefButI(block, NUM, B_MODIFIER_RECALC, "Count:",
2180 lx, (cy -= 19), buttonWidth, 19, &amd->count,
2181 1, 1000, 0, 0, "Number of duplicates to make");
2183 case MOD_ARR_FITLENGTH:
2184 uiDefButF(block, NUM, B_MODIFIER_RECALC, "Length:",
2185 lx, (cy -= 19), buttonWidth, 19, &amd->length,
2187 "Length to fit array within");
2189 case MOD_ARR_FITCURVE:
2190 uiDefIDPoinBut(block, modifier_testCurveObj, ID_OB,
2191 B_CHANGEDEP, "Ob: ",
2192 lx, (cy -= 19), buttonWidth, 19, &amd->curve_ob,
2193 "Curve object to fit array length to");
2196 uiBlockEndAlign(block);
2198 /* offset parameters */
2201 uiBlockBeginAlign(block);
2202 uiDefButBitI(block, TOG, MOD_ARR_OFF_CONST, B_MODIFIER_RECALC,
2203 "Constant Offset", lx, (cy-=19), halfwidth, 19,
2204 &amd->offset_type, 0, 0, 0, 0,
2205 "Constant offset between duplicates "
2206 "(local coordinates)");
2207 uiDefButF(block, NUM, B_MODIFIER_RECALC, "X:",
2208 lx, (cy-=19), halfwidth, 19,
2210 -range, range, 10, 3,
2211 "Constant component for duplicate offsets "
2212 "(local coordinates)");
2213 uiDefButF(block, NUM, B_MODIFIER_RECALC, "Y:",
2214 lx, (cy-=19), halfwidth, 19,
2216 -range, range, 10, 3,
2217 "Constant component for duplicate offsets "
2218 "(local coordinates)");
2219 uiDefButF(block, NUM, B_MODIFIER_RECALC, "Z:",
2220 lx, (cy-=19), halfwidth, 19,
2222 -range, range, 10, 3,
2223 "Constant component for duplicate offsets "
2224 "(local coordinates)");
2225 uiBlockEndAlign(block);
2228 uiBlockBeginAlign(block);
2229 uiDefButBitI(block, TOG, MOD_ARR_OFF_RELATIVE, B_MODIFIER_RECALC,
2230 "Relative Offset", halflx, (cy-=19), halfwidth, 19,
2231 &amd->offset_type, 0, 0, 0, 0,
2232 "Offset between duplicates relative to object width "
2233 "(local coordinates)");
2234 uiDefButF(block, NUM, B_MODIFIER_RECALC, "X:",
2235 halflx, (cy-=19), halfwidth, 19,
2237 -range, range, 10, 3,
2238 "Component for duplicate offsets relative to object "
2239 "width (local coordinates)");
2240 uiDefButF(block, NUM, B_MODIFIER_RECALC, "Y:",
2241 halflx, (cy-=19), halfwidth, 19,
2243 -range, range, 10, 3,
2244 "Component for duplicate offsets relative to object "
2245 "width (local coordinates)");
2246 uiDefButF(block, NUM, B_MODIFIER_RECALC, "Z:",
2247 halflx, (cy-=19), halfwidth, 19,
2249 -range, range, 10, 3,
2250 "Component for duplicate offsets relative to object "
2251 "width (local coordinates)");
2252 uiBlockEndAlign(block);
2254 /* vertex merging parameters */
2258 uiBlockBeginAlign(block);
2259 uiDefButBitI(block, TOG, MOD_ARR_MERGE, B_MODIFIER_RECALC,
2261 lx, (cy-=19), halfwidth/2, 19, &amd->flags,
2263 "Merge vertices in adjacent duplicates");
2264 uiDefButBitI(block, TOG, MOD_ARR_MERGEFINAL, B_MODIFIER_RECALC,
2266 lx + halfwidth/2, cy, (halfwidth+1)/2, 19,
2269 "Merge vertices in first duplicate with vertices"
2270 " in last duplicate");
2271 uiDefButF(block, NUM, B_MODIFIER_RECALC, "Limit:",
2272 lx, (cy-=19), halfwidth, 19, &amd->merge_dist,
2274 "Limit below which to merge vertices");
2278 uiBlockBeginAlign(block);
2279 uiDefButBitI(block, TOG, MOD_ARR_OFF_OBJ, B_MODIFIER_RECALC,
2280 "Object Offset", halflx, (cy -= 19), halfwidth, 19,
2281 &amd->offset_type, 0, 0, 0, 0,
2282 "Add an object transformation to the total offset");
2283 uiDefIDPoinBut(block, test_obpoin_but, ID_OB, B_CHANGEDEP,
2284 "Ob: ", halflx, (cy -= 19), halfwidth, 19,
2286 "Object from which to take offset transformation");
2287 uiBlockEndAlign(block);
2290 but = uiDefIDPoinBut(block, test_meshobpoin_but, ID_OB,
2291 B_CHANGEDEP, "Start cap: ",
2292 lx, (cy -= 19), halfwidth, 19,
2294 "Mesh object to use as start cap");
2295 uiButSetCompleteFunc(but, autocomplete_meshob, (void *)ob);
2296 but = uiDefIDPoinBut(block, test_meshobpoin_but, ID_OB,
2297 B_CHANGEDEP, "End cap: ",
2298 halflx, cy, halfwidth, 19,
2300 "Mesh object to use as end cap");
2301 uiButSetCompleteFunc(but, autocomplete_meshob, (void *)ob);
2302 } else if (md->type==eModifierType_MeshDeform) {
2303 MeshDeformModifierData *mmd = (MeshDeformModifierData*) md;
2305 uiBlockBeginAlign(block);
2306 uiDefIDPoinBut(block, test_meshobpoin_but, ID_OB, B_CHANGEDEP, "Ob: ", lx, (cy-=19), buttonWidth,19, &mmd->object, "Mesh object to be use as cage");
2307 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");
2308 uiButSetCompleteFunc(but, autocomplete_vgroup, (void *)ob);
2309 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");
2311 uiBlockBeginAlign(block);
2313 but= uiDefBut(block, BUT, B_MODIFIER_RECALC, "Unbind", lx,(cy-=24), buttonWidth,19, 0, 0, 0, 0, 0, "Unbind mesh from cage");
2314 uiButSetFunc(but,modifiers_bindMeshDeform,ob,md);
2317 but= uiDefBut(block, BUT, B_MODIFIER_RECALC, "Bind", lx,(cy-=24), buttonWidth,19, 0, 0, 0, 0, 0, "Bind mesh to cage");
2318 uiButSetFunc(but,modifiers_bindMeshDeform,ob,md);
2319 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");
2320 uiDefButBitS(block, TOG, MOD_MDEF_DYNAMIC_BIND, B_MODIFIER_RECALC, "Dynamic", lx+(buttonWidth+1)/2 + 20, (cy-=19), buttonWidth/2 - 20,19, &mmd->flag, 0.0, 31.0, 0, 0, "Invert vertex group influence");
2322 uiBlockEndAlign(block);
2323 } else if (md->type==eModifierType_ParticleSystem) {
2324 uiDefBut(block, LABEL, 1, "See Particle buttons.", lx, (cy-=19), buttonWidth,19, NULL, 0.0, 0.0, 0, 0, "");
2325 } else if (md->type==eModifierType_ParticleInstance) {
2326 ParticleInstanceModifierData *pimd = (ParticleInstanceModifierData*) md;
2327 uiDefIDPoinBut(block, test_obpoin_but, ID_OB, B_CHANGEDEP, "Ob: ", lx, (cy -= 19), buttonWidth, 19, &pimd->ob, "Object that has the particlesystem");
2328 uiDefButS(block, NUM, B_MODIFIER_RECALC, "PSYS:", lx, (cy -= 19), buttonWidth, 19, &pimd->psys, 1, 10, 10, 3, "Particlesystem number in the object");
2329 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");
2330 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");
2331 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");
2332 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");
2333 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");
2334 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");
2335 } else if (md->type==eModifierType_Explode) {
2336 ExplodeModifierData *emd = (ExplodeModifierData*) md;
2338 char *menustr= get_vertexgroup_menustr(ob);
2339 int defCount=BLI_countlist(&ob->defbase);
2340 if(defCount==0) emd->vgroup=0;
2342 but=uiDefButS(block, MENU, B_MODIFIER_RECALC, menustr, lx, (cy-=19), buttonWidth/2,19, &emd->vgroup, 0, defCount, 0, 0, "Protect this vertex group");
2343 uiButSetFunc(but,modifiers_explodeFacepa,emd,0);
2346 but=uiDefButF(block, NUMSLI, B_MODIFIER_RECALC, "", lx+buttonWidth/2, cy, buttonWidth/2,19, &emd->protect, 0.0f, 1.0f, 0, 0, "Clean vertex group edges");
2347 uiButSetFunc(but,modifiers_explodeFacepa,emd,0);
2349 but=uiDefBut(block, BUT, B_MODIFIER_RECALC, "Refresh", lx, (cy-=19), buttonWidth/2,19, 0, 0, 0, 0, 0, "Recalculate faces assigned to particles");
2350 uiButSetFunc(but,modifiers_explodeFacepa,emd,0);
2352 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");
2353 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");
2354 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");
2355 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");
2358 uiBlockEndAlign(block);
2368 uiBlockSetCol(block, color);
2369 /* roundbox 4 free variables: corner-rounding, nop, roundbox type, shade */
2370 uiDefBut(block, ROUNDBOX, 0, "", x-10, y, width, 20, NULL, 5.0, 0.0, 15, 40, "");
2371 uiBlockSetCol(block, TH_AUTO);
2373 sprintf(str, "Modifier Error: %s", md->error);
2374 uiDefBut(block, LABEL, B_NOP, str, x+15, y+15, width-35, 19, NULL, 0.0, 0.0, 0.0, 0.0, "");
2385 static void editing_panel_modifiers(Object *ob)
2390 int xco, yco, i, lastCageIndex, cageIndex = modifiers_getCageIndex(ob, &lastCageIndex);
2392 block= uiNewBlock(&curarea->uiblocks, "editing_panel_modifiers", UI_EMBOSS, UI_HELV, curarea->win);
2393 if( uiNewPanel(curarea, block, "Modifiers", "Editing", 640, 0, 318, 204)==0) return;
2395 uiSetButLock(object_data_is_libdata(ob), ERROR_LIBDATA_MESSAGE);
2396 uiNewPanelHeight(block, 204);
2398 uiDefBlockBut(block, modifiers_add_menu, ob, "Add Modifier", 0, 190, 130, 20, "Add a new modifier");
2400 sprintf(str, "To: %s", ob->id.name+2);
2401 uiDefBut(block, LABEL, 1, str, 140, 190, 150, 20, NULL, 0.0, 0.0, 0, 0, "Object whose modifier stack is being edited");
2406 md = modifiers_getVirtualModifierList(ob);
2408 for (i=0; md; i++, md=md->next) {
2409 draw_modifier(block, ob, md, &xco, &yco, i, cageIndex, lastCageIndex);
2410 if (md->mode&eModifierMode_Virtual) i--;
2413 if(yco < 0) uiNewPanelHeight(block, 204-yco);
2416 static char *make_key_menu(Key *key, int startindex)
2420 char *str, item[64];
2422 for (kb = key->block.first; kb; kb=kb->next, index++);
2423 str= MEM_mallocN(index*40, "key string");
2427 for (kb = key->block.first; kb; kb=kb->next, index++) {
2428 sprintf (item, "|%s%%x%d", kb->name, index);
2435 static void editing_panel_shapes(Object *ob)
2443 block= uiNewBlock(&curarea->uiblocks, "editing_panel_shapes", UI_EMBOSS, UI_HELV, curarea->win);
2444 uiNewPanelTabbed("Modifiers", "Editing");
2445 if( uiNewPanel(curarea, block, "Shapes", "Editing", 640, 0, 318, 204)==0) return;
2447 /* Todo check data is library here */
2448 uiSetButLock(object_data_is_libdata(ob), ERROR_LIBDATA_MESSAGE);
2450 uiDefBut(block, BUT, B_ADDKEY, "Add Shape Key" , 10, 180, 150, 20, NULL, 0.0, 0.0, 0, 0, "Add new Shape Key");
2452 key= ob_get_key(ob);
2454 /* label aligns add button */
2455 uiDefBut(block, LABEL, 0, "", 170, 180,140,20, NULL, 0, 0, 0, 0, "");
2459 uiDefButS(block, TOG, B_RELKEY, "Relative", 170, 180,140,20, &key->type, 0, 0, 0, 0, "Makes Shape Keys relative");
2461 kb= BLI_findlink(&key->block, ob->shapenr-1);
2464 kb= key->block.first;
2467 uiBlockBeginAlign(block);
2468 if(ob->shapeflag & OB_SHAPE_LOCK) icon= ICON_PIN_HLT; else icon= ICON_PIN_DEHLT;
2469 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");
2470 if(kb->flag & KEYBLOCK_MUTE) icon= ICON_MUTE_IPO_ON; else icon = ICON_MUTE_IPO_OFF;
2471 uiDefIconButBitS(block, TOG, KEYBLOCK_MUTE, B_MODIFIER_RECALC, icon, 35,150,20,20, &kb->flag, 0, 0, 0, 0, "Mute the current Shape");
2472 uiSetButLock(G.obedit==ob, "Unable to perform in EditMode");
2473 uiDefIconBut(block, BUT, B_PREVKEY, ICON_TRIA_LEFT, 55,150,20,20, NULL, 0, 0, 0, 0, "Previous Shape Key");
2474 strp= make_key_menu(key, 1);
2475 uiDefButS(block, MENU, B_SETKEY, strp, 75,150,20,20, &ob->shapenr, 0, 0, 0, 0, "Browse existing choices");
2478 uiDefIconBut(block, BUT, B_NEXTKEY, ICON_TRIA_RIGHT, 95,150,20,20, NULL, 0, 0, 0, 0, "Next Shape Key");
2480 uiDefBut(block, TEX, B_NAMEKEY, "", 115, 150, 170, 20, kb->name, 0.0, 31.0, 0, 0, "Current Shape Key name");
2481 uiDefIconBut(block, BUT, B_DELKEY, ICON_X, 285,150,25,20, 0, 0, 0, 0, 0, "Deletes current Shape Key");
2482 uiBlockEndAlign(block);
2484 if(key->type && (ob->shapeflag & OB_SHAPE_LOCK)==0 && ob->shapenr!=1) {
2485 uiBlockBeginAlign(block);
2486 make_rvk_slider(block, ob, ob->shapenr-1, 10, 120, 150, 20, "Key value, when used it inserts an animation curve point");
2487 uiDefButF(block, NUM, B_REDR, "Min ", 160,120, 75, 20, &kb->slidermin, -10.0, 10.0, 100, 1, "Minumum for slider");
2488 uiDefButF(block, NUM, B_REDR, "Max ", 235,120, 75, 20, &kb->slidermax, -10.0, 10.0, 100, 1, "Maximum for slider");
2489 uiBlockEndAlign(block);
2491 if(key->type && ob->shapenr!=1) {
2492 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");
2494 strp= make_key_menu(key, 0);
2495 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");
2500 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");
2504 /* *************************** FONT ******************************** */
2506 static short give_vfontnr(VFont *vfont)
2511 vf= G.main->vfont.first;
2513 if(vf==vfont) return nr;
2520 static VFont *give_vfontpointer(int nr) /* nr= button */
2525 vf= G.main->vfont.first;
2527 if(tel==nr) return vf;
2531 return G.main->vfont.first;
2534 VFont *exist_vfont(char *str)
2538 vf= G.main->vfont.first;
2540 if(strcmp(vf->name, str)==0) return vf;
2546 static char *give_vfontbutstr(void)
2550 char *str, di[FILE_MAXDIR], fi[FILE_MAXFILE];
2552 vf= G.main->vfont.first;
2554 strcpy(di, vf->name);
2555 BLI_splitdirstring(di, fi);
2560 str= MEM_callocN(len+21, "vfontbutstr");
2561 strcpy(str, "FONTS %t");
2562 vf= G.main->vfont.first;
2565 if(vf->id.us==0) strcat(str, "|0 ");
2566 else strcat(str, "| ");
2568 strcpy(di, vf->name);
2569 BLI_splitdirstring(di, fi);
2577 static void load_buts_vfont(char *name)
2582 if(OBACT && OBACT->type==OB_FONT) cu= OBACT->data;
2585 vf= exist_vfont(name);
2587 vf= load_vfont(name);
2590 else id_us_plus((ID *)vf);
2592 switch(cu->curinfo.flag & CU_STYLE) {
2594 if(cu->vfontb) cu->vfontb->id.us--;
2598 if(cu->vfonti) cu->vfonti->id.us--;
2601 case (CU_BOLD|CU_ITALIC):
2602 if(cu->vfontbi) cu->vfontbi->id.us--;
2606 if(cu->vfont) cu->vfont->id.us--;
2611 DAG_object_flush_update(G.scene, OBACT, OB_RECALC_DATA);
2612 BIF_undo_push("Load vector font");
2613 allqueue(REDRAWVIEW3D, 0);
2614 allqueue(REDRAWBUTSEDIT, 0);
2617 static void set_unicode_text_fs(char *file)
2619 if (file > 0) paste_unicodeText(file);
2622 void do_fontbuts(unsigned short event)
2638 DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA);
2639 allqueue(REDRAWVIEW3D, 0);
2646 case B_STYLETOSELU: style = CU_UNDERLINE; break;
2647 case B_STYLETOSELB: style = CU_BOLD; break;
2648 case B_STYLETOSELI: style = CU_ITALIC; break;
2650 if (style_to_sel(style, ((Curve*)ob->data)->curinfo.flag & style)) {
2651 text_to_curve(ob, 0);
2652 makeDispListCurveTypes(ob, 0);
2653 allqueue(REDRAWVIEW3D, 0);
2655 allqueue(REDRAWBUTSEDIT, 0);
2660 DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA);
2661 allqueue(REDRAWVIEW3D, 0);
2666 if (cu->totbox < 256) {
2667 for (i = cu->totbox; i>cu->actbox; i--) cu->tb[i]= cu->tb[i-1];
2668 cu->tb[cu->actbox]= cu->tb[cu->actbox-1];
2671 allqueue(REDRAWBUTSEDIT, 0);
2672 allqueue(REDRAWVIEW3D, 0);
2673 text_to_curve(ob, 0);
2674 makeDispListCurveTypes(ob, 0);
2677 error("Do you really need that many text frames?");
2682 if (cu->totbox > 1) {
2683 for (i = cu->actbox-1; i < cu->totbox; i++) cu->tb[i]= cu->tb[i+1];
2686 allqueue(REDRAWBUTSEDIT, 0);
2687 allqueue(REDRAWVIEW3D, 0);
2688 text_to_curve(ob, 0);
2689 makeDispListCurveTypes(ob, 0);
2696 vf= give_vfontpointer(G.buts->texnr);
2697 if(vf && vf->id.prev!=vf->id.next) strcpy(str, vf->name);
2698 else strcpy(str, U.fontdir);
2700 sa= closest_bigger_area();
2701 areawinset(sa->win);
2703 activate_fileselect(FILE_LOADFONT, "SELECT FONT", str, load_buts_vfont);
2709 if(cu && cu->vfont) {
2710 if (cu->vfont->packedfile) {
2711 if (G.fileflags & G_AUTOPACK) {
2712 if (okee("Disable AutoPack ?")) {
2713 G.fileflags &= ~G_AUTOPACK;
2717 if ((G.fileflags & G_AUTOPACK) == 0) {
2718 if (unpackVFont(cu->vfont, PF_ASK) == RET_OK) {
2719 DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA);
2720 allqueue(REDRAWVIEW3D, 0);
2724 cu->vfont->packedfile = newPackedFile(cu->vfont->name);
2728 allqueue(REDRAWHEADERS, 0);
2729 allqueue(REDRAWBUTSEDIT, 0);
2733 if (!G.obedit) { error("Only in editmode!"); return; }
2734 if (G.obedit->type != OB_FONT) return;
2735 activate_fileselect(FILE_SPECIAL, "Open Text File", G.sce, load_3dtext_fs);
2739 if (!G.obedit) { error("Only in editmode!"); return; }
2740 if (G.obedit->type != OB_FONT) return;
2749 vf= give_vfontpointer(G.buts->texnr);
2751 id_us_plus((ID *)vf);
2753 switch(cu->curinfo.flag & CU_STYLE) {
2755 cu->vfontb->id.us--;
2759 cu->vfonti->id.us--;
2762 case (CU_BOLD|CU_ITALIC):
2763 cu->vfontbi->id.us--;
2771 DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA);
2773 BIF_undo_push("Set vector font");
2774 allqueue(REDRAWVIEW3D, 0);
2775 allqueue(REDRAWBUTSEDIT, 0);
2785 if(G.charstart > (0xffff - 12*6))
2786 G.charstart = 0xffff - (12*6);
2787 allqueue(REDRAWBUTSEDIT, 0);
2791 G.charstart = G.charstart - (12*6);
2794 if(G.charstart < G.charmin)
2795 G.charstart = G.charmin;
2796 allqueue(REDRAWBUTSEDIT, 0);
2800 // Create new dynamic string
2801 ds = BLI_dynstr_new();
2803 // Fill the dynamic string with entries
2806 BLI_dynstr_append(ds, "|");
2807 BLI_dynstr_append(ds, uctabname[i].name);
2810 // Create the menu string from dyn string
2811 ctmenu = BLI_dynstr_get_cstring(ds);
2813 // Call the popup menu
2814 ctevt = pupmenu_col(ctmenu, 40);
2815 G.charstart = uctabname[ctevt-1].start;
2816 G.charmin = uctabname[ctevt-1].start;
2817 G.charmax = uctabname[ctevt-1].end;
2820 BLI_dynstr_free(ds);
2824 allqueue(REDRAWVIEW3D, 0);
2825 allqueue(REDRAWBUTSEDIT, 0);
2830 G.charstart = G.charstart + (12*6);
2831 if(G.charstart > (0xffff - 12*6))
2832 G.charstart = 0xffff - (12*6);
2833 if(G.charstart > G.charmax - 12*6)
2834 G.charstart = G.charmax - 12*6;
2835 allqueue(REDRAWBUTSEDIT, 0);
2839 sa= closest_bigger_area();
2840 areawinset(sa->win);
2843 activate_fileselect(FILE_SPECIAL, "Open Text File", G.sce, set_unicode_text_fs);
2850 if(cu->textoncurve && cu->textoncurve->type!=OB_CURVE) {
2851 error("Only Curve Objects");
2853 allqueue(REDRAWBUTSEDIT, 0);
2855 DAG_scene_sort(G.scene); // makes new dag
2856 DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA);
2857 allqueue(REDRAWVIEW3D, 0);
2862 #ifdef INTERNATIONAL
2863 static void editing_panel_char_type(Object *ob, Curve *cu)
2867 block= uiNewBlock(&curarea->uiblocks, "editing_panel_char_type", UI_EMBOSS, UI_HELV, curarea->win);
2868 uiNewPanelTabbed("Font", "Editing");
2869 if(uiNewPanel(curarea, block, "Char", "Editing", 640, 0, 318, 204)==0)
2872 // Set the selected font
2873 G.selfont = cu->vfont;
2875 uiDefIconBut(block, BUT, B_SETUNITEXT, ICON_TEXT, 0,210,20,20, 0, 0, 0, 0, 0, "Load Unicode Text file");
2877 // Unicode categorization selection button
2878 uiDefBut(block, BUT, B_SETCAT, "Unicode Table", 22,210,226,20, 0, 0, 0, 0, 0, "Select Unicode Table");
2879 uiDefButI(block, NUM, /*B_SETUPCHAR*/ 0, "", 250,210,50,20, &G.charstart, 0, 0xffff, 0, 0, "UT");
2881 // Character selection button
2882 uiDefBut(block, CHARTAB, B_SETCHAR, "", 0, 0, 264, 200, 0, 0, 0, 0, 0, "Select character");
2884 // Buttons to change the max, min
2885 uiDefButI(block, BUT, B_SETUPCHAR, "U", 280, 185, 15, 15, &G.charstart, 0, 0xffff, 0, 0, "Scroll character table up");
2886 uiDefButI(block, BUT, B_SETDOWNCHAR, "D", 280, 0, 15, 15, &G.charstart, 0, 0xffff, 0, 0, "Scroll character table down");
2890 static void editing_panel_font_type(Object *ob, Curve *cu)
2894 static int packdummy = 0;
2897 block= uiNewBlock(&curarea->uiblocks, "editing_panel_font_type", UI_EMBOSS, UI_HELV, curarea->win);
2898 if(uiNewPanel(curarea, block, "Font", "Editing", 640, 0, 470, 204)==0) return;
2900 switch(cu->curinfo.flag & CU_STYLE) {
2902 G.buts->texnr= give_vfontnr(cu->vfontb);
2905 G.buts->texnr= give_vfontnr(cu->vfonti);
2907 case (CU_BOLD|CU_ITALIC):
2908 G.buts->texnr= give_vfontnr(cu->vfontbi);
2911 G.buts->texnr= give_vfontnr(cu->vfont);
2915 strp= give_vfontbutstr();
2916 // vfd= cu->vfont->data;
2918 uiDefBut(block, BUT,B_LOADFONT, "Load", 480,188,68,20, 0, 0, 0, 0, 0, "Load a new font");
2919 uiDefButS(block, MENU, B_SETFONT, strp, 550,188,220,20, &G.buts->texnr, 0, 0, 0, 0, "Change font for object");
2921 if (cu->vfont->packedfile) {
2926 uiDefIconButI(block, TOG|BIT|0, B_PACKFONT, ICON_PACKAGE, 772,188,20,20, &packdummy, 0, 0, 0, 0, "Pack/Unpack this font");
2928 /* This doesn't work anyway */
2929 // uiDefBut(block, LABEL, 0, vfd->name, 480, 165,314,20, 0, 0, 0, 0, 0, "Postscript name of the font");
2931 uiDefBut(block, BUT, B_LOAD3DTEXT, "Insert Text", 480, 165, 90, 20, 0, 0, 0, 0, 0, "Insert text file at cursor");
2932 uiDefBut(block, BUT, B_LOREM, "Lorem", 575, 165, 70, 20, 0, 0, 0, 0, 0, "Insert a paragraph of Lorem Ipsum at cursor");
2933 uiDefButC(block, TOG|BIT|2,B_STYLETOSELU, "U", 727,165,20,20, &(cu->curinfo.flag), 0,0, 0, 0, "");
2934 uiBlockBeginAlign(block);
2935 uiDefButBitC(block, TOG, CU_BOLD, B_STYLETOSELB, "B", 752,165,20,20, &(cu->curinfo.flag), 0,0, 0, 0, "");
2936 uiDefButBitC(block, TOG, CU_ITALIC, B_STYLETOSELI, "i", 772,165,20,20, &(cu->curinfo.flag), 0, 0, 0, 0, "");
2937 uiBlockEndAlign(block);