From b0107f3f65df8f671ea74806b5d0a061e95daa96 Mon Sep 17 00:00:00 2001 From: Timo Korthals Date: Wed, 12 Jun 2024 13:14:45 +0200 Subject: [PATCH 1/7] Fix output-path argument processing (#19) * Fix output-path argument processing The output-path argument hasn't been processed such that it was constantly set to 'install_folder / "output"'. * chore: bump version to 1.3.4 --------- Co-authored-by: Anton Elmiger --- pyproject.toml | 2 +- syclops/cli.py | 6 ++++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 647ebb8..abf34ab 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -13,7 +13,7 @@ readme = "README.md" requires-python = ">=3.8" license = {text = "GPLv3"} -version = "1.3.3" +version = "1.3.4" dynamic = ["dependencies"] diff --git a/syclops/cli.py b/syclops/cli.py index e12903c..4afca24 100644 --- a/syclops/cli.py +++ b/syclops/cli.py @@ -50,7 +50,7 @@ "-o", "--output-path", help="Output path of generated files. Defaults to /output", - default="./output", + default=None, ) parser.add_argument( "-d", @@ -225,7 +225,9 @@ def _wait_for_debugger(): def _run_syclops_job(args, install_folder: Path, job_description: Path): - output_path = _configure_output_path(install_folder / "output") + output_path = (_configure_output_path(Path(args.output_path).absolute()) + if args.output_path + else _configure_output_path(install_folder / "output")) job_filepath = job_description asset_catalog_filepath = install_folder / "asset_catalog.yaml" From f4742fddc709a865115a2ca04310ba120eb6748f Mon Sep 17 00:00:00 2001 From: aelmiger <40243985+aelmiger@users.noreply.github.com> Date: Wed, 17 Jul 2024 11:13:31 +0200 Subject: [PATCH 2/7] Add Convex Hull mesh decimation (#20) * feature: bump version to 1.3.5 and add max_hull_vertices parameter to convex_decomposition function * fix: Set numpy ==1.23.5 to avoid issues with numpy 2.0.0 release * Fix issue with multiple testpypi version conflicts --- .github/workflows/deploy_to_pypi.yaml | 1 + pyproject.toml | 2 +- requirements.txt | 1 + syclops/utility/blender_utils.py | 12 +++++++++++- 4 files changed, 14 insertions(+), 2 deletions(-) diff --git a/.github/workflows/deploy_to_pypi.yaml b/.github/workflows/deploy_to_pypi.yaml index 857a2ca..e1f1bd9 100644 --- a/.github/workflows/deploy_to_pypi.yaml +++ b/.github/workflows/deploy_to_pypi.yaml @@ -115,3 +115,4 @@ jobs: uses: pypa/gh-action-pypi-publish@release/v1 with: repository-url: https://test.pypi.org/legacy/ + skip_existing: true diff --git a/pyproject.toml b/pyproject.toml index abf34ab..10f3424 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -13,7 +13,7 @@ readme = "README.md" requires-python = ">=3.8" license = {text = "GPLv3"} -version = "1.3.4" +version = "1.3.5" dynamic = ["dependencies"] diff --git a/requirements.txt b/requirements.txt index 4603416..16c4abb 100644 --- a/requirements.txt +++ b/requirements.txt @@ -6,6 +6,7 @@ filelock==3.9.0 GitPython==3.1.29 jsonschema==4.17.3 opencv-python==4.6.0.66 +numpy==1.23.5 Pillow==9.4.0 PyYAML==6.0.1 requests==2.27.1 diff --git a/syclops/utility/blender_utils.py b/syclops/utility/blender_utils.py index 31efb1a..7fd6e8f 100644 --- a/syclops/utility/blender_utils.py +++ b/syclops/utility/blender_utils.py @@ -398,6 +398,7 @@ def convex_decomposition( obj_pointer: ObjPointer, conv_hull_collection_pointer: ObjPointer, quality: float = 90, + max_hull_vertices: int = 100, ) -> List[bpy.types.Object]: """Decompose an object into convex hulls for physics simulation. @@ -405,7 +406,7 @@ def convex_decomposition( obj_pointer (ObjPointer): Pointer to object to decompose. conv_hull_collection_pointer (ObjPointer): Pointer to collection to store convex hulls in. quality (float, optional): Quality of the convex decomposition. Defaults to 90. - + max_hull_vertices (int, optional): Maximum number of vertices in a convex hull. Defaults to 256. Returns: list[bpy.types.Object]: List of convex hulls. """ @@ -436,6 +437,15 @@ def convex_decomposition( # Create the mesh data mesh.from_pydata(convex_hull[0], [], convex_hull[1]) + # Num vertices of mesh + num_vertices = len(mesh.vertices) + if num_vertices > max_hull_vertices: + decimate_factor = max_hull_vertices / num_vertices + + # Decimate the mesh if it has too many vertices + decimate_mesh(convex_obj, decimate_factor) + + # Update the mesh and object mesh.update() convex_obj.select_set(True) From bcf779c2d322092d70f67fcd3421a6c05271df68 Mon Sep 17 00:00:00 2001 From: aelmiger <40243985+aelmiger@users.noreply.github.com> Date: Wed, 17 Jul 2024 11:41:47 +0200 Subject: [PATCH 3/7] Add auto-tag workflow (#21) * Add auto-tag workflow * chore: bump version to 1.3.6 --- .github/workflows/auto-tag.yaml | 35 +++++++++++++++++++++++++ .github/workflows/integration_test.yaml | 3 +++ pyproject.toml | 2 +- 3 files changed, 39 insertions(+), 1 deletion(-) create mode 100644 .github/workflows/auto-tag.yaml diff --git a/.github/workflows/auto-tag.yaml b/.github/workflows/auto-tag.yaml new file mode 100644 index 0000000..0fc788d --- /dev/null +++ b/.github/workflows/auto-tag.yaml @@ -0,0 +1,35 @@ +on: + push: + branches: + - main + +jobs: + auto-tag: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - name: Get version from pyproject.toml + id: get_version + run: | + VERSION=$(grep '^version =' pyproject.toml | awk -F'"' '{print $2}') + echo "VERSION=v$VERSION" >> $GITHUB_OUTPUT + + - name: Check if tag exists + id: check_tag + run: | + if git rev-parse "${{ steps.get_version.outputs.VERSION }}" >/dev/null 2>&1; then + echo "TAG_EXISTS=true" >> $GITHUB_OUTPUT + else + echo "TAG_EXISTS=false" >> $GITHUB_OUTPUT + fi + + - name: Create and push tag + if: steps.check_tag.outputs.TAG_EXISTS == 'false' + run: | + git config user.name github-actions + git config user.email github-actions@github.com + git tag ${{ steps.get_version.outputs.VERSION }} + git push origin ${{ steps.get_version.outputs.VERSION }} diff --git a/.github/workflows/integration_test.yaml b/.github/workflows/integration_test.yaml index 142e7cf..8ae1246 100644 --- a/.github/workflows/integration_test.yaml +++ b/.github/workflows/integration_test.yaml @@ -3,6 +3,8 @@ name: Syclops Pipeline Test on: push: branches: [ main ] + tags: + - 'v*' # This will match any tag starting with 'v' pull_request: branches: [ main ] @@ -10,6 +12,7 @@ jobs: build-and-test: name: Syclops Pipeline Test runs-on: ubuntu-latest + if: github.event_name == 'pull_request' || (github.event_name == 'push' && startsWith(github.ref, 'refs/tags/v')) steps: - name: Checkout repository diff --git a/pyproject.toml b/pyproject.toml index 10f3424..ab06431 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -13,7 +13,7 @@ readme = "README.md" requires-python = ">=3.8" license = {text = "GPLv3"} -version = "1.3.5" +version = "1.3.6" dynamic = ["dependencies"] From 315af542f55b2870561bea141e0d166b25465254 Mon Sep 17 00:00:00 2001 From: Anton Elmiger Date: Wed, 17 Jul 2024 12:08:34 +0200 Subject: [PATCH 4/7] hotfix: Merge auto-tag workflow with pypi --- .github/workflows/auto-tag.yaml | 35 ----------- .github/workflows/deploy_to_pypi.yaml | 77 +++++++++++++++++-------- .github/workflows/integration_test.yaml | 2 - pyproject.toml | 2 +- 4 files changed, 54 insertions(+), 62 deletions(-) delete mode 100644 .github/workflows/auto-tag.yaml diff --git a/.github/workflows/auto-tag.yaml b/.github/workflows/auto-tag.yaml deleted file mode 100644 index 0fc788d..0000000 --- a/.github/workflows/auto-tag.yaml +++ /dev/null @@ -1,35 +0,0 @@ -on: - push: - branches: - - main - -jobs: - auto-tag: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - with: - fetch-depth: 0 - - - name: Get version from pyproject.toml - id: get_version - run: | - VERSION=$(grep '^version =' pyproject.toml | awk -F'"' '{print $2}') - echo "VERSION=v$VERSION" >> $GITHUB_OUTPUT - - - name: Check if tag exists - id: check_tag - run: | - if git rev-parse "${{ steps.get_version.outputs.VERSION }}" >/dev/null 2>&1; then - echo "TAG_EXISTS=true" >> $GITHUB_OUTPUT - else - echo "TAG_EXISTS=false" >> $GITHUB_OUTPUT - fi - - - name: Create and push tag - if: steps.check_tag.outputs.TAG_EXISTS == 'false' - run: | - git config user.name github-actions - git config user.email github-actions@github.com - git tag ${{ steps.get_version.outputs.VERSION }} - git push origin ${{ steps.get_version.outputs.VERSION }} diff --git a/.github/workflows/deploy_to_pypi.yaml b/.github/workflows/deploy_to_pypi.yaml index e1f1bd9..905355e 100644 --- a/.github/workflows/deploy_to_pypi.yaml +++ b/.github/workflows/deploy_to_pypi.yaml @@ -1,11 +1,48 @@ name: Publish Python 🐍 distribution 📦 to PyPI and TestPyPI -on: push +on: + push: + branches: [main] + pull_request: + branches: [main] jobs: + auto-tag: + name: Create and push tag + runs-on: ubuntu-latest + if: github.event_name == 'push' && github.ref == 'refs/heads/main' + outputs: + new_tag: ${{ steps.create_tag.outputs.new_tag }} + + steps: + - uses: actions/checkout@v4 + with: + fetch-depth: 0 + - name: Get version from pyproject.toml + id: get_version + run: | + VERSION=$(grep '^version =' pyproject.toml | awk -F'"' '{print $2}') + echo "VERSION=v$VERSION" >> $GITHUB_OUTPUT + - name: Create and push tag + id: create_tag + run: | + if ! git rev-parse ${{ steps.get_version.outputs.VERSION }} >/dev/null 2>&1; then + git config user.name github-actions + git config user.email github-actions@github.com + git tag ${{ steps.get_version.outputs.VERSION }} + git push origin ${{ steps.get_version.outputs.VERSION }} + echo "new_tag=true" >> $GITHUB_OUTPUT + else + echo "new_tag=false" >> $GITHUB_OUTPUT + fi + build: name: Build distribution 📦 + needs: [auto-tag] runs-on: ubuntu-latest + if: > + github.event_name == 'pull_request' || + (github.event_name == 'push' && needs.auto-tag.outputs.new_tag == 'true') steps: - uses: actions/checkout@v4 @@ -28,17 +65,15 @@ jobs: path: dist/ publish-to-pypi: - name: >- - Publish Python 🐍 distribution 📦 to PyPI - if: startsWith(github.ref, 'refs/tags/') # only publish to PyPI on tag pushes - needs: - - build + name: Publish Python 🐍 distribution 📦 to PyPI + needs: [auto-tag, build] + if: needs.auto-tag.outputs.new_tag == 'true' runs-on: ubuntu-latest environment: name: pypi url: https://pypi.org/p/syclops permissions: - id-token: write # IMPORTANT: mandatory for trusted publishing + id-token: write steps: - name: Download all the dists @@ -50,16 +85,13 @@ jobs: uses: pypa/gh-action-pypi-publish@release/v1 github-release: - name: >- - Sign the Python 🐍 distribution 📦 with Sigstore - and upload them to GitHub Release - needs: - - publish-to-pypi + name: Sign and upload to GitHub Release + needs: [auto-tag, publish-to-pypi] + if: needs.auto-tag.outputs.new_tag == 'true' runs-on: ubuntu-latest - permissions: - contents: write # IMPORTANT: mandatory for making GitHub Releases - id-token: write # IMPORTANT: mandatory for sigstore + contents: write + id-token: write steps: - name: Download all the dists @@ -84,9 +116,6 @@ jobs: - name: Upload artifact signatures to GitHub Release env: GITHUB_TOKEN: ${{ github.token }} - # Upload to GitHub Release using the `gh` CLI. - # `dist/` contains the built packages, and the - # sigstore-produced signatures and certificates. run: >- gh release upload '${{ github.ref_name }}' dist/** @@ -94,16 +123,16 @@ jobs: publish-to-testpypi: name: Publish Python 🐍 distribution 📦 to TestPyPI - needs: - - build + needs: [auto-tag, build] + if: > + github.event_name == 'pull_request' || + (github.event_name == 'push' && needs.auto-tag.outputs.new_tag == 'true') runs-on: ubuntu-latest - environment: name: testpypi url: https://test.pypi.org/p/syclops - permissions: - id-token: write # IMPORTANT: mandatory for trusted publishing + id-token: write steps: - name: Download all the dists @@ -115,4 +144,4 @@ jobs: uses: pypa/gh-action-pypi-publish@release/v1 with: repository-url: https://test.pypi.org/legacy/ - skip_existing: true + skip_existing: true \ No newline at end of file diff --git a/.github/workflows/integration_test.yaml b/.github/workflows/integration_test.yaml index 8ae1246..d396fc8 100644 --- a/.github/workflows/integration_test.yaml +++ b/.github/workflows/integration_test.yaml @@ -3,8 +3,6 @@ name: Syclops Pipeline Test on: push: branches: [ main ] - tags: - - 'v*' # This will match any tag starting with 'v' pull_request: branches: [ main ] diff --git a/pyproject.toml b/pyproject.toml index ab06431..77059d2 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -13,7 +13,7 @@ readme = "README.md" requires-python = ">=3.8" license = {text = "GPLv3"} -version = "1.3.6" +version = "1.3.7" dynamic = ["dependencies"] From 8b348d4765ebead6edad00fd6abbf9af6b4bf992 Mon Sep 17 00:00:00 2001 From: Anton Elmiger Date: Wed, 17 Jul 2024 12:15:59 +0200 Subject: [PATCH 5/7] hotfix: Bump signing workflow version to dependency error --- .github/workflows/deploy_to_pypi.yaml | 2 +- .github/workflows/integration_test.yaml | 1 - pyproject.toml | 2 +- 3 files changed, 2 insertions(+), 3 deletions(-) diff --git a/.github/workflows/deploy_to_pypi.yaml b/.github/workflows/deploy_to_pypi.yaml index 905355e..8345b01 100644 --- a/.github/workflows/deploy_to_pypi.yaml +++ b/.github/workflows/deploy_to_pypi.yaml @@ -100,7 +100,7 @@ jobs: name: python-package-distributions path: dist/ - name: Sign the dists with Sigstore - uses: sigstore/gh-action-sigstore-python@v1.2.3 + uses: sigstore/gh-action-sigstore-python@v3.0.0 with: inputs: >- ./dist/*.tar.gz diff --git a/.github/workflows/integration_test.yaml b/.github/workflows/integration_test.yaml index d396fc8..142e7cf 100644 --- a/.github/workflows/integration_test.yaml +++ b/.github/workflows/integration_test.yaml @@ -10,7 +10,6 @@ jobs: build-and-test: name: Syclops Pipeline Test runs-on: ubuntu-latest - if: github.event_name == 'pull_request' || (github.event_name == 'push' && startsWith(github.ref, 'refs/tags/v')) steps: - name: Checkout repository diff --git a/pyproject.toml b/pyproject.toml index 77059d2..497a1e4 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -13,7 +13,7 @@ readme = "README.md" requires-python = ">=3.8" license = {text = "GPLv3"} -version = "1.3.7" +version = "1.3.8" dynamic = ["dependencies"] From 2499805d4e99185b2582566d9a866a36c02055e7 Mon Sep 17 00:00:00 2001 From: Anton Elmiger Date: Wed, 17 Jul 2024 12:28:07 +0200 Subject: [PATCH 6/7] hotfix: Correct naming of releases --- .github/workflows/deploy_to_pypi.yaml | 5 +++-- pyproject.toml | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/.github/workflows/deploy_to_pypi.yaml b/.github/workflows/deploy_to_pypi.yaml index 8345b01..b7f728f 100644 --- a/.github/workflows/deploy_to_pypi.yaml +++ b/.github/workflows/deploy_to_pypi.yaml @@ -13,6 +13,7 @@ jobs: if: github.event_name == 'push' && github.ref == 'refs/heads/main' outputs: new_tag: ${{ steps.create_tag.outputs.new_tag }} + version: ${{ steps.get_version.outputs.VERSION }} steps: - uses: actions/checkout@v4 @@ -110,7 +111,7 @@ jobs: GITHUB_TOKEN: ${{ github.token }} run: >- gh release create - '${{ github.ref_name }}' + '${{ needs.auto-tag.outputs.version }}' --repo '${{ github.repository }}' --notes "" - name: Upload artifact signatures to GitHub Release @@ -118,7 +119,7 @@ jobs: GITHUB_TOKEN: ${{ github.token }} run: >- gh release upload - '${{ github.ref_name }}' dist/** + '${{ needs.auto-tag.outputs.version }}' dist/** --repo '${{ github.repository }}' publish-to-testpypi: diff --git a/pyproject.toml b/pyproject.toml index 497a1e4..00e1343 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -13,7 +13,7 @@ readme = "README.md" requires-python = ">=3.8" license = {text = "GPLv3"} -version = "1.3.8" +version = "1.3.9" dynamic = ["dependencies"] From 55b51114752c730b92b1a86e44822acbcc8df0c7 Mon Sep 17 00:00:00 2001 From: aelmiger <40243985+aelmiger@users.noreply.github.com> Date: Mon, 6 Jan 2025 13:39:54 +0100 Subject: [PATCH 7/7] Bug/various fixes (#22) * refactor: Adjust dicing rate and fix displacement parameter handling * fix: Increase precision of keypoint location rounding * refactor: Simplify keypoint handling and improve naming conventions in keypoint_script * feat: Extend bounding box parsing to include rotation data in viewer_utils * refactor: Rename 'translation' to 'location' in base_schema.yaml for clarity * bump: Update version to 1.3.10 in pyproject.toml --- pyproject.toml | 2 +- syclops/blender/plugins/ground.py | 11 +++- syclops/blender/sensor_outputs/keypoints.py | 2 +- syclops/schema/base_schema.yaml | 2 +- syclops/utility/keypoint_script.py | 71 ++++++++------------- syclops/utility/viewer_utils.py | 3 +- 6 files changed, 38 insertions(+), 53 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 00e1343..250f858 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -13,7 +13,7 @@ readme = "README.md" requires-python = ">=3.8" license = {text = "GPLv3"} -version = "1.3.9" +version = "1.3.10" dynamic = ["dependencies"] diff --git a/syclops/blender/plugins/ground.py b/syclops/blender/plugins/ground.py index 0616b4a..56e8768 100644 --- a/syclops/blender/plugins/ground.py +++ b/syclops/blender/plugins/ground.py @@ -55,7 +55,7 @@ def _setup_modifiers(self, ground): bpy.context.object.modifiers["Subdivision"].subdivision_type = "SIMPLE" bpy.context.object.modifiers["Subdivision"].levels = 2 bpy.context.object.cycles.use_adaptive_subdivision = True - bpy.context.object.cycles.dicing_rate = 2.0 + bpy.context.object.cycles.dicing_rate = 1.0 def _setup_ground_material(self): """Configure the ground material.""" @@ -69,7 +69,7 @@ def _setup_ground_material(self): self._configure_node_mappings(nodes, texture["texture_size"]) self._import_and_set_images(nodes, root_path, texture) self._set_voronoi_scale(nodes) - self._set_displacement_scale(nodes, texture) + self._set_displacement_params(nodes, texture) def _configure_node_mappings(self, nodes, texture_size): scale = self.config["size"] / texture_size @@ -101,11 +101,16 @@ def _set_voronoi_scale(self, nodes): for node_name in ["Voronoi Texture", "Voronoi Texture.001"]: nodes.get(node_name).inputs["Scale"].default_value = scale_value - def _set_displacement_scale(self, nodes, texture): + def _set_displacement_params(self, nodes, texture): if "texture_displacement_scale" in texture: nodes.get("Displacement").inputs["Scale"].default_value = float( texture["texture_displacement_scale"] ) + if "texture_displacement_midlevel" in texture: + nodes.get("Displacement").inputs["Midlevel"].default_value = float( + texture["texture_displacement_midlevel"] + ) + def _setup_ground_geometry(self): """Create a plane, scale and subdivide according to the ground size.""" diff --git a/syclops/blender/sensor_outputs/keypoints.py b/syclops/blender/sensor_outputs/keypoints.py index 782c877..28f7273 100644 --- a/syclops/blender/sensor_outputs/keypoints.py +++ b/syclops/blender/sensor_outputs/keypoints.py @@ -53,7 +53,7 @@ def generate_output(self, parent_class: object): if class_id is not None: if "keypoints" in object_instance.object: location = object_instance.matrix_world.translation - location = [round(x, 4) for x in location] + location = [round(x, 6) for x in location] instance_id = self._calculate_instance_id(location) for keypoint, pos in object_instance.object["keypoints"].items(): vec = mathutils.Vector((pos['x'], pos['y'], pos['z'])) diff --git a/syclops/schema/base_schema.yaml b/syclops/schema/base_schema.yaml index 7a5e5d7..d9e70c9 100644 --- a/syclops/schema/base_schema.yaml +++ b/syclops/schema/base_schema.yaml @@ -129,7 +129,7 @@ definitions: velocities: type: object properties: - translation: + location: description: Translation velocity in meters per second $ref: "#/definitions/vector_evaluation" rotation: diff --git a/syclops/utility/keypoint_script.py b/syclops/utility/keypoint_script.py index dd890c8..fa0becc 100644 --- a/syclops/utility/keypoint_script.py +++ b/syclops/utility/keypoint_script.py @@ -1,66 +1,45 @@ -""" -Script to be used inside of Blender to add keypoint information to 3d objects -""" - import bpy import mathutils - -# Function to get relative position def get_relative_position(obj, target): return target.matrix_world.inverted() @ obj.matrix_world.translation - -# Function to create empties at keypoint positions relative to the mesh object def create_empties_from_keypoints(mesh_object): keypoints = mesh_object["keypoints"] for key, pos in keypoints.items(): - # Calculate the world position from the relative position - world_position = mesh_object.matrix_world @ mathutils.Vector( - (pos["x"], pos["y"], pos["z"]) - ) - # Create an empty and set its world position + world_position = mesh_object.matrix_world @ mathutils.Vector((pos["x"], pos["y"], pos["z"])) bpy.ops.object.empty_add(location=world_position) empty = bpy.context.active_object - empty.name = f"Keypoint_{key}" - + empty.name = f"Keypoint_{mesh_object.name}_{key}" + +def add_keypoints_to_mesh(mesh_object, empty_objects): + mesh_object["keypoints"] = {} + for index, empty in enumerate(empty_objects): + relative_pos = get_relative_position(empty, mesh_object) + mesh_object["keypoints"][str(index)] = { + "x": relative_pos.x, + "y": relative_pos.y, + "z": relative_pos.z, + } # Main script selected_objects = bpy.context.selected_objects -active_object = bpy.context.active_object - -# Case 1: Multiple objects selected, last is a mesh -if len(selected_objects) > 1 and active_object.type == "MESH": - selected_objects.remove(active_object) - selected_objects.sort(key=lambda x: x.name) - - keypoints = {} - - for index, obj in enumerate(selected_objects): - if obj.type == "EMPTY": - relative_pos = get_relative_position(obj, active_object) - keypoints[str(index)] = { - "x": relative_pos.x, - "y": relative_pos.y, - "z": relative_pos.z, - } - - if "keypoints" in active_object: - del active_object["keypoints"] - - active_object["keypoints"] = keypoints - print("Key points added to", active_object.name) - -# Case 2: Single mesh object with keypoints attribute +mesh_objects = [obj for obj in selected_objects if obj.type == "MESH"] +empty_objects = [obj for obj in selected_objects if obj.type == "EMPTY"] + +if mesh_objects and empty_objects: + # Sort empty objects by name + empty_objects.sort(key=lambda x: x.name) + + for mesh in mesh_objects: + add_keypoints_to_mesh(mesh, empty_objects) + print(f"Key points added to {mesh.name}") elif len(selected_objects) == 1 and selected_objects[0].type == "MESH": active_object = selected_objects[0] if "keypoints" in active_object: create_empties_from_keypoints(active_object) - print("Empties created from key points in", active_object.name) + print(f"Empties created from key points in {active_object.name}") else: - print("No keypoints attribute found in", active_object.name) - + print(f"No keypoints attribute found in {active_object.name}") else: - print( - "Please select either multiple objects with a mesh as the active object, or a single mesh with a keypoints attribute." - ) + print("Please select either multiple mesh objects and at least one empty, or a single mesh with a keypoints attribute.") \ No newline at end of file diff --git a/syclops/utility/viewer_utils.py b/syclops/utility/viewer_utils.py index e10721e..fd3e3ba 100644 --- a/syclops/utility/viewer_utils.py +++ b/syclops/utility/viewer_utils.py @@ -25,7 +25,7 @@ def read_and_draw_bounding_boxes(img, bb_path): bb_img = img.copy() for line in lines: - _, x_center, y_center, width, height = map(float, line.split()) + _, x_center, y_center, width, height, *_ = map(float, line.split()) x = int(x_center * img.shape[1] - width * img.shape[1] / 2) y = int(y_center * img.shape[0] - height * img.shape[0] / 2) w = int(width * img.shape[1]) @@ -127,6 +127,7 @@ def dataset_viewer(args): object_positions_dict = json.load(f) for _, poses in object_positions_dict.items(): location_list = [element["loc"] for element in poses] + rotation_list = [element["rot"] for element in poses] positions_array = np.array(location_list, dtype=np.float32).reshape( (-1, 3) )