Blender  V3.3
Public Attributes | List of all members
MLoopTri Struct Reference

#include <DNA_meshdata_types.h>

Public Attributes

unsigned int tri [3]
 
unsigned int poly
 

Detailed Description

MLoopTri's are lightweight triangulation data, for functionality that doesn't support ngons (MPoly). This is cache data created from (MPoly, MLoop & MVert arrays). There is no attempt to maintain this data's validity over time, any changes to the underlying mesh invalidate the MLoopTri array, which will need to be re-calculated.

Users normally access this via BKE_mesh_runtime_looptri_ensure. In rare cases its calculated directly, with BKE_mesh_recalc_looptri.

Typical usage includes:

Storing loop indices (instead of vertex indices) allows us to directly access UV's, vertex-colors as well as vertices. The index of the source polygon is stored as well, giving access to materials and polygon normals.

Note
This data is runtime only, never written to disk.

Usage examples:

// access original material.
short mat_nr = mpoly[lt->poly].mat_nr;
// access vertex locations.
float *vtri_co[3] = {
mvert[mloop[lt->tri[0]].v].co,
mvert[mloop[lt->tri[1]].v].co,
mvert[mloop[lt->tri[2]].v].co,
};
// access UV coordinates (works for all loop data, vertex colors... etc).
float *uvtri_co[3] = {
mloopuv[lt->tri[0]].uv,
mloopuv[lt->tri[1]].uv,
mloopuv[lt->tri[2]].uv,
};

MLoopTri's are allocated in an array, where each polygon's MLoopTri's are stored contiguously, the number of triangles for each polygon is guaranteed to be (MPoly.totloop - 2), even for degenerate geometry. See ME_POLY_TRI_TOT macro.

It's also possible to perform a reverse lookup (find all MLoopTri's for any given MPoly).

// loop over all looptri's for a given polygon: i
MPoly *mp = &mpoly[i];
MLoopTri *lt = &looptri[poly_to_tri_count(i, mp->loopstart)];
int j, lt_tot = ME_POLY_TRI_TOT(mp);
for (j = 0; j < lt_tot; j++, lt++) {
unsigned int vtri[3] = {
mloop[lt->tri[0]].v,
mloop[lt->tri[1]].v,
mloop[lt->tri[2]].v,
};
printf("tri %u %u %u\n", vtri[0], vtri[1], vtri[2]);
};
MINLINE int poly_to_tri_count(int poly_count, int corner_count)
#define ME_POLY_TRI_TOT(mp)
unsigned int tri[3]

It may also be useful to check whether or not two vertices of a triangle form an edge in the underlying mesh.

This can be done by checking the edge of the referenced loop (MLoop.e), the winding of the MLoopTri and the MLoop's will always match, however the order of vertices in the edge is undefined.

// print real edges from an MLoopTri: lt
int j, j_next;
for (j = 2, j_next = 0; j_next < 3; j = j_next++) {
MEdge *ed = &medge[mloop[lt->tri[j]].e];
unsigned int tri_edge[2] = {mloop[lt->tri[j]].v, mloop[lt->tri[j_next]].v};
if (((ed->v1 == tri_edge[0]) && (ed->v2 == tri_edge[1])) ||
((ed->v1 == tri_edge[1]) && (ed->v2 == tri_edge[0])))
{
printf("real edge found %u %u\n", tri_edge[0], tri_edge[1]);
}
}
unsigned int v1
unsigned int v2

See BKE_mesh_looptri_get_real_edges for a utility that does this.

Note
A MLoopTri may be in the middle of an ngon and not reference any edges.

Definition at line 220 of file DNA_meshdata_types.h.

Member Data Documentation

◆ poly

unsigned int MLoopTri::poly

Definition at line 222 of file DNA_meshdata_types.h.

Referenced by apply_heights_callback(), apply_tangmat_callback(), bake_targets_populate_pixels_color_attributes(), BKE_mesh_origindex_map_create_looptri(), BKE_mesh_remap_calc_edges_from_mesh(), BKE_mesh_remap_calc_loops_from_mesh(), BKE_mesh_remap_calc_polys_from_mesh(), BKE_mesh_remap_calc_verts_from_mesh(), BKE_remesh_reproject_sculpt_face_sets(), BKE_shrinkwrap_compute_smooth_normal(), blender::draw::bvh_overlap_cb(), C_BVHTree_FromObject(), ccgDM_recalcLoopTri(), dm_ts_GetNumVertsOfFace(), dm_ts_GetPosition(), dm_ts_GetTextureCoordinate(), do_multires_bake_thread(), blender::draw::extract_edituv_tris_iter_looptri_mesh(), blender::draw::extract_lines_adjacency_iter_looptri_mesh(), blender::draw::extract_tris_single_mat_iter_looptri_mesh(), blender::render::texturemargin::generate_margin(), get_ccgdm_data(), blender::nodes::node_geo_transfer_attribute_cc::get_closest_mesh_polygons(), gpu_pbvh_is_looptri_visible(), GPU_pbvh_mesh_buffers_build(), GPU_pbvh_mesh_buffers_update(), imapaint_pick_uv(), Freestyle::BlenderFileLoader::insertShapeNode(), leaf_needs_material_split(), lineart_load_tri_task(), mesh_calc_tri_tessface(), meshdeform_ray_tree_intersect(), partition_indices_material(), pbvh_faces_node_raycast(), pbvh_update_normals_accum_task_cb(), project_paint_check_face_sel(), project_paint_clone_face_skip(), project_paint_prepare_all_faces(), project_paint_uvpixel_mask(), ps_tri_index_to_mpoly(), raycastMesh(), RE_bake_pixels_populate(), blender::bke::mesh_surface_sample::sample_face_attribute(), blender::draw::statvis_calc_intersect(), blender::draw::statvis_calc_thickness(), and blender::ed::curves::convert_to_particle_system::try_convert_single_object().

◆ tri

unsigned int MLoopTri::tri[3]

Definition at line 221 of file DNA_meshdata_types.h.

Referenced by blender::geometry::add_curves_on_mesh(), apply_heights_callback(), apply_tangmat_callback(), bake_targets_populate_pixels_color_attributes(), BKE_mesh_calc_normals_looptri(), BKE_mesh_calc_volume(), BKE_mesh_looptri_get_real_edges(), BKE_mesh_remap_calc_loops_from_mesh(), BKE_mesh_runtime_verttri_from_looptri(), BKE_mesh_vert_looptri_map_create(), BKE_pbvh_build_mesh(), BKE_pbvh_ensure_node_loops(), BKE_shrinkwrap_compute_smooth_normal(), build_mesh_leaf_node(), bvh_callback(), blender::draw::bvh_overlap_cb(), C_BVHTree_FromObject(), cb_mlooptri_edges_get(), cb_mlooptri_verts_get(), ccgDM_recalcLoopTri(), check_seam(), closest_point_on_surface(), blender::nodes::node_geo_distribute_points_on_faces_cc::compute_attribute_outputs(), blender::bke::mesh_surface_sample::compute_bary_coord_in_triangle(), blender::geometry::compute_surface_point_normal(), createFaceRingMap(), dm_ts_GetNormal(), dm_ts_GetPosition(), dm_ts_GetTextureCoordinate(), dm_ts_SetTSpace(), blender::bke::pbvh::pixels::do_encode_pixels(), do_multires_bake_thread(), dynamic_paint_create_uv_surface_direct_cb(), dynamic_paint_create_uv_surface_neighbor_cb(), dynamic_paint_find_island_border(), dynamic_paint_paint_mesh_cell_point_cb_ex(), ED_draw_object_facemap(), blender::bke::mesh_surface_sample::MeshAttributeInterpolator::ensure_barycentric_coords(), blender::bke::mesh_surface_sample::MeshAttributeInterpolator::ensure_nearest_weights(), blender::draw::extract_edituv_tris_iter_looptri_mesh(), blender::draw::extract_lines_adjacency_iter_looptri_mesh(), blender::draw::extract_tris_iter_poly_mesh(), blender::draw::extract_tris_single_mat_iter_looptri_mesh(), find_internal_spring_target_vertex(), blender::render::texturemargin::generate_margin(), GPU_pbvh_mesh_buffers_update(), heat_ray_tree_create(), imapaint_pick_uv(), blender::bke::pbvh::pixels::init_triangles(), initSystem(), insert_seam_vert_array(), Freestyle::BlenderFileLoader::insertShapeNode(), interp_barycentric_mlooptri(), lineart_edge_neighbor_init_task(), lineart_load_tri_task(), mesh_calc_center_centroid_ex(), mesh_calc_tessellation_for_face_impl(), mesh_calc_tri_tessface(), mesh_faces_to_scratch(), mesh_looptri_nearest_point(), mesh_looptri_raycast_backface_culling_cb(), mesh_looptri_spherecast(), mesh_looptri_target_project(), mesh_tris_nearest_point_dp(), mesh_tris_spherecast_dp(), paint_is_face_hidden(), pbvh_faces_node_nearest_to_ray(), pbvh_faces_node_raycast(), pbvh_update_normals_accum_task_cb(), project_bucket_point_occluded(), project_face_seams_init(), project_paint_delayed_face_init(), project_paint_face_init(), project_paint_PickFace(), project_paint_prepare_all_faces(), project_paint_uvpixel_mask(), RE_bake_pixels_populate(), blender::geometry::ReverseUVSampler::ReverseUVSampler(), blender::geometry::ReverseUVSampler::sample(), blender::bke::mesh_surface_sample::sample_corner_attribute(), blender::bke::mesh_surface_sample::sample_corner_attrribute_with_bary_coords(), blender::nodes::node_geo_distribute_points_on_faces_cc::sample_mesh_surface(), blender::bke::mesh_surface_sample::sample_point_attribute(), blender::ed::sculpt_paint::AddOperationExecutor::sample_spherical(), blender::bke::mesh_surface_sample::sample_surface_points_spherical(), blender::draw::statvis_calc_thickness(), Freestyle::testEdgeMark(), blender::nodes::node_geo_distribute_points_on_faces_cc::update_elimination_mask_based_on_density_factors(), and uv_image_outset().


The documentation for this struct was generated from the following file: