Compare commits

..

22 Commits

Author SHA1 Message Date
Jedd Morgan 3d0117f701 Removed old workflows (#442)
Build and deploy / build (push) Has been cancelled
Build and deploy / deploy-installers (push) Has been cancelled
2026-02-06 09:27:17 +03:00
Mucahit Bilal GOKER 08fe6f07cf Merge pull request #450 from specklesystems/bilal/cnx-3067-running-sketchup-when-speckle-folder-is-missing
fix: Make initialization robust when app data directory is missing
2026-02-06 08:08:06 +03:00
bimgeek 37be889932 revert check 2026-02-05 17:57:41 +03:00
Mucahit Bilal GOKER ed124dd288 init fix 2026-02-05 17:12:19 +03:00
Oğuzhan Koral 760d8a033d Treat grouped mesh as sketchup entity (#449)
Build and deploy / build (push) Has been cancelled
Build and deploy / deploy-installers (push) Has been cancelled
2026-01-30 10:34:27 +03:00
Oğuzhan Koral 96cd122645 Fix: add definition attributes to block instances (#448)
* wip

* get definition and instance props under properties

* Reordering docs
2026-01-16 15:38:33 +03:00
Oğuzhan Koral 533768eb14 strip out @ from detached props (#447) 2026-01-16 14:22:50 +03:00
Oğuzhan Koral c88d3c632d skip if elevation or units null (#446)
Build and deploy / build (push) Has been cancelled
Build and deploy / deploy-installers (push) Has been cancelled
2026-01-16 10:27:38 +03:00
Oğuzhan Koral 72f5185992 feat: do not try to hightlight on no selection (#445) 2026-01-13 10:40:31 +03:00
Oğuzhan Koral b8db07a66b Feat: add account (#443)
Build and deploy / build (push) Has been cancelled
Build and deploy / deploy-installers (push) Has been cancelled
* fix(macos): appdata path

* feat: add account via sqlite

* revert: material manager

* revert: dui url

* doc
2025-10-26 09:08:54 +03:00
Oğuzhan Koral 366b961039 Do not init diff materials (#440)
Build and deploy / build (push) Has been cancelled
Build and deploy / deploy-installers (push) Has been cancelled
2025-10-14 14:02:59 +03:00
Oğuzhan Koral e244a7e2e5 Convert argb to int always to be safe (#439)
Build and deploy / build (push) Has been cancelled
Build and deploy / deploy-installers (push) Has been cancelled
2025-10-14 13:28:52 +03:00
Mucahit Bilal GOKER 9b55764b38 replace logos (#437) 2025-10-03 12:28:26 +03:00
Oğuzhan Koral 4b8012f94b fix(macos): appdata path (#438) 2025-09-17 20:35:49 +03:00
Oğuzhan Koral 9871000d84 no more netlify url (#436)
Build and deploy / build (push) Has been cancelled
Build and deploy / deploy-installers (push) Has been cancelled
2025-07-23 17:47:27 +01:00
kekesidavid 17a056b3b9 fix(sketchup) fix for orphan edges (#435)
* fix for orphan edges

* fix
2025-07-10 13:27:34 +03:00
Oğuzhan Koral a8c5bd573f Try adding object ids to render material proxies (#434)
Build and deploy / build (push) Has been cancelled
Build and deploy / deploy-installers (push) Has been cancelled
2025-06-26 22:12:23 +03:00
Oğuzhan Koral 1d2fe047bf Fix: initializing sketchup connector on large models takes a lot (#433)
* Attach observers to only orphan edges

* Do not try to read entities on load
2025-06-26 19:36:35 +03:00
Jedd Morgan 3465f86605 chore(ci): Replace GitVersion (#431) 2025-06-26 11:58:30 +03:00
Oğuzhan Koral 540e727b73 Iterate sections planes over level proxies (#432) 2025-06-23 18:59:24 +03:00
Oğuzhan Koral 8c576f820c Default to unnamed folder name if name is empty string (#429) 2025-05-22 17:28:38 +03:00
Jedd Morgan df3b673064 refactor(ci): Update workflow to use new consolidated deployment workflow (#428)
Build and deploy / build (push) Has been cancelled
Build and deploy / deploy-installers (push) Has been cancelled
* Updated workflow

* update workflow

* target main
2025-04-25 10:43:27 +01:00
28 changed files with 183 additions and 218 deletions
+23 -20
View File
@@ -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?
-78
View File
@@ -1,78 +0,0 @@
name: Update issue Status
on:
issues:
types: [closed]
jobs:
update_issue:
runs-on: ubuntu-latest
steps:
- name: Get project data
env:
GITHUB_TOKEN: ${{secrets.GHPROJECT_TOKEN}}
ORGANIZATION: specklesystems
PROJECT_NUMBER: 9
run: |
gh api graphql --header 'GraphQL-Features: projects_next_graphql' -f query='
query($org: String!, $number: Int!) {
organization(login: $org){
projectNext(number: $number) {
id
fields(first:20) {
nodes {
id
name
settings
}
}
}
}
}' -f org=$ORGANIZATION -F number=$PROJECT_NUMBER > project_data.json
echo 'PROJECT_ID='$(jq '.data.organization.projectNext.id' project_data.json) >> $GITHUB_ENV
echo 'STATUS_FIELD_ID='$(jq '.data.organization.projectNext.fields.nodes[] | select(.name== "Status") | .id' project_data.json) >> $GITHUB_ENV
echo "$PROJECT_ID"
echo "$STATUS_FIELD_ID"
echo 'DONE_ID='$(jq '.data.organization.projectNext.fields.nodes[] | select(.name== "Status") | .settings | fromjson | .options[] | select(.name== "Done") | .id' project_data.json) >> $GITHUB_ENV
echo "$DONE_ID"
- name: Add Issue to project #it's already in the project, but we do this to get its node id!
env:
GITHUB_TOKEN: ${{secrets.GHPROJECT_TOKEN}}
ISSUE_ID: ${{ github.event.issue.node_id }}
run: |
item_id="$( gh api graphql --header 'GraphQL-Features: projects_next_graphql' -f query='
mutation($project:ID!, $id:ID!) {
addProjectNextItem(input: {projectId: $project, contentId: $id}) {
projectNextItem {
id
}
}
}' -f project=$PROJECT_ID -f id=$ISSUE_ID --jq '.data.addProjectNextItem.projectNextItem.id')"
echo 'ITEM_ID='$item_id >> $GITHUB_ENV
- name: Update Status
env:
GITHUB_TOKEN: ${{secrets.GHPROJECT_TOKEN}}
ISSUE_ID: ${{ github.event.issue.node_id }}
run: |
gh api graphql --header 'GraphQL-Features: projects_next_graphql' -f query='
mutation($project:ID!, $status:ID!, $id:ID!, $value:String!) {
set_status: updateProjectNextItemField(
input: {
projectId: $project
itemId: $id
fieldId: $status
value: $value
}
) {
projectNextItem {
id
}
}
}' -f project=$PROJECT_ID -f status=$STATUS_FIELD_ID -f id=$ITEM_ID -f value=${{ env.DONE_ID }}
+13 -7
View File
@@ -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
-50
View File
@@ -1,50 +0,0 @@
name: Move new issues into Project
on:
issues:
types: [opened]
jobs:
track_issue:
runs-on: ubuntu-latest
steps:
- name: Get project data
env:
GITHUB_TOKEN: ${{secrets.GHPROJECT_TOKEN}}
ORGANIZATION: specklesystems
PROJECT_NUMBER: 9
run: |
gh api graphql --header 'GraphQL-Features: projects_next_graphql' -f query='
query($org: String!, $number: Int!) {
organization(login: $org){
projectNext(number: $number) {
id
fields(first:20) {
nodes {
id
name
settings
}
}
}
}
}' -f org=$ORGANIZATION -F number=$PROJECT_NUMBER > project_data.json
echo 'PROJECT_ID='$(jq '.data.organization.projectNext.id' project_data.json) >> $GITHUB_ENV
echo 'STATUS_FIELD_ID='$(jq '.data.organization.projectNext.fields.nodes[] | select(.name== "Status") | .id' project_data.json) >> $GITHUB_ENV
- name: Add Issue to project
env:
GITHUB_TOKEN: ${{secrets.GHPROJECT_TOKEN}}
ISSUE_ID: ${{ github.event.issue.node_id }}
run: |
item_id="$( gh api graphql --header 'GraphQL-Features: projects_next_graphql' -f query='
mutation($project:ID!, $id:ID!) {
addProjectNextItem(input: {projectId: $project, contentId: $id}) {
projectNextItem {
id
}
}
}' -f project=$PROJECT_ID -f id=$ISSUE_ID --jq '.data.addProjectNextItem.projectNextItem.id')"
echo 'ITEM_ID='$item_id >> $GITHUB_ENV
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

@@ -1,6 +1,7 @@
# frozen_string_literal: true
require 'JSON'
require 'fileutils'
require_relative '../ext/sqlite3'
require_relative '../constants/path_constants'
require_relative '../preferences/preferences'
@@ -12,6 +13,8 @@ module SpeckleConnector3
def self.load_accounts
db_path = SPECKLE_ACCOUNTS_DB_PATH
unless File.exist?(db_path)
# Ensure parent directory exists before creating the database file
FileUtils.mkdir_p(File.dirname(db_path))
File.new(SPECKLE_ACCOUNTS_DB_PATH, "w")
db = Sqlite3::Database.new(SPECKLE_ACCOUNTS_DB_PATH)
Preferences.create_objects_table(db)
@@ -25,6 +28,40 @@ module SpeckleConnector3
rows.map { |row| JSON.parse(row[1]) }
end
def self.add_account(account_id, account)
unless File.exist?(SPECKLE_ACCOUNTS_DB_PATH)
# Ensure parent directory exists before creating the database file
FileUtils.mkdir_p(File.dirname(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
@@ -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])
@@ -29,6 +29,7 @@ module SpeckleConnector3
error: error,
stackTrace: error.backtrace
}
js_error_script = "#{@view_name}.receiveResponse('#{@args.first}', #{host_app_error.to_json})"
state.with_add_queue_js_command("error_#{@view_name}", js_error_script)
end
@@ -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
@@ -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,6 +53,7 @@ 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
@@ -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
@@ -49,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 = []
@@ -199,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
@@ -463,17 +467,6 @@ module SpeckleConnector3
end
faces = converted_entities.select { |e| e.is_a?(Sketchup::Face) }
@converted_faces += faces if faces.any?
if from_revit
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|
@@ -528,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
@@ -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
@@ -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
+1 -1
View File
@@ -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