8b803835b62771767fc72a5c09413990b82b0209
[blender-staging.git] / intern / cycles / blender / blender_geometry.cpp
1
2 /*
3  * Copyright 2011-2013 Blender Foundation
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */
17
18 #include "render/curves.h"
19 #include "render/hair.h"
20 #include "render/mesh.h"
21 #include "render/object.h"
22
23 #include "blender/blender_sync.h"
24 #include "blender/blender_util.h"
25
26 CCL_NAMESPACE_BEGIN
27
28 Geometry *BlenderSync::sync_geometry(BL::Depsgraph &b_depsgraph,
29                                      BL::Object &b_ob,
30                                      BL::Object &b_ob_instance,
31                                      bool object_updated,
32                                      bool use_particle_hair)
33 {
34   /* Test if we can instance or if the object is modified. */
35   BL::ID b_ob_data = b_ob.data();
36   BL::ID b_key_id = (BKE_object_is_modified(b_ob)) ? b_ob_instance : b_ob_data;
37   GeometryKey key(b_key_id.ptr.data, use_particle_hair);
38   BL::Material material_override = view_layer.material_override;
39   Shader *default_shader = scene->default_surface;
40   Geometry::Type geom_type = (use_particle_hair &&
41                               (scene->curve_system_manager->primitive != CURVE_TRIANGLES)) ?
42                                  Geometry::HAIR :
43                                  Geometry::MESH;
44
45   /* Find shader indices. */
46   vector<Shader *> used_shaders;
47
48   BL::Object::material_slots_iterator slot;
49   for (b_ob.material_slots.begin(slot); slot != b_ob.material_slots.end(); ++slot) {
50     if (material_override) {
51       find_shader(material_override, used_shaders, default_shader);
52     }
53     else {
54       BL::ID b_material(slot->material());
55       find_shader(b_material, used_shaders, default_shader);
56     }
57   }
58
59   if (used_shaders.size() == 0) {
60     if (material_override)
61       find_shader(material_override, used_shaders, default_shader);
62     else
63       used_shaders.push_back(default_shader);
64   }
65
66   /* Test if we need to sync. */
67   Geometry *geom = geometry_map.find(key);
68   bool sync = true;
69   if (geom == NULL) {
70     /* Add new geometry if it did not exist yet. */
71     if (geom_type == Geometry::HAIR) {
72       geom = new Hair();
73     }
74     else {
75       geom = new Mesh();
76     }
77     geometry_map.add(key, geom);
78   }
79   else {
80     /* Test if we need to update existing geometry. */
81     sync = geometry_map.update(geom, b_key_id);
82   }
83
84   if (!sync) {
85     /* If transform was applied to geometry, need full update. */
86     if (object_updated && geom->transform_applied) {
87       ;
88     }
89     /* Test if shaders changed, these can be object level so geometry
90      * does not get tagged for recalc. */
91     else if (geom->used_shaders != used_shaders) {
92       ;
93     }
94     else {
95       /* Even if not tagged for recalc, we may need to sync anyway
96        * because the shader needs different geometry attributes. */
97       bool attribute_recalc = false;
98
99       foreach (Shader *shader, geom->used_shaders) {
100         if (shader->need_update_geometry) {
101           attribute_recalc = true;
102         }
103       }
104
105       if (!attribute_recalc) {
106         return geom;
107       }
108     }
109   }
110
111   /* Ensure we only sync instanced geometry once. */
112   if (geometry_synced.find(geom) != geometry_synced.end()) {
113     return geom;
114   }
115
116   progress.set_sync_status("Synchronizing object", b_ob.name());
117
118   geometry_synced.insert(geom);
119
120   geom->clear();
121   geom->used_shaders = used_shaders;
122   geom->name = ustring(b_ob_data.name().c_str());
123
124   if (use_particle_hair) {
125     sync_hair(b_depsgraph, b_ob, geom);
126   }
127   else if (object_fluid_gas_domain_find(b_ob)) {
128     Mesh *mesh = static_cast<Mesh *>(geom);
129     sync_volume(b_ob, mesh);
130   }
131   else {
132     Mesh *mesh = static_cast<Mesh *>(geom);
133     sync_mesh(b_depsgraph, b_ob, mesh);
134   }
135
136   return geom;
137 }
138
139 void BlenderSync::sync_geometry_motion(BL::Depsgraph &b_depsgraph,
140                                        BL::Object &b_ob,
141                                        Object *object,
142                                        float motion_time,
143                                        bool use_particle_hair)
144 {
145   /* Ensure we only sync instanced geometry once. */
146   Geometry *geom = object->geometry;
147
148   if (geometry_motion_synced.find(geom) != geometry_motion_synced.end())
149     return;
150
151   geometry_motion_synced.insert(geom);
152
153   /* Ensure we only motion sync geometry that also had geometry synced, to avoid
154    * unnecessary work and to ensure that its attributes were clear. */
155   if (geometry_synced.find(geom) == geometry_synced.end())
156     return;
157
158   /* Find time matching motion step required by geometry. */
159   int motion_step = geom->motion_step(motion_time);
160   if (motion_step < 0) {
161     return;
162   }
163
164   if (use_particle_hair) {
165     sync_hair_motion(b_depsgraph, b_ob, geom, motion_step);
166   }
167   else if (object_fluid_gas_domain_find(b_ob)) {
168     /* No volume motion blur support yet. */
169   }
170   else {
171     Mesh *mesh = static_cast<Mesh *>(geom);
172     sync_mesh_motion(b_depsgraph, b_ob, mesh, motion_step);
173   }
174 }
175
176 CCL_NAMESPACE_END