Feat (SpeckleEntity): Read speckle entities when model loaded
This commit is contained in:
@@ -2,6 +2,7 @@
|
||||
|
||||
require_relative 'action'
|
||||
require_relative 'initialize_materials'
|
||||
require_relative '../sketchup_model/reader/speckle_entities_reader'
|
||||
require_relative '../preferences/preferences'
|
||||
require_relative '../states/state'
|
||||
require_relative '../states/sketchup_state'
|
||||
@@ -23,7 +24,10 @@ module SpeckleConnector
|
||||
# Init materials again
|
||||
new_state = InitializeMaterials.update_state(new_state)
|
||||
|
||||
# TODO: Read here SpeckleEntities if they exist in model.
|
||||
# Read speckle entities
|
||||
new_speckle_entities = SketchupModel::Reader::SpeckleEntitiesReader.read(sketchup_model.entities)
|
||||
new_speckle_state = new_state.speckle_state.with_speckle_entities(Immutable::Hash.new(new_speckle_entities))
|
||||
new_state = new_state.with_speckle_state(new_speckle_state)
|
||||
|
||||
# Read preferences from database and model.
|
||||
preferences = Preferences.read_preferences(new_state.sketchup_state.sketchup_model)
|
||||
|
||||
@@ -6,6 +6,7 @@ module SpeckleConnector
|
||||
SPECKLE_TYPE = 'speckle_type'
|
||||
APPLICATION_ID = 'application_id'
|
||||
TOTAL_CHILDREN_COUNT = 'total_children_count'
|
||||
CHILDREN = 'children'
|
||||
PARENT = 'parent'
|
||||
VALID_STREAM_IDS = 'valid_stream_ids'
|
||||
INVALID_STREAM_IDS = 'invalid_stream_ids'
|
||||
|
||||
@@ -5,6 +5,7 @@ require 'securerandom'
|
||||
# rubocop:enable SketchupPerformance/OpenSSL
|
||||
require 'digest'
|
||||
require_relative 'converter'
|
||||
require_relative '../speckle_entities/speckle_entity'
|
||||
require_relative '../relations/many_to_one_relation'
|
||||
|
||||
module SpeckleConnector
|
||||
@@ -117,11 +118,7 @@ module SpeckleConnector
|
||||
|
||||
if @preferences[:user][:diffing] && !entities.nil?
|
||||
entities.uniq.each do |entity|
|
||||
speckle_entity = if speckle_state.speckle_entities.keys.include?(entity.persistent_id)
|
||||
speckle_state.speckle_entities[entity.persistent_id].with_valid_stream_id(stream_id)
|
||||
else
|
||||
SpeckleEntities.with_converted(entity, traversed_base, stream_id)
|
||||
end
|
||||
speckle_entity = create_or_update_speckle_entity(entity, id, traversed_base)
|
||||
@speckle_state = speckle_state.with_speckle_entity(speckle_entity)
|
||||
end
|
||||
end
|
||||
@@ -345,6 +342,22 @@ module SpeckleConnector
|
||||
|
||||
speckle_state.speckle_entities[entity.persistent_id].valid_stream_ids.include?(stream_id)
|
||||
end
|
||||
|
||||
# Creates or updates speckle entity.
|
||||
# If speckle entity exist in state, creates new one by updating old one.
|
||||
# Else creates new one
|
||||
# @return [SpeckleEntity] speckle entity that collects both speckle and sketchup information.
|
||||
def create_or_update_speckle_entity(entity, id, traversed_base)
|
||||
if speckle_state.speckle_entities.keys.include?(entity.persistent_id)
|
||||
speckle_state.speckle_entities[entity.persistent_id].with_valid_stream_id(stream_id)
|
||||
else
|
||||
children = traversed_base[:__closure].nil? ? {} : traversed_base[:__closure]
|
||||
speckle_entity = SpeckleEntities::SpeckleEntity.new(entity, id, traversed_base[:speckle_type],
|
||||
children.keys, [stream_id])
|
||||
speckle_entity.write_initial_base_data
|
||||
speckle_entity
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
require_relative 'converter'
|
||||
require_relative 'base_object_serializer'
|
||||
require_relative '../relations/many_to_one_relation'
|
||||
require_relative '../speckle_entities/speckle_entities'
|
||||
require_relative '../speckle_objects/base'
|
||||
require_relative '../speckle_objects/geometry/line'
|
||||
require_relative '../speckle_objects/geometry/length'
|
||||
|
||||
+3
-2
@@ -12,13 +12,14 @@ module SpeckleConnector
|
||||
# Writes initial data while speckle entity is creating first time.
|
||||
# @param sketchup_entity [Sketchup::Entity] Sketchup entity to write data into it's attribute dictionary.
|
||||
# rubocop:disable Metrics/ParameterLists
|
||||
def self.write_initial_base_data(sketchup_entity, application_id, id, speckle_type, children_count, stream_id)
|
||||
def self.write_initial_base_data(sketchup_entity, application_id, id, speckle_type, children, stream_id)
|
||||
initial_dict_data = {
|
||||
# Add here more if you want to write here initial data
|
||||
SPECKLE_ID => id,
|
||||
APPLICATION_ID => application_id,
|
||||
SPECKLE_TYPE => speckle_type,
|
||||
TOTAL_CHILDREN_COUNT => children_count,
|
||||
TOTAL_CHILDREN_COUNT => children.length,
|
||||
CHILDREN => children.keys,
|
||||
VALID_STREAM_IDS => [stream_id],
|
||||
INVALID_STREAM_IDS => []
|
||||
}
|
||||
|
||||
@@ -0,0 +1,51 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require_relative '../../speckle_entities/speckle_entity'
|
||||
require_relative '../../constants/dict_constants'
|
||||
|
||||
module SpeckleConnector
|
||||
# Operations related to {SketchupModel}.
|
||||
module SketchupModel
|
||||
# Reader model for sketchup model.
|
||||
module Reader
|
||||
# Reader module for speckle entities.
|
||||
module SpeckleEntitiesReader
|
||||
# @param entities [Sketchup::Entities] entities to collect speckle entities.
|
||||
def self.read(entities)
|
||||
speckle_entities = {}
|
||||
entities.each do |entity|
|
||||
speckle_entities[entity.persistent_id] = read_speckle_entity(entity) if speckle_entity?(entity)
|
||||
next unless entity.is_a?(Sketchup::Group) || entity.is_a?(Sketchup::ComponentInstance)
|
||||
|
||||
if speckle_entity?(entity.definition)
|
||||
speckle_entities[entity.definition.persistent_id] = read_speckle_entity(entity.definition)
|
||||
end
|
||||
definition_speckle_entities = read(entity.definition.entities)
|
||||
speckle_entities = speckle_entities.merge(definition_speckle_entities)
|
||||
end
|
||||
speckle_entities
|
||||
end
|
||||
|
||||
# @param entity [Sketchup::Entity] sketchup entity to read from attribute dictionary.
|
||||
def self.read_speckle_entity(entity)
|
||||
dict = entity.attribute_dictionaries.to_a.find { |dict| dict.name == SPECKLE_BASE_OBJECT }
|
||||
speckle_id = dict[:speckle_id]
|
||||
speckle_type = dict[:speckle_type]
|
||||
children = dict[:children]
|
||||
valid_stream_ids = dict[:valid_stream_ids]
|
||||
invalid_stream_ids = dict[:invalid_stream_ids]
|
||||
SpeckleEntities::SpeckleEntity.new(entity, speckle_id, speckle_type, children,
|
||||
valid_stream_ids, invalid_stream_ids)
|
||||
end
|
||||
|
||||
# @param entity [Sketchup::Entity] sketchup entity to check if it was speckle entity once.
|
||||
def self.speckle_entity?(entity)
|
||||
return false if entity.attribute_dictionaries.nil?
|
||||
return false if entity.attribute_dictionaries.to_a.empty?
|
||||
|
||||
entity.attribute_dictionaries.to_a.any? { |dict| dict.name == SPECKLE_BASE_OBJECT }
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -1,23 +0,0 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require_relative 'speckle_entity'
|
||||
require_relative '../immutable/immutable'
|
||||
|
||||
module SpeckleConnector
|
||||
module SpeckleEntities
|
||||
# Speckle block definition entity is the state object for Sketchup::Entity and it's converted (or not yet) state.
|
||||
class SpeckleBlockDefinitionEntity < SpeckleEntities::SpeckleEntity
|
||||
include Immutable::ImmutableUtils
|
||||
|
||||
# @return [Hash{String=>SpeckleObjects::Base}] speckle objects belongs to block instance
|
||||
attr_reader :children
|
||||
|
||||
def initialize(sketchup_group_or_component_instance, traversed_speckle_object, stream_id)
|
||||
@children = traversed_speckle_object[:__closure].nil? ? {} : traversed_speckle_object[:__closure]
|
||||
super(sketchup_group_or_component_instance, traversed_speckle_object, children, stream_id)
|
||||
end
|
||||
|
||||
alias sketchup_edge sketchup_entity
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -1,27 +0,0 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require_relative 'speckle_entity'
|
||||
require_relative '../immutable/immutable'
|
||||
|
||||
module SpeckleConnector
|
||||
module SpeckleEntities
|
||||
# Speckle block instance entity is the state object for Sketchup::Entity and it's converted (or not yet) state.
|
||||
class SpeckleBlockInstanceEntity < SpeckleEntities::SpeckleEntity
|
||||
include Immutable::ImmutableUtils
|
||||
|
||||
# @return [Hash{String=>SpeckleObjects::Base}] speckle objects belongs to block instance
|
||||
attr_reader :children
|
||||
|
||||
# @return [Boolean] whether block instance represented as sketchup group or component instance
|
||||
attr_reader :is_sketchup_group
|
||||
|
||||
def initialize(sketchup_group_or_component_instance, traversed_speckle_object, stream_id)
|
||||
@children = traversed_speckle_object[:__closure].nil? ? {} : traversed_speckle_object[:__closure]
|
||||
@is_sketchup_group = traversed_speckle_object[:is_sketchup_group]
|
||||
super(sketchup_group_or_component_instance, traversed_speckle_object, children, stream_id)
|
||||
end
|
||||
|
||||
alias sketchup_edge sketchup_entity
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -1,36 +0,0 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require_relative 'speckle_entity'
|
||||
require_relative 'speckle_line_entity'
|
||||
require_relative 'speckle_mesh_entity'
|
||||
require_relative 'speckle_block_instance_entity'
|
||||
require_relative 'speckle_block_definition_entity'
|
||||
|
||||
module SpeckleConnector
|
||||
# Speckle entities are the state holder objects to achieve diffing, caching and updating.
|
||||
# They are created whenever user send/receive objects between SketchUp and Speckle XYZ server.
|
||||
# When Sketchup Entity is sent, by checking objects attributes, allow us to understand this object is sent previously?
|
||||
# If yes, then use it for caching purpose only if object hasn't changed since it's previous sent state.
|
||||
# If object has sent before but changed after, then update the SpeckleEntity with new traversed object.
|
||||
# If no, then create SpeckleEntity and add it to the SpeckleState to check later.
|
||||
module SpeckleEntities
|
||||
# Speckle entity is the state object for Sketchup::Entity and it's converted (or not yet) state.
|
||||
def self.with_converted(skp_entity, traversed, stream_id)
|
||||
# return the same object if it is already SpeckleEntity
|
||||
return skp_entity if skp_entity.is_a?(SpeckleEntity)
|
||||
return SpeckleBlockInstanceEntity.new(skp_entity, traversed, stream_id) if skp_entity.is_a?(Sketchup::Group)
|
||||
|
||||
if skp_entity.is_a?(Sketchup::ComponentInstance)
|
||||
return SpeckleBlockInstanceEntity.new(skp_entity, traversed,
|
||||
stream_id)
|
||||
end
|
||||
if skp_entity.is_a?(Sketchup::ComponentDefinition)
|
||||
return SpeckleBlockDefinitionEntity.new(skp_entity, traversed,
|
||||
stream_id)
|
||||
end
|
||||
return SpeckleMeshEntity.new(skp_entity, traversed, stream_id) if skp_entity.is_a?(Sketchup::Face)
|
||||
|
||||
SpeckleLineEntity.new(skp_entity, traversed, stream_id) if skp_entity.is_a?(Sketchup::Edge)
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -13,9 +13,6 @@ module SpeckleConnector
|
||||
# @return [Sketchup::Entity] Sketchup Entity represents {SpeckleEntity} on the model.
|
||||
attr_reader :sketchup_entity
|
||||
|
||||
# @return [SpeckleObjects::Base] Speckle object that represented on server.
|
||||
attr_reader :speckle_object
|
||||
|
||||
# @return [String] Speckle object type.
|
||||
attr_reader :speckle_type
|
||||
|
||||
@@ -43,27 +40,26 @@ module SpeckleConnector
|
||||
attr_reader :source_material, :active_diffing_stream_id
|
||||
|
||||
# @param sketchup_entity [Sketchup::Entity] sketchup entity represents {SpeckleEntity} on the model.
|
||||
def initialize(sketchup_entity, traversed_speckle_object, children, stream_id)
|
||||
# rubocop:disable Metrics/ParameterLists
|
||||
def initialize(sketchup_entity, speckle_id, speckle_type, children, valid_stream_ids, invalid_stream_ids = [])
|
||||
@status = SpeckleEntityStatus::UP_TO_DATE
|
||||
@source_material = sketchup_entity.material
|
||||
@active_diffing_stream_id = nil
|
||||
@valid_stream_ids = [stream_id]
|
||||
@invalid_stream_ids = []
|
||||
@valid_stream_ids = valid_stream_ids
|
||||
@invalid_stream_ids = invalid_stream_ids
|
||||
@sketchup_entity = sketchup_entity
|
||||
@application_id = @sketchup_entity.persistent_id
|
||||
@id = traversed_speckle_object[:id]
|
||||
@total_children_count = traversed_speckle_object[:totalChildrenCount]
|
||||
@speckle_object = traversed_speckle_object
|
||||
@speckle_type = speckle_object[:speckle_type]
|
||||
@id = speckle_id
|
||||
@total_children_count = children.length
|
||||
@speckle_type = speckle_type
|
||||
@speckle_children_objects = children
|
||||
end
|
||||
# rubocop:enable Metrics/ParameterLists
|
||||
|
||||
def write_initial_base_data
|
||||
SketchupModel::Dictionary::SpeckleEntityDictionaryHandler
|
||||
.write_initial_base_data(@sketchup_entity, application_id, id, speckle_type,
|
||||
@speckle_children_objects.length, stream_id)
|
||||
|
||||
# FIXME: Understand why below condition does not match for same cases. I guess it is a typo bug.
|
||||
# unless total_children_count == speckle_children_objects.length
|
||||
# raise StandardError "total children count mismatch for #{application_id}"
|
||||
# end
|
||||
@speckle_children_objects, valid_stream_ids.first)
|
||||
end
|
||||
|
||||
def with_up_to_date
|
||||
|
||||
@@ -1,23 +0,0 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require_relative 'speckle_entity'
|
||||
require_relative '../immutable/immutable'
|
||||
|
||||
module SpeckleConnector
|
||||
module SpeckleEntities
|
||||
# Speckle line entity is the state object for Sketchup::Entity and it's converted (or not yet) state.
|
||||
class SpeckleLineEntity < SpeckleEntities::SpeckleEntity
|
||||
include Immutable::ImmutableUtils
|
||||
|
||||
# @return [Hash{String=>SpeckleObjects::Base}] speckle objects belongs to edge
|
||||
attr_reader :children
|
||||
|
||||
def initialize(sketchup_edge, traversed_speckle_object, stream_id)
|
||||
@children = traversed_speckle_object[:__closure].nil? ? {} : traversed_speckle_object[:__closure]
|
||||
super(sketchup_edge, traversed_speckle_object, children, stream_id)
|
||||
end
|
||||
|
||||
alias sketchup_edge sketchup_entity
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -1,23 +0,0 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require_relative 'speckle_entity'
|
||||
require_relative '../immutable/immutable'
|
||||
|
||||
module SpeckleConnector
|
||||
module SpeckleEntities
|
||||
# Speckle mesh entity is the state object for Sketchup::Entity and it's converted (or not yet) state.
|
||||
class SpeckleMeshEntity < SpeckleEntities::SpeckleEntity
|
||||
include Immutable::ImmutableUtils
|
||||
|
||||
# @return [Hash{String=>SpeckleObjects::Base}] speckle objects belongs to edge
|
||||
attr_reader :children
|
||||
|
||||
def initialize(sketchup_face, traversed_speckle_object, stream_id)
|
||||
@children = traversed_speckle_object[:__closure].nil? ? {} : traversed_speckle_object[:__closure]
|
||||
super(sketchup_face, traversed_speckle_object, children, stream_id)
|
||||
end
|
||||
|
||||
alias sketchup_edge sketchup_entity
|
||||
end
|
||||
end
|
||||
end
|
||||
Reference in New Issue
Block a user