Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature/additional scatter plugins #10

Merged
merged 8 commits into from
Apr 15, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
49 changes: 49 additions & 0 deletions docs/docs/usage/job_description/config_descriptions/crop.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
# Crop Plugin Documentation

The Crop Plugin scatters 3D models on a floor object in a grid pattern to simulate crop rows.

## Configuration Parameters

The following table describes each configuration parameter for the Crop Plugin:

| Parameter | Type | Description | Requirement |
|-----------|------|-------------|-------------|
| `name` | string | Unique identifier of the plugin | **Required** |
| `models` | array or single item | 3D assets to scatter. | **Required** |
| `floor_object` | string | Name of the floor object to scatter on. | **Required** |
| `max_texture_size` | integer | Maximum texture size in pixel. Will reduce the texture to save GPU RAM. | Optional |
| `density_map` | image/texture evaluation | Texture that alters the density. It is normalized to 0-1. | Optional |
| `decimate_mesh_factor` | number (0-1) | Factor between 0-1 that decimates the number of vertices of the mesh. Lower means less vertices. | Optional |
| `scale_standard_deviation` | number evaluation | Scale variance of the scattered objects. | **Required** |
| `class_id` | integer | Class ID for ground truth output. | **Required** |
| `crop_angle` | number evaluation | Global orientation of the row direction in degrees. | **Required** |
| `row_distance` | number evaluation | Distance between rows in meters. | **Required** |
| `row_standard_deviation` | number evaluation | Standard deviation of the row distance in meters. | **Required** |
| `plant_distance` | number evaluation | Intra row distance between plants in meters. | **Required** |
| `plant_standard_deviation` | number evaluation | Standard deviation of the intra row distance in meters. | **Required** |

### Dynamic Evaluators

Most parameters, like `scale_standard_deviation`, `crop_angle` etc., can be dynamically evaluated. This means that their values can be altered for each new frame. For more insights on dynamic evaluators and how to use them, kindly refer to [Dynamic Evaluators](../dynamic_evaluators.md).

## Example Configuration

```yaml
scene:
syclops_plugin_crop:
- name: "Corn Crop"
models: Example Assets/Corn
floor_object: "Ground"
max_texture_size: 2048
scale_standard_deviation: 0.1
class_id: 2
crop_angle: 45
row_distance: 1
row_standard_deviation: 0.1
plant_distance: 0.3
plant_standard_deviation: 0.05
```

The above configuration will scatter corn models across the ground surface in a grid pattern resembling crop rows. The rows will be oriented at a 45 degree angle, with 1 meter spacing between rows and 30 cm spacing between plants. The row and plant spacings will vary according to the specified standard deviations.


Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
# Simulated Scatter Plugin Documentation

The Simulated Scatter Plugin scatters 3D assets on a floor object and simulates physics to drop them realistically on the surface.

## Configuration Parameters

The following table describes each configuration parameter for the Simulated Scatter Plugin:

| Parameter | Type | Description | Requirement |
|-----------|------|-------------|-------------|
| `name` | string | Unique identifier of the plugin | **Required** |
| `models` | array or single item | 3D assets to scatter. | **Required** |
| `floor_object` | string | Name of the floor object to scatter on. | **Required** |
| `max_texture_size` | integer | Maximum texture size in pixels. Will reduce the texture to save GPU RAM. | Optional |
| `decimate_mesh_factor` | number (0-1) | Factor between 0-1 that decimates the number of vertices of the mesh. Lower means less vertices. | Optional |
| `density` | number | Density of objects per square meter. | **Required** |
| `density_texture` | image/texture evaluation | Texture that alters the density per pixel. Needs to be a single channel image that is normalized to 0-1. | Optional |
| `scale_std` | number | Standard deviation of the scale randomization. | **Required** |
| `convex_decomposition_quality` | integer (1-100) | Quality setting for the convex decomposition. Higher means more accurate but slower. | **Required** |
| `simulation_steps` | integer | Number of simulation steps to run. | **Required** |

### Dynamic Evaluators

Parameters like `density_texture` and `scale_std` can be dynamically evaluated. This means that their values can be altered for each new frame. For more insights on dynamic evaluators and how to use them, kindly refer to [Dynamic Evaluators](../dynamic_evaluators.md).

## Example Configuration

```yaml
scene:
syclops_plugin_simulated_scatter:
- name: "Rock Scatter"
models: Example Assets/Rocks
floor_object: "Ground"
max_texture_size: 2048
density: 5
scale_std: 0.3
convex_decomposition_quality: 90
simulation_steps: 100
```

The above configuration will scatter rock models across the ground surface. The rocks will be dropped from above and settle into physically realistic positions using a convex decomposition simulation. The simulation will run for 100 steps to allow the rocks to come to rest.
2 changes: 2 additions & 0 deletions docs/mkdocs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,8 @@ nav:
- Environment: usage/job_description/config_descriptions/environment.md
- Object: usage/job_description/config_descriptions/object.md
- Scatter: usage/job_description/config_descriptions/scatter.md
- Crop: usage/job_description/config_descriptions/crop.md
- Simulated Scatter: usage/job_description/config_descriptions/simulated_scatter.md
- Sensor Configuration:
- Camera: usage/job_description/config_descriptions/camera.md
- Output Configuration:
Expand Down
2 changes: 2 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ syclops_plugin_ground = "syclops.blender.plugins.ground:Ground"
syclops_plugin_environment = "syclops.blender.plugins.environment:Environment"
syclops_plugin_scatter = "syclops.blender.plugins.scatter:Scatter"
syclops_plugin_object = "syclops.blender.plugins.object:Object"
syclops_plugin_simulated_scatter = "syclops.blender.plugins.simulated_scatter:SimulatedScatter"
syclops_plugin_crop = "syclops.blender.plugins.crop:Crop"
[project.entry-points."syclops.sensors"]
syclops_sensor_camera = "syclops.blender.sensors.camera:Camera"
[project.entry-points."syclops.outputs"]
Expand Down
14 changes: 9 additions & 5 deletions syclops/__example_assets__/example_job.syclops.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -51,18 +51,22 @@ scene:
environment_image:
random_selection: [Example Assets/Sunflower Field]

syclops_plugin_scatter:
- name: "Corn Scatter"
syclops_plugin_crop:
- name: "Corn"
models: [Example Assets/Corn]
floor_object: Ground
max_texture_size: 512
density_max: 10 # per m^2
distance_min: 0.05 # m
crop_angle: 0 # degrees; [-90, 90] possible
row_distance: 0.6 # m
row_standard_deviation: 0.2 # m
plant_distance: 0.1
plant_standard_deviation: 0.1 # m
scale_standard_deviation: 0.5
class_id: 2
class_id_offset:
Stem: 1
seed: 1

syclops_plugin_scatter:
- name: "Weed Scatter"
models: [Example Assets/Plain Weeds]
floor_object: Ground
Expand Down
49 changes: 28 additions & 21 deletions syclops/__example_assets__/test_job.syclops.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -9,19 +9,19 @@ denoising_algorithm: "OPENIMAGEDENOISE"

# TRANSFORMATION CONFIG
transformations:
map:
map:
location: [0, 0, 0]
rotation: [0, 0, 0]
children:
camera_link:
location:
linear: [[-20,0,2],[0.5,0,0]]
rotation:
normal: [[0.785398, 0, 0],[0.05,0.05,0.05]]
linear: [[-20, 0, 2], [0.5, 0, 0]]
rotation:
normal: [[0.785398, 0, 0], [0.05, 0.05, 0.05]]
iso_object:
location:
uniform: [[-20,-20,0],[20,20,0]]
rotation: [0,0,0]
uniform: [[-20, -20, 0], [20, 20, 0]]
rotation: [0, 0, 0]

textures:
plain_noise:
Expand All @@ -48,27 +48,35 @@ scene:

syclops_plugin_environment:
- type: hdri
environment_image:
environment_image:
random_selection: [Example Assets/Sunflower Field]

syclops_plugin_scatter:
- name: "Corn Scatter"
syclops_plugin_simulated_scatter:
- name: "ISO Object Scatter"
models: Example Assets/ISO Object
floor_object: Ground
class_id: 1
simulation_steps: 5
std_scale: 1
density: 0.01
convex_decomposition_quality: 90

syclops_plugin_crop:
- name: "Corn"
models: [Example Assets/Corn]
floor_object: Ground
max_texture_size: 512
density_max: 10 # per m^2
distance_min: 0.05 # m
crop_angle: 0 # degrees; [-90, 90] possible
row_distance: 0.6 # m
row_standard_deviation: 0.2 # m
plant_distance: 0.1
plant_standard_deviation: 0.1 # m
scale_standard_deviation: 0.5
class_id: 2
class_id_offset:
Stem: 1
seed: 1
clumps:
ratio: 0.3
size: 3
size_std: 2
position_std: 0.02
scale_std: 0.4

syclops_plugin_scatter:
- name: "Weed Scatter"
models: [Example Assets/Plain Weeds]
floor_object: Ground
Expand All @@ -93,7 +101,6 @@ scene:
models: [Example Assets/ISO Object]
floor_object: Ground


# SENSOR CONFIG
sensor:
syclops_sensor_camera:
Expand Down Expand Up @@ -151,7 +158,7 @@ sensor:
postprocessing:
syclops_postprocessing_bounding_boxes:
- type: "YOLO"
classes_to_skip: [0,1]
classes_to_skip: [0, 1]
id: yolo_bound_boxes
sources: ["main_cam_instance", "main_cam_semantic"]
multiple_bb_per_instance: False
multiple_bb_per_instance: False
80 changes: 80 additions & 0 deletions syclops/blender/plugins/crop.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
"""This module contains the Crop plugin for Syclops.

It is used to place objects in a row like fashion to simulate crop.
"""

import logging

import bpy
from syclops import utility
from syclops.blender.plugins.plugin_interface import PluginInterface


class Crop(PluginInterface):
"""Plugin scatters objects in a row like fashion to simulate crop."""

crop: utility.ObjPointer

def load(self):
"""Load everything into the scene but does not configure it."""
self.create_base_object()
self.load_instance_objects()
self.load_geometry_nodes()
logging.info("Crop: {0} loaded".format(self.config["name"]))

def load_geometry_nodes(self):
"""Load geometry nodes from .blend file and assigns them to the crop."""
# Add crop node group to the scene
node_group_name = "Crop"
blend_path = utility.abs_path("./plugin_data/crop.blend")

crop_nodes = utility.load_from_blend(
blend_path,
"node_groups",
node_group_name,
)[0]

# Create GeoNode Modifier
self.geo_node_modifier = self.crop.get().modifiers.new(
self.config["name"],
"NODES",
)
self.geo_node_modifier.show_viewport = False
self.geo_node_modifier.node_group = crop_nodes

def load_instance_objects(self):
"""Load crop geometry."""
# Create new collection and assign a pointer
self.instance_objects = utility.ObjPointer(
utility.create_collection("{0}_Objs".format(self.config["name"])),
)
utility.set_active_collection(self.instance_objects.get())

# Import the geometry
loaded_objs = utility.import_assets(self.config["models"])
for obj in loaded_objs:
self.reduce_size(obj)
obj.hide_set(True)
self.write_config(obj)
self.instance_objects.get().hide_render = True

def create_base_object(self):
"""Add placeholder object to assign GeoNode Modifier to."""
# Setup a blender collection
collection = utility.create_collection(self.config["name"])
utility.set_active_collection(collection)

# Setup GeoNodes
bpy.ops.mesh.primitive_plane_add()
bpy.context.active_object.name = self.config["name"]
self.crop = utility.ObjPointer(bpy.context.active_object)

def configure(self):
"""Apply configuration for current frame."""
# Refresh References
self.geo_node_modifier = self.crop.get().modifiers[self.config["name"]]
# Configure settings from config
self.configure_settings()
for obj in self.instance_objects.get().objects:
utility.add_volume_attribute(obj)
logging.info("Crop: {0} configured".format(self.config["name"]))
Binary file added syclops/blender/plugins/plugin_data/crop.blend
Binary file not shown.
Binary file not shown.
66 changes: 66 additions & 0 deletions syclops/blender/plugins/schema/crop.schema.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
description: Scatters 3D models on a floor object in a grid pattern.
type: array
items:
type: object
properties:
name:
description: Unique identifier of the plugin
type: string
models:
description: 3D assets to scatter.
oneOf:
- type: array
items:
$ref: "#/definitions/asset_models"
- $ref: "#/definitions/asset_models"
floor_object:
description: Name of the floor object to scatter on.
type: string
max_texture_size:
description: Maximum texture size in pixel. Will reduce the texture to save GPU RAM.
type: integer
density_map:
description: Texture that alters the density. It is normalized to 0-1.
$ref: "#/definitions/image_texture_evaluation"
decimate_mesh_factor:
description: Factor between 0-1 that decimates the number of vertices of the mesh. Lower means less vertices.
type: number
scale_standard_deviation:
description: Scale variance of the scattered objects.
$ref: "#/definitions/number_evaluation"
class_id:
description: Class ID for ground truth output.
type: integer
class_id_offset:
description: Class ID offset for ground truth output. The keys are the name of the material and the values are the offsets.
type: object
additionalProperties:
type: integer
crop_angle:
description: Global orientation of the row direction in degrees.
$ref: "#/definitions/number_evaluation"
row_distance:
description: Distance between rows in meters.
$ref: "#/definitions/number_evaluation"
row_standard_deviation:
description: Standard deviation of the row distance in meters.
$ref: "#/definitions/number_evaluation"
plant_distance:
description: Intra row distance between plants in meters.
$ref: "#/definitions/number_evaluation"
plant_standard_deviation:
description: Standard deviation of the intra row distance in meters.
$ref: "#/definitions/number_evaluation"

required:
[
name,
models,
floor_object,
scale_standard_deviation,
row_distance,
plant_distance,
crop_angle,
row_standard_deviation,
plant_standard_deviation,
]
Loading
Loading