diff --git a/speckle_connector/src/convertors/to_native.rb b/speckle_connector/src/convertors/to_native.rb index f2eba3d..ee7cb24 100644 --- a/speckle_connector/src/convertors/to_native.rb +++ b/speckle_connector/src/convertors/to_native.rb @@ -6,6 +6,7 @@ require_relative '../speckle_objects/other/render_material' require_relative '../speckle_objects/other/block_definition' require_relative '../speckle_objects/other/block_instance' require_relative '../speckle_objects/other/display_value' +require_relative '../speckle_objects/other/revit/revit_instance' require_relative '../speckle_objects/geometry/point' require_relative '../speckle_objects/geometry/line' require_relative '../speckle_objects/geometry/mesh' @@ -38,6 +39,7 @@ module SpeckleConnector MESH = GEOMETRY::Mesh BLOCK_DEFINITION = OTHER::BlockDefinition BLOCK_INSTANCE = OTHER::BlockInstance + REVIT_INSTANCE = OTHER::Revit::RevitInstance RENDER_MATERIAL = OTHER::RenderMaterial DISPLAY_VALUE = OTHER::DisplayValue @@ -340,7 +342,7 @@ module SpeckleConnector OBJECTS_GEOMETRY_BREP => MESH.method(:to_native), OBJECTS_OTHER_BLOCKDEFINITION => BLOCK_DEFINITION.method(:to_native), OBJECTS_OTHER_BLOCKINSTANCE => BLOCK_INSTANCE.method(:to_native), - OBJECTS_OTHER_REVIT_REVITINSTANCE => BLOCK_INSTANCE.method(:to_native), + OBJECTS_OTHER_REVIT_REVITINSTANCE => REVIT_INSTANCE.method(:to_native), OBJECTS_OTHER_RENDERMATERIAL => RENDER_MATERIAL.method(:to_native) }.freeze diff --git a/speckle_connector/src/speckle_objects/other/block_definition.rb b/speckle_connector/src/speckle_objects/other/block_definition.rb index 3fe2d09..52026ae 100644 --- a/speckle_connector/src/speckle_objects/other/block_definition.rb +++ b/speckle_connector/src/speckle_objects/other/block_definition.rb @@ -100,40 +100,8 @@ module SpeckleConnector # rubocop:enable Metrics/AbcSize # rubocop:enable Metrics/ParameterLists - def self.built_element?(definition_object) - definition_object['speckle_type'].include?('Objects.BuiltElements') - end - - def self.unique_element?(definition_object) - UNIQUE_DEFINITIONS.any? { |d| definition_object['speckle_type'].include?(d) } - end - - UNIQUE_DEFINITIONS = %w[ - Objects.BuiltElements.Wall - Objects.BuiltElements.Floor - Objects.BuiltElements.Ceiling - Objects.BuiltElements.Column - Objects.BuiltElements.Beam - Objects.BuiltElements.Roof - Objects.BuiltElements.Room - Objects.BuiltElements.Topography - ].freeze - def self.get_definition_name(def_obj) - return def_obj['name'] if !def_obj['name'].nil? && !def_obj['is_sketchup_group'].nil? - - family = def_obj['family'] - type = def_obj['type'] - category = def_obj['category'] - - # Check unique elements when instancing implemented to add it with element id. - if built_element?(def_obj) && unique_element?(def_obj) - element_id = def_obj['elementId'] - - return "#{family}-#{type}-#{category}-#{element_id}" - end - - return "#{family}-#{type}-#{category}" if built_element?(def_obj) + return def_obj['name'] unless def_obj['name'].nil? return "def::#{def_obj['applicationId']}" end diff --git a/speckle_connector/src/speckle_objects/other/block_instance.rb b/speckle_connector/src/speckle_objects/other/block_instance.rb index 326f52c..880cc20 100644 --- a/speckle_connector/src/speckle_objects/other/block_instance.rb +++ b/speckle_connector/src/speckle_objects/other/block_instance.rb @@ -108,10 +108,6 @@ module SpeckleConnector # @param block [Object] block object that represents Speckle block. # @param layer [Sketchup::Layer] layer to add {Sketchup::Edge} into it. # @param entities [Sketchup::Entities] entities collection to add {Sketchup::Edge} into it. - # rubocop:disable Metrics/AbcSize - # rubocop:disable Metrics/MethodLength - # rubocop:disable Metrics/CyclomaticComplexity - # rubocop:disable Metrics/PerceivedComplexity def self.to_native(state, block, layer, entities, &convert_to_native) # is_group = block.key?("is_sketchup_group") && block["is_sketchup_group"] # something about this conversion is freaking out if nested block geo is a group @@ -132,6 +128,42 @@ module SpeckleConnector definition = state.sketchup_state.sketchup_model .definitions[BlockDefinition.get_definition_name(block_definition)] + return add_instance_from_definition(state, block, layer, entities, definition, is_group, &convert_to_native) + end + + def self.get_transform_matrix(block) + if block['transform'].is_a?(Hash) + block['transform']['matrix'] || block['transform']['value'] + else + block['transform'] + end + end + + # takes a component definition and finds and erases the first instance with the matching name + # (and optionally the applicationId) + # rubocop:disable Metrics/PerceivedComplexity + # rubocop:disable Metrics/CyclomaticComplexity + def self.find_and_erase_existing_instance(definition, upcoming_speckle_id, upcoming_app_id = '') + definition.instances.find do |ins| + next if ins.attribute_dictionaries.nil? + next if ins.attribute_dictionaries.to_a.empty? + next if ins.attribute_dictionaries.to_a.none? { |dict| dict.name == SPECKLE_BASE_OBJECT } + + dict = ins.attribute_dictionaries.to_a.find { |d| d.name == SPECKLE_BASE_OBJECT } + speckle_id = dict[:speckle_id] + application_id = dict[:application_id] + speckle_id == upcoming_speckle_id || application_id == upcoming_app_id + end&.erase! + end + # rubocop:enable Metrics/PerceivedComplexity + # rubocop:enable Metrics/CyclomaticComplexity + + # rubocop:disable Metrics/AbcSize + # rubocop:disable Metrics/MethodLength + # rubocop:disable Metrics/CyclomaticComplexity + # rubocop:disable Metrics/PerceivedComplexity + # rubocop:disable Metrics/ParameterLists + def self.add_instance_from_definition(state, block, layer, entities, definition, is_group, &convert_to_native) t_arr = get_transform_matrix(block) transform = Other::Transform.to_native(t_arr, block['units']) instance = if is_group @@ -173,33 +205,7 @@ module SpeckleConnector # rubocop:enable Metrics/MethodLength # rubocop:enable Metrics/CyclomaticComplexity # rubocop:enable Metrics/PerceivedComplexity - - def self.get_transform_matrix(block) - if block['transform'].is_a?(Hash) - block['transform']['matrix'] || block['transform']['value'] - else - block['transform'] - end - end - - # takes a component definition and finds and erases the first instance with the matching name - # (and optionally the applicationId) - # rubocop:disable Metrics/PerceivedComplexity - # rubocop:disable Metrics/CyclomaticComplexity - def self.find_and_erase_existing_instance(definition, upcoming_speckle_id, upcoming_app_id = '') - definition.instances.find do |ins| - next if ins.attribute_dictionaries.nil? - next if ins.attribute_dictionaries.to_a.empty? - next if ins.attribute_dictionaries.to_a.none? { |dict| dict.name == SPECKLE_BASE_OBJECT } - - dict = ins.attribute_dictionaries.to_a.find { |d| d.name == SPECKLE_BASE_OBJECT } - speckle_id = dict[:speckle_id] - application_id = dict[:application_id] - speckle_id == upcoming_speckle_id || application_id == upcoming_app_id - end&.erase! - end - # rubocop:enable Metrics/PerceivedComplexity - # rubocop:enable Metrics/CyclomaticComplexity + # rubocop:enable Metrics/ParameterLists end end end diff --git a/speckle_connector/src/speckle_objects/other/display_value.rb b/speckle_connector/src/speckle_objects/other/display_value.rb index 1d92702..f746649 100644 --- a/speckle_connector/src/speckle_objects/other/display_value.rb +++ b/speckle_connector/src/speckle_objects/other/display_value.rb @@ -14,11 +14,37 @@ module SpeckleConnector module Other # DisplayValue object definition for Speckle that represents as BlockInstance in Sketchup. class DisplayValue + def self.get_definition_name(def_obj) + family = def_obj['family'] + type = def_obj['type'] + category = def_obj['category'] + element_id = def_obj['elementId'] + + return format_naming_convention([family, type, category, element_id]) unless element_id.nil? + + return "def::#{def_obj['applicationId']}" + end + + def self.format_naming_convention(entries) + name = '' + entries.each_with_index do |entry, index| + next if entry.nil? + + name += if index == entries.length - 1 + entry.to_s + else + "#{entry}-" + end + end + name + 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) # Switch displayValue with geometry obj = collect_definition_geometries(obj) + obj['name'] = get_definition_name(obj) state, _definitions = BlockDefinition.to_native( state, diff --git a/speckle_connector/src/speckle_objects/other/revit/revit_definition.rb b/speckle_connector/src/speckle_objects/other/revit/revit_definition.rb new file mode 100644 index 0000000..d5cc155 --- /dev/null +++ b/speckle_connector/src/speckle_objects/other/revit/revit_definition.rb @@ -0,0 +1,31 @@ +# frozen_string_literal: true + +require_relative '../block_definition' +require_relative '../../base' + +module SpeckleConnector + module SpeckleObjects + module Other + module Revit + # RevitDefinition for Speckle. + class RevitDefinition < Base + SPECKLE_TYPE = OBJECTS_OTHER_REVIT_REVITINSTANCE + + def self.get_definition_name(def_obj) + family = def_obj['family'] + type = def_obj['type'] + category = def_obj['category'] + + return "#{family}-#{type}-#{category}" + end + + def self.to_native(state, definition, layer, entities, &convert_to_native) + definition_name = get_definition_name(definition) + definition['name'] = definition_name + BlockDefinition.to_native(state, definition, layer, entities, &convert_to_native) + end + end + end + end + end +end diff --git a/speckle_connector/src/speckle_objects/other/revit/revit_instance.rb b/speckle_connector/src/speckle_objects/other/revit/revit_instance.rb new file mode 100644 index 0000000..c26e7dd --- /dev/null +++ b/speckle_connector/src/speckle_objects/other/revit/revit_instance.rb @@ -0,0 +1,46 @@ +# frozen_string_literal: true + +require_relative 'revit_definition' +require_relative '../render_material' +require_relative '../transform' +require_relative '../block_definition' +require_relative '../../base' +require_relative '../../geometry/bounding_box' +require_relative '../../../sketchup_model/dictionary/dictionary_handler' + +module SpeckleConnector + module SpeckleObjects + module Other + module Revit + # RevitInstance object definition for Speckle. + class RevitInstance < Base + SPECKLE_TYPE = OBJECTS_OTHER_REVIT_REVITINSTANCE + + # Creates a component instance from a block + # @param state [States::State] state of the application. + # @param block [Object] block object that represents Speckle block. + # @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, block, layer, entities, &convert_to_native) + + block_definition = block['definition'] + + state, _definitions = RevitDefinition.to_native( + state, + block_definition, + layer, + entities, + &convert_to_native + ) + + definition = state.sketchup_state.sketchup_model + .definitions[RevitDefinition.get_definition_name(block_definition)] + + return BlockInstance.add_instance_from_definition(state, block, layer, entities, + definition, false, &convert_to_native) + end + end + end + end + end +end