Changeset View
Changeset View
Standalone View
Standalone View
intern/cycles/blender/blender_mesh.cpp
| Show First 20 Lines • Show All 42 Lines • ▼ Show 20 Lines | |||||
| struct MikkUserData { | struct MikkUserData { | ||||
| MikkUserData(const BL::Mesh &b_mesh, | MikkUserData(const BL::Mesh &b_mesh, | ||||
| const char *layer_name, | const char *layer_name, | ||||
| const Mesh *mesh, | const Mesh *mesh, | ||||
| float3 *tangent, | float3 *tangent, | ||||
| float *tangent_sign) | float *tangent_sign) | ||||
| : mesh(mesh), texface(NULL), orco(NULL), tangent(tangent), tangent_sign(tangent_sign) | : mesh(mesh), texface(NULL), orco(NULL), tangent(tangent), tangent_sign(tangent_sign) | ||||
| { | { | ||||
| const AttributeSet &attributes = (mesh->get_num_subd_faces()) ? mesh->subd_attributes : | const AttributeSet &attributes = (mesh->get_num_subd_faces()) ? mesh->get_subd_attributes() : | ||||
| mesh->attributes; | mesh->get_attributes(); | ||||
| Attribute *attr_vN = attributes.find(ATTR_STD_VERTEX_NORMAL); | Attribute *attr_vN = attributes.find(ATTR_STD_VERTEX_NORMAL); | ||||
| vertex_normal = attr_vN->data_float3(); | vertex_normal = attr_vN->data_float3(); | ||||
| if (layer_name == NULL) { | if (layer_name == NULL) { | ||||
| Attribute *attr_orco = attributes.find(ATTR_STD_GENERATED); | Attribute *attr_orco = attributes.find(ATTR_STD_GENERATED); | ||||
| if (attr_orco) { | if (attr_orco) { | ||||
| ▲ Show 20 Lines • Show All 156 Lines • ▼ Show 20 Lines | if (userdata->tangent_sign != NULL) { | ||||
| userdata->tangent_sign[corner_index] = sign; | userdata->tangent_sign[corner_index] = sign; | ||||
| } | } | ||||
| } | } | ||||
| static void mikk_compute_tangents( | static void mikk_compute_tangents( | ||||
| const BL::Mesh &b_mesh, const char *layer_name, Mesh *mesh, bool need_sign, bool active_render) | const BL::Mesh &b_mesh, const char *layer_name, Mesh *mesh, bool need_sign, bool active_render) | ||||
| { | { | ||||
| /* Create tangent attributes. */ | /* Create tangent attributes. */ | ||||
| AttributeSet &attributes = (mesh->get_num_subd_faces()) ? mesh->subd_attributes : | AttributeSet &attributes = (mesh->get_num_subd_faces()) ? mesh->get_subd_attributes() : | ||||
| mesh->attributes; | mesh->get_attributes(); | ||||
| Attribute *attr; | Attribute *attr; | ||||
| ustring name; | ustring name; | ||||
| if (layer_name != NULL) { | if (layer_name != NULL) { | ||||
| name = ustring((string(layer_name) + ".tangent").c_str()); | name = ustring((string(layer_name) + ".tangent").c_str()); | ||||
| } | } | ||||
| else { | else { | ||||
| name = ustring("orco.tangent"); | name = ustring("orco.tangent"); | ||||
| } | } | ||||
| ▲ Show 20 Lines • Show All 59 Lines • ▼ Show 20 Lines | for (b_mesh.sculpt_vertex_colors.begin(l); l != b_mesh.sculpt_vertex_colors.end(); ++l) { | ||||
| const bool need_vcol = mesh->need_attribute(scene, vcol_name) || | const bool need_vcol = mesh->need_attribute(scene, vcol_name) || | ||||
| mesh->need_attribute(scene, vcol_std); | mesh->need_attribute(scene, vcol_std); | ||||
| if (!need_vcol) { | if (!need_vcol) { | ||||
| continue; | continue; | ||||
| } | } | ||||
| AttributeSet &attributes = (subdivision) ? mesh->subd_attributes : mesh->attributes; | AttributeSet &attributes = (subdivision) ? mesh->get_subd_attributes() : | ||||
| mesh->get_attributes(); | |||||
| Attribute *vcol_attr = attributes.add(vcol_name, TypeRGBA, ATTR_ELEMENT_VERTEX); | Attribute *vcol_attr = attributes.add(vcol_name, TypeRGBA, ATTR_ELEMENT_VERTEX); | ||||
| vcol_attr->std = vcol_std; | vcol_attr->set_std(vcol_std); | ||||
| float4 *cdata = vcol_attr->data_float4(); | float4 *cdata = vcol_attr->data_float4(); | ||||
| int numverts = b_mesh.vertices.length(); | int numverts = b_mesh.vertices.length(); | ||||
| for (int i = 0; i < numverts; i++) { | for (int i = 0; i < numverts; i++) { | ||||
| *(cdata++) = get_float4(l->data[i].color()); | *(cdata++) = get_float4(l->data[i].color()); | ||||
| } | } | ||||
| } | } | ||||
| Show All 15 Lines | for (b_mesh.vertex_colors.begin(l); l != b_mesh.vertex_colors.end(); ++l) { | ||||
| if (!need_vcol) { | if (!need_vcol) { | ||||
| continue; | continue; | ||||
| } | } | ||||
| Attribute *vcol_attr = NULL; | Attribute *vcol_attr = NULL; | ||||
| if (subdivision) { | if (subdivision) { | ||||
| if (active_render) { | if (active_render) { | ||||
| vcol_attr = mesh->subd_attributes.add(vcol_std, vcol_name); | vcol_attr = mesh->get_subd_attributes().add(vcol_std, vcol_name); | ||||
| } | } | ||||
| else { | else { | ||||
| vcol_attr = mesh->subd_attributes.add(vcol_name, TypeRGBA, ATTR_ELEMENT_CORNER_BYTE); | vcol_attr = mesh->get_subd_attributes().add(vcol_name, TypeRGBA, ATTR_ELEMENT_CORNER_BYTE); | ||||
| } | } | ||||
| BL::Mesh::polygons_iterator p; | BL::Mesh::polygons_iterator p; | ||||
| uchar4 *cdata = vcol_attr->data_uchar4(); | uchar4 *cdata = vcol_attr->data_uchar4(); | ||||
| for (b_mesh.polygons.begin(p); p != b_mesh.polygons.end(); ++p) { | for (b_mesh.polygons.begin(p); p != b_mesh.polygons.end(); ++p) { | ||||
| int n = p->loop_total(); | int n = p->loop_total(); | ||||
| for (int i = 0; i < n; i++) { | for (int i = 0; i < n; i++) { | ||||
| float4 color = get_float4(l->data[p->loop_start() + i].color()); | float4 color = get_float4(l->data[p->loop_start() + i].color()); | ||||
| /* Compress/encode vertex color using the sRGB curve. */ | /* Compress/encode vertex color using the sRGB curve. */ | ||||
| *(cdata++) = color_float4_to_uchar4(color); | *(cdata++) = color_float4_to_uchar4(color); | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| else { | else { | ||||
| if (active_render) { | if (active_render) { | ||||
| vcol_attr = mesh->attributes.add(vcol_std, vcol_name); | vcol_attr = mesh->get_attributes().add(vcol_std, vcol_name); | ||||
| } | } | ||||
| else { | else { | ||||
| vcol_attr = mesh->attributes.add(vcol_name, TypeRGBA, ATTR_ELEMENT_CORNER_BYTE); | vcol_attr = mesh->get_attributes().add(vcol_name, TypeRGBA, ATTR_ELEMENT_CORNER_BYTE); | ||||
| } | } | ||||
| BL::Mesh::loop_triangles_iterator t; | BL::Mesh::loop_triangles_iterator t; | ||||
| uchar4 *cdata = vcol_attr->data_uchar4(); | uchar4 *cdata = vcol_attr->data_uchar4(); | ||||
| for (b_mesh.loop_triangles.begin(t); t != b_mesh.loop_triangles.end(); ++t) { | for (b_mesh.loop_triangles.begin(t); t != b_mesh.loop_triangles.end(); ++t) { | ||||
| int3 li = get_int3(t->loops()); | int3 li = get_int3(t->loops()); | ||||
| float4 c1 = get_float4(l->data[li[0]].color()); | float4 c1 = get_float4(l->data[li[0]].color()); | ||||
| Show All 33 Lines | for (b_mesh.uv_layers.begin(l); l != b_mesh.uv_layers.end(); ++l) { | ||||
| /* UV map */ | /* UV map */ | ||||
| /* NOTE: We create temporary UV layer if its needed for tangent but | /* NOTE: We create temporary UV layer if its needed for tangent but | ||||
| * wasn't requested by other nodes in shaders. | * wasn't requested by other nodes in shaders. | ||||
| */ | */ | ||||
| Attribute *uv_attr = NULL; | Attribute *uv_attr = NULL; | ||||
| if (need_uv || need_tangent) { | if (need_uv || need_tangent) { | ||||
| if (active_render) { | if (active_render) { | ||||
| uv_attr = mesh->attributes.add(uv_std, uv_name); | uv_attr = mesh->get_attributes().add(uv_std, uv_name); | ||||
| } | } | ||||
| else { | else { | ||||
| uv_attr = mesh->attributes.add(uv_name, TypeFloat2, ATTR_ELEMENT_CORNER); | uv_attr = mesh->get_attributes().add(uv_name, TypeFloat2, ATTR_ELEMENT_CORNER); | ||||
| } | } | ||||
| BL::Mesh::loop_triangles_iterator t; | BL::Mesh::loop_triangles_iterator t; | ||||
| float2 *fdata = uv_attr->data_float2(); | float2 *fdata = uv_attr->data_float2(); | ||||
| for (b_mesh.loop_triangles.begin(t); t != b_mesh.loop_triangles.end(); ++t) { | for (b_mesh.loop_triangles.begin(t); t != b_mesh.loop_triangles.end(); ++t) { | ||||
| int3 li = get_int3(t->loops()); | int3 li = get_int3(t->loops()); | ||||
| fdata[0] = get_float2(l->data[li[0]].uv()); | fdata[0] = get_float2(l->data[li[0]].uv()); | ||||
| fdata[1] = get_float2(l->data[li[1]].uv()); | fdata[1] = get_float2(l->data[li[1]].uv()); | ||||
| fdata[2] = get_float2(l->data[li[2]].uv()); | fdata[2] = get_float2(l->data[li[2]].uv()); | ||||
| fdata += 3; | fdata += 3; | ||||
| } | } | ||||
| } | } | ||||
| /* UV tangent */ | /* UV tangent */ | ||||
| if (need_tangent) { | if (need_tangent) { | ||||
| AttributeStandard sign_std = (active_render) ? ATTR_STD_UV_TANGENT_SIGN : ATTR_STD_NONE; | 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()); | ustring sign_name = ustring((string(l->name().c_str()) + ".tangent_sign").c_str()); | ||||
| bool need_sign = (mesh->need_attribute(scene, sign_name) || | bool need_sign = (mesh->need_attribute(scene, sign_name) || | ||||
| mesh->need_attribute(scene, sign_std)); | mesh->need_attribute(scene, sign_std)); | ||||
| mikk_compute_tangents(b_mesh, l->name().c_str(), mesh, need_sign, active_render); | mikk_compute_tangents(b_mesh, l->name().c_str(), mesh, need_sign, active_render); | ||||
| } | } | ||||
| /* Remove temporarily created UV attribute. */ | /* Remove temporarily created UV attribute. */ | ||||
| if (!need_uv && uv_attr != NULL) { | if (!need_uv && uv_attr != NULL) { | ||||
| mesh->attributes.remove(uv_attr); | mesh->get_attributes().remove(uv_attr); | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| else if (mesh->need_attribute(scene, ATTR_STD_UV_TANGENT)) { | else if (mesh->need_attribute(scene, ATTR_STD_UV_TANGENT)) { | ||||
| bool need_sign = mesh->need_attribute(scene, ATTR_STD_UV_TANGENT_SIGN); | bool need_sign = mesh->need_attribute(scene, ATTR_STD_UV_TANGENT_SIGN); | ||||
| mikk_compute_tangents(b_mesh, NULL, mesh, need_sign, true); | mikk_compute_tangents(b_mesh, NULL, mesh, need_sign, true); | ||||
| if (!mesh->need_attribute(scene, ATTR_STD_GENERATED)) { | if (!mesh->need_attribute(scene, ATTR_STD_GENERATED)) { | ||||
| mesh->attributes.remove(ATTR_STD_GENERATED); | mesh->get_attributes().remove(ATTR_STD_GENERATED); | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| static void attr_create_subd_uv_map(Scene *scene, Mesh *mesh, BL::Mesh &b_mesh, bool subdivide_uvs) | static void attr_create_subd_uv_map(Scene *scene, Mesh *mesh, BL::Mesh &b_mesh, bool subdivide_uvs) | ||||
| { | { | ||||
| if (b_mesh.uv_layers.length() != 0) { | if (b_mesh.uv_layers.length() != 0) { | ||||
| BL::Mesh::uv_layers_iterator l; | BL::Mesh::uv_layers_iterator l; | ||||
| Show All 13 Lines | for (b_mesh.uv_layers.begin(l); l != b_mesh.uv_layers.end(); ++l, ++i) { | ||||
| const bool need_tangent = mesh->need_attribute(scene, tangent_name) || | const bool need_tangent = mesh->need_attribute(scene, tangent_name) || | ||||
| (active_render && mesh->need_attribute(scene, tangent_std)); | (active_render && mesh->need_attribute(scene, tangent_std)); | ||||
| Attribute *uv_attr = NULL; | Attribute *uv_attr = NULL; | ||||
| /* UV map */ | /* UV map */ | ||||
| if (need_uv || need_tangent) { | if (need_uv || need_tangent) { | ||||
| if (active_render) | if (active_render) | ||||
| uv_attr = mesh->subd_attributes.add(uv_std, uv_name); | uv_attr = mesh->get_subd_attributes().add(uv_std, uv_name); | ||||
| else | else | ||||
| uv_attr = mesh->subd_attributes.add(uv_name, TypeFloat2, ATTR_ELEMENT_CORNER); | uv_attr = mesh->get_subd_attributes().add(uv_name, TypeFloat2, ATTR_ELEMENT_CORNER); | ||||
| if (subdivide_uvs) { | if (subdivide_uvs) { | ||||
| uv_attr->flags |= ATTR_SUBDIVIDED; | uv_attr->get_flags() |= ATTR_SUBDIVIDED; | ||||
| } | } | ||||
| BL::Mesh::polygons_iterator p; | BL::Mesh::polygons_iterator p; | ||||
| float2 *fdata = uv_attr->data_float2(); | float2 *fdata = uv_attr->data_float2(); | ||||
| for (b_mesh.polygons.begin(p); p != b_mesh.polygons.end(); ++p) { | for (b_mesh.polygons.begin(p); p != b_mesh.polygons.end(); ++p) { | ||||
| int n = p->loop_total(); | int n = p->loop_total(); | ||||
| for (int j = 0; j < n; j++) { | for (int j = 0; j < n; j++) { | ||||
| *(fdata++) = get_float2(l->data[p->loop_start() + j].uv()); | *(fdata++) = get_float2(l->data[p->loop_start() + j].uv()); | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| /* UV tangent */ | /* UV tangent */ | ||||
| if (need_tangent) { | if (need_tangent) { | ||||
| AttributeStandard sign_std = (active_render) ? ATTR_STD_UV_TANGENT_SIGN : ATTR_STD_NONE; | 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()); | ustring sign_name = ustring((string(l->name().c_str()) + ".tangent_sign").c_str()); | ||||
| bool need_sign = (mesh->need_attribute(scene, sign_name) || | bool need_sign = (mesh->need_attribute(scene, sign_name) || | ||||
| mesh->need_attribute(scene, sign_std)); | mesh->need_attribute(scene, sign_std)); | ||||
| mikk_compute_tangents(b_mesh, l->name().c_str(), mesh, need_sign, active_render); | mikk_compute_tangents(b_mesh, l->name().c_str(), mesh, need_sign, active_render); | ||||
| } | } | ||||
| /* Remove temporarily created UV attribute. */ | /* Remove temporarily created UV attribute. */ | ||||
| if (!need_uv && uv_attr != NULL) { | if (!need_uv && uv_attr != NULL) { | ||||
| mesh->subd_attributes.remove(uv_attr); | mesh->get_subd_attributes().remove(uv_attr); | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| else if (mesh->need_attribute(scene, ATTR_STD_UV_TANGENT)) { | else if (mesh->need_attribute(scene, ATTR_STD_UV_TANGENT)) { | ||||
| bool need_sign = mesh->need_attribute(scene, ATTR_STD_UV_TANGENT_SIGN); | bool need_sign = mesh->need_attribute(scene, ATTR_STD_UV_TANGENT_SIGN); | ||||
| mikk_compute_tangents(b_mesh, NULL, mesh, need_sign, true); | mikk_compute_tangents(b_mesh, NULL, mesh, need_sign, true); | ||||
| if (!mesh->need_attribute(scene, ATTR_STD_GENERATED)) { | if (!mesh->need_attribute(scene, ATTR_STD_GENERATED)) { | ||||
| mesh->subd_attributes.remove(ATTR_STD_GENERATED); | mesh->get_subd_attributes().remove(ATTR_STD_GENERATED); | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| /* Create vertex pointiness attributes. */ | /* Create vertex pointiness attributes. */ | ||||
| /* Compare vertices by sum of their coordinates. */ | /* Compare vertices by sum of their coordinates. */ | ||||
| class VertexAverageComparator { | class VertexAverageComparator { | ||||
| ▲ Show 20 Lines • Show All 125 Lines • ▼ Show 20 Lines | if (counter[vert_index] > 0) { | ||||
| const float angle = safe_acosf(dot(normal, edge_accum[vert_index] / counter[vert_index])); | const float angle = safe_acosf(dot(normal, edge_accum[vert_index] / counter[vert_index])); | ||||
| raw_data[vert_index] = angle * M_1_PI_F; | raw_data[vert_index] = angle * M_1_PI_F; | ||||
| } | } | ||||
| else { | else { | ||||
| raw_data[vert_index] = 0.0f; | raw_data[vert_index] = 0.0f; | ||||
| } | } | ||||
| } | } | ||||
| /* STEP 3: Blur vertices to approximate 2 ring neighborhood. */ | /* STEP 3: Blur vertices to approximate 2 ring neighborhood. */ | ||||
| AttributeSet &attributes = (subdivision) ? mesh->subd_attributes : mesh->attributes; | AttributeSet &attributes = (subdivision) ? mesh->get_subd_attributes() : mesh->get_attributes(); | ||||
| Attribute *attr = attributes.add(ATTR_STD_POINTINESS); | Attribute *attr = attributes.add(ATTR_STD_POINTINESS); | ||||
| float *data = attr->data_float(); | float *data = attr->data_float(); | ||||
| memcpy(data, &raw_data[0], sizeof(float) * raw_data.size()); | memcpy(data, &raw_data[0], sizeof(float) * raw_data.size()); | ||||
| memset(&counter[0], 0, sizeof(int) * counter.size()); | memset(&counter[0], 0, sizeof(int) * counter.size()); | ||||
| edge_index = 0; | edge_index = 0; | ||||
| visited_edges.clear(); | visited_edges.clear(); | ||||
| for (b_mesh.edges.begin(e); e != b_mesh.edges.end(); ++e, ++edge_index) { | for (b_mesh.edges.begin(e); e != b_mesh.edges.end(); ++e, ++edge_index) { | ||||
| const int v0 = vert_orig_index[b_mesh.edges[edge_index].vertices()[0]], | const int v0 = vert_orig_index[b_mesh.edges[edge_index].vertices()[0]], | ||||
| ▲ Show 20 Lines • Show All 43 Lines • ▼ Show 20 Lines | static void attr_create_random_per_island(Scene *scene, | ||||
| DisjointSet vertices_sets(number_of_vertices); | DisjointSet vertices_sets(number_of_vertices); | ||||
| BL::Mesh::edges_iterator e; | BL::Mesh::edges_iterator e; | ||||
| for (b_mesh.edges.begin(e); e != b_mesh.edges.end(); ++e) { | for (b_mesh.edges.begin(e); e != b_mesh.edges.end(); ++e) { | ||||
| vertices_sets.join(e->vertices()[0], e->vertices()[1]); | vertices_sets.join(e->vertices()[0], e->vertices()[1]); | ||||
| } | } | ||||
| AttributeSet &attributes = (subdivision) ? mesh->subd_attributes : mesh->attributes; | AttributeSet &attributes = (subdivision) ? mesh->get_subd_attributes() : mesh->get_attributes(); | ||||
| Attribute *attribute = attributes.add(ATTR_STD_RANDOM_PER_ISLAND); | Attribute *attribute = attributes.add(ATTR_STD_RANDOM_PER_ISLAND); | ||||
| float *data = attribute->data_float(); | float *data = attribute->data_float(); | ||||
| if (!subdivision) { | if (!subdivision) { | ||||
| BL::Mesh::loop_triangles_iterator t; | BL::Mesh::loop_triangles_iterator t; | ||||
| for (b_mesh.loop_triangles.begin(t); t != b_mesh.loop_triangles.end(); ++t) { | for (b_mesh.loop_triangles.begin(t); t != b_mesh.loop_triangles.end(); ++t) { | ||||
| data[t->index()] = hash_uint_to_float(vertices_sets.find(t->vertices()[0])); | data[t->index()] = hash_uint_to_float(vertices_sets.find(t->vertices()[0])); | ||||
| } | } | ||||
| ▲ Show 20 Lines • Show All 47 Lines • ▼ Show 20 Lines | static void create_mesh(Scene *scene, | ||||
| mesh->reserve_mesh(numverts, numtris); | mesh->reserve_mesh(numverts, numtris); | ||||
| /* create vertex coordinates and normals */ | /* create vertex coordinates and normals */ | ||||
| BL::Mesh::vertices_iterator v; | BL::Mesh::vertices_iterator v; | ||||
| for (b_mesh.vertices.begin(v); v != b_mesh.vertices.end(); ++v) | for (b_mesh.vertices.begin(v); v != b_mesh.vertices.end(); ++v) | ||||
| mesh->add_vertex(get_float3(v->co())); | mesh->add_vertex(get_float3(v->co())); | ||||
| AttributeSet &attributes = (subdivision) ? mesh->subd_attributes : mesh->attributes; | AttributeSet &attributes = (subdivision) ? mesh->get_subd_attributes() : mesh->get_attributes(); | ||||
| Attribute *attr_N = attributes.add(ATTR_STD_VERTEX_NORMAL); | Attribute *attr_N = attributes.add(ATTR_STD_VERTEX_NORMAL); | ||||
| float3 *N = attr_N->data_float3(); | float3 *N = attr_N->data_float3(); | ||||
| for (b_mesh.vertices.begin(v); v != b_mesh.vertices.end(); ++v, ++N) | for (b_mesh.vertices.begin(v); v != b_mesh.vertices.end(); ++v, ++N) | ||||
| *N = get_float3(v->normal()); | *N = get_float3(v->normal()); | ||||
| N = attr_N->data_float3(); | N = attr_N->data_float3(); | ||||
| /* create generated coordinates from undeformed coordinates */ | /* create generated coordinates from undeformed coordinates */ | ||||
| const bool need_default_tangent = (subdivision == false) && (b_mesh.uv_layers.length() == 0) && | const bool need_default_tangent = (subdivision == false) && (b_mesh.uv_layers.length() == 0) && | ||||
| (mesh->need_attribute(scene, ATTR_STD_UV_TANGENT)); | (mesh->need_attribute(scene, ATTR_STD_UV_TANGENT)); | ||||
| if (mesh->need_attribute(scene, ATTR_STD_GENERATED) || need_default_tangent) { | if (mesh->need_attribute(scene, ATTR_STD_GENERATED) || need_default_tangent) { | ||||
| Attribute *attr = attributes.add(ATTR_STD_GENERATED); | Attribute *attr = attributes.add(ATTR_STD_GENERATED); | ||||
| attr->flags |= ATTR_SUBDIVIDED; | attr->get_flags() |= ATTR_SUBDIVIDED; | ||||
| float3 loc, size; | float3 loc, size; | ||||
| mesh_texture_space(b_mesh, loc, size); | mesh_texture_space(b_mesh, loc, size); | ||||
| float3 *generated = attr->data_float3(); | float3 *generated = attr->data_float3(); | ||||
| size_t i = 0; | size_t i = 0; | ||||
| for (b_mesh.vertices.begin(v); v != b_mesh.vertices.end(); ++v) { | for (b_mesh.vertices.begin(v); v != b_mesh.vertices.end(); ++v) { | ||||
| ▲ Show 20 Lines • Show All 61 Lines • ▼ Show 20 Lines | static void create_mesh(Scene *scene, | ||||
| else { | else { | ||||
| attr_create_uv_map(scene, mesh, b_mesh); | attr_create_uv_map(scene, mesh, b_mesh); | ||||
| } | } | ||||
| /* For volume objects, create a matrix to transform from object space to | /* For volume objects, create a matrix to transform from object space to | ||||
| * mesh texture space. this does not work with deformations but that can | * mesh texture space. this does not work with deformations but that can | ||||
| * probably only be done well with a volume grid mapping of coordinates. */ | * probably only be done well with a volume grid mapping of coordinates. */ | ||||
| if (mesh->need_attribute(scene, ATTR_STD_GENERATED_TRANSFORM)) { | if (mesh->need_attribute(scene, ATTR_STD_GENERATED_TRANSFORM)) { | ||||
| Attribute *attr = mesh->attributes.add(ATTR_STD_GENERATED_TRANSFORM); | Attribute *attr = mesh->get_attributes().add(ATTR_STD_GENERATED_TRANSFORM); | ||||
| Transform *tfm = attr->data_transform(); | Transform *tfm = attr->data_transform(); | ||||
| float3 loc, size; | float3 loc, size; | ||||
| mesh_texture_space(b_mesh, loc, size); | mesh_texture_space(b_mesh, loc, size); | ||||
| *tfm = transform_translate(-loc) * transform_scale(size); | *tfm = transform_translate(-loc) * transform_scale(size); | ||||
| } | } | ||||
| } | } | ||||
| ▲ Show 20 Lines • Show All 75 Lines • ▼ Show 20 Lines | static void sync_mesh_cached_velocities(BL::Object &b_ob, Scene *scene, Mesh *mesh) | ||||
| const size_t numverts = mesh->get_verts().size(); | const size_t numverts = mesh->get_verts().size(); | ||||
| if (b_mesh_cache.vertex_velocities.length() != numverts) { | if (b_mesh_cache.vertex_velocities.length() != numverts) { | ||||
| return; | return; | ||||
| } | } | ||||
| /* Find or add attribute */ | /* Find or add attribute */ | ||||
| float3 *P = &mesh->get_verts()[0]; | float3 *P = &mesh->get_verts()[0]; | ||||
| Attribute *attr_mP = mesh->attributes.find(ATTR_STD_MOTION_VERTEX_POSITION); | Attribute *attr_mP = mesh->get_attributes().find(ATTR_STD_MOTION_VERTEX_POSITION); | ||||
| if (!attr_mP) { | if (!attr_mP) { | ||||
| attr_mP = mesh->attributes.add(ATTR_STD_MOTION_VERTEX_POSITION); | attr_mP = mesh->get_attributes().add(ATTR_STD_MOTION_VERTEX_POSITION); | ||||
| } | } | ||||
| /* Only export previous and next frame, we don't have any in between data. */ | /* Only export previous and next frame, we don't have any in between data. */ | ||||
| float motion_times[2] = {-1.0f, 1.0f}; | float motion_times[2] = {-1.0f, 1.0f}; | ||||
| for (int step = 0; step < 2; step++) { | for (int step = 0; step < 2; step++) { | ||||
| const float relative_time = motion_times[step] * scene->motion_shutter_time() * 0.5f; | const float relative_time = motion_times[step] * scene->motion_shutter_time() * 0.5f; | ||||
| float3 *mP = attr_mP->data_float3() + step * numverts; | float3 *mP = attr_mP->data_float3() + step * numverts; | ||||
| Show All 18 Lines | if (!b_fluid_domain) | ||||
| return; | return; | ||||
| /* If the mesh has modifiers following the fluid domain we can't export motion. */ | /* If the mesh has modifiers following the fluid domain we can't export motion. */ | ||||
| if (b_fluid_domain.mesh_vertices.length() != mesh->get_verts().size()) | if (b_fluid_domain.mesh_vertices.length() != mesh->get_verts().size()) | ||||
| return; | return; | ||||
| /* Find or add attribute */ | /* Find or add attribute */ | ||||
| float3 *P = &mesh->get_verts()[0]; | float3 *P = &mesh->get_verts()[0]; | ||||
| Attribute *attr_mP = mesh->attributes.find(ATTR_STD_MOTION_VERTEX_POSITION); | Attribute *attr_mP = mesh->get_attributes().find(ATTR_STD_MOTION_VERTEX_POSITION); | ||||
| if (!attr_mP) { | if (!attr_mP) { | ||||
| attr_mP = mesh->attributes.add(ATTR_STD_MOTION_VERTEX_POSITION); | attr_mP = mesh->get_attributes().add(ATTR_STD_MOTION_VERTEX_POSITION); | ||||
| } | } | ||||
| /* Only export previous and next frame, we don't have any in between data. */ | /* Only export previous and next frame, we don't have any in between data. */ | ||||
| float motion_times[2] = {-1.0f, 1.0f}; | float motion_times[2] = {-1.0f, 1.0f}; | ||||
| for (int step = 0; step < 2; step++) { | for (int step = 0; step < 2; step++) { | ||||
| float relative_time = motion_times[step] * scene->motion_shutter_time() * 0.5f; | float relative_time = motion_times[step] * scene->motion_shutter_time() * 0.5f; | ||||
| float3 *mP = attr_mP->data_float3() + step * mesh->get_verts().size(); | float3 *mP = attr_mP->data_float3() + step * mesh->get_verts().size(); | ||||
| Show All 14 Lines | void BlenderSync::sync_mesh(BL::Depsgraph b_depsgraph, BL::Object b_ob, Mesh *mesh) | ||||
| array<Node *> used_shaders = mesh->get_used_shaders(); | array<Node *> used_shaders = mesh->get_used_shaders(); | ||||
| Mesh new_mesh; | Mesh new_mesh; | ||||
| new_mesh.set_used_shaders(used_shaders); | new_mesh.set_used_shaders(used_shaders); | ||||
| if (view_layer.use_surfaces) { | if (view_layer.use_surfaces) { | ||||
| /* Adaptive subdivision setup. Not for baking since that requires | /* Adaptive subdivision setup. Not for baking since that requires | ||||
| * exact mapping to the Blender mesh. */ | * exact mapping to the Blender mesh. */ | ||||
| if (!scene->bake_manager->get_baking()) { | if (!scene->get_bake_manager()->get_baking()) { | ||||
| new_mesh.set_subdivision_type(object_subdivision_type(b_ob, preview, experimental)); | new_mesh.set_subdivision_type(object_subdivision_type(b_ob, preview, experimental)); | ||||
| } | } | ||||
| /* For some reason, meshes do not need this... */ | /* For some reason, meshes do not need this... */ | ||||
| bool need_undeformed = new_mesh.need_attribute(scene, ATTR_STD_GENERATED); | bool need_undeformed = new_mesh.need_attribute(scene, ATTR_STD_GENERATED); | ||||
| BL::Mesh b_mesh = object_to_mesh( | BL::Mesh b_mesh = object_to_mesh( | ||||
| b_data, b_ob, b_depsgraph, need_undeformed, new_mesh.get_subdivision_type()); | b_data, b_ob, b_depsgraph, need_undeformed, new_mesh.get_subdivision_type()); | ||||
| Show All 19 Lines | void BlenderSync::sync_mesh(BL::Depsgraph b_depsgraph, BL::Object b_ob, Mesh *mesh) | ||||
| /* mesh fluid motion mantaflow */ | /* mesh fluid motion mantaflow */ | ||||
| sync_mesh_fluid_motion(b_ob, scene, &new_mesh); | sync_mesh_fluid_motion(b_ob, scene, &new_mesh); | ||||
| /* update original sockets */ | /* update original sockets */ | ||||
| mesh->clear_non_sockets(); | mesh->clear_non_sockets(); | ||||
| for (const SocketType &socket : new_mesh.type->inputs) { | for (const SocketType &socket : new_mesh.get_type()->get_inputs()) { | ||||
| /* Those sockets are updated in sync_object, so do not modify them. */ | /* Those sockets are updated in sync_object, so do not modify them. */ | ||||
| if (socket.name == "use_motion_blur" || socket.name == "motion_steps" || | if (socket.get_name() == "use_motion_blur" || socket.get_name() == "motion_steps" || | ||||
| socket.name == "used_shaders") { | socket.get_name() == "used_shaders") { | ||||
| continue; | continue; | ||||
| } | } | ||||
| mesh->set_value(socket, new_mesh, socket); | mesh->set_value(socket, new_mesh, socket); | ||||
| } | } | ||||
| mesh->attributes.clear(); | mesh->get_attributes().clear(); | ||||
| foreach (Attribute &attr, new_mesh.attributes.attributes) { | foreach (Attribute &attr, new_mesh.get_attributes().get_attributes()) { | ||||
| mesh->attributes.attributes.push_back(std::move(attr)); | mesh->get_attributes().get_attributes().push_back(std::move(attr)); | ||||
| } | } | ||||
| mesh->subd_attributes.clear(); | mesh->get_subd_attributes().clear(); | ||||
| foreach (Attribute &attr, new_mesh.subd_attributes.attributes) { | foreach (Attribute &attr, new_mesh.get_subd_attributes().get_attributes()) { | ||||
| mesh->subd_attributes.attributes.push_back(std::move(attr)); | mesh->get_subd_attributes().get_attributes().push_back(std::move(attr)); | ||||
| } | } | ||||
| mesh->set_num_subd_faces(new_mesh.get_num_subd_faces()); | mesh->set_num_subd_faces(new_mesh.get_num_subd_faces()); | ||||
| /* tag update */ | /* tag update */ | ||||
| bool rebuild = (mesh->triangles_is_modified()) || (mesh->subd_num_corners_is_modified()) || | bool rebuild = (mesh->triangles_is_modified()) || (mesh->subd_num_corners_is_modified()) || | ||||
| (mesh->subd_shader_is_modified()) || (mesh->subd_smooth_is_modified()) || | (mesh->subd_shader_is_modified()) || (mesh->subd_smooth_is_modified()) || | ||||
| (mesh->subd_ptex_offset_is_modified()) || | (mesh->subd_ptex_offset_is_modified()) || | ||||
| Show All 33 Lines | if (ccl::BKE_object_is_deform_modified(b_ob, b_scene, preview)) { | ||||
| /* get derived mesh */ | /* get derived mesh */ | ||||
| b_mesh = object_to_mesh(b_data, b_ob, b_depsgraph, false, Mesh::SUBDIVISION_NONE); | b_mesh = object_to_mesh(b_data, b_ob, b_depsgraph, false, Mesh::SUBDIVISION_NONE); | ||||
| } | } | ||||
| /* TODO(sergey): Perform preliminary check for number of vertices. */ | /* TODO(sergey): Perform preliminary check for number of vertices. */ | ||||
| if (b_mesh) { | if (b_mesh) { | ||||
| /* Export deformed coordinates. */ | /* Export deformed coordinates. */ | ||||
| /* Find attributes. */ | /* Find attributes. */ | ||||
| Attribute *attr_mP = mesh->attributes.find(ATTR_STD_MOTION_VERTEX_POSITION); | Attribute *attr_mP = mesh->get_attributes().find(ATTR_STD_MOTION_VERTEX_POSITION); | ||||
| Attribute *attr_mN = mesh->attributes.find(ATTR_STD_MOTION_VERTEX_NORMAL); | Attribute *attr_mN = mesh->get_attributes().find(ATTR_STD_MOTION_VERTEX_NORMAL); | ||||
| Attribute *attr_N = mesh->attributes.find(ATTR_STD_VERTEX_NORMAL); | Attribute *attr_N = mesh->get_attributes().find(ATTR_STD_VERTEX_NORMAL); | ||||
| bool new_attribute = false; | bool new_attribute = false; | ||||
| /* Add new attributes if they don't exist already. */ | /* Add new attributes if they don't exist already. */ | ||||
| if (!attr_mP) { | if (!attr_mP) { | ||||
| attr_mP = mesh->attributes.add(ATTR_STD_MOTION_VERTEX_POSITION); | attr_mP = mesh->get_attributes().add(ATTR_STD_MOTION_VERTEX_POSITION); | ||||
| if (attr_N) | if (attr_N) | ||||
| attr_mN = mesh->attributes.add(ATTR_STD_MOTION_VERTEX_NORMAL); | attr_mN = mesh->get_attributes().add(ATTR_STD_MOTION_VERTEX_NORMAL); | ||||
| new_attribute = true; | new_attribute = true; | ||||
| } | } | ||||
| /* Load vertex data from mesh. */ | /* Load vertex data from mesh. */ | ||||
| float3 *mP = attr_mP->data_float3() + motion_step * numverts; | float3 *mP = attr_mP->data_float3() + motion_step * numverts; | ||||
| float3 *mN = (attr_mN) ? attr_mN->data_float3() + motion_step * numverts : NULL; | float3 *mN = (attr_mN) ? attr_mN->data_float3() + motion_step * numverts : NULL; | ||||
| /* NOTE: We don't copy more that existing amount of vertices to prevent | /* NOTE: We don't copy more that existing amount of vertices to prevent | ||||
| * possible memory corruption. | * possible memory corruption. | ||||
| Show All 11 Lines | if (new_attribute) { | ||||
| memcmp(mP, &mesh->get_verts()[0], sizeof(float3) * numverts) == 0) { | memcmp(mP, &mesh->get_verts()[0], sizeof(float3) * numverts) == 0) { | ||||
| /* no motion, remove attributes again */ | /* no motion, remove attributes again */ | ||||
| if (b_mesh.vertices.length() != numverts) { | if (b_mesh.vertices.length() != numverts) { | ||||
| VLOG(1) << "Topology differs, disabling motion blur for object " << b_ob.name(); | VLOG(1) << "Topology differs, disabling motion blur for object " << b_ob.name(); | ||||
| } | } | ||||
| else { | else { | ||||
| VLOG(1) << "No actual deformation motion for object " << b_ob.name(); | VLOG(1) << "No actual deformation motion for object " << b_ob.name(); | ||||
| } | } | ||||
| mesh->attributes.remove(ATTR_STD_MOTION_VERTEX_POSITION); | mesh->get_attributes().remove(ATTR_STD_MOTION_VERTEX_POSITION); | ||||
| if (attr_mN) | if (attr_mN) | ||||
| mesh->attributes.remove(ATTR_STD_MOTION_VERTEX_NORMAL); | mesh->get_attributes().remove(ATTR_STD_MOTION_VERTEX_NORMAL); | ||||
| } | } | ||||
| else if (motion_step > 0) { | else if (motion_step > 0) { | ||||
| VLOG(1) << "Filling deformation motion for object " << b_ob.name(); | VLOG(1) << "Filling deformation motion for object " << b_ob.name(); | ||||
| /* motion, fill up previous steps that we might have skipped because | /* motion, fill up previous steps that we might have skipped because | ||||
| * they had no motion, but we need them anyway now */ | * they had no motion, but we need them anyway now */ | ||||
| float3 *P = &mesh->get_verts()[0]; | float3 *P = &mesh->get_verts()[0]; | ||||
| float3 *N = (attr_N) ? attr_N->data_float3() : NULL; | float3 *N = (attr_N) ? attr_N->data_float3() : NULL; | ||||
| for (int step = 0; step < motion_step; step++) { | for (int step = 0; step < motion_step; step++) { | ||||
| Show All 26 Lines | |||||