Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMartin Felke <martin.felke@googlemail.com>2015-03-17 22:48:03 +0300
committerMartin Felke <martin.felke@googlemail.com>2015-03-17 22:48:03 +0300
commit14a023abddcd27f8084945deb0e7609bebf54d7e (patch)
tree30ac552a0726f4f022ffd1d1e291d10aa3bb153c /source/blender/blenkernel/intern/fracture_util.c
parentd21c1dc1b44c6bd8220a326b0f0bdc6b2bd74883 (diff)
refactoring of FractureModifier: split very long functions into more, shorter ones
Diffstat (limited to 'source/blender/blenkernel/intern/fracture_util.c')
-rw-r--r--source/blender/blenkernel/intern/fracture_util.c747
1 files changed, 406 insertions, 341 deletions
diff --git a/source/blender/blenkernel/intern/fracture_util.c b/source/blender/blenkernel/intern/fracture_util.c
index 8e15f4f3aea..c6ab51a5056 100644
--- a/source/blender/blenkernel/intern/fracture_util.c
+++ b/source/blender/blenkernel/intern/fracture_util.c
@@ -100,11 +100,69 @@ void uv_transform(float uv[][2], int num_uv, float mat[2][2])
}
}
+static void do_unwrap(MPoly *mp, MVert *mvert, MLoop* mloop, int i, MLoopUV **mluv, BoxPack **boxpack)
+{
+ MLoop *ml;
+ int j = 0;
+ float (*verts)[3] = MEM_mallocN(sizeof(float[3]) * mp->totloop, "unwrap_shard_dm verts");
+ float nor[3];
+ float mat[3][3];
+ float (*uv)[2] = MEM_mallocN(sizeof(float[2]) * mp->totloop, "unwrap_shard_dm_uv");
+ BoxPack *box;
+ float uvbbox[2][2];
+ float angle;
+
+ /* uv unwrap cells, so inner faces get a uv map */
+ for (j = 0; j < mp->totloop; j++) {
+ ml = mloop + mp->loopstart + j;
+ copy_v3_v3(verts[j], (mvert + ml->v)->co);
+ }
+
+ normal_poly_v3(nor, (const float (*)[3])verts, mp->totloop);
+ normalize_v3(nor);
+ axis_dominant_v3_to_m3(mat, nor);
+
+ for (j = 0; j < mp->totloop; j++) {
+ mul_v2_m3v3(uv[j], mat, verts[j]);
+ }
+
+ /* rotate uvs for better packing */
+ angle = BLI_convexhull_aabb_fit_points_2d((const float (*)[2])uv, mp->totloop);
+
+ if (angle != 0.0f) {
+ float mat[2][2];
+ angle_to_mat2(mat, angle);
+ uv_transform((float (*)[2])uv, mp->totloop, mat);
+ }
+
+ /* prepare box packing... one poly is a box */
+ box = (*boxpack) + i;
+ uv_bbox((float (*)[2])uv, mp->totloop, uvbbox[0], uvbbox[1]);
+
+ uvbbox[0][0] = -uvbbox[0][0];
+ uvbbox[0][1] = -uvbbox[0][1];
+
+ uv_translate((float (*)[2])uv, mp->totloop, uvbbox[0]);
+
+ box->w = uvbbox[1][0] + uvbbox[0][0];
+ box->h = uvbbox[1][1] + uvbbox[0][1];
+ box->index = i;
+
+ /* copy coords back */
+ for (j = 0; j < mp->totloop; j++) {
+ copy_v2_v2((*mluv)[j + mp->loopstart].uv, uv[j]);
+ (*mluv)[j + mp->loopstart].flag = 0;
+ }
+
+ MEM_freeN(uv);
+ MEM_freeN(verts);
+}
+
void unwrap_shard_dm(DerivedMesh *dm)
{
- MPoly *mpoly, *mp;
- MLoop *mloop;
MVert *mvert;
+ MLoop *mloop;
+ MPoly *mpoly, *mp;
int totpoly, i = 0;
MLoopUV *mluv = MEM_callocN(sizeof(MLoopUV) * dm->numLoopData, "mluv");
BoxPack *boxpack = MEM_mallocN(sizeof(BoxPack) * dm->numPolyData, "boxpack");
@@ -116,60 +174,7 @@ void unwrap_shard_dm(DerivedMesh *dm)
mloop = dm->getLoopArray(dm);
totpoly = dm->getNumPolys(dm);
for (i = 0, mp = mpoly; i < totpoly; i++, mp++) {
- MLoop *ml;
- int j = 0;
- float (*verts)[3] = MEM_mallocN(sizeof(float[3]) * mp->totloop, "unwrap_shard_dm verts");
- float nor[3];
- float mat[3][3];
- float (*uv)[2] = MEM_mallocN(sizeof(float[2]) * mp->totloop, "unwrap_shard_dm_uv");
- BoxPack *box;
- float uvbbox[2][2];
- float angle;
-
- /* uv unwrap cells, so inner faces get a uv map */
- for (j = 0; j < mp->totloop; j++) {
- ml = mloop + mp->loopstart + j;
- copy_v3_v3(verts[j], (mvert + ml->v)->co);
- }
-
- normal_poly_v3(nor, (const float (*)[3])verts, mp->totloop);
- normalize_v3(nor);
- axis_dominant_v3_to_m3(mat, nor);
-
- for (j = 0; j < mp->totloop; j++) {
- mul_v2_m3v3(uv[j], mat, verts[j]);
- }
-
- /* rotate uvs for better packing */
- angle = BLI_convexhull_aabb_fit_points_2d((const float (*)[2])uv, mp->totloop);
-
- if (angle != 0.0f) {
- float mat[2][2];
- angle_to_mat2(mat, angle);
- uv_transform((float (*)[2])uv, mp->totloop, mat);
- }
-
- /* prepare box packing... one poly is a box */
- box = boxpack + i;
- uv_bbox((float (*)[2])uv, mp->totloop, uvbbox[0], uvbbox[1]);
-
- uvbbox[0][0] = -uvbbox[0][0];
- uvbbox[0][1] = -uvbbox[0][1];
-
- uv_translate((float (*)[2])uv, mp->totloop, uvbbox[0]);
-
- box->w = uvbbox[1][0] + uvbbox[0][0];
- box->h = uvbbox[1][1] + uvbbox[0][1];
- box->index = i;
-
- /* copy coords back */
- for (j = 0; j < mp->totloop; j++) {
- copy_v2_v2(mluv[j + mp->loopstart].uv, uv[j]);
- mluv[j + mp->loopstart].flag = 0;
- }
-
- MEM_freeN(uv);
- MEM_freeN(verts);
+ do_unwrap(mp, mvert, mloop, i, &mluv, &boxpack);
}
/* do box packing and match uvs according to it */
@@ -282,217 +287,285 @@ static bool compare_dm_size(DerivedMesh *dmOld, DerivedMesh *dmNew)
return v2 <= (v1 + 0.000001);
}
-Shard *BKE_fracture_shard_boolean(Object *obj, DerivedMesh *dm_parent, Shard *child, short inner_material_index, int num_cuts, float fractal, Shard** other, float mat[4][4], float radius, bool use_smooth_inner, int num_levels)
+static bool do_other_output(DerivedMesh** other_dm, Shard** other, DerivedMesh** output_dm, DerivedMesh** left_dm, float mat[4][4])
{
- Shard *output_s;
- DerivedMesh *left_dm, *right_dm, *output_dm, *other_dm;
- MPoly *mpoly, *mp;
- BMesh* bm = NULL;
- int totpoly, i = 0;
- BMFace* f;
- BMIter iter;
-
- if (other != NULL && mat != NULL)
+ if (*other_dm)
{
- /*create a grid plane */
-
- bm = BM_mesh_create(&bm_mesh_allocsize_default);
- BMO_op_callf(bm, (BMO_FLAG_DEFAULTS & ~BMO_FLAG_RESPECT_HIDE),
- "create_grid x_segments=%i y_segments=%i size=%f matrix=%m4",
- 1, 1, radius*1.4, mat);
+ *other = BKE_create_fracture_shard((*other_dm)->getVertArray(*other_dm),
+ (*other_dm)->getPolyArray(*other_dm),
+ (*other_dm)->getLoopArray(*other_dm),
+ (*other_dm)->getNumVerts(*other_dm),
+ (*other_dm)->getNumPolys(*other_dm),
+ (*other_dm)->getNumLoops(*other_dm),
+ true);
+
+ *other = BKE_custom_data_to_shard(*other, *other_dm);
+
+ #if 0
+ /* XXX TODO this might be wrong by now ... */
+ output_s->neighbor_count = child->neighbor_count;
+ output_s->neighbor_ids = MEM_mallocN(sizeof(int) * child->neighbor_count, __func__);
+ memcpy(output_s->neighbor_ids, child->neighbor_ids, sizeof(int) * child->neighbor_count);
+ #endif
+ BKE_fracture_shard_center_centroid(*other, (*other)->centroid);
- /*subdivide the plane fractally*/
- for (i = 0; i < num_levels; i++)
+ /* free the temp derivedmesh */
+ (*other_dm)->needsFree = 1;
+ (*other_dm)->release(*other_dm);
+ *other_dm = NULL;
+ }
+ else
+ {
+ if (other != NULL)
+ *other = NULL;
+ if (*left_dm != NULL) {
+ (*left_dm)->needsFree = 1;
+ (*left_dm)->release(*left_dm);
+ (*left_dm) = NULL;
+ }
+ if (*other_dm != NULL)
{
- BMO_op_callf(bm,(BMO_FLAG_DEFAULTS & ~BMO_FLAG_RESPECT_HIDE),
- "subdivide_edges edges=ae "
- "smooth=%f smooth_falloff=%i use_smooth_even=%b "
- "fractal=%f along_normal=%f "
- "cuts=%i "
- "quad_corner_type=%i "
- "use_single_edge=%b use_grid_fill=%b "
- "use_only_quads=%b "
- "seed=%i",
- 0.0f, SUBD_FALLOFF_ROOT, false,
- fractal, 1.0f,
- num_cuts,
- SUBD_CORNER_INNERVERT,
- false, true,
- true,
- 0);
+ (*other_dm)->needsFree = 1;
+ (*other_dm)->release(*other_dm);
+ (*other_dm) = NULL;
}
- BMO_op_callf(bm, (BMO_FLAG_DEFAULTS & ~BMO_FLAG_RESPECT_HIDE),
- "recalc_face_normals faces=af");
-
- BM_ITER_MESH(f, &iter, bm, BM_FACES_OF_MESH)
+ /*discard only at fractal boolean */
+ if (mat != NULL)
{
- if (use_smooth_inner)
- {
- BM_elem_flag_enable(f, BM_ELEM_SMOOTH);
- }
-
- if (inner_material_index > 0)
- {
- f->mat_nr = inner_material_index;
+ if (*output_dm != NULL) {
+ (*output_dm)->needsFree = 1;
+ (*output_dm)->release(*output_dm);
+ (*output_dm) = NULL;
}
+ return true;
}
+ }
- /*convert back*/
- left_dm = CDDM_from_bmesh(bm, true);
+ return false;
+}
+
+static Shard *do_output_shard_dm(DerivedMesh** output_dm, Shard *child, int num_cuts, float fractal, Shard **other)
+{
+ Shard* output_s = BKE_create_fracture_shard((*output_dm)->getVertArray(*output_dm),
+ (*output_dm)->getPolyArray(*output_dm),
+ (*output_dm)->getLoopArray(*output_dm),
+ (*output_dm)->getNumVerts(*output_dm),
+ (*output_dm)->getNumPolys(*output_dm),
+ (*output_dm)->getNumLoops(*output_dm),
+ true);
+
+ output_s = BKE_custom_data_to_shard(output_s, *output_dm);
+
+ /* useless, because its a bisect fast-like approach here */
+ if (num_cuts == 0 || fractal == 0.0f || other == NULL) {
+ /* XXX TODO this might be wrong by now ... */
+ output_s->neighbor_count = child->neighbor_count;
+ output_s->neighbor_ids = MEM_mallocN(sizeof(int) * child->neighbor_count, __func__);
+ memcpy(output_s->neighbor_ids, child->neighbor_ids, sizeof(int) * child->neighbor_count);
}
- else
+
+ BKE_fracture_shard_center_centroid(output_s, output_s->centroid);
+
+ /* free the temp derivedmesh */
+ (*output_dm)->needsFree = 1;
+ (*output_dm)->release(*output_dm);
+ *output_dm = NULL;
+
+ return output_s;
+}
+
+static BMesh* do_fractal(float radius, float mat[4][4], bool use_smooth_inner, short inner_material_index,
+ int num_levels, int num_cuts, float fractal, DerivedMesh** left_dm)
+{
+ BMFace* f;
+ BMIter iter;
+ BMesh *bm;
+ int i;
+
+ /*create a grid plane */
+ bm = BM_mesh_create(&bm_mesh_allocsize_default);
+ BMO_op_callf(bm, (BMO_FLAG_DEFAULTS & ~BMO_FLAG_RESPECT_HIDE),
+ "create_grid x_segments=%i y_segments=%i size=%f matrix=%m4",
+ 1, 1, radius*1.4, mat);
+
+ /*subdivide the plane fractally*/
+ for (i = 0; i < num_levels; i++)
{
- left_dm = BKE_shard_create_dm(child, false);
- unwrap_shard_dm(left_dm);
+ BMO_op_callf(bm,(BMO_FLAG_DEFAULTS & ~BMO_FLAG_RESPECT_HIDE),
+ "subdivide_edges edges=ae "
+ "smooth=%f smooth_falloff=%i use_smooth_even=%b "
+ "fractal=%f along_normal=%f "
+ "cuts=%i "
+ "quad_corner_type=%i "
+ "use_single_edge=%b use_grid_fill=%b "
+ "use_only_quads=%b "
+ "seed=%i",
+ 0.0f, SUBD_FALLOFF_ROOT, false,
+ fractal, 1.0f,
+ num_cuts,
+ SUBD_CORNER_INNERVERT,
+ false, true,
+ true,
+ 0);
}
- /* set inner material on child shard */
- if (other == NULL || mat == NULL)
+ BMO_op_callf(bm, (BMO_FLAG_DEFAULTS & ~BMO_FLAG_RESPECT_HIDE),
+ "recalc_face_normals faces=af");
+
+ BM_ITER_MESH(f, &iter, bm, BM_FACES_OF_MESH)
{
- mpoly = left_dm->getPolyArray(left_dm);
- totpoly = left_dm->getNumPolys(left_dm);
- for (i = 0, mp = mpoly; i < totpoly; i++, mp++) {
- if (inner_material_index > 0) {
- mp->mat_nr = inner_material_index;
+ if (use_smooth_inner)
+ {
+ BM_elem_flag_enable(f, BM_ELEM_SMOOTH);
+ }
+
+ if (inner_material_index > 0)
+ {
+ f->mat_nr = inner_material_index;
+ }
+ }
+
+ /*convert back*/
+ *left_dm = CDDM_from_bmesh(bm, true);
+
+ return bm;
+}
+
+static bool do_check_watertight_other(DerivedMesh **other_dm, DerivedMesh **output_dm, Shard **other, DerivedMesh *right_dm,
+ DerivedMesh **left_dm, float mat[4][4])
+{
+ bool do_return = false;
+
+ if (!other_dm || check_non_manifold(*other_dm) || !compare_dm_size(right_dm, *other_dm)) {
+ if (other != NULL)
+ *other = NULL;
+ if (*left_dm != NULL) {
+ (*left_dm)->needsFree = 1;
+ (*left_dm)->release(*left_dm);
+ (*left_dm) = NULL;
+ }
+ if (*other_dm != NULL)
+ {
+ (*other_dm)->needsFree = 1;
+ (*other_dm)->release(*other_dm);
+ (*other_dm) = NULL;
+ }
+
+ /*discard only at fractal boolean */
+ if (mat != NULL)
+ {
+ if (*output_dm != NULL) {
+ (*output_dm)->needsFree = 1;
+ (*output_dm)->release(*output_dm);
+ (*output_dm) = NULL;
}
- mp->flag |= ME_FACE_SEL;
+ do_return = true;
}
}
- right_dm = dm_parent;
- output_dm = NewBooleanDerivedMesh(right_dm, obj, left_dm, obj, 1); /*1 == intersection, 3 == difference*/
+ return do_return;
+}
- /*check for watertightness*/
- if (!output_dm || check_non_manifold(output_dm) || !compare_dm_size(right_dm, output_dm)) {
+static bool do_check_watertight(DerivedMesh **output_dm, BMesh** bm, DerivedMesh** left_dm, DerivedMesh *right_dm, Shard **other, float mat[4][4])
+{
+ bool do_return = false;
+
+ if (!(*output_dm) || check_non_manifold(*output_dm) || !compare_dm_size(right_dm, (*output_dm))) {
if (mat != NULL)
{
if (other != NULL)
*other = NULL;
- if (bm != NULL)
- BM_mesh_free(bm);
+ if (*bm != NULL) {
+ BM_mesh_free(*bm);
+ *bm = NULL;
+ }
- if (left_dm != NULL) {
- left_dm->needsFree = 1;
- left_dm->release(left_dm);
- left_dm = NULL;
+ if (*left_dm != NULL) {
+ (*left_dm)->needsFree = 1;
+ (*left_dm)->release(*left_dm);
+ *left_dm = NULL;
}
}
- if (output_dm != NULL) {
- output_dm->needsFree = 1;
- output_dm->release(output_dm);
- output_dm = NULL;
+ if (*output_dm != NULL) {
+ (*output_dm)->needsFree = 1;
+ (*output_dm)->release(*output_dm);
+ *output_dm = NULL;
}
if (mat != NULL)
{
- return NULL;
+ do_return = true;
}
}
- if (other != NULL)
- {
+ return do_return;
+}
-#if 0
- if (bm == NULL)
- {
- bm = DM_to_bmesh(left_dm, true);
+static void do_set_inner_material(Shard **other, float mat[4][4], DerivedMesh* left_dm, short inner_material_index)
+{
+ MPoly *mpoly, *mp;
+ int totpoly, i = 0;
+
+ /* set inner material on child shard */
+ if (other == NULL || mat == NULL)
+ {
+ mpoly = left_dm->getPolyArray(left_dm);
+ totpoly = left_dm->getNumPolys(left_dm);
+ for (i = 0, mp = mpoly; i < totpoly; i++, mp++) {
+ if (inner_material_index > 0) {
+ mp->mat_nr = inner_material_index;
+ }
+ mp->flag |= ME_FACE_SEL;
}
+ }
+}
- BMO_op_callf(bm, (BMO_FLAG_DEFAULTS & ~BMO_FLAG_RESPECT_HIDE),
- "reverse_faces faces=af");
+Shard *BKE_fracture_shard_boolean(Object *obj, DerivedMesh *dm_parent, Shard *child, short inner_material_index,
+ int num_cuts, float fractal, Shard** other, float mat[4][4], float radius, bool use_smooth_inner, int num_levels)
+{
+ DerivedMesh *left_dm = NULL, *right_dm, *output_dm, *other_dm;
+ BMesh* bm = NULL;
- left_dm->needsFree = 1;
- left_dm->release(left_dm);
- left_dm = NULL;
+ if (other != NULL && mat != NULL)
+ {
+ do_fractal(radius, mat, use_smooth_inner, inner_material_index, num_levels, num_cuts, fractal, &left_dm);
+ }
+ else
+ {
+ left_dm = BKE_shard_create_dm(child, false);
+ unwrap_shard_dm(left_dm);
+ }
- left_dm = CDDM_from_bmesh(bm, true);
-#endif
+ do_set_inner_material(other, mat, left_dm, inner_material_index);
+
+ right_dm = dm_parent;
+ output_dm = NewBooleanDerivedMesh(right_dm, obj, left_dm, obj, 1); /*1 == intersection, 3 == difference*/
+
+ /*check for watertightness*/
+ if (do_check_watertight(&output_dm, &bm, &left_dm, right_dm, other, mat))
+ {
+ return NULL;
+ }
+
+ if (other != NULL)
+ {
if (bm != NULL)
BM_mesh_free(bm);
other_dm = NewBooleanDerivedMesh(left_dm, obj, right_dm, obj, 3);
- /*check for watertightness again*/
- if (!other_dm || check_non_manifold(other_dm) || !compare_dm_size(right_dm, other_dm)) {
- if (other != NULL)
- *other = NULL;
- if (left_dm != NULL) {
- left_dm->needsFree = 1;
- left_dm->release(left_dm);
- left_dm = NULL;
- }
- if (other_dm != NULL)
- {
- other_dm->needsFree = 1;
- other_dm->release(other_dm);
- other_dm = NULL;
- }
-
- /*discard only at fractal boolean */
- if (mat != NULL)
- {
- if (output_dm != NULL) {
- output_dm->needsFree = 1;
- output_dm->release(output_dm);
- output_dm = NULL;
- }
- return NULL;
- }
- }
-
- if (other_dm)
+ /*check for watertightness again, true means do return NULL here*/
+ if (do_check_watertight_other(&other_dm, &output_dm, other, right_dm, &left_dm, mat))
{
- *other = BKE_create_fracture_shard(other_dm->getVertArray(other_dm),
- other_dm->getPolyArray(other_dm),
- other_dm->getLoopArray(other_dm),
- other_dm->getNumVerts(other_dm),
- other_dm->getNumPolys(other_dm),
- other_dm->getNumLoops(other_dm),
- true);
-
- *other = BKE_custom_data_to_shard(*other, other_dm);
-
-#if 0
- /* XXX TODO this might be wrong by now ... */
- output_s->neighbor_count = child->neighbor_count;
- output_s->neighbor_ids = MEM_mallocN(sizeof(int) * child->neighbor_count, __func__);
- memcpy(output_s->neighbor_ids, child->neighbor_ids, sizeof(int) * child->neighbor_count);
-#endif
- BKE_fracture_shard_center_centroid(*other, (*other)->centroid);
-
- /* free the temp derivedmesh */
- other_dm->needsFree = 1;
- other_dm->release(other_dm);
- other_dm = NULL;
+ return NULL;
}
- else
- {
- if (other != NULL)
- *other = NULL;
- if (left_dm != NULL) {
- left_dm->needsFree = 1;
- left_dm->release(left_dm);
- left_dm = NULL;
- }
- if (other_dm != NULL)
- {
- other_dm->needsFree = 1;
- other_dm->release(other_dm);
- other_dm = NULL;
- }
- /*discard only at fractal boolean */
- if (mat != NULL)
- {
- if (output_dm != NULL) {
- output_dm->needsFree = 1;
- output_dm->release(output_dm);
- output_dm = NULL;
- }
- return NULL;
- }
+ /*return here if this function returns true */
+ if (do_other_output(&other_dm, other, &output_dm, &left_dm, mat))
+ {
+ return NULL;
}
}
@@ -505,47 +578,111 @@ Shard *BKE_fracture_shard_boolean(Object *obj, DerivedMesh *dm_parent, Shard *ch
if (output_dm)
{
- output_s = BKE_create_fracture_shard(output_dm->getVertArray(output_dm),
- output_dm->getPolyArray(output_dm),
- output_dm->getLoopArray(output_dm),
- output_dm->getNumVerts(output_dm),
- output_dm->getNumPolys(output_dm),
- output_dm->getNumLoops(output_dm),
- true);
-
- output_s = BKE_custom_data_to_shard(output_s, output_dm);
-
- /* useless, because its a bisect fast-like approach here */
- if (num_cuts == 0 || fractal == 0.0f || other == NULL) {
- /* XXX TODO this might be wrong by now ... */
- output_s->neighbor_count = child->neighbor_count;
- output_s->neighbor_ids = MEM_mallocN(sizeof(int) * child->neighbor_count, __func__);
- memcpy(output_s->neighbor_ids, child->neighbor_ids, sizeof(int) * child->neighbor_count);
- }
+ return do_output_shard_dm(&output_dm, child, num_cuts, fractal, other);
+ }
- BKE_fracture_shard_center_centroid(output_s, output_s->centroid);
+ return NULL;
+}
- /* free the temp derivedmesh */
- output_dm->needsFree = 1;
- output_dm->release(output_dm);
- output_dm = NULL;
+static Shard *do_output_shard(BMesh* bm_parent, Shard *child)
+{
+ Shard *output_s = NULL;
+ DerivedMesh *dm_out;
+
+ if (bm_parent->totvert >= 3)
+ { /* atleast 3 verts form a face, so strip out invalid stuff */
+ dm_out = CDDM_from_bmesh(bm_parent, true);
+ output_s = BKE_create_fracture_shard(dm_out->getVertArray(dm_out),
+ dm_out->getPolyArray(dm_out),
+ dm_out->getLoopArray(dm_out),
+ dm_out->getNumVerts(dm_out),
+ dm_out->getNumPolys(dm_out),
+ dm_out->getNumLoops(dm_out), true);
+
+ output_s = BKE_custom_data_to_shard(output_s, dm_out);
- return output_s;
+ /*XXX TODO this might be wrong by now ... */
+ output_s->neighbor_count = child->neighbor_count;
+ output_s->neighbor_ids = MEM_mallocN(sizeof(int) * child->neighbor_count, __func__);
+ memcpy(output_s->neighbor_ids, child->neighbor_ids, sizeof(int) * child->neighbor_count);
+ BKE_fracture_shard_center_centroid(output_s, output_s->centroid);
+
+ dm_out->needsFree = 1;
+ dm_out->release(dm_out);
+ dm_out = NULL;
}
- return NULL;
+ return output_s;
}
-
-Shard *BKE_fracture_shard_bisect(BMesh *bm_orig, Shard *child, float obmat[4][4], bool use_fill, bool clear_inner,
- bool clear_outer, int cutlimit, float centroid[3], short inner_mat_index)
+static void do_fill(float plane_no[3], bool clear_outer, bool clear_inner, BMOperator bmop, short inner_mat_index, BMesh* bm_parent)
{
+ float normal_fill[3];
+ BMOperator bmop_fill;
+ BMOperator bmop_attr;
- Shard *output_s;
- DerivedMesh *dm_child = BKE_shard_create_dm(child, false);
- DerivedMesh *dm_out;
- BMesh *bm_parent = BM_mesh_copy(bm_orig);
- BMesh *bm_child;
+ normalize_v3_v3(normal_fill, plane_no);
+ if (clear_outer == true && clear_inner == false) {
+ negate_v3(normal_fill);
+ }
+
+ /* Fill, XXX attempted different fill algorithms here, needs further thoughts because none really suited */
+#if 0
+ BMO_op_initf(bm_parent, &bmop_fill, (BMO_FLAG_DEFAULTS & ~BMO_FLAG_RESPECT_HIDE),
+ "contextual_create geom=%S mat_nr=%i use_smooth=%b",
+ &bmop, "geom_cut.out", 0, false);
+ BMO_op_exec(bm_parent, &bmop_fill);
+
+ BMO_op_initf(bm_parent, &bmop_attr, (BMO_FLAG_DEFAULTS & ~BMO_FLAG_RESPECT_HIDE),
+ "face_attribute_fill faces=%S use_normals=%b use_data=%b",
+ &bmop_fill, "faces.out", false, true);
+ BMO_op_exec(bm_parent, &bmop_attr);
+
+ BMO_op_initf(bm_parent, &bmop_del, (BMO_FLAG_DEFAULTS & ~BMO_FLAG_RESPECT_HIDE),
+ "delete geom=%S context=%i", &bmop_fill, "edges.out", DEL_EDGESFACES);
+ BMO_op_exec(bm_parent, &bmop_del);
+
+ BMO_slot_buffer_hflag_enable(bm_parent, bmop_fill.slots_out, "faces.out", BM_FACE, BM_ELEM_TAG, true);
+#endif
+
+ if (inner_mat_index == 0) { /* dont use inner material here*/
+ BMO_op_initf(
+ bm_parent, &bmop_fill, (BMO_FLAG_DEFAULTS & ~BMO_FLAG_RESPECT_HIDE),
+ "triangle_fill edges=%S normal=%v use_dissolve=%b use_beauty=%b",
+ &bmop, "geom_cut.out", normal_fill, true, true);
+ BMO_op_exec(bm_parent, &bmop_fill);
+
+ BMO_op_initf(bm_parent, &bmop_attr, (BMO_FLAG_DEFAULTS & ~BMO_FLAG_RESPECT_HIDE),
+ "face_attribute_fill faces=%S use_normals=%b use_data=%b",
+ &bmop_fill, "geom.out", false, true);
+ BMO_op_exec(bm_parent, &bmop_attr);
+
+ BMO_slot_buffer_hflag_enable(bm_parent, bmop_fill.slots_out, "geom.out", BM_FACE, BM_ELEM_TAG | BM_ELEM_SELECT, true);
+ }
+ else {
+ /* use edgenet fill with inner material */
+ BMO_op_initf(
+ bm_parent, &bmop_fill, (BMO_FLAG_DEFAULTS & ~BMO_FLAG_RESPECT_HIDE),
+ "edgenet_fill edges=%S mat_nr=%i use_smooth=%b sides=%i",
+ &bmop, "geom_cut.out", inner_mat_index, false, 2);
+ BMO_op_exec(bm_parent, &bmop_fill);
+
+ /* Copy Attributes */
+ BMO_op_initf(bm_parent, &bmop_attr, (BMO_FLAG_DEFAULTS & ~BMO_FLAG_RESPECT_HIDE),
+ "face_attribute_fill faces=%S use_normals=%b use_data=%b",
+ &bmop_fill, "faces.out", true, false);
+ BMO_op_exec(bm_parent, &bmop_attr);
+
+ BMO_slot_buffer_hflag_enable(bm_parent, bmop_fill.slots_out, "faces.out", BM_FACE, BM_ELEM_TAG | BM_ELEM_SELECT, true);
+ }
+
+ BMO_op_finish(bm_parent, &bmop_attr);
+ BMO_op_finish(bm_parent, &bmop_fill);
+}
+
+static void do_bisect(BMesh* bm_parent, BMesh* bm_child, float obmat[4][4], bool use_fill, bool clear_inner,
+ bool clear_outer, int cutlimit, float centroid[3], short inner_mat_index)
+{
BMIter iter;
BMFace *f;
@@ -558,14 +695,8 @@ Shard *BKE_fracture_shard_bisect(BMesh *bm_orig, Shard *child, float obmat[4][4]
bool do_break = false;
int cut_index = 0;
-
- unwrap_shard_dm(dm_child);
- bm_child = DM_to_bmesh(dm_child, true);
-
invert_m4_m4(imat, obmat);
- BM_mesh_elem_hflag_enable_all(bm_parent, BM_VERT | BM_EDGE | BM_FACE, BM_ELEM_TAG, false);
-
BM_ITER_MESH_INDEX (f, &iter, bm_child, BM_FACES_OF_MESH, cut_index)
{
if (do_break) {
@@ -596,100 +727,36 @@ Shard *BKE_fracture_shard_bisect(BMesh *bm_orig, Shard *child, float obmat[4][4]
BM_mesh_elem_hflag_disable_all(bm_parent, BM_VERT | BM_EDGE | BM_FACE, BM_ELEM_TAG, false);
if (use_fill) {
- float normal_fill[3];
- BMOperator bmop_fill;
- BMOperator bmop_attr;
-
- normalize_v3_v3(normal_fill, plane_no);
- if (clear_outer == true && clear_inner == false) {
- negate_v3(normal_fill);
- }
-
- /* Fill, XXX attempted different fill algorithms here, needs further thoughts because none really suited */
-#if 0
- BMO_op_initf(bm_parent, &bmop_fill, (BMO_FLAG_DEFAULTS & ~BMO_FLAG_RESPECT_HIDE),
- "contextual_create geom=%S mat_nr=%i use_smooth=%b",
- &bmop, "geom_cut.out", 0, false);
- BMO_op_exec(bm_parent, &bmop_fill);
-
- BMO_op_initf(bm_parent, &bmop_attr, (BMO_FLAG_DEFAULTS & ~BMO_FLAG_RESPECT_HIDE),
- "face_attribute_fill faces=%S use_normals=%b use_data=%b",
- &bmop_fill, "faces.out", false, true);
- BMO_op_exec(bm_parent, &bmop_attr);
+ do_fill(plane_no, clear_outer, clear_inner, bmop, inner_mat_index, bm_parent);
+ }
- BMO_op_initf(bm_parent, &bmop_del, (BMO_FLAG_DEFAULTS & ~BMO_FLAG_RESPECT_HIDE),
- "delete geom=%S context=%i", &bmop_fill, "edges.out", DEL_EDGESFACES);
- BMO_op_exec(bm_parent, &bmop_del);
+ BMO_slot_buffer_hflag_enable(bm_parent, bmop.slots_out, "geom_cut.out", BM_VERT | BM_EDGE, BM_ELEM_TAG, true);
- BMO_slot_buffer_hflag_enable(bm_parent, bmop_fill.slots_out, "faces.out", BM_FACE, BM_ELEM_TAG, true);
-#endif
+ BMO_op_finish(bm_parent, &bmop);
+ }
+}
- if (inner_mat_index == 0) { /* dont use inner material here*/
- BMO_op_initf(
- bm_parent, &bmop_fill, (BMO_FLAG_DEFAULTS & ~BMO_FLAG_RESPECT_HIDE),
- "triangle_fill edges=%S normal=%v use_dissolve=%b use_beauty=%b",
- &bmop, "geom_cut.out", normal_fill, true, true);
- BMO_op_exec(bm_parent, &bmop_fill);
- BMO_op_initf(bm_parent, &bmop_attr, (BMO_FLAG_DEFAULTS & ~BMO_FLAG_RESPECT_HIDE),
- "face_attribute_fill faces=%S use_normals=%b use_data=%b",
- &bmop_fill, "geom.out", false, true);
- BMO_op_exec(bm_parent, &bmop_attr);
+Shard *BKE_fracture_shard_bisect(BMesh *bm_orig, Shard *child, float obmat[4][4], bool use_fill, bool clear_inner,
+ bool clear_outer, int cutlimit, float centroid[3], short inner_mat_index)
+{
- BMO_slot_buffer_hflag_enable(bm_parent, bmop_fill.slots_out, "geom.out", BM_FACE, BM_ELEM_TAG | BM_ELEM_SELECT, true);
- }
- else {
- /* use edgenet fill with inner material */
- BMO_op_initf(
- bm_parent, &bmop_fill, (BMO_FLAG_DEFAULTS & ~BMO_FLAG_RESPECT_HIDE),
- "edgenet_fill edges=%S mat_nr=%i use_smooth=%b sides=%i",
- &bmop, "geom_cut.out", inner_mat_index, false, 2);
- BMO_op_exec(bm_parent, &bmop_fill);
-
- /* Copy Attributes */
- BMO_op_initf(bm_parent, &bmop_attr, (BMO_FLAG_DEFAULTS & ~BMO_FLAG_RESPECT_HIDE),
- "face_attribute_fill faces=%S use_normals=%b use_data=%b",
- &bmop_fill, "faces.out", true, false);
- BMO_op_exec(bm_parent, &bmop_attr);
-
- BMO_slot_buffer_hflag_enable(bm_parent, bmop_fill.slots_out, "faces.out", BM_FACE, BM_ELEM_TAG | BM_ELEM_SELECT, true);
- }
+ Shard *output_s;
+ DerivedMesh *dm_child = BKE_shard_create_dm(child, false);
- BMO_op_finish(bm_parent, &bmop_attr);
- BMO_op_finish(bm_parent, &bmop_fill);
- }
+ BMesh *bm_parent = BM_mesh_copy(bm_orig);
+ BMesh *bm_child;
- BMO_slot_buffer_hflag_enable(bm_parent, bmop.slots_out, "geom_cut.out", BM_VERT | BM_EDGE, BM_ELEM_TAG, true);
- BMO_op_finish(bm_parent, &bmop);
- }
+ unwrap_shard_dm(dm_child);
+ bm_child = DM_to_bmesh(dm_child, true);
- if (bm_parent->totvert >= 3)
- { /* atleast 3 verts form a face, so strip out invalid stuff */
- dm_out = CDDM_from_bmesh(bm_parent, true);
- output_s = BKE_create_fracture_shard(dm_out->getVertArray(dm_out),
- dm_out->getPolyArray(dm_out),
- dm_out->getLoopArray(dm_out),
- dm_out->getNumVerts(dm_out),
- dm_out->getNumPolys(dm_out),
- dm_out->getNumLoops(dm_out), true);
- output_s = BKE_custom_data_to_shard(output_s, dm_out);
+ BM_mesh_elem_hflag_enable_all(bm_parent, BM_VERT | BM_EDGE | BM_FACE, BM_ELEM_TAG, false);
- /*XXX TODO this might be wrong by now ... */
- output_s->neighbor_count = child->neighbor_count;
- output_s->neighbor_ids = MEM_mallocN(sizeof(int) * child->neighbor_count, __func__);
- memcpy(output_s->neighbor_ids, child->neighbor_ids, sizeof(int) * child->neighbor_count);
- BKE_fracture_shard_center_centroid(output_s, output_s->centroid);
+ do_bisect(bm_parent, bm_child, obmat, use_fill, clear_inner, clear_outer, cutlimit, centroid, inner_mat_index);
- dm_out->needsFree = 1;
- dm_out->release(dm_out);
- dm_out = NULL;
- }
- else
- {
- output_s = NULL;
- }
+ output_s = do_output_shard(bm_parent, child);
BM_mesh_free(bm_child);
BM_mesh_free(bm_parent);
@@ -698,7 +765,5 @@ Shard *BKE_fracture_shard_bisect(BMesh *bm_orig, Shard *child, float obmat[4][4]
dm_child->release(dm_child);
dm_child = NULL;
-
-
return output_s;
}