1 /*
2  * This program is free software; you can redistribute it and/or
3  * modify it under the terms of the GNU General Public License
4  * as published by the Free Software Foundation; either version 2
5  * of the License, or (at your option) any later version.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * along with this program; if not, write to the Free Software Foundation,
14  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
15  */
16 
17 /** \file
18  * \ingroup modifiers
19  */
20 
21 /* Implementation based in part off the paper "B-Mesh: A Fast Modeling
22  * System for Base Meshes of 3D Articulated Shapes" (Zhongping Ji,
23  * Ligang Liu, Yigang Wang)
24  *
25  * Note that to avoid confusion with Blender's BMesh data structure,
26  * this tool is renamed as the Skin modifier.
27  *
28  * The B-Mesh paper is current available here:
29  * http://www.math.zju.edu.cn/ligangliu/CAGD/Projects/BMesh/
30  *
31  * The main missing features in this code compared to the paper are:
32  *
33  * + No mesh evolution. The paper suggests iteratively subsurfing the
34  *   skin output and adapting the output to better conform with the
35  *   spheres of influence surrounding each vertex.
36  *
37  * + No mesh fairing. The paper suggests re-aligning output edges to
38  *   follow principal mesh curvatures.
39  *
40  * + No auxiliary balls. These would serve to influence mesh
41  *   evolution, which as noted above is not implemented.
42  *
43  * The code also adds some features not present in the paper:
44  *
45  * + Loops in the input edge graph.
46  *
47  * + Concave surfaces around branch nodes. The paper does not discuss
48  *   how to handle non-convex regions; this code adds a number of
49  *   cleanup operations to handle many (though not all) of these
50  *   cases.
51  */
52 
53 #include "MEM_guardedalloc.h"
54 
55 #include "BLI_utildefines.h"
56 
57 #include "BLI_array.h"
58 #include "BLI_bitmap.h"
59 #include "BLI_heap_simple.h"
60 #include "BLI_math.h"
61 #include "BLI_math_geom.h"
62 #include "BLI_stack.h"
63 
64 #include "BLT_translation.h"
65 
66 #include "DNA_defaults.h"
67 #include "DNA_mesh_types.h"
68 #include "DNA_meshdata_types.h"
69 #include "DNA_modifier_types.h"
70 #include "DNA_object_types.h"
71 #include "DNA_screen_types.h"
72 
73 #include "BKE_context.h"
74 #include "BKE_deform.h"
75 #include "BKE_lib_id.h"
76 #include "BKE_mesh.h"
77 #include "BKE_mesh_mapping.h"
78 #include "BKE_modifier.h"
79 #include "BKE_screen.h"
80 
81 #include "UI_interface.h"
82 #include "UI_resources.h"
83 
84 #include "RNA_access.h"
85 
86 #include "WM_types.h" /* For skin mark clear operator UI. */
87 
88 #include "MOD_modifiertypes.h"
89 #include "MOD_ui_common.h"
90 
91 #include "bmesh.h"
92 
93 typedef struct {
94   float mat[3][3];
95   /* Vert that edge is pointing away from, no relation to
96    * MEdge.v1 */
97   int origin;
98 } EMat;
99 
100 typedef enum {
101   CAP_START = 1,
102   CAP_END = 2,
103   SEAM_FRAME = 4,
104   FLIP_NORMAL = 8,
105 } SkinNodeFlag;
106 
107 typedef struct Frame {
108   /* Index in the MVert array */
109   BMVert *verts[4];
110   /* Location of each corner */
111   float co[4][3];
112   /* Indicates which corners have been merged with another
113    * frame's corner (so they share an MVert index) */
114   struct {
115     /* Merge to target frame/corner (no merge if frame is null) */
116     struct Frame *frame;
117     int corner;
118     /* checked to avoid chaining.
119      * (merging when we're already been referenced), see T39775 */
120     uint is_target : 1;
121   } merge[4];
122 
123   /* For hull frames, whether each vertex is detached or not */
124   bool inside_hull[4];
125   /* Whether any part of the frame (corner or edge) is detached */
126   bool detached;
127 } Frame;
128 
129 #define MAX_SKIN_NODE_FRAMES 2
130 typedef struct {
131   Frame frames[MAX_SKIN_NODE_FRAMES];
132   int totframe;
133 
134   SkinNodeFlag flag;
135 
136   /* Used for hulling a loop seam */
137   int seam_edges[2];
138 } SkinNode;
139 
140 typedef struct {
141   BMesh *bm;
142   SkinModifierData *smd;
143   int mat_nr;
144 } SkinOutput;
145 
146 static void add_poly(SkinOutput *so, BMVert *v1, BMVert *v2, BMVert *v3, BMVert *v4);
147 
148 /***************************** Convex Hull ****************************/
149 
is_quad_symmetric(BMVert * quad[4],const SkinModifierData * smd)150 static bool is_quad_symmetric(BMVert *quad[4], const SkinModifierData *smd)
151 {
152   const float threshold = 0.0001f;
153   const float threshold_squared = threshold * threshold;
154   int axis;
155 
156   for (axis = 0; axis < 3; axis++) {
157     if (smd->symmetry_axes & (1 << axis)) {
158       float a[3];
159 
160       copy_v3_v3(a, quad[0]->co);
161       a[axis] = -a[axis];
162 
163       if (len_squared_v3v3(a, quad[1]->co) < threshold_squared) {
164         copy_v3_v3(a, quad[2]->co);
165         a[axis] = -a[axis];
166         if (len_squared_v3v3(a, quad[3]->co) < threshold_squared) {
167           return 1;
168         }
169       }
170       else if (len_squared_v3v3(a, quad[3]->co) < threshold_squared) {
171         copy_v3_v3(a, quad[2]->co);
172         a[axis] = -a[axis];
173         if (len_squared_v3v3(a, quad[1]->co) < threshold_squared) {
174           return 1;
175         }
176       }
177     }
178   }
179 
180   return 0;
181 }
182 
183 /* Returns true if the quad crosses the plane of symmetry, false otherwise */
quad_crosses_symmetry_plane(BMVert * quad[4],const SkinModifierData * smd)184 static bool quad_crosses_symmetry_plane(BMVert *quad[4], const SkinModifierData *smd)
185 {
186   int axis;
187 
188   for (axis = 0; axis < 3; axis++) {
189     if (smd->symmetry_axes & (1 << axis)) {
190       bool left = false, right = false;
191       int i;
192 
193       for (i = 0; i < 4; i++) {
194         if (quad[i]->co[axis] < 0.0f) {
195           left = true;
196         }
197         else if (quad[i]->co[axis] > 0.0f) {
198           right = true;
199         }
200 
201         if (left && right) {
202           return true;
203         }
204       }
205     }
206   }
207 
208   return false;
209 }
210 
211 /* Returns true if the frame is filled by precisely two faces (and
212  * outputs those faces to fill_faces), otherwise returns false. */
skin_frame_find_contained_faces(const Frame * frame,BMFace * fill_faces[2])213 static bool skin_frame_find_contained_faces(const Frame *frame, BMFace *fill_faces[2])
214 {
215   BMEdge *diag;
216 
217   /* See if the frame is bisected by a diagonal edge */
218   diag = BM_edge_exists(frame->verts[0], frame->verts[2]);
219   if (!diag) {
220     diag = BM_edge_exists(frame->verts[1], frame->verts[3]);
221   }
222 
223   if (diag) {
224     return BM_edge_face_pair(diag, &fill_faces[0], &fill_faces[1]);
225   }
226 
227   return false;
228 }
229 
230 /* Returns true if hull is successfully built, false otherwise */
build_hull(SkinOutput * so,Frame ** frames,int totframe)231 static bool build_hull(SkinOutput *so, Frame **frames, int totframe)
232 {
233 #ifdef WITH_BULLET
234   BMesh *bm = so->bm;
235   BMOperator op;
236   BMIter iter;
237   BMOIter oiter;
238   BMVert *v;
239   BMFace *f;
240   BMEdge *e;
241   int i, j;
242 
243   BM_mesh_elem_hflag_disable_all(bm, BM_VERT, BM_ELEM_TAG, false);
244 
245   for (i = 0; i < totframe; i++) {
246     for (j = 0; j < 4; j++) {
247       BM_elem_flag_enable(frames[i]->verts[j], BM_ELEM_TAG);
248     }
249   }
250 
251   /* Deselect all faces so that only new hull output faces are
252    * selected after the operator is run */
253   BM_mesh_elem_hflag_disable_all(bm, BM_ALL_NOLOOP, BM_ELEM_SELECT, false);
254 
255   BMO_op_initf(
256       bm, &op, (BMO_FLAG_DEFAULTS & ~BMO_FLAG_RESPECT_HIDE), "convex_hull input=%hv", BM_ELEM_TAG);
257   BMO_op_exec(bm, &op);
258 
259   if (BMO_error_occurred(bm)) {
260     BMO_op_finish(bm, &op);
261     return false;
262   }
263 
264   /* Apply face attributes to hull output */
265   BMO_ITER (f, &oiter, op.slots_out, "geom.out", BM_FACE) {
266     BM_face_normal_update(f);
267     if (so->smd->flag & MOD_SKIN_SMOOTH_SHADING) {
268       BM_elem_flag_enable(f, BM_ELEM_SMOOTH);
269     }
270     f->mat_nr = so->mat_nr;
271   }
272 
273   /* Mark interior frames */
274   BMO_ITER (v, &oiter, op.slots_out, "geom_interior.out", BM_VERT) {
275     for (i = 0; i < totframe; i++) {
276       Frame *frame = frames[i];
277 
278       if (!frame->detached) {
279         for (j = 0; j < 4; j++) {
280           if (frame->verts[j] == v) {
281             frame->inside_hull[j] = true;
282             frame->detached = true;
283             break;
284           }
285         }
286       }
287     }
288   }
289 
290   /* Also mark frames as interior if an edge is not in the hull */
291   for (i = 0; i < totframe; i++) {
292     Frame *frame = frames[i];
293 
294     if (!frame->detached && (!BM_edge_exists(frame->verts[0], frame->verts[1]) ||
295                              !BM_edge_exists(frame->verts[1], frame->verts[2]) ||
296                              !BM_edge_exists(frame->verts[2], frame->verts[3]) ||
297                              !BM_edge_exists(frame->verts[3], frame->verts[0]))) {
298       frame->detached = true;
299     }
300   }
301 
302   /* Remove triangles that would fill the original frames -- skip if
303    * frame is partially detached */
304   BM_mesh_elem_hflag_disable_all(bm, BM_ALL_NOLOOP, BM_ELEM_TAG, false);
305   for (i = 0; i < totframe; i++) {
306     Frame *frame = frames[i];
307     if (!frame->detached) {
308       BMFace *fill_faces[2];
309 
310       /* Check if the frame is filled by precisely two
311        * triangles. If so, delete the triangles and their shared
312        * edge. Otherwise, give up and mark the frame as
313        * detached. */
314       if (skin_frame_find_contained_faces(frame, fill_faces)) {
315         BM_elem_flag_enable(fill_faces[0], BM_ELEM_TAG);
316         BM_elem_flag_enable(fill_faces[1], BM_ELEM_TAG);
317       }
318       else {
319         frame->detached = true;
320       }
321     }
322   }
323 
324   /* Check if removing triangles above will create wire triangles,
325    * mark them too */
326   BMO_ITER (e, &oiter, op.slots_out, "geom.out", BM_EDGE) {
327     bool is_wire = true;
328     BM_ITER_ELEM (f, &iter, e, BM_FACES_OF_EDGE) {
329       if (!BM_elem_flag_test(f, BM_ELEM_TAG)) {
330         is_wire = false;
331         break;
332       }
333     }
334     if (is_wire) {
335       BM_elem_flag_enable(e, BM_ELEM_TAG);
336     }
337   }
338 
339   BMO_op_finish(bm, &op);
340 
341   BM_mesh_delete_hflag_tagged(bm, BM_ELEM_TAG, BM_EDGE | BM_FACE);
342 
343   return true;
344 #else
345   UNUSED_VARS(so, frames, totframe, skin_frame_find_contained_faces);
346   return false;
347 #endif
348 }
349 
350 /* Returns the average frame side length (frames are rectangular, so
351  * just the average of two adjacent edge lengths) */
frame_len(const Frame * frame)352 static float frame_len(const Frame *frame)
353 {
354   return (len_v3v3(frame->co[0], frame->co[1]) + len_v3v3(frame->co[1], frame->co[2])) * 0.5f;
355 }
356 
merge_frame_corners(Frame ** frames,int totframe)357 static void merge_frame_corners(Frame **frames, int totframe)
358 {
359   float dist, side_a, side_b, thresh, mid[3];
360   int i, j, k, l;
361 
362   for (i = 0; i < totframe; i++) {
363     side_a = frame_len(frames[i]);
364 
365     /* For each corner of each frame... */
366     for (j = 0; j < 4; j++) {
367 
368       /* Ensure the merge target is not itself a merge target */
369       if (frames[i]->merge[j].frame) {
370         continue;
371       }
372 
373       for (k = i + 1; k < totframe; k++) {
374         BLI_assert(frames[i] != frames[k]);
375 
376         side_b = frame_len(frames[k]);
377         thresh = min_ff(side_a, side_b) / 2.0f;
378 
379         /* Compare with each corner of all other frames... */
380         for (l = 0; l < 4; l++) {
381           if (frames[k]->merge[l].frame || frames[k]->merge[l].is_target) {
382             continue;
383           }
384 
385           /* Some additional concerns that could be checked
386            * further:
387            *
388            * + Vertex coords are being used for the
389            *   edge-length test, but are also being
390            *   modified, might cause symmetry problems.
391            *
392            * + A frame could be merged diagonally across
393            *   another, would generate a weird (bad) T
394            *   junction
395            */
396 
397           /* Check if corners are near each other, where
398            * 'near' is based in the frames' minimum side
399            * length */
400           dist = len_v3v3(frames[i]->co[j], frames[k]->co[l]);
401           if (dist < thresh) {
402             mid_v3_v3v3(mid, frames[i]->co[j], frames[k]->co[l]);
403 
404             copy_v3_v3(frames[i]->co[j], mid);
405             copy_v3_v3(frames[k]->co[l], mid);
406 
407             frames[k]->merge[l].frame = frames[i];
408             frames[k]->merge[l].corner = j;
409             frames[i]->merge[j].is_target = true;
410 
411             /* Can't merge another corner into the same
412              * frame corner, so move on to frame k+1 */
413             break;
414           }
415         }
416       }
417     }
418   }
419 }
420 
collect_hull_frames(int v,SkinNode * frames,const MeshElemMap * emap,const MEdge * medge,int * tothullframe)421 static Frame **collect_hull_frames(
422     int v, SkinNode *frames, const MeshElemMap *emap, const MEdge *medge, int *tothullframe)
423 {
424   SkinNode *f;
425   Frame **hull_frames;
426   int nbr, i;
427 
428   (*tothullframe) = emap[v].count;
429   hull_frames = MEM_calloc_arrayN(
430       (*tothullframe), sizeof(Frame *), "hull_from_frames.hull_frames");
431   i = 0;
432   for (nbr = 0; nbr < emap[v].count; nbr++) {
433     const MEdge *e = &medge[emap[v].indices[nbr]];
434     f = &frames[BKE_mesh_edge_other_vert(e, v)];
435     /* Can't have adjacent branch nodes yet */
436     if (f->totframe) {
437       hull_frames[i++] = &f->frames[0];
438     }
439     else {
440       (*tothullframe)--;
441     }
442   }
443 
444   return hull_frames;
445 }
446 
447 /**************************** Create Frames ***************************/
448 
node_frames_init(SkinNode * nf,int totframe)449 static void node_frames_init(SkinNode *nf, int totframe)
450 {
451   int i;
452 
453   nf->totframe = totframe;
454   memset(nf->frames, 0, sizeof(nf->frames));
455 
456   nf->flag = 0;
457   for (i = 0; i < 2; i++) {
458     nf->seam_edges[i] = -1;
459   }
460 }
461 
create_frame(Frame * frame,const float co[3],const float radius[2],const float mat[3][3],float offset)462 static void create_frame(
463     Frame *frame, const float co[3], const float radius[2], const float mat[3][3], float offset)
464 {
465   float rx[3], ry[3], rz[3];
466   int i;
467 
468   mul_v3_v3fl(ry, mat[1], radius[0]);
469   mul_v3_v3fl(rz, mat[2], radius[1]);
470 
471   add_v3_v3v3(frame->co[3], co, ry);
472   add_v3_v3v3(frame->co[3], frame->co[3], rz);
473 
474   sub_v3_v3v3(frame->co[2], co, ry);
475   add_v3_v3v3(frame->co[2], frame->co[2], rz);
476 
477   sub_v3_v3v3(frame->co[1], co, ry);
478   sub_v3_v3v3(frame->co[1], frame->co[1], rz);
479 
480   add_v3_v3v3(frame->co[0], co, ry);
481   sub_v3_v3v3(frame->co[0], frame->co[0], rz);
482 
483   mul_v3_v3fl(rx, mat[0], offset);
484   for (i = 0; i < 4; i++) {
485     add_v3_v3v3(frame->co[i], frame->co[i], rx);
486   }
487 }
488 
half_v2(const float v[2])489 static float half_v2(const float v[2])
490 {
491   return (v[0] + v[1]) * 0.5f;
492 }
493 
end_node_frames(int v,SkinNode * skin_nodes,const MVert * mvert,const MVertSkin * nodes,const MeshElemMap * emap,EMat * emat)494 static void end_node_frames(int v,
495                             SkinNode *skin_nodes,
496                             const MVert *mvert,
497                             const MVertSkin *nodes,
498                             const MeshElemMap *emap,
499                             EMat *emat)
500 {
501   const float *rad = nodes[v].radius;
502   float mat[3][3];
503 
504   if (emap[v].count == 0) {
505     float avg = half_v2(rad);
506 
507     /* For solitary nodes, just build a box (two frames) */
508     node_frames_init(&skin_nodes[v], 2);
509     skin_nodes[v].flag |= (CAP_START | CAP_END);
510 
511     /* Hardcoded basis */
512     zero_m3(mat);
513     mat[0][2] = mat[1][0] = mat[2][1] = 1;
514 
515     /* Caps */
516     create_frame(&skin_nodes[v].frames[0], mvert[v].co, rad, mat, avg);
517     create_frame(&skin_nodes[v].frames[1], mvert[v].co, rad, mat, -avg);
518   }
519   else {
520     /* For nodes with an incoming edge, create a single (capped) frame */
521     node_frames_init(&skin_nodes[v], 1);
522     skin_nodes[v].flag |= CAP_START;
523 
524     /* Use incoming edge for orientation */
525     copy_m3_m3(mat, emat[emap[v].indices[0]].mat);
526     if (emat[emap[v].indices[0]].origin != v) {
527       negate_v3(mat[0]);
528     }
529 
530     Frame *frame = &skin_nodes[v].frames[0];
531 
532     /* End frame */
533     create_frame(frame, mvert[v].co, rad, mat, 0);
534 
535     /* The caps might need to have their normals inverted. So check if they
536      * need to be flipped when creating faces. */
537     float normal[3];
538     normal_quad_v3(normal, frame->co[0], frame->co[1], frame->co[2], frame->co[3]);
539     if (dot_v3v3(mat[0], normal) < 0.0f) {
540       skin_nodes[v].flag |= FLIP_NORMAL;
541     }
542   }
543 }
544 
545 /* Returns 1 for seam, 0 otherwise */
connection_node_mat(float mat[3][3],int v,const MeshElemMap * emap,EMat * emat)546 static int connection_node_mat(float mat[3][3], int v, const MeshElemMap *emap, EMat *emat)
547 {
548   float axis[3], angle, ine[3][3], oute[3][3];
549   EMat *e1, *e2;
550 
551   e1 = &emat[emap[v].indices[0]];
552   e2 = &emat[emap[v].indices[1]];
553 
554   if (e1->origin != v && e2->origin == v) {
555     copy_m3_m3(ine, e1->mat);
556     copy_m3_m3(oute, e2->mat);
557   }
558   else if (e1->origin == v && e2->origin != v) {
559     copy_m3_m3(ine, e2->mat);
560     copy_m3_m3(oute, e1->mat);
561   }
562   else {
563     return 1;
564   }
565 
566   /* Get axis and angle to rotate frame by */
567   angle = angle_normalized_v3v3(ine[0], oute[0]) / 2.0f;
568   cross_v3_v3v3(axis, ine[0], oute[0]);
569   normalize_v3(axis);
570 
571   /* Build frame matrix (don't care about X axis here) */
572   copy_v3_v3(mat[0], ine[0]);
573   rotate_normalized_v3_v3v3fl(mat[1], ine[1], axis, angle);
574   rotate_normalized_v3_v3v3fl(mat[2], ine[2], axis, angle);
575 
576   return 0;
577 }
578 
connection_node_frames(int v,SkinNode * skin_nodes,const MVert * mvert,const MVertSkin * nodes,const MeshElemMap * emap,EMat * emat)579 static void connection_node_frames(int v,
580                                    SkinNode *skin_nodes,
581                                    const MVert *mvert,
582                                    const MVertSkin *nodes,
583                                    const MeshElemMap *emap,
584                                    EMat *emat)
585 {
586   const float *rad = nodes[v].radius;
587   float mat[3][3];
588   EMat *e1, *e2;
589 
590   if (connection_node_mat(mat, v, emap, emat)) {
591     float avg = half_v2(rad);
592 
593     /* Get edges */
594     e1 = &emat[emap[v].indices[0]];
595     e2 = &emat[emap[v].indices[1]];
596 
597     /* Handle seam separately to avoid twisting */
598     /* Create two frames, will be hulled to neighbors later */
599     node_frames_init(&skin_nodes[v], 2);
600     skin_nodes[v].flag |= SEAM_FRAME;
601 
602     copy_m3_m3(mat, e1->mat);
603     if (e1->origin != v) {
604       negate_v3(mat[0]);
605     }
606     create_frame(&skin_nodes[v].frames[0], mvert[v].co, rad, mat, avg);
607     skin_nodes[v].seam_edges[0] = emap[v].indices[0];
608 
609     copy_m3_m3(mat, e2->mat);
610     if (e2->origin != v) {
611       negate_v3(mat[0]);
612     }
613     create_frame(&skin_nodes[v].frames[1], mvert[v].co, rad, mat, avg);
614     skin_nodes[v].seam_edges[1] = emap[v].indices[1];
615 
616     return;
617   }
618 
619   /* Build regular frame */
620   node_frames_init(&skin_nodes[v], 1);
621   create_frame(&skin_nodes[v].frames[0], mvert[v].co, rad, mat, 0);
622 }
623 
build_frames(const MVert * mvert,int totvert,const MVertSkin * nodes,const MeshElemMap * emap,EMat * emat)624 static SkinNode *build_frames(
625     const MVert *mvert, int totvert, const MVertSkin *nodes, const MeshElemMap *emap, EMat *emat)
626 {
627   SkinNode *skin_nodes;
628   int v;
629 
630   skin_nodes = MEM_calloc_arrayN(totvert, sizeof(SkinNode), "build_frames.skin_nodes");
631 
632   for (v = 0; v < totvert; v++) {
633     if (emap[v].count <= 1) {
634       end_node_frames(v, skin_nodes, mvert, nodes, emap, emat);
635     }
636     else if (emap[v].count == 2) {
637       connection_node_frames(v, skin_nodes, mvert, nodes, emap, emat);
638     }
639     else {
640       /* Branch node generates no frames */
641     }
642   }
643 
644   return skin_nodes;
645 }
646 
647 /**************************** Edge Matrices ***************************/
648 
calc_edge_mat(float mat[3][3],const float a[3],const float b[3])649 static void calc_edge_mat(float mat[3][3], const float a[3], const float b[3])
650 {
651   const float z_up[3] = {0, 0, 1};
652   float dot;
653 
654   /* X = edge direction */
655   sub_v3_v3v3(mat[0], b, a);
656   normalize_v3(mat[0]);
657 
658   dot = dot_v3v3(mat[0], z_up);
659   if (dot > -1 + FLT_EPSILON && dot < 1 - FLT_EPSILON) {
660     /* Y = Z cross x */
661     cross_v3_v3v3(mat[1], z_up, mat[0]);
662     normalize_v3(mat[1]);
663 
664     /* Z = x cross y */
665     cross_v3_v3v3(mat[2], mat[0], mat[1]);
666     normalize_v3(mat[2]);
667   }
668   else {
669     mat[1][0] = 1;
670     mat[1][1] = 0;
671     mat[1][2] = 0;
672     mat[2][0] = 0;
673     mat[2][1] = 1;
674     mat[2][2] = 0;
675   }
676 }
677 
678 typedef struct {
679   float mat[3][3];
680   int parent_v;
681   int e;
682 } EdgeStackElem;
683 
build_emats_stack(BLI_Stack * stack,BLI_bitmap * visited_e,EMat * emat,const MeshElemMap * emap,const MEdge * medge,const MVertSkin * vs,const MVert * mvert)684 static void build_emats_stack(BLI_Stack *stack,
685                               BLI_bitmap *visited_e,
686                               EMat *emat,
687                               const MeshElemMap *emap,
688                               const MEdge *medge,
689                               const MVertSkin *vs,
690                               const MVert *mvert)
691 {
692   EdgeStackElem stack_elem;
693   float axis[3], angle;
694   int i, e, v, parent_v, parent_is_branch;
695 
696   BLI_stack_pop(stack, &stack_elem);
697   parent_v = stack_elem.parent_v;
698   e = stack_elem.e;
699 
700   /* Skip if edge already visited */
701   if (BLI_BITMAP_TEST(visited_e, e)) {
702     return;
703   }
704 
705   /* Mark edge as visited */
706   BLI_BITMAP_ENABLE(visited_e, e);
707 
708   /* Process edge */
709 
710   parent_is_branch = ((emap[parent_v].count > 2) || (vs[parent_v].flag & MVERT_SKIN_ROOT));
711 
712   v = BKE_mesh_edge_other_vert(&medge[e], parent_v);
713   emat[e].origin = parent_v;
714 
715   /* If parent is a branch node, start a new edge chain */
716   if (parent_is_branch) {
717     calc_edge_mat(emat[e].mat, mvert[parent_v].co, mvert[v].co);
718   }
719   else {
720     /* Build edge matrix guided by parent matrix */
721     sub_v3_v3v3(emat[e].mat[0], mvert[v].co, mvert[parent_v].co);
722     normalize_v3(emat[e].mat[0]);
723     angle = angle_normalized_v3v3(stack_elem.mat[0], emat[e].mat[0]);
724     cross_v3_v3v3(axis, stack_elem.mat[0], emat[e].mat[0]);
725     normalize_v3(axis);
726     rotate_normalized_v3_v3v3fl(emat[e].mat[1], stack_elem.mat[1], axis, angle);
727     rotate_normalized_v3_v3v3fl(emat[e].mat[2], stack_elem.mat[2], axis, angle);
728   }
729 
730   /* Add neighbors to stack */
731   for (i = 0; i < emap[v].count; i++) {
732     /* Add neighbors to stack */
733     copy_m3_m3(stack_elem.mat, emat[e].mat);
734     stack_elem.e = emap[v].indices[i];
735     stack_elem.parent_v = v;
736     BLI_stack_push(stack, &stack_elem);
737   }
738 }
739 
build_edge_mats(const MVertSkin * vs,const MVert * mvert,int totvert,const MEdge * medge,const MeshElemMap * emap,int totedge,bool * has_valid_root)740 static EMat *build_edge_mats(const MVertSkin *vs,
741                              const MVert *mvert,
742                              int totvert,
743                              const MEdge *medge,
744                              const MeshElemMap *emap,
745                              int totedge,
746                              bool *has_valid_root)
747 {
748   BLI_Stack *stack;
749   EMat *emat;
750   EdgeStackElem stack_elem;
751   BLI_bitmap *visited_e;
752   int i, v;
753 
754   stack = BLI_stack_new(sizeof(stack_elem), "build_edge_mats.stack");
755 
756   visited_e = BLI_BITMAP_NEW(totedge, "build_edge_mats.visited_e");
757   emat = MEM_calloc_arrayN(totedge, sizeof(EMat), "build_edge_mats.emat");
758 
759   /* Edge matrices are built from the root nodes, add all roots with
760    * children to the stack */
761   for (v = 0; v < totvert; v++) {
762     if (vs[v].flag & MVERT_SKIN_ROOT) {
763       if (emap[v].count >= 1) {
764         const MEdge *e = &medge[emap[v].indices[0]];
765         calc_edge_mat(stack_elem.mat, mvert[v].co, mvert[BKE_mesh_edge_other_vert(e, v)].co);
766         stack_elem.parent_v = v;
767 
768         /* Add adjacent edges to stack */
769         for (i = 0; i < emap[v].count; i++) {
770           stack_elem.e = emap[v].indices[i];
771           BLI_stack_push(stack, &stack_elem);
772         }
773 
774         *has_valid_root = true;
775       }
776       else if (totedge == 0) {
777         /* Vertex-only mesh is valid, mark valid root as well (will display error otherwise). */
778         *has_valid_root = true;
779         break;
780       }
781     }
782   }
783 
784   while (!BLI_stack_is_empty(stack)) {
785     build_emats_stack(stack, visited_e, emat, emap, medge, vs, mvert);
786   }
787 
788   MEM_freeN(visited_e);
789   BLI_stack_free(stack);
790 
791   return emat;
792 }
793 
794 /************************** Input Subdivision *************************/
795 
796 /* Returns number of edge subdivisions, taking into account the radius
797  * of the endpoints and the edge length. If both endpoints are branch
798  * nodes, at least two intermediate frames are required. (This avoids
799  * having any special cases for dealing with sharing a frame between
800  * two hulls.) */
calc_edge_subdivisions(const MVert * mvert,const MVertSkin * nodes,const MEdge * e,const int * degree)801 static int calc_edge_subdivisions(const MVert *mvert,
802                                   const MVertSkin *nodes,
803                                   const MEdge *e,
804                                   const int *degree)
805 {
806   /* prevent memory errors T38003. */
807 #define NUM_SUBDIVISIONS_MAX 128
808 
809   const MVertSkin *evs[2] = {&nodes[e->v1], &nodes[e->v2]};
810   float avg_radius;
811   const bool v1_branch = degree[e->v1] > 2;
812   const bool v2_branch = degree[e->v2] > 2;
813   int num_subdivisions;
814 
815   /* If either end is a branch node marked 'loose', don't subdivide
816    * the edge (or subdivide just twice if both are branches) */
817   if ((v1_branch && (evs[0]->flag & MVERT_SKIN_LOOSE)) ||
818       (v2_branch && (evs[1]->flag & MVERT_SKIN_LOOSE))) {
819     if (v1_branch && v2_branch) {
820       return 2;
821     }
822 
823     return 0;
824   }
825 
826   avg_radius = half_v2(evs[0]->radius) + half_v2(evs[1]->radius);
827 
828   if (avg_radius != 0.0f) {
829     /* possible (but unlikely) that we overflow INT_MAX */
830     float num_subdivisions_fl;
831     const float edge_len = len_v3v3(mvert[e->v1].co, mvert[e->v2].co);
832     num_subdivisions_fl = (edge_len / avg_radius);
833     if (num_subdivisions_fl < NUM_SUBDIVISIONS_MAX) {
834       num_subdivisions = (int)num_subdivisions_fl;
835     }
836     else {
837       num_subdivisions = NUM_SUBDIVISIONS_MAX;
838     }
839   }
840   else {
841     num_subdivisions = 0;
842   }
843 
844   /* If both ends are branch nodes, two intermediate nodes are
845    * required */
846   if (num_subdivisions < 2 && v1_branch && v2_branch) {
847     num_subdivisions = 2;
848   }
849 
850   return num_subdivisions;
851 
852 #undef NUM_SUBDIVISIONS_MAX
853 }
854 
855 /* Take a Mesh and subdivide its edges to keep skin nodes
856  * reasonably close. */
subdivide_base(Mesh * orig)857 static Mesh *subdivide_base(Mesh *orig)
858 {
859   Mesh *result;
860   MVertSkin *orignode, *outnode;
861   MVert *origvert, *outvert;
862   MEdge *origedge, *outedge, *e;
863   MDeformVert *origdvert, *outdvert;
864   int totorigvert, totorigedge;
865   int totsubd, *degree, *edge_subd;
866   int i, j, k, u, v;
867   float radrat;
868 
869   orignode = CustomData_get_layer(&orig->vdata, CD_MVERT_SKIN);
870   origvert = orig->mvert;
871   origedge = orig->medge;
872   origdvert = orig->dvert;
873   totorigvert = orig->totvert;
874   totorigedge = orig->totedge;
875 
876   /* Get degree of all vertices */
877   degree = MEM_calloc_arrayN(totorigvert, sizeof(int), "degree");
878   for (i = 0; i < totorigedge; i++) {
879     degree[origedge[i].v1]++;
880     degree[origedge[i].v2]++;
881   }
882 
883   /* Per edge, store how many subdivisions are needed */
884   edge_subd = MEM_calloc_arrayN((uint)totorigedge, sizeof(int), "edge_subd");
885   for (i = 0, totsubd = 0; i < totorigedge; i++) {
886     edge_subd[i] += calc_edge_subdivisions(origvert, orignode, &origedge[i], degree);
887     BLI_assert(edge_subd[i] >= 0);
888     totsubd += edge_subd[i];
889   }
890 
891   MEM_freeN(degree);
892 
893   /* Allocate output mesh */
894   result = BKE_mesh_new_nomain_from_template(
895       orig, totorigvert + totsubd, totorigedge + totsubd, 0, 0, 0);
896 
897   outvert = result->mvert;
898   outedge = result->medge;
899   outnode = CustomData_get_layer(&result->vdata, CD_MVERT_SKIN);
900   outdvert = result->dvert;
901 
902   /* Copy original vertex data */
903   CustomData_copy_data(&orig->vdata, &result->vdata, 0, 0, totorigvert);
904 
905   /* Subdivide edges */
906   for (i = 0, v = totorigvert; i < totorigedge; i++) {
907     struct {
908       /* Vertex group number */
909       int def_nr;
910       float w1, w2;
911     } *vgroups = NULL, *vg;
912     int totvgroup = 0;
913 
914     e = &origedge[i];
915 
916     if (origdvert) {
917       const MDeformVert *dv1 = &origdvert[e->v1];
918       const MDeformVert *dv2 = &origdvert[e->v2];
919       vgroups = MEM_calloc_arrayN(dv1->totweight, sizeof(*vgroups), "vgroup");
920 
921       /* Only want vertex groups used by both vertices */
922       for (j = 0; j < dv1->totweight; j++) {
923         vg = NULL;
924         for (k = 0; k < dv2->totweight; k++) {
925           if (dv1->dw[j].def_nr == dv2->dw[k].def_nr) {
926             vg = &vgroups[totvgroup];
927             totvgroup++;
928             break;
929           }
930         }
931 
932         if (vg) {
933           vg->def_nr = dv1->dw[j].def_nr;
934           vg->w1 = dv1->dw[j].weight;
935           vg->w2 = dv2->dw[k].weight;
936         }
937       }
938     }
939 
940     u = e->v1;
941     radrat = (half_v2(outnode[e->v2].radius) / half_v2(outnode[e->v1].radius));
942     if (isfinite(radrat)) {
943       radrat = (radrat + 1) / 2;
944     }
945     else {
946       /* Happens when skin is scaled to zero. */
947       radrat = 1.0f;
948     }
949 
950     /* Add vertices and edge segments */
951     for (j = 0; j < edge_subd[i]; j++, v++, outedge++) {
952       float r = (j + 1) / (float)(edge_subd[i] + 1);
953       float t = powf(r, radrat);
954 
955       /* Interpolate vertex coord */
956       interp_v3_v3v3(outvert[v].co, outvert[e->v1].co, outvert[e->v2].co, t);
957 
958       /* Interpolate skin radii */
959       interp_v3_v3v3(outnode[v].radius, orignode[e->v1].radius, orignode[e->v2].radius, t);
960 
961       /* Interpolate vertex group weights */
962       for (k = 0; k < totvgroup; k++) {
963         float weight;
964 
965         vg = &vgroups[k];
966         weight = interpf(vg->w2, vg->w1, t);
967 
968         if (weight > 0) {
969           BKE_defvert_add_index_notest(&outdvert[v], vg->def_nr, weight);
970         }
971       }
972 
973       outedge->v1 = u;
974       outedge->v2 = v;
975       u = v;
976     }
977 
978     if (vgroups) {
979       MEM_freeN(vgroups);
980     }
981 
982     /* Link up to final vertex */
983     outedge->v1 = u;
984     outedge->v2 = e->v2;
985     outedge++;
986   }
987 
988   MEM_freeN(edge_subd);
989 
990   return result;
991 }
992 
993 /******************************* Output *******************************/
994 
995 /* Can be either quad or triangle */
add_poly(SkinOutput * so,BMVert * v1,BMVert * v2,BMVert * v3,BMVert * v4)996 static void add_poly(SkinOutput *so, BMVert *v1, BMVert *v2, BMVert *v3, BMVert *v4)
997 {
998   BMVert *verts[4] = {v1, v2, v3, v4};
999   BMFace *f;
1000 
1001   BLI_assert(v1 != v2 && v1 != v3 && v1 != v4);
1002   BLI_assert(v2 != v3 && v2 != v4);
1003   BLI_assert(v3 != v4);
1004   BLI_assert(v1 && v2 && v3);
1005 
1006   f = BM_face_create_verts(so->bm, verts, v4 ? 4 : 3, NULL, BM_CREATE_NO_DOUBLE, true);
1007   BM_face_normal_update(f);
1008   if (so->smd->flag & MOD_SKIN_SMOOTH_SHADING) {
1009     BM_elem_flag_enable(f, BM_ELEM_SMOOTH);
1010   }
1011   f->mat_nr = so->mat_nr;
1012 }
1013 
connect_frames(SkinOutput * so,BMVert * frame1[4],BMVert * frame2[4])1014 static void connect_frames(SkinOutput *so, BMVert *frame1[4], BMVert *frame2[4])
1015 {
1016   BMVert *q[4][4] = {
1017       {frame2[0], frame2[1], frame1[1], frame1[0]},
1018       {frame2[1], frame2[2], frame1[2], frame1[1]},
1019       {frame2[2], frame2[3], frame1[3], frame1[2]},
1020       {frame2[3], frame2[0], frame1[0], frame1[3]},
1021   };
1022   int i;
1023   bool swap;
1024 
1025   /* Check if frame normals need swap */
1026 #if 0
1027   {
1028     /* simple method, works mostly */
1029     float p[3], no[3];
1030     sub_v3_v3v3(p, q[3][0]->co, q[0][0]->co);
1031     normal_quad_v3(no, q[0][0]->co, q[0][1]->co, q[0][2]->co, q[0][3]->co);
1032     swap = dot_v3v3(no, p) > 0;
1033   }
1034 #else
1035   {
1036     /* comprehensive method, accumulate flipping of all faces */
1037     float cent_sides[4][3];
1038     float cent[3];
1039     float dot = 0.0f;
1040 
1041     for (i = 0; i < 4; i++) {
1042       mid_v3_v3v3v3v3(cent_sides[i], UNPACK4_EX(, q[i], ->co));
1043     }
1044     mid_v3_v3v3v3v3(cent, UNPACK4(cent_sides));
1045 
1046     for (i = 0; i < 4; i++) {
1047       float p[3], no[3];
1048       normal_quad_v3(no, UNPACK4_EX(, q[i], ->co));
1049       sub_v3_v3v3(p, cent, cent_sides[i]);
1050       dot += dot_v3v3(no, p);
1051     }
1052 
1053     swap = dot > 0;
1054   }
1055 #endif
1056 
1057   for (i = 0; i < 4; i++) {
1058     if (swap) {
1059       add_poly(so, q[i][3], q[i][2], q[i][1], q[i][0]);
1060     }
1061     else {
1062       add_poly(so, q[i][0], q[i][1], q[i][2], q[i][3]);
1063     }
1064   }
1065 }
1066 
output_frames(BMesh * bm,SkinNode * sn,const MDeformVert * input_dvert)1067 static void output_frames(BMesh *bm, SkinNode *sn, const MDeformVert *input_dvert)
1068 {
1069   Frame *f;
1070   int i, j;
1071 
1072   /* Output all frame verts */
1073   for (i = 0; i < sn->totframe; i++) {
1074     f = &sn->frames[i];
1075     for (j = 0; j < 4; j++) {
1076       if (!f->merge[j].frame) {
1077         BMVert *v = f->verts[j] = BM_vert_create(bm, f->co[j], NULL, BM_CREATE_NOP);
1078 
1079         if (input_dvert) {
1080           MDeformVert *dv;
1081           dv = CustomData_bmesh_get(&bm->vdata, v->head.data, CD_MDEFORMVERT);
1082 
1083           BLI_assert(dv->totweight == 0);
1084           BKE_defvert_copy(dv, input_dvert);
1085         }
1086       }
1087     }
1088   }
1089 }
1090 
1091 #define PRINT_HOLE_INFO 0
1092 
calc_frame_center(float center[3],const Frame * frame)1093 static void calc_frame_center(float center[3], const Frame *frame)
1094 {
1095   add_v3_v3v3(center, frame->verts[0]->co, frame->verts[1]->co);
1096   add_v3_v3(center, frame->verts[2]->co);
1097   add_v3_v3(center, frame->verts[3]->co);
1098   mul_v3_fl(center, 0.25f);
1099 }
1100 
1101 /* Does crappy fan triangulation of poly, may not be so accurate for
1102  * concave faces */
isect_ray_poly(const float ray_start[3],const float ray_dir[3],BMFace * f,float * r_lambda)1103 static int isect_ray_poly(const float ray_start[3],
1104                           const float ray_dir[3],
1105                           BMFace *f,
1106                           float *r_lambda)
1107 {
1108   BMVert *v, *v_first = NULL, *v_prev = NULL;
1109   BMIter iter;
1110   float best_dist = FLT_MAX;
1111   bool hit = false;
1112 
1113   BM_ITER_ELEM (v, &iter, f, BM_VERTS_OF_FACE) {
1114     if (!v_first) {
1115       v_first = v;
1116     }
1117     else if (v_prev != v_first) {
1118       float dist;
1119       bool curhit;
1120 
1121       curhit = isect_ray_tri_v3(ray_start, ray_dir, v_first->co, v_prev->co, v->co, &dist, NULL);
1122       if (curhit && dist < best_dist) {
1123         hit = true;
1124         best_dist = dist;
1125       }
1126     }
1127 
1128     v_prev = v;
1129   }
1130 
1131   *r_lambda = best_dist;
1132   return hit;
1133 }
1134 
1135 /* Reduce the face down to 'n' corners by collapsing the edges;
1136  * returns the new face.
1137  *
1138  * The orig_verts should contain the vertices of 'f'
1139  */
collapse_face_corners(BMesh * bm,BMFace * f,int n,BMVert ** orig_verts)1140 static BMFace *collapse_face_corners(BMesh *bm, BMFace *f, int n, BMVert **orig_verts)
1141 {
1142   int orig_len = f->len;
1143 
1144   BLI_assert(n >= 3);
1145   BLI_assert(f->len > n);
1146   if (f->len <= n) {
1147     return f;
1148   }
1149 
1150   /* Collapse shortest edge for now */
1151   while (f->len > n) {
1152     BMFace *vf;
1153     BMEdge *shortest_edge;
1154     BMVert *v_safe, *v_merge;
1155     BMOperator op;
1156     BMIter iter;
1157     int i;
1158     BMOpSlot *slot_targetmap;
1159 
1160     shortest_edge = BM_face_find_shortest_loop(f)->e;
1161     BMO_op_initf(bm, &op, (BMO_FLAG_DEFAULTS & ~BMO_FLAG_RESPECT_HIDE), "weld_verts");
1162 
1163     slot_targetmap = BMO_slot_get(op.slots_in, "targetmap");
1164 
1165     /* Note: could probably calculate merges in one go to be
1166      * faster */
1167 
1168     v_safe = shortest_edge->v1;
1169     v_merge = shortest_edge->v2;
1170     mid_v3_v3v3(v_safe->co, v_safe->co, v_merge->co);
1171     BMO_slot_map_elem_insert(&op, slot_targetmap, v_merge, v_safe);
1172     BMO_op_exec(bm, &op);
1173     BMO_op_finish(bm, &op);
1174 
1175     /* Find the new face */
1176     f = NULL;
1177     BM_ITER_ELEM (vf, &iter, v_safe, BM_FACES_OF_VERT) {
1178       bool wrong_face = false;
1179 
1180       for (i = 0; i < orig_len; i++) {
1181         if (orig_verts[i] == v_merge) {
1182           orig_verts[i] = NULL;
1183         }
1184         else if (orig_verts[i] && !BM_vert_in_face(orig_verts[i], vf)) {
1185           wrong_face = true;
1186           break;
1187         }
1188       }
1189 
1190       if (!wrong_face) {
1191         f = vf;
1192         break;
1193       }
1194     }
1195 
1196     BLI_assert(f);
1197   }
1198 
1199   return f;
1200 }
1201 
1202 /* Choose a good face to merge the frame with, used in case the frame
1203  * is completely inside the hull. */
skin_hole_target_face(BMesh * bm,Frame * frame)1204 static BMFace *skin_hole_target_face(BMesh *bm, Frame *frame)
1205 {
1206   BMFace *f, *isect_target_face, *center_target_face;
1207   BMIter iter;
1208   float frame_center[3];
1209   float frame_normal[3];
1210   float best_isect_dist = FLT_MAX;
1211   float best_center_dist = FLT_MAX;
1212 
1213   calc_frame_center(frame_center, frame);
1214   normal_quad_v3(frame_normal,
1215                  frame->verts[3]->co,
1216                  frame->verts[2]->co,
1217                  frame->verts[1]->co,
1218                  frame->verts[0]->co);
1219 
1220   /* Use a line intersection test and nearest center test against
1221    * all faces */
1222   isect_target_face = center_target_face = NULL;
1223   BM_ITER_MESH (f, &iter, bm, BM_FACES_OF_MESH) {
1224     float dist, poly_center[3];
1225     int hit;
1226 
1227     /* Intersection test */
1228     hit = isect_ray_poly(frame_center, frame_normal, f, &dist);
1229     if (hit && dist < best_isect_dist) {
1230       isect_target_face = f;
1231       best_isect_dist = dist;
1232     }
1233 
1234     /* Nearest test */
1235     BM_face_calc_center_median(f, poly_center);
1236     dist = len_v3v3(frame_center, poly_center);
1237     if (dist < best_center_dist) {
1238       center_target_face = f;
1239       best_center_dist = dist;
1240     }
1241   }
1242 
1243   f = isect_target_face;
1244   if (!f || best_center_dist < best_isect_dist / 2) {
1245     f = center_target_face;
1246   }
1247 
1248   /* This case is unlikely now, but could still happen. Should look
1249    * into splitting edges to make new faces. */
1250 #if PRINT_HOLE_INFO
1251   if (!f) {
1252     printf("no good face found\n");
1253   }
1254 #endif
1255 
1256   return f;
1257 }
1258 
1259 /* Use edge-length heuristic to choose from eight possible polygon bridges */
skin_choose_quad_bridge_order(BMVert * a[4],BMVert * b[4],int best_order[4])1260 static void skin_choose_quad_bridge_order(BMVert *a[4], BMVert *b[4], int best_order[4])
1261 {
1262   int orders[8][4];
1263   float shortest_len;
1264   int i, j;
1265 
1266   /* Enumerate all valid orderings */
1267   for (i = 0; i < 4; i++) {
1268     for (j = 0; j < 4; j++) {
1269       orders[i][j] = (j + i) % 4;
1270       orders[i + 4][j] = 3 - ((j + i) % 4);
1271     }
1272   }
1273 
1274   shortest_len = FLT_MAX;
1275   for (i = 0; i < 8; i++) {
1276     float len = 0;
1277 
1278     /* Get total edge length for this configuration */
1279     for (j = 0; j < 4; j++) {
1280       len += len_squared_v3v3(a[j]->co, b[orders[i][j]]->co);
1281     }
1282 
1283     if (len < shortest_len) {
1284       shortest_len = len;
1285       memcpy(best_order, orders[i], sizeof(int[4]));
1286     }
1287   }
1288 }
1289 
skin_fix_hole_no_good_verts(BMesh * bm,Frame * frame,BMFace * split_face)1290 static void skin_fix_hole_no_good_verts(BMesh *bm, Frame *frame, BMFace *split_face)
1291 {
1292   BMFace *f;
1293   BMVert *verts[4];
1294   BMVert **vert_buf = NULL;
1295   BLI_array_declare(vert_buf);
1296   BMOIter oiter;
1297   BMOperator op;
1298   int i, best_order[4];
1299   BMOpSlot *slot_targetmap;
1300 
1301   BLI_assert(split_face->len >= 3);
1302 
1303   /* Extrude the split face */
1304   BM_mesh_elem_hflag_disable_all(bm, BM_FACE, BM_ELEM_TAG, false);
1305   BM_elem_flag_enable(split_face, BM_ELEM_TAG);
1306   BMO_op_initf(bm,
1307                &op,
1308                (BMO_FLAG_DEFAULTS & ~BMO_FLAG_RESPECT_HIDE),
1309                "extrude_discrete_faces faces=%hf",
1310                BM_ELEM_TAG);
1311   BMO_op_exec(bm, &op);
1312 
1313   /* Update split face (should only be one new face created
1314    * during extrusion) */
1315   split_face = NULL;
1316   BMO_ITER (f, &oiter, op.slots_out, "faces.out", BM_FACE) {
1317     BLI_assert(!split_face);
1318     split_face = f;
1319   }
1320 
1321   BMO_op_finish(bm, &op);
1322 
1323   if (split_face->len == 3) {
1324     BMEdge *longest_edge;
1325 
1326     /* Need at least four ring edges, so subdivide longest edge if
1327      * face is a triangle */
1328     longest_edge = BM_face_find_longest_loop(split_face)->e;
1329 
1330     BM_mesh_elem_hflag_disable_all(bm, BM_EDGE, BM_ELEM_TAG, false);
1331     BM_elem_flag_enable(longest_edge, BM_ELEM_TAG);
1332 
1333     BMO_op_callf(bm,
1334                  BMO_FLAG_DEFAULTS,
1335                  "subdivide_edges edges=%he cuts=%i quad_corner_type=%i",
1336                  BM_ELEM_TAG,
1337                  1,
1338                  SUBD_CORNER_STRAIGHT_CUT);
1339   }
1340   else if (split_face->len > 4) {
1341     /* Maintain a dynamic vert array containing the split_face's
1342      * vertices, avoids frequent allocs in collapse_face_corners() */
1343     if (BLI_array_len(vert_buf) < split_face->len) {
1344       BLI_array_grow_items(vert_buf, (split_face->len - BLI_array_len(vert_buf)));
1345     }
1346 
1347     /* Get split face's verts */
1348     BM_iter_as_array(bm, BM_VERTS_OF_FACE, split_face, (void **)vert_buf, split_face->len);
1349 
1350     /* Earlier edge split operations may have turned some quads
1351      * into higher-degree faces */
1352     split_face = collapse_face_corners(bm, split_face, 4, vert_buf);
1353   }
1354 
1355   /* Done with dynamic array, split_face must now be a quad */
1356   BLI_array_free(vert_buf);
1357   BLI_assert(split_face->len == 4);
1358   if (split_face->len != 4) {
1359     return;
1360   }
1361 
1362   /* Get split face's verts */
1363   // BM_iter_as_array(bm, BM_VERTS_OF_FACE, split_face, (void **)verts, 4);
1364   BM_face_as_array_vert_quad(split_face, verts);
1365   skin_choose_quad_bridge_order(verts, frame->verts, best_order);
1366 
1367   /* Delete split face and merge */
1368   BM_face_kill(bm, split_face);
1369   BMO_op_init(bm, &op, (BMO_FLAG_DEFAULTS & ~BMO_FLAG_RESPECT_HIDE), "weld_verts");
1370   slot_targetmap = BMO_slot_get(op.slots_in, "targetmap");
1371   for (i = 0; i < 4; i++) {
1372     BMO_slot_map_elem_insert(&op, slot_targetmap, verts[i], frame->verts[best_order[i]]);
1373   }
1374   BMO_op_exec(bm, &op);
1375   BMO_op_finish(bm, &op);
1376 }
1377 
1378 /* If the frame has some vertices that are inside the hull (detached)
1379  * and some attached, duplicate the attached vertices and take the
1380  * whole frame off the hull. */
skin_hole_detach_partially_attached_frame(BMesh * bm,Frame * frame)1381 static void skin_hole_detach_partially_attached_frame(BMesh *bm, Frame *frame)
1382 {
1383   int i, attached[4], totattached = 0;
1384 
1385   /* Get/count attached frame corners */
1386   for (i = 0; i < 4; i++) {
1387     if (!frame->inside_hull[i]) {
1388       attached[totattached++] = i;
1389     }
1390   }
1391 
1392   /* Detach everything */
1393   for (i = 0; i < totattached; i++) {
1394     BMVert **av = &frame->verts[attached[i]];
1395     (*av) = BM_vert_create(bm, (*av)->co, *av, BM_CREATE_NOP);
1396   }
1397 }
1398 
quad_from_tris(BMEdge * e,BMFace * adj[2],BMVert * ndx[4])1399 static void quad_from_tris(BMEdge *e, BMFace *adj[2], BMVert *ndx[4])
1400 {
1401   BMVert *tri[2][3];
1402   BMVert *opp = NULL;
1403   int i, j;
1404 
1405   BLI_assert(adj[0]->len == 3 && adj[1]->len == 3);
1406 
1407 #if 0
1408   BM_iter_as_array(bm, BM_VERTS_OF_FACE, adj[0], (void **)tri[0], 3);
1409   BM_iter_as_array(bm, BM_VERTS_OF_FACE, adj[1], (void **)tri[1], 3);
1410 #else
1411   BM_face_as_array_vert_tri(adj[0], tri[0]);
1412   BM_face_as_array_vert_tri(adj[1], tri[1]);
1413 #endif
1414 
1415   /* Find what the second tri has that the first doesn't */
1416   for (i = 0; i < 3; i++) {
1417     if (tri[1][i] != tri[0][0] && tri[1][i] != tri[0][1] && tri[1][i] != tri[0][2]) {
1418       opp = tri[1][i];
1419       break;
1420     }
1421   }
1422   BLI_assert(opp);
1423 
1424   for (i = 0, j = 0; i < 3; i++, j++) {
1425     ndx[j] = tri[0][i];
1426     /* When the triangle edge cuts across our quad-to-be,
1427      * throw in the second triangle's vertex */
1428     if ((tri[0][i] == e->v1 || tri[0][i] == e->v2) &&
1429         (tri[0][(i + 1) % 3] == e->v1 || tri[0][(i + 1) % 3] == e->v2)) {
1430       j++;
1431       ndx[j] = opp;
1432     }
1433   }
1434 }
1435 
add_quad_from_tris(SkinOutput * so,BMEdge * e,BMFace * adj[2])1436 static void add_quad_from_tris(SkinOutput *so, BMEdge *e, BMFace *adj[2])
1437 {
1438   BMVert *quad[4];
1439 
1440   quad_from_tris(e, adj, quad);
1441 
1442   add_poly(so, quad[0], quad[1], quad[2], quad[3]);
1443 }
1444 
hull_merge_triangles(SkinOutput * so,const SkinModifierData * smd)1445 static void hull_merge_triangles(SkinOutput *so, const SkinModifierData *smd)
1446 {
1447   BMIter iter;
1448   BMEdge *e;
1449   HeapSimple *heap;
1450   float score;
1451 
1452   heap = BLI_heapsimple_new();
1453 
1454   BM_mesh_elem_hflag_disable_all(so->bm, BM_FACE, BM_ELEM_TAG, false);
1455 
1456   /* Build heap */
1457   BM_ITER_MESH (e, &iter, so->bm, BM_EDGES_OF_MESH) {
1458     BMFace *adj[2];
1459 
1460     /* Only care if the edge is used by exactly two triangles */
1461     if (BM_edge_face_pair(e, &adj[0], &adj[1])) {
1462       if (adj[0]->len == 3 && adj[1]->len == 3) {
1463         BMVert *quad[4];
1464 
1465         BLI_assert(BM_face_is_normal_valid(adj[0]));
1466         BLI_assert(BM_face_is_normal_valid(adj[1]));
1467 
1468         /* Construct quad using the two triangles adjacent to
1469          * the edge */
1470         quad_from_tris(e, adj, quad);
1471 
1472         /* Calculate a score for the quad, higher score for
1473          * triangles being closer to coplanar */
1474         score = ((BM_face_calc_area(adj[0]) + BM_face_calc_area(adj[1])) *
1475                  dot_v3v3(adj[0]->no, adj[1]->no));
1476 
1477         /* Check if quad crosses the axis of symmetry */
1478         if (quad_crosses_symmetry_plane(quad, smd)) {
1479           /* Increase score if the triangles form a
1480            * symmetric quad, otherwise don't use it */
1481           if (is_quad_symmetric(quad, smd)) {
1482             score *= 10;
1483           }
1484           else {
1485             continue;
1486           }
1487         }
1488 
1489         /* Don't use the quad if it's concave */
1490         if (!is_quad_convex_v3(quad[0]->co, quad[1]->co, quad[2]->co, quad[3]->co)) {
1491           continue;
1492         }
1493 
1494         BLI_heapsimple_insert(heap, -score, e);
1495       }
1496     }
1497   }
1498 
1499   while (!BLI_heapsimple_is_empty(heap)) {
1500     BMFace *adj[2];
1501 
1502     e = BLI_heapsimple_pop_min(heap);
1503 
1504     if (BM_edge_face_pair(e, &adj[0], &adj[1])) {
1505       /* If both triangles still free, and if they don't already
1506        * share a border with another face, output as a quad */
1507       if (!BM_elem_flag_test(adj[0], BM_ELEM_TAG) && !BM_elem_flag_test(adj[1], BM_ELEM_TAG) &&
1508           !BM_face_share_face_check(adj[0], adj[1])) {
1509         add_quad_from_tris(so, e, adj);
1510         BM_elem_flag_enable(adj[0], BM_ELEM_TAG);
1511         BM_elem_flag_enable(adj[1], BM_ELEM_TAG);
1512         BM_elem_flag_enable(e, BM_ELEM_TAG);
1513       }
1514     }
1515   }
1516 
1517   BLI_heapsimple_free(heap, NULL);
1518 
1519   BM_mesh_delete_hflag_tagged(so->bm, BM_ELEM_TAG, BM_EDGE | BM_FACE);
1520 }
1521 
skin_merge_close_frame_verts(SkinNode * skin_nodes,int totvert,const MeshElemMap * emap,const MEdge * medge)1522 static void skin_merge_close_frame_verts(SkinNode *skin_nodes,
1523                                          int totvert,
1524                                          const MeshElemMap *emap,
1525                                          const MEdge *medge)
1526 {
1527   Frame **hull_frames;
1528   int v, tothullframe;
1529 
1530   for (v = 0; v < totvert; v++) {
1531     /* Only check branch nodes */
1532     if (!skin_nodes[v].totframe) {
1533       hull_frames = collect_hull_frames(v, skin_nodes, emap, medge, &tothullframe);
1534       merge_frame_corners(hull_frames, tothullframe);
1535       MEM_freeN(hull_frames);
1536     }
1537   }
1538 }
1539 
skin_update_merged_vertices(SkinNode * skin_nodes,int totvert)1540 static void skin_update_merged_vertices(SkinNode *skin_nodes, int totvert)
1541 {
1542   int v;
1543 
1544   for (v = 0; v < totvert; v++) {
1545     SkinNode *sn = &skin_nodes[v];
1546     int i, j;
1547 
1548     for (i = 0; i < sn->totframe; i++) {
1549       Frame *f = &sn->frames[i];
1550 
1551       for (j = 0; j < 4; j++) {
1552         if (f->merge[j].frame) {
1553           /* Merge chaining not allowed */
1554           BLI_assert(!f->merge[j].frame->merge[f->merge[j].corner].frame);
1555 
1556           f->verts[j] = f->merge[j].frame->verts[f->merge[j].corner];
1557         }
1558       }
1559     }
1560   }
1561 }
1562 
skin_fix_hull_topology(BMesh * bm,SkinNode * skin_nodes,int totvert)1563 static void skin_fix_hull_topology(BMesh *bm, SkinNode *skin_nodes, int totvert)
1564 {
1565   int v;
1566 
1567   for (v = 0; v < totvert; v++) {
1568     SkinNode *sn = &skin_nodes[v];
1569     int j;
1570 
1571     for (j = 0; j < sn->totframe; j++) {
1572       Frame *f = &sn->frames[j];
1573 
1574       if (f->detached) {
1575         BMFace *target_face;
1576 
1577         skin_hole_detach_partially_attached_frame(bm, f);
1578 
1579         target_face = skin_hole_target_face(bm, f);
1580         if (target_face) {
1581           skin_fix_hole_no_good_verts(bm, f, target_face);
1582         }
1583       }
1584     }
1585   }
1586 }
1587 
skin_output_end_nodes(SkinOutput * so,SkinNode * skin_nodes,int totvert)1588 static void skin_output_end_nodes(SkinOutput *so, SkinNode *skin_nodes, int totvert)
1589 {
1590   int v;
1591 
1592   for (v = 0; v < totvert; v++) {
1593     SkinNode *sn = &skin_nodes[v];
1594     /* Assuming here just two frames */
1595     if (sn->flag & SEAM_FRAME) {
1596       BMVert *v_order[4];
1597       int i, order[4];
1598 
1599       skin_choose_quad_bridge_order(sn->frames[0].verts, sn->frames[1].verts, order);
1600       for (i = 0; i < 4; i++) {
1601         v_order[i] = sn->frames[1].verts[order[i]];
1602       }
1603       connect_frames(so, sn->frames[0].verts, v_order);
1604     }
1605     else if (sn->totframe == 2) {
1606       connect_frames(so, sn->frames[0].verts, sn->frames[1].verts);
1607     }
1608 
1609     if (sn->flag & CAP_START) {
1610       if (sn->flag & FLIP_NORMAL) {
1611         add_poly(so,
1612                  sn->frames[0].verts[0],
1613                  sn->frames[0].verts[1],
1614                  sn->frames[0].verts[2],
1615                  sn->frames[0].verts[3]);
1616       }
1617       else {
1618         add_poly(so,
1619                  sn->frames[0].verts[3],
1620                  sn->frames[0].verts[2],
1621                  sn->frames[0].verts[1],
1622                  sn->frames[0].verts[0]);
1623       }
1624     }
1625     if (sn->flag & CAP_END) {
1626       add_poly(so,
1627                sn->frames[1].verts[0],
1628                sn->frames[1].verts[1],
1629                sn->frames[1].verts[2],
1630                sn->frames[1].verts[3]);
1631     }
1632   }
1633 }
1634 
skin_output_connections(SkinOutput * so,SkinNode * skin_nodes,const MEdge * medge,int totedge)1635 static void skin_output_connections(SkinOutput *so,
1636                                     SkinNode *skin_nodes,
1637                                     const MEdge *medge,
1638                                     int totedge)
1639 {
1640   int e;
1641 
1642   for (e = 0; e < totedge; e++) {
1643     SkinNode *a, *b;
1644     a = &skin_nodes[medge[e].v1];
1645     b = &skin_nodes[medge[e].v2];
1646 
1647     if (a->totframe && b->totframe) {
1648       if ((a->flag & SEAM_FRAME) || (b->flag & SEAM_FRAME)) {
1649         Frame *fr[2] = {&a->frames[0], &b->frames[0]};
1650         BMVert *v_order[4];
1651         int i, order[4];
1652 
1653         if ((a->flag & SEAM_FRAME) && (e != a->seam_edges[0])) {
1654           fr[0]++;
1655         }
1656         if ((b->flag & SEAM_FRAME) && (e != b->seam_edges[0])) {
1657           fr[1]++;
1658         }
1659 
1660         skin_choose_quad_bridge_order(fr[0]->verts, fr[1]->verts, order);
1661         for (i = 0; i < 4; i++) {
1662           v_order[i] = fr[1]->verts[order[i]];
1663         }
1664         connect_frames(so, fr[0]->verts, v_order);
1665       }
1666       else {
1667         connect_frames(so, a->frames[0].verts, b->frames[0].verts);
1668       }
1669     }
1670   }
1671 }
1672 
skin_smooth_hulls(BMesh * bm,SkinNode * skin_nodes,int totvert,const SkinModifierData * smd)1673 static void skin_smooth_hulls(BMesh *bm,
1674                               SkinNode *skin_nodes,
1675                               int totvert,
1676                               const SkinModifierData *smd)
1677 {
1678   BMIter iter, eiter;
1679   BMVert *v;
1680   int i, j, k, skey;
1681 
1682   if (smd->branch_smoothing == 0) {
1683     return;
1684   }
1685 
1686   /* Mark all frame vertices */
1687   BM_mesh_elem_hflag_disable_all(bm, BM_VERT, BM_ELEM_TAG, false);
1688   for (i = 0; i < totvert; i++) {
1689     for (j = 0; j < skin_nodes[i].totframe; j++) {
1690       Frame *frame = &skin_nodes[i].frames[j];
1691 
1692       for (k = 0; k < 4; k++) {
1693         BM_elem_flag_enable(frame->verts[k], BM_ELEM_TAG);
1694       }
1695     }
1696   }
1697 
1698   /* Add temporary shapekey layer to store original coordinates */
1699   BM_data_layer_add(bm, &bm->vdata, CD_SHAPEKEY);
1700   skey = CustomData_number_of_layers(&bm->vdata, CD_SHAPEKEY) - 1;
1701   BM_ITER_MESH (v, &iter, bm, BM_VERTS_OF_MESH) {
1702     copy_v3_v3(CustomData_bmesh_get_n(&bm->vdata, v->head.data, CD_SHAPEKEY, skey), v->co);
1703   }
1704 
1705   /* Smooth vertices, weight unmarked vertices more strongly (helps
1706    * to smooth frame vertices, but don't want to alter them too
1707    * much) */
1708   BM_ITER_MESH (v, &iter, bm, BM_VERTS_OF_MESH) {
1709     BMEdge *e;
1710     float avg[3];
1711     float weight = smd->branch_smoothing;
1712     int totv = 1;
1713 
1714     if (BM_elem_flag_test(v, BM_ELEM_TAG)) {
1715       weight *= 0.5f;
1716     }
1717 
1718     copy_v3_v3(avg, v->co);
1719     BM_ITER_ELEM (e, &eiter, v, BM_EDGES_OF_VERT) {
1720       BMVert *other = BM_edge_other_vert(e, v);
1721 
1722       add_v3_v3(avg, CustomData_bmesh_get_n(&bm->vdata, other->head.data, CD_SHAPEKEY, skey));
1723       totv++;
1724     }
1725 
1726     if (totv > 1) {
1727       mul_v3_fl(avg, 1.0f / (float)totv);
1728       interp_v3_v3v3(v->co, v->co, avg, weight);
1729     }
1730   }
1731 
1732   /* Done with original coordinates */
1733   BM_data_layer_free_n(bm, &bm->vdata, CD_SHAPEKEY, skey);
1734 }
1735 
1736 /* Returns true if all hulls are successfully built, false otherwise */
skin_output_branch_hulls(SkinOutput * so,SkinNode * skin_nodes,int totvert,const MeshElemMap * emap,const MEdge * medge)1737 static bool skin_output_branch_hulls(
1738     SkinOutput *so, SkinNode *skin_nodes, int totvert, const MeshElemMap *emap, const MEdge *medge)
1739 {
1740   bool result = true;
1741   int v;
1742 
1743   for (v = 0; v < totvert; v++) {
1744     SkinNode *sn = &skin_nodes[v];
1745 
1746     /* Branch node hulls */
1747     if (!sn->totframe) {
1748       Frame **hull_frames;
1749       int tothullframe;
1750 
1751       hull_frames = collect_hull_frames(v, skin_nodes, emap, medge, &tothullframe);
1752       if (!build_hull(so, hull_frames, tothullframe)) {
1753         result = false;
1754       }
1755 
1756       MEM_freeN(hull_frames);
1757     }
1758   }
1759 
1760   return result;
1761 }
1762 
build_skin(SkinNode * skin_nodes,int totvert,const MeshElemMap * emap,const MEdge * medge,int totedge,const MDeformVert * input_dvert,SkinModifierData * smd)1763 static BMesh *build_skin(SkinNode *skin_nodes,
1764                          int totvert,
1765                          const MeshElemMap *emap,
1766                          const MEdge *medge,
1767                          int totedge,
1768                          const MDeformVert *input_dvert,
1769                          SkinModifierData *smd)
1770 {
1771   SkinOutput so;
1772   int v;
1773 
1774   so.smd = smd;
1775   so.bm = BM_mesh_create(&bm_mesh_allocsize_default,
1776                          &((struct BMeshCreateParams){
1777                              .use_toolflags = true,
1778                          }));
1779   so.mat_nr = 0;
1780 
1781   /* BMESH_TODO: bumping up the stack level (see MOD_array.c) */
1782   BM_mesh_elem_toolflags_ensure(so.bm);
1783   BMO_push(so.bm, NULL);
1784   bmesh_edit_begin(so.bm, 0);
1785 
1786   if (input_dvert) {
1787     BM_data_layer_add(so.bm, &so.bm->vdata, CD_MDEFORMVERT);
1788   }
1789 
1790   /* Check for mergeable frame corners around hulls before
1791    * outputting vertices */
1792   skin_merge_close_frame_verts(skin_nodes, totvert, emap, medge);
1793 
1794   /* Write out all frame vertices to the mesh */
1795   for (v = 0; v < totvert; v++) {
1796     if (skin_nodes[v].totframe) {
1797       output_frames(so.bm, &skin_nodes[v], input_dvert ? &input_dvert[v] : NULL);
1798     }
1799   }
1800 
1801   /* Update vertex pointers for merged frame corners */
1802   skin_update_merged_vertices(skin_nodes, totvert);
1803 
1804   if (!skin_output_branch_hulls(&so, skin_nodes, totvert, emap, medge)) {
1805     BKE_modifier_set_error(&smd->modifier, "Hull error");
1806   }
1807 
1808   /* Merge triangles here in the hope of providing better target
1809    * faces for skin_fix_hull_topology() to connect to */
1810   hull_merge_triangles(&so, smd);
1811 
1812   /* Using convex hulls may not generate a nice manifold mesh. Two
1813    * problems can occur: an input frame's edges may be inside the
1814    * hull, and/or an input frame's vertices may be inside the hull.
1815    *
1816    * General fix to produce manifold mesh: for any frame that is
1817    * partially detached, first detach it fully, then find a suitable
1818    * existing face to merge with. (Note that we do this after
1819    * creating all hull faces, but before creating any other
1820    * faces.
1821    */
1822   skin_fix_hull_topology(so.bm, skin_nodes, totvert);
1823 
1824   skin_smooth_hulls(so.bm, skin_nodes, totvert, smd);
1825 
1826   skin_output_end_nodes(&so, skin_nodes, totvert);
1827   skin_output_connections(&so, skin_nodes, medge, totedge);
1828   hull_merge_triangles(&so, smd);
1829 
1830   bmesh_edit_end(so.bm, 0);
1831   BMO_pop(so.bm);
1832 
1833   return so.bm;
1834 }
1835 
skin_set_orig_indices(Mesh * mesh)1836 static void skin_set_orig_indices(Mesh *mesh)
1837 {
1838   int *orig, totpoly;
1839 
1840   totpoly = mesh->totpoly;
1841   orig = CustomData_add_layer(&mesh->pdata, CD_ORIGINDEX, CD_CALLOC, NULL, totpoly);
1842   copy_vn_i(orig, totpoly, ORIGINDEX_NONE);
1843 }
1844 
1845 /*
1846  * 0) Subdivide edges (in caller)
1847  * 1) Generate good edge matrices (uses root nodes)
1848  * 2) Generate node frames
1849  * 3) Output vertices and polygons from frames, connections, and hulls
1850  */
base_skin(Mesh * origmesh,SkinModifierData * smd)1851 static Mesh *base_skin(Mesh *origmesh, SkinModifierData *smd)
1852 {
1853   Mesh *result;
1854   MVertSkin *nodes;
1855   BMesh *bm;
1856   EMat *emat;
1857   SkinNode *skin_nodes;
1858   MeshElemMap *emap;
1859   int *emapmem;
1860   MVert *mvert;
1861   MEdge *medge;
1862   MDeformVert *dvert;
1863   int totvert, totedge;
1864   bool has_valid_root = false;
1865 
1866   nodes = CustomData_get_layer(&origmesh->vdata, CD_MVERT_SKIN);
1867 
1868   mvert = origmesh->mvert;
1869   dvert = origmesh->dvert;
1870   medge = origmesh->medge;
1871   totvert = origmesh->totvert;
1872   totedge = origmesh->totedge;
1873 
1874   BKE_mesh_vert_edge_map_create(&emap, &emapmem, medge, totvert, totedge);
1875 
1876   emat = build_edge_mats(nodes, mvert, totvert, medge, emap, totedge, &has_valid_root);
1877   skin_nodes = build_frames(mvert, totvert, nodes, emap, emat);
1878   MEM_freeN(emat);
1879   emat = NULL;
1880 
1881   bm = build_skin(skin_nodes, totvert, emap, medge, totedge, dvert, smd);
1882 
1883   MEM_freeN(skin_nodes);
1884   MEM_freeN(emap);
1885   MEM_freeN(emapmem);
1886 
1887   if (!has_valid_root) {
1888     BKE_modifier_set_error(
1889         &smd->modifier,
1890         "No valid root vertex found (you need one per mesh island you want to skin)");
1891   }
1892 
1893   if (!bm) {
1894     return NULL;
1895   }
1896 
1897   result = BKE_mesh_from_bmesh_for_eval_nomain(bm, NULL, origmesh);
1898   BM_mesh_free(bm);
1899 
1900   result->runtime.cd_dirty_vert |= CD_MASK_NORMAL;
1901 
1902   skin_set_orig_indices(result);
1903 
1904   return result;
1905 }
1906 
final_skin(SkinModifierData * smd,Mesh * mesh)1907 static Mesh *final_skin(SkinModifierData *smd, Mesh *mesh)
1908 {
1909   Mesh *result;
1910 
1911   /* Skin node layer is required */
1912   if (!CustomData_get_layer(&mesh->vdata, CD_MVERT_SKIN)) {
1913     return mesh;
1914   }
1915 
1916   mesh = subdivide_base(mesh);
1917   result = base_skin(mesh, smd);
1918 
1919   BKE_id_free(NULL, mesh);
1920   return result;
1921 }
1922 
1923 /**************************** Skin Modifier ***************************/
1924 
initData(ModifierData * md)1925 static void initData(ModifierData *md)
1926 {
1927   SkinModifierData *smd = (SkinModifierData *)md;
1928 
1929   BLI_assert(MEMCMP_STRUCT_AFTER_IS_ZERO(smd, modifier));
1930 
1931   MEMCPY_STRUCT_AFTER(smd, DNA_struct_default_get(SkinModifierData), modifier);
1932 
1933   /* Enable in editmode by default. */
1934   md->mode |= eModifierMode_Editmode;
1935 }
1936 
modifyMesh(ModifierData * md,const ModifierEvalContext * UNUSED (ctx),Mesh * mesh)1937 static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *UNUSED(ctx), Mesh *mesh)
1938 {
1939   Mesh *result;
1940 
1941   if (!(result = final_skin((SkinModifierData *)md, mesh))) {
1942     return mesh;
1943   }
1944   return result;
1945 }
1946 
requiredDataMask(Object * UNUSED (ob),ModifierData * UNUSED (md),CustomData_MeshMasks * r_cddata_masks)1947 static void requiredDataMask(Object *UNUSED(ob),
1948                              ModifierData *UNUSED(md),
1949                              CustomData_MeshMasks *r_cddata_masks)
1950 {
1951   r_cddata_masks->vmask |= CD_MASK_MVERT_SKIN | CD_MASK_MDEFORMVERT;
1952 }
1953 
panel_draw(const bContext * UNUSED (C),Panel * panel)1954 static void panel_draw(const bContext *UNUSED(C), Panel *panel)
1955 {
1956   uiLayout *row;
1957   uiLayout *layout = panel->layout;
1958   int toggles_flag = UI_ITEM_R_TOGGLE | UI_ITEM_R_FORCE_BLANK_DECORATE;
1959 
1960   PointerRNA ob_ptr;
1961   PointerRNA *ptr = modifier_panel_get_property_pointers(panel, &ob_ptr);
1962 
1963   PointerRNA op_ptr;
1964 
1965   uiLayoutSetPropSep(layout, true);
1966 
1967   uiItemR(layout, ptr, "branch_smoothing", 0, NULL, ICON_NONE);
1968 
1969   row = uiLayoutRowWithHeading(layout, true, IFACE_("Symmetry"));
1970   uiItemR(row, ptr, "use_x_symmetry", toggles_flag, NULL, ICON_NONE);
1971   uiItemR(row, ptr, "use_y_symmetry", toggles_flag, NULL, ICON_NONE);
1972   uiItemR(row, ptr, "use_z_symmetry", toggles_flag, NULL, ICON_NONE);
1973 
1974   uiItemR(layout, ptr, "use_smooth_shade", 0, NULL, ICON_NONE);
1975 
1976   row = uiLayoutRow(layout, false);
1977   uiItemO(row, IFACE_("Create Armature"), ICON_NONE, "OBJECT_OT_skin_armature_create");
1978   uiItemO(row, NULL, ICON_NONE, "MESH_OT_customdata_skin_add");
1979 
1980   row = uiLayoutRow(layout, false);
1981   uiItemFullO(row,
1982               "OBJECT_OT_skin_loose_mark_clear",
1983               IFACE_("Mark Loose"),
1984               ICON_NONE,
1985               NULL,
1986               WM_OP_EXEC_DEFAULT,
1987               0,
1988               &op_ptr);
1989   RNA_enum_set(&op_ptr, "action", 0); /* SKIN_LOOSE_MARK */
1990   uiItemFullO(row,
1991               "OBJECT_OT_skin_loose_mark_clear",
1992               IFACE_("Clear Loose"),
1993               ICON_NONE,
1994               NULL,
1995               WM_OP_EXEC_DEFAULT,
1996               0,
1997               &op_ptr);
1998   RNA_enum_set(&op_ptr, "action", 1); /* SKIN_LOOSE_CLEAR */
1999 
2000   uiItemO(layout, IFACE_("Mark Root"), ICON_NONE, "OBJECT_OT_skin_root_mark");
2001   uiItemO(layout, IFACE_("Equalize Radii"), ICON_NONE, "OBJECT_OT_skin_radii_equalize");
2002 
2003   modifier_panel_end(layout, ptr);
2004 }
2005 
panelRegister(ARegionType * region_type)2006 static void panelRegister(ARegionType *region_type)
2007 {
2008   modifier_panel_register(region_type, eModifierType_Skin, panel_draw);
2009 }
2010 
2011 ModifierTypeInfo modifierType_Skin = {
2012     /* name */ "Skin",
2013     /* structName */ "SkinModifierData",
2014     /* structSize */ sizeof(SkinModifierData),
2015     /* srna */ &RNA_SkinModifier,
2016     /* type */ eModifierTypeType_Constructive,
2017     /* flags */ eModifierTypeFlag_AcceptsMesh | eModifierTypeFlag_SupportsEditmode,
2018     /* icon */ ICON_MOD_SKIN,
2019 
2020     /* copyData */ BKE_modifier_copydata_generic,
2021 
2022     /* deformVerts */ NULL,
2023     /* deformMatrices */ NULL,
2024     /* deformVertsEM */ NULL,
2025     /* deformMatricesEM */ NULL,
2026     /* modifyMesh */ modifyMesh,
2027     /* modifyHair */ NULL,
2028     /* modifyPointCloud */ NULL,
2029     /* modifyVolume */ NULL,
2030 
2031     /* initData */ initData,
2032     /* requiredDataMask */ requiredDataMask,
2033     /* freeData */ NULL,
2034     /* isDisabled */ NULL,
2035     /* updateDepsgraph */ NULL,
2036     /* dependsOnTime */ NULL,
2037     /* dependsOnNormals */ NULL,
2038     /* foreachIDLink */ NULL,
2039     /* foreachTexLink */ NULL,
2040     /* freeRuntimeData */ NULL,
2041     /* panelRegister */ panelRegister,
2042     /* blendWrite */ NULL,
2043     /* blendRead */ NULL,
2044 };
2045