diff --git a/README.md b/README.md index 343b396..7e6f4c1 100644 --- a/README.md +++ b/README.md @@ -182,7 +182,7 @@ recommendable. It allows hot reloading and rapid iterations. # How to run the test -There is a handfull of tests for the geometries in the `tests/` directory. They +There is a handful of tests for the geometries in the `tests/` directory. They can be run by executing pytest from the Blender python distribution in the project root directory diff --git a/addon/geometry.py b/addon/geometry.py index c5e1e13..fb85c5e 100644 --- a/addon/geometry.py +++ b/addon/geometry.py @@ -445,7 +445,7 @@ def calculate_elevation(self, s): elevation['d'] * s_section**3 return z, curvature_elevation - def sample_cross_section(self, s, t_vec): + def sample_cross_section(self, s, t_vec, with_lane_offset): ''' Sample a cross section (multiple t values) in the local coordinate system. Also return corresponding curvature and heading of the @@ -458,7 +458,10 @@ def sample_cross_section(self, s, t_vec): vector_hdg_t.rotate(Matrix.Rotation(hdg + pi/2, 2)) xyz = [] for t in t_vec: - lane_offset = helpers.calculate_lane_offset(s, self.lane_offset_coefficients, self.total_length) + if with_lane_offset: + lane_offset = helpers.calculate_lane_offset(s, self.lane_offset_coefficients, self.total_length) + else: + lane_offset = 0 xy_vec = Vector((x_s, y_s)) + t * vector_hdg_t + lane_offset * vector_hdg_t xyz += [(xy_vec.x, xy_vec.y, z)] return xyz, hdg, curvature_abs diff --git a/addon/modal_road_object_base.py b/addon/modal_road_object_base.py index d169c80..4e03f85 100644 --- a/addon/modal_road_object_base.py +++ b/addon/modal_road_object_base.py @@ -330,7 +330,7 @@ def modal(self, context, event): # Recalculate the selected point by transforming back from the calculated Frenet coordinates selected_point_new = self.selected_geometry.matrix_world @ \ Vector(self.selected_geometry.sample_cross_section( - self.params_input['point_s'], [self.params_input['point_t']])[0][0]) + self.params_input['point_s'], [self.params_input['point_t']], False)[0][0]) if event.alt: # Calculate angular change to update start heading heading_difference = self.calculate_heading_start_difference( @@ -359,7 +359,7 @@ def modal(self, context, event): return {'RUNNING_MODAL'} if self.state == 'SELECT_ROAD': if self.params_snap['id_obj'] != None: - self.selected_geometry = load_geometry(self.selected_road['dsc_type'], self.selected_road['geometry']) + self.selected_geometry = load_geometry(self.selected_road['dsc_type'], self.selected_road['geometry'], self.selected_road['lane_offset_coefficients']) self.id_road = self.params_snap['id_obj'] self.id_lane = self.params_snap['id_lane'] # Set elevation so that end point selection starts on the same level diff --git a/addon/road.py b/addon/road.py index 1a82cd0..93b71db 100644 --- a/addon/road.py +++ b/addon/road.py @@ -276,7 +276,7 @@ def get_split_cps(self): cp_base = self.geometry.sections[-1]['point_end'] # Split cp_split = self.geometry.matrix_world @ Vector(self.geometry.sample_cross_section( - t, [t_cp_split])[0][0]) + t, [t_cp_split])[0][0], True) # Check which part of the split contains the center lane, that part # gets the contact point on the center lane if t_cp_split < 0: @@ -481,7 +481,7 @@ def get_road_sample_points(self, lanes, strips_s_boundaries): s = 0 strips_t_values = self.get_strips_t_values(lanes, s) # Obtain first curvature value - xyz_samples, hdg, curvature_abs = self.geometry.sample_cross_section(0, strips_t_values) + xyz_samples, hdg, curvature_abs = self.geometry.sample_cross_section(0, strips_t_values, True) # We need 2 vectors for each strip to later construct the faces with one # list per face on each side of each strip sample_points = [[[]] for _ in range(2 * (len(strips_t_values) - 1))] @@ -506,7 +506,7 @@ def get_road_sample_points(self, lanes, strips_s_boundaries): # Sample next points along road geometry (all t values for current s value) strips_t_values = self.get_strips_t_values(lanes, s) - xyz_samples, hdg, curvature_abs = self.geometry.sample_cross_section(s, strips_t_values) + xyz_samples, hdg, curvature_abs = self.geometry.sample_cross_section(s, strips_t_values, True) point_index = -2 while point_index < len(sample_points) - 2: point_index = point_index + 2 @@ -532,7 +532,7 @@ def get_road_sample_points(self, lanes, strips_s_boundaries): # Sample the geometry t_values = [strips_t_values[idx_strip], strips_t_values[idx_strip + 1]] xyz_boundary, hdg, curvature_abs = self.geometry.sample_cross_section( - s_boundaries_next[idx_smaller], t_values) + s_boundaries_next[idx_smaller], t_values, True) if idx_smaller == 0: # Append left extra point sample_points[2 * idx_strip][idx_boundaries[1]].append(xyz_boundary[0]) diff --git a/tests/test_geometry_arc.py b/tests/test_geometry_arc.py index 9cfd24d..991ef03 100644 --- a/tests/test_geometry_arc.py +++ b/tests/test_geometry_arc.py @@ -32,7 +32,7 @@ def test_geometry_arc_straight_case(): # Sample the first section length_0 = geometry.total_length - xyz_local_0, h_0, c_0 = geometry.sample_cross_section(s=length_0, t_vec=[0.0]) + xyz_local_0, h_0, c_0 = geometry.sample_cross_section(s=length_0, t_vec=[0.0], with_lane_offset=False) xyz_global_0 = geometry.matrix_world @ Vector(xyz_local_0[0]) assert [xyz_global_0.x, xyz_global_0.y, xyz_global_0.z] == approx([6.0, 3.0, 0.0], 1e-5) @@ -43,13 +43,13 @@ def test_geometry_arc_straight_case(): # Sample the first section again length_0 = geometry.sections[0]['length'] - xyz_local_0, h_0, c_0 = geometry.sample_cross_section(s=length_0, t_vec=[0.0]) + xyz_local_0, h_0, c_0 = geometry.sample_cross_section(s=length_0, t_vec=[0.0], with_lane_offset=False) xyz_global_0 = geometry.matrix_world @ Vector(xyz_local_0[0]) assert [xyz_global_0.x, xyz_global_0.y, xyz_global_0.z] == approx([6.0, 3.0, 0.0], 1e-5) # Sample the second section length_1 = geometry.total_length - xyz_local_1, h_0, c_1 = geometry.sample_cross_section(s=length_1, t_vec=[0.0]) + xyz_local_1, h_0, c_1 = geometry.sample_cross_section(s=length_1, t_vec=[0.0], with_lane_offset=False) xyz_global_1 = geometry.matrix_world @ Vector(xyz_local_1[0]) assert [xyz_global_1.x, xyz_global_1.y, xyz_global_1.z] == approx([8.0, 4.0, 0.0], 1e-5) @@ -64,7 +64,7 @@ def test_geometry_arc_180(): geometry.update(params_input, 0.0, 0.0 solver) length_0 = geometry.total_length - xyz_local_0, h_0, c_0 = geometry.sample_cross_section(s=length_0/2, t_vec=[0.0]) + xyz_local_0, h_0, c_0 = geometry.sample_cross_section(s=length_0/2, t_vec=[0.0], with_lane_offset=False) xyz_global_0 = geometry.matrix_world @ Vector(xyz_local_0[0]) assert [xyz_global_0.x, xyz_global_0.y, xyz_global_0.z] == approx([1.0, 1.0, 0.0], 1e-5) @@ -78,7 +78,7 @@ def test_geometry_arc_negative_start_heading(): geometry.add_section() geometry.update(params_input, 0.0, 0.0 solver) - xyz_local, h, c = geometry.sample_cross_section(s=geometry.total_length, t_vec=[sqrt(2.0)]) + xyz_local, h, c = geometry.sample_cross_section(s=geometry.total_length, t_vec=[sqrt(2.0)], with_lane_offset=False) xyz_global = geometry.matrix_world @ Vector(xyz_local[0]) assert [xyz_global.x, xyz_global.y, xyz_global.z] == approx([-2.0, 0.0, 0.0], abs=1e-5) @@ -94,7 +94,7 @@ def test_geometry_arc_y_axis_straight(): geometry.update(params_input, 0.0, 0.0 solver) length_0 = geometry.total_length - xyz_local_0, h_0, c_0 = geometry.sample_cross_section(s=length_0/2, t_vec=[0.0]) + xyz_local_0, h_0, c_0 = geometry.sample_cross_section(s=length_0/2, t_vec=[0.0], with_lane_offset=False) xyz_global_0 = geometry.matrix_world @ Vector(xyz_local_0[0]) assert [xyz_global_0.x, xyz_global_0.y, xyz_global_0.z] == approx([0.0, 1.0, 0.0], abs=1e-5) @@ -110,7 +110,7 @@ def test_geometry_arc_270_three_pieces(): geometry.update(params_input, 0.0, 0.0 solver) length_0 = geometry.total_length - xyz_local, h_0, c_0 = geometry.sample_cross_section(s=length_0, t_vec=[5.0]) + xyz_local, h_0, c_0 = geometry.sample_cross_section(s=length_0, t_vec=[5.0], with_lane_offset=False) xyz_global = geometry.matrix_world @ Vector(xyz_local[0]) assert [xyz_global.x, xyz_global.y, xyz_global.z] == approx([15.0, 20.0, 0.0], 1e-5) @@ -121,7 +121,7 @@ def test_geometry_arc_270_three_pieces(): geometry.update(params_input, 0.0, 0.0 solver) length = geometry.total_length - xyz_local, h_0, c_0 = geometry.sample_cross_section(s=length, t_vec=[2.0]) + xyz_local, h_0, c_0 = geometry.sample_cross_section(s=length, t_vec=[2.0], with_lane_offset=False) xyz_global = geometry.matrix_world @ Vector(xyz_local[0]) assert [xyz_global.x, xyz_global.y, xyz_global.z] == approx([10.0, 28.0, 0.0], 1e-5) @@ -133,6 +133,6 @@ def test_geometry_arc_270_three_pieces(): geometry.update(params_input, 0.0, 0.0 solver) length = geometry.total_length - xyz_local, h_0, c_0 = geometry.sample_cross_section(s=length, t_vec=[-5.0]) + xyz_local, h_0, c_0 = geometry.sample_cross_section(s=length, t_vec=[-5.0], with_lane_offset=False) xyz_global = geometry.matrix_world @ Vector(xyz_local[0]) assert [xyz_global.x, xyz_global.y, xyz_global.z] == approx([-5.0, 20.0, 0.0], 1e-5) \ No newline at end of file diff --git a/tests/test_geometry_clothoid.py b/tests/test_geometry_clothoid.py index 31cd736..3721cb6 100644 --- a/tests/test_geometry_clothoid.py +++ b/tests/test_geometry_clothoid.py @@ -30,7 +30,7 @@ def test_geometry_clothoid(): geometry.update(params_input, 0.0, 0.0 solver) length_0 = geometry.total_length - xyz_local_0, h_0, c_0 = geometry.sample_cross_section(s=length_0, t_vec=[0.0]) + xyz_local_0, h_0, c_0 = geometry.sample_cross_section(s=length_0, t_vec=[0.0, with_lane_offset=False]) xyz_global_0 = geometry.matrix_world @ Vector(xyz_local_0[0]) assert [xyz_global_0.x, xyz_global_0.y, xyz_global_0.z] == approx([6.0, 3.0, 0.0], 1e-5) @@ -39,11 +39,11 @@ def test_geometry_clothoid(): geometry.update(params_input, 0.0, 0.0 solver) length_0 = geometry.sections[0]['length'] - xyz_local_0, h_0, c_0 = geometry.sample_cross_section(s=length_0, t_vec=[0.0]) + xyz_local_0, h_0, c_0 = geometry.sample_cross_section(s=length_0, t_vec=[0.0], with_lane_offset=False) xyz_global_0 = geometry.matrix_world @ Vector(xyz_local_0[0]) assert [xyz_global_0.x, xyz_global_0.y, xyz_global_0.z] == approx([6.0, 3.0, 0.0], 1e-5) length_1 = geometry.total_length - xyz_local_1, h_1, c_1 = geometry.sample_cross_section(s=length_1, t_vec=[0.0]) + xyz_local_1, h_1, c_1 = geometry.sample_cross_section(s=length_1, t_vec=[0.0], with_lane_offset=False) xyz_global_1 = geometry.matrix_world @ Vector(xyz_local_1[0]) assert [xyz_global_1.x, xyz_global_1.y, xyz_global_1.z] == approx([8.0, 4.0, 0.0], 1e-5) diff --git a/tests/test_geometry_line.py b/tests/test_geometry_line.py index 1f3a398..5cf7ca2 100644 --- a/tests/test_geometry_line.py +++ b/tests/test_geometry_line.py @@ -28,7 +28,7 @@ def test_geometry_line_1d(): geometry.add_section() geometry.update(params_input, 0.0, 0.0, None) length = geometry.total_length - xyz_local, h, c = geometry.sample_cross_section(s=length/2.0, t_vec=[0.0]) + xyz_local, h, c = geometry.sample_cross_section(s=length/2.0, t_vec=[0.0], with_lane_offset=False) xyz_global = geometry.matrix_world @ Vector(xyz_local[0]) assert [xyz_global.x, xyz_global.y, xyz_global.z] == approx([15.0, 10.0, 0.0], 1e-5) @@ -37,7 +37,7 @@ def test_geometry_line_1d(): geometry.update(params_input, 0.0, 0.0, None) length = geometry.total_length length_section = geometry.sections[1]['length'] - xyz_local, h, c = geometry.sample_cross_section(s=length-length_section/2, t_vec=[0.0]) + xyz_local, h, c = geometry.sample_cross_section(s=length-length_section/2, t_vec=[0.0], with_lane_offset=False) xyz_global = geometry.matrix_world @ Vector(xyz_local[0]) assert [xyz_global.x, xyz_global.y, xyz_global.z] == approx([25.0, 10.0, 0.0], 1e-5) @@ -51,7 +51,7 @@ def test_geometry_line_2d(): geometry.add_section() geometry.update(params_input, 0.0, 0.0, None) length = geometry.total_length - xyz_local, h, c = geometry.sample_cross_section(s=length/2.0, t_vec=[0.0]) + xyz_local, h, c = geometry.sample_cross_section(s=length/2.0, t_vec=[0.0], with_lane_offset=False) xyz_global = geometry.matrix_world @ Vector(xyz_local[0]) assert [xyz_global.x, xyz_global.y, xyz_global.z] == approx([40.0, 20.0, 0.0], 1e-5) @@ -60,7 +60,7 @@ def test_geometry_line_2d(): geometry.update(params_input, 0.0, 0.0, None) length = geometry.total_length length_section = geometry.sections[1]['length'] - xyz_local, h, c = geometry.sample_cross_section(s=length-length_section/2, t_vec=[0.0]) + xyz_local, h, c = geometry.sample_cross_section(s=length-length_section/2, t_vec=[0.0], with_lane_offset=False) xyz_global = geometry.matrix_world @ Vector(xyz_local[0]) assert [xyz_global.x, xyz_global.y, xyz_global.z] == approx([80.0, 40.0, 0.0], 1e-5) @@ -69,7 +69,7 @@ def test_geometry_line_2d(): geometry.add_section() geometry.update(params_input, 0.0, 0.0, None) length = geometry.total_length - xyz_local, h, c = geometry.sample_cross_section(s=length, t_vec=[0.0]) + xyz_local, h, c = geometry.sample_cross_section(s=length, t_vec=[0.0], with_lane_offset=False) xyz_global = geometry.matrix_world @ Vector(xyz_local[0]) assert [xyz_global.x, xyz_global.y, xyz_global.z] == approx([320.0, 160.0, 0.0], 1e-5) @@ -83,7 +83,7 @@ def test_geometry_line_2d_projection(): geometry.add_section() geometry.update(params_input, 0.0, 0.0, None) length = geometry.total_length - xyz_local, h, c = geometry.sample_cross_section(s=length/2.0, t_vec=[0.0]) + xyz_local, h, c = geometry.sample_cross_section(s=length/2.0, t_vec=[0.0], with_lane_offset=False) xyz_global = geometry.matrix_world @ Vector(xyz_local[0]) assert [xyz_global.x, xyz_global.y, xyz_global.z] == approx([40.0, 20.0, 0.0], 1e-5) @@ -92,7 +92,7 @@ def test_geometry_line_2d_projection(): geometry.update(params_input, 0.0, 0.0, None) length = geometry.total_length length_section = geometry.sections[1]['length'] - xyz_local, h, c = geometry.sample_cross_section(s=length-length_section/2, t_vec=[0.0]) + xyz_local, h, c = geometry.sample_cross_section(s=length-length_section/2, t_vec=[0.0], with_lane_offset=False) xyz_global = geometry.matrix_world @ Vector(xyz_local[0]) # FIXME there seems to be a small error in the projection assert [xyz_global.x, xyz_global.y, xyz_global.z] == approx([80.0, 40.0, 0.0], 1e-5) @@ -107,7 +107,7 @@ def test_geometry_line_3d(): geometry.add_section() geometry.update(params_input, 0.0, 0.0, None) length = geometry.total_length - xyz_local, h, c = geometry.sample_cross_section(s=length/2.0, t_vec=[0.0]) + xyz_local, h, c = geometry.sample_cross_section(s=length/2.0, t_vec=[0.0], with_lane_offset=False) xyz_global = geometry.matrix_world @ Vector(xyz_local[0]) assert [xyz_global.x, xyz_global.y, xyz_global.z] == approx([4.0, 2.0, 1.5], 1e-5) @@ -115,6 +115,6 @@ def test_geometry_line_3d(): geometry.add_section() geometry.update(params_input, 0.0, 0.0, None) length = geometry.total_length - xyz_local, h, c = geometry.sample_cross_section(s=length, t_vec=[0.0]) + xyz_local, h, c = geometry.sample_cross_section(s=length, t_vec=[0.0], with_lane_offset=False) xyz_global = geometry.matrix_world @ Vector(xyz_local[0]) assert [xyz_global.x, xyz_global.y, xyz_global.z] == approx([10.0, 5.0, 4.0], 1e-5) \ No newline at end of file diff --git a/tests/test_geometry_parampoly3.py b/tests/test_geometry_parampoly3.py index 4a46fc8..35112f1 100644 --- a/tests/test_geometry_parampoly3.py +++ b/tests/test_geometry_parampoly3.py @@ -30,7 +30,7 @@ def test_geometry_parampoly3(): geometry.update(params_input, 0.0, 0.0, solver) length_0 = geometry.total_length - xyz_local_0, h_0, c_0 = geometry.sample_cross_section(s=length_0, t_vec=[0.0]) + xyz_local_0, h_0, c_0 = geometry.sample_cross_section(s=length_0, t_vec=[0.0], with_lane_offset=False) xyz_global_0 = geometry.matrix_world @ Vector(xyz_local_0[0]) assert [xyz_global_0.x, xyz_global_0.y, xyz_global_0.z] == approx([30.0, 0.0, 0.0], 1e-5) @@ -39,11 +39,11 @@ def test_geometry_parampoly3(): geometry.update(params_input, 0.0, 0.0, solver) length_0 = geometry.sections[0]['length'] - xyz_local_0, h_0, c_0 = geometry.sample_cross_section(s=length_0, t_vec=[0.0]) + xyz_local_0, h_0, c_0 = geometry.sample_cross_section(s=length_0, t_vec=[0.0], with_lane_offset=False) xyz_global_0 = geometry.matrix_world @ Vector(xyz_local_0[0]) assert [xyz_global_0.x, xyz_global_0.y, xyz_global_0.z] == approx([30.0, 0.0, 0.0], 1e-5) length_1 = geometry.total_length - xyz_local_1, h_1, c_1 = geometry.sample_cross_section(s=length_1, t_vec=[0.0]) + xyz_local_1, h_1, c_1 = geometry.sample_cross_section(s=length_1, t_vec=[0.0], with_lane_offset=False) xyz_global_1 = geometry.matrix_world @ Vector(xyz_local_1[0]) assert [xyz_global_1.x, xyz_global_1.y, xyz_global_1.z] == approx([40.0, 0.0, 0.0], 1e-5)