Compare commits
23 Commits
2.14.2
...
2.15.0-rc4
| Author | SHA1 | Date | |
|---|---|---|---|
| b6e4b711bf | |||
| 58fcfd210b | |||
| 5868b9c234 | |||
| 0dc6d9cf9d | |||
| 67f50cf2fd | |||
| 8b26a4d49a | |||
| a1d0bb0aa1 | |||
| bfe08560b1 | |||
| ac3ac24272 | |||
| 03e7191d0e | |||
| b3a42f8723 | |||
| 9c4b740300 | |||
| 2a12bdadf2 | |||
| c90e8ad4d2 | |||
| 4a52c51c86 | |||
| 0efc817ddc | |||
| fee54fc98c | |||
| 210f751396 | |||
| 2e2bc3fe29 | |||
| a6f05f86d1 | |||
| fc144e4848 | |||
| cef9531428 | |||
| abd4faefbf |
@@ -3,6 +3,7 @@
|
||||
require 'sketchup'
|
||||
require 'pathname'
|
||||
require 'speckle_connector/debug'
|
||||
require_relative 'src/log/log'
|
||||
require_relative 'src/ui/sketchup_ui'
|
||||
require_relative 'src/ui/ui_controller'
|
||||
require_relative 'src/commands/menu_command_handler'
|
||||
|
||||
@@ -12,6 +12,9 @@ module SpeckleConnector
|
||||
|
||||
OBJECTS_GEOMETRY_LINE = 'Objects.Geometry.Line'
|
||||
OBJECTS_GEOMETRY_POLYLINE = 'Objects.Geometry.Polyline'
|
||||
OBJECTS_GEOMETRY_POLYCURVE = 'Objects.Geometry.Polycurve'
|
||||
OBJECTS_GEOMETRY_ARC = 'Objects.Geometry.Arc'
|
||||
OBJECTS_GEOMETRY_CIRCLE = 'Objects.Geometry.Circle'
|
||||
OBJECTS_GEOMETRY_MESH = 'Objects.Geometry.Mesh'
|
||||
OBJECTS_GEOMETRY_BREP = 'Objects.Geometry.Brep'
|
||||
|
||||
|
||||
@@ -17,6 +17,8 @@ module SpeckleConnector
|
||||
faces.each { |face| face.edges.each { |edge| edges << edge } }
|
||||
edges.uniq!
|
||||
edges.each { |edge| remove_edge_have_coplanar_faces(edge, faces, false) }
|
||||
# Remove remaining orphan edges
|
||||
edges.reject(&:deleted?).select { |edge| edge.faces.empty? }.each(&:erase!)
|
||||
merged_faces(faces)
|
||||
end
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
require_relative 'converter'
|
||||
require_relative '../constants/type_constants'
|
||||
require_relative '../speckle_entities/speckle_entity'
|
||||
require_relative '../speckle_objects/gis/polygon_element'
|
||||
require_relative '../speckle_objects/other/transform'
|
||||
require_relative '../speckle_objects/other/render_material'
|
||||
@@ -11,6 +12,9 @@ require_relative '../speckle_objects/other/display_value'
|
||||
require_relative '../speckle_objects/revit/revit_instance'
|
||||
require_relative '../speckle_objects/geometry/point'
|
||||
require_relative '../speckle_objects/geometry/line'
|
||||
require_relative '../speckle_objects/geometry/polycurve'
|
||||
require_relative '../speckle_objects/geometry/arc'
|
||||
require_relative '../speckle_objects/geometry/circle'
|
||||
require_relative '../speckle_objects/geometry/mesh'
|
||||
require_relative '../speckle_objects/built_elements/view3d'
|
||||
require_relative '../speckle_objects/built_elements/network'
|
||||
@@ -45,6 +49,9 @@ module SpeckleConnector
|
||||
# Class aliases
|
||||
POINT = GEOMETRY::Point
|
||||
LINE = GEOMETRY::Line
|
||||
POLYCURVE = GEOMETRY::Polycurve
|
||||
ARC = GEOMETRY::Arc
|
||||
CIRCLE = GEOMETRY::Circle
|
||||
MESH = GEOMETRY::Mesh
|
||||
BLOCK_DEFINITION = OTHER::BlockDefinition
|
||||
BLOCK_INSTANCE = OTHER::BlockInstance
|
||||
@@ -59,6 +66,9 @@ module SpeckleConnector
|
||||
CONVERTABLE_SPECKLE_TYPES = %w[
|
||||
Objects.Geometry.Line
|
||||
Objects.Geometry.Polyline
|
||||
Objects.Geometry.Polycurve
|
||||
Objects.Geometry.Arc
|
||||
Objects.Geometry.Circle
|
||||
Objects.Geometry.Mesh
|
||||
Objects.Geometry.Brep
|
||||
Objects.Other.BlockInstance
|
||||
@@ -76,6 +86,10 @@ module SpeckleConnector
|
||||
@from_revit ||= source_app.include?('revit')
|
||||
end
|
||||
|
||||
def from_rhino
|
||||
@from_rhino ||= source_app.include?('rhino')
|
||||
end
|
||||
|
||||
def from_sketchup
|
||||
@from_sketchup ||= source_app.include?('sketchup')
|
||||
end
|
||||
@@ -89,14 +103,9 @@ module SpeckleConnector
|
||||
# UI is responsible currently to fetch objects from ObjectLoader module by calling getAndConstruct method.
|
||||
# @param obj [Object] speckle commit object.
|
||||
def receive_commit_object(obj)
|
||||
# First create layers on the sketchup before starting traversing
|
||||
# @Named Views are exception here. It does not mean a layer. But it is anti-pattern for now.
|
||||
# layers_relation = obj['layers_relation']
|
||||
|
||||
unless from_revit
|
||||
layers_relation = SpeckleObjects::Relations::Layers.extract_relations(obj)
|
||||
# Create layers and it's folders from layers relation on the model collection.
|
||||
SpeckleObjects::Relations::Layers.to_native(layers_relation, sketchup_model) if layers_relation
|
||||
SpeckleObjects::Relations::Layers.to_native(obj, source_app, sketchup_model)
|
||||
end
|
||||
|
||||
# By default entities to fill is sketchup model's entities.
|
||||
@@ -242,7 +251,7 @@ module SpeckleConnector
|
||||
# rubocop:disable Metrics/PerceivedComplexity
|
||||
def traverse_commit_object(obj, layer, entities)
|
||||
if convertible_to_native?(obj)
|
||||
@state = convert_to_native(@state, obj, layer, entities)
|
||||
@state, _converted_entities = convert_to_native(@state, obj, layer, entities)
|
||||
elsif obj.is_a?(Hash) && obj.key?('speckle_type')
|
||||
return if ignored_speckle_type?(obj)
|
||||
|
||||
@@ -254,7 +263,7 @@ module SpeckleConnector
|
||||
end
|
||||
else
|
||||
# puts(">>> Found #{obj['speckle_type']}: #{obj['id']} with displayValue.")
|
||||
@state = convert_to_native(@state, obj, layer, entities)
|
||||
@state, _converted_entities = convert_to_native(@state, obj, layer, entities)
|
||||
end
|
||||
elsif obj.is_a?(Hash)
|
||||
obj.each_value { |value| traverse_commit_object(value, layer, entities) }
|
||||
@@ -274,6 +283,9 @@ module SpeckleConnector
|
||||
SPECKLE_OBJECT_TO_NATIVE = {
|
||||
OBJECTS_GEOMETRY_LINE => LINE.method(:to_native),
|
||||
OBJECTS_GEOMETRY_POLYLINE => LINE.method(:to_native),
|
||||
OBJECTS_GEOMETRY_POLYCURVE => POLYCURVE.method(:to_native),
|
||||
OBJECTS_GEOMETRY_ARC => ARC.method(:to_native),
|
||||
OBJECTS_GEOMETRY_CIRCLE => CIRCLE.method(:to_native),
|
||||
OBJECTS_GEOMETRY_MESH => MESH.method(:to_native),
|
||||
OBJECTS_GEOMETRY_BREP => MESH.method(:to_native),
|
||||
OBJECTS_OTHER_BLOCKDEFINITION => BLOCK_DEFINITION.method(:to_native),
|
||||
@@ -304,11 +316,11 @@ module SpeckleConnector
|
||||
create_layers_from_categories(state, obj, converted_entities)
|
||||
end
|
||||
# Create speckle entities from sketchup entities to achieve continuous traversal.
|
||||
convert_to_speckle_entities(state, obj, converted_entities)
|
||||
SpeckleEntities::SpeckleEntity.from_speckle_object(state, obj, converted_entities, stream_id)
|
||||
rescue StandardError => e
|
||||
puts("Failed to convert #{obj['speckle_type']} (id: #{obj['id']})")
|
||||
puts(e)
|
||||
return state
|
||||
return state, []
|
||||
end
|
||||
|
||||
# rubocop:disable Metrics/CyclomaticComplexity
|
||||
@@ -353,30 +365,9 @@ module SpeckleConnector
|
||||
end
|
||||
|
||||
# @param state [States::State] state of the application
|
||||
# rubocop:disable Metrics/PerceivedComplexity
|
||||
# rubocop:disable Metrics/CyclomaticComplexity
|
||||
def convert_to_speckle_entities(state, speckle_object, entities)
|
||||
return state if entities.empty?
|
||||
|
||||
speckle_id = speckle_object['id']
|
||||
application_id = speckle_object['applicationId']
|
||||
speckle_type = speckle_object['speckle_type']
|
||||
children = speckle_object['__closure'].nil? ? [] : speckle_object['__closure']
|
||||
speckle_state = state.speckle_state
|
||||
entities.each do |entity|
|
||||
next if entity.is_a?(Sketchup::Material) || entity.is_a?(Sketchup::Page)
|
||||
next if (entity.is_a?(Sketchup::Face) || entity.is_a?(Sketchup::Edge)) &&
|
||||
!state.user_state.user_preferences[:register_speckle_entity]
|
||||
|
||||
ent = SpeckleEntities::SpeckleEntity.new(entity, speckle_id, application_id, speckle_type, children,
|
||||
[stream_id])
|
||||
ent.write_initial_base_data
|
||||
speckle_state = speckle_state.with_speckle_entity(ent)
|
||||
end
|
||||
state.with_speckle_state(speckle_state)
|
||||
def convert_to_speckle_entities(state, speckle_objects_with_entities)
|
||||
return state if speckle_objects_with_entities.empty?
|
||||
end
|
||||
# rubocop:enable Metrics/PerceivedComplexity
|
||||
# rubocop:enable Metrics/CyclomaticComplexity
|
||||
end
|
||||
# rubocop:enable Metrics/ClassLength
|
||||
end
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module SpeckleConnector
|
||||
# Helper module for logging.
|
||||
module Log
|
||||
def self.write_to_file(text, file_name = 'log', path = "#{ENV['HOME']}/Desktop")
|
||||
file_path = path + "/#{file_name}.json"
|
||||
File.delete(file_path) if File.exist?(file_path)
|
||||
File.write(file_path, text)
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -119,6 +119,32 @@ module SpeckleConnector
|
||||
def valid?
|
||||
sketchup_entity.valid?
|
||||
end
|
||||
|
||||
# @param state [States::State] state of the application
|
||||
# rubocop:disable Metrics/PerceivedComplexity
|
||||
# rubocop:disable Metrics/CyclomaticComplexity
|
||||
def self.from_speckle_object(state, speckle_object, entities, stream_id)
|
||||
return state, [] if entities.empty?
|
||||
|
||||
speckle_id = speckle_object['id']
|
||||
application_id = speckle_object['applicationId']
|
||||
speckle_type = speckle_object['speckle_type']
|
||||
children = speckle_object['__closure'].nil? ? [] : speckle_object['__closure']
|
||||
speckle_state = state.speckle_state
|
||||
entities.each do |entity|
|
||||
next if entity.is_a?(Sketchup::Material) || entity.is_a?(Sketchup::Page)
|
||||
next if (entity.is_a?(Sketchup::Face) || entity.is_a?(Sketchup::Edge)) &&
|
||||
!state.user_state.user_preferences[:register_speckle_entity]
|
||||
|
||||
ent = SpeckleEntity.new(entity, speckle_id, application_id, speckle_type, children, [stream_id])
|
||||
ent.write_initial_base_data
|
||||
speckle_state = speckle_state.with_speckle_entity(ent)
|
||||
end
|
||||
new_state = state.with_speckle_state(speckle_state)
|
||||
return new_state, entities
|
||||
end
|
||||
# rubocop:enable Metrics/PerceivedComplexity
|
||||
# rubocop:enable Metrics/CyclomaticComplexity
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -12,7 +12,7 @@ module SpeckleConnector
|
||||
|
||||
def self.to_native(state, network, layer, entities, &convert_to_native)
|
||||
network['elements'].each do |element|
|
||||
state = convert_to_native.call(state, element['elements'], layer, entities)
|
||||
state, _converted_entities = convert_to_native.call(state, element['elements'], layer, entities)
|
||||
end
|
||||
|
||||
return state, []
|
||||
|
||||
@@ -19,7 +19,7 @@ module SpeckleConnector
|
||||
# @param direction [SpeckleObjects::Geometry::Vector] direction of the view from eye to target.
|
||||
# @param up_direction [SpeckleObjects::Geometry::Vector] up direction of the view.
|
||||
# @param is_perspective [Boolean] whether view is perspective or not.
|
||||
# @param lens [Boolean] fov value of the view camera.
|
||||
# @param lens [Numeric] focal length value of the view camera.
|
||||
# @param units [String] units of the camera.
|
||||
# @param application_id [String] application_id of the view.
|
||||
# @param update_properties [Hash{Symbol=>boolean}] properties of the view.
|
||||
@@ -63,42 +63,44 @@ module SpeckleConnector
|
||||
rendering_options = SpeckleObjects::Other::RenderingOptions.to_speckle(page.rendering_options)
|
||||
View3d.new(
|
||||
page.name, origin, target, direction, SpeckleObjects::Geometry::Vector.new(0, 0, 1, units),
|
||||
cam.perspective?, cam.fov, units, page.name, update_properties, rendering_options
|
||||
cam.perspective?, cam.perspective? ? cam.focal_length : 35, units, page.name,
|
||||
update_properties, rendering_options
|
||||
)
|
||||
end
|
||||
|
||||
# @param state [States::State] state of the speckle app.
|
||||
# @param obj [Hash] commit object.
|
||||
# rubocop:disable Metrics/AbcSize
|
||||
# rubocop:disable Metrics/CyclomaticComplexity
|
||||
# rubocop:disable Metrics/PerceivedComplexity
|
||||
def self.to_native(state, view, _layer, _entities, &_convert_to_native)
|
||||
sketchup_model = state.sketchup_state.sketchup_model
|
||||
|
||||
return state, [] unless view['speckle_type'] == 'Objects.BuiltElements.View:Objects.BuiltElements.View3D'
|
||||
|
||||
name = view['name'] || view['id']
|
||||
return state, [] if sketchup_model.pages.any? { |page| page.name == name }
|
||||
|
||||
origin = view['origin']
|
||||
target = view['target']
|
||||
lens = view['lens'] || 50
|
||||
origin = SpeckleObjects::Geometry::Point.to_native(origin['x'], origin['y'], origin['z'], origin['units'])
|
||||
target = SpeckleObjects::Geometry::Point.to_native(target['x'], target['y'], target['z'], target['units'])
|
||||
view_direction = (origin - target).normalize
|
||||
up = view_direction.parallel?([0, 0, 1]) ? [0, 1, 0] : [0, 0, 1]
|
||||
# Set camera position before creating scene on it.
|
||||
my_camera = Sketchup::Camera.new(origin, target, up, !view['isOrthogonal'], lens)
|
||||
sketchup_model.active_view.camera = my_camera
|
||||
camera = create_camera(view)
|
||||
sketchup_model.active_view.camera = camera
|
||||
sketchup_model.pages.add(name)
|
||||
page = sketchup_model.pages[name]
|
||||
set_page_update_properties(page, view['update_properties']) if view['update_properties']
|
||||
set_rendering_options(page.rendering_options, view['rendering_options']) if view['rendering_options']
|
||||
return state, [page]
|
||||
end
|
||||
# rubocop:enable Metrics/AbcSize
|
||||
# rubocop:enable Metrics/CyclomaticComplexity
|
||||
# rubocop:enable Metrics/PerceivedComplexity
|
||||
|
||||
def self.create_camera(view)
|
||||
origin = view['origin']
|
||||
target = view['target']
|
||||
focal_length = view['lens'] || 35
|
||||
origin = SpeckleObjects::Geometry::Point.to_native(origin['x'], origin['y'], origin['z'], origin['units'])
|
||||
target = SpeckleObjects::Geometry::Point.to_native(target['x'], target['y'], target['z'], target['units'])
|
||||
view_direction = (origin - target).normalize
|
||||
up = view_direction.parallel?([0, 0, 1]) ? [0, 1, 0] : [0, 0, 1]
|
||||
# Set camera position before creating scene on it.
|
||||
is_perspective = !view['isOrthogonal']
|
||||
camera = Sketchup::Camera.new(origin, target, up, is_perspective)
|
||||
camera.focal_length = focal_length if is_perspective
|
||||
camera.height = (origin - target).length * 2 unless is_perspective
|
||||
camera
|
||||
end
|
||||
|
||||
# @param page [Sketchup::Page] scene to update -update properties-
|
||||
def self.set_page_update_properties(page, update_properties)
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require_relative '../base'
|
||||
require_relative '../../constants/type_constants'
|
||||
|
||||
module SpeckleConnector
|
||||
module SpeckleObjects
|
||||
module Geometry
|
||||
# Arc object definition for Speckle.
|
||||
class Arc < Base
|
||||
SPECKLE_TYPE = OBJECTS_GEOMETRY_ARC
|
||||
|
||||
# @param [States::State] state of the current application.
|
||||
# @param arc [Object] object represents Speckle Arc.
|
||||
# @param layer [Sketchup::Layer] layer to add {Sketchup::Edge} into it.
|
||||
# @param entities [Sketchup::Entities] entities collection to add {Sketchup::Edge} into it.
|
||||
def self.to_native(state, arc, layer, entities, &_convert_to_native)
|
||||
plane = arc['plane']
|
||||
units = arc['units']
|
||||
origin = Point.to_native(plane['origin']['x'], plane['origin']['y'], plane['origin']['z'], units)
|
||||
normal = Vector.to_native(plane['normal']['x'], plane['normal']['y'], plane['normal']['z'], units)
|
||||
x_axis = Vector.to_native(plane['xdir']['x'], plane['xdir']['y'], plane['xdir']['z'], units)
|
||||
radius = Geometry.length_to_native(arc['radius'], units)
|
||||
edges = entities.add_arc(origin, x_axis, normal, radius, arc['startAngle'], arc['endAngle'])
|
||||
edges.each { |edge| edge.layer = layer }
|
||||
return state, edges
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,33 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require_relative 'point'
|
||||
require_relative 'vector'
|
||||
require_relative 'length'
|
||||
require_relative '../base'
|
||||
require_relative '../../constants/type_constants'
|
||||
|
||||
module SpeckleConnector
|
||||
module SpeckleObjects
|
||||
module Geometry
|
||||
# Circle object definition for Speckle.
|
||||
class Circle < Base
|
||||
SPECKLE_TYPE = OBJECTS_GEOMETRY_CIRCLE
|
||||
|
||||
# @param [States::State] state of the current application.
|
||||
# @param circle [Object] object represents Speckle Circle.
|
||||
# @param layer [Sketchup::Layer] layer to add {Sketchup::Edge} into it.
|
||||
# @param entities [Sketchup::Entities] entities collection to add {Sketchup::Edge} into it.
|
||||
def self.to_native(state, circle, layer, entities, &_convert_to_native)
|
||||
plane = circle['plane']
|
||||
units = circle['units']
|
||||
origin = Point.to_native(plane['origin']['x'], plane['origin']['y'], plane['origin']['z'], units)
|
||||
normal = Vector.to_native(plane['normal']['x'], plane['normal']['y'], plane['normal']['z'], units)
|
||||
radius = Geometry.length_to_native(circle['radius'], units)
|
||||
edges = entities.add_circle(origin, normal, radius)
|
||||
edges.each { |edge| edge.layer = layer }
|
||||
return state, edges
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -60,7 +60,7 @@ module SpeckleConnector
|
||||
)
|
||||
end
|
||||
|
||||
# @param _state [States::State] state of the application.
|
||||
# @param state [States::State] state of the application.
|
||||
# @param line [Object] object represents Speckle line.
|
||||
# @param layer [Sketchup::Layer] layer to add {Sketchup::Edge} into it.
|
||||
# @param entities [Sketchup::Entities] entities collection to add {Sketchup::Edge} into it.
|
||||
|
||||
@@ -119,6 +119,10 @@ module SpeckleConnector
|
||||
added_faces = entities.grep(Sketchup::Face).last(native_mesh.polygons.length)
|
||||
mesh_layer_name = SketchupModel::Query::Layer.entity_layer_from_path(mesh['layer'])
|
||||
mesh_layer = state.sketchup_state.sketchup_model.layers.to_a.find { |l| l.display_name == mesh_layer_name }
|
||||
# Merge only added faces in this scope
|
||||
if model_preferences[:merge_coplanar_faces]
|
||||
added_faces = Converters::CleanUp.merge_coplanar_faces(added_faces)
|
||||
end
|
||||
added_faces.each do |face|
|
||||
face.layer = mesh_layer unless mesh_layer.nil?
|
||||
# Smooth edges if they already soft
|
||||
@@ -129,10 +133,7 @@ module SpeckleConnector
|
||||
.attribute_dictionaries_to_native(face, mesh['sketchup_attributes']['dictionaries'])
|
||||
end
|
||||
end
|
||||
# Merge only added faces in this scope
|
||||
if model_preferences[:merge_coplanar_faces]
|
||||
added_faces = Converters::CleanUp.merge_coplanar_faces(added_faces)
|
||||
end
|
||||
|
||||
return state, added_faces
|
||||
end
|
||||
# rubocop:enable Metrics/MethodLength
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require_relative '../base'
|
||||
require_relative '../../constants/type_constants'
|
||||
|
||||
module SpeckleConnector
|
||||
module SpeckleObjects
|
||||
module Geometry
|
||||
# Polycurve object definition for Speckle.
|
||||
# It basically groups the lines-curves under it's `segments` property.
|
||||
class Polycurve < Base
|
||||
SPECKLE_TYPE = OBJECTS_GEOMETRY_POLYCURVE
|
||||
|
||||
def self.to_native(state, polycurve, layer, entities, &convert_to_native)
|
||||
polycurve['displayValue'] = polycurve['segments']
|
||||
convert_to_native.call(state, polycurve, layer, entities)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -1,5 +1,6 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require_relative 'length'
|
||||
require_relative '../base'
|
||||
|
||||
module SpeckleConnector
|
||||
@@ -25,6 +26,14 @@ module SpeckleConnector
|
||||
self[:z] = z
|
||||
self[:units] = units
|
||||
end
|
||||
|
||||
def self.to_native(x, y, z, units)
|
||||
Geom::Vector3d.new(
|
||||
Geometry.length_to_native(x, units),
|
||||
Geometry.length_to_native(y, units),
|
||||
Geometry.length_to_native(z, units)
|
||||
)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -122,13 +122,23 @@ module SpeckleConnector
|
||||
definition&.entities&.clear!
|
||||
definition ||= sketchup_model.definitions.add(definition_name)
|
||||
|
||||
ngon_faces = []
|
||||
if geometry.is_a?(Array)
|
||||
geometry.each do |obj|
|
||||
state = convert_to_native.call(state, obj, layer, definition.entities)
|
||||
state, added_entities = convert_to_native.call(state, obj, layer, definition.entities)
|
||||
if added_entities.length == 1 && added_entities.first.is_a?(Sketchup::Face)
|
||||
ngon_faces.append(added_entities.first)
|
||||
end
|
||||
end
|
||||
end
|
||||
ngon_faces.each do |f|
|
||||
f.edges.each do |e|
|
||||
e.soft = false
|
||||
e.smooth = false
|
||||
end
|
||||
end
|
||||
if geometry.is_a?(Hash) && !definition_obj['speckle_type'].nil?
|
||||
state = convert_to_native.call(state, geometry, layer, definition.entities)
|
||||
state, _converted_entities = convert_to_native.call(state, geometry, layer, definition.entities)
|
||||
end
|
||||
# puts("definition finished: #{name} (#{application_id})")
|
||||
# puts(" entity count: #{definition.entities.count}")
|
||||
|
||||
@@ -9,7 +9,6 @@ module SpeckleConnector
|
||||
module Other
|
||||
# DisplayStyle object for layer.
|
||||
class DisplayStyle < Base
|
||||
|
||||
def initialize(name:, color:, line_type:)
|
||||
super(
|
||||
speckle_type: OBJECTS_OTHER_DISPLAYSTYLE,
|
||||
|
||||
@@ -22,9 +22,15 @@ module SpeckleConnector
|
||||
|
||||
return format_naming_convention([family, type, category, element_id]) unless element_id.nil?
|
||||
|
||||
return "def::#{def_obj['applicationId']}" unless def_obj['applicationId'].nil?
|
||||
name = def_obj['name']
|
||||
return "#{name}::#{def_obj['applicationId']}" if !name.nil? && !def_obj['applicationId'].nil?
|
||||
|
||||
return "def::#{def_obj['id']}"
|
||||
return "#{name}::#{def_obj['id']}" unless name.nil?
|
||||
|
||||
speckle_type = def_obj['speckle_type'].split('.').last
|
||||
return "#{speckle_type}::#{def_obj['applicationId']}" unless def_obj['applicationId'].nil?
|
||||
|
||||
return "#{speckle_type}::#{def_obj['id']}"
|
||||
end
|
||||
|
||||
def self.format_naming_convention(entries)
|
||||
@@ -41,6 +47,13 @@ module SpeckleConnector
|
||||
name
|
||||
end
|
||||
|
||||
# Get instance name as speckle_type if it is structured as `speckle_type::application_id`
|
||||
def self.get_instance_name(definition_name)
|
||||
return definition_name unless definition_name.include?('::')
|
||||
|
||||
definition_name.split('::').first
|
||||
end
|
||||
|
||||
# Creates a component definition and instance from a speckle object with a display value
|
||||
# @param state [States::State] state of the application.
|
||||
def self.to_native(state, obj, layer, entities, &convert_to_native)
|
||||
@@ -49,11 +62,7 @@ module SpeckleConnector
|
||||
obj['name'] = get_definition_name(obj)
|
||||
|
||||
state, _definitions = BlockDefinition.to_native(
|
||||
state,
|
||||
obj,
|
||||
layer,
|
||||
entities,
|
||||
&convert_to_native
|
||||
state, obj, layer, entities, &convert_to_native
|
||||
)
|
||||
|
||||
definition = state.sketchup_state.sketchup_model.definitions[BlockDefinition.get_definition_name(obj)]
|
||||
@@ -62,7 +71,7 @@ module SpeckleConnector
|
||||
t_arr = obj['transform']
|
||||
transform = t_arr.nil? ? Geom::Transformation.new : Other::Transform.to_native(t_arr, obj['units'])
|
||||
instance = entities.add_instance(definition, transform)
|
||||
instance.name = obj['name'] unless obj['name'].nil?
|
||||
instance.name = get_instance_name(obj['name']) unless obj['name'].nil?
|
||||
instance.layer = layer unless layer.nil?
|
||||
# Align instance axes that created from display value. (without any transform)
|
||||
# BlockInstance.align_instance_axes(instance)
|
||||
|
||||
@@ -11,7 +11,7 @@ module SpeckleConnector
|
||||
SPECKLE_TYPE = 'Speckle.Core.Models.Collection'
|
||||
|
||||
# rubocop:disable Metrics/ParameterLists
|
||||
def initialize(name:, visible:, is_folder:, line_style: nil, color: nil, layers_and_folders: [],
|
||||
def initialize(name:, visible:, is_folder:, full_path: nil, line_style: nil, color: nil, layers_and_folders: [],
|
||||
application_id: nil)
|
||||
super(
|
||||
speckle_type: SPECKLE_TYPE,
|
||||
@@ -23,6 +23,7 @@ module SpeckleConnector
|
||||
self[:color] = color
|
||||
self[:visible] = visible
|
||||
self[:is_folder] = is_folder
|
||||
self[:full_path] = full_path unless full_path.nil?
|
||||
self[:line_style] = line_style unless line_style.nil?
|
||||
self[:collectionType] = 'layer'
|
||||
self[:elements] = layers_and_folders if layers_and_folders.any?
|
||||
@@ -43,14 +44,31 @@ module SpeckleConnector
|
||||
folder.add_layer(layer) if folder.is_a?(Sketchup::LayerFolder)
|
||||
end
|
||||
|
||||
def self.to_native_layer_folder(speckle_layer_folder, folder, sketchup_model)
|
||||
speckle_layers = speckle_layer_folder[:elements].select { |layer_or_fol| layer_or_fol[:elements].nil? }
|
||||
# Flat layer conversion.
|
||||
def self.to_native_flat_layers(layers_relation, sketchup_model)
|
||||
speckle_layers = layers_relation[:elements]
|
||||
|
||||
elements_to_layers(speckle_layers, sketchup_model)
|
||||
end
|
||||
|
||||
# Converts elements to layers with it's full path.
|
||||
def self.elements_to_layers(elements, sketchup_model)
|
||||
elements.each do |element|
|
||||
element[:name] = element[:full_path]
|
||||
to_native_layer(element, sketchup_model.layers, sketchup_model)
|
||||
elements_to_layers(element[:elements], sketchup_model) unless element[:elements].nil?
|
||||
end
|
||||
end
|
||||
|
||||
# Nested layer conversion with folders.
|
||||
def self.to_native_layer_folder(layers_relation, folder, sketchup_model)
|
||||
speckle_layers = layers_relation[:elements].select { |layer_or_fol| layer_or_fol[:elements].nil? }
|
||||
|
||||
speckle_layers.each do |speckle_layer|
|
||||
to_native_layer(speckle_layer, folder, sketchup_model)
|
||||
end
|
||||
|
||||
speckle_folders = speckle_layer_folder[:elements].reject { |layer_or_fol| layer_or_fol[:elements].nil? }
|
||||
speckle_folders = layers_relation[:elements].reject { |layer_or_fol| layer_or_fol[:elements].nil? }
|
||||
|
||||
speckle_folders.each do |speckle_folder|
|
||||
sub_folder = folder.add_folder(speckle_folder[:name])
|
||||
|
||||
@@ -22,26 +22,18 @@ module SpeckleConnector
|
||||
self[:elements] = layers
|
||||
end
|
||||
|
||||
def self.element_to_relation(elements)
|
||||
elements.collect do |element|
|
||||
next unless element['speckle_type'] == SPECKLE_CORE_MODELS_COLLECTION
|
||||
|
||||
is_folder = element['elements'].any? { |e| e['speckle_type'] == SPECKLE_CORE_MODELS_COLLECTION }
|
||||
color = element['color'] || element['displayStyle']['color'] unless element['displayStyle'].nil?
|
||||
Layer.new(
|
||||
name: element['name'],
|
||||
visible: element['visible'],
|
||||
is_folder: is_folder,
|
||||
color: color,
|
||||
layers_and_folders: element_to_relation(element['elements'])
|
||||
)
|
||||
end.compact
|
||||
end
|
||||
|
||||
def self.extract_relations(commit_obj)
|
||||
# Extract relations from commit obj to create layers in advance.
|
||||
# By doing this, also checks layers will be created as flat list or nested structure according to source app.
|
||||
# @param commit_obj [Hash] commit object to extract layer relations.
|
||||
# @param source_app [String] source application to decide layer creation strategy.
|
||||
# Currently for
|
||||
# - Revit: we don't create layers in advance because we create layers according to categories.
|
||||
# - SketchUp: we create layers in advance as nested.
|
||||
# - Rhino: we create layers in advance as flat list with it's full path.
|
||||
def self.extract_relations(commit_obj, source_app)
|
||||
return nil unless commit_obj['speckle_type'] == SPECKLE_CORE_MODELS_COLLECTION
|
||||
|
||||
elements = element_to_relation(commit_obj['elements'])
|
||||
elements = element_to_relation(commit_obj['elements'], source_app, [])
|
||||
|
||||
Layers.new(
|
||||
active: commit_obj['active_layer'],
|
||||
@@ -49,10 +41,41 @@ module SpeckleConnector
|
||||
)
|
||||
end
|
||||
|
||||
def self.to_native(layers_relation, sketchup_model)
|
||||
folder = sketchup_model.layers
|
||||
# rubocop:disable Metrics/CyclomaticComplexity
|
||||
def self.element_to_relation(elements, source_app, parent_layers)
|
||||
elements.collect do |element|
|
||||
next unless element['speckle_type'] == SPECKLE_CORE_MODELS_COLLECTION
|
||||
|
||||
SpeckleObjects::Relations::Layer.to_native_layer_folder(layers_relation, folder, sketchup_model)
|
||||
layers_tree = parent_layers.dup.append(element['name'])
|
||||
full_path = ''
|
||||
parent_layers.each { |parent| full_path += "#{parent}::" }
|
||||
full_path += element['name']
|
||||
# Add this info to commit object to check later layer_collection conversion
|
||||
element['full_path'] = full_path if source_app.include?('rhino')
|
||||
|
||||
is_folder = element['elements'].any? { |e| e['speckle_type'] == SPECKLE_CORE_MODELS_COLLECTION }
|
||||
color = element['color'] || element['displayStyle']['color'] unless element['displayStyle'].nil?
|
||||
Layer.new(
|
||||
name: element['name'], visible: element['visible'], is_folder: is_folder,
|
||||
color: color, full_path: full_path,
|
||||
layers_and_folders: element_to_relation(element['elements'], source_app, layers_tree)
|
||||
)
|
||||
end.compact
|
||||
end
|
||||
# rubocop:enable Metrics/CyclomaticComplexity
|
||||
|
||||
def self.to_native(obj, source_app, sketchup_model)
|
||||
layers_relation = extract_relations(obj, source_app)
|
||||
return if layers_relation.nil?
|
||||
|
||||
folder = sketchup_model.layers
|
||||
is_flat = source_app.include?('rhino')
|
||||
|
||||
if is_flat
|
||||
SpeckleObjects::Relations::Layer.to_native_flat_layers(layers_relation, sketchup_model)
|
||||
else
|
||||
SpeckleObjects::Relations::Layer.to_native_layer_folder(layers_relation, folder, sketchup_model)
|
||||
end
|
||||
|
||||
active_layer = folder.to_a.find { |layer| layer.display_name == layers_relation['active_layer'] }
|
||||
sketchup_model.active_layer = active_layer unless active_layer.nil?
|
||||
|
||||
@@ -99,12 +99,13 @@ module SpeckleConnector
|
||||
sketchup_model = state.sketchup_state.sketchup_model
|
||||
elements = layer_collection['elements']
|
||||
name = layer_collection['name']
|
||||
name = layer_collection['full_path'] if layer_collection['full_path']
|
||||
|
||||
layer = sketchup_model.layers.find { |l| l.display_name == name }
|
||||
layer_or_folder = layer if layer
|
||||
|
||||
elements.each do |element|
|
||||
new_state = convert_to_native.call(state, element, layer_or_folder, entities)
|
||||
new_state, _converted_entities = convert_to_native.call(state, element, layer_or_folder, entities)
|
||||
state = new_state
|
||||
end
|
||||
|
||||
|
||||
@@ -66,7 +66,7 @@ module SpeckleConnector
|
||||
elements = model_collection['elements']
|
||||
|
||||
elements.each do |element|
|
||||
new_state = convert_to_native.call(state, element, layer, entities)
|
||||
new_state, _converted_entities = convert_to_native.call(state, element, layer, entities)
|
||||
state = new_state
|
||||
end
|
||||
|
||||
|
||||
Reference in New Issue
Block a user