Implement speckle Mesh and RenderMaterial objects

This commit is contained in:
oguzhankoral
2022-11-22 10:55:16 +03:00
parent 50886147ae
commit 2e8a040210
3 changed files with 144 additions and 14 deletions
+2 -14
View File
@@ -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