diff options
Diffstat (limited to 'source/blender/src/verse_mesh.c')
-rw-r--r-- | source/blender/src/verse_mesh.c | 1626 |
1 files changed, 0 insertions, 1626 deletions
diff --git a/source/blender/src/verse_mesh.c b/source/blender/src/verse_mesh.c deleted file mode 100644 index f2769c0d7e6..00000000000 --- a/source/blender/src/verse_mesh.c +++ /dev/null @@ -1,1626 +0,0 @@ -/** - * $Id$ - * - * ***** BEGIN GPL LICENSE BLOCK ***** - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - * - * Contributor(s): Jiri Hnidek. - * - * ***** END GPL LICENSE BLOCK ***** - */ - -#ifdef WITH_VERSE - -#include <string.h> - -#include "MEM_guardedalloc.h" - -#include "mydevice.h" - -#include "DNA_object_types.h" -#include "DNA_mesh_types.h" - -#include "BLI_dynamiclist.h" -#include "BLI_blenlib.h" -#include "BLI_edgehash.h" -#include "BLI_editVert.h" - -#include "BKE_customdata.h" -#include "BKE_depsgraph.h" -#include "BKE_global.h" -#include "BKE_mesh.h" -#include "BKE_utildefines.h" -#include "BKE_verse.h" - -#include "BIF_verse.h" -#include "BIF_editmesh.h" -#include "BIF_space.h" -#include "BIF_screen.h" - -#include "BSE_edit.h" - -#include "editmesh.h" - -#include "verse.h" - -/* prototypes of static functions */ - -static void mark_changed_face_obsolete(struct VerseFace *vface); -static void sync_verseface_with_editface(struct VLayer *vlayer, struct VerseFace *vface); - -void createVerseVertNL(struct EditVert *ev, struct VNode *vnode, struct VLayer *vlayer); -static void createAllVerseVerts(struct VNode *vnode, struct VLayer *vlayer); -void createVerseFaceNL(struct EditFace *efa, struct VNode *vnode, struct VLayer *vlayer); -static void createAllVerseFaces(struct VNode *vnode, struct VLayer *vlayer); - -/*============================================================================= - * - * functions handling verse/blender FACES - * - *===========================================================================*/ - -/* - * create new VerseFace (polygon), due to information about EditFace - * put VerseFace to queue ... send to verse host (server) - */ -void createVerseFace(EditFace *efa) -{ - if(G.editMesh->vnode) { - struct VLayer *vlayer = find_verse_layer_type((VGeomData*)((VNode*)G.editMesh->vnode)->data, POLYGON_LAYER); - createVerseFaceNL(efa, (VNode*)G.editMesh->vnode, vlayer); - } - else efa->vface = NULL; -} - -/* - * create new VerseFace (polygon), due to information about EditFace - * put VerseFace to queue ... send to verse host (server) - * NL version of function (infomration about verse node and - * layer is known ... optimalisation) - */ -void createVerseFaceNL(EditFace *efa, VNode *vnode, VLayer *vlayer) -{ - struct VerseFace *vface; - - vface = (VerseFace*)create_verse_face(vlayer, vlayer->counter, -1, -1, -1, -1); - - vface->face = (void*)efa; - efa->vface = (void*)vface; - - vface->flag |= FACE_SEND_READY; - - /* EditVert #1 */ - if(efa->v1) { - if(efa->v1->vvert) { - vface->vvert0 = (VerseVert*)efa->v1->vvert; - if(((VerseVert*)efa->v1->vvert)->flag & VERT_RECEIVED) { - vface->v0 = ((VerseVert*)efa->v1->vvert)->id; - vface->counter--; - } - else - vface->flag &= ~FACE_SEND_READY; - } - } - else - vface->counter--; - - /* EditVert #2 */ - if(efa->v2) { - if(efa->v2->vvert) { - vface->vvert1 = (VerseVert*)efa->v2->vvert; - if(((VerseVert*)efa->v2->vvert)->flag & VERT_RECEIVED) { - vface->v1 = ((VerseVert*)efa->v2->vvert)->id; - vface->counter--; - } - else - vface->flag &= ~FACE_SEND_READY; - } - } - else - vface->counter--; - /* EditVert #3 */ - if(efa->v3) { - if(efa->v3->vvert) { - vface->vvert2 = (VerseVert*)efa->v3->vvert; - if(((VerseVert*)efa->v3->vvert)->flag & VERT_RECEIVED) { - vface->v2 = ((VerseVert*)efa->v3->vvert)->id; - vface->counter--; - } - else - vface->flag &= ~FACE_SEND_READY; - } - } - else - vface->counter--; - /* EditVert #4 */ - if(efa->v4) { - if(efa->v4->vvert) { - vface->vvert3 = (VerseVert*)efa->v4->vvert; - if(((VerseVert*)efa->v4->vvert)->flag & VERT_RECEIVED) { - vface->v3 = ((VerseVert*)efa->v4->vvert)->id; - vface->counter--; - } - else - vface->flag &= ~FACE_SEND_READY; - } - } - else - vface->counter--; - - add_item_to_send_queue(&(vlayer->queue), (void*)vface, VERSE_FACE); -} - -/* - * creates new verse faces, add all of then to queue ... send to verse server - */ -static void createAllVerseFaces(VNode *vnode, VLayer *vlayer) -{ - if(G.obedit) { - struct EditMesh *em; - struct EditFace *efa; - - em = G.editMesh; - - efa = em->faces.first; - /* push all EditFaces to the verse server */ - while(efa){ - createVerseFaceNL(efa, vnode, vlayer); - efa = efa->next; - } - } -} - -/* - * When verse face is changed during sending/receiving from verse server, then - * this verse face is marked as obsolete and it will be send again, when it - * will be received from verse server - */ -static void mark_changed_face_obsolete(VerseFace *vface) -{ - struct EditFace *efa = (EditFace*)vface->face; - - if(efa) { - if(vface->vvert0->vertex != efa->v1) vface->flag |= FACE_OBSOLETE; - if(vface->vvert1->vertex != efa->v2) vface->flag |= FACE_OBSOLETE; - if(vface->vvert2->vertex != efa->v3) vface->flag |= FACE_OBSOLETE; - if(vface->vvert3 && (vface->vvert3->vertex != efa->v4)) vface->flag |= FACE_OBSOLETE; - } -} - -/* - * this function will sync EditFace and VerseFace and it will send changes to - * verse server too - */ -static void sync_verseface_with_editface(VLayer *vlayer, VerseFace *vface) -{ - struct EditFace *efa = (EditFace*)vface->face; - int dosend = 0; - - /* edit face and probably verse face was deleted */ - if(!efa || (vface->flag & FACE_DELETED)) return; - - /* blender nor verse don't support such crazy things */ - if(!(vface->vvert0) || !(vface->vvert1) || !(vface->vvert2)) { - printf("\tERROR: vface->vvert0: %p, vface->vvert1: %p, vface->vvert2: %p\n", vface->vvert0, vface->vvert1, vface->vvert2); - return; - } - - /* initialize verse face flag */ - vface->flag |= FACE_SEND_READY; - - /* debug print */ -#if 0 - printf("\n"); - if(efa->v4) { - printf("\tefa->v1,v2,v3,v4->vvert->id: %d, %d, %d, %d\n", - ((VerseVert*)efa->v1->vvert)->id, - ((VerseVert*)efa->v2->vvert)->id, - ((VerseVert*)efa->v3->vvert)->id, - ((VerseVert*)efa->v4->vvert)->id); - printf("\tefa->v1,v2,v3,v4->vvert: %p, %p, %p, %p\n", - efa->v1->vvert, - efa->v2->vvert, - efa->v3->vvert, - efa->v4->vvert); - } - else { - printf("\tefa->v1,v2,v3->vvert->id: %d, %d, %d, NULL\n", - ((VerseVert*)efa->v1->vvert)->id, - ((VerseVert*)efa->v2->vvert)->id, - ((VerseVert*)efa->v3->vvert)->id); - printf("\tefa->v1,v2,v3,v4->vvert: %p, %p, %p, NULL\n", - efa->v1->vvert, - efa->v2->vvert, - efa->v3->vvert); - } - printf("\tvface->vvert0, vvvert1, vvvert2, vvvert3: %p, %p, %p, %p\n", - vface->vvert0, - vface->vvert1, - vface->vvert2, - vface->vvert3); - - printf("\tefa->v1, v2, v3, v4: %p, %p, %p, %p\n", - efa->v1, - efa->v2, - efa->v3, - efa->v4); - if(vface->vvert3) { - printf("\tvface->v0,v1,v2,v3: %d, %d, %d, %d\n", - vface->v0, - vface->v1, - vface->v2, - vface->v3); - printf("\tvface->vvert0,vvvert1,vvvert2,vvvert3->vertex: %p, %p, %p, %p\n", - vface->vvert0->vertex, - vface->vvert1->vertex, - vface->vvert2->vertex, - vface->vvert3->vertex); - } - else { - printf("\tvface->v0,v1,v2,v3: %d, %d, %d, NULL\n", - vface->v0, - vface->v1, - vface->v2); - printf("\tvface->vvert0,vvvert1,vvvert2->vertex: %p, %p, %p, NULL\n", - vface->vvert0->vertex, - vface->vvert1->vertex, - vface->vvert2->vertex); - } -#endif - - /* initialize counter of unreceived vertexes */ - vface->counter = 4; - - /* 1st vertex */ - if(vface->vvert0->vertex != efa->v1) { - dosend = 1; - vface->vvert0->counter--; - vface->vvert0 = (VerseVert*)efa->v1->vvert; - vface->v0 = vface->vvert0->id; - if(vface->vvert0->flag & VERT_RECEIVED) - vface->counter--; - else - vface->flag &= ~FACE_SEND_READY; - } - else - vface->counter--; - - /* 2nd vertex */ - if(vface->vvert1->vertex != efa->v2) { - dosend = 1; - vface->vvert1->counter--; - vface->vvert1 = (VerseVert*)efa->v2->vvert; - vface->v1 = vface->vvert1->id; - if(vface->vvert1->flag & VERT_RECEIVED) - vface->counter--; - else - vface->flag &= ~FACE_SEND_READY; - } - else - vface->counter--; - - /* 3th vertex */ - if(vface->vvert2->vertex != efa->v3) { - dosend = 1; - vface->vvert2->counter--; - vface->vvert2 = (VerseVert*)efa->v3->vvert; - vface->v2 = vface->vvert2->id; - if(vface->vvert2->flag & VERT_RECEIVED) - vface->counter--; - else - vface->flag &= ~FACE_SEND_READY; - } - else - vface->counter--; - - /* 4th vertex */ - if(vface->vvert3 && ((vface->vvert3->vertex != efa->v4) || (vface->vvert3 && !efa->v4) || (vface->v3 != vface->vvert3->id))) { - dosend = 1; - if(efa->v4) { - vface->vvert3->counter--; - vface->vvert3 = (VerseVert*)efa->v4->vvert; - vface->v3 = vface->vvert3->id; - if(vface->vvert3->flag & VERT_RECEIVED) - vface->counter--; - else - vface->flag &= ~FACE_SEND_READY; - } - else { - vface->vvert3->counter--; - vface->vvert3 = NULL; - vface->v3 = -1; - vface->counter--; - } - } - /* verse face has 4 vertexes now, not 3 vertexes as in past */ - else if(!(vface->vvert3) && efa->v4) { - dosend = 1; - vface->vvert3 = (VerseVert*)efa->v4->vvert; - vface->v3 = vface->vvert3->id; - if(vface->vvert3->flag & VERT_RECEIVED) - vface->counter--; - else - vface->flag &= ~FACE_SEND_READY; - } - else - vface->counter--; - - if(dosend) { - /* printf("\tsending CHANGED FACE\n"); - printf("\t\tnew: %d %d %d %d\n", vface->v0, vface->v1, vface->v2, vface->v3);*/ - vface->flag |= FACE_CHANGED; - /* remove verse face from list of received faces */ - BLI_dlist_rem_item(&(vlayer->dl), vface->id); - /* and add verse face again to sending queue */ - add_item_to_send_queue(&(vlayer->queue), (void*)vface, VERSE_FACE); - } -} - -/* - * this function will sync all VerseFaces with coresponding EditFaces, - * this is useful, when some editmesh tool has changed editface pointers at - * vertexes (edges), parameter of this function is geometry node - */ -void sync_all_versefaces_with_editfaces(VNode *vnode) -{ - struct VLayer *vlayer; - struct VerseFace *vface, *nvface; - - if(vnode->type != V_NT_GEOMETRY) return; - - vlayer = find_verse_layer_type((VGeomData*)vnode->data, POLYGON_LAYER); - - /* mark changed verse faces in sending queue as obsolete at the first time */ - vface = vlayer->queue.first; - while(vface) { - mark_changed_face_obsolete(vface); - vface = vface->next; - } - - /* send all received and changed verse face again to verse server */ - vface = vlayer->dl.lb.first; - while(vface) { - nvface = vface->next; - sync_verseface_with_editface(vlayer, vface); - vface = nvface; - } -} - -/* - * send delete polygon command to verse server - */ -void b_verse_send_face_delete(EditFace *efa) -{ - ((VerseFace*)efa->vface)->face = NULL; - send_verse_face_delete((VerseFace*)efa->vface); - efa->vface = NULL; -} - -/*============================================================================= - * - * functions handling verse/blender VERTEXES - * - *===========================================================================*/ - -/* - * this function will sync position of all VerseVerts with EditVerts - * this function is called after actions: Smooth, Noise and To Sphere, - * because position of vertexes isn't managed by transform system - */ -void sync_all_verseverts_with_editverts(VNode *vnode) -{ - struct VLayer *vlayer; - struct VerseVert *vvert; - - if(vnode->type != V_NT_GEOMETRY) return; - - vlayer = find_verse_layer_type((VGeomData*)vnode->data, VERTEX_LAYER); - - vvert = vlayer->dl.lb.first; - - /* sync all received vertexes */ - while(vvert) { - send_versevert_pos(vvert); - vvert = vvert->next; - } - - vvert = vlayer->queue.first; - - /* sync all unreceived vertexes (mar pos as obsolete, when - * actual position was changed) */ - while(vvert) { - send_versevert_pos(vvert); - vvert = vvert->next; - } - - verse_callback_update(0); -} - -/* - * send delete vertex command to verse server - */ -void b_verse_send_vertex_delete(EditVert *eve) -{ - ((VerseVert*)eve->vvert)->vertex = NULL; - send_verse_vertex_delete((VerseVert*)eve->vvert); - eve->vvert = NULL; -} - -/* - * send position of verse vertex to verse server - */ -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) { - 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; - } - 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, - * 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); - send_verse_vertex(vvert); - } - } - } - 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])) { - vvert->flag |= VERT_POS_OBSOLETE; - } - } - - verse_callback_update(0); -} - -/* - * create new VerseVert due to information about EditVert, - * put VerseVert to queue ... send to verse host (server) - */ -void createVerseVert(EditVert *eve) -{ - if(G.editMesh->vnode) { - struct VLayer *vlayer = find_verse_layer_type((VGeomData*)((VNode*)G.editMesh->vnode)->data, VERTEX_LAYER); - createVerseVertNL(eve, (VNode*)G.editMesh->vnode, vlayer); - } - else eve->vvert = NULL; -} - -/* - * create new VerseVert due to information about EditVert, - * put VerseVert to queue ... send to verse host (server) - * NL version of function (infomration about verse node and - * layer is known ... optimalisation) - */ -void createVerseVertNL(EditVert *eve, VNode *vnode, VLayer *vlayer) -{ - struct VerseVert *vvert; - - vvert = create_verse_vertex(vlayer, vlayer->counter, eve->co[0], eve->co[1], eve->co[2]); - - vvert->vertex = (void*)eve; - eve->vvert = (void*)vvert; - - vvert->flag |= VERT_LOCKED; - -/* printf("\tsend_versevert_pos: %d create and LOCK \n", vvert->id);*/ - - /* add vvert to sending queue */ - add_item_to_send_queue(&(vlayer->queue), (void*)vvert, VERSE_VERT); -} - -/* - * create new verse vertexes due to all vertexes and send all of them to verse server - */ -static void createAllVerseVerts(VNode *vnode, VLayer *vlayer) -{ - if(G.obedit) { - struct EditMesh *em; - struct EditVert *eve; - - em = G.editMesh; - eve = em->verts.first; - - /* push all EditVertexes to the verse server */ - while(eve){ - createVerseVertNL(eve, vnode, vlayer); - eve = eve->next; - } - } -} - -/* - * unsubscribe from verse geometry layers of verse geometry node - * and clear bindings between verse node and mesh - */ -void unsubscribe_from_geom_node(VNode *vnode) -{ - struct VerseSession *session = vnode->session; - - struct VLayer *vlayer = ((VGeomData*)vnode->data)->layers.lb.first; - - if(vnode->type != V_NT_GEOMETRY) return; - - /* free bindings between verse node and blender mesh*/ - if(((VGeomData*)vnode->data)->mesh) { - ((Mesh*)((VGeomData*)vnode->data)->mesh)->vnode = NULL; - ((VGeomData*)vnode->data)->mesh = NULL; - } - - /* free bindings between verse node and blender editmesh */ - if(((VGeomData*)vnode->data)->editmesh) { - ((EditMesh*)((VGeomData*)vnode->data)->editmesh)->vnode = NULL; - ((VGeomData*)vnode->data)->editmesh = NULL; - } - - /* free all verse layer data and unsubscribe from all layers */ - while(vlayer) { - BLI_dlist_reinit(&(vlayer->dl)); - BLI_freelistN(&(vlayer->queue)); - BLI_freelistN(&(vlayer->orphans)); - - if(session->flag & VERSE_CONNECTED) - verse_send_g_layer_unsubscribe(vnode->id, vlayer->id); - - vlayer = vlayer->next; - } - -} - -/* =================================================================================== - * - * Function executed after execution of callback functions - * - * ===================================================================================*/ - -/* - * Actions executed after new VerseLayer is created - */ -void post_layer_create(struct VLayer *vlayer) -{ - /* if we are owners of VerseNode, then push geometry to verse server */ - if(vlayer->vnode->owner_id == VN_OWNER_MINE) { - switch(vlayer->type){ - case VN_G_LAYER_VERTEX_XYZ: -/* if(vlayer->id==0) createAllVerseVerts(vlayer->vnode, vlayer); - break;*/ - case VN_G_LAYER_POLYGON_CORNER_UINT32: -/* if(vlayer->id==1) createAllVerseFaces(vlayer->vnode, vlayer); - break;*/ - case VN_G_LAYER_VERTEX_UINT32: - case VN_G_LAYER_VERTEX_REAL: - case VN_G_LAYER_POLYGON_CORNER_REAL: - case VN_G_LAYER_POLYGON_FACE_UINT8: - case VN_G_LAYER_POLYGON_FACE_UINT32: - case VN_G_LAYER_POLYGON_FACE_REAL: - break; - } - } - else { - switch(vlayer->type) { - case VN_G_LAYER_VERTEX_XYZ: - case VN_G_LAYER_POLYGON_CORNER_UINT32: - case VN_G_LAYER_VERTEX_UINT32: - case VN_G_LAYER_VERTEX_REAL: - case VN_G_LAYER_POLYGON_CORNER_REAL: - case VN_G_LAYER_POLYGON_FACE_UINT8: - case VN_G_LAYER_POLYGON_FACE_UINT32: - case VN_G_LAYER_POLYGON_FACE_REAL: - break; - } - } -} - -/* - * Actions after destroying of VerseLayer - */ -void post_layer_destroy(struct VLayer *vlayer) -{ -} - -/* - * Actions executed after creating of new VerseVert, when object is in edit - * mode, and this client didn't create this VerseVert (vvert->vertex is NULL), - * then new editvert is created - */ -void post_vertex_create(VerseVert *vvert) -{ - struct VNode *obj_vnode; - struct VNode *geom_vnode = vvert->vlayer->vnode; - struct EditMesh *em=NULL; - - if(G.obedit && (((Mesh*)G.obedit->data)->vnode==geom_vnode)) { - em = (EditMesh*)((VGeomData*)geom_vnode->data)->editmesh; - } - - /* when vert was changed during sending to verse server, then - * we have to send it to verse server again */ - if(vvert->flag & VERT_POS_OBSOLETE) { - vvert->flag &= ~VERT_POS_OBSOLETE; - - if(em && (vvert->vertex)) { - struct EditVert *eve = (EditVert*)vvert->vertex; - VECCOPY(vvert->co, eve->co); - send_verse_vertex(vvert); - verse_callback_update(0); - - return; - } - } - - if(em && !(vvert->vertex)) { - struct EditVert *eve; - - /* to prevent never ending loop of sending and receiving - * vertexes, because addvertlist() sends new vertex to verse - * server if em->vnode isn't NULL */ - em->vnode = NULL; - eve = addvertlist(vvert->co, NULL); - em->vnode = (void*)geom_vnode; - - eve->vvert = (void*)vvert; - vvert->vertex = (void*)eve; - - countall(); - - recalc_editnormals(); - } - - if(((VGeomData*)geom_vnode->data)->vlink) { - obj_vnode = ((VGeomData*)geom_vnode->data)->vlink->source; - DAG_object_flush_update(G.scene, (Object*)((VObjectData*)obj_vnode->data)->object, OB_RECALC_DATA); - - allqueue(REDRAWVIEW3D, 1); - } -} - -/* - * Actions executed, when position of VerseVert was changed - * position of EditVert is changed in edit mode - */ -void post_vertex_set_xyz(VerseVert *vvert) -{ - struct VNode *obj_vnode; - struct VNode *geom_vnode = vvert->vlayer->vnode; - struct EditVert *eve = NULL; - - /* when vert was changed during sending to verse server, then - * we have to send it to verse server again */ - if(vvert->flag & VERT_POS_OBSOLETE) { - if(vvert->vertex) { - vvert->flag &= ~VERT_POS_OBSOLETE; - vvert->flag |= VERT_LOCKED; - - eve = (EditVert*)vvert->vertex; - VECCOPY(vvert->co, eve->co); - send_verse_vertex(vvert); - verse_callback_update(0); - } - else { - printf("\terror: vvert->vertex shouldn't be NULL\n"); - } - - 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; - VECCOPY(eve->co, vvert->co); - recalc_editnormals(); - } - else { - printf("\terror: vvert->vertex shouldn't be NULL\n"); - } - } - - if(((VGeomData*)geom_vnode->data)->vlink) { - obj_vnode = ((VGeomData*)geom_vnode->data)->vlink->source; - DAG_object_flush_update(G.scene, (Object*)((VObjectData*)obj_vnode->data)->object, OB_RECALC_DATA); - - allqueue(REDRAWVIEW3D, 1); - } -} - -/* - * Actions executed after deleting of VerseVert - */ -void post_vertex_delete(VerseVert *vvert) -{ - struct VNode *obj_vnode; - struct VNode *geom_vnode = vvert->vlayer->vnode; - struct EditMesh *em = NULL; - struct EditEdge *ed, *edn; - struct EditVert *eve = NULL; - - if(G.obedit && (((Mesh*)G.obedit->data)->vnode==geom_vnode)) { - em = (EditMesh*)((VGeomData*)geom_vnode->data)->editmesh; - eve = (EditVert*)vvert->vertex; - } - - if(em && eve) { - /*printf("\tPOST_VERTEX_DELETE()\n");*/ - - /* delete all edges needing eve vertex */ - ed = em->edges.first; - while(ed) { - edn = ed->next; - if(ed->v1==eve || ed->v2==eve) { - remedge(ed); - free_editedge(ed); - } - ed = edn; - } - - eve->vvert = NULL; - BLI_remlink(&em->verts, eve); - free_editvert(eve); - vvert->vertex = NULL; - - countall(); - - recalc_editnormals(); - } - - if(((VGeomData*)geom_vnode->data)->vlink) { - obj_vnode = ((VGeomData*)geom_vnode->data)->vlink->source; - DAG_object_flush_update(G.scene, (Object*)((VObjectData*)obj_vnode->data)->object, OB_RECALC_DATA); - - allqueue(REDRAWVIEW3D, 1); - } -} - -/* - * free constraint between VerseVert and EditVert - */ -void post_vertex_free_constraint(VerseVert *vvert) -{ - if(vvert->vertex) { - ((EditVert*)vvert->vertex)->vvert=NULL; - vvert->vertex=NULL; - } -} - -/* - * Action executed after setting up uint8 value of polygon - */ -void post_polygon_set_uint8(VerseFace *vface) -{ -} - -/* - * Action executed after creating of new VerseFace - */ -void post_polygon_create(VerseFace *vface) -{ - struct VNode *obj_vnode; - struct VNode *geom_vnode = vface->vlayer->vnode; - struct EditMesh *em = NULL; - - /* if verse face was set as deleted during sending to verse server, then send - * delete command to verse server now ... we know verse face id */ -/* if(vface->flag & FACE_DELETED) { - send_verse_face_delete(vface); - return; - }*/ - - if(G.obedit && (((Mesh*)G.obedit->data)->vnode==geom_vnode)) { - em = (EditMesh*)((VGeomData*)geom_vnode->data)->editmesh; - } - - /* when face was changed during sending to verse server, then - * we have to send it to verse server again */ - if(vface->flag & FACE_OBSOLETE) { - vface->flag &= ~FACE_OBSOLETE; - sync_verseface_with_editface(vface->vlayer, vface); - return; - } - - if(em && !(vface->face) && (vface->counter==0)) { - struct VLayer *vlayer; - struct VerseVert *vvert; - struct EditFace *efa; - struct EditVert *eves[4]={NULL, NULL, NULL, NULL}; - uint32 vert_ids[4]={vface->v0, vface->v1, vface->v2, vface->v3}; - int i; - - /*printf("\tPOST_POLYGON_CREATE()\n");*/ - - vlayer = find_verse_layer_type((VGeomData*)geom_vnode->data, VERTEX_LAYER); - - for(i=0; i<4; i++) { - if(vert_ids[i] != -1) { - vvert = BLI_dlist_find_link(&(vlayer->dl), vert_ids[i]); - if(vvert) eves[i] = (EditVert*)vvert->vertex; - } - } - - /* to prevent never ending loop of sending and receiving - * faces, because addfacelist() sends new face to verse - * server if em->vnode isn't NULL */ - em->vnode = NULL; - efa = addfacelist(eves[0], eves[1], eves[2], eves[3], NULL, NULL); - em->vnode = geom_vnode; - - if(efa) { - efa->vface = vface; - vface->face = efa; - } - - countall(); - - recalc_editnormals(); - } - - if(((VGeomData*)geom_vnode->data)->vlink) { - obj_vnode = ((VGeomData*)geom_vnode->data)->vlink->source; - DAG_object_flush_update(G.scene, (Object*)((VObjectData*)obj_vnode->data)->object, OB_RECALC_DATA); - - allqueue(REDRAWVIEW3D, 1); - } -} - -/* - * Action executed after changes of VerseFace - * ... order of vertexes was fliped, etc. - */ -void post_polygon_set_corner(VerseFace *vface) -{ - struct VNode *obj_vnode; - struct VNode *geom_vnode = vface->vlayer->vnode; - struct EditMesh *em = NULL; - struct EditFace *efa = NULL; - struct EditEdge *eed, *eedn; - - if(G.obedit && (((Mesh*)G.obedit->data)->vnode==geom_vnode)) { - em = (EditMesh*)((VGeomData*)geom_vnode->data)->editmesh; - efa = (EditFace*)vface->face; - } - - if(em && efa) { - - /* when face was changed during sending to verse server, then - * we have to send it to verse server again */ - if(vface->flag & FACE_OBSOLETE) { - vface->flag &= ~FACE_OBSOLETE; - sync_verseface_with_editface(vface->vlayer, vface); - return; - } - - /* mark all edges, which are part of face efa */ - efa->e1->f2 = 1; - efa->e2->f2 = 1; - efa->e3->f2 = 1; - if(efa->e4) efa->e4->f2 = 1; - - /* change pointers at EdtitVerts and decrease counters of "old" - * VerseVertexes reference ... less VerseFaces will need them */ - if(vface->vvert0 != efa->v1->vvert) - efa->v1 = (EditVert*)vface->vvert0->vertex; - if(vface->vvert1 != efa->v2->vvert) - efa->v2 = (EditVert*)vface->vvert1->vertex; - if(vface->vvert2 != efa->v3->vvert) - efa->v3 = (EditVert*)vface->vvert2->vertex; - if(efa->v4) { - if(!vface->vvert3) - efa->v4 = NULL; - else if(vface->vvert3 != efa->v4->vvert) - efa->v4 = (EditVert*)vface->vvert3->vertex; - } - - /* change pointers at EditEdges */ - - /* 1st edge */ - eed = findedgelist(efa->v1, efa->v2); - if(eed) efa->e1 = eed; - else efa->e1 = addedgelist(efa->v1, efa->v2, NULL); - - /* 2nd edge */ - eed = findedgelist(efa->v2, efa->v3); - if(eed) efa->e2 = eed; - else efa->e2 = addedgelist(efa->v2, efa->v3, NULL); - - if(efa->v4) { - /* 3th edge */ - eed = findedgelist(efa->v2, efa->v3); - if(eed) efa->e3 = eed; - else efa->e3 = addedgelist(efa->v2, efa->v3, NULL); - /* 4th edge */ - eed = findedgelist(efa->v4, efa->v1); - if(eed) efa->e4 = eed; - else efa->e4 = addedgelist(efa->v4, efa->v1, NULL); - } - else { - /* 3th edge */ - eed = findedgelist(efa->v3, efa->v1); - if(eed) efa->e3 = eed; - else efa->e3 = addedgelist(efa->v3, efa->v1, NULL); - /* 4th edge */ - efa->e4 = NULL; - } - - /* unmark needed edges */ - efa = em->faces.first; - while(efa) { - efa->e1->f2 = 0; - efa->e2->f2 = 0; - efa->e3->f2 = 0; - if(efa->e4) efa->e4->f2 = 0; - efa = efa->next; - } - - /* delete all unneeded edges */ - eed = em->edges.first; - while(eed) { - eedn = eed->next; - if(eed->f2) { - remedge(eed); - free_editedge(eed); - } - eed = eedn; - } - - countall(); - - recalc_editnormals(); - } - - if(((VGeomData*)geom_vnode->data)->vlink) { - obj_vnode = ((VGeomData*)geom_vnode->data)->vlink->source; - DAG_object_flush_update(G.scene, (Object*)((VObjectData*)obj_vnode->data)->object, OB_RECALC_DATA); - - allqueue(REDRAWVIEW3D, 1); - } -} - -/* - * Action executed after deleting of VerseFace - */ -void post_polygon_delete(VerseFace *vface) -{ - struct VNode *obj_vnode; - struct VNode *geom_vnode = vface->vlayer->vnode; - struct EditMesh *em = NULL; - struct EditFace *efa = NULL; - struct EditEdge *eed, *eedn; - - if(G.obedit && (((Mesh*)G.obedit->data)->vnode==geom_vnode)) { - em = (EditMesh*)((VGeomData*)geom_vnode->data)->editmesh; - efa = (EditFace*)vface->face; - } - - if(em && efa) { - /*printf("\tPOST_POLYGON_DELETE()\n");*/ - - /* mark all edges, which are part of face efa */ - efa->e1->f2 = 1; - efa->e2->f2 = 1; - efa->e3->f2 = 1; - if(efa->e4) efa->e4->f2 = 1; - - efa->vface = NULL; - BLI_remlink(&em->faces, efa); - free_editface(efa); - vface->face = NULL; - - /* following two crazy loops wouldn't be neccessary if verse spec - * would support edges */ - - /* unmark needed edges */ - efa = em->faces.first; - while(efa) { - efa->e1->f2 = 0; - efa->e2->f2 = 0; - efa->e3->f2 = 0; - if(efa->e4) efa->e4->f2 = 0; - efa = efa->next; - } - - /* delete all unneeded edges */ - eed = em->edges.first; - while(eed) { - eedn = eed->next; - if(eed->f2) { - remedge(eed); - free_editedge(eed); - } - eed = eedn; - } - - countall(); - } - - if(((VGeomData*)geom_vnode->data)->vlink) { - obj_vnode = ((VGeomData*)geom_vnode->data)->vlink->source; - DAG_object_flush_update(G.scene, (Object*)((VObjectData*)obj_vnode->data)->object, OB_RECALC_DATA); - - allqueue(REDRAWVIEW3D, 1); - } -} - -/* - * free constraint between VerseFace and EditFace - */ -void post_polygon_free_constraint(VerseFace *vface) -{ - if(vface->face) { - ((EditFace*)vface->face)->vface = NULL; - vface->face = NULL; - } -} - -/* - * free constraint between VGeomData, EditMesh and Mesh - */ -void post_geometry_free_constraint(VNode *vnode) -{ - if(((VGeomData*)vnode->data)->editmesh) { - G.editMesh->vnode = NULL; - ((VGeomData*)vnode->data)->editmesh = NULL; - } - if(((VGeomData*)vnode->data)->mesh) { - ((Mesh*)((VGeomData*)vnode->data)->mesh)->vnode = NULL; - ((VGeomData*)vnode->data)->mesh = NULL; - } -} - -/* ========================================================================= - * - * Functions influencing whole EditMesh or VerseMesh - * - * ========================================================================= */ - -/* - * free all bindings between EditMesh and "verse mesh" ... it is called between - * restorng editmesh from undo stack - */ -void destroy_versemesh(VNode *vnode) -{ - struct VLayer *vert_vlayer, *face_vlayer; - struct VerseVert *vvert; - struct VerseFace *vface; - - if(vnode->type != V_NT_GEOMETRY) return; - - vert_vlayer = find_verse_layer_type((VGeomData*)vnode->data, VERTEX_LAYER); - face_vlayer = find_verse_layer_type((VGeomData*)vnode->data, POLYGON_LAYER); - - - /* send delete command to all received verse faces */ - vface = face_vlayer->dl.lb.first; - while(vface) { - if(vface->face) ((EditFace*)vface->face)->vface = NULL; - vface->face = NULL; - send_verse_face_delete(vface); - vface = vface->next; - } - /* send delete command to all verse faces waiting in orphan list */ - vface = face_vlayer->orphans.first; - while(vface) { - if(vface->face) ((EditFace*)vface->face)->vface = NULL; - vface->face = NULL; - send_verse_face_delete(vface); - vface = vface->next; - } - /* mark all verse faces waiting in sending queue as deleted, - * send delete command, when this verse face was changed */ - vface = face_vlayer->queue.first; - while(vface) { - if(vface->face) ((EditFace*)vface->face)->vface = NULL; - vface->face = NULL; - if(vface->flag & FACE_CHANGED) - send_verse_face_delete(vface); - else { - vface->flag |= FACE_DELETED; - } - vface = vface->next; - } - - /* send delete command to all received verse vertexes */ - vvert = vert_vlayer->dl.lb.first; - while(vvert) { - if(vvert->vertex) ((EditVert*)vvert->vertex)->vvert = NULL; - vvert->vertex = NULL; - send_verse_vertex_delete(vvert); - vvert = vvert->next; - } - /* mark all verse vertexes waiting in sending queue as deleted - * ... verse vertexes will be deleted, when received */ - vvert = vert_vlayer->queue.first; - while(vvert) { - if(vvert->vertex) ((EditVert*)vvert->vertex)->vvert = NULL; - vvert->vertex = NULL; - vvert = vvert->next; - } -} - -/* - * duplicate geometry verse node, this can be handy, when you duplicate some - * object or make object single user - */ -VNode *create_geom_vnode_from_geom_vnode(VNode *vnode) -{ - struct VNode *n_vnode; /* new verse geometry node */ - struct VGeomData *geom_data; /* new geometry data */ - struct VLayer *n_vert_vlayer, *n_face_vlayer; /* new vertex and polygon layer */ - struct VLayer *vert_vlayer, *face_vlayer; - struct VerseVert *n_vvert, *vvert; - struct VerseFace *n_vface, *vface; - int i; - - if(!vnode) return NULL; - - if(vnode->type != V_NT_GEOMETRY) return NULL; - - /* create new verse node, when no one exist */ - n_vnode= create_verse_node(vnode->session, -1 , V_NT_GEOMETRY, VN_OWNER_MINE); - /* create new geometry data */ - geom_data = create_geometry_data(); - n_vnode->data = (void*)geom_data; - - /* set up name of VerseNode */ - n_vnode->name = (char*)MEM_mallocN(sizeof(char*)*(strlen(vnode->name)-1), "new geom node name"); - n_vnode->name[0] = '\0'; - strcat(n_vnode->name, vnode->name); - - /* add node to sending queue */ - add_item_to_send_queue(&(vnode->session->queue), n_vnode, VERSE_NODE); - - /* create vertex verse layer */ - n_vert_vlayer = create_verse_layer(n_vnode, 0, "vertex", VN_G_LAYER_VERTEX_XYZ, 0, 0); - add_item_to_send_queue(&(geom_data->queue), n_vert_vlayer, VERSE_LAYER); - - /* create polygon verse layer */ - n_face_vlayer = create_verse_layer(n_vnode, 1, "polygon", VN_G_LAYER_POLYGON_CORNER_UINT32, 0, 0); - add_item_to_send_queue(&(geom_data->queue), n_face_vlayer, VERSE_LAYER); - - /* find vertex layer of old verse node */ - vert_vlayer = find_verse_layer_type((VGeomData*)vnode->data, VERTEX_LAYER); - /* find polygon layer of old verse node */ - face_vlayer = find_verse_layer_type((VGeomData*)vnode->data, POLYGON_LAYER); - - /* duplicate verse vertexes */ - for(i=0, vvert = (VerseVert*)vert_vlayer->dl.lb.first; vvert; vvert = vvert->next, i++) { - n_vvert = create_verse_vertex(n_vert_vlayer, i, vvert->co[0], vvert->co[1], vvert->co[2]); - vvert->tmp.vvert = n_vvert; - add_item_to_send_queue(&(n_vert_vlayer->queue), n_vvert, VERSE_VERT); - } - - /* duplicate verse faces (polyons) */ - for(i=0, vface = (VerseFace*)face_vlayer->dl.lb.first; vface; vface = vface->next, i++) { - n_vface = create_verse_face(n_face_vlayer, i, -1, -1, -1, -1); - n_vface->vvert0 = vface->vvert0->tmp.vvert; - n_vface->vvert1 = vface->vvert1->tmp.vvert; - n_vface->vvert2 = vface->vvert2->tmp.vvert; - if(vface->vvert3) - n_vface->vvert3 = vface->vvert3->tmp.vvert; - else - n_vface->vvert3 = NULL; - add_item_to_send_queue(&(n_face_vlayer->queue), n_vface, VERSE_FACE); - } - - return n_vnode; -} - -/* - * create new geometry node, make bindings between geometry node and editmesh, - * make bindings between editverts and verseverts, make bindings between editfaces - * and versefaces - */ -VNode *create_geom_vnode_data_from_editmesh(VerseSession *session, EditMesh *em) -{ - struct VNode *vnode; - struct Mesh *me; - struct VGeomData *geom_data; - struct VLayer *vert_vlayer, *face_vlayer; - - if(!session) return NULL; - - if(!em) return NULL; - - /* some verse geometry node already exists */ - if(em->vnode) return NULL; - - /* we will need mesh too (mesh name, creating bindings between verse node, etc.) */ - me = get_mesh(G.obedit); - - /* create new verse node, when no one exist */ - vnode = create_verse_node(session, -1 , V_NT_GEOMETRY, VN_OWNER_MINE); - /* create new geometry data */ - geom_data = create_geometry_data(); - vnode->data = (void*)geom_data; - - /* set up name of VerseNode */ - vnode->name = (char*)MEM_mallocN(sizeof(char*)*(strlen(me->id.name)-1), "geom node name"); - vnode->name[0] = '\0'; - strcat(vnode->name, me->id.name+2); - - /* set up bindings */ - me->vnode = (void*)vnode; - em->vnode = (void*)vnode; - geom_data->mesh = (void*)me; - geom_data->editmesh = (void*)em; - - /* add node to sending queue */ - add_item_to_send_queue(&(session->queue), vnode, VERSE_NODE); - - /* create vertex verse layer */ - vert_vlayer = create_verse_layer(vnode, 0, "vertex", VN_G_LAYER_VERTEX_XYZ, 0, 0); - add_item_to_send_queue(&(geom_data->queue), vert_vlayer, VERSE_LAYER); - - /* create polygon verse layer */ - face_vlayer = create_verse_layer(vnode, 1, "polygon", VN_G_LAYER_POLYGON_CORNER_UINT32, 0, 0); - add_item_to_send_queue(&(geom_data->queue), face_vlayer, VERSE_LAYER); - - /* create all verse verts and add them to sending queue */ - createAllVerseVerts(vnode, vert_vlayer); - - /* create all verse faces and add tehm to sending queue */ - createAllVerseFaces(vnode, face_vlayer); - - return vnode; -} - -/* - * create new geometry node, make bindings between geometry node and mesh and - * fill geometry node with new data based at mesh data - */ -VNode *create_geom_vnode_data_from_mesh(VerseSession *session, Mesh *me) -{ - struct VNode *vnode; - struct VGeomData *geom_data; - struct VLayer *vert_vlayer, *face_vlayer; - struct VerseVert *vvert, **vverts; - struct VerseFace *vface; - struct MVert *mvert; - struct MFace *mface; - int i; - - if(!session) return NULL; - - if(!me) return NULL; - - /* some verse geometry node already exists */ - if(me->vnode) return NULL; - - /* create new verse node, when no one exist */ - vnode = create_verse_node(session, -1 , V_NT_GEOMETRY, VN_OWNER_MINE); - /* create new geometry data */ - geom_data = create_geometry_data(); - vnode->data = (void*)geom_data; - - /* set up name of VerseNode */ - vnode->name = (char*)MEM_mallocN(sizeof(char*)*(strlen(me->id.name)-1), "geom node name"); - vnode->name[0] = '\0'; - strcat(vnode->name, me->id.name+2); - - /* set up bindings */ - me->vnode = (void*)vnode; - geom_data->mesh = (void*)me; - - /* add node to sending queue */ - add_item_to_send_queue(&(session->queue), vnode, VERSE_NODE); - - /* create vertex verse layer */ - vert_vlayer = create_verse_layer(vnode, 0, "vertex", VN_G_LAYER_VERTEX_XYZ, 0, 0); - add_item_to_send_queue(&(geom_data->queue), vert_vlayer, VERSE_LAYER); - - /* create polygon verse layer */ - face_vlayer = create_verse_layer(vnode, 1, "polygon", VN_G_LAYER_POLYGON_CORNER_UINT32, 0, 0); - add_item_to_send_queue(&(geom_data->queue), face_vlayer, VERSE_LAYER); - - /* temporary array of VerseVerts */ - vverts = (VerseVert**)MEM_mallocN(sizeof(VerseVert*)*me->totvert,"temp array of vverts"); - - /* "fill vertex layer with vertexes" and add them to sending queue (send them to verse server) */ - for(i=0, mvert=me->mvert; i<me->totvert; i++, mvert++) { - vverts[i] = vvert = create_verse_vertex(vert_vlayer, i, mvert->co[0], mvert->co[1], mvert->co[2]); - add_item_to_send_queue(&(vert_vlayer->queue), vvert, VERSE_VERT); - } - - /* "fill face/polygon layer with faces" and them to sending queue */ - for(i=0, mface = me->mface; i<me->totface; i++, mface++) { - if(mface->v4) { - vface = create_verse_face(face_vlayer, i, mface->v1, mface->v2, mface->v3, mface->v4); - vface->vvert0 = vverts[mface->v1]; - vface->vvert1 = vverts[mface->v2]; - vface->vvert2 = vverts[mface->v3]; - vface->vvert3 = vverts[mface->v4]; - vface->counter = 4; - } - else { - vface = create_verse_face(face_vlayer, i, mface->v1, mface->v2, mface->v3, -1); - vface->vvert0 = vverts[mface->v1]; - vface->vvert1 = vverts[mface->v2]; - vface->vvert2 = vverts[mface->v3]; - vface->counter = 3; - } - add_item_to_send_queue(&(face_vlayer->queue), vface, VERSE_FACE); - } - - MEM_freeN(vverts); - - return vnode; -} - -/* - * creates Mesh from verse geometry node and create bindings - * between them - */ -Mesh *create_mesh_from_geom_node(VNode *vnode) -{ - struct Mesh *me; - - if(vnode->type != V_NT_GEOMETRY) return NULL; - - /* add new empty mesh*/ - me = add_mesh("Mesh"); - /* set up bindings between mesh and verse node */ - me->vnode = (void*)vnode; - ((VGeomData*)vnode->data)->mesh = (void*)me; - - return me; -} - -/* - * create mesh from verse mesh - */ -void create_meshdata_from_geom_node(Mesh *me, VNode *vnode) -{ - struct VLayer *vert_vlayer, *face_vlayer; - struct VerseVert *vvert; - struct VerseFace *vface; - struct MVert *mvert; - struct MFace *mface; - struct EdgeHash *edges; - int index; - - if(!me || !vnode) return; - - if(vnode->type != V_NT_GEOMETRY) return; - - vert_vlayer = find_verse_layer_type((VGeomData*)vnode->data, VERTEX_LAYER); - face_vlayer = find_verse_layer_type((VGeomData*)vnode->data, POLYGON_LAYER); - - CustomData_free(&me->vdata, me->totvert); - CustomData_free(&me->edata, me->totedge); - CustomData_free(&me->fdata, me->totface); - mesh_update_customdata_pointers(me); - - if(me->mselect) { - MEM_freeN(me->mselect); - me->mselect = NULL; - } - - me->totvert = vert_vlayer ? vert_vlayer->dl.da.count : 0; - me->totface = face_vlayer ? face_vlayer->dl.da.count : 0; - me->totselect = 0; - - CustomData_add_layer(&me->vdata, CD_MVERT, CD_CALLOC, NULL, me->totvert); - CustomData_add_layer(&me->fdata, CD_MFACE, CD_CALLOC, NULL, me->totface); - mesh_update_customdata_pointers(me); - - mvert = me->mvert; - mface = me->mface; - - index = 0; - vvert = vert_vlayer ? vert_vlayer->dl.lb.first : NULL; - while(vvert) { - VECCOPY(mvert->co, vvert->co); - VECCOPY(mvert->no, vvert->no); - mvert->flag = 0; - mvert->mat_nr = 0; - vvert->tmp.index = index++; - vvert = vvert->next; - mvert++; - } - - edges = BLI_edgehash_new(); - vface = face_vlayer ? face_vlayer->dl.lb.first : NULL; - while(vface) { - mface->v1 = vface->vvert0->tmp.index; - mface->v2 = vface->vvert1->tmp.index; - mface->v3 = vface->vvert2->tmp.index; - - if(!BLI_edgehash_haskey(edges, mface->v1, mface->v2)) - BLI_edgehash_insert(edges, mface->v1, mface->v2, NULL); - if(!BLI_edgehash_haskey(edges, mface->v2, mface->v3)) - BLI_edgehash_insert(edges, mface->v2, mface->v3, NULL); - if(vface->vvert3) { - mface->v4 = vface->vvert3->tmp.index; - if(!BLI_edgehash_haskey(edges, mface->v3, mface->v4)) - BLI_edgehash_insert(edges, mface->v3, mface->v4, NULL); - if(!BLI_edgehash_haskey(edges, mface->v4, mface->v1)) - BLI_edgehash_insert(edges, mface->v4, mface->v1, NULL); - } else { - mface->v4 = 0; - if(!BLI_edgehash_haskey(edges, mface->v3, mface->v1)) - BLI_edgehash_insert(edges, mface->v3, mface->v1, NULL); - } - - mface->flag = 0; - mface->pad = 0; - mface->mat_nr = 0; - mface->edcode = 0; - - /* index 0 isn't allowed at location 3 or 4 */ - test_index_face(mface, NULL, 0, vface->vvert3?4:3); -/* printf("\t mface: %d, %d, %d, %d\n", mface->v1, mface->v2, mface->v3, mface->v4);*/ - - vface = vface->next; - mface++; - } - - me->totedge = BLI_edgehash_size(edges); - - if(me->totedge) { - EdgeHashIterator *i; - MEdge *medge = me->medge = CustomData_add_layer(&me->edata, CD_MEDGE, CD_CALLOC, NULL, me->totedge); - - for(i = BLI_edgehashIterator_new(edges); !BLI_edgehashIterator_isDone(i); BLI_edgehashIterator_step(i), ++medge) { - memset(medge, 0, sizeof(struct MEdge)); - BLI_edgehashIterator_getKey(i, (int*)&medge->v1, (int*)&medge->v2); - } - BLI_edgehashIterator_free(i); - } - - BLI_edgehash_free(edges, NULL); - - mesh_calc_normals(me->mvert, me->totvert, me->mface, me->totface, NULL); -} - -/* - * Create EditMesh from VerseMesh and keep system in consitant state, this - * function is called, when edit mode is entered ... edit mesh is generated - * from verse mesh (not from Mesh: (Mesh*)ob->data) - */ -void create_edit_mesh_from_geom_node(VNode *vnode) -{ - struct VLayer *vert_layer, *face_layer; - struct VerseVert *vvert; - struct VerseFace *vface; - struct Mesh *me; - struct EditVert *eve, *eve0, *eve1, *eve2, *eve3; - struct EditFace *efa; - unsigned int keyindex; - - if(!(G.obedit && G.obedit->type==OB_MESH)) return; - me = (Mesh*)G.obedit->data; - if(vnode!=(VNode*)me->vnode || vnode->type!=V_NT_GEOMETRY) return; - - vert_layer = find_verse_layer_type((VGeomData*)vnode->data, VERTEX_LAYER); - face_layer = find_verse_layer_type((VGeomData*)vnode->data, POLYGON_LAYER); - - if(!(vert_layer && face_layer)) return; - - waitcursor(1); - - /* free old editMesh */ - free_editMesh(G.editMesh); - - G.editMesh->vnode = NULL; - - vvert = vert_layer->dl.lb.first; - - keyindex = 0; - - /* create all EditVerts */ - while(vvert) { - eve = addvertlist(vvert->co, NULL); - - eve->f = 0; - eve->h = 0; - eve->data = NULL; - eve->keyindex = keyindex; - eve->vvert = (void*)vvert; - - vvert->vertex = (void*)eve; - - keyindex++; - vvert = vvert->next; - } - - vface = face_layer->dl.lb.first; - - /* create all EditFaces and EditEdges */ - while(vface) { - if(vface->vvert0) eve0= vface->vvert0->vertex; - else eve0 = NULL; - if(vface->vvert1) eve1= vface->vvert1->vertex; - else eve1 = NULL; - if(vface->vvert2) eve2= vface->vvert2->vertex; - else eve2 = NULL; - if(vface->vvert3) eve3= vface->vvert3->vertex; - else eve3 = NULL; - - efa= addfacelist(eve0, eve1, eve2, eve3, NULL, NULL); - if(efa) { - efa->f = 0; - efa->h = 0; - efa->vface = (void*)vface; - vface->face = (void*)efa; - } - vface = vface->next; - } - - countall(); - - recalc_editnormals(); - - G.editMesh->vnode = (void*)vnode; - ((VGeomData*)vnode->data)->editmesh = (void*)G.editMesh; - - waitcursor(0); -} - -/* - * destroy bindings between EditMesh and VerseMesh and send delete commands - * for all VerseVerts and VerseFaces to verse server, Verse Node has to be - * geometry node - */ - -void destroy_verse_mesh(VNode *vnode) -{ - struct VLayer *vert_vlayer, *face_vlayer; - struct VerseFace *vface; - struct VerseVert *vvert; - - if(vnode->type != V_NT_GEOMETRY) return; - - face_vlayer = find_verse_layer_type((VGeomData*)vnode->data, POLYGON_LAYER); - vface = face_vlayer->dl.lb.first; - - while(vface) { - ((EditFace*)vface->face)->vface = NULL; - vface->face = NULL; - vface = vface->next; - } - - vert_vlayer = find_verse_layer_type((VGeomData*)vnode->data, VERTEX_LAYER); - vvert = vert_vlayer->dl.lb.first; - - while(vvert) { - ((EditVert*)vvert->vertex)->vvert = NULL; - vvert->vertex = NULL; - vvert = vvert->next; - } - - destroy_geometry(vnode); -} - -#endif - |