forked from bartvdbraak/blender
Huge commit: VERSE
- All code is in #ifdef ... #endif - Only make build system is supported and you have to add: export WITH_VERSE=true to user-def.mk file - Blender can share only mesh objects and bitmaps now - More informations can be found at wiki: http://mediawiki.blender.org/index.php/BlenderDev/VerseIntegrationToBlender http://mediawiki.blender.org/index.php/BlenderDev/VerseIntegrationToBlenderUserDoc I hope, that I didn't forget at anything
This commit is contained in:
parent
ffe630b452
commit
2ee42ac01e
4
extern/Makefile
vendored
4
extern/Makefile
vendored
@ -48,6 +48,10 @@ ifeq ($(NAN_FFMPEG), $(LCGDIR)/gcc/ffmpeg)
|
||||
endif
|
||||
endif
|
||||
|
||||
ifeq ($(WITH_VERSE), true)
|
||||
DIRS += verse
|
||||
endif
|
||||
|
||||
ifneq ($(NAN_NO_KETSJI), true)
|
||||
DIRS += bullet
|
||||
endif
|
||||
|
@ -209,6 +209,18 @@ ifeq ($(INTERNATIONAL), true)
|
||||
endif
|
||||
endif
|
||||
|
||||
ifeq ($(WITH_VERSE), true)
|
||||
ifeq ($(OS), windows)
|
||||
ifeq ($(FREE_WINDOWS), true)
|
||||
COMLIB += $(NAN_VERSE)/lib/libverse.a
|
||||
else
|
||||
COMLIB += $(NAN_VERSE)/lib/verse.lib
|
||||
endif
|
||||
else
|
||||
COMLIB += $(NAN_VERSE)/lib/libverse.a
|
||||
endif
|
||||
endif
|
||||
|
||||
ifeq ($(OS), irix)
|
||||
COMLIB += $(NAN_SDL)/lib/libSDL.a
|
||||
endif
|
||||
|
@ -184,6 +184,11 @@ typedef struct Global {
|
||||
|
||||
#define G_RECORDKEYS (1 << 25)
|
||||
|
||||
/*#ifdef WITH_VERSE*/
|
||||
#define G_VERSE_CONNECTED (1 << 26)
|
||||
#define G_DRAW_VERSE_DEBUG (1 << 27)
|
||||
/*#endif*/
|
||||
|
||||
/* G.fileflags */
|
||||
|
||||
#define G_AUTOPACK (1 << 0)
|
||||
|
503
source/blender/blenkernel/BKE_verse.h
Normal file
503
source/blender/blenkernel/BKE_verse.h
Normal file
@ -0,0 +1,503 @@
|
||||
/**
|
||||
* $Id$
|
||||
*
|
||||
* ***** BEGIN GPL/BL DUAL 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. The Blender
|
||||
* Foundation also sells licenses for use in proprietary software under
|
||||
* the Blender License. See http://www.blender.org/BL/ for information
|
||||
* about this.
|
||||
*
|
||||
* 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/BL DUAL LICENSE BLOCK *****
|
||||
*/
|
||||
|
||||
/* #define WITH_VERSE */
|
||||
|
||||
#ifndef BKE_VERSE_H
|
||||
#define BKE_VERSE_H
|
||||
|
||||
#include "DNA_listBase.h"
|
||||
#include "BLI_dynamiclist.h"
|
||||
|
||||
#include "verse.h"
|
||||
|
||||
struct VNode;
|
||||
|
||||
/*
|
||||
* virtual data type (used only for retype)
|
||||
*/
|
||||
typedef struct verse_parent {
|
||||
struct verse_parent *next, *prev;
|
||||
VLayerID layer_id;
|
||||
uint32 id;
|
||||
} verse_parent;
|
||||
|
||||
/*
|
||||
* verse data: 4 float value
|
||||
*/
|
||||
typedef struct quat_real32_item {
|
||||
struct quat_real32_item *next, *prev;
|
||||
VLayerID layer_id;
|
||||
void *parent;
|
||||
real32 value[4];
|
||||
} quat_real32_item;
|
||||
|
||||
/*
|
||||
* verse data: 4 uint32 values
|
||||
*/
|
||||
typedef struct quat_uint32_item {
|
||||
struct quat_uint32_item *next, *prev;
|
||||
VLayerID layer_id;
|
||||
void *parent;
|
||||
uint32 value[4];
|
||||
} quat_uint32_item;
|
||||
|
||||
/*
|
||||
* verse data: 3 float values
|
||||
*/
|
||||
typedef struct vec_real32_item {
|
||||
struct vec_real32_item *next, *prev;
|
||||
VLayerID layer_id;
|
||||
void *parent;
|
||||
real32 value[3];
|
||||
} vec_real32_item;
|
||||
|
||||
/*
|
||||
* verse data: float value (weight)
|
||||
*/
|
||||
typedef struct real32_item {
|
||||
struct real32_item *next, *prev;
|
||||
VLayerID layer_id;
|
||||
void *parent;
|
||||
real32 value;
|
||||
} real32_item;
|
||||
|
||||
/*
|
||||
* verse data: uint32 value
|
||||
*/
|
||||
typedef struct uint32_item {
|
||||
struct uint32_item *next, *prev;
|
||||
VLayerID layer_id;
|
||||
void *parent;
|
||||
uint32 value;
|
||||
} uint32_item;
|
||||
|
||||
/*
|
||||
* verse data: uint8 value
|
||||
*/
|
||||
typedef struct uint8_item {
|
||||
struct uint8_item *next, *prev;
|
||||
VLayerID layer_id;
|
||||
void *parent;
|
||||
uint8 value;
|
||||
} uint8_item;
|
||||
|
||||
/*
|
||||
* verse data: vertex
|
||||
*/
|
||||
typedef struct VerseVert {
|
||||
struct VerseVert *next, *prev;
|
||||
/* verse data */
|
||||
struct VLayer *vlayer; /* pointer at VerseLayer */
|
||||
uint32 id; /* id of vertex */
|
||||
real32 co[3]; /* x,y,z-coordinates of vertex */
|
||||
real32 no[3]; /* normal of vertex */
|
||||
/* blender internals */
|
||||
short flag; /* flags: VERT_DELETED, VERT_RECEIVED */
|
||||
void *vertex; /* pointer at EditVert or MVert */
|
||||
int counter; /* counter of VerseFaces using this VerseVert */
|
||||
union {
|
||||
unsigned int index; /* counter need during transformation to mesh */
|
||||
struct VerseVert *vvert;
|
||||
} tmp; /* pointer at new created verse vert, it is
|
||||
* used during duplicating geometry node */
|
||||
float *cos; /* modified coordinates of vertex */
|
||||
} VerseVert;
|
||||
|
||||
/*
|
||||
* verse data: polygon
|
||||
*/
|
||||
typedef struct VerseFace {
|
||||
struct VerseFace *next, *prev;
|
||||
/* verse data */
|
||||
struct VLayer *vlayer; /* pointer at VerseLayer */
|
||||
uint32 id; /* id of face */
|
||||
struct VerseVert *vvert0; /* pointer at 1st VerseVert */
|
||||
struct VerseVert *vvert1; /* pointer at 2nd VerseVert */
|
||||
struct VerseVert *vvert2; /* pointer at 3th VerseVert */
|
||||
struct VerseVert *vvert3; /* pointer at 4th VerseVert */
|
||||
unsigned int v0, v1, v2, v3; /* indexes of VerseVerts ... needed during receiving */
|
||||
/* blender internals */
|
||||
char flag; /* flags: FACE_SEND_READY, FACE_SENT, FACE_RECEIVED, FACE_CHANGED*/
|
||||
short counter; /* counter of missed VerseVertexes */
|
||||
void *face; /* pointer at EditFace */
|
||||
float no[3]; /* normal vector */
|
||||
} VerseFace;
|
||||
|
||||
/*
|
||||
* verse data: layer
|
||||
*/
|
||||
typedef struct VLayer {
|
||||
struct VLayer *next, *prev;
|
||||
/* verse data*/
|
||||
struct VNode *vnode; /* pointer at VerseNode */
|
||||
uint16 id; /* id of layer */
|
||||
char *name; /* name of layer */
|
||||
VNGLayerType type; /* type of layer (VN_G_LAYER_VERTEX_XYZ, VN_G_LAYER_POLYGON_CORNER_UINT32) */
|
||||
uint32 def_int; /* default integer value */
|
||||
real64 def_real; /* default float value */
|
||||
/* blender internals */
|
||||
char flag; /* flags: LAYER_SENT, LAYER_RECEIVED, LAYER_DELETED, LAYER_OBSOLETE */
|
||||
short content; /* type of content (VERTEX_LAYER, POLYGON_LAYER) */
|
||||
struct DynamicList dl; /* vertexes, polygons, etc. */
|
||||
struct ListBase queue; /* queue of vertexes, polygons, etc. waiting for sending to verse server */
|
||||
struct ListBase orphans; /* list of versedata (polygons, etc.), that can be added to the DynamicList
|
||||
* due to not received VerseVerts */
|
||||
unsigned int counter; /* counter of sent items */
|
||||
/* client dependent methods */
|
||||
void (*post_layer_create)(struct VLayer *vlayer);
|
||||
void (*post_layer_destroy)(struct VLayer *vlayer);
|
||||
} VLayer;
|
||||
|
||||
/*
|
||||
* verse data: link
|
||||
*/
|
||||
typedef struct VLink{
|
||||
struct VLink *next, *prev;
|
||||
/* verse data */
|
||||
struct VerseSession *session; /* session pointer */
|
||||
struct VNode *source; /* object VerseNode "pointing" at some other VerseNode */
|
||||
struct VNode *target; /* VerseNode linked with some object node */
|
||||
unsigned int id; /* id of VerseLink */
|
||||
unsigned int target_id; /* some unknow id */
|
||||
char *label; /* name/label of VerseLink */
|
||||
/* blender internals */
|
||||
char flag; /* flags: LINK_SEND_READY */
|
||||
/* client dependent methods */
|
||||
void (*post_link_set)(struct VLink *vlink);
|
||||
void (*post_link_destroy)(struct VLink *vlink);
|
||||
} VLink;
|
||||
|
||||
/*
|
||||
* bitmap layer
|
||||
*/
|
||||
typedef struct VBitmapLayer {
|
||||
struct VBitmapLayer *next, *prev;
|
||||
/* verse data */
|
||||
struct VNode *vnode; /* pointer at Verse Node */
|
||||
VLayerID id; /* id of layer */
|
||||
char *name; /* name of layer */
|
||||
VNBLayerType type; /* type of layer (bits per channel) 1, 8, 16, 32, 64 */
|
||||
void *data; /* dynamic allocated data */
|
||||
/* blender internals */
|
||||
char flag;
|
||||
} VBitmapLayer;
|
||||
|
||||
/*
|
||||
* data of bitmap node
|
||||
*/
|
||||
typedef struct VBitmapData {
|
||||
struct DynamicList layers; /* dynamic list with access array of bitmap layers */
|
||||
struct ListBase queue; /* queue of layers waiting for receiving from verse server */
|
||||
uint16 width; /* width of all verse layers */
|
||||
uint16 height; /* height of all verse layers */
|
||||
uint16 depth; /* depth of bitmap 1 is 2D bitmap, >1 is 3D bitmap */
|
||||
/* blender internals */
|
||||
uint16 t_width; /* = (width/VN_B_TILE_SIZE + 1)*VN_B_TILE_SIZE */
|
||||
uint16 t_height; /* = (height/VN_B_TILE_SIZE + 1)*VN_B_TILE_SIZE */
|
||||
void *image; /* pointer at image */
|
||||
/* client dependent methods */
|
||||
void (*post_bitmap_dimension_set)(struct VNode *vnode);
|
||||
void (*post_bitmap_layer_create)(struct VBitmapLayer *vblayer);
|
||||
void (*post_bitmap_layer_destroy)(struct VBitmapLayer *vblayer);
|
||||
void (*post_bitmap_tile_set)(struct VBitmapLayer *vblayer, unsigned int xs, unsigned int ys);
|
||||
}VBitmapData;
|
||||
|
||||
/*
|
||||
* data of geometry node
|
||||
*/
|
||||
typedef struct VGeomData {
|
||||
struct DynamicList layers; /* dynamic list with access array of Layers */
|
||||
struct VLink *vlink; /* pointer at VerseLink connecting object node and geom node */
|
||||
struct ListBase queue; /* queue of our layers waiting for receiving from verse server */
|
||||
void *mesh; /* pointer at Mesh (object node) */
|
||||
void *editmesh; /* pointer at EditMesh (edit mode) */
|
||||
/* client dependent methods */
|
||||
void (*post_vertex_create)(struct VerseVert *vvert);
|
||||
void (*post_vertex_set_xyz)(struct VerseVert *vvert);
|
||||
void (*post_vertex_delete)(struct VerseVert *vvert);
|
||||
void (*post_vertex_free_constraint)(struct VerseVert *vvert);
|
||||
void (*post_polygon_create)(struct VerseFace *vface);
|
||||
void (*post_polygon_set_corner)(struct VerseFace *vface);
|
||||
void (*post_polygon_delete)(struct VerseFace *vface);
|
||||
void (*post_polygon_free_constraint)(struct VerseFace *vface);
|
||||
void (*post_geometry_free_constraint)(struct VNode *vnode);
|
||||
void (*post_polygon_set_uint8)(struct VerseFace *vface);
|
||||
} VGeomData;
|
||||
|
||||
/*
|
||||
* data of object node
|
||||
*/
|
||||
typedef struct VObjectData {
|
||||
struct DynamicList links; /* dynamic list with access array of links between other nodes */
|
||||
struct ListBase queue; /* queue of links waiting for sending and receiving from verse server */
|
||||
float pos[3]; /* position of object VerseNode */
|
||||
float rot[4]; /* rotation of object VerseNode stored in quat */
|
||||
float scale[3]; /* scale of object VerseNode */
|
||||
void *object; /* pointer at object */
|
||||
short flag; /* flag: POS_RECEIVE_READY, ROT_RECEIVE_READY. SCALE_RECEIVE_READY */
|
||||
/* client dependent methods */
|
||||
void (*post_transform)(struct VNode *vnode);
|
||||
void (*post_object_free_constraint)(struct VNode *vnode);
|
||||
} VObjectData;
|
||||
|
||||
/*
|
||||
* Verse Tag
|
||||
*/
|
||||
typedef struct VTag {
|
||||
struct VTag *next, *prev;
|
||||
/* verse data*/
|
||||
struct VTagGroup *vtaggroup; /* pointer at Verse Tag Group */
|
||||
uint16 id; /* id of this tag */
|
||||
char *name; /* name of this tag*/
|
||||
VNTagType type; /* type: VN_TAG_BOOLEAN, VN_TAG_UINT32, VN_TAG_REAL64, VN_TAG_REAL64_VEC3,
|
||||
VN_TAG_LINK, VN_TAG_ANIMATION, VN_TAG_BLOB */
|
||||
VNTag *tag; /* pointer at value (enum: vboolean, vuint32, vreal64, vstring,
|
||||
vreal64_vec3, vlink, vanimation, vblob)*/
|
||||
/* blender internals */
|
||||
void *value; /* pointer at blender value */
|
||||
} VTag;
|
||||
|
||||
/*
|
||||
* Verse Tag Group (verse tags are grouped in tag groups)
|
||||
*/
|
||||
typedef struct VTagGroup {
|
||||
struct VTagGroup *next, *prev;
|
||||
/* verse data*/
|
||||
struct VNode *vnode; /* pointer at Verse Node */
|
||||
uint16 id; /* id of this tag group */
|
||||
char *name; /* name of this tag group */
|
||||
/* blender internals */
|
||||
struct DynamicList tags; /* dynamic list with access array containing tags */
|
||||
struct ListBase queue; /* list of tags waiting for receiving from verse server */
|
||||
/* client dependent methods */
|
||||
void (*post_tag_change)(struct VTag *vatg);
|
||||
void (*post_taggroup_create)(struct VTagGroup *vtaggroup);
|
||||
} VTagGroup;
|
||||
|
||||
/*
|
||||
* Verse Node
|
||||
*/
|
||||
typedef struct VNode {
|
||||
struct VNode *next, *prev;
|
||||
/* verse data*/
|
||||
struct VerseSession *session; /* session pointer */
|
||||
VNodeID id; /* node id */
|
||||
VNodeID owner_id; /* owner's id of this node */
|
||||
char *name; /* name of this node */
|
||||
uint32 type; /* type of node (V_NT_OBJECT, V_NT_GEOMETRY, V_NT_BITMAP) */
|
||||
/* blender internals */
|
||||
char flag; /* flags: NODE_SENT, NODE_RECEIVED, NODE_DELTED, NODE_OBSOLETE */
|
||||
struct DynamicList taggroups; /* dynamic list with access array of taggroups */
|
||||
struct ListBase queue; /* list of taggroups waiting for receiving from verse server */
|
||||
void *data; /* generic pointer at some data (VObjectData, VGeomData, ...) */
|
||||
int counter; /* counter of verse link pointing at this vnode (vlink->target) */
|
||||
/* client dependent methods */
|
||||
void (*post_node_create)(struct VNode *vnode);
|
||||
void (*post_node_destroy)(struct VNode *vnode);
|
||||
void (*post_node_name_set)(struct VNode *vnode);
|
||||
} VNode;
|
||||
|
||||
/*
|
||||
* Verse Session: verse client can be connected to several verse servers
|
||||
* it is neccessary to store some information about each session
|
||||
*/
|
||||
typedef struct VerseSession {
|
||||
struct VerseSession *next, *prev;
|
||||
/* verse data */
|
||||
VSession *vsession; /* pointer at VSeesion (verse.h) */
|
||||
uint32 avatar; /* id of avatar */
|
||||
char *address; /* string containg IP/domain name of verse server and number of port */
|
||||
void *connection; /* no clue */
|
||||
uint8 *host_id; /* no clue */
|
||||
/* blender internals */
|
||||
short flag; /* flag: VERSE_CONNECTING, VERSE_CONNECTED */
|
||||
DynamicList nodes; /* list of verse nodes */
|
||||
ListBase queue; /* list of nodes waiting for sending to verse server */
|
||||
unsigned int counter; /* count of events, when connection wasn't accepted */
|
||||
/* client dependent methods */
|
||||
void (*post_connect_accept)(struct VerseSession *session);
|
||||
void (*post_connect_terminated)(struct VerseSession *session);
|
||||
void (*post_connect_update)(struct VerseSession *session);
|
||||
} VerseSession;
|
||||
|
||||
/*
|
||||
* list of post callback functions
|
||||
*/
|
||||
typedef struct PostCallbackFunction {
|
||||
void (*function)(void *arg);
|
||||
void *param;
|
||||
} PostCallbackFunction;
|
||||
|
||||
/* VerseSession->flag */
|
||||
#define VERSE_CONNECTING 1
|
||||
#define VERSE_CONNECTED 2
|
||||
#define VERSE_AUTOSUBSCRIBE 4
|
||||
|
||||
/* max VerseSession->counter value */
|
||||
#define MAX_UNCONNECTED_EVENTS 100
|
||||
|
||||
/* VNode flags */
|
||||
#define NODE_SENT 1
|
||||
#define NODE_RECEIVED 2
|
||||
#define NODE_DELTED 4
|
||||
#define NODE_OBSOLETE 8
|
||||
|
||||
/* VLayer flags */
|
||||
#define LAYER_SENT 1
|
||||
#define LAYER_RECEIVED 2
|
||||
#define LAYER_DELETED 4
|
||||
#define LAYER_OBSOLETE 8
|
||||
|
||||
/* VLink->flag */
|
||||
#define LINK_SEND_READY 1
|
||||
|
||||
/* VObjectData->flag */
|
||||
#define POS_RECEIVE_READY 1
|
||||
#define ROT_RECEIVE_READY 2
|
||||
#define SCALE_RECEIVE_READY 4
|
||||
#define POS_SEND_READY 8
|
||||
#define ROT_SEND_READY 16
|
||||
#define SCALE_SEND_READY 32
|
||||
|
||||
/* VLayer->content */
|
||||
#define VERTEX_LAYER 0
|
||||
#define POLYGON_LAYER 1
|
||||
|
||||
/* VerseVert->flag */
|
||||
#define VERT_DELETED 1 /* vertex delete command was received from verse server */
|
||||
#define VERT_RECEIVED 2 /* VerseVert was received from verse server (is not in sending queue) */
|
||||
#define VERT_LOCKED 4 /* VerseVert is ready to send local position to verse server */
|
||||
#define VERT_POS_OBSOLETE 8 /* position of vertex was changed during sending to verse server */
|
||||
#define VERT_OBSOLETE 16 /* vertex delete command was sent to verse server; it means, that
|
||||
* no information related to this vertex shoudln't be sent to verse
|
||||
* until verse vertex is completely deleted ... then this vertex id
|
||||
* can be reused again for new vertex */
|
||||
|
||||
/* VerseFace->flag */
|
||||
#define FACE_SEND_READY 1 /* VerseFace is ready for sending to verse server */
|
||||
#define FACE_RECEIVED 2 /* VerseFace was received from verse server */
|
||||
#define FACE_SENT 4 /* VerseFace was sent to verse server and we expect receiving from verse server */
|
||||
#define FACE_DELETED 8 /* delete command was sent to verse server */
|
||||
#define FACE_CHANGED 16 /* VerseFace was only changed not created */
|
||||
#define FACE_OBSOLETE 32 /* VerseFace was changed during sending to verse server */
|
||||
|
||||
/* Queue type */
|
||||
#define VERSE_NODE 1
|
||||
#define VERSE_LINK 2
|
||||
#define VERSE_LAYER 3
|
||||
#define VERSE_VERT 4
|
||||
#define VERSE_FACE 5
|
||||
|
||||
#define VERSE_TAG 6
|
||||
#define VERSE_TAG_GROUP 7
|
||||
|
||||
#define VERSE_VERT_UINT32 8
|
||||
#define VERSE_VERT_REAL32 9
|
||||
#define VERSE_VERT_VEC_REAL32 10
|
||||
|
||||
#define VERSE_FACE_UINT8 11
|
||||
#define VERSE_FACE_UINT32 12
|
||||
#define VERSE_FACE_REAL32 13
|
||||
#define VERSE_FACE_QUAT_UINT32 14
|
||||
#define VERSE_FACE_QUAT_REAL32 15
|
||||
|
||||
/* Verse Bitmap Layer flags */
|
||||
#define VBLAYER_SUBSCRIBED 1
|
||||
|
||||
/* function prototypes */
|
||||
|
||||
/* functions from verse_session.c */
|
||||
void set_verse_session_callbacks(void);
|
||||
struct VerseSession *versesession_from_vsession(VSession *vsession);
|
||||
struct VerseSession *current_verse_session(void);
|
||||
struct VerseSession *create_verse_session(const char *name, const char *pass, const char *address, uint8 *expected_key);
|
||||
void free_verse_session(struct VerseSession *session);
|
||||
void b_verse_update(void);
|
||||
void b_verse_connect(char *address);
|
||||
void end_verse_session(struct VerseSession *session, char free);
|
||||
void end_all_verse_sessions(void);
|
||||
|
||||
/* functions from verse_node.c */
|
||||
void send_verse_tag(struct VTag *vtag);
|
||||
void send_verse_taggroup(struct VTagGroup *vtaggroup);
|
||||
void send_verse_node(struct VNode *vnode);
|
||||
void free_verse_node_data(struct VNode *vnode);
|
||||
void free_verse_node(struct VNode *vnode);
|
||||
struct VNode* create_verse_node(VerseSession *session, VNodeID node_id, uint8 type, VNodeID owner_id);
|
||||
void set_node_callbacks(void);
|
||||
|
||||
/* functions from verse_object_node.c */
|
||||
struct VLink *find_unsent_parent_vlink(struct VerseSession *session, struct VNode *vnode);
|
||||
struct VLink *find_unsent_child_vlink(struct VerseSession *session, struct VNode *vnode);
|
||||
struct VLink *create_verse_link(VerseSession *session, struct VNode *source, struct VNode *target, uint16 link_id, uint32 target_id, const char *label);
|
||||
void send_verse_object_position(struct VNode *vnode);
|
||||
void send_verse_object_rotation(struct VNode *vnode);
|
||||
void send_verse_object_scale(struct VNode *vnode);
|
||||
void send_verse_link(struct VLink *vlink);
|
||||
|
||||
void free_object_data(struct VNode *vnode);
|
||||
void set_object_callbacks(void);
|
||||
struct VObjectData *create_object_data(void);
|
||||
|
||||
/* functions from verse_geometry_node.c */
|
||||
struct VerseFace* create_verse_face(struct VLayer *vlayer, uint32 polygon_id, uint32 v0, uint32 v1, uint32 v2, uint32 v3);
|
||||
struct VerseVert* create_verse_vertex(struct VLayer *vlayer, uint32 vertex_id, real32 x, real32 y, real32 z);
|
||||
struct VLayer *create_verse_layer(struct VNode *vnode, VLayerID layer_id, const char *name, VNGLayerType type, uint32 def_integer, real64 def_real);
|
||||
struct VGeomData *create_geometry_data(void);
|
||||
|
||||
void send_verse_layer(struct VLayer *vlayer);
|
||||
|
||||
void send_verse_face_corner_quat_real32(struct quat_real32_item *item, short type);
|
||||
void send_verse_face_corner_quat_uint32(struct quat_uint32_item *item, short type);
|
||||
void send_verse_face_real32(struct real32_item *item, short type);
|
||||
void send_verse_face_uint32(struct uint32_item *item, short type);
|
||||
void send_verse_face_uint8(struct uint8_item *item, short type);
|
||||
|
||||
void send_verse_vert_vec_real32(struct vec_real32_item *item, short type);
|
||||
void send_verse_vert_real32(struct real32_item *item, short type);
|
||||
void send_verse_vert_uint32(struct uint32_item *item, short type);
|
||||
|
||||
void send_verse_vertex_delete(struct VerseVert *vvert);
|
||||
void send_verse_vertex(struct VerseVert *vvert);
|
||||
void send_verse_face_delete(struct VerseFace *vface);
|
||||
|
||||
void destroy_geometry(struct VNode *vnode);
|
||||
|
||||
struct VLayer* find_verse_layer_type(struct VGeomData *geom, short content);
|
||||
void add_item_to_send_queue(struct ListBase *lb, void *item, short type);
|
||||
void free_geom_data(struct VNode *vnode);
|
||||
void set_geometry_callbacks(void);
|
||||
|
||||
/* functions prototypes from verse_bitmap.c */
|
||||
void set_bitmap_callbacks(void);
|
||||
void free_bitmap_layer_data(struct VBitmapLayer *vblayer);
|
||||
struct VBitmapLayer *create_bitmap_layer(struct VNode *vnode, VLayerID layer_id, const char *name, VNBLayerType type);
|
||||
void free_bitmap_node_data(struct VNode *vnode);
|
||||
struct VBitmapData *create_bitmap_data(void);
|
||||
|
||||
#endif
|
@ -68,6 +68,10 @@
|
||||
#include "BKE_modifier.h"
|
||||
#include "BKE_key.h"
|
||||
|
||||
#ifdef WITH_VERSE
|
||||
#include "BKE_verse.h"
|
||||
#endif
|
||||
|
||||
#include "BIF_gl.h"
|
||||
#include "BIF_glutil.h"
|
||||
|
||||
@ -1490,6 +1494,454 @@ DerivedMesh *derivedmesh_from_displistmesh(DispListMesh *dlm, float (*vertexCos)
|
||||
return (DerivedMesh*) ssdm;
|
||||
}
|
||||
|
||||
#ifdef WITH_VERSE
|
||||
|
||||
/* verse derived mesh */
|
||||
typedef struct {
|
||||
struct DerivedMesh dm;
|
||||
struct VNode *vnode;
|
||||
struct VLayer *vertex_layer;
|
||||
struct VLayer *polygon_layer;
|
||||
float (*verts)[3];
|
||||
} VDerivedMesh;
|
||||
|
||||
/* this function set up border points of verse mesh bounding box */
|
||||
static void vDM_getMinMax(DerivedMesh *dm, float min_r[3], float max_r[3])
|
||||
{
|
||||
VDerivedMesh *vdm = (VDerivedMesh*)dm;
|
||||
struct VerseVert *vvert;
|
||||
|
||||
if(!vdm->vertex_layer) return;
|
||||
|
||||
vvert = (VerseVert*)vdm->vertex_layer->dl.lb.first;
|
||||
|
||||
if(vdm->vertex_layer->dl.da.count > 0) {
|
||||
while(vvert) {
|
||||
DO_MINMAX(vdm->verts ? vvert->cos : vvert->co, min_r, max_r);
|
||||
vvert = vvert->next;
|
||||
}
|
||||
}
|
||||
else {
|
||||
min_r[0] = min_r[1] = min_r[2] = max_r[0] = max_r[1] = max_r[2] = 0.0;
|
||||
}
|
||||
}
|
||||
|
||||
/* this function return number of vertexes in vertex layer */
|
||||
static int vDM_getNumVerts(DerivedMesh *dm)
|
||||
{
|
||||
VDerivedMesh *vdm = (VDerivedMesh*)dm;
|
||||
|
||||
if(!vdm->vertex_layer) return 0;
|
||||
else return vdm->vertex_layer->dl.da.count;
|
||||
}
|
||||
|
||||
/* this function returns number of polygons in polygon layer */
|
||||
static int vDM_getNumFaces(DerivedMesh *dm)
|
||||
{
|
||||
VDerivedMesh *vdm = (VDerivedMesh*)dm;
|
||||
|
||||
if(!vdm->polygon_layer) return 0;
|
||||
else return vdm->polygon_layer->dl.da.count;
|
||||
}
|
||||
|
||||
/* create diplist mesh from verse mesh */
|
||||
static DispListMesh* vDM_convertToDispListMesh(DerivedMesh *dm, int allowShared)
|
||||
{
|
||||
VDerivedMesh *vdm = (VDerivedMesh*)dm;
|
||||
DispListMesh *dlm = MEM_callocN(sizeof(*dlm), "dlm");
|
||||
struct VerseVert *vvert;
|
||||
struct VerseFace *vface;
|
||||
struct MVert *mvert=NULL;
|
||||
struct MFace *mface=NULL;
|
||||
float *norms;
|
||||
unsigned int i;
|
||||
|
||||
if(!vdm->vertex_layer || !vdm->polygon_layer) {
|
||||
dlm->totvert = 0;
|
||||
dlm->totedge = 0;
|
||||
dlm->totface = 0;
|
||||
dlm->dontFreeVerts = dlm->dontFreeOther = dlm->dontFreeNors = 0;
|
||||
|
||||
return dlm;
|
||||
};
|
||||
|
||||
/* number of vertexes, edges and faces */
|
||||
dlm->totvert = vdm->vertex_layer->dl.da.count;
|
||||
dlm->totedge = 0;
|
||||
dlm->totface = vdm->polygon_layer->dl.da.count;
|
||||
|
||||
/* create dynamic array of mverts */
|
||||
mvert = (MVert*)MEM_mallocN(sizeof(MVert)*dlm->totvert, "dlm verts");
|
||||
dlm->mvert = mvert;
|
||||
vvert = (VerseVert*)vdm->vertex_layer->dl.lb.first;
|
||||
i = 0;
|
||||
while(vvert) {
|
||||
VECCOPY(mvert->co, vdm->verts ? vvert->cos : vvert->co);
|
||||
VECCOPY(mvert->no, vvert->no);
|
||||
mvert->mat_nr = 0;
|
||||
mvert->flag = 0;
|
||||
|
||||
vvert->tmp.index = i++;
|
||||
mvert++;
|
||||
vvert = vvert->next;
|
||||
}
|
||||
|
||||
/* verse doesn't support edges */
|
||||
dlm->medge = NULL;
|
||||
|
||||
/* create dynamic array of faces */
|
||||
mface = (MFace*)MEM_mallocN(sizeof(MFace)*dlm->totface, "dlm faces");
|
||||
dlm->mface = mface;
|
||||
vface = (VerseFace*)vdm->polygon_layer->dl.lb.first;
|
||||
i = 0;
|
||||
while(vface) {
|
||||
mface->v1 = vface->vvert0->tmp.index;
|
||||
mface->v2 = vface->vvert1->tmp.index;
|
||||
mface->v3 = vface->vvert2->tmp.index;
|
||||
if(vface->vvert3) mface->v4 = vface->vvert3->tmp.index;
|
||||
else mface->v4 = 0;
|
||||
|
||||
mface->pad = 0;
|
||||
mface->mat_nr = 0;
|
||||
mface->flag = 0;
|
||||
mface->edcode = 0;
|
||||
|
||||
test_index_face(mface, NULL, NULL, vface->vvert3?4:3);
|
||||
|
||||
mface++;
|
||||
vface = vface->next;
|
||||
}
|
||||
|
||||
/* textures and verex colors aren't supported yet */
|
||||
dlm->tface = NULL;
|
||||
dlm->mcol = NULL;
|
||||
|
||||
/* faces normals */
|
||||
norms = (float*)MEM_mallocN(sizeof(float)*3*dlm->totface, "dlm norms");
|
||||
dlm->nors = norms;
|
||||
|
||||
vface = (VerseFace*)vdm->polygon_layer->dl.lb.first;
|
||||
while(vface){
|
||||
VECCOPY(norms, vface->no);
|
||||
norms += 3;
|
||||
vface = vface->next;
|
||||
}
|
||||
|
||||
/* free everything, nothing is shared */
|
||||
dlm->dontFreeVerts = dlm->dontFreeOther = dlm->dontFreeNors = 0;
|
||||
|
||||
return dlm;
|
||||
}
|
||||
|
||||
/* return coordination of vertex with index ... I suppose, that it will
|
||||
* be very hard to do, becuase there can be holes in access array */
|
||||
static void vDM_getVertCo(DerivedMesh *dm, int index, float co_r[3])
|
||||
{
|
||||
VDerivedMesh *vdm = (VDerivedMesh*)dm;
|
||||
struct VerseVert *vvert = NULL;
|
||||
|
||||
if(!vdm->vertex_layer) return;
|
||||
|
||||
vvert = BLI_dlist_find_link(&(vdm->vertex_layer->dl), index);
|
||||
if(vvert) {
|
||||
VECCOPY(co_r, vdm->verts ? vvert->cos : vvert->co);
|
||||
}
|
||||
else {
|
||||
co_r[0] = co_r[1] = co_r[2] = 0.0;
|
||||
}
|
||||
}
|
||||
|
||||
/* return array of vertex coordiantions */
|
||||
static void vDM_getVertCos(DerivedMesh *dm, float (*cos_r)[3])
|
||||
{
|
||||
VDerivedMesh *vdm = (VDerivedMesh*)dm;
|
||||
struct VerseVert *vvert;
|
||||
int i = 0;
|
||||
|
||||
if(!vdm->vertex_layer) return;
|
||||
|
||||
vvert = vdm->vertex_layer->dl.lb.first;
|
||||
while(vvert) {
|
||||
VECCOPY(cos_r[i], vdm->verts ? vvert->cos : vvert->co);
|
||||
i++;
|
||||
vvert = vvert->next;
|
||||
}
|
||||
}
|
||||
|
||||
/* return normal of vertex with index ... again, it will be hard to
|
||||
* implemente, because access array */
|
||||
static void vDM_getVertNo(DerivedMesh *dm, int index, float no_r[3])
|
||||
{
|
||||
VDerivedMesh *vdm = (VDerivedMesh*)dm;
|
||||
struct VerseVert *vvert = NULL;
|
||||
|
||||
if(!vdm->vertex_layer) return;
|
||||
|
||||
vvert = BLI_dlist_find_link(&(vdm->vertex_layer->dl), index);
|
||||
if(vvert) {
|
||||
VECCOPY(no_r, vvert->no);
|
||||
}
|
||||
else {
|
||||
no_r[0] = no_r[1] = no_r[2] = 0.0;
|
||||
}
|
||||
}
|
||||
|
||||
/* draw all VerseVertexes */
|
||||
static void vDM_drawVerts(DerivedMesh *dm)
|
||||
{
|
||||
VDerivedMesh *vdm = (VDerivedMesh*)dm;
|
||||
struct VerseVert *vvert;
|
||||
|
||||
if(!vdm->vertex_layer) return;
|
||||
|
||||
vvert = vdm->vertex_layer->dl.lb.first;
|
||||
|
||||
bglBegin(GL_POINTS);
|
||||
while(vvert) {
|
||||
bglVertex3fv(vdm->verts ? vvert->cos : vvert->co);
|
||||
vvert = vvert->next;
|
||||
}
|
||||
bglEnd();
|
||||
}
|
||||
|
||||
/* draw all edges of VerseFaces ... it isn't optimal, because verse
|
||||
* specification doesn't support edges :-( ... bother eskil ;-)
|
||||
* ... some edges (most of edges) are drawn twice */
|
||||
static void vDM_drawEdges(DerivedMesh *dm, int drawLooseEdges)
|
||||
{
|
||||
VDerivedMesh *vdm = (VDerivedMesh*)dm;
|
||||
struct VerseFace *vface;
|
||||
|
||||
if(!vdm->polygon_layer) return;
|
||||
|
||||
vface = vdm->polygon_layer->dl.lb.first;
|
||||
|
||||
while(vface) {
|
||||
glBegin(GL_LINE_LOOP);
|
||||
glVertex3fv(vdm->verts ? vface->vvert0->cos : vface->vvert0->co);
|
||||
glVertex3fv(vdm->verts ? vface->vvert1->cos : vface->vvert1->co);
|
||||
glVertex3fv(vdm->verts ? vface->vvert2->cos : vface->vvert2->co);
|
||||
if(vface->vvert3) glVertex3fv(vdm->verts ? vface->vvert3->cos : vface->vvert3->co);
|
||||
glEnd();
|
||||
|
||||
vface = vface->next;
|
||||
}
|
||||
}
|
||||
|
||||
/* verse spec doesn't support edges ... loose edges can't exist */
|
||||
void vDM_drawLooseEdges(DerivedMesh *dm)
|
||||
{
|
||||
}
|
||||
|
||||
/* draw uv edges, not supported yet */
|
||||
static void vDM_drawUVEdges(DerivedMesh *dm)
|
||||
{
|
||||
}
|
||||
|
||||
/* draw all VerseFaces */
|
||||
static void vDM_drawFacesSolid(DerivedMesh *dm, int (*setMaterial)(int))
|
||||
{
|
||||
VDerivedMesh *vdm = (VDerivedMesh*)dm;
|
||||
struct VerseFace *vface;
|
||||
|
||||
if(!vdm->polygon_layer) return;
|
||||
|
||||
vface = vdm->polygon_layer->dl.lb.first;
|
||||
|
||||
while(vface) {
|
||||
/* if((vface->smooth) && (vface->smooth->value)){
|
||||
glShadeModel(GL_SMOOTH);
|
||||
glBegin(vface->vvert3?GL_QUADS:GL_TRIANGLES);
|
||||
glNormal3fv(vface->vvert0->no);
|
||||
glVertex3fv(vdm->verts ? vface->vvert0->cos : vface->vvert0->co);
|
||||
glNormal3fv(vface->vvert1->no);
|
||||
glVertex3fv(vdm->verts ? vface->vvert1->cos : vface->vvert1->co);
|
||||
glNormal3fv(vface->vvert2->no);
|
||||
glVertex3fv(vdm->verts ? vface->vvert2->cos : vface->vvert2->co);
|
||||
if(vface->vvert3){
|
||||
glNormal3fv(vface->vvert3->no);
|
||||
glVertex3fv(vdm->verts ? vface->vvert3->cos : vface->vvert3->co);
|
||||
}
|
||||
glEnd();
|
||||
}
|
||||
else { */
|
||||
glShadeModel(GL_FLAT);
|
||||
glBegin(vface->vvert3?GL_QUADS:GL_TRIANGLES);
|
||||
glNormal3fv(vface->no);
|
||||
glVertex3fv(vdm->verts ? vface->vvert0->cos : vface->vvert0->co);
|
||||
glVertex3fv(vdm->verts ? vface->vvert1->cos : vface->vvert1->co);
|
||||
glVertex3fv(vdm->verts ? vface->vvert2->cos : vface->vvert2->co);
|
||||
if(vface->vvert3)
|
||||
glVertex3fv(vdm->verts ? vface->vvert3->cos : vface->vvert3->co);
|
||||
glEnd();
|
||||
/* } */
|
||||
|
||||
vface = vface->next;
|
||||
}
|
||||
glShadeModel(GL_FLAT);
|
||||
}
|
||||
|
||||
/* this function should draw mesh with colored faces (weight paint, vertex
|
||||
* colors, etc.), but it isn't supported yet */
|
||||
static void vDM_drawFacesColored(DerivedMesh *dm, int useTwoSided, unsigned char *col1, unsigned char *col2)
|
||||
{
|
||||
VDerivedMesh *vdm = (VDerivedMesh*)dm;
|
||||
struct VerseFace *vface;
|
||||
|
||||
if(!vdm->polygon_layer) return;
|
||||
|
||||
vface = vdm->polygon_layer->dl.lb.first;
|
||||
|
||||
while(vface) {
|
||||
glBegin(vface->vvert3?GL_QUADS:GL_TRIANGLES);
|
||||
glVertex3fv(vdm->verts ? vface->vvert0->cos : vface->vvert0->co);
|
||||
glVertex3fv(vdm->verts ? vface->vvert1->cos : vface->vvert1->co);
|
||||
glVertex3fv(vdm->verts ? vface->vvert2->cos : vface->vvert2->co);
|
||||
if(vface->vvert3)
|
||||
glVertex3fv(vdm->verts ? vface->vvert3->cos : vface->vvert3->co);
|
||||
glEnd();
|
||||
|
||||
vface = vface->next;
|
||||
}
|
||||
}
|
||||
|
||||
/**/
|
||||
static void vDM_foreachMappedVert(
|
||||
DerivedMesh *dm,
|
||||
void (*func)(void *userData, int index, float *co, float *no_f, short *no_s),
|
||||
void *userData)
|
||||
{
|
||||
}
|
||||
|
||||
/**/
|
||||
static void vDM_foreachMappedEdge(
|
||||
DerivedMesh *dm,
|
||||
void (*func)(void *userData, int index, float *v0co, float *v1co),
|
||||
void *userData)
|
||||
{
|
||||
}
|
||||
|
||||
/**/
|
||||
static void vDM_foreachMappedFaceCenter(
|
||||
DerivedMesh *dm,
|
||||
void (*func)(void *userData, int index, float *cent, float *no),
|
||||
void *userData)
|
||||
{
|
||||
}
|
||||
|
||||
/**/
|
||||
static void vDM_drawMappedFacesTex(
|
||||
DerivedMesh *dm,
|
||||
int (*setDrawOptions)(void *userData, int index, int matnr),
|
||||
void *userData)
|
||||
{
|
||||
}
|
||||
|
||||
/**/
|
||||
static void vDM_drawMappedFaces(
|
||||
DerivedMesh *dm,
|
||||
int (*setDrawOptions)(void *userData, int index, int *drawSmooth_r),
|
||||
void *userData,
|
||||
int useColors)
|
||||
{
|
||||
}
|
||||
|
||||
/**/
|
||||
static void vDM_drawMappedEdges(
|
||||
DerivedMesh *dm,
|
||||
int (*setDrawOptions)(void *userData, int index),
|
||||
void *userData)
|
||||
{
|
||||
}
|
||||
|
||||
/**/
|
||||
static void vDM_drawMappedEdgesInterp(
|
||||
DerivedMesh *dm,
|
||||
int (*setDrawOptions)(void *userData, int index),
|
||||
void (*setDrawInterpOptions)(void *userData, int index, float t),
|
||||
void *userData)
|
||||
{
|
||||
}
|
||||
|
||||
/* free all DerivedMesh data */
|
||||
static void vDM_release(DerivedMesh *dm)
|
||||
{
|
||||
VDerivedMesh *vdm = (VDerivedMesh*)dm;
|
||||
|
||||
if(vdm->verts) MEM_freeN(vdm->verts);
|
||||
MEM_freeN(vdm);
|
||||
}
|
||||
|
||||
/* create derived mesh from verse mesh ... it is used in object mode, when some other client can
|
||||
* change shared data and want to see this changes in real time too */
|
||||
DerivedMesh *derivedmesh_from_versemesh(VNode *vnode, float (*vertexCos)[3])
|
||||
{
|
||||
VDerivedMesh *vdm = MEM_callocN(sizeof(*vdm), "vdm");
|
||||
struct VerseVert *vvert;
|
||||
|
||||
vdm->vnode = vnode;
|
||||
vdm->vertex_layer = find_verse_layer_type((VGeomData*)vnode->data, VERTEX_LAYER);
|
||||
vdm->polygon_layer = find_verse_layer_type((VGeomData*)vnode->data, POLYGON_LAYER);
|
||||
|
||||
vdm->dm.getMinMax = vDM_getMinMax;
|
||||
|
||||
vdm->dm.getNumVerts = vDM_getNumVerts;
|
||||
vdm->dm.getNumFaces = vDM_getNumFaces;
|
||||
|
||||
vdm->dm.foreachMappedVert = vDM_foreachMappedVert;
|
||||
vdm->dm.foreachMappedEdge = vDM_foreachMappedEdge;
|
||||
vdm->dm.foreachMappedFaceCenter = vDM_foreachMappedFaceCenter;
|
||||
|
||||
vdm->dm.convertToDispListMesh = vDM_convertToDispListMesh;
|
||||
|
||||
vdm->dm.getVertCos = vDM_getVertCos;
|
||||
vdm->dm.getVertCo = vDM_getVertCo;
|
||||
vdm->dm.getVertNo = vDM_getVertNo;
|
||||
|
||||
vdm->dm.drawVerts = vDM_drawVerts;
|
||||
|
||||
vdm->dm.drawEdges = vDM_drawEdges;
|
||||
vdm->dm.drawLooseEdges = vDM_drawLooseEdges;
|
||||
vdm->dm.drawUVEdges = vDM_drawUVEdges;
|
||||
|
||||
vdm->dm.drawFacesSolid = vDM_drawFacesSolid;
|
||||
vdm->dm.drawFacesColored = vDM_drawFacesColored;
|
||||
|
||||
vdm->dm.drawMappedFacesTex = vDM_drawMappedFacesTex;
|
||||
vdm->dm.drawMappedFaces = vDM_drawMappedFaces;
|
||||
vdm->dm.drawMappedEdges = vDM_drawMappedEdges;
|
||||
vdm->dm.drawMappedEdgesInterp = vDM_drawMappedEdgesInterp;
|
||||
|
||||
vdm->dm.release = vDM_release;
|
||||
|
||||
if(vdm->vertex_layer) {
|
||||
if(vertexCos) {
|
||||
int i;
|
||||
|
||||
vdm->verts = MEM_mallocN(sizeof(float)*3*vdm->vertex_layer->dl.da.count, "verse mod vertexes");
|
||||
vvert = vdm->vertex_layer->dl.lb.first;
|
||||
|
||||
for(i=0; i<vdm->vertex_layer->dl.da.count && vvert; i++, vvert = vvert->next) {
|
||||
VECCOPY(vdm->verts[i], vertexCos[i]);
|
||||
vvert->cos = vdm->verts[i];
|
||||
}
|
||||
}
|
||||
else {
|
||||
vdm->verts = NULL;
|
||||
vvert = vdm->vertex_layer->dl.lb.first;
|
||||
|
||||
while(vvert) {
|
||||
vvert->cos = NULL;
|
||||
vvert = vvert->next;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return (DerivedMesh*) vdm;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/***/
|
||||
|
||||
DerivedMesh *mesh_create_derived_for_modifier(Object *ob, ModifierData *md)
|
||||
@ -1506,8 +1958,13 @@ DerivedMesh *mesh_create_derived_for_modifier(Object *ob, ModifierData *md)
|
||||
float (*deformedVerts)[3] = mesh_getVertexCos(me, &numVerts);
|
||||
|
||||
mti->deformVerts(md, ob, NULL, deformedVerts, numVerts);
|
||||
|
||||
#ifdef WITH_VERSE
|
||||
if(me->vnode) dm = derivedmesh_from_versemesh(me->vnode, deformedVerts);
|
||||
else dm = getMeshDerivedMesh(me, ob, deformedVerts);
|
||||
#else
|
||||
dm = getMeshDerivedMesh(me, ob, deformedVerts);
|
||||
#endif
|
||||
|
||||
MEM_freeN(deformedVerts);
|
||||
} else {
|
||||
dm = mti->applyModifier(md, ob, NULL, NULL, 0, 0);
|
||||
@ -1566,7 +2023,13 @@ static void mesh_calc_modifiers(Object *ob, float (*inputVertexCos)[3], DerivedM
|
||||
* places that wish to use the original mesh but with deformed
|
||||
* coordinates (vpaint, etc.)
|
||||
*/
|
||||
if (deform_r) *deform_r = getMeshDerivedMesh(me, ob, deformedVerts);
|
||||
if (deform_r)
|
||||
#ifdef WITH_VERSE
|
||||
if(me->vnode) *deform_r = derivedmesh_from_versemesh(me->vnode, deformedVerts);
|
||||
else *deform_r = getMeshDerivedMesh(me, ob, deformedVerts);
|
||||
#else
|
||||
*deform_r = getMeshDerivedMesh(me, ob, deformedVerts);
|
||||
#endif
|
||||
} else {
|
||||
if(!fluidsimMeshUsed) {
|
||||
// default behaviour for meshes
|
||||
@ -1651,7 +2114,12 @@ static void mesh_calc_modifiers(Object *ob, float (*inputVertexCos)[3], DerivedM
|
||||
} else if (dm) {
|
||||
*final_r = dm;
|
||||
} else {
|
||||
#ifdef WITH_VERSE
|
||||
if(me->vnode) *final_r = derivedmesh_from_versemesh(me->vnode, deformedVerts);
|
||||
else *final_r = getMeshDerivedMesh(me, ob, deformedVerts);
|
||||
#else
|
||||
*final_r = getMeshDerivedMesh(me, ob, deformedVerts);
|
||||
#endif
|
||||
}
|
||||
|
||||
if (deformedVerts && deformedVerts!=inputVertexCos) {
|
||||
|
@ -84,6 +84,11 @@ ifeq ($(WITH_FREETYPE2), true)
|
||||
CPPFLAGS += -I$(NAN_FREETYPE)/include/freetype2
|
||||
endif
|
||||
|
||||
ifeq ($(WITH_VERSE), true)
|
||||
CPPFLAGS += -DWITH_VERSE
|
||||
CPPFLAGS += -I$(NAN_VERSE)/include
|
||||
endif
|
||||
|
||||
ifeq ($(WITH_FFMPEG),true)
|
||||
CPPFLAGS += -DWITH_FFMPEG
|
||||
CPPFLAGS += $(NAN_FFMPEGCFLAGS)
|
||||
|
@ -71,6 +71,10 @@
|
||||
#include "BKE_utildefines.h"
|
||||
#include "BKE_bad_level_calls.h"
|
||||
|
||||
#ifdef WITH_VERSE
|
||||
#include "BKE_verse.h"
|
||||
#endif
|
||||
|
||||
#include "BLI_blenlib.h"
|
||||
#include "BLI_editVert.h"
|
||||
#include "BLI_arithb.h"
|
||||
@ -199,7 +203,11 @@ Mesh *add_mesh()
|
||||
me->texflag= AUTOSPACE;
|
||||
me->flag= ME_TWOSIDED;
|
||||
me->bb= unit_boundbox();
|
||||
|
||||
|
||||
#ifdef WITH_VERSE
|
||||
me->vnode = NULL;
|
||||
#endif
|
||||
|
||||
return me;
|
||||
}
|
||||
|
||||
@ -234,7 +242,11 @@ Mesh *copy_mesh(Mesh *me)
|
||||
|
||||
men->key= copy_key(me->key);
|
||||
if(men->key) men->key->from= (ID *)men;
|
||||
|
||||
|
||||
#ifdef WITH_VERSE
|
||||
men->vnode = NULL;
|
||||
#endif
|
||||
|
||||
return men;
|
||||
}
|
||||
|
||||
@ -1073,15 +1085,39 @@ void mesh_calc_normals(MVert *mverts, int numVerts, MFace *mfaces, int numFaces,
|
||||
|
||||
float (*mesh_getVertexCos(Mesh *me, int *numVerts_r))[3]
|
||||
{
|
||||
int i, numVerts = me->totvert;
|
||||
float (*cos)[3] = MEM_mallocN(sizeof(*cos)*numVerts, "vertexcos1");
|
||||
#ifdef WITH_VERSE
|
||||
if(me->vnode) {
|
||||
struct VLayer *vlayer;
|
||||
struct VerseVert *vvert;
|
||||
unsigned int i, numVerts;
|
||||
float (*cos)[3];
|
||||
|
||||
if (numVerts_r) *numVerts_r = numVerts;
|
||||
for (i=0; i<numVerts; i++) {
|
||||
VECCOPY(cos[i], me->mvert[i].co);
|
||||
vlayer = find_verse_layer_type((VGeomData*)((VNode*)me->vnode)->data, VERTEX_LAYER);
|
||||
|
||||
vvert = vlayer->dl.lb.first;
|
||||
numVerts = vlayer->dl.da.count;
|
||||
cos = MEM_mallocN(sizeof(*cos)*numVerts, "verse_vertexcos");
|
||||
|
||||
for(i=0; i<numVerts && vvert; vvert = vvert->next, i++) {
|
||||
VECCOPY(cos[i], vvert->co);
|
||||
}
|
||||
|
||||
return cos;
|
||||
}
|
||||
|
||||
return cos;
|
||||
else {
|
||||
#endif
|
||||
int i, numVerts = me->totvert;
|
||||
float (*cos)[3] = MEM_mallocN(sizeof(*cos)*numVerts, "vertexcos1");
|
||||
|
||||
if (numVerts_r) *numVerts_r = numVerts;
|
||||
for (i=0; i<numVerts; i++) {
|
||||
VECCOPY(cos[i], me->mvert[i].co);
|
||||
}
|
||||
|
||||
return cos;
|
||||
#ifdef WITH_VERSE
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/* UvVertMap */
|
||||
|
@ -910,6 +910,11 @@ Object *copy_object(Object *ob)
|
||||
obn->derivedDeform = NULL;
|
||||
obn->derivedFinal = NULL;
|
||||
|
||||
#ifdef WITH_VERSE
|
||||
obn->vnode = NULL;
|
||||
#endif
|
||||
|
||||
|
||||
return obn;
|
||||
}
|
||||
|
||||
|
449
source/blender/blenkernel/intern/verse_bitmap_node.c
Normal file
449
source/blender/blenkernel/intern/verse_bitmap_node.c
Normal file
@ -0,0 +1,449 @@
|
||||
/**
|
||||
* $Id$
|
||||
*
|
||||
* ***** BEGIN GPL/BL DUAL 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. The Blender
|
||||
* Foundation also sells licenses for use in proprietary software under
|
||||
* the Blender License. See http://www.blender.org/BL/ for information
|
||||
* about this.
|
||||
*
|
||||
* 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/BL DUAL LICENSE BLOCK *****
|
||||
*/
|
||||
|
||||
#ifdef WITH_VERSE
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "MEM_guardedalloc.h"
|
||||
|
||||
#include "DNA_listBase.h"
|
||||
|
||||
#include "BLI_dynamiclist.h"
|
||||
#include "BLI_blenlib.h"
|
||||
|
||||
#include "BIF_verse.h"
|
||||
|
||||
#include "BKE_verse.h"
|
||||
|
||||
#include "verse.h"
|
||||
|
||||
/* function prototypes of static functions */
|
||||
static void cb_b_dimension_set(void *user_data, VNodeID node_id, uint16 width, uint16 height, uint16 depth);
|
||||
static void cb_b_layer_create(void *user_data, VNodeID node_id, VLayerID layer_id, const char *name, VNBLayerType type);
|
||||
static void cb_b_layer_destroy(void *user_data, VNodeID node_id, VLayerID layer_id);
|
||||
static void cb_b_tile_set(void *user_data, VNodeID node_id, VLayerID layer_id, uint16 tile_x, uint16 tile_y, uint16 z, VNBLayerType type, const VNBTile *tile);
|
||||
|
||||
static void change_layer_dimension(
|
||||
VBitmapLayer *vblayer,
|
||||
unsigned int old_width,
|
||||
unsigned int old_height,
|
||||
unsigned int t_old_width,
|
||||
unsigned int t_old_height);
|
||||
static void *alloc_verse_bitmap_layer_data(struct VBitmapLayer *vblayer);
|
||||
|
||||
/*
|
||||
* resize/crop verse bitmap layer
|
||||
*/
|
||||
static void change_layer_dimension(
|
||||
VBitmapLayer *vblayer,
|
||||
unsigned int old_width,
|
||||
unsigned int old_height,
|
||||
unsigned int t_old_width,
|
||||
unsigned int t_old_height)
|
||||
{
|
||||
struct VNode *vnode = vblayer->vnode;
|
||||
unsigned int t_width = ((VBitmapData*)(vnode->data))->t_width;
|
||||
unsigned int t_height = ((VBitmapData*)(vnode->data))->t_height;
|
||||
unsigned int width = ((VBitmapData*)(vnode->data))->width;
|
||||
unsigned int height = ((VBitmapData*)(vnode->data))->height;
|
||||
unsigned int x, y, i, j;
|
||||
|
||||
i = j = 0;
|
||||
|
||||
/* "copy" old data to new data */
|
||||
if(vblayer->type==VN_B_LAYER_UINT8) {
|
||||
unsigned char *data = (unsigned char*)vblayer->data;
|
||||
/* allocate new verse bitmap layer data */
|
||||
unsigned char *new_data = (unsigned char*)alloc_verse_bitmap_layer_data(vblayer);
|
||||
for(y=0; y<old_height && y<height; y++, i=y*t_width, j=y*t_old_width) {
|
||||
for(x=0; x<old_width && y<width; x++, i++, j++) {
|
||||
new_data[i] = data[j];
|
||||
}
|
||||
}
|
||||
MEM_freeN(vblayer->data);
|
||||
vblayer->data = new_data;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* free data stored in verse bitmap layer
|
||||
*/
|
||||
void free_bitmap_layer_data(VBitmapLayer *vblayer)
|
||||
{
|
||||
struct VerseSession *session = vblayer->vnode->session;
|
||||
|
||||
/* free name of bitmap layer */
|
||||
MEM_freeN(vblayer->name);
|
||||
|
||||
/* unsubscribe from verse bitmap layer */
|
||||
if(session->flag & VERSE_CONNECTED)
|
||||
verse_send_b_layer_unsubscribe(vblayer->vnode->id, vblayer->id);
|
||||
|
||||
/* free image data of bitmap layer */
|
||||
if(vblayer->data) MEM_freeN(vblayer->data);
|
||||
}
|
||||
|
||||
/*
|
||||
* allocate data of verse bitmap layer
|
||||
*/
|
||||
static void *alloc_verse_bitmap_layer_data(VBitmapLayer *vblayer)
|
||||
{
|
||||
struct VNode *vnode = vblayer->vnode;
|
||||
unsigned int t_width = ((VBitmapData*)(vnode->data))->t_width;
|
||||
unsigned int t_height = ((VBitmapData*)(vnode->data))->t_height;
|
||||
unsigned int size;
|
||||
void *data;
|
||||
|
||||
size = t_width*t_height;
|
||||
|
||||
/* allocation of own data stored in verse bitmap layer */
|
||||
switch (vblayer->type) {
|
||||
case VN_B_LAYER_UINT1:
|
||||
data = (void*)MEM_mallocN(sizeof(unsigned char)*size, "VBLayer data uint1");
|
||||
break;
|
||||
case VN_B_LAYER_UINT8:
|
||||
data = (void*)MEM_mallocN(sizeof(unsigned char)*size, "VBLayer data uint8");
|
||||
break;
|
||||
case VN_B_LAYER_UINT16:
|
||||
data = (void*)MEM_mallocN(sizeof(unsigned int)*size, "VBLayer data uint16");
|
||||
break;
|
||||
case VN_B_LAYER_REAL32:
|
||||
data = (void*)MEM_mallocN(sizeof(float)*size, "VBLayer data float16");
|
||||
break;
|
||||
case VN_B_LAYER_REAL64:
|
||||
data = (void*)MEM_mallocN(sizeof(double)*size, "VBLayer data float32");
|
||||
break;
|
||||
}
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
/*
|
||||
* create verse bitmap layer
|
||||
*/
|
||||
VBitmapLayer *create_bitmap_layer(
|
||||
VNode *vnode,
|
||||
VLayerID layer_id,
|
||||
const char *name,
|
||||
VNBLayerType type)
|
||||
{
|
||||
struct VBitmapLayer *vblayer;
|
||||
unsigned int width = ((VBitmapData*)(vnode->data))->width;
|
||||
unsigned int height = ((VBitmapData*)(vnode->data))->height;
|
||||
|
||||
/* allocate memory for own verse bitmap layer */
|
||||
vblayer = (VBitmapLayer*)MEM_mallocN(sizeof(VBitmapLayer), "Verse Bitmap Layer");
|
||||
|
||||
/* verse bitmap layer will include pointer at parent verse node and own id */
|
||||
vblayer->vnode = vnode;
|
||||
vblayer->id = layer_id;
|
||||
|
||||
/* name of verse layer */
|
||||
vblayer->name = (char*)MEM_mallocN(sizeof(char)*(strlen(name)+1), "Verse Bitmap Layer name");
|
||||
vblayer->name[0] = '\0';
|
||||
strcpy(vblayer->name, name);
|
||||
|
||||
/* type of data stored in verse bitmap layer */
|
||||
vblayer->type = type;
|
||||
|
||||
/* we can allocate memory for layer data, when we know dimmension of layers; when
|
||||
* we don't know it, then we will allocate this data when we will receive dimmension */
|
||||
if(width==0 || height==0)
|
||||
vblayer->data = NULL;
|
||||
else
|
||||
vblayer->data = alloc_verse_bitmap_layer_data(vblayer);
|
||||
|
||||
vblayer->flag = 0;
|
||||
|
||||
return vblayer;
|
||||
}
|
||||
|
||||
/*
|
||||
* free data of bitmap node
|
||||
*/
|
||||
void free_bitmap_node_data(VNode *vnode)
|
||||
{
|
||||
if(vnode->data) {
|
||||
struct VBitmapLayer *vblayer = (VBitmapLayer*)((VBitmapData*)(vnode->data))->layers.lb.first;
|
||||
|
||||
/* free all VerseLayer data */
|
||||
while(vblayer) {
|
||||
free_bitmap_layer_data(vblayer);
|
||||
vblayer = vblayer->next;
|
||||
}
|
||||
|
||||
/* free all VerseLayers */
|
||||
BLI_dlist_destroy(&(((VGeomData*)vnode->data)->layers));
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* create data of bitmap node
|
||||
*/
|
||||
VBitmapData *create_bitmap_data()
|
||||
{
|
||||
struct VBitmapData *vbitmap;
|
||||
|
||||
vbitmap = (VBitmapData*)MEM_mallocN(sizeof(VBitmapData), "Verse Bitmap Data");
|
||||
|
||||
BLI_dlist_init(&(vbitmap->layers));
|
||||
vbitmap->queue.first = vbitmap->queue.last = NULL;
|
||||
|
||||
vbitmap->width = 0;
|
||||
vbitmap->height = 0;
|
||||
vbitmap->depth = 0;
|
||||
|
||||
vbitmap->image = NULL;
|
||||
|
||||
vbitmap->post_bitmap_dimension_set = post_bitmap_dimension_set;
|
||||
vbitmap->post_bitmap_layer_create = post_bitmap_layer_create;
|
||||
vbitmap->post_bitmap_layer_destroy = post_bitmap_layer_destroy;
|
||||
vbitmap->post_bitmap_tile_set = post_bitmap_tile_set;
|
||||
|
||||
return vbitmap;
|
||||
}
|
||||
|
||||
/*
|
||||
* callback function, dimension of image was changed, it is neccessary to
|
||||
* crop all layers
|
||||
*/
|
||||
static void cb_b_dimension_set(
|
||||
void *user_data,
|
||||
VNodeID node_id,
|
||||
uint16 width,
|
||||
uint16 height,
|
||||
uint16 depth)
|
||||
{
|
||||
struct VerseSession *session = (VerseSession*)current_verse_session();
|
||||
struct VNode *vnode;
|
||||
struct VBitmapLayer *vblayer;
|
||||
unsigned int old_width, old_height, t_old_width, t_old_height;
|
||||
|
||||
if(!session) return;
|
||||
|
||||
vnode = (VNode*)BLI_dlist_find_link(&(session->nodes), (unsigned int)node_id);
|
||||
if(!vnode) return;
|
||||
|
||||
#ifdef VERSE_DEBUG_PRINT
|
||||
printf("\t cb_b_dimension_set()\n");
|
||||
#endif
|
||||
|
||||
/* backup old width and height */
|
||||
old_width = ((VBitmapData*)(vnode->data))->width;
|
||||
old_height = ((VBitmapData*)(vnode->data))->height;
|
||||
t_old_width = ((VBitmapData*)(vnode->data))->t_width;
|
||||
t_old_height = ((VBitmapData*)(vnode->data))->t_height;
|
||||
|
||||
/* set up new dimension of layers */
|
||||
((VBitmapData*)(vnode->data))->width = width;
|
||||
((VBitmapData*)(vnode->data))->height = height;
|
||||
((VBitmapData*)(vnode->data))->depth = depth;
|
||||
|
||||
/* we cache t_width because tiles aren't one pixel width */
|
||||
if((width % VN_B_TILE_SIZE)!=0)
|
||||
((VBitmapData*)(vnode->data))->t_width = (width/VN_B_TILE_SIZE + 1)*VN_B_TILE_SIZE;
|
||||
else
|
||||
((VBitmapData*)(vnode->data))->t_width = width;
|
||||
|
||||
/* we cache t_height because tiles aren't one pixel height */
|
||||
if((height % VN_B_TILE_SIZE)!=0)
|
||||
((VBitmapData*)(vnode->data))->t_height = (height/VN_B_TILE_SIZE + 1)*VN_B_TILE_SIZE;
|
||||
else
|
||||
((VBitmapData*)(vnode->data))->t_height = height;
|
||||
|
||||
/* crop resize all layers */
|
||||
vblayer = ((VBitmapData*)vnode->data)->layers.lb.first;
|
||||
|
||||
while(vblayer) {
|
||||
/* when this callback function received after cb_b_layer_create,
|
||||
* then we have to allocate memory for verse bitmap layer data */
|
||||
if(!vblayer->data) vblayer->data = alloc_verse_bitmap_layer_data(vblayer);
|
||||
/* crop/resize all verse bitmap layers */
|
||||
else change_layer_dimension(vblayer, old_width, old_height, t_old_width, t_old_height);
|
||||
|
||||
vblayer = vblayer->next;
|
||||
}
|
||||
|
||||
/* post callback function */
|
||||
((VBitmapData*)(vnode->data))->post_bitmap_dimension_set(vnode);
|
||||
}
|
||||
|
||||
/*
|
||||
* callback function, new layer channel of image was created
|
||||
*/
|
||||
static void cb_b_layer_create(
|
||||
void *user_data,
|
||||
VNodeID node_id,
|
||||
VLayerID layer_id,
|
||||
const char *name,
|
||||
VNBLayerType type)
|
||||
{
|
||||
struct VerseSession *session = (VerseSession*)current_verse_session();
|
||||
struct VNode *vnode;
|
||||
struct VBitmapLayer *vblayer;
|
||||
|
||||
if(!session) return;
|
||||
|
||||
vnode = (VNode*)BLI_dlist_find_link(&(session->nodes), (unsigned int)node_id);
|
||||
if(!vnode) return;
|
||||
|
||||
#ifdef VERSE_DEBUG_PRINT
|
||||
printf("\t cb_b_layer_create()\n");
|
||||
#endif
|
||||
|
||||
/* when no layer exists, then new layer will be created */
|
||||
vblayer = create_bitmap_layer(vnode, layer_id, name, type);
|
||||
|
||||
/* add verse bitmap layer to list of layers */
|
||||
BLI_dlist_add_item_index(&((VBitmapData*)vnode->data)->layers, vblayer, layer_id);
|
||||
|
||||
/* post callback function */
|
||||
((VBitmapData*)(vnode->data))->post_bitmap_layer_create(vblayer);
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* callback function, existing layer of image was destroyed
|
||||
*/
|
||||
static void cb_b_layer_destroy(
|
||||
void *user_data,
|
||||
VNodeID node_id,
|
||||
VLayerID layer_id)
|
||||
{
|
||||
struct VerseSession *session = (VerseSession*)current_verse_session();
|
||||
struct VNode *vnode;
|
||||
struct VBitmapLayer *vblayer;
|
||||
|
||||
if(!session) return;
|
||||
|
||||
/* find node of this layer*/
|
||||
vnode = (VNode*)BLI_dlist_find_link(&(session->nodes), (unsigned int)node_id);
|
||||
if(!vnode) return;
|
||||
|
||||
vblayer = (VBitmapLayer*)BLI_dlist_find_link(&(((VBitmapData*)vnode->data)->layers), layer_id);
|
||||
if(!vblayer) return;
|
||||
|
||||
#ifdef VERSE_DEBUG_PRINT
|
||||
printf("\t cb_b_layer_destroy()\n");
|
||||
#endif
|
||||
|
||||
/* remove verse bitmap layer from list of layers */
|
||||
BLI_dlist_rem_item(&(((VBitmapData*)vnode->data)->layers), layer_id);
|
||||
|
||||
/* post callback function */
|
||||
((VBitmapData*)(vnode->data))->post_bitmap_layer_destroy(vblayer);
|
||||
|
||||
/* free data of verse bitmap layer */
|
||||
free_bitmap_layer_data(vblayer);
|
||||
|
||||
/* free verse bitmap layer */
|
||||
MEM_freeN(vblayer);
|
||||
}
|
||||
|
||||
/*
|
||||
* callback function, small part (8x8 pixels) was changed
|
||||
*/
|
||||
static void cb_b_tile_set(
|
||||
void *user_data,
|
||||
VNodeID node_id,
|
||||
VLayerID layer_id,
|
||||
uint16 tile_x,
|
||||
uint16 tile_y,
|
||||
uint16 z,
|
||||
VNBLayerType type,
|
||||
const VNBTile *tile)
|
||||
{
|
||||
struct VerseSession *session = (VerseSession*)current_verse_session();
|
||||
struct VNode *vnode;
|
||||
struct VBitmapLayer *vblayer;
|
||||
unsigned int x, y, xs, ys, width, height, t_height, t_width, i, j;
|
||||
|
||||
if(!session) return;
|
||||
|
||||
/* try to find verse node in dynamic list nodes */
|
||||
vnode = (VNode*)BLI_dlist_find_link(&(session->nodes), (unsigned int)node_id);
|
||||
if(!vnode) return;
|
||||
|
||||
/* try to find verse bitmap layer in list of layers */
|
||||
vblayer = (VBitmapLayer*)BLI_dlist_find_link(&(((VBitmapData*)vnode->data)->layers), layer_id);
|
||||
if(!vblayer) return;
|
||||
|
||||
/* we have to have allocated memory for bitmap layer */
|
||||
if(!vblayer->data) return;
|
||||
|
||||
width = ((VBitmapData*)vnode->data)->width;
|
||||
height = ((VBitmapData*)vnode->data)->height;
|
||||
|
||||
/* width of verse image including all tiles */
|
||||
t_height = ((VBitmapData*)vnode->data)->t_height;
|
||||
/* height of verse image including all tiles */
|
||||
t_width = ((VBitmapData*)vnode->data)->t_width;
|
||||
|
||||
#ifdef VERSE_DEBUG_PRINT
|
||||
printf("\t cb_b_tile_set()\n");
|
||||
#endif
|
||||
|
||||
xs = tile_x*VN_B_TILE_SIZE;
|
||||
ys = tile_y*VN_B_TILE_SIZE;
|
||||
|
||||
/* initial position in one dimension vblayer->data (y_start*width + x_start) */
|
||||
i = ys*t_width + xs;
|
||||
/* intial position in one dimension tile array */
|
||||
j = 0;
|
||||
|
||||
if(type==VN_B_LAYER_UINT8) {
|
||||
unsigned char *data = (unsigned char*)vblayer->data;
|
||||
for(y=ys; y<ys+VN_B_TILE_SIZE && y<height; y++, i=y*t_width+xs)
|
||||
for(x=xs; x<xs+VN_B_TILE_SIZE && x<width; x++, i++, j++)
|
||||
data[i] = (unsigned char)tile->vuint8[j];
|
||||
}
|
||||
|
||||
/* post callback function */
|
||||
((VBitmapData*)(vnode->data))->post_bitmap_tile_set(vblayer, xs, ys);
|
||||
}
|
||||
|
||||
/*
|
||||
* set up all callbacks functions for image nodes
|
||||
*/
|
||||
void set_bitmap_callbacks(void)
|
||||
{
|
||||
/* dimension (size) of bitmap was set up or changes (image will be croped) */
|
||||
verse_callback_set(verse_send_b_dimensions_set, cb_b_dimension_set, NULL);
|
||||
|
||||
/* new layer (chanell) of image was added or created */
|
||||
verse_callback_set(verse_send_b_layer_create, cb_b_layer_create, NULL);
|
||||
|
||||
/* existing layer was destroyed */
|
||||
verse_callback_set(verse_send_b_layer_destroy, cb_b_layer_destroy, NULL);
|
||||
|
||||
/* some tile (small part 8x8 pixels of image was changed) */
|
||||
verse_callback_set(verse_send_b_tile_set, cb_b_tile_set, NULL);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
1665
source/blender/blenkernel/intern/verse_geometry_node.c
Normal file
1665
source/blender/blenkernel/intern/verse_geometry_node.c
Normal file
File diff suppressed because it is too large
Load Diff
735
source/blender/blenkernel/intern/verse_node.c
Normal file
735
source/blender/blenkernel/intern/verse_node.c
Normal file
@ -0,0 +1,735 @@
|
||||
/**
|
||||
* $Id$
|
||||
*
|
||||
* ***** BEGIN GPL/BL DUAL 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. The Blender
|
||||
* Foundation also sells licenses for use in proprietary software under
|
||||
* the Blender License. See http://www.blender.org/BL/ for information
|
||||
* about this.
|
||||
*
|
||||
* 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/BL DUAL LICENSE BLOCK *****
|
||||
*/
|
||||
|
||||
#ifdef WITH_VERSE
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "MEM_guardedalloc.h"
|
||||
|
||||
#include "DNA_listBase.h"
|
||||
|
||||
#include "BLI_dynamiclist.h"
|
||||
#include "BLI_blenlib.h"
|
||||
|
||||
#include "BIF_verse.h"
|
||||
|
||||
#include "BKE_verse.h"
|
||||
|
||||
#include "verse.h"
|
||||
|
||||
/* function prototypes of static functions */
|
||||
/* for tags */
|
||||
static void free_verse_tag_data(struct VTag *vtag);
|
||||
static struct VTag *find_tag_in_queue(struct VTagGroup *vtaggroup, const char *name);
|
||||
static struct VTag *create_verse_tag(struct VTagGroup *vtaggroup, uint16 tag_id, const char *name, VNTagType type, const VNTag *tag);
|
||||
/* for verse tag groups */
|
||||
static void free_verse_taggroup_data(struct VTagGroup *taggroup);
|
||||
static struct VTagGroup *find_taggroup_in_queue(struct VNode *vnode, const char *name);
|
||||
static struct VTagGroup *create_verse_taggroup(VNode *vnode, uint16 group_id, const char *name);
|
||||
/* for verse nodes */
|
||||
static void move_verse_node_to_dlist(struct VerseSession *session, VNodeID vnode_id);
|
||||
/* function prototypes of node callback functions */
|
||||
static void cb_tag_destroy(void *user_data, VNodeID node_id, uint16 group_id, uint16 tag_id);
|
||||
static void cb_tag_create(void *user_data, VNodeID node_id, uint16 group_id, uint16 tag_id, const char *name, VNTagType type, const VNTag *tag);
|
||||
static void cb_tag_group_destroy(void *user_data, VNodeID node_id, uint16 group_id);
|
||||
static void cb_tag_group_create(void *user_data, VNodeID node_id, uint16 group_id, const char *name);
|
||||
static void cb_node_name_set(void *user_data, VNodeID node_id, const char *name);
|
||||
static void cb_node_destroy(void *user_data, VNodeID node_id);
|
||||
static void cb_node_create(void *user_data, VNodeID node_id, uint8 type, VNodeID owner_id);
|
||||
|
||||
/*
|
||||
* send new tag to verse server
|
||||
*/
|
||||
void send_verse_tag(VTag *vtag)
|
||||
{
|
||||
verse_send_tag_create(vtag->vtaggroup->vnode->id,
|
||||
vtag->vtaggroup->id,
|
||||
vtag->id,
|
||||
vtag->name,
|
||||
vtag->type,
|
||||
vtag->tag);
|
||||
}
|
||||
|
||||
/*
|
||||
* free tag data
|
||||
*/
|
||||
static void free_verse_tag_data(VTag *vtag)
|
||||
{
|
||||
/* free name of verse tag */
|
||||
MEM_freeN(vtag->name);
|
||||
/* free value of tag */
|
||||
MEM_freeN(vtag->tag);
|
||||
}
|
||||
|
||||
/*
|
||||
* try to find tag in sending queue ... if tag will be found, then
|
||||
* this function will removed tag from queue and will return pointer
|
||||
* at this tag
|
||||
*/
|
||||
static VTag *find_tag_in_queue(VTagGroup *vtaggroup, const char *name)
|
||||
{
|
||||
struct VTag *vtag;
|
||||
|
||||
vtag = vtaggroup->queue.first;
|
||||
|
||||
while(vtag) {
|
||||
if(strcmp(vtag->name, name)==0) {
|
||||
BLI_remlink(&(vtaggroup->queue), vtag);
|
||||
break;
|
||||
}
|
||||
vtag = vtag->next;
|
||||
}
|
||||
|
||||
return vtag;
|
||||
}
|
||||
|
||||
/*
|
||||
* create new verse tag
|
||||
*/
|
||||
static VTag *create_verse_tag(
|
||||
VTagGroup *vtaggroup,
|
||||
uint16 tag_id,
|
||||
const char *name,
|
||||
VNTagType type,
|
||||
const VNTag *tag)
|
||||
{
|
||||
struct VTag *vtag;
|
||||
|
||||
vtag = (VTag*)MEM_mallocN(sizeof(VTag), "VTag");
|
||||
|
||||
vtag->vtaggroup = vtaggroup;
|
||||
vtag->id = tag_id;
|
||||
vtag->name = (char*)MEM_mallocN(sizeof(char)*(strlen(name)+1), "VTag name");
|
||||
strcpy(vtag->name, name);
|
||||
vtag->type = type;
|
||||
|
||||
vtag->tag = (VNTag*)MEM_mallocN(sizeof(VNTag), "VNTag");
|
||||
*vtag->tag = *tag;
|
||||
|
||||
vtag->value = NULL;
|
||||
|
||||
return vtag;
|
||||
}
|
||||
|
||||
/*
|
||||
* send taggroup to verse server
|
||||
*/
|
||||
void send_verse_taggroup(VTagGroup *vtaggroup)
|
||||
{
|
||||
verse_send_tag_group_create(
|
||||
vtaggroup->vnode->id,
|
||||
vtaggroup->id,
|
||||
vtaggroup->name);
|
||||
}
|
||||
|
||||
/*
|
||||
* free taggroup data
|
||||
*/
|
||||
static void free_verse_taggroup_data(VTagGroup *taggroup)
|
||||
{
|
||||
struct VerseSession *session = taggroup->vnode->session;
|
||||
struct VTag *vtag;
|
||||
|
||||
vtag = taggroup->tags.lb.first;
|
||||
|
||||
while(vtag) {
|
||||
free_verse_tag_data(vtag);
|
||||
vtag = vtag->next;
|
||||
}
|
||||
|
||||
/* unsubscribe from taggroup */
|
||||
if(session->flag & VERSE_CONNECTED)
|
||||
verse_send_tag_group_unsubscribe(taggroup->vnode->id, taggroup->id);
|
||||
|
||||
BLI_dlist_destroy(&(taggroup->tags));
|
||||
MEM_freeN(taggroup->name);
|
||||
}
|
||||
|
||||
/*
|
||||
* move taggroup from queue to dynamic list with access array,
|
||||
* set up taggroup id and return pointer at this taggroup
|
||||
*/
|
||||
static VTagGroup *find_taggroup_in_queue(VNode *vnode, const char *name)
|
||||
{
|
||||
struct VTagGroup *vtaggroup;
|
||||
|
||||
vtaggroup = vnode->queue.first;
|
||||
|
||||
while(vtaggroup) {
|
||||
if(strcmp(vtaggroup->name, name)==0) {
|
||||
BLI_remlink(&(vnode->queue), vtaggroup);
|
||||
break;
|
||||
}
|
||||
vtaggroup = vtaggroup->next;
|
||||
}
|
||||
|
||||
return vtaggroup;
|
||||
}
|
||||
|
||||
/*
|
||||
* create new verse group of tags
|
||||
*/
|
||||
static VTagGroup *create_verse_taggroup(VNode *vnode, uint16 group_id, const char *name)
|
||||
{
|
||||
struct VTagGroup *taggroup;
|
||||
|
||||
taggroup = (VTagGroup*)MEM_mallocN(sizeof(VTagGroup), "VTagGroup");
|
||||
|
||||
taggroup->vnode = vnode;
|
||||
taggroup->id = group_id;
|
||||
taggroup->name = (char*)MEM_mallocN(sizeof(char)*(strlen(name)+1), "VTagGroup name");
|
||||
strcpy(taggroup->name, name);
|
||||
|
||||
BLI_dlist_init(&(taggroup->tags));
|
||||
taggroup->queue.first = taggroup->queue.last = NULL;
|
||||
|
||||
taggroup->post_tag_change = post_tag_change;
|
||||
taggroup->post_taggroup_create = post_taggroup_create;
|
||||
|
||||
return taggroup;
|
||||
}
|
||||
|
||||
/*
|
||||
* move first VerseNode waiting in sending queue to dynamic list of VerseNodes
|
||||
* (it usually happens, when "our" VerseNode was received from verse server)
|
||||
*/
|
||||
static void move_verse_node_to_dlist(VerseSession *session, VNodeID vnode_id)
|
||||
{
|
||||
VNode *vnode;
|
||||
|
||||
vnode = session->queue.first;
|
||||
|
||||
if(vnode) {
|
||||
BLI_remlink(&(session->queue), vnode);
|
||||
BLI_dlist_add_item_index(&(session->nodes), (void*)vnode, vnode_id);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* send VerseNode to verse server
|
||||
*/
|
||||
void send_verse_node(VNode *vnode)
|
||||
{
|
||||
verse_send_node_create(
|
||||
vnode->id,
|
||||
vnode->type,
|
||||
vnode->session->avatar);
|
||||
}
|
||||
|
||||
/*
|
||||
* free Verse Node data
|
||||
*/
|
||||
void free_verse_node_data(VNode *vnode)
|
||||
{
|
||||
struct VerseSession *session = vnode->session;
|
||||
struct VTagGroup *vtaggroup;
|
||||
|
||||
/* free node data (object, geometry, etc.) */
|
||||
switch(vnode->type){
|
||||
case V_NT_OBJECT:
|
||||
free_object_data(vnode);
|
||||
break;
|
||||
case V_NT_GEOMETRY:
|
||||
free_geom_data(vnode);
|
||||
break;
|
||||
case V_NT_BITMAP:
|
||||
free_bitmap_node_data(vnode);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
/* free all tag groups in dynamic list with access array */
|
||||
vtaggroup = vnode->taggroups.lb.first;
|
||||
while(vtaggroup) {
|
||||
free_verse_taggroup_data(vtaggroup);
|
||||
vtaggroup = vtaggroup->next;
|
||||
}
|
||||
BLI_dlist_destroy(&(vnode->taggroups));
|
||||
|
||||
/* free all tag groups still waiting in queue */
|
||||
vtaggroup = vnode->queue.first;
|
||||
while(vtaggroup) {
|
||||
free_verse_taggroup_data(vtaggroup);
|
||||
vtaggroup = vtaggroup->next;
|
||||
}
|
||||
BLI_freelistN(&(vnode->queue));
|
||||
|
||||
/* unsubscribe from node */
|
||||
if(session->flag & VERSE_CONNECTED)
|
||||
verse_send_node_unsubscribe(vnode->id);
|
||||
|
||||
/* free node name */
|
||||
MEM_freeN(vnode->name);
|
||||
vnode->name = NULL;
|
||||
|
||||
/* free node data */
|
||||
MEM_freeN(vnode->data);
|
||||
vnode->data = NULL;
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* free VerseNode
|
||||
*/
|
||||
void free_verse_node(VNode *vnode)
|
||||
{
|
||||
free_verse_node_data(vnode);
|
||||
|
||||
BLI_dlist_free_item(&(vnode->session->nodes), vnode->id);
|
||||
}
|
||||
|
||||
/*
|
||||
* create new Verse Node
|
||||
*/
|
||||
VNode* create_verse_node(VerseSession *session, VNodeID node_id, uint8 type, VNodeID owner_id)
|
||||
{
|
||||
struct VNode *vnode;
|
||||
|
||||
vnode = (VNode*)MEM_mallocN(sizeof(VNode), "VerseNode");
|
||||
|
||||
vnode->session = session;
|
||||
vnode->id = node_id;
|
||||
vnode->owner_id = owner_id;
|
||||
vnode->name = NULL;
|
||||
vnode->type = type;
|
||||
|
||||
BLI_dlist_init(&(vnode->taggroups));
|
||||
vnode->queue.first = vnode->queue.last = NULL;
|
||||
|
||||
vnode->data = NULL;
|
||||
|
||||
vnode->counter = 0;
|
||||
|
||||
vnode->flag = 0;
|
||||
|
||||
vnode->post_node_create = post_node_create;
|
||||
vnode->post_node_destroy = post_node_destroy;
|
||||
vnode->post_node_name_set = post_node_name_set;
|
||||
|
||||
return vnode;
|
||||
}
|
||||
|
||||
/*
|
||||
* callback function: tag was destroyed
|
||||
*/
|
||||
static void cb_tag_destroy(
|
||||
void *user_data,
|
||||
VNodeID node_id,
|
||||
uint16 group_id,
|
||||
uint16 tag_id)
|
||||
{
|
||||
struct VerseSession *session = (VerseSession*)current_verse_session();
|
||||
struct VNode *vnode;
|
||||
struct VTagGroup *vtaggroup;
|
||||
struct VTag *vtag;
|
||||
|
||||
if(!session) return;
|
||||
|
||||
vnode = (VNode*)BLI_dlist_find_link(&(session->nodes), (unsigned int)node_id);
|
||||
if(!vnode) return;
|
||||
|
||||
/* try to find tag group in list of tag groups */
|
||||
vtaggroup = BLI_dlist_find_link(&(vnode->taggroups), group_id);
|
||||
|
||||
if(!vtaggroup) return;
|
||||
|
||||
/* try to find verse tag in dynamic list of tags in tag group */
|
||||
vtag = (VTag*)BLI_dlist_find_link(&(vtaggroup->tags), tag_id);
|
||||
|
||||
if(vtag) {
|
||||
free_verse_tag_data(vtag);
|
||||
BLI_dlist_free_item(&(vtaggroup->tags), vtag->id);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* callback function: new tag was created
|
||||
*/
|
||||
static void cb_tag_create(
|
||||
void *user_data,
|
||||
VNodeID node_id,
|
||||
uint16 group_id,
|
||||
uint16 tag_id,
|
||||
const char *name,
|
||||
VNTagType type,
|
||||
const VNTag *tag)
|
||||
{
|
||||
struct VerseSession *session = (VerseSession*)current_verse_session();
|
||||
struct VNode *vnode;
|
||||
struct VTagGroup *vtaggroup;
|
||||
struct VTag *vtag;
|
||||
|
||||
if(!session) return;
|
||||
|
||||
vnode = (VNode*)BLI_dlist_find_link(&(session->nodes), (unsigned int)node_id);
|
||||
if(!vnode) return;
|
||||
|
||||
/* try to find tag group in list of tag groups */
|
||||
vtaggroup = BLI_dlist_find_link(&(vnode->taggroups), group_id);
|
||||
|
||||
if(!vtaggroup) return;
|
||||
|
||||
/* try to find verse tag in dynamic list of tags in tag group */
|
||||
vtag = (VTag*)BLI_dlist_find_link(&(vtaggroup->tags), tag_id);
|
||||
|
||||
if(!vtag) {
|
||||
/* we will try to find vtag in sending queue */
|
||||
vtag = find_tag_in_queue(vtaggroup, name);
|
||||
|
||||
/* when we didn't create this tag, then we will have to create one */
|
||||
if(!vtag) vtag = create_verse_tag(vtaggroup, tag_id, name, type, tag);
|
||||
else vtag->id = tag_id;
|
||||
|
||||
/* add tag to the list of tags in tag group */
|
||||
BLI_dlist_add_item_index(&(vtaggroup->tags), vtag, tag_id);
|
||||
|
||||
/* post change/create method */
|
||||
vtaggroup->post_tag_change(vtag);
|
||||
}
|
||||
else {
|
||||
/* this tag exists, then we will propably change value of this tag */
|
||||
if((vtag->type != type) || (strcmp(vtag->name, name)!=0)) {
|
||||
/* changes of type or name are not allowed and such
|
||||
* stupid changes will be returned back */
|
||||
send_verse_tag(vtag);
|
||||
}
|
||||
else {
|
||||
/* post change/create method */
|
||||
vtaggroup->post_tag_change(vtag);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* callback function: tag group was destroyed
|
||||
*/
|
||||
static void cb_tag_group_destroy(
|
||||
void *user_data,
|
||||
VNodeID node_id,
|
||||
uint16 group_id)
|
||||
{
|
||||
struct VerseSession *session = (VerseSession*)current_verse_session();
|
||||
struct VNode *vnode;
|
||||
struct VTagGroup *vtaggroup;
|
||||
|
||||
if(!session) return;
|
||||
|
||||
vnode = (VNode*)BLI_dlist_find_link(&(session->nodes), (unsigned int)node_id);
|
||||
if(!vnode) return;
|
||||
|
||||
vtaggroup = BLI_dlist_find_link(&(vnode->taggroups), group_id);
|
||||
|
||||
if(vtaggroup) {
|
||||
free_verse_taggroup_data(vtaggroup);
|
||||
BLI_dlist_free_item(&(vnode->taggroups), vtaggroup->id);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* callback function: new tag group was created
|
||||
*/
|
||||
static void cb_tag_group_create(
|
||||
void *user_data,
|
||||
VNodeID node_id,
|
||||
uint16 group_id,
|
||||
const char *name)
|
||||
{
|
||||
struct VerseSession *session = (VerseSession*)current_verse_session();
|
||||
struct VNode *vnode;
|
||||
struct VTagGroup *vtaggroup;
|
||||
|
||||
if(!session) return;
|
||||
|
||||
vnode = (VNode*)BLI_dlist_find_link(&(session->nodes), (unsigned int)node_id);
|
||||
if(!vnode) return;
|
||||
|
||||
/* name of taggroup has to begin with string "blender:" */
|
||||
if(strncmp("blender:", name, 8)) return;
|
||||
|
||||
/* try to find tag group in list of tag groups */
|
||||
vtaggroup = BLI_dlist_find_link(&(vnode->taggroups), group_id);
|
||||
|
||||
if(!vtaggroup) {
|
||||
/* subscribe to tag group (when new tag will be created, then blender will
|
||||
* receive command about it) */
|
||||
verse_send_tag_group_subscribe(vnode->id, group_id);
|
||||
verse_callback_update(0);
|
||||
|
||||
/* try to find taggroup in waiting queue */
|
||||
vtaggroup = find_taggroup_in_queue(vnode, name);
|
||||
|
||||
/* if no taggroup exist, then new has to be created */
|
||||
if(!vtaggroup) vtaggroup = create_verse_taggroup(vnode, group_id, name);
|
||||
else vtaggroup->id = group_id;
|
||||
|
||||
/* add tag group to dynamic list with access array */
|
||||
BLI_dlist_add_item_index(&(vnode->taggroups), (void*)vtaggroup, (unsigned int)group_id);
|
||||
|
||||
/* post create method */
|
||||
vtaggroup->post_taggroup_create(vtaggroup);
|
||||
}
|
||||
else {
|
||||
/* this taggroup exist and somebody try to change its name */
|
||||
if(strcmp(vtaggroup->name, name)!=0) {
|
||||
/* blender doesn't allow such stupid and dangerous things */
|
||||
send_verse_taggroup(vtaggroup);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* callback function: change name of node
|
||||
*/
|
||||
static void cb_node_name_set(
|
||||
void *user_data,
|
||||
VNodeID node_id,
|
||||
const char *name)
|
||||
{
|
||||
struct VerseSession *session = (VerseSession*)current_verse_session();
|
||||
struct VNode *vnode;
|
||||
|
||||
if(!session) return;
|
||||
|
||||
vnode = (VNode*)BLI_dlist_find_link(&(session->nodes), (unsigned int)node_id);
|
||||
if(vnode && name) {
|
||||
if(!vnode->name) {
|
||||
vnode->name = (char*)MEM_mallocN(sizeof(char)*(strlen(name)+1), "VerseNode name");
|
||||
}
|
||||
else if(strlen(name) > strlen(vnode->name)) {
|
||||
MEM_freeN(vnode->name);
|
||||
vnode->name = (char*)MEM_mallocN(sizeof(char)*(strlen(name)+1), "VerseNode name");
|
||||
}
|
||||
strcpy(vnode->name, name);
|
||||
|
||||
vnode->post_node_name_set(vnode);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* callback function for deleting node
|
||||
*/
|
||||
static void cb_node_destroy(
|
||||
void *user_data,
|
||||
VNodeID node_id)
|
||||
{
|
||||
struct VerseSession *session = (VerseSession*)current_verse_session();
|
||||
struct VNode *vnode;
|
||||
|
||||
if(!session) return;
|
||||
|
||||
vnode = BLI_dlist_find_link(&(session->nodes), (unsigned int)node_id);
|
||||
|
||||
if(vnode) {
|
||||
/* remove VerseNode from dynamic list */
|
||||
BLI_dlist_rem_item(&(session->nodes), (unsigned int)node_id);
|
||||
/* do post destroy operations */
|
||||
vnode->post_node_destroy(vnode);
|
||||
/* free verse data */
|
||||
free_verse_node_data(vnode);
|
||||
/* free VerseNode */
|
||||
MEM_freeN(vnode);
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* callback function for new created node
|
||||
*/
|
||||
static void cb_node_create(
|
||||
void *user_data,
|
||||
VNodeID node_id,
|
||||
uint8 type,
|
||||
VNodeID owner_id)
|
||||
{
|
||||
struct VerseSession *session = (VerseSession*)current_verse_session();
|
||||
struct VNode *vnode;
|
||||
|
||||
if(!session) return;
|
||||
|
||||
/* subscribe to node */
|
||||
if((type==V_NT_OBJECT) || (type==V_NT_GEOMETRY) || (type==V_NT_BITMAP))
|
||||
verse_send_node_subscribe(node_id);
|
||||
else
|
||||
return;
|
||||
|
||||
switch(type){
|
||||
case V_NT_OBJECT :
|
||||
if(owner_id==VN_OWNER_MINE) {
|
||||
struct VLink *vlink;
|
||||
/* collect VerseNode from VerseNode queue */
|
||||
move_verse_node_to_dlist(session, node_id);
|
||||
/* send next VerseNode waiting in queue */
|
||||
if(session->queue.first) send_verse_node(session->queue.first);
|
||||
/* get received VerseNode from list of VerseNodes */
|
||||
vnode = BLI_dlist_find_link(&(session->nodes), node_id);
|
||||
/* set up ID */
|
||||
vnode->id = node_id;
|
||||
/* set up flags */
|
||||
vnode->flag |= NODE_RECEIVED;
|
||||
/* find unsent link pointing at this VerseNode */
|
||||
vlink = find_unsent_child_vlink(session, vnode);
|
||||
/* send VerseLink */
|
||||
if(vlink) send_verse_link(vlink);
|
||||
/* send name of object node */
|
||||
verse_send_node_name_set(node_id, vnode->name);
|
||||
/* subscribe to changes of object node transformations */
|
||||
verse_send_o_transform_subscribe(node_id, 0);
|
||||
/* send object transformation matrix */
|
||||
send_verse_object_position(vnode);
|
||||
send_verse_object_rotation(vnode);
|
||||
send_verse_object_scale(vnode);
|
||||
}
|
||||
else {
|
||||
/* create new VerseNode */
|
||||
vnode = create_verse_node(session, node_id, type, owner_id);
|
||||
/* add VerseNode to list of nodes */
|
||||
BLI_dlist_add_item_index(&(session->nodes), (void*)vnode, (unsigned int)node_id);
|
||||
/* set up flags */
|
||||
vnode->flag |= NODE_RECEIVED;
|
||||
/* create object data */
|
||||
vnode->data = create_object_data();
|
||||
/* set up avatar's name */
|
||||
if(node_id == session->avatar) {
|
||||
char *client_name;
|
||||
client_name = verse_client_name();
|
||||
verse_send_node_name_set(node_id, client_name);
|
||||
MEM_freeN(client_name);
|
||||
}
|
||||
else if(session->flag & VERSE_AUTOSUBSCRIBE) {
|
||||
/* subscribe to changes of object node transformations */
|
||||
verse_send_o_transform_subscribe(node_id, 0);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case V_NT_GEOMETRY :
|
||||
if(owner_id==VN_OWNER_MINE){
|
||||
struct VLink *vlink;
|
||||
struct VLayer *vlayer;
|
||||
/* collect VerseNode from VerseNode queue */
|
||||
move_verse_node_to_dlist(session, node_id);
|
||||
/* send next VerseNode waiting in queue */
|
||||
if(session->queue.first) send_verse_node(session->queue.first);
|
||||
/* get received VerseNode from list of VerseNodes */
|
||||
vnode = BLI_dlist_find_link(&(session->nodes), node_id);
|
||||
/* set up ID */
|
||||
vnode->id = node_id;
|
||||
/* set up flags */
|
||||
vnode->flag |= NODE_RECEIVED;
|
||||
/* find unsent link pointing at this VerseNode */
|
||||
vlink = find_unsent_parent_vlink(session, vnode);
|
||||
/* send VerseLink */
|
||||
if(vlink) send_verse_link(vlink);
|
||||
/* send name of geometry node */
|
||||
verse_send_node_name_set(node_id, vnode->name);
|
||||
/* send all not sent layer to verse server */
|
||||
vlayer = (VLayer*)((VGeomData*)vnode->data)->queue.first;
|
||||
if(vlayer) {
|
||||
while(vlayer) {
|
||||
send_verse_layer(vlayer);
|
||||
vlayer = vlayer->next;
|
||||
}
|
||||
}
|
||||
else {
|
||||
/* send two verse layers to verse server */
|
||||
/* verse_send_g_layer_create(node_id, 0, "vertex", VN_G_LAYER_VERTEX_XYZ, 0, 0);
|
||||
verse_send_g_layer_create(node_id, 1, "polygon", VN_G_LAYER_POLYGON_CORNER_UINT32, 0, 0);*/
|
||||
}
|
||||
}
|
||||
else {
|
||||
/* create new VerseNode*/
|
||||
vnode = create_verse_node(session, node_id, type, owner_id);
|
||||
/* add VerseNode to dlist of nodes */
|
||||
BLI_dlist_add_item_index(&(session->nodes), (void*)vnode, (unsigned int)node_id);
|
||||
/* set up flags */
|
||||
vnode->flag |= NODE_RECEIVED;
|
||||
/* create geometry data */
|
||||
vnode->data = (void*)create_geometry_data();
|
||||
}
|
||||
break;
|
||||
case V_NT_BITMAP :
|
||||
if(owner_id==VN_OWNER_MINE) {
|
||||
/* collect VerseNode from VerseNode queue */
|
||||
move_verse_node_to_dlist(session, node_id);
|
||||
/* send next VerseNode waiting in queue */
|
||||
if(session->queue.first) send_verse_node(session->queue.first);
|
||||
/* get received VerseNode from list of VerseNodes */
|
||||
vnode = BLI_dlist_find_link(&(session->nodes), node_id);
|
||||
/* set up ID */
|
||||
vnode->id = node_id;
|
||||
/* set up flags */
|
||||
vnode->flag |= NODE_RECEIVED;
|
||||
/* send name of object node */
|
||||
verse_send_node_name_set(node_id, vnode->name);
|
||||
/* send dimension of image to verse server */
|
||||
verse_send_b_dimensions_set(node_id,
|
||||
((VBitmapData*)vnode->data)->width,
|
||||
((VBitmapData*)vnode->data)->height,
|
||||
((VBitmapData*)vnode->data)->depth);
|
||||
}
|
||||
else {
|
||||
/* create new VerseNode*/
|
||||
vnode = create_verse_node(session, node_id, type, owner_id);
|
||||
/* add VerseNode to dlist of nodes */
|
||||
BLI_dlist_add_item_index(&(session->nodes), (void*)vnode, (unsigned int)node_id);
|
||||
/* set up flags */
|
||||
vnode->flag |= NODE_RECEIVED;
|
||||
/* create bitmap data */
|
||||
vnode->data = (void*)create_bitmap_data();
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
vnode->post_node_create(vnode);
|
||||
}
|
||||
|
||||
/*
|
||||
* set up all callbacks for verse nodes
|
||||
*/
|
||||
void set_node_callbacks(void)
|
||||
{
|
||||
/* new node created */
|
||||
verse_callback_set(verse_send_node_create, cb_node_create, NULL);
|
||||
/* node was deleted */
|
||||
verse_callback_set(verse_send_node_destroy, cb_node_destroy, NULL);
|
||||
/* name of node was set */
|
||||
verse_callback_set(verse_send_node_name_set, cb_node_name_set, NULL);
|
||||
|
||||
/* new tag group was created */
|
||||
verse_callback_set(verse_send_tag_group_create, cb_tag_group_create, NULL);
|
||||
/* tag group was destroy */
|
||||
verse_callback_set(verse_send_tag_group_destroy, cb_tag_group_destroy, NULL);
|
||||
|
||||
/* new tag was created */
|
||||
verse_callback_set(verse_send_tag_create, cb_tag_create, NULL);
|
||||
/* tag was destroy */
|
||||
verse_callback_set(verse_send_tag_destroy, cb_tag_destroy, NULL);
|
||||
}
|
||||
|
||||
#endif
|
605
source/blender/blenkernel/intern/verse_object_node.c
Normal file
605
source/blender/blenkernel/intern/verse_object_node.c
Normal file
@ -0,0 +1,605 @@
|
||||
/**
|
||||
* $Id$
|
||||
*
|
||||
* ***** BEGIN GPL/BL DUAL 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. The Blender
|
||||
* Foundation also sells licenses for use in proprietary software under
|
||||
* the Blender License. See http://www.blender.org/BL/ for information
|
||||
* about this.
|
||||
*
|
||||
* 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/BL DUAL LICENSE BLOCK *****
|
||||
*/
|
||||
|
||||
#ifdef WITH_VERSE
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "MEM_guardedalloc.h"
|
||||
|
||||
#include "DNA_listBase.h"
|
||||
|
||||
#include "BLI_dynamiclist.h"
|
||||
#include "BLI_blenlib.h"
|
||||
#include "BLI_arithb.h"
|
||||
|
||||
#include "BIF_verse.h"
|
||||
|
||||
#include "BKE_verse.h"
|
||||
|
||||
#include "verse.h"
|
||||
|
||||
/* function prototypes of static functions */
|
||||
|
||||
/* callback functions */
|
||||
static void cb_o_transform_pos_real32(void *user_data, VNodeID node_id, uint32 time_s, uint32 time_f, const real32 *pos, const real32 *speed, const real32 *accelerate, const real32 *drag_normal, real32 drag);
|
||||
static void cb_o_transform_rot_real32(void *user_data, VNodeID node_id, uint32 time_s, uint32 time_f, const VNQuat32 *rot, const VNQuat32 *speed, const VNQuat32 *accelerate, const VNQuat32 *drag_normal, real32 drag);
|
||||
static void cb_o_transform_scale_real32(void *user_data, VNodeID node_id, real32 scale_x, real32 scale_y, real32 scale_z);
|
||||
static void cb_o_link_set(void *user_data, VNodeID node_id, uint16 link_id, VNodeID link, const char *label, uint32 target_id);
|
||||
static void cb_o_link_destroy(void *user_data, VNodeID node_id,uint16 link_id);
|
||||
|
||||
/* other functions */
|
||||
static void set_target_node_link_pointer(struct VNode *vnode, struct VLink *vlink);
|
||||
static void free_verse_link_data(struct VLink *vlink);
|
||||
|
||||
/*
|
||||
* find noy sent VerseLink in queue
|
||||
*/
|
||||
VLink *find_unsent_child_vlink(VerseSession *session, VNode *vnode)
|
||||
{
|
||||
struct VLink *vlink;
|
||||
|
||||
if(vnode->type!=V_NT_OBJECT) return NULL;
|
||||
|
||||
vlink = ((VObjectData*)vnode->data)->queue.first;
|
||||
while(vlink) {
|
||||
if(vlink->target->id != -1) {
|
||||
printf("\t vlink found, vnode target id %d\n", vlink->target->id);
|
||||
return vlink;
|
||||
}
|
||||
vlink = vlink->next;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* find unsent VerseLink "pointing at this VerseNode"
|
||||
*/
|
||||
VLink *find_unsent_parent_vlink(VerseSession *session, VNode *vnode)
|
||||
{
|
||||
struct VNode *tmp;
|
||||
struct VLink *vlink;
|
||||
|
||||
tmp = session->nodes.lb.first;
|
||||
|
||||
while(tmp) {
|
||||
if(tmp->type==V_NT_OBJECT) {
|
||||
vlink = ((VObjectData*)tmp->data)->queue.first;
|
||||
while(vlink) {
|
||||
if(vlink->target == vnode)
|
||||
return vlink;
|
||||
vlink = vlink->next;
|
||||
}
|
||||
}
|
||||
tmp = tmp->next;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* send object position to verse server
|
||||
*/
|
||||
void send_verse_object_position(VNode *vnode)
|
||||
{
|
||||
float tmp;
|
||||
|
||||
((VObjectData*)vnode->data)->flag &= ~POS_SEND_READY;
|
||||
|
||||
tmp = -((VObjectData*)vnode->data)->pos[1];
|
||||
((VObjectData*)vnode->data)->pos[1] = ((VObjectData*)vnode->data)->pos[2];
|
||||
((VObjectData*)vnode->data)->pos[2] = tmp;
|
||||
|
||||
verse_send_o_transform_pos_real32(
|
||||
vnode->id, /* node id */
|
||||
0, /* time_s ... no interpolation */
|
||||
0, /* time_f ... no interpolation */
|
||||
((VObjectData*)vnode->data)->pos,
|
||||
NULL, /* speed ... no interpolation */
|
||||
NULL, /* accelerate ... no interpolation */
|
||||
NULL, /* drag normal ... no interpolation */
|
||||
0.0); /* drag ... no interpolation */
|
||||
}
|
||||
|
||||
/*
|
||||
* send object rotation to verse server
|
||||
*/
|
||||
void send_verse_object_rotation(VNode *vnode)
|
||||
{
|
||||
float quat[4];
|
||||
/* float bvec[3], vvec[3];*/
|
||||
VNQuat32 rot;
|
||||
|
||||
rot.x = ((VObjectData*)vnode->data)->rot[0];
|
||||
rot.y = ((VObjectData*)vnode->data)->rot[1];
|
||||
rot.z = ((VObjectData*)vnode->data)->rot[2];
|
||||
rot.w = ((VObjectData*)vnode->data)->rot[3];
|
||||
|
||||
/*
|
||||
quat[0] = ((VObjectData*)vnode->data)->rot[0];
|
||||
quat[1] = ((VObjectData*)vnode->data)->rot[1];
|
||||
quat[2] = ((VObjectData*)vnode->data)->rot[2];
|
||||
quat[3] = ((VObjectData*)vnode->data)->rot[3];
|
||||
|
||||
QuatToEul(quat, bvec);
|
||||
vvec[0] = bvec[0];
|
||||
vvec[1] = bvec[1];
|
||||
vvec[2] = bvec[2];
|
||||
EulToQuat(vvec, quat);
|
||||
|
||||
rot.x = quat[0];
|
||||
rot.y = quat[1];
|
||||
rot.z = quat[2];
|
||||
rot.w = quat[3];
|
||||
*/
|
||||
|
||||
((VObjectData*)vnode->data)->flag &= ~ROT_SEND_READY;
|
||||
|
||||
verse_send_o_transform_rot_real32(
|
||||
vnode->id, /* node id */
|
||||
0, /* time_s ... no interpolation */
|
||||
0, /* time_f ... no interpolation */
|
||||
&rot,
|
||||
NULL, /* speed ... no interpolation */
|
||||
NULL, /* accelerate ... no interpolation */
|
||||
NULL, /* drag normal ... no interpolation */
|
||||
0.0); /* drag ... no interpolation */
|
||||
}
|
||||
|
||||
/*
|
||||
* send object rotation to verse server
|
||||
*/
|
||||
void send_verse_object_scale(VNode *vnode)
|
||||
{
|
||||
((VObjectData*)vnode->data)->flag &= ~SCALE_SEND_READY;
|
||||
|
||||
verse_send_o_transform_scale_real32(
|
||||
vnode->id,
|
||||
((VObjectData*)vnode->data)->scale[0],
|
||||
((VObjectData*)vnode->data)->scale[2],
|
||||
((VObjectData*)vnode->data)->scale[1]);
|
||||
}
|
||||
|
||||
/*
|
||||
* send VerseLink to verse server
|
||||
*/
|
||||
void send_verse_link(VLink *vlink)
|
||||
{
|
||||
verse_session_set(vlink->session->vsession);
|
||||
|
||||
verse_send_o_link_set(
|
||||
vlink->source->id,
|
||||
vlink->id,
|
||||
vlink->target->id,
|
||||
vlink->label,
|
||||
vlink->target_id);
|
||||
}
|
||||
|
||||
/*
|
||||
* set up pointer at VerseLink of target node (geometry node, material node, etc.)
|
||||
*/
|
||||
static void set_target_node_link_pointer(VNode *vnode, VLink *vlink)
|
||||
{
|
||||
switch (vnode->type) {
|
||||
case V_NT_GEOMETRY:
|
||||
((VGeomData*)vnode->data)->vlink = vlink;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* free VerseLink and it's label
|
||||
*/
|
||||
static void free_verse_link_data(VLink *vlink)
|
||||
{
|
||||
MEM_freeN(vlink->label);
|
||||
}
|
||||
|
||||
/*
|
||||
* create new VerseLink
|
||||
*/
|
||||
VLink *create_verse_link(
|
||||
VerseSession *session,
|
||||
VNode *source,
|
||||
VNode *target,
|
||||
uint16 link_id,
|
||||
uint32 target_id,
|
||||
const char *label)
|
||||
{
|
||||
struct VLink *vlink;
|
||||
|
||||
vlink = (VLink*)MEM_mallocN(sizeof(VLink), "VerseLink");
|
||||
vlink->session = session;
|
||||
vlink->source = source;
|
||||
vlink->target = target;
|
||||
vlink->id = link_id;
|
||||
vlink->target_id = target_id;
|
||||
|
||||
set_target_node_link_pointer(target, vlink);
|
||||
|
||||
vlink->label = (char*)MEM_mallocN(sizeof(char)*(strlen(label)+1), "VerseLink label");
|
||||
vlink->label[0] = '\0';
|
||||
strcat(vlink->label, label);
|
||||
|
||||
vlink->flag = 0;
|
||||
|
||||
vlink->post_link_set = post_link_set;
|
||||
vlink->post_link_destroy = post_link_destroy;
|
||||
|
||||
return vlink;
|
||||
}
|
||||
|
||||
/*
|
||||
* free ObjectData (links, links in queue and lables of links)
|
||||
*/
|
||||
void free_object_data(VNode *vnode)
|
||||
{
|
||||
struct VerseSession *session = vnode->session;
|
||||
struct VObjectData *obj = (VObjectData*)vnode->data;
|
||||
struct VLink *vlink;
|
||||
|
||||
if(!obj) return;
|
||||
|
||||
/* free all labels of links in dlist */
|
||||
vlink = obj->links.lb.first;
|
||||
while(vlink){
|
||||
free_verse_link_data(vlink);
|
||||
vlink = vlink->next;
|
||||
}
|
||||
|
||||
/* free all labels of links waiting in queue */
|
||||
vlink = obj->queue.first;
|
||||
while(vlink){
|
||||
free_verse_link_data(vlink);
|
||||
vlink = vlink->next;
|
||||
}
|
||||
/* free dynamic list and sendig queue of links */
|
||||
BLI_dlist_destroy(&(obj->links));
|
||||
BLI_freelistN(&(obj->queue));
|
||||
|
||||
/* free constraint between VerseNode and Object */
|
||||
obj->post_object_free_constraint(vnode);
|
||||
|
||||
/* unsubscribe from receiving changes of transformation matrix */
|
||||
if(session->flag & VERSE_CONNECTED)
|
||||
verse_send_o_transform_unsubscribe(vnode->id, 0);
|
||||
}
|
||||
|
||||
/*
|
||||
* create new object data
|
||||
*/
|
||||
VObjectData *create_object_data(void)
|
||||
{
|
||||
VObjectData *obj;
|
||||
|
||||
obj = (VObjectData*)MEM_mallocN(sizeof(VObjectData), "VerseObjectData");
|
||||
obj->object = NULL;
|
||||
BLI_dlist_init(&(obj->links));
|
||||
obj->queue.first = obj->queue.last = NULL;
|
||||
obj->flag = 0;
|
||||
|
||||
/* transformation matrix */
|
||||
obj->pos[0] = obj->pos[1] = obj->pos[2] = 0.0;
|
||||
obj->rot[0] = obj->rot[1] = obj->rot[2] = 0.0; obj->rot[3] = 1;
|
||||
obj->scale[0] = obj->scale[1] = obj->scale[2] = 1.0;
|
||||
|
||||
/* transformation flags */
|
||||
obj->flag |= POS_SEND_READY;
|
||||
obj->flag |= ROT_SEND_READY;
|
||||
obj->flag |= SCALE_SEND_READY;
|
||||
|
||||
/* set up pointers at post callback functions */
|
||||
obj->post_transform = post_transform;
|
||||
obj->post_object_free_constraint = post_object_free_constraint;
|
||||
|
||||
return obj;
|
||||
}
|
||||
|
||||
/*
|
||||
* callback function:
|
||||
*/
|
||||
static void cb_o_transform_pos_real32(
|
||||
void *user_data,
|
||||
VNodeID node_id,
|
||||
uint32 time_s,
|
||||
uint32 time_f,
|
||||
const real32 *pos,
|
||||
const real32 *speed,
|
||||
const real32 *accelerate,
|
||||
const real32 *drag_normal,
|
||||
real32 drag)
|
||||
{
|
||||
struct VerseSession *session = (VerseSession*)current_verse_session();
|
||||
struct VNode *vnode;
|
||||
float vec[3], dt, tmp;
|
||||
|
||||
if(!session) return;
|
||||
|
||||
vnode = BLI_dlist_find_link(&(session->nodes), (unsigned int)node_id);
|
||||
|
||||
((VObjectData*)vnode->data)->flag |= POS_SEND_READY;
|
||||
|
||||
/* verse server sends automaticaly some stupid default values ...
|
||||
* we have to ignore these values, when we created this object node */
|
||||
if( (vnode->owner_id==VN_OWNER_MINE) && !(((VObjectData*)vnode->data)->flag & POS_RECEIVE_READY) ) {
|
||||
((VObjectData*)vnode->data)->flag |= POS_RECEIVE_READY;
|
||||
return;
|
||||
}
|
||||
|
||||
dt = time_s + time_f/(0xffff);
|
||||
|
||||
/* we have to flip z and y coordinates, because verse and blender use different axis
|
||||
* orientation */
|
||||
if(pos) {
|
||||
vec[0] = pos[0];
|
||||
vec[1] = pos[1];
|
||||
vec[2] = pos[2];
|
||||
}
|
||||
|
||||
if(speed) {
|
||||
vec[0] += speed[0]*dt;
|
||||
vec[1] += speed[1]*dt;
|
||||
vec[2] += speed[2]*dt;
|
||||
}
|
||||
|
||||
if(accelerate) {
|
||||
vec[0] += accelerate[0]*dt*dt/2;
|
||||
vec[1] += accelerate[1]*dt*dt/2;
|
||||
vec[2] += accelerate[2]*dt*dt/2;
|
||||
}
|
||||
|
||||
/* flip axis (due to verse spec) */
|
||||
tmp = vec[1];
|
||||
vec[1] = -vec[2];
|
||||
vec[2] = tmp;
|
||||
|
||||
if( (((VObjectData*)vnode->data)->pos[0] != vec[0]) ||
|
||||
(((VObjectData*)vnode->data)->pos[1] != vec[1]) ||
|
||||
(((VObjectData*)vnode->data)->pos[2] != vec[2]))
|
||||
{
|
||||
((VObjectData*)vnode->data)->pos[0] = vec[0];
|
||||
((VObjectData*)vnode->data)->pos[1] = vec[1];
|
||||
((VObjectData*)vnode->data)->pos[2] = vec[2];
|
||||
|
||||
((VObjectData*)vnode->data)->post_transform(vnode);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* callback function:
|
||||
*/
|
||||
static void cb_o_transform_rot_real32(
|
||||
void *user_data,
|
||||
VNodeID node_id,
|
||||
uint32 time_s,
|
||||
uint32 time_f,
|
||||
const VNQuat32 *rot,
|
||||
const VNQuat32 *speed,
|
||||
const VNQuat32 *accelerate,
|
||||
const VNQuat32 *drag_normal,
|
||||
real32 drag)
|
||||
{
|
||||
struct VerseSession *session = (VerseSession*)current_verse_session();
|
||||
struct VNode *vnode;
|
||||
float quat[4]={0, 0, 0, 0}, dt;
|
||||
/* float vvec[3], bvec[3];*/
|
||||
|
||||
if(!session) return;
|
||||
|
||||
vnode = BLI_dlist_find_link(&(session->nodes), (unsigned int)node_id);
|
||||
|
||||
((VObjectData*)vnode->data)->flag |= ROT_SEND_READY;
|
||||
|
||||
/* verse server sends automaticaly some stupid default values ...
|
||||
* we have to ignore these values, when we created this object node */
|
||||
if( (vnode->owner_id==VN_OWNER_MINE) && !(((VObjectData*)vnode->data)->flag & ROT_RECEIVE_READY) ) {
|
||||
((VObjectData*)vnode->data)->flag |= ROT_RECEIVE_READY;
|
||||
return;
|
||||
}
|
||||
|
||||
dt = time_s + time_f/(0xffff);
|
||||
|
||||
if(rot) {
|
||||
quat[0] = rot->x;
|
||||
quat[1] = rot->y;
|
||||
quat[2] = rot->z;
|
||||
quat[3] = rot->w;
|
||||
}
|
||||
|
||||
if(speed) {
|
||||
quat[0] += speed->x*dt;
|
||||
quat[1] += speed->y*dt;
|
||||
quat[2] += speed->z*dt;
|
||||
quat[3] += speed->w*dt;
|
||||
}
|
||||
|
||||
if(accelerate) {
|
||||
quat[0] += accelerate->x*dt*dt/2;
|
||||
quat[1] += accelerate->y*dt*dt/2;
|
||||
quat[2] += accelerate->z*dt*dt/2;
|
||||
quat[3] += accelerate->w*dt*dt/2;
|
||||
}
|
||||
|
||||
/* QuatToEul(quat, vvec);
|
||||
bvec[0] = vvec[0];
|
||||
bvec[1] = vvec[1];
|
||||
bvec[2] = vvec[2];
|
||||
EulToQuat(bvec, quat);*/
|
||||
|
||||
if( (((VObjectData*)vnode->data)->rot[0] != quat[0]) ||
|
||||
(((VObjectData*)vnode->data)->rot[1] != quat[1]) ||
|
||||
(((VObjectData*)vnode->data)->rot[2] != quat[2]) ||
|
||||
(((VObjectData*)vnode->data)->rot[3] != quat[3]))
|
||||
{
|
||||
((VObjectData*)vnode->data)->rot[0] = quat[0];
|
||||
((VObjectData*)vnode->data)->rot[1] = quat[1];
|
||||
((VObjectData*)vnode->data)->rot[2] = quat[2];
|
||||
((VObjectData*)vnode->data)->rot[3] = quat[3];
|
||||
|
||||
((VObjectData*)vnode->data)->post_transform(vnode);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* callback function:
|
||||
*/
|
||||
static void cb_o_transform_scale_real32(
|
||||
void *user_data,
|
||||
VNodeID node_id,
|
||||
real32 scale_x,
|
||||
real32 scale_y,
|
||||
real32 scale_z)
|
||||
{
|
||||
struct VerseSession *session = (VerseSession*)current_verse_session();
|
||||
struct VNode *vnode;
|
||||
real32 tmp;
|
||||
|
||||
if(!session) return;
|
||||
|
||||
vnode = BLI_dlist_find_link(&(session->nodes), (unsigned int)node_id);
|
||||
|
||||
((VObjectData*)vnode->data)->flag |= SCALE_SEND_READY;
|
||||
|
||||
/* verse server sends automaticaly some stupid default values ...
|
||||
* we have to ignore these values, when we created this object node */
|
||||
if( (vnode->owner_id==VN_OWNER_MINE) && !(((VObjectData*)vnode->data)->flag & SCALE_RECEIVE_READY) ) {
|
||||
((VObjectData*)vnode->data)->flag |= SCALE_RECEIVE_READY;
|
||||
return;
|
||||
}
|
||||
|
||||
/* flip axis (verse spec) */
|
||||
tmp = scale_y;
|
||||
scale_y = scale_z;
|
||||
scale_z = tmp;
|
||||
|
||||
/* z and y axis are flipped here too */
|
||||
if( (((VObjectData*)vnode->data)->scale[0] != scale_x) ||
|
||||
(((VObjectData*)vnode->data)->scale[1] != scale_y) ||
|
||||
(((VObjectData*)vnode->data)->scale[2] != scale_z))
|
||||
{
|
||||
((VObjectData*)vnode->data)->scale[0] = scale_x;
|
||||
((VObjectData*)vnode->data)->scale[1] = scale_y;
|
||||
((VObjectData*)vnode->data)->scale[2] = scale_z;
|
||||
|
||||
((VObjectData*)vnode->data)->post_transform(vnode);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* callback function: link between object node and some other node was created
|
||||
*/
|
||||
static void cb_o_link_set(
|
||||
void *user_data,
|
||||
VNodeID node_id,
|
||||
uint16 link_id,
|
||||
VNodeID link,
|
||||
const char *label,
|
||||
uint32 target_id)
|
||||
{
|
||||
struct VLink *vlink;
|
||||
struct VNode *source;
|
||||
struct VNode *target;
|
||||
|
||||
struct VerseSession *session = (VerseSession*)current_verse_session();
|
||||
|
||||
if(!session) return;
|
||||
|
||||
source = BLI_dlist_find_link(&(session->nodes), (unsigned int)node_id);
|
||||
target = BLI_dlist_find_link(&(session->nodes), (unsigned int)link);
|
||||
|
||||
if(!(source && target)) return;
|
||||
|
||||
vlink = ((VObjectData*)source->data)->queue.first;
|
||||
|
||||
if(vlink && (vlink->source==source) && (vlink->target==target)) {
|
||||
/* remove VerseLink from sending queue */
|
||||
BLI_remlink(&(((VObjectData*)source->data)->queue), vlink);
|
||||
/* add VerseLink to dynamic list of VerseLinks */
|
||||
BLI_dlist_add_item_index(&(((VObjectData*)source->data)->links), vlink, (unsigned int)link_id);
|
||||
/* send next link from sending queue */
|
||||
if(((VObjectData*)source->data)->queue.first)
|
||||
send_verse_link(((VObjectData*)source->data)->queue.first);
|
||||
/* set up VerseLink variables */
|
||||
vlink->flag = 0;
|
||||
vlink->id = link_id;
|
||||
vlink->target_id = target_id;
|
||||
}
|
||||
else {
|
||||
/* create new VerseLink */
|
||||
vlink = create_verse_link(session, source, target, link_id, target_id, label);
|
||||
/* add VerseLink to dynamic list of VerseLinks */
|
||||
BLI_dlist_add_item_index(&(((VObjectData*)source->data)->links), vlink, (unsigned int)link_id);
|
||||
}
|
||||
|
||||
target->counter++;
|
||||
|
||||
vlink->post_link_set(vlink);
|
||||
}
|
||||
|
||||
/*
|
||||
* callback function: destroy link between two VerseNodes
|
||||
*/
|
||||
static void cb_o_link_destroy(
|
||||
void *user_data,
|
||||
VNodeID node_id,
|
||||
uint16 link_id)
|
||||
{
|
||||
struct VerseSession *session = (VerseSession*)current_verse_session();
|
||||
struct VNode *vnode;
|
||||
struct VLink *vlink;
|
||||
|
||||
if(!session) return;
|
||||
|
||||
vnode = BLI_dlist_find_link(&(session->nodes), (unsigned int)node_id);
|
||||
|
||||
vlink = BLI_dlist_find_link(&(((VObjectData*)vnode->data)->links), link_id);
|
||||
|
||||
if(vlink) {
|
||||
vlink->target->counter--;
|
||||
free_verse_link_data(vlink);
|
||||
BLI_dlist_free_item(&(((VObjectData*)vnode->data)->links), link_id);
|
||||
}
|
||||
|
||||
vlink->post_link_destroy(vlink);
|
||||
}
|
||||
|
||||
void set_object_callbacks(void)
|
||||
{
|
||||
/* position of object was changed */
|
||||
verse_callback_set(verse_send_o_transform_pos_real32, cb_o_transform_pos_real32, NULL);
|
||||
/* rotation of object was changed */
|
||||
verse_callback_set(verse_send_o_transform_rot_real32, cb_o_transform_rot_real32, NULL);
|
||||
/* size of object was changed */
|
||||
verse_callback_set(verse_send_o_transform_scale_real32, cb_o_transform_scale_real32, NULL);
|
||||
/* new link between nodes was created */
|
||||
verse_callback_set(verse_send_o_link_set, cb_o_link_set, NULL);
|
||||
/* link between nodes was destroyed */
|
||||
verse_callback_set(verse_send_o_link_destroy, cb_o_link_destroy, NULL);
|
||||
}
|
||||
|
||||
#endif
|
345
source/blender/blenkernel/intern/verse_session.c
Normal file
345
source/blender/blenkernel/intern/verse_session.c
Normal file
@ -0,0 +1,345 @@
|
||||
/**
|
||||
* $Id$
|
||||
*
|
||||
* ***** BEGIN GPL/BL DUAL 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. The Blender
|
||||
* Foundation also sells licenses for use in proprietary software under
|
||||
* the Blender License. See http://www.blender.org/BL/ for information
|
||||
* about this.
|
||||
*
|
||||
* 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/BL DUAL LICENSE BLOCK *****
|
||||
*/
|
||||
|
||||
#ifdef WITH_VERSE
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "MEM_guardedalloc.h"
|
||||
|
||||
#include "DNA_mesh_types.h" /* temp */
|
||||
#include "DNA_listBase.h"
|
||||
#include "DNA_screen_types.h"
|
||||
|
||||
#include "BLI_dynamiclist.h"
|
||||
#include "BLI_blenlib.h"
|
||||
|
||||
#include "BIF_verse.h"
|
||||
|
||||
#include "BKE_global.h"
|
||||
#include "BKE_verse.h"
|
||||
|
||||
#include "verse.h"
|
||||
|
||||
struct ListBase session_list={NULL, NULL};
|
||||
|
||||
/* list of static function prototypes */
|
||||
static void cb_connect_terminate(const char *address, const char *bye);
|
||||
static void cb_connect_accept(void *user_data, uint32 avatar, void *address, void *connection, const uint8 *host_id);
|
||||
static void set_all_callbacks(void);
|
||||
static void free_verse_session_data(struct VerseSession *session);
|
||||
|
||||
/*
|
||||
* callback function for connection terminated
|
||||
*/
|
||||
static void cb_connect_terminate(const char *address, const char *bye)
|
||||
{
|
||||
VerseSession *session = (VerseSession*)current_verse_session();
|
||||
|
||||
if(!session) return;
|
||||
|
||||
/* remove session from list of session */
|
||||
BLI_remlink(&session_list, session);
|
||||
/* do post connect operations */
|
||||
session->post_connect_terminated(session);
|
||||
/* free session data */
|
||||
free_verse_session_data(session);
|
||||
/* free session */
|
||||
MEM_freeN(session);
|
||||
}
|
||||
|
||||
/*
|
||||
* callback function for accepted connection to verse server
|
||||
*/
|
||||
static void cb_connect_accept(
|
||||
void *user_data,
|
||||
uint32 avatar,
|
||||
void *address,
|
||||
void *connection,
|
||||
const uint8 *host_id)
|
||||
{
|
||||
struct VerseSession *session = (VerseSession*)current_verse_session();
|
||||
uint32 i, mask=0;
|
||||
|
||||
if(!session) return;
|
||||
|
||||
session->flag |= VERSE_CONNECTED;
|
||||
session->flag &= ~VERSE_CONNECTING;
|
||||
|
||||
printf("\tBlender was connected to verse server: %s\n", (char*)address);
|
||||
printf("\tVerseSession->counter: %d\n", session->counter);
|
||||
|
||||
session->avatar = avatar;
|
||||
|
||||
session->post_connect_accept(session);
|
||||
|
||||
for(i = 0; i < V_NT_NUM_TYPES; i++)
|
||||
mask = mask | (1 << i);
|
||||
verse_send_node_index_subscribe(mask);
|
||||
}
|
||||
|
||||
/*
|
||||
* set up all callbacks for sessions
|
||||
*/
|
||||
void set_verse_session_callbacks(void)
|
||||
{
|
||||
/* connection */
|
||||
verse_callback_set(verse_send_connect_accept, cb_connect_accept, NULL);
|
||||
/* connection was terminated */
|
||||
verse_callback_set(verse_send_connect_terminate, cb_connect_terminate, NULL);
|
||||
}
|
||||
|
||||
/*
|
||||
* set all callbacks used in Blender
|
||||
*/
|
||||
static void set_all_callbacks(void)
|
||||
{
|
||||
/* set up all callbacks for sessions */
|
||||
set_verse_session_callbacks();
|
||||
|
||||
/* set up callbacks for nodes */
|
||||
set_node_callbacks();
|
||||
|
||||
/* set up all callbacks for object nodes */
|
||||
set_object_callbacks();
|
||||
|
||||
/* set up all callbacks for geometry nodes */
|
||||
set_geometry_callbacks();
|
||||
|
||||
/* set up all callbacks for bitmap nodes */
|
||||
set_bitmap_callbacks();
|
||||
}
|
||||
|
||||
/*
|
||||
* this function sends and receive all packets for all sessions
|
||||
*/
|
||||
void b_verse_update(void)
|
||||
{
|
||||
VerseSession *session, *next_session;
|
||||
|
||||
session = session_list.first;
|
||||
while(session){
|
||||
next_session = session->next;
|
||||
verse_session_set(session->vsession);
|
||||
if((session->flag & VERSE_CONNECTED) || (session->flag & VERSE_CONNECTING)) {
|
||||
verse_callback_update(10);
|
||||
session->post_connect_update(session);
|
||||
}
|
||||
session = next_session;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* returns VerseSession coresponding to vsession pointer
|
||||
*/
|
||||
VerseSession *versesession_from_vsession(VSession *vsession)
|
||||
{
|
||||
struct VerseSession *session;
|
||||
|
||||
session = session_list.first;
|
||||
|
||||
while(session) {
|
||||
if(session->vsession==vsession) return session;
|
||||
session = session->next;
|
||||
}
|
||||
|
||||
return session;
|
||||
}
|
||||
|
||||
/*
|
||||
* returns pointer at current VerseSession
|
||||
*/
|
||||
VerseSession *current_verse_session(void)
|
||||
{
|
||||
struct VerseSession *session;
|
||||
VSession vsession = verse_session_get();
|
||||
|
||||
session = session_list.first;
|
||||
|
||||
while(session){
|
||||
if(session->vsession == vsession)
|
||||
return session;
|
||||
session = session->next;
|
||||
}
|
||||
|
||||
printf("error: non-existing SESSION occured!\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* free VerseSession
|
||||
*/
|
||||
static void free_verse_session_data(VerseSession *session)
|
||||
{
|
||||
struct VNode *vnode;
|
||||
|
||||
/* free data of all nodes */
|
||||
vnode = session->nodes.lb.first;
|
||||
while(vnode){
|
||||
free_verse_node_data(vnode);
|
||||
vnode = vnode->next;
|
||||
}
|
||||
|
||||
/* free data of nodes waiting in queue */
|
||||
vnode = session->queue.first;
|
||||
while(vnode){
|
||||
free_verse_node_data(vnode);
|
||||
vnode = vnode->next;
|
||||
}
|
||||
|
||||
/* free all VerseNodes */
|
||||
BLI_dlist_destroy(&(session->nodes));
|
||||
/* free all VerseNodes waiting in queque */
|
||||
BLI_freelistN(&(session->queue));
|
||||
|
||||
/* free name of verse host for this session */
|
||||
MEM_freeN(session->address);
|
||||
}
|
||||
|
||||
/*
|
||||
* free VerseSession
|
||||
*/
|
||||
void free_verse_session(VerseSession *session)
|
||||
{
|
||||
/* remove session from session list*/
|
||||
BLI_remlink(&session_list, session);
|
||||
/* do post terminated operations */
|
||||
session->post_connect_terminated(session);
|
||||
/* free session data (nodes, layers) */
|
||||
free_verse_session_data(session);
|
||||
/* free session */
|
||||
MEM_freeN(session);
|
||||
}
|
||||
|
||||
/*
|
||||
* create new verse session and return coresponding data structure
|
||||
*/
|
||||
VerseSession *create_verse_session(
|
||||
const char *name,
|
||||
const char *pass,
|
||||
const char *address,
|
||||
uint8 *expected_key)
|
||||
{
|
||||
struct VerseSession *session;
|
||||
VSession *vsession;
|
||||
|
||||
vsession = verse_send_connect(name, pass, address, expected_key);
|
||||
|
||||
if(!vsession) return NULL;
|
||||
|
||||
session = (VerseSession*)MEM_mallocN(sizeof(VerseSession), "VerseSession");
|
||||
|
||||
session->flag = VERSE_CONNECTING;
|
||||
|
||||
session->vsession = vsession;
|
||||
session->avatar = -1;
|
||||
|
||||
session->address = (char*)MEM_mallocN(sizeof(char)*(strlen(address)+1),"session adress name");
|
||||
strcpy(session->address, address);
|
||||
|
||||
session->connection = NULL;
|
||||
session->host_id = NULL;
|
||||
session->counter = 0;
|
||||
|
||||
/* initialize dynamic list of nodes and node queue */
|
||||
BLI_dlist_init(&(session->nodes));
|
||||
session->queue.first = session->queue.last = NULL;
|
||||
|
||||
/* set up all client dependent functions */
|
||||
session->post_connect_accept = post_connect_accept;
|
||||
session->post_connect_terminated = post_connect_terminated;
|
||||
session->post_connect_update = post_connect_update;
|
||||
|
||||
return session;
|
||||
}
|
||||
|
||||
/*
|
||||
* end verse session and free all session data
|
||||
*/
|
||||
void end_verse_session(VerseSession *session, char free)
|
||||
{
|
||||
/* send terminate command to verse server */
|
||||
verse_send_connect_terminate(session->address, "blender: bye bye");
|
||||
/* update callbacks */
|
||||
verse_callback_update(1000);
|
||||
/* send destroy session command to verse server */
|
||||
verse_session_destroy(session->vsession);
|
||||
/* set up flag of verse session */
|
||||
session->flag &= ~VERSE_CONNECTED;
|
||||
/* do post connect operations */
|
||||
session->post_connect_terminated(session);
|
||||
/* free session data */
|
||||
free_verse_session_data(session);
|
||||
/* free structure of verse session */
|
||||
if(free) free_verse_session(session);
|
||||
}
|
||||
|
||||
/*
|
||||
* end connection to all verse hosts (servers) ... free all VerseSessions
|
||||
*/
|
||||
void end_all_verse_sessions(void)
|
||||
{
|
||||
VerseSession *session;
|
||||
|
||||
session = session_list.first;
|
||||
|
||||
while(session) {
|
||||
end_verse_session(session, 0);
|
||||
/* end next session */
|
||||
session = session->next;
|
||||
}
|
||||
|
||||
BLI_freelistN(&session_list);
|
||||
}
|
||||
|
||||
/*
|
||||
* connect to verse host, set up all callbacks, create session
|
||||
*/
|
||||
void b_verse_connect(char *address)
|
||||
{
|
||||
VerseSession *session;
|
||||
|
||||
/* if no session was created before, then set up all callbacks */
|
||||
if((session_list.first==NULL) && (session_list.last==NULL))
|
||||
set_all_callbacks();
|
||||
|
||||
/* create new session */
|
||||
if(address)
|
||||
session = create_verse_session("Blender", "pass", address, NULL);
|
||||
|
||||
if(session) {
|
||||
/* add new session to the list of sessions */
|
||||
BLI_addtail(&session_list, session);
|
||||
|
||||
/* add verse handler if this is first session */
|
||||
if(session_list.first == session_list.last)
|
||||
add_screenhandler(G.curscreen, SCREEN_HANDLER_VERSE, 1);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
@ -84,6 +84,7 @@ struct rcti;
|
||||
struct EditVert;
|
||||
struct PackedFile;
|
||||
struct LinkNode;
|
||||
struct DynamicList;
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
@ -112,6 +113,17 @@ int BLI_countlist(struct ListBase *listbase);
|
||||
void BLI_freelinkN(ListBase *listbase, void *vlink);
|
||||
void BLI_splitdirstring(char *di,char *fi);
|
||||
|
||||
struct DynamicList *BLI_dlist_from_listbase(struct ListBase *lb);
|
||||
struct ListBase *BLI_listbase_from_dlist(struct DynamicList *dlist, struct ListBase *lb);
|
||||
void * BLI_dlist_find_link(struct DynamicList *dlist, unsigned int index);
|
||||
unsigned int BLI_count_items(struct DynamicList *dlist);
|
||||
void BLI_dlist_free_item(struct DynamicList *dlist, unsigned int index);
|
||||
void BLI_dlist_rem_item(struct DynamicList *dlist, unsigned int index);
|
||||
void * BLI_dlist_add_item_index(struct DynamicList *dlist, void *item, unsigned int index);
|
||||
void BLI_dlist_destroy(struct DynamicList *dlist);
|
||||
void BLI_dlist_init(struct DynamicList *dlist);
|
||||
void BLI_dlist_reinit(struct DynamicList *dlist);
|
||||
|
||||
/**
|
||||
* dir can be any input, like from buttons, and this function
|
||||
* converts it to a regular full path.
|
||||
|
58
source/blender/blenlib/BLI_dynamiclist.h
Normal file
58
source/blender/blenlib/BLI_dynamiclist.h
Normal file
@ -0,0 +1,58 @@
|
||||
/**
|
||||
* $Id$
|
||||
*
|
||||
* ***** BEGIN GPL/BL DUAL 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. The Blender
|
||||
* Foundation also sells licenses for use in proprietary software under
|
||||
* the Blender License. See http://www.blender.org/BL/ for information
|
||||
* about this.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* Documentation of Two way dynamic list with access array can be found at:
|
||||
*
|
||||
* http://wiki.blender.org/bin/view.pl/Blenderwiki/DynamicListWithAccessArray
|
||||
*
|
||||
* ***** END GPL/BL DUAL LICENSE BLOCK *****
|
||||
*/
|
||||
|
||||
#ifndef B_DYNAMIC_LIST_H
|
||||
#define B_DYNAMIC_LIST_H
|
||||
|
||||
#define PAGE_SIZE 4
|
||||
|
||||
struct ListBase;
|
||||
|
||||
/*
|
||||
* Access array using realloc
|
||||
*/
|
||||
typedef struct DynamicArray{
|
||||
unsigned int count; /* count of items in list */
|
||||
unsigned int max_item_index; /* max available index */
|
||||
unsigned int last_item_index; /* max used index */
|
||||
void **items; /* dynamicaly allocated array of pointers
|
||||
pointing at items in list */
|
||||
} DynamicArray;
|
||||
|
||||
/*
|
||||
* Two way dynamic list with access array
|
||||
*/
|
||||
typedef struct DynamicList {
|
||||
struct DynamicArray da; /* access array */
|
||||
struct ListBase lb; /* two way linked dynamic list */
|
||||
} DynamicList;
|
||||
|
||||
#endif
|
@ -68,6 +68,9 @@ typedef struct EditVert
|
||||
int hash;
|
||||
struct MDeformWeight *dw; /* __NLA a pointer to an array of defirm weights */
|
||||
int keyindex; /* original index #, for restoring key information */
|
||||
/*#ifdef WITH_VERSE*/
|
||||
void *vvert;
|
||||
/*#endif*/
|
||||
} EditVert;
|
||||
|
||||
struct EditEdge;
|
||||
@ -124,6 +127,9 @@ typedef struct EditFace
|
||||
unsigned char f, f1, h;
|
||||
unsigned char fast; /* only 0 or 1, for editmesh_fastmalloc */
|
||||
unsigned char fgonf; /* flag for fgon options */
|
||||
/*#ifdef WITH_VERSE*/
|
||||
void *vface;
|
||||
/*#endif*/
|
||||
} EditFace;
|
||||
|
||||
|
||||
@ -154,6 +160,10 @@ typedef struct EditMesh
|
||||
* to derived final, care should be taken on release.
|
||||
*/
|
||||
struct DerivedMesh *derivedCage, *derivedFinal;
|
||||
|
||||
#ifdef WITH_VERSE
|
||||
void *vnode;
|
||||
#endif
|
||||
} EditMesh;
|
||||
|
||||
#endif
|
||||
|
@ -47,6 +47,7 @@
|
||||
#include "DNA_listBase.h"
|
||||
#include "BLI_storage.h"
|
||||
#include "BLI_storage_types.h"
|
||||
#include "BLI_dynamiclist.h"
|
||||
|
||||
#include "BLI_util.h"
|
||||
|
||||
@ -403,6 +404,228 @@ void * BLI_findlink(ListBase *listbase, int number)
|
||||
return (link);
|
||||
}
|
||||
|
||||
/*=====================================================================================*/
|
||||
/* Methods for access array (realloc) */
|
||||
/*=====================================================================================*/
|
||||
|
||||
/* remove item with index */
|
||||
static void rem_array_item(struct DynamicArray *da, unsigned int index)
|
||||
{
|
||||
da->items[index]=NULL;
|
||||
da->count--;
|
||||
if(index==da->last_item_index){
|
||||
while((!da->items[da->last_item_index]) && (da->last_item_index>0)){
|
||||
da->last_item_index--;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* add array (if needed, then realloc) */
|
||||
static void add_array_item(struct DynamicArray *da, void *item, unsigned int index)
|
||||
{
|
||||
/* realloc of access array */
|
||||
if(da->max_item_index < index){
|
||||
unsigned int i, max = da->max_item_index;
|
||||
void **nitems;
|
||||
|
||||
do {
|
||||
da->max_item_index += PAGE_SIZE; /* OS can allocate only PAGE_SIZE Bytes */
|
||||
} while(da->max_item_index<=index);
|
||||
|
||||
nitems = (void**)MEM_mallocN(sizeof(void*)*(da->max_item_index+1), "dlist access array");
|
||||
for(i=0;i<=max;i++)
|
||||
nitems[i] = da->items[i];
|
||||
|
||||
/* set rest pointers to the NULL */
|
||||
for(i=max+1; i<=da->max_item_index; i++)
|
||||
nitems[i]=NULL;
|
||||
|
||||
MEM_freeN(da->items); /* free old access array */
|
||||
da->items = nitems;
|
||||
}
|
||||
|
||||
da->items[index] = item;
|
||||
da->count++;
|
||||
if(index > da->last_item_index) da->last_item_index = index;
|
||||
}
|
||||
|
||||
/* free access array */
|
||||
static void destroy_array(DynamicArray *da)
|
||||
{
|
||||
da->count=0;
|
||||
da->last_item_index=0;
|
||||
da->max_item_index=0;
|
||||
MEM_freeN(da->items);
|
||||
da->items = NULL;
|
||||
}
|
||||
|
||||
/* initialize dynamic array */
|
||||
static void init_array(DynamicArray *da)
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
da->count=0;
|
||||
da->last_item_index=0;
|
||||
da->max_item_index = PAGE_SIZE-1;
|
||||
da->items = (void*)MEM_mallocN(sizeof(void*)*(da->max_item_index+1), "dlist access array");
|
||||
for(i=0; i<=da->max_item_index; i++) da->items[i]=NULL;
|
||||
}
|
||||
|
||||
/* reinitialize dynamic array */
|
||||
static void reinit_array(DynamicArray *da)
|
||||
{
|
||||
destroy_array(da);
|
||||
init_array(da);
|
||||
}
|
||||
|
||||
/*=====================================================================================*/
|
||||
/* Methods for two way dynamic list with access array */
|
||||
/*=====================================================================================*/
|
||||
|
||||
/* create new two way dynamic list with access array from two way dynamic list
|
||||
* it doesn't copy any items to new array or something like this It is strongly
|
||||
* recomended to use BLI_dlist_ methods for adding/removing items from dynamic list
|
||||
* unless you can end with inconsistence system !!! */
|
||||
DynamicList *BLI_dlist_from_listbase(ListBase *lb)
|
||||
{
|
||||
DynamicList *dlist;
|
||||
Link *item;
|
||||
int i=0, count;
|
||||
|
||||
if(!lb) return NULL;
|
||||
|
||||
count = BLI_countlist(lb);
|
||||
|
||||
dlist = MEM_mallocN(sizeof(DynamicList), "temp dynamic list");
|
||||
/* ListBase stuff */
|
||||
dlist->lb.first = lb->first;
|
||||
dlist->lb.last = lb->last;
|
||||
/* access array stuff */
|
||||
dlist->da.count=count;
|
||||
dlist->da.max_item_index = count-1;
|
||||
dlist->da.last_item_index = count -1;
|
||||
dlist->da.items = (void*)MEM_mallocN(sizeof(void*)*count, "temp dlist access array");
|
||||
|
||||
item = (Link*)lb->first;
|
||||
while(item){
|
||||
dlist->da.items[i] = (void*)item;
|
||||
item = item->next;
|
||||
i++;
|
||||
}
|
||||
|
||||
/* to prevent you of using original ListBase :-) */
|
||||
lb->first = lb->last = NULL;
|
||||
|
||||
return dlist;
|
||||
}
|
||||
|
||||
/* take out ListBase from DynamicList and destroy all temporary structures of DynamicList */
|
||||
ListBase *BLI_listbase_from_dlist(DynamicList *dlist, ListBase *lb)
|
||||
{
|
||||
if(!dlist) return NULL;
|
||||
|
||||
if(!lb) lb = (ListBase*)MEM_mallocN(sizeof(ListBase), "ListBase");
|
||||
|
||||
lb->first = dlist->lb.first;
|
||||
lb->last = dlist->lb.last;
|
||||
|
||||
/* free all items of access array */
|
||||
MEM_freeN(dlist->da.items);
|
||||
/* free DynamicList*/
|
||||
MEM_freeN(dlist);
|
||||
|
||||
return lb;
|
||||
}
|
||||
|
||||
/* return pointer at item from th dynamic list with access array */
|
||||
void *BLI_dlist_find_link(DynamicList *dlist, unsigned int index)
|
||||
{
|
||||
if(!dlist || !dlist->da.items) return NULL;
|
||||
|
||||
if((index <= dlist->da.last_item_index) && (index >= 0) && (dlist->da.count>0)){
|
||||
return dlist->da.items[index];
|
||||
}
|
||||
else {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/* return count of items in the dynamic list with access array */
|
||||
unsigned int BLI_count_items(DynamicList *dlist)
|
||||
{
|
||||
if(!dlist) return 0;
|
||||
|
||||
return dlist->da.count;
|
||||
}
|
||||
|
||||
/* free item from the dynamic list with access array */
|
||||
void BLI_dlist_free_item(DynamicList *dlist, unsigned int index)
|
||||
{
|
||||
if(!dlist || !dlist->da.items) return;
|
||||
|
||||
if((index <= dlist->da.last_item_index) && (dlist->da.items[index])){
|
||||
BLI_freelinkN(&(dlist->lb), dlist->da.items[index]);
|
||||
rem_array_item(&(dlist->da), index);
|
||||
}
|
||||
}
|
||||
|
||||
/* remove item from the dynamic list with access array */
|
||||
void BLI_dlist_rem_item(DynamicList *dlist, unsigned int index)
|
||||
{
|
||||
if(!dlist || !dlist->da.items) return;
|
||||
|
||||
if((index <= dlist->da.last_item_index) && (dlist->da.items[index])){
|
||||
BLI_remlink(&(dlist->lb), dlist->da.items[index]);
|
||||
rem_array_item(&(dlist->da), index);
|
||||
}
|
||||
}
|
||||
|
||||
/* add item to the dynamic list with access array (index) */
|
||||
void* BLI_dlist_add_item_index(DynamicList *dlist, void *item, unsigned int index)
|
||||
{
|
||||
if(!dlist || !dlist->da.items) return NULL;
|
||||
|
||||
if((index <= dlist->da.max_item_index) && (dlist->da.items[index])) {
|
||||
/* you can't place item at used index */
|
||||
return NULL;
|
||||
}
|
||||
else {
|
||||
add_array_item(&(dlist->da), item, index);
|
||||
BLI_addtail(&(dlist->lb), item);
|
||||
return item;
|
||||
}
|
||||
}
|
||||
|
||||
/* destroy dynamic list with access array */
|
||||
void BLI_dlist_destroy(DynamicList *dlist)
|
||||
{
|
||||
if(!dlist) return;
|
||||
|
||||
BLI_freelistN(&(dlist->lb));
|
||||
destroy_array(&(dlist->da));
|
||||
}
|
||||
|
||||
/* initialize dynamic list with access array */
|
||||
void BLI_dlist_init(DynamicList *dlist)
|
||||
{
|
||||
if(!dlist) return;
|
||||
|
||||
dlist->lb.first = NULL;
|
||||
dlist->lb.last = NULL;
|
||||
|
||||
init_array(&(dlist->da));
|
||||
}
|
||||
|
||||
/* reinitialize dynamic list with acces array */
|
||||
void BLI_dlist_reinit(DynamicList *dlist)
|
||||
{
|
||||
if(!dlist) return;
|
||||
|
||||
BLI_freelistN(&(dlist->lb));
|
||||
reinit_array(&(dlist->da));
|
||||
}
|
||||
|
||||
/*=====================================================================================*/
|
||||
|
||||
char *BLI_strdupn(char *str, int len) {
|
||||
char *n= MEM_mallocN(len+1, "strdup");
|
||||
|
@ -51,6 +51,11 @@ ifeq ($(OS),$(findstring $(OS), "solaris windows"))
|
||||
CPPFLAGS += -I$(NAN_ZLIB)/include
|
||||
endif
|
||||
|
||||
ifeq ($(WITH_VERSE), true)
|
||||
CPPFLAGS += -DWITH_VERSE
|
||||
CPPFLAGS += -I$(NAN_VERSE)/include
|
||||
endif
|
||||
|
||||
# streaming write function
|
||||
CPPFLAGS += -I../../writestreamglue
|
||||
CPPFLAGS += -I../../readstreamglue
|
||||
|
@ -164,6 +164,10 @@ Important to know is that 'streaming' has been added to files, for Blender Publi
|
||||
#include "BKE_sound.h" /* ... and for samples */
|
||||
#include "BKE_utildefines.h" // for defines
|
||||
#include "BKE_modifier.h"
|
||||
#ifdef WITH_VERSE
|
||||
#include "BKE_verse.h"
|
||||
#include "BIF_verse.h"
|
||||
#endif
|
||||
|
||||
#include "GEN_messaging.h"
|
||||
|
||||
@ -745,7 +749,15 @@ static void write_objects(WriteData *wd, ListBase *idbase)
|
||||
while(ob) {
|
||||
if(ob->id.us>0 || wd->current) {
|
||||
/* write LibData */
|
||||
#ifdef WITH_VERSE
|
||||
/* pointer at vnode stored in file have to be NULL */
|
||||
struct VNode *vnode = (VNode*)ob->vnode;
|
||||
if(vnode) ob->vnode = NULL;
|
||||
#endif
|
||||
writestruct(wd, ID_OB, "Object", 1, ob);
|
||||
#ifdef WITH_VERSE
|
||||
if(vnode) ob->vnode = (void*)vnode;
|
||||
#endif
|
||||
|
||||
/* direct data */
|
||||
writedata(wd, DATA, sizeof(void *)*ob->totcol, ob->mat);
|
||||
@ -987,7 +999,19 @@ static void write_meshs(WriteData *wd, ListBase *idbase)
|
||||
while(mesh) {
|
||||
if(mesh->id.us>0 || wd->current) {
|
||||
/* write LibData */
|
||||
#ifdef WITH_VERSE
|
||||
struct VNode *vnode = (VNode*)mesh->vnode;
|
||||
if(vnode) {
|
||||
/* mesh has to be created from verse geometry node*/
|
||||
create_meshdata_from_geom_node(mesh, vnode);
|
||||
/* pointer at verse node can't be stored in file */
|
||||
mesh->vnode = NULL;
|
||||
}
|
||||
#endif
|
||||
writestruct(wd, ID_ME, "Mesh", 1, mesh);
|
||||
#ifdef WITH_VERSE
|
||||
if(vnode) mesh->vnode = (void*)vnode;
|
||||
#endif
|
||||
|
||||
/* direct data */
|
||||
writedata(wd, DATA, sizeof(void *)*mesh->totcol, mesh->mat);
|
||||
|
@ -66,6 +66,11 @@ typedef struct TreeElement {
|
||||
#define TSE_SCRIPT_BASE 12
|
||||
#define TSE_POSE_BASE 13
|
||||
#define TSE_POSE_CHANNEL 14
|
||||
/*#ifdef WITH_VERSE*/
|
||||
#define TSE_VERSE_SESSION 15
|
||||
#define TSE_VERSE_OBJ_NODE 16
|
||||
#define TSE_VERSE_GEOM_NODE 17
|
||||
/*#endif*/
|
||||
|
||||
/* button events */
|
||||
#define OL_NAMEBUTTON 1
|
||||
|
134
source/blender/include/BIF_verse.h
Normal file
134
source/blender/include/BIF_verse.h
Normal file
@ -0,0 +1,134 @@
|
||||
/**
|
||||
* $Id$
|
||||
*
|
||||
* ***** BEGIN GPL/BL DUAL 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. The Blender
|
||||
* Foundation also sells licenses for use in proprietary software under
|
||||
* the Blender License. See http://www.blender.org/BL/ for information
|
||||
* about this.
|
||||
*
|
||||
* 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/BL DUAL LICENSE BLOCK *****
|
||||
*/
|
||||
|
||||
#ifdef WITH_VERSE
|
||||
|
||||
#ifndef BIF_VERSE_H
|
||||
#define BIF_VERSE_H
|
||||
|
||||
#include "BKE_verse.h"
|
||||
#include "DNA_meshdata_types.h"
|
||||
|
||||
struct Object;
|
||||
|
||||
struct EditVert;
|
||||
struct EditFace;
|
||||
struct MVert;
|
||||
struct Mface;
|
||||
|
||||
/* verse_object.c */
|
||||
void unsubscribe_from_obj_node(struct VNode *vnode);
|
||||
void unsubscribe_from_geom_node(struct VNode *vnode);
|
||||
void unsubscribe_from_bitmap_node(struct VNode *vnode);
|
||||
|
||||
void test_and_send_idbutton_cb(void *obj, void *ob_name);
|
||||
|
||||
struct Object *create_object_from_verse_node(struct VNode *vnode);
|
||||
|
||||
void b_verse_pop_node(struct VNode *vnode);
|
||||
void b_verse_unsubscribe(VNode *vnode);
|
||||
void b_verse_push_object(struct VerseSession *session, struct Object *ob);
|
||||
void b_verse_delete_object(struct Object *ob);
|
||||
|
||||
void post_transform(struct VNode *vnode);
|
||||
void post_link_set(struct VLink *vlink);
|
||||
void post_link_destroy(struct VLink *vlink);
|
||||
void post_object_free_constraint(struct VNode *vnode);
|
||||
|
||||
void b_verse_send_transformation(struct Object *ob);
|
||||
|
||||
/* verse_mesh.c */
|
||||
void b_verse_send_vertex_delete(struct EditVert *eve);
|
||||
void send_versevert_pos(struct VerseVert *vvert);
|
||||
|
||||
void b_verse_send_face_delete(struct EditFace *efa);
|
||||
|
||||
void sync_all_versefaces_with_editfaces(struct VNode *vnode);
|
||||
void sync_all_verseverts_with_editverts(struct VNode *vnode);
|
||||
|
||||
void createVerseVert(struct EditVert *ev);
|
||||
void createVerseFace(struct EditFace *efa);
|
||||
|
||||
void b_verse_duplicate_object(struct VerseSession *session, struct Object *ob, struct Object *n_ob);
|
||||
struct VNode *create_geom_vnode_from_geom_vnode(struct VNode *vnode);
|
||||
struct VNode *create_geom_vnode_data_from_editmesh(struct VerseSession *session, struct EditMesh *em);
|
||||
struct VNode *create_geom_vnode_data_from_mesh(struct VerseSession *session, struct Mesh *me);
|
||||
|
||||
void destroy_unused_geometry(struct VNode *vnode);
|
||||
void destroy_binding_between_versemesh_and_editmesh(struct VNode *vnode);
|
||||
|
||||
void destroy_verse_mesh(struct VNode *vnode);
|
||||
|
||||
void unsubscribe_from_geom_node(struct VNode *vnode);
|
||||
|
||||
void create_edit_mesh_from_geom_node(struct VNode *vnode);
|
||||
struct Mesh *create_mesh_from_geom_node(struct VNode *vnode);
|
||||
void create_meshdata_from_geom_node(struct Mesh *me, struct VNode *vnode);
|
||||
|
||||
/* geometry post callback functions */
|
||||
void post_layer_create(struct VLayer *vlayer);
|
||||
void post_layer_destroy(struct VLayer *vlayer);
|
||||
|
||||
void post_vertex_create(struct VerseVert *vvert);
|
||||
void post_vertex_set_xyz(struct VerseVert *vvert);
|
||||
void post_vertex_delete(struct VerseVert *vvert);
|
||||
void post_vertex_free_constraint(struct VerseVert *vvert);
|
||||
|
||||
void post_polygon_set_uint8(struct VerseFace *vface);
|
||||
void post_polygon_create(struct VerseFace *vface);
|
||||
void post_polygon_set_corner(struct VerseFace *vface);
|
||||
void post_polygon_delete(struct VerseFace *vface);
|
||||
void post_polygon_free_constraint(struct VerseFace *vface);
|
||||
|
||||
void post_geometry_free_constraint(struct VNode *vnode);
|
||||
|
||||
/* verse_common.c */
|
||||
struct VerseSession *session_menu(void);
|
||||
char *verse_client_name(void);
|
||||
|
||||
void post_tag_change(struct VTag *vtag);
|
||||
void post_taggroup_create(struct VTagGroup *vtaggroup);
|
||||
|
||||
void post_node_create(struct VNode *vnode);
|
||||
void post_node_destroy(struct VNode *vnode);
|
||||
void post_node_name_set(struct VNode *vnode);
|
||||
|
||||
void post_connect_accept(struct VerseSession *session);
|
||||
void post_connect_terminated(struct VerseSession *session);
|
||||
void post_connect_update(struct VerseSession *session);
|
||||
|
||||
/* verse_image.c */
|
||||
|
||||
void sync_blender_image_with_verse_bitmap_node(struct VNode *vnode);
|
||||
void post_bitmap_dimension_set(struct VNode *vnode);
|
||||
void post_bitmap_layer_create(struct VBitmapLayer *vblayer);
|
||||
void post_bitmap_layer_destroy(struct VBitmapLayer *vblayer);
|
||||
void post_bitmap_tile_set(struct VBitmapLayer *vblayer, unsigned int xs, unsigned int ys);
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
@ -89,6 +89,9 @@
|
||||
|
||||
#define SELECT 1
|
||||
#define ACTIVE 2
|
||||
/*#ifdef WITH_VERSE*/
|
||||
#define VERSE 3
|
||||
/*#endif*/
|
||||
#define DESELECT 0
|
||||
#define NOT_YET 0
|
||||
|
||||
|
@ -128,6 +128,9 @@ typedef struct TransData {
|
||||
void *tdmir; /* mirrored element pointer, in editmode mesh to EditVert */
|
||||
short flag; /* Various flags */
|
||||
short protectflag; /* If set, copy of Object or PoseChannel protection */
|
||||
/*#ifdef WITH_VERSE*/
|
||||
void *verse; /* pointer at verse data struct (VerseVert, etc.) */
|
||||
/*#endif*/
|
||||
} TransData;
|
||||
|
||||
typedef struct TransInfo {
|
||||
@ -232,6 +235,10 @@ typedef struct TransInfo {
|
||||
#define TD_USEQUAT 4
|
||||
#define TD_NOTCONNECTED 8
|
||||
#define TD_SINGLESIZE 16 /* used for scaling of MetaElem->rad */
|
||||
#ifdef WITH_VERSE
|
||||
#define TD_VERSE_OBJECT 32
|
||||
#define TD_VERSE_VERT 64
|
||||
#endif
|
||||
|
||||
void checkFirstTime(void);
|
||||
|
||||
|
@ -140,6 +140,11 @@ typedef struct Library {
|
||||
/* used in outliner... */
|
||||
#define ID_NLA MAKE_ID2('N', 'L')
|
||||
|
||||
/*#ifdef WITH_VERSE*/
|
||||
#define ID_VS MAKE_ID2('V', 'S') /* fake id for VerseSession, needed for outliner */
|
||||
#define ID_VN MAKE_ID2('V', 'N') /* fake id for VerseNode, needed for outliner */
|
||||
/*#endif*/
|
||||
|
||||
|
||||
/* id->flag: set frist 8 bits always at zero while reading */
|
||||
#define LIB_LOCAL 0
|
||||
|
@ -73,6 +73,9 @@ typedef struct Image {
|
||||
short animspeed;
|
||||
short reserved1;
|
||||
int reserved2;
|
||||
/*#ifdef WITH_VERSE*/
|
||||
void *vnode; /* pointer at verse bitmap node */
|
||||
/*#endif*/
|
||||
} Image;
|
||||
|
||||
/* in Image struct */
|
||||
|
@ -99,6 +99,10 @@ typedef struct Mesh {
|
||||
short totcol;
|
||||
short subsurftype;
|
||||
|
||||
/*ifdef WITH_VERSE*/
|
||||
/* not written in file, pointer at geometry VerseNode */
|
||||
void *vnode;
|
||||
/*#endif*/
|
||||
} Mesh;
|
||||
|
||||
|
||||
|
@ -201,6 +201,10 @@ typedef struct Object {
|
||||
struct FluidsimSettings *fluidsimSettings; /* if fluidsim enabled, store additional settings */
|
||||
|
||||
struct DerivedMesh *derivedDeform, *derivedFinal;
|
||||
|
||||
/*#ifdef WITH_VERSE*/
|
||||
void *vnode; /* pointer at object VerseNode */
|
||||
/*#endif*/
|
||||
} Object;
|
||||
|
||||
typedef struct ObHook {
|
||||
|
@ -123,6 +123,15 @@ ifeq ($(INTERNATIONAL), true)
|
||||
CPPFLAGS += -DINTERNATIONAL
|
||||
endif
|
||||
|
||||
ifeq ($(WITH_VERSE), true)
|
||||
CPPFLAGS += -DWITH_VERSE
|
||||
CPPFLAGS += -I$(NAN_VERSE)/include
|
||||
# print some other debug information
|
||||
ifeq ($(VERSE_DEBUG_PRINT), true)
|
||||
CPPFLAGS += -DVERSE_DEBUG_PRINT
|
||||
endif
|
||||
endif
|
||||
|
||||
ifeq ($(NAN_TWEAK_MODE), true)
|
||||
CPPFLAGS += -DTWEAK_MODE
|
||||
endif
|
||||
|
@ -117,6 +117,10 @@
|
||||
#include "BIF_previewrender.h"
|
||||
#include "BIF_butspace.h"
|
||||
|
||||
#ifdef WITH_VERSE
|
||||
#include "BIF_verse.h"
|
||||
#endif
|
||||
|
||||
#include "mydevice.h"
|
||||
#include "blendef.h"
|
||||
|
||||
@ -3499,6 +3503,10 @@ static void editing_panel_mesh_tools1(Object *ob, Mesh *me)
|
||||
|
||||
/* Measurement drawing options */
|
||||
uiBlockBeginAlign(block);
|
||||
#ifdef WITH_VERSE
|
||||
if(G.editMesh->vnode)
|
||||
uiDefButBitI(block, TOG, G_DRAW_VERSE_DEBUG, REDRAWVIEW3D, "Draw VDebug",1125,132,150,19, &G.f, 0, 0, 0, 0, "Displays verse debug information");
|
||||
#endif
|
||||
uiDefButBitI(block, TOG, G_DRAW_VNORMALS, REDRAWVIEW3D, "Draw VNormals",1125,110,150,19, &G.f, 0, 0, 0, 0, "Displays vertex normals as lines");
|
||||
uiDefButBitI(block, TOG, G_DRAW_EDGELEN, REDRAWVIEW3D, "Edge Length", 1125,88,150,19, &G.f, 0, 0, 0, 0, "Displays selected edge lengths");
|
||||
uiDefButBitI(block, TOG, G_DRAW_EDGEANG, REDRAWVIEW3D, "Edge Angles", 1125,66,150,19, &G.f, 0, 0, 0, 0, "Displays the angles in the selected edges in degrees");
|
||||
@ -3608,7 +3616,13 @@ static void editing_panel_links(Object *ob)
|
||||
}
|
||||
if(ob) {
|
||||
but = uiDefBut(block, TEX, B_IDNAME, "OB:", xco, 180, 454-xco, YIC, ob->id.name+2, 0.0, 19.0, 0, 0, "Displays Active Object name. Click to change.");
|
||||
#ifdef WITH_VERSE
|
||||
if(ob->vnode) uiButSetFunc(but, test_and_send_idbutton_cb, ob, ob->id.name);
|
||||
else uiButSetFunc(but, test_idbutton_cb, ob->id.name, NULL);
|
||||
#else
|
||||
uiButSetFunc(but, test_idbutton_cb, ob->id.name, NULL);
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
@ -92,6 +92,9 @@
|
||||
#include "BKE_mball.h"
|
||||
#include "BKE_object.h"
|
||||
#include "BKE_anim.h" //for the where_on_path function
|
||||
#ifdef WITH_VERSE
|
||||
#include "BKE_verse.h"
|
||||
#endif
|
||||
|
||||
#include "BIF_gl.h"
|
||||
#include "BIF_glutil.h"
|
||||
@ -325,7 +328,13 @@ static void drawcentercircle(float *vec, int selstate, int special_color)
|
||||
glEnable(GL_BLEND);
|
||||
|
||||
if(special_color) {
|
||||
#ifdef WITH_VERSE
|
||||
if (selstate==VERSE) glColor4ub(0x00, 0xFF, 0x00, 155);
|
||||
else if (selstate==ACTIVE || selstate==SELECT) glColor4ub(0x88, 0xFF, 0xFF, 155);
|
||||
#else
|
||||
if (selstate==ACTIVE || selstate==SELECT) glColor4ub(0x88, 0xFF, 0xFF, 155);
|
||||
#endif
|
||||
|
||||
else glColor4ub(0x55, 0xCC, 0xCC, 155);
|
||||
}
|
||||
else {
|
||||
@ -1506,6 +1515,71 @@ static void draw_em_fancy_edges(DerivedMesh *cageDM)
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef WITH_VERSE
|
||||
/*
|
||||
* draw some debug info about verse mesh (vertex indexes,
|
||||
* face indexes, status of )
|
||||
*/
|
||||
static draw_verse_debug(Object *ob, EditMesh *em)
|
||||
{
|
||||
struct EditVert *eve=NULL;
|
||||
struct EditFace *efa=NULL;
|
||||
float v1[3], v2[3], v3[3], v4[3], fvec[3], col[3];
|
||||
char val[32];
|
||||
|
||||
if(G.vd->zbuf && (G.vd->flag & V3D_ZBUF_SELECT)==0)
|
||||
glDisable(GL_DEPTH_TEST);
|
||||
|
||||
if(G.vd->zbuf) bglPolygonOffset(5.0);
|
||||
|
||||
BIF_GetThemeColor3fv(TH_TEXT, col);
|
||||
/* make color a bit more red */
|
||||
if(col[0]> 0.5) {col[1]*=0.7; col[2]*= 0.7;}
|
||||
else col[0]= col[0]*0.7 + 0.3;
|
||||
glColor3fv(col);
|
||||
|
||||
/* draw IDs of verse vertexes */
|
||||
for(eve = em->verts.first; eve; eve = eve->next) {
|
||||
if(eve->vvert) {
|
||||
VecLerpf(fvec, ob->loc, eve->co, 1.1);
|
||||
glRasterPos3f(fvec[0], fvec[1], fvec[2]);
|
||||
|
||||
sprintf(val, "%d", ((VerseVert*)eve->vvert)->id);
|
||||
BMF_DrawString(G.fonts, val);
|
||||
}
|
||||
}
|
||||
|
||||
/* draw IDs of verse faces */
|
||||
for(efa = em->faces.first; efa; efa = efa->next) {
|
||||
if(efa->vface) {
|
||||
VECCOPY(v1, efa->v1->co);
|
||||
VECCOPY(v2, efa->v2->co);
|
||||
VECCOPY(v3, efa->v3->co);
|
||||
if(efa->v4) {
|
||||
VECCOPY(v4, efa->v4->co);
|
||||
glRasterPos3f(0.25*(v1[0]+v2[0]+v3[0]+v4[0]),
|
||||
0.25*(v1[1]+v2[1]+v3[1]+v4[1]),
|
||||
0.25*(v1[2]+v2[2]+v3[2]+v4[2]));
|
||||
}
|
||||
else {
|
||||
glRasterPos3f((v1[0]+v2[0]+v3[0])/3,
|
||||
(v1[1]+v2[1]+v3[1])/3,
|
||||
(v1[2]+v2[2]+v3[2])/3);
|
||||
}
|
||||
|
||||
sprintf(val, "%d", ((VerseFace*)efa->vface)->id);
|
||||
BMF_DrawString(G.fonts, val);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
if(G.vd->zbuf) {
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
bglPolygonOffset(0.0);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
static void draw_em_measure_stats(Object *ob, EditMesh *em)
|
||||
{
|
||||
EditEdge *eed;
|
||||
@ -1760,6 +1834,10 @@ static void draw_em_fancy(Object *ob, EditMesh *em, DerivedMesh *cageDM, Derived
|
||||
|
||||
if(G.f & (G_DRAW_EDGELEN|G_DRAW_FACEAREA|G_DRAW_EDGEANG))
|
||||
draw_em_measure_stats(ob, em);
|
||||
#ifdef WITH_VERSE
|
||||
if(em->vnode && (G.f & G_DRAW_VERSE_DEBUG))
|
||||
draw_verse_debug(ob, em);
|
||||
#endif
|
||||
}
|
||||
|
||||
if(dt>OB_WIRE) {
|
||||
@ -1808,8 +1886,31 @@ static void draw_mesh_fancy(Base *base, DerivedMesh *baseDM, DerivedMesh *dm, in
|
||||
Material *ma= give_current_material(ob, 1);
|
||||
int hasHaloMat = (ma && (ma->mode&MA_HALO));
|
||||
int draw_wire = ob->dtx&OB_DRAWWIRE;
|
||||
int totvert, totedge, totface;
|
||||
DispList *dl;
|
||||
|
||||
#ifdef WITH_VERSE
|
||||
if(me->vnode) {
|
||||
struct VNode *vnode = (VNode*)me->vnode;
|
||||
struct VLayer *vert_vlayer = find_verse_layer_type((VGeomData*)vnode->data, VERTEX_LAYER);
|
||||
struct VLayer *face_vlayer = find_verse_layer_type((VGeomData*)vnode->data, POLYGON_LAYER);
|
||||
|
||||
if(vert_vlayer) totvert = vert_vlayer->dl.da.count;
|
||||
else totvert = 0;
|
||||
totedge = 0; /* total count of edge needn't to be zero, but verse doesn't know edges */
|
||||
if(face_vlayer) totface = face_vlayer->dl.da.count;
|
||||
else totface = 0;
|
||||
}
|
||||
else {
|
||||
totvert = me->totvert;
|
||||
totedge = me->totedge;
|
||||
totface = me->totface;
|
||||
}
|
||||
#else
|
||||
totvert = me->totvert;
|
||||
totedge = me->totedge;
|
||||
totface = me->totface;
|
||||
#endif
|
||||
glFrontFace((ob->transflag&OB_NEG_SCALE)?GL_CW:GL_CCW);
|
||||
|
||||
// Unwanted combination.
|
||||
@ -1818,12 +1919,12 @@ static void draw_mesh_fancy(Base *base, DerivedMesh *baseDM, DerivedMesh *dm, in
|
||||
if(dt==OB_BOUNDBOX) {
|
||||
draw_bounding_volume(ob);
|
||||
}
|
||||
else if(hasHaloMat || (me->totface==0 && me->totedge==0)) {
|
||||
else if(hasHaloMat || (totface==0 && totedge==0)) {
|
||||
glPointSize(1.5);
|
||||
dm->drawVerts(dm);
|
||||
glPointSize(1.0);
|
||||
}
|
||||
else if(dt==OB_WIRE || me->totface==0) {
|
||||
else if(dt==OB_WIRE || totface==0) {
|
||||
draw_wire = 1;
|
||||
}
|
||||
else if( (ob==OBACT && (G.f & G_FACESELECT)) || (G.vd->drawtype==OB_TEXTURE && dt>OB_SOLID)) {
|
||||
@ -1946,7 +2047,7 @@ static void draw_mesh_fancy(Base *base, DerivedMesh *baseDM, DerivedMesh *dm, in
|
||||
// if (G.f & (G_VERTEXPAINT|G_WEIGHTPAINT|G_TEXTUREPAINT)) {
|
||||
// baseDM->drawEdges(baseDM, dt==OB_WIRE);
|
||||
// } else {
|
||||
dm->drawEdges(dm, (dt==OB_WIRE || me->totface==0));
|
||||
dm->drawEdges(dm, (dt==OB_WIRE || totface==0));
|
||||
// }
|
||||
|
||||
if (dt!=OB_WIRE) {
|
||||
@ -3999,7 +4100,12 @@ void draw_object(Base *base, int flag)
|
||||
}
|
||||
else if((flag & DRAW_CONSTCOLOR)==0) {
|
||||
/* we don't draw centers for duplicators and sets */
|
||||
drawcentercircle(ob->obmat[3], do_draw_center, ob->id.lib || ob->id.us>1);
|
||||
#ifdef WITH_VERSE
|
||||
if(ob->vnode)
|
||||
drawcentercircle(ob->obmat[3], VERSE, 1);
|
||||
else
|
||||
#endif
|
||||
drawcentercircle(ob->obmat[3], do_draw_center, ob->id.lib || ob->id.us>1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -112,6 +112,10 @@
|
||||
#include "BIF_screen.h"
|
||||
#include "BIF_space.h"
|
||||
|
||||
#ifdef WITH_VERSE
|
||||
#include "BIF_verse.h"
|
||||
#endif
|
||||
|
||||
#include "BDR_drawmesh.h"
|
||||
#include "BDR_drawobject.h"
|
||||
#include "BDR_editobject.h"
|
||||
@ -2228,7 +2232,13 @@ static void view3d_panel_object(short cntrl) // VIEW3D_HANDLER_OBJECT
|
||||
}
|
||||
else {
|
||||
bt= uiDefBut(block, TEX, B_IDNAME, "OB: ", 10,180,140,20, ob->id.name+2, 0.0, 19.0, 0, 0, "");
|
||||
#ifdef WITH_VERSE
|
||||
if(ob->vnode) uiButSetFunc(bt, test_and_send_idbutton_cb, ob, ob->id.name);
|
||||
else uiButSetFunc(bt, test_idbutton_cb, ob->id.name, NULL);
|
||||
#else
|
||||
uiButSetFunc(bt, test_idbutton_cb, ob->id.name, NULL);
|
||||
#endif
|
||||
|
||||
|
||||
uiDefIDPoinBut(block, test_obpoin_but, ID_OB, B_OBJECTPANELPARENT, "Par:", 160, 180, 140, 20, &ob->parent, "Parent Object");
|
||||
}
|
||||
|
@ -82,6 +82,10 @@
|
||||
#include "BKE_object.h"
|
||||
#include "BKE_utildefines.h"
|
||||
|
||||
#ifdef WITH_VERSE
|
||||
#include "BKE_verse.h"
|
||||
#endif
|
||||
|
||||
#include "BIF_editmesh.h"
|
||||
#include "BIF_editview.h"
|
||||
#include "BIF_editarmature.h"
|
||||
@ -94,6 +98,10 @@
|
||||
#include "BIF_screen.h"
|
||||
#include "BIF_toolbox.h"
|
||||
|
||||
#ifdef WITH_VERSE
|
||||
#include "BIF_verse.h"
|
||||
#endif
|
||||
|
||||
#include "BSE_edit.h"
|
||||
#include "BSE_drawipo.h"
|
||||
#include "BSE_drawview.h"
|
||||
@ -759,6 +767,10 @@ static void special_transvert_update(void)
|
||||
DAG_object_flush_update(G.scene, G.obedit, OB_RECALC_DATA);
|
||||
|
||||
if(G.obedit->type==OB_MESH) {
|
||||
#ifdef WITH_VERSE
|
||||
if(G.editMesh->vnode)
|
||||
sync_all_verseverts_with_editverts((VNode*)G.editMesh->vnode);
|
||||
#endif
|
||||
recalc_editnormals(); // does face centers too
|
||||
}
|
||||
else if ELEM(G.obedit->type, OB_CURVE, OB_SURF) {
|
||||
@ -1114,6 +1126,9 @@ void snap_sel_to_grid()
|
||||
ob->loc[1]+= vec[1];
|
||||
ob->loc[2]+= vec[2];
|
||||
}
|
||||
#ifdef WITH_VERSE
|
||||
if(ob->vnode) b_verse_send_transformation(ob);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
@ -1212,6 +1227,9 @@ void snap_sel_to_curs()
|
||||
ob->loc[1]+= vec[1];
|
||||
ob->loc[2]+= vec[2];
|
||||
}
|
||||
#ifdef WITH_VERSE
|
||||
if(ob->vnode) b_verse_send_transformation(ob);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
@ -1519,6 +1537,9 @@ void snap_to_center()
|
||||
ob->loc[1]+= vec[1];
|
||||
ob->loc[2]+= vec[2];
|
||||
}
|
||||
#ifdef WITH_VERSE
|
||||
if(ob->vnode) b_verse_send_transformation(ob);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -74,6 +74,10 @@
|
||||
#include "BKE_texture.h"
|
||||
#include "BKE_utildefines.h"
|
||||
|
||||
#ifdef WITH_VERSE
|
||||
#include "BKE_verse.h"
|
||||
#endif
|
||||
|
||||
#include "BIF_editkey.h"
|
||||
#include "BIF_editmesh.h"
|
||||
#include "BIF_editmode_undo.h"
|
||||
@ -84,6 +88,10 @@
|
||||
#include "BIF_screen.h"
|
||||
#include "BIF_toolbox.h"
|
||||
|
||||
#ifdef WITH_VERSE
|
||||
#include "BIF_verse.h"
|
||||
#endif
|
||||
|
||||
#include "BSE_view.h"
|
||||
#include "BSE_edit.h"
|
||||
#include "BSE_trans_types.h"
|
||||
@ -141,11 +149,27 @@ EditVert *addvertlist(float *vec)
|
||||
* have a pre-editmode vertex order
|
||||
*/
|
||||
eve->keyindex = -1;
|
||||
|
||||
#ifdef WITH_VERSE
|
||||
createVerseVert(eve);
|
||||
#endif
|
||||
|
||||
return eve;
|
||||
}
|
||||
|
||||
void free_editvert (EditVert *eve)
|
||||
{
|
||||
#ifdef WITH_VERSE
|
||||
if(eve->vvert) {
|
||||
/* it prevents from removing all verse vertexes
|
||||
* during entering edit mode ... messy solution */
|
||||
if(G.editMesh->vnode)
|
||||
b_verse_send_vertex_delete(eve);
|
||||
else
|
||||
((VerseVert*)eve->vvert)->vertex = NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
if(eve->dw) MEM_freeN(eve->dw);
|
||||
EM_remove_selection(eve, EDITVERT);
|
||||
if(eve->fast==0){
|
||||
@ -288,6 +312,16 @@ void free_editedge(EditEdge *eed)
|
||||
|
||||
void free_editface(EditFace *efa)
|
||||
{
|
||||
#ifdef WITH_VERSE
|
||||
if(efa->vface) {
|
||||
/* it prevents from removing all verse faces
|
||||
* during entering edit mode ... messy solution */
|
||||
if(G.editMesh->vnode)
|
||||
b_verse_send_face_delete(efa);
|
||||
else
|
||||
((VerseFace*)efa->vface)->face = NULL;
|
||||
}
|
||||
#endif
|
||||
EM_remove_selection(efa, EDITFACE);
|
||||
if(efa->fast==0){
|
||||
free(efa);
|
||||
@ -397,6 +431,10 @@ EditFace *addfacelist(EditVert *v1, EditVert *v2, EditVert *v3, EditVert *v4, Ed
|
||||
CalcCent3f(efa->cent, efa->v1->co, efa->v2->co, efa->v3->co);
|
||||
}
|
||||
|
||||
#ifdef WITH_VERSE
|
||||
createVerseFace(efa);
|
||||
#endif
|
||||
|
||||
return efa;
|
||||
}
|
||||
|
||||
@ -500,8 +538,18 @@ static void end_editmesh_fastmalloc(void)
|
||||
|
||||
void free_editMesh(EditMesh *em)
|
||||
{
|
||||
#ifdef WITH_VERSE
|
||||
struct VNode *vnode=NULL;
|
||||
#endif
|
||||
if(em==NULL) return;
|
||||
|
||||
|
||||
#ifdef WITH_VERSE
|
||||
if(em->vnode) {
|
||||
vnode = (VNode*)em->vnode;
|
||||
em->vnode = NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
if(em->verts.first) free_vertlist(&em->verts);
|
||||
if(em->edges.first) free_edgelist(&em->edges);
|
||||
if(em->faces.first) free_facelist(&em->faces);
|
||||
@ -517,6 +565,12 @@ void free_editMesh(EditMesh *em)
|
||||
em->derivedCage= NULL;
|
||||
}
|
||||
|
||||
#ifdef WITH_VERSE
|
||||
if(vnode) {
|
||||
em->vnode = (void*)vnode;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* DEBUG: hashtabs are slowest part of enter/exit editmode. here a testprint */
|
||||
#if 0
|
||||
if(em->hashedgetab) {
|
||||
@ -727,6 +781,13 @@ void make_editMesh()
|
||||
EditSelection *ese;
|
||||
int tot, a, eekadoodle= 0;
|
||||
|
||||
#ifdef WITH_VERSE
|
||||
if(me->vnode){
|
||||
create_edit_mesh_from_geom_node(me->vnode);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* because of reload */
|
||||
free_editMesh(G.editMesh);
|
||||
|
||||
@ -907,6 +968,15 @@ void load_editMesh(void)
|
||||
MDeformVert *dvert;
|
||||
|
||||
waitcursor(1);
|
||||
|
||||
#ifdef WITH_VERSE
|
||||
if(em->vnode) {
|
||||
struct VNode *vnode = (VNode*)em->vnode;
|
||||
((VGeomData*)vnode->data)->editmesh = NULL;
|
||||
em->vnode = NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
countall();
|
||||
|
||||
/* this one also tests of edges are not in faces: */
|
||||
@ -989,7 +1059,13 @@ void load_editMesh(void)
|
||||
if(eve->f1==1) mvert->flag |= ME_SPHERETEST;
|
||||
mvert->flag |= (eve->f & SELECT);
|
||||
if (eve->h) mvert->flag |= ME_HIDE;
|
||||
|
||||
|
||||
#ifdef WITH_VERSE
|
||||
if(eve->vvert) {
|
||||
((VerseVert*)eve->vvert)->vertex = NULL;
|
||||
eve->vvert = NULL;
|
||||
}
|
||||
#endif
|
||||
eve= eve->next;
|
||||
mvert++;
|
||||
if(dvert) dvert++;
|
||||
@ -1069,7 +1145,13 @@ void load_editMesh(void)
|
||||
|
||||
/* no index '0' at location 3 or 4 */
|
||||
test_index_face(mface, NULL, &efa->tf, efa->v4?4:3);
|
||||
|
||||
|
||||
#ifdef WITH_VERSE
|
||||
if(efa->vface) {
|
||||
((VerseFace*)efa->vface)->face = NULL;
|
||||
efa->vface = NULL;
|
||||
}
|
||||
#endif
|
||||
efa->tmp.l = a++;
|
||||
i++;
|
||||
efa= efa->next;
|
||||
@ -1326,6 +1408,9 @@ void separate_mesh(void)
|
||||
Mesh *me, *men;
|
||||
Base *base, *oldbase;
|
||||
ListBase edve, eded, edvl;
|
||||
#ifdef WITH_VERSE
|
||||
struct VNode *vnode = NULL;
|
||||
#endif
|
||||
|
||||
TEST_EDITMESH
|
||||
|
||||
@ -1359,9 +1444,21 @@ void separate_mesh(void)
|
||||
base= base->next;
|
||||
}
|
||||
|
||||
#ifdef WITH_VERSE
|
||||
if(G.editMesh->vnode) {
|
||||
vnode = G.editMesh->vnode;
|
||||
G.editMesh->vnode = NULL;
|
||||
}
|
||||
#endif
|
||||
/* no test for split, split doesn't split when a loose part is selected */
|
||||
/* SPLIT: first make duplicate */
|
||||
adduplicateflag(SELECT);
|
||||
|
||||
#ifdef WITH_VERSE
|
||||
if(vnode) {
|
||||
G.editMesh->vnode = vnode;
|
||||
}
|
||||
#endif
|
||||
/* SPLIT: old faces have 3x flag 128 set, delete these ones */
|
||||
delfaceflag(128);
|
||||
|
||||
@ -1376,7 +1473,14 @@ void separate_mesh(void)
|
||||
if((eve->f & SELECT)==0) {
|
||||
BLI_remlink(&em->verts, eve);
|
||||
BLI_addtail(&edve, eve);
|
||||
#ifdef WITH_VERSE
|
||||
if(eve->vvert) {
|
||||
((VerseVert*)eve->vvert)->vertex = NULL;
|
||||
eve->vvert = NULL;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
eve= v1;
|
||||
}
|
||||
eed= em->edges.first;
|
||||
@ -1394,6 +1498,12 @@ void separate_mesh(void)
|
||||
if((efa->f & SELECT)==0) {
|
||||
BLI_remlink(&em->faces, efa);
|
||||
BLI_addtail(&edvl, efa);
|
||||
#ifdef WITH_VERSE
|
||||
if(efa->vface) {
|
||||
((VerseFace*)efa->vface)->face = NULL;
|
||||
efa->vface = NULL;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
efa= vl1;
|
||||
}
|
||||
@ -1401,7 +1511,18 @@ void separate_mesh(void)
|
||||
oldob= G.obedit;
|
||||
oldbase= BASACT;
|
||||
|
||||
#ifdef WITH_VERSE
|
||||
if(G.obedit->vnode) {
|
||||
vnode = G.obedit->vnode;
|
||||
G.obedit->vnode = NULL;
|
||||
}
|
||||
#endif
|
||||
adduplicate(1, 0); /* notrans and a linked duplicate*/
|
||||
#ifdef WITH_VERSE
|
||||
if(vnode) {
|
||||
G.obedit->vnode = vnode;
|
||||
}
|
||||
#endif
|
||||
|
||||
G.obedit= BASACT->object; /* basact was set in adduplicate() */
|
||||
|
||||
@ -1428,7 +1549,7 @@ void separate_mesh(void)
|
||||
|
||||
/* hashedges are freed now, make new! */
|
||||
editMesh_set_hash();
|
||||
|
||||
|
||||
DAG_object_flush_update(G.scene, G.obedit, OB_RECALC_DATA);
|
||||
G.obedit= oldob;
|
||||
BASACT= oldbase;
|
||||
@ -1449,13 +1570,28 @@ void separate_mesh_loose(void)
|
||||
EditVert *eve, *v1;
|
||||
EditEdge *eed, *e1;
|
||||
EditFace *efa, *vl1;
|
||||
Object *oldob;
|
||||
Object *oldob=NULL;
|
||||
Mesh *me, *men;
|
||||
Base *base, *oldbase;
|
||||
ListBase edve, eded, edvl;
|
||||
int vertsep=0;
|
||||
short done=0, check=1;
|
||||
|
||||
#ifdef WITH_VERSE
|
||||
struct VNode *vnode = NULL;
|
||||
#endif
|
||||
|
||||
me= get_mesh(G.obedit);
|
||||
#ifdef WITH_VERSE
|
||||
if(me->vnode) {
|
||||
error("Can't separate a mesh shared at verse server");
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
if(me->key) {
|
||||
error("Can't separate a mesh with vertex keys");
|
||||
return;
|
||||
}
|
||||
|
||||
TEST_EDITMESH
|
||||
waitcursor(1);
|
||||
|
||||
@ -1467,19 +1603,11 @@ void separate_mesh_loose(void)
|
||||
* 5. freelist and get back old verts, edges, facs
|
||||
*/
|
||||
|
||||
|
||||
|
||||
while(!done){
|
||||
vertsep=check=1;
|
||||
|
||||
countall();
|
||||
|
||||
me= get_mesh(G.obedit);
|
||||
if(me->key) {
|
||||
error("Can't separate a mesh with vertex keys");
|
||||
return;
|
||||
}
|
||||
|
||||
/* make only obedit selected */
|
||||
base= FIRSTBASE;
|
||||
while(base) {
|
||||
@ -1541,6 +1669,11 @@ void separate_mesh_loose(void)
|
||||
if((eve->f & SELECT)==0) {
|
||||
BLI_remlink(&em->verts, eve);
|
||||
BLI_addtail(&edve, eve);
|
||||
#ifdef WITH_VERSE
|
||||
if(eve->vvert) {
|
||||
b_verse_send_vertex_delete(eve);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
eve= v1;
|
||||
}
|
||||
@ -1559,6 +1692,11 @@ void separate_mesh_loose(void)
|
||||
if( (efa->f & SELECT)==0 ) {
|
||||
BLI_remlink(&em->faces, efa);
|
||||
BLI_addtail(&edvl, efa);
|
||||
#ifdef WITH_VERSE
|
||||
if(efa->vface) {
|
||||
b_verse_send_face_delete(efa);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
efa= vl1;
|
||||
}
|
||||
@ -1566,10 +1704,21 @@ void separate_mesh_loose(void)
|
||||
oldob= G.obedit;
|
||||
oldbase= BASACT;
|
||||
|
||||
adduplicate(1, 0); /* notrans and 0 for linked duplicate */
|
||||
#ifdef WITH_VERSE
|
||||
if(G.obedit->vnode) {
|
||||
vnode = G.obedit->vnode;
|
||||
G.obedit->vnode = NULL;
|
||||
}
|
||||
#endif
|
||||
adduplicate(1, 0); /* notrans and a linked duplicate*/
|
||||
#ifdef WITH_VERSE
|
||||
if(vnode) {
|
||||
G.obedit->vnode = vnode;
|
||||
}
|
||||
#endif
|
||||
|
||||
G.obedit= BASACT->object; /* basact was set in adduplicate() */
|
||||
|
||||
|
||||
men= copy_mesh(me);
|
||||
set_mesh(G.obedit, men);
|
||||
/* because new mesh is a copy: reduce user count */
|
||||
@ -1627,7 +1776,7 @@ typedef struct EditVertC
|
||||
unsigned char f, h;
|
||||
short totweight;
|
||||
struct MDeformWeight *dw;
|
||||
int keyindex;
|
||||
int keyindex;
|
||||
} EditVertC;
|
||||
|
||||
typedef struct EditEdgeC
|
||||
@ -1791,18 +1940,28 @@ static void undoMesh_to_editMesh(void *umv)
|
||||
EditSelectionC *esec;
|
||||
TFace *tface;
|
||||
int a=0;
|
||||
|
||||
|
||||
#ifdef WITH_VERSE
|
||||
struct VNode *vnode = G.editMesh->vnode;
|
||||
if(vnode) {
|
||||
/* send delete command to all verse vertexes and verse face ...
|
||||
* verse mesh will be recreated from new edit mesh */
|
||||
destroy_versemesh(vnode);
|
||||
}
|
||||
#endif
|
||||
G.scene->selectmode = um->selectmode;
|
||||
|
||||
free_editMesh(G.editMesh);
|
||||
|
||||
/* malloc blocks */
|
||||
memset(em, 0, sizeof(EditMesh));
|
||||
|
||||
|
||||
|
||||
init_editmesh_fastmalloc(em, um->totvert, um->totedge, um->totface);
|
||||
|
||||
#ifdef WITH_VERSE
|
||||
G.editMesh->vnode = vnode;
|
||||
#endif
|
||||
|
||||
/* now copy vertices */
|
||||
if(um->totvert) evar= MEM_mallocN(um->totvert*sizeof(EditVert *), "vertex ar");
|
||||
for(a=0, evec= um->verts; a<um->totvert; a++, evec++) {
|
||||
@ -1867,6 +2026,7 @@ static void undoMesh_to_editMesh(void *umv)
|
||||
}
|
||||
EM_free_index_arrays();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
@ -60,6 +60,11 @@
|
||||
#include "BKE_object.h"
|
||||
#include "BKE_utildefines.h"
|
||||
|
||||
#ifdef WITH_VERSE
|
||||
#include "BKE_verse.h"
|
||||
#endif
|
||||
|
||||
|
||||
#include "BIF_editmesh.h"
|
||||
#include "BIF_graphics.h"
|
||||
#include "BIF_interface.h"
|
||||
@ -69,6 +74,10 @@
|
||||
#include "BIF_toolbox.h"
|
||||
#include "BIF_transform.h"
|
||||
|
||||
#ifdef WITH_VERSE
|
||||
#include "BIF_verse.h"
|
||||
#endif
|
||||
|
||||
#include "BDR_editobject.h"
|
||||
|
||||
#include "BSE_view.h"
|
||||
@ -233,6 +242,12 @@ void add_click_mesh(void)
|
||||
|
||||
countall();
|
||||
|
||||
#ifdef WITH_VERSE
|
||||
if(G.editMesh->vnode) {
|
||||
sync_all_verseverts_with_editverts((VNode*)G.editMesh->vnode);
|
||||
}
|
||||
#endif
|
||||
|
||||
BIF_undo_push("Add vertex/edge/face");
|
||||
allqueue(REDRAWVIEW3D, 0);
|
||||
DAG_object_flush_update(G.scene, G.obedit, OB_RECALC_DATA);
|
||||
@ -561,7 +576,18 @@ static void fix_new_face(EditFace *eface)
|
||||
eface->flag &= ~ME_SMOOTH;
|
||||
|
||||
/* flip face, when too much "face normals" in neighbourhood is different */
|
||||
if(count > 0) flipface(eface);
|
||||
if(count > 0) {
|
||||
flipface(eface);
|
||||
#ifdef WITH_VERSE
|
||||
if(eface->vface) {
|
||||
struct VNode *vnode;
|
||||
struct VLayer *vlayer;
|
||||
vnode = (VNode*)((Mesh*)G.obedit->data)->vnode;
|
||||
vlayer = find_verse_layer_type((VGeomData*)vnode->data, POLYGON_LAYER);
|
||||
add_item_to_send_queue(&(vlayer->queue), (void*)eface->vface, VERSE_FACE);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
void addedgeface_mesh(void)
|
||||
|
@ -63,6 +63,10 @@ editmesh_lib: generic (no UI, no menus) operations/evaluators for editmesh data
|
||||
|
||||
#include "BIF_editmesh.h"
|
||||
|
||||
#ifdef WITH_VERSE
|
||||
#include "BIF_verse.h"
|
||||
#endif
|
||||
|
||||
#include "BSE_edit.h"
|
||||
|
||||
#include "editmesh.h"
|
||||
@ -1711,6 +1715,10 @@ void flip_editnormals(void)
|
||||
}
|
||||
efa= efa->next;
|
||||
}
|
||||
#ifdef WITH_VERSE
|
||||
if(G.editMesh->vnode)
|
||||
sync_all_versefaces_with_editfaces((VNode*)G.editMesh->vnode);
|
||||
#endif
|
||||
}
|
||||
|
||||
/* does face centers too */
|
||||
|
@ -63,6 +63,10 @@ editmesh_loop: tools with own drawing subloops, select, knife, subdiv
|
||||
#include "BKE_object.h"
|
||||
#include "BKE_utildefines.h"
|
||||
|
||||
#ifdef WITH_VERSE
|
||||
#include "BKE_verse.h"
|
||||
#endif
|
||||
|
||||
#include "BIF_cursors.h"
|
||||
#include "BIF_editmesh.h"
|
||||
#include "BIF_gl.h"
|
||||
@ -74,6 +78,10 @@ editmesh_loop: tools with own drawing subloops, select, knife, subdiv
|
||||
#include "BIF_space.h"
|
||||
#include "BIF_toolbox.h"
|
||||
|
||||
#ifdef WITH_VERSE
|
||||
#include "BIF_verse.h"
|
||||
#endif
|
||||
|
||||
#include "BSE_view.h"
|
||||
#include "BSE_edit.h"
|
||||
#include "BSE_drawview.h"
|
||||
@ -402,8 +410,12 @@ void CutEdgeloop(int numcuts)
|
||||
}
|
||||
|
||||
DAG_object_flush_update(G.scene, G.obedit, OB_RECALC_DATA);
|
||||
#ifdef WITH_VERSE
|
||||
if(G.editMesh->vnode)
|
||||
sync_all_verseverts_with_editverts((VNode*)G.editMesh->vnode);
|
||||
#endif
|
||||
scrarea_queue_headredraw(curarea);
|
||||
scrarea_queue_winredraw(curarea);
|
||||
scrarea_queue_winredraw(curarea);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -754,6 +766,12 @@ void KnifeSubdivide(char mode)
|
||||
window_set_cursor(win, oldcursor);
|
||||
BLI_ghash_free(gh, NULL, (GHashValFreeFP)MEM_freeN);
|
||||
if (curve) MEM_freeN(curve);
|
||||
|
||||
#ifdef WITH_VERSE
|
||||
if(G.editMesh->vnode)
|
||||
sync_all_versefaces_with_editfaces((VNode*)G.editMesh->vnode);
|
||||
#endif
|
||||
|
||||
BIF_undo_push("Knife");
|
||||
}
|
||||
|
||||
|
@ -68,6 +68,10 @@ editmesh_mods.c, UI level access, no geometry changes
|
||||
#include "BKE_texture.h"
|
||||
#include "BKE_utildefines.h"
|
||||
|
||||
#ifdef WITH_VERSE
|
||||
#include "BKE_verse.h"
|
||||
#endif
|
||||
|
||||
#include "BIF_editmesh.h"
|
||||
#include "BIF_resources.h"
|
||||
#include "BIF_gl.h"
|
||||
@ -81,6 +85,10 @@ editmesh_mods.c, UI level access, no geometry changes
|
||||
#include "BIF_space.h"
|
||||
#include "BIF_toolbox.h"
|
||||
|
||||
#ifdef WITH_VERSE
|
||||
#include "BIF_verse.h"
|
||||
#endif
|
||||
|
||||
#include "BDR_drawobject.h"
|
||||
#include "BDR_editobject.h"
|
||||
|
||||
@ -2792,6 +2800,11 @@ void righthandfaces(int select) /* makes faces righthand turning */
|
||||
recalc_editnormals();
|
||||
|
||||
DAG_object_flush_update(G.scene, G.obedit, OB_RECALC_DATA);
|
||||
|
||||
#ifdef WITH_VERSE
|
||||
if(G.editMesh->vnode)
|
||||
sync_all_versefaces_with_editfaces((VNode*)G.editMesh->vnode);
|
||||
#endif
|
||||
|
||||
waitcursor(0);
|
||||
}
|
||||
@ -3081,6 +3094,11 @@ void vertexsmooth(void)
|
||||
|
||||
allqueue(REDRAWVIEW3D, 0);
|
||||
DAG_object_flush_update(G.scene, G.obedit, OB_RECALC_DATA);
|
||||
|
||||
#ifdef WITH_VERSE
|
||||
if(G.editMesh->vnode)
|
||||
sync_all_verseverts_with_editverts(G.editMesh->vnode);
|
||||
#endif
|
||||
BIF_undo_push("Vertex Smooth");
|
||||
}
|
||||
|
||||
@ -3128,6 +3146,10 @@ void vertexnoise(void)
|
||||
recalc_editnormals();
|
||||
allqueue(REDRAWVIEW3D, 0);
|
||||
DAG_object_flush_update(G.scene, G.obedit, OB_RECALC_DATA);
|
||||
#ifdef WITH_VERSE
|
||||
if(G.editMesh->vnode)
|
||||
sync_all_verseverts_with_editverts(G.editMesh->vnode);
|
||||
#endif
|
||||
BIF_undo_push("Vertex Noise");
|
||||
}
|
||||
|
||||
@ -3192,6 +3214,10 @@ void vertices_to_sphere(void)
|
||||
recalc_editnormals();
|
||||
allqueue(REDRAWVIEW3D, 0);
|
||||
DAG_object_flush_update(G.scene, G.obedit, OB_RECALC_DATA);
|
||||
#ifdef WITH_VERSE
|
||||
if(G.editMesh->vnode)
|
||||
sync_all_verseverts_with_editverts(G.editMesh->vnode);
|
||||
#endif
|
||||
BIF_undo_push("To Sphere");
|
||||
}
|
||||
|
||||
|
@ -72,6 +72,10 @@ editmesh_tool.c: UI called tools for editmesh, geometry changes here, otherwise
|
||||
#include "BKE_object.h"
|
||||
#include "BKE_utildefines.h"
|
||||
|
||||
#ifdef WITH_VERSE
|
||||
#include "BKE_verse.h"
|
||||
#endif
|
||||
|
||||
#include "BIF_cursors.h"
|
||||
#include "BIF_editmesh.h"
|
||||
#include "BIF_gl.h"
|
||||
@ -85,6 +89,10 @@ editmesh_tool.c: UI called tools for editmesh, geometry changes here, otherwise
|
||||
#include "BIF_toolbox.h"
|
||||
#include "BIF_transform.h"
|
||||
|
||||
#ifdef WITH_VERSE
|
||||
#include "BIF_verse.h"
|
||||
#endif
|
||||
|
||||
#include "BDR_drawobject.h"
|
||||
#include "BDR_editobject.h"
|
||||
|
||||
@ -200,6 +208,11 @@ void convert_to_triface(int direction)
|
||||
}
|
||||
|
||||
EM_fgon_flags(); // redo flags and indices for fgons
|
||||
|
||||
#ifdef WITH_VERSE
|
||||
if(G.editMesh->vnode)
|
||||
sync_all_versefaces_with_editfaces((VNode*)G.editMesh->vnode);
|
||||
#endif
|
||||
BIF_undo_push("Convert Quads to Triangles");
|
||||
|
||||
}
|
||||
@ -509,6 +522,13 @@ int removedoublesflag(short flag, float limit) /* return amount */
|
||||
eve= nextve;
|
||||
}
|
||||
|
||||
#ifdef WITH_VERSE
|
||||
if((a>0) && (G.editMesh->vnode)) {
|
||||
sync_all_verseverts_with_editverts((VNode*)G.editMesh->vnode);
|
||||
sync_all_versefaces_with_editfaces((VNode*)G.editMesh->vnode);
|
||||
}
|
||||
#endif
|
||||
|
||||
return a; /* amount */
|
||||
}
|
||||
|
||||
@ -549,6 +569,12 @@ void xsortvert_flag(int flag)
|
||||
addlisttolist(&em->verts, &tbase);
|
||||
|
||||
MEM_freeN(sortblock);
|
||||
|
||||
#ifdef WITH_VERSE
|
||||
if(G.editMesh->vnode)
|
||||
sync_all_versefaces_with_editfaces((VNode*)G.editMesh->vnode);
|
||||
#endif
|
||||
|
||||
BIF_undo_push("Xsort");
|
||||
|
||||
}
|
||||
@ -609,6 +635,10 @@ void hashvert_flag(int flag)
|
||||
addlisttolist(&em->verts, &tbase);
|
||||
|
||||
MEM_freeN(sortblock);
|
||||
#ifdef WITH_VERSE
|
||||
if(G.editMesh->vnode)
|
||||
sync_all_versefaces_with_editfaces((VNode*)G.editMesh->vnode);
|
||||
#endif
|
||||
BIF_undo_push("Hash");
|
||||
|
||||
}
|
||||
@ -710,6 +740,12 @@ void split_mesh(void)
|
||||
countall();
|
||||
allqueue(REDRAWVIEW3D, 0);
|
||||
DAG_object_flush_update(G.scene, G.obedit, OB_RECALC_DATA);
|
||||
|
||||
#ifdef WITH_VERSE
|
||||
if(G.editMesh->vnode)
|
||||
sync_all_versefaces_with_editfaces((VNode*)G.editMesh->vnode);
|
||||
#endif
|
||||
|
||||
BIF_undo_push("Split");
|
||||
|
||||
}
|
||||
@ -747,7 +783,7 @@ void extrude_repeat_mesh(int steps, float offs)
|
||||
|
||||
allqueue(REDRAWVIEW3D, 0);
|
||||
DAG_object_flush_update(G.scene, G.obedit, OB_RECALC_DATA);
|
||||
|
||||
|
||||
BIF_undo_push("Extrude Repeat");
|
||||
}
|
||||
|
||||
@ -833,6 +869,7 @@ void spin_mesh(int steps, int degr, float *dvec, int mode)
|
||||
countall();
|
||||
allqueue(REDRAWVIEW3D, 0);
|
||||
DAG_object_flush_update(G.scene, G.obedit, OB_RECALC_DATA);
|
||||
|
||||
|
||||
if(dvec==NULL) BIF_undo_push("Spin");
|
||||
}
|
||||
@ -1180,6 +1217,12 @@ void fill_mesh(void)
|
||||
countall();
|
||||
allqueue(REDRAWVIEW3D, 0);
|
||||
DAG_object_flush_update(G.scene, G.obedit, OB_RECALC_DATA);
|
||||
|
||||
#ifdef WITH_VERSE
|
||||
if(G.editMesh->vnode)
|
||||
sync_all_versefaces_with_editfaces((VNode*)G.editMesh->vnode);
|
||||
#endif
|
||||
|
||||
BIF_undo_push("Fill");
|
||||
}
|
||||
/*GB*/
|
||||
@ -3310,6 +3353,10 @@ void beauty_fill(void)
|
||||
|
||||
allqueue(REDRAWVIEW3D, 0);
|
||||
DAG_object_flush_update(G.scene, G.obedit, OB_RECALC_DATA);
|
||||
#ifdef WITH_VERSE
|
||||
if(G.editMesh->vnode)
|
||||
sync_all_versefaces_with_editfaces((VNode*)G.editMesh->vnode);
|
||||
#endif
|
||||
BIF_undo_push("Beauty Fill");
|
||||
}
|
||||
|
||||
@ -3404,6 +3451,10 @@ void join_triangles(void)
|
||||
|
||||
allqueue(REDRAWVIEW3D, 0);
|
||||
DAG_object_flush_update(G.scene, G.obedit, OB_RECALC_DATA);
|
||||
#ifdef WITH_VERSE
|
||||
if(G.editMesh->vnode)
|
||||
sync_all_versefaces_with_editfaces((VNode*)G.editMesh->vnode);
|
||||
#endif
|
||||
BIF_undo_push("Convert Triangles to Quads");
|
||||
}
|
||||
|
||||
@ -3515,6 +3566,10 @@ void edge_flip(void)
|
||||
|
||||
allqueue(REDRAWVIEW3D, 0);
|
||||
DAG_object_flush_update(G.scene, G.obedit, OB_RECALC_DATA);
|
||||
#ifdef WITH_VERSE
|
||||
if(G.editMesh->vnode)
|
||||
sync_all_versefaces_with_editfaces((VNode*)G.editMesh->vnode);
|
||||
#endif
|
||||
BIF_undo_push("Flip Triangle Edges");
|
||||
|
||||
}
|
||||
@ -3974,7 +4029,12 @@ void edge_rotate_selected(int dir)
|
||||
|
||||
allqueue(REDRAWVIEW3D, 0);
|
||||
DAG_object_flush_update(G.scene, G.obedit, OB_RECALC_DATA);
|
||||
|
||||
|
||||
#ifdef WITH_VERSE
|
||||
if(G.editMesh->vnode)
|
||||
sync_all_versefaces_with_editfaces((VNode*)G.editMesh->vnode);
|
||||
#endif
|
||||
|
||||
BIF_undo_push("Rotate Edge");
|
||||
}
|
||||
|
||||
@ -5377,10 +5437,18 @@ int EdgeSlide(short immediate, float imperc)
|
||||
BLI_ghash_free(vertgh, NULL, (GHashValFreeFP)MEM_freeN);
|
||||
BLI_linklist_free(vertlist,NULL);
|
||||
BLI_linklist_free(edgelist,NULL);
|
||||
|
||||
|
||||
if(cancel == 1) {
|
||||
return -1;
|
||||
}
|
||||
else {
|
||||
#ifdef WITH_VERSE
|
||||
if(G.editMesh->vnode) {
|
||||
sync_all_verseverts_with_editverts((VNode*)G.editMesh->vnode);
|
||||
sync_all_versefaces_with_editfaces((VNode*)G.editMesh->vnode);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -5638,7 +5706,14 @@ void mesh_rip(void)
|
||||
}
|
||||
|
||||
countall(); // apparently always needed when adding stuff, derived mesh
|
||||
|
||||
|
||||
#ifdef WITH_VERSE
|
||||
if(G.editMesh->vnode) {
|
||||
sync_all_verseverts_with_editverts((VNode*)G.editMesh->vnode);
|
||||
sync_all_versefaces_with_editfaces((VNode*)G.editMesh->vnode);
|
||||
}
|
||||
#endif
|
||||
|
||||
BIF_TransformSetUndo("Rip");
|
||||
initTransform(TFM_TRANSLATION, 0);
|
||||
Transform();
|
||||
|
@ -143,6 +143,10 @@
|
||||
#include "BIF_toolbox.h"
|
||||
#include "BIF_toets.h"
|
||||
|
||||
#ifdef WITH_VERSE
|
||||
#include "BIF_verse.h"
|
||||
#endif
|
||||
|
||||
#include "BSE_edit.h"
|
||||
#include "BSE_editipo.h"
|
||||
#include "BSE_filesel.h" /* For activate_databrowse() */
|
||||
@ -255,7 +259,9 @@ void delete_obj(int ok)
|
||||
if TESTBASE(base) {
|
||||
if(ok==0 && (ok=okee("Erase selected Object(s)"))==0) return;
|
||||
if(base->object->type==OB_LAMP) islamp= 1;
|
||||
|
||||
#ifdef WITH_VERSE
|
||||
if(base->object->vnode) b_verse_delete_object(base->object);
|
||||
#endif
|
||||
free_and_unlink_base(base);
|
||||
}
|
||||
|
||||
@ -961,16 +967,40 @@ void clear_object(char mode)
|
||||
memset(ob->drot, 0, 3*sizeof(float));
|
||||
QuatOne(ob->quat);
|
||||
QuatOne(ob->dquat);
|
||||
#ifdef WITH_VERSE
|
||||
if(ob->vnode) {
|
||||
struct VNode *vnode = (VNode*)ob->vnode;
|
||||
((VObjectData*)vnode->data)->flag |= ROT_SEND_READY;
|
||||
b_verse_send_transformation(ob);
|
||||
}
|
||||
#endif
|
||||
|
||||
}
|
||||
else if(mode=='g') {
|
||||
memset(ob->loc, 0, 3*sizeof(float));
|
||||
memset(ob->dloc, 0, 3*sizeof(float));
|
||||
#ifdef WITH_VERSE
|
||||
if(ob->vnode) {
|
||||
struct VNode *vnode = (VNode*)ob->vnode;
|
||||
((VObjectData*)vnode->data)->flag |= POS_SEND_READY;
|
||||
b_verse_send_transformation(ob);
|
||||
}
|
||||
#endif
|
||||
|
||||
}
|
||||
else if(mode=='s') {
|
||||
memset(ob->dsize, 0, 3*sizeof(float));
|
||||
ob->size[0]= 1.0;
|
||||
ob->size[1]= 1.0;
|
||||
ob->size[2]= 1.0;
|
||||
#ifdef WITH_VERSE
|
||||
if(ob->vnode) {
|
||||
struct VNode *vnode = (VNode*)ob->vnode;
|
||||
((VObjectData*)vnode->data)->flag |= SCALE_SEND_READY;
|
||||
b_verse_send_transformation(ob);
|
||||
}
|
||||
#endif
|
||||
|
||||
}
|
||||
else if(mode=='o') {
|
||||
if(ob->parent) {
|
||||
@ -1661,7 +1691,6 @@ void docentre(int centremode)
|
||||
Mat4MulVecfl(base->object->imat, cent);
|
||||
} else {
|
||||
INIT_MINMAX(min, max);
|
||||
|
||||
mvert= me->mvert;
|
||||
for(a=0; a<me->totvert; a++, mvert++) {
|
||||
DO_MINMAX(mvert->co, min, max);
|
||||
@ -1671,7 +1700,7 @@ void docentre(int centremode)
|
||||
cent[1]= (min[1]+max[1])/2.0f;
|
||||
cent[2]= (min[2]+max[2])/2.0f;
|
||||
}
|
||||
|
||||
|
||||
mvert= me->mvert;
|
||||
for(a=0; a<me->totvert; a++, mvert++) {
|
||||
VecSubf(mvert->co, mvert->co, cent);
|
||||
@ -3770,7 +3799,19 @@ void single_obdata_users(int flag)
|
||||
Mesh *me;
|
||||
ID *id;
|
||||
int a;
|
||||
|
||||
|
||||
#ifdef WITH_VERSE
|
||||
base= FIRSTBASE;
|
||||
while(base) {
|
||||
ob= base->object;
|
||||
if(ob->vnode) {
|
||||
error("Can't make data single user, when data are shared at verse server");
|
||||
return;
|
||||
}
|
||||
base = base->next;
|
||||
}
|
||||
#endif
|
||||
|
||||
base= FIRSTBASE;
|
||||
while(base) {
|
||||
ob= base->object;
|
||||
@ -4478,6 +4519,13 @@ void adduplicate(int mode, int dupflag)
|
||||
}
|
||||
}
|
||||
}
|
||||
#ifdef WITH_VERSE
|
||||
/* send new created object to verse server,
|
||||
* when original object was linked with object node */
|
||||
if(ob->vnode) {
|
||||
b_verse_duplicate_object(((VNode*)ob->vnode)->session, ob, obn);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -76,6 +76,10 @@
|
||||
#include "BKE_blender.h"
|
||||
#include "BKE_screen.h"
|
||||
|
||||
#ifdef WITH_VERSE
|
||||
#include "BKE_verse.h"
|
||||
#endif
|
||||
|
||||
#include "BIF_cursors.h"
|
||||
#include "BIF_drawscene.h"
|
||||
#include "BIF_editsound.h"
|
||||
@ -1118,6 +1122,10 @@ int do_screenhandlers(bScreen *sc)
|
||||
done= 1;
|
||||
break;
|
||||
case SCREEN_HANDLER_VERSE:
|
||||
#ifdef WITH_VERSE
|
||||
b_verse_update();
|
||||
#endif
|
||||
|
||||
done= 1;
|
||||
break;
|
||||
}
|
||||
|
@ -79,6 +79,10 @@
|
||||
#include "BIF_writeimage.h"
|
||||
#include "BIF_drawscene.h"
|
||||
|
||||
#ifdef WITH_VERSE
|
||||
#include "BIF_verse.h"
|
||||
#endif
|
||||
|
||||
#include "BKE_blender.h"
|
||||
#include "BKE_depsgraph.h"
|
||||
#include "BKE_exotic.h"
|
||||
@ -91,6 +95,10 @@
|
||||
#include "BKE_scene.h"
|
||||
#include "BKE_world.h"
|
||||
|
||||
#ifdef WITH_VERSE
|
||||
#include "BKE_verse.h"
|
||||
#endif
|
||||
|
||||
#include "BLI_arithb.h"
|
||||
#include "BLI_blenlib.h"
|
||||
#include "BLO_writefile.h"
|
||||
@ -720,6 +728,82 @@ static uiBlock *info_file_exportmenu(void *arg_unused)
|
||||
return block;
|
||||
}
|
||||
|
||||
#ifdef WITH_VERSE
|
||||
|
||||
extern ListBase session_list;
|
||||
|
||||
static void do_verse_filemenu(void *arg, int event)
|
||||
{
|
||||
char address[64]; /* lenght of domain name is 63 characters or less */
|
||||
VerseSession *session = NULL;
|
||||
ScrArea *sa;
|
||||
|
||||
if(curarea->spacetype==SPACE_INFO) {
|
||||
sa= closest_bigger_area();
|
||||
areawinset(sa->win);
|
||||
}
|
||||
|
||||
switch(event) {
|
||||
case 0:
|
||||
waitcursor(1);
|
||||
printf("Connecting to localhost!\n");
|
||||
b_verse_connect("localhost");
|
||||
waitcursor(0);
|
||||
break;
|
||||
case 1:
|
||||
address[0] = '\0';
|
||||
if(sbutton(address, 0, 63, "Server:")) {
|
||||
waitcursor(1);
|
||||
printf("Connecting to %s\n", address);
|
||||
b_verse_connect(address);
|
||||
waitcursor(0);
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
session = session_menu();
|
||||
if(session) {
|
||||
printf("Disconnecting session: %s!\n", session->address);
|
||||
end_verse_session(session, 1);
|
||||
}
|
||||
break;
|
||||
case 3:
|
||||
printf("Disconnecting all sessions!\n");
|
||||
end_all_verse_sessions();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static uiBlock *verse_filemenu(void *unusedargs)
|
||||
{
|
||||
uiBlock *block;
|
||||
short yco = 20, menuwidth = 120;
|
||||
|
||||
block= uiNewBlock(&curarea->uiblocks, "verse_filemenu", UI_EMBOSSP, UI_HELV, G.curscreen->mainwin);
|
||||
uiBlockSetButmFunc(block, do_verse_filemenu, NULL);
|
||||
|
||||
uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Connect to localhost", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 0, "");
|
||||
uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Connect ...", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 1, "");
|
||||
if(session_list.first != NULL) {
|
||||
if(session_list.first != session_list.last) {
|
||||
uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Disconnect ...",
|
||||
0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 2, "");
|
||||
uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Disconnect all",
|
||||
0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 3, "");
|
||||
}
|
||||
else {
|
||||
uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Disconnect",
|
||||
0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 3, "");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
uiBlockSetDirection(block, UI_RIGHT);
|
||||
uiTextBoundsBlock(block, 60);
|
||||
|
||||
return block;
|
||||
}
|
||||
#endif
|
||||
|
||||
static void do_info_filemenu(void *arg, int event)
|
||||
{
|
||||
ScrArea *sa;
|
||||
@ -871,6 +955,9 @@ static uiBlock *info_filemenu(void *arg_unused)
|
||||
|
||||
uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "New|Ctrl X", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 0, "");
|
||||
uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Open...|F1", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 1, "");
|
||||
#ifdef WITH_VERSE
|
||||
uiDefIconTextBlockBut(block, verse_filemenu, NULL, ICON_RIGHTARROW_THIN, "Verse", 0, yco-=20, menuwidth, 19, "");
|
||||
#endif
|
||||
uiDefIconTextBlockBut(block, info_openrecentmenu, NULL, ICON_RIGHTARROW_THIN, "Open Recent",0, yco-=20, 120, 19, "");
|
||||
uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Recover Last Session", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 15, "");
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
/**
|
||||
/*
|
||||
* header_view3d.c oct-2003
|
||||
*
|
||||
* Functions to draw the "3D Viewport" window header
|
||||
@ -69,6 +69,10 @@
|
||||
#include "BKE_main.h"
|
||||
#include "BKE_mesh.h"
|
||||
|
||||
#ifdef WITH_VERSE
|
||||
#include "BKE_verse.h"
|
||||
#endif
|
||||
|
||||
#include "BLI_arithb.h"
|
||||
#include "BLI_blenlib.h"
|
||||
|
||||
@ -106,6 +110,10 @@
|
||||
#include "BIF_toolbox.h"
|
||||
#include "BIF_transform.h"
|
||||
|
||||
#ifdef WITH_VERSE
|
||||
#include "BIF_verse.h"
|
||||
#endif
|
||||
|
||||
#include "BPY_extern.h"
|
||||
#include "BPY_menus.h"
|
||||
|
||||
@ -2074,11 +2082,18 @@ static uiBlock *view3d_edit_object_scriptsmenu(void *arg_unused)
|
||||
return block;
|
||||
}
|
||||
|
||||
#ifdef WITH_VERSE
|
||||
extern ListBase session_list;
|
||||
#endif
|
||||
|
||||
static void do_view3d_edit_objectmenu(void *arg, int event)
|
||||
{
|
||||
/* needed to check for valid selected objects */
|
||||
Base *base=NULL;
|
||||
Object *ob=NULL;
|
||||
#ifdef WITH_VERSE
|
||||
struct VerseSession *session=NULL;
|
||||
#endif
|
||||
|
||||
base= BASACT;
|
||||
if (base) ob= base->object;
|
||||
@ -2118,6 +2133,13 @@ static void do_view3d_edit_objectmenu(void *arg, int event)
|
||||
case 15: /* Object Panel */
|
||||
add_blockhandler(curarea, VIEW3D_HANDLER_OBJECT, UI_PNL_UNSTOW);
|
||||
break;
|
||||
#ifdef WITH_VERSE
|
||||
case 16: /* Share Object at Verse server */
|
||||
if(session_list.first != session_list.last) session = session_menu();
|
||||
else session = session_list.first;
|
||||
if(session) b_verse_push_object(session, ob);
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
allqueue(REDRAWVIEW3D, 0);
|
||||
}
|
||||
@ -2130,6 +2152,19 @@ static uiBlock *view3d_edit_objectmenu(void *arg_unused)
|
||||
block= uiNewBlock(&curarea->uiblocks, "view3d_edit_objectmenu", UI_EMBOSSP, UI_HELV, curarea->headwin);
|
||||
uiBlockSetButmFunc(block, do_view3d_edit_objectmenu, NULL);
|
||||
|
||||
#ifdef WITH_VERSE
|
||||
if(session_list.first != NULL) {
|
||||
Base *base = BASACT;
|
||||
Object *ob = NULL;
|
||||
if (base) ob= base->object;
|
||||
|
||||
if((ob->type == OB_MESH) && (!ob->vnode)) {
|
||||
uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Share at Verse Server", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 16, "");
|
||||
uiDefBut(block, SEPR, 0, "", 0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
uiDefIconTextBut(block, BUTM, 1, ICON_MENU_PANEL, "Transform Properties|N", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 15, "");
|
||||
uiDefIconTextBlockBut(block, view3d_transformmenu, NULL, ICON_RIGHTARROW_THIN, "Transform", 0, yco-=20, 120, 19, "");
|
||||
uiDefIconTextBlockBut(block, view3d_object_mirrormenu, NULL, ICON_RIGHTARROW_THIN, "Mirror", 0, yco-=20, menuwidth, 19, "");
|
||||
@ -2610,6 +2645,10 @@ static uiBlock *view3d_edit_mesh_scriptsmenu(void *arg_unused)
|
||||
|
||||
static void do_view3d_edit_meshmenu(void *arg, int event)
|
||||
{
|
||||
#ifdef WITH_VERSE
|
||||
struct VerseSession *session;
|
||||
#endif
|
||||
|
||||
switch(event) {
|
||||
|
||||
case 0: /* Undo Editing */
|
||||
@ -2652,6 +2691,13 @@ static void do_view3d_edit_meshmenu(void *arg, int event)
|
||||
if(G.scene->proportional) G.scene->proportional= 0;
|
||||
else G.scene->proportional= 1;
|
||||
break;
|
||||
#ifdef WITH_VERSE
|
||||
case 13:
|
||||
if(session_list.first != session_list.last) session = session_menu();
|
||||
else session = session_list.first;
|
||||
if(session) b_verse_push_object(session, G.obedit);
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
allqueue(REDRAWVIEW3D, 0);
|
||||
}
|
||||
@ -2664,7 +2710,15 @@ static uiBlock *view3d_edit_meshmenu(void *arg_unused)
|
||||
|
||||
block= uiNewBlock(&curarea->uiblocks, "view3d_edit_meshmenu", UI_EMBOSSP, UI_HELV, curarea->headwin);
|
||||
uiBlockSetButmFunc(block, do_view3d_edit_meshmenu, NULL);
|
||||
|
||||
|
||||
#ifdef WITH_VERSE
|
||||
if((session_list.first != NULL) && (!G.obedit->vnode)) {
|
||||
uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Share at Verse Server",
|
||||
0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 13, "");
|
||||
uiDefBut(block, SEPR, 0, "", 0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
|
||||
}
|
||||
#endif
|
||||
|
||||
uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Undo Editing|U", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 0, "");
|
||||
uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Redo Editing|Shift U", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 1, "");
|
||||
uiDefIconTextBlockBut(block, editmode_undohistorymenu, NULL, ICON_RIGHTARROW_THIN, "Undo History", 0, yco-=20, 120, 19, "");
|
||||
|
@ -138,7 +138,28 @@ int join_mesh(void)
|
||||
|
||||
ob= OBACT;
|
||||
if(!ob || ob->type!=OB_MESH) return 0;
|
||||
|
||||
|
||||
#ifdef WITH_VERSE
|
||||
/* it isn't allowed to join shared object at verse server
|
||||
* this function will be implemented as soon as possible */
|
||||
base= FIRSTBASE;
|
||||
while(base) {
|
||||
if TESTBASELIB(base) {
|
||||
if(base->object->type==OB_MESH) {
|
||||
if(base->object->vnode) {
|
||||
haskey= 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
base= base->next;
|
||||
}
|
||||
if(haskey) {
|
||||
error("Can't join meshes shared at verse server");
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* count */
|
||||
base= FIRSTBASE;
|
||||
while(base) {
|
||||
|
@ -70,6 +70,10 @@
|
||||
#include "BKE_scene.h"
|
||||
#include "BKE_utildefines.h"
|
||||
|
||||
#ifdef WITH_VERSE
|
||||
#include "BKE_verse.h"
|
||||
#endif
|
||||
|
||||
#include "BIF_butspace.h"
|
||||
#include "BIF_drawscene.h"
|
||||
#include "BIF_drawtext.h"
|
||||
@ -94,6 +98,10 @@
|
||||
#include "BIF_space.h"
|
||||
#include "BIF_toolbox.h"
|
||||
|
||||
#ifdef WITH_VERSE
|
||||
#include "BIF_verse.h"
|
||||
#endif
|
||||
|
||||
#ifdef INTERNATIONAL
|
||||
#include "FTF_Api.h"
|
||||
#endif
|
||||
@ -114,6 +122,10 @@
|
||||
|
||||
#define TREESTORE(a) ((a)?soops->treestore->data+(a)->store_index:NULL)
|
||||
|
||||
#ifdef WITH_VERSE
|
||||
extern ListBase session_list;
|
||||
#endif
|
||||
|
||||
/* ******************** PERSISTANT DATA ***************** */
|
||||
|
||||
static void outliner_storage_cleanup(SpaceOops *soops)
|
||||
@ -702,6 +714,34 @@ static TreeElement *outliner_add_element(SpaceOops *soops, ListBase *lb, void *i
|
||||
break;
|
||||
}
|
||||
}
|
||||
#ifdef WITH_VERSE
|
||||
else if(type==ID_VS) {
|
||||
struct VerseSession *session = (VerseSession*)idv;
|
||||
te->name = session->address;
|
||||
te->directdata = (void*)session;
|
||||
te->idcode = ID_VS;
|
||||
}
|
||||
else if(type==ID_VN) {
|
||||
struct VNode *vnode = (VNode*)idv;
|
||||
te->name = vnode->name;
|
||||
te->idcode = ID_VN;
|
||||
if(vnode->type==V_NT_OBJECT) {
|
||||
struct TreeElement *ten;
|
||||
struct VNode *child_node;
|
||||
struct VLink *vlink;
|
||||
|
||||
vlink = ((VObjectData*)vnode->data)->links.lb.first;
|
||||
while(vlink) {
|
||||
child_node = vlink->target;
|
||||
if(child_node && child_node->type==V_NT_GEOMETRY) {
|
||||
ten = outliner_add_element(soops, &te->subtree, child_node, te, ID_VN, 0);
|
||||
ten->directdata = child_node;
|
||||
}
|
||||
vlink = vlink->next;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
return te;
|
||||
}
|
||||
|
||||
@ -754,6 +794,9 @@ static void outliner_build_tree(SpaceOops *soops)
|
||||
TreeElement *te, *ten;
|
||||
TreeStoreElem *tselem;
|
||||
int show_opened= soops->treestore==NULL; /* on first view, we open scenes */
|
||||
#ifdef WITH_VERSE
|
||||
struct VerseSession *session;
|
||||
#endif
|
||||
|
||||
outliner_free_tree(&soops->tree);
|
||||
outliner_storage_cleanup(soops);
|
||||
@ -840,7 +883,28 @@ static void outliner_build_tree(SpaceOops *soops)
|
||||
ten= outliner_add_element(soops, &soops->tree, OBACT, NULL, 0, 0);
|
||||
if(ten) ten->directdata= BASACT;
|
||||
}
|
||||
|
||||
|
||||
#ifdef WITH_VERSE
|
||||
/* add all session to the "root" of hierarchy */
|
||||
for(session=session_list.first; session; session = session->next) {
|
||||
struct VNode *vnode;
|
||||
if(session->flag & VERSE_CONNECTED) {
|
||||
te= outliner_add_element(soops, &soops->tree, session, NULL, ID_VS, 0);
|
||||
/* add all object nodes as childreen of session */
|
||||
for(vnode=session->nodes.lb.first; vnode; vnode=vnode->next) {
|
||||
if(vnode->type==V_NT_OBJECT) {
|
||||
ten= outliner_add_element(soops, &te->subtree, vnode, te, ID_VN, 0);
|
||||
ten->directdata= vnode;
|
||||
}
|
||||
else if(vnode->type==V_NT_BITMAP) {
|
||||
ten= outliner_add_element(soops, &te->subtree, vnode, te, ID_VN, 0);
|
||||
ten->directdata= vnode;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
outliner_sort(soops, &soops->tree);
|
||||
}
|
||||
|
||||
@ -1509,6 +1573,59 @@ static int do_outliner_mouse_event(SpaceOops *soops, TreeElement *te, short even
|
||||
}
|
||||
}
|
||||
else {
|
||||
#ifdef WITH_VERSE
|
||||
if(event==RIGHTMOUSE) {
|
||||
short event;
|
||||
if(te->idcode==ID_VS) {
|
||||
struct VerseSession *session = (VerseSession*)te->directdata;
|
||||
struct VNode *vnode;
|
||||
if(!(session->flag & VERSE_AUTOSUBSCRIBE)) {
|
||||
event = pupmenu("VerseSession %t| End Session %x1| Subscribe to All Nodes %x2| Start Autosubscribe %x3");
|
||||
}
|
||||
else {
|
||||
event = pupmenu("VerseSession %t| End Session %x1| Subscribe to All Nodes %x2| Stop Autosubscribe %x4");
|
||||
}
|
||||
switch(event) {
|
||||
case 1:
|
||||
end_verse_session(session, 1);
|
||||
break;
|
||||
case 2:
|
||||
vnode = session->nodes.lb.first;
|
||||
while(vnode) {
|
||||
b_verse_pop_node(vnode);
|
||||
vnode = vnode->next;
|
||||
}
|
||||
break;
|
||||
case 3:
|
||||
vnode = session->nodes.lb.first;
|
||||
while(vnode) {
|
||||
b_verse_pop_node(vnode);
|
||||
vnode = vnode->next;
|
||||
}
|
||||
session->flag |= VERSE_AUTOSUBSCRIBE;
|
||||
break;
|
||||
case 4:
|
||||
session->flag &= ~VERSE_AUTOSUBSCRIBE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if(te->idcode==ID_VN) {
|
||||
struct VNode *vnode = (VNode*)te->directdata;
|
||||
event = pupmenu("VerseNode %t| Subscribe %x1| Unsubscribe %x2");
|
||||
switch(event) {
|
||||
case 1:
|
||||
b_verse_pop_node(vnode);
|
||||
break;
|
||||
case 2:
|
||||
/* Global */
|
||||
b_verse_unsubscribe(vnode);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
#endif
|
||||
|
||||
/* always makes active object */
|
||||
tree_element_active_object(soops, te);
|
||||
|
||||
@ -1533,6 +1650,9 @@ static int do_outliner_mouse_event(SpaceOops *soops, TreeElement *te, short even
|
||||
|
||||
}
|
||||
else tree_element_type_active(soops, te, tselem, 1);
|
||||
#ifdef WITH_VERSE
|
||||
}
|
||||
#endif
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
@ -1722,7 +1842,13 @@ static void set_operation_types(SpaceOops *soops, ListBase *lb)
|
||||
tselem= TREESTORE(te);
|
||||
if(tselem->flag & TSE_SELECTED) {
|
||||
if(tselem->type) {
|
||||
#ifdef WITH_VERSE
|
||||
if(te->idcode==ID_VS) datalevel= TSE_VERSE_SESSION;
|
||||
else if(te->idcode==ID_VN) datalevel= TSE_VERSE_OBJ_NODE;
|
||||
else if(datalevel==0) datalevel= tselem->type;
|
||||
#else
|
||||
if(datalevel==0) datalevel= tselem->type;
|
||||
#endif
|
||||
else if(datalevel!=tselem->type) datalevel= -1;
|
||||
}
|
||||
else {
|
||||
@ -1973,6 +2099,17 @@ static void ebone_cb(int event, TreeElement *te, TreeStoreElem *tselem)
|
||||
ebone->flag &= ~BONE_HIDDEN_A;
|
||||
}
|
||||
|
||||
#ifdef WITH_VERSE
|
||||
static void vsession_cb(int event, TreeElement *te, TreeStoreElem *tselem)
|
||||
{
|
||||
/* struct VerseSession *vsession =(VerseSession*)te->directdata;*/
|
||||
|
||||
if(event==1) {
|
||||
printf("\tending verse session\n");
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
static void outliner_do_data_operation(SpaceOops *soops, int type, int event, ListBase *lb,
|
||||
void (*operation_cb)(int, TreeElement *, TreeStoreElem *))
|
||||
{
|
||||
@ -2095,6 +2232,14 @@ void outliner_operation_menu(ScrArea *sa)
|
||||
BIF_undo_push("EditBone operation");
|
||||
}
|
||||
}
|
||||
#ifdef WITH_VERSE
|
||||
else if(datalevel==TSE_VERSE_SESSION) {
|
||||
short event= pupmenu("VerseSession %t| End %x1");
|
||||
if(event>0) {
|
||||
outliner_do_data_operation(soops, datalevel, event, &soops->tree, vsession_cb);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
allqueue(REDRAWOOPS, 0);
|
||||
allqueue(REDRAWBUTSALL, 0);
|
||||
@ -2163,6 +2308,12 @@ static void tselem_draw_icon(float x, float y, TreeStoreElem *tselem, TreeElemen
|
||||
BIF_icon_draw(x, y, ICON_ARMATURE_DEHLT); break;
|
||||
case TSE_POSE_CHANNEL:
|
||||
BIF_icon_draw(x, y, ICON_WPAINT_DEHLT); break;
|
||||
#ifdef WITH_VERSE
|
||||
case ID_VS:
|
||||
BIF_icon_draw(x, y, ICON_VERSE); break;
|
||||
case ID_VN:
|
||||
BIF_icon_draw(x, y, ICON_VERSE); break;
|
||||
#endif
|
||||
default:
|
||||
BIF_icon_draw(x, y, ICON_DOT); break;
|
||||
}
|
||||
@ -2354,9 +2505,14 @@ static void outliner_draw_tree_element(SpaceOops *soops, TreeElement *te, int st
|
||||
else BIF_ThemeColor(TH_TEXT);
|
||||
glRasterPos2i(startx+offsx, *starty+5);
|
||||
BIF_RasterPos(startx+offsx, *starty+5);
|
||||
BIF_DrawString(G.font, te->name, 0);
|
||||
|
||||
offsx+= OL_X + BIF_GetStringWidth(G.font, te->name, 0);
|
||||
#ifdef WITH_VERSE
|
||||
if(te->name) {
|
||||
#endif
|
||||
BIF_DrawString(G.font, te->name, 0);
|
||||
offsx+= OL_X + BIF_GetStringWidth(G.font, te->name, 0);
|
||||
#ifdef WITH_VERSE
|
||||
}
|
||||
#endif
|
||||
|
||||
/* closed item, we draw the icons, not when it's a scene though */
|
||||
if(tselem->flag & TSE_CLOSED) {
|
||||
|
@ -4327,7 +4327,12 @@ static void winqreadoopsspace(ScrArea *sa, void *spacedata, BWinEvent *evt)
|
||||
view2dmove(event); /* in drawipo.c */
|
||||
break;
|
||||
case RIGHTMOUSE:
|
||||
#ifdef WITH_VERSE
|
||||
/* evil hack due to verse */
|
||||
outliner_mouse_event(sa, event);
|
||||
#else
|
||||
outliner_operation_menu(sa);
|
||||
#endif
|
||||
break;
|
||||
|
||||
case AKEY:
|
||||
|
@ -1428,6 +1428,15 @@ static void VertsToTransData(TransData *td, EditVert *eve)
|
||||
td->tdi = NULL;
|
||||
td->val = NULL;
|
||||
td->tdmir= NULL;
|
||||
|
||||
#ifdef WITH_VERSE
|
||||
if(eve->vvert) {
|
||||
td->verse = (void*)eve->vvert;
|
||||
td->flag |= TD_VERSE_VERT;
|
||||
}
|
||||
else
|
||||
td->flag &= ~TD_VERSE_VERT;
|
||||
#endif
|
||||
}
|
||||
|
||||
/* *********************** CrazySpace correction. Now without doing subsurf optimal ****************** */
|
||||
@ -2051,6 +2060,14 @@ static void ObjectToTransData(TransData *td, Object *ob)
|
||||
Mat3One(td->smtx);
|
||||
Mat3One(td->mtx);
|
||||
}
|
||||
#ifdef WITH_VERSE
|
||||
if(ob->vnode) {
|
||||
td->verse = (void*)ob;
|
||||
td->flag |= TD_VERSE_OBJECT;
|
||||
}
|
||||
else
|
||||
td->flag &= ~TD_VERSE_OBJECT;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
@ -59,6 +59,10 @@
|
||||
#include "BIF_editsima.h"
|
||||
#include "BIF_meshtools.h"
|
||||
|
||||
#ifdef WITH_VERSE
|
||||
#include "BIF_verse.h"
|
||||
#endif
|
||||
|
||||
#include "BKE_action.h"
|
||||
#include "BKE_anim.h"
|
||||
#include "BKE_armature.h"
|
||||
@ -74,6 +78,10 @@
|
||||
#include "BKE_object.h"
|
||||
#include "BKE_utildefines.h"
|
||||
|
||||
#ifdef WITH_VERSE
|
||||
#include "BKE_verse.h"
|
||||
#endif
|
||||
|
||||
#include "BSE_view.h"
|
||||
#include "BDR_unwrapper.h"
|
||||
|
||||
@ -202,6 +210,9 @@ static void editmesh_apply_to_mirror(TransInfo *t)
|
||||
void recalcData(TransInfo *t)
|
||||
{
|
||||
Base *base;
|
||||
#ifdef WITH_VERSE
|
||||
struct TransData *td;
|
||||
#endif
|
||||
|
||||
if (G.obedit) {
|
||||
if (G.obedit->type == OB_MESH) {
|
||||
@ -334,6 +345,17 @@ void recalcData(TransInfo *t)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef WITH_VERSE
|
||||
for (td = t->data; td < t->data + t->total; td++) {
|
||||
if(td->flag & TD_VERSE_VERT) {
|
||||
if(td->verse)
|
||||
send_versevert_pos((VerseVert*)td->verse);
|
||||
}
|
||||
else if(td->flag & TD_VERSE_OBJECT)
|
||||
if(td->verse) b_verse_send_transformation((Object*)td->verse);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* update shaded drawmode while transform */
|
||||
if(t->spacetype==SPACE_VIEW3D && G.vd->drawtype == OB_SHADED)
|
||||
@ -463,6 +485,25 @@ void initTrans (TransInfo *t)
|
||||
void postTrans (TransInfo *t)
|
||||
{
|
||||
G.moving = 0; // Set moving flag off (display as usual)
|
||||
#ifdef WITH_VERSE
|
||||
struct TransData *td;
|
||||
|
||||
for (td = t->data; td < t->data + t->total; td++) {
|
||||
if(td->flag & TD_VERSE_VERT) {
|
||||
if(td->verse) send_versevert_pos((VerseVert*)td->verse);
|
||||
}
|
||||
else if(td->flag & TD_VERSE_OBJECT) {
|
||||
if(td->verse) {
|
||||
struct VNode *vnode;
|
||||
vnode = (VNode*)((Object*)td->verse)->vnode;
|
||||
((VObjectData*)vnode->data)->flag |= POS_SEND_READY;
|
||||
((VObjectData*)vnode->data)->flag |= ROT_SEND_READY;
|
||||
((VObjectData*)vnode->data)->flag |= SCALE_SEND_READY;
|
||||
b_verse_send_transformation((Object*)td->verse);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
stopConstraint(t);
|
||||
|
||||
@ -619,6 +660,25 @@ void restoreTransObjects(TransInfo *t)
|
||||
|
||||
for (td = t->data; td < t->data + t->total; td++) {
|
||||
restoreElement(td);
|
||||
#ifdef WITH_VERSE
|
||||
/* position of vertexes and object transformation matrix is sent
|
||||
* extra, becuase blender uses synchronous sending of vertexes
|
||||
* position as well object trans. matrix and it isn't possible to
|
||||
* send it in recalcData sometimes */
|
||||
if(td->flag & TD_VERSE_VERT) {
|
||||
if(td->verse) {
|
||||
((VerseVert*)td->verse)->flag |= VERT_POS_OBSOLETE;
|
||||
}
|
||||
}
|
||||
else if(td->flag & TD_VERSE_OBJECT)
|
||||
if(td->verse) {
|
||||
struct VNode *vnode;
|
||||
vnode = (VNode*)((Object*)td->verse)->vnode;
|
||||
((VObjectData*)vnode->data)->flag |= POS_SEND_READY;
|
||||
((VObjectData*)vnode->data)->flag |= ROT_SEND_READY;
|
||||
((VObjectData*)vnode->data)->flag |= SCALE_SEND_READY;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
recalcData(t);
|
||||
}
|
||||
|
@ -82,6 +82,10 @@
|
||||
#include "BKE_packedFile.h"
|
||||
#include "BKE_utildefines.h"
|
||||
|
||||
#ifdef WITH_VERSE
|
||||
#include "BKE_verse.h"
|
||||
#endif
|
||||
|
||||
#include "BLI_vfontdata.h"
|
||||
|
||||
#include "BIF_fsmenu.h"
|
||||
@ -104,6 +108,11 @@
|
||||
#include "BIF_toolbox.h"
|
||||
#include "BIF_cursors.h"
|
||||
|
||||
#ifdef WITH_VERSE
|
||||
#include "BIF_verse.h"
|
||||
#endif
|
||||
|
||||
|
||||
#include "BSE_drawview.h"
|
||||
#include "BSE_edit.h"
|
||||
#include "BSE_editipo.h"
|
||||
@ -344,13 +353,38 @@ static void init_userdef_file(void)
|
||||
|
||||
}
|
||||
|
||||
#ifdef WITH_VERSE
|
||||
extern ListBase session_list;
|
||||
#endif
|
||||
|
||||
void BIF_read_file(char *name)
|
||||
{
|
||||
extern short winqueue_break; /* editscreen.c */
|
||||
int retval;
|
||||
|
||||
//NOT here!
|
||||
//sound_end_all_sounds();
|
||||
#ifdef WITH_VERSE
|
||||
struct VerseSession *session;
|
||||
struct VNode *vnode;
|
||||
|
||||
session = session_list.first;
|
||||
while(session) {
|
||||
vnode = session->nodes.lb.first;
|
||||
while(vnode) {
|
||||
switch(vnode->type) {
|
||||
case V_NT_OBJECT:
|
||||
unsubscribe_from_obj_node(vnode);
|
||||
break;
|
||||
case V_NT_GEOMETRY:
|
||||
unsubscribe_from_geom_node(vnode);
|
||||
break;
|
||||
case V_NT_BITMAP:
|
||||
unsubscribe_from_bitmap_node(vnode);
|
||||
break;
|
||||
}
|
||||
vnode = vnode->next;
|
||||
}
|
||||
session = session->next;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* first try to read exotic file formats... */
|
||||
/* it throws error box when file doesnt exist and returns -1 */
|
||||
@ -568,7 +602,6 @@ static void readBlog(void)
|
||||
BLI_free_file_lines(lines);
|
||||
}
|
||||
|
||||
|
||||
static void writeBlog(void)
|
||||
{
|
||||
struct RecentFile *recent, *next_recent;
|
||||
@ -859,6 +892,10 @@ void exit_usiblender(void)
|
||||
sound_exit_audio();
|
||||
if(G.listener) MEM_freeN(G.listener);
|
||||
|
||||
#ifdef WITH_VERSE
|
||||
end_all_verse_sessions();
|
||||
#endif
|
||||
|
||||
libtiff_exit();
|
||||
|
||||
#ifdef WITH_QUICKTIME
|
||||
|
270
source/blender/src/verse_common.c
Normal file
270
source/blender/src/verse_common.c
Normal file
@ -0,0 +1,270 @@
|
||||
/**
|
||||
* $Id$
|
||||
*
|
||||
* ***** BEGIN GPL/BL DUAL 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. The Blender
|
||||
* Foundation also sells licenses for use in proprietary software under
|
||||
* the Blender License. See http://www.blender.org/BL/ for information
|
||||
* about this.
|
||||
*
|
||||
* 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/BL DUAL LICENSE BLOCK *****
|
||||
*/
|
||||
|
||||
#ifdef WITH_VERSE
|
||||
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "MEM_guardedalloc.h"
|
||||
|
||||
#include "mydevice.h"
|
||||
|
||||
#include "DNA_object_types.h"
|
||||
#include "DNA_mesh_types.h"
|
||||
|
||||
#include "BKE_global.h"
|
||||
#include "BKE_blender.h"
|
||||
|
||||
#include "BIF_verse.h"
|
||||
#include "BIF_space.h"
|
||||
#include "BIF_interface.h"
|
||||
|
||||
extern ListBase session_list;
|
||||
|
||||
/*
|
||||
* this function creates popup menu with all active VerseSessions
|
||||
* it return pointer at selected VerseSession, if no VerseSession
|
||||
* is selected, then NULL is returned
|
||||
*/
|
||||
VerseSession *session_menu(void)
|
||||
{
|
||||
struct VerseSession *session;
|
||||
char session_number[10];
|
||||
short i=1, num=1;
|
||||
char session_address_list[1024]; /* pupmenu business */
|
||||
|
||||
session_number[0] = '\0';
|
||||
session_address_list[0] = '\0';
|
||||
|
||||
strcat(session_address_list, "Session list %t");
|
||||
|
||||
session = session_list.first;
|
||||
|
||||
while(session){
|
||||
strcat(session_address_list, "| ");
|
||||
strcat(session_address_list, session->address);
|
||||
strcat(session_address_list, " %x");
|
||||
sprintf(session_number, "%d", num);
|
||||
strcat(session_address_list, session_number);
|
||||
num++;
|
||||
session = session->next;
|
||||
}
|
||||
|
||||
printf("session list: %s\n", session_address_list);
|
||||
num = pupmenu(session_address_list);
|
||||
|
||||
if(num==-1) return NULL;
|
||||
|
||||
session = session_list.first;
|
||||
|
||||
while(session) {
|
||||
if(i==num) return session;
|
||||
i++;
|
||||
session = session->next;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* returns name of verse client (it is used as avatar's name)
|
||||
*/
|
||||
char *verse_client_name(void)
|
||||
{
|
||||
char *client_name;
|
||||
char blender_version[5];
|
||||
short name_lenght = 14;
|
||||
|
||||
#ifndef WIN32
|
||||
char *hostname;
|
||||
hostname = getenv("HOSTNAME");
|
||||
if(hostname) name_lenght += strlen(hostname);
|
||||
#endif
|
||||
|
||||
client_name = (char*)MEM_mallocN(sizeof(char)*name_lenght, "verse client name");
|
||||
client_name[0] = '\0';
|
||||
|
||||
strcat(client_name, "blender_");
|
||||
blender_version[0] = '\0';
|
||||
sprintf(blender_version, "%d", BLENDER_VERSION);
|
||||
strcat(client_name, blender_version);
|
||||
|
||||
#ifndef WIN32
|
||||
/* add at the end of the client name hostname */
|
||||
if(hostname) {
|
||||
strcat(client_name, ":");
|
||||
strcat(client_name, hostname);
|
||||
}
|
||||
#endif
|
||||
|
||||
return client_name;
|
||||
}
|
||||
|
||||
/*===========================================================
|
||||
*
|
||||
* functions executed after calling callback functions
|
||||
*
|
||||
============================================================*/
|
||||
|
||||
/*
|
||||
* this function is called, when some tag was changed or new tag was created
|
||||
*/
|
||||
void post_tag_change(VTag *vtag)
|
||||
{
|
||||
printf("\tnew tag %s was created or changed\n", vtag->name);
|
||||
}
|
||||
|
||||
/*
|
||||
* this function is called, when verse taggroup was created
|
||||
*/
|
||||
void post_taggroup_create(VTagGroup *vtaggroup)
|
||||
{
|
||||
printf("\tnew taggroup %s was created\n", vtaggroup->name);
|
||||
}
|
||||
|
||||
/*
|
||||
* this function is called after creating of new VerseNode
|
||||
*/
|
||||
void post_node_create(VNode *vnode)
|
||||
{
|
||||
struct VerseSession *session = vnode->session;
|
||||
|
||||
if((session->flag & VERSE_AUTOSUBSCRIBE) && (vnode->owner_id != VN_OWNER_MINE)) {
|
||||
if(vnode->type == V_NT_OBJECT) {
|
||||
create_object_from_verse_node(vnode);
|
||||
}
|
||||
else if(vnode->type == V_NT_GEOMETRY) {
|
||||
create_mesh_from_geom_node(vnode);;
|
||||
}
|
||||
}
|
||||
|
||||
allqueue(REDRAWOOPS, 0);
|
||||
}
|
||||
|
||||
/*
|
||||
* this function is called after destroying of VerseNode
|
||||
*/
|
||||
void post_node_destroy(VNode *vnode)
|
||||
{
|
||||
allqueue(REDRAWOOPS, 0);
|
||||
|
||||
/* TODO: destroy bindings between vnode and blender data structures */
|
||||
}
|
||||
|
||||
/*
|
||||
* this function is calles after renaming of VerseNode by verse_server
|
||||
*/
|
||||
void post_node_name_set(VNode *vnode)
|
||||
{
|
||||
/* if VerseNode has coresponding blender data structure, then
|
||||
* change ID name of data structure */
|
||||
if(vnode->type==V_NT_OBJECT) {
|
||||
struct Object *ob;
|
||||
ob = (Object*)((VObjectData*)vnode->data)->object;
|
||||
if(ob) {
|
||||
char *str;
|
||||
str = (char*)malloc(sizeof(char)*(strlen(vnode->name)+3));
|
||||
str[0] = '\0';
|
||||
strcat(str, "OB");
|
||||
strcat(str, vnode->name);
|
||||
strncpy(ob->id.name, str, 23);
|
||||
printf("\tob->id.name: %s\n", ob->id.name);
|
||||
free(str);
|
||||
}
|
||||
}
|
||||
else if(vnode->type==V_NT_GEOMETRY) {
|
||||
struct Mesh *me;
|
||||
|
||||
me = (Mesh*)((VGeomData*)vnode->data)->mesh;
|
||||
if(me) {
|
||||
char *str;
|
||||
str = (char*)malloc(sizeof(char)*(strlen(vnode->name)+3));
|
||||
str[0] = '\0';
|
||||
strcat(str, "ME");
|
||||
strcat(str, vnode->name);
|
||||
strncpy(me->id.name, str, 23);
|
||||
printf("\tme->id.name: %s\n", me->id.name);
|
||||
free(str);
|
||||
}
|
||||
}
|
||||
|
||||
allqueue(REDRAWALL, 0);
|
||||
}
|
||||
|
||||
/*
|
||||
* this function is called after acception connection with verse server
|
||||
*/
|
||||
void post_connect_accept(VerseSession *session)
|
||||
{
|
||||
G.f |= G_VERSE_CONNECTED;
|
||||
|
||||
session->counter = 0;
|
||||
|
||||
allqueue(REDRAWOOPS, 0);
|
||||
}
|
||||
|
||||
/*
|
||||
* this function is called, when connestion with verse server is ended/terminated/etc.
|
||||
*/
|
||||
void post_connect_terminated(VerseSession *session)
|
||||
{
|
||||
/* if it is last session, then no other will exist ... set Global flag */
|
||||
if((session->prev==NULL) && (session->next==NULL))
|
||||
G.f &= ~G_VERSE_CONNECTED;
|
||||
|
||||
allqueue(REDRAWOOPS, 0);
|
||||
}
|
||||
|
||||
/*
|
||||
* if connection wasn't accepted, then free VerseSession
|
||||
* and print warning message with popupmenu
|
||||
*/
|
||||
void post_connect_update(VerseSession *session)
|
||||
{
|
||||
if(session->flag & VERSE_CONNECTING) {
|
||||
session->counter++;
|
||||
if(session->counter > MAX_UNCONNECTED_EVENTS) {
|
||||
char *str;
|
||||
/* popup menu*/
|
||||
str = malloc(sizeof(char)*(strlen(session->address)+35));
|
||||
str[0]='\0';
|
||||
strcat(str, "Error%t|No response from server: ");
|
||||
strcat(str, session->address);
|
||||
pupmenu(str);
|
||||
free(str);
|
||||
|
||||
session->flag = 0;
|
||||
session->counter = 0;
|
||||
session->post_connect_terminated(session);
|
||||
free_verse_session(session);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
345
source/blender/src/verse_image.c
Normal file
345
source/blender/src/verse_image.c
Normal file
@ -0,0 +1,345 @@
|
||||
/**
|
||||
* $Id$
|
||||
*
|
||||
* ***** BEGIN GPL/BL DUAL 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. The Blender
|
||||
* Foundation also sells licenses for use in proprietary software under
|
||||
* the Blender License. See http://www.blender.org/BL/ for information
|
||||
* about this.
|
||||
*
|
||||
* 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/BL DUAL LICENSE BLOCK *****
|
||||
*/
|
||||
|
||||
#ifdef WITH_VERSE
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "mydevice.h"
|
||||
|
||||
#include "BKE_verse.h"
|
||||
|
||||
#include "MEM_guardedalloc.h"
|
||||
|
||||
#include "DNA_image_types.h"
|
||||
|
||||
#include "IMB_imbuf_types.h"
|
||||
#include "IMB_imbuf.h"
|
||||
|
||||
#include "BDR_drawmesh.h"
|
||||
|
||||
#include "BIF_verse.h"
|
||||
#include "BIF_space.h"
|
||||
|
||||
/*
|
||||
* unsubscribe from verse bitmap
|
||||
*/
|
||||
void unsubscribe_from_bitmap_node(VNode *vnode)
|
||||
{
|
||||
if(vnode->type != V_NT_BITMAP) return;
|
||||
|
||||
/* TODO */
|
||||
}
|
||||
|
||||
/*
|
||||
* upload image to verse server
|
||||
*/
|
||||
void push_image_to_verse_server(VerseSession *session, Image *image)
|
||||
{
|
||||
struct VNode *vnode;
|
||||
|
||||
if(!session) return;
|
||||
|
||||
if(!(session->flag & VERSE_CONNECTED)) return;
|
||||
|
||||
/* create "my" new object VerseNode */
|
||||
vnode= create_verse_node(session->vsession, -1 , V_NT_BITMAP, VN_OWNER_MINE);
|
||||
/* create object data */
|
||||
vnode->data = create_bitmap_data();
|
||||
|
||||
/* set up name of VerseNode */
|
||||
vnode->name = (char*)MEM_mallocN(sizeof(char*)*(strlen(image->id.name)-1), "object node name");
|
||||
vnode->name[0] = '\0';
|
||||
strcat(vnode->name, image->id.name+2);
|
||||
|
||||
/* set up dimension of image */
|
||||
if(image->ibuf) {
|
||||
((VBitmapData*)vnode->data)->width = image->ibuf->x;
|
||||
((VBitmapData*)vnode->data)->height = image->ibuf->y;
|
||||
}
|
||||
else {
|
||||
((VBitmapData*)vnode->data)->width = 0;
|
||||
((VBitmapData*)vnode->data)->height = 0;
|
||||
}
|
||||
((VBitmapData*)(vnode->data))->height = 1;
|
||||
|
||||
/* set up pointers between Object and VerseNode */
|
||||
((VBitmapData*)vnode->data)->image = (void*)image;
|
||||
image->vnode = (void*)vnode;
|
||||
|
||||
/* add node to sending queue */
|
||||
add_item_to_send_queue(&(session->queue), vnode, VERSE_NODE);
|
||||
}
|
||||
|
||||
/*
|
||||
* synchronize blender image channel (R,G,B,A) with verse bitmap layer
|
||||
*/
|
||||
void sync_blender_image_channel_with_verse_layer(VNode *vnode, VBitmapLayer *vblayer)
|
||||
{
|
||||
struct Image *image = (Image*)((VBitmapData*)(vnode->data))->image;
|
||||
struct ImBuf *ibuf;
|
||||
unsigned char *rect;
|
||||
int x, y, height, t_width, i, channel=0;
|
||||
|
||||
if(!image) return;
|
||||
|
||||
ibuf = image->ibuf;
|
||||
if(!ibuf) return;
|
||||
|
||||
rect = (unsigned char*)ibuf->rect;
|
||||
|
||||
/* select channel due to verse layer name */
|
||||
if(strcmp(vblayer->name,"col_r")==0)
|
||||
channel = 0;
|
||||
else if(strcmp(vblayer->name,"col_g")==0)
|
||||
channel = 1;
|
||||
else if(strcmp(vblayer->name, "col_b")==0)
|
||||
channel = 2;
|
||||
else if(strcmp(vblayer->name,"alpha")==0)
|
||||
channel = 3;
|
||||
|
||||
#ifdef VERSE_DEBUG_PRINT
|
||||
printf(" %s:%d\n", vblayer->name, channel);
|
||||
#endif
|
||||
|
||||
height = ((VBitmapData*)(vnode->data))->height;
|
||||
t_width = ((VBitmapData*)(vnode->data))->t_width;
|
||||
|
||||
i = (height-1)*t_width;
|
||||
|
||||
#ifdef VERSE_DEBUG_PRINT
|
||||
printf("\ti:%d\n", i);
|
||||
#endif
|
||||
|
||||
if(vblayer->type==VN_B_LAYER_UINT8) {
|
||||
unsigned char *vuint8 = (unsigned char*)vblayer->data;
|
||||
for(y=height-1; y>=0; y--, i=y*t_width)
|
||||
for(x=0; x<ibuf->x; x++, rect+=4, i++)
|
||||
rect[channel] = (char)vuint8[i];
|
||||
}
|
||||
|
||||
allqueue(REDRAWIMAGE, 0);
|
||||
allqueue(REDRAWVIEW3D, 0);
|
||||
}
|
||||
|
||||
/*
|
||||
* synchronize blender image with verse image
|
||||
*/
|
||||
void sync_blender_image_with_verse_bitmap_node(VNode *vnode)
|
||||
{
|
||||
struct VBitmapLayer *vblayer;
|
||||
|
||||
vblayer = ((VBitmapData*)(vnode->data))->layers.lb.first;
|
||||
|
||||
while(vblayer) {
|
||||
#ifdef VERSE_DEBUG_PRINT
|
||||
printf("\tsyncing layer:");
|
||||
#endif
|
||||
sync_blender_image_channel_with_verse_layer(vnode, vblayer);
|
||||
vblayer = vblayer->next;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* This function is called, when some other verse client change dimension of image.
|
||||
* It is neccesary to reallocate blender image too, when dimension of verse image
|
||||
* is different from blender image.
|
||||
*/
|
||||
void post_bitmap_dimension_set(VNode *vnode)
|
||||
{
|
||||
struct Image *image = (Image*)((VBitmapData*)(vnode->data))->image;
|
||||
struct ImBuf *ibuf;
|
||||
|
||||
if(!image) return;
|
||||
|
||||
ibuf = image->ibuf;
|
||||
if(!ibuf) return;
|
||||
|
||||
if(vnode->owner_id == VN_OWNER_MINE) {
|
||||
if( ((VBitmapData*)vnode->data)->layers.lb.first == NULL ) {
|
||||
/* send all verse bitmap layers (RGBA) to verse server */
|
||||
printf("\tsending all bitmap layers to verse server\n");
|
||||
verse_send_b_layer_create(vnode->id, -1, "col_r", VN_B_LAYER_UINT8);
|
||||
verse_send_b_layer_create(vnode->id, -1, "col_g", VN_B_LAYER_UINT8);
|
||||
verse_send_b_layer_create(vnode->id, -1, "col_b", VN_B_LAYER_UINT8);
|
||||
verse_send_b_layer_create(vnode->id, -1, "alpha", VN_B_LAYER_UINT8);
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if((ibuf->x!=((VBitmapData*)vnode->data)->width) || (ibuf->y!=((VBitmapData*)vnode->data)->height)) {
|
||||
struct VBitmapLayer *vblayer;
|
||||
struct ImBuf *new_ibuf;
|
||||
|
||||
/* allocate new ibuf */
|
||||
new_ibuf= IMB_allocImBuf(((VBitmapData*)vnode->data)->width,
|
||||
((VBitmapData*)vnode->data)->height, 24, IB_rect, 0);
|
||||
/* free old ibuf */
|
||||
IMB_freeImBuf(ibuf);
|
||||
/* set up pointer at new ibuf */
|
||||
image->ibuf = new_ibuf;
|
||||
|
||||
/* sync blender image with all verse layers */
|
||||
vblayer = ((VBitmapData*)(vnode->data))->layers.lb.first;
|
||||
while(vblayer) {
|
||||
sync_blender_image_channel_with_verse_layer(vnode, vblayer);
|
||||
vblayer = vblayer->next;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* when blender tries to upload image to verse server, then it is neccessary
|
||||
* to push coresponding channel data to verse server, when verse bitmap layer
|
||||
* was created
|
||||
*/
|
||||
void post_bitmap_layer_create(VBitmapLayer *vblayer)
|
||||
{
|
||||
struct VNode *vnode = vblayer->vnode;
|
||||
struct Image *image = (Image*)((VBitmapData*)(vnode->data))->image;
|
||||
struct ImBuf *ibuf;
|
||||
unsigned char *rect;
|
||||
short channel;
|
||||
/* VNBTile tile[VN_B_TILE_SIZE*VN_B_TILE_SIZE];
|
||||
unsigned int width, t_width, height, t_height, x, y, i, j; */
|
||||
|
||||
/* if this application doesn't try to upload this image to verse
|
||||
* server then do nothing */
|
||||
if(vnode->owner_id != VN_OWNER_MINE) return;
|
||||
|
||||
if(!image) return;
|
||||
|
||||
ibuf = image->ibuf;
|
||||
if(!ibuf) return;
|
||||
|
||||
rect = (unsigned char*)ibuf->rect;
|
||||
|
||||
if(strncmp(vblayer->name, "col_r", 5))
|
||||
channel = 0;
|
||||
else if(strncmp(vblayer->name, "col_g", 5))
|
||||
channel = 1;
|
||||
else if(strncmp(vblayer->name, "col_b", 5))
|
||||
channel = 2;
|
||||
else if(strncmp(vblayer->name, "alpha", 5))
|
||||
channel = 3;
|
||||
|
||||
/* TODO: send all data of channel to verse server */
|
||||
}
|
||||
|
||||
/*
|
||||
* dummy function now
|
||||
*/
|
||||
void post_bitmap_layer_destroy(VBitmapLayer *vblayer)
|
||||
{
|
||||
}
|
||||
|
||||
/*
|
||||
* this function is executed, when some image changed tile comes from verse server,
|
||||
* it is neccessary to do some crazy transformation here, because blender uses
|
||||
* different (very unstandard) image coordinate system (begining of coordinate
|
||||
* system is in bottom left corner) ... all other programs (including verse) has
|
||||
* begining of image coordinate system in left top corner
|
||||
*/
|
||||
void post_bitmap_tile_set(VBitmapLayer *vblayer, unsigned int xs, unsigned int ys)
|
||||
{
|
||||
struct VNode *vnode = vblayer->vnode;
|
||||
struct Image *image = (Image*)((VBitmapData*)(vnode->data))->image;
|
||||
struct ImBuf *ibuf;
|
||||
unsigned char *rect, *i_rect;
|
||||
unsigned int x, y, t_width, t_height, height, m_ys, m_y, d, i, j, channel=0;
|
||||
|
||||
if(!image) return;
|
||||
|
||||
ibuf = image->ibuf;
|
||||
if(!ibuf) return;
|
||||
|
||||
/* select channel due to verse layer name */
|
||||
if(strcmp(vblayer->name,"col_r")==0)
|
||||
channel = 0;
|
||||
else if(strcmp(vblayer->name,"col_g")==0)
|
||||
channel = 1;
|
||||
else if(strcmp(vblayer->name, "col_b")==0)
|
||||
channel = 2;
|
||||
else if(strcmp(vblayer->name,"alpha")==0)
|
||||
channel = 3;
|
||||
|
||||
i_rect = rect = (unsigned char*)ibuf->rect;
|
||||
|
||||
/* width of verse image including all tiles */
|
||||
t_width =((VBitmapData*)vnode->data)->t_width;
|
||||
/* height of verse image including all tiles */
|
||||
t_height =((VBitmapData*)vnode->data)->t_height;
|
||||
/* height of blender image */
|
||||
height = ((VBitmapData*)vnode->data)->height;
|
||||
|
||||
/* if the bitmap's dimensions are not integer multiples of the tile
|
||||
* side length, eight, then d will not be zero (height of "uncomplete
|
||||
* tile") */
|
||||
d = VN_B_TILE_SIZE - (t_height - height);
|
||||
/* mirrored coordination of received tile */
|
||||
m_ys = t_height - ys - VN_B_TILE_SIZE;
|
||||
|
||||
/* ys and m_ys are y axis, where we will do some changes */
|
||||
if(ys + VN_B_TILE_SIZE > height) {
|
||||
m_ys = 0;
|
||||
ys = ys + d - 1;
|
||||
}
|
||||
else {
|
||||
m_ys = m_ys - VN_B_TILE_SIZE + d;
|
||||
ys = ys + VN_B_TILE_SIZE - 1;
|
||||
}
|
||||
|
||||
/* "index" of blender image */
|
||||
j = m_ys*ibuf->x + xs;
|
||||
/* index of verse image */
|
||||
i = ys*t_width + xs;
|
||||
|
||||
/* pointer at image data, that will be changed in following loop */
|
||||
rect = i_rect + 4*j;
|
||||
|
||||
/* it seems hackish, but I didn't find better solution :-/ */
|
||||
if(vblayer->type==VN_B_LAYER_UINT8) {
|
||||
unsigned char *vuint8 = (unsigned char*)vblayer->data;
|
||||
for(y=ys, m_y = m_ys;
|
||||
(m_y<m_ys+VN_B_TILE_SIZE) && (m_y<ibuf->y);
|
||||
y--, m_y++, i=y*t_width+xs, j=m_y*ibuf->x+xs, rect=i_rect+4*j)
|
||||
for(x=xs; (x<xs+VN_B_TILE_SIZE) && (x<ibuf->x); x++, rect+=4, i++, j++)
|
||||
rect[channel] = (char)vuint8[i];
|
||||
}
|
||||
|
||||
free_realtime_image(image);
|
||||
|
||||
/* redraw preview of image ... uncommented, because rendering
|
||||
* was computed too often */
|
||||
/* BIF_preview_changed(ID_TE); */
|
||||
allqueue(REDRAWIMAGE, 0);
|
||||
allqueue(REDRAWVIEW3D, 0);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
1611
source/blender/src/verse_mesh.c
Normal file
1611
source/blender/src/verse_mesh.c
Normal file
File diff suppressed because it is too large
Load Diff
587
source/blender/src/verse_object.c
Normal file
587
source/blender/src/verse_object.c
Normal file
@ -0,0 +1,587 @@
|
||||
/**
|
||||
* $Id$
|
||||
*
|
||||
* ***** BEGIN GPL/BL DUAL 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. The Blender
|
||||
* Foundation also sells licenses for use in proprietary software under
|
||||
* the Blender License. See http://www.blender.org/BL/ for information
|
||||
* about this.
|
||||
*
|
||||
* 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/BL DUAL 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 "DNA_image_types.h"
|
||||
#include "DNA_listBase.h"
|
||||
|
||||
#include "BLI_dynamiclist.h"
|
||||
#include "BLI_blenlib.h"
|
||||
#include "BLI_editVert.h"
|
||||
#include "BLI_arithb.h"
|
||||
|
||||
#include "BIF_verse.h"
|
||||
#include "BIF_space.h"
|
||||
#include "BIF_editmesh.h"
|
||||
#include "BIF_drawimage.h"
|
||||
#include "BIF_editmode_undo.h"
|
||||
#include "BIF_toolbox.h"
|
||||
|
||||
#include "BKE_verse.h"
|
||||
#include "BKE_global.h"
|
||||
#include "BKE_object.h"
|
||||
#include "BKE_utildefines.h"
|
||||
#include "BKE_depsgraph.h"
|
||||
#include "BKE_image.h"
|
||||
#include "BKE_library.h"
|
||||
#include "BKE_DerivedMesh.h"
|
||||
#include "BKE_mesh.h"
|
||||
#include "BKE_displist.h"
|
||||
|
||||
#include "BDR_editobject.h"
|
||||
|
||||
#include "verse.h"
|
||||
|
||||
/* button callback function, it test object name and send new name to verse server */
|
||||
void test_and_send_idbutton_cb(void *obj, void *ob_name)
|
||||
{
|
||||
struct Object *ob = (Object*)obj;
|
||||
char *name= (char*)ob_name;
|
||||
|
||||
test_idbutton(name+2);
|
||||
|
||||
if(ob->vnode) verse_send_node_name_set(((VNode*)ob->vnode)->id, name+2);
|
||||
}
|
||||
|
||||
/*
|
||||
* duplicate verse object nodes
|
||||
*/
|
||||
void b_verse_duplicate_object(VerseSession *session, Object *ob, Object *n_ob)
|
||||
{
|
||||
struct VNode *obj_vnode;
|
||||
|
||||
if(!session) return;
|
||||
|
||||
if(!(session->flag & VERSE_CONNECTED)) return;
|
||||
|
||||
/* create "my" new object VerseNode */
|
||||
obj_vnode= create_verse_node(session, -1 , V_NT_OBJECT, VN_OWNER_MINE);
|
||||
/* create object data */
|
||||
obj_vnode->data = create_object_data();
|
||||
|
||||
/* set up name of VerseNode */
|
||||
obj_vnode->name = (char*)MEM_mallocN(sizeof(char*)*(strlen(n_ob->id.name)-1), "object node name");
|
||||
obj_vnode->name[0] = '\0';
|
||||
strcat(obj_vnode->name, n_ob->id.name+2);
|
||||
|
||||
/* set up object node transformation */
|
||||
VECCOPY(((VObjectData*)obj_vnode->data)->pos, n_ob->loc);
|
||||
EulToQuat(n_ob->rot, ((VObjectData*)obj_vnode->data)->rot);
|
||||
VECCOPY(((VObjectData*)obj_vnode->data)->scale, n_ob->size);
|
||||
|
||||
/* set up pointers between Object and VerseNode */
|
||||
((VObjectData*)obj_vnode->data)->object = (void*)n_ob;
|
||||
n_ob->vnode = (void*)obj_vnode;
|
||||
|
||||
/* add node to sending queue */
|
||||
add_item_to_send_queue(&(session->queue), obj_vnode, VERSE_NODE);
|
||||
|
||||
if(ob->type==OB_MESH) {
|
||||
struct Mesh *me;
|
||||
struct VNode *geom_vnode;
|
||||
struct VLink *vlink;
|
||||
|
||||
/* when current mesh already shared at verse server, then only set up link
|
||||
* between object node and geometry node */
|
||||
if(ob->data == n_ob->data) {
|
||||
geom_vnode = (VNode*)((Mesh*)ob->data)->vnode;
|
||||
}
|
||||
else {
|
||||
geom_vnode = create_geom_vnode_from_geom_vnode((VNode*)((Mesh*)ob->data)->vnode);
|
||||
me = (Mesh*)n_ob->data;
|
||||
me->vnode = (void*)geom_vnode;
|
||||
((VGeomData*)geom_vnode->data)->mesh = (void*)me;
|
||||
|
||||
}
|
||||
/* create new link between VereseNodes */
|
||||
vlink = create_verse_link(session, obj_vnode, geom_vnode, -1, -1, "geometry");
|
||||
/* "send" link to verse server */
|
||||
add_item_to_send_queue(&(((VObjectData*)obj_vnode->data)->queue), vlink, VERSE_LINK);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* temp hack: this function push mesh objects (edit mode only) to verse server
|
||||
*/
|
||||
void b_verse_push_object(VerseSession *session, Object *ob)
|
||||
{
|
||||
struct VNode *obj_vnode;
|
||||
|
||||
if(!session) return;
|
||||
|
||||
if(!(session->flag & VERSE_CONNECTED)) return;
|
||||
|
||||
/* create "my" new object VerseNode */
|
||||
obj_vnode= create_verse_node(session, -1 , V_NT_OBJECT, VN_OWNER_MINE);
|
||||
/* create object data */
|
||||
obj_vnode->data = create_object_data();
|
||||
|
||||
/* set up name of VerseNode */
|
||||
obj_vnode->name = (char*)MEM_mallocN(sizeof(char*)*(strlen(ob->id.name)-1), "object node name");
|
||||
obj_vnode->name[0] = '\0';
|
||||
strcat(obj_vnode->name, ob->id.name+2);
|
||||
|
||||
/* set up object node transformation */
|
||||
VECCOPY(((VObjectData*)obj_vnode->data)->pos, ob->loc);
|
||||
EulToQuat(ob->rot, ((VObjectData*)obj_vnode->data)->rot);
|
||||
VECCOPY(((VObjectData*)obj_vnode->data)->scale, ob->size);
|
||||
|
||||
/* set up pointers between Object and VerseNode */
|
||||
((VObjectData*)obj_vnode->data)->object = (void*)ob;
|
||||
ob->vnode = (void*)obj_vnode;
|
||||
|
||||
/* add node to sending queue */
|
||||
add_item_to_send_queue(&(session->queue), obj_vnode, VERSE_NODE);
|
||||
|
||||
if(ob->type==OB_MESH) {
|
||||
struct VNode *geom_vnode;
|
||||
struct VLink *vlink;
|
||||
|
||||
if(G.obedit)
|
||||
geom_vnode = create_geom_vnode_data_from_editmesh(session, G.editMesh);
|
||||
else
|
||||
geom_vnode = create_geom_vnode_data_from_mesh(session, get_mesh(ob));
|
||||
|
||||
if(geom_vnode) {
|
||||
/* create new link between VereseNodes */
|
||||
vlink = create_verse_link(session, obj_vnode, geom_vnode, -1, -1, "geometry");
|
||||
/* send link to verse server */
|
||||
add_item_to_send_queue(&(((VObjectData*)obj_vnode->data)->queue), vlink, VERSE_LINK);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* creates blender object from verse object node and it
|
||||
* will create links between them
|
||||
*/
|
||||
Object *create_object_from_verse_node(VNode *vnode)
|
||||
{
|
||||
struct Object *ob;
|
||||
|
||||
if(vnode->type != V_NT_OBJECT) return NULL;
|
||||
|
||||
/* create new object*/
|
||||
ob = add_object(OB_MESH);
|
||||
/* set up bindings between verse node and blender object */
|
||||
ob->vnode = (void*)vnode;
|
||||
((VObjectData*)vnode->data)->object = (void*)ob;
|
||||
/* set up flags */
|
||||
((VObjectData*)vnode->data)->flag |= POS_RECEIVE_READY;
|
||||
((VObjectData*)vnode->data)->flag |= ROT_RECEIVE_READY;
|
||||
((VObjectData*)vnode->data)->flag |= SCALE_RECEIVE_READY;
|
||||
/* copy name from verse node to object */
|
||||
if(vnode->name) {
|
||||
char *str;
|
||||
str = (char*)MEM_mallocN(sizeof(char)*(strlen(vnode->name)+3), "temp object name");
|
||||
str[0] = '\0';
|
||||
strcat(str, "OB");
|
||||
strcat(str, vnode->name);
|
||||
strncpy(ob->id.name, str, 23);
|
||||
MEM_freeN(str);
|
||||
}
|
||||
/* subscribe for object transformation */
|
||||
verse_send_o_transform_subscribe(vnode->id, 0);
|
||||
|
||||
return ob;
|
||||
}
|
||||
|
||||
/*
|
||||
* Create blender object-mesh from verse object node, verse geometry node,
|
||||
*/
|
||||
void b_verse_pop_node(VNode *vnode)
|
||||
{
|
||||
if((!vnode) || (!(vnode->data))) return;
|
||||
|
||||
if(vnode->type==V_NT_OBJECT) {
|
||||
struct VNode *geom_node=NULL;
|
||||
struct VLink *vlink;
|
||||
struct VLayer *vlayer;
|
||||
struct Object *ob;
|
||||
struct Mesh *me;
|
||||
|
||||
if(((VObjectData*)vnode->data)->object) {
|
||||
printf("\tError: already subscribed to object node.\n");
|
||||
return;
|
||||
}
|
||||
|
||||
vlink = ((VObjectData*)vnode->data)->links.lb.first;
|
||||
|
||||
/* try to find geometry node */
|
||||
while(vlink) {
|
||||
if(vlink->target && vlink->target->type==V_NT_GEOMETRY){
|
||||
geom_node = vlink->target;
|
||||
break;
|
||||
}
|
||||
vlink = vlink->next;
|
||||
}
|
||||
|
||||
/* we are not interested now in avatars node, etc. (vnodes without
|
||||
* links at geometry node) */
|
||||
if(!geom_node) return;
|
||||
|
||||
/* subscribe to all verse geometry layer */
|
||||
vlayer = ((VGeomData*)geom_node->data)->layers.lb.first;
|
||||
while(vlayer) {
|
||||
verse_send_g_layer_subscribe(geom_node->id, vlayer->id, 0);
|
||||
vlayer = vlayer->next;
|
||||
}
|
||||
|
||||
ob = create_object_from_verse_node(vnode);
|
||||
|
||||
me = create_mesh_from_geom_node(geom_node);
|
||||
|
||||
/* set up bindings between object and mesh */
|
||||
if(ob && me) ob->data = me;
|
||||
}
|
||||
else if(vnode->type==V_NT_BITMAP) {
|
||||
struct VBitmapData *vbitmap;
|
||||
struct VBitmapLayer *vblayer;
|
||||
|
||||
vbitmap = (VBitmapData*)vnode->data;
|
||||
|
||||
vblayer = vbitmap->layers.lb.first;
|
||||
|
||||
while(vblayer) {
|
||||
if(!(vblayer->flag & VBLAYER_SUBSCRIBED)) {
|
||||
/* 0 means level of subscription (full resolution) */
|
||||
verse_send_b_layer_subscribe(vnode->id, vblayer->id, 0);
|
||||
vblayer->flag |= VBLAYER_SUBSCRIBED;
|
||||
}
|
||||
vblayer = vblayer->next;
|
||||
}
|
||||
|
||||
if(vbitmap->image) {
|
||||
printf("\tError: already subscribed to image node.\n");
|
||||
return;
|
||||
}
|
||||
|
||||
vbitmap->image = (void*)new_image(
|
||||
vbitmap->width,
|
||||
vbitmap->height,
|
||||
vnode->name,
|
||||
0);
|
||||
((Image*)vbitmap->image)->vnode = (void*)vnode;
|
||||
sync_blender_image_with_verse_bitmap_node(vnode);
|
||||
|
||||
allqueue(REDRAWIMAGE, 0);
|
||||
allqueue(REDRAWVIEW3D, 0);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* this function will unsubscribe object node from transformation, but it will
|
||||
* keep all tags and links at other nodes ... user could subscribe to this node
|
||||
* again in future
|
||||
*/
|
||||
void unsubscribe_from_obj_node(VNode *vnode)
|
||||
{
|
||||
struct VerseSession *session = vnode->session;
|
||||
struct VLink *vlink;
|
||||
|
||||
if(vnode->type != V_NT_OBJECT) return;
|
||||
|
||||
/* unsubscribe from receiving changes of transformation matrix */
|
||||
if(session->flag & VERSE_CONNECTED)
|
||||
verse_send_o_transform_unsubscribe(vnode->id, 0);
|
||||
|
||||
/* we have to reinitialize object node transformation */
|
||||
((VObjectData*)vnode->data)->pos[0] = 0.0f;
|
||||
((VObjectData*)vnode->data)->pos[1] = 0.0f;
|
||||
((VObjectData*)vnode->data)->pos[2] = 0.0f;
|
||||
|
||||
((VObjectData*)vnode->data)->rot[0] = 0.0f;
|
||||
((VObjectData*)vnode->data)->rot[1] = 0.0f;
|
||||
((VObjectData*)vnode->data)->rot[2] = 0.0f;
|
||||
((VObjectData*)vnode->data)->rot[3] = 0.0f;
|
||||
|
||||
((VObjectData*)vnode->data)->scale[0] = 0.0f;
|
||||
((VObjectData*)vnode->data)->scale[1] = 0.0f;
|
||||
((VObjectData*)vnode->data)->scale[2] = 0.0f;
|
||||
|
||||
/* clear bindings between object and object node */
|
||||
if(((VObjectData*)vnode->data)->object) {
|
||||
((Object*)((VObjectData*)vnode->data)->object)->vnode = NULL;
|
||||
((VObjectData*)vnode->data)->object = NULL;
|
||||
}
|
||||
|
||||
/* unsubscribe from all supported verse nodes */
|
||||
vlink = ((VObjectData*)vnode->data)->links.lb.first;
|
||||
while(vlink) {
|
||||
if(vlink->target->counter==1) {
|
||||
switch(vlink->target->type) {
|
||||
case V_NT_OBJECT:
|
||||
unsubscribe_from_obj_node(vlink->target);
|
||||
break;
|
||||
case V_NT_GEOMETRY:
|
||||
unsubscribe_from_geom_node(vlink->target);
|
||||
break;
|
||||
case V_NT_BITMAP:
|
||||
unsubscribe_from_bitmap_node(vlink->target);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
vlink = vlink->next;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* when blender Object is deleted, then we have to unsubscribe and free all
|
||||
* VerseNode dependent on this object
|
||||
*/
|
||||
void b_verse_delete_object(Object *object)
|
||||
{
|
||||
struct VNode *vnode;
|
||||
|
||||
vnode = (VNode*)object->vnode;
|
||||
|
||||
if(vnode) unsubscribe_from_obj_node(vnode);
|
||||
}
|
||||
|
||||
/*
|
||||
* "fake" unsubscribing from object node and all child nodes
|
||||
*/
|
||||
void b_verse_unsubscribe(VNode *vnode)
|
||||
{
|
||||
struct VLink *vlink = ((VObjectData*)vnode->data)->links.lb.first;
|
||||
struct Object *ob = (Object*)((VObjectData*)vnode->data)->object;
|
||||
|
||||
if(vnode->type != V_NT_OBJECT) return;
|
||||
|
||||
if(G.obedit && G.obedit->vnode == (void*)vnode)
|
||||
exit_editmode(2);
|
||||
|
||||
/* create mesh data */
|
||||
while(vlink){
|
||||
if(vlink->target->type == V_NT_GEOMETRY) {
|
||||
struct Mesh *me;
|
||||
me = ((VGeomData*)vnode->data)->mesh;
|
||||
create_meshdata_from_geom_node(me, vnode);
|
||||
break;
|
||||
}
|
||||
vlink = vlink->next;
|
||||
}
|
||||
|
||||
/* unsubscribe from object transformation and clear bindings between
|
||||
* verse object node and object */
|
||||
unsubscribe_from_obj_node(vnode);
|
||||
|
||||
/* when geometry node was shared with more object nodes, then make
|
||||
* data single user */
|
||||
if(ob->type == OB_MESH) {
|
||||
struct ID *id = ob->data;
|
||||
if(id && id->us>1 && id->lib==0) {
|
||||
ob->recalc= OB_RECALC_DATA;
|
||||
ob->data = copy_mesh(ob->data);
|
||||
id->us--;
|
||||
id->newid= ob->data;
|
||||
}
|
||||
}
|
||||
|
||||
/* reinitialize object derived mesh */
|
||||
makeDispListMesh(ob);
|
||||
|
||||
DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA);
|
||||
allqueue(REDRAWVIEW3D, 1);
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* whe VerseLink is created between two nodes, the Object start to point at
|
||||
* coresponding data
|
||||
*/
|
||||
void post_link_set(VLink *vlink)
|
||||
{
|
||||
struct VNode *target, *source;
|
||||
struct Object *ob=NULL;
|
||||
struct Mesh *me=NULL;
|
||||
|
||||
source = vlink->source;
|
||||
target = vlink->target;
|
||||
|
||||
if(source->type==V_NT_OBJECT && target->type==V_NT_GEOMETRY){
|
||||
if(((VObjectData*)source->data)->object)
|
||||
ob = (Object*)((VObjectData*)source->data)->object;
|
||||
if(((VGeomData*)target->data)->mesh)
|
||||
me = (Mesh*)((VGeomData*)target->data)->mesh;
|
||||
if(ob && me && ob->data!=me) {
|
||||
ob->data = me;
|
||||
makeDispListMesh(ob);
|
||||
}
|
||||
}
|
||||
|
||||
allqueue(REDRAWALL, 1);
|
||||
}
|
||||
|
||||
/*
|
||||
* when VerseLink is deleted, then bindings between Object and data should be removed
|
||||
*/
|
||||
void post_link_destroy(VLink *vlink)
|
||||
{
|
||||
struct VNode *source, *target;
|
||||
struct Object *ob;
|
||||
|
||||
source = vlink->source;
|
||||
target = vlink->target;
|
||||
|
||||
if(source->type==V_NT_OBJECT && target->type==V_NT_GEOMETRY) {
|
||||
if(((VObjectData*)source->data)->object) {
|
||||
ob = (Object*)((VObjectData*)source->data)->object;
|
||||
ob->data=NULL;
|
||||
}
|
||||
}
|
||||
|
||||
allqueue(REDRAWALL, 1);
|
||||
}
|
||||
|
||||
/*
|
||||
* recalculate transformation matrix of object
|
||||
*/
|
||||
void post_transform(VNode *vnode)
|
||||
{
|
||||
struct VObjectData *obj_data = (VObjectData*)vnode->data;
|
||||
struct Object *ob = (Object*)obj_data->object;
|
||||
float mat_s[4][4];
|
||||
float mat_r[4][4];
|
||||
float mat_p[4][4];
|
||||
float mat[4][4];
|
||||
|
||||
if(!obj_data->object) return;
|
||||
|
||||
Mat4One(mat_s);
|
||||
Mat4One(mat_r);
|
||||
Mat4One(mat_p);
|
||||
|
||||
/* scale */
|
||||
mat_s[0][0] = ob->size[0] = obj_data->scale[0];
|
||||
mat_s[1][1] = ob->size[1] = obj_data->scale[1];
|
||||
mat_s[2][2] = ob->size[2] = obj_data->scale[2];
|
||||
|
||||
/* rotate */
|
||||
QuatToEul(obj_data->rot, ob->rot);
|
||||
QuatToMat4(obj_data->rot, mat_r);
|
||||
|
||||
/* position */
|
||||
mat_p[3][0] = ob->loc[0] = obj_data->pos[0];
|
||||
mat_p[3][1] = ob->loc[1] = obj_data->pos[1];
|
||||
mat_p[3][2] = ob->loc[2] = obj_data->pos[2];
|
||||
|
||||
/* matrix multiplication */
|
||||
Mat4MulMat4(mat, mat_r, mat_p);
|
||||
Mat4MulMat4(ob->obmat, mat_s, mat);
|
||||
|
||||
DAG_object_flush_update(G.scene, ob, OB_RECALC_OB);
|
||||
|
||||
allqueue(REDRAWVIEW3D, 1);
|
||||
}
|
||||
|
||||
/*
|
||||
* send transformation of Object to verse server
|
||||
*/
|
||||
void b_verse_send_transformation(Object *ob)
|
||||
{
|
||||
struct VNode *vnode= ob->vnode;
|
||||
float quat[4];
|
||||
|
||||
if(!vnode) return;
|
||||
|
||||
/* if last sent position wasn't received yet, then next change of position
|
||||
* can't be send until last send change is received */
|
||||
if( ((VObjectData*)vnode->data)->flag & POS_SEND_READY ) {
|
||||
if((((VObjectData*)vnode->data)->pos[0]!=ob->loc[0]) ||
|
||||
(((VObjectData*)vnode->data)->pos[1]!=ob->loc[1]) ||
|
||||
(((VObjectData*)vnode->data)->pos[2]!=ob->loc[2])) {
|
||||
VECCOPY(((VObjectData*)vnode->data)->pos, ob->loc);
|
||||
send_verse_object_position(vnode);
|
||||
}
|
||||
}
|
||||
|
||||
/* if last sent rotation wasn't received yet, then next change of rotation
|
||||
* can't be send until last send change is received */
|
||||
if( ((VObjectData*)vnode->data)->flag & ROT_SEND_READY ) {
|
||||
EulToQuat(ob->rot, quat);
|
||||
|
||||
if((((VObjectData*)vnode->data)->rot[0] != quat[0]) ||
|
||||
(((VObjectData*)vnode->data)->rot[1] != quat[1]) ||
|
||||
(((VObjectData*)vnode->data)->rot[2] != quat[2]) ||
|
||||
(((VObjectData*)vnode->data)->rot[3] != quat[3])) {
|
||||
QUATCOPY(((VObjectData*)vnode->data)->rot, quat);
|
||||
send_verse_object_rotation(vnode);
|
||||
}
|
||||
}
|
||||
|
||||
/* if last sent object size wasn't received yet, then next change of object size
|
||||
* can't be send until last send change is received */
|
||||
if( ((VObjectData*)vnode->data)->flag & SCALE_SEND_READY ) {
|
||||
if((((VObjectData*)vnode->data)->scale[0]!=ob->size[0]) ||
|
||||
(((VObjectData*)vnode->data)->scale[1]!=ob->size[1]) ||
|
||||
(((VObjectData*)vnode->data)->scale[2]!=ob->size[2])) {
|
||||
VECCOPY(((VObjectData*)vnode->data)->scale, ob->size);
|
||||
send_verse_object_scale(vnode);
|
||||
}
|
||||
}
|
||||
|
||||
verse_callback_update(0);
|
||||
}
|
||||
|
||||
/*
|
||||
* free constraint between object VerseNode and blender Object
|
||||
*/
|
||||
void post_object_free_constraint(VNode *vnode)
|
||||
{
|
||||
if(((VObjectData*)vnode->data)->object) {
|
||||
/* free pointer at verse derived mesh */
|
||||
struct Object *ob = (Object*)((VObjectData*)vnode->data)->object;
|
||||
if(ob) {
|
||||
if(ob->derivedFinal) {
|
||||
((DerivedMesh*)ob->derivedFinal)->release((DerivedMesh*)ob->derivedFinal);
|
||||
ob->derivedFinal = NULL;
|
||||
}
|
||||
if(ob->derivedDeform) {
|
||||
((DerivedMesh*)ob->derivedDeform)->release((DerivedMesh*)ob->derivedDeform);
|
||||
ob->derivedDeform = NULL;
|
||||
}
|
||||
}
|
||||
/* free constraint */
|
||||
((Object*)((VObjectData*)vnode->data)->object)->vnode = NULL;
|
||||
((VObjectData*)vnode->data)->object = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -357,7 +357,6 @@ int main(int argc, char **argv)
|
||||
case 'v':
|
||||
print_version();
|
||||
exit(0);
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
@ -143,8 +143,8 @@ ifeq ($(OS),linux)
|
||||
CFLAGS += -pipe -fPIC
|
||||
CCFLAGS += -pipe -fPIC
|
||||
# CCFLAGS += -pipe
|
||||
REL_CFLAGS += -O2
|
||||
REL_CCFLAGS += -O2
|
||||
REL_CFLAGS += -ggdb
|
||||
REL_CCFLAGS += -ggdb
|
||||
NAN_DEPEND = true
|
||||
ifeq ($(CPU),alpha)
|
||||
CFLAGS += -mieee
|
||||
|
@ -98,6 +98,10 @@ endif
|
||||
export NAN_FFMPEGCFLAGS ?= -I$(NAN_FFMPEG)/include
|
||||
endif
|
||||
|
||||
ifeq ($(WITH_VERSE), true)
|
||||
export NAN_VERSE ?= $(LCGDIR)/verse
|
||||
endif
|
||||
|
||||
export WITH_OPENEXR ?= true
|
||||
ifeq ($(OS),windows)
|
||||
ifeq ($(FREE_WINDOWS), true)
|
||||
|
@ -136,6 +136,9 @@ ifeq ($(OS),windows)
|
||||
LDFLAGS += -mwindows -mno-cygwin -mconsole
|
||||
DADD += -L/usr/lib/w32api -lnetapi32 -lopengl32 -lglu32 -lshfolder
|
||||
DADD += -L/usr/lib/w32api -lwinmm -lwsock32
|
||||
ifeq ($(WITH_VERSE),true)
|
||||
DADD += -lws2_32
|
||||
endif
|
||||
else
|
||||
DADD = kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib
|
||||
DADD += advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib
|
||||
|
Loading…
Reference in New Issue
Block a user