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:
Diffstat (limited to 'source/blender/blenkernel')
-rw-r--r--source/blender/blenkernel/BKE_DerivedMesh.h1
-rw-r--r--source/blender/blenkernel/BKE_mesh.h2
-rw-r--r--source/blender/blenkernel/BKE_multires.h7
-rw-r--r--source/blender/blenkernel/intern/DerivedMesh.c180
-rw-r--r--source/blender/blenkernel/intern/cdderivedmesh.c14
-rw-r--r--source/blender/blenkernel/intern/customdata.c3
-rw-r--r--source/blender/blenkernel/intern/mesh_evaluate.c46
-rw-r--r--source/blender/blenkernel/intern/multires.c30
8 files changed, 212 insertions, 71 deletions
diff --git a/source/blender/blenkernel/BKE_DerivedMesh.h b/source/blender/blenkernel/BKE_DerivedMesh.h
index 6b331980df5..f331bcb1ac5 100644
--- a/source/blender/blenkernel/BKE_DerivedMesh.h
+++ b/source/blender/blenkernel/BKE_DerivedMesh.h
@@ -615,6 +615,7 @@ void DM_ensure_looptri_data(DerivedMesh *dm);
void DM_ensure_looptri(DerivedMesh *dm);
void DM_update_tessface_data(DerivedMesh *dm);
+void DM_generate_tangent_tessface_data(DerivedMesh *dm, bool generate);
void DM_update_materials(DerivedMesh *dm, struct Object *ob);
struct MLoopUV *DM_paint_uvlayer_active_get(DerivedMesh *dm, int mat_nr);
diff --git a/source/blender/blenkernel/BKE_mesh.h b/source/blender/blenkernel/BKE_mesh.h
index b20bca71c6d..12330698131 100644
--- a/source/blender/blenkernel/BKE_mesh.h
+++ b/source/blender/blenkernel/BKE_mesh.h
@@ -287,6 +287,8 @@ void BKE_mesh_loops_to_mface_corners(
void BKE_mesh_loops_to_tessdata(
struct CustomData *fdata, struct CustomData *ldata, struct CustomData *pdata, struct MFace *mface,
int *polyindices, unsigned int (*loopindices)[4], const int num_faces);
+void BKE_mesh_tangent_loops_to_tessdata(struct CustomData *fdata, struct CustomData *ldata, struct MFace *mface,
+ int *polyindices, unsigned int (*loopindices)[4], const int num_faces);
int BKE_mesh_recalc_tessellation(
struct CustomData *fdata, struct CustomData *ldata, struct CustomData *pdata,
struct MVert *mvert,
diff --git a/source/blender/blenkernel/BKE_multires.h b/source/blender/blenkernel/BKE_multires.h
index a8242a529f3..178751d1640 100644
--- a/source/blender/blenkernel/BKE_multires.h
+++ b/source/blender/blenkernel/BKE_multires.h
@@ -42,6 +42,11 @@ struct MultiresModifierData;
struct Object;
struct Scene;
+struct MLoop;
+struct MVert;
+struct MPoly;
+struct MLoopTri;
+
/* Delete mesh mdisps and grid paint masks */
void multires_customdata_delete(struct Mesh *me);
@@ -114,6 +119,6 @@ void multires_topology_changed(struct Mesh *me);
/**** interpolation stuff ****/
void old_mdisps_bilinear(float out[3], float (*disps)[3], const int st, float u, float v);
-int mdisp_rot_face_to_crn(const int corners, const int face_side, const float u, const float v, float *x, float *y);
+int mdisp_rot_face_to_crn(struct MVert *mvert, struct MPoly *mpoly, struct MLoop *mloops, const struct MLoopTri *lt, const int face_side, const float u, const float v, float *x, float *y);
#endif /* __BKE_MULTIRES_H__ */
diff --git a/source/blender/blenkernel/intern/DerivedMesh.c b/source/blender/blenkernel/intern/DerivedMesh.c
index 0b1b4310ca4..3156eb391b8 100644
--- a/source/blender/blenkernel/intern/DerivedMesh.c
+++ b/source/blender/blenkernel/intern/DerivedMesh.c
@@ -521,7 +521,8 @@ void DM_update_tessface_data(DerivedMesh *dm)
CustomData_has_layer(fdata, CD_MCOL) ||
CustomData_has_layer(fdata, CD_PREVIEW_MCOL) ||
CustomData_has_layer(fdata, CD_ORIGSPACE) ||
- CustomData_has_layer(fdata, CD_TESSLOOPNORMAL))
+ CustomData_has_layer(fdata, CD_TESSLOOPNORMAL) ||
+ CustomData_has_layer(fdata, CD_TANGENT))
{
loopindex = MEM_mallocN(sizeof(*loopindex) * totface, __func__);
@@ -557,6 +558,69 @@ void DM_update_tessface_data(DerivedMesh *dm)
dm->dirty &= ~DM_DIRTY_TESS_CDLAYERS;
}
+void DM_generate_tangent_tessface_data(DerivedMesh *dm, bool generate)
+{
+ int i;
+ MFace *mf, *mface = dm->getTessFaceArray(dm);
+ MPoly *mp = dm->getPolyArray(dm);
+ MLoop *ml = dm->getLoopArray(dm);
+
+ CustomData *fdata = dm->getTessFaceDataLayout(dm);
+ CustomData *pdata = dm->getPolyDataLayout(dm);
+ CustomData *ldata = dm->getLoopDataLayout(dm);
+
+ const int totface = dm->getNumTessFaces(dm);
+ int mf_idx;
+
+ int *polyindex = CustomData_get_layer(fdata, CD_ORIGINDEX);
+ unsigned int (*loopindex)[4];
+
+ /* Should never occure, but better abort than segfault! */
+ if (!polyindex)
+ return;
+
+ CustomData_from_bmeshpoly(fdata, pdata, ldata, totface);
+
+ if (generate) {
+ for (i = 0; i < ldata->totlayer; i++) {
+ if (ldata->layers[i].type == CD_TANGENT)
+ CustomData_add_layer_named(fdata, CD_TANGENT, CD_CALLOC, NULL, totface, ldata->layers[i].name);
+ }
+ CustomData_bmesh_update_active_layers(fdata, pdata, ldata);
+ }
+
+ loopindex = MEM_mallocN(sizeof(*loopindex) * totface, __func__);
+
+ for (mf_idx = 0, mf = mface; mf_idx < totface; mf_idx++, mf++) {
+ const int mf_len = mf->v4 ? 4 : 3;
+ unsigned int *ml_idx = loopindex[mf_idx];
+ int i, not_done;
+
+ /* Find out loop indices. */
+ /* NOTE: This assumes tessface are valid and in sync with loop/poly... Else, most likely, segfault! */
+ for (i = mp[polyindex[mf_idx]].loopstart, not_done = mf_len; not_done; i++) {
+ const int tf_v = BKE_MESH_TESSFACE_VINDEX_ORDER(mf, ml[i].v);
+ if (tf_v != -1) {
+ ml_idx[tf_v] = i;
+ not_done--;
+ }
+ }
+ }
+
+ /* NOTE: quad detection issue - forth vertidx vs forth loopidx:
+ * Here, our tfaces' forth vertex index is never 0 for a quad. However, we know our forth loop index may be
+ * 0 for quads (because our quads may have been rotated compared to their org poly, see tessellation code).
+ * So we pass the MFace's, and BKE_mesh_loops_to_tessdata will use MFace->v4 index as quad test.
+ */
+ BKE_mesh_tangent_loops_to_tessdata(fdata, ldata, mface, polyindex, loopindex, totface);
+
+ MEM_freeN(loopindex);
+
+ if (G.debug & G_DEBUG)
+ printf("%s: Updated tessellated tangents of dm %p\n", __func__, dm);
+}
+
+
void DM_update_materials(DerivedMesh *dm, Object *ob)
{
int i, totmat = ob->totcol + 1; /* materials start from 1, default material is 0 */
@@ -2899,9 +2963,11 @@ void mesh_get_mapped_verts_coords(DerivedMesh *dm, float (*r_cos)[3], const int
typedef struct {
float (*precomputedFaceNormals)[3];
- short (*precomputedLoopNormals)[4][3];
- MTFace *mtface; /* texture coordinates */
- MFace *mface; /* indices */
+ float (*precomputedLoopNormals)[3];
+ const MLoopTri *looptri;
+ MLoopUV *mloopuv; /* texture coordinates */
+ MPoly *mpoly; /* indices */
+ MLoop *mloop; /* indices */
MVert *mvert; /* vertices & normals */
float (*orco)[3];
float (*tangent)[4]; /* destination */
@@ -2920,15 +2986,17 @@ static int GetNumFaces(const SMikkTSpaceContext *pContext)
static int GetNumVertsOfFace(const SMikkTSpaceContext *pContext, const int face_num)
{
- SGLSLMeshToTangent *pMesh = (SGLSLMeshToTangent *) pContext->m_pUserData;
- return pMesh->mface[face_num].v4 != 0 ? 4 : 3;
+ //SGLSLMeshToTangent *pMesh = (SGLSLMeshToTangent *) pContext->m_pUserData;
+ UNUSED_VARS(pContext, face_num);
+ return 3;
}
static void GetPosition(const SMikkTSpaceContext *pContext, float r_co[3], const int face_num, const int vert_index)
{
//assert(vert_index >= 0 && vert_index < 4);
SGLSLMeshToTangent *pMesh = (SGLSLMeshToTangent *) pContext->m_pUserData;
- const float *co = pMesh->mvert[(&pMesh->mface[face_num].v1)[vert_index]].co;
+ const MLoopTri *lt = &pMesh->looptri[face_num];
+ const float *co = pMesh->mvert[pMesh->mloop[lt->tri[vert_index]].v].co;
copy_v3_v3(r_co, co);
}
@@ -2936,13 +3004,14 @@ static void GetTextureCoordinate(const SMikkTSpaceContext *pContext, float r_uv[
{
//assert(vert_index >= 0 && vert_index < 4);
SGLSLMeshToTangent *pMesh = (SGLSLMeshToTangent *) pContext->m_pUserData;
+ const MLoopTri *lt = &pMesh->looptri[face_num];
- if (pMesh->mtface != NULL) {
- const float *uv = pMesh->mtface[face_num].uv[vert_index];
+ if (pMesh->mloopuv != NULL) {
+ const float *uv = pMesh->mloopuv[lt->tri[vert_index]].uv;
copy_v2_v2(r_uv, uv);
}
else {
- const float *orco = pMesh->orco[(&pMesh->mface[face_num].v1)[vert_index]];
+ const float *orco = pMesh->orco[pMesh->mloop[lt->tri[vert_index]].v];
map_to_sphere(&r_uv[0], &r_uv[1], orco[0], orco[1], orco[2]);
}
}
@@ -2951,41 +3020,36 @@ static void GetNormal(const SMikkTSpaceContext *pContext, float r_no[3], const i
{
//assert(vert_index >= 0 && vert_index < 4);
SGLSLMeshToTangent *pMesh = (SGLSLMeshToTangent *) pContext->m_pUserData;
- const bool smoothnormal = (pMesh->mface[face_num].flag & ME_SMOOTH) != 0;
+ const MLoopTri *lt = &pMesh->looptri[face_num];
+ const bool smoothnormal = (pMesh->mpoly[lt->poly].flag & ME_SMOOTH) != 0;
if (pMesh->precomputedLoopNormals) {
- normal_short_to_float_v3(r_no, pMesh->precomputedLoopNormals[face_num][vert_index]);
+ copy_v3_v3(r_no, pMesh->precomputedLoopNormals[lt->tri[vert_index]]);
}
else if (!smoothnormal) { // flat
if (pMesh->precomputedFaceNormals) {
- copy_v3_v3(r_no, pMesh->precomputedFaceNormals[face_num]);
+ copy_v3_v3(r_no, pMesh->precomputedFaceNormals[lt->poly]);
}
else {
- MFace *mf = &pMesh->mface[face_num];
- const float *p0 = pMesh->mvert[mf->v1].co;
- const float *p1 = pMesh->mvert[mf->v2].co;
- const float *p2 = pMesh->mvert[mf->v3].co;
-
- if (mf->v4) {
- const float *p3 = pMesh->mvert[mf->v4].co;
- normal_quad_v3(r_no, p0, p1, p2, p3);
- }
- else {
- normal_tri_v3(r_no, p0, p1, p2);
- }
+ const float *p0 = pMesh->mvert[pMesh->mloop[lt->tri[0]].v].co;
+ const float *p1 = pMesh->mvert[pMesh->mloop[lt->tri[1]].v].co;
+ const float *p2 = pMesh->mvert[pMesh->mloop[lt->tri[2]].v].co;
+
+ normal_tri_v3(r_no, p0, p1, p2);
}
}
else {
- const short *no = pMesh->mvert[(&pMesh->mface[face_num].v1)[vert_index]].no;
+ const short *no = pMesh->mvert[pMesh->mloop[lt->tri[0]].v].no;
normal_short_to_float_v3(r_no, no);
}
}
-static void SetTSpace(const SMikkTSpaceContext *pContext, const float fvTangent[3], const float fSign, const int face_num, const int iVert)
+static void SetTSpace(const SMikkTSpaceContext *pContext, const float fvTangent[3], const float fSign, const int face_num, const int vert_index)
{
//assert(vert_index >= 0 && vert_index < 4);
SGLSLMeshToTangent *pMesh = (SGLSLMeshToTangent *) pContext->m_pUserData;
- float *pRes = pMesh->tangent[4 * face_num + iVert];
+ const MLoopTri *lt = &pMesh->looptri[face_num];
+ float *pRes = pMesh->tangent[lt->tri[vert_index]];
copy_v3_v3(pRes, fvTangent);
pRes[3] = fSign;
}
@@ -2993,40 +3057,44 @@ static void SetTSpace(const SMikkTSpaceContext *pContext, const float fvTangent[
void DM_add_tangent_layer(DerivedMesh *dm)
{
/* mesh vars */
+ const MLoopTri *looptri;
MVert *mvert;
- MTFace *mtface;
- MFace *mface;
+ MLoopUV *mloopuv;
+ MPoly *mpoly;
+ MLoop *mloop;
float (*orco)[3] = NULL, (*tangent)[4];
int /* totvert, */ totface;
float (*fnors)[3];
- short (*tlnors)[4][3];
+ float (*tlnors)[3];
- if (CustomData_get_layer_index(&dm->faceData, CD_TANGENT) != -1)
+ if (CustomData_get_layer_index(&dm->loopData, CD_TANGENT) != -1)
return;
- fnors = dm->getTessFaceDataArray(dm, CD_NORMAL);
+ fnors = dm->getPolyDataArray(dm, CD_NORMAL);
/* Note, we assume we do have tessellated loop normals at this point (in case it is object-enabled),
* have to check this is valid...
*/
- tlnors = dm->getTessFaceDataArray(dm, CD_TESSLOOPNORMAL);
+ tlnors = dm->getLoopDataArray(dm, CD_NORMAL);
/* check we have all the needed layers */
/* totvert = dm->getNumVerts(dm); */ /* UNUSED */
- totface = dm->getNumTessFaces(dm);
+ looptri = dm->getLoopTriArray(dm);
+ totface = dm->getNumLoopTri(dm);
mvert = dm->getVertArray(dm);
- mface = dm->getTessFaceArray(dm);
- mtface = dm->getTessFaceDataArray(dm, CD_MTFACE);
+ mpoly = dm->getPolyArray(dm);
+ mloop = dm->getLoopArray(dm);
+ mloopuv = dm->getLoopDataArray(dm, CD_MLOOPUV);
- if (!mtface) {
+ if (!mloopuv) {
orco = dm->getVertDataArray(dm, CD_ORCO);
if (!orco)
return;
}
/* create tangent layer */
- DM_add_tessface_layer(dm, CD_TANGENT, CD_CALLOC, NULL);
- tangent = DM_get_tessface_data_layer(dm, CD_TANGENT);
+ DM_add_loop_layer(dm, CD_TANGENT, CD_CALLOC, NULL);
+ tangent = DM_get_loop_data_layer(dm, CD_TANGENT);
/* new computation method */
{
@@ -3036,8 +3104,10 @@ void DM_add_tangent_layer(DerivedMesh *dm)
mesh2tangent.precomputedFaceNormals = fnors;
mesh2tangent.precomputedLoopNormals = tlnors;
- mesh2tangent.mtface = mtface;
- mesh2tangent.mface = mface;
+ mesh2tangent.looptri = looptri;
+ mesh2tangent.mloopuv = mloopuv;
+ mesh2tangent.mpoly = mpoly;
+ mesh2tangent.mloop = mloop;
mesh2tangent.mvert = mvert;
mesh2tangent.orco = orco;
mesh2tangent.tangent = tangent;
@@ -3208,7 +3278,7 @@ void DM_calc_auto_bump_scale(DerivedMesh *dm)
void DM_vertex_attributes_from_gpu(DerivedMesh *dm, GPUVertexAttribs *gattribs, DMVertexAttribs *attribs)
{
- CustomData *vdata, *fdata, *tfdata = NULL;
+ CustomData *vdata, *ldata;
int a, b, layer;
/* From the layers requested by the GLSL shader, figure out which ones are
@@ -3217,7 +3287,7 @@ void DM_vertex_attributes_from_gpu(DerivedMesh *dm, GPUVertexAttribs *gattribs,
memset(attribs, 0, sizeof(DMVertexAttribs));
vdata = &dm->vertData;
- fdata = tfdata = dm->getTessFaceDataLayout(dm);
+ ldata = dm->getLoopDataLayout(dm);
/* calc auto bump scale if necessary */
if (dm->auto_bump_scale <= 0.0f)
@@ -3226,7 +3296,7 @@ void DM_vertex_attributes_from_gpu(DerivedMesh *dm, GPUVertexAttribs *gattribs,
/* add a tangent layer if necessary */
for (b = 0; b < gattribs->totlayer; b++) {
if (gattribs->layer[b].type == CD_TANGENT) {
- if (CustomData_get_layer_index(fdata, CD_TANGENT) == -1) {
+ if (CustomData_get_layer_index(ldata, CD_TANGENT) == -1) {
DM_add_tangent_layer(dm);
break;
}
@@ -3261,9 +3331,6 @@ void DM_vertex_attributes_from_gpu(DerivedMesh *dm, GPUVertexAttribs *gattribs,
attribs->tface[a].gl_texco = gattribs->layer[b].gltexco;
}
else {
- /* exception .. */
- CustomData *ldata = dm->getLoopDataLayout(dm);
-
if (gattribs->layer[b].name[0])
layer = CustomData_get_named_layer_index(ldata, CD_MLOOPUV,
gattribs->layer[b].name);
@@ -3287,9 +3354,6 @@ void DM_vertex_attributes_from_gpu(DerivedMesh *dm, GPUVertexAttribs *gattribs,
}
else if (gattribs->layer[b].type == CD_MCOL) {
if (dm->type == DM_TYPE_EDITBMESH) {
- /* exception .. */
- CustomData *ldata = dm->getLoopDataLayout(dm);
-
if (gattribs->layer[b].name[0])
layer = CustomData_get_named_layer_index(ldata, CD_MLOOPCOL,
gattribs->layer[b].name);
@@ -3311,9 +3375,6 @@ void DM_vertex_attributes_from_gpu(DerivedMesh *dm, GPUVertexAttribs *gattribs,
attribs->mcol[a].gl_index = gattribs->layer[b].glindex;
}
else {
- /* exception .. */
- CustomData *ldata = dm->getLoopDataLayout(dm);
-
/* vertex colors */
if (gattribs->layer[b].name[0])
layer = CustomData_get_named_layer_index(ldata, CD_MLOOPCOL,
@@ -3337,14 +3398,13 @@ void DM_vertex_attributes_from_gpu(DerivedMesh *dm, GPUVertexAttribs *gattribs,
}
}
else if (gattribs->layer[b].type == CD_TANGENT) {
- /* tangents */
- layer = CustomData_get_layer_index(fdata, CD_TANGENT);
+ layer = CustomData_get_layer_index(ldata, CD_TANGENT);
attribs->tottang = 1;
if (layer != -1) {
- attribs->tang.array = fdata->layers[layer].data;
- attribs->tang.em_offset = fdata->layers[layer].offset;
+ attribs->tang.array = ldata->layers[layer].data;
+ attribs->tang.em_offset = ldata->layers[layer].offset;
}
else {
attribs->tang.array = NULL;
@@ -3386,6 +3446,8 @@ void DM_draw_attrib_vertex(DMVertexAttribs *attribs, int a, int index, int vert,
const float zero[4] = {0.0f, 0.0f, 0.0f, 0.0f};
int b;
+ UNUSED_VARS(a, vert);
+
/* orco texture coordinates */
if (attribs->totorco) {
/*const*/ float (*array)[3] = attribs->orco.array;
@@ -3433,7 +3495,7 @@ void DM_draw_attrib_vertex(DMVertexAttribs *attribs, int a, int index, int vert,
/* tangent for normal mapping */
if (attribs->tottang) {
/*const*/ float (*array)[4] = attribs->tang.array;
- const float *tang = (array) ? array[a * 4 + vert] : zero;
+ const float *tang = (array) ? array[loop] : zero;
glVertexAttrib4fvARB(attribs->tang.gl_index, tang);
}
}
diff --git a/source/blender/blenkernel/intern/cdderivedmesh.c b/source/blender/blenkernel/intern/cdderivedmesh.c
index b5ff4f6ee5f..9a3a74103f8 100644
--- a/source/blender/blenkernel/intern/cdderivedmesh.c
+++ b/source/blender/blenkernel/intern/cdderivedmesh.c
@@ -1076,15 +1076,13 @@ static void cdDM_drawMappedFacesGLSL(
offset += sizeof(unsigned char) * 4;
}
}
- /* TODO, handle tangents */
if (matconv[i].attribs.tottang && matconv[i].attribs.tang.array) {
- const float *tang = matconv[i].attribs.tang.array[i * 4 + 0];
- copy_v4_v4((float *)&varray[offset], tang);
- tang = matconv[i].attribs.tang.array[i * 4 + 1];
- copy_v4_v4((float *)&varray[offset + max_element_size], tang);
- tang = matconv[i].attribs.tang.array[i * 4 + 2];
- copy_v4_v4((float *)&varray[offset + max_element_size * 2], tang);
- offset += sizeof(float) * 4;
+ if (matconv[i].attribs.tface[b].array) {
+ const float (*looptang)[4] = (const float (*)[4])matconv[i].attribs.tang.array;
+ for (j = 0; j < mpoly->totloop; j++)
+ copy_v4_v4((float *)&varray[offset + j * max_element_size], looptang[mpoly->loopstart + j]);
+ offset += sizeof(float) * 4;
+ }
}
}
diff --git a/source/blender/blenkernel/intern/customdata.c b/source/blender/blenkernel/intern/customdata.c
index 2bf3657f920..7593ea104c6 100644
--- a/source/blender/blenkernel/intern/customdata.c
+++ b/source/blender/blenkernel/intern/customdata.c
@@ -2489,6 +2489,9 @@ void CustomData_from_bmeshpoly(CustomData *fdata, CustomData *pdata, CustomData
else if (ldata->layers[i].type == CD_NORMAL) {
CustomData_add_layer_named(fdata, CD_TESSLOOPNORMAL, CD_CALLOC, NULL, total, ldata->layers[i].name);
}
+ else if (ldata->layers[i].type == CD_TANGENT) {
+ CustomData_add_layer_named(fdata, CD_TANGENT, CD_CALLOC, NULL, total, ldata->layers[i].name);
+ }
}
CustomData_bmesh_update_active_layers(fdata, pdata, ldata);
diff --git a/source/blender/blenkernel/intern/mesh_evaluate.c b/source/blender/blenkernel/intern/mesh_evaluate.c
index 74c5fb8114d..a334951c772 100644
--- a/source/blender/blenkernel/intern/mesh_evaluate.c
+++ b/source/blender/blenkernel/intern/mesh_evaluate.c
@@ -2243,6 +2243,7 @@ void BKE_mesh_loops_to_tessdata(CustomData *fdata, CustomData *ldata, CustomData
const bool hasPCol = CustomData_has_layer(ldata, CD_PREVIEW_MLOOPCOL);
const bool hasOrigSpace = CustomData_has_layer(ldata, CD_ORIGSPACE_MLOOP);
const bool hasLoopNormal = CustomData_has_layer(ldata, CD_NORMAL);
+ const bool hasLoopTangent = CustomData_has_layer(ldata, CD_TANGENT);
int findex, i, j;
const int *pidx;
unsigned int (*lidx)[4];
@@ -2307,6 +2308,51 @@ void BKE_mesh_loops_to_tessdata(CustomData *fdata, CustomData *ldata, CustomData
}
}
}
+
+ if (hasLoopTangent) {
+ /* need to do for all uv maps at some point */
+ float (*ftangents)[4] = CustomData_get_layer(fdata, CD_TANGENT);
+ float (*ltangents)[4] = CustomData_get_layer(ldata, CD_TANGENT);
+
+ for (findex = 0, pidx = polyindices, lidx = loopindices;
+ findex < num_faces;
+ pidx++, lidx++, findex++)
+ {
+ int nverts = (mface ? mface[findex].v4 : (*lidx)[3]) ? 4 : 3;
+ for (j = nverts; j--;) {
+ copy_v4_v4(ftangents[findex * 4 + j], ltangents[(*lidx)[j]]);
+ }
+ }
+ }
+}
+
+void BKE_mesh_tangent_loops_to_tessdata(CustomData *fdata, CustomData *ldata, MFace *mface,
+ int *polyindices, unsigned int (*loopindices)[4], const int num_faces)
+{
+ /* Note: performances are sub-optimal when we get a NULL mface, we could be ~25% quicker with dedicated code...
+ * Issue is, unless having two different functions with nearly the same code, there's not much ways to solve
+ * this. Better imho to live with it for now. :/ --mont29
+ */
+ const bool hasLoopTangent = CustomData_has_layer(ldata, CD_TANGENT);
+ int findex, j;
+ const int *pidx;
+ unsigned int (*lidx)[4];
+
+ if (hasLoopTangent) {
+ /* need to do for all uv maps at some point */
+ float (*ftangents)[4] = CustomData_get_layer(fdata, CD_TANGENT);
+ float (*ltangents)[4] = CustomData_get_layer(ldata, CD_TANGENT);
+
+ for (findex = 0, pidx = polyindices, lidx = loopindices;
+ findex < num_faces;
+ pidx++, lidx++, findex++)
+ {
+ int nverts = (mface ? mface[findex].v4 : (*lidx)[3]) ? 4 : 3;
+ for (j = nverts; j--;) {
+ copy_v4_v4(ftangents[findex * 4 + j], ltangents[(*lidx)[j]]);
+ }
+ }
+ }
}
/**
diff --git a/source/blender/blenkernel/intern/multires.c b/source/blender/blenkernel/intern/multires.c
index 0c984c38b8e..9ef5b697079 100644
--- a/source/blender/blenkernel/intern/multires.c
+++ b/source/blender/blenkernel/intern/multires.c
@@ -2338,12 +2338,12 @@ void multires_topology_changed(Mesh *me)
/***************** Multires interpolation stuff *****************/
/* Find per-corner coordinate with given per-face UV coord */
-int mdisp_rot_face_to_crn(const int corners, const int face_side, const float u, const float v, float *x, float *y)
+int mdisp_rot_face_to_crn(struct MVert *UNUSED(mvert), struct MPoly *mpoly, struct MLoop *UNUSED(mloop), const struct MLoopTri *UNUSED(lt), const int face_side, const float u, const float v, float *x, float *y)
{
const float offset = face_side * 0.5f - 0.5f;
int S = 0;
- if (corners == 4) {
+ if (mpoly->totloop == 4) {
if (u <= offset && v <= offset) S = 0;
else if (u > offset && v <= offset) S = 1;
else if (u > offset && v > offset) S = 2;
@@ -2366,7 +2366,7 @@ int mdisp_rot_face_to_crn(const int corners, const int face_side, const float u,
*y = v - offset;
}
}
- else {
+ else if (mpoly->totloop == 3) {
int grid_size = offset;
float w = (face_side - 1) - u - v;
float W1, W2;
@@ -2381,6 +2381,30 @@ int mdisp_rot_face_to_crn(const int corners, const int face_side, const float u,
*x = (1 - (2 * W1) / (1 - W2)) * grid_size;
*y = (1 - (2 * W2) / (1 - W1)) * grid_size;
}
+ else {
+ /* the complicated ngon case: find the actual coordinate from
+ * the barycentric coordinates and finally find the closest vertex
+ * should work reliably for convex cases only but better than nothing */
+
+#if 0
+ int minS, i;
+ float mindist = FLT_MAX;
+
+ for (i = 0; i < mpoly->totloop; i++) {
+ float len = len_v3v3(NULL, mvert[mloop[mpoly->loopstart + i].v].co);
+ if (len < mindist) {
+ mindist = len;
+ minS = i;
+ }
+ }
+ S = minS;
+#endif
+ /* temp not implemented yet and also not working properly in current master.
+ * (was worked around by subdividing once) */
+ S = 0;
+ *x = 0;
+ *y = 0;
+ }
return S;
}