diff options
-rw-r--r-- | source/blender/blenkernel/BKE_cdderivedmesh.h | 4 | ||||
-rw-r--r-- | source/blender/blenkernel/BKE_mesh.h | 8 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/cdderivedmesh.c | 51 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/displist.c | 4 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/mesh.c | 58 | ||||
-rw-r--r-- | source/blender/makesrna/intern/rna_object_api.c | 38 |
6 files changed, 145 insertions, 18 deletions
diff --git a/source/blender/blenkernel/BKE_cdderivedmesh.h b/source/blender/blenkernel/BKE_cdderivedmesh.h index eeebcdafe48..d7882d8e7ec 100644 --- a/source/blender/blenkernel/BKE_cdderivedmesh.h +++ b/source/blender/blenkernel/BKE_cdderivedmesh.h @@ -61,12 +61,14 @@ DerivedMesh *CDDM_from_BMEditMesh(struct BMEditMesh *em, struct Mesh *me, int us /* merge verts */ DerivedMesh *CDDM_merge_verts(DerivedMesh *dm, const int *vtargetmap); +DerivedMesh *CDDM_from_curve_orco(struct Scene *scene, struct Object *ob); + /* creates a CDDerivedMesh from the given curve object */ struct DerivedMesh *CDDM_from_curve(struct Object *ob); /* creates a CDDerivedMesh from the given curve object and specified dispbase */ /* useful for OrcoDM creation for curves with constructive modifiers */ -DerivedMesh *CDDM_from_curve_displist(struct Object *ob, struct ListBase *dispbase); +DerivedMesh *CDDM_from_curve_displist(struct Object *ob, struct ListBase *dispbase, int **orco_index_ptr); /* Copies the given DerivedMesh with verts, faces & edges stored as * custom element data. diff --git a/source/blender/blenkernel/BKE_mesh.h b/source/blender/blenkernel/BKE_mesh.h index 6fac915d520..b635a37e4f6 100644 --- a/source/blender/blenkernel/BKE_mesh.h +++ b/source/blender/blenkernel/BKE_mesh.h @@ -143,9 +143,13 @@ int BKE_mesh_nurbs_to_mdata(struct Object *ob, struct MVert **allvert, int *tot int *totloop, int *totpoly); int BKE_mesh_nurbs_displist_to_mdata(struct Object *ob, struct ListBase *dispbase, struct MVert **allvert, int *_totvert, struct MEdge **alledge, int *_totedge, struct MLoop **allloop, struct MPoly **allpoly, - int *_totloop, int *_totpoly); + int *_totloop, int *_totpoly, int **orco_index_ptr); +void BKE_mesh_nurbs_to_mdata_orco(struct MPoly *mpoly, int totpoly, + struct MLoop *mloops, struct MLoopUV *mloopuvs, + float (*orco)[3], int (*orco_index)[4]); void BKE_mesh_from_nurbs(struct Object *ob); -void BKE_mesh_from_nurbs_displist(struct Object *ob, struct ListBase *dispbase); +void BKE_mesh_from_nurbs_displist(struct Object *ob, struct ListBase *dispbase, + int **orco_index_ptr); void BKE_mesh_from_curve(struct Scene *scene, struct Object *ob); void free_dverts(struct MDeformVert *dvert, int totvert); void copy_dverts(struct MDeformVert *dst, struct MDeformVert *src, int totvert); /* __NLA */ diff --git a/source/blender/blenkernel/intern/cdderivedmesh.c b/source/blender/blenkernel/intern/cdderivedmesh.c index b19b9db8749..641033a2ec9 100644 --- a/source/blender/blenkernel/intern/cdderivedmesh.c +++ b/source/blender/blenkernel/intern/cdderivedmesh.c @@ -52,6 +52,7 @@ #include "BKE_paint.h" #include "BKE_utildefines.h" #include "BKE_tessmesh.h" +#include "BKE_curve.h" #include "DNA_mesh_types.h" #include "DNA_meshdata_types.h" @@ -1709,11 +1710,51 @@ DerivedMesh *CDDM_from_mesh(Mesh *mesh, Object *UNUSED(ob)) DerivedMesh *CDDM_from_curve(Object *ob) { - return CDDM_from_curve_displist(ob, &ob->disp); + return CDDM_from_curve_displist(ob, &ob->disp, NULL); } -DerivedMesh *CDDM_from_curve_displist(Object *ob, ListBase *dispbase) +DerivedMesh *CDDM_from_curve_orco(struct Scene *scene, Object *ob) { + int *orco_index_ptr = NULL; + int (*orco_index)[4] = NULL; + float (*orco)[3] = NULL; + DerivedMesh *dm = CDDM_from_curve_displist(ob, &ob->disp, &orco_index_ptr); + + if (orco_index_ptr) { + orco = (float (*)[3])BKE_curve_make_orco(scene, ob); + } + + if (orco && orco_index_ptr) { + const char *uvname = "Orco"; + + int totpoly = dm->getNumPolys(dm); + + MPoly *mpolys = dm->getPolyArray(dm); + MLoop *mloops = dm->getLoopArray(dm); + + MLoopUV *mloopuvs; + + CustomData_add_layer_named(&dm->polyData, CD_MTEXPOLY, CD_DEFAULT, NULL, dm->numPolyData, uvname); + mloopuvs = CustomData_add_layer_named(&dm->loopData, CD_MLOOPUV, CD_DEFAULT, NULL, dm->numLoopData, uvname); + + BKE_mesh_nurbs_to_mdata_orco(mpolys, totpoly, + mloops, mloopuvs, + orco, orco_index); + } + + if (orco_index) { + MEM_freeN(orco_index); + } + if (orco) { + MEM_freeN(orco); + } + + return dm; +} + +DerivedMesh *CDDM_from_curve_displist(Object *ob, ListBase *dispbase, int **orco_index_ptr) +{ + const short do_orco_as_uv= 1; DerivedMesh *dm; CDDerivedMesh *cddm; MVert *allvert; @@ -1723,7 +1764,7 @@ DerivedMesh *CDDM_from_curve_displist(Object *ob, ListBase *dispbase) int totvert, totedge, totloop, totpoly; if (BKE_mesh_nurbs_displist_to_mdata(ob, dispbase, &allvert, &totvert, &alledge, - &totedge, &allloop, &allpoly, &totloop, &totpoly) != 0) + &totedge, &allloop, &allpoly, &totloop, &totpoly, orco_index_ptr) != 0) { /* Error initializing mdata. This often happens when curve is empty */ return CDDM_new(0, 0, 0, 0, 0); @@ -1746,6 +1787,10 @@ DerivedMesh *CDDM_from_curve_displist(Object *ob, ListBase *dispbase) CDDM_calc_edges(dm); + if (do_orco_as_uv ) { + BKE_curve_make_orco(NULL, ob); + } + return dm; } diff --git a/source/blender/blenkernel/intern/displist.c b/source/blender/blenkernel/intern/displist.c index 8011efebaac..00a76e87d83 100644 --- a/source/blender/blenkernel/intern/displist.c +++ b/source/blender/blenkernel/intern/displist.c @@ -948,7 +948,7 @@ static void curve_calc_modifiers_post(Scene *scene, Object *ob, ListBase *dispba curve_to_filledpoly(cu, nurb, dispbase); } - dm = CDDM_from_curve_displist(ob, dispbase); + dm = CDDM_from_curve_displist(ob, dispbase, NULL); CDDM_calc_normals_mapping(dm); } @@ -1038,7 +1038,7 @@ static DerivedMesh *create_orco_dm(Scene *scene, Object *ob) /* OrcoDM should be created from underformed disp lists */ BKE_displist_make_curveTypes_forOrco(scene, ob, &disp); - dm = CDDM_from_curve_displist(ob, &disp); + dm = CDDM_from_curve_displist(ob, &disp, NULL); BKE_displist_free(&disp); diff --git a/source/blender/blenkernel/intern/mesh.c b/source/blender/blenkernel/intern/mesh.c index a65c202479e..77cd127e6ea 100644 --- a/source/blender/blenkernel/intern/mesh.c +++ b/source/blender/blenkernel/intern/mesh.c @@ -394,6 +394,7 @@ void BKE_mesh_unlink(Mesh *me) if (me == NULL) return; + if (me->mat) for (a = 0; a < me->totcol; a++) { if (me->mat[a]) me->mat[a]->id.us--; me->mat[a] = NULL; @@ -1234,19 +1235,21 @@ int BKE_mesh_nurbs_to_mdata(Object *ob, MVert **allvert, int *totvert, allvert, totvert, alledge, totedge, allloop, allpoly, - totloop, totpoly); + totloop, totpoly, NULL); } /* BMESH: this doesn't calculate all edges from polygons, * only free standing edges are calculated */ /* Initialize mverts, medges and, faces for converting nurbs to mesh and derived mesh */ -/* use specified dispbase */ +/* use specified dispbase */ +/* TODO: orco values for non DL_SURF types */ int BKE_mesh_nurbs_displist_to_mdata(Object *ob, ListBase *dispbase, MVert **allvert, int *_totvert, MEdge **alledge, int *_totedge, MLoop **allloop, MPoly **allpoly, - int *_totloop, int *_totpoly) + int *_totloop, int *_totpoly, + int **orco_index_ptr) { DispList *dl; Curve *cu; @@ -1258,6 +1261,7 @@ int BKE_mesh_nurbs_displist_to_mdata(Object *ob, ListBase *dispbase, int a, b, ofs, vertcount, startvert, totvert = 0, totedge = 0, totloop = 0, totvlak = 0; int p1, p2, p3, p4, *index; int conv_polys = 0; + int (*orco_index)[4] = NULL; cu = ob->data; @@ -1308,6 +1312,11 @@ int BKE_mesh_nurbs_displist_to_mdata(Object *ob, ListBase *dispbase, /* verts and faces */ vertcount = 0; + if (orco_index_ptr) { + *orco_index_ptr = MEM_callocN(sizeof(int) * totvlak * 4, "nurbs_init orco"); + orco_index = (int (*)[4]) *orco_index_ptr; + } + dl = dispbase->first; while (dl) { int smooth = dl->rt & CU_SMOOTH ? 1 : 0; @@ -1385,8 +1394,6 @@ int BKE_mesh_nurbs_displist_to_mdata(Object *ob, ListBase *dispbase, mloop += 3; index += 3; } - - } else if (dl->type == DL_SURF) { startvert = vertcount; @@ -1431,6 +1438,15 @@ int BKE_mesh_nurbs_displist_to_mdata(Object *ob, ListBase *dispbase, mpoly->totloop = 4; mpoly->mat_nr = dl->col; + if (orco_index) { + const int poly_index = mpoly - *allpoly; + const int p_orco_base = startvert + ((dl->nr + 1) * a) + b; + orco_index[poly_index][0] = p_orco_base + 1; + orco_index[poly_index][1] = p_orco_base + dl->nr + 2; + orco_index[poly_index][2] = p_orco_base + dl->nr + 1; + orco_index[poly_index][3] = p_orco_base; + } + if (smooth) mpoly->flag |= ME_SMOOTH; mpoly++; mloop += 4; @@ -1461,8 +1477,34 @@ int BKE_mesh_nurbs_displist_to_mdata(Object *ob, ListBase *dispbase, return 0; } + +MINLINE void copy_uv_orco_v2_v2(float r[2], const float a[2]) +{ + r[0] = 0.5f + a[0] * 0.5f; + r[1] = 0.5f + a[1] * 0.5f; +} + +/** + * orco is normally from #BKE_curve_make_orco + */ +void BKE_mesh_nurbs_to_mdata_orco(MPoly *mpoly, int totpoly, + MLoop *mloops, MLoopUV *mloopuvs, + float (*orco)[3], int (*orco_index)[4]) +{ + MPoly *mp; + + int i, j; + for (i = 0, mp = mpoly; i < totpoly; i++, mp++) { + MLoop *ml = mloops + mp->loopstart; + MLoopUV *mluv = mloopuvs + mp->loopstart; + for (j = 0; j < mp->totloop; j++, ml++, mluv++) { + copy_uv_orco_v2_v2(mluv->uv, orco[orco_index[i][j]]); + } + } +} + /* this may fail replacing ob->data, be sure to check ob->type */ -void BKE_mesh_from_nurbs_displist(Object *ob, ListBase *dispbase) +void BKE_mesh_from_nurbs_displist(Object *ob, ListBase *dispbase, int **orco_index_ptr) { Main *bmain = G.main; Object *ob1; @@ -1480,7 +1522,7 @@ void BKE_mesh_from_nurbs_displist(Object *ob, ListBase *dispbase) if (dm == NULL) { if (BKE_mesh_nurbs_displist_to_mdata(ob, dispbase, &allvert, &totvert, &alledge, &totedge, &allloop, - &allpoly, &totloop, &totpoly) != 0) + &allpoly, &totloop, &totpoly, orco_index_ptr) != 0) { /* Error initializing */ return; @@ -1536,7 +1578,7 @@ void BKE_mesh_from_nurbs_displist(Object *ob, ListBase *dispbase) void BKE_mesh_from_nurbs(Object *ob) { - BKE_mesh_from_nurbs_displist(ob, &ob->disp); + BKE_mesh_from_nurbs_displist(ob, &ob->disp, NULL); } typedef struct EdgeLink { diff --git a/source/blender/makesrna/intern/rna_object_api.c b/source/blender/makesrna/intern/rna_object_api.c index ae8c331bf1e..0fefc4c89fb 100644 --- a/source/blender/makesrna/intern/rna_object_api.c +++ b/source/blender/makesrna/intern/rna_object_api.c @@ -87,6 +87,10 @@ Mesh *rna_Object_to_mesh(Object *ob, ReportList *reports, Scene *sce, int apply_ case OB_SURF: { ListBase dispbase = {NULL, NULL}; DerivedMesh *derivedFinal = NULL; + int uv_from_orco; + + int (*orco_index)[4] = NULL; + float (*orco)[3] = NULL; /* copies object and modifiers (but not the data) */ tmpobj = BKE_object_copy(ob); @@ -114,7 +118,37 @@ Mesh *rna_Object_to_mesh(Object *ob, ReportList *reports, Scene *sce, int apply_ tmpobj->derivedFinal = derivedFinal; - BKE_mesh_from_nurbs_displist(tmpobj, &dispbase); + uv_from_orco = (tmpcu->flag & CU_UV_ORCO) != 0; + + if (uv_from_orco) { + /* before curve conversion */ + orco = (float (*)[3])BKE_curve_make_orco(sce, tmpobj); + } + + /* convert object type to mesh */ + BKE_mesh_from_nurbs_displist(tmpobj, &dispbase, uv_from_orco ? &orco_index : NULL); + + tmpmesh = tmpobj->data; + + if (uv_from_orco && orco && orco_index) { + const char *uvname = "Orco"; + /* add UV's */ + MTexPoly *mtpoly = CustomData_add_layer_named(&tmpmesh->pdata, CD_MTEXPOLY, CD_DEFAULT, NULL, tmpmesh->totpoly, uvname); + MLoopUV *mloopuvs = CustomData_add_layer_named(&tmpmesh->ldata, CD_MLOOPUV, CD_DEFAULT, NULL, tmpmesh->totloop, uvname); + + BKE_mesh_nurbs_to_mdata_orco(tmpmesh->mpoly, tmpmesh->totpoly, + tmpmesh->mloop, mloopuvs, + orco, orco_index); + + (void)mtpoly; + } + + if (orco_index) { + MEM_freeN(orco_index); + } + if (orco) { + MEM_freeN(orco); + } BKE_displist_free(&dispbase); @@ -124,7 +158,7 @@ Mesh *rna_Object_to_mesh(Object *ob, ReportList *reports, Scene *sce, int apply_ BKE_report(reports, RPT_ERROR, "cant convert curve to mesh. Does the curve have any segments?"); return NULL; } - tmpmesh = tmpobj->data; + BKE_libblock_free_us(&G.main->object, tmpobj); break; } |