Changeset View
Changeset View
Standalone View
Standalone View
source/blender/blenkernel/intern/subdiv_eval.c
| Show First 20 Lines • Show All 120 Lines • ▼ Show 20 Lines | static void set_coarse_positions(Subdiv *subdiv, | ||||
| MEM_freeN(buffer); | MEM_freeN(buffer); | ||||
| } | } | ||||
| /* Context which is used to fill face varying data in parallel. */ | /* Context which is used to fill face varying data in parallel. */ | ||||
| typedef struct FaceVaryingDataFromUVContext { | typedef struct FaceVaryingDataFromUVContext { | ||||
| OpenSubdiv_TopologyRefiner *topology_refiner; | OpenSubdiv_TopologyRefiner *topology_refiner; | ||||
| const Mesh *mesh; | const Mesh *mesh; | ||||
| const MPoly *polys; | const MPoly *polys; | ||||
| const MLoopUV *mloopuv; | const float (*mloopuv)[2]; | ||||
| float (*buffer)[2]; | float (*buffer)[2]; | ||||
| int layer_index; | int layer_index; | ||||
| } FaceVaryingDataFromUVContext; | } FaceVaryingDataFromUVContext; | ||||
| static void set_face_varying_data_from_uv_task(void *__restrict userdata, | static void set_face_varying_data_from_uv_task(void *__restrict userdata, | ||||
| const int face_index, | const int face_index, | ||||
| const TaskParallelTLS *__restrict UNUSED(tls)) | const TaskParallelTLS *__restrict UNUSED(tls)) | ||||
| { | { | ||||
| FaceVaryingDataFromUVContext *ctx = userdata; | FaceVaryingDataFromUVContext *ctx = userdata; | ||||
| OpenSubdiv_TopologyRefiner *topology_refiner = ctx->topology_refiner; | OpenSubdiv_TopologyRefiner *topology_refiner = ctx->topology_refiner; | ||||
| const int layer_index = ctx->layer_index; | const int layer_index = ctx->layer_index; | ||||
| const MPoly *mpoly = &ctx->polys[face_index]; | const MPoly *mpoly = &ctx->polys[face_index]; | ||||
| const MLoopUV *mluv = &ctx->mloopuv[mpoly->loopstart]; | const float(*mluv)[2] = &ctx->mloopuv[mpoly->loopstart]; | ||||
| /* TODO(sergey): OpenSubdiv's C-API converter can change winding of | /* TODO(sergey): OpenSubdiv's C-API converter can change winding of | ||||
| * loops of a face, need to watch for that, to prevent wrong UVs assigned. | * loops of a face, need to watch for that, to prevent wrong UVs assigned. | ||||
| */ | */ | ||||
| const int num_face_vertices = topology_refiner->getNumFaceVertices(topology_refiner, face_index); | const int num_face_vertices = topology_refiner->getNumFaceVertices(topology_refiner, face_index); | ||||
| const int *uv_indices = topology_refiner->getFaceFVarValueIndices( | const int *uv_indices = topology_refiner->getFaceFVarValueIndices( | ||||
| topology_refiner, face_index, layer_index); | topology_refiner, face_index, layer_index); | ||||
| for (int vertex_index = 0; vertex_index < num_face_vertices; vertex_index++, mluv++) { | for (int vertex_index = 0; vertex_index < num_face_vertices; vertex_index++, mluv++) { | ||||
| copy_v2_v2(ctx->buffer[uv_indices[vertex_index]], mluv->uv); | copy_v2_v2(ctx->buffer[uv_indices[vertex_index]], *mluv); | ||||
| } | } | ||||
| } | } | ||||
| static void set_face_varying_data_from_uv(Subdiv *subdiv, | static void set_face_varying_data_from_uv(Subdiv *subdiv, | ||||
| const Mesh *mesh, | const Mesh *mesh, | ||||
| const MLoopUV *mloopuv, | const float (*mloopuv)[2], | ||||
| const int layer_index) | const int layer_index) | ||||
| { | { | ||||
| OpenSubdiv_TopologyRefiner *topology_refiner = subdiv->topology_refiner; | OpenSubdiv_TopologyRefiner *topology_refiner = subdiv->topology_refiner; | ||||
| OpenSubdiv_Evaluator *evaluator = subdiv->evaluator; | OpenSubdiv_Evaluator *evaluator = subdiv->evaluator; | ||||
| const int num_faces = topology_refiner->getNumFaces(topology_refiner); | const int num_faces = topology_refiner->getNumFaces(topology_refiner); | ||||
| const MLoopUV *mluv = mloopuv; | const float(*mluv)[2] = mloopuv; | ||||
| const int num_fvar_values = topology_refiner->getNumFVarValues(topology_refiner, layer_index); | const int num_fvar_values = topology_refiner->getNumFVarValues(topology_refiner, layer_index); | ||||
| /* Use a temporary buffer so we do not upload UVs one at a time to the GPU. */ | /* Use a temporary buffer so we do not upload UVs one at a time to the GPU. */ | ||||
| float(*buffer)[2] = MEM_mallocN(sizeof(float[2]) * num_fvar_values, "temp UV storage"); | float(*buffer)[2] = MEM_mallocN(sizeof(float[2]) * num_fvar_values, "temp UV storage"); | ||||
| FaceVaryingDataFromUVContext ctx; | FaceVaryingDataFromUVContext ctx; | ||||
| ctx.topology_refiner = topology_refiner; | ctx.topology_refiner = topology_refiner; | ||||
| ctx.layer_index = layer_index; | ctx.layer_index = layer_index; | ||||
| ▲ Show 20 Lines • Show All 72 Lines • ▼ Show 20 Lines | bool BKE_subdiv_eval_refine_from_mesh(Subdiv *subdiv, | ||||
| if (subdiv->evaluator == NULL) { | if (subdiv->evaluator == NULL) { | ||||
| /* NOTE: This situation is supposed to be handled by begin(). */ | /* NOTE: This situation is supposed to be handled by begin(). */ | ||||
| BLI_assert_msg(0, "Is not supposed to happen"); | BLI_assert_msg(0, "Is not supposed to happen"); | ||||
| return false; | return false; | ||||
| } | } | ||||
| /* Set coordinates of base mesh vertices. */ | /* Set coordinates of base mesh vertices. */ | ||||
| set_coarse_positions(subdiv, mesh, coarse_vertex_cos); | set_coarse_positions(subdiv, mesh, coarse_vertex_cos); | ||||
| /* Set face-varying data to UV maps. */ | /* Set face-varying data to UV maps. */ | ||||
| const int num_uv_layers = CustomData_number_of_layers(&mesh->ldata, CD_MLOOPUV); | const int num_uv_layers = CustomData_number_of_layers(&mesh->ldata, CD_PROP_FLOAT2); | ||||
| for (int layer_index = 0; layer_index < num_uv_layers; layer_index++) { | for (int layer_index = 0; layer_index < num_uv_layers; layer_index++) { | ||||
| const MLoopUV *mloopuv = CustomData_get_layer_n(&mesh->ldata, CD_MLOOPUV, layer_index); | const float(*mloopuv)[2] = CustomData_get_layer_n(&mesh->ldata, CD_PROP_FLOAT2, layer_index); | ||||
| set_face_varying_data_from_uv(subdiv, mesh, mloopuv, layer_index); | set_face_varying_data_from_uv(subdiv, mesh, mloopuv, layer_index); | ||||
| } | } | ||||
| /* Set vertex data to orco. */ | /* Set vertex data to orco. */ | ||||
| set_vertex_data_from_orco(subdiv, mesh); | set_vertex_data_from_orco(subdiv, mesh); | ||||
| /* Update evaluator to the new coarse geometry. */ | /* Update evaluator to the new coarse geometry. */ | ||||
| BKE_subdiv_stats_begin(&subdiv->stats, SUBDIV_STATS_EVALUATOR_REFINE); | BKE_subdiv_stats_begin(&subdiv->stats, SUBDIV_STATS_EVALUATOR_REFINE); | ||||
| subdiv->evaluator->refine(subdiv->evaluator); | subdiv->evaluator->refine(subdiv->evaluator); | ||||
| BKE_subdiv_stats_end(&subdiv->stats, SUBDIV_STATS_EVALUATOR_REFINE); | BKE_subdiv_stats_end(&subdiv->stats, SUBDIV_STATS_EVALUATOR_REFINE); | ||||
| ▲ Show 20 Lines • Show All 117 Lines • Show Last 20 Lines | |||||