Changeset View
Changeset View
Standalone View
Standalone View
source/blender/blenkernel/intern/subdiv_mesh.cc
| Show All 25 Lines | |||||
| #include "BKE_subdiv_eval.h" | #include "BKE_subdiv_eval.h" | ||||
| #include "BKE_subdiv_foreach.h" | #include "BKE_subdiv_foreach.h" | ||||
| #include "BKE_subdiv_mesh.h" | #include "BKE_subdiv_mesh.h" | ||||
| #include "MEM_guardedalloc.h" | #include "MEM_guardedalloc.h" | ||||
| using blender::float2; | using blender::float2; | ||||
| using blender::float3; | using blender::float3; | ||||
| using blender::MutableSpan; | |||||
| using blender::Span; | using blender::Span; | ||||
| /* -------------------------------------------------------------------- */ | /* -------------------------------------------------------------------- */ | ||||
| /** \name Subdivision Context | /** \name Subdivision Context | ||||
| * \{ */ | * \{ */ | ||||
| struct SubdivMeshContext { | struct SubdivMeshContext { | ||||
| const SubdivToMeshSettings *settings; | const SubdivToMeshSettings *settings; | ||||
| const Mesh *coarse_mesh; | const Mesh *coarse_mesh; | ||||
| const float (*coarse_positions)[3]; | const float (*coarse_positions)[3]; | ||||
| const MEdge *coarse_edges; | const MEdge *coarse_edges; | ||||
| const MPoly *coarse_polys; | const MPoly *coarse_polys; | ||||
| const MLoop *coarse_loops; | Span<int> coarse_corner_verts; | ||||
| Subdiv *subdiv; | Subdiv *subdiv; | ||||
| Mesh *subdiv_mesh; | Mesh *subdiv_mesh; | ||||
| float3 *subdiv_positions; | float3 *subdiv_positions; | ||||
| MEdge *subdiv_edges; | MEdge *subdiv_edges; | ||||
| MPoly *subdiv_polys; | MPoly *subdiv_polys; | ||||
| MLoop *subdiv_loops; | MutableSpan<int> subdiv_corner_verts; | ||||
| MutableSpan<int> subdiv_corner_edges; | |||||
| /* Cached custom data arrays for faster access. */ | /* Cached custom data arrays for faster access. */ | ||||
| int *vert_origindex; | int *vert_origindex; | ||||
| int *edge_origindex; | int *edge_origindex; | ||||
| int *loop_origindex; | int *loop_origindex; | ||||
| int *poly_origindex; | int *poly_origindex; | ||||
| /* UV layers interpolation. */ | /* UV layers interpolation. */ | ||||
| int num_uv_layers; | int num_uv_layers; | ||||
| Show All 23 Lines | |||||
| } | } | ||||
| static void subdiv_mesh_ctx_cache_custom_data_layers(SubdivMeshContext *ctx) | static void subdiv_mesh_ctx_cache_custom_data_layers(SubdivMeshContext *ctx) | ||||
| { | { | ||||
| Mesh *subdiv_mesh = ctx->subdiv_mesh; | Mesh *subdiv_mesh = ctx->subdiv_mesh; | ||||
| ctx->subdiv_positions = subdiv_mesh->vert_positions_for_write().data(); | ctx->subdiv_positions = subdiv_mesh->vert_positions_for_write().data(); | ||||
| ctx->subdiv_edges = BKE_mesh_edges_for_write(subdiv_mesh); | ctx->subdiv_edges = BKE_mesh_edges_for_write(subdiv_mesh); | ||||
| ctx->subdiv_polys = BKE_mesh_polys_for_write(subdiv_mesh); | ctx->subdiv_polys = BKE_mesh_polys_for_write(subdiv_mesh); | ||||
| ctx->subdiv_loops = BKE_mesh_loops_for_write(subdiv_mesh); | ctx->subdiv_corner_verts = subdiv_mesh->corner_verts_for_write(); | ||||
| ctx->subdiv_corner_edges = subdiv_mesh->corner_edges_for_write(); | |||||
| /* Pointers to original indices layers. */ | /* Pointers to original indices layers. */ | ||||
| ctx->vert_origindex = static_cast<int *>( | ctx->vert_origindex = static_cast<int *>( | ||||
| CustomData_get_layer_for_write(&subdiv_mesh->vdata, CD_ORIGINDEX, subdiv_mesh->totvert)); | CustomData_get_layer_for_write(&subdiv_mesh->vdata, CD_ORIGINDEX, subdiv_mesh->totvert)); | ||||
| ctx->edge_origindex = static_cast<int *>( | ctx->edge_origindex = static_cast<int *>( | ||||
| CustomData_get_layer_for_write(&subdiv_mesh->edata, CD_ORIGINDEX, subdiv_mesh->totedge)); | CustomData_get_layer_for_write(&subdiv_mesh->edata, CD_ORIGINDEX, subdiv_mesh->totedge)); | ||||
| ctx->loop_origindex = static_cast<int *>( | ctx->loop_origindex = static_cast<int *>( | ||||
| CustomData_get_layer_for_write(&subdiv_mesh->ldata, CD_ORIGINDEX, subdiv_mesh->totloop)); | CustomData_get_layer_for_write(&subdiv_mesh->ldata, CD_ORIGINDEX, subdiv_mesh->totloop)); | ||||
| ctx->poly_origindex = static_cast<int *>( | ctx->poly_origindex = static_cast<int *>( | ||||
| Show All 26 Lines | |||||
| /** \} */ | /** \} */ | ||||
| /* -------------------------------------------------------------------- */ | /* -------------------------------------------------------------------- */ | ||||
| /** \name Loop custom data copy helpers | /** \name Loop custom data copy helpers | ||||
| * \{ */ | * \{ */ | ||||
| struct LoopsOfPtex { | struct LoopsOfPtex { | ||||
| /* First loop of the ptex, starts at ptex (0, 0) and goes in u direction. */ | /* First loop of the ptex, starts at ptex (0, 0) and goes in u direction. */ | ||||
| const MLoop *first_loop; | int first_loop; | ||||
| /* Last loop of the ptex, starts at ptex (0, 0) and goes in v direction. */ | /* Last loop of the ptex, starts at ptex (0, 0) and goes in v direction. */ | ||||
| const MLoop *last_loop; | int last_loop; | ||||
| /* For quad coarse faces only. */ | /* For quad coarse faces only. */ | ||||
| const MLoop *second_loop; | int second_loop; | ||||
| const MLoop *third_loop; | int third_loop; | ||||
| }; | }; | ||||
| static void loops_of_ptex_get(const SubdivMeshContext *ctx, | static void loops_of_ptex_get(LoopsOfPtex *loops_of_ptex, | ||||
| LoopsOfPtex *loops_of_ptex, | |||||
| const MPoly *coarse_poly, | const MPoly *coarse_poly, | ||||
| const int ptex_of_poly_index) | const int ptex_of_poly_index) | ||||
| { | { | ||||
| const MLoop *coarse_mloop = ctx->coarse_loops; | |||||
| const int first_ptex_loop_index = coarse_poly->loopstart + ptex_of_poly_index; | const int first_ptex_loop_index = coarse_poly->loopstart + ptex_of_poly_index; | ||||
| /* Loop which look in the (opposite) V direction of the current | /* Loop which look in the (opposite) V direction of the current | ||||
| * ptex face. | * ptex face. | ||||
| * | * | ||||
| * TODO(sergey): Get rid of using module on every iteration. */ | * TODO(sergey): Get rid of using module on every iteration. */ | ||||
| const int last_ptex_loop_index = coarse_poly->loopstart + | const int last_ptex_loop_index = coarse_poly->loopstart + | ||||
| (ptex_of_poly_index + coarse_poly->totloop - 1) % | (ptex_of_poly_index + coarse_poly->totloop - 1) % | ||||
| coarse_poly->totloop; | coarse_poly->totloop; | ||||
| loops_of_ptex->first_loop = &coarse_mloop[first_ptex_loop_index]; | loops_of_ptex->first_loop = first_ptex_loop_index; | ||||
| loops_of_ptex->last_loop = &coarse_mloop[last_ptex_loop_index]; | loops_of_ptex->last_loop = last_ptex_loop_index; | ||||
| if (coarse_poly->totloop == 4) { | if (coarse_poly->totloop == 4) { | ||||
| loops_of_ptex->second_loop = loops_of_ptex->first_loop + 1; | loops_of_ptex->second_loop = loops_of_ptex->first_loop + 1; | ||||
| loops_of_ptex->third_loop = loops_of_ptex->first_loop + 2; | loops_of_ptex->third_loop = loops_of_ptex->first_loop + 2; | ||||
| } | } | ||||
| else { | else { | ||||
| loops_of_ptex->second_loop = nullptr; | loops_of_ptex->second_loop = -1; | ||||
| loops_of_ptex->third_loop = nullptr; | loops_of_ptex->third_loop = -1; | ||||
| } | } | ||||
| } | } | ||||
| /** \} */ | /** \} */ | ||||
| /* -------------------------------------------------------------------- */ | /* -------------------------------------------------------------------- */ | ||||
| /** \name Vertex custom data interpolation helpers | /** \name Vertex custom data interpolation helpers | ||||
| * \{ */ | * \{ */ | ||||
| Show All 22 Lines | |||||
| int vertex_indices[4]; | int vertex_indices[4]; | ||||
| }; | }; | ||||
| static void vertex_interpolation_init(const SubdivMeshContext *ctx, | static void vertex_interpolation_init(const SubdivMeshContext *ctx, | ||||
| VerticesForInterpolation *vertex_interpolation, | VerticesForInterpolation *vertex_interpolation, | ||||
| const MPoly *coarse_poly) | const MPoly *coarse_poly) | ||||
| { | { | ||||
| const Mesh *coarse_mesh = ctx->coarse_mesh; | const Mesh *coarse_mesh = ctx->coarse_mesh; | ||||
| const MLoop *coarse_mloop = ctx->coarse_loops; | |||||
| if (coarse_poly->totloop == 4) { | if (coarse_poly->totloop == 4) { | ||||
| vertex_interpolation->vertex_data = &coarse_mesh->vdata; | vertex_interpolation->vertex_data = &coarse_mesh->vdata; | ||||
| vertex_interpolation->vertex_indices[0] = coarse_mloop[coarse_poly->loopstart + 0].v; | vertex_interpolation->vertex_indices[0] = ctx->coarse_corner_verts[coarse_poly->loopstart + 0]; | ||||
| vertex_interpolation->vertex_indices[1] = coarse_mloop[coarse_poly->loopstart + 1].v; | vertex_interpolation->vertex_indices[1] = ctx->coarse_corner_verts[coarse_poly->loopstart + 1]; | ||||
| vertex_interpolation->vertex_indices[2] = coarse_mloop[coarse_poly->loopstart + 2].v; | vertex_interpolation->vertex_indices[2] = ctx->coarse_corner_verts[coarse_poly->loopstart + 2]; | ||||
| vertex_interpolation->vertex_indices[3] = coarse_mloop[coarse_poly->loopstart + 3].v; | vertex_interpolation->vertex_indices[3] = ctx->coarse_corner_verts[coarse_poly->loopstart + 3]; | ||||
| vertex_interpolation->vertex_data_storage_allocated = false; | vertex_interpolation->vertex_data_storage_allocated = false; | ||||
| } | } | ||||
| else { | else { | ||||
| vertex_interpolation->vertex_data = &vertex_interpolation->vertex_data_storage; | vertex_interpolation->vertex_data = &vertex_interpolation->vertex_data_storage; | ||||
| /* Allocate storage for loops corresponding to ptex corners. */ | /* Allocate storage for loops corresponding to ptex corners. */ | ||||
| CustomData_copy(&ctx->coarse_mesh->vdata, | CustomData_copy(&ctx->coarse_mesh->vdata, | ||||
| &vertex_interpolation->vertex_data_storage, | &vertex_interpolation->vertex_data_storage, | ||||
| CD_MASK_EVERYTHING.vmask, | CD_MASK_EVERYTHING.vmask, | ||||
| CD_SET_DEFAULT, | CD_SET_DEFAULT, | ||||
| 4); | 4); | ||||
| /* Initialize indices. */ | /* Initialize indices. */ | ||||
| vertex_interpolation->vertex_indices[0] = 0; | vertex_interpolation->vertex_indices[0] = 0; | ||||
| vertex_interpolation->vertex_indices[1] = 1; | vertex_interpolation->vertex_indices[1] = 1; | ||||
| vertex_interpolation->vertex_indices[2] = 2; | vertex_interpolation->vertex_indices[2] = 2; | ||||
| vertex_interpolation->vertex_indices[3] = 3; | vertex_interpolation->vertex_indices[3] = 3; | ||||
| vertex_interpolation->vertex_data_storage_allocated = true; | vertex_interpolation->vertex_data_storage_allocated = true; | ||||
| /* Interpolate center of poly right away, it stays unchanged for all | /* Interpolate center of poly right away, it stays unchanged for all | ||||
| * ptex faces. */ | * ptex faces. */ | ||||
| const float weight = 1.0f / float(coarse_poly->totloop); | const float weight = 1.0f / float(coarse_poly->totloop); | ||||
| blender::Array<float, 32> weights(coarse_poly->totloop); | blender::Array<float, 32> weights(coarse_poly->totloop); | ||||
| blender::Array<int, 32> indices(coarse_poly->totloop); | blender::Array<int, 32> indices(coarse_poly->totloop); | ||||
| for (int i = 0; i < coarse_poly->totloop; i++) { | for (int i = 0; i < coarse_poly->totloop; i++) { | ||||
| weights[i] = weight; | weights[i] = weight; | ||||
| indices[i] = coarse_mloop[coarse_poly->loopstart + i].v; | indices[i] = ctx->coarse_corner_verts[coarse_poly->loopstart + i]; | ||||
| } | } | ||||
| CustomData_interp(&coarse_mesh->vdata, | CustomData_interp(&coarse_mesh->vdata, | ||||
| &vertex_interpolation->vertex_data_storage, | &vertex_interpolation->vertex_data_storage, | ||||
| indices.data(), | indices.data(), | ||||
| weights.data(), | weights.data(), | ||||
| nullptr, | nullptr, | ||||
| coarse_poly->totloop, | coarse_poly->totloop, | ||||
| 2); | 2); | ||||
| } | } | ||||
| } | } | ||||
| static void vertex_interpolation_from_corner(const SubdivMeshContext *ctx, | static void vertex_interpolation_from_corner(const SubdivMeshContext *ctx, | ||||
| VerticesForInterpolation *vertex_interpolation, | VerticesForInterpolation *vertex_interpolation, | ||||
| const MPoly *coarse_poly, | const MPoly *coarse_poly, | ||||
| const int corner) | const int corner) | ||||
| { | { | ||||
| if (coarse_poly->totloop == 4) { | if (coarse_poly->totloop == 4) { | ||||
| /* Nothing to do, all indices and data is already assigned. */ | /* Nothing to do, all indices and data is already assigned. */ | ||||
| } | } | ||||
| else { | else { | ||||
| const CustomData *vertex_data = &ctx->coarse_mesh->vdata; | const CustomData *vertex_data = &ctx->coarse_mesh->vdata; | ||||
| const MLoop *coarse_mloop = ctx->coarse_loops; | |||||
| LoopsOfPtex loops_of_ptex; | LoopsOfPtex loops_of_ptex; | ||||
| loops_of_ptex_get(ctx, &loops_of_ptex, coarse_poly, corner); | loops_of_ptex_get(&loops_of_ptex, coarse_poly, corner); | ||||
| /* Ptex face corner corresponds to a poly loop with same index. */ | /* Ptex face corner corresponds to a poly loop with same index. */ | ||||
| CustomData_copy_data(vertex_data, | CustomData_copy_data(vertex_data, | ||||
| &vertex_interpolation->vertex_data_storage, | &vertex_interpolation->vertex_data_storage, | ||||
| coarse_mloop[coarse_poly->loopstart + corner].v, | ctx->coarse_corner_verts[coarse_poly->loopstart + corner], | ||||
| 0, | 0, | ||||
| 1); | 1); | ||||
| /* Interpolate remaining ptex face corners, which hits loops | /* Interpolate remaining ptex face corners, which hits loops | ||||
| * middle points. | * middle points. | ||||
| * | * | ||||
| * TODO(sergey): Re-use one of interpolation results from previous | * TODO(sergey): Re-use one of interpolation results from previous | ||||
| * iteration. */ | * iteration. */ | ||||
| const float weights[2] = {0.5f, 0.5f}; | const float weights[2] = {0.5f, 0.5f}; | ||||
| const int first_loop_index = loops_of_ptex.first_loop - coarse_mloop; | const int first_loop_index = loops_of_ptex.first_loop; | ||||
| const int last_loop_index = loops_of_ptex.last_loop - coarse_mloop; | const int last_loop_index = loops_of_ptex.last_loop; | ||||
| const int first_indices[2] = { | const int first_indices[2] = { | ||||
| int(coarse_mloop[first_loop_index].v), | ctx->coarse_corner_verts[first_loop_index], | ||||
| int(coarse_mloop[coarse_poly->loopstart + | ctx->coarse_corner_verts[coarse_poly->loopstart + | ||||
| (first_loop_index - coarse_poly->loopstart + 1) % coarse_poly->totloop] | (first_loop_index - coarse_poly->loopstart + 1) % | ||||
| .v)}; | coarse_poly->totloop]}; | ||||
| const int last_indices[2] = { | const int last_indices[2] = {ctx->coarse_corner_verts[first_loop_index], | ||||
| int(coarse_mloop[first_loop_index].v), | ctx->coarse_corner_verts[last_loop_index]}; | ||||
| int(coarse_mloop[last_loop_index].v), | |||||
| }; | |||||
| CustomData_interp(vertex_data, | CustomData_interp(vertex_data, | ||||
| &vertex_interpolation->vertex_data_storage, | &vertex_interpolation->vertex_data_storage, | ||||
| first_indices, | first_indices, | ||||
| weights, | weights, | ||||
| nullptr, | nullptr, | ||||
| 2, | 2, | ||||
| 1); | 1); | ||||
| CustomData_interp(vertex_data, | CustomData_interp(vertex_data, | ||||
| ▲ Show 20 Lines • Show All 91 Lines • ▼ Show 20 Lines | |||||
| const MPoly *coarse_poly, | const MPoly *coarse_poly, | ||||
| const int corner) | const int corner) | ||||
| { | { | ||||
| if (coarse_poly->totloop == 4) { | if (coarse_poly->totloop == 4) { | ||||
| /* Nothing to do, all indices and data is already assigned. */ | /* Nothing to do, all indices and data is already assigned. */ | ||||
| } | } | ||||
| else { | else { | ||||
| const CustomData *loop_data = &ctx->coarse_mesh->ldata; | const CustomData *loop_data = &ctx->coarse_mesh->ldata; | ||||
| const MLoop *coarse_mloop = ctx->coarse_loops; | |||||
| LoopsOfPtex loops_of_ptex; | LoopsOfPtex loops_of_ptex; | ||||
| loops_of_ptex_get(ctx, &loops_of_ptex, coarse_poly, corner); | loops_of_ptex_get(&loops_of_ptex, coarse_poly, corner); | ||||
| /* Ptex face corner corresponds to a poly loop with same index. */ | /* Ptex face corner corresponds to a poly loop with same index. */ | ||||
| CustomData_free_elem(&loop_interpolation->loop_data_storage, 0, 1); | CustomData_free_elem(&loop_interpolation->loop_data_storage, 0, 1); | ||||
| CustomData_copy_data( | CustomData_copy_data( | ||||
| loop_data, &loop_interpolation->loop_data_storage, coarse_poly->loopstart + corner, 0, 1); | loop_data, &loop_interpolation->loop_data_storage, coarse_poly->loopstart + corner, 0, 1); | ||||
| /* Interpolate remaining ptex face corners, which hits loops | /* Interpolate remaining ptex face corners, which hits loops | ||||
| * middle points. | * middle points. | ||||
| * | * | ||||
| * TODO(sergey): Re-use one of interpolation results from previous | * TODO(sergey): Re-use one of interpolation results from previous | ||||
| * iteration. */ | * iteration. */ | ||||
| const float weights[2] = {0.5f, 0.5f}; | const float weights[2] = {0.5f, 0.5f}; | ||||
| const int base_loop_index = coarse_poly->loopstart; | const int base_loop_index = coarse_poly->loopstart; | ||||
| const int first_loop_index = loops_of_ptex.first_loop - coarse_mloop; | const int first_loop_index = loops_of_ptex.first_loop; | ||||
| const int second_loop_index = base_loop_index + | const int second_loop_index = base_loop_index + | ||||
| (first_loop_index - base_loop_index + 1) % coarse_poly->totloop; | (first_loop_index - base_loop_index + 1) % coarse_poly->totloop; | ||||
| const int first_indices[2] = {first_loop_index, second_loop_index}; | const int first_indices[2] = {first_loop_index, second_loop_index}; | ||||
| const int last_indices[2] = { | const int last_indices[2] = {loops_of_ptex.last_loop, loops_of_ptex.first_loop}; | ||||
| int(loops_of_ptex.last_loop - coarse_mloop), | |||||
| int(loops_of_ptex.first_loop - coarse_mloop), | |||||
| }; | |||||
| CustomData_interp( | CustomData_interp( | ||||
| loop_data, &loop_interpolation->loop_data_storage, first_indices, weights, nullptr, 2, 1); | loop_data, &loop_interpolation->loop_data_storage, first_indices, weights, nullptr, 2, 1); | ||||
| CustomData_interp( | CustomData_interp( | ||||
| loop_data, &loop_interpolation->loop_data_storage, last_indices, weights, nullptr, 2, 3); | loop_data, &loop_interpolation->loop_data_storage, last_indices, weights, nullptr, 2, 3); | ||||
| } | } | ||||
| } | } | ||||
| static void loop_interpolation_end(LoopsForInterpolation *loop_interpolation) | static void loop_interpolation_end(LoopsForInterpolation *loop_interpolation) | ||||
| ▲ Show 20 Lines • Show All 184 Lines • ▼ Show 20 Lines | |||||
| /** \} */ | /** \} */ | ||||
| /* -------------------------------------------------------------------- */ | /* -------------------------------------------------------------------- */ | ||||
| /** \name Loops creation/interpolation | /** \name Loops creation/interpolation | ||||
| * \{ */ | * \{ */ | ||||
| static void subdiv_interpolate_loop_data(const SubdivMeshContext *ctx, | static void subdiv_interpolate_loop_data(const SubdivMeshContext *ctx, | ||||
| MLoop *subdiv_loop, | const int subdiv_loop_index, | ||||
| const LoopsForInterpolation *loop_interpolation, | const LoopsForInterpolation *loop_interpolation, | ||||
| const float u, | const float u, | ||||
| const float v) | const float v) | ||||
| { | { | ||||
| const int subdiv_loop_index = subdiv_loop - ctx->subdiv_loops; | |||||
| const float weights[4] = {(1.0f - u) * (1.0f - v), u * (1.0f - v), u * v, (1.0f - u) * v}; | const float weights[4] = {(1.0f - u) * (1.0f - v), u * (1.0f - v), u * v, (1.0f - u) * v}; | ||||
| CustomData_interp(loop_interpolation->loop_data, | CustomData_interp(loop_interpolation->loop_data, | ||||
| &ctx->subdiv_mesh->ldata, | &ctx->subdiv_mesh->ldata, | ||||
| loop_interpolation->loop_indices, | loop_interpolation->loop_indices, | ||||
| weights, | weights, | ||||
| nullptr, | nullptr, | ||||
| 4, | 4, | ||||
| subdiv_loop_index); | subdiv_loop_index); | ||||
| /* TODO(sergey): Set ORIGINDEX. */ | /* TODO(sergey): Set ORIGINDEX. */ | ||||
| } | } | ||||
| static void subdiv_eval_uv_layer(SubdivMeshContext *ctx, | static void subdiv_eval_uv_layer(SubdivMeshContext *ctx, | ||||
| MLoop *subdiv_loop, | const int corner_index, | ||||
| const int ptex_face_index, | const int ptex_face_index, | ||||
| const float u, | const float u, | ||||
| const float v) | const float v) | ||||
| { | { | ||||
| if (ctx->num_uv_layers == 0) { | if (ctx->num_uv_layers == 0) { | ||||
| return; | return; | ||||
| } | } | ||||
| Subdiv *subdiv = ctx->subdiv; | Subdiv *subdiv = ctx->subdiv; | ||||
| const int mloop_index = subdiv_loop - ctx->subdiv_loops; | |||||
| for (int layer_index = 0; layer_index < ctx->num_uv_layers; layer_index++) { | for (int layer_index = 0; layer_index < ctx->num_uv_layers; layer_index++) { | ||||
| BKE_subdiv_eval_face_varying( | BKE_subdiv_eval_face_varying( | ||||
| subdiv, layer_index, ptex_face_index, u, v, ctx->uv_layers[layer_index][mloop_index]); | subdiv, layer_index, ptex_face_index, u, v, ctx->uv_layers[layer_index][corner_index]); | ||||
| } | } | ||||
| } | } | ||||
| static void subdiv_mesh_ensure_loop_interpolation(SubdivMeshContext *ctx, | static void subdiv_mesh_ensure_loop_interpolation(SubdivMeshContext *ctx, | ||||
| SubdivMeshTLS *tls, | SubdivMeshTLS *tls, | ||||
| const MPoly *coarse_poly, | const MPoly *coarse_poly, | ||||
| const int coarse_corner) | const int coarse_corner) | ||||
| { | { | ||||
| Show All 31 Lines | |||||
| const int subdiv_loop_index, | const int subdiv_loop_index, | ||||
| const int subdiv_vertex_index, | const int subdiv_vertex_index, | ||||
| const int subdiv_edge_index) | const int subdiv_edge_index) | ||||
| { | { | ||||
| SubdivMeshContext *ctx = static_cast<SubdivMeshContext *>(foreach_context->user_data); | SubdivMeshContext *ctx = static_cast<SubdivMeshContext *>(foreach_context->user_data); | ||||
| SubdivMeshTLS *tls = static_cast<SubdivMeshTLS *>(tls_v); | SubdivMeshTLS *tls = static_cast<SubdivMeshTLS *>(tls_v); | ||||
| const MPoly *coarse_mpoly = ctx->coarse_polys; | const MPoly *coarse_mpoly = ctx->coarse_polys; | ||||
| const MPoly *coarse_poly = &coarse_mpoly[coarse_poly_index]; | const MPoly *coarse_poly = &coarse_mpoly[coarse_poly_index]; | ||||
| MLoop *subdiv_loop = &ctx->subdiv_loops[subdiv_loop_index]; | |||||
| subdiv_mesh_ensure_loop_interpolation(ctx, tls, coarse_poly, coarse_corner); | subdiv_mesh_ensure_loop_interpolation(ctx, tls, coarse_poly, coarse_corner); | ||||
| subdiv_interpolate_loop_data(ctx, subdiv_loop, &tls->loop_interpolation, u, v); | subdiv_interpolate_loop_data(ctx, subdiv_loop_index, &tls->loop_interpolation, u, v); | ||||
| subdiv_eval_uv_layer(ctx, subdiv_loop, ptex_face_index, u, v); | subdiv_eval_uv_layer(ctx, subdiv_loop_index, ptex_face_index, u, v); | ||||
| subdiv_loop->v = subdiv_vertex_index; | |||||
| subdiv_loop->e = subdiv_edge_index; | ctx->subdiv_corner_verts[subdiv_loop_index] = subdiv_vertex_index; | ||||
| ctx->subdiv_corner_edges[subdiv_loop_index] = subdiv_edge_index; | |||||
| } | } | ||||
| /** \} */ | /** \} */ | ||||
| /* -------------------------------------------------------------------- */ | /* -------------------------------------------------------------------- */ | ||||
| /** \name Polygons subdivision process | /** \name Polygons subdivision process | ||||
| * \{ */ | * \{ */ | ||||
| ▲ Show 20 Lines • Show All 184 Lines • ▼ Show 20 Lines | |||||
| /* Initialize subdivision mesh creation context. */ | /* Initialize subdivision mesh creation context. */ | ||||
| SubdivMeshContext subdiv_context{}; | SubdivMeshContext subdiv_context{}; | ||||
| subdiv_context.settings = settings; | subdiv_context.settings = settings; | ||||
| subdiv_context.coarse_mesh = coarse_mesh; | subdiv_context.coarse_mesh = coarse_mesh; | ||||
| subdiv_context.coarse_positions = BKE_mesh_vert_positions(coarse_mesh); | subdiv_context.coarse_positions = BKE_mesh_vert_positions(coarse_mesh); | ||||
| subdiv_context.coarse_edges = BKE_mesh_edges(coarse_mesh); | subdiv_context.coarse_edges = BKE_mesh_edges(coarse_mesh); | ||||
| subdiv_context.coarse_polys = BKE_mesh_polys(coarse_mesh); | subdiv_context.coarse_polys = BKE_mesh_polys(coarse_mesh); | ||||
| subdiv_context.coarse_loops = BKE_mesh_loops(coarse_mesh); | subdiv_context.coarse_corner_verts = coarse_mesh->corner_verts(); | ||||
| subdiv_context.subdiv = subdiv; | subdiv_context.subdiv = subdiv; | ||||
| subdiv_context.have_displacement = (subdiv->displacement_evaluator != nullptr); | subdiv_context.have_displacement = (subdiv->displacement_evaluator != nullptr); | ||||
| /* Multi-threaded traversal/evaluation. */ | /* Multi-threaded traversal/evaluation. */ | ||||
| BKE_subdiv_stats_begin(&subdiv->stats, SUBDIV_STATS_SUBDIV_TO_MESH_GEOMETRY); | BKE_subdiv_stats_begin(&subdiv->stats, SUBDIV_STATS_SUBDIV_TO_MESH_GEOMETRY); | ||||
| SubdivForeachContext foreach_context; | SubdivForeachContext foreach_context; | ||||
| setup_foreach_callbacks(&subdiv_context, &foreach_context); | setup_foreach_callbacks(&subdiv_context, &foreach_context); | ||||
| SubdivMeshTLS tls{}; | SubdivMeshTLS tls{}; | ||||
| Show All 19 Lines | |||||