[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