Compare commits
13 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 4c381bd809 | |||
| 8c3885ece8 | |||
| 15bd3f5070 | |||
| 6fd4571d34 | |||
| 5081177653 | |||
| 0d0ca2c811 | |||
| 230e27a162 | |||
| 669fd19c2e | |||
| 139f8ccb33 | |||
| 7f625bd468 | |||
| 4d07ba7637 | |||
| e74a6cebb1 | |||
| 5e01d5a976 |
@@ -116,7 +116,8 @@ jobs:
|
||||
|
||||
build-installer-mac:
|
||||
macos:
|
||||
xcode: 12.5.1
|
||||
xcode: 13.4.1
|
||||
resource_class: macos.m1.medium.gen1
|
||||
parameters:
|
||||
runtime:
|
||||
type: string
|
||||
|
||||
@@ -138,7 +138,6 @@ def ensure_pip() -> None:
|
||||
def get_requirements_path() -> Path:
|
||||
# we assume that a requirements.txt exists next to the __init__.py file
|
||||
path = Path(Path(__file__).parent, "requirements.txt")
|
||||
assert path.exists()
|
||||
return path
|
||||
|
||||
|
||||
@@ -147,10 +146,22 @@ def install_requirements(host_application: str) -> None:
|
||||
# script path. Here we'll install the
|
||||
# dependencies
|
||||
path = connector_installation_path(host_application)
|
||||
print(f"Installing Speckle dependencies to {path}")
|
||||
|
||||
from subprocess import run
|
||||
|
||||
def debugger_is_active() -> bool:
|
||||
"""Return if the debugger is currently active"""
|
||||
return hasattr(sys, 'gettrace') and sys.gettrace() is not None
|
||||
|
||||
requirements_path = get_requirements_path()
|
||||
|
||||
is_debug = debugger_is_active()
|
||||
|
||||
if not is_debug and not requirements_path.exists():
|
||||
print("Skipped installing dependencies")
|
||||
return
|
||||
|
||||
print(f"Installing Speckle dependencies to {path}")
|
||||
completed_process = run(
|
||||
[
|
||||
PYTHON_PATH,
|
||||
@@ -165,16 +176,21 @@ def install_requirements(host_application: str) -> None:
|
||||
"-t",
|
||||
str(path),
|
||||
"-r",
|
||||
str(get_requirements_path()),
|
||||
str(requirements_path),
|
||||
],
|
||||
capture_output=True,
|
||||
text=True,
|
||||
)
|
||||
|
||||
if completed_process.returncode != 0:
|
||||
m = f"Failed to install dependenices through pip, got {completed_process.returncode} return code"
|
||||
m = f"Failed to install dependencies through pip, got {completed_process.returncode} return code"
|
||||
print(m)
|
||||
raise Exception(m)
|
||||
|
||||
print("Successfully installed dependencies")
|
||||
|
||||
if not is_debug:
|
||||
requirements_path.unlink()
|
||||
|
||||
|
||||
def install_dependencies(host_application: str) -> None:
|
||||
|
||||
@@ -33,7 +33,7 @@ from bpy_speckle.functions import (
|
||||
)
|
||||
from bpy_speckle.clients import speckle_clients
|
||||
from bpy_speckle.operators.users import LoadUserStreams, add_user_stream
|
||||
from bpy_speckle.properties.scene import SpeckleSceneSettings, SpeckleStreamObject, SpeckleUserObject, get_speckle
|
||||
from bpy_speckle.properties.scene import SpeckleSceneSettings, SpeckleStreamObject, SpeckleUserObject, get_speckle, selection_state
|
||||
from bpy_speckle.convert.util import ConversionSkippedException, add_to_hierarchy
|
||||
from specklepy.core.api.models import Commit
|
||||
from specklepy.core.api import operations, host_applications
|
||||
@@ -380,6 +380,11 @@ class SendStreamObjects(bpy.types.Operator):
|
||||
|
||||
_report(f"Commit Created {sent_url}")
|
||||
|
||||
selection_state.selected_commit_id = COMMIT_ID
|
||||
selection_state.selected_branch_id = branch.id
|
||||
selection_state.selected_stream_id = stream.id
|
||||
selection_state.selected_user_id = user.id
|
||||
|
||||
bpy.ops.speckle.load_user_streams() # refresh loaded commits
|
||||
context.view_layer.update()
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@ import bpy
|
||||
from bpy.types import Context
|
||||
from bpy_speckle.functions import _report
|
||||
from bpy_speckle.clients import speckle_clients
|
||||
from bpy_speckle.properties.scene import SpeckleBranchObject, SpeckleCommitObject, SpeckleSceneSettings, SpeckleStreamObject, SpeckleUserObject, get_speckle
|
||||
from bpy_speckle.properties.scene import SpeckleBranchObject, SpeckleCommitObject, SpeckleSceneSettings, SpeckleStreamObject, SpeckleUserObject, get_speckle, restore_selection_state
|
||||
from specklepy.core.api.client import SpeckleClient
|
||||
from specklepy.core.api.models import Stream
|
||||
from specklepy.core.api.credentials import get_local_accounts, Account
|
||||
@@ -137,28 +137,8 @@ def add_user_stream(user: SpeckleUserObject, stream: Stream):
|
||||
|
||||
_report(f"Adding stream {s.id} - {s.name}")
|
||||
|
||||
if not stream.branches:
|
||||
return
|
||||
|
||||
# branches = [branch for branch in stream.branches.items if branch.name != "globals"]
|
||||
for b in stream.branches.items:
|
||||
branch = cast(SpeckleBranchObject, s.branches.add())
|
||||
branch.name = b.name
|
||||
branch.id = b.id
|
||||
branch.description = b.description or ""
|
||||
|
||||
if not b.commits:
|
||||
continue
|
||||
|
||||
for c in b.commits.items:
|
||||
commit: SpeckleCommitObject = branch.commits.add()
|
||||
commit.id = commit.name = c.id
|
||||
commit.message = c.message or ""
|
||||
commit.author_name = c.authorName
|
||||
commit.author_id = c.authorId
|
||||
commit.created_at = c.createdAt.strftime("%Y-%m-%d %H:%M:%S.%f%Z") if c.createdAt else ""
|
||||
commit.source_application = str(c.sourceApplication)
|
||||
commit.referenced_object = c.referencedObject
|
||||
if stream.branches:
|
||||
s.load_stream_branches(stream)
|
||||
|
||||
|
||||
class LoadUserStreams(bpy.types.Operator):
|
||||
@@ -195,12 +175,25 @@ class LoadUserStreams(bpy.types.Operator):
|
||||
_report("Zero projects found")
|
||||
return
|
||||
|
||||
|
||||
active_stream_id = None
|
||||
if active_stream := user.get_active_stream():
|
||||
active_stream_id = active_stream.id
|
||||
elif len(user.streams) > 0:
|
||||
active_stream_id = user.streams[0].id
|
||||
|
||||
user.streams.clear()
|
||||
|
||||
for s in streams:
|
||||
for i, s in enumerate(streams):
|
||||
assert(s.id)
|
||||
sstream = client.stream.get(id=s.id, branch_limit=self.branch_limit, commit_limit=10)
|
||||
add_user_stream(user, sstream)
|
||||
load_branches = s.id == active_stream_id if active_stream_id else i == 0
|
||||
if load_branches:
|
||||
sstream = client.stream.get(id=s.id, branch_limit=self.branch_limit, commit_limit=10)
|
||||
add_user_stream(user, sstream)
|
||||
else:
|
||||
add_user_stream(user, s)
|
||||
|
||||
restore_selection_state(speckle)
|
||||
|
||||
bpy.context.view_layer.update()
|
||||
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
"""
|
||||
Scene properties
|
||||
"""
|
||||
from typing import Iterable, Optional, Tuple, cast
|
||||
from typing import Iterable, Optional, Tuple, Union, cast
|
||||
from dataclasses import dataclass
|
||||
import bpy
|
||||
from bpy.props import (
|
||||
StringProperty,
|
||||
@@ -11,6 +12,9 @@ from bpy.props import (
|
||||
IntProperty,
|
||||
)
|
||||
|
||||
from bpy_speckle.clients import speckle_clients
|
||||
from specklepy.core.api.models import Stream
|
||||
|
||||
class SpeckleSceneObject(bpy.types.PropertyGroup):
|
||||
name: bpy.props.StringProperty(default="") # type: ignore
|
||||
|
||||
@@ -35,6 +39,11 @@ class SpeckleBranchObject(bpy.types.PropertyGroup):
|
||||
]
|
||||
return [("0", "<none>", "<none>", 0)]
|
||||
|
||||
def commit_update_hook(self, context: bpy.types.Context):
|
||||
selection_state.selected_commit_id = SelectionState.get_item_id_by_index(self.commits, self.commit)
|
||||
selection_state.selected_branch_id = self.id
|
||||
# print(f"commit_update_hook: {selection_state.selected_commit_id=}, {selection_state.selected_branch_id=}")
|
||||
|
||||
name: StringProperty(default="main") # type: ignore
|
||||
id: StringProperty(default="") # type: ignore
|
||||
description: StringProperty(default="") # type: ignore
|
||||
@@ -43,6 +52,7 @@ class SpeckleBranchObject(bpy.types.PropertyGroup):
|
||||
name="Version",
|
||||
description="Selected model version",
|
||||
items=get_commits,
|
||||
update=commit_update_hook,
|
||||
) # type: ignore
|
||||
|
||||
def get_active_commit(self) -> Optional[SpeckleCommitObject]:
|
||||
@@ -50,9 +60,30 @@ class SpeckleBranchObject(bpy.types.PropertyGroup):
|
||||
if 0 <= selected_index < len(self.commits):
|
||||
return self.commits[selected_index]
|
||||
return None
|
||||
|
||||
|
||||
|
||||
class SpeckleStreamObject(bpy.types.PropertyGroup):
|
||||
def load_stream_branches(self, sstream: Stream):
|
||||
self.branches.clear()
|
||||
# branches = [branch for branch in stream.branches.items if branch.name != "globals"]
|
||||
for b in sstream.branches.items:
|
||||
branch = cast(SpeckleBranchObject, self.branches.add())
|
||||
branch.name = b.name
|
||||
branch.id = b.id
|
||||
branch.description = b.description or ""
|
||||
|
||||
if not b.commits:
|
||||
continue
|
||||
|
||||
for c in b.commits.items:
|
||||
commit: SpeckleCommitObject = branch.commits.add()
|
||||
commit.id = commit.name = c.id
|
||||
commit.message = c.message or ""
|
||||
commit.author_name = c.authorName
|
||||
commit.author_id = c.authorId
|
||||
commit.created_at = c.createdAt.strftime("%Y-%m-%d %H:%M:%S.%f%Z") if c.createdAt else ""
|
||||
commit.source_application = str(c.sourceApplication)
|
||||
commit.referenced_object = c.referencedObject
|
||||
|
||||
def get_branches(self, context):
|
||||
if self.branches:
|
||||
BRANCHES = cast(Iterable[SpeckleBranchObject], self.branches)
|
||||
@@ -62,6 +93,10 @@ class SpeckleStreamObject(bpy.types.PropertyGroup):
|
||||
if branch.name != "globals"
|
||||
]
|
||||
return [("0", "<none>", "<none>", 0)]
|
||||
|
||||
def branch_update_hook(self, context: bpy.types.Context):
|
||||
selection_state.selected_branch_id = SelectionState.get_item_id_by_index(self.branches, self.branch)
|
||||
# print(f"branch_update_hook: {selection_state.selected_branch_id=}, {selection_state.selected_stream_id=}")
|
||||
|
||||
name: StringProperty(default="") # type: ignore
|
||||
description: StringProperty(default="") # type: ignore
|
||||
@@ -71,6 +106,7 @@ class SpeckleStreamObject(bpy.types.PropertyGroup):
|
||||
name="Model",
|
||||
description="Selected Model",
|
||||
items=get_branches,
|
||||
update=branch_update_hook,
|
||||
) # type: ignore
|
||||
|
||||
def get_active_branch(self) -> Optional[SpeckleBranchObject]:
|
||||
@@ -79,8 +115,20 @@ class SpeckleStreamObject(bpy.types.PropertyGroup):
|
||||
return self.branches[selected_index]
|
||||
return None
|
||||
|
||||
|
||||
class SpeckleUserObject(bpy.types.PropertyGroup):
|
||||
def fetch_stream_branches(self, context: bpy.types.Context, stream: SpeckleStreamObject):
|
||||
speckle = context.scene.speckle
|
||||
client = speckle_clients[int(speckle.active_user)]
|
||||
sstream = client.stream.get(id=stream.id, branch_limit=100, commit_limit=10) # TODO: refactor magic numbers
|
||||
stream.load_stream_branches(sstream)
|
||||
|
||||
def stream_update_hook(self, context: bpy.types.Context):
|
||||
stream = SelectionState.get_item_by_index(self.streams, self.active_stream)
|
||||
selection_state.selected_stream_id = stream.id
|
||||
# print(f"stream_update_hook: {selection_state.selected_stream_id=}, {selection_state.selected_user_id=}")
|
||||
if len(stream.branches) == 0: # do not reload on selection, same as the old behavior
|
||||
self.fetch_stream_branches(context, stream)
|
||||
|
||||
server_name: StringProperty(default="SpeckleXYZ") # type: ignore
|
||||
server_url: StringProperty(default="https://speckle.xyz") # type: ignore
|
||||
id: StringProperty(default="") # type: ignore
|
||||
@@ -88,13 +136,14 @@ class SpeckleUserObject(bpy.types.PropertyGroup):
|
||||
email: StringProperty(default="user@speckle.xyz") # type: ignore
|
||||
company: StringProperty(default="SpeckleSystems") # type: ignore
|
||||
streams: CollectionProperty(type=SpeckleStreamObject) # type: ignore
|
||||
active_stream: IntProperty(default=0) # type: ignore
|
||||
active_stream: IntProperty(default=0, update=stream_update_hook) # type: ignore
|
||||
|
||||
def get_active_stream(self) -> Optional[SpeckleStreamObject]:
|
||||
selected_index = int(self.active_stream)
|
||||
if 0 <= selected_index < len(self.streams):
|
||||
return self.streams[selected_index]
|
||||
return None
|
||||
|
||||
|
||||
class SpeckleSceneSettings(bpy.types.PropertyGroup):
|
||||
def get_scripts(self, context):
|
||||
@@ -118,14 +167,15 @@ class SpeckleSceneSettings(bpy.types.PropertyGroup):
|
||||
for i, user in enumerate(USERS)
|
||||
]
|
||||
|
||||
def set_user(self, context):
|
||||
def user_update_hook(self, context):
|
||||
bpy.ops.speckle.load_user_streams() # type: ignore
|
||||
selection_state.selected_user_id = SelectionState.get_item_id_by_index(self.users, self.active_user)
|
||||
|
||||
active_user: EnumProperty(
|
||||
items=get_users,
|
||||
name="Account",
|
||||
description="Select account",
|
||||
update=set_user,
|
||||
update=user_update_hook,
|
||||
get=None,
|
||||
set=None,
|
||||
) # type: ignore
|
||||
@@ -153,6 +203,8 @@ class SpeckleSceneSettings(bpy.types.PropertyGroup):
|
||||
) # type: ignore
|
||||
|
||||
def get_active_user(self) -> Optional[SpeckleUserObject]:
|
||||
if self.active_user is None:
|
||||
return None
|
||||
selected_index = int(self.active_user)
|
||||
if 0 <= selected_index < len(self.users):
|
||||
return self.users[selected_index]
|
||||
@@ -197,4 +249,63 @@ def get_speckle(context: bpy.types.Context) -> SpeckleSceneSettings:
|
||||
"""
|
||||
Gets the speckle scene object
|
||||
"""
|
||||
return context.scene.speckle #type: ignore
|
||||
return context.scene.speckle #type: ignore
|
||||
|
||||
@dataclass
|
||||
class SelectionState:
|
||||
selected_user_id : Optional[str] = None
|
||||
selected_stream_id : Optional[str] = None
|
||||
selected_branch_id : Optional[str] = None
|
||||
selected_commit_id : Optional[str] = None
|
||||
|
||||
@staticmethod
|
||||
def get_item_id_by_index(collection: bpy.types.PropertyGroup, index: Union[str, int]) -> Optional[str]:
|
||||
if item := SelectionState.get_item_by_index(collection, index):
|
||||
return item.id
|
||||
return None
|
||||
|
||||
@staticmethod
|
||||
def get_item_by_index(collection: bpy.types.PropertyGroup, index: Union[str, int]) -> Optional[bpy.types.PropertyGroup]:
|
||||
items = collection.values()
|
||||
i = int(index)
|
||||
if 0 <= i <= len(items):
|
||||
return items[i]
|
||||
return None
|
||||
|
||||
@staticmethod
|
||||
def get_item_index_by_id(collection: Iterable[SpeckleCommitObject], id: Optional[str]) -> Optional[str]:
|
||||
for index, item in enumerate(collection):
|
||||
if item.id == id:
|
||||
return str(index)
|
||||
return None
|
||||
|
||||
selection_state = SelectionState()
|
||||
|
||||
def restore_selection_state(speckle: SpeckleSceneSettings) -> None:
|
||||
# Restore branch selection state
|
||||
if selection_state.selected_branch_id != None:
|
||||
(active_user, active_stream) = speckle.validate_stream_selection()
|
||||
# print(f"restore_selection_state: {active_user.id=}, {active_stream.id=}")
|
||||
# print(f"restore_selection_state: {selection_state.selected_user_id=}, {selection_state.selected_stream_id=}, {selection_state.selected_branch_id=}, {selection_state.selected_commit_id=}")
|
||||
|
||||
is_same_user = active_user.id == selection_state.selected_user_id
|
||||
|
||||
if is_same_user:
|
||||
active_user.active_stream = int(SelectionState.get_item_index_by_id(active_user.streams, selection_state.selected_stream_id))
|
||||
active_stream = SelectionState.get_item_by_index(active_user.streams, active_user.active_stream)
|
||||
if branch := SelectionState.get_item_index_by_id(active_stream.branches, selection_state.selected_branch_id):
|
||||
active_stream.branch = branch
|
||||
|
||||
# Restore commit selection state
|
||||
if selection_state.selected_commit_id != None:
|
||||
(active_user, active_stream, active_branch) = speckle.validate_branch_selection()
|
||||
# print(f"restore_selection_state: {active_user.id=}, {active_stream.id=}, {active_branch.id=}")
|
||||
# print(f"restore_selection_state: {selection_state.selected_user_id=}, {selection_state.selected_stream_id=}, {selection_state.selected_branch_id=}, {selection_state.selected_commit_id=}")
|
||||
|
||||
is_same_user = active_user.id == selection_state.selected_user_id
|
||||
is_same_stream = active_stream.id == selection_state.selected_stream_id
|
||||
is_same_branch = active_branch.id == selection_state.selected_branch_id
|
||||
|
||||
if is_same_user and is_same_stream and is_same_branch:
|
||||
if commit := SelectionState.get_item_index_by_id(active_branch.commits, selection_state.selected_commit_id):
|
||||
active_branch.commit = commit
|
||||
Reference in New Issue
Block a user