[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