Changeset View
Changeset View
Standalone View
Standalone View
source/blender/modifiers/intern/MOD_skin.c
| Show First 20 Lines • Show All 84 Lines • ▼ Show 20 Lines | |||||
| #include "WM_types.h" /* For skin mark clear operator UI. */ | #include "WM_types.h" /* For skin mark clear operator UI. */ | ||||
| #include "MOD_modifiertypes.h" | #include "MOD_modifiertypes.h" | ||||
| #include "MOD_ui_common.h" | #include "MOD_ui_common.h" | ||||
| #include "bmesh.h" | #include "bmesh.h" | ||||
| /* -------------------------------------------------------------------- */ | |||||
| /** \name Generic BMesh Utilities | |||||
| * \{ */ | |||||
| static void vert_face_normal_mark_set(BMVert *v) | |||||
| { | |||||
| BMIter iter; | |||||
| BMFace *f; | |||||
| BM_ITER_ELEM (f, &iter, v, BM_FACES_OF_VERT) { | |||||
| f->no[0] = FLT_MAX; | |||||
| } | |||||
| } | |||||
| static void vert_face_normal_mark_update(BMVert *v) | |||||
| { | |||||
| BMIter iter; | |||||
| BMFace *f; | |||||
| BM_ITER_ELEM (f, &iter, v, BM_FACES_OF_VERT) { | |||||
| if (f->no[0] == FLT_MAX) { | |||||
| BM_face_normal_update(f); | |||||
| } | |||||
| } | |||||
| } | |||||
| /** | |||||
| * Recalculate the normals of all faces connected to `verts`. | |||||
| */ | |||||
| static void vert_array_face_normal_update(BMVert **verts, int verts_len) | |||||
| { | |||||
| for (int i = 0; i < verts_len; i++) { | |||||
| vert_face_normal_mark_set(verts[i]); | |||||
| } | |||||
| for (int i = 0; i < verts_len; i++) { | |||||
| vert_face_normal_mark_update(verts[i]); | |||||
| } | |||||
| } | |||||
| /** \} */ | |||||
| typedef struct { | typedef struct { | ||||
| float mat[3][3]; | float mat[3][3]; | ||||
| /* Vert that edge is pointing away from, no relation to | /* Vert that edge is pointing away from, no relation to | ||||
| * MEdge.v1 */ | * MEdge.v1 */ | ||||
| int origin; | int origin; | ||||
| } EMat; | } EMat; | ||||
| typedef enum { | typedef enum { | ||||
| ▲ Show 20 Lines • Show All 1,246 Lines • ▼ Show 20 Lines | else if (split_face->len > 4) { | ||||
| /* Get split face's verts */ | /* Get split face's verts */ | ||||
| BM_iter_as_array(bm, BM_VERTS_OF_FACE, split_face, (void **)vert_buf, split_face->len); | BM_iter_as_array(bm, BM_VERTS_OF_FACE, split_face, (void **)vert_buf, split_face->len); | ||||
| /* Earlier edge split operations may have turned some quads | /* Earlier edge split operations may have turned some quads | ||||
| * into higher-degree faces */ | * into higher-degree faces */ | ||||
| split_face = collapse_face_corners(bm, split_face, 4, vert_buf); | split_face = collapse_face_corners(bm, split_face, 4, vert_buf); | ||||
| } | } | ||||
| /* Done with dynamic array, split_face must now be a quad */ | /* `split_face` should now be a quad. */ | ||||
| BLI_array_free(vert_buf); | |||||
| BLI_assert(split_face->len == 4); | BLI_assert(split_face->len == 4); | ||||
| /* Account for the highly unlikely case that it's not a quad. */ | |||||
| if (split_face->len != 4) { | if (split_face->len != 4) { | ||||
| /* Reuse `vert_buf` for updating normals. */ | |||||
| BLI_array_clear(vert_buf); | |||||
| BLI_array_grow_items(vert_buf, split_face->len); | |||||
| BM_iter_as_array(bm, BM_FACES_OF_VERT, split_face, (void **)vert_buf, split_face->len); | |||||
| vert_array_face_normal_update(vert_buf, split_face->len); | |||||
| BLI_array_free(vert_buf); | |||||
| return; | return; | ||||
| } | } | ||||
| /* Done with dynamic array. */ | |||||
| BLI_array_free(vert_buf); | |||||
| /* Get split face's verts */ | /* Get split face's verts */ | ||||
| // BM_iter_as_array(bm, BM_VERTS_OF_FACE, split_face, (void **)verts, 4); | // BM_iter_as_array(bm, BM_VERTS_OF_FACE, split_face, (void **)verts, 4); | ||||
| BM_face_as_array_vert_quad(split_face, verts); | BM_face_as_array_vert_quad(split_face, verts); | ||||
| skin_choose_quad_bridge_order(verts, frame->verts, best_order); | skin_choose_quad_bridge_order(verts, frame->verts, best_order); | ||||
| /* Delete split face and merge */ | /* Delete split face and merge */ | ||||
| BM_face_kill(bm, split_face); | BM_face_kill(bm, split_face); | ||||
| BMO_op_init(bm, &op, (BMO_FLAG_DEFAULTS & ~BMO_FLAG_RESPECT_HIDE), "weld_verts"); | BMO_op_init(bm, &op, (BMO_FLAG_DEFAULTS & ~BMO_FLAG_RESPECT_HIDE), "weld_verts"); | ||||
| slot_targetmap = BMO_slot_get(op.slots_in, "targetmap"); | slot_targetmap = BMO_slot_get(op.slots_in, "targetmap"); | ||||
| for (i = 0; i < 4; i++) { | for (i = 0; i < 4; i++) { | ||||
| BMO_slot_map_elem_insert(&op, slot_targetmap, verts[i], frame->verts[best_order[i]]); | BMO_slot_map_elem_insert(&op, slot_targetmap, verts[i], frame->verts[best_order[i]]); | ||||
| } | } | ||||
| BMO_op_exec(bm, &op); | BMO_op_exec(bm, &op); | ||||
| BMO_op_finish(bm, &op); | BMO_op_finish(bm, &op); | ||||
| vert_array_face_normal_update(frame->verts, 4); | |||||
| } | } | ||||
| /* If the frame has some vertices that are inside the hull (detached) | /* If the frame has some vertices that are inside the hull (detached) | ||||
| * and some attached, duplicate the attached vertices and take the | * and some attached, duplicate the attached vertices and take the | ||||
| * whole frame off the hull. */ | * whole frame off the hull. */ | ||||
| static void skin_hole_detach_partially_attached_frame(BMesh *bm, Frame *frame) | static void skin_hole_detach_partially_attached_frame(BMesh *bm, Frame *frame) | ||||
| { | { | ||||
| int i, attached[4], totattached = 0; | int i, attached[4], totattached = 0; | ||||
| ▲ Show 20 Lines • Show All 342 Lines • ▼ Show 20 Lines | BM_ITER_MESH (v, &iter, bm, BM_VERTS_OF_MESH) { | ||||
| if (totv > 1) { | if (totv > 1) { | ||||
| mul_v3_fl(avg, 1.0f / (float)totv); | mul_v3_fl(avg, 1.0f / (float)totv); | ||||
| interp_v3_v3v3(v->co, v->co, avg, weight); | interp_v3_v3v3(v->co, v->co, avg, weight); | ||||
| } | } | ||||
| } | } | ||||
| /* Done with original coordinates */ | /* Done with original coordinates */ | ||||
| BM_data_layer_free_n(bm, &bm->vdata, CD_SHAPEKEY, skey); | BM_data_layer_free_n(bm, &bm->vdata, CD_SHAPEKEY, skey); | ||||
| BMFace *f; | |||||
| BM_ITER_MESH (f, &iter, bm, BM_FACES_OF_MESH) { | |||||
| BM_face_normal_update(f); | |||||
| } | |||||
| } | } | ||||
| /* Returns true if all hulls are successfully built, false otherwise */ | /* Returns true if all hulls are successfully built, false otherwise */ | ||||
| static bool skin_output_branch_hulls( | static bool skin_output_branch_hulls( | ||||
| SkinOutput *so, SkinNode *skin_nodes, int totvert, const MeshElemMap *emap, const MEdge *medge) | SkinOutput *so, SkinNode *skin_nodes, int totvert, const MeshElemMap *emap, const MEdge *medge) | ||||
| { | { | ||||
| bool result = true; | bool result = true; | ||||
| int v; | int v; | ||||
| ▲ Show 20 Lines • Show All 321 Lines • Show Last 20 Lines | |||||