sketchucation logo sketchucation
    • Login
    ℹ️ Licensed Extensions | FredoBatch, ElevationProfile, FredoSketch, LayOps, MatSim and Pic2Shape will require license from Sept 1st More Info

    Vertex Normals... ?

    Scheduled Pinned Locked Moved Developers' Forum
    26 Posts 6 Posters 2.4k Views 6 Watching
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • A Offline
      Anton_S
      last edited by

      I'm no expert, but I don't think it would be logical for a vertex to have a normal. It's just a point connecting edges and faces. Of course, the vertex normal could be determined by probably adding the normals of the connected faces. You can start off by using the Sketchup::Vertex.#faces function, which returns all the connected faces.

      1 Reply Last reply Reply Quote 0
      • tt_suT Offline
        tt_su
        last edited by

        @oajfh said:

        If I'm not mistaken (I could be, but API doc is down for me atm), the PolygonMesh.normal_at method will return the normal of the face it was created from (if it was created from a mesh).

        PolygonMesh will in fact return vector normal. It depend on the edges connected are soft+smooth or note.
        However, not too long ago we followed up on a developer support request where it turned out that the internal vertex normal cache some times was invalid when the mesh was obtained - in which case the normals wasn't what you expected.

        I don't recall the exact detail right now.

        For Vertex Tools, I added a feature to visualize vertex normals, but I wrote my own method to calculate this. This is currently done in Ruby - which isn't the fastest way to compute things. If you need a bulk set of vertices to calculate normals for then a Ruby C extensions might be useful to get some better performance.

        Can you provide some info to what you want to use the vertex normals for and when you are trying to obtain them?

        1 Reply Last reply Reply Quote 0
        • sdmitchS Offline
          sdmitch
          last edited by

          @oajfh said:

          Hiya all.

          Is there a cheap and easy way to get vertex normals from a mesh, or do I have to do some weighted averaging of the face normals manually ?

          If I'm not mistaken (I could be, but API doc is down for me atm), the PolygonMesh.normal_at method will return the normal of the face it was created from (if it was created from a mesh).

          I'm pretty sure I'm going to need to fiddle with vertex normals at some point, and I'm mildly surprised there isn't any direct way of accessing the vertex normals. Aren't they used internally ?

          Older posts seem to indicate that there isn't a way to access the vertex normals. Perhaps things have changed... ?

          This seems to work

          mod = Sketchup.active_model
          ent = mod.active_entities
          sel = mod.selection
          sel.empty? ? ents=ent ; ents=sel
          vrt = []; vertex_and_normal = []
          ents.grep(Sketchup;;Face).each{|f| vrt<<f.vertices}
          vrt.flatten!;vrt.uniq!
          vrt.each{|v|
           nrm = Geom;;Vector3d.new(0,0,0)
           for f in v.faces
            nrm += f.normal
           end
           vertex_and_normal << [v.position,nrm.normalize]
          }
          vertex_and_normal.each{|van|
           ent.add_cline(van[0],van[0].offset(van[1],12))
          }
          
          

          Nothing is worthless, it can always be used as a bad example.

          http://sdmitch.blogspot.com/

          1 Reply Last reply Reply Quote 0
          • O Offline
            oajfh
            last edited by

            Thanks for the replies.

            I don't specifically need the vertex normals in Ruby itself (although visualising them in there would be useful, I suppose). It's for fiddling with stuff like Gouraud shading, amongst other things. But that's outside of Sketchup, so I can write it outside of the Ruby. I don't need them in Sketchup itself.

            It's just that I wouldn't have minded if I didn't need to rewrite such a method myself if it happened to be implemented somewhere already, being inherently lazy 😄

            Also, sdmitch, your code works fine but doesn't apply any weighting to the faces, which means subdividing a triangle your vertex is in (for example) changes the normal value, which isn't always ideal.

            1 Reply Last reply Reply Quote 0
            • tt_suT Offline
              tt_su
              last edited by

              Yea - fully understand. I wish I could say that the PolygonMesh returned a reliable vertex normal, but as it is right now I think there are issues if you happen to query it after the cache is invalidated and generated. (This is a result of Geom::PolygonMesh tapping directly into the polygonmesh we use for triangulation and the vertex normal cache is controlled by SU when it needs it - which can leave the API in the dark... :/)

              1 Reply Last reply Reply Quote 0
              • tt_suT Offline
                tt_su
                last edited by

                @sdmitch said:

                This seems to work

                Have a look at this thread: http://sketchucation.com/forums/viewtopic.php?f=180%26amp;t=39625

                1 Reply Last reply Reply Quote 0
                • O Offline
                  oajfh
                  last edited by

                  Thanks ThomThom, I had seen that thread but was wondering if things had changed.

                  In any case, I'll work on it outside of SU. I don't think there are many people who would need vertex normals while working in SU, since they are mostly used for lighting and rendering (as far as I know, anyway, but I don't know much).
                  However, perhaps a way to recover them in exporters could be useful, I dunno.

                  Also, just in case, could you clarify this statement :
                  "PolygonMesh will in fact return vector normal. It depend on the edges connected are soft+smooth or note."

                  So they do return vertex normals... ? I thought it was a normal linked to the surface. Sorry, I'm confused. I'm not sure I understood what you meant completely, could you possibly expand on it ?

                  [Edit] Never mind, I think I got it. I can recover vertex normals but they might not be reliable for now ?
                  In that case, I guess I will recover Face normals for now.

                  1 Reply Last reply Reply Quote 0
                  • tt_suT Offline
                    tt_su
                    last edited by

                    @oajfh said:

                    Also, just in case, could you clarify this statement :
                    "PolygonMesh will in fact return vector normal. It depend on the edges connected are soft+smooth or note."

                    Sorry - I think I confused polygon meshes normals vs the ones I made up in Vertex Tools (There the faces will contribute to a vertex normal only if the edge separating them is soft-smooth. So that the normal depend on the smoothing of the surface. but the PolygonMesh shouldn't do this.)

                    Yea - exporters do tend to have a need for this. I think they generally are able to use PolygonMesh for this. But I think there was issues for live render engines - which queried the polygonmesh in the middle of operations (at which point the cache might be invalid.) We should have an issue file for this to look into.

                    1 Reply Last reply Reply Quote 0
                    • O Offline
                      oajfh
                      last edited by

                      Ok, thanks.

                      1 Reply Last reply Reply Quote 0
                      • tt_suT Offline
                        tt_su
                        last edited by

                        By the way - what version of SU are you developing in?
                        In SU2015 the polygon_mesh should return correct vertex normal - as we make sure to rebuild the cache if it's invalid when the mesh is built.
                        http://www.sketchup.com/intl/en/developer/docs/releases

                        @unknownuser said:

                        Fixed a bug where Geom::PolygonMesh.normal_at would not return correct vertex normal if the model was modified in the same processing loop as the script obtaining the PolygonMesh.

                        1 Reply Last reply Reply Quote 0
                        • O Offline
                          oajfh
                          last edited by

                          I'm using SU 2015.

                          I was just confused mostly by the documentation, heh -I'm still a rather inexperienced Ruby and SU coder, and when I wanted to look it up and check the methods the SU doc site was down, so I thought I might as well ask here and learn a little more.

                          If vertex normals can be safely recovered, then perhaps I should use those.

                          Hmm. How would that fare performance-wise ? If I want to recover vertex normals, I probably end up checking vertexes multiple times and making sure I don't get a normal from the same vertex more than once, but on the other hand calculating face normals is faster than calculating weighted vertex normals.

                          1 Reply Last reply Reply Quote 0
                          • Dan RathbunD Offline
                            Dan Rathbun
                            last edited by

                            Face.vertices and Edge.vertices both return an array.

                            You'll likely be concat'ing these returned arrays with a "master" array collection.

                            After stuffing the master array, you can use the Array#uniq! method to remove duplicates, before processing.

                            I'm not here much anymore.

                            1 Reply Last reply Reply Quote 0
                            • tt_suT Offline
                              tt_su
                              last edited by

                              @oajfh said:

                              Hmm. How would that fare performance-wise ? If I want to recover vertex normals, I probably end up checking vertexes multiple times and making sure I don't get a normal from the same vertex more than once, but on the other hand calculating face normals is faster than calculating weighted vertex normals.

                              Yea - that's a good point. I don't think you can rely on 100% that the order of the points in PolygonMesh to match the face it came from.

                              If performance is critical I think you will get best results from calculating in C/C++ via A Ruby extension which then only iterates the vertices (though you need to collect that from edges or faces - but collecting that into an std::set or something shouldn't affect your performance too much.). You then do the calculations with native code.

                              1 Reply Last reply Reply Quote 0
                              • O Offline
                                oajfh
                                last edited by

                                Thanks for the tips Dan.

                                My code recovers points rather than vertices from a component (it's based off what Anton_S posted in my topic about PolygonMesh triangulation).

                                ThomThom, doesn't the add_polygon method simply add any new points at the end of the point array ? That's the behaviour it's exhibited for me so far, so wouldn't applying what Dan said be alright ?

                                On another note, the vertex normal seems to be local to the transformation the face's parent possesses. It complexifies the recursion somewhat to recover the transformation at that point in the iteration.

                                I'll just post my code, it'll be clearer for you. Thanks again to the both of you and Anton_S, by the way.

                                
                                # Original credit ; Anton_S
                                # Get group/component entities.
                                # @param [Sketchup;;Group, Sketchup;;ComponentInstance] entity
                                # @return [Sketchup;;Entities]
                                def get_entities(entity)
                                	if entity.is_a?(Sketchup;;ComponentInstance)
                                		return entity.definition.entities
                                	else 
                                		return entity.entities
                                	end
                                end
                                
                                # Original credit ; Anton_S
                                # Get triangular mesh of the group.
                                # @param [Sketchup;;Group, Sketchup;;ComponentInstance] entity
                                # @param [Boolean] recursive Whether to include all the child groups and
                                #   components.
                                # @param [Boolean] transform Whether to give points in global coordinates.
                                # @param [Integer] Keep face counter so as not to mess up normal exporting
                                # @yield A procedure to determine whether particular child group/component
                                #   should be considered a part of the collection.
                                # @yieldparam [Sketchup;;Group, Sketchup;;ComponentInstance] entity
                                # @yieldreturn [Boolean] Pass true to consider an entity as part of the
                                #   collection. Pass false to not consider an entity as part of the
                                #   collection.
                                # @return [Geom;;PolygonMesh]
                                def get_triangular_mesh(entity, recursive = true, transform = false,normal_array, &entity_validation)
                                
                                  mesh = Geom;;PolygonMesh.new
                                  if( entity.is_a?(;;Sketchup;;Face)||entity.is_a?(;;Sketchup;;ComponentInstance)||entity.is_a?(;;Sketchup;;Group))
                                	get_entities(entity).each { |e|
                                		if e.is_a?(;;Sketchup;;Face)
                                
                                			e.mesh.polygons.each_index{ |i|
                                			pts = e.mesh.polygon_points_at(i+1)
                                			
                                			mesh_b = e.mesh 4
                                
                                			index = mesh.add_polygon(pts) # Note ; index not necessary here
                                		
                                			normal_array << e.normal # add face normal
                                			
                                			#puts "e"
                                			for k in 1..mesh_b.count_points
                                				#puts mesh_b.point_at(k) #Not global coordinates
                                				#puts mesh_b.normal_at(k) #Not global coordinates... ?
                                			end
                                			puts "j"
                                      }
                                		elsif recursive && (e.is_a?(;;Sketchup;;Group) || e.is_a?(;;Sketchup;;ComponentInstance)) && entity_validation.call(e)
                                			new_array = []
                                			mesh2 = get_triangular_mesh(e, true, true, new_array, &entity_validation)
                                			mesh2.polygons.each_index { |i|
                                			index = mesh.add_polygon(mesh2.polygon_points_at(i+1))
                                			normal_array[index] = new_array[i] # Doesn't seem to be overriding previous values
                                			#counter=counter+1
                                			#puts counter
                                		}
                                    end
                                  }
                                  mesh.transform!(entity.transformation) if transform
                                  end
                                  return mesh
                                end
                                
                                
                                group = Sketchup.active_model.selection[0] # Lazy component recovery
                                
                                #TODO begin end
                                
                                normal_array = [] # Contains the face normals.
                                mesh = get_triangular_mesh(group, true, true,normal_array){ |e| true }
                                puts mesh.points
                                pt = Geom;;Point3d.new(100,0,0)
                                mesh.transform!(pt) # Move triangles 100 units on xaxis from original component.
                                Sketchup.active_model.entities.add_faces_from_mesh(mesh, 0)
                                
                                
                                #puts mesh.points # translated mesh
                                
                                

                                It isn't super fast though.

                                Actually, perhaps the simplest would be to traverse the triangulation a second time ? The generated mesh is all in global coordinates, so the normals would be as well.

                                I could probably do that as a temporary solution, until performance becomes too critical and I have to do stuff out of Ruby. I'm still prototyping, so I just need a reliable way of recovering the normals for the moment.

                                1 Reply Last reply Reply Quote 0
                                • tt_suT Offline
                                  tt_su
                                  last edited by

                                  @oajfh said:

                                  ThomThom, doesn't the add_polygon method simply add any new points at the end of the point array ? That's the behaviour it's exhibited for me so far, so wouldn't applying what Dan said be alright ?

                                  PolygonMesh.add_point will add a new point only if there isn't an existing point for the same location (within tolerance). This means it looks up the existing points (which unfortunately is a linear look up.)
                                  PolygonMesh.add_polygon will internally call this same function.

                                  The linear nature of add_point I assume is because internally this class is for use with individual faces - so you're not going to have that many points nor duplicates.

                                  To get max performance when building a PolygonMesh you add all the points first - collecting the indices you get in return. Then add polygons using indices instead of points - this reduce the number of linear lookups.

                                  I usually use a Hash to build a source => polygon_point_index lookup. This can be vertex => index for instance.

                                  1 Reply Last reply Reply Quote 0
                                  • tt_suT Offline
                                    tt_su
                                    last edited by

                                    Btw - if you build your own PolygonMesh from scratch the vertex normals won't be correct I believe...

                                    1 Reply Last reply Reply Quote 0
                                    • O Offline
                                      oajfh
                                      last edited by

                                      I'm building it from an existing component, so I'd simply be copying existing normals. Why would the vertex normals be incorrect ?

                                      Also, are you sure about the point to point comparison ? If you create different groups within a component, won't it duplicate the points ? I was getting different results after exploding groups and creating the mesh after making a component out of the exploded ex-groups. So the comparison might not only be coordinate-based.

                                      Thanks for the tip on performance, too. Will come in handy.

                                      1 Reply Last reply Reply Quote 0
                                      • tt_suT Offline
                                        tt_su
                                        last edited by

                                        @oajfh said:

                                        I'm building it from an existing component, so I'd simply be copying existing normals. Why would the vertex normals be incorrect ?

                                        If you query mesh.normal_at(i) on a mesh you created yourself (Geom::PolygonMesh.new) vs face.mesh the normals won't be computed for you.

                                        @oajfh said:

                                        Also, are you sure about the point to point comparison ? If you create different groups within a component, won't it duplicate the points ?

                                        You can observer this in action by inspecting the indices and point count:

                                        <span class="syntaxdefault"><br />mesh&nbsp;</span><span class="syntaxkeyword">=&nbsp;</span><span class="syntaxdefault">Geom</span><span class="syntaxkeyword">;;</span><span class="syntaxdefault">PolygonMesh</span><span class="syntaxkeyword">.new<br /></span><span class="syntaxcomment">#<Geom;;PolygonMesh;0x0000000936e850><br /><br /></span><span class="syntaxdefault">index1&nbsp;</span><span class="syntaxkeyword">=&nbsp;</span><span class="syntaxdefault">mesh</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">add_point</span><span class="syntaxkeyword">(</span><span class="syntaxdefault">Geom</span><span class="syntaxkeyword">;;</span><span class="syntaxdefault">Point3d</span><span class="syntaxkeyword">.new(</span><span class="syntaxdefault">1</span><span class="syntaxkeyword">,&nbsp;</span><span class="syntaxdefault">2</span><span class="syntaxkeyword">,&nbsp;</span><span class="syntaxdefault">3</span><span class="syntaxkeyword">))<br /></span><span class="syntaxdefault">1<br /><br />index2&nbsp;</span><span class="syntaxkeyword">=&nbsp;</span><span class="syntaxdefault">mesh</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">add_point</span><span class="syntaxkeyword">(</span><span class="syntaxdefault">Geom</span><span class="syntaxkeyword">;;</span><span class="syntaxdefault">Point3d</span><span class="syntaxkeyword">.new(</span><span class="syntaxdefault">1</span><span class="syntaxkeyword">,&nbsp;</span><span class="syntaxdefault">2</span><span class="syntaxkeyword">,&nbsp;</span><span class="syntaxdefault">3</span><span class="syntaxkeyword">))<br /></span><span class="syntaxdefault">1<br /><br />index3&nbsp;</span><span class="syntaxkeyword">=&nbsp;</span><span class="syntaxdefault">mesh</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">add_point</span><span class="syntaxkeyword">(</span><span class="syntaxdefault">Geom</span><span class="syntaxkeyword">;;</span><span class="syntaxdefault">Point3d</span><span class="syntaxkeyword">.new(</span><span class="syntaxdefault">1</span><span class="syntaxkeyword">,&nbsp;</span><span class="syntaxdefault">2</span><span class="syntaxkeyword">,&nbsp;</span><span class="syntaxdefault">3.5</span><span class="syntaxkeyword">))<br /></span><span class="syntaxdefault">2<br /><br />mesh</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">count_points<br />2<br /></span>
                                        

                                        Or by adding polygons using 3d points:

                                        <span class="syntaxdefault"><br />mesh&nbsp;</span><span class="syntaxkeyword">=&nbsp;</span><span class="syntaxdefault">Geom</span><span class="syntaxkeyword">;;</span><span class="syntaxdefault">PolygonMesh</span><span class="syntaxkeyword">.new<br /></span><span class="syntaxcomment">#<Geom;;PolygonMesh;0x0000000a70ec48><br /><br /></span><span class="syntaxdefault">mesh</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">add_polygon</span><span class="syntaxkeyword">(</span><span class="syntaxdefault">Geom</span><span class="syntaxkeyword">;;</span><span class="syntaxdefault">Point3d</span><span class="syntaxkeyword">.new(</span><span class="syntaxdefault">1</span><span class="syntaxkeyword">,</span><span class="syntaxdefault">1</span><span class="syntaxkeyword">,</span><span class="syntaxdefault">1</span><span class="syntaxkeyword">),&nbsp;</span><span class="syntaxdefault">Geom</span><span class="syntaxkeyword">;;</span><span class="syntaxdefault">Point3d</span><span class="syntaxkeyword">.new(</span><span class="syntaxdefault">5</span><span class="syntaxkeyword">,</span><span class="syntaxdefault">1</span><span class="syntaxkeyword">,</span><span class="syntaxdefault">1</span><span class="syntaxkeyword">),&nbsp;</span><span class="syntaxdefault">Geom</span><span class="syntaxkeyword">;;</span><span class="syntaxdefault">Point3d</span><span class="syntaxkeyword">.new(</span><span class="syntaxdefault">5</span><span class="syntaxkeyword">,</span><span class="syntaxdefault">5</span><span class="syntaxkeyword">,</span><span class="syntaxdefault">1</span><span class="syntaxkeyword">))<br /></span><span class="syntaxdefault">1<br /><br />mesh</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">add_polygon</span><span class="syntaxkeyword">(</span><span class="syntaxdefault">Geom</span><span class="syntaxkeyword">;;</span><span class="syntaxdefault">Point3d</span><span class="syntaxkeyword">.new(</span><span class="syntaxdefault">1</span><span class="syntaxkeyword">,</span><span class="syntaxdefault">1</span><span class="syntaxkeyword">,</span><span class="syntaxdefault">1</span><span class="syntaxkeyword">),&nbsp;</span><span class="syntaxdefault">Geom</span><span class="syntaxkeyword">;;</span><span class="syntaxdefault">Point3d</span><span class="syntaxkeyword">.new(</span><span class="syntaxdefault">5</span><span class="syntaxkeyword">,</span><span class="syntaxdefault">1</span><span class="syntaxkeyword">,</span><span class="syntaxdefault">1</span><span class="syntaxkeyword">),&nbsp;</span><span class="syntaxdefault">Geom</span><span class="syntaxkeyword">;;</span><span class="syntaxdefault">Point3d</span><span class="syntaxkeyword">.new(</span><span class="syntaxdefault">5</span><span class="syntaxkeyword">,-</span><span class="syntaxdefault">5</span><span class="syntaxkeyword">,</span><span class="syntaxdefault">1</span><span class="syntaxkeyword">))<br /></span><span class="syntaxdefault">2<br /><br />mesh</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">count_polygons<br />2<br /><br />mesh</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">count_points<br />4<br /></span>
                                        
                                        1 Reply Last reply Reply Quote 0
                                        • tt_suT Offline
                                          tt_su
                                          last edited by

                                          @oajfh said:

                                          I was getting different results after exploding groups and creating the mesh after making a component out of the exploded ex-groups. So the comparison might not only be coordinate-based.

                                          When you explode the coordinates of the vertices are transformed to it's parents - so you will see different values then before they they where local to the component definition.
                                          (Also, entities in model.active_entities) are transformed into global coordinates.)

                                          1 Reply Last reply Reply Quote 0
                                          • O Offline
                                            oajfh
                                            last edited by

                                            Well, after more experimenting, taking into account what's been said :

                                            
                                            # Original credit ; Anton_S
                                            # Get group/component entities.
                                            # @param [Sketchup;;Group, Sketchup;;ComponentInstance] entity
                                            # @return [Sketchup;;Entities]
                                            def get_entities(entity)
                                            	if entity.is_a?(Sketchup;;ComponentInstance)
                                            		return entity.definition.entities
                                            	else 
                                            		return entity.entities
                                            	end
                                            end
                                            
                                            # Original credit ; Anton_S
                                            # Get triangular mesh of the group.
                                            # @param [Sketchup;;Group, Sketchup;;ComponentInstance] entity
                                            # @param [Boolean] recursive Whether to include all the child groups and
                                            #   components.
                                            # @param [Boolean] transform Whether to give points in global coordinates.
                                            # @param [Integer] Keep face counter so as not to mess up normal exporting
                                            # @yield A procedure to determine whether particular child group/component
                                            #   should be considered a part of the collection.
                                            # @yieldparam [Sketchup;;Group, Sketchup;;ComponentInstance] entity
                                            # @yieldreturn [Boolean] Pass true to consider an entity as part of the
                                            #   collection. Pass false to not consider an entity as part of the
                                            #   collection.
                                            # @return [Geom;;PolygonMesh]
                                            def get_triangular_mesh(entity, recursive = true, transform = false,normal_array, &entity_validation)
                                            
                                              mesh = Geom;;PolygonMesh.new
                                              if( entity.is_a?(;;Sketchup;;Face)||entity.is_a?(;;Sketchup;;ComponentInstance)||entity.is_a?(;;Sketchup;;Group))
                                            	get_entities(entity).each { |e|
                                            		if e.is_a?(;;Sketchup;;Face)
                                            
                                            			e.mesh.polygons.each_index{ |i|
                                            			pts = e.mesh.polygon_points_at(i+1)
                                            			
                                            			mesh_b = e.mesh 4 #Temp face with normals
                                            
                                            			index = mesh.add_polygon(pts)
                                            			
                                            			#puts "e"
                                            			for k in 1..mesh_b.count_points
                                            				#puts "k"
                                            				#puts mesh_b.point_at(k) #Not global coordinates
                                            				#puts mesh_b.normal_at(k)
                                            				index = mesh.point_index(mesh_b.point_at(k)) # Get index of current point being examined
                                            				#puts index
                                            				#puts mesh.point_at(index)
                                            				#puts "k"
                                            				normal_array[index] = mesh_b.normal_at(k) # Set that point's normal to the current point's normal's value
                                            			end
                                            			#puts "j"
                                                  }
                                            		elsif recursive && (e.is_a?(;;Sketchup;;Group) || e.is_a?(;;Sketchup;;ComponentInstance)) && entity_validation.call(e)
                                            			new_array = []
                                            			mesh2 = get_triangular_mesh(e, true, true, new_array, &entity_validation)
                                            			mesh2.polygons.each_index { |i|
                                            			index = mesh.add_polygon(mesh2.polygon_points_at(i+1))
                                            
                                            			mesh2.points.each_with_index{|point, index|
                                            				ind = mesh.point_index(point)
                                            				normal_array[ind]= new_array[index]
                                            			}
                                            		}
                                                end
                                              }
                                              mesh.transform!(entity.transformation) if transform
                                            	for l in 1..normal_array.length-1 #index 0 not used so length is 1 more than expected
                                            		#puts l
                                            		normal_array[l].transform!(entity.transformation) if transform
                                            	end
                                              end
                                              return mesh
                                            end
                                            
                                            
                                            normal_array = [] # Contains the VERTEX normals.
                                            mesh = get_triangular_mesh(group, true, true,normal_array){ |e| true }
                                            
                                            
                                            

                                            (This code is bad and unoptimised, I'm aware of that. I'm a terrible programmer)

                                            I'm not sure what to think of this.

                                            If I look at what vertex normals are returned during recursion, I occasionally get different normals for what appears to be the same vertex, and I don't know why. For a cube, I only get global axis-aligned vectors, which isn't really what I was expecting.

                                            1 Reply Last reply Reply Quote 0
                                            • 1
                                            • 2
                                            • 1 / 2
                                            • First post
                                              Last post
                                            Buy SketchPlus
                                            Buy SUbD
                                            Buy WrapR
                                            Buy eBook
                                            Buy Modelur
                                            Buy Vertex Tools
                                            Buy SketchCuisine
                                            Buy FormFonts

                                            Advertisement