Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
 
Share Thread:
Reddit Facebook Twitter
Anyone else suffer because vertex normals calc wrongly?
03-28-2014, 01:50 AM
Post: #2
RE: Anyone else suffer because vertex normals calc wrongly?
This MIGHT be better approach for some folks.

Code:
normal(V, #we{}=We) ->
  EL = wings_edge:from_vs([V], We),
  case EL  of
     [_,_] -> normal0(V, We);
     _ -> normal1(V, We)
  end.
        
%% normal(Vertex, We) -> Normal
%%  Calculate the normal for a vertex (based on the normals for all
%%  surrounding faces).
normal0(V, We) ->
    Ns = fold(fun(_, Face, _, A) ->
              [wings_face:normal(Face, We)|A]
          end, [], V, We),
    e3d_vec:norm(e3d_vec:add(Ns)).  
    
    
normal1(V, #we{vp=VPos, es=Etab}=We) ->
    MyAcc = fun(Edge, _, _, A) ->
        #edge{vs=VS,ve=VE}=array:get(Edge,Etab),
        case VS of
            V -> [VE|A];
            _ -> [VS|A]
        end
    end,
    
    Vs = fold(MyAcc, [], V, We),  %% outer verts !
    Len = length(Vs),
    
    MyAcc2 = fun(Idx1, Acc) ->
        Idx2 = (Idx1 + 1) rem Len,
        Pt2 = array:get(lists:nth(Idx2+1,Vs), VPos),
        Pt1 = array:get(lists:nth(Idx1+1,Vs), VPos),
        Pt0 = array:get(V, VPos),
        D1 = e3d_vec:sub(Pt2,Pt0),
        D2 = e3d_vec:sub(Pt1,Pt0),
        Cross0 = e3d_vec:cross(D1, D2),
        Cross = e3d_vec:norm(Cross0),
        [Cross|Acc]
    end,
    
    Ns = lists:foldl(MyAcc2, [], lists:seq(0,Len-1) ),
    N1 = e3d_vec:norm(e3d_vec:add(Ns)),
    N2 = normal0(V,We),
    case  e3d_vec:degrees(N1,N2) > 90.0 of
        true ->  e3d_vec:mul(N1,-1.0);
        false -> N1
    end.
Reply


Messages In This Thread
RE: Anyone else suffer because vertex normals calc wrongly? - ggaliens - 03-28-2014 01:50 AM

Forum Jump:


User(s) browsing this thread: 1 Guest(s)