Cycles: svn merge -r39457:39669 https://svn.blender.org/svnroot/bf-blender/trunk...
[blender.git] / intern / cycles / blender / blender_object.cpp
1 /*
2  * Copyright 2011, Blender Foundation.
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License
6  * as published by the Free Software Foundation; either version 2
7  * of the License, or (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software Foundation,
16  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17  */
18
19 #include "light.h"
20 #include "mesh.h"
21 #include "object.h"
22 #include "scene.h"
23
24 #include "blender_sync.h"
25 #include "blender_util.h"
26
27 #include "util_foreach.h"
28
29 CCL_NAMESPACE_BEGIN
30
31 /* Utilities */
32
33 bool BlenderSync::object_is_modified(BL::Object b_ob)
34 {
35         /* test if we can instance or if the object is modified */
36         if(ccl::object_is_modified(b_ob, b_scene, preview)) {
37                 /* modifiers */
38                 return true;
39         }
40         else {
41                 /* object level material links */
42                 BL::Object::material_slots_iterator slot;
43                 for(b_ob.material_slots.begin(slot); slot != b_ob.material_slots.end(); ++slot)
44                         if(slot->link() == BL::MaterialSlot::link_OBJECT)
45                                 return true;
46         }
47
48         return false;
49 }
50
51 bool BlenderSync::object_is_mesh(BL::Object b_ob)
52 {
53         BL::ID b_ob_data = b_ob.data();
54
55         return (b_ob_data && (b_ob_data.is_a(&RNA_Mesh) ||
56                 b_ob_data.is_a(&RNA_Curve) || b_ob_data.is_a(&RNA_MetaBall)));
57 }
58
59 bool BlenderSync::object_is_light(BL::Object b_ob)
60 {
61         BL::ID b_ob_data = b_ob.data();
62
63         return (b_ob_data && b_ob_data.is_a(&RNA_Lamp));
64 }
65
66 /* Light */
67
68 void BlenderSync::sync_light(BL::Object b_parent, int b_index, BL::Object b_ob, Transform& tfm)
69 {
70         /* test if we need to sync */
71         Light *light;
72         ObjectKey key(b_parent, b_index, b_ob);
73
74         if(!light_map.sync(&light, b_ob, b_parent, key))
75                 return;
76
77         /* location */
78         light->co = make_float3(tfm.x.w, tfm.y.w, tfm.z.w);
79
80         /* shader */
81         BL::Lamp b_lamp(b_ob.data());
82         vector<uint> used_shaders;
83
84         find_shader(b_lamp, used_shaders);
85
86         if(used_shaders.size() == 0)
87                 used_shaders.push_back(scene->default_light);
88
89         light->shader = used_shaders[0];
90
91         /* tag */
92         light->tag_update(scene);
93 }
94
95 /* Object */
96
97 void BlenderSync::sync_object(BL::Object b_parent, int b_index, BL::Object b_ob, Transform& tfm)
98 {
99         /* light is handled separately */
100         if(object_is_light(b_ob)) {
101                 sync_light(b_parent, b_index, b_ob, tfm);
102                 return;
103         }
104
105         /* only interested in object that we can create meshes from */
106         if(!object_is_mesh(b_ob))
107                 return;
108
109         /* test if we need to sync */
110         ObjectKey key(b_parent, b_index, b_ob);
111         Object *object;
112         bool object_updated = false;
113
114         /* object sync */
115         if(object_map.sync(&object, b_ob, b_parent, key)) {
116                 object->name = b_ob.name();
117                 object->tfm = tfm;
118                 object->tag_update(scene);
119                 object_updated = true;
120         }
121
122         /* mesh sync */
123         object->mesh = sync_mesh(b_ob, object_updated);
124 }
125
126 /* Object Loop */
127
128 void BlenderSync::sync_objects(BL::SpaceView3D b_v3d)
129 {
130         /* layer data */
131         uint layer;
132         
133         if(b_v3d)
134                 layer = get_layer(b_v3d.layers());
135         else
136                 layer = get_layer(b_scene.layers());
137         
138         /* prepare for sync */
139         light_map.pre_sync();
140         mesh_map.pre_sync();
141         object_map.pre_sync();
142         mesh_synced.clear();
143
144         /* object loop */
145         BL::Scene::objects_iterator b_ob;
146
147         for(b_scene.objects.begin(b_ob); b_ob != b_scene.objects.end(); ++b_ob) {
148                 bool hide = (b_v3d)? b_ob->hide(): b_ob->hide_render();
149
150                 if(!hide && get_layer(b_ob->layers()) & layer) {
151                         if(b_ob->is_duplicator()) {
152                                 /* dupli objects */
153                                 object_create_duplilist(*b_ob, b_scene);
154
155                                 BL::Object::dupli_list_iterator b_dup;
156                                 int b_index = 0;
157
158                                 for(b_ob->dupli_list.begin(b_dup); b_dup != b_ob->dupli_list.end(); ++b_dup) {
159                                         Transform tfm = get_transform(b_dup->matrix());
160                                         sync_object(*b_ob, b_index, b_dup->object(), tfm);
161                                         b_index++;
162                                 }
163
164                                 object_free_duplilist(*b_ob);
165                         }
166                         else {
167                                 /* object itself */
168                                 Transform tfm = get_transform(b_ob->matrix_world());
169                                 sync_object(*b_ob, 0, *b_ob, tfm);
170                         }
171                 }
172         }
173
174         /* handle removed data and modified pointers */
175         if(light_map.post_sync())
176                 scene->light_manager->tag_update(scene);
177         if(mesh_map.post_sync())
178                 scene->mesh_manager->tag_update(scene);
179         if(object_map.post_sync())
180                 scene->object_manager->tag_update(scene);
181         mesh_synced.clear();
182 }
183
184 CCL_NAMESPACE_END
185