diff options
Diffstat (limited to 'source/blender/draw')
19 files changed, 275 insertions, 137 deletions
diff --git a/source/blender/draw/CMakeLists.txt b/source/blender/draw/CMakeLists.txt index 47d99963ef9..17feb39a072 100644 --- a/source/blender/draw/CMakeLists.txt +++ b/source/blender/draw/CMakeLists.txt @@ -86,9 +86,9 @@ set(SRC intern/mesh_extractors/extract_mesh_vbo_vcol.cc intern/mesh_extractors/extract_mesh_vbo_weights.cc intern/draw_cache_impl_curve.cc + intern/draw_cache_impl_curves.cc intern/draw_cache_impl_displist.c intern/draw_cache_impl_gpencil.c - intern/draw_cache_impl_hair.cc intern/draw_cache_impl_lattice.c intern/draw_cache_impl_mesh.c intern/draw_cache_impl_metaball.c diff --git a/source/blender/draw/engines/eevee/eevee_cryptomatte.c b/source/blender/draw/engines/eevee/eevee_cryptomatte.c index 80207523a65..8f02e96b168 100644 --- a/source/blender/draw/engines/eevee/eevee_cryptomatte.c +++ b/source/blender/draw/engines/eevee/eevee_cryptomatte.c @@ -56,7 +56,7 @@ #include "BLI_math_bits.h" #include "BLI_rect.h" -#include "DNA_hair_types.h" +#include "DNA_curves_types.h" #include "DNA_mesh_types.h" #include "DNA_modifier_types.h" #include "DNA_particle_types.h" @@ -248,25 +248,25 @@ static DRWShadingGroup *eevee_cryptomatte_shading_group_create(EEVEE_Data *vedat return grp; } -static void eevee_cryptomatte_hair_cache_populate(EEVEE_Data *vedata, - EEVEE_ViewLayerData *sldata, - Object *ob, - ParticleSystem *psys, - ModifierData *md, - Material *material) +static void eevee_cryptomatte_curves_cache_populate(EEVEE_Data *vedata, + EEVEE_ViewLayerData *sldata, + Object *ob, + ParticleSystem *psys, + ModifierData *md, + Material *material) { DRWShadingGroup *grp = eevee_cryptomatte_shading_group_create( vedata, sldata, ob, material, true); DRW_shgroup_hair_create_sub(ob, psys, md, grp, NULL); } -void EEVEE_cryptomatte_object_hair_cache_populate(EEVEE_Data *vedata, - EEVEE_ViewLayerData *sldata, - Object *ob) +void EEVEE_cryptomatte_object_curves_cache_populate(EEVEE_Data *vedata, + EEVEE_ViewLayerData *sldata, + Object *ob) { - BLI_assert(ob->type == OB_HAIR); - Material *material = BKE_object_material_get_eval(ob, HAIR_MATERIAL_NR); - eevee_cryptomatte_hair_cache_populate(vedata, sldata, ob, NULL, NULL, material); + BLI_assert(ob->type == OB_CURVES); + Material *material = BKE_object_material_get_eval(ob, CURVES_MATERIAL_NR); + eevee_cryptomatte_curves_cache_populate(vedata, sldata, ob, NULL, NULL, material); } void EEVEE_cryptomatte_particle_hair_cache_populate(EEVEE_Data *vedata, @@ -291,7 +291,7 @@ void EEVEE_cryptomatte_particle_hair_cache_populate(EEVEE_Data *vedata, continue; } Material *material = BKE_object_material_get_eval(ob, part->omat); - eevee_cryptomatte_hair_cache_populate(vedata, sldata, ob, psys, md, material); + eevee_cryptomatte_curves_cache_populate(vedata, sldata, ob, psys, md, material); } } } diff --git a/source/blender/draw/engines/eevee/eevee_data.c b/source/blender/draw/engines/eevee/eevee_data.c index b453df284ed..64553acd228 100644 --- a/source/blender/draw/engines/eevee/eevee_data.c +++ b/source/blender/draw/engines/eevee/eevee_data.c @@ -177,7 +177,7 @@ static void *motion_blur_deform_data_get(EEVEE_MotionBlurData *mb, Object *ob, b if (hair) { EEVEE_HairMotionData *hair_step; /* Ugly, we allocate for each modifiers and just fill based on modifier index in the list. */ - int psys_len = (ob->type != OB_HAIR) ? BLI_listbase_count(&ob->modifiers) : 1; + int psys_len = (ob->type != OB_CURVES) ? BLI_listbase_count(&ob->modifiers) : 1; hair_step = MEM_callocN(sizeof(EEVEE_HairMotionData) + sizeof(hair_step->psys[0]) * psys_len, __func__); hair_step->psys_len = psys_len; diff --git a/source/blender/draw/engines/eevee/eevee_engine.c b/source/blender/draw/engines/eevee/eevee_engine.c index fc9b8b0cde4..9b6b5c5f08d 100644 --- a/source/blender/draw/engines/eevee/eevee_engine.c +++ b/source/blender/draw/engines/eevee/eevee_engine.c @@ -125,7 +125,7 @@ void EEVEE_cache_populate(void *vedata, Object *ob) if (ELEM(ob->type, OB_MESH, OB_SURF, OB_MBALL)) { EEVEE_materials_cache_populate(vedata, sldata, ob, &cast_shadow); } - else if (ob->type == OB_HAIR) { + else if (ob->type == OB_CURVES) { EEVEE_object_hair_cache_populate(vedata, sldata, ob, &cast_shadow); } else if (ob->type == OB_VOLUME) { diff --git a/source/blender/draw/engines/eevee/eevee_materials.c b/source/blender/draw/engines/eevee/eevee_materials.c index a027a29c813..b8586ee0f68 100644 --- a/source/blender/draw/engines/eevee/eevee_materials.c +++ b/source/blender/draw/engines/eevee/eevee_materials.c @@ -33,7 +33,7 @@ #include "BKE_paint.h" #include "BKE_particle.h" -#include "DNA_hair_types.h" +#include "DNA_curves_types.h" #include "DNA_modifier_types.h" #include "DNA_view3d_types.h" #include "DNA_world_types.h" @@ -925,7 +925,7 @@ void EEVEE_object_hair_cache_populate(EEVEE_Data *vedata, Object *ob, bool *cast_shadow) { - eevee_hair_cache_populate(vedata, sldata, ob, NULL, NULL, HAIR_MATERIAL_NR, cast_shadow); + eevee_hair_cache_populate(vedata, sldata, ob, NULL, NULL, CURVES_MATERIAL_NR, cast_shadow); } void EEVEE_materials_cache_finish(EEVEE_ViewLayerData *UNUSED(sldata), EEVEE_Data *vedata) diff --git a/source/blender/draw/engines/eevee/eevee_private.h b/source/blender/draw/engines/eevee/eevee_private.h index 766e721b1b8..883d2eff852 100644 --- a/source/blender/draw/engines/eevee/eevee_private.h +++ b/source/blender/draw/engines/eevee/eevee_private.h @@ -1385,9 +1385,9 @@ void EEVEE_cryptomatte_cache_populate(EEVEE_Data *vedata, EEVEE_ViewLayerData *s void EEVEE_cryptomatte_particle_hair_cache_populate(EEVEE_Data *vedata, EEVEE_ViewLayerData *sldata, Object *ob); -void EEVEE_cryptomatte_object_hair_cache_populate(EEVEE_Data *vedata, - EEVEE_ViewLayerData *sldata, - Object *ob); +void EEVEE_cryptomatte_object_curves_cache_populate(EEVEE_Data *vedata, + EEVEE_ViewLayerData *sldata, + Object *ob); void EEVEE_cryptomatte_output_accumulate(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata); /** * Register the render passes needed for cryptomatte diff --git a/source/blender/draw/engines/eevee/eevee_render.c b/source/blender/draw/engines/eevee/eevee_render.c index e4e7f6fa4e3..2fd033b6745 100644 --- a/source/blender/draw/engines/eevee/eevee_render.c +++ b/source/blender/draw/engines/eevee/eevee_render.c @@ -244,10 +244,10 @@ void EEVEE_render_cache(void *vedata, EEVEE_cryptomatte_cache_populate(data, sldata, ob); } } - else if (ob->type == OB_HAIR) { + else if (ob->type == OB_CURVES) { EEVEE_object_hair_cache_populate(vedata, sldata, ob, &cast_shadow); if (do_cryptomatte) { - EEVEE_cryptomatte_object_hair_cache_populate(data, sldata, ob); + EEVEE_cryptomatte_object_curves_cache_populate(data, sldata, ob); } } else if (ob->type == OB_VOLUME) { diff --git a/source/blender/draw/engines/image/image_partial_updater.hh b/source/blender/draw/engines/image/image_partial_updater.hh index f0c1db2331a..e74c31e9e8a 100644 --- a/source/blender/draw/engines/image/image_partial_updater.hh +++ b/source/blender/draw/engines/image/image_partial_updater.hh @@ -32,11 +32,11 @@ struct PartialImageUpdater { /** * \brief Ensure that there is a partial update user for the given image. */ - void ensure_image(const Image *image) + void ensure_image(const Image *new_image) { - if (!is_valid(image)) { + if (!is_valid(new_image)) { free(); - create(image); + create(new_image); } } @@ -60,11 +60,11 @@ struct PartialImageUpdater { return user != nullptr; } - void create(const Image *image) + void create(const Image *new_image) { BLI_assert(user == nullptr); - user = BKE_image_partial_update_create(image); - image = image; + user = BKE_image_partial_update_create(new_image); + image = new_image; } void free() diff --git a/source/blender/draw/engines/overlay/overlay_armature.c b/source/blender/draw/engines/overlay/overlay_armature.c index ccf8f9e0c36..f9694b329aa 100644 --- a/source/blender/draw/engines/overlay/overlay_armature.c +++ b/source/blender/draw/engines/overlay/overlay_armature.c @@ -2038,6 +2038,128 @@ static void draw_bone_name(ArmatureDrawContext *ctx, /** \} */ /* -------------------------------------------------------------------- */ +/** \name Pose Bone Culling + * + * Used for selection since drawing many bones can be slow, see: T91253. + * + * Bounding spheres are used with margins added to ensure bones are included. + * An added margin is needed because #BKE_pchan_minmax only returns the bounds + * of the bones head & tail which doesn't account for parts of the bone users may select + * (octahedral spheres or envelope radius for example). + * \{ */ + +static void pchan_culling_calc_bsphere(const Object *ob, + const bPoseChannel *pchan, + BoundSphere *r_bsphere) +{ + float min[3], max[3]; + INIT_MINMAX(min, max); + BKE_pchan_minmax(ob, pchan, min, max); + mid_v3_v3v3(r_bsphere->center, min, max); + r_bsphere->radius = len_v3v3(min, r_bsphere->center); +} + +/** + * \return true when bounding sphere from `pchan` intersect the view. + * (same for other "test" functions defined here). + */ +static bool pchan_culling_test_simple(const DRWView *view, + const Object *ob, + const bPoseChannel *pchan) +{ + BoundSphere bsphere; + pchan_culling_calc_bsphere(ob, pchan, &bsphere); + return DRW_culling_sphere_test(view, &bsphere); +} + +static bool pchan_culling_test_with_radius_scale(const DRWView *view, + const Object *ob, + const bPoseChannel *pchan, + const float scale) +{ + BoundSphere bsphere; + pchan_culling_calc_bsphere(ob, pchan, &bsphere); + bsphere.radius *= scale; + return DRW_culling_sphere_test(view, &bsphere); +} + +static bool pchan_culling_test_custom(const DRWView *view, + const Object *ob, + const bPoseChannel *pchan) +{ + /* For more aggressive culling the bounding box of the custom-object could be used. */ + return pchan_culling_test_simple(view, ob, pchan); +} + +static bool pchan_culling_test_wire(const DRWView *view, + const Object *ob, + const bPoseChannel *pchan) +{ + BLI_assert(((const bArmature *)ob->data)->drawtype == ARM_WIRE); + return pchan_culling_test_simple(view, ob, pchan); +} + +static bool pchan_culling_test_line(const DRWView *view, + const Object *ob, + const bPoseChannel *pchan) +{ + BLI_assert(((const bArmature *)ob->data)->drawtype == ARM_LINE); + /* Account for the end-points, as the line end-points size is in pixels, this is a rough value. + * Since the end-points are small the difference between having any margin or not is unlikely + * to be noticeable. */ + const float scale = 1.1f; + return pchan_culling_test_with_radius_scale(view, ob, pchan, scale); +} + +static bool pchan_culling_test_envelope(const DRWView *view, + const Object *ob, + const bPoseChannel *pchan) +{ + const bArmature *arm = ob->data; + BLI_assert(arm->drawtype == ARM_ENVELOPE); + UNUSED_VARS_NDEBUG(arm); + BoundSphere bsphere; + pchan_culling_calc_bsphere(ob, pchan, &bsphere); + bsphere.radius += max_ff(pchan->bone->rad_head, pchan->bone->rad_tail) * + mat4_to_size_max_axis(ob->obmat) * mat4_to_size_max_axis(pchan->disp_mat); + return DRW_culling_sphere_test(view, &bsphere); +} + +static bool pchan_culling_test_bbone(const DRWView *view, + const Object *ob, + const bPoseChannel *pchan) +{ + const bArmature *arm = ob->data; + BLI_assert(arm->drawtype == ARM_B_BONE); + UNUSED_VARS_NDEBUG(arm); + const float ob_scale = mat4_to_size_max_axis(ob->obmat); + const Mat4 *bbones_mat = (const Mat4 *)pchan->draw_data->bbone_matrix; + for (int i = pchan->bone->segments; i--; bbones_mat++) { + BoundSphere bsphere; + float size[3]; + mat4_to_size(size, bbones_mat->mat); + copy_v3_v3(bsphere.center, bbones_mat->mat[3]); + bsphere.radius = len_v3(size) * ob_scale; + if (DRW_culling_sphere_test(view, &bsphere)) { + return true; + } + } + return false; +} + +static bool pchan_culling_test_octohedral(const DRWView *view, + const Object *ob, + const bPoseChannel *pchan) +{ + /* No type assertion as this is a fallback (files from the future will end up here). */ + /* Account for spheres on the end-points. */ + const float scale = 1.2f; + return pchan_culling_test_with_radius_scale(view, ob, pchan, scale); +} + +/** \} */ + +/* -------------------------------------------------------------------- */ /** \name Main Draw Loops * \{ */ @@ -2185,6 +2307,8 @@ static void draw_armature_pose(ArmatureDrawContext *ctx) } } + const DRWView *view = is_pose_select ? DRW_view_default_get() : NULL; + for (pchan = ob->pose->chanbase.first; pchan; pchan = pchan->next, index += 0x10000) { Bone *bone = pchan->bone; const bool bone_visible = (bone->flag & (BONE_HIDDEN_P | BONE_HIDDEN_PG)) == 0; @@ -2225,27 +2349,39 @@ static void draw_armature_pose(ArmatureDrawContext *ctx) if ((pchan->custom) && !(arm->flag & ARM_NO_CUSTOM)) { draw_bone_update_disp_matrix_custom(pchan); - draw_bone_custom_shape(ctx, NULL, pchan, arm, boneflag, constflag, select_id); + if (!is_pose_select || pchan_culling_test_custom(view, ob, pchan)) { + draw_bone_custom_shape(ctx, NULL, pchan, arm, boneflag, constflag, select_id); + } } else if (arm->drawtype == ARM_ENVELOPE) { draw_bone_update_disp_matrix_default(NULL, pchan); - draw_bone_envelope(ctx, NULL, pchan, arm, boneflag, constflag, select_id); + if (!is_pose_select || pchan_culling_test_envelope(view, ob, pchan)) { + draw_bone_envelope(ctx, NULL, pchan, arm, boneflag, constflag, select_id); + } } else if (arm->drawtype == ARM_LINE) { draw_bone_update_disp_matrix_default(NULL, pchan); - draw_bone_line(ctx, NULL, pchan, arm, boneflag, constflag, select_id); + if (!is_pose_select || pchan_culling_test_line(view, ob, pchan)) { + draw_bone_line(ctx, NULL, pchan, arm, boneflag, constflag, select_id); + } } else if (arm->drawtype == ARM_WIRE) { draw_bone_update_disp_matrix_bbone(NULL, pchan); - draw_bone_wire(ctx, NULL, pchan, arm, boneflag, constflag, select_id); + if (!is_pose_select || pchan_culling_test_wire(view, ob, pchan)) { + draw_bone_wire(ctx, NULL, pchan, arm, boneflag, constflag, select_id); + } } else if (arm->drawtype == ARM_B_BONE) { draw_bone_update_disp_matrix_bbone(NULL, pchan); - draw_bone_box(ctx, NULL, pchan, arm, boneflag, constflag, select_id); + if (!is_pose_select || pchan_culling_test_bbone(view, ob, pchan)) { + draw_bone_box(ctx, NULL, pchan, arm, boneflag, constflag, select_id); + } } else { draw_bone_update_disp_matrix_default(NULL, pchan); - draw_bone_octahedral(ctx, NULL, pchan, arm, boneflag, constflag, select_id); + if (!is_pose_select || pchan_culling_test_octohedral(view, ob, pchan)) { + draw_bone_octahedral(ctx, NULL, pchan, arm, boneflag, constflag, select_id); + } } /* These aren't included in the selection. */ diff --git a/source/blender/draw/engines/overlay/overlay_engine.c b/source/blender/draw/engines/overlay/overlay_engine.c index 12db2bd02cf..54e8ef80854 100644 --- a/source/blender/draw/engines/overlay/overlay_engine.c +++ b/source/blender/draw/engines/overlay/overlay_engine.c @@ -262,7 +262,7 @@ static bool overlay_object_is_edit_mode(const OVERLAY_PrivateData *pd, const Obj return pd->ctx_mode == CTX_MODE_EDIT_METABALL; case OB_FONT: return pd->ctx_mode == CTX_MODE_EDIT_TEXT; - case OB_HAIR: + case OB_CURVES: case OB_POINTCLOUD: case OB_VOLUME: /* No edit mode yet. */ @@ -316,7 +316,7 @@ static void OVERLAY_cache_populate(void *vedata, Object *ob) OB_MBALL, OB_FONT, OB_GPENCIL, - OB_HAIR, + OB_CURVES, OB_POINTCLOUD, OB_VOLUME); const bool draw_surface = (ob->dt >= OB_WIRE) && (renderable || (ob->dt == OB_WIRE)); diff --git a/source/blender/draw/engines/overlay/overlay_extra.c b/source/blender/draw/engines/overlay/overlay_extra.c index a2362cd8850..de0003625a2 100644 --- a/source/blender/draw/engines/overlay/overlay_extra.c +++ b/source/blender/draw/engines/overlay/overlay_extra.c @@ -484,7 +484,7 @@ static void OVERLAY_texture_space(OVERLAY_ExtraCallBuffers *cb, Object *ob, cons texcosize = mb->size; break; } - case ID_HA: + case ID_CV: case ID_PT: case ID_VO: { /* No user defined texture space support. */ diff --git a/source/blender/draw/engines/workbench/workbench_engine.c b/source/blender/draw/engines/workbench/workbench_engine.c index 0dfc3c4b119..8773c78e82f 100644 --- a/source/blender/draw/engines/workbench/workbench_engine.c +++ b/source/blender/draw/engines/workbench/workbench_engine.c @@ -34,8 +34,8 @@ #include "BKE_paint.h" #include "BKE_particle.h" +#include "DNA_curves_types.h" #include "DNA_fluid_types.h" -#include "DNA_hair_types.h" #include "DNA_image_types.h" #include "DNA_mesh_types.h" #include "DNA_modifier_types.h" @@ -419,9 +419,9 @@ void workbench_cache_populate(void *ved, Object *ob) workbench_shadow_cache_populate(vedata, ob, has_transp_mat); } } - else if (ob->type == OB_HAIR) { + else if (ob->type == OB_CURVES) { int color_type = workbench_color_type_get(wpd, ob, NULL, NULL, NULL); - workbench_cache_hair_populate(wpd, ob, NULL, NULL, color_type, false, HAIR_MATERIAL_NR); + workbench_cache_hair_populate(wpd, ob, NULL, NULL, color_type, false, CURVES_MATERIAL_NR); } else if (ob->type == OB_VOLUME) { if (wpd->shading.type != OB_WIRE) { diff --git a/source/blender/draw/intern/draw_cache.c b/source/blender/draw/intern/draw_cache.c index a4564ce2668..430b28f1224 100644 --- a/source/blender/draw/intern/draw_cache.c +++ b/source/blender/draw/intern/draw_cache.c @@ -19,7 +19,7 @@ */ #include "DNA_curve_types.h" -#include "DNA_hair_types.h" +#include "DNA_curves_types.h" #include "DNA_lattice_types.h" #include "DNA_mesh_types.h" #include "DNA_meta_types.h" @@ -835,7 +835,7 @@ GPUBatch *DRW_cache_object_edge_detection_get(Object *ob, bool *r_is_manifold) return NULL; case OB_MBALL: return DRW_cache_mball_edge_detection_get(ob, r_is_manifold); - case OB_HAIR: + case OB_CURVES: return NULL; case OB_POINTCLOUD: return NULL; @@ -859,7 +859,7 @@ GPUBatch *DRW_cache_object_face_wireframe_get(Object *ob) return NULL; case OB_MBALL: return DRW_cache_mball_face_wireframe_get(ob); - case OB_HAIR: + case OB_CURVES: return NULL; case OB_POINTCLOUD: return DRW_pointcloud_batch_cache_get_dots(ob); @@ -886,7 +886,7 @@ GPUBatch *DRW_cache_object_loose_edges_get(struct Object *ob) return NULL; case OB_MBALL: return NULL; - case OB_HAIR: + case OB_CURVES: return NULL; case OB_POINTCLOUD: return NULL; @@ -910,7 +910,7 @@ GPUBatch *DRW_cache_object_surface_get(Object *ob) return NULL; case OB_MBALL: return DRW_cache_mball_surface_get(ob); - case OB_HAIR: + case OB_CURVES: return NULL; case OB_POINTCLOUD: return DRW_cache_pointcloud_surface_get(ob); @@ -935,7 +935,7 @@ GPUVertBuf *DRW_cache_object_pos_vertbuf_get(Object *ob) return DRW_curve_batch_cache_pos_vertbuf_get(ob->data); case OB_MBALL: return DRW_mball_batch_cache_pos_vertbuf_get(ob); - case OB_HAIR: + case OB_CURVES: return NULL; case OB_POINTCLOUD: return NULL; @@ -967,8 +967,8 @@ int DRW_cache_object_material_count_get(struct Object *ob) return DRW_curve_material_count_get(ob->data); case OB_MBALL: return DRW_metaball_material_count_get(ob->data); - case OB_HAIR: - return DRW_hair_material_count_get(ob->data); + case OB_CURVES: + return DRW_curves_material_count_get(ob->data); case OB_POINTCLOUD: return DRW_pointcloud_material_count_get(ob->data); case OB_VOLUME: @@ -994,7 +994,7 @@ GPUBatch **DRW_cache_object_surface_material_get(struct Object *ob, return NULL; case OB_MBALL: return DRW_cache_mball_surface_shaded_get(ob, gpumat_array, gpumat_array_len); - case OB_HAIR: + case OB_CURVES: return NULL; case OB_POINTCLOUD: return DRW_cache_pointcloud_surface_shaded_get(ob, gpumat_array, gpumat_array_len); @@ -3403,8 +3403,8 @@ void drw_batch_cache_validate(Object *ob) case OB_LATTICE: DRW_lattice_batch_cache_validate((Lattice *)ob->data); break; - case OB_HAIR: - DRW_hair_batch_cache_validate((Hair *)ob->data); + case OB_CURVES: + DRW_curves_batch_cache_validate((Curves *)ob->data); break; case OB_POINTCLOUD: DRW_pointcloud_batch_cache_validate((PointCloud *)ob->data); diff --git a/source/blender/draw/intern/draw_cache.h b/source/blender/draw/intern/draw_cache.h index 30e5a10df91..b94dd466364 100644 --- a/source/blender/draw/intern/draw_cache.h +++ b/source/blender/draw/intern/draw_cache.h @@ -246,14 +246,14 @@ struct GPUBatch **DRW_cache_mball_surface_shaded_get(struct Object *ob, struct GPUBatch *DRW_cache_mball_face_wireframe_get(struct Object *ob); struct GPUBatch *DRW_cache_mball_edge_detection_get(struct Object *ob, bool *r_is_manifold); -/* Hair */ - -struct GPUBatch *DRW_cache_hair_surface_get(struct Object *ob); -struct GPUBatch **DRW_cache_hair_surface_shaded_get(struct Object *ob, - struct GPUMaterial **gpumat_array, - uint gpumat_array_len); -struct GPUBatch *DRW_cache_hair_face_wireframe_get(struct Object *ob); -struct GPUBatch *DRW_cache_hair_edge_detection_get(struct Object *ob, bool *r_is_manifold); +/* Curves */ + +struct GPUBatch *DRW_cache_curves_surface_get(struct Object *ob); +struct GPUBatch **DRW_cache_curves_surface_shaded_get(struct Object *ob, + struct GPUMaterial **gpumat_array, + uint gpumat_array_len); +struct GPUBatch *DRW_cache_curves_face_wireframe_get(struct Object *ob); +struct GPUBatch *DRW_cache_curves_edge_detection_get(struct Object *ob, bool *r_is_manifold); /* PointCloud */ diff --git a/source/blender/draw/intern/draw_cache_impl.h b/source/blender/draw/intern/draw_cache_impl.h index 6a2f4b91ad1..9c6814d910e 100644 --- a/source/blender/draw/intern/draw_cache_impl.h +++ b/source/blender/draw/intern/draw_cache_impl.h @@ -33,7 +33,7 @@ struct ParticleSystem; struct TaskGraph; struct Curve; -struct Hair; +struct Curves; struct Lattice; struct Mesh; struct MetaBall; @@ -73,9 +73,9 @@ void DRW_particle_batch_cache_free(struct ParticleSystem *psys); void DRW_gpencil_batch_cache_dirty_tag(struct bGPdata *gpd); void DRW_gpencil_batch_cache_free(struct bGPdata *gpd); -void DRW_hair_batch_cache_dirty_tag(struct Hair *hair, int mode); -void DRW_hair_batch_cache_validate(struct Hair *hair); -void DRW_hair_batch_cache_free(struct Hair *hair); +void DRW_curves_batch_cache_dirty_tag(struct Curves *curves, int mode); +void DRW_curves_batch_cache_validate(struct Curves *curves); +void DRW_curves_batch_cache_free(struct Curves *curves); void DRW_pointcloud_batch_cache_dirty_tag(struct PointCloud *pointcloud, int mode); void DRW_pointcloud_batch_cache_validate(struct PointCloud *pointcloud); @@ -188,7 +188,7 @@ struct GPUBatch *DRW_lattice_batch_cache_get_edit_verts(struct Lattice *lt); /** \name Hair * \{ */ -int DRW_hair_material_count_get(struct Hair *hair); +int DRW_curves_material_count_get(struct Curves *curves); /** \} */ diff --git a/source/blender/draw/intern/draw_cache_impl_hair.cc b/source/blender/draw/intern/draw_cache_impl_curves.cc index cdc06b121b0..8ec97495fcf 100644 --- a/source/blender/draw/intern/draw_cache_impl_hair.cc +++ b/source/blender/draw/intern/draw_cache_impl_curves.cc @@ -35,10 +35,10 @@ #include "BLI_span.hh" #include "BLI_utildefines.h" -#include "DNA_hair_types.h" +#include "DNA_curves_types.h" #include "DNA_object_types.h" -#include "BKE_hair.h" +#include "BKE_curves.h" #include "GPU_batch.h" #include "GPU_material.h" @@ -51,7 +51,7 @@ using blender::float3; using blender::IndexRange; using blender::Span; -static void hair_batch_cache_clear(Hair *hair); +static void curves_batch_cache_clear(Curves *curves); /* ---------------------------------------------------------------------- */ /* Hair GPUBatch Cache */ @@ -65,19 +65,19 @@ struct HairBatchCache { /* GPUBatch cache management. */ -static bool hair_batch_cache_valid(Hair *hair) +static bool curves_batch_cache_valid(Curves *curves) { - HairBatchCache *cache = static_cast<HairBatchCache *>(hair->batch_cache); + HairBatchCache *cache = static_cast<HairBatchCache *>(curves->batch_cache); return (cache && cache->is_dirty == false); } -static void hair_batch_cache_init(Hair *hair) +static void curves_batch_cache_init(Curves *curves) { - HairBatchCache *cache = static_cast<HairBatchCache *>(hair->batch_cache); + HairBatchCache *cache = static_cast<HairBatchCache *>(curves->batch_cache); if (!cache) { cache = MEM_cnew<HairBatchCache>(__func__); - hair->batch_cache = cache; + curves->batch_cache = cache; } else { memset(cache, 0, sizeof(*cache)); @@ -86,28 +86,28 @@ static void hair_batch_cache_init(Hair *hair) cache->is_dirty = false; } -void DRW_hair_batch_cache_validate(Hair *hair) +void DRW_curves_batch_cache_validate(Curves *curves) { - if (!hair_batch_cache_valid(hair)) { - hair_batch_cache_clear(hair); - hair_batch_cache_init(hair); + if (!curves_batch_cache_valid(curves)) { + curves_batch_cache_clear(curves); + curves_batch_cache_init(curves); } } -static HairBatchCache *hair_batch_cache_get(Hair *hair) +static HairBatchCache *curves_batch_cache_get(Curves *curves) { - DRW_hair_batch_cache_validate(hair); - return static_cast<HairBatchCache *>(hair->batch_cache); + DRW_curves_batch_cache_validate(curves); + return static_cast<HairBatchCache *>(curves->batch_cache); } -void DRW_hair_batch_cache_dirty_tag(Hair *hair, int mode) +void DRW_curves_batch_cache_dirty_tag(Curves *curves, int mode) { - HairBatchCache *cache = static_cast<HairBatchCache *>(hair->batch_cache); + HairBatchCache *cache = static_cast<HairBatchCache *>(curves->batch_cache); if (cache == nullptr) { return; } switch (mode) { - case BKE_HAIR_BATCH_DIRTY_ALL: + case BKE_CURVES_BATCH_DIRTY_ALL: cache->is_dirty = true; break; default: @@ -115,9 +115,9 @@ void DRW_hair_batch_cache_dirty_tag(Hair *hair, int mode) } } -static void hair_batch_cache_clear(Hair *hair) +static void curves_batch_cache_clear(Curves *curves) { - HairBatchCache *cache = static_cast<HairBatchCache *>(hair->batch_cache); + HairBatchCache *cache = static_cast<HairBatchCache *>(curves->batch_cache); if (!cache) { return; } @@ -125,33 +125,33 @@ static void hair_batch_cache_clear(Hair *hair) particle_batch_cache_clear_hair(&cache->hair); } -void DRW_hair_batch_cache_free(Hair *hair) +void DRW_curves_batch_cache_free(Curves *curves) { - hair_batch_cache_clear(hair); - MEM_SAFE_FREE(hair->batch_cache); + curves_batch_cache_clear(curves); + MEM_SAFE_FREE(curves->batch_cache); } -static void ensure_seg_pt_count(Hair *hair, ParticleHairCache *hair_cache) +static void ensure_seg_pt_count(Curves *curves, ParticleHairCache *curves_cache) { - if ((hair_cache->pos != nullptr && hair_cache->indices != nullptr) || - (hair_cache->proc_point_buf != nullptr)) { + if ((curves_cache->pos != nullptr && curves_cache->indices != nullptr) || + (curves_cache->proc_point_buf != nullptr)) { return; } - hair_cache->strands_len = hair->geometry.curve_size; - hair_cache->elems_len = hair->geometry.point_size + hair->geometry.curve_size; - hair_cache->point_len = hair->geometry.point_size; + curves_cache->strands_len = curves->geometry.curve_size; + curves_cache->elems_len = curves->geometry.point_size + curves->geometry.curve_size; + curves_cache->point_len = curves->geometry.point_size; } -static void hair_batch_cache_fill_segments_proc_pos(Hair *hair, - GPUVertBufRaw *attr_step, - GPUVertBufRaw *length_step) +static void curves_batch_cache_fill_segments_proc_pos(Curves *curves, + GPUVertBufRaw *attr_step, + GPUVertBufRaw *length_step) { /* TODO: use hair radius layer if available. */ - const int curve_size = hair->geometry.curve_size; - Span<int> offsets{hair->geometry.offsets, hair->geometry.curve_size + 1}; + const int curve_size = curves->geometry.curve_size; + Span<int> offsets{curves->geometry.offsets, curves->geometry.curve_size + 1}; - Span<float3> positions{(float3 *)hair->geometry.position, hair->geometry.point_size}; + Span<float3> positions{(float3 *)curves->geometry.position, curves->geometry.point_size}; for (const int i : IndexRange(curve_size)) { const IndexRange curve_range(offsets[i], offsets[i + 1] - offsets[i]); @@ -183,9 +183,9 @@ static void hair_batch_cache_fill_segments_proc_pos(Hair *hair, } } -static void hair_batch_cache_ensure_procedural_pos(Hair *hair, - ParticleHairCache *cache, - GPUMaterial *gpu_material) +static void curves_batch_cache_ensure_procedural_pos(Curves *curves, + ParticleHairCache *cache, + GPUMaterial *gpu_material) { if (cache->proc_point_buf == nullptr) { /* initialize vertex format */ @@ -208,7 +208,7 @@ static void hair_batch_cache_ensure_procedural_pos(Hair *hair, GPUVertBufRaw length_step; GPU_vertbuf_attr_get_raw_data(cache->proc_length_buf, length_id, &length_step); - hair_batch_cache_fill_segments_proc_pos(hair, &point_step, &length_step); + curves_batch_cache_fill_segments_proc_pos(curves, &point_step, &length_step); /* Create vbo immediately to bind to texture buffer. */ GPU_vertbuf_use(cache->proc_point_buf); @@ -227,12 +227,12 @@ static void hair_batch_cache_ensure_procedural_pos(Hair *hair, } } -static void hair_batch_cache_fill_strands_data(Hair *hair, - GPUVertBufRaw *data_step, - GPUVertBufRaw *seg_step) +static void curves_batch_cache_fill_strands_data(Curves *curves, + GPUVertBufRaw *data_step, + GPUVertBufRaw *seg_step) { - const int curve_size = hair->geometry.curve_size; - Span<int> offsets{hair->geometry.offsets, hair->geometry.curve_size + 1}; + const int curve_size = curves->geometry.curve_size; + Span<int> offsets{curves->geometry.offsets, curves->geometry.curve_size + 1}; for (const int i : IndexRange(curve_size)) { const IndexRange curve_range(offsets[i], offsets[i + 1] - offsets[i]); @@ -242,7 +242,8 @@ static void hair_batch_cache_fill_strands_data(Hair *hair, } } -static void hair_batch_cache_ensure_procedural_strand_data(Hair *hair, ParticleHairCache *cache) +static void curves_batch_cache_ensure_procedural_strand_data(Curves *curves, + ParticleHairCache *cache) { GPUVertBufRaw data_step, seg_step; @@ -261,18 +262,18 @@ static void hair_batch_cache_ensure_procedural_strand_data(Hair *hair, ParticleH GPU_vertbuf_data_alloc(cache->proc_strand_seg_buf, cache->strands_len); GPU_vertbuf_attr_get_raw_data(cache->proc_strand_seg_buf, seg_id, &seg_step); - hair_batch_cache_fill_strands_data(hair, &data_step, &seg_step); + curves_batch_cache_fill_strands_data(curves, &data_step, &seg_step); /* Create vbo immediately to bind to texture buffer. */ GPU_vertbuf_use(cache->proc_strand_buf); - cache->strand_tex = GPU_texture_create_from_vertbuf("hair_strand", cache->proc_strand_buf); + cache->strand_tex = GPU_texture_create_from_vertbuf("curves_strand", cache->proc_strand_buf); GPU_vertbuf_use(cache->proc_strand_seg_buf); - cache->strand_seg_tex = GPU_texture_create_from_vertbuf("hair_strand_seg", + cache->strand_seg_tex = GPU_texture_create_from_vertbuf("curves_strand_seg", cache->proc_strand_seg_buf); } -static void hair_batch_cache_ensure_procedural_final_points(ParticleHairCache *cache, int subdiv) +static void curves_batch_cache_ensure_procedural_final_points(ParticleHairCache *cache, int subdiv) { /* Same format as point_tex. */ GPUVertFormat format = {0}; @@ -293,11 +294,11 @@ static void hair_batch_cache_ensure_procedural_final_points(ParticleHairCache *c cache->final[subdiv].proc_buf); } -static void hair_batch_cache_fill_segments_indices(Hair *hair, - const int res, - GPUIndexBufBuilder *elb) +static void curves_batch_cache_fill_segments_indices(Curves *curves, + const int res, + GPUIndexBufBuilder *elb) { - const int curve_size = hair->geometry.curve_size; + const int curve_size = curves->geometry.curve_size; uint curr_point = 0; @@ -309,10 +310,10 @@ static void hair_batch_cache_fill_segments_indices(Hair *hair, } } -static void hair_batch_cache_ensure_procedural_indices(Hair *hair, - ParticleHairCache *cache, - int thickness_res, - int subdiv) +static void curves_batch_cache_ensure_procedural_indices(Curves *curves, + ParticleHairCache *cache, + int thickness_res, + int subdiv) { BLI_assert(thickness_res <= MAX_THICKRES); /* Cylinder strip not currently supported. */ @@ -337,7 +338,7 @@ static void hair_batch_cache_ensure_procedural_indices(Hair *hair, GPUIndexBufBuilder elb; GPU_indexbuf_init_ex(&elb, prim_type, element_count, element_count); - hair_batch_cache_fill_segments_indices(hair, verts_per_hair, &elb); + curves_batch_cache_fill_segments_indices(curves, verts_per_hair, &elb); cache->final[subdiv].proc_hairs[thickness_res - 1] = GPU_batch_create_ex( prim_type, vbo, GPU_indexbuf_build(&elb), GPU_BATCH_OWNS_VBO | GPU_BATCH_OWNS_INDEX); @@ -350,9 +351,9 @@ bool hair_ensure_procedural_data(Object *object, int thickness_res) { bool need_ft_update = false; - Hair *hair = static_cast<Hair *>(object->data); + Curves *curves = static_cast<Curves *>(object->data); - HairBatchCache *cache = hair_batch_cache_get(hair); + HairBatchCache *cache = curves_batch_cache_get(curves); *r_hair_cache = &cache->hair; const int steps = 2; /* TODO: don't hard-code? */ @@ -360,29 +361,29 @@ bool hair_ensure_procedural_data(Object *object, /* Refreshed on combing and simulation. */ if ((*r_hair_cache)->proc_point_buf == nullptr) { - ensure_seg_pt_count(hair, &cache->hair); - hair_batch_cache_ensure_procedural_pos(hair, &cache->hair, gpu_material); + ensure_seg_pt_count(curves, &cache->hair); + curves_batch_cache_ensure_procedural_pos(curves, &cache->hair, gpu_material); need_ft_update = true; } /* Refreshed if active layer or custom data changes. */ if ((*r_hair_cache)->strand_tex == nullptr) { - hair_batch_cache_ensure_procedural_strand_data(hair, &cache->hair); + curves_batch_cache_ensure_procedural_strand_data(curves, &cache->hair); } /* Refreshed only on subdiv count change. */ if ((*r_hair_cache)->final[subdiv].proc_buf == nullptr) { - hair_batch_cache_ensure_procedural_final_points(&cache->hair, subdiv); + curves_batch_cache_ensure_procedural_final_points(&cache->hair, subdiv); need_ft_update = true; } if ((*r_hair_cache)->final[subdiv].proc_hairs[thickness_res - 1] == nullptr) { - hair_batch_cache_ensure_procedural_indices(hair, &cache->hair, thickness_res, subdiv); + curves_batch_cache_ensure_procedural_indices(curves, &cache->hair, thickness_res, subdiv); } return need_ft_update; } -int DRW_hair_material_count_get(Hair *hair) +int DRW_curves_material_count_get(Curves *curves) { - return max_ii(1, hair->totcol); + return max_ii(1, curves->totcol); } diff --git a/source/blender/draw/intern/draw_cache_impl_subdivision.cc b/source/blender/draw/intern/draw_cache_impl_subdivision.cc index 4a8670a9ee2..56184f20f7b 100644 --- a/source/blender/draw/intern/draw_cache_impl_subdivision.cc +++ b/source/blender/draw/intern/draw_cache_impl_subdivision.cc @@ -820,6 +820,7 @@ static void draw_subdiv_edge_cb(const SubdivForeachContext *foreach_context, void *UNUSED(tls), const int coarse_edge_index, const int subdiv_edge_index, + const bool UNUSED(is_loose), const int UNUSED(subdiv_v1), const int UNUSED(subdiv_v2)) { diff --git a/source/blender/draw/intern/draw_common.c b/source/blender/draw/intern/draw_common.c index 65afc5ed3d8..82b830f6799 100644 --- a/source/blender/draw/intern/draw_common.c +++ b/source/blender/draw/intern/draw_common.c @@ -431,7 +431,7 @@ bool DRW_object_is_flat(Object *ob, int *r_axis) OB_SURF, OB_FONT, OB_MBALL, - OB_HAIR, + OB_CURVES, OB_POINTCLOUD, OB_VOLUME)) { /* Non-meshes object cannot be considered as flat. */ diff --git a/source/blender/draw/intern/draw_manager.c b/source/blender/draw/intern/draw_manager.c index 1249004eda0..039fae43329 100644 --- a/source/blender/draw/intern/draw_manager.c +++ b/source/blender/draw/intern/draw_manager.c @@ -35,11 +35,11 @@ #include "BKE_colortools.h" #include "BKE_context.h" #include "BKE_curve.h" +#include "BKE_curves.h" #include "BKE_duplilist.h" #include "BKE_editmesh.h" #include "BKE_global.h" #include "BKE_gpencil.h" -#include "BKE_hair.h" #include "BKE_lattice.h" #include "BKE_main.h" #include "BKE_mball.h" @@ -2948,8 +2948,8 @@ void DRW_engines_register(void) BKE_gpencil_batch_cache_dirty_tag_cb = DRW_gpencil_batch_cache_dirty_tag; BKE_gpencil_batch_cache_free_cb = DRW_gpencil_batch_cache_free; - BKE_hair_batch_cache_dirty_tag_cb = DRW_hair_batch_cache_dirty_tag; - BKE_hair_batch_cache_free_cb = DRW_hair_batch_cache_free; + BKE_curves_batch_cache_dirty_tag_cb = DRW_curves_batch_cache_dirty_tag; + BKE_curves_batch_cache_free_cb = DRW_curves_batch_cache_free; BKE_pointcloud_batch_cache_dirty_tag_cb = DRW_pointcloud_batch_cache_dirty_tag; BKE_pointcloud_batch_cache_free_cb = DRW_pointcloud_batch_cache_free; |