diff options
author | Brecht Van Lommel <brechtvanlommel@gmail.com> | 2020-02-02 14:04:19 +0300 |
---|---|---|
committer | Brecht Van Lommel <brechtvanlommel@gmail.com> | 2020-02-07 14:18:15 +0300 |
commit | d9c5f0d25fc91b069158ae1ab4fddc21bfd85846 (patch) | |
tree | 18f55163c5b06385d055d5a79a4c653d3da6e595 /intern/cycles/blender | |
parent | 46c9872afaa8053f8b2894c038402b1beb3ac66c (diff) |
Cleanup: split Cycles Hair and Mesh classes, with Geometry base class
Diffstat (limited to 'intern/cycles/blender')
-rw-r--r-- | intern/cycles/blender/blender_curves.cpp | 242 | ||||
-rw-r--r-- | intern/cycles/blender/blender_geometry.cpp | 100 | ||||
-rw-r--r-- | intern/cycles/blender/blender_id_map.h | 56 | ||||
-rw-r--r-- | intern/cycles/blender/blender_light.cpp | 6 | ||||
-rw-r--r-- | intern/cycles/blender/blender_mesh.cpp | 14 | ||||
-rw-r--r-- | intern/cycles/blender/blender_object.cpp | 33 | ||||
-rw-r--r-- | intern/cycles/blender/blender_particles.cpp | 6 | ||||
-rw-r--r-- | intern/cycles/blender/blender_session.cpp | 7 | ||||
-rw-r--r-- | intern/cycles/blender/blender_shader.cpp | 4 | ||||
-rw-r--r-- | intern/cycles/blender/blender_sync.cpp | 25 | ||||
-rw-r--r-- | intern/cycles/blender/blender_sync.h | 26 |
11 files changed, 294 insertions, 225 deletions
diff --git a/intern/cycles/blender/blender_curves.cpp b/intern/cycles/blender/blender_curves.cpp index e42151d8f48..affd5685337 100644 --- a/intern/cycles/blender/blender_curves.cpp +++ b/intern/cycles/blender/blender_curves.cpp @@ -17,6 +17,7 @@ #include "render/attribute.h" #include "render/camera.h" #include "render/curves.h" +#include "render/hair.h" #include "render/mesh.h" #include "render/object.h" #include "render/scene.h" @@ -107,12 +108,12 @@ static void InterpolateKeySegments( } static bool ObtainCacheParticleData( - Mesh *mesh, BL::Mesh *b_mesh, BL::Object *b_ob, ParticleCurveData *CData, bool background) + Geometry *geom, BL::Mesh *b_mesh, BL::Object *b_ob, ParticleCurveData *CData, bool background) { int curvenum = 0; int keyno = 0; - if (!(mesh && b_mesh && b_ob && CData)) + if (!(geom && b_mesh && b_ob && CData)) return false; Transform tfm = get_transform(b_ob->matrix_world()); @@ -128,7 +129,7 @@ static bool ObtainCacheParticleData( if ((b_part.render_type() == BL::ParticleSettings::render_type_PATH) && (b_part.type() == BL::ParticleSettings::type_HAIR)) { - int shader = clamp(b_part.material() - 1, 0, mesh->used_shaders.size() - 1); + int shader = clamp(b_part.material() - 1, 0, geom->used_shaders.size() - 1); int display_step = background ? b_part.render_step() : b_part.display_step(); int totparts = b_psys.particles.length(); int totchild = background ? b_psys.child_particles.length() : @@ -202,14 +203,14 @@ static bool ObtainCacheParticleData( return true; } -static bool ObtainCacheParticleUV(Mesh *mesh, +static bool ObtainCacheParticleUV(Geometry *geom, BL::Mesh *b_mesh, BL::Object *b_ob, ParticleCurveData *CData, bool background, int uv_num) { - if (!(mesh && b_mesh && b_ob && CData)) + if (!(geom && b_mesh && b_ob && CData)) return false; CData->curve_uv.clear(); @@ -265,14 +266,14 @@ static bool ObtainCacheParticleUV(Mesh *mesh, return true; } -static bool ObtainCacheParticleVcol(Mesh *mesh, +static bool ObtainCacheParticleVcol(Geometry *geom, BL::Mesh *b_mesh, BL::Object *b_ob, ParticleCurveData *CData, bool background, int vcol_num) { - if (!(mesh && b_mesh && b_ob && CData)) + if (!(geom && b_mesh && b_ob && CData)) return false; CData->curve_vcol.clear(); @@ -594,21 +595,55 @@ static void ExportCurveTriangleGeometry(Mesh *mesh, ParticleCurveData *CData, in /* texture coords still needed */ } -static void ExportCurveSegments(Scene *scene, Mesh *mesh, ParticleCurveData *CData) +static void export_hair_motion_validate_attribute(Hair *hair, + int motion_step, + int num_motion_keys, + bool have_motion) +{ + Attribute *attr_mP = hair->attributes.find(ATTR_STD_MOTION_VERTEX_POSITION); + const int num_keys = hair->curve_keys.size(); + + if (num_motion_keys != num_keys || !have_motion) { + /* No motion or hair "topology" changed, remove attributes again. */ + if (num_motion_keys != num_keys) { + VLOG(1) << "Hair topology changed, removing attribute."; + } + else { + VLOG(1) << "No motion, removing attribute."; + } + hair->attributes.remove(ATTR_STD_MOTION_VERTEX_POSITION); + } + else if (motion_step > 0) { + VLOG(1) << "Filling in new motion vertex position for motion_step " << motion_step; + + /* Motion, fill up previous steps that we might have skipped because + * they had no motion, but we need them anyway now. */ + for (int step = 0; step < motion_step; step++) { + float4 *mP = attr_mP->data_float4() + step * num_keys; + + for (int key = 0; key < num_keys; key++) { + mP[key] = float3_to_float4(hair->curve_keys[key]); + mP[key].w = hair->curve_radius[key]; + } + } + } +} + +static void ExportCurveSegments(Scene *scene, Hair *hair, ParticleCurveData *CData) { int num_keys = 0; int num_curves = 0; - if (mesh->num_curves()) + if (hair->num_curves()) return; Attribute *attr_intercept = NULL; Attribute *attr_random = NULL; - if (mesh->need_attribute(scene, ATTR_STD_CURVE_INTERCEPT)) - attr_intercept = mesh->curve_attributes.add(ATTR_STD_CURVE_INTERCEPT); - if (mesh->need_attribute(scene, ATTR_STD_CURVE_RANDOM)) - attr_random = mesh->curve_attributes.add(ATTR_STD_CURVE_RANDOM); + if (hair->need_attribute(scene, ATTR_STD_CURVE_INTERCEPT)) + attr_intercept = hair->attributes.add(ATTR_STD_CURVE_INTERCEPT); + if (hair->need_attribute(scene, ATTR_STD_CURVE_RANDOM)) + attr_random = hair->attributes.add(ATTR_STD_CURVE_RANDOM); /* compute and reserve size of arrays */ for (int sys = 0; sys < CData->psys_firstcurve.size(); sys++) { @@ -621,10 +656,10 @@ static void ExportCurveSegments(Scene *scene, Mesh *mesh, ParticleCurveData *CDa } if (num_curves > 0) { - VLOG(1) << "Exporting curve segments for mesh " << mesh->name; + VLOG(1) << "Exporting curve segments for mesh " << hair->name; } - mesh->reserve_curves(mesh->num_curves() + num_curves, mesh->curve_keys.size() + num_keys); + hair->reserve_curves(hair->num_curves() + num_curves, hair->curve_keys.size() + num_keys); num_keys = 0; num_curves = 0; @@ -649,7 +684,7 @@ static void ExportCurveSegments(Scene *scene, Mesh *mesh, ParticleCurveData *CDa (curvekey == CData->curve_firstkey[curve] + CData->curve_keynum[curve] - 1)) { radius = 0.0f; } - mesh->add_curve_key(ickey_loc, radius); + hair->add_curve_key(ickey_loc, radius); if (attr_intercept) attr_intercept->add(time); @@ -660,16 +695,16 @@ static void ExportCurveSegments(Scene *scene, Mesh *mesh, ParticleCurveData *CDa attr_random->add(hash_uint2_to_float(num_curves, 0)); } - mesh->add_curve(num_keys, CData->psys_shader[sys]); + hair->add_curve(num_keys, CData->psys_shader[sys]); num_keys += num_curve_keys; num_curves++; } } /* check allocation */ - if ((mesh->curve_keys.size() != num_keys) || (mesh->num_curves() != num_curves)) { + if ((hair->curve_keys.size() != num_keys) || (hair->num_curves() != num_curves)) { VLOG(1) << "Allocation failed, clearing data"; - mesh->clear(); + hair->clear(); } } @@ -713,24 +748,24 @@ static float4 LerpCurveSegmentMotionCV(ParticleCurveData *CData, int sys, int cu return lerp(mP, mP2, remainder); } -static void ExportCurveSegmentsMotion(Mesh *mesh, ParticleCurveData *CData, int motion_step) +static void ExportCurveSegmentsMotion(Hair *hair, ParticleCurveData *CData, int motion_step) { - VLOG(1) << "Exporting curve motion segments for mesh " << mesh->name << ", motion step " + VLOG(1) << "Exporting curve motion segments for hair " << hair->name << ", motion step " << motion_step; /* find attribute */ - Attribute *attr_mP = mesh->curve_attributes.find(ATTR_STD_MOTION_VERTEX_POSITION); + Attribute *attr_mP = hair->attributes.find(ATTR_STD_MOTION_VERTEX_POSITION); bool new_attribute = false; /* add new attribute if it doesn't exist already */ if (!attr_mP) { VLOG(1) << "Creating new motion vertex position attribute"; - attr_mP = mesh->curve_attributes.add(ATTR_STD_MOTION_VERTEX_POSITION); + attr_mP = hair->attributes.add(ATTR_STD_MOTION_VERTEX_POSITION); new_attribute = true; } /* export motion vectors for curve keys */ - size_t numkeys = mesh->curve_keys.size(); + size_t numkeys = hair->curve_keys.size(); float4 *mP = attr_mP->data_float4() + motion_step * numkeys; bool have_motion = false; int i = 0; @@ -741,24 +776,24 @@ static void ExportCurveSegmentsMotion(Mesh *mesh, ParticleCurveData *CData, int curve < CData->psys_firstcurve[sys] + CData->psys_curvenum[sys]; curve++) { /* Curve lengths may not match! Curves can be clipped. */ - int curve_key_end = (num_curves + 1 < (int)mesh->curve_first_key.size() ? - mesh->curve_first_key[num_curves + 1] : - (int)mesh->curve_keys.size()); - const int num_center_curve_keys = curve_key_end - mesh->curve_first_key[num_curves]; + int curve_key_end = (num_curves + 1 < (int)hair->curve_first_key.size() ? + hair->curve_first_key[num_curves + 1] : + (int)hair->curve_keys.size()); + const int num_center_curve_keys = curve_key_end - hair->curve_first_key[num_curves]; const int is_num_keys_different = CData->curve_keynum[curve] - num_center_curve_keys; if (!is_num_keys_different) { for (int curvekey = CData->curve_firstkey[curve]; curvekey < CData->curve_firstkey[curve] + CData->curve_keynum[curve]; curvekey++) { - if (i < mesh->curve_keys.size()) { + if (i < hair->curve_keys.size()) { mP[i] = CurveSegmentMotionCV(CData, sys, curve, curvekey); if (!have_motion) { /* unlike mesh coordinates, these tend to be slightly different * between frames due to particle transforms into/out of object * space, so we use an epsilon to detect actual changes */ - float4 curve_key = float3_to_float4(mesh->curve_keys[i]); - curve_key.w = mesh->curve_radius[i]; + float4 curve_key = float3_to_float4(hair->curve_keys[i]); + curve_key.w = hair->curve_radius[i]; if (len_squared(mP[i] - curve_key) > 1e-5f * 1e-5f) have_motion = true; } @@ -784,40 +819,15 @@ static void ExportCurveSegmentsMotion(Mesh *mesh, ParticleCurveData *CData, int /* in case of new attribute, we verify if there really was any motion */ if (new_attribute) { - if (i != numkeys || !have_motion) { - /* No motion or hair "topology" changed, remove attributes again. */ - if (i != numkeys) { - VLOG(1) << "Hair topology changed, removing attribute."; - } - else { - VLOG(1) << "No motion, removing attribute."; - } - mesh->curve_attributes.remove(ATTR_STD_MOTION_VERTEX_POSITION); - } - else if (motion_step > 0) { - VLOG(1) << "Filling in new motion vertex position for motion_step " << motion_step; - /* motion, fill up previous steps that we might have skipped because - * they had no motion, but we need them anyway now */ - for (int step = 0; step < motion_step; step++) { - float4 *mP = attr_mP->data_float4() + step * numkeys; - - for (int key = 0; key < numkeys; key++) { - mP[key] = float3_to_float4(mesh->curve_keys[key]); - mP[key].w = mesh->curve_radius[key]; - } - } - } + export_hair_motion_validate_attribute(hair, motion_step, i, have_motion); } } -static void ExportCurveTriangleUV(ParticleCurveData *CData, - int vert_offset, - int resol, - float2 *uvdata) +static void ExportCurveTriangleUV(ParticleCurveData *CData, int resol, float2 *uvdata) { if (uvdata == NULL) return; - int vertexindex = vert_offset; + int vertexindex = 0; for (int sys = 0; sys < CData->psys_firstcurve.size(); sys++) { for (int curve = CData->psys_firstcurve[sys]; @@ -845,15 +855,12 @@ static void ExportCurveTriangleUV(ParticleCurveData *CData, } } -static void ExportCurveTriangleVcol(ParticleCurveData *CData, - int vert_offset, - int resol, - uchar4 *cdata) +static void ExportCurveTriangleVcol(ParticleCurveData *CData, int resol, uchar4 *cdata) { if (cdata == NULL) return; - int vertexindex = vert_offset; + int vertexindex = 0; for (int sys = 0; sys < CData->psys_firstcurve.size(); sys++) { for (int curve = CData->psys_firstcurve[sys]; @@ -952,7 +959,7 @@ void BlenderSync::sync_curve_settings() if ((b_psys->settings().render_type() == BL::ParticleSettings::render_type_PATH) && (b_psys->settings().type() == BL::ParticleSettings::type_HAIR)) { BL::ID key = BKE_object_is_modified(*b_ob) ? *b_ob : b_ob->data(); - mesh_map.set_recalc(key); + geometry_map.set_recalc(key); object_map.set_recalc(*b_ob); } } @@ -987,28 +994,28 @@ bool BlenderSync::object_has_particle_hair(BL::Object b_ob) /* Old particle hair. */ void BlenderSync::sync_particle_hair( - Mesh *mesh, BL::Mesh &b_mesh, BL::Object &b_ob, bool motion, int motion_step) + Geometry *geom, BL::Mesh &b_mesh, BL::Object &b_ob, bool motion, int motion_step) { + Hair *hair = (geom->type == Geometry::HAIR) ? static_cast<Hair *>(geom) : NULL; + Mesh *mesh = (geom->type == Geometry::MESH) ? static_cast<Mesh *>(geom) : NULL; + + /* obtain general settings */ if (b_ob.mode() == b_ob.mode_PARTICLE_EDIT || b_ob.mode() == b_ob.mode_EDIT) { return; } - /* obtain general settings */ - const int primitive = scene->curve_system_manager->primitive; const int triangle_method = scene->curve_system_manager->triangle_method; const int resolution = scene->curve_system_manager->resolution; - const size_t vert_num = mesh->verts.size(); - const size_t tri_num = mesh->num_triangles(); int used_res = 1; /* extract particle hair data - should be combined with connecting to mesh later*/ ParticleCurveData CData; - ObtainCacheParticleData(mesh, &b_mesh, &b_ob, &CData, !preview); + ObtainCacheParticleData(geom, &b_mesh, &b_ob, &CData, !preview); /* add hair geometry to mesh */ - if (primitive == CURVE_TRIANGLES) { + if (mesh) { if (triangle_method == CURVE_CAMERA_TRIANGLES) { /* obtain camera parameters */ float3 RotCam; @@ -1032,31 +1039,31 @@ void BlenderSync::sync_particle_hair( } else { if (motion) - ExportCurveSegmentsMotion(mesh, &CData, motion_step); + ExportCurveSegmentsMotion(hair, &CData, motion_step); else - ExportCurveSegments(scene, mesh, &CData); + ExportCurveSegments(scene, hair, &CData); } /* generated coordinates from first key. we should ideally get this from * blender to handle deforming objects */ if (!motion) { - if (mesh->need_attribute(scene, ATTR_STD_GENERATED)) { + if (geom->need_attribute(scene, ATTR_STD_GENERATED)) { float3 loc, size; mesh_texture_space(b_mesh, loc, size); - if (primitive == CURVE_TRIANGLES) { + if (mesh) { Attribute *attr_generated = mesh->attributes.add(ATTR_STD_GENERATED); float3 *generated = attr_generated->data_float3(); - for (size_t i = vert_num; i < mesh->verts.size(); i++) + for (size_t i = 0; i < mesh->verts.size(); i++) generated[i] = mesh->verts[i] * size - loc; } else { - Attribute *attr_generated = mesh->curve_attributes.add(ATTR_STD_GENERATED); + Attribute *attr_generated = hair->attributes.add(ATTR_STD_GENERATED); float3 *generated = attr_generated->data_float3(); - for (size_t i = 0; i < mesh->num_curves(); i++) { - float3 co = mesh->curve_keys[mesh->get_curve(i).first_key]; + for (size_t i = 0; i < hair->num_curves(); i++) { + float3 co = hair->curve_keys[hair->get_curve(i).first_key]; generated[i] = co * size - loc; } } @@ -1069,21 +1076,21 @@ void BlenderSync::sync_particle_hair( int vcol_num = 0; for (b_mesh.vertex_colors.begin(l); l != b_mesh.vertex_colors.end(); ++l, vcol_num++) { - if (!mesh->need_attribute(scene, ustring(l->name().c_str()))) + if (!geom->need_attribute(scene, ustring(l->name().c_str()))) continue; - ObtainCacheParticleVcol(mesh, &b_mesh, &b_ob, &CData, !preview, vcol_num); + ObtainCacheParticleVcol(geom, &b_mesh, &b_ob, &CData, !preview, vcol_num); - if (primitive == CURVE_TRIANGLES) { + if (mesh) { Attribute *attr_vcol = mesh->attributes.add( ustring(l->name().c_str()), TypeDesc::TypeColor, ATTR_ELEMENT_CORNER_BYTE); uchar4 *cdata = attr_vcol->data_uchar4(); - ExportCurveTriangleVcol(&CData, tri_num * 3, used_res, cdata); + ExportCurveTriangleVcol(&CData, used_res, cdata); } else { - Attribute *attr_vcol = mesh->curve_attributes.add( + Attribute *attr_vcol = hair->attributes.add( ustring(l->name().c_str()), TypeDesc::TypeColor, ATTR_ELEMENT_CURVE); float3 *fdata = attr_vcol->data_float3(); @@ -1111,12 +1118,12 @@ void BlenderSync::sync_particle_hair( ustring name = ustring(l->name().c_str()); /* UV map */ - if (mesh->need_attribute(scene, name) || mesh->need_attribute(scene, std)) { + if (geom->need_attribute(scene, name) || geom->need_attribute(scene, std)) { Attribute *attr_uv; - ObtainCacheParticleUV(mesh, &b_mesh, &b_ob, &CData, !preview, uv_num); + ObtainCacheParticleUV(geom, &b_mesh, &b_ob, &CData, !preview, uv_num); - if (primitive == CURVE_TRIANGLES) { + if (mesh) { if (active_render) attr_uv = mesh->attributes.add(std, name); else @@ -1124,13 +1131,13 @@ void BlenderSync::sync_particle_hair( float2 *uv = attr_uv->data_float2(); - ExportCurveTriangleUV(&CData, tri_num * 3, used_res, uv); + ExportCurveTriangleUV(&CData, used_res, uv); } else { if (active_render) - attr_uv = mesh->curve_attributes.add(std, name); + attr_uv = hair->attributes.add(std, name); else - attr_uv = mesh->curve_attributes.add(name, TypeFloat2, ATTR_ELEMENT_CURVE); + attr_uv = hair->attributes.add(name, TypeFloat2, ATTR_ELEMENT_CURVE); float2 *uv = attr_uv->data_float2(); @@ -1145,44 +1152,56 @@ void BlenderSync::sync_particle_hair( } } } - - mesh->geometry_flags |= Mesh::GEOMETRY_CURVES; } -void BlenderSync::sync_hair(BL::Depsgraph b_depsgraph, BL::Object b_ob, Mesh *mesh) +void BlenderSync::sync_hair(BL::Depsgraph b_depsgraph, BL::Object b_ob, Geometry *geom) { - /* compares curve_keys rather than strands in order to handle quick hair - * adjustments in dynamic BVH - other methods could probably do this better*/ + Hair *hair = (geom->type == Geometry::HAIR) ? static_cast<Hair *>(geom) : NULL; + Mesh *mesh = (geom->type == Geometry::MESH) ? static_cast<Mesh *>(geom) : NULL; + + /* Compares curve_keys rather than strands in order to handle quick hair + * adjustments in dynamic BVH - other methods could probably do this better. */ array<float3> oldcurve_keys; array<float> oldcurve_radius; - oldcurve_keys.steal_data(mesh->curve_keys); - oldcurve_radius.steal_data(mesh->curve_radius); + array<int> oldtriangles; + if (hair) { + oldcurve_keys.steal_data(hair->curve_keys); + oldcurve_radius.steal_data(hair->curve_radius); + } + else { + oldtriangles.steal_data(mesh->triangles); + } if (view_layer.use_hair && scene->curve_system_manager->use_curves) { /* Particle hair. */ - bool need_undeformed = mesh->need_attribute(scene, ATTR_STD_GENERATED); + bool need_undeformed = geom->need_attribute(scene, ATTR_STD_GENERATED); BL::Mesh b_mesh = object_to_mesh( b_data, b_ob, b_depsgraph, need_undeformed, Mesh::SUBDIVISION_NONE); if (b_mesh) { - sync_particle_hair(mesh, b_mesh, b_ob, false); + sync_particle_hair(geom, b_mesh, b_ob, false); free_object_to_mesh(b_data, b_ob, b_mesh); } } /* tag update */ - bool rebuild = (oldcurve_keys != mesh->curve_keys) || (oldcurve_radius != mesh->curve_radius); - mesh->tag_update(scene, rebuild); + const bool rebuild = (hair && ((oldcurve_keys != hair->curve_keys) || + (oldcurve_radius != hair->curve_radius))) || + (mesh && (oldtriangles != mesh->triangles)); + + geom->tag_update(scene, rebuild); } void BlenderSync::sync_hair_motion(BL::Depsgraph b_depsgraph, BL::Object b_ob, - Mesh *mesh, + Geometry *geom, int motion_step) { - /* Skip if no curves were exported. */ - size_t numkeys = mesh->curve_keys.size(); - if (numkeys == 0) { + Hair *hair = (geom->type == Geometry::HAIR) ? static_cast<Hair *>(geom) : NULL; + Mesh *mesh = (geom->type == Geometry::MESH) ? static_cast<Mesh *>(geom) : NULL; + + /* Skip if nothing exported. */ + if ((hair && hair->num_keys() == 0) || (mesh && mesh->verts.size() == 0)) { return; } @@ -1191,17 +1210,18 @@ void BlenderSync::sync_hair_motion(BL::Depsgraph b_depsgraph, /* Particle hair. */ BL::Mesh b_mesh = object_to_mesh(b_data, b_ob, b_depsgraph, false, Mesh::SUBDIVISION_NONE); if (b_mesh) { - sync_particle_hair(mesh, b_mesh, b_ob, true, motion_step); + sync_particle_hair(geom, b_mesh, b_ob, true, motion_step); free_object_to_mesh(b_data, b_ob, b_mesh); return; } } /* No deformation on this frame, copy coordinates if other frames did have it. */ - Attribute *attr_mP = mesh->curve_attributes.find(ATTR_STD_MOTION_VERTEX_POSITION); - if (attr_mP) { - float3 *keys = &mesh->curve_keys[0]; - memcpy(attr_mP->data_float3() + motion_step * numkeys, keys, sizeof(float3) * numkeys); + if (hair) { + hair->copy_center_to_motion_step(motion_step); + } + else { + mesh->copy_center_to_motion_step(motion_step); } } diff --git a/intern/cycles/blender/blender_geometry.cpp b/intern/cycles/blender/blender_geometry.cpp index 151b741b003..8b803835b62 100644 --- a/intern/cycles/blender/blender_geometry.cpp +++ b/intern/cycles/blender/blender_geometry.cpp @@ -15,6 +15,8 @@ * limitations under the License. */ +#include "render/curves.h" +#include "render/hair.h" #include "render/mesh.h" #include "render/object.h" @@ -23,18 +25,22 @@ CCL_NAMESPACE_BEGIN -Mesh *BlenderSync::sync_geometry(BL::Depsgraph &b_depsgraph, - BL::Object &b_ob, - BL::Object &b_ob_instance, - bool object_updated, - bool use_particle_hair) +Geometry *BlenderSync::sync_geometry(BL::Depsgraph &b_depsgraph, + BL::Object &b_ob, + BL::Object &b_ob_instance, + bool object_updated, + bool use_particle_hair) { /* Test if we can instance or if the object is modified. */ BL::ID b_ob_data = b_ob.data(); BL::ID b_key_id = (BKE_object_is_modified(b_ob)) ? b_ob_instance : b_ob_data; - MeshKey key(b_key_id.ptr.data, use_particle_hair); + GeometryKey key(b_key_id.ptr.data, use_particle_hair); BL::Material material_override = view_layer.material_override; Shader *default_shader = scene->default_surface; + Geometry::Type geom_type = (use_particle_hair && + (scene->curve_system_manager->primitive != CURVE_TRIANGLES)) ? + Geometry::HAIR : + Geometry::MESH; /* Find shader indices. */ vector<Shader *> used_shaders; @@ -58,53 +64,76 @@ Mesh *BlenderSync::sync_geometry(BL::Depsgraph &b_depsgraph, } /* Test if we need to sync. */ - Mesh *mesh; + Geometry *geom = geometry_map.find(key); + bool sync = true; + if (geom == NULL) { + /* Add new geometry if it did not exist yet. */ + if (geom_type == Geometry::HAIR) { + geom = new Hair(); + } + else { + geom = new Mesh(); + } + geometry_map.add(key, geom); + } + else { + /* Test if we need to update existing geometry. */ + sync = geometry_map.update(geom, b_key_id); + } - if (!mesh_map.sync(&mesh, b_key_id, key)) { - /* If transform was applied to mesh, need full update. */ - if (object_updated && mesh->transform_applied) + if (!sync) { + /* If transform was applied to geometry, need full update. */ + if (object_updated && geom->transform_applied) { ; - /* Test if shaders changed, these can be object level so mesh + } + /* Test if shaders changed, these can be object level so geometry * does not get tagged for recalc. */ - else if (mesh->used_shaders != used_shaders) + else if (geom->used_shaders != used_shaders) { ; + } else { /* Even if not tagged for recalc, we may need to sync anyway - * because the shader needs different mesh attributes. */ + * because the shader needs different geometry attributes. */ bool attribute_recalc = false; - foreach (Shader *shader, mesh->used_shaders) - if (shader->need_update_mesh) + foreach (Shader *shader, geom->used_shaders) { + if (shader->need_update_geometry) { attribute_recalc = true; + } + } - if (!attribute_recalc) - return mesh; + if (!attribute_recalc) { + return geom; + } } } - /* Ensure we only sync instanced meshes once. */ - if (mesh_synced.find(mesh) != mesh_synced.end()) - return mesh; + /* Ensure we only sync instanced geometry once. */ + if (geometry_synced.find(geom) != geometry_synced.end()) { + return geom; + } progress.set_sync_status("Synchronizing object", b_ob.name()); - mesh_synced.insert(mesh); + geometry_synced.insert(geom); - mesh->clear(); - mesh->used_shaders = used_shaders; - mesh->name = ustring(b_ob_data.name().c_str()); + geom->clear(); + geom->used_shaders = used_shaders; + geom->name = ustring(b_ob_data.name().c_str()); if (use_particle_hair) { - sync_hair(b_depsgraph, b_ob, mesh); + sync_hair(b_depsgraph, b_ob, geom); } else if (object_fluid_gas_domain_find(b_ob)) { + Mesh *mesh = static_cast<Mesh *>(geom); sync_volume(b_ob, mesh); } else { + Mesh *mesh = static_cast<Mesh *>(geom); sync_mesh(b_depsgraph, b_ob, mesh); } - return mesh; + return geom; } void BlenderSync::sync_geometry_motion(BL::Depsgraph &b_depsgraph, @@ -113,32 +142,33 @@ void BlenderSync::sync_geometry_motion(BL::Depsgraph &b_depsgraph, float motion_time, bool use_particle_hair) { - /* Ensure we only sync instanced meshes once. */ - Mesh *mesh = object->mesh; + /* Ensure we only sync instanced geometry once. */ + Geometry *geom = object->geometry; - if (mesh_motion_synced.find(mesh) != mesh_motion_synced.end()) + if (geometry_motion_synced.find(geom) != geometry_motion_synced.end()) return; - mesh_motion_synced.insert(mesh); + geometry_motion_synced.insert(geom); - /* Ensure we only motion sync meshes that also had mesh synced, to avoid + /* Ensure we only motion sync geometry that also had geometry synced, to avoid * unnecessary work and to ensure that its attributes were clear. */ - if (mesh_synced.find(mesh) == mesh_synced.end()) + if (geometry_synced.find(geom) == geometry_synced.end()) return; - /* Find time matching motion step required by mesh. */ - int motion_step = mesh->motion_step(motion_time); + /* Find time matching motion step required by geometry. */ + int motion_step = geom->motion_step(motion_time); if (motion_step < 0) { return; } if (use_particle_hair) { - sync_hair_motion(b_depsgraph, b_ob, mesh, motion_step); + sync_hair_motion(b_depsgraph, b_ob, geom, motion_step); } else if (object_fluid_gas_domain_find(b_ob)) { /* No volume motion blur support yet. */ } else { + Mesh *mesh = static_cast<Mesh *>(geom); sync_mesh_motion(b_depsgraph, b_ob, mesh, motion_step); } } diff --git a/intern/cycles/blender/blender_id_map.h b/intern/cycles/blender/blender_id_map.h index 52031cd9f34..83c93bb09ee 100644 --- a/intern/cycles/blender/blender_id_map.h +++ b/intern/cycles/blender/blender_id_map.h @@ -72,41 +72,61 @@ template<typename K, typename T> class id_map { used_set.clear(); } - bool sync(T **r_data, const BL::ID &id) + /* Add new data. */ + void add(const K &key, T *data) { - return sync(r_data, id, id, id.ptr.owner_id); + assert(find(key) == NULL); + scene_data->push_back(data); + b_map[key] = data; + used(data); } - bool sync(T **r_data, const BL::ID &id, const K &key) + /* Update existing data. */ + bool update(T *data, const BL::ID &id) { - return sync(r_data, id, id, key); + return update(data, id, id); + } + bool update(T *data, const BL::ID &id, const BL::ID &parent) + { + bool recalc = (b_recalc.find(id.ptr.data) != b_recalc.end()); + if (parent.ptr.data && parent.ptr.data != id.ptr.data) { + recalc = recalc || (b_recalc.find(parent.ptr.data) != b_recalc.end()); + } + used(data); + return recalc; } - bool sync(T **r_data, const BL::ID &id, const BL::ID &parent, const K &key) + /* Combined add and update as needed. */ + bool add_or_update(T **r_data, const BL::ID &id) + { + return add_or_update(r_data, id, id, id.ptr.owner_id); + } + bool add_or_update(T **r_data, const BL::ID &id, const K &key) + { + return add_or_update(r_data, id, id, key); + } + bool add_or_update(T **r_data, const BL::ID &id, const BL::ID &parent, const K &key) { T *data = find(key); bool recalc; if (!data) { - /* add data if it didn't exist yet */ + /* Add data if it didn't exist yet. */ data = new T(); - scene_data->push_back(data); - b_map[key] = data; + add(key, data); recalc = true; } else { - recalc = (b_recalc.find(id.ptr.data) != b_recalc.end()); - if (parent.ptr.data && parent.ptr.data != id.ptr.data) { - recalc = recalc || (b_recalc.find(parent.ptr.data) != b_recalc.end()); - } + /* check if updated needed. */ + recalc = update(data, id, parent); } - used(data); - *r_data = data; return recalc; } + /* Combined add or update for convenience. */ + bool is_used(const K &key) { T *data = find(key); @@ -220,20 +240,20 @@ struct ObjectKey { } }; -/* Mesh Key +/* Geometry Key * * We export separate geomtry for a mesh and its particle hair, so key needs to * distinguish between them. */ -struct MeshKey { +struct GeometryKey { void *id; bool use_particle_hair; - MeshKey(void *id, bool use_particle_hair) : id(id), use_particle_hair(use_particle_hair) + GeometryKey(void *id, bool use_particle_hair) : id(id), use_particle_hair(use_particle_hair) { } - bool operator<(const MeshKey &k) const + bool operator<(const GeometryKey &k) const { if (id < k.id) { return true; diff --git a/intern/cycles/blender/blender_light.cpp b/intern/cycles/blender/blender_light.cpp index a8e28a011d7..5351de2e84b 100644 --- a/intern/cycles/blender/blender_light.cpp +++ b/intern/cycles/blender/blender_light.cpp @@ -39,9 +39,9 @@ void BlenderSync::sync_light(BL::Object &b_parent, BL::Light b_light(b_ob.data()); /* Update if either object or light data changed. */ - if (!light_map.sync(&light, b_ob, b_parent, key)) { + if (!light_map.add_or_update(&light, b_ob, b_parent, key)) { Shader *shader; - if (!shader_map.sync(&shader, b_light)) { + if (!shader_map.add_or_update(&shader, b_light)) { if (light->is_portal) *use_portal = true; return; @@ -176,7 +176,7 @@ void BlenderSync::sync_background_light(BL::SpaceView3D &b_v3d, bool use_portal) Light *light; ObjectKey key(b_world, 0, b_world, false); - if (light_map.sync(&light, b_world, b_world, key) || world_recalc || + if (light_map.add_or_update(&light, b_world, b_world, key) || world_recalc || b_world.ptr.data != world_map) { light->type = LIGHT_BACKGROUND; if (sampling_method == SAMPLING_MANUAL) { diff --git a/intern/cycles/blender/blender_mesh.cpp b/intern/cycles/blender/blender_mesh.cpp index 00faafe29ee..332c26161dc 100644 --- a/intern/cycles/blender/blender_mesh.cpp +++ b/intern/cycles/blender/blender_mesh.cpp @@ -719,7 +719,6 @@ static void create_mesh(Scene *scene, /* allocate memory */ mesh->reserve_mesh(numverts, numtris); mesh->reserve_subd_faces(numfaces, numngons, numcorners); - mesh->geometry_flags |= Mesh::GEOMETRY_TRIANGLES; /* create vertex coordinates and normals */ BL::Mesh::vertices_iterator v; @@ -1053,18 +1052,7 @@ void BlenderSync::sync_mesh_motion(BL::Depsgraph b_depsgraph, } /* No deformation on this frame, copy coordinates if other frames did have it. */ - Attribute *attr_mP = mesh->attributes.find(ATTR_STD_MOTION_VERTEX_POSITION); - - if (attr_mP) { - Attribute *attr_mN = mesh->attributes.find(ATTR_STD_MOTION_VERTEX_NORMAL); - Attribute *attr_N = mesh->attributes.find(ATTR_STD_VERTEX_NORMAL); - float3 *P = &mesh->verts[0]; - float3 *N = (attr_N) ? attr_N->data_float3() : NULL; - - memcpy(attr_mP->data_float3() + motion_step * numverts, P, sizeof(float3) * numverts); - if (attr_mN) - memcpy(attr_mN->data_float3() + motion_step * numverts, N, sizeof(float3) * numverts); - } + mesh->copy_center_to_motion_step(motion_step); } CCL_NAMESPACE_END diff --git a/intern/cycles/blender/blender_object.cpp b/intern/cycles/blender/blender_object.cpp index 13dfd0867ba..2b1d1eff7e5 100644 --- a/intern/cycles/blender/blender_object.cpp +++ b/intern/cycles/blender/blender_object.cpp @@ -191,7 +191,7 @@ Object *BlenderSync::sync_object(BL::Depsgraph &b_depsgraph, } /* mesh deformation */ - if (object->mesh) + if (object->geometry) sync_geometry_motion(b_depsgraph, b_ob, object, motion_time, use_particle_hair); } @@ -201,11 +201,11 @@ Object *BlenderSync::sync_object(BL::Depsgraph &b_depsgraph, /* test if we need to sync */ bool object_updated = false; - if (object_map.sync(&object, b_ob, b_parent, key)) + if (object_map.add_or_update(&object, b_ob, b_parent, key)) object_updated = true; /* mesh sync */ - object->mesh = sync_geometry( + object->geometry = sync_geometry( b_depsgraph, b_ob, b_ob_instance, object_updated, use_particle_hair); /* special case not tracked by object update flags */ @@ -248,7 +248,8 @@ Object *BlenderSync::sync_object(BL::Depsgraph &b_depsgraph, /* object sync * transform comparison should not be needed, but duplis don't work perfect * in the depsgraph and may not signal changes, so this is a workaround */ - if (object_updated || (object->mesh && object->mesh->need_update) || tfm != object->tfm) { + if (object_updated || (object->geometry && object->geometry->need_update) || + tfm != object->tfm) { object->name = b_ob.name().c_str(); object->pass_id = b_ob.pass_index(); object->color = get_float3(b_ob.color()); @@ -257,23 +258,23 @@ Object *BlenderSync::sync_object(BL::Depsgraph &b_depsgraph, /* motion blur */ Scene::MotionType need_motion = scene->need_motion(); - if (need_motion != Scene::MOTION_NONE && object->mesh) { - Mesh *mesh = object->mesh; - mesh->use_motion_blur = false; - mesh->motion_steps = 0; + if (need_motion != Scene::MOTION_NONE && object->geometry) { + Geometry *geom = object->geometry; + geom->use_motion_blur = false; + geom->motion_steps = 0; uint motion_steps; if (need_motion == Scene::MOTION_BLUR) { motion_steps = object_motion_steps(b_parent, b_ob); - mesh->motion_steps = motion_steps; + geom->motion_steps = motion_steps; if (motion_steps && object_use_deform_motion(b_parent, b_ob)) { - mesh->use_motion_blur = true; + geom->use_motion_blur = true; } } else { motion_steps = 3; - mesh->motion_steps = motion_steps; + geom->motion_steps = motion_steps; } object->motion.clear(); @@ -324,13 +325,13 @@ void BlenderSync::sync_objects(BL::Depsgraph &b_depsgraph, if (!motion) { /* prepare for sync */ light_map.pre_sync(); - mesh_map.pre_sync(); + geometry_map.pre_sync(); object_map.pre_sync(); particle_system_map.pre_sync(); motion_times.clear(); } else { - mesh_motion_synced.clear(); + geometry_motion_synced.clear(); } /* initialize culling */ @@ -394,8 +395,8 @@ void BlenderSync::sync_objects(BL::Depsgraph &b_depsgraph, /* handle removed data and modified pointers */ if (light_map.post_sync()) scene->light_manager->tag_update(scene); - if (mesh_map.post_sync()) - scene->mesh_manager->tag_update(scene); + if (geometry_map.post_sync()) + scene->geometry_manager->tag_update(scene); if (object_map.post_sync()) scene->object_manager->tag_update(scene); if (particle_system_map.post_sync()) @@ -403,7 +404,7 @@ void BlenderSync::sync_objects(BL::Depsgraph &b_depsgraph, } if (motion) - mesh_motion_synced.clear(); + geometry_motion_synced.clear(); } void BlenderSync::sync_motion(BL::RenderSettings &b_render, diff --git a/intern/cycles/blender/blender_particles.cpp b/intern/cycles/blender/blender_particles.cpp index d74f132ed60..e5eab1ae62b 100644 --- a/intern/cycles/blender/blender_particles.cpp +++ b/intern/cycles/blender/blender_particles.cpp @@ -39,7 +39,7 @@ bool BlenderSync::sync_dupli_particle(BL::Object &b_ob, object->hide_on_missing_motion = true; /* test if we need particle data */ - if (!object->mesh->need_attribute(scene, ATTR_STD_PARTICLE)) + if (!object->geometry->need_attribute(scene, ATTR_STD_PARTICLE)) return false; /* don't handle child particles yet */ @@ -53,10 +53,10 @@ bool BlenderSync::sync_dupli_particle(BL::Object &b_ob, ParticleSystem *psys; bool first_use = !particle_system_map.is_used(key); - bool need_update = particle_system_map.sync(&psys, b_ob, b_instance.object(), key); + bool need_update = particle_system_map.add_or_update(&psys, b_ob, b_instance.object(), key); /* no update needed? */ - if (!need_update && !object->mesh->need_update && !scene->object_manager->need_update) + if (!need_update && !object->geometry->need_update && !scene->object_manager->need_update) return true; /* first time used in this sync loop? clear and tag update */ diff --git a/intern/cycles/blender/blender_session.cpp b/intern/cycles/blender/blender_session.cpp index 663f3d72110..1490348743e 100644 --- a/intern/cycles/blender/blender_session.cpp +++ b/intern/cycles/blender/blender_session.cpp @@ -720,9 +720,12 @@ void BlenderSession::bake(BL::Depsgraph &b_depsgraph_, int tri_offset = 0; for (size_t i = 0; i < scene->objects.size(); i++) { - if (strcmp(scene->objects[i]->name.c_str(), b_object.name().c_str()) == 0) { + const Object *object = scene->objects[i]; + const Geometry *geom = object->geometry; + if (object->name == b_object.name() && geom->type == Geometry::MESH) { + const Mesh *mesh = static_cast<const Mesh *>(geom); object_index = i; - tri_offset = scene->objects[i]->mesh->tri_offset; + tri_offset = mesh->prim_offset; break; } } diff --git a/intern/cycles/blender/blender_shader.cpp b/intern/cycles/blender/blender_shader.cpp index 206058259af..635405e42c7 100644 --- a/intern/cycles/blender/blender_shader.cpp +++ b/intern/cycles/blender/blender_shader.cpp @@ -1255,7 +1255,7 @@ void BlenderSync::sync_materials(BL::Depsgraph &b_depsgraph, bool update_all) Shader *shader; /* test if we need to sync */ - if (shader_map.sync(&shader, b_mat) || shader->need_sync_object || update_all) { + if (shader_map.add_or_update(&shader, b_mat) || shader->need_sync_object || update_all) { ShaderGraph *graph = new ShaderGraph(); shader->name = b_mat.name().c_str(); @@ -1480,7 +1480,7 @@ void BlenderSync::sync_lights(BL::Depsgraph &b_depsgraph, bool update_all) Shader *shader; /* test if we need to sync */ - if (shader_map.sync(&shader, b_light) || update_all) { + if (shader_map.add_or_update(&shader, b_light) || update_all) { ShaderGraph *graph = new ShaderGraph(); /* create nodes */ diff --git a/intern/cycles/blender/blender_sync.cpp b/intern/cycles/blender/blender_sync.cpp index bb8a132ebb7..8960c84567e 100644 --- a/intern/cycles/blender/blender_sync.cpp +++ b/intern/cycles/blender/blender_sync.cpp @@ -56,7 +56,7 @@ BlenderSync::BlenderSync(BL::RenderEngine &b_engine, b_scene(b_scene), shader_map(&scene->shaders), object_map(&scene->objects), - mesh_map(&scene->meshes), + geometry_map(&scene->geometry), light_map(&scene->lights), particle_system_map(&scene->particle_systems), world_map(NULL), @@ -108,12 +108,15 @@ void BlenderSync::sync_recalc(BL::Depsgraph &b_depsgraph, BL::SpaceView3D &b_v3d } if (dicing_prop_changed) { - for (const pair<MeshKey, Mesh *> &iter : mesh_map.key_to_scene_data()) { - Mesh *mesh = iter.second; - if (mesh->subdivision_type != Mesh::SUBDIVISION_NONE) { - PointerRNA id_ptr; - RNA_id_pointer_create((::ID *)iter.first.id, &id_ptr); - mesh_map.set_recalc(BL::ID(id_ptr)); + for (const pair<GeometryKey, Geometry *> &iter : geometry_map.key_to_scene_data()) { + Geometry *geom = iter.second; + if (geom->type == Geometry::MESH) { + Mesh *mesh = static_cast<Mesh *>(geom); + if (mesh->subdivision_type != Mesh::SUBDIVISION_NONE) { + PointerRNA id_ptr; + RNA_id_pointer_create((::ID *)iter.first.id, &id_ptr); + geometry_map.set_recalc(BL::ID(id_ptr)); + } } } } @@ -148,7 +151,7 @@ void BlenderSync::sync_recalc(BL::Depsgraph &b_depsgraph, BL::SpaceView3D &b_v3d if (updated_geometry || (object_subdivision_type(b_ob, preview, experimental) != Mesh::SUBDIVISION_NONE)) { BL::ID key = BKE_object_is_modified(b_ob) ? b_ob : b_ob.data(); - mesh_map.set_recalc(key); + geometry_map.set_recalc(key); } } else if (object_is_light(b_ob)) { @@ -166,7 +169,7 @@ void BlenderSync::sync_recalc(BL::Depsgraph &b_depsgraph, BL::SpaceView3D &b_v3d /* Mesh */ else if (b_id.is_a(&RNA_Mesh)) { BL::Mesh b_mesh(b_id); - mesh_map.set_recalc(b_mesh); + geometry_map.set_recalc(b_mesh); } /* World */ else if (b_id.is_a(&RNA_World)) { @@ -213,7 +216,7 @@ void BlenderSync::sync_data(BL::RenderSettings &b_render, sync_images(); sync_curve_settings(); - mesh_synced.clear(); /* use for objects and motion sync */ + geometry_synced.clear(); /* use for objects and motion sync */ if (scene->need_motion() == Scene::MOTION_PASS || scene->need_motion() == Scene::MOTION_NONE || scene->camera->motion_position == Camera::MOTION_POSITION_CENTER) { @@ -221,7 +224,7 @@ void BlenderSync::sync_data(BL::RenderSettings &b_render, } sync_motion(b_render, b_depsgraph, b_v3d, b_override, width, height, python_thread_state); - mesh_synced.clear(); + geometry_synced.clear(); /* Shader sync done at the end, since object sync uses it. * false = don't delete unused shaders, not supported. */ diff --git a/intern/cycles/blender/blender_sync.h b/intern/cycles/blender/blender_sync.h index 295d9d2e307..f8134ff8b5c 100644 --- a/intern/cycles/blender/blender_sync.h +++ b/intern/cycles/blender/blender_sync.h @@ -40,6 +40,7 @@ class BlenderObjectCulling; class BlenderViewportParameters; class Camera; class Film; +class Hair; class Light; class Mesh; class Object; @@ -142,10 +143,13 @@ class BlenderSync { void sync_mesh_motion(BL::Depsgraph b_depsgraph, BL::Object b_ob, Mesh *mesh, int motion_step); /* Hair */ - void sync_hair(BL::Depsgraph b_depsgraph, BL::Object b_ob, Mesh *mesh); - void sync_hair_motion(BL::Depsgraph b_depsgraph, BL::Object b_ob, Mesh *mesh, int motion_step); + void sync_hair(BL::Depsgraph b_depsgraph, BL::Object b_ob, Geometry *geom); + void sync_hair_motion(BL::Depsgraph b_depsgraph, + BL::Object b_ob, + Geometry *geom, + int motion_step); void sync_particle_hair( - Mesh *mesh, BL::Mesh &b_mesh, BL::Object &b_ob, bool motion, int motion_step = 0); + Geometry *geom, BL::Mesh &b_mesh, BL::Object &b_ob, bool motion, int motion_step = 0); void sync_curve_settings(); bool object_has_particle_hair(BL::Object b_ob); @@ -154,11 +158,11 @@ class BlenderSync { BL::RenderSettings &b_render, BL::Object &b_ob, int width, int height, float motion_time); /* Geometry */ - Mesh *sync_geometry(BL::Depsgraph &b_depsgrpah, - BL::Object &b_ob, - BL::Object &b_ob_instance, - bool object_updated, - bool use_particle_hair); + Geometry *sync_geometry(BL::Depsgraph &b_depsgrpah, + BL::Object &b_ob, + BL::Object &b_ob_instance, + bool object_updated, + bool use_particle_hair); void sync_geometry_motion(BL::Depsgraph &b_depsgraph, BL::Object &b_ob, Object *object, @@ -199,11 +203,11 @@ class BlenderSync { id_map<void *, Shader> shader_map; id_map<ObjectKey, Object> object_map; - id_map<MeshKey, Mesh> mesh_map; + id_map<GeometryKey, Geometry> geometry_map; id_map<ObjectKey, Light> light_map; id_map<ParticleSystemKey, ParticleSystem> particle_system_map; - set<Mesh *> mesh_synced; - set<Mesh *> mesh_motion_synced; + set<Geometry *> geometry_synced; + set<Geometry *> geometry_motion_synced; set<float> motion_times; void *world_map; bool world_recalc; |