This commit is contained in:
Campbell Barton 2011-09-07 00:46:11 +00:00
commit a167ee1262
60 changed files with 994 additions and 389 deletions

@ -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.

@ -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();
}

@ -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}
};

@ -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);