From 80c2229b61c48b072687483952bd1614cc7903e4 Mon Sep 17 00:00:00 2001 From: ishaan95 Date: Mon, 5 Dec 2022 18:47:40 -0800 Subject: [PATCH] t junction meshes --- README.md | 10 ++++-- junction_four_way.py | 74 ++++++++++++++++++++++++++++++++++++++++++-- road_base.py | 22 ++++++------- 3 files changed, 91 insertions(+), 15 deletions(-) diff --git a/README.md b/README.md index 92b9fbb..6b2295f 100644 --- a/README.md +++ b/README.md @@ -5,6 +5,12 @@ Generate roads and scenarios for testing autonomous vehicles in simulation using * First, [download and install Blender](https://www.blender.org/download/). This is a 3D modeling tool. It has a [Python API](https://docs.blender.org/api/current/info_overview.html). This repository contains python scripts that make use of this API for generating roads. * Add the [Blender installation directory](https://docs.blender.org/manual/en/latest/advanced/command_line/launch/index.html) to the environment variable such that the command *blender* can be accessed from the command line. [Here](https://docs.blender.org/manual/en/latest/advanced/command_line/launch/macos.html) are the instructions for doing so on MacOS and [here](https://docs.blender.org/manual/en/latest/advanced/command_line/launch/windows.html) are the instructions for doing so on Windows. * Clone this repository and change directory to it. -* Run the python script *road_base.py* using the **Blender python only**. This will *register* the *pr* (procedural roads) set of operations. The command for this would be **blender --python road_base.py** +* Run the python script *road_base.py* using the **Blender python only**. This will *register* the *pr* (procedural roads) set of operations. The command for this would be **blender --python road_base.py**. * Run from the Blender python console, *bpy.ops.pr.road()*. This should generate a road in the 3D viewport. -* For further code editing, you can open the python script on Blender's text editor and click play for running the script. +* For further code editing, you can open the python script on Blender's text editor and click play for running the script. + +## Features to be implemented +- [] Junction creation capability: straight and curved roads, multiple incoming roads. +- [] OpenDRIVE export capability. +- [] Operator for procedurally generating buildings +- [] Operator for procedurally placing tree assets diff --git a/junction_four_way.py b/junction_four_way.py index 59d8758..6c309d0 100644 --- a/junction_four_way.py +++ b/junction_four_way.py @@ -13,12 +13,26 @@ import bpy from mathutils import Vector, Matrix - from math import pi +import os +import sys +import importlib + +# Make a change to path to be able to find files in the current directory. +dir = os.path.dirname(bpy.data.filepath) +if not dir in sys.path: + sys.path.append(dir) + +# Below this, import all the other python scripts in this project. +# Reload if the module python script has changed. import helper +importlib.reload(helper) +import road_base +importlib.reload(road_base) -class DSC_OT_junction_four_way(bpy.types.Operator): +# Creates a 4 units x 4 units square for a junction along with incoming roads. +class PR_OT_junction_four_way(bpy.types.Operator): bl_idname = 'pr.junction_four_way' bl_label = '4-way junction' bl_description = 'Create a junction' @@ -27,6 +41,38 @@ class DSC_OT_junction_four_way(bpy.types.Operator): object_type = 'junction_4way' snap_filter = 'OpenDRIVE' + # Input parameters for this operator + # pendx and pendy doesn't really matter + pstartx: bpy.props.FloatProperty() + pstarty: bpy.props.FloatProperty() + + locationx: bpy.props.FloatProperty() + locationy: bpy.props.FloatProperty() + + #Define the two param dictionaries. These decide how the road will be constructed. + def init_state(self): + self.params_input = { + 'point_start': Vector((self.pstartx,self.pstarty,0.0)), + 'point_end': Vector((0.0,0.0,0.0)), + 'heading_start': 0, + 'heading_end': 0, + 'curvature_start': 2, + 'curvature_end': 0, + 'slope_start': 0, + 'slope_end': 0, + 'connected_start': True, + 'connected_end': False, + 'design_speed': 130.0, + } + self.params_snap = { + 'id_obj': None, + 'point': Vector((0.0,0.0,0.0)), + 'type': 'cp_none', + 'heading': 0, + 'curvature': 0, + 'slope': 0, + } + def create_3d_object(self, context): ''' Create a junction object @@ -137,5 +183,29 @@ def update_params_get_mesh(self, context, wireframe): # TODO implement material dictionary for the faces materials = {} return valid, mesh, matrix_world, materials + + # TODO Define a function that aligns the dimensions of the meshes + + def execute(self, context): + ''' + Called every time your operator runs + ''' + self.init_state() + bpy.ops.pr.road(pstartx=0.0, pstarty=0.0, pendx=20.0, pendy=0.0) + self.create_3d_object(context) + bpy.ops.pr.road(pstartx=28.0, pstarty=0.0, pendx=60.0, pendy=0.0) + bpy.ops.pr.road(pstartx=24.0, pstarty=4.0, pendx=24.0, pendy=50.0) + return {'FINISHED'} + +def register(): + road_base.register() + bpy.utils.register_class(PR_OT_junction_four_way) + +def unregister(): + road_base.unregister() + bpy.utils.unregister_class(PR_OT_junction_four_way) + +if __name__ == '__main__': + register() diff --git a/road_base.py b/road_base.py index afd9bad..2a2bacb 100644 --- a/road_base.py +++ b/road_base.py @@ -48,17 +48,24 @@ class PR_OT_road(bpy.types.Operator): params = {} + # Properties are used to pass in values into the operator + # Therefore when the operator is used as bpy.ops.. this value can just be used as a parameter geometry_solver: bpy.props.StringProperty( name='Geometry solver', description='Solver used to determine geometry parameters.', options={'HIDDEN'}, default='default') + + pstartx: bpy.props.FloatProperty() + pstarty: bpy.props.FloatProperty() + pendx: bpy.props.FloatProperty() + pendy: bpy.props.FloatProperty() #Define the two param dictionaries. These decide how the road will be constructed. def init_state(self): self.params_input = { - 'point_start': Vector((0.0,0.0,0.0)), - 'point_end': Vector((100.0,0.0,0.0)), + 'point_start': Vector((self.pstartx, self.pstarty, 0.0)), + 'point_end': Vector((self.pendx, self.pendy, 0.0)), 'heading_start': 0, 'heading_end': 0, 'curvature_start': 2, @@ -725,15 +732,8 @@ def execute(self, context): ''' self.init_state() self.create_3d_object(context) - # length_broken_line = context.scene.road_properties.length_broken_line - # self.set_lane_params(context.scene.road_properties) - # lanes = context.scene.road_properties.lanes - # # Get values in t and s direction where the faces of the road start and end - # strips_s_boundaries = self.get_strips_s_boundaries(lanes, length_broken_line) - # # Calculate meshes for Blender - # road_sample_points = self.get_road_sample_points(lanes, strips_s_boundaries) - # vertex_loc_middle = int(len(road_sample_points[5][0])/2) - # bpy.ops.mesh.primitive_cube_add(location = [road_sample_points[5][0][vertex_loc_middle][1]+5, road_sample_points[5][0][vertex_loc_middle][0], 0]) + xyz = self.get_xyz_any_s(10.0, 10.0) + bpy.ops.mesh.primitive_cube_add(location= xyz) return {'FINISHED'} def register():