Skip to content

Instantly share code, notes, and snippets.

@thomthom
Created March 14, 2013 09:40
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save thomthom/5160068 to your computer and use it in GitHub Desktop.
Save thomthom/5160068 to your computer and use it in GitHub Desktop.
Experimental mapping of SketchUp's Geom::PolygonMesh points to vertices.
# Experimental mapping of PolygonMesh points to vertices.
#
# Example::MeshVertices.test_map_mesh_vertices
module Example
module MeshVertices
def self.test_map_mesh_vertices
model = Sketchup.active_model
group = model.selection[0]
mesh = Example::MeshVertices.get_group_mesh( group )
vertices = Example::MeshVertices.get_group_vertices( group )
map = Example::MeshVertices.map_mesh_vertices( mesh, vertices )
success = mesh.count_points == vertices.length
puts "Mapping PolygonMesh Vertices"
puts "Mesh points: #{mesh.count_points}"
puts " Vertices: #{vertices.length}"
puts ( success ) ? 'MATCH!' : 'FAILURE!'
output = ''
for point, vertex in map
match = point.to_a == vertex.position.to_a
output << "%-35s %35s %-40s %s\n" % [point, vertex, vertex.position, match.to_s]
end
puts output
success
end
def self.get_group_mesh( group )
mesh = Geom::PolygonMesh.new
group.entities.grep( Sketchup::Face ) { |face|
pm = face.mesh
(1..pm.count_polygons).each { |i|
points = pm.polygon_points_at( i )
mesh.add_polygon( *points )
}
}
mesh
end
def self.get_group_vertices( group )
vertices = group.entities.grep( Sketchup::Face ) { |face| face.vertices }
vertices.flatten!
vertices.uniq!
vertices
end
# In order for this method to work it assumes that the 3d position reported
# by the mesh is 100% the same as the position the vertices report.
#
# So far it seem to work fine on existing meshes.
#
# What what if you generate a mesh, then add it to SketchUp - is there a
# chance that SketchUp slightly adjusts the points within it's tolerance range
# in order to merge vertices etc?
def self.map_mesh_vertices( mesh, vertices )
# Because Geom::Point3d objects cannot be compared they are mapped to an
# hash where the key is a 3d position of the vertex as an array.
#
# pt1 = Geom::Point3d.new(20,30,40)
# pt2 = Geom::Point3d.new(20,30,40)
#
# pt1 == pt2
# > true
#
# pt1.hash
# > 139549730
# pt2.hash
# > 139359140
#
# pt1.to_a.hash
# > 246416
# pt2.to_a.hash
# > 246416
#
# pt1.to_s.hash
# > 337406463
# pt2.to_s.hash
# > 337406463
#
# How big are the posibilities for collisions?
vertex_map = {}
for vertex in vertices
point = vertex.position.to_a
vertex_map[ point ] = vertex
end
# Now the PolygonMesh points are mapped to vertices cached.
# (i) One could map point index to vertex instead of that is needed.
map = {}
for point in mesh.points
map[ point ] = vertex_map[ point.to_a ]
end
map
end
end # module
end # module
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment