52 if (tan_layers == 0 && use_orco_tan &&
60 if (tan_layers & (1 <<
i)) {
65 SNPRINTF(attr_name,
"t%s", attr_safe_name);
76 STRNCPY(r_tangent_names[tan_len++], layer_name);
79 if (use_orco_tan && orco.
is_empty()) {
89 orco_allocated[
v] = eve->
co;
99 orco = orco_allocated;
104 if (tan_len != 0 || use_orco_tan) {
105 short tangent_mask = 0;
106 bool calc_active_tangent =
false;
123 mr.
mesh->corner_tris(),
124 mr.
mesh->corner_tri_faces(),
130 mr.
mesh->vert_normals(),
144 SNPRINTF(attr_name,
"t%s", attr_safe_name);
151 if (
format->attr_len == 0) {
157 *r_use_orco_tan = use_orco_tan;
159 *r_tan_len = tan_len;
191 for (
int i = 0;
i < tan_len;
i++) {
192 const char *name = tangent_names[
i];
195 for (
int corner = 0; corner < mr.
corners_num; corner++) {
197 (*tan_data)[3] = (layer_data[corner][3] > 0.0f) ? SHRT_MAX : SHRT_MIN;
204 for (
int corner = 0; corner < mr.
corners_num; corner++) {
206 (*tan_data)[3] = (layer_data[corner][3] > 0.0f) ? SHRT_MAX : SHRT_MIN;
213 for (
int i = 0;
i < tan_len;
i++) {
214 const char *name = tangent_names[
i];
217 for (
int corner = 0; corner < mr.
corners_num; corner++) {
219 tan_data->
w = (layer_data[corner][3] > 0.0f) ? 1 : -2;
226 for (
int corner = 0; corner < mr.
corners_num; corner++) {
228 tan_data->
w = (layer_data[corner][3] > 0.0f) ? 1 : -2;
278 int pack_layer_index = 0;
279 for (
int i = 0;
i < tan_len;
i++) {
281 const char *name = tangent_names[
i];
284 for (
int corner = 0; corner < mr.
corners_num; corner++) {
285 *tan_data = layer_data[corner];
286 (*tan_data)[3] = (layer_data[corner][3] > 0.0f) ? 1.0f : -1.0f;
293 const int dst_offset = int(subdiv_cache.
num_subdiv_loops) * 4 * pack_layer_index++;
300 for (
int corner = 0; corner < mr.
corners_num; corner++) {
301 *tan_data = layer_data[corner];
302 (*tan_data)[3] = (layer_data[corner][3] > 0.0f) ? 1.0f : -1.0f;
309 const int dst_offset = int(subdiv_cache.
num_subdiv_loops) * 4 * pack_layer_index++;
const void * CustomData_get_layer_n(const CustomData *data, eCustomDataType type, int n)
const void * CustomData_get_layer(const CustomData *data, eCustomDataType type)
const void * CustomData_get_layer_named(const CustomData *data, eCustomDataType type, blender::StringRef name)
void CustomData_reset(CustomData *data)
const char * CustomData_get_layer_name(const CustomData *data, eCustomDataType type, int n)
void CustomData_free(CustomData *data)
int CustomData_get_layer_index(const CustomData *data, eCustomDataType type)
int CustomData_get_active_layer(const CustomData *data, eCustomDataType type)
int CustomData_get_render_layer(const CustomData *data, eCustomDataType type)
void BKE_editmesh_loop_tangent_calc(BMEditMesh *em, bool calc_active_tangent, const char(*tangent_names)[MAX_CUSTOMDATA_LAYER_NAME], int tangent_names_len, blender::Span< blender::float3 > face_normals, blender::Span< blender::float3 > corner_normals, blender::Span< blender::float3 > vert_orco, CustomData *dm_loopdata_out, uint dm_loopdata_out_len, short *tangent_mask_curr_p)
void BKE_mesh_orco_verts_transform(Mesh *mesh, blender::MutableSpan< blender::float3 > orco, bool invert)
void BKE_mesh_calc_loop_tangent_ex(blender::Span< blender::float3 > vert_positions, blender::OffsetIndices< int > faces, blender::Span< int > corner_verts, blender::Span< blender::int3 > corner_tris, blender::Span< int > corner_tri_faces, blender::Span< bool > sharp_faces, const CustomData *loopdata, bool calc_active_tangent, const char(*tangent_names)[MAX_CUSTOMDATA_LAYER_NAME], int tangent_names_len, blender::Span< blender::float3 > vert_normals, blender::Span< blender::float3 > face_normals, blender::Span< blender::float3 > corner_normals, blender::Span< blender::float3 > vert_orco, CustomData *loopdata_out, uint loopdata_out_len, short *tangent_mask_curr_p)
#define SNPRINTF(dst, format,...)
char * STRNCPY(char(&dst)[N], const char *src)
blender::gpu::VertBuf * GPU_vertbuf_create_on_device(const GPUVertFormat &format, uint v_len)
#define GPU_vertbuf_create_with_format(format)
void GPU_vertbuf_tag_dirty(blender::gpu::VertBuf *verts)
blender::gpu::VertBuf * GPU_vertbuf_calloc()
void GPU_vertbuf_data_alloc(blender::gpu::VertBuf &verts, uint v_len)
void GPU_vertbuf_init_with_format_ex(blender::gpu::VertBuf &verts, const GPUVertFormat &format, GPUUsageType)
void GPU_vertbuf_discard(blender::gpu::VertBuf *)
BMesh const char void * data
BLI_INLINE BMVert * BM_vert_at_index(BMesh *bm, const int index)
ATTR_WARN_UNUSED_RESULT const BMVert * v
constexpr int64_t size() const
void reinitialize(const int64_t new_size)
constexpr bool is_empty() const
#define MAX_CUSTOMDATA_LAYER_NAME
gpu::VertBufPtr extract_tangents_subdiv(const MeshRenderData &mr, const DRWSubdivCache &subdiv_cache, const MeshBatchCache &cache)
void draw_subdiv_interp_custom_data(const DRWSubdivCache &cache, gpu::VertBuf &src_data, gpu::VertBuf &dst_data, GPUVertCompType comp_type, int dimensions, int dst_offset)
gpu::VertBufPtr extract_tangents(const MeshRenderData &mr, const MeshBatchCache &cache, bool use_hq)
static const GPUVertFormat & get_coarse_tan_format()
static void extract_tan_init_common(const MeshRenderData &mr, const MeshBatchCache &cache, GPUVertFormat *format, GPUVertCompType comp_type, GPUVertFetchMode fetch_mode, CustomData *r_loop_data, int *r_v_len, int *r_tan_len, char r_tangent_names[MAX_MTFACE][MAX_CUSTOMDATA_LAYER_NAME], bool *r_use_orco_tan)
GPUType convert_normal(const float3 &src)
std::unique_ptr< gpu::VertBuf, gpu::VertBufDeleter > VertBufPtr
blender::VecBase< int16_t, 4 > short4
VecBase< float, 4 > float4
VecBase< float, 3 > float3
Span< float3 > vert_positions
MeshExtractType extract_type
VArraySpan< bool > sharp_faces
Span< float3 > bm_face_normals
Span< float3 > face_normals
Span< float3 > corner_normals
OffsetIndices< int > faces
Array< float3 > bm_loop_normals