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 "dict2dict.h" |
33 | |
34 | // appleseed.renderer headers. |
35 | #include "renderer/api/frame.h" |
36 | #include "renderer/kernel/aov/imagestack.h" |
37 | |
38 | // appleseed.foundation headers. |
39 | #include "foundation/image/image.h" |
40 | #include "foundation/image/tile.h" |
41 | |
42 | namespace bpy = boost::python; |
43 | using namespace foundation; |
44 | using namespace renderer; |
45 | using namespace std; |
46 | |
47 | // Work around a regression in Visual Studio 2015 Update 3. |
48 | #if defined(_MSC_VER) && _MSC_VER == 1900 |
49 | namespace boost |
50 | { |
51 | template <> Image const volatile* get_pointer<Image const volatile>(Image const volatile* p) { return p; } |
52 | template <> Frame const volatile* get_pointer<Frame const volatile>(Frame const volatile* p) { return p; } |
53 | } |
54 | #endif |
55 | |
56 | namespace |
57 | { |
58 | auto_release_ptr<Frame> create_frame( |
59 | const string& name, |
60 | const bpy::dict& params) |
61 | { |
62 | return FrameFactory::create(name.c_str(), bpy_dict_to_param_array(params)); |
63 | } |
64 | |
65 | void transform_tile_to_output_color_space(const Frame* frame, Tile* tile) |
66 | { |
67 | frame->transform_to_output_color_space(*tile); |
68 | } |
69 | |
70 | void transform_image_to_output_color_space(const Frame* frame, Image* image) |
71 | { |
72 | frame->transform_to_output_color_space(*image); |
73 | } |
74 | |
75 | bpy::object archive_frame(const Frame* frame, const char* directory) |
76 | { |
77 | char* output = 0; |
78 | |
79 | if (frame->archive(directory, &output)) |
80 | { |
81 | const bpy::str path(output); |
82 | foundation::free_string(output); |
83 | return path; |
84 | } |
85 | |
86 | // Return None. |
87 | return bpy::object(); |
88 | } |
89 | |
90 | void copy_item_from_list( |
91 | const bpy::list& l, |
92 | const size_t index, |
93 | size_t& dst) |
94 | { |
95 | bpy::extract<size_t> ex(l[index]); |
96 | if (!ex.check()) |
97 | { |
98 | PyErr_SetString(PyExc_TypeError, "Incompatible type." ); |
99 | bpy::throw_error_already_set(); |
100 | } |
101 | |
102 | dst = ex(); |
103 | } |
104 | |
105 | void set_crop_window(Frame* frame, const bpy::list& window) |
106 | { |
107 | if (bpy::len(window) != 4) |
108 | { |
109 | PyErr_SetString(PyExc_RuntimeError, "Invalid list length given to appleseed.Frame.set_crop_window" ); |
110 | bpy::throw_error_already_set(); |
111 | } |
112 | |
113 | AABB2u crop; |
114 | copy_item_from_list(window, 0, crop.min[0]); |
115 | copy_item_from_list(window, 1, crop.min[1]); |
116 | copy_item_from_list(window, 2, crop.max[0]); |
117 | copy_item_from_list(window, 3, crop.max[1]); |
118 | frame->set_crop_window(crop); |
119 | } |
120 | |
121 | bpy::list get_crop_window(const Frame* frame) |
122 | { |
123 | AABB2u window = frame->get_crop_window(); |
124 | bpy::list result; |
125 | result.append(window.min[0]); |
126 | result.append(window.min[1]); |
127 | result.append(window.max[0]); |
128 | result.append(window.max[1]); |
129 | return result; |
130 | } |
131 | } |
132 | |
133 | void bind_frame() |
134 | { |
135 | bpy::class_<Frame, auto_release_ptr<Frame>, bpy::bases<Entity>, boost::noncopyable>("Frame" , bpy::no_init) |
136 | .def("__init__" , bpy::make_constructor(create_frame)) |
137 | |
138 | .def("reset_crop_window" , &Frame::reset_crop_window) |
139 | .def("has_crop_window" , &Frame::has_crop_window) |
140 | .def("set_crop_window" , set_crop_window) |
141 | .def("get_crop_window" , get_crop_window) |
142 | |
143 | .def("image" , &Frame::image, bpy::return_value_policy<bpy::reference_existing_object>()) |
144 | .def("aov_images" , &Frame::aov_images, bpy::return_value_policy<bpy::reference_existing_object>()) |
145 | |
146 | .def("transform_tile_to_output_color_space" , transform_tile_to_output_color_space) |
147 | .def("transform_image_to_output_color_space" , transform_image_to_output_color_space) |
148 | |
149 | .def("clear_main_image" , &Frame::clear_main_image) |
150 | .def("write_main_image" , &Frame::write_main_image) |
151 | .def("write_aov_images" , &Frame::write_aov_images) |
152 | .def("archive" , archive_frame) |
153 | ; |
154 | } |
155 | |