Changeset View
Changeset View
Standalone View
Standalone View
source/blender/blenkernel/intern/mesh.c
| Show First 20 Lines • Show All 2,118 Lines • ▼ Show 20 Lines | else if (msel_index != me->totselect - 1) { | ||||
| /* move to the end */ | /* move to the end */ | ||||
| SWAP(MSelect, me->mselect[msel_index], me->mselect[me->totselect - 1]); | SWAP(MSelect, me->mselect[msel_index], me->mselect[me->totselect - 1]); | ||||
| } | } | ||||
| BLI_assert((me->mselect[me->totselect - 1].index == index) && | BLI_assert((me->mselect[me->totselect - 1].index == index) && | ||||
| (me->mselect[me->totselect - 1].type == type)); | (me->mselect[me->totselect - 1].type == type)); | ||||
| } | } | ||||
| void BKE_mesh_calc_normals_split(Mesh *mesh) | |||||
| { | |||||
| float (*r_loopnors)[3]; | |||||
| float (*polynors)[3]; | |||||
| short (*clnors)[2] = NULL; | |||||
| bool free_polynors = false; | |||||
| if (CustomData_has_layer(&mesh->ldata, CD_NORMAL)) { | |||||
| r_loopnors = CustomData_get_layer(&mesh->ldata, CD_NORMAL); | |||||
| memset(r_loopnors, 0, sizeof(float[3]) * mesh->totloop); | |||||
| } | |||||
| else { | |||||
| r_loopnors = CustomData_add_layer(&mesh->ldata, CD_NORMAL, CD_CALLOC, NULL, mesh->totloop); | |||||
| CustomData_set_layer_flag(&mesh->ldata, CD_NORMAL, CD_FLAG_TEMPORARY); | |||||
| } | |||||
| /* may be NULL */ | |||||
| clnors = CustomData_get_layer(&mesh->ldata, CD_CUSTOMLOOPNORMAL); | |||||
| if (CustomData_has_layer(&mesh->pdata, CD_NORMAL)) { | |||||
| /* This assume that layer is always up to date, not sure this is the case (esp. in Edit mode?)... */ | |||||
| polynors = CustomData_get_layer(&mesh->pdata, CD_NORMAL); | |||||
| free_polynors = false; | |||||
| } | |||||
| else { | |||||
| polynors = MEM_mallocN(sizeof(float[3]) * mesh->totpoly, __func__); | |||||
| BKE_mesh_calc_normals_poly(mesh->mvert, mesh->totvert, mesh->mloop, mesh->mpoly, mesh->totloop, mesh->totpoly, | |||||
| polynors, false); | |||||
| free_polynors = true; | |||||
| } | |||||
| BKE_mesh_normals_loop_split( | |||||
| mesh->mvert, mesh->totvert, mesh->medge, mesh->totedge, | |||||
| mesh->mloop, r_loopnors, mesh->totloop, mesh->mpoly, (const float (*)[3])polynors, mesh->totpoly, | |||||
| (mesh->flag & ME_AUTOSMOOTH) != 0, mesh->smoothresh, NULL, clnors, NULL); | |||||
| if (free_polynors) { | |||||
| MEM_freeN(polynors); | |||||
| } | |||||
| } | |||||
| /* Spli faces based on the edge angle. | |||||
campbellbarton: Could use some comment as to what its doing. `/* split faces based on edge angle, matches… | |||||
| * Matches behavior of face splitting in render engines. | |||||
| */ | |||||
| void BKE_mesh_split_faces(Mesh *mesh) | |||||
| { | |||||
| const int num_verts = mesh->totvert; | |||||
| const int num_edges = mesh->totedge; | |||||
| const int num_polys = mesh->totpoly; | |||||
| MVert *mvert = mesh->mvert; | |||||
| MEdge *medge = mesh->medge; | |||||
| MLoop *mloop = mesh->mloop; | |||||
| MPoly *mpoly = mesh->mpoly; | |||||
| float (*lnors)[3]; | |||||
| int poly, num_new_verts = 0; | |||||
| if ((mesh->flag & ME_AUTOSMOOTH) == 0) { | |||||
| return; | |||||
| } | |||||
| BKE_mesh_tessface_clear(mesh); | |||||
| /* Compute loop normals if needed. */ | |||||
| if (!CustomData_has_layer(&mesh->ldata, CD_NORMAL)) { | |||||
| BKE_mesh_calc_normals_split(mesh); | |||||
| } | |||||
Not Done Inline Actionsconvention is to use poly++, same for ~4 other uses in this function num_new_verts campbellbarton: convention is to use `poly++`, same for ~4 other uses in this function `num_new_verts` | |||||
| lnors = CustomData_get_layer(&mesh->ldata, CD_NORMAL); | |||||
| /* Count. */ | |||||
| for (poly = 0; poly < num_polys; poly++) { | |||||
| MPoly *mp = &mpoly[poly]; | |||||
| int loop; | |||||
| for (loop = 0; loop < mp->totloop; loop++) { | |||||
| MLoop *ml = &mloop[mp->loopstart + loop]; | |||||
| MVert *mv = &mvert[ml->v]; | |||||
| float vn[3]; | |||||
| normal_short_to_float_v3(vn, mv->no); | |||||
| if (!equals_v3v3(vn, lnors[mp->loopstart + loop])) { | |||||
| num_new_verts++; | |||||
| } | |||||
| } | |||||
| } | |||||
| if (num_new_verts == 0) { | |||||
| /* No new vertices are to be added, can do early exit. */ | |||||
| return; | |||||
| } | |||||
| /* Actual split. */ | |||||
| mesh->totvert += num_new_verts; | |||||
| mesh->totedge += 2 * num_new_verts; | |||||
| mvert = mesh->mvert = MEM_reallocN(mesh->mvert, | |||||
| sizeof(MVert) * mesh->totvert); | |||||
| medge = mesh->medge = MEM_reallocN(mesh->medge, | |||||
| sizeof(MEdge) * mesh->totedge); | |||||
| CustomData_set_layer(&mesh->vdata, CD_MVERT, mesh->mvert); | |||||
| CustomData_set_layer(&mesh->edata, CD_MEDGE, mesh->medge); | |||||
| num_new_verts = 0; | |||||
| for (poly = 0; poly < num_polys; poly++) { | |||||
| MPoly *mp = &mpoly[poly]; | |||||
| int loop; | |||||
| for (loop = 0; loop < mp->totloop; loop++) { | |||||
| int poly_loop = mp->loopstart + loop; | |||||
| MLoop *ml = &mloop[poly_loop]; | |||||
| MVert *mv = &mvert[ml->v]; | |||||
| float vn[3]; | |||||
| normal_short_to_float_v3(vn, mv->no); | |||||
| if (!equals_v3v3(vn, lnors[mp->loopstart + loop])) { | |||||
| int poly_loop_prev = mp->loopstart + (loop + mp->totloop - 1) % mp->totloop; | |||||
| MLoop *ml_prev = &mloop[poly_loop_prev]; | |||||
| int new_edge_prev, new_edge; | |||||
| /* Cretae new vertex. */ | |||||
| int new_vert = num_verts + num_new_verts; | |||||
| CustomData_copy_data(&mesh->vdata, &mesh->vdata, | |||||
| ml->v, new_vert, 1); | |||||
| normal_float_to_short_v3(mvert[new_vert].no, | |||||
| lnors[poly_loop]); | |||||
| /* Create new edges. */ | |||||
| new_edge_prev = num_edges + 2 * num_new_verts; | |||||
| new_edge = num_edges + 2 * num_new_verts + 1; | |||||
| CustomData_copy_data(&mesh->edata, &mesh->edata, | |||||
| ml_prev->e, new_edge_prev, 1); | |||||
| CustomData_copy_data(&mesh->edata, &mesh->edata, | |||||
| ml->e, new_edge, 1); | |||||
| if (medge[new_edge_prev].v1 == ml->v) { | |||||
| medge[new_edge_prev].v1 = new_vert; | |||||
| } | |||||
| else { | |||||
| medge[new_edge_prev].v2 = new_vert; | |||||
| } | |||||
| if (medge[new_edge].v1 == ml->v) { | |||||
| medge[new_edge].v1 = new_vert; | |||||
| } | |||||
| else { | |||||
| medge[new_edge].v2 = new_vert; | |||||
| } | |||||
| ml->v = new_vert; | |||||
| ml_prev->e = new_edge_prev; | |||||
| ml->e = new_edge; | |||||
| num_new_verts++; | |||||
| } | |||||
| } | |||||
| } | |||||
| } | |||||
| /* settings: 1 - preview, 2 - render */ | /* settings: 1 - preview, 2 - render */ | ||||
| Mesh *BKE_mesh_new_from_object( | Mesh *BKE_mesh_new_from_object( | ||||
| Main *bmain, Scene *sce, Object *ob, | Main *bmain, Scene *sce, Object *ob, | ||||
| int apply_modifiers, int settings, int calc_tessface, int calc_undeformed) | int apply_modifiers, int settings, int calc_tessface, int calc_undeformed) | ||||
| { | { | ||||
| Mesh *tmpmesh; | Mesh *tmpmesh; | ||||
| Curve *tmpcu = NULL, *copycu; | Curve *tmpcu = NULL, *copycu; | ||||
| Object *tmpobj = NULL; | Object *tmpobj = NULL; | ||||
| ▲ Show 20 Lines • Show All 207 Lines • Show Last 20 Lines | |||||
Could use some comment as to what its doing. /* split faces based on edge angle, matches behavior in ... blah blah ... */