Compare commits

...

28 Commits

Author SHA1 Message Date
Oğuzhan Koral 69bde5539c Add serverUrl and workspaceSlug to model cards (#427)
Build and deploy / build (push) Has been cancelled
Build and deploy / deploy-installers (push) Has been cancelled
2025-04-21 15:06:19 +03:00
Oğuzhan Koral aa12b7b11b remove unnessary logging (#426) 2025-04-21 14:11:45 +03:00
Oğuzhan Koral e0b3b3cca2 Convert revit data object natively (#425) 2025-04-21 14:08:20 +03:00
Jedd Morgan ea9a5741d7 Update config.yml (#424) 2025-04-21 10:30:19 +03:00
Oğuzhan Koral 1fe1c8d5a8 Fix the source of the issue (#423)
Build and deploy / build (push) Has been cancelled
Build and deploy / deploy-installers (push) Has been cancelled
2025-03-28 16:47:56 +03:00
Oğuzhan Koral ac58560a69 Verbose about menu commands and guard about name (#422)
Build and deploy / build (push) Has been cancelled
Build and deploy / deploy-installers (push) Has been cancelled
2025-03-24 15:32:39 +03:00
Oğuzhan Koral d0b234bf3d delete ruby.yml temp (#421)
Build and deploy / build (push) Has been cancelled
Build and deploy / deploy-installers (push) Has been cancelled
2025-03-19 13:32:09 +03:00
oguzhankoral 981fe05c15 deploy over main 2025-03-19 11:50:17 +03:00
Oğuzhan Koral 918550465b No more beta (#418) 2025-03-19 10:20:46 +03:00
Oğuzhan Koral 963d4f1738 Add remove account and remove models (#417) 2025-03-19 10:16:34 +03:00
oguzhankoral d809732280 Merge branch 'dui3/alpha'
# Conflicts:
#	.circleci/config.yml
2025-03-17 23:16:02 +03:00
oguzhankoral c4e38a11b7 run on ubuntu-22.04 2025-03-17 20:03:42 +03:00
oguzhankoral 7abe215bc2 sorry circleci, have you back for now 2025-03-17 20:01:04 +03:00
oguzhankoral 0f269430bc no more circleci 2025-03-17 19:29:39 +03:00
Oğuzhan Koral b8a298c54b Fix: various papercuts (#409)
Build and deploy / build (push) Has been cancelled
Build and deploy / deploy-installers (push) Has been cancelled
* Do not report converted grouped meshes

* remember last selected account on db
2025-03-10 18:36:58 +03:00
Oğuzhan Koral e1d33cd250 fix the highlight freeze (#408) 2025-03-10 16:18:07 +03:00
Oğuzhan Koral 4563dec9bc Debounce progress update (#407) 2025-03-07 21:07:44 +03:00
Oğuzhan Koral de284083fd add defintiion and layer name to instance proxy (#406)
Build and deploy / build (push) Has been cancelled
Build and deploy / deploy-installers (push) Has been cancelled
2025-03-07 12:19:11 +03:00
Oğuzhan Koral 85ee66ca4d Fix(instances): instance name prop is missing (#405)
Build and deploy / build (push) Has been cancelled
Build and deploy / deploy-installers (push) Has been cancelled
* add name to instances

* set name only if it is not empty
2025-03-07 12:04:16 +03:00
Jedd Morgan 5365dc858e Jedd/cxpla 169 update connector deployment ci to error on publishing zero (#404)
* Update deploy.yml

* Update build.yml
2025-03-05 11:47:56 +03:00
Oğuzhan Koral 69f9544638 get accounts always from sqlite - not from cached state (#403)
Build and deploy / build (push) Has been cancelled
Build and deploy / deploy-installers (push) Has been cancelled
2025-02-27 14:57:28 +03:00
Oğuzhan Koral bf5409cf90 Feat(dui3): add properties (#402)
Build and deploy / build (push) Has been cancelled
Build and deploy / deploy-installers (push) Has been cancelled
* rename sketchup_attributes with properties for send

* receive properties

* handle send receive properties
2025-02-18 22:32:05 +03:00
Oğuzhan Koral bd4f668526 Make selection is default (#401)
Build and deploy / build (push) Has been cancelled
Build and deploy / deploy-installers (push) Has been cancelled
2025-01-16 19:34:16 +03:00
Oğuzhan Koral d21df0c6fd Update build.yml
Build and deploy / build (push) Has been cancelled
Build and deploy / deploy-installers (push) Has been cancelled
2024-12-20 17:33:55 +03:00
Oğuzhan Koral d808fdaa09 Update build.yml 2024-12-20 17:31:44 +03:00
oguzhankoral 20528f72df Merge remote-tracking branch 'origin/development' 2024-03-19 13:32:03 +03:00
oguzhankoral ad9af9bb3d Merge remote-tracking branch 'origin/development' 2024-02-27 12:38:00 +03:00
oguzhankoral 133308141b Merge branch 'development' 2023-11-28 13:57:11 +03:00
48 changed files with 487 additions and 141 deletions
+17
View File
@@ -0,0 +1,17 @@
version: 2.1
# Define the jobs we want to run for this project
jobs:
build:
docker:
- image: cimg/base:2023.03
steps:
- run: echo "so long and thanks for all the fish"
# Orchestrate our job run sequence
workflows:
build_and_test:
when:
false
jobs:
- build
+4
View File
@@ -31,6 +31,8 @@ jobs:
- name: Install GitVersion
uses: gittools/actions/gitversion/setup@v3.0.0
with:
versionSpec: 6.0.5 # github actions doesnt like 6.1.0 onwards https://github.com/GitTools/actions/blob/main/docs/versions.md
- name: Determine Version
id: gitversion
@@ -48,6 +50,8 @@ jobs:
with:
name: output-${{steps.gitversion.outputs.semVer}}
path: sketchup.zip
retention-days: 1
if-no-files-found: error
compression-level: 0 # no compression
- id: set-version
name: Set version to output
+4 -1
View File
@@ -5,7 +5,7 @@ name: Build and deploy
on:
push:
branches: ["dui3/alpha", "deploy/*"] # Continuous delivery on every long-lived branch
branches: ["main"] # Continuous delivery on every long-lived branch
tags: ["v3.*"] # Manual delivery on every 3.x tag
jobs:
@@ -31,3 +31,6 @@ jobs:
wait-for-completion-timeout: 10m
display-workflow-run-url: true
display-workflow-run-url-interval: 10s
- uses: geekyeggo/delete-artifact@v5
with:
name: output-*
-38
View File
@@ -1,38 +0,0 @@
# This workflow uses actions that are not certified by GitHub.
# They are provided by a third-party and are governed by
# separate terms of service, privacy policy, and support
# documentation.
# This workflow will download a prebuilt Ruby version, install dependencies and run tests with Rake
# For more information see: https://github.com/marketplace/actions/setup-ruby-jruby-and-truffleruby
name: Ruby
on:
push:
branches: [ "main" ]
pull_request:
branches: [ "main" ]
permissions:
contents: read
jobs:
test:
runs-on: ubuntu-latest
strategy:
matrix:
ruby-version: ['2.7']
steps:
- uses: actions/checkout@v3
- name: Set up Ruby
# To automatically get bug fixes and new Ruby versions for ruby/setup-ruby,
# change this to (see https://github.com/ruby/setup-ruby#versioning):
# uses: ruby/setup-ruby@v1
uses: ruby/setup-ruby@0a29871fe2b0200a17a4497bae54fe5df0d973aa # v1.115.3
with:
ruby-version: ${{ matrix.ruby-version }}
bundler-cache: true # runs 'bundle install' and caches installed gems automatically
- name: Run tests
run: bundle exec rake
+27 -5
View File
@@ -3,6 +3,7 @@
require 'JSON'
require_relative '../ext/sqlite3'
require_relative '../constants/path_constants'
require_relative '../preferences/preferences'
module SpeckleConnector3
# Accounts to communicate with models on user's account.
@@ -11,11 +12,11 @@ module SpeckleConnector3
def self.load_accounts
db_path = SPECKLE_ACCOUNTS_DB_PATH
unless File.exist?(db_path)
raise(
IOError,
"No Accounts db found. Please read the guide for different options for adding your account:\n
https://speckle.guide/user/manager.html#adding-accounts"
)
File.new(SPECKLE_ACCOUNTS_DB_PATH, "w")
db = Sqlite3::Database.new(SPECKLE_ACCOUNTS_DB_PATH)
Preferences.create_objects_table(db)
db.close
return []
end
db = Sqlite3::Database.new(db_path)
@@ -24,6 +25,27 @@ module SpeckleConnector3
rows.map { |row| JSON.parse(row[1]) }
end
def self.remove_account(account_id)
db_path = SPECKLE_ACCOUNTS_DB_PATH
unless File.exist?(db_path)
raise(
IOError,
"No Accounts db found. Please read the guide for different options for adding your account:\n
https://speckle.guide/user/manager.html#adding-accounts"
)
end
db = Sqlite3::Database.new(db_path)
begin
db.exec("DELETE FROM objects WHERE hash = '#{account_id}'")
puts "Account with hash #{account_id} has been removed."
rescue StandardError => e
puts "An error occurred: #{e}"
ensure
db.close
end
end
def self.get_account_by_id(id)
accounts = load_accounts
accounts.select { |acc| acc['id'] == id }[0]
@@ -1,8 +1,8 @@
# frozen_string_literal: true
require_relative 'action'
require_relative '../accounts/accounts'
require_relative 'load_saved_streams'
require_relative '../action'
require_relative '../../accounts/accounts'
require_relative '../load_saved_streams'
module SpeckleConnector3
module Actions
@@ -12,7 +12,7 @@ module SpeckleConnector3
# @return [States::State] the new updated state object
def self.update_state(state, resolve_id)
puts 'Initialisation of Speckle accounts requested by plugin'
accounts_data = state.speckle_state.accounts
accounts_data = SpeckleConnector3::Accounts.load_accounts
js_script = "accountsBinding.receiveResponse('#{resolve_id}', #{accounts_data.to_json})"
state.with_add_queue_js_command('getAccounts', js_script)
end
@@ -0,0 +1,20 @@
# frozen_string_literal: true
require_relative '../action'
require_relative '../../accounts/accounts'
require_relative '../load_saved_streams'
module SpeckleConnector3
module Actions
# Action to remove account from database.
class RemoveAccount < Action
# @param state [States::State] the current state of the {App::SpeckleConnectorApp}
# @return [States::State] the new updated state object
def self.update_state(state, resolve_id, account_id)
SpeckleConnector3::Accounts.remove_account(account_id)
js_script = "accountsBinding.receiveResponse('#{resolve_id}')"
state.with_add_queue_js_command('removeAccount', js_script)
end
end
end
end
@@ -17,7 +17,9 @@ module SpeckleConnector3
def self.update_state(state, resolve_id, data)
model_card_id = data['modelCardId']
account_id = data['accountId']
server_url = data['serverUrl']
workspace_id = data['workspaceId']
workspace_slug = data['workspaceSlug']
project_id = data['projectId']
model_id = data['modelId']
project_name = data['projectName']
@@ -32,7 +34,7 @@ module SpeckleConnector3
has_dismissed_update_warning = data['hasDismissedUpdateWarning']
baked_object_ids = data['bakedObjectIds'].nil? ? nil : data['bakedObjectIds'].values
receive_card = Cards::ReceiveCard.new(model_card_id, account_id, workspace_id,
receive_card = Cards::ReceiveCard.new(model_card_id, account_id, server_url, workspace_id, workspace_slug,
project_id, model_id,
project_name, model_name,
selected_version_id, selected_version_source_app, selected_version_user_id,
@@ -22,7 +22,9 @@ module SpeckleConnector3
send_card = Cards::SendCard.new(
data['modelCardId'],
data['accountId'],
data['serverUrl'],
data['workspaceId'],
data['workspaceSlug'],
data['projectId'],
data['projectName'],
data['modelId'],
@@ -21,7 +21,9 @@ module SpeckleConnector3
send_card = Cards::SendCard.new(
id,
card['account_id'],
card['server_url'],
card['workspace_id'],
card['workspace_slug'],
card['project_id'],
card['project_name'],
card['model_id'],
@@ -36,7 +38,9 @@ module SpeckleConnector3
{
modelCardId: send_card.model_card_id,
accountId: send_card.account_id,
serverUrl: send_card.server_url,
workspaceId: send_card.workspace_id,
workspaceSlug: send_card.workspace_slug,
projectId: send_card.project_id,
modelId: send_card.model_id,
sendFilter: send_card.send_filter,
@@ -51,7 +55,7 @@ module SpeckleConnector3
# TODO: CONVERTER_V2: Extract into new actions
receive_cards = receive_cards_hash.collect do |id, card|
receive_card = Cards::ReceiveCard.new(id, card['account_id'], card['workspace_id'], card['project_id'], card['model_id'],
receive_card = Cards::ReceiveCard.new(id, card['account_id'], card['server_url'], card['workspace_id'], card['workspace_slug'], card['project_id'], card['model_id'],
card['project_name'], card['model_name'], card['selected_version_id'],
card['selected_version_source_app'], card['selected_version_user_id'],
card['latest_version_id'], card['latest_version_source_app'],
@@ -63,7 +67,9 @@ module SpeckleConnector3
{
modelCardId: receive_card.model_card_id,
accountId: receive_card.account_id,
serverUrl: receive_card.server_url,
workspaceId: receive_card.workspace_id,
workspaceSlug: receive_card.workspace_slug,
projectId: receive_card.project_id,
modelId: receive_card.model_id,
projectName: receive_card.project_name,
@@ -0,0 +1,34 @@
# frozen_string_literal: true
require_relative '../action'
require_relative '../../cards/send_card'
require_relative '../../cards/receive_card'
require_relative '../../filters/send/everything_filter'
require_relative '../../filters/send/selection_filter'
require_relative '../../filters/send_filters'
require_relative '../../sketchup_model/dictionary/model_card_dictionary_handler'
module SpeckleConnector3
module Actions
# Action to remove cards.
class RemoveModels < Action
# @param state [States::State] the current state of the {App::SpeckleConnectorApp}
# @return [States::State] the new updated state object
def self.update_state(state, resolve_id, data)
data.each do |model_card|
SketchupModel::Dictionary::ModelCardDictionaryHandler.remove_card_dict(state.sketchup_state.sketchup_model, model_card)
new_speckle_state = if model_card['typeDiscriminator'] == 'ReceiverModelCard'
state.speckle_state.without_receive_card(model_card['id'])
else
state.speckle_state.without_send_card(model_card['id'])
end
state = state.with_speckle_state(new_speckle_state)
end
# Resolve promise
js_script = "baseBinding.receiveResponse('#{resolve_id}')"
state.with_add_queue_js_command('removeModels', js_script)
end
end
end
end
@@ -0,0 +1,21 @@
# frozen_string_literal: true
require_relative '../action'
require_relative '../../preferences/preferences'
module SpeckleConnector3
module Actions
class GetUserSelectedAccountId < Action
# @param state [States::State] the current state of the {App::SpeckleConnectorApp}
# @return [States::State] the new updated state object
def self.update_state(state, resolve_id)
user_selected_account_id = Preferences.get_user_selected_account_id
accountsConfig = {
userSelectedAccountId: user_selected_account_id
}
js_script = "configBinding.receiveResponse('#{resolve_id}', #{accountsConfig.to_json})"
state.with_add_queue_js_command('getUserSelectedAccountId', js_script)
end
end
end
end
@@ -0,0 +1,18 @@
# frozen_string_literal: true
require_relative '../action'
require_relative '../../preferences/preferences'
module SpeckleConnector3
module Actions
class SetUserSelectedAccountId < Action
# @param state [States::State] the current state of the {App::SpeckleConnectorApp}
# @return [States::State] the new updated state object
def self.update_state(state, resolve_id, account_id)
Preferences.set_user_selected_account_id(account_id)
js_script = "configBinding.receiveResponse('#{resolve_id}')"
state.with_add_queue_js_command('setUserSelectedAccountId', js_script)
end
end
end
end
@@ -17,6 +17,7 @@ module SpeckleConnector3
# @return [States::State] the new updated state object
def self.update_state(state, resolve_id, model_card_id)
# Set active path always to model to be safe always. Later we can address it
start_time = Time.now.to_f
state.sketchup_state.sketchup_model.active_path = nil
units = Converters::SKETCHUP_UNITS[state.sketchup_state.length_units]
model_card = state.speckle_state.send_cards[model_card_id]
@@ -53,11 +54,29 @@ module SpeckleConnector3
base[:colorProxies] = unpacked_colors
base[:units] = units
elapsed_time = (Time.now.to_f - start_time).round(3)
puts "==== Converting objects executed in #{elapsed_time} sec ===="
start_time = Time.now.to_f
sender_progress_args = {
modelCardId: model_card_id,
progress: {
progress: nil,
status: 'Serializing'
}
}
state.instant_message_sender.call("sendBinding.emit('setModelProgress', #{sender_progress_args.to_json})")
id, batches, refs = converter.serialize(base, state.user_state.preferences)
elapsed_time = (Time.now.to_f - start_time).round(3)
puts "==== Serializing objects executed in #{elapsed_time} sec ===="
new_speckle_state = new_speckle_state.with_object_references(model_card.project_id, refs)
new_speckle_state = new_speckle_state.with_empty_changed_entity_persistent_ids
new_speckle_state = new_speckle_state.with_empty_changed_entity_ids
puts "Cached/Total object: #{converter.cached_object_count}/#{converter.object_count}"
puts("converted #{base.count} objects for stream #{model_card.project_id}")
state = state.with_speckle_state(new_speckle_state)
+11 -1
View File
@@ -27,27 +27,37 @@ module SpeckleConnector3
# @return [String] workspace id of the card.
attr_reader :workspace_id
# @return [String] workspace slug of the card.
attr_reader :workspace_slug
# @return [String] server url of the card.
attr_reader :server_url
# @return [Boolean] card is valid or not.
attr_reader :valid
# rubocop:disable Metrics/ParameterLists
def initialize(model_card_id, account_id, workspace_id, project_id, project_name, model_id, model_name)
def initialize(model_card_id, account_id, server_url, workspace_id, workspace_slug, project_id, project_name, model_id, model_name)
super()
@model_card_id = model_card_id
@account_id = account_id
@workspace_id = workspace_id
@workspace_slug = workspace_slug
@project_id = project_id
@project_name = project_name
@model_id = model_id
@model_name = model_name
@server_url = server_url
@valid = true
self[:model_card_id] = model_card_id
self[:account_id] = account_id
self[:workspace_id] = workspace_id
self[:workspace_slug] = workspace_slug
self[:project_id] = project_id
self[:project_name] = project_name
self[:model_id] = model_id
self[:model_name] = model_name
self[:server_url] = server_url
self[:valid] = @valid
end
# rubocop:enable Metrics/ParameterLists
@@ -48,7 +48,9 @@ module SpeckleConnector3
def initialize(
model_card_id,
account_id,
server_url,
workspace_id,
workspace_slug,
project_id,
model_id,
project_name,
@@ -63,7 +65,7 @@ module SpeckleConnector3
expired,
baked_object_ids = nil
)
super(model_card_id, account_id, workspace_id, project_id, project_name, model_id, model_name)
super(model_card_id, account_id, server_url, workspace_id, workspace_slug, project_id, project_name, model_id, model_name)
@selected_version_id = selected_version_id
@selected_version_source_app = selected_version_source_app
@selected_version_user_id = selected_version_user_id
+3 -1
View File
@@ -26,7 +26,9 @@ module SpeckleConnector3
def initialize(
model_card_id,
account_id,
server_url,
workspace_id,
workspace_slug,
project_id,
project_name,
model_id,
@@ -35,7 +37,7 @@ module SpeckleConnector3
send_filter,
send_settings
)
super(model_card_id, account_id, workspace_id, project_id, project_name, model_id, model_name)
super(model_card_id, account_id, server_url, workspace_id, workspace_slug, project_id, project_name, model_id, model_name)
@send_filter = send_filter
@send_settings = send_settings
@latest_created_version_id = latest_created_version_id
@@ -1,19 +1,19 @@
# frozen_string_literal: true
require_relative 'card'
module SpeckleConnector3
module Cards
# Send card for sketchup connector to communicate speckle.
class SendCardMultipleFilters < Card
# @return [Hash{String=>Filter}] filters of the card.
attr_reader :filters
def initialize(card_id, account_id, project_id, model_id, filters)
super(card_id, account_id, project_id, model_id)
@filters = filters
self[:filters] = filters
end
end
end
end
# # frozen_string_literal: true
#
# require_relative 'card'
#
# module SpeckleConnector3
# module Cards
# # Send card for sketchup connector to communicate speckle.
# class SendCardMultipleFilters < Card
# # @return [Hash{String=>Filter}] filters of the card.
# attr_reader :filters
#
# def initialize(card_id, account_id, project_id, model_id, filters)
# super(card_id, account_id, project_id, model_id)
# @filters = filters
# self[:filters] = filters
# end
# end
# end
# end
+1 -1
View File
@@ -26,7 +26,7 @@ module SpeckleConnector3
_run(*parameters)
end
rescue StandardError => e
action = Actions::HandleError.new(e, @binding.name, @action, parameters)
action = Actions::HandleError.new(e, @binding.nil? ? "unknown binding" : @binding.name, @action, parameters)
app.update_state!(action)
end
end
@@ -22,7 +22,7 @@ module SpeckleConnector3
SPECKLE_DUI3 = 'speckle_dui3'
def dialog_title
"Speckle (Beta) for SketchUp"
"Speckle for SketchUp"
end
private
@@ -9,6 +9,8 @@ module SpeckleConnector3
# @return [UI::Command] the command that can be added to Sketchup menu or toolbar
def self.sketchup_command(command, menu_text)
UI::Command.new(menu_text) do
puts '### COMMAND CALLED BY MENU ###'
puts "Name: #{menu_text}"
command.run
end
end
@@ -65,10 +65,10 @@ module SpeckleConnector3
def self.initialize_dui3_speckle_command(app)
cmd = MenuCommandHandler.sketchup_command(
InitializeDUI3Speckle.new(app, nil), 'Initialize Speckle (Beta)'
InitializeDUI3Speckle.new(app, nil), 'Initialize Speckle'
)
cmd.tooltip = 'Speckle (Beta) for SketchUp'
cmd.status_bar_text = 'Opens the Speckle Connector (Beta)'
cmd.tooltip = 'Speckle for SketchUp'
cmd.status_bar_text = 'Opens the Speckle Connector'
cmd.small_icon = '../../img/s2logo_dui3.png'
cmd.large_icon = '../../img/s2logo_dui3.png'
cmd
@@ -54,4 +54,8 @@ module SpeckleConnector3
SPECKLE_CORE_MODELS_INSTANCES_INSTANCE_DEFINITION_PROXY = 'Speckle.Core.Models.Instances.InstanceDefinitionProxy'
SPECKLE_CORE_OTHER_RENDER_MATERIAL_PROXY = 'Objects.Other.RenderMaterialProxy'
SPECKLE_CORE_OTHER_COLOR_PROXY = 'Speckle.Core.Models.Proxies.ColorProxy'
# DATA OBJECTS
SPECKLE_OBJECT_DATA_OBJECT = 'Objects.Data.DataObject'
SPECKLE_OBJECT_DATA_OBJECT_REVIT = 'Objects.Data.DataObject:Objects.Data.RevitObject'
end
@@ -22,6 +22,7 @@ require_relative '../speckle_objects/built_elements/network'
require_relative '../speckle_objects/speckle/core/models/collection'
require_relative '../speckle_objects/speckle/core/models/gis_layer_collection'
require_relative '../speckle_objects/instance_definition_proxy'
require_relative '../speckle_objects/data/revit_data_object'
require_relative '../sketchup_model/dictionary/speckle_entity_dictionary_handler'
require_relative '../ui_data/report/conversion_result'
require_relative '../convertors/conversion_error'
@@ -94,6 +95,8 @@ module SpeckleConnector3
LAYER_COLLECTION = SpeckleObjects::Speckle::Core::Models::LayerCollection
GIS_LAYER_COLLECTION = SpeckleObjects::Speckle::Core::Models::GisLayerCollection
REVIT_DATA_OBJECT = SpeckleObjects::RevitDataObject
BASE_OBJECT_PROPS = %w[applicationId id speckle_type].freeze
CONVERTABLE_SPECKLE_TYPES = %w[
Objects.Geometry.Line
@@ -117,6 +120,7 @@ module SpeckleConnector3
Speckle.Core.Models.Collections.Collection:Speckle.Core.Models.Collections.Layer
Speckle.Core.Models.Collections.Collection:Objects.GIS.RasterLayer
Speckle.Core.Models.Collections.Collection:Objects.GIS.VectorLayer
Objects.Data.DataObject:Objects.Data.RevitObject
].freeze
def from_revit
@@ -153,6 +157,11 @@ module SpeckleConnector3
definition_name = proxy['name']
definition = state.sketchup_state.sketchup_model.definitions.add(definition_name)
properties = proxy['properties'] || proxy['sketchup_attributes']
unless properties.nil?
SketchupModel::Dictionary::BaseDictionaryHandler
.attribute_dictionaries_to_native(definition, properties['dictionaries'])
end
definition.behavior.always_face_camera = proxy['alwaysFaceCamera'] if proxy['alwaysFaceCamera']
@definition_proxies[proxy['applicationId']] = SpeckleObjects::InstanceDefinitionProxy.new(
definition,
@@ -372,6 +381,10 @@ module SpeckleConnector3
# rubocop:enable Metrics/PerceivedComplexity
def speckle_object_to_native(obj)
if SPECKLE_OBJECTS_WITH_NATIVE_CONVERSION[obj['speckle_type']]
return SPECKLE_OBJECTS_WITH_NATIVE_CONVERSION[obj['speckle_type']]
end
return DISPLAY_VALUE.method(:to_native) unless obj['displayValue'].nil? && obj['@displayValue'].nil?
SPECKLE_OBJECT_TO_NATIVE[obj['speckle_type']]
@@ -404,6 +417,10 @@ module SpeckleConnector3
SPECKLE_CORE_MODELS_COLLECTION_VECTOR_LAYER => GIS_LAYER_COLLECTION.method(:to_native)
}.freeze
SPECKLE_OBJECTS_WITH_NATIVE_CONVERSION = {
SPECKLE_OBJECT_DATA_OBJECT_REVIT => REVIT_DATA_OBJECT.method(:to_native)
}
def entities_to_bake(obj, entities)
entities_to_bake = entities
object_id = obj['applicationId'].to_s # TODO: CONVERTER_V2: faces have integer application id..!!?
@@ -447,14 +464,25 @@ module SpeckleConnector3
faces = converted_entities.select { |e| e.is_a?(Sketchup::Face) }
@converted_faces += faces if faces.any?
if from_revit
# Create levels as section planes if they exists
create_levels(state, obj)
# Create layers from category of object and place object in it
# create_layers_from_categories(state, obj, converted_entities)
begin
# Create levels as section planes if they exists
create_levels(state, obj)
# Create layers from category of object and place object in it
# create_layers_from_categories(state, obj, converted_entities)
rescue StandardError => e
puts "Level could not be created: #{e.message}"
end
end
# Create speckle entities from sketchup entities to achieve continuous traversal.
converted_entities.each do |converted|
if converted.is_a?(Sketchup::ComponentDefinition)
next # no need to report definitions
end
if !from_sketchup && converted.is_a?(Sketchup::Face)
next # Otherwise we have many noise in report and causing delay post-receive
end
@conversion_results.push(UiData::Report::ConversionResult.new(UiData::Report::ConversionStatus::SUCCESS,
obj['id'],
obj['speckle_type'],
@@ -37,12 +37,17 @@ module SpeckleConnector3
# @return [SketchupModel::Definitions::UnpackResult]
attr_reader :unpacked_entities
attr_reader :object_count
attr_reader :cached_object_count
# @param model_card [Cards::SendCard] sender card
def initialize(state, unpacked_entities, model_card)
super(state, model_card)
@send_filter = model_card.send_filter
@conversion_results = []
@unpacked_entities = unpacked_entities
@object_count = 0
@cached_object_count = 0
end
def convert_entities_to_base_blocks_poc
@@ -64,11 +69,9 @@ module SpeckleConnector3
# @return [String, Integer, Array<Object>] base id of base and batches
def serialize(base_and_entity, preferences)
serializer = SpeckleConnector3::Converters::BaseObjectSerializer.new(preferences)
t = Time.now.to_f
id = serializer.serialize(base_and_entity)
batches = serializer.batch_json_objects
write_to_speckle_folder(id, batches)
puts "Generating traversed object elapsed #{(Time.now.to_f - t).round(5)} s"
return id, batches, serializer.object_references
end
@@ -122,26 +125,28 @@ module SpeckleConnector3
# @param speckle_state [States::SpeckleState]
# rubocop:disable Metrics/MethodLength
def from_native_to_speckle(entity, preferences, speckle_state, parent, ignore_cache, &convert)
@object_count += 1
persistent_id = entity.is_a?(SpeckleObjects::Geometry::GroupedMesh) ? entity.faces.first.persistent_id.to_s : entity.persistent_id.to_s
# Where we do send caching!
if !ignore_cache && !entity_has_changed?(entity) &&
speckle_state.object_references_by_project[model_card.project_id] &&
speckle_state.object_references_by_project[model_card.project_id].keys.include?(entity.persistent_id.to_s)
reference = speckle_state.object_references_by_project[model_card.project_id][entity.persistent_id.to_s]
speckle_state.object_references_by_project.keys.include?(model_card.project_id) &&
speckle_state.object_references_by_project[model_card.project_id].keys.include?(persistent_id)
reference = speckle_state.object_references_by_project[model_card.project_id][persistent_id]
add_to_report(entity, reference)
@cached_object_count += 1
return speckle_state, reference
end
if entity.is_a?(SpeckleObjects::Geometry::GroupedMesh)
mesh = SpeckleObjects::Geometry::Mesh.from_faces(speckle_state: speckle_state, faces: entity.faces,
units: @units, model_preferences: preferences[:model])
add_to_report(entity, mesh)
return speckle_state, mesh
end
if entity.is_a?(Sketchup::Edge)
line = SpeckleObjects::Geometry::Line.from_edge(speckle_state: speckle_state, edge: entity,
units: @units, model_preferences: preferences[:model]).to_h
add_to_report(entity, line)
add_to_report(entity, line) unless entity.parent.is_a?(Sketchup::ComponentDefinition)
return speckle_state, line
end
@@ -16,6 +16,7 @@ module SpeckleConnector3
super('selection', 'Selection', nil, summary)
@selected_object_ids = selected_object_ids
self[:selectedObjectIds] = selected_object_ids
self[:isDefault] = true # hard coded default value, that's fair
end
def check_expiry(ids)
@@ -34,6 +34,41 @@ module SpeckleConnector3
)
end
# this is needed to get last selected account
def self.get_user_selected_account_id
db = Sqlite3::Database.new(SPECKLE_CONFIG_DB_PATH)
row_data = db.exec("SELECT content FROM 'objects' WHERE hash = 'accounts'")
is_config_accounts_exist = !row_data.empty?
return nil unless is_config_accounts_exist
# Select data
row_data = db.exec("SELECT content FROM 'objects' WHERE hash = 'accounts'").first.first
# Parse string to hash
data_hash = JSON.parse(row_data).to_h
# Get current theme value
data_hash['userSelectedAccountId']
end
def self.format_user_selected_accounts_insert(account_id)
"('accounts', '{\"userSelectedAccountId\": \"#{account_id}\"}');"
end
def self.format_user_selected_accounts_update(account_id)
"{\"userSelectedAccountId\": \"#{account_id}\"}"
end
def self.set_user_selected_account_id(account_id)
db = Sqlite3::Database.new(SPECKLE_CONFIG_DB_PATH)
row_data = db.exec("SELECT content FROM 'objects' WHERE hash = 'accounts'")
is_config_accounts_exist = !row_data.empty?
if !is_config_accounts_exist
db.exec("INSERT INTO 'objects' VALUES #{format_user_selected_accounts_insert(account_id)}")
else
db.exec("UPDATE 'objects' SET content = '#{format_user_selected_accounts_update(account_id)}' WHERE hash = 'accounts'")
end
end
# Creates the 'objects' table in the database if it doesn't already exist.
# @param db [Sqlite3::Database] the SQLite3 database instance.
def self.create_objects_table(db)
@@ -46,11 +46,19 @@ module SpeckleConnector3
instance_id = entity.persistent_id.to_s
definition_id = entity.definition.persistent_id.to_s
instance_dictionaries = SketchupModel::Dictionary::BaseDictionaryHandler
.attribute_dictionaries_to_speckle(entity)
instance_att = instance_dictionaries.any? ? { dictionaries: instance_dictionaries } : {}
instance_proxies[instance_id] = SpeckleObjects::InstanceProxy.new(
definition_id,
entity.name,
entity.definition.name,
entity.layer.display_name,
SpeckleObjects::Other::Transform.from_transformation(entity.transformation, @units).value,
depth,
@units,
sketchup_attributes: instance_att,
application_id: instance_id
)
@@ -70,7 +78,17 @@ module SpeckleConnector3
return
end
definition_proxy = SpeckleObjects::InstanceDefinitionProxy.new(entity.definition, [], depth, application_id: definition_id)
definition_dictionaries = SketchupModel::Dictionary::BaseDictionaryHandler
.attribute_dictionaries_to_speckle(entity.definition)
definition_att = definition_dictionaries.any? ? { dictionaries: definition_dictionaries } : {}
definition_proxy = SpeckleObjects::InstanceDefinitionProxy.new(
entity.definition,
[],
depth,
sketchup_attributes: definition_att,
application_id: definition_id
)
definition_proxy[:name] = entity.definition.name
definition_proxy[:description] = entity.definition.description
@@ -16,7 +16,20 @@ module SpeckleConnector3
].freeze
# @param entity [Sketchup::Entity] entity to get attribute dictionaries
def self.attribute_dictionaries_to_speckle(entity, model_preferences)
def self.attribute_dictionaries_to_speckle(entity)
dictionaries = {}
return dictionaries if entity.attribute_dictionaries.nil?
entity.attribute_dictionaries.each do |att_dict|
dict_name = att_dict == '' ? 'empty_dictionary_name' : att_dict.name
dictionaries[dict_name] = att_dict.to_h unless IGNORED_DICTIONARY_NAMES.include?(att_dict.name)
end
dictionaries
end
# @param entity [Sketchup::Entity] entity to get attribute dictionaries
# @note v2 logic
def self.attribute_dictionaries_to_speckle_by_settings(entity, model_preferences)
dictionaries = {}
return dictionaries unless model_preferences[INCLUDE_ENTITY_ATTRIBUTES]
@@ -72,6 +72,22 @@ module SpeckleConnector3
hash
end
# @param obj [Object] object to write
# @param dict [Sketchup::AttributeDictionary] attribute dictionary to write data.
def self.hash_to_dict(dict_name, obj, dict)
dict_to_write = dict.attribute_dictionary(dict_name, true)
obj.each do |key, value|
# value = obj.instance_variable_get(var)
# var_name = var.to_s[1..-1]
if value.is_a?(Hash) # FIXME or not, depends:-> This doesn't cover arrays that has objects in it.
hash_to_dict(key.to_s, value, dict_to_write)
else
dict_to_write[key] = value
end
end
end
# @return [String] the name of the dictionary to read from
def self.dictionary_name
raise NotImplementedError 'Implement this in subclass'
@@ -13,30 +13,14 @@ module SpeckleConnector3
# @param sketchup_model [Sketchup::Model] sketchup model to save cards into it's attribute dictionary
def self.save_send_card_to_model(send_card, sketchup_model)
send_cards_dict = send_cards_dict(sketchup_model)
serialize_obj_to_dict(send_card.model_card_id, send_card, send_cards_dict)
hash_to_dict(send_card.model_card_id, send_card, send_cards_dict)
end
# @param receive_card [Cards::ReceiveCard] card to save model
# @param sketchup_model [Sketchup::Model] sketchup model to save cards into it's attribute dictionary
def self.save_receive_card_to_model(receive_card, sketchup_model)
receive_cards_dict = receive_cards_dict(sketchup_model)
serialize_obj_to_dict(receive_card.model_card_id, receive_card, receive_cards_dict)
end
# @param obj [Object] object to write
# @param dict [Sketchup::AttributeDictionary] attribute dictionary to write data.
def self.serialize_obj_to_dict(dict_name, obj, dict)
dict_to_write = dict.attribute_dictionary(dict_name, true)
obj.each do |key, value|
# value = obj.instance_variable_get(var)
# var_name = var.to_s[1..-1]
if value.is_a?(Hash) # FIXME or not depends: This doesn't cover arrays that has objects in it.
serialize_obj_to_dict(key.to_s, value, dict_to_write)
else
dict_to_write[key] = value
end
end
hash_to_dict(receive_card.model_card_id, receive_card, receive_cards_dict)
end
def self.remove_card_dict(sketchup_model, data)
@@ -101,7 +85,7 @@ module SpeckleConnector3
dict_to_write = dict_to_write.attribute_dictionary(dict_name, true)
dict_to_write = dict_to_write.attribute_dictionary(var_name, true)
value.each do |key, hash_value|
serialize_obj_to_dict(key.to_s, hash_value, dict_to_write)
hash_to_dict(key.to_s, hash_value, dict_to_write)
end
else
dict_to_write.set_attribute(dict_name, var_name, value)
@@ -12,10 +12,13 @@ module SpeckleConnector3
def self.highlight_entities(sketchup_model, entity_ids)
sketchup_model.selection.clear
# below code causing huge performance bottleneck since iterate nestedly, I was initially considering to cover all cases,
# but not worth to have highlighting sub elements since we already highlight the parent. This can be only an issue when user sends
# only the sub elements
# Flat entities to select entities on card
flat_entities = SketchupModel::Query::Entity.flat_entities(sketchup_model.entities)
# flat_entities = SketchupModel::Query::Entity.flat_entities(sketchup_model.entities)
flat_entities.each do |entity|
sketchup_model.entities.each do |entity|
next unless entity_ids.include?(entity.persistent_id.to_s)
sketchup_model.selection.add(entity.instances) if entity.is_a?(Sketchup::ComponentDefinition)
@@ -0,0 +1,17 @@
# frozen_string_literal: true
require_relative '../base'
require_relative '../../constants/type_constants'
module SpeckleConnector3
module SpeckleObjects
class DataObject < Base
SPECKLE_TYPE = SPECKLE_OBJECT_DATA_OBJECT
def self.to_native(state, data_object, layer, _entities, &convert_to_native)
properties = data_object['properties']
return state
end
end
end
end
@@ -0,0 +1,25 @@
# frozen_string_literal: true
require_relative '../base'
require_relative '../../constants/type_constants'
require_relative '../other/display_value'
require_relative '../../sketchup_model/dictionary/base_dictionary_handler'
module SpeckleConnector3
module SpeckleObjects
class RevitDataObject < Base
SPECKLE_TYPE = SPECKLE_OBJECT_DATA_OBJECT_REVIT
def self.to_native(state, revit_data_object, layer, entities, &convert_to_native)
properties = revit_data_object['properties']
new_state, instance_and_definition = SpeckleObjects::Other::DisplayValue.to_native(state, revit_data_object, layer, entities, &convert_to_native)
instance, _definition = instance_and_definition
attr = instance.attribute_dictionary('Speckle', true)
SketchupModel::Dictionary::BaseDictionaryHandler.hash_to_dict('Revit Parameters', properties, attr) if properties
return new_state, instance_and_definition
end
end
end
end
@@ -36,7 +36,7 @@ module SpeckleConnector3
self[:units] = units
self[:layer] = layer unless layer.nil?
self['@SpeckleSchema'] = speckle_schema if speckle_schema.any?
self[:sketchup_attributes] = sketchup_attributes if sketchup_attributes.any?
self[:properties] = sketchup_attributes if sketchup_attributes.any?
end
# rubocop:enable Metrics/ParameterLists
@@ -59,7 +59,7 @@ module SpeckleConnector3
# @param edge [Sketchup::Edge] edge to convert line.
def self.from_edge(speckle_state:, edge:, units:, model_preferences:, global_transformation: nil)
dictionaries = SketchupModel::Dictionary::BaseDictionaryHandler
.attribute_dictionaries_to_speckle(edge, model_preferences)
.attribute_dictionaries_to_speckle_by_settings(edge, model_preferences)
att = dictionaries.any? ? { dictionaries: dictionaries } : {}
speckle_schema = Mapper.to_speckle(speckle_state, edge, units, global_transformation: global_transformation)
start_pt = Geometry::Point.from_vertex(edge.start.position, units)
@@ -141,7 +141,10 @@ module SpeckleConnector3
edges.each do |edge|
edge.layer = layer
# edge.layer = line_layer.nil? ? layer : line_layer
unless line['sketchup_attributes'].nil?
if !line['properties'].nil?
SketchupModel::Dictionary::BaseDictionaryHandler
.attribute_dictionaries_to_native(edge, line['properties']['dictionaries'])
elsif !line['sketchup_attributes'].nil? # backward compatibility
SketchupModel::Dictionary::BaseDictionaryHandler
.attribute_dictionaries_to_native(edge, line['sketchup_attributes']['dictionaries'])
end
@@ -49,7 +49,7 @@ module SpeckleConnector3
# self[:renderMaterial] = render_material
self[:'@(31250)vertices'] = vertices
self[:'@(62500)faces'] = faces
self[:sketchup_attributes] = sketchup_attributes if sketchup_attributes.any?
self[:properties] = sketchup_attributes if sketchup_attributes.any?
self['@SpeckleSchema'] = speckle_schema if speckle_schema.any?
end
# rubocop:enable Metrics/ParameterLists
@@ -129,7 +129,10 @@ module SpeckleConnector3
# 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?
if !mesh['properties'].nil?
SketchupModel::Dictionary::BaseDictionaryHandler
.attribute_dictionaries_to_native(face, mesh['properties']['dictionaries'])
elsif !mesh['sketchup_attributes'].nil? # backward compatibility
SketchupModel::Dictionary::BaseDictionaryHandler
.attribute_dictionaries_to_native(face, mesh['sketchup_attributes']['dictionaries'])
end
@@ -151,7 +154,7 @@ module SpeckleConnector3
# rubocop:disable Metrics/ParameterLists
def self.from_face(speckle_state:, face:, units:, model_preferences:, global_transform: nil, parent_material: nil)
dictionaries = SketchupModel::Dictionary::BaseDictionaryHandler
.attribute_dictionaries_to_speckle(face, model_preferences)
.attribute_dictionaries_to_speckle_by_settings(face, model_preferences)
has_any_soften_edge = face.edges.any?(&:soft?)
att = dictionaries.any? ? { is_soften: has_any_soften_edge, dictionaries: dictionaries }
: { is_soften: has_any_soften_edge }
@@ -278,7 +281,9 @@ module SpeckleConnector3
# @param mesh [Object] speckle mesh object
# @param entities [Sketchup::Entities] sketchup entities that mesh will be created in it as face.
def self.get_soften_setting(mesh, entities)
unless mesh['sketchup_attributes'].nil?
if !mesh['properties'].nil?
return mesh['properties']['is_soften'].nil? ? true : mesh['properties']['is_soften']
elsif !mesh['sketchup_attributes'].nil? # backward compatibility
return mesh['sketchup_attributes']['is_soften'].nil? ? true : mesh['sketchup_attributes']['is_soften']
end
@@ -55,7 +55,7 @@ module SpeckleConnector3
geometries.each do |geo|
if geo['speckle_type'] && geo['speckle_type'] == OBJECTS_GEOMETRY_MESH
geo['sketchup_attributes'] = { 'is_soften' => false }
geo['properties'] = { 'is_soften' => false }
end
end
@@ -57,7 +57,7 @@ module SpeckleConnector3
geometries.each do |geo|
if geo['speckle_type'] && geo['speckle_type'] == OBJECTS_GEOMETRY_MESH
geo['sketchup_attributes'] = { 'is_soften' => false }
geo['properties'] = { 'is_soften' => false }
end
end
@@ -20,7 +20,7 @@ module SpeckleConnector3
# @param object_ids [Array<String>]
# @param max_depth [Integer]
# @param application_id [String | NilClass]
def initialize(definition, object_ids, max_depth, application_id: nil)
def initialize(definition, object_ids, max_depth, sketchup_attributes: {}, application_id: nil)
super(
speckle_type: SPECKLE_TYPE,
application_id: application_id,
@@ -31,6 +31,7 @@ module SpeckleConnector3
self[:objects] = object_ids
self[:maxDepth] = max_depth
self[:alwaysFaceCamera] = definition.behavior.always_face_camera?
self[:properties] = sketchup_attributes if sketchup_attributes.any?
end
def add_object_id(object_id)
@@ -8,24 +8,37 @@ module SpeckleConnector3
module SpeckleObjects
class InstanceProxy < Base
SPECKLE_TYPE = SPECKLE_CORE_MODELS_INSTANCES_INSTANCE_PROXY
def initialize(definition_id, transform, max_depth, units, application_id: nil)
def initialize(definition_id, name, definitionName, layerName, transform, max_depth, units, sketchup_attributes: {}, application_id: nil)
super(
speckle_type: SPECKLE_TYPE,
application_id: application_id,
id: nil
)
self[:name] = name if name != ""
self[:definition] = definitionName if definitionName != ""
self[:layer] = layerName if layerName != ""
self[:units] = units
self[:definitionId] = definition_id
self[:maxDepth] = max_depth
self[:transform] = transform
self[:properties] = sketchup_attributes if sketchup_attributes.any?
end
def self.to_native(state, instance_proxy, layer, entities, definition_proxies, &_convert_to_native)
definition_id = instance_proxy['definitionId']
proxy_transform = instance_proxy['transform']
name = instance_proxy['name']
transform = Other::Transform.to_native(proxy_transform, instance_proxy['units'])
definition = definition_proxies[definition_id].definition
instance = entities.add_instance(definition, transform)
instance.name = name if name
unless instance_proxy['properties'].nil?
SketchupModel::Dictionary::BaseDictionaryHandler
.attribute_dictionaries_to_native(instance, instance_proxy['properties']['dictionaries'])
end
instance.layer = layer if layer # TODO: CONVERTER_V2 check
# TODO: CONVERTER_V2 handle groups
return state, [instance, definition]
@@ -32,7 +32,7 @@ module SpeckleConnector3
self[:units] = units
self[:name] = name
self[:always_face_camera] = always_face_camera
self[:sketchup_attributes] = sketchup_attributes if sketchup_attributes.any?
self[:properties] = sketchup_attributes if sketchup_attributes.any?
self[:SpeckleSchema] = speckle_schema if speckle_schema.any?
# '@@' means that it is a detached property.
self['@@geometry'] = geometry
@@ -47,7 +47,7 @@ module SpeckleConnector3
# rubocop:disable Metrics/ParameterLists
def self.from_definition(definition, units, preferences, speckle_state, parent, &convert)
dictionaries = SketchupModel::Dictionary::BaseDictionaryHandler
.attribute_dictionaries_to_speckle(definition, preferences[:model])
.attribute_dictionaries_to_speckle_by_settings(definition, preferences[:model])
att = dictionaries.any? ? { dictionaries: dictionaries } : {}
speckle_schema = SketchupModel::Dictionary::SpeckleSchemaDictionaryHandler
.speckle_schema_to_speckle(definition)
@@ -118,7 +118,7 @@ module SpeckleConnector3
geometry = definition_obj['geometry'] || definition_obj['@geometry'] || definition_obj['displayValue']
always_face_camera = definition_obj['always_face_camera'].nil? ? false : definition_obj['always_face_camera']
sketchup_attributes = definition_obj['sketchup_attributes']
properties = definition_obj['properties'] || definition_obj['sketchup_attributes']
definition&.entities&.clear!
definition ||= sketchup_model.definitions.add(definition_name)
@@ -143,9 +143,9 @@ module SpeckleConnector3
# puts("definition finished: #{name} (#{application_id})")
# puts(" entity count: #{definition.entities.count}")
definition.behavior.always_face_camera = always_face_camera
unless sketchup_attributes.nil?
unless properties.nil?
SketchupModel::Dictionary::BaseDictionaryHandler
.attribute_dictionaries_to_native(definition, sketchup_attributes['dictionaries'])
.attribute_dictionaries_to_native(definition, properties['dictionaries'])
end
return state, [definition]
end
@@ -40,7 +40,7 @@ module SpeckleConnector3
self[:is_sketchup_group] = is_sketchup_group
# self[:renderMaterial] = render_material
self[:transform] = transform
self[:sketchup_attributes] = sketchup_attributes if sketchup_attributes.any?
self[:properties] = sketchup_attributes if sketchup_attributes.any?
self[:speckle_schema] = speckle_schema if speckle_schema.any?
# FIXME: Since blockDefinition sends with @ as detached, block basePlane renders on viewer.
self['@@definition'] = block_definition
@@ -53,7 +53,7 @@ module SpeckleConnector3
group.persistent_id.to_s)
speckle_state = new_speckle_state
dictionaries = SketchupModel::Dictionary::BaseDictionaryHandler
.attribute_dictionaries_to_speckle(group, preferences[:model])
.attribute_dictionaries_to_speckle_by_settings(group, preferences[:model])
att = dictionaries.any? ? { dictionaries: dictionaries } : {}
speckle_schema = SketchupModel::Dictionary::SpeckleSchemaDictionaryHandler.speckle_schema_to_speckle(group)
block_instance = BlockInstance.new(
@@ -83,7 +83,7 @@ module SpeckleConnector3
speckle_state = new_speckle_state
dictionaries = SketchupModel::Dictionary::BaseDictionaryHandler
.attribute_dictionaries_to_speckle(component_instance, preferences[:model])
.attribute_dictionaries_to_speckle_by_settings(component_instance, preferences[:model])
att = dictionaries.any? ? { dictionaries: dictionaries } : {}
speckle_schema = SketchupModel::Dictionary::SpeckleSchemaDictionaryHandler
.speckle_schema_to_speckle(component_instance)
@@ -245,10 +245,15 @@ module SpeckleConnector3
end
instance.name = block['name'] unless block['name'].nil?
unless block['sketchup_attributes'].nil?
if !block['properties'].nil?
SketchupModel::Dictionary::BaseDictionaryHandler
.attribute_dictionaries_to_native(instance, block['properties']['dictionaries'])
elsif !block['sketchup_attributes'].nil? # backward compatibility
SketchupModel::Dictionary::BaseDictionaryHandler
.attribute_dictionaries_to_native(instance, block['sketchup_attributes']['dictionaries'])
end
return state, [instance, definition]
end
# rubocop:enable Metrics/AbcSize
@@ -32,7 +32,7 @@ module SpeckleConnector3
self[:emissive] = emissive
self[:metalness] = metalness
self[:roughness] = roughness
self[:sketchup_attributes] = sketchup_attributes
self[:properties] = sketchup_attributes
end
# rubocop:enable Metrics/ParameterLists
@@ -12,6 +12,23 @@ module SpeckleConnector3
module Speckle
module Core
module Models
class Debouncer
def initialize(wait_time)
@wait_time = wait_time
@mutex = Mutex.new
@thread = nil
end
def call(&block)
@mutex.synchronize do
@thread&.kill # Cancel the previous execution
@thread = Thread.new do
sleep @wait_time
block.call
end
end
end
end
# ModelCollection object that collect other speckle objects under it's elements.
class ModelCollection < Collection
DIRECT_SHAPE = SpeckleObjects::BuiltElements::Revit::DirectShape
@@ -61,6 +78,8 @@ module SpeckleConnector3
application_id: sketchup_model.guid
)
last_sent_time = Time.now
count = 0
entities.each do |entity|
layer_collection = LayerCollection.get_or_create_layer_collection(entity.layer, model_collection)
@@ -83,13 +102,10 @@ module SpeckleConnector3
status: progress == 1 ? 'Completed' : 'Converting'
}
}
action = Proc.new do
if Time.now - last_sent_time >= 1
state.instant_message_sender.call("sendBinding.emit('setModelProgress', #{sender_progress_args.to_json})")
last_sent_time = Time.now
end
state.worker.add_job(Job.new(entity.persistent_id.to_s, &action))
state.worker.do_work(Time.now.to_f, &action)
end
return speckle_state, model_collection
@@ -1,7 +1,8 @@
# frozen_string_literal: true
require_relative 'binding'
require_relative '../../actions/get_accounts'
require_relative '../../actions/account_actions/get_accounts'
require_relative '../../actions/account_actions/remove_account'
module SpeckleConnector3
module Ui
@@ -11,7 +12,8 @@ module SpeckleConnector3
class AccountsBinding < Binding
def commands
@commands ||= {
getAccounts: Commands::ActionCommand.new(@app, self, Actions::GetAccounts)
getAccounts: Commands::ActionCommand.new(@app, self, Actions::GetAccounts),
removeAccount: Commands::ActionCommand.new(@app, self, Actions::RemoveAccount)
}.freeze
end
end
@@ -11,6 +11,7 @@ require_relative '../../actions/base_actions/add_model'
require_relative '../../actions/base_actions/highlight_model'
require_relative '../../actions/base_actions/highlight_objects'
require_relative '../../actions/base_actions/remove_model'
require_relative '../../actions/base_actions/remove_models'
require_relative '../../actions/base_actions/get_send_filters'
require_relative '../../actions/base_actions/update_send_filter'
require_relative '../../actions/base_actions/get_document_state'
@@ -27,6 +28,7 @@ module SpeckleConnector3
highlightModel: Commands::ActionCommand.new(@app, self, Actions::HighlightModel),
highlightObjects: Commands::ActionCommand.new(@app, self, Actions::HighlightObjects),
removeModel: Commands::ActionCommand.new(@app, self, Actions::RemoveModel),
removeModels: Commands::ActionCommand.new(@app, self, Actions::RemoveModels),
# Since we send exact model card with updateModel, I can use directly AddModel action, it will replace
updateModel: Commands::ActionCommand.new(@app, self, Actions::AddModel),
getSourceApplicationName: Commands::ActionCommand.new(@app, self, Actions::GetSourceAppName),
@@ -4,6 +4,8 @@ require_relative 'binding'
require_relative '../../actions/config_actions/get_is_dev_mode'
require_relative '../../actions/config_actions/get_config'
require_relative '../../actions/config_actions/update_config'
require_relative '../../actions/config_actions/get_user_selected_account_id'
require_relative '../../actions/config_actions/set_user_selected_account_id'
module SpeckleConnector3
module Ui
@@ -15,7 +17,9 @@ module SpeckleConnector3
@commands ||= {
getIsDevMode: Commands::ActionCommand.new(@app, self, Actions::GetIsDevMode),
getConfig: Commands::ActionCommand.new(@app, self, Actions::GetConfig),
updateConfig: Commands::ActionCommand.new(@app, self, Actions::UpdateConfig)
updateConfig: Commands::ActionCommand.new(@app, self, Actions::UpdateConfig),
getUserSelectedAccountId: Commands::ActionCommand.new(@app, self, Actions::GetUserSelectedAccountId),
setUserSelectedAccountId: Commands::ActionCommand.new(@app, self, Actions::SetUserSelectedAccountId)
}.freeze
end
end
+1 -1
View File
@@ -5,7 +5,7 @@ module SpeckleConnector3
# An interface to Sketchup user interface. This object controls the menu `Extensions->Speckle` in Sketchup's menu,
# the Speckle toolbar and sending message to the user via Sketchup.
class SketchupUi
MENU_TITLE = 'Speckle Beta'
MENU_TITLE = 'Speckle'
BEFORE_NEVER_SHOWN = -1
# @return [Sketchup::Menu] the menu of the Speckle