Compare commits

...

53 Commits

Author SHA1 Message Date
Gergő Jedlicska 13421a23a0 build for osx 13 for arm 2022-12-13 16:48:23 +01:00
Gergő Jedlicska 4328c5b8cb only parameter 2022-12-13 13:12:49 +01:00
Gergő Jedlicska 4d44a49988 no CD 2022-12-13 13:11:36 +01:00
Gergő Jedlicska c174101176 pipe the zip 2022-12-13 13:11:18 +01:00
Gergő Jedlicska 62566b1bab top level cp operation 2022-12-13 12:59:27 +01:00
Gergő Jedlicska 88ec39caa4 mkdir 101 2022-12-13 12:52:37 +01:00
Gergő Jedlicska d65920a774 copy 101 2022-12-13 12:42:26 +01:00
Gergő Jedlicska c133689fea force copy 2022-12-13 12:37:52 +01:00
Gergő Jedlicska 6aaf4a5a99 mkdir -p 2022-12-13 12:33:42 +01:00
Gergő Jedlicska 66ec9d5af1 mkdir for the zip folder 2022-12-13 12:31:29 +01:00
Gergő Jedlicska 3cabadf552 fix zipping dir 2022-12-13 12:28:01 +01:00
Gergő Jedlicska c15bb7f045 ci(circleci): fix persist to workspace pathing 2022-12-13 12:21:26 +01:00
Gergő Jedlicska b0aa9cb48f ci(circleci): wtf is microsoft doing with env vars in net6 containers? 2022-12-13 12:05:58 +01:00
Gergő Jedlicska 7bbc286ae2 ci(circleci): fix missing semver in files 2022-12-13 11:48:56 +01:00
Gergő Jedlicska 99b130290f ci(circleci): fix env var restore in deploy 2022-12-13 11:38:51 +01:00
Gergő Jedlicska a0f782af5f make sure semver is set 2022-12-13 11:26:49 +01:00
Gergő Jedlicska f48a5c9582 ci(cirleci): fix mac build triggers 2022-12-13 11:21:12 +01:00
Gergő Jedlicska a9875ffbaa ci(circleci): fix filters 2022-12-13 11:18:13 +01:00
Gergő Jedlicska cee9d83e1d ci(circleci): update details in deploy 2022-12-13 11:09:56 +01:00
Gergő Jedlicska f76b6cf59b publish only usefull stuff 2022-12-12 18:10:52 +01:00
Gergő Jedlicska 8cd9d03806 only zip the published isntaller 2022-12-12 18:08:23 +01:00
Gergő Jedlicska 28ace1f591 add zip again 2022-12-12 18:04:26 +01:00
Gergő Jedlicska beebe10dff add python to dotnet installer 2022-12-12 17:58:33 +01:00
Gergő Jedlicska 1f964bf939 properly saving packaged zip 2022-12-12 17:52:40 +01:00
Gergő Jedlicska 997b94dab9 fix installer patch pathing 2022-12-12 17:46:48 +01:00
Gergő Jedlicska ea962952e5 force remove new lines from installer tags 2022-12-12 17:45:33 +01:00
Gergő Jedlicska 5aff85b586 get proper ci tools 2022-12-12 17:37:28 +01:00
Gergő Jedlicska e1553ed389 getting the specific installer branch 2022-12-12 17:36:20 +01:00
Gergő Jedlicska 88235402f1 ci(circleci): update dependency graph 2022-12-12 17:28:14 +01:00
Gergő Jedlicska a1eea0a6fc ci(circleci): update semver location 2022-12-12 17:26:34 +01:00
Gergő Jedlicska 80496be394 ci(circleci): update filters 2022-12-12 17:21:01 +01:00
Gergő Jedlicska ac63cbe17d ci(circleci): fix naming 2022-12-12 17:18:15 +01:00
Gergő Jedlicska de0c97cdbd ci(circleci): updates 2022-12-12 17:16:51 +01:00
Gergő Jedlicska 14e8445cf2 fix(installer): ensure pip call was commented outy 2022-12-12 16:09:45 +01:00
Gergő Jedlicska ddf908b3f9 ci(circleci): rewrite full ci WIP 2022-12-09 13:58:48 +01:00
Gergő Jedlicska cda621d735 chore(deps): relock again 2022-12-07 14:46:09 +01:00
Gergő Jedlicska 2d052d1379 chore(deps): remove local specklepy dep 2022-12-07 14:44:20 +01:00
Gergő Jedlicska 46ce2bc0df ci(circleci): install dependencies before packaging 2022-12-07 14:38:06 +01:00
Gergő Jedlicska 80e2216aa0 ci(circleci): add new package connector step 2022-12-07 14:32:48 +01:00
Gergő Jedlicska 10d69aa44b add new installer mechanism 2022-12-07 13:52:22 +01:00
Jedd Morgan b1481bd259 Merge pull request #135 from specklesystems/jrm/2.10-fixes
Jrm/2.10 fixes
2022-11-30 20:40:01 +00:00
Jedd Morgan e19fc9ef4e fix(deployment): potential fix for mac releases 2022-11-30 20:38:43 +00:00
Jedd Morgan 448eb856b2 Bumped dependencies 2022-11-30 20:36:07 +00:00
Jedd Morgan 06a7d416c7 Merge pull request #134 from specklesystems/jrm/2.10-fixes
fix(converter): fixed issue with meshes with very high number of vert…
2022-11-30 20:32:42 +00:00
Jedd Morgan 0753436899 fix(converter): fixed issue with meshes with very high number of verts taking an eternity to send
Changed from using sum to extend list functions
2022-11-29 23:54:28 +00:00
Jedd Morgan 40e0a49b11 Merge pull request #130 from specklesystems/jrm/clean-mesh-fix
fix(receive): Fixed issue with Clean Mesh creating duplicated collection
2022-11-17 16:05:56 +00:00
JR-Morgan b17b9c9de4 fix(receive): Fixed issue with Clean Mesh creating duplicated collection 2022-11-17 14:45:17 +00:00
Jedd Morgan f035111ffa Merge pull request #128 from specklesystems/fix-py39
Fixed issue with connector failing to load on Blender 2.93
2022-11-11 12:09:55 +00:00
JR-Morgan fa073f754f Merge remote-tracking branch 'origin' into fix-py39 2022-11-11 02:23:50 +00:00
Jedd Morgan 83919375f9 Merge pull request #129 from specklesystems/jrm/ci/macos
MacOS CI
2022-11-11 02:22:49 +00:00
JR-Morgan defb11bc89 fix: Fixed issue with connector on Blender 2.93 failing due to accidental use of unsupported python features 2022-11-11 02:13:19 +00:00
JR-Morgan 548b3ad352 CI fix for macos slugs 2022-10-24 21:48:25 +01:00
JR-Morgan d2deecf099 added deploy steps for macos 2022-10-24 21:27:38 +01:00
13 changed files with 829 additions and 732 deletions
+171 -259
View File
@@ -1,178 +1,50 @@
version: 2.1
orbs:
python: circleci/python@1.3.2
# Using windows for builds
win: circleci/windows@2.4.0
# Upload artifacts to s3
aws-s3: circleci/aws-s3@2.0.0
commands:
install-specklepy-windows: # Reusable job for installing `specklepy` for windows machines
parameters:
python-version:
type: string
default: "" # leave blank for blender v2.93
steps:
- when:
condition: << parameters.python-version >>
steps:
- run:
name: Upgrade python version << parameters.python-version >>
shell: powershell.exe
command: |
choco upgrade python --version=<< parameters.python-version >>
refreshenv
python --version
- run:
name: Install specklepy into modules directory
shell: powershell.exe
command: |
$pyarr=(python --version).split(' ')[1].split('.')
$pyver=($pyarr[0..1] -join '.')
echo "using python version:" $pyver
$specklepy=(python patch_version.py)
python -m pip install --target=./modules-$pyver specklepy==$specklepy
jobs:
build-connector-win: # Reusable job for basic connectors
executor:
name: win/default # comes with python 3.7.3
shell: cmd.exe
parameters:
slug:
type: string
default: "blender"
installer:
type: boolean
default: false
package-connector:
docker:
- image: cimg/python:3.11.0
steps:
- checkout
- attach_workspace:
at: ./
- install-specklepy-windows
- install-specklepy-windows:
python-version: "3.9.10"
- install-specklepy-windows:
python-version: "3.10.2"
- run:
name: Patch
shell: powershell.exe
command:
| # If no tag, use 0.0.0.1 and don't make any YML (for testing only!)
$tag = if([string]::IsNullOrEmpty($env:CIRCLE_TAG)) { "0.0.0" } else { $env:CIRCLE_TAG }
$semver = if($tag.Contains('/')) {$tag.Split("/")[1] } else { $tag }
$ver = if($semver.Contains('-')) {$semver.Split("-")[0] } else { $semver }
$version = "$($ver).$($env:CIRCLE_BUILD_NUM)"
$channel = if($semver.Contains('-')) { "prerelease" } else { "latest" }
New-Item -Force "speckle-sharp-ci-tools/Installers/blender/$channel.yml" -ItemType File -Value "version: $semver"
echo $semver
python patch_version.py $semver
- run:
name: Installer
shell: cmd.exe #does not work in powershell
command: speckle-sharp-ci-tools\InnoSetup\ISCC.exe speckle-sharp-ci-tools\blender.iss /Sbyparam=$p
- when:
condition: << parameters.installer >>
steps:
- persist_to_workspace:
root: ./
paths:
- speckle-sharp-ci-tools/Installers
build-connector-mac:
macos:
xcode: 12.5.1
parameters:
slug:
type: string
default: "blender-mac"
installername:
type: string
default: "SpeckleBlenderInstall"
runtime:
type: string
default: "osx-x64"
installer:
type: boolean
default: false
steps:
- checkout
- attach_workspace:
at: ./
- run:
name: Install mono
name: Setup SEMVER value
command: |
HOMEBREW_NO_AUTO_UPDATE=1 brew install mono
# Compress build files
- run:
name: Install dotnet
command: curl -sSL https://dot.net/v1/dotnet-install.sh | bash /dev/stdin
- run:
name: Build & Patch Version
command: |
TAG=$(if [ "${CIRCLE_TAG}" ]; then echo $CIRCLE_TAG; else echo "0.0.0"; fi;)
SEMVER=$(echo "$TAG" | sed -e 's/[a-zA-Z-]*\///')
VER=$(echo "$SEMVER" | sed -e 's/-beta//')
VERSION=$(echo $VER.$CIRCLE_BUILD_NUM)
CHANNEL=$(if [[ "$VERSION" == *"-"* ]]; then echo $(cut -d "-" -f2 \<\<\< $VERSION); else echo latest; fi)
mkdir -p speckle-sharp-ci-tools/Installers/<< parameters.slug >>
if [ "${CIRCLE_TAG}" ]; then echo "version: $SEMVER" > "speckle-sharp-ci-tools/Installers/<< parameters.slug >>/$CHANNEL.yml"; fi
SEMVER=$(if [ "${CIRCLE_TAG}" ]; then echo $CIRCLE_TAG; else echo "0.0.0"; fi;)
echo $SEMVER > ./SEMVER
python3 patch_version.py $SEMVER
# update python and package dependencies
- when:
condition:
and:
# - << parameters.installer >>
- equal: [osx-x64, << parameters.runtime >>]
steps:
- run:
name: Install python 3.10
command: |
brew install python@3.10
brew link --overwrite python@3.10
- run:
name: Package specklepy dependencies for blender 3.1 & 3.2
command: |
python3 --version
python3 -m pip install --target=./modules-intel-3.10 specklepy==$(python3 -m patch_version)
zip -r modules-intel-3.10.zip modules-intel-3.10/
cp modules-intel-3.10.zip speckle-sharp-ci-tools/Mac/<<parameters.installername>>/.installationFiles
- run:
name: Zip Connector files
command: |
zip -r << parameters.slug >>.zip bpy_speckle/
name: install dependencies
command: poetry install --only main
- run:
name: Copy connector files to installer
command: |
mkdir -p speckle-sharp-ci-tools/Mac/<<parameters.installername>>/.installationFiles/
cp << parameters.slug >>.zip speckle-sharp-ci-tools/Mac/<<parameters.installername>>/.installationFiles
python3 patch_version.py > speckle-sharp-ci-tools/Mac/<<parameters.installername>>/.installationFiles/specklepy_ver.yml
name: export package dependencies
command: ./export_dependencies.sh
- persist_to_workspace:
root: ./
paths:
- bpy_speckle
- patch_installer.py
- SEMVER
build-connector-zip:
docker:
- image: cimg/python:3.11.0
steps:
- attach_workspace:
at: ./
- run: &restore_semver
name: Restore Semver
command: SEMVER=$(cat ./SEMVER) && echo $SEMVER
- run:
name: Build Mac installer
command: ~/.dotnet/dotnet publish speckle-sharp-ci-tools/Mac/<<parameters.installername>>/<<parameters.installername>>.sln -r << parameters.runtime >> -c Release
- run:
name: Zip installer
command: |
cd speckle-sharp-ci-tools/Mac/<<parameters.installername>>/bin/Release/net6.0/<< parameters.runtime >>/
zip -r << parameters.slug >>.zip ./
- store_artifacts:
path: speckle-sharp-ci-tools/Mac/<<parameters.installername>>/bin/Release/net6.0/<< parameters.runtime >>/<< parameters.slug >>.zip
- run:
name: Copy to installer location
command: |
TAG=$(if [ "${CIRCLE_TAG}" ]; then echo $CIRCLE_TAG; else echo "0.0.0"; fi;)
SEMVER=$(echo "$TAG" | sed -e 's/[a-zA-Z-]*\///')
cp speckle-sharp-ci-tools/Mac/<<parameters.installername>>/bin/Release/net6.0/<< parameters.runtime >>/<< parameters.slug >>.zip speckle-sharp-ci-tools/Installers/<< parameters.slug >>/<< parameters.slug >>-$SEMVER.zip
- when:
condition: << parameters.installer >>
steps:
- persist_to_workspace:
root: ./
paths:
- speckle-sharp-ci-tools/Installers
name: Package to Zip
command: zip -r bpy_speckle.zip bpy_speckle
- persist_to_workspace:
root: ./
paths:
- bpy_speckle.zip
get-ci-tools: # Clones our ci tools and persists them to the workspace
docker:
- image: cimg/base:2021.01
@@ -180,38 +52,89 @@ jobs:
- run: # Could not get ssh to work, so using a personal token
name: Clone
command: git clone https://$GITHUB_TOKEN@github.com/specklesystems/speckle-sharp-ci-tools.git speckle-sharp-ci-tools
- run:
command: cd speckle-sharp-ci-tools && git checkout blender/installer-changes
- persist_to_workspace:
root: ./
paths:
- speckle-sharp-ci-tools
deploy: # Uploads all installers found to S3
docker:
- image: cimg/base:2021.01
build-installer-win:
executor:
name: win/default
shell: cmd.exe
steps:
- attach_workspace:
at: ./
- run:
name: List contents
command: ls -R speckle-sharp-ci-tools/Installers
- aws-s3/copy:
arguments: "--recursive --endpoint=https://$SPACES_REGION.digitaloceanspaces.com --acl public-read"
aws-access-key-id: SPACES_KEY
aws-region: SPACES_REGION
aws-secret-access-key: SPACES_SECRET
from: '"speckle-sharp-ci-tools/Installers/"'
to: s3://speckle-releases/installers/
name: Patch installer
shell: powershell.exe
command: python patch_installer.py (Get-Content -Raw SEMVER)
- run:
name: Installer
shell: cmd.exe #does not work in powershell
command: speckle-sharp-ci-tools\InnoSetup\ISCC.exe speckle-sharp-ci-tools\blender.iss /Sbyparam=$p
- persist_to_workspace:
root: ./
paths:
- speckle-sharp-ci-tools/Installers/blender/blender-*.exe
deploy-manager2:
build-dotnet-installer:
docker:
- image: mcr.microsoft.com/dotnet/sdk:6.0
parameters:
runtime:
type: string
slug:
type: string
installer_path:
type: string
default: speckle-sharp-ci-tools/Mac/SpeckleBlenderInstall
steps:
- attach_workspace:
at: ./
- run: *restore_semver
- run:
name: ensure zip
command: apt update && apt install -y zip
- run:
name: Copy connector files to installer
command: |
mkdir -p << parameters.installer_path >>/.installationFiles
cp bpy_speckle.zip << parameters.installer_path >>/.installationFiles
- run:
name: Build installer
command: dotnet publish <<parameters.installer_path>>/SpeckleBlenderInstall.sln -r << parameters.runtime >> -c Release
# cd <<parameters.installer_path>>/bin/Release/net6.0/<< parameters.runtime >>/publish/
# zip -r << parameters.slug >>-${SEMVER}.zip <<parameters.installer_path>>/bin/Release/net6.0/<< parameters.runtime >>/publish/.
# cd ${CIRCLE_WORKING_DIRECTORY}
- run:
name: Zip installer
command: |
SEMVER=$(cat ./SEMVER)
echo $SEMVER
mkdir -p speckle-sharp-ci-tools/Installers/blender
(cd <<parameters.installer_path>>/bin/Release/net6.0/<< parameters.runtime >>/publish/ && zip -r - ./) > << parameters.slug >>-${SEMVER}.zip
cp << parameters.slug >>-${SEMVER}.zip speckle-sharp-ci-tools/Installers/blender/
- persist_to_workspace:
root: ./
paths:
- speckle-sharp-ci-tools/Installers/blender/<< parameters.slug >>*.zip
deploy-connector:
docker:
- image: mcr.microsoft.com/dotnet/sdk:6.0
parameters:
file_slug:
type: string
os:
type: string
extension:
type: string
arch:
type: string
default: Any
steps:
- checkout
- attach_workspace:
@@ -219,110 +142,99 @@ jobs:
- run:
name: Install Manager Feed CLI
command: dotnet tool install --global Speckle.Manager.Feed
- run: *restore_semver
- run:
name: Upload new version
# this is where the installer gets the semver baked into the file name
command: |
TAG=$(if [ "${CIRCLE_TAG}" ]; then echo $CIRCLE_TAG; else echo "0.0.0"; fi;)
SEMVER=$(echo "$TAG" | sed -e 's/\/[a-zA-Z-]*//')
/root/.dotnet/tools/Speckle.Manager.Feed deploy -s << parameters.slug >> -v ${SEMVER} -u https://releases.speckle.dev/installers/<< parameters.slug >>/<< parameters.slug >>-${SEMVER}.<< parameters.extension >> -o << parameters.os >> -f speckle-sharp-ci-tools/Installers/<< parameters.slug >>/<< parameters.slug >>-${SEMVER}.<< parameters.extension >>
SEMVER=$(cat ./SEMVER)
echo $SEMVER
/root/.dotnet/tools/Speckle.Manager.Feed deploy \
-s blender \
-v ${SEMVER} \
-u https://releases.speckle.dev/installers/blender/<< parameters.file_slug >>-${SEMVER}.<< parameters.extension >> \
-o << parameters.os >> \
-a << parameters.arch >> \
-f speckle-sharp-ci-tools/Installers/blender/<< parameters.file_slug >>-${SEMVER}.<< parameters.extension >>
workflows:
build: # build the installers, but don't persist to workspace for deployment
jobs:
- get-ci-tools:
filters:
branches:
only:
- main
- /ci\/.*/
- build-connector-win:
name: Windows Build
- package-connector:
filters: &build_filters
tags:
only: /([0-9]+)\.([0-9]+)\.([0-9]+)(?:-\w+)?$/
- build-connector-zip:
requires:
- package-connector
filters: *build_filters
- get-ci-tools:
filters: *build_filters
- build-installer-win:
name: Windows Installer Build
requires:
- package-connector
- get-ci-tools
filters:
filters: *build_filters
- deploy-connector:
name: deploy-windows
file_slug: blender
os: WIN
arch: Any
extension: exe
requires:
- Windows Installer Build
- Mac Intel Build
- Mac ARM Build
filters: &deploy_filters
branches:
only:
- main
- /ci\/.*/
- build-connector-mac:
ignore: /.*/
tags:
only: /([0-9]+)\.([0-9]+)\.([0-9]+)(?:-\w+)?$/
- build-dotnet-installer:
name: Mac ARM Build
slug: blender-mac-arm
runtime: osx-arm64
runtime: osx.13-arm64
requires:
- get-ci-tools
- build-connector-mac:
- build-connector-zip
filters: *build_filters
- deploy-connector:
name: deploy-mac-arm
file_slug: blender-mac-arm
os: OSX
arch: Arm
extension: zip
requires:
- Windows Installer Build
- Mac Intel Build
- Mac ARM Build
filters: *deploy_filters
- build-dotnet-installer:
name: Mac Intel Build
slug: blender-mac-intel
runtime: osx-x64
requires:
- get-ci-tools
deploy: # build installers and deploy
jobs:
- get-ci-tools:
filters:
tags:
only: /.*/
branches:
ignore: /.*/
- build-connector-zip
filters: *build_filters
- build-connector-win:
name: Windows Build&Deploy
slug: blender
installer: true
- deploy-connector:
name: deploy-mac-intel
file_slug: blender-mac-intel
os: OSX
arch: Intel
extension: zip
requires:
- get-ci-tools
filters:
tags:
only: /([0-9]+)\.([0-9]+)\.([0-9]+)(?:-\w+)?$/
branches:
ignore: /.*/
- build-connector-mac:
name: Mac ARM Build&Deploy
slug: blender-mac-arm
runtime: osx-arm64
installer: true
requires:
- get-ci-tools
filters:
tags:
only: /([0-9]+)\.([0-9]+)\.([0-9]+)(?:-\w+)?$/
branches:
ignore: /.*/
- build-connector-mac:
name: Mac Intel Build&Deploy
slug: blender-mac-intel
runtime: osx-x64
installer: true
requires:
- get-ci-tools
filters:
tags:
only: /([0-9]+)\.([0-9]+)\.([0-9]+)(?:-\w+)?$/
branches:
ignore: /.*/
- deploy:
requires:
- get-ci-tools
- Windows Build&Deploy
- Mac ARM Build&Deploy
- Mac Intel Build&Deploy
filters:
tags:
only: /([0-9]+)\.([0-9]+)\.([0-9]+)(?:-\w+)?$/
branches:
ignore: /.*/
- deploy-manager2:
slug: blender
os: Win
extension: exe
requires:
- deploy
filters:
tags:
only: /([0-9]+)\.([0-9]+)\.([0-9]+)(?:-\w+)?$/
branches:
ignore: /.*/ # For testing only! /ci\/.*/
- Windows Installer Build
- Mac Intel Build
- Mac ARM Build
filters: *deploy_filters
+3 -1
View File
@@ -11,4 +11,6 @@ __pycache__/
.venv
Installers/
modules/
.tool-versions
.tool-versions
requirements.txt
SEMVER
+11 -9
View File
@@ -1,4 +1,15 @@
import bpy
from bpy_speckle.installer import ensure_dependencies
ensure_dependencies()
from specklepy.logging import metrics
from bpy_speckle.ui import *
from bpy_speckle.properties import *
from bpy_speckle.operators import *
from bpy_speckle.callbacks import *
from bpy.app.handlers import persistent
bl_info = {
"name": "SpeckleBlender 2.0",
@@ -18,15 +29,6 @@ bl_info = {
Import SpeckleBlender classes
"""
from specklepy.api.client import SpeckleClient # , SpeckleCache
from specklepy.logging import metrics
from bpy_speckle.ui import *
from bpy_speckle.properties import *
from bpy_speckle.operators import *
from bpy_speckle.callbacks import *
from bpy.app.handlers import persistent
"""
Add load handler to initialize Speckle when
loading a Blender file
+2 -1
View File
@@ -1,7 +1,8 @@
from typing import Union
from bpy_speckle.convert.to_native import convert_to_native
from specklepy.objects.base import Base
def get_speckle_subobjects(attr: dict | Base, scale: float, name: str) -> list:
def get_speckle_subobjects(attr: Union[dict, Base], scale: float, name: str) -> list:
subobjects = []
keys = attr.keys() if isinstance(attr, dict) else attr.get_dynamic_member_names()
for key in keys:
+8 -7
View File
@@ -1,4 +1,5 @@
import math
from typing import Union
from bpy_speckle.functions import get_scale_length, _report
import mathutils
import bpy, bmesh, bpy_types
@@ -38,7 +39,7 @@ def can_convert_to_native(speckle_object: Base) -> bool:
return False
def convert_to_native(speckle_object: Base, name: str = None) -> list | Object | None:
def convert_to_native(speckle_object: Base, name: Optional[str] = None) -> Optional[Union[list, Object]]:
speckle_type = type(speckle_object)
speckle_name = (
name
@@ -63,7 +64,7 @@ def convert_to_native(speckle_object: Base, name: str = None) -> list | Object |
# not making it hidden, so it will get added on send as i think it might be helpful? can reconsider
converted = []
for item in elements:
if(item is None):
if not isinstance(item, Base):
continue
item.parent_speckle_type = speckle_object.speckle_type
blender_object = convert_to_native(item)
@@ -154,7 +155,7 @@ def mesh_to_native(speckle_mesh: Mesh, name: str, scale=1.0) -> bpy.types.Mesh:
return blender_mesh
def line_to_native(speckle_curve: Line, blender_curve: bpy.types.Curve, scale: float) -> bpy.types.Spline | None:
def line_to_native(speckle_curve: Line, blender_curve: bpy.types.Curve, scale: float) -> Optional[bpy.types.Spline]:
line = blender_curve.splines.new("POLY")
line.points.add(1)
@@ -177,7 +178,7 @@ def line_to_native(speckle_curve: Line, blender_curve: bpy.types.Curve, scale: f
return line
def polyline_to_native(scurve: Polyline, bcurve: bpy.types.Curve, scale: float) -> bpy.types.Spline | None:
def polyline_to_native(scurve: Polyline, bcurve: bpy.types.Curve, scale: float) -> Optional[bpy.types.Spline]:
if value := scurve.value:
N = len(value) // 3
@@ -201,7 +202,7 @@ def polyline_to_native(scurve: Polyline, bcurve: bpy.types.Curve, scale: float)
return polyline
def nurbs_to_native(scurve: Curve, bcurve: bpy.types.Curve, scale: float) -> bpy.types.Spline | None:
def nurbs_to_native(scurve: Curve, bcurve: bpy.types.Curve, scale: float) -> Optional[bpy.types.Spline]:
if points := scurve.points:
N = len(points) // 3
@@ -230,7 +231,7 @@ def nurbs_to_native(scurve: Curve, bcurve: bpy.types.Curve, scale: float) -> bpy
return nurbs
def arc_to_native(rcurve: Arc, bcurve: bpy.types.Curve, scale: float) -> bpy.types.Spline | None:
def arc_to_native(rcurve: Arc, bcurve: bpy.types.Curve, scale: float) -> Optional[bpy.types.Spline]:
# TODO: improve Blender representation of arc
plane = rcurve.plane
@@ -325,7 +326,7 @@ def icurve_to_native_spline(speckle_curve: Base, blender_curve: bpy.types.Curve,
return arc_to_native(speckle_curve, blender_curve, scale)
def icurve_to_native(speckle_curve: Base, name=None, scale=1.0) -> Curve | None:
def icurve_to_native(speckle_curve: Base, name=None, scale=1.0) -> Optional[Curve]:
curve_type = type(speckle_curve)
if curve_type not in SUPPORTED_CURVES:
_report(f"Unsupported curve type: {curve_type}")
+29 -16
View File
@@ -1,5 +1,6 @@
from typing import Optional
import bpy
from bpy.types import MeshVertColor, MeshVertex, Object
from bpy.types import Depsgraph, MeshVertColor, MeshVertex, Object
from specklepy.objects.geometry import Mesh, Curve, Interval, Box, Point, Polyline
from specklepy.objects.other import *
from bpy_speckle.functions import _report
@@ -14,7 +15,7 @@ UNITS = "m"
CAN_CONVERT_TO_SPECKLE = ("MESH", "CURVE", "EMPTY")
def convert_to_speckle(blender_object: Object, scale: float, units: str, desgraph=None) -> list | None:
def convert_to_speckle(blender_object: Object, scale: float, units: str, desgraph: Optional[Depsgraph]) -> Optional[list]:
global UNITS
UNITS = units
blender_type = blender_object.type
@@ -64,12 +65,15 @@ def mesh_to_speckle(blender_object: Object, data: bpy.types.Mesh, scale=1.0) ->
verts = [tuple(mat @ x.co * scale) for x in data.vertices]
flattend_verts = []
for row in verts: flattend_verts.extend(row)
faces = [p.vertices for p in data.polygons]
unit_system = bpy.context.scene.unit_settings.system
sm = Mesh(
name=blender_object.name,
vertices=list(sum(verts, ())),
vertices=flattend_verts,
faces=[],
colors=[],
textureCoordinates=[],
@@ -100,7 +104,7 @@ def mesh_to_speckle(blender_object: Object, data: bpy.types.Mesh, scale=1.0) ->
return [sm]
def bezier_to_speckle(matrix: List[float], spline: bpy.types.Spline, scale: float, name:str = None) -> Curve:
def bezier_to_speckle(matrix: List[float], spline: bpy.types.Spline, scale: float, name: Optional[str] = None) -> Curve:
degree = 3
closed = spline.use_cyclic_u
@@ -120,9 +124,12 @@ def bezier_to_speckle(matrix: List[float], spline: bpy.types.Spline, scale: floa
tuple(matrix @ spline.bezier_points[0].co * scale),
)
)
num_points = len(points)
flattend_points = []
for row in points: flattend_points.extend(row)
knot_count = num_points + degree - 1
knots = [0] * knot_count
@@ -136,7 +143,7 @@ def bezier_to_speckle(matrix: List[float], spline: bpy.types.Spline, scale: floa
degree=degree,
closed=spline.use_cyclic_u,
periodic=spline.use_cyclic_u,
points=list(sum(points, ())), # magic (flatten list of tuples)
points=flattend_points,
weights=[1] * num_points,
knots=knots,
rational=False,
@@ -149,7 +156,7 @@ def bezier_to_speckle(matrix: List[float], spline: bpy.types.Spline, scale: floa
)
def nurbs_to_speckle(matrix: List[float], spline: bpy.types.Spline, scale: float, name:str = None) -> Curve:
def nurbs_to_speckle(matrix: List[float], spline: bpy.types.Spline, scale: float, name: Optional[str] = None) -> Curve:
knots = make_knots(spline)
points = [tuple(matrix @ pt.co.xyz * scale) for pt in spline.points]
degree = spline.order_u - 1
@@ -157,12 +164,15 @@ def nurbs_to_speckle(matrix: List[float], spline: bpy.types.Spline, scale: float
length = spline.calc_length()
domain = Interval(start=0, end=length, totalChildrenCount=0)
flattend_points = []
for row in points: flattend_points.extend(row)
return Curve(
name=name,
degree=degree,
closed=spline.use_cyclic_u,
periodic=spline.use_cyclic_u,
points=list(sum(points, ())), # magic (flatten list of tuples)
points=flattend_points,
weights=[pt.weight for pt in spline.points],
knots=knots,
rational=False,
@@ -175,15 +185,18 @@ def nurbs_to_speckle(matrix: List[float], spline: bpy.types.Spline, scale: float
)
def poly_to_speckle(matrix: List[float], spline: bpy.types.Spline, scale: float, name: str = None) -> Polyline:
def poly_to_speckle(matrix: List[float], spline: bpy.types.Spline, scale: float, name: Optional[str] = None) -> Polyline:
points = [tuple(matrix @ pt.co.xyz * scale) for pt in spline.points]
flattend_points = []
for row in points: flattend_points.extend(row)
length = spline.calc_length()
domain = Interval(start=0, end=length, totalChildrenCount=0)
return Polyline(
name=name,
closed=bool(spline.use_cyclic_u),
value=list(sum(points, ())), # magic (flatten list of tuples)
value=list(flattend_points),
length=length,
domain=domain,
bbox=Box(area=0.0, volume=0.0),
@@ -192,7 +205,7 @@ def poly_to_speckle(matrix: List[float], spline: bpy.types.Spline, scale: float,
)
def icurve_to_speckle(blender_object: Object, data: bpy.types.Curve, scale=1.0) -> List[Base] | None:
def icurve_to_speckle(blender_object: Object, data: bpy.types.Curve, scale=1.0) -> Optional[List[Base]]:
UNITS = "m" if bpy.context.scene.unit_settings.system == "METRIC" else "ft"
if blender_object.type != "CURVE":
@@ -221,7 +234,7 @@ def icurve_to_speckle(blender_object: Object, data: bpy.types.Curve, scale=1.0)
return curves
def ngons_to_speckle_polylines(blender_object: Object, data: bpy.types.Mesh, scale=1.0) -> List[Polyline] | None:
def ngons_to_speckle_polylines(blender_object: Object, data: bpy.types.Mesh, scale=1.0) -> Optional[List[Polyline]]:
UNITS = "m" if bpy.context.scene.unit_settings.system == "METRIC" else "ft"
if blender_object.type != "MESH":
@@ -253,7 +266,7 @@ def ngons_to_speckle_polylines(blender_object: Object, data: bpy.types.Mesh, sca
return polylines
def material_to_speckle(blender_object: Object) -> RenderMaterial | None:
def material_to_speckle(blender_object: Object) -> Optional[RenderMaterial]:
"""Create and return a render material from a blender object"""
if not getattr(blender_object.data, "materials", None):
return None
@@ -295,7 +308,7 @@ def transform_to_speckle(blender_transform: List[float], scale=1.0) -> Transform
def block_def_to_speckle(blender_definition: bpy.types.Collection, scale=1.0) -> BlockDefinition:
geometry = []
for geo in blender_definition.objects:
geometry.extend(convert_to_speckle(geo, scale, UNITS))
geometry.extend(convert_to_speckle(geo, scale, UNITS, None))
block_def = BlockDefinition(
units=UNITS,
name=blender_definition.name,
@@ -307,7 +320,7 @@ def block_def_to_speckle(blender_definition: bpy.types.Collection, scale=1.0) ->
return block_def
def block_instance_to_speckle(blender_instance: Object, scale=1.0):
def block_instance_to_speckle(blender_instance: Object, scale=1.0) -> BlockInstance:
return BlockInstance(
blockDefinition=block_def_to_speckle(
blender_instance.instance_collection, scale
@@ -318,7 +331,7 @@ def block_instance_to_speckle(blender_instance: Object, scale=1.0):
)
def empty_to_speckle(blender_object: Object, scale=1.0) -> BlockInstance | None:
def empty_to_speckle(blender_object: Object, scale=1.0) -> Optional[BlockInstance]:
# probably an instance collection (block) so let's try it
try:
geo = blender_object.instance_collection.objects.items()
+125
View File
@@ -0,0 +1,125 @@
from pathlib import Path
from importlib import import_module
import bpy
import sys
print("Starting Speckle Blender installation")
print(sys.executable)
PYTHON_PATH = sys.executable
def modules_path() -> Path:
modules_path = Path(bpy.utils.script_path_user(), "addons", "modules")
modules_path.mkdir(exist_ok=True, parents=True)
# set user modules path at beginning of paths for earlier hit
if sys.path[1] != modules_path:
sys.path.insert(1, modules_path)
return modules_path
print(f"Found blender modules path {modules_path()}")
def is_pip_available() -> bool:
try:
import_module("pip") # noqa F401
return True
except ImportError:
return False
def ensure_pip() -> None:
print("Installing pip... "),
from subprocess import run
completed_process = run([PYTHON_PATH, "-m", "ensurepip"])
if completed_process.returncode == 0:
print("Successfully installed pip")
else:
raise Exception("Failed to install pip.")
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
def install_requirements() -> None:
# set up addons/modules under the user
# script path. Here we'll install the
# dependencies
path = modules_path()
print(f"Installing Speckle dependencies to {path}")
from subprocess import run
completed_process = run(
[
PYTHON_PATH,
"-m",
"pip",
"install",
"-t",
str(path),
"-r",
str(get_requirements_path()),
],
capture_output=True,
text=True,
)
if completed_process.returncode != 0:
print("Please try manually installing speckle-blender")
raise Exception(
"""
Failed to install speckle-blender.
See console for manual install instruction.
"""
)
def install_dependencies() -> None:
if not is_pip_available():
ensure_pip()
install_requirements()
def _import_dependencies() -> None:
import_module("specklepy")
# the code above doesn't work for now, it fails on importing graphql-core
# despite that, the connector seams to be working as expected
# But it would be nice to make this solution work
# it would ensure that all dependencies are fully loaded
# requirements = get_requirements_path().read_text()
# reqs = [
# req.split(" ; ")[0].split("==")[0].split("[")[0].replace("-", "_")
# for req in requirements.split("\n")
# if req and not req.startswith(" ")
# ]
# for req in reqs:
# print(req)
# import_module("specklepy")
def ensure_dependencies() -> None:
try:
_import_dependencies()
print("Found all dependencies, proceed with loading")
except ImportError:
print("Failed to load all dependencies, trying to install them...")
install_dependencies()
raise Exception("Please restart Blender.")
if __name__ == "__main__":
ensure_dependencies()
+4 -8
View File
@@ -49,7 +49,7 @@ def get_objects_collections(base: Base) -> Dict[str, list]:
return collections
def get_objects_nested_lists(items: list, parent_col: bpy.types.Collection = None) -> List:
def get_objects_nested_lists(items: list, parent_col: Optional[bpy.types.Collection] = None) -> List:
"""For handling the weird nested lists that come from Grasshopper"""
objects = []
@@ -66,7 +66,7 @@ def get_objects_nested_lists(items: list, parent_col: bpy.types.Collection = Non
return objects
def get_objects_collections_recursive(base: Base, parent_col: bpy.types.Collection = None) -> List:
def get_objects_collections_recursive(base: Base, parent_col: Optional[bpy.types.Collection] = None) -> List:
"""Recursively create collections based on the dynamic members on nested `Base` objects within the root commit object"""
# if it's a convertable (registered) class and not just a plain `Base`, return the object itself
if can_convert_to_native(base):
@@ -96,8 +96,8 @@ def get_objects_collections_recursive(base: Base, parent_col: bpy.types.Collecti
return objects
ObjectCallback = Callable[[bpy.types.Context, Object, Base], Object] | None
ReceiveCompleteCallback = Callable[[bpy.types.Context, Dict[str, Object]], None] | None
ObjectCallback = Optional[Callable[[bpy.types.Context, Object, Base], Object]]
ReceiveCompleteCallback = Optional[Callable[[bpy.types.Context, Dict[str, Object]], None]]
def get_receive_funcs(context: Context, created_objects: Dict[str, Object]) -> tuple[ObjectCallback, ReceiveCompleteCallback]:
"""
@@ -310,10 +310,6 @@ class ReceiveStreamObjects(bpy.types.Operator):
if obj.type != 'MESH':
continue
# This seems to be required inorder to select the object here
if obj.name not in context.scene.collection.objects:
context.scene.collection.objects.link(obj)
obj.select_set(True, view_layer=context.scene.view_layers[0])
active = obj
+4
View File
@@ -0,0 +1,4 @@
#!/usr/bin/env bash
set -e -o pipefail
poetry export --only main -o bpy_speckle/requirements.txt
+20
View File
@@ -0,0 +1,20 @@
import sys
from pathlib import Path
def patch_installer(tag: str):
"""Patches the installer with the correct connector version and specklepy version"""
tag = tag.replace("\n", "")
iss_file = "speckle-sharp-ci-tools/blender.iss"
iss_path = Path(iss_file)
lines = iss_path.read_text().split("\n")
lines.insert(12, f'#define AppVersion "{tag.split("-")[0]}"')
lines.insert(13, f'#define AppInfoVersion "{tag}"')
iss_path.write_text("\n".join(lines))
print(f"Patched installer with connector v{tag}")
if __name__ == "__main__":
tag = sys.argv[1]
patch_installer(tag)
-36
View File
@@ -1,7 +1,6 @@
import re
import sys
def patch_connector(tag):
"""Patches the connector version within the connector init file"""
bpy_file = "bpy_speckle/__init__.py"
@@ -19,48 +18,13 @@ def patch_connector(tag):
with open(bpy_file, "w") as file:
file.writelines(lines)
def patch_installer(tag):
"""Patches the installer with the correct connector version and specklepy version"""
iss_file = "speckle-sharp-ci-tools/blender.iss"
py_tag = get_specklepy_version()
with open(iss_file, "r") as file:
lines = file.readlines()
lines.insert(11, f'#define SpecklepyVersion "{py_tag}"\n')
lines.insert(12, f'#define AppVersion "{tag.split("-")[0]}"\n')
lines.insert(13, f'#define AppInfoVersion "{tag}"\n')
with open(iss_file, "w") as file:
file.writelines(lines)
print(f"Patched installer with connector v{tag} and specklepy v{py_tag}")
def get_specklepy_version():
"""Get version of specklepy to install from the pyproject.toml"""
version = "2.3.3"
with open("pyproject.toml", "r") as f:
lines = [line for line in f if line.startswith("specklepy = ")]
if not lines:
raise Exception("Could not find specklepy in pyproject.toml")
match = re.search(r"[0-9]+(\.[0-9]+)*", lines[0])
if match:
version = match[0]
return version
def main():
if len(sys.argv) < 2:
print(get_specklepy_version())
return
tag = sys.argv[1]
if not re.match(r"([0-9]+)\.([0-9]+)\.([0-9]+)", tag):
raise ValueError(f"Invalid tag provided: {tag}")
print(f"Patching version: {tag}")
patch_connector(tag.split("-")[0])
patch_installer(tag)
if __name__ == "__main__":
Generated
+443 -386
View File
File diff suppressed because it is too large Load Diff
+9 -9
View File
@@ -7,17 +7,17 @@ license = "Apache-2.0"
[tool.poetry.dependencies]
python = ">=3.8, <4.0.0"
specklepy = "^2.9.0"
specklepy = "^2.9.1"
[tool.poetry.dev-dependencies]
devtools = "^0.6.1"
numpy = "^1.20.2"
fake-bpy-module-latest = "^20220401"
black = "^21.12b0"
pylint = "^2.12.2"
# [tool.poetry.group.local_specklepy.dependencies]
# specklepy = {path = "../specklepy", develop = true}
[tool.poetry.group.local_specklepy.dependencies]
specklepy = {path = "../specklepy", develop = true}
[tool.poetry.group.dev.dependencies]
numpy = "^1.23.5"
fake-bpy-module-latest = "^20221006"
black = "^22.10.0"
pylint = "^2.15.7"
ruff = "^0.0.166"
[build-system]
requires = ["poetry-core>=1.0.0"]