forked from bartvdbraak/blender
svn merge -r39951:39986 https://svn.blender.org/svnroot/bf-blender/trunk/blender
This commit is contained in:
commit
a167ee1262
@ -797,7 +797,7 @@ elseif(WIN32)
|
||||
else()
|
||||
# keep GCC spesific stuff here
|
||||
if(CMAKE_COMPILER_IS_GNUCC)
|
||||
set(PLATFORM_LINKLIBS "-lshell32 -lshfolder -lgdi32 -lmsvcrt -lwinmm -lmingw32 -lm -lws2_32 -lz -lstdc++ -lole32 -luuid")
|
||||
set(PLATFORM_LINKLIBS "-lshell32 -lshfolder -lgdi32 -lmsvcrt -lwinmm -lmingw32 -lm -lws2_32 -lz -lstdc++ -lole32 -luuid -lwsock32")
|
||||
set(PLATFORM_CFLAGS "-pipe -funsigned-char -fno-strict-aliasing")
|
||||
|
||||
add_definitions(-D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 -D_LARGEFILE64_SOURCE)
|
||||
|
@ -392,6 +392,7 @@ macro(remove_strict_flags)
|
||||
remove_flag("-Wstrict-prototypes")
|
||||
remove_flag("-Wunused-parameter")
|
||||
remove_flag("-Wwrite-strings")
|
||||
remove_flag("-Wundef")
|
||||
remove_flag("-Wshadow")
|
||||
remove_flag("-Werror=[^ ]+")
|
||||
remove_flag("-Werror")
|
||||
|
@ -174,7 +174,7 @@ C_WARN = ['-Wno-char-subscripts', '-Wdeclaration-after-statement', '-Wstrict-pro
|
||||
|
||||
CC_WARN = [ '-Wall' ]
|
||||
|
||||
LLIBS = ['-lshell32', '-lshfolder', '-lgdi32', '-lmsvcrt', '-lwinmm', '-lmingw32', '-lm', '-lws2_32', '-lz', '-lstdc++','-lole32','-luuid']
|
||||
LLIBS = ['-lshell32', '-lshfolder', '-lgdi32', '-lmsvcrt', '-lwinmm', '-lmingw32', '-lm', '-lws2_32', '-lz', '-lstdc++','-lole32','-luuid', '-lwsock32']
|
||||
|
||||
PLATFORM_LINKFLAGS = ['--stack,2097152']
|
||||
|
||||
|
@ -98,7 +98,8 @@ typedef unsigned long uintptr_t;
|
||||
#include <inttypes.h>
|
||||
|
||||
#elif defined(FREE_WINDOWS)
|
||||
|
||||
/* define htoln here, there must be a syntax error in winsock2.h in MinGW */
|
||||
unsigned long __attribute__((__stdcall__)) htonl(unsigned long);
|
||||
#include <stdint.h>
|
||||
|
||||
#else
|
||||
@ -109,12 +110,14 @@ typedef unsigned long uintptr_t;
|
||||
#endif /* ifdef platform for types */
|
||||
|
||||
#ifdef _WIN32
|
||||
#ifndef FREE_WINDOWS
|
||||
#ifndef htonl
|
||||
#define htonl(x) correctByteOrder(x)
|
||||
#endif
|
||||
#ifndef ntohl
|
||||
#define ntohl(x) correctByteOrder(x)
|
||||
#endif
|
||||
#endif
|
||||
#elif defined (__FreeBSD__) || defined (__OpenBSD__)
|
||||
#include <sys/param.h>
|
||||
#elif defined (__APPLE__)
|
||||
|
@ -54,6 +54,9 @@ def draw_gpencil_tools(context, layout):
|
||||
row = col.row()
|
||||
row.operator("gpencil.draw", text="Draw").mode = 'DRAW'
|
||||
row.operator("gpencil.draw", text="Line").mode = 'DRAW_STRAIGHT'
|
||||
|
||||
row = col.row()
|
||||
row.operator("gpencil.draw", text="Poly").mode = 'DRAW_POLY'
|
||||
row.operator("gpencil.draw", text="Erase").mode = 'ERASER'
|
||||
|
||||
row = col.row()
|
||||
|
@ -111,7 +111,7 @@ typedef struct Global {
|
||||
#define G_SCRIPT_OVERRIDE_PREF (1 << 14) /* when this flag is set ignore the userprefs */
|
||||
|
||||
/* #define G_NOFROZEN (1 << 17) also removed */
|
||||
#define G_GREASEPENCIL (1 << 17)
|
||||
/* #define G_GREASEPENCIL (1 << 17) also removed */
|
||||
|
||||
/* #define G_AUTOMATKEYS (1 << 30) also removed */
|
||||
|
||||
|
@ -466,8 +466,8 @@ struct ShadeResult;
|
||||
|
||||
/* API */
|
||||
|
||||
struct bNodeTreeExec *ntreeShaderBeginExecTree(struct bNodeTree *ntree);
|
||||
void ntreeShaderEndExecTree(struct bNodeTreeExec *exec);
|
||||
struct bNodeTreeExec *ntreeShaderBeginExecTree(struct bNodeTree *ntree, int use_tree_data);
|
||||
void ntreeShaderEndExecTree(struct bNodeTreeExec *exec, int use_tree_data);
|
||||
void ntreeShaderExecTree(struct bNodeTree *ntree, struct ShadeInput *shi, struct ShadeResult *shr);
|
||||
void ntreeShaderGetTexcoMode(struct bNodeTree *ntree, int osa, short *texco, int *mode);
|
||||
void nodeShaderSynchronizeID(struct bNode *node, int copyto);
|
||||
@ -594,8 +594,8 @@ void ntreeGPUMaterialNodes(struct bNodeTree *ntree, struct GPUMaterial *mat);
|
||||
|
||||
/* API */
|
||||
struct CompBuf;
|
||||
struct bNodeTreeExec *ntreeCompositBeginExecTree(struct bNodeTree *ntree);
|
||||
void ntreeCompositEndExecTree(struct bNodeTreeExec *exec);
|
||||
struct bNodeTreeExec *ntreeCompositBeginExecTree(struct bNodeTree *ntree, int use_tree_data);
|
||||
void ntreeCompositEndExecTree(struct bNodeTreeExec *exec, int use_tree_data);
|
||||
void ntreeCompositExecTree(struct bNodeTree *ntree, struct RenderData *rd, int do_previews);
|
||||
void ntreeCompositTagRender(struct Scene *sce);
|
||||
int ntreeCompositTagAnimated(struct bNodeTree *ntree);
|
||||
@ -642,8 +642,8 @@ void ntreeTexSetPreviewFlag(int);
|
||||
void ntreeTexCheckCyclics(struct bNodeTree *ntree);
|
||||
char* ntreeTexOutputMenu(struct bNodeTree *ntree);
|
||||
|
||||
struct bNodeTreeExec *ntreeTexBeginExecTree(struct bNodeTree *ntree);
|
||||
void ntreeTexEndExecTree(struct bNodeTreeExec *exec);
|
||||
struct bNodeTreeExec *ntreeTexBeginExecTree(struct bNodeTree *ntree, int use_tree_data);
|
||||
void ntreeTexEndExecTree(struct bNodeTreeExec *exec, int use_tree_data);
|
||||
int ntreeTexExecTree(struct bNodeTree *ntree, struct TexResult *target, float *coord, float *dxt, float *dyt, int osatex, short thread, struct Tex *tex, short which_output, int cfra, int preview, struct ShadeInput *shi, struct MTex *mtex);
|
||||
|
||||
|
||||
|
@ -324,17 +324,14 @@ static void setup_app_data(bContext *C, BlendFileData *bfd, const char *filepath
|
||||
MEM_freeN(bfd);
|
||||
}
|
||||
|
||||
static int handle_subversion_warning(Main *main)
|
||||
static int handle_subversion_warning(Main *main, ReportList *reports)
|
||||
{
|
||||
if(main->minversionfile > BLENDER_VERSION ||
|
||||
(main->minversionfile == BLENDER_VERSION &&
|
||||
main->minsubversionfile > BLENDER_SUBVERSION)) {
|
||||
|
||||
char str[128];
|
||||
|
||||
BLI_snprintf(str, sizeof(str), "File written by newer Blender binary: %d.%d , expect loss of data!", main->minversionfile, main->minsubversionfile);
|
||||
// XXX error(str);
|
||||
BKE_reportf(reports, RPT_ERROR, "File written by newer Blender binary: %d.%d , expect loss of data!", main->minversionfile, main->minsubversionfile);
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -392,7 +389,7 @@ int BKE_read_file(bContext *C, const char *filepath, ReportList *reports)
|
||||
if (bfd) {
|
||||
if(bfd->user) retval= BKE_READ_FILE_OK_USERPREFS;
|
||||
|
||||
if(0==handle_subversion_warning(bfd->main)) {
|
||||
if(0==handle_subversion_warning(bfd->main, reports)) {
|
||||
free_main(bfd->main);
|
||||
MEM_freeN(bfd);
|
||||
bfd= NULL;
|
||||
|
@ -926,7 +926,7 @@ void init_render_material(Material *mat, int r_mode, float *amb)
|
||||
init_render_nodetree(mat->nodetree, mat, r_mode, amb);
|
||||
|
||||
if (!mat->nodetree->execdata)
|
||||
mat->nodetree->execdata = ntreeShaderBeginExecTree(mat->nodetree);
|
||||
mat->nodetree->execdata = ntreeShaderBeginExecTree(mat->nodetree, 1);
|
||||
}
|
||||
}
|
||||
|
||||
@ -960,7 +960,7 @@ void end_render_material(Material *mat)
|
||||
{
|
||||
if(mat && mat->nodetree && mat->use_nodes) {
|
||||
if (mat->nodetree->execdata)
|
||||
ntreeShaderEndExecTree(mat->nodetree->execdata);
|
||||
ntreeShaderEndExecTree(mat->nodetree->execdata, 1);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -897,13 +897,13 @@ void ntreeFreeTree(bNodeTree *ntree)
|
||||
if (ntree->execdata) {
|
||||
switch (ntree->type) {
|
||||
case NTREE_COMPOSIT:
|
||||
ntreeCompositEndExecTree(ntree->execdata);
|
||||
ntreeCompositEndExecTree(ntree->execdata, 1);
|
||||
break;
|
||||
case NTREE_SHADER:
|
||||
ntreeShaderEndExecTree(ntree->execdata);
|
||||
ntreeShaderEndExecTree(ntree->execdata, 1);
|
||||
break;
|
||||
case NTREE_TEXTURE:
|
||||
ntreeTexEndExecTree(ntree->execdata);
|
||||
ntreeTexEndExecTree(ntree->execdata, 1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -1524,21 +1524,25 @@ void NodeTagChanged(bNodeTree *ntree, bNode *node)
|
||||
{
|
||||
bNodeTreeType *ntreetype = ntreeGetType(ntree->type);
|
||||
|
||||
if (ntreetype->update_node)
|
||||
/* extra null pointer checks here because this is called when unlinking
|
||||
unknown nodes on file load, so typeinfo pointers may not be set */
|
||||
if (ntreetype && ntreetype->update_node)
|
||||
ntreetype->update_node(ntree, node);
|
||||
else if (node->typeinfo->updatefunc)
|
||||
else if (node->typeinfo && node->typeinfo->updatefunc)
|
||||
node->typeinfo->updatefunc(ntree, node);
|
||||
}
|
||||
|
||||
int NodeTagIDChanged(bNodeTree *ntree, ID *id)
|
||||
{
|
||||
bNodeTreeType *ntreetype = ntreeGetType(ntree->type);
|
||||
bNodeTreeType *ntreetype;
|
||||
bNode *node;
|
||||
int change = FALSE;
|
||||
|
||||
if(ELEM(NULL, id, ntree))
|
||||
return change;
|
||||
|
||||
ntreetype = ntreeGetType(ntree->type);
|
||||
|
||||
if (ntreetype->update_node) {
|
||||
for(node= ntree->nodes.first; node; node= node->next) {
|
||||
if(node->id==id) {
|
||||
|
@ -767,7 +767,7 @@ Tex *copy_texture(Tex *tex)
|
||||
|
||||
if(tex->nodetree) {
|
||||
if (tex->nodetree->execdata) {
|
||||
ntreeTexEndExecTree(tex->nodetree->execdata);
|
||||
ntreeTexEndExecTree(tex->nodetree->execdata, 1);
|
||||
}
|
||||
texn->nodetree= ntreeCopyTree(tex->nodetree);
|
||||
}
|
||||
|
@ -129,7 +129,7 @@ size_t BLI_strescape(char *dst, const char *src, const size_t maxlen)
|
||||
while(len < maxlen) {
|
||||
switch(*src) {
|
||||
case '\0':
|
||||
break;
|
||||
goto escape_finish;
|
||||
case '\\':
|
||||
case '"':
|
||||
|
||||
@ -154,6 +154,8 @@ size_t BLI_strescape(char *dst, const char *src, const size_t maxlen)
|
||||
len++;
|
||||
}
|
||||
|
||||
escape_finish:
|
||||
|
||||
*dst= '\0';
|
||||
|
||||
return len;
|
||||
|
@ -93,7 +93,8 @@ typedef unsigned long uintptr_t;
|
||||
#include <inttypes.h>
|
||||
|
||||
#elif defined(FREE_WINDOWS)
|
||||
|
||||
/* define htoln here, there must be a syntax error in winsock2.h in MinGW */
|
||||
unsigned long __attribute__((__stdcall__)) htonl(unsigned long);
|
||||
#include <stdint.h>
|
||||
|
||||
#else
|
||||
@ -105,8 +106,14 @@ typedef unsigned long uintptr_t;
|
||||
|
||||
|
||||
#ifdef _WIN32
|
||||
#ifndef FREE_WINDOWS
|
||||
#ifndef htonl
|
||||
#define htonl(x) correctByteOrder(x)
|
||||
#endif
|
||||
#ifndef ntohl
|
||||
#define ntohl(x) correctByteOrder(x)
|
||||
#endif
|
||||
#endif
|
||||
#elif defined (__FreeBSD__) || defined (__OpenBSD__)
|
||||
#include <sys/param.h>
|
||||
#elif defined (__APPLE__)
|
||||
|
@ -2219,8 +2219,9 @@ static void direct_link_nodetree(FileData *fd, bNodeTree *ntree)
|
||||
if(node->type == NODE_DYNAMIC) {
|
||||
node->custom1= 0;
|
||||
node->custom1= BSET(node->custom1, NODE_DYNAMIC_LOADED);
|
||||
node->typeinfo= NULL;
|
||||
}
|
||||
|
||||
node->typeinfo= NULL;
|
||||
|
||||
link_list(fd, &node->inputs);
|
||||
link_list(fd, &node->outputs);
|
||||
@ -7081,6 +7082,15 @@ static void do_versions_nodetree_default_value(bNodeTree *ntree)
|
||||
do_versions_socket_default_value(sock);
|
||||
}
|
||||
|
||||
static void do_versions_nodetree_dynamic_sockets(bNodeTree *ntree)
|
||||
{
|
||||
bNodeSocket *sock;
|
||||
for (sock=ntree->inputs.first; sock; sock=sock->next)
|
||||
sock->flag |= SOCK_DYNAMIC;
|
||||
for (sock=ntree->outputs.first; sock; sock=sock->next)
|
||||
sock->flag |= SOCK_DYNAMIC;
|
||||
}
|
||||
|
||||
static void do_versions(FileData *fd, Library *lib, Main *main)
|
||||
{
|
||||
/* WATCH IT!!!: pointers from libdata have not been converted */
|
||||
@ -12038,6 +12048,27 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
|
||||
tex->nodetree->update |= NTREE_UPDATE;
|
||||
}
|
||||
}
|
||||
|
||||
/* add SOCK_DYNAMIC flag to existing group sockets */
|
||||
{
|
||||
bNodeTree *ntree;
|
||||
/* only need to do this for trees in main, local trees are not used as groups */
|
||||
for (ntree=main->nodetree.first; ntree; ntree=ntree->id.next) {
|
||||
do_versions_nodetree_dynamic_sockets(ntree);
|
||||
ntree->update |= NTREE_UPDATE;
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
/* Initialize group tree nodetypes.
|
||||
* These are used to distinguish tree types and
|
||||
* associate them with specific node types for polling.
|
||||
*/
|
||||
bNodeTree *ntree;
|
||||
/* all node trees in main->nodetree are considered groups */
|
||||
for (ntree=main->nodetree.first; ntree; ntree=ntree->id.next)
|
||||
ntree->nodetype = NODE_GROUP;
|
||||
}
|
||||
}
|
||||
|
||||
/* put compatibility code here until next subversion bump */
|
||||
|
@ -135,6 +135,7 @@ Any case: direct data is ALWAYS after the lib block
|
||||
#include "BLI_blenlib.h"
|
||||
#include "BLI_linklist.h"
|
||||
#include "BLI_bpath.h"
|
||||
#include "BLI_math.h"
|
||||
#include "BLI_utildefines.h"
|
||||
|
||||
#include "BKE_action.h"
|
||||
@ -645,6 +646,38 @@ static void write_curvemapping(WriteData *wd, CurveMapping *cumap)
|
||||
static void write_node_socket(WriteData *wd, bNodeSocket *sock)
|
||||
{
|
||||
bNodeSocketType *stype= ntreeGetSocketType(sock->type);
|
||||
|
||||
/* forward compatibility code, so older blenders still open */
|
||||
sock->stack_type = 1;
|
||||
|
||||
if(sock->default_value) {
|
||||
bNodeSocketValueFloat *valfloat;
|
||||
bNodeSocketValueVector *valvector;
|
||||
bNodeSocketValueRGBA *valrgba;
|
||||
|
||||
switch (sock->type) {
|
||||
case SOCK_FLOAT:
|
||||
valfloat = sock->default_value;
|
||||
sock->ns.vec[0] = valfloat->value;
|
||||
sock->ns.min = valfloat->min;
|
||||
sock->ns.max = valfloat->max;
|
||||
break;
|
||||
case SOCK_VECTOR:
|
||||
valvector = sock->default_value;
|
||||
copy_v3_v3(sock->ns.vec, valvector->value);
|
||||
sock->ns.min = valvector->min;
|
||||
sock->ns.max = valvector->max;
|
||||
break;
|
||||
case SOCK_RGBA:
|
||||
valrgba = sock->default_value;
|
||||
copy_v4_v4(sock->ns.vec, valrgba->value);
|
||||
sock->ns.min = 0.0f;
|
||||
sock->ns.max = 1.0f;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* actual socket writing */
|
||||
writestruct(wd, DATA, "bNodeSocket", 1, sock);
|
||||
if (sock->default_value)
|
||||
writestruct(wd, DATA, stype->value_structname, 1, sock->default_value);
|
||||
|
@ -61,6 +61,7 @@ set(SRC
|
||||
MaterialExporter.cpp
|
||||
MeshImporter.cpp
|
||||
SkinInfo.cpp
|
||||
SceneExporter.cpp
|
||||
TransformReader.cpp
|
||||
TransformWriter.cpp
|
||||
collada.cpp
|
||||
@ -85,6 +86,7 @@ set(SRC
|
||||
MaterialExporter.h
|
||||
MeshImporter.h
|
||||
SkinInfo.h
|
||||
SceneExporter.h
|
||||
TransformReader.h
|
||||
TransformWriter.h
|
||||
collada.h
|
||||
|
@ -34,6 +34,7 @@ extern "C"
|
||||
{
|
||||
#include "DNA_scene_types.h"
|
||||
#include "DNA_object_types.h"
|
||||
#include "DNA_group_types.h"
|
||||
#include "DNA_meshdata_types.h"
|
||||
#include "DNA_mesh_types.h"
|
||||
#include "DNA_image_types.h"
|
||||
@ -104,6 +105,7 @@ extern char build_rev[];
|
||||
#include "COLLADASWConstants.h"
|
||||
#include "COLLADASWLibraryControllers.h"
|
||||
#include "COLLADASWInstanceController.h"
|
||||
#include "COLLADASWInstanceNode.h"
|
||||
#include "COLLADASWBaseInputElement.h"
|
||||
|
||||
#include "collada_internal.h"
|
||||
@ -113,6 +115,7 @@ extern char build_rev[];
|
||||
#include "InstanceWriter.h"
|
||||
#include "TransformWriter.h"
|
||||
|
||||
#include "SceneExporter.h"
|
||||
#include "ArmatureExporter.h"
|
||||
#include "AnimationExporter.h"
|
||||
#include "CameraExporter.h"
|
||||
@ -142,165 +145,6 @@ char *bc_CustomData_get_active_layer_name(const CustomData *data, int type)
|
||||
return data->layers[layer_index].name;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Utilities to avoid code duplication.
|
||||
Definition can take some time to understand, but they should be useful.
|
||||
*/
|
||||
|
||||
|
||||
template<class Functor>
|
||||
void forEachObjectInScene(Scene *sce, Functor &f)
|
||||
{
|
||||
Base *base= (Base*) sce->base.first;
|
||||
while(base) {
|
||||
Object *ob = base->object;
|
||||
|
||||
f(ob);
|
||||
|
||||
base= base->next;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
class SceneExporter: COLLADASW::LibraryVisualScenes, protected TransformWriter, protected InstanceWriter
|
||||
{
|
||||
ArmatureExporter *arm_exporter;
|
||||
public:
|
||||
SceneExporter(COLLADASW::StreamWriter *sw, ArmatureExporter *arm) : COLLADASW::LibraryVisualScenes(sw),
|
||||
arm_exporter(arm) {}
|
||||
|
||||
void exportScene(Scene *sce, bool export_selected) {
|
||||
// <library_visual_scenes> <visual_scene>
|
||||
std::string id_naming = id_name(sce);
|
||||
openVisualScene(translate_id(id_naming), id_naming);
|
||||
|
||||
// write <node>s
|
||||
//forEachMeshObjectInScene(sce, *this);
|
||||
//forEachCameraObjectInScene(sce, *this);
|
||||
//forEachLampObjectInScene(sce, *this);
|
||||
exportHierarchy(sce, export_selected);
|
||||
|
||||
// </visual_scene> </library_visual_scenes>
|
||||
closeVisualScene();
|
||||
|
||||
closeLibrary();
|
||||
}
|
||||
|
||||
void exportHierarchy(Scene *sce, bool export_selected)
|
||||
{
|
||||
Base *base= (Base*) sce->base.first;
|
||||
while(base) {
|
||||
Object *ob = base->object;
|
||||
|
||||
if (!ob->parent) {
|
||||
if(sce->lay & ob->lay) {
|
||||
switch(ob->type) {
|
||||
case OB_MESH:
|
||||
case OB_CAMERA:
|
||||
case OB_LAMP:
|
||||
case OB_ARMATURE:
|
||||
case OB_EMPTY:
|
||||
if (export_selected && !(ob->flag & SELECT)) {
|
||||
break;
|
||||
}
|
||||
// write nodes....
|
||||
writeNodes(ob, sce);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
base= base->next;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// called for each object
|
||||
//void operator()(Object *ob) {
|
||||
void writeNodes(Object *ob, Scene *sce)
|
||||
{
|
||||
COLLADASW::Node node(mSW);
|
||||
node.setNodeId(translate_id(id_name(ob)));
|
||||
node.setType(COLLADASW::Node::NODE);
|
||||
|
||||
node.start();
|
||||
|
||||
bool is_skinned_mesh = arm_exporter->is_skinned_mesh(ob);
|
||||
|
||||
if (ob->type == OB_MESH && is_skinned_mesh)
|
||||
// for skinned mesh we write obmat in <bind_shape_matrix>
|
||||
TransformWriter::add_node_transform_identity(node);
|
||||
else
|
||||
TransformWriter::add_node_transform_ob(node, ob);
|
||||
|
||||
// <instance_geometry>
|
||||
if (ob->type == OB_MESH) {
|
||||
if (is_skinned_mesh) {
|
||||
arm_exporter->add_instance_controller(ob);
|
||||
}
|
||||
else {
|
||||
COLLADASW::InstanceGeometry instGeom(mSW);
|
||||
instGeom.setUrl(COLLADASW::URI(COLLADABU::Utils::EMPTY_STRING, get_geometry_id(ob)));
|
||||
|
||||
InstanceWriter::add_material_bindings(instGeom.getBindMaterial(), ob);
|
||||
|
||||
instGeom.add();
|
||||
}
|
||||
}
|
||||
|
||||
// <instance_controller>
|
||||
else if (ob->type == OB_ARMATURE) {
|
||||
arm_exporter->add_armature_bones(ob, sce);
|
||||
|
||||
// XXX this looks unstable...
|
||||
node.end();
|
||||
}
|
||||
|
||||
// <instance_camera>
|
||||
else if (ob->type == OB_CAMERA) {
|
||||
COLLADASW::InstanceCamera instCam(mSW, COLLADASW::URI(COLLADABU::Utils::EMPTY_STRING, get_camera_id(ob)));
|
||||
instCam.add();
|
||||
}
|
||||
|
||||
// <instance_light>
|
||||
else if (ob->type == OB_LAMP) {
|
||||
COLLADASW::InstanceLight instLa(mSW, COLLADASW::URI(COLLADABU::Utils::EMPTY_STRING, get_light_id(ob)));
|
||||
instLa.add();
|
||||
}
|
||||
|
||||
// empty object
|
||||
else if (ob->type == OB_EMPTY) {
|
||||
}
|
||||
|
||||
// write nodes for child objects
|
||||
Base *b = (Base*) sce->base.first;
|
||||
while(b) {
|
||||
// cob - child object
|
||||
Object *cob = b->object;
|
||||
|
||||
if (cob->parent == ob) {
|
||||
switch(cob->type) {
|
||||
case OB_MESH:
|
||||
case OB_CAMERA:
|
||||
case OB_LAMP:
|
||||
case OB_EMPTY:
|
||||
case OB_ARMATURE:
|
||||
// write node...
|
||||
writeNodes(cob, sce);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
b = b->next;
|
||||
}
|
||||
|
||||
if (ob->type != OB_ARMATURE)
|
||||
node.end();
|
||||
}
|
||||
};
|
||||
|
||||
// TODO: it would be better to instantiate animations rather than create a new one per object
|
||||
// COLLADA allows this through multiple <channel>s in <animation>.
|
||||
// For this to work, we need to know objects that use a certain action.
|
||||
|
161
source/blender/collada/SceneExporter.cpp
Normal file
161
source/blender/collada/SceneExporter.cpp
Normal file
@ -0,0 +1,161 @@
|
||||
/*
|
||||
* $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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* Contributor(s): Chingiz Dyussenov, Arystanbek Dyussenov, Jan Diederich, Tod Liverseed.
|
||||
*
|
||||
* ***** END GPL LICENSE BLOCK *****
|
||||
*/
|
||||
|
||||
/** \file blender/collada/SceneExporter.cpp
|
||||
* \ingroup collada
|
||||
*/
|
||||
|
||||
#include "SceneExporter.h"
|
||||
|
||||
SceneExporter::SceneExporter(COLLADASW::StreamWriter *sw, ArmatureExporter *arm)
|
||||
: COLLADASW::LibraryVisualScenes(sw), arm_exporter(arm)
|
||||
{}
|
||||
|
||||
void SceneExporter::exportScene(Scene *sce, bool export_selected)
|
||||
{
|
||||
// <library_visual_scenes> <visual_scene>
|
||||
std::string id_naming = id_name(sce);
|
||||
openVisualScene(translate_id(id_naming), id_naming);
|
||||
exportHierarchy(sce, export_selected);
|
||||
closeVisualScene();
|
||||
closeLibrary();
|
||||
}
|
||||
|
||||
void SceneExporter::exportHierarchy(Scene *sce, bool export_selected)
|
||||
{
|
||||
Base *base= (Base*) sce->base.first;
|
||||
while(base) {
|
||||
Object *ob = base->object;
|
||||
|
||||
if (!ob->parent) {
|
||||
if(sce->lay & ob->lay) {
|
||||
switch(ob->type) {
|
||||
case OB_MESH:
|
||||
case OB_CAMERA:
|
||||
case OB_LAMP:
|
||||
case OB_ARMATURE:
|
||||
case OB_EMPTY:
|
||||
if (export_selected && !(ob->flag & SELECT)) {
|
||||
break;
|
||||
}
|
||||
// write nodes....
|
||||
writeNodes(ob, sce);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
base= base->next;
|
||||
}
|
||||
}
|
||||
|
||||
void SceneExporter::writeNodes(Object *ob, Scene *sce)
|
||||
{
|
||||
COLLADASW::Node node(mSW);
|
||||
node.setNodeId(translate_id(id_name(ob)));
|
||||
node.setType(COLLADASW::Node::NODE);
|
||||
|
||||
node.start();
|
||||
|
||||
bool is_skinned_mesh = arm_exporter->is_skinned_mesh(ob);
|
||||
|
||||
if (ob->type == OB_MESH && is_skinned_mesh)
|
||||
// for skinned mesh we write obmat in <bind_shape_matrix>
|
||||
TransformWriter::add_node_transform_identity(node);
|
||||
else
|
||||
TransformWriter::add_node_transform_ob(node, ob);
|
||||
|
||||
// <instance_geometry>
|
||||
if (ob->type == OB_MESH) {
|
||||
if (is_skinned_mesh) {
|
||||
arm_exporter->add_instance_controller(ob);
|
||||
}
|
||||
else {
|
||||
COLLADASW::InstanceGeometry instGeom(mSW);
|
||||
instGeom.setUrl(COLLADASW::URI(COLLADABU::Utils::EMPTY_STRING, get_geometry_id(ob)));
|
||||
|
||||
InstanceWriter::add_material_bindings(instGeom.getBindMaterial(), ob);
|
||||
|
||||
instGeom.add();
|
||||
}
|
||||
}
|
||||
|
||||
// <instance_controller>
|
||||
else if (ob->type == OB_ARMATURE) {
|
||||
arm_exporter->add_armature_bones(ob, sce);
|
||||
|
||||
// XXX this looks unstable...
|
||||
node.end();
|
||||
}
|
||||
|
||||
// <instance_camera>
|
||||
else if (ob->type == OB_CAMERA) {
|
||||
COLLADASW::InstanceCamera instCam(mSW, COLLADASW::URI(COLLADABU::Utils::EMPTY_STRING, get_camera_id(ob)));
|
||||
instCam.add();
|
||||
}
|
||||
|
||||
// <instance_light>
|
||||
else if (ob->type == OB_LAMP) {
|
||||
COLLADASW::InstanceLight instLa(mSW, COLLADASW::URI(COLLADABU::Utils::EMPTY_STRING, get_light_id(ob)));
|
||||
instLa.add();
|
||||
}
|
||||
|
||||
// empty object
|
||||
else if (ob->type == OB_EMPTY) { // TODO: handle groups (OB_DUPLIGROUP
|
||||
if((ob->transflag & OB_DUPLIGROUP) == OB_DUPLIGROUP && ob->dup_group) {
|
||||
GroupObject *go = NULL;
|
||||
Group *gr = ob->dup_group;
|
||||
printf("group detected %u\n", gr);
|
||||
for(go = (GroupObject*)(gr->gobject.first); go; go=go->next) {
|
||||
printf("\t%s\n", go->ob->id.name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// write nodes for child objects
|
||||
Base *b = (Base*) sce->base.first;
|
||||
while(b) {
|
||||
// cob - child object
|
||||
Object *cob = b->object;
|
||||
|
||||
if (cob->parent == ob) {
|
||||
switch(cob->type) {
|
||||
case OB_MESH:
|
||||
case OB_CAMERA:
|
||||
case OB_LAMP:
|
||||
case OB_EMPTY:
|
||||
case OB_ARMATURE:
|
||||
// write node...
|
||||
writeNodes(cob, sce);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
b = b->next;
|
||||
}
|
||||
|
||||
if (ob->type != OB_ARMATURE)
|
||||
node.end();
|
||||
}
|
||||
|
101
source/blender/collada/SceneExporter.h
Normal file
101
source/blender/collada/SceneExporter.h
Normal file
@ -0,0 +1,101 @@
|
||||
/*
|
||||
* $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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* Contributor(s): Chingiz Dyussenov, Arystanbek Dyussenov.
|
||||
*
|
||||
* ***** END GPL LICENSE BLOCK *****
|
||||
*/
|
||||
|
||||
/** \file SceneExporter.h
|
||||
* \ingroup collada
|
||||
*/
|
||||
|
||||
#ifndef __SCENEEXPORTER_H__
|
||||
#define __SCENEEXPORTER_H__
|
||||
|
||||
extern "C" {
|
||||
#include "DNA_scene_types.h"
|
||||
#include "DNA_object_types.h"
|
||||
#include "DNA_group_types.h"
|
||||
#include "DNA_meshdata_types.h"
|
||||
#include "DNA_mesh_types.h"
|
||||
#include "DNA_image_types.h"
|
||||
#include "DNA_material_types.h"
|
||||
#include "DNA_texture_types.h"
|
||||
#include "DNA_anim_types.h"
|
||||
#include "DNA_action_types.h"
|
||||
#include "DNA_curve_types.h"
|
||||
#include "DNA_armature_types.h"
|
||||
#include "DNA_modifier_types.h"
|
||||
#include "DNA_userdef_types.h"
|
||||
|
||||
#include "BKE_DerivedMesh.h"
|
||||
#include "BKE_fcurve.h"
|
||||
#include "BKE_animsys.h"
|
||||
#include "BLI_path_util.h"
|
||||
#include "BLI_fileops.h"
|
||||
#include "ED_keyframing.h"
|
||||
}
|
||||
|
||||
#include "COLLADASWAsset.h"
|
||||
#include "COLLADASWLibraryVisualScenes.h"
|
||||
#include "COLLADASWNode.h"
|
||||
#include "COLLADASWSource.h"
|
||||
#include "COLLADASWInstanceGeometry.h"
|
||||
#include "COLLADASWInputList.h"
|
||||
#include "COLLADASWPrimitves.h"
|
||||
#include "COLLADASWVertices.h"
|
||||
#include "COLLADASWLibraryAnimations.h"
|
||||
#include "COLLADASWLibraryImages.h"
|
||||
#include "COLLADASWLibraryEffects.h"
|
||||
#include "COLLADASWImage.h"
|
||||
#include "COLLADASWEffectProfile.h"
|
||||
#include "COLLADASWColorOrTexture.h"
|
||||
#include "COLLADASWParamTemplate.h"
|
||||
#include "COLLADASWParamBase.h"
|
||||
#include "COLLADASWSurfaceInitOption.h"
|
||||
#include "COLLADASWSampler.h"
|
||||
#include "COLLADASWScene.h"
|
||||
#include "COLLADASWTechnique.h"
|
||||
#include "COLLADASWTexture.h"
|
||||
#include "COLLADASWLibraryMaterials.h"
|
||||
#include "COLLADASWBindMaterial.h"
|
||||
#include "COLLADASWInstanceCamera.h"
|
||||
#include "COLLADASWInstanceLight.h"
|
||||
#include "COLLADASWConstants.h"
|
||||
#include "COLLADASWLibraryControllers.h"
|
||||
#include "COLLADASWInstanceController.h"
|
||||
#include "COLLADASWInstanceNode.h"
|
||||
#include "COLLADASWBaseInputElement.h"
|
||||
|
||||
#include "ArmatureExporter.h"
|
||||
|
||||
class SceneExporter: COLLADASW::LibraryVisualScenes, protected TransformWriter, protected InstanceWriter
|
||||
{
|
||||
ArmatureExporter *arm_exporter;
|
||||
public:
|
||||
SceneExporter(COLLADASW::StreamWriter *sw, ArmatureExporter *arm);
|
||||
void exportScene(Scene *sce, bool export_selected);
|
||||
|
||||
private:
|
||||
void exportHierarchy(Scene *sce, bool export_selected);
|
||||
void writeNodes(Object *ob, Scene *sce);
|
||||
};
|
||||
|
||||
#endif
|
@ -42,6 +42,7 @@ set(SRC
|
||||
gpencil_edit.c
|
||||
gpencil_ops.c
|
||||
gpencil_paint.c
|
||||
gpencil_undo.c
|
||||
|
||||
gpencil_intern.h
|
||||
)
|
||||
|
@ -644,7 +644,7 @@ static void gp_draw_data (bGPdata *gpd, int offsx, int offsy, int winx, int winy
|
||||
/* Check if may need to draw the active stroke cache, only if this layer is the active layer
|
||||
* that is being edited. (Stroke buffer is currently stored in gp-data)
|
||||
*/
|
||||
if ((G.f & G_GREASEPENCIL) && (gpl->flag & GP_LAYER_ACTIVE) &&
|
||||
if (ED_gpencil_session_active() && (gpl->flag & GP_LAYER_ACTIVE) &&
|
||||
(gpf->flag & GP_FRAME_PAINT))
|
||||
{
|
||||
/* Buffer stroke needs to be drawn with a different linestyle to help differentiate them from normal strokes. */
|
||||
|
@ -511,8 +511,8 @@ static void gp_stroke_to_bezier (bContext *C, bGPDlayer *gpl, bGPDstroke *gps, C
|
||||
copy_v3_v3(p3d_prev, p3d_cur);
|
||||
copy_v3_v3(p3d_cur, p3d_next);
|
||||
|
||||
if (i + 1 < tot) {
|
||||
gp_strokepoint_convertcoords(C, gps, pt+1, p3d_next, subrect);
|
||||
if (i + 2 < tot) {
|
||||
gp_strokepoint_convertcoords(C, gps, pt + 2, p3d_next, subrect);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -37,6 +37,7 @@
|
||||
/* ***************************************************** */
|
||||
/* Operator Defines */
|
||||
|
||||
struct bGPdata;
|
||||
struct wmOperatorType;
|
||||
|
||||
/* drawing ---------- */
|
||||
@ -48,6 +49,7 @@ typedef enum eGPencil_PaintModes {
|
||||
GP_PAINTMODE_DRAW = 0,
|
||||
GP_PAINTMODE_ERASER,
|
||||
GP_PAINTMODE_DRAW_STRAIGHT,
|
||||
GP_PAINTMODE_DRAW_POLY
|
||||
} eGPencil_PaintModes;
|
||||
|
||||
/* buttons editing --- */
|
||||
@ -61,6 +63,11 @@ void GPENCIL_OT_active_frame_delete(struct wmOperatorType *ot);
|
||||
|
||||
void GPENCIL_OT_convert(struct wmOperatorType *ot);
|
||||
|
||||
/* undo stack ---------- */
|
||||
|
||||
void gpencil_undo_init(struct bGPdata *gpd);
|
||||
void gpencil_undo_push(struct bGPdata *gpd);
|
||||
void gpencil_undo_finish(void);
|
||||
|
||||
/******************************************************* */
|
||||
/* FILTERED ACTION DATA - TYPES ---> XXX DEPRECEATED OLD ANIM SYSTEM CODE! */
|
||||
|
@ -59,6 +59,9 @@ void ED_keymap_gpencil(wmKeyConfig *keyconf)
|
||||
/* draw - straight lines */
|
||||
kmi=WM_keymap_add_item(keymap, "GPENCIL_OT_draw", LEFTMOUSE, KM_PRESS, KM_CTRL, DKEY);
|
||||
RNA_enum_set(kmi->ptr, "mode", GP_PAINTMODE_DRAW_STRAIGHT);
|
||||
/* draw - poly lines */
|
||||
kmi=WM_keymap_add_item(keymap, "GPENCIL_OT_draw", RIGHTMOUSE, KM_PRESS, KM_CTRL, DKEY);
|
||||
RNA_enum_set(kmi->ptr, "mode", GP_PAINTMODE_DRAW_POLY);
|
||||
/* erase */
|
||||
kmi=WM_keymap_add_item(keymap, "GPENCIL_OT_draw", RIGHTMOUSE, KM_PRESS, 0, DKEY);
|
||||
RNA_enum_set(kmi->ptr, "mode", GP_PAINTMODE_ERASER);
|
||||
|
@ -123,6 +123,7 @@ enum {
|
||||
/* Runtime flags */
|
||||
enum {
|
||||
GP_PAINTFLAG_FIRSTRUN = (1<<0), /* operator just started */
|
||||
GP_PAINTFLAG_STROKEADDED = (1<<1) /* stroke was already added during draw session */
|
||||
};
|
||||
|
||||
/* ------ */
|
||||
@ -151,7 +152,7 @@ static int gpencil_draw_poll (bContext *C)
|
||||
/* check if current context can support GPencil data */
|
||||
if (gpencil_data_get_pointers(C, NULL) != NULL) {
|
||||
/* check if Grease Pencil isn't already running */
|
||||
if ((G.f & G_GREASEPENCIL) == 0)
|
||||
if (ED_gpencil_session_active() == 0)
|
||||
return 1;
|
||||
else
|
||||
CTX_wm_operator_poll_msg_set(C, "Grease Pencil operator is already active");
|
||||
@ -374,6 +375,52 @@ static short gp_stroke_addpoint (tGPsdata *p, const int mval[2], float pressure)
|
||||
else
|
||||
return GP_STROKEADD_NORMAL;
|
||||
}
|
||||
else if (p->paintmode == GP_PAINTMODE_DRAW_POLY) {
|
||||
/* get pointer to destination point */
|
||||
pt= (tGPspoint *)(gpd->sbuffer);
|
||||
|
||||
/* store settings */
|
||||
pt->x= mval[0];
|
||||
pt->y= mval[1];
|
||||
pt->pressure= pressure;
|
||||
|
||||
/* if there's stroke fir this poly line session add (or replace last) point
|
||||
to stroke. This allows to draw lines more interactively (see new segment
|
||||
during mouse slide, i.e.) */
|
||||
if (p->flags & GP_PAINTFLAG_STROKEADDED) {
|
||||
bGPDstroke *gps= p->gpf->strokes.last;
|
||||
bGPDspoint *pts;
|
||||
|
||||
/* first time point is adding to temporary buffer -- need to allocate new point in stroke */
|
||||
if (gpd->sbuffer_size == 0) {
|
||||
gps->points = MEM_reallocN(gps->points, sizeof(bGPDspoint)*(gps->totpoints+1));
|
||||
gps->totpoints++;
|
||||
}
|
||||
|
||||
pts = &gps->points[gps->totpoints-1];
|
||||
|
||||
/* special case for poly lines: normally, depth is needed only when creating new stroke from buffer,
|
||||
but poly lines are converting to stroke instantly, so initialize depth buffer before converting coordinates */
|
||||
if (gpencil_project_check(p)) {
|
||||
View3D *v3d= p->sa->spacedata.first;
|
||||
|
||||
view3d_region_operator_needs_opengl(p->win, p->ar);
|
||||
ED_view3d_autodist_init(p->scene, p->ar, v3d, (p->gpd->flag & GP_DATA_DEPTH_STROKE) ? 1:0);
|
||||
}
|
||||
|
||||
/* convert screen-coordinates to appropriate coordinates (and store them) */
|
||||
gp_stroke_convertcoords(p, &pt->x, &pts->x, NULL);
|
||||
|
||||
/* copy pressure */
|
||||
pts->pressure= pt->pressure;
|
||||
}
|
||||
|
||||
/* increment counters */
|
||||
if (gpd->sbuffer_size == 0)
|
||||
gpd->sbuffer_size++;
|
||||
|
||||
return GP_STROKEADD_NORMAL;
|
||||
}
|
||||
|
||||
/* return invalid state for now... */
|
||||
return GP_STROKEADD_INVALID;
|
||||
@ -394,7 +441,7 @@ static void gp_stroke_smooth (tGPsdata *p)
|
||||
int i=0, cmx=gpd->sbuffer_size;
|
||||
|
||||
/* only smooth if smoothing is enabled, and we're not doing a straight line */
|
||||
if (!(U.gp_settings & GP_PAINT_DOSMOOTH) || (p->paintmode == GP_PAINTMODE_DRAW_STRAIGHT))
|
||||
if (!(U.gp_settings & GP_PAINT_DOSMOOTH) || ELEM(p->paintmode, GP_PAINTMODE_DRAW_STRAIGHT, GP_PAINTMODE_DRAW_POLY))
|
||||
return;
|
||||
|
||||
/* don't try if less than 2 points in buffer */
|
||||
@ -526,17 +573,28 @@ static void gp_stroke_newfrombuffer (tGPsdata *p)
|
||||
return;
|
||||
}
|
||||
|
||||
/* special case for poly line -- for already added stroke during session
|
||||
coordinates are getting added to stroke immediatelly to allow more
|
||||
interactive behavior */
|
||||
if (p->paintmode == GP_PAINTMODE_DRAW_POLY) {
|
||||
if (p->flags & GP_PAINTFLAG_STROKEADDED)
|
||||
return;
|
||||
}
|
||||
|
||||
/* allocate memory for a new stroke */
|
||||
gps= MEM_callocN(sizeof(bGPDstroke), "gp_stroke");
|
||||
|
||||
/* allocate enough memory for a continuous array for storage points */
|
||||
pt= gps->points= MEM_callocN(sizeof(bGPDspoint)*totelem, "gp_stroke_points");
|
||||
|
||||
/* copy appropriate settings for stroke */
|
||||
gps->totpoints= totelem;
|
||||
gps->thickness= p->gpl->thickness;
|
||||
gps->flag= gpd->sbuffer_sflag;
|
||||
|
||||
/* allocate enough memory for a continuous array for storage points */
|
||||
gps->points= MEM_callocN(sizeof(bGPDspoint)*gps->totpoints, "gp_stroke_points");
|
||||
|
||||
/* set pointer to first non-initialized point */
|
||||
pt= gps->points + (gps->totpoints - totelem);
|
||||
|
||||
/* copy points from the buffer to the stroke */
|
||||
if (p->paintmode == GP_PAINTMODE_DRAW_STRAIGHT) {
|
||||
/* straight lines only -> only endpoints */
|
||||
@ -564,6 +622,16 @@ static void gp_stroke_newfrombuffer (tGPsdata *p)
|
||||
pt->pressure= ptc->pressure;
|
||||
}
|
||||
}
|
||||
else if (p->paintmode == GP_PAINTMODE_DRAW_POLY) {
|
||||
/* first point */
|
||||
ptc= gpd->sbuffer;
|
||||
|
||||
/* convert screen-coordinates to appropriate coordinates (and store them) */
|
||||
gp_stroke_convertcoords(p, &ptc->x, &pt->x, NULL);
|
||||
|
||||
/* copy pressure */
|
||||
pt->pressure= ptc->pressure;
|
||||
}
|
||||
else {
|
||||
float *depth_arr= NULL;
|
||||
|
||||
@ -642,6 +710,8 @@ static void gp_stroke_newfrombuffer (tGPsdata *p)
|
||||
MEM_freeN(depth_arr);
|
||||
}
|
||||
|
||||
p->flags |= GP_PAINTFLAG_STROKEADDED;
|
||||
|
||||
/* add stroke to frame */
|
||||
BLI_addtail(&p->gpf->strokes, gps);
|
||||
}
|
||||
@ -890,10 +960,14 @@ static void gp_session_validatebuffer (tGPsdata *p)
|
||||
bGPdata *gpd= p->gpd;
|
||||
|
||||
/* clear memory of buffer (or allocate it if starting a new session) */
|
||||
if (gpd->sbuffer)
|
||||
if (gpd->sbuffer) {
|
||||
//printf("\t\tGP - reset sbuffer\n");
|
||||
memset(gpd->sbuffer, 0, sizeof(tGPspoint)*GP_STROKE_BUFFER_MAX);
|
||||
else
|
||||
}
|
||||
else {
|
||||
//printf("\t\tGP - allocate sbuffer\n");
|
||||
gpd->sbuffer= MEM_callocN(sizeof(tGPspoint)*GP_STROKE_BUFFER_MAX, "gp_session_strokebuffer");
|
||||
}
|
||||
|
||||
/* reset indices */
|
||||
gpd->sbuffer_size = 0;
|
||||
@ -902,24 +976,21 @@ static void gp_session_validatebuffer (tGPsdata *p)
|
||||
gpd->sbuffer_sflag= 0;
|
||||
}
|
||||
|
||||
/* init new painting session */
|
||||
static tGPsdata *gp_session_initpaint (bContext *C)
|
||||
/* (re)init new painting data */
|
||||
static int gp_session_initdata (bContext *C, tGPsdata *p)
|
||||
{
|
||||
tGPsdata *p = NULL;
|
||||
bGPdata **gpd_ptr = NULL;
|
||||
ScrArea *curarea= CTX_wm_area(C);
|
||||
ARegion *ar= CTX_wm_region(C);
|
||||
|
||||
/* make sure the active view (at the starting time) is a 3d-view */
|
||||
if (curarea == NULL) {
|
||||
p->status= GP_STATUS_ERROR;
|
||||
if (G.f & G_DEBUG)
|
||||
printf("Error: No active view for painting \n");
|
||||
return NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* create new context data */
|
||||
p= MEM_callocN(sizeof(tGPsdata), "GPencil Drawing Data");
|
||||
|
||||
/* pass on current scene and window */
|
||||
p->scene= CTX_data_scene(C);
|
||||
p->win= CTX_wm_window(C);
|
||||
@ -941,7 +1012,7 @@ static tGPsdata *gp_session_initpaint (bContext *C)
|
||||
p->status= GP_STATUS_ERROR;
|
||||
if (G.f & G_DEBUG)
|
||||
printf("Error: 3D-View active region doesn't have any region data, so cannot be drawable \n");
|
||||
return p;
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if 0 // XXX will this sort of antiquated stuff be restored?
|
||||
@ -950,7 +1021,7 @@ static tGPsdata *gp_session_initpaint (bContext *C)
|
||||
p->status= GP_STATUS_ERROR;
|
||||
if (G.f & G_DEBUG)
|
||||
printf("Error: In active view, Grease Pencil not shown \n");
|
||||
return p;
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
@ -971,7 +1042,7 @@ static tGPsdata *gp_session_initpaint (bContext *C)
|
||||
p->status= GP_STATUS_ERROR;
|
||||
if (G.f & G_DEBUG)
|
||||
printf("Error: In active view, Grease Pencil not shown \n");
|
||||
return;
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
@ -991,13 +1062,13 @@ static tGPsdata *gp_session_initpaint (bContext *C)
|
||||
p->status= GP_STATUS_ERROR;
|
||||
if (G.f & G_DEBUG)
|
||||
printf("Error: In active view (sequencer), active mode doesn't support Grease Pencil \n");
|
||||
return;
|
||||
return 0;
|
||||
}
|
||||
if ((sseq->flag & SEQ_DRAW_GPENCIL)==0) {
|
||||
p->status= GP_STATUS_ERROR;
|
||||
if (G.f & G_DEBUG)
|
||||
printf("Error: In active view, Grease Pencil not shown \n");
|
||||
return;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
break;
|
||||
@ -1018,7 +1089,7 @@ static tGPsdata *gp_session_initpaint (bContext *C)
|
||||
p->status= GP_STATUS_ERROR;
|
||||
if (G.f & G_DEBUG)
|
||||
printf("Error: In active view, Grease Pencil not shown \n");
|
||||
return p;
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
@ -1030,7 +1101,7 @@ static tGPsdata *gp_session_initpaint (bContext *C)
|
||||
p->status= GP_STATUS_ERROR;
|
||||
if (G.f & G_DEBUG)
|
||||
printf("Error: Active view not appropriate for Grease Pencil drawing \n");
|
||||
return p;
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
}
|
||||
@ -1041,7 +1112,7 @@ static tGPsdata *gp_session_initpaint (bContext *C)
|
||||
p->status= GP_STATUS_ERROR;
|
||||
if (G.f & G_DEBUG)
|
||||
printf("Error: Current context doesn't allow for any Grease Pencil data \n");
|
||||
return p;
|
||||
return 0;
|
||||
}
|
||||
else {
|
||||
/* if no existing GPencil block exists, add one */
|
||||
@ -1050,8 +1121,11 @@ static tGPsdata *gp_session_initpaint (bContext *C)
|
||||
p->gpd= *gpd_ptr;
|
||||
}
|
||||
|
||||
/* set edit flags - so that buffer will get drawn */
|
||||
G.f |= G_GREASEPENCIL;
|
||||
if(ED_gpencil_session_active()==0) {
|
||||
/* initialize undo stack,
|
||||
also, existing undo stack would make buffer drawn */
|
||||
gpencil_undo_init(p->gpd);
|
||||
}
|
||||
|
||||
/* clear out buffer (stored in gp-data), in case something contaminated it */
|
||||
gp_session_validatebuffer(p);
|
||||
@ -1061,6 +1135,19 @@ static tGPsdata *gp_session_initpaint (bContext *C)
|
||||
p->im2d_settings.sizex= 1;
|
||||
p->im2d_settings.sizey= 1;
|
||||
#endif
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* init new painting session */
|
||||
static tGPsdata *gp_session_initpaint (bContext *C)
|
||||
{
|
||||
tGPsdata *p = NULL;
|
||||
|
||||
/* create new context data */
|
||||
p= MEM_callocN(sizeof(tGPsdata), "GPencil Drawing Data");
|
||||
|
||||
gp_session_initdata(C, p);
|
||||
|
||||
/* return context data for running paint operator */
|
||||
return p;
|
||||
@ -1077,6 +1164,7 @@ static void gp_session_cleanup (tGPsdata *p)
|
||||
|
||||
/* free stroke buffer */
|
||||
if (gpd->sbuffer) {
|
||||
//printf("\t\tGP - free sbuffer\n");
|
||||
MEM_freeN(gpd->sbuffer);
|
||||
gpd->sbuffer= NULL;
|
||||
}
|
||||
@ -1246,7 +1334,8 @@ static void gp_paint_strokeend (tGPsdata *p)
|
||||
static void gp_paint_cleanup (tGPsdata *p)
|
||||
{
|
||||
/* finish off a stroke */
|
||||
gp_paint_strokeend(p);
|
||||
if(p->gpd)
|
||||
gp_paint_strokeend(p);
|
||||
|
||||
/* "unlock" frame */
|
||||
if (p->gpf)
|
||||
@ -1259,8 +1348,8 @@ static void gpencil_draw_exit (bContext *C, wmOperator *op)
|
||||
{
|
||||
tGPsdata *p= op->customdata;
|
||||
|
||||
/* clear edit flags */
|
||||
G.f &= ~G_GREASEPENCIL;
|
||||
/* clear undo stack */
|
||||
gpencil_undo_finish();
|
||||
|
||||
/* restore cursor to indicate end of drawing */
|
||||
WM_cursor_restore(CTX_wm_window(C));
|
||||
@ -1591,6 +1680,7 @@ static int gpencil_draw_invoke (bContext *C, wmOperator *op, wmEvent *event)
|
||||
//printf("\tGP - hotkey invoked... waiting for click-drag\n");
|
||||
}
|
||||
|
||||
WM_event_add_notifier(C, NC_SCREEN|ND_GPENCIL, NULL);
|
||||
/* add a modal handler for this operator, so that we can then draw continuous strokes */
|
||||
WM_event_add_modal_handler(C, op);
|
||||
return OPERATOR_RUNNING_MODAL;
|
||||
@ -1608,16 +1698,57 @@ static int gpencil_area_exists(bContext *C, ScrArea *satest)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static tGPsdata *gpencil_stroke_begin(bContext *C, wmOperator *op)
|
||||
{
|
||||
tGPsdata *p= op->customdata;
|
||||
|
||||
/* we must check that we're still within the area that we're set up to work from
|
||||
* otherwise we could crash (see bug #20586)
|
||||
*/
|
||||
if (CTX_wm_area(C) != p->sa) {
|
||||
printf("\t\t\tGP - wrong area execution abort! \n");
|
||||
p->status= GP_STATUS_ERROR;
|
||||
}
|
||||
|
||||
//printf("\t\tGP - start stroke \n");
|
||||
|
||||
/* we may need to set up paint env again if we're resuming */
|
||||
// XXX: watch it with the paintmode! in future, it'd be nice to allow changing paint-mode when in sketching-sessions
|
||||
// XXX: with tablet events, we may event want to check for eraser here, for nicer tablet support
|
||||
|
||||
if (gp_session_initdata(C, p))
|
||||
gp_paint_initstroke(p, p->paintmode);
|
||||
|
||||
p= op->customdata;
|
||||
|
||||
if(p->status != GP_STATUS_ERROR)
|
||||
p->status= GP_STATUS_PAINTING;
|
||||
|
||||
return op->customdata;
|
||||
}
|
||||
|
||||
static void gpencil_stroke_end(wmOperator *op)
|
||||
{
|
||||
tGPsdata *p= op->customdata;
|
||||
|
||||
gp_paint_cleanup(p);
|
||||
|
||||
gpencil_undo_push(p->gpd);
|
||||
|
||||
gp_session_cleanup(p);
|
||||
|
||||
p->status= GP_STATUS_IDLING;
|
||||
|
||||
p->gpd= NULL;
|
||||
p->gpl= NULL;
|
||||
p->gpf= NULL;
|
||||
}
|
||||
|
||||
/* events handling during interactive drawing part of operator */
|
||||
static int gpencil_draw_modal (bContext *C, wmOperator *op, wmEvent *event)
|
||||
{
|
||||
tGPsdata *p= op->customdata;
|
||||
//int estate = OPERATOR_PASS_THROUGH; /* default exit state - not handled, so let others have a share of the pie */
|
||||
/* currently, grease pencil conflicts with such operators as undo and set object mode
|
||||
which makes behavior of operator totally unpredictable and crash for some cases.
|
||||
the only way to solve this proper is to ger rid of pointers to data which can
|
||||
chage stored in operator custom data (sergey) */
|
||||
int estate = OPERATOR_RUNNING_MODAL;
|
||||
int estate = OPERATOR_PASS_THROUGH; /* default exit state - not handled, so let others have a share of the pie */
|
||||
|
||||
// if (event->type == NDOF_MOTION)
|
||||
// return OPERATOR_PASS_THROUGH;
|
||||
@ -1645,17 +1776,24 @@ static int gpencil_draw_modal (bContext *C, wmOperator *op, wmEvent *event)
|
||||
if (ELEM(event->type, LEFTMOUSE, RIGHTMOUSE)) {
|
||||
/* if painting, end stroke */
|
||||
if (p->status == GP_STATUS_PAINTING) {
|
||||
int sketch= 0;
|
||||
/* basically, this should be mouse-button up = end stroke
|
||||
* BUT what happens next depends on whether we 'painting sessions' is enabled
|
||||
*/
|
||||
if (GPENCIL_SKETCH_SESSIONS_ON(p->scene)) {
|
||||
sketch|= GPENCIL_SKETCH_SESSIONS_ON(p->scene);
|
||||
/* polyline drawig is also 'sketching' -- all knots should be added during one session */
|
||||
sketch|= p->paintmode == GP_PAINTMODE_DRAW_POLY;
|
||||
|
||||
if (sketch) {
|
||||
/* end stroke only, and then wait to resume painting soon */
|
||||
//printf("\t\tGP - end stroke only\n");
|
||||
gp_paint_cleanup(p);
|
||||
p->status= GP_STATUS_IDLING;
|
||||
gpencil_stroke_end(op);
|
||||
|
||||
/* we've just entered idling state, so this event was processed (but no others yet) */
|
||||
estate = OPERATOR_RUNNING_MODAL;
|
||||
|
||||
/* stroke could be smoothed, send notifier to refresh screen */
|
||||
WM_event_add_notifier(C, NC_SCREEN|ND_GPENCIL|NA_EDITED, NULL);
|
||||
}
|
||||
else {
|
||||
//printf("\t\tGP - end of stroke + op\n");
|
||||
@ -1663,35 +1801,19 @@ static int gpencil_draw_modal (bContext *C, wmOperator *op, wmEvent *event)
|
||||
estate = OPERATOR_FINISHED;
|
||||
}
|
||||
}
|
||||
else {
|
||||
else if (event->val == KM_PRESS) {
|
||||
/* not painting, so start stroke (this should be mouse-button down) */
|
||||
|
||||
/* we must check that we're still within the area that we're set up to work from
|
||||
* otherwise we could crash (see bug #20586)
|
||||
*/
|
||||
if (CTX_wm_area(C) != p->sa) {
|
||||
//printf("\t\t\tGP - wrong area execution abort! \n");
|
||||
p->status= GP_STATUS_ERROR;
|
||||
p= gpencil_stroke_begin(C, op);
|
||||
|
||||
if (p->status == GP_STATUS_ERROR) {
|
||||
estate = OPERATOR_CANCELLED;
|
||||
}
|
||||
else {
|
||||
//printf("\t\tGP - start stroke \n");
|
||||
p->status= GP_STATUS_PAINTING;
|
||||
|
||||
/* we may need to set up paint env again if we're resuming */
|
||||
// XXX: watch it with the paintmode! in future, it'd be nice to allow changing paint-mode when in sketching-sessions
|
||||
// XXX: with tablet events, we may event want to check for eraser here, for nicer tablet support
|
||||
gp_paint_initstroke(p, p->paintmode);
|
||||
|
||||
if (p->status == GP_STATUS_ERROR) {
|
||||
estate = OPERATOR_CANCELLED;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
p->status = GP_STATUS_IDLING;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* handle mode-specific events */
|
||||
if (p->status == GP_STATUS_PAINTING) {
|
||||
/* handle painting mouse-movements? */
|
||||
@ -1703,7 +1825,7 @@ static int gpencil_draw_modal (bContext *C, wmOperator *op, wmEvent *event)
|
||||
|
||||
/* finish painting operation if anything went wrong just now */
|
||||
if (p->status == GP_STATUS_ERROR) {
|
||||
//printf("\t\t\t\tGP - add error done! \n");
|
||||
printf("\t\t\t\tGP - add error done! \n");
|
||||
estate = OPERATOR_CANCELLED;
|
||||
}
|
||||
else {
|
||||
@ -1720,28 +1842,6 @@ static int gpencil_draw_modal (bContext *C, wmOperator *op, wmEvent *event)
|
||||
estate = OPERATOR_RUNNING_MODAL;
|
||||
}
|
||||
}
|
||||
else if (p->status == GP_STATUS_IDLING) {
|
||||
/* standard undo/redo shouldn't be allowed to execute or else it causes crashes, so catch it here */
|
||||
// FIXME: this is a hardcoded hotkey that can't be changed
|
||||
// TODO: catch redo as well, but how?
|
||||
if (event->type == ZKEY && event->val == KM_RELEASE) {
|
||||
/* oskey = cmd key on macs as they seem to use cmd-z for undo as well? */
|
||||
if ((event->ctrl) || (event->oskey)) {
|
||||
/* just delete last stroke, which will look like undo to the end user */
|
||||
//printf("caught attempted undo event... deleting last stroke \n");
|
||||
gpencil_frame_delete_laststroke(p->gpl, p->gpf);
|
||||
/* undoing the last line can free p->gpf
|
||||
* note, could do this in a bit more of an elegant way then a search but it at least prevents a crash */
|
||||
if(BLI_findindex(&p->gpl->frames, p->gpf) == -1) {
|
||||
p->gpf= NULL;
|
||||
}
|
||||
|
||||
/* event handled, so force refresh */
|
||||
ED_region_tag_redraw(p->ar); /* just active area for now, since doing whole screen is too slow */
|
||||
estate = OPERATOR_RUNNING_MODAL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* gpencil modal operator stores area, which can be removed while using it (like fullscreen) */
|
||||
if(0==gpencil_area_exists(C, p->sa))
|
||||
@ -1777,6 +1877,7 @@ static int gpencil_draw_modal (bContext *C, wmOperator *op, wmEvent *event)
|
||||
static EnumPropertyItem prop_gpencil_drawmodes[] = {
|
||||
{GP_PAINTMODE_DRAW, "DRAW", 0, "Draw Freehand", ""},
|
||||
{GP_PAINTMODE_DRAW_STRAIGHT, "DRAW_STRAIGHT", 0, "Draw Straight Lines", ""},
|
||||
{GP_PAINTMODE_DRAW_POLY, "DRAW_POLY", 0, "Dtaw Poly Line", ""},
|
||||
{GP_PAINTMODE_ERASER, "ERASER", 0, "Eraser", ""},
|
||||
{0, NULL, 0, NULL, NULL}
|
||||
};
|
||||
|
168
source/blender/editors/gpencil/gpencil_undo.c
Normal file
168
source/blender/editors/gpencil/gpencil_undo.c
Normal file
@ -0,0 +1,168 @@
|
||||
/*
|
||||
* $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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* The Original Code is Copyright (C) 2011 Blender Foundation.
|
||||
* All rights reserved.
|
||||
*
|
||||
*
|
||||
* Contributor(s): Blender Foundation,
|
||||
* Sergey Sharybin
|
||||
*
|
||||
* ***** END GPL LICENSE BLOCK *****
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "MEM_guardedalloc.h"
|
||||
|
||||
#include "DNA_gpencil_types.h"
|
||||
#include "DNA_listBase.h"
|
||||
#include "DNA_windowmanager_types.h"
|
||||
|
||||
#include "BKE_context.h"
|
||||
#include "BKE_gpencil.h"
|
||||
|
||||
#include "BLI_listbase.h"
|
||||
|
||||
#include "ED_gpencil.h"
|
||||
|
||||
#include "WM_api.h"
|
||||
#include "WM_types.h"
|
||||
|
||||
#include "gpencil_intern.h"
|
||||
|
||||
#define MAXUNDONAME 64
|
||||
|
||||
typedef struct bGPundonode {
|
||||
struct bGPundonode *next, *prev;
|
||||
|
||||
char name[MAXUNDONAME];
|
||||
struct bGPdata *gpd;
|
||||
} bGPundonode;
|
||||
|
||||
static ListBase undo_nodes = {NULL, NULL};
|
||||
static bGPundonode *cur_node = NULL;
|
||||
|
||||
int ED_gpencil_session_active(void)
|
||||
{
|
||||
return undo_nodes.first != NULL;
|
||||
}
|
||||
|
||||
int ED_undo_gpencil_step(bContext *C, int step, const char *name)
|
||||
{
|
||||
bGPdata **gpd_ptr= NULL, *new_gpd= NULL;
|
||||
|
||||
gpd_ptr= gpencil_data_get_pointers(C, NULL);
|
||||
|
||||
if(step==1) { /* undo */
|
||||
//printf("\t\tGP - undo step\n");
|
||||
if(cur_node->prev) {
|
||||
if(!name || strcmp(cur_node->name, name) == 0) {
|
||||
cur_node= cur_node->prev;
|
||||
new_gpd= cur_node->gpd;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (step==-1) {
|
||||
//printf("\t\tGP - redo step\n");
|
||||
if(cur_node->next) {
|
||||
if(!name || strcmp(cur_node->name, name) == 0) {
|
||||
cur_node= cur_node->next;
|
||||
new_gpd= cur_node->gpd;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(new_gpd) {
|
||||
if(gpd_ptr) {
|
||||
if(*gpd_ptr) {
|
||||
bGPdata *gpd= *gpd_ptr;
|
||||
bGPDlayer *gpl, *gpld;
|
||||
|
||||
free_gpencil_layers(&gpd->layers);
|
||||
|
||||
/* copy layers */
|
||||
gpd->layers.first= gpd->layers.last= NULL;
|
||||
|
||||
for (gpl= new_gpd->layers.first; gpl; gpl= gpl->next) {
|
||||
/* make a copy of source layer and its data */
|
||||
gpld= gpencil_layer_duplicate(gpl);
|
||||
BLI_addtail(&gpd->layers, gpld);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
WM_event_add_notifier(C, NC_SCREEN|ND_GPENCIL|NA_EDITED, NULL);
|
||||
|
||||
return OPERATOR_FINISHED;
|
||||
}
|
||||
|
||||
void gpencil_undo_init(bGPdata *gpd)
|
||||
{
|
||||
gpencil_undo_push(gpd);
|
||||
}
|
||||
|
||||
void gpencil_undo_push(bGPdata *gpd)
|
||||
{
|
||||
bGPundonode *undo_node;
|
||||
|
||||
//printf("\t\tGP - undo push\n");
|
||||
|
||||
if(cur_node) {
|
||||
/* remove all un-done nodes from stack */
|
||||
undo_node= cur_node->next;
|
||||
|
||||
while(undo_node) {
|
||||
bGPundonode *next_node= undo_node->next;
|
||||
|
||||
free_gpencil_data(undo_node->gpd);
|
||||
MEM_freeN(undo_node->gpd);
|
||||
|
||||
BLI_freelinkN(&undo_nodes, undo_node);
|
||||
|
||||
undo_node= next_node;
|
||||
}
|
||||
}
|
||||
|
||||
/* create new undo node */
|
||||
undo_node= MEM_callocN(sizeof(bGPundonode), "gpencil undo node");
|
||||
undo_node->gpd= gpencil_data_duplicate(gpd);
|
||||
|
||||
cur_node= undo_node;
|
||||
|
||||
BLI_addtail(&undo_nodes, undo_node);
|
||||
}
|
||||
|
||||
void gpencil_undo_finish(void)
|
||||
{
|
||||
bGPundonode *undo_node= undo_nodes.first;
|
||||
|
||||
while(undo_node) {
|
||||
free_gpencil_data(undo_node->gpd);
|
||||
MEM_freeN(undo_node->gpd);
|
||||
|
||||
undo_node= undo_node->next;
|
||||
}
|
||||
|
||||
BLI_freelistN(&undo_nodes);
|
||||
|
||||
cur_node= NULL;
|
||||
}
|
@ -106,4 +106,8 @@ void paste_gpdata(void);
|
||||
void snap_gplayer_frames(struct bGPDlayer *gpl, short mode);
|
||||
void mirror_gplayer_frames(struct bGPDlayer *gpl, short mode);
|
||||
|
||||
/* ------------ Grease-Pencil Undo System ------------------ */
|
||||
int ED_gpencil_session_active(void);
|
||||
int ED_undo_gpencil_step(struct bContext *C, int step, const char *name);
|
||||
|
||||
#endif /* ED_GPENCIL_H */
|
||||
|
@ -4668,7 +4668,7 @@ static void paint_brush_init_tex(Brush *brush)
|
||||
if(brush) {
|
||||
MTex *mtex= &brush->mtex;
|
||||
if(mtex->tex && mtex->tex->nodetree)
|
||||
ntreeTexBeginExecTree(mtex->tex->nodetree); /* has internal flag to detect it only does it once */
|
||||
ntreeTexBeginExecTree(mtex->tex->nodetree, 1); /* has internal flag to detect it only does it once */
|
||||
}
|
||||
|
||||
}
|
||||
@ -4830,7 +4830,7 @@ static void paint_brush_exit_tex(Brush *brush)
|
||||
if(brush) {
|
||||
MTex *mtex= &brush->mtex;
|
||||
if(mtex->tex && mtex->tex->nodetree)
|
||||
ntreeTexEndExecTree(mtex->tex->nodetree->execdata);
|
||||
ntreeTexEndExecTree(mtex->tex->nodetree->execdata, 1);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3297,7 +3297,7 @@ static void sculpt_brush_init_tex(Sculpt *sd, SculptSession *ss)
|
||||
|
||||
/* init mtex nodes */
|
||||
if(mtex->tex && mtex->tex->nodetree)
|
||||
ntreeTexBeginExecTree(mtex->tex->nodetree); /* has internal flag to detect it only does it once */
|
||||
ntreeTexBeginExecTree(mtex->tex->nodetree, 1); /* has internal flag to detect it only does it once */
|
||||
|
||||
/* TODO: Shouldn't really have to do this at the start of every
|
||||
stroke, but sculpt would need some sort of notification when
|
||||
@ -3483,7 +3483,7 @@ static void sculpt_brush_exit_tex(Sculpt *sd)
|
||||
MTex *mtex= &brush->mtex;
|
||||
|
||||
if(mtex->tex && mtex->tex->nodetree)
|
||||
ntreeTexEndExecTree(mtex->tex->nodetree->execdata);
|
||||
ntreeTexEndExecTree(mtex->tex->nodetree->execdata, 1);
|
||||
}
|
||||
|
||||
static void sculpt_stroke_done(bContext *C, struct PaintStroke *UNUSED(stroke))
|
||||
|
@ -637,7 +637,7 @@ static void draw_group_socket(const bContext *C, SpaceNode *snode, bNodeTree *nt
|
||||
float arrowbutw= 0.8f*UI_UNIT_X;
|
||||
/* layout stuff for buttons on group left frame */
|
||||
float colw= 0.6f*node_group_frame;
|
||||
float col1= 6;
|
||||
float col1= 6 - node_group_frame;
|
||||
float col2= col1 + colw+6;
|
||||
float col3= node_group_frame - arrowbutw - 6;
|
||||
/* layout stuff for buttons on group right frame */
|
||||
|
@ -232,6 +232,7 @@ static void node_menu_add(const bContext *C, Menu *menu)
|
||||
uiItemMenuF(layout, "Convertor", 0, node_add_menu, SET_INT_IN_POINTER(NODE_CLASS_CONVERTOR));
|
||||
uiItemMenuF(layout, "Group", 0, node_add_menu, SET_INT_IN_POINTER(NODE_CLASS_GROUP));
|
||||
uiItemMenuF(layout, "Dynamic", 0, node_add_menu, SET_INT_IN_POINTER(NODE_CLASS_OP_DYNAMIC));
|
||||
uiItemMenuF(layout, "Layout", 0, node_add_menu, SET_INT_IN_POINTER(NODE_CLASS_LAYOUT));
|
||||
}
|
||||
else if(snode->treetype==NTREE_COMPOSIT) {
|
||||
uiItemMenuF(layout, "Input", 0, node_add_menu, SET_INT_IN_POINTER(NODE_CLASS_INPUT));
|
||||
@ -243,6 +244,7 @@ static void node_menu_add(const bContext *C, Menu *menu)
|
||||
uiItemMenuF(layout, "Matte", 0, node_add_menu, SET_INT_IN_POINTER(NODE_CLASS_MATTE));
|
||||
uiItemMenuF(layout, "Distort", 0, node_add_menu, SET_INT_IN_POINTER(NODE_CLASS_DISTORT));
|
||||
uiItemMenuF(layout, "Group", 0, node_add_menu, SET_INT_IN_POINTER(NODE_CLASS_GROUP));
|
||||
uiItemMenuF(layout, "Layout", 0, node_add_menu, SET_INT_IN_POINTER(NODE_CLASS_LAYOUT));
|
||||
}
|
||||
else if(snode->treetype==NTREE_TEXTURE) {
|
||||
uiItemMenuF(layout, "Input", 0, node_add_menu, SET_INT_IN_POINTER(NODE_CLASS_INPUT));
|
||||
@ -253,6 +255,7 @@ static void node_menu_add(const bContext *C, Menu *menu)
|
||||
uiItemMenuF(layout, "Convertor", 0, node_add_menu, SET_INT_IN_POINTER(NODE_CLASS_CONVERTOR));
|
||||
uiItemMenuF(layout, "Distort", 0, node_add_menu, SET_INT_IN_POINTER(NODE_CLASS_DISTORT));
|
||||
uiItemMenuF(layout, "Group", 0, node_add_menu, SET_INT_IN_POINTER(NODE_CLASS_GROUP));
|
||||
uiItemMenuF(layout, "Layout", 0, node_add_menu, SET_INT_IN_POINTER(NODE_CLASS_LAYOUT));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2502,12 +2502,32 @@ static void draw_em_measure_stats(View3D *v3d, RegionView3D *rv3d,
|
||||
/* useful for debugging index vs shape key index */
|
||||
#if 0
|
||||
{
|
||||
EditVert *eve;
|
||||
int j;
|
||||
BMIter iter;
|
||||
BMVert *eve;
|
||||
int j=0;
|
||||
|
||||
UI_GetThemeColor3ubv(TH_DRAWEXTRA_FACEANG, col);
|
||||
for(eve= em->verts.first, j= 0; eve; eve= eve->next, j++) {
|
||||
sprintf(val, "%d:%d", j, eve->keyindex);
|
||||
view3d_cached_text_draw_add(eve->co, val, 0, V3D_CACHE_TEXT_ASCII, col);
|
||||
|
||||
if(CustomData_has_layer(&em->bm->vdata, CD_SHAPE_KEYINDEX)) {
|
||||
int *keyi;
|
||||
BM_ITER(eve, &iter, em->bm, BM_VERTS_OF_MESH, NULL) {
|
||||
keyi = CustomData_bmesh_get(&em->bm->vdata, eve->head.data, CD_SHAPE_KEYINDEX);
|
||||
if(keyi && *keyi != ORIGINDEX_NONE) {
|
||||
sprintf(val, "%d:%d", j, *keyi);
|
||||
}
|
||||
else {
|
||||
sprintf(val, "%d", j);
|
||||
}
|
||||
view3d_cached_text_draw_add(eve->co, val, 0, V3D_CACHE_TEXT_ASCII, col);
|
||||
i++;
|
||||
}
|
||||
}
|
||||
else {
|
||||
BM_ITER(eve, &iter, em->bm, BM_VERTS_OF_MESH, NULL) {
|
||||
sprintf(val, "%d", j);
|
||||
view3d_cached_text_draw_add(eve->co, val, 0, V3D_CACHE_TEXT_ASCII, col);
|
||||
j++;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
@ -1682,7 +1682,14 @@ int initTransform(bContext *C, TransInfo *t, wmOperator *op, wmEvent *event, int
|
||||
if (RNA_property_is_set(op->ptr, "value"))
|
||||
{
|
||||
float values[4]= {0}; /* incase value isn't length 4, avoid uninitialized memory */
|
||||
RNA_float_get_array(op->ptr, "value", values);
|
||||
PropertyRNA *prop= RNA_struct_find_property(op->ptr, "value");
|
||||
|
||||
if(RNA_property_array_check(prop)) {
|
||||
RNA_float_get_array(op->ptr, "value", values);
|
||||
} else {
|
||||
values[0]= RNA_float_get(op->ptr, "value");
|
||||
}
|
||||
|
||||
QUATCOPY(t->values, values);
|
||||
QUATCOPY(t->auto_values, values);
|
||||
t->flag |= T_AUTOVALUES;
|
||||
|
@ -54,6 +54,7 @@
|
||||
#include "ED_armature.h"
|
||||
#include "ED_particle.h"
|
||||
#include "ED_curve.h"
|
||||
#include "ED_gpencil.h"
|
||||
#include "ED_mball.h"
|
||||
#include "ED_mesh.h"
|
||||
#include "ED_object.h"
|
||||
@ -126,6 +127,11 @@ static int ed_undo_step(bContext *C, int step, const char *undoname)
|
||||
Object *obact= CTX_data_active_object(C);
|
||||
ScrArea *sa= CTX_wm_area(C);
|
||||
|
||||
/* grease pencil can be can be used in plenty of spaces, so check it first */
|
||||
if(ED_gpencil_session_active()) {
|
||||
return ED_undo_gpencil_step(C, step, undoname);
|
||||
}
|
||||
|
||||
if(sa && sa->spacetype==SPACE_IMAGE) {
|
||||
SpaceImage *sima= (SpaceImage *)sa->spacedata.first;
|
||||
|
||||
|
@ -84,7 +84,7 @@ typedef struct bNodeSocket {
|
||||
|
||||
/* execution data */
|
||||
short stack_index; /* local stack index */
|
||||
short pad2;
|
||||
short stack_type; /* deprecated, kept for forward compatibility */
|
||||
int pad3;
|
||||
void *cache; /* cached data from execution */
|
||||
|
||||
@ -198,8 +198,8 @@ typedef struct bNodeLink {
|
||||
} bNodeLink;
|
||||
|
||||
/* link->flag */
|
||||
#define NODE_LINK_VALID 1 /* link has been successfully validated */
|
||||
#define NODE_LINKFLAG_HILITE 2
|
||||
#define NODE_LINKFLAG_HILITE 1 /* link has been successfully validated */
|
||||
#define NODE_LINK_VALID 2
|
||||
|
||||
/* the basis for a Node tree, all links and nodes reside internal here */
|
||||
/* only re-usable node trees are in the library though, materials and textures allocate own tree struct */
|
||||
|
@ -4407,7 +4407,7 @@ char *RNA_property_as_string(bContext *C, PointerRNA *ptr, PropertyRNA *prop)
|
||||
buf= MEM_mallocN(sizeof(char)*(length+1), "RNA_property_as_string");
|
||||
buf_esc= MEM_mallocN(sizeof(char)*(length*2+1), "RNA_property_as_string esc");
|
||||
RNA_property_string_get(ptr, prop, buf);
|
||||
BLI_strescape(buf_esc, buf, length*2);
|
||||
BLI_strescape(buf_esc, buf, length*2+1);
|
||||
MEM_freeN(buf);
|
||||
BLI_dynstr_appendf(dynstr, "\"%s\"", buf_esc);
|
||||
MEM_freeN(buf_esc);
|
||||
|
@ -261,6 +261,7 @@ void RNA_api_wm(struct StructRNA *srna);
|
||||
void RNA_api_sensor(struct StructRNA *srna);
|
||||
void RNA_api_controller(struct StructRNA *srna);
|
||||
void RNA_api_actuator(struct StructRNA *srna);
|
||||
void RNA_api_texture(struct StructRNA *srna);
|
||||
void RNA_api_environment_map(struct StructRNA *srna);
|
||||
|
||||
/* main collection functions */
|
||||
|
@ -68,13 +68,14 @@ static void rna_Screen_scene_set(PointerRNA *ptr, PointerRNA value)
|
||||
sc->newscene= value.data;
|
||||
}
|
||||
|
||||
static void rna_Screen_scene_update(Main *UNUSED(bmain), Scene *UNUSED(scene), PointerRNA *ptr)
|
||||
static void rna_Screen_scene_update(bContext *C, PointerRNA *ptr)
|
||||
{
|
||||
bScreen *sc= (bScreen*)ptr->data;
|
||||
|
||||
/* exception: can't set screens inside of area/region handers */
|
||||
/* exception: can't set screens inside of area/region handers, and must
|
||||
use context so notifier gets to the right window */
|
||||
if(sc->newscene) {
|
||||
WM_main_add_notifier(NC_SCENE|ND_SCENEBROWSE, sc->newscene);
|
||||
WM_event_add_notifier(C, NC_SCENE|ND_SCENEBROWSE, sc->newscene);
|
||||
sc->newscene= NULL;
|
||||
}
|
||||
}
|
||||
@ -231,6 +232,7 @@ static void rna_def_screen(BlenderRNA *brna)
|
||||
RNA_def_property_flag(prop, PROP_EDITABLE|PROP_NEVER_NULL);
|
||||
RNA_def_property_pointer_funcs(prop, NULL, "rna_Screen_scene_set", NULL, NULL);
|
||||
RNA_def_property_ui_text(prop, "Scene", "Active scene to be edited in the screen");
|
||||
RNA_def_property_flag(prop, PROP_CONTEXT_UPDATE);
|
||||
RNA_def_property_update(prop, 0, "rna_Screen_scene_update");
|
||||
|
||||
/* collections */
|
||||
|
@ -1820,6 +1820,8 @@ static void rna_def_texture(BlenderRNA *brna)
|
||||
rna_def_texture_pointdensity(brna);
|
||||
rna_def_texture_voxeldata(brna);
|
||||
/* XXX add more types here .. */
|
||||
|
||||
RNA_api_texture(srna);
|
||||
}
|
||||
|
||||
void RNA_def_texture(BlenderRNA *brna)
|
||||
|
@ -43,6 +43,7 @@
|
||||
#include "BKE_context.h"
|
||||
#include "BKE_global.h"
|
||||
#include "RE_pipeline.h"
|
||||
#include "RE_shader_ext.h"
|
||||
|
||||
void save_envmap(struct EnvMap *env, bContext *C, ReportList *reports, const char* filepath, struct Scene *scene, float layout[12])
|
||||
{
|
||||
@ -67,30 +68,59 @@ void clear_envmap(struct EnvMap *env, bContext *C)
|
||||
}
|
||||
}
|
||||
|
||||
void texture_evaluate(struct Tex *tex, float value[3], float color_r[3])
|
||||
{
|
||||
TexResult texres= {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0, NULL};
|
||||
multitex_ext(tex, value, NULL, NULL, 1, &texres);
|
||||
|
||||
color_r[0] = texres.tr;
|
||||
color_r[1] = texres.tg;
|
||||
color_r[2] = texres.tb;
|
||||
color_r[3] = texres.tin;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
void RNA_api_texture(StructRNA *srna)
|
||||
{
|
||||
FunctionRNA *func;
|
||||
PropertyRNA *parm;
|
||||
|
||||
func= RNA_def_function(srna, "evaluate", "texture_evaluate");
|
||||
RNA_def_function_ui_description(func, "Evaluate the texture at the coordinates given");
|
||||
|
||||
parm= RNA_def_float_vector(func, "value", 3, NULL, -FLT_MAX, FLT_MAX, "", "", -1e4, 1e4);
|
||||
RNA_def_property_flag(parm, PROP_REQUIRED);
|
||||
|
||||
/* return location and normal */
|
||||
parm= RNA_def_float_vector(func, "result", 4, NULL, -FLT_MAX, FLT_MAX, "Result", NULL, -1e4, 1e4);
|
||||
RNA_def_property_flag(parm, PROP_THICK_WRAP);
|
||||
RNA_def_function_output(func, parm);
|
||||
|
||||
}
|
||||
|
||||
void RNA_api_environment_map(StructRNA *srna)
|
||||
{
|
||||
FunctionRNA *func;
|
||||
PropertyRNA *parm;
|
||||
|
||||
|
||||
static const float default_layout[] = { 0,0, 1,0, 2,0, 0,1, 1,1, 2,1 };
|
||||
|
||||
|
||||
func= RNA_def_function(srna, "clear", "clear_envmap");
|
||||
RNA_def_function_ui_description(func, "Discard the environment map and free it from memory.");
|
||||
RNA_def_function_flag(func, FUNC_USE_CONTEXT);
|
||||
RNA_def_function_ui_description(func, "Discard the environment map and free it from memory.");
|
||||
RNA_def_function_flag(func, FUNC_USE_CONTEXT);
|
||||
|
||||
|
||||
func= RNA_def_function(srna,"save", "save_envmap");
|
||||
RNA_def_function_ui_description(func, "Save the environment map to disc using the scene render settings.");
|
||||
RNA_def_function_flag(func, FUNC_USE_CONTEXT|FUNC_USE_REPORTS);
|
||||
|
||||
parm= RNA_def_string_file_name(func,"filepath","",FILE_MAX,"File path","Location of the output file");
|
||||
RNA_def_property_flag(parm, PROP_REQUIRED);
|
||||
|
||||
RNA_def_pointer(func, "scene", "Scene", "", "Overrides the scene from which image parameters are taken.");
|
||||
RNA_def_function_ui_description(func, "Save the environment map to disc using the scene render settings.");
|
||||
RNA_def_function_flag(func, FUNC_USE_CONTEXT|FUNC_USE_REPORTS);
|
||||
|
||||
parm = RNA_def_float_array(func, "layout", 12, default_layout, 0.0f, 0.0f, "File layout", "Flat array describing the X,Y position of each cube face in the output image, where 1 is the size of a face. Order is [+Z -Z +Y -X -Y +X]. Use -1 to skip a face.", 0.0f, 0.0f);
|
||||
parm= RNA_def_string_file_name(func,"filepath","",FILE_MAX,"File path","Location of the output file");
|
||||
RNA_def_property_flag(parm, PROP_REQUIRED);
|
||||
|
||||
RNA_def_pointer(func, "scene", "Scene", "", "Overrides the scene from which image parameters are taken.");
|
||||
|
||||
parm = RNA_def_float_array(func, "layout", 12, default_layout, 0.0f, 0.0f, "File layout", "Flat array describing the X,Y position of each cube face in the output image, where 1 is the size of a face. Order is [+Z -Z +Y -X -Y +X]. Use -1 to skip a face.", 0.0f, 0.0f);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -482,13 +482,14 @@ static void rna_Window_screen_set(PointerRNA *ptr, PointerRNA value)
|
||||
win->newscreen= value.data;
|
||||
}
|
||||
|
||||
static void rna_Window_screen_update(Main *UNUSED(bmain), Scene *UNUSED(scene), PointerRNA *ptr)
|
||||
static void rna_Window_screen_update(bContext *C, PointerRNA *ptr)
|
||||
{
|
||||
wmWindow *win= (wmWindow*)ptr->data;
|
||||
|
||||
/* exception: can't set screens inside of area/region handers */
|
||||
/* exception: can't set screens inside of area/region handers, and must
|
||||
use context so notifier gets to the right window */
|
||||
if(win->newscreen) {
|
||||
WM_main_add_notifier(NC_SCREEN|ND_SCREENBROWSE, win->newscreen);
|
||||
WM_event_add_notifier(C, NC_SCREEN|ND_SCREENBROWSE, win->newscreen);
|
||||
win->newscreen= NULL;
|
||||
}
|
||||
}
|
||||
@ -1454,6 +1455,7 @@ static void rna_def_window(BlenderRNA *brna)
|
||||
RNA_def_property_ui_text(prop, "Screen", "Active screen showing in the window");
|
||||
RNA_def_property_flag(prop, PROP_EDITABLE);
|
||||
RNA_def_property_pointer_funcs(prop, NULL, "rna_Window_screen_set", NULL, NULL);
|
||||
RNA_def_property_flag(prop, PROP_CONTEXT_UPDATE);
|
||||
RNA_def_property_update(prop, 0, "rna_Window_screen_update");
|
||||
}
|
||||
|
||||
|
@ -360,7 +360,7 @@ static void rna_def_lighting(BlenderRNA *brna)
|
||||
|
||||
prop= RNA_def_property(srna, "samples", PROP_INT, PROP_NONE);
|
||||
RNA_def_property_int_sdna(prop, NULL, "aosamp");
|
||||
RNA_def_property_range(prop, 1, 32);
|
||||
RNA_def_property_range(prop, 1, 128);
|
||||
RNA_def_property_ui_text(prop, "Samples", "Amount of ray samples. Higher values give smoother results and longer rendering times");
|
||||
RNA_def_property_update(prop, 0, "rna_World_update");
|
||||
|
||||
|
@ -200,17 +200,22 @@ bNodeTreeType ntreeType_Composite = {
|
||||
};
|
||||
|
||||
|
||||
struct bNodeTreeExec *ntreeCompositBeginExecTree(bNodeTree *ntree)
|
||||
/* XXX Group nodes must set use_tree_data to false, since their trees can be shared by multiple nodes.
|
||||
* If use_tree_data is true, the ntree->execdata pointer is checked to avoid multiple execution of top-level trees.
|
||||
*/
|
||||
struct bNodeTreeExec *ntreeCompositBeginExecTree(bNodeTree *ntree, int use_tree_data)
|
||||
{
|
||||
bNodeTreeExec *exec;
|
||||
bNode *node;
|
||||
bNodeSocket *sock;
|
||||
|
||||
/* XXX hack: prevent exec data from being generated twice.
|
||||
* this should be handled by the renderer!
|
||||
*/
|
||||
if (ntree->execdata)
|
||||
return ntree->execdata;
|
||||
if (use_tree_data) {
|
||||
/* XXX hack: prevent exec data from being generated twice.
|
||||
* this should be handled by the renderer!
|
||||
*/
|
||||
if (ntree->execdata)
|
||||
return ntree->execdata;
|
||||
}
|
||||
|
||||
/* ensures only a single output node is enabled */
|
||||
ntreeSetOutput(ntree);
|
||||
@ -236,15 +241,20 @@ struct bNodeTreeExec *ntreeCompositBeginExecTree(bNodeTree *ntree)
|
||||
}
|
||||
}
|
||||
|
||||
/* XXX this should not be necessary, but is still used for cmp/sha/tex nodes,
|
||||
if (use_tree_data) {
|
||||
/* XXX this should not be necessary, but is still used for cmp/sha/tex nodes,
|
||||
* which only store the ntree pointer. Should be fixed at some point!
|
||||
*/
|
||||
ntree->execdata = exec;
|
||||
ntree->execdata = exec;
|
||||
}
|
||||
|
||||
return exec;
|
||||
}
|
||||
|
||||
void ntreeCompositEndExecTree(bNodeTreeExec *exec)
|
||||
/* XXX Group nodes must set use_tree_data to false, since their trees can be shared by multiple nodes.
|
||||
* If use_tree_data is true, the ntree->execdata pointer is checked to avoid multiple execution of top-level trees.
|
||||
*/
|
||||
void ntreeCompositEndExecTree(bNodeTreeExec *exec, int use_tree_data)
|
||||
{
|
||||
if(exec) {
|
||||
bNodeTree *ntree= exec->nodetree;
|
||||
@ -269,8 +279,10 @@ void ntreeCompositEndExecTree(bNodeTreeExec *exec)
|
||||
|
||||
ntree_exec_end(exec);
|
||||
|
||||
/* XXX clear nodetree backpointer to exec data, same problem as noted in ntreeBeginExecTree */
|
||||
ntree->execdata = NULL;
|
||||
if (use_tree_data) {
|
||||
/* XXX clear nodetree backpointer to exec data, same problem as noted in ntreeBeginExecTree */
|
||||
ntree->execdata = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -495,10 +507,10 @@ static void ntree_composite_texnode(bNodeTree *ntree, int init)
|
||||
/* has internal flag to detect it only does it once */
|
||||
if(init) {
|
||||
if (!tex->nodetree->execdata)
|
||||
tex->nodetree->execdata = ntreeTexBeginExecTree(tex->nodetree);
|
||||
tex->nodetree->execdata = ntreeTexBeginExecTree(tex->nodetree, 1);
|
||||
}
|
||||
else
|
||||
ntreeTexEndExecTree(tex->nodetree->execdata);
|
||||
ntreeTexEndExecTree(tex->nodetree->execdata, 1);
|
||||
tex->nodetree->execdata = NULL;
|
||||
}
|
||||
}
|
||||
@ -521,8 +533,10 @@ void ntreeCompositExecTree(bNodeTree *ntree, RenderData *rd, int do_preview)
|
||||
if(do_preview)
|
||||
ntreeInitPreview(ntree, 0, 0);
|
||||
|
||||
if (!ntree->execdata)
|
||||
exec = ntreeCompositBeginExecTree(ntree);
|
||||
if (!ntree->execdata) {
|
||||
/* XXX this is the top-level tree, so we use the ntree->execdata pointer. */
|
||||
exec = ntreeCompositBeginExecTree(ntree, 1);
|
||||
}
|
||||
ntree_composite_texnode(ntree, 1);
|
||||
|
||||
/* prevent unlucky accidents */
|
||||
@ -592,7 +606,8 @@ void ntreeCompositExecTree(bNodeTree *ntree, RenderData *rd, int do_preview)
|
||||
|
||||
BLI_end_threads(&threads);
|
||||
|
||||
ntreeCompositEndExecTree(exec);
|
||||
/* XXX top-level tree uses the ntree->execdata pointer */
|
||||
ntreeCompositEndExecTree(exec, 1);
|
||||
}
|
||||
|
||||
/* *********************************************** */
|
||||
|
@ -122,7 +122,7 @@ static void *group_initexec(bNode *node)
|
||||
bNodeStack *ns;
|
||||
|
||||
/* initialize the internal node tree execution */
|
||||
exec = ntreeCompositBeginExecTree(ngroup);
|
||||
exec = ntreeCompositBeginExecTree(ngroup, 0);
|
||||
|
||||
/* tag group outputs as external to prevent freeing */
|
||||
for (sock=ngroup->outputs.first; sock; sock=sock->next) {
|
||||
@ -139,7 +139,7 @@ static void group_freeexec(bNode *UNUSED(node), void *nodedata)
|
||||
{
|
||||
bNodeTreeExec *gexec= (bNodeTreeExec*)nodedata;
|
||||
|
||||
ntreeCompositEndExecTree(gexec);
|
||||
ntreeCompositEndExecTree(gexec, 0);
|
||||
}
|
||||
|
||||
/* Copy inputs to the internal stack.
|
||||
|
@ -422,7 +422,11 @@ static void verify_socket_template_list(bNodeTree *ntree, bNode *node, int in_ou
|
||||
void node_verify_socket_templates(bNodeTree *ntree, bNode *node)
|
||||
{
|
||||
bNodeType *ntype= node->typeinfo;
|
||||
if(ntype) {
|
||||
/* XXX Small trick: don't try to match socket lists when there are no templates.
|
||||
* This also prevents group node sockets from being removed, without the need to explicitly
|
||||
* check the node type here.
|
||||
*/
|
||||
if(ntype && ((ntype->inputs && ntype->inputs[0].type>=0) || (ntype->outputs && ntype->outputs[0].type>=0))) {
|
||||
verify_socket_template_list(ntree, node, SOCK_IN, &node->inputs, ntype->inputs);
|
||||
verify_socket_template_list(ntree, node, SOCK_OUT, &node->outputs, ntype->outputs);
|
||||
}
|
||||
|
@ -108,11 +108,11 @@ void ntreeGPUMaterialNodes(bNodeTree *ntree, GPUMaterial *mat)
|
||||
bNodeTreeExec *exec;
|
||||
|
||||
if(!ntree->execdata)
|
||||
exec = ntreeShaderBeginExecTree(ntree);
|
||||
exec = ntreeShaderBeginExecTree(ntree, 1);
|
||||
|
||||
ntreeExecGPUNodes(exec, mat, 1);
|
||||
|
||||
ntreeShaderEndExecTree(exec);
|
||||
ntreeShaderEndExecTree(exec, 1);
|
||||
}
|
||||
|
||||
/* **************** call to switch lamploop for material node ************ */
|
||||
@ -125,16 +125,21 @@ void set_node_shader_lamp_loop(void (*lamp_loop_func)(ShadeInput *, ShadeResult
|
||||
}
|
||||
|
||||
|
||||
bNodeTreeExec *ntreeShaderBeginExecTree(bNodeTree *ntree)
|
||||
/* XXX Group nodes must set use_tree_data to false, since their trees can be shared by multiple nodes.
|
||||
* If use_tree_data is true, the ntree->execdata pointer is checked to avoid multiple execution of top-level trees.
|
||||
*/
|
||||
bNodeTreeExec *ntreeShaderBeginExecTree(bNodeTree *ntree, int use_tree_data)
|
||||
{
|
||||
bNodeTreeExec *exec;
|
||||
bNode *node;
|
||||
|
||||
/* XXX hack: prevent exec data from being generated twice.
|
||||
* this should be handled by the renderer!
|
||||
*/
|
||||
if (ntree->execdata)
|
||||
return ntree->execdata;
|
||||
if (use_tree_data) {
|
||||
/* XXX hack: prevent exec data from being generated twice.
|
||||
* this should be handled by the renderer!
|
||||
*/
|
||||
if (ntree->execdata)
|
||||
return ntree->execdata;
|
||||
}
|
||||
|
||||
/* ensures only a single output node is enabled */
|
||||
ntreeSetOutput(ntree);
|
||||
@ -148,15 +153,20 @@ bNodeTreeExec *ntreeShaderBeginExecTree(bNodeTree *ntree)
|
||||
for(node= exec->nodetree->nodes.first; node; node= node->next)
|
||||
node->need_exec= 1;
|
||||
|
||||
/* XXX this should not be necessary, but is still used for cmp/sha/tex nodes,
|
||||
* which only store the ntree pointer. Should be fixed at some point!
|
||||
*/
|
||||
ntree->execdata = exec;
|
||||
if (use_tree_data) {
|
||||
/* XXX this should not be necessary, but is still used for cmp/sha/tex nodes,
|
||||
* which only store the ntree pointer. Should be fixed at some point!
|
||||
*/
|
||||
ntree->execdata = exec;
|
||||
}
|
||||
|
||||
return exec;
|
||||
}
|
||||
|
||||
void ntreeShaderEndExecTree(bNodeTreeExec *exec)
|
||||
/* XXX Group nodes must set use_tree_data to false, since their trees can be shared by multiple nodes.
|
||||
* If use_tree_data is true, the ntree->execdata pointer is checked to avoid multiple execution of top-level trees.
|
||||
*/
|
||||
void ntreeShaderEndExecTree(bNodeTreeExec *exec, int use_tree_data)
|
||||
{
|
||||
if(exec) {
|
||||
bNodeTree *ntree= exec->nodetree;
|
||||
@ -176,8 +186,10 @@ void ntreeShaderEndExecTree(bNodeTreeExec *exec)
|
||||
|
||||
ntree_exec_end(exec);
|
||||
|
||||
/* XXX clear nodetree backpointer to exec data, same problem as noted in ntreeBeginExecTree */
|
||||
ntree->execdata = NULL;
|
||||
if (use_tree_data) {
|
||||
/* XXX clear nodetree backpointer to exec data, same problem as noted in ntreeBeginExecTree */
|
||||
ntree->execdata = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -199,7 +211,7 @@ void ntreeShaderExecTree(bNodeTree *ntree, ShadeInput *shi, ShadeResult *shr)
|
||||
memset(shr, 0, sizeof(ShadeResult));
|
||||
|
||||
if (!exec)
|
||||
exec = ntree->execdata = ntreeShaderBeginExecTree(exec->nodetree);
|
||||
exec = ntree->execdata = ntreeShaderBeginExecTree(exec->nodetree, 1);
|
||||
|
||||
nts= ntreeGetThreadStack(exec, shi->thread);
|
||||
ntreeExecThreadNodes(exec, nts, &scd, shi->thread);
|
||||
|
@ -76,7 +76,7 @@ static void *group_initexec(bNode *node)
|
||||
bNodeTreeExec *exec;
|
||||
|
||||
/* initialize the internal node tree execution */
|
||||
exec = ntreeShaderBeginExecTree(ngroup);
|
||||
exec = ntreeShaderBeginExecTree(ngroup, 0);
|
||||
|
||||
return exec;
|
||||
}
|
||||
@ -85,7 +85,7 @@ static void group_freeexec(bNode *UNUSED(node), void *nodedata)
|
||||
{
|
||||
bNodeTreeExec*gexec= (bNodeTreeExec*)nodedata;
|
||||
|
||||
ntreeShaderEndExecTree(gexec);
|
||||
ntreeShaderEndExecTree(gexec, 0);
|
||||
}
|
||||
|
||||
/* Copy inputs to the internal stack.
|
||||
|
@ -121,16 +121,21 @@ int ntreeTexTagAnimated(bNodeTree *ntree)
|
||||
return 0;
|
||||
}
|
||||
|
||||
bNodeTreeExec *ntreeTexBeginExecTree(bNodeTree *ntree)
|
||||
/* XXX Group nodes must set use_tree_data to false, since their trees can be shared by multiple nodes.
|
||||
* If use_tree_data is true, the ntree->execdata pointer is checked to avoid multiple execution of top-level trees.
|
||||
*/
|
||||
bNodeTreeExec *ntreeTexBeginExecTree(bNodeTree *ntree, int use_tree_data)
|
||||
{
|
||||
bNodeTreeExec *exec;
|
||||
bNode *node;
|
||||
|
||||
/* XXX hack: prevent exec data from being generated twice.
|
||||
* this should be handled by the renderer!
|
||||
*/
|
||||
if (ntree->execdata)
|
||||
return ntree->execdata;
|
||||
if (use_tree_data) {
|
||||
/* XXX hack: prevent exec data from being generated twice.
|
||||
* this should be handled by the renderer!
|
||||
*/
|
||||
if (ntree->execdata)
|
||||
return ntree->execdata;
|
||||
}
|
||||
|
||||
/* common base initialization */
|
||||
exec = ntree_exec_begin(ntree);
|
||||
@ -141,10 +146,12 @@ bNodeTreeExec *ntreeTexBeginExecTree(bNodeTree *ntree)
|
||||
for(node= exec->nodetree->nodes.first; node; node= node->next)
|
||||
node->need_exec= 1;
|
||||
|
||||
/* XXX this should not be necessary, but is still used for cmp/sha/tex nodes,
|
||||
* which only store the ntree pointer. Should be fixed at some point!
|
||||
*/
|
||||
ntree->execdata = exec;
|
||||
if (use_tree_data) {
|
||||
/* XXX this should not be necessary, but is still used for cmp/sha/tex nodes,
|
||||
* which only store the ntree pointer. Should be fixed at some point!
|
||||
*/
|
||||
ntree->execdata = exec;
|
||||
}
|
||||
|
||||
return exec;
|
||||
}
|
||||
@ -163,7 +170,10 @@ static void tex_free_delegates(bNodeTreeExec *exec)
|
||||
MEM_freeN(ns->data);
|
||||
}
|
||||
|
||||
void ntreeTexEndExecTree(bNodeTreeExec *exec)
|
||||
/* XXX Group nodes must set use_tree_data to false, since their trees can be shared by multiple nodes.
|
||||
* If use_tree_data is true, the ntree->execdata pointer is checked to avoid multiple execution of top-level trees.
|
||||
*/
|
||||
void ntreeTexEndExecTree(bNodeTreeExec *exec, int use_tree_data)
|
||||
{
|
||||
if(exec) {
|
||||
bNodeTree *ntree= exec->nodetree;
|
||||
@ -185,8 +195,10 @@ void ntreeTexEndExecTree(bNodeTreeExec *exec)
|
||||
|
||||
ntree_exec_end(exec);
|
||||
|
||||
/* XXX clear nodetree backpointer to exec data, same problem as noted in ntreeBeginExecTree */
|
||||
ntree->execdata = NULL;
|
||||
if (use_tree_data) {
|
||||
/* XXX clear nodetree backpointer to exec data, same problem as noted in ntreeBeginExecTree */
|
||||
ntree->execdata = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -223,7 +235,7 @@ int ntreeTexExecTree(
|
||||
data.shi= shi;
|
||||
|
||||
if (!exec)
|
||||
exec = ntreeTexBeginExecTree(nodes);
|
||||
exec = ntreeTexBeginExecTree(nodes, 1);
|
||||
|
||||
nts= ntreeGetThreadStack(exec, thread);
|
||||
ntreeExecThreadNodes(exec, nts, &data, thread);
|
||||
|
@ -61,7 +61,7 @@ static void *group_initexec(bNode *node)
|
||||
void *exec;
|
||||
|
||||
/* initialize the internal node tree execution */
|
||||
exec = ntreeTexBeginExecTree(ngroup);
|
||||
exec = ntreeTexBeginExecTree(ngroup, 0);
|
||||
|
||||
return exec;
|
||||
}
|
||||
@ -70,7 +70,7 @@ static void group_freeexec(bNode *UNUSED(node), void *nodedata)
|
||||
{
|
||||
bNodeTreeExec*gexec= (bNodeTreeExec*)nodedata;
|
||||
|
||||
ntreeTexEndExecTree(gexec);
|
||||
ntreeTexEndExecTree(gexec, 0);
|
||||
}
|
||||
|
||||
/* Copy inputs to the internal stack.
|
||||
|
@ -344,7 +344,7 @@ void bpy_text_clear_modules(int clear_all)
|
||||
|
||||
/* looping over the dict */
|
||||
PyObject *key, *value;
|
||||
int pos= 0;
|
||||
Py_ssize_t pos= 0;
|
||||
|
||||
/* new list */
|
||||
PyObject *list;
|
||||
@ -374,7 +374,7 @@ void bpy_text_clear_modules(int clear_all)
|
||||
}
|
||||
|
||||
/* remove all our modules */
|
||||
for(pos=0; pos < PyList_Size(list); pos++) {
|
||||
for(pos=0; pos < PyList_GET_SIZE(list); pos++) {
|
||||
/* PyObject_Print(key, stderr, 0); */
|
||||
key= PyList_GET_ITEM(list, pos);
|
||||
PyDict_DelItem(modules, key);
|
||||
|
@ -4608,7 +4608,7 @@ static PyObject *pyrna_func_call(BPy_FunctionRNA *self, PyObject *args, PyObject
|
||||
|
||||
|
||||
#ifdef DEBUG_STRING_FREE
|
||||
// if(PyList_Size(string_free_ls)) printf("%.200s.%.200s(): has %d strings\n", RNA_struct_identifier(self_ptr->type), RNA_function_identifier(self_func), (int)PyList_Size(string_free_ls));
|
||||
// if(PyList_GET_SIZE(string_free_ls)) printf("%.200s.%.200s(): has %d strings\n", RNA_struct_identifier(self_ptr->type), RNA_function_identifier(self_func), (int)PyList_GET_SIZE(string_free_ls));
|
||||
Py_DECREF(string_free_ls);
|
||||
#undef DEBUG_STRING_FREE
|
||||
#endif
|
||||
|
@ -983,7 +983,7 @@ static PyObject *M_Geometry_tesselate_polygon(PyObject *UNUSED(self), PyObject *
|
||||
|
||||
static int boxPack_FromPyObject(PyObject *value, boxPack **boxarray)
|
||||
{
|
||||
int len, i;
|
||||
Py_ssize_t len, i;
|
||||
PyObject *list_item, *item_1, *item_2;
|
||||
boxPack *box;
|
||||
|
||||
@ -995,14 +995,14 @@ static int boxPack_FromPyObject(PyObject *value, boxPack **boxarray)
|
||||
return -1;
|
||||
}
|
||||
|
||||
len= PyList_Size(value);
|
||||
len= PyList_GET_SIZE(value);
|
||||
|
||||
(*boxarray)= MEM_mallocN(len*sizeof(boxPack), "boxPack box");
|
||||
|
||||
|
||||
for(i= 0; i < len; i++) {
|
||||
list_item= PyList_GET_ITEM(value, i);
|
||||
if(!PyList_Check(list_item) || PyList_Size(list_item) < 4) {
|
||||
if(!PyList_Check(list_item) || PyList_GET_SIZE(list_item) < 4) {
|
||||
MEM_freeN(*boxarray);
|
||||
PyErr_SetString(PyExc_TypeError,
|
||||
"can only pack a list of [x, y, w, h]");
|
||||
@ -1034,11 +1034,11 @@ static int boxPack_FromPyObject(PyObject *value, boxPack **boxarray)
|
||||
|
||||
static void boxPack_ToPyObject(PyObject *value, boxPack **boxarray)
|
||||
{
|
||||
int len, i;
|
||||
Py_ssize_t len, i;
|
||||
PyObject *list_item;
|
||||
boxPack *box;
|
||||
|
||||
len= PyList_Size(value);
|
||||
len= PyList_GET_SIZE(value);
|
||||
|
||||
for(i= 0; i < len; i++) {
|
||||
box= (*boxarray)+i;
|
||||
@ -1062,7 +1062,7 @@ PyDoc_STRVAR(M_Geometry_box_pack_2d_doc,
|
||||
static PyObject *M_Geometry_box_pack_2d(PyObject *UNUSED(self), PyObject *boxlist)
|
||||
{
|
||||
float tot_width= 0.0f, tot_height= 0.0f;
|
||||
int len;
|
||||
Py_ssize_t len;
|
||||
|
||||
PyObject *ret;
|
||||
|
||||
|
@ -125,7 +125,7 @@ static void init_render_texture(Render *re, Tex *tex)
|
||||
}
|
||||
|
||||
if(tex->nodetree && tex->use_nodes) {
|
||||
ntreeTexBeginExecTree(tex->nodetree); /* has internal flag to detect it only does it once */
|
||||
ntreeTexBeginExecTree(tex->nodetree, 1); /* has internal flag to detect it only does it once */
|
||||
}
|
||||
}
|
||||
|
||||
@ -145,7 +145,7 @@ void init_render_textures(Render *re)
|
||||
static void end_render_texture(Tex *tex)
|
||||
{
|
||||
if(tex && tex->use_nodes && tex->nodetree && tex->nodetree->execdata)
|
||||
ntreeTexEndExecTree(tex->nodetree->execdata);
|
||||
ntreeTexEndExecTree(tex->nodetree->execdata, 1);
|
||||
}
|
||||
|
||||
void end_render_textures(Render *re)
|
||||
|
@ -507,9 +507,10 @@ extern "C" void StartKetsjiShell(struct bContext *C, struct ARegion *ar, rcti *c
|
||||
//PyDict_Clear(PyModule_GetDict(gameLogic));
|
||||
|
||||
// Keep original items, means python plugins will autocomplete members
|
||||
int listIndex;
|
||||
PyObject *gameLogic_keys_new = PyDict_Keys(PyModule_GetDict(gameLogic));
|
||||
for (listIndex=0; listIndex < PyList_Size(gameLogic_keys_new); listIndex++) {
|
||||
const Py_ssize_t numitems= PyList_GET_SIZE(gameLogic_keys_new);
|
||||
Py_ssize_t listIndex;
|
||||
for (listIndex=0; listIndex < numitems; listIndex++) {
|
||||
PyObject* item = PyList_GET_ITEM(gameLogic_keys_new, listIndex);
|
||||
if (!PySequence_Contains(gameLogic_keys, item)) {
|
||||
PyDict_DelItem( PyModule_GetDict(gameLogic), item);
|
||||
|
@ -413,14 +413,21 @@ void BL_ConvertActuators(char* maggiename,
|
||||
// if sound shall be 3D but isn't mono, we have to make it mono!
|
||||
if(is3d)
|
||||
{
|
||||
AUD_Reference<AUD_IReader> reader = snd_sound->createReader();
|
||||
if(reader->getSpecs().channels != AUD_CHANNELS_MONO)
|
||||
try
|
||||
{
|
||||
AUD_DeviceSpecs specs;
|
||||
specs.channels = AUD_CHANNELS_MONO;
|
||||
specs.rate = AUD_RATE_INVALID;
|
||||
specs.format = AUD_FORMAT_INVALID;
|
||||
snd_sound = new AUD_ChannelMapperFactory(snd_sound, specs);
|
||||
AUD_Reference<AUD_IReader> reader = snd_sound->createReader();
|
||||
if(reader->getSpecs().channels != AUD_CHANNELS_MONO)
|
||||
{
|
||||
AUD_DeviceSpecs specs;
|
||||
specs.channels = AUD_CHANNELS_MONO;
|
||||
specs.rate = AUD_RATE_INVALID;
|
||||
specs.format = AUD_FORMAT_INVALID;
|
||||
snd_sound = new AUD_ChannelMapperFactory(snd_sound, specs);
|
||||
}
|
||||
}
|
||||
catch(AUD_Exception&)
|
||||
{
|
||||
// sound cannot be played... ignore
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -387,7 +387,7 @@ PyObject* listvalue_buffer_slice(PyObject* self,Py_ssize_t ilow, Py_ssize_t ihig
|
||||
static PyObject *listvalue_buffer_concat(PyObject * self, PyObject * other)
|
||||
{
|
||||
CListValue *listval= static_cast<CListValue *>(BGE_PROXY_REF(self));
|
||||
int i, numitems, numitems_orig;
|
||||
Py_ssize_t i, numitems, numitems_orig;
|
||||
|
||||
if (listval==NULL) {
|
||||
PyErr_SetString(PyExc_SystemError, "CList+other, "BGE_PROXY_ERROR_MSG);
|
||||
@ -408,7 +408,7 @@ static PyObject *listvalue_buffer_concat(PyObject * self, PyObject * other)
|
||||
CValue* listitemval;
|
||||
bool error = false;
|
||||
|
||||
numitems = PyList_Size(other);
|
||||
numitems = PyList_GET_SIZE(other);
|
||||
|
||||
/* copy the first part of the list */
|
||||
listval_new->Resize(numitems_orig + numitems);
|
||||
|
@ -546,8 +546,8 @@ CValue* CValue::ConvertPythonToValue(PyObject* pyobj, const char *error_prefix)
|
||||
CListValue* listval = new CListValue();
|
||||
bool error = false;
|
||||
|
||||
int i;
|
||||
int numitems = PyList_Size(pyobj);
|
||||
Py_ssize_t i;
|
||||
Py_ssize_t numitems = PyList_GET_SIZE(pyobj);
|
||||
for (i=0;i<numitems;i++)
|
||||
{
|
||||
PyObject* listitem = PyList_GetItem(pyobj,i); /* borrowed ref */
|
||||
|
@ -725,7 +725,7 @@ static PyObject *gLibNew(PyObject*, PyObject* args)
|
||||
if(idcode==ID_ME) {
|
||||
PyObject *ret= PyList_New(0);
|
||||
PyObject *item;
|
||||
for(int i= 0; i < PyList_GET_SIZE(names); i++) {
|
||||
for(Py_ssize_t i= 0; i < PyList_GET_SIZE(names); i++) {
|
||||
name= _PyUnicode_AsString(PyList_GET_ITEM(names, i));
|
||||
if(name) {
|
||||
RAS_MeshObject *meshobj= kx_scene->GetSceneConverter()->ConvertMeshSpecial(kx_scene, maggie, name);
|
||||
@ -1751,7 +1751,7 @@ static void initPySysObjects(Main *maggie)
|
||||
|
||||
initPySysObjects__append(sys_path, gp_GamePythonPath);
|
||||
|
||||
// fprintf(stderr, "\nNew Path: %d ", PyList_Size(sys_path));
|
||||
// fprintf(stderr, "\nNew Path: %d ", PyList_GET_SIZE(sys_path));
|
||||
// PyObject_Print(sys_path, stderr, 0);
|
||||
}
|
||||
|
||||
@ -1775,7 +1775,7 @@ static void restorePySysObjects(void)
|
||||
gp_OrigPythonSysModules= NULL;
|
||||
|
||||
|
||||
// fprintf(stderr, "\nRestore Path: %d ", PyList_Size(sys_path));
|
||||
// fprintf(stderr, "\nRestore Path: %d ", PyList_GET_SIZE(sys_path));
|
||||
// PyObject_Print(sys_path, stderr, 0);
|
||||
}
|
||||
|
||||
|
@ -1916,7 +1916,7 @@ void KX_Scene::Render2DFilters(RAS_ICanvas* canvas)
|
||||
|
||||
void KX_Scene::RunDrawingCallbacks(PyObject* cb_list)
|
||||
{
|
||||
int len;
|
||||
Py_ssize_t len;
|
||||
|
||||
if (cb_list && (len=PyList_GET_SIZE(cb_list)))
|
||||
{
|
||||
@ -1925,7 +1925,7 @@ void KX_Scene::RunDrawingCallbacks(PyObject* cb_list)
|
||||
PyObject* ret;
|
||||
|
||||
// Iterate the list and run the callbacks
|
||||
for (int pos=0; pos < len; pos++)
|
||||
for (Py_ssize_t pos=0; pos < len; pos++)
|
||||
{
|
||||
func= PyList_GET_ITEM(cb_list, pos);
|
||||
ret= PyObject_Call(func, args, NULL);
|
||||
|
@ -108,7 +108,15 @@ void KX_SoundActuator::play()
|
||||
break;
|
||||
}
|
||||
|
||||
m_handle = AUD_getDevice()->play(sound, 0);
|
||||
try
|
||||
{
|
||||
m_handle = AUD_getDevice()->play(sound, 0);
|
||||
}
|
||||
catch(AUD_Exception&)
|
||||
{
|
||||
// cannot play back, ignore
|
||||
return;
|
||||
}
|
||||
|
||||
AUD_Reference<AUD_I3DHandle> handle3d = AUD_Reference<AUD_I3DHandle>(m_handle);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user