resolve some compiler warnings with intel c/c++ compiler
[blender.git] / source / blender / blenkernel / intern / verse_geometry_node.c
1 /**
2  * $Id$
3  *
4  * ***** BEGIN GPL LICENSE BLOCK *****
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * as published by the Free Software Foundation; either version 2
9  * of the License, or (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software Foundation,
18  * Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
19  *
20  * Contributor(s): Jiri Hnidek.
21  *
22  * ***** END GPL LICENSE BLOCK *****
23  */
24
25 #ifdef WITH_VERSE
26
27 #include <string.h>
28
29 #include "MEM_guardedalloc.h"
30
31 #include "DNA_listBase.h"
32
33 #include "BLI_dynamiclist.h"
34 #include "BLI_blenlib.h"
35 #include "BLI_arithb.h"
36
37 #include "BKE_verse.h"
38 #include "BKE_utildefines.h"
39
40 #include "BIF_verse.h"
41
42 #include "verse.h"
43
44 /* function prototypes of static functions */
45
46 /* test functions for callback functions */
47 static char test_polygon_set_corner_uint32(uint32 v0, uint32 v1, uint32 v2, uint32 v3);
48
49 /* callback functions */
50 static void cb_g_layer_create(void *user_data, VNodeID node_id, VLayerID layer_id, const char *name, VNGLayerType type, uint32 def_integer, real64 def_real);
51 static void cb_g_layer_destroy(void *user_data, VNodeID node_id, VLayerID layer_id);
52 static void cb_g_vertex_set_xyz_real32(void *user_data, VNodeID node_id, VLayerID layer_id, uint32 vertex_id, real32 x,         real32 y, real32 z);
53 static void cb_g_polygon_set_corner_uint32(void *user_data, VNodeID node_id, VLayerID layer_id, uint32 polygon_id, uint32 v0, uint32 v1, uint32 v2, uint32 v3);
54 static void cb_g_vertex_delete_real32(void *user_data, VNodeID node_id, uint32 vertex_id);
55 static void cb_g_polygon_delete(void *user_data, VNodeID node_id, uint32 polygon_id);
56 static void cb_g_crease_set_edge(void *user_data, VNodeID node_id, const char *layer, uint32 def_crease);
57 static void cb_g_crease_set_vertex(void *user_data, VNodeID node_id, const char *layer, uint32 def_crease);
58
59 /* other static functions */
60
61 static void free_unneeded_verseverts_of_verseface(struct VNode *vnode, struct VerseFace *vface);
62 static void free_verse_vertex(struct VLayer *vlayer, struct VerseVert *vvert);
63 static void free_verse_face(struct VLayer *vlayer, struct VerseFace *vface);
64 static void free_verse_layer_data(struct VNode *vnode, struct VLayer *vlayer);
65
66 static void send_verse_face(struct VerseFace *vface);
67
68 static VerseVert* find_verse_vert_in_queue(struct VLayer *vlayer, VNodeID node_id, uint32 vertex_id, real32 x, real32 y, real32 z);
69 static VerseFace* find_verse_face_in_queue(struct VLayer *vlayer, VNodeID node_id, uint32 polygon_id, uint32 v0, uint32 v1, uint32 v2, uint32 v3);
70
71 static unsigned short test_incoming_verseface(struct VGeomData *geom, struct VerseFace *vface);
72 static void find_unsent_faces(struct VNode *vnode, struct VerseVert *vvert);
73 static void find_vlayer_orphans(struct VNode *vnode, struct VerseVert *vvert);
74 static void move_face_orphan_to_dlist(struct VNode *vnode, struct VLayer *vlayer, struct VerseFace *vface);
75 static void increase_verse_verts_references(struct VerseFace *vface);
76 static void recalculate_verseface_normals(struct VNode *vnode);
77
78 /* verse edge functions */
79 static VerseEdge* find_verse_edge(struct VNode *vnode, uint32 v0, uint32 v1);
80 static void insert_verse_edgehash(struct VNode *vnode, struct VerseEdge *vedge);
81 static void remove_verse_edgehash(struct VNode *vnode, struct VerseEdge *vedge);
82 static void remove_verse_edge(struct VNode *vnode, uint32 v0, uint32 v1);
83 static void add_verse_edge(struct VNode *vnode, uint32 v0, uint32 v1);
84 static void update_edgehash_of_deleted_verseface(struct VNode *vnode, struct VerseFace *vface);
85 static void update_edgehash_of_changed_verseface(struct VNode *vnode, struct VerseFace *vface, uint32 v0, uint32 v1, uint32 v2, uint32 v3);
86 static void update_edgehash_of_new_verseface(struct VNode *vnode, uint32 v0, uint32 v1, uint32 v2, uint32 v3);
87
88 /*
89  * recalcute normals of all VerseFaces
90  */
91 static void recalculate_verseface_normals(VNode *vnode)
92 {
93         struct VLayer *vert_layer, *face_layer;
94         struct VerseFace *vface;
95         struct VerseVert *vvert;
96
97         if(vnode->type != V_NT_GEOMETRY) return;
98
99         vert_layer = find_verse_layer_type((VGeomData*)vnode->data, VERTEX_LAYER);
100         face_layer = find_verse_layer_type((VGeomData*)vnode->data, POLYGON_LAYER);
101
102         vvert = vert_layer->dl.lb.first;
103         while(vvert) {
104                 vvert->no[0] = vvert->no[1] = vvert->no[2] = 0.0;
105                 vvert = vvert->next;
106         }
107
108         vface = face_layer->dl.lb.first;
109         while(vface) {
110                 /* calculate face normals */
111                 if(vface->vvert3) {
112                         CalcNormFloat4(vface->vvert0->co, vface->vvert1->co,
113                                         vface->vvert2->co, vface->vvert3->co, vface->no);
114                         VecAddf(vface->vvert3->no, vface->vvert3->no, vface->no);
115                 }
116                 else
117                         CalcNormFloat(vface->vvert0->co, vface->vvert1->co,
118                                         vface->vvert2->co, vface->no);
119
120                 /* calculate vertex normals ... it is averadge of all face normals using the vertex */
121                 VecAddf(vface->vvert0->no, vface->vvert0->no, vface->no);
122                 VecAddf(vface->vvert1->no, vface->vvert1->no, vface->no);
123                 VecAddf(vface->vvert2->no, vface->vvert2->no, vface->no);
124
125                 vface = vface->next;
126         }
127
128         /* we have to normalize all vertex normals */
129         vvert = vert_layer->dl.lb.first;
130         while(vvert) {
131                 Normalize(vvert->no);
132                 vvert = vvert->next;
133         }
134 }
135
136 /*
137  * add created item to the queue and send it if possible
138  */
139 void add_item_to_send_queue(ListBase *lb, void *item, short type)
140 {
141         struct VNode *vnode;
142         struct VLayer *vlayer;
143         struct VerseVert *vvert;
144         struct VerseFace *vface;
145
146         /* this prevent from adding duplicated faces */
147         if(type==VERSE_FACE) {
148                 struct Link *link = (Link*)lb->first;
149                 while(link) {
150                         if(link==item) {
151                                 if(((VerseFace*)item)->flag & FACE_SENT) {
152 /*                                      printf("\tverse face %d marked as OBSOLETE\n", ((VerseFace*)item)->id);*/
153                                         ((VerseFace*)item)->flag |= FACE_OBSOLETE;
154                                 }
155                                 return;
156                         }
157                         link = link->next;
158                 }
159         }
160
161         /* add item to sending queue (two way dynamic list) */
162         BLI_addtail(lb, item);
163
164         /* send item, when it is possible */
165         switch (type) {
166                 case VERSE_NODE:        /* only first node in queue can be sent */
167                         if(lb->first==lb->last) 
168                                 send_verse_node((VNode*)item);
169                         break;
170                 case VERSE_LINK:        /* both object between have to exist */
171                         if(((VLink*)item)->flag & LINK_SEND_READY)
172                                 send_verse_link((VLink*)item);
173                         break;
174                 case VERSE_LAYER:
175                         if(((VLayer*)item)->vnode->flag & NODE_RECEIVED)
176                                 send_verse_layer((VLayer*)item);
177                         break;
178                 case VERSE_VERT:
179                         if(((VerseVert*)item)->vlayer->flag & LAYER_RECEIVED)
180                                 send_verse_vertex((VerseVert*)item);
181                         break;
182                 case VERSE_FACE:        /* all vertexes of face have to be received */
183                         if(((VerseFace*)item)->flag & FACE_SEND_READY)
184                                 send_verse_face((VerseFace*)item);
185                         break;
186                 case VERSE_TAG:
187                         send_verse_tag((VTag*)item);
188                         break;
189                 case VERSE_TAG_GROUP:
190                         send_verse_taggroup((VTagGroup*)item);
191                         break;
192                 case VERSE_VERT_UINT32: /* parent item has to exist */
193                         vnode = (((uint32_item*)item)->vlayer)->vnode;
194                         vlayer = (VLayer*)BLI_dlist_find_link(&(((VGeomData*)vnode->data)->layers), 0 );
195                         vvert = (VerseVert*)BLI_dlist_find_link(&(vlayer->dl), ((uint32_item*)item)->id );
196                         if(vvert != NULL)
197                                 send_verse_vert_uint32((uint32_item*)item, type);
198                         break;
199                 case VERSE_VERT_REAL32: /* parent item has to exist */
200                         vnode = (((real32_item*)item)->vlayer)->vnode;
201                         vlayer = (VLayer*)BLI_dlist_find_link(&(((VGeomData*)vnode->data)->layers), 0 );
202                         vvert = (VerseVert*)BLI_dlist_find_link(&(vlayer->dl), ((real32_item*)item)->id );
203                         if( vvert != NULL)
204                                 send_verse_vert_real32((real32_item*)item, type);
205                         break;
206                 case VERSE_VERT_VEC_REAL32:     /* parent item has to exist */
207                         vnode = (((vec_real32_item*)item)->vlayer)->vnode;
208                         vlayer = (VLayer*)BLI_dlist_find_link(&(((VGeomData*)vnode->data)->layers), 0 );
209                         vvert = (VerseVert*)BLI_dlist_find_link(&(vlayer->dl), ((vec_real32_item*)item)->id );
210                         if(vvert != NULL)
211                                 send_verse_vert_vec_real32((vec_real32_item*)item, type);
212                         break;
213                 case VERSE_FACE_UINT8:  /* parent item has to exist */
214                         vnode = (((uint8_item*)item)->vlayer)->vnode;
215                         vlayer = (VLayer*)BLI_dlist_find_link(&(((VGeomData*)vnode->data)->layers), 1 );
216                         vface = (VerseFace*)BLI_dlist_find_link(&(vlayer->dl), ((uint8_item*)item)->id );
217                         if(vface != NULL)
218                                 send_verse_face_uint8((uint8_item*)item, type);
219                         break;
220                 case VERSE_FACE_UINT32: /* parent item has to exist */
221                         vnode = (((uint32_item*)item)->vlayer)->vnode;
222                         vlayer = (VLayer*)BLI_dlist_find_link(&(((VGeomData*)vnode->data)->layers), 1 );
223                         vface = (VerseFace*)BLI_dlist_find_link(&(vlayer->dl), ((uint32_item*)item)->id );
224                         if(vface != NULL)
225                                 send_verse_face_uint32((uint32_item*)item, type);
226                         break;
227                 case VERSE_FACE_REAL32: /* parent item has to exist */
228                         vnode = (((real32_item*)item)->vlayer)->vnode;
229                         vlayer = (VLayer*)BLI_dlist_find_link(&(((VGeomData*)vnode->data)->layers), 1 );
230                         vface = (VerseFace*)BLI_dlist_find_link(&(vlayer->dl), ((real32_item*)item)->id );
231                         if(vface != NULL)
232                                 send_verse_face_real32((real32_item*)item, type);
233                         break;
234                 case VERSE_FACE_QUAT_UINT32:    /* parent item has to exist */
235                         vnode = (((quat_uint32_item*)item)->vlayer)->vnode;
236                         vlayer = (VLayer*)BLI_dlist_find_link(&(((VGeomData*)vnode->data)->layers), 1 );
237                         vface = (VerseFace*)BLI_dlist_find_link(&(vlayer->dl), ((quat_uint32_item*)item)->id );
238                         if(vface != NULL)
239                                 send_verse_face_corner_quat_uint32((quat_uint32_item*)item, type);
240                         break;
241                 case VERSE_FACE_QUAT_REAL32:    /* parent item has to exist */
242                         vnode = (((quat_real32_item*)item)->vlayer)->vnode;
243                         vlayer = (VLayer*)BLI_dlist_find_link(&(((VGeomData*)vnode->data)->layers), 1 );
244                         vface = (VerseFace*)BLI_dlist_find_link(&(vlayer->dl), ((quat_real32_item*)item)->id );
245                         if(vface != NULL)
246                                 send_verse_face_corner_quat_real32((quat_real32_item*)item, type);
247                         break;
248         }
249 }
250
251 /*
252  * return VerseLayer with certain content (vertexes, polygons, in the
253  * future: weight, red color, etc.)
254  */
255 VLayer* find_verse_layer_type(VGeomData *geom, short content)
256 {
257         struct VLayer *vlayer = NULL;
258         
259         switch(content) {
260                 case VERTEX_LAYER:
261                         /* VERTEX_LAYER equals 0 and vertex layer is
262                          * always in 1st layer */
263                         vlayer = geom->layers.da.items[VERTEX_LAYER];
264                         break;
265                 case POLYGON_LAYER:
266                         /* POLYGON_LAYER equals 1 and vertex layer is
267                          * always in 2nd layer */
268                         vlayer = geom->layers.da.items[POLYGON_LAYER];
269                         break;
270         }
271
272         return vlayer;
273 }
274
275 /*
276  * increase references of VerseVerts of new VerseFace
277  */
278 static void increase_verse_verts_references(VerseFace *vface)
279 {
280         if(vface->vvert0) vface->vvert0->counter++;
281         if(vface->vvert1) vface->vvert1->counter++;
282         if(vface->vvert2) vface->vvert2->counter++;
283         if(vface->vvert3) vface->vvert3->counter++;
284 }
285
286 /*
287  * move VerseFace from list of orphans to dlist of VerseFaces (if VerseFace was only changed
288  * then this VerseFace is only removed from list of orphans)
289  */
290 static void move_face_orphan_to_dlist(VNode *vnode, VLayer *vlayer, VerseFace *vface)
291 {
292         /* remove vface from list of orphans */
293         BLI_remlink(&(vlayer->orphans), vface);
294         /* increase references of all vertexes beying part of this face*/
295         increase_verse_verts_references(vface);
296
297         if(vface->flag & FACE_RECEIVED) {
298                 /* set up vface flag */
299                 vface->flag &= ~FACE_RECEIVED;
300                 /* move vface to dynamic list of faces */
301                 BLI_dlist_add_item_index(&(vlayer->dl), (void*)vface, vface->id);
302                 /* recalculate all vertex and faces normals */
303                 recalculate_verseface_normals(vnode);
304                 /* post create action (change local data) */
305                 ((VGeomData*)vnode->data)->post_polygon_create(vface);
306         }
307         else if(vface->flag & FACE_CHANGED) {
308                 /* set up vface flag */
309                 vface->flag &= ~FACE_CHANGED;
310                 /* move vface to dynamic list of faces */
311                 BLI_dlist_add_item_index(&(vlayer->dl), (void*)vface, vface->id);
312                 /* recalculate all vertex and faces normals */
313                 recalculate_verseface_normals(vnode);
314                 /* post create action (change local data) */
315                 ((VGeomData*)vnode->data)->post_polygon_set_corner(vface);
316         }
317 }
318
319 /*
320  * find all VerseFaces waiting in queue, which needs id of new VerseVert
321  */
322 static void find_unsent_faces(VNode *vnode, VerseVert *vvert)
323 {
324         VLayer *vlayer;
325         VerseFace *vface, *next_vface;
326
327         vlayer = find_verse_layer_type((VGeomData*)vnode->data, POLYGON_LAYER);
328
329         if(vlayer) {
330                 vface = vlayer->queue.first;
331                 while(vface) {
332                         next_vface = vface->next;
333                         if(vface->vvert0==vvert) {
334                                 vface->v0 = vvert->id;
335                                 vface->counter--;
336                         }
337                         else if(vface->vvert1==vvert) {
338                                 vface->v1 = vvert->id;
339                                 vface->counter--;
340                         }
341                         else if(vface->vvert2==vvert) {
342                                 vface->v2 = vvert->id;
343                                 vface->counter--;
344                         }
345                         else if(vface->vvert3==vvert){
346                                 vface->v3 = vvert->id;
347                                 vface->counter--;
348                         }
349
350                         if(vface->counter<1 && !(vface->flag & FACE_SENT))
351                                 send_verse_face(vface);
352
353                         vface = next_vface;
354                 }
355         }
356 }
357
358 /*
359  * find all VerseFace orphans, which needs incoming VerseVert
360  */
361 static void find_vlayer_orphans(VNode *vnode, VerseVert *vvert)
362 {
363         VLayer *vlayer;
364         VerseFace *vface, *next_vface;
365         unsigned int vertex_id = vvert->id;
366
367         vlayer = find_verse_layer_type((VGeomData*)vnode->data, POLYGON_LAYER);
368
369         if(vlayer) {
370                 vface = vlayer->orphans.first;
371                 while(vface){
372                         next_vface = vface->next;
373                         if(vface->v0 == vertex_id) {
374                                 vface->vvert0 = vvert;
375                                 vface->counter--;
376                         }
377                         else if(vface->v1 == vertex_id) {
378                                 vface->vvert1 = vvert;
379                                 vface->counter--;
380                         }
381                         else if(vface->v2 == vertex_id) {
382                                 vface->vvert2 = vvert;
383                                 vface->counter--;
384                         }
385                         else if(vface->v3 == vertex_id) {
386                                 vface->vvert3 = vvert;
387                                 vface->counter--;
388                         }
389                         if(vface->counter<1) {
390                                 /* moving VerseFace orphan to dlist */
391                                 move_face_orphan_to_dlist(vnode, vlayer, vface);
392                         }
393                         vface = next_vface;
394                 }
395         }
396 }
397
398 /*
399  * return number of VerseVerts missing to incoming VerseFace, set up pointers
400  * at VerseVerts
401  */
402 static unsigned short test_incoming_verseface(VGeomData *geom, VerseFace *vface)
403 {
404         struct VLayer *vert_layer;
405         struct VerseVert *vvert; 
406         int counter=0;
407
408         vert_layer = find_verse_layer_type(geom, VERTEX_LAYER);
409
410         if(vface->v0 != -1){
411                 vvert = BLI_dlist_find_link(&(vert_layer->dl), vface->v0);
412                 if(vvert==NULL) counter++;
413                 else vface->vvert0 = vvert;
414         }
415         if(vface->v1 != -1){
416                 vvert = BLI_dlist_find_link(&(vert_layer->dl), vface->v1);
417                 if(vvert==NULL) counter++;
418                 else vface->vvert1 = vvert;
419         }
420         if(vface->v2 != -1){
421                 vvert = BLI_dlist_find_link(&(vert_layer->dl), vface->v2);
422                 if(vvert==NULL) counter++;
423                 else vface->vvert2 = vvert;
424         }
425         if(vface->v3 != -1){
426                 vvert = BLI_dlist_find_link(&(vert_layer->dl), vface->v3);
427                 if(vvert==NULL) counter++;
428                 else vface->vvert3 = vvert;
429         }
430         
431         return counter;
432 }
433
434 /*
435  * try to find changed VerseFace in sending queue
436  */
437 static VerseFace* find_changed_verse_face_in_queue(VLayer *vlayer, uint32 polygon_id)
438 {
439         struct VerseFace *vface = vlayer->queue.first;
440
441         while(vface){
442                 if(vface->id == polygon_id && vface->flag & FACE_CHANGED) {
443                         return vface;
444                 }
445                 vface = vface->next;
446         }
447         return NULL;
448 }
449
450 /*
451  * try to find VerseFace in queue
452  */
453 static VerseFace* find_verse_face_in_queue(
454                 VLayer *vlayer,
455                 VNodeID node_id,
456                 uint32 polygon_id,
457                 uint32 v0,
458                 uint32 v1,
459                 uint32 v2,
460                 uint32 v3)
461 {
462         struct VerseFace *vface = vlayer->queue.first;
463
464         while(vface){
465                 if((vface->v0==v0) && (vface->v1==v1) && (vface->v2==v2) && (vface->v3==v3)){
466                         vface->id = polygon_id;
467                         vface->vlayer = vlayer;
468                         return vface;
469                 }
470                 vface = vface->next;
471         }
472         return NULL;
473 }
474
475 /*
476  * try to find VerseVert in queue
477  */
478 static VerseVert* find_verse_vert_in_queue(
479                 VLayer *vlayer,
480                 VNodeID node_id,
481                 uint32 vertex_id,
482                 real32 x,
483                 real32 y,
484                 real32 z)
485 {
486         struct VerseVert *vvert = vlayer->queue.first;
487
488         while(vvert){
489                 if((vvert->vlayer->vnode->id == node_id) && (vvert->co[0] == x) && (vvert->co[1] == y) && (vvert->co[2] == z))
490                 {
491                         vvert->id = vertex_id;
492                         vvert->vlayer = vlayer;
493
494                         return vvert;
495                 }
496                 vvert = vvert->next;
497         }
498
499         return NULL;
500 }
501
502
503 /*
504  * send quat of float values to verse server (4x32 bits)
505  */
506 void send_verse_face_corner_quat_real32(quat_real32_item *item, short type)
507 {
508         verse_send_g_polygon_set_corner_real32(
509                         item->vlayer->vnode->id,
510                         item->vlayer->id,
511                         item->id,
512                         item->value[0],
513                         item->value[1],
514                         item->value[2],
515                         item->value[3]);
516 }
517
518 /*
519  * send quat of unsigned int values to verse server (4x32 bits)
520  */
521 void send_verse_face_corner_quat_uint32(quat_uint32_item *item, short type)
522 {
523         verse_send_g_polygon_set_corner_uint32(
524                         item->vlayer->vnode->id,
525                         item->vlayer->id,
526                         item->id,
527                         item->value[0],
528                         item->value[1],
529                         item->value[2],
530                         item->value[3]);
531 }
532
533 /*
534  * send float value (32 bits) to verse server
535  */
536 void send_verse_face_real32(real32_item *item, short type)
537 {
538         verse_send_g_polygon_set_face_real32(
539                         item->vlayer->vnode->id,
540                         item->vlayer->id,
541                         item->id,
542                         item->value);
543 }
544
545 /*
546  * send unsigned integer (32 bits) to verse server
547  */
548 void send_verse_face_uint32(uint32_item *item, short type)
549 {
550         verse_send_g_polygon_set_face_uint32(
551                         item->vlayer->vnode->id,
552                         item->vlayer->id,
553                         item->id,
554                         item->value);
555 }
556
557 /*
558  * send unsigned char (8 bits) to verse server
559  */
560 void send_verse_face_uint8(uint8_item *item, short type)
561 {
562         verse_send_g_polygon_set_face_uint8(
563                         item->vlayer->vnode->id,
564                         item->vlayer->id,
565                         item->id,
566                         item->value);
567 }
568
569 /*
570  * send vector of float values to verse server (3x32 bits)
571  */
572 void send_verse_vert_vec_real32(vec_real32_item *item, short type)
573 {
574         verse_send_g_vertex_set_xyz_real32(
575                         item->vlayer->vnode->id,
576                         item->vlayer->id,
577                         item->id,
578                         item->value[0],
579                         item->value[1],
580                         item->value[2]);
581 }
582
583 /*
584  * send float value (32 bits) to verse server
585  */
586 void send_verse_vert_real32(real32_item *item, short type)
587 {
588         verse_send_g_vertex_set_real32(
589                         item->vlayer->vnode->id,
590                         item->vlayer->id,
591                         item->id,
592                         item->value);
593 }
594
595 /*
596  * send unsigned integer (32 bits) to verse server
597  */
598 void send_verse_vert_uint32(uint32_item *item, short type)
599 {
600         verse_send_g_vertex_set_uint32(
601                         item->vlayer->vnode->id,
602                         item->vlayer->id,
603                         item->id,
604                         item->value);
605 }
606
607 /*
608  * send delete command to verse server
609  */
610 void send_verse_vertex_delete(VerseVert *vvert)
611 {
612         verse_session_set(vvert->vlayer->vnode->session->vsession);
613
614         vvert->flag |= VERT_OBSOLETE;
615         
616         verse_send_g_vertex_delete_real32(vvert->vlayer->vnode->id, vvert->id);
617 }
618
619 /*
620  * send VerseLayer to verse server
621  */
622 void send_verse_layer(VLayer *vlayer)
623 {
624         verse_session_set(vlayer->vnode->session->vsession);
625
626         verse_send_g_layer_create(
627                         vlayer->vnode->id,
628                         vlayer->id,
629                         vlayer->name,
630                         vlayer->type,
631                         vlayer->def_int,
632                         vlayer->def_real);
633 }
634
635 /* 
636  * send VerseVert to verse server
637  */
638 void send_verse_vertex(VerseVert *vvert)
639 {
640         /* new vertex position will not be sent, when vertex was deleted */
641         if(vvert->flag & VERT_OBSOLETE) return;
642         
643         verse_session_set(vvert->vlayer->vnode->session->vsession);
644
645         verse_send_g_vertex_set_xyz_real32(
646                         vvert->vlayer->vnode->id,
647                         vvert->vlayer->id,
648                         vvert->id,
649                         vvert->co[0],
650                         vvert->co[2],
651                         -vvert->co[1]);
652 }
653
654 /*
655  * send delete command to verse server
656  */
657 void send_verse_face_delete(VerseFace *vface)
658 {
659         verse_session_set(vface->vlayer->vnode->session->vsession);
660
661         vface->flag |= FACE_DELETED;
662
663         verse_send_g_polygon_delete(vface->vlayer->vnode->id, vface->id);
664 }
665
666 /*
667  * send VerseFace to verse server
668  */
669 static void send_verse_face(VerseFace *vface)
670 {
671         verse_session_set(vface->vlayer->vnode->session->vsession);
672
673         vface->flag |= FACE_SENT;
674
675         if(vface->v3 != -1) {
676                 verse_send_g_polygon_set_corner_uint32(
677                                 vface->vlayer->vnode->id,
678                                 vface->vlayer->id,
679                                 vface->id,
680                                 vface->v0,
681                                 vface->v3,      /* verse use clock-wise winding */
682                                 vface->v2,
683                                 vface->v1);     /* verse use clock-wise winding */
684         }
685         else {
686                 verse_send_g_polygon_set_corner_uint32(
687                                 vface->vlayer->vnode->id,
688                                 vface->vlayer->id,
689                                 vface->id,
690                                 vface->v0,
691                                 vface->v2,      /* verse use clock-wise winding */
692                                 vface->v1,      /* verse use clock-wise winding */
693                                 vface->v3);
694         }
695 }
696
697 /*
698  * free VerseVert
699  */
700 static void free_verse_vertex(VLayer *vlayer, VerseVert *vvert)
701 {
702         /* free VerseVert */
703         BLI_freelinkN(&(vlayer->orphans), vvert);
704 }
705
706 /*
707  * free VerseFace (and blender face)
708  */
709 static void free_verse_face(VLayer *vlayer, VerseFace *vface)
710 {
711         /* free VerseFace */
712         BLI_dlist_free_item(&(vlayer->dl), (unsigned int)vface->id);
713 }
714
715 /*
716  * free VerseLayer data
717  */
718 static void free_verse_layer_data(VNode *vnode, VLayer *vlayer)
719 {
720         struct VerseFace *vface;
721         struct VerseVert *vvert;
722
723         /* set up EditVert->vvert and EditFace->vface pointers to NULL */
724         switch(vlayer->content) {
725                 case VERTEX_LAYER:
726                         vvert = (VerseVert*)vlayer->dl.lb.first;
727                         while(vvert) {
728                                 ((VGeomData*)vnode->data)->post_vertex_free_constraint(vvert);
729                                 vvert = vvert->next;
730                         }
731                         break;
732                 case POLYGON_LAYER:
733                         vface = (VerseFace*)vlayer->dl.lb.first;
734                         while(vface) {
735                                 ((VGeomData*)vnode->data)->post_polygon_free_constraint(vface);
736                                 vface = vface->next;
737                         }
738                         break;
739                 default:
740                         break;
741         }
742         /* free Verse Layer name */
743         MEM_freeN(vlayer->name);
744         /* destroy VerseLayer data (vertexes, polygons, etc.) */
745         BLI_dlist_destroy(&(vlayer->dl));
746         /* free unsent data */
747         BLI_freelistN(&(vlayer->queue));
748         /* free orphans */
749         BLI_freelistN(&(vlayer->orphans));
750 }
751
752 /*
753  * free all unneeded VerseVerts waiting for deleting
754  */
755 static void free_unneeded_verseverts_of_verseface(VNode *vnode, VerseFace *vface)
756 {
757         struct VLayer *vert_vlayer;
758
759         /* find layer containing vertexes */
760         vert_vlayer = find_verse_layer_type((VGeomData*)vnode->data, VERTEX_LAYER);
761
762         /* free all "deleted" VerseVert waiting for deleting this VerseFace */
763         
764         if((vface->vvert0->counter < 1) && (vface->vvert0->flag & VERT_DELETED)) {
765                 ((VGeomData*)vnode->data)->post_vertex_delete(vface->vvert0);
766                 free_verse_vertex(vert_vlayer, vface->vvert0);
767                 vface->vvert0 = NULL;
768         }
769         if((vface->vvert1->counter < 1) && (vface->vvert1->flag & VERT_DELETED)) {
770                 ((VGeomData*)vnode->data)->post_vertex_delete(vface->vvert1);
771                 free_verse_vertex(vert_vlayer, vface->vvert1);
772                 vface->vvert1 = NULL;
773         }
774         if((vface->vvert2->counter < 1) && (vface->vvert2->flag & VERT_DELETED)) {
775                 ((VGeomData*)vnode->data)->post_vertex_delete(vface->vvert2);
776                 free_verse_vertex(vert_vlayer, vface->vvert2);
777                 vface->vvert2 = NULL;
778         }
779         if((vface->vvert3) && (vface->vvert3->counter < 1) && (vface->vvert3->flag & VERT_DELETED)) {
780                 ((VGeomData*)vnode->data)->post_vertex_delete(vface->vvert3);
781                 free_verse_vertex(vert_vlayer, vface->vvert3);
782                 vface->vvert3 = NULL;
783         }
784 }
785
786 /*
787  * This function create VerseVert and returns pointer on this vertex
788  */
789 VerseVert* create_verse_vertex(
790                 VLayer *vlayer,
791                 uint32 vertex_id,
792                 real32 x,
793                 real32 y,
794                 real32 z)
795 {
796         struct VerseVert *vvert;
797
798         vvert = (VerseVert*)MEM_mallocN(sizeof(VerseVert), "VerseVert");
799         
800         /* set up pointer on parent node */
801         vvert->vlayer = vlayer;
802         vvert->id = vertex_id;
803         /* position */
804         vvert->co[0] = x;
805         vvert->co[1] = y;
806         vvert->co[2] = z;
807         /* normal */
808         vvert->no[0] = vvert->no[1] = vvert->no[2] = 0.0;
809         /* blender internals */
810         vvert->flag = 0;
811         vvert->counter = 0;
812         vvert->vertex = NULL;
813
814         /* increase layer counter of vertexes */
815         vlayer->counter++;
816
817         return vvert;
818 }
819
820 /*
821  * this function creates fake VerseEdge and returns pointer at this edge
822  */
823 VerseEdge *create_verse_edge(uint32 v0, uint32 v1)
824 {
825         struct VerseEdge *vedge;
826
827         vedge = (VerseEdge*)MEM_mallocN(sizeof(VerseEdge), "VerseEdge");
828
829         vedge->v0 = v0;
830         vedge->v1 = v1;
831         vedge->counter = 0;
832
833         return vedge;
834 }
835
836 /*
837  * this function will create new VerseFace and will return pointer on such Face
838  */
839 VerseFace* create_verse_face(
840                 VLayer *vlayer,
841                 uint32 polygon_id,
842                 uint32 v0,
843                 uint32 v1,
844                 uint32 v2,
845                 uint32 v3)
846 {
847         struct VerseFace *vface;
848
849         vface = (VerseFace*)MEM_mallocN(sizeof(VerseFace), "VerseFace");
850
851         /* verse data */
852         vface->vlayer = vlayer;
853         vface->id = polygon_id;
854
855         vface->vvert0 = NULL;
856         vface->vvert1 = NULL;
857         vface->vvert2 = NULL;
858         vface->vvert3 = NULL;
859
860         vface->v0 = v0;
861         vface->v1 = v1;
862         vface->v2 = v2;
863         vface->v3 = v3;
864
865         /* blender data */
866         vface->face = NULL;
867         vface->flag = 0;
868         vface->counter = 4;
869
870         /* increase layer counter of faces */
871         vlayer->counter++;
872         
873         return vface;
874 }
875
876 /*
877  * create and return VerseLayer
878  */
879 VLayer *create_verse_layer(
880                 VNode *vnode,
881                 VLayerID layer_id,
882                 const char *name,
883                 VNGLayerType type,
884                 uint32 def_integer,
885                 real64 def_real)
886 {
887         struct VLayer *vlayer;
888
889         /* add layer to the DynamicList */
890         vlayer = (VLayer*)MEM_mallocN(sizeof(VLayer), "VerseLayer");
891
892         /* store all relevant info to the vlayer and set up vlayer */
893         vlayer->vnode = vnode;
894         vlayer->id = layer_id;
895         vlayer->name = (char*)MEM_mallocN(sizeof(char)*(sizeof(name)+1),"Verse Layer name");
896         strcpy(vlayer->name, name);
897         vlayer->type = type;
898         vlayer->def_int = def_integer;
899         vlayer->def_real = def_real;
900
901         if((type == VN_G_LAYER_VERTEX_XYZ) && (layer_id == 0))
902                 vlayer->content = VERTEX_LAYER;
903         else if((type == VN_G_LAYER_POLYGON_CORNER_UINT32) && (layer_id == 1))
904                 vlayer->content = POLYGON_LAYER;
905         else
906                 vlayer->content = -1;
907
908         /* initialize DynamicList in the vlayer (vertexes, polygons, etc.)*/
909         BLI_dlist_init(&(vlayer->dl));
910         /* initialization of queue of layer */
911         vlayer->queue.first = vlayer->queue.last = NULL;
912         /* initialization of list of orphans */
913         vlayer->orphans.first = vlayer->orphans.last = NULL;
914         /* initialize number of sent items (vertexes, faces, etc) */
915         vlayer->counter = 0;
916         /* initialize flag */
917         vlayer->flag = 0;
918
919         /* set up methods */
920         vlayer->post_layer_create = post_layer_create;
921         vlayer->post_layer_destroy = post_layer_destroy;
922
923         return vlayer;
924 }
925
926 /*
927  * create geometry data
928  */
929 VGeomData *create_geometry_data(void)
930 {
931         struct VGeomData *geom;
932
933         geom = (VGeomData*)MEM_mallocN(sizeof(VGeomData), "VerseGeometryData");
934         BLI_dlist_init(&(geom->layers));
935         geom->vlink = NULL;
936         geom->queue.first = geom->queue.last = NULL;
937         geom->mesh = NULL;
938         geom->editmesh = NULL;
939
940         /* initialize list of fake verse edges and initialize verse edge hash */
941         geom->edges.first = geom->edges.last = NULL;
942         geom->hash = MEM_callocN(VEDHASHSIZE*sizeof(HashVerseEdge), "verse hashedge tab");
943
944         /* set up methods */
945         geom->post_vertex_create = post_vertex_create;
946         geom->post_vertex_set_xyz = post_vertex_set_xyz;
947         geom->post_vertex_delete = post_vertex_delete;
948         geom->post_vertex_free_constraint = post_vertex_free_constraint;
949         geom->post_polygon_create = post_polygon_create;
950         geom->post_polygon_set_corner = post_polygon_set_corner;
951         geom->post_polygon_delete = post_polygon_delete;
952         geom->post_polygon_free_constraint = post_polygon_free_constraint;
953         geom->post_geometry_free_constraint = post_geometry_free_constraint;
954         geom->post_polygon_set_uint8 = post_polygon_set_uint8;
955
956         return geom;
957 }
958
959 /* Create item containing 4 floats */
960 static quat_real32_item *create_quat_real32_item(
961                 VLayer *vlayer,
962                 uint32 item_id,
963                 real32 v0,
964                 real32 v1,
965                 real32 v2,
966                 real32 v3)
967 {
968         struct quat_real32_item *item;
969
970         item = (quat_real32_item*)MEM_mallocN(sizeof(quat_real32_item), "quat_real32_item");
971
972         item->vlayer = vlayer;
973         item->id = item_id;
974         item->value[0] = v0;
975         item->value[1] = v1;
976         item->value[2] = v2;
977         item->value[3] = v3;
978
979         return item;
980 }
981
982 /* Create item containing 1 float */
983 static real32_item *create_real32_item(VLayer *vlayer, uint32 item_id, real32 value)
984 {
985         struct real32_item *item;
986
987         item = (real32_item*)MEM_mallocN(sizeof(real32_item), "real32_item");
988
989         item->vlayer = vlayer;
990         item->id = item_id;
991         item->value = value;
992
993         return item;
994 }
995
996 /* Create item containing 1 integer */
997 static uint32_item *create_uint32_item(VLayer *vlayer, uint32 item_id, uint32 value)
998 {
999         struct uint32_item *item;
1000
1001         item = (uint32_item*)MEM_mallocN(sizeof(uint32_item), "uint32_item");
1002
1003         item->vlayer = vlayer;
1004         item->id = item_id;
1005         item->value = value;
1006
1007         return item;
1008 }
1009
1010 /* Create item containing 1 byte */
1011 static uint8_item *create_uint8_item(VLayer *vlayer, uint32 item_id, uint8 value)
1012 {
1013         struct uint8_item *item;
1014
1015         item = (uint8_item*)MEM_mallocN(sizeof(uint8_item), "uint8_item");
1016
1017         item->vlayer = vlayer;
1018         item->id = item_id;
1019         item->value = value;
1020
1021         return item;
1022 }
1023
1024 /*
1025  * callback function: vertex crease was set
1026  */
1027 static void cb_g_crease_set_vertex(
1028                 void *user_data,
1029                 VNodeID node_id,
1030                 const char *layer,
1031                 uint32 def_crease)
1032 {
1033 }
1034
1035 /*
1036  * we have to test corretness of incoming data from verse server
1037  * no two vertexes can have the same index
1038  */
1039 static char test_polygon_set_corner_uint32(
1040                 uint32 v0,
1041                 uint32 v1,
1042                 uint32 v2,
1043                 uint32 v3)
1044 {
1045         if((v0==v1) || (v0==v2) || (v0==v3) || (v1==v2) || (v1==v3) || (v2==v3))
1046                 return 0;
1047         else
1048                 return 1;
1049 }
1050
1051 /*
1052  * try to find verse layer in sending queue of verse geometry node
1053  */
1054 static VLayer *find_vlayer_in_sending_queue(VNode *vnode, VLayerID layer_id)
1055 {
1056         struct VLayer *vlayer;
1057         
1058         /* try to find verse layyer in sending queue */
1059         vlayer = ((VGeomData*)vnode->data)->queue.first;
1060         while(vlayer) {
1061                 if(vlayer->id==layer_id) return vlayer;
1062                 vlayer = vlayer->next;
1063         }
1064
1065         return NULL;
1066 }
1067
1068 /*
1069  * this function will find edge in hash table, hash function isn't too optimal (it needs
1070  * lot of memory for every verse node), but it works without any bug
1071  */
1072 static VerseEdge* find_verse_edge(VNode *vnode, uint32 v0, uint32 v1)
1073 {
1074         struct HashVerseEdge *hve;
1075
1076         if(((VGeomData*)vnode->data)->hash==NULL)
1077                 ((VGeomData*)vnode->data)->hash = MEM_callocN(VEDHASHSIZE*sizeof(HashVerseEdge), "verse hashedge tab");
1078
1079         hve = ((VGeomData*)vnode->data)->hash + VEDHASH(v0, v1);;
1080         while(hve) {
1081                 /* edge v0---v1 is the same edge as v1---v0 */
1082                 if(hve->vedge && ((hve->vedge->v0==v0 && hve->vedge->v1==v1) || (hve->vedge->v0==v1 && hve->vedge->v1==v0))) return hve->vedge;
1083                 hve = hve->next;
1084         }
1085
1086         return NULL;
1087 }
1088
1089 /*
1090  * insert hash of verse edge to hash table
1091  */
1092 static void insert_verse_edgehash(VNode *vnode, VerseEdge *vedge)
1093 {
1094         struct HashVerseEdge *first, *hve;
1095
1096         if(((VGeomData*)vnode->data)->hash==NULL)
1097                 ((VGeomData*)vnode->data)->hash = MEM_callocN(VEDHASHSIZE*sizeof(HashVerseEdge), "verse hashedge tab");
1098
1099         first = ((VGeomData*)vnode->data)->hash + VEDHASH(vedge->v0, vedge->v1);
1100
1101         if(first->vedge==NULL) {
1102                 first->vedge = vedge;
1103         }
1104         else {
1105                 hve = &(vedge->hash);
1106                 hve->vedge = vedge;
1107                 hve->next = first->next;
1108                 first->next = hve;
1109         }
1110 }
1111
1112 /*
1113  * remove hash of verse edge from hash table
1114  */
1115 static void remove_verse_edgehash(VNode *vnode, VerseEdge *vedge)
1116 {
1117         struct HashVerseEdge *first, *hve, *prev;
1118
1119         hve = first = ((VGeomData*)vnode->data)->hash + VEDHASH(vedge->v0, vedge->v1);
1120
1121         while(hve) {
1122                 if(hve->vedge == vedge) {
1123                         if(hve==first) {
1124                                 if(first->next) {
1125                                         hve = first->next;
1126                                         first->vedge = hve->vedge;
1127                                         first->next = hve->next;
1128                                 }
1129                                 else {
1130                                         hve->vedge = NULL;
1131                                 }
1132                         }
1133                         else {
1134                                 prev->next = hve->next;
1135                         }
1136                         return;
1137                 }
1138                 prev = hve;
1139                 hve = hve->next;
1140         }
1141 }
1142
1143 /*
1144  * this function will try to remove existing fake verse edge, when this verse
1145  * edge is still used by some faces, then counter will be only decremented
1146  */
1147 static void remove_verse_edge(VNode *vnode, uint32 v0, uint32 v1)
1148 {
1149         struct VerseEdge *vedge;
1150
1151         vedge = find_verse_edge(vnode, v0, v1);
1152         if(vedge) {
1153                 vedge->counter--;
1154                 if(vedge->counter==0) {
1155                         remove_verse_edgehash(vnode, vedge);
1156                         BLI_freelinkN(&(((VGeomData*)vnode->data)->edges), vedge);
1157                 }
1158         }
1159         else {
1160                 printf("error: remove_verse_edge %d, %d\n", v0, v1);
1161         }
1162 }
1163
1164 /*
1165  * this function will try to add new fake verse edge, when no such edge exist,
1166  * when such edge exist, then only counter of edge will be incremented
1167  */
1168 static void add_verse_edge(VNode *vnode, uint32 v0, uint32 v1)
1169 {
1170         struct VerseEdge *vedge;
1171
1172         vedge = find_verse_edge(vnode, v0, v1);
1173         if(!vedge) {
1174                 if(v0!=v1) {
1175                         vedge = create_verse_edge(v0, v1);
1176                         BLI_addtail(&(((VGeomData*)vnode->data)->edges), vedge);
1177                         insert_verse_edgehash(vnode, vedge);
1178                 }
1179                 else {
1180                         printf("error:add_verse_edge: %d, %d\n", v0, v1);
1181                         return;
1182                 }
1183         }
1184         vedge->counter++;
1185 }
1186
1187 /*
1188  * verse face was deleted ... update edge hash
1189  */
1190 static void update_edgehash_of_deleted_verseface(VNode *vnode, VerseFace *vface)
1191 {
1192         uint32 v0, v1, v2, v3;          /* verse vertex indexes of deleted verse face */
1193         
1194         v0 = vface->vvert0->id;
1195         v1 = vface->vvert1->id;
1196         v2 = vface->vvert2->id;
1197         v3 = vface->vvert3 ? vface->vvert3->id : -1;
1198
1199         remove_verse_edge(vnode, v0, v1);
1200         remove_verse_edge(vnode, v1, v2);
1201         if(v3!=-1) {
1202                 remove_verse_edge(vnode, v2, v3);
1203                 remove_verse_edge(vnode, v3, v0);
1204         }
1205         else {
1206                 remove_verse_edge(vnode, v2, v0);
1207         }
1208 }
1209
1210 /*
1211  * existing verse face was changed ... update edge hash
1212  */
1213 static void update_edgehash_of_changed_verseface(
1214                 VNode *vnode,
1215                 VerseFace *vface,
1216                 uint32 v0,
1217                 uint32 v1,
1218                 uint32 v2,
1219                 uint32 v3)
1220 {
1221         uint32 ov0, ov1, ov2, ov3;      /* old indexes at verse vertexes*/
1222         
1223         ov0 = vface->vvert0->id;
1224         ov1 = vface->vvert1->id;
1225         ov2 = vface->vvert2->id;
1226         ov3 = vface->vvert3 ? vface->vvert3->id : -1;
1227
1228         /* 1st edge */
1229         if(v0!=ov0 || v1!=ov1) {
1230                 remove_verse_edge(vnode, ov0, ov1);
1231                 add_verse_edge(vnode, v0, v1);
1232         }
1233         
1234         /* 2nd edge */
1235         if(v1!=ov1 || v2!=ov2) {
1236                 remove_verse_edge(vnode, ov1, ov2);
1237                 add_verse_edge(vnode, v1, v2);
1238         }
1239
1240         /* 3rd edge */
1241         if(v2!=ov2 || v3!=ov3 || v0!=ov0) {
1242                 if(ov3!=-1) {
1243                         remove_verse_edge(vnode, ov2, ov3);
1244                         if(v3!=-1) {
1245                                 add_verse_edge(vnode, v2, v3);          /* new 3rd edge (quat->quat) */
1246                         }
1247                         else {
1248                                 remove_verse_edge(vnode, ov3, ov0);     /* old edge v3,v0 of quat have to be removed */
1249                                 add_verse_edge(vnode, v2, v0);          /* new 3rd edge (quat->triangle) */     
1250                         }
1251                 }
1252                 else {
1253                         remove_verse_edge(vnode, ov2, ov0);
1254                         if(v3!=-1) {
1255                                 add_verse_edge(vnode, v2, v3);          /* new 3rd edge (triangle->quat) */
1256                         }
1257                         else {
1258                                 add_verse_edge(vnode, v2, v0);          /* new 3rd edge (triangle->triangle) */
1259                         }
1260                 }
1261         }
1262
1263         /* 4th edge */
1264         if(v3!=-1 && (v3!=ov3 || v0!=ov0)) {
1265                 remove_verse_edge(vnode, ov3, ov0);
1266                 add_verse_edge(vnode, v3, v0);
1267         }
1268 }
1269
1270 /*
1271  * new verse face was created ... update list of edges and edge has
1272  */
1273 static void update_edgehash_of_new_verseface(
1274                 VNode *vnode,
1275                 uint32 v0,
1276                 uint32 v1,
1277                 uint32 v2,
1278                 uint32 v3)
1279 {
1280         /* when edge already exists, then only its counter is incremented,
1281          * look at commentary of add_verse_edge() function */
1282         add_verse_edge(vnode, v0, v1);
1283         add_verse_edge(vnode, v1, v2);
1284         if(v3!=-1) {
1285                 add_verse_edge(vnode, v2, v3);
1286                 add_verse_edge(vnode, v3, v0);
1287         }
1288         else {
1289                 add_verse_edge(vnode, v2, v0);
1290         }
1291 }
1292
1293 /*
1294  * callback function: edge crease was set
1295  */
1296 static void cb_g_crease_set_edge(
1297                 void *user_data,
1298                 VNodeID node_id,
1299                 const char *layer,
1300                 uint32 def_crease)
1301 {
1302 }
1303
1304 /*
1305  * callback function: float value for polygon was set up
1306  */
1307 static void cb_g_polygon_set_face_real32(
1308                 void *user_def,
1309                 VNodeID node_id,
1310                 VLayerID layer_id,
1311                 uint32 polygon_id,
1312                 real32 value)
1313 {
1314         struct VerseSession *session = (VerseSession*)current_verse_session();
1315         struct VNode *vnode;
1316         struct VLayer *vlayer;
1317         struct real32_item *item;
1318
1319         if(!session) return;
1320
1321         /* find needed node (we can be sure, that it is geometry node) */
1322         vnode = (VNode*)BLI_dlist_find_link(&(session->nodes), (unsigned int)node_id);
1323
1324         /* find layer containing uint_8 data */
1325         vlayer = (VLayer*)BLI_dlist_find_link(&(((VGeomData*)vnode->data)->layers), (unsigned int)layer_id);
1326
1327         /* try to find item*/
1328         item = BLI_dlist_find_link(&(vlayer->dl), polygon_id);
1329
1330         if(item) {
1331                 item->value = value;
1332         }
1333         else {
1334                 item = create_real32_item(vlayer, polygon_id, value);
1335                 BLI_dlist_add_item_index(&(vlayer->dl), item, item->id);
1336         }
1337 }
1338
1339 /*
1340  * callback function: int values for polygon was set up
1341  */
1342 static void cb_g_polygon_set_face_uint32(
1343                 void *user_def,
1344                 VNodeID node_id,
1345                 VLayerID layer_id,
1346                 uint32 polygon_id,
1347                 uint32 value)
1348 {
1349         struct VerseSession *session = (VerseSession*)current_verse_session();
1350         struct VNode *vnode;
1351         struct VLayer *vlayer;
1352         struct uint32_item *item;
1353
1354         if(!session) return;
1355
1356         /* find needed node (we can be sure, that it is geometry node) */
1357         vnode = (VNode*)BLI_dlist_find_link(&(session->nodes), (unsigned int)node_id);
1358
1359         /* find layer containing uint_8 data */
1360         vlayer = (VLayer*)BLI_dlist_find_link(&(((VGeomData*)vnode->data)->layers), (unsigned int)layer_id);
1361
1362         /* try to find item*/
1363         item = BLI_dlist_find_link(&(vlayer->dl), polygon_id);
1364
1365         if(item) {
1366                 item->value = value;
1367         }
1368         else {
1369                 item = create_uint32_item(vlayer, polygon_id, value);
1370                 BLI_dlist_add_item_index(&(vlayer->dl), item, item->id);
1371         }
1372 }
1373
1374 /*
1375  * callback function: uint8 value for polygon was set up
1376  */
1377 static void cb_g_polygon_set_face_uint8(
1378                 void *user_def,
1379                 VNodeID node_id,
1380                 VLayerID layer_id,
1381                 uint32 polygon_id,
1382                 uint8 value)
1383 {
1384         struct VerseSession *session = (VerseSession*)current_verse_session();
1385         struct VNode *vnode;
1386         struct VLayer *vlayer;
1387         struct uint8_item *item;
1388
1389         if(!session) return;
1390
1391         /* find needed node (we can be sure, that it is geometry node) */
1392         vnode = (VNode*)BLI_dlist_find_link(&(session->nodes), (unsigned int)node_id);
1393
1394         /* find layer containing uint_8 data */
1395         vlayer = (VLayer*)BLI_dlist_find_link(&(((VGeomData*)vnode->data)->layers), (unsigned int)layer_id);
1396
1397         /* try to find item*/
1398         item = BLI_dlist_find_link(&(vlayer->dl), polygon_id);
1399
1400         if(item) {
1401                 item->value = value;
1402         }
1403         else {
1404                 item = create_uint8_item(vlayer, polygon_id, value);
1405                 BLI_dlist_add_item_index(&(vlayer->dl), item, item->id);
1406         }
1407 }
1408
1409 /*
1410  * callback function: float value for polygon corner was set up
1411  */
1412 static void cb_g_polygon_set_corner_real32(
1413                 void *user_def,
1414                 VNodeID node_id,
1415                 VLayerID layer_id,
1416                 uint32 polygon_id,
1417                 real32 v0,
1418                 real32 v1,
1419                 real32 v2,
1420                 real32 v3)
1421 {
1422         struct VerseSession *session = (VerseSession*)current_verse_session();
1423         struct VNode *vnode;
1424         struct VLayer *vlayer;
1425         struct quat_real32_item *item;
1426
1427         if(!session) return;
1428
1429         /* find needed node (we can be sure, that it is geometry node) */
1430         vnode = (VNode*)BLI_dlist_find_link(&(session->nodes), (unsigned int)node_id);
1431
1432         /* find layer containing uint_8 data */
1433         vlayer = (VLayer*)BLI_dlist_find_link(&(((VGeomData*)vnode->data)->layers), (unsigned int)layer_id);
1434
1435         /* try to find item*/
1436         item = BLI_dlist_find_link(&(vlayer->dl), polygon_id);
1437
1438         if(item) {
1439                 item->value[0] = v0;
1440                 item->value[1] = v1;
1441                 item->value[2] = v2;
1442                 item->value[3] = v3;
1443         }
1444         else {
1445                 item = create_quat_real32_item(vlayer, polygon_id, v0, v1, v2, v3);
1446                 BLI_dlist_add_item_index(&(vlayer->dl), item, item->id);
1447         }
1448 }
1449
1450 /*
1451  * callback function: polygon is deleted
1452  */
1453 static void cb_g_polygon_delete(
1454                 void *user_data,
1455                 VNodeID node_id,
1456                 uint32 polygon_id)
1457 {
1458         struct VerseSession *session = (VerseSession*)current_verse_session();
1459         VNode *vnode;
1460         VLayer *vlayer;
1461         VerseFace *vface;
1462
1463         if(!session) return;
1464
1465         /* find needed node (we can be sure, that it is geometry node) */
1466         vnode = BLI_dlist_find_link(&(session->nodes), node_id);
1467
1468         /* find layer containing faces */
1469         vlayer = find_verse_layer_type((VGeomData*)vnode->data, POLYGON_LAYER);
1470
1471         /* find wanted VerseFace */
1472         vface = BLI_dlist_find_link(&(vlayer->dl), polygon_id);
1473
1474         if(!vface) return;
1475
1476         /* update edge hash */
1477         update_edgehash_of_deleted_verseface(vnode, vface);
1478         
1479         ((VGeomData*)vnode->data)->post_polygon_delete(vface);
1480
1481         /* decrease references at coresponding VerseVertexes */
1482         vface->vvert0->counter--;
1483         vface->vvert1->counter--;
1484         vface->vvert2->counter--;
1485         if(vface->vvert3) vface->vvert3->counter--;
1486
1487         /* delete unneeded VerseVertexes */
1488         free_unneeded_verseverts_of_verseface(vnode, vface);
1489         
1490         free_verse_face(vlayer, vface);
1491 }
1492
1493 /*
1494  * callback function: new polygon (face) created or existing polygon was changed
1495  */
1496 static void cb_g_polygon_set_corner_uint32(
1497                 void *user_data,
1498                 VNodeID node_id,
1499                 VLayerID layer_id,
1500                 uint32 polygon_id,
1501                 uint32 v0,
1502                 uint32 v1,
1503                 uint32 v2,
1504                 uint32 v3)
1505 {
1506         struct VerseSession *session = (VerseSession*)current_verse_session();
1507         struct VNode *vnode;
1508         struct VLayer *vlayer;
1509         struct VerseFace *vface=NULL;
1510
1511         if(!session) return;
1512
1513         /* try to find VerseNode */
1514         vnode = (VNode*)BLI_dlist_find_link(&(session->nodes), (unsigned int)node_id);
1515         if(!vnode) return;
1516
1517         /* try to find VerseLayer */
1518         vlayer = (VLayer*)BLI_dlist_find_link(&(((VGeomData*)vnode->data)->layers), (unsigned int)layer_id);
1519         if(!vlayer) return;
1520
1521         /* we have to test coretness of incoming data */
1522         if(!test_polygon_set_corner_uint32(v0, v1, v2, v3)) return;
1523         
1524         /* Blender uses different order of vertexes */
1525         if(v3!=-1) { /* quat swap */
1526                 unsigned int v; v = v1; v1 = v3; v3 = v;
1527         }
1528         else { /* triangle swap */
1529                 unsigned int v; v = v1; v1 = v2; v2 = v;
1530         }
1531
1532         /* try to find VerseFace */
1533         vface = (VerseFace*)BLI_dlist_find_link(&(vlayer->dl), (unsigned int)polygon_id);
1534
1535         /* try to find modified VerseFace */
1536         if(!vface) {
1537                 vface = find_changed_verse_face_in_queue(vlayer, polygon_id);
1538                 if(vface) {
1539                         BLI_remlink(&(vlayer->queue), (void*)vface);
1540                         BLI_dlist_add_item_index(&(vlayer->dl), (void*)vface, (unsigned int)polygon_id);
1541                 }
1542         }
1543
1544         if(!vface) {
1545                 /* try to find VerseFace in list of VerseVaces created by me and set up polygon and
1546                  * layer ids */
1547                 vface = find_verse_face_in_queue(vlayer, node_id, polygon_id, v0, v1, v2, v3);
1548                 
1549                 /* update edge hash */
1550                 update_edgehash_of_new_verseface(vnode, v0, v1, v2, v3);
1551                 
1552                 if(vface){
1553                         /* I creeated this face ... remove VerseFace from queue */
1554                         BLI_remlink(&(vlayer->queue), (void*)vface);
1555                 }
1556                 else {
1557                         /* some other client created this face*/
1558                         vface = create_verse_face(vlayer, polygon_id, v0, v1, v2, v3);
1559                 }
1560
1561                 vface->flag &= ~FACE_SENT;
1562
1563                 /* return number of missing verse vertexes */
1564                 vface->counter = test_incoming_verseface((VGeomData*)vnode->data, vface);
1565
1566                 if(vface->counter < 1) {
1567                         /* when VerseFace received all needed VerseFaces, then it is moved
1568                          * to list of VerseFaces */
1569                         BLI_dlist_add_item_index(&(vlayer->dl), (void*)vface, (unsigned int)polygon_id);
1570                         increase_verse_verts_references(vface);
1571                         recalculate_verseface_normals(vnode);
1572                         ((VGeomData*)vnode->data)->post_polygon_create(vface);
1573                 }
1574                 else {
1575                         /* when all needed VerseVertexes weren't received, then VerseFace is moved to
1576                          * the list of orphans waiting on needed vertexes */
1577                         vface->flag |= FACE_RECEIVED;
1578                         BLI_addtail(&(vlayer->orphans), (void*)vface);
1579                 }
1580         }
1581         else {
1582                 VLayer *vert_vlayer = find_verse_layer_type((VGeomData*)vnode->data, VERTEX_LAYER);
1583                 /* VerseVertexes of existing VerseFace were changed (VerseFace will use some different
1584                  * VerseVertexes or it will use them in different order) */
1585
1586                 /* update fake verse edges */
1587                 update_edgehash_of_changed_verseface(vnode, vface, v0, v1, v2, v3);
1588                 
1589                 /* initialize count of unreceived vertexes needed for this face */
1590                 vface->counter = 4;
1591
1592                 /* 1st corner */
1593                 if(vface->vvert0->id != v0) {
1594                         /* decrease references of obsolete vertexes*/
1595                         vface->vvert0->counter--;
1596                         /* delete this vertex, when it isn't used by any face and it was marked as deleted */
1597                         if((vface->vvert0->counter < 1) && (vface->vvert0->flag & VERT_DELETED)) {
1598                                 ((VGeomData*)vnode->data)->post_vertex_delete(vface->vvert0);
1599                                 free_verse_vertex(vert_vlayer, vface->vvert0);
1600                         }
1601                         /* try to set up new pointer at verse vertex */
1602                         vface->v0 = v0;
1603                         vface->vvert0 = BLI_dlist_find_link(&(vert_vlayer->dl), vface->v0);
1604                         if(vface->vvert0) {
1605                                 /* increase references at new vertex */
1606                                 vface->vvert0->counter++;
1607                                 /* decrease count of needed vertex to receive */
1608                                 vface->counter--;
1609                         }
1610                         
1611                 }
1612                 else
1613                         /* this corner wasn't changed */
1614                         vface->counter--;
1615
1616                 /* 2nd corner */
1617                 if(vface->vvert1->id != v1) {
1618                         vface->vvert1->counter--;
1619                         if((vface->vvert1->counter < 1) && (vface->vvert1->flag & VERT_DELETED)) {
1620                                 ((VGeomData*)vnode->data)->post_vertex_delete(vface->vvert1);
1621                                 free_verse_vertex(vert_vlayer, vface->vvert1);
1622                         }
1623                         vface->v1 = v1;
1624                         vface->vvert1 = BLI_dlist_find_link(&(vert_vlayer->dl), vface->v1);
1625                         if(vface->vvert1) {
1626                                 vface->vvert1->counter++;
1627                                 vface->counter--;
1628                         }
1629                 }
1630                 else
1631                         vface->counter--;
1632
1633                 /* 3rd corner */
1634                 if(vface->vvert2->id != v2) {
1635                         vface->vvert2->counter--;
1636                         if((vface->vvert2->counter < 1) && (vface->vvert2->flag & VERT_DELETED)) {
1637                                 ((VGeomData*)vnode->data)->post_vertex_delete(vface->vvert2);
1638                                 free_verse_vertex(vert_vlayer, vface->vvert2);
1639                         }
1640                         vface->v2 = v2;
1641                         vface->vvert2 = BLI_dlist_find_link(&(vert_vlayer->dl), vface->v2);
1642                         if(vface->vvert2) {
1643                                 vface->vvert2->counter++;
1644                                 vface->counter--;
1645                         }
1646                 }
1647                 else
1648                         vface->counter--;
1649         
1650                 /* 4th corner */        
1651                 if(vface->vvert3) {
1652                         if(vface->vvert3->id != v3) {
1653                                 vface->vvert3->counter--;
1654                                 if((vface->vvert3->counter < 1) && (vface->vvert3->flag & VERT_DELETED)) {
1655                                         ((VGeomData*)vnode->data)->post_vertex_delete(vface->vvert3);
1656                                         free_verse_vertex(vert_vlayer, vface->vvert3);
1657                                 }
1658                                 vface->v3 = v3;
1659                                 if(v3 != -1) {
1660                                         vface->vvert3 = BLI_dlist_find_link(&(vert_vlayer->dl), vface->v3);
1661                                         if(vface->vvert3) {
1662                                                 vface->vvert3->counter++;
1663                                                 vface->counter--;
1664                                         }
1665                                 }
1666                                 else {
1667                                         /* this is some special case, this face hase now only 3 corners
1668                                          * quat -> triangle */
1669                                         vface->vvert3 = NULL;
1670                                         vface->counter--;
1671                                 }
1672                         }
1673                 }
1674                 else if(v3 != -1)
1675                         /* this is some special case, 4th corner of this polygon was created
1676                          * triangle -> quat */
1677                         vface->v3 = v3;
1678                         vface->vvert3 = BLI_dlist_find_link(&(vert_vlayer->dl), vface->v3);
1679                         if(vface->vvert3) {
1680                                 vface->vvert3->counter++;
1681                                 vface->counter--;
1682                         }
1683                 else {
1684                         vface->v3 = -1;
1685                         vface->counter--;
1686                 }
1687                 
1688                 vface->flag &= ~FACE_SENT;
1689                 vface->flag |= FACE_CHANGED;
1690
1691                 if(vface->counter<1) {
1692                         vface->flag &= ~FACE_CHANGED;
1693                         recalculate_verseface_normals(vnode);
1694                         ((VGeomData*)vnode->data)->post_polygon_set_corner(vface);
1695                 }
1696                 else {
1697                         /* when all needed VerseVertexes weren't received, then VerseFace is added to
1698                          * the list of orphans waiting on needed vertexes */
1699                         BLI_dlist_rem_item(&(vlayer->dl), vface->id);
1700                         BLI_addtail(&(vlayer->orphans), (void*)vface);
1701                 }
1702         }
1703 }
1704
1705 /*
1706  * callback function: float value was set up for VerseVert with vertex_id
1707  */
1708 static void cb_g_vertex_set_real32(
1709                 void *user_def,
1710                 VNodeID node_id,
1711                 VLayerID layer_id,
1712                 uint32 vertex_id,
1713                 real32 value)
1714 {
1715         struct VerseSession *session = (VerseSession*)current_verse_session();
1716         struct VNode *vnode;
1717         struct VLayer *vlayer;
1718         struct real32_item *item;
1719
1720         if(!session) return;
1721
1722         /* find needed node (we can be sure, that it is geometry node) */
1723         vnode = (VNode*)BLI_dlist_find_link(&(session->nodes), (unsigned int)node_id);
1724
1725         /* find layer containing uint_8 data */
1726         vlayer = (VLayer*)BLI_dlist_find_link(&(((VGeomData*)vnode->data)->layers), (unsigned int)layer_id);
1727
1728         /* try to find item*/
1729         item = BLI_dlist_find_link(&(vlayer->dl), vertex_id);
1730
1731         if(item) {
1732                 item->value = value;
1733         }
1734         else {
1735                 item = create_real32_item(vlayer, vertex_id, value);
1736                 BLI_dlist_add_item_index(&(vlayer->dl), item, item->id);
1737         }
1738 }
1739
1740 /*
1741  * callback function: int value was set up for VerseVert with vertex_id
1742  */
1743 static void cb_g_vertex_set_uint32(
1744                 void *user_def,
1745                 VNodeID node_id,
1746                 VLayerID layer_id,
1747                 uint32 vertex_id,
1748                 uint32 value)
1749 {
1750         struct VerseSession *session = (VerseSession*)current_verse_session();
1751         struct VNode *vnode;
1752         struct VLayer *vlayer;
1753         struct uint32_item *item;
1754
1755         if(!session) return;
1756
1757         /* find needed node (we can be sure, that it is geometry node) */
1758         vnode = (VNode*)BLI_dlist_find_link(&(session->nodes), (unsigned int)node_id);
1759
1760         /* find layer containing uint_8 data */
1761         vlayer = (VLayer*)BLI_dlist_find_link(&(((VGeomData*)vnode->data)->layers), (unsigned int)layer_id);
1762
1763         /* try to find item*/
1764         item = BLI_dlist_find_link(&(vlayer->dl), vertex_id);
1765
1766         if(item) {
1767                 item->value = value;
1768         }
1769         else {
1770                 item = create_uint32_item(vlayer, vertex_id, value);
1771                 BLI_dlist_add_item_index(&(vlayer->dl), item, item->id);
1772         }
1773 }
1774
1775 /*
1776  * callback function: polygon was deleted
1777  */
1778 static void cb_g_vertex_delete_real32(
1779                 void *user_data,
1780                 VNodeID node_id,
1781                 uint32 vertex_id)
1782 {
1783         struct VerseSession *session = (VerseSession*)current_verse_session();
1784         VNode *vnode=NULL;
1785         VLayer *vert_vlayer=NULL;
1786         VerseVert *vvert=NULL;
1787
1788         if(!session) return;
1789
1790         vnode = BLI_dlist_find_link(&(session->nodes), (unsigned int)node_id);
1791
1792         vert_vlayer = find_verse_layer_type((VGeomData*)vnode->data, VERTEX_LAYER);
1793
1794         vvert = BLI_dlist_find_link(&(vert_vlayer->dl), (unsigned int)vertex_id);
1795
1796         if(!vvert) return;
1797
1798         if(vvert->counter < 1) {
1799                 ((VGeomData*)vnode->data)->post_vertex_delete(vvert);
1800                 BLI_dlist_free_item(&(vert_vlayer->dl), (unsigned int)vertex_id);
1801         }
1802         else {
1803                 /* some VerseFace(s) still need VerseVert, remove verse vert from
1804                  * list verse vertexes and put it to list of orphans */
1805                 vvert->flag |= VERT_DELETED;
1806                 BLI_dlist_rem_item(&(vert_vlayer->dl), (unsigned int)vertex_id);
1807                 BLI_addtail(&(vert_vlayer->orphans), vvert);
1808         }
1809 }
1810
1811 /*
1812  * callback function: position of one vertex was changed or new vertex was created
1813  */
1814 static void cb_g_vertex_set_xyz_real32(
1815                 void *user_data,
1816                 VNodeID node_id,
1817                 VLayerID layer_id,
1818                 uint32 vertex_id,
1819                 real32 x,
1820                 real32 y,
1821                 real32 z)
1822 {
1823         struct VerseSession *session = (VerseSession*)current_verse_session();
1824         struct VNode *vnode = NULL;
1825         struct VLayer *vlayer = NULL;
1826         struct VerseVert *vvert = NULL;
1827         real32 tmp;
1828
1829         if(!session) return;
1830
1831         vnode = (VNode*)BLI_dlist_find_link(&(session->nodes), (unsigned int)node_id);
1832         if(!vnode)return;
1833
1834         vlayer = (VLayer*)BLI_dlist_find_link(&(((VGeomData*)vnode->data)->layers), (unsigned int)layer_id);
1835         if(!vlayer) return;
1836
1837         /* switch axis orientation */
1838         tmp = y;
1839         y = -z;
1840         z = tmp;
1841         
1842         if(vlayer->id == 0) {
1843                 /* try to pick up verse vert from DynamicList */
1844                 vvert = (VerseVert*)BLI_dlist_find_link(&(vlayer->dl), (unsigned int)vertex_id);
1845
1846                 if(vvert) {
1847                         if(vvert->flag & VERT_OBSOLETE) return;
1848
1849                         if (vvert->flag & VERT_LOCKED) {
1850                                 /* this application changed position of this vertex */
1851                                 if((vvert->co[0]==x) && (vvert->co[1]==y) && (vvert->co[2]==z)) {
1852                                         /* unlock vertex position */
1853                                         vvert->flag &= ~VERT_LOCKED;
1854                                         /* call post_vertex_set_xyz only, when position of vertex is
1855                                          * obsolete ... the new vertex position will be sent to
1856                                          * verse server */
1857                                         if (vvert->flag & VERT_POS_OBSOLETE) {
1858                                                 ((VGeomData*)vnode->data)->post_vertex_set_xyz(vvert);
1859                                         }
1860                                 }
1861                         }
1862                         else {
1863                                 /* somebody else changed position of this vertex*/
1864                                 if((vvert->co[0]!=x) || (vvert->co[1]!=y) || (vvert->co[2]!=z)) {
1865                                         vvert->co[0] = x;
1866                                         vvert->co[1] = y;
1867                                         vvert->co[2] = z;
1868                                         recalculate_verseface_normals(vnode);
1869                                         ((VGeomData*)vnode->data)->post_vertex_set_xyz(vvert);
1870                                 }
1871                         }
1872                 }
1873                 else {
1874                         /* create new verse vert */
1875
1876                         /* test if we are authors of this vertex :-) */
1877                         vvert = find_verse_vert_in_queue(vlayer, node_id, vertex_id, x, y, z);
1878
1879                         if(vvert) {
1880                                 /* remove vert from queue */
1881                                 BLI_remlink(&(vlayer->queue), (void*)vvert);
1882                                 /* add vvert to the dynamic list */
1883                                 BLI_dlist_add_item_index(&(vlayer->dl), (void*)vvert, (unsigned int)vertex_id);
1884                                 /* set VerseVert flags */
1885                                 vvert->flag |= VERT_RECEIVED;
1886                                 if(!(vvert->flag & VERT_POS_OBSOLETE))
1887                                         vvert->flag &= ~VERT_LOCKED;
1888                                 /* find VerseFaces orphans */
1889                                 find_vlayer_orphans(vnode, vvert);
1890                                 /* find unsent VerseFaces */
1891                                 find_unsent_faces(vnode, vvert);
1892                         }
1893                         else {
1894                                 /* create new VerseVert */
1895                                 vvert = create_verse_vertex(vlayer, vertex_id, x, y, z);
1896                                 /* add VerseVert to list of VerseVerts */
1897                                 BLI_dlist_add_item_index(&(vlayer->dl), (void*)vvert, (unsigned int)vertex_id);
1898                                 /* set VerseVert flags */
1899                                 vvert->flag |= VERT_RECEIVED;
1900                                 /* find VerseFaces orphans */
1901                                 find_vlayer_orphans(vnode, vvert);
1902                         }
1903
1904                         ((VGeomData*)vnode->data)->post_vertex_create(vvert);
1905                 }
1906         }
1907 }
1908
1909 /*
1910  * callback function for destroyng of verse layer
1911  */
1912 static void cb_g_layer_destroy(
1913                 void *user_data,
1914                 VNodeID node_id,
1915                 VLayerID layer_id)
1916 {
1917         struct VerseSession *session = (VerseSession*)current_verse_session();
1918         struct VNode *vnode;
1919         struct VLayer *vlayer;
1920
1921         if(!session) return;
1922
1923         vnode = (VNode*)BLI_dlist_find_link(&(session->nodes), node_id);
1924         if(!vnode) return;
1925
1926         vlayer = (VLayer*) BLI_dlist_find_link(&(((VGeomData*)vnode->data)->layers), layer_id);
1927
1928         if(vlayer){
1929                 /* free VerseLayer data */
1930                 free_verse_layer_data(vnode, vlayer);
1931                 /* remove VerseLayer from list of verse layers */
1932                 BLI_dlist_rem_item(&(((VGeomData*)vnode->data)->layers), layer_id);
1933                 /* do client dependent actions */
1934                 vlayer->post_layer_destroy(vlayer);
1935                 /* free vlayer itself */
1936                 MEM_freeN(vlayer);
1937         }
1938
1939 }
1940
1941 /*
1942  * callback function: new layer was created
1943  */
1944 static void cb_g_layer_create(
1945                 void *user_data,
1946                 VNodeID node_id,
1947                 VLayerID layer_id,
1948                 const char *name,
1949                 VNGLayerType type,
1950                 uint32 def_integer,
1951                 real64 def_real)
1952 {
1953         struct VerseSession *session = (VerseSession*)current_verse_session();
1954         struct VNode *vnode=NULL;
1955         struct VLayer *vlayer=NULL;
1956
1957         if(!session) return;
1958
1959         /* find node of this layer*/
1960         vnode = BLI_dlist_find_link(&(session->nodes), node_id);
1961         if(!vnode) return;
1962
1963         /* when we created this layer, then subscribe to this layer */
1964         if(vnode->owner_id == VN_OWNER_MINE || session->flag & VERSE_AUTOSUBSCRIBE)
1965                 verse_send_g_layer_subscribe(node_id, layer_id, 0);
1966
1967         /* try to find */
1968         if(vnode->owner_id == VN_OWNER_MINE)
1969                 vlayer = find_vlayer_in_sending_queue(vnode, layer_id);
1970
1971         if(vlayer) {
1972                 /* remove vlayer form sending queue add verse layer to list of verse layers */
1973                 BLI_remlink(&((VGeomData*)vnode->data)->queue, vlayer);
1974                 BLI_dlist_add_item_index(&((VGeomData*)vnode->data)->layers, (void*)vlayer, (unsigned int)vlayer->id);
1975                 /* send all not sent vertexes to verse server
1976                  * other items waiting in sending queue will be automaticaly sent to verse server,
1977                  * when verse vertexes will be received from verse server */
1978                 if((vlayer->type == VN_G_LAYER_VERTEX_XYZ) && (layer_id==0)) {
1979                         struct VerseVert *vvert = (VerseVert*)vlayer->queue.first;
1980                         while(vvert) {
1981                                 send_verse_vertex(vvert);
1982                                 vvert = vvert->next;
1983                         }
1984                 }
1985         }
1986         else {
1987                 /* create new VerseLayer */
1988                 vlayer = create_verse_layer(vnode, layer_id, name, type, def_integer, def_real);
1989                 /* add layer to the list of VerseLayers */
1990                 BLI_dlist_add_item_index(&(((VGeomData*)vnode->data)->layers), (void*)vlayer, (unsigned int)layer_id);
1991         }
1992
1993         vlayer->flag |= LAYER_RECEIVED;
1994
1995         /* post callback function */
1996         vlayer->post_layer_create(vlayer);
1997 }
1998
1999 /*
2000  * this function will send destroy commands for all VerseVertexes and
2001  * VerseFaces to verse server, but it will not send destroy commands
2002  * for VerseLayers or geometry node, it can be used in other functions
2003  * (undo, destroy geom node, some edit mesh commands, ... ), parameter of
2004  * this function has to be geometry verse node
2005  */
2006 void destroy_geometry(VNode *vnode)
2007 {
2008         struct VLayer *vert_vlayer, *face_vlayer;
2009         struct VerseFace *vface;
2010         struct VerseVert *vvert;
2011
2012         if(vnode->type != V_NT_GEOMETRY) return;
2013
2014         face_vlayer = find_verse_layer_type((VGeomData*)vnode->data, POLYGON_LAYER);
2015         vface = face_vlayer->dl.lb.first;
2016
2017         while(vface) {
2018                 send_verse_face_delete(vface);
2019                 vface = vface->next;
2020         }
2021
2022         vert_vlayer = find_verse_layer_type((VGeomData*)vnode->data, VERTEX_LAYER);
2023         vvert = vert_vlayer->dl.lb.first;
2024
2025         while(vvert) {
2026                 send_verse_vertex_delete(vvert);
2027                 vvert = vvert->next;
2028         }
2029
2030         /* own destruction of local verse date will be executed, when client will
2031          * receive apropriate callback commands from verse server */
2032 }
2033
2034 /*
2035  * free VGeomData
2036  */
2037 void free_geom_data(VNode *vnode)
2038 {
2039         struct VerseSession *session = vnode->session;
2040         struct VLayer *vlayer;
2041
2042         if(vnode->data){
2043                 vlayer = (VLayer*)((VGeomData*)vnode->data)->layers.lb.first;
2044                 while(vlayer){
2045                         /* unsubscribe from layer */
2046                         if(session->flag & VERSE_CONNECTED)
2047                                 verse_send_g_layer_unsubscribe(vnode->id, vlayer->id);
2048                         /* free VerseLayer data */
2049                         free_verse_layer_data(vnode, vlayer);
2050                         /* next layer */
2051                         vlayer = vlayer->next;
2052                 }
2053                 /* free constraint between vnode and mesh */
2054                 ((VGeomData*)vnode->data)->post_geometry_free_constraint(vnode);
2055                 /* free all VerseLayers */
2056                 BLI_dlist_destroy(&(((VGeomData*)vnode->data)->layers));
2057                 /* free fake verse edges */
2058                 BLI_freelistN(&((VGeomData*)vnode->data)->edges);
2059                 /* free edge hash */
2060                 MEM_freeN(((VGeomData*)vnode->data)->hash);
2061         }
2062 }
2063
2064 void set_geometry_callbacks(void)
2065 {
2066         /* new layer created */
2067         verse_callback_set(verse_send_g_layer_create, cb_g_layer_create, NULL);
2068         /* layer was destroyed */
2069         verse_callback_set(verse_send_g_layer_destroy, cb_g_layer_destroy, NULL);
2070
2071         /* position of vertex was changed */
2072         verse_callback_set(verse_send_g_vertex_set_xyz_real32, cb_g_vertex_set_xyz_real32, NULL);
2073         /* vertex was deleted */
2074         verse_callback_set(verse_send_g_vertex_delete_real32, cb_g_vertex_delete_real32, NULL);
2075
2076         /* callback functions for values being associated with vertexes */
2077         verse_callback_set(verse_send_g_vertex_set_uint32, cb_g_vertex_set_uint32, NULL);
2078         verse_callback_set(verse_send_g_vertex_set_real32, cb_g_vertex_set_real32, NULL);
2079
2080         /* new polygon was created / vertex(es) of polygon was set */
2081         verse_callback_set(verse_send_g_polygon_set_corner_uint32, cb_g_polygon_set_corner_uint32, NULL);
2082         /* polygon was deleted */
2083         verse_callback_set(verse_send_g_polygon_delete, cb_g_polygon_delete, NULL);
2084
2085         /* callback functions for values being associated with polygon corners */
2086         verse_callback_set(verse_send_g_polygon_set_corner_real32, cb_g_polygon_set_corner_real32, NULL);
2087         /* callback functions for values being associated with faces */
2088         verse_callback_set(verse_send_g_polygon_set_face_uint8, cb_g_polygon_set_face_uint8, NULL);
2089         verse_callback_set(verse_send_g_polygon_set_face_uint32, cb_g_polygon_set_face_uint32, NULL);
2090         verse_callback_set(verse_send_g_polygon_set_face_real32, cb_g_polygon_set_face_real32, NULL);
2091
2092         /* crease of vertex was set */
2093         verse_callback_set(verse_send_g_crease_set_vertex, cb_g_crease_set_vertex, NULL);
2094         /* crease of edge was set */
2095         verse_callback_set(verse_send_g_crease_set_edge, cb_g_crease_set_edge, NULL);
2096 }
2097
2098 #endif