forked from bartvdbraak/blender
svn merge ^/trunk/blender -r42680:42722
This commit is contained in:
commit
2457d4f5ab
@ -649,10 +649,6 @@ elseif(WIN32)
|
|||||||
set(ICONV_LIBPATH ${ICONV}/lib)
|
set(ICONV_LIBPATH ${ICONV}/lib)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
set(PNG "${LIBDIR}/png")
|
|
||||||
set(PNG_INCLUDE_DIR "${PNG}/include")
|
|
||||||
set(PNG_LIBPATH ${PNG}/lib) # not cmake defined
|
|
||||||
|
|
||||||
set(JPEG "${LIBDIR}/jpeg")
|
set(JPEG "${LIBDIR}/jpeg")
|
||||||
set(JPEG_INCLUDE_DIR "${JPEG}/include")
|
set(JPEG_INCLUDE_DIR "${JPEG}/include")
|
||||||
set(JPEG_LIBPATH ${JPEG}/lib) # not cmake defined
|
set(JPEG_LIBPATH ${JPEG}/lib) # not cmake defined
|
||||||
@ -734,6 +730,10 @@ elseif(WIN32)
|
|||||||
endif()
|
endif()
|
||||||
set(JPEG_LIBRARIES libjpeg)
|
set(JPEG_LIBRARIES libjpeg)
|
||||||
|
|
||||||
|
set(PNG "${LIBDIR}/png")
|
||||||
|
set(PNG_INCLUDE_DIR "${PNG}/include")
|
||||||
|
set(PNG_LIBPATH ${PNG}/lib) # not cmake defined
|
||||||
|
|
||||||
set(ZLIB_INCLUDE_DIRS ${LIBDIR}/zlib/include)
|
set(ZLIB_INCLUDE_DIRS ${LIBDIR}/zlib/include)
|
||||||
if(CMAKE_CL_64)
|
if(CMAKE_CL_64)
|
||||||
set(ZLIB_LIBRARIES ${LIBDIR}/zlib/lib/libz.lib)
|
set(ZLIB_LIBRARIES ${LIBDIR}/zlib/lib/libz.lib)
|
||||||
@ -914,6 +914,10 @@ elseif(WIN32)
|
|||||||
set(GETTEXT_LIBRARIES intl)
|
set(GETTEXT_LIBRARIES intl)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
set(PNG "${LIBDIR}/gcc/png")
|
||||||
|
set(PNG_INCLUDE_DIR "${PNG}/include")
|
||||||
|
set(PNG_LIBPATH ${PNG}/lib) # not cmake defined
|
||||||
|
|
||||||
set(JPEG_LIBRARIES libjpeg)
|
set(JPEG_LIBRARIES libjpeg)
|
||||||
set(PNG_LIBRARIES png)
|
set(PNG_LIBRARIES png)
|
||||||
|
|
||||||
|
@ -64,7 +64,7 @@ BF_JPEG_LIB = 'liblibjpeg'
|
|||||||
BF_JPEG_LIBPATH = '${BF_JPEG}/lib'
|
BF_JPEG_LIBPATH = '${BF_JPEG}/lib'
|
||||||
|
|
||||||
WITH_BF_PNG = True
|
WITH_BF_PNG = True
|
||||||
BF_PNG = LIBDIR + '/png'
|
BF_PNG = LIBDIR + 'gcc/png'
|
||||||
BF_PNG_INC = '${BF_PNG}/include'
|
BF_PNG_INC = '${BF_PNG}/include'
|
||||||
BF_PNG_LIB = 'png'
|
BF_PNG_LIB = 'png'
|
||||||
BF_PNG_LIBPATH = '${BF_PNG}/lib'
|
BF_PNG_LIBPATH = '${BF_PNG}/lib'
|
||||||
|
@ -50,28 +50,6 @@ void BlenderSync::find_shader(BL::ID id, vector<uint>& used_shaders, int default
|
|||||||
|
|
||||||
/* Graph */
|
/* Graph */
|
||||||
|
|
||||||
static BL::NodeSocket get_node_input(BL::Node *b_group_node, BL::NodeSocket b_in)
|
|
||||||
{
|
|
||||||
if(b_group_node) {
|
|
||||||
|
|
||||||
BL::NodeTree b_ntree = BL::NodeGroup(*b_group_node).node_tree();
|
|
||||||
BL::NodeTree::links_iterator b_link;
|
|
||||||
|
|
||||||
for(b_ntree.links.begin(b_link); b_link != b_ntree.links.end(); ++b_link) {
|
|
||||||
if(b_link->to_socket().ptr.data == b_in.ptr.data) {
|
|
||||||
BL::Node::inputs_iterator b_gin;
|
|
||||||
|
|
||||||
for(b_group_node->inputs.begin(b_gin); b_gin != b_group_node->inputs.end(); ++b_gin)
|
|
||||||
if(b_gin->group_socket().ptr.data == b_link->from_socket().ptr.data)
|
|
||||||
return *b_gin;
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return b_in;
|
|
||||||
}
|
|
||||||
|
|
||||||
static BL::NodeSocket get_node_output(BL::Node b_node, const string& name)
|
static BL::NodeSocket get_node_output(BL::Node b_node, const string& name)
|
||||||
{
|
{
|
||||||
BL::Node::outputs_iterator b_out;
|
BL::Node::outputs_iterator b_out;
|
||||||
@ -121,7 +99,7 @@ static void get_tex_mapping(TextureMapping *mapping, BL::ShaderNodeMapping b_map
|
|||||||
mapping->scale = get_float3(b_mapping.scale());
|
mapping->scale = get_float3(b_mapping.scale());
|
||||||
}
|
}
|
||||||
|
|
||||||
static ShaderNode *add_node(BL::BlendData b_data, ShaderGraph *graph, BL::Node *b_group_node, BL::ShaderNode b_node)
|
static ShaderNode *add_node(BL::BlendData b_data, ShaderGraph *graph, BL::ShaderNode b_node)
|
||||||
{
|
{
|
||||||
ShaderNode *node = NULL;
|
ShaderNode *node = NULL;
|
||||||
|
|
||||||
@ -470,37 +448,28 @@ static SocketPair node_socket_map_pair(PtrNodeMap& node_map, BL::Node b_node, BL
|
|||||||
return SocketPair(node_map[b_node.ptr.data], name);
|
return SocketPair(node_map[b_node.ptr.data], name);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void add_nodes(BL::BlendData b_data, ShaderGraph *graph, BL::ShaderNodeTree b_ntree, BL::Node *b_group_node, PtrSockMap& sockets_map)
|
static ShaderSocketType convert_socket_type(BL::NodeSocket::type_enum b_type)
|
||||||
{
|
{
|
||||||
/* add nodes */
|
switch (b_type) {
|
||||||
BL::ShaderNodeTree::nodes_iterator b_node;
|
case BL::NodeSocket::type_VALUE:
|
||||||
PtrNodeMap node_map;
|
return SHADER_SOCKET_FLOAT;
|
||||||
map<void*, PtrSockMap> node_groups;
|
case BL::NodeSocket::type_VECTOR:
|
||||||
|
return SHADER_SOCKET_VECTOR;
|
||||||
|
case BL::NodeSocket::type_RGBA:
|
||||||
|
return SHADER_SOCKET_COLOR;
|
||||||
|
case BL::NodeSocket::type_SHADER:
|
||||||
|
return SHADER_SOCKET_CLOSURE;
|
||||||
|
|
||||||
for(b_ntree.nodes.begin(b_node); b_node != b_ntree.nodes.end(); ++b_node) {
|
case BL::NodeSocket::type_BOOLEAN:
|
||||||
if(b_node->is_a(&RNA_NodeGroup)) {
|
case BL::NodeSocket::type_MESH:
|
||||||
BL::NodeGroup b_gnode(*b_node);
|
case BL::NodeSocket::type_INT:
|
||||||
BL::ShaderNodeTree b_group_ntree(b_gnode.node_tree());
|
default:
|
||||||
|
return SHADER_SOCKET_FLOAT;
|
||||||
node_groups[b_node->ptr.data] = PtrSockMap();
|
|
||||||
add_nodes(b_data, graph, b_group_ntree, &b_gnode, node_groups[b_node->ptr.data]);
|
|
||||||
}
|
}
|
||||||
else {
|
}
|
||||||
ShaderNode *node = add_node(b_data, graph, b_group_node, BL::ShaderNode(*b_node));
|
|
||||||
|
|
||||||
if(node) {
|
|
||||||
BL::Node::inputs_iterator b_input;
|
|
||||||
BL::Node::outputs_iterator b_output;
|
|
||||||
|
|
||||||
node_map[b_node->ptr.data] = node;
|
|
||||||
|
|
||||||
for(b_node->inputs.begin(b_input); b_input != b_node->inputs.end(); ++b_input) {
|
|
||||||
SocketPair pair = node_socket_map_pair(node_map, *b_node, *b_input);
|
|
||||||
ShaderInput *input = pair.first->input(pair.second.c_str());
|
|
||||||
BL::NodeSocket sock(get_node_input(b_group_node, *b_input));
|
|
||||||
|
|
||||||
assert(input);
|
|
||||||
|
|
||||||
|
static void set_default_value(ShaderInput *input, BL::NodeSocket sock)
|
||||||
|
{
|
||||||
/* copy values for non linked inputs */
|
/* copy values for non linked inputs */
|
||||||
switch(input->type) {
|
switch(input->type) {
|
||||||
case SHADER_SOCKET_FLOAT: {
|
case SHADER_SOCKET_FLOAT: {
|
||||||
@ -523,6 +492,71 @@ static void add_nodes(BL::BlendData b_data, ShaderGraph *graph, BL::ShaderNodeTr
|
|||||||
case SHADER_SOCKET_CLOSURE:
|
case SHADER_SOCKET_CLOSURE:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void add_nodes(BL::BlendData b_data, ShaderGraph *graph, BL::ShaderNodeTree b_ntree, PtrSockMap& sockets_map)
|
||||||
|
{
|
||||||
|
/* add nodes */
|
||||||
|
BL::ShaderNodeTree::nodes_iterator b_node;
|
||||||
|
PtrNodeMap node_map;
|
||||||
|
PtrSockMap proxy_map;
|
||||||
|
|
||||||
|
for(b_ntree.nodes.begin(b_node); b_node != b_ntree.nodes.end(); ++b_node) {
|
||||||
|
if(b_node->is_a(&RNA_NodeGroup)) {
|
||||||
|
/* add proxy converter nodes for inputs and outputs */
|
||||||
|
BL::NodeGroup b_gnode(*b_node);
|
||||||
|
BL::ShaderNodeTree b_group_ntree(b_gnode.node_tree());
|
||||||
|
BL::Node::inputs_iterator b_input;
|
||||||
|
BL::Node::outputs_iterator b_output;
|
||||||
|
|
||||||
|
PtrSockMap group_sockmap;
|
||||||
|
|
||||||
|
for(b_node->inputs.begin(b_input); b_input != b_node->inputs.end(); ++b_input) {
|
||||||
|
ShaderSocketType extern_type = convert_socket_type(b_input->type());
|
||||||
|
ShaderSocketType intern_type = convert_socket_type(b_input->group_socket().type());
|
||||||
|
ShaderNode *proxy = graph->add(new ProxyNode(extern_type, intern_type));
|
||||||
|
|
||||||
|
/* map the external node socket to the proxy node socket */
|
||||||
|
proxy_map[b_input->ptr.data] = SocketPair(proxy, proxy->inputs[0]->name);
|
||||||
|
/* map the internal group socket to the proxy node socket */
|
||||||
|
group_sockmap[b_input->group_socket().ptr.data] = SocketPair(proxy, proxy->outputs[0]->name);
|
||||||
|
|
||||||
|
/* default input values of the group node */
|
||||||
|
set_default_value(proxy->inputs[0], *b_input);
|
||||||
|
}
|
||||||
|
|
||||||
|
for(b_node->outputs.begin(b_output); b_output != b_node->outputs.end(); ++b_output) {
|
||||||
|
ShaderSocketType extern_type = convert_socket_type(b_output->type());
|
||||||
|
ShaderSocketType intern_type = convert_socket_type(b_output->group_socket().type());
|
||||||
|
ShaderNode *proxy = graph->add(new ProxyNode(intern_type, extern_type));
|
||||||
|
|
||||||
|
/* map the external node socket to the proxy node socket */
|
||||||
|
proxy_map[b_output->ptr.data] = SocketPair(proxy, proxy->outputs[0]->name);
|
||||||
|
/* map the internal group socket to the proxy node socket */
|
||||||
|
group_sockmap[b_output->group_socket().ptr.data] = SocketPair(proxy, proxy->inputs[0]->name);
|
||||||
|
|
||||||
|
/* default input values of internal, unlinked group outputs */
|
||||||
|
set_default_value(proxy->inputs[0], b_output->group_socket());
|
||||||
|
}
|
||||||
|
|
||||||
|
add_nodes(b_data, graph, b_group_ntree, group_sockmap);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
ShaderNode *node = add_node(b_data, graph, BL::ShaderNode(*b_node));
|
||||||
|
|
||||||
|
if(node) {
|
||||||
|
BL::Node::inputs_iterator b_input;
|
||||||
|
|
||||||
|
node_map[b_node->ptr.data] = node;
|
||||||
|
|
||||||
|
for(b_node->inputs.begin(b_input); b_input != b_node->inputs.end(); ++b_input) {
|
||||||
|
SocketPair pair = node_socket_map_pair(node_map, *b_node, *b_input);
|
||||||
|
ShaderInput *input = pair.first->input(pair.second.c_str());
|
||||||
|
|
||||||
|
assert(input);
|
||||||
|
|
||||||
|
/* copy values for non linked inputs */
|
||||||
|
set_default_value(input, *b_input);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -539,55 +573,35 @@ static void add_nodes(BL::BlendData b_data, ShaderGraph *graph, BL::ShaderNodeTr
|
|||||||
BL::NodeSocket b_from_sock = b_link->from_socket();
|
BL::NodeSocket b_from_sock = b_link->from_socket();
|
||||||
BL::NodeSocket b_to_sock = b_link->to_socket();
|
BL::NodeSocket b_to_sock = b_link->to_socket();
|
||||||
|
|
||||||
/* if link with group socket, add to map so we can connect it later */
|
|
||||||
if(b_group_node) {
|
|
||||||
if(!b_from_node) {
|
|
||||||
sockets_map[b_from_sock.ptr.data] =
|
|
||||||
node_socket_map_pair(node_map, b_to_node, b_to_sock);
|
|
||||||
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
else if(!b_to_node) {
|
|
||||||
sockets_map[b_to_sock.ptr.data] =
|
|
||||||
node_socket_map_pair(node_map, b_from_node, b_from_sock);
|
|
||||||
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
SocketPair from_pair, to_pair;
|
SocketPair from_pair, to_pair;
|
||||||
|
|
||||||
|
/* links without a node pointer are connections to group inputs/outputs */
|
||||||
|
|
||||||
/* from sock */
|
/* from sock */
|
||||||
if(b_from_node.is_a(&RNA_NodeGroup)) {
|
if(b_from_node) {
|
||||||
/* group node */
|
if (b_from_node.is_a(&RNA_NodeGroup))
|
||||||
BL::NodeSocket group_sock = b_from_sock.group_socket();
|
from_pair = proxy_map[b_from_sock.ptr.data];
|
||||||
from_pair = node_groups[b_from_node.ptr.data][group_sock.ptr.data];
|
else
|
||||||
}
|
|
||||||
else {
|
|
||||||
/* regular node */
|
|
||||||
from_pair = node_socket_map_pair(node_map, b_from_node, b_from_sock);
|
from_pair = node_socket_map_pair(node_map, b_from_node, b_from_sock);
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
from_pair = sockets_map[b_from_sock.ptr.data];
|
||||||
|
|
||||||
/* to sock */
|
/* to sock */
|
||||||
if(b_to_node.is_a(&RNA_NodeGroup)) {
|
if(b_to_node) {
|
||||||
/* group node */
|
if (b_to_node.is_a(&RNA_NodeGroup))
|
||||||
BL::NodeSocket group_sock = b_to_sock.group_socket();
|
to_pair = proxy_map[b_to_sock.ptr.data];
|
||||||
to_pair = node_groups[b_to_node.ptr.data][group_sock.ptr.data];
|
else
|
||||||
}
|
|
||||||
else {
|
|
||||||
/* regular node */
|
|
||||||
to_pair = node_socket_map_pair(node_map, b_to_node, b_to_sock);
|
to_pair = node_socket_map_pair(node_map, b_to_node, b_to_sock);
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
to_pair = sockets_map[b_to_sock.ptr.data];
|
||||||
|
|
||||||
/* in case of groups there may not actually be a node inside the group
|
|
||||||
that the group socket connects to, so from_node or to_node may be NULL */
|
|
||||||
if(from_pair.first && to_pair.first) {
|
|
||||||
ShaderOutput *output = from_pair.first->output(from_pair.second.c_str());
|
ShaderOutput *output = from_pair.first->output(from_pair.second.c_str());
|
||||||
ShaderInput *input = to_pair.first->input(to_pair.second.c_str());
|
ShaderInput *input = to_pair.first->input(to_pair.second.c_str());
|
||||||
|
|
||||||
graph->connect(output, input);
|
graph->connect(output, input);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Sync Materials */
|
/* Sync Materials */
|
||||||
@ -613,7 +627,7 @@ void BlenderSync::sync_materials()
|
|||||||
PtrSockMap sock_to_node;
|
PtrSockMap sock_to_node;
|
||||||
BL::ShaderNodeTree b_ntree(b_mat->node_tree());
|
BL::ShaderNodeTree b_ntree(b_mat->node_tree());
|
||||||
|
|
||||||
add_nodes(b_data, graph, b_ntree, NULL, sock_to_node);
|
add_nodes(b_data, graph, b_ntree, sock_to_node);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
ShaderNode *closure, *out;
|
ShaderNode *closure, *out;
|
||||||
@ -654,7 +668,7 @@ void BlenderSync::sync_world()
|
|||||||
PtrSockMap sock_to_node;
|
PtrSockMap sock_to_node;
|
||||||
BL::ShaderNodeTree b_ntree(b_world.node_tree());
|
BL::ShaderNodeTree b_ntree(b_world.node_tree());
|
||||||
|
|
||||||
add_nodes(b_data, graph, b_ntree, NULL, sock_to_node);
|
add_nodes(b_data, graph, b_ntree, sock_to_node);
|
||||||
}
|
}
|
||||||
else if(b_world) {
|
else if(b_world) {
|
||||||
ShaderNode *closure, *out;
|
ShaderNode *closure, *out;
|
||||||
@ -703,7 +717,7 @@ void BlenderSync::sync_lamps()
|
|||||||
PtrSockMap sock_to_node;
|
PtrSockMap sock_to_node;
|
||||||
BL::ShaderNodeTree b_ntree(b_lamp->node_tree());
|
BL::ShaderNodeTree b_ntree(b_lamp->node_tree());
|
||||||
|
|
||||||
add_nodes(b_data, graph, b_ntree, NULL, sock_to_node);
|
add_nodes(b_data, graph, b_ntree, sock_to_node);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
ShaderNode *closure, *out;
|
ShaderNode *closure, *out;
|
||||||
|
@ -292,6 +292,42 @@ void ShaderGraph::copy_nodes(set<ShaderNode*>& nodes, map<ShaderNode*, ShaderNod
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ShaderGraph::remove_proxy_nodes(vector<bool>& removed)
|
||||||
|
{
|
||||||
|
foreach(ShaderNode *node, nodes) {
|
||||||
|
ProxyNode *proxy = dynamic_cast<ProxyNode*>(node);
|
||||||
|
if (proxy) {
|
||||||
|
ShaderInput *input = proxy->inputs[0];
|
||||||
|
ShaderOutput *output = proxy->outputs[0];
|
||||||
|
|
||||||
|
/* temp. copy of the output links list.
|
||||||
|
* output->links is modified when we disconnect!
|
||||||
|
*/
|
||||||
|
vector<ShaderInput*> links(output->links);
|
||||||
|
ShaderOutput *from = input->link;
|
||||||
|
|
||||||
|
/* bypass the proxy node */
|
||||||
|
if (from) {
|
||||||
|
disconnect(input);
|
||||||
|
foreach(ShaderInput *to, links) {
|
||||||
|
disconnect(to);
|
||||||
|
connect(from, to);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
foreach(ShaderInput *to, links) {
|
||||||
|
disconnect(to);
|
||||||
|
|
||||||
|
/* transfer the default input value to the target socket */
|
||||||
|
to->set(input->value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
removed[proxy->id] = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void ShaderGraph::break_cycles(ShaderNode *node, vector<bool>& visited, vector<bool>& on_stack)
|
void ShaderGraph::break_cycles(ShaderNode *node, vector<bool>& visited, vector<bool>& on_stack)
|
||||||
{
|
{
|
||||||
visited[node->id] = true;
|
visited[node->id] = true;
|
||||||
@ -322,15 +358,28 @@ void ShaderGraph::clean()
|
|||||||
nodes that don't feed into the output. how cycles are broken is
|
nodes that don't feed into the output. how cycles are broken is
|
||||||
undefined, they are invalid input, the important thing is to not crash */
|
undefined, they are invalid input, the important thing is to not crash */
|
||||||
|
|
||||||
|
vector<bool> removed(nodes.size(), false);
|
||||||
vector<bool> visited(nodes.size(), false);
|
vector<bool> visited(nodes.size(), false);
|
||||||
vector<bool> on_stack(nodes.size(), false);
|
vector<bool> on_stack(nodes.size(), false);
|
||||||
|
|
||||||
|
list<ShaderNode*> newnodes;
|
||||||
|
|
||||||
|
/* remove proxy nodes */
|
||||||
|
remove_proxy_nodes(removed);
|
||||||
|
|
||||||
|
foreach(ShaderNode *node, nodes) {
|
||||||
|
if(!removed[node->id])
|
||||||
|
newnodes.push_back(node);
|
||||||
|
else
|
||||||
|
delete node;
|
||||||
|
}
|
||||||
|
nodes = newnodes;
|
||||||
|
newnodes.clear();
|
||||||
|
|
||||||
/* break cycles */
|
/* break cycles */
|
||||||
break_cycles(output(), visited, on_stack);
|
break_cycles(output(), visited, on_stack);
|
||||||
|
|
||||||
/* remove unused nodes */
|
/* remove unused nodes */
|
||||||
list<ShaderNode*> newnodes;
|
|
||||||
|
|
||||||
foreach(ShaderNode *node, nodes) {
|
foreach(ShaderNode *node, nodes) {
|
||||||
if(visited[node->id])
|
if(visited[node->id])
|
||||||
newnodes.push_back(node);
|
newnodes.push_back(node);
|
||||||
|
@ -217,6 +217,7 @@ protected:
|
|||||||
void find_dependencies(set<ShaderNode*>& dependencies, ShaderInput *input);
|
void find_dependencies(set<ShaderNode*>& dependencies, ShaderInput *input);
|
||||||
void copy_nodes(set<ShaderNode*>& nodes, map<ShaderNode*, ShaderNode*>& nnodemap);
|
void copy_nodes(set<ShaderNode*>& nodes, map<ShaderNode*, ShaderNode*>& nnodemap);
|
||||||
|
|
||||||
|
void remove_proxy_nodes(vector<bool>& removed);
|
||||||
void break_cycles(ShaderNode *node, vector<bool>& visited, vector<bool>& on_stack);
|
void break_cycles(ShaderNode *node, vector<bool>& visited, vector<bool>& on_stack);
|
||||||
void clean();
|
void clean();
|
||||||
void bump_from_displacement();
|
void bump_from_displacement();
|
||||||
|
@ -869,6 +869,26 @@ void ConvertNode::compile(OSLCompiler& compiler)
|
|||||||
assert(0);
|
assert(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Proxy */
|
||||||
|
|
||||||
|
ProxyNode::ProxyNode(ShaderSocketType from_, ShaderSocketType to_)
|
||||||
|
: ShaderNode("proxy")
|
||||||
|
{
|
||||||
|
from = from_;
|
||||||
|
to = to_;
|
||||||
|
|
||||||
|
add_input("Input", from);
|
||||||
|
add_output("Output", to);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ProxyNode::compile(SVMCompiler& compiler)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void ProxyNode::compile(OSLCompiler& compiler)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
/* BSDF Closure */
|
/* BSDF Closure */
|
||||||
|
|
||||||
BsdfNode::BsdfNode()
|
BsdfNode::BsdfNode()
|
||||||
|
@ -158,6 +158,14 @@ public:
|
|||||||
ShaderSocketType from, to;
|
ShaderSocketType from, to;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class ProxyNode : public ShaderNode {
|
||||||
|
public:
|
||||||
|
ProxyNode(ShaderSocketType from, ShaderSocketType to);
|
||||||
|
SHADER_NODE_BASE_CLASS(ProxyNode)
|
||||||
|
|
||||||
|
ShaderSocketType from, to;
|
||||||
|
};
|
||||||
|
|
||||||
class BsdfNode : public ShaderNode {
|
class BsdfNode : public ShaderNode {
|
||||||
public:
|
public:
|
||||||
SHADER_NODE_CLASS(BsdfNode)
|
SHADER_NODE_CLASS(BsdfNode)
|
||||||
|
@ -156,6 +156,7 @@ class NODE_MT_node(Menu):
|
|||||||
layout.operator("node.mute_toggle")
|
layout.operator("node.mute_toggle")
|
||||||
layout.operator("node.preview_toggle")
|
layout.operator("node.preview_toggle")
|
||||||
layout.operator("node.hide_socket_toggle")
|
layout.operator("node.hide_socket_toggle")
|
||||||
|
layout.operator("node.options_toggle")
|
||||||
|
|
||||||
layout.separator()
|
layout.separator()
|
||||||
|
|
||||||
|
@ -153,9 +153,9 @@ int CustomData_number_of_layers(const struct CustomData *data, int type);
|
|||||||
|
|
||||||
/* duplicate data of a layer with flag NOFREE, and remove that flag.
|
/* duplicate data of a layer with flag NOFREE, and remove that flag.
|
||||||
* returns the layer data */
|
* returns the layer data */
|
||||||
void *CustomData_duplicate_referenced_layer(struct CustomData *data, int type);
|
void *CustomData_duplicate_referenced_layer(struct CustomData *data, const int type, const int totelem);
|
||||||
void *CustomData_duplicate_referenced_layer_named(struct CustomData *data,
|
void *CustomData_duplicate_referenced_layer_named(struct CustomData *data,
|
||||||
int type, const char *name);
|
const int type, const char *name, const int totelem);
|
||||||
int CustomData_is_referenced_layer(struct CustomData *data, int type);
|
int CustomData_is_referenced_layer(struct CustomData *data, int type);
|
||||||
|
|
||||||
/* set the CD_FLAG_NOCOPY flag in custom data layers where the mask is
|
/* set the CD_FLAG_NOCOPY flag in custom data layers where the mask is
|
||||||
|
@ -218,7 +218,7 @@ static CCGAllocatorIFC *_getStandardAllocatorIFC(void) {
|
|||||||
|
|
||||||
/***/
|
/***/
|
||||||
|
|
||||||
static int VertDataEqual(float *a, float *b) {
|
static int VertDataEqual(const float *a, const float *b) {
|
||||||
return a[0]==b[0] && a[1]==b[1] && a[2]==b[2];
|
return a[0]==b[0] && a[1]==b[1] && a[2]==b[2];
|
||||||
}
|
}
|
||||||
#define VertDataZero(av) { float *_a = (float*) av; _a[0] = _a[1] = _a[2] = 0.0f; }
|
#define VertDataZero(av) { float *_a = (float*) av; _a[0] = _a[1] = _a[2] = 0.0f; }
|
||||||
@ -238,7 +238,7 @@ static int VertDataEqual(float *a, float *b) {
|
|||||||
#define NormAdd(av, bv) { float *_a = (float*) av, *_b = (float*) bv; _a[0]+=_b[0]; _a[1]+=_b[1]; _a[2]+=_b[2]; }
|
#define NormAdd(av, bv) { float *_a = (float*) av, *_b = (float*) bv; _a[0]+=_b[0]; _a[1]+=_b[1]; _a[2]+=_b[2]; }
|
||||||
|
|
||||||
|
|
||||||
static int _edge_isBoundary(CCGEdge *e);
|
static int _edge_isBoundary(const CCGEdge *e);
|
||||||
|
|
||||||
/***/
|
/***/
|
||||||
|
|
||||||
@ -392,7 +392,7 @@ static void _vert_addFace(CCGVert *v, CCGFace *f, CCGSubSurf *ss) {
|
|||||||
v->faces = CCGSUBSURF_realloc(ss, v->faces, (v->numFaces+1)*sizeof(*v->faces), v->numFaces*sizeof(*v->faces));
|
v->faces = CCGSUBSURF_realloc(ss, v->faces, (v->numFaces+1)*sizeof(*v->faces), v->numFaces*sizeof(*v->faces));
|
||||||
v->faces[v->numFaces++] = f;
|
v->faces[v->numFaces++] = f;
|
||||||
}
|
}
|
||||||
static CCGEdge *_vert_findEdgeTo(CCGVert *v, CCGVert *vQ) {
|
static CCGEdge *_vert_findEdgeTo(const CCGVert *v, const CCGVert *vQ) {
|
||||||
int i;
|
int i;
|
||||||
for (i=0; i<v->numEdges; i++) {
|
for (i=0; i<v->numEdges; i++) {
|
||||||
CCGEdge *e = v->edges[v->numEdges-1-i]; // XXX, note reverse
|
CCGEdge *e = v->edges[v->numEdges-1-i]; // XXX, note reverse
|
||||||
@ -402,7 +402,7 @@ static CCGEdge *_vert_findEdgeTo(CCGVert *v, CCGVert *vQ) {
|
|||||||
}
|
}
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
static int _vert_isBoundary(CCGVert *v) {
|
static int _vert_isBoundary(const CCGVert *v) {
|
||||||
int i;
|
int i;
|
||||||
for (i=0; i<v->numEdges; i++)
|
for (i=0; i<v->numEdges; i++)
|
||||||
if (_edge_isBoundary(v->edges[i]))
|
if (_edge_isBoundary(v->edges[i]))
|
||||||
@ -423,7 +423,7 @@ static void _vert_free(CCGVert *v, CCGSubSurf *ss) {
|
|||||||
CCGSUBSURF_free(ss, v);
|
CCGSUBSURF_free(ss, v);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int VERT_seam(CCGVert *v) {
|
static int VERT_seam(const CCGVert *v) {
|
||||||
return ((v->flags & Vert_eSeam) != 0);
|
return ((v->flags & Vert_eSeam) != 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -462,7 +462,7 @@ static void _edge_addFace(CCGEdge *e, CCGFace *f, CCGSubSurf *ss) {
|
|||||||
e->faces = CCGSUBSURF_realloc(ss, e->faces, (e->numFaces+1)*sizeof(*e->faces), e->numFaces*sizeof(*e->faces));
|
e->faces = CCGSUBSURF_realloc(ss, e->faces, (e->numFaces+1)*sizeof(*e->faces), e->numFaces*sizeof(*e->faces));
|
||||||
e->faces[e->numFaces++] = f;
|
e->faces[e->numFaces++] = f;
|
||||||
}
|
}
|
||||||
static int _edge_isBoundary(CCGEdge *e) {
|
static int _edge_isBoundary(const CCGEdge *e) {
|
||||||
return e->numFaces<2;
|
return e->numFaces<2;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -900,7 +900,7 @@ CCGError ccgSubSurf_syncFaceDel(CCGSubSurf *ss, CCGFaceHDL fHDL) {
|
|||||||
return eCCGError_None;
|
return eCCGError_None;
|
||||||
}
|
}
|
||||||
|
|
||||||
CCGError ccgSubSurf_syncVert(CCGSubSurf *ss, CCGVertHDL vHDL, void *vertData, int seam, CCGVert **v_r) {
|
CCGError ccgSubSurf_syncVert(CCGSubSurf *ss, CCGVertHDL vHDL, const void *vertData, int seam, CCGVert **v_r) {
|
||||||
void **prevp;
|
void **prevp;
|
||||||
CCGVert *v = NULL;
|
CCGVert *v = NULL;
|
||||||
short seamflag = (seam)? Vert_eSeam: 0;
|
short seamflag = (seam)? Vert_eSeam: 0;
|
||||||
@ -2484,13 +2484,13 @@ CCGError ccgSubSurf_updateLevels(CCGSubSurf *ss, int lvl, CCGFace **effectedF, i
|
|||||||
|
|
||||||
/*** External API accessor functions ***/
|
/*** External API accessor functions ***/
|
||||||
|
|
||||||
int ccgSubSurf_getNumVerts(CCGSubSurf *ss) {
|
int ccgSubSurf_getNumVerts(const CCGSubSurf *ss) {
|
||||||
return ss->vMap->numEntries;
|
return ss->vMap->numEntries;
|
||||||
}
|
}
|
||||||
int ccgSubSurf_getNumEdges(CCGSubSurf *ss) {
|
int ccgSubSurf_getNumEdges(const CCGSubSurf *ss) {
|
||||||
return ss->eMap->numEntries;
|
return ss->eMap->numEntries;
|
||||||
}
|
}
|
||||||
int ccgSubSurf_getNumFaces(CCGSubSurf *ss) {
|
int ccgSubSurf_getNumFaces(const CCGSubSurf *ss) {
|
||||||
return ss->fMap->numEntries;
|
return ss->fMap->numEntries;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2504,23 +2504,23 @@ CCGFace *ccgSubSurf_getFace(CCGSubSurf *ss, CCGFaceHDL f) {
|
|||||||
return (CCGFace*) _ehash_lookup(ss->fMap, f);
|
return (CCGFace*) _ehash_lookup(ss->fMap, f);
|
||||||
}
|
}
|
||||||
|
|
||||||
int ccgSubSurf_getSubdivisionLevels(CCGSubSurf *ss) {
|
int ccgSubSurf_getSubdivisionLevels(const CCGSubSurf *ss) {
|
||||||
return ss->subdivLevels;
|
return ss->subdivLevels;
|
||||||
}
|
}
|
||||||
int ccgSubSurf_getEdgeSize(CCGSubSurf *ss) {
|
int ccgSubSurf_getEdgeSize(const CCGSubSurf *ss) {
|
||||||
return ccgSubSurf_getEdgeLevelSize(ss, ss->subdivLevels);
|
return ccgSubSurf_getEdgeLevelSize(ss, ss->subdivLevels);
|
||||||
}
|
}
|
||||||
int ccgSubSurf_getEdgeLevelSize(CCGSubSurf *ss, int level) {
|
int ccgSubSurf_getEdgeLevelSize(const CCGSubSurf *ss, int level) {
|
||||||
if (level<1 || level>ss->subdivLevels) {
|
if (level<1 || level>ss->subdivLevels) {
|
||||||
return -1;
|
return -1;
|
||||||
} else {
|
} else {
|
||||||
return 1 + (1<<level);
|
return 1 + (1<<level);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
int ccgSubSurf_getGridSize(CCGSubSurf *ss) {
|
int ccgSubSurf_getGridSize(const CCGSubSurf *ss) {
|
||||||
return ccgSubSurf_getGridLevelSize(ss, ss->subdivLevels);
|
return ccgSubSurf_getGridLevelSize(ss, ss->subdivLevels);
|
||||||
}
|
}
|
||||||
int ccgSubSurf_getGridLevelSize(CCGSubSurf *ss, int level) {
|
int ccgSubSurf_getGridLevelSize(const CCGSubSurf *ss, int level) {
|
||||||
if (level<1 || level>ss->subdivLevels) {
|
if (level<1 || level>ss->subdivLevels) {
|
||||||
return -1;
|
return -1;
|
||||||
} else {
|
} else {
|
||||||
@ -2736,19 +2736,19 @@ void ccgFaceIterator_free(CCGFaceIterator *vi) {
|
|||||||
|
|
||||||
/*** Extern API final vert/edge/face interface ***/
|
/*** Extern API final vert/edge/face interface ***/
|
||||||
|
|
||||||
int ccgSubSurf_getNumFinalVerts(CCGSubSurf *ss) {
|
int ccgSubSurf_getNumFinalVerts(const CCGSubSurf *ss) {
|
||||||
int edgeSize = 1 + (1<<ss->subdivLevels);
|
int edgeSize = 1 + (1<<ss->subdivLevels);
|
||||||
int gridSize = 1 + (1<<(ss->subdivLevels-1));
|
int gridSize = 1 + (1<<(ss->subdivLevels-1));
|
||||||
int numFinalVerts = ss->vMap->numEntries + ss->eMap->numEntries*(edgeSize-2) + ss->fMap->numEntries + ss->numGrids*((gridSize-2) + ((gridSize-2)*(gridSize-2)));
|
int numFinalVerts = ss->vMap->numEntries + ss->eMap->numEntries*(edgeSize-2) + ss->fMap->numEntries + ss->numGrids*((gridSize-2) + ((gridSize-2)*(gridSize-2)));
|
||||||
return numFinalVerts;
|
return numFinalVerts;
|
||||||
}
|
}
|
||||||
int ccgSubSurf_getNumFinalEdges(CCGSubSurf *ss) {
|
int ccgSubSurf_getNumFinalEdges(const CCGSubSurf *ss) {
|
||||||
int edgeSize = 1 + (1<<ss->subdivLevels);
|
int edgeSize = 1 + (1<<ss->subdivLevels);
|
||||||
int gridSize = 1 + (1<<(ss->subdivLevels-1));
|
int gridSize = 1 + (1<<(ss->subdivLevels-1));
|
||||||
int numFinalEdges = ss->eMap->numEntries*(edgeSize-1) + ss->numGrids*((gridSize-1) + 2*((gridSize-2)*(gridSize-1)));
|
int numFinalEdges = ss->eMap->numEntries*(edgeSize-1) + ss->numGrids*((gridSize-1) + 2*((gridSize-2)*(gridSize-1)));
|
||||||
return numFinalEdges;
|
return numFinalEdges;
|
||||||
}
|
}
|
||||||
int ccgSubSurf_getNumFinalFaces(CCGSubSurf *ss) {
|
int ccgSubSurf_getNumFinalFaces(const CCGSubSurf *ss) {
|
||||||
int gridSize = 1 + (1<<(ss->subdivLevels-1));
|
int gridSize = 1 + (1<<(ss->subdivLevels-1));
|
||||||
int numFinalFaces = ss->numGrids*((gridSize-1)*(gridSize-1));
|
int numFinalFaces = ss->numGrids*((gridSize-1)*(gridSize-1));
|
||||||
return numFinalFaces;
|
return numFinalFaces;
|
||||||
|
@ -56,7 +56,7 @@ CCGError ccgSubSurf_sync (CCGSubSurf *ss);
|
|||||||
CCGError ccgSubSurf_initFullSync (CCGSubSurf *ss);
|
CCGError ccgSubSurf_initFullSync (CCGSubSurf *ss);
|
||||||
CCGError ccgSubSurf_initPartialSync (CCGSubSurf *ss);
|
CCGError ccgSubSurf_initPartialSync (CCGSubSurf *ss);
|
||||||
|
|
||||||
CCGError ccgSubSurf_syncVert (CCGSubSurf *ss, CCGVertHDL vHDL, void *vertData, int seam, CCGVert **v_r);
|
CCGError ccgSubSurf_syncVert (CCGSubSurf *ss, CCGVertHDL vHDL, const void *vertData, int seam, CCGVert **v_r);
|
||||||
CCGError ccgSubSurf_syncEdge (CCGSubSurf *ss, CCGEdgeHDL eHDL, CCGVertHDL e_vHDL0, CCGVertHDL e_vHDL1, float crease, CCGEdge **e_r);
|
CCGError ccgSubSurf_syncEdge (CCGSubSurf *ss, CCGEdgeHDL eHDL, CCGVertHDL e_vHDL0, CCGVertHDL e_vHDL1, float crease, CCGEdge **e_r);
|
||||||
CCGError ccgSubSurf_syncFace (CCGSubSurf *ss, CCGFaceHDL fHDL, int numVerts, CCGVertHDL *vHDLs, CCGFace **f_r);
|
CCGError ccgSubSurf_syncFace (CCGSubSurf *ss, CCGFaceHDL fHDL, int numVerts, CCGVertHDL *vHDLs, CCGFace **f_r);
|
||||||
|
|
||||||
@ -84,15 +84,15 @@ CCGError ccgSubSurf_setCalcVertexNormals (CCGSubSurf *ss, int useVertNormals, i
|
|||||||
|
|
||||||
/***/
|
/***/
|
||||||
|
|
||||||
int ccgSubSurf_getNumVerts (CCGSubSurf *ss);
|
int ccgSubSurf_getNumVerts (const CCGSubSurf *ss);
|
||||||
int ccgSubSurf_getNumEdges (CCGSubSurf *ss);
|
int ccgSubSurf_getNumEdges (const CCGSubSurf *ss);
|
||||||
int ccgSubSurf_getNumFaces (CCGSubSurf *ss);
|
int ccgSubSurf_getNumFaces (const CCGSubSurf *ss);
|
||||||
|
|
||||||
int ccgSubSurf_getSubdivisionLevels (CCGSubSurf *ss);
|
int ccgSubSurf_getSubdivisionLevels (const CCGSubSurf *ss);
|
||||||
int ccgSubSurf_getEdgeSize (CCGSubSurf *ss);
|
int ccgSubSurf_getEdgeSize (const CCGSubSurf *ss);
|
||||||
int ccgSubSurf_getEdgeLevelSize (CCGSubSurf *ss, int level);
|
int ccgSubSurf_getEdgeLevelSize (const CCGSubSurf *ss, int level);
|
||||||
int ccgSubSurf_getGridSize (CCGSubSurf *ss);
|
int ccgSubSurf_getGridSize (const CCGSubSurf *ss);
|
||||||
int ccgSubSurf_getGridLevelSize (CCGSubSurf *ss, int level);
|
int ccgSubSurf_getGridLevelSize (const CCGSubSurf *ss, int level);
|
||||||
|
|
||||||
CCGVert* ccgSubSurf_getVert (CCGSubSurf *ss, CCGVertHDL v);
|
CCGVert* ccgSubSurf_getVert (CCGSubSurf *ss, CCGVertHDL v);
|
||||||
CCGVertHDL ccgSubSurf_getVertVertHandle (CCGVert *v);
|
CCGVertHDL ccgSubSurf_getVertVertHandle (CCGVert *v);
|
||||||
@ -135,9 +135,9 @@ void* ccgSubSurf_getFaceGridEdgeData (CCGSubSurf *ss, CCGFace *f, int gridInde
|
|||||||
void* ccgSubSurf_getFaceGridDataArray (CCGSubSurf *ss, CCGFace *f, int gridIndex);
|
void* ccgSubSurf_getFaceGridDataArray (CCGSubSurf *ss, CCGFace *f, int gridIndex);
|
||||||
void* ccgSubSurf_getFaceGridData (CCGSubSurf *ss, CCGFace *f, int gridIndex, int x, int y);
|
void* ccgSubSurf_getFaceGridData (CCGSubSurf *ss, CCGFace *f, int gridIndex, int x, int y);
|
||||||
|
|
||||||
int ccgSubSurf_getNumFinalVerts (CCGSubSurf *ss);
|
int ccgSubSurf_getNumFinalVerts (const CCGSubSurf *ss);
|
||||||
int ccgSubSurf_getNumFinalEdges (CCGSubSurf *ss);
|
int ccgSubSurf_getNumFinalEdges (const CCGSubSurf *ss);
|
||||||
int ccgSubSurf_getNumFinalFaces (CCGSubSurf *ss);
|
int ccgSubSurf_getNumFinalFaces (const CCGSubSurf *ss);
|
||||||
|
|
||||||
/***/
|
/***/
|
||||||
|
|
||||||
|
@ -883,24 +883,37 @@ enum {
|
|||||||
CALC_WP_AUTO_NORMALIZE= (1<<1)
|
CALC_WP_AUTO_NORMALIZE= (1<<1)
|
||||||
};
|
};
|
||||||
|
|
||||||
static void calc_weightpaint_vert_color(
|
void weightpaint_color(unsigned char r_col[4], ColorBand *coba, const float input)
|
||||||
Object *ob, const int defbase_tot, ColorBand *coba, int vert, unsigned char *col,
|
{
|
||||||
const char *dg_flags, int selected, int UNUSED(unselected), const int draw_flag)
|
float colf[4];
|
||||||
|
|
||||||
|
if(coba) do_colorband(coba, input, colf);
|
||||||
|
else weight_to_rgb(colf, input);
|
||||||
|
|
||||||
|
r_col[3] = (unsigned char)(colf[0] * 255.0f);
|
||||||
|
r_col[2] = (unsigned char)(colf[1] * 255.0f);
|
||||||
|
r_col[1] = (unsigned char)(colf[2] * 255.0f);
|
||||||
|
r_col[0] = 255;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void calc_weightpaint_vert_color(
|
||||||
|
unsigned char r_col[4],
|
||||||
|
MDeformVert *dv, ColorBand *coba,
|
||||||
|
const int defbase_tot, const int defbase_act,
|
||||||
|
const char *dg_flags,
|
||||||
|
const int selected, const int draw_flag)
|
||||||
{
|
{
|
||||||
Mesh *me = ob->data;
|
|
||||||
float input = 0.0f;
|
float input = 0.0f;
|
||||||
|
|
||||||
int make_black= FALSE;
|
int make_black= FALSE;
|
||||||
|
|
||||||
if (me->dvert) {
|
|
||||||
MDeformVert *dvert= &me->dvert[vert];
|
|
||||||
|
|
||||||
if ((selected > 1) && (draw_flag & CALC_WP_MULTIPAINT)) {
|
if ((selected > 1) && (draw_flag & CALC_WP_MULTIPAINT)) {
|
||||||
int was_a_nonzero= FALSE;
|
int was_a_nonzero= FALSE;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
MDeformWeight *dw= dvert->dw;
|
MDeformWeight *dw= dv->dw;
|
||||||
for (i = dvert->totweight; i > 0; i--, dw++) {
|
for (i = dv->totweight; i > 0; i--, dw++) {
|
||||||
/* in multipaint, get the average if auto normalize is inactive
|
/* in multipaint, get the average if auto normalize is inactive
|
||||||
* get the sum if it is active */
|
* get the sum if it is active */
|
||||||
if (dw->def_nr < defbase_tot) {
|
if (dw->def_nr < defbase_tot) {
|
||||||
@ -923,27 +936,18 @@ static void calc_weightpaint_vert_color(
|
|||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
/* default, non tricky behavior */
|
/* default, non tricky behavior */
|
||||||
input= defvert_find_weight(dvert, ob->actdef-1);
|
input= defvert_find_weight(dv, defbase_act);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (make_black) {
|
if (make_black) { /* TODO, theme color */
|
||||||
col[3] = 0;
|
r_col[3] = 0;
|
||||||
col[2] = 0;
|
r_col[2] = 0;
|
||||||
col[1] = 0;
|
r_col[1] = 0;
|
||||||
col[0] = 255;
|
r_col[0] = 255;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
float colf[4];
|
|
||||||
CLAMP(input, 0.0f, 1.0f);
|
CLAMP(input, 0.0f, 1.0f);
|
||||||
|
weightpaint_color(r_col, coba, input);
|
||||||
if(coba) do_colorband(coba, input, colf);
|
|
||||||
else weight_to_rgb(colf, input);
|
|
||||||
|
|
||||||
col[3] = (unsigned char)(colf[0] * 255.0f);
|
|
||||||
col[2] = (unsigned char)(colf[1] * 255.0f);
|
|
||||||
col[1] = (unsigned char)(colf[2] * 255.0f);
|
|
||||||
col[0] = 255;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -956,7 +960,7 @@ void vDM_ColorBand_store(ColorBand *coba)
|
|||||||
|
|
||||||
static void add_weight_mcol_dm(Object *ob, DerivedMesh *dm, int const draw_flag)
|
static void add_weight_mcol_dm(Object *ob, DerivedMesh *dm, int const draw_flag)
|
||||||
{
|
{
|
||||||
// Mesh *me = ob->data; // UNUSED
|
Mesh *me = ob->data;
|
||||||
MFace *mf = dm->getTessFaceArray(dm);
|
MFace *mf = dm->getTessFaceArray(dm);
|
||||||
MLoop *mloop = dm->getLoopArray(dm), *ml;
|
MLoop *mloop = dm->getLoopArray(dm), *ml;
|
||||||
MPoly *mp = dm->getPolyArray(dm);
|
MPoly *mp = dm->getPolyArray(dm);
|
||||||
@ -968,21 +972,32 @@ static void add_weight_mcol_dm(Object *ob, DerivedMesh *dm, int const draw_flag)
|
|||||||
int *origIndex = dm->getVertDataArray(dm, CD_ORIGINDEX);
|
int *origIndex = dm->getVertDataArray(dm, CD_ORIGINDEX);
|
||||||
|
|
||||||
int defbase_tot = BLI_countlist(&ob->defbase);
|
int defbase_tot = BLI_countlist(&ob->defbase);
|
||||||
char *defbase_sel = MEM_mallocN(defbase_tot * sizeof(char), __func__);
|
const int defbase_act = ob->actdef-1;
|
||||||
int selected = get_selected_defgroups(ob, defbase_sel, defbase_tot);
|
char *dg_flags = MEM_mallocN(defbase_tot * sizeof(char), __func__);
|
||||||
int unselected = defbase_tot - selected;
|
int selected = get_selected_defgroups(ob, dg_flags, defbase_tot);
|
||||||
|
|
||||||
wtcol = MEM_callocN (sizeof (unsigned char) * totface*4*4, "weightmap");
|
wtcol = MEM_callocN (sizeof (unsigned char) * totface*4*4, "weightmap");
|
||||||
|
|
||||||
|
if (me->dvert) {
|
||||||
|
MDeformVert *dvert= me->dvert;
|
||||||
/*first add colors to the tesselation faces*/
|
/*first add colors to the tesselation faces*/
|
||||||
memset(wtcol, 0x55, sizeof (unsigned char) * totface*4*4);
|
memset(wtcol, 0x55, sizeof (unsigned char) * totface*4*4);
|
||||||
for (i=0; i<totface; i++, mf++) {
|
for (i=0; i<totface; i++, mf++) {
|
||||||
/*origindex being NULL means we're operating on original mesh data*/
|
/*origindex being NULL means we're operating on original mesh data*/
|
||||||
calc_weightpaint_vert_color(ob, defbase_tot, coba, mf->v1, &wtcol[(i*4 + 0)*4], defbase_sel, selected, unselected, draw_flag);
|
unsigned int fidx= mf->v4 ? 3:2;
|
||||||
calc_weightpaint_vert_color(ob, defbase_tot, coba, mf->v2, &wtcol[(i*4 + 1)*4], defbase_sel, selected, unselected, draw_flag);
|
do {
|
||||||
calc_weightpaint_vert_color(ob, defbase_tot, coba, mf->v3, &wtcol[(i*4 + 2)*4], defbase_sel, selected, unselected, draw_flag);
|
calc_weightpaint_vert_color(&wtcol[(i*4 + fidx)*4],
|
||||||
if (mf->v4)
|
&dvert[*(&mf->v1 + fidx)], coba,
|
||||||
calc_weightpaint_vert_color(ob, defbase_tot, coba, mf->v4, &wtcol[(i*4 + 3)*4], defbase_sel, selected, unselected, draw_flag);
|
defbase_tot, defbase_act,
|
||||||
|
dg_flags, selected, draw_flag);
|
||||||
|
} while (fidx--);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
/* no weights, fill in zero */
|
||||||
|
int col_i;
|
||||||
|
weightpaint_color((unsigned char *)&col_i, coba, 0.0f);
|
||||||
|
fill_vn_i((int *)wtcol, totface*4, col_i);
|
||||||
}
|
}
|
||||||
|
|
||||||
CustomData_add_layer(&dm->faceData, CD_WEIGHT_MCOL, CD_ASSIGN, wtcol, totface);
|
CustomData_add_layer(&dm->faceData, CD_WEIGHT_MCOL, CD_ASSIGN, wtcol, totface);
|
||||||
@ -990,17 +1005,21 @@ static void add_weight_mcol_dm(Object *ob, DerivedMesh *dm, int const draw_flag)
|
|||||||
/*now add to loops, so the data can be passed through the modifier stack*/
|
/*now add to loops, so the data can be passed through the modifier stack*/
|
||||||
totloop = 0;
|
totloop = 0;
|
||||||
for (i=0; i<dm->numPolyData; i++, mp++) {
|
for (i=0; i<dm->numPolyData; i++, mp++) {
|
||||||
|
MDeformVert *dvert= me->dvert;
|
||||||
|
|
||||||
ml = mloop + mp->loopstart;
|
ml = mloop + mp->loopstart;
|
||||||
|
|
||||||
for (j=0; j<mp->totloop; j++, ml++, totloop++) {
|
for (j=0; j<mp->totloop; j++, ml++, totloop++) {
|
||||||
BLI_array_growone(wlcol);
|
BLI_array_growone(wlcol);
|
||||||
|
|
||||||
calc_weightpaint_vert_color(ob, defbase_tot, coba, origIndex ? origIndex[ml->v] : ml->v,
|
calc_weightpaint_vert_color((unsigned char *)&wlcol[totloop],
|
||||||
(unsigned char *)&wlcol[totloop], defbase_sel, selected, unselected, draw_flag);
|
&dvert[origIndex ? origIndex[ml->v] : ml->v], coba,
|
||||||
|
defbase_tot, defbase_act,
|
||||||
|
dg_flags, selected, draw_flag);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
MEM_freeN(defbase_sel);
|
MEM_freeN(dg_flags);
|
||||||
|
|
||||||
CustomData_add_layer(&dm->loopData, CD_WEIGHT_MLOOPCOL, CD_ASSIGN, wlcol, totloop);
|
CustomData_add_layer(&dm->loopData, CD_WEIGHT_MLOOPCOL, CD_ASSIGN, wlcol, totloop);
|
||||||
}
|
}
|
||||||
|
@ -693,7 +693,7 @@ static void cdDM_drawFacesTex_common(DerivedMesh *dm,
|
|||||||
float *nors= dm->getTessFaceDataArray(dm, CD_NORMAL);
|
float *nors= dm->getTessFaceDataArray(dm, CD_NORMAL);
|
||||||
MTFace *tf = DM_get_tessface_data_layer(dm, CD_MTFACE);
|
MTFace *tf = DM_get_tessface_data_layer(dm, CD_MTFACE);
|
||||||
int i, j, orig, *index = DM_get_tessface_data_layer(dm, CD_ORIGINDEX);
|
int i, j, orig, *index = DM_get_tessface_data_layer(dm, CD_ORIGINDEX);
|
||||||
int startFace = 0, lastFlag = 0xdeadbeef;
|
int startFace = 0 /*, lastFlag = 0xdeadbeef */ /* UNUSED */;
|
||||||
MCol *mcol = dm->getTessFaceDataArray(dm, CD_WEIGHT_MCOL);
|
MCol *mcol = dm->getTessFaceDataArray(dm, CD_WEIGHT_MCOL);
|
||||||
if(!mcol)
|
if(!mcol)
|
||||||
mcol = dm->getTessFaceDataArray(dm, CD_MCOL);
|
mcol = dm->getTessFaceDataArray(dm, CD_MCOL);
|
||||||
@ -812,7 +812,7 @@ static void cdDM_drawFacesTex_common(DerivedMesh *dm,
|
|||||||
int next_actualFace= dm->drawObject->triangle_to_mface[0];
|
int next_actualFace= dm->drawObject->triangle_to_mface[0];
|
||||||
|
|
||||||
glShadeModel( GL_SMOOTH );
|
glShadeModel( GL_SMOOTH );
|
||||||
lastFlag = 0;
|
/* lastFlag = 0; */ /* UNUSED */
|
||||||
for(i = 0; i < tottri; i++) {
|
for(i = 0; i < tottri; i++) {
|
||||||
int actualFace = next_actualFace;
|
int actualFace = next_actualFace;
|
||||||
int flag = 1;
|
int flag = 1;
|
||||||
@ -2204,7 +2204,7 @@ void CDDM_apply_vert_coords(DerivedMesh *dm, float (*vertCoords)[3])
|
|||||||
int i;
|
int i;
|
||||||
|
|
||||||
/* this will just return the pointer if it wasn't a referenced layer */
|
/* this will just return the pointer if it wasn't a referenced layer */
|
||||||
vert = CustomData_duplicate_referenced_layer(&dm->vertData, CD_MVERT);
|
vert = CustomData_duplicate_referenced_layer(&dm->vertData, CD_MVERT, dm->numVertData);
|
||||||
cddm->mvert = vert;
|
cddm->mvert = vert;
|
||||||
|
|
||||||
for(i = 0; i < dm->numVertData; ++i, ++vert)
|
for(i = 0; i < dm->numVertData; ++i, ++vert)
|
||||||
@ -2218,7 +2218,7 @@ void CDDM_apply_vert_normals(DerivedMesh *dm, short (*vertNormals)[3])
|
|||||||
int i;
|
int i;
|
||||||
|
|
||||||
/* this will just return the pointer if it wasn't a referenced layer */
|
/* this will just return the pointer if it wasn't a referenced layer */
|
||||||
vert = CustomData_duplicate_referenced_layer(&dm->vertData, CD_MVERT);
|
vert = CustomData_duplicate_referenced_layer(&dm->vertData, CD_MVERT, dm->numVertData);
|
||||||
cddm->mvert = vert;
|
cddm->mvert = vert;
|
||||||
|
|
||||||
for(i = 0; i < dm->numVertData; ++i, ++vert)
|
for(i = 0; i < dm->numVertData; ++i, ++vert)
|
||||||
@ -2241,7 +2241,7 @@ void CDDM_calc_normals(DerivedMesh *dm)
|
|||||||
* need to take care of the side effects here - campbell */
|
* need to take care of the side effects here - campbell */
|
||||||
#if 0
|
#if 0
|
||||||
/* we don't want to overwrite any referenced layers */
|
/* we don't want to overwrite any referenced layers */
|
||||||
cddm->mvert = CustomData_duplicate_referenced_layer(&dm->vertData, CD_MVERT);
|
cddm->mvert = CustomData_duplicate_referenced_layer(&dm->vertData, CD_MVERT, dm->numVertData);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (dm->numTessFaceData == 0) {
|
if (dm->numTessFaceData == 0) {
|
||||||
|
@ -1701,7 +1701,7 @@ int CustomData_number_of_layers(const CustomData *data, int type)
|
|||||||
return number;
|
return number;
|
||||||
}
|
}
|
||||||
|
|
||||||
void *CustomData_duplicate_referenced_layer(struct CustomData *data, int type)
|
void *CustomData_duplicate_referenced_layer(struct CustomData *data, const int type, const int totelem)
|
||||||
{
|
{
|
||||||
CustomDataLayer *layer;
|
CustomDataLayer *layer;
|
||||||
int layer_index;
|
int layer_index;
|
||||||
@ -1713,7 +1713,20 @@ void *CustomData_duplicate_referenced_layer(struct CustomData *data, int type)
|
|||||||
layer = &data->layers[layer_index];
|
layer = &data->layers[layer_index];
|
||||||
|
|
||||||
if (layer->flag & CD_FLAG_NOFREE) {
|
if (layer->flag & CD_FLAG_NOFREE) {
|
||||||
|
/* MEM_dupallocN won’t work in case of complex layers, like e.g.
|
||||||
|
* CD_MDEFORMVERT, which has pointers to allocated data...
|
||||||
|
* So in case a custom copy function is defined, use it!
|
||||||
|
*/
|
||||||
|
const LayerTypeInfo *typeInfo = layerType_getInfo(layer->type);
|
||||||
|
|
||||||
|
if(typeInfo->copy) {
|
||||||
|
char *dest_data = MEM_mallocN(typeInfo->size * totelem, "CD duplicate ref layer");
|
||||||
|
typeInfo->copy(layer->data, dest_data, totelem);
|
||||||
|
layer->data = dest_data;
|
||||||
|
}
|
||||||
|
else
|
||||||
layer->data = MEM_dupallocN(layer->data);
|
layer->data = MEM_dupallocN(layer->data);
|
||||||
|
|
||||||
layer->flag &= ~CD_FLAG_NOFREE;
|
layer->flag &= ~CD_FLAG_NOFREE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1721,7 +1734,7 @@ void *CustomData_duplicate_referenced_layer(struct CustomData *data, int type)
|
|||||||
}
|
}
|
||||||
|
|
||||||
void *CustomData_duplicate_referenced_layer_named(struct CustomData *data,
|
void *CustomData_duplicate_referenced_layer_named(struct CustomData *data,
|
||||||
int type, const char *name)
|
const int type, const char *name, const int totelem)
|
||||||
{
|
{
|
||||||
CustomDataLayer *layer;
|
CustomDataLayer *layer;
|
||||||
int layer_index;
|
int layer_index;
|
||||||
@ -1733,7 +1746,20 @@ void *CustomData_duplicate_referenced_layer_named(struct CustomData *data,
|
|||||||
layer = &data->layers[layer_index];
|
layer = &data->layers[layer_index];
|
||||||
|
|
||||||
if (layer->flag & CD_FLAG_NOFREE) {
|
if (layer->flag & CD_FLAG_NOFREE) {
|
||||||
|
/* MEM_dupallocN won’t work in case of complex layers, like e.g.
|
||||||
|
* CD_MDEFORMVERT, which has pointers to allocated data...
|
||||||
|
* So in case a custom copy function is defined, use it!
|
||||||
|
*/
|
||||||
|
const LayerTypeInfo *typeInfo = layerType_getInfo(layer->type);
|
||||||
|
|
||||||
|
if(typeInfo->copy) {
|
||||||
|
char *dest_data = MEM_mallocN(typeInfo->size * totelem, "CD duplicate ref layer");
|
||||||
|
typeInfo->copy(layer->data, dest_data, totelem);
|
||||||
|
layer->data = dest_data;
|
||||||
|
}
|
||||||
|
else
|
||||||
layer->data = MEM_dupallocN(layer->data);
|
layer->data = MEM_dupallocN(layer->data);
|
||||||
|
|
||||||
layer->flag &= ~CD_FLAG_NOFREE;
|
layer->flag &= ~CD_FLAG_NOFREE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -216,7 +216,7 @@ void defvert_normalize_lock(MDeformVert *dvert, const int def_nr_lock)
|
|||||||
dvert->dw[0].weight= 1.0f;
|
dvert->dw[0].weight= 1.0f;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
MDeformWeight *dw_lock;
|
MDeformWeight *dw_lock = NULL;
|
||||||
MDeformWeight *dw;
|
MDeformWeight *dw;
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
float tot_weight= 0.0f;
|
float tot_weight= 0.0f;
|
||||||
|
@ -3214,7 +3214,7 @@ static int dynamicPaint_paintMesh(DynamicPaintSurface *surface,
|
|||||||
/* hit data */
|
/* hit data */
|
||||||
float hitCoord[3];
|
float hitCoord[3];
|
||||||
int hitFace = -1;
|
int hitFace = -1;
|
||||||
short hitQuad;
|
short hitQuad = 0;
|
||||||
|
|
||||||
/* Supersampling factor */
|
/* Supersampling factor */
|
||||||
if (samples > 1 && surface->format == MOD_DPAINT_SURFACE_F_IMAGESEQ)
|
if (samples > 1 && surface->format == MOD_DPAINT_SURFACE_F_IMAGESEQ)
|
||||||
@ -4641,7 +4641,7 @@ static int dynamicPaint_generateBakeData(DynamicPaintSurface *surface, Scene *sc
|
|||||||
#pragma omp parallel for schedule(static)
|
#pragma omp parallel for schedule(static)
|
||||||
for (index=0; index<sData->total_points; index++)
|
for (index=0; index<sData->total_points; index++)
|
||||||
{
|
{
|
||||||
float prev_point[3];
|
float prev_point[3] = {0.0f, 0.0f, 0.0f};
|
||||||
if (do_velocity_data && !new_bdata) {
|
if (do_velocity_data && !new_bdata) {
|
||||||
copy_v3_v3(prev_point, bData->realCoord[bData->s_pos[index]].v);
|
copy_v3_v3(prev_point, bData->realCoord[bData->s_pos[index]].v);
|
||||||
}
|
}
|
||||||
|
@ -231,6 +231,7 @@ static int ss_sync_from_uv(CCGSubSurf *ss, CCGSubSurf *origss, DerivedMesh *dm,
|
|||||||
BLI_array_declare(fverts);
|
BLI_array_declare(fverts);
|
||||||
EdgeHash *ehash;
|
EdgeHash *ehash;
|
||||||
float creaseFactor = (float)ccgSubSurf_getSubdivisionLevels(ss);
|
float creaseFactor = (float)ccgSubSurf_getSubdivisionLevels(ss);
|
||||||
|
float uv[3]= {0.0f, 0.0f, 0.0f}; /* only first 2 values are written into */
|
||||||
|
|
||||||
limit[0]= limit[1]= STD_UV_CONNECT_LIMIT;
|
limit[0]= limit[1]= STD_UV_CONNECT_LIMIT;
|
||||||
vmap= make_uv_vert_map(mpoly, mloop, mloopuv, totface, totvert, 0, limit);
|
vmap= make_uv_vert_map(mpoly, mloop, mloopuv, totface, totvert, 0, limit);
|
||||||
@ -254,11 +255,8 @@ static int ss_sync_from_uv(CCGSubSurf *ss, CCGSubSurf *origss, DerivedMesh *dm,
|
|||||||
if (v->separate) {
|
if (v->separate) {
|
||||||
CCGVert *ssv;
|
CCGVert *ssv;
|
||||||
CCGVertHDL vhdl = SET_INT_IN_POINTER(v->f*4 + v->tfindex);
|
CCGVertHDL vhdl = SET_INT_IN_POINTER(v->f*4 + v->tfindex);
|
||||||
float uv[3];
|
|
||||||
|
|
||||||
uv[0]= mloopuv[mpoly[v->f].loopstart + v->tfindex].uv[0];
|
copy_v2_v2(uv, mloopuv[mpoly[v->f].loopstart + v->tfindex].uv);
|
||||||
uv[1]= mloopuv[mpoly[v->f].loopstart + v->tfindex].uv[1];
|
|
||||||
uv[2]= 0.0f;
|
|
||||||
|
|
||||||
ccgSubSurf_syncVert(ss, vhdl, uv, seam, &ssv);
|
ccgSubSurf_syncVert(ss, vhdl, uv, seam, &ssv);
|
||||||
}
|
}
|
||||||
|
@ -1154,7 +1154,7 @@ int BKE_tracking_next(MovieTrackingContext *context)
|
|||||||
|
|
||||||
#pragma omp parallel for private(a) shared(ibuf_new, ok) if(map_size>1)
|
#pragma omp parallel for private(a) shared(ibuf_new, ok) if(map_size>1)
|
||||||
for(a= 0; a<map_size; a++) {
|
for(a= 0; a<map_size; a++) {
|
||||||
TrackContext *track_context;
|
TrackContext *track_context = NULL;
|
||||||
MovieTrackingTrack *track;
|
MovieTrackingTrack *track;
|
||||||
MovieTrackingMarker *marker;
|
MovieTrackingMarker *marker;
|
||||||
|
|
||||||
|
@ -199,6 +199,7 @@ double dot_vn_vn(const float *array_src_a, const float *array_src_b, const int s
|
|||||||
float normalize_vn_vn(float *array_tar, const float *array_src, const int size);
|
float normalize_vn_vn(float *array_tar, const float *array_src, const int size);
|
||||||
float normalize_vn(float *array_tar, const int size);
|
float normalize_vn(float *array_tar, const int size);
|
||||||
void range_vn_i(int *array_tar, const int size, const int start);
|
void range_vn_i(int *array_tar, const int size, const int start);
|
||||||
|
void range_vn_fl(float *array_tar, const int size, const float start, const float step);
|
||||||
void negate_vn(float *array_tar, const int size);
|
void negate_vn(float *array_tar, const int size);
|
||||||
void negate_vn_vn(float *array_tar, const float *array_src, const int size);
|
void negate_vn_vn(float *array_tar, const float *array_src, const int size);
|
||||||
void mul_vn_fl(float *array_tar, const int size, const float f);
|
void mul_vn_fl(float *array_tar, const int size, const float f);
|
||||||
|
@ -279,24 +279,22 @@
|
|||||||
# endif
|
# endif
|
||||||
# if defined(__GNUC__) || defined(_MSC_VER) /* check __func__ is available */
|
# if defined(__GNUC__) || defined(_MSC_VER) /* check __func__ is available */
|
||||||
# define BLI_assert(a) \
|
# define BLI_assert(a) \
|
||||||
do { \
|
(void)((!(a)) ? ( \
|
||||||
if (!(a)) { \
|
( \
|
||||||
fprintf(stderr, \
|
fprintf(stderr, \
|
||||||
"BLI_assert failed: %s, %s(), %d at \'%s\'\n", \
|
"BLI_assert failed: %s, %s(), %d at \'%s\'\n", \
|
||||||
__FILE__, __func__, __LINE__, STRINGIFY(a)); \
|
__FILE__, __func__, __LINE__, STRINGIFY(a)), \
|
||||||
_dummy_abort(); \
|
_dummy_abort(), \
|
||||||
} \
|
NULL)) : NULL)
|
||||||
} while (0)
|
|
||||||
# else
|
# else
|
||||||
# define BLI_assert(a) \
|
# define BLI_assert(a) \
|
||||||
do { \
|
(void)((!(a)) ? ( \
|
||||||
if (0 == (a)) { \
|
( \
|
||||||
fprintf(stderr, \
|
fprintf(stderr, \
|
||||||
"BLI_assert failed: %s, %d at \'%s\'\n", \
|
"BLI_assert failed: %s, %d at \'%s\'\n", \
|
||||||
__FILE__, __LINE__, STRINGIFY(a)); \
|
__FILE__, __LINE__, STRINGIFY(a)), \
|
||||||
_dummy_abort(); \
|
_dummy_abort(), \
|
||||||
} \
|
NULL)) : NULL)
|
||||||
} while (0)
|
|
||||||
# endif
|
# endif
|
||||||
#else
|
#else
|
||||||
# define BLI_assert(a) (void)0
|
# define BLI_assert(a) (void)0
|
||||||
|
@ -199,7 +199,11 @@ void makeFilesAbsolute(Main *bmain, const char *basedir, ReportList *reports)
|
|||||||
- filesize: filesize for the file
|
- filesize: filesize for the file
|
||||||
*/
|
*/
|
||||||
#define MAX_RECUR 16
|
#define MAX_RECUR 16
|
||||||
static int findFileRecursive(char *filename_new, const char *dirname, const char *filename, int *filesize, int *recur_depth)
|
static int findFileRecursive(char *filename_new,
|
||||||
|
const char *dirname,
|
||||||
|
const char *filename,
|
||||||
|
int *filesize,
|
||||||
|
int *recur_depth)
|
||||||
{
|
{
|
||||||
/* file searching stuff */
|
/* file searching stuff */
|
||||||
DIR *dir;
|
DIR *dir;
|
||||||
@ -314,7 +318,11 @@ static int rewrite_path_fixed(char *path, BPathVisitor visit_cb, const char *abs
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int rewrite_path_fixed_dirfile(char path_dir[FILE_MAXDIR], char path_file[FILE_MAXFILE], BPathVisitor visit_cb, const char *absbase, void *userdata)
|
static int rewrite_path_fixed_dirfile(char path_dir[FILE_MAXDIR],
|
||||||
|
char path_file[FILE_MAXFILE],
|
||||||
|
BPathVisitor visit_cb,
|
||||||
|
const char *absbase,
|
||||||
|
void *userdata)
|
||||||
{
|
{
|
||||||
char path_src[FILE_MAX];
|
char path_src[FILE_MAX];
|
||||||
char path_dst[FILE_MAX];
|
char path_dst[FILE_MAX];
|
||||||
@ -496,7 +504,8 @@ void bpath_traverse_id(Main *bmain, ID *id, BPathVisitor visit_cb, const int fla
|
|||||||
SEQ_BEGIN(scene->ed, seq) {
|
SEQ_BEGIN(scene->ed, seq) {
|
||||||
if (SEQ_HAS_PATH(seq)) {
|
if (SEQ_HAS_PATH(seq)) {
|
||||||
if (ELEM(seq->type, SEQ_MOVIE, SEQ_SOUND)) {
|
if (ELEM(seq->type, SEQ_MOVIE, SEQ_SOUND)) {
|
||||||
rewrite_path_fixed_dirfile(seq->strip->dir, seq->strip->stripdata->name, visit_cb, absbase, bpath_user_data);
|
rewrite_path_fixed_dirfile(seq->strip->dir, seq->strip->stripdata->name,
|
||||||
|
visit_cb, absbase, bpath_user_data);
|
||||||
}
|
}
|
||||||
else if (seq->type == SEQ_IMAGE) {
|
else if (seq->type == SEQ_IMAGE) {
|
||||||
/* might want an option not to loop over all strips */
|
/* might want an option not to loop over all strips */
|
||||||
@ -510,7 +519,8 @@ void bpath_traverse_id(Main *bmain, ID *id, BPathVisitor visit_cb, const int fla
|
|||||||
}
|
}
|
||||||
|
|
||||||
for(i= 0; i < len; i++, se++) {
|
for(i= 0; i < len; i++, se++) {
|
||||||
rewrite_path_fixed_dirfile(seq->strip->dir, se->name, visit_cb, absbase, bpath_user_data);
|
rewrite_path_fixed_dirfile(seq->strip->dir, se->name,
|
||||||
|
visit_cb, absbase, bpath_user_data);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
@ -430,6 +430,15 @@ void range_vn_i(int *array_tar, const int size, const int start)
|
|||||||
while(i--) { *(array_pt--) = j--; }
|
while(i--) { *(array_pt--) = j--; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void range_vn_fl(float *array_tar, const int size, const float start, const float step)
|
||||||
|
{
|
||||||
|
float *array_pt= array_tar + (size-1);
|
||||||
|
int i= size;
|
||||||
|
while(i--) {
|
||||||
|
*(array_pt--) = start + step * (float)(i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void negate_vn(float *array_tar, const int size)
|
void negate_vn(float *array_tar, const int size)
|
||||||
{
|
{
|
||||||
float *array_pt= array_tar + (size-1);
|
float *array_pt= array_tar + (size-1);
|
||||||
|
@ -330,7 +330,6 @@ static void uiPanelPop(uiBlock *UNUSED(block))
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* triangle 'icon' for panel header */
|
/* triangle 'icon' for panel header */
|
||||||
/* NOTE - this seems to be only used for hiding nodes now */
|
|
||||||
void UI_DrawTriIcon(float x, float y, char dir)
|
void UI_DrawTriIcon(float x, float y, char dir)
|
||||||
{
|
{
|
||||||
if(dir=='h') {
|
if(dir=='h') {
|
||||||
|
@ -1071,7 +1071,6 @@ ARegion *ui_searchbox_create(bContext *C, ARegion *butregion, uiBut *but)
|
|||||||
/* copy to int, gets projected if possible too */
|
/* copy to int, gets projected if possible too */
|
||||||
x1= x1f; y1= y1f; x2= x2f; y2= y2f;
|
x1= x1f; y1= y1f; x2= x2f; y2= y2f;
|
||||||
|
|
||||||
if(butregion) {
|
|
||||||
if(butregion->v2d.cur.xmin != butregion->v2d.cur.xmax) {
|
if(butregion->v2d.cur.xmin != butregion->v2d.cur.xmax) {
|
||||||
UI_view2d_to_region_no_clip(&butregion->v2d, x1f, y1f, &x1, &y1);
|
UI_view2d_to_region_no_clip(&butregion->v2d, x1f, y1f, &x1, &y1);
|
||||||
UI_view2d_to_region_no_clip(&butregion->v2d, x2f, y2f, &x2, &y2);
|
UI_view2d_to_region_no_clip(&butregion->v2d, x2f, y2f, &x2, &y2);
|
||||||
@ -1081,7 +1080,6 @@ ARegion *ui_searchbox_create(bContext *C, ARegion *butregion, uiBut *but)
|
|||||||
x2 += butregion->winrct.xmin;
|
x2 += butregion->winrct.xmin;
|
||||||
y1 += butregion->winrct.ymin;
|
y1 += butregion->winrct.ymin;
|
||||||
y2 += butregion->winrct.ymin;
|
y2 += butregion->winrct.ymin;
|
||||||
}
|
|
||||||
|
|
||||||
wm_window_get_size(CTX_wm_window(C), &winx, &winy);
|
wm_window_get_size(CTX_wm_window(C), &winx, &winy);
|
||||||
|
|
||||||
@ -1096,7 +1094,8 @@ ARegion *ui_searchbox_create(bContext *C, ARegion *butregion, uiBut *but)
|
|||||||
x2= winx;
|
x2= winx;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(y1 < 0) { /* XXX butregion NULL check?, there is one above */
|
|
||||||
|
if(y1 < 0) {
|
||||||
int newy1;
|
int newy1;
|
||||||
UI_view2d_to_region_no_clip(&butregion->v2d, 0, but->y2 + ofsy, NULL, &newy1);
|
UI_view2d_to_region_no_clip(&butregion->v2d, 0, but->y2 + ofsy, NULL, &newy1);
|
||||||
newy1 += butregion->winrct.ymin;
|
newy1 += butregion->winrct.ymin;
|
||||||
|
@ -894,7 +894,7 @@ static void moveCloserToDistanceFromPlane(Scene *scene, Object *ob, Mesh *me, in
|
|||||||
int totweight = dvert->totweight;
|
int totweight = dvert->totweight;
|
||||||
float oldw = 0;
|
float oldw = 0;
|
||||||
float oldPos[3] = {0};
|
float oldPos[3] = {0};
|
||||||
float vc, hc, dist;
|
float vc, hc, dist = 0.0f;
|
||||||
int i, k;
|
int i, k;
|
||||||
float (*changes)[2] = MEM_mallocN(sizeof(float *)*totweight*2, "vertHorzChange");
|
float (*changes)[2] = MEM_mallocN(sizeof(float *)*totweight*2, "vertHorzChange");
|
||||||
float *dists = MEM_mallocN(sizeof(float)*totweight, "distance");
|
float *dists = MEM_mallocN(sizeof(float)*totweight, "distance");
|
||||||
|
@ -1688,7 +1688,7 @@ static void calc_flatten_center(Sculpt *sd, Object *ob, PBVHNode **nodes, int to
|
|||||||
if(ss->cache->original) {
|
if(ss->cache->original) {
|
||||||
BLI_pbvh_vertex_iter_begin(ss->pbvh, nodes[n], vd, PBVH_ITER_UNIQUE) {
|
BLI_pbvh_vertex_iter_begin(ss->pbvh, nodes[n], vd, PBVH_ITER_UNIQUE) {
|
||||||
if(sculpt_brush_test_fast(&test, unode->co[vd.i])) {
|
if(sculpt_brush_test_fast(&test, unode->co[vd.i])) {
|
||||||
add_v3_v3(private_fc, vd.co);
|
add_v3_v3(private_fc, unode->co[vd.i]);
|
||||||
private_count++;
|
private_count++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1758,7 +1758,7 @@ static void calc_area_normal_and_flatten_center(Sculpt *sd, Object *ob, PBVHNode
|
|||||||
add_norm_if(ss->cache->view_normal, private_an, private_out_flip, fno);
|
add_norm_if(ss->cache->view_normal, private_an, private_out_flip, fno);
|
||||||
|
|
||||||
// fc
|
// fc
|
||||||
add_v3_v3(private_fc, vd.co);
|
add_v3_v3(private_fc, unode->co[vd.i]);
|
||||||
private_count++;
|
private_count++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -562,6 +562,18 @@ static void node_draw_preview(bNodePreview *preview, rctf *prv)
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* common handle function for operator buttons that need to select the node first */
|
||||||
|
static void node_toggle_button_cb(struct bContext *C, void *node_argv, void *op_argv)
|
||||||
|
{
|
||||||
|
bNode *node = (bNode*)node_argv;
|
||||||
|
const char *opname = (const char *)op_argv;
|
||||||
|
|
||||||
|
/* select & activate only the button's node */
|
||||||
|
node_select_single(C, node);
|
||||||
|
|
||||||
|
WM_operator_name_call(C, opname, WM_OP_INVOKE_DEFAULT, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
static void node_draw_basis(const bContext *C, ARegion *ar, SpaceNode *snode, bNodeTree *ntree, bNode *node)
|
static void node_draw_basis(const bContext *C, ARegion *ar, SpaceNode *snode, bNodeTree *ntree, bNode *node)
|
||||||
{
|
{
|
||||||
bNodeSocket *sock;
|
bNodeSocket *sock;
|
||||||
@ -601,39 +613,34 @@ static void node_draw_basis(const bContext *C, ARegion *ar, SpaceNode *snode, bN
|
|||||||
uiSetRoundBox(UI_CNR_TOP_LEFT | UI_CNR_TOP_RIGHT);
|
uiSetRoundBox(UI_CNR_TOP_LEFT | UI_CNR_TOP_RIGHT);
|
||||||
uiRoundBox(rct->xmin, rct->ymax-NODE_DY, rct->xmax, rct->ymax, BASIS_RAD);
|
uiRoundBox(rct->xmin, rct->ymax-NODE_DY, rct->xmax, rct->ymax, BASIS_RAD);
|
||||||
|
|
||||||
/* show/hide icons, note this sequence is copied in do_header_node() node_state.c */
|
/* show/hide icons */
|
||||||
iconofs= rct->xmax - 7.0f;
|
iconofs= rct->xmax - 7.0f;
|
||||||
|
|
||||||
|
/* preview */
|
||||||
if(node->typeinfo->flag & NODE_PREVIEW) {
|
if(node->typeinfo->flag & NODE_PREVIEW) {
|
||||||
float alpha = (node->flag & (NODE_ACTIVE_ID|NODE_DO_OUTPUT))? 1.0f: 0.5f;
|
uiBut *but;
|
||||||
|
|
||||||
iconofs-=iconbutw;
|
iconofs-=iconbutw;
|
||||||
uiDefIconBut(node->block, LABEL, B_REDR, ICON_MATERIAL, iconofs, rct->ymax-NODE_DY,
|
uiBlockSetEmboss(node->block, UI_EMBOSSN);
|
||||||
iconbutw, UI_UNIT_Y, NULL, 0.0, 0.0, 1.0, alpha, "");
|
but = uiDefIconBut(node->block, TOGBUT, B_REDR, ICON_MATERIAL,
|
||||||
|
iconofs, rct->ymax-NODE_DY, iconbutw, UI_UNIT_Y, NULL, 0, 0, 0, 0, "");
|
||||||
|
uiButSetFunc(but, node_toggle_button_cb, node, (void*)"NODE_OT_preview_toggle");
|
||||||
|
/* XXX this does not work when node is activated and the operator called right afterwards,
|
||||||
|
* since active ID is not updated yet (needs to process the notifier).
|
||||||
|
* This can only work as visual indicator!
|
||||||
|
*/
|
||||||
|
// if (!(node->flag & (NODE_ACTIVE_ID|NODE_DO_OUTPUT)))
|
||||||
|
// uiButSetFlag(but, UI_BUT_DISABLED);
|
||||||
|
uiBlockSetEmboss(node->block, UI_EMBOSS);
|
||||||
}
|
}
|
||||||
|
/* group edit */
|
||||||
if(node->type == NODE_GROUP) {
|
if(node->type == NODE_GROUP) {
|
||||||
|
uiBut *but;
|
||||||
iconofs-=iconbutw;
|
iconofs-=iconbutw;
|
||||||
uiDefIconBut(node->block, LABEL, B_REDR, ICON_NODETREE, iconofs, rct->ymax-NODE_DY,
|
uiBlockSetEmboss(node->block, UI_EMBOSSN);
|
||||||
iconbutw, UI_UNIT_Y, NULL, 0.0, 0.0, 1.0, 0.5, "");
|
but = uiDefIconBut(node->block, TOGBUT, B_REDR, ICON_NODETREE,
|
||||||
}
|
iconofs, rct->ymax-NODE_DY, iconbutw, UI_UNIT_Y, NULL, 0, 0, 0, 0, "");
|
||||||
if(node->typeinfo->flag & NODE_OPTIONS) {
|
uiButSetFunc(but, node_toggle_button_cb, node, (void*)"NODE_OT_group_edit");
|
||||||
iconofs-=iconbutw;
|
uiBlockSetEmboss(node->block, UI_EMBOSS);
|
||||||
uiDefIconBut(node->block, LABEL, B_REDR, ICON_BUTS, iconofs, rct->ymax-NODE_DY,
|
|
||||||
iconbutw, UI_UNIT_Y, NULL, 0.0, 0.0, 1.0, 0.5, "");
|
|
||||||
}
|
|
||||||
{ /* always hide/reveal unused sockets */
|
|
||||||
// XXX re-enable
|
|
||||||
/* int shade;
|
|
||||||
if(node_has_hidden_sockets(node))
|
|
||||||
shade= -40;
|
|
||||||
else
|
|
||||||
shade= -90; */
|
|
||||||
|
|
||||||
iconofs-=iconbutw;
|
|
||||||
|
|
||||||
uiDefIconBut(node->block, LABEL, B_REDR, ICON_PLUS, iconofs, rct->ymax-NODE_DY,
|
|
||||||
iconbutw, UI_UNIT_Y, NULL, 0.0, 0.0, 1.0, 0.5, "");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* title */
|
/* title */
|
||||||
@ -643,7 +650,19 @@ static void node_draw_basis(const bContext *C, ARegion *ar, SpaceNode *snode, bN
|
|||||||
UI_ThemeColorBlendShade(TH_TEXT, color_id, 0.4f, 10);
|
UI_ThemeColorBlendShade(TH_TEXT, color_id, 0.4f, 10);
|
||||||
|
|
||||||
/* open/close entirely? */
|
/* open/close entirely? */
|
||||||
|
{
|
||||||
|
uiBut *but;
|
||||||
|
int but_size = UI_UNIT_X *0.6f;
|
||||||
|
/* XXX button uses a custom triangle draw below, so make it invisible without icon */
|
||||||
|
uiBlockSetEmboss(node->block, UI_EMBOSSN);
|
||||||
|
but = uiDefBut(node->block, TOGBUT, B_REDR, "",
|
||||||
|
rct->xmin+10.0f-but_size/2, rct->ymax-NODE_DY/2.0f-but_size/2, but_size, but_size, NULL, 0, 0, 0, 0, "");
|
||||||
|
uiButSetFunc(but, node_toggle_button_cb, node, (void*)"NODE_OT_hide_toggle");
|
||||||
|
uiBlockSetEmboss(node->block, UI_EMBOSS);
|
||||||
|
|
||||||
|
/* custom draw function for this button */
|
||||||
UI_DrawTriIcon(rct->xmin+10.0f, rct->ymax-NODE_DY/2.0f, 'v');
|
UI_DrawTriIcon(rct->xmin+10.0f, rct->ymax-NODE_DY/2.0f, 'v');
|
||||||
|
}
|
||||||
|
|
||||||
/* this isn't doing anything for the label, so commenting out
|
/* this isn't doing anything for the label, so commenting out
|
||||||
if(node->flag & SELECT)
|
if(node->flag & SELECT)
|
||||||
@ -789,7 +808,19 @@ static void node_draw_hidden(const bContext *C, ARegion *ar, SpaceNode *snode, b
|
|||||||
UI_ThemeColorBlendShade(TH_TEXT, color_id, 0.4f, 10);
|
UI_ThemeColorBlendShade(TH_TEXT, color_id, 0.4f, 10);
|
||||||
|
|
||||||
/* open entirely icon */
|
/* open entirely icon */
|
||||||
|
{
|
||||||
|
uiBut *but;
|
||||||
|
int but_size = UI_UNIT_X *0.6f;
|
||||||
|
/* XXX button uses a custom triangle draw below, so make it invisible without icon */
|
||||||
|
uiBlockSetEmboss(node->block, UI_EMBOSSN);
|
||||||
|
but = uiDefBut(node->block, TOGBUT, B_REDR, "",
|
||||||
|
rct->xmin+10.0f-but_size/2, centy-but_size/2, but_size, but_size, NULL, 0, 0, 0, 0, "");
|
||||||
|
uiButSetFunc(but, node_toggle_button_cb, node, (void*)"NODE_OT_hide_toggle");
|
||||||
|
uiBlockSetEmboss(node->block, UI_EMBOSS);
|
||||||
|
|
||||||
|
/* custom draw function for this button */
|
||||||
UI_DrawTriIcon(rct->xmin+10.0f, centy, 'h');
|
UI_DrawTriIcon(rct->xmin+10.0f, centy, 'h');
|
||||||
|
}
|
||||||
|
|
||||||
/* disable lines */
|
/* disable lines */
|
||||||
if(node->flag & NODE_MUTED)
|
if(node->flag & NODE_MUTED)
|
||||||
|
@ -690,108 +690,6 @@ void ED_node_set_active(Main *bmain, bNodeTree *ntree, bNode *node)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int compare_nodes(bNode *a, bNode *b)
|
|
||||||
{
|
|
||||||
bNode *parent;
|
|
||||||
/* These tell if either the node or any of the parent nodes is selected.
|
|
||||||
* A selected parent means an unselected node is also in foreground!
|
|
||||||
*/
|
|
||||||
int a_select=(a->flag & NODE_SELECT), b_select=(b->flag & NODE_SELECT);
|
|
||||||
int a_active=(a->flag & NODE_ACTIVE), b_active=(b->flag & NODE_ACTIVE);
|
|
||||||
|
|
||||||
/* if one is an ancestor of the other */
|
|
||||||
/* XXX there might be a better sorting algorithm for stable topological sort, this is O(n^2) worst case */
|
|
||||||
for (parent = a->parent; parent; parent=parent->parent) {
|
|
||||||
/* if b is an ancestor, it is always behind a */
|
|
||||||
if (parent==b)
|
|
||||||
return 1;
|
|
||||||
/* any selected ancestor moves the node forward */
|
|
||||||
if (parent->flag & NODE_ACTIVE)
|
|
||||||
a_active = 1;
|
|
||||||
if (parent->flag & NODE_SELECT)
|
|
||||||
a_select = 1;
|
|
||||||
}
|
|
||||||
for (parent = b->parent; parent; parent=parent->parent) {
|
|
||||||
/* if a is an ancestor, it is always behind b */
|
|
||||||
if (parent==a)
|
|
||||||
return 0;
|
|
||||||
/* any selected ancestor moves the node forward */
|
|
||||||
if (parent->flag & NODE_ACTIVE)
|
|
||||||
b_active = 1;
|
|
||||||
if (parent->flag & NODE_SELECT)
|
|
||||||
b_select = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* if one of the nodes is in the background and the other not */
|
|
||||||
if ((a->flag & NODE_BACKGROUND) && !(b->flag & NODE_BACKGROUND))
|
|
||||||
return 0;
|
|
||||||
else if (!(a->flag & NODE_BACKGROUND) && (b->flag & NODE_BACKGROUND))
|
|
||||||
return 1;
|
|
||||||
|
|
||||||
/* if one has a higher selection state (active > selected > nothing) */
|
|
||||||
if (!b_active && a_active)
|
|
||||||
return 1;
|
|
||||||
else if (!b_select && (a_active || a_select))
|
|
||||||
return 1;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
/* Sorts nodes by selection: unselected nodes first, then selected,
|
|
||||||
* then the active node at the very end. Relative order is kept intact!
|
|
||||||
*/
|
|
||||||
void node_sort(bNodeTree *ntree)
|
|
||||||
{
|
|
||||||
/* merge sort is the algorithm of choice here */
|
|
||||||
bNode *first_a, *first_b, *node_a, *node_b, *tmp;
|
|
||||||
int totnodes= BLI_countlist(&ntree->nodes);
|
|
||||||
int k, a, b;
|
|
||||||
|
|
||||||
k = 1;
|
|
||||||
while (k < totnodes) {
|
|
||||||
first_a = first_b = ntree->nodes.first;
|
|
||||||
|
|
||||||
do {
|
|
||||||
/* setup first_b pointer */
|
|
||||||
for (b=0; b < k && first_b; ++b) {
|
|
||||||
first_b = first_b->next;
|
|
||||||
}
|
|
||||||
/* all batches merged? */
|
|
||||||
if (first_b==NULL)
|
|
||||||
break;
|
|
||||||
|
|
||||||
/* merge batches */
|
|
||||||
node_a = first_a;
|
|
||||||
node_b = first_b;
|
|
||||||
a = b = 0;
|
|
||||||
while (a < k && b < k && node_b) {
|
|
||||||
if (compare_nodes(node_a, node_b)==0) {
|
|
||||||
node_a = node_a->next;
|
|
||||||
++a;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
tmp = node_b;
|
|
||||||
node_b = node_b->next;
|
|
||||||
++b;
|
|
||||||
BLI_remlink(&ntree->nodes, tmp);
|
|
||||||
BLI_insertlinkbefore(&ntree->nodes, node_a, tmp);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* setup first pointers for next batch */
|
|
||||||
first_b = node_b;
|
|
||||||
for (; b < k; ++b) {
|
|
||||||
/* all nodes sorted? */
|
|
||||||
if (first_b==NULL)
|
|
||||||
break;
|
|
||||||
first_b = first_b->next;
|
|
||||||
}
|
|
||||||
first_a = first_b;
|
|
||||||
} while (first_b);
|
|
||||||
|
|
||||||
k = k << 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static int inside_rctf(rctf *bounds, rctf *rect)
|
static int inside_rctf(rctf *bounds, rctf *rect)
|
||||||
{
|
{
|
||||||
return (bounds->xmin <= rect->xmin && bounds->xmax >= rect->xmax
|
return (bounds->xmin <= rect->xmin && bounds->xmax >= rect->xmax
|
||||||
@ -940,7 +838,7 @@ static int node_group_edit_exec(bContext *C, wmOperator *UNUSED(op))
|
|||||||
ED_preview_kill_jobs(C);
|
ED_preview_kill_jobs(C);
|
||||||
|
|
||||||
if (snode->nodetree==snode->edittree) {
|
if (snode->nodetree==snode->edittree) {
|
||||||
bNode *gnode= nodeGetActive(snode->nodetree);
|
bNode *gnode = nodeGetActive(snode->edittree);
|
||||||
snode_make_group_editable(snode, gnode);
|
snode_make_group_editable(snode, gnode);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -956,7 +854,10 @@ static int node_group_edit_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(e
|
|||||||
SpaceNode *snode = CTX_wm_space_node(C);
|
SpaceNode *snode = CTX_wm_space_node(C);
|
||||||
bNode *gnode;
|
bNode *gnode;
|
||||||
|
|
||||||
gnode= nodeGetActive(snode->edittree);
|
gnode = nodeGetActive(snode->edittree);
|
||||||
|
if (!gnode)
|
||||||
|
return OPERATOR_CANCELLED;
|
||||||
|
|
||||||
/* XXX callback? */
|
/* XXX callback? */
|
||||||
if(gnode && gnode->id && GS(gnode->id->name)==ID_NT && gnode->id->lib) {
|
if(gnode && gnode->id && GS(gnode->id->name)==ID_NT && gnode->id->lib) {
|
||||||
uiPupMenuOkee(C, op->type->idname, "Make group local?");
|
uiPupMenuOkee(C, op->type->idname, "Make group local?");
|
||||||
@ -1696,90 +1597,8 @@ void NODE_OT_resize(wmOperatorType *ot)
|
|||||||
ot->flag= OPTYPE_BLOCKING;
|
ot->flag= OPTYPE_BLOCKING;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ********************** select ******************** */
|
|
||||||
|
|
||||||
|
/* ********************** hidden sockets ******************** */
|
||||||
/* no undo here! */
|
|
||||||
void node_deselectall(SpaceNode *snode)
|
|
||||||
{
|
|
||||||
bNode *node;
|
|
||||||
|
|
||||||
for(node= snode->edittree->nodes.first; node; node= node->next)
|
|
||||||
node->flag &= ~SELECT;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* return 1 if we need redraw otherwise zero. */
|
|
||||||
int node_select_same_type(SpaceNode *snode)
|
|
||||||
{
|
|
||||||
bNode *nac, *p;
|
|
||||||
int redraw;
|
|
||||||
|
|
||||||
/* search for the active node. */
|
|
||||||
for (nac= snode->edittree->nodes.first; nac; nac= nac->next) {
|
|
||||||
if (nac->flag & SELECT)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* no active node, return. */
|
|
||||||
if (!nac)
|
|
||||||
return(0);
|
|
||||||
|
|
||||||
redraw= 0;
|
|
||||||
for (p= snode->edittree->nodes.first; p; p= p->next) {
|
|
||||||
if (p->type != nac->type && p->flag & SELECT) {
|
|
||||||
/* if it's selected but different type, unselect */
|
|
||||||
redraw= 1;
|
|
||||||
p->flag &= ~SELECT;
|
|
||||||
}
|
|
||||||
else if (p->type == nac->type && (!(p->flag & SELECT))) {
|
|
||||||
/* if it's the same type and is not selected, select! */
|
|
||||||
redraw= 1;
|
|
||||||
p->flag |= SELECT;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return(redraw);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* return 1 if we need redraw, otherwise zero.
|
|
||||||
* dir can be 0 == next or 0 != prev.
|
|
||||||
*/
|
|
||||||
int node_select_same_type_np(SpaceNode *snode, int dir)
|
|
||||||
{
|
|
||||||
bNode *nac, *p;
|
|
||||||
|
|
||||||
/* search the active one. */
|
|
||||||
for (nac= snode->edittree->nodes.first; nac; nac= nac->next) {
|
|
||||||
if (nac->flag & SELECT)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* no active node, return. */
|
|
||||||
if (!nac)
|
|
||||||
return(0);
|
|
||||||
|
|
||||||
if (dir == 0)
|
|
||||||
p= nac->next;
|
|
||||||
else
|
|
||||||
p= nac->prev;
|
|
||||||
|
|
||||||
while (p) {
|
|
||||||
/* Now search the next with the same type. */
|
|
||||||
if (p->type == nac->type)
|
|
||||||
break;
|
|
||||||
|
|
||||||
if (dir == 0)
|
|
||||||
p= p->next;
|
|
||||||
else
|
|
||||||
p= p->prev;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (p) {
|
|
||||||
node_deselectall(snode);
|
|
||||||
p->flag |= SELECT;
|
|
||||||
return(1);
|
|
||||||
}
|
|
||||||
return(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
int node_has_hidden_sockets(bNode *node)
|
int node_has_hidden_sockets(bNode *node)
|
||||||
{
|
{
|
||||||
@ -1794,6 +1613,31 @@ int node_has_hidden_sockets(bNode *node)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* note: call node_tree_verify_groups(snode->nodetree) after this
|
||||||
|
*/
|
||||||
|
void node_set_hidden_sockets(SpaceNode *snode, bNode *node, int set)
|
||||||
|
{
|
||||||
|
bNodeSocket *sock;
|
||||||
|
|
||||||
|
if(set==0) {
|
||||||
|
for(sock= node->inputs.first; sock; sock= sock->next)
|
||||||
|
sock->flag &= ~SOCK_HIDDEN;
|
||||||
|
for(sock= node->outputs.first; sock; sock= sock->next)
|
||||||
|
sock->flag &= ~SOCK_HIDDEN;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
/* hide unused sockets */
|
||||||
|
for(sock= node->inputs.first; sock; sock= sock->next) {
|
||||||
|
if(sock->link==NULL)
|
||||||
|
sock->flag |= SOCK_HIDDEN;
|
||||||
|
}
|
||||||
|
for(sock= node->outputs.first; sock; sock= sock->next) {
|
||||||
|
if(nodeCountSocketLinks(snode->edittree, sock)==0)
|
||||||
|
sock->flag |= SOCK_HIDDEN;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void node_link_viewer(SpaceNode *snode, bNode *tonode)
|
static void node_link_viewer(SpaceNode *snode, bNode *tonode)
|
||||||
{
|
{
|
||||||
bNode *node;
|
bNode *node;
|
||||||
@ -2232,7 +2076,7 @@ bNode *node_add_node(SpaceNode *snode, Main *bmain, Scene *scene, bNodeTemplate
|
|||||||
{
|
{
|
||||||
bNode *node= NULL, *gnode;
|
bNode *node= NULL, *gnode;
|
||||||
|
|
||||||
node_deselectall(snode);
|
node_deselect_all(snode);
|
||||||
|
|
||||||
node = nodeAddNode(snode->edittree, ntemp);
|
node = nodeAddNode(snode->edittree, ntemp);
|
||||||
|
|
||||||
@ -3130,14 +2974,20 @@ void NODE_OT_group_make(wmOperatorType *ot)
|
|||||||
|
|
||||||
static void node_flag_toggle_exec(SpaceNode *snode, int toggle_flag)
|
static void node_flag_toggle_exec(SpaceNode *snode, int toggle_flag)
|
||||||
{
|
{
|
||||||
int tot_eq= 0, tot_neq= 0;
|
|
||||||
bNode *node;
|
bNode *node;
|
||||||
|
int tot_eq= 0, tot_neq= 0;
|
||||||
|
|
||||||
|
/* Toggles the flag on all selected nodes.
|
||||||
|
* If the flag is set on all nodes it is unset.
|
||||||
|
* If the flag is not set on all nodes, it is set.
|
||||||
|
*/
|
||||||
for(node= snode->edittree->nodes.first; node; node= node->next) {
|
for(node= snode->edittree->nodes.first; node; node= node->next) {
|
||||||
if(node->flag & SELECT) {
|
if(node->flag & SELECT) {
|
||||||
|
|
||||||
if(toggle_flag== NODE_PREVIEW && (node->typeinfo->flag & NODE_PREVIEW)==0)
|
if(toggle_flag== NODE_PREVIEW && (node->typeinfo->flag & NODE_PREVIEW)==0)
|
||||||
continue;
|
continue;
|
||||||
|
if(toggle_flag== NODE_OPTIONS && (node->typeinfo->flag & NODE_OPTIONS)==0)
|
||||||
|
continue;
|
||||||
|
|
||||||
if(node->flag & toggle_flag)
|
if(node->flag & toggle_flag)
|
||||||
tot_eq++;
|
tot_eq++;
|
||||||
@ -3150,6 +3000,8 @@ static void node_flag_toggle_exec(SpaceNode *snode, int toggle_flag)
|
|||||||
|
|
||||||
if(toggle_flag== NODE_PREVIEW && (node->typeinfo->flag & NODE_PREVIEW)==0)
|
if(toggle_flag== NODE_PREVIEW && (node->typeinfo->flag & NODE_PREVIEW)==0)
|
||||||
continue;
|
continue;
|
||||||
|
if(toggle_flag== NODE_OPTIONS && (node->typeinfo->flag & NODE_OPTIONS)==0)
|
||||||
|
continue;
|
||||||
|
|
||||||
if( (tot_eq && tot_neq) || tot_eq==0)
|
if( (tot_eq && tot_neq) || tot_eq==0)
|
||||||
node->flag |= toggle_flag;
|
node->flag |= toggle_flag;
|
||||||
@ -3159,7 +3011,7 @@ static void node_flag_toggle_exec(SpaceNode *snode, int toggle_flag)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int node_hide_exec(bContext *C, wmOperator *UNUSED(op))
|
static int node_hide_toggle_exec(bContext *C, wmOperator *UNUSED(op))
|
||||||
{
|
{
|
||||||
SpaceNode *snode= CTX_wm_space_node(C);
|
SpaceNode *snode= CTX_wm_space_node(C);
|
||||||
|
|
||||||
@ -3182,14 +3034,14 @@ void NODE_OT_hide_toggle(wmOperatorType *ot)
|
|||||||
ot->idname= "NODE_OT_hide_toggle";
|
ot->idname= "NODE_OT_hide_toggle";
|
||||||
|
|
||||||
/* callbacks */
|
/* callbacks */
|
||||||
ot->exec= node_hide_exec;
|
ot->exec= node_hide_toggle_exec;
|
||||||
ot->poll= ED_operator_node_active;
|
ot->poll= ED_operator_node_active;
|
||||||
|
|
||||||
/* flags */
|
/* flags */
|
||||||
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
|
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int node_preview_exec(bContext *C, wmOperator *UNUSED(op))
|
static int node_preview_toggle_exec(bContext *C, wmOperator *UNUSED(op))
|
||||||
{
|
{
|
||||||
SpaceNode *snode= CTX_wm_space_node(C);
|
SpaceNode *snode= CTX_wm_space_node(C);
|
||||||
|
|
||||||
@ -3214,7 +3066,37 @@ void NODE_OT_preview_toggle(wmOperatorType *ot)
|
|||||||
ot->idname= "NODE_OT_preview_toggle";
|
ot->idname= "NODE_OT_preview_toggle";
|
||||||
|
|
||||||
/* callbacks */
|
/* callbacks */
|
||||||
ot->exec= node_preview_exec;
|
ot->exec= node_preview_toggle_exec;
|
||||||
|
ot->poll= ED_operator_node_active;
|
||||||
|
|
||||||
|
/* flags */
|
||||||
|
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int node_options_toggle_exec(bContext *C, wmOperator *UNUSED(op))
|
||||||
|
{
|
||||||
|
SpaceNode *snode= CTX_wm_space_node(C);
|
||||||
|
|
||||||
|
/* sanity checking (poll callback checks this already) */
|
||||||
|
if((snode == NULL) || (snode->edittree == NULL))
|
||||||
|
return OPERATOR_CANCELLED;
|
||||||
|
|
||||||
|
node_flag_toggle_exec(snode, NODE_OPTIONS);
|
||||||
|
|
||||||
|
snode_notify(C, snode);
|
||||||
|
|
||||||
|
return OPERATOR_FINISHED;
|
||||||
|
}
|
||||||
|
|
||||||
|
void NODE_OT_options_toggle(wmOperatorType *ot)
|
||||||
|
{
|
||||||
|
/* identifiers */
|
||||||
|
ot->name= "Toggle Node Options";
|
||||||
|
ot->description= "Toggle option buttons display for selected nodes";
|
||||||
|
ot->idname= "NODE_OT_options_toggle";
|
||||||
|
|
||||||
|
/* callbacks */
|
||||||
|
ot->exec= node_options_toggle_exec;
|
||||||
ot->poll= ED_operator_node_active;
|
ot->poll= ED_operator_node_active;
|
||||||
|
|
||||||
/* flags */
|
/* flags */
|
||||||
@ -3225,7 +3107,7 @@ static int node_socket_toggle_exec(bContext *C, wmOperator *UNUSED(op))
|
|||||||
{
|
{
|
||||||
SpaceNode *snode= CTX_wm_space_node(C);
|
SpaceNode *snode= CTX_wm_space_node(C);
|
||||||
bNode *node;
|
bNode *node;
|
||||||
int hidden= 0;
|
int hidden;
|
||||||
|
|
||||||
/* sanity checking (poll callback checks this already) */
|
/* sanity checking (poll callback checks this already) */
|
||||||
if((snode == NULL) || (snode->edittree == NULL))
|
if((snode == NULL) || (snode->edittree == NULL))
|
||||||
@ -3233,6 +3115,8 @@ static int node_socket_toggle_exec(bContext *C, wmOperator *UNUSED(op))
|
|||||||
|
|
||||||
ED_preview_kill_jobs(C);
|
ED_preview_kill_jobs(C);
|
||||||
|
|
||||||
|
/* Toggle for all selected nodes */
|
||||||
|
hidden = 0;
|
||||||
for(node= snode->edittree->nodes.first; node; node= node->next) {
|
for(node= snode->edittree->nodes.first; node; node= node->next) {
|
||||||
if(node->flag & SELECT) {
|
if(node->flag & SELECT) {
|
||||||
if(node_has_hidden_sockets(node)) {
|
if(node_has_hidden_sockets(node)) {
|
||||||
@ -3570,7 +3454,7 @@ static int node_add_file_exec(bContext *C, wmOperator *op)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
node_deselectall(snode);
|
node_deselect_all(snode);
|
||||||
|
|
||||||
if (snode->nodetree->type==NTREE_COMPOSIT)
|
if (snode->nodetree->type==NTREE_COMPOSIT)
|
||||||
ntemp.type = CMP_NODE_IMAGE;
|
ntemp.type = CMP_NODE_IMAGE;
|
||||||
|
@ -82,17 +82,23 @@ void node_operatortypes(void);
|
|||||||
void node_keymap(wmKeyConfig *keyconf);
|
void node_keymap(wmKeyConfig *keyconf);
|
||||||
|
|
||||||
/* node_select.c */
|
/* node_select.c */
|
||||||
|
void node_deselect_all(struct SpaceNode *snode);
|
||||||
|
int node_select_same_type(struct SpaceNode *snode);
|
||||||
|
int node_select_same_type_np(struct SpaceNode *snode, int dir);
|
||||||
|
void node_select_single(struct bContext *C, struct bNode *node);
|
||||||
|
|
||||||
void NODE_OT_select(struct wmOperatorType *ot);
|
void NODE_OT_select(struct wmOperatorType *ot);
|
||||||
void NODE_OT_select_all(wmOperatorType *ot);
|
void NODE_OT_select_all(wmOperatorType *ot);
|
||||||
void NODE_OT_select_linked_to(wmOperatorType *ot);
|
void NODE_OT_select_linked_to(wmOperatorType *ot);
|
||||||
void NODE_OT_select_linked_from(wmOperatorType *ot);
|
void NODE_OT_select_linked_from(wmOperatorType *ot);
|
||||||
void NODE_OT_visibility_toggle(struct wmOperatorType *ot);
|
|
||||||
void NODE_OT_view_all(struct wmOperatorType *ot);
|
|
||||||
void NODE_OT_select_border(struct wmOperatorType *ot);
|
void NODE_OT_select_border(struct wmOperatorType *ot);
|
||||||
void NODE_OT_select_same_type(struct wmOperatorType *ot);
|
void NODE_OT_select_same_type(struct wmOperatorType *ot);
|
||||||
void NODE_OT_select_same_type_next(wmOperatorType *ot);
|
void NODE_OT_select_same_type_next(wmOperatorType *ot);
|
||||||
void NODE_OT_select_same_type_prev(wmOperatorType *ot);
|
void NODE_OT_select_same_type_prev(wmOperatorType *ot);
|
||||||
|
|
||||||
|
/* node_state.c */
|
||||||
|
void NODE_OT_view_all(struct wmOperatorType *ot);
|
||||||
|
|
||||||
/* drawnode.c */
|
/* drawnode.c */
|
||||||
void node_draw_link(View2D *v2d, SpaceNode *snode, bNodeLink *link);
|
void node_draw_link(View2D *v2d, SpaceNode *snode, bNodeLink *link);
|
||||||
void node_draw_link_bezier(View2D *v2d, SpaceNode *snode, bNodeLink *link, int th_col1, int do_shaded, int th_col2, int do_triple, int th_col3 );
|
void node_draw_link_bezier(View2D *v2d, SpaceNode *snode, bNodeLink *link, int th_col1, int do_shaded, int th_col2, int do_triple, int th_col3 );
|
||||||
@ -108,10 +114,6 @@ void snode_dag_update(bContext *C, SpaceNode *snode);
|
|||||||
bNode *node_add_node(struct SpaceNode *snode, struct Main *bmain, struct Scene *scene, struct bNodeTemplate *ntemp, float locx, float locy);
|
bNode *node_add_node(struct SpaceNode *snode, struct Main *bmain, struct Scene *scene, struct bNodeTemplate *ntemp, float locx, float locy);
|
||||||
void snode_set_context(SpaceNode *snode, Scene *scene);
|
void snode_set_context(SpaceNode *snode, Scene *scene);
|
||||||
void snode_make_group_editable(SpaceNode *snode, bNode *gnode);
|
void snode_make_group_editable(SpaceNode *snode, bNode *gnode);
|
||||||
void node_sort(struct bNodeTree *ntree);
|
|
||||||
void node_deselectall(SpaceNode *snode);
|
|
||||||
int node_select_same_type(SpaceNode *snode);
|
|
||||||
int node_select_same_type_np(SpaceNode *snode, int dir);
|
|
||||||
void snode_composite_job(const struct bContext *C, ScrArea *sa);
|
void snode_composite_job(const struct bContext *C, ScrArea *sa);
|
||||||
bNode *node_tree_get_editgroup(bNodeTree *ntree);
|
bNode *node_tree_get_editgroup(bNodeTree *ntree);
|
||||||
void node_tree_verify_groups(bNodeTree *nodetree);
|
void node_tree_verify_groups(bNodeTree *nodetree);
|
||||||
@ -141,6 +143,7 @@ void NODE_OT_mute_toggle(struct wmOperatorType *ot);
|
|||||||
void NODE_OT_hide_toggle(struct wmOperatorType *ot);
|
void NODE_OT_hide_toggle(struct wmOperatorType *ot);
|
||||||
void NODE_OT_hide_socket_toggle(struct wmOperatorType *ot);
|
void NODE_OT_hide_socket_toggle(struct wmOperatorType *ot);
|
||||||
void NODE_OT_preview_toggle(struct wmOperatorType *ot);
|
void NODE_OT_preview_toggle(struct wmOperatorType *ot);
|
||||||
|
void NODE_OT_options_toggle(struct wmOperatorType *ot);
|
||||||
|
|
||||||
void NODE_OT_show_cyclic_dependencies(struct wmOperatorType *ot);
|
void NODE_OT_show_cyclic_dependencies(struct wmOperatorType *ot);
|
||||||
void NODE_OT_link_viewer(struct wmOperatorType *ot);
|
void NODE_OT_link_viewer(struct wmOperatorType *ot);
|
||||||
|
@ -59,10 +59,11 @@ void node_operatortypes(void)
|
|||||||
WM_operatortype_append(NODE_OT_select_same_type_prev);
|
WM_operatortype_append(NODE_OT_select_same_type_prev);
|
||||||
|
|
||||||
WM_operatortype_append(NODE_OT_view_all);
|
WM_operatortype_append(NODE_OT_view_all);
|
||||||
WM_operatortype_append(NODE_OT_visibility_toggle);
|
|
||||||
WM_operatortype_append(NODE_OT_mute_toggle);
|
WM_operatortype_append(NODE_OT_mute_toggle);
|
||||||
WM_operatortype_append(NODE_OT_hide_toggle);
|
WM_operatortype_append(NODE_OT_hide_toggle);
|
||||||
WM_operatortype_append(NODE_OT_preview_toggle);
|
WM_operatortype_append(NODE_OT_preview_toggle);
|
||||||
|
WM_operatortype_append(NODE_OT_options_toggle);
|
||||||
WM_operatortype_append(NODE_OT_hide_socket_toggle);
|
WM_operatortype_append(NODE_OT_hide_socket_toggle);
|
||||||
WM_operatortype_append(NODE_OT_show_cyclic_dependencies);
|
WM_operatortype_append(NODE_OT_show_cyclic_dependencies);
|
||||||
|
|
||||||
@ -148,7 +149,6 @@ void node_keymap(struct wmKeyConfig *keyconf)
|
|||||||
/* each of these falls through if not handled... */
|
/* each of these falls through if not handled... */
|
||||||
WM_keymap_add_item(keymap, "NODE_OT_link", LEFTMOUSE, KM_PRESS, 0, 0);
|
WM_keymap_add_item(keymap, "NODE_OT_link", LEFTMOUSE, KM_PRESS, 0, 0);
|
||||||
WM_keymap_add_item(keymap, "NODE_OT_resize", LEFTMOUSE, KM_PRESS, 0, 0);
|
WM_keymap_add_item(keymap, "NODE_OT_resize", LEFTMOUSE, KM_PRESS, 0, 0);
|
||||||
WM_keymap_add_item(keymap, "NODE_OT_visibility_toggle", LEFTMOUSE, KM_PRESS, 0, 0);
|
|
||||||
|
|
||||||
WM_keymap_add_item(keymap, "NODE_OT_links_cut", LEFTMOUSE, KM_PRESS, KM_CTRL, 0);
|
WM_keymap_add_item(keymap, "NODE_OT_links_cut", LEFTMOUSE, KM_PRESS, KM_CTRL, 0);
|
||||||
WM_keymap_add_item(keymap, "NODE_OT_select_link_viewer", LEFTMOUSE, KM_PRESS, KM_SHIFT|KM_CTRL, 0);
|
WM_keymap_add_item(keymap, "NODE_OT_select_link_viewer", LEFTMOUSE, KM_PRESS, KM_SHIFT|KM_CTRL, 0);
|
||||||
|
@ -31,6 +31,8 @@
|
|||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
|
#include "BLI_listbase.h"
|
||||||
|
|
||||||
#include "DNA_node_types.h"
|
#include "DNA_node_types.h"
|
||||||
#include "DNA_scene_types.h"
|
#include "DNA_scene_types.h"
|
||||||
|
|
||||||
@ -68,6 +70,206 @@ static bNode *node_under_mouse(bNodeTree *ntree, int mx, int my)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int compare_nodes(bNode *a, bNode *b)
|
||||||
|
{
|
||||||
|
bNode *parent;
|
||||||
|
/* These tell if either the node or any of the parent nodes is selected.
|
||||||
|
* A selected parent means an unselected node is also in foreground!
|
||||||
|
*/
|
||||||
|
int a_select=(a->flag & NODE_SELECT), b_select=(b->flag & NODE_SELECT);
|
||||||
|
int a_active=(a->flag & NODE_ACTIVE), b_active=(b->flag & NODE_ACTIVE);
|
||||||
|
|
||||||
|
/* if one is an ancestor of the other */
|
||||||
|
/* XXX there might be a better sorting algorithm for stable topological sort, this is O(n^2) worst case */
|
||||||
|
for (parent = a->parent; parent; parent=parent->parent) {
|
||||||
|
/* if b is an ancestor, it is always behind a */
|
||||||
|
if (parent==b)
|
||||||
|
return 1;
|
||||||
|
/* any selected ancestor moves the node forward */
|
||||||
|
if (parent->flag & NODE_ACTIVE)
|
||||||
|
a_active = 1;
|
||||||
|
if (parent->flag & NODE_SELECT)
|
||||||
|
a_select = 1;
|
||||||
|
}
|
||||||
|
for (parent = b->parent; parent; parent=parent->parent) {
|
||||||
|
/* if a is an ancestor, it is always behind b */
|
||||||
|
if (parent==a)
|
||||||
|
return 0;
|
||||||
|
/* any selected ancestor moves the node forward */
|
||||||
|
if (parent->flag & NODE_ACTIVE)
|
||||||
|
b_active = 1;
|
||||||
|
if (parent->flag & NODE_SELECT)
|
||||||
|
b_select = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* if one of the nodes is in the background and the other not */
|
||||||
|
if ((a->flag & NODE_BACKGROUND) && !(b->flag & NODE_BACKGROUND))
|
||||||
|
return 0;
|
||||||
|
else if (!(a->flag & NODE_BACKGROUND) && (b->flag & NODE_BACKGROUND))
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
/* if one has a higher selection state (active > selected > nothing) */
|
||||||
|
if (!b_active && a_active)
|
||||||
|
return 1;
|
||||||
|
else if (!b_select && (a_active || a_select))
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Sorts nodes by selection: unselected nodes first, then selected,
|
||||||
|
* then the active node at the very end. Relative order is kept intact!
|
||||||
|
*/
|
||||||
|
static void node_sort(bNodeTree *ntree)
|
||||||
|
{
|
||||||
|
/* merge sort is the algorithm of choice here */
|
||||||
|
bNode *first_a, *first_b, *node_a, *node_b, *tmp;
|
||||||
|
int totnodes= BLI_countlist(&ntree->nodes);
|
||||||
|
int k, a, b;
|
||||||
|
|
||||||
|
k = 1;
|
||||||
|
while (k < totnodes) {
|
||||||
|
first_a = first_b = ntree->nodes.first;
|
||||||
|
|
||||||
|
do {
|
||||||
|
/* setup first_b pointer */
|
||||||
|
for (b=0; b < k && first_b; ++b) {
|
||||||
|
first_b = first_b->next;
|
||||||
|
}
|
||||||
|
/* all batches merged? */
|
||||||
|
if (first_b==NULL)
|
||||||
|
break;
|
||||||
|
|
||||||
|
/* merge batches */
|
||||||
|
node_a = first_a;
|
||||||
|
node_b = first_b;
|
||||||
|
a = b = 0;
|
||||||
|
while (a < k && b < k && node_b) {
|
||||||
|
if (compare_nodes(node_a, node_b)==0) {
|
||||||
|
node_a = node_a->next;
|
||||||
|
++a;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
tmp = node_b;
|
||||||
|
node_b = node_b->next;
|
||||||
|
++b;
|
||||||
|
BLI_remlink(&ntree->nodes, tmp);
|
||||||
|
BLI_insertlinkbefore(&ntree->nodes, node_a, tmp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* setup first pointers for next batch */
|
||||||
|
first_b = node_b;
|
||||||
|
for (; b < k; ++b) {
|
||||||
|
/* all nodes sorted? */
|
||||||
|
if (first_b==NULL)
|
||||||
|
break;
|
||||||
|
first_b = first_b->next;
|
||||||
|
}
|
||||||
|
first_a = first_b;
|
||||||
|
} while (first_b);
|
||||||
|
|
||||||
|
k = k << 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* no undo here! */
|
||||||
|
void node_deselect_all(SpaceNode *snode)
|
||||||
|
{
|
||||||
|
bNode *node;
|
||||||
|
|
||||||
|
for(node= snode->edittree->nodes.first; node; node= node->next)
|
||||||
|
node->flag &= ~SELECT;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* return 1 if we need redraw otherwise zero. */
|
||||||
|
int node_select_same_type(SpaceNode *snode)
|
||||||
|
{
|
||||||
|
bNode *nac, *p;
|
||||||
|
int redraw;
|
||||||
|
|
||||||
|
/* search for the active node. */
|
||||||
|
for (nac= snode->edittree->nodes.first; nac; nac= nac->next) {
|
||||||
|
if (nac->flag & SELECT)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* no active node, return. */
|
||||||
|
if (!nac)
|
||||||
|
return(0);
|
||||||
|
|
||||||
|
redraw= 0;
|
||||||
|
for (p= snode->edittree->nodes.first; p; p= p->next) {
|
||||||
|
if (p->type != nac->type && p->flag & SELECT) {
|
||||||
|
/* if it's selected but different type, unselect */
|
||||||
|
redraw= 1;
|
||||||
|
p->flag &= ~SELECT;
|
||||||
|
}
|
||||||
|
else if (p->type == nac->type && (!(p->flag & SELECT))) {
|
||||||
|
/* if it's the same type and is not selected, select! */
|
||||||
|
redraw= 1;
|
||||||
|
p->flag |= SELECT;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return(redraw);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* return 1 if we need redraw, otherwise zero.
|
||||||
|
* dir can be 0 == next or 0 != prev.
|
||||||
|
*/
|
||||||
|
int node_select_same_type_np(SpaceNode *snode, int dir)
|
||||||
|
{
|
||||||
|
bNode *nac, *p;
|
||||||
|
|
||||||
|
/* search the active one. */
|
||||||
|
for (nac= snode->edittree->nodes.first; nac; nac= nac->next) {
|
||||||
|
if (nac->flag & SELECT)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* no active node, return. */
|
||||||
|
if (!nac)
|
||||||
|
return(0);
|
||||||
|
|
||||||
|
if (dir == 0)
|
||||||
|
p= nac->next;
|
||||||
|
else
|
||||||
|
p= nac->prev;
|
||||||
|
|
||||||
|
while (p) {
|
||||||
|
/* Now search the next with the same type. */
|
||||||
|
if (p->type == nac->type)
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (dir == 0)
|
||||||
|
p= p->next;
|
||||||
|
else
|
||||||
|
p= p->prev;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (p) {
|
||||||
|
node_deselect_all(snode);
|
||||||
|
p->flag |= SELECT;
|
||||||
|
return(1);
|
||||||
|
}
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void node_select_single(bContext *C, bNode *node)
|
||||||
|
{
|
||||||
|
Main *bmain= CTX_data_main(C);
|
||||||
|
SpaceNode *snode= CTX_wm_space_node(C);
|
||||||
|
|
||||||
|
node_deselect_all(snode);
|
||||||
|
node->flag |= SELECT;
|
||||||
|
|
||||||
|
ED_node_set_active(bmain, snode->edittree, node);
|
||||||
|
|
||||||
|
node_sort(snode->edittree);
|
||||||
|
|
||||||
|
WM_event_add_notifier(C, NC_NODE|NA_SELECTED, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
/* ****** Click Select ****** */
|
/* ****** Click Select ****** */
|
||||||
|
|
||||||
static bNode *node_mouse_select(Main *bmain, SpaceNode *snode, ARegion *ar, const int mval[2], short extend)
|
static bNode *node_mouse_select(Main *bmain, SpaceNode *snode, ARegion *ar, const int mval[2], short extend)
|
||||||
@ -86,7 +288,7 @@ static bNode *node_mouse_select(Main *bmain, SpaceNode *snode, ARegion *ar, cons
|
|||||||
|
|
||||||
if (node) {
|
if (node) {
|
||||||
if (extend == 0) {
|
if (extend == 0) {
|
||||||
node_deselectall(snode);
|
node_deselect_all(snode);
|
||||||
node->flag |= SELECT;
|
node->flag |= SELECT;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -52,160 +52,6 @@
|
|||||||
|
|
||||||
#include "node_intern.h"
|
#include "node_intern.h"
|
||||||
|
|
||||||
/* **************** Node Header Buttons ************** */
|
|
||||||
|
|
||||||
/* note: call node_tree_verify_groups(snode->nodetree) after this
|
|
||||||
*/
|
|
||||||
void node_set_hidden_sockets(SpaceNode *snode, bNode *node, int set)
|
|
||||||
{
|
|
||||||
bNodeSocket *sock;
|
|
||||||
|
|
||||||
if(set==0) {
|
|
||||||
for(sock= node->inputs.first; sock; sock= sock->next)
|
|
||||||
sock->flag &= ~SOCK_HIDDEN;
|
|
||||||
for(sock= node->outputs.first; sock; sock= sock->next)
|
|
||||||
sock->flag &= ~SOCK_HIDDEN;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
/* hide unused sockets */
|
|
||||||
for(sock= node->inputs.first; sock; sock= sock->next) {
|
|
||||||
if(sock->link==NULL)
|
|
||||||
sock->flag |= SOCK_HIDDEN;
|
|
||||||
}
|
|
||||||
for(sock= node->outputs.first; sock; sock= sock->next) {
|
|
||||||
if(nodeCountSocketLinks(snode->edittree, sock)==0)
|
|
||||||
sock->flag |= SOCK_HIDDEN;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void node_hide_unhide_sockets(SpaceNode *snode, bNode *node)
|
|
||||||
{
|
|
||||||
node_set_hidden_sockets(snode, node, !node_has_hidden_sockets(node));
|
|
||||||
ntreeUpdateTree(snode->edittree);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int do_header_node(SpaceNode *snode, bNode *node, float mx, float my)
|
|
||||||
{
|
|
||||||
rctf totr= node->totr;
|
|
||||||
|
|
||||||
totr.ymin= totr.ymax-20.0f;
|
|
||||||
|
|
||||||
totr.xmax= totr.xmin+15.0f;
|
|
||||||
if(BLI_in_rctf(&totr, mx, my)) {
|
|
||||||
node->flag |= NODE_HIDDEN;
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
totr.xmax= node->totr.xmax;
|
|
||||||
totr.xmin= totr.xmax-18.0f;
|
|
||||||
if(node->typeinfo->flag & NODE_PREVIEW) {
|
|
||||||
if(BLI_in_rctf(&totr, mx, my)) {
|
|
||||||
node->flag ^= NODE_PREVIEW;
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
totr.xmin-=15.0f;
|
|
||||||
}
|
|
||||||
if(node->type == NODE_GROUP) {
|
|
||||||
if(BLI_in_rctf(&totr, mx, my)) {
|
|
||||||
snode_make_group_editable(snode, node);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
totr.xmin-=15.0f;
|
|
||||||
}
|
|
||||||
if(node->typeinfo->flag & NODE_OPTIONS) {
|
|
||||||
if(BLI_in_rctf(&totr, mx, my)) {
|
|
||||||
node->flag ^= NODE_OPTIONS;
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
totr.xmin-=15.0f;
|
|
||||||
}
|
|
||||||
/* hide unused sockets */
|
|
||||||
if(BLI_in_rctf(&totr, mx, my)) {
|
|
||||||
node_hide_unhide_sockets(snode, node);
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int do_header_hidden_node(bNode *node, float mx, float my)
|
|
||||||
{
|
|
||||||
rctf totr= node->totr;
|
|
||||||
|
|
||||||
totr.xmax= totr.xmin+15.0f;
|
|
||||||
if(BLI_in_rctf(&totr, mx, my)) {
|
|
||||||
node->flag &= ~NODE_HIDDEN;
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int node_toggle_visibility(SpaceNode *snode, ARegion *ar, const int mval[2])
|
|
||||||
{
|
|
||||||
bNode *node;
|
|
||||||
float mx, my;
|
|
||||||
|
|
||||||
mx= (float)mval[0];
|
|
||||||
my= (float)mval[1];
|
|
||||||
|
|
||||||
UI_view2d_region_to_view(&ar->v2d, mval[0], mval[1], &mx, &my);
|
|
||||||
|
|
||||||
for(node=snode->edittree->nodes.last; node; node=node->prev) {
|
|
||||||
if(node->flag & NODE_HIDDEN) {
|
|
||||||
if(do_header_hidden_node(node, mx, my)) {
|
|
||||||
ED_region_tag_redraw(ar);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
if(do_header_node(snode, node, mx, my)) {
|
|
||||||
ED_region_tag_redraw(ar);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int node_toggle_visibility_exec(bContext *C, wmOperator *op)
|
|
||||||
{
|
|
||||||
SpaceNode *snode= CTX_wm_space_node(C);
|
|
||||||
ARegion *ar= CTX_wm_region(C);
|
|
||||||
int mval[2];
|
|
||||||
|
|
||||||
mval[0] = RNA_int_get(op->ptr, "mouse_x");
|
|
||||||
mval[1] = RNA_int_get(op->ptr, "mouse_y");
|
|
||||||
if(node_toggle_visibility(snode, ar, mval))
|
|
||||||
return OPERATOR_FINISHED;
|
|
||||||
else
|
|
||||||
return OPERATOR_CANCELLED|OPERATOR_PASS_THROUGH;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int node_toggle_visibility_invoke(bContext *C, wmOperator *op, wmEvent *event)
|
|
||||||
{
|
|
||||||
RNA_int_set(op->ptr, "mouse_x", event->mval[0]);
|
|
||||||
RNA_int_set(op->ptr, "mouse_y", event->mval[1]);
|
|
||||||
|
|
||||||
return node_toggle_visibility_exec(C,op);
|
|
||||||
}
|
|
||||||
|
|
||||||
void NODE_OT_visibility_toggle(wmOperatorType *ot)
|
|
||||||
{
|
|
||||||
/* identifiers */
|
|
||||||
ot->name= "Toggle Visibility";
|
|
||||||
ot->idname= "NODE_OT_visibility_toggle";
|
|
||||||
ot->description= "Handle clicks on node header buttons";
|
|
||||||
|
|
||||||
/* api callbacks */
|
|
||||||
ot->invoke= node_toggle_visibility_invoke;
|
|
||||||
ot->poll= ED_operator_node_active;
|
|
||||||
|
|
||||||
/* flags */
|
|
||||||
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
|
|
||||||
|
|
||||||
RNA_def_int(ot->srna, "mouse_x", 0, INT_MIN, INT_MAX, "Mouse X", "", INT_MIN, INT_MAX);
|
|
||||||
RNA_def_int(ot->srna, "mouse_y", 0, INT_MIN, INT_MAX, "Mouse Y", "", INT_MIN, INT_MAX);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* **************** View All Operator ************** */
|
/* **************** View All Operator ************** */
|
||||||
|
|
||||||
|
@ -724,8 +724,7 @@ static void find_nearest_uv_face(Scene *scene, Image *ima, BMEditMesh *em, float
|
|||||||
BM_ITER(l, &liter, em->bm, BM_LOOPS_OF_FACE, efa) {
|
BM_ITER(l, &liter, em->bm, BM_LOOPS_OF_FACE, efa) {
|
||||||
luv = CustomData_bmesh_get(&em->bm->ldata, l->head.data, CD_MLOOPUV);
|
luv = CustomData_bmesh_get(&em->bm->ldata, l->head.data, CD_MLOOPUV);
|
||||||
|
|
||||||
cent[0] += luv->uv[0];
|
add_v2_v2(cent, luv->uv);
|
||||||
cent[1] += luv->uv[1];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
cent[0] /= efa->len;
|
cent[0] /= efa->len;
|
||||||
|
@ -112,6 +112,8 @@ void GPU_extensions_init(void)
|
|||||||
if (!GLEW_ARB_vertex_shader) GG.glslsupport = 0;
|
if (!GLEW_ARB_vertex_shader) GG.glslsupport = 0;
|
||||||
if (!GLEW_ARB_fragment_shader) GG.glslsupport = 0;
|
if (!GLEW_ARB_fragment_shader) GG.glslsupport = 0;
|
||||||
|
|
||||||
|
GPU_code_generate_glsl_lib();
|
||||||
|
|
||||||
glGetIntegerv(GL_RED_BITS, &r);
|
glGetIntegerv(GL_RED_BITS, &r);
|
||||||
glGetIntegerv(GL_GREEN_BITS, &g);
|
glGetIntegerv(GL_GREEN_BITS, &g);
|
||||||
glGetIntegerv(GL_BLUE_BITS, &b);
|
glGetIntegerv(GL_BLUE_BITS, &b);
|
||||||
|
@ -67,6 +67,10 @@ EnumPropertyItem node_socket_type_items[] = {
|
|||||||
{SOCK_FLOAT, "VALUE", 0, "Value", ""},
|
{SOCK_FLOAT, "VALUE", 0, "Value", ""},
|
||||||
{SOCK_VECTOR, "VECTOR", 0, "Vector", ""},
|
{SOCK_VECTOR, "VECTOR", 0, "Vector", ""},
|
||||||
{SOCK_RGBA, "RGBA", 0, "RGBA", ""},
|
{SOCK_RGBA, "RGBA", 0, "RGBA", ""},
|
||||||
|
{SOCK_SHADER, "SHADER", 0, "Shader", ""},
|
||||||
|
{SOCK_BOOLEAN, "BOOLEAN", 0, "Boolean", ""},
|
||||||
|
{SOCK_MESH, "MESH", 0, "Mesh", ""},
|
||||||
|
{SOCK_INT, "INT", 0, "Int", ""},
|
||||||
{0, NULL, 0, NULL, NULL}};
|
{0, NULL, 0, NULL, NULL}};
|
||||||
|
|
||||||
EnumPropertyItem node_math_items[] = {
|
EnumPropertyItem node_math_items[] = {
|
||||||
|
@ -810,11 +810,11 @@ static void rna_MaterialSlot_link_set(PointerRNA *ptr, int value)
|
|||||||
|
|
||||||
if(value) {
|
if(value) {
|
||||||
ob->matbits[index]= 1;
|
ob->matbits[index]= 1;
|
||||||
ob->colbits |= (1<<index);
|
/* ob->colbits |= (1<<index); */ /* DEPRECATED */
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
ob->matbits[index]= 0;
|
ob->matbits[index]= 0;
|
||||||
ob->colbits &= ~(1<<index);
|
/* ob->colbits &= ~(1<<index); */ /* DEPRECATED */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -191,15 +191,14 @@ Mesh *rna_Object_to_mesh(Object *ob, ReportList *reports, Scene *sce, int apply_
|
|||||||
if( tmpcu->mat ) {
|
if( tmpcu->mat ) {
|
||||||
for( i = tmpcu->totcol; i-- > 0; ) {
|
for( i = tmpcu->totcol; i-- > 0; ) {
|
||||||
/* are we an object material or data based? */
|
/* are we an object material or data based? */
|
||||||
if (ob->colbits & 1<<i)
|
|
||||||
tmpmesh->mat[i] = ob->mat[i];
|
|
||||||
else
|
|
||||||
tmpmesh->mat[i] = tmpcu->mat[i];
|
|
||||||
|
|
||||||
if (tmpmesh->mat[i])
|
tmpmesh->mat[i] = ob->matbits[i] ? ob->mat[i] : tmpcu->mat[i];
|
||||||
|
|
||||||
|
if (tmpmesh->mat[i]) {
|
||||||
tmpmesh->mat[i]->id.us++;
|
tmpmesh->mat[i]->id.us++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
@ -230,15 +229,14 @@ Mesh *rna_Object_to_mesh(Object *ob, ReportList *reports, Scene *sce, int apply_
|
|||||||
if( origmesh->mat ) {
|
if( origmesh->mat ) {
|
||||||
for( i = origmesh->totcol; i-- > 0; ) {
|
for( i = origmesh->totcol; i-- > 0; ) {
|
||||||
/* are we an object material or data based? */
|
/* are we an object material or data based? */
|
||||||
if (ob->colbits & 1<<i)
|
tmpmesh->mat[i] = ob->matbits[i] ? ob->mat[i] : origmesh->mat[i];
|
||||||
tmpmesh->mat[i] = ob->mat[i];
|
|
||||||
else
|
if (tmpmesh->mat[i]) {
|
||||||
tmpmesh->mat[i] = origmesh->mat[i];
|
|
||||||
if (tmpmesh->mat[i])
|
|
||||||
tmpmesh->mat[i]->id.us++;
|
tmpmesh->mat[i]->id.us++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
} /* end copy materials */
|
} /* end copy materials */
|
||||||
|
|
||||||
|
@ -2000,23 +2000,6 @@ static void rna_def_space_sequencer(BlenderRNA *brna)
|
|||||||
RNA_def_property_enum_items(prop, proxy_render_size_items);
|
RNA_def_property_enum_items(prop, proxy_render_size_items);
|
||||||
RNA_def_property_ui_text(prop, "Proxy render size", "Draw preview using full resolution or different proxy resolutions");
|
RNA_def_property_ui_text(prop, "Proxy render size", "Draw preview using full resolution or different proxy resolutions");
|
||||||
RNA_def_property_update(prop, NC_SPACE|ND_SPACE_SEQUENCER, NULL);
|
RNA_def_property_update(prop, NC_SPACE|ND_SPACE_SEQUENCER, NULL);
|
||||||
|
|
||||||
|
|
||||||
/* not sure we need rna access to these but adding anyway */
|
|
||||||
prop= RNA_def_property(srna, "offset_x", PROP_FLOAT, PROP_NONE);
|
|
||||||
RNA_def_property_float_sdna(prop, NULL, "xof");
|
|
||||||
RNA_def_property_ui_text(prop, "X Offset", "Offset image horizontally from the view center");
|
|
||||||
RNA_def_property_update(prop, NC_SPACE|ND_SPACE_SEQUENCER, NULL);
|
|
||||||
|
|
||||||
prop= RNA_def_property(srna, "offset_y", PROP_FLOAT, PROP_NONE);
|
|
||||||
RNA_def_property_float_sdna(prop, NULL, "yof");
|
|
||||||
RNA_def_property_ui_text(prop, "Y Offset", "Offset image vertically from the view center");
|
|
||||||
RNA_def_property_update(prop, NC_SPACE|ND_SPACE_SEQUENCER, NULL);
|
|
||||||
|
|
||||||
prop= RNA_def_property(srna, "zoom", PROP_FLOAT, PROP_NONE);
|
|
||||||
RNA_def_property_float_sdna(prop, NULL, "zoom");
|
|
||||||
RNA_def_property_ui_text(prop, "Zoom", "Display zoom level");
|
|
||||||
RNA_def_property_update(prop, NC_SPACE|ND_SPACE_SEQUENCER, NULL);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void rna_def_space_text(BlenderRNA *brna)
|
static void rna_def_space_text(BlenderRNA *brna)
|
||||||
|
@ -79,8 +79,8 @@ static void dm_calc_normal(DerivedMesh *dm, float (*temp_nors)[3])
|
|||||||
/* we don't want to overwrite any referenced layers */
|
/* we don't want to overwrite any referenced layers */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Dosnt work here!
|
Doesn't work here!
|
||||||
mv = CustomData_duplicate_referenced_layer(&dm->vertData, CD_MVERT);
|
mv = CustomData_duplicate_referenced_layer(&dm->vertData, CD_MVERT, numVerts);
|
||||||
cddm->mvert = mv;
|
cddm->mvert = mv;
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@ -259,10 +259,11 @@ static DerivedMesh *uvprojectModifier_do(UVProjectModifierData *umd,
|
|||||||
mul_mat3_m4_v3(projectors[i].ob->obmat, projectors[i].normal);
|
mul_mat3_m4_v3(projectors[i].ob->obmat, projectors[i].normal);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
numFaces = dm->getNumTessFaces(dm);
|
||||||
|
|
||||||
/* make sure we are not modifying the original UV map */
|
/* make sure we are not modifying the original UV map */
|
||||||
tface = CustomData_duplicate_referenced_layer_named(&dm->faceData,
|
tface = CustomData_duplicate_referenced_layer_named(&dm->faceData,
|
||||||
CD_MTFACE, uvname);
|
CD_MTFACE, uvname, numFaces);
|
||||||
|
|
||||||
|
|
||||||
numVerts = dm->getNumVerts(dm);
|
numVerts = dm->getNumVerts(dm);
|
||||||
|
|
||||||
@ -295,15 +296,11 @@ static DerivedMesh *uvprojectModifier_do(UVProjectModifierData *umd,
|
|||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
/* apply transformed coords as UVs */
|
/* apply transformed coords as UVs */
|
||||||
tface->uv[0][0] = coords[mf->v1][0];
|
copy_v2_v2(tface->uv[0], coords[mf->v1]);
|
||||||
tface->uv[0][1] = coords[mf->v1][1];
|
copy_v2_v2(tface->uv[1], coords[mf->v2]);
|
||||||
tface->uv[1][0] = coords[mf->v2][0];
|
copy_v2_v2(tface->uv[2], coords[mf->v3]);
|
||||||
tface->uv[1][1] = coords[mf->v2][1];
|
if (mf->v4) {
|
||||||
tface->uv[2][0] = coords[mf->v3][0];
|
copy_v2_v2(tface->uv[3], coords[mf->v4]);
|
||||||
tface->uv[2][1] = coords[mf->v3][1];
|
|
||||||
if(mf->v4) {
|
|
||||||
tface->uv[3][0] = coords[mf->v4][0];
|
|
||||||
tface->uv[3][1] = coords[mf->v4][1];
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -358,15 +355,11 @@ static DerivedMesh *uvprojectModifier_do(UVProjectModifierData *umd,
|
|||||||
mul_project_m4_v3(best_projector->projmat, co4);
|
mul_project_m4_v3(best_projector->projmat, co4);
|
||||||
|
|
||||||
/* apply transformed coords as UVs */
|
/* apply transformed coords as UVs */
|
||||||
tface->uv[0][0] = co1[0];
|
copy_v2_v2(tface->uv[0], co1);
|
||||||
tface->uv[0][1] = co1[1];
|
copy_v2_v2(tface->uv[1], co2);
|
||||||
tface->uv[1][0] = co2[0];
|
copy_v2_v2(tface->uv[2], co3);
|
||||||
tface->uv[1][1] = co2[1];
|
if (mf->v4) {
|
||||||
tface->uv[2][0] = co3[0];
|
copy_v2_v2(tface->uv[3], co4);
|
||||||
tface->uv[2][1] = co3[1];
|
|
||||||
if(mf->v4) {
|
|
||||||
tface->uv[3][0] = co4[0];
|
|
||||||
tface->uv[3][1] = co4[1];
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -449,9 +449,17 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob, DerivedMesh *der
|
|||||||
MEM_freeN(tdw);
|
MEM_freeN(tdw);
|
||||||
|
|
||||||
/* Get our vertex coordinates. */
|
/* Get our vertex coordinates. */
|
||||||
|
{
|
||||||
|
/* XXX In some situations, this code can be up to about 50 times more performant
|
||||||
|
* than simply using getVertCo for each affected vertex...
|
||||||
|
*/
|
||||||
|
float (*tv_cos)[3] = MEM_mallocN(sizeof(float[3]) * numVerts, "WeightVGProximity Modifier, tv_cos");
|
||||||
v_cos = MEM_mallocN(sizeof(float[3]) * numIdx, "WeightVGProximity Modifier, v_cos");
|
v_cos = MEM_mallocN(sizeof(float[3]) * numIdx, "WeightVGProximity Modifier, v_cos");
|
||||||
|
ret->getVertCos(ret, tv_cos);
|
||||||
for (i = 0; i < numIdx; i++)
|
for (i = 0; i < numIdx; i++)
|
||||||
ret->getVertCo(ret, indices[i], v_cos[i]);
|
copy_v3_v3(v_cos[i], tv_cos[indices[i]]);
|
||||||
|
MEM_freeN(tv_cos);
|
||||||
|
}
|
||||||
|
|
||||||
/* Compute wanted distances. */
|
/* Compute wanted distances. */
|
||||||
if (wmd->proximity_mode == MOD_WVG_PROXIMITY_OBJECT) {
|
if (wmd->proximity_mode == MOD_WVG_PROXIMITY_OBJECT) {
|
||||||
|
@ -453,7 +453,7 @@ static int Buffer_ass_item(Buffer *self, int i, PyObject *v)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
switch(self->type) {
|
switch (self->type) {
|
||||||
case GL_BYTE:
|
case GL_BYTE:
|
||||||
return PyArg_Parse(v, "b:Expected ints", &self->buf.asbyte[i]) ? 0:-1;
|
return PyArg_Parse(v, "b:Expected ints", &self->buf.asbyte[i]) ? 0:-1;
|
||||||
case GL_SHORT:
|
case GL_SHORT:
|
||||||
@ -595,7 +595,7 @@ static PyObject *Buffer_repr(Buffer *self)
|
|||||||
PyObject *repr;
|
PyObject *repr;
|
||||||
const char *typestr= "UNKNOWN";
|
const char *typestr= "UNKNOWN";
|
||||||
|
|
||||||
switch(self->type) {
|
switch (self->type) {
|
||||||
case GL_BYTE: typestr= "GL_BYTE"; break;
|
case GL_BYTE: typestr= "GL_BYTE"; break;
|
||||||
case GL_SHORT: typestr= "GL_SHORT"; break;
|
case GL_SHORT: typestr= "GL_SHORT"; break;
|
||||||
case GL_INT: typestr= "GL_BYTE"; break;
|
case GL_INT: typestr= "GL_BYTE"; break;
|
||||||
|
@ -405,7 +405,7 @@ const char *BPy_IDProperty_Map_ValidateAndCreate(PyObject *name_obj, IDProperty
|
|||||||
|
|
||||||
val.array.len = PySequence_Size(ob);
|
val.array.len = PySequence_Size(ob);
|
||||||
|
|
||||||
switch(val.array.type) {
|
switch (val.array.type) {
|
||||||
case IDP_DOUBLE:
|
case IDP_DOUBLE:
|
||||||
prop = IDP_New(IDP_ARRAY, &val, name);
|
prop = IDP_New(IDP_ARRAY, &val, name);
|
||||||
for (i=0; i<val.array.len; i++) {
|
for (i=0; i<val.array.len; i++) {
|
||||||
@ -565,7 +565,7 @@ static PyObject *BPy_IDGroup_MapDataToPy(IDProperty *prop)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch(prop->subtype) {
|
switch (prop->subtype) {
|
||||||
case IDP_FLOAT:
|
case IDP_FLOAT:
|
||||||
{
|
{
|
||||||
float *array= (float*)IDP_Array(prop);
|
float *array= (float*)IDP_Array(prop);
|
||||||
@ -976,7 +976,7 @@ static PyObject *BPy_IDArray_repr(BPy_IDArray *self)
|
|||||||
|
|
||||||
static PyObject *BPy_IDArray_GetType(BPy_IDArray *self)
|
static PyObject *BPy_IDArray_GetType(BPy_IDArray *self)
|
||||||
{
|
{
|
||||||
switch(self->prop->subtype) {
|
switch (self->prop->subtype) {
|
||||||
case IDP_FLOAT:
|
case IDP_FLOAT:
|
||||||
return PyUnicode_FromString("f");
|
return PyUnicode_FromString("f");
|
||||||
case IDP_DOUBLE:
|
case IDP_DOUBLE:
|
||||||
|
@ -191,7 +191,7 @@ void PyC_FileAndNum(const char **filename, int *lineno)
|
|||||||
|
|
||||||
void PyC_FileAndNum_Safe(const char **filename, int *lineno)
|
void PyC_FileAndNum_Safe(const char **filename, int *lineno)
|
||||||
{
|
{
|
||||||
if(!PYC_INTERPRETER_ACTIVE) {
|
if (!PYC_INTERPRETER_ACTIVE) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -82,7 +82,7 @@ static PyObject *bpy_app_handlers_persistent_new(PyTypeObject *UNUSED(type), PyO
|
|||||||
{
|
{
|
||||||
PyObject *value;
|
PyObject *value;
|
||||||
|
|
||||||
if(!PyArg_ParseTuple(args, "O:bpy.app.handlers.persistent", &value))
|
if (!PyArg_ParseTuple(args, "O:bpy.app.handlers.persistent", &value))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
if (PyFunction_Check(value)) {
|
if (PyFunction_Check(value)) {
|
||||||
@ -252,7 +252,7 @@ void BPY_app_handlers_reset(const short do_all)
|
|||||||
PyObject *item;
|
PyObject *item;
|
||||||
PyObject **dict_ptr;
|
PyObject **dict_ptr;
|
||||||
|
|
||||||
for(i= PyList_GET_SIZE(ls) - 1; i >= 0; i--) {
|
for (i= PyList_GET_SIZE(ls) - 1; i >= 0; i--) {
|
||||||
|
|
||||||
if ( (PyFunction_Check((item= PyList_GET_ITEM(ls, i)))) &&
|
if ( (PyFunction_Check((item= PyList_GET_ITEM(ls, i)))) &&
|
||||||
(dict_ptr= _PyObject_GetDictPtr(item)) &&
|
(dict_ptr= _PyObject_GetDictPtr(item)) &&
|
||||||
|
@ -977,8 +977,8 @@ static EnumPropertyItem *enum_items_from_py(PyObject *seq_fast, PyObject *def, i
|
|||||||
(tmp.identifier= _PyUnicode_AsStringAndSize(PyTuple_GET_ITEM(item, 0), &id_str_size)) &&
|
(tmp.identifier= _PyUnicode_AsStringAndSize(PyTuple_GET_ITEM(item, 0), &id_str_size)) &&
|
||||||
(tmp.name= _PyUnicode_AsStringAndSize(PyTuple_GET_ITEM(item, 1), &name_str_size)) &&
|
(tmp.name= _PyUnicode_AsStringAndSize(PyTuple_GET_ITEM(item, 1), &name_str_size)) &&
|
||||||
(tmp.description= _PyUnicode_AsStringAndSize(PyTuple_GET_ITEM(item, 2), &desc_str_size)) &&
|
(tmp.description= _PyUnicode_AsStringAndSize(PyTuple_GET_ITEM(item, 2), &desc_str_size)) &&
|
||||||
(item_size < 4 || py_long_as_int(PyTuple_GET_ITEM(item, 3), &tmp.value) != -1) /* TODO, number isnt ensured to be unique from the script author */
|
(item_size < 4 || py_long_as_int(PyTuple_GET_ITEM(item, 3), &tmp.value) != -1)) /* TODO, number isnt ensured to be unique from the script author */
|
||||||
) {
|
{
|
||||||
if (is_enum_flag) {
|
if (is_enum_flag) {
|
||||||
if (item_size < 4) {
|
if (item_size < 4) {
|
||||||
tmp.value= 1<<i;
|
tmp.value= 1<<i;
|
||||||
|
@ -624,7 +624,7 @@ PyObject *pyrna_math_object_from_array(PointerRNA *ptr, PropertyRNA *prop)
|
|||||||
if (!is_thick)
|
if (!is_thick)
|
||||||
ret= pyrna_prop_CreatePyObject(ptr, prop); /* owned by the mathutils PyObject */
|
ret= pyrna_prop_CreatePyObject(ptr, prop); /* owned by the mathutils PyObject */
|
||||||
|
|
||||||
switch(subtype) {
|
switch (subtype) {
|
||||||
case PROP_ALL_VECTOR_SUBTYPES:
|
case PROP_ALL_VECTOR_SUBTYPES:
|
||||||
if (len>=2 && len <= 4) {
|
if (len>=2 && len <= 4) {
|
||||||
if (is_thick) {
|
if (is_thick) {
|
||||||
@ -3441,7 +3441,7 @@ static PyObject *pyrna_struct_getattro(BPy_StructRNA *self, PyObject *pyname)
|
|||||||
int done= CTX_data_get(C, name, &newptr, &newlb, &newtype);
|
int done= CTX_data_get(C, name, &newptr, &newlb, &newtype);
|
||||||
|
|
||||||
if (done==1) { /* found */
|
if (done==1) { /* found */
|
||||||
switch(newtype) {
|
switch (newtype) {
|
||||||
case CTX_DATA_TYPE_POINTER:
|
case CTX_DATA_TYPE_POINTER:
|
||||||
if (newptr.data == NULL) {
|
if (newptr.data == NULL) {
|
||||||
ret= Py_None;
|
ret= Py_None;
|
||||||
@ -4201,7 +4201,7 @@ static int foreach_compat_buffer(RawPropertyType raw_type, int attr_signed, cons
|
|||||||
{
|
{
|
||||||
char f= format ? *format:'B'; /* B is assumed when not set */
|
char f= format ? *format:'B'; /* B is assumed when not set */
|
||||||
|
|
||||||
switch(raw_type) {
|
switch (raw_type) {
|
||||||
case PROP_RAW_CHAR:
|
case PROP_RAW_CHAR:
|
||||||
if (attr_signed) return (f=='b') ? 1:0;
|
if (attr_signed) return (f=='b') ? 1:0;
|
||||||
else return (f=='B') ? 1:0;
|
else return (f=='B') ? 1:0;
|
||||||
@ -4265,7 +4265,7 @@ static PyObject *foreach_getset(BPy_PropertyRNA *self, PyObject *args, int set)
|
|||||||
|
|
||||||
for ( ; i<tot; i++) {
|
for ( ; i<tot; i++) {
|
||||||
item= PySequence_GetItem(seq, i);
|
item= PySequence_GetItem(seq, i);
|
||||||
switch(raw_type) {
|
switch (raw_type) {
|
||||||
case PROP_RAW_CHAR:
|
case PROP_RAW_CHAR:
|
||||||
((char *)array)[i]= (char)PyLong_AsLong(item);
|
((char *)array)[i]= (char)PyLong_AsLong(item);
|
||||||
break;
|
break;
|
||||||
@ -4320,7 +4320,7 @@ static PyObject *foreach_getset(BPy_PropertyRNA *self, PyObject *args, int set)
|
|||||||
|
|
||||||
for ( ; i<tot; i++) {
|
for ( ; i<tot; i++) {
|
||||||
|
|
||||||
switch(raw_type) {
|
switch (raw_type) {
|
||||||
case PROP_RAW_CHAR:
|
case PROP_RAW_CHAR:
|
||||||
item= PyLong_FromSsize_t((Py_ssize_t) ((char *)array)[i]);
|
item= PyLong_FromSsize_t((Py_ssize_t) ((char *)array)[i]);
|
||||||
break;
|
break;
|
||||||
@ -4616,7 +4616,7 @@ static PyObject *pyrna_param_to_py(PointerRNA *ptr, PropertyRNA *prop, void *dat
|
|||||||
PyTuple_SET_ITEM(ret, a, PyLong_FromSsize_t((Py_ssize_t)((int*)data)[a]));
|
PyTuple_SET_ITEM(ret, a, PyLong_FromSsize_t((Py_ssize_t)((int*)data)[a]));
|
||||||
break;
|
break;
|
||||||
case PROP_FLOAT:
|
case PROP_FLOAT:
|
||||||
switch(RNA_property_subtype(prop)) {
|
switch (RNA_property_subtype(prop)) {
|
||||||
#ifdef USE_MATHUTILS
|
#ifdef USE_MATHUTILS
|
||||||
case PROP_ALL_VECTOR_SUBTYPES:
|
case PROP_ALL_VECTOR_SUBTYPES:
|
||||||
ret= Vector_CreatePyObject(data, len, Py_NEW, NULL);
|
ret= Vector_CreatePyObject(data, len, Py_NEW, NULL);
|
||||||
|
@ -60,7 +60,7 @@ static void cb_region_draw(const bContext *C, ARegion *UNUSED(ar), void *customd
|
|||||||
cb_args= PyTuple_GET_ITEM((PyObject *)customdata, 1);
|
cb_args= PyTuple_GET_ITEM((PyObject *)customdata, 1);
|
||||||
result= PyObject_CallObject(cb_func, cb_args);
|
result= PyObject_CallObject(cb_func, cb_args);
|
||||||
|
|
||||||
if(result) {
|
if (result) {
|
||||||
Py_DECREF(result);
|
Py_DECREF(result);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@ -82,22 +82,23 @@ PyObject *pyrna_callback_add(BPy_StructRNA *self, PyObject *args)
|
|||||||
if (!PyArg_ParseTuple(args, "OO!|s:bpy_struct.callback_add", &cb_func, &PyTuple_Type, &cb_args, &cb_event_str))
|
if (!PyArg_ParseTuple(args, "OO!|s:bpy_struct.callback_add", &cb_func, &PyTuple_Type, &cb_args, &cb_event_str))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
if(!PyCallable_Check(cb_func)) {
|
if (!PyCallable_Check(cb_func)) {
|
||||||
PyErr_SetString(PyExc_TypeError, "callback_add(): first argument isn't callable");
|
PyErr_SetString(PyExc_TypeError, "callback_add(): first argument isn't callable");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(RNA_struct_is_a(self->ptr.type, &RNA_Region)) {
|
if (RNA_struct_is_a(self->ptr.type, &RNA_Region)) {
|
||||||
if(cb_event_str) {
|
if (cb_event_str) {
|
||||||
static EnumPropertyItem region_draw_mode_items[]= {
|
static EnumPropertyItem region_draw_mode_items[]= {
|
||||||
{REGION_DRAW_POST_PIXEL, "POST_PIXEL", 0, "Post Pixel", ""},
|
{REGION_DRAW_POST_PIXEL, "POST_PIXEL", 0, "Post Pixel", ""},
|
||||||
{REGION_DRAW_POST_VIEW, "POST_VIEW", 0, "Post View", ""},
|
{REGION_DRAW_POST_VIEW, "POST_VIEW", 0, "Post View", ""},
|
||||||
{REGION_DRAW_PRE_VIEW, "PRE_VIEW", 0, "Pre View", ""},
|
{REGION_DRAW_PRE_VIEW, "PRE_VIEW", 0, "Pre View", ""},
|
||||||
{0, NULL, 0, NULL, NULL}};
|
{0, NULL, 0, NULL, NULL}};
|
||||||
|
|
||||||
if(pyrna_enum_value_from_id(region_draw_mode_items, cb_event_str, &cb_event, "bpy_struct.callback_add()") < 0)
|
if (pyrna_enum_value_from_id(region_draw_mode_items, cb_event_str, &cb_event, "bpy_struct.callback_add()") < 0) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
else {
|
else {
|
||||||
cb_event= REGION_DRAW_POST_PIXEL;
|
cb_event= REGION_DRAW_POST_PIXEL;
|
||||||
}
|
}
|
||||||
@ -124,12 +125,12 @@ PyObject *pyrna_callback_remove(BPy_StructRNA *self, PyObject *args)
|
|||||||
|
|
||||||
handle= PyCapsule_GetPointer(py_handle, RNA_CAPSULE_ID);
|
handle= PyCapsule_GetPointer(py_handle, RNA_CAPSULE_ID);
|
||||||
|
|
||||||
if(handle==NULL) {
|
if (handle==NULL) {
|
||||||
PyErr_SetString(PyExc_ValueError, "callback_remove(handle): NULL handle given, invalid or already removed");
|
PyErr_SetString(PyExc_ValueError, "callback_remove(handle): NULL handle given, invalid or already removed");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(RNA_struct_is_a(self->ptr.type, &RNA_Region)) {
|
if (RNA_struct_is_a(self->ptr.type, &RNA_Region)) {
|
||||||
customdata= ED_region_draw_cb_customdata(handle);
|
customdata= ED_region_draw_cb_customdata(handle);
|
||||||
Py_DECREF((PyObject *)customdata);
|
Py_DECREF((PyObject *)customdata);
|
||||||
|
|
||||||
|
@ -184,7 +184,8 @@ static PyObject* GPU_export_shader(PyObject* UNUSED(self), PyObject *args, PyObj
|
|||||||
PyErr_SetString(PyExc_SystemError, "scene.as_pointer() failed");
|
PyErr_SetString(PyExc_SystemError, "scene.as_pointer() failed");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
PyErr_SetString(PyExc_TypeError, "gpu.export_shader() first argument should be of Scene type");
|
PyErr_SetString(PyExc_TypeError, "gpu.export_shader() first argument should be of Scene type");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
@ -204,7 +205,8 @@ static PyObject* GPU_export_shader(PyObject* UNUSED(self), PyObject *args, PyObj
|
|||||||
PyErr_SetString(PyExc_SystemError, "scene.as_pointer() failed");
|
PyErr_SetString(PyExc_SystemError, "scene.as_pointer() failed");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
PyErr_SetString(PyExc_TypeError, "gpu.export_shader() second argument should be of Material type");
|
PyErr_SetString(PyExc_TypeError, "gpu.export_shader() second argument should be of Material type");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
@ -260,7 +262,8 @@ static PyObject* GPU_export_shader(PyObject* UNUSED(self), PyObject *args, PyObj
|
|||||||
if (attribute->name) {
|
if (attribute->name) {
|
||||||
if (attribute->name[0] != 0) {
|
if (attribute->name[0] != 0) {
|
||||||
PY_DICT_ADD_STRING(dict,attribute,name);
|
PY_DICT_ADD_STRING(dict,attribute,name);
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
val = PyLong_FromLong(0);
|
val = PyLong_FromLong(0);
|
||||||
PyDict_SetItemString(dict, "name", val);
|
PyDict_SetItemString(dict, "name", val);
|
||||||
Py_DECREF(val);
|
Py_DECREF(val);
|
||||||
|
@ -40,36 +40,13 @@ PyDoc_STRVAR(M_Mathutils_doc,
|
|||||||
"This module provides access to matrices, eulers, quaternions and vectors."
|
"This module provides access to matrices, eulers, quaternions and vectors."
|
||||||
);
|
);
|
||||||
static int mathutils_array_parse_fast(float *array,
|
static int mathutils_array_parse_fast(float *array,
|
||||||
int array_min, int array_max,
|
int size,
|
||||||
PyObject *value, const char *error_prefix)
|
PyObject *value_fast,
|
||||||
|
const char *error_prefix)
|
||||||
{
|
{
|
||||||
PyObject *value_fast= NULL;
|
|
||||||
PyObject *item;
|
PyObject *item;
|
||||||
|
|
||||||
int i, size;
|
int i;
|
||||||
|
|
||||||
/* non list/tuple cases */
|
|
||||||
if (!(value_fast=PySequence_Fast(value, error_prefix))) {
|
|
||||||
/* PySequence_Fast sets the error */
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
size= PySequence_Fast_GET_SIZE(value_fast);
|
|
||||||
|
|
||||||
if (size > array_max || size < array_min) {
|
|
||||||
if (array_max == array_min) {
|
|
||||||
PyErr_Format(PyExc_ValueError,
|
|
||||||
"%.200s: sequence size is %d, expected %d",
|
|
||||||
error_prefix, size, array_max);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
PyErr_Format(PyExc_ValueError,
|
|
||||||
"%.200s: sequence size is %d, expected [%d - %d]",
|
|
||||||
error_prefix, size, array_min, array_max);
|
|
||||||
}
|
|
||||||
Py_DECREF(value_fast);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
i= size;
|
i= size;
|
||||||
do {
|
do {
|
||||||
@ -93,9 +70,10 @@ static int mathutils_array_parse_fast(float *array,
|
|||||||
/* helper functionm returns length of the 'value', -1 on error */
|
/* helper functionm returns length of the 'value', -1 on error */
|
||||||
int mathutils_array_parse(float *array, int array_min, int array_max, PyObject *value, const char *error_prefix)
|
int mathutils_array_parse(float *array, int array_min, int array_max, PyObject *value, const char *error_prefix)
|
||||||
{
|
{
|
||||||
#if 1 /* approx 6x speedup for mathutils types */
|
|
||||||
int size;
|
int size;
|
||||||
|
|
||||||
|
#if 1 /* approx 6x speedup for mathutils types */
|
||||||
|
|
||||||
if ( (size= VectorObject_Check(value) ? ((VectorObject *)value)->size : 0) ||
|
if ( (size= VectorObject_Check(value) ? ((VectorObject *)value)->size : 0) ||
|
||||||
(size= EulerObject_Check(value) ? 3 : 0) ||
|
(size= EulerObject_Check(value) ? 3 : 0) ||
|
||||||
(size= QuaternionObject_Check(value) ? 4 : 0) ||
|
(size= QuaternionObject_Check(value) ? 4 : 0) ||
|
||||||
@ -125,7 +103,85 @@ int mathutils_array_parse(float *array, int array_min, int array_max, PyObject *
|
|||||||
else
|
else
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
return mathutils_array_parse_fast(array, array_min, array_max, value, error_prefix);
|
PyObject *value_fast= NULL;
|
||||||
|
|
||||||
|
/* non list/tuple cases */
|
||||||
|
if (!(value_fast=PySequence_Fast(value, error_prefix))) {
|
||||||
|
/* PySequence_Fast sets the error */
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
size= PySequence_Fast_GET_SIZE(value_fast);
|
||||||
|
|
||||||
|
if (size > array_max || size < array_min) {
|
||||||
|
if (array_max == array_min) {
|
||||||
|
PyErr_Format(PyExc_ValueError,
|
||||||
|
"%.200s: sequence size is %d, expected %d",
|
||||||
|
error_prefix, size, array_max);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
PyErr_Format(PyExc_ValueError,
|
||||||
|
"%.200s: sequence size is %d, expected [%d - %d]",
|
||||||
|
error_prefix, size, array_min, array_max);
|
||||||
|
}
|
||||||
|
Py_DECREF(value_fast);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return mathutils_array_parse_fast(array, size, value_fast, error_prefix);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int mathutils_array_parse_alloc(float **array, int array_min, PyObject *value, const char *error_prefix)
|
||||||
|
{
|
||||||
|
int size;
|
||||||
|
|
||||||
|
#if 1 /* approx 6x speedup for mathutils types */
|
||||||
|
|
||||||
|
if ( (size= VectorObject_Check(value) ? ((VectorObject *)value)->size : 0) ||
|
||||||
|
(size= EulerObject_Check(value) ? 3 : 0) ||
|
||||||
|
(size= QuaternionObject_Check(value) ? 4 : 0) ||
|
||||||
|
(size= ColorObject_Check(value) ? 3 : 0))
|
||||||
|
{
|
||||||
|
if (BaseMath_ReadCallback((BaseMathObject *)value) == -1) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (size < array_min) {
|
||||||
|
PyErr_Format(PyExc_ValueError,
|
||||||
|
"%.200s: sequence size is %d, expected > %d",
|
||||||
|
error_prefix, size, array_min);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
*array= PyMem_Malloc(size * sizeof(float));
|
||||||
|
memcpy(*array, ((BaseMathObject *)value)->data, size * sizeof(float));
|
||||||
|
return size;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
PyObject *value_fast= NULL;
|
||||||
|
//*array= NULL;
|
||||||
|
|
||||||
|
/* non list/tuple cases */
|
||||||
|
if (!(value_fast=PySequence_Fast(value, error_prefix))) {
|
||||||
|
/* PySequence_Fast sets the error */
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
size= PySequence_Fast_GET_SIZE(value_fast);
|
||||||
|
|
||||||
|
if (size < array_min) {
|
||||||
|
PyErr_Format(PyExc_ValueError,
|
||||||
|
"%.200s: sequence size is %d, expected > %d",
|
||||||
|
error_prefix, size, array_min);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
*array= PyMem_Malloc(size * sizeof(float));
|
||||||
|
|
||||||
|
return mathutils_array_parse_fast(*array, size, value_fast, error_prefix);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -115,6 +115,7 @@ int _BaseMathObject_WriteIndexCallback(BaseMathObject *self, int index);
|
|||||||
|
|
||||||
/* utility func */
|
/* utility func */
|
||||||
int mathutils_array_parse(float *array, int array_min, int array_max, PyObject *value, const char *error_prefix);
|
int mathutils_array_parse(float *array, int array_min, int array_max, PyObject *value, const char *error_prefix);
|
||||||
|
int mathutils_array_parse_alloc(float **array, int array_min, PyObject *value, const char *error_prefix);
|
||||||
int mathutils_any_to_rotmat(float rmat[3][3], PyObject *value, const char *error_prefix);
|
int mathutils_any_to_rotmat(float rmat[3][3], PyObject *value, const char *error_prefix);
|
||||||
|
|
||||||
int column_vector_multiplication(float rvec[4], VectorObject *vec, MatrixObject *mat);
|
int column_vector_multiplication(float rvec[4], VectorObject *vec, MatrixObject *mat);
|
||||||
|
@ -48,7 +48,7 @@ static PyObject *Color_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch(PyTuple_GET_SIZE(args)) {
|
switch (PyTuple_GET_SIZE(args)) {
|
||||||
case 0:
|
case 0:
|
||||||
break;
|
break;
|
||||||
case 1:
|
case 1:
|
||||||
|
@ -59,7 +59,7 @@ static PyObject *Euler_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
|
|||||||
if (!PyArg_ParseTuple(args, "|Os:mathutils.Euler", &seq, &order_str))
|
if (!PyArg_ParseTuple(args, "|Os:mathutils.Euler", &seq, &order_str))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
switch(PyTuple_GET_SIZE(args)) {
|
switch (PyTuple_GET_SIZE(args)) {
|
||||||
case 0:
|
case 0:
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
@ -84,7 +84,7 @@ static const char *euler_order_str(EulerObject *self)
|
|||||||
short euler_order_from_string(const char *str, const char *error_prefix)
|
short euler_order_from_string(const char *str, const char *error_prefix)
|
||||||
{
|
{
|
||||||
if ((str[0] && str[1] && str[2] && str[3]=='\0')) {
|
if ((str[0] && str[1] && str[2] && str[3]=='\0')) {
|
||||||
switch(*((PY_INT32_T *)str)) {
|
switch (*((PY_INT32_T *)str)) {
|
||||||
case 'X'|'Y'<<8|'Z'<<16: return EULER_ORDER_XYZ;
|
case 'X'|'Y'<<8|'Z'<<16: return EULER_ORDER_XYZ;
|
||||||
case 'X'|'Z'<<8|'Y'<<16: return EULER_ORDER_XZY;
|
case 'X'|'Z'<<8|'Y'<<16: return EULER_ORDER_XZY;
|
||||||
case 'Y'|'X'<<8|'Z'<<16: return EULER_ORDER_YXZ;
|
case 'Y'|'X'<<8|'Z'<<16: return EULER_ORDER_YXZ;
|
||||||
|
@ -52,13 +52,14 @@ static int mathutils_matrix_vector_check(BaseMathObject *bmo)
|
|||||||
static int mathutils_matrix_vector_get(BaseMathObject *bmo, int subtype)
|
static int mathutils_matrix_vector_get(BaseMathObject *bmo, int subtype)
|
||||||
{
|
{
|
||||||
MatrixObject *self= (MatrixObject *)bmo->cb_user;
|
MatrixObject *self= (MatrixObject *)bmo->cb_user;
|
||||||
int i;
|
int index;
|
||||||
|
|
||||||
if (BaseMath_ReadCallback(self) == -1)
|
if (BaseMath_ReadCallback(self) == -1)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
for (i=0; i < self->col_size; i++)
|
for (index=0; index < self->col_size; index++) {
|
||||||
bmo->data[i]= self->matrix[subtype][i];
|
bmo->data[index] = MATRIX_ITEM(self, subtype, index);
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -66,13 +67,14 @@ static int mathutils_matrix_vector_get(BaseMathObject *bmo, int subtype)
|
|||||||
static int mathutils_matrix_vector_set(BaseMathObject *bmo, int subtype)
|
static int mathutils_matrix_vector_set(BaseMathObject *bmo, int subtype)
|
||||||
{
|
{
|
||||||
MatrixObject *self= (MatrixObject *)bmo->cb_user;
|
MatrixObject *self= (MatrixObject *)bmo->cb_user;
|
||||||
int i;
|
int index;
|
||||||
|
|
||||||
if (BaseMath_ReadCallback(self) == -1)
|
if (BaseMath_ReadCallback(self) == -1)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
for (i=0; i < self->col_size; i++)
|
for (index=0; index < self->col_size; index++) {
|
||||||
self->matrix[subtype][i]= bmo->data[i];
|
MATRIX_ITEM(self, subtype, index) = bmo->data[index];
|
||||||
|
}
|
||||||
|
|
||||||
(void)BaseMath_WriteCallback(self);
|
(void)BaseMath_WriteCallback(self);
|
||||||
return 0;
|
return 0;
|
||||||
@ -85,7 +87,7 @@ static int mathutils_matrix_vector_get_index(BaseMathObject *bmo, int subtype, i
|
|||||||
if (BaseMath_ReadCallback(self) == -1)
|
if (BaseMath_ReadCallback(self) == -1)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
bmo->data[index]= self->matrix[subtype][index];
|
bmo->data[index]= MATRIX_ITEM(self, subtype, index);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -96,7 +98,7 @@ static int mathutils_matrix_vector_set_index(BaseMathObject *bmo, int subtype, i
|
|||||||
if (BaseMath_ReadCallback(self) == -1)
|
if (BaseMath_ReadCallback(self) == -1)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
self->matrix[subtype][index]= bmo->data[index];
|
MATRIX_ITEM(self, subtype, index) = bmo->data[index];
|
||||||
|
|
||||||
(void)BaseMath_WriteCallback(self);
|
(void)BaseMath_WriteCallback(self);
|
||||||
return 0;
|
return 0;
|
||||||
@ -123,7 +125,7 @@ static PyObject *Matrix_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch(PyTuple_GET_SIZE(args)) {
|
switch (PyTuple_GET_SIZE(args)) {
|
||||||
case 0:
|
case 0:
|
||||||
return Matrix_CreatePyObject(NULL, 4, 4, Py_NEW, type);
|
return Matrix_CreatePyObject(NULL, 4, 4, Py_NEW, type);
|
||||||
case 1:
|
case 1:
|
||||||
@ -620,24 +622,22 @@ static PyObject *C_Matrix_Shear(PyObject *cls, PyObject *args)
|
|||||||
|
|
||||||
void matrix_as_3x3(float mat[3][3], MatrixObject *self)
|
void matrix_as_3x3(float mat[3][3], MatrixObject *self)
|
||||||
{
|
{
|
||||||
copy_v3_v3(mat[0], self->matrix[0]);
|
copy_v3_v3(mat[0], MATRIX_ROW_PTR(self, 0));
|
||||||
copy_v3_v3(mat[1], self->matrix[1]);
|
copy_v3_v3(mat[1], MATRIX_ROW_PTR(self, 1));
|
||||||
copy_v3_v3(mat[2], self->matrix[2]);
|
copy_v3_v3(mat[2], MATRIX_ROW_PTR(self, 2));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* assumes rowsize == colsize is checked and the read callback has run */
|
/* assumes rowsize == colsize is checked and the read callback has run */
|
||||||
static float matrix_determinant_internal(MatrixObject *self)
|
static float matrix_determinant_internal(MatrixObject *self)
|
||||||
{
|
{
|
||||||
if (self->row_size == 2) {
|
if (self->row_size == 2) {
|
||||||
return determinant_m2(self->matrix[0][0], self->matrix[0][1],
|
return determinant_m2(MATRIX_ITEM(self, 0, 0), MATRIX_ITEM(self, 0, 1),
|
||||||
self->matrix[1][0], self->matrix[1][1]);
|
MATRIX_ITEM(self, 1, 0), MATRIX_ITEM(self, 1, 1));
|
||||||
}
|
}
|
||||||
else if (self->row_size == 3) {
|
else if (self->row_size == 3) {
|
||||||
return determinant_m3(self->matrix[0][0], self->matrix[0][1],
|
return determinant_m3(MATRIX_ITEM(self, 0, 0), MATRIX_ITEM(self, 0, 1), MATRIX_ITEM(self, 0, 2),
|
||||||
self->matrix[0][2], self->matrix[1][0],
|
MATRIX_ITEM(self, 1, 0), MATRIX_ITEM(self, 1, 1), MATRIX_ITEM(self, 1, 2),
|
||||||
self->matrix[1][1], self->matrix[1][2],
|
MATRIX_ITEM(self, 2, 0), MATRIX_ITEM(self, 2, 1), MATRIX_ITEM(self, 2, 2));
|
||||||
self->matrix[2][0], self->matrix[2][1],
|
|
||||||
self->matrix[2][2]);
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
return determinant_m4((float (*)[4])self->contigPtr);
|
return determinant_m4((float (*)[4])self->contigPtr);
|
||||||
@ -781,10 +781,7 @@ static PyObject *Matrix_resize_4x4(MatrixObject *self)
|
|||||||
"problem allocating pointer space");
|
"problem allocating pointer space");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
/*set row pointers*/
|
|
||||||
for (x = 0; x < 4; x++) {
|
|
||||||
self->matrix[x] = self->contigPtr + (x * 4);
|
|
||||||
}
|
|
||||||
/*move data to new spot in array + clean*/
|
/*move data to new spot in array + clean*/
|
||||||
for (blank_rows = (4 - self->row_size); blank_rows > 0; blank_rows--) {
|
for (blank_rows = (4 - self->row_size); blank_rows > 0; blank_rows--) {
|
||||||
for (x = 0; x < 4; x++) {
|
for (x = 0; x < 4; x++) {
|
||||||
@ -890,7 +887,7 @@ static PyObject *Matrix_to_translation(MatrixObject *self)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
return Vector_CreatePyObject(self->matrix[3], 3, Py_NEW, NULL);
|
return Vector_CreatePyObject(MATRIX_ROW_PTR(self, 3), 3, Py_NEW, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
PyDoc_STRVAR(Matrix_to_scale_doc,
|
PyDoc_STRVAR(Matrix_to_scale_doc,
|
||||||
@ -964,10 +961,10 @@ static PyObject *Matrix_invert(MatrixObject *self)
|
|||||||
if (det != 0) {
|
if (det != 0) {
|
||||||
/*calculate the classical adjoint*/
|
/*calculate the classical adjoint*/
|
||||||
if (self->row_size == 2) {
|
if (self->row_size == 2) {
|
||||||
mat[0] = self->matrix[1][1];
|
mat[0] = MATRIX_ITEM(self, 1, 1);
|
||||||
mat[1] = -self->matrix[0][1];
|
mat[1] = -MATRIX_ITEM(self, 0, 1);
|
||||||
mat[2] = -self->matrix[1][0];
|
mat[2] = -MATRIX_ITEM(self, 1, 0);
|
||||||
mat[3] = self->matrix[0][0];
|
mat[3] = MATRIX_ITEM(self, 0, 0);
|
||||||
}
|
}
|
||||||
else if (self->row_size == 3) {
|
else if (self->row_size == 3) {
|
||||||
adjoint_m3_m3((float (*)[3]) mat,(float (*)[3])self->contigPtr);
|
adjoint_m3_m3((float (*)[3]) mat,(float (*)[3])self->contigPtr);
|
||||||
@ -982,7 +979,7 @@ static PyObject *Matrix_invert(MatrixObject *self)
|
|||||||
/*set values*/
|
/*set values*/
|
||||||
for (x = 0; x < self->row_size; x++) {
|
for (x = 0; x < self->row_size; x++) {
|
||||||
for (y = 0; y < self->col_size; y++) {
|
for (y = 0; y < self->col_size; y++) {
|
||||||
self->matrix[x][y] = mat[z];
|
MATRIX_ITEM(self, x, y) = mat[z];
|
||||||
z++;
|
z++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1173,8 +1170,6 @@ PyDoc_STRVAR(Matrix_transpose_doc,
|
|||||||
);
|
);
|
||||||
static PyObject *Matrix_transpose(MatrixObject *self)
|
static PyObject *Matrix_transpose(MatrixObject *self)
|
||||||
{
|
{
|
||||||
float t = 0.0f;
|
|
||||||
|
|
||||||
if (BaseMath_ReadCallback(self) == -1)
|
if (BaseMath_ReadCallback(self) == -1)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
@ -1186,9 +1181,9 @@ static PyObject *Matrix_transpose(MatrixObject *self)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (self->row_size == 2) {
|
if (self->row_size == 2) {
|
||||||
t = self->matrix[1][0];
|
const float t = MATRIX_ITEM(self, 1, 0);
|
||||||
self->matrix[1][0] = self->matrix[0][1];
|
MATRIX_ITEM(self, 1, 0) = MATRIX_ITEM(self, 0, 1);
|
||||||
self->matrix[0][1] = t;
|
MATRIX_ITEM(self, 0, 1) = t;
|
||||||
}
|
}
|
||||||
else if (self->row_size == 3) {
|
else if (self->row_size == 3) {
|
||||||
transpose_m3((float (*)[3])self->contigPtr);
|
transpose_m3((float (*)[3])self->contigPtr);
|
||||||
@ -1256,10 +1251,10 @@ static PyObject *Matrix_identity(MatrixObject *self)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (self->row_size == 2) {
|
if (self->row_size == 2) {
|
||||||
self->matrix[0][0] = 1.0f;
|
MATRIX_ITEM(self, 0, 0) = 1.0f;
|
||||||
self->matrix[0][1] = 0.0f;
|
MATRIX_ITEM(self, 0, 1) = 0.0f;
|
||||||
self->matrix[1][0] = 0.0f;
|
MATRIX_ITEM(self, 1, 0) = 0.0f;
|
||||||
self->matrix[1][1] = 1.0f;
|
MATRIX_ITEM(self, 1, 1) = 1.0f;
|
||||||
}
|
}
|
||||||
else if (self->row_size == 3) {
|
else if (self->row_size == 3) {
|
||||||
unit_m3((float (*)[3])self->contigPtr);
|
unit_m3((float (*)[3])self->contigPtr);
|
||||||
@ -1304,10 +1299,10 @@ static PyObject *Matrix_repr(MatrixObject *self)
|
|||||||
for (x = 0; x < self->row_size; x++) {
|
for (x = 0; x < self->row_size; x++) {
|
||||||
rows[x]= PyTuple_New(self->col_size);
|
rows[x]= PyTuple_New(self->col_size);
|
||||||
for (y = 0; y < self->col_size; y++) {
|
for (y = 0; y < self->col_size; y++) {
|
||||||
PyTuple_SET_ITEM(rows[x], y, PyFloat_FromDouble(self->matrix[x][y]));
|
PyTuple_SET_ITEM(rows[x], y, PyFloat_FromDouble(MATRIX_ITEM(self, x, y)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
switch(self->row_size) {
|
switch (self->row_size) {
|
||||||
case 2: return PyUnicode_FromFormat("Matrix((%R,\n"
|
case 2: return PyUnicode_FromFormat("Matrix((%R,\n"
|
||||||
" %R))", rows[0], rows[1]);
|
" %R))", rows[0], rows[1]);
|
||||||
|
|
||||||
@ -1406,7 +1401,7 @@ static int Matrix_ass_item(MatrixObject *self, int i, PyObject *value)
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
memcpy(self->matrix[i], vec, self->col_size *sizeof(float));
|
memcpy(MATRIX_ROW_PTR(self, i), vec, self->col_size * sizeof(float));
|
||||||
|
|
||||||
(void)BaseMath_WriteCallback(self);
|
(void)BaseMath_WriteCallback(self);
|
||||||
return 0;
|
return 0;
|
||||||
@ -1591,7 +1586,7 @@ static PyObject *Matrix_mul(PyObject *m1, PyObject *m2)
|
|||||||
for (x = 0; x < mat2->row_size; x++) {
|
for (x = 0; x < mat2->row_size; x++) {
|
||||||
for (y = 0; y < mat1->col_size; y++) {
|
for (y = 0; y < mat1->col_size; y++) {
|
||||||
for (z = 0; z < mat1->row_size; z++) {
|
for (z = 0; z < mat1->row_size; z++) {
|
||||||
dot += (mat1->matrix[z][y] * mat2->matrix[x][z]);
|
dot += MATRIX_ITEM(mat1, z, y) * MATRIX_ITEM(mat2, x, z);
|
||||||
}
|
}
|
||||||
mat[((x * mat1->col_size) + y)] = (float)dot;
|
mat[((x * mat1->col_size) + y)] = (float)dot;
|
||||||
dot = 0.0f;
|
dot = 0.0f;
|
||||||
@ -1944,31 +1939,18 @@ PyTypeObject matrix_Type = {
|
|||||||
NULL /*tp_del*/
|
NULL /*tp_del*/
|
||||||
};
|
};
|
||||||
|
|
||||||
/*------------------------Matrix_CreatePyObject (internal)-------------
|
/* pass Py_WRAP - if vector is a WRAPPER for data allocated by BLENDER
|
||||||
creates a new matrix object
|
* (i.e. it was allocated elsewhere by MEM_mallocN())
|
||||||
self->matrix self->contiguous_ptr (reference to data.xxx)
|
* pass Py_NEW - if vector is not a WRAPPER and managed by PYTHON
|
||||||
[0]------------->[0]
|
* (i.e. it must be created here with PyMEM_malloc()) */
|
||||||
[1]
|
|
||||||
[2]
|
|
||||||
[1]------------->[3]
|
|
||||||
[4]
|
|
||||||
[5]
|
|
||||||
|
|
||||||
self->matrix[1][1] = self->contigPtr[4] */
|
|
||||||
|
|
||||||
/*pass Py_WRAP - if vector is a WRAPPER for data allocated by BLENDER
|
|
||||||
(i.e. it was allocated elsewhere by MEM_mallocN())
|
|
||||||
pass Py_NEW - if vector is not a WRAPPER and managed by PYTHON
|
|
||||||
(i.e. it must be created here with PyMEM_malloc())*/
|
|
||||||
PyObject *Matrix_CreatePyObject(float *mat,
|
PyObject *Matrix_CreatePyObject(float *mat,
|
||||||
const unsigned short rowSize, const unsigned short colSize,
|
const unsigned short row_size, const unsigned short col_size,
|
||||||
int type, PyTypeObject *base_type)
|
int type, PyTypeObject *base_type)
|
||||||
{
|
{
|
||||||
MatrixObject *self;
|
MatrixObject *self;
|
||||||
int x, row, col;
|
|
||||||
|
|
||||||
/*matrix objects can be any 2-4row x 2-4col matrix*/
|
/* matrix objects can be any 2-4row x 2-4col matrix */
|
||||||
if (rowSize < 2 || rowSize > 4 || colSize < 2 || colSize > 4) {
|
if (row_size < 2 || row_size > 4 || col_size < 2 || col_size > 4) {
|
||||||
PyErr_SetString(PyExc_RuntimeError,
|
PyErr_SetString(PyExc_RuntimeError,
|
||||||
"Matrix(): "
|
"Matrix(): "
|
||||||
"row and column sizes must be between 2 and 4");
|
"row and column sizes must be between 2 and 4");
|
||||||
@ -1979,8 +1961,8 @@ PyObject *Matrix_CreatePyObject(float *mat,
|
|||||||
(MatrixObject *)PyObject_GC_New(MatrixObject, &matrix_Type);
|
(MatrixObject *)PyObject_GC_New(MatrixObject, &matrix_Type);
|
||||||
|
|
||||||
if (self) {
|
if (self) {
|
||||||
self->row_size = rowSize;
|
self->row_size = row_size;
|
||||||
self->col_size = colSize;
|
self->col_size = col_size;
|
||||||
|
|
||||||
/* init callbacks as NULL */
|
/* init callbacks as NULL */
|
||||||
self->cb_user= NULL;
|
self->cb_user= NULL;
|
||||||
@ -1988,36 +1970,29 @@ PyObject *Matrix_CreatePyObject(float *mat,
|
|||||||
|
|
||||||
if (type == Py_WRAP) {
|
if (type == Py_WRAP) {
|
||||||
self->contigPtr = mat;
|
self->contigPtr = mat;
|
||||||
/*pointer array points to contigous memory*/
|
|
||||||
for (x = 0; x < rowSize; x++) {
|
|
||||||
self->matrix[x] = self->contigPtr + (x * colSize);
|
|
||||||
}
|
|
||||||
self->wrapped = Py_WRAP;
|
self->wrapped = Py_WRAP;
|
||||||
}
|
}
|
||||||
else if (type == Py_NEW) {
|
else if (type == Py_NEW) {
|
||||||
self->contigPtr = PyMem_Malloc(rowSize * colSize * sizeof(float));
|
self->contigPtr = PyMem_Malloc(row_size * col_size * sizeof(float));
|
||||||
if (self->contigPtr == NULL) { /*allocation failure*/
|
if (self->contigPtr == NULL) { /*allocation failure*/
|
||||||
PyErr_SetString(PyExc_MemoryError,
|
PyErr_SetString(PyExc_MemoryError,
|
||||||
"Matrix(): "
|
"Matrix(): "
|
||||||
"problem allocating pointer space");
|
"problem allocating pointer space");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
/*pointer array points to contigous memory*/
|
|
||||||
for (x = 0; x < rowSize; x++) {
|
|
||||||
self->matrix[x] = self->contigPtr + (x * colSize);
|
|
||||||
}
|
|
||||||
/*parse*/
|
|
||||||
if (mat) { /*if a float array passed*/
|
if (mat) { /*if a float array passed*/
|
||||||
for (row = 0; row < rowSize; row++) {
|
memcpy(self->contigPtr, mat, row_size * col_size * sizeof(float));
|
||||||
for (col = 0; col < colSize; col++) {
|
|
||||||
self->matrix[row][col] = mat[(row * colSize) + col];
|
|
||||||
}
|
}
|
||||||
}
|
else if (row_size == col_size) {
|
||||||
}
|
/* or if no arguments are passed return identity matrix for square matrices */
|
||||||
else if (rowSize == colSize) { /*or if no arguments are passed return identity matrix for square matrices */
|
|
||||||
PyObject *ret_dummy= Matrix_identity(self);
|
PyObject *ret_dummy= Matrix_identity(self);
|
||||||
Py_DECREF(ret_dummy);
|
Py_DECREF(ret_dummy);
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
/* otherwise zero everything */
|
||||||
|
memset(self->contigPtr, 0, row_size * col_size * sizeof(float));
|
||||||
|
}
|
||||||
self->wrapped = Py_NEW;
|
self->wrapped = Py_NEW;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
@ -38,19 +38,33 @@ extern PyTypeObject matrix_Type;
|
|||||||
#define MatrixObject_Check(_v) PyObject_TypeCheck((_v), &matrix_Type)
|
#define MatrixObject_Check(_v) PyObject_TypeCheck((_v), &matrix_Type)
|
||||||
#define MATRIX_MAX_DIM 4
|
#define MATRIX_MAX_DIM 4
|
||||||
|
|
||||||
|
/* matrix[row][col] == MATRIX_ITEM_INDEX(matrix, row, col) */
|
||||||
|
|
||||||
|
#ifdef DEBUG
|
||||||
|
# define MATRIX_ITEM_ASSERT(_mat, _row, _col) (BLI_assert(_row < (_mat)->row_size && _col < (_mat)->col_size))
|
||||||
|
#else
|
||||||
|
# define MATRIX_ITEM_ASSERT(_mat, _row, _col) (void)0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define MATRIX_ITEM_INDEX(_mat, _row, _col) (MATRIX_ITEM_ASSERT(_mat, _row, _col),(((_mat)->col_size * (_row)) + (_col)))
|
||||||
|
#define MATRIX_ITEM_PTR( _mat, _row, _col) ((_mat)->contigPtr + MATRIX_ITEM_INDEX(_mat, _row, _col))
|
||||||
|
#define MATRIX_ITEM( _mat, _row, _col) ((_mat)->contigPtr [MATRIX_ITEM_INDEX(_mat, _row, _col)])
|
||||||
|
|
||||||
|
#define MATRIX_ROW_INDEX(_mat, _row) (MATRIX_ITEM_INDEX(_mat, _row, 0))
|
||||||
|
#define MATRIX_ROW_PTR( _mat, _row) ((_mat)->contigPtr + MATRIX_ROW_INDEX(_mat, _row))
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
BASE_MATH_MEMBERS(contigPtr);
|
BASE_MATH_MEMBERS(contigPtr);
|
||||||
float *matrix[MATRIX_MAX_DIM]; /* ptr to the contigPtr (accessor) */
|
|
||||||
unsigned short row_size;
|
unsigned short row_size;
|
||||||
unsigned short col_size;
|
unsigned short col_size;
|
||||||
} MatrixObject;
|
} MatrixObject;
|
||||||
|
|
||||||
/*struct data contains a pointer to the actual data that the
|
/* struct data contains a pointer to the actual data that the
|
||||||
object uses. It can use either PyMem allocated data (which will
|
* object uses. It can use either PyMem allocated data (which will
|
||||||
be stored in py_data) or be a wrapper for data allocated through
|
* be stored in py_data) or be a wrapper for data allocated through
|
||||||
blender (stored in blend_data). This is an either/or struct not both*/
|
* blender (stored in blend_data). This is an either/or struct not both */
|
||||||
|
|
||||||
/*prototypes*/
|
/* prototypes */
|
||||||
PyObject *Matrix_CreatePyObject(float *mat,
|
PyObject *Matrix_CreatePyObject(float *mat,
|
||||||
const unsigned short row_size, const unsigned short col_size,
|
const unsigned short row_size, const unsigned short col_size,
|
||||||
int type, PyTypeObject *base_type);
|
int type, PyTypeObject *base_type);
|
||||||
|
@ -1039,7 +1039,7 @@ static PyObject *Quaternion_new(PyTypeObject *type, PyObject *args, PyObject *kw
|
|||||||
if (!PyArg_ParseTuple(args, "|Od:mathutils.Quaternion", &seq, &angle))
|
if (!PyArg_ParseTuple(args, "|Od:mathutils.Quaternion", &seq, &angle))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
switch(PyTuple_GET_SIZE(args)) {
|
switch (PyTuple_GET_SIZE(args)) {
|
||||||
case 0:
|
case 0:
|
||||||
break;
|
break;
|
||||||
case 1:
|
case 1:
|
||||||
@ -1085,8 +1085,8 @@ static void quat__axis_angle_sanitize(float axis[3], float *angle)
|
|||||||
}
|
}
|
||||||
else if ( EXPP_FloatsAreEqual(axis[0], 0.0f, 10) &&
|
else if ( EXPP_FloatsAreEqual(axis[0], 0.0f, 10) &&
|
||||||
EXPP_FloatsAreEqual(axis[1], 0.0f, 10) &&
|
EXPP_FloatsAreEqual(axis[1], 0.0f, 10) &&
|
||||||
EXPP_FloatsAreEqual(axis[2], 0.0f, 10)
|
EXPP_FloatsAreEqual(axis[2], 0.0f, 10))
|
||||||
) {
|
{
|
||||||
axis[0] = 1.0f;
|
axis[0] = 1.0f;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -54,15 +54,29 @@ static int row_vector_multiplication(float rvec[MAX_DIMENSIONS], VectorObject *v
|
|||||||
*/
|
*/
|
||||||
static PyObject *Vector_new(PyTypeObject *type, PyObject *args, PyObject *UNUSED(kwds))
|
static PyObject *Vector_new(PyTypeObject *type, PyObject *args, PyObject *UNUSED(kwds))
|
||||||
{
|
{
|
||||||
float vec[4]= {0.0f, 0.0f, 0.0f, 0.0f};
|
float *vec= NULL;
|
||||||
int size= 3; /* default to a 3D vector */
|
int size= 3; /* default to a 3D vector */
|
||||||
|
|
||||||
switch(PyTuple_GET_SIZE(args)) {
|
switch (PyTuple_GET_SIZE(args)) {
|
||||||
case 0:
|
case 0:
|
||||||
|
vec= PyMem_Malloc(size * sizeof(float));
|
||||||
|
|
||||||
|
if (vec == NULL) {
|
||||||
|
PyErr_SetString(PyExc_MemoryError,
|
||||||
|
"Vector(): "
|
||||||
|
"problem allocating pointer space");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
fill_vn_fl(vec, size, 0.0f);
|
||||||
break;
|
break;
|
||||||
case 1:
|
case 1:
|
||||||
if ((size=mathutils_array_parse(vec, 2, 4, PyTuple_GET_ITEM(args, 0), "mathutils.Vector()")) == -1)
|
if ((size=mathutils_array_parse_alloc(&vec, 2, PyTuple_GET_ITEM(args, 0), "mathutils.Vector()")) == -1) {
|
||||||
|
if (vec) {
|
||||||
|
PyMem_Free(vec);
|
||||||
|
}
|
||||||
return NULL;
|
return NULL;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
PyErr_SetString(PyExc_TypeError,
|
PyErr_SetString(PyExc_TypeError,
|
||||||
@ -87,6 +101,215 @@ static PyObject *vec__apply_to_copy(PyNoArgsFunction vec_func, VectorObject *sel
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*-----------------------CLASS-METHODS----------------------------*/
|
||||||
|
PyDoc_STRVAR(C_Vector_Fill_doc,
|
||||||
|
".. classmethod:: Fill(size, fill=0.0)\n"
|
||||||
|
"\n"
|
||||||
|
" Create a vector of length size with all values set to fill.\n"
|
||||||
|
"\n"
|
||||||
|
" :arg size: The length of the vector to be created.\n"
|
||||||
|
" :type size: int\n"
|
||||||
|
" :arg fill: The value used to fill the vector.\n"
|
||||||
|
" :type fill: float\n"
|
||||||
|
);
|
||||||
|
static PyObject *C_Vector_Fill(PyObject *cls, PyObject *args)
|
||||||
|
{
|
||||||
|
float *vec;
|
||||||
|
int size;
|
||||||
|
float fill= 0.0f;
|
||||||
|
|
||||||
|
if (!PyArg_ParseTuple(args, "i|f:Vector.Fill", &size, &fill)) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (size < 2) {
|
||||||
|
PyErr_SetString(PyExc_RuntimeError,
|
||||||
|
"Vector(): invalid size");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
vec= PyMem_Malloc(size * sizeof(float));
|
||||||
|
|
||||||
|
if (vec == NULL) {
|
||||||
|
PyErr_SetString(PyExc_MemoryError,
|
||||||
|
"Vector.Fill(): "
|
||||||
|
"problem allocating pointer space");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
fill_vn_fl(vec, size, fill);
|
||||||
|
|
||||||
|
return Vector_CreatePyObject_alloc(vec, size, (PyTypeObject *)cls);
|
||||||
|
}
|
||||||
|
|
||||||
|
PyDoc_STRVAR(C_Vector_Range_doc,
|
||||||
|
".. classmethod:: Range(start=0, stop, step=1)\n"
|
||||||
|
"\n"
|
||||||
|
" Create a filled with a range of values.\n"
|
||||||
|
"\n"
|
||||||
|
" :arg start: The start of the range used to fill the vector.\n"
|
||||||
|
" :type start: int\n"
|
||||||
|
" :arg stop: The end of the range used to fill the vector.\n"
|
||||||
|
" :type stop: int\n"
|
||||||
|
" :arg step: The step between successive values in the vector.\n"
|
||||||
|
" :type step: int\n"
|
||||||
|
);
|
||||||
|
static PyObject *C_Vector_Range(PyObject *cls, PyObject *args)
|
||||||
|
{
|
||||||
|
float *vec;
|
||||||
|
int stop, size;
|
||||||
|
int start= 0;
|
||||||
|
int step= 1;
|
||||||
|
|
||||||
|
if (!PyArg_ParseTuple(args, "i|ii:Vector.Range", &start, &stop, &step)) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (PyTuple_GET_SIZE(args)) {
|
||||||
|
case 1:
|
||||||
|
size = start;
|
||||||
|
start= 0;
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
if (start >= stop) {
|
||||||
|
PyErr_SetString(PyExc_RuntimeError,
|
||||||
|
"Start value is larger"
|
||||||
|
"than the stop value");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
size= stop - start;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
if (start >= stop) {
|
||||||
|
PyErr_SetString(PyExc_RuntimeError,
|
||||||
|
"Start value is larger"
|
||||||
|
"than the stop value");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
size= (stop - start)/step;
|
||||||
|
if (size%step)
|
||||||
|
size++;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
vec= PyMem_Malloc(size * sizeof(float));
|
||||||
|
|
||||||
|
if (vec == NULL) {
|
||||||
|
PyErr_SetString(PyExc_MemoryError,
|
||||||
|
"Vector.Range(): "
|
||||||
|
"problem allocating pointer space");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
range_vn_fl(vec, size, (float)start, (float)step);
|
||||||
|
|
||||||
|
return Vector_CreatePyObject_alloc(vec, size, (PyTypeObject *)cls);
|
||||||
|
}
|
||||||
|
|
||||||
|
PyDoc_STRVAR(C_Vector_Linspace_doc,
|
||||||
|
".. classmethod:: Linspace(start, stop, size)\n"
|
||||||
|
"\n"
|
||||||
|
" Create a vector of the specified size which is filled with linearly spaced values between start and stop values.\n"
|
||||||
|
"\n"
|
||||||
|
" :arg start: The start of the range used to fill the vector.\n"
|
||||||
|
" :type start: int\n"
|
||||||
|
" :arg stop: The end of the range used to fill the vector.\n"
|
||||||
|
" :type stop: int\n"
|
||||||
|
" :arg size: The size of the vector to be created.\n"
|
||||||
|
" :type size: int\n"
|
||||||
|
);
|
||||||
|
static PyObject *C_Vector_Linspace(PyObject *cls, PyObject *args)
|
||||||
|
{
|
||||||
|
float *vec;
|
||||||
|
int size;
|
||||||
|
float start, end, step;
|
||||||
|
|
||||||
|
if (!PyArg_ParseTuple(args, "ffi:Vector.Linspace", &start, &end, &size)) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (size < 2) {
|
||||||
|
PyErr_SetString(PyExc_RuntimeError,
|
||||||
|
"Vector.Linspace(): invalid size");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
step= (end - start)/(float)(size-1);
|
||||||
|
|
||||||
|
vec= PyMem_Malloc(size * sizeof(float));
|
||||||
|
|
||||||
|
if (vec == NULL) {
|
||||||
|
PyErr_SetString(PyExc_MemoryError,
|
||||||
|
"Vector.Linspace(): "
|
||||||
|
"problem allocating pointer space");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
range_vn_fl(vec, size, start, step);
|
||||||
|
|
||||||
|
return Vector_CreatePyObject_alloc(vec, size, (PyTypeObject *)cls);
|
||||||
|
}
|
||||||
|
|
||||||
|
PyDoc_STRVAR(C_Vector_Repeat_doc,
|
||||||
|
".. classmethod:: Repeat(vector, size)\n"
|
||||||
|
"\n"
|
||||||
|
" Create a vector by repeating the values in vector until the required size is reached.\n"
|
||||||
|
"\n"
|
||||||
|
" :arg tuple: The vector to draw values from.\n"
|
||||||
|
" :type tuple: :class:`mathutils.Vector`\n"
|
||||||
|
" :arg size: The size of the vector to be created.\n"
|
||||||
|
" :type size: int\n"
|
||||||
|
);
|
||||||
|
static PyObject *C_Vector_Repeat(PyObject *cls, PyObject *args)
|
||||||
|
{
|
||||||
|
float *vec;
|
||||||
|
float *iter_vec= NULL;
|
||||||
|
int i, size, value_size;
|
||||||
|
PyObject *value;
|
||||||
|
|
||||||
|
if (!PyArg_ParseTuple(args, "Oi:Vector.Repeat", &value, &size)) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (size < 2) {
|
||||||
|
PyErr_SetString(PyExc_RuntimeError,
|
||||||
|
"Vector.Repeat(): invalid size");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((value_size=mathutils_array_parse_alloc(&iter_vec, 2, value, "Vector.Repeat(vector, size), invalid 'vector' arg")) == -1) {
|
||||||
|
PyMem_Free(iter_vec);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (iter_vec == NULL) {
|
||||||
|
PyErr_SetString(PyExc_MemoryError,
|
||||||
|
"Vector.Repeat(): "
|
||||||
|
"problem allocating pointer space");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
vec= PyMem_Malloc(size * sizeof(float));
|
||||||
|
|
||||||
|
if (vec == NULL) {
|
||||||
|
PyErr_SetString(PyExc_MemoryError,
|
||||||
|
"Vector.Repeat(): "
|
||||||
|
"problem allocating pointer space");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
i= 0;
|
||||||
|
while (i < size) {
|
||||||
|
vec[i]= iter_vec[i % value_size];
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
|
||||||
|
PyMem_Free(iter_vec);
|
||||||
|
|
||||||
|
return Vector_CreatePyObject_alloc(vec, size, (PyTypeObject *)cls);
|
||||||
|
}
|
||||||
|
|
||||||
/*-----------------------------METHODS---------------------------- */
|
/*-----------------------------METHODS---------------------------- */
|
||||||
PyDoc_STRVAR(Vector_zero_doc,
|
PyDoc_STRVAR(Vector_zero_doc,
|
||||||
".. method:: zero()\n"
|
".. method:: zero()\n"
|
||||||
@ -137,6 +360,101 @@ static PyObject *Vector_normalized(VectorObject *self)
|
|||||||
return vec__apply_to_copy((PyNoArgsFunction)Vector_normalize, self);
|
return vec__apply_to_copy((PyNoArgsFunction)Vector_normalize, self);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PyDoc_STRVAR(Vector_resize_doc,
|
||||||
|
".. method:: resize(size=3)\n"
|
||||||
|
"\n"
|
||||||
|
" Resize the vector to have size number of elements.\n"
|
||||||
|
"\n"
|
||||||
|
" :return: an instance of itself\n"
|
||||||
|
" :rtype: :class:`Vector`\n"
|
||||||
|
);
|
||||||
|
static PyObject *Vector_resize(VectorObject *self, PyObject *value)
|
||||||
|
{
|
||||||
|
int size;
|
||||||
|
|
||||||
|
if (self->wrapped==Py_WRAP) {
|
||||||
|
PyErr_SetString(PyExc_TypeError,
|
||||||
|
"Vector.resize(): "
|
||||||
|
"cannot resize wrapped data - only python vectors");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
if (self->cb_user) {
|
||||||
|
PyErr_SetString(PyExc_TypeError,
|
||||||
|
"Vector.resize(): "
|
||||||
|
"cannot resize a vector that has an owner");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((size = PyLong_AsLong(value)) == -1) {
|
||||||
|
PyErr_SetString(PyExc_TypeError,
|
||||||
|
"Vector.resize(size): "
|
||||||
|
"expected size argument to be an integer");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (size < 2) {
|
||||||
|
PyErr_SetString(PyExc_RuntimeError,
|
||||||
|
"Vector.resize(): invalid size");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
self->vec = PyMem_Realloc(self->vec, (size * sizeof(float)));
|
||||||
|
if (self->vec == NULL) {
|
||||||
|
PyErr_SetString(PyExc_MemoryError,
|
||||||
|
"Vector.resize(): "
|
||||||
|
"problem allocating pointer space");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* If the vector has increased in length, set all new elements to 0.0f */
|
||||||
|
if (size > self->size) {
|
||||||
|
fill_vn_fl(self->vec + self->size, size - self->size, 0.0f);
|
||||||
|
}
|
||||||
|
|
||||||
|
self->size = size;
|
||||||
|
Py_RETURN_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
PyDoc_STRVAR(Vector_resized_doc,
|
||||||
|
".. method:: resized(size=3)\n"
|
||||||
|
"\n"
|
||||||
|
" Return a resized copy of the vector with size number of elements.\n"
|
||||||
|
"\n"
|
||||||
|
" :return: a new vector\n"
|
||||||
|
" :rtype: :class:`Vector`\n"
|
||||||
|
);
|
||||||
|
static PyObject *Vector_resized(VectorObject *self, PyObject *value)
|
||||||
|
{
|
||||||
|
int size;
|
||||||
|
float *vec;
|
||||||
|
|
||||||
|
/*if (!PyArg_ParseTuple(args, "i:resize", &size))
|
||||||
|
return NULL;*/
|
||||||
|
if ((size = PyLong_AsLong(value)) == -1) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (size < 2) {
|
||||||
|
PyErr_SetString(PyExc_RuntimeError,
|
||||||
|
"Vector.resized(): invalid size");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
vec= PyMem_Malloc(size * sizeof(float));
|
||||||
|
|
||||||
|
if (vec == NULL) {
|
||||||
|
PyErr_SetString(PyExc_MemoryError,
|
||||||
|
"Vector.resized(): "
|
||||||
|
"problem allocating pointer space");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
fill_vn_fl(vec, size, 0.0f);
|
||||||
|
memcpy(vec, self->vec, self->size * sizeof(float));
|
||||||
|
|
||||||
|
return Vector_CreatePyObject_alloc(vec, size, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
PyDoc_STRVAR(Vector_resize_2d_doc,
|
PyDoc_STRVAR(Vector_resize_2d_doc,
|
||||||
".. method:: resize_2d()\n"
|
".. method:: resize_2d()\n"
|
||||||
"\n"
|
"\n"
|
||||||
@ -394,7 +712,7 @@ static PyObject *Vector_to_track_quat(VectorObject *self, PyObject *args)
|
|||||||
|
|
||||||
if (strlen(strack) == 2) {
|
if (strlen(strack) == 2) {
|
||||||
if (strack[0] == '-') {
|
if (strack[0] == '-') {
|
||||||
switch(strack[1]) {
|
switch (strack[1]) {
|
||||||
case 'X':
|
case 'X':
|
||||||
track = 3;
|
track = 3;
|
||||||
break;
|
break;
|
||||||
@ -415,7 +733,7 @@ static PyObject *Vector_to_track_quat(VectorObject *self, PyObject *args)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (strlen(strack) == 1) {
|
else if (strlen(strack) == 1) {
|
||||||
switch(strack[0]) {
|
switch (strack[0]) {
|
||||||
case '-':
|
case '-':
|
||||||
case 'X':
|
case 'X':
|
||||||
track = 0;
|
track = 0;
|
||||||
@ -440,7 +758,7 @@ static PyObject *Vector_to_track_quat(VectorObject *self, PyObject *args)
|
|||||||
if (sup) {
|
if (sup) {
|
||||||
const char *axis_err_msg= "only X, Y or Z for up axis";
|
const char *axis_err_msg= "only X, Y or Z for up axis";
|
||||||
if (strlen(sup) == 1) {
|
if (strlen(sup) == 1) {
|
||||||
switch(*sup) {
|
switch (*sup) {
|
||||||
case 'X':
|
case 'X':
|
||||||
up = 0;
|
up = 0;
|
||||||
break;
|
break;
|
||||||
@ -505,6 +823,12 @@ static PyObject *Vector_reflect(VectorObject *self, PyObject *value)
|
|||||||
if ((value_size= mathutils_array_parse(tvec, 2, 4, value, "Vector.reflect(other), invalid 'other' arg")) == -1)
|
if ((value_size= mathutils_array_parse(tvec, 2, 4, value, "Vector.reflect(other), invalid 'other' arg")) == -1)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
|
if (self->size < 2 || self->size > 4) {
|
||||||
|
PyErr_SetString(PyExc_ValueError,
|
||||||
|
"Vector must be 2D, 3D or 4D");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
mirror[0] = tvec[0];
|
mirror[0] = tvec[0];
|
||||||
mirror[1] = tvec[1];
|
mirror[1] = tvec[1];
|
||||||
if (value_size > 2) mirror[2] = tvec[2];
|
if (value_size > 2) mirror[2] = tvec[2];
|
||||||
@ -544,6 +868,12 @@ static PyObject *Vector_cross(VectorObject *self, PyObject *value)
|
|||||||
if (mathutils_array_parse(tvec, self->size, self->size, value, "Vector.cross(other), invalid 'other' arg") == -1)
|
if (mathutils_array_parse(tvec, self->size, self->size, value, "Vector.cross(other), invalid 'other' arg") == -1)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
|
if (self->size != 3) {
|
||||||
|
PyErr_SetString(PyExc_ValueError,
|
||||||
|
"Vector must be 3D");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
ret= (VectorObject *)Vector_CreatePyObject(NULL, 3, Py_NEW, Py_TYPE(self));
|
ret= (VectorObject *)Vector_CreatePyObject(NULL, 3, Py_NEW, Py_TYPE(self));
|
||||||
cross_v3_v3v3(ret->vec, self->vec, tvec);
|
cross_v3_v3v3(ret->vec, self->vec, tvec);
|
||||||
return (PyObject *)ret;
|
return (PyObject *)ret;
|
||||||
@ -561,15 +891,20 @@ PyDoc_STRVAR(Vector_dot_doc,
|
|||||||
);
|
);
|
||||||
static PyObject *Vector_dot(VectorObject *self, PyObject *value)
|
static PyObject *Vector_dot(VectorObject *self, PyObject *value)
|
||||||
{
|
{
|
||||||
float tvec[MAX_DIMENSIONS];
|
float *tvec;
|
||||||
|
|
||||||
if (BaseMath_ReadCallback(self) == -1)
|
if (BaseMath_ReadCallback(self) == -1)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
if (mathutils_array_parse(tvec, self->size, self->size, value, "Vector.dot(other), invalid 'other' arg") == -1)
|
if (mathutils_array_parse_alloc(&tvec, self->size, value, "Vector.dot(other), invalid 'other' arg") == -1) {
|
||||||
return NULL;
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
return PyFloat_FromDouble(dot_vn_vn(self->vec, tvec, self->size));
|
return PyFloat_FromDouble(dot_vn_vn(self->vec, tvec, self->size));
|
||||||
|
|
||||||
|
cleanup:
|
||||||
|
PyMem_Free(tvec);
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
PyDoc_STRVAR(Vector_angle_doc,
|
PyDoc_STRVAR(Vector_angle_doc,
|
||||||
@ -607,6 +942,12 @@ static PyObject *Vector_angle(VectorObject *self, PyObject *args)
|
|||||||
if (mathutils_array_parse(tvec, self->size, self->size, value, "Vector.angle(other), invalid 'other' arg") == -1)
|
if (mathutils_array_parse(tvec, self->size, self->size, value, "Vector.angle(other), invalid 'other' arg") == -1)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
|
if (self->size > 4) {
|
||||||
|
PyErr_SetString(PyExc_ValueError,
|
||||||
|
"Vector must be 2D, 3D or 4D");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
for (x = 0; x < size; x++) {
|
for (x = 0; x < size; x++) {
|
||||||
dot_self += (double)self->vec[x] * (double)self->vec[x];
|
dot_self += (double)self->vec[x] * (double)self->vec[x];
|
||||||
dot_other += (double)tvec[x] * (double)tvec[x];
|
dot_other += (double)tvec[x] * (double)tvec[x];
|
||||||
@ -647,7 +988,7 @@ static PyObject *Vector_rotation_difference(VectorObject *self, PyObject *value)
|
|||||||
{
|
{
|
||||||
float quat[4], vec_a[3], vec_b[3];
|
float quat[4], vec_a[3], vec_b[3];
|
||||||
|
|
||||||
if (self->size < 3) {
|
if (self->size < 3 || self->size > 4) {
|
||||||
PyErr_SetString(PyExc_ValueError,
|
PyErr_SetString(PyExc_ValueError,
|
||||||
"vec.difference(value): "
|
"vec.difference(value): "
|
||||||
"expects both vectors to be size 3 or 4");
|
"expects both vectors to be size 3 or 4");
|
||||||
@ -692,6 +1033,12 @@ static PyObject *Vector_project(VectorObject *self, PyObject *value)
|
|||||||
if (mathutils_array_parse(tvec, size, size, value, "Vector.project(other), invalid 'other' arg") == -1)
|
if (mathutils_array_parse(tvec, size, size, value, "Vector.project(other), invalid 'other' arg") == -1)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
|
if (self->size > 4) {
|
||||||
|
PyErr_SetString(PyExc_ValueError,
|
||||||
|
"Vector must be 2D, 3D or 4D");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
if (BaseMath_ReadCallback(self) == -1)
|
if (BaseMath_ReadCallback(self) == -1)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
@ -725,24 +1072,41 @@ static PyObject *Vector_lerp(VectorObject *self, PyObject *args)
|
|||||||
const int size= self->size;
|
const int size= self->size;
|
||||||
PyObject *value= NULL;
|
PyObject *value= NULL;
|
||||||
float fac, ifac;
|
float fac, ifac;
|
||||||
float tvec[MAX_DIMENSIONS], vec[MAX_DIMENSIONS];
|
float *tvec, *vec;
|
||||||
int x;
|
int x;
|
||||||
|
|
||||||
if (!PyArg_ParseTuple(args, "Of:lerp", &value, &fac))
|
if (!PyArg_ParseTuple(args, "Of:lerp", &value, &fac))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
if (mathutils_array_parse(tvec, size, size, value, "Vector.lerp(other), invalid 'other' arg") == -1)
|
if (mathutils_array_parse_alloc(&tvec, size, value, "Vector.lerp(other), invalid 'other' arg") == -1) {
|
||||||
return NULL;
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
if (BaseMath_ReadCallback(self) == -1)
|
if (BaseMath_ReadCallback(self) == -1) {
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
vec= PyMem_Malloc(size * sizeof(float));
|
||||||
|
if (vec == NULL) {
|
||||||
|
PyErr_SetString(PyExc_MemoryError,
|
||||||
|
"Vector.lerp(): "
|
||||||
|
"problem allocating pointer space");
|
||||||
return NULL;
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
ifac= 1.0f - fac;
|
ifac= 1.0f - fac;
|
||||||
|
|
||||||
for (x = 0; x < size; x++) {
|
for (x = 0; x < size; x++) {
|
||||||
vec[x] = (ifac * self->vec[x]) + (fac * tvec[x]);
|
vec[x] = (ifac * self->vec[x]) + (fac * tvec[x]);
|
||||||
}
|
}
|
||||||
return Vector_CreatePyObject(vec, size, Py_NEW, Py_TYPE(self));
|
|
||||||
|
PyMem_Free(tvec);
|
||||||
|
|
||||||
|
return Vector_CreatePyObject_alloc(vec, size, Py_TYPE(self));
|
||||||
|
|
||||||
|
cleanup:
|
||||||
|
PyMem_Free(tvec);
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
PyDoc_STRVAR(Vector_rotate_doc,
|
PyDoc_STRVAR(Vector_rotate_doc,
|
||||||
@ -763,7 +1127,7 @@ static PyObject *Vector_rotate(VectorObject *self, PyObject *value)
|
|||||||
if (mathutils_any_to_rotmat(other_rmat, value, "Vector.rotate(value)") == -1)
|
if (mathutils_any_to_rotmat(other_rmat, value, "Vector.rotate(value)") == -1)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
if (self->size < 3) {
|
if (self->size < 3 || self->size > 4) {
|
||||||
PyErr_SetString(PyExc_ValueError,
|
PyErr_SetString(PyExc_ValueError,
|
||||||
"Vector must be 3D or 4D");
|
"Vector must be 3D or 4D");
|
||||||
return NULL;
|
return NULL;
|
||||||
@ -903,8 +1267,8 @@ static PyObject *Vector_slice(VectorObject *self, int begin, int end)
|
|||||||
/* sequence slice (set): vector[a:b] = value */
|
/* sequence slice (set): vector[a:b] = value */
|
||||||
static int Vector_ass_slice(VectorObject *self, int begin, int end, PyObject *seq)
|
static int Vector_ass_slice(VectorObject *self, int begin, int end, PyObject *seq)
|
||||||
{
|
{
|
||||||
int y, size = 0;
|
int size = 0;
|
||||||
float vec[MAX_DIMENSIONS];
|
float *vec= NULL;
|
||||||
|
|
||||||
if (BaseMath_ReadCallback(self) == -1)
|
if (BaseMath_ReadCallback(self) == -1)
|
||||||
return -1;
|
return -1;
|
||||||
@ -914,18 +1278,30 @@ static int Vector_ass_slice(VectorObject *self, int begin, int end, PyObject *se
|
|||||||
begin = MIN2(begin, end);
|
begin = MIN2(begin, end);
|
||||||
|
|
||||||
size = (end - begin);
|
size = (end - begin);
|
||||||
if (mathutils_array_parse(vec, size, size, seq, "vector[begin:end] = [...]") == -1)
|
if (mathutils_array_parse_alloc(&vec, size, seq, "vector[begin:end] = [...]") == -1) {
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (vec == NULL) {
|
||||||
|
PyErr_SetString(PyExc_MemoryError,
|
||||||
|
"vec[:] = seq: "
|
||||||
|
"problem allocating pointer space");
|
||||||
return -1;
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
/*parsed well - now set in vector*/
|
/*parsed well - now set in vector*/
|
||||||
for (y = 0; y < size; y++) {
|
memcpy(self->vec + begin, vec, size * sizeof(float));
|
||||||
self->vec[begin + y] = vec[y];
|
|
||||||
}
|
|
||||||
|
|
||||||
if (BaseMath_WriteCallback(self) == -1)
|
if (BaseMath_WriteCallback(self) == -1)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
|
PyMem_Free(vec);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
cleanup:
|
||||||
|
PyMem_Free(vec);
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Numeric Protocols */
|
/* Numeric Protocols */
|
||||||
@ -933,7 +1309,7 @@ static int Vector_ass_slice(VectorObject *self, int begin, int end, PyObject *se
|
|||||||
static PyObject *Vector_add(PyObject *v1, PyObject *v2)
|
static PyObject *Vector_add(PyObject *v1, PyObject *v2)
|
||||||
{
|
{
|
||||||
VectorObject *vec1 = NULL, *vec2 = NULL;
|
VectorObject *vec1 = NULL, *vec2 = NULL;
|
||||||
float vec[MAX_DIMENSIONS];
|
float *vec= NULL;
|
||||||
|
|
||||||
if (!VectorObject_Check(v1) || !VectorObject_Check(v2)) {
|
if (!VectorObject_Check(v1) || !VectorObject_Check(v2)) {
|
||||||
PyErr_Format(PyExc_AttributeError,
|
PyErr_Format(PyExc_AttributeError,
|
||||||
@ -956,9 +1332,18 @@ static PyObject *Vector_add(PyObject *v1, PyObject *v2)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
vec= PyMem_Malloc(vec1->size * sizeof(float));
|
||||||
|
|
||||||
|
if (vec == NULL) { /*allocation failure*/
|
||||||
|
PyErr_SetString(PyExc_MemoryError,
|
||||||
|
"Vector(): "
|
||||||
|
"problem allocating pointer space");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
add_vn_vnvn(vec, vec1->vec, vec2->vec, vec1->size);
|
add_vn_vnvn(vec, vec1->vec, vec2->vec, vec1->size);
|
||||||
|
|
||||||
return Vector_CreatePyObject(vec, vec1->size, Py_NEW, Py_TYPE(v1));
|
return Vector_CreatePyObject_alloc(vec, vec1->size, Py_TYPE(v1));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* addition in-place: obj += obj */
|
/* addition in-place: obj += obj */
|
||||||
@ -997,7 +1382,7 @@ static PyObject *Vector_iadd(PyObject *v1, PyObject *v2)
|
|||||||
static PyObject *Vector_sub(PyObject *v1, PyObject *v2)
|
static PyObject *Vector_sub(PyObject *v1, PyObject *v2)
|
||||||
{
|
{
|
||||||
VectorObject *vec1 = NULL, *vec2 = NULL;
|
VectorObject *vec1 = NULL, *vec2 = NULL;
|
||||||
float vec[MAX_DIMENSIONS];
|
float *vec;
|
||||||
|
|
||||||
if (!VectorObject_Check(v1) || !VectorObject_Check(v2)) {
|
if (!VectorObject_Check(v1) || !VectorObject_Check(v2)) {
|
||||||
PyErr_Format(PyExc_AttributeError,
|
PyErr_Format(PyExc_AttributeError,
|
||||||
@ -1019,9 +1404,18 @@ static PyObject *Vector_sub(PyObject *v1, PyObject *v2)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
vec= PyMem_Malloc(vec1->size * sizeof(float));
|
||||||
|
|
||||||
|
if (vec == NULL) { /*allocation failure*/
|
||||||
|
PyErr_SetString(PyExc_MemoryError,
|
||||||
|
"Vector(): "
|
||||||
|
"problem allocating pointer space");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
sub_vn_vnvn(vec, vec1->vec, vec2->vec, vec1->size);
|
sub_vn_vnvn(vec, vec1->vec, vec2->vec, vec1->size);
|
||||||
|
|
||||||
return Vector_CreatePyObject(vec, vec1->size, Py_NEW, Py_TYPE(v1));
|
return Vector_CreatePyObject_alloc(vec, vec1->size, Py_TYPE(v1));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* subtraction in-place: obj -= obj */
|
/* subtraction in-place: obj -= obj */
|
||||||
@ -1093,7 +1487,7 @@ int column_vector_multiplication(float rvec[MAX_DIMENSIONS], VectorObject* vec,
|
|||||||
|
|
||||||
for (x = 0; x < mat->col_size; x++) {
|
for (x = 0; x < mat->col_size; x++) {
|
||||||
for (y = 0; y < mat->row_size; y++) {
|
for (y = 0; y < mat->row_size; y++) {
|
||||||
dot += (double)(mat->matrix[y][x] * vec_cpy[y]);
|
dot += (double)(MATRIX_ITEM(mat, y, x) * vec_cpy[y]);
|
||||||
}
|
}
|
||||||
rvec[z++] = (float)dot;
|
rvec[z++] = (float)dot;
|
||||||
dot = 0.0f;
|
dot = 0.0f;
|
||||||
@ -1104,9 +1498,18 @@ int column_vector_multiplication(float rvec[MAX_DIMENSIONS], VectorObject* vec,
|
|||||||
|
|
||||||
static PyObject *vector_mul_float(VectorObject *vec, const float scalar)
|
static PyObject *vector_mul_float(VectorObject *vec, const float scalar)
|
||||||
{
|
{
|
||||||
float tvec[MAX_DIMENSIONS];
|
float *tvec= NULL;
|
||||||
|
tvec= PyMem_Malloc(vec->size * sizeof(float));
|
||||||
|
|
||||||
|
if (tvec == NULL) { /*allocation failure*/
|
||||||
|
PyErr_SetString(PyExc_MemoryError,
|
||||||
|
"vec * float: "
|
||||||
|
"problem allocating pointer space");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
mul_vn_vn_fl(tvec, vec->vec, vec->size, scalar);
|
mul_vn_vn_fl(tvec, vec->vec, vec->size, scalar);
|
||||||
return Vector_CreatePyObject(tvec, vec->size, Py_NEW, Py_TYPE(vec));
|
return Vector_CreatePyObject_alloc(tvec, vec->size, Py_TYPE(vec));
|
||||||
}
|
}
|
||||||
|
|
||||||
static PyObject *Vector_mul(PyObject *v1, PyObject *v2)
|
static PyObject *Vector_mul(PyObject *v1, PyObject *v2)
|
||||||
@ -1277,8 +1680,7 @@ static PyObject *Vector_imul(PyObject *v1, PyObject *v2)
|
|||||||
/* divid: obj / obj */
|
/* divid: obj / obj */
|
||||||
static PyObject *Vector_div(PyObject *v1, PyObject *v2)
|
static PyObject *Vector_div(PyObject *v1, PyObject *v2)
|
||||||
{
|
{
|
||||||
int i;
|
float *vec= NULL, scalar;
|
||||||
float vec[4], scalar;
|
|
||||||
VectorObject *vec1 = NULL;
|
VectorObject *vec1 = NULL;
|
||||||
|
|
||||||
if (!VectorObject_Check(v1)) { /* not a vector */
|
if (!VectorObject_Check(v1)) { /* not a vector */
|
||||||
@ -1287,7 +1689,7 @@ static PyObject *Vector_div(PyObject *v1, PyObject *v2)
|
|||||||
"Vector must be divided by a float");
|
"Vector must be divided by a float");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
vec1 = (VectorObject*)v1; /* vector */
|
vec1 = (VectorObject *)v1; /* vector */
|
||||||
|
|
||||||
if (BaseMath_ReadCallback(vec1) == -1)
|
if (BaseMath_ReadCallback(vec1) == -1)
|
||||||
return NULL;
|
return NULL;
|
||||||
@ -1306,16 +1708,23 @@ static PyObject *Vector_div(PyObject *v1, PyObject *v2)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i < vec1->size; i++) {
|
vec= PyMem_Malloc(vec1->size * sizeof(float));
|
||||||
vec[i] = vec1->vec[i] / scalar;
|
|
||||||
|
if (vec == NULL) { /*allocation failure*/
|
||||||
|
PyErr_SetString(PyExc_MemoryError,
|
||||||
|
"vec / value: "
|
||||||
|
"problem allocating pointer space");
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
return Vector_CreatePyObject(vec, vec1->size, Py_NEW, Py_TYPE(v1));
|
|
||||||
|
mul_vn_vn_fl(vec, vec1->vec, vec1->size, 1.0f/scalar);
|
||||||
|
|
||||||
|
return Vector_CreatePyObject_alloc(vec, vec1->size, Py_TYPE(v1));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* divide in-place: obj /= obj */
|
/* divide in-place: obj /= obj */
|
||||||
static PyObject *Vector_idiv(PyObject *v1, PyObject *v2)
|
static PyObject *Vector_idiv(PyObject *v1, PyObject *v2)
|
||||||
{
|
{
|
||||||
int i;
|
|
||||||
float scalar;
|
float scalar;
|
||||||
VectorObject *vec1 = (VectorObject*)v1;
|
VectorObject *vec1 = (VectorObject*)v1;
|
||||||
|
|
||||||
@ -1335,9 +1744,8 @@ static PyObject *Vector_idiv(PyObject *v1, PyObject *v2)
|
|||||||
"divide by zero error");
|
"divide by zero error");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
for (i = 0; i < vec1->size; i++) {
|
|
||||||
vec1->vec[i] /= scalar;
|
mul_vn_fl(vec1->vec, vec1->size, 1.0f/scalar);
|
||||||
}
|
|
||||||
|
|
||||||
(void)BaseMath_WriteCallback(vec1);
|
(void)BaseMath_WriteCallback(vec1);
|
||||||
|
|
||||||
@ -1349,29 +1757,24 @@ static PyObject *Vector_idiv(PyObject *v1, PyObject *v2)
|
|||||||
returns the negative of this object*/
|
returns the negative of this object*/
|
||||||
static PyObject *Vector_neg(VectorObject *self)
|
static PyObject *Vector_neg(VectorObject *self)
|
||||||
{
|
{
|
||||||
float tvec[MAX_DIMENSIONS];
|
float *tvec;
|
||||||
|
|
||||||
if (BaseMath_ReadCallback(self) == -1)
|
if (BaseMath_ReadCallback(self) == -1)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
|
tvec= PyMem_Malloc(self->size * sizeof(float));
|
||||||
negate_vn_vn(tvec, self->vec, self->size);
|
negate_vn_vn(tvec, self->vec, self->size);
|
||||||
return Vector_CreatePyObject(tvec, self->size, Py_NEW, Py_TYPE(self));
|
return Vector_CreatePyObject_alloc(tvec, self->size, Py_TYPE(self));
|
||||||
}
|
}
|
||||||
|
|
||||||
/*------------------------vec_magnitude_nosqrt (internal) - for comparing only */
|
/*------------------------vec_magnitude_nosqrt (internal) - for comparing only */
|
||||||
static double vec_magnitude_nosqrt(float *data, int size)
|
static double vec_magnitude_nosqrt(float *data, int size)
|
||||||
{
|
{
|
||||||
double dot = 0.0f;
|
|
||||||
int i;
|
|
||||||
|
|
||||||
for (i=0; i<size; i++) {
|
|
||||||
dot += (double)data[i];
|
|
||||||
}
|
|
||||||
/*return (double)sqrt(dot);*/
|
/*return (double)sqrt(dot);*/
|
||||||
/* warning, line above removed because we are not using the length,
|
/* warning, line above removed because we are not using the length,
|
||||||
rather the comparing the sizes and for this we do not need the sqrt
|
rather the comparing the sizes and for this we do not need the sqrt
|
||||||
for the actual length, the dot must be sqrt'd */
|
for the actual length, the dot must be sqrt'd */
|
||||||
return dot;
|
return dot_vn_vn(data, data, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -1606,16 +2009,10 @@ static int Vector_setAxis(VectorObject *self, PyObject *value, void *type)
|
|||||||
/* vector.length */
|
/* vector.length */
|
||||||
static PyObject *Vector_getLength(VectorObject *self, void *UNUSED(closure))
|
static PyObject *Vector_getLength(VectorObject *self, void *UNUSED(closure))
|
||||||
{
|
{
|
||||||
double dot = 0.0f;
|
|
||||||
int i;
|
|
||||||
|
|
||||||
if (BaseMath_ReadCallback(self) == -1)
|
if (BaseMath_ReadCallback(self) == -1)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
for (i = 0; i < self->size; i++) {
|
return PyFloat_FromDouble(sqrt(dot_vn_vn(self->vec, self->vec, self->size)));
|
||||||
dot += (double)(self->vec[i] * self->vec[i]);
|
|
||||||
}
|
|
||||||
return PyFloat_FromDouble(sqrt(dot));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int Vector_setLength(VectorObject *self, PyObject *value)
|
static int Vector_setLength(VectorObject *self, PyObject *value)
|
||||||
@ -2213,7 +2610,7 @@ static int row_vector_multiplication(float rvec[MAX_DIMENSIONS], VectorObject *v
|
|||||||
//muliplication
|
//muliplication
|
||||||
for (x = 0; x < mat->row_size; x++) {
|
for (x = 0; x < mat->row_size; x++) {
|
||||||
for (y = 0; y < mat->col_size; y++) {
|
for (y = 0; y < mat->col_size; y++) {
|
||||||
dot += mat->matrix[x][y] * vec_cpy[y];
|
dot += MATRIX_ITEM(mat, x, y) * vec_cpy[y];
|
||||||
}
|
}
|
||||||
rvec[z++] = (float)dot;
|
rvec[z++] = (float)dot;
|
||||||
dot = 0.0f;
|
dot = 0.0f;
|
||||||
@ -2242,6 +2639,12 @@ static PyObject *Vector_negate(VectorObject *self)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static struct PyMethodDef Vector_methods[] = {
|
static struct PyMethodDef Vector_methods[] = {
|
||||||
|
/* Class Methods */
|
||||||
|
{"Fill", (PyCFunction) C_Vector_Fill, METH_VARARGS | METH_CLASS, C_Vector_Fill_doc},
|
||||||
|
{"Range", (PyCFunction) C_Vector_Range, METH_VARARGS | METH_CLASS, C_Vector_Range_doc},
|
||||||
|
{"Linspace", (PyCFunction) C_Vector_Linspace, METH_VARARGS | METH_CLASS, C_Vector_Linspace_doc},
|
||||||
|
{"Repeat", (PyCFunction) C_Vector_Repeat, METH_VARARGS | METH_CLASS, C_Vector_Repeat_doc},
|
||||||
|
|
||||||
/* in place only */
|
/* in place only */
|
||||||
{"zero", (PyCFunction) Vector_zero, METH_NOARGS, Vector_zero_doc},
|
{"zero", (PyCFunction) Vector_zero, METH_NOARGS, Vector_zero_doc},
|
||||||
{"negate", (PyCFunction) Vector_negate, METH_NOARGS, Vector_negate_doc},
|
{"negate", (PyCFunction) Vector_negate, METH_NOARGS, Vector_negate_doc},
|
||||||
@ -2250,6 +2653,8 @@ static struct PyMethodDef Vector_methods[] = {
|
|||||||
{"normalize", (PyCFunction) Vector_normalize, METH_NOARGS, Vector_normalize_doc},
|
{"normalize", (PyCFunction) Vector_normalize, METH_NOARGS, Vector_normalize_doc},
|
||||||
{"normalized", (PyCFunction) Vector_normalized, METH_NOARGS, Vector_normalized_doc},
|
{"normalized", (PyCFunction) Vector_normalized, METH_NOARGS, Vector_normalized_doc},
|
||||||
|
|
||||||
|
{"resize", (PyCFunction) Vector_resize, METH_O, Vector_resize_doc},
|
||||||
|
{"resized", (PyCFunction) Vector_resized, METH_O, Vector_resized_doc},
|
||||||
{"to_2d", (PyCFunction) Vector_to_2d, METH_NOARGS, Vector_to_2d_doc},
|
{"to_2d", (PyCFunction) Vector_to_2d, METH_NOARGS, Vector_to_2d_doc},
|
||||||
{"resize_2d", (PyCFunction) Vector_resize_2d, METH_NOARGS, Vector_resize_2d_doc},
|
{"resize_2d", (PyCFunction) Vector_resize_2d, METH_NOARGS, Vector_resize_2d_doc},
|
||||||
{"to_3d", (PyCFunction) Vector_to_3d, METH_NOARGS, Vector_to_3d_doc},
|
{"to_3d", (PyCFunction) Vector_to_3d, METH_NOARGS, Vector_to_3d_doc},
|
||||||
@ -2375,7 +2780,7 @@ PyObject *Vector_CreatePyObject(float *vec, const int size, const int type, PyTy
|
|||||||
{
|
{
|
||||||
VectorObject *self;
|
VectorObject *self;
|
||||||
|
|
||||||
if (size > 4 || size < 2) {
|
if (size < 2) {
|
||||||
PyErr_SetString(PyExc_RuntimeError,
|
PyErr_SetString(PyExc_RuntimeError,
|
||||||
"Vector(): invalid size");
|
"Vector(): invalid size");
|
||||||
return NULL;
|
return NULL;
|
||||||
@ -2429,3 +2834,12 @@ PyObject *Vector_CreatePyObject_cb(PyObject *cb_user, int size, int cb_type, int
|
|||||||
|
|
||||||
return (PyObject *)self;
|
return (PyObject *)self;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PyObject *Vector_CreatePyObject_alloc(float *vec, const int size, PyTypeObject *base_type)
|
||||||
|
{
|
||||||
|
VectorObject *vect_ob;
|
||||||
|
vect_ob= (VectorObject *)Vector_CreatePyObject(vec, size, Py_WRAP, base_type);
|
||||||
|
vect_ob->wrapped= Py_NEW;
|
||||||
|
|
||||||
|
return (PyObject *)vect_ob;
|
||||||
|
}
|
||||||
|
@ -41,11 +41,12 @@ extern PyTypeObject vector_Type;
|
|||||||
typedef struct {
|
typedef struct {
|
||||||
BASE_MATH_MEMBERS(vec);
|
BASE_MATH_MEMBERS(vec);
|
||||||
|
|
||||||
unsigned char size; /* vec size 2,3 or 4 */
|
int size; /* vec size 2,3 or 4 */
|
||||||
} VectorObject;
|
} VectorObject;
|
||||||
|
|
||||||
/*prototypes*/
|
/*prototypes*/
|
||||||
PyObject *Vector_CreatePyObject(float *vec, const int size, const int type, PyTypeObject *base_type);
|
PyObject *Vector_CreatePyObject(float *vec, const int size, const int type, PyTypeObject *base_type);
|
||||||
PyObject *Vector_CreatePyObject_cb(PyObject *user, int size, int callback_type, int subtype);
|
PyObject *Vector_CreatePyObject_cb(PyObject *user, int size, int callback_type, int subtype);
|
||||||
|
PyObject *Vector_CreatePyObject_alloc(float *vec, const int size, PyTypeObject *base_type);
|
||||||
|
|
||||||
#endif /* MATHUTILS_VECTOR_H */
|
#endif /* MATHUTILS_VECTOR_H */
|
||||||
|
@ -612,7 +612,7 @@ static PyObject *M_Geometry_intersect_line_sphere(PyObject *UNUSED(self), PyObje
|
|||||||
|
|
||||||
PyObject *ret= PyTuple_New(2);
|
PyObject *ret= PyTuple_New(2);
|
||||||
|
|
||||||
switch(isect_line_sphere_v3(line_a->vec, line_b->vec, sphere_co->vec, sphere_radius, isect_a, isect_b)) {
|
switch (isect_line_sphere_v3(line_a->vec, line_b->vec, sphere_co->vec, sphere_radius, isect_a, isect_b)) {
|
||||||
case 1:
|
case 1:
|
||||||
if (!(!clip || (((lambda= line_point_factor_v3(isect_a, line_a->vec, line_b->vec)) >= 0.0f) && (lambda <= 1.0f)))) use_a= FALSE;
|
if (!(!clip || (((lambda= line_point_factor_v3(isect_a, line_a->vec, line_b->vec)) >= 0.0f) && (lambda <= 1.0f)))) use_a= FALSE;
|
||||||
use_b= FALSE;
|
use_b= FALSE;
|
||||||
@ -685,7 +685,7 @@ static PyObject *M_Geometry_intersect_line_sphere_2d(PyObject *UNUSED(self), PyO
|
|||||||
|
|
||||||
PyObject *ret= PyTuple_New(2);
|
PyObject *ret= PyTuple_New(2);
|
||||||
|
|
||||||
switch(isect_line_sphere_v2(line_a->vec, line_b->vec, sphere_co->vec, sphere_radius, isect_a, isect_b)) {
|
switch (isect_line_sphere_v2(line_a->vec, line_b->vec, sphere_co->vec, sphere_radius, isect_a, isect_b)) {
|
||||||
case 1:
|
case 1:
|
||||||
if (!(!clip || (((lambda= line_point_factor_v2(isect_a, line_a->vec, line_b->vec)) >= 0.0f) && (lambda <= 1.0f)))) use_a= FALSE;
|
if (!(!clip || (((lambda= line_point_factor_v2(isect_a, line_a->vec, line_b->vec)) >= 0.0f) && (lambda <= 1.0f)))) use_a= FALSE;
|
||||||
use_b= FALSE;
|
use_b= FALSE;
|
||||||
|
@ -201,7 +201,7 @@ static void rand_vn(float *array_tar, const int size)
|
|||||||
{
|
{
|
||||||
float *array_pt= array_tar + (size-1);
|
float *array_pt= array_tar + (size-1);
|
||||||
int i= size;
|
int i= size;
|
||||||
while(i--) { *(array_pt--) = 2.0f * frand() - 1.0f; }
|
while (i--) { *(array_pt--) = 2.0f * frand() - 1.0f; }
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Fills an array of length 3 with noise values */
|
/* Fills an array of length 3 with noise values */
|
||||||
|
@ -177,7 +177,6 @@ void WM_init(bContext *C, int argc, const char **argv)
|
|||||||
GPU_extensions_init();
|
GPU_extensions_init();
|
||||||
GPU_set_mipmap(!(U.gameflags & USER_DISABLE_MIPMAP));
|
GPU_set_mipmap(!(U.gameflags & USER_DISABLE_MIPMAP));
|
||||||
GPU_set_anisotropic(U.anisotropic_filter);
|
GPU_set_anisotropic(U.anisotropic_filter);
|
||||||
GPU_code_generate_glsl_lib();
|
|
||||||
|
|
||||||
UI_init();
|
UI_init();
|
||||||
}
|
}
|
||||||
|
@ -431,6 +431,8 @@ void RAS_2DFilterManager::RenderFilters(RAS_ICanvas* canvas)
|
|||||||
glViewport(0,0, texturewidth, textureheight);
|
glViewport(0,0, texturewidth, textureheight);
|
||||||
|
|
||||||
glDisable(GL_DEPTH_TEST);
|
glDisable(GL_DEPTH_TEST);
|
||||||
|
// in case the previous material was wire
|
||||||
|
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
|
||||||
// if the last rendered face had alpha add it would messes with the color of the plane we apply 2DFilter to
|
// if the last rendered face had alpha add it would messes with the color of the plane we apply 2DFilter to
|
||||||
glDisable(GL_BLEND);
|
glDisable(GL_BLEND);
|
||||||
glPushMatrix(); //GL_MODELVIEW
|
glPushMatrix(); //GL_MODELVIEW
|
||||||
|
Loading…
Reference in New Issue
Block a user