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:
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
===================================
|
||||
|
||||
|
||||
@@ -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());
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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):
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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");
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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");
|
||||
|
||||
@@ -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");
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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}
|
||||
};
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user