Compare commits
59 Commits
2.15.0-rc5
..
2.17.2
| Author | SHA1 | Date | |
|---|---|---|---|
| 503fb4d246 | |||
| 2befefa752 | |||
| 85e64c5076 | |||
| 60523dc994 | |||
| 6d780bf350 | |||
| eec02a1f84 | |||
| ace2fe6fe3 | |||
| 188794af8d | |||
| 92a941a944 | |||
| 0e1ddf2b11 | |||
| b57fa010d1 | |||
| f816452b78 | |||
| 120083bb31 | |||
| a5bb5c4686 | |||
| e5e2729f0a | |||
| ba8b902f48 | |||
| 2d67815ae6 | |||
| ec0c9066d2 | |||
| 58ae858077 | |||
| 613e7938b3 | |||
| e07ff1a445 | |||
| de7dd34ea2 | |||
| 0552f695f9 | |||
| b8d4f3d946 | |||
| fa112a70b1 | |||
| 97309ebb88 | |||
| 556ddc0b6f | |||
| a0dde690ea | |||
| a76dab5be6 | |||
| 2d10bc5bbf | |||
| 4042632e0b | |||
| 7ccf83e1a4 | |||
| 019cd0756f | |||
| 0e5f9f80be | |||
| fc6767860a | |||
| 5b5b4be7b2 | |||
| 45351d082e | |||
| 22ccd07491 | |||
| 2cf9ee647b | |||
| efb567824b | |||
| f0aac39486 | |||
| f278055805 | |||
| 6f2e36fd11 | |||
| 119d80ffc8 | |||
| 771c3df864 | |||
| 7d1963e458 | |||
| dde85972b3 | |||
| 5e061da910 | |||
| 46bea345de | |||
| bc53462ad6 | |||
| 884df40a1d | |||
| b23168c067 | |||
| 5568212f15 | |||
| 79db79d799 | |||
| 18a4008efd | |||
| 83e4abd1ee | |||
| 243bcfba72 | |||
| e7f641046b | |||
| 9aaabe0fab |
+116
-2
@@ -76,6 +76,99 @@ jobs:
|
||||
paths:
|
||||
- speckle-sharp-ci-tools/Installers
|
||||
|
||||
build-connector-mac:
|
||||
macos:
|
||||
xcode: 12.5.1
|
||||
parameters:
|
||||
projname:
|
||||
type: string
|
||||
default: ""
|
||||
slug:
|
||||
type: string
|
||||
default: ""
|
||||
installer:
|
||||
type: boolean
|
||||
default: false
|
||||
converter-files:
|
||||
type: string
|
||||
default: ""
|
||||
installername:
|
||||
type: string
|
||||
default: ""
|
||||
build-config:
|
||||
type: string
|
||||
default: Release
|
||||
bundlename:
|
||||
type: string
|
||||
default: ""
|
||||
steps:
|
||||
- checkout
|
||||
- attach_workspace:
|
||||
at: ./
|
||||
- run:
|
||||
name: Install dotnet
|
||||
command: |
|
||||
curl -sSL https://dot.net/v1/dotnet-install.sh | bash /dev/stdin --channel Current
|
||||
|
||||
$HOME/.dotnet/dotnet --version
|
||||
$HOME/.dotnet/dotnet --list-runtimes
|
||||
$HOME/.dotnet/dotnet --list-sdks
|
||||
- run:
|
||||
name: Create installer target dir
|
||||
command: |
|
||||
mkdir -p speckle-sharp-ci-tools/Installers/<< parameters.slug >>
|
||||
- run:
|
||||
name: Set Environment Variable
|
||||
command: |
|
||||
TAG=$(if [ "${CIRCLE_TAG}" ]; then echo $CIRCLE_TAG; else echo "2.0.999"; fi;)
|
||||
SEMVER=$(echo "$TAG" | sed -e 's/\/[a-zA-Z-]*//')
|
||||
VER=$(echo "$SEMVER" | sed -e 's/-.*//')
|
||||
VERSION=$(echo $VER.$WORKFLOW_NUM)
|
||||
python3 patch_version.py $SEMVER
|
||||
environment:
|
||||
WORKFLOW_NUM: << pipeline.number >>
|
||||
- run:
|
||||
name: Zip Connector files
|
||||
command: |
|
||||
zip -r << parameters.slug >>-mac.zip "./speckle_connector" "./speckle_connector.rb"
|
||||
# Copy installer files
|
||||
- run:
|
||||
name: Copy files to installer
|
||||
command: |
|
||||
mkdir -p speckle-sharp-ci-tools/Mac/<< parameters.installername >>/.installationFiles/
|
||||
cp << parameters.slug >>-mac.zip speckle-sharp-ci-tools/Mac/<<parameters.installername>>/.installationFiles
|
||||
# Create installer
|
||||
- run:
|
||||
name: Exit if External PR
|
||||
command: if [ "$CIRCLE_PR_REPONAME" ]; then circleci-agent step halt; fi
|
||||
- run:
|
||||
name: Build Mac installer
|
||||
command: ~/.dotnet/dotnet publish speckle-sharp-ci-tools/Mac/<<parameters.installername>>/<<parameters.installername>>.sln -r osx-x64 -c Release
|
||||
- run:
|
||||
name: Zip installer
|
||||
command: |
|
||||
cd speckle-sharp-ci-tools/Mac/<<parameters.installername>>/bin/Release/net6.0/osx-x64/publish/
|
||||
zip -r <<parameters.slug>>.zip ./
|
||||
- store_artifacts:
|
||||
path: speckle-sharp-ci-tools/Mac/<<parameters.installername>>/bin/Release/net6.0/osx-x64/publish/<<parameters.slug>>.zip
|
||||
- run:
|
||||
name: Copy to installer location
|
||||
command: |
|
||||
TAG=$(if [ "${CIRCLE_TAG}" ]; then echo $CIRCLE_TAG; else echo "2.0.999"; fi;)
|
||||
SEMVER=$(echo "$TAG" | sed -e 's/\/[a-zA-Z-]*//')
|
||||
VER=$(echo "$SEMVER" | sed -e 's/-.*//')
|
||||
VERSION=$(echo $VER.$WORKFLOW_NUM)
|
||||
cp speckle-sharp-ci-tools/Mac/<<parameters.installername>>/bin/Release/net6.0/osx-x64/publish/<<parameters.slug>>.zip speckle-sharp-ci-tools/Installers/<< parameters.slug >>/<<parameters.slug>>-$SEMVER.zip
|
||||
environment:
|
||||
WORKFLOW_NUM: << pipeline.number >>
|
||||
- when:
|
||||
condition: << pipeline.git.tag >>
|
||||
steps:
|
||||
- persist_to_workspace:
|
||||
root: ./
|
||||
paths:
|
||||
- speckle-sharp-ci-tools/Installers
|
||||
|
||||
get-ci-tools: # Clones our ci tools and persists them to the workspace
|
||||
docker:
|
||||
- image: cimg/base:2021.01
|
||||
@@ -99,6 +192,7 @@ jobs:
|
||||
root: ./
|
||||
paths:
|
||||
- speckle-sharp-ci-tools
|
||||
|
||||
deploy-manager2:
|
||||
docker:
|
||||
- image: mcr.microsoft.com/dotnet/sdk:6.0
|
||||
@@ -146,17 +240,37 @@ workflows:
|
||||
only: /.*/
|
||||
context: innosetup
|
||||
|
||||
- build-connector-mac:
|
||||
slug: sketchup
|
||||
requires:
|
||||
- get-ci-tools
|
||||
- build-ui
|
||||
filters:
|
||||
tags:
|
||||
only: /.*/
|
||||
installername: SpeckleSketchUpInstall
|
||||
|
||||
- deploy-manager2:
|
||||
context: do-spaces-speckle-releases
|
||||
slug: sketchup
|
||||
os: Win
|
||||
extension: exe
|
||||
requires:
|
||||
- get-ci-tools
|
||||
- build-ui
|
||||
- build-connector
|
||||
filters:
|
||||
tags:
|
||||
only: /([0-9]+)\.([0-9]+)\.([0-9]+)(?:-\w+)?$/
|
||||
branches:
|
||||
ignore: /.*/ # For testing only! /ci\/.*/
|
||||
- deploy-manager2:
|
||||
context: do-spaces-speckle-releases
|
||||
slug: sketchup
|
||||
os: OSX
|
||||
extension: zip
|
||||
requires:
|
||||
- build-connector-mac
|
||||
filters:
|
||||
tags:
|
||||
only: /([0-9]+)\.([0-9]+)\.([0-9]+)(?:-\w+)?$/
|
||||
branches:
|
||||
ignore: /.*/ # For testing only! /ci\/.*/
|
||||
|
||||
@@ -111,7 +111,7 @@ module SpeckleConnector
|
||||
categories: Mapper::Category::RevitCategory.to_a,
|
||||
types: types,
|
||||
levels: levels,
|
||||
selectedLevel: selected_level_name
|
||||
selectedLevelName: selected_level_name
|
||||
}.freeze
|
||||
end
|
||||
|
||||
@@ -140,10 +140,10 @@ module SpeckleConnector
|
||||
source_exist = !state.speckle_state.speckle_mapper_state.mapper_source.nil?
|
||||
|
||||
if source_exist
|
||||
methods = ['Column', 'Beam', 'Brace', 'Pipe', 'Duct']
|
||||
methods = ['Column', 'Beam', 'Pipe', 'Duct']
|
||||
direct_shape_selection_info_with_source(state, edges, methods)
|
||||
else
|
||||
default_methods = ['Default Column', 'Default Beam', 'Default Brace', 'Default Pipe', 'Default Duct']
|
||||
default_methods = ['Default Column', 'Default Beam', 'Default Pipe', 'Default Duct']
|
||||
direct_shape_selection_info_with_default(edges, default_methods)
|
||||
end
|
||||
end
|
||||
|
||||
@@ -38,6 +38,7 @@ module SpeckleConnector
|
||||
elements = type_elements.map do |type_element|
|
||||
SpeckleObjects::BuiltElements::Revit::RevitElementType.to_native(type_element)
|
||||
end
|
||||
elements = elements.group_by { |e| e[:family] }
|
||||
[type, elements]
|
||||
end.compact.to_h
|
||||
end
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
require_relative 'action'
|
||||
require_relative '../convertors/units'
|
||||
require_relative '../convertors/to_native'
|
||||
require_relative '../convertors/clean_up'
|
||||
|
||||
module SpeckleConnector
|
||||
module Actions
|
||||
@@ -26,7 +27,12 @@ module SpeckleConnector
|
||||
converter = Converters::ToNative.new(state, @stream_id, @stream_name, @branch_name, @source_app)
|
||||
# Have side effects on the sketchup model. It effects directly on the entities by adding new objects.
|
||||
start_time = Time.now.to_f
|
||||
state.sketchup_state.sketchup_model.start_operation('Receive Speckle Objects', true)
|
||||
state = converter.receive_commit_object(@base)
|
||||
if state.user_state.model_preferences[:merge_coplanar_faces]
|
||||
Converters::CleanUp.merge_coplanar_faces(converter.converted_faces)
|
||||
end
|
||||
state.sketchup_state.sketchup_model.commit_operation
|
||||
elapsed_time = (Time.now.to_f - start_time).round(3)
|
||||
puts "==== Converting to Native executed in #{elapsed_time} sec ===="
|
||||
puts "==== Source application is #{@source_app}. ===="
|
||||
|
||||
@@ -14,7 +14,7 @@ module SpeckleConnector
|
||||
path = ENV.fetch('APPDATA')
|
||||
Pathname.new(File.join(path, 'Speckle')).cleanpath.to_s
|
||||
when OS_MAC
|
||||
File.join(Dir.home, 'Library/Application Support/Speckle')
|
||||
File.join(Dir.home, '.config/Speckle')
|
||||
else
|
||||
raise 'Speckle could not determine your Appdata path'
|
||||
end
|
||||
|
||||
@@ -4,15 +4,18 @@ module SpeckleConnector
|
||||
BASE_OBJECT = 'Base'
|
||||
|
||||
OBJECTS_GIS_POLYGONELEMENT = 'Objects.GIS.PolygonElement'
|
||||
OBJECTS_GIS_LINEELEMENT = 'Objects.GIS.LineElement'
|
||||
|
||||
OBJECTS_BUILTELEMENTS_VIEW3D = 'Objects.BuiltElements.View:Objects.BuiltElements.View3D'
|
||||
OBJECTS_BUILTELEMENTS_NETWORK = 'Objects.BuiltElements.Network'
|
||||
OBJECTS_BUILTELEMENTS_REVIT_LEVEL = 'Objects.BuiltElements.Level:Objects.BuiltElements.Revit.RevitLevel'
|
||||
OBJECTS_BUILTELEMENTS_DEFAULT_FLOOR = 'Objects.BuiltElements.Floor'
|
||||
OBJECTS_BUILTELEMENTS_FLOOR = 'Objects.BuiltElements.Floor:Objects.BuiltElements.Revit.RevitFloor'
|
||||
OBJECTS_BUILTELEMENTS_REVIT_FLOOR = 'Objects.BuiltElements.Floor:Objects.BuiltElements.Revit.RevitFloor'
|
||||
OBJECTS_BUILTELEMENTS_DEFAULT_WALL = 'Objects.BuiltElements.Wall'
|
||||
OBJECTS_BUILTELEMENTS_REVIT_WALL = 'Objects.BuiltElements.Wall:Objects.BuiltElements.Revit.RevitWall'
|
||||
OBJECTS_BUILTELEMENTS_REVIT_DIRECTSHAPE = 'Objects.BuiltElements.Revit.DirectShape'
|
||||
OBJECTS_BUILTELEMENTS_REVIT_PARAMETER = 'Objects.BuiltElements.Revit.Parameter'
|
||||
OBJECTS_BUILTELEMENTS_REVIT_REVITELEMENTTYPE = 'Objects.BuiltElements.Revit.RevitElementType'
|
||||
OBJECTS_BUILTELEMENTS_REVIT_LEVEL = 'Objects.BuiltElements.Level:Objects.BuiltElements.Revit.RevitLevel'
|
||||
|
||||
OBJECTS_GEOMETRY_LINE = 'Objects.Geometry.Line'
|
||||
OBJECTS_GEOMETRY_POLYLINE = 'Objects.Geometry.Polyline'
|
||||
@@ -31,4 +34,6 @@ module SpeckleConnector
|
||||
OBJECTS_OTHER_DISPLAYSTYLE = 'Objects.Other.DisplayStyle'
|
||||
|
||||
SPECKLE_CORE_MODELS_COLLECTION = 'Speckle.Core.Models.Collection'
|
||||
SPECKLE_CORE_MODELS_COLLECTION_RASTER_LAYER = 'Speckle.Core.Models.Collection:Objects.GIS.RasterLayer'
|
||||
SPECKLE_CORE_MODELS_COLLECTION_VECTOR_LAYER = 'Speckle.Core.Models.Collection:Objects.GIS.VectorLayer'
|
||||
end
|
||||
|
||||
@@ -11,9 +11,10 @@ module SpeckleConnector
|
||||
# @param entities [Sketchup::Entities] entities to remove edges between that make entities coplanar.
|
||||
# @note Merging coplanar faces idea originated from [CleanUp](https://github.com/thomthom/cleanup) plugin
|
||||
# which is developed by [Thomas Thomassen](https://github.com/thomthom).
|
||||
def self.merge_coplanar_faces(entities)
|
||||
def self.merge_coplanar_entities(entities)
|
||||
edges = []
|
||||
faces = entities.collect { |entity| entity if entity.is_a? Sketchup::Face }.compact
|
||||
faces = merged_faces(faces)
|
||||
faces.each { |face| face.edges.each { |edge| edges << edge } }
|
||||
edges.uniq!
|
||||
edges.each { |edge| remove_edge_have_coplanar_faces(edge, faces, false) }
|
||||
@@ -22,6 +23,22 @@ module SpeckleConnector
|
||||
merged_faces(faces)
|
||||
end
|
||||
|
||||
def self.merge_coplanar_faces(faces)
|
||||
edges = []
|
||||
faces = faces.reject(&:deleted?)
|
||||
|
||||
faces.each { |face| face.edges.each { |edge| edges << edge } }
|
||||
|
||||
edges.uniq!
|
||||
|
||||
edges.each { |edge| remove_edge_have_coplanar_faces(edge) }
|
||||
|
||||
# Remove remaining orphan edges
|
||||
# edges.reject(&:deleted?).select { |edge| edge.faces.empty? }.each(&:erase!)
|
||||
|
||||
merged_faces(faces)
|
||||
end
|
||||
|
||||
def self.merged_faces(faces)
|
||||
faces.reject(&:deleted?)
|
||||
end
|
||||
@@ -35,43 +52,34 @@ module SpeckleConnector
|
||||
# - Whether UV texture map is aligned between faces or not.
|
||||
# - Finally, if faces are coplanar by correcting these checks, then removes edge from Sketchup.active_model.
|
||||
# @param edge [Sketchup::Edge] edge to check.
|
||||
# @param faces [Array<Sketchup::Face>] scoped faces to check 'edge.faces' both (first and second)
|
||||
# belongs to this faces or not. If any of this faces does not involve this scoped faces, then do not delete.
|
||||
# @param ignore_materials [Boolean] whether ignore materials or not.
|
||||
# Returns true if the given edge separating two coplanar faces.
|
||||
# Return false otherwise.
|
||||
# rubocop:disable Metrics/AbcSize
|
||||
def self.remove_edge_have_coplanar_faces(edge, faces, ignore_materials)
|
||||
def self.remove_edge_have_coplanar_faces(edge)
|
||||
return false unless edge.valid? && edge.is_a?(Sketchup::Edge)
|
||||
return false unless edge.faces.size == 2
|
||||
|
||||
# Check scoped faces have this edges
|
||||
if edge.faces.size == 2
|
||||
is_first = faces.include?(edge.faces[0])
|
||||
is_second = faces.include?(edge.faces[1])
|
||||
return false unless is_first && is_second
|
||||
end
|
||||
|
||||
face_1, face_2 = edge.faces
|
||||
|
||||
return false if face_duplicate?(face_1, face_2)
|
||||
# Check for troublesome faces which might lead to missing geometry if merged.
|
||||
return false unless edge_safe_to_merge?(edge)
|
||||
begin
|
||||
return false unless face_1.normal.samedirection?(face_2.normal)
|
||||
|
||||
return false if face_duplicate?(face_1, face_2)
|
||||
# Check for troublesome faces which might lead to missing geometry if merged.
|
||||
return false unless edge_safe_to_merge?(edge)
|
||||
|
||||
# Check materials match.
|
||||
unless ignore_materials
|
||||
return false unless (face_1.material == face_2.material) && (face_1.back_material == face_2.back_material)
|
||||
|
||||
# Verify UV mapping match.
|
||||
return false if !face_1.material.nil? && !continuous_uv?(face_1, face_2, edge) && face_1.material.texture.nil?
|
||||
end
|
||||
# Check faces are coplanar or not.
|
||||
return false unless faces_coplanar?(face_1, face_2)
|
||||
# Check faces are coplanar or not.
|
||||
return false unless faces_coplanar?(face_1, face_2)
|
||||
|
||||
edge.erase!
|
||||
true
|
||||
edge.erase!
|
||||
true
|
||||
rescue StandardError => e
|
||||
puts "Failed to merge coplanar faces by removing edge with error: #{e}"
|
||||
false
|
||||
end
|
||||
end
|
||||
# rubocop:enable Metrics/AbcSize
|
||||
|
||||
# Determines if two faces are overlapped.
|
||||
def self.face_duplicate?(face_1, face_2, overlapping: false)
|
||||
|
||||
@@ -4,6 +4,7 @@ require_relative 'converter'
|
||||
require_relative '../constants/type_constants'
|
||||
require_relative '../speckle_entities/speckle_entity'
|
||||
require_relative '../speckle_objects/gis/polygon_element'
|
||||
require_relative '../speckle_objects/gis/line_element'
|
||||
require_relative '../speckle_objects/other/transform'
|
||||
require_relative '../speckle_objects/other/render_material'
|
||||
require_relative '../speckle_objects/other/block_definition'
|
||||
@@ -19,6 +20,7 @@ require_relative '../speckle_objects/geometry/mesh'
|
||||
require_relative '../speckle_objects/built_elements/view3d'
|
||||
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 '../sketchup_model/dictionary/speckle_entity_dictionary_handler'
|
||||
|
||||
module SpeckleConnector
|
||||
@@ -32,11 +34,14 @@ module SpeckleConnector
|
||||
# @return [String] source application of received object that will be converted to native
|
||||
attr_reader :source_app
|
||||
|
||||
attr_reader :converted_faces
|
||||
|
||||
def initialize(state, stream_id, stream_name, branch_name, source_app)
|
||||
super(state, stream_id)
|
||||
@stream_name = stream_name
|
||||
@branch_name = branch_name
|
||||
@source_app = source_app.downcase
|
||||
@converted_faces = []
|
||||
end
|
||||
|
||||
# Module aliases
|
||||
@@ -56,11 +61,14 @@ module SpeckleConnector
|
||||
BLOCK_DEFINITION = OTHER::BlockDefinition
|
||||
BLOCK_INSTANCE = OTHER::BlockInstance
|
||||
REVIT_INSTANCE = REVIT::Other::RevitInstance
|
||||
REVIT_WALL = BUILTELEMENTS::RevitWall
|
||||
RENDER_MATERIAL = OTHER::RenderMaterial
|
||||
DISPLAY_VALUE = OTHER::DisplayValue
|
||||
VIEW3D = BUILTELEMENTS::View3d
|
||||
POLYGON_ELEMENT = GIS::PolygonElement
|
||||
LINE_ELEMENT = GIS::LineElement
|
||||
COLLECTION = SpeckleObjects::Speckle::Core::Models::Collection
|
||||
GIS_LAYER_COLLECTION = SpeckleObjects::Speckle::Core::Models::GisLayerCollection
|
||||
|
||||
BASE_OBJECT_PROPS = %w[applicationId id speckle_type totalChildrenCount].freeze
|
||||
CONVERTABLE_SPECKLE_TYPES = %w[
|
||||
@@ -77,9 +85,13 @@ module SpeckleConnector
|
||||
Objects.Other.RenderMaterial
|
||||
Objects.Other.Instance:Objects.Other.BlockInstance
|
||||
Objects.BuiltElements.View:Objects.BuiltElements.View3D
|
||||
Objects.BuiltElements.Wall:Objects.BuiltElements.Revit.RevitWall
|
||||
Objects.BuiltElements.Network
|
||||
Objects.GIS.PolygonElement
|
||||
Objects.GIS.LineElement
|
||||
Speckle.Core.Models.Collection
|
||||
Speckle.Core.Models.Collection:Objects.GIS.RasterLayer
|
||||
Speckle.Core.Models.Collection:Objects.GIS.VectorLayer
|
||||
].freeze
|
||||
|
||||
def from_revit
|
||||
@@ -294,10 +306,14 @@ module SpeckleConnector
|
||||
OBJECTS_OTHER_REVIT_REVITINSTANCE => REVIT_INSTANCE.method(:to_native),
|
||||
OBJECTS_OTHER_RENDERMATERIAL => RENDER_MATERIAL.method(:to_native),
|
||||
OBJECTS_BUILTELEMENTS_VIEW3D => VIEW3D.method(:to_native),
|
||||
OBJECTS_BUILTELEMENTS_REVIT_WALL => REVIT_WALL.method(:to_native),
|
||||
OBJECTS_BUILTELEMENTS_REVIT_DIRECTSHAPE => BUILTELEMENTS::Revit::DirectShape.method(:to_native),
|
||||
OBJECTS_BUILTELEMENTS_NETWORK => BUILTELEMENTS::Network.method(:to_native),
|
||||
OBJECTS_GIS_POLYGONELEMENT => POLYGON_ELEMENT.method(:to_native),
|
||||
SPECKLE_CORE_MODELS_COLLECTION => COLLECTION.method(:to_native)
|
||||
OBJECTS_GIS_LINEELEMENT => LINE_ELEMENT.method(:to_native),
|
||||
SPECKLE_CORE_MODELS_COLLECTION => COLLECTION.method(:to_native),
|
||||
SPECKLE_CORE_MODELS_COLLECTION_RASTER_LAYER => GIS_LAYER_COLLECTION.method(:to_native),
|
||||
SPECKLE_CORE_MODELS_COLLECTION_VECTOR_LAYER => GIS_LAYER_COLLECTION.method(:to_native)
|
||||
}.freeze
|
||||
|
||||
# @param state [States::State] state of the speckle application
|
||||
@@ -309,6 +325,8 @@ module SpeckleConnector
|
||||
# Call 'to_native' method by passing this method itself to handle nested 'to_native' conversions.
|
||||
# It returns updated state and converted entities.
|
||||
state, converted_entities = to_native_method.call(state, obj, layer, entities, &convert_to_native)
|
||||
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)
|
||||
|
||||
BIN
Binary file not shown.
@@ -1,7 +1,9 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require_relative '../speckle_objects/built_elements/floor'
|
||||
require_relative '../speckle_objects/built_elements/revit/revit_floor'
|
||||
require_relative '../speckle_objects/built_elements/revit/revit_wall'
|
||||
require_relative '../speckle_objects/built_elements/default_floor'
|
||||
require_relative '../speckle_objects/built_elements/default_wall'
|
||||
require_relative '../sketchup_model/query/entity'
|
||||
require_relative '../sketchup_model/reader/mapper_reader'
|
||||
require_relative '../sketchup_model/dictionary/speckle_schema_dictionary_handler'
|
||||
@@ -39,7 +41,17 @@ module SpeckleConnector
|
||||
end
|
||||
|
||||
if speckle_schema['method'] == 'Floor'
|
||||
return SpeckleObjects::BuiltElements::Floor
|
||||
return SpeckleObjects::BuiltElements::RevitFloor
|
||||
.to_speckle_schema(speckle_state, entity, units, global_transformation: global_transformation)
|
||||
end
|
||||
|
||||
if speckle_schema['method'] == 'Default Wall'
|
||||
return SpeckleObjects::BuiltElements::DefaultWall
|
||||
.to_speckle_schema(entity, units, global_transformation: global_transformation)
|
||||
end
|
||||
|
||||
if speckle_schema['method'] == 'Wall'
|
||||
return SpeckleObjects::BuiltElements::RevitWall
|
||||
.to_speckle_schema(speckle_state, entity, units, global_transformation: global_transformation)
|
||||
end
|
||||
|
||||
|
||||
@@ -12,9 +12,9 @@ module SpeckleConnector
|
||||
include Immutable::ImmutableUtils
|
||||
DICT_HANDLER = SketchupModel::Dictionary::SpeckleModelDictionaryHandler
|
||||
# rubocop:disable Layout/LineLength
|
||||
DEFAULT_CONFIG = "('configSketchup', '{\"dark_theme\":false, \"diffing\":false, \"register_speckle_entity\":false}');"
|
||||
DEFAULT_CONFIG = "('configSketchup', '{\"dark_theme\":false, \"diffing\":false, \"register_speckle_entity\":false, \"fe2\":false}');"
|
||||
# rubocop:enable Layout/LineLength
|
||||
DEFAULT_PREFERENCES = '{"dark_theme":false, "diffing":false, "register_speckle_entity": false}'
|
||||
DEFAULT_PREFERENCES = '{"dark_theme":false, "diffing":false, "register_speckle_entity": false, "fe2": false}'
|
||||
|
||||
# @param sketchup_model [Sketchup::Model] active model.
|
||||
def self.read_preferences(sketchup_model)
|
||||
@@ -34,10 +34,16 @@ module SpeckleConnector
|
||||
def self.data_complete?(row_data)
|
||||
return false if row_data.empty?
|
||||
|
||||
data = JSON.parse(row_data.first.first)
|
||||
return false if data['dark_theme'].nil? || data['diffing'].nil? || data['register_speckle_entity'].nil?
|
||||
begin
|
||||
data = JSON.parse(row_data.first.first)
|
||||
if data['dark_theme'].nil? || data['fe2'].nil? || data['diffing'].nil? || data['register_speckle_entity'].nil?
|
||||
return false
|
||||
end
|
||||
|
||||
true
|
||||
true
|
||||
rescue StandardError
|
||||
false
|
||||
end
|
||||
end
|
||||
|
||||
# Validates current preferences. If there are incomplete data then this method resets it with default preferences.
|
||||
@@ -65,11 +71,13 @@ module SpeckleConnector
|
||||
data_hash = JSON.parse(row_data).to_h
|
||||
# Get current theme value
|
||||
dark_theme = data_hash['dark_theme']
|
||||
fe2 = data_hash['fe2']
|
||||
diffing = data_hash['diffing']
|
||||
register_speckle_entity = data_hash['register_speckle_entity']
|
||||
|
||||
{
|
||||
dark_theme: dark_theme,
|
||||
fe2: fe2,
|
||||
diffing: diffing,
|
||||
register_speckle_entity: register_speckle_entity
|
||||
}.freeze
|
||||
|
||||
@@ -27,14 +27,11 @@ module SpeckleConnector
|
||||
adj_faces.uniq
|
||||
end
|
||||
|
||||
# @param face [Sketchup::Face] face to check whether is vertical or not.
|
||||
def self.vertical?(face)
|
||||
face.normal.perpendicular?(VECTOR_Z)
|
||||
end
|
||||
|
||||
# @param face [Sketchup::Face] face to check whether is horizontal or not.
|
||||
def self.horizontal?(face)
|
||||
face.normal.parallel?(VECTOR_Z)
|
||||
# @param face [Sketchup::Face] face to get max z distance for all vertices.
|
||||
def self.max_z(face)
|
||||
points = face.vertices.collect(&:position)
|
||||
points_z_values = points.collect(&:z)
|
||||
points_z_values.max - points_z_values.min
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -136,6 +136,15 @@ module SpeckleConnector
|
||||
next if (entity.is_a?(Sketchup::Face) || entity.is_a?(Sketchup::Edge)) &&
|
||||
!state.user_state.user_preferences[:register_speckle_entity]
|
||||
|
||||
if entity.is_a?(Sketchup::ComponentDefinition)
|
||||
definition = speckle_object['definition'] || speckle_object['@block_definition'] ||
|
||||
speckle_object['block_definition']
|
||||
if definition
|
||||
speckle_id = definition['id']
|
||||
speckle_type = definition['speckle_type']
|
||||
end
|
||||
end
|
||||
|
||||
ent = SpeckleEntity.new(entity, speckle_id, application_id, speckle_type, children, [stream_id])
|
||||
ent.write_initial_base_data
|
||||
speckle_state = speckle_state.with_speckle_entity(ent)
|
||||
|
||||
@@ -0,0 +1,52 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require_relative '../base'
|
||||
require_relative '../built_elements/revit/parameter'
|
||||
require_relative '../other/render_material'
|
||||
require_relative '../geometry/length'
|
||||
require_relative '../geometry/line'
|
||||
require_relative '../geometry/polyline'
|
||||
require_relative '../../constants/type_constants'
|
||||
require_relative '../../sketchup_model/dictionary/speckle_schema_dictionary_handler'
|
||||
require_relative '../../sketchup_model/utils/face_utils'
|
||||
|
||||
module SpeckleConnector
|
||||
module SpeckleObjects
|
||||
module BuiltElements
|
||||
# Default Wall object.
|
||||
class DefaultWall < Base
|
||||
SPECKLE_TYPE = OBJECTS_BUILTELEMENTS_DEFAULT_WALL
|
||||
|
||||
def initialize(base_line:, height:, flipped:, units:, material:, application_id: nil)
|
||||
super(
|
||||
speckle_type: SPECKLE_TYPE,
|
||||
total_children_count: 0,
|
||||
application_id: application_id,
|
||||
id: nil
|
||||
)
|
||||
self[:baseLine] = base_line
|
||||
self[:height] = height
|
||||
self[:flipped] = flipped
|
||||
self[:units] = units
|
||||
self[:renderMaterial] = material
|
||||
end
|
||||
|
||||
# @param face [Sketchup::Face] face to get speckle schema for floor.
|
||||
def self.to_speckle_schema(face, units, global_transformation: nil)
|
||||
base_line = Geometry::Line.base_line_from_face(face, units, global_transformation: global_transformation)
|
||||
|
||||
material = face.material || face.back_material
|
||||
|
||||
DefaultWall.new(
|
||||
base_line: base_line,
|
||||
height: Geometry.length_to_speckle(SketchupModel::Utils::FaceUtils.max_z(face), units),
|
||||
flipped: false,
|
||||
units: units,
|
||||
material: material.nil? ? nil : Other::RenderMaterial.from_material(face.material || face.back_material),
|
||||
application_id: face.persistent_id
|
||||
)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
+13
-11
@@ -1,20 +1,21 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require_relative '../base'
|
||||
require_relative '../built_elements/revit/parameter'
|
||||
require_relative '../other/render_material'
|
||||
require_relative '../geometry/line'
|
||||
require_relative '../geometry/polyline'
|
||||
require_relative '../../constants/type_constants'
|
||||
require_relative '../../sketchup_model/dictionary/speckle_schema_dictionary_handler'
|
||||
require_relative '../../base'
|
||||
require_relative '../../built_elements/revit/parameter'
|
||||
require_relative '../../other/render_material'
|
||||
require_relative '../../geometry/line'
|
||||
require_relative '../../geometry/polyline'
|
||||
require_relative '../../../constants/type_constants'
|
||||
require_relative '../../../sketchup_model/dictionary/speckle_schema_dictionary_handler'
|
||||
|
||||
module SpeckleConnector
|
||||
module SpeckleObjects
|
||||
module BuiltElements
|
||||
# Floor object.
|
||||
class Floor < Base
|
||||
SPECKLE_TYPE = OBJECTS_BUILTELEMENTS_FLOOR
|
||||
# Revit floor object.
|
||||
class RevitFloor < Base
|
||||
SPECKLE_TYPE = OBJECTS_BUILTELEMENTS_REVIT_FLOOR
|
||||
|
||||
# rubocop:disable Metrics/ParameterLists
|
||||
def initialize(family:, type:, outline:, voids:, level:, units:, material:, parameters:nil, application_id: nil)
|
||||
super(
|
||||
speckle_type: SPECKLE_TYPE,
|
||||
@@ -31,6 +32,7 @@ module SpeckleConnector
|
||||
self[:parameters] = parameters
|
||||
self[:renderMaterial] = material
|
||||
end
|
||||
# rubocop:enable Metrics/ParameterLists
|
||||
|
||||
# @param face [Sketchup::Face] face to get speckle schema for floor.
|
||||
def self.to_speckle_schema(speckle_state, face, units, global_transformation: nil)
|
||||
@@ -57,7 +59,7 @@ module SpeckleConnector
|
||||
parameters['Height Offset From Level'] = offset_parameter
|
||||
end
|
||||
|
||||
Floor.new(
|
||||
RevitFloor.new(
|
||||
family: schema['family'],
|
||||
type: schema['family_type'],
|
||||
outline: outline,
|
||||
@@ -0,0 +1,102 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require_relative '../../base'
|
||||
require_relative '../../built_elements/revit/parameter'
|
||||
require_relative '../../other/render_material'
|
||||
require_relative '../../geometry/line'
|
||||
require_relative '../../geometry/length'
|
||||
require_relative '../../../constants/type_constants'
|
||||
require_relative '../../../sketchup_model/dictionary/speckle_schema_dictionary_handler'
|
||||
require_relative '../../../sketchup_model/utils/face_utils'
|
||||
|
||||
module SpeckleConnector
|
||||
module SpeckleObjects
|
||||
module BuiltElements
|
||||
# Revit wall object.
|
||||
class RevitWall < Base
|
||||
SPECKLE_TYPE = OBJECTS_BUILTELEMENTS_REVIT_WALL
|
||||
|
||||
# rubocop:disable Metrics/ParameterLists
|
||||
def initialize(family:, type:, base_line:, height:, flipped:, level:, units:, material:, parameters: nil, application_id: nil)
|
||||
super(
|
||||
speckle_type: SPECKLE_TYPE,
|
||||
total_children_count: 0,
|
||||
application_id: application_id,
|
||||
id: nil
|
||||
)
|
||||
self[:family] = family
|
||||
self[:type] = type
|
||||
self[:height] = height
|
||||
self[:flipped] = flipped
|
||||
self[:level] = level
|
||||
self[:baseLine] = base_line
|
||||
self[:units] = units
|
||||
self[:parameters] = parameters
|
||||
self[:renderMaterial] = material
|
||||
end
|
||||
# rubocop:enable Metrics/ParameterLists
|
||||
|
||||
def self.to_native(state, wall, layer, entities, &convert_to_native)
|
||||
obj = Other::DisplayValue.collect_definition_geometries(wall)
|
||||
obj['name'] = Other::DisplayValue.get_definition_name(obj)
|
||||
|
||||
state, _definitions = Other::BlockDefinition.to_native(
|
||||
state, obj, layer, entities, &convert_to_native
|
||||
)
|
||||
|
||||
definition = state.sketchup_state.sketchup_model.definitions[Other::BlockDefinition.get_definition_name(obj)]
|
||||
|
||||
Other::BlockInstance.find_and_erase_existing_instance(definition, obj['id'], obj['applicationId'])
|
||||
t_arr = obj['transform']
|
||||
transform = t_arr.nil? ? Geom::Transformation.new : Other::Transform.to_native(t_arr, obj['units'])
|
||||
instance = entities.add_instance(definition, transform)
|
||||
instance.name = Other::DisplayValue.get_instance_name(obj['name']) unless obj['name'].nil?
|
||||
instance.layer = layer unless layer.nil?
|
||||
# Align instance axes that created from display value. (without any transform)
|
||||
# BlockInstance.align_instance_axes(instance)
|
||||
return state, [instance, definition]
|
||||
end
|
||||
|
||||
# @param face [Sketchup::Face] face to get speckle schema for wall.
|
||||
def self.to_speckle_schema(speckle_state, face, units, global_transformation: nil)
|
||||
base_line = Geometry::Line.base_line_from_face(face, units, global_transformation: global_transformation)
|
||||
|
||||
material = face.material || face.back_material
|
||||
schema = SketchupModel::Dictionary::SpeckleSchemaDictionaryHandler.speckle_schema_to_speckle(face).to_h
|
||||
source_exist = !speckle_state.speckle_mapper_state.mapper_source.nil?
|
||||
level = nil
|
||||
parameters = nil
|
||||
if source_exist
|
||||
level = speckle_state.speckle_mapper_state.mapper_source.levels.find { |l| l[:name] == schema['level'] }
|
||||
parameters = Base.new
|
||||
offset_parameter = BuiltElements::Revit::Parameter.new(name: 'Height Offset From Level')
|
||||
level_z = Geometry.length_to_native(level[:elevation], level[:units])
|
||||
min_z = face.vertices.collect(&:position).map(&:z).min
|
||||
offset_parameter['value'] = Geometry.length_to_speckle(min_z - level_z, units)
|
||||
offset_parameter['units'] = units
|
||||
parameters['Height Offset From Level'] = offset_parameter
|
||||
end
|
||||
|
||||
RevitWall.new(
|
||||
family: schema['family'],
|
||||
type: schema['family_type'],
|
||||
base_line: base_line,
|
||||
height: Geometry.length_to_speckle(SketchupModel::Utils::FaceUtils.max_z(face), units),
|
||||
flipped: false,
|
||||
level: level,
|
||||
units: units,
|
||||
parameters: parameters,
|
||||
material: material.nil? ? nil : Other::RenderMaterial.from_material(face.material || face.back_material),
|
||||
application_id: face.persistent_id
|
||||
)
|
||||
end
|
||||
|
||||
def self.get_wall_height(face, units)
|
||||
points = face.vertices.collect(&:position)
|
||||
points_z_values = points.collect(&:z)
|
||||
Geometry.length_to_speckle(points_z_values.max - points_z_values.min, units)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -11,6 +11,10 @@ module SpeckleConnector
|
||||
end
|
||||
|
||||
def self.length_to_native(length, units)
|
||||
if units == 'none'
|
||||
units = SpeckleConnector::Converters::
|
||||
SKETCHUP_UNITS[Sketchup.active_model.options['UnitsOptions']['LengthUnit']]
|
||||
end
|
||||
length.__send__(SpeckleConnector::Converters::SKETCHUP_UNIT_STRINGS[units])
|
||||
end
|
||||
end
|
||||
|
||||
@@ -40,7 +40,7 @@ module SpeckleConnector
|
||||
# rubocop:enable Metrics/ParameterLists
|
||||
|
||||
# @param edge [Sketchup::Edge] edge to convert line.
|
||||
def self.from_edge(edge, units, model_preferences)
|
||||
def self.from_edge(edge, units, model_preferences, global_transformation: nil)
|
||||
dictionaries = SketchupModel::Dictionary::BaseDictionaryHandler
|
||||
.attribute_dictionaries_to_speckle(edge, model_preferences)
|
||||
att = dictionaries.any? ? { dictionaries: dictionaries } : {}
|
||||
@@ -60,6 +60,41 @@ module SpeckleConnector
|
||||
)
|
||||
end
|
||||
|
||||
# @param edge [Sketchup::Face] face to get base line from face.
|
||||
def self.base_line_from_face(face, units, global_transformation: nil)
|
||||
points = face.vertices.collect(&:position)
|
||||
points_z_values = points.collect(&:z)
|
||||
height = Geometry.length_to_speckle(points_z_values.max - points_z_values.min, units)
|
||||
min_z = points_z_values.min
|
||||
projected_points = points.map { |p| Geom::Point3d.new(p.x, p.y, min_z) }
|
||||
distance_with_points = Struct.new(:distance, :point_1, :point_2)
|
||||
lines_with_distances = []
|
||||
projected_points.each do |p|
|
||||
projected_points.each do |p_other|
|
||||
next if p_other == p
|
||||
|
||||
lines_with_distances.append(distance_with_points.new(p.distance(p_other), p, p_other))
|
||||
end
|
||||
end
|
||||
lines_with_distances.sort_by!(&:distance).reverse!
|
||||
p_1 = lines_with_distances.first.point_1
|
||||
p_2 = lines_with_distances.first.point_2
|
||||
unless global_transformation.nil?
|
||||
p_1 = p_1.transform!(global_transformation)
|
||||
p_2 = p_2.transform!(global_transformation)
|
||||
end
|
||||
Line.new(
|
||||
start_pt: Geometry::Point.from_vertex(p_1, units),
|
||||
end_pt: Geometry::Point.from_vertex(p_2, units),
|
||||
domain: Primitive::Interval.from_numeric(0, Geometry.length_to_speckle(p_1.distance(p_2), units), units),
|
||||
units: units,
|
||||
layer: SketchupModel::Query::Layer.entity_path(face),
|
||||
sketchup_attributes: {},
|
||||
speckle_schema: {},
|
||||
application_id: face.persistent_id.to_s
|
||||
)
|
||||
end
|
||||
|
||||
# @param state [States::State] state of the application.
|
||||
# @param line [Object] object represents Speckle line.
|
||||
# @param layer [Sketchup::Layer] layer to add {Sketchup::Edge} into it.
|
||||
|
||||
@@ -121,9 +121,9 @@ module SpeckleConnector
|
||||
mesh_layer_name = SketchupModel::Query::Layer.entity_layer_from_path(mesh['layer'])
|
||||
mesh_layer = state.sketchup_state.sketchup_model.layers.to_a.find { |l| l.display_name == mesh_layer_name }
|
||||
# Merge only added faces in this scope
|
||||
if model_preferences[:merge_coplanar_faces]
|
||||
added_faces = Converters::CleanUp.merge_coplanar_faces(added_faces)
|
||||
end
|
||||
# if model_preferences[:merge_coplanar_faces]
|
||||
# added_faces = Converters::CleanUp.merge_coplanar_faces(added_faces)
|
||||
# end
|
||||
added_faces.each do |face|
|
||||
face.layer = mesh_layer unless mesh_layer.nil?
|
||||
# Smooth edges if they already soft
|
||||
|
||||
@@ -0,0 +1,207 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module SpeckleConnector
|
||||
module SpeckleObjects
|
||||
module Geometry
|
||||
module Units
|
||||
MILLIMETERS = 'mm'
|
||||
CENTIMETERS = 'cm'
|
||||
METERS = 'm'
|
||||
KILOMETERS = 'km'
|
||||
INCHES = 'in'
|
||||
FEET = 'ft'
|
||||
YARDS = 'yd'
|
||||
MILES = 'mi'
|
||||
NONE = 'none'
|
||||
|
||||
# USInches = "us_in" the smelliest ones, can add later if people scream "USA #1"
|
||||
USFEET = 'us_ft' # it happened, absolutely gross
|
||||
|
||||
SUPPORTED_UNITS = [MILLIMETERS, CENTIMETERS, METERS, KILOMETERS,
|
||||
INCHES, FEET, USFEET, YARDS, MILES, NONE].freeze
|
||||
|
||||
CONVERSION_TABLE = {
|
||||
MILLIMETERS => {
|
||||
CENTIMETERS => 0.1,
|
||||
METERS => 0.001,
|
||||
KILOMETERS => 1e-6,
|
||||
INCHES => 0.0393701,
|
||||
FEET => 0.00328084,
|
||||
USFEET => 0.0032808333,
|
||||
YARDS => 0.00109361,
|
||||
MILES => 6.21371e-7
|
||||
},
|
||||
CENTIMETERS => {
|
||||
MILLIMETERS => 10,
|
||||
METERS => 0.01,
|
||||
KILOMETERS => 1e-5,
|
||||
INCHES => 0.393701,
|
||||
FEET => 0.0328084,
|
||||
USFEET => 0.0328083333,
|
||||
YARDS => 0.0109361,
|
||||
MILES => 6.21371e-6
|
||||
},
|
||||
METERS => {
|
||||
MILLIMETERS => 1000,
|
||||
CENTIMETERS => 100,
|
||||
KILOMETERS => 0.001,
|
||||
INCHES => 39.3701,
|
||||
FEET => 3.28084,
|
||||
USFEET => 3.28083333,
|
||||
YARDS => 1.09361,
|
||||
MILES => 0.000621371
|
||||
},
|
||||
KILOMETERS => {
|
||||
MILLIMETERS => 1e6,
|
||||
CENTIMETERS => 100000,
|
||||
METERS => 1000,
|
||||
INCHES => 39370.1,
|
||||
FEET => 3280.84,
|
||||
USFEET => 3280.83333,
|
||||
YARDS => 1093.61,
|
||||
MILES => 0.621371
|
||||
},
|
||||
INCHES => {
|
||||
MILLIMETERS => 25.4,
|
||||
CENTIMETERS => 2.54,
|
||||
METERS => 0.0254,
|
||||
KILOMETERS => 2.54e-5,
|
||||
FEET => 0.0833333,
|
||||
USFEET => 0.0833331667,
|
||||
YARDS => 0.027777694,
|
||||
MILES => 1.57828e-5
|
||||
},
|
||||
FEET => {
|
||||
MILLIMETERS => 304.8,
|
||||
CENTIMETERS => 30.48,
|
||||
METERS => 0.3048,
|
||||
KILOMETERS => 0.0003048,
|
||||
INCHES => 12,
|
||||
USFEET => 0.999998,
|
||||
YARDS => 0.333332328,
|
||||
MILES => 0.000189394
|
||||
},
|
||||
USFEET => {
|
||||
MILLIMETERS => 120000.0 / 3937.0,
|
||||
CENTIMETERS => 12000.0 / 3937.0,
|
||||
METERS => 1200.0 / 3937.0,
|
||||
KILOMETERS => 1.2 / 3937.0,
|
||||
INCHES => 12.000024,
|
||||
FEET => 1.000002,
|
||||
YARDS => 1.000002 / 3.0,
|
||||
MILES => 1.000002 / 5280.0
|
||||
},
|
||||
YARDS => {
|
||||
MILLIMETERS => 914.4,
|
||||
CENTIMETERS => 91.44,
|
||||
METERS => 0.9144,
|
||||
KILOMETERS => 0.0009144,
|
||||
INCHES => 36,
|
||||
FEET => 3,
|
||||
USFEET => 2.999994,
|
||||
MILES => 1.0 / 1760.0
|
||||
},
|
||||
MILES => {
|
||||
MILLIMETERS => 1.609e6,
|
||||
CENTIMETERS => 160934,
|
||||
METERS => 1609.34,
|
||||
KILOMETERS => 1.60934,
|
||||
INCHES => 63360,
|
||||
FEET => 5280,
|
||||
USFEET => 5279.98944002112,
|
||||
YARDS => 1759.99469184
|
||||
},
|
||||
NONE => { NONE => 1 }
|
||||
}.freeze
|
||||
|
||||
def self.unit_supported?(unit)
|
||||
SUPPORTED_UNITS.include?(unit)
|
||||
end
|
||||
|
||||
# USYards = "us_yd" the smelliest ones, can add later if people scream "USA #1"
|
||||
# USMiles = "us_mi" the smelliest ones, can add later if people scream "USA #1"
|
||||
|
||||
def self.get_conversion_factor(from, to)
|
||||
from = get_units_from_string(from)
|
||||
to = get_units_from_string(to)
|
||||
CONVERSION_TABLE[from][to] || 1
|
||||
end
|
||||
|
||||
def self.get_units_from_string(unit)
|
||||
return nil if unit.nil?
|
||||
|
||||
case unit.downcase
|
||||
when 'mm', 'mil', 'millimeter', 'millimeters', 'millimetres'
|
||||
MILLIMETERS
|
||||
when 'cm', 'centimetre', 'centimeter', 'centimetres', 'centimeters'
|
||||
CENTIMETERS
|
||||
when 'm', 'meter', 'metre', 'meters', 'metres'
|
||||
METERS
|
||||
when 'inches', 'inch', 'in'
|
||||
INCHES
|
||||
when 'feet', 'foot', 'ft'
|
||||
FEET
|
||||
when 'ussurveyfeet'
|
||||
USFEET
|
||||
when 'yard', 'yards', 'yd'
|
||||
YARDS
|
||||
when 'miles', 'mile', 'mi'
|
||||
MILES
|
||||
when 'kilometers', 'kilometer', 'km'
|
||||
KILOMETERS
|
||||
when 'none'
|
||||
NONE
|
||||
else
|
||||
raise "Cannot understand what unit #{unit} is."
|
||||
end
|
||||
end
|
||||
|
||||
def self.get_encoding_from_unit(unit)
|
||||
case unit
|
||||
when MILLIMETERS
|
||||
1
|
||||
when CENTIMETERS
|
||||
2
|
||||
when METERS
|
||||
3
|
||||
when KILOMETERS
|
||||
4
|
||||
when INCHES
|
||||
5
|
||||
when FEET
|
||||
6
|
||||
when YARDS
|
||||
7
|
||||
when MILES
|
||||
8
|
||||
else
|
||||
0
|
||||
end
|
||||
end
|
||||
|
||||
def self.get_unit_from_encoding(unit)
|
||||
case unit
|
||||
when 1
|
||||
MILLIMETERS
|
||||
when 2
|
||||
CENTIMETERS
|
||||
when 3
|
||||
METERS
|
||||
when 4
|
||||
KILOMETERS
|
||||
when 5
|
||||
INCHES
|
||||
when 6
|
||||
FEET
|
||||
when 7
|
||||
YARDS
|
||||
when 8
|
||||
MILES
|
||||
else
|
||||
NONE
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,68 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require_relative 'utils'
|
||||
require_relative '../base'
|
||||
require_relative '../other/transform'
|
||||
require_relative '../other/block_definition'
|
||||
require_relative '../other/block_instance'
|
||||
require_relative '../../constants/type_constants'
|
||||
require_relative '../../sketchup_model/dictionary/dictionary_handler'
|
||||
|
||||
module SpeckleConnector
|
||||
module SpeckleObjects
|
||||
module GIS
|
||||
# Line element in GIS tools.
|
||||
class LineElement < Base
|
||||
SPECKLE_TYPE = OBJECTS_GIS_LINEELEMENT
|
||||
|
||||
# Handles polygon element differently from display value.
|
||||
def self.to_native(state, obj, layer, entities, &convert_to_native)
|
||||
attributes = GIS.get_qgis_attributes(obj)
|
||||
obj = collect_definition_geometries(obj)
|
||||
obj['name'] = GIS.get_definition_name(obj, attributes)
|
||||
|
||||
state, _definitions = Other::BlockDefinition.to_native(
|
||||
state, obj, layer, entities, &convert_to_native
|
||||
)
|
||||
|
||||
definition = state.sketchup_state.sketchup_model
|
||||
.definitions[Other::BlockDefinition.get_definition_name(obj)]
|
||||
|
||||
Other::BlockInstance.find_and_erase_existing_instance(definition, obj['id'], obj['applicationId'])
|
||||
t_arr = obj['transform']
|
||||
transform = t_arr.nil? ? Geom::Transformation.new : Other::Transform.to_native(t_arr, obj['units'])
|
||||
instance = entities.add_instance(definition, transform)
|
||||
instance.name = obj['name'] unless obj['name'].nil?
|
||||
SketchupModel::Dictionary::DictionaryHandler.set_hash(instance, attributes, 'qgis')
|
||||
SketchupModel::Dictionary::DictionaryHandler.set_hash(definition, attributes, 'qgis')
|
||||
# Align instance axes that created from display value. (without any transform)
|
||||
Other::BlockInstance.align_instance_axes(instance)
|
||||
return state, [instance, definition]
|
||||
end
|
||||
|
||||
def self.collect_definition_geometries(obj)
|
||||
geometries = []
|
||||
|
||||
# FIXME: This type check needed because of QGIS. It can send geometries both way, object or array..
|
||||
# This is something need to be fixed by QGIS.
|
||||
if obj['geometry'].is_a?(Array)
|
||||
obj['geometry'].each do |geometry|
|
||||
geometries << geometry
|
||||
end
|
||||
else
|
||||
geometries += obj['geometry']
|
||||
end
|
||||
|
||||
geometries.each do |geo|
|
||||
if geo['speckle_type'] && geo['speckle_type'] == OBJECTS_GEOMETRY_MESH
|
||||
geo['sketchup_attributes'] = { 'is_soften' => false }
|
||||
end
|
||||
end
|
||||
|
||||
obj['geometry'] = geometries
|
||||
obj
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -1,5 +1,6 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require_relative 'utils'
|
||||
require_relative '../base'
|
||||
require_relative '../other/transform'
|
||||
require_relative '../other/block_definition'
|
||||
@@ -14,26 +15,11 @@ module SpeckleConnector
|
||||
class PolygonElement < Base
|
||||
SPECKLE_TYPE = OBJECTS_GIS_POLYGONELEMENT
|
||||
|
||||
def self.get_definition_name(obj, attributes)
|
||||
return obj['name'] unless obj['name'].nil?
|
||||
|
||||
return attributes['name'] unless attributes['name'].nil?
|
||||
|
||||
return "def::#{obj['id']}"
|
||||
end
|
||||
|
||||
def self.get_qgis_attributes(obj)
|
||||
attributes = obj['attributes'].to_h
|
||||
speckle_properties = %w[id speckle_type totalChildrenCount units applicationId]
|
||||
speckle_properties.each { |key| attributes.delete(key) }
|
||||
attributes
|
||||
end
|
||||
|
||||
# Handles polygon element differently from display value.
|
||||
def self.to_native(state, obj, layer, entities, &convert_to_native)
|
||||
attributes = get_qgis_attributes(obj)
|
||||
attributes = GIS.get_qgis_attributes(obj)
|
||||
obj = collect_definition_geometries(obj)
|
||||
obj['name'] = get_definition_name(obj, attributes)
|
||||
obj['name'] = GIS.get_definition_name(obj, attributes)
|
||||
|
||||
state, _definitions = Other::BlockDefinition.to_native(
|
||||
state, obj, layer, entities, &convert_to_native
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require_relative '../base'
|
||||
require_relative '../other/transform'
|
||||
require_relative '../other/block_definition'
|
||||
require_relative '../other/block_instance'
|
||||
require_relative '../../constants/type_constants'
|
||||
require_relative '../../sketchup_model/dictionary/dictionary_handler'
|
||||
|
||||
module SpeckleConnector
|
||||
module SpeckleObjects
|
||||
module GIS
|
||||
def self.get_definition_name(obj, attributes)
|
||||
return obj['name'] unless obj['name'].nil?
|
||||
|
||||
return attributes['name'] unless attributes['name'].nil?
|
||||
|
||||
return "def::#{obj['id']}"
|
||||
end
|
||||
|
||||
def self.get_qgis_attributes(obj)
|
||||
attributes = obj['attributes'].to_h
|
||||
speckle_properties = %w[id speckle_type totalChildrenCount units applicationId]
|
||||
speckle_properties.each { |key| attributes.delete(key) }
|
||||
attributes
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -159,6 +159,7 @@ module SpeckleConnector
|
||||
# rubocop:disable Metrics/CyclomaticComplexity
|
||||
# rubocop:disable Metrics/PerceivedComplexity
|
||||
def self.group_entities_to_speckle(entities, preferences, speckle_state, parent, &convert)
|
||||
entities = entities.reject(&:hidden?)
|
||||
orphan_edges = entities.grep(Sketchup::Edge).filter { |edge| edge.faces.none? }
|
||||
lines = orphan_edges.collect do |orphan_edge|
|
||||
new_speckle_state, converted = convert.call(orphan_edge, preferences, speckle_state, parent)
|
||||
|
||||
@@ -83,13 +83,19 @@ module SpeckleConnector
|
||||
|
||||
elements = obj['elements'] || obj['@elements']
|
||||
|
||||
if !elements.nil? && elements.is_a?(Array)
|
||||
elements.each do |element|
|
||||
# Mullions is a special case here, they are extracted as base object with @displayValue from revit..
|
||||
if element['@displayValue'].nil?
|
||||
obj['geometry'].append(element)
|
||||
else
|
||||
obj['geometry'] += element['@displayValue']
|
||||
# if only elements are there then assign only elements, there are some cases that RevitWalls can only
|
||||
# have elements instead of display value
|
||||
if obj['geometry'].nil? && !elements.nil?
|
||||
obj['geometry'] = elements
|
||||
else
|
||||
if !elements.nil? && elements.is_a?(Array)
|
||||
elements.each do |element|
|
||||
# Mullions is a special case here, they are extracted as base object with @displayValue from revit..
|
||||
if element['@displayValue'].nil?
|
||||
obj['geometry'].append(element)
|
||||
else
|
||||
obj['geometry'] += element['@displayValue']
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -15,8 +15,10 @@ module SpeckleConnector
|
||||
family = def_obj['family']
|
||||
type = def_obj['type']
|
||||
category = def_obj['category']
|
||||
element_id = def_obj['elementId']
|
||||
id = def_obj['id']
|
||||
|
||||
return "#{family}-#{type}-#{category}-#{def_obj['elementId']}"
|
||||
return "#{family}-#{type}-#{category}-#{element_id}-#{id}"
|
||||
end
|
||||
|
||||
def self.to_native(state, definition, layer, entities, &convert_to_native)
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require_relative 'collection'
|
||||
|
||||
module SpeckleConnector
|
||||
module SpeckleObjects
|
||||
module Speckle
|
||||
module Core
|
||||
module Models
|
||||
# VectorLayerCollection object that collect GIS vector elements under it's elements.
|
||||
class GisLayerCollection < Collection
|
||||
# @param state [States::State] state of the Speckle application.
|
||||
def self.to_native(state, vector_layer_collection, layer_or_folder, entities, &convert_to_native)
|
||||
elements = vector_layer_collection['elements']
|
||||
|
||||
elements.each do |element|
|
||||
new_state, _converted_entities = convert_to_native.call(state, element, layer_or_folder, entities)
|
||||
state = new_state
|
||||
end
|
||||
|
||||
return state, []
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -66,6 +66,13 @@ module SpeckleConnector
|
||||
|
||||
def self.to_native(state, model_collection, layer, entities, &convert_to_native)
|
||||
elements = model_collection['elements']
|
||||
views = model_collection['@Views']
|
||||
if views
|
||||
views.each do |view|
|
||||
new_state, _converted_entities = convert_to_native.call(state, view, layer, entities)
|
||||
state = new_state
|
||||
end
|
||||
end
|
||||
|
||||
elements.each do |element|
|
||||
new_state, _converted_entities = convert_to_native.call(state, element, layer, entities)
|
||||
@@ -84,7 +91,7 @@ module SpeckleConnector
|
||||
|
||||
method = SPECKLE_SCHEMA_DICTIONARY_HANDLER.get_attribute(entity, 'method')
|
||||
|
||||
if method.include?('Floor') && entity.is_a?(Sketchup::Face)
|
||||
if !method.nil? && (method.include?('Floor') || method.include?('Wall')) && entity.is_a?(Sketchup::Face)
|
||||
global_transformation = QUERY::Entity.global_transformation(entity, path)
|
||||
floor = SpeckleObjects::Geometry::Mesh.from_face(speckle_state: speckle_state, face: entity,
|
||||
units: units, model_preferences: preferences,
|
||||
|
||||
+15
-7
@@ -15,7 +15,7 @@
|
||||
>
|
||||
<v-tabs-slider class="mx-sm-1"></v-tabs-slider>
|
||||
<v-tab href="#streams">
|
||||
{{"Streams"}}
|
||||
{{ streamsText }}
|
||||
</v-tab>
|
||||
<v-tab href="#mapper">
|
||||
{{"Mapper"}}
|
||||
@@ -88,7 +88,7 @@
|
||||
<v-text-field
|
||||
v-model="streamSearchQuery"
|
||||
prepend-inner-icon="mdi-magnify"
|
||||
label="Search streams"
|
||||
:label="searchText"
|
||||
background-color="background"
|
||||
hide-details
|
||||
clearable
|
||||
@@ -101,6 +101,7 @@
|
||||
</v-container>
|
||||
<create-stream-dialog
|
||||
v-if="accounts().length !== 0"
|
||||
:is-f-e2="preferences && preferences.user && preferences.user.fe2"
|
||||
:account-id="activeAccount().userInfo.id"
|
||||
:server-url="activeAccount().serverInfo.url"
|
||||
/>
|
||||
@@ -115,7 +116,7 @@
|
||||
</v-tab-item>
|
||||
<v-tab-item :key="2" value="mapper">
|
||||
<v-card flat>
|
||||
<mapper></mapper>
|
||||
<mapper :stream-text="streamText" :branch-text="branchText"></mapper>
|
||||
</v-card>
|
||||
</v-tab-item>
|
||||
</v-tabs-items>
|
||||
@@ -174,7 +175,7 @@ export default {
|
||||
size: {
|
||||
type: Number,
|
||||
default: 42
|
||||
},
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
@@ -183,7 +184,11 @@ export default {
|
||||
createStreamByIdDialog: false,
|
||||
createStreamByIdText: "",
|
||||
preferences: {},
|
||||
tab: "streams"
|
||||
tab: "streams",
|
||||
searchText: '',
|
||||
streamsText: 'Streams',
|
||||
streamText: 'Stream',
|
||||
branchText: 'Branch'
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
@@ -209,8 +214,11 @@ export default {
|
||||
})
|
||||
|
||||
bus.$on('update-preferences', async (preferences) => {
|
||||
let prefs = JSON.parse(preferences)
|
||||
this.preferences = prefs
|
||||
this.preferences = JSON.parse(preferences)
|
||||
this.searchText = this.preferences.user.fe2 ? 'Search projects' : 'Search streams'
|
||||
this.streamsText = this.preferences.user.fe2 ? 'Projects' : 'Streams'
|
||||
this.streamText = this.preferences.user.fe2 ? 'Project' : 'Stream'
|
||||
this.branchText = this.preferences.user.fe2 ? 'Model' : 'Branch'
|
||||
this.$vuetify.theme.dark = this.preferences.user.dark_theme
|
||||
})
|
||||
|
||||
|
||||
@@ -232,22 +232,27 @@ export default {
|
||||
// }
|
||||
},
|
||||
clearMappingsFromTableSelection(){
|
||||
sketchup.exec({ name: "clear_mappings_from_table", data: this.elementSelection })
|
||||
sketchup.exec({ name: "clear_mappings_from_table", data: this.elementSelection })
|
||||
this.$mixpanel.track('MappingsAction', { name: 'Mappings Clear' })
|
||||
},
|
||||
isolateMappedElementsOnSketchup(){
|
||||
if (this.isIsolated){
|
||||
this.isIsolated = false
|
||||
sketchup.exec({ name: "show_all_entities", data: {} })
|
||||
this.$mixpanel.track('MappingsAction', { name: 'Mappings Un-Isolate' })
|
||||
} else {
|
||||
this.isIsolated = true
|
||||
sketchup.exec({ name: "isolate_mappings_from_table", data: this.elementSelection })
|
||||
this.$mixpanel.track('MappingsAction', { name: 'Mappings Isolate' })
|
||||
}
|
||||
},
|
||||
hideMappedElementsOnSketchup(){
|
||||
sketchup.exec({ name: "hide_mappings_from_table", data: this.elementSelection })
|
||||
sketchup.exec({ name: "hide_mappings_from_table", data: this.elementSelection })
|
||||
this.$mixpanel.track('MappingsAction', { name: 'Mappings Hide' })
|
||||
},
|
||||
selectMappedElementsOnSketchup(){
|
||||
sketchup.exec({ name: "select_mappings_from_table", data: this.elementSelection })
|
||||
sketchup.exec({ name: "select_mappings_from_table", data: this.elementSelection })
|
||||
this.$mixpanel.track('MappingsAction', { name: 'Mappings Select Elements' })
|
||||
},
|
||||
// Update mapped elements table whenever mapped elements has changed.
|
||||
getMappedElementsTableData(){
|
||||
|
||||
+194
-62
@@ -65,24 +65,31 @@
|
||||
mdi-source-branch
|
||||
</v-icon>
|
||||
{{ `Source` }}
|
||||
<v-btn
|
||||
v-if="!sourceUpToDate"
|
||||
v-tooltip="'Source branch is not up-to-date!'"
|
||||
class="ma-0"
|
||||
height="20px"
|
||||
icon
|
||||
small
|
||||
color="red"
|
||||
@click="refreshSourceBranch"
|
||||
>
|
||||
<v-icon>
|
||||
mdi-update
|
||||
</v-icon>
|
||||
</v-btn>
|
||||
<v-tooltip right>
|
||||
<template #activator="{ on, attrs }">
|
||||
<v-btn
|
||||
class="ma-0 ml-1"
|
||||
height="20px"
|
||||
width="20px"
|
||||
icon
|
||||
x-small
|
||||
:color="getSourceStateIconColor()"
|
||||
v-bind="attrs"
|
||||
v-on="on"
|
||||
@click="refreshSourceBranch"
|
||||
>
|
||||
<v-icon>
|
||||
{{ getSourceStateIcon() }}
|
||||
</v-icon>
|
||||
</v-btn>
|
||||
</template>
|
||||
<span>{{ getSourceStateToolTip() }}</span>
|
||||
</v-tooltip>
|
||||
|
||||
</v-container>
|
||||
</v-expansion-panel-header>
|
||||
<v-expansion-panel-content>
|
||||
<mapper-source :source-up-to-date="this.sourceUpToDate"/>
|
||||
<mapper-source :stream-text="streamText" :branch-text="branchText" :source-state="this.sourceState"/>
|
||||
</v-expansion-panel-content>
|
||||
</v-expansion-panel>
|
||||
|
||||
@@ -152,7 +159,7 @@
|
||||
class="pt-0"
|
||||
label="Mapper Method"
|
||||
:disabled="!entitySelected"
|
||||
:items="enabledMethods"
|
||||
:items="availableMethods"
|
||||
density="compact"
|
||||
clearable
|
||||
@change="onSelectedMethodChange"
|
||||
@@ -167,6 +174,7 @@
|
||||
:items="families"
|
||||
density="compact"
|
||||
clearable
|
||||
@change="onSelectedFamilyChange"
|
||||
></v-autocomplete>
|
||||
|
||||
<v-autocomplete
|
||||
@@ -272,6 +280,7 @@
|
||||
import {bus} from "@/main";
|
||||
import {groupBy} from "@/utils/groupBy";
|
||||
import MappingSource from "@/components/MapperSource.vue";
|
||||
import {sourceMap} from "@vue/cli-service/lib/config/terserOptions";
|
||||
|
||||
global.mapperSourceUpdated = function (streamId, levels, types) {
|
||||
console.log(`Mapper source updated for ${streamId}.`)
|
||||
@@ -291,6 +300,16 @@ global.mappedEntitiesUpdated = function (mappedEntities) {
|
||||
|
||||
export default {
|
||||
name: "Mapper",
|
||||
props: {
|
||||
streamText: {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
branchText: {
|
||||
type: String,
|
||||
default: ''
|
||||
}
|
||||
},
|
||||
components: {
|
||||
MapperSource: () => import('@/components/MapperSource.vue'),
|
||||
GlobalToast: () => import('@/components/GlobalToast'),
|
||||
@@ -309,7 +328,7 @@ export default {
|
||||
categorySelectionActive: false,
|
||||
nameSelectionActive: false,
|
||||
|
||||
sourceUpToDate: true,
|
||||
sourceState: 'Not Set',
|
||||
// Expanded indexes for selection table (Types)
|
||||
selectionExpandedIndexes: [],
|
||||
// Expanded indexes for mapped element table (Categories)
|
||||
@@ -324,6 +343,7 @@ export default {
|
||||
entitySelected: false,
|
||||
selectedEntityCount: 0,
|
||||
selectedEntities: [],
|
||||
allFamilyTypes: {},
|
||||
familyTypes: [],
|
||||
lastSelectedEntity: null,
|
||||
|
||||
@@ -334,7 +354,7 @@ export default {
|
||||
selectedLevel: null,
|
||||
name: "",
|
||||
|
||||
enabledMethods: [],
|
||||
availableMethods: [],
|
||||
availableCategories: [],
|
||||
families: [],
|
||||
allTypes: {},
|
||||
@@ -449,10 +469,51 @@ export default {
|
||||
}
|
||||
},
|
||||
methods:{
|
||||
getSourceStateIcon(){
|
||||
switch (this.sourceState){
|
||||
case "Not Set":
|
||||
return `mdi-cloud-off-outline`;
|
||||
case "Set":
|
||||
return `mdi-checkbox-marked-circle-outline`;
|
||||
case "Outdated":
|
||||
return `mdi-update`;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
},
|
||||
getSourceStateToolTip(){
|
||||
switch (this.sourceState){
|
||||
case "Not Set":
|
||||
return 'Source disconnected.';
|
||||
case "Set":
|
||||
return 'Source connected.';
|
||||
case "Outdated":
|
||||
return 'Source branch is not up-to-date!';
|
||||
default:
|
||||
break;
|
||||
}
|
||||
},
|
||||
getSourceStateIconColor(){
|
||||
switch (this.sourceState){
|
||||
case "Not Set":
|
||||
return `grey`;
|
||||
case "Set":
|
||||
return `green`;
|
||||
case "Outdated":
|
||||
return `red`;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
},
|
||||
onSelectedMethodChange(){
|
||||
this.hideOptionalMappingInputs()
|
||||
this.updateMappingInputs()
|
||||
this.getTypesFromSelectedMethod()
|
||||
this.getFamiliesFromSelectedMethod()
|
||||
this.getTypesFromSelectedFamily()
|
||||
this.$mixpanel.track('MappingsAction', { name: 'Mappings Set', schema: this.selectedMethod })
|
||||
},
|
||||
onSelectedFamilyChange(){
|
||||
this.getTypesFromSelectedFamily();
|
||||
},
|
||||
updateMappingInputs(){
|
||||
if (this.selectedMethod === null){
|
||||
@@ -483,39 +544,54 @@ export default {
|
||||
this.levelSelectionActive = true
|
||||
}
|
||||
},
|
||||
getTypesFromSelectedMethod(){
|
||||
getTypesFromSelectedFamily(){
|
||||
this.familyTypes = this.allFamilyTypes[this.selectedFamily]
|
||||
this.selectedFamilyType = this.familyTypes[0].type
|
||||
if (this.selectedFamily === null || this.selectedFamily === undefined){
|
||||
this.selectedFamily = this.families[0]
|
||||
}
|
||||
if (this.familyTypes === null ||this.familyTypes === undefined){
|
||||
this.familyTypes = this.allFamilyTypes[this.selectedFamily]
|
||||
}
|
||||
if (this.selectedFamilyType === null || this.selectedFamilyType === undefined){
|
||||
this.selectedFamilyType = this.familyTypes[0].type
|
||||
}
|
||||
},
|
||||
getFamiliesFromSelectedMethod(){
|
||||
switch (this.selectedMethod) {
|
||||
case 'Floor':
|
||||
this.familyTypes = this.allTypes['Floors'];
|
||||
this.families = ['Floor'];
|
||||
this.families = Object.keys(this.allTypes['Floors']);
|
||||
this.allFamilyTypes = this.allTypes['Floors']
|
||||
break;
|
||||
case 'Wall':
|
||||
this.familyTypes = this.allTypes['Walls'];
|
||||
this.families = ['Wall'];
|
||||
this.families = Object.keys(this.allTypes['Walls']);
|
||||
this.allFamilyTypes = this.allTypes['Walls']
|
||||
break;
|
||||
case 'Column':
|
||||
this.familyTypes = this.allTypes['Columns'];
|
||||
this.families = ['Column'];
|
||||
this.families = Object.keys(this.allTypes['Columns']);
|
||||
this.allFamilyTypes = this.allTypes['Columns']
|
||||
break;
|
||||
case 'Beam':
|
||||
this.familyTypes = this.allTypes['Beams'];
|
||||
this.families = ['Beam'];
|
||||
break;
|
||||
case 'Brace':
|
||||
this.familyTypes = this.allTypes['Braces'];
|
||||
this.families = ['Brace'];
|
||||
this.families = Object.keys(this.allTypes['Beams']);
|
||||
this.allFamilyTypes = this.allTypes['Beams']
|
||||
break;
|
||||
case 'Pipe':
|
||||
this.familyTypes = this.allTypes['Pipes'];
|
||||
this.families = ['Pipe'];
|
||||
this.families = Object.keys(this.allTypes['Piping System']);
|
||||
this.allFamilyTypes = this.allTypes['Piping System']
|
||||
break;
|
||||
case 'Duct':
|
||||
this.familyTypes = this.allTypes['Ducts'];
|
||||
this.families = ['Duct'];
|
||||
this.families = Object.keys(this.allTypes['Duct System']);
|
||||
this.allFamilyTypes = this.allTypes['Duct System']
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
if (this.selectedFamily === null || this.selectedFamily === undefined){
|
||||
this.selectedFamily = this.families[0]
|
||||
}
|
||||
if (this.selectedLevel === null || this.selectedLevel === undefined){
|
||||
this.selectedLevel = this.levels[0].name
|
||||
}
|
||||
},
|
||||
hideOptionalMappingInputs(){
|
||||
this.categorySelectionActive = false
|
||||
@@ -525,10 +601,13 @@ export default {
|
||||
this.levelSelectionActive = false
|
||||
},
|
||||
refreshSourceBranch(){
|
||||
bus.$emit('refresh-source-branch')
|
||||
if (this.sourceState === 'Outdated'){
|
||||
bus.$emit('refresh-source-branch')
|
||||
this.$mixpanel.track('MappingsAction', { name: 'Mappings Source Update' })
|
||||
}
|
||||
},
|
||||
clearInputs(){
|
||||
this.enabledMethods = []
|
||||
this.availableMethods = []
|
||||
this.availableCategories = []
|
||||
this.selectedEntities = []
|
||||
this.selectionTableData = []
|
||||
@@ -581,12 +660,12 @@ export default {
|
||||
return summary
|
||||
},
|
||||
setInputValuesFromSelection(){
|
||||
// Clear all inputs if entity is not selected.
|
||||
if (!this.entitySelected){
|
||||
this.name = ""
|
||||
this.selectedMethod = null
|
||||
this.selectedCategory = null
|
||||
this.clearMappingInputs()
|
||||
return
|
||||
}
|
||||
// Check if definition card is selected and set definition mappings.
|
||||
if (this.definitionSelected) {
|
||||
if (!this.definitionMapped){
|
||||
if (this.selectedEntityCount > 1){
|
||||
@@ -605,15 +684,20 @@ export default {
|
||||
this.selectedMethod = this.lastSelectedEntity['definition']['schema']['method']
|
||||
this.selectedCategory = this.lastSelectedEntity['definition']['schema']['category']
|
||||
}
|
||||
} else {
|
||||
}
|
||||
// Otherwise set entity mappings.
|
||||
else
|
||||
{
|
||||
if (!this.entityMapped){
|
||||
if (this.selectedEntityCount > 1){
|
||||
this.name = '<Mixed>'
|
||||
}else{
|
||||
this.name = this.lastSelectedEntity['entityName']
|
||||
}
|
||||
console.log("entity not mapped")
|
||||
this.updateMappingInputs()
|
||||
// this.selectedMethod = 'Direct Shape'
|
||||
this.getFamiliesFromSelectedMethod()
|
||||
this.getTypesFromSelectedFamily()
|
||||
this.selectedCategory = 49
|
||||
} else {
|
||||
if (this.selectedEntityCount > 1){
|
||||
@@ -622,10 +706,12 @@ export default {
|
||||
this.name = this.lastSelectedEntity['schema']['name']
|
||||
}
|
||||
this.selectedMethod = this.lastSelectedEntity['schema']['method']
|
||||
console.log("entity is mapped")
|
||||
this.updateMappingInputs()
|
||||
this.getTypesFromSelectedMethod()
|
||||
this.selectedCategory = this.lastSelectedEntity['schema']['category']
|
||||
this.selectedFamily = this.lastSelectedEntity['schema']['family']
|
||||
this.selectedCategory = this.lastSelectedEntity['schema']['category']
|
||||
this.getFamiliesFromSelectedMethod()
|
||||
this.getTypesFromSelectedFamily()
|
||||
this.selectedFamilyType = this.lastSelectedEntity['schema']['family_type']
|
||||
this.selectedLevel = this.lastSelectedEntity['schema']['level']
|
||||
}
|
||||
@@ -666,10 +752,29 @@ export default {
|
||||
this.mappedElementsExpandedIndexes.push(slotData.item);
|
||||
}
|
||||
},
|
||||
inputsReadyToApply(){
|
||||
if (this.selectedMethod === null || this.selectedMethod === undefined){
|
||||
return false;
|
||||
}
|
||||
|
||||
const nativeMethods = this.nativeEdgeMethods.concat(this.nativeFaceMethods)
|
||||
|
||||
if (this.selectedMethod === 'Direct Shape'){
|
||||
return this.selectedCategory !== null
|
||||
}
|
||||
else if (nativeMethods.includes(this.selectedMethod)){
|
||||
return this.selectedFamily !== null &&
|
||||
this.selectedFamilyType !== null &&
|
||||
this.selectedLevel !== null
|
||||
}
|
||||
else {
|
||||
return true;
|
||||
}
|
||||
},
|
||||
applyMapping(){
|
||||
if (this.selectedMethod === null || this.selectedCategory === null){
|
||||
if (!this.inputsReadyToApply()){
|
||||
this.$eventHub.$emit('error', {
|
||||
text: 'Method and category are not set.\n'
|
||||
text: 'Some inputs are not set to apply mapping.\n'
|
||||
})
|
||||
return
|
||||
}
|
||||
@@ -687,6 +792,8 @@ export default {
|
||||
this.$eventHub.$emit('success', {
|
||||
text: 'Mapping Applied.\n'
|
||||
})
|
||||
|
||||
this.$mixpanel.track('MappingsAction', { name: 'Mappings Applied' })
|
||||
},
|
||||
clearMapping(){
|
||||
const mapping = {
|
||||
@@ -698,28 +805,53 @@ export default {
|
||||
this.$eventHub.$emit('error', {
|
||||
text: 'Mapping Cleared.\n'
|
||||
})
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
sketchup.exec({name: "collect_mapped_entities", data: {}})
|
||||
|
||||
bus.$on('entities-selected', async (selectionParameters) => {
|
||||
this.$mixpanel.track('MappingsAction', { name: 'Mappings Clear' })
|
||||
},
|
||||
clearMappingInputs(){
|
||||
this.selectedMethod = null
|
||||
const selectionPars = JSON.parse(selectionParameters)
|
||||
this.enabledMethods = selectionPars.mappingMethods
|
||||
this.availableCategories = selectionPars.categories
|
||||
this.selectedEntities = selectionPars.selection
|
||||
this.allTypes = selectionPars.types
|
||||
this.levels = selectionPars.levels
|
||||
this.selectedLevel = selectionPars.selectedLevel
|
||||
console.log(selectionPars)
|
||||
this.selectedCategory = null
|
||||
this.name = ""
|
||||
this.selectedFamily = null
|
||||
this.selectedFamilyType = null
|
||||
this.selectedLevel = null
|
||||
this.familyTypes = null
|
||||
this.levels = null
|
||||
this.availableMethods = null
|
||||
this.availableCategories = null
|
||||
this.allTypes = null
|
||||
},
|
||||
getDataFromSelection(selectionParameters){
|
||||
this.availableMethods = selectionParameters.mappingMethods
|
||||
this.availableCategories = selectionParameters.categories
|
||||
this.selectedEntities = selectionParameters.selection
|
||||
this.allTypes = selectionParameters.types
|
||||
this.levels = selectionParameters.levels
|
||||
this.selectedLevel = selectionParameters.selectedLevelName
|
||||
},
|
||||
updateStatesFromSelectionData(){
|
||||
this.lastSelectedEntity = this.selectedEntities[this.selectedEntities.length - 1]
|
||||
this.entityMapped = this.isEntitiesMapped(this.selectedEntities)
|
||||
this.definitionMapped = this.isEntityDefinitionsMapped(this.selectedEntities)
|
||||
this.definitionSelected = !this.entityMapped && this.definitionMapped
|
||||
this.selectedEntityCount = this.selectedEntities.length
|
||||
this.entitySelected = this.selectedEntityCount !== 0
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
sketchup.exec({name: "collect_mapped_entities", data: {}})
|
||||
|
||||
bus.$on('entities-selected', async (selectionParameters) => {
|
||||
// Parse data to json object
|
||||
const selectionPars = JSON.parse(selectionParameters)
|
||||
// Reset mapping inputs with nulls and empties.
|
||||
this.clearMappingInputs()
|
||||
// Get data from selection into objects and arrays. These data basically constructs the dropdowns.
|
||||
this.getDataFromSelection(selectionPars)
|
||||
// Update inner state of the mapper component according to selection data.
|
||||
this.updateStatesFromSelectionData()
|
||||
// Get selection table data.
|
||||
this.getSelectionTableData()
|
||||
// Set mapping input values from selection data.
|
||||
this.setInputValuesFromSelection()
|
||||
})
|
||||
bus.$on('entities-deselected', async () => {
|
||||
@@ -731,7 +863,7 @@ export default {
|
||||
this.mappedEntityCount = mappedEntities.length
|
||||
})
|
||||
bus.$on('set-source-up-to-date', (isUpToDate) => {
|
||||
this.sourceUpToDate = isUpToDate
|
||||
this.sourceState = isUpToDate
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
<v-container class="pa-0">
|
||||
<v-autocomplete
|
||||
v-model="sourceStreamId"
|
||||
label="Stream"
|
||||
:label="streamText"
|
||||
:items="allStreamsList"
|
||||
item-text="name"
|
||||
item-value="id"
|
||||
@@ -12,7 +12,7 @@
|
||||
<v-autocomplete
|
||||
v-model="sourceBranchId"
|
||||
class="pt-0 mb-n5"
|
||||
label="Branch"
|
||||
:label="branchText"
|
||||
:items="allBranchesList"
|
||||
:disabled="sourceStreamId === null"
|
||||
item-text="name"
|
||||
@@ -62,7 +62,15 @@ export default {
|
||||
name: "MappingSource",
|
||||
props: {
|
||||
streamSearchQuery: { type: String, default: null },
|
||||
sourceUpToDate: { type: Boolean },
|
||||
sourceState: { type: String, default: 'Not Set' },
|
||||
streamText: {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
branchText: {
|
||||
type: String,
|
||||
default: ''
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
@@ -117,11 +125,13 @@ export default {
|
||||
},
|
||||
result(data) {
|
||||
if (data.data.commitCreated.sourceApplication.includes('Revit')){
|
||||
this.afterCommitCreated()
|
||||
this.$eventHub.$emit('notification', {
|
||||
text: `A new commit was created on Revit!`,
|
||||
})
|
||||
this.$apollo.queries.stream.refetch()
|
||||
if (data.data.commitCreated.branchName === this.selectedBranch.name){
|
||||
this.afterCommitCreated()
|
||||
this.$eventHub.$emit('notification', {
|
||||
text: `A new commit was created on Revit!`,
|
||||
})
|
||||
this.$apollo.queries.stream.refetch()
|
||||
}
|
||||
}
|
||||
},
|
||||
skip() {
|
||||
@@ -161,19 +171,32 @@ export default {
|
||||
mounted() {
|
||||
bus.$on('refresh-source-branch', () => {
|
||||
this.onSourceBranchChanged()
|
||||
bus.$emit('set-source-up-to-date', true)
|
||||
bus.$emit('set-source-up-to-date', 'Set')
|
||||
})
|
||||
},
|
||||
methods: {
|
||||
applySource(){
|
||||
bus.$emit('set-source-up-to-date', 'Set')
|
||||
this.onSourceBranchChanged()
|
||||
this.$eventHub.$emit('success', {
|
||||
text: 'Mapper source applied.\n'
|
||||
})
|
||||
this.$mixpanel.track('MappingsAction', { name: 'Mappings Source Apply' })
|
||||
},
|
||||
clearSource(){
|
||||
sketchup.exec({name:"clear_mapper_source" , data: {}})
|
||||
bus.$emit('set-source-up-to-date', 'Not Set')
|
||||
this.sourceApplied = false
|
||||
this.sourceBranchName = null
|
||||
this.sourceStreamName = null
|
||||
this.sourceBranchId = null
|
||||
this.sourceStreamId = null
|
||||
this.$eventHub.$emit('error', {
|
||||
text: 'Mapper source cleared.\n'
|
||||
})
|
||||
},
|
||||
afterCommitCreated(){
|
||||
bus.$emit('set-source-up-to-date', false)
|
||||
bus.$emit('set-source-up-to-date', 'Outdated')
|
||||
},
|
||||
async onSourceBranchChanged() {
|
||||
const commitRefId = this.selectedBranch.commits.items[0]?.referencedObject
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
<v-toolbar-title class="ml-0" style="position: relative; left: -10px">
|
||||
<!-- Uncomment when pinning is in place and add style="position: relative; left: -10px" to the element above :) -->
|
||||
<v-btn
|
||||
v-tooltip="'Pin this stream - it will be saved to this file.'"
|
||||
v-tooltip="`Pin this ${streamText.toLowerCase()} - it will be saved to this file.`"
|
||||
icon
|
||||
x-small
|
||||
@click="toggleSavedStream"
|
||||
@@ -66,7 +66,11 @@
|
||||
<template #activator="{ on, attrs }">
|
||||
<v-slide-x-transition>
|
||||
<div v-show="hover">
|
||||
<create-branch-dialog :stream-name="stream.name" :stream-id="streamId"/>
|
||||
<create-branch-dialog
|
||||
:is-f-e2="preferences && preferences.user && preferences.user.fe2"
|
||||
:stream-name="stream.name"
|
||||
:stream-id="streamId"
|
||||
/>
|
||||
</div>
|
||||
</v-slide-x-transition>
|
||||
<v-chip v-if="stream.branches" small v-bind="attrs" class="mr-1" v-on="on">
|
||||
@@ -133,7 +137,7 @@
|
||||
hide-details
|
||||
dense
|
||||
flat
|
||||
placeholder="Write your commit message here"
|
||||
:placeholder="`Write your ${commitText.toLowerCase()} message here`"
|
||||
/>
|
||||
</div>
|
||||
</v-slide-y-transition>
|
||||
@@ -204,7 +208,11 @@ export default {
|
||||
commitId: 'latest',
|
||||
commitMessage: null,
|
||||
invalid: false,
|
||||
diffing: false
|
||||
diffing: false,
|
||||
streamText: '',
|
||||
branchText: '',
|
||||
commitText: '',
|
||||
preferences: {}
|
||||
}
|
||||
},
|
||||
apollo: {
|
||||
@@ -286,6 +294,16 @@ export default {
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
bus.$on('update-preferences', async (preferences) => {
|
||||
const pref = JSON.parse(preferences)
|
||||
this.preferences = pref
|
||||
this.streamText = pref.user.fe2 ? 'Project' : 'Stream'
|
||||
this.branchText = pref.user.fe2 ? 'Model' : 'Branch'
|
||||
this.commitText = pref.user.fe2 ? 'Version' : 'Commit'
|
||||
})
|
||||
// Collect preferences to render UI according to it
|
||||
sketchup.exec({name: "collect_preferences", data: {}})
|
||||
|
||||
bus.$on(`deactivate-diffing-${this.streamId}`, () => {
|
||||
this.diffing = false
|
||||
})
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<v-dialog v-model="showCreateBranch">
|
||||
<template #activator="{ on: dialog, attrs }">
|
||||
<v-btn
|
||||
v-tooltip="'Create Branch'"
|
||||
v-tooltip="`Create ${isFE2 ? 'Model' : 'Branch'}`"
|
||||
icon x-small class="ml-0 mr-1"
|
||||
v-bind="attrs"
|
||||
v-on="{...dialog}"
|
||||
@@ -15,10 +15,10 @@
|
||||
</template>
|
||||
<v-card>
|
||||
<v-card-title class="text-h5 mb-1">
|
||||
Create a New Branch
|
||||
{{ `Create a New ${isFE2 ? 'Model' : 'Branch'}` }}
|
||||
</v-card-title>
|
||||
<v-card-subtitle class="py-0 my-0 font-italic">
|
||||
under {{ streamName }} stream
|
||||
{{ `under ${streamName} ${isFE2 ? 'project' : 'stream'}` }}
|
||||
</v-card-subtitle>
|
||||
<v-container class="px-6" pb-0>
|
||||
<v-text-field
|
||||
@@ -27,7 +27,7 @@
|
||||
hide-details
|
||||
dense
|
||||
flat
|
||||
placeholder="Branch Name"
|
||||
:placeholder="`${isFE2 ? 'Model' : 'Branch'} Name`"
|
||||
/>
|
||||
<v-text-field
|
||||
v-model="description"
|
||||
@@ -75,6 +75,14 @@ export default {
|
||||
streamName: {
|
||||
type: String,
|
||||
default: null
|
||||
},
|
||||
isFE2: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
branchTooltipName: {
|
||||
type: String,
|
||||
default: ''
|
||||
}
|
||||
},
|
||||
data() {
|
||||
|
||||
@@ -16,13 +16,14 @@
|
||||
left
|
||||
>
|
||||
mdi-plus-circle
|
||||
</v-icon>Create New Stream
|
||||
</v-icon>
|
||||
{{ `Create New ${isFE2 ? 'Project': 'Stream'}` }}
|
||||
</v-btn>
|
||||
</template>
|
||||
|
||||
<v-card>
|
||||
<v-card-title class="text-h5">
|
||||
Create a New Stream
|
||||
{{ `Create a New ${isFE2 ? 'Project' : 'Stream'}` }}
|
||||
</v-card-title>
|
||||
<v-container class="px-6" pb-0>
|
||||
<!--
|
||||
@@ -55,7 +56,7 @@
|
||||
hide-details
|
||||
dense
|
||||
flat
|
||||
placeholder="Stream Name (Optional)"
|
||||
:placeholder="`${isFE2 ? 'Project' : 'Stream'} Name (Optional)`"
|
||||
/>
|
||||
<v-text-field
|
||||
v-model="description"
|
||||
@@ -67,7 +68,7 @@
|
||||
/>
|
||||
<v-switch
|
||||
v-model="privateStream"
|
||||
:label="'Private Stream'"
|
||||
:label="`Private ${isFE2 ? 'Project' : 'Stream'}`"
|
||||
></v-switch>
|
||||
</v-container>
|
||||
|
||||
@@ -169,6 +170,10 @@ export default {
|
||||
serverUrl: {
|
||||
type: String,
|
||||
default: null
|
||||
},
|
||||
isFE2: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
}
|
||||
},
|
||||
data() {
|
||||
@@ -200,7 +205,7 @@ export default {
|
||||
},
|
||||
async getStream(){
|
||||
try {
|
||||
const streamWrapper = new StreamWrapper(this.createStreamByIdText, this.accountId, this.serverUrl)
|
||||
const streamWrapper = new StreamWrapper(this.createStreamByIdText, this.accountId, this.serverUrl, this.isFE2)
|
||||
let res = await this.$apollo.query({
|
||||
query: gql`
|
||||
query Stream($id: String!){
|
||||
|
||||
@@ -16,14 +16,25 @@
|
||||
Settings
|
||||
</v-card-title>
|
||||
<v-container class="px-6" pb-0>
|
||||
<!-- Switch Theme -->
|
||||
|
||||
<!-- User preferences -->
|
||||
<div class="sm1 mt-3">User Preferences</div>
|
||||
<v-divider class="mb-2"/>
|
||||
|
||||
<!-- Switch Theme -->
|
||||
<v-btn icon small class="mx-1" @click="switchTheme">
|
||||
<v-icon>mdi-theme-light-dark</v-icon>
|
||||
</v-btn>
|
||||
<span>Color Mode</span>
|
||||
|
||||
<!-- FE2 -->
|
||||
<v-switch
|
||||
:input-value="fe2"
|
||||
class="pt-3 mt-n2 mb-n7"
|
||||
:label="'FE2'"
|
||||
@change="fe2Handler"
|
||||
/>
|
||||
|
||||
<!-- Register objects as Speckle Entity on send/receive -->
|
||||
<v-switch
|
||||
:input-value="registerSpeckleEntity"
|
||||
@@ -133,6 +144,7 @@ export default {
|
||||
includeComponentAttributes: this.preferences.model.include_component_entity_attributes,
|
||||
mergeCoplanarFaces: this.preferences.model.merge_coplanar_faces,
|
||||
diffing: this.preferences.user.diffing,
|
||||
fe2: this.preferences.user.fe2,
|
||||
registerSpeckleEntity: this.preferences.user.register_speckle_entity
|
||||
}
|
||||
},
|
||||
@@ -147,6 +159,7 @@ export default {
|
||||
this.includeComponentAttributes = newValue.model.include_component_entity_attributes
|
||||
this.mergeCoplanarFaces = newValue.model.merge_coplanar_faces
|
||||
this.diffing = newValue.user.diffing
|
||||
this.fe2 = newValue.user.fe2
|
||||
this.registerSpeckleEntity = newValue.user.register_speckle_entity
|
||||
},
|
||||
deep: true,
|
||||
@@ -161,6 +174,15 @@ export default {
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
fe2Handler(newValue){
|
||||
this.fe2 = !!newValue
|
||||
sketchup.exec({
|
||||
name: "user_preferences_updated",
|
||||
data: {preference_hash: "configSketchup", preference: "fe2", value: this.fe2}
|
||||
})
|
||||
this.$mixpanel.track('Connector Action', { name: 'Toggle FE2' })
|
||||
sketchup.exec({name: "collect_preferences", data: {}})
|
||||
},
|
||||
diffingHandler(newValue){
|
||||
this.diffing = !!newValue
|
||||
sketchup.exec({
|
||||
|
||||
@@ -1,7 +1,11 @@
|
||||
require('url')
|
||||
|
||||
export class StreamWrapper {
|
||||
constructor(streamIdOrUrl, accountId, serverUrl) {
|
||||
constructor(streamIdOrUrl, accountId, serverUrl, isFE2) {
|
||||
this.isFE2 = isFE2
|
||||
this.streamsKey = this.isFE2 ? 'projects/': 'streams/'
|
||||
this.branchesKey = this.isFE2 ? 'models/': 'branches/'
|
||||
this.commitsKey = this.isFE2 ? 'versions/': 'commits/'
|
||||
this.originalOutput = streamIdOrUrl
|
||||
try {
|
||||
this.streamWrapperFromUrl(streamIdOrUrl)
|
||||
@@ -18,7 +22,7 @@ export class StreamWrapper {
|
||||
this.segments = this.url.pathname.split('/').map((segment) => segment + '/')
|
||||
this.serverUrl = this.url.origin
|
||||
|
||||
if (this.segments.length >= 4 && this.segments[3]?.toLowerCase() === "branches/"){
|
||||
if (this.segments.length >= 4 && this.segments[3]?.toLowerCase() === this.branchesKey){
|
||||
this.streamId = this.segments[2].replace("/", "")
|
||||
if (this.segments.length > 5)
|
||||
{
|
||||
@@ -32,7 +36,7 @@ export class StreamWrapper {
|
||||
} else {
|
||||
switch (this.segments.length){
|
||||
case 3: // ie http://speckle.server/streams/8fecc9aa6d
|
||||
if (this.segments[1].toLowerCase() === "streams/")
|
||||
if (this.segments[1].toLowerCase() === this.streamsKey)
|
||||
this.streamId = this.segments[2].replace("/", "");
|
||||
else
|
||||
throw new Error(`Cannot parse ${this.originalOutput} into a stream wrapper class`);
|
||||
@@ -48,7 +52,7 @@ export class StreamWrapper {
|
||||
break;
|
||||
case 5: // ie http://speckle.server/streams/8fecc9aa6d/commits/76a23d7179
|
||||
switch (this.segments[3].toLowerCase()){
|
||||
case "commits/":
|
||||
case this.commitsKey:
|
||||
this.streamId = this.segments[2].replace("/", "");
|
||||
this.commitId = this.segments[4].replace("/", "");
|
||||
break;
|
||||
@@ -57,7 +61,7 @@ export class StreamWrapper {
|
||||
this.branchName = this.segments[3].replace("/", "");
|
||||
this.commitId = this.segments[4].replace("/", "");
|
||||
break;
|
||||
case "branches/":
|
||||
case this.branchesKey:
|
||||
this.streamId = this.segments[2].replace("/", "");
|
||||
this.branchName = this.segments[4].replace("/", "");
|
||||
break;
|
||||
|
||||
@@ -27,7 +27,7 @@
|
||||
elevation="0"
|
||||
@click="showMore"
|
||||
>
|
||||
More Streams
|
||||
{{ `More ${streamsText}` }}
|
||||
</v-btn>
|
||||
</div>
|
||||
</div>
|
||||
@@ -64,7 +64,8 @@ export default {
|
||||
data() {
|
||||
return {
|
||||
showMoreEnabled: true,
|
||||
savedStreams: []
|
||||
savedStreams: [],
|
||||
streamsText: ''
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
@@ -80,6 +81,14 @@ export default {
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
bus.$on('update-preferences', async (preferences) => {
|
||||
const pref = JSON.parse(preferences)
|
||||
this.streamsText = pref.user.fe2 ? 'Projects' : 'Streams'
|
||||
})
|
||||
|
||||
// Collect preferences to render UI according to it
|
||||
sketchup.exec({name: "collect_preferences", data: {}})
|
||||
|
||||
bus.$on("deactivate-diffing-except", (exceptedStreamId) => {
|
||||
this.savedStreams.forEach((streamId) => {
|
||||
if (streamId !== exceptedStreamId){
|
||||
|
||||
Reference in New Issue
Block a user