From f0bf1f57f68023ba6a73ce10ad8afc066a8b4cb1 Mon Sep 17 00:00:00 2001 From: Martin Felke Date: Thu, 4 Apr 2019 15:08:19 +0200 Subject: attempt to fix inner uv for fractal boolean --- source/blender/blenkernel/BKE_fracture.h | 1 + source/blender/blenkernel/intern/fracture.c | 7 +++ source/blender/blenkernel/intern/fracture_util.c | 64 ++++++++++++++++++++---- 3 files changed, 61 insertions(+), 11 deletions(-) diff --git a/source/blender/blenkernel/BKE_fracture.h b/source/blender/blenkernel/BKE_fracture.h index b28b25f54f2..850a5708dc3 100644 --- a/source/blender/blenkernel/BKE_fracture.h +++ b/source/blender/blenkernel/BKE_fracture.h @@ -190,5 +190,6 @@ void BKE_fracture_meshislands_connect(struct Scene* scene, struct FractureModifi struct Shard* mi, struct Shard* mi2, short con_type, float thresh); void BKE_fracture_shard_velocity_ensure(struct Shard* mi); +void BKE_fracture_copy_inner_uv(struct Mesh *dm, char uv_layer[64], int inner_material_index); #endif /* BKE_FRACTURE_H */ diff --git a/source/blender/blenkernel/intern/fracture.c b/source/blender/blenkernel/intern/fracture.c index 732ffac6197..dfbd2e83b80 100644 --- a/source/blender/blenkernel/intern/fracture.c +++ b/source/blender/blenkernel/intern/fracture.c @@ -965,6 +965,13 @@ void BKE_fracture_postprocess_meshisland(FractureModifierData *fmd, Object* ob, result->id = last_id + j; result->rigidbody->flag = mi->rigidbody->flag; + /* inner UV handling... */ + if (fmd->uvlayer_name[0]) + { + BKE_fracture_copy_inner_uv(result->mesh, fmd->uvlayer_name, + BKE_object_material_slot_find_index(ob, fmd->inner_material) - 1); + } + /* dont forget copying over the neighborhood info, we expose this to python so it might be useful */ if ((i < count) && shards && shards[i]) { result->neighbor_count = shards[i]->neighbor_count; diff --git a/source/blender/blenkernel/intern/fracture_util.c b/source/blender/blenkernel/intern/fracture_util.c index 1c3c9bd5e2f..1f94367a83d 100644 --- a/source/blender/blenkernel/intern/fracture_util.c +++ b/source/blender/blenkernel/intern/fracture_util.c @@ -104,24 +104,31 @@ void uv_transform(float uv[][2], int num_uv, float mat[2][2]) } } -static void do_clean_uv(Mesh *dm, char uv_layer[64]) +void BKE_fracture_copy_inner_uv(Mesh *dm, char uv_layer[64], int inner_material_index) { - MLoopUV* mluv = CustomData_get_layer_named(&dm->ldata, CD_MLOOPUV, uv_layer); + MLoopUV* mluv = CustomData_get_layer_named(&dm->ldata, CD_MLOOPUV, "UVMap"); + MLoopUV* inner_uv = CustomData_get_layer_named(&dm->ldata, CD_MLOOPUV, uv_layer); int i, totpoly = dm->totpoly; MPoly *mp, *mpoly = dm->mpoly; - if (mluv) + if (mluv && inner_uv) { for (i = 0, mp = mpoly; i < totpoly; i++, mp++) { - if (mp->mat_nr != 1) - { //clean up (set uv coords to zero) all except inner faces (material based) - int j; - for (j = mp->loopstart; j < mp->loopstart + mp->totloop; j++) - { + int j; + for (j = mp->loopstart; j < mp->loopstart + mp->totloop; j++) + { + if (mp->mat_nr == inner_material_index) + { //copy and clean (set uv coords to zero) all inner faces (material based) + inner_uv[j].uv[0] = mluv[j].uv[0]; + inner_uv[j].uv[1] = mluv[j].uv[1]; mluv[j].uv[0] = 0.0f; mluv[j].uv[1] = 0.0f; } + else { + inner_uv[j].uv[0] = 0.0f; + inner_uv[j].uv[1] = 0.0f; + } } } } @@ -307,11 +314,13 @@ static bool compare_size(Mesh *result, Mesh *check) static Mesh* do_fractal(BooleanContext *ctx) { - BMFace* f; - BMIter iter; + BMLoop* l; + BMFace* f, *efa; + BMIter iter, liter, fiter; BMesh *bm; int i; Mesh *ret = NULL; + MLoopUV *mluv; /*create a grid plane */ bm = BM_mesh_create(&bm_mesh_allocsize_default, &((struct BMeshCreateParams){.use_toolflags = true,})); @@ -319,6 +328,39 @@ static Mesh* do_fractal(BooleanContext *ctx) "create_grid x_segments=%i y_segments=%i size=%f matrix=%m4", 1, 1, ctx->cutter_plane_radius, ctx->cutter_plane_matrix); + /* uv unwrap */ + mluv = MEM_callocN(sizeof(MLoopUV) * bm->totloop, "mluv_cutter"); + + BM_mesh_elem_toolflags_ensure(bm); + CustomData_bmesh_init_pool(&bm->vdata, bm->totloop, BM_VERT); + CustomData_bmesh_init_pool(&bm->edata, bm->totedge, BM_EDGE); + CustomData_bmesh_init_pool(&bm->ldata, bm->totloop, BM_LOOP); + CustomData_bmesh_init_pool(&bm->pdata, bm->totface, BM_FACE); + + BM_data_layer_add(bm, &bm->ldata, CD_MLOOPUV); + + /* should be 4 loops, since its just a quad / plane */ + mluv[0].uv[0] = 0.0f; + mluv[0].uv[1] = 0.0f; + + mluv[1].uv[0] = 1.0f; + mluv[1].uv[1] = 0.0f; + + mluv[2].uv[0] = 1.0f; + mluv[2].uv[1] = 1.0f; + + mluv[3].uv[0] = 0.0f; + mluv[3].uv[1] = 1.0f; + + BM_ITER_MESH (efa, &fiter, bm, BM_FACES_OF_MESH) { + BM_ITER_ELEM_INDEX (l, &liter, efa, BM_LOOPS_OF_FACE, i) { + MLoopUV *uv = CustomData_bmesh_get(&bm->ldata, ((BMHeader *)l)->data, CD_MLOOPUV); + if (uv) *uv = mluv[i]; + } + } + + MEM_freeN(mluv); + /*subdivide the plane fractally*/ for (i = 0; i < ctx->num_iterations; i++) { @@ -444,7 +486,7 @@ void BKE_fracture_mesh_boolean_fractal(Mesh* geometry, Mesh **outputA, Mesh** ou { Mesh* cutter = do_fractal(ctx); /* dont do fancy boxpacking of uv here, the uv of the fractal surface takes ages to process else */ - uv_unwrap_raw_geometry(cutter, ctx->uv_layer, false); + //uv_unwrap_raw_geometry(cutter, ctx->uv_layer, false); do_set_inner_material(cutter, ctx->inner_material_index, obj); /* first intersect, then difference with the cutter on inverted positions*/ -- cgit v1.2.3