Skip to content

Commit

Permalink
Bug/various fixes (#22)
Browse files Browse the repository at this point in the history
* 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
  • Loading branch information
aelmiger authored Jan 6, 2025
1 parent 2499805 commit 55b5111
Show file tree
Hide file tree
Showing 6 changed files with 38 additions and 53 deletions.
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ readme = "README.md"
requires-python = ">=3.8"
license = {text = "GPLv3"}

version = "1.3.9"
version = "1.3.10"

dynamic = ["dependencies"]

Expand Down
11 changes: 8 additions & 3 deletions syclops/blender/plugins/ground.py
Original file line number Diff line number Diff line change
Expand Up @@ -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."""
Expand All @@ -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
Expand Down Expand Up @@ -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."""
Expand Down
2 changes: 1 addition & 1 deletion syclops/blender/sensor_outputs/keypoints.py
Original file line number Diff line number Diff line change
Expand Up @@ -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']))
Expand Down
2 changes: 1 addition & 1 deletion syclops/schema/base_schema.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,7 @@ definitions:
velocities:
type: object
properties:
translation:
location:
description: Translation velocity in meters per second
$ref: "#/definitions/vector_evaluation"
rotation:
Expand Down
71 changes: 25 additions & 46 deletions syclops/utility/keypoint_script.py
Original file line number Diff line number Diff line change
@@ -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.")
3 changes: 2 additions & 1 deletion syclops/utility/viewer_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -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])
Expand Down Expand Up @@ -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)
)
Expand Down

0 comments on commit 55b5111

Please sign in to comment.