[Code] How do you compute weighted vertex normals?

[Code] How do you compute weighted vertex normals?

Postby thomthom » Wed Aug 24, 2011 12:26 pm

Reference:
http://www.bytehazard.com/code/vertnorm.html
http://meshlabstuff.blogspot.com/2009/0 ... rmals.html

How can you compute weighted vertex normals for vertices in SketchUp?

Vertex Normal.png

Compute vertex normals so these two boxes produces similar normals.
Adding up all connected face normals results in a normal that lean towards the triangulated side - which not what I want.




Current Solution
The current solution that appear to yield the best results:
Code: Select all

  def self
.vertex_normal( vertex )
    faces = vertex.faces
    edges 
= vertex.edges
    point 
= vertex.position
    normal 
= Geom::Vector3d.new( 0, 0, 0 )
    until faces.empty?
      face = faces.shift
      e1
, e2 = face.edges & edges
      
# Ensure the vectors are in the order of the loop.
      
test_vertex e1.reversed_in?( face ) ? e1.start e1.end
      
if test_vertex == vertex
        e1
e2 = [ e2e1 ]
      
end
      
# Now the full angle can be calculated.
      pt1 = e1.other_vertex( vertex ).position
      pt2 
= e2.other_vertex( vertex ).position
      v1 
= point.vector_to( pt1 )
      v2 = point.vector_to( pt2 )
      angle = self.full_angle_between( v1, v2, face.normal )
      face_normal = face.normal
      face_normal
.length = angle
      normal 
+= face_normal
    end
    normal
.normalize!
  end
  
  def self
.full_angle_between( vector1, vector2, normal )
    cross = vector1 * vector2
    direction 
= cross % normal
    angle 
= vector1.angle_between( vector2 )
    angle = 360.degrees - angle if direction > 0.0
    angle
  end
0
Last edited by thomthom on Thu Aug 25, 2011 12:04 pm, edited 7 times in total.
Reason: Added more description.
Thomas Thomassen — SketchUp Monkey & Coding addict
List of my plugins and link to the CookieWare fund
User avatar
thomthom 
PluginStore Author
PluginStore Author
 

Re: How do you computer weighted vertex normals?

Postby TIG » Wed Aug 24, 2011 12:47 pm

Perhaps something like
faces = vertex.faces
return nil if not faces[0]
norm = faces[0].normal
faces.shift
faces.each{|face| norm = norm + face.normal }
return norm

???
EDIT: Fixed typo * >>> + TIG.
0
TIG
User avatar
TIG 
Global Moderator
 

Re: How do you computer weighted vertex normals?

Postby thomthom » Wed Aug 24, 2011 1:02 pm

That's the naive version I used. But it doesn't always produce the normal one want. The linked articles describe the issues that method has, and further explains one has to weigh the contribution of the faces.
0
Thomas Thomassen — SketchUp Monkey & Coding addict
List of my plugins and link to the CookieWare fund
User avatar
thomthom 
PluginStore Author
PluginStore Author
 

Re: How do you computer weighted vertex normals?

Postby TIG » Wed Aug 24, 2011 1:13 pm

Well then try perhaps 'weight' by each face's surface area...
faces = vertex.faces
return nil if not faces[0]
norm = faces[0].normal
norm.length = faces[0].area
faces.shift
faces.each{|face|
fnor = face.normal
fnor.length = face.area
norm = norm + fnor
}
norm.normalize!
return norm

OR get relative angles between the normals and make adjustments ???
EDIT: typo fixed * >>> + TIG.
0
TIG
User avatar
TIG 
Global Moderator
 

Re: How do you computer weighted vertex normals?

Postby thomthom » Wed Aug 24, 2011 2:39 pm

That snippet gave me zero length vectors for a vertex with three connected faces at an corner.
0
Thomas Thomassen — SketchUp Monkey & Coding addict
List of my plugins and link to the CookieWare fund
User avatar
thomthom 
PluginStore Author
PluginStore Author
 

Re: How do you computer weighted vertex normals?

Postby Chris Fullmer » Wed Aug 24, 2011 4:11 pm

Wouldn't it have something to do with the angle between the 2 edges of the face at that vertex * that face's normal. Something so that a small sliver of a face - only 5 degrees for example, would get its normal * 5. Then a face with 90 degrees would get its normal weight * 90. Then combine all those normals, and the vector will be greater than 1, so normalize it to scale it back down.

Would that give an appropriate weight to each face in the overall vertex normal?
0
Lately you've been tan, suspicious for the winter.
All my Plugins I've written
User avatar
Chris Fullmer 
SketchUp Team
SketchUp Team
 

Re: How do you computer weighted vertex normals?

Postby thomthom » Wed Aug 24, 2011 4:21 pm

Chris Fullmer wrote:Wouldn't it have something to do with the angle between the 2 edges of the face at that vertex * that face's normal. Something so that a small sliver of a face - only 5 degrees for example, would get its normal * 5. Then a face with 90 degrees would get its normal weight * 90. Then combine all those normals, and the vector will be greater than 1, so normalize it to scale it back down.

Would that give an appropriate weight to each face in the overall vertex normal?

What you describe is one of the methods in the links in my OP. The problem is that I don't fully understand how to implement the weighting... :(
0
Thomas Thomassen — SketchUp Monkey & Coding addict
List of my plugins and link to the CookieWare fund
User avatar
thomthom 
PluginStore Author
PluginStore Author
 

Re: How do you computer weighted vertex normals?

Postby thomthom » Wed Aug 24, 2011 4:45 pm

This appear to work:
Code: Select all

def self
.vertex_normalvertex )
    
faces vertex.faces
    edges 
vertex.edges
    point 
vertex.position
    
return nil if faces.empty?
    
normal Geom::Vector3d.new( 00)
    
until faces.empty?
      
face faces.shift
      e1
e2 face.edges edges
      pt1 
e1.other_vertexvertex ).position
      pt2 
e2.other_vertexvertex ).position
      v1 
point.vector_topt1 )
      
v2 point.vector_topt2 )
      
angle v1.angle_betweenv2 )
      
face_normal face.normal
      face_normal
.length angle
      normal 
+= face_normal
    end
    normal
.normalize!
  
end
0
Thomas Thomassen — SketchUp Monkey & Coding addict
List of my plugins and link to the CookieWare fund
User avatar
thomthom 
PluginStore Author
PluginStore Author
 

Re: How do you computer weighted vertex normals?

Postby thomthom » Wed Aug 24, 2011 4:47 pm

Though, the linked article seem to also take into account the face area... wonder what importance that has...
0
Thomas Thomassen — SketchUp Monkey & Coding addict
List of my plugins and link to the CookieWare fund
User avatar
thomthom 
PluginStore Author
PluginStore Author
 

Re: How do you computer weighted vertex normals?

Postby thomthom » Wed Aug 24, 2011 5:38 pm

hmm... it must be flawed. if a face is connected to the vertex then vector1.angle_between( vector2 ) won't give the correct angle, as it only return angles between 0 - 180 degrees. Either I need to deal with each triangle in each face, or I calculate the full angle.
0
Thomas Thomassen — SketchUp Monkey & Coding addict
List of my plugins and link to the CookieWare fund
User avatar
thomthom 
PluginStore Author
PluginStore Author
 

Re: How do you computer weighted vertex normals?

Postby TIG » Wed Aug 24, 2011 6:06 pm

Stupid typo is my code should be norm + fnor not '*'... I've corrected the original - it should now work as expected - weighting vertex-normals dependent on the face's areas!
0
TIG
User avatar
TIG 
Global Moderator
 

Re: How do you computer weighted vertex normals?

Postby thomthom » Wed Aug 24, 2011 6:07 pm

This seem to account for wide angle corners:

Code: Select all

  def self
.vertex_normalvertex )
    
faces vertex.faces
    edges 
vertex.edges
    point 
vertex.position
    normal 
Geom::Vector3d.new( 00)
    
until faces.empty?
      
face faces.shift
      e1
e2 face.edges edges
      pt1 
e1.other_vertexvertex ).position
      pt2 
e2.other_vertexvertex ).position
      v1 
point.vector_topt1 )
      
v2 point.vector_topt2 )
      
angle self.full_angle_betweenv1v2face.normal )
      
face_normal face.normal
      face_normal
.length angle
      normal 
+= face_normal
    end
    normal
.normalize!
  
end
  
  def self
.full_angle_betweenvector1vector2normal )
    
cross vector1 vector2
    direction 
cross normal
    angle 
vector1.angle_betweenvector2 )
    
angle 360.degrees angle if direction 0.0
    angle
  end
0
Thomas Thomassen — SketchUp Monkey & Coding addict
List of my plugins and link to the CookieWare fund
User avatar
thomthom 
PluginStore Author
PluginStore Author
 

Re: How do you computer weighted vertex normals?

Postby thomthom » Wed Aug 24, 2011 6:09 pm

TIG wrote:Stupid typo is my code should be norm + fnorm not '*'... I've corrected the original - it should now work as expected !!!!

I'll revisit your code again. http://www.bytehazard.com/code/vertnorm.html mentions that using the area still makes some faces weigh too much, but that it's not that notable. But since it looks to require less computing that checking the angles then it might be preferable.
0
Thomas Thomassen — SketchUp Monkey & Coding addict
List of my plugins and link to the CookieWare fund
User avatar
thomthom 
PluginStore Author
PluginStore Author
 

Re: How do you computer weighted vertex normals?

Postby thomthom » Wed Aug 24, 2011 6:14 pm

hm... I added face area to the equations, but that yielded deviating normals depending how I divided the large face.
removing the face area appear to yield the exact same result.

VertexNormals.png

Weighted by angle:
  1. Vector3d(0.419345, 0.0772543, 0.904534)
  2. Vector3d(0.419345, 0.0772543, 0.904534)
  3. Vector3d(0.419345, 0.0772543, 0.904534)

Weighted by area * angle:
  1. Vector3d(0.324298, 0.116468, 0.938758)
  2. Vector3d(0.706956, 0.253896, 0.660114)
  3. Vector3d(0.770689, 0.276785, 0.573959)
0
Thomas Thomassen — SketchUp Monkey & Coding addict
List of my plugins and link to the CookieWare fund
User avatar
thomthom 
PluginStore Author
PluginStore Author
 

Re: [Code] How do you computer weighted vertex normals?

Postby thomthom » Wed Aug 24, 2011 6:32 pm

I wonder if the linked article uses the face area because they computer the normals for lighting...
0
Thomas Thomassen — SketchUp Monkey & Coding addict
List of my plugins and link to the CookieWare fund
User avatar
thomthom 
PluginStore Author
PluginStore Author
 

Re: [Code] How do you computer weighted vertex normals?

Postby TIG » Wed Aug 24, 2011 6:49 pm

Several coplanar faces at a vertex are the same as one face of the same area as the bits? So the both area-weight-adjusted vertex-normals will be the same.
I think it is more for lighting...
0
TIG
User avatar
TIG 
Global Moderator
 

Re: [Code] How do you computer weighted vertex normals?

Postby thomthom » Wed Aug 24, 2011 7:05 pm

TIG wrote:Several coplanar faces at a vertex are the same as one face of the same area as the bits? So the both area-weight-adjusted vertex-normals will be the same.

But if a vertex is connected to three sides, one large and two small, then using the area would make the normal lean toward the large area, would it not?
0
Thomas Thomassen — SketchUp Monkey & Coding addict
List of my plugins and link to the CookieWare fund
User avatar
thomthom 
PluginStore Author
PluginStore Author
 

Re: [Code] How do you computer weighted vertex normals?

Postby TIG » Wed Aug 24, 2011 7:32 pm

Not if the two small areas were equivalent to the large one... then it'd be 'balanced'...
The large area pulls it over then the 1st small are pulls it back and then the 2nd small area pulls it back again.
IF there's a large and a small area the large one 'wins'.
0
TIG
User avatar
TIG 
Global Moderator
 

Re: [Code] How do you computer weighted vertex normals?

Postby voljanko » Wed Aug 24, 2011 7:43 pm

By computer you mean compute?
0
SuSolid.com - solid check - solid repair- solid intersection check - weight plugin
User avatar
voljanko 
PluginStore Author
PluginStore Author
 

Re: [Code] How do you computer weighted vertex normals?

Postby TIG » Wed Aug 24, 2011 7:48 pm

voljanko wrote:By computer you mean compute?
A simple typo by tt in the original title - but we understood what he meant... ;)
0
TIG
User avatar
TIG 
Global Moderator
 

Re: [Code] How do you computer weighted vertex normals?

Postby voljanko » Wed Aug 24, 2011 8:00 pm

I'm trying to follow your conversation,but not sure to understand what are you trying to do.
Do you want to align faces that are nearly aligned?
0
SuSolid.com - solid check - solid repair- solid intersection check - weight plugin
User avatar
voljanko 
PluginStore Author
PluginStore Author
 

Re: [Code] How do you computer weighted vertex normals?

Postby thomthom » Wed Aug 24, 2011 8:47 pm

TIG wrote:Not if the two small areas were equivalent to the large one... then it'd be 'balanced'...
The large area pulls it over then the 1st small are pulls it back and then the 2nd small area pulls it back again.
IF there's a large and a small area the large one 'wins'.

Yes, but when they are not, which would be in any non-regular mesh. So I still wonder why one would use area to weigh the normals.
0
Thomas Thomassen — SketchUp Monkey & Coding addict
List of my plugins and link to the CookieWare fund
User avatar
thomthom 
PluginStore Author
PluginStore Author
 

Re: [Code] How do you computer weighted vertex normals?

Postby thomthom » Wed Aug 24, 2011 8:47 pm

TIG wrote:
voljanko wrote:By computer you mean compute?
A simple typo by tt in the original title - but we understood what he meant... ;)

Fixed! :oops:
0
Thomas Thomassen — SketchUp Monkey & Coding addict
List of my plugins and link to the CookieWare fund
User avatar
thomthom 
PluginStore Author
PluginStore Author
 

Re: [Code] How do you computer weighted vertex normals?

Postby thomthom » Wed Aug 24, 2011 8:49 pm

voljanko wrote:I'm trying to follow your conversation,but not sure to understand what are you trying to do.
Do you want to align faces that are nearly aligned?

No, I just want to compute the vertex normals.
In this particular case I need it to be able to calculate some of the topographical characteristic of the mesh.
0
Thomas Thomassen — SketchUp Monkey & Coding addict
List of my plugins and link to the CookieWare fund
User avatar
thomthom 
PluginStore Author
PluginStore Author
 

Re: [Code] How do you compute weighted vertex normals?

Postby thomthom » Thu Aug 25, 2011 9:28 am

My full_angle_between code seem to not work in all scenarios... back to the drawing table...
0
Thomas Thomassen — SketchUp Monkey & Coding addict
List of my plugins and link to the CookieWare fund
User avatar
thomthom 
PluginStore Author
PluginStore Author
 

Re: [Code] How do you compute weighted vertex normals?

Postby thomthom » Thu Aug 25, 2011 12:05 pm

Now I seemed to have corrected it. I had to ensure the vectors I used came in the same direction as the edge loop.
0
Thomas Thomassen — SketchUp Monkey & Coding addict
List of my plugins and link to the CookieWare fund
User avatar
thomthom 
PluginStore Author
PluginStore Author
 

SketchUcation One-Liner Adverts

by Ad Machine » 5 minutes ago



Ad Machine 
Robot
 



 

Return to Developers' Forum

Who is online

Users browsing this forum: No registered users and 14 guests