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/scene/assembly.h"
37#include "renderer/modeling/scene/assemblyfactoryregistrar.h"
38#include "renderer/modeling/scene/assemblyinstance.h"
39#include "renderer/modeling/scene/iassemblyfactory.h"
40
41// Standard headers.
42#include <string>
43
44namespace bpy = boost::python;
45using namespace foundation;
46using namespace renderer;
47using namespace std;
48
49// Work around a regression in Visual Studio 2015 Update 3.
50#if defined(_MSC_VER) && _MSC_VER == 1900
51namespace boost
52{
53 template <> Assembly const volatile* get_pointer<Assembly const volatile>(Assembly const volatile* p) { return p; }
54 template <> AssemblyInstance const volatile* get_pointer<AssemblyInstance const volatile>(AssemblyInstance const volatile* p) { return p; }
55}
56#endif
57
58namespace
59{
60 auto_release_ptr<Assembly> create_assembly(const string& name)
61 {
62 return AssemblyFactory().create(name.c_str(), ParamArray());
63 }
64
65 auto_release_ptr<Assembly> create_assembly_with_params(
66 const string& name,
67 const bpy::dict& params)
68 {
69 return AssemblyFactory().create(name.c_str(), bpy_dict_to_param_array(params));
70 }
71
72 auto_release_ptr<Assembly> create_assembly_with_model_and_params(
73 const string& model,
74 const string& name,
75 const bpy::dict& params)
76 {
77 AssemblyFactoryRegistrar factories;
78 const IAssemblyFactory* factory = factories.lookup(model.c_str());
79
80 if (factory)
81 return factory->create(name.c_str(), bpy_dict_to_param_array(params));
82 else
83 {
84 PyErr_SetString(PyExc_RuntimeError, "Assembly model not found");
85 bpy::throw_error_already_set();
86 }
87
88 return auto_release_ptr<Assembly>();
89 }
90
91 auto_release_ptr<AssemblyInstance> create_assembly_instance(
92 const string& name,
93 const bpy::dict& params,
94 const string& assembly_name)
95 {
96 return
97 AssemblyInstanceFactory::create(
98 name.c_str(),
99 bpy_dict_to_param_array(params),
100 assembly_name.c_str());
101 }
102
103 TransformSequence& get_transform_sequence(AssemblyInstance* instance)
104 {
105 return instance->transform_sequence();
106 }
107
108 string get_assembly_name(AssemblyInstance* instance)
109 {
110 return instance->get_assembly_name();
111 }
112}
113
114void bind_assembly()
115{
116 bpy::class_<BaseGroup, boost::noncopyable>("BaseGroup")
117 .def("colors", &BaseGroup::colors, bpy::return_value_policy<bpy::reference_existing_object>())
118 .def("textures", &BaseGroup::textures, bpy::return_value_policy<bpy::reference_existing_object>())
119 .def("texture_instances", &BaseGroup::texture_instances, bpy::return_value_policy<bpy::reference_existing_object>())
120 .def("shader_groups", &BaseGroup::shader_groups, bpy::return_value_policy<bpy::reference_existing_object>())
121 .def("assemblies", &BaseGroup::assemblies, bpy::return_value_policy<bpy::reference_existing_object>())
122 .def("assembly_instances", &BaseGroup::assembly_instances, bpy::return_value_policy<bpy::reference_existing_object>())
123 ;
124
125 bpy::class_<Assembly, auto_release_ptr<Assembly>, bpy::bases<Entity, BaseGroup>, boost::noncopyable>("Assembly", bpy::no_init)
126 .def("__init__", bpy::make_constructor(create_assembly))
127 .def("__init__", bpy::make_constructor(create_assembly_with_params))
128 .def("__init__", bpy::make_constructor(create_assembly_with_model_and_params))
129 .def("bsdfs", &Assembly::bsdfs, bpy::return_value_policy<bpy::reference_existing_object>())
130 .def("edfs", &Assembly::edfs, bpy::return_value_policy<bpy::reference_existing_object>())
131 .def("surface_shaders", &Assembly::surface_shaders, bpy::return_value_policy<bpy::reference_existing_object>())
132 .def("materials", &Assembly::materials, bpy::return_value_policy<bpy::reference_existing_object>())
133 .def("lights", &Assembly::lights, bpy::return_value_policy<bpy::reference_existing_object>())
134 .def("objects", &Assembly::objects, bpy::return_value_policy<bpy::reference_existing_object>())
135 .def("object_instances", &Assembly::object_instances, bpy::return_value_policy<bpy::reference_existing_object>())
136 .def("compute_local_bbox", &Assembly::compute_local_bbox)
137 .def("compute_non_hierarchical_local_bbox", &Assembly::compute_local_bbox)
138 ;
139
140 bind_typed_entity_map<Assembly>("AssemblyContainer");
141
142 bpy::class_<AssemblyInstance, auto_release_ptr<AssemblyInstance>, bpy::bases<Entity>, boost::noncopyable>("AssemblyInstance", bpy::no_init)
143 .def("__init__", bpy::make_constructor(create_assembly_instance))
144 .def("transform_sequence", get_transform_sequence, bpy::return_value_policy<bpy::reference_existing_object>())
145 .def("get_vis_flags", &AssemblyInstance::get_vis_flags)
146 .def("compute_parent_bbox", &AssemblyInstance::compute_parent_bbox)
147 .def("get_assembly_name", &get_assembly_name)
148 .def("find_assembly", &AssemblyInstance::find_assembly, bpy::return_value_policy<bpy::reference_existing_object>())
149 ;
150
151 bind_typed_entity_map<AssemblyInstance>("AssemblyInstanceContainer");
152}
153