diff options
author | Bastien Montagne <montagne29@wanadoo.fr> | 2011-09-07 09:40:12 +0400 |
---|---|---|
committer | Bastien Montagne <montagne29@wanadoo.fr> | 2011-09-07 09:40:12 +0400 |
commit | bac64b39e91f9da10f2b79db8fafecaf9c45a4e7 (patch) | |
tree | 58e40312855dfaf9d367ec6e23a9e1faed968426 /source | |
parent | c64336390569a344f972ce41d8a1fb96d3c9c38f (diff) | |
parent | 9161d3ce4bdd7c838751462b47eb045ea33a686e (diff) |
Merging r39948 through r39988 from trunk into vgroup_modifiers.vgroup_modifiers
Diffstat (limited to 'source')
54 files changed, 959 insertions, 381 deletions
diff --git a/source/blender/blenkernel/BKE_global.h b/source/blender/blenkernel/BKE_global.h index 17876c6ec9d..0e48673f1b1 100644 --- a/source/blender/blenkernel/BKE_global.h +++ b/source/blender/blenkernel/BKE_global.h @@ -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 */ diff --git a/source/blender/blenkernel/BKE_node.h b/source/blender/blenkernel/BKE_node.h index 7207fb7d0fb..1de3c295f4d 100644 --- a/source/blender/blenkernel/BKE_node.h +++ b/source/blender/blenkernel/BKE_node.h @@ -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); diff --git a/source/blender/blenkernel/intern/blender.c b/source/blender/blenkernel/intern/blender.c index 5f33059e117..2d4354bdd9f 100644 --- a/source/blender/blenkernel/intern/blender.c +++ b/source/blender/blenkernel/intern/blender.c @@ -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; diff --git a/source/blender/blenkernel/intern/material.c b/source/blender/blenkernel/intern/material.c index 36631d5af90..aab8e1abbea 100644 --- a/source/blender/blenkernel/intern/material.c +++ b/source/blender/blenkernel/intern/material.c @@ -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); } } diff --git a/source/blender/blenkernel/intern/node.c b/source/blender/blenkernel/intern/node.c index 481893b86a8..292f38b9472 100644 --- a/source/blender/blenkernel/intern/node.c +++ b/source/blender/blenkernel/intern/node.c @@ -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) { diff --git a/source/blender/blenkernel/intern/texture.c b/source/blender/blenkernel/intern/texture.c index 6119a855366..38165182d83 100644 --- a/source/blender/blenkernel/intern/texture.c +++ b/source/blender/blenkernel/intern/texture.c @@ -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); } diff --git a/source/blender/blenlib/intern/string.c b/source/blender/blenlib/intern/string.c index c4ed44f0cdb..ae5fa40f3b9 100644 --- a/source/blender/blenlib/intern/string.c +++ b/source/blender/blenlib/intern/string.c @@ -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; diff --git a/source/blender/blenloader/BLO_sys_types.h b/source/blender/blenloader/BLO_sys_types.h index 2114fc34bf1..4b3902dca43 100644 --- a/source/blender/blenloader/BLO_sys_types.h +++ b/source/blender/blenloader/BLO_sys_types.h @@ -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__) diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index 5518e133daf..eb5d6a6fbcb 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -2217,8 +2217,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); @@ -7022,6 +7023,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 */ @@ -11979,6 +11989,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 */ diff --git a/source/blender/blenloader/intern/writefile.c b/source/blender/blenloader/intern/writefile.c index c3f51dc6ce4..3b736e8aeae 100644 --- a/source/blender/blenloader/intern/writefile.c +++ b/source/blender/blenloader/intern/writefile.c @@ -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); diff --git a/source/blender/collada/CMakeLists.txt b/source/blender/collada/CMakeLists.txt index d73373aa901..cc7229383e3 100644 --- a/source/blender/collada/CMakeLists.txt +++ b/source/blender/collada/CMakeLists.txt @@ -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 diff --git a/source/blender/collada/DocumentExporter.cpp b/source/blender/collada/DocumentExporter.cpp index 6e780889d16..85f37d29f22 100644 --- a/source/blender/collada/DocumentExporter.cpp +++ b/source/blender/collada/DocumentExporter.cpp @@ -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. diff --git a/source/blender/collada/SceneExporter.cpp b/source/blender/collada/SceneExporter.cpp new file mode 100644 index 00000000000..96f20ac21c3 --- /dev/null +++ b/source/blender/collada/SceneExporter.cpp @@ -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(); +} + diff --git a/source/blender/collada/SceneExporter.h b/source/blender/collada/SceneExporter.h new file mode 100644 index 00000000000..30fef924ffd --- /dev/null +++ b/source/blender/collada/SceneExporter.h @@ -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 diff --git a/source/blender/editors/gpencil/CMakeLists.txt b/source/blender/editors/gpencil/CMakeLists.txt index 7a2f196fd6d..b312f397939 100644 --- a/source/blender/editors/gpencil/CMakeLists.txt +++ b/source/blender/editors/gpencil/CMakeLists.txt @@ -42,6 +42,7 @@ set(SRC gpencil_edit.c gpencil_ops.c gpencil_paint.c + gpencil_undo.c gpencil_intern.h ) diff --git a/source/blender/editors/gpencil/drawgpencil.c b/source/blender/editors/gpencil/drawgpencil.c index 440d5ee7c4d..cfa9585868e 100644 --- a/source/blender/editors/gpencil/drawgpencil.c +++ b/source/blender/editors/gpencil/drawgpencil.c @@ -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. */ diff --git a/source/blender/editors/gpencil/gpencil_edit.c b/source/blender/editors/gpencil/gpencil_edit.c index 9dc764b7aac..1cd8b1f05db 100644 --- a/source/blender/editors/gpencil/gpencil_edit.c +++ b/source/blender/editors/gpencil/gpencil_edit.c @@ -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); } } diff --git a/source/blender/editors/gpencil/gpencil_intern.h b/source/blender/editors/gpencil/gpencil_intern.h index c31de8d30a7..8000af54f53 100644 --- a/source/blender/editors/gpencil/gpencil_intern.h +++ b/source/blender/editors/gpencil/gpencil_intern.h @@ -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! */ diff --git a/source/blender/editors/gpencil/gpencil_ops.c b/source/blender/editors/gpencil/gpencil_ops.c index e1e4c8d5457..150e0ba90e4 100644 --- a/source/blender/editors/gpencil/gpencil_ops.c +++ b/source/blender/editors/gpencil/gpencil_ops.c @@ -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); diff --git a/source/blender/editors/gpencil/gpencil_paint.c b/source/blender/editors/gpencil/gpencil_paint.c index 04565eab155..a23f2064a9e 100644 --- a/source/blender/editors/gpencil/gpencil_paint.c +++ b/source/blender/editors/gpencil/gpencil_paint.c @@ -124,6 +124,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 */ }; /* ------ */ @@ -152,7 +153,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"); @@ -375,6 +376,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; @@ -395,7 +442,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 */ @@ -527,17 +574,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 */ @@ -565,6 +623,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; @@ -643,6 +711,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); } @@ -891,10 +961,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; @@ -903,24 +977,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); @@ -942,7 +1013,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? @@ -951,7 +1022,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 } @@ -972,7 +1043,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 } @@ -992,13 +1063,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; @@ -1019,7 +1090,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 } @@ -1031,7 +1102,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; } @@ -1042,7 +1113,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 */ @@ -1051,8 +1122,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); @@ -1062,6 +1136,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; @@ -1078,6 +1165,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; } @@ -1247,7 +1335,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) @@ -1260,8 +1349,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)); @@ -1592,6 +1681,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; @@ -1609,16 +1699,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; @@ -1646,17 +1777,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"); @@ -1664,35 +1802,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? */ @@ -1704,7 +1826,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 { @@ -1721,28 +1843,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)) @@ -1778,6 +1878,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} }; diff --git a/source/blender/editors/gpencil/gpencil_undo.c b/source/blender/editors/gpencil/gpencil_undo.c new file mode 100644 index 00000000000..1154975e3cc --- /dev/null +++ b/source/blender/editors/gpencil/gpencil_undo.c @@ -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; +} diff --git a/source/blender/editors/include/ED_gpencil.h b/source/blender/editors/include/ED_gpencil.h index 07dcc959e32..bfd16487ae5 100644 --- a/source/blender/editors/include/ED_gpencil.h +++ b/source/blender/editors/include/ED_gpencil.h @@ -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 */ diff --git a/source/blender/editors/sculpt_paint/paint_image.c b/source/blender/editors/sculpt_paint/paint_image.c index 9539706468f..79a3251cdf1 100644 --- a/source/blender/editors/sculpt_paint/paint_image.c +++ b/source/blender/editors/sculpt_paint/paint_image.c @@ -4664,7 +4664,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 */ } } @@ -4806,7 +4806,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); } } diff --git a/source/blender/editors/sculpt_paint/sculpt.c b/source/blender/editors/sculpt_paint/sculpt.c index bf34a3b8c9f..ced3dd00a9c 100644 --- a/source/blender/editors/sculpt_paint/sculpt.c +++ b/source/blender/editors/sculpt_paint/sculpt.c @@ -3274,7 +3274,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 @@ -3455,7 +3455,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)) diff --git a/source/blender/editors/space_node/drawnode.c b/source/blender/editors/space_node/drawnode.c index 890b04dce91..0d2ec7c646f 100644 --- a/source/blender/editors/space_node/drawnode.c +++ b/source/blender/editors/space_node/drawnode.c @@ -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 */ diff --git a/source/blender/editors/space_node/node_header.c b/source/blender/editors/space_node/node_header.c index 5c921d40344..7077f4a7497 100644 --- a/source/blender/editors/space_node/node_header.c +++ b/source/blender/editors/space_node/node_header.c @@ -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)); } } diff --git a/source/blender/editors/transform/transform.c b/source/blender/editors/transform/transform.c index 09507194969..1796bd4e928 100644 --- a/source/blender/editors/transform/transform.c +++ b/source/blender/editors/transform/transform.c @@ -1678,7 +1678,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; diff --git a/source/blender/editors/util/undo.c b/source/blender/editors/util/undo.c index a2381a208ef..c1aca61f795 100644 --- a/source/blender/editors/util/undo.c +++ b/source/blender/editors/util/undo.c @@ -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; diff --git a/source/blender/makesdna/DNA_node_types.h b/source/blender/makesdna/DNA_node_types.h index 3a51a6a56a4..bac1e3cd8ca 100644 --- a/source/blender/makesdna/DNA_node_types.h +++ b/source/blender/makesdna/DNA_node_types.h @@ -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 */ diff --git a/source/blender/makesrna/intern/rna_access.c b/source/blender/makesrna/intern/rna_access.c index 936f2e5e40c..e7d0c5cdec2 100644 --- a/source/blender/makesrna/intern/rna_access.c +++ b/source/blender/makesrna/intern/rna_access.c @@ -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); diff --git a/source/blender/makesrna/intern/rna_internal.h b/source/blender/makesrna/intern/rna_internal.h index 9e98f166875..78b8c67d92c 100644 --- a/source/blender/makesrna/intern/rna_internal.h +++ b/source/blender/makesrna/intern/rna_internal.h @@ -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 */ diff --git a/source/blender/makesrna/intern/rna_screen.c b/source/blender/makesrna/intern/rna_screen.c index 59707f05e6f..bd1021f038a 100644 --- a/source/blender/makesrna/intern/rna_screen.c +++ b/source/blender/makesrna/intern/rna_screen.c @@ -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 */ diff --git a/source/blender/makesrna/intern/rna_texture.c b/source/blender/makesrna/intern/rna_texture.c index 503212201c4..890be76c49a 100644 --- a/source/blender/makesrna/intern/rna_texture.c +++ b/source/blender/makesrna/intern/rna_texture.c @@ -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) diff --git a/source/blender/makesrna/intern/rna_texture_api.c b/source/blender/makesrna/intern/rna_texture_api.c index 8d4b73f1f0c..8c63d5da8fd 100644 --- a/source/blender/makesrna/intern/rna_texture_api.c +++ b/source/blender/makesrna/intern/rna_texture_api.c @@ -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_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); + 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 diff --git a/source/blender/makesrna/intern/rna_wm.c b/source/blender/makesrna/intern/rna_wm.c index a595b121d1a..7ce1e1ab88f 100644 --- a/source/blender/makesrna/intern/rna_wm.c +++ b/source/blender/makesrna/intern/rna_wm.c @@ -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"); } diff --git a/source/blender/makesrna/intern/rna_world.c b/source/blender/makesrna/intern/rna_world.c index 72b54dce473..11ec327c306 100644 --- a/source/blender/makesrna/intern/rna_world.c +++ b/source/blender/makesrna/intern/rna_world.c @@ -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"); diff --git a/source/blender/nodes/composite/node_composite_tree.c b/source/blender/nodes/composite/node_composite_tree.c index 0ea62b0aa5f..4fc5e23e26a 100644 --- a/source/blender/nodes/composite/node_composite_tree.c +++ b/source/blender/nodes/composite/node_composite_tree.c @@ -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); } /* *********************************************** */ diff --git a/source/blender/nodes/composite/nodes/node_composite_common.c b/source/blender/nodes/composite/nodes/node_composite_common.c index fbff8198dde..d5ae442c25f 100644 --- a/source/blender/nodes/composite/nodes/node_composite_common.c +++ b/source/blender/nodes/composite/nodes/node_composite_common.c @@ -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. diff --git a/source/blender/nodes/intern/node_socket.c b/source/blender/nodes/intern/node_socket.c index 3ea34dd094a..aabaf5b86de 100644 --- a/source/blender/nodes/intern/node_socket.c +++ b/source/blender/nodes/intern/node_socket.c @@ -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); } diff --git a/source/blender/nodes/shader/node_shader_tree.c b/source/blender/nodes/shader/node_shader_tree.c index 8cb1ebeb15f..642e4be10d7 100644 --- a/source/blender/nodes/shader/node_shader_tree.c +++ b/source/blender/nodes/shader/node_shader_tree.c @@ -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); diff --git a/source/blender/nodes/shader/nodes/node_shader_common.c b/source/blender/nodes/shader/nodes/node_shader_common.c index aa8e8241bf8..2dd15ab1e99 100644 --- a/source/blender/nodes/shader/nodes/node_shader_common.c +++ b/source/blender/nodes/shader/nodes/node_shader_common.c @@ -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. diff --git a/source/blender/nodes/texture/node_texture_tree.c b/source/blender/nodes/texture/node_texture_tree.c index 3ea15a316ab..603aa7ceb77 100644 --- a/source/blender/nodes/texture/node_texture_tree.c +++ b/source/blender/nodes/texture/node_texture_tree.c @@ -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); diff --git a/source/blender/nodes/texture/nodes/node_texture_common.c b/source/blender/nodes/texture/nodes/node_texture_common.c index afb24226416..1b46b830909 100644 --- a/source/blender/nodes/texture/nodes/node_texture_common.c +++ b/source/blender/nodes/texture/nodes/node_texture_common.c @@ -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. diff --git a/source/blender/python/generic/bpy_internal_import.c b/source/blender/python/generic/bpy_internal_import.c index f0158fe72c3..67ed90c79eb 100644 --- a/source/blender/python/generic/bpy_internal_import.c +++ b/source/blender/python/generic/bpy_internal_import.c @@ -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); diff --git a/source/blender/python/intern/bpy_rna.c b/source/blender/python/intern/bpy_rna.c index d10c8c843e8..2212499d842 100644 --- a/source/blender/python/intern/bpy_rna.c +++ b/source/blender/python/intern/bpy_rna.c @@ -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 diff --git a/source/blender/python/mathutils/mathutils_geometry.c b/source/blender/python/mathutils/mathutils_geometry.c index bcdfe020e1a..0394d732ae3 100644 --- a/source/blender/python/mathutils/mathutils_geometry.c +++ b/source/blender/python/mathutils/mathutils_geometry.c @@ -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; diff --git a/source/blender/render/intern/source/render_texture.c b/source/blender/render/intern/source/render_texture.c index e35b3e53f5b..cf1fae81eb5 100644 --- a/source/blender/render/intern/source/render_texture.c +++ b/source/blender/render/intern/source/render_texture.c @@ -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) diff --git a/source/gameengine/BlenderRoutines/BL_KetsjiEmbedStart.cpp b/source/gameengine/BlenderRoutines/BL_KetsjiEmbedStart.cpp index 40f1701e44a..810e9b6ddfb 100644 --- a/source/gameengine/BlenderRoutines/BL_KetsjiEmbedStart.cpp +++ b/source/gameengine/BlenderRoutines/BL_KetsjiEmbedStart.cpp @@ -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); diff --git a/source/gameengine/Converter/KX_ConvertActuators.cpp b/source/gameengine/Converter/KX_ConvertActuators.cpp index 8fc224fba6f..6ba178cbb2f 100644 --- a/source/gameengine/Converter/KX_ConvertActuators.cpp +++ b/source/gameengine/Converter/KX_ConvertActuators.cpp @@ -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 } } } diff --git a/source/gameengine/Expressions/ListValue.cpp b/source/gameengine/Expressions/ListValue.cpp index 271d5067dd9..934f2a8dd87 100644 --- a/source/gameengine/Expressions/ListValue.cpp +++ b/source/gameengine/Expressions/ListValue.cpp @@ -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); diff --git a/source/gameengine/Expressions/Value.cpp b/source/gameengine/Expressions/Value.cpp index e60b380e95c..41c0850a779 100644 --- a/source/gameengine/Expressions/Value.cpp +++ b/source/gameengine/Expressions/Value.cpp @@ -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 */ diff --git a/source/gameengine/Ketsji/KX_PythonInit.cpp b/source/gameengine/Ketsji/KX_PythonInit.cpp index 395e2048cb7..f14d73cb990 100644 --- a/source/gameengine/Ketsji/KX_PythonInit.cpp +++ b/source/gameengine/Ketsji/KX_PythonInit.cpp @@ -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); } diff --git a/source/gameengine/Ketsji/KX_Scene.cpp b/source/gameengine/Ketsji/KX_Scene.cpp index 06e343cedb2..7c76ab01e93 100644 --- a/source/gameengine/Ketsji/KX_Scene.cpp +++ b/source/gameengine/Ketsji/KX_Scene.cpp @@ -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); diff --git a/source/gameengine/Ketsji/KX_SoundActuator.cpp b/source/gameengine/Ketsji/KX_SoundActuator.cpp index 6c7b515c095..f24243fcdfc 100644 --- a/source/gameengine/Ketsji/KX_SoundActuator.cpp +++ b/source/gameengine/Ketsji/KX_SoundActuator.cpp @@ -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); |