Separate revit instance from block instance

This commit is contained in:
oguzhankoral
2023-03-14 20:08:02 +03:00
parent 9ecad52df2
commit a9ded445a7
6 changed files with 144 additions and 65 deletions
@@ -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
@@ -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
@@ -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
@@ -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,
@@ -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
@@ -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