Merge branch 'blender-v4.0-release'
This commit is contained in:
commit
acbab3550f
@ -36,7 +36,8 @@
|
|||||||
#include "DNA_meshdata_types.h"
|
#include "DNA_meshdata_types.h"
|
||||||
|
|
||||||
#include "BKE_DerivedMesh.h"
|
#include "BKE_DerivedMesh.h"
|
||||||
#include "BKE_attribute.h"
|
#include "BKE_attribute.hh"
|
||||||
|
#include "BKE_attribute_math.hh"
|
||||||
#include "BKE_ccg.h"
|
#include "BKE_ccg.h"
|
||||||
#include "BKE_customdata.h"
|
#include "BKE_customdata.h"
|
||||||
#include "BKE_mesh.hh"
|
#include "BKE_mesh.hh"
|
||||||
@ -75,20 +76,147 @@ using blender::ushort3;
|
|||||||
using blender::ushort4;
|
using blender::ushort4;
|
||||||
using blender::Vector;
|
using blender::Vector;
|
||||||
|
|
||||||
static bool valid_pbvh_attr(int type)
|
/**
|
||||||
|
* Component length of 3 is used for scalars because implicit conversion is done by OpenGL from a
|
||||||
|
* scalar `s` will produce `vec4(s, 0, 0, 1)`. However, following the Blender convention, it should
|
||||||
|
* be `vec4(s, s, s, 1)`.
|
||||||
|
*/
|
||||||
|
constexpr int COMPONENT_LEN_SCALAR = 3;
|
||||||
|
|
||||||
|
namespace blender::draw {
|
||||||
|
|
||||||
|
/** Similar to #AttributeTypeConverter. */
|
||||||
|
template<typename T> struct AttributeConverter {
|
||||||
|
using VBOT = void;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<> struct AttributeConverter<bool> {
|
||||||
|
using VBOT = VecBase<int, COMPONENT_LEN_SCALAR>;
|
||||||
|
static constexpr GPUVertCompType gpu_component_type = GPU_COMP_I32;
|
||||||
|
static constexpr int gpu_component_len = COMPONENT_LEN_SCALAR;
|
||||||
|
static constexpr GPUVertFetchMode gpu_fetch_mode = GPU_FETCH_INT_TO_FLOAT;
|
||||||
|
static VBOT convert(const bool &value)
|
||||||
{
|
{
|
||||||
switch (type) {
|
return VBOT(value);
|
||||||
case CD_PBVH_CO_TYPE:
|
}
|
||||||
case CD_PBVH_NO_TYPE:
|
};
|
||||||
case CD_PBVH_FSET_TYPE:
|
template<> struct AttributeConverter<int8_t> {
|
||||||
case CD_PBVH_MASK_TYPE:
|
using VBOT = VecBase<int, COMPONENT_LEN_SCALAR>;
|
||||||
case CD_PROP_COLOR:
|
static constexpr GPUVertCompType gpu_component_type = GPU_COMP_I32;
|
||||||
case CD_PROP_BYTE_COLOR:
|
static constexpr int gpu_component_len = COMPONENT_LEN_SCALAR;
|
||||||
case CD_PROP_FLOAT2:
|
static constexpr GPUVertFetchMode gpu_fetch_mode = GPU_FETCH_INT_TO_FLOAT;
|
||||||
|
static VBOT convert(const int8_t &value)
|
||||||
|
{
|
||||||
|
return VecBase<int, COMPONENT_LEN_SCALAR>(value);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
template<> struct AttributeConverter<int> {
|
||||||
|
using VBOT = VecBase<int, COMPONENT_LEN_SCALAR>;
|
||||||
|
static constexpr GPUVertCompType gpu_component_type = GPU_COMP_I32;
|
||||||
|
static constexpr int gpu_component_len = COMPONENT_LEN_SCALAR;
|
||||||
|
static constexpr GPUVertFetchMode gpu_fetch_mode = GPU_FETCH_INT_TO_FLOAT;
|
||||||
|
static VBOT convert(const int &value)
|
||||||
|
{
|
||||||
|
return int3(value);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
template<> struct AttributeConverter<int2> {
|
||||||
|
using VBOT = int2;
|
||||||
|
static constexpr GPUVertCompType gpu_component_type = GPU_COMP_I32;
|
||||||
|
static constexpr int gpu_component_len = 2;
|
||||||
|
static constexpr GPUVertFetchMode gpu_fetch_mode = GPU_FETCH_INT_TO_FLOAT;
|
||||||
|
static VBOT convert(const int2 &value)
|
||||||
|
{
|
||||||
|
return int2(value.x, value.y);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
template<> struct AttributeConverter<float> {
|
||||||
|
using VBOT = VecBase<float, COMPONENT_LEN_SCALAR>;
|
||||||
|
static constexpr GPUVertCompType gpu_component_type = GPU_COMP_F32;
|
||||||
|
static constexpr int gpu_component_len = COMPONENT_LEN_SCALAR;
|
||||||
|
static constexpr GPUVertFetchMode gpu_fetch_mode = GPU_FETCH_FLOAT;
|
||||||
|
static VBOT convert(const float &value)
|
||||||
|
{
|
||||||
|
return VBOT(value);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
template<> struct AttributeConverter<float2> {
|
||||||
|
using VBOT = float2;
|
||||||
|
static constexpr GPUVertCompType gpu_component_type = GPU_COMP_F32;
|
||||||
|
static constexpr int gpu_component_len = 2;
|
||||||
|
static constexpr GPUVertFetchMode gpu_fetch_mode = GPU_FETCH_FLOAT;
|
||||||
|
static VBOT convert(const float2 &value)
|
||||||
|
{
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
template<> struct AttributeConverter<float3> {
|
||||||
|
using VBOT = float3;
|
||||||
|
static constexpr GPUVertCompType gpu_component_type = GPU_COMP_F32;
|
||||||
|
static constexpr int gpu_component_len = 3;
|
||||||
|
static constexpr GPUVertFetchMode gpu_fetch_mode = GPU_FETCH_FLOAT;
|
||||||
|
static VBOT convert(const float3 &value)
|
||||||
|
{
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
template<> struct AttributeConverter<ColorGeometry4b> {
|
||||||
|
/* 16 bits are required to store the color in linear space without precision loss. */
|
||||||
|
using VBOT = ushort4;
|
||||||
|
static constexpr GPUVertCompType gpu_component_type = GPU_COMP_U16;
|
||||||
|
static constexpr int gpu_component_len = 4;
|
||||||
|
static constexpr GPUVertFetchMode gpu_fetch_mode = GPU_FETCH_INT_TO_FLOAT_UNIT;
|
||||||
|
static VBOT convert(const ColorGeometry4b &value)
|
||||||
|
{
|
||||||
|
return {unit_float_to_ushort_clamp(BLI_color_from_srgb_table[value.r]),
|
||||||
|
unit_float_to_ushort_clamp(BLI_color_from_srgb_table[value.g]),
|
||||||
|
unit_float_to_ushort_clamp(BLI_color_from_srgb_table[value.b]),
|
||||||
|
ushort(value.a * 257)};
|
||||||
|
}
|
||||||
|
};
|
||||||
|
template<> struct AttributeConverter<ColorGeometry4f> {
|
||||||
|
using VBOT = ColorGeometry4f;
|
||||||
|
static constexpr GPUVertCompType gpu_component_type = GPU_COMP_F32;
|
||||||
|
static constexpr int gpu_component_len = 4;
|
||||||
|
static constexpr GPUVertFetchMode gpu_fetch_mode = GPU_FETCH_FLOAT;
|
||||||
|
static VBOT convert(const ColorGeometry4f &value)
|
||||||
|
{
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
template<> struct AttributeConverter<blender::math::Quaternion> {
|
||||||
|
using VBOT = float4;
|
||||||
|
static constexpr GPUVertCompType gpu_component_type = GPU_COMP_F32;
|
||||||
|
static constexpr int gpu_component_len = 4;
|
||||||
|
static constexpr GPUVertFetchMode gpu_fetch_mode = GPU_FETCH_FLOAT;
|
||||||
|
static VBOT convert(const blender::math::Quaternion &value)
|
||||||
|
{
|
||||||
|
return float4(value.w, value.x, value.y, value.z);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace blender::draw
|
||||||
|
|
||||||
|
static bool pbvh_attr_supported(int type, const eAttrDomain domain)
|
||||||
|
{
|
||||||
|
using namespace blender;
|
||||||
|
if (!ELEM(domain, ATTR_DOMAIN_POINT, ATTR_DOMAIN_FACE, ATTR_DOMAIN_CORNER)) {
|
||||||
|
/* PBVH drawing does not support edge domain attributes. */
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (ELEM(type, CD_PBVH_CO_TYPE, CD_PBVH_NO_TYPE, CD_PBVH_FSET_TYPE, CD_PBVH_MASK_TYPE)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
bool type_supported = false;
|
||||||
return false;
|
bke::attribute_math::convert_to_static_type(eCustomDataType(type), [&](auto dummy) {
|
||||||
|
using T = decltype(dummy);
|
||||||
|
using Converter = draw::AttributeConverter<T>;
|
||||||
|
using VBOT = typename Converter::VBOT;
|
||||||
|
if constexpr (!std::is_void_v<VBOT>) {
|
||||||
|
type_supported = true;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return type_supported;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct PBVHVbo {
|
struct PBVHVbo {
|
||||||
@ -118,46 +246,18 @@ struct PBVHVbo {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename AttributeT, typename VBOT> VBOT convert_value(const AttributeT &value)
|
inline short4 normal_float_to_short(const float3 &value)
|
||||||
{
|
|
||||||
if constexpr (std::is_same_v<AttributeT, VBOT>) {
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
template<> inline uchar convert_value(const float &value)
|
|
||||||
{
|
|
||||||
return uchar(value * 255.0f);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<> inline ushort4 convert_value(const MPropCol &value)
|
|
||||||
{
|
|
||||||
return {unit_float_to_ushort_clamp(value.color[0]),
|
|
||||||
unit_float_to_ushort_clamp(value.color[1]),
|
|
||||||
unit_float_to_ushort_clamp(value.color[2]),
|
|
||||||
unit_float_to_ushort_clamp(value.color[3])};
|
|
||||||
}
|
|
||||||
|
|
||||||
template<> inline ushort4 convert_value(const MLoopCol &value)
|
|
||||||
{
|
|
||||||
return {unit_float_to_ushort_clamp(BLI_color_from_srgb_table[value.r]),
|
|
||||||
unit_float_to_ushort_clamp(BLI_color_from_srgb_table[value.g]),
|
|
||||||
unit_float_to_ushort_clamp(BLI_color_from_srgb_table[value.b]),
|
|
||||||
ushort(value.a * 257)};
|
|
||||||
}
|
|
||||||
|
|
||||||
template<> inline short4 convert_value(const float3 &value)
|
|
||||||
{
|
{
|
||||||
short3 result;
|
short3 result;
|
||||||
normal_float_to_short_v3(result, value);
|
normal_float_to_short_v3(result, value);
|
||||||
return short4(result.x, result.y, result.z, 0);
|
return short4(result.x, result.y, result.z, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename AttributeT, typename VBOT>
|
template<typename T>
|
||||||
void extract_data_vert_faces(const PBVH_GPU_Args &args,
|
void extract_data_vert_faces(const PBVH_GPU_Args &args, const Span<T> attribute, GPUVertBuf &vbo)
|
||||||
const Span<AttributeT> attribute,
|
|
||||||
GPUVertBuf &vbo)
|
|
||||||
{
|
{
|
||||||
|
using Converter = blender::draw::AttributeConverter<T>;
|
||||||
|
using VBOT = typename Converter::VBOT;
|
||||||
const Span<int> corner_verts = args.corner_verts;
|
const Span<int> corner_verts = args.corner_verts;
|
||||||
const Span<MLoopTri> looptris = args.mlooptri;
|
const Span<MLoopTri> looptris = args.mlooptri;
|
||||||
const Span<int> looptri_faces = args.looptri_faces;
|
const Span<int> looptri_faces = args.looptri_faces;
|
||||||
@ -170,17 +270,38 @@ void extract_data_vert_faces(const PBVH_GPU_Args &args,
|
|||||||
}
|
}
|
||||||
for (int i : IndexRange(3)) {
|
for (int i : IndexRange(3)) {
|
||||||
const int vert = corner_verts[looptris[looptri_i].tri[i]];
|
const int vert = corner_verts[looptris[looptri_i].tri[i]];
|
||||||
*data = convert_value<AttributeT, VBOT>(attribute[vert]);
|
*data = Converter::convert(attribute[vert]);
|
||||||
data++;
|
data++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename AttributeT, typename VBOT>
|
template<typename T>
|
||||||
void extract_data_corner_faces(const PBVH_GPU_Args &args,
|
void extract_data_face_faces(const PBVH_GPU_Args &args, const Span<T> attribute, GPUVertBuf &vbo)
|
||||||
const Span<AttributeT> attribute,
|
|
||||||
GPUVertBuf &vbo)
|
|
||||||
{
|
{
|
||||||
|
using Converter = blender::draw::AttributeConverter<T>;
|
||||||
|
using VBOT = typename Converter::VBOT;
|
||||||
|
|
||||||
|
const Span<int> looptri_faces = args.looptri_faces;
|
||||||
|
const bool *hide_poly = args.hide_poly;
|
||||||
|
|
||||||
|
VBOT *data = static_cast<VBOT *>(GPU_vertbuf_get_data(&vbo));
|
||||||
|
for (const int looptri_i : args.prim_indices) {
|
||||||
|
const int face = looptri_faces[looptri_i];
|
||||||
|
if (hide_poly && hide_poly[face]) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
std::fill_n(data, 3, Converter::convert(attribute[face]));
|
||||||
|
data += 3;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
void extract_data_corner_faces(const PBVH_GPU_Args &args, const Span<T> attribute, GPUVertBuf &vbo)
|
||||||
|
{
|
||||||
|
using Converter = blender::draw::AttributeConverter<T>;
|
||||||
|
using VBOT = typename Converter::VBOT;
|
||||||
|
|
||||||
const Span<MLoopTri> looptris = args.mlooptri;
|
const Span<MLoopTri> looptris = args.mlooptri;
|
||||||
const Span<int> looptri_faces = args.looptri_faces;
|
const Span<int> looptri_faces = args.looptri_faces;
|
||||||
const bool *hide_poly = args.hide_poly;
|
const bool *hide_poly = args.hide_poly;
|
||||||
@ -192,7 +313,7 @@ void extract_data_corner_faces(const PBVH_GPU_Args &args,
|
|||||||
}
|
}
|
||||||
for (int i : IndexRange(3)) {
|
for (int i : IndexRange(3)) {
|
||||||
const int corner = looptris[looptri_i].tri[i];
|
const int corner = looptris[looptri_i].tri[i];
|
||||||
*data = convert_value<AttributeT, VBOT>(attribute[corner]);
|
*data = Converter::convert(attribute[corner]);
|
||||||
data++;
|
data++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -213,9 +334,11 @@ template<typename T> const T &bmesh_cd_face_get(const BMFace &face, const int of
|
|||||||
return *static_cast<const T *>(POINTER_OFFSET(face.head.data, offset));
|
return *static_cast<const T *>(POINTER_OFFSET(face.head.data, offset));
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename AttributeT, typename VBOT>
|
template<typename T>
|
||||||
void extract_data_vert_bmesh(const PBVH_GPU_Args &args, const int cd_offset, GPUVertBuf &vbo)
|
void extract_data_vert_bmesh(const PBVH_GPU_Args &args, const int cd_offset, GPUVertBuf &vbo)
|
||||||
{
|
{
|
||||||
|
using Converter = blender::draw::AttributeConverter<T>;
|
||||||
|
using VBOT = typename Converter::VBOT;
|
||||||
VBOT *data = static_cast<VBOT *>(GPU_vertbuf_get_data(&vbo));
|
VBOT *data = static_cast<VBOT *>(GPU_vertbuf_get_data(&vbo));
|
||||||
|
|
||||||
for (const BMFace *f : *args.bm_faces) {
|
for (const BMFace *f : *args.bm_faces) {
|
||||||
@ -223,18 +346,36 @@ void extract_data_vert_bmesh(const PBVH_GPU_Args &args, const int cd_offset, GPU
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
const BMLoop *l = f->l_first;
|
const BMLoop *l = f->l_first;
|
||||||
*data = convert_value<AttributeT, VBOT>(bmesh_cd_vert_get<AttributeT>(*l->prev->v, cd_offset));
|
*data = Converter::convert(bmesh_cd_vert_get<T>(*l->prev->v, cd_offset));
|
||||||
data++;
|
data++;
|
||||||
*data = convert_value<AttributeT, VBOT>(bmesh_cd_vert_get<AttributeT>(*l->v, cd_offset));
|
*data = Converter::convert(bmesh_cd_vert_get<T>(*l->v, cd_offset));
|
||||||
data++;
|
data++;
|
||||||
*data = convert_value<AttributeT, VBOT>(bmesh_cd_vert_get<AttributeT>(*l->next->v, cd_offset));
|
*data = Converter::convert(bmesh_cd_vert_get<T>(*l->next->v, cd_offset));
|
||||||
data++;
|
data++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename AttributeT, typename VBOT>
|
template<typename T>
|
||||||
|
void extract_data_face_bmesh(const PBVH_GPU_Args &args, const int cd_offset, GPUVertBuf &vbo)
|
||||||
|
{
|
||||||
|
using Converter = blender::draw::AttributeConverter<T>;
|
||||||
|
using VBOT = typename Converter::VBOT;
|
||||||
|
VBOT *data = static_cast<VBOT *>(GPU_vertbuf_get_data(&vbo));
|
||||||
|
|
||||||
|
for (const BMFace *f : *args.bm_faces) {
|
||||||
|
if (BM_elem_flag_test(f, BM_ELEM_HIDDEN)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
std::fill_n(data, 3, Converter::convert(bmesh_cd_face_get<T>(*f, cd_offset)));
|
||||||
|
data += 3;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
void extract_data_corner_bmesh(const PBVH_GPU_Args &args, const int cd_offset, GPUVertBuf &vbo)
|
void extract_data_corner_bmesh(const PBVH_GPU_Args &args, const int cd_offset, GPUVertBuf &vbo)
|
||||||
{
|
{
|
||||||
|
using Converter = blender::draw::AttributeConverter<T>;
|
||||||
|
using VBOT = typename Converter::VBOT;
|
||||||
VBOT *data = static_cast<VBOT *>(GPU_vertbuf_get_data(&vbo));
|
VBOT *data = static_cast<VBOT *>(GPU_vertbuf_get_data(&vbo));
|
||||||
|
|
||||||
for (const BMFace *f : *args.bm_faces) {
|
for (const BMFace *f : *args.bm_faces) {
|
||||||
@ -242,11 +383,11 @@ void extract_data_corner_bmesh(const PBVH_GPU_Args &args, const int cd_offset, G
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
const BMLoop *l = f->l_first;
|
const BMLoop *l = f->l_first;
|
||||||
*data = convert_value<AttributeT, VBOT>(bmesh_cd_loop_get<AttributeT>(*l->prev, cd_offset));
|
*data = Converter::convert(bmesh_cd_loop_get<T>(*l->prev, cd_offset));
|
||||||
data++;
|
data++;
|
||||||
*data = convert_value<AttributeT, VBOT>(bmesh_cd_loop_get<AttributeT>(*l, cd_offset));
|
*data = Converter::convert(bmesh_cd_loop_get<T>(*l, cd_offset));
|
||||||
data++;
|
data++;
|
||||||
*data = convert_value<AttributeT, VBOT>(bmesh_cd_loop_get<AttributeT>(*l->next, cd_offset));
|
*data = Converter::convert(bmesh_cd_loop_get<T>(*l->next, cd_offset));
|
||||||
data++;
|
data++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -396,7 +537,7 @@ struct PBVHBatches {
|
|||||||
for (int i : IndexRange(attrs_num)) {
|
for (int i : IndexRange(attrs_num)) {
|
||||||
PBVHAttrReq *attr = attrs + i;
|
PBVHAttrReq *attr = attrs + i;
|
||||||
|
|
||||||
if (!valid_pbvh_attr(attr->type)) {
|
if (!pbvh_attr_supported(attr->type, attr->domain)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -476,7 +617,7 @@ struct PBVHBatches {
|
|||||||
}
|
}
|
||||||
if (sharp_faces && sharp_faces[face_i]) {
|
if (sharp_faces && sharp_faces[face_i]) {
|
||||||
if (face_i != last_face) {
|
if (face_i != last_face) {
|
||||||
face_no = convert_value<float3, short4>(args.face_normals[face_i]);
|
face_no = normal_float_to_short(args.face_normals[face_i]);
|
||||||
last_face = face_i;
|
last_face = face_i;
|
||||||
}
|
}
|
||||||
std::fill_n(data, 3, face_no);
|
std::fill_n(data, 3, face_no);
|
||||||
@ -485,7 +626,7 @@ struct PBVHBatches {
|
|||||||
else {
|
else {
|
||||||
for (const int i : IndexRange(3)) {
|
for (const int i : IndexRange(3)) {
|
||||||
const int vert = args.corner_verts[args.mlooptri[looptri_i].tri[i]];
|
const int vert = args.corner_verts[args.mlooptri[looptri_i].tri[i]];
|
||||||
*data = convert_value<float3, short4>(args.vert_normals[vert]);
|
*data = normal_float_to_short(args.vert_normals[vert]);
|
||||||
data++;
|
data++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -498,6 +639,7 @@ struct PBVHBatches {
|
|||||||
FunctionRef<void(FunctionRef<void(int x, int y, int grid_index, CCGElem *elems[4], int i)>
|
FunctionRef<void(FunctionRef<void(int x, int y, int grid_index, CCGElem *elems[4], int i)>
|
||||||
func)> foreach_grids)
|
func)> foreach_grids)
|
||||||
{
|
{
|
||||||
|
using namespace blender;
|
||||||
uint vert_per_grid = square_i(args.ccg_key.grid_size - 1) * 4;
|
uint vert_per_grid = square_i(args.ccg_key.grid_size - 1) * 4;
|
||||||
uint vert_count = args.grid_indices.size() * vert_per_grid;
|
uint vert_count = args.grid_indices.size() * vert_per_grid;
|
||||||
|
|
||||||
@ -512,29 +654,14 @@ struct PBVHBatches {
|
|||||||
GPUVertBufRaw access;
|
GPUVertBufRaw access;
|
||||||
GPU_vertbuf_attr_get_raw_data(vbo.vert_buf, 0, &access);
|
GPU_vertbuf_attr_get_raw_data(vbo.vert_buf, 0, &access);
|
||||||
|
|
||||||
switch (vbo.type) {
|
if (vbo.type == CD_PBVH_CO_TYPE) {
|
||||||
case CD_PROP_COLOR:
|
|
||||||
case CD_PROP_BYTE_COLOR: {
|
|
||||||
/* TODO: Implement color support for multires similar to the mesh cache
|
|
||||||
* extractor code. For now just upload white.
|
|
||||||
*/
|
|
||||||
const ushort4 white(USHRT_MAX, USHRT_MAX, USHRT_MAX, USHRT_MAX);
|
|
||||||
|
|
||||||
foreach_grids(
|
|
||||||
[&](int /*x*/, int /*y*/, int /*grid_index*/, CCGElem * /*elems*/[4], int /*i*/) {
|
|
||||||
*static_cast<ushort4 *>(GPU_vertbuf_raw_step(&access)) = white;
|
|
||||||
});
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case CD_PBVH_CO_TYPE:
|
|
||||||
foreach_grids([&](int /*x*/, int /*y*/, int /*grid_index*/, CCGElem *elems[4], int i) {
|
foreach_grids([&](int /*x*/, int /*y*/, int /*grid_index*/, CCGElem *elems[4], int i) {
|
||||||
float *co = CCG_elem_co(&args.ccg_key, elems[i]);
|
float *co = CCG_elem_co(&args.ccg_key, elems[i]);
|
||||||
|
|
||||||
*static_cast<float3 *>(GPU_vertbuf_raw_step(&access)) = co;
|
*static_cast<float3 *>(GPU_vertbuf_raw_step(&access)) = co;
|
||||||
});
|
});
|
||||||
break;
|
}
|
||||||
|
else if (vbo.type == CD_PBVH_NO_TYPE) {
|
||||||
case CD_PBVH_NO_TYPE:
|
|
||||||
foreach_grids([&](int /*x*/, int /*y*/, int grid_index, CCGElem *elems[4], int /*i*/) {
|
foreach_grids([&](int /*x*/, int /*y*/, int grid_index, CCGElem *elems[4], int /*i*/) {
|
||||||
float3 no(0.0f, 0.0f, 0.0f);
|
float3 no(0.0f, 0.0f, 0.0f);
|
||||||
|
|
||||||
@ -557,9 +684,8 @@ struct PBVHBatches {
|
|||||||
|
|
||||||
*static_cast<short3 *>(GPU_vertbuf_raw_step(&access)) = sno;
|
*static_cast<short3 *>(GPU_vertbuf_raw_step(&access)) = sno;
|
||||||
});
|
});
|
||||||
break;
|
}
|
||||||
|
else if (vbo.type == CD_PBVH_MASK_TYPE) {
|
||||||
case CD_PBVH_MASK_TYPE:
|
|
||||||
if (args.ccg_key.has_mask) {
|
if (args.ccg_key.has_mask) {
|
||||||
foreach_grids([&](int /*x*/, int /*y*/, int /*grid_index*/, CCGElem *elems[4], int i) {
|
foreach_grids([&](int /*x*/, int /*y*/, int /*grid_index*/, CCGElem *elems[4], int i) {
|
||||||
float *mask = CCG_elem_mask(&args.ccg_key, elems[i]);
|
float *mask = CCG_elem_mask(&args.ccg_key, elems[i]);
|
||||||
@ -573,11 +699,8 @@ struct PBVHBatches {
|
|||||||
*static_cast<uchar *>(GPU_vertbuf_raw_step(&access)) = 0;
|
*static_cast<uchar *>(GPU_vertbuf_raw_step(&access)) = 0;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
break;
|
}
|
||||||
|
else if (vbo.type == CD_PBVH_FSET_TYPE) {
|
||||||
case CD_PBVH_FSET_TYPE: {
|
|
||||||
BLI_assert(vbo.domain == ATTR_DOMAIN_FACE);
|
|
||||||
|
|
||||||
const int *face_sets = args.face_sets;
|
const int *face_sets = args.face_sets;
|
||||||
|
|
||||||
if (!face_sets) {
|
if (!face_sets) {
|
||||||
@ -608,8 +731,16 @@ struct PBVHBatches {
|
|||||||
*static_cast<uchar3 *>(GPU_vertbuf_raw_step(&access)) = face_set_color;
|
*static_cast<uchar3 *>(GPU_vertbuf_raw_step(&access)) = face_set_color;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
bke::attribute_math::convert_to_static_type(eCustomDataType(vbo.type), [&](auto dummy) {
|
||||||
|
using T = decltype(dummy);
|
||||||
|
using Converter = draw::AttributeConverter<T>;
|
||||||
|
using VBOT = typename Converter::VBOT;
|
||||||
|
std::fill_n(static_cast<VBOT *>(GPU_vertbuf_get_data(vbo.vert_buf)),
|
||||||
|
GPU_vertbuf_get_vertex_len(vbo.vert_buf),
|
||||||
|
VBOT());
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -679,6 +810,7 @@ struct PBVHBatches {
|
|||||||
|
|
||||||
void fill_vbo_faces(PBVHVbo &vbo, const PBVH_GPU_Args &args)
|
void fill_vbo_faces(PBVHVbo &vbo, const PBVH_GPU_Args &args)
|
||||||
{
|
{
|
||||||
|
using namespace blender;
|
||||||
const int totvert = this->count_faces(args) * 3;
|
const int totvert = this->count_faces(args) * 3;
|
||||||
|
|
||||||
int existing_num = GPU_vertbuf_get_vertex_len(vbo.vert_buf);
|
int existing_num = GPU_vertbuf_get_vertex_len(vbo.vert_buf);
|
||||||
@ -691,28 +823,38 @@ struct PBVHBatches {
|
|||||||
|
|
||||||
GPUVertBuf &vert_buf = *vbo.vert_buf;
|
GPUVertBuf &vert_buf = *vbo.vert_buf;
|
||||||
|
|
||||||
switch (vbo.type) {
|
if (vbo.type == CD_PBVH_CO_TYPE) {
|
||||||
case CD_PBVH_CO_TYPE:
|
extract_data_vert_faces<float3>(args, args.vert_positions, vert_buf);
|
||||||
extract_data_vert_faces<float3, float3>(args, args.vert_positions, vert_buf);
|
}
|
||||||
break;
|
else if (vbo.type == CD_PBVH_NO_TYPE) {
|
||||||
case CD_PBVH_NO_TYPE:
|
|
||||||
fill_vbo_normal_faces(args, vert_buf);
|
fill_vbo_normal_faces(args, vert_buf);
|
||||||
break;
|
}
|
||||||
case CD_PBVH_MASK_TYPE: {
|
else if (vbo.type == CD_PBVH_MASK_TYPE) {
|
||||||
if (const float *mask = static_cast<const float *>(
|
if (const float *mask = static_cast<const float *>(
|
||||||
CustomData_get_layer(args.vert_data, CD_PAINT_MASK)))
|
CustomData_get_layer(args.vert_data, CD_PAINT_MASK)))
|
||||||
{
|
{
|
||||||
extract_data_vert_faces<float, float>(args, {mask, args.me->totvert}, vert_buf);
|
const Span<int> corner_verts = args.corner_verts;
|
||||||
|
const Span<MLoopTri> looptris = args.mlooptri;
|
||||||
|
const Span<int> looptri_faces = args.looptri_faces;
|
||||||
|
const bool *hide_poly = args.hide_poly;
|
||||||
|
|
||||||
|
float *data = static_cast<float *>(GPU_vertbuf_get_data(&vert_buf));
|
||||||
|
for (const int looptri_i : args.prim_indices) {
|
||||||
|
if (hide_poly && hide_poly[looptri_faces[looptri_i]]) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
for (int i : IndexRange(3)) {
|
||||||
|
const int vert = corner_verts[looptris[looptri_i].tri[i]];
|
||||||
|
*data = mask[vert];
|
||||||
|
data++;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
MutableSpan(static_cast<float *>(GPU_vertbuf_get_data(vbo.vert_buf)), totvert)
|
MutableSpan(static_cast<float *>(GPU_vertbuf_get_data(vbo.vert_buf)), totvert).fill(0);
|
||||||
.fill(0.0f);
|
|
||||||
}
|
}
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
case CD_PBVH_FSET_TYPE: {
|
else if (vbo.type == CD_PBVH_FSET_TYPE) {
|
||||||
BLI_assert(vbo.domain == ATTR_DOMAIN_FACE);
|
|
||||||
|
|
||||||
const int *face_sets = static_cast<const int *>(
|
const int *face_sets = static_cast<const int *>(
|
||||||
CustomData_get_layer_named(args.face_data, CD_PROP_INT32, ".sculpt_face_set"));
|
CustomData_get_layer_named(args.face_data, CD_PROP_INT32, ".sculpt_face_set"));
|
||||||
uchar4 *data = static_cast<uchar4 *>(GPU_vertbuf_get_data(vbo.vert_buf));
|
uchar4 *data = static_cast<uchar4 *>(GPU_vertbuf_get_data(vbo.vert_buf));
|
||||||
@ -745,41 +887,27 @@ struct PBVHBatches {
|
|||||||
else {
|
else {
|
||||||
MutableSpan(data, totvert).fill(uchar4(255));
|
MutableSpan(data, totvert).fill(uchar4(255));
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
const bke::AttributeAccessor attributes = args.me->attributes();
|
||||||
|
const eCustomDataType data_type = eCustomDataType(vbo.type);
|
||||||
|
const GVArraySpan attribute = *attributes.lookup_or_default(vbo.name, vbo.domain, data_type);
|
||||||
|
bke::attribute_math::convert_to_static_type(data_type, [&](auto dummy) {
|
||||||
|
using T = decltype(dummy);
|
||||||
|
switch (vbo.domain) {
|
||||||
|
case ATTR_DOMAIN_POINT:
|
||||||
|
extract_data_vert_faces<T>(args, attribute.typed<T>(), vert_buf);
|
||||||
break;
|
break;
|
||||||
}
|
case ATTR_DOMAIN_FACE:
|
||||||
case CD_PROP_COLOR: {
|
extract_data_face_faces<T>(args, attribute.typed<T>(), vert_buf);
|
||||||
const MPropCol *data = static_cast<const MPropCol *>(CustomData_get_layer_named(
|
|
||||||
get_cdata(vbo.domain, args), CD_PROP_COLOR, vbo.name.c_str()));
|
|
||||||
if (vbo.domain == ATTR_DOMAIN_POINT) {
|
|
||||||
extract_data_vert_faces<MPropCol, ushort4>(args, {data, args.me->totvert}, vert_buf);
|
|
||||||
}
|
|
||||||
else if (vbo.domain == ATTR_DOMAIN_CORNER) {
|
|
||||||
extract_data_corner_faces<MPropCol, ushort4>(args, {data, args.me->totloop}, vert_buf);
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
}
|
case ATTR_DOMAIN_CORNER:
|
||||||
case CD_PROP_BYTE_COLOR: {
|
extract_data_corner_faces<T>(args, attribute.typed<T>(), vert_buf);
|
||||||
const MLoopCol *data = static_cast<const MLoopCol *>(CustomData_get_layer_named(
|
|
||||||
get_cdata(vbo.domain, args), CD_PROP_BYTE_COLOR, vbo.name.c_str()));
|
|
||||||
if (vbo.domain == ATTR_DOMAIN_POINT) {
|
|
||||||
extract_data_vert_faces<MLoopCol, ushort4>(args, {data, args.me->totvert}, vert_buf);
|
|
||||||
}
|
|
||||||
else if (vbo.domain == ATTR_DOMAIN_CORNER) {
|
|
||||||
extract_data_corner_faces<MLoopCol, ushort4>(args, {data, args.me->totloop}, vert_buf);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case CD_PROP_FLOAT2: {
|
|
||||||
const float2 *data = static_cast<const float2 *>(CustomData_get_layer_named(
|
|
||||||
get_cdata(vbo.domain, args), CD_PROP_FLOAT2, vbo.name.c_str()));
|
|
||||||
if (vbo.domain == ATTR_DOMAIN_POINT) {
|
|
||||||
extract_data_vert_faces<float2, float2>(args, {data, args.me->totvert}, vert_buf);
|
|
||||||
}
|
|
||||||
else if (vbo.domain == ATTR_DOMAIN_CORNER) {
|
|
||||||
extract_data_corner_faces<float2, float2>(args, {data, args.me->totloop}, vert_buf);
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
|
default:
|
||||||
|
BLI_assert_unreachable();
|
||||||
}
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -803,6 +931,7 @@ struct PBVHBatches {
|
|||||||
|
|
||||||
void fill_vbo_bmesh(PBVHVbo &vbo, const PBVH_GPU_Args &args)
|
void fill_vbo_bmesh(PBVHVbo &vbo, const PBVH_GPU_Args &args)
|
||||||
{
|
{
|
||||||
|
using namespace blender;
|
||||||
faces_count = tris_count = count_faces(args);
|
faces_count = tris_count = count_faces(args);
|
||||||
|
|
||||||
int existing_num = GPU_vertbuf_get_vertex_len(vbo.vert_buf);
|
int existing_num = GPU_vertbuf_get_vertex_len(vbo.vert_buf);
|
||||||
@ -826,42 +955,7 @@ struct PBVHBatches {
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
const eCustomDataType type = eCustomDataType(vbo.type);
|
if (vbo.type == CD_PBVH_CO_TYPE) {
|
||||||
if (vbo.domain == ATTR_DOMAIN_POINT) {
|
|
||||||
const int cd_offset = CustomData_get_offset_named(&args.bm->vdata, type, vbo.name.c_str());
|
|
||||||
switch (type) {
|
|
||||||
case CD_PROP_COLOR:
|
|
||||||
extract_data_vert_bmesh<MPropCol, ushort4>(args, cd_offset, *vbo.vert_buf);
|
|
||||||
return;
|
|
||||||
case CD_PROP_BYTE_COLOR:
|
|
||||||
extract_data_vert_bmesh<MLoopCol, ushort4>(args, cd_offset, *vbo.vert_buf);
|
|
||||||
return;
|
|
||||||
case CD_PROP_FLOAT2:
|
|
||||||
extract_data_vert_bmesh<float2, float2>(args, cd_offset, *vbo.vert_buf);
|
|
||||||
return;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (vbo.domain == ATTR_DOMAIN_CORNER) {
|
|
||||||
const int cd_offset = CustomData_get_offset_named(&args.bm->ldata, type, vbo.name.c_str());
|
|
||||||
switch (type) {
|
|
||||||
case CD_PROP_COLOR:
|
|
||||||
extract_data_corner_bmesh<MPropCol, ushort4>(args, cd_offset, *vbo.vert_buf);
|
|
||||||
return;
|
|
||||||
case CD_PROP_BYTE_COLOR:
|
|
||||||
extract_data_corner_bmesh<MLoopCol, ushort4>(args, cd_offset, *vbo.vert_buf);
|
|
||||||
return;
|
|
||||||
case CD_PROP_FLOAT2:
|
|
||||||
extract_data_corner_bmesh<float2, float2>(args, cd_offset, *vbo.vert_buf);
|
|
||||||
return;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (vbo.type) {
|
|
||||||
case CD_PBVH_CO_TYPE: {
|
|
||||||
float3 *data = static_cast<float3 *>(GPU_vertbuf_get_data(vbo.vert_buf));
|
float3 *data = static_cast<float3 *>(GPU_vertbuf_get_data(vbo.vert_buf));
|
||||||
for (const BMFace *f : *args.bm_faces) {
|
for (const BMFace *f : *args.bm_faces) {
|
||||||
if (BM_elem_flag_test(f, BM_ELEM_HIDDEN)) {
|
if (BM_elem_flag_test(f, BM_ELEM_HIDDEN)) {
|
||||||
@ -875,9 +969,8 @@ struct PBVHBatches {
|
|||||||
*data = l->next->v->co;
|
*data = l->next->v->co;
|
||||||
data++;
|
data++;
|
||||||
}
|
}
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
case CD_PBVH_NO_TYPE: {
|
else if (vbo.type == CD_PBVH_NO_TYPE) {
|
||||||
short4 *data = static_cast<short4 *>(GPU_vertbuf_get_data(vbo.vert_buf));
|
short4 *data = static_cast<short4 *>(GPU_vertbuf_get_data(vbo.vert_buf));
|
||||||
for (const BMFace *f : *args.bm_faces) {
|
for (const BMFace *f : *args.bm_faces) {
|
||||||
if (BM_elem_flag_test(f, BM_ELEM_HIDDEN)) {
|
if (BM_elem_flag_test(f, BM_ELEM_HIDDEN)) {
|
||||||
@ -885,32 +978,44 @@ struct PBVHBatches {
|
|||||||
}
|
}
|
||||||
if (BM_elem_flag_test(f, BM_ELEM_SMOOTH)) {
|
if (BM_elem_flag_test(f, BM_ELEM_SMOOTH)) {
|
||||||
const BMLoop *l = f->l_first;
|
const BMLoop *l = f->l_first;
|
||||||
*data = convert_value<float3, short4>(l->prev->v->no);
|
*data = normal_float_to_short(l->prev->v->no);
|
||||||
data++;
|
data++;
|
||||||
*data = convert_value<float3, short4>(l->v->no);
|
*data = normal_float_to_short(l->v->no);
|
||||||
data++;
|
data++;
|
||||||
*data = convert_value<float3, short4>(l->next->v->no);
|
*data = normal_float_to_short(l->next->v->no);
|
||||||
data++;
|
data++;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
std::fill_n(data, 3, convert_value<float3, short4>(f->no));
|
std::fill_n(data, 3, normal_float_to_short(f->no));
|
||||||
data += 3;
|
data += 3;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
case CD_PBVH_MASK_TYPE: {
|
else if (vbo.type == CD_PBVH_MASK_TYPE) {
|
||||||
if (args.cd_mask_layer != -1) {
|
const int cd_offset = args.cd_mask_layer;
|
||||||
extract_data_vert_bmesh<float, float>(args, args.cd_mask_layer, *vbo.vert_buf);
|
if (cd_offset != -1) {
|
||||||
|
float *data = static_cast<float *>(GPU_vertbuf_get_data(vbo.vert_buf));
|
||||||
|
|
||||||
|
for (const BMFace *f : *args.bm_faces) {
|
||||||
|
if (BM_elem_flag_test(f, BM_ELEM_HIDDEN)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
const BMLoop *l = f->l_first;
|
||||||
|
*data = bmesh_cd_vert_get<float>(*l->prev->v, cd_offset);
|
||||||
|
data++;
|
||||||
|
*data = bmesh_cd_vert_get<float>(*l->v, cd_offset);
|
||||||
|
data++;
|
||||||
|
*data = bmesh_cd_vert_get<float>(*l->next->v, cd_offset);
|
||||||
|
data++;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
MutableSpan(static_cast<float *>(GPU_vertbuf_get_data(vbo.vert_buf)),
|
MutableSpan(static_cast<float *>(GPU_vertbuf_get_data(vbo.vert_buf)),
|
||||||
GPU_vertbuf_get_vertex_len(vbo.vert_buf))
|
GPU_vertbuf_get_vertex_len(vbo.vert_buf))
|
||||||
.fill(0.0f);
|
.fill(0.0f);
|
||||||
}
|
}
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
case CD_PBVH_FSET_TYPE: {
|
else if (vbo.type == CD_PBVH_FSET_TYPE) {
|
||||||
BLI_assert(vbo.domain == ATTR_DOMAIN_FACE);
|
BLI_assert(vbo.domain == ATTR_DOMAIN_FACE);
|
||||||
|
|
||||||
const int cd_offset = CustomData_get_offset_named(
|
const int cd_offset = CustomData_get_offset_named(
|
||||||
@ -940,8 +1045,28 @@ struct PBVHBatches {
|
|||||||
else {
|
else {
|
||||||
MutableSpan(data, GPU_vertbuf_get_vertex_len(vbo.vert_buf)).fill(uchar4(255));
|
MutableSpan(data, GPU_vertbuf_get_vertex_len(vbo.vert_buf)).fill(uchar4(255));
|
||||||
}
|
}
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
const eCustomDataType type = eCustomDataType(vbo.type);
|
||||||
|
const CustomData &custom_data = *get_cdata(vbo.domain, args);
|
||||||
|
const int cd_offset = CustomData_get_offset_named(&custom_data, type, vbo.name.c_str());
|
||||||
|
|
||||||
|
bke::attribute_math::convert_to_static_type(eCustomDataType(vbo.type), [&](auto dummy) {
|
||||||
|
using T = decltype(dummy);
|
||||||
|
switch (vbo.domain) {
|
||||||
|
case ATTR_DOMAIN_POINT:
|
||||||
|
extract_data_vert_bmesh<T>(args, cd_offset, *vbo.vert_buf);
|
||||||
|
break;
|
||||||
|
case ATTR_DOMAIN_FACE:
|
||||||
|
extract_data_face_bmesh<T>(args, cd_offset, *vbo.vert_buf);
|
||||||
|
break;
|
||||||
|
case ATTR_DOMAIN_CORNER:
|
||||||
|
extract_data_corner_bmesh<T>(args, cd_offset, *vbo.vert_buf);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
BLI_assert_unreachable();
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -965,6 +1090,7 @@ struct PBVHBatches {
|
|||||||
const StringRefNull name,
|
const StringRefNull name,
|
||||||
const PBVH_GPU_Args &args)
|
const PBVH_GPU_Args &args)
|
||||||
{
|
{
|
||||||
|
using namespace blender;
|
||||||
PBVHVbo vbo(domain, type, name);
|
PBVHVbo vbo(domain, type, name);
|
||||||
GPUVertFormat format;
|
GPUVertFormat format;
|
||||||
|
|
||||||
@ -973,42 +1099,29 @@ struct PBVHBatches {
|
|||||||
|
|
||||||
GPU_vertformat_clear(&format);
|
GPU_vertformat_clear(&format);
|
||||||
|
|
||||||
switch (type) {
|
if (type == CD_PBVH_CO_TYPE) {
|
||||||
case CD_PBVH_CO_TYPE:
|
|
||||||
GPU_vertformat_attr_add(&format, "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT);
|
GPU_vertformat_attr_add(&format, "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT);
|
||||||
break;
|
|
||||||
case CD_PROP_FLOAT3:
|
|
||||||
GPU_vertformat_attr_add(&format, "a", GPU_COMP_F32, 3, GPU_FETCH_FLOAT);
|
|
||||||
need_aliases = true;
|
|
||||||
break;
|
|
||||||
case CD_PBVH_NO_TYPE:
|
|
||||||
GPU_vertformat_attr_add(&format, "nor", GPU_COMP_I16, 3, GPU_FETCH_INT_TO_FLOAT_UNIT);
|
|
||||||
break;
|
|
||||||
case CD_PROP_FLOAT2:
|
|
||||||
GPU_vertformat_attr_add(&format, "a", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
|
|
||||||
need_aliases = true;
|
|
||||||
break;
|
|
||||||
case CD_PBVH_FSET_TYPE:
|
|
||||||
GPU_vertformat_attr_add(&format, "fset", GPU_COMP_U8, 3, GPU_FETCH_INT_TO_FLOAT_UNIT);
|
|
||||||
break;
|
|
||||||
case CD_PBVH_MASK_TYPE:
|
|
||||||
GPU_vertformat_attr_add(&format, "msk", GPU_COMP_F32, 1, GPU_FETCH_FLOAT);
|
|
||||||
break;
|
|
||||||
case CD_PROP_FLOAT:
|
|
||||||
GPU_vertformat_attr_add(&format, "f", GPU_COMP_F32, 1, GPU_FETCH_FLOAT);
|
|
||||||
need_aliases = true;
|
|
||||||
break;
|
|
||||||
case CD_PROP_COLOR:
|
|
||||||
case CD_PROP_BYTE_COLOR: {
|
|
||||||
GPU_vertformat_attr_add(&format, "c", GPU_COMP_U16, 4, GPU_FETCH_INT_TO_FLOAT_UNIT);
|
|
||||||
need_aliases = true;
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
default:
|
else if (type == CD_PBVH_NO_TYPE) {
|
||||||
printf("%s: Unsupported attribute type %u\n", __func__, type);
|
GPU_vertformat_attr_add(&format, "nor", GPU_COMP_I16, 3, GPU_FETCH_INT_TO_FLOAT_UNIT);
|
||||||
BLI_assert_unreachable();
|
}
|
||||||
|
else if (type == CD_PBVH_FSET_TYPE) {
|
||||||
return;
|
GPU_vertformat_attr_add(&format, "fset", GPU_COMP_U8, 3, GPU_FETCH_INT_TO_FLOAT_UNIT);
|
||||||
|
}
|
||||||
|
else if (type == CD_PBVH_MASK_TYPE) {
|
||||||
|
GPU_vertformat_attr_add(&format, "msk", GPU_COMP_F32, 1, GPU_FETCH_FLOAT);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
bke::attribute_math::convert_to_static_type(eCustomDataType(type), [&](auto dummy) {
|
||||||
|
using T = decltype(dummy);
|
||||||
|
using Converter = draw::AttributeConverter<T>;
|
||||||
|
GPU_vertformat_attr_add(&format,
|
||||||
|
"data",
|
||||||
|
Converter::gpu_component_type,
|
||||||
|
Converter::gpu_component_len,
|
||||||
|
Converter::gpu_fetch_mode);
|
||||||
|
});
|
||||||
|
need_aliases = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (need_aliases) {
|
if (need_aliases) {
|
||||||
@ -1403,7 +1516,7 @@ struct PBVHBatches {
|
|||||||
for (int i : IndexRange(attrs_num)) {
|
for (int i : IndexRange(attrs_num)) {
|
||||||
PBVHAttrReq *attr = attrs + i;
|
PBVHAttrReq *attr = attrs + i;
|
||||||
|
|
||||||
if (!valid_pbvh_attr(attr->type)) {
|
if (!pbvh_attr_supported(attr->type, attr->domain)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user