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/modeling/color/colorentity.h"
37
38// appleseed.foundation headers.
39#include "foundation/image/colorspace.h"
40#include "foundation/utility/api/specializedapiarrays.h"
41
42// Standard headers.
43#include <cstddef>
44#include <string>
45
46namespace bpy = boost::python;
47using namespace foundation;
48using namespace renderer;
49
50// Work around a regression in Visual Studio 2015 Update 3.
51#if defined(_MSC_VER) && _MSC_VER == 1900
52namespace boost
53{
54 template <> ColorEntity const volatile* get_pointer<ColorEntity const volatile>(ColorEntity const volatile* p) { return p; }
55}
56#endif
57
58namespace
59{
60 ColorValueArray color_value_array_from_bpy_list(const bpy::list& vals)
61 {
62 ColorValueArray result;
63
64 ssize_t size = bpy::len(vals);
65 result.reserve(size);
66
67 for (ssize_t i = 0; i < size; ++i)
68 {
69 bpy::extract<float> ex(vals[i]);
70 if (ex.check())
71 result.push_back(ex());
72 else
73 {
74 PyErr_SetString(PyExc_TypeError, "Incompatible type, only float is allowed.");
75 bpy::throw_error_already_set();
76 }
77 }
78
79 return result;
80 }
81
82 bpy::list bpy_list_from_color_value_array(const ColorValueArray& vals)
83 {
84 bpy::list result;
85
86 for (size_t i = 0, e = vals.size(); i < e; ++i)
87 result.append(vals[i]);
88
89 return result;
90 }
91
92 auto_release_ptr<ColorEntity> create_color_entity(
93 const std::string& name,
94 const bpy::dict& params)
95 {
96 return ColorEntityFactory::create(name.c_str(), bpy_dict_to_param_array(params));
97 }
98
99 auto_release_ptr<ColorEntity> create_color_entity_vals(
100 const std::string& name,
101 const bpy::dict& params,
102 const bpy::list& values)
103 {
104 return
105 ColorEntityFactory::create(
106 name.c_str(),
107 bpy_dict_to_param_array(params),
108 color_value_array_from_bpy_list(values));
109 }
110
111 auto_release_ptr<ColorEntity> create_color_entity_vals_alpha(
112 const std::string& name,
113 const bpy::dict& params,
114 const bpy::list& values,
115 const bpy::list& alpha)
116 {
117 return
118 ColorEntityFactory::create(
119 name.c_str(),
120 bpy_dict_to_param_array(params),
121 color_value_array_from_bpy_list(values),
122 color_value_array_from_bpy_list(alpha));
123 }
124
125 bpy::list color_entity_get_vals(const ColorEntity* color)
126 {
127 return bpy_list_from_color_value_array(color->get_values());
128 }
129
130 bpy::list color_entity_get_alpha(const ColorEntity* color)
131 {
132 return bpy_list_from_color_value_array(color->get_alpha());
133 }
134}
135
136void bind_color()
137{
138 bpy::enum_<ColorSpace>("ColorSpace")
139 .value("LinearRGB", ColorSpaceLinearRGB)
140 .value("SRGB", ColorSpaceSRGB)
141 .value("CIEXYZ", ColorSpaceCIEXYZ)
142 .value("Spectral", ColorSpaceSpectral)
143 ;
144
145 bpy::class_<ColorEntity, auto_release_ptr<ColorEntity>, bpy::bases<Entity>, boost::noncopyable>("ColorEntity", bpy::no_init)
146 .def("__init__", bpy::make_constructor(create_color_entity))
147 .def("__init__", bpy::make_constructor(create_color_entity_vals))
148 .def("__init__", bpy::make_constructor(create_color_entity_vals_alpha))
149 .def("get_values", color_entity_get_vals)
150 .def("get_alpha", color_entity_get_alpha)
151 .def("get_color_space", &ColorEntity::get_color_space)
152 .def("get_wavelength_range", &ColorEntity::get_wavelength_range, bpy::return_value_policy<bpy::copy_const_reference>())
153 .def("get_multiplier", &ColorEntity::get_multiplier)
154 ;
155
156 bind_typed_entity_vector<ColorEntity>("ColorContainer");
157}
158