[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [38865] trunk/blender/source/blender: EditMesh-based skin node drawing

Nicholas Bishop nicholasbishop at gmail.com
Sun Jul 31 04:03:49 CEST 2011


Revision: 38865
          http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=38865
Author:   nicholasbishop
Date:     2011-07-31 02:03:48 +0000 (Sun, 31 Jul 2011)
Log Message:
-----------
EditMesh-based skin node drawing

Modified Paths:
--------------
    trunk/blender/source/blender/blenkernel/BKE_DerivedMesh.h
    trunk/blender/source/blender/blenkernel/intern/bsphere.c
    trunk/blender/source/blender/gpu/GPU_buffers.h
    trunk/blender/source/blender/gpu/intern/gpu_buffers.c
    trunk/blender/source/blender/modifiers/CMakeLists.txt
    trunk/blender/source/blender/modifiers/intern/MOD_skin.c

Modified: trunk/blender/source/blender/blenkernel/BKE_DerivedMesh.h
===================================================================
--- trunk/blender/source/blender/blenkernel/BKE_DerivedMesh.h	2011-07-31 02:03:39 UTC (rev 38864)
+++ trunk/blender/source/blender/blenkernel/BKE_DerivedMesh.h	2011-07-31 02:03:48 UTC (rev 38865)
@@ -83,7 +83,8 @@
 typedef enum DerivedMeshType {
 	DM_TYPE_CDDM,
 	DM_TYPE_EDITMESH,
-	DM_TYPE_CCGDM
+	DM_TYPE_CCGDM,
+	DM_TYPE_SKIN,
 } DerivedMeshType;
 
 typedef struct DerivedMesh DerivedMesh;

Modified: trunk/blender/source/blender/blenkernel/intern/bsphere.c
===================================================================
--- trunk/blender/source/blender/blenkernel/intern/bsphere.c	2011-07-31 02:03:39 UTC (rev 38864)
+++ trunk/blender/source/blender/blenkernel/intern/bsphere.c	2011-07-31 02:03:48 UTC (rev 38865)
@@ -1176,3 +1176,4 @@
 	return dm;
 }
 #endif
+

Modified: trunk/blender/source/blender/gpu/GPU_buffers.h
===================================================================
--- trunk/blender/source/blender/gpu/GPU_buffers.h	2011-07-31 02:03:39 UTC (rev 38864)
+++ trunk/blender/source/blender/gpu/GPU_buffers.h	2011-07-31 02:03:48 UTC (rev 38865)
@@ -163,6 +163,7 @@
 int GPU_buffer_legacy( struct DerivedMesh *dm );
 
 /* Buffers for non-DerivedMesh drawing */
+void GPU_draw_smooth_sphere(void);
 void *GPU_build_mesh_buffers(struct GHash *map, struct MVert *mvert,
 			struct MFace *mface, int *face_indices,
 			int totface, int *vert_indices, int uniq_verts,

Modified: trunk/blender/source/blender/gpu/intern/gpu_buffers.c
===================================================================
--- trunk/blender/source/blender/gpu/intern/gpu_buffers.c	2011-07-31 02:03:39 UTC (rev 38864)
+++ trunk/blender/source/blender/gpu/intern/gpu_buffers.c	2011-07-31 02:03:48 UTC (rev 38865)
@@ -1268,7 +1268,132 @@
 			((int*)elements->pointer) + start));
 }
 
+/* draw a smooth sphere; VBO-only for now */
+const int sphere_stacks = 32;
+const int sphere_slices = 64;
 
+static int sphere_totvert(void)
+{
+	return sphere_stacks * sphere_slices + 2;
+}
+
+static int sphere_tottri(void)
+{
+	return (2 * sphere_slices * (sphere_stacks - 1)) +
+		(sphere_slices * 2);
+}
+
+static void gen_sphere_points(float (*co)[3])
+{
+	const float x_angle_step = M_PI * 2 / sphere_slices;
+	const float y_angle_step = M_PI / (sphere_stacks+1);
+	float x_angle, y_angle, r;
+	int i, j;
+
+	for(i = 0, y_angle = M_PI / 2; i < sphere_stacks; i++) {
+		y_angle += y_angle_step;
+		r = cos(y_angle);
+
+		for(j = 0, x_angle = 0; j < sphere_slices; j++, co++) {
+			(*co)[0] = r*cos(x_angle);
+			(*co)[1] = r*sin(x_angle);
+			(*co)[2] = sin(y_angle);
+			x_angle += x_angle_step;
+		}
+	}
+
+	/* top and bottom points */
+	zero_v3(*co);
+	(*co)[2] = 1;
+	++co;
+	zero_v3(*co);
+	(*co)[2] = -1;
+}
+
+static void gen_sphere_tris(unsigned short (*tri)[3])
+{
+	int i, j, ring1, ring2, totvert;
+
+	totvert = sphere_totvert();
+	ring2 = totvert - 2 - sphere_slices;
+
+	/* caps */
+	for(i = 0; i < sphere_slices; i++) {
+		(*tri)[0] = totvert - 2;
+		(*tri)[1] = i;
+		(*tri)[2] = (i+1) % sphere_slices;
+		tri++;
+		(*tri)[0] = totvert - 1;
+		(*tri)[1] = ring2 + i;
+		(*tri)[2] = ring2 + (i+1) % sphere_slices;
+		tri++;
+	}
+
+	for(i = 0; i < sphere_stacks-1; i++) {
+		ring1 = i * sphere_slices;
+		ring2 = (i+1) * sphere_slices;
+		for(j = 0; j < sphere_slices; j++) {
+			(*tri)[0] = ring1 + j;
+			(*tri)[1] = ring1 + ((j+1) % sphere_slices);
+			(*tri)[2] = ring2 + j;
+			tri++;
+			(*tri)[0] = ring2 + ((j+1) % sphere_slices);
+			(*tri)[1] = ring2 + j;
+			(*tri)[2] = i*sphere_slices + (j+1) % sphere_slices;
+			tri++;
+		}
+	}
+}
+
+void GPU_draw_smooth_sphere(void)
+{
+	static GLuint buffers[2];
+	static int inited = 0;
+	static int totndx;
+
+	if(!inited) {
+		float (*co)[3];
+		unsigned short (*tri)[3];
+
+		glGenBuffersARB(2, buffers);
+
+		/* build vertex buffer */
+		glBindBufferARB(GL_ARRAY_BUFFER_ARB, buffers[0]);
+		glBufferDataARB(GL_ARRAY_BUFFER_ARB,
+				sizeof(float) * 3 * sphere_totvert(),
+				NULL, GL_STATIC_DRAW_ARB);
+		co = glMapBufferARB(GL_ARRAY_BUFFER_ARB, GL_WRITE_ONLY_ARB);
+		gen_sphere_points(co);
+		glUnmapBufferARB(GL_ARRAY_BUFFER_ARB);
+
+		/* build index buffer */
+		totndx = 3 * sphere_tottri();
+		glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, buffers[1]);
+		glBufferDataARB(GL_ELEMENT_ARRAY_BUFFER_ARB,
+				sizeof(unsigned short) * totndx,
+				NULL, GL_STATIC_DRAW_ARB);
+		tri = glMapBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, GL_WRITE_ONLY_ARB);
+		gen_sphere_tris(tri);
+		glUnmapBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB);
+
+		inited = 1;
+	}
+
+	glEnableClientState(GL_VERTEX_ARRAY);
+	glEnableClientState(GL_NORMAL_ARRAY);
+
+	glVertexPointer(3, GL_FLOAT, 0, 0);
+	glNormalPointer(GL_FLOAT, 0, 0);
+
+	glBindBufferARB(GL_ARRAY_BUFFER_ARB, buffers[0]);
+	glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, buffers[1]);
+	glDrawElements(GL_TRIANGLES, totndx, GL_UNSIGNED_SHORT, 0);
+
+	glDisableClientState(GL_VERTEX_ARRAY);
+	glDisableClientState(GL_NORMAL_ARRAY);
+}
+/* end sphere drawing */
+
 /* XXX: the rest of the code in this file is used for optimized PBVH
    drawing and doesn't interact at all with the buffer code above */
 

Modified: trunk/blender/source/blender/modifiers/CMakeLists.txt
===================================================================
--- trunk/blender/source/blender/modifiers/CMakeLists.txt	2011-07-31 02:03:39 UTC (rev 38864)
+++ trunk/blender/source/blender/modifiers/CMakeLists.txt	2011-07-31 02:03:48 UTC (rev 38865)
@@ -32,6 +32,10 @@
 	../blenlib
 	../blenloader
 	../makesdna
+	../editors/include # needed in SkinDM for GL stuff
+	../gpu # needed in SkinDM for GL stuff
+	../blenkernel
+	../blenkernel/intern
 	../render/extern/include
 	../../../intern/elbeem/extern
 	../../../intern/guardedalloc

Modified: trunk/blender/source/blender/modifiers/intern/MOD_skin.c
===================================================================
--- trunk/blender/source/blender/modifiers/intern/MOD_skin.c	2011-07-31 02:03:39 UTC (rev 38864)
+++ trunk/blender/source/blender/modifiers/intern/MOD_skin.c	2011-07-31 02:03:48 UTC (rev 38865)
@@ -28,14 +28,27 @@
 
 #include <stddef.h>
 
+#include "MEM_guardedalloc.h"
+
+#include "BLI_editVert.h"
+#include "BLI_math.h"
+
 #include "BKE_cdderivedmesh.h"
+#include "BKE_DerivedMesh.h"
 #include "BKE_modifier.h"
 
 #include "DNA_mesh_types.h"
+#include "DNA_meshdata_types.h"
 #include "DNA_object_types.h"
 
 #include "MOD_util.h"
 
+/* probably bad level call? */
+#include "BIF_gl.h"
+#include "UI_resources.h"
+
+#include "GPU_buffers.h"
+
 static void initData(ModifierData *md)
 {
 	SkinModifierData *smd = (SkinModifierData*)md;
@@ -55,9 +68,151 @@
 	tsmd->flag = smd->flag;
 }
 
+typedef struct {
+	DerivedMesh dm;
+	EditMesh *em;
+} SkinDM;
+
+static void skindm_draw(SkinDM *dm)
+{
+	float col_vert[3], col_vertsel[3];
+	float col_elemact[3];
+	EditMesh *em;
+	EditVert *eve, *eve_act;
+	EditEdge *eed, *eed_act;
+	SkinNode *n1, *n2;
+
+	em = dm->em;
+
+	/* get colors */
+	UI_GetThemeColor3fv(TH_VERTEX, col_vert);
+	UI_GetThemeColor3fv(TH_VERTEX_SELECT, col_vertsel);
+	UI_GetThemeColor3fv(TH_EDITMESH_ACTIVE, col_elemact);
+
+	/* check for active vertex */
+	if(em->selected.last) {
+		EditSelection *ese = em->selected.last;
+		if(ese->type == EDITEDGE)
+			eed_act = ese->data;
+		else if(ese->type == EDITVERT)
+			eve_act = ese->data;
+	}
+
+	/* set up GL state */
+	glShadeModel(GL_SMOOTH);
+	glColorMaterial(GL_FRONT_AND_BACK, GL_DIFFUSE);
+	glEnable(GL_COLOR_MATERIAL);
+
+	/* draw nodes */
+	for(eve = em->verts.first; eve; eve = eve->next) {
+		n1 = CustomData_em_get(&em->vdata, eve->data, CD_SKIN_NODE);
+
+		glPushMatrix();
+		glTranslatef(eve->co[0], eve->co[1], eve->co[2]);
+		glScalef(n1->radius, n1->radius, n1->radius);
+		glColor3fv(eve == eve_act ? col_elemact :
+			   eve->f & SELECT ? col_vertsel : col_vert);
+		GPU_draw_smooth_sphere();
+		glPopMatrix();
+	}
+
+	/* draw edges */
+	for(eed = em->edges.first; eed; eed = eed->next) {
+		float f, t, col[3], *col1, *col2, co[3], radius;
+		int i, totstep;
+
+		n1 = CustomData_em_get(&em->vdata, eed->v1->data, CD_SKIN_NODE);
+		n2 = CustomData_em_get(&em->vdata, eed->v2->data, CD_SKIN_NODE);
+
+		/* XXX: assuming vert sel mode here? */
+		col1 = eed->v1->f & SELECT ? col_vertsel : col_vert;
+		col2 = eed->v2->f & SELECT ? col_vertsel : col_vert;
+
+		/* factor to adjust steps by... just guessing at a nice value here */
+		f = (n1->radius + n2->radius) / 6;
+
+		totstep = len_v3v3(eed->v1->co, eed->v2->co) / f;
+		if(totstep <= 2) totstep = 3;
+
+		for(i = 1; i < totstep-1; i++) {
+			t = i / (totstep-1.0f);
+
+			interp_v3_v3v3(col, col1, col2, t);
+			interp_v3_v3v3(co, eed->v1->co, eed->v2->co, t);
+			radius = interpf(n1->radius, n2->radius, t);
+
+			glPushMatrix();
+
+			glColor3fv(col);
+			glTranslatef(co[0], co[1], co[2]);
+			glScalef(radius, radius, radius);
+			GPU_draw_smooth_sphere();
+
+			glPopMatrix();
+		}
+	}
+
+	glShadeModel(GL_FLAT);
+	glDisable(GL_COLOR_MATERIAL);
+}
+
+static void skindm_getMinMax(DerivedMesh *dm, float min_r[3], float max_r[3])
+{
+	/* TODO */
+	zero_v3(min_r);
+	zero_v3(max_r);
+}
+
+static void skindm_drawEdges(DerivedMesh *dm, int drawLooseEdges, int drawAllEdges)
+{
+	skindm_draw((SkinDM*)dm);
+}
+
+static void skindm_drawMappedFaces(DerivedMesh *dm,
+				   int (*setDrawOptions)(void*, int, int*),
+				   void *userData, int useColors,
+				   int (*setMaterial)(int, void*))
+{
+	skindm_draw((SkinDM*)dm);
+}
+
+static void skindm_release(DerivedMesh *dm)
+{
+	if(DM_release(dm))
+		MEM_freeN(dm);
+}
+
+static DerivedMesh *applyModifierEM(ModifierData *md, Object *ob,
+				    EditMesh *em,
+				    DerivedMesh *dm)
+{
+	SkinDM *skin;
+
+	skin = MEM_callocN(sizeof(SkinDM), "SkinDM");
+
+	/* standard DerivedMesh stuff */
+	skin->dm.drawEdges = skindm_drawEdges;
+	skin->dm.drawMappedFaces = skindm_drawMappedFaces;
+	skin->dm.getMinMax = skindm_getMinMax;
+	skin->dm.release = skindm_release;
+
+	skin->em = em;
+
+	return (DerivedMesh*)skin;
+}
+
+
 static DerivedMesh *applyModifier(ModifierData *md, Object *ob, DerivedMesh *dm,
-						   int useRenderParams, int isFinalCalc)
+				  int useRenderParams, int isFinalCalc)
 {
+	Mesh *me;
+
+	/* XXX: temporary hack to make sure there's some customdata
+	   for us to use, later can do a proper interface for this */
+	me = ob->data;
+	if(!CustomData_get_layer(&me->vdata, CD_SKIN_NODE))
+		CustomData_add_layer(&me->vdata, CD_SKIN_NODE, CD_DEFAULT, NULL, me->totvert);
+
 	return dm;
 }
 
@@ -67,7 +222,7 @@

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list