forked from bartvdbraak/blender
- support for fake verse edges (subsurf modifier should work now)
- edges are generated from verse faces - no support for lose edge! - informations about edges aren't sent to verse server (other applications can't share edges with blender) - better sending/receiving vertex position
This commit is contained in:
parent
d584c8a1e6
commit
76c11ec9f7
@ -37,6 +37,13 @@
|
||||
#include "verse_ms.h"
|
||||
|
||||
struct VNode;
|
||||
struct VerseEdge;
|
||||
|
||||
/*
|
||||
* Verse Edge Hash (similar to edit edge hash)
|
||||
*/
|
||||
#define VEDHASHSIZE (512*512)
|
||||
#define VEDHASH(a, b) ((a<b ? a : b) % VEDHASHSIZE)
|
||||
|
||||
/*
|
||||
* virtual data type (used only for retype)
|
||||
@ -118,7 +125,7 @@ typedef struct VerseVert {
|
||||
real32 co[3]; /* x,y,z-coordinates of vertex */
|
||||
real32 no[3]; /* normal of vertex */
|
||||
/* blender internals */
|
||||
short flag; /* flags: VERT_DELETED, VERT_RECEIVED */
|
||||
short flag; /* flags: VERT_DELETED, VERT_RECEIVED, etc. */
|
||||
void *vertex; /* pointer at EditVert or MVert */
|
||||
int counter; /* counter of VerseFaces using this VerseVert */
|
||||
union {
|
||||
@ -127,8 +134,30 @@ typedef struct VerseVert {
|
||||
} tmp; /* pointer at new created verse vert, it is
|
||||
* used during duplicating geometry node */
|
||||
float *cos; /* modified coordinates of vertex */
|
||||
float *nos; /* modified normal vector */
|
||||
} VerseVert;
|
||||
|
||||
/*
|
||||
* structture used for verse edge hash
|
||||
*/
|
||||
typedef struct HashVerseEdge {
|
||||
struct VerseEdge *vedge;
|
||||
struct HashVerseEdge *next;
|
||||
} HashVerseEdge;
|
||||
|
||||
/*
|
||||
* fake verse data: edge
|
||||
*/
|
||||
typedef struct VerseEdge {
|
||||
struct VerseEdge *next, *prev;
|
||||
uint32 v0, v1; /* indexes of verse vertexes */
|
||||
int counter; /* counter of verse faces using this edge */
|
||||
struct HashVerseEdge hash; /* hash table */
|
||||
union {
|
||||
unsigned int index; /* temporary index of edge */
|
||||
} tmp;
|
||||
} VerseEdge;
|
||||
|
||||
/*
|
||||
* verse data: polygon
|
||||
*/
|
||||
@ -147,6 +176,7 @@ typedef struct VerseFace {
|
||||
short counter; /* counter of missed VerseVertexes */
|
||||
void *face; /* pointer at EditFace */
|
||||
float no[3]; /* normal vector */
|
||||
float *nos; /* modified normal vector */
|
||||
} VerseFace;
|
||||
|
||||
/*
|
||||
@ -237,6 +267,8 @@ typedef struct VGeomData {
|
||||
struct ListBase queue; /* queue of our layers waiting for receiving from verse server */
|
||||
void *mesh; /* pointer at Mesh (object node) */
|
||||
void *editmesh; /* pointer at EditMesh (edit mode) */
|
||||
struct HashVerseEdge *hash; /* verse edge hash */
|
||||
struct ListBase edges; /* list of fake verse edges */
|
||||
/* client dependent methods */
|
||||
void (*post_vertex_create)(struct VerseVert *vvert);
|
||||
void (*post_vertex_set_xyz)(struct VerseVert *vvert);
|
||||
|
@ -1019,7 +1019,8 @@ typedef struct {
|
||||
struct VNode *vnode;
|
||||
struct VLayer *vertex_layer;
|
||||
struct VLayer *polygon_layer;
|
||||
float (*verts)[3];
|
||||
struct ListBase *edges;
|
||||
float (*vertexCos)[3];
|
||||
} VDerivedMesh;
|
||||
|
||||
/* this function set up border points of verse mesh bounding box */
|
||||
@ -1034,7 +1035,7 @@ static void vDM_getMinMax(DerivedMesh *dm, float min_r[3], float max_r[3])
|
||||
|
||||
if(vdm->vertex_layer->dl.da.count > 0) {
|
||||
while(vvert) {
|
||||
DO_MINMAX(vdm->verts ? vvert->cos : vvert->co, min_r, max_r);
|
||||
DO_MINMAX(vdm->vertexCos ? vvert->cos : vvert->co, min_r, max_r);
|
||||
vvert = vvert->next;
|
||||
}
|
||||
}
|
||||
@ -1055,7 +1056,9 @@ static int vDM_getNumVerts(DerivedMesh *dm)
|
||||
/* this function return number of 'fake' edges */
|
||||
static int vDM_getNumEdges(DerivedMesh *dm)
|
||||
{
|
||||
return 0;
|
||||
VDerivedMesh *vdm = (VDerivedMesh*)dm;
|
||||
|
||||
return BLI_countlist(vdm->edges);
|
||||
}
|
||||
|
||||
/* this function returns number of polygons in polygon layer */
|
||||
@ -1071,10 +1074,13 @@ static int vDM_getNumFaces(DerivedMesh *dm)
|
||||
* but it return 'indexth' vertex of dynamic list */
|
||||
void vDM_getVert(DerivedMesh *dm, int index, MVert *vert_r)
|
||||
{
|
||||
VerseVert *vvert = ((VDerivedMesh*)dm)->vertex_layer->dl.lb.first;
|
||||
VDerivedMesh *vdm = (VDerivedMesh*)dm;
|
||||
struct VerseVert *vvert;
|
||||
int i;
|
||||
|
||||
for(i=0 ; i<index; i++) vvert = vvert->next;
|
||||
if(!vdm->vertex_layer) return;
|
||||
|
||||
for(vvert = vdm->vertex_layer->dl.lb.first, i=0 ; i<index; i++) vvert = vvert->next;
|
||||
|
||||
if(vvert) {
|
||||
VECCOPY(vert_r->co, vvert->co);
|
||||
@ -1089,25 +1095,59 @@ void vDM_getVert(DerivedMesh *dm, int index, MVert *vert_r)
|
||||
}
|
||||
}
|
||||
|
||||
/* dummy function, because verse mesh doesn't store edges */
|
||||
/* this function returns fake verse edge */
|
||||
void vDM_getEdge(DerivedMesh *dm, int index, MEdge *edge_r)
|
||||
{
|
||||
edge_r->flag = 0;
|
||||
edge_r->crease = 0;
|
||||
edge_r->v1 = 0;
|
||||
edge_r->v2 = 0;
|
||||
VDerivedMesh *vdm = (VDerivedMesh*)dm;
|
||||
struct VerseEdge *vedge;
|
||||
struct VLayer *vert_vlayer = vdm->vertex_layer;
|
||||
struct VerseVert *vvert;
|
||||
int j;
|
||||
|
||||
if(!vdm->vertex_layer || !vdm->edges) return;
|
||||
|
||||
if(vdm->edges->first) {
|
||||
struct VerseVert *vvert1, *vvert2;
|
||||
|
||||
/* store vert indices in tmp union */
|
||||
for(vvert = vdm->vertex_layer->dl.lb.first, j = 0; vvert; vvert = vvert->next, j++)
|
||||
vvert->tmp.index = j;
|
||||
|
||||
for(vedge = vdm->edges->first; vedge; vedge = vedge->next) {
|
||||
if(vedge->tmp.index==index) {
|
||||
vvert1 = BLI_dlist_find_link(&(vert_vlayer->dl), (unsigned int)vedge->v0);
|
||||
vvert2 = BLI_dlist_find_link(&(vert_vlayer->dl), (unsigned int)vedge->v1);
|
||||
|
||||
if(vvert1 && vvert2) {
|
||||
edge_r->v1 = vvert1->tmp.index;
|
||||
edge_r->v2 = vvert2->tmp.index;
|
||||
}
|
||||
else {
|
||||
edge_r->v1 = 0;
|
||||
edge_r->v2 = 0;
|
||||
}
|
||||
/* not supported yet */
|
||||
edge_r->flag = 0;
|
||||
edge_r->crease = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* this function doesn't return face with index of access array,
|
||||
* but it returns 'indexth' vertex of dynamic list */
|
||||
void vDM_getFace(DerivedMesh *dm, int index, MFace *face_r)
|
||||
{
|
||||
struct VerseFace *vface = ((VDerivedMesh*)dm)->polygon_layer->dl.lb.first;
|
||||
struct VerseVert *vvert = ((VDerivedMesh*)dm)->vertex_layer->dl.lb.first;
|
||||
VDerivedMesh *vdm = (VDerivedMesh*)dm;
|
||||
struct VerseFace *vface;
|
||||
struct VerseVert *vvert;
|
||||
struct VerseVert *vvert0, *vvert1, *vvert2, *vvert3;
|
||||
int i;
|
||||
|
||||
for(i = 0; i < index; ++i) vface = vface->next;
|
||||
if(!vdm->vertex_layer || !vdm->polygon_layer) return;
|
||||
|
||||
for(vface = vdm->polygon_layer->dl.lb.first, i = 0; i < index; ++i) vface = vface->next;
|
||||
|
||||
face_r->mat_nr = 0;
|
||||
face_r->flag = 0;
|
||||
@ -1119,7 +1159,7 @@ void vDM_getFace(DerivedMesh *dm, int index, MFace *face_r)
|
||||
vvert3 = vface->vvert3;
|
||||
if(!vvert3) face_r->v4 = 0;
|
||||
|
||||
for(i = 0; vvert0 || vvert1 || vvert2 || vvert3; i++, vvert = vvert->next) {
|
||||
for(vvert = vdm->vertex_layer->dl.lb.first, i = 0; vvert0 || vvert1 || vvert2 || vvert3; i++, vvert = vvert->next) {
|
||||
if(vvert == vvert0) {
|
||||
face_r->v1 = i;
|
||||
vvert0 = NULL;
|
||||
@ -1144,9 +1184,12 @@ void vDM_getFace(DerivedMesh *dm, int index, MFace *face_r)
|
||||
/* fill array of mvert */
|
||||
void vDM_copyVertArray(DerivedMesh *dm, MVert *vert_r)
|
||||
{
|
||||
VerseVert *vvert = ((VDerivedMesh *)dm)->vertex_layer->dl.lb.first;
|
||||
VDerivedMesh *vdm = (VDerivedMesh*)dm;
|
||||
struct VerseVert *vvert;
|
||||
|
||||
for( ; vvert; vvert = vvert->next, ++vert_r) {
|
||||
if(!vdm->vertex_layer) return;
|
||||
|
||||
for(vvert = vdm->vertex_layer->dl.lb.first ; vvert; vvert = vvert->next, ++vert_r) {
|
||||
VECCOPY(vert_r->co, vvert->co);
|
||||
|
||||
vert_r->no[0] = vvert->no[0] * 32767.0;
|
||||
@ -1161,20 +1204,56 @@ void vDM_copyVertArray(DerivedMesh *dm, MVert *vert_r)
|
||||
/* dummy function, edges arent supported in verse mesh */
|
||||
void vDM_copyEdgeArray(DerivedMesh *dm, MEdge *edge_r)
|
||||
{
|
||||
VDerivedMesh *vdm = (VDerivedMesh*)dm;
|
||||
|
||||
if(!vdm->vertex_layer || !vdm->edges) return;
|
||||
|
||||
if(vdm->edges->first) {
|
||||
struct VerseEdge *vedge;
|
||||
struct VLayer *vert_vlayer = vdm->vertex_layer;
|
||||
struct VerseVert *vvert, *vvert1, *vvert2;
|
||||
int j;
|
||||
|
||||
/* store vert indices in tmp union */
|
||||
for(vvert = vdm->vertex_layer->dl.lb.first, j = 0; vvert; vvert = vvert->next, ++j)
|
||||
vvert->tmp.index = j;
|
||||
|
||||
for(vedge = vdm->edges->first, j=0 ; vedge; vedge = vedge->next, ++edge_r, j++) {
|
||||
/* create temporary edge index */
|
||||
vedge->tmp.index = j;
|
||||
vvert1 = BLI_dlist_find_link(&(vert_vlayer->dl), (unsigned int)vedge->v0);
|
||||
vvert2 = BLI_dlist_find_link(&(vert_vlayer->dl), (unsigned int)vedge->v1);
|
||||
if(vvert1 && vvert2) {
|
||||
edge_r->v1 = vvert1->tmp.index;
|
||||
edge_r->v2 = vvert2->tmp.index;
|
||||
}
|
||||
else {
|
||||
printf("error: vDM_copyEdgeArray: %d, %d\n", vedge->v0, vedge->v1);
|
||||
edge_r->v1 = 0;
|
||||
edge_r->v2 = 0;
|
||||
}
|
||||
/* not supported yet */
|
||||
edge_r->flag = 0;
|
||||
edge_r->crease = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* fill array of mfaces */
|
||||
void vDM_copyFaceArray(DerivedMesh *dm, MFace *face_r)
|
||||
{
|
||||
VerseFace *vface = ((VDerivedMesh*)dm)->polygon_layer->dl.lb.first;
|
||||
VerseVert *vvert = ((VDerivedMesh*)dm)->vertex_layer->dl.lb.first;
|
||||
VDerivedMesh *vdm = (VDerivedMesh*)dm;
|
||||
struct VerseFace *vface;
|
||||
struct VerseVert *vvert;
|
||||
int i;
|
||||
|
||||
|
||||
if(!vdm->vertex_layer || !vdm->polygon_layer) return;
|
||||
|
||||
/* store vertexes indices in tmp union */
|
||||
for(i = 0; vvert; vvert = vvert->next, ++i)
|
||||
for(vvert = vdm->vertex_layer->dl.lb.first, i = 0; vvert; vvert = vvert->next, ++i)
|
||||
vvert->tmp.index = i;
|
||||
|
||||
for( ; vface; vface = vface->next, ++face_r) {
|
||||
for(vface = vdm->polygon_layer->dl.lb.first; vface; vface = vface->next, ++face_r) {
|
||||
face_r->mat_nr = 0;
|
||||
face_r->flag = 0;
|
||||
|
||||
@ -1188,8 +1267,7 @@ void vDM_copyFaceArray(DerivedMesh *dm, MFace *face_r)
|
||||
}
|
||||
}
|
||||
|
||||
/* return coordination of vertex with index ... I suppose, that it will
|
||||
* be very hard to do, becuase there can be holes in access array */
|
||||
/* return coordination of vertex with index */
|
||||
static void vDM_getVertCo(DerivedMesh *dm, int index, float co_r[3])
|
||||
{
|
||||
VDerivedMesh *vdm = (VDerivedMesh*)dm;
|
||||
@ -1198,8 +1276,9 @@ static void vDM_getVertCo(DerivedMesh *dm, int index, float co_r[3])
|
||||
if(!vdm->vertex_layer) return;
|
||||
|
||||
vvert = BLI_dlist_find_link(&(vdm->vertex_layer->dl), index);
|
||||
|
||||
if(vvert) {
|
||||
VECCOPY(co_r, vdm->verts ? vvert->cos : vvert->co);
|
||||
VECCOPY(co_r, vdm->vertexCos ? vvert->cos : vvert->co);
|
||||
}
|
||||
else {
|
||||
co_r[0] = co_r[1] = co_r[2] = 0.0;
|
||||
@ -1217,14 +1296,13 @@ static void vDM_getVertCos(DerivedMesh *dm, float (*cos_r)[3])
|
||||
|
||||
vvert = vdm->vertex_layer->dl.lb.first;
|
||||
while(vvert) {
|
||||
VECCOPY(cos_r[i], vdm->verts ? vvert->cos : vvert->co);
|
||||
VECCOPY(cos_r[i], vdm->vertexCos ? vvert->cos : vvert->co);
|
||||
i++;
|
||||
vvert = vvert->next;
|
||||
}
|
||||
}
|
||||
|
||||
/* return normal of vertex with index ... again, it will be hard to
|
||||
* implemente, because access array */
|
||||
/* return normal of vertex with index */
|
||||
static void vDM_getVertNo(DerivedMesh *dm, int index, float no_r[3])
|
||||
{
|
||||
VDerivedMesh *vdm = (VDerivedMesh*)dm;
|
||||
@ -1253,7 +1331,7 @@ static void vDM_drawVerts(DerivedMesh *dm)
|
||||
|
||||
bglBegin(GL_POINTS);
|
||||
while(vvert) {
|
||||
bglVertex3fv(vdm->verts ? vvert->cos : vvert->co);
|
||||
bglVertex3fv(vdm->vertexCos ? vvert->cos : vvert->co);
|
||||
vvert = vvert->next;
|
||||
}
|
||||
bglEnd();
|
||||
@ -1265,21 +1343,22 @@ static void vDM_drawVerts(DerivedMesh *dm)
|
||||
static void vDM_drawEdges(DerivedMesh *dm, int drawLooseEdges)
|
||||
{
|
||||
VDerivedMesh *vdm = (VDerivedMesh*)dm;
|
||||
struct VerseFace *vface;
|
||||
struct VerseEdge *vedge;
|
||||
struct VLayer *vert_vlayer = vdm->vertex_layer;
|
||||
|
||||
if(!vdm->polygon_layer) return;
|
||||
if(vert_vlayer && vdm->edges && (BLI_countlist(vdm->edges) > 0)) {
|
||||
struct VerseVert *vvert1, *vvert2;
|
||||
|
||||
vface = vdm->polygon_layer->dl.lb.first;
|
||||
|
||||
while(vface) {
|
||||
glBegin(GL_LINE_LOOP);
|
||||
glVertex3fv(vdm->verts ? vface->vvert0->cos : vface->vvert0->co);
|
||||
glVertex3fv(vdm->verts ? vface->vvert1->cos : vface->vvert1->co);
|
||||
glVertex3fv(vdm->verts ? vface->vvert2->cos : vface->vvert2->co);
|
||||
if(vface->vvert3) glVertex3fv(vdm->verts ? vface->vvert3->cos : vface->vvert3->co);
|
||||
glBegin(GL_LINES);
|
||||
for(vedge = vdm->edges->first; vedge; vedge = vedge->next) {
|
||||
vvert1 = BLI_dlist_find_link(&(vert_vlayer->dl), (unsigned int)vedge->v0);
|
||||
vvert2 = BLI_dlist_find_link(&(vert_vlayer->dl), (unsigned int)vedge->v1);
|
||||
if(vvert1 && vvert2) {
|
||||
glVertex3fv(vdm->vertexCos ? vvert1->cos : vvert1->co);
|
||||
glVertex3fv(vdm->vertexCos ? vvert2->cos : vvert2->co);
|
||||
}
|
||||
}
|
||||
glEnd();
|
||||
|
||||
vface = vface->next;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1303,40 +1382,21 @@ static void vDM_drawFacesSolid(DerivedMesh *dm, int (*setMaterial)(int))
|
||||
|
||||
vface = vdm->polygon_layer->dl.lb.first;
|
||||
|
||||
glShadeModel(GL_FLAT);
|
||||
while(vface) {
|
||||
/* if((vface->smooth) && (vface->smooth->value)){
|
||||
glShadeModel(GL_SMOOTH);
|
||||
glBegin(vface->vvert3?GL_QUADS:GL_TRIANGLES);
|
||||
glNormal3fv(vface->vvert0->no);
|
||||
glVertex3fv(vdm->verts ? vface->vvert0->cos : vface->vvert0->co);
|
||||
glNormal3fv(vface->vvert1->no);
|
||||
glVertex3fv(vdm->verts ? vface->vvert1->cos : vface->vvert1->co);
|
||||
glNormal3fv(vface->vvert2->no);
|
||||
glVertex3fv(vdm->verts ? vface->vvert2->cos : vface->vvert2->co);
|
||||
if(vface->vvert3){
|
||||
glNormal3fv(vface->vvert3->no);
|
||||
glVertex3fv(vdm->verts ? vface->vvert3->cos : vface->vvert3->co);
|
||||
}
|
||||
glEnd();
|
||||
}
|
||||
else { */
|
||||
glShadeModel(GL_FLAT);
|
||||
glBegin(vface->vvert3?GL_QUADS:GL_TRIANGLES);
|
||||
glNormal3fv(vface->no);
|
||||
glVertex3fv(vdm->verts ? vface->vvert0->cos : vface->vvert0->co);
|
||||
glVertex3fv(vdm->verts ? vface->vvert1->cos : vface->vvert1->co);
|
||||
glVertex3fv(vdm->verts ? vface->vvert2->cos : vface->vvert2->co);
|
||||
if(vface->vvert3)
|
||||
glVertex3fv(vdm->verts ? vface->vvert3->cos : vface->vvert3->co);
|
||||
glEnd();
|
||||
/* } */
|
||||
|
||||
glBegin(vface->vvert3?GL_QUADS:GL_TRIANGLES);
|
||||
glNormal3fv(vface->no);
|
||||
glVertex3fv(vdm->vertexCos ? vface->vvert0->cos : vface->vvert0->co);
|
||||
glVertex3fv(vdm->vertexCos ? vface->vvert1->cos : vface->vvert1->co);
|
||||
glVertex3fv(vdm->vertexCos ? vface->vvert2->cos : vface->vvert2->co);
|
||||
if(vface->vvert3)
|
||||
glVertex3fv(vdm->vertexCos ? vface->vvert3->cos : vface->vvert3->co);
|
||||
glEnd();
|
||||
vface = vface->next;
|
||||
}
|
||||
glShadeModel(GL_FLAT);
|
||||
}
|
||||
|
||||
/* thsi function should draw mesh with mapped texture, but it isn't supported yet */
|
||||
/* this function should draw mesh with mapped texture, but it isn't supported yet */
|
||||
static void vDM_drawFacesTex(DerivedMesh *dm, int (*setDrawOptions)(MTFace *tface, MCol *mcol, int matnr))
|
||||
{
|
||||
VDerivedMesh *vdm = (VDerivedMesh*)dm;
|
||||
@ -1348,11 +1408,11 @@ static void vDM_drawFacesTex(DerivedMesh *dm, int (*setDrawOptions)(MTFace *tfac
|
||||
|
||||
while(vface) {
|
||||
glBegin(vface->vvert3?GL_QUADS:GL_TRIANGLES);
|
||||
glVertex3fv(vdm->verts ? vface->vvert0->cos : vface->vvert0->co);
|
||||
glVertex3fv(vdm->verts ? vface->vvert1->cos : vface->vvert1->co);
|
||||
glVertex3fv(vdm->verts ? vface->vvert2->cos : vface->vvert2->co);
|
||||
glVertex3fv(vdm->vertexCos ? vface->vvert0->cos : vface->vvert0->co);
|
||||
glVertex3fv(vdm->vertexCos ? vface->vvert1->cos : vface->vvert1->co);
|
||||
glVertex3fv(vdm->vertexCos ? vface->vvert2->cos : vface->vvert2->co);
|
||||
if(vface->vvert3)
|
||||
glVertex3fv(vdm->verts ? vface->vvert3->cos : vface->vvert3->co);
|
||||
glVertex3fv(vdm->vertexCos ? vface->vvert3->cos : vface->vvert3->co);
|
||||
glEnd();
|
||||
|
||||
vface = vface->next;
|
||||
@ -1372,11 +1432,11 @@ static void vDM_drawFacesColored(DerivedMesh *dm, int useTwoSided, unsigned char
|
||||
|
||||
while(vface) {
|
||||
glBegin(vface->vvert3?GL_QUADS:GL_TRIANGLES);
|
||||
glVertex3fv(vdm->verts ? vface->vvert0->cos : vface->vvert0->co);
|
||||
glVertex3fv(vdm->verts ? vface->vvert1->cos : vface->vvert1->co);
|
||||
glVertex3fv(vdm->verts ? vface->vvert2->cos : vface->vvert2->co);
|
||||
glVertex3fv(vdm->vertexCos ? vface->vvert0->cos : vface->vvert0->co);
|
||||
glVertex3fv(vdm->vertexCos ? vface->vvert1->cos : vface->vvert1->co);
|
||||
glVertex3fv(vdm->vertexCos ? vface->vvert2->cos : vface->vvert2->co);
|
||||
if(vface->vvert3)
|
||||
glVertex3fv(vdm->verts ? vface->vvert3->cos : vface->vvert3->co);
|
||||
glVertex3fv(vdm->vertexCos ? vface->vvert3->cos : vface->vvert3->co);
|
||||
glEnd();
|
||||
|
||||
vface = vface->next;
|
||||
@ -1447,7 +1507,7 @@ static void vDM_release(DerivedMesh *dm)
|
||||
VDerivedMesh *vdm = (VDerivedMesh*)dm;
|
||||
|
||||
if (DM_release(dm)) {
|
||||
if(vdm->verts) MEM_freeN(vdm->verts);
|
||||
if(vdm->vertexCos) MEM_freeN(vdm->vertexCos);
|
||||
MEM_freeN(vdm);
|
||||
}
|
||||
}
|
||||
@ -1462,9 +1522,11 @@ DerivedMesh *derivedmesh_from_versemesh(VNode *vnode, float (*vertexCos)[3])
|
||||
vdm->vnode = vnode;
|
||||
vdm->vertex_layer = find_verse_layer_type((VGeomData*)vnode->data, VERTEX_LAYER);
|
||||
vdm->polygon_layer = find_verse_layer_type((VGeomData*)vnode->data, POLYGON_LAYER);
|
||||
vdm->edges = &((VGeomData*)vnode->data)->edges;
|
||||
|
||||
/* vertex and polygon layer has to exist */
|
||||
if(vdm->vertex_layer && vdm->polygon_layer)
|
||||
DM_init(&vdm->dm, vdm->vertex_layer->dl.da.count, 0, vdm->polygon_layer->dl.da.count);
|
||||
DM_init(&vdm->dm, vdm->vertex_layer->dl.da.count, BLI_countlist(vdm->edges), vdm->polygon_layer->dl.da.count);
|
||||
else
|
||||
DM_init(&vdm->dm, 0, 0, 0);
|
||||
|
||||
@ -1506,28 +1568,7 @@ DerivedMesh *derivedmesh_from_versemesh(VNode *vnode, float (*vertexCos)[3])
|
||||
|
||||
vdm->dm.release = vDM_release;
|
||||
|
||||
if(vdm->vertex_layer) {
|
||||
if(vertexCos) {
|
||||
int i;
|
||||
|
||||
vdm->verts = MEM_mallocN(sizeof(float)*3*vdm->vertex_layer->dl.da.count, "verse mod vertexes");
|
||||
vvert = vdm->vertex_layer->dl.lb.first;
|
||||
|
||||
for(i=0; i<vdm->vertex_layer->dl.da.count && vvert; i++, vvert = vvert->next) {
|
||||
VECCOPY(vdm->verts[i], vertexCos[i]);
|
||||
vvert->cos = vdm->verts[i];
|
||||
}
|
||||
}
|
||||
else {
|
||||
vdm->verts = NULL;
|
||||
vvert = vdm->vertex_layer->dl.lb.first;
|
||||
|
||||
while(vvert) {
|
||||
vvert->cos = NULL;
|
||||
vvert = vvert->next;
|
||||
}
|
||||
}
|
||||
}
|
||||
vdm->vertexCos = vertexCos;
|
||||
|
||||
return (DerivedMesh*) vdm;
|
||||
}
|
||||
|
@ -400,10 +400,12 @@ static void cdDM_drawFacesTex_common(DerivedMesh *dm,
|
||||
if(index) {
|
||||
orig = *index++;
|
||||
if(orig == ORIGINDEX_NONE) continue;
|
||||
flag = drawParamsMapped(userData, orig);
|
||||
if(drawParamsMapped) flag = drawParamsMapped(userData, orig);
|
||||
else continue;
|
||||
}
|
||||
else
|
||||
flag = drawParamsMapped(userData, i);
|
||||
if(drawParamsMapped) flag = drawParamsMapped(userData, i);
|
||||
else continue;
|
||||
}
|
||||
|
||||
if(flag == 0)
|
||||
|
@ -78,6 +78,16 @@ static void move_face_orphan_to_dlist(struct VNode *vnode, struct VLayer *vlayer
|
||||
static void increase_verse_verts_references(struct VerseFace *vface);
|
||||
static void recalculate_verseface_normals(struct VNode *vnode);
|
||||
|
||||
/* verse edge functions */
|
||||
static VerseEdge* find_verse_edge(struct VNode *vnode, uint32 v0, uint32 v1);
|
||||
static void insert_verse_edgehash(struct VNode *vnode, struct VerseEdge *vedge);
|
||||
static void remove_verse_edgehash(struct VNode *vnode, struct VerseEdge *vedge);
|
||||
static void remove_verse_edge(struct VNode *vnode, uint32 v0, uint32 v1);
|
||||
static void add_verse_edge(struct VNode *vnode, uint32 v0, uint32 v1);
|
||||
static void update_edgehash_of_deleted_verseface(struct VNode *vnode, struct VerseFace *vface);
|
||||
static void update_edgehash_of_changed_verseface(struct VNode *vnode, struct VerseFace *vface, uint32 v0, uint32 v1, uint32 v2, uint32 v3);
|
||||
static void update_edgehash_of_new_verseface(struct VNode *vnode, uint32 v0, uint32 v1, uint32 v2, uint32 v3);
|
||||
|
||||
/*
|
||||
* recalcute normals of all VerseFaces
|
||||
*/
|
||||
@ -799,6 +809,22 @@ VerseVert* create_verse_vertex(
|
||||
return vvert;
|
||||
}
|
||||
|
||||
/*
|
||||
* this function creates fake VerseEdge and returns pointer at this edge
|
||||
*/
|
||||
VerseEdge *create_verse_edge(uint32 v0, uint32 v1)
|
||||
{
|
||||
struct VerseEdge *vedge;
|
||||
|
||||
vedge = (VerseEdge*)MEM_mallocN(sizeof(VerseEdge), "VerseEdge");
|
||||
|
||||
vedge->v0 = v0;
|
||||
vedge->v1 = v1;
|
||||
vedge->counter = 0;
|
||||
|
||||
return vedge;
|
||||
}
|
||||
|
||||
/*
|
||||
* this function will create new VerseFace and will return pointer on such Face
|
||||
*/
|
||||
@ -903,6 +929,10 @@ VGeomData *create_geometry_data(void)
|
||||
geom->mesh = NULL;
|
||||
geom->editmesh = NULL;
|
||||
|
||||
/* initialize list of fake verse edges and initialize verse edge hash */
|
||||
geom->edges.first = geom->edges.last = NULL;
|
||||
geom->hash = MEM_callocN(VEDHASHSIZE*sizeof(HashVerseEdge), "verse hashedge tab");
|
||||
|
||||
/* set up methods */
|
||||
geom->post_vertex_create = post_vertex_create;
|
||||
geom->post_vertex_set_xyz = post_vertex_set_xyz;
|
||||
@ -1058,6 +1088,9 @@ static void cb_g_polygon_delete(
|
||||
vface = BLI_dlist_find_link(&(vlayer->dl), polygon_id);
|
||||
|
||||
if(!vface) return;
|
||||
|
||||
/* update edge hash */
|
||||
update_edgehash_of_deleted_verseface(vnode, vface);
|
||||
|
||||
((VGeomData*)vnode->data)->post_polygon_delete(vface);
|
||||
|
||||
@ -1106,6 +1139,231 @@ static VLayer *find_vlayer_in_sending_queue(VNode *vnode, VLayerID layer_id)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* this function will find edge in hash table, hash function isn't too optimal (it needs
|
||||
* lot of memory for every verse node), but it works without any bug
|
||||
*/
|
||||
static VerseEdge* find_verse_edge(VNode *vnode, uint32 v0, uint32 v1)
|
||||
{
|
||||
struct HashVerseEdge *hve;
|
||||
|
||||
if(((VGeomData*)vnode->data)->hash==NULL)
|
||||
((VGeomData*)vnode->data)->hash = MEM_callocN(VEDHASHSIZE*sizeof(HashVerseEdge), "verse hashedge tab");
|
||||
|
||||
hve = ((VGeomData*)vnode->data)->hash + VEDHASH(v0, v1);;
|
||||
while(hve) {
|
||||
/* edge v0---v1 is the same edge as v1---v0 */
|
||||
if(hve->vedge && ((hve->vedge->v0==v0 && hve->vedge->v1==v1) || (hve->vedge->v0==v1 && hve->vedge->v1==v0))) return hve->vedge;
|
||||
hve = hve->next;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* insert hash of verse edge to hash table
|
||||
*/
|
||||
static void insert_verse_edgehash(VNode *vnode, VerseEdge *vedge)
|
||||
{
|
||||
struct HashVerseEdge *first, *hve;
|
||||
|
||||
if(((VGeomData*)vnode->data)->hash==NULL)
|
||||
((VGeomData*)vnode->data)->hash = MEM_callocN(VEDHASHSIZE*sizeof(HashVerseEdge), "verse hashedge tab");
|
||||
|
||||
first = ((VGeomData*)vnode->data)->hash + VEDHASH(vedge->v0, vedge->v1);
|
||||
|
||||
if(first->vedge==NULL) {
|
||||
first->vedge = vedge;
|
||||
}
|
||||
else {
|
||||
hve = &(vedge->hash);
|
||||
hve->vedge = vedge;
|
||||
hve->next = first->next;
|
||||
first->next = hve;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* remove hash of verse edge from hash table
|
||||
*/
|
||||
static void remove_verse_edgehash(VNode *vnode, VerseEdge *vedge)
|
||||
{
|
||||
struct HashVerseEdge *first, *hve, *prev;
|
||||
|
||||
hve = first = ((VGeomData*)vnode->data)->hash + VEDHASH(vedge->v0, vedge->v1);
|
||||
|
||||
while(hve) {
|
||||
if(hve->vedge == vedge) {
|
||||
if(hve==first) {
|
||||
if(first->next) {
|
||||
hve = first->next;
|
||||
first->vedge = hve->vedge;
|
||||
first->next = hve->next;
|
||||
}
|
||||
else {
|
||||
hve->vedge = NULL;
|
||||
}
|
||||
}
|
||||
else {
|
||||
prev->next = hve->next;
|
||||
}
|
||||
return;
|
||||
}
|
||||
prev = hve;
|
||||
hve = hve->next;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* this function will try to remove existing fake verse edge, when this verse
|
||||
* edge is still used by some faces, then counter will be only decremented
|
||||
*/
|
||||
static void remove_verse_edge(VNode *vnode, uint32 v0, uint32 v1)
|
||||
{
|
||||
struct VerseEdge *vedge;
|
||||
|
||||
vedge = find_verse_edge(vnode, v0, v1);
|
||||
if(vedge) {
|
||||
vedge->counter--;
|
||||
if(vedge->counter==0) {
|
||||
remove_verse_edgehash(vnode, vedge);
|
||||
BLI_freelinkN(&(((VGeomData*)vnode->data)->edges), vedge);
|
||||
}
|
||||
}
|
||||
else {
|
||||
printf("error: remove_verse_edge %d, %d\n", v0, v1);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* this function will try to add new fake verse edge, when no such edge exist,
|
||||
* when such edge exist, then only counter of edge will be incremented
|
||||
*/
|
||||
static void add_verse_edge(VNode *vnode, uint32 v0, uint32 v1)
|
||||
{
|
||||
struct VerseEdge *vedge;
|
||||
|
||||
vedge = find_verse_edge(vnode, v0, v1);
|
||||
if(!vedge) {
|
||||
if(v0!=v1) {
|
||||
vedge = create_verse_edge(v0, v1);
|
||||
BLI_addtail(&(((VGeomData*)vnode->data)->edges), vedge);
|
||||
insert_verse_edgehash(vnode, vedge);
|
||||
}
|
||||
else {
|
||||
printf("error:add_verse_edge: %d, %d\n", v0, v1);
|
||||
return;
|
||||
}
|
||||
}
|
||||
vedge->counter++;
|
||||
}
|
||||
|
||||
/*
|
||||
* verse face was deleted ... update edge hash
|
||||
*/
|
||||
static void update_edgehash_of_deleted_verseface(VNode *vnode, VerseFace *vface)
|
||||
{
|
||||
uint32 v0, v1, v2, v3; /* verse vertex indexes of deleted verse face */
|
||||
|
||||
v0 = vface->vvert0->id;
|
||||
v1 = vface->vvert1->id;
|
||||
v2 = vface->vvert2->id;
|
||||
v3 = vface->vvert3 ? vface->vvert3->id : -1;
|
||||
|
||||
remove_verse_edge(vnode, v0, v1);
|
||||
remove_verse_edge(vnode, v1, v2);
|
||||
if(v3!=-1) {
|
||||
remove_verse_edge(vnode, v2, v3);
|
||||
remove_verse_edge(vnode, v3, v0);
|
||||
}
|
||||
else {
|
||||
remove_verse_edge(vnode, v2, v0);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* existing verse face was changed ... update edge hash
|
||||
*/
|
||||
static void update_edgehash_of_changed_verseface(
|
||||
VNode *vnode,
|
||||
VerseFace *vface,
|
||||
uint32 v0,
|
||||
uint32 v1,
|
||||
uint32 v2,
|
||||
uint32 v3)
|
||||
{
|
||||
uint32 ov0, ov1, ov2, ov3; /* old indexes at verse vertexes*/
|
||||
|
||||
ov0 = vface->vvert0->id;
|
||||
ov1 = vface->vvert1->id;
|
||||
ov2 = vface->vvert2->id;
|
||||
ov3 = vface->vvert3 ? vface->vvert3->id : -1;
|
||||
|
||||
/* 1st edge */
|
||||
if(v0!=ov0 || v1!=ov1) {
|
||||
remove_verse_edge(vnode, ov0, ov1);
|
||||
add_verse_edge(vnode, v0, v1);
|
||||
}
|
||||
|
||||
/* 2nd edge */
|
||||
if(v1!=ov1 || v2!=ov2) {
|
||||
remove_verse_edge(vnode, ov1, ov2);
|
||||
add_verse_edge(vnode, v1, v2);
|
||||
}
|
||||
|
||||
/* 3rd edge */
|
||||
if(v2!=ov2 || v3!=ov3 || v0!=ov0) {
|
||||
if(ov3!=-1) {
|
||||
remove_verse_edge(vnode, ov2, ov3);
|
||||
if(v3!=-1) {
|
||||
add_verse_edge(vnode, v2, v3); /* new 3rd edge (quat->quat) */
|
||||
}
|
||||
else {
|
||||
remove_verse_edge(vnode, ov3, ov0); /* old edge v3,v0 of quat have to be removed */
|
||||
add_verse_edge(vnode, v2, v0); /* new 3rd edge (quat->triangle) */
|
||||
}
|
||||
}
|
||||
else {
|
||||
remove_verse_edge(vnode, ov2, ov0);
|
||||
if(v3!=-1) {
|
||||
add_verse_edge(vnode, v2, v3); /* new 3rd edge (triangle->quat) */
|
||||
}
|
||||
else {
|
||||
add_verse_edge(vnode, v2, v0); /* new 3rd edge (triangle->triangle) */
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* 4th edge */
|
||||
if(v3!=-1 && (v3!=ov3 || v0!=ov0)) {
|
||||
remove_verse_edge(vnode, ov3, ov0);
|
||||
add_verse_edge(vnode, v3, v0);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* new verse face was created ... update list of edges and edge has
|
||||
*/
|
||||
static void update_edgehash_of_new_verseface(
|
||||
VNode *vnode,
|
||||
uint32 v0,
|
||||
uint32 v1,
|
||||
uint32 v2,
|
||||
uint32 v3)
|
||||
{
|
||||
/* when edge already exists, then only its counter is incremented,
|
||||
* look at commentary of add_verse_edge() function */
|
||||
add_verse_edge(vnode, v0, v1);
|
||||
add_verse_edge(vnode, v1, v2);
|
||||
if(v3!=-1) {
|
||||
add_verse_edge(vnode, v2, v3);
|
||||
add_verse_edge(vnode, v3, v0);
|
||||
}
|
||||
else {
|
||||
add_verse_edge(vnode, v2, v0);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* callback function: new polygon (face) created or existing polygon was changed
|
||||
*/
|
||||
@ -1166,6 +1424,9 @@ static void cb_g_polygon_set_corner_uint32(
|
||||
* layer ids */
|
||||
vface = find_verse_face_in_queue(vlayer, node_id, polygon_id, v0, v1, v2, v3);
|
||||
|
||||
/* update edge hash */
|
||||
update_edgehash_of_new_verseface(vnode, v0, v1, v2, v3);
|
||||
|
||||
if(vface){
|
||||
/* printf("\tremove from vface queue\n");*/
|
||||
/* I creeated this face ... remove VerseFace from queue */
|
||||
@ -1204,6 +1465,9 @@ static void cb_g_polygon_set_corner_uint32(
|
||||
/* VerseVertexes of existing VerseFace were changed (VerseFace will use some different
|
||||
* VerseVertexes or it will use them in different order) */
|
||||
|
||||
/* update fake verse edges */
|
||||
update_edgehash_of_changed_verseface(vnode, vface, v0, v1, v2, v3);
|
||||
|
||||
/* initialize count of unreceived vertexes needed for this face */
|
||||
vface->counter = 4;
|
||||
|
||||
@ -1423,19 +1687,24 @@ static void cb_g_vertex_set_xyz_real32(
|
||||
if(vvert->flag & VERT_OBSOLETE) return;
|
||||
|
||||
if (vvert->flag & VERT_LOCKED) {
|
||||
/* this application changed position of this vertex */
|
||||
if((vvert->co[0]==x) && (vvert->co[1]==y) && (vvert->co[2]==z)) {
|
||||
if (!(vvert->flag & VERT_POS_OBSOLETE))
|
||||
vvert->flag &= ~VERT_LOCKED;
|
||||
recalculate_verseface_normals(vnode);
|
||||
((VGeomData*)vnode->data)->post_vertex_set_xyz(vvert);
|
||||
/* unlock vertex position */
|
||||
vvert->flag &= ~VERT_LOCKED;
|
||||
/* call post_vertex_set_xyz only, when position of vertex is
|
||||
* obsolete ... the new vertex position will be sent to
|
||||
* verse server */
|
||||
if (vvert->flag & VERT_POS_OBSOLETE) {
|
||||
((VGeomData*)vnode->data)->post_vertex_set_xyz(vvert);
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
/* somebody else changed position of this vertex*/
|
||||
if((vvert->co[0]!=x) || (vvert->co[1]!=y) || (vvert->co[2]!=z)) {
|
||||
vvert->co[0] = x;
|
||||
vvert->co[1] = y;
|
||||
vvert->co[2] = z;
|
||||
|
||||
recalculate_verseface_normals(vnode);
|
||||
((VGeomData*)vnode->data)->post_vertex_set_xyz(vvert);
|
||||
}
|
||||
@ -1625,6 +1894,10 @@ void free_geom_data(VNode *vnode)
|
||||
((VGeomData*)vnode->data)->post_geometry_free_constraint(vnode);
|
||||
/* free all VerseLayers */
|
||||
BLI_dlist_destroy(&(((VGeomData*)vnode->data)->layers));
|
||||
/* free fake verse edges */
|
||||
BLI_freelistN(&((VGeomData*)vnode->data)->edges);
|
||||
/* free edge hash */
|
||||
MEM_freeN(((VGeomData*)vnode->data)->hash);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -467,38 +467,45 @@ void b_verse_send_vertex_delete(EditVert *eve)
|
||||
*/
|
||||
void send_versevert_pos(VerseVert *vvert)
|
||||
{
|
||||
/* delete command was sent to verse server ... sending one
|
||||
* more position command would create new vertex */
|
||||
if ((vvert->flag & VERT_DELETED) | (vvert->flag & VERT_OBSOLETE)) return;
|
||||
|
||||
/* don't send position of verse vertex to verse server, because it could create
|
||||
* new vertex */
|
||||
if(vvert->flag & VERT_RECEIVED && !(vvert->flag & VERT_DELETED)) {
|
||||
if(vvert->flag & VERT_RECEIVED) {
|
||||
if(vvert->flag & VERT_LOCKED) {
|
||||
/* when position of verse vert was sent to verse server
|
||||
* and it wasn't received yet, then mark sent position
|
||||
* as obsolete ... blender will automaticaly send actual
|
||||
* position, when old will be received */
|
||||
vvert->flag |= VERT_POS_OBSOLETE;
|
||||
/* printf("\tsend_versevert_pos: %d mark OBSOLETE\n", vvert->id);*/
|
||||
}
|
||||
else {
|
||||
struct EditVert *eve = (EditVert*)vvert->vertex;
|
||||
/* send position to verse server, when it is different from actual position */
|
||||
if(eve && (eve->co[0]!=vvert->co[0] || eve->co[1]!=vvert->co[1] || eve->co[2]!=vvert->co[2])) {
|
||||
/* lock vertex and send its position to verse server */
|
||||
/* lock vertex and send its position to verse server,
|
||||
* locking of vertex prevents from sending too many
|
||||
* informations about vertex position during draging
|
||||
* of vertex */
|
||||
vvert->flag |= VERT_LOCKED;
|
||||
VECCOPY(vvert->co, eve->co);
|
||||
/* printf("\tsend_versevert_pos: %d send and LOCK \n", vvert->id);*/
|
||||
send_verse_vertex(vvert);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(!(vvert->flag & VERT_RECEIVED) && (vvert->flag & VERT_LOCKED)) {
|
||||
else {
|
||||
/* we created this vertex and we sent new position to verse server, but "confirmation" command about
|
||||
* position of vertex didn't arrived yet, then we can't send new position of vertex ... we only mark
|
||||
* position of vertex as obsolete and new position will be sent to verse server, when confirmation
|
||||
* command will arive */
|
||||
struct EditVert *eve = (EditVert*)vvert->vertex;
|
||||
if(eve && (eve->co[0]!=vvert->co[0] || eve->co[1]!=vvert->co[1] || eve->co[2]!=vvert->co[2])) {
|
||||
/* printf("\tsend_versevert_pos: %d mark VERT_POS_OBSOLETE\n", vvert->id); */
|
||||
vvert->flag |= VERT_POS_OBSOLETE;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
verse_callback_update(0);
|
||||
}
|
||||
|
||||
@ -723,7 +730,6 @@ void post_vertex_set_xyz(VerseVert *vvert)
|
||||
|
||||
eve = (EditVert*)vvert->vertex;
|
||||
VECCOPY(vvert->co, eve->co);
|
||||
/* printf("\tpost_vertex_set_xyz: %d send and NOT_OBSOLETE\n", vvert->id); */
|
||||
send_verse_vertex(vvert);
|
||||
verse_callback_update(0);
|
||||
}
|
||||
@ -733,12 +739,11 @@ void post_vertex_set_xyz(VerseVert *vvert)
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/* when shared object is in edit mode, then update editmesh */
|
||||
if(G.obedit && (((Mesh*)G.obedit->data)->vnode==geom_vnode)) {
|
||||
if(vvert->vertex) {
|
||||
eve = (EditVert*)vvert->vertex;
|
||||
/* printf("\tupdate pos of edit vert %d\n", vvert->id); */
|
||||
VECCOPY(eve->co, vvert->co);
|
||||
recalc_editnormals();
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user