[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

Brecht Van Lommel brechtvanlommel at pandora.be
Fri Mar 25 10:47:38 CET 2011


There's also a bug about this in the tracker, will be fixed.

Thanks.

On Fri, Mar 25, 2011 at 3:36 AM, Campbell Barton <ideasman42 at gmail.com> wrote:
> This also causes a problem with modifiers that use the vertex normal,
> https://projects.blender.org/tracker/index.php?func=detail&aid=26582&group_id=9&atid=498
>
> new code
>  >>> bpy.context.object.data.vertices[0].normal
>  Vector((0.0, 0.0, -1.0))
>
> 2.56
>   >>> bpy.context.object.data.vertices[0].normal
>  Vector((0.5773491859436035, 0.5773491859436035, -0.5773491859436035))
>
> On Fri, Mar 25, 2011 at 1:35 AM, Nicholas Bishop
> <nicholasbishop at gmail.com> wrote:
>> 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
>>>
>> _______________________________________________
>> Bf-committers mailing list
>> Bf-committers at blender.org
>> http://lists.blender.org/mailman/listinfo/bf-committers
>>
>
>
>
> --
> - Campbell
> _______________________________________________
> Bf-committers mailing list
> Bf-committers at blender.org
> http://lists.blender.org/mailman/listinfo/bf-committers
>


More information about the Bf-committers mailing list