Compare commits

...

23 Commits

Author SHA1 Message Date
Oğuzhan Koral 85312cf20d Fix (Mapper): inconsistency on mapped elements table state 2023-05-16 13:36:27 +03:00
oguzhankoral 4051cae5b0 Clear cached element and category selection when mapped elements updated 2023-05-16 13:27:02 +03:00
oguzhankoral c64bb6dedf Include instances for button reactions
- Clear, Isolate, Hide, Select
2023-05-16 13:25:41 +03:00
Oğuzhan Koral 7bb17ae0db Fix (Collections): Add layer property to objects as full path 2023-05-16 08:39:06 +03:00
oguzhankoral 3244eb9b15 Add layer property to objects as full path
This is for receiving on Rhino
2023-05-16 08:33:42 +03:00
Oğuzhan Koral 6e173847ba Fix (Performance): Smooth only non-planar quad meshes 2023-05-15 13:53:56 +03:00
oguzhankoral 8cbc1f763d Smooth only non-planar quad meshes 2023-05-15 13:40:31 +03:00
Oğuzhan Koral 2d45abeb28 Release 2.14.0
Merging 2.13 hotfixes into dev branch
2023-05-15 13:17:54 +03:00
oguzhankoral 2fd0ad77bc Fix or disable rubocop issues 2023-05-15 13:14:32 +03:00
oguzhankoral 53c1167831 Remove orthogonality checks 2023-05-15 13:04:22 +03:00
oguzhankoral 48d4a1d7bb Add plane_utils to calculate planarity of 4 points for quad meshes 2023-05-15 13:04:19 +03:00
oguzhankoral 4bbbba6e89 Split all quad meshes 2023-05-15 13:03:22 +03:00
oguzhankoral 0a13575325 Disable rubocop for to_native 2023-05-15 13:02:12 +03:00
Oğuzhan Koral d6075209df Fix (Update): Check if branch instance is deleted 2023-05-12 12:53:19 +03:00
oguzhankoral 9d1b39422b Extract entities_updated method 2023-05-12 12:39:37 +03:00
oguzhankoral 38e297d32b Correct condition for is_update_commit 2023-05-12 11:31:23 +03:00
oguzhankoral 459ef3c9f1 Check if branch instance is deleted 2023-05-12 11:21:34 +03:00
Oğuzhan Koral 3bb12487ba Feat (QGIS): Attribute support for qgis commits 2023-05-12 10:13:44 +03:00
oguzhankoral 8b2428c60d Workaround for QGIS geometry objects or arrays 2023-05-10 17:26:47 +03:00
oguzhankoral f9befd9051 Write qgis attributes to components 2023-05-10 12:43:29 +03:00
oguzhankoral 1020a9bd5d Wrap PolygonElement object into component 2023-05-10 12:07:40 +03:00
Oğuzhan Koral 2844c4ea86 Fix (Instance): Disable aligning axes of displayValue components 2023-05-08 16:54:52 +03:00
oguzhankoral 3344188fee Disable aligning axes of displayValue components 2023-05-08 16:44:10 +03:00
19 changed files with 331 additions and 41 deletions
@@ -21,6 +21,11 @@ module SpeckleConnector
flat_entities.each do |entity|
next unless entity_ids.include?(entity.persistent_id)
if entity.is_a?(Sketchup::ComponentDefinition)
entity.instances.each do |instance|
instance.hidden = true
end
end
entity.hidden = true
end
@@ -24,14 +24,15 @@ module SpeckleConnector
# Flat entities to isolate mappings
flat_entities = SketchupModel::Query::Entity.flat_entities(sketchup_model.entities)
comp_flat_entities = flat_entities.grep(Sketchup::ComponentInstance) + flat_entities.grep(Sketchup::Group)
comp_flat_entities = flat_entities.grep(Sketchup::ComponentInstance) + flat_entities.grep(Sketchup::Group) +
flat_entities.grep(Sketchup::ComponentDefinition)
face_edge_flat_entities = flat_entities.grep(Sketchup::Face) + flat_entities.grep(Sketchup::Edge)
# Collect entity ids to clear mappings
selected_elements = data.collect { |_, entities| entities['selectedElements'] }.flatten
comps_or_groups, faces_or_edges = selected_elements.partition do |e|
e['entityType'] == 'Component' || e['entityType'] == 'Group'
e['entityType'] == 'Component' || e['entityType'] == 'Definition' || e['entityType'] == 'Group'
end
faces_or_edges_ids = faces_or_edges.collect { |e| e['entityId'] }
@@ -43,6 +44,11 @@ module SpeckleConnector
comps_or_groups_ids = comps_or_groups.collect { |e| e['entityId'] }
comp_flat_entities.select { |e| comps_or_groups_ids.include?(e.persistent_id) }.each do |entity|
if entity.is_a?(Sketchup::ComponentDefinition)
entity.instances.each do |instance|
instance.hidden = false
end
end
entity.hidden = false
end
@@ -24,6 +24,9 @@ module SpeckleConnector
flat_entities.each do |entity|
next unless entity_ids.include?(entity.persistent_id)
if entity.is_a?(Sketchup::ComponentDefinition)
state.sketchup_state.sketchup_model.selection.add(entity.instances)
end
state.sketchup_state.sketchup_model.selection.add(entity)
end
@@ -3,6 +3,8 @@
module SpeckleConnector
BASE_OBJECT = 'Base'
OBJECTS_GIS_POLYGONELEMENT = 'Objects.GIS.PolygonElement'
OBJECTS_BUILTELEMENTS_VIEW3D = 'Objects.BuiltElements.View:Objects.BuiltElements.View3D'
OBJECTS_BUILTELEMENTS_REVIT_DIRECTSHAPE = 'Objects.BuiltElements.Revit.DirectShape'
OBJECTS_BUILTELEMENTS_REVIT_LEVEL = 'Objects.BuiltElements.Level:Objects.BuiltElements.Revit.RevitLevel'
+24 -5
View File
@@ -2,6 +2,7 @@
require_relative 'converter'
require_relative '../constants/type_constants'
require_relative '../speckle_objects/gis/polygon_element'
require_relative '../speckle_objects/other/transform'
require_relative '../speckle_objects/other/render_material'
require_relative '../speckle_objects/other/block_definition'
@@ -37,6 +38,7 @@ module SpeckleConnector
OTHER = SpeckleObjects::Other
REVIT = SpeckleObjects::Revit
BUILTELEMENTS = SpeckleObjects::BuiltElements
GIS = SpeckleObjects::GIS
# Class aliases
POINT = GEOMETRY::Point
@@ -48,6 +50,7 @@ module SpeckleConnector
RENDER_MATERIAL = OTHER::RenderMaterial
DISPLAY_VALUE = OTHER::DisplayValue
VIEW3D = BUILTELEMENTS::View3d
POLYGON_ELEMENT = GIS::PolygonElement
BASE_OBJECT_PROPS = %w[applicationId id speckle_type totalChildrenCount].freeze
CONVERTABLE_SPECKLE_TYPES = %w[
@@ -61,6 +64,7 @@ module SpeckleConnector
Objects.Other.RenderMaterial
Objects.Other.Instance:Objects.Other.BlockInstance
Objects.BuiltElements.View:Objects.BuiltElements.View3D
Objects.GIS.PolygonElement
].freeze
def from_revit
@@ -71,6 +75,10 @@ module SpeckleConnector
@from_sketchup ||= source_app.include?('sketchup')
end
def from_qgis
@from_qgis ||= source_app.include?('qgis')
end
# ReceiveObjects action call this method by giving everything that comes from server.
# Upcoming object is a referencedObject of selected commit to receive.
# UI is responsible currently to fetch objects from ObjectLoader module by calling getAndConstruct method.
@@ -95,13 +103,23 @@ module SpeckleConnector
traverse_commit_object(obj, @entities_to_fill)
create_levels_from_section_planes
check_hiding_layers_needed
if !from_sketchup && !@is_update_commit
sketchup_model.entities.add_instance(@branch_definition, Geom::Transformation.new)
end
try_create_instance
@state
end
# Creating instance from @branch_definition only available for non-sketchup commits since we wrap commits
# under instance.
# There is also another use case that maybe definition is exist in file but user might be deleted it before.
# If this is the case we can add instance by checking number of instances.
# rubocop:disable Style/GuardClause
def try_create_instance
if !from_sketchup && (!@is_update_commit || @branch_definition.instances.empty?)
instance = sketchup_model.entities.add_instance(@branch_definition, Geom::Transformation.new)
BLOCK_INSTANCE.align_instance_axes(instance) if from_qgis
end
end
# rubocop:enable Style/GuardClause
def levels_layer
@levels_layer ||= sketchup_model.layers.add('Levels')
end
@@ -253,7 +271,8 @@ module SpeckleConnector
OBJECTS_OTHER_BLOCKINSTANCE_FULL => BLOCK_INSTANCE.method(:to_native),
OBJECTS_OTHER_REVIT_REVITINSTANCE => REVIT_INSTANCE.method(:to_native),
OBJECTS_OTHER_RENDERMATERIAL => RENDER_MATERIAL.method(:to_native),
OBJECTS_BUILTELEMENTS_VIEW3D => VIEW3D.method(:to_native)
OBJECTS_BUILTELEMENTS_VIEW3D => VIEW3D.method(:to_native),
OBJECTS_GIS_POLYGONELEMENT => POLYGON_ELEMENT.method(:to_native)
}.freeze
# @param state [States::State] state of the speckle application
@@ -18,6 +18,23 @@ module SpeckleConnector
end
parent_folders.reverse
end
# @param entity [Sketchup::Entity] entity to find path.
def entity_path(entity, separation = '::')
path = path(entity.layer)
full_path = path.append(entity.layer)
full_path_string = ''
full_path.each_with_index do |layer, i|
full_path_string += layer.display_name
full_path_string += separation unless i == full_path.length - 1
end
full_path_string
end
# @param string_layer_path [String] string layer path to split.
def entity_layer_from_path(string_layer_path, separation = '::')
string_layer_path.split(separation).last
end
end
end
end
@@ -100,23 +100,30 @@ module SpeckleConnector
}
end
# rubocop:disable Metrics/CyclomaticComplexity
# rubocop:disable Metrics/PerceivedComplexity
def self.mapped_entity_details(entities)
reverse_category_dictionary = Mapping::Category::RevitCategory.reverse_dictionary
entities.collect do |entity|
speckle_schema = get_schema(entity)
speckle_schema_definition = entity.respond_to?(:definition) ? get_schema(entity.definition) : nil
entity_type = entity.class.name.split('::').last.gsub(/(?<=[a-z])(?=[A-Z])/, ' ').split.first
{
name: speckle_schema['name'],
category: speckle_schema['category'],
categoryName: reverse_category_dictionary[speckle_schema['category']],
method: speckle_schema['method'],
name: speckle_schema['name'] || speckle_schema_definition['name'],
category: speckle_schema['category'] || speckle_schema_definition['category'],
categoryName: reverse_category_dictionary[speckle_schema['category']] ||
reverse_category_dictionary[speckle_schema_definition['category']],
method: speckle_schema['method'] || speckle_schema_definition['method'],
entityName: entity.respond_to?(:name) ? entity.name : '',
entityId: entity.persistent_id,
entityType: entity.class.name.split('::').last.gsub(/(?<=[a-z])(?=[A-Z])/, ' ').split.first,
entityType: entity.is_a?(Sketchup::ComponentDefinition) ? 'Definition' : entity_type,
schema: speckle_schema,
definitionSchema: entity.respond_to?(:definition) ? get_schema(entity.definition) : nil
definitionSchema: speckle_schema_definition
}
end
end
# rubocop:enable Metrics/CyclomaticComplexity
# rubocop:enable Metrics/PerceivedComplexity
end
end
end
@@ -0,0 +1,84 @@
# frozen_string_literal: true
module SpeckleConnector
# Operations related to {SketchupModel}.
module SketchupModel
# Works directly with/on SketchUp Entities of different kinds (Groups, Faces, Edges, ...).
module Utils
# Static methods to do plane calculations with sketchup geom objects like Point3d and Vector3d.
class Plane
LENGTH_TOLERANCE = 1e-8
# Create plane from 3 points
# @param origin [Geom::Point3d] the point on the plane that wil become the origin of the local coordinate system
# @param point_1 [Geom::Point3d] the point that defines first direction
# @param point_2 [Geom::Point3d] the third point on the plane
# @return [Plane] the parametrization of the plane that goes through the given points
def self.from_points(origin, point_1, point_2)
direction_x = origin.vector_to(point_1).normalize
direction_x = direction_x.normalize
normal = direction_x.cross(origin.vector_to(point_2))
direction_y = direction_x.cross(normal.normalize)
new(origin: origin, direction_u: direction_x, direction_v: direction_y)
end
# @return [Geom::Vector3d] the direction of the u-axis on the plane
attr_reader :direction_u
# @return [Geom::Vector3d] the direction of the v-axis on the plane
attr_reader :direction_v
# @return [Geom::Point3d] the origin of the local coordinate system on the plane
attr_reader :origin
# @param origin [Geom::Point3d] the origin of the coordinate system on the plane
# @param direction_u [Geom::Vector3d] the direction of the x-axis
# @param direction_v [Geom::Vector3d] the direction of the y-axis
def initialize(origin:, direction_u:, direction_v:)
@origin = origin
@direction_u = direction_u
@direction_v = direction_v
end
# Get the point object in global coordinates for the point on the plane with local coordinates (u,v).
# @param coordinate_u [Float] the u-coordinate on the plane
# @param coordinate_v [Float] the v-coordinate on the plane
# @return [Geom::Point3d] the point in space that corresponds to the given (u, v) coordinates
def point_at(coordinate_u, coordinate_v)
scaled_direction_u = Geom::Vector3d.new(direction_u.x * coordinate_u,
direction_u.y * coordinate_u,
direction_u.z * coordinate_u)
scaled_direction_v = Geom::Vector3d.new(direction_v.x * coordinate_v,
direction_v.y * coordinate_v,
direction_v.z * coordinate_v)
origin + scaled_direction_u + scaled_direction_v
end
# Find local (u, v) coordinates of the projection of the given point to the plane
# @param point [Geom::Point3d] the point that will be projected to the plane
# @return [(Float, Float)] the local coordinates on the plane that correspond to the projected point
def plane_coordinates(point)
origin_to_point = origin.vector_to(point)
coordinate_u = origin_to_point.dot(direction_u)
coordinate_v = origin_to_point.dot(direction_v)
[coordinate_u, coordinate_v]
end
# Project a given point to the plane
# @param point [Geom::Point3d] the point that will be projected to the plane
# @return [Geom::Point3d] the projected point on the plane
def project_to_plane(point)
coordinate_u, coordinate_v = plane_coordinates(point)
point_at(coordinate_u, coordinate_v)
end
# Check if the given point lies on the plane
# @param point [Geom::Point3d] the point to check
# @return [Boolean] whether the point lies on the plane
def on_plane?(point)
point.distance(project_to_plane(point)).to_m < LENGTH_TOLERANCE
end
end
end
end
end
@@ -93,9 +93,9 @@ module SpeckleConnector
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
# @param page [Sketchup::Page] scene to update -update properties-
def self.set_page_update_properties(page, update_properties)
update_properties.each do |prop, value|
@@ -53,7 +53,7 @@ module SpeckleConnector
end_pt: end_pt,
domain: domain,
units: units,
layer: edge.layer.display_name,
layer: SketchupModel::Query::Layer.entity_path(edge),
sketchup_attributes: att,
speckle_schema: speckle_schema,
application_id: edge.persistent_id.to_s
@@ -65,6 +65,8 @@ module SpeckleConnector
# @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/PerceivedComplexity
# rubocop:disable Metrics/CyclomaticComplexity
def self.to_native(state, line, entities, &_convert_to_native)
if line.key?('value')
values = line['value']
@@ -76,7 +78,8 @@ module SpeckleConnector
end_pt = Point.to_native(line['end']['x'], line['end']['y'], line['end']['z'], line['units'])
edges = entities.add_edges(start_pt, end_pt)
end
line_layer = state.sketchup_state.sketchup_model.layers.to_a.find { |l| l.display_name == line['layer'] }
line_layer_name = SketchupModel::Query::Layer.entity_layer_from_path(line['layer'])
line_layer = state.sketchup_state.sketchup_model.layers.to_a.find { |l| l.display_name == line_layer_name }
edges.each do |edge|
edge.layer = line_layer unless line_layer.nil?
unless line['sketchup_attributes'].nil?
@@ -87,6 +90,8 @@ module SpeckleConnector
return state, edges
end
# rubocop:enable Metrics/AbcSize
# rubocop:enable Metrics/PerceivedComplexity
# rubocop:enable Metrics/CyclomaticComplexity
def self.test_line(start_point, end_point, units)
domain = Primitive::Interval.from_numeric(0, 5, units)
@@ -94,6 +99,7 @@ module SpeckleConnector
start_pt: start_point,
end_pt: end_point,
domain: domain,
layer: 'test',
application_id: '',
units: units
)
@@ -7,6 +7,9 @@ require_relative '../../sketchup_model/query/entity'
require_relative '../../convertors/clean_up'
require_relative '../../sketchup_model/dictionary/base_dictionary_handler'
require_relative '../../sketchup_model/dictionary/speckle_schema_dictionary_handler'
require_relative '../../sketchup_model/dictionary/dictionary_handler'
require_relative '../../sketchup_model/utils/plane_utils'
require_relative '../../sketchup_model/query/layer'
module SpeckleConnector
module SpeckleObjects
@@ -52,6 +55,26 @@ module SpeckleConnector
end
# rubocop:enable Metrics/ParameterLists
# Checks 4 points are planar or not.
def self.check_4_points_planar(points)
plane = SketchupModel::Utils::Plane.from_points(points[0], points[1], points[2])
plane.on_plane?(points[3])
end
# Add quad mesh to sketchup native mesh by checking planarity.
# @param native_mesh [Geom::Mesh] sketchup mesh to convert them later faces.
# @param polygon_points [Array<Geom::Point3d>] sketchup points to add them with polygon to mesh.
def self.add_quad_mesh(native_mesh, polygon_points)
is_planar = check_4_points_planar(polygon_points)
if is_planar
native_mesh.add_polygon(polygon_points)
else
native_mesh.add_polygon([polygon_points[0], polygon_points[1], polygon_points[2]])
native_mesh.add_polygon([polygon_points[0], polygon_points[2], polygon_points[3]])
end
is_planar
end
# @param entities [Sketchup::Entities] entities to add
# rubocop:disable Metrics/MethodLength
# rubocop:disable Metrics/AbcSize
@@ -67,12 +90,20 @@ module SpeckleConnector
# Initialize native PolygonMesh object later to add polygon inside it.
native_mesh = Geom::PolygonMesh.new(mesh['vertices'].count / 3)
faces = mesh['faces']
has_any_non_planar_quad_mesh = false
while faces.count > 0
num_pts = faces.shift
# 0 -> 3, 1 -> 4 to preserve backwards compatibility
num_pts += 3 if num_pts < 3
indices = faces.shift(num_pts)
native_mesh.add_polygon(indices.map { |index| points[index] })
polygon_points = indices.map { |index| points[index] }
# Quad mesh
if num_pts == 4
is_planar = add_quad_mesh(native_mesh, polygon_points)
has_any_non_planar_quad_mesh = true unless is_planar
else
native_mesh.add_polygon(polygon_points)
end
end
state, _materials = Other::RenderMaterial.to_native(state, mesh['renderMaterial'],
entities, &convert_to_native)
@@ -86,9 +117,13 @@ module SpeckleConnector
# Add faces from mesh with material and smooth setting
entities.add_faces_from_mesh(native_mesh, smooth_flags, material, material)
added_faces = entities.grep(Sketchup::Face).last(native_mesh.polygons.length)
mesh_layer = state.sketchup_state.sketchup_model.layers.to_a.find { |l| l.display_name == mesh['layer'] }
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 }
added_faces.each do |face|
face.layer = mesh_layer unless mesh_layer.nil?
# Smooth edges if they already soft
# FIXME: Below line should be reconsidered. It might be a good to know here mesh comes from NURBS or not.
face.edges.each { |edge| edge.smooth = true if edge.soft? } if has_any_non_planar_quad_mesh
unless mesh['sketchup_attributes'].nil?
SketchupModel::Dictionary::BaseDictionaryHandler
.attribute_dictionaries_to_native(face, mesh['sketchup_attributes']['dictionaries'])
@@ -125,7 +160,7 @@ module SpeckleConnector
vertices: [],
faces: [],
sketchup_attributes: att,
layer: face.layer.display_name,
layer: SketchupModel::Query::Layer.entity_path(face),
speckle_schema: speckle_schema,
application_id: face.persistent_id
)
@@ -0,0 +1,87 @@
# frozen_string_literal: true
require_relative '../base'
require_relative '../other/transform'
require_relative '../other/block_definition'
require_relative '../other/block_instance'
require_relative '../../constants/type_constants'
require_relative '../../sketchup_model/dictionary/dictionary_handler'
module SpeckleConnector
module SpeckleObjects
module GIS
# BoundingBox object definition for Speckle.
class PolygonElement < Base
SPECKLE_TYPE = OBJECTS_GIS_POLYGONELEMENT
def self.get_definition_name(obj, attributes)
return obj['name'] unless obj['name'].nil?
return attributes['name'] unless attributes['name'].nil?
return "def::#{obj['id']}"
end
def self.get_qgis_attributes(obj)
attributes = obj['attributes'].to_h
speckle_properties = %w[id speckle_type totalChildrenCount units applicationId]
speckle_properties.each { |key| attributes.delete(key) }
attributes
end
# Handles polygon element differently from display value.
def self.to_native(state, obj, entities, &convert_to_native)
attributes = get_qgis_attributes(obj)
obj = collect_definition_geometries(obj)
obj['name'] = get_definition_name(obj, attributes)
state, _definitions = Other::BlockDefinition.to_native(
state,
obj,
entities,
&convert_to_native
)
definition = state.sketchup_state.sketchup_model
.definitions[Other::BlockDefinition.get_definition_name(obj)]
Other::BlockInstance.find_and_erase_existing_instance(definition, obj['id'], obj['applicationId'])
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?
SketchupModel::Dictionary::DictionaryHandler.set_hash(instance, attributes, 'qgis')
SketchupModel::Dictionary::DictionaryHandler.set_hash(definition, attributes, 'qgis')
# Align instance axes that created from display value. (without any transform)
Other::BlockInstance.align_instance_axes(instance)
return state, [instance, definition]
end
def self.collect_definition_geometries(obj)
geometries = []
# FIXME: This type check needed because of QGIS. It can send geometries both way, object or array..
# This is something need to be fixed by QGIS.
if obj['geometry'].is_a?(Array)
obj['geometry'].each do |geometry|
display_value = geometry['displayValue']
geometries += display_value
end
else
geometries += obj['geometry']['displayValue']
end
geometries.each do |geo|
if geo['speckle_type'] && geo['speckle_type'] == OBJECTS_GEOMETRY_MESH
geo['sketchup_attributes'] = { 'is_soften' => false }
end
end
obj['geometry'] = geometries
obj
end
end
end
end
end
@@ -107,16 +107,10 @@ module SpeckleConnector
application_id = definition_obj['applicationId']
definition = sketchup_model.definitions[definition_name]
# It is important check for hosted elements that wrapped into component in sketchup.
# Their definition name might be stay same but their speckle ids should be checked
# to compare they updated or not.
children_changed = false
unless definition.nil?
previous_speckle_id = definition.get_attribute(SPECKLE_BASE_OBJECT, 'speckle_id')
children_changed = previous_speckle_id != definition_obj['id']
end
# Check any entities of definition changed
entities_updated = entities_updated?(definition, definition_obj)
if definition && !children_changed &&
if definition && !entities_updated &&
(definition.name == definition_name || definition.guid == application_id)
return state, [definition]
end
@@ -216,6 +210,19 @@ module SpeckleConnector
new_speckle_state
end
# rubocop:enable Metrics/ParameterLists
# It is important check for hosted elements that wrapped into component in sketchup.
# Their definition name might be stay same but their speckle ids should be checked
# to compare they updated or not.
def self.entities_updated?(definition, speckle_definition)
children_changed = false
unless definition.nil?
# TODO: Here we need to check later if definition invalid or not.
previous_speckle_id = definition.get_attribute(SPECKLE_BASE_OBJECT, 'speckle_id')
children_changed = previous_speckle_id != speckle_definition['id']
end
children_changed
end
end
end
end
@@ -7,6 +7,7 @@ require_relative '../base'
require_relative '../geometry/bounding_box'
require_relative '../../sketchup_model/dictionary/base_dictionary_handler'
require_relative '../../sketchup_model/dictionary/speckle_schema_dictionary_handler'
require_relative '../../sketchup_model/query/layer'
module SpeckleConnector
module SpeckleObjects
@@ -61,7 +62,7 @@ module SpeckleConnector
render_material: group.material.nil? ? nil : RenderMaterial.from_material(group.material),
transform: Other::Transform.from_transformation(group.transformation, units),
block_definition: block_definition,
layer: group.layer.display_name,
layer: SketchupModel::Query::Layer.entity_path(group),
sketchup_attributes: att,
speckle_schema: speckle_schema,
application_id: group.guid
@@ -97,7 +98,7 @@ module SpeckleConnector
end,
transform: Other::Transform.from_transformation(component_instance.transformation, units),
block_definition: block_definition,
layer: component_instance.layer.display_name,
layer: SketchupModel::Query::Layer.entity_path(component_instance),
sketchup_attributes: att,
speckle_schema: speckle_schema,
application_id: component_instance.persistent_id.to_s
@@ -130,8 +131,10 @@ module SpeckleConnector
definition = state.sketchup_state.sketchup_model
.definitions[BlockDefinition.get_definition_name(block_definition)]
block_layer = state.sketchup_state.sketchup_model.layers.to_a.find { |l| l.display_name == block['layer'] }
return add_instance_from_definition(state, block, block_layer, entities, definition, is_group, &convert_to_native)
block_layer_name = SketchupModel::Query::Layer.entity_layer_from_path(block['layer'])
block_layer = state.sketchup_state.sketchup_model.layers.to_a.find { |l| l.display_name == block_layer_name }
return add_instance_from_definition(state, block, block_layer, entities, definition, is_group,
&convert_to_native)
end
def self.get_transform_matrix(block)
@@ -63,7 +63,7 @@ module SpeckleConnector
instance = entities.add_instance(definition, transform)
instance.name = obj['name'] unless obj['name'].nil?
# Align instance axes that created from display value. (without any transform)
BlockInstance.align_instance_axes(instance)
# BlockInstance.align_instance_axes(instance)
return state, [instance, definition]
end
@@ -10,6 +10,7 @@ module SpeckleConnector
class Layer < Base
SPECKLE_TYPE = 'Speckle.Core.Models.Collection'
# rubocop:disable Metrics/ParameterLists
def initialize(name:, visible:, is_folder:, color: nil, layers_and_folders: [], application_id: nil)
super(
speckle_type: SPECKLE_TYPE,
@@ -24,6 +25,7 @@ module SpeckleConnector
self[:collectionType] = 'layer'
self[:elements] = layers_and_folders if layers_and_folders.any?
end
# rubocop:enable Metrics/ParameterLists
# @param speckle_layer [Object] speckle layer object.
# @param folder [Sketchup::Layers, Sketchup::LayerFolder] folder to create layers in it.
@@ -2,7 +2,6 @@
require_relative '../../../base'
module SpeckleConnector
module SpeckleObjects
module Speckle
@@ -12,6 +12,7 @@ module SpeckleConnector
# LayerCollection object that collect other speckle objects under it's elements.
class LayerCollection < Collection
SPECKLE_TYPE = 'Speckle.Core.Models.Collection'
# rubocop:disable Metrics/ParameterLists
def initialize(name:, visible:, is_folder:, color: nil, elements: [], application_id: nil)
super(
name: name,
@@ -23,6 +24,7 @@ module SpeckleConnector
self[:is_folder] = is_folder
self[:color] = color unless color.nil?
end
# rubocop:enable Metrics/ParameterLists
def self.create_layer_collections(sketchup_model)
headless_layers = sketchup_model.layers.layers.collect do |layer|
@@ -62,6 +64,7 @@ module SpeckleConnector
# @param entity_layer [Sketchup::Layer] entity layer.
# @param collection [Array] collection to search elements for entity's layer.
# rubocop:disable Metrics/CyclomaticComplexity
def self.get_or_create_layer_collection(entity_layer, collection)
folder_path = SpeckleConnector::SketchupModel::Query::Layer.path(entity_layer)
entity_layer_path = folder_path + [entity_layer]
@@ -75,10 +78,8 @@ module SpeckleConnector
if collection_candidate.nil?
color = folder.respond_to?(:color) ? SpeckleObjects::Others::Color.to_speckle(folder.color) : nil
collection_candidate = LayerCollection.new(
name: folder.display_name,
visible: folder.visible?,
is_folder: folder.is_a?(Sketchup::LayerFolder),
color: color
name: folder.display_name, visible: folder.visible?,
is_folder: folder.is_a?(Sketchup::LayerFolder), color: color
)
# Before switching collection with the new one, we should add it to current collection's elements
collection[:elements].append(collection_candidate)
@@ -88,6 +89,7 @@ module SpeckleConnector
collection
end
# rubocop:enable Metrics/CyclomaticComplexity
end
end
end
+9 -3
View File
@@ -165,6 +165,7 @@ export default {
return {
isIsolated: false,
elementSelection: {},
categorySelection: [],
mappedEntities: [],
mappedEntityCount: 0,
// Expanded indexes for mapped element table (Categories)
@@ -181,9 +182,9 @@ export default {
}
},
computed: {
categorySelection() {
return Object.keys(this.elementSelection)
},
// categorySelection() {
// return Object.keys(this.elementSelection)
// },
},
mounted() {
sketchup.exec({name: "collect_mapped_entities", data: {}})
@@ -248,9 +249,14 @@ export default {
selectMappedElementsOnSketchup(){
sketchup.exec({ name: "select_mappings_from_table", data: this.elementSelection })
},
// Update mapped elements table whenever mapped elements has changed.
getMappedElementsTableData(){
let groupByCategoryName = groupBy('categoryName')
let groupedByCategoryName = groupByCategoryName(this.mappedEntities)
// Reset selected categories and elements whenever mapped elements states has changed
this.elementSelection = {}
this.categorySelection = []
this.mappedElementsExpandedIndexes = []
this.mappedEntitiesTableData = Object.entries(groupedByCategoryName).map(
(entry) => {
const [categoryName, entities] = entry