[Bf-blender-cvs] [faba1e7d6e3] blender2.8: DWM: Tangent support for editmesh

Campbell Barton noreply at git.blender.org
Tue May 9 02:26:02 CEST 2017


Commit: faba1e7d6e3fb510adf3c5507049598141d6e730
Author: Campbell Barton
Date:   Tue May 9 08:50:45 2017 +1000
Branches: blender2.8
https://developer.blender.org/rBfaba1e7d6e3fb510adf3c5507049598141d6e730

DWM: Tangent support for editmesh

===================================================================

A	source/blender/blenkernel/BKE_editmesh_tangent.h
M	source/blender/blenkernel/CMakeLists.txt
M	source/blender/blenkernel/intern/editderivedmesh.c
A	source/blender/blenkernel/intern/editmesh_tangent.c
M	source/blender/draw/intern/draw_cache_impl_mesh.c

===================================================================

diff --git a/source/blender/blenkernel/BKE_editmesh_tangent.h b/source/blender/blenkernel/BKE_editmesh_tangent.h
new file mode 100644
index 00000000000..7d6839a4e6a
--- /dev/null
+++ b/source/blender/blenkernel/BKE_editmesh_tangent.h
@@ -0,0 +1,40 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * Contributor(s): Joseph Eagar.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+#ifndef __BKE_EDITMESH_TANGENT_H__
+#define __BKE_EDITMESH_TANGENT_H__
+
+/** \file BKE_editmesh_tangent.h
+ *  \ingroup bke
+ */
+
+void BKE_editmesh_loop_tangent_calc(
+        BMEditMesh *em, bool calc_active_tangent,
+        const char (*tangent_names)[MAX_NAME], int tangent_names_len,
+        const float (*poly_normals)[3],
+        const float (*loop_normals)[3],
+        const float (*vert_orco)[3],
+        CustomData *dm_loopdata_out,
+        const uint dm_loopdata_out_len,
+        char *tangent_mask_curr_p);
+
+#endif /* __BKE_EDITMESH_TANGENT_H__ */
diff --git a/source/blender/blenkernel/CMakeLists.txt b/source/blender/blenkernel/CMakeLists.txt
index 9fa6b7cc3cf..1acc45c9f00 100644
--- a/source/blender/blenkernel/CMakeLists.txt
+++ b/source/blender/blenkernel/CMakeLists.txt
@@ -103,6 +103,7 @@ set(SRC
 	intern/editderivedmesh.c
 	intern/editmesh.c
 	intern/editmesh_bvh.c
+	intern/editmesh_tangent.c
 	intern/effect.c
 	intern/fcurve.c
 	intern/fluidsim.c
@@ -232,6 +233,7 @@ set(SRC
 	BKE_dynamicpaint.h
 	BKE_editmesh.h
 	BKE_editmesh_bvh.h
+	BKE_editmesh_tangent.h
 	BKE_effect.h
 	BKE_fcurve.h
 	BKE_fluidsim.h
diff --git a/source/blender/blenkernel/intern/editderivedmesh.c b/source/blender/blenkernel/intern/editderivedmesh.c
index 19a27499ff0..320299d1933 100644
--- a/source/blender/blenkernel/intern/editderivedmesh.c
+++ b/source/blender/blenkernel/intern/editderivedmesh.c
@@ -50,6 +50,7 @@
 #include "BKE_mesh.h"
 #include "BKE_editmesh.h"
 #include "BKE_editmesh_bvh.h"
+#include "BKE_editmesh_tangent.h"
 
 #include "DNA_scene_types.h"
 #include "DNA_object_types.h"
@@ -238,383 +239,24 @@ static void emDM_calcLoopNormalsSpaceArray(
 #endif
 }
 
-
-/** \name Tangent Space Calculation
- * \{ */
-
-/* Necessary complexity to handle looptri's as quads for correct tangents */
-#define USE_LOOPTRI_DETECT_QUADS
-
-typedef struct {
-	const float (*precomputedFaceNormals)[3];
-	const float (*precomputedLoopNormals)[3];
-	const BMLoop *(*looptris)[3];
-	int cd_loop_uv_offset;   /* texture coordinates */
-	const float (*orco)[3];
-	float (*tangent)[4];    /* destination */
-	int numTessFaces;
-
-#ifdef USE_LOOPTRI_DETECT_QUADS
-	/* map from 'fake' face index to looptri,
-	 * quads will point to the first looptri of the quad */
-	const int    *face_as_quad_map;
-	int       num_face_as_quad_map;
-#endif
-
-} SGLSLEditMeshToTangent;
-
-#ifdef USE_LOOPTRI_DETECT_QUADS
-/* seems weak but only used on quads */
-static const BMLoop *bm_loop_at_face_index(const BMFace *f, int vert_index)
-{
-	const BMLoop *l = BM_FACE_FIRST_LOOP(f);
-	while (vert_index--) {
-		l = l->next;
-	}
-	return l;
-}
-#endif
-
-/* interface */
-#include "mikktspace.h"
-
-static int emdm_ts_GetNumFaces(const SMikkTSpaceContext *pContext)
-{
-	SGLSLEditMeshToTangent *pMesh = pContext->m_pUserData;
-
-#ifdef USE_LOOPTRI_DETECT_QUADS
-	return pMesh->num_face_as_quad_map;
-#else
-	return pMesh->numTessFaces;
-#endif
-}
-
-static int emdm_ts_GetNumVertsOfFace(const SMikkTSpaceContext *pContext, const int face_num)
-{
-#ifdef USE_LOOPTRI_DETECT_QUADS
-	SGLSLEditMeshToTangent *pMesh = pContext->m_pUserData;
-	if (pMesh->face_as_quad_map) {
-		const BMLoop **lt = pMesh->looptris[pMesh->face_as_quad_map[face_num]];
-		if (lt[0]->f->len == 4) {
-			return 4;
-		}
-	}
-	return 3;
-#else
-	UNUSED_VARS(pContext, face_num);
-	return 3;
-#endif
-}
-
-static void emdm_ts_GetPosition(
-        const SMikkTSpaceContext *pContext, float r_co[3],
-        const int face_num, const int vert_index)
-{
-	//assert(vert_index >= 0 && vert_index < 4);
-	SGLSLEditMeshToTangent *pMesh = pContext->m_pUserData;
-	const BMLoop **lt;
-	const BMLoop *l;
-
-#ifdef USE_LOOPTRI_DETECT_QUADS
-	if (pMesh->face_as_quad_map) {
-		lt = pMesh->looptris[pMesh->face_as_quad_map[face_num]];
-		if (lt[0]->f->len == 4) {
-			l = bm_loop_at_face_index(lt[0]->f, vert_index);
-			goto finally;
-		}
-		/* fall through to regular triangle */
-	}
-	else {
-		lt = pMesh->looptris[face_num];
-	}
-#else
-	lt = pMesh->looptris[face_num];
-#endif
-	l = lt[vert_index];
-
-	const float *co;
-
-finally:
-	co = l->v->co;
-	copy_v3_v3(r_co, co);
-}
-
-static void emdm_ts_GetTextureCoordinate(
-        const SMikkTSpaceContext *pContext, float r_uv[2],
-        const int face_num, const int vert_index)
-{
-	//assert(vert_index >= 0 && vert_index < 4);
-	SGLSLEditMeshToTangent *pMesh = pContext->m_pUserData;
-	const BMLoop **lt;
-	const BMLoop *l;
-
-#ifdef USE_LOOPTRI_DETECT_QUADS
-	if (pMesh->face_as_quad_map) {
-		lt = pMesh->looptris[pMesh->face_as_quad_map[face_num]];
-		if (lt[0]->f->len == 4) {
-			l = bm_loop_at_face_index(lt[0]->f, vert_index);
-			goto finally;
-		}
-		/* fall through to regular triangle */
-	}
-	else {
-		lt = pMesh->looptris[face_num];
-	}
-#else
-	lt = pMesh->looptris[face_num];
-#endif
-	l = lt[vert_index];
-
-finally:
-	if (pMesh->cd_loop_uv_offset != -1) {
-		const float *uv = BM_ELEM_CD_GET_VOID_P(l, pMesh->cd_loop_uv_offset);
-		copy_v2_v2(r_uv, uv);
-	}
-	else {
-		const float *orco = pMesh->orco[BM_elem_index_get(l->v)];
-		map_to_sphere(&r_uv[0], &r_uv[1], orco[0], orco[1], orco[2]);
-	}
-}
-
-static void emdm_ts_GetNormal(
-        const SMikkTSpaceContext *pContext, float r_no[3],
-        const int face_num, const int vert_index)
-{
-	//assert(vert_index >= 0 && vert_index < 4);
-	SGLSLEditMeshToTangent *pMesh = pContext->m_pUserData;
-	const BMLoop **lt;
-	const BMLoop *l;
-
-#ifdef USE_LOOPTRI_DETECT_QUADS
-	if (pMesh->face_as_quad_map) {
-		lt = pMesh->looptris[pMesh->face_as_quad_map[face_num]];
-		if (lt[0]->f->len == 4) {
-			l = bm_loop_at_face_index(lt[0]->f, vert_index);
-			goto finally;
-		}
-		/* fall through to regular triangle */
-	}
-	else {
-		lt = pMesh->looptris[face_num];
-	}
-#else
-	lt = pMesh->looptris[face_num];
-#endif
-	l = lt[vert_index];
-
-finally:
-	if (pMesh->precomputedLoopNormals) {
-		copy_v3_v3(r_no, pMesh->precomputedLoopNormals[BM_elem_index_get(l)]);
-	}
-	else if (BM_elem_flag_test(l->f, BM_ELEM_SMOOTH) == 0) {  /* flat */
-		if (pMesh->precomputedFaceNormals) {
-			copy_v3_v3(r_no, pMesh->precomputedFaceNormals[BM_elem_index_get(l->f)]);
-		}
-		else {
-			copy_v3_v3(r_no, l->f->no);
-		}
-	}
-	else {
-		copy_v3_v3(r_no, l->v->no);
-	}
-}
-
-static void emdm_ts_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);
-	SGLSLEditMeshToTangent *pMesh = pContext->m_pUserData;
-	const BMLoop **lt;
-	const BMLoop *l;
-
-#ifdef USE_LOOPTRI_DETECT_QUADS
-	if (pMesh->face_as_quad_map) {
-		lt = pMesh->looptris[pMesh->face_as_quad_map[face_num]];
-		if (lt[0]->f->len == 4) {
-			l = bm_loop_at_face_index(lt[0]->f, vert_index);
-			goto finally;
-		}
-		/* fall through to regular triangle */
-	}
-	else {
-		lt = pMesh->looptris[face_num];
-	}
-#else
-	lt = pMesh->looptris[face_num];
-#endif
-	l = lt[vert_index];
-
-	float *pRes;
-
-finally:
-	pRes = pMesh->tangent[BM_elem_index_get(l)];
-	copy_v3_v3(pRes, fvTangent);
-	pRes[3] = fSign;
-}
-
-static void emDM_calc_loop_tangents_thread(TaskPool * __restrict UNUSED(pool), void *taskdata, int UNUSED(threadid))
-{
-	struct SGLSLEditMeshToTangent *mesh2tangent = taskdata;
-	/* new computation method */
-	{
-		SMikkTSpaceContext sContext = {NULL};
-		SMikkTSpaceInterface sInterface = {NULL};
-		sContext.m_pUserData = mesh2tangent;
-		sContext.m_pInterface = &sInterface;
-		sInterface.m_getNumFaces = emdm_ts_GetNumFaces;
-		sInterface.m_getNumVerticesOfFace = emdm_ts_GetNumVertsOfFace;
-		sInterface.m_getPosition = emdm_ts_GetPosition;
-		sInterface.m_getTexCoord = emdm_ts_GetTextureCoordinate;
-		sInterface.m_getNormal = emdm_ts_GetNormal;
-		sInterface.m_setTSpaceBasic = emdm_ts_SetTSpace;
-		/* 0 if failed */
-		genTangSpaceDefault(&sContext);
-	}
-}
-
-/**
- * \see #DM_calc_loop_tangents, same logic but used arrays instead of #BMesh data.
- *
- * \note This function is not so normal, its using `bm->ldata` as input, but output's to `dm->loopData`.
- * This is done because #CD_TANGENT is cache data used only for drawing.
- */
-
 static void emDM_calc_loop_tangents(
         DerivedMesh *dm, bool calc_active_tangent,
-        const char (*tangent_names)[MAX_NAME], int tangent_names_count)
+        const char (*tangent_names)[MAX_NAME], int tangent_names_len)
 {
 	EditDerivedBMesh *bmdm = (EditDerivedBMesh *)dm;
 	BMEditMesh *em = bmdm->em;
-	BMesh *bm = bmdm->em->bm;
-	if (CustomData_number_of_layers(&bm->ldata, CD_MLOOPUV) == 0)
-		return;
-
-	int act_uv_n = -1;
-	int ren_uv_n = -1;
-	bool calc_act = false;
-	bool calc_ren = false;
-	char act_uv_name[MAX_NAME];
-	char ren_uv_name[MAX_NAME];
-	char tangent_mask = 0;
-
-	DM_calc_loop_tangents_step_0(
-	        &bm->ldata, calc_active_tangent, tangent_names, tangent_names_count,
-	        &calc_act, &calc_ren, &act_uv_n, &ren_uv_n, act_uv_name, ren_uv_name, &tangent_mask);
-
-	if ((dm->tangent_mask | tangent_mask) != dm->tangent_mask) {
-		for (int i = 0; i < tangent_names_count; i++)
-			if (tangent_names[i][0])
-				DM_add_named_tangent_l

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list