2 * $Id: drawview.c 12979 2007-12-23 17:01:44Z schlaile $
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>
47 #define snprintf _snprintf
51 #include "MEM_guardedalloc.h"
57 #include "IMB_imbuf_types.h"
58 #include "IMB_imbuf.h"
60 #include "DNA_action_types.h"
61 #include "DNA_armature_types.h"
62 #include "DNA_brush_types.h"
63 #include "DNA_camera_types.h"
64 #include "DNA_constraint_types.h"
65 #include "DNA_curve_types.h"
66 #include "DNA_group_types.h"
67 #include "DNA_image_types.h"
68 #include "DNA_key_types.h"
69 #include "DNA_lattice_types.h"
70 #include "DNA_mesh_types.h"
71 #include "DNA_meshdata_types.h"
72 #include "DNA_meta_types.h"
73 #include "DNA_object_types.h"
74 #include "DNA_screen_types.h"
75 #include "DNA_scene_types.h"
76 #include "DNA_space_types.h"
77 #include "DNA_texture_types.h"
78 #include "DNA_userdef_types.h"
79 #include "DNA_view3d_types.h"
80 #include "DNA_world_types.h"
82 #include "BLI_blenlib.h"
83 #include "BLI_arithb.h"
84 #include "BLI_editVert.h"
86 #include "BKE_action.h"
87 #include "BKE_armature.h"
89 #include "BKE_constraint.h"
90 #include "BKE_curve.h"
91 #include "BKE_customdata.h"
92 #include "BKE_displist.h"
93 #include "BKE_depsgraph.h"
94 #include "BKE_DerivedMesh.h"
95 #include "BKE_global.h"
96 #include "BKE_lattice.h"
97 #include "BKE_library.h"
98 #include "BKE_image.h"
101 #include "BKE_main.h"
102 #include "BKE_mesh.h"
103 #include "BKE_object.h"
104 #include "BKE_scene.h"
105 #include "BKE_texture.h"
106 #include "BKE_utildefines.h"
108 #include "BIF_butspace.h"
109 #include "BIF_drawimage.h"
110 #include "BIF_editgroup.h"
111 #include "BIF_editarmature.h"
112 #include "BIF_editmesh.h"
114 #include "BIF_glutil.h"
115 #include "BIF_interface.h"
116 #include "BIF_interface_icons.h"
117 #include "BIF_mywindow.h"
118 #include "BIF_poseobject.h"
119 #include "BIF_previewrender.h"
120 #include "BIF_resources.h"
121 #include "BIF_retopo.h"
122 #include "BIF_screen.h"
123 #include "BIF_space.h"
126 #include "BIF_verse.h"
129 #include "BDR_drawmesh.h"
130 #include "BDR_drawobject.h"
131 #include "BDR_editobject.h"
132 #include "BDR_vpaint.h"
133 #include "BDR_sculptmode.h"
135 #include "BSE_drawview.h"
136 #include "BSE_filesel.h"
137 #include "BSE_headerbuttons.h"
138 #include "BSE_seqaudio.h"
139 #include "BSE_trans_types.h"
140 #include "BSE_time.h"
141 #include "BSE_view.h"
143 #include "BPY_extern.h"
145 #include "RE_render_ext.h"
148 #include "mydevice.h"
149 #include "butspace.h" // event codes
151 #include "BIF_transform.h"
153 #include "RE_pipeline.h" // make_stars
155 #include "multires.h"
157 /* For MULTISAMPLE_ARB #define.
158 Note that older systems like irix
159 may not have this, and will need a #ifdef
161 /* #include "GL/glext.h" Disabled for release, to avoid possibly breaking platforms.
162 Instead, the define we need will just be #defined if it's not in the platform opengl.h.
169 void drawname(Object
*ob
);
171 static void star_stuff_init_func(void)
177 static void star_stuff_vertex_func(float* i
)
181 static void star_stuff_term_func(void)
186 void default_gl_light(void)
191 if(U
.light
[0].flag
==0 && U
.light
[1].flag
==0 && U
.light
[2].flag
==0) {
193 U
.light
[0].vec
[0]= -0.3; U
.light
[0].vec
[1]= 0.3; U
.light
[0].vec
[2]= 0.9;
194 U
.light
[0].col
[0]= 0.8; U
.light
[0].col
[1]= 0.8; U
.light
[0].col
[2]= 0.8;
195 U
.light
[0].spec
[0]= 0.5; U
.light
[0].spec
[1]= 0.5; U
.light
[0].spec
[2]= 0.5;
196 U
.light
[0].spec
[3]= 1.0;
199 U
.light
[1].vec
[0]= 0.5; U
.light
[1].vec
[1]= 0.5; U
.light
[1].vec
[2]= 0.1;
200 U
.light
[1].col
[0]= 0.4; U
.light
[1].col
[1]= 0.4; U
.light
[1].col
[2]= 0.8;
201 U
.light
[1].spec
[0]= 0.3; U
.light
[1].spec
[1]= 0.3; U
.light
[1].spec
[2]= 0.5;
202 U
.light
[1].spec
[3]= 1.0;
205 U
.light
[2].vec
[0]= 0.3; U
.light
[2].vec
[1]= -0.3; U
.light
[2].vec
[2]= -0.2;
206 U
.light
[2].col
[0]= 0.8; U
.light
[2].col
[1]= 0.5; U
.light
[2].col
[2]= 0.4;
207 U
.light
[2].spec
[0]= 0.5; U
.light
[2].spec
[1]= 0.4; U
.light
[2].spec
[2]= 0.3;
208 U
.light
[2].spec
[3]= 1.0;
212 glLightfv(GL_LIGHT0
, GL_POSITION
, U
.light
[0].vec
);
213 glLightfv(GL_LIGHT0
, GL_DIFFUSE
, U
.light
[0].col
);
214 glLightfv(GL_LIGHT0
, GL_SPECULAR
, U
.light
[0].spec
);
216 glLightfv(GL_LIGHT1
, GL_POSITION
, U
.light
[1].vec
);
217 glLightfv(GL_LIGHT1
, GL_DIFFUSE
, U
.light
[1].col
);
218 glLightfv(GL_LIGHT1
, GL_SPECULAR
, U
.light
[1].spec
);
220 glLightfv(GL_LIGHT2
, GL_POSITION
, U
.light
[2].vec
);
221 glLightfv(GL_LIGHT2
, GL_DIFFUSE
, U
.light
[2].col
);
222 glLightfv(GL_LIGHT2
, GL_SPECULAR
, U
.light
[2].spec
);
226 if(U
.light
[a
].flag
) glEnable(GL_LIGHT0
+a
);
227 else glDisable(GL_LIGHT0
+a
);
229 // clear stuff from other opengl lamp usage
230 glLightf(GL_LIGHT0
+a
, GL_SPOT_CUTOFF
, 180.0);
231 glLightf(GL_LIGHT0
+a
, GL_CONSTANT_ATTENUATION
, 1.0);
232 glLightf(GL_LIGHT0
+a
, GL_LINEAR_ATTENUATION
, 0.0);
234 else glDisable(GL_LIGHT0
+a
);
237 glDisable(GL_LIGHTING
);
239 glDisable(GL_COLOR_MATERIAL
);
242 /* also called when render 'ogl' */
243 void init_gl_stuff(void)
245 float mat_ambient
[] = { 0.0, 0.0, 0.0, 0.0 };
246 float mat_specular
[] = { 0.5, 0.5, 0.5, 1.0 };
247 float mat_shininess
[] = { 35.0 };
250 const GLubyte
*patc
= pat
;
253 glMaterialfv(GL_FRONT_AND_BACK
, GL_AMBIENT
, mat_ambient
);
254 glMaterialfv(GL_FRONT_AND_BACK
, GL_DIFFUSE
, mat_specular
);
255 glMaterialfv(GL_FRONT_AND_BACK
, GL_SPECULAR
, mat_specular
);
256 glMaterialfv(GL_FRONT_AND_BACK
, GL_SHININESS
, mat_shininess
);
260 /* no local viewer, looks ugly in ortho mode */
261 /* glLightModelfv(GL_LIGHT_MODEL_LOCAL_VIEWER, &one); */
263 glDepthFunc(GL_LEQUAL
);
264 /* scaling matrices */
265 glEnable(GL_NORMALIZE
);
267 glShadeModel(GL_FLAT
);
269 glDisable(GL_ALPHA_TEST
);
271 glDisable(GL_DEPTH_TEST
);
273 glDisable(GL_LIGHTING
);
274 glDisable(GL_LOGIC_OP
);
275 glDisable(GL_STENCIL_TEST
);
276 glDisable(GL_TEXTURE_1D
);
277 glDisable(GL_TEXTURE_2D
);
279 /* default on, disable/enable should be local per function */
280 glEnableClientState(GL_VERTEX_ARRAY
);
281 glEnableClientState(GL_NORMAL_ARRAY
);
283 glPixelTransferi(GL_MAP_COLOR
, GL_FALSE
);
284 glPixelTransferi(GL_RED_SCALE
, 1);
285 glPixelTransferi(GL_RED_BIAS
, 0);
286 glPixelTransferi(GL_GREEN_SCALE
, 1);
287 glPixelTransferi(GL_GREEN_BIAS
, 0);
288 glPixelTransferi(GL_BLUE_SCALE
, 1);
289 glPixelTransferi(GL_BLUE_BIAS
, 0);
290 glPixelTransferi(GL_ALPHA_SCALE
, 1);
291 glPixelTransferi(GL_ALPHA_BIAS
, 0);
293 glPixelTransferi(GL_DEPTH_BIAS
, 0);
294 glPixelTransferi(GL_DEPTH_SCALE
, 1);
295 glDepthRange(0.0, 1.0);
298 for(x
=0; x
<32; x
++) {
300 if( (x
) & 1) pat
[a
++]= 0x88;
305 glPolygonStipple(patc
);
311 void circf(float x
, float y
, float rad
)
313 GLUquadricObj
*qobj
= gluNewQuadric();
315 gluQuadricDrawStyle(qobj
, GLU_FILL
);
319 glTranslatef(x
, y
, 0.);
321 gluDisk( qobj
, 0.0, rad
, 32, 1);
325 gluDeleteQuadric(qobj
);
328 void circ(float x
, float y
, float rad
)
330 GLUquadricObj
*qobj
= gluNewQuadric();
332 gluQuadricDrawStyle(qobj
, GLU_SILHOUETTE
);
336 glTranslatef(x
, y
, 0.);
338 gluDisk( qobj
, 0.0, rad
, 32, 1);
342 gluDeleteQuadric(qobj
);
345 /* ********** ********** */
347 static void draw_bgpic(void)
352 float vec
[4], fac
, asp
, zoomx
, zoomy
;
353 float x1
, y1
, x2
, y2
, cx
, cy
;
356 if(bgpic
==NULL
) return;
361 ibuf
= BKE_image_get_ibuf(ima
, &bgpic
->iuser
);
362 if(ibuf
==NULL
|| (ibuf
->rect
==NULL
&& ibuf
->rect_float
==NULL
) )
364 if(ibuf
->channels
!=4)
367 IMB_rect_from_float(ibuf
);
372 calc_viewborder(G
.vd
, &vb
);
382 /* calc window coord */
383 initgrabz(0.0, 0.0, 0.0);
384 window_to_3d(vec
, 1, 0);
385 fac
= MAX3( fabs(vec
[0]), fabs(vec
[1]), fabs(vec
[1]) );
388 asp
= ( (float)ibuf
->y
)/(float)ibuf
->x
;
390 vec
[0] = vec
[1] = vec
[2] = 0.0;
391 view3d_project_float(curarea
, vec
, sco
, G
.vd
->persmat
);
395 x1
= cx
+ fac
*(bgpic
->xof
-bgpic
->size
);
396 y1
= cy
+ asp
*fac
*(bgpic
->yof
-bgpic
->size
);
397 x2
= cx
+ fac
*(bgpic
->xof
+bgpic
->size
);
398 y2
= cy
+ asp
*fac
*(bgpic
->yof
+bgpic
->size
);
405 if(x1
> curarea
->winx
) return;
406 if(y1
> curarea
->winy
) return;
408 zoomx
= (x2
-x1
)/ibuf
->x
;
409 zoomy
= (y2
-y1
)/ibuf
->y
;
411 /* for some reason; zoomlevels down refuses to use GL_ALPHA_SCALE */
412 if(zoomx
< 1.0f
|| zoomy
< 1.0f
) {
413 float tzoom
= MIN2(zoomx
, zoomy
);
416 if(ibuf
->mipmap
[0]==NULL
)
417 IMB_makemipmap(ibuf
, 0);
419 while(tzoom
< 1.0f
&& mip
<8 && ibuf
->mipmap
[mip
]) {
426 ibuf
= ibuf
->mipmap
[mip
-1];
429 if(G
.vd
->zbuf
) glDisable(GL_DEPTH_TEST
);
431 glBlendFunc(GL_SRC_ALPHA
, GL_ONE_MINUS_SRC_ALPHA
);
433 glMatrixMode(GL_PROJECTION
);
435 glMatrixMode(GL_MODELVIEW
);
438 glaDefine2DArea(&curarea
->winrct
);
442 glPixelZoom(zoomx
, zoomy
);
443 glColor4f(1.0, 1.0, 1.0, 1.0-bgpic
->blend
);
444 glaDrawPixelsTex(x1
, y1
, ibuf
->x
, ibuf
->y
, GL_UNSIGNED_BYTE
, ibuf
->rect
);
446 glPixelZoom(1.0, 1.0);
447 glPixelTransferf(GL_ALPHA_SCALE
, 1.0f
);
449 glMatrixMode(GL_PROJECTION
);
451 glMatrixMode(GL_MODELVIEW
);
455 if(G
.vd
->zbuf
) glEnable(GL_DEPTH_TEST
);
457 areawinset(curarea
->win
); // restore viewport / scissor
460 static void drawgrid_draw(float wx
, float wy
, float x
, float y
, float dx
)
469 while(fx
< curarea
->winx
) {
470 fdrawline(fx
, 0.0, fx
, (float)curarea
->winy
);
478 while(fy
< curarea
->winy
) {
479 fdrawline(0.0, fy
, (float)curarea
->winx
, fy
);
485 // not intern, called in editobject for constraint axis too
486 void make_axis_color(char *col
, char *col2
, char axis
)
489 col2
[0]= col
[0]>219?255:col
[0]+36;
490 col2
[1]= col
[1]<26?0:col
[1]-26;
491 col2
[2]= col
[2]<26?0:col
[2]-26;
494 col2
[0]= col
[0]<46?0:col
[0]-36;
495 col2
[1]= col
[1]>189?255:col
[1]+66;
496 col2
[2]= col
[2]<46?0:col
[2]-36;
499 col2
[0]= col
[0]<26?0:col
[0]-26;
500 col2
[1]= col
[1]<26?0:col
[1]-26;
501 col2
[2]= col
[2]>209?255:col
[2]+46;
506 static void drawgrid(void)
508 /* extern short bgpicmode; */
509 float wx
, wy
, x
, y
, fw
, fx
, fy
, dx
;
511 char col
[3], col2
[3];
512 short sublines
= G
.vd
->gridsubdiv
;
514 vec4
[0]=vec4
[1]=vec4
[2]=0.0;
516 Mat4MulVec4fl(G
.vd
->persmat
, vec4
);
521 wx
= (curarea
->winx
/2.0); /* because of rounding errors, grid at wrong location */
522 wy
= (curarea
->winy
/2.0);
527 vec4
[0]=vec4
[1]=G
.vd
->grid
;
530 Mat4MulVec4fl(G
.vd
->persmat
, vec4
);
535 dx
= fabs(x
-(wx
)*fx
/fw
);
536 if(dx
==0) dx
= fabs(y
-(wy
)*fy
/fw
);
538 glDepthMask(0); // disable write in zbuffer
541 BIF_ThemeColor(TH_GRID
);
545 G
.vd
->gridview
*= sublines
;
549 G
.vd
->gridview
*= sublines
;
553 G
.vd
->gridview
*= sublines
;
557 BIF_ThemeColor(TH_GRID
);
558 drawgrid_draw(wx
, wy
, x
, y
, dx
);
561 else { // start blending out
562 BIF_ThemeColorBlend(TH_BACK
, TH_GRID
, dx
/60.0);
563 drawgrid_draw(wx
, wy
, x
, y
, dx
);
565 BIF_ThemeColor(TH_GRID
);
566 drawgrid_draw(wx
, wy
, x
, y
, sublines
*dx
);
569 else { // start blending out (6 < dx < 60)
570 BIF_ThemeColorBlend(TH_BACK
, TH_GRID
, dx
/60.0);
571 drawgrid_draw(wx
, wy
, x
, y
, dx
);
573 BIF_ThemeColor(TH_GRID
);
574 drawgrid_draw(wx
, wy
, x
, y
, sublines
*dx
);
578 if(dx
>60.0) { // start blending in
579 G
.vd
->gridview
/= sublines
;
581 if(dx
>60.0) { // start blending in
582 G
.vd
->gridview
/= sublines
;
585 BIF_ThemeColor(TH_GRID
);
586 drawgrid_draw(wx
, wy
, x
, y
, dx
);
589 BIF_ThemeColorBlend(TH_BACK
, TH_GRID
, dx
/60.0);
590 drawgrid_draw(wx
, wy
, x
, y
, dx
);
591 BIF_ThemeColor(TH_GRID
);
592 drawgrid_draw(wx
, wy
, x
, y
, dx
*sublines
);
596 BIF_ThemeColorBlend(TH_BACK
, TH_GRID
, dx
/60.0);
597 drawgrid_draw(wx
, wy
, x
, y
, dx
);
598 BIF_ThemeColor(TH_GRID
);
599 drawgrid_draw(wx
, wy
, x
, y
, dx
*sublines
);
603 BIF_ThemeColorBlend(TH_BACK
, TH_GRID
, dx
/60.0);
604 drawgrid_draw(wx
, wy
, x
, y
, dx
);
605 BIF_ThemeColor(TH_GRID
);
606 drawgrid_draw(wx
, wy
, x
, y
, dx
*sublines
);
612 BIF_GetThemeColor3ubv(TH_GRID
, col
);
617 if(G
.vd
->view
==3) make_axis_color(col
, col2
, 'y');
618 else make_axis_color(col
, col2
, 'x');
619 glColor3ubv((GLubyte
*)col2
);
621 fdrawline(0.0, y
, (float)curarea
->winx
, y
);
623 if(G
.vd
->view
==7) make_axis_color(col
, col2
, 'y');
624 else make_axis_color(col
, col2
, 'z');
625 glColor3ubv((GLubyte
*)col2
);
627 fdrawline(x
, 0.0, x
, (float)curarea
->winy
);
629 glDepthMask(1); // enable write in zbuffer
635 static void drawfloor(void)
639 int a
, gridlines
, emphasise
;
640 char col
[3], col2
[3];
643 vd
= curarea
->spacedata
.first
;
647 if(vd
->gridlines
<3) return;
649 if(G
.vd
->zbuf
&& G
.obedit
) glDepthMask(0); // for zbuffer-select
651 gridlines
= vd
->gridlines
/2;
652 grid
= gridlines
*vd
->grid
;
654 BIF_GetThemeColor3ubv(TH_GRID
, col
);
655 BIF_GetThemeColor3ubv(TH_BACK
, col2
);
657 /* emphasise division lines lighter instead of darker, if background is darker than grid */
658 if ( ((col
[0]+col
[1]+col
[2])/3+10) > (col2
[0]+col2
[1]+col2
[2])/3 )
663 /* draw the Y axis and/or grid lines */
664 for(a
= -gridlines
;a
<=gridlines
;a
++) {
666 /* check for the 'show Y axis' preference */
667 if (vd
->gridflag
& V3D_SHOW_Y
) {
668 make_axis_color(col
, col2
, 'y');
669 glColor3ubv((GLubyte
*)col2
);
672 } else if (vd
->gridflag
& V3D_SHOW_FLOOR
) {
673 BIF_ThemeColorShade(TH_GRID
, emphasise
);
678 /* check for the 'show grid floor' preference */
679 if (vd
->gridflag
& V3D_SHOW_FLOOR
) {
681 BIF_ThemeColorShade(TH_GRID
, emphasise
);
683 else BIF_ThemeColorShade(TH_GRID
, 10);
692 glBegin(GL_LINE_STRIP
);
702 /* draw the X axis and/or grid lines */
703 for(a
= -gridlines
;a
<=gridlines
;a
++) {
705 /* check for the 'show X axis' preference */
706 if (vd
->gridflag
& V3D_SHOW_X
) {
707 make_axis_color(col
, col2
, 'x');
708 glColor3ubv((GLubyte
*)col2
);
711 } else if (vd
->gridflag
& V3D_SHOW_FLOOR
) {
712 BIF_ThemeColorShade(TH_GRID
, emphasise
);
717 /* check for the 'show grid floor' preference */
718 if (vd
->gridflag
& V3D_SHOW_FLOOR
) {
720 BIF_ThemeColorShade(TH_GRID
, emphasise
);
722 else BIF_ThemeColorShade(TH_GRID
, 10);
731 glBegin(GL_LINE_STRIP
);
741 /* draw the Z axis line */
742 /* check for the 'show Z axis' preference */
743 if (vd
->gridflag
& V3D_SHOW_Z
) {
744 make_axis_color(col
, col2
, 'z');
745 glColor3ubv((GLubyte
*)col2
);
747 glBegin(GL_LINE_STRIP
);
757 if(G
.vd
->zbuf
&& G
.obedit
) glDepthMask(1);
761 static void drawcursor(View3D
*v3d
)
766 /* we dont want the clipping for cursor */
769 project_short( give_cursor(), co
);
778 circ((float)mx
, (float)my
, 10.0);
781 circ((float)mx
, (float)my
, 10.0);
785 sdrawline(mx
-20, my
, mx
-5, my
);
786 sdrawline(mx
+5, my
, mx
+20, my
);
787 sdrawline(mx
, my
-20, mx
, my
-5);
788 sdrawline(mx
, my
+5, mx
, my
+20);
792 /* ********* custom clipping *********** */
794 static void view3d_draw_clipping(View3D
*v3d
)
796 BoundBox
*bb
= v3d
->clipbb
;
798 BIF_ThemeColorShade(TH_BACK
, -8);
802 glVertex3fv(bb
->vec
[0]); glVertex3fv(bb
->vec
[1]); glVertex3fv(bb
->vec
[2]); glVertex3fv(bb
->vec
[3]);
803 glVertex3fv(bb
->vec
[0]); glVertex3fv(bb
->vec
[4]); glVertex3fv(bb
->vec
[5]); glVertex3fv(bb
->vec
[1]);
804 glVertex3fv(bb
->vec
[4]); glVertex3fv(bb
->vec
[7]); glVertex3fv(bb
->vec
[6]); glVertex3fv(bb
->vec
[5]);
805 glVertex3fv(bb
->vec
[7]); glVertex3fv(bb
->vec
[3]); glVertex3fv(bb
->vec
[2]); glVertex3fv(bb
->vec
[6]);
806 glVertex3fv(bb
->vec
[1]); glVertex3fv(bb
->vec
[5]); glVertex3fv(bb
->vec
[6]); glVertex3fv(bb
->vec
[2]);
807 glVertex3fv(bb
->vec
[7]); glVertex3fv(bb
->vec
[4]); glVertex3fv(bb
->vec
[0]); glVertex3fv(bb
->vec
[3]);
812 void view3d_set_clipping(View3D
*v3d
)
818 QUATCOPY(plane
, v3d
->clip
[a
]);
819 glClipPlane(GL_CLIP_PLANE0
+a
, plane
);
820 glEnable(GL_CLIP_PLANE0
+a
);
824 void view3d_clr_clipping(void)
829 glDisable(GL_CLIP_PLANE0
+a
);
833 int view3d_test_clipping(View3D
*v3d
, float *vec
)
835 /* vec in world coordinates, returns 1 if clipped */
840 if(0.0f
< v3d
->clip
[0][3] + INPR(view
, v3d
->clip
[0]))
841 if(0.0f
< v3d
->clip
[1][3] + INPR(view
, v3d
->clip
[1]))
842 if(0.0f
< v3d
->clip
[2][3] + INPR(view
, v3d
->clip
[2]))
843 if(0.0f
< v3d
->clip
[3][3] + INPR(view
, v3d
->clip
[3]))
849 /* ********* end custom clipping *********** */
851 static void view3d_get_viewborder_size(View3D
*v3d
, float size_r
[2])
853 float winmax
= MAX2(v3d
->area
->winx
, v3d
->area
->winy
);
854 float aspect
= (float) (G
.scene
->r
.xsch
*G
.scene
->r
.xasp
)/(G
.scene
->r
.ysch
*G
.scene
->r
.yasp
);
858 size_r
[1]= winmax
/aspect
;
860 size_r
[0]= winmax
*aspect
;
865 void calc_viewborder(struct View3D
*v3d
, rctf
*viewborder_r
)
867 float zoomfac
, size
[2];
868 float dx
= 0.0f
, dy
= 0.0f
;
870 view3d_get_viewborder_size(v3d
, size
);
872 /* magic zoom calculation, no idea what
873 * it signifies, if you find out, tell me! -zr
875 /* simple, its magic dude!
876 * well, to be honest, this gives a natural feeling zooming
877 * with multiple keypad presses (ton)
880 zoomfac
= (M_SQRT2
+ v3d
->camzoom
/50.0);
881 zoomfac
= (zoomfac
*zoomfac
)*0.25;
883 size
[0]= size
[0]*zoomfac
;
884 size
[1]= size
[1]*zoomfac
;
886 /* center in window */
887 viewborder_r
->xmin
= 0.5*v3d
->area
->winx
- 0.5*size
[0];
888 viewborder_r
->ymin
= 0.5*v3d
->area
->winy
- 0.5*size
[1];
889 viewborder_r
->xmax
= viewborder_r
->xmin
+ size
[0];
890 viewborder_r
->ymax
= viewborder_r
->ymin
+ size
[1];
892 dx
= v3d
->area
->winx
*G
.vd
->camdx
*zoomfac
*2.0f
;
893 dy
= v3d
->area
->winy
*G
.vd
->camdy
*zoomfac
*2.0f
;
896 viewborder_r
->xmin
-= dx
;
897 viewborder_r
->ymin
-= dy
;
898 viewborder_r
->xmax
-= dx
;
899 viewborder_r
->ymax
-= dy
;
901 if(v3d
->camera
&& v3d
->camera
->type
==OB_CAMERA
) {
902 Camera
*cam
= v3d
->camera
->data
;
903 float w
= viewborder_r
->xmax
- viewborder_r
->xmin
;
904 float h
= viewborder_r
->ymax
- viewborder_r
->ymin
;
905 float side
= MAX2(w
, h
);
907 viewborder_r
->xmin
+= cam
->shiftx
*side
;
908 viewborder_r
->xmax
+= cam
->shiftx
*side
;
909 viewborder_r
->ymin
+= cam
->shifty
*side
;
910 viewborder_r
->ymax
+= cam
->shifty
*side
;
914 void view3d_set_1_to_1_viewborder(View3D
*v3d
)
917 int im_width
= (G
.scene
->r
.size
*G
.scene
->r
.xsch
)/100;
919 view3d_get_viewborder_size(v3d
, size
);
921 v3d
->camzoom
= (sqrt(4.0*im_width
/size
[0]) - M_SQRT2
)*50.0;
922 v3d
->camzoom
= CLAMPIS(v3d
->camzoom
, -30, 300);
926 static void drawviewborder_flymode(void)
928 /* draws 4 edge brackets that frame the safe area where the
929 mouse can move during fly mode without spinning the view */
930 float x1
, x2
, y1
, y2
;
932 x1
= 0.45*(float)curarea
->winx
;
933 y1
= 0.45*(float)curarea
->winy
;
934 x2
= 0.55*(float)curarea
->winx
;
935 y2
= 0.55*(float)curarea
->winy
;
971 static void drawviewborder(void)
973 extern void gl_round_box(int mode
, float minx
, float miny
, float maxx
, float maxy
, float rad
); // interface_panel.c
975 float x1
, x2
, y1
, y2
;
976 float x3
, y3
, x4
, y4
;
980 if(G
.vd
->camera
==NULL
)
982 if(G
.vd
->camera
->type
==OB_CAMERA
)
983 ca
= G
.vd
->camera
->data
;
985 calc_viewborder(G
.vd
, &viewborder
);
991 /* passepartout, specified in camera edit buttons */
992 if (ca
&& (ca
->flag
& CAM_SHOWPASSEPARTOUT
) && ca
->passepartalpha
> 0.000001) {
993 if (ca
->passepartalpha
== 1.0) {
996 glBlendFunc( GL_SRC_ALPHA
, GL_ONE_MINUS_SRC_ALPHA
);
998 glColor4f(0, 0, 0, ca
->passepartalpha
);
1001 glRectf(0.0, (float)curarea
->winy
, x1
, 0.0);
1002 if (x2
< (float)curarea
->winx
)
1003 glRectf(x2
, (float)curarea
->winy
, (float)curarea
->winx
, 0.0);
1004 if (y2
< (float)curarea
->winy
)
1005 glRectf(x1
, (float)curarea
->winy
, x2
, y2
);
1007 glRectf(x1
, y1
, x2
, 0.0);
1009 glDisable(GL_BLEND
);
1013 glPolygonMode(GL_FRONT_AND_BACK
, GL_LINE
);
1016 BIF_ThemeColor(TH_BACK
);
1017 glRectf(x1
, y1
, x2
, y2
);
1020 BIF_ThemeColor(TH_WIRE
);
1021 glRectf(x1
, y1
, x2
, y2
);
1023 /* camera name - draw in highlighted text colour */
1024 if (ca
&& (ca
->flag
& CAM_SHOWNAME
)) {
1025 BIF_ThemeColor(TH_TEXT_HI
);
1026 glRasterPos2f(x1
, y1
-15);
1028 BMF_DrawString(G
.font
, G
.vd
->camera
->id
.name
+2);
1029 BIF_ThemeColor(TH_WIRE
);
1034 if(G
.scene
->r
.mode
& R_BORDER
) {
1037 x3
= x1
+ G
.scene
->r
.border
.xmin
*(x2
-x1
);
1038 y3
= y1
+ G
.scene
->r
.border
.ymin
*(y2
-y1
);
1039 x4
= x1
+ G
.scene
->r
.border
.xmax
*(x2
-x1
);
1040 y4
= y1
+ G
.scene
->r
.border
.ymax
*(y2
-y1
);
1043 glRectf(x3
, y3
, x4
, y4
);
1047 if (ca
&& (ca
->flag
& CAM_SHOWTITLESAFE
)) {
1058 BIF_ThemeColorBlendShade(TH_WIRE
, TH_BACK
, 0.25, 0);
1061 gl_round_box(GL_LINE_LOOP
, x1
, y1
, x2
, y2
, 12.0);
1065 glPolygonMode(GL_FRONT_AND_BACK
, GL_FILL
);
1069 void backdrawview3d(int test
)
1073 /*for 2.43 release, don't use glext and just define the constant.
1074 this to avoid possibly breaking platforms before release.*/
1075 #ifndef GL_MULTISAMPLE_ARB
1076 #define GL_MULTISAMPLE_ARB 0x809D
1079 #ifdef GL_MULTISAMPLE_ARB
1083 if(G
.f
& (G_VERTEXPAINT
|G_FACESELECT
|G_TEXTUREPAINT
|G_WEIGHTPAINT
));
1084 else if(G
.obedit
&& G
.vd
->drawtype
>OB_WIRE
&& (G
.vd
->flag
& V3D_ZBUF_SELECT
));
1086 G
.vd
->flag
&= ~V3D_NEEDBACKBUFDRAW
;
1090 if( !(G
.vd
->flag
& V3D_NEEDBACKBUFDRAW
) ) return;
1094 addafterqueue(curarea
->win
, BACKBUFDRAW
, 1);
1100 /*Disable FSAA for backbuffer selection.
1102 Only works if GL_MULTISAMPLE_ARB is defined by the header
1103 file, which is should be for every OS that supports FSAA.*/
1105 #ifdef GL_MULTISAMPLE_ARB
1106 m
= glIsEnabled(GL_MULTISAMPLE_ARB
);
1107 if (m
) glDisable(GL_MULTISAMPLE_ARB
);
1111 glDrawBuffer(GL_AUX0
);
1113 if(G
.vd
->drawtype
> OB_WIRE
) G
.vd
->zbuf
= TRUE
;
1114 curarea
->win_swap
&= ~WIN_BACK_OK
;
1116 glDisable(GL_DITHER
);
1118 glClearColor(0.0, 0.0, 0.0, 0.0);
1120 glEnable(GL_DEPTH_TEST
);
1121 glClear(GL_COLOR_BUFFER_BIT
| GL_DEPTH_BUFFER_BIT
);
1124 glClear(GL_COLOR_BUFFER_BIT
);
1125 glDisable(GL_DEPTH_TEST
);
1128 if(G
.vd
->flag
& V3D_CLIPPING
)
1129 view3d_set_clipping(G
.vd
);
1131 G
.f
|= G_BACKBUFSEL
;
1133 base
= (G
.scene
->basact
);
1134 if(base
&& (base
->lay
& G
.vd
->lay
)) {
1135 draw_object_backbufsel(base
->object
);
1138 G
.vd
->flag
&= ~V3D_NEEDBACKBUFDRAW
;
1140 G
.f
&= ~G_BACKBUFSEL
;
1142 glDisable(GL_DEPTH_TEST
);
1143 glEnable(GL_DITHER
);
1146 glDrawBuffer(GL_BACK
); /* we were in aux buffers */
1149 if(G
.vd
->flag
& V3D_CLIPPING
)
1150 view3d_clr_clipping();
1152 #ifdef GL_MULTISAMPLE_ARB
1153 if (m
) glEnable(GL_MULTISAMPLE_ARB
);
1156 /* it is important to end a view in a transform compatible with buttons */
1157 persp(PERSP_WIN
); // set ortho
1158 bwin_scalematrix(curarea
->win
, G
.vd
->blockscale
, G
.vd
->blockscale
, G
.vd
->blockscale
);
1162 void check_backbuf(void)
1164 if(G
.vd
->flag
& V3D_NEEDBACKBUFDRAW
)
1168 /* samples a single pixel (copied from vpaint) */
1169 unsigned int sample_backbuf(int x
, int y
)
1173 if(x
>=curarea
->winx
|| y
>=curarea
->winy
) return 0;
1174 x
+= curarea
->winrct
.xmin
;
1175 y
+= curarea
->winrct
.ymin
;
1177 check_backbuf(); // actually not needed for apple
1180 glReadBuffer(GL_AUX0
);
1182 glReadPixels(x
, y
, 1, 1, GL_RGBA
, GL_UNSIGNED_BYTE
, &col
);
1183 glReadBuffer(GL_BACK
);
1185 if(G
.order
==B_ENDIAN
) SWITCH_INT(col
);
1187 return framebuffer_to_index(col
);
1190 /* reads full rect, converts indices */
1191 ImBuf
*read_backbuf(short xmin
, short ymin
, short xmax
, short ymax
)
1193 unsigned int *dr
, *rd
;
1194 struct ImBuf
*ibuf
, *ibuf1
;
1196 short xminc
, yminc
, xmaxc
, ymaxc
, xs
, ys
;
1199 if(xmin
<0) xminc
= 0; else xminc
= xmin
;
1200 if(xmax
>=curarea
->winx
) xmaxc
= curarea
->winx
-1; else xmaxc
= xmax
;
1201 if(xminc
> xmaxc
) return NULL
;
1203 if(ymin
<0) yminc
= 0; else yminc
= ymin
;
1204 if(ymax
>=curarea
->winy
) ymaxc
= curarea
->winy
-1; else ymaxc
= ymax
;
1205 if(yminc
> ymaxc
) return NULL
;
1207 ibuf
= IMB_allocImBuf((xmaxc
-xminc
+1), (ymaxc
-yminc
+1), 32, IB_rect
,0);
1209 check_backbuf(); // actually not needed for apple
1212 glReadBuffer(GL_AUX0
);
1214 glReadPixels(curarea
->winrct
.xmin
+xminc
, curarea
->winrct
.ymin
+yminc
, (xmaxc
-xminc
+1), (ymaxc
-yminc
+1), GL_RGBA
, GL_UNSIGNED_BYTE
, ibuf
->rect
);
1215 glReadBuffer(GL_BACK
);
1217 if(G
.order
==B_ENDIAN
) IMB_convert_rgba_to_abgr(ibuf
);
1219 a
= (xmaxc
-xminc
+1)*(ymaxc
-yminc
+1);
1222 if(*dr
) *dr
= framebuffer_to_index(*dr
);
1226 /* put clipped result back, if needed */
1227 if(xminc
==xmin
&& xmaxc
==xmax
&& yminc
==ymin
&& ymaxc
==ymax
)
1230 ibuf1
= IMB_allocImBuf( (xmax
-xmin
+1),(ymax
-ymin
+1),32,IB_rect
,0);
1234 for(ys
= ymin
; ys
<=ymax
; ys
++) {
1235 for(xs
= xmin
; xs
<=xmax
; xs
++, dr
++) {
1236 if( xs
>=xminc
&& xs
<=xmaxc
&& ys
>=yminc
&& ys
<=ymaxc
) {
1242 IMB_freeImBuf(ibuf
);
1246 /* smart function to sample a rect spiralling outside, nice for backbuf selection */
1247 unsigned int sample_backbuf_rect(short mval
[2], int size
, unsigned int min
, unsigned int max
, int *dist
, short strict
, unsigned int (*indextest
)(unsigned int index
))
1250 unsigned int *bufmin
, *bufmax
, *tbuf
;
1252 int a
, b
, rc
, nr
, amount
, dirvec
[4][2];
1254 unsigned int index
= 0;
1259 minx
= mval
[0]-(amount
+1);
1260 miny
= mval
[1]-(amount
+1);
1261 buf
= read_backbuf(minx
, miny
, minx
+size
-1, miny
+size
-1);
1266 dirvec
[0][0]= 1; dirvec
[0][1]= 0;
1267 dirvec
[1][0]= 0; dirvec
[1][1]= -size
;
1268 dirvec
[2][0]= -1; dirvec
[2][1]= 0;
1269 dirvec
[3][0]= 0; dirvec
[3][1]= size
;
1273 bufmax
= buf
->rect
+ size
*size
;
1274 tbuf
+= amount
*size
+ amount
;
1276 for(nr
=1; nr
<=size
; nr
++) {
1278 for(a
=0; a
<2; a
++) {
1279 for(b
=0; b
<nr
; b
++, distance
++) {
1280 if (*tbuf
&& *tbuf
>=min
&& *tbuf
<max
) { //we got a hit
1282 indexok
= indextest(*tbuf
- min
+1);
1284 *dist
= (short) sqrt( (float)distance
);
1285 index
= *tbuf
- min
+1;
1290 *dist
= (short) sqrt( (float)distance
); // XXX, this distance is wrong -
1291 index
= *tbuf
- min
+1; // messy yah, but indices start at 1
1296 tbuf
+= (dirvec
[rc
][0]+dirvec
[rc
][1]);
1298 if(tbuf
<bufmin
|| tbuf
>=bufmax
) {
1312 void drawname(Object
*ob
)
1315 glRasterPos3f(0.0, 0.0, 0.0);
1317 BMF_DrawString(G
.font
, " ");
1318 BMF_DrawString(G
.font
, ob
->id
.name
+2);
1322 static void draw_selected_name(Object
*ob
)
1327 if(ob
->type
==OB_ARMATURE
) {
1328 bArmature
*arm
= ob
->data
;
1333 for (ebo
=G
.edbo
.first
; ebo
; ebo
=ebo
->next
){
1334 if ((ebo
->flag
& BONE_ACTIVE
) && (ebo
->layer
& arm
->layer
)) {
1340 else if(ob
->pose
&& (ob
->flag
& OB_POSEMODE
)) {
1341 bPoseChannel
*pchan
;
1342 for(pchan
= ob
->pose
->chanbase
.first
; pchan
; pchan
= pchan
->next
) {
1343 if((pchan
->bone
->flag
& BONE_ACTIVE
) && (pchan
->bone
->layer
& arm
->layer
)) {
1350 sprintf(info
, "(%d) %s %s", CFRA
, ob
->id
.name
+2, name
);
1352 sprintf(info
, "(%d) %s", CFRA
, ob
->id
.name
+2);
1354 else if(ob
->type
==OB_MESH
) {
1356 KeyBlock
*kb
= NULL
;
1360 key
= ob_get_key(ob
);
1362 kb
= BLI_findlink(&key
->block
, ob
->shapenr
-1);
1364 sprintf(shapes
, ": %s ", kb
->name
);
1365 if(ob
->shapeflag
== OB_SHAPE_LOCK
){
1366 sprintf(shapes
, "%s (Pinned)",shapes
);
1370 sprintf(info
, "(%d) %s %s", CFRA
, ob
->id
.name
+2, shapes
);
1372 else sprintf(info
, "(%d) %s", CFRA
, ob
->id
.name
+2);
1374 BIF_ThemeColor(TH_TEXT_HI
);
1375 if (U
.uiflag
& USER_SHOW_ROTVIEWICON
)
1376 offset
= 14 + (U
.rvisize
* 2);
1378 glRasterPos2i(offset
, 10);
1379 BMF_DrawString(G
.fonts
, info
);
1383 /* Draw a live substitute of the view icon, which is always shown */
1384 static void draw_view_axis(void)
1386 const float k
= U
.rvisize
; /* axis size */
1387 const float toll
= 0.5; /* used to see when view is quasi-orthogonal */
1388 const float start
= k
+ 1.0; /* axis center in screen coordinates, x=y */
1389 float ydisp
= 0.0; /* vertical displacement to allow obj info text */
1390 char *cam_name
, info
[128];
1393 if((G
.scene
) && (G
.scene
->camera
))
1394 cam_name
= G
.scene
->camera
->id
.name
+2;
1398 /* rvibright ranges approx. from original axis icon color to gizmo color */
1399 float bright
= U
.rvibright
/ 15.0f
;
1401 unsigned char col
[3];
1402 unsigned char gridcol
[3];
1409 BIF_GetThemeColor3ubv(TH_GRID
, (char *)gridcol
);
1412 vec
[0] = vec
[3] = 1;
1413 vec
[1] = vec
[2] = 0;
1414 QuatMulVecf(G
.vd
->viewquat
, vec
);
1416 make_axis_color((char *)gridcol
, (char *)col
, 'x');
1417 rgb_to_hsv(col
[0]/255.0f
, col
[1]/255.0f
, col
[2]/255.0f
, &h
, &s
, &v
);
1418 s
= s
<0.5 ? s
+0.5 : 1.0;
1420 v
= (v
<1.0-(bright
) ? v
+bright
: 1.0);
1421 hsv_to_rgb(h
, s
, v
, colf
, colf
+1, colf
+2);
1426 fdrawline(start
, start
+ ydisp
, start
+ dx
, start
+ dy
+ ydisp
);
1427 if (fabs(dx
) > toll
|| fabs(dy
) > toll
) {
1428 glRasterPos2i(start
+ dx
+ 2, start
+ dy
+ ydisp
+ 2);
1429 BMF_DrawString(G
.fonts
, "x");
1433 vec
[1] = vec
[3] = 1;
1434 vec
[0] = vec
[2] = 0;
1435 QuatMulVecf(G
.vd
->viewquat
, vec
);
1437 make_axis_color((char *)gridcol
, (char *)col
, 'y');
1438 rgb_to_hsv(col
[0]/255.0f
, col
[1]/255.0f
, col
[2]/255.0f
, &h
, &s
, &v
);
1439 s
= s
<0.5 ? s
+0.5 : 1.0;
1441 v
= (v
<1.0-(bright
) ? v
+bright
: 1.0);
1442 hsv_to_rgb(h
, s
, v
, colf
, colf
+1, colf
+2);
1447 fdrawline(start
, start
+ ydisp
, start
+ dx
, start
+ dy
+ ydisp
);
1448 if (fabs(dx
) > toll
|| fabs(dy
) > toll
) {
1449 glRasterPos2i(start
+ dx
+ 2, start
+ dy
+ ydisp
+ 2);
1450 BMF_DrawString(G
.fonts
, "y");
1454 vec
[2] = vec
[3] = 1;
1455 vec
[1] = vec
[0] = 0;
1456 QuatMulVecf(G
.vd
->viewquat
, vec
);
1458 make_axis_color((char *)gridcol
, (char *)col
, 'z');
1459 rgb_to_hsv(col
[0]/255.0f
, col
[1]/255.0f
, col
[2]/255.0f
, &h
, &s
, &v
);
1460 s
= s
<0.5 ? s
+0.5 : 1.0;
1462 v
= (v
<1.0-(bright
) ? v
+bright
: 1.0);
1463 hsv_to_rgb(h
, s
, v
, colf
, colf
+1, colf
+2);
1468 fdrawline(start
, start
+ ydisp
, start
+ dx
, start
+ dy
+ ydisp
);
1469 if (fabs(dx
) > toll
|| fabs(dy
) > toll
) {
1470 glRasterPos2i(start
+ dx
+ 2, start
+ dy
+ ydisp
+ 2);
1471 BMF_DrawString(G
.fonts
, "z");
1474 if((G
.show_cam
) && (cam_name
)) {
1475 BIF_ThemeColor(TH_TEXT_HI
);
1476 sprintf(info
, "CA: %s", cam_name
);
1477 offset
= (G
.vd
->area
->winx
-30) - (strlen (cam_name
) * 12);
1478 glRasterPos2i(offset
, 10);
1479 BMF_DrawString(G
.fonts
, info
);
1484 static void draw_view_icon(void)
1488 if(G
.vd
->view
==7) icon
= ICON_AXIS_TOP
;
1489 else if(G
.vd
->view
==1) icon
= ICON_AXIS_FRONT
;
1490 else if(G
.vd
->view
==3) icon
= ICON_AXIS_SIDE
;
1494 glBlendFunc(GL_SRC_ALPHA
, GL_ONE_MINUS_SRC_ALPHA
);
1496 BIF_icon_draw(5.0, 5.0, icon
);
1498 glDisable(GL_BLEND
);
1501 static void draw_viewport_name(ScrArea
*sa
)
1504 char *printable
= NULL
;
1506 switch(G
.vd
->view
) {
1508 if (G
.vd
->persp
& V3D_PERSP_DO_3D_PERSP
)
1509 name
= (G
.vd
->flag2
& V3D_OPP_DIRECTION_NAME
) ? "Back Persp" : "Front Persp";
1511 name
= (G
.vd
->flag2
& V3D_OPP_DIRECTION_NAME
) ? "Back Ortho" : "Front Ortho";
1514 if (G
.vd
->persp
& V3D_PERSP_DO_3D_PERSP
)
1515 name
= (G
.vd
->flag2
& V3D_OPP_DIRECTION_NAME
) ? "Left Persp" : "Right Persp";
1517 name
= (G
.vd
->flag2
& V3D_OPP_DIRECTION_NAME
) ? "Left Ortho" : "Right Ortho";
1520 if (G
.vd
->persp
& V3D_PERSP_DO_3D_PERSP
)
1521 name
= (G
.vd
->flag2
& V3D_OPP_DIRECTION_NAME
) ? "Bottom Persp" : "Top Persp";
1523 name
= (G
.vd
->flag2
& V3D_OPP_DIRECTION_NAME
) ? "Bottom Ortho" : "Top Ortho";
1526 if(G
.vd
->persp
==V3D_PERSP_USE_THE_CAMERA
) {
1527 if (G
.vd
->camera
->type
== OB_CAMERA
) {
1529 cam
= G
.vd
->camera
->data
;
1530 name
= (cam
->type
!= CAM_ORTHO
) ? "Camera Persp" : "Camera Ortho";
1532 name
= "Object as Camera";
1535 name
= (G
.vd
->persp
& V3D_PERSP_DO_3D_PERSP
) ? "User Persp" : "User Ortho";
1539 /* Easy sync of tests to clean up the string allocation */
1540 if (G
.vd
->localview
) {
1541 printable
= malloc(strlen(name
) + strlen(" (Local)_")); /* '_' gives space for '\0' */
1542 strcpy(printable
, name
);
1543 strcat(printable
, " (Local)");
1549 BIF_ThemeColor(TH_TEXT_HI
);
1550 glRasterPos2i(10, sa
->winy
-20);
1551 BMF_DrawString(G
.fonts
, printable
);
1554 if (G
.vd
->localview
) {
1559 /* ******************* view3d space & buttons ************** */
1562 /* temporal struct for storing transform properties */
1564 float ob_eul
[4]; // used for quat too....
1565 float ob_scale
[3]; // need temp space due to linked values
1571 } TransformProperties
;
1573 /* is used for both read and write... */
1574 static void v3d_editvertex_buts(uiBlock
*block
, Object
*ob
, float lim
)
1576 EditMesh
*em
= G
.editMesh
;
1577 EditVert
*eve
, *evedef
=NULL
;
1579 MDeformVert
*dvert
=NULL
;
1580 TransformProperties
*tfp
= G
.vd
->properties_storage
;
1581 float median
[5], ve_median
[5];
1582 int tot
, totw
, totweight
, totedge
;
1585 median
[0]= median
[1]= median
[2]= median
[3]= median
[4]= 0.0;
1586 tot
= totw
= totweight
= totedge
= 0;
1589 if(ob
->type
==OB_MESH
) {
1590 eve
= em
->verts
.first
;
1595 VecAddf(median
, median
, eve
->co
);
1599 eed
= em
->edges
.first
;
1601 if((eed
->f
& SELECT
)) {
1603 median
[3]+= eed
->crease
;
1608 /* check for defgroups */
1610 dvert
= CustomData_em_get(&em
->vdata
, evedef
->data
, CD_MDEFORMVERT
);
1611 if(tot
==1 && dvert
&& dvert
->totweight
) {
1613 int i
, max
=1, init
=1;
1616 for (i
=0; i
<dvert
->totweight
; i
++){
1617 dg
= BLI_findlink (&ob
->defbase
, dvert
->dw
[i
].def_nr
);
1619 max
+= snprintf(str
, sizeof(str
), "%s %%x%d|", dg
->name
, dvert
->dw
[i
].def_nr
);
1620 if(max
<320) strcat(defstr
, str
);
1622 else printf("oh no!\n");
1623 if(tfp
->curdef
==dvert
->dw
[i
].def_nr
) {
1625 tfp
->defweightp
= &dvert
->dw
[i
].weight
;
1629 if(init
) { // needs new initialized
1630 tfp
->curdef
= dvert
->dw
[0].def_nr
;
1631 tfp
->defweightp
= &dvert
->dw
[0].weight
;
1635 else if(ob
->type
==OB_CURVE
|| ob
->type
==OB_SURF
) {
1636 extern ListBase editNurb
; /* editcurve.c */
1644 if((nu
->type
& 7)==CU_BEZIER
) {
1649 VecAddf(median
, median
, bezt
->vec
[1]);
1651 median
[4]+= bezt
->weight
;
1656 VecAddf(median
, median
, bezt
->vec
[0]);
1660 VecAddf(median
, median
, bezt
->vec
[2]);
1669 a
= nu
->pntsu
*nu
->pntsv
;
1672 VecAddf(median
, median
, bp
->vec
);
1673 median
[3]+= bp
->vec
[3];
1676 median
[4]+= bp
->weight
;
1685 else if(ob
->type
==OB_LATTICE
) {
1689 a
= editLatt
->pntsu
*editLatt
->pntsv
*editLatt
->pntsw
;
1692 if(bp
->f1
& SELECT
) {
1693 VecAddf(median
, median
, bp
->vec
);
1695 median
[4]+= bp
->weight
;
1704 median
[0] /= (float)tot
;
1705 median
[1] /= (float)tot
;
1706 median
[2] /= (float)tot
;
1707 if(totedge
) median
[3] /= (float)totedge
;
1708 else if(totw
) median
[3] /= (float)totw
;
1709 if(totweight
) median
[4] /= (float)totweight
;
1711 if(G
.vd
->flag
& V3D_GLOBAL_STATS
)
1712 Mat4MulVecfl(ob
->obmat
, median
);
1714 if(block
) { // buttons
1716 uiBlockBeginAlign(block
);
1717 if((ob
->parent
) && (ob
->partype
== PARBONE
)) {
1718 uiDefButBitS(block
, TOG
, V3D_GLOBAL_STATS
, REDRAWVIEW3D
, "Global", 160, 135, 70, 19, &G
.vd
->flag
, 0, 0, 0, 0, "Displays global values");
1719 uiDefButBitS(block
, TOGN
, V3D_GLOBAL_STATS
, REDRAWVIEW3D
, "Local", 230, 135, 70, 19, &G
.vd
->flag
, 0, 0, 0, 0, "Displays local values");
1722 uiDefButBitS(block
, TOG
, V3D_GLOBAL_STATS
, REDRAWVIEW3D
, "Global", 160, 150, 70, 19, &G
.vd
->flag
, 0, 0, 0, 0, "Displays global values");
1723 uiDefButBitS(block
, TOGN
, V3D_GLOBAL_STATS
, REDRAWVIEW3D
, "Local", 230, 150, 70, 19, &G
.vd
->flag
, 0, 0, 0, 0, "Displays local values");
1726 memcpy(tfp
->ve_median
, median
, sizeof(tfp
->ve_median
));
1728 uiBlockBeginAlign(block
);
1730 uiDefButF(block
, NUM
, B_OBJECTPANELMEDIAN
, "Vertex X:", 10, 110, 290, 19, &(tfp
->ve_median
[0]), -lim
, lim
, 10, 3, "");
1731 uiDefButF(block
, NUM
, B_OBJECTPANELMEDIAN
, "Vertex Y:", 10, 90, 290, 19, &(tfp
->ve_median
[1]), -lim
, lim
, 10, 3, "");
1732 uiDefButF(block
, NUM
, B_OBJECTPANELMEDIAN
, "Vertex Z:", 10, 70, 290, 19, &(tfp
->ve_median
[2]), -lim
, lim
, 10, 3, "");
1734 uiDefButF(block
, NUM
, B_OBJECTPANELMEDIAN
, "Vertex W:", 10, 50, 290, 19, &(tfp
->ve_median
[3]), 0.01, 100.0, 10, 3, "");
1735 uiBlockEndAlign(block
);
1738 uiDefBut(block
, LABEL
, 1, "Vertex Deform Groups", 10, 40, 290, 20, NULL
, 0.0, 0.0, 0, 0, "");
1740 uiBlockBeginAlign(block
);
1741 uiDefButF(block
, NUM
, B_NOP
, "Weight:", 10, 20, 150, 19, tfp
->defweightp
, 0.0f
, 1.0f
, 10, 3, "Weight value");
1742 uiDefButI(block
, MENU
, REDRAWVIEW3D
, defstr
, 160, 20, 140, 19, &tfp
->curdef
, 0.0, 0.0, 0, 0, "Current Vertex Group");
1743 uiBlockEndAlign(block
);
1746 uiDefButF(block
, NUM
, B_OBJECTPANELMEDIAN
, "Weight:", 10, 20, 290, 19, &(tfp
->ve_median
[4]), 0.0, 1.0, 10, 3, "");
1750 uiDefButF(block
, NUM
, B_OBJECTPANELMEDIAN
, "Median X:", 10, 110, 290, 19, &(tfp
->ve_median
[0]), -lim
, lim
, 10, 3, "");
1751 uiDefButF(block
, NUM
, B_OBJECTPANELMEDIAN
, "Median Y:", 10, 90, 290, 19, &(tfp
->ve_median
[1]), -lim
, lim
, 10, 3, "");
1752 uiDefButF(block
, NUM
, B_OBJECTPANELMEDIAN
, "Median Z:", 10, 70, 290, 19, &(tfp
->ve_median
[2]), -lim
, lim
, 10, 3, "");
1754 uiDefButF(block
, NUM
, B_OBJECTPANELMEDIAN
, "Median W:", 10, 50, 290, 19, &(tfp
->ve_median
[3]), 0.01, 100.0, 10, 3, "");
1755 uiBlockEndAlign(block
);
1757 uiDefButF(block
, NUM
, B_OBJECTPANELMEDIAN
, "Weight:", 10, 20, 290, 19, &(tfp
->ve_median
[4]), 0.0, 1.0, 10, 3, "Weight is used for SoftBody Goal");
1761 uiDefButF(block
, NUM
, B_OBJECTPANELMEDIAN
, "Crease W:", 10, 30, 290, 19, &(tfp
->ve_median
[3]), 0.0, 1.0, 10, 3, "");
1763 uiDefButF(block
, NUM
, B_OBJECTPANELMEDIAN
, "Median Crease W:", 10, 30, 290, 19, &(tfp
->ve_median
[3]), 0.0, 1.0, 10, 3, "");
1767 memcpy(ve_median
, tfp
->ve_median
, sizeof(tfp
->ve_median
));
1769 if(G
.vd
->flag
& V3D_GLOBAL_STATS
) {
1770 Mat4Invert(ob
->imat
, ob
->obmat
);
1771 Mat4MulVecfl(ob
->imat
, median
);
1772 Mat4MulVecfl(ob
->imat
, ve_median
);
1774 VecSubf(median
, ve_median
, median
);
1775 median
[3]= ve_median
[3]-median
[3];
1776 median
[4]= ve_median
[4]-median
[4];
1778 if(ob
->type
==OB_MESH
) {
1780 eve
= em
->verts
.first
;
1783 VecAddf(eve
->co
, eve
->co
, median
);
1788 for(eed
= em
->edges
.first
; eed
; eed
= eed
->next
) {
1789 if(eed
->f
& SELECT
) {
1790 /* ensure the median can be set to zero or one */
1791 if(ve_median
[3]==0.0f
) eed
->crease
= 0.0f
;
1792 else if(ve_median
[3]==1.0f
) eed
->crease
= 1.0f
;
1794 eed
->crease
+= median
[3];
1795 CLAMP(eed
->crease
, 0.0, 1.0);
1800 recalc_editnormals();
1802 else if(ob
->type
==OB_CURVE
|| ob
->type
==OB_SURF
) {
1803 extern ListBase editNurb
; /* editcurve.c */
1811 if((nu
->type
& 7)==1) {
1816 VecAddf(bezt
->vec
[0], bezt
->vec
[0], median
);
1817 VecAddf(bezt
->vec
[1], bezt
->vec
[1], median
);
1818 VecAddf(bezt
->vec
[2], bezt
->vec
[2], median
);
1819 bezt
->weight
+= median
[4];
1823 VecAddf(bezt
->vec
[0], bezt
->vec
[0], median
);
1826 VecAddf(bezt
->vec
[2], bezt
->vec
[2], median
);
1834 a
= nu
->pntsu
*nu
->pntsv
;
1837 VecAddf(bp
->vec
, bp
->vec
, median
);
1838 bp
->vec
[3]+= median
[3];
1839 bp
->weight
+= median
[4];
1845 testhandlesNurb(nu
); /* test for bezier too */
1850 else if(ob
->type
==OB_LATTICE
) {
1854 a
= editLatt
->pntsu
*editLatt
->pntsv
*editLatt
->pntsw
;
1857 if(bp
->f1
& SELECT
) {
1858 VecAddf(bp
->vec
, bp
->vec
, median
);
1859 bp
->weight
+= median
[4];
1865 BIF_undo_push("Transform properties");
1869 /* assumes armature active */
1870 static void validate_bonebutton_cb(void *bonev
, void *namev
)
1874 if(ob
&& ob
->type
==OB_ARMATURE
) {
1876 char oldname
[32], newname
[32];
1878 /* need to be on the stack */
1879 BLI_strncpy(newname
, bone
->name
, 32);
1880 BLI_strncpy(oldname
, (char *)namev
, 32);
1882 BLI_strncpy(bone
->name
, oldname
, 32);
1884 armature_bone_rename(ob
->data
, oldname
, newname
); // editarmature.c
1885 allqueue(REDRAWALL
, 0);
1890 static void v3d_posearmature_buts(uiBlock
*block
, Object
*ob
, float lim
)
1894 bPoseChannel
*pchan
;
1896 TransformProperties
*tfp
= G
.vd
->properties_storage
;
1898 arm
= get_armature(OBACT
);
1899 if (!arm
|| !ob
->pose
) return;
1901 for(pchan
= ob
->pose
->chanbase
.first
; pchan
; pchan
= pchan
->next
) {
1903 if(bone
&& (bone
->flag
& BONE_ACTIVE
) && (bone
->layer
& arm
->layer
))
1906 if (!pchan
|| !bone
) return;
1908 if((ob
->parent
) && (ob
->partype
== PARBONE
))
1909 but
= uiDefBut (block
, TEX
, B_DIFF
, "Bone:", 160, 130, 140, 19, bone
->name
, 1, 31, 0, 0, "");
1911 but
= uiDefBut(block
, TEX
, B_DIFF
, "Bone:", 160, 140, 140, 19, bone
->name
, 1, 31, 0, 0, "");
1912 uiButSetFunc(but
, validate_bonebutton_cb
, bone
, NULL
);
1914 QuatToEul(pchan
->quat
, tfp
->ob_eul
);
1915 tfp
->ob_eul
[0]*= 180.0/M_PI
;
1916 tfp
->ob_eul
[1]*= 180.0/M_PI
;
1917 tfp
->ob_eul
[2]*= 180.0/M_PI
;
1919 uiBlockBeginAlign(block
);
1920 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");
1921 uiDefButF(block
, NUM
, B_ARMATUREPANEL2
, "LocX:", 30, 140, 120, 19, pchan
->loc
, -lim
, lim
, 100, 3, "");
1922 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");
1923 uiDefButF(block
, NUM
, B_ARMATUREPANEL2
, "LocY:", 30, 120, 120, 19, pchan
->loc
+1, -lim
, lim
, 100, 3, "");
1924 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");
1925 uiDefButF(block
, NUM
, B_ARMATUREPANEL2
, "LocZ:", 30, 100, 120, 19, pchan
->loc
+2, -lim
, lim
, 100, 3, "");
1927 uiBlockBeginAlign(block
);
1928 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");
1929 uiDefButF(block
, NUM
, B_ARMATUREPANEL3
, "RotX:", 30, 70, 120, 19, tfp
->ob_eul
, -1000.0, 1000.0, 100, 3, "");
1930 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");
1931 uiDefButF(block
, NUM
, B_ARMATUREPANEL3
, "RotY:", 30, 50, 120, 19, tfp
->ob_eul
+1, -1000.0, 1000.0, 100, 3, "");
1932 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");
1933 uiDefButF(block
, NUM
, B_ARMATUREPANEL3
, "RotZ:", 30, 30, 120, 19, tfp
->ob_eul
+2, -1000.0, 1000.0, 100, 3, "");
1935 uiBlockBeginAlign(block
);
1936 uiDefIconButBitS(block
, ICONTOG
, OB_LOCK_SCALEX
, REDRAWVIEW3D
, ICON_UNLOCKED
, 160,70,20,19, &(pchan
->protectflag
), 0, 0, 0, 0, "Protects this value from being Transformed");
1937 uiDefButF(block
, NUM
, B_ARMATUREPANEL2
, "ScaleX:", 180, 70, 120, 19, pchan
->size
, -lim
, lim
, 10, 3, "");
1938 uiDefIconButBitS(block
, ICONTOG
, OB_LOCK_SCALEY
, REDRAWVIEW3D
, ICON_UNLOCKED
, 160,50,20,19, &(pchan
->protectflag
), 0, 0, 0, 0, "Protects this value from being Transformed");
1939 uiDefButF(block
, NUM
, B_ARMATUREPANEL2
, "ScaleY:", 180, 50, 120, 19, pchan
->size
+1, -lim
, lim
, 10, 3, "");
1940 uiDefIconButBitS(block
, ICONTOG
, OB_LOCK_SCALEZ
, REDRAWVIEW3D
, ICON_UNLOCKED
, 160,30,20,19, &(pchan
->protectflag
), 0, 0, 0, 0, "Protects this value from being Transformed");
1941 uiDefButF(block
, NUM
, B_ARMATUREPANEL2
, "ScaleZ:", 180, 30, 120, 19, pchan
->size
+2, -lim
, lim
, 10, 3, "");
1942 uiBlockEndAlign(block
);
1945 static void v3d_editarmature_buts(uiBlock
*block
, Object
*ob
, float lim
)
1947 bArmature
*arm
= G
.obedit
->data
;
1950 TransformProperties
*tfp
= G
.vd
->properties_storage
;
1952 ebone
= G
.edbo
.first
;
1954 for (ebone
= G
.edbo
.first
; ebone
; ebone
=ebone
->next
){
1955 if ((ebone
->flag
& BONE_ACTIVE
) && (ebone
->layer
& arm
->layer
))
1962 if((ob
->parent
) && (ob
->partype
== PARBONE
))
1963 but
= uiDefBut(block
, TEX
, B_DIFF
, "Bone:", 160, 130, 140, 19, ebone
->name
, 1, 31, 0, 0, "");
1965 but
= uiDefBut(block
, TEX
, B_DIFF
, "Bone:", 160, 150, 140, 19, ebone
->name
, 1, 31, 0, 0, "");
1966 uiButSetFunc(but
, validate_editbonebutton_cb
, ebone
, NULL
);
1968 uiBlockBeginAlign(block
);
1969 uiDefButF(block
, NUM
, B_ARMATUREPANEL1
, "RootX:", 10, 70, 140, 19, ebone
->head
, -lim
, lim
, 10, 3, "");
1970 uiDefButF(block
, NUM
, B_ARMATUREPANEL1
, "RootY:", 10, 50, 140, 19, ebone
->head
+1, -lim
, lim
, 10, 3, "");
1971 uiDefButF(block
, NUM
, B_ARMATUREPANEL1
, "RootZ:", 10, 30, 140, 19, ebone
->head
+2, -lim
, lim
, 10, 3, "");
1972 uiBlockBeginAlign(block
);
1973 uiDefButF(block
, NUM
, B_ARMATUREPANEL1
, "TipX:", 160, 70, 140, 19, ebone
->tail
, -lim
, lim
, 10, 3, "");
1974 uiDefButF(block
, NUM
, B_ARMATUREPANEL1
, "TipY:", 160, 50, 140, 19, ebone
->tail
+1, -lim
, lim
, 10, 3, "");
1975 uiDefButF(block
, NUM
, B_ARMATUREPANEL1
, "TipZ:", 160, 30, 140, 19, ebone
->tail
+2, -lim
, lim
, 10, 3, "");
1976 uiBlockEndAlign(block
);
1977 tfp
->ob_eul
[0]= 180.0*ebone
->roll
/M_PI
;
1978 uiDefIconButBitI(block
, ICONTOG
, BONE_LOCK_ROLL
, REDRAWVIEW3D
, ICON_UNLOCKED
, 10,100,20,19, &(ebone
->flag
), 0, 0, 0, 0, "Protects roll value from being Recalculate");
1979 uiDefButF(block
, NUM
, B_ARMATUREPANEL1
, "Roll:", 30, 100, 120, 19, tfp
->ob_eul
, -lim
, lim
, 1000, 3, "");
1983 uiBlockBeginAlign(block
);
1984 uiDefButF(block
, NUM
, B_ARMATUREPANEL1
, "TipRadius:", 10, 150, 140, 19, &ebone
->rad_tail
, 0, lim
, 10, 3, "");
1985 if (ebone
->parent
&& ebone
->flag
& BONE_CONNECTED
)
1986 uiDefButF(block
, NUM
, B_ARMATUREPANEL1
, "HeadRadius:", 10, 130, 140, 19, &ebone
->parent
->rad_tail
, 0, lim
, 10, 3, "");
1988 uiDefButF(block
, NUM
, B_ARMATUREPANEL1
, "HeadRadius:", 10, 130, 140, 19, &ebone
->rad_head
, 0, lim
, 10, 3, "");
1989 uiBlockEndAlign(block
);
1992 static void v3d_editmetaball_buts(uiBlock
*block
, Object
*ob
, float lim
)
1994 extern MetaElem
*lastelem
;
1997 uiBlockBeginAlign(block
);
1998 uiDefButF(block
, NUM
, B_RECALCMBALL
, "LocX:", 10, 70, 140, 19, &lastelem
->x
, -lim
, lim
, 100, 3, "");
1999 uiDefButF(block
, NUM
, B_RECALCMBALL
, "LocY:", 10, 50, 140, 19, &lastelem
->y
, -lim
, lim
, 100, 3, "");
2000 uiDefButF(block
, NUM
, B_RECALCMBALL
, "LocZ:", 10, 30, 140, 19, &lastelem
->z
, -lim
, lim
, 100, 3, "");
2002 uiBlockBeginAlign(block
);
2003 if(lastelem
->type
!=MB_BALL
)
2004 uiDefButF(block
, NUM
, B_RECALCMBALL
, "dx:", 160, 70, 140, 19, &lastelem
->expx
, 0, lim
, 100, 3, "");
2005 if((lastelem
->type
!=MB_BALL
) && (lastelem
->type
!=MB_TUBE
))
2006 uiDefButF(block
, NUM
, B_RECALCMBALL
, "dy:", 160, 50, 140, 19, &lastelem
->expy
, 0, lim
, 100, 3, "");
2007 if((lastelem
->type
==MB_ELIPSOID
) || (lastelem
->type
==MB_CUBE
))
2008 uiDefButF(block
, NUM
, B_RECALCMBALL
, "dz:", 160, 30, 140, 19, &lastelem
->expz
, 0, lim
, 100, 3, "");
2010 uiBlockEndAlign(block
);
2012 uiBlockBeginAlign(block
);
2013 uiDefButF(block
, NUM
, B_RECALCMBALL
, "Radius:", 10, 120, 140, 19, &lastelem
->rad
, 0, lim
, 100, 3, "Size of the active metaball");
2014 uiDefButF(block
, NUM
, B_RECALCMBALL
, "Stiffness:", 10, 100, 140, 19, &lastelem
->s
, 0, 10, 100, 3, "Stiffness of the active metaball");
2015 uiBlockEndAlign(block
);
2017 uiDefButS(block
, MENU
, B_RECALCMBALL
, "Type%t|Ball%x0|Tube%x4|Plane%x5|Elipsoid%x6|Cube%x7", 160, 120, 140, 19, &lastelem
->type
, 0.0, 0.0, 0, 0, "Set active element type");
2022 void do_viewbuts(unsigned short event
)
2027 TransformProperties
*tfp
= G
.vd
->properties_storage
;
2030 if(vd
==NULL
) return;
2035 DAG_object_flush_update(G
.scene
, ob
, OB_RECALC_OB
);
2036 allqueue(REDRAWVIEW3D
, 1);
2039 case B_OBJECTPANELROT
:
2041 ob
->rot
[0]= M_PI
*tfp
->ob_eul
[0]/180.0;
2042 ob
->rot
[1]= M_PI
*tfp
->ob_eul
[1]/180.0;
2043 ob
->rot
[2]= M_PI
*tfp
->ob_eul
[2]/180.0;
2044 DAG_object_flush_update(G
.scene
, ob
, OB_RECALC_OB
);
2045 allqueue(REDRAWVIEW3D
, 1);
2049 case B_OBJECTPANELSCALE
:
2052 /* link scale; figure out which axis changed */
2053 if (tfp
->link_scale
) {
2054 float ratio
, tmp
, max
= 0.0;
2058 max
= fabs(tfp
->ob_scale
[0] - ob
->size
[0]);
2059 tmp
= fabs(tfp
->ob_scale
[1] - ob
->size
[1]);
2064 tmp
= fabs(tfp
->ob_scale
[2] - ob
->size
[2]);
2070 if (ob
->size
[axis
] != tfp
->ob_scale
[axis
]) {
2071 if (fabs(ob
->size
[axis
]) > FLT_EPSILON
) {
2072 ratio
= tfp
->ob_scale
[axis
] / ob
->size
[axis
];
2073 ob
->size
[0] *= ratio
;
2074 ob
->size
[1] *= ratio
;
2075 ob
->size
[2] *= ratio
;
2080 VECCOPY(ob
->size
, tfp
->ob_scale
);
2083 DAG_object_flush_update(G
.scene
, ob
, OB_RECALC_OB
);
2084 allqueue(REDRAWVIEW3D
, 1);
2088 case B_OBJECTPANELDIMS
:
2089 bb
= object_get_boundbox(ob
);
2091 float old_dims
[3], scale
[3], ratio
, len
[3];
2094 Mat4ToSize(ob
->obmat
, scale
);
2096 len
[0] = bb
->vec
[4][0] - bb
->vec
[0][0];
2097 len
[1] = bb
->vec
[2][1] - bb
->vec
[0][1];
2098 len
[2] = bb
->vec
[1][2] - bb
->vec
[0][2];
2100 old_dims
[0] = fabs(scale
[0]) * len
[0];
2101 old_dims
[1] = fabs(scale
[1]) * len
[1];
2102 old_dims
[2] = fabs(scale
[2]) * len
[2];
2104 /* for each axis changed */
2105 for (axis
= 0; axis
<3; axis
++) {
2106 if (fabs(old_dims
[axis
] - tfp
->ob_dims
[axis
]) > 0.0001) {
2107 if (old_dims
[axis
] > 0.0) {
2108 ratio
= tfp
->ob_dims
[axis
] / old_dims
[axis
];
2109 if (tfp
->link_scale
) {
2110 ob
->size
[0] *= ratio
;
2111 ob
->size
[1] *= ratio
;
2112 ob
->size
[2] *= ratio
;
2116 ob
->size
[axis
] *= ratio
;
2120 if (len
[axis
] > 0) {
2121 ob
->size
[axis
] = tfp
->ob_dims
[axis
] / len
[axis
];
2127 /* prevent multiple B_OBJECTPANELDIMS events to keep scaling, cycling with TAB on buttons can cause that */
2128 VECCOPY(tfp
->ob_dims
, old_dims
);
2130 DAG_object_flush_update(G
.scene
, ob
, OB_RECALC_OB
);
2131 allqueue(REDRAWVIEW3D
, 1);
2135 case B_OBJECTPANELMEDIAN
:
2137 v3d_editvertex_buts(NULL
, ob
, 1.0);
2138 DAG_object_flush_update(G
.scene
, ob
, OB_RECALC_DATA
);
2139 allqueue(REDRAWVIEW3D
, 1);
2143 /* note; this case also used for parbone */
2144 case B_OBJECTPANELPARENT
:
2146 if(ob
->id
.lib
|| test_parent_loop(ob
->parent
, ob
) )
2149 DAG_scene_sort(G
.scene
);
2150 DAG_object_flush_update(G
.scene
, ob
, OB_RECALC_OB
);
2152 allqueue(REDRAWVIEW3D
, 1);
2153 allqueue(REDRAWBUTSOBJECT
, 0);
2157 case B_ARMATUREPANEL1
:
2159 bArmature
*arm
= G
.obedit
->data
;
2160 EditBone
*ebone
, *child
;
2162 for (ebone
= G
.edbo
.first
; ebone
; ebone
=ebone
->next
){
2163 if ((ebone
->flag
& BONE_ACTIVE
) && (ebone
->layer
& arm
->layer
))
2167 ebone
->roll
= M_PI
*tfp
->ob_eul
[0]/180.0;
2168 // Update our parent
2169 if (ebone
->parent
&& ebone
->flag
& BONE_CONNECTED
){
2170 VECCOPY (ebone
->parent
->tail
, ebone
->head
);
2173 // Update our children if necessary
2174 for (child
= G
.edbo
.first
; child
; child
=child
->next
){
2175 if (child
->parent
== ebone
&& (child
->flag
& BONE_CONNECTED
)){
2176 VECCOPY (child
->head
, ebone
->tail
);
2179 if(arm
->flag
& ARM_MIRROR_EDIT
) {
2180 EditBone
*eboflip
= armature_bone_get_mirrored(ebone
);
2182 eboflip
->roll
= -ebone
->roll
;
2183 eboflip
->head
[0]= -ebone
->head
[0];
2184 eboflip
->tail
[0]= -ebone
->tail
[0];
2186 // Update our parent
2187 if (eboflip
->parent
&& eboflip
->flag
& BONE_CONNECTED
){
2188 VECCOPY (eboflip
->parent
->tail
, eboflip
->head
);
2191 // Update our children if necessary
2192 for (child
= G
.edbo
.first
; child
; child
=child
->next
){
2193 if (child
->parent
== eboflip
&& (child
->flag
& BONE_CONNECTED
)){
2194 VECCOPY (child
->head
, eboflip
->tail
);
2200 allqueue(REDRAWVIEW3D
, 1);
2204 case B_ARMATUREPANEL3
: // rotate button on channel
2207 bPoseChannel
*pchan
;
2211 arm
= get_armature(OBACT
);
2212 if (!arm
|| !ob
->pose
) return;
2214 for(pchan
= ob
->pose
->chanbase
.first
; pchan
; pchan
= pchan
->next
) {
2216 if(bone
&& (bone
->flag
& BONE_ACTIVE
) && (bone
->layer
& arm
->layer
))
2221 /* make a copy to eul[3], to allow TAB on buttons to work */
2222 eul
[0]= M_PI
*tfp
->ob_eul
[0]/180.0;
2223 eul
[1]= M_PI
*tfp
->ob_eul
[1]/180.0;
2224 eul
[2]= M_PI
*tfp
->ob_eul
[2]/180.0;
2225 EulToQuat(eul
, pchan
->quat
);
2227 /* no break, pass on */
2228 case B_ARMATUREPANEL2
:
2230 ob
->pose
->flag
|= (POSE_LOCKED
|POSE_DO_UNLOCK
);
2231 DAG_object_flush_update(G
.scene
, ob
, OB_RECALC_DATA
);
2232 allqueue(REDRAWVIEW3D
, 1);
2238 static void panel_armature_layer_cb (void *lay_v
, void *value_v
)
2240 short *layer
= lay_v
;
2241 int value
= (int)value_v
;
2243 if(*layer
==0 || G
.qual
==0) *layer
= value
;
2244 allqueue(REDRAWBUTSEDIT
, 0);
2245 allqueue(REDRAWACTION
, 0);
2246 allqueue(REDRAWNLA
, 0);
2249 static void view3d_panel_object(short cntrl
) // VIEW3D_HANDLER_OBJECT
2254 TransformProperties
*tfp
;
2256 static char hexcol
[128];
2260 if(ob
==NULL
) return;
2262 /* make sure we got storage */
2263 if(G
.vd
->properties_storage
==NULL
)
2264 G
.vd
->properties_storage
= MEM_callocN(sizeof(TransformProperties
), "TransformProperties");
2265 tfp
= G
.vd
->properties_storage
;
2267 block
= uiNewBlock(&curarea
->uiblocks
, "view3d_panel_object", UI_EMBOSS
, UI_HELV
, curarea
->win
);
2268 uiPanelControl(UI_PNL_SOLID
| UI_PNL_CLOSE
| cntrl
);
2269 uiSetPanelHandler(VIEW3D_HANDLER_OBJECT
); // for close and esc
2271 if(ob
->type
== OB_ARMATURE
) {
2272 if(G
.prop_flag
& 1) {
2273 if(!uiNewPanel(curarea
, block
, "Transform Properties", "View3d", 10, 230, 318, 310))
2277 if(!uiNewPanel(curarea
, block
, "Transform Properties", "View3d", 10, 230, 195, 100))
2282 if(!uiNewPanel(curarea
, block
, "Transform Properties", "View3d", 10, 230, 318, 204))
2286 uiSetButLock(object_data_is_libdata(ob
), ERROR_LIBDATA_MESSAGE
);
2288 if(G
.prop_flag
& 1) {
2289 if(G
.f
& (G_VERTEXPAINT
|G_FACESELECT
|G_TEXTUREPAINT
|G_WEIGHTPAINT
))
2290 uiBlockSetFlag(block
, UI_BLOCK_FRONTBUFFER
);
2292 bt
= uiDefBut(block
, TEX
, B_IDNAME
, "OB: ", 10, 180, 140, 20, ob
->id
.name
+2, 0.0, 19.0, 0, 0, "");
2294 if(ob
->vnode
) uiButSetFunc(bt
, test_and_send_idbutton_cb
, ob
, ob
->id
.name
);
2295 else uiButSetFunc(bt
, test_idbutton_cb
, ob
->id
.name
, NULL
);
2297 uiButSetFunc(bt
, test_idbutton_cb
, ob
->id
.name
, NULL
);
2301 uiDefIDPoinBut(block
, test_obpoin_but
, ID_OB
, B_OBJECTPANELPARENT
, "Par:", 160, 180, 140, 20, &ob
->parent
, "Parent Object");
2302 if((ob
->parent
) && (ob
->partype
== PARBONE
)) {
2303 if (G
.f
& G_SCULPTMODE
)
2304 uiDefBut(block
, TEX
, B_OBJECTPANELPARENT
, "ParBone:", 310, 180, 140, 20, ob
->parsubstr
, 0.0, 30.0, 0, 0, "");
2306 uiDefBut(block
, TEX
, B_OBJECTPANELPARENT
, "ParBone:", 160, 160, 140, 20, ob
->parsubstr
, 0.0, 30.0, 0, 0, "");
2308 uiButSetCompleteFunc(bt
, autocomplete_bone
, (void *)ob
->parent
);
2311 strcpy(ob
->parsubstr
, "");
2314 lim
= 10000.0f
*MAX2(1.0, G
.vd
->grid
);
2317 if(ob
->type
==OB_ARMATURE
) {
2318 v3d_editarmature_buts(block
, ob
, lim
);
2319 uiDefButS(block
, TOG
, REDRAWVIEW3D
, "Hide Properties", 10, -10, 140, 19, &G
.prop_flag
, 0, 0, 0, 0, "Don't show transformation properties");
2321 if(ob
->type
==OB_MBALL
) v3d_editmetaball_buts(block
, ob
, lim
);
2322 else v3d_editvertex_buts(block
, ob
, lim
);
2324 else if(ob
->flag
& OB_POSEMODE
) {
2325 v3d_posearmature_buts(block
, ob
, lim
);
2326 uiDefButS(block
, TOG
, REDRAWVIEW3D
, "Hide Properties", 10, -10, 140, 19, &G
.prop_flag
, 0, 0, 0, 0, "Don't show transformation properties");
2328 else if(G
.f
& G_WEIGHTPAINT
) {
2329 uiNewPanelTitle(block
, "Weight Paint Properties");
2330 weight_paint_buttons(block
);
2332 else if(G
.f
& (G_VERTEXPAINT
|G_TEXTUREPAINT
)) {
2333 extern VPaint Gvp
; /* from vpaint */
2334 static float hsv
[3], old
[3]; // used as temp mem for picker
2336 ToolSettings
*settings
= G
.scene
->toolsettings
;
2338 if(G
.f
& G_VERTEXPAINT
) rgb
= &Gvp
.r
;
2339 else if(settings
->imapaint
.brush
) rgb
= settings
->imapaint
.brush
->rgb
;
2341 uiNewPanelTitle(block
, "Paint Properties");
2343 /* 'f' is for floating panel */
2344 uiBlockPickerButtons(block
, rgb
, hsv
, old
, hexcol
, 'f', REDRAWBUTSEDIT
);
2346 else if(G
.f
& G_SCULPTMODE
) {
2347 uiNewPanelTitle(block
, "Sculpt Properties");
2348 sculptmode_draw_interface_tools(block
,10,150);
2350 BoundBox
*bb
= NULL
;
2352 uiBlockBeginAlign(block
);
2353 uiDefIconButBitS(block
, ICONTOG
, OB_LOCK_LOCX
, REDRAWVIEW3D
, ICON_UNLOCKED
, 10,150,20,19, &(ob
->protectflag
), 0, 0, 0, 0, "Protects this value from being Transformed");
2354 uiDefButF(block
, NUM
, B_OBJECTPANEL
, "LocX:", 30, 150, 120, 19, &(ob
->loc
[0]), -lim
, lim
, 100, 3, "");
2355 uiDefIconButBitS(block
, ICONTOG
, OB_LOCK_LOCY
, REDRAWVIEW3D
, ICON_UNLOCKED
, 10,130,20,19, &(ob
->protectflag
), 0, 0, 0, 0, "Protects this value from being Transformed");
2356 uiDefButF(block
, NUM
, B_OBJECTPANEL
, "LocY:", 30, 130, 120, 19, &(ob
->loc
[1]), -lim
, lim
, 100, 3, "");
2357 uiDefIconButBitS(block
, ICONTOG
, OB_LOCK_LOCZ
, REDRAWVIEW3D
, ICON_UNLOCKED
, 10,110,20,19, &(ob
->protectflag
), 0, 0, 0, 0, "Protects this value from being Transformed");
2358 uiDefButF(block
, NUM
, B_OBJECTPANEL
, "LocZ:", 30, 110, 120, 19, &(ob
->loc
[2]), -lim
, lim
, 100, 3, "");
2360 tfp
->ob_eul
[0]= 180.0*ob
->rot
[0]/M_PI
;
2361 tfp
->ob_eul
[1]= 180.0*ob
->rot
[1]/M_PI
;
2362 tfp
->ob_eul
[2]= 180.0*ob
->rot
[2]/M_PI
;
2364 uiBlockBeginAlign(block
);
2365 if ((ob
->parent
) && (ob
->partype
== PARBONE
)) {
2366 uiDefIconButBitS(block
, ICONTOG
, OB_LOCK_ROTX
, REDRAWVIEW3D
, ICON_UNLOCKED
, 160,130,20,19, &(ob
->protectflag
), 0, 0, 0, 0, "Protects this value from being Transformed");
2367 uiDefButF(block
, NUM
, B_OBJECTPANELROT
, "RotX:", 180, 130, 120, 19, &(tfp
->ob_eul
[0]), -lim
, lim
, 1000, 3, "");
2368 uiDefIconButBitS(block
, ICONTOG
, OB_LOCK_ROTY
, REDRAWVIEW3D
, ICON_UNLOCKED
, 160,110,20,19, &(ob
->protectflag
), 0, 0, 0, 0, "Protects this value from being Transformed");
2369 uiDefButF(block
, NUM
, B_OBJECTPANELROT
, "RotY:", 180, 110, 120, 19, &(tfp
->ob_eul
[1]), -lim
, lim
, 1000, 3, "");
2370 uiDefIconButBitS(block
, ICONTOG
, OB_LOCK_ROTZ
, REDRAWVIEW3D
, ICON_UNLOCKED
, 160,90,20,19, &(ob
->protectflag
), 0, 0, 0, 0, "Protects this value from being Transformed");
2371 uiDefButF(block
, NUM
, B_OBJECTPANELROT
, "RotZ:", 180, 90, 120, 19, &(tfp
->ob_eul
[2]), -lim
, lim
, 1000, 3, "");
2374 uiDefIconButBitS(block
, ICONTOG
, OB_LOCK_ROTX
, REDRAWVIEW3D
, ICON_UNLOCKED
, 160,150,20,19, &(ob
->protectflag
), 0, 0, 0, 0, "Protects this value from being Transformed");
2375 uiDefButF(block
, NUM
, B_OBJECTPANELROT
, "RotX:", 180, 150, 120, 19, &(tfp
->ob_eul
[0]), -lim
, lim
, 1000, 3, "");
2376 uiDefIconButBitS(block
, ICONTOG
, OB_LOCK_ROTY
, REDRAWVIEW3D
, ICON_UNLOCKED
, 160,130,20,19, &(ob
->protectflag
), 0, 0, 0, 0, "Protects this value from being Transformed");
2377 uiDefButF(block
, NUM
, B_OBJECTPANELROT
, "RotY:", 180, 130, 120, 19, &(tfp
->ob_eul
[1]), -lim
, lim
, 1000, 3, "");
2378 uiDefIconButBitS(block
, ICONTOG
, OB_LOCK_ROTZ
, REDRAWVIEW3D
, ICON_UNLOCKED
, 160,110,20,19, &(ob
->protectflag
), 0, 0, 0, 0, "Protects this value from being Transformed");
2379 uiDefButF(block
, NUM
, B_OBJECTPANELROT
, "RotZ:", 180, 110, 120, 19, &(tfp
->ob_eul
[2]), -lim
, lim
, 1000, 3, "");
2382 tfp
->ob_scale
[0]= ob
->size
[0];
2383 tfp
->ob_scale
[1]= ob
->size
[1];
2384 tfp
->ob_scale
[2]= ob
->size
[2];
2386 uiBlockBeginAlign(block
);
2387 uiDefIconButBitS(block
, ICONTOG
, OB_LOCK_SCALEX
, REDRAWVIEW3D
, ICON_UNLOCKED
, 10,80,20,19, &(ob
->protectflag
), 0, 0, 0, 0, "Protects this value from being Transformed");
2388 uiDefButF(block
, NUM
, B_OBJECTPANELSCALE
, "ScaleX:", 30, 80, 120, 19, &(tfp
->ob_scale
[0]), -lim
, lim
, 10, 3, "");
2389 uiDefIconButBitS(block
, ICONTOG
, OB_LOCK_SCALEY
, REDRAWVIEW3D
, ICON_UNLOCKED
, 10,60,20,19, &(ob
->protectflag
), 0, 0, 0, 0, "Protects this value from being Transformed");
2390 uiDefButF(block
, NUM
, B_OBJECTPANELSCALE
, "ScaleY:", 30, 60, 120, 19, &(tfp
->ob_scale
[1]), -lim
, lim
, 10, 3, "");
2391 uiDefIconButBitS(block
, ICONTOG
, OB_LOCK_SCALEZ
, REDRAWVIEW3D
, ICON_UNLOCKED
, 10,40,20,19, &(ob
->protectflag
), 0, 0, 0, 0, "Protects this value from being Transformed");
2392 uiDefButF(block
, NUM
, B_OBJECTPANELSCALE
, "ScaleZ:", 30, 40, 120, 19, &(tfp
->ob_scale
[2]), -lim
, lim
, 10, 3, "");
2393 uiBlockEndAlign(block
);
2395 uiDefButS(block
, TOG
, REDRAWVIEW3D
, "Link Scale", 10, 10, 140, 19, &(tfp
->link_scale
), 0, 1, 0, 0, "Scale values vary proportionally in all directions");
2396 uiDefButS(block
, TOG
, REDRAWVIEW3D
, "Hide Properties", 10, -15, 140, 19, &G
.prop_flag
, 0, 0, 0, 0, "Don't show transformation properties");
2398 bb
= object_get_boundbox(ob
);
2402 Mat4ToSize(ob
->obmat
, scale
);
2404 tfp
->ob_dims
[0] = fabs(scale
[0]) * (bb
->vec
[4][0] - bb
->vec
[0][0]);
2405 tfp
->ob_dims
[1] = fabs(scale
[1]) * (bb
->vec
[2][1] - bb
->vec
[0][1]);
2406 tfp
->ob_dims
[2] = fabs(scale
[2]) * (bb
->vec
[1][2] - bb
->vec
[0][2]);
2408 uiBlockBeginAlign(block
);
2409 if ((ob
->parent
) && (ob
->partype
== PARBONE
)) {
2410 uiDefButF(block
, NUM
, B_OBJECTPANELDIMS
, "DimX:", 160, 60, 140, 19, &(tfp
->ob_dims
[0]), 0.0, lim
, 10, 3, "Manipulate bounding box size");
2411 uiDefButF(block
, NUM
, B_OBJECTPANELDIMS
, "DimY:", 160, 40, 140, 19, &(tfp
->ob_dims
[1]), 0.0, lim
, 10, 3, "Manipulate bounding box size");
2412 uiDefButF(block
, NUM
, B_OBJECTPANELDIMS
, "DimZ:", 160, 20, 140, 19, &(tfp
->ob_dims
[2]), 0.0, lim
, 10, 3, "Manipulate bounding box size");
2416 uiDefButF(block
, NUM
, B_OBJECTPANELDIMS
, "DimX:", 160, 80, 140, 19, &(tfp
->ob_dims
[0]), 0.0, lim
, 10, 3, "Manipulate bounding box size");
2417 uiDefButF(block
, NUM
, B_OBJECTPANELDIMS
, "DimY:", 160, 60, 140, 19, &(tfp
->ob_dims
[1]), 0.0, lim
, 10, 3, "Manipulate bounding box size");
2418 uiDefButF(block
, NUM
, B_OBJECTPANELDIMS
, "DimZ:", 160, 40, 140, 19, &(tfp
->ob_dims
[2]), 0.0, lim
, 10, 3, "Manipulate bounding box size");
2421 uiBlockEndAlign(block
);
2426 uiDefButS(block
, TOG
, REDRAWVIEW3D
, "Show Properties", 10, 170, 140, 19, &G
.prop_flag
, 0, 1, 0, 0, "Show transformation Properties");
2428 if((ob
->type
!=OB_ARMATURE
) || (G
.f
& G_SCULPTMODE
)) {
2434 if(!(G
.prop_flag
& 1)) {
2435 uiDefBut(block
, LABEL
, 0, "Armature Layers:", 10, 150, 150, 19, 0, 0, 0, 0, 0, "");
2438 uiBlockBeginAlign (block
);
2439 for(a
= 0; a
<8; a
++) {
2440 bt
= uiDefButBitS(block
, BUT_TOGDUAL
, 1<<a
, REDRAWVIEW3D
, "", 10 + 19 * a
, 130, 19, 19, &arm
->layer
, 0, 0, 0, 0, "");
2441 uiButSetFunc(bt
, panel_armature_layer_cb
, &arm
->layer
, (void *)(1<<a
));
2444 uiBlockBeginAlign (block
);
2445 for (a
= 8; a
< 16; a
++) {
2446 bt
= uiDefButBitS (block
, BUT_TOGDUAL
, 1<<a
, REDRAWVIEW3D
, "", 10 + 19 * (a
-8), 110, 19, 19, &arm
->layer
, 0, 0, 0, 0, "");
2447 uiButSetFunc (bt
, panel_armature_layer_cb
, &arm
->layer
, (void *)(1<<a
));
2451 uiDefBut(block
, LABEL
, 0, "Armature Layers:", 10, -40, 150, 19, 0, 0, 0, 0, 0, "");
2454 uiBlockBeginAlign (block
);
2456 for(a
= 0; a
<8; a
++) {
2457 bt
= uiDefButBitS(block
, BUT_TOGDUAL
, 1<<a
, REDRAWVIEW3D
, "", 10 + 19 * a
, -60, 19, 19, &arm
->layer
, 0, 0, 0, 0, "");
2458 uiButSetFunc(bt
, panel_armature_layer_cb
, &arm
->layer
, (void *)(1<<a
));
2461 uiBlockBeginAlign (block
);
2462 for (a
= 8; a
< 16; a
++) {
2463 bt
= uiDefButBitS (block
, BUT_TOGDUAL
, 1<<a
, REDRAWVIEW3D
, "", 10 + 19 * (a
-8), -80, 19, 19, &arm
->layer
, 0, 0, 0, 0, "");
2464 uiButSetFunc (bt
, panel_armature_layer_cb
, &arm
->layer
, (void *)(1<<a
));
2468 /* quite bad here, but I don't know a better place for copy... */
2469 /* need here to!! */
2471 ob
->pose
->proxy_layer
= arm
->layer
;
2473 uiBlockEndAlign (block
);
2477 static void view3d_panel_background(short cntrl
) // VIEW3D_HANDLER_BACKGROUND
2484 block
= uiNewBlock(&curarea
->uiblocks
, "view3d_panel_background", UI_EMBOSS
, UI_HELV
, curarea
->win
);
2485 uiPanelControl(UI_PNL_SOLID
| UI_PNL_CLOSE
| cntrl
);
2486 uiSetPanelHandler(VIEW3D_HANDLER_BACKGROUND
); // for close and esc
2487 if(uiNewPanel(curarea
, block
, "Background Image", "View3d", 340, 10, 318, 204)==0) return;
2489 if(G
.f
& (G_VERTEXPAINT
|G_FACESELECT
|G_TEXTUREPAINT
|G_WEIGHTPAINT
)) {
2490 uiBlockSetFlag(block
, UI_BLOCK_FRONTBUFFER
); // force old style frontbuffer draw
2493 if(vd
->flag
& V3D_DISPBGPIC
) {
2494 if(vd
->bgpic
==NULL
) {
2495 vd
->bgpic
= MEM_callocN(sizeof(BGpic
), "bgpic");
2496 vd
->bgpic
->size
= 5.0;
2497 vd
->bgpic
->blend
= 0.5;
2498 vd
->bgpic
->iuser
.fie_ima
= 2;
2499 vd
->bgpic
->iuser
.ok
= 1;
2503 if(!(vd
->flag
& V3D_DISPBGPIC
)) {
2504 uiDefButBitS(block
, TOG
, V3D_DISPBGPIC
, B_REDR
, "Use Background Image", 10, 180, 150, 20, &vd
->flag
, 0, 0, 0, 0, "Display an image in the background of the 3D View");
2505 uiDefBut(block
, LABEL
, 1, " ", 160, 180, 150, 20, NULL
, 0.0, 0.0, 0, 0, "");
2508 uiBlockBeginAlign(block
);
2509 uiDefButBitS(block
, TOG
, V3D_DISPBGPIC
, B_REDR
, "Use", 10, 225, 50, 20, &vd
->flag
, 0, 0, 0, 0, "Display an image in the background of the 3D View");
2510 uiDefButF(block
, NUMSLI
, B_REDR
, "Blend:", 60, 225, 150, 20, &vd
->bgpic
->blend
, 0.0,1.0, 0, 0, "Set the transparency of the background image");
2511 uiDefButF(block
, NUM
, B_REDR
, "Size:", 210, 225, 100, 20, &vd
->bgpic
->size
, 0.1, 250.0*vd
->grid
, 100, 0, "Set the size (width) of the background image");
2513 uiDefButF(block
, NUM
, B_REDR
, "X Offset:", 10, 205, 150, 20, &vd
->bgpic
->xof
, -250.0*vd
->grid
,250.0*vd
->grid
, 10, 2, "Set the horizontal offset of the background image");
2514 uiDefButF(block
, NUM
, B_REDR
, "Y Offset:", 160, 205, 150, 20, &vd
->bgpic
->yof
, -250.0*vd
->grid
,250.0*vd
->grid
, 10, 2, "Set the vertical offset of the background image");
2516 uiblock_image_panel(block
, &vd
->bgpic
->ima
, &vd
->bgpic
->iuser
, B_REDR
, B_REDR
);
2521 static void view3d_panel_properties(short cntrl
) // VIEW3D_HANDLER_SETTINGS
2529 block
= uiNewBlock(&curarea
->uiblocks
, "view3d_panel_properties", UI_EMBOSS
, UI_HELV
, curarea
->win
);
2530 uiPanelControl(UI_PNL_SOLID
| UI_PNL_CLOSE
| cntrl
);
2531 uiSetPanelHandler(VIEW3D_HANDLER_PROPERTIES
); // for close and esc
2532 if(uiNewPanel(curarea
, block
, "View Properties", "View3d", 340, 30, 318, 254)==0) return;
2534 /* to force height */
2535 uiNewPanelHeight(block
, 264);
2537 if(G
.f
& (G_VERTEXPAINT
|G_FACESELECT
|G_TEXTUREPAINT
|G_WEIGHTPAINT
)) {
2538 uiBlockSetFlag(block
, UI_BLOCK_FRONTBUFFER
); // force old style frontbuffer draw
2541 uiDefBut(block
, LABEL
, 1, "Grid:", 10, 220, 150, 19, NULL
, 0.0, 0.0, 0, 0, "");
2542 uiBlockBeginAlign(block
);
2543 uiDefButF(block
, NUM
, REDRAWVIEW3D
, "Spacing:", 10, 200, 140, 19, &vd
->grid
, 0.001, 100.0, 10, 0, "Set the distance between grid lines");
2544 uiDefButS(block
, NUM
, REDRAWVIEW3D
, "Lines:", 10, 180, 140, 19, &vd
->gridlines
, 0.0, 100.0, 100, 0, "Set the number of grid lines");
2545 uiDefButS(block
, NUM
, REDRAWVIEW3D
, "Divisions:", 10, 160, 140, 19, &vd
->gridsubdiv
, 0.0, 100.0, 100, 0, "Set the number of grid lines");
2546 uiBlockEndAlign(block
);
2548 uiDefBut(block
, LABEL
, 1, "3D Display:", 160, 220, 150, 19, NULL
, 0.0, 0.0, 0, 0, "");
2549 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");
2550 uiDefButBitS(block
, TOG
, V3D_SHOW_X
, REDRAWVIEW3D
, "X Axis", 160, 180, 48, 19, &vd
->gridflag
, 0, 0, 0, 0, "Show the X Axis line");
2551 uiDefButBitS(block
, TOG
, V3D_SHOW_Y
, REDRAWVIEW3D
, "Y Axis", 212, 180, 48, 19, &vd
->gridflag
, 0, 0, 0, 0, "Show the Y Axis line");
2552 uiDefButBitS(block
, TOG
, V3D_SHOW_Z
, REDRAWVIEW3D
, "Z Axis", 262, 180, 48, 19, &vd
->gridflag
, 0, 0, 0, 0, "Show the Z Axis line");
2553 if(vd
->gridflag
& V3D_USE_F_FOR_FLY
)
2554 uiDefButBitS(block
, TOG
, V3D_USE_F_FOR_FLY
, REDRAWVIEW3D
, "Use shift+F for Fly", 160, 160, 150, 19, &vd
->gridflag
, 0, 0, 0, 0, "Use shift+F for enter to fly mode");
2556 uiDefButBitS(block
, TOG
, V3D_USE_F_FOR_FLY
, REDRAWVIEW3D
, "Use F for Fly", 160, 160, 150, 19, &vd
->gridflag
, 0, 0, 0, 0, "Use F for enter to fly mode");
2557 uiDefBut(block
, LABEL
, 1, "View Camera:", 10, 140, 140, 19, NULL
, 0.0, 0.0, 0, 0, "");
2559 uiDefButF(block
, NUM
, REDRAWVIEW3D
, "Lens:", 10, 120, 140, 19, &vd
->lens
, 10.0, 120.0, 100, 0, "The lens angle in perspective view");
2560 uiBlockBeginAlign(block
);
2561 uiDefButF(block
, NUM
, REDRAWVIEW3D
, "Clip Start:", 10, 101, 140, 19, &vd
->near
, vd
->grid
/100.0, 100.0, 10, 0, "Set the beginning of the range in which 3D objects are displayed (perspective view)");
2562 uiDefButF(block
, NUM
, REDRAWVIEW3D
, "Clip End:", 10, 82, 140, 19, &vd
->far
, 1.0, 10000.0*vd
->grid
, 100, 0, "Set the end of the range in which 3D objects are displayed (perspective view)");
2563 uiDefButS(block
, TOG
, 1, "Show Camera Name", 10, 56, 140, 19, &G
.show_cam
, 0, 1, 0, 1, "Show the name of the active camera");
2564 uiBlockEndAlign(block
);
2566 uiDefBut(block
, LABEL
, 1, "3D Cursor:", 160, 140, 140, 19, NULL
, 0.0, 0.0, 0, 0, "");
2568 uiBlockBeginAlign(block
);
2569 curs
= give_cursor();
2570 uiDefButF(block
, NUM
, REDRAWVIEW3D
, "X:", 160, 120, 150, 19, curs
, -10000.0*vd
->grid
, 10000.0*vd
->grid
, 10, 0, "X co-ordinate of the 3D cursor");
2571 uiDefButF(block
, NUM
, REDRAWVIEW3D
, "Y:", 160, 101, 150, 19, curs
+1, -10000.0*vd
->grid
, 10000.0*vd
->grid
, 10, 0, "Y co-ordinate of the 3D cursor");
2572 uiDefButF(block
, NUM
, REDRAWVIEW3D
, "Z:", 160, 82, 150, 19, curs
+2, -10000.0*vd
->grid
, 10000.0*vd
->grid
, 10, 0, "Z co-ordinate of the 3D cursor");
2573 uiBlockEndAlign(block
);
2575 uiDefBut(block
, LABEL
, 1, "Display:", 10, 30, 150, 19, NULL
, 0.0, 0.0, 0, 0, "");
2577 uiBlockBeginAlign(block
);
2578 uiDefButBitS(block
, TOG
, V3D_SELECT_OUTLINE
, REDRAWVIEW3D
, "Outline Selected", 10, 10, 140, 19, &vd
->flag
, 0, 0, 0, 0, "Highlight selected objects with an outline, in Solid, Shaded or Textured viewport shading modes");
2579 uiDefButBitS(block
, TOG
, V3D_DRAW_CENTERS
, REDRAWVIEW3D
, "All Object Centers", 10, -10, 140, 19, &vd
->flag
, 0, 0, 0, 0, "Draw the center points on all objects");
2580 uiDefButBitS(block
, TOGN
, V3D_HIDE_HELPLINES
, REDRAWVIEW3D
, "Relationship Lines", 10, -30, 140, 19, &vd
->flag
, 0, 0, 0, 0, "Draw dashed lines indicating Parent, Constraint, or Hook relationships");
2581 uiBlockEndAlign(block
);
2583 uiDefBut(block
, LABEL
, 1, "View Locking:", 160, 50, 150, 19, NULL
, 0.0, 0.0, 0, 0, "");
2584 uiBlockBeginAlign(block
);
2585 uiDefIDPoinBut(block
, test_obpoin_but
, ID_OB
, REDRAWVIEW3D
, "Object:", 160, 30, 140, 19, &vd
->ob_centre
, "Lock view to center always on this Object");
2586 uiDefBut(block
, TEX
, REDRAWVIEW3D
, "Bone:", 160, 10, 140, 19, vd
->ob_centre_bone
, 1, 31, 0, 0, "If view locked to Object, use this Bone to lock to view to");
2590 static void view3d_panel_preview(ScrArea
*sa
, short cntrl
) // VIEW3D_HANDLER_PREVIEW
2593 View3D
*v3d
= sa
->spacedata
.first
;
2596 block
= uiNewBlock(&sa
->uiblocks
, "view3d_panel_preview", UI_EMBOSS
, UI_HELV
, sa
->win
);
2597 uiPanelControl(UI_PNL_SOLID
| UI_PNL_CLOSE
| UI_PNL_SCALE
| cntrl
);
2598 uiSetPanelHandler(VIEW3D_HANDLER_PREVIEW
); // for close and esc
2600 ofsx
= -150+(sa
->winx
/2)/v3d
->blockscale
;
2601 ofsy
= -100+(sa
->winy
/2)/v3d
->blockscale
;
2602 if(uiNewPanel(sa
, block
, "Preview", "View3d", ofsx
, ofsy
, 300, 200)==0) return;
2604 uiBlockSetDrawExtraFunc(block
, BIF_view3d_previewdraw
);
2606 if(G
.scene
->recalc
& SCE_PRV_CHANGED
) {
2607 G
.scene
->recalc
&= ~SCE_PRV_CHANGED
;
2608 //printf("found recalc\n");
2609 BIF_view3d_previewrender_free(sa
->spacedata
.first
);
2610 BIF_preview_changed(0);
2615 static void view3d_blockhandlers(ScrArea
*sa
)
2617 View3D
*v3d
= sa
->spacedata
.first
;
2620 /* warning; blocks need to be freed each time, handlers dont remove */
2621 uiFreeBlocksWin(&sa
->uiblocks
, sa
->win
);
2623 /*uv face-sel and wp mode when mixed with wire leave depth enabled causing
2624 models to draw over the UI */
2625 glDisable(GL_DEPTH_TEST
);
2627 for(a
=0; a
<SPACE_MAXHANDLER
; a
+=2) {
2629 switch(v3d
->blockhandler
[a
]) {
2631 case VIEW3D_HANDLER_PROPERTIES
:
2632 view3d_panel_properties(v3d
->blockhandler
[a
+1]);
2634 case VIEW3D_HANDLER_BACKGROUND
:
2635 view3d_panel_background(v3d
->blockhandler
[a
+1]);
2637 case VIEW3D_HANDLER_OBJECT
:
2638 view3d_panel_object(v3d
->blockhandler
[a
+1]);
2640 case VIEW3D_HANDLER_PREVIEW
:
2641 view3d_panel_preview(sa
, v3d
->blockhandler
[a
+1]);
2644 /* clear action value for event */
2645 v3d
->blockhandler
[a
+1]= 0;
2647 uiDrawBlocksPanels(sa
, 0);
2651 /* ****************** View3d afterdraw *************** */
2653 typedef struct View3DAfter
{
2654 struct View3DAfter
*next
, *prev
;
2659 /* temp storage of Objects that need to be drawn as last */
2660 void add_view3d_after(View3D
*v3d
, Base
*base
, int type
)
2662 View3DAfter
*v3da
= MEM_callocN(sizeof(View3DAfter
), "View 3d after");
2664 BLI_addtail(&v3d
->afterdraw
, v3da
);
2669 /* clears zbuffer and draws it over */
2670 static void view3d_draw_xray(View3D
*v3d
, int flag
)
2672 View3DAfter
*v3da
, *next
;
2675 for(v3da
= v3d
->afterdraw
.first
; v3da
; v3da
= v3da
->next
)
2676 if(v3da
->type
==V3D_XRAY
) doit
= 1;
2679 if(v3d
->zbuf
) glClear(GL_DEPTH_BUFFER_BIT
);
2682 for(v3da
= v3d
->afterdraw
.first
; v3da
; v3da
= next
) {
2684 if(v3da
->type
==V3D_XRAY
) {
2685 draw_object(v3da
->base
, flag
);
2686 BLI_remlink(&v3d
->afterdraw
, v3da
);
2694 /* disables write in zbuffer and draws it over */
2695 static void view3d_draw_transp(View3D
*v3d
, int flag
)
2697 View3DAfter
*v3da
, *next
;
2702 for(v3da
= v3d
->afterdraw
.first
; v3da
; v3da
= next
) {
2704 if(v3da
->type
==V3D_TRANSP
) {
2705 draw_object(v3da
->base
, flag
);
2706 BLI_remlink(&v3d
->afterdraw
, v3da
);
2716 /* *********************** */
2719 In most cases call draw_dupli_objects,
2720 draw_dupli_objects_color was added because when drawing set dupli's
2721 we need to force the color
2723 static void draw_dupli_objects_color(View3D
*v3d
, Base
*base
, int color
)
2730 short transflag
, use_displist
= -1; /* -1 is initialize */
2733 if (base
->object
->restrictflag
& OB_RESTRICT_VIEW
) return;
2735 /* test if we can do a displist */
2736 if(base
->object
->transflag
& OB_DUPLIGROUP
)
2739 tbase
.flag
= OB_FROMDUPLI
|base
->flag
;
2740 lb
= object_duplilist(G
.scene
, base
->object
);
2742 for(dob
= lb
->first
; dob
; dob
= dob
->next
) {
2745 tbase
.object
= dob
->ob
;
2747 /* extra service: draw the duplicator in drawtype of parent */
2748 dt
= tbase
.object
->dt
; tbase
.object
->dt
= base
->object
->dt
;
2749 dtx
= tbase
.object
->dtx
; tbase
.object
->dtx
= base
->object
->dtx
;
2751 /* negative scale flag has to propagate */
2752 transflag
= tbase
.object
->transflag
;
2753 if(base
->object
->transflag
& OB_NEG_SCALE
)
2754 tbase
.object
->transflag
^= OB_NEG_SCALE
;
2756 BIF_ThemeColorBlend(color
, TH_BACK
, 0.5);
2758 /* generate displist, test for new object */
2759 if(use_displist
==1 && dob
->prev
&& dob
->prev
->ob
!=dob
->ob
) {
2761 glDeleteLists(displist
, 1);
2763 /* generate displist */
2764 if(use_displist
== -1) {
2766 /* lamp drawing messes with matrices, could be handled smarter... but this works */
2767 if(dob
->ob
->type
==OB_LAMP
)
2770 /* disable boundbox check for list creation */
2771 object_boundbox_flag(dob
->ob
, OB_BB_DISABLED
, 1);
2772 /* need this for next part of code */
2773 bb
= object_get_boundbox(dob
->ob
);
2775 Mat4One(dob
->ob
->obmat
); /* obmat gets restored */
2777 displist
= glGenLists(1);
2778 glNewList(displist
, GL_COMPILE
);
2779 draw_object(&tbase
, DRAW_CONSTCOLOR
);
2783 object_boundbox_flag(dob
->ob
, OB_BB_DISABLED
, 0);
2787 mymultmatrix(dob
->mat
);
2788 if(boundbox_clip(dob
->mat
, bb
))
2789 glCallList(displist
);
2790 myloadmatrix(G
.vd
->viewmat
);
2793 Mat4CpyMat4(dob
->ob
->obmat
, dob
->mat
);
2794 draw_object(&tbase
, DRAW_CONSTCOLOR
);
2797 tbase
.object
->dt
= dt
;
2798 tbase
.object
->dtx
= dtx
;
2799 tbase
.object
->transflag
= transflag
;
2803 /* Transp afterdraw disabled, afterdraw only stores base pointers, and duplis can be same obj */
2805 free_object_duplilist(lb
); /* does restore */
2808 glDeleteLists(displist
, 1);
2811 static void draw_dupli_objects(View3D
*v3d
, Base
*base
)
2813 /* define the color here so draw_dupli_objects_color can be called
2814 * from the set loop */
2816 int color
= (base
->flag
& SELECT
)?TH_SELECT
:TH_WIRE
;
2818 if(base
->object
->dup_group
&& base
->object
->dup_group
->id
.us
<1)
2821 draw_dupli_objects_color(v3d
, base
, color
);
2824 void view3d_update_depths(View3D
*v3d
)
2826 /* Create storage for, and, if necessary, copy depth buffer */
2827 if(!v3d
->depths
) v3d
->depths
= MEM_callocN(sizeof(ViewDepths
),"ViewDepths");
2829 ViewDepths
*d
= v3d
->depths
;
2830 if(d
->w
!= v3d
->area
->winx
||
2831 d
->h
!= v3d
->area
->winy
||
2833 d
->w
= v3d
->area
->winx
;
2834 d
->h
= v3d
->area
->winy
;
2836 MEM_freeN(d
->depths
);
2837 d
->depths
= MEM_mallocN(sizeof(float)*d
->w
*d
->h
,"View depths");
2842 glReadPixels(v3d
->area
->winrct
.xmin
,v3d
->area
->winrct
.ymin
,d
->w
,d
->h
,
2843 GL_DEPTH_COMPONENT
,GL_FLOAT
, d
->depths
);
2845 glGetDoublev(GL_DEPTH_RANGE
,d
->depth_range
);
2852 void drawview3dspace(ScrArea
*sa
, void *spacedata
)
2854 View3D
*v3d
= spacedata
;
2858 char retopo
, sculpt
;
2859 Object
*obact
= OBACT
;
2861 /* update all objects, ipos, matrices, displists, etc. Flags set by depgraph or manual,
2862 no layer check here, gets correct flushed */
2863 /* sets first, we allow per definition current scene to have dependencies on sets */
2865 for(SETLOOPER(G
.scene
->set
, base
))
2866 object_handle_update(base
->object
); // bke_object.h
2868 for(base
= G
.scene
->base
.first
; base
; base
= base
->next
)
2869 object_handle_update(base
->object
); // bke_object.h
2871 setwinmatrixview3d(sa
->winx
, sa
->winy
, NULL
); /* 0= no pick rect */
2872 setviewmatrixview3d(); /* note: calls where_is_object for camera... */
2874 Mat4MulMat4(v3d
->persmat
, v3d
->viewmat
, sa
->winmat
);
2875 Mat4Invert(v3d
->persinv
, v3d
->persmat
);
2876 Mat4Invert(v3d
->viewinv
, v3d
->viewmat
);
2878 /* calculate pixelsize factor once, is used for lamps and obcenters */
2880 float len1
, len2
, vec
[3];
2882 VECCOPY(vec
, v3d
->persinv
[0]);
2883 len1
= Normalize(vec
);
2884 VECCOPY(vec
, v3d
->persinv
[1]);
2885 len2
= Normalize(vec
);
2887 v3d
->pixsize
= 2.0f
*(len1
>len2
?len1
:len2
);
2889 /* correct for window size */
2890 if(sa
->winx
> sa
->winy
) v3d
->pixsize
/= (float)sa
->winx
;
2891 else v3d
->pixsize
/= (float)sa
->winy
;
2894 if(v3d
->drawtype
> OB_WIRE
) {
2895 if(G
.f
& G_SIMULATION
)
2896 glClearColor(0.0, 0.0, 0.0, 0.0);
2899 BIF_GetThemeColor3fv(TH_BACK
, col
);
2900 glClearColor(col
[0], col
[1], col
[2], 0.0);
2902 glClear(GL_COLOR_BUFFER_BIT
| GL_DEPTH_BUFFER_BIT
);
2908 BIF_GetThemeColor3fv(TH_BACK
, col
);
2909 glClearColor(col
[0], col
[1], col
[2], 0.0);
2910 glClear(GL_COLOR_BUFFER_BIT
);
2913 myloadmatrix(v3d
->viewmat
);
2914 persp(PERSP_STORE
); // store correct view for persp(PERSP_VIEW) calls
2916 if(v3d
->flag
& V3D_CLIPPING
)
2917 view3d_draw_clipping(v3d
);
2919 /* set zbuffer after we draw clipping region */
2920 if(v3d
->drawtype
> OB_WIRE
) {
2922 glEnable(GL_DEPTH_TEST
);
2925 // needs to be done always, gridview is adjusted in drawgrid() now
2926 v3d
->gridview
= v3d
->grid
;
2928 if(v3d
->view
==0 || v3d
->persp
!=0) {
2931 if(G
.scene
->world
) {
2932 if(G
.scene
->world
->mode
& WO_STARS
) {
2933 RE_make_stars(NULL
, star_stuff_init_func
, star_stuff_vertex_func
,
2934 star_stuff_term_func
);
2937 if(v3d
->flag
& V3D_DISPBGPIC
) draw_bgpic();
2943 if(v3d
->flag
& V3D_DISPBGPIC
) {
2948 if(v3d
->flag
& V3D_CLIPPING
)
2949 view3d_set_clipping(v3d
);
2951 /* draw set first */
2953 for(SETLOOPER(G
.scene
->set
, base
)) {
2955 if(v3d
->lay
& base
->lay
) {
2957 BIF_ThemeColorBlend(TH_WIRE
, TH_BACK
, 0.6f
);
2958 draw_object(base
, DRAW_CONSTCOLOR
);
2960 if(base
->object
->transflag
& OB_DUPLI
) {
2961 draw_dupli_objects_color(v3d
, base
, TH_WIRE
);
2966 /* Transp and X-ray afterdraw stuff */
2967 view3d_draw_xray(v3d
, DRAW_CONSTCOLOR
); // clears zbuffer if it is used!
2968 view3d_draw_transp(v3d
, DRAW_CONSTCOLOR
);
2971 /* then draw not selected and the duplis, but skip editmode object */
2972 for(base
= G
.scene
->base
.first
; base
; base
= base
->next
) {
2973 if(v3d
->lay
& base
->lay
) {
2976 if(base
->object
->transflag
& OB_DUPLI
) {
2977 draw_dupli_objects(v3d
, base
);
2979 if((base
->flag
& SELECT
)==0) {
2980 if(base
->object
!=G
.obedit
) draw_object(base
, 0);
2985 retopo
= retopo_mesh_check() || retopo_curve_check();
2986 sculpt
= (G
.f
& G_SCULPTMODE
) && !G
.obedit
;
2988 view3d_update_depths(v3d
);
2990 /* draw selected and editmode */
2991 for(base
= G
.scene
->base
.first
; base
; base
= base
->next
) {
2992 if(v3d
->lay
& base
->lay
) {
2993 if (base
->object
==G
.obedit
|| ( base
->flag
& SELECT
) )
2994 draw_object(base
, 0);
2998 if(!retopo
&& sculpt
&& !(obact
&& (obact
->dtx
& OB_DRAWXRAY
)))
2999 view3d_update_depths(v3d
);
3002 BIF_drawConstraint();
3003 if(G
.obedit
) BIF_drawPropCircle(); // only editmode has proportional edit
3007 if(G
.scene
->radio
) RAD_drawall(v3d
->drawtype
>=OB_SOLID
);
3009 /* Transp and X-ray afterdraw stuff */
3010 view3d_draw_xray(v3d
, 0); // clears zbuffer if it is used!
3011 view3d_draw_transp(v3d
, 0);
3013 if(!retopo
&& sculpt
&& (obact
&& (OBACT
->dtx
& OB_DRAWXRAY
)))
3014 view3d_update_depths(v3d
);
3016 if(v3d
->flag
& V3D_CLIPPING
)
3017 view3d_clr_clipping();
3019 BIF_draw_manipulator(sa
);
3023 glDisable(GL_DEPTH_TEST
);
3026 persp(PERSP_WIN
); // set ortho
3028 /* Draw Sculpt Mode brush */
3029 if(!G
.obedit
&& (G
.f
& G_SCULPTMODE
) && area_is_active_area(v3d
->area
) && sculpt_session()) {
3030 PropsetData
*pd
= sculpt_session()->propset
;
3031 short r1
=100, r2
=100, r3
=100;
3034 if(pd
->mode
== PropsetSize
) {
3035 r1
= sculptmode_brush()->size
;
3038 } else if(pd
->mode
== PropsetStrength
) {
3039 r1
= 200 - sculptmode_brush()->strength
* 2;
3042 } else if(pd
->mode
== PropsetTexRot
) {
3047 /* Draw brush with texture */
3049 glBlendFunc(GL_SRC_ALPHA
, GL_ONE_MINUS_SRC_ALPHA
);
3051 glBindTexture(GL_TEXTURE_2D
, pd
->tex
);
3053 glTexParameterf(GL_TEXTURE_2D
, GL_TEXTURE_MIN_FILTER
, GL_LINEAR
);
3054 glTexParameterf(GL_TEXTURE_2D
, GL_TEXTURE_MAG_FILTER
, GL_LINEAR
);
3057 glTranslatef(pd
->origloc
[0], pd
->origloc
[1], 0);
3058 glRotatef(tex_angle(), 0, 0, 1);
3060 glEnable(GL_TEXTURE_2D
);
3064 glVertex2f(-r3
, -r3
);
3066 glVertex2f(r3
, -r3
);
3070 glVertex2f(-r3
, r3
);
3072 glDisable(GL_TEXTURE_2D
);
3077 fdrawXORcirc(pd
->origloc
[0], pd
->origloc
[1], r1
);
3078 fdrawXORcirc(pd
->origloc
[0], pd
->origloc
[1], r2
);
3080 if(pd
->mode
== PropsetTexRot
) {
3081 const float ang
= pd
->origtexrot
* (M_PI
/180.0f
);
3082 getmouseco_areawin(mouse
);
3083 sdrawXORline(pd
->origloc
[0], pd
->origloc
[1],
3084 pd
->origloc
[0]+200*cos(ang
), pd
->origloc
[1]+200*sin(ang
));
3085 sdrawXORline(pd
->origloc
[0], pd
->origloc
[1], mouse
[0], mouse
[1]);
3088 else if(sculpt_data()->draw_flag
& SCULPTDRAW_BRUSH
) {
3089 short csc
[2], car
[2];
3091 getmouseco_areawin(car
);
3092 if(csc
[0] > v3d
->area
->winrct
.xmin
&&
3093 csc
[1] > v3d
->area
->winrct
.ymin
&&
3094 csc
[0] < v3d
->area
->winrct
.xmax
&&
3095 csc
[1] < v3d
->area
->winrct
.ymax
)
3096 fdrawXORcirc((float)car
[0], (float)car
[1], sculptmode_brush()->size
);
3099 retopo_draw_paint_lines();
3101 if(v3d
->persp
>1) drawviewborder();
3102 if(v3d
->flag2
& V3D_FLYMODE
) drawviewborder_flymode();
3103 if(!(G
.f
& G_PLAYANIM
)) drawcursor(v3d
);
3104 if(U
.uiflag
& USER_SHOW_ROTVIEWICON
)
3108 if(U
.uiflag
& USER_SHOW_VIEWPORTNAME
)
3109 draw_viewport_name(sa
);
3112 if(ob
&& (U
.uiflag
& USER_DRAWVIEWINFO
))
3113 draw_selected_name(ob
);
3115 draw_area_emboss(sa
);
3117 /* it is important to end a view in a transform compatible with buttons */
3119 bwin_scalematrix(sa
->win
, v3d
->blockscale
, v3d
->blockscale
, v3d
->blockscale
);
3120 view3d_blockhandlers(sa
);
3122 sa
->win_swap
= WIN_BACK_OK
;
3124 if(G
.f
& (G_VERTEXPAINT
|G_FACESELECT
|G_TEXTUREPAINT
|G_WEIGHTPAINT
)) {
3125 v3d
->flag
|= V3D_NEEDBACKBUFDRAW
;
3126 addafterqueue(sa
->win
, BACKBUFDRAW
, 1);
3128 // test for backbuf select
3129 if(G
.obedit
&& v3d
->drawtype
>OB_WIRE
&& (v3d
->flag
& V3D_ZBUF_SELECT
)) {
3130 extern int afterqtest(short win
, unsigned short evt
); //editscreen.c
3132 v3d
->flag
|= V3D_NEEDBACKBUFDRAW
;
3133 if(afterqtest(sa
->win
, BACKBUFDRAW
)==0) {
3134 addafterqueue(sa
->win
, BACKBUFDRAW
, 1);
3138 /* run any view3d draw handler script links */
3139 if (sa
->scriptlink
.totscript
)
3140 BPY_do_spacehandlers(sa
, 0, SPACEHANDLER_VIEW3D_DRAW
);
3142 /* run scene redraw script links */
3143 if((G
.f
& G_DOSCRIPTLINKS
) && G
.scene
->scriptlink
.totscript
&&
3145 BPY_do_pyscript((ID
*)G
.scene
, SCRIPT_REDRAW
);
3151 void drawview3d_render(struct View3D
*v3d
, int winx
, int winy
, float winmat
[][4])
3155 float v3dwinmat
[4][4];
3157 setviewmatrixview3d();
3158 myloadmatrix(v3d
->viewmat
);
3160 /* when winmat is not NULL, it overrides the regular window matrix */
3161 glMatrixMode(GL_PROJECTION
);
3163 myloadmatrix(winmat
);
3165 setwinmatrixview3d(winx
, winy
, NULL
);
3166 mygetmatrix(v3dwinmat
);
3167 glMatrixMode(GL_MODELVIEW
);
3169 Mat4MulMat4(v3d
->persmat
, v3d
->viewmat
, v3dwinmat
);
3170 Mat4Invert(v3d
->persinv
, v3d
->persmat
);
3171 Mat4Invert(v3d
->viewinv
, v3d
->viewmat
);
3173 free_all_realtime_images();
3174 reshadeall_displist();
3176 if(v3d
->drawtype
> OB_WIRE
) {
3178 glEnable(GL_DEPTH_TEST
);
3181 if(v3d
->flag
& V3D_CLIPPING
)
3182 view3d_set_clipping(v3d
);
3184 if (v3d
->drawtype
==OB_TEXTURE
&& G
.scene
->world
) {
3185 glClearColor(G
.scene
->world
->horr
, G
.scene
->world
->horg
, G
.scene
->world
->horb
, 0.0);
3188 BIF_GetThemeColor3fv(TH_BACK
, col
);
3189 glClearColor(col
[0], col
[1], col
[2], 0.0);
3191 glClear(GL_COLOR_BUFFER_BIT
| GL_DEPTH_BUFFER_BIT
);
3193 /* abuse! to make sure it doesnt draw the helpstuff */
3194 G
.f
|= G_SIMULATION
;
3196 /* first draw set */
3199 for(SETLOOPER(G
.scene
->set
, base
)) {
3200 if(v3d
->lay
& base
->lay
) {
3201 if ELEM3(base
->object
->type
, OB_LAMP
, OB_CAMERA
, OB_LATTICE
);
3203 where_is_object(base
->object
);
3205 BIF_ThemeColorBlend(TH_WIRE
, TH_BACK
, 0.6f
);
3206 draw_object(base
, DRAW_CONSTCOLOR
);
3208 if(base
->object
->transflag
& OB_DUPLI
) {
3209 draw_dupli_objects(v3d
, base
);
3215 /* Transp and X-ray afterdraw stuff */
3216 view3d_draw_xray(v3d
, DRAW_CONSTCOLOR
); // clears zbuffer if it is used!
3217 view3d_draw_transp(v3d
, DRAW_CONSTCOLOR
);
3220 /* first not selected and duplis */
3221 base
= G
.scene
->base
.first
;
3224 if(v3d
->lay
& base
->lay
) {
3225 if ELEM3(base
->object
->type
, OB_LAMP
, OB_CAMERA
, OB_LATTICE
);
3228 if(base
->object
->transflag
& OB_DUPLI
) {
3229 draw_dupli_objects(v3d
, base
);
3231 else if((base
->flag
& SELECT
)==0) {
3232 draw_object(base
, 0);
3241 base
= G
.scene
->base
.first
;
3244 if ( ((base
)->flag
& SELECT
) && ((base
)->lay
& v3d
->lay
) ) {
3245 if ELEM3(base
->object
->type
, OB_LAMP
, OB_CAMERA
, OB_LATTICE
);
3246 else draw_object(base
, 0);
3252 if(G
.scene
->radio
) RAD_drawall(v3d
->drawtype
>=OB_SOLID
);
3254 /* Transp and X-ray afterdraw stuff */
3255 view3d_draw_xray(v3d
, 0); // clears zbuffer if it is used!
3256 view3d_draw_transp(v3d
, 0);
3258 if(v3d
->flag
& V3D_CLIPPING
)
3259 view3d_clr_clipping();
3263 glDisable(GL_DEPTH_TEST
);
3266 G
.f
&= ~G_SIMULATION
;
3272 free_all_realtime_images();
3276 double tottime
= 0.0;
3278 int update_time(void)
3280 static double ltime
;
3283 if ((audiostream_pos() != CFRA
)
3284 && (G
.scene
->audio
.flag
& AUDIO_SYNC
)) {
3288 time
= PIL_check_seconds_timer();
3290 tottime
+= (time
- ltime
);
3292 return (tottime
< 0.0);
3295 void inner_play_anim_loop(int init
, int mode
)
3298 static ScrArea
*oldsa
;
3299 static double swaptime
;
3312 set_timecursor(CFRA
);
3314 update_for_newframe_nodraw(1); /* adds no events in UI */
3316 sa
= G
.curscreen
->areabase
.first
;
3319 scrarea_do_windraw(sa
);
3321 else if(curmode
& 1) { /* all view3d and seq spaces */
3322 if ELEM(sa
->spacetype
, SPACE_VIEW3D
, SPACE_SEQ
) {
3323 scrarea_do_windraw(sa
);
3326 else if(curmode
& 4) { /* all seq spaces */
3327 if (sa
->spacetype
== SPACE_SEQ
) {
3328 scrarea_do_windraw(sa
);
3335 /* make sure that swaptime passed by */
3336 tottime
-= swaptime
;
3337 while (update_time()) PIL_sleep_ms(1);
3340 if (tottime
> 0.0) tottime
= 0.0;
3343 audiostream_start( CFRA
);
3346 if (U
.mixbufsize
&& (G
.scene
->audio
.flag
& AUDIO_SYNC
)) CFRA
= audiostream_pos();
3351 /* play_anim: 'mode' defines where to play and if repeat is on (now bitfield):
3352 * - mode & 1 : All view3d and seq areas
3353 * - mode & 2 : No replay
3354 * - mode & 4 : All seq areas
3356 int play_anim(int mode
)
3358 ScrArea
*sa
, *oldsa
;
3360 unsigned short event
=0;
3363 /* patch for very very old scenes */
3364 if(SFRA
==0) SFRA
= 1;
3365 if(EFRA
==0) EFRA
= 250;
3367 if(PSFRA
>PEFRA
) return 0;
3371 /* waitcursor(1); */
3372 G
.f
|= G_PLAYANIM
; /* in sequence.c and view.c this is handled */
3377 audiostream_start( CFRA
);
3379 if (curarea
&& curarea
->spacetype
== SPACE_SEQ
) {
3380 SpaceSeq
*sseq
= curarea
->spacedata
.first
;
3381 if (sseq
->mainb
== 0) mode
|= 4;
3384 inner_play_anim_loop(1, mode
); /* 1==init */
3386 /* forces all buffers to be OK for current frame (otherwise other windows get redrawn with CFRA+1) */
3387 curarea
->win_swap
= WIN_BACK_OK
;
3388 screen_swapbuffers();
3394 /* we test events first because of MKEY event */
3396 event
= extern_qread(&val
);
3397 if(event
==ESCKEY
) break;
3398 else if(event
==MIDDLEMOUSE
) {
3399 if(U
.flag
& USER_VIEWMOVE
) {
3400 if(G
.qual
& LR_SHIFTKEY
) viewmove(0);
3401 else if(G
.qual
& LR_CTRLKEY
) viewmove(2);
3405 if(G
.qual
& LR_SHIFTKEY
) viewmove(1);
3406 else if(G
.qual
& LR_CTRLKEY
) viewmove(2);
3410 else if(event
==MKEY
) {
3411 if(val
) add_marker(CFRA
-1);
3414 if(ELEM3(event
, ESCKEY
, SPACEKEY
, RIGHTMOUSE
)) break;
3416 inner_play_anim_loop(0, 0);
3417 screen_swapbuffers();
3419 if((mode
& 2) && CFRA
==PEFRA
) break; /* no replay */
3422 if(event
==SPACEKEY
);
3427 if(oldsa
!=curarea
) areawinset(oldsa
->win
);
3429 /* restore all areas */
3430 sa
= G
.curscreen
->areabase
.first
;
3432 if( ((mode
& 1) && sa
->spacetype
==SPACE_VIEW3D
) || sa
==curarea
) addqueue(sa
->win
, REDRAW
, 1);
3436 /* groups could have changed ipo */
3437 allspace(REMAKEIPO
, 0);
3438 allqueue(REDRAWIPO
, 0);
3439 allqueue(REDRAWNLA
, 0);
3440 allqueue (REDRAWACTION
, 0);
3442 /* restore for cfra */
3443 update_for_newframe_muted();
3448 if (event
==ESCKEY
|| event
==SPACEKEY
) return 1;