support for curve orco uv's as UV's in cycles.

ideally these would be used as generated coordinates, but this is tricly because cycles calculates its own orco's and doesnt know about curve settings.
This commit is contained in:
2012-07-31 13:43:26 +00:00
parent e7e7972cd6
commit 8f6197bd08
6 changed files with 145 additions and 18 deletions

View File

@@ -61,12 +61,14 @@ DerivedMesh *CDDM_from_BMEditMesh(struct BMEditMesh *em, struct Mesh *me, int us
/* merge verts */ /* merge verts */
DerivedMesh *CDDM_merge_verts(DerivedMesh *dm, const int *vtargetmap); 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 */ /* creates a CDDerivedMesh from the given curve object */
struct DerivedMesh *CDDM_from_curve(struct Object *ob); struct DerivedMesh *CDDM_from_curve(struct Object *ob);
/* creates a CDDerivedMesh from the given curve object and specified dispbase */ /* creates a CDDerivedMesh from the given curve object and specified dispbase */
/* useful for OrcoDM creation for curves with constructive modifiers */ /* 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 /* Copies the given DerivedMesh with verts, faces & edges stored as
* custom element data. * custom element data.

View File

@@ -143,9 +143,13 @@ int BKE_mesh_nurbs_to_mdata(struct Object *ob, struct MVert **allvert, int *tot
int *totloop, int *totpoly); int *totloop, int *totpoly);
int BKE_mesh_nurbs_displist_to_mdata(struct Object *ob, struct ListBase *dispbase, struct MVert **allvert, int *_totvert, 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, 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(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 BKE_mesh_from_curve(struct Scene *scene, struct Object *ob);
void free_dverts(struct MDeformVert *dvert, int totvert); void free_dverts(struct MDeformVert *dvert, int totvert);
void copy_dverts(struct MDeformVert *dst, struct MDeformVert *src, int totvert); /* __NLA */ void copy_dverts(struct MDeformVert *dst, struct MDeformVert *src, int totvert); /* __NLA */

View File

@@ -52,6 +52,7 @@
#include "BKE_paint.h" #include "BKE_paint.h"
#include "BKE_utildefines.h" #include "BKE_utildefines.h"
#include "BKE_tessmesh.h" #include "BKE_tessmesh.h"
#include "BKE_curve.h"
#include "DNA_mesh_types.h" #include "DNA_mesh_types.h"
#include "DNA_meshdata_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) 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; DerivedMesh *dm;
CDDerivedMesh *cddm; CDDerivedMesh *cddm;
MVert *allvert; MVert *allvert;
@@ -1723,7 +1764,7 @@ DerivedMesh *CDDM_from_curve_displist(Object *ob, ListBase *dispbase)
int totvert, totedge, totloop, totpoly; int totvert, totedge, totloop, totpoly;
if (BKE_mesh_nurbs_displist_to_mdata(ob, dispbase, &allvert, &totvert, &alledge, 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 */ /* Error initializing mdata. This often happens when curve is empty */
return CDDM_new(0, 0, 0, 0, 0); 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); CDDM_calc_edges(dm);
if (do_orco_as_uv ) {
BKE_curve_make_orco(NULL, ob);
}
return dm; return dm;
} }

View File

@@ -948,7 +948,7 @@ static void curve_calc_modifiers_post(Scene *scene, Object *ob, ListBase *dispba
curve_to_filledpoly(cu, nurb, dispbase); 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); 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 */ /* OrcoDM should be created from underformed disp lists */
BKE_displist_make_curveTypes_forOrco(scene, ob, &disp); 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); BKE_displist_free(&disp);

View File

@@ -394,6 +394,7 @@ void BKE_mesh_unlink(Mesh *me)
if (me == NULL) return; if (me == NULL) return;
if (me->mat)
for (a = 0; a < me->totcol; a++) { for (a = 0; a < me->totcol; a++) {
if (me->mat[a]) me->mat[a]->id.us--; if (me->mat[a]) me->mat[a]->id.us--;
me->mat[a] = NULL; me->mat[a] = NULL;
@@ -1234,19 +1235,21 @@ int BKE_mesh_nurbs_to_mdata(Object *ob, MVert **allvert, int *totvert,
allvert, totvert, allvert, totvert,
alledge, totedge, alledge, totedge,
allloop, allpoly, allloop, allpoly,
totloop, totpoly); totloop, totpoly, NULL);
} }
/* BMESH: this doesn't calculate all edges from polygons, /* BMESH: this doesn't calculate all edges from polygons,
* only free standing edges are calculated */ * only free standing edges are calculated */
/* Initialize mverts, medges and, faces for converting nurbs to mesh and derived mesh */ /* 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, int BKE_mesh_nurbs_displist_to_mdata(Object *ob, ListBase *dispbase,
MVert **allvert, int *_totvert, MVert **allvert, int *_totvert,
MEdge **alledge, int *_totedge, MEdge **alledge, int *_totedge,
MLoop **allloop, MPoly **allpoly, MLoop **allloop, MPoly **allpoly,
int *_totloop, int *_totpoly) int *_totloop, int *_totpoly,
int **orco_index_ptr)
{ {
DispList *dl; DispList *dl;
Curve *cu; 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 a, b, ofs, vertcount, startvert, totvert = 0, totedge = 0, totloop = 0, totvlak = 0;
int p1, p2, p3, p4, *index; int p1, p2, p3, p4, *index;
int conv_polys = 0; int conv_polys = 0;
int (*orco_index)[4] = NULL;
cu = ob->data; cu = ob->data;
@@ -1308,6 +1312,11 @@ int BKE_mesh_nurbs_displist_to_mdata(Object *ob, ListBase *dispbase,
/* verts and faces */ /* verts and faces */
vertcount = 0; 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; dl = dispbase->first;
while (dl) { while (dl) {
int smooth = dl->rt & CU_SMOOTH ? 1 : 0; 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; mloop += 3;
index += 3; index += 3;
} }
} }
else if (dl->type == DL_SURF) { else if (dl->type == DL_SURF) {
startvert = vertcount; startvert = vertcount;
@@ -1431,6 +1438,15 @@ int BKE_mesh_nurbs_displist_to_mdata(Object *ob, ListBase *dispbase,
mpoly->totloop = 4; mpoly->totloop = 4;
mpoly->mat_nr = dl->col; 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; if (smooth) mpoly->flag |= ME_SMOOTH;
mpoly++; mpoly++;
mloop += 4; mloop += 4;
@@ -1461,8 +1477,34 @@ int BKE_mesh_nurbs_displist_to_mdata(Object *ob, ListBase *dispbase,
return 0; 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 */ /* 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; Main *bmain = G.main;
Object *ob1; Object *ob1;
@@ -1480,7 +1522,7 @@ void BKE_mesh_from_nurbs_displist(Object *ob, ListBase *dispbase)
if (dm == NULL) { if (dm == NULL) {
if (BKE_mesh_nurbs_displist_to_mdata(ob, dispbase, &allvert, &totvert, if (BKE_mesh_nurbs_displist_to_mdata(ob, dispbase, &allvert, &totvert,
&alledge, &totedge, &allloop, &alledge, &totedge, &allloop,
&allpoly, &totloop, &totpoly) != 0) &allpoly, &totloop, &totpoly, orco_index_ptr) != 0)
{ {
/* Error initializing */ /* Error initializing */
return; return;
@@ -1536,7 +1578,7 @@ void BKE_mesh_from_nurbs_displist(Object *ob, ListBase *dispbase)
void BKE_mesh_from_nurbs(Object *ob) 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 { typedef struct EdgeLink {

View File

@@ -87,6 +87,10 @@ Mesh *rna_Object_to_mesh(Object *ob, ReportList *reports, Scene *sce, int apply_
case OB_SURF: { case OB_SURF: {
ListBase dispbase = {NULL, NULL}; ListBase dispbase = {NULL, NULL};
DerivedMesh *derivedFinal = 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) */ /* copies object and modifiers (but not the data) */
tmpobj = BKE_object_copy(ob); 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; 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); 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?"); BKE_report(reports, RPT_ERROR, "cant convert curve to mesh. Does the curve have any segments?");
return NULL; return NULL;
} }
tmpmesh = tmpobj->data;
BKE_libblock_free_us(&G.main->object, tmpobj); BKE_libblock_free_us(&G.main->object, tmpobj);
break; break;
} }