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 *****
33 //#define NAN_LINEAR_PHYSICS
40 #include <sys/times.h>
45 #include "MEM_guardedalloc.h"
51 #include "IMB_imbuf_types.h"
52 #include "IMB_imbuf.h"
54 #include "DNA_action_types.h"
55 #include "DNA_armature_types.h"
56 #include "DNA_camera_types.h"
57 #include "DNA_constraint_types.h"
58 #include "DNA_curve_types.h"
59 #include "DNA_group_types.h"
60 #include "DNA_image_types.h"
61 #include "DNA_lattice_types.h"
62 #include "DNA_mesh_types.h"
63 #include "DNA_meshdata_types.h"
64 #include "DNA_meta_types.h"
65 #include "DNA_object_types.h"
66 #include "DNA_screen_types.h"
67 #include "DNA_scene_types.h"
68 #include "DNA_space_types.h"
69 #include "DNA_texture_types.h"
70 #include "DNA_userdef_types.h"
71 #include "DNA_view3d_types.h"
72 #include "DNA_world_types.h"
74 #include "BLI_blenlib.h"
75 #include "BLI_arithb.h"
76 #include "BLI_editVert.h"
78 #include "BKE_action.h"
79 #include "BKE_armature.h"
81 #include "BKE_constraint.h"
82 #include "BKE_curve.h"
83 #include "BKE_displist.h"
84 #include "BKE_depsgraph.h"
85 #include "BKE_DerivedMesh.h"
86 #include "BKE_global.h"
87 #include "BKE_lattice.h"
88 #include "BKE_library.h"
89 #include "BKE_image.h"
93 #include "BKE_object.h"
94 #include "BKE_texture.h"
95 #include "BKE_utildefines.h"
97 #include "BIF_butspace.h"
98 #include "BIF_drawimage.h"
99 #include "BIF_editgroup.h"
100 #include "BIF_editarmature.h"
101 #include "BIF_editmesh.h"
103 #include "BIF_glutil.h"
104 #include "BIF_interface.h"
105 #include "BIF_interface_icons.h"
106 #include "BIF_mywindow.h"
107 #include "BIF_poseobject.h"
108 #include "BIF_previewrender.h"
109 #include "BIF_resources.h"
110 #include "BIF_screen.h"
111 #include "BIF_space.h"
113 #include "BDR_drawmesh.h"
114 #include "BDR_drawobject.h"
115 #include "BDR_editobject.h"
116 #include "BDR_vpaint.h"
118 #include "BSE_drawview.h"
119 #include "BSE_filesel.h"
120 #include "BSE_headerbuttons.h"
121 #include "BSE_seqaudio.h"
122 #include "BSE_trans_types.h"
123 #include "BSE_time.h"
124 #include "BSE_view.h"
126 #include "BPY_extern.h"
128 #include "RE_render_ext.h"
131 #include "mydevice.h"
132 #include "butspace.h" // event codes
134 #include "BIF_transform.h"
140 void drawname(Object *ob);
141 void star_stuff_init_func(void);
142 void star_stuff_vertex_func(float* i);
143 void star_stuff_term_func(void);
145 void star_stuff_init_func(void)
151 void star_stuff_vertex_func(float* i)
155 void star_stuff_term_func(void)
160 void setalpha_bgpic(BGpic *bgpic)
165 alph= (int)(255.0*(1.0-bgpic->blend));
167 rect= (char *)bgpic->rect;
168 for(y=0; y< bgpic->yim; y++) {
169 for(x= bgpic->xim; x>0; x--, rect+=4) {
176 void default_gl_light(void)
181 if(U.light[0].flag==0 && U.light[1].flag==0 && U.light[2].flag==0) {
183 U.light[0].vec[0]= -0.3; U.light[0].vec[1]= 0.3; U.light[0].vec[2]= 0.9;
184 U.light[0].col[0]= 0.8; U.light[0].col[1]= 0.8; U.light[0].col[2]= 0.8;
185 U.light[0].spec[0]= 0.5; U.light[0].spec[1]= 0.5; U.light[0].spec[2]= 0.5;
186 U.light[0].spec[3]= 1.0;
189 U.light[1].vec[0]= 0.5; U.light[1].vec[1]= 0.5; U.light[1].vec[2]= 0.1;
190 U.light[1].col[0]= 0.4; U.light[1].col[1]= 0.4; U.light[1].col[2]= 0.8;
191 U.light[1].spec[0]= 0.3; U.light[1].spec[1]= 0.3; U.light[1].spec[2]= 0.5;
192 U.light[1].spec[3]= 1.0;
195 U.light[2].vec[0]= 0.3; U.light[2].vec[1]= -0.3; U.light[2].vec[2]= -0.2;
196 U.light[2].col[0]= 0.8; U.light[2].col[1]= 0.5; U.light[2].col[2]= 0.4;
197 U.light[2].spec[0]= 0.5; U.light[2].spec[1]= 0.4; U.light[2].spec[2]= 0.3;
198 U.light[2].spec[3]= 1.0;
202 glLightfv(GL_LIGHT0, GL_POSITION, U.light[0].vec);
203 glLightfv(GL_LIGHT0, GL_DIFFUSE, U.light[0].col);
204 glLightfv(GL_LIGHT0, GL_SPECULAR, U.light[0].spec);
206 glLightfv(GL_LIGHT1, GL_POSITION, U.light[1].vec);
207 glLightfv(GL_LIGHT1, GL_DIFFUSE, U.light[1].col);
208 glLightfv(GL_LIGHT1, GL_SPECULAR, U.light[1].spec);
210 glLightfv(GL_LIGHT2, GL_POSITION, U.light[2].vec);
211 glLightfv(GL_LIGHT2, GL_DIFFUSE, U.light[2].col);
212 glLightfv(GL_LIGHT2, GL_SPECULAR, U.light[2].spec);
216 if(U.light[a].flag) glEnable(GL_LIGHT0+a);
217 else glDisable(GL_LIGHT0+a);
219 // clear stuff from other opengl lamp usage
220 glLightf(GL_LIGHT0+a, GL_SPOT_CUTOFF, 180.0);
221 glLightf(GL_LIGHT0+a, GL_CONSTANT_ATTENUATION, 1.0);
222 glLightf(GL_LIGHT0+a, GL_LINEAR_ATTENUATION, 0.0);
224 else glDisable(GL_LIGHT0+a);
227 glDisable(GL_LIGHTING);
229 glDisable(GL_COLOR_MATERIAL);
232 /* also called when render 'ogl' */
233 void init_gl_stuff(void)
235 float mat_ambient[] = { 0.0, 0.0, 0.0, 0.0 };
236 float mat_specular[] = { 0.5, 0.5, 0.5, 1.0 };
237 float mat_shininess[] = { 35.0 };
240 const GLubyte *patc= pat;
243 glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, mat_ambient);
244 glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, mat_specular);
245 glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, mat_specular);
246 glMaterialfv(GL_FRONT_AND_BACK, GL_SHININESS, mat_shininess);
250 /* no local viewer, looks ugly in ortho mode */
251 /* glLightModelfv(GL_LIGHT_MODEL_LOCAL_VIEWER, &one); */
253 glDepthFunc(GL_LEQUAL);
254 /* scaling matrices */
255 glEnable(GL_NORMALIZE);
257 glShadeModel(GL_FLAT);
259 glDisable(GL_ALPHA_TEST);
261 glDisable(GL_DEPTH_TEST);
263 glDisable(GL_LIGHTING);
264 glDisable(GL_LOGIC_OP);
265 glDisable(GL_STENCIL_TEST);
266 glDisable(GL_TEXTURE_1D);
267 glDisable(GL_TEXTURE_2D);
269 glPixelTransferi(GL_MAP_COLOR, GL_FALSE);
270 glPixelTransferi(GL_RED_SCALE, 1);
271 glPixelTransferi(GL_RED_BIAS, 0);
272 glPixelTransferi(GL_GREEN_SCALE, 1);
273 glPixelTransferi(GL_GREEN_BIAS, 0);
274 glPixelTransferi(GL_BLUE_SCALE, 1);
275 glPixelTransferi(GL_BLUE_BIAS, 0);
276 glPixelTransferi(GL_ALPHA_SCALE, 1);
277 glPixelTransferi(GL_ALPHA_BIAS, 0);
279 glPixelTransferi(GL_DEPTH_BIAS, 0);
280 glPixelTransferi(GL_DEPTH_SCALE, 1);
281 glDepthRange(0.0, 1.0);
284 for(x=0; x<32; x++) {
286 if( (x) & 1) pat[a++]= 0x88;
291 glPolygonStipple(patc);
297 void circf(float x, float y, float rad)
299 GLUquadricObj *qobj = gluNewQuadric();
301 gluQuadricDrawStyle(qobj, GLU_FILL);
305 glTranslatef(x, y, 0.);
307 gluDisk( qobj, 0.0, rad, 32, 1);
311 gluDeleteQuadric(qobj);
314 void circ(float x, float y, float rad)
316 GLUquadricObj *qobj = gluNewQuadric();
318 gluQuadricDrawStyle(qobj, GLU_SILHOUETTE);
322 glTranslatef(x, y, 0.);
324 gluDisk( qobj, 0.0, rad, 32, 1);
328 gluDeleteQuadric(qobj);
331 /* ********** ********** */
333 static void draw_bgpic(void)
337 float vec[4], fac, asp, zoomx, zoomy;
338 float x1, y1, x2, y2, cx, cy;
344 extern void init_render_texture(struct Render *re, Tex *tex);
345 /* note; bad call, this has to be recoded to move to blenkernel */
346 init_render_texture(NULL, bgpic->tex);
347 free_unused_animimages();
348 ima= bgpic->tex->ima;
355 if(ima->ok==0) return;
362 if(bgpic->rect) MEM_freeN(bgpic->rect);
366 ima_ibuf_is_nul(bgpic->tex, bgpic->tex->ima);
370 load_image(ima, IB_rect, G.sce, G.scene->r.cfra);
381 bgpic->rect= MEM_dupallocN(ima->ibuf->rect);
382 bgpic->xim= ima->ibuf->x;
383 bgpic->yim= ima->ibuf->y;
384 setalpha_bgpic(bgpic);
390 calc_viewborder(G.vd, &vb);
400 /* calc window coord */
401 initgrabz(0.0, 0.0, 0.0);
402 window_to_3d(vec, 1, 0);
403 fac= MAX3( fabs(vec[0]), fabs(vec[1]), fabs(vec[1]) );
406 asp= ( (float)ima->ibuf->y)/(float)ima->ibuf->x;
408 vec[0] = vec[1] = vec[2] = 0.0;
409 view3d_project_float(curarea, vec, sco, G.vd->persmat);
413 x1= cx+ fac*(bgpic->xof-bgpic->size);
414 y1= cy+ asp*fac*(bgpic->yof-bgpic->size);
415 x2= cx+ fac*(bgpic->xof+bgpic->size);
416 y2= cy+ asp*fac*(bgpic->yof+bgpic->size);
423 if(x1 > curarea->winx ) return;
424 if(y1 > curarea->winy ) return;
426 zoomx= (x2-x1)/ima->ibuf->x;
427 zoomy= (y2-y1)/ima->ibuf->y;
430 if(G.vd->zbuf) glDisable(GL_DEPTH_TEST);
432 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
434 glMatrixMode(GL_PROJECTION);
436 glMatrixMode(GL_MODELVIEW);
439 glaDefine2DArea(&curarea->winrct);
440 glPixelZoom(zoomx, zoomy);
441 glaDrawPixelsSafe(x1, y1, ima->ibuf->x, ima->ibuf->y, ima->ibuf->x, GL_RGBA, GL_UNSIGNED_BYTE, bgpic->rect);
442 glPixelZoom(1.0, 1.0);
444 glMatrixMode(GL_PROJECTION);
446 glMatrixMode(GL_MODELVIEW);
449 glBlendFunc(GL_ONE, GL_ZERO);
451 if(G.vd->zbuf) glEnable(GL_DEPTH_TEST);
453 areawinset(curarea->win); // restore viewport / scissor
456 static void drawgrid_draw(float wx, float wy, float x, float y, float dx)
465 while(fx< curarea->winx) {
466 fdrawline(fx, 0.0, fx, (float)curarea->winy);
474 while(fy< curarea->winy) {
475 fdrawline(0.0, fy, (float)curarea->winx, fy);
481 // not intern, called in editobject for constraint axis too
482 void make_axis_color(char *col, char *col2, char axis)
485 col2[0]= col[0]>219?255:col[0]+36;
486 col2[1]= col[1]<26?0:col[1]-26;
487 col2[2]= col[2]<26?0:col[2]-26;
490 col2[0]= col[0]<46?0:col[0]-36;
491 col2[1]= col[1]>189?255:col[1]+66;
492 col2[2]= col[2]<46?0:col[2]-36;
495 col2[0]= col[0]<26?0:col[0]-26;
496 col2[1]= col[1]<26?0:col[1]-26;
497 col2[2]= col[2]>209?255:col[2]+46;
502 static void drawgrid(void)
504 /* extern short bgpicmode; */
505 float wx, wy, x, y, fw, fx, fy, dx;
507 char col[3], col2[3];
509 vec4[0]=vec4[1]=vec4[2]=0.0;
511 Mat4MulVec4fl(G.vd->persmat, vec4);
516 wx= (curarea->winx/2.0); /* because of rounding errors, grid at wrong location */
517 wy= (curarea->winy/2.0);
522 vec4[0]=vec4[1]=G.vd->grid;
525 Mat4MulVec4fl(G.vd->persmat, vec4);
530 dx= fabs(x-(wx)*fx/fw);
531 if(dx==0) dx= fabs(y-(wy)*fy/fw);
533 glDepthMask(0); // disable write in zbuffer
536 BIF_ThemeColor(TH_GRID);
540 G.vd->gridview*= 10.0;
544 G.vd->gridview*= 10.0;
548 G.vd->gridview*= 10.0;
552 BIF_ThemeColor(TH_GRID);
553 drawgrid_draw(wx, wy, x, y, dx);
556 else { // start blending out
557 BIF_ThemeColorBlend(TH_BACK, TH_GRID, dx/60.0);
558 drawgrid_draw(wx, wy, x, y, dx);
560 BIF_ThemeColor(TH_GRID);
561 drawgrid_draw(wx, wy, x, y, 10*dx);
564 else { // start blending out (6 < dx < 60)
565 BIF_ThemeColorBlend(TH_BACK, TH_GRID, dx/60.0);
566 drawgrid_draw(wx, wy, x, y, dx);
568 BIF_ThemeColor(TH_GRID);
569 drawgrid_draw(wx, wy, x, y, 10*dx);
573 if(dx>60.0) { // start blending in
574 G.vd->gridview/= 10.0;
576 if(dx>60.0) { // start blending in
577 G.vd->gridview/= 10.0;
580 BIF_ThemeColor(TH_GRID);
581 drawgrid_draw(wx, wy, x, y, dx);
584 BIF_ThemeColorBlend(TH_BACK, TH_GRID, dx/60.0);
585 drawgrid_draw(wx, wy, x, y, dx);
586 BIF_ThemeColor(TH_GRID);
587 drawgrid_draw(wx, wy, x, y, dx*10);
591 BIF_ThemeColorBlend(TH_BACK, TH_GRID, dx/60.0);
592 drawgrid_draw(wx, wy, x, y, dx);
593 BIF_ThemeColor(TH_GRID);
594 drawgrid_draw(wx, wy, x, y, dx*10);
598 BIF_ThemeColorBlend(TH_BACK, TH_GRID, dx/60.0);
599 drawgrid_draw(wx, wy, x, y, dx);
600 BIF_ThemeColor(TH_GRID);
601 drawgrid_draw(wx, wy, x, y, dx*10);
607 BIF_GetThemeColor3ubv(TH_GRID, col);
612 if(G.vd->view==3) make_axis_color(col, col2, 'y');
613 else make_axis_color(col, col2, 'x');
616 fdrawline(0.0, y, (float)curarea->winx, y);
618 if(G.vd->view==7) make_axis_color(col, col2, 'y');
619 else make_axis_color(col, col2, 'z');
622 fdrawline(x, 0.0, x, (float)curarea->winy);
624 glDepthMask(1); // enable write in zbuffer
629 static void drawfloor(void)
634 char col[3], col2[3];
637 vd= curarea->spacedata.first;
641 if(vd->gridlines<3) return;
643 if(G.vd->zbuf && G.obedit) glDepthMask(0); // for zbuffer-select
645 gridlines= vd->gridlines/2;
646 grid= gridlines*vd->grid;
648 BIF_GetThemeColor3ubv(TH_GRID, col);
650 /* draw the Y axis and/or grid lines */
651 for(a= -gridlines;a<=gridlines;a++) {
653 /* check for the 'show Y axis' preference */
654 if (vd->gridflag & V3D_SHOW_Y) {
655 make_axis_color(col, col2, 'y');
659 } else if (vd->gridflag & V3D_SHOW_FLOOR) {
660 BIF_ThemeColorShade(TH_GRID, -10);
665 /* check for the 'show grid floor' preference */
666 if (vd->gridflag & V3D_SHOW_FLOOR) {
668 BIF_ThemeColorShade(TH_GRID, -10);
670 else BIF_ThemeColorShade(TH_GRID, 10);
679 glBegin(GL_LINE_STRIP);
689 /* draw the X axis and/or grid lines */
690 for(a= -gridlines;a<=gridlines;a++) {
692 /* check for the 'show X axis' preference */
693 if (vd->gridflag & V3D_SHOW_X) {
694 make_axis_color(col, col2, 'x');
698 } else if (vd->gridflag & V3D_SHOW_FLOOR) {
699 BIF_ThemeColorShade(TH_GRID, -10);
704 /* check for the 'show grid floor' preference */
705 if (vd->gridflag & V3D_SHOW_FLOOR) {
707 BIF_ThemeColorShade(TH_GRID, -10);
709 else BIF_ThemeColorShade(TH_GRID, 10);
718 glBegin(GL_LINE_STRIP);
728 /* draw the Z axis line */
729 /* check for the 'show Z axis' preference */
730 if (vd->gridflag & V3D_SHOW_Z) {
731 make_axis_color(col, col2, 'z');
734 glBegin(GL_LINE_STRIP);
744 if(G.vd->zbuf && G.obedit) glDepthMask(1);
748 static void drawcursor(View3D *v3d)
753 /* we dont want the clipping for cursor */
756 project_short( give_cursor(), co);
765 circ((float)mx, (float)my, 10.0);
768 circ((float)mx, (float)my, 10.0);
772 sdrawline(mx-20, my, mx-5, my);
773 sdrawline(mx+5, my, mx+20, my);
774 sdrawline(mx, my-20, mx, my-5);
775 sdrawline(mx, my+5, mx, my+20);
779 /* ********* custom clipping *********** */
781 static void view3d_draw_clipping(View3D *v3d)
783 BoundBox *bb= v3d->clipbb;
785 BIF_ThemeColorShade(TH_BACK, -8);
789 glVertex3fv(bb->vec[0]); glVertex3fv(bb->vec[1]); glVertex3fv(bb->vec[2]); glVertex3fv(bb->vec[3]);
790 glVertex3fv(bb->vec[0]); glVertex3fv(bb->vec[4]); glVertex3fv(bb->vec[5]); glVertex3fv(bb->vec[1]);
791 glVertex3fv(bb->vec[4]); glVertex3fv(bb->vec[7]); glVertex3fv(bb->vec[6]); glVertex3fv(bb->vec[5]);
792 glVertex3fv(bb->vec[7]); glVertex3fv(bb->vec[3]); glVertex3fv(bb->vec[2]); glVertex3fv(bb->vec[6]);
793 glVertex3fv(bb->vec[1]); glVertex3fv(bb->vec[5]); glVertex3fv(bb->vec[6]); glVertex3fv(bb->vec[2]);
794 glVertex3fv(bb->vec[7]); glVertex3fv(bb->vec[4]); glVertex3fv(bb->vec[0]); glVertex3fv(bb->vec[3]);
799 void view3d_set_clipping(View3D *v3d)
805 QUATCOPY(plane, v3d->clip[a]);
806 glClipPlane(GL_CLIP_PLANE0+a, plane);
807 glEnable(GL_CLIP_PLANE0+a);
811 void view3d_clr_clipping(void)
816 glDisable(GL_CLIP_PLANE0+a);
820 int view3d_test_clipping(View3D *v3d, float *vec)
822 /* vec in world coordinates, returns 1 if clipped */
827 if(0.0f < v3d->clip[0][3] + INPR(view, v3d->clip[0]))
828 if(0.0f < v3d->clip[1][3] + INPR(view, v3d->clip[1]))
829 if(0.0f < v3d->clip[2][3] + INPR(view, v3d->clip[2]))
830 if(0.0f < v3d->clip[3][3] + INPR(view, v3d->clip[3]))
836 /* ********* end custom clipping *********** */
838 static void view3d_get_viewborder_size(View3D *v3d, float size_r[2])
840 float winmax= MAX2(v3d->area->winx, v3d->area->winy);
841 float aspect= (float) (G.scene->r.xsch*G.scene->r.xasp)/(G.scene->r.ysch*G.scene->r.yasp);
845 size_r[1]= winmax/aspect;
847 size_r[0]= winmax*aspect;
852 void calc_viewborder(struct View3D *v3d, rcti *viewborder_r)
854 float zoomfac, size[2];
855 float dx= 0.0f, dy= 0.0f;
857 view3d_get_viewborder_size(v3d, size);
859 /* magic zoom calculation, no idea what
860 * it signifies, if you find out, tell me! -zr
862 /* simple, its magic dude!
863 * well, to be honest, this gives a natural feeling zooming
864 * with multiple keypad presses (ton)
867 zoomfac= (M_SQRT2 + v3d->camzoom/50.0);
868 zoomfac= (zoomfac*zoomfac)*0.25;
870 size[0]= size[0]*zoomfac;
871 size[1]= size[1]*zoomfac;
873 /* center in window */
874 viewborder_r->xmin= 0.5*v3d->area->winx - 0.5*size[0];
875 viewborder_r->ymin= 0.5*v3d->area->winy - 0.5*size[1];
876 viewborder_r->xmax= viewborder_r->xmin + size[0];
877 viewborder_r->ymax= viewborder_r->ymin + size[1];
879 dx= v3d->area->winx*G.vd->camdx;
880 dy= v3d->area->winy*G.vd->camdy;
883 viewborder_r->xmin-= dx;
884 viewborder_r->ymin-= dy;
885 viewborder_r->xmax-= dx;
886 viewborder_r->ymax-= dy;
889 void view3d_set_1_to_1_viewborder(View3D *v3d)
892 int im_width= (G.scene->r.size*G.scene->r.xsch)/100;
894 view3d_get_viewborder_size(v3d, size);
896 v3d->camzoom= (sqrt(4.0*im_width/size[0]) - M_SQRT2)*50.0;
897 v3d->camzoom= CLAMPIS(v3d->camzoom, -30, 300);
900 static void drawviewborder(void)
902 extern void gl_round_box(int mode, float minx, float miny, float maxx, float maxy, float rad); // interface_panel.c
904 float x1, x2, y1, y2;
905 float x3, y3, x4, y4;
909 if(G.vd->camera==NULL)
911 if(G.vd->camera->type==OB_CAMERA)
912 ca = G.vd->camera->data;
914 calc_viewborder(G.vd, &viewborder);
920 /* passepartout, specified in camera edit buttons */
921 if (ca && (ca->flag & CAM_SHOWPASSEPARTOUT)) {
922 glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
924 glColor4f(0, 0, 0, ca->passepartalpha);
927 glRectf(0.0, (float)curarea->winy, x1, 0.0);
928 if (x2 < (float)curarea->winx)
929 glRectf(x2, (float)curarea->winy, (float)curarea->winx, 0.0);
930 if (y2 < (float)curarea->winy)
931 glRectf(x1, (float)curarea->winy, x2, y2);
933 glRectf(x1, y1, x2, 0.0);
939 glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
942 BIF_ThemeColor(TH_BACK);
943 glRectf(x1, y1, x2, y2);
946 BIF_ThemeColor(TH_WIRE);
947 glRectf(x1, y1, x2, y2);
950 if (ca && (ca->flag & CAM_SHOWNAME)) {
951 glRasterPos2f(x1, y1-15);
953 BMF_DrawString(G.font, G.vd->camera->id.name+2);
958 if(G.scene->r.mode & R_BORDER) {
961 x3= x1+ G.scene->r.border.xmin*(x2-x1);
962 y3= y1+ G.scene->r.border.ymin*(y2-y1);
963 x4= x1+ G.scene->r.border.xmax*(x2-x1);
964 y4= y1+ G.scene->r.border.ymax*(y2-y1);
967 glRectf(x3, y3, x4, y4);
971 if (ca && (ca->flag & CAM_SHOWTITLESAFE)) {
982 BIF_ThemeColorBlendShade(TH_WIRE, TH_BACK, 0.25, 0);
985 gl_round_box(GL_LINE_LOOP, x1, y1, x2, y2, 12.0);
989 glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
994 void backdrawview3d(int test)
998 if(G.f & (G_VERTEXPAINT|G_FACESELECT|G_TEXTUREPAINT|G_WEIGHTPAINT));
999 else if(G.obedit && G.vd->drawtype>OB_WIRE && (G.vd->flag & V3D_ZBUF_SELECT));
1001 G.vd->flag &= ~V3D_NEEDBACKBUFDRAW;
1005 if( !(G.vd->flag & V3D_NEEDBACKBUFDRAW) ) return;
1009 addafterqueue(curarea->win, BACKBUFDRAW, 1);
1016 glDrawBuffer(GL_AUX0);
1018 if(G.vd->drawtype > OB_WIRE) G.vd->zbuf= TRUE;
1019 curarea->win_swap &= ~WIN_BACK_OK;
1021 glDisable(GL_DITHER);
1023 glClearColor(0.0, 0.0, 0.0, 0.0);
1025 glEnable(GL_DEPTH_TEST);
1026 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
1029 glClear(GL_COLOR_BUFFER_BIT);
1030 glDisable(GL_DEPTH_TEST);
1033 if(G.vd->flag & V3D_CLIPPING)
1034 view3d_set_clipping(G.vd);
1036 G.f |= G_BACKBUFSEL;
1038 base= (G.scene->basact);
1039 if(base && (base->lay & G.vd->lay)) {
1040 draw_object_backbufsel(base->object);
1043 G.vd->flag &= ~V3D_NEEDBACKBUFDRAW;
1045 G.f &= ~G_BACKBUFSEL;
1047 glDisable(GL_DEPTH_TEST);
1048 glEnable(GL_DITHER);
1051 glDrawBuffer(GL_BACK); /* we were in aux buffers */
1054 if(G.vd->flag & V3D_CLIPPING)
1055 view3d_clr_clipping();
1057 /* it is important to end a view in a transform compatible with buttons */
1058 persp(PERSP_WIN); // set ortho
1059 bwin_scalematrix(curarea->win, G.vd->blockscale, G.vd->blockscale, G.vd->blockscale);
1063 void check_backbuf(void)
1065 if(G.vd->flag & V3D_NEEDBACKBUFDRAW)
1069 /* samples a single pixel (copied from vpaint) */
1070 unsigned int sample_backbuf(int x, int y)
1074 if(x>=curarea->winx || y>=curarea->winy) return 0;
1075 x+= curarea->winrct.xmin;
1076 y+= curarea->winrct.ymin;
1078 check_backbuf(); // actually not needed for apple
1081 glReadBuffer(GL_AUX0);
1083 glReadPixels(x, y, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, &col);
1084 glReadBuffer(GL_BACK);
1086 if(G.order==B_ENDIAN) SWITCH_INT(col);
1088 return framebuffer_to_index(col);
1091 /* reads full rect, converts indices */
1092 ImBuf *read_backbuf(short xmin, short ymin, short xmax, short ymax)
1094 unsigned int *dr, *rd;
1095 struct ImBuf *ibuf, *ibuf1;
1097 short xminc, yminc, xmaxc, ymaxc, xs, ys;
1100 if(xmin<0) xminc= 0; else xminc= xmin;
1101 if(xmax>=curarea->winx) xmaxc= curarea->winx-1; else xmaxc= xmax;
1102 if(xminc > xmaxc) return NULL;
1104 if(ymin<0) yminc= 0; else yminc= ymin;
1105 if(ymax>=curarea->winy) ymaxc= curarea->winy-1; else ymaxc= ymax;
1106 if(yminc > ymaxc) return NULL;
1108 ibuf= IMB_allocImBuf((xmaxc-xminc+1),(ymaxc-yminc+1),32,IB_rect,0);
1110 check_backbuf(); // actually not needed for apple
1113 glReadBuffer(GL_AUX0);
1115 glReadPixels(curarea->winrct.xmin+xminc, curarea->winrct.ymin+yminc, (xmaxc-xminc+1), (ymaxc-yminc+1), GL_RGBA, GL_UNSIGNED_BYTE, ibuf->rect);
1116 glReadBuffer(GL_BACK);
1118 if(G.order==B_ENDIAN) IMB_convert_rgba_to_abgr(ibuf);
1120 a= (xmaxc-xminc+1)*(ymaxc-yminc+1);
1123 if(*dr) *dr= framebuffer_to_index(*dr);
1127 /* put clipped result back, if needed */
1128 if(xminc==xmin && xmaxc==xmax && yminc==ymin && ymaxc==ymax) return ibuf;
1129 ibuf1= IMB_allocImBuf( (xmax-xmin+1),(ymax-ymin+1),32,IB_rect,0);
1133 for(ys= ymin; ys<=ymax; ys++) {
1134 for(xs= xmin; xs<=xmax; xs++, dr++) {
1135 if( xs>=xminc && xs<=xmaxc && ys>=yminc && ys<=ymaxc) {
1141 IMB_freeImBuf(ibuf);
1145 /* smart function to sample a rect spiralling outside, nice for backbuf selection */
1146 unsigned int sample_backbuf_rect(short mval[2], int size, unsigned int min, unsigned int max, short *dist)
1149 unsigned int *bufmin, *bufmax, *tbuf;
1151 int a, b, rc, nr, amount, dirvec[4][2];
1153 unsigned int index = 0;
1157 minx = mval[0]-(amount+1);
1158 miny = mval[1]-(amount+1);
1159 buf = read_backbuf(minx, miny, minx+size-1, miny+size-1);
1164 dirvec[0][0]= 1; dirvec[0][1]= 0;
1165 dirvec[1][0]= 0; dirvec[1][1]= -size;
1166 dirvec[2][0]= -1; dirvec[2][1]= 0;
1167 dirvec[3][0]= 0; dirvec[3][1]= size;
1171 bufmax = buf->rect + size*size;
1172 tbuf+= amount*size+ amount;
1174 for(nr=1; nr<=size; nr++) {
1176 for(a=0; a<2; a++) {
1177 for(b=0; b<nr; b++, distance++) {
1178 if (*tbuf && *tbuf>=min && *tbuf<max) {
1179 *dist= (short) sqrt( (float)distance ); // XXX, this distance is wrong - zr
1180 index = *tbuf - min+1; // messy yah, but indices start at 1
1184 tbuf+= (dirvec[rc][0]+dirvec[rc][1]);
1186 if(tbuf<bufmin || tbuf>=bufmax) {
1200 void drawname(Object *ob)
1203 glRasterPos3f(0.0, 0.0, 0.0);
1205 BMF_DrawString(G.font, " ");
1206 BMF_DrawString(G.font, ob->id.name+2);
1210 static void draw_selected_name(Object *ob)
1214 if(ob->type==OB_ARMATURE) {
1215 bArmature *arm= ob->data;
1220 for (ebo=G.edbo.first; ebo; ebo=ebo->next){
1221 if ((ebo->flag & BONE_ACTIVE) && (ebo->layer & arm->layer)) {
1227 else if(ob->pose && (ob->flag & OB_POSEMODE)) {
1228 bPoseChannel *pchan;
1229 for(pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) {
1230 if((pchan->bone->flag & BONE_ACTIVE) && (pchan->bone->layer & arm->layer)) {
1237 sprintf(info, "(%d) %s %s", CFRA, ob->id.name+2, name);
1239 sprintf(info, "(%d) %s", CFRA, ob->id.name+2);
1241 else sprintf(info, "(%d) %s", CFRA, ob->id.name+2);
1243 BIF_ThemeColor(TH_TEXT_HI);
1244 glRasterPos2i(30, 10);
1245 BMF_DrawString(G.fonts, info);
1249 static void draw_view_icon(void)
1253 if(G.vd->view==7) icon= ICON_AXIS_TOP;
1254 else if(G.vd->view==1) icon= ICON_AXIS_FRONT;
1255 else if(G.vd->view==3) icon= ICON_AXIS_SIDE;
1259 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
1261 BIF_icon_draw(5.0, 5.0, icon);
1263 glBlendFunc(GL_ONE, GL_ZERO);
1264 glDisable(GL_BLEND);
1267 /* ******************* view3d space & buttons ************** */
1269 static void view3d_change_bgpic_ima(View3D *v3d, Image *newima) {
1270 if (v3d->bgpic && v3d->bgpic->ima!=newima) {
1272 id_us_plus((ID*) newima);
1273 if (v3d->bgpic->ima)
1274 v3d->bgpic->ima->id.us--;
1275 v3d->bgpic->ima= newima;
1277 if(v3d->bgpic->rect) MEM_freeN(v3d->bgpic->rect);
1278 v3d->bgpic->rect= NULL;
1280 allqueue(REDRAWVIEW3D, 0);
1283 static void view3d_change_bgpic_tex(View3D *v3d, Tex *newtex) {
1284 if (v3d->bgpic && v3d->bgpic->tex!=newtex) {
1286 id_us_plus((ID*) newtex);
1287 if (v3d->bgpic->tex)
1288 v3d->bgpic->tex->id.us--;
1289 v3d->bgpic->tex= newtex;
1291 allqueue(REDRAWVIEW3D, 0);
1295 static void load_bgpic_image(char *name)
1300 areawinset(curarea->win);
1302 if(vd==0 || vd->bgpic==0) return;
1304 ima= add_image(name);
1306 if(vd->bgpic->ima) {
1307 vd->bgpic->ima->id.us--;
1309 vd->bgpic->ima= ima;
1311 free_image_buffers(ima); /* force read again */
1314 allqueue(REDRAWVIEW3D, 0);
1318 /* this one assumes there is only one global active object in blender... (for object panel) */
1319 static float ob_eul[4]; // used for quat too....
1320 /* this one assumes there is only one editmode in blender... (for object panel) */
1321 static float ve_median[5];
1323 /* is used for both read and write... */
1324 static void v3d_editvertex_buts(uiBlock *block, Object *ob, float lim)
1326 static int curdef=0;
1327 static float *defweightp= NULL;
1328 EditMesh *em = G.editMesh;
1329 EditVert *eve, *evedef=NULL;
1332 int tot, totw, totweight, totedge;
1335 median[0]= median[1]= median[2]= median[3]= median[4]= 0.0;
1336 tot= totw= totweight= totedge= 0;
1339 if(ob->type==OB_MESH) {
1340 eve= em->verts.first;
1345 VecAddf(median, median, eve->co);
1349 eed= em->edges.first;
1351 if((eed->f & SELECT)) {
1353 median[3]+= eed->crease;
1357 /* check for defgroups */
1358 if(tot==1 && evedef->totweight) {
1360 int i, max=1, init=1;
1363 for (i=0; i<evedef->totweight; i++){
1364 dg = BLI_findlink (&ob->defbase, evedef->dw[i].def_nr);
1366 max+= sprintf(str, "%s %%x%d|", dg->name, evedef->dw[i].def_nr);
1367 if(max<320) strcat(defstr, str);
1369 else printf("oh no!\n");
1370 if(curdef==evedef->dw[i].def_nr) {
1372 defweightp= &evedef->dw[i].weight;
1376 if(init) { // needs new initialized
1377 curdef= evedef->dw[0].def_nr;
1378 defweightp= &evedef->dw[0].weight;
1382 else if(ob->type==OB_CURVE || ob->type==OB_SURF) {
1383 extern ListBase editNurb; /* editcurve.c */
1391 if((nu->type & 7)==1) {
1396 VecAddf(median, median, bezt->vec[1]);
1398 median[4]+= bezt->weight;
1403 VecAddf(median, median, bezt->vec[0]);
1407 VecAddf(median, median, bezt->vec[2]);
1416 a= nu->pntsu*nu->pntsv;
1419 VecAddf(median, median, bp->vec);
1420 median[3]+= bp->vec[3];
1423 median[4]+= bp->weight;
1432 else if(ob->type==OB_LATTICE) {
1436 a= editLatt->pntsu*editLatt->pntsv*editLatt->pntsw;
1439 if(bp->f1 & SELECT) {
1440 VecAddf(median, median, bp->vec);
1442 median[4]+= bp->weight;
1451 median[0] /= (float)tot;
1452 median[1] /= (float)tot;
1453 median[2] /= (float)tot;
1454 if(totedge) median[3] /= (float)totedge;
1455 else if(totw) median[3] /= (float)totw;
1456 if(totweight) median[4] /= (float)totweight;
1458 if(G.vd->flag & V3D_GLOBAL_STATS)
1459 Mat4MulVecfl(ob->obmat, median);
1461 if(block) { // buttons
1463 uiBlockBeginAlign(block);
1464 uiDefButBitS(block, TOG, V3D_GLOBAL_STATS, REDRAWVIEW3D, "Global", 160, 150, 70, 19, &G.vd->flag, 0, 0, 0, 0, "Displays global values");
1465 uiDefButBitS(block, TOGN, V3D_GLOBAL_STATS, REDRAWVIEW3D, "Local", 230, 150, 70, 19, &G.vd->flag, 0, 0, 0, 0, "Displays local values");
1467 memcpy(ve_median, median, sizeof(ve_median));
1469 uiBlockBeginAlign(block);
1471 uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, "Vertex X:", 10, 110, 290, 19, &(ve_median[0]), -lim, lim, 10, 3, "");
1472 uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, "Vertex Y:", 10, 90, 290, 19, &(ve_median[1]), -lim, lim, 10, 3, "");
1473 uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, "Vertex Z:", 10, 70, 290, 19, &(ve_median[2]), -lim, lim, 10, 3, "");
1475 uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, "Vertex W:", 10, 50, 290, 19, &(ve_median[3]), 0.01, 100.0, 10, 3, "");
1476 uiBlockEndAlign(block);
1479 uiDefBut(block, LABEL, 1, "Vertex Deform Groups", 10, 40, 290, 20, NULL, 0.0, 0.0, 0, 0, "");
1481 uiBlockBeginAlign(block);
1482 uiDefButF(block, NUM, B_NOP, "Weight:", 10, 20, 150, 19, defweightp, 0.0f, 1.0f, 10, 3, "Weight value");
1483 uiDefButI(block, MENU, REDRAWVIEW3D, defstr, 160, 20, 140, 19, &curdef, 0.0, 0.0, 0, 0, "Current Vertex Group");
1484 uiBlockEndAlign(block);
1487 uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, "Weight:", 10, 20, 290, 19, &(ve_median[4]), 0.0, 1.0, 10, 3, "");
1491 uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, "Median X:", 10, 110, 290, 19, &(ve_median[0]), -lim, lim, 10, 3, "");
1492 uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, "Median Y:", 10, 90, 290, 19, &(ve_median[1]), -lim, lim, 10, 3, "");
1493 uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, "Median Z:", 10, 70, 290, 19, &(ve_median[2]), -lim, lim, 10, 3, "");
1495 uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, "Median W:", 10, 50, 290, 19, &(ve_median[3]), 0.01, 100.0, 10, 3, "");
1496 uiBlockEndAlign(block);
1498 uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, "Weight:", 10, 20, 290, 19, &(ve_median[4]), 0.0, 1.0, 10, 3, "Weight is used for SoftBody Goal");
1502 uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, "Crease W:", 10, 30, 290, 19, &(ve_median[3]), 0.0, 1.0, 10, 3, "");
1504 uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, "Median Crease W:", 10, 30, 290, 19, &(ve_median[3]), 0.0, 1.0, 10, 3, "");
1509 if(G.vd->flag & V3D_GLOBAL_STATS) {
1510 Mat4Invert(ob->imat, ob->obmat);
1511 Mat4MulVecfl(ob->imat, median);
1512 Mat4MulVecfl(ob->imat, ve_median);
1514 VecSubf(median, ve_median, median);
1515 median[3]= ve_median[3]-median[3];
1516 median[4]= ve_median[4]-median[4];
1518 if(ob->type==OB_MESH) {
1521 eve= em->verts.first;
1524 VecAddf(eve->co, eve->co, median);
1529 /* calculate the differences to squeeze a range smaller when values are close to 1 or 0 */
1530 /* this way you can edit a median value which is applied on clipped values :) */
1533 for(eed= em->edges.first; eed; eed= eed->next) {
1534 if(eed->f & SELECT) {
1535 if(max < ABS(eed->crease-ve_median[3])) max= ABS(eed->crease-ve_median[3]);
1539 if(ve_median[3]> 0.5) diffac= (1.0-ve_median[3])/max;
1540 else diffac= (ve_median[3])/max;
1541 if(diffac>1.0) diffac= 1.0;
1545 for(eed= em->edges.first; eed; eed= eed->next) {
1546 if(eed->f & SELECT) {
1547 eed->crease+= median[3];
1548 eed->crease= ve_median[3] + diffac*(eed->crease-ve_median[3]);
1550 CLAMP(eed->crease, 0.0, 1.0);
1554 recalc_editnormals();
1556 else if(ob->type==OB_CURVE || ob->type==OB_SURF) {
1557 extern ListBase editNurb; /* editcurve.c */
1565 if((nu->type & 7)==1) {
1570 VecAddf(bezt->vec[0], bezt->vec[0], median);
1571 VecAddf(bezt->vec[1], bezt->vec[1], median);
1572 VecAddf(bezt->vec[2], bezt->vec[2], median);
1573 bezt->weight+= median[4];
1577 VecAddf(bezt->vec[0], bezt->vec[0], median);
1580 VecAddf(bezt->vec[2], bezt->vec[2], median);
1588 a= nu->pntsu*nu->pntsv;
1591 VecAddf(bp->vec, bp->vec, median);
1592 bp->vec[3]+= median[3];
1593 bp->weight+= median[4];
1599 testhandlesNurb(nu); /* test for bezier too */
1604 else if(ob->type==OB_LATTICE) {
1608 a= editLatt->pntsu*editLatt->pntsv*editLatt->pntsw;
1611 if(bp->f1 & SELECT) {
1612 VecAddf(bp->vec, bp->vec, median);
1613 bp->weight+= median[4];
1619 BIF_undo_push("Transform properties");
1623 /* assumes armature active */
1624 static void validate_bonebutton_cb(void *bonev, void *namev)
1628 if(ob && ob->type==OB_ARMATURE) {
1630 char oldname[32], newname[32];
1632 /* need to be on the stack */
1633 BLI_strncpy(newname, bone->name, 32);
1634 BLI_strncpy(oldname, (char *)namev, 32);
1636 BLI_strncpy(bone->name, oldname, 32);
1638 armature_bone_rename(ob->data, oldname, newname); // editarmature.c
1639 allqueue(REDRAWALL, 0);
1644 static void v3d_posearmature_buts(uiBlock *block, Object *ob, float lim)
1648 bPoseChannel *pchan;
1651 arm = get_armature(OBACT);
1652 if (!arm || !ob->pose) return;
1654 for(pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) {
1656 if(bone && (bone->flag & BONE_ACTIVE) && (bone->layer & arm->layer))
1661 but= uiDefBut(block, TEX, B_DIFF, "Bone:", 160, 140, 140, 19, bone->name, 1, 31, 0, 0, "");
1662 uiButSetFunc(but, validate_bonebutton_cb, bone, NULL);
1664 QuatToEul(pchan->quat, ob_eul);
1665 ob_eul[0]*= 180.0/M_PI;
1666 ob_eul[1]*= 180.0/M_PI;
1667 ob_eul[2]*= 180.0/M_PI;
1669 uiBlockBeginAlign(block);
1670 uiDefIconButBitS(block, ICONTOG, OB_LOCK_LOCX, REDRAWVIEW3D, ICON_UNLOCKED, 10,140,20,19, &(pchan->protectflag), 0, 0, 0, 0, "Protects this value from being Transformed");
1671 uiDefButF(block, NUM, B_ARMATUREPANEL2, "LocX:", 30, 140, 120, 19, pchan->loc, -lim, lim, 100, 3, "");
1672 uiDefIconButBitS(block, ICONTOG, OB_LOCK_LOCY, REDRAWVIEW3D, ICON_UNLOCKED, 10,120,20,19, &(pchan->protectflag), 0, 0, 0, 0, "Protects this value from being Transformed");
1673 uiDefButF(block, NUM, B_ARMATUREPANEL2, "LocY:", 30, 120, 120, 19, pchan->loc+1, -lim, lim, 100, 3, "");
1674 uiDefIconButBitS(block, ICONTOG, OB_LOCK_LOCZ, REDRAWVIEW3D, ICON_UNLOCKED, 10,100,20,19, &(pchan->protectflag), 0, 0, 0, 0, "Protects this value from being Transformed");
1675 uiDefButF(block, NUM, B_ARMATUREPANEL2, "locZ:", 30, 100, 120, 19, pchan->loc+2, -lim, lim, 100, 3, "");
1677 uiBlockBeginAlign(block);
1678 uiDefIconButBitS(block, ICONTOG, OB_LOCK_ROTX, REDRAWVIEW3D, ICON_UNLOCKED, 10,70,20,19, &(pchan->protectflag), 0, 0, 0, 0, "Protects this value from being Transformed");
1679 uiDefButF(block, NUM, B_ARMATUREPANEL3, "RotX:", 30, 70, 120, 19, ob_eul, -1000.0, 1000.0, 100, 3, "");
1680 uiDefIconButBitS(block, ICONTOG, OB_LOCK_ROTY, REDRAWVIEW3D, ICON_UNLOCKED, 10,50,20,19, &(pchan->protectflag), 0, 0, 0, 0, "Protects this value from being Transformed");
1681 uiDefButF(block, NUM, B_ARMATUREPANEL3, "RotY:", 30, 50, 120, 19, ob_eul+1, -1000.0, 1000.0, 100, 3, "");
1682 uiDefIconButBitS(block, ICONTOG, OB_LOCK_ROTZ, REDRAWVIEW3D, ICON_UNLOCKED, 10,30,20,19, &(pchan->protectflag), 0, 0, 0, 0, "Protects this value from being Transformed");
1683 uiDefButF(block, NUM, B_ARMATUREPANEL3, "RotZ:", 30, 30, 120, 19, ob_eul+2, -1000.0, 1000.0, 100, 3, "");
1685 uiBlockBeginAlign(block);
1686 uiDefIconButBitS(block, ICONTOG, OB_LOCK_SIZEX, REDRAWVIEW3D, ICON_UNLOCKED, 160,70,20,19, &(pchan->protectflag), 0, 0, 0, 0, "Protects this value from being Transformed");
1687 uiDefButF(block, NUM, B_ARMATUREPANEL2, "SizeX:", 180, 70, 120, 19, pchan->size, -lim, lim, 10, 3, "");
1688 uiDefIconButBitS(block, ICONTOG, OB_LOCK_SIZEY, REDRAWVIEW3D, ICON_UNLOCKED, 160,50,20,19, &(pchan->protectflag), 0, 0, 0, 0, "Protects this value from being Transformed");
1689 uiDefButF(block, NUM, B_ARMATUREPANEL2, "SizeY:", 180, 50, 120, 19, pchan->size+1, -lim, lim, 10, 3, "");
1690 uiDefIconButBitS(block, ICONTOG, OB_LOCK_SIZEZ, REDRAWVIEW3D, ICON_UNLOCKED, 160,30,20,19, &(pchan->protectflag), 0, 0, 0, 0, "Protects this value from being Transformed");
1691 uiDefButF(block, NUM, B_ARMATUREPANEL2, "SizeZ:", 180, 30, 120, 19, pchan->size+2, -lim, lim, 10, 3, "");
1692 uiBlockEndAlign(block);
1695 static void v3d_editarmature_buts(uiBlock *block, Object *ob, float lim)
1697 bArmature *arm= G.obedit->data;
1701 ebone= G.edbo.first;
1703 for (ebone = G.edbo.first; ebone; ebone=ebone->next){
1704 if ((ebone->flag & BONE_ACTIVE) && (ebone->layer & arm->layer))
1711 but= uiDefBut(block, TEX, B_DIFF, "Bone:", 160, 150, 140, 19, ebone->name, 1, 31, 0, 0, "");
1712 uiButSetFunc(but, validate_editbonebutton_cb, ebone, NULL);
1714 uiBlockBeginAlign(block);
1715 uiDefButF(block, NUM, B_ARMATUREPANEL1, "RootX:", 10, 70, 140, 19, ebone->head, -lim, lim, 10, 3, "");
1716 uiDefButF(block, NUM, B_ARMATUREPANEL1, "RootY:", 10, 50, 140, 19, ebone->head+1, -lim, lim, 10, 3, "");
1717 uiDefButF(block, NUM, B_ARMATUREPANEL1, "RootZ:", 10, 30, 140, 19, ebone->head+2, -lim, lim, 10, 3, "");
1718 uiBlockBeginAlign(block);
1719 uiDefButF(block, NUM, B_ARMATUREPANEL1, "TipX:", 160, 70, 140, 19, ebone->tail, -lim, lim, 10, 3, "");
1720 uiDefButF(block, NUM, B_ARMATUREPANEL1, "TipY:", 160, 50, 140, 19, ebone->tail+1, -lim, lim, 10, 3, "");
1721 uiDefButF(block, NUM, B_ARMATUREPANEL1, "TipZ:", 160, 30, 140, 19, ebone->tail+2, -lim, lim, 10, 3, "");
1722 uiBlockEndAlign(block);
1723 ob_eul[0]= 180.0*ebone->roll/M_PI;
1724 uiDefButF(block, NUM, B_ARMATUREPANEL1, "Roll:", 10, 100, 140, 19, ob_eul, -lim, lim, 1000, 3, "");
1727 uiBlockBeginAlign(block);
1728 uiDefButF(block, NUM, B_ARMATUREPANEL1, "TipRadius:", 10, 150, 140, 19, &ebone->rad_tail, 0, lim, 10, 3, "");
1729 if (ebone->parent && ebone->flag & BONE_CONNECTED )
1730 uiDefButF(block, NUM, B_ARMATUREPANEL1, "HeadRadius:", 10, 130, 140, 19, &ebone->parent->rad_tail, 0, lim, 10, 3, "");
1732 uiDefButF(block, NUM, B_ARMATUREPANEL1, "HeadRadius:", 10, 130, 140, 19, &ebone->rad_head, 0, lim, 10, 3, "");
1733 uiBlockEndAlign(block);
1736 static void v3d_editmetaball_buts(uiBlock *block, Object *ob, float lim)
1738 extern MetaElem *lastelem;
1741 uiBlockBeginAlign(block);
1742 uiDefButF(block, NUM, B_RECALCMBALL, "LocX:", 10, 70, 140, 19, &lastelem->x, -lim, lim, 100, 3, "");
1743 uiDefButF(block, NUM, B_RECALCMBALL, "LocY:", 10, 50, 140, 19, &lastelem->y, -lim, lim, 100, 3, "");
1744 uiDefButF(block, NUM, B_RECALCMBALL, "LocZ:", 10, 30, 140, 19, &lastelem->z, -lim, lim, 100, 3, "");
1746 uiBlockBeginAlign(block);
1747 if(lastelem->type!=MB_BALL)
1748 uiDefButF(block, NUM, B_RECALCMBALL, "dx:", 160, 70, 140, 19, &lastelem->expx, 0, lim, 100, 3, "");
1749 if((lastelem->type!=MB_BALL) && (lastelem->type!=MB_TUBE))
1750 uiDefButF(block, NUM, B_RECALCMBALL, "dy:", 160, 50, 140, 19, &lastelem->expy, 0, lim, 100, 3, "");
1751 if((lastelem->type==MB_ELIPSOID) || (lastelem->type==MB_CUBE))
1752 uiDefButF(block, NUM, B_RECALCMBALL, "dz:", 160, 30, 140, 19, &lastelem->expz, 0, lim, 100, 3, "");
1754 uiBlockEndAlign(block);
1756 uiDefButF(block, NUM, B_RECALCMBALL, "Stiffness:", 10, 100, 140, 19, &lastelem->s, 0, lim, 100, 3, "");
1760 void do_viewbuts(unsigned short event)
1771 if(vd->bgpic && vd->bgpic->ima) name= vd->bgpic->ima->name;
1774 if(G.qual==LR_CTRLKEY)
1775 activate_imageselect(FILE_SPECIAL, "Select Image", name, load_bgpic_image);
1777 activate_fileselect(FILE_SPECIAL, "Select Image", name, load_bgpic_image);
1781 if(vd->bgpic && vd->bgpic->rect) setalpha_bgpic(vd->bgpic);
1782 addqueue(curarea->win, REDRAW, 1);
1787 if (vd->menunr==-2) {
1788 activate_databrowse((ID*) vd->bgpic->ima, ID_IM, 0, B_BGPICBROWSE, &vd->menunr, do_viewbuts);
1789 } else if (vd->menunr>0) {
1790 Image *newima= (Image*) BLI_findlink(&G.main->image, vd->menunr-1);
1793 view3d_change_bgpic_ima(vd, newima);
1800 view3d_change_bgpic_ima(vd, NULL);
1805 if (vd->texnr==-2) {
1806 activate_databrowse((ID*) vd->bgpic->tex, ID_TE, 0, B_BGPICTEX, &vd->texnr, do_viewbuts);
1807 } else if (vd->texnr>0) {
1808 Tex *newtex= (Tex*) BLI_findlink(&G.main->tex, vd->texnr-1);
1811 view3d_change_bgpic_tex(vd, newtex);
1816 case B_BGPICTEXCLEAR:
1818 view3d_change_bgpic_tex(vd, NULL);
1822 DAG_object_flush_update(G.scene, ob, OB_RECALC_OB);
1823 allqueue(REDRAWVIEW3D, 1);
1826 case B_OBJECTPANELROT:
1828 ob->rot[0]= M_PI*ob_eul[0]/180.0;
1829 ob->rot[1]= M_PI*ob_eul[1]/180.0;
1830 ob->rot[2]= M_PI*ob_eul[2]/180.0;
1831 DAG_object_flush_update(G.scene, ob, OB_RECALC_OB);
1832 allqueue(REDRAWVIEW3D, 1);
1836 case B_OBJECTPANELMEDIAN:
1838 v3d_editvertex_buts(NULL, ob, 1.0);
1839 DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA);
1840 allqueue(REDRAWVIEW3D, 1);
1843 case B_OBJECTPANELPARENT:
1845 if( test_parent_loop(ob->parent, ob) )
1848 DAG_scene_sort(G.scene);
1849 DAG_object_flush_update(G.scene, ob, OB_RECALC_OB);
1850 allqueue(REDRAWVIEW3D, 1);
1851 allqueue(REDRAWBUTSOBJECT, 0);
1856 case B_ARMATUREPANEL1:
1858 bArmature *arm= G.obedit->data;
1859 EditBone *ebone, *child;
1861 for (ebone = G.edbo.first; ebone; ebone=ebone->next){
1862 if ((ebone->flag & BONE_ACTIVE) && (ebone->layer & arm->layer))
1866 ebone->roll= M_PI*ob_eul[0]/180.0;
1867 // Update our parent
1868 if (ebone->parent && ebone->flag & BONE_CONNECTED){
1869 VECCOPY (ebone->parent->tail, ebone->head);
1872 // Update our children if necessary
1873 for (child = G.edbo.first; child; child=child->next){
1874 if (child->parent == ebone && (child->flag & BONE_CONNECTED)){
1875 VECCOPY (child->head, ebone->tail);
1878 if(arm->flag & ARM_MIRROR_EDIT) {
1879 EditBone *eboflip= armature_bone_get_mirrored(ebone);
1881 eboflip->roll= -ebone->roll;
1882 eboflip->head[0]= -ebone->head[0];
1883 eboflip->tail[0]= -ebone->tail[0];
1885 // Update our parent
1886 if (eboflip->parent && eboflip->flag & BONE_CONNECTED){
1887 VECCOPY (eboflip->parent->tail, eboflip->head);
1890 // Update our children if necessary
1891 for (child = G.edbo.first; child; child=child->next){
1892 if (child->parent == eboflip && (child->flag & BONE_CONNECTED)){
1893 VECCOPY (child->head, eboflip->tail);
1899 allqueue(REDRAWVIEW3D, 1);
1903 case B_ARMATUREPANEL3: // rotate button on channel
1906 bPoseChannel *pchan;
1909 arm = get_armature(OBACT);
1910 if (!arm || !ob->pose) return;
1912 for(pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) {
1914 if(bone && (bone->flag & BONE_ACTIVE) && (bone->layer & arm->layer))
1919 ob_eul[0]*= M_PI/180.0;
1920 ob_eul[1]*= M_PI/180.0;
1921 ob_eul[2]*= M_PI/180.0;
1922 EulToQuat(ob_eul, pchan->quat);
1924 /* no break, pass on */
1925 case B_ARMATUREPANEL2:
1927 ob->pose->flag |= (POSE_LOCKED|POSE_DO_UNLOCK);
1928 DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA);
1929 allqueue(REDRAWVIEW3D, 1);
1936 static void view3d_panel_object(short cntrl) // VIEW3D_HANDLER_OBJECT
1942 static char hexcol[128];
1944 if(ob==NULL) return;
1946 block= uiNewBlock(&curarea->uiblocks, "view3d_panel_object", UI_EMBOSS, UI_HELV, curarea->win);
1947 uiPanelControl(UI_PNL_SOLID | UI_PNL_CLOSE | cntrl);
1948 uiSetPanelHandler(VIEW3D_HANDLER_OBJECT); // for close and esc
1950 /* (ton) can't use the rename trick for paint... panel names and settings are stored in the files and
1951 used to find previous locations when re-open. This causes flipping */
1953 if(uiNewPanel(curarea, block, "Transform Properties", "View3d", 10, 230, 318, 204)==0) return;
1955 if(ob->id.lib) uiSetButLock(1, "Can't edit library data");
1957 if(G.f & (G_VERTEXPAINT|G_FACESELECT|G_TEXTUREPAINT|G_WEIGHTPAINT)) {
1958 uiBlockSetFlag(block, UI_BLOCK_FRONTBUFFER); // force old style frontbuffer draw
1961 bt= uiDefBut(block, TEX, B_IDNAME, "OB: ", 10,180,140,20, ob->id.name+2, 0.0, 19.0, 0, 0, "");
1962 uiButSetFunc(bt, test_idbutton_cb, ob->id.name, NULL);
1964 uiDefIDPoinBut(block, test_obpoin_but, ID_OB, B_OBJECTPANELPARENT, "Par:", 160, 180, 140, 20, &ob->parent, "Parent Object");
1967 lim= 10000.0f*MAX2(1.0, G.vd->grid);
1970 if(ob->type==OB_ARMATURE) v3d_editarmature_buts(block, ob, lim);
1971 if(ob->type==OB_MBALL) v3d_editmetaball_buts(block, ob, lim);
1972 else v3d_editvertex_buts(block, ob, lim);
1974 else if(ob->flag & OB_POSEMODE) {
1975 v3d_posearmature_buts(block, ob, lim);
1977 else if(G.f & (G_VERTEXPAINT|G_TEXTUREPAINT)) {
1978 extern VPaint Gvp; /* from vpaint */
1979 static float hsv[3], old[3]; // used as temp mem for picker
1980 uiBlockPickerButtons(block, &Gvp.r, hsv, old, hexcol, 'f', REDRAWBUTSEDIT); /* 'f' is for floating panel */
1983 uiBlockBeginAlign(block);
1984 uiDefIconButBitS(block, ICONTOG, OB_LOCK_LOCX, REDRAWVIEW3D, ICON_UNLOCKED, 10,140,20,19, &(ob->protectflag), 0, 0, 0, 0, "Protects this value from being Transformed");
1985 uiDefButF(block, NUM, B_OBJECTPANEL, "LocX:", 30, 140, 120, 19, &(ob->loc[0]), -lim, lim, 100, 3, "");
1986 uiDefIconButBitS(block, ICONTOG, OB_LOCK_LOCY, REDRAWVIEW3D, ICON_UNLOCKED, 10,120,20,19, &(ob->protectflag), 0, 0, 0, 0, "Protects this value from being Transformed");
1987 uiDefButF(block, NUM, B_OBJECTPANEL, "LocY:", 30, 120, 120, 19, &(ob->loc[1]), -lim, lim, 100, 3, "");
1988 uiDefIconButBitS(block, ICONTOG, OB_LOCK_LOCZ, REDRAWVIEW3D, ICON_UNLOCKED, 10,100,20,19, &(ob->protectflag), 0, 0, 0, 0, "Protects this value from being Transformed");
1989 uiDefButF(block, NUM, B_OBJECTPANEL, "LocZ:", 30, 100, 120, 19, &(ob->loc[2]), -lim, lim, 100, 3, "");
1991 ob_eul[0]= 180.0*ob->rot[0]/M_PI;
1992 ob_eul[1]= 180.0*ob->rot[1]/M_PI;
1993 ob_eul[2]= 180.0*ob->rot[2]/M_PI;
1995 uiBlockBeginAlign(block);
1996 uiDefIconButBitS(block, ICONTOG, OB_LOCK_ROTX, REDRAWVIEW3D, ICON_UNLOCKED, 10,70,20,19, &(ob->protectflag), 0, 0, 0, 0, "Protects this value from being Transformed");
1997 uiDefButF(block, NUM, B_OBJECTPANELROT, "RotX:", 30, 70, 120, 19, &(ob_eul[0]), -lim, lim, 1000, 3, "");
1998 uiDefIconButBitS(block, ICONTOG, OB_LOCK_ROTY, REDRAWVIEW3D, ICON_UNLOCKED, 10,50,20,19, &(ob->protectflag), 0, 0, 0, 0, "Protects this value from being Transformed");
1999 uiDefButF(block, NUM, B_OBJECTPANELROT, "RotY:", 30, 50, 120, 19, &(ob_eul[1]), -lim, lim, 1000, 3, "");
2000 uiDefIconButBitS(block, ICONTOG, OB_LOCK_ROTZ, REDRAWVIEW3D, ICON_UNLOCKED, 10,30,20,19, &(ob->protectflag), 0, 0, 0, 0, "Protects this value from being Transformed");
2001 uiDefButF(block, NUM, B_OBJECTPANELROT, "RotZ:", 30, 30, 120, 19, &(ob_eul[2]), -lim, lim, 1000, 3, "");
2003 uiBlockBeginAlign(block);
2004 uiDefIconButBitS(block, ICONTOG, OB_LOCK_SIZEX, REDRAWVIEW3D, ICON_UNLOCKED, 160,70,20,19, &(ob->protectflag), 0, 0, 0, 0, "Protects this value from being Transformed");
2005 uiDefButF(block, NUM, B_OBJECTPANEL, "SizeX:", 180, 70, 120, 19, &(ob->size[0]), -lim, lim, 10, 3, "");
2006 uiDefIconButBitS(block, ICONTOG, OB_LOCK_SIZEY, REDRAWVIEW3D, ICON_UNLOCKED, 160,50,20,19, &(ob->protectflag), 0, 0, 0, 0, "Protects this value from being Transformed");
2007 uiDefButF(block, NUM, B_OBJECTPANEL, "SizeY:", 180, 50, 120, 19, &(ob->size[1]), -lim, lim, 10, 3, "");
2008 uiDefIconButBitS(block, ICONTOG, OB_LOCK_SIZEZ, REDRAWVIEW3D, ICON_UNLOCKED, 160,30,20,19, &(ob->protectflag), 0, 0, 0, 0, "Protects this value from being Transformed");
2009 uiDefButF(block, NUM, B_OBJECTPANEL, "SizeZ:", 180, 30, 120, 19, &(ob->size[2]), -lim, lim, 10, 3, "");
2010 uiBlockEndAlign(block);
2015 static void view3d_panel_background(short cntrl) // VIEW3D_HANDLER_BACKGROUND
2024 block= uiNewBlock(&curarea->uiblocks, "view3d_panel_background", UI_EMBOSS, UI_HELV, curarea->win);
2025 uiPanelControl(UI_PNL_SOLID | UI_PNL_CLOSE | cntrl);
2026 uiSetPanelHandler(VIEW3D_HANDLER_BACKGROUND); // for close and esc
2027 if(uiNewPanel(curarea, block, "Background Image", "View3d", 340, 10, 318, 204)==0) return;
2029 if(G.f & (G_VERTEXPAINT|G_FACESELECT|G_TEXTUREPAINT|G_WEIGHTPAINT)) {
2030 uiBlockSetFlag(block, UI_BLOCK_FRONTBUFFER); // force old style frontbuffer draw
2033 if(vd->flag & V3D_DISPBGPIC) {
2035 vd->bgpic= MEM_callocN(sizeof(BGpic), "bgpic");
2036 vd->bgpic->size= 5.0;
2037 vd->bgpic->blend= 0.5;
2041 uiDefButBitS(block, TOG, V3D_DISPBGPIC, REDRAWVIEW3D, "Use Background Image", 0, 162, 200, 20, &vd->flag, 0, 0, 0, 0, "Display an image in the background of the 3D View");
2043 uiDefBut(block, LABEL, 1, " ", 206, 162, 84, 20, NULL, 0.0, 0.0, 0, 0, "");
2046 if(vd->flag & V3D_DISPBGPIC) {
2048 /* Background Image */
2049 uiDefBut(block, LABEL, 1, "Image:", 0, 128, 76, 19, NULL, 0.0, 0.0, 0, 0, "");
2051 uiBlockBeginAlign(block);
2052 uiDefIconBut(block, BUT, B_LOADBGPIC, ICON_FILESEL, 90, 128, 20, 20, 0, 0, 0, 0, 0, "Open a new background image");
2054 id= (ID *)vd->bgpic->ima;
2055 IDnames_to_pupstring(&strp, NULL, NULL, &(G.main->image), id, &(vd->menunr));
2058 uiDefButS(block, MENU, B_BGPICBROWSE, strp, 110, 128, 20, 20, &(vd->menunr), 0, 0, 0, 0, "Select a background image");
2060 if(vd->bgpic->ima) {
2061 uiDefBut(block, TEX, 0,"BG: ", 130, 128, 140, 20, &vd->bgpic->ima->name,0.0,100.0, 0, 0, "The currently selected background image");
2062 uiDefIconBut(block, BUT, B_BGPICCLEAR, ICON_X, 270, 128, 20, 20, 0, 0, 0, 0, 0, "Remove background image link");
2064 uiBlockEndAlign(block);
2066 uiBlockEndAlign(block);
2071 /* Background texture */
2072 uiDefBut(block, LABEL, 1, "Texture:", 0, 100, 76, 19, NULL, 0.0, 0.0, 0, 0, "");
2074 id= (ID *)vd->bgpic->tex;
2075 IDnames_to_pupstring(&strp, NULL, NULL, &(G.main->tex), id, &(vd->texnr));
2077 uiBlockBeginAlign(block);
2078 uiDefButS(block, MENU, B_BGPICTEX, strp, 90, 100, 20,20, &(vd->texnr), 0, 0, 0, 0, "Select a texture to use as an animated background image");
2082 uiDefBut(block, TEX, B_IDNAME, "TE:", 110, 100, 160, 20, id->name+2, 0.0, 18.0, 0, 0, "");
2083 uiDefIconBut(block, BUT, B_BGPICTEXCLEAR, ICON_X, 270, 100, 20, 20, 0, 0, 0, 0, 0, "Remove background texture link");
2084 uiBlockEndAlign(block);
2086 uiBlockEndAlign(block);
2089 uiDefButF(block, NUMSLI, B_BLENDBGPIC, "Blend:", 0, 60 , 290, 19, &vd->bgpic->blend, 0.0,1.0, 0, 0, "Set the transparency of the background image");
2091 uiDefButF(block, NUM, REDRAWVIEW3D, "Size:", 0, 28, 140, 19, &vd->bgpic->size, 0.1, 250.0*vd->grid, 100, 0, "Set the size (width) of the background image");
2093 uiDefButF(block, NUM, REDRAWVIEW3D, "X Offset:", 0, 6, 140, 19, &vd->bgpic->xof, -250.0*vd->grid,250.0*vd->grid, 10, 2, "Set the horizontal offset of the background image");
2094 uiDefButF(block, NUM, REDRAWVIEW3D, "Y Offset:", 150, 6, 140, 19, &vd->bgpic->yof, -250.0*vd->grid,250.0*vd->grid, 10, 2, "Set the vertical offset of the background image");
2098 // uiDefButF(block, NUM, REDRAWVIEW3D, "Size:", 160,160,150,20, &vd->bgpic->size, 0.1, 250.0, 100, 0, "Set the size for the width of the BackGroundPic");
2102 // uiDefButF(block, NUMSLI, B_BLENDBGPIC, "Blend:", 120,100,190,20,&vd->bgpic->blend, 0.0,1.0, 0, 0, "Set the BackGroundPic transparency");
2104 // uiDefButF(block, NUM, B_DIFF, "Center X: ", 10,70,140,20,&vd->bgpic->xof, -20.0,20.0, 10, 2, "Set the BackGroundPic X Offset");
2105 // uiDefButF(block, NUM, B_DIFF, "Center Y: ", 160,70,140,20,&vd->bgpic->yof, -20.0,20.0, 10, 2, "Set the BackGroundPic Y Offset");
2111 static void view3d_panel_properties(short cntrl) // VIEW3D_HANDLER_SETTINGS
2119 block= uiNewBlock(&curarea->uiblocks, "view3d_panel_properties", UI_EMBOSS, UI_HELV, curarea->win);
2120 uiPanelControl(UI_PNL_SOLID | UI_PNL_CLOSE | cntrl);
2121 uiSetPanelHandler(VIEW3D_HANDLER_PROPERTIES); // for close and esc
2122 if(uiNewPanel(curarea, block, "View Properties", "View3d", 340, 30, 318, 254)==0) return;
2124 /* to force height */
2125 uiNewPanelHeight(block, 254);
2127 if(G.f & (G_VERTEXPAINT|G_FACESELECT|G_TEXTUREPAINT|G_WEIGHTPAINT)) {
2128 uiBlockSetFlag(block, UI_BLOCK_FRONTBUFFER); // force old style frontbuffer draw
2131 uiDefBut(block, LABEL, 1, "Grid:", 10, 220, 150, 19, NULL, 0.0, 0.0, 0, 0, "");
2132 uiDefButF(block, NUM, REDRAWVIEW3D, "Spacing:", 10, 200, 140, 19, &vd->grid, 0.001, 100.0, 10, 0, "Set the distance between grid lines");
2133 uiDefButS(block, NUM, REDRAWVIEW3D, "Lines:", 10, 176, 140, 19, &vd->gridlines, 0.0, 100.0, 100, 0, "Set the number of grid lines");
2135 uiDefBut(block, LABEL, 1, "3D Display:", 160, 220, 150, 19, NULL, 0.0, 0.0, 0, 0, "");
2136 uiDefButBitS(block, TOG, V3D_SHOW_FLOOR, REDRAWVIEW3D, "Grid Floor",160, 200, 150, 19, &vd->gridflag, 0, 0, 0, 0, "Show the grid floor in free camera mode");
2137 uiDefButBitS(block, TOG, V3D_SHOW_X, REDRAWVIEW3D, "X Axis", 160, 176, 48, 19, &vd->gridflag, 0, 0, 0, 0, "Show the X Axis line");
2138 uiDefButBitS(block, TOG, V3D_SHOW_Y, REDRAWVIEW3D, "Y Axis", 212, 176, 48, 19, &vd->gridflag, 0, 0, 0, 0, "Show the Y Axis line");
2139 uiDefButBitS(block, TOG, V3D_SHOW_Z, REDRAWVIEW3D, "Z Axis", 262, 176, 48, 19, &vd->gridflag, 0, 0, 0, 0, "Show the Z Axis line");
2141 uiDefBut(block, LABEL, 1, "View Camera:", 10, 150, 140, 19, NULL, 0.0, 0.0, 0, 0, "");
2143 uiDefButF(block, NUM, REDRAWVIEW3D, "Lens:", 10, 130, 140, 19, &vd->lens, 10.0, 120.0, 100, 0, "The lens angle in perspective view");
2144 uiBlockBeginAlign(block);
2145 uiDefButF(block, NUM, REDRAWVIEW3D, "Clip Start:", 10, 106, 140, 19, &vd->near, vd->grid/10.0, 100.0, 10, 0, "Set the beginning of the range in which 3D objects are displayed (perspective view)");
2146 uiDefButF(block, NUM, REDRAWVIEW3D, "Clip End:", 10, 86, 140, 19, &vd->far, 1.0, 1000.0*vd->grid, 100, 0, "Set the end of the range in which 3D objects are displayed (perspective view)");
2147 uiBlockEndAlign(block);
2149 uiDefBut(block, LABEL, 1, "3D Cursor:", 160, 150, 140, 19, NULL, 0.0, 0.0, 0, 0, "");
2151 uiBlockBeginAlign(block);
2152 curs= give_cursor();
2153 uiDefButF(block, NUM, REDRAWVIEW3D, "X:", 160, 130, 150, 22, curs, -1000.0*vd->grid, 1000.0*vd->grid, 10, 0, "X co-ordinate of the 3D cursor");
2154 uiDefButF(block, NUM, REDRAWVIEW3D, "Y:", 160, 108, 150, 22, curs+1, -1000.0*vd->grid, 1000.0*vd->grid, 10, 0, "Y co-ordinate of the 3D cursor");
2155 uiDefButF(block, NUM, REDRAWVIEW3D, "Z:", 160, 86, 150, 22, curs+2, -1000.0*vd->grid, 1000.0*vd->grid, 10, 0, "Z co-ordinate of the 3D cursor");
2156 uiBlockEndAlign(block);
2158 uiDefBut(block, LABEL, 1, "Display:", 10, 50, 150, 19, NULL, 0.0, 0.0, 0, 0, "");
2160 uiDefButBitS(block, TOG, V3D_SELECT_OUTLINE, REDRAWVIEW3D, "Outline Selected", 10, 30, 140, 19, &vd->flag, 0, 0, 0, 0, "Highlight selected objects with an outline, in Solid, Shaded or Textured viewport shading modes");
2161 uiDefButBitS(block, TOG, V3D_DRAW_CENTERS, REDRAWVIEW3D, "All Object Centers", 160, 30, 150, 19, &vd->flag, 0, 0, 0, 0, "Draw the center points on all objects");
2163 uiDefButBitS(block, TOGN, V3D_HIDE_HELPLINES, REDRAWVIEW3D, "Relationship Lines", 10, 6, 140, 19, &vd->flag, 0, 0, 0, 0, "Draw dashed lines indicating Parent, Constraint, or Hook relationships");
2167 static void view3d_panel_preview(ScrArea *sa, short cntrl) // VIEW3D_HANDLER_PREVIEW
2170 View3D *v3d= sa->spacedata.first;
2173 block= uiNewBlock(&sa->uiblocks, "view3d_panel_preview", UI_EMBOSS, UI_HELV, sa->win);
2174 uiPanelControl(UI_PNL_SOLID | UI_PNL_CLOSE | UI_PNL_SCALE | cntrl);
2175 uiSetPanelHandler(VIEW3D_HANDLER_PREVIEW); // for close and esc
2177 ofsx= -150+(sa->winx/2)/v3d->blockscale;
2178 ofsy= -100+(sa->winy/2)/v3d->blockscale;
2179 if(uiNewPanel(sa, block, "Preview", "View3d", ofsx, ofsy, 300, 200)==0) return;
2181 uiBlockSetDrawExtraFunc(block, BIF_view3d_previewdraw);
2183 if(G.scene->recalc & SCE_PRV_CHANGED) {
2184 G.scene->recalc &= ~SCE_PRV_CHANGED;
2185 //printf("found recalc\n");
2186 BIF_view3d_previewrender_free(sa->spacedata.first);
2187 BIF_preview_changed(0);
2192 static void view3d_blockhandlers(ScrArea *sa)
2194 View3D *v3d= sa->spacedata.first;
2197 /* warning; blocks need to be freed each time, handlers dont remove */
2198 uiFreeBlocksWin(&sa->uiblocks, sa->win);
2200 for(a=0; a<SPACE_MAXHANDLER; a+=2) {
2202 switch(v3d->blockhandler[a]) {
2204 case VIEW3D_HANDLER_PROPERTIES:
2205 view3d_panel_properties(v3d->blockhandler[a+1]);
2207 case VIEW3D_HANDLER_BACKGROUND:
2208 view3d_panel_background(v3d->blockhandler[a+1]);
2210 case VIEW3D_HANDLER_OBJECT:
2211 view3d_panel_object(v3d->blockhandler[a+1]);
2213 case VIEW3D_HANDLER_PREVIEW:
2214 view3d_panel_preview(sa, v3d->blockhandler[a+1]);
2218 /* clear action value for event */
2219 v3d->blockhandler[a+1]= 0;
2221 uiDrawBlocksPanels(sa, 0);
2225 /* ****************** View3d afterdraw *************** */
2227 typedef struct View3DAfter {
2228 struct View3DAfter *next, *prev;
2233 /* temp storage of Objects that need to be drawn as last */
2234 void add_view3d_after(View3D *v3d, Base *base, int type)
2236 View3DAfter *v3da= MEM_callocN(sizeof(View3DAfter), "View 3d after");
2238 BLI_addtail(&v3d->afterdraw, v3da);
2243 /* clears zbuffer and draws it over */
2244 static void view3d_draw_xray(View3D *v3d, int flag)
2246 View3DAfter *v3da, *next;
2249 for(v3da= v3d->afterdraw.first; v3da; v3da= v3da->next)
2250 if(v3da->type==V3D_XRAY) doit= 1;
2253 if(v3d->zbuf) glClear(GL_DEPTH_BUFFER_BIT);
2256 for(v3da= v3d->afterdraw.first; v3da; v3da= next) {
2258 if(v3da->type==V3D_XRAY) {
2259 draw_object(v3da->base, flag);
2260 BLI_remlink(&v3d->afterdraw, v3da);
2268 /* disables write in zbuffer and draws it over */
2269 static void view3d_draw_transp(View3D *v3d, int flag)
2271 View3DAfter *v3da, *next;
2276 for(v3da= v3d->afterdraw.first; v3da; v3da= next) {
2278 if(v3da->type==V3D_TRANSP) {
2279 draw_object(v3da->base, flag);
2280 BLI_remlink(&v3d->afterdraw, v3da);
2290 /* *********************** */
2292 static void draw_dupli_objects(View3D *v3d, Base *base)
2297 int color= (base->flag & SELECT)?TH_SELECT:TH_WIRE;
2301 if(base->object->dup_group && base->object->dup_group->id.us<1)
2304 tbase.flag= OB_FROMDUPLI|base->flag;
2305 lb= object_duplilist(G.scene, base->object);
2307 for(dob= lb->first; dob; dob= dob->next) {
2308 tbase.object= dob->ob;
2310 Mat4CpyMat4(dob->ob->obmat, dob->mat);
2312 /* extra service: draw the duplicator in drawtype of parent */
2313 dt= tbase.object->dt; tbase.object->dt= base->object->dt;
2314 dtx= tbase.object->dtx; tbase.object->dtx= base->object->dtx;
2316 BIF_ThemeColorBlend(color, TH_BACK, 0.5);
2317 draw_object(&tbase, DRAW_CONSTCOLOR);
2319 tbase.object->dt= dt;
2320 tbase.object->dtx= dtx;
2323 /* Transp afterdraw disabled, afterdraw only stores base pointers, and duplis can be same obj */
2325 free_object_duplilist(lb); /* does restore */
2329 void drawview3dspace(ScrArea *sa, void *spacedata)
2331 View3D *v3d= spacedata;
2336 setwinmatrixview3d(sa->winx, sa->winy, NULL); /* 0= no pick rect */
2337 setviewmatrixview3d(); /* note: calls where_is_object for camera... */
2339 Mat4MulMat4(v3d->persmat, v3d->viewmat, sa->winmat);
2340 Mat4Invert(v3d->persinv, v3d->persmat);
2341 Mat4Invert(v3d->viewinv, v3d->viewmat);
2343 /* calculate pixelsize factor once, is used for lamps and obcenters */
2345 float len1, len2, vec[3];
2347 VECCOPY(vec, v3d->persinv[0]);
2348 len1= Normalise(vec);
2349 VECCOPY(vec, v3d->persinv[1]);
2350 len2= Normalise(vec);
2352 v3d->pixsize= 2.0f*(len1>len2?len1:len2);
2354 /* correct for window size */
2355 if(sa->winx > sa->winy) v3d->pixsize/= (float)sa->winx;
2356 else v3d->pixsize/= (float)sa->winy;
2359 if(v3d->drawtype > OB_WIRE) {
2360 if(G.f & G_SIMULATION)
2361 glClearColor(0.0, 0.0, 0.0, 0.0);
2364 BIF_GetThemeColor3fv(TH_BACK, col);
2365 glClearColor(col[0], col[1], col[2], 0.0);
2367 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
2373 BIF_GetThemeColor3fv(TH_BACK, col);
2374 glClearColor(col[0], col[1], col[2], 0.0);
2375 glClear(GL_COLOR_BUFFER_BIT);
2378 myloadmatrix(v3d->viewmat);
2379 persp(PERSP_STORE); // store correct view for persp(PERSP_VIEW) calls
2381 if(v3d->flag & V3D_CLIPPING)
2382 view3d_draw_clipping(v3d);
2384 /* set zbuffer after we draw clipping region */
2385 if(v3d->drawtype > OB_WIRE) {
2387 glEnable(GL_DEPTH_TEST);
2390 // needs to be done always, gridview is adjusted in drawgrid() now
2391 v3d->gridview= v3d->grid;
2393 if(v3d->view==0 || v3d->persp!=0) {
2396 if(G.scene->world) {
2397 if(G.scene->world->mode & WO_STARS) {
2398 // RE_make_stars(star_stuff_init_func, star_stuff_vertex_func,
2399 // star_stuff_term_func);
2402 if(v3d->flag & V3D_DISPBGPIC) draw_bgpic();
2408 if(v3d->flag & V3D_DISPBGPIC) {
2413 if(v3d->flag & V3D_CLIPPING)
2414 view3d_set_clipping(v3d);
2416 /* draw set first */
2417 setscene= G.scene->set;
2418 if(setscene) { /* if(G.scene->set) { */
2420 base= setscene->base.first; /* base= G.scene->set->base.first; */
2423 if(v3d->lay & base->lay) {
2425 object_handle_update(base->object);
2427 BIF_ThemeColorBlend(TH_WIRE, TH_BACK, 0.6f);
2428 draw_object(base, DRAW_CONSTCOLOR);
2430 if(base->object->transflag & OB_DUPLI) {
2431 draw_dupli_objects(v3d, base);
2436 if(base==0 && setscene && setscene->set) {
2437 setscene= setscene->set;
2438 base= setscene->base.first;
2442 /* Transp and X-ray afterdraw stuff */
2443 view3d_draw_xray(v3d, DRAW_CONSTCOLOR); // clears zbuffer if it is used!
2444 view3d_draw_transp(v3d, DRAW_CONSTCOLOR);
2447 /* update all objects, ipos, matrices, displists, etc. Flags set by depgraph or manual, no layer check here, gets correct flushed */
2448 for(base= G.scene->base.first; base; base= base->next) {
2449 object_handle_update(base->object); // bke_object.h
2451 if(v3d->lay & base->lay) {
2452 if(base->object->dup_group) {
2454 for(go= base->object->dup_group->gobject.first; go; go= go->next) {
2456 if(go->ob->type==OB_MESH) {
2458 mesh_get_derived_deform(go->ob, &dummy);
2459 mesh_get_derived_final(go->ob, &dummy);
2461 else if(go->ob->type==OB_CURVE) {
2463 if (cu->disp.first==NULL) makeDispListCurveTypes(ob, 0);
2472 /* then draw not selected and the duplis, but skip editmode object */
2473 for(base= G.scene->base.first; base; base= base->next) {
2474 if(v3d->lay & base->lay) {
2477 if(base->object->transflag & OB_DUPLI) {
2478 draw_dupli_objects(v3d, base);
2480 if((base->flag & SELECT)==0) {
2481 if(base->object!=G.obedit) draw_object(base, 0);
2485 /* draw selected and editmode */
2486 for(base= G.scene->base.first; base; base= base->next) {
2487 if(v3d->lay & base->lay) {
2488 if (base->object==G.obedit || ( base->flag & SELECT) )
2489 draw_object(base, 0);
2494 BIF_drawConstraint();
2495 if(G.obedit) BIF_drawPropCircle(); // only editmode has proportional edit
2498 if(G.scene->radio) RAD_drawall(v3d->drawtype>=OB_SOLID);
2500 /* Transp and X-ray afterdraw stuff */
2501 view3d_draw_xray(v3d, 0); // clears zbuffer if it is used!
2502 view3d_draw_transp(v3d, 0);
2504 if(v3d->flag & V3D_CLIPPING)
2505 view3d_clr_clipping();
2507 BIF_draw_manipulator(sa);
2511 glDisable(GL_DEPTH_TEST);
2514 persp(PERSP_WIN); // set ortho
2516 if(v3d->persp>1) drawviewborder();
2517 if(!(G.f & G_PLAYANIM)) drawcursor(v3d);
2521 if(ob && (U.uiflag & USER_DRAWVIEWINFO))
2522 draw_selected_name(ob);
2524 draw_area_emboss(sa);
2526 /* it is important to end a view in a transform compatible with buttons */
2528 bwin_scalematrix(sa->win, v3d->blockscale, v3d->blockscale, v3d->blockscale);
2529 view3d_blockhandlers(sa);
2531 sa->win_swap= WIN_BACK_OK;
2533 if(G.f & (G_VERTEXPAINT|G_FACESELECT|G_TEXTUREPAINT|G_WEIGHTPAINT)) {
2534 v3d->flag |= V3D_NEEDBACKBUFDRAW;
2535 addafterqueue(sa->win, BACKBUFDRAW, 1);
2537 // test for backbuf select
2538 if(G.obedit && v3d->drawtype>OB_WIRE && (v3d->flag & V3D_ZBUF_SELECT)) {
2539 extern int afterqtest(short win, unsigned short evt); //editscreen.c
2541 v3d->flag |= V3D_NEEDBACKBUFDRAW;
2542 if(afterqtest(sa->win, BACKBUFDRAW)==0) {
2543 addafterqueue(sa->win, BACKBUFDRAW, 1);
2547 /* run any view3d draw handler script links */
2548 if (sa->scriptlink.totscript)
2549 BPY_do_spacehandlers(sa, 0, SPACEHANDLER_VIEW3D_DRAW);
2551 /* run scene redraw script links */
2552 if((G.f & G_DOSCRIPTLINKS) && G.scene->scriptlink.totscript &&
2554 BPY_do_pyscript((ID *)G.scene, SCRIPT_REDRAW);
2560 void drawview3d_render(struct View3D *v3d, int winx, int winy)
2566 update_for_newframe_muted(); /* first, since camera can be animated */
2568 setwinmatrixview3d(winx, winy, NULL);
2570 setviewmatrixview3d();
2571 myloadmatrix(v3d->viewmat);
2572 glMatrixMode(GL_PROJECTION);
2573 mygetmatrix(winmat);
2574 glMatrixMode(GL_MODELVIEW);
2575 Mat4MulMat4(v3d->persmat, v3d->viewmat, winmat);
2576 Mat4Invert(v3d->persinv, v3d->persmat);
2577 Mat4Invert(v3d->viewinv, v3d->viewmat);
2579 free_all_realtime_images();
2580 reshadeall_displist();
2582 if(v3d->drawtype > OB_WIRE) {
2584 glEnable(GL_DEPTH_TEST);
2587 if(v3d->flag & V3D_CLIPPING)
2588 view3d_set_clipping(v3d);
2590 if (v3d->drawtype==OB_TEXTURE && G.scene->world) {
2591 glClearColor(G.scene->world->horr, G.scene->world->horg, G.scene->world->horb, 0.0);
2594 BIF_GetThemeColor3fv(TH_BACK, col);
2595 glClearColor(col[0], col[1], col[2], 0.0);
2597 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
2599 /* abuse! to make sure it doesnt draw the helpstuff */
2600 G.f |= G_SIMULATION;
2602 /* first draw set */
2603 setscene= G.scene->set;
2604 if(setscene) { /* if(G.scene->set) { */
2606 base= setscene->base.first; /* base= G.scene->set->base.first; */
2608 if(v3d->lay & base->lay) {
2609 if ELEM3(base->object->type, OB_LAMP, OB_CAMERA, OB_LATTICE);
2611 where_is_object(base->object);
2613 BIF_ThemeColorBlend(TH_WIRE, TH_BACK, 0.6f);
2614 draw_object(base, DRAW_CONSTCOLOR);
2616 if(base->object->transflag & OB_DUPLI) {
2617 draw_dupli_objects(v3d, base);
2622 if(base==0 && setscene && setscene->set) {
2623 setscene= setscene->set;
2624 base= setscene->base.first;
2628 /* Transp and X-ray afterdraw stuff */
2629 view3d_draw_xray(v3d, DRAW_CONSTCOLOR); // clears zbuffer if it is used!
2630 view3d_draw_transp(v3d, DRAW_CONSTCOLOR);
2633 /* first not selected and duplis */
2634 base= G.scene->base.first;
2637 if(v3d->lay & base->lay) {
2638 if ELEM3(base->object->type, OB_LAMP, OB_CAMERA, OB_LATTICE);
2641 if(base->object->transflag & OB_DUPLI) {
2642 draw_dupli_objects(v3d, base);
2644 else if((base->flag & SELECT)==0) {
2645 draw_object(base, 0);
2654 base= G.scene->base.first;
2657 if ( ((base)->flag & SELECT) && ((base)->lay & v3d->lay) ) {
2658 if ELEM3(base->object->type, OB_LAMP, OB_CAMERA, OB_LATTICE);
2659 else draw_object(base, 0);
2665 if(G.scene->radio) RAD_drawall(v3d->drawtype>=OB_SOLID);
2667 /* Transp and X-ray afterdraw stuff */
2668 view3d_draw_xray(v3d, 0); // clears zbuffer if it is used!
2669 view3d_draw_transp(v3d, 0);
2671 if(v3d->flag & V3D_CLIPPING)
2672 view3d_clr_clipping();
2676 glDisable(GL_DEPTH_TEST);
2679 G.f &= ~G_SIMULATION;
2685 free_all_realtime_images();
2689 double tottime = 0.0;
2691 int update_time(void)
2693 static double ltime;
2696 if ((U.mixbufsize)&&(audiostream_pos() != CFRA)&&(G.scene->audio.flag & AUDIO_SYNC)) return 0;
2698 time = PIL_check_seconds_timer();
2700 tottime += (time - ltime);
2702 return (tottime < 0.0);
2705 void inner_play_anim_loop(int init, int mode)
2708 static ScrArea *oldsa;
2709 static double swaptime;
2715 swaptime= 1.0/(float)G.scene->r.frs_sec;
2722 set_timecursor(CFRA);
2724 update_for_newframe_muted();
2726 sa= G.curscreen->areabase.first;
2729 scrarea_do_windraw(sa);
2731 else if(curmode & 1) { /* catch modes 1 and 3 */
2732 if ELEM(sa->spacetype, SPACE_VIEW3D, SPACE_SEQ) {
2733 scrarea_do_windraw(sa);
2740 /* make sure that swaptime passed by */
2741 tottime -= swaptime;
2742 while (update_time()) PIL_sleep_ms(1);
2745 if (tottime > 0.0) tottime = 0.0;
2748 audiostream_start( CFRA );
2751 if (U.mixbufsize && (G.scene->audio.flag & AUDIO_SYNC)) CFRA = audiostream_pos();
2756 /* play_anim: 'mode' defines where to play and if repeat is on:
2758 * - 1: all view3d and seq areas
2759 * - 2: current area, no replay
2760 * - 3: all view3d and seq areas, no replay */
2761 int play_anim(int mode)
2763 ScrArea *sa, *oldsa;
2765 unsigned short event=0;
2768 /* patch for very very old scenes */
2769 if(SFRA==0) SFRA= 1;
2770 if(EFRA==0) EFRA= 250;
2772 if(SFRA>EFRA) return 0;
2776 /* waitcursor(1); */
2777 G.f |= G_PLAYANIM; /* in sequence.c and view.c this is handled */
2782 audiostream_start( CFRA );
2784 inner_play_anim_loop(1, mode); /* 1==init */
2786 /* forces all buffers to be OK for current frame (otherwise other windows get redrawn with CFRA+1) */
2787 curarea->win_swap= WIN_BACK_OK;
2788 screen_swapbuffers();
2794 /* we test events first because of MKEY event */
2796 event= extern_qread(&val);
2797 if(event==ESCKEY) break;
2798 else if(event==MIDDLEMOUSE) {
2799 if(U.flag & USER_VIEWMOVE) {
2800 if(G.qual & LR_SHIFTKEY) viewmove(0);
2801 else if(G.qual & LR_CTRLKEY) viewmove(2);
2805 if(G.qual & LR_SHIFTKEY) viewmove(1);
2806 else if(G.qual & LR_CTRLKEY) viewmove(2);
2810 else if(event==MKEY) {
2811 if(val) add_timeline_marker(CFRA-1);
2814 if(ELEM3(event, ESCKEY, SPACEKEY, RIGHTMOUSE)) break;
2816 inner_play_anim_loop(0, 0);
2817 screen_swapbuffers();
2819 if((mode > 1) && CFRA==EFRA) break; /* no replay */
2822 if(event==SPACEKEY);
2827 if(oldsa!=curarea) areawinset(oldsa->win);
2829 /* restore all areas */
2830 sa= G.curscreen->areabase.first;
2832 if( (mode && sa->spacetype==SPACE_VIEW3D) || sa==curarea) addqueue(sa->win, REDRAW, 1);
2836 /* groups could have changed ipo */
2837 allspace(REMAKEIPO, 0);
2838 allqueue(REDRAWIPO, 0);
2839 allqueue(REDRAWNLA, 0);
2840 allqueue (REDRAWACTION, 0);
2842 /* restore for cfra */
2843 update_for_newframe_muted();
2848 if (event==ESCKEY || event==SPACEKEY) return 1;