diff --git a/.github/workflows/BlackFormat.yml b/.github/workflows/BlackFormat.yml index 151d49269e..99050f95ed 100644 --- a/.github/workflows/BlackFormat.yml +++ b/.github/workflows/BlackFormat.yml @@ -9,11 +9,31 @@ on: jobs: blackFormatChecker: - name: Black Formatter for Python Exporter + name: Black Format Validation runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 - - uses: psf/black@stable + - name: Checkout Code + uses: actions/checkout@v2 + - name: Python Setup + uses: actions/setup-python@v2 + with: + python-version: '3.9' + - name: Setup Isort + run: python3 -m pip install isort + - name: Validate Isort Formatting + run: python3 ./exporter/SynthesisFusionAddin/tools/verifyIsortFormatting.py + id: isort-format-validation + continue-on-error: true + - name: Check Isort Formatting Validation + run: | + if [ ${{ steps.isort-format-validation.outcome }} == "success" ]; then + echo "Isort Formatting Validation Passed" + else + echo "Isort Formatting Validation Failed" + exit 1 + fi + - name: Validate Black Formatting + uses: psf/black@stable with: options: "--check" src: "./exporter/SynthesisFusionAddin/" diff --git a/exporter/SynthesisFusionAddin/README.md b/exporter/SynthesisFusionAddin/README.md index ccff41f411..8f40acf4cd 100644 --- a/exporter/SynthesisFusionAddin/README.md +++ b/exporter/SynthesisFusionAddin/README.md @@ -78,9 +78,10 @@ Contact us for information on how to use the packaging script to obfuscate all o ### How to Format -We format using a Python formatter called `black` [![Code style: black](https://img.shields.io/badge/code%20style-black-000000.svg)](https://github.com/psf/black) +We format using a Python formatter called `black` [![Code style: black](https://img.shields.io/badge/code%20style-black-000000.svg)](https://github.com/psf/black) in conjunction with [`isort`](https://pycqa.github.io/isort/). -- install by `pip3 install black` or `pip install black` -- use `black ./src`, Formats all files in src directory +- install by `pip3 install black && pip3 install isort` or `pip install black && pip install isort` +- use `isort .` followed by `black .` to format all relevant exporter python files. + - or, alternatively, run `python ./tools/format.py` to do this for you! __Note: black will always ignore files in the proto/proto_out folder since google formats those__ diff --git a/exporter/SynthesisFusionAddin/Synthesis.py b/exporter/SynthesisFusionAddin/Synthesis.py index 4711a8bae5..335a2416ce 100644 --- a/exporter/SynthesisFusionAddin/Synthesis.py +++ b/exporter/SynthesisFusionAddin/Synthesis.py @@ -1,16 +1,17 @@ -from .src.general_imports import root_logger, gm, INTERNAL_ID, APP_NAME, DESCRIPTION - -from .src.UI import HUI, Handlers, Camera, Helper, ConfigCommand -from .src.UI.Toolbar import Toolbar -from .src.Types.OString import OString -from .src.configure import setAnalytics, unload_config - +import importlib.util +import logging.handlers +import os +import traceback from shutil import rmtree -import logging.handlers, traceback, importlib.util, os -from .src.UI import MarkingMenu import adsk.core +from .src.configure import setAnalytics, unload_config +from .src.general_imports import APP_NAME, DESCRIPTION, INTERNAL_ID, gm, root_logger +from .src.Types.OString import OString +from .src.UI import HUI, Camera, ConfigCommand, Handlers, Helper, MarkingMenu +from .src.UI.Toolbar import Toolbar + def run(_): """## Entry point to application from Fusion. @@ -32,9 +33,7 @@ def run(_): MarkingMenu.setupMarkingMenu(ui) except: - logging.getLogger(f"{INTERNAL_ID}").error( - "Failed:\n{}".format(traceback.format_exc()) - ) + logging.getLogger(f"{INTERNAL_ID}").error("Failed:\n{}".format(traceback.format_exc())) def stop(_): @@ -74,9 +73,7 @@ def stop(_): path = os.path.abspath(os.path.dirname(__file__)) - path_proto_files = os.path.abspath( - os.path.join(os.path.dirname(__file__), "..", "proto", "proto_out") - ) + path_proto_files = os.path.abspath(os.path.join(os.path.dirname(__file__), "..", "proto", "proto_out")) if path in sys.path: sys.path.remove(path) @@ -85,9 +82,7 @@ def stop(_): sys.path.remove(path_proto_files) except: - logging.getLogger(f"{INTERNAL_ID}").error( - "Failed:\n{}".format(traceback.format_exc()) - ) + logging.getLogger(f"{INTERNAL_ID}").error("Failed:\n{}".format(traceback.format_exc())) def unregister_all() -> None: @@ -105,9 +100,7 @@ def unregister_all() -> None: tab.deleteMe() except: - logging.getLogger(f"{INTERNAL_ID}").error( - "Failed:\n{}".format(traceback.format_exc()) - ) + logging.getLogger(f"{INTERNAL_ID}").error("Failed:\n{}".format(traceback.format_exc())) def register_ui() -> None: diff --git a/exporter/SynthesisFusionAddin/proto/deps.py b/exporter/SynthesisFusionAddin/proto/deps.py index 5b26d159bc..ea6da5a406 100644 --- a/exporter/SynthesisFusionAddin/proto/deps.py +++ b/exporter/SynthesisFusionAddin/proto/deps.py @@ -1,11 +1,12 @@ +import logging import os import platform -import logging from pathlib import Path -from src.general_imports import INTERNAL_ID +import adsk.core +import adsk.fusion -import adsk.core, adsk.fusion +from src.general_imports import INTERNAL_ID system = platform.system() @@ -21,8 +22,8 @@ def getPythonFolder() -> str: """ # Thank you Kris Kaplan - import sys import importlib.machinery + import sys osPath = importlib.machinery.PathFinder.find_spec("os", sys.path).origin @@ -32,9 +33,7 @@ def getPythonFolder() -> str: elif system == "Darwin": pythonFolder = f"{Path(osPath).parents[2]}/bin" else: - raise ImportError( - "Unsupported platform! This add-in only supports windows and macos" - ) + raise ImportError("Unsupported platform! This add-in only supports windows and macos") logging.getLogger(f"{INTERNAL_ID}").debug(f"Python Folder -> {pythonFolder}") return pythonFolder @@ -89,9 +88,7 @@ def installCross(pipDeps: list) -> bool: try: pythonFolder = getPythonFolder() except ImportError as e: - logging.getLogger(f"{INTERNAL_ID}").error( - f"Failed to download dependencies: {e.msg}" - ) + logging.getLogger(f"{INTERNAL_ID}").error(f"Failed to download dependencies: {e.msg}") return False if system == "Darwin": # macos @@ -108,9 +105,9 @@ def installCross(pipDeps: list) -> bool: executeCommand([f'"{pythonFolder}/python"', f'"{pythonFolder}/get-pip.py"']) - pythonExecutable = 'python' + pythonExecutable = "python" if system == "Windows": - pythonExecutable = 'python.exe' + pythonExecutable = "python.exe" for depName in pipDeps: progressBar.progressValue += 1 @@ -120,7 +117,7 @@ def installCross(pipDeps: list) -> bool: # os.path.join needed for varying system path separators installResult = executeCommand( [ - f"\"{os.path.join(pythonFolder, pythonExecutable)}\"", + f'"{os.path.join(pythonFolder, pythonExecutable)}"', "-m", "pip", "install", @@ -128,9 +125,7 @@ def installCross(pipDeps: list) -> bool: ] ) if installResult != 0: - logging.getLogger(f"{INTERNAL_ID}").warn( - f'Dep installation "{depName}" exited with code "{installResult}"' - ) + logging.getLogger(f"{INTERNAL_ID}").warn(f'Dep installation "{depName}" exited with code "{installResult}"') if system == "Darwin": pipAntiDeps = ["dataclasses", "typing"] @@ -142,7 +137,7 @@ def installCross(pipDeps: list) -> bool: adsk.doEvents() uninstallResult = executeCommand( [ - f"\"{os.path.join(pythonFolder, pythonExecutable)}\"", + f'"{os.path.join(pythonFolder, pythonExecutable)}"', "-m", "pip", "uninstall", @@ -165,7 +160,7 @@ def installCross(pipDeps: list) -> bool: def _checkDeps() -> bool: try: - from .proto_out import joint_pb2, assembly_pb2, types_pb2, material_pb2 + from .proto_out import assembly_pb2, joint_pb2, material_pb2, types_pb2 return True except ImportError: @@ -174,10 +169,11 @@ def _checkDeps() -> bool: try: import logging.handlers + import google.protobuf import pkg_resources - from .proto_out import joint_pb2, assembly_pb2, types_pb2, material_pb2 + from .proto_out import assembly_pb2, joint_pb2, material_pb2, types_pb2 except ImportError or ModuleNotFoundError: installCross(["protobuf==4.23.3"]) - from .proto_out import joint_pb2, assembly_pb2, types_pb2, material_pb2 + from .proto_out import assembly_pb2, joint_pb2, material_pb2, types_pb2 diff --git a/exporter/SynthesisFusionAddin/pyproject.toml b/exporter/SynthesisFusionAddin/pyproject.toml index b5a222b7c7..01222be485 100644 --- a/exporter/SynthesisFusionAddin/pyproject.toml +++ b/exporter/SynthesisFusionAddin/pyproject.toml @@ -1,8 +1,22 @@ [build-system] -requires = ["protobuf", "black", "pyminifier"] +requires = ["protobuf", "isort", "black", "pyminifier"] + +[tool.isort] +py_version = 39 +profile = "black" +skip = [ + "*.git/", + "*.venv", + "/build/", + "/docs/", + "/logs/", + ".vscode/", + "/dist/", + "proto/proto_out", +] [tool.black] -line-length = 90 +line-length = 120 target-version = ['py39'] include = '\.pyi?$' exclude = ''' @@ -13,10 +27,9 @@ exclude = ''' | build | docs | logs - | proto | .vscode | dist - | src/proto_out + | proto_out )/ ) -''' \ No newline at end of file +''' diff --git a/exporter/SynthesisFusionAddin/requirements.txt b/exporter/SynthesisFusionAddin/requirements.txt index cf28d6f7d4..75a3dbe98a 100644 --- a/exporter/SynthesisFusionAddin/requirements.txt +++ b/exporter/SynthesisFusionAddin/requirements.txt @@ -1,2 +1,2 @@ black -pyminifier \ No newline at end of file +pyminifier diff --git a/exporter/SynthesisFusionAddin/src/Analytics/alert.py b/exporter/SynthesisFusionAddin/src/Analytics/alert.py index 05c269dfa3..c134f1906b 100644 --- a/exporter/SynthesisFusionAddin/src/Analytics/alert.py +++ b/exporter/SynthesisFusionAddin/src/Analytics/alert.py @@ -1,5 +1,5 @@ -from ..general_imports import gm from ..configure import setAnalytics +from ..general_imports import gm def showAnalyticsAlert(): diff --git a/exporter/SynthesisFusionAddin/src/Analytics/poster.py b/exporter/SynthesisFusionAddin/src/Analytics/poster.py index 5c80138eb4..1c5056ff72 100644 --- a/exporter/SynthesisFusionAddin/src/Analytics/poster.py +++ b/exporter/SynthesisFusionAddin/src/Analytics/poster.py @@ -1,7 +1,10 @@ -from ..general_imports import * -from ..configure import CID, ANALYTICS, DEBUG +import sys +import urllib + +import adsk.core -import urllib, sys, adsk.core +from ..configure import ANALYTICS, CID, DEBUG +from ..general_imports import * # Reference https://developers.google.com/analytics/devguides/collection/protocol/v1/parameters @@ -169,9 +172,7 @@ def __send(self, body) -> bool: if DEBUG: self.logger.debug(f"Sending request: \n {url}") - req = urllib.request.Request( - f"{self.url}/collect?{body}", data=b"", headers=headers - ) + req = urllib.request.Request(f"{self.url}/collect?{body}", data=b"", headers=headers) # makes the request response = urllib.request.urlopen(req) diff --git a/exporter/SynthesisFusionAddin/src/Analyzer/sniff.py b/exporter/SynthesisFusionAddin/src/Analyzer/sniff.py index 83200053c4..01d64dadf0 100644 --- a/exporter/SynthesisFusionAddin/src/Analyzer/sniff.py +++ b/exporter/SynthesisFusionAddin/src/Analyzer/sniff.py @@ -1,18 +1,21 @@ """ Takes in a given function call and times and tests the memory allocations to get data """ -from ..general_imports import * +import inspect +import linecache +import os +import time +import tracemalloc from time import time -import tracemalloc, time, linecache, os, inspect + +from ..general_imports import * class Sniffer: def __init__(self): self.logger = logging.getLogger(f"{INTERNAL_ID}.Analyzer.Sniffer") - (self.filename, self.line_number, _, self.lines, _) = inspect.getframeinfo( - inspect.currentframe().f_back.f_back - ) + (self.filename, self.line_number, _, self.lines, _) = inspect.getframeinfo(inspect.currentframe().f_back.f_back) self.stopped = False diff --git a/exporter/SynthesisFusionAddin/src/Analyzer/timer.py b/exporter/SynthesisFusionAddin/src/Analyzer/timer.py index b89099ee7c..41bb86135f 100644 --- a/exporter/SynthesisFusionAddin/src/Analyzer/timer.py +++ b/exporter/SynthesisFusionAddin/src/Analyzer/timer.py @@ -1,9 +1,11 @@ """ Takes in a given function call and times and tests the memory allocations to get data """ -from ..general_imports import * +import inspect +import os from time import time -import os, inspect + +from ..general_imports import * class Timer: diff --git a/exporter/SynthesisFusionAddin/src/GlobalManager.py b/exporter/SynthesisFusionAddin/src/GlobalManager.py index 33ccdbfa71..b438a2eb23 100644 --- a/exporter/SynthesisFusionAddin/src/GlobalManager.py +++ b/exporter/SynthesisFusionAddin/src/GlobalManager.py @@ -1,7 +1,10 @@ """ Initializes the global variables that are set in the run method to reduce hanging commands. """ -import adsk.core, adsk.fusion, traceback import inspect +import traceback + +import adsk.core +import adsk.fusion from .general_imports import * from .strings import * diff --git a/exporter/SynthesisFusionAddin/src/Parser/ExporterOptions.py b/exporter/SynthesisFusionAddin/src/Parser/ExporterOptions.py index f01835a0ef..31ed4cd0c4 100644 --- a/exporter/SynthesisFusionAddin/src/Parser/ExporterOptions.py +++ b/exporter/SynthesisFusionAddin/src/Parser/ExporterOptions.py @@ -3,14 +3,14 @@ These options are saved per-design and are passed to the parser upon design export. """ -import os import json +import os import platform -from typing import get_origin +from dataclasses import dataclass, field, fields from enum import Enum, EnumType -from dataclasses import dataclass, fields, field -import adsk.core +from typing import get_origin +import adsk.core from adsk.fusion import CalculationAccuracy, TriangleMeshQualityOptions from ..strings import INTERNAL_ID @@ -77,7 +77,9 @@ class ModelHierarchy(Enum): @dataclass class ExporterOptions: - fileLocation: str = field(default=(os.getenv("HOME") if platform.system() == "Windows" else os.path.expanduser("~"))) + fileLocation: str = field( + default=(os.getenv("HOME") if platform.system() == "Windows" else os.path.expanduser("~")) + ) name: str = field(default=None) version: str = field(default=None) materials: int = field(default=0) @@ -94,13 +96,9 @@ class ExporterOptions: exportAsPart: bool = field(default=False) hierarchy: ModelHierarchy = field(default=ModelHierarchy.FusionAssembly) - visualQuality: TriangleMeshQualityOptions = field( - default=TriangleMeshQualityOptions.LowQualityTriangleMesh - ) + visualQuality: TriangleMeshQualityOptions = field(default=TriangleMeshQualityOptions.LowQualityTriangleMesh) physicalDepth: PhysicalDepth = field(default=PhysicalDepth.AllOccurrence) - physicalCalculationLevel: CalculationAccuracy = field( - default=CalculationAccuracy.LowCalculationAccuracy - ) + physicalCalculationLevel: CalculationAccuracy = field(default=CalculationAccuracy.LowCalculationAccuracy) def readFromDesign(self) -> None: designAttributes = adsk.core.Application.get().activeProduct.attributes @@ -125,11 +123,7 @@ def writeToDesign(self) -> None: if isinstance(obj, Enum) else ( { - key: ( - lambda value: ( - value if not isinstance(value, Enum) else value.value - ) - )(value) + key: (lambda value: (value if not isinstance(value, Enum) else value.value))(value) for key, value in obj.__dict__.items() } if hasattr(obj, "__dict__") @@ -150,26 +144,17 @@ def _makeObjectFromJson(self, objectType: type, data: any) -> any: ): # Required to catch `fusion.TriangleMeshQualityOptions` return data elif get_origin(objectType) is list: - return [ - self._makeObjectFromJson(objectType.__args__[0], item) for item in data - ] + return [self._makeObjectFromJson(objectType.__args__[0], item) for item in data] newObject = objectType() - attrs = [ - x - for x in dir(newObject) - if not x.startswith("__") and not callable(getattr(newObject, x)) - ] + attrs = [x for x in dir(newObject) if not x.startswith("__") and not callable(getattr(newObject, x))] for attr in attrs: currType = objectType.__annotations__.get(attr, None) if get_origin(currType) is list: setattr( newObject, attr, - [ - self._makeObjectFromJson(currType.__args__[0], item) - for item in data[attr] - ], + [self._makeObjectFromJson(currType.__args__[0], item) for item in data[attr]], ) elif currType in primitives: setattr(newObject, attr, data[attr]) diff --git a/exporter/SynthesisFusionAddin/src/Parser/SynthesisParser/Components.py b/exporter/SynthesisFusionAddin/src/Parser/SynthesisParser/Components.py index 0e2970eff9..c6c741b0b2 100644 --- a/exporter/SynthesisFusionAddin/src/Parser/SynthesisParser/Components.py +++ b/exporter/SynthesisFusionAddin/src/Parser/SynthesisParser/Components.py @@ -1,15 +1,19 @@ # Contains all of the logic for mapping the Components / Occurrences -import adsk.core, adsk.fusion, uuid, logging, traceback -from proto.proto_out import assembly_pb2, types_pb2, material_pb2, joint_pb2 - -from .Utilities import * -from ..ExporterOptions import ExporterOptions, ExportMode +import logging +import traceback +import uuid from typing import * -from . import PhysicalProperties +import adsk.core +import adsk.fusion + +from proto.proto_out import assembly_pb2, joint_pb2, material_pb2, types_pb2 -from .PDMessage import PDMessage from ...Analyzer.timer import TimeThis +from ..ExporterOptions import ExporterOptions, ExportMode +from . import PhysicalProperties +from .PDMessage import PDMessage +from .Utilities import * # TODO: Impelement Material overrides @@ -98,9 +102,7 @@ def _ParseComponentRoot( if occur.isLightBulbOn: child_node = types_pb2.Node() - __parseChildOccurrence( - occur, progressDialog, options, partsData, material_map, child_node - ) + __parseChildOccurrence(occur, progressDialog, options, partsData, material_map, child_node) node.children.append(child_node) @@ -133,9 +135,7 @@ def __parseChildOccurrence( if occurrence.appearance: try: - part.appearance = "{}_{}".format( - occurrence.appearance.name, occurrence.appearance.id - ) + part.appearance = "{}_{}".format(occurrence.appearance.name, occurrence.appearance.id) except: part.appearance = "default" # TODO: Add phyical_material parser @@ -168,9 +168,7 @@ def __parseChildOccurrence( if occur.isLightBulbOn: child_node = types_pb2.Node() - __parseChildOccurrence( - occur, progressDialog, options, partsData, material_map, child_node - ) + __parseChildOccurrence(occur, progressDialog, options, partsData, material_map, child_node) node.children.append(child_node) @@ -206,9 +204,7 @@ def _ParseBRep( plainmesh_out.indices.extend(mesh.nodeIndices) plainmesh_out.uv.extend(mesh.textureCoordinatesAsFloat) except: - logging.getLogger("{INTERNAL_ID}.Parser.BrepBody").error( - "Failed:\n{}".format(traceback.format_exc()) - ) + logging.getLogger("{INTERNAL_ID}.Parser.BrepBody").error("Failed:\n{}".format(traceback.format_exc())) def _ParseMesh( @@ -229,14 +225,10 @@ def _ParseMesh( plainmesh_out.indices.extend(mesh.nodeIndices) plainmesh_out.uv.extend(mesh.textureCoordinatesAsFloat) except: - logging.getLogger("{INTERNAL_ID}.Parser.BrepBody").error( - "Failed:\n{}".format(traceback.format_exc()) - ) + logging.getLogger("{INTERNAL_ID}.Parser.BrepBody").error("Failed:\n{}".format(traceback.format_exc())) -def _MapRigidGroups( - rootComponent: adsk.fusion.Component, joints: joint_pb2.Joints -) -> None: +def _MapRigidGroups(rootComponent: adsk.fusion.Component, joints: joint_pb2.Joints) -> None: groups = rootComponent.allRigidGroups for group in groups: mira_group = joint_pb2.RigidGroup() diff --git a/exporter/SynthesisFusionAddin/src/Parser/SynthesisParser/JointHierarchy.py b/exporter/SynthesisFusionAddin/src/Parser/SynthesisParser/JointHierarchy.py index 4ed2717f35..93d320b987 100644 --- a/exporter/SynthesisFusionAddin/src/Parser/SynthesisParser/JointHierarchy.py +++ b/exporter/SynthesisFusionAddin/src/Parser/SynthesisParser/JointHierarchy.py @@ -1,11 +1,17 @@ -from .Utilities import guid_component, guid_occurrence -from ...general_imports import * -import adsk.core, adsk.fusion, traceback, logging, enum +import enum +import logging +import traceback from typing import * + +import adsk.core +import adsk.fusion + +from proto.proto_out import joint_pb2, types_pb2 + +from ...general_imports import * from ..ExporterOptions import ExporterOptions from .PDMessage import PDMessage -from proto.proto_out import types_pb2, joint_pb2 - +from .Utilities import guid_component, guid_occurrence # ____________________________ DATA TYPES __________________ @@ -82,9 +88,7 @@ class JointRelationship(enum.Enum): class DynamicOccurrenceNode(GraphNode): - def __init__( - self, occurrence: adsk.fusion.Occurrence, isGround=False, previous=None - ): + def __init__(self, occurrence: adsk.fusion.Occurrence, isGround=False, previous=None): super().__init__(occurrence) self.isGround = isGround self.name = occurrence.name @@ -124,9 +128,7 @@ def getConnectedAxisTokens(self) -> list: class DynamicEdge(GraphEdge): - def __init__( - self, relationship: OccurrenceRelationship, node: DynamicOccurrenceNode - ): + def __init__(self, relationship: OccurrenceRelationship, node: DynamicOccurrenceNode): super().__init__(relationship, node) # should print all in this class @@ -205,9 +207,7 @@ def __init__(self, design): self.grounded = searchForGrounded(design.rootComponent) if self.grounded is None: - gm.ui.messageBox( - "There is not currently a Grounded Component in the assembly, stopping kinematic export." - ) + gm.ui.messageBox("There is not currently a Grounded Component in the assembly, stopping kinematic export.") raise RuntimeWarning("There is no grounded component") return @@ -245,9 +245,7 @@ def __init__(self, design): # self.groundSimNode.printLink() def __getAllJoints(self): - for joint in list(self.design.rootComponent.allJoints) + list( - self.design.rootComponent.allAsBuiltJoints - ): + for joint in list(self.design.rootComponent.allJoints) + list(self.design.rootComponent.allAsBuiltJoints): try: if joint and joint.occurrenceOne and joint.occurrenceTwo: occurrenceOne = joint.occurrenceOne @@ -257,17 +255,13 @@ def __getAllJoints(self): if occurrenceOne is None: try: - occurrenceOne = ( - joint.geometryOrOriginOne.entityOne.assemblyContext - ) + occurrenceOne = joint.geometryOrOriginOne.entityOne.assemblyContext except: pass if occurrenceTwo is None: try: - occurrenceTwo = ( - joint.geometryOrOriginTwo.entityOne.assemblyContext - ) + occurrenceTwo = joint.geometryOrOriginTwo.entityOne.assemblyContext except: pass @@ -312,8 +306,7 @@ def _linkAllAxis(self): def _recurseLink(self, simNode: SimulationNode): connectedAxisNodes = [ - self.simulationNodesRef.get(componentKeys, None) - for componentKeys in simNode.data.getConnectedAxisTokens() + self.simulationNodesRef.get(componentKeys, None) for componentKeys in simNode.data.getConnectedAxisTokens() ] for connectedAxis in connectedAxisNodes: # connected is the occurrence @@ -363,9 +356,9 @@ def _populateNode( edge = DynamicEdge(relationship, node) prev.edges.append(edge) return - elif ( - (occ.entityToken in self.dynamicJoints.keys()) and (prev is not None) - ) or self.currentTraversal.get(occ.entityToken) is not None: + elif ((occ.entityToken in self.dynamicJoints.keys()) and (prev is not None)) or self.currentTraversal.get( + occ.entityToken + ) is not None: return node = DynamicOccurrenceNode(occ) @@ -373,9 +366,7 @@ def _populateNode( self.currentTraversal[occ.entityToken] = True for occurrence in occ.childOccurrences: - self._populateNode( - occurrence, node, OccurrenceRelationship.TRANSFORM, is_ground=is_ground - ) + self._populateNode(occurrence, node, OccurrenceRelationship.TRANSFORM, is_ground=is_ground) # if not is_ground: # THIS IS A BUG - OCCURRENCE ACCESS VIOLATION try: @@ -396,18 +387,11 @@ def _populateNode( connection = joint.occurrenceOne if connection is not None: - if ( - prev is None - or connection.entityToken != prev.data.entityToken - ): + if prev is None or connection.entityToken != prev.data.entityToken: self._populateNode( connection, node, - ( - OccurrenceRelationship.CONNECTION - if rigid - else OccurrenceRelationship.NEXT - ), + (OccurrenceRelationship.CONNECTION if rigid else OccurrenceRelationship.NEXT), is_ground=is_ground, ) else: @@ -489,9 +473,7 @@ def BuildJointPartHierarchy( except Warning: return False except: - logging.getLogger(f"{INTERNAL_ID}.JointHierarchy").error( - "Failed:\n{}".format(traceback.format_exc()) - ) + logging.getLogger(f"{INTERNAL_ID}.JointHierarchy").error("Failed:\n{}".format(traceback.format_exc())) def populateJoint(simNode: SimulationNode, joints: joint_pb2.Joints, progressDialog): @@ -507,9 +489,7 @@ def populateJoint(simNode: SimulationNode, joints: joint_pb2.Joints, progressDia progressDialog.update() if not proto_joint: - logging.getLogger(f"{INTERNAL_ID}.JointHierarchy").error( - f"Could not find protobuf joint for {simNode.name}" - ) + logging.getLogger(f"{INTERNAL_ID}.JointHierarchy").error(f"Could not find protobuf joint for {simNode.name}") return root = types_pb2.Node() @@ -518,9 +498,7 @@ def populateJoint(simNode: SimulationNode, joints: joint_pb2.Joints, progressDia # print(f"Configuring {proto_joint.info.name}") # construct body tree if possible - createTreeParts( - simNode.data, OccurrenceRelationship.CONNECTION, root, progressDialog - ) + createTreeParts(simNode.data, OccurrenceRelationship.CONNECTION, root, progressDialog) proto_joint.parts.nodes.append(root) @@ -539,10 +517,7 @@ def createTreeParts( raise RuntimeError("User canceled export") # if it's the next part just exit early for our own sanity - if ( - relationship == OccurrenceRelationship.NEXT - or dynNode.data.isLightBulbOn == False - ): + if relationship == OccurrenceRelationship.NEXT or dynNode.data.isLightBulbOn == False: return # set the occurrence / component id to reference the part diff --git a/exporter/SynthesisFusionAddin/src/Parser/SynthesisParser/Joints.py b/exporter/SynthesisFusionAddin/src/Parser/SynthesisParser/Joints.py index 7e67388aa1..7ba62c1f5e 100644 --- a/exporter/SynthesisFusionAddin/src/Parser/SynthesisParser/Joints.py +++ b/exporter/SynthesisFusionAddin/src/Parser/SynthesisParser/Joints.py @@ -22,16 +22,19 @@ """ -import adsk.fusion, adsk.core, traceback, uuid - -from proto.proto_out import types_pb2, joint_pb2, signal_pb2, motor_pb2, assembly_pb2 +import traceback +import uuid from typing import Union +import adsk.core +import adsk.fusion + +from proto.proto_out import assembly_pb2, joint_pb2, motor_pb2, signal_pb2, types_pb2 + from ...general_imports import * -from .Utilities import fill_info, construct_info, guid_occurrence -from .PDMessage import PDMessage from ..ExporterOptions import ExporterOptions, JointParentType, SignalType - +from .PDMessage import PDMessage +from .Utilities import construct_info, fill_info, guid_occurrence # Need to take in a graphcontainer # Need to create a new base node for each Joint Instance @@ -79,9 +82,7 @@ def populateJoints( # Add the rest of the dynamic objects - for joint in list(design.rootComponent.allJoints) + list( - design.rootComponent.allAsBuiltJoints - ): + for joint in list(design.rootComponent.allJoints) + list(design.rootComponent.allAsBuiltJoints): if joint.isSuppressed: continue @@ -115,10 +116,7 @@ def populateJoints( signal.io = signal_pb2.IOType.OUTPUT # really could just map the enum to a friggin string - if ( - parse_joints.signalType != SignalType.PASSIVE - and assembly.dynamic - ): + if parse_joints.signalType != SignalType.PASSIVE and assembly.dynamic: if parse_joints.signalType == SignalType.CAN: signal.device_type = signal_pb2.DeviceType.CANBUS elif parse_joints.signalType == SignalType.PWM: @@ -136,18 +134,14 @@ def populateJoints( # else: # signals.signal_map.remove(guid) - _addJointInstance( - joint, joint_instance, joint_definition, signals, options - ) + _addJointInstance(joint, joint_instance, joint_definition, signals, options) # adds information for joint motion and limits _motionFromJoint(joint.jointMotion, joint_definition) except: err_msg = "Failed:\n{}".format(traceback.format_exc()) - logging.getLogger(f"{INTERNAL_ID}.JointParser").error( - "Failed:\n{}".format(traceback.format_exc()) - ) + logging.getLogger(f"{INTERNAL_ID}.JointParser").error("Failed:\n{}".format(traceback.format_exc())) continue @@ -212,9 +206,7 @@ def _addJointInstance( joint_definition.user_data.data["wheel"] = "true" # Must convert type 'enum' to int to store wheelType in mirabuf - joint_definition.user_data.data["wheelType"] = str( - wheel.wheelType.value - 1 - ) + joint_definition.user_data.data["wheelType"] = str(wheel.wheelType.value - 1) # if it exists get it and overwrite the signal type if joint_instance.signal_reference: @@ -248,9 +240,7 @@ def _addRigidGroup(joint: adsk.fusion.Joint, assembly: assembly_pb2.Assembly): assembly.data.joints.rigid_groups.append(mira_group) -def _motionFromJoint( - fusionMotionDefinition: adsk.fusion.JointMotion, proto_joint: joint_pb2.Joint -) -> None: +def _motionFromJoint(fusionMotionDefinition: adsk.fusion.JointMotion, proto_joint: joint_pb2.Joint) -> None: # if fusionJoint.geometryOrOriginOne.objectType == "adsk::fusion::JointGeometry" # create the DOF depending on what kind of information the joint has @@ -264,16 +254,12 @@ def _motionFromJoint( 6: noop, # TODO: Implement } - fillJointMotionFunc = fillJointMotionFuncSwitcher.get( - fusionMotionDefinition.jointType, lambda: None - ) + fillJointMotionFunc = fillJointMotionFuncSwitcher.get(fusionMotionDefinition.jointType, lambda: None) fillJointMotionFunc(fusionMotionDefinition, proto_joint) -def fillRevoluteJointMotion( - revoluteMotion: adsk.fusion.RevoluteJointMotion, proto_joint: joint_pb2.Joint -): +def fillRevoluteJointMotion(revoluteMotion: adsk.fusion.RevoluteJointMotion, proto_joint: joint_pb2.Joint): """#### Fill Protobuf revolute joint motion data Args: @@ -315,9 +301,7 @@ def fillRevoluteJointMotion( dof.axis.z = int(rotationAxis == 1) -def fillSliderJointMotion( - sliderMotion: adsk.fusion.SliderJointMotion, proto_joint: joint_pb2.Joint -) -> None: +def fillSliderJointMotion(sliderMotion: adsk.fusion.SliderJointMotion, proto_joint: joint_pb2.Joint) -> None: """#### Fill Protobuf slider joint motion data Args: @@ -388,9 +372,7 @@ def _searchForGrounded( return None -def _jointOrigin( - fusionJoint: Union[adsk.fusion.Joint, adsk.fusion.AsBuiltJoint] -) -> adsk.core.Point3D: +def _jointOrigin(fusionJoint: Union[adsk.fusion.Joint, adsk.fusion.AsBuiltJoint]) -> adsk.core.Point3D: """#### Joint Origin Internal Finder that was orignally created for Synthesis by Liam Wang Args: @@ -402,8 +384,7 @@ def _jointOrigin( geometryOrOrigin = ( ( fusionJoint.geometryOrOriginOne - if fusionJoint.geometryOrOriginOne.objectType - == "adsk::fusion::JointGeometry" + if fusionJoint.geometryOrOriginOne.objectType == "adsk::fusion::JointGeometry" else fusionJoint.geometryOrOriginTwo ) if fusionJoint.objectType == "adsk::fusion::Joint" @@ -422,9 +403,7 @@ def _jointOrigin( newEnt = ent.createForAssemblyContext(fusionJoint.occurrenceOne) min = newEnt.boundingBox.minPoint max = newEnt.boundingBox.maxPoint - org = adsk.core.Point3D.create( - (max.x + min.x) / 2.0, (max.y + min.y) / 2.0, (max.z + min.z) / 2.0 - ) + org = adsk.core.Point3D.create((max.x + min.x) / 2.0, (max.y + min.y) / 2.0, (max.z + min.z) / 2.0) return org # ent.startVertex.geometry else: return geometryOrOrigin.origin @@ -439,19 +418,11 @@ def _jointOrigin( else: # adsk::fusion::JointOrigin origin = geometryOrOrigin.geometry.origin # todo: Is this the correct way to calculate a joint origin's true location? Why isn't this exposed in the API? - offsetX = ( - 0 if geometryOrOrigin.offsetX is None else geometryOrOrigin.offsetX.value - ) - offsetY = ( - 0 if geometryOrOrigin.offsetY is None else geometryOrOrigin.offsetY.value - ) - offsetZ = ( - 0 if geometryOrOrigin.offsetZ is None else geometryOrOrigin.offsetZ.value - ) + offsetX = 0 if geometryOrOrigin.offsetX is None else geometryOrOrigin.offsetX.value + offsetY = 0 if geometryOrOrigin.offsetY is None else geometryOrOrigin.offsetY.value + offsetZ = 0 if geometryOrOrigin.offsetZ is None else geometryOrOrigin.offsetZ.value # noinspection PyArgumentList - return adsk.core.Point3D.create( - origin.x + offsetX, origin.y + offsetY, origin.z + offsetZ - ) + return adsk.core.Point3D.create(origin.x + offsetX, origin.y + offsetY, origin.z + offsetZ) def createJointGraph( @@ -487,13 +458,8 @@ def createJointGraph( current_node = node_map[supplied_joint.jointToken] if supplied_joint.parent == JointParentType.ROOT: node_map["ground"].children.append(node_map[supplied_joint.jointToken]) - elif ( - node_map[supplied_joint.parent.value] is not None - and node_map[supplied_joint.jointToken] is not None - ): - node_map[supplied_joint.parent].children.append( - node_map[supplied_joint.jointToken] - ) + elif node_map[supplied_joint.parent.value] is not None and node_map[supplied_joint.jointToken] is not None: + node_map[supplied_joint.parent].children.append(node_map[supplied_joint.jointToken]) else: logging.getLogger("JointHierarchy").error( f"Cannot construct hierarhcy because of detached tree at : {supplied_joint.jointToken}" @@ -504,9 +470,7 @@ def createJointGraph( joint_tree.nodes.append(node) -def addWheelsToGraph( - wheels: list, rootNode: types_pb2.Node, joint_tree: types_pb2.GraphContainer -): +def addWheelsToGraph(wheels: list, rootNode: types_pb2.Node, joint_tree: types_pb2.GraphContainer): for wheel in wheels: # wheel name # wheel signal diff --git a/exporter/SynthesisFusionAddin/src/Parser/SynthesisParser/Materials.py b/exporter/SynthesisFusionAddin/src/Parser/SynthesisParser/Materials.py index 45e909e0eb..b3199a1f9d 100644 --- a/exporter/SynthesisFusionAddin/src/Parser/SynthesisParser/Materials.py +++ b/exporter/SynthesisFusionAddin/src/Parser/SynthesisParser/Materials.py @@ -1,13 +1,16 @@ # Should contain Physical and Apperance materials ? -import adsk, logging, traceback, math +import logging +import math +import traceback -from .Utilities import * -from .. import ExporterOptions +import adsk -from ...general_imports import INTERNAL_ID +from proto.proto_out import material_pb2 +from ...general_imports import INTERNAL_ID +from .. import ExporterOptions from .PDMessage import PDMessage -from proto.proto_out import material_pb2 +from .Utilities import * OPACITY_RAMPING_CONSTANT = 14.0 @@ -97,31 +100,17 @@ def getPhysicalMaterialData(fusion_material, proto_material, options): """ Mechanical Properties """ - mechanicalProperties.young_mod = materialProperties.itemById( - "structural_Young_modulus" - ).value - mechanicalProperties.poisson_ratio = materialProperties.itemById( - "structural_Poisson_ratio" - ).value - mechanicalProperties.shear_mod = materialProperties.itemById( - "structural_Shear_modulus" - ).value - mechanicalProperties.density = materialProperties.itemById( - "structural_Density" - ).value - mechanicalProperties.damping_coefficient = materialProperties.itemById( - "structural_Damping_coefficient" - ).value + mechanicalProperties.young_mod = materialProperties.itemById("structural_Young_modulus").value + mechanicalProperties.poisson_ratio = materialProperties.itemById("structural_Poisson_ratio").value + mechanicalProperties.shear_mod = materialProperties.itemById("structural_Shear_modulus").value + mechanicalProperties.density = materialProperties.itemById("structural_Density").value + mechanicalProperties.damping_coefficient = materialProperties.itemById("structural_Damping_coefficient").value """ Strength Properties """ - strengthProperties.yield_strength = materialProperties.itemById( - "structural_Minimum_yield_stress" - ).value - strengthProperties.tensile_strength = materialProperties.itemById( - "structural_Minimum_tensile_strength" - ).value + strengthProperties.yield_strength = materialProperties.itemById("structural_Minimum_yield_stress").value + strengthProperties.tensile_strength = materialProperties.itemById("structural_Minimum_tensile_strength").value """ strengthProperties.thermal_treatment = materialProperties.itemById( "structural_Thermally_treated" @@ -129,9 +118,9 @@ def getPhysicalMaterialData(fusion_material, proto_material, options): """ except: - logging.getLogger( - f"{INTERNAL_ID}.Parser.Materials.getPhysicalMaterialData" - ).error("Failed:\n{}".format(traceback.format_exc())) + logging.getLogger(f"{INTERNAL_ID}.Parser.Materials.getPhysicalMaterialData").error( + "Failed:\n{}".format(traceback.format_exc()) + ) def _MapAllAppearances( @@ -224,9 +213,7 @@ def getMaterialAppearance( baseColor = properties.itemById("transparent_color").value transparent_distance = properties.itemById("transparent_distance").value - opac = (255.0 * transparent_distance) / ( - transparent_distance + OPACITY_RAMPING_CONSTANT - ) + opac = (255.0 * transparent_distance) / (transparent_distance + OPACITY_RAMPING_CONSTANT) if opac > 255: opac = 255 elif opac < 0: @@ -242,11 +229,7 @@ def getMaterialAppearance( color.A = baseColor.opacity else: for prop in fusionAppearance.appearanceProperties: - if ( - (prop.name == "Color") - and (prop.value is not None) - and (prop.id != "surface_albedo") - ): + if (prop.name == "Color") and (prop.value is not None) and (prop.id != "surface_albedo"): baseColor = prop.value color.R = baseColor.red color.G = baseColor.green diff --git a/exporter/SynthesisFusionAddin/src/Parser/SynthesisParser/PDMessage.py b/exporter/SynthesisFusionAddin/src/Parser/SynthesisParser/PDMessage.py index d5057709da..ad441fc901 100644 --- a/exporter/SynthesisFusionAddin/src/Parser/SynthesisParser/PDMessage.py +++ b/exporter/SynthesisFusionAddin/src/Parser/SynthesisParser/PDMessage.py @@ -28,12 +28,7 @@ def __init__( self.currentMessage = "working..." - self.finalValue = ( - self.componentCount - + self.occurrenceCount - + self.materialCount - + self.appearanceCount - ) + self.finalValue = self.componentCount + self.occurrenceCount + self.materialCount + self.appearanceCount self.currentValue = 0 self.progressDialog = progressDialog @@ -43,13 +38,9 @@ def _format(self): # TABS DO NOTHING HALP out = f"{self.assemblyName} parsing:\n" out += f"\t Components: \t[ {self.currentCompCount} / {self.componentCount} ]\n" - out += ( - f"\t Occurrences: \t[ {self.currentOccCount} / {self.occurrenceCount} ]\n" - ) + out += f"\t Occurrences: \t[ {self.currentOccCount} / {self.occurrenceCount} ]\n" out += f"\t Materials: \t[ {self.currentMatCount} / {self.materialCount} ]\n" - out += ( - f"\t Appearances: \t[ {self.currentAppCount} / {self.appearanceCount} ]\n" - ) + out += f"\t Appearances: \t[ {self.currentAppCount} / {self.appearanceCount} ]\n" out += f"{self.currentMessage}" return out diff --git a/exporter/SynthesisFusionAddin/src/Parser/SynthesisParser/Parser.py b/exporter/SynthesisFusionAddin/src/Parser/SynthesisParser/Parser.py index 70f5e54062..a925f5b119 100644 --- a/exporter/SynthesisFusionAddin/src/Parser/SynthesisParser/Parser.py +++ b/exporter/SynthesisFusionAddin/src/Parser/SynthesisParser/Parser.py @@ -1,18 +1,17 @@ -import adsk.core, adsk.fusion -import traceback, gzip - -from ...general_imports import * +import gzip +import traceback +import adsk.core +import adsk.fusion from google.protobuf.json_format import MessageToJson from proto.proto_out import assembly_pb2, types_pb2 +from ...general_imports import * from ...UI.Camera import captureThumbnail, clearIconCache - -from . import Materials, Components, Joints, JointHierarchy, PDMessage - -from .Utilities import * from ..ExporterOptions import ExporterOptions, ExportMode +from . import Components, JointHierarchy, Joints, Materials, PDMessage +from .Utilities import * class Parser: @@ -54,9 +53,7 @@ def export(self) -> bool: progressDialog.title = "Exporting to Synthesis Format" progressDialog.minimumValue = 0 progressDialog.maximumValue = totalIterations - progressDialog.show( - "Synthesis Export", "Currently on %v of %m", 0, totalIterations - ) + progressDialog.show("Synthesis Export", "Currently on %v of %m", 0, totalIterations) # this is the formatter for the progress dialog now self.pdMessage = PDMessage.PDMessage( @@ -198,37 +195,19 @@ def export(self) -> bool: joint_hierarchy_out = f"{joint_hierarchy_out} |- ground\n" else: newnode = assembly_out.data.joints.joint_instances[node.value] - jointdefinition = assembly_out.data.joints.joint_definitions[ - newnode.joint_reference - ] + jointdefinition = assembly_out.data.joints.joint_definitions[newnode.joint_reference] - wheel_ = ( - " wheel : true" - if (jointdefinition.user_data.data["wheel"] != "") - else "" - ) + wheel_ = " wheel : true" if (jointdefinition.user_data.data["wheel"] != "") else "" joint_hierarchy_out = f"{joint_hierarchy_out} |- {jointdefinition.info.name} type: {jointdefinition.joint_motion_type} {wheel_}\n" for child in node.children: if child.value == "ground": - joint_hierarchy_out = ( - f"{joint_hierarchy_out} |---> ground\n" - ) + joint_hierarchy_out = f"{joint_hierarchy_out} |---> ground\n" else: - newnode = assembly_out.data.joints.joint_instances[ - child.value - ] - jointdefinition = ( - assembly_out.data.joints.joint_definitions[ - newnode.joint_reference - ] - ) - wheel_ = ( - " wheel : true" - if (jointdefinition.user_data.data["wheel"] != "") - else "" - ) + newnode = assembly_out.data.joints.joint_instances[child.value] + jointdefinition = assembly_out.data.joints.joint_definitions[newnode.joint_reference] + wheel_ = " wheel : true" if (jointdefinition.user_data.data["wheel"] != "") else "" joint_hierarchy_out = f"{joint_hierarchy_out} |---> {jointdefinition.info.name} type: {jointdefinition.joint_motion_type} {wheel_}\n" joint_hierarchy_out += "\n\n" diff --git a/exporter/SynthesisFusionAddin/src/Parser/SynthesisParser/PhysicalProperties.py b/exporter/SynthesisFusionAddin/src/Parser/SynthesisParser/PhysicalProperties.py index 4ff71be8b7..afd9489909 100644 --- a/exporter/SynthesisFusionAddin/src/Parser/SynthesisParser/PhysicalProperties.py +++ b/exporter/SynthesisFusionAddin/src/Parser/SynthesisParser/PhysicalProperties.py @@ -16,17 +16,19 @@ """ -import adsk, logging, traceback +import logging +import traceback +from typing import Union + +import adsk from proto.proto_out import types_pb2 -from typing import Union + from ...general_imports import INTERNAL_ID def GetPhysicalProperties( - fusionObject: Union[ - adsk.fusion.BRepBody, adsk.fusion.Occurrence, adsk.fusion.Component - ], + fusionObject: Union[adsk.fusion.BRepBody, adsk.fusion.Occurrence, adsk.fusion.Component], physicalProperties: types_pb2.PhysicalProperties, level=1, ): diff --git a/exporter/SynthesisFusionAddin/src/Parser/SynthesisParser/RigidGroup.py b/exporter/SynthesisFusionAddin/src/Parser/SynthesisParser/RigidGroup.py index 5d93aaea0f..7e8f592466 100644 --- a/exporter/SynthesisFusionAddin/src/Parser/SynthesisParser/RigidGroup.py +++ b/exporter/SynthesisFusionAddin/src/Parser/SynthesisParser/RigidGroup.py @@ -12,9 +12,12 @@ - Success """ -import adsk.core, adsk.fusion, logging +import logging from typing import * +import adsk.core +import adsk.fusion + from proto.proto_out import assembly_pb2 diff --git a/exporter/SynthesisFusionAddin/src/Parser/SynthesisParser/Utilities.py b/exporter/SynthesisFusionAddin/src/Parser/SynthesisParser/Utilities.py index 4cff7f0655..7169cd4085 100644 --- a/exporter/SynthesisFusionAddin/src/Parser/SynthesisParser/Utilities.py +++ b/exporter/SynthesisFusionAddin/src/Parser/SynthesisParser/Utilities.py @@ -1,5 +1,7 @@ -import math, uuid -from adsk.core import Vector3D, Base +import math +import uuid + +from adsk.core import Base, Vector3D from adsk.fusion import Component, Occurrence # from proto.proto_out import types_pb2 @@ -60,18 +62,18 @@ def construct_info(name: str, proto_obj, version=5, fus_object=None, GUID=None) # My previous function was alot more optimized however now I realize the bug was this doesn't work well with degrees def euler_to_quaternion(r): (yaw, pitch, roll) = (r[0], r[1], r[2]) - qx = math.sin(roll / 2) * math.cos(pitch / 2) * math.cos(yaw / 2) - math.cos( - roll / 2 - ) * math.sin(pitch / 2) * math.sin(yaw / 2) - qy = math.cos(roll / 2) * math.sin(pitch / 2) * math.cos(yaw / 2) + math.sin( - roll / 2 - ) * math.cos(pitch / 2) * math.sin(yaw / 2) - qz = math.cos(roll / 2) * math.cos(pitch / 2) * math.sin(yaw / 2) - math.sin( - roll / 2 - ) * math.sin(pitch / 2) * math.cos(yaw / 2) - qw = math.cos(roll / 2) * math.cos(pitch / 2) * math.cos(yaw / 2) + math.sin( - roll / 2 - ) * math.sin(pitch / 2) * math.sin(yaw / 2) + qx = math.sin(roll / 2) * math.cos(pitch / 2) * math.cos(yaw / 2) - math.cos(roll / 2) * math.sin( + pitch / 2 + ) * math.sin(yaw / 2) + qy = math.cos(roll / 2) * math.sin(pitch / 2) * math.cos(yaw / 2) + math.sin(roll / 2) * math.cos( + pitch / 2 + ) * math.sin(yaw / 2) + qz = math.cos(roll / 2) * math.cos(pitch / 2) * math.sin(yaw / 2) - math.sin(roll / 2) * math.sin( + pitch / 2 + ) * math.cos(yaw / 2) + qw = math.cos(roll / 2) * math.cos(pitch / 2) * math.cos(yaw / 2) + math.sin(roll / 2) * math.sin( + pitch / 2 + ) * math.sin(yaw / 2) return [qx, qy, qz, qw] @@ -133,9 +135,7 @@ def throwZero(): Raises: RuntimeError: Error describing the issue """ - raise RuntimeError( - "While computing the quaternion the trace was reported as 0 which is invalid" - ) + raise RuntimeError("While computing the quaternion the trace was reported as 0 which is invalid") def spatial_to_quaternion(mat): @@ -193,9 +193,7 @@ def spatial_to_quaternion(mat): return round(qx, 13), round(-qy, 13), round(-qz, 13), round(qw, 13) else: - raise RuntimeError( - "Supplied matrix to spatial_to_quaternion is not a 1D spatial matrix in size." - ) + raise RuntimeError("Supplied matrix to spatial_to_quaternion is not a 1D spatial matrix in size.") def normalize_quaternion(x, y, z, w): diff --git a/exporter/SynthesisFusionAddin/src/Types/OString.py b/exporter/SynthesisFusionAddin/src/Types/OString.py index 47cdcdeb48..ba547fe953 100644 --- a/exporter/SynthesisFusionAddin/src/Types/OString.py +++ b/exporter/SynthesisFusionAddin/src/Types/OString.py @@ -1,6 +1,7 @@ -from typing import Union -import os, platform +import os import pathlib +import platform +from typing import Union class OString: @@ -37,11 +38,7 @@ def __eq__(self, value: object) -> bool: bool: Did the OString objects match? """ if isinstance(value, OString): - if ( - self.path == value.path - and self.fileName == value.fileName - and self.platform == value.platform - ): + if self.path == value.path and self.fileName == value.fileName and self.platform == value.platform: return True return False diff --git a/exporter/SynthesisFusionAddin/src/UI/Camera.py b/exporter/SynthesisFusionAddin/src/UI/Camera.py index 33c84eb319..a7076fdfd2 100644 --- a/exporter/SynthesisFusionAddin/src/UI/Camera.py +++ b/exporter/SynthesisFusionAddin/src/UI/Camera.py @@ -1,12 +1,11 @@ -from ..general_imports import * - -from . import Helper import os -from ..Types.OString import OString - from adsk.core import SaveImageFileOptions +from ..general_imports import * +from ..Types.OString import OString +from . import Helper + def captureThumbnail(size=250): """ diff --git a/exporter/SynthesisFusionAddin/src/UI/ConfigCommand.py b/exporter/SynthesisFusionAddin/src/UI/ConfigCommand.py index 37b9f2b4e2..6ea4e0b702 100644 --- a/exporter/SynthesisFusionAddin/src/UI/ConfigCommand.py +++ b/exporter/SynthesisFusionAddin/src/UI/ConfigCommand.py @@ -2,30 +2,33 @@ links the Configuration Command seen when pressing the Synthesis button in the Addins Panel """ -from enum import Enum +import logging +import os import platform +import traceback +from enum import Enum + +import adsk.core +import adsk.fusion -from ..Parser.SynthesisParser.Utilities import guid_occurrence -from ..general_imports import * -from ..configure import NOTIFIED, write_configuration from ..Analytics.alert import showAnalyticsAlert -from . import Helper, OsHelper, CustomGraphics, IconPaths, FileDialogConfig +from ..configure import NOTIFIED, write_configuration +from ..general_imports import * from ..Parser.ExporterOptions import ( - Gamepiece, - ExportMode, ExporterOptions, + ExportMode, + Gamepiece, Joint, - Wheel, - WheelType, - SignalType, JointParentType, PreferredUnits, + SignalType, + Wheel, + WheelType, ) -from .Configuration.SerialCommand import SerialCommand - -import adsk.core, adsk.fusion, traceback, logging, os - from ..Parser.SynthesisParser.Parser import Parser +from ..Parser.SynthesisParser.Utilities import guid_occurrence +from . import CustomGraphics, FileDialogConfig, Helper, IconPaths, OsHelper +from .Configuration.SerialCommand import SerialCommand # ====================================== CONFIG COMMAND ====================================== @@ -119,9 +122,7 @@ def bRepMassInRoot(self): for body in gm.app.activeDocument.design.rootComponent.bRepBodies: if not body.isLightBulbOn: continue - physical = body.getPhysicalProperties( - adsk.fusion.CalculationAccuracy.LowCalculationAccuracy - ) + physical = body.getPhysicalProperties(adsk.fusion.CalculationAccuracy.LowCalculationAccuracy) self.totalMass += physical.mass except: if gm.ui: @@ -136,9 +137,7 @@ def traverseOccurrenceHierarchy(self): for body in occ.component.bRepBodies: if not body.isLightBulbOn: continue - physical = body.getPhysicalProperties( - adsk.fusion.CalculationAccuracy.LowCalculationAccuracy - ) + physical = body.getPhysicalProperties(adsk.fusion.CalculationAccuracy.LowCalculationAccuracy) self.totalMass += physical.mass except: pass @@ -186,12 +185,8 @@ def notify(self, args): cmd.isAutoExecute = False cmd.isExecutedWhenPreEmpted = False cmd.okButtonText = "Export" # replace default OK text with "export" - cmd.setDialogInitialSize( - 400, 350 - ) # these aren't working for some reason... - cmd.setDialogMinimumSize( - 400, 350 - ) # these aren't working for some reason... + cmd.setDialogInitialSize(400, 350) # these aren't working for some reason... + cmd.setDialogMinimumSize(400, 350) # these aren't working for some reason... global INPUTS_ROOT # Global CommandInputs arg INPUTS_ROOT = cmd.commandInputs @@ -201,9 +196,7 @@ def notify(self, args): Creates the general tab. - Parent container for all the command inputs in the tab. """ - inputs = INPUTS_ROOT.addTabCommandInput( - "general_settings", "General" - ).children + inputs = INPUTS_ROOT.addTabCommandInput("general_settings", "General").children # ~~~~~~~~~~~~~~~~ HELP FILE ~~~~~~~~~~~~~~~~ """ @@ -227,9 +220,7 @@ def notify(self, args): dropdownExportMode.listItems.add("Static", not dynamic) dropdownExportMode.tooltip = "Export Mode" - dropdownExportMode.tooltipDescription = ( - "
Does this object move dynamically?" - ) + dropdownExportMode.tooltipDescription = "
Does this object move dynamically?" # ~~~~~~~~~~~~~~~~ WEIGHT CONFIGURATION ~~~~~~~~~~~~~~~~ """ @@ -244,9 +235,7 @@ def notify(self, args): "3:2:2:1", 1, ) - weightTableInput.tablePresentationStyle = ( - 2 # set transparent background for table - ) + weightTableInput.tablePresentationStyle = 2 # set transparent background for table weight_name = inputs.addStringValueInput("weight_name", "Weight") weight_name.value = "Weight" @@ -279,7 +268,9 @@ def notify(self, args): adsk.core.ValueInput.createByReal(displayWeight), ) weight_input.tooltip = "Robot weight" - weight_input.tooltipDescription = """(in pounds)
This is the weight of the entire robot assembly.""" + weight_input.tooltipDescription = ( + """(in pounds)
This is the weight of the entire robot assembly.""" + ) weight_unit = inputs.addDropDownCommandInput( "weight_unit", @@ -287,43 +278,25 @@ def notify(self, args): adsk.core.DropDownStyles.LabeledIconDropDownStyle, ) - weight_unit.listItems.add( - "‎", imperialUnits, IconPaths.massIcons["LBS"] - ) # add listdropdown mass options - weight_unit.listItems.add( - "‎", not imperialUnits, IconPaths.massIcons["KG"] - ) # add listdropdown mass options + weight_unit.listItems.add("‎", imperialUnits, IconPaths.massIcons["LBS"]) # add listdropdown mass options + weight_unit.listItems.add("‎", not imperialUnits, IconPaths.massIcons["KG"]) # add listdropdown mass options weight_unit.tooltip = "Unit of mass" - weight_unit.tooltipDescription = ( - "
Configure the unit of mass for the weight calculation." - ) + weight_unit.tooltipDescription = "
Configure the unit of mass for the weight calculation." - weightTableInput.addCommandInput( - weight_name, 0, 0 - ) # add command inputs to table - weightTableInput.addCommandInput( - auto_calc_weight, 0, 1 - ) # add command inputs to table - weightTableInput.addCommandInput( - weight_input, 0, 2 - ) # add command inputs to table - weightTableInput.addCommandInput( - weight_unit, 0, 3 - ) # add command inputs to table + weightTableInput.addCommandInput(weight_name, 0, 0) # add command inputs to table + weightTableInput.addCommandInput(auto_calc_weight, 0, 1) # add command inputs to table + weightTableInput.addCommandInput(weight_input, 0, 2) # add command inputs to table + weightTableInput.addCommandInput(weight_unit, 0, 3) # add command inputs to table # ~~~~~~~~~~~~~~~~ WHEEL CONFIGURATION ~~~~~~~~~~~~~~~~ """ Wheel configuration command input group - Container for wheel selection Table """ - wheelConfig = inputs.addGroupCommandInput( - "wheel_config", "Wheel Configuration" - ) + wheelConfig = inputs.addGroupCommandInput("wheel_config", "Wheel Configuration") wheelConfig.isExpanded = True wheelConfig.isEnabled = True - wheelConfig.tooltip = ( - "Select and define the drive-train wheels in your assembly." - ) + wheelConfig.tooltip = "Select and define the drive-train wheels in your assembly." wheel_inputs = wheelConfig.children @@ -340,13 +313,9 @@ def notify(self, args): 50, ) - addWheelInput = wheel_inputs.addBoolValueInput( - "wheel_add", "Add", False - ) # add button + addWheelInput = wheel_inputs.addBoolValueInput("wheel_add", "Add", False) # add button - removeWheelInput = wheel_inputs.addBoolValueInput( # remove button - "wheel_delete", "Remove", False - ) + removeWheelInput = wheel_inputs.addBoolValueInput("wheel_delete", "Remove", False) # remove button addWheelInput.tooltip = "Add a wheel joint" # tooltips removeWheelInput.tooltip = "Remove a wheel joint" @@ -356,25 +325,17 @@ def notify(self, args): "Selection", "Select the wheels joints in your drive-train assembly.", ) - wheelSelectInput.addSelectionFilter( - "Joints" - ) # filter selection to only occurrences + wheelSelectInput.addSelectionFilter("Joints") # filter selection to only occurrences wheelSelectInput.setSelectionLimits(0) # no selection count limit wheelSelectInput.isEnabled = False wheelSelectInput.isVisible = False - wheelTableInput.addToolbarCommandInput( - addWheelInput - ) # add buttons to the toolbar - wheelTableInput.addToolbarCommandInput( - removeWheelInput - ) # add buttons to the toolbar + wheelTableInput.addToolbarCommandInput(addWheelInput) # add buttons to the toolbar + wheelTableInput.addToolbarCommandInput(removeWheelInput) # add buttons to the toolbar wheelTableInput.addCommandInput( # create textbox input using helper (component name) - self.createTextBoxInput( - "name_header", "Name", wheel_inputs, "Joint name", bold=False - ), + self.createTextBoxInput("name_header", "Name", wheel_inputs, "Joint name", bold=False), 0, 1, ) @@ -405,23 +366,17 @@ def notify(self, args): if exporterOptions.wheels: for wheel in exporterOptions.wheels: - wheelEntity = gm.app.activeDocument.design.findEntityByToken( - wheel.jointToken - )[0] + wheelEntity = gm.app.activeDocument.design.findEntityByToken(wheel.jointToken)[0] addWheelToTable(wheelEntity) # ~~~~~~~~~~~~~~~~ JOINT CONFIGURATION ~~~~~~~~~~~~~~~~ """ Joint configuration group. Container for joint selection table """ - jointConfig = inputs.addGroupCommandInput( - "joint_config", "Joint Configuration" - ) + jointConfig = inputs.addGroupCommandInput("joint_config", "Joint Configuration") jointConfig.isExpanded = False jointConfig.isVisible = True - jointConfig.tooltip = ( - "Select and define joint occurrences in your assembly." - ) + jointConfig.tooltip = "Select and define joint occurrences in your assembly." joint_inputs = jointConfig.children @@ -429,24 +384,18 @@ def notify(self, args): """ All selection joints appear here. """ - jointTableInput = ( - self.createTableInput( # create tablecommandinput using helper - "joint_table", - "Joint Table", - joint_inputs, - 6, - "1:2:2:2:2:2", - 50, - ) + jointTableInput = self.createTableInput( # create tablecommandinput using helper + "joint_table", + "Joint Table", + joint_inputs, + 6, + "1:2:2:2:2:2", + 50, ) - addJointInput = joint_inputs.addBoolValueInput( - "joint_add", "Add", False - ) # add button + addJointInput = joint_inputs.addBoolValueInput("joint_add", "Add", False) # add button - removeJointInput = joint_inputs.addBoolValueInput( # remove button - "joint_delete", "Remove", False - ) + removeJointInput = joint_inputs.addBoolValueInput("joint_delete", "Remove", False) # remove button addJointInput.isEnabled = removeJointInput.isEnabled = True @@ -464,12 +413,8 @@ def notify(self, args): jointSelectInput.isEnabled = False jointSelectInput.isVisible = False # make selection box invisible - jointTableInput.addToolbarCommandInput( - addJointInput - ) # add bool inputs to the toolbar - jointTableInput.addToolbarCommandInput( - removeJointInput - ) # add bool inputs to the toolbar + jointTableInput.addToolbarCommandInput(addJointInput) # add bool inputs to the toolbar + jointTableInput.addToolbarCommandInput(removeJointInput) # add bool inputs to the toolbar jointTableInput.addCommandInput( self.createTextBoxInput( # create a textBoxCommandInput for the table header (Joint Motion), using helper @@ -540,9 +485,9 @@ def notify(self, args): ) # Fill the table with all joints in current design - for joint in list( - gm.app.activeDocument.design.rootComponent.allJoints - ) + list(gm.app.activeDocument.design.rootComponent.allAsBuiltJoints): + for joint in list(gm.app.activeDocument.design.rootComponent.allJoints) + list( + gm.app.activeDocument.design.rootComponent.allAsBuiltJoints + ): if ( joint.jointMotion.jointType == JointMotions.REVOLUTE.value or joint.jointMotion.jointType == JointMotions.SLIDER.value @@ -554,9 +499,7 @@ def notify(self, args): Gamepiece group command input, isVisible=False by default - Container for gamepiece selection table """ - gamepieceConfig = inputs.addGroupCommandInput( - "gamepiece_config", "Gamepiece Configuration" - ) + gamepieceConfig = inputs.addGroupCommandInput("gamepiece_config", "Gamepiece Configuration") gamepieceConfig.isExpanded = True gamepieceConfig.isVisible = False gamepieceConfig.tooltip = "Select and define the gamepieces in your field." @@ -571,9 +514,7 @@ def notify(self, args): ) weightTableInput_f.tablePresentationStyle = 2 # set to clear background - weight_name_f = gamepiece_inputs.addStringValueInput( - "weight_name", "Weight" - ) + weight_name_f = gamepiece_inputs.addStringValueInput("weight_name", "Weight") weight_name_f.value = "Unit of Mass" weight_name_f.isReadOnly = True @@ -586,9 +527,7 @@ def notify(self, args): enabled=True, isCheckBox=False, ) - auto_calc_weight_f.resourceFolder = IconPaths.stringIcons[ - "calculate-enabled" - ] + auto_calc_weight_f.resourceFolder = IconPaths.stringIcons["calculate-enabled"] auto_calc_weight_f.isFullWidth = True weight_unit_f = gamepiece_inputs.addDropDownCommandInput( @@ -596,26 +535,14 @@ def notify(self, args): "Unit of Mass", adsk.core.DropDownStyles.LabeledIconDropDownStyle, ) - weight_unit_f.listItems.add( - "‎", True, IconPaths.massIcons["LBS"] - ) # add listdropdown mass options - weight_unit_f.listItems.add( - "‎", False, IconPaths.massIcons["KG"] - ) # add listdropdown mass options + weight_unit_f.listItems.add("‎", True, IconPaths.massIcons["LBS"]) # add listdropdown mass options + weight_unit_f.listItems.add("‎", False, IconPaths.massIcons["KG"]) # add listdropdown mass options weight_unit_f.tooltip = "Unit of mass" - weight_unit_f.tooltipDescription = ( - "
Configure the unit of mass for for the weight calculation." - ) + weight_unit_f.tooltipDescription = "
Configure the unit of mass for for the weight calculation." - weightTableInput_f.addCommandInput( - weight_name_f, 0, 0 - ) # add command inputs to table - weightTableInput_f.addCommandInput( - auto_calc_weight_f, 0, 1 - ) # add command inputs to table - weightTableInput_f.addCommandInput( - weight_unit_f, 0, 2 - ) # add command inputs to table + weightTableInput_f.addCommandInput(weight_name_f, 0, 0) # add command inputs to table + weightTableInput_f.addCommandInput(auto_calc_weight_f, 0, 1) # add command inputs to table + weightTableInput_f.addCommandInput(weight_unit_f, 0, 2) # add command inputs to table # GAMEPIECE SELECTION TABLE """ @@ -630,13 +557,9 @@ def notify(self, args): 50, ) - addFieldInput = gamepiece_inputs.addBoolValueInput( - "field_add", "Add", False - ) + addFieldInput = gamepiece_inputs.addBoolValueInput("field_add", "Add", False) - removeFieldInput = gamepiece_inputs.addBoolValueInput( - "field_delete", "Remove", False - ) + removeFieldInput = gamepiece_inputs.addBoolValueInput("field_delete", "Remove", False) addFieldInput.isEnabled = removeFieldInput.isEnabled = True removeFieldInput.tooltip = "Remove a field element" @@ -698,19 +621,17 @@ def notify(self, args): """ Creates the advanced tab, which is the parent container for internal command inputs """ - advancedSettings = INPUTS_ROOT.addTabCommandInput( - "advanced_settings", "Advanced" + advancedSettings = INPUTS_ROOT.addTabCommandInput("advanced_settings", "Advanced") + advancedSettings.tooltip = ( + "Additional Advanced Settings to change how your model will be translated into Unity." ) - advancedSettings.tooltip = "Additional Advanced Settings to change how your model will be translated into Unity." a_input = advancedSettings.children # ~~~~~~~~~~~~~~~~ EXPORTER SETTINGS ~~~~~~~~~~~~~~~~ """ Exporter settings group command """ - exporterSettings = a_input.addGroupCommandInput( - "exporter_settings", "Exporter Settings" - ) + exporterSettings = a_input.addGroupCommandInput("exporter_settings", "Exporter Settings") exporterSettings.isExpanded = True exporterSettings.isEnabled = True exporterSettings.tooltip = "tooltip" # TODO: update tooltip @@ -739,9 +660,7 @@ def notify(self, args): """ Physics settings group command """ - physicsSettings = a_input.addGroupCommandInput( - "physics_settings", "Physics Settings" - ) + physicsSettings = a_input.addGroupCommandInput("physics_settings", "Physics Settings") physicsSettings.isExpanded = False physicsSettings.isEnabled = True @@ -773,9 +692,7 @@ def notify(self, args): enabled=True, isCheckBox=False, ) - frictionOverride.resourceFolder = IconPaths.stringIcons[ - "friction_override-enabled" - ] + frictionOverride.resourceFolder = IconPaths.stringIcons["friction_override-enabled"] frictionOverride.isFullWidth = True valueList = [1] @@ -788,9 +705,7 @@ def notify(self, args): frictionCoeff.isVisible = False frictionCoeff.valueOne = 0.5 frictionCoeff.tooltip = "Friction coefficient of field element." - frictionCoeff.tooltipDescription = ( - "Friction coefficients range from 0 (ice) to 1 (rubber)." - ) + frictionCoeff.tooltipDescription = "Friction coefficients range from 0 (ice) to 1 (rubber)." frictionOverrideTable.addCommandInput(frictionOverride, 0, 0) frictionOverrideTable.addCommandInput(frictionCoeff, 0, 1) @@ -903,9 +818,9 @@ def notify(self, args): except: if gm.ui: gm.ui.messageBox("Failed:\n{}".format(traceback.format_exc())) - logging.getLogger( - "{INTERNAL_ID}.UI.ConfigCommand.{self.__class__.__name__}" - ).error("Failed:\n{}".format(traceback.format_exc())) + logging.getLogger("{INTERNAL_ID}.UI.ConfigCommand.{self.__class__.__name__}").error( + "Failed:\n{}".format(traceback.format_exc()) + ) def createBooleanInput( self, @@ -939,9 +854,9 @@ def createBooleanInput( _input.tooltipDescription = tooltipadvanced return _input except: - logging.getLogger( - "{INTERNAL_ID}.UI.ConfigCommand.{self.__class__.__name__}.createBooleanInput()" - ).error("Failed:\n{}".format(traceback.format_exc())) + logging.getLogger("{INTERNAL_ID}.UI.ConfigCommand.{self.__class__.__name__}.createBooleanInput()").error( + "Failed:\n{}".format(traceback.format_exc()) + ) def createTableInput( self, @@ -979,9 +894,9 @@ def createTableInput( _input.rowSpacing = rowSpacing return _input except: - logging.getLogger( - "{INTERNAL_ID}.UI.ConfigCommand.{self.__class__.__name__}.createTableInput()" - ).error("Failed:\n{}".format(traceback.format_exc())) + logging.getLogger("{INTERNAL_ID}.UI.ConfigCommand.{self.__class__.__name__}.createTableInput()").error( + "Failed:\n{}".format(traceback.format_exc()) + ) def createTextBoxInput( self, @@ -1045,9 +960,9 @@ def createTextBoxInput( _input.tooltipDescription = advanced_tooltip return _input except: - logging.getLogger( - "{INTERNAL_ID}.UI.ConfigCommand.createTextBoxInput()" - ).error("Failed:\n{}".format(traceback.format_exc())) + logging.getLogger("{INTERNAL_ID}.UI.ConfigCommand.createTextBoxInput()").error( + "Failed:\n{}".format(traceback.format_exc()) + ) class ConfigureCommandExecuteHandler(adsk.core.CommandEventHandler): @@ -1103,9 +1018,7 @@ def notify(self, args): ext="Synthesis File (*.synth)", ) else: - savepath = FileDialogConfig.SaveFileDialog( - defaultPath=exporterOptions.fileLocation - ) + savepath = FileDialogConfig.SaveFileDialog(defaultPath=exporterOptions.fileLocation) if savepath == False: # save was canceled @@ -1140,9 +1053,7 @@ def notify(self, args): row, 2 ).selectedItem.index # This must be either 0 or 1 for standard or omni - signalTypeIndex = wheelTableInput.getInputAtPosition( - row, 3 - ).selectedItem.index + signalTypeIndex = wheelTableInput.getInputAtPosition(row, 3).selectedItem.index _exportWheels.append( Wheel( @@ -1191,13 +1102,9 @@ def notify(self, args): ) continue elif parentJointIndex < row: - parentJointToken = JointListGlobal[ - parentJointIndex - 1 - ].entityToken # parent joint GUID, str + parentJointToken = JointListGlobal[parentJointIndex - 1].entityToken # parent joint GUID, str else: - parentJointToken = JointListGlobal[ - parentJointIndex + 1 - ].entityToken # parent joint GUID, str + parentJointToken = JointListGlobal[parentJointIndex + 1].entityToken # parent joint GUID, str # for wheel in _exportWheels: # find some way to get joint @@ -1223,16 +1130,12 @@ def notify(self, args): if row == 0: continue - weightValue = gamepieceTableInput.getInputAtPosition( - row, 2 - ).value # weight/mass input, float + weightValue = gamepieceTableInput.getInputAtPosition(row, 2).value # weight/mass input, float if weight_unit_f.selectedItem.index == 0: weightValue /= 2.2046226218 - frictionValue = gamepieceTableInput.getInputAtPosition( - row, 3 - ).valueOne # friction value, float + frictionValue = gamepieceTableInput.getInputAtPosition(row, 3).valueOne # friction value, float _exportGamepieces.append( Gamepiece( @@ -1351,15 +1254,10 @@ def notify(self, args): gm.app.activeViewport.refresh() else: gm.app.activeDocument.design.rootComponent.opacity = 1 - - for ( - group - ) in gm.app.activeDocument.design.rootComponent.customGraphicsGroups: + for group in gm.app.activeDocument.design.rootComponent.customGraphicsGroups: group.deleteMe() - if ( - not addJointInput.isEnabled or not removeJointInput - ): # TODO: improve joint highlighting + if not addJointInput.isEnabled or not removeJointInput: # TODO: improve joint highlighting # for joint in JointListGlobal: # CustomGraphics.highlightJointedOccurrences(joint) @@ -1381,9 +1279,9 @@ def notify(self, args): except: if gm.ui: gm.ui.messageBox("Failed:\n{}".format(traceback.format_exc())) - logging.getLogger( - "{INTERNAL_ID}.UI.ConfigCommand.{self.__class__.__name__}" - ).error("Failed:\n{}".format(traceback.format_exc())) + logging.getLogger("{INTERNAL_ID}.UI.ConfigCommand.{self.__class__.__name__}").error( + "Failed:\n{}".format(traceback.format_exc()) + ) class MySelectHandler(adsk.core.SelectionEventHandler): @@ -1400,9 +1298,7 @@ def __init__(self, cmd): self.cmd = cmd self.allWheelPreselections = [] # all child occurrences of selections - self.allGamepiecePreselections = ( - [] - ) # all child gamepiece occurrences of selections + self.allGamepiecePreselections = [] # all child gamepiece occurrences of selections self.selectedOcc = None # selected occurrence (if there is one) self.selectedJoint = None # selected joint (if there is one) @@ -1428,17 +1324,15 @@ def traverseAssembly( if occ in value: return [joint, occ] # occurrence that is jointed - if ( - occ.childOccurrences - ): # if occurrence has children, traverse sub-tree + if occ.childOccurrences: # if occurrence has children, traverse sub-tree self.traverseAssembly(occ.childOccurrences, jointedOcc) return None # no jointed occurrence found except: if gm.ui: gm.ui.messageBox("Failed:\n{}".format(traceback.format_exc())) - logging.getLogger( - "{INTERNAL_ID}.UI.ConfigCommand.{self.__class__.__name__}.traverseAssembly()" - ).error("Failed:\n{}".format(traceback.format_exc())) + logging.getLogger("{INTERNAL_ID}.UI.ConfigCommand.{self.__class__.__name__}.traverseAssembly()").error( + "Failed:\n{}".format(traceback.format_exc()) + ) def wheelParent(self, occ: adsk.fusion.Occurrence): """### Identify an occurrence that encompasses the entire wheel component. @@ -1467,18 +1361,12 @@ def wheelParent(self, occ: adsk.fusion.Occurrence): try: for joint in occ.joints: - if ( - joint.jointMotion.jointType - == adsk.fusion.JointTypes.RevoluteJointType - ): + if joint.jointMotion.jointType == adsk.fusion.JointTypes.RevoluteJointType: # gm.ui.messageBox("Selection is directly jointed.\nReturning selection.\n\n" + "Occurrence:\n--> " + occ.name + "\nJoint:\n--> " + joint.name) return [joint.entityToken, occ] except: for joint in occ.component.joints: - if ( - joint.jointMotion.jointType - == adsk.fusion.JointTypes.RevoluteJointType - ): + if joint.jointMotion.jointType == adsk.fusion.JointTypes.RevoluteJointType: # gm.ui.messageBox("Selection is directly jointed.\nReturning selection.\n\n" + "Occurrence:\n--> " + occ.name + "\nJoint:\n--> " + joint.name) return [joint.entityToken, occ] @@ -1487,10 +1375,7 @@ def wheelParent(self, occ: adsk.fusion.Occurrence): return [None, occ] # return what is selected for joint in gm.app.activeDocument.design.rootComponent.allJoints: - if ( - joint.jointMotion.jointType - != adsk.fusion.JointTypes.RevoluteJointType - ): + if joint.jointMotion.jointType != adsk.fusion.JointTypes.RevoluteJointType: continue jointedOcc[joint.entityToken] = [ joint.occurrenceOne, @@ -1503,9 +1388,7 @@ def wheelParent(self, occ: adsk.fusion.Occurrence): treeParent = parent # each parent that will traverse up in algorithm. while treeParent != None: # loops until reaches top-level component - returned = self.traverseAssembly( - treeParent.childOccurrences, jointedOcc - ) + returned = self.traverseAssembly(treeParent.childOccurrences, jointedOcc) if returned != None: for i in range(parentLevel): @@ -1521,9 +1404,9 @@ def wheelParent(self, occ: adsk.fusion.Occurrence): except: if gm.ui: gm.ui.messageBox("Failed:\n{}".format(traceback.format_exc())) - logging.getLogger( - "{INTERNAL_ID}.UI.ConfigCommand.{self.__class__.__name__}.wheelParent()" - ).error("Failed:\n{}".format(traceback.format_exc())) + logging.getLogger("{INTERNAL_ID}.UI.ConfigCommand.{self.__class__.__name__}.wheelParent()").error( + "Failed:\n{}".format(traceback.format_exc()) + ) # gm.ui.messageBox("Selection's component has no referenced joints.\nReturning selection.\n\n" + "Occurrence:\n--> " + occ.name + "\nJoint:\n--> NONE") return [None, occ] @@ -1563,23 +1446,12 @@ def notify(self, args: adsk.core.SelectionEventArgs): elif self.selectedJoint: self.cmd.setCursor("", 0, 0) jointType = self.selectedJoint.jointMotion.jointType - if ( - jointType == JointMotions.REVOLUTE.value - or jointType == JointMotions.SLIDER.value - ): - if ( - jointType == JointMotions.REVOLUTE.value - and MySelectHandler.lastInputCmd.id == "wheel_select" - ): + if jointType == JointMotions.REVOLUTE.value or jointType == JointMotions.SLIDER.value: + if jointType == JointMotions.REVOLUTE.value and MySelectHandler.lastInputCmd.id == "wheel_select": addWheelToTable(self.selectedJoint) - elif ( - jointType == JointMotions.REVOLUTE.value - and MySelectHandler.lastInputCmd.id == "wheel_remove" - ): + elif jointType == JointMotions.REVOLUTE.value and MySelectHandler.lastInputCmd.id == "wheel_remove": if self.selectedJoint in WheelListGlobal: - removeWheelFromTable( - WheelListGlobal.index(self.selectedJoint) - ) + removeWheelFromTable(WheelListGlobal.index(self.selectedJoint)) else: if self.selectedJoint not in JointListGlobal: addJointToTable(self.selectedJoint) @@ -1591,9 +1463,9 @@ def notify(self, args: adsk.core.SelectionEventArgs): except: if gm.ui: gm.ui.messageBox("Failed:\n{}".format(traceback.format_exc())) - logging.getLogger( - "{INTERNAL_ID}.UI.ConfigCommand.{self.__class__.__name__}" - ).error("Failed:\n{}".format(traceback.format_exc())) + logging.getLogger("{INTERNAL_ID}.UI.ConfigCommand.{self.__class__.__name__}").error( + "Failed:\n{}".format(traceback.format_exc()) + ) class MyPreSelectHandler(adsk.core.SelectionEventHandler): @@ -1655,9 +1527,9 @@ def notify(self, args): except: if gm.ui: gm.ui.messageBox("Failed:\n{}".format(traceback.format_exc())) - logging.getLogger( - "{INTERNAL_ID}.UI.ConfigCommand.{self.__class__.__name__}" - ).error("Failed:\n{}".format(traceback.format_exc())) + logging.getLogger("{INTERNAL_ID}.UI.ConfigCommand.{self.__class__.__name__}").error( + "Failed:\n{}".format(traceback.format_exc()) + ) class MyPreselectEndHandler(adsk.core.SelectionEventHandler): @@ -1683,9 +1555,9 @@ def notify(self, args): except: if gm.ui: gm.ui.messageBox("Failed:\n{}".format(traceback.format_exc())) - logging.getLogger( - "{INTERNAL_ID}.UI.ConfigCommand.{self.__class__.__name__}" - ).error("Failed:\n{}".format(traceback.format_exc())) + logging.getLogger("{INTERNAL_ID}.UI.ConfigCommand.{self.__class__.__name__}").error( + "Failed:\n{}".format(traceback.format_exc()) + ) class ConfigureCommandInputChanged(adsk.core.InputChangedEventHandler): @@ -1697,9 +1569,7 @@ class ConfigureCommandInputChanged(adsk.core.InputChangedEventHandler): def __init__(self, cmd): super().__init__() - self.log = logging.getLogger( - f"{INTERNAL_ID}.UI.ConfigCommand.{self.__class__.__name__}" - ) + self.log = logging.getLogger(f"{INTERNAL_ID}.UI.ConfigCommand.{self.__class__.__name__}") self.cmd = cmd self.allWeights = [None, None] # [lbs, kg] self.isLbs = True @@ -1714,9 +1584,9 @@ def reset(self): self.cmd.setCursor("", 0, 0) gm.ui.activeSelections.clear() except: - logging.getLogger( - "{INTERNAL_ID}.UI.ConfigCommand.{self.__class__.__name__}.reset()" - ).error("Failed:\n{}".format(traceback.format_exc())) + logging.getLogger("{INTERNAL_ID}.UI.ConfigCommand.{self.__class__.__name__}.reset()").error( + "Failed:\n{}".format(traceback.format_exc()) + ) def weight(self, isLbs=True): # maybe add a progress dialog?? """### Get the total design weight using the predetermined units. @@ -1746,9 +1616,9 @@ def weight(self, isLbs=True): # maybe add a progress dialog?? value = round(value, 2) # round weight to 2 decimals places return value except: - logging.getLogger( - "{INTERNAL_ID}.UI.ConfigCommand.{self.__class__.__name__}.weight()" - ).error("Failed:\n{}".format(traceback.format_exc())) + logging.getLogger("{INTERNAL_ID}.UI.ConfigCommand.{self.__class__.__name__}.weight()").error( + "Failed:\n{}".format(traceback.format_exc()) + ) def notify(self, args): try: @@ -1796,31 +1666,21 @@ def notify(self, args): gamepieceConfig.isVisible = False weightTableInput.isVisible = True - addFieldInput.isEnabled = wheelConfig.isVisible = ( - jointConfig.isVisible - ) = True + addFieldInput.isEnabled = wheelConfig.isVisible = jointConfig.isVisible = True elif modeDropdown.selectedItem.index == 1: if gamepieceConfig: gm.ui.activeSelections.clear() gm.app.activeDocument.design.rootComponent.opacity = 1 - addWheelInput.isEnabled = addJointInput.isEnabled = ( - gamepieceConfig.isVisible - ) = True + addWheelInput.isEnabled = addJointInput.isEnabled = gamepieceConfig.isVisible = True - jointConfig.isVisible = wheelConfig.isVisible = ( - weightTableInput.isVisible - ) = False + jointConfig.isVisible = wheelConfig.isVisible = weightTableInput.isVisible = False elif cmdInput.id == "joint_config": gm.app.activeDocument.design.rootComponent.opacity = 1 - elif ( - cmdInput.id == "placeholder_w" - or cmdInput.id == "name_w" - or cmdInput.id == "signal_type_w" - ): + elif cmdInput.id == "placeholder_w" or cmdInput.id == "name_w" or cmdInput.id == "signal_type_w": self.reset() wheelSelect.isEnabled = False @@ -1829,26 +1689,11 @@ def notify(self, args): cmdInput_str = cmdInput.id if cmdInput_str == "placeholder_w": - position = ( - wheelTableInput.getPosition( - adsk.core.ImageCommandInput.cast(cmdInput) - )[1] - - 1 - ) + position = wheelTableInput.getPosition(adsk.core.ImageCommandInput.cast(cmdInput))[1] - 1 elif cmdInput_str == "name_w": - position = ( - wheelTableInput.getPosition( - adsk.core.TextBoxCommandInput.cast(cmdInput) - )[1] - - 1 - ) + position = wheelTableInput.getPosition(adsk.core.TextBoxCommandInput.cast(cmdInput))[1] - 1 elif cmdInput_str == "signal_type_w": - position = ( - wheelTableInput.getPosition( - adsk.core.DropDownCommandInput.cast(cmdInput) - )[1] - - 1 - ) + position = wheelTableInput.getPosition(adsk.core.DropDownCommandInput.cast(cmdInput))[1] - 1 gm.ui.activeSelections.add(WheelListGlobal[position]) @@ -1862,11 +1707,7 @@ def notify(self, args): jointSelect.isEnabled = False addJointInput.isEnabled = True - elif ( - cmdInput.id == "blank_gp" - or cmdInput.id == "name_gp" - or cmdInput.id == "weight_gp" - ): + elif cmdInput.id == "blank_gp" or cmdInput.id == "name_gp" or cmdInput.id == "weight_gp": self.reset() gamepieceSelect.isEnabled = False @@ -1875,33 +1716,13 @@ def notify(self, args): cmdInput_str = cmdInput.id if cmdInput_str == "name_gp": - position = ( - gamepieceTableInput.getPosition( - adsk.core.TextBoxCommandInput.cast(cmdInput) - )[1] - - 1 - ) + position = gamepieceTableInput.getPosition(adsk.core.TextBoxCommandInput.cast(cmdInput))[1] - 1 elif cmdInput_str == "weight_gp": - position = ( - gamepieceTableInput.getPosition( - adsk.core.ValueCommandInput.cast(cmdInput) - )[1] - - 1 - ) + position = gamepieceTableInput.getPosition(adsk.core.ValueCommandInput.cast(cmdInput))[1] - 1 elif cmdInput_str == "blank_gp": - position = ( - gamepieceTableInput.getPosition( - adsk.core.ImageCommandInput.cast(cmdInput) - )[1] - - 1 - ) + position = gamepieceTableInput.getPosition(adsk.core.ImageCommandInput.cast(cmdInput))[1] - 1 else: - position = ( - gamepieceTableInput.getPosition( - adsk.core.FloatSliderCommandInput.cast(cmdInput) - )[1] - - 1 - ) + position = gamepieceTableInput.getPosition(adsk.core.FloatSliderCommandInput.cast(cmdInput))[1] - 1 gm.ui.activeSelections.add(GamepieceListGlobal[position]) @@ -1912,34 +1733,23 @@ def notify(self, args): addWheelInput.isEnabled = True cmdInput_str = cmdInput.id - position = ( - wheelTableInput.getPosition( - adsk.core.DropDownCommandInput.cast(cmdInput) - )[1] - - 1 - ) + position = wheelTableInput.getPosition(adsk.core.DropDownCommandInput.cast(cmdInput))[1] - 1 wheelDropdown = adsk.core.DropDownCommandInput.cast(cmdInput) if wheelDropdown.selectedItem.index == 0: - getPosition = wheelTableInput.getPosition( - adsk.core.DropDownCommandInput.cast(cmdInput) - ) + getPosition = wheelTableInput.getPosition(adsk.core.DropDownCommandInput.cast(cmdInput)) iconInput = wheelTableInput.getInputAtPosition(getPosition[1], 0) iconInput.imageFile = IconPaths.wheelIcons["standard"] iconInput.tooltip = "Standard wheel" elif wheelDropdown.selectedItem.index == 1: - getPosition = wheelTableInput.getPosition( - adsk.core.DropDownCommandInput.cast(cmdInput) - ) + getPosition = wheelTableInput.getPosition(adsk.core.DropDownCommandInput.cast(cmdInput)) iconInput = wheelTableInput.getInputAtPosition(getPosition[1], 0) iconInput.imageFile = IconPaths.wheelIcons["omni"] iconInput.tooltip = "Omni wheel" elif wheelDropdown.selectedItem.index == 2: - getPosition = wheelTableInput.getPosition( - adsk.core.DropDownCommandInput.cast(cmdInput) - ) + getPosition = wheelTableInput.getPosition(adsk.core.DropDownCommandInput.cast(cmdInput)) iconInput = wheelTableInput.getInputAtPosition(getPosition[1], 0) iconInput.imageFile = IconPaths.wheelIcons["mecanum"] iconInput.tooltip = "Mecanum wheel" @@ -1977,10 +1787,7 @@ def notify(self, args): # gm.ui.activeSelections.clear() addWheelInput.isEnabled = True - if ( - wheelTableInput.selectedRow == -1 - or wheelTableInput.selectedRow == 0 - ): + if wheelTableInput.selectedRow == -1 or wheelTableInput.selectedRow == 0: wheelTableInput.selectedRow = wheelTableInput.rowCount - 1 gm.ui.messageBox("Select a row to delete.") else: @@ -1993,10 +1800,7 @@ def notify(self, args): addJointInput.isEnabled = True addWheelInput.isEnabled = True - if ( - jointTableInput.selectedRow == -1 - or jointTableInput.selectedRow == 0 - ): + if jointTableInput.selectedRow == -1 or jointTableInput.selectedRow == 0: jointTableInput.selectedRow = jointTableInput.rowCount - 1 gm.ui.messageBox("Select a row to delete.") else: @@ -2008,10 +1812,7 @@ def notify(self, args): addFieldInput.isEnabled = True - if ( - gamepieceTableInput.selectedRow == -1 - or gamepieceTableInput.selectedRow == 0 - ): + if gamepieceTableInput.selectedRow == -1 or gamepieceTableInput.selectedRow == 0: gamepieceTableInput.selectedRow = gamepieceTableInput.rowCount - 1 gm.ui.messageBox("Select a row to delete.") else: @@ -2041,11 +1842,15 @@ def notify(self, args): if unitDropdown.selectedItem.index == 0: self.isLbs = True - weightInput.tooltipDescription = """(in pounds)
This is the weight of the entire robot assembly.""" + weightInput.tooltipDescription = ( + """(in pounds)
This is the weight of the entire robot assembly.""" + ) elif unitDropdown.selectedItem.index == 1: self.isLbs = False - weightInput.tooltipDescription = """(in kilograms)
This is the weight of the entire robot assembly.""" + weightInput.tooltipDescription = ( + """(in kilograms)
This is the weight of the entire robot assembly.""" + ) elif cmdInput.id == "weight_unit_f": unitDropdown = adsk.core.DropDownCommandInput.cast(cmdInput) @@ -2070,9 +1875,7 @@ def notify(self, args): button = adsk.core.BoolValueCommandInput.cast(cmdInput) if button.value == True: # CALCULATE button pressed - if ( - self.allWeights.count(None) == 2 - ): # if button is pressed for the first time + if self.allWeights.count(None) == 2: # if button is pressed for the first time if self.isLbs: # if pounds unit selected self.allWeights[0] = self.weight() weight_input.value = self.allWeights[0] @@ -2099,9 +1902,7 @@ def notify(self, args): if row == 0: continue weightInput = gamepieceTableInput.getInputAtPosition(row, 2) - physical = GamepieceListGlobal[ - row - 1 - ].component.getPhysicalProperties( + physical = GamepieceListGlobal[row - 1].component.getPhysicalProperties( adsk.fusion.CalculationAccuracy.LowCalculationAccuracy ) value = round(physical.mass * 2.2046226218, 2) @@ -2112,9 +1913,7 @@ def notify(self, args): if row == 0: continue weightInput = gamepieceTableInput.getInputAtPosition(row, 2) - physical = GamepieceListGlobal[ - row - 1 - ].component.getPhysicalProperties( + physical = GamepieceListGlobal[row - 1].component.getPhysicalProperties( adsk.fusion.CalculationAccuracy.LowCalculationAccuracy ) value = round(physical.mass, 2) @@ -2127,9 +1926,9 @@ def notify(self, args): except: if gm.ui: gm.ui.messageBox("Failed:\n{}".format(traceback.format_exc())) - logging.getLogger( - "{INTERNAL_ID}.UI.ConfigCommand.{self.__class__.__name__}" - ).error("Failed:\n{}".format(traceback.format_exc())) + logging.getLogger("{INTERNAL_ID}.UI.ConfigCommand.{self.__class__.__name__}").error( + "Failed:\n{}".format(traceback.format_exc()) + ) class MyCommandDestroyHandler(adsk.core.CommandEventHandler): @@ -2152,9 +1951,7 @@ def notify(self, args): onSelect.allWheelPreselections.clear() onSelect.wheelJointList.clear() - for ( - group - ) in gm.app.activeDocument.design.rootComponent.customGraphicsGroups: + for group in gm.app.activeDocument.design.rootComponent.customGraphicsGroups: group.deleteMe() # Currently causes Internal Autodesk Error @@ -2163,9 +1960,9 @@ def notify(self, args): except: if gm.ui: gm.ui.messageBox("Failed:\n{}".format(traceback.format_exc())) - logging.getLogger( - "{INTERNAL_ID}.UI.ConfigCommand.{self.__class__.__name__}" - ).error("Failed:\n{}".format(traceback.format_exc())) + logging.getLogger("{INTERNAL_ID}.UI.ConfigCommand.{self.__class__.__name__}").error( + "Failed:\n{}".format(traceback.format_exc()) + ) def addJointToTable(joint: adsk.fusion.Joint) -> None: @@ -2181,51 +1978,35 @@ def addJointToTable(joint: adsk.fusion.Joint) -> None: # joint type icons if joint.jointMotion.jointType == adsk.fusion.JointTypes.RigidJointType: - icon = cmdInputs.addImageCommandInput( - "placeholder", "Rigid", IconPaths.jointIcons["rigid"] - ) + icon = cmdInputs.addImageCommandInput("placeholder", "Rigid", IconPaths.jointIcons["rigid"]) icon.tooltip = "Rigid joint" elif joint.jointMotion.jointType == adsk.fusion.JointTypes.RevoluteJointType: - icon = cmdInputs.addImageCommandInput( - "placeholder", "Revolute", IconPaths.jointIcons["revolute"] - ) + icon = cmdInputs.addImageCommandInput("placeholder", "Revolute", IconPaths.jointIcons["revolute"]) icon.tooltip = "Revolute joint" elif joint.jointMotion.jointType == adsk.fusion.JointTypes.SliderJointType: - icon = cmdInputs.addImageCommandInput( - "placeholder", "Slider", IconPaths.jointIcons["slider"] - ) + icon = cmdInputs.addImageCommandInput("placeholder", "Slider", IconPaths.jointIcons["slider"]) icon.tooltip = "Slider joint" elif joint.jointMotion.jointType == adsk.fusion.JointTypes.PlanarJointType: - icon = cmdInputs.addImageCommandInput( - "placeholder", "Planar", IconPaths.jointIcons["planar"] - ) + icon = cmdInputs.addImageCommandInput("placeholder", "Planar", IconPaths.jointIcons["planar"]) icon.tooltip = "Planar joint" elif joint.jointMotion.jointType == adsk.fusion.JointTypes.PinSlotJointType: - icon = cmdInputs.addImageCommandInput( - "placeholder", "Pin Slot", IconPaths.jointIcons["pin_slot"] - ) + icon = cmdInputs.addImageCommandInput("placeholder", "Pin Slot", IconPaths.jointIcons["pin_slot"]) icon.tooltip = "Pin slot joint" elif joint.jointMotion.jointType == adsk.fusion.JointTypes.CylindricalJointType: - icon = cmdInputs.addImageCommandInput( - "placeholder", "Cylindrical", IconPaths.jointIcons["cylindrical"] - ) + icon = cmdInputs.addImageCommandInput("placeholder", "Cylindrical", IconPaths.jointIcons["cylindrical"]) icon.tooltip = "Cylindrical joint" elif joint.jointMotion.jointType == adsk.fusion.JointTypes.BallJointType: - icon = cmdInputs.addImageCommandInput( - "placeholder", "Ball", IconPaths.jointIcons["ball"] - ) + icon = cmdInputs.addImageCommandInput("placeholder", "Ball", IconPaths.jointIcons["ball"]) icon.tooltip = "Ball joint" # joint name - name = cmdInputs.addTextBoxCommandInput( - "name_j", "Occurrence name", "", 1, True - ) + name = cmdInputs.addTextBoxCommandInput("name_j", "Occurrence name", "", 1, True) name.tooltip = joint.name name.formattedText = "

{}

".format(joint.name) @@ -2277,9 +2058,7 @@ def addJointToTable(joint: adsk.fusion.Joint) -> None: jointSpeed.tooltip = "Degrees per second" jointTableInput.addCommandInput(jointSpeed, row, 4) - jointForce = cmdInputs.addValueInput( - "joint_force", "Force", "N", adsk.core.ValueInput.createByReal(5000) - ) + jointForce = cmdInputs.addValueInput("joint_force", "Force", "N", adsk.core.ValueInput.createByReal(5000)) jointForce.tooltip = "Newton-Meters***" jointTableInput.addCommandInput(jointForce, row, 5) @@ -2293,9 +2072,7 @@ def addJointToTable(joint: adsk.fusion.Joint) -> None: jointSpeed.tooltip = "Meters per second" jointTableInput.addCommandInput(jointSpeed, row, 4) - jointForce = cmdInputs.addValueInput( - "joint_force", "Force", "N", adsk.core.ValueInput.createByReal(5000) - ) + jointForce = cmdInputs.addValueInput("joint_force", "Force", "N", adsk.core.ValueInput.createByReal(5000)) jointForce.tooltip = "Newtons" jointTableInput.addCommandInput(jointForce, row, 5) @@ -2337,13 +2114,9 @@ def addWheelToTable(wheel: adsk.fusion.Joint) -> None: WheelListGlobal.append(wheel) cmdInputs = adsk.core.CommandInputs.cast(wheelTableInput.commandInputs) - icon = cmdInputs.addImageCommandInput( - "placeholder_w", "Placeholder", IconPaths.wheelIcons["standard"] - ) + icon = cmdInputs.addImageCommandInput("placeholder_w", "Placeholder", IconPaths.wheelIcons["standard"]) - name = cmdInputs.addTextBoxCommandInput( - "name_w", "Joint name", wheel.name, 1, True - ) + name = cmdInputs.addTextBoxCommandInput("name_w", "Joint name", wheel.name, 1, True) name.tooltip = wheel.name wheelType = cmdInputs.addDropDownCommandInput( @@ -2355,9 +2128,9 @@ def addWheelToTable(wheel: adsk.fusion.Joint) -> None: wheelType.listItems.add("Omni", False, "") wheelType.tooltip = "Wheel type" wheelType.tooltipDescription = "
Omni-directional wheels can be used just like regular drive wheels but they have the advantage of being able to roll freely perpendicular to the drive direction.
" - wheelType.toolClipFilename = OsHelper.getOSPath( - ".", "src", "Resources" - ) + os.path.join("WheelIcons", "omni-wheel-preview.png") + wheelType.toolClipFilename = OsHelper.getOSPath(".", "src", "Resources") + os.path.join( + "WheelIcons", "omni-wheel-preview.png" + ) signalType = cmdInputs.addDropDownCommandInput( "signal_type_w", @@ -2407,18 +2180,12 @@ def addPreselections(child_occurrences): GamepieceListGlobal.append(gamepiece) cmdInputs = adsk.core.CommandInputs.cast(gamepieceTableInput.commandInputs) - blankIcon = cmdInputs.addImageCommandInput( - "blank_gp", "Blank", IconPaths.gamepieceIcons["blank"] - ) + blankIcon = cmdInputs.addImageCommandInput("blank_gp", "Blank", IconPaths.gamepieceIcons["blank"]) - type = cmdInputs.addTextBoxCommandInput( - "name_gp", "Occurrence name", gamepiece.name, 1, True - ) + type = cmdInputs.addTextBoxCommandInput("name_gp", "Occurrence name", gamepiece.name, 1, True) value = 0.0 - physical = gamepiece.component.getPhysicalProperties( - adsk.fusion.CalculationAccuracy.LowCalculationAccuracy - ) + physical = gamepiece.component.getPhysicalProperties(adsk.fusion.CalculationAccuracy.LowCalculationAccuracy) value = physical.mass # check if dropdown unit is kg or lbs. bool value taken from ConfigureCommandInputChanged @@ -2442,9 +2209,7 @@ def addPreselections(child_occurrences): for i in range(20): valueList.append(i / 20) - friction_coeff = cmdInputs.addFloatSliderListCommandInput( - "friction_coeff", "", "", valueList - ) + friction_coeff = cmdInputs.addFloatSliderListCommandInput("friction_coeff", "", "", valueList) friction_coeff.valueOne = 0.5 type.tooltip = gamepiece.name @@ -2453,9 +2218,7 @@ def addPreselections(child_occurrences): weight.tooltipDescription = massUnitInString friction_coeff.tooltip = "Friction coefficient of field element" - friction_coeff.tooltipDescription = ( - "Friction coefficients range from 0 (ice) to 1 (rubber)." - ) + friction_coeff.tooltipDescription = "Friction coefficients range from 0 (ice) to 1 (rubber)." row = gamepieceTableInput.rowCount gamepieceTableInput.addCommandInput(blankIcon, row, 0) @@ -2498,9 +2261,9 @@ def removeWheelFromTable(index: int) -> None: except IndexError: pass except: - logging.getLogger( - "{INTERNAL_ID}.UI.ConfigCommand.removeWheelFromTable()" - ).error("Failed:\n{}".format(traceback.format_exc())) + logging.getLogger("{INTERNAL_ID}.UI.ConfigCommand.removeWheelFromTable()").error( + "Failed:\n{}".format(traceback.format_exc()) + ) def removeJointFromTable(joint: adsk.fusion.Joint) -> None: @@ -2536,9 +2299,9 @@ def removeJointFromTable(joint: adsk.fusion.Joint) -> None: else: listItems.item(index).deleteMe() except: - logging.getLogger( - "{INTERNAL_ID}.UI.ConfigCommand.removeJointFromTable()" - ).error("Failed:\n{}".format(traceback.format_exc())) + logging.getLogger("{INTERNAL_ID}.UI.ConfigCommand.removeJointFromTable()").error( + "Failed:\n{}".format(traceback.format_exc()) + ) def removeGamePieceFromTable(index: int) -> None: @@ -2569,6 +2332,6 @@ def removePreselections(child_occurrences): except IndexError: pass except: - logging.getLogger( - "{INTERNAL_ID}.UI.ConfigCommand.removeGamePieceFromTable()" - ).error("Failed:\n{}".format(traceback.format_exc())) + logging.getLogger("{INTERNAL_ID}.UI.ConfigCommand.removeGamePieceFromTable()").error( + "Failed:\n{}".format(traceback.format_exc()) + ) diff --git a/exporter/SynthesisFusionAddin/src/UI/Configuration/SerialCommand.py b/exporter/SynthesisFusionAddin/src/UI/Configuration/SerialCommand.py index 15691017dd..7f03642fec 100644 --- a/exporter/SynthesisFusionAddin/src/UI/Configuration/SerialCommand.py +++ b/exporter/SynthesisFusionAddin/src/UI/Configuration/SerialCommand.py @@ -6,6 +6,7 @@ """ import json + from ...Types.OString import OString diff --git a/exporter/SynthesisFusionAddin/src/UI/CustomGraphics.py b/exporter/SynthesisFusionAddin/src/UI/CustomGraphics.py index d6986f9844..17b63c8222 100644 --- a/exporter/SynthesisFusionAddin/src/UI/CustomGraphics.py +++ b/exporter/SynthesisFusionAddin/src/UI/CustomGraphics.py @@ -1,4 +1,9 @@ -import adsk.fusion, adsk.core, traceback, logging +import logging +import traceback + +import adsk.core +import adsk.fusion + from ..general_imports import * @@ -12,30 +17,20 @@ def createTextGraphics(wheel: adsk.fusion.Occurrence, _wheels) -> None: max = boundingBox.maxPoint.asArray() # [x, y, z] max coords if design: - graphics = ( - gm.app.activeDocument.design.rootComponent.customGraphicsGroups.add() - ) + graphics = gm.app.activeDocument.design.rootComponent.customGraphicsGroups.add() matrix = adsk.core.Matrix3D.create() matrix.translation = adsk.core.Vector3D.create(min[0], min[1] - 5, min[2]) - billBoard = adsk.fusion.CustomGraphicsBillBoard.create( - adsk.core.Point3D.create(0, 0, 0) - ) - billBoard.billBoardStyle = ( - adsk.fusion.CustomGraphicsBillBoardStyles.ScreenBillBoardStyle - ) + billBoard = adsk.fusion.CustomGraphicsBillBoard.create(adsk.core.Point3D.create(0, 0, 0)) + billBoard.billBoardStyle = adsk.fusion.CustomGraphicsBillBoardStyles.ScreenBillBoardStyle text = str(_wheels.index(wheel) + 1) graphicsText = graphics.addText(text, "Arial Black", 6, matrix) graphicsText.billBoarding = billBoard # make the text follow the camera graphicsText.isSelectable = False # make it non-selectable - graphicsText.cullMode = ( - adsk.fusion.CustomGraphicsCullModes.CustomGraphicsCullBack - ) - graphicsText.color = ( - adsk.fusion.CustomGraphicsShowThroughColorEffect.create( - adsk.core.Color.create(230, 146, 18, 255), 1 - ) + graphicsText.cullMode = adsk.fusion.CustomGraphicsCullModes.CustomGraphicsCullBack + graphicsText.color = adsk.fusion.CustomGraphicsShowThroughColorEffect.create( + adsk.core.Color.create(230, 146, 18, 255), 1 ) # orange/synthesis theme graphicsText.depthPriority = 0 @@ -82,6 +77,4 @@ def createTextGraphics(wheel: adsk.fusion.Occurrence, _wheels) -> None: line.isSelectable = False line.depthPriority = 1 except: - logging.getLogger("{INTERNAL_ID}.UI.CreateTextGraphics").error( - "Failed:\n{}".format(traceback.format_exc()) - ) + logging.getLogger("{INTERNAL_ID}.UI.CreateTextGraphics").error("Failed:\n{}".format(traceback.format_exc())) diff --git a/exporter/SynthesisFusionAddin/src/UI/Events.py b/exporter/SynthesisFusionAddin/src/UI/Events.py index 407b71e481..60e2af032f 100644 --- a/exporter/SynthesisFusionAddin/src/UI/Events.py +++ b/exporter/SynthesisFusionAddin/src/UI/Events.py @@ -1,7 +1,7 @@ -from ..general_imports import * - -from typing import Sequence, Tuple import logging.handlers +from typing import Sequence, Tuple + +from ..general_imports import * """ # This file is Special It links all function names to command requests that palletes can make automatically @@ -51,9 +51,7 @@ def openDocument(json_data: str) -> str: """ data = json.loads(json_data) data = data["arguments"] - gm.ui.messageBox( - f"Attempting to open and focus on a given document: {data}\n TODO: Implement" - ) + gm.ui.messageBox(f"Attempting to open and focus on a given document: {data}\n TODO: Implement") logging.getLogger(f"{INTERNAL_ID}.Events.openDocument").info( f"Attempting to open and focus on a given document: {data}\n TODO: Implement" ) diff --git a/exporter/SynthesisFusionAddin/src/UI/FileDialogConfig.py b/exporter/SynthesisFusionAddin/src/UI/FileDialogConfig.py index 895940387e..e49cf240b7 100644 --- a/exporter/SynthesisFusionAddin/src/UI/FileDialogConfig.py +++ b/exporter/SynthesisFusionAddin/src/UI/FileDialogConfig.py @@ -1,15 +1,15 @@ +from typing import Union + +import adsk.core +import adsk.fusion + from ..general_imports import * # from ..proto_out import Configuration_pb2 from ..Types.OString import OString -from typing import Union -import adsk.core, adsk.fusion - -def SaveFileDialog( - defaultPath="", defaultName="", ext="MiraBuf Package (*.mira)" -) -> Union[str, bool]: +def SaveFileDialog(defaultPath="", defaultName="", ext="MiraBuf Package (*.mira)") -> Union[str, bool]: """Function to generate the Save File Dialog for the Hellion Data files Args: diff --git a/exporter/SynthesisFusionAddin/src/UI/HUI.py b/exporter/SynthesisFusionAddin/src/UI/HUI.py index d8933e4ed5..b17ba6ea96 100644 --- a/exporter/SynthesisFusionAddin/src/UI/HUI.py +++ b/exporter/SynthesisFusionAddin/src/UI/HUI.py @@ -1,7 +1,5 @@ -from . import OsHelper -from . import Handlers - from ..general_imports import * +from . import Handlers, OsHelper # no longer used @@ -47,9 +45,7 @@ def __init__( self.events.append(arg) if self.uid in gm.uniqueIds: - raise ValueError( - f"Cannot create two UI Elements with the same ID {self.uid}\n" - ) + raise ValueError(f"Cannot create two UI Elements with the same ID {self.uid}\n") if gm.ui.palettes is None: raise RuntimeError(f"No Palette object exists yet") @@ -57,9 +53,7 @@ def __init__( self.palette = gm.ui.palettes.itemById(self.uid) if self.palette is None: - path = OsHelper.getOSPathPalette( - "src", "Resources", "Palette", f'{self.name.replace(" ", "")}' - ) + path = OsHelper.getOSPathPalette("src", "Resources", "Palette", f'{self.name.replace(" ", "")}') self.palette = gm.ui.palettes.add( self.uid, @@ -72,9 +66,7 @@ def __init__( height, ) - self.palette.dockingState = ( - adsk.core.PaletteDockingStates.PaletteDockStateLeft - ) + self.palette.dockingState = adsk.core.PaletteDockingStates.PaletteDockStateLeft onHTML = Handlers.HPaletteHTMLEventHandler(self) self.palette.incomingFromHTML.add(onHTML) @@ -124,9 +116,7 @@ def __init__( self.uid = name.replace(" ", "") + f"_{INTERNAL_ID}" if self.uid in gm.uniqueIds: - raise ValueError( - f"Cannot create two UI Elements with the same ID {self.uid}\n" - ) + raise ValueError(f"Cannot create two UI Elements with the same ID {self.uid}\n") self.name = name @@ -138,9 +128,7 @@ def __init__( cmdDef = gm.ui.commandDefinitions.itemById(self.uid) if cmdDef: # gm.ui.messageBox("Looks like you have experienced a crash we will do cleanup.") - self.logger.debug( - "Looks like there was a crash, doing cleanup in button id" - ) + self.logger.debug("Looks like there was a crash, doing cleanup in button id") self.scrub() # needs to updated with new OString data @@ -148,9 +136,7 @@ def __init__( self.uid, f"{name}", f"{description}", - OsHelper.getOSPath( - ".", "src", "Resources", f'{self.name.replace(" ", "")}' - ), + OsHelper.getOSPath(".", "src", "Resources", f'{self.name.replace(" ", "")}'), ) """ Button Command Definition stored as a member """ @@ -208,9 +194,7 @@ def deleteMe(self): self.logger.debug(f"Removing Button {self.uid}") cmdDef.deleteMe() - ctrl = gm.ui.allToolbarPanels.itemById(self.location).controls.itemById( - self.uid - ) + ctrl = gm.ui.allToolbarPanels.itemById(self.location).controls.itemById(self.uid) if ctrl: self.logger.debug(f"Removing Button Control {self.location}:{self.uid}") ctrl.deleteMe() diff --git a/exporter/SynthesisFusionAddin/src/UI/Helper.py b/exporter/SynthesisFusionAddin/src/UI/Helper.py index 3b99bc5425..8f88240247 100644 --- a/exporter/SynthesisFusionAddin/src/UI/Helper.py +++ b/exporter/SynthesisFusionAddin/src/UI/Helper.py @@ -1,8 +1,8 @@ -from ..general_imports import * from inspect import getmembers, isfunction from typing import Union -from . import Events, HUI +from ..general_imports import * +from . import HUI, Events def check_solid_open() -> bool: @@ -33,9 +33,7 @@ def checkAttribute() -> bool: return connected.value return False except: - app.userInterface.messageBox( - f"Could not access the attributes of the file \n -- {traceback.format_exc()}." - ) + app.userInterface.messageBox(f"Could not access the attributes of the file \n -- {traceback.format_exc()}.") return False @@ -56,9 +54,7 @@ def addUnityAttribute() -> bool or None: return None except: - app.userInterface.messageBox( - f"Could not access the attributes of the file \n -- {traceback.format_exc()}." - ) + app.userInterface.messageBox(f"Could not access the attributes of the file \n -- {traceback.format_exc()}.") return False @@ -79,9 +75,7 @@ def openPanel() -> None: gm.app.data.isDataPanelVisible = False else: func_list = [o for o in getmembers(Events, isfunction)] - palette_new = HUI.HPalette( - name, APP_TITLE, True, True, False, 400, 500, func_list - ) + palette_new = HUI.HPalette(name, APP_TITLE, True, True, False, 400, 500, func_list) gm.elements.append(palette_new) return diff --git a/exporter/SynthesisFusionAddin/src/UI/IconPaths.py b/exporter/SynthesisFusionAddin/src/UI/IconPaths.py index b07edab1fb..261720494c 100644 --- a/exporter/SynthesisFusionAddin/src/UI/IconPaths.py +++ b/exporter/SynthesisFusionAddin/src/UI/IconPaths.py @@ -1,30 +1,24 @@ -from . import OsHelper import os +from . import OsHelper + """ Dictionaries that store all the icon paths in ConfigCommand. All path strings are OS-independent """ -resources = OsHelper.getOSPath( - ".", "src", "Resources" -) # str shortcut with primary directories to all images in file +resources = OsHelper.getOSPath(".", "src", "Resources") # str shortcut with primary directories to all images in file wheelIcons = { "omni": resources + os.path.join("WheelIcons", "omni-wheel-preview190x24.png"), - "standard": resources - + os.path.join("WheelIcons", "standard-wheel-preview190x24.png"), - "mecanum": resources - + os.path.join("WheelIcons", "mecanum-wheel-preview190x24.png"), + "standard": resources + os.path.join("WheelIcons", "standard-wheel-preview190x24.png"), + "mecanum": resources + os.path.join("WheelIcons", "mecanum-wheel-preview190x24.png"), } jointIcons = { "rigid": resources + os.path.join("JointIcons", "JointRigid", "rigid190x24.png"), - "revolute": resources - + os.path.join("JointIcons", "JointRev", "revolute190x24.png"), + "revolute": resources + os.path.join("JointIcons", "JointRev", "revolute190x24.png"), "slider": resources + os.path.join("JointIcons", "JointSlider", "slider190x24.png"), - "cylindrical": resources - + os.path.join("JointIcons", "JointCyl", "cylindrical190x24.png"), - "pin_slot": resources - + os.path.join("JointIcons", "JointPinSlot", "pin_slot190x24.png"), + "cylindrical": resources + os.path.join("JointIcons", "JointCyl", "cylindrical190x24.png"), + "pin_slot": resources + os.path.join("JointIcons", "JointPinSlot", "pin_slot190x24.png"), "planar": resources + os.path.join("JointIcons", "JointPlanar", "planar190x24.png"), "ball": resources + os.path.join("JointIcons", "JointBall", "ball190x24.png"), } @@ -50,8 +44,6 @@ } stringIcons = { - "calculate-enabled": resources - + os.path.join("AutoCalcWeight_icon"), # resource folder - "friction_override-enabled": resources - + os.path.join("FrictionOverride_icon"), # resource folder + "calculate-enabled": resources + os.path.join("AutoCalcWeight_icon"), # resource folder + "friction_override-enabled": resources + os.path.join("FrictionOverride_icon"), # resource folder } diff --git a/exporter/SynthesisFusionAddin/src/UI/MarkingMenu.py b/exporter/SynthesisFusionAddin/src/UI/MarkingMenu.py index 0a1fbadcbf..5c68d2c79a 100644 --- a/exporter/SynthesisFusionAddin/src/UI/MarkingMenu.py +++ b/exporter/SynthesisFusionAddin/src/UI/MarkingMenu.py @@ -1,5 +1,8 @@ -import adsk.core, adsk.fusion, traceback import logging.handlers +import traceback + +import adsk.core +import adsk.fusion # Ripped all the boiler plate from the example code: https://help.autodesk.com/view/fusion360/ENU/?guid=GUID-c90ce6a2-c282-11e6-a365-3417ebc87622 @@ -22,9 +25,7 @@ def setLinearMarkingMenu(args): linearMenu = menuArgs.linearMarkingMenu linearMenu.controls.addSeparator("LinearSeparator") - synthDropDown = linearMenu.controls.addDropDown( - "Synthesis", "", "synthesis" - ) + synthDropDown = linearMenu.controls.addDropDown("Synthesis", "", "synthesis") cmdSelectDisabled = ui.commandDefinitions.itemById("SelectDisabled") synthDropDown.controls.addCommand(cmdSelectDisabled) @@ -40,24 +41,15 @@ def setLinearMarkingMenu(args): occ = adsk.fusion.Occurrence.cast(sel0) if occ: - if ( - occ.attributes.itemByName("synthesis", "collision_off") - == None - ): - cmdDisableCollision = ui.commandDefinitions.itemById( - "DisableCollision" - ) + if occ.attributes.itemByName("synthesis", "collision_off") == None: + cmdDisableCollision = ui.commandDefinitions.itemById("DisableCollision") synthDropDown.controls.addCommand(cmdDisableCollision) else: - cmdEnableCollision = ui.commandDefinitions.itemById( - "EnableCollision" - ) + cmdEnableCollision = ui.commandDefinitions.itemById("EnableCollision") synthDropDown.controls.addCommand(cmdEnableCollision) except: if ui: - ui.messageBox("setting linear menu failed: {}").format( - traceback.format_exc() - ) + ui.messageBox("setting linear menu failed: {}").format(traceback.format_exc()) def setCollisionAttribute(occ: adsk.fusion.Occurrence, isEnabled: bool = True): attr = occ.attributes.itemByName("synthesis", "collision_off") @@ -90,9 +82,7 @@ def notify(self, args): handlers.append(onCommandExcute) command.execute.add(onCommandExcute) except: - ui.messageBox("command created failed: {}").format( - traceback.format_exc() - ) + ui.messageBox("command created failed: {}").format(traceback.format_exc()) class MyCommandExecuteHandler(adsk.core.CommandEventHandler): def __init__(self): @@ -125,34 +115,24 @@ def notify(self, args): design = adsk.fusion.Design.cast(product) ui.activeSelections.clear() if design: - attrs = design.findAttributes( - "synthesis", "collision_off" - ) + attrs = design.findAttributes("synthesis", "collision_off") for attr in attrs: - for b in adsk.fusion.Occurrence.cast( - attr.parent - ).bRepBodies: + for b in adsk.fusion.Occurrence.cast(attr.parent).bRepBodies: ui.activeSelections.add(b) elif cmdDef.id == "EnableAllCollision": app = adsk.core.Application.get() product = app.activeProduct design = adsk.fusion.Design.cast(product) if design: - for attr in design.findAttributes( - "synthesis", "collision_off" - ): + for attr in design.findAttributes("synthesis", "collision_off"): attr.deleteMe() else: ui.messageBox("command {} triggered.".format(cmdDef.id)) else: ui.messageBox("No CommandDefinition") except: - ui.messageBox("command executed failed: {}").format( - traceback.format_exc() - ) - logging.getLogger(f"{INTERNAL_ID}").error( - "Failed:\n{}".format(traceback.format_exc()) - ) + ui.messageBox("command executed failed: {}").format(traceback.format_exc()) + logging.getLogger(f"{INTERNAL_ID}").error("Failed:\n{}".format(traceback.format_exc())) class MyMarkingMenuHandler(adsk.core.MarkingMenuEventHandler): def __init__(self): @@ -170,11 +150,7 @@ def notify(self, args): entities = args.selectedEntities except: if ui: - ui.messageBox( - "Marking Menu Displaying event failed: {}".format( - traceback.format_exc() - ) - ) + ui.messageBox("Marking Menu Displaying event failed: {}".format(traceback.format_exc())) # Add customized handler for marking menu displaying onMarkingMenuDisplaying = MyMarkingMenuHandler() diff --git a/exporter/SynthesisFusionAddin/src/UI/OsHelper.py b/exporter/SynthesisFusionAddin/src/UI/OsHelper.py index 956c9f6fd1..e338be5815 100644 --- a/exporter/SynthesisFusionAddin/src/UI/OsHelper.py +++ b/exporter/SynthesisFusionAddin/src/UI/OsHelper.py @@ -1,4 +1,5 @@ -import os, platform +import os +import platform def getOSPath(*argv) -> str: diff --git a/exporter/SynthesisFusionAddin/src/UI/Toolbar.py b/exporter/SynthesisFusionAddin/src/UI/Toolbar.py index 4a260ae18a..e0b8f26f19 100644 --- a/exporter/SynthesisFusionAddin/src/UI/Toolbar.py +++ b/exporter/SynthesisFusionAddin/src/UI/Toolbar.py @@ -36,9 +36,7 @@ def __init__(self, name: str): except: error = traceback.format_exc() - self.logger.error( - f"Failed at creating toolbar with {self.uid} due to {error}" - ) + self.logger.error(f"Failed at creating toolbar with {self.uid} due to {error}") def getPanel(self, name: str, visibility: bool = True) -> str or None: """# Gets a control for a panel to the tabbed toolbar @@ -57,15 +55,11 @@ def getPanel(self, name: str, visibility: bool = True) -> str or None: self.logger.debug(f"Created Panel {panel_uid} in Toolbar {self.uid}") return panel_uid else: - self.logger.error( - f"Failed to Create Panel {panel_uid} in Toolbar {self.uid}" - ) + self.logger.error(f"Failed to Create Panel {panel_uid} in Toolbar {self.uid}") return None @staticmethod - def getNewPanel( - name: str, tab_id: str, toolbar_id: str, visibility: bool = True - ) -> str or None: + def getNewPanel(name: str, tab_id: str, toolbar_id: str, visibility: bool = True) -> str or None: """# Gets a control for a panel to the tabbed toolbar visibility""" logger = logging.getLogger(f"{INTERNAL_ID}.Toolbar.getNewPanel") diff --git a/exporter/SynthesisFusionAddin/src/configure.py b/exporter/SynthesisFusionAddin/src/configure.py index 5226a2acce..e121e7ae6e 100644 --- a/exporter/SynthesisFusionAddin/src/configure.py +++ b/exporter/SynthesisFusionAddin/src/configure.py @@ -1,11 +1,12 @@ """ Stores data and fields from config.ini """ -from configparser import ConfigParser -from .Types.OString import OString -from .strings import INTERNAL_ID -import uuid, traceback import logging.handlers +import traceback +import uuid +from configparser import ConfigParser +from .strings import INTERNAL_ID +from .Types.OString import OString try: config = ConfigParser() @@ -35,19 +36,13 @@ else: # in here we need to ask for analytics CID = uuid.uuid4() - config.set( - "analytics", "c_id", str(CID) - ) # default values - add exception handling + config.set("analytics", "c_id", str(CID)) # default values - add exception handling except: - logging.getLogger(f"{INTERNAL_ID}.import_manager").error( - "Failed\n{}".format(traceback.format_exc()) - ) + logging.getLogger(f"{INTERNAL_ID}.import_manager").error("Failed\n{}".format(traceback.format_exc())) def setAnalytics(enabled: bool): - logging.getLogger(f"{INTERNAL_ID}.configure.setAnalytics").info( - f"First run , Analytics set to {enabled}" - ) + logging.getLogger(f"{INTERNAL_ID}.configure.setAnalytics").info(f"First run , Analytics set to {enabled}") ANALYTICS = enabled ans = "yes" if ANALYTICS else "no" write_configuration("analytics", "analytics", ans) diff --git a/exporter/SynthesisFusionAddin/src/general_imports.py b/exporter/SynthesisFusionAddin/src/general_imports.py index e32e90df39..042e4618ea 100644 --- a/exporter/SynthesisFusionAddin/src/general_imports.py +++ b/exporter/SynthesisFusionAddin/src/general_imports.py @@ -1,19 +1,25 @@ -import os, sys, uuid, json -import adsk.core, adsk.fusion, traceback -import logging.handlers, pathlib - -from time import time +import json +import logging.handlers +import os +import pathlib +import sys +import traceback +import uuid from datetime import datetime +from time import time from types import FunctionType +import adsk.core +import adsk.fusion + # hard coded to bypass errors for now PROTOBUF = True DEBUG = True try: - from .strings import * from .GlobalManager import * from .logging import setupLogger + from .strings import * (root_logger, log_handler) = setupLogger() except ImportError as e: @@ -23,9 +29,7 @@ try: path = os.path.abspath(os.path.join(os.path.dirname(__file__), "..")) - path_proto_files = os.path.abspath( - os.path.join(os.path.dirname(__file__), "..", "proto", "proto_out") - ) + path_proto_files = os.path.abspath(os.path.join(os.path.dirname(__file__), "..", "proto", "proto_out")) if not path in sys.path: sys.path.insert(1, path) @@ -36,9 +40,7 @@ from proto import deps except: - logging.getLogger(f"{INTERNAL_ID}.import_manager").error( - "Failed\n{}".format(traceback.format_exc()) - ) + logging.getLogger(f"{INTERNAL_ID}.import_manager").error("Failed\n{}".format(traceback.format_exc())) try: # simple analytics endpoint @@ -50,6 +52,4 @@ my_addin_path = os.path.dirname(os.path.realpath(__file__)) except: # should also log this - logging.getLogger(f"{INTERNAL_ID}.import_manager").error( - "Failed\n{}".format(traceback.format_exc()) - ) + logging.getLogger(f"{INTERNAL_ID}.import_manager").error("Failed\n{}".format(traceback.format_exc())) diff --git a/exporter/SynthesisFusionAddin/src/logging.py b/exporter/SynthesisFusionAddin/src/logging.py index 00b9fcfe4f..2a0233ae5a 100644 --- a/exporter/SynthesisFusionAddin/src/logging.py +++ b/exporter/SynthesisFusionAddin/src/logging.py @@ -2,11 +2,12 @@ """ import logging.handlers +import os +import pathlib from datetime import datetime -import os, pathlib -from .UI.OsHelper import getOSPath from .strings import * +from .UI.OsHelper import getOSPath def setupLogger(): @@ -19,14 +20,10 @@ def setupLogger(): loc = pathlib.Path(__file__).parent.parent path = getOSPath(f"{loc}", "logs") - _log_handler = logging.handlers.WatchedFileHandler( - os.environ.get("LOGFILE", f"{path}{INTERNAL_ID}.log"), mode="w" - ) + _log_handler = logging.handlers.WatchedFileHandler(os.environ.get("LOGFILE", f"{path}{INTERNAL_ID}.log"), mode="w") # This will make it so I can see the auxiliary logging levels of each of the subclasses - _log_handler.setFormatter( - logging.Formatter("%(asctime)s - %(name)s - %(levelname)s - %(message)s") - ) + _log_handler.setFormatter(logging.Formatter("%(asctime)s - %(name)s - %(levelname)s - %(message)s")) log = logging.getLogger(f"{INTERNAL_ID}") log.setLevel(os.environ.get("LOGLEVEL", "DEBUG")) diff --git a/exporter/SynthesisFusionAddin/tools/format.py b/exporter/SynthesisFusionAddin/tools/format.py new file mode 100644 index 0000000000..7531b93de7 --- /dev/null +++ b/exporter/SynthesisFusionAddin/tools/format.py @@ -0,0 +1,25 @@ +import os +import subprocess +import sys + + +def main(args: list[str] = sys.argv[1:]) -> None: + dir = args[0] if len(args) else "." + if "pyproject.toml" not in os.listdir(dir): + print("WARNING: Configuration file for autoformatters was not found. Are you sure you specified the root DIR?") + + for command in ["isort", "black"]: + try: + print(f"Formatting with {command}...") + subprocess.call([command, dir], shell=False, stdout=subprocess.PIPE, stderr=subprocess.PIPE) + except FileNotFoundError: + print(f'"{command}" could not be found. Please resolve dependencies.') + return + except BaseException as error: + print(f'An unknown error occurred while running "{command}"\n{error}') + + print("Done! All files successfully formatted.") + + +if __name__ == "__main__": + main() diff --git a/exporter/SynthesisFusionAddin/tools/verifyIsortFormatting.py b/exporter/SynthesisFusionAddin/tools/verifyIsortFormatting.py new file mode 100644 index 0000000000..0f9d899d5a --- /dev/null +++ b/exporter/SynthesisFusionAddin/tools/verifyIsortFormatting.py @@ -0,0 +1,32 @@ +import os +import subprocess +import sys + +ROOT_EXPORTER_DIR = "exporter/SynthesisFusionAddin" + + +def main() -> None: + files = [ + os.path.abspath(os.path.join(root, filename)) + for root, _, filenames in os.walk(ROOT_EXPORTER_DIR) + for filename in filenames + if filename.endswith(".py") + ] + oldFileStates = [open(file, "r").readlines() for file in files] + subprocess.call(["isort", ROOT_EXPORTER_DIR], bufsize=1, shell=False) + newFileStates = [open(file, "r").readlines() for file in files] + exitCode = 0 + for i, (oldFileState, newFileState) in enumerate(zip(oldFileStates, newFileStates)): + for j, (previousLine, newLine) in enumerate(zip(oldFileState, newFileState)): + if previousLine != newLine: + print(f"File {files[i]} is not formatted correctly!\nLine: {j + 1}") + exitCode = 1 + + if not exitCode: + print("All files are formatted correctly with isort!") + + sys.exit(exitCode) + + +if __name__ == "__main__": + main()