From fe1816f67fbc6aaf383ec77847d668367335d093 Mon Sep 17 00:00:00 2001 From: Hans Goudey Date: Mon, 7 Feb 2022 11:55:54 -0600 Subject: Curves: Rename "Hair" types, variables, and functions to "Curves" Based on discussions from T95355 and T94193, the plan is to use the name "Curves" to describe the data-block container for multiple curves. Eventually this will replace the existing "Curve" data-block. However, it will be a while before the curve data-block can be replaced so in order to distinguish the two curve types in the UI, "Hair Curves" will be used, but eventually changed back to "Curves". This patch renames "hair-related" files, functions, types, and variable names to this convention. A deep rename is preferred to keep code consistent and to avoid any "hair" terminology from leaking, since the new data-block is meant for all curve types, not just hair use cases. The downside of this naming is that the difference between "Curve" and "Curves" has become important. That was considered during design discussons and deemed acceptable, especially given the non-permanent nature of the somewhat common conflict. Some points of interest: - All DNA compatibility is lost, just like rBf59767ff9729. - I renamed `ID_HA` to `ID_CV` so there is no complete mismatch. - `hair_curves` is used where necessary to distinguish from the existing "curves" plural. - I didn't rename any of the cycles/rendering code function names, since that is also used by the old hair particle system. Differential Revision: https://developer.blender.org/D14007 --- source/blender/draw/CMakeLists.txt | 2 +- .../blender/draw/engines/eevee/eevee_cryptomatte.c | 28 +- source/blender/draw/engines/eevee/eevee_data.c | 2 +- source/blender/draw/engines/eevee/eevee_engine.c | 2 +- .../blender/draw/engines/eevee/eevee_materials.c | 4 +- source/blender/draw/engines/eevee/eevee_private.h | 6 +- source/blender/draw/engines/eevee/eevee_render.c | 4 +- .../blender/draw/engines/overlay/overlay_engine.c | 4 +- .../blender/draw/engines/overlay/overlay_extra.c | 2 +- .../draw/engines/workbench/workbench_engine.c | 6 +- source/blender/draw/intern/draw_cache.c | 22 +- source/blender/draw/intern/draw_cache.h | 16 +- source/blender/draw/intern/draw_cache_impl.h | 10 +- .../blender/draw/intern/draw_cache_impl_curves.cc | 389 +++++++++++++++++++++ source/blender/draw/intern/draw_cache_impl_hair.cc | 388 -------------------- source/blender/draw/intern/draw_common.c | 2 +- source/blender/draw/intern/draw_manager.c | 6 +- 17 files changed, 447 insertions(+), 446 deletions(-) create mode 100644 source/blender/draw/intern/draw_cache_impl_curves.cc delete mode 100644 source/blender/draw/intern/draw_cache_impl_hair.cc (limited to 'source/blender/draw') 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/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_curves.cc b/source/blender/draw/intern/draw_cache_impl_curves.cc new file mode 100644 index 00000000000..8ec97495fcf --- /dev/null +++ b/source/blender/draw/intern/draw_cache_impl_curves.cc @@ -0,0 +1,389 @@ +/* + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * The Original Code is Copyright (C) 2017 by Blender Foundation. + * All rights reserved. + */ + +/** \file + * \ingroup draw + * + * \brief Hair API for render engines + */ + +#include + +#include "MEM_guardedalloc.h" + +#include "BLI_listbase.h" +#include "BLI_math_base.h" +#include "BLI_math_vec_types.hh" +#include "BLI_math_vector.h" +#include "BLI_math_vector.hh" +#include "BLI_span.hh" +#include "BLI_utildefines.h" + +#include "DNA_curves_types.h" +#include "DNA_object_types.h" + +#include "BKE_curves.h" + +#include "GPU_batch.h" +#include "GPU_material.h" +#include "GPU_texture.h" + +#include "draw_cache_impl.h" /* own include */ +#include "draw_hair_private.h" /* own include */ + +using blender::float3; +using blender::IndexRange; +using blender::Span; + +static void curves_batch_cache_clear(Curves *curves); + +/* ---------------------------------------------------------------------- */ +/* Hair GPUBatch Cache */ + +struct HairBatchCache { + ParticleHairCache hair; + + /* settings to determine if cache is invalid */ + bool is_dirty; +}; + +/* GPUBatch cache management. */ + +static bool curves_batch_cache_valid(Curves *curves) +{ + HairBatchCache *cache = static_cast(curves->batch_cache); + return (cache && cache->is_dirty == false); +} + +static void curves_batch_cache_init(Curves *curves) +{ + HairBatchCache *cache = static_cast(curves->batch_cache); + + if (!cache) { + cache = MEM_cnew(__func__); + curves->batch_cache = cache; + } + else { + memset(cache, 0, sizeof(*cache)); + } + + cache->is_dirty = false; +} + +void DRW_curves_batch_cache_validate(Curves *curves) +{ + if (!curves_batch_cache_valid(curves)) { + curves_batch_cache_clear(curves); + curves_batch_cache_init(curves); + } +} + +static HairBatchCache *curves_batch_cache_get(Curves *curves) +{ + DRW_curves_batch_cache_validate(curves); + return static_cast(curves->batch_cache); +} + +void DRW_curves_batch_cache_dirty_tag(Curves *curves, int mode) +{ + HairBatchCache *cache = static_cast(curves->batch_cache); + if (cache == nullptr) { + return; + } + switch (mode) { + case BKE_CURVES_BATCH_DIRTY_ALL: + cache->is_dirty = true; + break; + default: + BLI_assert(0); + } +} + +static void curves_batch_cache_clear(Curves *curves) +{ + HairBatchCache *cache = static_cast(curves->batch_cache); + if (!cache) { + return; + } + + particle_batch_cache_clear_hair(&cache->hair); +} + +void DRW_curves_batch_cache_free(Curves *curves) +{ + curves_batch_cache_clear(curves); + MEM_SAFE_FREE(curves->batch_cache); +} + +static void ensure_seg_pt_count(Curves *curves, ParticleHairCache *curves_cache) +{ + if ((curves_cache->pos != nullptr && curves_cache->indices != nullptr) || + (curves_cache->proc_point_buf != nullptr)) { + return; + } + + 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 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 = curves->geometry.curve_size; + Span offsets{curves->geometry.offsets, curves->geometry.curve_size + 1}; + + Span 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]); + + Span spline_positions = positions.slice(curve_range); + float total_len = 0.0f; + float *seg_data_first; + for (const int i_spline : spline_positions.index_range()) { + float *seg_data = (float *)GPU_vertbuf_raw_step(attr_step); + copy_v3_v3(seg_data, spline_positions[i_spline]); + if (i_spline == 0) { + seg_data_first = seg_data; + } + else { + total_len += blender::math::distance(spline_positions[i_spline - 1], + spline_positions[i_spline]); + } + seg_data[3] = total_len; + } + /* Assign length value. */ + *(float *)GPU_vertbuf_raw_step(length_step) = total_len; + if (total_len > 0.0f) { + /* Divide by total length to have a [0-1] number. */ + for ([[maybe_unused]] const int i_spline : spline_positions.index_range()) { + seg_data_first[3] /= total_len; + seg_data_first += 4; + } + } + } +} + +static void curves_batch_cache_ensure_procedural_pos(Curves *curves, + ParticleHairCache *cache, + GPUMaterial *gpu_material) +{ + if (cache->proc_point_buf == nullptr) { + /* initialize vertex format */ + GPUVertFormat format = {0}; + uint pos_id = GPU_vertformat_attr_add(&format, "posTime", GPU_COMP_F32, 4, GPU_FETCH_FLOAT); + + cache->proc_point_buf = GPU_vertbuf_create_with_format(&format); + GPU_vertbuf_data_alloc(cache->proc_point_buf, cache->point_len); + + GPUVertBufRaw point_step; + GPU_vertbuf_attr_get_raw_data(cache->proc_point_buf, pos_id, &point_step); + + GPUVertFormat length_format = {0}; + uint length_id = GPU_vertformat_attr_add( + &length_format, "hairLength", GPU_COMP_F32, 1, GPU_FETCH_FLOAT); + + cache->proc_length_buf = GPU_vertbuf_create_with_format(&length_format); + GPU_vertbuf_data_alloc(cache->proc_length_buf, cache->strands_len); + + GPUVertBufRaw length_step; + GPU_vertbuf_attr_get_raw_data(cache->proc_length_buf, length_id, &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); + cache->point_tex = GPU_texture_create_from_vertbuf("hair_point", cache->proc_point_buf); + } + + if (gpu_material && cache->proc_length_buf != nullptr && cache->length_tex) { + ListBase gpu_attrs = GPU_material_attributes(gpu_material); + LISTBASE_FOREACH (GPUMaterialAttribute *, attr, &gpu_attrs) { + if (attr->type == CD_HAIRLENGTH) { + GPU_vertbuf_use(cache->proc_length_buf); + cache->length_tex = GPU_texture_create_from_vertbuf("hair_length", cache->proc_length_buf); + break; + } + } + } +} + +static void curves_batch_cache_fill_strands_data(Curves *curves, + GPUVertBufRaw *data_step, + GPUVertBufRaw *seg_step) +{ + const int curve_size = curves->geometry.curve_size; + Span 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]); + + *(uint *)GPU_vertbuf_raw_step(data_step) = curve_range.start(); + *(ushort *)GPU_vertbuf_raw_step(seg_step) = curve_range.size() - 1; + } +} + +static void curves_batch_cache_ensure_procedural_strand_data(Curves *curves, + ParticleHairCache *cache) +{ + GPUVertBufRaw data_step, seg_step; + + GPUVertFormat format_data = {0}; + uint data_id = GPU_vertformat_attr_add(&format_data, "data", GPU_COMP_U32, 1, GPU_FETCH_INT); + + GPUVertFormat format_seg = {0}; + uint seg_id = GPU_vertformat_attr_add(&format_seg, "data", GPU_COMP_U16, 1, GPU_FETCH_INT); + + /* Strand Data */ + cache->proc_strand_buf = GPU_vertbuf_create_with_format(&format_data); + GPU_vertbuf_data_alloc(cache->proc_strand_buf, cache->strands_len); + GPU_vertbuf_attr_get_raw_data(cache->proc_strand_buf, data_id, &data_step); + + cache->proc_strand_seg_buf = GPU_vertbuf_create_with_format(&format_seg); + 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); + + 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("curves_strand", cache->proc_strand_buf); + + GPU_vertbuf_use(cache->proc_strand_seg_buf); + cache->strand_seg_tex = GPU_texture_create_from_vertbuf("curves_strand_seg", + cache->proc_strand_seg_buf); +} + +static void curves_batch_cache_ensure_procedural_final_points(ParticleHairCache *cache, int subdiv) +{ + /* Same format as point_tex. */ + GPUVertFormat format = {0}; + GPU_vertformat_attr_add(&format, "pos", GPU_COMP_F32, 4, GPU_FETCH_FLOAT); + + cache->final[subdiv].proc_buf = GPU_vertbuf_create_with_format_ex(&format, + GPU_USAGE_DEVICE_ONLY); + + /* Create a destination buffer for the transform feedback. Sized appropriately */ + /* Those are points! not line segments. */ + GPU_vertbuf_data_alloc(cache->final[subdiv].proc_buf, + cache->final[subdiv].strands_res * cache->strands_len); + + /* Create vbo immediately to bind to texture buffer. */ + GPU_vertbuf_use(cache->final[subdiv].proc_buf); + + cache->final[subdiv].proc_tex = GPU_texture_create_from_vertbuf("hair_proc", + cache->final[subdiv].proc_buf); +} + +static void curves_batch_cache_fill_segments_indices(Curves *curves, + const int res, + GPUIndexBufBuilder *elb) +{ + const int curve_size = curves->geometry.curve_size; + + uint curr_point = 0; + + for ([[maybe_unused]] const int i : IndexRange(curve_size)) { + for (int k = 0; k < res; k++) { + GPU_indexbuf_add_generic_vert(elb, curr_point++); + } + GPU_indexbuf_add_primitive_restart(elb); + } +} + +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. */ + + if (cache->final[subdiv].proc_hairs[thickness_res - 1] != nullptr) { + return; + } + + int verts_per_hair = cache->final[subdiv].strands_res * thickness_res; + /* +1 for primitive restart */ + int element_count = (verts_per_hair + 1) * cache->strands_len; + GPUPrimType prim_type = (thickness_res == 1) ? GPU_PRIM_LINE_STRIP : GPU_PRIM_TRI_STRIP; + + static GPUVertFormat format = {0}; + GPU_vertformat_clear(&format); + + /* initialize vertex format */ + GPU_vertformat_attr_add(&format, "dummy", GPU_COMP_U8, 1, GPU_FETCH_INT_TO_FLOAT_UNIT); + + GPUVertBuf *vbo = GPU_vertbuf_create_with_format(&format); + GPU_vertbuf_data_alloc(vbo, 1); + + GPUIndexBufBuilder elb; + GPU_indexbuf_init_ex(&elb, prim_type, element_count, element_count); + + 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); +} + +bool hair_ensure_procedural_data(Object *object, + ParticleHairCache **r_hair_cache, + GPUMaterial *gpu_material, + int subdiv, + int thickness_res) +{ + bool need_ft_update = false; + Curves *curves = static_cast(object->data); + + HairBatchCache *cache = curves_batch_cache_get(curves); + *r_hair_cache = &cache->hair; + + const int steps = 2; /* TODO: don't hard-code? */ + (*r_hair_cache)->final[subdiv].strands_res = 1 << (steps + subdiv); + + /* Refreshed on combing and simulation. */ + if ((*r_hair_cache)->proc_point_buf == nullptr) { + 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) { + 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) { + 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) { + curves_batch_cache_ensure_procedural_indices(curves, &cache->hair, thickness_res, subdiv); + } + + return need_ft_update; +} + +int DRW_curves_material_count_get(Curves *curves) +{ + return max_ii(1, curves->totcol); +} diff --git a/source/blender/draw/intern/draw_cache_impl_hair.cc b/source/blender/draw/intern/draw_cache_impl_hair.cc deleted file mode 100644 index cdc06b121b0..00000000000 --- a/source/blender/draw/intern/draw_cache_impl_hair.cc +++ /dev/null @@ -1,388 +0,0 @@ -/* - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * The Original Code is Copyright (C) 2017 by Blender Foundation. - * All rights reserved. - */ - -/** \file - * \ingroup draw - * - * \brief Hair API for render engines - */ - -#include - -#include "MEM_guardedalloc.h" - -#include "BLI_listbase.h" -#include "BLI_math_base.h" -#include "BLI_math_vec_types.hh" -#include "BLI_math_vector.h" -#include "BLI_math_vector.hh" -#include "BLI_span.hh" -#include "BLI_utildefines.h" - -#include "DNA_hair_types.h" -#include "DNA_object_types.h" - -#include "BKE_hair.h" - -#include "GPU_batch.h" -#include "GPU_material.h" -#include "GPU_texture.h" - -#include "draw_cache_impl.h" /* own include */ -#include "draw_hair_private.h" /* own include */ - -using blender::float3; -using blender::IndexRange; -using blender::Span; - -static void hair_batch_cache_clear(Hair *hair); - -/* ---------------------------------------------------------------------- */ -/* Hair GPUBatch Cache */ - -struct HairBatchCache { - ParticleHairCache hair; - - /* settings to determine if cache is invalid */ - bool is_dirty; -}; - -/* GPUBatch cache management. */ - -static bool hair_batch_cache_valid(Hair *hair) -{ - HairBatchCache *cache = static_cast(hair->batch_cache); - return (cache && cache->is_dirty == false); -} - -static void hair_batch_cache_init(Hair *hair) -{ - HairBatchCache *cache = static_cast(hair->batch_cache); - - if (!cache) { - cache = MEM_cnew(__func__); - hair->batch_cache = cache; - } - else { - memset(cache, 0, sizeof(*cache)); - } - - cache->is_dirty = false; -} - -void DRW_hair_batch_cache_validate(Hair *hair) -{ - if (!hair_batch_cache_valid(hair)) { - hair_batch_cache_clear(hair); - hair_batch_cache_init(hair); - } -} - -static HairBatchCache *hair_batch_cache_get(Hair *hair) -{ - DRW_hair_batch_cache_validate(hair); - return static_cast(hair->batch_cache); -} - -void DRW_hair_batch_cache_dirty_tag(Hair *hair, int mode) -{ - HairBatchCache *cache = static_cast(hair->batch_cache); - if (cache == nullptr) { - return; - } - switch (mode) { - case BKE_HAIR_BATCH_DIRTY_ALL: - cache->is_dirty = true; - break; - default: - BLI_assert(0); - } -} - -static void hair_batch_cache_clear(Hair *hair) -{ - HairBatchCache *cache = static_cast(hair->batch_cache); - if (!cache) { - return; - } - - particle_batch_cache_clear_hair(&cache->hair); -} - -void DRW_hair_batch_cache_free(Hair *hair) -{ - hair_batch_cache_clear(hair); - MEM_SAFE_FREE(hair->batch_cache); -} - -static void ensure_seg_pt_count(Hair *hair, ParticleHairCache *hair_cache) -{ - if ((hair_cache->pos != nullptr && hair_cache->indices != nullptr) || - (hair_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; -} - -static void hair_batch_cache_fill_segments_proc_pos(Hair *hair, - GPUVertBufRaw *attr_step, - GPUVertBufRaw *length_step) -{ - /* TODO: use hair radius layer if available. */ - const int curve_size = hair->geometry.curve_size; - Span offsets{hair->geometry.offsets, hair->geometry.curve_size + 1}; - - Span positions{(float3 *)hair->geometry.position, hair->geometry.point_size}; - - for (const int i : IndexRange(curve_size)) { - const IndexRange curve_range(offsets[i], offsets[i + 1] - offsets[i]); - - Span spline_positions = positions.slice(curve_range); - float total_len = 0.0f; - float *seg_data_first; - for (const int i_spline : spline_positions.index_range()) { - float *seg_data = (float *)GPU_vertbuf_raw_step(attr_step); - copy_v3_v3(seg_data, spline_positions[i_spline]); - if (i_spline == 0) { - seg_data_first = seg_data; - } - else { - total_len += blender::math::distance(spline_positions[i_spline - 1], - spline_positions[i_spline]); - } - seg_data[3] = total_len; - } - /* Assign length value. */ - *(float *)GPU_vertbuf_raw_step(length_step) = total_len; - if (total_len > 0.0f) { - /* Divide by total length to have a [0-1] number. */ - for ([[maybe_unused]] const int i_spline : spline_positions.index_range()) { - seg_data_first[3] /= total_len; - seg_data_first += 4; - } - } - } -} - -static void hair_batch_cache_ensure_procedural_pos(Hair *hair, - ParticleHairCache *cache, - GPUMaterial *gpu_material) -{ - if (cache->proc_point_buf == nullptr) { - /* initialize vertex format */ - GPUVertFormat format = {0}; - uint pos_id = GPU_vertformat_attr_add(&format, "posTime", GPU_COMP_F32, 4, GPU_FETCH_FLOAT); - - cache->proc_point_buf = GPU_vertbuf_create_with_format(&format); - GPU_vertbuf_data_alloc(cache->proc_point_buf, cache->point_len); - - GPUVertBufRaw point_step; - GPU_vertbuf_attr_get_raw_data(cache->proc_point_buf, pos_id, &point_step); - - GPUVertFormat length_format = {0}; - uint length_id = GPU_vertformat_attr_add( - &length_format, "hairLength", GPU_COMP_F32, 1, GPU_FETCH_FLOAT); - - cache->proc_length_buf = GPU_vertbuf_create_with_format(&length_format); - GPU_vertbuf_data_alloc(cache->proc_length_buf, cache->strands_len); - - 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); - - /* Create vbo immediately to bind to texture buffer. */ - GPU_vertbuf_use(cache->proc_point_buf); - cache->point_tex = GPU_texture_create_from_vertbuf("hair_point", cache->proc_point_buf); - } - - if (gpu_material && cache->proc_length_buf != nullptr && cache->length_tex) { - ListBase gpu_attrs = GPU_material_attributes(gpu_material); - LISTBASE_FOREACH (GPUMaterialAttribute *, attr, &gpu_attrs) { - if (attr->type == CD_HAIRLENGTH) { - GPU_vertbuf_use(cache->proc_length_buf); - cache->length_tex = GPU_texture_create_from_vertbuf("hair_length", cache->proc_length_buf); - break; - } - } - } -} - -static void hair_batch_cache_fill_strands_data(Hair *hair, - GPUVertBufRaw *data_step, - GPUVertBufRaw *seg_step) -{ - const int curve_size = hair->geometry.curve_size; - Span offsets{hair->geometry.offsets, hair->geometry.curve_size + 1}; - - for (const int i : IndexRange(curve_size)) { - const IndexRange curve_range(offsets[i], offsets[i + 1] - offsets[i]); - - *(uint *)GPU_vertbuf_raw_step(data_step) = curve_range.start(); - *(ushort *)GPU_vertbuf_raw_step(seg_step) = curve_range.size() - 1; - } -} - -static void hair_batch_cache_ensure_procedural_strand_data(Hair *hair, ParticleHairCache *cache) -{ - GPUVertBufRaw data_step, seg_step; - - GPUVertFormat format_data = {0}; - uint data_id = GPU_vertformat_attr_add(&format_data, "data", GPU_COMP_U32, 1, GPU_FETCH_INT); - - GPUVertFormat format_seg = {0}; - uint seg_id = GPU_vertformat_attr_add(&format_seg, "data", GPU_COMP_U16, 1, GPU_FETCH_INT); - - /* Strand Data */ - cache->proc_strand_buf = GPU_vertbuf_create_with_format(&format_data); - GPU_vertbuf_data_alloc(cache->proc_strand_buf, cache->strands_len); - GPU_vertbuf_attr_get_raw_data(cache->proc_strand_buf, data_id, &data_step); - - cache->proc_strand_seg_buf = GPU_vertbuf_create_with_format(&format_seg); - 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); - - /* 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); - - GPU_vertbuf_use(cache->proc_strand_seg_buf); - cache->strand_seg_tex = GPU_texture_create_from_vertbuf("hair_strand_seg", - cache->proc_strand_seg_buf); -} - -static void hair_batch_cache_ensure_procedural_final_points(ParticleHairCache *cache, int subdiv) -{ - /* Same format as point_tex. */ - GPUVertFormat format = {0}; - GPU_vertformat_attr_add(&format, "pos", GPU_COMP_F32, 4, GPU_FETCH_FLOAT); - - cache->final[subdiv].proc_buf = GPU_vertbuf_create_with_format_ex(&format, - GPU_USAGE_DEVICE_ONLY); - - /* Create a destination buffer for the transform feedback. Sized appropriately */ - /* Those are points! not line segments. */ - GPU_vertbuf_data_alloc(cache->final[subdiv].proc_buf, - cache->final[subdiv].strands_res * cache->strands_len); - - /* Create vbo immediately to bind to texture buffer. */ - GPU_vertbuf_use(cache->final[subdiv].proc_buf); - - cache->final[subdiv].proc_tex = GPU_texture_create_from_vertbuf("hair_proc", - cache->final[subdiv].proc_buf); -} - -static void hair_batch_cache_fill_segments_indices(Hair *hair, - const int res, - GPUIndexBufBuilder *elb) -{ - const int curve_size = hair->geometry.curve_size; - - uint curr_point = 0; - - for ([[maybe_unused]] const int i : IndexRange(curve_size)) { - for (int k = 0; k < res; k++) { - GPU_indexbuf_add_generic_vert(elb, curr_point++); - } - GPU_indexbuf_add_primitive_restart(elb); - } -} - -static void hair_batch_cache_ensure_procedural_indices(Hair *hair, - ParticleHairCache *cache, - int thickness_res, - int subdiv) -{ - BLI_assert(thickness_res <= MAX_THICKRES); /* Cylinder strip not currently supported. */ - - if (cache->final[subdiv].proc_hairs[thickness_res - 1] != nullptr) { - return; - } - - int verts_per_hair = cache->final[subdiv].strands_res * thickness_res; - /* +1 for primitive restart */ - int element_count = (verts_per_hair + 1) * cache->strands_len; - GPUPrimType prim_type = (thickness_res == 1) ? GPU_PRIM_LINE_STRIP : GPU_PRIM_TRI_STRIP; - - static GPUVertFormat format = {0}; - GPU_vertformat_clear(&format); - - /* initialize vertex format */ - GPU_vertformat_attr_add(&format, "dummy", GPU_COMP_U8, 1, GPU_FETCH_INT_TO_FLOAT_UNIT); - - GPUVertBuf *vbo = GPU_vertbuf_create_with_format(&format); - GPU_vertbuf_data_alloc(vbo, 1); - - GPUIndexBufBuilder elb; - GPU_indexbuf_init_ex(&elb, prim_type, element_count, element_count); - - hair_batch_cache_fill_segments_indices(hair, 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); -} - -bool hair_ensure_procedural_data(Object *object, - ParticleHairCache **r_hair_cache, - GPUMaterial *gpu_material, - int subdiv, - int thickness_res) -{ - bool need_ft_update = false; - Hair *hair = static_cast(object->data); - - HairBatchCache *cache = hair_batch_cache_get(hair); - *r_hair_cache = &cache->hair; - - const int steps = 2; /* TODO: don't hard-code? */ - (*r_hair_cache)->final[subdiv].strands_res = 1 << (steps + subdiv); - - /* 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); - 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); - } - - /* 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); - 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); - } - - return need_ft_update; -} - -int DRW_hair_material_count_get(Hair *hair) -{ - return max_ii(1, hair->totcol); -} 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; -- cgit v1.2.3