Split dissolve_disk into dissolve_vert and dissolve_disk as agreed.

also made dissolve vert bmop use the error api, and put in some code 
to report it to the user in the xkey ui code.

Need to make a file in editors/mesh for client code utility functions for 
bmesh, like e.g. reporting bmesh errors to the user, handling conversion 
more automatically, etc.
This commit is contained in:
Joseph Eagar 2009-03-01 06:36:16 +00:00
parent 8be2a86ce1
commit 30313645b0
14 changed files with 8503 additions and 0 deletions

@ -0,0 +1,586 @@
/**
* $Id: BKE_verse.h 12931 2007-12-17 18:20:48Z theeth $
*
* ***** 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"
#include "verse_ms.h"
struct VNode;
struct VerseEdge;
/*
* Verse Edge Hash (similar to edit edge hash)
*/
#define VEDHASHSIZE (512*512)
#define VEDHASH(a, b) ((a<b ? a : b) % VEDHASHSIZE)
/*
* verse data: 4 float value
*/
typedef struct quat_real32_item {
struct quat_real32_item *next, *prev;
struct VLayer *vlayer; /* pointer at VerseLayer */
uint32 id; /* id of item */
real32 value[4];
} quat_real32_item;
/*
* verse data: 4 uint32 values
*/
typedef struct quat_uint32_item {
struct quat_uint32_item *next, *prev;
struct VLayer *vlayer; /* pointer at VerseLayer */
uint32 id; /* id of item */
uint32 value[4];
} quat_uint32_item;
/*
* verse data: 3 float values
*/
typedef struct vec_real32_item {
struct vec_real32_item *next, *prev;
struct VLayer *vlayer; /* pointer at VerseLayer */
uint32 id; /* id of item */
real32 value[3];
} vec_real32_item;
/*
* verse data: float value (weight)
*/
typedef struct real32_item {
struct real32_item *next, *prev;
struct VLayer *vlayer; /* pointer at VerseLayer */
uint32 id; /* id of item */
real32 value;
} real32_item;
/*
* verse data: uint32 value
*/
typedef struct uint32_item {
struct uint32_item *next, *prev;
struct VLayer *vlayer; /* pointer at VerseLayer */
uint32 id; /* id of item */
uint32 value;
} uint32_item;
/*
* verse data: uint8 value
*/
typedef struct uint8_item {
struct uint8_item *next, *prev;
struct VLayer *vlayer; /* pointer at VerseLayer */
uint32 id; /* id of item */
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, etc. */
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 */
float *nos; /* modified normal vector */
} VerseVert;
/*
* structture used for verse edge hash
*/
typedef struct HashVerseEdge {
struct VerseEdge *vedge;
struct HashVerseEdge *next;
} HashVerseEdge;
/*
* fake verse data: edge
*/
typedef struct VerseEdge {
struct VerseEdge *next, *prev;
uint32 v0, v1; /* indexes of verse vertexes */
int counter; /* counter of verse faces using this edge */
struct HashVerseEdge hash; /* hash table */
union {
unsigned int index; /* temporary index of edge */
} tmp;
} VerseEdge;
/*
* verse data: polygon
*/
typedef struct VerseFace {
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 */
float *nos; /* modified 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) */
struct HashVerseEdge *hash; /* verse edge hash */
struct ListBase edges; /* list of fake verse edges */
/* client dependent methods */
void (*post_vertex_create)(struct VerseVert *vvert);
void (*post_vertex_set_xyz)(struct VerseVert *vvert);
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 quat[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_transform_pos)(struct VNode *vnode);
void (*post_transform_rot)(struct VNode *vnode);
void (*post_transform_scale)(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 Method Group
*/
typedef struct VMethodGroup
{
struct VMethodGroup *next, *prev;
uint16 group_id;
char name[16];
struct ListBase methods;
} VMethodGroup;
/*
* Verse Method
*/
typedef struct VMethod
{
struct VMethod *next, *prev;
uint16 id;
char name[500];
uint8 param_count;
VNOParamType *param_type;
char **param_name;
} VMethod;
/*
* 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 methodgroups; /* method groups */
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);
#ifdef VERSECHAT
/* verse chat */
int chat_flag; /* CHAT_LOGGED, CHAT_NOTLOGGED */
#endif
} 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;
typedef struct VerseServer {
struct VerseServer *next, *prev;
char *name; /* human-readable server name */
char *ip; /* string containing IP/domain name of verse server and number of port */
short flag; /* flag: VERSE_CONNECTING, VERSE_CONNECTED */
struct VerseSession *session; /* pointer to related session */
} VerseServer;
/*
* 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
#ifdef VERSECHAT
#define CHAT_NOTLOGGED 0
#define CHAT_LOGGED 1
#endif
/* 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_ms_get(void);
void b_verse_connect(char *address);
void end_verse_session(struct VerseSession *session);
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* lookup_vnode(VerseSession *session, VNodeID node_id);
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_method.c */
void free_verse_methodgroup(VMethodGroup *vmg);
#ifdef VERSECHAT
void send_say(const char *chan, const char *utter);
void send_login(struct VNode *vnode);
void send_logout(struct VNode *vnode);
void send_join(struct VNode *vnode, const char *chan);
void send_leave(struct VNode *vnode, const char *chan);
#endif
void set_method_callbacks(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

@ -0,0 +1,451 @@
/**
* $Id: verse_bitmap_node.c 12931 2007-12-17 18:20:48Z theeth $
*
* ***** 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 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;
default:
data = NULL;
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

File diff suppressed because it is too large Load Diff

@ -0,0 +1,523 @@
/**
* $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): Nathan Letwory.
*
* ***** END GPL/BL DUAL LICENSE BLOCK *****
*/
#ifdef WITH_VERSE
#include <string.h>
#include "MEM_guardedalloc.h"
#include "DNA_listBase.h"
#include "DNA_userdef_types.h"
#include "DNA_text_types.h"
#include "BLI_dynamiclist.h"
#include "BLI_blenlib.h"
#include "BLI_arithb.h"
#include "BIF_verse.h"
#include "BKE_bad_level_calls.h"
#include "BKE_library.h"
#include "BKE_text.h"
#include "BKE_verse.h"
#include "BKE_global.h"
#include "BKE_main.h"
#include "verse.h"
/* helper struct for creating method descriptions */
typedef struct VMethodInfo {
const char *name;
uint8 param_count;
const VNOParamType param_type[4];
const char *param_name[4];
uint16 id;
} VMethodInfo;
#ifdef VERSECHAT
/* array with methods for verse chat */
static VMethodInfo vmethod_info[] = {
{ "join", 1, { VN_O_METHOD_PTYPE_STRING }, { "channel"}},
{ "leave", 1, { VN_O_METHOD_PTYPE_STRING }, { "channel"}},
{ "hear", 3, { VN_O_METHOD_PTYPE_STRING, VN_O_METHOD_PTYPE_STRING, VN_O_METHOD_PTYPE_STRING }, { "channel", "from", "msg"}}
};
#endif
/* lookup a method group based on its name */
struct VMethodGroup *lookup_vmethodgroup_name(ListBase *lb, const char *name) {
struct VMethodGroup *vmg;
for(vmg= lb->first; vmg; vmg= vmg->next)
if(strcmp(vmg->name,name)==0) break;
return vmg;
}
/* lookup a method group based on its group_id */
struct VMethodGroup *lookup_vmethodgroup(ListBase *lb, uint16 group_id) {
struct VMethodGroup *vmg;
for(vmg= lb->first; vmg; vmg= vmg->next)
if(vmg->group_id==group_id) break;
return vmg;
}
/* lookup a method based on its name */
struct VMethod *lookup_vmethod_name(ListBase *lb, const char *name) {
struct VMethod *vm;
for(vm= lb->first; vm; vm= vm->next)
if(strcmp(vm->name,name)==0) break;
return vm;
}
/* lookup a method based on its method_id */
struct VMethod *lookup_vmethod(ListBase *lb, uint8 method_id) {
struct VMethod *vm;
for(vm= lb->first; vm; vm= vm->next)
if(vm->id==method_id) break;
return vm;
}
#ifdef VERSECHAT
/*
* send say command
*/
void send_say(const char *chan, const char *utter)
{
struct VerseSession *session = (VerseSession*)current_verse_session();
struct VNode *vnode;
struct VMethodGroup *vmg;
struct VMethod *vm;
VNOPackedParams *utterpack;
VNOParam args[2];
vnode= (VNode *)(session->nodes.lb.first);
for( ; vnode; vnode= vnode->next) {
if(strcmp(vnode->name, "tawksrv")==0) {
vmg= lookup_vmethodgroup_name(&(vnode->methodgroups), "tawk");
if(!vmg) break;
vm= lookup_vmethod_name(&(vmg->methods), "say");
if(!vm) break;
args[0].vstring= (char *)chan;
args[1].vstring= (char *)utter;
if((utterpack= verse_method_call_pack(vm->param_count, vm->param_type, args))!=NULL) {
verse_send_o_method_call(vnode->id, vmg->group_id, vm->id, vnode->session->avatar, utterpack);
}
break;
}
}
}
/*
* send logout command
*/
void send_logout(VNode *vnode)
{
struct VMethodGroup *vmg;
struct VMethod *vm;
VNOPackedParams *pack;
vnode->chat_flag = CHAT_LOGGED;
vmg= lookup_vmethodgroup_name(&(vnode->methodgroups), "tawk");
if(!vmg) return;
vm= lookup_vmethod_name(&(vmg->methods), "logout");
if(!vm) return;
if((pack= verse_method_call_pack(vm->param_count, vm->param_type, NULL))!=NULL) {
verse_send_o_method_call(vnode->id, vmg->group_id, vm->id, vnode->session->avatar, pack);
}
vnode->chat_flag = CHAT_NOTLOGGED;
}
/*
* send join command
*/
void send_join(VNode *vnode, const char *chan)
{
struct VMethodGroup *vmg;
struct VMethod *vm;
VNOPackedParams *join;
VNOParam channel[1];
vmg= lookup_vmethodgroup_name(&(vnode->methodgroups), "tawk");
if(!vmg) return;
vm= lookup_vmethod_name(&(vmg->methods), "join");
if(!vm) return;
channel[0].vstring= (char *)chan;
if((join= verse_method_call_pack(vm->param_count, vm->param_type, channel))!=NULL) {
verse_send_o_method_call(vnode->id, vmg->group_id, vm->id, vnode->session->avatar, join);
}
}
/*
* send leave command
*/
void send_leave(VNode *vnode, const char *chan)
{
struct VMethodGroup *vmg;
struct VMethod *vm;
VNOPackedParams *leave;
VNOParam channel[1];
vmg= lookup_vmethodgroup_name(&(vnode->methodgroups), "tawk");
if(!vmg) return;
vm= lookup_vmethod_name(&(vmg->methods), "leave");
if(!vm) return;
channel[0].vstring= (char *)chan;
if((leave= verse_method_call_pack(vm->param_count, vm->param_type, channel))!=NULL) {
verse_send_o_method_call(vnode->id, vmg->group_id, vm->id, vnode->session->avatar, leave);
}
}
/*
* send login command
*/
void send_login(VNode *vnode)
{
struct VMethodGroup *vmg;
struct VMethod *vm;
VNOPackedParams *login;
VNOParam param[1];
vnode->chat_flag = CHAT_LOGGED;
vmg= lookup_vmethodgroup_name(&(vnode->methodgroups), "tawk");
if(!vmg) return;
vm= lookup_vmethod_name(&(vmg->methods), "login");
if(!vm) return;
param[0].vstring= U.verseuser;
if((login= verse_method_call_pack(vm->param_count, vm->param_type, param))!=NULL) {
verse_send_o_method_call(vnode->id, vmg->group_id, vm->id, vnode->session->avatar, login);
}
vnode->chat_flag = CHAT_LOGGED;
vnode= lookup_vnode(vnode->session, vnode->session->avatar);
vmg= lookup_vmethodgroup_name(&(vnode->methodgroups), "tawk-client");
if(!vmg)
verse_send_o_method_group_create(vnode->session->avatar, ~0, "tawk-client");
}
#endif
/*
* Free a VMethod
*/
void free_verse_method(VMethod *vm) {
if(!vm) return;
MEM_freeN(vm->param_type);
}
/*
* Free methods for VMethodGroup
*/
void free_verse_methodgroup(VMethodGroup *vmg)
{
struct VMethod *vm, *tmpvm;
if(!vmg) return;
vm= vmg->methods.first;
while(vm) {
tmpvm=vm->next;
free_verse_method(vm);
vm= tmpvm;
}
BLI_freelistN(&(vmg->methods));
}
/* callback for method group creation */
static void cb_o_method_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 VMethodGroup *vmg;
if(!session) return;
vnode = BLI_dlist_find_link(&(session->nodes), (unsigned int)node_id);
vmg = lookup_vmethodgroup(&(vnode->methodgroups), group_id);
/* create method group holder in node node_id */
if(!vmg) {
vmg= MEM_mallocN(sizeof(VMethodGroup), "VMethodGroup");
vmg->group_id = group_id;
vmg->methods.first = vmg->methods.last = NULL;
BLI_addtail(&(vnode->methodgroups), vmg);
printf("new method group with name %s (group_id %d) for node %u created\n", name, group_id, node_id);
}
/* this ensures name of an existing group gets updated, in case it is changed */
BLI_strncpy(vmg->name, (char *)name, 16);
/* subscribe to method group */
verse_send_o_method_group_subscribe(node_id, group_id);
#ifdef VERSECHAT
/* if this is our own method group, register our methods */
if(node_id==session->avatar) {
verse_send_o_method_create(node_id, group_id, (uint8)~0u, vmethod_info[0].name,
vmethod_info[0].param_count,
(VNOParamType *)vmethod_info[0].param_type,
(const char **)vmethod_info[0].param_name);
b_verse_update();
verse_send_o_method_create(node_id, group_id, (uint8)~0u, vmethod_info[1].name,
vmethod_info[1].param_count,
(VNOParamType *)vmethod_info[1].param_type,
(const char **)vmethod_info[1].param_name);
b_verse_update();
verse_send_o_method_create(node_id, group_id, (uint8)~0u, vmethod_info[2].name,
vmethod_info[2].param_count,
(VNOParamType *)vmethod_info[2].param_type,
(const char **)vmethod_info[2].param_name);
b_verse_update();
}
#endif
}
/* callback for method group destruction */
static void cb_o_method_group_destroy(
void *user_data,
VNodeID node_id,
uint16 group_id,
const char *name)
{
struct VerseSession *session = (VerseSession*)current_verse_session();
struct VNode *vnode;
struct VMethodGroup *vmg;
struct VMethod *vm;
printf("method group %d destroyed\n", group_id);
if(!session) return;
vnode = BLI_dlist_find_link(&(session->nodes), (unsigned int)node_id);
for(vmg= vnode->methodgroups.first; vmg; vmg= vmg->next)
if(vmg->group_id==group_id) break;
if(!vmg) return; /* method group doesn't exist? */
vmg->group_id = 0;
vmg->name[0] = '\0';
vm= vmg->methods.first;
while(vm) {
/* free vm */
}
/* TODO: unsubscribe from method group */
BLI_remlink(&(vnode->methodgroups),vmg);
MEM_freeN(vmg);
}
/* callback for method creation */
static void cb_o_method_create(
void *user_data,
VNodeID node_id,
uint16 group_id,
uint16 method_id,
const char *name,
uint8 param_count,
const VNOParamType *param_type,
const char *param_name[])
{
struct VerseSession *session = (VerseSession*)current_verse_session();
struct VNode *vnode;
struct VMethodGroup *vmg;
struct VMethod *vm;
unsigned int size;
unsigned int i;
char *put;
if(!session) return;
vnode = BLI_dlist_find_link(&(session->nodes), (unsigned int)node_id);
vmg= lookup_vmethodgroup((&vnode->methodgroups), group_id);
if(!vmg) return;
vm= lookup_vmethod((&vmg->methods), method_id);
if(!vm) {
vm= MEM_mallocN(sizeof(VMethod), "VMethod");
vm->id= method_id;
vm->param_count= param_count;
size= param_count* (sizeof(*vm->param_type) + sizeof(*vm->param_name));
for(i= 0; i <param_count; i++) {
size+=strlen(param_name[i])+1;
}
vm->param_type= MEM_mallocN(size, "param_type and param_name");
memcpy(vm->param_type, param_type, sizeof(VNOParamType)*param_count);
vm->param_name= (char **)(vm->param_type + param_count);
put= (char *)(vm->param_name + param_count);
for(i= 0; i < param_count; i++) {
vm->param_name[i]= put;
strcpy(put, param_name[i]);
put += strlen(param_name[i]) + 1;
}
BLI_addtail(&(vmg->methods), vm);
#ifdef VERSECHAT
if(strcmp(vmethod_info[0].name, name)==0) {
vmethod_info[0].id = method_id;
}
#endif
printf("method %s in group %d of node %u created\n", name, group_id, node_id);
}
BLI_strncpy(vm->name, (char *)name, 500);
}
/* callback for method destruction */
static void cb_o_method_destroy(
void *user_data,
VNodeID node_id,
uint16 group_id,
uint16 method_id,
const char *name,
uint8 param_count,
const VNOParamType *param_type,
const char *param_name[])
{
struct VerseSession *session = (VerseSession*)current_verse_session();
struct VNode *vnode;
struct VMethodGroup *vmg;
struct VMethod *vm;
if(!session) return;
vnode = BLI_dlist_find_link(&(session->nodes), (unsigned int)node_id);
for(vmg= vnode->methodgroups.first; vmg; vmg= vmg->next)
if(vmg->group_id==group_id) break;
if(!vmg) return; /* method group doesn't exist? */
for(vm= vmg->methods.first; vm; vm= vm->next)
if(vm->id==method_id) break;
if(!vm) return;
BLI_remlink(&(vmg->methods), vm);
MEM_freeN(vm->param_type);
MEM_freeN(vm);
}
/* callback for method calls */
static void cb_o_method_call(void *user_data, VNodeID node_id, uint8 group_id, uint8 method_id, VNodeID sender, VNOPackedParams *params)
{
struct VerseSession *session = (VerseSession*)current_verse_session();
struct VNode *vnode;
struct VMethodGroup *vmg;
struct VMethod *vm;
Text *text;
int method_idx= -1;
VNOParam arg[3];
if(!session) return;
if(session->avatar!=node_id) return;
vnode = BLI_dlist_find_link(&(session->nodes), (unsigned int)node_id);
vmg= lookup_vmethodgroup(&(vnode->methodgroups), group_id);
if(!vmg) return;
vm= lookup_vmethod(&(vmg->methods), method_id);
if(!vm) return;
#ifdef VERSECHAT
if(strcmp(vm->name, "join")==0) method_idx=0;
if(strcmp(vm->name, "leave")==0) method_idx=1;
if(strcmp(vm->name, "hear")==0) method_idx=2;
if(method_idx>-1)
verse_method_call_unpack(params, vmethod_info[method_idx].param_count, vmethod_info[method_idx].param_type, arg);
switch(method_idx) {
case 0:
printf("Joining channel %s\n",arg[0].vstring);
text=add_empty_text();
text->flags |= TXT_ISCHAT;
rename_id(&(text->id), arg[0].vstring);
break;
case 1:
printf("Leaving channel %s\n",arg[0].vstring);
break;
case 2:
{
ListBase lb = G.main->text;
ID *id= (ID *)lb.first;
char showstr[1024];
showstr[0]='\0';
text = NULL;
sprintf(showstr, "%s: %s\n", arg[1].vstring, arg[2].vstring);
for(; id; id= id->next) {
if(strcmp(id->name+2, arg[0].vstring)==0 && strcmp(arg[0].vstring, "#server")!=0) {
text = (Text *)id;
break;
}
}
if(text) {
txt_insert_buf(text, showstr);
txt_move_eof(text, 0);
allqueue(REDRAWCHAT, 0);
} else {
printf("%s> %s: %s\n",arg[0].vstring, arg[1].vstring, arg[2].vstring);
}
}
break;
}
#endif
}
void set_method_callbacks(void)
{
/* create and destroy method groups */
verse_callback_set(verse_send_o_method_group_create, cb_o_method_group_create, NULL);
verse_callback_set(verse_send_o_method_group_destroy, cb_o_method_group_destroy, NULL);
/* create and destroy methods */
verse_callback_set(verse_send_o_method_create, cb_o_method_create, NULL);
verse_callback_set(verse_send_o_method_destroy, cb_o_method_destroy, NULL);
/* call methods */
verse_callback_set(verse_send_o_method_call, cb_o_method_call, NULL);
}
#endif

@ -0,0 +1,750 @@
/**
* $Id: verse_node.c 12931 2007-12-17 18:20:48Z theeth $
*
* ***** 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 "DNA_userdef_types.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);
}
/*
* Find a Verse Node from session
*/
VNode* lookup_vnode(VerseSession *session, VNodeID node_id)
{
struct VNode *vnode;
vnode = BLI_dlist_find_link(&(session->nodes), (unsigned int)node_id);
return vnode;
}
/*
* 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->methodgroups.first = vnode->methodgroups.last = NULL;
vnode->data = NULL;
vnode->counter = 0;
vnode->flag = 0;
#ifdef VERSECHAT
vnode->chat_flag = CHAT_NOTLOGGED;
#endif
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 = NULL;
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) {
verse_send_node_name_set(node_id, U.verseuser);
}
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();
}
break;
default:
vnode = NULL;
break;
}
if(vnode) 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

@ -0,0 +1,620 @@
/**
* $Id: verse_object_node.c 12931 2007-12-17 18:20:48Z theeth $
*
* ***** 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 <math.h>
#include "MEM_guardedalloc.h"
#include "DNA_listBase.h"
#include "DNA_userdef_types.h"
#include "BLI_dynamiclist.h"
#include "BLI_blenlib.h"
#include "BLI_arithb.h"
#include "BIF_verse.h"
#include "BKE_verse.h"
#include "BKE_utildefines.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 *temp, 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;
/* we have to do rotation around x axis (+pi/2) to be
compatible with other verse applications */
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)
{
VNQuat32 quat;
float q[4] = {cos(-M_PI/4), -sin(-M_PI/4), 0, 0}, v[4], tmp[4];
/* inverse transformation to transformation in function cb_o_transform_rot_real32 */
QuatMul(v, ((VObjectData*)vnode->data)->quat, q);
q[1]= sin(-M_PI/4);
QuatMul(tmp, q, v);
quat.x = tmp[1];
quat.y = tmp[2];
quat.z = tmp[3];
quat.w = tmp[0];
((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 */
&quat,
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)
{
float tmp;
((VObjectData*)vnode->data)->flag &= ~SCALE_SEND_READY;
/* we have to do rotation around x axis (+pi/2) to be
compatible with other verse applications */
tmp = ((VObjectData*)vnode->data)->scale[1];
((VObjectData*)vnode->data)->scale[1] = ((VObjectData*)vnode->data)->scale[2];
((VObjectData*)vnode->data)->scale[2] = tmp;
verse_send_o_transform_scale_real32(
vnode->id,
((VObjectData*)vnode->data)->scale[0],
((VObjectData*)vnode->data)->scale[1],
((VObjectData*)vnode->data)->scale[2]);
}
/*
* 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;
struct VMethodGroup *vmg;
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 method groups and their methods */
for(vmg = vnode->methodgroups.first; vmg; vmg= vmg->next) {
free_verse_methodgroup(vmg);
}
BLI_freelistN(&(vnode->methodgroups));
/* 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->quat[0] = obj->quat[1] = obj->quat[2] = 0.0; obj->quat[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_transform_pos = post_transform_pos;
obj->post_transform_rot = post_transform_rot;
obj->post_transform_scale = post_transform_scale;
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);
if(pos) {
vec[0] = pos[0];
vec[1] = pos[1];
vec[2] = pos[2];
}
else {
vec[0] = 0.0f;
vec[1] = 0.0f;
vec[2] = 0.0f;
}
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;
}
/* we have to do rotation around x axis (+pi/2) to be
compatible with other verse applications */
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_pos(vnode);
}
}
/*
* callback function:
*/
static void cb_o_transform_rot_real32(
void *user_data,
VNodeID node_id,
uint32 time_s,
uint32 time_f,
const VNQuat32 *quat,
const VNQuat32 *speed,
const VNQuat32 *accelerate,
const VNQuat32 *drag_normal,
real32 drag)
{
struct VerseSession *session = (VerseSession*)current_verse_session();
struct VNode *vnode;
float temp[4]={0, 0, 0, 0}, v[4], dt; /* temporary quaternions */
float q[4]={cos(M_PI/4), -sin(M_PI/4), 0, 0}; /* conjugate quaternion (represents rotation
around x-axis +90 degrees) */
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(quat) {
temp[1] = quat->x;
temp[2] = quat->y;
temp[3] = quat->z;
temp[0] = quat->w;
}
if(speed) {
temp[1] += speed->x*dt;
temp[2] += speed->y*dt;
temp[3] += speed->z*dt;
temp[0] += speed->w*dt;
}
if(accelerate) {
temp[1] += accelerate->x*dt*dt/2;
temp[2] += accelerate->y*dt*dt/2;
temp[3] += accelerate->z*dt*dt/2;
temp[0] += accelerate->w*dt*dt/2;
}
/* following matematical operation transform rotation:
*
* v' = quaternion * v * conjugate_quaternion
*
*, where v is original representation of rotation */
QuatMul(v, temp, q);
q[1]= sin(M_PI/4); /* normal quaternion */
QuatMul(temp, q, v);
if( (((VObjectData*)vnode->data)->quat[0] != temp[0]) ||
(((VObjectData*)vnode->data)->quat[1] != temp[1]) ||
(((VObjectData*)vnode->data)->quat[2] != temp[2]) ||
(((VObjectData*)vnode->data)->quat[3] != temp[3]))
{
QUATCOPY(((VObjectData*)vnode->data)->quat, temp);
((VObjectData*)vnode->data)->post_transform_rot(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_scale(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

@ -0,0 +1,480 @@
/**
* $Id: verse_session.c 12931 2007-12-17 18:20:48Z theeth $
*
* ***** 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 "DNA_userdef_types.h"
#include "BLI_dynamiclist.h"
#include "BLI_blenlib.h"
#include "BIF_screen.h"
#include "BIF_verse.h"
#include "BKE_global.h"
#include "BKE_verse.h"
struct ListBase session_list={NULL, NULL};
struct ListBase server_list={NULL, NULL};
static int cb_ping_registered = 0;
/* 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);
static void add_verse_server(VMSServer *server);
static void check_connection_state(struct VerseServer *server);
static void check_connection_state(struct VerseServer *server)
{
struct VerseSession *session;
session = session_list.first;
while(session) {
if(strcmp(server->ip,session->address)==0) {
server->flag = session->flag;
return;
}
session = session->next;
}
}
/*
* add verse server to server_list. Prevents duplicate
* entries
*/
static void add_verse_server(VMSServer *server)
{
struct VerseServer *iter, *niter;
VerseServer *newserver;
const char *name = verse_ms_field_value(server, "DE");
iter = server_list.first;
while(iter) {
niter = iter->next;
if(strcmp(iter->ip, server->ip)==0) {
return;
}
iter = niter;
}
newserver = (VerseServer *)MEM_mallocN(sizeof(VerseServer), "VerseServer");
newserver->ip = (char *)MEM_mallocN(sizeof(char)*(strlen(server->ip)+1), "VerseServer ip");
strcpy(newserver->ip, server->ip);
if(name) {
newserver->name = (char *)MEM_mallocN(sizeof(char)*(strlen(name)+strlen(newserver->ip)+4), "VerseServer name");
strcpy(newserver->name, name);
strcat(newserver->name, " (");
strcat(newserver->name, newserver->ip);
strcat(newserver->name, ")");
}
newserver->flag = 0;
check_connection_state(newserver);
printf("Adding new verse server: %s at %s\n", newserver->name, newserver->ip);
BLI_addtail(&server_list, newserver);
post_server_add();
}
/*
* callback function for ping
*/
static void cb_ping(void *user, const char *address, const char *message)
{
VMSServer **servers = verse_ms_list_parse(message);
if(servers != NULL)
{
int i;
for(i = 0; servers[i] != NULL; i++)
add_verse_server(servers[i]);
free(servers);
}
}
/*
* 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();
struct VerseServer *server = server_list.first;
uint32 i, mask=0;
if(!session) return;
session->flag |= VERSE_CONNECTED;
session->flag &= ~VERSE_CONNECTING;
while(server) {
if(strcmp(session->address, server->ip)==0) {
server->flag |= VERSE_CONNECTED;
server->flag &= ~VERSE_CONNECTING;
server->session = session;
break;
}
server = server->next;
}
printf("\tBlender is 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);
verse_send_node_subscribe(session->avatar); /* subscribe to avatar node, as well */
/* create our own method group and method */
/*verse_send_o_method_group_create(session->avatar, ~0, "tawk-client");*/
}
/*
* 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();
/* set up all callbacks for method groups and methods */
set_method_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;
}
if(cb_ping_registered>0) {
verse_callback_update(10);
}
}
/*
* 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;
post_server_add();
return session;
}
/*
* end verse session and free all session data
*/
void end_verse_session(VerseSession *session)
{
/* 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 structure of verse session */
free_verse_session(session);
}
void free_all_servers(void)
{
VerseServer *server, *nextserver;
server = server_list.first;
while(server) {
nextserver = server->next;
BLI_remlink(&server_list, server);
MEM_freeN(server->name);
MEM_freeN(server->ip);
MEM_freeN(server);
server = nextserver;
}
BLI_freelistN(&server_list);
}
/*
* end connection to all verse hosts (servers) ... free all VerseSessions
* free all VerseServers
*/
void end_all_verse_sessions(void)
{
VerseSession *session,*nextsession;
session = session_list.first;
while(session) {
nextsession= session->next;
end_verse_session(session);
/* end next session */
session = nextsession;
}
BLI_freelistN(&session_list);
free_all_servers();
}
/*
* do a get from ms
*/
void b_verse_ms_get(void)
{
if(cb_ping_registered==0) {
/* handle ping messages (for master server) */
verse_callback_set(verse_send_ping, cb_ping, NULL);
add_screenhandler(G.curscreen, SCREEN_HANDLER_VERSE, 1);
cb_ping_registered++;
}
free_all_servers();
verse_ms_get_send(U.versemaster, VERSE_MS_FIELD_DESCRIPTION, NULL);
verse_callback_update(10);
}
/*
* connect to verse host, set up all callbacks, create session
*/
void b_verse_connect(char *address)
{
VerseSession *session = NULL;
/* 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

@ -0,0 +1,99 @@
/*
* $Id: ED_editparticle.h $
*
* ***** BEGIN GPL LICENSE BLOCK *****
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
* The Original Code is Copyright (C) 2007 by Janne Karhu.
* All rights reserved.
*
* The Original Code is: all of this file.
*
* Contributor(s): none yet.
*
* ***** END GPL LICENSE BLOCK *****
*/
#ifndef ED_PARTICLE_H
#define ED_PARTICLE_H
struct Object;
struct ParticleSystem;
struct ParticleEditSettings;
struct RadialControl;
struct ViewContext;
struct rcti;
struct wmWindowManager;
/* particle edit mode */
void PE_set_particle_edit(struct Scene *scene);
void PE_create_particle_edit(struct Scene *scene, struct Object *ob, struct ParticleSystem *psys);
void PE_free_particle_edit(struct ParticleSystem *psys);
void PE_change_act(void *ob_v, void *act_v);
void PE_change_act_psys(struct Scene *scene, struct Object *ob, struct ParticleSystem *psys);
int PE_can_edit(struct ParticleSystem *psys);
/* access */
struct ParticleSystem *PE_get_current(struct Scene *scene, struct Object *ob);
short PE_get_current_num(struct Object *ob);
int PE_minmax(struct Scene *scene, float *min, float *max);
void PE_get_colors(char sel[4], char nosel[4]);
struct ParticleEditSettings *PE_settings(Scene *scene);
struct RadialControl **PE_radialcontrol(void);
/* update calls */
void PE_hide_keys_time(struct Scene *scene, struct ParticleSystem *psys, float cfra);
void PE_update_object(struct Scene *scene, struct Object *ob, int useflag);
void PE_update_selection(struct Scene *scene, struct Object *ob, int useflag);
void PE_recalc_world_cos(struct Object *ob, struct ParticleSystem *psys);
/* selection tools */
void PE_select_root(void);
void PE_select_tip(void);
void PE_deselectall(void);
void PE_select_linked(void);
void PE_select_less(void);
void PE_select_more(void);
void PE_mouse_particles(void);
void PE_border_select(struct ViewContext *vc, struct rcti *rect, int select);
void PE_circle_select(struct ViewContext *vc, int selecting, short *mval, float rad);
void PE_lasso_select(struct ViewContext *vc, short mcords[][2], short moves, short select);
/* tools */
void PE_hide(int mode);
void PE_rekey(void);
void PE_subdivide(Object *ob);
int PE_brush_particles(void);
void PE_remove_doubles(void);
void PE_selectbrush_menu(Scene *scene);
void PE_remove_doubles(void);
void PE_radialcontrol_start(const int mode);
/* undo */
void PE_undo_push(Scene *scene, char *str);
void PE_undo_step(Scene *scene, int step);
void PE_undo(Scene *scene);
void PE_redo(Scene *scene);
void PE_undo_menu(Scene *scene, Object *ob);
/* operators */
void ED_operatortypes_particle(void);
void ED_keymap_particle(struct wmWindowManager *wm);
#endif /* ED_PARTICLE_H */

@ -0,0 +1,213 @@
/**
* $Id:
*
* ***** BEGIN GPL LICENSE BLOCK *****
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
* The Original Code is Copyright (C) 2009 Blender Foundation.
* All rights reserved.
*
*
* Contributor(s): Blender Foundation, Joshua Leung
*
* ***** END GPL LICENSE BLOCK *****
*/
#include <string.h>
#include <stdio.h>
#include <math.h>
#include <float.h>
#include "DNA_anim_types.h"
#include "DNA_action_types.h"
#include "DNA_object_types.h"
#include "DNA_space_types.h"
#include "DNA_scene_types.h"
#include "DNA_screen_types.h"
#include "DNA_userdef_types.h"
#include "MEM_guardedalloc.h"
#include "BLI_arithb.h"
#include "BLI_blenlib.h"
#include "BLI_editVert.h"
#include "BLI_rand.h"
#include "BKE_animsys.h"
#include "BKE_action.h"
#include "BKE_context.h"
#include "BKE_curve.h"
#include "BKE_customdata.h"
#include "BKE_depsgraph.h"
#include "BKE_object.h"
#include "BKE_global.h"
#include "BKE_scene.h"
#include "BKE_screen.h"
#include "BKE_utildefines.h"
#include "BIF_gl.h"
#include "WM_api.h"
#include "WM_types.h"
#include "RNA_access.h"
#include "RNA_define.h"
#include "ED_anim_api.h"
#include "ED_keyframing.h"
#include "ED_screen.h"
#include "ED_types.h"
#include "ED_util.h"
#include "UI_interface.h"
#include "UI_resources.h"
#include "UI_view2d.h"
#include "graph_intern.h" // own include
/* ******************* view3d space & buttons ************** */
#define B_NOP 1
#define B_REDR 2
static void do_graph_region_buttons(bContext *C, void *arg, int event)
{
//Scene *scene= CTX_data_scene(C);
switch(event) {
}
/* default for now */
//WM_event_add_notifier(C, NC_OBJECT|ND_TRANSFORM, ob);
}
static void graph_panel_properties(const bContext *C, ARegion *ar, short cntrl, bAnimListElem *ale) // GRAPH_HANDLER_SETTINGS
{
uiBlock *block;
char name[128];
block= uiBeginBlock(C, ar, "graph_panel_properties", UI_EMBOSS, UI_HELV);
if(uiNewPanel(C, ar, block, "Properties", "Graph", 340, 30, 318, 254)==0) return;
uiBlockSetHandleFunc(block, do_graph_region_buttons, NULL);
/* to force height */
uiNewPanelHeight(block, 204);
// XXX testing buttons
uiDefBut(block, LABEL, 1, "Active F-Curve:", 10, 200, 150, 19, NULL, 0.0, 0.0, 0, 0, "");
getname_anim_fcurve(name, ale->id, (FCurve *)ale->data);
uiDefBut(block, LABEL, 1, name, 30, 180, 300, 19, NULL, 0.0, 0.0, 0, 0, "Name of Active F-Curve");
#if 0
uiBlockBeginAlign(block);
uiDefButF(block, NUM, B_REDR, "Spacing:", 10, 200, 140, 19, &v3d->grid, 0.001, 100.0, 10, 0, "Set the distance between grid lines");
uiDefButS(block, NUM, B_REDR, "Lines:", 10, 180, 140, 19, &v3d->gridlines, 0.0, 100.0, 100, 0, "Set the number of grid lines in perspective view");
uiDefButS(block, NUM, B_REDR, "Divisions:", 10, 160, 140, 19, &v3d->gridsubdiv, 1.0, 100.0, 100, 0, "Set the number of grid lines");
uiBlockEndAlign(block);
#endif
}
/* Find 'active' F-Curve. It must be editable, since that's the purpose of these buttons (subject to change).
* We return the 'wrapper' since it contains valuable context info (about hierarchy), which will need to be freed
* when the caller is done with it.
*/
// TODO: move this to anim api with another name?
static bAnimListElem *get_active_fcurve_channel (bAnimContext *ac)
{
ListBase anim_data = {NULL, NULL};
int filter= (ANIMFILTER_VISIBLE | ANIMFILTER_FOREDIT | ANIMFILTER_ACTIVE | ANIMFILTER_CURVESONLY);
int items = ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
/* We take the first F-Curve only, since some other ones may have had 'active' flag set
* if they were from linked data.
*/
if (items) {
bAnimListElem *ale= (bAnimListElem *)anim_data.first;
/* remove first item from list, then free the rest of the list and return the stored one */
BLI_remlink(&anim_data, ale);
BLI_freelistN(&anim_data);
return ale;
}
/* no active F-Curve */
return NULL;
}
void graph_region_buttons(const bContext *C, ARegion *ar)
{
SpaceIpo *sipo= (SpaceIpo *)CTX_wm_space_data(C);
bAnimContext ac;
bAnimListElem *ale= NULL;
/* for now, only draw if we could init the anim-context info (necessary for all animation-related tools)
* to work correctly is able to be correctly retrieved. There's no point showing empty panels?
*/
if (ANIM_animdata_get_context(C, &ac) == 0)
return;
/* try to find 'active' F-Curve */
ale= get_active_fcurve_channel(&ac);
if (ale == NULL)
return;
// XXX temp panel for testing
graph_panel_properties(C, ar, 0, ale);
/* driver settings for active F-Curve (only for 'Drivers' mode) */
if (sipo->mode == SIPO_MODE_DRIVERS) {
//graph_panel_drivers(C, ar, 0);
}
uiDrawPanels(C, 1); /* 1 = align */
uiMatchPanelsView2d(ar); /* sets v2d->totrct */
/* free temp data */
MEM_freeN(ale);
}
static int graph_properties(bContext *C, wmOperator *op)
{
ScrArea *sa= CTX_wm_area(C);
ARegion *ar= graph_has_buttons_region(sa);
if(ar) {
ar->flag ^= RGN_FLAG_HIDDEN;
ar->v2d.flag &= ~V2D_IS_INITIALISED; /* XXX should become hide/unhide api? */
ED_area_initialize(CTX_wm_manager(C), CTX_wm_window(C), sa);
ED_area_tag_redraw(sa);
}
return OPERATOR_FINISHED;
}
void GRAPHEDIT_OT_properties(wmOperatorType *ot)
{
ot->name= "Properties";
ot->idname= "GRAPHEDIT_OT_properties";
ot->exec= graph_properties;
ot->poll= ED_operator_ipo_active; // xxx
/* flags */
ot->flag= 0;
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

@ -0,0 +1,128 @@
/*
* $Id: BPY_menus.h 12931 2007-12-17 18:20:48Z theeth $
*
* ***** 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.
*
* The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
* All rights reserved.
*
* This is a new part of Blender.
*
* Contributor(s): Willian P. Germano, Matt Ebb
*
* ***** END GPL/BL DUAL LICENSE BLOCK *****
*/
#ifndef BPY_MENUS_H
#define BPY_MENUS_H
/* This header exposes BPyMenu related public declarations. The implementation
* adds 'dynamic' menus to Blender, letting scripts register themselves in any
* of a few pre-defined (trivial to upgrade) places in menus. These places or
* slots are called groups here (Import, Export, etc). This is how it works:
* - scripts at dirs user pref U.pythondir and .blender/scripts/ are scanned
* for registration info.
* - this data is also saved to a Bpymenus file at the user's .blender/ dir and
* only re-created when the scripts folder gets modified.
* - on start-up Blender uses this info to fill a table, which is used to
* create the menu entries when they are needed (see header_info.c or
* header_script.c, under source/blender/src/, for examples).
*/
/* These two structs hold py menu/submenu info.
* BPyMenu holds a script's name (as should appear in the menu) and filename,
* plus an optional list of submenus. Each submenu is related to a string
* (arg) that the script can get from the __script__ pydict, to know which
* submenu was chosen. */
typedef struct BPySubMenu {
char *name;
char *arg;
struct BPySubMenu *next;
} BPySubMenu;
typedef struct BPyMenu {
char *name;
char *filename;
char *tooltip;
short version; /* Blender version */
int dir; /* 0: default, 1: U.pythondir */
struct BPySubMenu *submenus;
struct BPyMenu *next;
} BPyMenu;
/* Scripts can be added to only a few pre-defined places in menus, like
* File->Import, File->Export, etc. (for speed and better control).
* To make a new menu 'slot' available for scripts:
* - add an entry to the enum below, before PYMENU_TOTAL, of course;
* - update the bpymenu_group_atoi() and BPyMenu_group_itoa() functions in
* BPY_menus.c;
* - add the necessary code to the header_***.c file in
* source/blender/src/, like done in header_info.c for import/export;
*/
typedef enum {
PYMENU_ADD,/* creates new objects */
PYMENU_ANIMATION,
PYMENU_EXPORT,
PYMENU_IMPORT,
PYMENU_MATERIALS,
PYMENU_MESH,
PYMENU_MISC,
PYMENU_OBJECT,
PYMENU_RENDER,/* exporters to external renderers */
PYMENU_SYSTEM,
PYMENU_THEMES,
PYMENU_UV,/* UV editing tools, to go in UV/Image editor space, 'UV' menu */
PYMENU_IMAGE,/* Image editing tools, to go in UV/Image editor space, 'Image' menu */
PYMENU_WIZARDS,/* complex 'app' scripts */
/* entries put after Wizards don't appear at the Scripts win->Scripts menu;
* see define right below */
PYMENU_FACESELECT,
PYMENU_WEIGHTPAINT,
PYMENU_VERTEXPAINT,
PYMENU_UVCALCULATION,
PYMENU_ARMATURE,
PYMENU_SCRIPTTEMPLATE,
PYMENU_HELP,/*Main Help menu items - prob best to leave for 'official' ones*/
PYMENU_HELPSYSTEM,/* Resources, troubleshooting, system tools */
PYMENU_HELPWEBSITES,/* Help -> Websites submenu */
PYMENU_MESHFACEKEY, /* face key in mesh editmode */
PYMENU_ADDMESH, /* adds mesh */
PYMENU_TOTAL
} PYMENUHOOKS;
#define PYMENU_SCRIPTS_MENU_TOTAL (PYMENU_WIZARDS + 1)
/* BPyMenuTable holds all registered pymenus, as linked lists for each menu
* where they can appear (see PYMENUHOOKS enum above).
*/
extern BPyMenu *BPyMenuTable[]; /* defined in BPY_menus.c */
/* public functions: */
int BPyMenu_Init( int usedir );
void BPyMenu_RemoveAllEntries( void );
void BPyMenu_PrintAllEntries( void );
char *BPyMenu_CreatePupmenuStr( BPyMenu * pym, short group );
char *BPyMenu_group_itoa( short group );
struct BPyMenu *BPyMenu_GetEntry( short group, short pos );
#endif /* BPY_MENUS_H */

@ -0,0 +1,255 @@
/**
* $Id$
*
* ***** BEGIN GPL LICENSE BLOCK *****
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
* Contributor(s): Campbell Barton
*
* ***** END GPL LICENSE BLOCK *****
*/
#include "bpy_ui.h"
#include "bpy_compat.h"
#include "BLI_dynstr.h"
#include "MEM_guardedalloc.h"
#include "BKE_global.h" /* evil G.* */
#include "BKE_context.h"
#include "DNA_screen_types.h"
#include "UI_interface.h"
#include "WM_api.h"
static PyObject *Method_pupMenuBegin( PyObject * self, PyObject * args )
{
char *title; int icon;
if( !PyArg_ParseTuple( args, "si:pupMenuBegin", &title, &icon))
return NULL;
return PyCObject_FromVoidPtr( uiPupMenuBegin(title, icon), NULL );
}
static PyObject *Method_pupMenuEnd( PyObject * self, PyObject * args )
{
PyObject *py_context, *py_head;
if( !PyArg_ParseTuple( args, "O!O!:pupMenuEnd", &PyCObject_Type, &py_context, &PyCObject_Type, &py_head))
return NULL;
uiPupMenuEnd(PyCObject_AsVoidPtr(py_context), PyCObject_AsVoidPtr(py_head));
Py_RETURN_NONE;
}
static PyObject *Method_menuItemO( PyObject * self, PyObject * args )
{
PyObject *py_head;
char *opname;
int icon;
if( !PyArg_ParseTuple( args, "O!is:menuItemO", &PyCObject_Type, &py_head, &icon, &opname))
return NULL;
uiMenuItemO(PyCObject_AsVoidPtr(py_head), icon, opname);
Py_RETURN_NONE;
}
static PyObject *Method_defButO( PyObject * self, PyObject * args )
{
PyObject *py_block;
char *opname, *butname, *tip;
int exec, xco, yco, width, height;
if( !PyArg_ParseTuple( args, "O!sisiiiis:defButO", &PyCObject_Type, &py_block, &opname, &exec, &butname, &xco, &yco, &width, &height, &tip))
return NULL;
return PyCObject_FromVoidPtr(uiDefButO(PyCObject_AsVoidPtr(py_block), BUT, opname, exec, butname, xco, yco, width, height, tip), NULL );
}
static uiBlock *py_internal_uiBlockCreateFunc(struct bContext *C, struct ARegion *ar, void *arg1)
{
PyObject *ret, *args;
args = Py_BuildValue("(NN)", PyCObject_FromVoidPtr(C, NULL), PyCObject_FromVoidPtr(ar, NULL));
ret = PyObject_CallObject( (PyObject *)arg1, args );
Py_DECREF(args);
if (ret==NULL) {
PyErr_Print();
return NULL;
}
if (!PyCObject_Check(ret)) {
printf("invalid return value, not a PyCObject block\n");
return NULL;
}
return (uiBlock *)PyCObject_AsVoidPtr(ret);
}
static PyObject *Method_pupBlock( PyObject * self, PyObject * args )
{
PyObject *py_context, *py_func;
if( !PyArg_ParseTuple( args, "O!O:pupBlock", &PyCObject_Type, &py_context, &py_func) )
return NULL;
if (!PyCallable_Check(py_func)) {
PyErr_SetString(PyExc_ValueError, "arg not callable");
return NULL;
}
uiPupBlock(PyCObject_AsVoidPtr(py_context), py_internal_uiBlockCreateFunc, (void *)py_func);
Py_RETURN_NONE;
}
static PyObject *Method_beginBlock( PyObject * self, PyObject * args ) // XXX missing 2 args - UI_EMBOSS, UI_HELV, do we care?
{
PyObject *py_context, *py_ar;
char *name;
if( !PyArg_ParseTuple( args, "O!O!s:beginBlock", &PyCObject_Type, &py_context, &PyCObject_Type, &py_ar, &name) )
return NULL;
return PyCObject_FromVoidPtr(uiBeginBlock(PyCObject_AsVoidPtr(py_context), PyCObject_AsVoidPtr(py_ar), name, UI_EMBOSS, UI_HELV), NULL);
}
static PyObject *Method_endBlock( PyObject * self, PyObject * args )
{
PyObject *py_context, *py_block;
if( !PyArg_ParseTuple( args, "O!O!:endBlock", &PyCObject_Type, &py_context, &PyCObject_Type, &py_block) )
return NULL;
uiEndBlock(PyCObject_AsVoidPtr(py_context), PyCObject_AsVoidPtr(py_block));
Py_RETURN_NONE;
}
static PyObject *Method_popupBoundsBlock( PyObject * self, PyObject * args )
{
PyObject *py_block;
int addval, mx, my;
if( !PyArg_ParseTuple( args, "O!iii:popupBoundsBlock", &PyCObject_Type, &py_block, &addval, &mx, &my) )
return NULL;
uiPopupBoundsBlock(PyCObject_AsVoidPtr(py_block), addval, mx, my);
Py_RETURN_NONE;
}
static PyObject *Method_blockBeginAlign( PyObject * self, PyObject * args )
{
PyObject *py_block;
if( !PyArg_ParseTuple( args, "O!:blockBeginAlign", &PyCObject_Type, &py_block) )
return NULL;
uiBlockBeginAlign(PyCObject_AsVoidPtr(py_block));
Py_RETURN_NONE;
}
static PyObject *Method_blockEndAlign( PyObject * self, PyObject * args )
{
PyObject *py_block;
if( !PyArg_ParseTuple( args, "O!:blockEndAlign", &PyCObject_Type, &py_block))
return NULL;
uiBlockEndAlign(PyCObject_AsVoidPtr(py_block));
Py_RETURN_NONE;
}
static PyObject *Method_newPanel( PyObject * self, PyObject * args )
{
PyObject *py_context, *py_area, *py_block;
char *panelname, *tabname;
int ofsx, ofsy, sizex, sizey;
if( !PyArg_ParseTuple( args, "O!O!O!ssiiii:newPanel", &PyCObject_Type, &py_context, &PyCObject_Type, &py_area, &PyCObject_Type, &py_block, &panelname, &tabname, &ofsx, &ofsy, &sizex, &sizey))
return NULL;
return PyLong_FromSize_t(uiNewPanel(PyCObject_AsVoidPtr(py_context), PyCObject_AsVoidPtr(py_area), PyCObject_AsVoidPtr(py_block), panelname, tabname, ofsx, ofsy, sizex, sizey));
}
/* internal use only */
static bContext *get_py_context__internal(void)
{
PyObject *globals = PyEval_GetGlobals();
PyObject *val= PyDict_GetItemString(globals, "__bpy_context__");
return PyCObject_AsVoidPtr(val);
}
static PyObject *Method_getRegonPtr( PyObject * self )
{
bContext *C= get_py_context__internal();
ARegion *ar = CTX_wm_region(C);
return PyCObject_FromVoidPtr(ar, NULL);
}
static PyObject *Method_getAreaPtr( PyObject * self )
{
bContext *C= get_py_context__internal();
ScrArea *area = CTX_wm_area(C);
return PyCObject_FromVoidPtr(area, NULL);
}
static PyObject *Method_getScreenPtr( PyObject * self )
{
bContext *C= get_py_context__internal();
bScreen *screen= CTX_wm_screen(C);
return PyCObject_FromVoidPtr(screen, NULL);
}
static PyObject *Method_getWindowPtr( PyObject * self )
{
bContext *C= get_py_context__internal();
wmWindow *window= CTX_wm_window(C);
return PyCObject_FromVoidPtr(window, NULL);
}
static struct PyMethodDef ui_methods[] = {
{"pupMenuBegin", (PyCFunction)Method_pupMenuBegin, METH_VARARGS, ""},
{"pupMenuEnd", (PyCFunction)Method_pupMenuEnd, METH_VARARGS, ""},
{"menuItemO", (PyCFunction)Method_menuItemO, METH_VARARGS, ""},
{"defButO", (PyCFunction)Method_defButO, METH_VARARGS, ""},
{"pupBlock", (PyCFunction)Method_pupBlock, METH_VARARGS, ""},
{"beginBlock", (PyCFunction)Method_beginBlock, METH_VARARGS, ""},
{"endBlock", (PyCFunction)Method_endBlock, METH_VARARGS, ""},
{"popupBoundsBlock", (PyCFunction)Method_popupBoundsBlock, METH_VARARGS, ""},
{"blockBeginAlign", (PyCFunction)Method_blockBeginAlign, METH_VARARGS, ""},
{"blockEndAlign", (PyCFunction)Method_blockEndAlign, METH_VARARGS, ""},
{"newPanel", (PyCFunction)Method_newPanel, METH_VARARGS, ""},
{"getRegonPtr", (PyCFunction)Method_getRegonPtr, METH_NOARGS, ""}, // XXX Nasty, we really need to improve dealing with context!
{"getAreaPtr", (PyCFunction)Method_getAreaPtr, METH_NOARGS, ""},
{"getScreenPtr", (PyCFunction)Method_getScreenPtr, METH_NOARGS, ""},
{"getWindowPtr", (PyCFunction)Method_getWindowPtr, METH_NOARGS, ""},
{NULL, NULL, 0, NULL}
};
PyObject *BPY_ui_module( void )
{
PyObject *submodule;
submodule = Py_InitModule3( "bpyui", ui_methods, "" );
return submodule;
}

@ -0,0 +1,31 @@
/**
* $Id$
*
* ***** BEGIN GPL LICENSE BLOCK *****
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
* Contributor(s): Campbell Barton
*
* ***** END GPL LICENSE BLOCK *****
*/
#ifndef BPY_UI_H__
#define BPY_UI_H__
#include <Python.h>
PyObject *BPY_ui_module( void );
#endif