Fix T49159: missing Cycles tangents for adaptive subdivision.
This commit is contained in:
		@@ -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_textures[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 = b_mesh.uv_textures[i].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
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user