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:
authorCampbell Barton <ideasman42@gmail.com>2012-02-05 15:30:26 +0400
committerCampbell Barton <ideasman42@gmail.com>2012-02-05 15:30:26 +0400
commit543fb27fd0a54287b32f3d2c0066c10a120a596d (patch)
treee50dd87a0ffb2abab73d3293dd126e2b2922b05a /source/blender/blenkernel/intern
parent059a4b508527d094bd456f49d7f18c75c5e72d33 (diff)
support for 'origspace' data layer - used for hair on subsurf mesh.
currently only works for 3/4 sided faces.
Diffstat (limited to 'source/blender/blenkernel/intern')
-rw-r--r--source/blender/blenkernel/intern/DerivedMesh.c53
-rw-r--r--source/blender/blenkernel/intern/customdata.c84
-rw-r--r--source/blender/blenkernel/intern/mesh.c22
-rw-r--r--source/blender/blenkernel/intern/particle.c10
-rw-r--r--source/blender/blenkernel/intern/particle_system.c2
-rw-r--r--source/blender/blenkernel/intern/subsurf_ccg.c33
6 files changed, 177 insertions, 27 deletions
diff --git a/source/blender/blenkernel/intern/DerivedMesh.c b/source/blender/blenkernel/intern/DerivedMesh.c
index 939fe2caa17..ec7780eed5d 100644
--- a/source/blender/blenkernel/intern/DerivedMesh.c
+++ b/source/blender/blenkernel/intern/DerivedMesh.c
@@ -562,6 +562,11 @@ void *DM_get_poly_data_layer(DerivedMesh *dm, int type)
return CustomData_get_layer(&dm->polyData, type);
}
+void *DM_get_loop_data_layer(DerivedMesh *dm, int type)
+{
+ return CustomData_get_layer(&dm->loopData, type);
+}
+
void DM_set_vert_data(DerivedMesh *dm, int index, int type, void *data)
{
CustomData_set(&dm->vertData, index, type, data);
@@ -1504,9 +1509,12 @@ static void mesh_calc_modifiers(Scene *scene, Object *ob, float (*inputVertexCos
add_orco_dm(ob, NULL, dm, clothorcodm, CD_CLOTH_ORCO);
/* add an origspace layer if needed */
- if(((CustomDataMask)GET_INT_FROM_POINTER(curr->link)) & CD_MASK_ORIGSPACE)
- if(!CustomData_has_layer(&dm->faceData, CD_ORIGSPACE))
- DM_add_tessface_layer(dm, CD_ORIGSPACE, CD_DEFAULT, NULL);
+ if(((CustomDataMask)GET_INT_FROM_POINTER(curr->link)) & CD_MASK_ORIGSPACE_MLOOP) {
+ if(!CustomData_has_layer(&dm->loopData, CD_ORIGSPACE_MLOOP)) {
+ DM_add_loop_layer(dm, CD_ORIGSPACE_MLOOP, CD_CALLOC, NULL);
+ DM_init_origspace(dm);
+ }
+ }
ndm = mti->applyModifier(md, ob, dm, useRenderParams, useCache);
@@ -1825,9 +1833,12 @@ static void editbmesh_calc_modifiers(Scene *scene, Object *ob, BMEditMesh *em, D
DM_set_only_copy(dm, mask | CD_MASK_ORIGINDEX);
- if(mask & CD_MASK_ORIGSPACE)
- if(!CustomData_has_layer(&dm->faceData, CD_ORIGSPACE))
- DM_add_tessface_layer(dm, CD_ORIGSPACE, CD_DEFAULT, NULL);
+ if(mask & CD_MASK_ORIGSPACE_MLOOP) {
+ if(!CustomData_has_layer(&dm->loopData, CD_ORIGSPACE_MLOOP)) {
+ DM_add_loop_layer(dm, CD_ORIGSPACE_MLOOP, CD_CALLOC, NULL);
+ DM_init_origspace(dm);
+ }
+ }
if (mti->applyModifierEM)
ndm = mti->applyModifierEM(md, ob, em, dm);
@@ -2859,6 +2870,30 @@ static DerivedMesh *navmesh_dm_createNavMeshForVisualization(DerivedMesh *dm)
/* --- NAVMESH (end) --- */
+void DM_init_origspace(DerivedMesh *dm)
+{
+ static float default_osf[4][2] = {{0, 0}, {1, 0}, {1, 1}, {0, 1}};
+
+ OrigSpaceLoop *lof_array = CustomData_get_layer(&dm->loopData, CD_ORIGSPACE_MLOOP);
+ OrigSpaceLoop *lof;
+ const int numpoly = dm->getNumPolys(dm);
+ // const int numloop = dm->getNumLoops(dm);
+ MPoly *mp = dm->getPolyArray(dm);
+ int i, j;
+
+ for (i = 0; i < numpoly; i++, mp++) {
+ /* only quads/tri's for now */
+ if (mp->totloop == 3 || mp->totloop == 4) {
+ lof = lof_array + mp->loopstart;
+ for (j = 0; j < mp->totloop; j++, lof++) {
+ copy_v2_v2(lof->uv, default_osf[j]);
+ }
+ }
+ }
+}
+
+
+
/* derivedmesh info printing function,
* to help track down differences DM output */
@@ -2910,6 +2945,10 @@ char *DM_debug_info(DerivedMesh *dm)
dm_debug_info_layers(dynstr, dm, dm->getVertDataArray);
BLI_dynstr_appendf(dynstr, " ),\n");
+ BLI_dynstr_appendf(dynstr, " 'loopLayers': (\n");
+ dm_debug_info_layers(dynstr, dm, DM_get_loop_data_layer);
+ BLI_dynstr_appendf(dynstr, " ),\n");
+
BLI_dynstr_appendf(dynstr, " 'edgeLayers': (\n");
dm_debug_info_layers(dynstr, dm, dm->getEdgeDataArray);
BLI_dynstr_appendf(dynstr, " ),\n");
@@ -2918,7 +2957,7 @@ char *DM_debug_info(DerivedMesh *dm)
dm_debug_info_layers(dynstr, dm, dm->getTessFaceDataArray);
BLI_dynstr_appendf(dynstr, " ),\n");
- BLI_dynstr_appendf(dynstr, " 'PolyLayers': (\n");
+ BLI_dynstr_appendf(dynstr, " 'polyLayers': (\n");
dm_debug_info_layers(dynstr, dm, DM_get_poly_data_layer);
BLI_dynstr_appendf(dynstr, " ),\n");
diff --git a/source/blender/blenkernel/intern/customdata.c b/source/blender/blenkernel/intern/customdata.c
index 4dbb143a73e..b7066dbcd84 100644
--- a/source/blender/blenkernel/intern/customdata.c
+++ b/source/blender/blenkernel/intern/customdata.c
@@ -871,6 +871,77 @@ static void layerInterp_mloopuv(void **sources, float *weights,
}
}
+/* origspace is almost exact copy of mloopuv's, keep in sync */
+static void layerCopyValue_mloop_origspace(void *source, void *dest)
+{
+ OrigSpaceLoop *luv1 = source, *luv2 = dest;
+
+ copy_v2_v2(luv2->uv, luv1->uv);
+}
+
+static int layerEqual_mloop_origspace(void *data1, void *data2)
+{
+ OrigSpaceLoop *luv1 = data1, *luv2 = data2;
+
+ return len_squared_v2v2(luv1->uv, luv2->uv) < 0.00001f;
+}
+
+static void layerMultiply_mloop_origspace(void *data, float fac)
+{
+ OrigSpaceLoop *luv = data;
+
+ mul_v2_fl(luv->uv, fac);
+}
+
+static void layerInitMinMax_mloop_origspace(void *vmin, void *vmax)
+{
+ OrigSpaceLoop *min = vmin, *max = vmax;
+
+ INIT_MINMAX2(min->uv, max->uv);
+}
+
+static void layerDoMinMax_mloop_origspace(void *data, void *vmin, void *vmax)
+{
+ OrigSpaceLoop *min = vmin, *max = vmax, *luv = data;
+
+ DO_MINMAX2(luv->uv, min->uv, max->uv);
+}
+
+static void layerAdd_mloop_origspace(void *data1, void *data2)
+{
+ OrigSpaceLoop *l1 = data1, *l2 = data2;
+
+ add_v2_v2(l1->uv, l2->uv);
+}
+
+static void layerInterp_mloop_origspace(void **sources, float *weights,
+ float *sub_weights, int count, void *dest)
+{
+ OrigSpaceLoop *mluv = dest;
+ float *uv= mluv->uv;
+ int i;
+
+ zero_v2(uv);
+
+ if (sub_weights) {
+ const float *sub_weight = sub_weights;
+ for(i = 0; i < count; i++) {
+ float weight = weights ? weights[i] : 1.0f;
+ OrigSpaceLoop *src = sources[i];
+ madd_v2_v2fl(uv, src->uv, (*sub_weight) * weight);
+ sub_weight++;
+ }
+ }
+ else {
+ for(i = 0; i < count; i++) {
+ float weight = weights ? weights[i] : 1;
+ OrigSpaceLoop *src = sources[i];
+ madd_v2_v2fl(uv, src->uv, weight);
+ }
+ }
+}
+/* --- end copy */
+
static void layerInterp_mcol(void **sources, float *weights,
float *sub_weights, int count, void *dest)
{
@@ -1079,7 +1150,11 @@ static const LayerTypeInfo LAYERTYPEINFO[CD_NUMTYPES] = {
{sizeof(float), "", 0, "BevelWeight", NULL, NULL, layerInterp_bweight},
/* 30: CD_CREASE */
{sizeof(float), "", 0, "SubSurfCrease", NULL, NULL, layerInterp_bweight},
- /* 31: CD_WEIGHT_MLOOPCOL */
+ /* 31: CD_ORIGSPACE_MLOOP */
+ {sizeof(OrigSpaceLoop), "OrigSpaceLoop", 1, "OS Loop", NULL, NULL, layerInterp_mloop_origspace, NULL, NULL,
+ layerEqual_mloop_origspace, layerMultiply_mloop_origspace, layerInitMinMax_mloop_origspace,
+ layerAdd_mloop_origspace, layerDoMinMax_mloop_origspace, layerCopyValue_mloop_origspace},
+ /* 32: CD_WEIGHT_MLOOPCOL */
{sizeof(MLoopCol), "MLoopCol", 1, "WeightLoopCol", NULL, NULL, layerInterp_mloopcol, NULL,
layerDefault_mloopcol, layerEqual_mloopcol, layerMultiply_mloopcol, layerInitMinMax_mloopcol,
layerAdd_mloopcol, layerDoMinMax_mloopcol, layerCopyValue_mloopcol},
@@ -1100,7 +1175,7 @@ static const char *LAYERTYPENAMES[CD_NUMTYPES] = {
/* BMESH ONLY */
,
/* 25-29 */ "CDMPoly", "CDMLoop", "CDShapeKeyIndex", "CDShapeKey", "CDBevelWeight",
- /* 30-31 */ "CDSubSurfCrease", "CDWeightLoopCol"
+ /* 30-32 */ "CDSubSurfCrease", "CDOrigSpaceLoop", "CDWeightLoopCol"
/* END BMESH ONLY */
};
@@ -1123,7 +1198,7 @@ const CustomDataMask CD_MASK_DERIVEDMESH =
CD_MASK_MSTICKY | CD_MASK_MDEFORMVERT | CD_MASK_MTFACE |
CD_MASK_MCOL | CD_MASK_PROP_FLT | CD_MASK_PROP_INT | CD_MASK_CLOTH_ORCO |
CD_MASK_MLOOPUV | CD_MASK_MLOOPCOL | CD_MASK_MTEXPOLY | CD_MASK_WEIGHT_MLOOPCOL |
- CD_MASK_PROP_STR | CD_MASK_ORIGSPACE | CD_MASK_ORCO | CD_MASK_TANGENT |
+ CD_MASK_PROP_STR | CD_MASK_ORIGSPACE | CD_MASK_ORIGSPACE_MLOOP | CD_MASK_ORCO | CD_MASK_TANGENT |
CD_MASK_WEIGHT_MCOL | CD_MASK_NORMAL | CD_MASK_SHAPEKEY | CD_MASK_RECAST |
CD_MASK_ORIGINDEX | CD_MASK_POLYINDEX;
const CustomDataMask CD_MASK_BMESH = CD_MASK_MLOOPUV | CD_MASK_MLOOPCOL | CD_MASK_MTEXPOLY |
@@ -2395,6 +2470,9 @@ void CustomData_from_bmeshpoly(CustomData *fdata, CustomData *pdata, CustomData
else if (ldata->layers[i].type == CD_WEIGHT_MLOOPCOL) {
CustomData_add_layer_named(fdata, CD_WEIGHT_MCOL, CD_CALLOC, NULL, total, ldata->layers[i].name);
}
+ else if (ldata->layers[i].type == CD_ORIGSPACE_MLOOP) {
+ CustomData_add_layer_named(fdata, CD_ORIGSPACE, CD_CALLOC, NULL, total, ldata->layers[i].name);
+ }
}
}
diff --git a/source/blender/blenkernel/intern/mesh.c b/source/blender/blenkernel/intern/mesh.c
index 7f217eb8e62..2a78bbca7fb 100644
--- a/source/blender/blenkernel/intern/mesh.c
+++ b/source/blender/blenkernel/intern/mesh.c
@@ -2177,7 +2177,8 @@ void mesh_loops_to_mface_corners(CustomData *fdata, CustomData *ldata,
/* cache values to avoid lookups every time */
const int numTex, /* CustomData_number_of_layers(pdata, CD_MTEXPOLY) */
const int numCol, /* CustomData_number_of_layers(ldata, CD_MLOOPCOL) */
- const int hasWCol /* CustomData_has_layer(ldata, CD_WEIGHT_MLOOPCOL) */
+ const int hasWCol, /* CustomData_has_layer(ldata, CD_WEIGHT_MLOOPCOL) */
+ const int hasOrigSpace /* CustomData_has_layer(ldata, CD_ORIGSPACE_MLOOP) */
)
{
MTFace *texface;
@@ -2228,6 +2229,17 @@ void mesh_loops_to_mface_corners(CustomData *fdata, CustomData *ldata,
mcol[j].a = mloopcol->a;
}
}
+
+ if (hasOrigSpace) {
+ OrigSpaceFace *of = CustomData_get(fdata, findex, CD_ORIGSPACE);
+ OrigSpaceLoop *lof;
+
+ for (j=0; j < mf_len; j++) {
+ lof = CustomData_get(ldata, lindex[j], CD_ORIGSPACE_MLOOP);
+ of->uv[j][0] = lof->uv[0];
+ of->uv[j][1] = lof->uv[1];
+ }
+ }
}
/*
@@ -2269,6 +2281,7 @@ int mesh_recalcTesselation(CustomData *fdata,
const int numTex = CustomData_number_of_layers(pdata, CD_MTEXPOLY);
const int numCol = CustomData_number_of_layers(ldata, CD_MLOOPCOL);
const int hasWCol = CustomData_has_layer(ldata, CD_WEIGHT_MLOOPCOL);
+ const int hasOrigSpace = CustomData_has_layer(ldata, CD_ORIGSPACE_MLOOP);
mpoly = CustomData_get_layer(pdata, CD_MPOLY);
mloop = CustomData_get_layer(ldata, CD_MLOOP);
@@ -2493,7 +2506,7 @@ int mesh_recalcTesselation(CustomData *fdata,
#else
3,
#endif
- numTex, numCol, hasWCol);
+ numTex, numCol, hasWCol, hasOrigSpace);
#ifdef USE_TESSFACE_QUADS
@@ -2531,6 +2544,7 @@ int mesh_mpoly_to_mface(struct CustomData *fdata, struct CustomData *ldata,
const int numTex = CustomData_number_of_layers(pdata, CD_MTEXPOLY);
const int numCol = CustomData_number_of_layers(ldata, CD_MLOOPCOL);
const int hasWCol = CustomData_has_layer(ldata, CD_WEIGHT_MLOOPCOL);
+ const int hasOrigSpace = CustomData_has_layer(ldata, CD_ORIGSPACE_MLOOP);
mpoly = CustomData_get_layer(pdata, CD_MPOLY);
mloop = CustomData_get_layer(ldata, CD_MLOOP);
@@ -2588,7 +2602,7 @@ int mesh_mpoly_to_mface(struct CustomData *fdata, struct CustomData *ldata,
mesh_loops_to_mface_corners(fdata, ldata, pdata,
lindex, k, i, 3,
- numTex, numCol, hasWCol);
+ numTex, numCol, hasWCol, hasOrigSpace);
test_index_face(mf, fdata, k, 3);
}
else {
@@ -2608,7 +2622,7 @@ int mesh_mpoly_to_mface(struct CustomData *fdata, struct CustomData *ldata,
mesh_loops_to_mface_corners(fdata, ldata, pdata,
lindex, k, i, 4,
- numTex, numCol, hasWCol);
+ numTex, numCol, hasWCol, hasOrigSpace);
test_index_face(mf, fdata, k, 4);
}
diff --git a/source/blender/blenkernel/intern/particle.c b/source/blender/blenkernel/intern/particle.c
index 98413d79358..ec3f71e6713 100644
--- a/source/blender/blenkernel/intern/particle.c
+++ b/source/blender/blenkernel/intern/particle.c
@@ -1587,13 +1587,13 @@ static void psys_origspace_to_w(OrigSpaceFace *osface, int quad, const float w[4
int psys_particle_dm_face_lookup(Object *ob, DerivedMesh *dm, int index, const float fw[4], struct LinkNode *node)
{
Mesh *me= (Mesh*)ob->data;
- MFace *mface;
+ MPoly *mface;
OrigSpaceFace *osface;
int *origindex;
int quad, findex, totface;
float uv[2], (*faceuv)[2];
- mface = dm->getTessFaceDataArray(dm, CD_MFACE);
+ mface = dm->getPolyArray(dm);
origindex = dm->getTessFaceDataArray(dm, CD_ORIGINDEX);
osface = dm->getTessFaceDataArray(dm, CD_ORIGSPACE);
@@ -1609,7 +1609,7 @@ int psys_particle_dm_face_lookup(Object *ob, DerivedMesh *dm, int index, const f
return DMCACHE_NOTFOUND;
}
}
- else if(index >= me->totface)
+ else if(index >= me->totpoly)
return DMCACHE_NOTFOUND; /* index not in the original mesh */
psys_w_to_origspace(fw, uv);
@@ -1618,7 +1618,7 @@ int psys_particle_dm_face_lookup(Object *ob, DerivedMesh *dm, int index, const f
for(;node; node=node->next) {
findex= GET_INT_FROM_POINTER(node->link);
faceuv= osface[findex].uv;
- quad= mface[findex].v4;
+ quad = (mface[findex].totloop == 4);
/* check that this intersects - Its possible this misses :/ -
* could also check its not between */
@@ -1634,7 +1634,7 @@ int psys_particle_dm_face_lookup(Object *ob, DerivedMesh *dm, int index, const f
for(findex=0; findex<totface; findex++) {
if(origindex[findex] == index) {
faceuv= osface[findex].uv;
- quad= mface[findex].v4;
+ quad = (mface[findex].totloop == 4);
/* check that this intersects - Its possible this misses :/ -
* could also check its not between */
diff --git a/source/blender/blenkernel/intern/particle_system.c b/source/blender/blenkernel/intern/particle_system.c
index 5356615b122..75bf89fb032 100644
--- a/source/blender/blenkernel/intern/particle_system.c
+++ b/source/blender/blenkernel/intern/particle_system.c
@@ -353,7 +353,7 @@ void psys_calc_dmcache(Object *ob, DerivedMesh *dm, ParticleSystem *psys)
}
else { /* FROM_FACE/FROM_VOLUME */
totdmelem= dm->getNumTessFaces(dm);
- totelem= me->totface;
+ totelem= me->totpoly;
origindex= dm->getTessFaceDataArray(dm, CD_ORIGINDEX);
}
diff --git a/source/blender/blenkernel/intern/subsurf_ccg.c b/source/blender/blenkernel/intern/subsurf_ccg.c
index 7f2aa947db5..3352766a859 100644
--- a/source/blender/blenkernel/intern/subsurf_ccg.c
+++ b/source/blender/blenkernel/intern/subsurf_ccg.c
@@ -2388,7 +2388,7 @@ static void ccgDM_release(DerivedMesh *dm) {
static void ccg_loops_to_corners(CustomData *fdata, CustomData *ldata,
CustomData *pdata, int loopstart, int findex, int polyindex,
- const int numTex, const int numCol, const int hasWCol)
+ const int numTex, const int numCol, const int hasWCol, const int hasOrigSpace)
{
MTFace *texface;
MTexPoly *texpoly;
@@ -2438,6 +2438,17 @@ static void ccg_loops_to_corners(CustomData *fdata, CustomData *ldata,
mcol[j].a = mloopcol->a;
}
}
+
+ if (hasOrigSpace) {
+ OrigSpaceFace *of = CustomData_get(fdata, findex, CD_ORIGSPACE);
+ OrigSpaceLoop *lof;
+
+ lof = CustomData_get(ldata, loopstart, CD_ORIGSPACE_MLOOP);
+ for (j=0; j<4; j++, lof++) {
+ of->uv[j][0] = lof->uv[0];
+ of->uv[j][1] = lof->uv[1];
+ }
+ }
}
static void *ccgDM_get_vert_data_layer(DerivedMesh *dm, int type)
@@ -2855,7 +2866,8 @@ static CCGDerivedMesh *getCCGDerivedMesh(CCGSubSurf *ss,
int gridFaces, gridCuts;
/*int gridSideVerts;*/
int gridSideEdges;
- int numTex, numCol, hasWCol;
+ int numTex, numCol;
+ int hasWCol, hasOrigSpace;
int gridInternalEdges;
float *w = NULL;
WeightTable wtable = {0};
@@ -2874,11 +2886,18 @@ static CCGDerivedMesh *getCCGDerivedMesh(CCGSubSurf *ss,
numTex = CustomData_number_of_layers(&ccgdm->dm.loopData, CD_MLOOPUV);
numCol = CustomData_number_of_layers(&ccgdm->dm.loopData, CD_MLOOPCOL);
hasWCol = CustomData_has_layer(&ccgdm->dm.loopData, CD_WEIGHT_MLOOPCOL);
+ hasOrigSpace = CustomData_has_layer(&ccgdm->dm.loopData, CD_ORIGSPACE_MLOOP);
- if (numTex && CustomData_number_of_layers(&ccgdm->dm.faceData, CD_MTFACE) != numTex)
- CustomData_from_bmeshpoly(&ccgdm->dm.faceData, &ccgdm->dm.polyData, &ccgdm->dm.loopData, ccgSubSurf_getNumFinalFaces(ss));
- else if (numCol && CustomData_number_of_layers(&ccgdm->dm.faceData, CD_MCOL) != numCol)
- CustomData_from_bmeshpoly(&ccgdm->dm.faceData, &ccgdm->dm.polyData, &ccgdm->dm.loopData, ccgSubSurf_getNumFinalFaces(ss));
+ if (
+ (numTex && CustomData_number_of_layers(&ccgdm->dm.faceData, CD_MTFACE) != numTex) ||
+ (numCol && CustomData_number_of_layers(&ccgdm->dm.faceData, CD_MCOL) != numCol) ||
+ (hasOrigSpace && !CustomData_has_layer(&ccgdm->dm.faceData, CD_ORIGSPACE)) )
+ {
+ CustomData_from_bmeshpoly(&ccgdm->dm.faceData,
+ &ccgdm->dm.polyData,
+ &ccgdm->dm.loopData,
+ ccgSubSurf_getNumFinalFaces(ss));
+ }
ccgdm->dm.getMinMax = ccgDM_getMinMax;
ccgdm->dm.getNumVerts = ccgDM_getNumVerts;
@@ -3143,7 +3162,7 @@ static CCGDerivedMesh *getCCGDerivedMesh(CCGSubSurf *ss,
/*generate tesselated face data used for drawing*/
ccg_loops_to_corners(&ccgdm->dm.faceData, &ccgdm->dm.loopData,
&ccgdm->dm.polyData, loopindex2-4, faceNum, faceNum,
- numTex, numCol, hasWCol);
+ numTex, numCol, hasWCol, hasOrigSpace);
/*set original index data*/
if (faceOrigIndex) {