[Bf-committers] [Bf-blender-cvs] SVN commit: /data/svn/bf-blender [35646] trunk/blender/source/blender: Fix/ change in normal computation, now the viewport uses the same angle
Nicholas Bishop
nicholasbishop at gmail.com
Fri Mar 25 02:35:43 CET 2011
Just FYI, this commit seems to make Subdivide Smooth significantly
less smooth. For example, doing Subdivide Smooth on a cube multiple
times keeps the same cube shape.
-Nicholas
On Sun, Mar 20, 2011 at 9:35 AM, Brecht Van Lommel
<brechtvanlommel at pandora.be> wrote:
> Revision: 35646
> http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=35646
> Author: blendix
> Date: 2011-03-20 13:35:35 +0000 (Sun, 20 Mar 2011)
> Log Message:
> -----------
> Fix/change in normal computation, now the viewport uses the same angle
> weighted normals as the render engine, and the render engine will copy
> normals from the mesh rather than always recalculating them.
>
> Subsurf/multires still use regular vertex normals, but they are expected
> to be sufficiently high resolution to not need this.
>
> This means that normal maps displayed in the viewport actually match the
> render engine exactly and don't have artifacts due to this discrepancy.
> It of course also avoids unexpected surprises where your render normals
> look different than your viewport normals.
>
> Subversion bumped to 4 for version patch to recalculate normals.
>
> Patch by Morten Mikkelsen, with some small changes.
>
> Modified Paths:
> --------------
> trunk/blender/source/blender/blenkernel/BKE_DerivedMesh.h
> trunk/blender/source/blender/blenkernel/BKE_blender.h
> trunk/blender/source/blender/blenkernel/intern/cdderivedmesh.c
> trunk/blender/source/blender/blenkernel/intern/mesh.c
> trunk/blender/source/blender/blenlib/BLI_math_geom.h
> trunk/blender/source/blender/blenlib/intern/math_geom.c
> trunk/blender/source/blender/blenloader/intern/readfile.c
> trunk/blender/source/blender/editors/mesh/editmesh_lib.c
> trunk/blender/source/blender/render/intern/source/convertblender.c
>
> Modified: trunk/blender/source/blender/blenkernel/BKE_DerivedMesh.h
> ===================================================================
> --- trunk/blender/source/blender/blenkernel/BKE_DerivedMesh.h 2011-03-20 12:19:21 UTC (rev 35645)
> +++ trunk/blender/source/blender/blenkernel/BKE_DerivedMesh.h 2011-03-20 13:35:35 UTC (rev 35646)
> @@ -206,7 +206,7 @@
> /* Fill the array (of length .getNumVerts()) with all vertex locations */
> void (*getVertCos)(DerivedMesh *dm, float (*cos_r)[3]);
>
> - /* Get vertex normal, undefined if index is not valid */
> + /* Get smooth vertex normal, undefined if index is not valid */
> void (*getVertNo)(DerivedMesh *dm, int index, float no_r[3]);
>
> /* Get a map of vertices to faces
>
> Modified: trunk/blender/source/blender/blenkernel/BKE_blender.h
> ===================================================================
> --- trunk/blender/source/blender/blenkernel/BKE_blender.h 2011-03-20 12:19:21 UTC (rev 35645)
> +++ trunk/blender/source/blender/blenkernel/BKE_blender.h 2011-03-20 13:35:35 UTC (rev 35646)
> @@ -44,7 +44,7 @@
> * and keep comment above the defines.
> * Use STRINGIFY() rather then defining with quotes */
> #define BLENDER_VERSION 256
> -#define BLENDER_SUBVERSION 3
> +#define BLENDER_SUBVERSION 4
>
> #define BLENDER_MINVERSION 250
> #define BLENDER_MINSUBVERSION 0
>
> Modified: trunk/blender/source/blender/blenkernel/intern/cdderivedmesh.c
> ===================================================================
> --- trunk/blender/source/blender/blenkernel/intern/cdderivedmesh.c 2011-03-20 12:19:21 UTC (rev 35645)
> +++ trunk/blender/source/blender/blenkernel/intern/cdderivedmesh.c 2011-03-20 13:35:35 UTC (rev 35646)
> @@ -1798,7 +1798,7 @@
> int i;
> int numVerts = dm->numVertData;
> int numFaces = dm->numFaceData;
> - MFace *mf;
> + MFace *mfaces;
> MVert *mv;
>
> if(numVerts == 0) return;
> @@ -1817,27 +1817,43 @@
> NULL, dm->numFaceData);
>
> /* calculate face normals and add to vertex normals */
> - mf = CDDM_get_faces(dm);
> - for(i = 0; i < numFaces; i++, mf++) {
> + mfaces = CDDM_get_faces(dm);
> + for(i = 0; i < numFaces; i++) {
> + MFace * mf = &mfaces[i];
> float *f_no = face_nors[i];
>
> if(mf->v4)
> - normal_quad_v3( f_no,mv[mf->v1].co, mv[mf->v2].co, mv[mf->v3].co, mv[mf->v4].co);
> + normal_quad_v3(f_no, mv[mf->v1].co, mv[mf->v2].co, mv[mf->v3].co, mv[mf->v4].co);
> else
> - normal_tri_v3( f_no,mv[mf->v1].co, mv[mf->v2].co, mv[mf->v3].co);
> + normal_tri_v3(f_no, mv[mf->v1].co, mv[mf->v2].co, mv[mf->v3].co);
>
> - add_v3_v3(temp_nors[mf->v1], f_no);
> - add_v3_v3(temp_nors[mf->v2], f_no);
> - add_v3_v3(temp_nors[mf->v3], f_no);
> - if(mf->v4)
> - add_v3_v3(temp_nors[mf->v4], f_no);
> + if((mf->flag&ME_SMOOTH)!=0) {
> + float *n4 = (mf->v4)? temp_nors[mf->v4]: NULL;
> + float *c4 = (mf->v4)? mv[mf->v4].co: NULL;
> +
> + accumulate_vertex_normals(temp_nors[mf->v1], temp_nors[mf->v2], temp_nors[mf->v3], n4,
> + f_no, mv[mf->v1].co, mv[mf->v2].co, mv[mf->v3].co, c4);
> + }
> }
>
> + for(i = 0; i < numFaces; i++) {
> + MFace * mf = &mfaces[i];
> +
> + if((mf->flag&ME_SMOOTH)==0) {
> + float *f_no = face_nors[i];
> +
> + if(is_zero_v3(temp_nors[mf->v1])) copy_v3_v3(temp_nors[mf->v1], f_no);
> + if(is_zero_v3(temp_nors[mf->v2])) copy_v3_v3(temp_nors[mf->v2], f_no);
> + if(is_zero_v3(temp_nors[mf->v3])) copy_v3_v3(temp_nors[mf->v3], f_no);
> + if(mf->v4 && is_zero_v3(temp_nors[mf->v4])) copy_v3_v3(temp_nors[mf->v4], f_no);
> + }
> + }
> +
> /* normalize vertex normals and assign */
> for(i = 0; i < numVerts; i++, mv++) {
> float *no = temp_nors[i];
>
> - if (normalize_v3(no) == 0.0)
> + if(normalize_v3(no) == 0.0f)
> normalize_v3_v3(no, mv->co);
>
> normal_float_to_short_v3(mv->no, no);
>
> Modified: trunk/blender/source/blender/blenkernel/intern/mesh.c
> ===================================================================
> --- trunk/blender/source/blender/blenkernel/intern/mesh.c 2011-03-20 12:19:21 UTC (rev 35645)
> +++ trunk/blender/source/blender/blenkernel/intern/mesh.c 2011-03-20 13:35:35 UTC (rev 35646)
> @@ -1278,26 +1278,42 @@
> float *fnors= MEM_callocN(sizeof(*fnors)*3*numFaces, "meshnormals");
> int i;
>
> - for (i=0; i<numFaces; i++) {
> + for(i=0; i<numFaces; i++) {
> MFace *mf= &mfaces[i];
> float *f_no= &fnors[i*3];
>
> - if (mf->v4)
> - normal_quad_v3( f_no,mverts[mf->v1].co, mverts[mf->v2].co, mverts[mf->v3].co, mverts[mf->v4].co);
> + if(mf->v4)
> + normal_quad_v3(f_no, mverts[mf->v1].co, mverts[mf->v2].co, mverts[mf->v3].co, mverts[mf->v4].co);
> else
> - normal_tri_v3( f_no,mverts[mf->v1].co, mverts[mf->v2].co, mverts[mf->v3].co);
> -
> - add_v3_v3(tnorms[mf->v1], f_no);
> - add_v3_v3(tnorms[mf->v2], f_no);
> - add_v3_v3(tnorms[mf->v3], f_no);
> - if (mf->v4)
> - add_v3_v3(tnorms[mf->v4], f_no);
> + normal_tri_v3(f_no, mverts[mf->v1].co, mverts[mf->v2].co, mverts[mf->v3].co);
> +
> + if((mf->flag&ME_SMOOTH)!=0) {
> + float *n4 = (mf->v4)? tnorms[mf->v4]: NULL;
> + float *c4 = (mf->v4)? mverts[mf->v4].co: NULL;
> +
> + accumulate_vertex_normals(tnorms[mf->v1], tnorms[mf->v2], tnorms[mf->v3], n4,
> + f_no, mverts[mf->v1].co, mverts[mf->v2].co, mverts[mf->v3].co, c4);
> + }
> }
> - for (i=0; i<numVerts; i++) {
> +
> + for(i=0; i<numFaces; i++) {
> + MFace *mf= &mfaces[i];
> +
> + if((mf->flag&ME_SMOOTH)==0) {
> + float *f_no= &fnors[i*3];
> + if(is_zero_v3(tnorms[mf->v1])) copy_v3_v3(tnorms[mf->v1], f_no);
> + if(is_zero_v3(tnorms[mf->v2])) copy_v3_v3(tnorms[mf->v2], f_no);
> + if(is_zero_v3(tnorms[mf->v3])) copy_v3_v3(tnorms[mf->v3], f_no);
> + if(mf->v4 && is_zero_v3(tnorms[mf->v4])) copy_v3_v3(tnorms[mf->v4], f_no);
> + }
> + }
> +
> + /* following Mesh convention; we use vertex coordinate itself for normal in this case */
> + for(i=0; i<numVerts; i++) {
> MVert *mv= &mverts[i];
> float *no= tnorms[i];
>
> - if (normalize_v3(no)==0.0)
> + if(normalize_v3(no) == 0.0f)
> normalize_v3_v3(no, mv->co);
>
> normal_float_to_short_v3(mv->no, no);
> @@ -1305,11 +1321,10 @@
>
> MEM_freeN(tnorms);
>
> - if (faceNors_r) {
> + if(faceNors_r)
> *faceNors_r = fnors;
> - } else {
> + else
> MEM_freeN(fnors);
> - }
> }
>
> float (*mesh_getVertexCos(Mesh *me, int *numVerts_r))[3]
>
> Modified: trunk/blender/source/blender/blenlib/BLI_math_geom.h
> ===================================================================
> --- trunk/blender/source/blender/blenlib/BLI_math_geom.h 2011-03-20 12:19:21 UTC (rev 35645)
> +++ trunk/blender/source/blender/blenlib/BLI_math_geom.h 2011-03-20 13:35:35 UTC (rev 35646)
> @@ -169,6 +169,12 @@
> void map_to_tube(float *u, float *v, float x, float y, float z);
> void map_to_sphere(float *u, float *v, float x, float y, float z);
>
> +/********************************** Normals **********************************/
> +
> +void accumulate_vertex_normals(float n1[3], float n2[3], float n3[3],
> + float n4[3], const float f_no[3], const float co1[3], const float co2[3],
> + const float co3[3], const float co4[3]);
> +
> /********************************* Tangents **********************************/
>
> typedef struct VertexTangent {
>
> Modified: trunk/blender/source/blender/blenlib/intern/math_geom.c
> ===================================================================
> --- trunk/blender/source/blender/blenlib/intern/math_geom.c 2011-03-20 12:19:21 UTC (rev 35645)
> +++ trunk/blender/source/blender/blenlib/intern/math_geom.c 2011-03-20 13:35:35 UTC (rev 35646)
> @@ -1980,6 +1980,49 @@
> }
> }
>
> +/********************************* Normals **********************************/
> +
> +void accumulate_vertex_normals(float n1[3], float n2[3], float n3[3],
> + float n4[3], const float f_no[3], const float co1[3], const float co2[3],
> + const float co3[3], const float co4[3])
> +{
> + float vdiffs[4][3];
> + const int nverts= (n4!=NULL && co4!=NULL)? 4: 3;
> +
> + /* compute normalized edge vectors */
> + sub_v3_v3v3(vdiffs[0], co2, co1);
> + sub_v3_v3v3(vdiffs[1], co3, co2);
> +
> + if(nverts==3) {
> + sub_v3_v3v3(vdiffs[2], co1, co3);
> + }
> + else {
> + sub_v3_v3v3(vdiffs[2], co4, co3);
> + sub_v3_v3v3(vdiffs[3], co1, co4);
> + normalize_v3(vdiffs[3]);
> + }
> +
> + normalize_v3(vdiffs[0]);
> + normalize_v3(vdiffs[1]);
> + normalize_v3(vdiffs[2]);
> +
> + /* accumulate angle weighted face normal */
> + {
> + float *vn[]= {n1, n2, n3, n4};
> + const float *prev_edge = vdiffs[nverts-1];
> + int i;
> +
> + for(i=0; i<nverts; i++) {
> + const float *cur_edge= vdiffs[i];
> + const float fac= saacos(-dot_v3v3(cur_edge, prev_edge));
> +
> + // accumulate
> + madd_v3_v3fl(vn[i], f_no, fac);
> + prev_edge = cur_edge;
> + }
> + }
> +}
> +
> /********************************* Tangents **********************************/
>
> /* For normal map tangents we need to detect uv boundaries, and only average
>
> Modified: trunk/blender/source/blender/blenloader/intern/readfile.c
> ===================================================================
> --- trunk/blender/source/blender/blenloader/intern/readfile.c 2011-03-20 12:19:21 UTC (rev 35645)
> +++ trunk/blender/source/blender/blenloader/intern/readfile.c 2011-03-20 13:35:35 UTC (rev 35646)
> @@ -11551,6 +11551,13 @@
> }
> }
>
> + if (main->versionfile < 256 || (main->versionfile == 256 && main->subversionfile <4)){
> + Mesh *me;
> +
> + for(me= main->mesh.first; me; me= me->id.next)
> + mesh_calc_normals(me->mvert, me->totvert, me->mface, me->totface, NULL);
> + }
> +
> /* put compatibility code here until next subversion bump */
>
> {
>
> Modified: trunk/blender/source/blender/editors/mesh/editmesh_lib.c
> ===================================================================
> --- trunk/blender/source/blender/editors/mesh/editmesh_lib.c 2011-03-20 12:19:21 UTC (rev 35645)
> +++ trunk/blender/source/blender/editors/mesh/editmesh_lib.c 2011-03-20 13:35:35 UTC (rev 35646)
> @@ -2010,21 +2010,34 @@
> if(efa->v4) {
> normal_quad_v3( efa->n,efa->v1->co, efa->v2->co, efa->v3->co, efa->v4->co);
> cent_quad_v3(efa->cent, efa->v1->co, efa->v2->co, efa->v3->co, efa->v4->co);
> - add_v3_v3(efa->v4->no, efa->n);
> }
> else {
> normal_tri_v3( efa->n,efa->v1->co, efa->v2->co, efa->v3->co);
> cent_tri_v3(efa->cent, efa->v1->co, efa->v2->co, efa->v3->co);
> }
> - add_v3_v3(efa->v1->no, efa->n);
> - add_v3_v3(efa->v2->no, efa->n);
> - add_v3_v3(efa->v3->no, efa->n);
> +
> + if((efa->flag&ME_SMOOTH)!=0) {
> + float *n4= (efa->v4)? efa->v4->no: NULL;
> + float *c4= (efa->v4)? efa->v4->co: NULL;
> +
> + accumulate_vertex_normals(efa->v1->no, efa->v2->no, efa->v3->no, n4,
> + efa->n, efa->v1->co, efa->v2->co, efa->v3->co, c4);
> + }
> }
>
> + for(efa= em->faces.first; efa; efa=efa->next) {
> + if((efa->flag&ME_SMOOTH)==0) {
> + if(is_zero_v3(efa->v1->no)) copy_v3_v3(efa->v1->no, efa->n);
> + if(is_zero_v3(efa->v2->no)) copy_v3_v3(efa->v2->no, efa->n);
>
> @@ Diff output truncated at 10240 characters. @@
> _______________________________________________
> Bf-blender-cvs mailing list
> Bf-blender-cvs at blender.org
> http://lists.blender.org/mailman/listinfo/bf-blender-cvs
>
More information about the Bf-committers
mailing list