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_camera_types.h"
52 #include "DNA_constraint_types.h"
53 #include "DNA_curve_types.h"
54 #include "DNA_effect_types.h"
55 #include "DNA_group_types.h"
56 #include "DNA_image_types.h"
57 #include "DNA_key_types.h"
58 #include "DNA_lamp_types.h"
59 #include "DNA_lattice_types.h"
60 #include "DNA_material_types.h"
61 #include "DNA_meta_types.h"
62 #include "DNA_mesh_types.h"
63 #include "DNA_meshdata_types.h"
64 #include "DNA_modifier_types.h"
65 #include "DNA_object_types.h"
66 #include "DNA_object_force.h"
67 #include "DNA_radio_types.h"
68 #include "DNA_screen_types.h"
69 #include "DNA_texture_types.h"
70 #include "DNA_userdef_types.h"
71 #include "DNA_vfont_types.h"
72 #include "DNA_view3d_types.h"
73 #include "DNA_world_types.h"
74 #include "DNA_packedFile_types.h"
76 #include "BKE_depsgraph.h"
77 #include "BKE_global.h"
78 #include "BKE_curve.h"
79 #include "BKE_library.h"
81 #include "BKE_modifier.h"
82 #include "BKE_packedFile.h"
83 #include "BKE_scene.h"
85 #include "BLI_blenlib.h"
86 #include "BLI_arithb.h"
87 #include "BLI_vfontdata.h"
88 #include "BLI_editVert.h"
90 #include "BSE_filesel.h"
93 #include "BIF_editarmature.h"
94 #include "BIF_editconstraint.h"
95 #include "BIF_editdeform.h"
96 #include "BIF_editfont.h"
97 #include "BIF_editmesh.h"
98 #include "BIF_interface.h"
99 #include "BIF_meshtools.h"
100 #include "BIF_mywindow.h"
101 #include "BIF_renderwin.h"
102 #include "BIF_resources.h"
103 #include "BIF_screen.h"
104 #include "BIF_scrarea.h"
105 #include "BIF_space.h"
106 #include "BIF_toets.h"
107 #include "BIF_toolbox.h"
108 #include "BIF_previewrender.h"
109 #include "BIF_butspace.h"
111 #include "mydevice.h"
114 #include "BKE_action.h"
115 #include "BKE_anim.h"
116 #include "BKE_armature.h"
117 #include "BKE_constraint.h"
118 #include "BKE_curve.h"
119 #include "BKE_displist.h"
120 #include "BKE_DerivedMesh.h"
121 #include "BKE_effect.h"
122 #include "BKE_font.h"
123 #include "BKE_image.h"
125 #include "BKE_lattice.h"
126 #include "BKE_material.h"
127 #include "BKE_mball.h"
128 #include "BKE_mesh.h"
129 #include "BKE_object.h"
130 #include "BKE_texture.h"
131 #include "BKE_utildefines.h"
133 #include "BDR_drawobject.h"
134 #include "BDR_editcurve.h"
135 #include "BDR_editface.h"
136 #include "BDR_editobject.h"
137 #include "BDR_vpaint.h"
138 #include "BDR_unwrapper.h"
140 #include "BSE_drawview.h"
141 #include "BSE_editipo.h"
142 #include "BSE_edit.h"
143 #include "BSE_filesel.h"
144 #include "BSE_headerbuttons.h"
145 #include "BSE_trans_types.h"
146 #include "BSE_view.h"
147 #include "BSE_buttons.h"
148 #include "BSE_seqaudio.h"
150 #include "RE_renderconverter.h" // make_sticky
152 #include "butspace.h" // own module
154 static short degr= 90, step= 9, turn= 1;
155 static float extr_offs= 1.0;
156 static float editbutweight=1.0;
157 short editbutflag= 1;
158 float doublimit= 0.001, editbutvweight=1;
159 float uv_calc_radius= 1.0, uv_calc_cubesize= 1.0;
160 short uv_calc_mapdir= 1, uv_calc_mapalign= 1, facesel_draw_edges= 0;
162 extern ListBase editNurb;
165 /* *************************** static functions prototypes ****************** */
166 VFont *exist_vfont(char *str);
168 /* *************** */
170 void do_common_editbuts(unsigned short event) // old name, is a mix of object and editing events....
172 EditMesh *em = G.editMesh;
181 int a, bit, index= -1;
186 if(G.obedit && G.obedit->actcol>0) {
187 if(G.obedit->type == OB_MESH) {
188 efa= em->faces.first;
190 if(efa->f & SELECT) {
191 if(index== -1) index= efa->mat_nr;
192 else if(index!=efa->mat_nr) {
193 error("Mixed colors");
200 else if ELEM(G.obedit->type, OB_CURVE, OB_SURF) {
203 if( isNurbsel(nu) ) {
204 if(index== -1) index= nu->mat_nr;
205 else if(index!=nu->mat_nr) {
206 error("Mixed colors");
214 G.obedit->actcol= index+1;
215 scrarea_queue_winredraw(curarea);
220 new_material_to_objectdata((G.scene->basact) ? (G.scene->basact->object) : 0);
221 scrarea_queue_winredraw(curarea);
222 BIF_undo_push("New material");
223 allqueue(REDRAWBUTSSHADING, 0);
224 allqueue(REDRAWVIEW3D_Z, 0);
225 allqueue(REDRAWOOPS, 0);
228 delete_material_index();
229 scrarea_queue_winredraw(curarea);
230 BIF_undo_push("Delete material index");
231 allqueue(REDRAWBUTSSHADING, 0);
232 allqueue(REDRAWVIEW3D_Z, 0);
233 allqueue(REDRAWOOPS, 0);
236 if(G.obedit && G.obedit->actcol>0) {
237 if(G.obedit->type == OB_MESH) {
238 efa= em->faces.first;
241 efa->mat_nr= G.obedit->actcol-1;
245 else if ELEM(G.obedit->type, OB_CURVE, OB_SURF) {
249 nu->mat_nr= nu->charidx= G.obedit->actcol-1;
253 else if (G.obedit->type == OB_FONT) {
255 allqueue(REDRAWVIEW3D, 0);
258 allqueue(REDRAWVIEW3D_Z, 0);
259 DAG_object_flush_update(G.scene, G.obedit, OB_RECALC_DATA);
260 BIF_undo_push("Assign material index");
266 if(G.obedit->type == OB_MESH) {
267 if (event==B_MATSEL) {
268 editmesh_select_by_material(G.obedit->actcol-1);
270 editmesh_deselect_by_material(G.obedit->actcol-1);
272 allqueue(REDRAWVIEW3D, 0);
274 else if ELEM(G.obedit->type, OB_CURVE, OB_SURF) {
277 if(nu->mat_nr==G.obedit->actcol-1) {
283 if(event==B_MATSEL) {
298 a= nu->pntsu*nu->pntsv;
302 if(event==B_MATSEL) bp->f1 |= 1;
311 BIF_undo_push("Select material index");
312 allqueue(REDRAWVIEW3D, 0);
318 if(G.obedit->type == OB_MESH) hide_mesh(0);
319 else if ELEM(G.obedit->type, OB_CURVE, OB_SURF) hideNurb(0);
324 if(G.obedit->type == OB_MESH) reveal_mesh();
325 else if ELEM(G.obedit->type, OB_CURVE, OB_SURF) revealNurb();
327 else if(G.f & G_FACESELECT) reveal_tface();
332 if(G.obedit->type == OB_MESH) selectswap_mesh();
333 else if ELEM(G.obedit->type, OB_CURVE, OB_SURF) selectswapNurb();
338 if(ob && G.obedit==0) {
339 if(ELEM3(ob->type, OB_CURVE, OB_SURF, OB_FONT)) tex_space_curve(ob->data);
348 case B_DOCENTRECURSOR:
354 if(G.obedit->type == OB_MESH) {
355 efa= em->faces.first;
357 if(efa->f & SELECT) {
358 if(event==B_SETSMOOTH) efa->flag |= ME_SMOOTH;
359 else efa->flag &= ~ME_SMOOTH;
368 if(event==B_SETSMOOTH) nu->flag |= CU_SMOOTH;
369 else nu->flag &= ~CU_SMOOTH;
374 DAG_object_flush_update(G.scene, G.obedit, OB_RECALC_DATA);
375 allqueue(REDRAWVIEW3D, 0);
380 if(TESTBASELIB(base)) {
381 if(base->object->type==OB_MESH) {
382 mesh_set_smooth_flag(base->object, (event==B_SETSMOOTH));
384 else if ELEM(base->object->type, OB_SURF, OB_CURVE) {
385 cu= base->object->data;
388 if(event==B_SETSMOOTH) nu->flag |= ME_SMOOTH;
389 else nu->flag &= ~ME_SMOOTH;
392 makeDispListCurveTypes(base->object, 0);
397 allqueue(REDRAWVIEW3D, 0);
399 if(event == B_SETSMOOTH) BIF_undo_push("Set Smooth");
400 else BIF_undo_push("Set Solid");
404 DAG_scene_sort(G.scene); // makes new dag
406 if(ob) ob->recalc |= OB_RECALC;
407 allqueue(REDRAWVIEW3D, 0);
410 if(event>=B_OBLAY && event<=B_OBLAY+31) {
411 local= BASACT->lay & 0xFF000000;
412 BASACT->lay -= local;
413 if(BASACT->lay==0 || (G.qual & LR_SHIFTKEY)==0) {
416 scrarea_queue_winredraw(curarea);
418 BASACT->lay += local;
420 if( (OBACT->lay & G.vd->lay) && (BASACT->lay & G.vd->lay) );
421 else if( (OBACT->lay & G.vd->lay)==0 && (BASACT->lay & G.vd->lay)==0 );
422 else allqueue(REDRAWVIEW3D, 0);
424 OBACT->lay= BASACT->lay;
430 /* *************************** MESH ******************************** */
433 static void editing_panel_mesh_type(Object *ob, Mesh *me)
438 block= uiNewBlock(&curarea->uiblocks, "editing_panel_mesh_type", UI_EMBOSS, UI_HELV, curarea->win);
439 if( uiNewPanel(curarea, block, "Mesh", "Editing", 320, 0, 318, 204)==0) return;
441 uiBlockBeginAlign(block);
442 uiDefButBitS(block, TOG, ME_AUTOSMOOTH, REDRAWVIEW3D, "Auto Smooth",10,180,154,19, &me->flag, 0, 0, 0, 0, "Treats all set-smoothed faces with angles less than Degr: as 'smooth' during render");
443 uiDefButS(block, NUM, B_DIFF, "Degr:", 10,160,154,19, &me->smoothresh, 1, 80, 0, 0, "Defines maximum angle between face normals that 'Auto Smooth' will operate on");
445 uiBlockBeginAlign(block);
446 uiBlockSetCol(block, TH_AUTO);
448 if(me->medge) val= 1.0; else val= 0.0;
449 uiDefBut(block, LABEL, 0, "Edges", 10,70,70,20, 0, val, 0, 0, 0, "");
450 if(me->medge==NULL) {
451 uiDefBut(block, BUT, B_MAKEEDGES, "Make", 80,70,84,19, 0, 0, 0, 0, 0, "Adds edges data to active Mesh, enables creases/seams and faster wireframe draw");
453 else uiDefBut(block, BUT, B_DELEDGES, "Delete", 80,70,84,19, 0, 0, 0, 0, 0, "Deletes edges data from active Mesh");
455 if(me->mcol) val= 1.0; else val= 0.0;
456 uiDefBut(block, LABEL, 0, "VertCol", 10,50,70,20, 0, val, 0, 0, 0, "");
458 uiDefBut(block, BUT, B_MAKEVERTCOL, "Make", 80,50,84,19, 0, 0, 0, 0, 0, "Enables vertex colour painting on active Mesh");
460 else uiDefBut(block, BUT, B_DELVERTCOL, "Delete", 80,50,84,19, 0, 0, 0, 0, 0, "Deletes vertex colours on active Mesh");
462 if(me->tface) val= 1.0; else val= 0.0;
463 uiDefBut(block, LABEL, 0, "TexFace", 10,30,70,20, 0, val, 0, 0, 0, "");
464 if(me->tface==NULL) {
465 uiDefBut(block, BUT, B_MAKE_TFACES, "Make", 80,30,84,19, 0, 0, 0, 0, 0, "Enables the active Mesh's faces for UV coordinate mapping");
467 else uiDefBut(block, BUT, B_DEL_TFACES, "Delete", 80,30,84,19, 0, 0, 0, 0, 0, "Deletes UV coordinates for active Mesh's faces");
469 if(me->msticky) val= 1.0; else val= 0.0;
470 uiDefBut(block, LABEL, 0, "Sticky", 10,10,70,20, 0, val, 0, 0, 0, "");
471 if(me->msticky==NULL) {
472 uiDefBut(block, BUT, B_MAKESTICKY, "Make", 80,10,84,19, 0, 0, 0, 0, 0, "Creates Sticky coordinates for the active Mesh from the current camera view background picture");
474 else uiDefBut(block, BUT, B_DELSTICKY, "Delete", 80,10,84,19, 0, 0, 0, 0, 0, "Deletes Sticky texture coordinates");
476 uiBlockEndAlign(block);
478 uiDefIDPoinBut(block, test_meshpoin_but, 0, "TexMesh: ", 175,124,230,19, &me->texcomesh, "Enter the name of a Meshblock");
481 uiBlockBeginAlign(block);
482 uiDefButS(block, NUM, B_DIFF, "Slurph:", 175,95,95,19, &(me->key->slurph), -500.0, 500.0, 0, 0, "");
483 uiDefButS(block, TOG, B_RELKEY, "Relative Keys", 175,75,95,19, &me->key->type, 0, 0, 0, 0, "");
486 uiBlockBeginAlign(block);
487 uiDefBut(block, BUT, B_SLOWERDRAW,"SlowerDraw", 175,30,95,19, 0, 0, 0, 0, 0, "Displays the active object with all possible edges shown");
488 uiDefBut(block, BUT, B_FASTERDRAW,"FasterDraw", 175,10,95,19, 0, 0, 0, 0, 0, "Displays the active object faster by omitting some edges when drawing");
490 uiBlockBeginAlign(block);
491 uiDefBut(block, BUT,B_DOCENTRE, "Centre", 275, 95, 130, 19, 0, 0, 0, 0, 0, "Shifts object data to be centered about object's origin");
492 uiDefBut(block, BUT,B_DOCENTRENEW, "Centre New", 275, 75, 130, 19, 0, 0, 0, 0, 0, "Shifts object's origin to center of object data");
493 uiDefBut(block, BUT,B_DOCENTRECURSOR, "Centre Cursor", 275, 55, 130, 19, 0, 0, 0, 0, 0, "Shifts object's origin to cursor location");
495 uiBlockBeginAlign(block);
496 uiDefButBitS(block, TOG, ME_TWOSIDED, REDRAWVIEW3D, "Double Sided", 275,30,130,19, &me->flag, 0, 0, 0, 0, "Toggles selected faces as doublesided or single-sided");
497 uiDefButBitS(block, TOG, ME_NOPUNOFLIP, REDRAWVIEW3D, "No V.Normal Flip",275,10,130,19, &me->flag, 0, 0, 0, 0, "Disables flipping of vertexnormals during render");
498 uiBlockEndAlign(block);
502 /* *************************** MODIFIERS ******************************** */
504 void do_modifier_panels(unsigned short event)
509 case B_MODIFIER_REDRAW:
510 allqueue(REDRAWBUTSEDIT, 0);
511 allqueue(REDRAWOOPS, 0);
514 case B_MODIFIER_RECALC:
515 ob->softflag |= OB_SB_RESET;
516 allqueue(REDRAWBUTSEDIT, 0);
517 allqueue(REDRAWVIEW3D, 0);
518 allqueue(REDRAWIMAGE, 0);
519 allqueue(REDRAWOOPS, 0);
520 DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA);
525 static void modifiers_add(void *ob_v, int type)
528 ModifierTypeInfo *mti = modifierType_getInfo(type);
530 if (mti->flags&eModifierTypeFlag_RequiresOriginalData) {
531 ModifierData *md = ob->modifiers.first;
533 while (md && modifierType_getInfo(md->type)->type==eModifierTypeType_OnlyDeform) {
537 BLI_insertlinkbefore(&ob->modifiers, md, modifier_new(type));
539 BLI_addtail(&ob->modifiers, modifier_new(type));
542 BIF_undo_push("Add modifier");
545 static uiBlock *modifiers_add_menu(void *ob_v)
551 block= uiNewBlock(&curarea->uiblocks, "modifier_add_menu", UI_EMBOSSP, UI_HELV, curarea->win);
552 uiBlockSetButmFunc(block, modifiers_add, ob);
554 for (i=eModifierType_None+1; i<NUM_MODIFIER_TYPES; i++) {
555 ModifierTypeInfo *mti = modifierType_getInfo(i);
557 /* Only allow adding through appropriate other interfaces */
558 if (ELEM(i, eModifierType_Softbody, eModifierType_Hook)) continue;
560 if ( (mti->flags&eModifierTypeFlag_AcceptsCVs) ||
561 (ob->type==OB_MESH && (mti->flags&eModifierTypeFlag_AcceptsMesh))) {
562 uiDefBut(block, BUTM, B_MODIFIER_RECALC, mti->name, 0, yco-=20, 160, 19, NULL, 0, 0, 1, i, "");
566 uiTextBoundsBlock(block, 50);
567 uiBlockSetDirection(block, UI_DOWN);
572 static void modifiers_del(void *ob_v, void *md_v)
577 /* It seems on rapid delete it is possible to
578 * get called twice on same modifier, so make
579 * sure it is in list.
581 for (md=ob->modifiers.first; md; md=md->next)
588 BLI_remlink(&ob->modifiers, md_v);
592 BIF_undo_push("Del modifier");
595 static void modifiers_moveUp(void *ob_v, void *md_v)
598 ModifierData *md = md_v;
601 ModifierTypeInfo *mti = modifierType_getInfo(md->type);
603 if (mti->type!=eModifierTypeType_OnlyDeform) {
604 ModifierTypeInfo *nmti = modifierType_getInfo(md->prev->type);
606 if (nmti->flags&eModifierTypeFlag_RequiresOriginalData) {
607 error("Cannot move above a modifier requiring original data.");
612 BLI_remlink(&ob->modifiers, md);
613 BLI_insertlink(&ob->modifiers, md->prev->prev, md);
616 BIF_undo_push("Move modifier");
619 static void modifiers_moveDown(void *ob_v, void *md_v)
622 ModifierData *md = md_v;
625 ModifierTypeInfo *mti = modifierType_getInfo(md->type);
627 if (mti->flags&eModifierTypeFlag_RequiresOriginalData) {
628 ModifierTypeInfo *nmti = modifierType_getInfo(md->next->type);
630 if (nmti->type!=eModifierTypeType_OnlyDeform) {
631 error("Cannot move beyond a non-deforming modifier.");
636 BLI_remlink(&ob->modifiers, md);
637 BLI_insertlink(&ob->modifiers, md->next, md);
640 BIF_undo_push("Move modifier");
643 static void modifier_testLatticeObj(char *name, ID **idpp)
647 for (id= G.main->object.first; id; id= id->next) {
648 if( strcmp(name, id->name+2)==0 ) {
649 if (((Object *)id)->type != OB_LATTICE) {
650 error ("Lattice deform object must be a lattice");
660 static void modifier_testCurveObj(char *name, ID **idpp)
664 for (id= G.main->object.first; id; id= id->next) {
665 if( strcmp(name, id->name+2)==0 ) {
666 if (((Object *)id)->type != OB_CURVE) {
667 error ("Curve deform object must be a curve");
677 static void modifier_testArmatureObj(char *name, ID **idpp)
681 for (id= G.main->object.first; id; id= id->next) {
682 if( strcmp(name, id->name+2)==0 ) {
683 if (((Object *)id)->type != OB_ARMATURE) {
684 error ("Armature deform object must be an armature");
694 static void modifiers_applyModifier(void *obv, void *mdv)
697 ModifierData *md = mdv;
704 error("Modifiers cannot be applied in editmode");
706 } else if (((ID*) ob->data)->us>1) {
707 error("Modifiers cannot be applied to multi-user data");
711 if (md!=ob->modifiers.first) {
712 if (!okee("Modifier is not first"))
716 if (ob->type==OB_MESH) {
717 dm = mesh_create_derived_for_modifier(ob, md);
719 error("Modifier is disabled or returned error, skipping apply");
723 dlm= dm->convertToDispListMesh(dm, 0);
725 if ((!me->tface || dlm->tface) || okee("Applying will delete mesh UVs and vertex colors")) {
726 if ((!me->mcol || dlm->mcol) || okee("Applying will delete mesh vertex colors")) {
727 if (dlm->totvert==me->totvert || okee("Applying will delete mesh sticky, keys, and vertex groups")) {
728 displistmesh_to_mesh(dlm, me);
735 displistmesh_free(dlm);
739 else if (ELEM(ob->type, OB_CURVE, OB_SURF)) {
740 ModifierTypeInfo *mti = modifierType_getInfo(md->type);
741 Curve *cu = ob->data;
743 float (*vertexCos)[3];
745 if (!okee("Apply will only change CV points, not tesselated/bevel vertices"))
748 if (!(md->mode&eModifierMode_Realtime) || (mti->isDisabled && mti->isDisabled(md))) {
749 error("Modifier is disabled, skipping apply");
753 vertexCos = curve_getVertexCos(cu, &cu->nurb, &numVerts);
754 mti->deformVerts(md, ob, NULL, vertexCos, numVerts);
755 curve_applyVertexCos(cu, &cu->nurb, vertexCos);
756 MEM_freeN(vertexCos);
758 DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA);
761 error("Cannot apply modifier for this object type");
766 BLI_remlink(&ob->modifiers, md);
769 BIF_undo_push("Apply modifier");
773 static void modifiers_copyModifier(void *ob_v, void *md_v)
776 ModifierData *md = md_v;
777 ModifierData *nmd = modifier_new(md->type);
779 modifier_copyData(md, nmd);
781 BLI_insertlink(&ob->modifiers, md, nmd);
783 BIF_undo_push("Copy modifier");
786 static void modifiers_setOnCage(void *ob_v, void *md_v)
791 for (md=ob->modifiers.first; md; md=md->next)
793 md->mode &= ~eModifierMode_OnCage;
796 md->mode ^= eModifierMode_OnCage;
799 static void modifiers_setSubsurfIncremental(void *ob_v, void *md_v)
802 ModifierData *md = md_v;
803 SubsurfModifierData *smd = (SubsurfModifierData*) md;
805 if ((smd->flags&eSubsurfModifierFlag_Incremental) && ob->type==OB_MESH) {
809 if (okee("Requires mesh edges, create now?")) {
816 static void modifiers_clearHookOffset(void *ob_v, void *md_v)
819 ModifierData *md = md_v;
820 HookModifierData *hmd = (HookModifierData*) md;
823 Mat4Invert(hmd->object->imat, hmd->object->obmat);
824 Mat4MulSerie(hmd->parentinv, hmd->object->imat, ob->obmat, NULL, NULL, NULL, NULL, NULL, NULL);
825 BIF_undo_push("Clear hook");
829 static void modifiers_cursorHookCenter(void *ob_v, void *md_v)
832 ModifierData *md = md_v;
833 HookModifierData *hmd = (HookModifierData*) md;
836 float *curs = give_cursor();
837 float bmat[3][3], imat[3][3];
841 Mat3CpyMat4(bmat, ob->obmat);
845 hmd->cent[0]= curs[0]-ob->obmat[3][0];
846 hmd->cent[1]= curs[1]-ob->obmat[3][1];
847 hmd->cent[2]= curs[2]-ob->obmat[3][2];
848 Mat3MulVecfl(imat, hmd->cent);
850 BIF_undo_push("Hook cursor center");
854 static void modifiers_selectHook(void *ob_v, void *md_v)
856 ModifierData *md = md_v;
857 HookModifierData *hmd = (HookModifierData*) md;
862 static void modifiers_reassignHook(void *ob_v, void *md_v)
864 ModifierData *md = md_v;
865 HookModifierData *hmd = (HookModifierData*) md;
867 int *indexar, tot = hook_getIndexArray(&indexar, cent);
870 error("Requires selected vertices");
873 MEM_freeN(hmd->indexar);
876 VECCOPY(hmd->cent, cent);
877 hmd->indexar = indexar;
882 static void modifiers_convertToReal(void *ob_v, void *md_v)
885 ModifierData *md = md_v;
886 ModifierData *nmd = modifier_new(md->type);
888 modifier_copyData(md, nmd);
889 nmd->mode &= ~eModifierMode_Virtual;
891 BLI_addhead(&ob->modifiers, nmd);
893 ob->partype = PAROBJECT;
895 BIF_undo_push("Modifier convert to real");
898 static void draw_modifier(uiBlock *block, Object *ob, ModifierData *md, int *xco, int *yco, int index, int cageIndex, int lastCageIndex)
900 ModifierTypeInfo *mti = modifierType_getInfo(md->type);
902 int isVirtual = md->mode&eModifierMode_Virtual;
903 int x = *xco, y = *yco, color = md->error?TH_REDALERT:TH_BUT_NEUTRAL;
904 int editing = (G.obedit==ob);
905 short height=26, width = 295, buttonWidth = width-120-10;
909 uiBlockSetCol(block, color);
910 /* roundbox 4 free variables: corner-rounding, nop, roundbox type, shade */
911 uiDefBut(block, ROUNDBOX, 0, "", x-10, y-4, width, 26, NULL, 7.0, 0.0,
912 md->mode&eModifierMode_Expanded?3:15, -20, "");
913 uiBlockSetCol(block, TH_AUTO);
915 /* open/close icon */
917 uiSetButLock(1, "Modifier is virtual and cannot be edited.");
918 color = TH_BUT_SETTING1;
920 uiBlockSetEmboss(block, UI_EMBOSSN);
921 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");
924 uiBlockSetEmboss(block, UI_EMBOSS);
927 sprintf(str, "%s (virtual)", md->name);
928 uiDefBut(block, LABEL, 0, str, x+10, y-1, buttonWidth-60, 19, NULL, 0.0, 0.0, 0.0, 0.0, "Modifier name");
932 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");
933 uiButSetFunc(but, modifiers_convertToReal, ob, md);
934 uiSetButLock(1, "Modifier is virtual and cannot be edited.");
936 uiBlockBeginAlign(block);
937 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");
939 /* Softbody not allowed in this situation, enforce! */
940 if (md->type!=eModifierType_Softbody || !(ob->pd && ob->pd->deflect)) {
941 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");
942 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");
943 if (mti->flags&eModifierTypeFlag_SupportsEditmode) {
944 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)");
947 uiBlockEndAlign(block);
949 uiBlockSetEmboss(block, UI_EMBOSSR);
951 if (ob->type==OB_MESH && modifier_couldBeCage(md) && index<=lastCageIndex) {
954 if (index==cageIndex) {
955 color = TH_BUT_SETTING;
956 icon = VICON_EDITMODE_HLT;
957 } else if (index<cageIndex) {
958 color = TH_BUT_NEUTRAL;
959 icon = VICON_EDITMODE_DEHLT;
961 color = TH_BUT_NEUTRAL;
964 uiBlockSetCol(block, color);
965 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");
966 uiButSetFunc(but, modifiers_setOnCage, ob, md);
967 uiBlockSetCol(block, TH_AUTO);
970 uiBlockSetCol(block, TH_BUT_ACTION);
972 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");
973 uiButSetFunc(but, modifiers_moveUp, ob, md);
975 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");
976 uiButSetFunc(but, modifiers_moveDown, ob, md);
978 uiBlockSetEmboss(block, UI_EMBOSSN);
980 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");
981 uiButSetFunc(but, modifiers_del, ob, md);
982 uiBlockSetCol(block, TH_AUTO);
985 uiBlockSetEmboss(block, UI_EMBOSS);
987 if (!(md->mode&eModifierMode_Expanded)) {
991 int lx = x + width - 60 - 15;
993 if (md->type==eModifierType_Subsurf) {
995 } else if (md->type==eModifierType_Lattice) {
997 } else if (md->type==eModifierType_Curve) {
999 } else if (md->type==eModifierType_Build) {
1001 } else if (md->type==eModifierType_Mirror) {
1003 } else if (md->type==eModifierType_Decimate) {
1005 } else if (md->type==eModifierType_Wave) {
1007 } else if (md->type==eModifierType_Armature) {
1009 } else if (md->type==eModifierType_Hook) {
1013 } else if (md->type==eModifierType_Softbody) {
1017 /* roundbox 4 free variables: corner-rounding, nop, roundbox type, shade */
1018 uiDefBut(block, ROUNDBOX, 0, "", x-10, y-height-2, width, height-2, NULL, 5.0, 0.0, 12, 0, "");
1023 uiBlockBeginAlign(block);
1024 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");
1025 uiButSetFunc(but, modifiers_applyModifier, ob, md);
1026 if (md->type!=eModifierType_Softbody) {
1027 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");
1028 uiButSetFunc(but, modifiers_copyModifier, ob, md);
1030 uiBlockEndAlign(block);
1035 uiBlockBeginAlign(block);
1036 if (md->type==eModifierType_Subsurf) {
1037 SubsurfModifierData *smd = (SubsurfModifierData*) md;
1038 char subsurfmenu[]="Subsurf Type%t|Catmull-Clark%x0|Simple Subdiv.%x1";
1039 uiDefButS(block, MENU, B_MODIFIER_RECALC, subsurfmenu, lx,(cy-=19),buttonWidth,19, &smd->subdivType, 0, 0, 0, 0, "Selects type of subdivision algorithm.");
1040 uiDefButS(block, NUM, B_MODIFIER_RECALC, "Levels:", lx, (cy-=19), buttonWidth,19, &smd->levels, 1, 6, 0, 0, "Number subdivisions to perform");
1041 uiDefButS(block, NUM, B_MODIFIER_RECALC, "Render Levels:", lx, (cy-=19), buttonWidth,19, &smd->renderLevels, 1, 6, 0, 0, "Number subdivisions to perform when rendering");
1043 but = 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");
1044 uiButSetFunc(but, modifiers_setSubsurfIncremental, ob, md);
1046 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");
1048 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");
1049 } else if (md->type==eModifierType_Lattice) {
1050 LatticeModifierData *lmd = (LatticeModifierData*) md;
1051 uiDefIDPoinBut(block, modifier_testLatticeObj, B_CHANGEDEP, "Ob: ", lx, (cy-=19), buttonWidth,19, &lmd->object, "Lattice object to deform with");
1052 } else if (md->type==eModifierType_Curve) {
1053 CurveModifierData *cmd = (CurveModifierData*) md;
1054 uiDefIDPoinBut(block, modifier_testCurveObj, B_CHANGEDEP, "Ob: ", lx, (cy-=19), buttonWidth,19, &cmd->object, "Curve object to deform with");
1055 } else if (md->type==eModifierType_Build) {
1056 BuildModifierData *bmd = (BuildModifierData*) md;
1057 uiDefButF(block, NUM, B_MODIFIER_RECALC, "Start:", lx, (cy-=19), buttonWidth,19, &bmd->start, 1.0, 9000.0, 100, 0, "Specify the start frame of the effect");
1058 uiDefButF(block, NUM, B_MODIFIER_RECALC, "Length:", lx, (cy-=19), buttonWidth,19, &bmd->length, 1.0, 9000.0, 100, 0, "Specify the total time the build effect requires");
1059 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.");
1060 uiDefButI(block, NUM, B_MODIFIER_RECALC, "Seed:", lx, (cy-=19), buttonWidth,19, &bmd->seed, 1.0, 9000.0, 100, 0, "Specify the seed for random if used.");
1061 } else if (md->type==eModifierType_Mirror) {
1062 MirrorModifierData *mmd = (MirrorModifierData*) md;
1063 uiDefButF(block, NUM, B_MODIFIER_RECALC, "Merge Limit:", lx, (cy-=19), buttonWidth,19, &mmd->tolerance, 0.0, 1, 0, 0, "Distance from axis within which mirrored vertices are merged");
1064 uiDefButI(block, ROW, B_MODIFIER_RECALC, "X", lx, (cy-=19), 20,19, &mmd->axis, 1, 0, 0, 0, "Specify the axis to mirror about");
1065 uiDefButI(block, ROW, B_MODIFIER_RECALC, "Y", lx+20, cy, 20,19, &mmd->axis, 1, 1, 0, 0, "Specify the axis to mirror about");
1066 uiDefButI(block, ROW, B_MODIFIER_RECALC, "Z", lx+40, cy, 20,19, &mmd->axis, 1, 2, 0, 0, "Specify the axis to mirror about");
1067 } else if (md->type==eModifierType_Decimate) {
1068 DecimateModifierData *dmd = (DecimateModifierData*) md;
1069 uiDefButF(block, NUM, B_MODIFIER_RECALC, "Percent:", lx,(cy-=19),buttonWidth,19, &dmd->percent, 0.0, 1.0, 0, 0, "Defines the percentage of triangles to reduce to");
1070 sprintf(str, "Face Count: %d", dmd->faceCount);
1071 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");
1072 } else if (md->type==eModifierType_Wave) {
1073 WaveModifierData *wmd = (WaveModifierData*) md;
1074 uiDefButBitS(block, TOG, WAV_X, B_MODIFIER_RECALC, "X", lx,(cy-=19),45,19, &wmd->flag, 0, 0, 0, 0, "Enable X axis motion");
1075 uiDefButBitS(block, TOG, WAV_Y, B_MODIFIER_RECALC, "Y", lx+45,cy,45,19, &wmd->flag, 0, 0, 0, 0, "Enable Y axis motion");
1076 uiDefButBitS(block, TOG, WAV_CYCL, B_MODIFIER_RECALC, "Cycl", lx+90,cy,buttonWidth-90,19, &wmd->flag, 0, 0, 0, 0, "Enable cyclic wave effect");
1077 uiDefButF(block, NUM, B_MODIFIER_RECALC, "Time sta:", lx,(cy-=19),buttonWidth,19, &wmd->timeoffs, -1000.0, 1000.0, 100, 0, "Specify startingframe of the wave");
1078 uiDefButF(block, NUM, B_MODIFIER_RECALC, "Lifetime:", lx,(cy-=19),buttonWidth,19, &wmd->lifetime, -1000.0, 1000.0, 100, 0, "Specify the lifespan of the wave");
1079 uiDefButF(block, NUM, B_MODIFIER_RECALC, "Damptime:", lx,(cy-=19),buttonWidth,19, &wmd->damp, -1000.0, 1000.0, 100, 0, "Specify the dampingtime of the wave");
1081 uiBlockBeginAlign(block);
1082 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");
1083 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");
1084 uiBlockBeginAlign(block);
1085 uiDefButF(block, NUMSLI, B_MODIFIER_RECALC, "Speed:", lx,(cy-=19),220,19, &wmd->speed, -2.0, 2.0, 0, 0, "Specify the wave speed");
1086 uiDefButF(block, NUMSLI, B_MODIFIER_RECALC, "Heigth:", lx,(cy-=19),220,19, &wmd->height, -2.0, 2.0, 0, 0, "Specify the amplitude of the wave");
1087 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");
1088 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");
1089 } else if (md->type==eModifierType_Armature) {
1090 ArmatureModifierData *amd = (ArmatureModifierData*) md;
1091 uiDefIDPoinBut(block, modifier_testArmatureObj, B_CHANGEDEP, "Ob: ", lx, (cy-=19), buttonWidth,19, &amd->object, "Armature object to deform with");
1092 } else if (md->type==eModifierType_Hook) {
1093 HookModifierData *hmd = (HookModifierData*) md;
1094 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");
1095 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");
1096 uiDefIDPoinBut(block, test_obpoin_but, B_CHANGEDEP, "Ob: ", lx, (cy-=19), buttonWidth,19, &hmd->object, "Parent Object for hook, also recalculates and clears offset");
1097 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");
1098 uiButSetFunc(but, modifiers_clearHookOffset, ob, md);
1099 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");
1100 uiButSetFunc(but, modifiers_cursorHookCenter, ob, md);
1103 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");
1104 uiButSetFunc(but, modifiers_selectHook, ob, md);
1105 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");
1106 uiButSetFunc(but, modifiers_reassignHook, ob, md);
1108 } else if (md->type==eModifierType_Softbody) {
1109 uiDefBut(block, LABEL, 1, "See Softbody panel.", lx, (cy-=19), buttonWidth,19, NULL, 0.0, 0.0, 0, 0, "");
1111 uiBlockEndAlign(block);
1121 uiBlockSetCol(block, color);
1122 /* roundbox 4 free variables: corner-rounding, nop, roundbox type, shade */
1123 uiDefBut(block, ROUNDBOX, 0, "", x-10, y, width, 20, NULL, 5.0, 0.0, 15, 40, "");
1124 uiBlockSetCol(block, TH_AUTO);
1126 sprintf(str, "Modifier Error: %s", md->error);
1127 uiDefBut(block, LABEL, B_NOP, str, x+15, y+15, width-35, 19, NULL, 0.0, 0.0, 0.0, 0.0, "");
1140 static void editing_panel_modifiers(Object *ob)
1145 int xco, yco, i, lastCageIndex, cageIndex = modifiers_getCageIndex(ob, &lastCageIndex);
1147 block= uiNewBlock(&curarea->uiblocks, "editing_panel_modifiers", UI_EMBOSS, UI_HELV, curarea->win);
1148 if( uiNewPanel(curarea, block, "Modifiers", "Editing", 640, 0, 318, 204)==0) return;
1150 uiNewPanelHeight(block, 204);
1152 uiDefBlockBut(block, modifiers_add_menu, ob, "Add Modifier", 0, 190, 130, 20, "Add a new modifier");
1154 sprintf(str, "To: %s", ob->id.name+2);
1155 uiDefBut(block, LABEL, 1, str, 140, 190, 140, 20, NULL, 0.0, 0.0, 0, 0, "Object whose modifier stack is being edited");
1160 md = modifiers_getVirtualModifierList(ob);
1162 for (i=0; md; i++, md=md->next) {
1163 draw_modifier(block, ob, md, &xco, &yco, i, cageIndex, lastCageIndex);
1164 if (md->mode&eModifierMode_Virtual) i--;
1167 if(yco < 0) uiNewPanelHeight(block, 204-yco);
1170 /* *************************** FONT ******************************** */
1172 static short give_vfontnr(VFont *vfont)
1177 vf= G.main->vfont.first;
1179 if(vf==vfont) return nr;
1186 static VFont *give_vfontpointer(int nr) /* nr= button */
1191 vf= G.main->vfont.first;
1193 if(tel==nr) return vf;
1197 return G.main->vfont.first;
1200 VFont *exist_vfont(char *str)
1204 vf= G.main->vfont.first;
1206 if(strcmp(vf->name, str)==0) return vf;
1212 static char *give_vfontbutstr(void)
1216 char *str, di[FILE_MAXDIR], fi[FILE_MAXFILE];
1218 vf= G.main->vfont.first;
1220 strcpy(di, vf->name);
1221 BLI_splitdirstring(di, fi);
1226 str= MEM_callocN(len+21, "vfontbutstr");
1227 strcpy(str, "FONTS %t");
1228 vf= G.main->vfont.first;
1231 if(vf->id.us==0) strcat(str, "|0 ");
1232 else strcat(str, "| ");
1234 strcpy(di, vf->name);
1235 BLI_splitdirstring(di, fi);
1243 static void load_buts_vfont(char *name)
1248 if(OBACT && OBACT->type==OB_FONT) cu= OBACT->data;
1251 vf= exist_vfont(name);
1253 vf= load_vfont(name);
1256 else id_us_plus((ID *)vf);
1258 switch(cu->curinfo.flag & CU_STYLE) {
1260 if(cu->vfontb) cu->vfontb->id.us--;
1264 if(cu->vfonti) cu->vfonti->id.us--;
1267 case (CU_BOLD|CU_ITALIC):
1268 if(cu->vfontbi) cu->vfontbi->id.us--;
1272 if(cu->vfont) cu->vfont->id.us--;
1277 DAG_object_flush_update(G.scene, OBACT, OB_RECALC_DATA);
1278 BIF_undo_push("Load vector font");
1279 allqueue(REDRAWVIEW3D, 0);
1280 allqueue(REDRAWBUTSEDIT, 0);
1283 void do_fontbuts(unsigned short event)
1296 DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA);
1297 allqueue(REDRAWVIEW3D, 0);
1301 if (style_to_sel()) {
1302 DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA);
1303 allqueue(REDRAWVIEW3D, 0);
1305 allqueue(REDRAWBUTSEDIT, 0);
1310 DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA);
1311 allqueue(REDRAWVIEW3D, 0);
1316 if (cu->totbox < 256) {
1317 for (i = cu->totbox; i>cu->actbox; i--) cu->tb[i]= cu->tb[i-1];
1318 cu->tb[cu->actbox]= cu->tb[cu->actbox-1];
1321 allqueue(REDRAWBUTSEDIT, 0);
1322 allqueue(REDRAWVIEW3D, 0);
1323 text_to_curve(ob, 0);
1324 makeDispListCurveTypes(ob, 0);
1327 error("Do you really need that many text frames?");
1332 if (cu->totbox > 1) {
1333 for (i = cu->actbox-1; i < cu->totbox; i++) cu->tb[i]= cu->tb[i+1];
1336 allqueue(REDRAWBUTSEDIT, 0);
1337 allqueue(REDRAWVIEW3D, 0);
1338 text_to_curve(ob, 0);
1339 makeDispListCurveTypes(ob, 0);
1346 vf= give_vfontpointer(G.buts->texnr);
1347 if(vf && vf->id.prev!=vf->id.next) strcpy(str, vf->name);
1348 else strcpy(str, U.fontdir);
1350 sa= closest_bigger_area();
1351 areawinset(sa->win);
1353 activate_fileselect(FILE_SPECIAL, "SELECT FONT", str, load_buts_vfont);
1359 if(cu && cu->vfont) {
1360 if (cu->vfont->packedfile) {
1361 if (G.fileflags & G_AUTOPACK) {
1362 if (okee("Disable AutoPack ?")) {
1363 G.fileflags &= ~G_AUTOPACK;
1367 if ((G.fileflags & G_AUTOPACK) == 0) {
1368 if (unpackVFont(cu->vfont, PF_ASK) == RET_OK) {
1369 DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA);
1370 allqueue(REDRAWVIEW3D, 0);
1374 cu->vfont->packedfile = newPackedFile(cu->vfont->name);
1378 allqueue(REDRAWHEADERS, 0);
1379 allqueue(REDRAWBUTSEDIT, 0);
1383 if (!G.obedit) { error("Only in editmode!"); return; }
1384 if (G.obedit->type != OB_FONT) return;
1385 activate_fileselect(FILE_SPECIAL, "Open Text File", G.sce, load_3dtext_fs);
1389 if (!G.obedit) { error("Only in editmode!"); return; }
1390 if (G.obedit->type != OB_FONT) return;
1399 vf= give_vfontpointer(G.buts->texnr);
1401 id_us_plus((ID *)vf);
1403 switch(cu->curinfo.flag & CU_STYLE) {
1405 cu->vfontb->id.us--;
1409 cu->vfonti->id.us--;
1412 case (CU_BOLD|CU_ITALIC):
1413 cu->vfontbi->id.us--;
1421 DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA);
1423 BIF_undo_push("Set vector font");
1424 allqueue(REDRAWVIEW3D, 0);
1425 allqueue(REDRAWBUTSEDIT, 0);
1432 if(cu->textoncurve && cu->textoncurve->type!=OB_CURVE) {
1433 error("Only Curve Objects");
1435 allqueue(REDRAWBUTSEDIT, 0);
1437 DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA);
1438 allqueue(REDRAWVIEW3D, 0);
1443 static void editing_panel_font_type(Object *ob, Curve *cu)
1447 static int packdummy = 0;
1450 block= uiNewBlock(&curarea->uiblocks, "editing_panel_font_type", UI_EMBOSS, UI_HELV, curarea->win);
1451 if(uiNewPanel(curarea, block, "Font", "Editing", 640, 0, 470, 204)==0) return;
1453 switch(cu->curinfo.flag & CU_STYLE) {
1455 G.buts->texnr= give_vfontnr(cu->vfontb);
1458 G.buts->texnr= give_vfontnr(cu->vfonti);
1460 case (CU_BOLD|CU_ITALIC):
1461 G.buts->texnr= give_vfontnr(cu->vfontbi);
1464 G.buts->texnr= give_vfontnr(cu->vfont);
1468 strp= give_vfontbutstr();
1469 // vfd= cu->vfont->data;
1471 uiDefBut(block, BUT,B_LOADFONT, "Load", 480,188,68,20, 0, 0, 0, 0, 0, "Load a new font");
1472 uiDefButS(block, MENU, B_SETFONT, strp, 550,188,220,20, &G.buts->texnr, 0, 0, 0, 0, "Change font for object");
1474 if (cu->vfont->packedfile) {
1479 uiDefIconButI(block, TOG|BIT|0, B_PACKFONT, ICON_PACKAGE, 772,188,20,20, &packdummy, 0, 0, 0, 0, "Pack/Unpack this font");
1481 /* This doesn't work anyway */
1482 // uiDefBut(block, LABEL, 0, vfd->name, 480, 165,314,20, 0, 0, 0, 0, 0, "Postscript name of the font");
1484 uiDefBut(block, BUT, B_LOAD3DTEXT, "Insert Text", 480, 165, 90, 20, 0, 0, 0, 0, 0, "Insert text file at cursor");
1485 uiDefBut(block, BUT, B_LOREM, "Lorem", 575, 165, 70, 20, 0, 0, 0, 0, 0, "Insert a paragraph of Lorem Ipsum at cursor");
1486 uiBlockBeginAlign(block);
1487 uiDefButBitC(block, TOG, CU_BOLD, B_STYLETOSEL, "B", 752,165,20,20, &(cu->curinfo.flag), 0,0, 0, 0, "");
1488 uiDefButBitC(block, TOG, CU_ITALIC, B_STYLETOSEL, "i", 772,165,20,20, &(cu->curinfo.flag), 0, 0, 0, 0, "");
1489 uiBlockEndAlign(block);
1493 uiBlockBeginAlign(block);
1494 uiDefButS(block, ROW,B_MAKEFONT, "Left", 480,135,47,20, &cu->spacemode, 0.0,0.0, 0, 0, "Left align the text from the object centre");
1495 uiDefButS(block, ROW,B_MAKEFONT, "Center", 527,135,47,20, &cu->spacemode, 0.0,1.0, 0, 0, "Middle align the text from the object centre");
1496 uiDefButS(block, ROW,B_MAKEFONT, "Right", 574,135,47,20, &cu->spacemode, 0.0,2.0, 0, 0, "Right align the text from the object centre");
1497 uiDefButS(block, ROW,B_MAKEFONT, "Justify", 621,135,47,20, &cu->spacemode, 0.0,3.0, 0, 0, "Fill completed lines to maximum textframe width");
1498 uiDefButS(block, ROW,B_MAKEFONT, "Flush", 668,135,47,20, &cu->spacemode, 0.0,4.0, 0, 0, "Always fill to maximum textframe width");
1499 uiDefBut(block, BUT, B_TOUPPER, "ToUpper", 715,135,78,20, 0, 0, 0, 0, 0, "Toggle between upper and lower case in editmode");
1500 uiBlockEndAlign(block);
1501 uiDefButBitS(block, TOG, CU_FAST, B_FASTFONT, "Fast Edit", 715,105,78,20, &cu->flag, 0, 0, 0, 0, "Don't fill polygons while editing");
1503 uiDefIDPoinBut(block, test_obpoin_but, B_TEXTONCURVE, "TextOnCurve:", 480,105,220,19, &cu->textoncurve, "Apply a deforming curve to the text");
1504 uiDefBut(block, TEX,REDRAWVIEW3D, "Ob Family:", 480,84,220,19, cu->family, 0.0, 20.0, 0, 0, "Blender uses font from selfmade objects");
1506 uiBlockBeginAlign(block);
1507 uiDefButF(block, NUM,B_MAKEFONT, "Size:", 480,56,155,20, &cu->fsize, 0.1,10.0, 10, 0, "Size of the text");
1508 uiDefButF(block, NUM,B_MAKEFONT, "Linedist:", 640,56,155,20, &cu->linedist, 0.0,10.0, 10, 0, "Distance between text lines");
1509 uiDefButF(block, NUM,B_MAKEFONT, "Word spacing:", 795,56,155,20, &cu->wordspace, 0.0,10.0, 10, 0, "Distance factor between words");
1510 uiDefButF(block, NUM,B_MAKEFONT, "Spacing:", 480,34,155,20, &cu->spacing, 0.0,10.0, 10, 0, "Spacing of individual characters");
1511 uiDefButF(block, NUM,B_MAKEFONT, "X offset:", 640,34,155,20, &cu->xof, -50.0,50.0, 10, 0, "Horizontal position from object centre");
1512 uiDefButF(block, NUM,B_MAKEFONT, "Shear:", 480,12,155,20, &cu->shear, -1.0,1.0, 10, 0, "Italic angle of the characters");
1513 uiDefButF(block, NUM,B_MAKEFONT, "Y offset:", 640,12,155,20, &cu->yof, -50.0,50.0, 10, 0, "Vertical position from object centre");
1514 uiBlockEndAlign(block);
1516 sprintf(str, "%d TextFrame: ", cu->totbox);
1517 uiBlockBeginAlign(block);
1518 uiDefButI(block, NUM, REDRAWVIEW3D, str, 805, 188, 145, 20, &cu->actbox, 1.0, cu->totbox, 0, 10, "Textbox to show settings for");
1519 uiDefBut(block, BUT,B_INSTB, "Insert", 805, 168, 72, 20, 0, 0, 0, 0, 0, "Insert a new text frame after the current one");
1520 uiDefBut(block, BUT,B_DELTB, "Delete", 877, 168, 73, 20, 0, 0, 0, 0, 0, "Delete current text frame and shift the others up");
1521 uiDefButF(block, NUM,B_MAKEFONT, "X:", 805, 148, 72, 20, &(cu->tb[cu->actbox-1].x), -50.0, 50.0, 10, 0, "Horizontal offset of text frame");
1522 uiDefButF(block, NUM,B_MAKEFONT, "Y:", 877, 148, 73, 20, &(cu->tb[cu->actbox-1].y), -50.0, 50.0, 10, 0, "Horizontal offset of text frame");
1523 uiDefButF(block, NUM,B_MAKEFONT, "Width:", 805, 128, 145, 20, &(cu->tb[cu->actbox-1].w), 0.0, 50.0, 10, 0, "Horizontal offset of text frame");
1524 uiDefButF(block, NUM,B_MAKEFONT, "Height:", 805, 108, 145, 20, &(cu->tb[cu->actbox-1].h), 0.0, 50.0, 10, 0, "Horizontal offset of text frame");
1525 uiBlockEndAlign(block);
1529 /* *************************** CURVE ******************************** */
1532 void do_curvebuts(unsigned short event)
1534 extern Nurb *lastnu;
1535 extern ListBase editNurb; /* from editcurve */
1551 setsplinetype(event-B_CONVERTPOLY);
1552 DAG_object_flush_update(G.scene, G.obedit, OB_RECALC_DATA);
1553 allqueue(REDRAWVIEW3D, 0);
1566 if((nu->type & 7)==CU_NURBS) {
1569 nu->flagu += ((event-B_UNIFU)<<1);
1570 makeknots(nu, 1, nu->flagu>>1);
1572 else if(nu->pntsv>1) {
1574 nu->flagv += ((event-B_UNIFV)<<1);
1575 makeknots(nu, 2, nu->flagv>>1);
1581 DAG_object_flush_update(G.scene, G.obedit, OB_RECALC_DATA);
1582 allqueue(REDRAWVIEW3D, 0);
1587 weightflagNurb(1, editbutweight, 0);
1588 DAG_object_flush_update(G.scene, G.obedit, OB_RECALC_DATA);
1589 allqueue(REDRAWVIEW3D, 0);
1594 scrarea_queue_winredraw(curarea);
1597 editbutweight= sqrt(2.0)/4.0;
1598 scrarea_queue_winredraw(curarea);
1601 editbutweight= 0.25;
1602 scrarea_queue_winredraw(curarea);
1605 editbutweight= sqrt(0.5);
1606 scrarea_queue_winredraw(curarea);
1611 if(nu && (nu->type & 7)==CU_NURBS ) {
1612 if(nu->orderu>nu->pntsu) {
1613 nu->orderu= nu->pntsu;
1614 scrarea_queue_winredraw(curarea);
1616 makeknots(nu, 1, nu->flagu>>1);
1617 if(nu->orderv>nu->pntsv) {
1618 nu->orderv= nu->pntsv;
1619 scrarea_queue_winredraw(curarea);
1621 makeknots(nu, 2, nu->flagv>>1);
1623 DAG_object_flush_update(G.scene, G.obedit, OB_RECALC_DATA);
1624 allqueue(REDRAWVIEW3D, 0);
1631 DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA);
1632 allqueue(REDRAWVIEW3D, 0);
1633 allqueue(REDRAWINFO, 1); /* 1, because header->win==0! */
1641 if( (G.obedit==NULL) || (G.obedit->type!=OB_SURF) || (G.vd==NULL) ||
1642 ((G.obedit->lay & G.vd->lay) == 0) ) return;
1645 DAG_object_flush_update(G.scene, G.obedit, OB_RECALC_DATA);
1646 allqueue(REDRAWVIEW3D, 0);
1648 case B_CU3D: /* allow 3D curve */
1654 if((cu->flag & CU_3D)==0) nu->type |= CU_2D;
1659 if(ob->type==OB_CURVE) {
1664 if((cu->flag & CU_3D)==0) nu->type |= CU_2D;
1669 DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA);
1670 allqueue(REDRAWVIEW3D, 0);
1673 if(ob->type==OB_CURVE) {
1675 if(ob==G.obedit) nu= editNurb.first;
1676 else nu= cu->nurb.first;
1679 nu->resolu= cu->resolu;
1684 DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA);
1685 allqueue(REDRAWVIEW3D, 0);
1691 static void editing_panel_curve_tools(Object *ob, Curve *cu)
1694 extern ListBase editNurb; /* from editcurve */
1695 extern Nurb *lastnu;
1699 block= uiNewBlock(&curarea->uiblocks, "editing_panel_curve_tools", UI_EMBOSS, UI_HELV, curarea->win);
1700 if(uiNewPanel(curarea, block, "Curve Tools", "Editing", 640, 0, 318, 204)==0) return;
1702 uiDefBut(block, LABEL, 0, "Make Knots",562,173,102, 18, 0, 0, 0, 0, 0, "");
1704 if(ob->type==OB_CURVE) {
1705 uiDefBut(block, LABEL, 0, "Convert", 463,173,72, 18, 0, 0, 0, 0, 0, "");
1706 uiBlockBeginAlign(block);
1707 uiDefBut(block, BUT,B_CONVERTPOLY,"Poly", 467,152,72, 18, 0, 0, 0, 0, 0, "Converts selected into regular Polygon vertices");
1708 uiDefBut(block, BUT,B_CONVERTBEZ,"Bezier", 467,132,72, 18, 0, 0, 0, 0, 0, "Converts selected to Bezier triples");
1709 uiDefBut(block, BUT,B_CONVERTNURB,"Nurb", 467,112,72, 18, 0, 0, 0, 0, 0, "Converts selected to Nurbs Points");
1711 uiBlockBeginAlign(block);
1712 uiDefBut(block, BUT,B_UNIFU,"Uniform U", 565,152,102, 18, 0, 0, 0, 0, 0, "Nurbs only; interpolated result doesn't go to end points in U");
1713 uiDefBut(block, BUT,B_UNIFV,"V", 670,152,50, 18, 0, 0, 0, 0, 0, "Nurbs only; interpolated result doesn't go to end points in V");
1714 uiDefBut(block, BUT,B_ENDPU,"Endpoint U", 565,132,102, 18, 0, 0, 0, 0, 0, "Nurbs only; interpolated result is forced to end points in U");
1715 uiDefBut(block, BUT,B_ENDPV,"V", 670,132,50, 18, 0, 0, 0, 0, 0, "Nurbs only; interpolated result is forced to end points in V");
1716 uiDefBut(block, BUT,B_BEZU,"Bezier U", 565,112,102, 18, 0, 0, 0, 0, 0, "Nurbs only; make knots array mimic a Bezier in U");
1717 uiDefBut(block, BUT,B_BEZV,"V", 670,112,50, 18, 0, 0, 0, 0, 0, "Nurbs only; make knots array mimic a Bezier in V");
1718 uiBlockEndAlign(block);
1720 uiDefBut(block, BUT,B_SETWEIGHT,"Set Weight", 465,11,95,49, 0, 0, 0, 0, 0, "Nurbs only; set weight for select points");
1722 uiBlockBeginAlign(block);
1723 uiDefButF(block, NUM,0,"Weight:", 565,36,102,22, &editbutweight, 0.01, 100.0, 10, 0, "The weight you can assign");
1724 uiDefBut(block, BUT,B_SETW1,"1.0", 670,36,50,22, 0, 0, 0, 0, 0, "");
1725 uiDefBut(block, BUT,B_SETW2,"sqrt(2)/4",565,11,55,20, 0, 0, 0, 0, 0, "");
1726 uiDefBut(block, BUT,B_SETW3,"0.25", 620,11,45,20, 0, 0, 0, 0, 0, "");
1727 uiDefBut(block, BUT,B_SETW4,"sqrt(0.5)",665,11,55,20, 0, 0, 0, 0, 0, "");
1728 uiBlockEndAlign(block);
1732 if(nu==NULL) nu= editNurb.first;
1734 uiBlockBeginAlign(block);
1736 uiDefButS(block, NUM, B_SETORDER, "Order U:", 565,90,102, 19, sp, 2.0, 6.0, 0, 0, "Nurbs only; the amount of control points involved");
1738 uiDefButS(block, NUM, B_SETORDER, "V:", 670,90,50, 19, sp, 2.0, 6.0, 0, 0, "Nurbs only; the amount of control points involved");
1740 uiDefButS(block, NUM, B_MAKEDISP, "Resol U:", 565,70,102, 19, sp, 1.0, 1024.0, 0, 0, "The amount of new points interpolated per control vertex pair");
1742 uiDefButS(block, NUM, B_MAKEDISP, "V:", 670,70,50, 19, sp, 1.0, 1024.0, 0, 0, "The amount of new points interpolated per control vertex pair");
1749 static void editing_panel_curve_tools1(Object *ob, Curve *cu)
1753 block= uiNewBlock(&curarea->uiblocks, "editing_panel_curve_tools1", UI_EMBOSS, UI_HELV, curarea->win);
1754 if(uiNewPanel(curarea, block, "Curve Tools1", "Editing", 960, 0, 318, 204)==0) return;
1756 uiDefBut(block, BUT, B_SUBDIVCURVE, "Subdivide", 400,180,150,20, 0, 0, 0, 0, 0, "Subdivide selected");
1757 if(ob->type==OB_SURF) {
1758 uiDefBut(block, BUT, B_SPINNURB, "Spin", 400,160,150,20, 0, 0, 0, 0, 0, "Spin selected 360 degrees");
1760 uiBlockBeginAlign(block);
1761 uiDefBut(block, BUT,B_HIDE, "Hide", 400,120,150,18, 0, 0, 0, 0, 0, "Hides selected faces");
1762 uiDefBut(block, BUT,B_REVEAL, "Reveal", 400,100,150,18, 0, 0, 0, 0, 0, "Reveals selected faces");
1763 uiDefBut(block, BUT,B_SELSWAP, "Select Swap", 400,80,150,18, 0, 0, 0, 0, 0, "Selects unselected faces, and deselects selected faces");
1764 uiBlockEndAlign(block);
1766 uiDefButF(block, NUM, REDRAWVIEW3D, "NSize:", 400, 40, 150, 19, &G.scene->editbutsize, 0.001, 1.0, 10, 0, "Normal size for drawing");
1769 /* for curve, surf and font! */
1770 static void editing_panel_curve_type(Object *ob, Curve *cu)
1774 block= uiNewBlock(&curarea->uiblocks, "editing_panel_curve_type", UI_EMBOSS, UI_HELV, curarea->win);
1775 if(uiNewPanel(curarea, block, "Curve and Surface", "Editing", 320, 0, 318, 204)==0) return;
1777 uiDefButBitS(block, TOG, CU_UV_ORCO, 0, "UV Orco", 600,160,150,19, &cu->flag, 0, 0, 0, 0, "Forces to use UV coordinates for texture mapping 'orco'");
1778 if(ob->type==OB_SURF)
1779 uiDefButBitS(block, TOG, CU_NOPUNOFLIP, REDRAWVIEW3D, "No Puno Flip", 600,140,150,19, &cu->flag, 0, 0, 0, 0, "Don't flip vertex normals while render");
1781 uiBlockBeginAlign(block);
1782 uiDefBut(block, BUT,B_DOCENTRE, "Centre", 600, 115, 150, 19, 0, 0, 0, 0, 0, "Shifts object data to be centered about object's origin");
1783 uiDefBut(block, BUT,B_DOCENTRENEW, "Centre New", 600, 95, 150, 19, 0, 0, 0, 0, 0, "Shifts object's origin to center of object data");
1784 uiDefBut(block, BUT,B_DOCENTRECURSOR, "Centre Cursor", 600, 75, 150, 19, 0, 0, 0, 0, 0, "Shifts object's origin to cursor location");
1785 uiBlockEndAlign(block);
1787 if(ob->type==OB_SURF) {
1789 /* uiDefButS(block, NUM, B_DIFF, "Slurph:", 600,25,140,19, &(cu->key->slurph), -500.0, 500.0,0,0); ,""*/
1790 uiDefButS(block, TOG, B_RELKEY, "Relative Keys", 600,45,140,19, &cu->key->type, 0, 0, 0, 0, "");
1794 if(ob->type!=OB_SURF) {
1796 if(ob->type==OB_CURVE) {
1797 extern float prlen; // buttons_object.c, should be moved....
1800 sprintf(str, "%.4f", prlen);
1801 uiDefBut(block, BUT, B_PRINTLEN, "PrintLen", 600,135,75,19, 0, 0, 0, 0, 0, "");
1802 uiDefBut(block, LABEL, 0, str, 675,135,75,19, 0, 1.0, 0, 0, 0, "");
1804 uiBlockBeginAlign(block);
1805 uiDefButS(block, NUM, B_RECALCPATH, "PathLen:", 600,50,150,19, &cu->pathlen, 1.0, 9000.0, 0, 0, "If no speed Ipo was set, the amount of frames of the path");
1806 uiDefButBitS(block, TOG, CU_PATH, B_RECALCPATH, "CurvePath", 600,30,75,19 , &cu->flag, 0, 0, 0, 0, "Enables curve to become translation path");
1807 uiDefButBitS(block, TOG, CU_FOLLOW, REDRAWVIEW3D, "CurveFollow",675,30,75,19, &cu->flag, 0, 0, 0, 0, "Makes curve path children to rotate along path");
1808 uiDefButBitS(block, TOG, CU_STRETCH, B_CURVECHECK, "CurveStretch", 600,10,150,19, &cu->flag, 0, 0, 0, 0, "Option for curve-deform: makes deformed child to stretch along entire path");
1809 uiDefButBitS(block, TOG, CU_OFFS_PATHDIST, REDRAWVIEW3D, "PathDist Offs", 600,-10,150,19, &cu->flag, 0, 0, 0, 0, "Children will use TimeOffs value as path distance offset");
1811 uiBlockEndAlign(block);
1814 uiBlockBeginAlign(block);
1815 uiDefButS(block, NUM, B_MAKEDISP, "DefResolU:", 760,160,120,19, &cu->resolu, 1.0, 1024.0, 0, 0, "Default resolution");
1816 uiDefBut(block, BUT, B_SETRESOLU, "Set", 880,160,30,19, 0, 0, 0, 0, 0, "Set resolution for interpolation");
1818 uiBlockBeginAlign(block);
1819 uiDefButF(block, NUM, B_MAKEDISP, "Width:", 760,90,150,19, &cu->width, 0.0, 2.0, 1, 0, "Make interpolated result thinner or fatter");
1820 uiDefButF(block, NUM, B_MAKEDISP, "Extrude:", 760,70,150,19, &cu->ext1, 0.0, 5.0, 10, 0, "Curve extrusion size when not using a bevel object");
1821 uiDefButF(block, NUM, B_MAKEDISP, "Bevel Depth:", 760,50,150,19, &cu->ext2, 0.0, 2.0, 1, 0, "Bevel depth when not using a bevel object");
1822 uiDefButS(block, NUM, B_MAKEDISP, "BevResol:", 760,30,150,19, &cu->bevresol, 0.0, 10.0, 0, 0, "Bevel resolution when depth is non-zero and not using a bevel object");
1823 uiDefIDPoinBut(block, test_obcurpoin_but, B_CHANGEDEP, "BevOb:", 760,10,150,19, &cu->bevobj, "Curve object name that defines the bevel shape");
1824 uiDefIDPoinBut(block, test_obcurpoin_but, B_CHANGEDEP, "TaperOb:", 760,-10,150,19, &cu->taperobj, "Curve object name that defines the taper (width)");
1826 uiBlockBeginAlign(block);
1827 uiBlockSetCol(block, TH_BUT_SETTING1);
1828 uiDefButBitS(block, TOG, CU_BACK, B_MAKEDISP, "Back", 760,130,50,19, &cu->flag, 0, 0, 0, 0, "Draw filled back for curves");
1829 uiDefButBitS(block, TOG, CU_FRONT, B_MAKEDISP, "Front",810,130,50,19, &cu->flag, 0, 0, 0, 0, "Draw filled front for curves");
1830 uiDefButBitS(block, TOG, CU_3D, B_CU3D, "3D", 860,130,50,19, &cu->flag, 0, 0, 0, 0, "Allow Curve Object to be 3d, it doesn't fill then");
1835 /* *************************** CAMERA ******************************** */
1838 static void editing_panel_camera_type(Object *ob, Camera *cam)
1843 if(G.vd) grid= G.vd->grid;
1844 if(grid<1.0) grid= 1.0;
1846 block= uiNewBlock(&curarea->uiblocks, "editing_panel_camera_type", UI_EMBOSS, UI_HELV, curarea->win);
1847 if(uiNewPanel(curarea, block, "Camera", "Editing", 320, 0, 318, 204)==0) return;
1849 if(cam->type==CAM_ORTHO)
1850 uiDefButF(block, NUM,REDRAWVIEW3D, "Scale:", 470,178,160,20, &cam->ortho_scale, 0.01, 1000.0, 50, 0, "Specify the ortho scaling of the used camera");
1852 uiDefButF(block, NUM,REDRAWVIEW3D, "Lens:", 470,178,160,20, &cam->lens, 1.0, 250.0, 100, 0, "Specify the lens of the camera");
1854 uiBlockBeginAlign(block);
1855 uiDefButF(block, NUM,REDRAWVIEW3D, "ClipSta:", 470,147,160,20, &cam->clipsta, 0.001*grid, 100.0*grid, 10, 0, "Specify the startvalue of the the field of view");
1856 uiDefButF(block, NUM,REDRAWVIEW3D, "ClipEnd:", 470,125,160,20, &cam->clipend, 1.0, 5000.0*grid, 100, 0, "Specify the endvalue of the the field of view");
1857 uiBlockEndAlign(block);
1859 uiDefButF(block, NUM,REDRAWVIEW3D, "DrawSize:", 470,90,160,20, &cam->drawsize, 0.1*grid, 10.0, 10, 0, "Specify the drawsize of the camera");
1861 uiDefButS(block, TOG, REDRAWVIEW3D, "Ortho", 470,29,61,60, &cam->type, 0, 0, 0, 0, "Render orthogonally");
1862 uiBlockBeginAlign(block);
1863 uiDefButBitS(block, TOG, CAM_SHOWLIMITS, REDRAWVIEW3D, "ShowLimits", 533,59,97,30, &cam->flag, 0, 0, 0, 0, "Draw the field of view");
1864 uiDefButBitS(block, TOG, CAM_SHOWMIST, REDRAWVIEW3D, "Show Mist", 533,29,97,30, &cam->flag, 0, 0, 0, 0, "Draw a line that indicates the mist area");
1865 uiBlockEndAlign(block);
1868 /* yafray: extra camera panel to set Depth-of-Field parameters */
1869 static void editing_panel_camera_yafraydof(Object *ob, Camera *cam)
1874 block= uiNewBlock(&curarea->uiblocks, "editing_panel_camera_yafraydof", UI_EMBOSS, UI_HELV, curarea->win);
1875 uiNewPanelTabbed("Camera", "Editing");
1876 if(uiNewPanel(curarea, block, "Yafray DoF", "Editing", 320, 0, 318, 204)==0) return;
1878 uiDefButF(block, NUM, REDRAWVIEW3D, "DoFDist:", 10, 147, 180, 20, &cam->YF_dofdist, 0.0, 5000.0, 50, 0, "Sets distance to point of focus (use camera 'ShowLimits' to make visible in 3Dview)");
1879 uiDefButF(block, NUM, B_DIFF, "Aperture:", 10, 125, 180, 20, &cam->YF_aperture, 0.0, 2.0, 1, 0, "Sets lens aperture, the larger, the more blur (use small values, 0 is no DoF)");
1881 uiDefButBitS(block, TOG, CAM_YF_NO_QMC, B_DIFF, "Random sampling", 10, 90, 180, 20, &cam->flag, 0, 0, 0, 0, "Use noisy random Lens sampling instead of QMC");
1883 uiDefBut(block, LABEL, 0, "Bokeh", 10, 60, 180, 19, 0, 0.0, 0.0, 0, 0, "");
1884 mst1 = "Bokeh Type%t|Disk1%x0|Disk2%x1|Triangle%x2|Square%x3|Pentagon%x4|Hexagon%x5|Ring%x6";
1885 uiDefButS(block, MENU, B_REDR, mst1, 10, 40, 89, 20, &cam->YF_bkhtype, 0.0, 0.0, 0, 0, "Sets Bokeh type");
1887 if ((cam->YF_bkhtype!=0) && (cam->YF_bkhtype!=6)) {
1888 mst2 = "Bokeh Bias%t|Uniform%x0|Center%x1|Edge%x2";
1889 uiDefButS(block, MENU, B_REDR, mst2, 100, 40, 90, 20, &cam->YF_bkhbias, 0.0, 0.0, 0, 0, "Sets Bokeh bias");
1890 if (cam->YF_bkhtype>1)
1891 uiDefButF(block, NUM, B_DIFF, "Rotation:", 10, 15, 180, 20, &cam->YF_bkhrot, 0.0, 360.0, 100, 0, "Shape rotation amount in degrees");
1896 /* **************************** CAMERA *************************** */
1898 void do_cambuts(unsigned short event)
1914 /* *************************** MBALL ******************************** */
1916 void do_mballbuts(unsigned short event)
1920 DAG_object_flush_update(G.scene, OBACT, OB_RECALC_DATA);
1921 allqueue(REDRAWVIEW3D, 0);
1926 static void editing_panel_mball_type(Object *ob, MetaBall *mb)
1930 block= uiNewBlock(&curarea->uiblocks, "editing_panel_mball_type", UI_EMBOSS, UI_HELV, curarea->win);
1931 if(uiNewPanel(curarea, block, "MetaBall", "Editing", 320, 0, 318, 204)==0) return;
1933 ob= find_basis_mball(ob);
1936 uiBlockBeginAlign(block);
1937 uiDefButF(block, NUM, B_RECALCMBALL, "Wiresize:", 470,178,250,19, &mb->wiresize, 0.05, 1.0, 1, 0, "Polygonization resolution in 3d window");
1938 uiDefButF(block, NUM, 0, "Rendersize:", 470,158,250,19, &mb->rendersize, 0.05, 1.0, 1, 0, "Polygonization resolution in rendering");
1939 uiDefButF(block, NUM, B_RECALCMBALL, "Threshold:", 470,138,250,19, &mb->thresh, 0.0001, 5.0, 1, 0, "Defines influence of meta elements");
1941 uiBlockBeginAlign(block);
1942 uiBlockSetCol(block, TH_BUT_SETTING1);
1943 uiDefBut(block, LABEL, 0, "Update:", 471,108,120,19, 0, 0, 0, 0, 0, "");
1944 uiDefButS(block, ROW, B_DIFF, "Always", 471, 85, 120, 19, &mb->flag, 0.0, 0.0, 0, 0, "While editing, always updates");
1945 uiDefButS(block, ROW, B_DIFF, "Half Res", 471, 65, 120, 19, &mb->flag, 0.0, 1.0, 0, 0, "While editing, updates in half resolution");
1946 uiDefButS(block, ROW, B_DIFF, "Fast", 471, 45, 120, 19, &mb->flag, 0.0, 2.0, 0, 0, "While editing, updates without polygonization");
1947 uiDefButS(block, ROW, B_DIFF, "Never", 471, 25, 120, 19, &mb->flag, 0.0, 3.0, 0, 0, "While editing, doesn't update");
1951 static void editing_panel_mball_tools(Object *ob, MetaBall *mb)
1953 extern MetaElem *lastelem;
1956 block= uiNewBlock(&curarea->uiblocks, "editing_panel_mball_tools", UI_EMBOSS, UI_HELV, curarea->win);
1957 if( uiNewPanel(curarea, block, "MetaBall tools", "Editing", 640, 0, 318, 204)==0) return;
1959 if(ob==G.obedit && lastelem) {
1960 uiBlockBeginAlign(block);
1961 uiDefButF(block, NUM, B_RECALCMBALL, "Stiffness:", 750,178,250,19, &lastelem->s, 0.0, 10.0, 1, 0, "Stiffness for active meta");
1962 if(lastelem->type!=MB_BALL)
1963 uiDefButF(block, NUM, B_RECALCMBALL, "dx:", 750,158,250,19, &lastelem->expx, 0.0, 20.0, 1, 0, "X size for active meta");
1964 if((lastelem->type!=MB_BALL)&&(lastelem->type!=MB_TUBE))
1965 uiDefButF(block, NUM, B_RECALCMBALL, "dy:", 750,138,250,19, &lastelem->expy, 0.0, 20.0, 1, 0, "Y size for active meta");
1967 if((lastelem->type==MB_CUBE)||(lastelem->type==MB_ELIPSOID))
1968 uiDefButF(block, NUM, B_RECALCMBALL, "dz:", 750,118,250,19, &lastelem->expz, 0.0, 20.0, 1, 0, "Z size for active meta");
1969 uiBlockEndAlign(block);
1971 uiDefButS(block, ROW, B_RECALCMBALL, "Ball", 753,83,60,19, &lastelem->type, 1.0, 0.0, 0, 0, "Draw active meta as Ball");
1972 uiBlockBeginAlign(block);
1973 uiDefButS(block, ROW, B_RECALCMBALL, "Tube", 753,62,60,19, &lastelem->type, 1.0, 4.0, 0, 0, "Draw active meta as Ball");
1974 uiDefButS(block, ROW, B_RECALCMBALL, "Plane", 814,62,60,19, &lastelem->type, 1.0, 5.0, 0, 0, "Draw active meta as Plane");
1975 uiDefButS(block, ROW, B_RECALCMBALL, "Elipsoid", 876,62,60,19, &lastelem->type, 1.0, 6.0, 0, 0, "Draw active meta as Ellipsoid");
1976 uiDefButS(block, ROW, B_RECALCMBALL, "Cube", 938,62,60,19, &lastelem->type, 1.0, 7.0, 0, 0, "Draw active meta as Cube");
1977 uiBlockEndAlign(block);
1979 uiBlockBeginAlign(block);
1980 uiDefButBitS(block, TOG, MB_NEGATIVE, B_RECALCMBALL, "Negative",753,16,125,19, &lastelem->flag, 0, 0, 0, 0, "Make active meta creating holes");
1981 uiDefButBitS(block, TOG, MB_HIDE, B_RECALCMBALL, "Hide",878,16,125,19, &lastelem->flag, 0, 0, 0, 0, "Make active meta invisible");
1982 uiBlockEndAlign(block);
1989 /* *************************** LATTICE ******************************** */
1991 void do_latticebuts(unsigned short event)
1997 if(ob->type!=OB_LATTICE) return;
2003 if(ob==G.obedit) resizelattice(editLatt, lt->opntsu, lt->opntsv, lt->opntsw, NULL);
2004 else resizelattice(ob->data, lt->opntsu, lt->opntsv, lt->opntsw, NULL);
2005 ob->softflag |= OB_SB_REDO;
2006 DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA);
2007 allqueue(REDRAWVIEW3D, 0);
2012 resizelattice(ob->data, lt->opntsu, lt->opntsv, lt->opntsw, ob);
2013 ob->softflag |= OB_SB_REDO;
2014 DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA);
2015 allqueue(REDRAWVIEW3D, 0);
2019 allqueue(REDRAWVIEW3D, 0);
2024 if(lt->flag & LT_OUTSIDE) outside_lattice(lt);
2026 DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA);
2028 allqueue(REDRAWVIEW3D, 0);
2034 static void editing_panel_lattice_type(Object *ob, Lattice *lt)
2038 block= uiNewBlock(&curarea->uiblocks, "editing_panel_lattice_type", UI_EMBOSS, UI_HELV, curarea->win);
2039 if(uiNewPanel(curarea, block, "Lattice", "Editing", 320, 0, 318, 204)==0) return;
2042 uiSetButLock(lt->key!=0, "Not with VertexKeys");
2043 uiSetButLock(ob==G.obedit, "Unable to perform function in EditMode");
2045 uiBlockBeginAlign(block);
2047 lt->opntsu = lt->pntsu;
2048 lt->opntsv = lt->pntsv;
2049 lt->opntsw = lt->pntsw;
2051 uiDefButS(block, NUM, B_RESIZELAT, "U:", 469, 178,100,19, <->opntsu, 1.0, 64.0, 0, 0, "Points in U direction");
2052 uiDefButC(block, ROW, B_LATTCHANGED, "Lin", 572, 178, 40, 19, <->typeu, 1.0, (float)KEY_LINEAR, 0, 0, "Set Linear interpolation");
2053 uiDefButC(block, ROW, B_LATTCHANGED, "Card", 613, 178, 40, 19, <->typeu, 1.0, (float)KEY_CARDINAL, 0, 0, "Set Cardinal interpolation");
2054 uiDefButC(block, ROW, B_LATTCHANGED, "B", 652, 178, 40, 19, <->typeu, 1.0, (float)KEY_BSPLINE, 0, 0, "Set B-spline interpolation");
2056 uiDefButS(block, NUM, B_RESIZELAT, "V:", 469, 156,100,19, <->opntsv, 1.0, 64.0, 0, 0, "Points in V direction");
2057 uiDefButC(block, ROW, B_LATTCHANGED, "Lin", 572, 156, 40, 19, <->typev, 2.0, (float)KEY_LINEAR, 0, 0, "Set Linear interpolation");
2058 uiDefButC(block, ROW, B_LATTCHANGED, "Card", 613, 156, 40, 19, <->typev, 2.0, (float)KEY_CARDINAL, 0, 0, "Set Cardinal interpolation");
2059 uiDefButC(block, ROW, B_LATTCHANGED, "B", 652, 156, 40, 19, <->typev, 2.0, (float)KEY_BSPLINE, 0, 0, "Set B-spline interpolation");
2061 uiDefButS(block, NUM, B_RESIZELAT, "W:", 469, 134,100,19, <->opntsw, 1.0, 64.0, 0, 0, "Points in W direction");
2062 uiDefButC(block, ROW, B_LATTCHANGED, "Lin", 572, 134, 40, 19, <->typew, 3.0, (float)KEY_LINEAR, 0, 0, "Set Linear interpolation");
2063 uiDefButC(block, ROW, B_LATTCHANGED, "Card", 613, 134, 40, 19, <->typew, 3.0, (float)KEY_CARDINAL, 0, 0, "Set Cardinal interpolation");
2064 uiDefButC(block, ROW, B_LATTCHANGED, "B", 652, 134, 40, 19, <->typew, 3.0, (float)KEY_BSPLINE, 0, 0, "Set B-spline interpolation");
2066 uiBlockEndAlign(block);
2068 uiDefBut(block, BUT, B_REGULARLAT, "Make Regular", 469,98,102,31, 0, 0, 0, 0, 0, "Make Lattice regular");
2071 uiDefButBitS(block, TOG, LT_OUTSIDE, B_LATTCHANGED, "Outside", 571,98,122,31, <->flag, 0, 0, 0, 0, "Only draw, and take into account, the outer vertices");
2074 uiDefButS(block, NUM, B_DIFF, "Slurph:", 469,60,120,19, &(lt->key->slurph), -500.0, 500.0, 0, 0, "Set time value to denote 'slurph' (sequential delay) vertices with key framing");
2075 uiDefButS(block, TOG, B_RELKEY, "Relative Keys", 469,40,120,19, <->key->type, 0, 0, 0, 0, "Use relative keys (instead of absolute)");
2080 /* *************************** ARMATURE ******************************** */
2084 static int editbone_to_parnr (EditBone *bone)
2089 for (ebone=G.edbo.first, index=0; ebone; ebone=ebone->next, index++){
2097 static void parnr_to_editbone(EditBone *bone)
2099 if (bone->parNr == -1){
2100 bone->parent = NULL;
2101 bone->flag &= ~BONE_IK_TOPARENT;
2104 bone->parent = BLI_findlink(&G.edbo, bone->parNr);
2105 attach_bone_to_parent(bone);
2109 static void parnr_to_editbone_cb(void *bonev, void *arg2_unused)
2111 EditBone *curBone= bonev;
2112 parnr_to_editbone(curBone);
2115 static void build_bonestring (char *string, EditBone *bone)
2120 int index, numbones, i;
2121 char (*qsort_ptr)[32] = NULL;
2123 sprintf (string, "Parent%%t| %%x%d", -1); /* That space is there
2127 numbones = BLI_countlist(&G.edbo);
2130 * This will hold the bone names temporarily so we can sort them
2133 qsort_ptr = MEM_callocN (numbones * sizeof (qsort_ptr[0]),
2137 for (curBone = G.edbo.first, index=0; curBone;
2138 curBone=curBone->next, index++){
2139 /* Make sure this is a valid child */
2140 if (curBone != bone){
2142 for (pBone=curBone->parent; pBone; pBone=pBone->parent){
2152 sprintf (qsort_ptr[numbones], "|%s%%x%d", curBone->name, index);
2156 qsort (qsort_ptr, numbones, sizeof (qsort_ptr[0]),
2157 ( int (*)(const void *, const void *) ) strcmp);
2159 for (i=0; i < numbones; ++i) {
2160 sprintf (string, "%s%s", string, qsort_ptr[i]);
2164 MEM_freeN(qsort_ptr);
2167 /* assumes armature editmode */
2168 /* exported to drawview.c via BIF_butspace.h */
2169 void validate_editbonebutton_cb(void *bonev, void *namev)
2171 EditBone *eBone= bonev;
2172 char oldname[32], newname[32];
2174 /* need to be on the stack */
2175 BLI_strncpy(newname, eBone->name, 32);
2176 BLI_strncpy(oldname, (char *)namev, 32);
2178 BLI_strncpy(eBone->name, oldname, 32);
2180 armature_bone_rename(G.obedit->data, oldname, newname); // editarmature.c
2181 allqueue(REDRAWALL, 0);
2184 /* assumes armature posemode */
2185 static void validate_posebonebutton_cb(void *bonev, void *namev)
2189 char oldname[32], newname[32];
2191 /* need to be on the stack */
2192 BLI_strncpy(newname, bone->name, 32);
2193 BLI_strncpy(oldname, (char *)namev, 32);
2195 BLI_strncpy(bone->name, oldname, 32);
2197 armature_bone_rename(ob->data, oldname, newname); // editarmature.c
2198 allqueue(REDRAWALL, 0);
2201 static void armature_recalc_func(void *obp, void *pointer2)
2205 DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA);
2208 static void editing_panel_armature_type(Object *ob, bArmature *arm)
2213 block= uiNewBlock(&curarea->uiblocks, "editing_panel_armature_type", UI_EMBOSS, UI_HELV, curarea->win);
2214 if(uiNewPanel(curarea, block, "Armature", "Editing", 320, 0, 318, 204)==0) return;
2216 uiBlockBeginAlign(block);
2217 but = uiDefButBitI(block, TOG, ARM_RESTPOS, REDRAWVIEW3D,
2218 "Rest Position", 10,180,150,20, &arm->flag, 0, 0, 0, 0, "Disable all animation for this object");
2219 uiButSetFunc(but, armature_recalc_func, ob, NULL);
2220 uiDefButBitI(block, TOG, ARM_DELAYDEFORM, REDRAWVIEW3D, "Delay Deform", 160, 180,150,20, &arm->flag, 0, 0, 0, 0, "Don't deform children when manipulating bones in pose mode");
2221 uiBlockBeginAlign(block);
2222 uiDefButI(block, ROW, REDRAWVIEW3D, "Octahedron", 10, 140,75,20, &arm->drawtype, 0, ARM_OCTA, 0, 0, "Draw bones as octahedra");
2223 uiDefButI(block, ROW, REDRAWVIEW3D, "Stick", 85, 140,70,20, &arm->drawtype, 0, ARM_LINE, 0, 0, "Draw bones as simple 2d lines with dots");
2224 uiDefButI(block, ROW, REDRAWVIEW3D, "B-Bone", 155, 140,70,20, &arm->drawtype, 0, ARM_B_BONE, 0, 0, "Draw bones as boxes, showing subdivision and b-splines");
2225 uiDefButI(block, ROW, REDRAWVIEW3D, "Envelope", 225, 140,85,20, &arm->drawtype, 0, ARM_ENVELOPE, 0, 0, "Draw bones as extruded spheres, showing deformation influence volume");
2227 uiBlockBeginAlign(block);
2228 uiDefButBitI(block, TOG, ARM_DRAWAXES, REDRAWVIEW3D, "Draw Axes", 10, 110,100,20, &arm->flag, 0, 0, 0, 0, "Draw bone axes");
2229 uiDefButBitI(block, TOG, ARM_DRAWNAMES, REDRAWVIEW3D, "Draw Names", 110,110,100,20, &arm->flag, 0, 0, 0, 0, "Draw bone names");
2230 uiDefButBitC(block, TOG, OB_DRAWXRAY,REDRAWVIEW3D, "X-Ray", 210,110,100,20, &ob->dtx, 0, 0, 0, 0, "Draw armature in front of solid objects");
2232 uiBlockBeginAlign(block);
2233 uiDefButBitI(block, TOG, ARM_MIRROR_EDIT, B_DIFF, "X-Axis Mirror Edit", 10, 80,150,20, &arm->flag, 0, 0, 0, 0, "Draw bone axes");
2236 static void editing_panel_armature_bones(Object *ob, bArmature *arm)
2241 char *boneString=NULL;
2245 /* Draw the bone name block */
2247 block= uiNewBlock(&curarea->uiblocks, "editing_panel_armature_bones", UI_EMBOSS, UI_HELV, curarea->win);
2248 if(uiNewPanel(curarea, block, "Armature Bones", "Editing", 640, 0, 318, 204)==0) return;
2250 /* this is a variable height panel, newpanel doesnt force new size on existing panels */
2251 /* so first we make it default height */
2252 uiNewPanelHeight(block, 204);
2255 uiDefBut(block, LABEL, 0, "Selected Bones", bx,by,158,18, 0, 0, 0, 0, 0, "Only show in Armature Editmode");
2257 for (curBone=G.edbo.first, index=0; curBone; curBone=curBone->next, index++){
2258 if (curBone->flag & (BONE_SELECTED)) {
2260 /* Bone naming button */
2261 but=uiDefBut(block, TEX, REDRAWVIEW3D, "BO:", bx-10,by,117,18, &curBone->name, 0, 24, 0, 0, "Change the bone name");
2262 uiButSetFunc(but, validate_editbonebutton_cb, curBone, NULL);
2264 uiDefBut(block, LABEL, 0, "child of", bx+107,by,73,18, NULL, 0.0, 0.0, 0.0, 0.0, "");
2266 boneString = MEM_mallocN((BLI_countlist(&G.edbo) * 64)+64, "Bone str");
2267 build_bonestring (boneString, curBone);
2269 curBone->parNr = editbone_to_parnr(curBone->parent);
2270 but = uiDefButI(block, MENU,REDRAWVIEW3D, boneString, bx+180,by,120,18, &curBone->parNr, 0.0, 0.0, 0.0, 0.0, "Parent");
2271 /* last arg NULL means button will put old string there */
2272 uiButSetFunc(but, parnr_to_editbone_cb, curBone, NULL);
2274 MEM_freeN(boneString);
2276 /* IK to parent flag */
2277 if (curBone->parent){
2278 but=uiDefButBitI(block, TOG, BONE_IK_TOPARENT, REDRAWVIEW3D, "IK", bx+300,by,32,18, &curBone->flag, 0.0, 0.0, 0.0, 0.0, "IK link to parent");
2279 uiButSetFunc(but, attach_bone_to_parent_cb, curBone, NULL);
2282 /* Segment, dist and weight buttons */
2283 uiBlockBeginAlign(block);
2284 uiDefButS(block, NUM, REDRAWVIEW3D, "Segm: ", bx-10,by-19,117,18, &curBone->segments, 1.0, 32.0, 0.0, 0.0, "Subdivisions for B-bones");
2285 uiDefButF(block, NUM,REDRAWVIEW3D, "Dist:", bx+110, by-19, 105, 18, &curBone->dist, 0.0, 1000.0, 10.0, 0.0, "Bone deformation distance");
2286 uiDefButF(block, NUM,REDRAWVIEW3D, "Weight:", bx+223, by-19,110, 18, &curBone->weight, 0.0F, 1000.0F, 10.0F, 0.0F, "Bone deformation weight");
2289 uiDefButBitI(block, TOG, BONE_HINGE, REDRAWVIEW3D, "Hinge", bx-10,by-38,117,18, &curBone->flag, 1.0, 32.0, 0.0, 0.0, "Don't inherit rotation or scale from parent Bone");
2290 uiDefButBitS(block, TOGN, 1,REDRAWVIEW3D, "Skinnable", bx+110, by-38, 105, 18, &curBone->boneclass, 0.0, 0.0, 0.0, 0.0, "Indicate if Bone is included in automatic creation of vertex groups");
2291 /* Hide in posemode flag */
2292 uiDefButBitI(block, TOG, BONE_HIDDEN_A, REDRAWVIEW3D, "Hide", bx+223,by-38,110,18, &curBone->flag, 0, 0, 0, 0, "Toggles display of this bone in Edit Mode");
2294 uiBlockEndAlign(block);
2297 if(by < -200) break; // for time being... extreme long panels are very slow
2302 uiNewPanelHeight(block, 204 - by);
2307 static void editing_panel_pose_bones(Object *ob, bArmature *arm)
2311 bPoseChannel *pchan;
2316 /* Draw the bone name block */
2318 block= uiNewBlock(&curarea->uiblocks, "editing_panel_pose_bones", UI_EMBOSS, UI_HELV, curarea->win);
2319 if(uiNewPanel(curarea, block, "Armature Bones", "Editing", 640, 0, 318, 204)==0) return;
2321 /* this is a variable height panel, newpanel doesnt force new size on existing panels */
2322 /* so first we make it default height */
2323 uiNewPanelHeight(block, 204);
2325 uiDefBut(block, LABEL, 0, "Selected Bones", bx,by,158,18, 0, 0, 0, 0, 0, "Only show in Armature Editmode/Posemode");
2327 for (pchan=ob->pose->chanbase.first, index=0; pchan; pchan=pchan->next, index++){
2328 curBone= pchan->bone;
2329 if (curBone->flag & (BONE_SELECTED)) {
2331 /* Bone naming button */
2332 uiBlockBeginAlign(block);
2333 but=uiDefBut(block, TEX, REDRAWVIEW3D, "BO:", bx-10,by,117,18, &curBone->name, 0, 24, 0, 0, "Change the bone name");
2334 uiButSetFunc(but, validate_posebonebutton_cb, curBone, NULL);
2336 /* Dist and weight buttons */
2337 uiDefButF(block, NUM,REDRAWVIEW3D, "Dist:", bx+107, by, 105, 18, &curBone->dist, 0.0, 1000.0, 10.0, 0.0, "Bone deformation distance");
2338 uiDefButF(block, NUM,REDRAWVIEW3D, "Weight:", bx+220, by, 110, 18, &curBone->weight, 0.0F, 1000.0F, 10.0F, 0.0F, "Bone deformation weight");
2341 /* Segment, ease in/out buttons */
2342 uiBlockBeginAlign(block);
2343 uiDefButS(block, NUM, REDRAWVIEW3D, "Segm: ", bx-10,by-19,117,19, &curBone->segments, 1.0, 32.0, 0.0, 0.0, "Subdivisions for B-bones");
2344 uiDefButF(block, NUM,REDRAWVIEW3D, "In:", bx+107, by-19,105, 19, &curBone->ease1, 0.0, 2.0, 10.0, 0.0, "First length of Bezier handle");
2345 uiDefButF(block, NUM,REDRAWVIEW3D, "Out:", bx+220, by-19, 110, 19, &curBone->ease2, 0.0, 2.0, 10.0, 0.0, "Second length of Bezier handle");
2348 but= uiDefButBitI(block, TOG, BONE_HINGE, REDRAWVIEW3D, "Hinge", bx-10,by-38,117,18, &curBone->flag, 1.0, 32.0, 0.0, 0.0, "Don't inherit rotation or scale from parent Bone");
2349 uiButSetFunc(but, armature_recalc_func, ob, NULL);
2350 uiDefButBitS(block, TOGN, 1,REDRAWVIEW3D, "Skinnable", bx+110, by-38, 105, 18, &curBone->boneclass, 0.0, 0.0, 0.0, 0.0, "Indicate if Bone is included in automatic creation of vertex groups");
2351 /* Hide in posemode flag */
2352 uiDefButBitI(block, TOG, BONE_HIDDEN_P, REDRAWVIEW3D, "Hide", bx+223,by-38,110,18, &curBone->flag, 0, 0, 0, 0, "Toggles display of this bone in posemode");
2353 uiBlockEndAlign(block);
2356 if(by < -200) break; // for time being... extreme long panels are very slow
2361 uiNewPanelHeight(block, 204 - by);
2367 /* *************************** MESH ******************************** */
2369 void do_meshbuts(unsigned short event)
2377 if(ob && ob->type==OB_MESH) {
2384 if (!get_armature(ob->parent)){
2385 error ("Mesh must be the child of an armature");
2388 /* Verify that there are vertex groups for bones in armature */
2389 /* Remove selected vertices from all defgroups */
2390 /* Perform assignment for selected vertices */
2392 allqueue (REDRAWVIEW3D, 1);
2395 add_defgroup (G.obedit);
2396 scrarea_queue_winredraw(curarea);
2399 del_defgroup (G.obedit);
2400 allqueue (REDRAWVIEW3D, 1);
2401 BIF_undo_push("Delete vertex group");
2403 case B_ASSIGNVGROUP:
2404 assign_verts_defgroup ();
2405 allqueue (REDRAWVIEW3D, 1);
2406 BIF_undo_push("Assign to vertex group");
2408 case B_REMOVEVGROUP:
2409 remove_verts_defgroup (0);
2410 allqueue (REDRAWVIEW3D, 1);
2411 BIF_undo_push("Remove from vertex group");
2414 sel_verts_defgroup(1);
2415 allqueue (REDRAWVIEW3D, 1);
2418 sel_verts_defgroup(0);
2419 allqueue (REDRAWVIEW3D, 1);
2423 if(me->msticky) MEM_freeN(me->msticky);
2425 allqueue(REDRAWBUTSEDIT, 0);
2429 allqueue(REDRAWBUTSEDIT, 0);
2433 /* in editmode we only have to set edge pointer */
2435 me->medge= MEM_callocN(sizeof(MEdge), "fake mesh edge");
2438 else make_edges(me);
2439 DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA);
2440 allqueue(REDRAWBUTSEDIT, 0);
2443 if(me->medge) MEM_freeN(me->medge);
2446 DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA);
2447 allqueue(REDRAWBUTSEDIT, 0);
2448 allqueue(REDRAWVIEW3D, 0);
2455 if(me->mcol) MEM_freeN(me->mcol);
2457 G.f &= ~G_VERTEXPAINT;
2458 freedisplist(&(ob->disp));
2459 allqueue(REDRAWBUTSEDIT, 0);
2460 allqueue(REDRAWVIEW3D, 0);
2465 allqueue(REDRAWBUTSEDIT, 0);
2469 if(me->tface) MEM_freeN(me->tface);
2471 G.f &= ~G_FACESELECT;
2472 allqueue(REDRAWBUTSEDIT, 0);
2473 allqueue(REDRAWVIEW3D, 0);
2474 allqueue(REDRAWIMAGE, 0);
2481 allqueue(REDRAWVIEW3D, 0);
2493 if(G.obedit==0 || (G.obedit->type!=OB_MESH)) return;
2497 if( select_area(SPACE_VIEW3D)) spin_mesh(step, degr, 0, 0);
2500 if( select_area(SPACE_VIEW3D)) spin_mesh(step, degr, 0, 1);
2503 G.f |= G_DISABLE_OK;
2504 if( select_area(SPACE_VIEW3D)) extrude_mesh();
2505 G.f -= G_DISABLE_OK;
2508 if( select_area(SPACE_VIEW3D)) screw_mesh(step, turn);
2511 if( select_area(SPACE_VIEW3D)) extrude_repeat_mesh(step, extr_offs);
2514 G.f |= G_DISABLE_OK;
2516 G.f -= G_DISABLE_OK;
2519 notice("Removed: %d", removedoublesflag(1, doublimit));
2520 allqueue(REDRAWVIEW3D, 0);
2521 BIF_undo_push("Rem Doubles");
2525 esubdivideflag(1, 0.0, editbutflag & B_BEAUTY,1,0);
2528 allqueue(REDRAWVIEW3D, 0);
2529 BIF_undo_push("Subdivide");
2533 if(button(&randfac, 1, 100, "Rand fac:")==0) return;
2535 fac= -( (float)randfac )/100;
2536 esubdivideflag(1, fac, editbutflag & B_BEAUTY,1,0);
2539 allqueue(REDRAWVIEW3D, 0);
2540 BIF_undo_push("Fractal Subdivide");
2543 if( select_area(SPACE_VIEW3D)) xsortvert_flag(1);
2549 vertices_to_sphere();
2554 case B_VERTEXSMOOTH:
2558 G.f &= ~G_DRAWCREASES;
2559 allqueue(REDRAWBUTSEDIT, 0);
2560 allqueue(REDRAWVIEW3D, 0);
2563 G.f &= ~G_DRAWEDGES;
2564 allqueue(REDRAWBUTSEDIT, 0);
2565 allqueue(REDRAWVIEW3D, 0);
2568 /* WATCH IT: previous events only in editmode! */
2571 static void editing_panel_mesh_tools(Object *ob, Mesh *me)
2575 block= uiNewBlock(&curarea->uiblocks, "editing_panel_mesh_tools", UI_EMBOSS, UI_HELV, curarea->win);
2576 if(uiNewPanel(curarea, block, "Mesh Tools", "Editing", 640, 0, 318, 204)==0) return;
2578 uiBlockBeginAlign(block);
2579 uiDefButBitS(block, TOG, B_BEAUTY, 0, "Beauty", 10,195,40,19, &editbutflag, 0, 0, 0, 0, "Causes 'Subdivide' to split faces in halves instead of quarters using Long Edges Unless short is selected");
2580 uiDefButBitS(block, TOG, B_BEAUTY_SHORT, 0, "Short", 50,195,40,19, &editbutflag, 0, 0, 0, 0, "Causes 'Subdivide' to split faces in halves instead of quarters using Short Edges");
2582 uiDefBut(block, BUT,B_SUBDIV,"Subdivide", 90,195,80,19, 0, 0, 0, 0, 0, "Splits selected faces into halves or quarters");
2583 uiDefBut(block, BUT,B_FRACSUBDIV, "Fract Subd", 170,195,85,19, 0, 0, 0, 0, 0, "Subdivides selected faces with a random factor");
2585 uiDefBut(block, BUT,B_VERTEXNOISE,"Noise", 10,175,80,19, 0, 0, 0, 0, 0, "Use vertex coordinate as texture coordinate");
2586 uiDefBut(block, BUT,B_HASH,"Hash", 90,175,80,19, 0, 0, 0, 0, 0, "Randomizes selected vertice sequence data");
2587 uiDefBut(block, BUT,B_XSORT,"Xsort", 170,175,85,19, 0, 0, 0, 0, 0, "Sorts selected vertice data in the X direction");
2589 uiDefBut(block, BUT,B_TOSPHERE,"To Sphere", 10,155,80,19, 0, 0, 0, 0, 0, "Moves selected vertices outwards into a spherical shape");
2590 uiDefBut(block, BUT,B_VERTEXSMOOTH,"Smooth", 90,155,80,19, 0, 0, 0, 0, 0, "Flattens angles of selected faces");
2591 uiDefBut(block, BUT,B_SPLIT,"Split", 170,155,85,19, 0, 0, 0, 0, 0, "Splits selected verts to separate sub-mesh.");
2593 uiDefBut(block, BUT,B_FLIPNORM,"Flip Normals", 10,135,80,19, 0, 0, 0, 0, 0, "Toggles the direction of the selected face's normals");
2594 uiDefBut(block, BUT,B_REMDOUB,"Rem Doubles", 90,135,80,19, 0, 0, 0, 0, 0, "Removes duplicates from selected vertices");
2595 uiDefButF(block, NUM, B_DIFF, "Limit:", 170,135,85,19, &doublimit, 0.0001, 1.0, 10, 0, "Specifies the max distance 'Rem Doubles' will consider vertices as 'doubled'");
2596 uiBlockEndAlign(block);
2598 uiDefBut(block, BUT,B_EXTR,"Extrude", 10,105,245,24, 0, 0, 0, 0, 0, "Converts selected edges to faces and selects the new vertices");
2600 uiBlockBeginAlign(block);
2601 uiDefBut(block, BUT,B_SCREW,"Screw", 10,75,80,24, 0, 0, 0, 0, 0, "Activates the screw tool"); // Bish - This could use some more definition
2602 uiDefBut(block, BUT,B_SPIN, "Spin", 90,75,80,24, 0, 0, 0, 0, 0, "Extrudes the selected vertices in a circle around the cursor in the indicated viewport");
2603 uiDefBut(block, BUT,B_SPINDUP,"Spin Dup", 170,75,85,24, 0, 0, 0, 0, 0, "Creates copies of the selected vertices in a circle around the cursor in the indicated viewport");
2605 uiDefButS(block, NUM, B_DIFF, "Degr:", 10,55,80,19, °r,10.0,360.0, 0, 0, "Specifies the number of degrees 'Spin' revolves");
2606 uiDefButS(block, NUM, B_DIFF, "Steps:", 90,55,80,19, &step,1.0,180.0, 0, 0, "Specifies the total number of 'Spin' slices");
2607 uiDefButS(block, NUM, B_DIFF, "Turns:", 170,55,85,19, &turn,1.0,360.0, 0, 0, "Specifies the number of revolutions the screw turns");
2608 uiDefButBitS(block, TOG, B_KEEPORIG, B_DIFF, "Keep Original",10,35,160,19, &editbutflag, 0, 0, 0, 0, "Keeps a copy of the original vertices and faces after executing tools");
2609 uiDefButBitS(block, TOG, B_CLOCKWISE, B_DIFF, "Clockwise", 170,35,85,19, &editbutflag, 0, 0, 0, 0, "Specifies the direction for 'Screw' and 'Spin'");
2611 uiBlockBeginAlign(block);
2612 uiDefBut(block, BUT,B_EXTREP, "Extrude Dup", 10,10,120,19, 0, 0, 0, 0, 0, "Creates copies of the selected vertices in a straight line away from the current viewport");
2613 uiDefButF(block, NUM, B_DIFF, "Offset:", 130,10,125,19, &extr_offs, 0.01, 100.0, 100, 0, "Sets the distance between each copy for 'Extrude Dup'");
2614 uiBlockEndAlign(block);
2617 static void verify_vertexgroup_name_func(void *datav, void *data2_unused)
2619 unique_vertexgroup_name((bDeformGroup*)datav, OBACT);
2624 static void editing_panel_mesh_tools1(Object *ob, Mesh *me)
2629 block= uiNewBlock(&curarea->uiblocks, "editing_panel_mesh_tools1", UI_EMBOSS, UI_HELV, curarea->win);
2630 if(uiNewPanel(curarea, block, "Mesh Tools 1", "Editing", 960, 0, 318, 204)==0) return;
2632 uiBlockBeginAlign(block);
2633 uiDefBut(block, BUT,B_DOCENTRE, "Centre", 955, 200, 160, 19, 0, 0, 0, 0, 0, "Shifts object data to be centered about object's origin");
2634 uiDefBut(block, BUT,B_HIDE, "Hide", 1115, 200, 160, 19, 0, 0, 0, 0, 0, "Hides selected faces");
2635 uiDefBut(block, BUT,B_SELSWAP, "Select Swap", 955, 180, 160, 19, 0, 0, 0, 0, 0, "Selects unselected faces, and deselects selected faces");
2636 uiDefBut(block, BUT,B_REVEAL, "Reveal", 1115, 180, 160, 19, 0, 0, 0, 0, 0, "Reveals selected faces");
2637 uiBlockEndAlign(block);
2639 uiBlockBeginAlign(block);
2640 uiDefButF(block, NUM, REDRAWVIEW3D, "NSize:", 955, 131, 150, 19, &G.scene->editbutsize, 0.001, 2.0, 10, 0, "Sets the length to use when displaying face normals");
2641 uiDefButBitI(block, TOG, G_DRAWNORMALS, REDRAWVIEW3D, "Draw Normals", 955,110,150,19, &G.f, 0, 0, 0, 0, "Displays face normals as lines");
2642 uiDefButBitI(block, TOG, G_DRAWFACES, REDRAWVIEW3D, "Draw Faces", 955,88,150,19, &G.f, 0, 0, 0, 0, "Displays all faces as shades");
2643 uiDefButBitI(block, TOG, G_DRAWEDGES, REDRAWVIEW3D, "Draw Edges", 955,66,150,19, &G.f, 0, 0, 0, 0, "Displays selected edges using hilights");
2644 uiDefButBitI(block, TOG, G_DRAWCREASES, REDRAWVIEW3D, "Draw Creases", 955,44,150,19, &G.f, 0, 0, 0, 0, "Displays creases created for subsurf weighting");
2645 uiDefButBitI(block, TOG, G_DRAWSEAMS, REDRAWVIEW3D, "Draw Seams", 955,22,150,19, &G.f, 0, 0, 0, 0, "Displays UV unwrapping seams");
2646 uiDefButBitI(block, TOG, G_ALLEDGES, 0, "All Edges", 955, 0,150,19, &G.f, 0, 0, 0, 0, "Displays all edges in object mode without optimization");
2647 uiBlockEndAlign(block);
2649 /* Measurement drawing options */
2650 uiBlockBeginAlign(block);
2651 uiDefButBitI(block, TOG, G_DRAW_VNORMALS, REDRAWVIEW3D, "Draw VNormals",1125,110,150,19, &G.f, 0, 0, 0, 0, "Displays vertex normals as lines");
2652 uiDefButBitI(block, TOG, G_DRAW_EDGELEN, REDRAWVIEW3D, "Edge Length", 1125,88,150,19, &G.f, 0, 0, 0, 0, "Displays selected edge lengths");
2653 uiDefButBitI(block, TOG, G_DRAW_EDGEANG, REDRAWVIEW3D, "Edge Angles", 1125,66,150,19, &G.f, 0, 0, 0, 0, "Displays the angles in the selected edges in degrees");
2654 uiDefButBitI(block, TOG, G_DRAW_FACEAREA, REDRAWVIEW3D, "Face Area", 1125,44,150,19, &G.f, 0, 0, 0, 0, "Displays the area of selected faces");
2655 uiBlockEndAlign(block);
2659 char *get_vertexgroup_menustr(Object *ob)
2662 int defCount, min, index;
2663 char (*qsort_ptr)[32] = NULL;
2666 defCount=BLI_countlist(&ob->defbase);
2668 if (!defCount) min=0;
2673 * This will hold the group names temporarily
2674 * so we can sort them
2676 qsort_ptr = MEM_callocN (defCount * sizeof (qsort_ptr[0]),
2678 for (index = 1, dg = ob->defbase.first; dg; index++, dg=dg->next) {
2679 snprintf (qsort_ptr[index - 1], sizeof (qsort_ptr[0]),
2680 "%s%%x%d|", dg->name, index);
2683 qsort (qsort_ptr, defCount, sizeof (qsort_ptr[0]),
2684 ( int (*)(const void *, const void *) ) strcmp);
2687 s= menustr = MEM_callocN((32 * defCount)+30, "menustr"); // plus 30 for when defCount==0
2689 for (index = 0; index < defCount; index++) {
2690 int cnt= sprintf (s, "%s", qsort_ptr[index]);
2694 else strcpy(menustr, "No Vertex Groups in Object");
2697 MEM_freeN (qsort_ptr);
2702 static void editing_panel_links(Object *ob)
2712 block= uiNewBlock(&curarea->uiblocks, "editing_panel_links", UI_EMBOSS, UI_HELV, curarea->win);
2713 if(uiNewPanel(curarea, block, "Link and Materials", "Editing", 0, 0, 318, 204)==0) return;
2715 buttons_active_id(&id, &idfrom);
2720 int browse= B_EDITBROWSE;
2722 if(ob->type==OB_MESH) {
2723 browse= B_MESHBROWSE;
2726 uiSetButLock(G.obedit!=0, "Unable to perform function in EditMode");
2728 else if(ob->type==OB_MBALL) {
2729 alone= B_MBALLALONE;
2730 local= B_MBALLLOCAL;
2732 else if ELEM3(ob->type, OB_CURVE, OB_FONT, OB_SURF) {
2733 alone= B_CURVEALONE;
2734 local= B_CURVELOCAL;
2736 else if(ob->type==OB_CAMERA) {
2737 alone= B_CAMERAALONE;
2738 local= B_CAMERALOCAL;
2740 else if(ob->type==OB_LAMP) {
2744 else if (ob->type==OB_ARMATURE){
2748 else if(ob->type==OB_LATTICE) {
2752 uiBlockSetCol(block, TH_BUT_SETTING2);
2753 xco= std_libbuttons(block, 143, 180, 0, NULL, browse, id, idfrom, &(G.buts->menunr), alone, local, 0, 0, B_KEEPDATA);
2754 uiBlockSetCol(block, TH_AUTO);
2757 but = uiDefBut(block, TEX, B_IDNAME, "OB:", xco, 180, 454-xco, YIC, ob->id.name+2, 0.0, 19.0, 0, 0, "Displays Active Object name. Click to change.");
2758 uiButSetFunc(but, test_idbutton_cb, ob->id.name, NULL);
2764 if ELEM5(ob->type, OB_MESH, OB_CURVE, OB_SURF, OB_FONT, OB_MBALL);
2768 if(ob->type==OB_MESH) poin= &( ((Mesh *)ob->data)->texflag );
2769 else if(ob->type==OB_MBALL) poin= &( ((MetaBall *)ob->data)->texflag );
2770 else poin= &( ((Curve *)ob->data)->texflag );
2771 uiDefButBitI(block, TOG, AUTOSPACE, B_AUTOTEX, "AutoTexSpace", 143,15,140,19, poin, 0, 0, 0, 0, "Adjusts active object's texture space automatically when transforming object");
2773 sprintf(str,"%d Mat ", ob->totcol);
2774 if(ob->totcol) min= 1.0; else min= 0.0;
2775 ma= give_current_material(ob, ob->actcol);
2777 if(ma) uiDefBut(block, LABEL, 0, ma->id.name+2, 318,153, 103, 20, 0, 0, 0, 0, 0, "");
2779 uiBlockBeginAlign(block);
2780 if(ma) uiDefButF(block, COL, B_REDR, "", 292,123,31,30, &(ma->r), 0, 0, 0, 0, "");
2781 uiDefButC(block, NUM, B_ACTCOL, str, 324,123,100,30, &ob->actcol, min, (float)(ob->totcol), 0, 0, "Displays total number of material indices and the current index");
2782 uiDefBut(block, BUT,B_MATWICH, "?", 424,123,30,30, 0, 0, 0, 0, 0, "In EditMode, sets the active material index from selected faces");
2784 uiBlockBeginAlign(block);
2785 uiDefBut(block, BUT,B_MATNEW, "New", 292,98,80,20, 0, 0, 0, 0, 0, "Adds a new Material index");
2786 uiDefBut(block, BUT,B_MATDEL, "Delete", 374,98,80,20, 0, 0, 0, 0, 0, "Deletes this Material index");
2787 uiDefBut(block, BUT,B_MATSEL, "Select", 292,76,80,20, 0, 0, 0, 0, 0, "In EditMode, selects faces that have the active index");
2788 uiDefBut(block, BUT,B_MATDESEL, "Deselect", 374,76,80,20, 0, 0, 0, 0, 0, "Deselects everything with current indexnumber");
2789 uiDefBut(block, BUT,B_MATASS, "Assign", 292,47,162,26, 0, 0, 0, 0, 0, "In EditMode, assigns the active index to selected faces");
2791 uiBlockBeginAlign(block);
2792 uiDefBut(block, BUT,B_SETSMOOTH,"Set Smooth", 291,15,80,20, 0, 0, 0, 0, 0, "In EditMode, sets 'smooth' rendering of selected faces");
2793 uiDefBut(block, BUT,B_SETSOLID, "Set Solid", 373,15,80,20, 0, 0, 0, 0, 0, "In EditMode, sets 'solid' rendering of selected faces");
2794 uiBlockEndAlign(block);
2796 /* vertex group... partially editmode... */
2797 if(ob->type==OB_MESH) {
2800 bDeformGroup *defGroup;
2802 uiDefBut(block, LABEL,0,"Vertex Groups",
2803 143,153,130,20, 0, 0, 0, 0, 0, "");
2805 defCount=BLI_countlist(&ob->defbase);
2807 uiBlockBeginAlign(block);
2809 char *menustr= get_vertexgroup_menustr(ob);
2811 uiDefButS(block, MENU, REDRAWBUTSEDIT, menustr, 143, 132,18,21, &ob->actdef, 1, defCount, 0, 0, "Browses available vertex groups");
2812 MEM_freeN (menustr);
2816 defGroup = BLI_findlink(&ob->defbase, ob->actdef-1);
2817 but= uiDefBut(block, TEX,REDRAWBUTSEDIT,"", 161,132,140-18,21, defGroup->name, 0, 32, 0, 0, "Displays current vertex group name. Click to change. (Match bone name for deformation.)");
2818 uiButSetFunc(but, verify_vertexgroup_name_func, defGroup, NULL);
2820 uiDefButF(block, NUM, REDRAWVIEW3D, "Weight:", 143, 111, 140, 21, &editbutvweight, 0, 1, 10, 0, "Sets the current vertex group's bone deformation strength");
2822 uiBlockEndAlign(block);
2824 if (G.obedit && G.obedit==ob){
2825 uiBlockBeginAlign(block);
2826 /* uiDefBut(block, BUT,B_AUTOVGROUP,"Auto Weight", 740,by-=22,93,18, 0, 0, 0, 0, 0, "Automatically assigns deformation groups"); */
2827 uiDefBut(block, BUT,B_NEWVGROUP,"New", 143,90,70,21, 0, 0, 0, 0, 0, "Creates a new vertex group");
2828 uiDefBut(block, BUT,B_DELVGROUP,"Delete", 213,90,70,21, 0, 0, 0, 0, 0, "Removes the current vertex group");
2830 uiDefBut(block, BUT,B_ASSIGNVGROUP,"Assign", 143,69,70,21, 0, 0, 0, 0, 0, "Assigns selected vertices to the current vertex group");
2831 uiDefBut(block, BUT,B_REMOVEVGROUP,"Remove", 213,69,70,21, 0, 0, 0, 0, 0, "Removes selected vertices from the current vertex group");
2833 uiDefBut(block, BUT,B_SELVGROUP,"Select", 143,48,70,21, 0, 0, 0, 0, 0, "Selects vertices belonging to the current vertex group");
2834 uiDefBut(block, BUT,B_DESELVGROUP,"Desel.", 213,48,70,21, 0, 0, 0, 0, 0, "Deselects vertices belonging to the current vertex group");
2835 uiBlockEndAlign(block);
2842 /* *************************** FACE/PAINT *************************** */
2844 void do_fpaintbuts(unsigned short event)
2848 bDeformGroup *defGroup;
2849 extern TFace *lasttface; /* caches info on tface bookkeeping ?*/
2850 extern VPaint Gwp; /* from vpaint */
2853 if(ob==NULL) return;
2860 case B_COPY_TF_MODE:
2865 if(me && me->tface) {
2866 /* extern TFace *lasttface; */
2867 TFace *tface= me->tface;
2874 if(tface!=lasttface && (tface->flag & TF_SELECT)) {
2875 if(event==B_COPY_TF_MODE) {
2876 tface->mode= lasttface->mode;
2877 tface->transp= lasttface->transp;
2879 else if(event==B_COPY_TF_UV) {
2880 memcpy(tface->uv, lasttface->uv, sizeof(tface->uv));
2881 tface->tpage= lasttface->tpage;
2882 tface->tile= lasttface->tile;
2884 if(lasttface->mode & TF_TILES) tface->mode |= TF_TILES;
2885 else tface->mode &= ~TF_TILES;
2888 else if(event==B_COPY_TF_TEX) {
2889 tface->tpage= lasttface->tpage;
2890 tface->tile= lasttface->tile;
2892 if(lasttface->mode & TF_TILES) tface->mode |= TF_TILES;
2893 else tface->mode &= ~TF_TILES;
2895 else if(event==B_COPY_TF_COL) memcpy(tface->col, lasttface->col, sizeof(tface->col));
2900 do_shared_vertexcol(me);
2901 allqueue(REDRAWVIEW3D, 0);
2902 allqueue(REDRAWIMAGE, 0);
2906 if(G.f & G_FACESELECT)
2907 clear_vpaint_selectedfaces();
2912 allqueue(REDRAWVIEW3D, 0);
2913 allqueue(REDRAWIMAGE, 0);
2917 test_object_materials(ob->data);
2918 allqueue(REDRAWVIEW3D, 0);
2919 allqueue(REDRAWBUTSEDIT, 0);
2925 lasttface->mode &= ~TF_BILLBOARD2;
2926 allqueue(REDRAWBUTSEDIT, 0);
2933 lasttface->mode &= ~TF_BILLBOARD;
2934 allqueue(REDRAWBUTSEDIT, 0);
2938 editbutvweight = 0.0f;
2939 allqueue(REDRAWBUTSEDIT, 0);
2943 editbutvweight = 0.25f;
2944 allqueue(REDRAWBUTSEDIT, 0);
2947 editbutvweight = 0.5f;
2948 allqueue(REDRAWBUTSEDIT, 0);
2951 editbutvweight = 0.75f;
2952 allqueue(REDRAWBUTSEDIT, 0);
2955 editbutvweight = 1.0f;
2956 allqueue(REDRAWBUTSEDIT, 0);
2961 allqueue(REDRAWBUTSEDIT, 0);
2965 allqueue(REDRAWBUTSEDIT, 0);
2969 allqueue(REDRAWBUTSEDIT, 0);
2973 allqueue(REDRAWBUTSEDIT, 0);
2977 allqueue(REDRAWBUTSEDIT, 0);