1 | |
2 | // |
3 | // This source file is part of appleseed. |
4 | // Visit http://appleseedhq.net/ for additional information and resources. |
5 | // |
6 | // This software is released under the MIT license. |
7 | // |
8 | // Copyright (c) 2012-2013 Esteban Tovagliari, Jupiter Jazz Limited |
9 | // Copyright (c) 2014-2017 Esteban Tovagliari, The appleseedhq Organization |
10 | // |
11 | // Permission is hereby granted, free of charge, to any person obtaining a copy |
12 | // of this software and associated documentation files (the "Software"), to deal |
13 | // in the Software without restriction, including without limitation the rights |
14 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell |
15 | // copies of the Software, and to permit persons to whom the Software is |
16 | // furnished to do so, subject to the following conditions: |
17 | // |
18 | // The above copyright notice and this permission notice shall be included in |
19 | // all copies or substantial portions of the Software. |
20 | // |
21 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
22 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
23 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
24 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
25 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
26 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN |
27 | // THE SOFTWARE. |
28 | // |
29 | |
30 | // appleseed.python headers. |
31 | #include "pyseed.h" // has to be first, to avoid redefinition warnings |
32 | #include "bindentitycontainers.h" |
33 | #include "dict2dict.h" |
34 | |
35 | // appleseed.renderer headers. |
36 | #include "renderer/api/shadergroup.h" |
37 | |
38 | // appleseed.foundation headers. |
39 | #include "foundation/utility/api/specializedapiarrays.h" |
40 | #include "foundation/utility/autoreleaseptr.h" |
41 | #include "foundation/utility/searchpaths.h" |
42 | |
43 | // Standard headers. |
44 | #include <cstddef> |
45 | #include <string> |
46 | |
47 | namespace bpy = boost::python; |
48 | using namespace foundation; |
49 | using namespace renderer; |
50 | using namespace std; |
51 | |
52 | // Work around a regression in Visual Studio 2015 Update 3. |
53 | #if defined(_MSC_VER) && _MSC_VER == 1900 |
54 | namespace boost |
55 | { |
56 | template <> ShaderGroup const volatile* get_pointer<ShaderGroup const volatile>(ShaderGroup const volatile* p) { return p; } |
57 | } |
58 | #endif |
59 | |
60 | namespace |
61 | { |
62 | auto_release_ptr<ShaderGroup> create_shader_group(const string& name) |
63 | { |
64 | return ShaderGroupFactory::create(name.c_str()); |
65 | } |
66 | |
67 | void add_shader( |
68 | ShaderGroup* sg, |
69 | const string& type, |
70 | const string& name, |
71 | const string& layer, |
72 | bpy::dict params) |
73 | { |
74 | sg->add_shader(type.c_str(), name.c_str(), layer.c_str(), bpy_dict_to_param_array(params)); |
75 | } |
76 | |
77 | // A wrapper class that contains a ShaderQuery and a SearchPaths. |
78 | class ShaderQueryWrapper |
79 | : public boost::noncopyable |
80 | { |
81 | public: |
82 | ShaderQueryWrapper() |
83 | { |
84 | m_shader_query = ShaderQueryFactory::create(); |
85 | } |
86 | |
87 | explicit ShaderQueryWrapper(const char* search_path) |
88 | { |
89 | m_shader_query = ShaderQueryFactory::create(search_path); |
90 | } |
91 | |
92 | explicit ShaderQueryWrapper(bpy::list search_paths) |
93 | { |
94 | for (bpy::ssize_t i = 0, e = bpy::len(search_paths); i < e; ++i) |
95 | { |
96 | const bpy::extract<const char*> (search_paths[i]); |
97 | if (extractor.check()) |
98 | m_search_paths.push_back(extractor()); |
99 | else |
100 | { |
101 | PyErr_SetString(PyExc_TypeError, "Incompatible type. Only strings accepted." ); |
102 | bpy::throw_error_already_set(); |
103 | } |
104 | } |
105 | |
106 | m_shader_query = ShaderQueryFactory::create(m_search_paths); |
107 | } |
108 | |
109 | bool open(const char* shader_name) |
110 | { |
111 | return m_shader_query->open(shader_name); |
112 | } |
113 | |
114 | string get_shader_name() const |
115 | { |
116 | return m_shader_query->get_shader_name(); |
117 | } |
118 | |
119 | string get_shader_type() const |
120 | { |
121 | return m_shader_query->get_shader_type(); |
122 | } |
123 | |
124 | size_t get_param_count() const |
125 | { |
126 | return m_shader_query->get_param_count(); |
127 | } |
128 | |
129 | bpy::dict get_param_info(const size_t param_index) const |
130 | { |
131 | return dictionary_to_bpy_dict( |
132 | m_shader_query->get_param_info(param_index)); |
133 | } |
134 | |
135 | bpy::dict get_metadata() const |
136 | { |
137 | return dictionary_to_bpy_dict( |
138 | m_shader_query->get_metadata()); |
139 | } |
140 | |
141 | private: |
142 | SearchPaths m_search_paths; |
143 | auto_release_ptr<ShaderQuery> m_shader_query; |
144 | }; |
145 | } |
146 | |
147 | void bind_shader_group() |
148 | { |
149 | bpy::class_<ShaderGroup, auto_release_ptr<ShaderGroup>, bpy::bases<Entity>, boost::noncopyable>("ShaderGroup" , bpy::no_init) |
150 | .def("__init__" , bpy::make_constructor(create_shader_group)) |
151 | .def("add_shader" , add_shader) |
152 | .def("add_connection" , &ShaderGroup::add_connection) |
153 | .def("clear" , &ShaderGroup::clear) |
154 | ; |
155 | |
156 | bpy::class_<ShaderQueryWrapper, boost::noncopyable>("ShaderQuery" ) |
157 | .def(bpy::init<const char*>()) |
158 | .def(bpy::init<bpy::list>()) |
159 | .def("open" , &ShaderQueryWrapper::open) |
160 | .def("get_shader_name" , &ShaderQueryWrapper::get_shader_name) |
161 | .def("get_shader_type" , &ShaderQueryWrapper::get_shader_type) |
162 | .def("get_num_params" , &ShaderQueryWrapper::get_param_count) |
163 | .def("get_param_info" , &ShaderQueryWrapper::get_param_info) |
164 | .def("get_metadata" , &ShaderQueryWrapper::get_metadata) |
165 | ; |
166 | |
167 | bind_typed_entity_vector<ShaderGroup>("ShaderGroupContainer" ); |
168 | } |
169 | |