Python API: add loop triangles access, remove tessfaces.

Loop triangles are tessellated triangles create from polygons, for renderers
or exporters that need to match Blender's polygon tesselation exactly. These
are a read-only runtime cache.

Tessfaces are a legacy data structure from before Blender supported n-gons,
and were already mostly removed from the C code.

Details on porting code to loop triangles is in the release notes.

Differential Revision: https://developer.blender.org/D3539
This commit is contained in:
Brecht Van Lommel
2018-09-06 14:28:14 +02:00
parent 468474a653
commit e65784a051
21 changed files with 261 additions and 1236 deletions

View File

@@ -83,7 +83,7 @@ When writing scripts that operate on editmode data you will normally want to re-
running the script, this needs to be called explicitly.
The BMesh its self does not store the triangulated faces, they are stored in the :class:`bpy.types.Mesh`,
to refresh tessellation faces call :class:`bpy.types.Mesh.calc_tessface`.
to refresh tessellation triangles call :class:`bpy.types.Mesh.calc_loop_triangles`.
CustomData Access

View File

@@ -164,26 +164,26 @@ for list removal, but these are slower.
Sometimes its faster (but more memory hungry) to just rebuild the list.
Say you want to remove all triangular faces in a list.
Say you want to remove all triangular polygons in a list.
Rather than...
.. code-block:: python
faces = mesh.tessfaces[:] # make a list copy of the meshes faces
f_idx = len(faces) # Loop backwards
while f_idx: # while the value is not 0
f_idx -= 1
polygons = mesh.polygons[:] # make a list copy of the meshes polygons
p_idx = len(polygons) # Loop backwards
while p_idx: # while the value is not 0
p_idx -= 1
if len(faces[f_idx].vertices) == 3:
faces.pop(f_idx) # remove the triangle
if len(polygons[p_idx].vertices) == 3:
polygons.pop(p_idx) # remove the triangle
It's faster to build a new list with list comprehension.
.. code-block:: python
faces = [f for f in mesh.tessfaces if len(f.vertices) != 3]
polygons = [p for p in mesh.polygons if len(p.vertices) != 3]
Adding List Items

View File

@@ -173,25 +173,25 @@ In this situation you can...
.. _info_gotcha_mesh_faces:
N-Gons and Tessellation Faces
=============================
N-Gons and Tessellation
=======================
Since 2.63 NGons are supported, this adds some complexity
since in some cases you need to access triangles/quads still (some exporters for example).
since in some cases you need to access triangles still (some exporters for example).
There are now 3 ways to access faces:
- :class:`bpy.types.MeshPolygon` -
this is the data structure which now stores faces in object mode
(access as ``mesh.polygons`` rather than ``mesh.faces``).
- :class:`bpy.types.MeshTessFace` -
the result of triangulating (tessellated) polygons,
the main method of face access in 2.62 or older (access as ``mesh.tessfaces``).
- :class:`bpy.types.MeshLoopTriangle` -
the result of tessellating polygons into triangles
(access as ``mesh.loop_triangles``).
- :class:`bmesh.types.BMFace` -
the polygons as used in editmode.
For the purpose of the following documentation,
these will be referred to as polygons, tessfaces and bmesh-faces respectively.
these will be referred to as polygons, loop triangles and bmesh-faces respectively.
5+ sided faces will be referred to as ``ngons``.
@@ -234,13 +234,8 @@ All 3 datatypes can be used for face creation.
- polygons are the most efficient way to create faces but the data structure is _very_ rigid and inflexible,
you must have all your vertes and faces ready and create them all at once.
This is further complicated by the fact that each polygon does not store its own verts (as with tessfaces),
This is further complicated by the fact that each polygon does not store its own verts,
rather they reference an index and size in :class:`bpy.types.Mesh.loops` which are a fixed array too.
- tessfaces ideally should not be used for creating faces since they are really only tessellation cache of polygons,
however for scripts upgrading from 2.62 this is by far the most straightforward option.
This works by creating tessfaces and when finished -
they can be converted into polygons by calling :class:`bpy.types.Mesh.update`.
The obvious limitation is ngons can't be created this way.
- bmesh-faces are most likely the easiest way for new scripts to create faces,
since faces can be added one by one and the api has features intended for mesh manipulation.
While :class:`bmesh.types.BMesh` uses more memory it can be managed by only operating on one mesh at a time.
@@ -271,30 +266,6 @@ the choice mostly depends on whether the target format supports ngons or not.
since using bmesh gives some overhead because its not the native storage format in object mode.
Upgrading Importers from 2.62
-----------------------------
Importers can be upgraded to work with only minor changes.
The main change to be made is used the tessellation versions of each attribute.
- mesh.faces --> :class:`bpy.types.Mesh.tessfaces`
- mesh.uv_textures --> :class:`bpy.types.Mesh.tessface_uv_textures`
- mesh.vertex_colors --> :class:`bpy.types.Mesh.tessface_vertex_colors`
Once the data is created call :class:`bpy.types.Mesh.update` to convert the tessfaces into polygons.
Upgrading Exporters from 2.62
-----------------------------
For exporters the most direct way to upgrade is to use tessfaces as with importing
however its important to know that tessfaces may **not** exist for a mesh,
the array will be empty as if there are no faces.
So before accessing tessface data call: :class:`bpy.types.Mesh.update` ``(calc_tessface=True)``.
EditBones, PoseBones, Bone... Bones
===================================

View File

@@ -247,11 +247,11 @@ static bool ObtainCacheParticleUV(Mesh *mesh,
b_psys.particles.begin(b_pa);
for(; pa_no < totparts+totchild; pa_no++) {
/* Add UVs */
BL::Mesh::tessface_uv_textures_iterator l;
b_mesh->tessface_uv_textures.begin(l);
BL::Mesh::uv_layers_iterator l;
b_mesh->uv_layers.begin(l);
float3 uv = make_float3(0.0f, 0.0f, 0.0f);
if(b_mesh->tessface_uv_textures.length())
if(b_mesh->uv_layers.length())
b_psys.uv_on_emitter(psmd, *b_pa, pa_no, uv_num, &uv.x);
CData->curve_uv.push_back_slow(uv);
@@ -306,11 +306,11 @@ static bool ObtainCacheParticleVcol(Mesh *mesh,
b_psys.particles.begin(b_pa);
for(; pa_no < totparts+totchild; pa_no++) {
/* Add vertex colors */
BL::Mesh::tessface_vertex_colors_iterator l;
b_mesh->tessface_vertex_colors.begin(l);
BL::Mesh::vertex_colors_iterator l;
b_mesh->vertex_colors.begin(l);
float3 vcol = make_float3(0.0f, 0.0f, 0.0f);
if(b_mesh->tessface_vertex_colors.length())
if(b_mesh->vertex_colors.length())
b_psys.mcol_on_emitter(psmd, *b_pa, pa_no, vcol_num, &vcol.x);
CData->curve_vcol.push_back_slow(vcol);
@@ -968,10 +968,10 @@ void BlenderSync::sync_curves(Mesh *mesh,
/* create vertex color attributes */
if(!motion) {
BL::Mesh::tessface_vertex_colors_iterator l;
BL::Mesh::vertex_colors_iterator l;
int vcol_num = 0;
for(b_mesh.tessface_vertex_colors.begin(l); l != b_mesh.tessface_vertex_colors.end(); ++l, vcol_num++) {
for(b_mesh.vertex_colors.begin(l); l != b_mesh.vertex_colors.end(); ++l, vcol_num++) {
if(!mesh->need_attribute(scene, ustring(l->name().c_str())))
continue;
@@ -1005,10 +1005,10 @@ void BlenderSync::sync_curves(Mesh *mesh,
/* create UV attributes */
if(!motion) {
BL::Mesh::tessface_uv_textures_iterator l;
BL::Mesh::uv_layers_iterator l;
int uv_num = 0;
for(b_mesh.tessface_uv_textures.begin(l); l != b_mesh.tessface_uv_textures.end(); ++l, uv_num++) {
for(b_mesh.uv_layers.begin(l); l != b_mesh.uv_layers.end(); ++l, uv_num++) {
bool active_render = l->active_render();
AttributeStandard std = (active_render)? ATTR_STD_UV: ATTR_STD_NONE;
ustring name = ustring(l->name().c_str());

View File

@@ -35,46 +35,6 @@
CCL_NAMESPACE_BEGIN
/* Per-face bit flags. */
enum {
/* Face has no special flags. */
FACE_FLAG_NONE = (0 << 0),
/* Quad face was split using 1-3 diagonal. */
FACE_FLAG_DIVIDE_13 = (1 << 0),
/* Quad face was split using 2-4 diagonal. */
FACE_FLAG_DIVIDE_24 = (1 << 1),
};
/* Get vertex indices to create triangles from a given face.
*
* Two triangles has vertex indices in the original Blender-side face.
* If face is already a quad tri_b will not be initialized.
*/
inline void face_split_tri_indices(const int face_flag,
int tri_a[3],
int tri_b[3])
{
if(face_flag & FACE_FLAG_DIVIDE_24) {
tri_a[0] = 0;
tri_a[1] = 1;
tri_a[2] = 3;
tri_b[0] = 2;
tri_b[1] = 3;
tri_b[2] = 1;
}
else {
/* Quad with FACE_FLAG_DIVIDE_13 or single triangle. */
tri_a[0] = 0;
tri_a[1] = 1;
tri_a[2] = 2;
tri_b[0] = 0;
tri_b[1] = 2;
tri_b[2] = 3;
}
}
/* Tangent Space */
struct MikkUserData {
@@ -379,8 +339,6 @@ static void create_mesh_volume_attributes(Scene *scene,
static void attr_create_vertex_color(Scene *scene,
Mesh *mesh,
BL::Mesh& b_mesh,
const vector<int>& nverts,
const vector<int>& face_flags,
bool subdivision)
{
if(subdivision) {
@@ -401,15 +359,15 @@ static void attr_create_vertex_color(Scene *scene,
int n = p->loop_total();
for(int i = 0; i < n; i++) {
float3 color = get_float3(l->data[p->loop_start() + i].color());
/* Encode vertex color using the sRGB curve. */
/* Compress/encode vertex color using the sRGB curve. */
*(cdata++) = color_float_to_byte(color_srgb_to_linear_v3(color));
}
}
}
}
else {
BL::Mesh::tessface_vertex_colors_iterator l;
for(b_mesh.tessface_vertex_colors.begin(l); l != b_mesh.tessface_vertex_colors.end(); ++l) {
BL::Mesh::vertex_colors_iterator l;
for(b_mesh.vertex_colors.begin(l); l != b_mesh.vertex_colors.end(); ++l) {
if(!mesh->need_attribute(scene, ustring(l->name().c_str())))
continue;
@@ -417,35 +375,20 @@ static void attr_create_vertex_color(Scene *scene,
TypeDesc::TypeColor,
ATTR_ELEMENT_CORNER_BYTE);
BL::MeshColorLayer::data_iterator c;
BL::Mesh::loop_triangles_iterator t;
uchar4 *cdata = attr->data_uchar4();
size_t i = 0;
for(l->data.begin(c); c != l->data.end(); ++c, ++i) {
int tri_a[3], tri_b[3];
face_split_tri_indices(face_flags[i], tri_a, tri_b);
for(b_mesh.loop_triangles.begin(t); t != b_mesh.loop_triangles.end(); ++t) {
int3 li = get_int3(t->loops());
float3 c1 = get_float3(l->data[li[0]].color());
float3 c2 = get_float3(l->data[li[1]].color());
float3 c3 = get_float3(l->data[li[2]].color());
/* Encode vertex color using the sRGB curve. */
uchar4 colors[4];
colors[0] = color_float_to_byte(color_srgb_to_linear_v3(get_float3(c->color1())));
colors[1] = color_float_to_byte(color_srgb_to_linear_v3(get_float3(c->color2())));
colors[2] = color_float_to_byte(color_srgb_to_linear_v3(get_float3(c->color3())));
if(nverts[i] == 4) {
colors[3] = color_float_to_byte(color_srgb_to_linear_v3(get_float3(c->color4())));
}
cdata[0] = colors[tri_a[0]];
cdata[1] = colors[tri_a[1]];
cdata[2] = colors[tri_a[2]];
if(nverts[i] == 4) {
cdata[3] = colors[tri_b[0]];
cdata[4] = colors[tri_b[1]];
cdata[5] = colors[tri_b[2]];
cdata += 6;
}
else
cdata += 3;
/* Compress/encode vertex color using the sRGB curve. */
cdata[0] = color_float_to_byte(color_srgb_to_linear_v3(c1));
cdata[1] = color_float_to_byte(color_srgb_to_linear_v3(c2));
cdata[2] = color_float_to_byte(color_srgb_to_linear_v3(c3));
cdata += 3;
}
}
}
@@ -454,14 +397,12 @@ static void attr_create_vertex_color(Scene *scene,
/* Create uv map attributes. */
static void attr_create_uv_map(Scene *scene,
Mesh *mesh,
BL::Mesh& b_mesh,
const vector<int>& nverts,
const vector<int>& face_flags)
BL::Mesh& b_mesh)
{
if(b_mesh.tessface_uv_textures.length() != 0) {
BL::Mesh::tessface_uv_textures_iterator l;
if(b_mesh.uv_layers.length() != 0) {
BL::Mesh::uv_layers_iterator l;
for(b_mesh.tessface_uv_textures.begin(l); l != b_mesh.tessface_uv_textures.end(); ++l) {
for(b_mesh.uv_layers.begin(l); l != b_mesh.uv_layers.end(); ++l) {
const bool active_render = l->active_render();
AttributeStandard uv_std = (active_render)? ATTR_STD_UV: ATTR_STD_NONE;
ustring uv_name = ustring(l->name().c_str());
@@ -493,33 +434,15 @@ static void attr_create_uv_map(Scene *scene,
ATTR_ELEMENT_CORNER);
}
BL::MeshTextureFaceLayer::data_iterator t;
BL::Mesh::loop_triangles_iterator t;
float3 *fdata = uv_attr->data_float3();
size_t i = 0;
for(l->data.begin(t); t != l->data.end(); ++t, ++i) {
int tri_a[3], tri_b[3];
face_split_tri_indices(face_flags[i], tri_a, tri_b);
float3 uvs[4];
uvs[0] = get_float3(t->uv1());
uvs[1] = get_float3(t->uv2());
uvs[2] = get_float3(t->uv3());
if(nverts[i] == 4) {
uvs[3] = get_float3(t->uv4());
}
fdata[0] = uvs[tri_a[0]];
fdata[1] = uvs[tri_a[1]];
fdata[2] = uvs[tri_a[2]];
for(b_mesh.loop_triangles.begin(t); t != b_mesh.loop_triangles.end(); ++t) {
int3 li = get_int3(t->loops());
fdata[0] = get_float3(l->data[li[0]].uv());
fdata[1] = get_float3(l->data[li[1]].uv());
fdata[2] = get_float3(l->data[li[2]].uv());
fdata += 3;
if(nverts[i] == 4) {
fdata[0] = uvs[tri_b[0]];
fdata[1] = uvs[tri_b[1]];
fdata[2] = uvs[tri_b[2]];
fdata += 3;
}
}
}
@@ -822,7 +745,7 @@ static void create_mesh(Scene *scene,
{
/* count vertices and faces */
int numverts = b_mesh.vertices.length();
int numfaces = (!subdivision) ? b_mesh.tessfaces.length() : b_mesh.polygons.length();
int numfaces = (!subdivision) ? b_mesh.loop_triangles.length() : b_mesh.polygons.length();
int numtris = 0;
int numcorners = 0;
int numngons = 0;
@@ -834,14 +757,10 @@ static void create_mesh(Scene *scene,
}
BL::Mesh::vertices_iterator v;
BL::Mesh::tessfaces_iterator f;
BL::Mesh::polygons_iterator p;
if(!subdivision) {
for(b_mesh.tessfaces.begin(f); f != b_mesh.tessfaces.end(); ++f) {
int4 vi = get_int4(f->vertices_raw());
numtris += (vi[3] == 0)? 1: 2;
}
numtris = numfaces;
}
else {
for(b_mesh.polygons.begin(p); p != b_mesh.polygons.end(); ++p) {
@@ -869,7 +788,7 @@ static void create_mesh(Scene *scene,
/* create generated coordinates from undeformed coordinates */
const bool need_default_tangent =
(subdivision == false) &&
(b_mesh.tessface_uv_textures.length() == 0) &&
(b_mesh.uv_layers.length() == 0) &&
(mesh->need_attribute(scene, ATTR_STD_UV_TANGENT));
if(mesh->need_attribute(scene, ATTR_STD_GENERATED) ||
need_default_tangent)
@@ -890,19 +809,21 @@ static void create_mesh(Scene *scene,
/* create faces */
vector<int> nverts(numfaces);
vector<int> face_flags(numfaces, FACE_FLAG_NONE);
int fi = 0;
if(!subdivision) {
for(b_mesh.tessfaces.begin(f); f != b_mesh.tessfaces.end(); ++f, ++fi) {
int4 vi = get_int4(f->vertices_raw());
int n = (vi[3] == 0)? 3: 4;
int shader = clamp(f->material_index(), 0, used_shaders.size()-1);
bool smooth = f->use_smooth() || use_loop_normals;
BL::Mesh::loop_triangles_iterator t;
int ti = 0;
for(b_mesh.loop_triangles.begin(t); t != b_mesh.loop_triangles.end(); ++t, ++ti) {
BL::MeshPolygon p = b_mesh.polygons[t->polygon_index()];
int3 vi = get_int3(t->vertices());
int shader = clamp(p.material_index(), 0, used_shaders.size()-1);
bool smooth = p.use_smooth() || use_loop_normals;
if(use_loop_normals) {
BL::Array<float, 12> loop_normals = f->split_normals();
for(int i = 0; i < n; i++) {
BL::Array<float, 9> loop_normals = t->split_normals();
for(int i = 0; i < 3; i++) {
N[vi[i]] = make_float3(loop_normals[i * 3],
loop_normals[i * 3 + 1],
loop_normals[i * 3 + 2]);
@@ -913,25 +834,8 @@ static void create_mesh(Scene *scene,
*
* NOTE: Autosmooth is already taken care about.
*/
if(n == 4) {
if(is_zero(cross(mesh->verts[vi[1]] - mesh->verts[vi[0]], mesh->verts[vi[2]] - mesh->verts[vi[0]])) ||
is_zero(cross(mesh->verts[vi[2]] - mesh->verts[vi[0]], mesh->verts[vi[3]] - mesh->verts[vi[0]])))
{
mesh->add_triangle(vi[0], vi[1], vi[3], shader, smooth);
mesh->add_triangle(vi[2], vi[3], vi[1], shader, smooth);
face_flags[fi] |= FACE_FLAG_DIVIDE_24;
}
else {
mesh->add_triangle(vi[0], vi[1], vi[2], shader, smooth);
mesh->add_triangle(vi[0], vi[2], vi[3], shader, smooth);
face_flags[fi] |= FACE_FLAG_DIVIDE_13;
}
}
else {
mesh->add_triangle(vi[0], vi[1], vi[2], shader, smooth);
}
nverts[fi] = n;
mesh->add_triangle(vi[0], vi[1], vi[2], shader, smooth);
nverts[ti] = 3;
}
}
else {
@@ -957,13 +861,13 @@ static void create_mesh(Scene *scene,
* The calculate functions will check whether they're needed or not.
*/
attr_create_pointiness(scene, mesh, b_mesh, subdivision);
attr_create_vertex_color(scene, mesh, b_mesh, nverts, face_flags, subdivision);
attr_create_vertex_color(scene, mesh, b_mesh, subdivision);
if(subdivision) {
attr_create_subd_uv_map(scene, mesh, b_mesh, subdivide_uvs);
}
else {
attr_create_uv_map(scene, mesh, b_mesh, nverts, face_flags);
attr_create_uv_map(scene, mesh, b_mesh);
}
/* for volume objects, create a matrix to transform from object space to

View File

@@ -83,7 +83,7 @@ static inline BL::Mesh object_to_mesh(BL::BlendData& data,
}
}
if(subdivision_type == Mesh::SUBDIVISION_NONE) {
me.calc_tessface(true);
me.calc_loop_triangles();
}
}
return me;

View File

@@ -20,13 +20,12 @@
__all__ = (
"mesh_linked_uv_islands",
"mesh_linked_tessfaces",
"mesh_linked_triangles",
"edge_face_count_dict",
"edge_face_count",
"edge_loops_from_tessfaces",
"edge_loops_from_edges",
"ngon_tessellate",
"face_random_points",
"triangle_random_points",
)
@@ -90,41 +89,41 @@ def mesh_linked_uv_islands(mesh):
return poly_islands
def mesh_linked_tessfaces(mesh):
def mesh_linked_triangles(mesh):
"""
Splits the mesh into connected faces, use this for separating cubes from
Splits the mesh into connected triangles, use this for separating cubes from
other mesh elements within 1 mesh datablock.
:arg mesh: the mesh used to group with.
:type mesh: :class:`bpy.types.Mesh`
:return: lists of lists containing faces.
:return: lists of lists containing triangles.
:rtype: list
"""
# Build vert face connectivity
vert_faces = [[] for i in range(len(mesh.vertices))]
for f in mesh.tessfaces:
for v in f.vertices:
vert_faces[v].append(f)
vert_tris = [[] for i in range(len(mesh.vertices))]
for t in mesh.loop_triangles:
for v in t.vertices:
vert_tris[v].append(t)
# sort faces into connectivity groups
face_groups = [[f] for f in mesh.tessfaces]
# map old, new face location
face_mapping = list(range(len(mesh.tessfaces)))
# sort triangles into connectivity groups
tri_groups = [[t] for t in mesh.loop_triangles]
# map old, new tri location
tri_mapping = list(range(len(mesh.loop_triangles)))
# Now clump faces iteratively
# Now clump triangles iteratively
ok = True
while ok:
ok = False
for i, f in enumerate(mesh.tessfaces):
mapped_index = face_mapping[f.index]
mapped_group = face_groups[mapped_index]
for i, t in enumerate(mesh.loop_triangles):
mapped_index = tri_mapping[t.index]
mapped_group = tri_groups[mapped_index]
for v in f.vertices:
for nxt_f in vert_faces[v]:
if nxt_f != f:
nxt_mapped_index = face_mapping[nxt_f.index]
for v in t.vertices:
for nxt_t in vert_tris[v]:
if nxt_t != t:
nxt_mapped_index = tri_mapping[nxt_t.index]
# We are not a part of the same group
if mapped_index != nxt_mapped_index:
@@ -132,18 +131,18 @@ def mesh_linked_tessfaces(mesh):
# Assign mapping to this group so they
# all map to this group
for grp_f in face_groups[nxt_mapped_index]:
face_mapping[grp_f.index] = mapped_index
for grp_t in tri_groups[nxt_mapped_index]:
tri_mapping[grp_t.index] = mapped_index
# Move faces into this group
mapped_group.extend(face_groups[nxt_mapped_index])
# Move triangles into this group
mapped_group.extend(tri_groups[nxt_mapped_index])
# remove reference to the list
face_groups[nxt_mapped_index] = None
tri_groups[nxt_mapped_index] = None
# return all face groups that are not null
# this is all the faces that are connected in their own lists.
return [fg for fg in face_groups if fg]
# return all tri groups that are not null
# this is all the triangles that are connected in their own lists.
return [tg for tg in tri_groups if tg]
def edge_face_count_dict(mesh):
@@ -177,87 +176,6 @@ def edge_face_count(mesh):
return [get(edge_face_count, ed.key, 0) for ed in mesh.edges]
def edge_loops_from_tessfaces(mesh, tessfaces=None, seams=()):
"""
Edge loops defined by faces
Takes me.tessfaces or a list of faces and returns the edge loops
These edge loops are the edges that sit between quads, so they don't touch
1 quad, note: not connected will make 2 edge loops,
both only containing 2 edges.
return a list of edge key lists
[[(0, 1), (4, 8), (3, 8)], ...]
:arg mesh: the mesh used to get edge loops from.
:type mesh: :class:`bpy.types.Mesh`
:arg tessfaces: optional face list to only use some of the meshes faces.
:type tessfaces: :class:`bpy.types.MeshTessFace`, sequence or or NoneType
:return: return a list of edge vertex index lists.
:rtype: list
"""
OTHER_INDEX = 2, 3, 0, 1 # opposite face index
if tessfaces is None:
tessfaces = mesh.tessfaces
edges = {}
for f in tessfaces:
if len(f.vertices) == 4:
edge_keys = f.edge_keys
for i, edkey in enumerate(f.edge_keys):
edges.setdefault(edkey, []).append(edge_keys[OTHER_INDEX[i]])
for edkey in seams:
edges[edkey] = []
# Collect edge loops here
edge_loops = []
for edkey, ed_adj in edges.items():
if 0 < len(ed_adj) < 3: # 1 or 2
# Seek the first edge
context_loop = [edkey, ed_adj[0]]
edge_loops.append(context_loop)
if len(ed_adj) == 2:
other_dir = ed_adj[1]
else:
other_dir = None
del ed_adj[:]
flipped = False
while 1:
# from knowing the last 2, look for the next.
ed_adj = edges[context_loop[-1]]
if len(ed_adj) != 2:
# the original edge had 2 other edges
if other_dir and flipped is False:
flipped = True # only flip the list once
context_loop.reverse()
del ed_adj[:]
context_loop.append(other_dir) # save 1 look-up
ed_adj = edges[context_loop[-1]]
if len(ed_adj) != 2:
del ed_adj[:]
break
else:
del ed_adj[:]
break
i = ed_adj.index(context_loop[-2])
context_loop.append(ed_adj[not i])
# Don't look at this again
del ed_adj[:]
return edge_loops
def edge_loops_from_edges(mesh, edges=None):
"""
Edge loops defined by edges
@@ -511,54 +429,42 @@ def ngon_tessellate(from_data, indices, fix_loops=True):
return fill
def face_random_points(num_points, tessfaces):
def triangle_random_points(num_points, loop_triangles):
"""
Generates a list of random points over mesh tessfaces.
Generates a list of random points over mesh loop triangles.
:arg num_points: the number of random points to generate on each face.
:arg num_points: the number of random points to generate on each triangle.
:type int:
:arg tessfaces: list of the faces to generate points on.
:type tessfaces: :class:`bpy.types.MeshTessFace`, sequence
:return: list of random points over all faces.
:arg loop_triangles: list of the triangles to generate points on.
:type loop_triangles: :class:`bpy.types.MeshLoopTriangle`, sequence
:return: list of random points over all triangles.
:rtype: list
"""
from random import random
from mathutils.geometry import area_tri
# Split all quads into 2 tris, tris remain unchanged
tri_faces = []
for f in tessfaces:
tris = []
verts = f.id_data.vertices
fv = f.vertices[:]
tris.append((verts[fv[0]].co,
verts[fv[1]].co,
verts[fv[2]].co,
))
if len(fv) == 4:
tris.append((verts[fv[0]].co,
verts[fv[3]].co,
verts[fv[2]].co,
))
tri_faces.append(tris)
# For each triangle, generate the required number of random points
sampled_points = [None] * (num_points * len(loop_triangles))
for i, lt in enumerate(loop_triangles):
# Get triangle vertex coordinates
verts = lt.id_data.vertices
ltv = lt.vertices[:]
tv = (verts[ltv[0]].co, verts[ltv[1]].co, verts[ltv[2]].co)
# For each face, generate the required number of random points
sampled_points = [None] * (num_points * len(tessfaces))
for i, tf in enumerate(tri_faces):
for k in range(num_points):
# If this is a quad, we need to weight its 2 tris by their area
if len(tf) != 1:
area1 = area_tri(*tf[0])
area2 = area_tri(*tf[1])
if len(tv) != 1:
area1 = area_tri(*tv[0])
area2 = area_tri(*tv[1])
area_tot = area1 + area2
area1 = area1 / area_tot
area2 = area2 / area_tot
vecs = tf[0 if (random() < area1) else 1]
vecs = tv[0 if (random() < area1) else 1]
else:
vecs = tf[0]
vecs = tv[0]
u1 = random()
u2 = random()

View File

@@ -468,7 +468,7 @@ class MeshEdge(StructRNA):
return ord_ind(*tuple(self.vertices))
class MeshTessFace(StructRNA):
class MeshLoopTriangle(StructRNA):
__slots__ = ()
@property
@@ -476,32 +476,18 @@ class MeshTessFace(StructRNA):
"""The midpoint of the face."""
face_verts = self.vertices[:]
mesh_verts = self.id_data.vertices
if len(face_verts) == 3:
return (mesh_verts[face_verts[0]].co +
mesh_verts[face_verts[1]].co +
mesh_verts[face_verts[2]].co
) / 3.0
else:
return (mesh_verts[face_verts[0]].co +
mesh_verts[face_verts[1]].co +
mesh_verts[face_verts[2]].co +
mesh_verts[face_verts[3]].co
) / 4.0
return (mesh_verts[face_verts[0]].co +
mesh_verts[face_verts[1]].co +
mesh_verts[face_verts[2]].co
) / 3.0
@property
def edge_keys(self):
verts = self.vertices[:]
if len(verts) == 3:
return (ord_ind(verts[0], verts[1]),
ord_ind(verts[1], verts[2]),
ord_ind(verts[2], verts[0]),
)
else:
return (ord_ind(verts[0], verts[1]),
ord_ind(verts[1], verts[2]),
ord_ind(verts[2], verts[3]),
ord_ind(verts[3], verts[0]),
)
return (ord_ind(verts[0], verts[1]),
ord_ind(verts[1], verts[2]),
ord_ind(verts[2], verts[0]),
)
class MeshPolygon(StructRNA):

View File

@@ -179,7 +179,7 @@ void BKE_mesh_split_faces(struct Mesh *mesh, bool free_loop_normals);
struct Mesh *BKE_mesh_new_from_object(
struct Depsgraph *depsgraph, struct Main *bmain, struct Scene *sce, struct Object *ob,
const bool apply_modifiers, const bool calc_tessface, const bool calc_undeformed);
const bool apply_modifiers, const bool calc_loop_triangles, const bool calc_undeformed);
struct Mesh *BKE_mesh_create_derived_for_modifier(
struct Depsgraph *depsgraph, struct Scene *scene, struct Object *ob,
struct ModifierData *md, int build_shapekey_layers);

View File

@@ -840,7 +840,7 @@ void BKE_mesh_to_curve(Main *bmain, Depsgraph *depsgraph, Scene *scene, Object *
/* settings: 1 - preview, 2 - render */
Mesh *BKE_mesh_new_from_object(
Depsgraph *depsgraph, Main *bmain, Scene *sce, Object *ob,
const bool apply_modifiers, const bool calc_tessface, const bool calc_undeformed)
const bool apply_modifiers, const bool calc_loop_triangles, const bool calc_undeformed)
{
Mesh *tmpmesh;
Curve *tmpcu = NULL, *copycu;
@@ -1069,9 +1069,9 @@ Mesh *BKE_mesh_new_from_object(
break;
} /* end copy materials */
if (calc_tessface) {
if (calc_loop_triangles) {
/* cycles and exporters rely on this still */
BKE_mesh_tessface_ensure(tmpmesh);
BKE_mesh_runtime_looptri_ensure(tmpmesh);
}
return tmpmesh;

View File

@@ -107,13 +107,13 @@ NodeGroup *BlenderFileLoader::Load()
bool apply_modifiers = false;
bool calc_undeformed = false;
bool calc_tessface = false;
bool calc_loop_triangles = false;
Mesh *mesh = BKE_mesh_new_from_object(depsgraph,
_re->main,
_re->scene,
ob,
apply_modifiers,
calc_tessface,
calc_loop_triangles,
calc_undeformed);
if (mesh) {

View File

@@ -174,8 +174,6 @@ typedef struct MLoop {
*
* \note A #MLoopTri may be in the middle of an ngon and not reference **any** edges.
*/
#
#
typedef struct MLoopTri {
unsigned int tri[3];
unsigned int poly;

View File

@@ -390,7 +390,7 @@ extern StructRNA RNA_MeshLoopColorLayer;
extern StructRNA RNA_MeshDeformModifier;
extern StructRNA RNA_MeshEdge;
extern StructRNA RNA_MeshPolygon;
extern StructRNA RNA_MeshTessFace;
extern StructRNA RNA_MeshLoopTriangle;
extern StructRNA RNA_MeshLoop;
extern StructRNA RNA_MeshFloatProperty;
extern StructRNA RNA_MeshFloatPropertyLayer;

View File

@@ -490,7 +490,7 @@ int rna_parameter_size(struct PropertyRNA *parm);
struct Mesh *rna_Main_meshes_new_from_object(
struct Main *bmain, struct ReportList *reports, struct Depsgraph *depsgraph,
struct Object *ob, bool apply_modifiers, bool calc_tessface, bool calc_undeformed);
struct Object *ob, bool apply_modifiers, bool calc_loop_triangles, bool calc_undeformed);
/* XXX, these should not need to be defined here~! */
struct MTex *rna_mtex_texture_slots_add(struct ID *self, struct bContext *C, struct ReportList *reports);

View File

@@ -310,7 +310,7 @@ static Mesh *rna_Main_meshes_new(Main *bmain, const char *name)
/* copied from Mesh_getFromObject and adapted to RNA interface */
Mesh *rna_Main_meshes_new_from_object(
Main *bmain, ReportList *reports, Depsgraph *depsgraph,
Object *ob, bool apply_modifiers, bool calc_tessface, bool calc_undeformed)
Object *ob, bool apply_modifiers, bool calc_loop_triangles, bool calc_undeformed)
{
Scene *sce = DEG_get_evaluated_scene(depsgraph);
@@ -326,7 +326,7 @@ Mesh *rna_Main_meshes_new_from_object(
return NULL;
}
return BKE_mesh_new_from_object(depsgraph, bmain, sce, ob, apply_modifiers, calc_tessface, calc_undeformed);
return BKE_mesh_new_from_object(depsgraph, bmain, sce, ob, apply_modifiers, calc_loop_triangles, calc_undeformed);
}
static Lamp *rna_Main_lights_new(Main *bmain, const char *name, int type)
@@ -893,7 +893,7 @@ void RNA_def_main_meshes(BlenderRNA *brna, PropertyRNA *cprop)
RNA_def_parameter_flags(parm, PROP_NEVER_NULL, PARM_REQUIRED);
parm = RNA_def_boolean(func, "apply_modifiers", 0, "", "Apply modifiers");
RNA_def_parameter_flags(parm, 0, PARM_REQUIRED);
RNA_def_boolean(func, "calc_tessface", true, "Calculate Tessellation", "Calculate tessellation faces");
RNA_def_boolean(func, "calc_loop_triangles", true, "Calculate Triangles", "Calculate tesselated triangles");
RNA_def_boolean(func, "calc_undeformed", false, "Calculate Undeformed", "Calculate undeformed vertex coordinates");
parm = RNA_def_pointer(func, "mesh", "Mesh", "",
"Mesh created from object, remove it if it is only used for export");

View File

@@ -70,6 +70,7 @@ const EnumPropertyItem rna_enum_mesh_delimit_mode_items[] = {
#include "BKE_customdata.h"
#include "BKE_main.h"
#include "BKE_mesh.h"
#include "BKE_mesh_runtime.h"
#include "BKE_report.h"
#include "DEG_depsgraph.h"
@@ -139,12 +140,6 @@ static CustomData *rna_mesh_ldata(PointerRNA *ptr)
return rna_mesh_ldata_helper(me);
}
static CustomData *rna_mesh_fdata(PointerRNA *ptr)
{
Mesh *me = rna_mesh(ptr);
return rna_mesh_fdata_helper(me);
}
/* -------------------------------------------------------------------- */
/* Generic CustomData Layer Functions */
@@ -195,12 +190,6 @@ static void rna_MeshLoopLayer_name_set(PointerRNA *ptr, const char *value)
{
rna_cd_layer_name_set(rna_mesh_ldata(ptr), (CustomDataLayer *)ptr->data, value);
}
#if 0
static void rna_MeshTessfaceLayer_name_set(PointerRNA *ptr, const char *value)
{
rna_cd_layer_name_set(rna_mesh_fdata(ptr), (CustomDataLayer *)ptr->data, value);
}
#endif
/* only for layers shared between types */
static void rna_MeshAnyLayer_name_set(PointerRNA *ptr, const char *value)
{
@@ -435,232 +424,57 @@ static void rna_MeshPolygon_flip(ID *id, MPoly *mp)
BKE_mesh_polygon_flip(mp, me->mloop, &me->ldata);
BKE_mesh_tessface_clear(me);
BKE_mesh_runtime_clear_geometry(me);
}
static void rna_MeshTessFace_normal_get(PointerRNA *ptr, float *values)
static void rna_MeshLoopTriangle_verts_get(PointerRNA *ptr, int *values)
{
Mesh *me = rna_mesh(ptr);
MFace *mface = (MFace *)ptr->data;
if (mface->v4)
normal_quad_v3(values, me->mvert[mface->v1].co, me->mvert[mface->v2].co,
me->mvert[mface->v3].co, me->mvert[mface->v4].co);
else
normal_tri_v3(values, me->mvert[mface->v1].co, me->mvert[mface->v2].co, me->mvert[mface->v3].co);
MLoopTri *lt = (MLoopTri *)ptr->data;
values[0] = me->mloop[lt->tri[0]].v;
values[1] = me->mloop[lt->tri[1]].v;
values[2] = me->mloop[lt->tri[2]].v;
}
static void rna_MeshTessFace_split_normals_get(PointerRNA *ptr, float *values)
static void rna_MeshLoopTriangle_normal_get(PointerRNA *ptr, float *values)
{
Mesh *me = rna_mesh(ptr);
MFace *mface = (MFace *)ptr->data;
const short (*vec)[4][3] = CustomData_get(&me->fdata, (int)(mface - me->mface), CD_TESSLOOPNORMAL);
int i = 4;
MLoopTri *lt = (MLoopTri *)ptr->data;
unsigned int v1 = me->mloop[lt->tri[0]].v;
unsigned int v2 = me->mloop[lt->tri[1]].v;
unsigned int v3 = me->mloop[lt->tri[2]].v;
if (!vec) {
while (i--) zero_v3(&values[i * 3]);
normal_tri_v3(values, me->mvert[v1].co, me->mvert[v2].co, me->mvert[v3].co);
}
static void rna_MeshLoopTriangle_split_normals_get(PointerRNA *ptr, float *values)
{
Mesh *me = rna_mesh(ptr);
const float (*lnors)[3] = CustomData_get_layer(&me->ldata, CD_NORMAL);
if (!lnors) {
zero_v3(values + 0);
zero_v3(values + 3);
zero_v3(values + 6);
}
else {
while (i--) normal_short_to_float_v3(&values[i * 3], (const short *)(*vec)[i]);
MLoopTri *lt = (MLoopTri *)ptr->data;
copy_v3_v3(values + 0, lnors[lt->tri[0]]);
copy_v3_v3(values + 3, lnors[lt->tri[1]]);
copy_v3_v3(values + 6, lnors[lt->tri[2]]);
}
}
static float rna_MeshTessFace_area_get(PointerRNA *ptr)
static float rna_MeshLoopTriangle_area_get(PointerRNA *ptr)
{
Mesh *me = rna_mesh(ptr);
MFace *mface = (MFace *)ptr->data;
MLoopTri *lt = (MLoopTri *)ptr->data;
unsigned int v1 = me->mloop[lt->tri[0]].v;
unsigned int v2 = me->mloop[lt->tri[1]].v;
unsigned int v3 = me->mloop[lt->tri[2]].v;
if (mface->v4)
return area_quad_v3(me->mvert[mface->v1].co, me->mvert[mface->v2].co, me->mvert[mface->v3].co,
me->mvert[mface->v4].co);
else
return area_tri_v3(me->mvert[mface->v1].co, me->mvert[mface->v2].co, me->mvert[mface->v3].co);
}
static void rna_MeshTextureFace_uv1_get(PointerRNA *ptr, float *values)
{
MTFace *mtface = (MTFace *)ptr->data;
values[0] = mtface->uv[0][0];
values[1] = mtface->uv[0][1];
}
static void rna_MeshTextureFace_uv1_set(PointerRNA *ptr, const float *values)
{
MTFace *mtface = (MTFace *)ptr->data;
mtface->uv[0][0] = values[0];
mtface->uv[0][1] = values[1];
}
static void rna_MeshTextureFace_uv2_get(PointerRNA *ptr, float *values)
{
MTFace *mtface = (MTFace *)ptr->data;
values[0] = mtface->uv[1][0];
values[1] = mtface->uv[1][1];
}
static void rna_MeshTextureFace_uv2_set(PointerRNA *ptr, const float *values)
{
MTFace *mtface = (MTFace *)ptr->data;
mtface->uv[1][0] = values[0];
mtface->uv[1][1] = values[1];
}
static void rna_MeshTextureFace_uv3_get(PointerRNA *ptr, float *values)
{
MTFace *mtface = (MTFace *)ptr->data;
values[0] = mtface->uv[2][0];
values[1] = mtface->uv[2][1];
}
static void rna_MeshTextureFace_uv3_set(PointerRNA *ptr, const float *values)
{
MTFace *mtface = (MTFace *)ptr->data;
mtface->uv[2][0] = values[0];
mtface->uv[2][1] = values[1];
}
static void rna_MeshTextureFace_uv4_get(PointerRNA *ptr, float *values)
{
MTFace *mtface = (MTFace *)ptr->data;
values[0] = mtface->uv[3][0];
values[1] = mtface->uv[3][1];
}
static void rna_MeshTextureFace_uv4_set(PointerRNA *ptr, const float *values)
{
MTFace *mtface = (MTFace *)ptr->data;
mtface->uv[3][0] = values[0];
mtface->uv[3][1] = values[1];
}
static int rna_CustomDataData_numverts(PointerRNA *ptr, int type)
{
Mesh *me = rna_mesh(ptr);
CustomData *fdata = rna_mesh_fdata(ptr);
CustomDataLayer *cdl;
int a, b;
for (cdl = fdata->layers, a = 0; a < fdata->totlayer; cdl++, a++) {
if (cdl->type == type) {
b = ((char *)ptr->data - ((char *)cdl->data)) / CustomData_sizeof(type);
if (b >= 0 && b < me->totface) {
return (me->mface[b].v4 ? 4 : 3);
}
}
}
return 0;
}
static int rna_MeshTextureFace_uv_get_length(PointerRNA *ptr, int length[RNA_MAX_ARRAY_DIMENSION])
{
length[0] = rna_CustomDataData_numverts(ptr, CD_MTFACE);
length[1] = 2;
return length[0] * length[1];
}
static void rna_MeshTextureFace_uv_get(PointerRNA *ptr, float *values)
{
MTFace *mtface = (MTFace *)ptr->data;
int totvert = rna_CustomDataData_numverts(ptr, CD_MTFACE);
memcpy(values, mtface->uv, totvert * 2 * sizeof(float));
}
static void rna_MeshTextureFace_uv_set(PointerRNA *ptr, const float *values)
{
MTFace *mtface = (MTFace *)ptr->data;
int totvert = rna_CustomDataData_numverts(ptr, CD_MTFACE);
memcpy(mtface->uv, values, totvert * 2 * sizeof(float));
}
/* notice red and blue are swapped */
static void rna_MeshColor_color1_get(PointerRNA *ptr, float *values)
{
MCol *mcol = (MCol *)ptr->data;
values[3] = mcol[0].a / 255.0f;
values[2] = mcol[0].r / 255.0f;
values[1] = mcol[0].g / 255.0f;
values[0] = mcol[0].b / 255.0f;
}
static void rna_MeshColor_color1_set(PointerRNA *ptr, const float *values)
{
MCol *mcol = (MCol *)ptr->data;
mcol[0].a = round_fl_to_uchar_clamp(values[3] * 255.0f);
mcol[0].r = round_fl_to_uchar_clamp(values[2] * 255.0f);
mcol[0].g = round_fl_to_uchar_clamp(values[1] * 255.0f);
mcol[0].b = round_fl_to_uchar_clamp(values[0] * 255.0f);
}
static void rna_MeshColor_color2_get(PointerRNA *ptr, float *values)
{
MCol *mcol = (MCol *)ptr->data;
values[3] = mcol[1].a / 255.0f;
values[2] = mcol[1].r / 255.0f;
values[1] = mcol[1].g / 255.0f;
values[0] = mcol[1].b / 255.0f;
}
static void rna_MeshColor_color2_set(PointerRNA *ptr, const float *values)
{
MCol *mcol = (MCol *)ptr->data;
mcol[1].a = round_fl_to_uchar_clamp(values[3] * 255.0f);
mcol[1].r = round_fl_to_uchar_clamp(values[2] * 255.0f);
mcol[1].g = round_fl_to_uchar_clamp(values[1] * 255.0f);
mcol[1].b = round_fl_to_uchar_clamp(values[0] * 255.0f);
}
static void rna_MeshColor_color3_get(PointerRNA *ptr, float *values)
{
MCol *mcol = (MCol *)ptr->data;
values[3] = mcol[2].a / 255.0f;
values[2] = mcol[2].r / 255.0f;
values[1] = mcol[2].g / 255.0f;
values[0] = mcol[2].b / 255.0f;
}
static void rna_MeshColor_color3_set(PointerRNA *ptr, const float *values)
{
MCol *mcol = (MCol *)ptr->data;
mcol[2].a = round_fl_to_uchar_clamp(values[3] * 255.0f);
mcol[2].r = round_fl_to_uchar_clamp(values[2] * 255.0f);
mcol[2].g = round_fl_to_uchar_clamp(values[1] * 255.0f);
mcol[2].b = round_fl_to_uchar_clamp(values[0] * 255.0f);
}
static void rna_MeshColor_color4_get(PointerRNA *ptr, float *values)
{
MCol *mcol = (MCol *)ptr->data;
values[3] = mcol[3].a / 255.0f;
values[2] = mcol[3].r / 255.0f;
values[1] = mcol[3].g / 255.0f;
values[0] = mcol[3].b / 255.0f;
}
static void rna_MeshColor_color4_set(PointerRNA *ptr, const float *values)
{
MCol *mcol = (MCol *)ptr->data;
mcol[3].a = round_fl_to_uchar_clamp(values[3] * 255.0f);
mcol[3].r = round_fl_to_uchar_clamp(values[2] * 255.0f);
mcol[3].g = round_fl_to_uchar_clamp(values[1] * 255.0f);
mcol[3].b = round_fl_to_uchar_clamp(values[0] * 255.0f);
return area_tri_v3(me->mvert[v1].co, me->mvert[v2].co, me->mvert[v3].co);
}
static void rna_MeshLoopColor_color_get(PointerRNA *ptr, float *values)
@@ -902,93 +716,8 @@ static void rna_MeshUVLoopLayer_clone_set(PointerRNA *ptr, bool value)
rna_CustomDataLayer_clone_set(ptr, rna_mesh_ldata(ptr), value, CD_MLOOPUV);
}
/* face uv_textures */
DEFINE_CUSTOMDATA_LAYER_COLLECTION(tessface_uv_texture, fdata, CD_MTFACE)
DEFINE_CUSTOMDATA_LAYER_COLLECTION_ACTIVEITEM(tessface_uv_texture, fdata, CD_MTFACE, active, MeshTextureFaceLayer)
static void rna_MeshTextureFaceLayer_data_begin(CollectionPropertyIterator *iter, PointerRNA *ptr)
{
Mesh *me = rna_mesh(ptr);
CustomDataLayer *layer = (CustomDataLayer *)ptr->data;
rna_iterator_array_begin(iter, layer->data, sizeof(MTFace), (me->edit_btmesh) ? 0 : me->totface, 0, NULL);
}
static int rna_MeshTextureFaceLayer_data_length(PointerRNA *ptr)
{
Mesh *me = rna_mesh(ptr);
return (me->edit_btmesh) ? 0 : me->totface;
}
static bool rna_MeshTextureFaceLayer_active_render_get(PointerRNA *ptr)
{
return rna_CustomDataLayer_active_get(ptr, rna_mesh_fdata(ptr), CD_MTFACE, 1);
}
static bool rna_MeshTextureFaceLayer_active_get(PointerRNA *ptr)
{
return rna_CustomDataLayer_active_get(ptr, rna_mesh_fdata(ptr), CD_MTFACE, 0);
}
static bool rna_MeshTextureFaceLayer_clone_get(PointerRNA *ptr)
{
return rna_CustomDataLayer_clone_get(ptr, rna_mesh_fdata(ptr), CD_MTFACE);
}
static void rna_MeshTextureFaceLayer_active_render_set(PointerRNA *ptr, bool value)
{
rna_CustomDataLayer_active_set(ptr, rna_mesh_fdata(ptr), value, CD_MTFACE, 1);
}
static void rna_MeshTextureFaceLayer_active_set(PointerRNA *ptr, int value)
{
rna_CustomDataLayer_active_set(ptr, rna_mesh_fdata(ptr), value, CD_MTFACE, 0);
}
static void rna_MeshTextureFaceLayer_clone_set(PointerRNA *ptr, int value)
{
rna_CustomDataLayer_clone_set(ptr, rna_mesh_fdata(ptr), value, CD_MTFACE);
}
/* vertex_color_layers */
DEFINE_CUSTOMDATA_LAYER_COLLECTION(tessface_vertex_color, fdata, CD_MCOL)
DEFINE_CUSTOMDATA_LAYER_COLLECTION_ACTIVEITEM(tessface_vertex_color, fdata, CD_MCOL, active, MeshColorLayer)
DEFINE_CUSTOMDATA_LAYER_COLLECTION_ACTIVEITEM(tessface_vertex_color, fdata, CD_MCOL, render, MeshColorLayer)
static void rna_MeshColorLayer_data_begin(CollectionPropertyIterator *iter, PointerRNA *ptr)
{
Mesh *me = rna_mesh(ptr);
CustomDataLayer *layer = (CustomDataLayer *)ptr->data;
rna_iterator_array_begin(iter, layer->data, sizeof(MCol) * 4, me->totface, 0, NULL);
}
static int rna_MeshColorLayer_data_length(PointerRNA *ptr)
{
Mesh *me = rna_mesh(ptr);
return me->totface;
}
static bool rna_MeshColorLayer_active_render_get(PointerRNA *ptr)
{
return rna_CustomDataLayer_active_get(ptr, rna_mesh_fdata(ptr), CD_MCOL, 1);
}
static bool rna_MeshColorLayer_active_get(PointerRNA *ptr)
{
return rna_CustomDataLayer_active_get(ptr, rna_mesh_fdata(ptr), CD_MCOL, 0);
}
static void rna_MeshColorLayer_active_render_set(PointerRNA *ptr, bool value)
{
rna_CustomDataLayer_active_set(ptr, rna_mesh_fdata(ptr), value, CD_MCOL, 1);
}
static void rna_MeshColorLayer_active_set(PointerRNA *ptr, int value)
{
rna_CustomDataLayer_active_set(ptr, rna_mesh_fdata(ptr), value, CD_MCOL, 0);
}
DEFINE_CUSTOMDATA_LAYER_COLLECTION(vertex_color, ldata, CD_MLOOPCOL)
DEFINE_CUSTOMDATA_LAYER_COLLECTION_ACTIVEITEM(vertex_color, ldata, CD_MLOOPCOL, active, MeshLoopColorLayer)
DEFINE_CUSTOMDATA_LAYER_COLLECTION_ACTIVEITEM(vertex_color, ldata, CD_MLOOPCOL, render, MeshLoopColorLayer)
@@ -1242,30 +971,6 @@ static void rna_Mesh_face_map_remove(struct Mesh *me, ReportList *reports, struc
/* End face maps */
static int rna_MeshTessFace_verts_get_length(PointerRNA *ptr, int length[RNA_MAX_ARRAY_DIMENSION])
{
MFace *face = (MFace *)ptr->data;
if (face)
length[0] = (face->v4) ? 4 : 3;
else
length[0] = 4; /* XXX rna_raw_access wants the length of a dummy face. this needs fixing. - Campbell */
return length[0];
}
static void rna_MeshTessFace_verts_get(PointerRNA *ptr, int *values)
{
MFace *face = (MFace *)ptr->data;
memcpy(values, &face->v1, (face->v4 ? 4 : 3) * sizeof(int));
}
static void rna_MeshTessFace_verts_set(PointerRNA *ptr, const int *values)
{
MFace *face = (MFace *)ptr->data;
memcpy(&face->v1, values, (face->v4 ? 4 : 3) * sizeof(int));
}
/* poly.vertices - this is faked loop access for convenience */
static int rna_MeshPoly_vertices_get_length(PointerRNA *ptr, int length[RNA_MAX_ARRAY_DIMENSION])
{
@@ -1320,11 +1025,25 @@ static int rna_MeshEdge_index_get(PointerRNA *ptr)
return (int)(edge - me->medge);
}
static int rna_MeshTessFace_index_get(PointerRNA *ptr)
static int rna_MeshLoopTriangle_index_get(PointerRNA *ptr)
{
Mesh *me = rna_mesh(ptr);
MFace *face = (MFace *)ptr->data;
return (int)(face - me->mface);
MLoopTri *ltri = (MLoopTri *)ptr->data;
return (int)(ltri - me->runtime.looptris.array);
}
static int rna_MeshLoopTriangle_material_index_get(PointerRNA *ptr)
{
Mesh *me = rna_mesh(ptr);
MLoopTri *ltri = (MLoopTri *)ptr->data;
return me->mpoly[ltri->poly].mat_nr;
}
static bool rna_MeshLoopTriangle_use_smooth_get(PointerRNA *ptr)
{
Mesh *me = rna_mesh(ptr);
MLoopTri *ltri = (MLoopTri *)ptr->data;
return me->mpoly[ltri->poly].flag & ME_SMOOTH;
}
static int rna_MeshPolygon_index_get(PointerRNA *ptr)
@@ -1363,9 +1082,9 @@ static char *rna_MeshPolygon_path(PointerRNA *ptr)
return BLI_sprintfN("polygons[%d]", (int)((MPoly *)ptr->data - rna_mesh(ptr)->mpoly));
}
static char *rna_MeshTessFace_path(PointerRNA *ptr)
static char *rna_MeshLoopTriangle_path(PointerRNA *ptr)
{
return BLI_sprintfN("tessfaces[%d]", (int)((MFace *)ptr->data - rna_mesh(ptr)->mface));
return BLI_sprintfN("loop_triangles[%d]", (int)((MLoopTri *)ptr->data - rna_mesh(ptr)->runtime.looptris.array));
}
static char *rna_MeshEdge_path(PointerRNA *ptr)
@@ -1384,14 +1103,6 @@ static char *rna_MeshVertex_path(PointerRNA *ptr)
return BLI_sprintfN("vertices[%d]", (int)((MVert *)ptr->data - rna_mesh(ptr)->mvert));
}
static char *rna_MeshTextureFaceLayer_path(PointerRNA *ptr)
{
CustomDataLayer *cdl = ptr->data;
char name_esc[sizeof(cdl->name) * 2];
BLI_strescape(name_esc, cdl->name, sizeof(name_esc));
return BLI_sprintfN("tessface_uv_textures[\"%s\"]", name_esc);
}
static char *rna_VertCustomData_data_path(PointerRNA *ptr, const char *collection, int type)
{
CustomDataLayer *cdl;
@@ -1455,46 +1166,11 @@ static char *rna_LoopCustomData_data_path(PointerRNA *ptr, const char *collectio
return NULL;
}
static char *rna_FaceCustomData_data_path(PointerRNA *ptr, const char *collection, int type)
{
CustomDataLayer *cdl;
Mesh *me = rna_mesh(ptr);
CustomData *fdata = rna_mesh_fdata(ptr);
int a, b, totloop = (me->edit_btmesh) ? 0 : me->totloop;
for (cdl = fdata->layers, a = 0; a < fdata->totlayer; cdl++, a++) {
if (cdl->type == type) {
b = ((char *)ptr->data - ((char *)cdl->data)) / CustomData_sizeof(type);
if (b >= 0 && b < totloop) {
char name_esc[sizeof(cdl->name) * 2];
BLI_strescape(name_esc, cdl->name, sizeof(name_esc));
return BLI_sprintfN("%s[\"%s\"].data[%d]", collection, name_esc, b);
}
}
}
return NULL;
}
static char *rna_MeshUVLoop_path(PointerRNA *ptr)
{
return rna_LoopCustomData_data_path(ptr, "uv_layers", CD_MLOOPUV);
}
static char *rna_MeshTextureFace_path(PointerRNA *ptr)
{
return rna_FaceCustomData_data_path(ptr, "tessface_uv_textures", CD_MTFACE);
}
static char *rna_MeshColorLayer_path(PointerRNA *ptr)
{
CustomDataLayer *cdl = ptr->data;
char name_esc[sizeof(cdl->name) * 2];
BLI_strescape(name_esc, cdl->name, sizeof(name_esc));
return BLI_sprintfN("tessface_vertex_colors[\"%s\"]", name_esc);
}
static char *rna_MeshLoopColorLayer_path(PointerRNA *ptr)
{
CustomDataLayer *cdl = ptr->data;
@@ -1721,34 +1397,6 @@ static void rna_Mesh_vertex_color_remove(struct Mesh *me, ReportList *reports, C
}
}
static PointerRNA rna_Mesh_tessface_vertex_color_new(struct Mesh *me, ReportList *reports, const char *name)
{
PointerRNA ptr;
CustomData *fdata;
CustomDataLayer *cdl = NULL;
int index;
if (me->edit_btmesh) {
BKE_report(reports, RPT_ERROR, "Cannot add tessface colors in edit mode");
return PointerRNA_NULL;
}
if (me->mpoly) {
BKE_report(reports, RPT_ERROR, "Cannot add tessface colors when MPoly's exist");
return PointerRNA_NULL;
}
index = ED_mesh_color_add(me, name, false);
if (index != -1) {
fdata = rna_mesh_fdata_helper(me);
cdl = &fdata->layers[CustomData_get_layer_index_n(fdata, CD_MCOL, index)];
}
RNA_pointer_create(&me->id, &RNA_MeshColorLayer, cdl, &ptr);
return ptr;
}
#define DEFINE_CUSTOMDATA_PROPERTY_API(elemname, datatype, cd_prop_type, cdata, countvar, layertype) \
static PointerRNA rna_Mesh_##elemname##_##datatype##_property_new(struct Mesh *me, const char *name) \
{ \
@@ -1796,38 +1444,6 @@ static void rna_Mesh_uv_layers_remove(struct Mesh *me, ReportList *reports, Cust
}
}
/* while this is supposed to be readonly,
* keep it to support importers that only make tessfaces */
static PointerRNA rna_Mesh_tessface_uv_texture_new(struct Mesh *me, ReportList *reports, const char *name)
{
PointerRNA ptr;
CustomData *fdata;
CustomDataLayer *cdl = NULL;
int index;
if (me->edit_btmesh) {
BKE_report(reports, RPT_ERROR, "Cannot add tessface uv's in edit mode");
return PointerRNA_NULL;
}
if (me->mpoly) {
BKE_report(reports, RPT_ERROR, "Cannot add tessface uv's when MPoly's exist");
return PointerRNA_NULL;
}
index = ED_mesh_uv_texture_add(me, name, false);
if (index != -1) {
fdata = rna_mesh_fdata_helper(me);
cdl = &fdata->layers[CustomData_get_layer_index_n(fdata, CD_MTFACE, index)];
}
RNA_pointer_create(&me->id, &RNA_MeshTextureFaceLayer, cdl, &ptr);
return ptr;
}
static bool rna_Mesh_is_editmode_get(PointerRNA *ptr)
{
Mesh *me = rna_mesh(ptr);
@@ -1840,14 +1456,6 @@ static void UNUSED_FUNCTION(rna_mesh_unused)(void)
/* unused functions made by macros */
(void)rna_Mesh_skin_vertice_index_range;
(void)rna_Mesh_vertex_paint_mask_index_range;
(void)rna_Mesh_tessface_uv_texture_active_set;
(void)rna_Mesh_tessface_uv_texture_index_range;
(void)rna_Mesh_tessface_vertex_color_active_set;
(void)rna_Mesh_tessface_vertex_color_index_range;
(void)rna_Mesh_tessface_vertex_color_render_get;
(void)rna_Mesh_tessface_vertex_color_render_index_get;
(void)rna_Mesh_tessface_vertex_color_render_index_set;
(void)rna_Mesh_tessface_vertex_color_render_set;
(void)rna_Mesh_uv_layer_render_get;
(void)rna_Mesh_uv_layer_render_index_get;
(void)rna_Mesh_uv_layer_render_index_set;
@@ -2009,83 +1617,70 @@ static void rna_def_medge(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Index", "Index of this edge");
}
static void rna_def_mface(BlenderRNA *brna)
static void rna_def_mlooptri(BlenderRNA *brna)
{
StructRNA *srna;
PropertyRNA *prop;
const int splitnor_dim[] = {4, 3};
const int splitnor_dim[] = {3, 3};
srna = RNA_def_struct(brna, "MeshTessFace", NULL);
RNA_def_struct_sdna(srna, "MFace");
RNA_def_struct_ui_text(srna, "Mesh TessFace", "TessFace in a Mesh data-block");
RNA_def_struct_path_func(srna, "rna_MeshTessFace_path");
srna = RNA_def_struct(brna, "MeshLoopTriangle", NULL);
RNA_def_struct_sdna(srna, "MLoopTri");
RNA_def_struct_ui_text(srna, "Mesh Loop Triangle", "Tessellated triangle in a Mesh data-block");
RNA_def_struct_path_func(srna, "rna_MeshLoopTriangle_path");
RNA_def_struct_ui_icon(srna, ICON_FACESEL);
/* XXX allows creating invalid meshes */
prop = RNA_def_property(srna, "vertices", PROP_INT, PROP_UNSIGNED);
RNA_def_property_array(prop, 4);
RNA_def_property_flag(prop, PROP_DYNAMIC);
RNA_def_property_dynamic_array_funcs(prop, "rna_MeshTessFace_verts_get_length");
RNA_def_property_int_funcs(prop, "rna_MeshTessFace_verts_get", "rna_MeshTessFace_verts_set", NULL);
RNA_def_property_ui_text(prop, "Vertices", "Vertex indices");
RNA_def_property_array(prop, 3);
RNA_def_property_int_funcs(prop, "rna_MeshLoopTriangle_verts_get", NULL, NULL);
RNA_def_property_ui_text(prop, "Vertices", "Indices of triangle vertices");
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
/* leaving this fixed size array for foreach_set used in import scripts */
prop = RNA_def_property(srna, "vertices_raw", PROP_INT, PROP_UNSIGNED);
RNA_def_property_int_sdna(prop, NULL, "v1");
RNA_def_property_array(prop, 4);
RNA_def_property_ui_text(prop, "Vertices", "Fixed size vertex indices array");
prop = RNA_def_property(srna, "loops", PROP_INT, PROP_UNSIGNED);
RNA_def_property_int_sdna(prop, NULL, "tri");
RNA_def_property_ui_text(prop, "Loops", "Indices of mesh loops that make up the triangle");
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
prop = RNA_def_property(srna, "material_index", PROP_INT, PROP_UNSIGNED);
RNA_def_property_int_sdna(prop, NULL, "mat_nr");
RNA_def_property_ui_text(prop, "Material Index", "");
#if 0
RNA_def_property_int_funcs(prop, NULL, NULL, "rna_MeshPoly_material_index_range"); /* reuse for tessface is ok */
#endif
RNA_def_property_update(prop, 0, "rna_Mesh_update_data");
prop = RNA_def_property(srna, "select", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", ME_FACE_SEL);
RNA_def_property_ui_text(prop, "Select", "");
RNA_def_property_update(prop, 0, "rna_Mesh_update_select");
prop = RNA_def_property(srna, "hide", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", ME_HIDE);
RNA_def_property_ui_text(prop, "Hide", "");
RNA_def_property_update(prop, 0, "rna_Mesh_update_select");
prop = RNA_def_property(srna, "use_smooth", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", ME_SMOOTH);
RNA_def_property_ui_text(prop, "Smooth", "");
RNA_def_property_update(prop, 0, "rna_Mesh_update_data");
prop = RNA_def_property(srna, "polygon_index", PROP_INT, PROP_UNSIGNED);
RNA_def_property_int_sdna(prop, NULL, "poly");
RNA_def_property_ui_text(prop, "Polygon", "Index of mesh polygon that the triangle is a part of");
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
prop = RNA_def_property(srna, "normal", PROP_FLOAT, PROP_DIRECTION);
RNA_def_property_array(prop, 3);
RNA_def_property_range(prop, -1.0f, 1.0f);
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
RNA_def_property_float_funcs(prop, "rna_MeshTessFace_normal_get", NULL, NULL);
RNA_def_property_ui_text(prop, "Face Normal", "Local space unit length normal vector for this face");
RNA_def_property_float_funcs(prop, "rna_MeshLoopTriangle_normal_get", NULL, NULL);
RNA_def_property_ui_text(prop, "Triangle Normal", "Local space unit length normal vector for this triangle");
prop = RNA_def_property(srna, "split_normals", PROP_FLOAT, PROP_DIRECTION);
RNA_def_property_multi_array(prop, 2, splitnor_dim);
RNA_def_property_range(prop, -1.0f, 1.0f);
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
RNA_def_property_float_funcs(prop, "rna_MeshTessFace_split_normals_get", NULL, NULL);
RNA_def_property_float_funcs(prop, "rna_MeshLoopTriangle_split_normals_get", NULL, NULL);
RNA_def_property_ui_text(prop, "Split Normals",
"Local space unit length split normals vectors of the vertices of this face "
"(must be computed beforehand using calc_normals_split or calc_tangents, "
"and then calc_tessface)");
"Local space unit length split normals vectors of the vertices of this triangle "
"(must be computed beforehand using calc_normals_split or calc_tangents)");
prop = RNA_def_property(srna, "area", PROP_FLOAT, PROP_UNSIGNED);
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
RNA_def_property_float_funcs(prop, "rna_MeshTessFace_area_get", NULL, NULL);
RNA_def_property_ui_text(prop, "Face Area", "Read only area of this face");
RNA_def_property_float_funcs(prop, "rna_MeshLoopTriangle_area_get", NULL, NULL);
RNA_def_property_ui_text(prop, "Triangle Area", "Area of this triangle");
prop = RNA_def_property(srna, "index", PROP_INT, PROP_UNSIGNED);
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
RNA_def_property_int_funcs(prop, "rna_MeshTessFace_index_get", NULL, NULL);
RNA_def_property_ui_text(prop, "Index", "Index of this face");
}
RNA_def_property_int_funcs(prop, "rna_MeshLoopTriangle_index_get", NULL, NULL);
RNA_def_property_ui_text(prop, "Index", "Index of this loop triangle");
prop = RNA_def_property(srna, "material_index", PROP_INT, PROP_UNSIGNED);
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
RNA_def_property_int_funcs(prop, "rna_MeshLoopTriangle_material_index_get", NULL, NULL);
RNA_def_property_ui_text(prop, "Material Index", "");
prop = RNA_def_property(srna, "use_smooth", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
RNA_def_property_boolean_funcs(prop, "rna_MeshLoopTriangle_use_smooth_get", NULL);
RNA_def_property_ui_text(prop, "Smooth", "");
}
static void rna_def_mloop(BlenderRNA *brna)
{
@@ -2295,179 +1890,6 @@ static void rna_def_mloopuv(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "UV Edge Select", "");
}
static void rna_def_mtface(BlenderRNA *brna)
{
StructRNA *srna;
PropertyRNA *prop;
const int uv_dim[] = {4, 2};
srna = RNA_def_struct(brna, "MeshTextureFaceLayer", NULL);
RNA_def_struct_ui_text(srna, "Mesh UV Map", "UV map with assigned image textures in a Mesh data-block");
RNA_def_struct_sdna(srna, "CustomDataLayer");
RNA_def_struct_path_func(srna, "rna_MeshTextureFaceLayer_path");
RNA_def_struct_ui_icon(srna, ICON_GROUP_UVS);
prop = RNA_def_property(srna, "name", PROP_STRING, PROP_NONE);
RNA_def_struct_name_property(srna, prop);
RNA_def_property_string_funcs(prop, NULL, NULL, "rna_MeshUVLayer_name_set");
RNA_def_property_ui_text(prop, "Name", "Name of UV map");
RNA_def_property_update(prop, 0, "rna_Mesh_update_data");
prop = RNA_def_property(srna, "active", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_funcs(prop, "rna_MeshTextureFaceLayer_active_get", "rna_MeshTextureFaceLayer_active_set");
RNA_def_property_ui_text(prop, "Active", "Set the map as active for display and editing");
RNA_def_property_update(prop, 0, "rna_Mesh_update_data");
prop = RNA_def_property(srna, "active_render", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "active_rnd", 0);
RNA_def_property_boolean_funcs(prop, "rna_MeshTextureFaceLayer_active_render_get",
"rna_MeshTextureFaceLayer_active_render_set");
RNA_def_property_ui_text(prop, "Active Render", "Set the map as active for rendering");
RNA_def_property_update(prop, 0, "rna_Mesh_update_data");
prop = RNA_def_property(srna, "active_clone", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "active_clone", 0);
RNA_def_property_boolean_funcs(prop, "rna_MeshTextureFaceLayer_clone_get", "rna_MeshTextureFaceLayer_clone_set");
RNA_def_property_ui_text(prop, "Active Clone", "Set the map as active for cloning");
RNA_def_property_update(prop, 0, "rna_Mesh_update_data");
prop = RNA_def_property(srna, "data", PROP_COLLECTION, PROP_NONE);
RNA_def_property_struct_type(prop, "MeshTextureFace");
RNA_def_property_ui_text(prop, "Data", "");
RNA_def_property_collection_funcs(prop, "rna_MeshTextureFaceLayer_data_begin", "rna_iterator_array_next",
"rna_iterator_array_end", "rna_iterator_array_get",
"rna_MeshTextureFaceLayer_data_length", NULL, NULL, NULL);
srna = RNA_def_struct(brna, "MeshTextureFace", NULL);
RNA_def_struct_sdna(srna, "MTFace");
RNA_def_struct_ui_text(srna, "Mesh UV Map Face", "UV map and image texture for a face");
RNA_def_struct_path_func(srna, "rna_MeshTextureFace_path");
RNA_def_struct_ui_icon(srna, ICON_FACESEL_HLT);
/* these are for editing only, access at loops now */
#if 0
prop = RNA_def_property(srna, "select_uv", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", TF_SEL1);
RNA_def_property_array(prop, 4);
RNA_def_property_ui_text(prop, "UV Selected", "");
RNA_def_property_update(prop, 0, "rna_Mesh_update_select");
prop = RNA_def_property(srna, "pin_uv", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "unwrap", TF_PIN1);
RNA_def_property_array(prop, 4);
RNA_def_property_ui_text(prop, "UV Pinned", "");
RNA_def_property_update(prop, 0, "rna_Mesh_update_select");
#endif
prop = RNA_def_property(srna, "uv1", PROP_FLOAT, PROP_XYZ);
RNA_def_property_array(prop, 2);
RNA_def_property_float_funcs(prop, "rna_MeshTextureFace_uv1_get", "rna_MeshTextureFace_uv1_set", NULL);
RNA_def_property_ui_text(prop, "UV 1", "");
RNA_def_property_update(prop, 0, "rna_Mesh_update_data");
prop = RNA_def_property(srna, "uv2", PROP_FLOAT, PROP_XYZ);
RNA_def_property_array(prop, 2);
RNA_def_property_float_funcs(prop, "rna_MeshTextureFace_uv2_get", "rna_MeshTextureFace_uv2_set", NULL);
RNA_def_property_ui_text(prop, "UV 2", "");
RNA_def_property_update(prop, 0, "rna_Mesh_update_data");
prop = RNA_def_property(srna, "uv3", PROP_FLOAT, PROP_XYZ);
RNA_def_property_array(prop, 2);
RNA_def_property_float_funcs(prop, "rna_MeshTextureFace_uv3_get", "rna_MeshTextureFace_uv3_set", NULL);
RNA_def_property_ui_text(prop, "UV 3", "");
RNA_def_property_update(prop, 0, "rna_Mesh_update_data");
prop = RNA_def_property(srna, "uv4", PROP_FLOAT, PROP_XYZ);
RNA_def_property_array(prop, 2);
RNA_def_property_float_funcs(prop, "rna_MeshTextureFace_uv4_get", "rna_MeshTextureFace_uv4_set", NULL);
RNA_def_property_ui_text(prop, "UV 4", "");
RNA_def_property_update(prop, 0, "rna_Mesh_update_data");
prop = RNA_def_property(srna, "uv", PROP_FLOAT, PROP_NONE);
RNA_def_property_multi_array(prop, 2, uv_dim);
RNA_def_property_flag(prop, PROP_DYNAMIC);
RNA_def_property_dynamic_array_funcs(prop, "rna_MeshTextureFace_uv_get_length");
RNA_def_property_float_funcs(prop, "rna_MeshTextureFace_uv_get", "rna_MeshTextureFace_uv_set", NULL);
RNA_def_property_ui_text(prop, "UV", "");
RNA_def_property_update(prop, 0, "rna_Mesh_update_data");
prop = RNA_def_property(srna, "uv_raw", PROP_FLOAT, PROP_NONE);
RNA_def_property_multi_array(prop, 2, uv_dim);
RNA_def_property_float_sdna(prop, NULL, "uv");
RNA_def_property_ui_text(prop, "UV Raw", "Fixed size UV coordinates array");
}
static void rna_def_mcol(BlenderRNA *brna)
{
StructRNA *srna;
PropertyRNA *prop;
srna = RNA_def_struct(brna, "MeshColorLayer", NULL);
RNA_def_struct_ui_text(srna, "Mesh Vertex Color Layer", "Layer of vertex colors in a Mesh data-block");
RNA_def_struct_sdna(srna, "CustomDataLayer");
RNA_def_struct_path_func(srna, "rna_MeshColorLayer_path");
RNA_def_struct_ui_icon(srna, ICON_GROUP_VCOL);
prop = RNA_def_property(srna, "name", PROP_STRING, PROP_NONE);
RNA_def_struct_name_property(srna, prop);
RNA_def_property_string_funcs(prop, NULL, NULL, NULL);
RNA_def_property_ui_text(prop, "Name", "Name of Vertex color layer");
RNA_def_property_update(prop, 0, "rna_Mesh_update_data");
prop = RNA_def_property(srna, "active", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_funcs(prop, "rna_MeshColorLayer_active_get", "rna_MeshColorLayer_active_set");
RNA_def_property_ui_text(prop, "Active", "Sets the layer as active for display and editing");
RNA_def_property_update(prop, 0, "rna_Mesh_update_data");
prop = RNA_def_property(srna, "active_render", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "active_rnd", 0);
RNA_def_property_boolean_funcs(prop, "rna_MeshColorLayer_active_render_get",
"rna_MeshColorLayer_active_render_set");
RNA_def_property_ui_text(prop, "Active Render", "Sets the layer as active for rendering");
RNA_def_property_update(prop, 0, "rna_Mesh_update_data");
prop = RNA_def_property(srna, "data", PROP_COLLECTION, PROP_NONE);
RNA_def_property_struct_type(prop, "MeshColor");
RNA_def_property_ui_text(prop, "Data", "");
RNA_def_property_collection_funcs(prop, "rna_MeshColorLayer_data_begin", "rna_iterator_array_next",
"rna_iterator_array_end", "rna_iterator_array_get",
"rna_MeshColorLayer_data_length", NULL, NULL, NULL);
srna = RNA_def_struct(brna, "MeshColor", NULL);
RNA_def_struct_sdna(srna, "MCol");
RNA_def_struct_ui_text(srna, "Mesh Vertex Color", "Vertex colors for a face in a Mesh");
RNA_def_struct_path_func(srna, "rna_MeshColor_path");
prop = RNA_def_property(srna, "color1", PROP_FLOAT, PROP_COLOR);
RNA_def_property_array(prop, 4);
RNA_def_property_range(prop, 0.0f, 1.0f);
RNA_def_property_float_funcs(prop, "rna_MeshColor_color1_get", "rna_MeshColor_color1_set", NULL);
RNA_def_property_ui_text(prop, "Color 1", "");
RNA_def_property_update(prop, 0, "rna_Mesh_update_data");
prop = RNA_def_property(srna, "color2", PROP_FLOAT, PROP_COLOR);
RNA_def_property_array(prop, 4);
RNA_def_property_range(prop, 0.0f, 1.0f);
RNA_def_property_float_funcs(prop, "rna_MeshColor_color2_get", "rna_MeshColor_color2_set", NULL);
RNA_def_property_ui_text(prop, "Color 2", "");
RNA_def_property_update(prop, 0, "rna_Mesh_update_data");
prop = RNA_def_property(srna, "color3", PROP_FLOAT, PROP_COLOR);
RNA_def_property_array(prop, 4);
RNA_def_property_range(prop, 0.0f, 1.0f);
RNA_def_property_float_funcs(prop, "rna_MeshColor_color3_get", "rna_MeshColor_color3_set", NULL);
RNA_def_property_ui_text(prop, "Color 3", "");
RNA_def_property_update(prop, 0, "rna_Mesh_update_data");
prop = RNA_def_property(srna, "color4", PROP_FLOAT, PROP_COLOR);
RNA_def_property_array(prop, 4);
RNA_def_property_range(prop, 0.0f, 1.0f);
RNA_def_property_float_funcs(prop, "rna_MeshColor_color4_get", "rna_MeshColor_color4_set", NULL);
RNA_def_property_ui_text(prop, "Color 4", "");
RNA_def_property_update(prop, 0, "rna_Mesh_update_data");
}
static void rna_def_mloopcol(BlenderRNA *brna)
{
StructRNA *srna;
@@ -2723,33 +2145,15 @@ static void rna_def_mesh_edges(BlenderRNA *brna, PropertyRNA *cprop)
#endif
}
/* mesh.faces */
static void rna_def_mesh_tessfaces(BlenderRNA *brna, PropertyRNA *cprop)
/* mesh.loop_triangles */
static void rna_def_mesh_looptris(BlenderRNA *brna, PropertyRNA *cprop)
{
StructRNA *srna;
PropertyRNA *prop;
FunctionRNA *func;
PropertyRNA *parm;
RNA_def_property_srna(cprop, "MeshTessFaces");
srna = RNA_def_struct(brna, "MeshTessFaces", NULL);
RNA_def_property_srna(cprop, "MeshLoopTriangle");
srna = RNA_def_struct(brna, "MeshLoopTriangles", NULL);
RNA_def_struct_sdna(srna, "Mesh");
RNA_def_struct_ui_text(srna, "Mesh Faces", "Collection of mesh faces");
prop = RNA_def_property(srna, "active", PROP_INT, PROP_NONE);
RNA_def_property_int_sdna(prop, NULL, "act_face");
RNA_def_property_ui_text(prop, "Active Face", "The active face for this mesh");
func = RNA_def_function(srna, "add", "ED_mesh_tessfaces_add");
RNA_def_function_flag(func, FUNC_USE_REPORTS);
parm = RNA_def_int(func, "count", 0, 0, INT_MAX, "Count", "Number of faces to add", 0, INT_MAX);
RNA_def_parameter_flags(parm, 0, PARM_REQUIRED);
#if 0 /* BMESH_TODO Remove until BMesh merge */
func = RNA_def_function(srna, "remove", "ED_mesh_faces_remove");
RNA_def_function_flag(func, FUNC_USE_REPORTS);
RNA_def_int(func, "count", 0, 0, INT_MAX, "Count", "Number of faces to remove", 0, INT_MAX);
#endif
RNA_def_struct_ui_text(srna, "Mesh Loop Triangles", "Tessellation of mesh polygons into triangles");
}
/* mesh.loops */
@@ -2799,43 +2203,6 @@ static void rna_def_mesh_polygons(BlenderRNA *brna, PropertyRNA *cprop)
}
/* mesh.vertex_colors */
static void rna_def_tessface_vertex_colors(BlenderRNA *brna, PropertyRNA *cprop)
{
StructRNA *srna;
PropertyRNA *prop;
FunctionRNA *func;
PropertyRNA *parm;
RNA_def_property_srna(cprop, "VertexColors");
srna = RNA_def_struct(brna, "VertexColors", NULL);
RNA_def_struct_sdna(srna, "Mesh");
RNA_def_struct_ui_text(srna, "Vertex Colors", "Collection of vertex colors");
/* eventually deprecate this */
func = RNA_def_function(srna, "new", "rna_Mesh_tessface_vertex_color_new");
RNA_def_function_flag(func, FUNC_USE_REPORTS);
RNA_def_function_ui_description(func, "Add a vertex color layer to Mesh");
RNA_def_string(func, "name", "Col", 0, "", "Vertex color name");
parm = RNA_def_pointer(func, "layer", "MeshColorLayer", "", "The newly created layer");
RNA_def_parameter_flags(parm, 0, PARM_RNAPTR);
RNA_def_function_return(func, parm);
prop = RNA_def_property(srna, "active", PROP_POINTER, PROP_NONE);
RNA_def_property_struct_type(prop, "MeshColorLayer");
RNA_def_property_pointer_funcs(prop, "rna_Mesh_tessface_vertex_color_active_get",
"rna_Mesh_tessface_vertex_color_active_set", NULL, NULL);
RNA_def_property_ui_text(prop, "Active Vertex Color Layer", "Active vertex color layer");
RNA_def_property_update(prop, 0, "rna_Mesh_update_data");
prop = RNA_def_property(srna, "active_index", PROP_INT, PROP_UNSIGNED);
RNA_def_property_int_funcs(prop, "rna_Mesh_tessface_vertex_color_active_index_get",
"rna_Mesh_tessface_vertex_color_active_index_set", "rna_Mesh_vertex_color_index_range");
RNA_def_property_ui_text(prop, "Active Vertex Color Index", "Active vertex color index");
RNA_def_property_update(prop, 0, "rna_Mesh_update_data");
}
static void rna_def_loop_colors(BlenderRNA *brna, PropertyRNA *cprop)
{
StructRNA *srna;
@@ -3045,43 +2412,6 @@ static void rna_def_polygon_string_layers(BlenderRNA *brna, PropertyRNA *cprop)
RNA_def_function_return(func, parm);
}
/* mesh.tessface_uv_layers */
static void rna_def_tessface_uv_textures(BlenderRNA *brna, PropertyRNA *cprop)
{
StructRNA *srna;
PropertyRNA *prop;
FunctionRNA *func;
PropertyRNA *parm;
RNA_def_property_srna(cprop, "TessfaceUVTextures");
srna = RNA_def_struct(brna, "TessfaceUVTextures", NULL);
RNA_def_struct_sdna(srna, "Mesh");
RNA_def_struct_ui_text(srna, "UV Maps", "Collection of UV maps for tessellated faces");
/* eventually deprecate this */
func = RNA_def_function(srna, "new", "rna_Mesh_tessface_uv_texture_new");
RNA_def_function_flag(func, FUNC_USE_REPORTS);
RNA_def_function_ui_description(func, "Add a UV tessface-texture layer to Mesh (only for meshes with no polygons)");
RNA_def_string(func, "name", "UVMap", 0, "", "UV map name");
parm = RNA_def_pointer(func, "layer", "MeshTextureFaceLayer", "", "The newly created layer");
RNA_def_parameter_flags(parm, 0, PARM_RNAPTR);
RNA_def_function_return(func, parm);
prop = RNA_def_property(srna, "active", PROP_POINTER, PROP_NONE);
RNA_def_property_struct_type(prop, "MeshTextureFaceLayer");
RNA_def_property_pointer_funcs(prop, "rna_Mesh_tessface_uv_texture_active_get",
"rna_Mesh_tessface_uv_texture_active_set", NULL, NULL);
RNA_def_property_ui_text(prop, "Active UV Map", "Active UV Map");
RNA_def_property_update(prop, 0, "rna_Mesh_update_data");
prop = RNA_def_property(srna, "active_index", PROP_INT, PROP_UNSIGNED);
RNA_def_property_int_funcs(prop, "rna_Mesh_tessface_uv_texture_active_index_get",
"rna_Mesh_tessface_uv_texture_active_index_set", "rna_Mesh_uv_layer_index_range");
RNA_def_property_ui_text(prop, "Active UV Map Index", "Active UV Map index");
RNA_def_property_update(prop, 0, "rna_Mesh_update_data");
}
static void rna_def_skin_vertices(BlenderRNA *brna, PropertyRNA *UNUSED(cprop))
{
StructRNA *srna;
@@ -3256,12 +2586,6 @@ static void rna_def_mesh(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Edges", "Edges of the mesh");
rna_def_mesh_edges(brna, prop);
prop = RNA_def_property(srna, "tessfaces", PROP_COLLECTION, PROP_NONE);
RNA_def_property_collection_sdna(prop, NULL, "mface", "totface");
RNA_def_property_struct_type(prop, "MeshTessFace");
RNA_def_property_ui_text(prop, "TessFaces", "Tessellated faces of the mesh (derived from polygons)");
rna_def_mesh_tessfaces(brna, prop);
prop = RNA_def_property(srna, "loops", PROP_COLLECTION, PROP_NONE);
RNA_def_property_collection_sdna(prop, NULL, "mloop", "totloop");
RNA_def_property_struct_type(prop, "MeshLoop");
@@ -3274,6 +2598,12 @@ static void rna_def_mesh(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Polygons", "Polygons of the mesh");
rna_def_mesh_polygons(brna, prop);
prop = RNA_def_property(srna, "loop_triangles", PROP_COLLECTION, PROP_NONE);
RNA_def_property_collection_sdna(prop, NULL, "runtime.looptris.array", "runtime.looptris.len");
RNA_def_property_struct_type(prop, "MeshLoopTriangle");
RNA_def_property_ui_text(prop, "Loop Triangles", "Tessellation of mesh polygons into triangles");
rna_def_mesh_looptris(brna, prop);
/* TODO, should this be allowed to be its self? */
prop = RNA_def_property(srna, "texture_mesh", PROP_POINTER, PROP_NONE);
RNA_def_property_pointer_sdna(prop, NULL, "texcomesh");
@@ -3314,27 +2644,6 @@ static void rna_def_mesh(BlenderRNA *brna)
"rna_Mesh_uv_layer_stencil_index_set", "rna_Mesh_uv_layer_index_range");
RNA_def_property_ui_text(prop, "Mask UV loop layer Index", "Mask UV loop layer index");
/* Tessellated face UV maps - used by renderers */
prop = RNA_def_property(srna, "tessface_uv_textures", PROP_COLLECTION, PROP_NONE);
RNA_def_property_collection_sdna(prop, NULL, "fdata.layers", "fdata.totlayer");
RNA_def_property_collection_funcs(prop, "rna_Mesh_tessface_uv_textures_begin", NULL, NULL, NULL,
"rna_Mesh_tessface_uv_textures_length", NULL, NULL, NULL);
RNA_def_property_struct_type(prop, "MeshTextureFaceLayer");
RNA_def_property_ui_text(prop, "Tessellated Face UV Maps",
"All UV maps for tessellated faces (read-only, for use by renderers)");
rna_def_tessface_uv_textures(brna, prop);
/* Tessellated face colors - used by renderers */
prop = RNA_def_property(srna, "tessface_vertex_colors", PROP_COLLECTION, PROP_NONE);
RNA_def_property_collection_sdna(prop, NULL, "fdata.layers", "fdata.totlayer");
RNA_def_property_collection_funcs(prop, "rna_Mesh_tessface_vertex_colors_begin", NULL, NULL, NULL,
"rna_Mesh_tessface_vertex_colors_length", NULL, NULL, NULL);
RNA_def_property_struct_type(prop, "MeshColorLayer");
RNA_def_property_ui_text(prop, "Tessellated Face Colors",
"All tessellated face colors (read-only, for use by renderers)");
rna_def_tessface_vertex_colors(brna, prop);
/* Vertex colors */
prop = RNA_def_property(srna, "vertex_colors", PROP_COLLECTION, PROP_NONE);
@@ -3570,12 +2879,10 @@ void RNA_def_mesh(BlenderRNA *brna)
rna_def_mvert(brna);
rna_def_mvert_group(brna);
rna_def_medge(brna);
rna_def_mface(brna);
rna_def_mlooptri(brna);
rna_def_mloop(brna);
rna_def_mpolygon(brna);
rna_def_mloopuv(brna);
rna_def_mtface(brna);
rna_def_mcol(brna);
rna_def_mloopcol(brna);
rna_def_mproperties(brna);
rna_def_face_map(brna);

View File

@@ -50,6 +50,7 @@
#include "BKE_mesh.h"
#include "BKE_mesh_tangent.h"
#include "BKE_mesh_mapping.h"
#include "BKE_mesh_runtime.h"
#include "ED_mesh.h"
static const char *rna_Mesh_unit_test_compare(struct Mesh *mesh, struct Mesh *mesh2)
@@ -101,9 +102,9 @@ static void rna_Mesh_free_tangents(Mesh *mesh)
CustomData_free_layers(&mesh->ldata, CD_MLOOPTANGENT, mesh->totloop);
}
static void rna_Mesh_calc_tessface(Mesh *mesh, bool free_mpoly)
static void rna_Mesh_calc_looptri(Mesh *mesh)
{
ED_mesh_calc_tessface(mesh, free_mpoly != 0);
BKE_mesh_runtime_looptri_ensure(mesh);
}
static void rna_Mesh_calc_smooth_groups(Mesh *mesh, bool use_bitflags, int *r_poly_group_len,
@@ -206,6 +207,7 @@ static void rna_Mesh_flip_normals(Mesh *mesh)
BKE_mesh_polygons_flip(mesh->mpoly, mesh->mloop, &mesh->ldata, mesh->totpoly);
BKE_mesh_tessface_clear(mesh);
BKE_mesh_calc_normals(mesh);
BKE_mesh_runtime_clear_geometry(mesh);
DEG_id_tag_update(&mesh->id, 0);
}
@@ -269,12 +271,8 @@ void RNA_api_mesh(StructRNA *srna)
func = RNA_def_function(srna, "free_tangents", "rna_Mesh_free_tangents");
RNA_def_function_ui_description(func, "Free tangents");
func = RNA_def_function(srna, "calc_tessface", "rna_Mesh_calc_tessface");
RNA_def_function_ui_description(func, "Calculate face tessellation (supports editmode too)");
RNA_def_boolean(func, "free_mpoly", 0, "Free MPoly", "Free data used by polygons and loops. "
"WARNING: This destructive operation removes regular faces, "
"only used on temporary mesh data-blocks to reduce memory footprint of render "
"engines and export scripts");
func = RNA_def_function(srna, "calc_loop_triangles", "rna_Mesh_calc_looptri");
RNA_def_function_ui_description(func, "Calculate loop triangle tessellation (supports editmode too)");
func = RNA_def_function(srna, "calc_smooth_groups", "rna_Mesh_calc_smooth_groups");
RNA_def_function_ui_description(func, "Calculate smooth groups from sharp edges");
@@ -308,7 +306,7 @@ void RNA_api_mesh(StructRNA *srna)
func = RNA_def_function(srna, "update", "ED_mesh_update");
RNA_def_boolean(func, "calc_edges", 0, "Calculate Edges", "Force recalculation of edges");
RNA_def_boolean(func, "calc_tessface", 0, "Calculate Tessellation", "Force recalculation of tessellation faces");
RNA_def_boolean(func, "calc_loop_triangles", 0, "Calculate Triangules", "Force recalculation of triangle tessellation");
RNA_def_function_flag(func, FUNC_USE_CONTEXT);
RNA_def_function(srna, "update_gpu_tag", "rna_Mesh_update_gpu_tag");

View File

@@ -224,11 +224,11 @@ static void rna_Object_camera_fit_coords(
/* settings: 0 - preview, 1 - render */
static Mesh *rna_Object_to_mesh(
Object *ob, bContext *C, ReportList *reports, Depsgraph *depsgraph,
bool apply_modifiers, bool calc_tessface, bool calc_undeformed)
bool apply_modifiers, bool calc_loop_triangles, bool calc_undeformed)
{
Main *bmain = CTX_data_main(C);
return rna_Main_meshes_new_from_object(bmain, reports, depsgraph, ob, apply_modifiers, calc_tessface, calc_undeformed);
return rna_Main_meshes_new_from_object(bmain, reports, depsgraph, ob, apply_modifiers, calc_loop_triangles, calc_undeformed);
}
static PointerRNA rna_Object_shape_key_add(Object *ob, bContext *C, ReportList *reports,
@@ -594,7 +594,7 @@ void RNA_api_object(StructRNA *srna)
RNA_def_parameter_flags(parm, PROP_NEVER_NULL, PARM_REQUIRED);
parm = RNA_def_boolean(func, "apply_modifiers", 0, "", "Apply modifiers");
RNA_def_parameter_flags(parm, 0, PARM_REQUIRED);
RNA_def_boolean(func, "calc_tessface", true, "Calculate Tessellation", "Calculate tessellation faces");
RNA_def_boolean(func, "calc_loop_triangles", true, "Calculate Loop Triangles", "Calculate triangle tessellation");
RNA_def_boolean(func, "calc_undeformed", false, "Calculate Undeformed", "Calculate undeformed vertex coordinates");
parm = RNA_def_pointer(func, "mesh", "Mesh", "",
"Mesh created from object, remove it if it is only used for export");

View File

@@ -113,30 +113,30 @@ static PyObject *bpy_bm_from_edit_mesh(PyObject *UNUSED(self), PyObject *value)
}
PyDoc_STRVAR(bpy_bm_update_edit_mesh_doc,
".. method:: update_edit_mesh(mesh, tessface=True, destructive=True)\n"
".. method:: update_edit_mesh(mesh, loop_triangles=True, destructive=True)\n"
"\n"
" Update the mesh after changes to the BMesh in editmode, \n"
" optionally recalculating n-gon tessellation.\n"
"\n"
" :arg mesh: The editmode mesh.\n"
" :type mesh: :class:`bpy.types.Mesh`\n"
" :arg tessface: Option to recalculate n-gon tessellation.\n"
" :type tessface: boolean\n"
" :arg loop_triangles: Option to recalculate n-gon tessellation.\n"
" :type loop_triangles: boolean\n"
" :arg destructive: Use when geometry has been added or removed.\n"
" :type destructive: boolean\n"
);
static PyObject *bpy_bm_update_edit_mesh(PyObject *UNUSED(self), PyObject *args, PyObject *kw)
{
static const char *kwlist[] = {"mesh", "tessface", "destructive", NULL};
static const char *kwlist[] = {"mesh", "loop_triangles", "destructive", NULL};
PyObject *py_me;
Mesh *me;
bool do_tessface = true;
bool do_loop_triangles = true;
bool is_destructive = true;
if (!PyArg_ParseTupleAndKeywords(
args, kw, "O|O&O&:update_edit_mesh", (char **)kwlist,
&py_me,
PyC_ParseBool, &do_tessface,
PyC_ParseBool, &do_loop_triangles,
PyC_ParseBool, &is_destructive))
{
return NULL;
@@ -157,7 +157,7 @@ static PyObject *bpy_bm_update_edit_mesh(PyObject *UNUSED(self), PyObject *args,
{
extern void EDBM_update_generic(BMEditMesh *em, const bool do_tessface, const bool is_destructive);
EDBM_update_generic(me->edit_btmesh, do_tessface, is_destructive);
EDBM_update_generic(me->edit_btmesh, do_loop_triangles, is_destructive);
}
Py_RETURN_NONE;

View File

@@ -1246,15 +1246,15 @@ static PyObject *bpy_bmesh_calc_volume(BPy_BMElem *self, PyObject *args, PyObjec
}
}
PyDoc_STRVAR(bpy_bmesh_calc_tessface_doc,
".. method:: calc_tessface()\n"
PyDoc_STRVAR(bpy_bmesh_calc_loop_triangles_doc,
".. method:: calc_loop_triangles()\n"
"\n"
" Calculate triangle tessellation from quads/ngons.\n"
"\n"
" :return: The triangulated faces.\n"
" :rtype: list of :class:`BMLoop` tuples\n"
);
static PyObject *bpy_bmesh_calc_tessface(BPy_BMElem *self)
static PyObject *bpy_bmesh_calc_loop_triangles(BPy_BMElem *self)
{
BMesh *bm;
@@ -2733,7 +2733,7 @@ static struct PyMethodDef bpy_bmesh_methods[] = {
/* calculations */
{"calc_volume", (PyCFunction)bpy_bmesh_calc_volume, METH_VARARGS | METH_KEYWORDS, bpy_bmesh_calc_volume_doc},
{"calc_tessface", (PyCFunction)bpy_bmesh_calc_tessface, METH_NOARGS, bpy_bmesh_calc_tessface_doc},
{"calc_loop_triangles", (PyCFunction)bpy_bmesh_calc_loop_triangles, METH_NOARGS, bpy_bmesh_calc_loop_triangles_doc},
{NULL, NULL, 0, NULL}
};

View File

@@ -86,9 +86,6 @@
#include "render_types.h"
#include "zbuf.h"
/* Remove when Cycles moves from MFace to MLoopTri */
#define USE_MFACE_WORKAROUND
typedef struct BakeDataZSpan {
BakePixel *pixel_array;
int primitive_id;
@@ -393,27 +390,6 @@ static bool cast_ray_highpoly(
return hit_mesh != -1;
}
#ifdef USE_MFACE_WORKAROUND
/**
* Until cycles moves to #MLoopTri, we need to keep face-rotation in sync with #test_index_face
*
* We only need to consider quads since #BKE_mesh_recalc_tessellation doesn't execute this on triangles.
*/
static void test_index_face_looptri(const MPoly *mp, MLoop *mloop, MLoopTri *lt)
{
if (mp->totloop == 4) {
if (UNLIKELY((mloop[mp->loopstart + 2].v == 0) ||
(mloop[mp->loopstart + 3].v == 0)))
{
/* remap: (2, 3, 0, 1) */
unsigned int l = mp->loopstart;
ARRAY_SET_ITEMS(lt[0].tri, l + 2, l + 3, l + 0);
ARRAY_SET_ITEMS(lt[1].tri, l + 2, l + 0, l + 1);
}
}
}
#endif
/**
* This function populates an array of verts for the triangles of a mesh
* Tangent and Normals are also stored
@@ -433,10 +409,6 @@ static TriTessFace *mesh_calc_tri_tessface(
unsigned int mpoly_prev = UINT_MAX;
float no[3];
#ifdef USE_MFACE_WORKAROUND
unsigned int mpoly_prev_testindex = UINT_MAX;
#endif
mvert = CustomData_get_layer(&me->vdata, CD_MVERT);
looptri = MEM_mallocN(sizeof(*looptri) * tottri, __func__);
triangles = MEM_mallocN(sizeof(TriTessFace) * tottri, __func__);
@@ -463,13 +435,6 @@ static TriTessFace *mesh_calc_tri_tessface(
const MLoopTri *lt = &looptri[i];
const MPoly *mp = &me->mpoly[lt->poly];
#ifdef USE_MFACE_WORKAROUND
if (lt->poly != mpoly_prev_testindex) {
test_index_face_looptri(mp, me->mloop, &looptri[i]);
mpoly_prev_testindex = lt->poly;
}
#endif
triangles[i].mverts[0] = &mvert[me->mloop[lt->tri[0]].v];
triangles[i].mverts[1] = &mvert[me->mloop[lt->tri[1]].v];
triangles[i].mverts[2] = &mvert[me->mloop[lt->tri[2]].v];
@@ -662,9 +627,6 @@ void RE_bake_pixels_populate(
const MLoopUV *mloopuv;
const int tottri = poly_to_tri_count(me->totpoly, me->totloop);
MLoopTri *looptri;
#ifdef USE_MFACE_WORKAROUND
unsigned int mpoly_prev_testindex = UINT_MAX;
#endif
if ((uv_layer == NULL) || (uv_layer[0] == '\0')) {
mloopuv = CustomData_get_layer(&me->ldata, CD_MLOOPUV);
@@ -714,13 +676,6 @@ void RE_bake_pixels_populate(
bd.bk_image = &bake_images->data[image_id];
bd.primitive_id = ++p_id;
#ifdef USE_MFACE_WORKAROUND
if (lt->poly != mpoly_prev_testindex) {
test_index_face_looptri(mp, me->mloop, &looptri[i]);
mpoly_prev_testindex = lt->poly;
}
#endif
for (a = 0; a < 3; a++) {
const float *uv = mloopuv[lt->tri[a]].uv;