Compare commits
22 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 760d8a033d | |||
| 96cd122645 | |||
| 533768eb14 | |||
| c88d3c632d | |||
| 72f5185992 | |||
| b8db07a66b | |||
| 366b961039 | |||
| e244a7e2e5 | |||
| 9b55764b38 | |||
| 4b8012f94b | |||
| 9871000d84 | |||
| 17a056b3b9 | |||
| a8c5bd573f | |||
| 1d2fe047bf | |||
| 3465f86605 | |||
| 540e727b73 | |||
| 8c576f820c | |||
| df3b673064 | |||
| 69bde5539c | |||
| aa12b7b11b | |||
| e0b3b3cca2 | |||
| ea9a5741d7 |
@@ -11,5 +11,7 @@ jobs:
|
||||
# Orchestrate our job run sequence
|
||||
workflows:
|
||||
build_and_test:
|
||||
when:
|
||||
false
|
||||
jobs:
|
||||
- build
|
||||
- build
|
||||
|
||||
+23
-20
@@ -8,54 +8,57 @@ on:
|
||||
workflow_call:
|
||||
outputs:
|
||||
semver:
|
||||
description: "The computed version number for this run"
|
||||
description: "The full SemVer 2.0 version of this build, e.g. '3.0.0-alpha.1234' (note: no 'v'-prefix)"
|
||||
value: ${{ jobs.build.outputs.semver }}
|
||||
file_version:
|
||||
description: "The assembly info version for this run"
|
||||
description: "The file info version, e.g. '3.0.0.1234'"
|
||||
value: ${{ jobs.build.outputs.file_version }}
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
outputs:
|
||||
semver: ${{ steps.set-version.outputs.semver }}
|
||||
file_version: ${{ steps.set-info-version.outputs.file-version }}
|
||||
file_version: ${{ steps.set-version.outputs.file-version }}
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Set up Python 3.10
|
||||
uses: actions/setup-python@v3
|
||||
with:
|
||||
python-version: "3.10"
|
||||
|
||||
- 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
|
||||
- id: set-version
|
||||
name: Set version to output
|
||||
shell: bash
|
||||
run: |
|
||||
TAG=${{ github.ref_name }}
|
||||
if [[ "${{ github.ref }}" != refs/tags/* ]]; then
|
||||
TAG="v3.0.99.${{ github.run_number }}"
|
||||
fi
|
||||
SEMVER="${TAG#v}"
|
||||
FILE_VERSION=$(echo "$TAG" | sed -E 's/^v([0-9]+\.[0-9]+\.[0-9]+).*/\1/')
|
||||
FILE_VERSION="$FILE_VERSION.${{ github.run_number }}"
|
||||
|
||||
- name: Determine Version
|
||||
id: gitversion
|
||||
uses: gittools/actions/gitversion/execute@v3.0.0
|
||||
echo "semver=$SEMVER" >> "$GITHUB_OUTPUT"
|
||||
echo "file-version=$FILE_VERSION" >> "$GITHUB_OUTPUT"
|
||||
|
||||
echo $SEMVER
|
||||
echo $FILE_VERSION
|
||||
|
||||
- name: Set connector version
|
||||
run: |
|
||||
python patch_version.py ${{steps.gitversion.outputs.semVer}}
|
||||
python patch_version.py ${{steps.set-version.outputs.semver}}
|
||||
|
||||
- uses: montudor/action-zip@v1
|
||||
with:
|
||||
args: zip -q -r sketchup.zip vendor speckle_connector_3/ speckle_connector_3.rb
|
||||
|
||||
- name: ⬆️ Upload artifacts
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: output-${{steps.gitversion.outputs.semVer}}
|
||||
name: output-${{steps.set-version.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
|
||||
run: echo "semver=${{steps.gitversion.outputs.semVer}}" >> "$GITHUB_OUTPUT" # version will be retrieved from tag?
|
||||
- id: set-info-version
|
||||
name: Set version to output
|
||||
run: echo "file-version=${{steps.gitversion.outputs.AssemblySemVer}}" >> "$GITHUB_OUTPUT" # version will be retrieved from tag?
|
||||
|
||||
@@ -5,8 +5,8 @@ name: Build and deploy
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: ["main"] # Continuous delivery on every long-lived branch
|
||||
tags: ["v3.*"] # Manual delivery on every 3.x tag
|
||||
branches: ["main", "installer-test/**"]
|
||||
tags: ["v3.*.*"] # Manual delivery on every 3.x tag
|
||||
|
||||
jobs:
|
||||
build:
|
||||
@@ -16,15 +16,21 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
needs: build
|
||||
env:
|
||||
IS_TAG_BUILD: ${{ github.ref_type == 'tag' }}
|
||||
IS_PUBLIC_RELEASE: ${{ github.ref_type == 'tag' }}
|
||||
steps:
|
||||
- name: 🔫 Trigger Build Installers
|
||||
uses: ALEEF02/workflow-dispatch@v3.0.0
|
||||
- name: 🔫 Trigger Build Installer(s)
|
||||
uses: the-actions-org/workflow-dispatch@v4.0.0
|
||||
with:
|
||||
workflow: Build Sketchup
|
||||
workflow: Build Installers
|
||||
repo: specklesystems/connector-installers
|
||||
token: ${{ secrets.CONNECTORS_GH_TOKEN }}
|
||||
inputs: '{ "run_id": "${{ github.run_id }}", "semver": "${{ needs.build.outputs.semver }}", "file_version": "${{ needs.build.outputs.file_version }}", "public_release": ${{ env.IS_TAG_BUILD }} }'
|
||||
inputs: '{
|
||||
"run_id": "${{ github.run_id }}",
|
||||
"semver": "${{ needs.build.outputs.semver }}",
|
||||
"file_version": "${{ needs.build.outputs.file_version }}",
|
||||
"repo": "${{ github.repository }}",
|
||||
"is_public_release": ${{ env.IS_PUBLIC_RELEASE }}
|
||||
}'
|
||||
ref: main
|
||||
wait-for-completion: true
|
||||
wait-for-completion-interval: 10s
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 2.2 KiB After Width: | Height: | Size: 26 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 18 KiB After Width: | Height: | Size: 4.0 KiB |
@@ -25,6 +25,38 @@ module SpeckleConnector3
|
||||
rows.map { |row| JSON.parse(row[1]) }
|
||||
end
|
||||
|
||||
def self.add_account(account_id, account)
|
||||
unless File.exist?(SPECKLE_ACCOUNTS_DB_PATH)
|
||||
File.new(SPECKLE_ACCOUNTS_DB_PATH, "w")
|
||||
db = Sqlite3::Database.new(SPECKLE_ACCOUNTS_DB_PATH)
|
||||
create_objects_table(db)
|
||||
db.close
|
||||
end
|
||||
db = Sqlite3::Database.new(SPECKLE_ACCOUNTS_DB_PATH)
|
||||
account_json = JSON.generate(account)
|
||||
sql_query = "INSERT OR REPLACE INTO objects (hash, content) VALUES ('#{account_id}', '#{account_json}')"
|
||||
|
||||
begin
|
||||
db.exec(sql_query)
|
||||
puts "Account with hash #{account_id} has been added/updated."
|
||||
rescue StandardError => e
|
||||
puts "An error occurred while adding the account: #{e}"
|
||||
ensure
|
||||
db.close
|
||||
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)
|
||||
db.exec <<-SQL
|
||||
CREATE TABLE IF NOT EXISTS objects (
|
||||
hash TEXT PRIMARY KEY,
|
||||
content TEXT
|
||||
);
|
||||
SQL
|
||||
end
|
||||
|
||||
def self.remove_account(account_id)
|
||||
db_path = SPECKLE_ACCOUNTS_DB_PATH
|
||||
unless File.exist?(db_path)
|
||||
|
||||
@@ -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 add account to local Account db.
|
||||
class AddAccount < 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, account)
|
||||
SpeckleConnector3::Accounts.add_account(account_id, account)
|
||||
js_script = "accountsBinding.receiveResponse('#{resolve_id}')"
|
||||
state.with_add_queue_js_command('addAccount', 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,
|
||||
|
||||
@@ -26,7 +26,8 @@ module SpeckleConnector3
|
||||
unless path.nil?
|
||||
new_path_entities = path[-1].definition.entities
|
||||
new_path_entities.add_observer(observers[ENTITIES_OBSERVER])
|
||||
edges = new_path_entities.grep(Sketchup::Edge)
|
||||
# attach observers to only orphan edges since face edges can be detected via face changes.
|
||||
edges = new_path_entities.grep(Sketchup::Edge).filter { |edge| edge.faces.none? }
|
||||
edges.each do |edge|
|
||||
edge.add_observer(observers[ENTITY_OBSERVER])
|
||||
edge.start.add_observer(observers[ENTITY_OBSERVER])
|
||||
|
||||
@@ -6,7 +6,7 @@ require_relative '../constants/mat_constants'
|
||||
|
||||
module SpeckleConnector3
|
||||
module Actions
|
||||
# Action to initialize materials
|
||||
# Action to initialize materials (legacy for diff colors)
|
||||
class InitializeMaterials < Action
|
||||
# @param state [States::State] the current state of the {App::SpeckleConnectorApp}
|
||||
# @return [States::State] the new updated state object
|
||||
|
||||
@@ -23,18 +23,16 @@ module SpeckleConnector3
|
||||
new_sketchup_state = States::SketchupState.new(sketchup_model)
|
||||
sketchup_model.rendering_options['DisplaySectionPlanes'] = true
|
||||
new_state = state.with(:@sketchup_state => new_sketchup_state)
|
||||
# Init materials again
|
||||
new_state = InitializeMaterials.update_state(new_state)
|
||||
|
||||
# Read speckle entities
|
||||
new_speckle_entities = SketchupModel::Reader::SpeckleEntitiesReader.read(sketchup_model.entities)
|
||||
new_speckle_state = new_state.speckle_state.with_speckle_entities(Immutable::Hash.new(new_speckle_entities))
|
||||
#new_speckle_entities = SketchupModel::Reader::SpeckleEntitiesReader.read(sketchup_model.entities)
|
||||
#new_speckle_state = new_state.speckle_state.with_speckle_entities(Immutable::Hash.new(new_speckle_entities))
|
||||
# POC: Reconsider it when we will do caching between sessions!
|
||||
new_speckle_state = new_speckle_state.with_empty_object_references
|
||||
# new_speckle_state = new_speckle_state.with_empty_object_references
|
||||
# Read mapped entities
|
||||
new_mapped_entities = SketchupModel::Reader::MapperReader.read_mapped_entities(sketchup_model.entities)
|
||||
new_speckle_state = new_speckle_state.with_mapped_entities(Immutable::Hash.new(new_mapped_entities))
|
||||
new_state = new_state.with_speckle_state(new_speckle_state)
|
||||
# new_mapped_entities = SketchupModel::Reader::MapperReader.read_mapped_entities(sketchup_model.entities)
|
||||
# new_speckle_state = new_speckle_state.with_mapped_entities(Immutable::Hash.new(new_mapped_entities))
|
||||
# new_state = new_state.with_speckle_state(new_speckle_state)
|
||||
|
||||
# Read preferences from database and model.
|
||||
preferences = Preferences.read_preferences(new_state.sketchup_state.sketchup_model)
|
||||
|
||||
@@ -18,6 +18,7 @@ module SpeckleConnector3
|
||||
converter = Converters::ToNativeV2.new(state,
|
||||
root_obj['instanceDefinitionProxies'] || [],
|
||||
root_obj['renderMaterialProxies'] || [],
|
||||
root_obj['levelProxies'] || [],
|
||||
source_application,
|
||||
model_card)
|
||||
start_time = Time.now.to_f
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -14,7 +14,7 @@ module SpeckleConnector3
|
||||
path = ENV.fetch('APPDATA')
|
||||
Pathname.new(File.join(path, 'Speckle')).cleanpath.to_s
|
||||
when OS_MAC
|
||||
File.join(Dir.home, '.config/Speckle')
|
||||
File.join(Dir.home, 'Library/Application Support/Speckle')
|
||||
else
|
||||
raise 'Speckle could not determine your Appdata path'
|
||||
end
|
||||
|
||||
@@ -53,5 +53,10 @@ module SpeckleConnector3
|
||||
SPECKLE_CORE_MODELS_INSTANCES_INSTANCE_PROXY = 'Speckle.Core.Models.Instances.InstanceProxy'
|
||||
SPECKLE_CORE_MODELS_INSTANCES_INSTANCE_DEFINITION_PROXY = 'Speckle.Core.Models.Instances.InstanceDefinitionProxy'
|
||||
SPECKLE_CORE_OTHER_RENDER_MATERIAL_PROXY = 'Objects.Other.RenderMaterialProxy'
|
||||
SPECKLE_CORE_OTHER_LEVEL_PROXY = 'Objects.Other.LevelProxy'
|
||||
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
|
||||
|
||||
@@ -109,13 +109,12 @@ module SpeckleConnector3
|
||||
next
|
||||
end
|
||||
|
||||
# 3.3. Determine prop is dynamically detached or not
|
||||
# 3.3. Check prop needs to split into chunks
|
||||
chunked_detach_match = prop.match(/^@\((\d*)\)/)
|
||||
|
||||
# 3.4. Determine prop is dynamically detached or not
|
||||
is_detach_prop = prop[0] == '@'
|
||||
is_dynamically_detached = prop[0] == '@' && prop.length > 2 && prop[1] == '@'
|
||||
prop = prop[2..-1] if is_dynamically_detached
|
||||
|
||||
# 3.4. Check prop needs to split into chunks
|
||||
chunked_detach_match = prop.match(/^@\((\d*)\)/)
|
||||
|
||||
# 3.5. If split chunk is needed and prop value is array, then run chunking process
|
||||
if value.is_a?(Array) && chunked_detach_match
|
||||
@@ -165,11 +164,18 @@ module SpeckleConnector3
|
||||
next
|
||||
end
|
||||
|
||||
# 3.6 we cleanup the semantic @ or @@ we used so far for detaching or chunking
|
||||
if is_dynamically_detached
|
||||
prop = prop[2..-1]
|
||||
else
|
||||
prop = prop[1..-1] if is_detach_prop
|
||||
end
|
||||
|
||||
child = traverse_value(value, is_detach_prop)
|
||||
|
||||
is_base = value.is_a?(Hash) && !value[:speckle_type].nil?
|
||||
|
||||
# 3.6. traverse value according to value is a speckle object or not
|
||||
# 3.7. traverse value according to value is a speckle object or not
|
||||
traversed_base[prop] = if is_base
|
||||
if child[:referencedId] && child[:speckle_type] == 'reference'
|
||||
is_detach_prop ? detach_helper(child[:referencedId]) : child
|
||||
|
||||
@@ -34,7 +34,17 @@ module SpeckleConnector3
|
||||
edges.each { |edge| remove_edge_have_coplanar_faces(edge) }
|
||||
|
||||
# Remove remaining orphan edges
|
||||
# the commented out code throws an exception over deleted elements
|
||||
# even if they are rejected by deleted? flag
|
||||
# edges.reject(&:deleted?).select { |edge| edge.faces.empty? }.each(&:erase!)
|
||||
edges.each do |edge|
|
||||
next if edge.deleted?
|
||||
begin
|
||||
edge.erase! if edge.faces.empty?
|
||||
rescue Sketchup::DeletedEntityError
|
||||
# Ignore deleted edge
|
||||
end
|
||||
end
|
||||
|
||||
merged_faces(faces)
|
||||
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'
|
||||
@@ -48,16 +49,19 @@ module SpeckleConnector3
|
||||
# @return [Array<SpeckleObjects::InstanceDefinitionProxy>]
|
||||
attr_reader :root_definition_proxies
|
||||
|
||||
attr_reader :level_proxies
|
||||
|
||||
# @return [Array<SpeckleObjects::RenderMaterialProxy>]
|
||||
attr_accessor :root_render_material_proxies
|
||||
|
||||
# @param definition_proxies [Array<SpeckleObjects::InstanceDefinitionProxy>]
|
||||
# @param render_material_proxies [Array<SpeckleObjects::RenderMaterialProxy>]
|
||||
# @param model_card [SpeckleConnector3::Cards::ReceiveCard]
|
||||
def initialize(state, definition_proxies, render_material_proxies, source_app, model_card)
|
||||
def initialize(state, definition_proxies, render_material_proxies, level_proxies, source_app, model_card)
|
||||
super(state, model_card)
|
||||
@root_definition_proxies = definition_proxies
|
||||
@root_render_material_proxies = render_material_proxies
|
||||
@level_proxies = level_proxies
|
||||
@definition_proxies = {}
|
||||
@source_app = source_app.downcase
|
||||
@converted_faces = []
|
||||
@@ -94,6 +98,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 +123,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
|
||||
@@ -195,6 +202,7 @@ module SpeckleConnector3
|
||||
default_commit_layer = sketchup_model.layers.layers.find { |layer| layer.display_name == '@Untagged' }
|
||||
|
||||
traverse_commit_object(obj, default_commit_layer, @entities_to_fill)
|
||||
create_levels
|
||||
create_levels_from_section_planes
|
||||
check_hiding_layers_needed
|
||||
try_create_instance
|
||||
@@ -377,6 +385,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']]
|
||||
@@ -409,6 +421,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..!!?
|
||||
@@ -451,15 +467,15 @@ module SpeckleConnector3
|
||||
end
|
||||
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)
|
||||
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'],
|
||||
@@ -505,25 +521,29 @@ module SpeckleConnector3
|
||||
nil
|
||||
end
|
||||
|
||||
# @param state [States::State] state of the speckle application
|
||||
def create_levels(state, speckle_object)
|
||||
level = speckle_object['level']
|
||||
return state if level.nil?
|
||||
# return state unless level['speckle_type'].include?('Objects.BuiltElements.Level')
|
||||
def create_levels
|
||||
return if level_proxies.empty?
|
||||
|
||||
level_name = level['name'] || level['id']
|
||||
is_exist = @entities_to_fill.grep(Sketchup::SectionPlane).any? { |sp| sp.name == level_name }
|
||||
return state if is_exist
|
||||
level_proxies.each do |level_proxy|
|
||||
level_data_object = level_proxy['value']
|
||||
name = level_data_object['name'] || level_data_object['id']
|
||||
units = level_data_object['units']
|
||||
elevation_raw = level_data_object['elevation']
|
||||
|
||||
elevation = SpeckleObjects::Geometry.length_to_native(level['elevation'], level['units'])
|
||||
next if elevation_raw.nil? || units.nil?
|
||||
|
||||
section_plane = @entities_to_fill.add_section_plane([0, 0, elevation + LEVEL_SHIFT_VALUE], [0, 0, -1])
|
||||
section_plane.name = level_name
|
||||
section_plane.layer = levels_layer
|
||||
SketchupModel::Dictionary::SpeckleEntityDictionaryHandler.write_initial_base_data(
|
||||
section_plane, level['applicationId'], level['id'], level['speckle_type'], [], model_card.project_id
|
||||
)
|
||||
state
|
||||
is_exist = @entities_to_fill.grep(Sketchup::SectionPlane).any? { |sp| sp.name == name }
|
||||
next if is_exist
|
||||
|
||||
elevation = SpeckleObjects::Geometry.length_to_native(elevation_raw, units)
|
||||
|
||||
section_plane = @entities_to_fill.add_section_plane([0, 0, elevation + LEVEL_SHIFT_VALUE], [0, 0, -1])
|
||||
section_plane.name = name
|
||||
section_plane.layer = levels_layer
|
||||
SketchupModel::Dictionary::SpeckleEntityDictionaryHandler.write_initial_base_data(
|
||||
section_plane, level_data_object['applicationId'], level_data_object['id'], level_data_object['speckle_type'], [], model_card.project_id
|
||||
)
|
||||
end
|
||||
end
|
||||
end
|
||||
# rubocop:enable Metrics/ClassLength
|
||||
|
||||
@@ -105,9 +105,6 @@ module SpeckleConnector3
|
||||
|
||||
# @param entity [Sketchup::Entity]
|
||||
def entity_has_changed?(entity)
|
||||
# We do not necessarily consider grouped meshes for caching?
|
||||
return false if entity.is_a?(SpeckleObjects::Geometry::GroupedMesh)
|
||||
|
||||
speckle_state.changed_entity_persistent_ids.include?(entity.persistent_id.to_s) ||
|
||||
speckle_state.changed_entity_ids.include?(entity.entityID.to_s)
|
||||
end
|
||||
|
||||
@@ -48,7 +48,9 @@ module SpeckleConnector3
|
||||
|
||||
instance_dictionaries = SketchupModel::Dictionary::BaseDictionaryHandler
|
||||
.attribute_dictionaries_to_speckle(entity)
|
||||
instance_att = instance_dictionaries.any? ? { dictionaries: instance_dictionaries } : {}
|
||||
definition_dictionaries = SketchupModel::Dictionary::BaseDictionaryHandler
|
||||
.attribute_dictionaries_to_speckle(entity.definition)
|
||||
instance_att = instance_dictionaries.any? ? { "Instance Attributes": instance_dictionaries, "Definition Attributes": definition_dictionaries } : {}
|
||||
|
||||
instance_proxies[instance_id] = SpeckleObjects::InstanceProxy.new(
|
||||
definition_id,
|
||||
@@ -100,8 +102,8 @@ module SpeckleConnector3
|
||||
grouped_meshes = faces.group_by { |face| [face.layer, face.material || face.back_material] }
|
||||
grouped_meshes.each do |(layer, mat), faces|
|
||||
material_id = mat.nil? ? 'none' : mat.persistent_id.to_s
|
||||
grouped_mesh_id = "#{layer.name} - #{material_id} - #{entity.definition.persistent_id.to_s}"
|
||||
grouped_mesh = SpeckleObjects::Geometry::GroupedMesh.new(faces, layer, mat, grouped_mesh_id)
|
||||
# grouped_mesh_id = "#{layer.name} - #{material_id} - #{entity.definition.persistent_id.to_s}"
|
||||
grouped_mesh = SpeckleObjects::Geometry::GroupedMesh.new(faces, layer, mat)
|
||||
flat_atomic_objects[grouped_mesh.persistent_id.to_s] = grouped_mesh
|
||||
definition_proxy.add_object_id(grouped_mesh.faces.first.persistent_id.to_s)
|
||||
end
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -34,7 +34,7 @@ module SpeckleConnector3
|
||||
|
||||
unless material.nil?
|
||||
if render_material_proxies.has_key?(material.persistent_id.to_s)
|
||||
render_material_proxies[material.persistent_id.to_s].add_object_id(entity.persistent_id.to_s)
|
||||
render_material_proxies[material.persistent_id.to_s].try_add_object_id(entity.persistent_id.to_s)
|
||||
else
|
||||
convert_material_and_add_to_proxies(material, entity)
|
||||
end
|
||||
@@ -43,7 +43,7 @@ module SpeckleConnector3
|
||||
unless back_material.nil?
|
||||
if render_material_proxies.has_key?(back_material.persistent_id.to_s)
|
||||
render_material_proxies[back_material.persistent_id.to_s]
|
||||
.add_object_id("#{entity.persistent_id.to_s}_back")
|
||||
.try_add_object_id("#{entity.persistent_id.to_s}_back")
|
||||
else
|
||||
convert_material_and_add_to_proxies(back_material, entity, true)
|
||||
end
|
||||
|
||||
@@ -25,7 +25,11 @@ module SpeckleConnector3
|
||||
sketchup_model.selection.add(entity)
|
||||
end
|
||||
|
||||
sketchup_model.active_view.zoom(sketchup_model.selection)
|
||||
if sketchup_model.selection.empty?
|
||||
puts 'No object is selected to highlight'
|
||||
else
|
||||
sketchup_model.active_view.zoom(sketchup_model.selection)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -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
|
||||
@@ -28,15 +28,19 @@ module SpeckleConnector3
|
||||
# @return [Sketchup::Material] material that faces belong to
|
||||
attr_reader :material
|
||||
|
||||
# @return [String] structured id for grouped mesh
|
||||
# @return [String] fake id for grouped mesh
|
||||
attr_reader :persistent_id
|
||||
|
||||
# @return [String] fake id for grouped mesh
|
||||
attr_reader :entityID
|
||||
|
||||
# @return Hash{String=>Sketchup::Face}
|
||||
attr_reader :mesh_groups
|
||||
|
||||
def initialize(faces, layer, material, persistent_id)
|
||||
def initialize(faces, layer, material)
|
||||
@faces = faces
|
||||
@persistent_id = persistent_id
|
||||
@persistent_id = faces.first.persistent_id.to_s
|
||||
@entityID = faces.first.persistent_id.to_s
|
||||
@layer = layer
|
||||
@material = material
|
||||
@mesh_groups = {}
|
||||
|
||||
@@ -44,7 +44,7 @@ module SpeckleConnector3
|
||||
# @param argb [Numeric] int value of the corresponding color
|
||||
# @return [Sketchup::Color] sketchup color
|
||||
def self.from_int(argb)
|
||||
Sketchup::Color.new((argb >> 16) & 255, (argb >> 8) & 255, argb & 255, (argb >> 24) & 255)
|
||||
Sketchup::Color.new((argb.to_i >> 16) & 255, (argb.to_i >> 8) & 255, argb.to_i & 255, (argb.to_i >> 24) & 255)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -114,7 +114,8 @@ module SpeckleConnector3
|
||||
speckle_folders = layers_relation[:elements].reject { |layer_or_fol| layer_or_fol[:elements].nil? }
|
||||
|
||||
speckle_folders.each do |speckle_folder|
|
||||
sub_folder = folder.add_folder(speckle_folder[:name])
|
||||
folder_name = speckle_folder[:name] == '' ? 'Unnamed' : speckle_folder[:name]
|
||||
sub_folder = folder.add_folder(folder_name)
|
||||
sub_folder.visible = speckle_folder[:visible] unless speckle_folder[:visible].nil?
|
||||
to_native_layer_folder(speckle_folder, color_proxies, sub_folder, sketchup_model, project_id, model_id)
|
||||
end
|
||||
|
||||
@@ -35,9 +35,11 @@ module SpeckleConnector3
|
||||
end
|
||||
|
||||
# @param object_id [String] application id of the object to add into proxy list
|
||||
def add_object_id(object_id)
|
||||
object_ids.append(object_id)
|
||||
self[:objects] = object_ids
|
||||
def try_add_object_id(object_id)
|
||||
unless object_ids.include?(object_id)
|
||||
object_ids.append(object_id)
|
||||
self[:objects] = object_ids
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
require_relative 'binding'
|
||||
require_relative '../../actions/account_actions/get_accounts'
|
||||
require_relative '../../actions/account_actions/add_account'
|
||||
require_relative '../../actions/account_actions/remove_account'
|
||||
|
||||
module SpeckleConnector3
|
||||
@@ -13,6 +14,7 @@ module SpeckleConnector3
|
||||
def commands
|
||||
@commands ||= {
|
||||
getAccounts: Commands::ActionCommand.new(@app, self, Actions::GetAccounts),
|
||||
addAccount: Commands::ActionCommand.new(@app, self, Actions::AddAccount),
|
||||
removeAccount: Commands::ActionCommand.new(@app, self, Actions::RemoveAccount)
|
||||
}.freeze
|
||||
end
|
||||
|
||||
@@ -85,7 +85,7 @@ module SpeckleConnector3
|
||||
end
|
||||
# File.exist?(@htm_file) ? dialog.set_file(@htm_file) : dialog.set_url('http://localhost:9091')
|
||||
# dialog.set_url('http://localhost:8082') # uncomment this line if you want to use your local version of ui
|
||||
dialog.set_url('https://boisterous-douhua-e3cefb.netlify.app/') # uncomment this line if you want to use deployed ui on netlify
|
||||
dialog.set_url('https://dui.speckle.systems/') # uncomment this line if you want to use deployed ui on netlify
|
||||
add_exec_callback(dialog)
|
||||
dialog
|
||||
end
|
||||
|
||||
Reference in New Issue
Block a user