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 "unalignedtransform.h"
33
34// appleseed.renderer headers.
35#include "renderer/utility/transformsequence.h"
36
37// appleseed.foundation headers.
38#include "foundation/utility/iostreamop.h"
39
40// Standard headers.
41#include <cstddef>
42
43namespace bpy = boost::python;
44using namespace foundation;
45using namespace renderer;
46
47namespace
48{
49 void bind_typed_transform_extra(bpy::class_<UnalignedTransformf>& X)
50 {
51 X.def(bpy::init<const UnalignedTransformd&>());
52 }
53
54 void bind_typed_transform_extra(bpy::class_<UnalignedTransformd>& X)
55 {
56 X.def(bpy::init<const UnalignedTransformf&>());
57 }
58
59 template <typename T>
60 void bind_typed_transform(const char* class_name)
61 {
62 bpy::class_<UnalignedTransform<T> > X(class_name);
63 X.def(bpy::init<const UnalignedMatrix44<T>&>())
64 .def(bpy::init<const UnalignedMatrix44<T>&>())
65 .def(bpy::init<const UnalignedMatrix44<T>&, const UnalignedMatrix44<T>&>())
66
67 .def("identity", &UnalignedTransform<T>::identity).staticmethod("identity")
68
69 .def("get_local_to_parent", &UnalignedTransform<T>::get_local_to_parent, bpy::return_value_policy<bpy::copy_const_reference>())
70 .def("get_parent_to_local", &UnalignedTransform<T>::get_parent_to_local, bpy::return_value_policy<bpy::copy_const_reference>())
71
72 .def(bpy::self * bpy::self)
73
74 .def("point_to_local", &UnalignedTransform<T>::point_to_local)
75 .def("point_to_parent", &UnalignedTransform<T>::point_to_parent)
76 .def("vector_to_local", &UnalignedTransform<T>::vector_to_local)
77 .def("vector_to_parent", &UnalignedTransform<T>::vector_to_parent)
78 .def("normal_to_local" , &UnalignedTransform<T>::normal_to_local)
79 .def("normal_to_parent", &UnalignedTransform<T>::normal_to_parent)
80
81 // Because of a bug in Boost.Python, this needs the extra self_ns qualification.
82 .def(bpy::self_ns::str(bpy::self))
83 .def(bpy::self_ns::repr(bpy::self))
84 ;
85
86 bind_typed_transform_extra(X);
87 }
88
89 void transform_seq_set_transform(
90 TransformSequence* seq,
91 const float time,
92 const UnalignedTransformd& transform)
93 {
94 const Transformd xform(
95 transform.get_local_to_parent().as_foundation_matrix(),
96 transform.get_parent_to_local().as_foundation_matrix());
97
98 seq->set_transform(time, xform);
99 }
100
101 bpy::tuple transform_seq_get_transform(
102 const TransformSequence* seq,
103 const size_t index)
104 {
105 float time;
106 Transformd xform;
107 seq->get_transform(index, time, xform);
108 return bpy::make_tuple(time, UnalignedTransformd(xform));
109 }
110
111 bpy::list transform_seq_as_list(const TransformSequence* seq)
112 {
113 bpy::list result;
114
115 for (size_t i = 0, e = seq->size(); i < e; ++i)
116 {
117 float time;
118 Transformd xform;
119 seq->get_transform(i, time, xform);
120 bpy::tuple t = bpy::make_tuple(time, UnalignedTransformd(xform));
121 result.append(t);
122 }
123
124 return result;
125 }
126
127 UnalignedTransformd transform_seq_get_earliest(const TransformSequence* seq)
128 {
129 const Transformd xform(seq->get_earliest_transform());
130 return UnalignedTransformd(xform);
131 }
132}
133
134void bind_transform()
135{
136 bind_typed_transform<float>("Transformf");
137 bind_typed_transform<double>("Transformd");
138
139 bpy::class_<TransformSequence>("TransformSequence")
140 .def(bpy::init<>())
141 .def("set_transform", &transform_seq_set_transform)
142 .def("get_transform", &transform_seq_get_transform)
143 .def("get_earliest_transform", &transform_seq_get_earliest)
144
145 .def("empty", &TransformSequence::empty)
146 .def("size", &TransformSequence::size)
147 .def("clear", &TransformSequence::clear)
148
149 .def("transforms", &transform_seq_as_list)
150
151 .def(bpy::self * bpy::self)
152 ;
153}
154