Implement speckle Mesh and RenderMaterial objects
This commit is contained in:
@@ -2,6 +2,7 @@
|
||||
|
||||
require_relative 'converter'
|
||||
require_relative '../speckle_objects/geometry/line'
|
||||
require_relative '../speckle_objects/geometry/mesh'
|
||||
|
||||
module SpeckleConnector
|
||||
module Converters
|
||||
@@ -13,7 +14,7 @@ module SpeckleConnector
|
||||
|
||||
def convert(obj)
|
||||
return SpeckleObjects::Geometry::Line.from_edge(obj, @units).to_h if obj.is_a?(Sketchup::Edge)
|
||||
return face_to_speckle(obj) if obj.is_a?(Sketchup::Face)
|
||||
return SpeckleObjects::Geometry::Mesh.from_face(obj, @units) if obj.is_a?(Sketchup::Face)
|
||||
return group_to_speckle(obj) if obj.is_a?(Sketchup::Group)
|
||||
return component_definition_to_speckle(obj) if obj.is_a?(Sketchup::ComponentDefinition)
|
||||
|
||||
@@ -223,19 +224,6 @@ module SpeckleConnector
|
||||
uvs_array
|
||||
end
|
||||
|
||||
def face_to_speckle(face)
|
||||
mesh = face.loops.count > 1 ? face.mesh : nil
|
||||
{
|
||||
speckle_type: 'Objects.Geometry.Mesh',
|
||||
units: @units,
|
||||
renderMaterial: face.material.nil? ? nil : material_to_speckle(face.material),
|
||||
bbox: bounds_to_speckle(face.bounds),
|
||||
'@(31250)vertices' => mesh.nil? ? face_vertices_to_array(face) : mesh_points_to_array(mesh),
|
||||
'@(62500)faces' => mesh.nil? ? face_indices_to_array(face, 0) : mesh_faces_to_array(mesh, -1),
|
||||
'@(31250)faceEdgeFlags' => mesh.nil? ? face_edge_flags_to_array(face) : mesh_edge_flags_to_array(mesh)
|
||||
}
|
||||
end
|
||||
|
||||
def vertex_to_speckle(vertex)
|
||||
point = vertex.position
|
||||
{
|
||||
|
||||
@@ -0,0 +1,100 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require_relative '../geometry/bounding_box'
|
||||
require_relative '../other/render_material'
|
||||
require_relative '../../typescript/typescript_object'
|
||||
|
||||
module SpeckleConnector
|
||||
module SpeckleObjects
|
||||
module Geometry
|
||||
# Mesh object definition for Speckle.
|
||||
class Mesh < Typescript::TypescriptObject
|
||||
SPECKLE_TYPE = 'Objects.Geometry.Mesh'
|
||||
ATTRIBUTES = {
|
||||
speckle_type: String,
|
||||
units: String,
|
||||
renderMaterial: [NilClass, Other::RenderMaterial],
|
||||
bbox: Geometry::BoundingBox,
|
||||
'@(31250)vertices': Array,
|
||||
'@(62500)faces': Array,
|
||||
'@(31250)faceEdgeFlags': Array
|
||||
}.freeze
|
||||
|
||||
# @param face [Sketchup::Face] face to convert mesh
|
||||
def self.from_face(face, units)
|
||||
mesh = face.loops.count > 1 ? face.mesh : nil
|
||||
Mesh.new(
|
||||
speckle_type: SPECKLE_TYPE,
|
||||
units: units,
|
||||
renderMaterial: face.material.nil? ? nil : Other::RenderMaterial.from_material(face.material),
|
||||
bbox: Geometry::BoundingBox.from_bounds(face.bounds, units),
|
||||
'@(31250)vertices': mesh.nil? ? face_vertices_to_array(face, units) : mesh_points_to_array(mesh, units),
|
||||
'@(62500)faces': mesh.nil? ? face_indices_to_array(face, 0) : mesh_faces_to_array(mesh, -1),
|
||||
'@(31250)faceEdgeFlags': mesh.nil? ? face_edge_flags_to_array(face) : mesh_edge_flags_to_array(mesh)
|
||||
)
|
||||
end
|
||||
|
||||
# get a flat array of vertices from a list of sketchup vertices
|
||||
def self.face_vertices_to_array(face, units)
|
||||
pts_array = []
|
||||
face.vertices.each do |v|
|
||||
pt = v.position
|
||||
pts_array.push(Geometry.length_to_speckle(pt[0], units),
|
||||
Geometry.length_to_speckle(pt[1], units),
|
||||
Geometry.length_to_speckle(pt[2], units))
|
||||
end
|
||||
pts_array
|
||||
end
|
||||
|
||||
# get a flat array of vertices from a sketchup polygon mesh
|
||||
def self.mesh_points_to_array(mesh, units)
|
||||
pts_array = []
|
||||
mesh.points.each do |pt|
|
||||
pts_array.push(
|
||||
Geometry.length_to_speckle(pt[0], units),
|
||||
Geometry.length_to_speckle(pt[1], units),
|
||||
Geometry.length_to_speckle(pt[2], units)
|
||||
)
|
||||
end
|
||||
pts_array
|
||||
end
|
||||
|
||||
# get a flat array of face indices from a sketchup face
|
||||
def self.face_indices_to_array(face, offset)
|
||||
face_array = [face.vertices.count]
|
||||
face_array.push(*face.vertices.count.times.map { |index| index + offset })
|
||||
face_array
|
||||
end
|
||||
|
||||
# get an array of face indices from a sketchup polygon mesh
|
||||
def self.mesh_faces_to_array(mesh, offset = 0)
|
||||
faces = []
|
||||
mesh.polygons.each do |poly|
|
||||
faces.push(
|
||||
poly.count, *poly.map { |index| index.abs + offset }
|
||||
)
|
||||
end
|
||||
faces
|
||||
end
|
||||
|
||||
def self.face_edge_flags_to_array(face)
|
||||
face.outer_loop.edges.map(&:soft?)
|
||||
end
|
||||
|
||||
def self.mesh_edge_flags_to_array(mesh)
|
||||
edge_flags = []
|
||||
mesh.polygons.each do |poly|
|
||||
edge_flags.push(
|
||||
*poly.map(&:negative?)
|
||||
)
|
||||
end
|
||||
edge_flags
|
||||
end
|
||||
|
||||
def attribute_types
|
||||
ATTRIBUTES
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,42 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require_relative '../../typescript/typescript_object'
|
||||
|
||||
module SpeckleConnector
|
||||
module SpeckleObjects
|
||||
module Other
|
||||
# RenderMaterial object definition for Speckle.
|
||||
class RenderMaterial < Typescript::TypescriptObject
|
||||
SPECKLE_TYPE = 'Objects.Other.RenderMaterial'
|
||||
ATTRIBUTE_TYPES = {
|
||||
speckle_type: String,
|
||||
name: String,
|
||||
diffuse: Numeric,
|
||||
opacity: Numeric,
|
||||
emissive: Numeric,
|
||||
metalness: Numeric,
|
||||
roughness: Numeric
|
||||
}.freeze
|
||||
|
||||
def self.from_material(material)
|
||||
rgba = material.color.to_a
|
||||
RenderMaterial.new(
|
||||
speckle_type: SPECKLE_TYPE,
|
||||
name: material.name,
|
||||
diffuse: [rgba[3] << 24 | rgba[0] << 16 | rgba[1] << 8 | rgba[2]].pack('l').unpack1('l'),
|
||||
opacity: material.alpha,
|
||||
emissive: -16_777_216,
|
||||
metalness: 0,
|
||||
roughness: 1
|
||||
)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def attribute_types
|
||||
ATTRIBUTE_TYPES
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
Reference in New Issue
Block a user