Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/source
diff options
context:
space:
mode:
authorJiri Hnidek <jiri.hnidek@tul.cz>2007-04-27 18:04:30 +0400
committerJiri Hnidek <jiri.hnidek@tul.cz>2007-04-27 18:04:30 +0400
commit76c11ec9f71ef796d6cd6cbbe09add73a30e4af2 (patch)
tree2dcd9bf62ba94ea4fc2127b7fca38e6e67e361bd /source
parentd584c8a1e62a596d3a9bf3f5555ed050427a5990 (diff)
- 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
Diffstat (limited to 'source')
-rw-r--r--source/blender/blenkernel/BKE_verse.h34
-rw-r--r--source/blender/blenkernel/intern/DerivedMesh.c243
-rw-r--r--source/blender/blenkernel/intern/cdderivedmesh.c6
-rw-r--r--source/blender/blenkernel/intern/verse_geometry_node.c283
-rw-r--r--source/blender/src/verse_mesh.c27
5 files changed, 473 insertions, 120 deletions
diff --git a/source/blender/blenkernel/BKE_verse.h b/source/blender/blenkernel/BKE_verse.h
index 18dfbf15640..fe5fc44ba1e 100644
--- a/source/blender/blenkernel/BKE_verse.h
+++ b/source/blender/blenkernel/BKE_verse.h
@@ -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,9 +134,31 @@ 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
*/
typedef struct VerseFace {
@@ -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);
diff --git a/source/blender/blenkernel/intern/DerivedMesh.c b/source/blender/blenkernel/intern/DerivedMesh.c
index ff704d59463..38762d8f49a 100644
--- a/source/blender/blenkernel/intern/DerivedMesh.c
+++ b/source/blender/blenkernel/intern/DerivedMesh.c
@@ -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;
+
+ if(!vdm->vertex_layer) return;
- for( ; vvert; vvert = vvert->next, ++vert_r) {
+ 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;
}
diff --git a/source/blender/blenkernel/intern/cdderivedmesh.c b/source/blender/blenkernel/intern/cdderivedmesh.c
index 404e433d6cd..c983f6b48e5 100644
--- a/source/blender/blenkernel/intern/cdderivedmesh.c
+++ b/source/blender/blenkernel/intern/cdderivedmesh.c
@@ -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)
diff --git a/source/blender/blenkernel/intern/verse_geometry_node.c b/source/blender/blenkernel/intern/verse_geometry_node.c
index 9af22bfd37d..8d58d140c79 100644
--- a/source/blender/blenkernel/intern/verse_geometry_node.c
+++ b/source/blender/blenkernel/intern/verse_geometry_node.c
@@ -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
*/
@@ -800,6 +810,22 @@ VerseVert* create_verse_vertex(
}
/*
+ * 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
*/
VerseFace* create_verse_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);
@@ -1107,6 +1140,231 @@ static VLayer *find_vlayer_in_sending_queue(VNode *vnode, VLayerID layer_id)
}
/*
+ * 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
*/
static void cb_g_polygon_set_corner_uint32(
@@ -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);
}
}
diff --git a/source/blender/src/verse_mesh.c b/source/blender/src/verse_mesh.c
index 350d78b6bae..8c7d6509502 100644
--- a/source/blender/src/verse_mesh.c
+++ b/source/blender/src/verse_mesh.c
@@ -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();
}