void GeometryExporter::create_normals(std::vector<Normal> &normals, std::vector<BCPolygonNormalsIndices> &polygons_normals, Mesh *me) { std::map<Normal, unsigned int> shared_normal_indices; int last_normal_index = -1; MVert *verts = me->mvert; MLoop *mloops = me->mloop; float(*lnors)[3]; BKE_mesh_calc_normals_split(me); if (CustomData_has_layer(&me->ldata, CD_NORMAL)) { lnors = (float(*)[3])CustomData_get_layer(&me->ldata, CD_NORMAL); } for (int poly_index = 0; poly_index < me->totpoly; poly_index++) { MPoly *mpoly = &me->mpoly[poly_index]; if (!(mpoly->flag & ME_SMOOTH)) { // For flat faces use face normal as vertex normal: float vector[3]; BKE_mesh_calc_poly_normal(mpoly, mloops+mpoly->loopstart, verts, vector); Normal n = { vector[0], vector[1], vector[2] }; normals.push_back(n); last_normal_index++; } MLoop *mloop = mloops + mpoly->loopstart; BCPolygonNormalsIndices poly_indices; for (int loop_index = 0; loop_index < mpoly->totloop; loop_index++) { unsigned int loop_idx = mpoly->loopstart + loop_index; if (mpoly->flag & ME_SMOOTH) { float normalized[3]; normalize_v3_v3(normalized, lnors[loop_idx]); Normal n = { normalized[0], normalized[1], normalized[2] }; if (shared_normal_indices.find(n) != shared_normal_indices.end()) { poly_indices.add_index(shared_normal_indices[n]); } else { last_normal_index++; poly_indices.add_index(last_normal_index); shared_normal_indices[n] = last_normal_index; normals.push_back(n); } } else { poly_indices.add_index(last_normal_index); } } polygons_normals.push_back(poly_indices); } }
static void rna_Mesh_calc_tangents(Mesh *mesh, ReportList *reports, const char *uvmap) { float (*r_looptangents)[4]; if (CustomData_has_layer(&mesh->ldata, CD_MLOOPTANGENT)) { r_looptangents = CustomData_get_layer(&mesh->ldata, CD_MLOOPTANGENT); memset(r_looptangents, 0, sizeof(float[4]) * mesh->totloop); } else { r_looptangents = CustomData_add_layer(&mesh->ldata, CD_MLOOPTANGENT, CD_CALLOC, NULL, mesh->totloop); CustomData_set_layer_flag(&mesh->ldata, CD_MLOOPTANGENT, CD_FLAG_TEMPORARY); } /* Compute loop normals if needed. */ if (!CustomData_has_layer(&mesh->ldata, CD_NORMAL)) { BKE_mesh_calc_normals_split(mesh); } BKE_mesh_loop_tangents(mesh, uvmap, r_looptangents, reports); }