Fix T74095: crash deleting all faces in edit mode with Cycles rendering
[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->name = ustring(b_ob_data.name().c_str());
121
122   if (use_particle_hair) {
123     sync_hair(b_depsgraph, b_ob, geom, used_shaders);
124   }
125   else if (object_fluid_gas_domain_find(b_ob)) {
126     Mesh *mesh = static_cast<Mesh *>(geom);
127     sync_volume(b_ob, mesh, used_shaders);
128   }
129   else {
130     Mesh *mesh = static_cast<Mesh *>(geom);
131     sync_mesh(b_depsgraph, b_ob, mesh, used_shaders);
132   }
133
134   return geom;
135 }
136
137 void BlenderSync::sync_geometry_motion(BL::Depsgraph &b_depsgraph,
138                                        BL::Object &b_ob,
139                                        Object *object,
140                                        float motion_time,
141                                        bool use_particle_hair)
142 {
143   /* Ensure we only sync instanced geometry once. */
144   Geometry *geom = object->geometry;
145
146   if (geometry_motion_synced.find(geom) != geometry_motion_synced.end())
147     return;
148
149   geometry_motion_synced.insert(geom);
150
151   /* Ensure we only motion sync geometry that also had geometry synced, to avoid
152    * unnecessary work and to ensure that its attributes were clear. */
153   if (geometry_synced.find(geom) == geometry_synced.end())
154     return;
155
156   /* Find time matching motion step required by geometry. */
157   int motion_step = geom->motion_step(motion_time);
158   if (motion_step < 0) {
159     return;
160   }
161
162   if (use_particle_hair) {
163     sync_hair_motion(b_depsgraph, b_ob, geom, motion_step);
164   }
165   else if (object_fluid_gas_domain_find(b_ob)) {
166     /* No volume motion blur support yet. */
167   }
168   else {
169     Mesh *mesh = static_cast<Mesh *>(geom);
170     sync_mesh_motion(b_depsgraph, b_ob, mesh, motion_step);
171   }
172 }
173
174 CCL_NAMESPACE_END