Changeset View
Changeset View
Standalone View
Standalone View
source/blender/blenkernel/intern/multires_reshape_apply_base.cc
| Show All 28 Lines | |||||
| void multires_reshape_apply_base_update_mesh_coords(MultiresReshapeContext *reshape_context) | void multires_reshape_apply_base_update_mesh_coords(MultiresReshapeContext *reshape_context) | ||||
| { | { | ||||
| Mesh *base_mesh = reshape_context->base_mesh; | Mesh *base_mesh = reshape_context->base_mesh; | ||||
| float(*base_positions)[3] = BKE_mesh_vert_positions_for_write(base_mesh); | float(*base_positions)[3] = BKE_mesh_vert_positions_for_write(base_mesh); | ||||
| /* Update the context in case the vertices were duplicated. */ | /* Update the context in case the vertices were duplicated. */ | ||||
| reshape_context->base_positions = base_positions; | reshape_context->base_positions = base_positions; | ||||
| const MLoop *mloop = reshape_context->base_loops; | const int *corner_verts = reshape_context->base_corner_verts; | ||||
| for (int loop_index = 0; loop_index < base_mesh->totloop; ++loop_index) { | for (int loop_index = 0; loop_index < base_mesh->totloop; ++loop_index) { | ||||
| const MLoop *loop = &mloop[loop_index]; | |||||
| GridCoord grid_coord; | GridCoord grid_coord; | ||||
| grid_coord.grid_index = loop_index; | grid_coord.grid_index = loop_index; | ||||
| grid_coord.u = 1.0f; | grid_coord.u = 1.0f; | ||||
| grid_coord.v = 1.0f; | grid_coord.v = 1.0f; | ||||
| float P[3]; | float P[3]; | ||||
| float tangent_matrix[3][3]; | float tangent_matrix[3][3]; | ||||
| multires_reshape_evaluate_limit_at_grid(reshape_context, &grid_coord, P, tangent_matrix); | multires_reshape_evaluate_limit_at_grid(reshape_context, &grid_coord, P, tangent_matrix); | ||||
| ReshapeConstGridElement grid_element = multires_reshape_orig_grid_element_for_grid_coord( | ReshapeConstGridElement grid_element = multires_reshape_orig_grid_element_for_grid_coord( | ||||
| reshape_context, &grid_coord); | reshape_context, &grid_coord); | ||||
| float D[3]; | float D[3]; | ||||
| mul_v3_m3v3(D, tangent_matrix, grid_element.displacement); | mul_v3_m3v3(D, tangent_matrix, grid_element.displacement); | ||||
| add_v3_v3v3(base_positions[loop->v], P, D); | add_v3_v3v3(base_positions[corner_verts[loop_index]], P, D); | ||||
| } | } | ||||
| } | } | ||||
| /* Assumes no is normalized; return value's sign is negative if v is on the other side of the | /* Assumes no is normalized; return value's sign is negative if v is on the other side of the | ||||
| * plane. */ | * plane. */ | ||||
| static float v3_dist_from_plane(const float v[3], const float center[3], const float no[3]) | static float v3_dist_from_plane(const float v[3], const float center[3], const float no[3]) | ||||
| { | { | ||||
| float s[3]; | float s[3]; | ||||
| sub_v3_v3v3(s, v, center); | sub_v3_v3v3(s, v, center); | ||||
| return dot_v3v3(s, no); | return dot_v3v3(s, no); | ||||
| } | } | ||||
| void multires_reshape_apply_base_refit_base_mesh(MultiresReshapeContext *reshape_context) | void multires_reshape_apply_base_refit_base_mesh(MultiresReshapeContext *reshape_context) | ||||
| { | { | ||||
| Mesh *base_mesh = reshape_context->base_mesh; | Mesh *base_mesh = reshape_context->base_mesh; | ||||
| float(*base_positions)[3] = BKE_mesh_vert_positions_for_write(base_mesh); | float(*base_positions)[3] = BKE_mesh_vert_positions_for_write(base_mesh); | ||||
| /* Update the context in case the vertices were duplicated. */ | /* Update the context in case the vertices were duplicated. */ | ||||
| reshape_context->base_positions = base_positions; | reshape_context->base_positions = base_positions; | ||||
| MeshElemMap *pmap; | MeshElemMap *pmap; | ||||
| int *pmap_mem; | int *pmap_mem; | ||||
| BKE_mesh_vert_poly_map_create(&pmap, | BKE_mesh_vert_poly_map_create(&pmap, | ||||
| &pmap_mem, | &pmap_mem, | ||||
| reshape_context->base_polys, | reshape_context->base_polys, | ||||
| reshape_context->base_loops, | reshape_context->base_corner_verts, | ||||
| base_mesh->totvert, | base_mesh->totvert, | ||||
| base_mesh->totpoly, | base_mesh->totpoly, | ||||
| base_mesh->totloop); | base_mesh->totloop); | ||||
| float(*origco)[3] = static_cast<float(*)[3]>( | float(*origco)[3] = static_cast<float(*)[3]>( | ||||
| MEM_calloc_arrayN(base_mesh->totvert, sizeof(float[3]), __func__)); | MEM_calloc_arrayN(base_mesh->totvert, sizeof(float[3]), __func__)); | ||||
| for (int i = 0; i < base_mesh->totvert; i++) { | for (int i = 0; i < base_mesh->totvert; i++) { | ||||
| copy_v3_v3(origco[i], base_positions[i]); | copy_v3_v3(origco[i], base_positions[i]); | ||||
| Show All 9 Lines | for (int i = 0; i < base_mesh->totvert; i++) { | ||||
| /* Find center. */ | /* Find center. */ | ||||
| int tot = 0; | int tot = 0; | ||||
| for (int j = 0; j < pmap[i].count; j++) { | for (int j = 0; j < pmap[i].count; j++) { | ||||
| const MPoly *p = &reshape_context->base_polys[pmap[i].indices[j]]; | const MPoly *p = &reshape_context->base_polys[pmap[i].indices[j]]; | ||||
| /* This double counts, not sure if that's bad or good. */ | /* This double counts, not sure if that's bad or good. */ | ||||
| for (int k = 0; k < p->totloop; k++) { | for (int k = 0; k < p->totloop; k++) { | ||||
| const int vndx = reshape_context->base_loops[p->loopstart + k].v; | const int vndx = reshape_context->base_corner_verts[p->loopstart + k]; | ||||
| if (vndx != i) { | if (vndx != i) { | ||||
| add_v3_v3(center, origco[vndx]); | add_v3_v3(center, origco[vndx]); | ||||
| tot++; | tot++; | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| mul_v3_fl(center, 1.0f / tot); | mul_v3_fl(center, 1.0f / tot); | ||||
| /* Find normal. */ | /* Find normal. */ | ||||
| for (int j = 0; j < pmap[i].count; j++) { | for (int j = 0; j < pmap[i].count; j++) { | ||||
| const MPoly *p = &reshape_context->base_polys[pmap[i].indices[j]]; | const MPoly *p = &reshape_context->base_polys[pmap[i].indices[j]]; | ||||
| MPoly fake_poly; | MPoly fake_poly; | ||||
| float no[3]; | float no[3]; | ||||
| /* Set up poly, loops, and coords in order to call BKE_mesh_calc_poly_normal(). */ | /* Set up poly, loops, and coords in order to call BKE_mesh_calc_poly_normal(). */ | ||||
| fake_poly.totloop = p->totloop; | fake_poly.totloop = p->totloop; | ||||
| fake_poly.loopstart = 0; | fake_poly.loopstart = 0; | ||||
| MLoop *fake_loops = static_cast<MLoop *>( | int *poly_verts = static_cast<int *>(MEM_malloc_arrayN(p->totloop, sizeof(int), __func__)); | ||||
| MEM_malloc_arrayN(p->totloop, sizeof(MLoop), __func__)); | |||||
| float(*fake_co)[3] = static_cast<float(*)[3]>( | float(*fake_co)[3] = static_cast<float(*)[3]>( | ||||
| MEM_malloc_arrayN(p->totloop, sizeof(float[3]), __func__)); | MEM_malloc_arrayN(p->totloop, sizeof(float[3]), __func__)); | ||||
| for (int k = 0; k < p->totloop; k++) { | for (int k = 0; k < p->totloop; k++) { | ||||
| const int vndx = reshape_context->base_loops[p->loopstart + k].v; | const int vndx = reshape_context->base_corner_verts[p->loopstart + k]; | ||||
| fake_loops[k].v = k; | poly_verts[k] = k; | ||||
| if (vndx == i) { | if (vndx == i) { | ||||
| copy_v3_v3(fake_co[k], center); | copy_v3_v3(fake_co[k], center); | ||||
| } | } | ||||
| else { | else { | ||||
| copy_v3_v3(fake_co[k], origco[vndx]); | copy_v3_v3(fake_co[k], origco[vndx]); | ||||
| } | } | ||||
| } | } | ||||
| BKE_mesh_calc_poly_normal(&fake_poly, fake_loops, (const float(*)[3])fake_co, no); | BKE_mesh_calc_poly_normal(&fake_poly, poly_verts, (const float(*)[3])fake_co, no); | ||||
| MEM_freeN(fake_loops); | MEM_freeN(poly_verts); | ||||
| MEM_freeN(fake_co); | MEM_freeN(fake_co); | ||||
| add_v3_v3(avg_no, no); | add_v3_v3(avg_no, no); | ||||
| } | } | ||||
| normalize_v3(avg_no); | normalize_v3(avg_no); | ||||
| /* Push vertex away from the plane. */ | /* Push vertex away from the plane. */ | ||||
| const float dist = v3_dist_from_plane(base_positions[i], center, avg_no); | const float dist = v3_dist_from_plane(base_positions[i], center, avg_no); | ||||
| Show All 37 Lines | |||||