2.5: Space Image ported back
Organized as follows: uvedit/ uv editing related code uvedit_draw.c: drawing code uvedit_ops.c: operators, just a few done uvedit_unwrap_ops.c: will be operators for unwrapping uvedit_paramatrizer.c: lscm/abf/stretch/pack space_image/ space_image.c: registration and common getter/setters image_draw.c: drawing code, mostly functional image_panels.c: panels, all commented out image_render.c: render callbacks, non functional image_ops.c: operators, only view navigation done image_header.c: header, menus mostly done but missing buttons Notes: * Header menus consist only of Operator and RNA buttons, if they are not implemented they're displayed grayed out. Ideally the full header could work like this, but std_libbuttons looks problematic. * Started using view2d code more than the old code, but for now it still does own view2d management due to some very specific requirements that the image window has. The drawing code however is more clear hopefully, it only uses view2d, and there is no switching between 'p' and 'f' view2d's anymore, it is always 'f'. * In order to make uvedit operators more independent I move some image space settings to scene toolsettings, and the current image and its buffer is in the context. Especially sync selection and select mode belonged there anyway as this cannot work correct with different spaces having different settings anyway. * Image paint is not back yet, did not want to put that together with uvedit because there's really no code sharing.. perhaps vertex paint, image paint and sculpt would be good to have in one module to share brush code, partial redraw, etc better.
This commit is contained in:
@@ -47,6 +47,8 @@ struct ScrArea;
|
||||
struct SpaceLink;
|
||||
struct StructRNA;
|
||||
struct ToolSettings;
|
||||
struct Image;
|
||||
struct ImBuf;
|
||||
struct wmWindow;
|
||||
struct wmWindowManager;
|
||||
|
||||
@@ -149,6 +151,9 @@ struct Object *CTX_data_active_object(const bContext *C);
|
||||
struct Base *CTX_data_active_base(const bContext *C);
|
||||
struct Object *CTX_data_edit_object(const bContext *C);
|
||||
|
||||
struct Image *CTX_data_edit_image(const bContext *C);
|
||||
struct ImBuf *CTX_data_edit_image_buffer(const bContext *C);
|
||||
|
||||
int CTX_data_selected_nodes(const bContext *C, ListBase *list);
|
||||
|
||||
/* Data Evaluation Context */
|
||||
|
||||
@@ -392,6 +392,16 @@ struct Object *CTX_data_edit_object(const bContext *C)
|
||||
return ctx_data_pointer_get(C, CTX_data_edit_object);
|
||||
}
|
||||
|
||||
struct Image *CTX_data_edit_image(const bContext *C)
|
||||
{
|
||||
return ctx_data_pointer_get(C, CTX_data_edit_image);
|
||||
}
|
||||
|
||||
struct ImBuf *CTX_data_edit_image_buffer(const bContext *C)
|
||||
{
|
||||
return ctx_data_pointer_get(C, CTX_data_edit_image_buffer);
|
||||
}
|
||||
|
||||
/* data evaluation */
|
||||
|
||||
float CTX_eval_frame(const bContext *C)
|
||||
|
||||
@@ -29,6 +29,6 @@
|
||||
# Bounces make to subdirectories.
|
||||
|
||||
SOURCEDIR = source/blender/editors
|
||||
DIRS = armature mesh animation object sculpt datafiles transform screen curve gpencil physics preview space_outliner space_time space_view3d interface util space_api space_ipo space_image space_node space_buttons space_info space_file space_sound space_action space_nla space_script space_text space_sequencer
|
||||
DIRS = armature mesh animation object sculpt datafiles transform screen curve gpencil physics preview uvedit space_outliner space_time space_view3d interface util space_api space_ipo space_image space_node space_buttons space_info space_file space_sound space_action space_nla space_script space_text space_sequencer
|
||||
|
||||
include nan_subdirs.mk
|
||||
|
||||
@@ -31,4 +31,5 @@ SConscript(['datafiles/SConscript',
|
||||
'space_sequencer/SConscript',
|
||||
'transform/SConscript',
|
||||
'screen/SConscript',
|
||||
'sculpt/SConscript'])
|
||||
'sculpt/SConscript',
|
||||
'uvedit/SConscript'])
|
||||
|
||||
@@ -33,7 +33,9 @@ struct Object;
|
||||
struct Base;
|
||||
struct Bone;
|
||||
struct bArmature;
|
||||
struct bPoseChannel;
|
||||
struct ListBase;
|
||||
struct View3D;
|
||||
|
||||
typedef struct EditBone
|
||||
{
|
||||
|
||||
@@ -42,6 +42,11 @@ struct ViewContext;
|
||||
struct bDeformGroup;
|
||||
struct MDeformWeight;
|
||||
struct MDeformVert;
|
||||
struct Scene;
|
||||
struct MCol;
|
||||
struct UvVertMap;
|
||||
struct UvMapVert;
|
||||
struct CustomData;
|
||||
|
||||
// edge and face flag both
|
||||
#define EM_FGON 2
|
||||
@@ -79,9 +84,9 @@ void ED_keymap_mesh(struct wmWindowManager *wm);
|
||||
void ED_spacetypes_init(void);
|
||||
void ED_keymap_mesh(struct wmWindowManager *wm);
|
||||
|
||||
void make_editMesh(Scene *scene, Object *ob);
|
||||
void load_editMesh(Scene *scene, Object *ob);
|
||||
void remake_editMesh(Scene *scene, Object *ob);
|
||||
void make_editMesh(struct Scene *scene, Object *ob);
|
||||
void load_editMesh(struct Scene *scene, Object *ob);
|
||||
void remake_editMesh(struct Scene *scene, Object *ob);
|
||||
void free_editMesh(struct EditMesh *em);
|
||||
|
||||
void recalc_editnormals(struct EditMesh *em);
|
||||
@@ -100,8 +105,12 @@ void undo_push_mesh(struct bContext *C, char *name);
|
||||
/* editmesh_lib.c */
|
||||
|
||||
struct EditFace *EM_get_actFace(struct EditMesh *em, int sloppy);
|
||||
void EM_set_actFace(struct EditMesh *em, struct EditFace *efa);
|
||||
float EM_face_area(struct EditFace *efa);
|
||||
void EM_add_data_layer(struct EditMesh *em, struct CustomData *data, int type);
|
||||
|
||||
void EM_select_edge(struct EditEdge *eed, int sel);
|
||||
void EM_select_face(struct EditFace *efa, int sel);
|
||||
void EM_select_face_fgon(struct EditMesh *em, struct EditFace *efa, int val);
|
||||
void EM_selectmode_flush(struct EditMesh *em);
|
||||
void EM_deselect_flush(struct EditMesh *em);
|
||||
@@ -114,6 +123,9 @@ int EM_get_actSelection(struct EditMesh *em, struct EditSelection *ese);
|
||||
void EM_editselection_normal(float *normal, struct EditSelection *ese);
|
||||
void EM_editselection_plane(float *plane, struct EditSelection *ese);
|
||||
|
||||
struct UvVertMap *EM_make_uv_vert_map(struct EditMesh *em, int selected, int do_face_idx_array, float *limit);
|
||||
struct UvMapVert *EM_get_uv_map_vert(struct UvVertMap *vmap, unsigned int v);
|
||||
void EM_free_uv_vert_map(struct UvVertMap *vmap);
|
||||
|
||||
/* editmesh_mods.c */
|
||||
extern unsigned int em_vertoffs, em_solidoffs, em_wireoffs;
|
||||
@@ -125,6 +137,9 @@ void EM_free_backbuf(void);
|
||||
int EM_init_backbuf_border(struct ViewContext *vc, short xmin, short ymin, short xmax, short ymax);
|
||||
int EM_init_backbuf_circle(struct ViewContext *vc, short xs, short ys, short rads);
|
||||
|
||||
/* editface.c */
|
||||
struct MTFace *EM_get_active_mtface(struct EditMesh *em, struct EditFace **act_efa, struct MCol **mcol, int sloppy);
|
||||
|
||||
/* editdeform.c XXX rename functions? */
|
||||
|
||||
#define WEIGHT_REPLACE 1
|
||||
|
||||
@@ -35,6 +35,10 @@ struct bContext;
|
||||
struct Base;
|
||||
struct View3D;
|
||||
struct bConstraint;
|
||||
struct KeyBlock;
|
||||
struct Lattice;
|
||||
struct Mesh;
|
||||
struct Curve;
|
||||
|
||||
void ED_operatortypes_object(void);
|
||||
void ED_keymap_object(struct wmWindowManager *wm);
|
||||
|
||||
@@ -107,6 +107,7 @@ int ED_operator_sequencer_active(struct bContext *C);
|
||||
int ED_operator_object_active(struct bContext *C);
|
||||
int ED_operator_editmesh(struct bContext *C);
|
||||
int ED_operator_editcurve(struct bContext *C);
|
||||
int ED_operator_uvedit(struct bContext *C);
|
||||
|
||||
/* default keymaps, bitflags */
|
||||
#define ED_KEYMAP_UI 1
|
||||
|
||||
45
source/blender/editors/include/ED_uvedit.h
Normal file
45
source/blender/editors/include/ED_uvedit.h
Normal file
@@ -0,0 +1,45 @@
|
||||
/**
|
||||
* $Id:
|
||||
*
|
||||
* ***** BEGIN GPL LICENSE BLOCK *****
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*
|
||||
* The Original Code is Copyright (C) 2008 Blender Foundation.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Contributor(s): Blender Foundation
|
||||
*
|
||||
* ***** END GPL LICENSE BLOCK *****
|
||||
*/
|
||||
|
||||
#ifndef ED_UVEDIT_H
|
||||
#define ED_UVEDIT_H
|
||||
|
||||
struct Scene;
|
||||
struct Object;
|
||||
struct Image;
|
||||
struct wmWindowManager;
|
||||
|
||||
/* uvedit_ops.c */
|
||||
void ED_operatortypes_uvedit(void);
|
||||
void ED_keymap_uvedit(struct wmWindowManager *wm);
|
||||
|
||||
void ED_uvedit_assign_image(struct Scene *scene, struct Object *obedit, struct Image *ima, struct Image *previma);
|
||||
void ED_uvedit_set_tile(struct Scene *scene, struct Object *obedit, struct Image *ima, int curtile, int dotile);
|
||||
int ED_uvedit_minmax(struct Scene *scene, struct Image *ima, struct Object *obedit, float *min, float *max);
|
||||
|
||||
#endif /* ED_UVEDIT_H */
|
||||
|
||||
@@ -598,7 +598,7 @@ static void calculate_uv_map(Scene *scene, ARegion *ar, View3D *v3d, EditMesh *e
|
||||
|
||||
/* last_sel, use em->act_face otherwise get the last selected face in the editselections
|
||||
* at the moment, last_sel is mainly useful for gaking sure the space image dosnt flicker */
|
||||
MTFace *get_active_mtface(EditMesh *em, EditFace **act_efa, MCol **mcol, int sloppy)
|
||||
MTFace *EM_get_active_mtface(EditMesh *em, EditFace **act_efa, MCol **mcol, int sloppy)
|
||||
{
|
||||
EditFace *efa = NULL;
|
||||
|
||||
|
||||
@@ -2133,7 +2133,7 @@ void EM_fgon_flags(EditMesh *em)
|
||||
* if do_face_idx_array is 0 it means we need to run it as well as freeing
|
||||
* */
|
||||
|
||||
UvVertMap *make_uv_vert_map_EM(EditMesh *em, int selected, int do_face_idx_array, float *limit)
|
||||
UvVertMap *EM_make_uv_vert_map(EditMesh *em, int selected, int do_face_idx_array, float *limit)
|
||||
{
|
||||
EditVert *ev;
|
||||
EditFace *efa;
|
||||
@@ -2251,12 +2251,12 @@ UvVertMap *make_uv_vert_map_EM(EditMesh *em, int selected, int do_face_idx_array
|
||||
return vmap;
|
||||
}
|
||||
|
||||
UvMapVert *get_uv_map_vert_EM(UvVertMap *vmap, unsigned int v)
|
||||
UvMapVert *EM_get_uv_map_vert(UvVertMap *vmap, unsigned int v)
|
||||
{
|
||||
return vmap->vert[v];
|
||||
}
|
||||
|
||||
void free_uv_vert_map_EM(UvVertMap *vmap)
|
||||
void EM_free_uv_vert_map(UvVertMap *vmap)
|
||||
{
|
||||
if (vmap) {
|
||||
if (vmap->vert) MEM_freeN(vmap->vert);
|
||||
|
||||
@@ -112,19 +112,14 @@ extern int faceselectedOR(EditFace *efa, int flag);
|
||||
extern int faceselectedAND(EditFace *efa, int flag);
|
||||
|
||||
void EM_remove_selection(EditMesh *em, void *data, int type);
|
||||
void EM_set_actFace(EditMesh *em, EditFace *efa);
|
||||
void EM_select_face(EditFace *efa, int sel);
|
||||
void EM_clear_flag_all(EditMesh *em, int flag);
|
||||
void EM_set_flag_all(EditMesh *em, int flag);
|
||||
|
||||
void EM_add_data_layer(EditMesh *em, CustomData *data, int type);
|
||||
|
||||
void EM_data_interp_from_verts(EditMesh *em, EditVert *v1, EditVert *v2, EditVert *eve, float fac);
|
||||
void EM_data_interp_from_faces(EditMesh *em, EditFace *efa1, EditFace *efa2, EditFace *efan, int i1, int i2, int i3, int i4);
|
||||
|
||||
int EM_nvertices_selected(EditMesh *em);
|
||||
int EM_nfaces_selected(EditMesh *em);
|
||||
float EM_face_area(EditFace *efa);
|
||||
float EM_face_perimeter(EditFace *efa);
|
||||
|
||||
void EM_store_selection(EditMesh *em, void *data, int type);
|
||||
|
||||
@@ -26,10 +26,12 @@
|
||||
|
||||
#include "MEM_guardedalloc.h"
|
||||
|
||||
#include "BLI_blenlib.h"
|
||||
#include "BLI_arithb.h"
|
||||
#include "BLI_blenlib.h"
|
||||
#include "BLI_editVert.h"
|
||||
|
||||
#include "BKE_context.h"
|
||||
#include "BKE_customdata.h"
|
||||
#include "BKE_library.h"
|
||||
#include "BKE_main.h"
|
||||
#include "BKE_screen.h"
|
||||
@@ -158,6 +160,20 @@ int ED_operator_editmesh(bContext *C)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ED_operator_uvedit(bContext *C)
|
||||
{
|
||||
Object *obedit= CTX_data_edit_object(C);
|
||||
EditMesh *em= NULL;
|
||||
|
||||
if(obedit && obedit->type==OB_MESH)
|
||||
em= ((Mesh *)obedit->data)->edit_mesh;
|
||||
|
||||
if(em && (em->faces.first) && (CustomData_has_layer(&em->fdata, CD_MTFACE)))
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ED_operator_editcurve(bContext *C)
|
||||
{
|
||||
Object *obedit= CTX_data_edit_object(C);
|
||||
|
||||
@@ -42,10 +42,10 @@
|
||||
#include "ED_anim_api.h"
|
||||
#include "ED_mesh.h"
|
||||
#include "ED_object.h"
|
||||
#include "ED_space_api.h"
|
||||
#include "ED_screen.h"
|
||||
#include "ED_sculpt.h"
|
||||
|
||||
#include "ED_screen.h"
|
||||
#include "ED_space_api.h"
|
||||
#include "ED_uvedit.h"
|
||||
|
||||
ARegionType *ED_regiontype_from_id(SpaceType *st, int regionid)
|
||||
{
|
||||
@@ -91,6 +91,7 @@ void ED_spacetypes_init(void)
|
||||
ED_operatortypes_object();
|
||||
ED_operatortypes_mesh();
|
||||
ED_operatortypes_sculpt();
|
||||
ED_operatortypes_uvedit();
|
||||
ui_view2d_operatortypes();
|
||||
|
||||
spacetypes = BKE_spacetypes_list();
|
||||
@@ -112,6 +113,7 @@ void ED_spacetypes_keymap(wmWindowManager *wm)
|
||||
ED_keymap_animchannels(wm);
|
||||
ED_keymap_object(wm);
|
||||
ED_keymap_mesh(wm);
|
||||
ED_keymap_uvedit(wm);
|
||||
UI_view2d_keymap(wm);
|
||||
|
||||
spacetypes = BKE_spacetypes_list();
|
||||
|
||||
@@ -40,14 +40,16 @@ CPPFLAGS += -I$(OPENGL_HEADERS)
|
||||
|
||||
# not very neat....
|
||||
CPPFLAGS += -I../../windowmanager
|
||||
CPPFLAGS += -I../../blenloader
|
||||
CPPFLAGS += -I../../blenkernel
|
||||
CPPFLAGS += -I../../blenlib
|
||||
CPPFLAGS += -I../../makesdna
|
||||
CPPFLAGS += -I../../makesrna
|
||||
CPPFLAGS += -I../../imbuf
|
||||
CPPFLAGS += -I../../python
|
||||
CPPFLAGS += -I../../render/extern/include
|
||||
CPPFLAGS += -I$(NAN_GUARDEDALLOC)/include
|
||||
|
||||
# own include
|
||||
|
||||
CPPFLAGS += -I../include
|
||||
|
||||
|
||||
@@ -5,5 +5,6 @@ sources = env.Glob('*.c')
|
||||
|
||||
incs = '../include ../../blenlib ../../blenkernel ../../makesdna ../../imbuf'
|
||||
incs += ' ../../windowmanager #/intern/guardedalloc #/extern/glew/include'
|
||||
incs += ' ../../render/extern/include ../../makesrna'
|
||||
|
||||
env.BlenderLib ( 'bf_editors_space_image', sources, Split(incs), [], libtype=['core'], priority=[45] )
|
||||
|
||||
722
source/blender/editors/space_image/image_draw.c
Normal file
722
source/blender/editors/space_image/image_draw.c
Normal file
@@ -0,0 +1,722 @@
|
||||
/**
|
||||
* $Id$
|
||||
*
|
||||
* ***** BEGIN GPL LICENSE BLOCK *****
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*
|
||||
* The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Contributor(s): Blender Foundation, 2002-2009
|
||||
*
|
||||
* ***** END GPL LICENSE BLOCK *****
|
||||
*/
|
||||
|
||||
#include <math.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "MEM_guardedalloc.h"
|
||||
|
||||
#include "DNA_brush_types.h"
|
||||
#include "DNA_camera_types.h"
|
||||
#include "DNA_image_types.h"
|
||||
#include "DNA_object_types.h"
|
||||
#include "DNA_space_types.h"
|
||||
#include "DNA_scene_types.h"
|
||||
#include "DNA_screen_types.h"
|
||||
|
||||
#include "PIL_time.h"
|
||||
|
||||
#include "IMB_imbuf.h"
|
||||
#include "IMB_imbuf_types.h"
|
||||
|
||||
#include "BKE_colortools.h"
|
||||
#include "BKE_global.h"
|
||||
#include "BKE_image.h"
|
||||
#include "BKE_utildefines.h"
|
||||
|
||||
#include "BIF_gl.h"
|
||||
#include "BIF_glutil.h"
|
||||
|
||||
#include "ED_screen.h"
|
||||
|
||||
#include "UI_resources.h"
|
||||
#include "UI_text.h"
|
||||
#include "UI_view2d.h"
|
||||
|
||||
#include "WM_api.h"
|
||||
|
||||
#include "image_intern.h"
|
||||
|
||||
#define HEADER_HEIGHT 18
|
||||
|
||||
#if 0
|
||||
static int image_preview_active(SpaceImage *sima, Scene *scene, float *xim, float *yim)
|
||||
{
|
||||
/* only when compositor shows, and image handler set */
|
||||
if(sima->image && sima->image->type==IMA_TYPE_COMPOSITE) {
|
||||
/* XXX panels .. */
|
||||
#if 0
|
||||
short a;
|
||||
|
||||
for(a=0; a<SPACE_MAXHANDLER; a+=2) {
|
||||
if(sima->blockhandler[a] == IMAGE_HANDLER_PREVIEW) {
|
||||
if(xim) *xim= (scene->r.size*scene->r.xsch)/100;
|
||||
if(yim) *yim= (scene->r.size*scene->r.ysch)/100;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* are there curves? curves visible? and curves do something? */
|
||||
static int image_curves_active(SpaceImage *sima)
|
||||
{
|
||||
if(sima->cumap) {
|
||||
if(curvemapping_RGBA_does_something(sima->cumap)) {
|
||||
/* XXX panels .. */
|
||||
#if 0
|
||||
short a;
|
||||
for(a=0; a<SPACE_MAXHANDLER; a+=2) {
|
||||
if(sima->blockhandler[a] == IMAGE_HANDLER_CURVES)
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void image_verify_buffer_float(SpaceImage *sima, ImBuf *ibuf)
|
||||
{
|
||||
/* detect if we need to redo the curve map.
|
||||
ibuf->rect is zero for compositor and render results after change
|
||||
convert to 32 bits always... drawing float rects isnt supported well (atis)
|
||||
|
||||
NOTE: if float buffer changes, we have to manually remove the rect
|
||||
*/
|
||||
|
||||
if(ibuf->rect_float) {
|
||||
if(ibuf->rect==NULL) {
|
||||
if(image_curves_active(sima))
|
||||
curvemapping_do_ibuf(sima->cumap, ibuf);
|
||||
else
|
||||
IMB_rect_from_float(ibuf);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void sima_draw_render_info(SpaceImage *sima, ARegion *ar)
|
||||
{
|
||||
rcti rect;
|
||||
float colf[3];
|
||||
int showspare= 0; // XXX BIF_show_render_spare();
|
||||
char *str= "render text"; // XXX BIF_render_text();
|
||||
|
||||
if(str==NULL)
|
||||
return;
|
||||
|
||||
rect= ar->winrct;
|
||||
rect.ymin= rect.ymax - HEADER_HEIGHT;
|
||||
|
||||
glaDefine2DArea(&rect);
|
||||
|
||||
/* clear header rect */
|
||||
UI_GetThemeColor3fv(TH_BACK, colf);
|
||||
glClearColor(colf[0]+0.1f, colf[1]+0.1f, colf[2]+0.1f, 1.0);
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
|
||||
UI_ThemeColor(TH_TEXT_HI);
|
||||
glRasterPos2i(12, 5);
|
||||
UI_RasterPos(12, 5);
|
||||
|
||||
if(showspare) {
|
||||
UI_DrawString(G.fonts, "(Previous)", 0);
|
||||
glRasterPos2i(72, 5);
|
||||
UI_RasterPos(72, 5);
|
||||
}
|
||||
|
||||
UI_DrawString(G.fonts, str, 0);
|
||||
}
|
||||
|
||||
/*static void sima_draw_image_info(ARegion *ar, int channels, int x, int y, char *cp, float *fp, int *zp, float *zpf)
|
||||
{
|
||||
char str[256];
|
||||
int ofs;
|
||||
|
||||
ofs= sprintf(str, "X: %d Y: %d ", x, y);
|
||||
if(cp)
|
||||
ofs+= sprintf(str+ofs, "| R: %d G: %d B: %d A: %d ", cp[0], cp[1], cp[2], cp[3]);
|
||||
|
||||
if(fp) {
|
||||
if(channels==4)
|
||||
ofs+= sprintf(str+ofs, "| R: %.3f G: %.3f B: %.3f A: %.3f ", fp[0], fp[1], fp[2], fp[3]);
|
||||
else if(channels==1)
|
||||
ofs+= sprintf(str+ofs, "| Val: %.3f ", fp[0]);
|
||||
else if(channels==3)
|
||||
ofs+= sprintf(str+ofs, "| R: %.3f G: %.3f B: %.3f ", fp[0], fp[1], fp[2]);
|
||||
}
|
||||
|
||||
if(zp)
|
||||
ofs+= sprintf(str+ofs, "| Z: %.4f ", 0.5+0.5*(((float)*zp)/(float)0x7fffffff));
|
||||
if(zpf)
|
||||
ofs+= sprintf(str+ofs, "| Z: %.3f ", *zpf);
|
||||
|
||||
glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
|
||||
glEnable(GL_BLEND);
|
||||
|
||||
glColor4f(.0,.0,.0,.25);
|
||||
glRectf(0.0, 0.0, ar->winrct.xmax - ar->winrct.xmin + 1, 30.0);
|
||||
glDisable(GL_BLEND);
|
||||
|
||||
glColor3ub(255, 255, 255);
|
||||
glRasterPos2i(10, 10);
|
||||
UI_RasterPos(10, 10);
|
||||
|
||||
UI_DrawString(G.fonts, str, 0);
|
||||
}*/
|
||||
|
||||
/* image drawing */
|
||||
|
||||
static void draw_image_grid(ARegion *ar, float zoomx, float zoomy)
|
||||
{
|
||||
float gridsize, gridstep= 1.0f/32.0f;
|
||||
float fac, blendfac;
|
||||
int x1, y1, x2, y2;
|
||||
|
||||
/* the image is located inside (0,0),(1, 1) as set by view2d */
|
||||
UI_ThemeColorShade(TH_BACK, 20);
|
||||
|
||||
UI_view2d_to_region_no_clip(&ar->v2d, 0.0f, 0.0f, &x1, &y1);
|
||||
UI_view2d_to_region_no_clip(&ar->v2d, 1.0f, 1.0f, &x2, &y2);
|
||||
glRectf(x1, y1, x2, y2);
|
||||
|
||||
/* gridsize adapted to zoom level */
|
||||
gridsize= 0.5f*(zoomx+zoomy);
|
||||
if(gridsize<=0.0f) return;
|
||||
|
||||
if(gridsize<1.0f) {
|
||||
while(gridsize<1.0f) {
|
||||
gridsize*= 4.0;
|
||||
gridstep*= 4.0;
|
||||
}
|
||||
}
|
||||
else {
|
||||
while(gridsize>=4.0f) {
|
||||
gridsize/= 4.0;
|
||||
gridstep/= 4.0;
|
||||
}
|
||||
}
|
||||
|
||||
/* the fine resolution level */
|
||||
blendfac= 0.25*gridsize - floor(0.25*gridsize);
|
||||
CLAMP(blendfac, 0.0, 1.0);
|
||||
UI_ThemeColorShade(TH_BACK, (int)(20.0*(1.0-blendfac)));
|
||||
|
||||
fac= 0.0f;
|
||||
glBegin(GL_LINES);
|
||||
while(fac<1.0f) {
|
||||
glVertex2f(x1, y1*(1.0f-fac) + y2*fac);
|
||||
glVertex2f(x2, y1*(1.0f-fac) + y2*fac);
|
||||
glVertex2f(x1*(1.0f-fac) + x2*fac, y1);
|
||||
glVertex2f(x1*(1.0f-fac) + x2*fac, y2);
|
||||
fac+= gridstep;
|
||||
}
|
||||
|
||||
/* the large resolution level */
|
||||
UI_ThemeColor(TH_BACK);
|
||||
|
||||
fac= 0.0f;
|
||||
while(fac<1.0f) {
|
||||
glVertex2f(x1, y1*(1.0f-fac) + y2*fac);
|
||||
glVertex2f(x2, y1*(1.0f-fac) + y2*fac);
|
||||
glVertex2f(x1*(1.0f-fac) + x2*fac, y1);
|
||||
glVertex2f(x1*(1.0f-fac) + x2*fac, y2);
|
||||
fac+= 4.0f*gridstep;
|
||||
}
|
||||
glEnd();
|
||||
}
|
||||
|
||||
static void sima_draw_alpha_backdrop(float x1, float y1, float xsize, float ysize, float zoomx, float zoomy)
|
||||
{
|
||||
GLubyte checker_stipple[32*32/8] =
|
||||
{
|
||||
255,255,0,0,255,255,0,0,255,255,0,0,255,255,0,0, \
|
||||
255,255,0,0,255,255,0,0,255,255,0,0,255,255,0,0, \
|
||||
255,255,0,0,255,255,0,0,255,255,0,0,255,255,0,0, \
|
||||
255,255,0,0,255,255,0,0,255,255,0,0,255,255,0,0, \
|
||||
0,0,255,255,0,0,255,255,0,0,255,255,0,0,255,255, \
|
||||
0,0,255,255,0,0,255,255,0,0,255,255,0,0,255,255, \
|
||||
0,0,255,255,0,0,255,255,0,0,255,255,0,0,255,255, \
|
||||
0,0,255,255,0,0,255,255,0,0,255,255,0,0,255,255, \
|
||||
};
|
||||
|
||||
glColor3ub(100, 100, 100);
|
||||
glRectf(x1, y1, x1 + zoomx*xsize, y1 + zoomy*ysize);
|
||||
glColor3ub(160, 160, 160);
|
||||
|
||||
glEnable(GL_POLYGON_STIPPLE);
|
||||
glPolygonStipple(checker_stipple);
|
||||
glRectf(x1, y1, x1 + zoomx*xsize, y1 + zoomy*ysize);
|
||||
glDisable(GL_POLYGON_STIPPLE);
|
||||
}
|
||||
|
||||
static void sima_draw_alpha_pixels(float x1, float y1, int rectx, int recty, unsigned int *recti)
|
||||
{
|
||||
|
||||
/* swap bytes, so alpha is most significant one, then just draw it as luminance int */
|
||||
if(ENDIAN_ORDER == B_ENDIAN)
|
||||
glPixelStorei(GL_UNPACK_SWAP_BYTES, 1);
|
||||
|
||||
glaDrawPixelsSafe(x1, y1, rectx, recty, rectx, GL_LUMINANCE, GL_UNSIGNED_INT, recti);
|
||||
glPixelStorei(GL_UNPACK_SWAP_BYTES, 0);
|
||||
}
|
||||
|
||||
static void sima_draw_alpha_pixelsf(float x1, float y1, int rectx, int recty, float *rectf)
|
||||
{
|
||||
float *trectf= MEM_mallocN(rectx*recty*4, "temp");
|
||||
int a, b;
|
||||
|
||||
for(a= rectx*recty -1, b= 4*a+3; a>=0; a--, b-=4)
|
||||
trectf[a]= rectf[b];
|
||||
|
||||
glaDrawPixelsSafe(x1, y1, rectx, recty, rectx, GL_LUMINANCE, GL_FLOAT, trectf);
|
||||
MEM_freeN(trectf);
|
||||
/* ogl trick below is slower... (on ATI 9600) */
|
||||
// glColorMask(1, 0, 0, 0);
|
||||
// glaDrawPixelsSafe(x1, y1, rectx, recty, rectx, GL_RGBA, GL_FLOAT, rectf+3);
|
||||
// glColorMask(0, 1, 0, 0);
|
||||
// glaDrawPixelsSafe(x1, y1, rectx, recty, rectx, GL_RGBA, GL_FLOAT, rectf+2);
|
||||
// glColorMask(0, 0, 1, 0);
|
||||
// glaDrawPixelsSafe(x1, y1, rectx, recty, rectx, GL_RGBA, GL_FLOAT, rectf+1);
|
||||
// glColorMask(1, 1, 1, 1);
|
||||
}
|
||||
|
||||
static void sima_draw_zbuf_pixels(float x1, float y1, int rectx, int recty, int *recti)
|
||||
{
|
||||
/* zbuffer values are signed, so we need to shift color range */
|
||||
glPixelTransferf(GL_RED_SCALE, 0.5f);
|
||||
glPixelTransferf(GL_GREEN_SCALE, 0.5f);
|
||||
glPixelTransferf(GL_BLUE_SCALE, 0.5f);
|
||||
glPixelTransferf(GL_RED_BIAS, 0.5f);
|
||||
glPixelTransferf(GL_GREEN_BIAS, 0.5f);
|
||||
glPixelTransferf(GL_BLUE_BIAS, 0.5f);
|
||||
|
||||
glaDrawPixelsSafe(x1, y1, rectx, recty, rectx, GL_LUMINANCE, GL_INT, recti);
|
||||
|
||||
glPixelTransferf(GL_RED_SCALE, 1.0f);
|
||||
glPixelTransferf(GL_GREEN_SCALE, 1.0f);
|
||||
glPixelTransferf(GL_BLUE_SCALE, 1.0f);
|
||||
glPixelTransferf(GL_RED_BIAS, 0.0f);
|
||||
glPixelTransferf(GL_GREEN_BIAS, 0.0f);
|
||||
glPixelTransferf(GL_BLUE_BIAS, 0.0f);
|
||||
}
|
||||
|
||||
static void sima_draw_zbuffloat_pixels(Scene *scene, float x1, float y1, int rectx, int recty, float *rect_float)
|
||||
{
|
||||
float bias, scale, *rectf, clipend;
|
||||
int a;
|
||||
|
||||
if(scene->camera && scene->camera->type==OB_CAMERA) {
|
||||
bias= ((Camera *)scene->camera->data)->clipsta;
|
||||
clipend= ((Camera *)scene->camera->data)->clipend;
|
||||
scale= 1.0f/(clipend-bias);
|
||||
}
|
||||
else {
|
||||
bias= 0.1f;
|
||||
scale= 0.01f;
|
||||
clipend= 100.0f;
|
||||
}
|
||||
|
||||
rectf= MEM_mallocN(rectx*recty*4, "temp");
|
||||
for(a= rectx*recty -1; a>=0; a--) {
|
||||
if(rect_float[a]>clipend)
|
||||
rectf[a]= 0.0f;
|
||||
else if(rect_float[a]<bias)
|
||||
rectf[a]= 1.0f;
|
||||
else {
|
||||
rectf[a]= 1.0f - (rect_float[a]-bias)*scale;
|
||||
rectf[a]*= rectf[a];
|
||||
}
|
||||
}
|
||||
glaDrawPixelsSafe(x1, y1, rectx, recty, rectx, GL_LUMINANCE, GL_FLOAT, rectf);
|
||||
|
||||
MEM_freeN(rectf);
|
||||
}
|
||||
|
||||
static void draw_image_buffer(SpaceImage *sima, ARegion *ar, Scene *scene, ImBuf *ibuf, float fx, float fy, float zoomx, float zoomy)
|
||||
{
|
||||
int x, y;
|
||||
|
||||
/* set zoom */
|
||||
glPixelZoom(zoomx, zoomy);
|
||||
|
||||
/* find window pixel coordinates of origin */
|
||||
UI_view2d_to_region_no_clip(&ar->v2d, fx, fy, &x, &y);
|
||||
|
||||
/* this part is generic image display */
|
||||
if(sima->flag & SI_SHOW_ALPHA) {
|
||||
if(ibuf->rect)
|
||||
sima_draw_alpha_pixels(x, y, ibuf->x, ibuf->y, ibuf->rect);
|
||||
else if(ibuf->rect_float && ibuf->channels==4)
|
||||
sima_draw_alpha_pixelsf(x, y, ibuf->x, ibuf->y, ibuf->rect_float);
|
||||
}
|
||||
else if(sima->flag & SI_SHOW_ZBUF && (ibuf->zbuf || ibuf->zbuf_float || (ibuf->channels==1))) {
|
||||
if(ibuf->zbuf)
|
||||
sima_draw_zbuf_pixels(x, y, ibuf->x, ibuf->y, ibuf->zbuf);
|
||||
else if(ibuf->zbuf_float)
|
||||
sima_draw_zbuffloat_pixels(scene, x, y, ibuf->x, ibuf->y, ibuf->zbuf_float);
|
||||
else if(ibuf->channels==1)
|
||||
sima_draw_zbuffloat_pixels(scene, x, y, ibuf->x, ibuf->y, ibuf->rect_float);
|
||||
}
|
||||
else {
|
||||
if(sima->flag & SI_USE_ALPHA) {
|
||||
sima_draw_alpha_backdrop(x, y, ibuf->x, ibuf->y, zoomx, zoomy);
|
||||
|
||||
glEnable(GL_BLEND);
|
||||
glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
|
||||
}
|
||||
|
||||
/* we don't draw floats buffers directly but
|
||||
* convert them, and optionally apply curves */
|
||||
image_verify_buffer_float(sima, ibuf);
|
||||
|
||||
if(ibuf->rect)
|
||||
glaDrawPixelsSafe(x, y, ibuf->x, ibuf->y, ibuf->x, GL_RGBA, GL_UNSIGNED_BYTE, ibuf->rect);
|
||||
/*else
|
||||
glaDrawPixelsSafe(x, y, ibuf->x, ibuf->y, ibuf->x, GL_RGBA, GL_FLOAT, ibuf->rect_float);*/
|
||||
|
||||
if(sima->flag & SI_USE_ALPHA)
|
||||
glDisable(GL_BLEND);
|
||||
}
|
||||
|
||||
/* reset zoom */
|
||||
glPixelZoom(1.0f, 1.0f);
|
||||
}
|
||||
|
||||
static unsigned int *get_part_from_ibuf(ImBuf *ibuf, short startx, short starty, short endx, short endy)
|
||||
{
|
||||
unsigned int *rt, *rp, *rectmain;
|
||||
short y, heigth, len;
|
||||
|
||||
/* the right offset in rectot */
|
||||
|
||||
rt= ibuf->rect+ (starty*ibuf->x+ startx);
|
||||
|
||||
len= (endx-startx);
|
||||
heigth= (endy-starty);
|
||||
|
||||
rp=rectmain= MEM_mallocN(heigth*len*sizeof(int), "rect");
|
||||
|
||||
for(y=0; y<heigth; y++) {
|
||||
memcpy(rp, rt, len*4);
|
||||
rt+= ibuf->x;
|
||||
rp+= len;
|
||||
}
|
||||
return rectmain;
|
||||
}
|
||||
|
||||
static void draw_image_buffer_tiled(SpaceImage *sima, ARegion *ar, Image *ima, ImBuf *ibuf, float zoomx, float zoomy)
|
||||
{
|
||||
unsigned int *rect;
|
||||
int dx, dy, sx, sy, x, y;
|
||||
|
||||
/* verify valid values, just leave this a while */
|
||||
if(ima->xrep<1) return;
|
||||
if(ima->yrep<1) return;
|
||||
|
||||
glPixelZoom(zoomx, zoomy);
|
||||
|
||||
if(sima->curtile >= ima->xrep*ima->yrep)
|
||||
sima->curtile = ima->xrep*ima->yrep - 1;
|
||||
|
||||
/* create char buffer from float if needed */
|
||||
image_verify_buffer_float(sima, ibuf);
|
||||
|
||||
/* retrieve part of image buffer */
|
||||
dx= ibuf->x/ima->xrep;
|
||||
dy= ibuf->y/ima->yrep;
|
||||
sx= (sima->curtile % ima->xrep)*dx;
|
||||
sy= (sima->curtile / ima->xrep)*dy;
|
||||
rect= get_part_from_ibuf(ibuf, sx, sy, sx+dx, sy+dy);
|
||||
|
||||
/* draw repeated */
|
||||
for(sy=0; sy+dy<=ibuf->y; sy+= dy) {
|
||||
for(sx=0; sx+dx<=ibuf->x; sx+= dx) {
|
||||
UI_view2d_view_to_region(&ar->v2d, (float)sx/(float)ibuf->x, (float)sy/(float)ibuf->y, &x, &y);
|
||||
|
||||
glaDrawPixelsSafe(x, y, dx, dy, dx, GL_RGBA, GL_UNSIGNED_BYTE, rect);
|
||||
}
|
||||
}
|
||||
|
||||
glPixelZoom(1.0f, 1.0f);
|
||||
|
||||
MEM_freeN(rect);
|
||||
}
|
||||
|
||||
static void draw_image_buffer_repeated(SpaceImage *sima, ARegion *ar, Scene *scene, ImBuf *ibuf, float zoomx, float zoomy)
|
||||
{
|
||||
float x, y;
|
||||
double time_current;
|
||||
|
||||
time_current = PIL_check_seconds_timer();
|
||||
|
||||
for(x=ar->v2d.cur.xmin; x<ar->v2d.cur.xmax; x += zoomx) {
|
||||
for(y=ar->v2d.cur.ymin; y<ar->v2d.cur.ymax; y += zoomy) {
|
||||
draw_image_buffer(sima, ar, scene, ibuf, x, y, zoomx, zoomy);
|
||||
|
||||
/* only draw until running out of time */
|
||||
if((PIL_check_seconds_timer() - time_current) > 0.25)
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* draw uv edit */
|
||||
|
||||
/* XXX this becomes draw extra? */
|
||||
#if 0
|
||||
glPixelZoom(zoomx, zoomy);
|
||||
|
||||
if(sima->flag & SI_EDITTILE) {
|
||||
/* create char buffer from float if needed */
|
||||
image_verify_buffer_float(sima, ibuf);
|
||||
|
||||
glaDrawPixelsSafe(x1, y1, ibuf->x, ibuf->y, ibuf->x, GL_RGBA, GL_UNSIGNED_BYTE, ibuf->rect);
|
||||
|
||||
glPixelZoom(1.0, 1.0);
|
||||
|
||||
dx= ibuf->x/sima->image->xrep;
|
||||
dy= ibuf->y/sima->image->yrep;
|
||||
sy= (sima->curtile / sima->image->xrep);
|
||||
sx= sima->curtile - sy*sima->image->xrep;
|
||||
|
||||
sx*= dx;
|
||||
sy*= dy;
|
||||
|
||||
calc_image_view(sima, 'p'); /* pixel */
|
||||
myortho2(G.v2d->cur.xmin, G.v2d->cur.xmax, G.v2d->cur.ymin, G.v2d->cur.ymax);
|
||||
|
||||
cpack(0x0);
|
||||
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); glRects(sx, sy, sx+dx-1, sy+dy-1); glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
|
||||
cpack(0xFFFFFF);
|
||||
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); glRects(sx+1, sy+1, sx+dx, sy+dy); glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* draw grease pencil */
|
||||
|
||||
static void draw_image_grease_pencil(SpaceImage *sima, ImBuf *ibuf)
|
||||
{
|
||||
/* XXX bring back */
|
||||
/* draw grease-pencil ('image' strokes) */
|
||||
if (sima->flag & SI_DISPGP)
|
||||
; // XXX draw_gpencil_2dimage(sa, ibuf);
|
||||
|
||||
#if 0
|
||||
mywinset(sa->win); /* restore scissor after gla call... */
|
||||
wmOrtho2(-0.375, sa->winx-0.375, -0.375, sa->winy-0.375);
|
||||
#endif
|
||||
|
||||
/* draw grease-pencil (screen strokes) */
|
||||
if (sima->flag & SI_DISPGP)
|
||||
; // XXX draw_gpencil_2dview(sa, NULL);
|
||||
}
|
||||
|
||||
/* XXX becomes WM paint cursor */
|
||||
#if 0
|
||||
static void draw_image_view_tool(Scene *scene)
|
||||
{
|
||||
ToolSettings *settings= scene->toolsettings;
|
||||
Brush *brush= settings->imapaint.brush;
|
||||
short mval[2];
|
||||
float radius;
|
||||
int draw= 0;
|
||||
|
||||
if(brush) {
|
||||
if(settings->imapaint.flag & IMAGEPAINT_DRAWING) {
|
||||
if(settings->imapaint.flag & IMAGEPAINT_DRAW_TOOL_DRAWING)
|
||||
draw= 1;
|
||||
}
|
||||
else if(settings->imapaint.flag & IMAGEPAINT_DRAW_TOOL)
|
||||
draw= 1;
|
||||
|
||||
if(draw) {
|
||||
getmouseco_areawin(mval);
|
||||
|
||||
radius= brush->size*G.sima->zoom/2;
|
||||
fdrawXORcirc(mval[0], mval[1], radius);
|
||||
|
||||
if (brush->innerradius != 1.0) {
|
||||
radius *= brush->innerradius;
|
||||
fdrawXORcirc(mval[0], mval[1], radius);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
static unsigned char *get_alpha_clone_image(Scene *scene, int *width, int *height)
|
||||
{
|
||||
Brush *brush = scene->toolsettings->imapaint.brush;
|
||||
ImBuf *ibuf;
|
||||
unsigned int size, alpha;
|
||||
unsigned char *rect, *cp;
|
||||
|
||||
if(!brush || !brush->clone.image)
|
||||
return NULL;
|
||||
|
||||
ibuf= BKE_image_get_ibuf(brush->clone.image, NULL);
|
||||
|
||||
if(!ibuf || !ibuf->rect)
|
||||
return NULL;
|
||||
|
||||
rect= MEM_dupallocN(ibuf->rect);
|
||||
if(!rect)
|
||||
return NULL;
|
||||
|
||||
*width= ibuf->x;
|
||||
*height= ibuf->y;
|
||||
|
||||
size= (*width)*(*height);
|
||||
alpha= (unsigned char)255*brush->clone.alpha;
|
||||
cp= rect;
|
||||
|
||||
while(size-- > 0) {
|
||||
cp[3]= alpha;
|
||||
cp += 4;
|
||||
}
|
||||
|
||||
return rect;
|
||||
}
|
||||
|
||||
static void draw_image_paint_helpers(SpaceImage *sima, ARegion *ar, Scene *scene, float zoomx, float zoomy)
|
||||
{
|
||||
Brush *brush;
|
||||
int x, y, w, h;
|
||||
unsigned char *clonerect;
|
||||
|
||||
brush= scene->toolsettings->imapaint.brush;
|
||||
|
||||
if(brush && (scene->toolsettings->imapaint.tool == PAINT_TOOL_CLONE)) {
|
||||
/* this is not very efficient, but glDrawPixels doesn't allow
|
||||
drawing with alpha */
|
||||
clonerect= get_alpha_clone_image(scene, &w, &h);
|
||||
|
||||
if(clonerect) {
|
||||
UI_view2d_to_region_no_clip(&ar->v2d, brush->clone.offset[0], brush->clone.offset[1], &x, &y);
|
||||
|
||||
glPixelZoom(zoomx, zoomy);
|
||||
|
||||
glEnable(GL_BLEND);
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
glaDrawPixelsSafe(x, y, w, h, w, GL_RGBA, GL_UNSIGNED_BYTE, clonerect);
|
||||
glDisable(GL_BLEND);
|
||||
|
||||
glPixelZoom(1.0, 1.0);
|
||||
|
||||
MEM_freeN(clonerect);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* draw main image area */
|
||||
|
||||
void draw_image_main(SpaceImage *sima, ARegion *ar, Scene *scene)
|
||||
{
|
||||
Image *ima;
|
||||
ImBuf *ibuf;
|
||||
float zoomx, zoomy;
|
||||
int show_viewer, show_render;
|
||||
|
||||
/* XXX can we do this in refresh? */
|
||||
#if 0
|
||||
what_image(sima);
|
||||
|
||||
if(sima->image) {
|
||||
image_pixel_aspect(sima->image, &xuser_asp, &yuser_asp);
|
||||
|
||||
/* UGLY hack? until now iusers worked fine... but for flipbook viewer we need this */
|
||||
if(sima->image->type==IMA_TYPE_COMPOSITE) {
|
||||
ImageUser *iuser= ntree_get_active_iuser(scene->nodetree);
|
||||
if(iuser) {
|
||||
BKE_image_user_calc_imanr(iuser, scene->r.cfra, 0);
|
||||
sima->iuser= *iuser;
|
||||
}
|
||||
}
|
||||
/* and we check for spare */
|
||||
ibuf= get_space_image_buffer(sima);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* retrieve the image and information about it */
|
||||
ima= get_space_image(sima);
|
||||
ibuf= get_space_image_buffer(sima);
|
||||
get_space_image_zoom(sima, ar, &zoomx, &zoomy);
|
||||
|
||||
show_viewer= (ima && ima->source == IMA_SRC_VIEWER);
|
||||
show_render= (show_viewer && ima->type == IMA_TYPE_R_RESULT);
|
||||
|
||||
/* draw the image or grid */
|
||||
if(ibuf==NULL)
|
||||
draw_image_grid(ar, zoomx, zoomy);
|
||||
else if(sima->flag & SI_DRAW_TILE)
|
||||
draw_image_buffer_repeated(sima, ar, scene, ibuf, zoomx, zoomy);
|
||||
else if(ima && (ima->tpageflag & IMA_TILES))
|
||||
draw_image_buffer_tiled(sima, ar, ima, ibuf, zoomx, zoomy);
|
||||
else
|
||||
draw_image_buffer(sima, ar, scene, ibuf, 0.0f, 0.0f, zoomx, zoomy);
|
||||
|
||||
/* grease pencil */
|
||||
draw_image_grease_pencil(sima, ibuf);
|
||||
|
||||
/* paint helpers */
|
||||
draw_image_paint_helpers(sima, ar, scene, zoomx, zoomy);
|
||||
|
||||
/* render info */
|
||||
if(ibuf && show_render)
|
||||
sima_draw_render_info(sima, ar);
|
||||
|
||||
/* XXX integrate this code */
|
||||
#if 0
|
||||
if(ibuf) {
|
||||
float xoffs=0.0f, yoffs= 0.0f;
|
||||
|
||||
if(image_preview_active(sa, &xim, &yim)) {
|
||||
xoffs= scene->r.disprect.xmin;
|
||||
yoffs= scene->r.disprect.ymin;
|
||||
glColor3ub(0,0,0);
|
||||
calc_image_view(sima, 'f');
|
||||
myortho2(G.v2d->cur.xmin, G.v2d->cur.xmax, G.v2d->cur.ymin, G.v2d->cur.ymax);
|
||||
glRectf(0.0f, 0.0f, 1.0f, 1.0f);
|
||||
glLoadIdentity();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
/* it is important to end a view in a transform compatible with buttons */
|
||||
bwin_scalematrix(sa->win, sima->blockscale, sima->blockscale, sima->blockscale);
|
||||
if(!(G.rendering && show_render))
|
||||
image_blockhandlers(sa);
|
||||
#endif
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -25,15 +25,51 @@
|
||||
*
|
||||
* ***** END GPL LICENSE BLOCK *****
|
||||
*/
|
||||
|
||||
#ifndef ED_IMAGE_INTERN_H
|
||||
#define ED_IMAGE_INTERN_H
|
||||
|
||||
/* internal exports only */
|
||||
struct bContext;
|
||||
struct ARegion;
|
||||
struct SpaceImage;
|
||||
struct Object;
|
||||
struct Image;
|
||||
struct ImBuf;
|
||||
struct wmOperatorType;
|
||||
struct Scene;
|
||||
|
||||
/* space_image.c */
|
||||
struct Image *get_space_image(struct SpaceImage *sima);
|
||||
void set_space_image(struct SpaceImage *sima, struct Scene *scene, struct Object *obedit, struct Image *ima);
|
||||
|
||||
struct ImBuf *get_space_image_buffer(struct SpaceImage *sima);
|
||||
void get_space_image_size(struct SpaceImage *sima, int *width, int *height);
|
||||
void get_space_image_aspect(struct SpaceImage *sima, float *aspx, float *aspy);
|
||||
void get_space_image_zoom(struct SpaceImage *sima, struct ARegion *ar, float *zoomx, float *zoomy);
|
||||
|
||||
int get_space_image_show_render(struct SpaceImage *sima);
|
||||
int get_space_image_show_paint(struct SpaceImage *sima);
|
||||
int get_space_image_show_uvedit(struct SpaceImage *sima, struct Object *obedit);
|
||||
int get_space_image_show_uvshadow(struct SpaceImage *sima, struct Object *obedit);
|
||||
|
||||
/* image_header.c */
|
||||
void image_header_buttons(const bContext *C, ARegion *ar);
|
||||
void image_header_buttons(const struct bContext *C, struct ARegion *ar);
|
||||
|
||||
/* image_draw.c */
|
||||
void draw_image_main(struct SpaceImage *sima, struct ARegion *ar, struct Scene *scene);
|
||||
|
||||
/* image_ops.c */
|
||||
void IMAGE_OT_view_all(struct wmOperatorType *ot);
|
||||
void IMAGE_OT_view_pan(struct wmOperatorType *ot);
|
||||
void IMAGE_OT_view_selected(struct wmOperatorType *ot);
|
||||
void IMAGE_OT_view_zoom(struct wmOperatorType *ot);
|
||||
void IMAGE_OT_view_zoom_in(struct wmOperatorType *ot);
|
||||
void IMAGE_OT_view_zoom_out(struct wmOperatorType *ot);
|
||||
void IMAGE_OT_view_zoom_ratio(struct wmOperatorType *ot);
|
||||
|
||||
/* uvedit_draw.c */
|
||||
void draw_uvedit_main(struct SpaceImage *sima, struct ARegion *ar, struct Scene *scene, struct Object *obedit);
|
||||
|
||||
#endif /* ED_IMAGE_INTERN_H */
|
||||
|
||||
|
||||
1178
source/blender/editors/space_image/image_ops.c
Normal file
1178
source/blender/editors/space_image/image_ops.c
Normal file
File diff suppressed because it is too large
Load Diff
631
source/blender/editors/space_image/image_panels.c
Normal file
631
source/blender/editors/space_image/image_panels.c
Normal file
@@ -0,0 +1,631 @@
|
||||
/**
|
||||
* $Id$
|
||||
*
|
||||
* ***** BEGIN GPL LICENSE BLOCK *****
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*
|
||||
* The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Contributor(s): Blender Foundation, 2002-2009
|
||||
*
|
||||
* ***** END GPL LICENSE BLOCK *****
|
||||
*/
|
||||
|
||||
#if 0
|
||||
|
||||
/* ************ panel stuff ************* */
|
||||
|
||||
/* this function gets the values for cursor and vertex number buttons */
|
||||
static void image_transform_but_attr(int *imx, int *imy, int *step, int *digits) /*, float *xcoord, float *ycoord)*/
|
||||
{
|
||||
ImBuf *ibuf= imagewindow_get_ibuf(G.sima);
|
||||
if(ibuf) {
|
||||
*imx= ibuf->x;
|
||||
*imy= ibuf->y;
|
||||
}
|
||||
|
||||
if (G.sima->flag & SI_COORDFLOATS) {
|
||||
*step= 1;
|
||||
*digits= 3;
|
||||
}
|
||||
else {
|
||||
*step= 100;
|
||||
*digits= 2;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* is used for both read and write... */
|
||||
void image_editvertex_buts(uiBlock *block)
|
||||
{
|
||||
static float ocent[2];
|
||||
float cent[2]= {0.0, 0.0};
|
||||
int imx= 256, imy= 256;
|
||||
int nactive= 0, step, digits;
|
||||
EditMesh *em = G.editMesh;
|
||||
EditFace *efa;
|
||||
MTFace *tf;
|
||||
|
||||
if( is_uv_tface_editing_allowed_silent()==0 ) return;
|
||||
|
||||
image_transform_but_attr(&imx, &imy, &step, &digits);
|
||||
|
||||
for (efa= em->faces.first; efa; efa= efa->next) {
|
||||
tf= CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
|
||||
if (simaFaceDraw_Check(efa, tf)) {
|
||||
|
||||
if (simaUVSel_Check(efa, tf, 0)) {
|
||||
cent[0]+= tf->uv[0][0];
|
||||
cent[1]+= tf->uv[0][1];
|
||||
nactive++;
|
||||
}
|
||||
if (simaUVSel_Check(efa, tf, 1)) {
|
||||
cent[0]+= tf->uv[1][0];
|
||||
cent[1]+= tf->uv[1][1];
|
||||
nactive++;
|
||||
}
|
||||
if (simaUVSel_Check(efa, tf, 2)) {
|
||||
cent[0]+= tf->uv[2][0];
|
||||
cent[1]+= tf->uv[2][1];
|
||||
nactive++;
|
||||
}
|
||||
if (efa->v4 && simaUVSel_Check(efa, tf, 3)) {
|
||||
cent[0]+= tf->uv[3][0];
|
||||
cent[1]+= tf->uv[3][1];
|
||||
nactive++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(block) { // do the buttons
|
||||
if (nactive) {
|
||||
ocent[0]= cent[0]/nactive;
|
||||
ocent[1]= cent[1]/nactive;
|
||||
if (G.sima->flag & SI_COORDFLOATS) {
|
||||
} else {
|
||||
ocent[0] *= imx;
|
||||
ocent[1] *= imy;
|
||||
}
|
||||
|
||||
//uiBlockBeginAlign(block);
|
||||
if(nactive==1) {
|
||||
uiDefButF(block, NUM, B_TRANS_IMAGE, "Vertex X:", 10, 10, 145, 19, &ocent[0], -10*imx, 10.0*imx, step, digits, "");
|
||||
uiDefButF(block, NUM, B_TRANS_IMAGE, "Vertex Y:", 165, 10, 145, 19, &ocent[1], -10*imy, 10.0*imy, step, digits, "");
|
||||
}
|
||||
else {
|
||||
uiDefButF(block, NUM, B_TRANS_IMAGE, "Median X:", 10, 10, 145, 19, &ocent[0], -10*imx, 10.0*imx, step, digits, "");
|
||||
uiDefButF(block, NUM, B_TRANS_IMAGE, "Median Y:", 165, 10, 145, 19, &ocent[1], -10*imy, 10.0*imy, step, digits, "");
|
||||
}
|
||||
//uiBlockEndAlign(block);
|
||||
}
|
||||
}
|
||||
else { // apply event
|
||||
float delta[2];
|
||||
|
||||
cent[0]= cent[0]/nactive;
|
||||
cent[1]= cent[1]/nactive;
|
||||
|
||||
if (G.sima->flag & SI_COORDFLOATS) {
|
||||
delta[0]= ocent[0]-cent[0];
|
||||
delta[1]= ocent[1]-cent[1];
|
||||
}
|
||||
else {
|
||||
delta[0]= ocent[0]/imx - cent[0];
|
||||
delta[1]= ocent[1]/imy - cent[1];
|
||||
}
|
||||
|
||||
for (efa= em->faces.first; efa; efa= efa->next) {
|
||||
tf= CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
|
||||
if (simaFaceDraw_Check(efa, tf)) {
|
||||
if (simaUVSel_Check(efa, tf, 0)) {
|
||||
tf->uv[0][0]+= delta[0];
|
||||
tf->uv[0][1]+= delta[1];
|
||||
}
|
||||
if (simaUVSel_Check(efa, tf, 1)) {
|
||||
tf->uv[1][0]+= delta[0];
|
||||
tf->uv[1][1]+= delta[1];
|
||||
}
|
||||
if (simaUVSel_Check(efa, tf, 2)) {
|
||||
tf->uv[2][0]+= delta[0];
|
||||
tf->uv[2][1]+= delta[1];
|
||||
}
|
||||
if (efa->v4 && simaUVSel_Check(efa, tf, 3)) {
|
||||
tf->uv[3][0]+= delta[0];
|
||||
tf->uv[3][1]+= delta[1];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
allqueue(REDRAWVIEW3D, 0);
|
||||
allqueue(REDRAWIMAGE, 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* is used for both read and write... */
|
||||
void image_editcursor_buts(uiBlock *block)
|
||||
{
|
||||
static float ocent[2];
|
||||
int imx= 256, imy= 256;
|
||||
int step, digits;
|
||||
|
||||
if( is_uv_tface_editing_allowed_silent()==0 ) return;
|
||||
|
||||
image_transform_but_attr(&imx, &imy, &step, &digits);
|
||||
|
||||
if(block) { // do the buttons
|
||||
ocent[0]= G.v2d->cursor[0];
|
||||
ocent[1]= G.v2d->cursor[1];
|
||||
if (G.sima->flag & SI_COORDFLOATS) {
|
||||
} else {
|
||||
ocent[0] *= imx;
|
||||
ocent[1] *= imy;
|
||||
}
|
||||
|
||||
uiBlockBeginAlign(block);
|
||||
uiDefButF(block, NUM, B_CURSOR_IMAGE, "Cursor X:", 165, 120, 145, 19, &ocent[0], -10*imx, 10.0*imx, step, digits, "");
|
||||
uiDefButF(block, NUM, B_CURSOR_IMAGE, "Cursor Y:", 165, 100, 145, 19, &ocent[1], -10*imy, 10.0*imy, step, digits, "");
|
||||
uiBlockEndAlign(block);
|
||||
}
|
||||
else { // apply event
|
||||
if (G.sima->flag & SI_COORDFLOATS) {
|
||||
G.v2d->cursor[0]= ocent[0];
|
||||
G.v2d->cursor[1]= ocent[1];
|
||||
}
|
||||
else {
|
||||
G.v2d->cursor[0]= ocent[0]/imx;
|
||||
G.v2d->cursor[1]= ocent[1]/imy;
|
||||
}
|
||||
allqueue(REDRAWIMAGE, 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void image_info(Image *ima, ImBuf *ibuf, char *str)
|
||||
{
|
||||
int ofs= 0;
|
||||
|
||||
str[0]= 0;
|
||||
|
||||
if(ima==NULL) return;
|
||||
if(ibuf==NULL) {
|
||||
sprintf(str, "Can not get an image");
|
||||
return;
|
||||
}
|
||||
|
||||
if(ima->source==IMA_SRC_MOVIE) {
|
||||
ofs= sprintf(str, "Movie ");
|
||||
if(ima->anim)
|
||||
ofs+= sprintf(str+ofs, "%d frs", IMB_anim_get_duration(ima->anim));
|
||||
}
|
||||
else
|
||||
ofs= sprintf(str, "Image ");
|
||||
|
||||
ofs+= sprintf(str+ofs, ": size %d x %d,", ibuf->x, ibuf->y);
|
||||
|
||||
if(ibuf->rect_float) {
|
||||
if(ibuf->channels!=4) {
|
||||
sprintf(str+ofs, "%d float channel(s)", ibuf->channels);
|
||||
}
|
||||
else if(ibuf->depth==32)
|
||||
strcat(str, " RGBA float");
|
||||
else
|
||||
strcat(str, " RGB float");
|
||||
}
|
||||
else {
|
||||
if(ibuf->depth==32)
|
||||
strcat(str, " RGBA byte");
|
||||
else
|
||||
strcat(str, " RGB byte");
|
||||
}
|
||||
if(ibuf->zbuf || ibuf->zbuf_float)
|
||||
strcat(str, " + Z");
|
||||
|
||||
}
|
||||
|
||||
static void image_panel_properties(short cntrl) // IMAGE_HANDLER_PROPERTIES
|
||||
{
|
||||
uiBlock *block;
|
||||
|
||||
block= uiNewBlock(&curarea->uiblocks, "image_panel_properties", UI_EMBOSS, UI_HELV, curarea->win);
|
||||
uiPanelControl(UI_PNL_SOLID | UI_PNL_CLOSE | cntrl);
|
||||
uiSetPanelHandler(IMAGE_HANDLER_PROPERTIES); // for close and esc
|
||||
if(uiNewPanel(curarea, block, "Image Properties", "Image", 10, 10, 318, 204)==0)
|
||||
return;
|
||||
|
||||
/* note, it draws no bottom half in facemode, for vertex buttons */
|
||||
uiblock_image_panel(block, &G.sima->image, &G.sima->iuser, B_REDR, B_REDR);
|
||||
image_editvertex_buts(block);
|
||||
}
|
||||
|
||||
static void image_panel_game_properties(short cntrl) // IMAGE_HANDLER_GAME_PROPERTIES
|
||||
{
|
||||
ImBuf *ibuf= BKE_image_get_ibuf(G.sima->image, &G.sima->iuser);
|
||||
uiBlock *block;
|
||||
|
||||
block= uiNewBlock(&curarea->uiblocks, "image_panel_game_properties", UI_EMBOSS, UI_HELV, curarea->win);
|
||||
uiPanelControl(UI_PNL_SOLID | UI_PNL_CLOSE | cntrl);
|
||||
uiSetPanelHandler(IMAGE_HANDLER_GAME_PROPERTIES); // for close and esc
|
||||
if(uiNewPanel(curarea, block, "Real-time Properties", "Image", 10, 10, 318, 204)==0)
|
||||
return;
|
||||
|
||||
if (ibuf) {
|
||||
char str[128];
|
||||
|
||||
image_info(G.sima->image, ibuf, str);
|
||||
uiDefBut(block, LABEL, B_NOP, str, 10,180,300,19, 0, 0, 0, 0, 0, "");
|
||||
|
||||
uiBlockBeginAlign(block);
|
||||
uiDefButBitS(block, TOG, IMA_TWINANIM, B_TWINANIM, "Anim", 10,150,140,19, &G.sima->image->tpageflag, 0, 0, 0, 0, "Toggles use of animated texture");
|
||||
uiDefButS(block, NUM, B_TWINANIM, "Start:", 10,130,140,19, &G.sima->image->twsta, 0.0, 128.0, 0, 0, "Displays the start frame of an animated texture");
|
||||
uiDefButS(block, NUM, B_TWINANIM, "End:", 10,110,140,19, &G.sima->image->twend, 0.0, 128.0, 0, 0, "Displays the end frame of an animated texture");
|
||||
uiDefButS(block, NUM, B_NOP, "Speed", 10,90,140,19, &G.sima->image->animspeed, 1.0, 100.0, 0, 0, "Displays Speed of the animation in frames per second");
|
||||
uiBlockEndAlign(block);
|
||||
|
||||
uiBlockBeginAlign(block);
|
||||
uiDefButBitS(block, TOG, IMA_TILES, B_SIMAGETILE, "Tiles", 160,150,140,19, &G.sima->image->tpageflag, 0, 0, 0, 0, "Toggles use of tilemode for faces (Shift LMB to pick the tile for selected faces)");
|
||||
uiDefButS(block, NUM, B_SIMA_REDR_IMA_3D, "X:", 160,130,70,19, &G.sima->image->xrep, 1.0, 16.0, 0, 0, "Sets the degree of repetition in the X direction");
|
||||
uiDefButS(block, NUM, B_SIMA_REDR_IMA_3D, "Y:", 230,130,70,19, &G.sima->image->yrep, 1.0, 16.0, 0, 0, "Sets the degree of repetition in the Y direction");
|
||||
uiBlockBeginAlign(block);
|
||||
|
||||
uiBlockBeginAlign(block);
|
||||
uiDefButBitS(block, TOG, IMA_CLAMP_U, B_SIMA3DVIEWDRAW, "ClampX", 160,100,70,19, &G.sima->image->tpageflag, 0, 0, 0, 0, "Disable texture repeating horizontaly");
|
||||
uiDefButBitS(block, TOG, IMA_CLAMP_V, B_SIMA3DVIEWDRAW, "ClampY", 230,100,70,19, &G.sima->image->tpageflag, 0, 0, 0, 0, "Disable texture repeating vertically");
|
||||
uiBlockEndAlign(block);
|
||||
}
|
||||
}
|
||||
|
||||
static void image_panel_view_properties(short cntrl) // IMAGE_HANDLER_VIEW_PROPERTIES
|
||||
{
|
||||
uiBlock *block;
|
||||
|
||||
block= uiNewBlock(&curarea->uiblocks, "image_view_properties", UI_EMBOSS, UI_HELV, curarea->win);
|
||||
uiPanelControl(UI_PNL_SOLID | UI_PNL_CLOSE | cntrl);
|
||||
uiSetPanelHandler(IMAGE_HANDLER_VIEW_PROPERTIES); // for close and esc
|
||||
if(uiNewPanel(curarea, block, "View Properties", "Image", 10, 10, 318, 204)==0)
|
||||
return;
|
||||
|
||||
|
||||
uiDefButBitI(block, TOG, SI_DRAW_TILE, B_REDR, "Repeat Image", 10,160,140,19, &G.sima->flag, 0, 0, 0, 0, "Repeat/Tile the image display");
|
||||
uiDefButBitI(block, TOG, SI_COORDFLOATS, B_REDR, "Normalized Coords", 165,160,145,19, &G.sima->flag, 0, 0, 0, 0, "Display coords from 0.0 to 1.0 rather then in pixels");
|
||||
|
||||
|
||||
if (G.sima->image) {
|
||||
uiDefBut(block, LABEL, B_NOP, "Image Display:", 10,140,140,19, 0, 0, 0, 0, 0, "");
|
||||
uiBlockBeginAlign(block);
|
||||
uiDefButF(block, NUM, B_REDR, "AspX:", 10,120,140,19, &G.sima->image->aspx, 0.1, 5000.0, 100, 0, "X Display Aspect for this image, does not affect renderingm 0 disables.");
|
||||
uiDefButF(block, NUM, B_REDR, "AspY:", 10,100,140,19, &G.sima->image->aspy, 0.1, 5000.0, 100, 0, "X Display Aspect for this image, does not affect rendering 0 disables.");
|
||||
uiBlockEndAlign(block);
|
||||
}
|
||||
|
||||
|
||||
if (EM_texFaceCheck()) {
|
||||
uiDefBut(block, LABEL, B_NOP, "Draw Type:", 10, 80,120,19, 0, 0, 0, 0, 0, "");
|
||||
uiBlockBeginAlign(block);
|
||||
uiDefButC(block, ROW, B_REDR, "Outline", 10,60,58,19, &G.sima->dt_uv, 0.0, SI_UVDT_OUTLINE, 0, 0, "Outline Wire UV drawtype");
|
||||
uiDefButC(block, ROW, B_REDR, "Dash", 68, 60,58,19, &G.sima->dt_uv, 0.0, SI_UVDT_DASH, 0, 0, "Dashed Wire UV drawtype");
|
||||
uiDefButC(block, ROW, B_REDR, "Black", 126, 60,58,19, &G.sima->dt_uv, 0.0, SI_UVDT_BLACK, 0, 0, "Black Wire UV drawtype");
|
||||
uiDefButC(block, ROW, B_REDR, "White", 184,60,58,19, &G.sima->dt_uv, 0.0, SI_UVDT_WHITE, 0, 0, "White Wire UV drawtype");
|
||||
|
||||
uiBlockEndAlign(block);
|
||||
uiDefButBitI(block, TOG, SI_SMOOTH_UV, B_REDR, "Smooth", 250,60,60,19, &G.sima->flag, 0, 0, 0, 0, "Display smooth lines in the UV view");
|
||||
|
||||
|
||||
uiDefButBitI(block, TOG, G_DRAWFACES, B_REDR, "Faces", 10,30,60,19, &G.f, 0, 0, 0, 0, "Displays all faces as shades in the 3d view and UV editor");
|
||||
uiDefButBitI(block, TOG, G_DRAWEDGES, B_REDR, "Edges", 70, 30,60,19, &G.f, 0, 0, 0, 0, "Displays selected edges using hilights in the 3d view and UV editor");
|
||||
|
||||
uiDefButBitI(block, TOG, SI_DRAWSHADOW, B_REDR, "Final Shadow", 130, 30,110,19, &G.sima->flag, 0, 0, 0, 0, "Draw the final result from the objects modifiers");
|
||||
|
||||
uiDefButBitI(block, TOG, SI_DRAW_STRETCH, B_REDR, "UV Stretch", 10,0,100,19, &G.sima->flag, 0, 0, 0, 0, "Difference between UV's and the 3D coords (blue for low distortion, red is high)");
|
||||
if (G.sima->flag & SI_DRAW_STRETCH) {
|
||||
uiBlockBeginAlign(block);
|
||||
uiDefButC(block, ROW, B_REDR, "Area", 120,0,60,19, &G.sima->dt_uvstretch, 0.0, SI_UVDT_STRETCH_AREA, 0, 0, "Area distortion between UV's and 3D coords");
|
||||
uiDefButC(block, ROW, B_REDR, "Angle", 180,0,60,19, &G.sima->dt_uvstretch, 0.0, SI_UVDT_STRETCH_ANGLE, 0, 0, "Angle distortion between UV's and 3D coords");
|
||||
uiBlockEndAlign(block);
|
||||
}
|
||||
|
||||
}
|
||||
image_editcursor_buts(block);
|
||||
}
|
||||
|
||||
static void image_panel_paint(short cntrl) // IMAGE_HANDLER_PAINT
|
||||
{
|
||||
uiBlock *block;
|
||||
if ((G.sima->image && (G.sima->flag & SI_DRAWTOOL))==0) {
|
||||
return;
|
||||
}
|
||||
|
||||
block= uiNewBlock(&curarea->uiblocks, "image_panel_paint", UI_EMBOSS, UI_HELV, curarea->win);
|
||||
uiPanelControl(UI_PNL_SOLID | UI_PNL_CLOSE | cntrl);
|
||||
uiSetPanelHandler(IMAGE_HANDLER_PAINT); // for close and esc
|
||||
if(uiNewPanel(curarea, block, "Image Paint", "Image", 10, 230, 318, 204)==0)
|
||||
return;
|
||||
|
||||
brush_buttons(block, 1, B_SIMANOTHING, B_SIMABRUSHCHANGE, B_SIMABRUSHBROWSE, B_SIMABRUSHLOCAL, B_SIMABRUSHDELETE, B_KEEPDATA, B_SIMABTEXBROWSE, B_SIMABTEXDELETE);
|
||||
}
|
||||
|
||||
static void image_panel_curves_reset(void *cumap_v, void *ibuf_v)
|
||||
{
|
||||
CurveMapping *cumap = cumap_v;
|
||||
int a;
|
||||
|
||||
for(a=0; a<CM_TOT; a++)
|
||||
curvemap_reset(cumap->cm+a, &cumap->clipr);
|
||||
|
||||
cumap->black[0]=cumap->black[1]=cumap->black[2]= 0.0f;
|
||||
cumap->white[0]=cumap->white[1]=cumap->white[2]= 1.0f;
|
||||
curvemapping_set_black_white(cumap, NULL, NULL);
|
||||
|
||||
curvemapping_changed(cumap, 0);
|
||||
curvemapping_do_ibuf(cumap, ibuf_v);
|
||||
|
||||
allqueue(REDRAWIMAGE, 0);
|
||||
}
|
||||
|
||||
|
||||
static void image_panel_curves(short cntrl) // IMAGE_HANDLER_CURVES
|
||||
{
|
||||
ImBuf *ibuf;
|
||||
uiBlock *block;
|
||||
uiBut *bt;
|
||||
|
||||
/* and we check for spare */
|
||||
ibuf= imagewindow_get_ibuf(G.sima);
|
||||
|
||||
block= uiNewBlock(&curarea->uiblocks, "image_panel_curves", UI_EMBOSS, UI_HELV, curarea->win);
|
||||
uiPanelControl(UI_PNL_SOLID | UI_PNL_CLOSE | cntrl);
|
||||
uiSetPanelHandler(IMAGE_HANDLER_CURVES); // for close and esc
|
||||
if(uiNewPanel(curarea, block, "Curves", "Image", 10, 450, 318, 204)==0)
|
||||
return;
|
||||
|
||||
if (ibuf) {
|
||||
rctf rect;
|
||||
|
||||
if(G.sima->cumap==NULL)
|
||||
G.sima->cumap= curvemapping_add(4, 0.0f, 0.0f, 1.0f, 1.0f);
|
||||
|
||||
rect.xmin= 110; rect.xmax= 310;
|
||||
rect.ymin= 10; rect.ymax= 200;
|
||||
curvemap_buttons(block, G.sima->cumap, 'c', B_SIMACURVES, B_REDR, &rect);
|
||||
|
||||
/* curvemap min/max only works for RGBA */
|
||||
if(ibuf->channels==4) {
|
||||
bt=uiDefBut(block, BUT, B_SIMARANGE, "Reset", 10, 160, 90, 19, NULL, 0.0f, 0.0f, 0, 0, "Reset Black/White point and curves");
|
||||
uiButSetFunc(bt, image_panel_curves_reset, G.sima->cumap, ibuf);
|
||||
|
||||
uiBlockBeginAlign(block);
|
||||
uiDefButF(block, NUM, B_SIMARANGE, "Min R:", 10, 120, 90, 19, G.sima->cumap->black, -1000.0f, 1000.0f, 10, 2, "Black level");
|
||||
uiDefButF(block, NUM, B_SIMARANGE, "Min G:", 10, 100, 90, 19, G.sima->cumap->black+1, -1000.0f, 1000.0f, 10, 2, "Black level");
|
||||
uiDefButF(block, NUM, B_SIMARANGE, "Min B:", 10, 80, 90, 19, G.sima->cumap->black+2, -1000.0f, 1000.0f, 10, 2, "Black level");
|
||||
|
||||
uiBlockBeginAlign(block);
|
||||
uiDefButF(block, NUM, B_SIMARANGE, "Max R:", 10, 50, 90, 19, G.sima->cumap->white, -1000.0f, 1000.0f, 10, 2, "White level");
|
||||
uiDefButF(block, NUM, B_SIMARANGE, "Max G:", 10, 30, 90, 19, G.sima->cumap->white+1, -1000.0f, 1000.0f, 10, 2, "White level");
|
||||
uiDefButF(block, NUM, B_SIMARANGE, "Max B:", 10, 10, 90, 19, G.sima->cumap->white+2, -1000.0f, 1000.0f, 10, 2, "White level");
|
||||
}
|
||||
}
|
||||
}
|
||||
/* 0: disable preview
|
||||
otherwise refresh preview
|
||||
*/
|
||||
void image_preview_event(int event)
|
||||
{
|
||||
int exec= 0;
|
||||
|
||||
|
||||
if(event==0) {
|
||||
G.scene->r.scemode &= ~R_COMP_CROP;
|
||||
exec= 1;
|
||||
}
|
||||
else {
|
||||
if(image_preview_active(curarea, NULL, NULL)) {
|
||||
G.scene->r.scemode |= R_COMP_CROP;
|
||||
exec= 1;
|
||||
}
|
||||
else
|
||||
G.scene->r.scemode &= ~R_COMP_CROP;
|
||||
}
|
||||
|
||||
if(exec && G.scene->nodetree) {
|
||||
/* should work when no node editor in screen..., so we execute right away */
|
||||
|
||||
ntreeCompositTagGenerators(G.scene->nodetree);
|
||||
|
||||
G.afbreek= 0;
|
||||
G.scene->nodetree->timecursor= set_timecursor;
|
||||
G.scene->nodetree->test_break= blender_test_break;
|
||||
|
||||
BIF_store_spare();
|
||||
|
||||
ntreeCompositExecTree(G.scene->nodetree, &G.scene->r, 1); /* 1 is do_previews */
|
||||
|
||||
G.scene->nodetree->timecursor= NULL;
|
||||
G.scene->nodetree->test_break= NULL;
|
||||
|
||||
scrarea_do_windraw(curarea);
|
||||
waitcursor(0);
|
||||
|
||||
allqueue(REDRAWNODE, 1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* nothing drawn here, we use it to store values */
|
||||
static void preview_cb(struct ScrArea *sa, struct uiBlock *block)
|
||||
{
|
||||
rctf dispf;
|
||||
rcti *disprect= &G.scene->r.disprect;
|
||||
int winx= (G.scene->r.size*G.scene->r.xsch)/100;
|
||||
int winy= (G.scene->r.size*G.scene->r.ysch)/100;
|
||||
short mval[2];
|
||||
|
||||
if(G.scene->r.mode & R_BORDER) {
|
||||
winx*= (G.scene->r.border.xmax - G.scene->r.border.xmin);
|
||||
winy*= (G.scene->r.border.ymax - G.scene->r.border.ymin);
|
||||
}
|
||||
|
||||
/* while dragging we need to update the rects, otherwise it doesn't end with correct one */
|
||||
|
||||
BLI_init_rctf(&dispf, 15.0f, (block->maxx - block->minx)-15.0f, 15.0f, (block->maxy - block->miny)-15.0f);
|
||||
ui_graphics_to_window_rct(sa->win, &dispf, disprect);
|
||||
|
||||
/* correction for gla draw */
|
||||
BLI_translate_rcti(disprect, -curarea->winrct.xmin, -curarea->winrct.ymin);
|
||||
|
||||
calc_image_view(G.sima, 'p');
|
||||
// printf("winrct %d %d %d %d\n", disprect->xmin, disprect->ymin,disprect->xmax, disprect->ymax);
|
||||
/* map to image space coordinates */
|
||||
mval[0]= disprect->xmin; mval[1]= disprect->ymin;
|
||||
areamouseco_to_ipoco(G.v2d, mval, &dispf.xmin, &dispf.ymin);
|
||||
mval[0]= disprect->xmax; mval[1]= disprect->ymax;
|
||||
areamouseco_to_ipoco(G.v2d, mval, &dispf.xmax, &dispf.ymax);
|
||||
|
||||
/* map to render coordinates */
|
||||
disprect->xmin= dispf.xmin;
|
||||
disprect->xmax= dispf.xmax;
|
||||
disprect->ymin= dispf.ymin;
|
||||
disprect->ymax= dispf.ymax;
|
||||
|
||||
CLAMP(disprect->xmin, 0, winx);
|
||||
CLAMP(disprect->xmax, 0, winx);
|
||||
CLAMP(disprect->ymin, 0, winy);
|
||||
CLAMP(disprect->ymax, 0, winy);
|
||||
// printf("drawrct %d %d %d %d\n", disprect->xmin, disprect->ymin,disprect->xmax, disprect->ymax);
|
||||
|
||||
}
|
||||
|
||||
static int is_preview_allowed(ScrArea *cur)
|
||||
{
|
||||
SpaceImage *sima= cur->spacedata.first;
|
||||
ScrArea *sa;
|
||||
|
||||
/* check if another areawindow has preview set */
|
||||
for(sa=G.curscreen->areabase.first; sa; sa= sa->next) {
|
||||
if(sa!=cur && sa->spacetype==SPACE_IMAGE) {
|
||||
if(image_preview_active(sa, NULL, NULL))
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
/* check image type */
|
||||
if(sima->image==NULL || sima->image->type!=IMA_TYPE_COMPOSITE)
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void image_panel_preview(ScrArea *sa, short cntrl) // IMAGE_HANDLER_PREVIEW
|
||||
{
|
||||
uiBlock *block;
|
||||
SpaceImage *sima= sa->spacedata.first;
|
||||
int ofsx, ofsy;
|
||||
|
||||
if(is_preview_allowed(sa)==0) {
|
||||
rem_blockhandler(sa, IMAGE_HANDLER_PREVIEW);
|
||||
G.scene->r.scemode &= ~R_COMP_CROP; /* quite weak */
|
||||
return;
|
||||
}
|
||||
|
||||
block= uiNewBlock(&sa->uiblocks, "image_panel_preview", UI_EMBOSS, UI_HELV, sa->win);
|
||||
uiPanelControl(UI_PNL_SOLID | UI_PNL_CLOSE | UI_PNL_SCALE | cntrl);
|
||||
uiSetPanelHandler(IMAGE_HANDLER_PREVIEW); // for close and esc
|
||||
|
||||
ofsx= -150+(sa->winx/2)/sima->blockscale;
|
||||
ofsy= -100+(sa->winy/2)/sima->blockscale;
|
||||
if(uiNewPanel(sa, block, "Preview", "Image", ofsx, ofsy, 300, 200)==0) return;
|
||||
|
||||
uiBlockSetDrawExtraFunc(block, preview_cb);
|
||||
|
||||
}
|
||||
|
||||
static void image_panel_gpencil(short cntrl) // IMAGE_HANDLER_GREASEPENCIL
|
||||
{
|
||||
uiBlock *block;
|
||||
SpaceImage *sima;
|
||||
|
||||
sima= curarea->spacedata.first;
|
||||
|
||||
block= uiNewBlock(&curarea->uiblocks, "image_panel_gpencil", UI_EMBOSS, UI_HELV, curarea->win);
|
||||
uiPanelControl(UI_PNL_SOLID | UI_PNL_CLOSE | cntrl);
|
||||
uiSetPanelHandler(IMAGE_HANDLER_GREASEPENCIL); // for close and esc
|
||||
if (uiNewPanel(curarea, block, "Grease Pencil", "SpaceImage", 100, 30, 318, 204)==0) return;
|
||||
|
||||
/* allocate memory for gpd if drawing enabled (this must be done first or else we crash) */
|
||||
if (sima->flag & SI_DISPGP) {
|
||||
if (sima->gpd == NULL)
|
||||
gpencil_data_setactive(curarea, gpencil_data_addnew());
|
||||
}
|
||||
|
||||
if (sima->flag & SI_DISPGP) {
|
||||
bGPdata *gpd= sima->gpd;
|
||||
short newheight;
|
||||
|
||||
/* this is a variable height panel, newpanel doesnt force new size on existing panels */
|
||||
/* so first we make it default height */
|
||||
uiNewPanelHeight(block, 204);
|
||||
|
||||
/* draw button for showing gpencil settings and drawings */
|
||||
uiDefButBitI(block, TOG, SI_DISPGP, B_REDR, "Use Grease Pencil", 10, 225, 150, 20, &sima->flag, 0, 0, 0, 0, "Display freehand annotations overlay over this Image/UV Editor (draw using Shift-LMB)");
|
||||
|
||||
/* extend the panel if the contents won't fit */
|
||||
newheight= draw_gpencil_panel(block, gpd, curarea);
|
||||
uiNewPanelHeight(block, newheight);
|
||||
}
|
||||
else {
|
||||
uiDefButBitI(block, TOG, SI_DISPGP, B_REDR, "Use Grease Pencil", 10, 225, 150, 20, &sima->flag, 0, 0, 0, 0, "Display freehand annotations overlay over this Image/UV Editor");
|
||||
uiDefBut(block, LABEL, 1, " ", 160, 180, 150, 20, NULL, 0.0, 0.0, 0, 0, "");
|
||||
}
|
||||
}
|
||||
|
||||
static void image_blockhandlers(ScrArea *sa)
|
||||
{
|
||||
SpaceImage *sima= sa->spacedata.first;
|
||||
short a;
|
||||
|
||||
/* warning; blocks need to be freed each time, handlers dont remove */
|
||||
uiFreeBlocksWin(&sa->uiblocks, sa->win);
|
||||
|
||||
for(a=0; a<SPACE_MAXHANDLER; a+=2) {
|
||||
switch(sima->blockhandler[a]) {
|
||||
case IMAGE_HANDLER_PROPERTIES:
|
||||
image_panel_properties(sima->blockhandler[a+1]);
|
||||
break;
|
||||
case IMAGE_HANDLER_GAME_PROPERTIES:
|
||||
image_panel_game_properties(sima->blockhandler[a+1]);
|
||||
break;
|
||||
case IMAGE_HANDLER_VIEW_PROPERTIES:
|
||||
image_panel_view_properties(sima->blockhandler[a+1]);
|
||||
break;
|
||||
case IMAGE_HANDLER_PAINT:
|
||||
image_panel_paint(sima->blockhandler[a+1]);
|
||||
break;
|
||||
case IMAGE_HANDLER_CURVES:
|
||||
image_panel_curves(sima->blockhandler[a+1]);
|
||||
break;
|
||||
case IMAGE_HANDLER_PREVIEW:
|
||||
image_panel_preview(sa, sima->blockhandler[a+1]);
|
||||
break;
|
||||
case IMAGE_HANDLER_GREASEPENCIL:
|
||||
image_panel_gpencil(sima->blockhandler[a+1]);
|
||||
break;
|
||||
}
|
||||
/* clear action value for event */
|
||||
sima->blockhandler[a+1]= 0;
|
||||
}
|
||||
uiDrawBlocksPanels(sa, 0);
|
||||
}
|
||||
#endif
|
||||
|
||||
335
source/blender/editors/space_image/image_render.c
Normal file
335
source/blender/editors/space_image/image_render.c
Normal file
@@ -0,0 +1,335 @@
|
||||
/**
|
||||
* $Id$
|
||||
*
|
||||
* ***** BEGIN GPL LICENSE BLOCK *****
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*
|
||||
* The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Contributor(s): Blender Foundation, 2002-2009
|
||||
*
|
||||
* ***** END GPL LICENSE BLOCK *****
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "DNA_image_types.h"
|
||||
#include "DNA_screen_types.h"
|
||||
#include "DNA_space_types.h"
|
||||
|
||||
#include "BKE_context.h"
|
||||
#include "BKE_global.h"
|
||||
#include "BKE_image.h"
|
||||
|
||||
#include "BIF_gl.h"
|
||||
#include "BIF_glutil.h"
|
||||
|
||||
#include "RE_pipeline.h"
|
||||
|
||||
#define HEADER_HEIGHT 18
|
||||
|
||||
/* *********************** render callbacks ***************** */
|
||||
|
||||
/* set on initialize render, only one render output to imagewindow can exist, so the global isnt dangerous yet :) */
|
||||
static ScrArea *image_area= NULL;
|
||||
|
||||
/* can get as well the full picture, as the parts while rendering */
|
||||
static void imagewindow_progress(ScrArea *sa, RenderResult *rr, volatile rcti *renrect)
|
||||
{
|
||||
SpaceImage *sima= sa->spacedata.first;
|
||||
float x1, y1, *rectf= NULL;
|
||||
unsigned int *rect32= NULL;
|
||||
int ymin, ymax, xmin, xmax;
|
||||
|
||||
/* if renrect argument, we only display scanlines */
|
||||
if(renrect) {
|
||||
/* if ymax==recty, rendering of layer is ready, we should not draw, other things happen... */
|
||||
if(rr->renlay==NULL || renrect->ymax>=rr->recty)
|
||||
return;
|
||||
|
||||
/* xmin here is first subrect x coord, xmax defines subrect width */
|
||||
xmin = renrect->xmin;
|
||||
xmax = renrect->xmax - xmin;
|
||||
if (xmax<2) return;
|
||||
|
||||
ymin= renrect->ymin;
|
||||
ymax= renrect->ymax - ymin;
|
||||
if(ymax<2)
|
||||
return;
|
||||
renrect->ymin= renrect->ymax;
|
||||
}
|
||||
else {
|
||||
xmin = ymin = 0;
|
||||
xmax = rr->rectx - 2*rr->crop;
|
||||
ymax = rr->recty - 2*rr->crop;
|
||||
}
|
||||
|
||||
/* image window cruft */
|
||||
|
||||
/* find current float rect for display, first case is after composit... still weak */
|
||||
if(rr->rectf)
|
||||
rectf= rr->rectf;
|
||||
else {
|
||||
if(rr->rect32)
|
||||
rect32= (unsigned int *)rr->rect32;
|
||||
else {
|
||||
if(rr->renlay==NULL || rr->renlay->rectf==NULL) return;
|
||||
rectf= rr->renlay->rectf;
|
||||
}
|
||||
}
|
||||
if(rectf) {
|
||||
/* if scanline updates... */
|
||||
rectf+= 4*(rr->rectx*ymin + xmin);
|
||||
|
||||
/* when rendering more pixels than needed, we crop away cruft */
|
||||
if(rr->crop)
|
||||
rectf+= 4*(rr->crop*rr->rectx + rr->crop);
|
||||
}
|
||||
|
||||
/* tilerect defines drawing offset from (0,0) */
|
||||
/* however, tilerect (xmin, ymin) is first pixel */
|
||||
x1 = sima->centx + (rr->tilerect.xmin + rr->crop + xmin)*sima->zoom;
|
||||
y1 = sima->centy + (rr->tilerect.ymin + rr->crop + ymin)*sima->zoom;
|
||||
|
||||
/* needed for gla draw */
|
||||
// XXX { rcti rct= ar->winrct; rct.ymax-= HEADER_HEIGHT; glaDefine2DArea(&rct);}
|
||||
|
||||
glPixelZoom(sima->zoom, sima->zoom);
|
||||
|
||||
if(rect32)
|
||||
glaDrawPixelsSafe(x1, y1, xmax, ymax, rr->rectx, GL_RGBA, GL_UNSIGNED_BYTE, rect32);
|
||||
else
|
||||
glaDrawPixelsSafe_to32(x1, y1, xmax, ymax, rr->rectx, rectf);
|
||||
|
||||
glPixelZoom(1.0, 1.0);
|
||||
|
||||
}
|
||||
|
||||
/* in render window; display a couple of scanlines of rendered image */
|
||||
/* NOTE: called while render, so no malloc allowed! */
|
||||
static void imagewindow_progress_display_cb(RenderResult *rr, volatile rcti *rect)
|
||||
{
|
||||
if (image_area) {
|
||||
imagewindow_progress(image_area, rr, rect);
|
||||
|
||||
/* no screen_swapbuffers, prevent any other window to draw */
|
||||
// XXX myswapbuffers();
|
||||
}
|
||||
}
|
||||
|
||||
/* unused, init_display_cb is called on each render */
|
||||
static void imagewindow_clear_display_cb(RenderResult *rr)
|
||||
{
|
||||
if (image_area) {
|
||||
}
|
||||
}
|
||||
|
||||
/* returns biggest area that is not uv/image editor. Note that it uses buttons */
|
||||
/* window as the last possible alternative. */
|
||||
static ScrArea *biggest_non_image_area(bContext *C)
|
||||
{
|
||||
bScreen *sc= CTX_wm_screen(C);
|
||||
ScrArea *sa, *big= NULL;
|
||||
int size, maxsize= 0, bwmaxsize= 0;
|
||||
short foundwin= 0;
|
||||
|
||||
for(sa= sc->areabase.first; sa; sa= sa->next) {
|
||||
if(sa->winx > 10 && sa->winy > 10) {
|
||||
size= sa->winx*sa->winy;
|
||||
if(sa->spacetype == SPACE_BUTS) {
|
||||
if(foundwin == 0 && size > bwmaxsize) {
|
||||
bwmaxsize= size;
|
||||
big= sa;
|
||||
}
|
||||
}
|
||||
else if(sa->spacetype != SPACE_IMAGE && size > maxsize) {
|
||||
maxsize= size;
|
||||
big= sa;
|
||||
foundwin= 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return big;
|
||||
}
|
||||
|
||||
static ScrArea *biggest_area(bContext *C)
|
||||
{
|
||||
bScreen *sc= CTX_wm_screen(C);
|
||||
ScrArea *sa, *big= NULL;
|
||||
int size, maxsize= 0;
|
||||
|
||||
for(sa= sc->areabase.first; sa; sa= sa->next) {
|
||||
size= sa->winx*sa->winy;
|
||||
if(size > maxsize) {
|
||||
maxsize= size;
|
||||
big= sa;
|
||||
}
|
||||
}
|
||||
return big;
|
||||
}
|
||||
|
||||
|
||||
/* if R_DISPLAYIMAGE
|
||||
use Image Window showing Render Result
|
||||
else: turn largest non-image area into Image Window (not to frustrate texture or composite usage)
|
||||
else: then we use Image Window anyway...
|
||||
if R_DISPSCREEN
|
||||
make a new temp fullscreen area with Image Window
|
||||
*/
|
||||
|
||||
static ScrArea *find_area_showing_r_result(bContext *C)
|
||||
{
|
||||
bScreen *sc= CTX_wm_screen(C);
|
||||
ScrArea *sa;
|
||||
SpaceImage *sima;
|
||||
|
||||
/* find an imagewindow showing render result */
|
||||
for(sa=sc->areabase.first; sa; sa= sa->next) {
|
||||
if(sa->spacetype==SPACE_IMAGE) {
|
||||
sima= sa->spacedata.first;
|
||||
if(sima->image && sima->image->type==IMA_TYPE_R_RESULT)
|
||||
break;
|
||||
}
|
||||
}
|
||||
return sa;
|
||||
}
|
||||
|
||||
static ScrArea *imagewindow_set_render_display(bContext *C)
|
||||
{
|
||||
ScrArea *sa;
|
||||
SpaceImage *sima;
|
||||
|
||||
sa= find_area_showing_r_result(C);
|
||||
|
||||
if(sa==NULL) {
|
||||
/* find largest open non-image area */
|
||||
sa= biggest_non_image_area(C);
|
||||
if(sa) {
|
||||
// XXX newspace(sa, SPACE_IMAGE);
|
||||
sima= sa->spacedata.first;
|
||||
|
||||
/* makes ESC go back to prev space */
|
||||
sima->flag |= SI_PREVSPACE;
|
||||
}
|
||||
else {
|
||||
/* use any area of decent size */
|
||||
sa= biggest_area(C);
|
||||
if(sa->spacetype!=SPACE_IMAGE) {
|
||||
// XXX newspace(sa, SPACE_IMAGE);
|
||||
sima= sa->spacedata.first;
|
||||
|
||||
/* makes ESC go back to prev space */
|
||||
sima->flag |= SI_PREVSPACE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sima= sa->spacedata.first;
|
||||
|
||||
/* get the correct image, and scale it */
|
||||
sima->image= BKE_image_verify_viewer(IMA_TYPE_R_RESULT, "Render Result");
|
||||
|
||||
if(0) { // XXX G.displaymode==R_DISPLAYSCREEN) {
|
||||
if(sa->full==0) {
|
||||
sima->flag |= SI_FULLWINDOW;
|
||||
/* fullscreen works with lousy curarea */
|
||||
// XXX curarea= sa;
|
||||
// XXX area_fullscreen();
|
||||
// XXX sa= curarea;
|
||||
}
|
||||
}
|
||||
|
||||
return sa;
|
||||
}
|
||||
|
||||
static void imagewindow_init_display_cb(RenderResult *rr)
|
||||
{
|
||||
bContext *C= NULL; // XXX
|
||||
|
||||
image_area= imagewindow_set_render_display(C);
|
||||
|
||||
if(image_area) {
|
||||
SpaceImage *sima= image_area->spacedata.first;
|
||||
|
||||
// XXX areawinset(image_area->win);
|
||||
|
||||
/* calc location using original size (tiles don't tell) */
|
||||
sima->centx= (image_area->winx - sima->zoom*(float)rr->rectx)/2.0f;
|
||||
sima->centy= (image_area->winy - sima->zoom*(float)rr->recty)/2.0f;
|
||||
|
||||
sima->centx-= sima->zoom*sima->xof;
|
||||
sima->centy-= sima->zoom*sima->yof;
|
||||
|
||||
// XXX drawimagespace(image_area, sima);
|
||||
// XXX if(image_area->headertype) scrarea_do_headdraw(image_area);
|
||||
|
||||
/* no screen_swapbuffers, prevent any other window to draw */
|
||||
// XXX myswapbuffers();
|
||||
|
||||
// XXX allqueue(REDRAWIMAGE, 0); /* redraw in end */
|
||||
}
|
||||
}
|
||||
|
||||
/* coming from BIF_toggle_render_display() */
|
||||
void imagewindow_toggle_render(bContext *C)
|
||||
{
|
||||
bScreen *sc= CTX_wm_screen(C);
|
||||
ScrArea *sa;
|
||||
|
||||
/* check if any imagewindow is showing temporal render output */
|
||||
for(sa=sc->areabase.first; sa; sa= sa->next) {
|
||||
if(sa->spacetype==SPACE_IMAGE) {
|
||||
SpaceImage *sima= sa->spacedata.first;
|
||||
|
||||
if(sima->image && sima->image->type==IMA_TYPE_R_RESULT)
|
||||
if(sima->flag & (SI_PREVSPACE|SI_FULLWINDOW))
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(sa) {
|
||||
// XXX addqueue(sa->win, ESCKEY, 1); /* also returns from fullscreen */
|
||||
}
|
||||
else {
|
||||
sa= imagewindow_set_render_display(C);
|
||||
// XXX scrarea_queue_headredraw(sa);
|
||||
// XXX scrarea_queue_winredraw(sa);
|
||||
}
|
||||
}
|
||||
|
||||
/* NOTE: called while render, so no malloc allowed! */
|
||||
static void imagewindow_renderinfo_cb(RenderStats *rs)
|
||||
{
|
||||
if(image_area) {
|
||||
// XXX BIF_make_render_text(rs);
|
||||
|
||||
// XXX sima_draw_render_info(sima, ar);
|
||||
|
||||
/* no screen_swapbuffers, prevent any other window to draw */
|
||||
// XXX myswapbuffers();
|
||||
}
|
||||
}
|
||||
|
||||
void imagewindow_render_callbacks(Render *re)
|
||||
{
|
||||
RE_display_init_cb(re, imagewindow_init_display_cb);
|
||||
RE_display_draw_cb(re, imagewindow_progress_display_cb);
|
||||
RE_display_clear_cb(re, imagewindow_clear_display_cb);
|
||||
RE_stats_draw_cb(re, imagewindow_renderinfo_cb);
|
||||
}
|
||||
|
||||
@@ -30,6 +30,8 @@
|
||||
#include <stdio.h>
|
||||
|
||||
#include "DNA_image_types.h"
|
||||
#include "DNA_mesh_types.h"
|
||||
#include "DNA_meshdata_types.h"
|
||||
#include "DNA_object_types.h"
|
||||
#include "DNA_space_types.h"
|
||||
#include "DNA_scene_types.h"
|
||||
@@ -39,16 +41,27 @@
|
||||
|
||||
#include "BLI_blenlib.h"
|
||||
#include "BLI_arithb.h"
|
||||
#include "BLI_editVert.h"
|
||||
#include "BLI_rand.h"
|
||||
|
||||
#include "BKE_colortools.h"
|
||||
#include "BKE_context.h"
|
||||
#include "BKE_image.h"
|
||||
#include "BKE_screen.h"
|
||||
#include "BKE_utildefines.h"
|
||||
|
||||
#include "IMB_imbuf.h"
|
||||
#include "IMB_imbuf_types.h"
|
||||
|
||||
#include "ED_mesh.h"
|
||||
#include "ED_space_api.h"
|
||||
#include "ED_screen.h"
|
||||
#include "ED_uvedit.h"
|
||||
|
||||
#include "BIF_gl.h"
|
||||
#include "BIF_glutil.h"
|
||||
|
||||
#include "RNA_access.h"
|
||||
|
||||
#include "WM_api.h"
|
||||
#include "WM_types.h"
|
||||
@@ -57,9 +70,7 @@
|
||||
#include "UI_resources.h"
|
||||
#include "UI_view2d.h"
|
||||
|
||||
#include "ED_markers.h"
|
||||
|
||||
#include "image_intern.h" // own include
|
||||
#include "image_intern.h"
|
||||
|
||||
/* ******************** default callbacks for image space ***************** */
|
||||
|
||||
@@ -76,7 +87,6 @@ static SpaceLink *image_new(const bContext *C)
|
||||
simage->iuser.fie_ima= 2;
|
||||
simage->iuser.frames= 100;
|
||||
|
||||
|
||||
/* header */
|
||||
ar= MEM_callocN(sizeof(ARegion), "header for image");
|
||||
|
||||
@@ -126,25 +136,201 @@ static SpaceLink *image_duplicate(SpaceLink *sl)
|
||||
return (SpaceLink *)simagen;
|
||||
}
|
||||
|
||||
void image_operatortypes(void)
|
||||
{
|
||||
WM_operatortype_append(IMAGE_OT_view_all);
|
||||
WM_operatortype_append(IMAGE_OT_view_pan);
|
||||
WM_operatortype_append(IMAGE_OT_view_selected);
|
||||
WM_operatortype_append(IMAGE_OT_view_zoom);
|
||||
WM_operatortype_append(IMAGE_OT_view_zoom_in);
|
||||
WM_operatortype_append(IMAGE_OT_view_zoom_out);
|
||||
WM_operatortype_append(IMAGE_OT_view_zoom_ratio);
|
||||
}
|
||||
|
||||
void image_keymap(struct wmWindowManager *wm)
|
||||
{
|
||||
ListBase *keymap= WM_keymap_listbase(wm, "Image", SPACE_IMAGE, 0);
|
||||
|
||||
WM_keymap_add_item(keymap, "IMAGE_OT_view_all", HOMEKEY, KM_PRESS, 0, 0);
|
||||
WM_keymap_add_item(keymap, "IMAGE_OT_view_selected", PADPERIOD, KM_PRESS, 0, 0);
|
||||
WM_keymap_add_item(keymap, "IMAGE_OT_view_pan", MIDDLEMOUSE, KM_PRESS, 0, 0);
|
||||
|
||||
WM_keymap_add_item(keymap, "IMAGE_OT_view_zoom_in", WHEELINMOUSE, KM_PRESS, 0, 0);
|
||||
WM_keymap_add_item(keymap, "IMAGE_OT_view_zoom_out", WHEELOUTMOUSE, KM_PRESS, 0, 0);
|
||||
WM_keymap_add_item(keymap, "IMAGE_OT_view_zoom_in", PADPLUSKEY, KM_PRESS, 0, 0);
|
||||
WM_keymap_add_item(keymap, "IMAGE_OT_view_zoom_out", PADMINUS, KM_PRESS, 0, 0);
|
||||
WM_keymap_add_item(keymap, "IMAGE_OT_view_zoom", MIDDLEMOUSE, KM_PRESS, KM_CTRL, 0);
|
||||
|
||||
RNA_float_set(WM_keymap_add_item(keymap, "IMAGE_OT_view_zoom_ratio", PAD8, KM_PRESS, KM_SHIFT, 0)->ptr, "ratio", 8.0f);
|
||||
RNA_float_set(WM_keymap_add_item(keymap, "IMAGE_OT_view_zoom_ratio", PAD4, KM_PRESS, KM_SHIFT, 0)->ptr, "ratio", 4.0f);
|
||||
RNA_float_set(WM_keymap_add_item(keymap, "IMAGE_OT_view_zoom_ratio", PAD2, KM_PRESS, KM_SHIFT, 0)->ptr, "ratio", 2.0f);
|
||||
RNA_float_set(WM_keymap_add_item(keymap, "IMAGE_OT_view_zoom_ratio", PAD1, KM_PRESS, 0, 0)->ptr, "ratio", 1.0f);
|
||||
RNA_float_set(WM_keymap_add_item(keymap, "IMAGE_OT_view_zoom_ratio", PAD2, KM_PRESS, 0, 0)->ptr, "ratio", 0.5f);
|
||||
RNA_float_set(WM_keymap_add_item(keymap, "IMAGE_OT_view_zoom_ratio", PAD4, KM_PRESS, 0, 0)->ptr, "ratio", 0.25f);
|
||||
RNA_float_set(WM_keymap_add_item(keymap, "IMAGE_OT_view_zoom_ratio", PAD8, KM_PRESS, 0, 0)->ptr, "ratio", 0.125f);
|
||||
}
|
||||
|
||||
static void image_refresh(const bContext *C, ScrArea *sa)
|
||||
{
|
||||
SpaceImage *sima= (SpaceImage*)CTX_wm_space_data(C);
|
||||
Object *obedit= CTX_data_edit_object(C);
|
||||
Image *ima;
|
||||
|
||||
ima= get_space_image(sima);
|
||||
|
||||
/* check if we have to set the image from the editmesh */
|
||||
if(ima && (ima->source==IMA_SRC_VIEWER || sima->pin));
|
||||
else if(obedit && obedit->type == OB_MESH) {
|
||||
Mesh *me= (Mesh*)obedit->data;
|
||||
EditMesh *em= me->edit_mesh;
|
||||
MTFace *tf;
|
||||
|
||||
if(EM_texFaceCheck(em)) {
|
||||
sima->image= ima= NULL;
|
||||
|
||||
tf = EM_get_active_mtface(em, NULL, NULL, 1); /* partially selected face is ok */
|
||||
|
||||
if(tf && (tf->mode & TF_TEX)) {
|
||||
/* don't need to check for pin here, see above */
|
||||
sima->image= ima= tf->tpage;
|
||||
|
||||
if(sima->flag & SI_EDITTILE);
|
||||
else sima->curtile= tf->tile;
|
||||
|
||||
if(ima) {
|
||||
if(tf->mode & TF_TILES)
|
||||
ima->tpageflag |= IMA_TILES;
|
||||
else
|
||||
ima->tpageflag &= ~IMA_TILES;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void image_listener(ScrArea *sa, wmNotifier *wmn)
|
||||
{
|
||||
/* context changes */
|
||||
switch(wmn->category) {
|
||||
case NC_SCENE:
|
||||
switch(wmn->data) {
|
||||
case ND_MODE:
|
||||
ED_area_tag_refresh(sa);
|
||||
ED_area_tag_redraw(sa);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static int image_context(const bContext *C, const bContextDataMember *member, bContextDataResult *result)
|
||||
{
|
||||
SpaceImage *sima= (SpaceImage*)CTX_wm_space_data(C);
|
||||
|
||||
if(member == CTX_data_edit_image) {
|
||||
CTX_data_pointer_set(result, get_space_image(sima));
|
||||
return 1;
|
||||
}
|
||||
else if(member == CTX_data_edit_image_buffer) {
|
||||
CTX_data_pointer_set(result, get_space_image_buffer(sima));
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/************************** main region ***************************/
|
||||
|
||||
/* sets up the fields of the View2D from zoom and offset */
|
||||
static void image_main_area_set_view2d(SpaceImage *sima, ARegion *ar)
|
||||
{
|
||||
Image *ima= get_space_image(sima);
|
||||
float x1, y1, w, h;
|
||||
int width, height, winx, winy;
|
||||
|
||||
#if 0
|
||||
if(image_preview_active(curarea, &xim, &yim));
|
||||
else if(sima->image) {
|
||||
ImBuf *ibuf= imagewindow_get_ibuf(sima);
|
||||
float xuser_asp, yuser_asp;
|
||||
|
||||
image_pixel_aspect(sima->image, &xuser_asp, &yuser_asp);
|
||||
if(ibuf) {
|
||||
xim= ibuf->x * xuser_asp;
|
||||
yim= ibuf->y * yuser_asp;
|
||||
}
|
||||
else if( sima->image->type==IMA_TYPE_R_RESULT ) {
|
||||
/* not very important, just nice */
|
||||
xim= (G.scene->r.xsch*G.scene->r.size)/100;
|
||||
yim= (G.scene->r.ysch*G.scene->r.size)/100;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
get_space_image_size(sima, &width, &height);
|
||||
|
||||
w= width;
|
||||
h= height;
|
||||
|
||||
if(ima)
|
||||
h *= ima->aspy/ima->aspx;
|
||||
|
||||
winx= ar->winrct.xmax - ar->winrct.xmin + 1;
|
||||
winy= ar->winrct.ymax - ar->winrct.ymin + 1;
|
||||
|
||||
ar->v2d.tot.xmin= 0;
|
||||
ar->v2d.tot.ymin= 0;
|
||||
ar->v2d.tot.xmax= w;
|
||||
ar->v2d.tot.ymax= h;
|
||||
|
||||
ar->v2d.mask.xmin= ar->v2d.mask.ymin= 0;
|
||||
ar->v2d.mask.xmax= winx;
|
||||
ar->v2d.mask.ymax= winy;
|
||||
|
||||
/* which part of the image space do we see? */
|
||||
/* same calculation as in lrectwrite: area left and down*/
|
||||
x1= ar->winrct.xmin+(winx-sima->zoom*w)/2;
|
||||
y1= ar->winrct.ymin+(winy-sima->zoom*h)/2;
|
||||
|
||||
x1-= sima->zoom*sima->xof;
|
||||
y1-= sima->zoom*sima->yof;
|
||||
|
||||
/* relative display right */
|
||||
ar->v2d.cur.xmin= ((ar->winrct.xmin - (float)x1)/sima->zoom);
|
||||
ar->v2d.cur.xmax= ar->v2d.cur.xmin + ((float)winx/sima->zoom);
|
||||
|
||||
/* relative display left */
|
||||
ar->v2d.cur.ymin= ((ar->winrct.ymin-(float)y1)/sima->zoom);
|
||||
ar->v2d.cur.ymax= ar->v2d.cur.ymin + ((float)winy/sima->zoom);
|
||||
|
||||
/* normalize 0.0..1.0 */
|
||||
ar->v2d.cur.xmin /= w;
|
||||
ar->v2d.cur.xmax /= w;
|
||||
ar->v2d.cur.ymin /= h;
|
||||
ar->v2d.cur.ymax /= h;
|
||||
}
|
||||
|
||||
/* add handlers, stuff you only do once or on area/region changes */
|
||||
static void image_main_area_init(wmWindowManager *wm, ARegion *ar)
|
||||
{
|
||||
ListBase *keymap;
|
||||
|
||||
UI_view2d_region_reinit(&ar->v2d, V2D_COMMONVIEW_STANDARD, ar->winx, ar->winy);
|
||||
// image space manages own v2d
|
||||
// UI_view2d_region_reinit(&ar->v2d, V2D_COMMONVIEW_STANDARD, ar->winx, ar->winy);
|
||||
|
||||
/* own keymap */
|
||||
keymap= WM_keymap_listbase(wm, "Image", SPACE_IMAGE, 0); /* XXX weak? */
|
||||
keymap= WM_keymap_listbase(wm, "Image", SPACE_IMAGE, 0);
|
||||
WM_event_add_keymap_handler_bb(&ar->handlers, keymap, &ar->v2d.mask, &ar->winrct);
|
||||
}
|
||||
|
||||
static void image_main_area_draw(const bContext *C, ARegion *ar)
|
||||
{
|
||||
/* draw entirely, view changes should be handled here */
|
||||
// SpaceImage *simage= (SpaceImage*)CTX_wm_space_data(C);
|
||||
SpaceImage *sima= (SpaceImage*)CTX_wm_space_data(C);
|
||||
Object *obedit= CTX_data_edit_object(C);
|
||||
Scene *scene= CTX_data_scene(C);
|
||||
View2D *v2d= &ar->v2d;
|
||||
//View2DScrollers *scrollers;
|
||||
float col[3];
|
||||
|
||||
/* clear and setup matrix */
|
||||
@@ -152,27 +338,56 @@ static void image_main_area_draw(const bContext *C, ARegion *ar)
|
||||
glClearColor(col[0], col[1], col[2], 0.0);
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
|
||||
UI_view2d_view_ortho(C, v2d);
|
||||
/* we set view2d from own zoom and offset each time */
|
||||
image_main_area_set_view2d(sima, ar);
|
||||
|
||||
/* data... */
|
||||
|
||||
|
||||
/* reset view matrix */
|
||||
/* we draw image in pixelspace */
|
||||
draw_image_main(sima, ar, scene);
|
||||
|
||||
/* and uvs in 0.0-1.0 space */
|
||||
UI_view2d_view_ortho(C, v2d);
|
||||
draw_uvedit_main(sima, ar, scene, obedit);
|
||||
UI_view2d_view_restore(C);
|
||||
|
||||
/* scrollers? */
|
||||
/*scrollers= UI_view2d_scrollers_calc(C, v2d, V2D_UNIT_VALUES, V2D_GRID_CLAMP, V2D_ARG_DUMMY, V2D_ARG_DUMMY);
|
||||
UI_view2d_scrollers_draw(C, v2d, scrollers);
|
||||
UI_view2d_scrollers_free(scrollers);*/
|
||||
}
|
||||
|
||||
void image_operatortypes(void)
|
||||
static void image_modal_keymaps(wmWindowManager *wm, ARegion *ar, int stype)
|
||||
{
|
||||
ListBase *keymap;
|
||||
|
||||
keymap= WM_keymap_listbase(wm, "UVEdit", 0, 0);
|
||||
if(stype==NS_EDITMODE_MESH)
|
||||
WM_event_add_keymap_handler(&ar->handlers, keymap);
|
||||
else
|
||||
WM_event_remove_keymap_handler(&ar->handlers, keymap);
|
||||
}
|
||||
|
||||
void image_keymap(struct wmWindowManager *wm)
|
||||
static void image_main_area_listener(ARegion *ar, wmNotifier *wmn)
|
||||
{
|
||||
|
||||
/* context changes */
|
||||
switch(wmn->category) {
|
||||
case NC_SCENE:
|
||||
switch(wmn->data) {
|
||||
case ND_MODE:
|
||||
image_modal_keymaps(wmn->wm, ar, wmn->subtype);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case NC_OBJECT:
|
||||
switch(wmn->data) {
|
||||
case ND_GEOM_SELECT:
|
||||
ED_region_tag_redraw(ar);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/************************* header region **************************/
|
||||
|
||||
/* add handlers, stuff you only do once or on area/region changes */
|
||||
static void image_header_area_init(wmWindowManager *wm, ARegion *ar)
|
||||
{
|
||||
@@ -201,10 +416,7 @@ static void image_header_area_draw(const bContext *C, ARegion *ar)
|
||||
UI_view2d_view_restore(C);
|
||||
}
|
||||
|
||||
static void image_main_area_listener(ARegion *ar, wmNotifier *wmn)
|
||||
{
|
||||
/* context changes */
|
||||
}
|
||||
/**************************** spacetype *****************************/
|
||||
|
||||
/* only called once, from space/spacetypes.c */
|
||||
void ED_spacetype_image(void)
|
||||
@@ -220,6 +432,9 @@ void ED_spacetype_image(void)
|
||||
st->duplicate= image_duplicate;
|
||||
st->operatortypes= image_operatortypes;
|
||||
st->keymap= image_keymap;
|
||||
st->refresh= image_refresh;
|
||||
st->listener= image_listener;
|
||||
st->context= image_context;
|
||||
|
||||
/* regions: main window */
|
||||
art= MEM_callocN(sizeof(ARegionType), "spacetype image region");
|
||||
@@ -227,7 +442,7 @@ void ED_spacetype_image(void)
|
||||
art->init= image_main_area_init;
|
||||
art->draw= image_main_area_draw;
|
||||
art->listener= image_main_area_listener;
|
||||
art->keymapflag= ED_KEYMAP_VIEW2D;
|
||||
art->keymapflag= 0;
|
||||
|
||||
BLI_addhead(&st->regiontypes, art);
|
||||
|
||||
@@ -242,18 +457,128 @@ void ED_spacetype_image(void)
|
||||
|
||||
BLI_addhead(&st->regiontypes, art);
|
||||
|
||||
/* regions: channels */
|
||||
art= MEM_callocN(sizeof(ARegionType), "spacetype image region");
|
||||
art->regionid = RGN_TYPE_CHANNELS;
|
||||
art->minsizex= 80;
|
||||
art->keymapflag= ED_KEYMAP_UI|ED_KEYMAP_VIEW2D;
|
||||
|
||||
// art->init= image_channel_area_init;
|
||||
// art->draw= image_channel_area_draw;
|
||||
|
||||
BLI_addhead(&st->regiontypes, art);
|
||||
|
||||
|
||||
BKE_spacetype_register(st);
|
||||
}
|
||||
|
||||
/**************************** common state *****************************/
|
||||
|
||||
Image *get_space_image(SpaceImage *sima)
|
||||
{
|
||||
return sima->image;
|
||||
}
|
||||
|
||||
/* called to assign images to UV faces */
|
||||
void set_space_image(SpaceImage *sima, Scene *scene, Object *obedit, Image *ima)
|
||||
{
|
||||
ED_uvedit_assign_image(scene, obedit, ima, sima->image);
|
||||
|
||||
/* change the space ima after because uvedit_face_visible uses the space ima
|
||||
* to check if the face is displayed in UV-localview */
|
||||
sima->image= ima;
|
||||
|
||||
if(ima == NULL || ima->type==IMA_TYPE_R_RESULT || ima->type==IMA_TYPE_COMPOSITE)
|
||||
sima->flag &= ~SI_DRAWTOOL;
|
||||
}
|
||||
|
||||
ImBuf *get_space_image_buffer(SpaceImage *sima)
|
||||
{
|
||||
ImBuf *ibuf;
|
||||
|
||||
if(sima->image) {
|
||||
#if 0
|
||||
if(sima->image->type==IMA_TYPE_R_RESULT && BIF_show_render_spare())
|
||||
return BIF_render_spare_imbuf();
|
||||
else
|
||||
#endif
|
||||
ibuf= BKE_image_get_ibuf(sima->image, &sima->iuser);
|
||||
|
||||
if(ibuf->rect || ibuf->rect_float)
|
||||
return ibuf;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void get_space_image_size(SpaceImage *sima, int *width, int *height)
|
||||
{
|
||||
ImBuf *ibuf;
|
||||
|
||||
ibuf= get_space_image_buffer(sima);
|
||||
|
||||
if(ibuf && ibuf->x > 0 && ibuf->y > 0) {
|
||||
*width= ibuf->x;
|
||||
*height= ibuf->y;
|
||||
}
|
||||
/* I know a bit weak... but preview uses not actual image size */
|
||||
// XXX else if(image_preview_active(sima, width, height));
|
||||
else {
|
||||
*width= 256;
|
||||
*height= 256;
|
||||
}
|
||||
}
|
||||
|
||||
void get_space_image_aspect(SpaceImage *sima, float *aspx, float *aspy)
|
||||
{
|
||||
Image *ima;
|
||||
|
||||
ima= get_space_image(sima);
|
||||
|
||||
*aspx= *aspy= 1.0;
|
||||
|
||||
if((ima == NULL) || (ima->type == IMA_TYPE_R_RESULT) || (ima->type == IMA_TYPE_COMPOSITE) ||
|
||||
(ima->tpageflag & IMA_TILES) || (ima->aspx==0.0 || ima->aspy==0.0))
|
||||
return;
|
||||
|
||||
/* x is always 1 */
|
||||
*aspy = ima->aspy/ima->aspx;
|
||||
}
|
||||
|
||||
void get_space_image_zoom(SpaceImage *sima, ARegion *ar, float *zoomx, float *zoomy)
|
||||
{
|
||||
int width, height;
|
||||
|
||||
get_space_image_size(sima, &width, &height);
|
||||
|
||||
*zoomx= (float)(ar->winrct.xmax - ar->winrct.xmin)/(float)((ar->v2d.cur.xmax - ar->v2d.cur.xmin)*width);
|
||||
*zoomy= (float)(ar->winrct.ymax - ar->winrct.ymin)/(float)((ar->v2d.cur.ymax - ar->v2d.cur.ymin)*height);
|
||||
}
|
||||
|
||||
int get_space_image_show_render(SpaceImage *sima)
|
||||
{
|
||||
return (sima->image && ELEM(sima->image->type, IMA_TYPE_R_RESULT, IMA_TYPE_COMPOSITE));
|
||||
}
|
||||
|
||||
int get_space_image_show_paint(SpaceImage *sima)
|
||||
{
|
||||
if(get_space_image_show_render(sima))
|
||||
return 0;
|
||||
|
||||
return (sima->flag & SI_DRAWTOOL);
|
||||
}
|
||||
|
||||
int get_space_image_show_uvedit(SpaceImage *sima, Object *obedit)
|
||||
{
|
||||
if(get_space_image_show_render(sima))
|
||||
return 0;
|
||||
if(get_space_image_show_paint(sima))
|
||||
return 0;
|
||||
|
||||
if(obedit && obedit->type == OB_MESH)
|
||||
return EM_texFaceCheck(((Mesh*)obedit->data)->edit_mesh);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int get_space_image_show_uvshadow(SpaceImage *sima, Object *obedit)
|
||||
{
|
||||
if(get_space_image_show_render(sima))
|
||||
return 0;
|
||||
|
||||
if(get_space_image_show_paint(sima))
|
||||
if(obedit && obedit->type == OB_MESH)
|
||||
return EM_texFaceCheck(((Mesh*)obedit->data)->edit_mesh);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
54
source/blender/editors/uvedit/Makefile
Normal file
54
source/blender/editors/uvedit/Makefile
Normal file
@@ -0,0 +1,54 @@
|
||||
#
|
||||
# $Id: Makefile 14 2002-10-13 15:57:19Z hans $
|
||||
#
|
||||
# ***** BEGIN GPL LICENSE BLOCK *****
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License
|
||||
# as published by the Free Software Foundation; either version 2
|
||||
# of the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software Foundation,
|
||||
# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
#
|
||||
# The Original Code is Copyright (C) 2007 Blender Foundation
|
||||
# All rights reserved.
|
||||
#
|
||||
# The Original Code is: all of this file.
|
||||
#
|
||||
# Contributor(s): none yet.
|
||||
#
|
||||
# ***** END GPL LICENSE BLOCK *****
|
||||
#
|
||||
# Makes module object directory and bounces make to subdirectories.
|
||||
|
||||
LIBNAME = ed_uvedit
|
||||
DIR = $(OCGDIR)/blender/$(LIBNAME)
|
||||
|
||||
include nan_compile.mk
|
||||
|
||||
CFLAGS += $(LEVEL_1_C_WARNINGS)
|
||||
|
||||
CPPFLAGS += -I$(NAN_GLEW)/include
|
||||
CPPFLAGS += -I$(OPENGL_HEADERS)
|
||||
|
||||
# not very neat....
|
||||
CPPFLAGS += -I../../windowmanager
|
||||
CPPFLAGS += -I../../blenkernel
|
||||
CPPFLAGS += -I../../blenlib
|
||||
CPPFLAGS += -I../../makesdna
|
||||
CPPFLAGS += -I../../makesrna
|
||||
CPPFLAGS += -I../../imbuf
|
||||
CPPFLAGS += -I$(NAN_GUARDEDALLOC)/include
|
||||
CPPFLAGS += -I$(NAN_OPENNL)/include
|
||||
|
||||
# own include
|
||||
|
||||
CPPFLAGS += -I../include
|
||||
|
||||
10
source/blender/editors/uvedit/SConscript
Normal file
10
source/blender/editors/uvedit/SConscript
Normal file
@@ -0,0 +1,10 @@
|
||||
#!/usr/bin/python
|
||||
Import ('env')
|
||||
|
||||
sources = env.Glob('*.c')
|
||||
|
||||
incs = '../include ../../blenlib ../../blenkernel ../../makesdna ../../imbuf'
|
||||
incs += ' ../../windowmanager #/intern/guardedalloc #/extern/glew/include'
|
||||
incs += ' ../../makesrna #/intern/opennl/extern'
|
||||
|
||||
env.BlenderLib ( 'bf_editors_uvedit', sources, Split(incs), [], libtype=['core'], priority=[45] )
|
||||
808
source/blender/editors/uvedit/uvedit_draw.c
Normal file
808
source/blender/editors/uvedit/uvedit_draw.c
Normal file
@@ -0,0 +1,808 @@
|
||||
/**
|
||||
* $Id$
|
||||
*
|
||||
* ***** BEGIN GPL LICENSE BLOCK *****
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*
|
||||
* The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Contributor(s): Blender Foundation, 2002-2009
|
||||
*
|
||||
* ***** END GPL LICENSE BLOCK *****
|
||||
*/
|
||||
|
||||
#include <float.h>
|
||||
#include <math.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "DNA_mesh_types.h"
|
||||
#include "DNA_meshdata_types.h"
|
||||
#include "DNA_object_types.h"
|
||||
#include "DNA_scene_types.h"
|
||||
#include "DNA_screen_types.h"
|
||||
#include "DNA_space_types.h"
|
||||
|
||||
#include "BKE_customdata.h"
|
||||
#include "BKE_DerivedMesh.h"
|
||||
#include "BKE_global.h" // XXX make edge and face drawing flags local
|
||||
#include "BKE_object.h"
|
||||
#include "BKE_utildefines.h"
|
||||
|
||||
#include "BLI_arithb.h"
|
||||
#include "BLI_editVert.h"
|
||||
|
||||
#include "BIF_gl.h"
|
||||
#include "BIF_glutil.h"
|
||||
|
||||
#include "ED_mesh.h"
|
||||
|
||||
#include "UI_resources.h"
|
||||
|
||||
#include "../space_image/image_intern.h"
|
||||
#include "uvedit_intern.h"
|
||||
|
||||
/* XXX make this draw extra for transform operator */
|
||||
#if 0
|
||||
static void draw_image_transform(ImBuf *ibuf, float xuser_asp, float yuser_asp)
|
||||
{
|
||||
#if 0
|
||||
if(G.moving) {
|
||||
float aspx, aspy, center[3];
|
||||
|
||||
BIF_drawConstraint();
|
||||
|
||||
if(ibuf==0 || ibuf->rect==0 || ibuf->x==0 || ibuf->y==0) {
|
||||
aspx= aspy= 1.0;
|
||||
}
|
||||
else {
|
||||
aspx= (256.0/ibuf->x) * xuser_asp;
|
||||
aspy= (256.0/ibuf->y) * yuser_asp;
|
||||
}
|
||||
BIF_getPropCenter(center);
|
||||
|
||||
/* scale and translate the circle into place and draw it */
|
||||
glPushMatrix();
|
||||
glScalef(aspx, aspy, 1.0);
|
||||
glTranslatef((1/aspx)*center[0] - center[0],
|
||||
(1/aspy)*center[1] - center[1], 0.0);
|
||||
|
||||
BIF_drawPropCircle();
|
||||
|
||||
glPopMatrix();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
static void drawcursor_sima(SpaceImage *sima, ARegion *ar)
|
||||
{
|
||||
View2D *v2d= &ar->v2d;
|
||||
float zoomx, zoomy, w, h;
|
||||
int width, height;
|
||||
|
||||
get_space_image_size(sima, &width, &height);
|
||||
get_space_image_zoom(sima, ar, &zoomx, &zoomy);
|
||||
|
||||
w= zoomx*width/256.0f;
|
||||
h= zoomy*height/256.0f;
|
||||
|
||||
cpack(0xFFFFFF);
|
||||
glTranslatef(v2d->cursor[0], v2d->cursor[1], 0.0f);
|
||||
fdrawline(-0.05/w, 0, 0, 0.05/h);
|
||||
fdrawline(0, 0.05/h, 0.05/w, 0);
|
||||
fdrawline(0.05/w, 0, 0, -0.05/h);
|
||||
fdrawline(0, -0.05/h, -0.05/w, 0);
|
||||
|
||||
setlinestyle(4);
|
||||
cpack(0xFF);
|
||||
fdrawline(-0.05/w, 0, 0, 0.05/h);
|
||||
fdrawline(0, 0.05/h, 0.05/w, 0);
|
||||
fdrawline(0.05/w, 0, 0, -0.05/h);
|
||||
fdrawline(0, -0.05/h, -0.05/w, 0);
|
||||
|
||||
|
||||
setlinestyle(0);
|
||||
cpack(0x0);
|
||||
fdrawline(-0.020/w, 0, -0.1/w, 0);
|
||||
fdrawline(0.1/w, 0, .020/w, 0);
|
||||
fdrawline(0, -0.020/h, 0, -0.1/h);
|
||||
fdrawline(0, 0.1/h, 0, 0.020/h);
|
||||
|
||||
setlinestyle(1);
|
||||
cpack(0xFFFFFF);
|
||||
fdrawline(-0.020/w, 0, -0.1/w, 0);
|
||||
fdrawline(0.1/w, 0, .020/w, 0);
|
||||
fdrawline(0, -0.020/h, 0, -0.1/h);
|
||||
fdrawline(0, 0.1/h, 0, 0.020/h);
|
||||
|
||||
glTranslatef(-v2d->cursor[0], -v2d->cursor[1], 0.0f);
|
||||
setlinestyle(0);
|
||||
}
|
||||
|
||||
static int draw_uvs_face_check(Scene *scene)
|
||||
{
|
||||
/* checks if we are selecting only faces */
|
||||
if(scene->toolsettings->uv_flag & UV_SYNC_SELECTION) {
|
||||
if(scene->selectmode == SCE_SELECT_FACE)
|
||||
return 2;
|
||||
else if(scene->selectmode & SCE_SELECT_FACE)
|
||||
return 1;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
return (scene->toolsettings->uv_selectmode == UV_SELECT_FACE);
|
||||
}
|
||||
|
||||
static void draw_uvs_shadow(SpaceImage *sima, Object *obedit)
|
||||
{
|
||||
EditMesh *em;
|
||||
EditFace *efa;
|
||||
TFace *tf;
|
||||
|
||||
em= ((Mesh*)obedit->data)->edit_mesh;
|
||||
|
||||
/* draws the grey mesh when painting */
|
||||
glColor3ub(112, 112, 112);
|
||||
|
||||
for(efa= em->faces.first; efa; efa= efa->next) {
|
||||
tf= CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
|
||||
|
||||
glBegin(GL_LINE_LOOP);
|
||||
glVertex2fv(tf->uv[0]);
|
||||
glVertex2fv(tf->uv[1]);
|
||||
glVertex2fv(tf->uv[2]);
|
||||
if(efa->v4) glVertex2fv(tf->uv[3]);
|
||||
glEnd();
|
||||
}
|
||||
}
|
||||
|
||||
static int draw_uvs_dm_shadow(DerivedMesh *dm)
|
||||
{
|
||||
/* draw shadow mesh - this is the mesh with the modifier applied */
|
||||
|
||||
if(dm && dm->drawUVEdges && CustomData_has_layer(&dm->faceData, CD_MTFACE)) {
|
||||
glColor3ub(112, 112, 112);
|
||||
dm->drawUVEdges(dm);
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void draw_uvs_stretch(SpaceImage *sima, Scene *scene, EditMesh *em, MTFace *activetf)
|
||||
{
|
||||
EditFace *efa;
|
||||
MTFace *tf;
|
||||
Image *ima= sima->image;
|
||||
float aspx, aspy, col[4], tf_uv[4][2];
|
||||
|
||||
aspx= 1.0f;
|
||||
aspy= 1.0f;
|
||||
//XXX transform_aspect_ratio_tf_uv(&aspx, &aspy);
|
||||
|
||||
switch(sima->dt_uvstretch) {
|
||||
case SI_UVDT_STRETCH_AREA:
|
||||
{
|
||||
float totarea=0.0f, totuvarea=0.0f, areadiff, uvarea, area;
|
||||
|
||||
for(efa= em->faces.first; efa; efa= efa->next) {
|
||||
tf= CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
|
||||
uv_copy_aspect(tf->uv, tf_uv, aspx, aspy);
|
||||
|
||||
totarea += EM_face_area(efa);
|
||||
//totuvarea += tf_area(tf, efa->v4!=0);
|
||||
totuvarea += uv_area(tf_uv, efa->v4!=0);
|
||||
|
||||
if(uvedit_face_visible(scene, ima, efa, tf)) {
|
||||
efa->tmp.p = tf;
|
||||
}
|
||||
else {
|
||||
if(tf == activetf)
|
||||
activetf= NULL;
|
||||
efa->tmp.p = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
if(totarea < FLT_EPSILON || totuvarea < FLT_EPSILON) {
|
||||
col[0] = 1.0;
|
||||
col[1] = col[2] = 0.0;
|
||||
glColor3fv(col);
|
||||
for(efa= em->faces.first; efa; efa= efa->next) {
|
||||
if((tf=(MTFace *)efa->tmp.p)) {
|
||||
glBegin(efa->v4?GL_QUADS:GL_TRIANGLES);
|
||||
glVertex2fv(tf->uv[0]);
|
||||
glVertex2fv(tf->uv[1]);
|
||||
glVertex2fv(tf->uv[2]);
|
||||
if(efa->v4) glVertex2fv(tf->uv[3]);
|
||||
glEnd();
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
for(efa= em->faces.first; efa; efa= efa->next) {
|
||||
if((tf=(MTFace *)efa->tmp.p)) {
|
||||
area = EM_face_area(efa) / totarea;
|
||||
uv_copy_aspect(tf->uv, tf_uv, aspx, aspy);
|
||||
//uvarea = tf_area(tf, efa->v4!=0) / totuvarea;
|
||||
uvarea = uv_area(tf_uv, efa->v4!=0) / totuvarea;
|
||||
|
||||
if(area < FLT_EPSILON || uvarea < FLT_EPSILON)
|
||||
areadiff = 1.0;
|
||||
else if(area>uvarea)
|
||||
areadiff = 1.0-(uvarea/area);
|
||||
else
|
||||
areadiff = 1.0-(area/uvarea);
|
||||
|
||||
weight_to_rgb(areadiff, col, col+1, col+2);
|
||||
glColor3fv(col);
|
||||
|
||||
glBegin(efa->v4?GL_QUADS:GL_TRIANGLES);
|
||||
glVertex2fv(tf->uv[0]);
|
||||
glVertex2fv(tf->uv[1]);
|
||||
glVertex2fv(tf->uv[2]);
|
||||
if(efa->v4) glVertex2fv(tf->uv[3]);
|
||||
glEnd();
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case SI_UVDT_STRETCH_ANGLE:
|
||||
{
|
||||
float uvang1,uvang2,uvang3,uvang4;
|
||||
float ang1,ang2,ang3,ang4;
|
||||
float av1[3], av2[3], av3[3], av4[3]; /* use for 2d and 3d angle vectors */
|
||||
float a;
|
||||
|
||||
col[3] = 0.5; /* hard coded alpha, not that nice */
|
||||
|
||||
glShadeModel(GL_SMOOTH);
|
||||
|
||||
for(efa= em->faces.first; efa; efa= efa->next) {
|
||||
tf= CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
|
||||
|
||||
if(uvedit_face_visible(scene, ima, efa, tf)) {
|
||||
efa->tmp.p = tf;
|
||||
uv_copy_aspect(tf->uv, tf_uv, aspx, aspy);
|
||||
if(efa->v4) {
|
||||
|
||||
#if 0 /* Simple but slow, better reuse normalized vectors */
|
||||
uvang1 = VecAngle3_2D(tf_uv[3], tf_uv[0], tf_uv[1]);
|
||||
ang1 = VecAngle3(efa->v4->co, efa->v1->co, efa->v2->co);
|
||||
|
||||
uvang2 = VecAngle3_2D(tf_uv[0], tf_uv[1], tf_uv[2]);
|
||||
ang2 = VecAngle3(efa->v1->co, efa->v2->co, efa->v3->co);
|
||||
|
||||
uvang3 = VecAngle3_2D(tf_uv[1], tf_uv[2], tf_uv[3]);
|
||||
ang3 = VecAngle3(efa->v2->co, efa->v3->co, efa->v4->co);
|
||||
|
||||
uvang4 = VecAngle3_2D(tf_uv[2], tf_uv[3], tf_uv[0]);
|
||||
ang4 = VecAngle3(efa->v3->co, efa->v4->co, efa->v1->co);
|
||||
#endif
|
||||
|
||||
/* uv angles */
|
||||
VECSUB2D(av1, tf_uv[3], tf_uv[0]); Normalize2(av1);
|
||||
VECSUB2D(av2, tf_uv[0], tf_uv[1]); Normalize2(av2);
|
||||
VECSUB2D(av3, tf_uv[1], tf_uv[2]); Normalize2(av3);
|
||||
VECSUB2D(av4, tf_uv[2], tf_uv[3]); Normalize2(av4);
|
||||
|
||||
/* This is the correct angle however we are only comparing angles
|
||||
* uvang1 = 90-((NormalizedVecAngle2_2D(av1, av2) * 180.0/M_PI)-90);*/
|
||||
uvang1 = NormalizedVecAngle2_2D(av1, av2)*180.0/M_PI;
|
||||
uvang2 = NormalizedVecAngle2_2D(av2, av3)*180.0/M_PI;
|
||||
uvang3 = NormalizedVecAngle2_2D(av3, av4)*180.0/M_PI;
|
||||
uvang4 = NormalizedVecAngle2_2D(av4, av1)*180.0/M_PI;
|
||||
|
||||
/* 3d angles */
|
||||
VECSUB(av1, efa->v4->co, efa->v1->co); Normalize(av1);
|
||||
VECSUB(av2, efa->v1->co, efa->v2->co); Normalize(av2);
|
||||
VECSUB(av3, efa->v2->co, efa->v3->co); Normalize(av3);
|
||||
VECSUB(av4, efa->v3->co, efa->v4->co); Normalize(av4);
|
||||
|
||||
/* This is the correct angle however we are only comparing angles
|
||||
* ang1 = 90-((NormalizedVecAngle2(av1, av2) * 180.0/M_PI)-90);*/
|
||||
ang1 = NormalizedVecAngle2(av1, av2)*180.0/M_PI;
|
||||
ang2 = NormalizedVecAngle2(av2, av3)*180.0/M_PI;
|
||||
ang3 = NormalizedVecAngle2(av3, av4)*180.0/M_PI;
|
||||
ang4 = NormalizedVecAngle2(av4, av1)*180.0/M_PI;
|
||||
|
||||
glBegin(GL_QUADS);
|
||||
|
||||
/* This simple makes the angles display worse then they really are ;)
|
||||
* 1.0-pow((1.0-a), 2) */
|
||||
|
||||
a = fabs(uvang1-ang1)/180.0;
|
||||
weight_to_rgb(1.0-pow((1.0-a), 2), col, col+1, col+2);
|
||||
glColor3fv(col);
|
||||
glVertex2fv(tf->uv[0]);
|
||||
a = fabs(uvang2-ang2)/180.0;
|
||||
weight_to_rgb(1.0-pow((1.0-a), 2), col, col+1, col+2);
|
||||
glColor3fv(col);
|
||||
glVertex2fv(tf->uv[1]);
|
||||
a = fabs(uvang3-ang3)/180.0;
|
||||
weight_to_rgb(1.0-pow((1.0-a), 2), col, col+1, col+2);
|
||||
glColor3fv(col);
|
||||
glVertex2fv(tf->uv[2]);
|
||||
a = fabs(uvang4-ang4)/180.0;
|
||||
weight_to_rgb(1.0-pow((1.0-a), 2), col, col+1, col+2);
|
||||
glColor3fv(col);
|
||||
glVertex2fv(tf->uv[3]);
|
||||
|
||||
}
|
||||
else {
|
||||
#if 0 /* Simple but slow, better reuse normalized vectors */
|
||||
uvang1 = VecAngle3_2D(tf_uv[2], tf_uv[0], tf_uv[1]);
|
||||
ang1 = VecAngle3(efa->v3->co, efa->v1->co, efa->v2->co);
|
||||
|
||||
uvang2 = VecAngle3_2D(tf_uv[0], tf_uv[1], tf_uv[2]);
|
||||
ang2 = VecAngle3(efa->v1->co, efa->v2->co, efa->v3->co);
|
||||
|
||||
uvang3 = 180-(uvang1+uvang2);
|
||||
ang3 = 180-(ang1+ang2);
|
||||
#endif
|
||||
|
||||
/* uv angles */
|
||||
VECSUB2D(av1, tf_uv[2], tf_uv[0]); Normalize2(av1);
|
||||
VECSUB2D(av2, tf_uv[0], tf_uv[1]); Normalize2(av2);
|
||||
VECSUB2D(av3, tf_uv[1], tf_uv[2]); Normalize2(av3);
|
||||
|
||||
/* This is the correct angle however we are only comparing angles
|
||||
* uvang1 = 90-((NormalizedVecAngle2_2D(av1, av2) * 180.0/M_PI)-90); */
|
||||
uvang1 = NormalizedVecAngle2_2D(av1, av2)*180.0/M_PI;
|
||||
uvang2 = NormalizedVecAngle2_2D(av2, av3)*180.0/M_PI;
|
||||
uvang3 = NormalizedVecAngle2_2D(av3, av1)*180.0/M_PI;
|
||||
|
||||
/* 3d angles */
|
||||
VECSUB(av1, efa->v3->co, efa->v1->co); Normalize(av1);
|
||||
VECSUB(av2, efa->v1->co, efa->v2->co); Normalize(av2);
|
||||
VECSUB(av3, efa->v2->co, efa->v3->co); Normalize(av3);
|
||||
/* This is the correct angle however we are only comparing angles
|
||||
* ang1 = 90-((NormalizedVecAngle2(av1, av2) * 180.0/M_PI)-90); */
|
||||
ang1 = NormalizedVecAngle2(av1, av2)*180.0/M_PI;
|
||||
ang2 = NormalizedVecAngle2(av2, av3)*180.0/M_PI;
|
||||
ang3 = NormalizedVecAngle2(av3, av1)*180.0/M_PI;
|
||||
|
||||
/* This simple makes the angles display worse then they really are ;)
|
||||
* 1.0-pow((1.0-a), 2) */
|
||||
|
||||
glBegin(GL_TRIANGLES);
|
||||
a = fabs(uvang1-ang1)/180.0;
|
||||
weight_to_rgb(1.0-pow((1.0-a), 2), col, col+1, col+2);
|
||||
glColor3fv(col);
|
||||
glVertex2fv(tf->uv[0]);
|
||||
a = fabs(uvang2-ang2)/180.0;
|
||||
weight_to_rgb(1.0-pow((1.0-a), 2), col, col+1, col+2);
|
||||
glColor3fv(col);
|
||||
glVertex2fv(tf->uv[1]);
|
||||
a = fabs(uvang3-ang3)/180.0;
|
||||
weight_to_rgb(1.0-pow((1.0-a), 2), col, col+1, col+2);
|
||||
glColor3fv(col);
|
||||
glVertex2fv(tf->uv[2]);
|
||||
}
|
||||
glEnd();
|
||||
}
|
||||
else {
|
||||
if(tf == activetf)
|
||||
activetf= NULL;
|
||||
efa->tmp.p = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
glShadeModel(GL_FLAT);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* draws uv's in the image space */
|
||||
static void draw_uvs(SpaceImage *sima, Scene *scene, Object *obedit)
|
||||
{
|
||||
EditMesh *em;
|
||||
EditFace *efa, *efa_act;
|
||||
MTFace *tf, *activetf = NULL;
|
||||
DerivedMesh *finaldm, *cagedm;
|
||||
char col1[4], col2[4];
|
||||
float pointsize;
|
||||
int drawfaces, lastsel, sel;
|
||||
Image *ima= sima->image;
|
||||
|
||||
em= ((Mesh*)obedit->data)->edit_mesh;
|
||||
activetf= EM_get_active_mtface(em, &efa_act, NULL, 0); /* will be set to NULL if hidden */
|
||||
|
||||
drawfaces= draw_uvs_face_check(scene);
|
||||
|
||||
#if 0
|
||||
calc_image_view(G.sima, 'f'); /* float */
|
||||
myortho2(G.v2d->cur.xmin, G.v2d->cur.xmax, G.v2d->cur.ymin, G.v2d->cur.ymax);
|
||||
glLoadIdentity();
|
||||
#endif
|
||||
|
||||
/* 1. draw shadow mesh */
|
||||
|
||||
if(sima->flag & SI_DRAWSHADOW) {
|
||||
/* first try existing derivedmesh */
|
||||
if(!draw_uvs_dm_shadow(em->derivedFinal)) {
|
||||
/* create one if it does not exist */
|
||||
cagedm = editmesh_get_derived_cage_and_final(scene, obedit, em, &finaldm, CD_MASK_BAREMESH|CD_MASK_MTFACE);
|
||||
|
||||
/* when sync selection is enabled, all faces are drawn (except for hidden)
|
||||
* so if cage is the same as the final, theres no point in drawing this */
|
||||
if(!((scene->toolsettings->uv_flag & UV_SYNC_SELECTION) && (cagedm == finaldm)))
|
||||
draw_uvs_dm_shadow(finaldm);
|
||||
|
||||
/* release derivedmesh again */
|
||||
if(cagedm != finaldm) cagedm->release(cagedm);
|
||||
finaldm->release(finaldm);
|
||||
}
|
||||
}
|
||||
|
||||
/* 2. draw colored faces */
|
||||
|
||||
if(sima->flag & SI_DRAW_STRETCH) {
|
||||
draw_uvs_stretch(sima, scene, em, activetf);
|
||||
}
|
||||
else if(G.f & G_DRAWFACES) {
|
||||
/* draw transparent faces */
|
||||
UI_GetThemeColor4ubv(TH_FACE, col1);
|
||||
UI_GetThemeColor4ubv(TH_FACE_SELECT, col2);
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
glEnable(GL_BLEND);
|
||||
|
||||
for(efa= em->faces.first; efa; efa= efa->next) {
|
||||
tf= CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
|
||||
|
||||
if(uvedit_face_visible(scene, ima, efa, tf)) {
|
||||
efa->tmp.p = tf;
|
||||
if(tf==activetf) continue; /* important the temp pointer is set above */
|
||||
|
||||
if(uvedit_face_selected(scene, efa, tf))
|
||||
glColor4ubv((GLubyte *)col2);
|
||||
else
|
||||
glColor4ubv((GLubyte *)col1);
|
||||
|
||||
glBegin(efa->v4?GL_QUADS:GL_TRIANGLES);
|
||||
glVertex2fv(tf->uv[0]);
|
||||
glVertex2fv(tf->uv[1]);
|
||||
glVertex2fv(tf->uv[2]);
|
||||
if(efa->v4) glVertex2fv(tf->uv[3]);
|
||||
glEnd();
|
||||
}
|
||||
else {
|
||||
if(tf == activetf)
|
||||
activetf= NULL;
|
||||
efa->tmp.p = NULL;
|
||||
}
|
||||
}
|
||||
glDisable(GL_BLEND);
|
||||
}
|
||||
else {
|
||||
/* would be nice to do this within a draw loop but most below are optional, so it would involve too many checks */
|
||||
for(efa= em->faces.first; efa; efa= efa->next) {
|
||||
tf= CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
|
||||
|
||||
if(uvedit_face_visible(scene, ima, efa, tf)) {
|
||||
efa->tmp.p = tf;
|
||||
}
|
||||
else {
|
||||
if(tf == activetf)
|
||||
activetf= NULL;
|
||||
efa->tmp.p = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* 3. draw active face stippled */
|
||||
|
||||
if(activetf) {
|
||||
glEnable(GL_BLEND);
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
UI_ThemeColor4(TH_EDITMESH_ACTIVE);
|
||||
|
||||
glEnable(GL_POLYGON_STIPPLE);
|
||||
glPolygonStipple(stipple_quarttone);
|
||||
|
||||
glBegin(efa_act->v4? GL_QUADS: GL_TRIANGLES);
|
||||
glVertex2fv(activetf->uv[0]);
|
||||
glVertex2fv(activetf->uv[1]);
|
||||
glVertex2fv(activetf->uv[2]);
|
||||
if(efa_act->v4) glVertex2fv(activetf->uv[3]);
|
||||
glEnd();
|
||||
|
||||
glDisable(GL_POLYGON_STIPPLE);
|
||||
glDisable(GL_BLEND);
|
||||
}
|
||||
|
||||
/* 4. draw edges */
|
||||
|
||||
if(sima->flag & SI_SMOOTH_UV) {
|
||||
glEnable(GL_LINE_SMOOTH);
|
||||
glEnable(GL_BLEND);
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
}
|
||||
|
||||
switch(sima->dt_uv) {
|
||||
case SI_UVDT_DASH:
|
||||
for(efa= em->faces.first; efa; efa= efa->next) {
|
||||
tf= (MTFace *)efa->tmp.p; /* visible faces cached */
|
||||
|
||||
if(tf) {
|
||||
cpack(0x111111);
|
||||
|
||||
glBegin(GL_LINE_LOOP);
|
||||
glVertex2fv(tf->uv[0]);
|
||||
glVertex2fv(tf->uv[1]);
|
||||
glVertex2fv(tf->uv[2]);
|
||||
if(efa->v4) glVertex2fv(tf->uv[3]);
|
||||
glEnd();
|
||||
|
||||
setlinestyle(2);
|
||||
cpack(0x909090);
|
||||
|
||||
glBegin(GL_LINE_STRIP);
|
||||
glVertex2fv(tf->uv[0]);
|
||||
glVertex2fv(tf->uv[1]);
|
||||
glEnd();
|
||||
|
||||
glBegin(GL_LINE_STRIP);
|
||||
glVertex2fv(tf->uv[0]);
|
||||
if(efa->v4) glVertex2fv(tf->uv[3]);
|
||||
else glVertex2fv(tf->uv[2]);
|
||||
glEnd();
|
||||
|
||||
glBegin(GL_LINE_STRIP);
|
||||
glVertex2fv(tf->uv[1]);
|
||||
glVertex2fv(tf->uv[2]);
|
||||
if(efa->v4) glVertex2fv(tf->uv[3]);
|
||||
glEnd();
|
||||
|
||||
setlinestyle(0);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case SI_UVDT_BLACK: /* black/white */
|
||||
case SI_UVDT_WHITE:
|
||||
cpack((sima->dt_uv==SI_UVDT_WHITE) ? 0xFFFFFF : 0x0);
|
||||
|
||||
for(efa= em->faces.first; efa; efa= efa->next) {
|
||||
tf= (MTFace *)efa->tmp.p; /* visible faces cached */
|
||||
|
||||
if(tf) {
|
||||
glBegin(GL_LINE_LOOP);
|
||||
glVertex2fv(tf->uv[0]);
|
||||
glVertex2fv(tf->uv[1]);
|
||||
glVertex2fv(tf->uv[2]);
|
||||
if(efa->v4) glVertex2fv(tf->uv[3]);
|
||||
glEnd();
|
||||
}
|
||||
}
|
||||
break;
|
||||
case SI_UVDT_OUTLINE:
|
||||
glLineWidth(3);
|
||||
cpack(0x0);
|
||||
|
||||
for(efa= em->faces.first; efa; efa= efa->next) {
|
||||
tf= (MTFace *)efa->tmp.p; /* visible faces cached */
|
||||
|
||||
if(tf) {
|
||||
glBegin(GL_LINE_LOOP);
|
||||
glVertex2fv(tf->uv[0]);
|
||||
glVertex2fv(tf->uv[1]);
|
||||
glVertex2fv(tf->uv[2]);
|
||||
if(efa->v4) glVertex2fv(tf->uv[3]);
|
||||
glEnd();
|
||||
}
|
||||
}
|
||||
|
||||
glLineWidth(1);
|
||||
col2[0] = col2[1] = col2[2] = 128; col2[3] = 255;
|
||||
glColor4ubv((unsigned char *)col2);
|
||||
|
||||
if(G.f & G_DRAWEDGES) {
|
||||
glShadeModel(GL_SMOOTH);
|
||||
UI_GetThemeColor4ubv(TH_VERTEX_SELECT, col1);
|
||||
lastsel = sel = 0;
|
||||
|
||||
for(efa= em->faces.first; efa; efa= efa->next) {
|
||||
tf= (MTFace *)efa->tmp.p; /* visible faces cached */
|
||||
|
||||
if(tf) {
|
||||
glBegin(GL_LINE_LOOP);
|
||||
sel = (uvedit_uv_selected(scene, efa, tf, 0) ? 1 : 0);
|
||||
if(sel != lastsel) { glColor4ubv(sel ? (GLubyte *)col1 : (GLubyte *)col2); lastsel = sel; }
|
||||
glVertex2fv(tf->uv[0]);
|
||||
|
||||
sel = uvedit_uv_selected(scene, efa, tf, 1) ? 1 : 0;
|
||||
if(sel != lastsel) { glColor4ubv(sel ? (GLubyte *)col1 : (GLubyte *)col2); lastsel = sel; }
|
||||
glVertex2fv(tf->uv[1]);
|
||||
|
||||
sel = uvedit_uv_selected(scene, efa, tf, 2) ? 1 : 0;
|
||||
if(sel != lastsel) { glColor4ubv(sel ? (GLubyte *)col1 : (GLubyte *)col2); lastsel = sel; }
|
||||
glVertex2fv(tf->uv[2]);
|
||||
|
||||
if(efa->v4) {
|
||||
sel = uvedit_uv_selected(scene, efa, tf, 3) ? 1 : 0;
|
||||
if(sel != lastsel) { glColor4ubv(sel ? (GLubyte *)col1 : (GLubyte *)col2); lastsel = sel; }
|
||||
glVertex2fv(tf->uv[3]);
|
||||
}
|
||||
|
||||
glEnd();
|
||||
}
|
||||
}
|
||||
glShadeModel(GL_FLAT);
|
||||
}
|
||||
else {
|
||||
/* no nice edges */
|
||||
for(efa= em->faces.first; efa; efa= efa->next) {
|
||||
tf= (MTFace *)efa->tmp.p; /* visible faces cached */
|
||||
|
||||
if(tf) {
|
||||
glBegin(GL_LINE_LOOP);
|
||||
glVertex2fv(tf->uv[0]);
|
||||
glVertex2fv(tf->uv[1]);
|
||||
glVertex2fv(tf->uv[2]);
|
||||
if(efa->v4) glVertex2fv(tf->uv[3]);
|
||||
glEnd();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
if(sima->flag & SI_SMOOTH_UV) {
|
||||
glDisable(GL_LINE_SMOOTH);
|
||||
glDisable(GL_BLEND);
|
||||
}
|
||||
|
||||
/* 5. draw face centers */
|
||||
|
||||
if(drawfaces) {
|
||||
float cent[2];
|
||||
|
||||
pointsize = UI_GetThemeValuef(TH_FACEDOT_SIZE);
|
||||
glPointSize(pointsize); // TODO - drawobject.c changes this value after - Investigate!
|
||||
|
||||
/* unselected faces */
|
||||
UI_ThemeColor(TH_WIRE);
|
||||
|
||||
bglBegin(GL_POINTS);
|
||||
for(efa= em->faces.first; efa; efa= efa->next) {
|
||||
tf= (MTFace *)efa->tmp.p; /* visible faces cached */
|
||||
|
||||
if(tf && !uvedit_face_selected(scene, efa, tf)) {
|
||||
uv_center(tf->uv, cent, efa->v4 != NULL);
|
||||
bglVertex2fv(cent);
|
||||
}
|
||||
}
|
||||
bglEnd();
|
||||
|
||||
/* selected faces */
|
||||
UI_ThemeColor(TH_FACE_DOT);
|
||||
|
||||
bglBegin(GL_POINTS);
|
||||
for(efa= em->faces.first; efa; efa= efa->next) {
|
||||
tf= (MTFace *)efa->tmp.p; /* visible faces cached */
|
||||
|
||||
if(tf && uvedit_face_selected(scene, efa, tf)) {
|
||||
uv_center(tf->uv, cent, efa->v4 != NULL);
|
||||
bglVertex2fv(cent);
|
||||
}
|
||||
}
|
||||
bglEnd();
|
||||
}
|
||||
|
||||
/* 6. draw uv vertices */
|
||||
|
||||
if(drawfaces != 2) { /* 2 means Mesh Face Mode */
|
||||
/* unselected uvs */
|
||||
UI_ThemeColor(TH_VERTEX);
|
||||
pointsize = UI_GetThemeValuef(TH_VERTEX_SIZE);
|
||||
glPointSize(pointsize);
|
||||
|
||||
bglBegin(GL_POINTS);
|
||||
for(efa= em->faces.first; efa; efa= efa->next) {
|
||||
tf= (MTFace *)efa->tmp.p; /* visible faces cached */
|
||||
|
||||
if(tf) {
|
||||
if(!uvedit_uv_selected(scene, efa, tf, 0))
|
||||
bglVertex2fv(tf->uv[0]);
|
||||
if(!uvedit_uv_selected(scene, efa, tf, 1))
|
||||
bglVertex2fv(tf->uv[1]);
|
||||
if(!uvedit_uv_selected(scene, efa, tf, 2))
|
||||
bglVertex2fv(tf->uv[2]);
|
||||
if(efa->v4 && !uvedit_uv_selected(scene, efa, tf, 3))
|
||||
bglVertex2fv(tf->uv[3]);
|
||||
}
|
||||
}
|
||||
bglEnd();
|
||||
|
||||
/* pinned uvs */
|
||||
/* give odd pointsizes odd pin pointsizes */
|
||||
glPointSize(pointsize*2 + (((int)pointsize % 2)? (-1): 0));
|
||||
cpack(0xFF);
|
||||
|
||||
bglBegin(GL_POINTS);
|
||||
for(efa= em->faces.first; efa; efa= efa->next) {
|
||||
tf= (MTFace *)efa->tmp.p; /* visible faces cached */
|
||||
|
||||
if(tf) {
|
||||
if(tf->unwrap & TF_PIN1)
|
||||
bglVertex2fv(tf->uv[0]);
|
||||
if(tf->unwrap & TF_PIN2)
|
||||
bglVertex2fv(tf->uv[1]);
|
||||
if(tf->unwrap & TF_PIN3)
|
||||
bglVertex2fv(tf->uv[2]);
|
||||
if(efa->v4 && (tf->unwrap & TF_PIN4))
|
||||
bglVertex2fv(tf->uv[3]);
|
||||
}
|
||||
}
|
||||
bglEnd();
|
||||
|
||||
/* selected uvs */
|
||||
UI_ThemeColor(TH_VERTEX_SELECT);
|
||||
glPointSize(pointsize);
|
||||
|
||||
bglBegin(GL_POINTS);
|
||||
for(efa= em->faces.first; efa; efa= efa->next) {
|
||||
tf= (MTFace *)efa->tmp.p; /* visible faces cached */
|
||||
|
||||
if(tf) {
|
||||
if(uvedit_uv_selected(scene, efa, tf, 0))
|
||||
bglVertex2fv(tf->uv[0]);
|
||||
if(uvedit_uv_selected(scene, efa, tf, 1))
|
||||
bglVertex2fv(tf->uv[1]);
|
||||
if(uvedit_uv_selected(scene, efa, tf, 2))
|
||||
bglVertex2fv(tf->uv[2]);
|
||||
if(efa->v4 && uvedit_uv_selected(scene, efa, tf, 3))
|
||||
bglVertex2fv(tf->uv[3]);
|
||||
}
|
||||
}
|
||||
bglEnd();
|
||||
}
|
||||
|
||||
glPointSize(1.0);
|
||||
}
|
||||
|
||||
void draw_uvedit_main(SpaceImage *sima, ARegion *ar, Scene *scene, Object *obedit)
|
||||
{
|
||||
int show_uvedit, show_uvshadow;
|
||||
|
||||
show_uvedit= get_space_image_show_uvedit(sima, obedit);
|
||||
show_uvshadow= get_space_image_show_uvshadow(sima, obedit);
|
||||
|
||||
if(show_uvedit || show_uvshadow) {
|
||||
/* this is basically the same object_handle_update as in the 3d view,
|
||||
* here we have to do it as well for the object we are editing if we
|
||||
* are displaying the final result */
|
||||
if(obedit && (sima->flag & SI_DRAWSHADOW))
|
||||
object_handle_update(scene, obedit);
|
||||
|
||||
if(show_uvshadow)
|
||||
draw_uvs_shadow(sima, obedit);
|
||||
else
|
||||
draw_uvs(sima, scene, obedit);
|
||||
|
||||
if(show_uvedit)
|
||||
drawcursor_sima(sima, ar);
|
||||
|
||||
// XXX becomes operator draw extra:
|
||||
// draw_image_transform(ibuf, xuser_asp, yuser_asp);
|
||||
}
|
||||
}
|
||||
|
||||
72
source/blender/editors/uvedit/uvedit_intern.h
Normal file
72
source/blender/editors/uvedit/uvedit_intern.h
Normal file
@@ -0,0 +1,72 @@
|
||||
/**
|
||||
* $Id:
|
||||
*
|
||||
* ***** BEGIN GPL LICENSE BLOCK *****
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*
|
||||
* The Original Code is Copyright (C) 2008 Blender Foundation.
|
||||
* All rights reserved.
|
||||
*
|
||||
*
|
||||
* Contributor(s): Blender Foundation
|
||||
*
|
||||
* ***** END GPL LICENSE BLOCK *****
|
||||
*/
|
||||
|
||||
#ifndef ED_UVEDIT_INTERN_H
|
||||
#define ED_UVEDIT_INTERN_H
|
||||
|
||||
struct SpaceImage;
|
||||
struct EditFace;
|
||||
struct MTFace;
|
||||
struct Scene;
|
||||
struct Image;
|
||||
struct Object;
|
||||
struct wmOperatorType;
|
||||
|
||||
#define UV_SELECT_ALL 1
|
||||
#define UV_SELECT_PINNED 2
|
||||
|
||||
/* id can be from 0 to 3 */
|
||||
#define TF_PIN_MASK(id) (TF_PIN1 << id)
|
||||
#define TF_SEL_MASK(id) (TF_SEL1 << id)
|
||||
|
||||
/* state testing */
|
||||
int uvedit_test(struct Object *obedit);
|
||||
int uvedit_test_silent(struct Object *obedit);
|
||||
|
||||
/* visibility and selection */
|
||||
int uvedit_face_visible_nolocal(struct Scene *scene, struct EditFace *efa);
|
||||
int uvedit_face_visible(struct Scene *scene, struct Image *ima, struct EditFace *efa, struct MTFace *tf);
|
||||
|
||||
int uvedit_face_selected(struct Scene *scene, struct EditFace *efa, struct MTFace *tf);
|
||||
void uvedit_face_select(struct Scene *scene, struct EditFace *efa, struct MTFace *tf);
|
||||
void uvedit_face_deselect(struct Scene *scene, struct EditFace *efa, struct MTFace *tf);
|
||||
|
||||
int uvedit_uv_selected(struct Scene *scene, struct EditFace *efa, struct MTFace *tf, int i);
|
||||
void uvedit_uv_select(struct Scene *scene, struct EditFace *efa, struct MTFace *tf, int i);
|
||||
void uvedit_uv_deselect(struct Scene *scene, struct EditFace *efa, struct MTFace *tf, int i);
|
||||
|
||||
/* geometric utilities */
|
||||
void uv_center(float uv[][2], float cent[2], int quad);
|
||||
float uv_area(float uv[][2], int quad);
|
||||
void uv_copy_aspect(float uv_orig[][2], float uv[][2], float aspx, float aspy);
|
||||
|
||||
/* operators */
|
||||
void UV_OT_de_select_all(struct wmOperatorType *ot);
|
||||
|
||||
#endif /* ED_UVEDIT_INTERN_H */
|
||||
|
||||
2401
source/blender/editors/uvedit/uvedit_ops.c
Normal file
2401
source/blender/editors/uvedit/uvedit_ops.c
Normal file
File diff suppressed because it is too large
Load Diff
4481
source/blender/editors/uvedit/uvedit_parametrizer.c
Normal file
4481
source/blender/editors/uvedit/uvedit_parametrizer.c
Normal file
File diff suppressed because it is too large
Load Diff
97
source/blender/editors/uvedit/uvedit_parametrizer.h
Normal file
97
source/blender/editors/uvedit/uvedit_parametrizer.h
Normal file
@@ -0,0 +1,97 @@
|
||||
|
||||
#ifndef __PARAMETRIZER_H__
|
||||
#define __PARAMETRIZER_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "BLO_sys_types.h" // for intptr_t support
|
||||
|
||||
typedef void ParamHandle; /* handle to a set of charts */
|
||||
typedef intptr_t ParamKey; /* (hash) key for identifying verts and faces */
|
||||
typedef enum ParamBool {
|
||||
PARAM_TRUE = 1,
|
||||
PARAM_FALSE = 0
|
||||
} ParamBool;
|
||||
|
||||
/* Chart construction:
|
||||
-------------------
|
||||
- faces and seams may only be added between construct_{begin|end}
|
||||
- the pointers to co and uv are stored, rather than being copied
|
||||
- vertices are implicitly created
|
||||
- in construct_end the mesh will be split up according to the seams
|
||||
- the resulting charts must be:
|
||||
- manifold, connected, open (at least one boundary loop)
|
||||
- output will be written to the uv pointers
|
||||
*/
|
||||
|
||||
ParamHandle *param_construct_begin();
|
||||
|
||||
void param_aspect_ratio(ParamHandle *handle, float aspx, float aspy);
|
||||
|
||||
void param_face_add(ParamHandle *handle,
|
||||
ParamKey key,
|
||||
int nverts,
|
||||
ParamKey *vkeys,
|
||||
float **co,
|
||||
float **uv,
|
||||
ParamBool *pin,
|
||||
ParamBool *select);
|
||||
|
||||
void param_edge_set_seam(ParamHandle *handle,
|
||||
ParamKey *vkeys);
|
||||
|
||||
void param_construct_end(ParamHandle *handle, ParamBool fill, ParamBool impl);
|
||||
void param_delete(ParamHandle *chart);
|
||||
|
||||
/* Least Squares Conformal Maps:
|
||||
-----------------------------
|
||||
- charts with less than two pinned vertices are assigned 2 pins
|
||||
- lscm is divided in three steps:
|
||||
- begin: compute matrix and it's factorization (expensive)
|
||||
- solve using pinned coordinates (cheap)
|
||||
- end: clean up
|
||||
- uv coordinates are allowed to change within begin/end, for
|
||||
quick re-solving
|
||||
*/
|
||||
|
||||
void param_lscm_begin(ParamHandle *handle, ParamBool live, ParamBool abf);
|
||||
void param_lscm_solve(ParamHandle *handle);
|
||||
void param_lscm_end(ParamHandle *handle);
|
||||
|
||||
/* Stretch */
|
||||
|
||||
void param_stretch_begin(ParamHandle *handle);
|
||||
void param_stretch_blend(ParamHandle *handle, float blend);
|
||||
void param_stretch_iter(ParamHandle *handle);
|
||||
void param_stretch_end(ParamHandle *handle);
|
||||
|
||||
/* Area Smooth */
|
||||
|
||||
void param_smooth_area(ParamHandle *handle);
|
||||
|
||||
/* Packing */
|
||||
|
||||
void param_pack(ParamHandle *handle);
|
||||
|
||||
/* Average area for all charts */
|
||||
|
||||
void param_average(ParamHandle *handle);
|
||||
|
||||
/* Simple x,y scale */
|
||||
|
||||
void param_scale(ParamHandle *handle, float x, float y);
|
||||
|
||||
/* Flushing */
|
||||
|
||||
void param_flush(ParamHandle *handle);
|
||||
void param_flush_restore(ParamHandle *handle);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /*__PARAMETRIZER_H__*/
|
||||
|
||||
383
source/blender/editors/uvedit/uvedit_unwrap_ops.c
Normal file
383
source/blender/editors/uvedit/uvedit_unwrap_ops.c
Normal file
@@ -0,0 +1,383 @@
|
||||
/**
|
||||
* $Id$
|
||||
*
|
||||
* ***** BEGIN GPL LICENSE BLOCK *****
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*
|
||||
* The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
|
||||
* All rights reserved.
|
||||
*
|
||||
* The Original Code is: all of this file.
|
||||
*
|
||||
* Contributor(s): none yet.
|
||||
*
|
||||
* ***** END GPL LICENSE BLOCK *****
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <math.h>
|
||||
|
||||
#include "MEM_guardedalloc.h"
|
||||
|
||||
#include "DNA_mesh_types.h"
|
||||
#include "DNA_meshdata_types.h"
|
||||
#include "DNA_object_types.h"
|
||||
#include "DNA_scene_types.h"
|
||||
#include "DNA_screen_types.h"
|
||||
#include "DNA_space_types.h"
|
||||
|
||||
#include "BKE_customdata.h"
|
||||
#include "BKE_depsgraph.h"
|
||||
#include "BKE_global.h"
|
||||
#include "BKE_mesh.h"
|
||||
#include "BKE_utildefines.h"
|
||||
|
||||
#include "BLI_arithb.h"
|
||||
#include "BLI_edgehash.h"
|
||||
#include "BLI_editVert.h"
|
||||
|
||||
#include "PIL_time.h"
|
||||
|
||||
#include "ED_mesh.h"
|
||||
|
||||
#include "uvedit_intern.h"
|
||||
#include "uvedit_parametrizer.h"
|
||||
|
||||
/* Parametrizer */
|
||||
ParamHandle *construct_param_handle(Scene *scene, EditMesh *em, short implicit, short fill, short sel)
|
||||
{
|
||||
ParamHandle *handle;
|
||||
EditFace *efa;
|
||||
EditEdge *eed;
|
||||
EditVert *ev;
|
||||
MTFace *tf;
|
||||
int a;
|
||||
|
||||
handle = param_construct_begin();
|
||||
|
||||
if ((scene->toolsettings->uvcalc_flag & UVCALC_NO_ASPECT_CORRECT)==0) {
|
||||
efa = EM_get_actFace(em, 1);
|
||||
|
||||
if (efa) {
|
||||
float aspx = 1.0f, aspy= 1.0f;
|
||||
// XXX MTFace *tf = CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
|
||||
// XXX image_final_aspect(tf->tpage, &aspx, &aspy);
|
||||
|
||||
if (aspx!=aspy)
|
||||
param_aspect_ratio(handle, aspx, aspy);
|
||||
}
|
||||
}
|
||||
|
||||
/* we need the vert indicies */
|
||||
for (ev= em->verts.first, a=0; ev; ev= ev->next, a++)
|
||||
ev->tmp.l = a;
|
||||
|
||||
for (efa= em->faces.first; efa; efa= efa->next) {
|
||||
ParamKey key, vkeys[4];
|
||||
ParamBool pin[4], select[4];
|
||||
float *co[4];
|
||||
float *uv[4];
|
||||
int nverts;
|
||||
|
||||
if ((efa->h) || (sel && (efa->f & SELECT)==0))
|
||||
continue;
|
||||
|
||||
tf= (MTFace *)CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
|
||||
|
||||
if (implicit &&
|
||||
!( uvedit_uv_selected(scene, efa, tf, 0) ||
|
||||
uvedit_uv_selected(scene, efa, tf, 1) ||
|
||||
uvedit_uv_selected(scene, efa, tf, 2) ||
|
||||
(efa->v4 && uvedit_uv_selected(scene, efa, tf, 3)) )
|
||||
) {
|
||||
continue;
|
||||
}
|
||||
|
||||
key = (ParamKey)efa;
|
||||
vkeys[0] = (ParamKey)efa->v1->tmp.l;
|
||||
vkeys[1] = (ParamKey)efa->v2->tmp.l;
|
||||
vkeys[2] = (ParamKey)efa->v3->tmp.l;
|
||||
|
||||
co[0] = efa->v1->co;
|
||||
co[1] = efa->v2->co;
|
||||
co[2] = efa->v3->co;
|
||||
|
||||
uv[0] = tf->uv[0];
|
||||
uv[1] = tf->uv[1];
|
||||
uv[2] = tf->uv[2];
|
||||
|
||||
pin[0] = ((tf->unwrap & TF_PIN1) != 0);
|
||||
pin[1] = ((tf->unwrap & TF_PIN2) != 0);
|
||||
pin[2] = ((tf->unwrap & TF_PIN3) != 0);
|
||||
|
||||
select[0] = ((uvedit_uv_selected(scene, efa, tf, 0)) != 0);
|
||||
select[1] = ((uvedit_uv_selected(scene, efa, tf, 1)) != 0);
|
||||
select[2] = ((uvedit_uv_selected(scene, efa, tf, 2)) != 0);
|
||||
|
||||
if (efa->v4) {
|
||||
vkeys[3] = (ParamKey)efa->v4->tmp.l;
|
||||
co[3] = efa->v4->co;
|
||||
uv[3] = tf->uv[3];
|
||||
pin[3] = ((tf->unwrap & TF_PIN4) != 0);
|
||||
select[3] = (uvedit_uv_selected(scene, efa, tf, 3) != 0);
|
||||
nverts = 4;
|
||||
}
|
||||
else
|
||||
nverts = 3;
|
||||
|
||||
param_face_add(handle, key, nverts, vkeys, co, uv, pin, select);
|
||||
}
|
||||
|
||||
if (!implicit) {
|
||||
for (eed= em->edges.first; eed; eed= eed->next) {
|
||||
if(eed->seam) {
|
||||
ParamKey vkeys[2];
|
||||
vkeys[0] = (ParamKey)eed->v1->tmp.l;
|
||||
vkeys[1] = (ParamKey)eed->v2->tmp.l;
|
||||
param_edge_set_seam(handle, vkeys);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
param_construct_end(handle, fill, implicit);
|
||||
|
||||
return handle;
|
||||
}
|
||||
|
||||
void unwrap_lscm(Scene *scene, Object *obedit, short seamcut)
|
||||
{
|
||||
EditMesh *em= ((Mesh*)obedit->data)->edit_mesh;
|
||||
ParamHandle *handle;
|
||||
short abf = scene->toolsettings->unwrapper == 1;
|
||||
short fillholes = scene->toolsettings->uvcalc_flag & UVCALC_FILLHOLES;
|
||||
|
||||
/* add uvs if there not here */
|
||||
if (!uvedit_test(obedit)) {
|
||||
#if 0
|
||||
if (em && em->faces.first)
|
||||
EM_add_data_layer(&em->fdata, CD_MTFACE);
|
||||
|
||||
if (!uvedit_test(obedit))
|
||||
return;
|
||||
|
||||
if (G.sima && G.sima->image) /* this is a bit of a kludge, but assume they want the image on their mesh when UVs are added */
|
||||
image_changed(G.sima, G.sima->image);
|
||||
|
||||
/* select new UV's */
|
||||
if ((G.sima==0 || G.sima->flag & SI_SYNC_UVSEL)==0) {
|
||||
EditFace *efa;
|
||||
MTFace *tf;
|
||||
for(efa=em->faces.first; efa; efa=efa->next) {
|
||||
tf= (MTFace *)CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
|
||||
simaFaceSel_Set(efa, tf);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
handle = construct_param_handle(scene, em, 0, fillholes, seamcut == 0);
|
||||
|
||||
param_lscm_begin(handle, PARAM_FALSE, abf);
|
||||
param_lscm_solve(handle);
|
||||
param_lscm_end(handle);
|
||||
|
||||
param_pack(handle);
|
||||
|
||||
param_flush(handle);
|
||||
|
||||
param_delete(handle);
|
||||
|
||||
if (!seamcut)
|
||||
; // XXX BIF_undo_push("UV unwrap");
|
||||
|
||||
DAG_object_flush_update(scene, obedit, OB_RECALC_DATA);
|
||||
|
||||
// XXX allqueue(REDRAWVIEW3D, 0);
|
||||
// XXX allqueue(REDRAWIMAGE, 0);
|
||||
}
|
||||
|
||||
void minimize_stretch_tface_uv(Scene *scene, Object *obedit)
|
||||
{
|
||||
EditMesh *em= ((Mesh*)obedit->data)->edit_mesh;
|
||||
ParamHandle *handle;
|
||||
double lasttime;
|
||||
short doit = 1, escape = 0, val, blend = 0;
|
||||
unsigned short event = 0;
|
||||
short fillholes = scene->toolsettings->uvcalc_flag & UVCALC_FILLHOLES;
|
||||
|
||||
if(!uvedit_test(obedit)) return;
|
||||
|
||||
handle = construct_param_handle(scene, em, 1, fillholes, 1);
|
||||
|
||||
lasttime = PIL_check_seconds_timer();
|
||||
|
||||
param_stretch_begin(handle);
|
||||
|
||||
while (doit) {
|
||||
param_stretch_iter(handle);
|
||||
|
||||
while (0) { // XXX qtest()) {
|
||||
event= 0; // XXX extern_qread(&val);
|
||||
|
||||
if (val) {
|
||||
#if 0
|
||||
switch (event) {
|
||||
case ESCKEY:
|
||||
escape = 1;
|
||||
case RETKEY:
|
||||
case PADENTER:
|
||||
doit = 0;
|
||||
break;
|
||||
case PADPLUSKEY:
|
||||
case WHEELUPMOUSE:
|
||||
if (blend < 10) {
|
||||
blend++;
|
||||
param_stretch_blend(handle, blend*0.1f);
|
||||
param_flush(handle);
|
||||
lasttime = 0.0f;
|
||||
}
|
||||
break;
|
||||
case PADMINUS:
|
||||
case WHEELDOWNMOUSE:
|
||||
if (blend > 0) {
|
||||
blend--;
|
||||
param_stretch_blend(handle, blend*0.1f);
|
||||
param_flush(handle);
|
||||
lasttime = 0.0f;
|
||||
}
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
else if (0) { // XXX (event == LEFTMOUSE) || (event == RIGHTMOUSE)) {
|
||||
escape = 0; // XXX (event == RIGHTMOUSE);
|
||||
doit = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (!doit)
|
||||
break;
|
||||
|
||||
if (PIL_check_seconds_timer() - lasttime > 0.5) {
|
||||
char str[100];
|
||||
|
||||
param_flush(handle);
|
||||
|
||||
sprintf(str, "Stretch minimize. Blend %.2f.", blend*0.1f);
|
||||
// XXX headerprint(str);
|
||||
|
||||
lasttime = PIL_check_seconds_timer();
|
||||
DAG_object_flush_update(scene, obedit, OB_RECALC_DATA);
|
||||
// XXX if(G.sima->lock) force_draw_plus(SPACE_VIEW3D, 0);
|
||||
// XXX else force_draw(0);
|
||||
}
|
||||
}
|
||||
|
||||
if (escape)
|
||||
param_flush_restore(handle);
|
||||
else
|
||||
param_flush(handle);
|
||||
|
||||
param_stretch_end(handle);
|
||||
|
||||
param_delete(handle);
|
||||
|
||||
// XXX BIF_undo_push("UV stretch minimize");
|
||||
|
||||
DAG_object_flush_update(scene, obedit, OB_RECALC_DATA);
|
||||
|
||||
// XXX allqueue(REDRAWVIEW3D, 0);
|
||||
// XXX allqueue(REDRAWIMAGE, 0);
|
||||
}
|
||||
|
||||
void pack_charts_tface_uv(Scene *scene, Object *obedit)
|
||||
{
|
||||
EditMesh *em= ((Mesh*)obedit->data)->edit_mesh;
|
||||
ParamHandle *handle;
|
||||
|
||||
if(!uvedit_test(obedit)) return;
|
||||
|
||||
handle = construct_param_handle(scene, em, 1, 0, 1);
|
||||
param_pack(handle);
|
||||
param_flush(handle);
|
||||
param_delete(handle);
|
||||
|
||||
// XXX BIF_undo_push("UV pack islands");
|
||||
|
||||
DAG_object_flush_update(scene, obedit, OB_RECALC_DATA);
|
||||
|
||||
// XXX allqueue(REDRAWVIEW3D, 0);
|
||||
// XXX allqueue(REDRAWIMAGE, 0);
|
||||
}
|
||||
|
||||
|
||||
void average_charts_tface_uv(Scene *scene, Object *obedit)
|
||||
{
|
||||
EditMesh *em= ((Mesh*)obedit->data)->edit_mesh;
|
||||
ParamHandle *handle;
|
||||
|
||||
if(!uvedit_test(obedit)) return;
|
||||
|
||||
handle = construct_param_handle(scene, em, 1, 0, 1);
|
||||
param_average(handle);
|
||||
param_flush(handle);
|
||||
param_delete(handle);
|
||||
|
||||
// XXX BIF_undo_push("UV average island scale");
|
||||
|
||||
DAG_object_flush_update(scene, obedit, OB_RECALC_DATA);
|
||||
|
||||
// XXX allqueue(REDRAWVIEW3D, 0);
|
||||
// XXX allqueue(REDRAWIMAGE, 0);
|
||||
}
|
||||
|
||||
/* LSCM live mode */
|
||||
|
||||
static ParamHandle *liveHandle = NULL;
|
||||
|
||||
void unwrap_lscm_live_begin(Scene *scene, Object *obedit)
|
||||
{
|
||||
EditMesh *em= ((Mesh*)obedit->data)->edit_mesh;
|
||||
short abf = scene->toolsettings->unwrapper == 1;
|
||||
short fillholes = scene->toolsettings->uvcalc_flag & UVCALC_FILLHOLES;
|
||||
|
||||
if(!uvedit_test(obedit)) return;
|
||||
|
||||
liveHandle = construct_param_handle(scene, em, 0, fillholes, 1);
|
||||
|
||||
param_lscm_begin(liveHandle, PARAM_TRUE, abf);
|
||||
}
|
||||
|
||||
void unwrap_lscm_live_re_solve(void)
|
||||
{
|
||||
if (liveHandle) {
|
||||
param_lscm_solve(liveHandle);
|
||||
param_flush(liveHandle);
|
||||
}
|
||||
}
|
||||
|
||||
void unwrap_lscm_live_end(short cancel)
|
||||
{
|
||||
if (liveHandle) {
|
||||
param_lscm_end(liveHandle);
|
||||
if (cancel)
|
||||
param_flush_restore(liveHandle);
|
||||
param_delete(liveHandle);
|
||||
liveHandle = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user