Fix broken merge in fb45821, was missing changes from cc64872.

This commit is contained in:
Brecht Van Lommel 2018-01-22 14:28:43 +01:00
parent f7c812e199
commit 51da664fa1
1 changed files with 176 additions and 76 deletions

View File

@ -79,7 +79,7 @@ inline void face_split_tri_indices(const int face_flag,
struct MikkUserData {
MikkUserData(const BL::Mesh& b_mesh,
BL::MeshTextureFaceLayer *layer,
const char *layer_name,
const Mesh *mesh,
float3 *tangent,
float *tangent_sign)
@ -89,16 +89,19 @@ struct MikkUserData {
tangent(tangent),
tangent_sign(tangent_sign)
{
Attribute *attr_vN = mesh->attributes.find(ATTR_STD_VERTEX_NORMAL);
const AttributeSet& attributes = (mesh->subd_faces.size()) ?
mesh->subd_attributes : mesh->attributes;
Attribute *attr_vN = attributes.find(ATTR_STD_VERTEX_NORMAL);
vertex_normal = attr_vN->data_float3();
if(layer == NULL) {
Attribute *attr_orco = mesh->attributes.find(ATTR_STD_GENERATED);
if(layer_name == NULL) {
Attribute *attr_orco = attributes.find(ATTR_STD_GENERATED);
orco = attr_orco->data_float3();
mesh_texture_space(*(BL::Mesh*)&b_mesh, orco_loc, orco_size);
}
else {
Attribute *attr_uv = mesh->attributes.find(ustring(layer->name()));
Attribute *attr_uv = attributes.find(ustring(layer_name));
if(attr_uv != NULL) {
texface = attr_uv->data_float3();
}
@ -120,13 +123,47 @@ struct MikkUserData {
static int mikk_get_num_faces(const SMikkTSpaceContext *context)
{
const MikkUserData *userdata = (const MikkUserData *)context->m_pUserData;
return userdata->mesh->num_triangles();
if(userdata->mesh->subd_faces.size()) {
return userdata->mesh->subd_faces.size();
}
else {
return userdata->mesh->num_triangles();
}
}
static int mikk_get_num_verts_of_face(const SMikkTSpaceContext * /*context*/,
const int /*face_num*/)
static int mikk_get_num_verts_of_face(const SMikkTSpaceContext *context,
const int face_num)
{
return 3;
const MikkUserData *userdata = (const MikkUserData *)context->m_pUserData;
if(userdata->mesh->subd_faces.size()) {
const Mesh *mesh = userdata->mesh;
return mesh->subd_faces[face_num].num_corners;
}
else {
return 3;
}
}
static int mikk_vertex_index(const Mesh *mesh, const int face_num, const int vert_num)
{
if(mesh->subd_faces.size()) {
const Mesh::SubdFace& face = mesh->subd_faces[face_num];
return mesh->subd_face_corners[face.start_corner + vert_num];
}
else {
return mesh->triangles[face_num * 3 + vert_num];
}
}
static int mikk_corner_index(const Mesh *mesh, const int face_num, const int vert_num)
{
if(mesh->subd_faces.size()) {
const Mesh::SubdFace& face = mesh->subd_faces[face_num];
return face.start_corner + vert_num;
}
else {
return face_num * 3 + vert_num;
}
}
static void mikk_get_position(const SMikkTSpaceContext *context,
@ -135,9 +172,8 @@ static void mikk_get_position(const SMikkTSpaceContext *context,
{
const MikkUserData *userdata = (const MikkUserData *)context->m_pUserData;
const Mesh *mesh = userdata->mesh;
const int vert_index = mesh->triangles[face_num * 3 + vert_num];
const float3 vP = mesh->verts[vert_index];
const int vertex_index = mikk_vertex_index(mesh, face_num, vert_num);
const float3 vP = mesh->verts[vertex_index];
P[0] = vP.x;
P[1] = vP.y;
P[2] = vP.z;
@ -148,15 +184,15 @@ static void mikk_get_texture_coordinate(const SMikkTSpaceContext *context,
const int face_num, const int vert_num)
{
const MikkUserData *userdata = (const MikkUserData *)context->m_pUserData;
const Mesh *mesh = userdata->mesh;
if(userdata->texface != NULL) {
const size_t corner_index = face_num * 3 + vert_num;
const int corner_index = mikk_corner_index(mesh, face_num, vert_num);
float3 tfuv = userdata->texface[corner_index];
uv[0] = tfuv.x;
uv[1] = tfuv.y;
}
else if(userdata->orco != NULL) {
const Mesh *mesh = userdata->mesh;
const size_t vertex_index = mesh->triangles[face_num * 3 + vert_num];
const int vertex_index = mikk_vertex_index(mesh, face_num, vert_num);
const float3 orco_loc = userdata->orco_loc;
const float3 orco_size = userdata->orco_size;
const float3 orco = (userdata->orco[vertex_index] + orco_loc) / orco_size;
@ -177,13 +213,25 @@ static void mikk_get_normal(const SMikkTSpaceContext *context, float N[3],
const MikkUserData *userdata = (const MikkUserData *)context->m_pUserData;
const Mesh *mesh = userdata->mesh;
float3 vN;
if(mesh->smooth[face_num]) {
const size_t vert_index = mesh->triangles[face_num * 3 + vert_num];
vN = userdata->vertex_normal[vert_index];
if(mesh->subd_faces.size()) {
const Mesh::SubdFace& face = mesh->subd_faces[face_num];
if(face.smooth) {
const int vertex_index = mikk_vertex_index(mesh, face_num, vert_num);
vN = userdata->vertex_normal[vertex_index];
}
else {
vN = face.normal(mesh);
}
}
else {
const Mesh::Triangle tri = mesh->get_triangle(face_num);
vN = tri.compute_normal(&mesh->verts[0]);
if(mesh->smooth[face_num]) {
const int vertex_index = mikk_vertex_index(mesh, face_num, vert_num);
vN = userdata->vertex_normal[vertex_index];
}
else {
const Mesh::Triangle tri = mesh->get_triangle(face_num);
vN = tri.compute_normal(&mesh->verts[0]);
}
}
N[0] = vN.x;
N[1] = vN.y;
@ -196,7 +244,8 @@ static void mikk_set_tangent_space(const SMikkTSpaceContext *context,
const int face_num, const int vert_num)
{
MikkUserData *userdata = (MikkUserData *)context->m_pUserData;
const size_t corner_index = face_num * 3 + vert_num;
const Mesh *mesh = userdata->mesh;
const int corner_index = mikk_corner_index(mesh, face_num, vert_num);
userdata->tangent[corner_index] = make_float3(T[0], T[1], T[2]);
if(userdata->tangent_sign != NULL) {
userdata->tangent_sign[corner_index] = sign;
@ -204,27 +253,27 @@ static void mikk_set_tangent_space(const SMikkTSpaceContext *context,
}
static void mikk_compute_tangents(const BL::Mesh& b_mesh,
BL::MeshTextureFaceLayer *b_layer,
const char *layer_name,
Mesh *mesh,
bool need_sign,
bool active_render)
{
/* Create tangent attributes. */
AttributeSet& attributes = (mesh->subd_faces.size()) ?
mesh->subd_attributes : mesh->attributes;
Attribute *attr;
ustring name;
if(b_layer != NULL) {
name = ustring((string(b_layer->name().c_str()) + ".tangent").c_str());
if(layer_name != NULL) {
name = ustring((string(layer_name) + ".tangent").c_str());
}
else {
name = ustring("orco.tangent");
}
if(active_render) {
attr = mesh->attributes.add(ATTR_STD_UV_TANGENT, name);
attr = attributes.add(ATTR_STD_UV_TANGENT, name);
}
else {
attr = mesh->attributes.add(name,
TypeDesc::TypeVector,
ATTR_ELEMENT_CORNER);
attr = attributes.add(name, TypeDesc::TypeVector, ATTR_ELEMENT_CORNER);
}
float3 *tangent = attr->data_float3();
/* Create bitangent sign attribute. */
@ -232,8 +281,8 @@ static void mikk_compute_tangents(const BL::Mesh& b_mesh,
if(need_sign) {
Attribute *attr_sign;
ustring name_sign;
if(b_layer != NULL) {
name_sign = ustring((string(b_layer->name().c_str()) +
if(layer_name != NULL) {
name_sign = ustring((string(layer_name) +
".tangent_sign").c_str());
}
else {
@ -241,18 +290,17 @@ static void mikk_compute_tangents(const BL::Mesh& b_mesh,
}
if(active_render) {
attr_sign = mesh->attributes.add(ATTR_STD_UV_TANGENT_SIGN,
name_sign);
attr_sign = attributes.add(ATTR_STD_UV_TANGENT_SIGN, name_sign);
}
else {
attr_sign = mesh->attributes.add(name_sign,
TypeDesc::TypeFloat,
ATTR_ELEMENT_CORNER);
attr_sign = attributes.add(name_sign,
TypeDesc::TypeFloat,
ATTR_ELEMENT_CORNER);
}
tangent_sign = attr_sign->data_float();
}
/* Setup userdata. */
MikkUserData userdata(b_mesh, b_layer, mesh, tangent, tangent_sign);
MikkUserData userdata(b_mesh, layer_name, mesh, tangent, tangent_sign);
/* Setup interface. */
SMikkTSpaceInterface sm_interface;
memset(&sm_interface, 0, sizeof(sm_interface));
@ -399,45 +447,9 @@ static void attr_create_uv_map(Scene *scene,
Mesh *mesh,
BL::Mesh& b_mesh,
const vector<int>& nverts,
const vector<int>& face_flags,
bool subdivision,
bool subdivide_uvs)
const vector<int>& face_flags)
{
if(subdivision) {
BL::Mesh::uv_layers_iterator l;
int i = 0;
for(b_mesh.uv_layers.begin(l); l != b_mesh.uv_layers.end(); ++l, ++i) {
bool active_render = b_mesh.uv_layers[i].active_render();
AttributeStandard std = (active_render)? ATTR_STD_UV: ATTR_STD_NONE;
ustring name = ustring(l->name().c_str());
/* UV map */
if(mesh->need_attribute(scene, name) || mesh->need_attribute(scene, std)) {
Attribute *attr;
if(active_render)
attr = mesh->subd_attributes.add(std, name);
else
attr = mesh->subd_attributes.add(name, TypeDesc::TypePoint, ATTR_ELEMENT_CORNER);
if(subdivide_uvs) {
attr->flags |= ATTR_SUBDIVIDED;
}
BL::Mesh::polygons_iterator p;
float3 *fdata = attr->data_float3();
for(b_mesh.polygons.begin(p); p != b_mesh.polygons.end(); ++p) {
int n = p->loop_total();
for(int j = 0; j < n; j++) {
*(fdata++) = get_float3(l->data[p->loop_start() + j].uv());
}
}
}
}
}
else if(b_mesh.tessface_uv_textures.length() != 0) {
if(b_mesh.tessface_uv_textures.length() != 0) {
BL::Mesh::tessface_uv_textures_iterator l;
for(b_mesh.tessface_uv_textures.begin(l); l != b_mesh.tessface_uv_textures.end(); ++l) {
@ -512,7 +524,7 @@ static void attr_create_uv_map(Scene *scene,
bool need_sign = (mesh->need_attribute(scene, sign_name) ||
mesh->need_attribute(scene, sign_std));
mikk_compute_tangents(b_mesh,
&(*l),
l->name().c_str(),
mesh,
need_sign,
active_render);
@ -532,6 +544,88 @@ static void attr_create_uv_map(Scene *scene,
}
}
static void attr_create_subd_uv_map(Scene *scene,
Mesh *mesh,
BL::Mesh& b_mesh,
const vector<int>& nverts,
const vector<int>& face_flags,
bool subdivide_uvs)
{
if(b_mesh.uv_layers.length() != 0) {
BL::Mesh::uv_layers_iterator l;
int i = 0;
for(b_mesh.uv_layers.begin(l); l != b_mesh.uv_layers.end(); ++l, ++i) {
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());
AttributeStandard tangent_std = (active_render)? ATTR_STD_UV_TANGENT
: ATTR_STD_NONE;
ustring tangent_name = ustring(
(string(l->name().c_str()) + ".tangent").c_str());
/* Denotes whether UV map was requested directly. */
const bool need_uv = mesh->need_attribute(scene, uv_name) ||
mesh->need_attribute(scene, uv_std);
/* Denotes whether tangent was requested directly. */
const bool need_tangent =
mesh->need_attribute(scene, tangent_name) ||
(active_render && mesh->need_attribute(scene, tangent_std));
Attribute *uv_attr = NULL;
/* UV map */
if(need_uv || need_tangent) {
if(active_render)
uv_attr = mesh->subd_attributes.add(uv_std, uv_name);
else
uv_attr = mesh->subd_attributes.add(uv_name, TypeDesc::TypePoint, ATTR_ELEMENT_CORNER);
if(subdivide_uvs) {
uv_attr->flags |= ATTR_SUBDIVIDED;
}
BL::Mesh::polygons_iterator p;
float3 *fdata = uv_attr->data_float3();
for(b_mesh.polygons.begin(p); p != b_mesh.polygons.end(); ++p) {
int n = p->loop_total();
for(int j = 0; j < n; j++) {
*(fdata++) = get_float3(l->data[p->loop_start() + j].uv());
}
}
}
/* UV tangent */
if(need_tangent) {
AttributeStandard sign_std =
(active_render)? ATTR_STD_UV_TANGENT_SIGN
: ATTR_STD_NONE;
ustring sign_name = ustring(
(string(l->name().c_str()) + ".tangent_sign").c_str());
bool need_sign = (mesh->need_attribute(scene, sign_name) ||
mesh->need_attribute(scene, sign_std));
mikk_compute_tangents(b_mesh,
l->name().c_str(),
mesh,
need_sign,
active_render);
}
/* Remove temporarily created UV attribute. */
if(!need_uv && uv_attr != NULL) {
mesh->subd_attributes.remove(uv_attr);
}
}
}
else if(mesh->need_attribute(scene, ATTR_STD_UV_TANGENT)) {
bool need_sign = mesh->need_attribute(scene, ATTR_STD_UV_TANGENT_SIGN);
mikk_compute_tangents(b_mesh, NULL, mesh, need_sign, true);
if(!mesh->need_attribute(scene, ATTR_STD_GENERATED)) {
mesh->subd_attributes.remove(ATTR_STD_GENERATED);
}
}
}
/* Create vertex pointiness attributes. */
/* Compare vertices by sum of their coordinates. */
@ -857,7 +951,13 @@ static void create_mesh(Scene *scene,
*/
attr_create_pointiness(scene, mesh, b_mesh, subdivision);
attr_create_vertex_color(scene, mesh, b_mesh, nverts, face_flags, subdivision);
attr_create_uv_map(scene, mesh, b_mesh, nverts, face_flags, subdivision, subdivide_uvs);
if(subdivision) {
attr_create_subd_uv_map(scene, mesh, b_mesh, nverts, face_flags, subdivide_uvs);
}
else {
attr_create_uv_map(scene, mesh, b_mesh, nverts, face_flags);
}
/* for volume objects, create a matrix to transform from object space to
* mesh texture space. this does not work with deformations but that can