[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [14933] branches/apricot: added a fairly spesific function to Mesh. c that gets the contrast of the texture under a face (should move to Image. c)
Campbell Barton
ideasman42 at gmail.com
Fri May 23 01:25:32 CEST 2008
Revision: 14933
http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=14933
Author: campbellbarton
Date: 2008-05-23 01:25:32 +0200 (Fri, 23 May 2008)
Log Message:
-----------
added a fairly spesific function to Mesh.c that gets the contrast of the texture under a face (should move to Image.c)
added an option for lightmap UV packer that scales down faces with low light contrast for 2Pass-Adaptive-ShadowMapsTM :)
Modified Paths:
--------------
branches/apricot/release/scripts/uvcalc_lightmap.py
branches/apricot/source/blender/python/api2_2x/Mesh.c
Modified: branches/apricot/release/scripts/uvcalc_lightmap.py
===================================================================
--- branches/apricot/release/scripts/uvcalc_lightmap.py 2008-05-22 17:32:15 UTC (rev 14932)
+++ branches/apricot/release/scripts/uvcalc_lightmap.py 2008-05-22 23:25:32 UTC (rev 14933)
@@ -42,13 +42,14 @@
from math import sqrt
class prettyface(object):
- __slots__ = 'uv', 'width', 'height', 'children', 'xoff', 'yoff', 'has_parent', 'rot'
- def __init__(self, data):
+ __slots__ = 'uv', 'width', 'height', 'children', 'xoff', 'yoff', 'has_parent', 'rot', 'noarea'
+ def __init__(self, data, noarea = False):
self.has_parent = False
self.rot = False # only used for triables
self.xoff = 0
self.yoff = 0
+ self.noarea = noarea
if type(data) == list: # list of data
self.uv = None
@@ -87,14 +88,18 @@
# f, (len_min, len_mid, len_max)
self.uv = data
- f1, lens1, lens1ord = data[0]
- if data[1]:
- f2, lens2, lens2ord = data[1]
- self.width = (lens1[lens1ord[0]] + lens2[lens2ord[0]])/2
- self.height = (lens1[lens1ord[1]] + lens2[lens2ord[1]])/2
- else: # 1 tri :/
- self.width = lens1[0]
- self.height = lens1[1]
+ if noarea:
+ self.width = 0.0
+ self.height = 0.0
+ else:
+ f1, lens1, lens1ord = data[0]
+ if data[1]:
+ f2, lens2, lens2ord = data[1]
+ self.width = (lens1[lens1ord[0]] + lens2[lens2ord[0]])/2
+ self.height = (lens1[lens1ord[1]] + lens2[lens2ord[1]])/2
+ else: # 1 tri :/
+ self.width = lens1[0]
+ self.height = lens1[1]
self.children = []
@@ -102,9 +107,13 @@
else: # blender face
self.uv = data.uv
- cos = [v.co for v in data]
- self.width = ((cos[0]-cos[1]).length + (cos[2]-cos[3]).length)/2
- self.height = ((cos[1]-cos[2]).length + (cos[0]-cos[3]).length)/2
+ if noarea:
+ self.width = 0.0
+ self.height = 0.0
+ else:
+ cos = [v.co for v in data]
+ self.width = ((cos[0]-cos[1]).length + (cos[2]-cos[3]).length)/2
+ self.height = ((cos[1]-cos[2]).length + (cos[0]-cos[3]).length)/2
self.children = []
@@ -202,7 +211,9 @@
PREF_APPLY_IMAGE= False,\
PREF_IMG_PX_SIZE= 512,\
PREF_BOX_DIV= 8,\
-PREF_MARGIN_DIV= 512):
+PREF_MARGIN_DIV= 512,
+PREF_2PASS= False,\
+PREF_2PASS_ERROR= 0.05):
'''
BOX_DIV if the maximum division of the UV map that
a box may be consolidated into.
@@ -232,7 +243,7 @@
# Add face UV if it does not exist.
# All new faces are selected.
me.faceUV = True
-
+
if PREF_SEL_ONLY:
faces = [f for f in me.faces if f.sel]
else:
@@ -246,7 +257,8 @@
if PREF_NEW_UVLAYER:
me.addUVLayer('lightmap')
me.activeUVLayer = 'lightmap'
-
+
+
if PREF_PACK_TO_MANY and len(face_groups[0]) < 4:
PREF_PACK_TO_MANY = False
@@ -305,6 +317,10 @@
# Replace the old face list
face_groups[:] = face_grid.values()
+
+ print "Test1234", len(face_groups)
+ print face_groups
+
for face_sel in face_groups:
print "\nStarting unwrap"
@@ -312,14 +328,27 @@
print '\tWarning, less then 4 faces, skipping'
continue
- pretty_faces = [prettyface(f) for f in face_sel if len(f) == 4]
+ if PREF_2PASS:
+ m = int(PREF_2PASS_ERROR*255);
+ skip_faces = [ f.uvColRange<=m for f in face_sel ]
+ del m
+ else:
+ skip_faces = [False] * len(face_sel)
+ pretty_faces = [prettyface(f,skip_faces[i]) for i,f in enumerate(face_sel) if len(f) == 4]
+
+ print len(pretty_faces)
+ print pretty_faces
+
# Do we have any tri's
if len(pretty_faces) != len(face_sel):
-
# Now add tri's, not so simple because we need to pair them up.
- def trylens(f):
+ def trylens(f, noarea):
+
+ if noarea:
+ return (f, [0.0,0.0,0.0], [0,1,2]), noarea
+
# f must be a tri
cos = [v.co for v in f]
lens = [(cos[0] - cos[1]).length, (cos[1] - cos[2]).length, (cos[2] - cos[0]).length]
@@ -332,9 +361,9 @@
break
lens_order = lens_min, lens_mid, lens_max
- return f, lens, lens_order
+ return (f, lens, lens_order), noarea
- tri_lengths = [trylens(f) for f in face_sel if len(f) == 3]
+ tri_lengths = [trylens(f,skip_faces[i]) for f,i in enumerate(face_sel) if len(f) == 3]
del trylens
def trilensdiff(t1,t2):
@@ -344,33 +373,41 @@
abs(t1[1][t1[2][2]]-t2[1][t2[2][2]])
while tri_lengths:
- tri1 = tri_lengths.pop()
+ tri1, noarea = tri_lengths.pop()
if not tri_lengths:
- pretty_faces.append(prettyface((tri1, None)))
+ pretty_faces.append(prettyface((tri1, None), noarea))
break
best_tri_index = -1
best_tri_diff = 100000000.0
+ best_noarea = False
- for i, tri2 in enumerate(tri_lengths):
+ i=0
+ for tri2, noarea in enumerate(tri_lengths):
diff = trilensdiff(tri1, tri2)
if diff < best_tri_diff:
best_tri_index = i
best_tri_diff = diff
+
+ if diff==0: break
+ i+=1
- pretty_faces.append(prettyface((tri1, tri_lengths.pop(best_tri_index))))
+ pretty_faces.append(prettyface((tri1, tri_lengths.pop(best_tri_index) )) )
# Get the min, max and total areas
max_area = 0.0
min_area = 100000000.0
tot_area = 0
- for f in face_sel:
- area = f.area
- if area > max_area: max_area = area
- if area < min_area: min_area = area
- tot_area += area
+ for i,f in enumerate(face_sel):
+ if skip_faces[i]:
+ min_area = 0.0
+ else:
+ area = f.area
+ if area > max_area: max_area = area
+ if area < min_area: min_area = area
+ tot_area += area
max_len = sqrt(max_area)
min_len = sqrt(min_area)
@@ -381,7 +418,13 @@
curr_len = max_len
print '\tGenerating lengths...',
+
+ print "test"
+ print "test", min_len
+ print "test", curr_len
+ print skip_faces
+
lengths = []
while curr_len > min_len:
lengths.append(curr_len)
@@ -393,6 +436,9 @@
if curr_len/4 < side_len/PREF_MARGIN_DIV:
break
+
+
+
# convert into ints
lengths_to_ints = {}
@@ -402,6 +448,7 @@
l_int*=2
lengths_to_ints = lengths_to_ints.items()
+
lengths_to_ints.sort()
print 'done'
@@ -579,6 +626,8 @@
PREF_APPLY_IMAGE = Draw.Create(0)
PREF_IMG_PX_SIZE = Draw.Create(512)
PREF_BOX_DIV = Draw.Create(12)
+ PREF_2PASS = Draw.Create(0)
+ PREF_2PASS_ERROR = Draw.Create(0.002)
PREF_MARGIN_DIV = Draw.Create(0.1)
if not Draw.PupBlock('Lightmap Pack', [\
@@ -588,12 +637,12 @@
'UV Packing...',
('Pack Quality: ', PREF_BOX_DIV, 1, 48, 'Pre Packing before the complex boxpack'),\
('Margin: ', PREF_MARGIN_DIV, 0.001, 1.0, 'Size of the margin as a division of the UV'),\
- '',\
- '',\
+ ('2ndPassOptimize', PREF_2PASS, 'Faces with low contrast on the active UV layers image get scaled down.'),\
+ ('Pass Error: ', PREF_2PASS_ERROR, 0.001, 1.0, 'Use with 2nd pass optimize, faces with a contrast lower then this margin will be scaled down'),\
'Image & UVs...',
('Share Tex Space', PREF_PACK_IN_ONE, 'Objects Share texture space, map all objects into 1 uvmap'),\
- ('Tile Images: ', PREF_PACK_IN_MANY, 1, 16, 'Tile images over one or more mesh, value squared (n*n)'),\
+ ('Tile Images: ', PREF_PACK_IN_MANY, 0, 16, 'Tile images over one or more mesh, value squared (n*n)'),\
('New UV Layer', PREF_NEW_UVLAYER, 'Create a new UV layer for every mesh packed'),\
('New Image', PREF_APPLY_IMAGE, 'Assign new images for every mesh (only one if shared tex space enabled)'),\
('Image Size', PREF_IMG_PX_SIZE, 64, 5000, 'Width and Height for the new image'),\
@@ -630,7 +679,10 @@
PREF_APPLY_IMAGE.val,\
PREF_IMG_PX_SIZE.val,\
PREF_BOX_DIV.val,\
- int(1/(PREF_MARGIN_DIV.val/100)))
+ int(1/(PREF_MARGIN_DIV.val/100)),\
+ PREF_2PASS.val,\
+ PREF_2PASS_ERROR.val,\
+ )
if is_editmode:
Window.EditMode(1)
Modified: branches/apricot/source/blender/python/api2_2x/Mesh.c
===================================================================
--- branches/apricot/source/blender/python/api2_2x/Mesh.c 2008-05-22 17:32:15 UTC (rev 14932)
+++ branches/apricot/source/blender/python/api2_2x/Mesh.c 2008-05-22 23:25:32 UTC (rev 14933)
@@ -89,6 +89,8 @@
#include "gen_library.h"
#include "multires.h"
+#include "IMB_imbuf_types.h" /* for the IB_rect define */
+
/* EXPP Mesh defines */
#define MESH_SMOOTHRESH 30
@@ -3950,6 +3952,112 @@
}
/*
+ * this is a util to get the color range for this UV faces
+ */
+
+/* Warning - this is ordered - need to test both orders to be sure */
+#define SIDE_OF_LINE(pa,pb,pp) ((pa[0]-pp[0])*(pb[1]-pp[1]))-((pb[0]-pp[0])*(pa[1]-pp[1]))
+#define POINT_IN_TRI(p0,p1,p2,p3) ((SIDE_OF_LINE(p1,p2,p0)>=0) && (SIDE_OF_LINE(p2,p3,p0)>=0) && (SIDE_OF_LINE(p3,p1,p0)>=0))
+
+static PyObject *MFace_getUVColRange( BPy_MFace * self )
+{
+ MFace *mface = MFace_get_pointer( self );
+ MTFace *face;
+ if( !self->mesh->mtface )
+ return EXPP_ReturnPyObjError( PyExc_ValueError,
+ "face has no texture values" );
+
+ if( !mface )
+ return NULL;
+
+ face = &self->mesh->mtface[self->index];
+
+ if( !face->tpage ) {
+ return PyInt_FromLong( 0 );
+ } else {
+ ImBuf *ibuf= BKE_image_get_ibuf((Image *)face->tpage, NULL);
+
+ if (!ibuf || !ibuf->rect || ibuf->type == 1) {
+ return PyInt_FromLong( 0 );
+ } else {
+ char *pixel, *p; /* image data */
+ int index; /* offset into image data */
+ int x = 0;
+ int y = 0;
+ float uv[2];
+ int pixel_size = 4; /* each pixel is 4 x 8-bits packed in unsigned int */
+ int i, length = (mface->v4==0 ? 3:4);
+ float xmin, ymin, xmax, ymax;
+ int xmini, ymini, xmaxi, ymaxi;
+ int col_min = 255, col_max = 0, ok = 0;
+
+ /* clamp to 0-1 for now */
+ xmin = ymin = 1.0f;
+ xmax = ymax = 0.0f;
+
+ for (i=0; i < length; i++) {
+ xmin = MIN2(xmin, face->uv[i][0]);
+ ymin = MIN2(ymin, face->uv[i][1]);
+
+ xmax = MAX2(xmax, face->uv[i][0]);
+ ymax = MAX2(ymax, face->uv[i][1]);
+ }
+
+ xmini = (int)(ibuf->x * xmin);
+ ymini = (int)(ibuf->y * ymin);
+
+ xmaxi = (int)(ibuf->x * xmax) +1;
+ ymaxi = (int)(ibuf->y * ymax) +1;
+
+ printf("%d %d %d %d \n", xmini, ymini, xmaxi, ymaxi);
+
+ if (xmini < 0) xmini = 0;
+ if (ymini < 0) ymini = 0;
+
+ if (xmaxi > ibuf->x) xmaxi = ibuf->x;
+ if (ymaxi > ibuf->y) ymaxi = ibuf->y;
+
+
+
+ if (xmini == xmaxi || ymini == ymaxi) {
+ return PyInt_FromLong( 0 );
+ }
+
+ x = xmini;
+ y = ymini;
+
+ pixel = ( char * ) ibuf->rect;
+
+ for (x = xmini; x < xmaxi; x++) {
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-blender-cvs
mailing list