[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [15253] branches/soc-2008-jaguarandi: Added merge option to shrinkwrap when using projection mode ( bruteforce for now)

André Pinto andresusanopinto at gmail.com
Tue Jun 17 21:00:37 CEST 2008


Revision: 15253
          http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=15253
Author:   jaguarandi
Date:     2008-06-17 21:00:21 +0200 (Tue, 17 Jun 2008)

Log Message:
-----------
Added merge option to shrinkwrap when using projection mode (bruteforce for now)
Changed code to remove faces (now quad faces that got one vertice projected are turned on tri)

Merge option is still not very usefull since shrinkwrap does not yet moves unprojected vertices

Modified Paths:
--------------
    branches/soc-2008-jaguarandi/release/scripts/CreatePlane.py
    branches/soc-2008-jaguarandi/source/blender/blenkernel/BKE_shrinkwrap.h
    branches/soc-2008-jaguarandi/source/blender/blenkernel/intern/modifier.c
    branches/soc-2008-jaguarandi/source/blender/blenkernel/intern/shrinkwrap.c
    branches/soc-2008-jaguarandi/source/blender/makesdna/DNA_modifier_types.h
    branches/soc-2008-jaguarandi/source/blender/src/buttons_editing.c

Modified: branches/soc-2008-jaguarandi/release/scripts/CreatePlane.py
===================================================================
--- branches/soc-2008-jaguarandi/release/scripts/CreatePlane.py	2008-06-17 18:36:29 UTC (rev 15252)
+++ branches/soc-2008-jaguarandi/release/scripts/CreatePlane.py	2008-06-17 19:00:21 UTC (rev 15253)
@@ -45,24 +45,23 @@
 def matrix(dima, dimb):
 	return [[0 for b in range(dimb)] for a in range(dima)]
 
-def makelist(a):
-	res = []
-	for i in a:
-		res.append(i)
-	return res
-
 def dotProduct(a):
-	sum = 0.0
-	for i in a:
-		sum += i*i
-	return sum
+	return reduce(lambda x, y: x + y*y, a) 
 
+def manhattanDistance(a, b):
+	return reduce(lambda x, y: x + abs(y[0]-y[1]), zip(a, b), 0)
+
+def xrange_tuple(low, upper):
+	for i in xrange( low[0], upper[0]):
+		for j in xrange( low[1], upper[1]):
+			yield (i,j)
+
+
 # For now simply decompose in a triangle fan
 def DecomposePolygon(poly):
-	for i in range(2, len(poly), 1):
+	for i in xrange(2, len(poly), 1):
 		yield [ poly[0], poly[i-1], poly[i] ]
 
-
 def Expand3dCoordsFrom2d(coords):
 	for c in coords:
 		yield ( c[0] , c[1], 0 )
@@ -76,35 +75,42 @@
 	mdim = max( image.size )
 	dx = float(image.size[0]) / x_samples
 	dy = float(image.size[1]) / y_samples
-	ox = -float(x_samples)*0.5
-	oy = -float(y_samples)*0.5
 
+	offset = [ -0.5*i for i in image.size]
+
 	def scale(a):
-		return ( (a[0] + ox)*dx , (a[1] + oy)*dy )
-			
-	used = matrix(x_samples, y_samples)
-	for a in range(x_samples):
-		for b in range(y_samples):
-			if dotProduct(image.getPixelHDR( (int)(a*dx), (int)(b*dy))) <= 1:
-				used[a][b] = 1
+		return (a[0] + offset[0] , a[1] + offset[1])
+	
+	sx = 0
+#(int) (float(image.size[0]) / (x_samples))
+	sy = 0
+#(int) (float(image.size[1]) / (y_samples))
 
-	for a in range(x_samples-1):
-		for b in range(y_samples-1):
-			sum = used[a][b] + used[a+1][b] + used[a][b+1] + used[a+1][b+1]
-			
-			if sum == 4:
-				yield map( scale, [ (a,b) , (a+1,b), (a+1,b+1), (a,b+1) ] )
-			elif sum == 3:
-				if not used[a][b]:
-					yield map( scale, [ (a+1,b), (a+1,b+1) , (a,b+1) ] )
-				if not used[a+1][b]:
-					yield map( scale, [ (a,b), (a+1,b+1) , (a,b+1) ] )
-				if not used[a][b+1]:
-					yield map( scale, [ (a,b), (a+1,b) , (a+1,b+1) ] )
-				if not used[a+1][b+1]:
-					yield map( scale, [ (a,b), (a+1,b) , (a,b+1) ] )
-					
+	def get( center ):
+		best = None
+		for pos in xrange_tuple( (max(0, center[0]-sx),max(0, center[1]-sy)) , (min(image.size[0], center[0]+sx)+1, min(image.size[1], center[1]+sy)+1 )):
+				if dotProduct(image.getPixelHDR(pos[0],pos[1])) <= 1:
+					if best == None or manhattanDistance(center, pos) < manhattanDistance(center, best):
+						best = pos
+		return best
 
+
+	pos = matrix(x_samples, y_samples)
+	sdx = dx
+	sdy = dy
+	for a in xrange(x_samples):
+		for b in xrange(y_samples):
+			pos[a][b] = get(((int)(a*sdx),(int)(b*sdy)))
+
+	for a in xrange(x_samples-1):
+		for b in xrange(y_samples-1):
+			arround = [ (a,b) , (a+1,b), (a+1,b+1), (a,b+1) ]
+
+			valid = [ pos[c[0]][c[1]] for c in arround if pos[c[0]][c[1]] != None]
+			if len(valid) >= 3:
+				yield map( scale, valid )
+				
+
 def ImportPlaneFromImage(image, mesh):
 
 	new_verts = []
@@ -134,8 +140,6 @@
 
 
 
-#use the current image on the image editor? or ask the user what image to load
-#image = Blender.Image.GetCurrent()
 
 def load_image(filename):
 	print "Loading ",filename
@@ -144,11 +148,13 @@
 	Blender.Scene.GetCurrent().objects.new(mesh)
 
 	image = Blender.Image.Load(filename)
-	print image
 	ImportPlaneFromImage(image, mesh)
 	Blender.Redraw()
 	
 
-image = Blender.Window.FileSelector(load_image, "Load Image")
+Blender.Window.FileSelector(load_image, "Load Image")
+#use the current image on the image editor? or ask the user what image to load
+#image = Blender.Image.GetCurrent()
+#load_image("/home/darkaj/develop/blender/shrinkwrap/road.png")
 
 

Modified: branches/soc-2008-jaguarandi/source/blender/blenkernel/BKE_shrinkwrap.h
===================================================================
--- branches/soc-2008-jaguarandi/source/blender/blenkernel/BKE_shrinkwrap.h	2008-06-17 18:36:29 UTC (rev 15252)
+++ branches/soc-2008-jaguarandi/source/blender/blenkernel/BKE_shrinkwrap.h	2008-06-17 19:00:21 UTC (rev 15253)
@@ -39,8 +39,10 @@
 
 #define bitset_get(set,index)	((set)[(index)>>3] & (1 << ((index)&0x7)))
 #define bitset_set(set,index)	((set)[(index)>>3] |= (1 << ((index)&0x7)))
+#define bitset_unset(set,index)	((set)[(index)>>3] &= ~(1 << ((index)&0x7)))
 
 
+
 struct Object;
 struct DerivedMesh;
 struct ShrinkwrapModifierData;

Modified: branches/soc-2008-jaguarandi/source/blender/blenkernel/intern/modifier.c
===================================================================
--- branches/soc-2008-jaguarandi/source/blender/blenkernel/intern/modifier.c	2008-06-17 18:36:29 UTC (rev 15252)
+++ branches/soc-2008-jaguarandi/source/blender/blenkernel/intern/modifier.c	2008-06-17 19:00:21 UTC (rev 15253)
@@ -7021,6 +7021,7 @@
 	smd->shrinkType = MOD_SHRINKWRAP_NEAREST_SURFACE;
 	smd->shrinkOpts = MOD_SHRINKWRAP_ALLOW_DEFAULT_NORMAL;
 	smd->keptDist	= 0.0f;
+	smd->mergeDist	= 0.0f;
 }
 
 static void shrinkwrapModifier_copyData(ModifierData *md, ModifierData *target)

Modified: branches/soc-2008-jaguarandi/source/blender/blenkernel/intern/shrinkwrap.c
===================================================================
--- branches/soc-2008-jaguarandi/source/blender/blenkernel/intern/shrinkwrap.c	2008-06-17 18:36:29 UTC (rev 15252)
+++ branches/soc-2008-jaguarandi/source/blender/blenkernel/intern/shrinkwrap.c	2008-06-17 19:00:21 UTC (rev 15253)
@@ -29,6 +29,7 @@
 #include <string.h>
 #include <float.h>
 #include <math.h>
+#include <memory.h>
 #include <stdio.h>
 #include <time.h>
 
@@ -58,7 +59,7 @@
 #define OUT_OF_MEMORY()	((void)printf("Shrinkwrap: Out of memory\n"))
 
 /* Benchmark macros */
-#if 1
+#if 0
 
 #define BENCH(a)	\
 	do {			\
@@ -323,6 +324,82 @@
 }
 
 /*
+ *
+ */
+static void derivedmesh_mergeNearestPoints(DerivedMesh *dm, float mdist, BitSet skipVert)
+{
+	if(mdist > 0.0f)
+	{
+		int i, j, merged;
+		int	numVerts = dm->getNumVerts(dm);
+		int *translate_vert = MEM_mallocN( sizeof(int)*numVerts, "merge points array");
+
+		MVert *vert = dm->getVertDataArray(dm, CD_MVERT);
+
+		if(!translate_vert) return;
+
+		merged = 0;
+		for(i=0; i<numVerts; i++)
+		{
+			translate_vert[i] = i;
+
+			if(skipVert && bitset_get(skipVert, i)) continue;
+
+			for(j = 0; j<i; j++)
+			{
+				if(skipVert && bitset_get(skipVert, j)) continue;
+				if(squared_dist(vert[i].co, vert[j].co) < mdist)
+				{
+					translate_vert[i] = j;
+					merged++;
+					break;
+				}
+			}
+		}
+
+		//some vertexs were merged.. recalculate structure (edges and faces)
+		if(merged > 0)
+		{
+			int	numFaces = dm->getNumFaces(dm);
+			int freeVert;
+			MFace *face = dm->getFaceDataArray(dm, CD_MFACE);
+
+
+			//Adjust vertexs using the translation_table.. only translations to back indexs are allowed
+			//which means t[i] <= i must always verify
+			for(i=0, freeVert = 0; i<numVerts; i++)
+			{
+				if(translate_vert[i] == i)
+				{
+					memcpy(&vert[freeVert], &vert[i], sizeof(*vert));
+					translate_vert[i] = freeVert++;
+				}
+				else translate_vert[i] = translate_vert[ translate_vert[i] ];
+			}
+
+			CDDM_lower_num_verts(dm, numVerts - merged);
+
+			for(i=0; i<numFaces; i++)
+			{
+				MFace *f = face+i;
+				f->v1 = translate_vert[f->v1];
+				f->v2 = translate_vert[f->v2];
+				f->v3 = translate_vert[f->v3];
+				//TODO be carefull with vertexs v4 being translated to 0
+				f->v4 = translate_vert[f->v4];
+			}
+
+			//TODO: maybe update edges could be done outside this function
+			CDDM_calc_edges(dm);
+			//CDDM_calc_normals(dm);
+		}
+
+		if(translate_vert) MEM_freeN( translate_vert );
+	}
+}
+
+
+/*
  * This calculates the distance (in dir units) that the ray must travel to intersect plane
  * It can return negative values
  *
@@ -703,25 +780,57 @@
 	BitSet used_faces = bitset_new(numFaces, "shrinkwrap used faces");
 	int numUsedFaces = 0;
 
+
+	//calculate which vertexs need to be used
+	//even unmoved vertices might need to be used if theres a face that needs it
 	//calc real number of faces, and vertices
 	//Count used faces
 	for(i=0; i<numFaces; i++)
 	{
-		char res = bitset_get(moved_verts, face[i].v1)
-				 | bitset_get(moved_verts, face[i].v2)
-				 | bitset_get(moved_verts, face[i].v3)
-				 | (face[i].v4 ? bitset_get(moved_verts, face[i].v4) : 0);
+		char res = 0;
+		if(bitset_get(moved_verts, face[i].v1)) res++;
+		if(bitset_get(moved_verts, face[i].v2)) res++;
+		if(bitset_get(moved_verts, face[i].v3)) res++;
+		if(face[i].v4 && bitset_get(moved_verts, face[i].v4)) res++;
 
-		if(res)
+		//Ignore a face were not a single vertice moved
+		if(res == 0) continue;
+
+		//Only 1 vertice moved.. (if its a quad.. remove the vertice oposite to it)
+		if(res == 1 && face[i].v4)
 		{
-			bitset_set(used_faces, i);	//Mark face to maintain
-			numUsedFaces++;
+			if(bitset_get(moved_verts, face[i].v1))
+			{
+				//remove vertex 3
+				face[i].v3 = face[i].v4;
+			}
+			else if(bitset_get(moved_verts, face[i].v2))
+			{
+				//remove vertex 4
+			}
+			else if(bitset_get(moved_verts, face[i].v3))
+			{
+				//remove vertex 1
+				face[i].v1 = face[i].v4;
+			}
+			else if(bitset_get(moved_verts, face[i].v4))
+			{
+				//remove vertex 2
+				face[i].v2 = face[i].v3;
+				face[i].v3 = face[i].v4;
+			}
 
-			vert_index[face[i].v1] = 1;
-			vert_index[face[i].v2] = 1;
-			vert_index[face[i].v3] = 1;
-			if(face[i].v4) vert_index[face[i].v4] = 1;
+			face[i].v4 = 0;	//this quad turned on a tri
 		}
+
+		bitset_set(used_faces, i);	//Mark face to maintain
+		numUsedFaces++;
+
+		//Mark vertices are needed
+		vert_index[face[i].v1] = 1;
+		vert_index[face[i].v2] = 1;
+		vert_index[face[i].v3] = 1;
+		if(face[i].v4) vert_index[face[i].v4] = 1;
 	}
 
 	//DP: Accumulate vertexs indexs.. (will calculate the new vertex index with a 1 offset)
@@ -736,10 +845,16 @@
 	new_vert  = new->getVertDataArray(new, CD_MVERT);
 	for(i=0, t=0; i<numVerts; i++)
 	{
+		
 		if(vert_index[i] != t)
 		{
 			t = vert_index[i];
 			memcpy(new_vert++, vert+i, sizeof(MVert));
+
+			if(bitset_get(moved_verts, i))
+				bitset_set(moved_verts, t-1);
+			else
+				bitset_unset(moved_verts, t-1);
 		}
 	}
 
@@ -779,6 +894,7 @@
 	calc->final = new;
 }
 
+
 /* Main shrinkwrap function */
 DerivedMesh *shrinkwrapModifier_do(ShrinkwrapModifierData *smd, Object *ob, DerivedMesh *dm, int useRenderParams, int isFinalCalc)
 {
@@ -820,10 +936,12 @@

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list