Changeset View
Changeset View
Standalone View
Standalone View
source/blender/blenkernel/intern/subdiv_eval.c
| Show First 20 Lines • Show All 42 Lines • ▼ Show 20 Lines | |||||
| } | } | ||||
| /* -------------------------------------------------------------------- | /* -------------------------------------------------------------------- | ||||
| * Main subdivision evaluation. | * Main subdivision evaluation. | ||||
| */ | */ | ||||
| bool BKE_subdiv_eval_begin(Subdiv *subdiv, | bool BKE_subdiv_eval_begin(Subdiv *subdiv, | ||||
| eSubdivEvaluatorType evaluator_type, | eSubdivEvaluatorType evaluator_type, | ||||
| OpenSubdiv_EvaluatorCache *evaluator_cache) | OpenSubdiv_EvaluatorCache *evaluator_cache, | ||||
| const OpenSubdiv_EvaluatorSettings *settings) | |||||
| { | { | ||||
| BKE_subdiv_stats_reset(&subdiv->stats, SUBDIV_STATS_EVALUATOR_CREATE); | BKE_subdiv_stats_reset(&subdiv->stats, SUBDIV_STATS_EVALUATOR_CREATE); | ||||
| if (subdiv->topology_refiner == NULL) { | if (subdiv->topology_refiner == NULL) { | ||||
| /* Happens on input mesh with just loose geometry, | /* Happens on input mesh with just loose geometry, | ||||
| * or when OpenSubdiv is disabled */ | * or when OpenSubdiv is disabled */ | ||||
| return false; | return false; | ||||
| } | } | ||||
| if (subdiv->evaluator == NULL) { | if (subdiv->evaluator == NULL) { | ||||
| eOpenSubdivEvaluator opensubdiv_evaluator_type = | eOpenSubdivEvaluator opensubdiv_evaluator_type = | ||||
| opensubdiv_evalutor_from_subdiv_evaluator_type(evaluator_type); | opensubdiv_evalutor_from_subdiv_evaluator_type(evaluator_type); | ||||
| BKE_subdiv_stats_begin(&subdiv->stats, SUBDIV_STATS_EVALUATOR_CREATE); | BKE_subdiv_stats_begin(&subdiv->stats, SUBDIV_STATS_EVALUATOR_CREATE); | ||||
| subdiv->evaluator = openSubdiv_createEvaluatorFromTopologyRefiner( | subdiv->evaluator = openSubdiv_createEvaluatorFromTopologyRefiner( | ||||
| subdiv->topology_refiner, opensubdiv_evaluator_type, evaluator_cache); | subdiv->topology_refiner, opensubdiv_evaluator_type, evaluator_cache, settings); | ||||
| BKE_subdiv_stats_end(&subdiv->stats, SUBDIV_STATS_EVALUATOR_CREATE); | BKE_subdiv_stats_end(&subdiv->stats, SUBDIV_STATS_EVALUATOR_CREATE); | ||||
| if (subdiv->evaluator == NULL) { | if (subdiv->evaluator == NULL) { | ||||
| return false; | return false; | ||||
| } | } | ||||
| } | } | ||||
| else { | else { | ||||
| /* TODO(sergey): Check for topology change. */ | /* TODO(sergey): Check for topology change. */ | ||||
| } | } | ||||
| ▲ Show 20 Lines • Show All 105 Lines • ▼ Show 20 Lines | static void set_face_varying_data_from_uv(Subdiv *subdiv, | ||||
| BLI_task_parallel_range( | BLI_task_parallel_range( | ||||
| 0, num_faces, &ctx, set_face_varying_data_from_uv_task, ¶llel_range_settings); | 0, num_faces, &ctx, set_face_varying_data_from_uv_task, ¶llel_range_settings); | ||||
| evaluator->setFaceVaryingData(evaluator, layer_index, &buffer[0][0], 0, num_fvar_values); | evaluator->setFaceVaryingData(evaluator, layer_index, &buffer[0][0], 0, num_fvar_values); | ||||
| MEM_freeN(buffer); | MEM_freeN(buffer); | ||||
| } | } | ||||
| static void set_vertex_data_from_orco(Subdiv *subdiv, const Mesh *mesh) | |||||
| { | |||||
| const float(*orco)[3] = CustomData_get_layer(&mesh->vdata, CD_ORCO); | |||||
| const float(*cloth_orco)[3] = CustomData_get_layer(&mesh->vdata, CD_CLOTH_ORCO); | |||||
| if (orco || cloth_orco) { | |||||
| OpenSubdiv_TopologyRefiner *topology_refiner = subdiv->topology_refiner; | |||||
| OpenSubdiv_Evaluator *evaluator = subdiv->evaluator; | |||||
| const int num_verts = topology_refiner->getNumVertices(topology_refiner); | |||||
| if (orco && cloth_orco) { | |||||
| /* Set one by one if have both. */ | |||||
| for (int i = 0; i < num_verts; i++) { | |||||
| float data[6]; | |||||
| copy_v3_v3(data, orco[i]); | |||||
| copy_v3_v3(data + 3, cloth_orco[i]); | |||||
| evaluator->setVertexData(evaluator, data, i, 1); | |||||
| } | |||||
| } | |||||
| else { | |||||
| /* Faster single call if we have either. */ | |||||
| if (orco) { | |||||
| evaluator->setVertexData(evaluator, orco[0], 0, num_verts); | |||||
| } | |||||
| else if (cloth_orco) { | |||||
| evaluator->setVertexData(evaluator, cloth_orco[0], 0, num_verts); | |||||
| } | |||||
| } | |||||
| } | |||||
| } | |||||
| static void get_mesh_evaluator_settings(OpenSubdiv_EvaluatorSettings *settings, const Mesh *mesh) | |||||
| { | |||||
| settings->num_vertex_data = (CustomData_has_layer(&mesh->vdata, CD_ORCO) ? 3 : 0) + | |||||
| (CustomData_has_layer(&mesh->vdata, CD_CLOTH_ORCO) ? 3 : 0); | |||||
| } | |||||
| bool BKE_subdiv_eval_begin_from_mesh(Subdiv *subdiv, | bool BKE_subdiv_eval_begin_from_mesh(Subdiv *subdiv, | ||||
| const Mesh *mesh, | const Mesh *mesh, | ||||
| const float (*coarse_vertex_cos)[3], | const float (*coarse_vertex_cos)[3], | ||||
| eSubdivEvaluatorType evaluator_type, | eSubdivEvaluatorType evaluator_type, | ||||
| OpenSubdiv_EvaluatorCache *evaluator_cache) | OpenSubdiv_EvaluatorCache *evaluator_cache) | ||||
| { | { | ||||
| if (!BKE_subdiv_eval_begin(subdiv, evaluator_type, evaluator_cache)) { | OpenSubdiv_EvaluatorSettings settings = {0}; | ||||
| get_mesh_evaluator_settings(&settings, mesh); | |||||
| if (!BKE_subdiv_eval_begin(subdiv, evaluator_type, evaluator_cache, &settings)) { | |||||
| return false; | return false; | ||||
| } | } | ||||
| return BKE_subdiv_eval_refine_from_mesh(subdiv, mesh, coarse_vertex_cos); | return BKE_subdiv_eval_refine_from_mesh(subdiv, mesh, coarse_vertex_cos); | ||||
| } | } | ||||
| bool BKE_subdiv_eval_refine_from_mesh(Subdiv *subdiv, | bool BKE_subdiv_eval_refine_from_mesh(Subdiv *subdiv, | ||||
| const Mesh *mesh, | const Mesh *mesh, | ||||
| const float (*coarse_vertex_cos)[3]) | const float (*coarse_vertex_cos)[3]) | ||||
| { | { | ||||
| 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-varyign data to UV maps. */ | /* Set face-varyign 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_MLOOPUV); | ||||
| 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 MLoopUV *mloopuv = CustomData_get_layer_n(&mesh->ldata, CD_MLOOPUV, 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_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); | ||||
| return true; | return true; | ||||
| } | } | ||||
| void BKE_subdiv_eval_init_displacement(Subdiv *subdiv) | void BKE_subdiv_eval_init_displacement(Subdiv *subdiv) | ||||
| ▲ Show 20 Lines • Show All 59 Lines • ▼ Show 20 Lines | void BKE_subdiv_eval_limit_point_and_normal(Subdiv *subdiv, | ||||
| float r_N[3]) | float r_N[3]) | ||||
| { | { | ||||
| float dPdu[3], dPdv[3]; | float dPdu[3], dPdv[3]; | ||||
| BKE_subdiv_eval_limit_point_and_derivatives(subdiv, ptex_face_index, u, v, r_P, dPdu, dPdv); | BKE_subdiv_eval_limit_point_and_derivatives(subdiv, ptex_face_index, u, v, r_P, dPdu, dPdv); | ||||
| cross_v3_v3v3(r_N, dPdu, dPdv); | cross_v3_v3v3(r_N, dPdu, dPdv); | ||||
| normalize_v3(r_N); | normalize_v3(r_N); | ||||
| } | } | ||||
| void BKE_subdiv_eval_vertex_data( | |||||
| Subdiv *subdiv, const int ptex_face_index, const float u, const float v, float r_vertex_data[]) | |||||
| { | |||||
| subdiv->evaluator->evaluateVertexData(subdiv->evaluator, ptex_face_index, u, v, r_vertex_data); | |||||
| } | |||||
| void BKE_subdiv_eval_face_varying(Subdiv *subdiv, | void BKE_subdiv_eval_face_varying(Subdiv *subdiv, | ||||
| const int face_varying_channel, | const int face_varying_channel, | ||||
| const int ptex_face_index, | const int ptex_face_index, | ||||
| const float u, | const float u, | ||||
| const float v, | const float v, | ||||
| float r_face_varying[2]) | float r_face_varying[2]) | ||||
| { | { | ||||
| subdiv->evaluator->evaluateFaceVarying( | subdiv->evaluator->evaluateFaceVarying( | ||||
| Show All 32 Lines | |||||