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:
authorBastien Montagne <montagne29@wanadoo.fr>2015-02-05 16:24:48 +0300
committerBastien Montagne <montagne29@wanadoo.fr>2015-02-05 16:32:57 +0300
commit138c9dba9be67a93c91717ae3fcd8855aced9185 (patch)
treedfb5d14d965297a069386148bdcff4236ca1f23b /source/blender/blenkernel/intern/editderivedmesh.c
parent7bae9ee6b62dbc5defffb698ec3d3f39ce460254 (diff)
Add Custom Loop Normals.
This is the core code for it, tools (datatransfer and modifier) will come in next commits). RNA api is already there, though. See the code for details, but basically, we define, for each 'smooth fan' (which is a set of adjacent loops around a same vertex that are smooth, i.e. have a single same normal), a 'loop normal space' (or lnor space), using auto-computed normal and relevant edges, and store custom normal as two angular factors inside that space. This allows to have custom normals 'following' deformations of the geometry, and to only save two shorts per loop in new clnor CDLayer. Normal manipulation (editing, mixing, interpolating, etc.) shall always happen with plain 3D vectors normals, and be converted back into storage format at the end. Clnor computation has also been threaded (at least for Mesh case, not for BMesh), since the process can be rather heavy with high poly meshes. Also, bumping subversion, and fix mess in 2.70 versioning code.
Diffstat (limited to 'source/blender/blenkernel/intern/editderivedmesh.c')
-rw-r--r--source/blender/blenkernel/intern/editderivedmesh.c46
1 files changed, 45 insertions, 1 deletions
diff --git a/source/blender/blenkernel/intern/editderivedmesh.c b/source/blender/blenkernel/intern/editderivedmesh.c
index 62d9009a131..082edb01efd 100644
--- a/source/blender/blenkernel/intern/editderivedmesh.c
+++ b/source/blender/blenkernel/intern/editderivedmesh.c
@@ -169,12 +169,25 @@ static void emDM_calcNormals(DerivedMesh *dm)
dm->dirty &= ~DM_DIRTY_NORMALS;
}
+static void emDM_calcLoopNormalsSpaceArray(
+ DerivedMesh *dm, const bool use_split_normals, const float split_angle, MLoopNorSpaceArray *r_lnors_spacearr);
+
static void emDM_calcLoopNormals(DerivedMesh *dm, const bool use_split_normals, const float split_angle)
{
+ emDM_calcLoopNormalsSpaceArray(dm, use_split_normals, split_angle, NULL);
+}
+
+/* #define DEBUG_CLNORS */
+
+static void emDM_calcLoopNormalsSpaceArray(
+ DerivedMesh *dm, const bool use_split_normals, const float split_angle, MLoopNorSpaceArray *r_lnors_spacearr)
+{
EditDerivedBMesh *bmdm = (EditDerivedBMesh *)dm;
BMesh *bm = bmdm->em->bm;
const float (*vertexCos)[3], (*vertexNos)[3], (*polyNos)[3];
float (*loopNos)[3];
+ short (*clnors_data)[2];
+ int cd_loop_clnors_offset;
/* calculate loop normals from poly and vertex normals */
emDM_ensureVertNormals(bmdm);
@@ -191,7 +204,37 @@ static void emDM_calcLoopNormals(DerivedMesh *dm, const bool use_split_normals,
loopNos = dm->getLoopDataArray(dm, CD_NORMAL);
}
- BM_loops_calc_normal_vcos(bm, vertexCos, vertexNos, polyNos, use_split_normals, split_angle, loopNos);
+ /* We can have both, give priority to dm's data, and fallback to bm's ones. */
+ clnors_data = dm->getLoopDataArray(dm, CD_CUSTOMLOOPNORMAL);
+ cd_loop_clnors_offset = clnors_data ? -1 : CustomData_get_offset(&bm->ldata, CD_CUSTOMLOOPNORMAL);
+
+ BM_loops_calc_normal_vcos(bm, vertexCos, vertexNos, polyNos, use_split_normals, split_angle, loopNos,
+ r_lnors_spacearr, clnors_data, cd_loop_clnors_offset);
+#ifdef DEBUG_CLNORS
+ if (r_lnors_spacearr) {
+ int i;
+ for (i = 0; i < numLoops; i++) {
+ if (r_lnors_spacearr->lspacearr[i]->ref_alpha != 0.0f) {
+ LinkNode *loops = r_lnors_spacearr->lspacearr[i]->loops;
+ printf("Loop %d uses lnor space %p:\n", i, r_lnors_spacearr->lspacearr[i]);
+ print_v3("\tfinal lnor:", loopNos[i]);
+ print_v3("\tauto lnor:", r_lnors_spacearr->lspacearr[i]->vec_lnor);
+ print_v3("\tref_vec:", r_lnors_spacearr->lspacearr[i]->vec_ref);
+ printf("\talpha: %f\n\tbeta: %f\n\tloops: %p\n", r_lnors_spacearr->lspacearr[i]->ref_alpha,
+ r_lnors_spacearr->lspacearr[i]->ref_beta, r_lnors_spacearr->lspacearr[i]->loops);
+ printf("\t\t(shared with loops");
+ while (loops) {
+ printf(" %d", GET_INT_FROM_POINTER(loops->link));
+ loops = loops->next;
+ }
+ printf(")\n");
+ }
+ else {
+ printf("Loop %d has no lnor space\n", i);
+ }
+ }
+ }
+#endif
}
static void emDM_recalcTessellation(DerivedMesh *UNUSED(dm))
@@ -1764,6 +1807,7 @@ DerivedMesh *getEditDerivedBMesh(BMEditMesh *em,
bmdm->dm.calcNormals = emDM_calcNormals;
bmdm->dm.calcLoopNormals = emDM_calcLoopNormals;
+ bmdm->dm.calcLoopNormalsSpaceArray = emDM_calcLoopNormalsSpaceArray;
bmdm->dm.recalcTessellation = emDM_recalcTessellation;
bmdm->dm.foreachMappedVert = emDM_foreachMappedVert;