Uv Tools branch GSOC 2011

=========================
Documentation: http://wiki.blender.org/index.php/User:Psy-Fi/UV_Tools

Major features include:

*16 bit image support in viewport
*Subsurf aware unwrapping
*Smart Stitch(snap/rotate islands, preview, middlepoint/endpoint stitching)
*Seams from islands tool (marks seams and sharp, depending on settings)
*Uv Sculpting(Grab/Pinch/Rotate)

All tools are complete apart from stitching that is considered stable but with an extra edge mode under development(will be in soc-2011-onion-uv-tools).
This commit is contained in:
2012-01-17 16:31:13 +00:00
parent fcc54520d1
commit a8081c1d2b
42 changed files with 3727 additions and 320 deletions

View File

@@ -410,9 +410,12 @@ int GPU_verify_image(Image *ima, ImageUser *iuser, int tftile, int compare, int
ImBuf *ibuf = NULL;
unsigned int *bind = NULL;
int rectw, recth, tpx=0, tpy=0, y;
unsigned int *rectrow, *tilerectrow;
unsigned int *tilerect= NULL, *scalerect= NULL, *rect= NULL;
float *ftilerect= NULL, *fscalerect = NULL, *frect = NULL;
float *srgb_frect = NULL;
short texwindx, texwindy, texwinsx, texwinsy;
/* flag to determine whether high resolution format is used */
int use_high_bit_depth = FALSE, do_color_management = FALSE;
/* initialize tile mode and number of repeats */
GTS.ima = ima;
@@ -462,9 +465,20 @@ int GPU_verify_image(Image *ima, ImageUser *iuser, int tftile, int compare, int
if(ibuf==NULL)
return 0;
/* ensure we have a char buffer and not only float */
if ((ibuf->rect==NULL) && ibuf->rect_float)
IMB_rect_from_float(ibuf);
if(ibuf->rect_float) {
if(U.use_16bit_textures) {
/* use high precision textures. This is relatively harmless because OpenGL gives us
a high precision format only if it is available */
use_high_bit_depth = TRUE;
}
/* TODO unneeded when float images are correctly treated as linear always */
if(ibuf->profile == IB_PROFILE_LINEAR_RGB)
do_color_management = TRUE;
if(ibuf->rect==NULL)
IMB_rect_from_float(ibuf);
}
/* currently, tpage refresh is used by ima sequences */
if(ima->tpageflag & IMA_TPAGE_REFRESH) {
@@ -498,17 +512,39 @@ int GPU_verify_image(Image *ima, ImageUser *iuser, int tftile, int compare, int
tpx= texwindx;
tpy= texwindy;
rect= ibuf->rect + texwinsy*ibuf->x + texwinsx;
if(use_high_bit_depth) {
if(do_color_management) {
srgb_frect = MEM_mallocN(ibuf->x*ibuf->y*sizeof(float)*4, "floar_buf_col_cor");
IMB_buffer_float_from_float(srgb_frect, ibuf->rect_float,
ibuf->channels, IB_PROFILE_SRGB, ibuf->profile, 0,
ibuf->x, ibuf->y, ibuf->x, ibuf->x);
frect= srgb_frect + texwinsy*ibuf->x + texwinsx;
}
else
frect= ibuf->rect_float + texwinsy*ibuf->x + texwinsx;
}
else
rect= ibuf->rect + texwinsy*ibuf->x + texwinsx;
}
}
else {
/* regular image mode */
bind= &ima->bindcode;
if(*bind==0) {
tpx= ibuf->x;
tpy= ibuf->y;
rect= ibuf->rect;
if(use_high_bit_depth) {
if(do_color_management) {
frect = srgb_frect = MEM_mallocN(ibuf->x*ibuf->y*sizeof(*srgb_frect)*4, "floar_buf_col_cor");
IMB_buffer_float_from_float(srgb_frect, ibuf->rect_float,
ibuf->channels, IB_PROFILE_SRGB, ibuf->profile, 0,
ibuf->x, ibuf->y, ibuf->x, ibuf->x);
}
else
frect= ibuf->rect_float;
}
}
}
@@ -523,26 +559,57 @@ int GPU_verify_image(Image *ima, ImageUser *iuser, int tftile, int compare, int
/* for tiles, copy only part of image into buffer */
if (GTS.tilemode) {
tilerect= MEM_mallocN(rectw*recth*sizeof(*tilerect), "tilerect");
if(use_high_bit_depth) {
float *frectrow, *ftilerectrow;
for (y=0; y<recth; y++) {
rectrow= &rect[y*ibuf->x];
tilerectrow= &tilerect[y*rectw];
memcpy(tilerectrow, rectrow, tpx*sizeof(*rectrow));
ftilerect= MEM_mallocN(rectw*recth*sizeof(*ftilerect), "tilerect");
for (y=0; y<recth; y++) {
frectrow= &frect[y*ibuf->x];
ftilerectrow= &ftilerect[y*rectw];
memcpy(ftilerectrow, frectrow, tpx*sizeof(*frectrow));
}
frect= ftilerect;
}
else {
unsigned int *rectrow, *tilerectrow;
tilerect= MEM_mallocN(rectw*recth*sizeof(*tilerect), "tilerect");
for (y=0; y<recth; y++) {
rectrow= &rect[y*ibuf->x];
tilerectrow= &tilerect[y*rectw];
memcpy(tilerectrow, rectrow, tpx*sizeof(*rectrow));
}
rect= tilerect;
rect= tilerect;
}
}
/* scale if not a power of two */
/* scale if not a power of two. this is not strictly necessary for newer
GPUs (OpenGL version >= 2.0) since they support non-power-of-two-textures */
if (!is_pow2_limit(rectw) || !is_pow2_limit(recth)) {
rectw= smaller_pow2_limit(rectw);
recth= smaller_pow2_limit(recth);
scalerect= MEM_mallocN(rectw*recth*sizeof(*scalerect), "scalerect");
gluScaleImage(GL_RGBA, tpx, tpy, GL_UNSIGNED_BYTE, rect, rectw, recth, GL_UNSIGNED_BYTE, scalerect);
rect= scalerect;
if(use_high_bit_depth) {
fscalerect= MEM_mallocN(rectw*recth*sizeof(*fscalerect)*4, "fscalerect");
gluScaleImage(GL_RGBA, tpx, tpy, GL_FLOAT, frect, rectw, recth, GL_FLOAT, fscalerect);
/* frect will refer to ibuf->rect_float when not color converting. We don't want to free that */
if(do_color_management)
MEM_freeN(frect);
frect = fscalerect;
}
else {
scalerect= MEM_mallocN(rectw*recth*sizeof(*scalerect), "scalerect");
gluScaleImage(GL_RGBA, tpx, tpy, GL_UNSIGNED_BYTE, rect, rectw, recth, GL_UNSIGNED_BYTE, scalerect);
rect= scalerect;
}
}
/* create image */
@@ -550,12 +617,18 @@ int GPU_verify_image(Image *ima, ImageUser *iuser, int tftile, int compare, int
glBindTexture( GL_TEXTURE_2D, *bind);
if (!(gpu_get_mipmap() && mipmap)) {
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, rectw, recth, 0, GL_RGBA, GL_UNSIGNED_BYTE, rect);
if(use_high_bit_depth)
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA16, rectw, recth, 0, GL_RGBA, GL_FLOAT, frect);
else
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, rectw, recth, 0, GL_RGBA, GL_UNSIGNED_BYTE, rect);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, gpu_get_mipmap_filter(1));
}
else {
gluBuild2DMipmaps(GL_TEXTURE_2D, GL_RGBA, rectw, recth, GL_RGBA, GL_UNSIGNED_BYTE, rect);
if(use_high_bit_depth)
gluBuild2DMipmaps(GL_TEXTURE_2D, GL_RGBA16, rectw, recth, GL_RGBA, GL_FLOAT, frect);
else
gluBuild2DMipmaps(GL_TEXTURE_2D, GL_RGBA, rectw, recth, GL_RGBA, GL_UNSIGNED_BYTE, rect);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, gpu_get_mipmap_filter(0));
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, gpu_get_mipmap_filter(1));
@@ -570,9 +643,14 @@ int GPU_verify_image(Image *ima, ImageUser *iuser, int tftile, int compare, int
/* clean up */
if (tilerect)
MEM_freeN(tilerect);
if (ftilerect)
MEM_freeN(ftilerect);
if (scalerect)
MEM_freeN(scalerect);
if (fscalerect)
MEM_freeN(fscalerect);
if (srgb_frect)
MEM_freeN(srgb_frect);
return *bind;
}
@@ -692,23 +770,21 @@ void GPU_paint_update_image(Image *ima, int x, int y, int w, int h, int mipmap)
glGetIntegerv(GL_UNPACK_SKIP_PIXELS, &skip_pixels);
glGetIntegerv(GL_UNPACK_SKIP_ROWS, &skip_rows);
if (ibuf->rect_float){
/*This case needs a whole new buffer*/
if(ibuf->rect==NULL) {
IMB_rect_from_float(ibuf);
}
else {
/* Do partial drawing. 'buffer' holds only the changed part. Needed for color corrected result */
float *buffer = (float *)MEM_mallocN(w*h*sizeof(float)*4, "temp_texpaint_float_buf");
IMB_partial_rect_from_float(ibuf, buffer, x, y, w, h);
glBindTexture(GL_TEXTURE_2D, ima->bindcode);
glTexSubImage2D(GL_TEXTURE_2D, 0, x, y, w, h, GL_RGBA,
/* if color correction is needed, we must update the part that needs updating. */
if(ibuf->rect_float && (!U.use_16bit_textures || (ibuf->profile == IB_PROFILE_LINEAR_RGB))) {
float *buffer = MEM_mallocN(w*h*sizeof(float)*4, "temp_texpaint_float_buf");
IMB_partial_rect_from_float(ibuf, buffer, x, y, w, h);
glBindTexture(GL_TEXTURE_2D, ima->bindcode);
glTexSubImage2D(GL_TEXTURE_2D, 0, x, y, w, h, GL_RGBA,
GL_FLOAT, buffer);
MEM_freeN(buffer);
if(ima->tpageflag & IMA_MIPMAP_COMPLETE)
ima->tpageflag &= ~IMA_MIPMAP_COMPLETE;
return;
}
MEM_freeN(buffer);
if(ima->tpageflag & IMA_MIPMAP_COMPLETE)
ima->tpageflag &= ~IMA_MIPMAP_COMPLETE;
return;
}
glBindTexture(GL_TEXTURE_2D, ima->bindcode);
@@ -717,8 +793,12 @@ void GPU_paint_update_image(Image *ima, int x, int y, int w, int h, int mipmap)
glPixelStorei(GL_UNPACK_SKIP_PIXELS, x);
glPixelStorei(GL_UNPACK_SKIP_ROWS, y);
glTexSubImage2D(GL_TEXTURE_2D, 0, x, y, w, h, GL_RGBA,
GL_UNSIGNED_BYTE, ibuf->rect);
if(ibuf->rect_float)
glTexSubImage2D(GL_TEXTURE_2D, 0, x, y, w, h, GL_RGBA,
GL_FLOAT, ibuf->rect_float);
else
glTexSubImage2D(GL_TEXTURE_2D, 0, x, y, w, h, GL_RGBA,
GL_UNSIGNED_BYTE, ibuf->rect);
glPixelStorei(GL_UNPACK_ROW_LENGTH, row_length);
glPixelStorei(GL_UNPACK_SKIP_PIXELS, skip_pixels);