Blender V4.5
draw_sculpt.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2023 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
8
9#include "draw_sculpt.hh"
10
11#include "DNA_mesh_types.h"
12#include "DNA_scene_types.h"
13#include "draw_attributes.hh"
15#include "draw_view.hh"
16
17#include "BKE_attribute.hh"
18#include "BKE_customdata.hh"
19#include "BKE_material.hh"
20#include "BKE_object.hh"
21#include "BKE_paint.hh"
22
23#include "BLI_math_matrix.hh"
24
25#include "bmesh_class.hh"
26
27#include "DRW_pbvh.hh"
28#include "DRW_render.hh"
29
30namespace blender::draw {
31
33{
34 static float3 colors[9] = {
35 {1.0f, 0.2f, 0.2f},
36 {0.2f, 1.0f, 0.2f},
37 {0.2f, 0.2f, 1.0f},
38 {1.0f, 1.0f, 0.2f},
39 {0.2f, 1.0f, 1.0f},
40 {1.0f, 0.2f, 1.0f},
41 {1.0f, 0.7f, 0.2f},
42 {0.2f, 1.0f, 0.7f},
43 {0.7f, 0.2f, 1.0f},
44 };
45
46 return colors[debug_index % 9];
47}
48
50 const bool use_wire,
52{
53 /* pbvh::Tree should always exist for non-empty meshes, created by depsgraph eval. */
55 nullptr;
56 if (!pbvh) {
57 return {};
58 }
59
60 /* TODO(Miguel Pozo): Don't use global context. */
61 const DRWContext *drwctx = DRW_context_get();
62 RegionView3D *rv3d = drwctx->rv3d;
63 const bool navigating = rv3d && (rv3d->rflag & RV3D_NAVIGATING);
64
65 Paint *paint = nullptr;
66 if (drwctx->evil_C != nullptr) {
68 }
69
70 /* TODO: take into account partial redraw for clipping planes. */
71 /* Frustum planes to show only visible pbvh::Tree nodes. */
72 std::array<float4, 6> draw_frustum_planes = View::default_get().frustum_planes_get();
73 /* Transform clipping planes to object space. Transforming a plane with a
74 * 4x4 matrix is done by multiplying with the transpose inverse.
75 * The inverse cancels out here since we transform by inverse(obmat). */
76 float4x4 tmat = math::transpose(ob->object_to_world());
77 for (int i : IndexRange(draw_frustum_planes.size())) {
78 draw_frustum_planes[i] = tmat * draw_frustum_planes[i];
79 }
80
81 /* Fast mode to show low poly multires while navigating. */
82 bool fast_mode = false;
83 if (paint && (paint->flags & PAINT_FAST_NAVIGATE)) {
84 fast_mode = navigating;
85 }
86
87 /* Update draw buffers only for visible nodes while painting.
88 * But do update them otherwise so navigating stays smooth. */
89 bool update_only_visible = rv3d && !(rv3d->rflag & RV3D_PAINTING);
90 if (paint && (paint->flags & PAINT_SCULPT_DELAY_UPDATES)) {
91 update_only_visible = true;
92 }
93
95
96 pbvh::DrawCache &draw_data = pbvh::ensure_draw_data(pbvh->draw_data);
97
98 IndexMaskMemory memory;
99 const IndexMask visible_nodes = bke::pbvh::search_nodes(
100 *pbvh, memory, [&](const bke::pbvh::Node &node) {
101 return !BKE_pbvh_node_fully_hidden_get(node) &&
102 bke::pbvh::node_frustum_contain_aabb(node, draw_frustum_planes);
103 });
104
105 const IndexMask nodes_to_update = update_only_visible ? visible_nodes :
107
108 Span<gpu::Batch *> batches;
109 if (use_wire) {
110 batches = draw_data.ensure_lines_batches(*ob, {{}, fast_mode}, nodes_to_update);
111 }
112 else {
113 batches = draw_data.ensure_tris_batches(*ob, {attrs, fast_mode}, nodes_to_update);
114 }
115
116 const Span<int> material_indices = draw_data.ensure_material_indices(*ob);
117
118 const int max_material = std::max(0, BKE_object_material_count_eval(ob) - 1);
119 Vector<SculptBatch> result_batches(visible_nodes.size());
120 visible_nodes.foreach_index([&](const int i, const int pos) {
121 result_batches[pos] = {};
122 result_batches[pos].batch = batches[i];
123 result_batches[pos].material_slot = material_indices.is_empty() ?
124 0 :
125 std::clamp(material_indices[i], 0, max_material);
126 result_batches[pos].debug_index = pos;
127 });
128
129 return result_batches;
130}
131
133{
135
138 if (features & SCULPT_BATCH_MASK) {
140 }
141 if (features & SCULPT_BATCH_FACE_SET) {
143 }
144
145 const Mesh *mesh = BKE_object_get_original_mesh(ob);
146 const SculptSession &ss = *ob->sculpt;
147
148 if (features & SCULPT_BATCH_VERTEX_COLOR) {
149 if (const char *name = mesh->active_color_attribute) {
150 attrs.append(pbvh::GenericRequest(name));
151 }
152 }
153
154 if (features & SCULPT_BATCH_UV) {
155 const CustomData *corner_data = ss.bm ? &ss.bm->ldata : &mesh->corner_data;
156 if (const char *name = CustomData_get_active_layer_name(corner_data, CD_PROP_FLOAT2)) {
157 attrs.append(pbvh::GenericRequest(name));
158 }
159 }
160
161 return sculpt_batches_get_ex(ob, features & SCULPT_BATCH_WIREFRAME, attrs);
162}
163
166{
167 BLI_assert(ob->type == OB_MESH);
169
170 VectorSet<std::string> draw_attrs;
171 DRW_MeshCDMask cd_needed;
172 DRW_mesh_get_attributes(*ob, mesh, materials, &draw_attrs, &cd_needed);
173
175
178
179 for (const StringRef name : draw_attrs) {
180 attrs.append(pbvh::GenericRequest(name));
181 }
182
183 /* UV maps are not in attribute requests. */
184 for (uint i = 0; i < 32; i++) {
185 if (cd_needed.uv & (1 << i)) {
187 CustomDataLayer *layer = layer_i != -1 ? mesh.corner_data.layers + layer_i : nullptr;
188 if (layer) {
189 attrs.append(pbvh::GenericRequest(layer->name));
190 }
191 }
192 }
193
194 return sculpt_batches_get_ex(ob, false, attrs);
195}
196
197} // namespace blender::draw
CustomData interface, see also DNA_customdata_types.h.
int CustomData_get_layer_index_n(const CustomData *data, eCustomDataType type, int n)
const char * CustomData_get_active_layer_name(const CustomData *data, eCustomDataType type)
General operations, lookup, etc. for materials.
int BKE_object_material_count_eval(const Object *ob)
General operations, lookup, etc. for blender objects.
Mesh * BKE_object_get_original_mesh(const Object *object)
Paint * BKE_paint_get_active_from_context(const bContext *C)
Definition paint.cc:467
bool BKE_pbvh_node_fully_hidden_get(const blender::bke::pbvh::Node &node)
Definition pbvh.cc:1539
#define BLI_assert(a)
Definition BLI_assert.h:46
unsigned int uint
@ CD_PROP_FLOAT2
@ OB_MESH
@ PAINT_SCULPT_DELAY_UPDATES
@ PAINT_FAST_NAVIGATE
@ RV3D_PAINTING
@ RV3D_NAVIGATING
constexpr bool is_empty() const
Definition BLI_span.hh:260
void append(const T &value)
static View & default_get()
Definition draw_view.cc:317
std::array< float4, 6 > frustum_planes_get(int view_id=0)
Definition draw_view.cc:327
virtual Span< int > ensure_material_indices(const Object &object)=0
virtual Span< gpu::Batch * > ensure_lines_batches(const Object &object, const ViewportRequest &request, const IndexMask &nodes_to_update)=0
virtual Span< gpu::Batch * > ensure_tris_batches(const Object &object, const ViewportRequest &request, const IndexMask &nodes_to_update)=0
void foreach_index(Fn &&fn) const
Utilities for rendering attributes.
const DRWContext * DRW_context_get()
Mesh & DRW_object_get_data_for_drawing(const Object &object)
uint pos
pbvh::Tree * pbvh_get(Object &object)
Definition paint.cc:2912
IndexMask search_nodes(const Tree &pbvh, IndexMaskMemory &memory, FunctionRef< bool(const Node &)> filter_fn)
Definition pbvh.cc:2579
IndexMask all_leaf_nodes(const Tree &pbvh, IndexMaskMemory &memory)
Definition pbvh.cc:2544
void update_normals_from_eval(Object &object_eval, Tree &pbvh)
Definition pbvh.cc:1080
bool node_frustum_contain_aabb(const Node &node, Span< float4 > frustum_planes)
Definition pbvh.cc:2336
DrawCache & ensure_draw_data(std::unique_ptr< bke::pbvh::DrawCache > &ptr)
Definition draw_pbvh.cc:249
std::string GenericRequest
Definition DRW_pbvh.hh:39
Vector< SculptBatch > sculpt_batches_get(const Object *ob, SculptBatchFeature features)
static Vector< SculptBatch > sculpt_batches_get_ex(const Object *ob, const bool use_wire, const Span< pbvh::AttributeRequest > attrs)
@ SCULPT_BATCH_VERTEX_COLOR
void DRW_mesh_get_attributes(const Object &object, const Mesh &mesh, const Span< const GPUMaterial * > materials, VectorSet< std::string > *r_attrs, DRW_MeshCDMask *r_cd_needed)
Vector< SculptBatch > sculpt_batches_per_material_get(const Object *ob, Span< const GPUMaterial * > materials)
MatBase< T, NumCol, NumRow > transpose(const MatBase< T, NumRow, NumCol > &mat)
MatBase< float, 4, 4 > float4x4
VecBase< float, 3 > float3
CustomData ldata
CustomDataLayer * layers
RegionView3D * rv3d
const bContext * evil_C
CustomData corner_data
char * active_color_attribute
struct SculptSession * sculpt
i
Definition text_draw.cc:230