123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693 |
- import copy
- import datetime
- import numpy
- import pytest
- from conftest import ANNOTATION_FILE_PATH, SURFACE_FILE_PATH
- from freesurfer_surface import (
- Annotation,
- LineSegment,
- PolygonalCircuit,
- Surface,
- Triangle,
- Vertex,
- setlocale,
- )
- # pylint: disable=protected-access
- def test_read_triangular():
- surface = Surface.read_triangular(SURFACE_FILE_PATH)
- assert surface.creator == b"fabianpeter"
- assert surface.creation_datetime == datetime.datetime(2019, 5, 9, 22, 37, 41)
- assert len(surface.vertices) == 155622
- assert len(surface.triangles) == 311240
- assert not surface.using_old_real_ras
- assert surface.volume_geometry_info == (
- b"valid = 1 # volume info valid\n",
- b"filename = ../mri/filled-pretess255.mgz\n",
- b"volume = 256 256 256\n",
- b"voxelsize = 1.000000000000000e+00 1.000000000000000e+00 1.000000000000000e+00\n",
- b"xras = -1.000000000000000e+00 0.000000000000000e+00 1.862645149230957e-09\n",
- b"yras = 0.000000000000000e+00 -6.655682227574289e-09 -1.000000000000000e+00\n",
- b"zras = 0.000000000000000e+00 1.000000000000000e+00 -8.300048648379743e-09\n",
- b"cras = -2.773597717285156e+00 1.566547393798828e+01 -7.504364013671875e+00\n",
- )
- assert surface.command_lines == [
- b"mris_remove_intersection ../surf/lh.orig ../surf/lh.orig"
- b" ProgramVersion: $Name: stable6 $"
- b" TimeStamp: 2019/05/09-17:42:36-GMT"
- b" BuildTimeStamp: Jan 18 2017 16:38:58"
- b" CVS: $Id: mris_remove_intersection.c,v 1.6 2011/03/02 00:04:32 nicks Exp $"
- b" User: fabianpeter"
- b" Machine: host12345"
- b" Platform: Linux"
- b" PlatformVersion: 4.15.0-46-generic"
- b" CompilerName: GCC"
- b" CompilerVersion: 40400"
- b" ",
- b"mris_make_surfaces -orig_white white.preaparc -orig_pial white.preaparc"
- b" -aseg ../mri/aseg.presurf -mgz -T1 brain.finalsurfs"
- b" fabian20190509 lh ProgramVersion: $Name: $"
- b" TimeStamp: 2019/05/09-20:27:28-GMT"
- b" BuildTimeStamp: Jan 18 2017 16:38:58"
- b" CVS: $Id: mris_make_surfaces.c,v 1.164.2.4 2016/12/13 22:26:32 zkaufman Exp $"
- b" User: fabianpeter"
- b" Machine: host12345"
- b" Platform: Linux"
- b" PlatformVersion: 4.15.0-46-generic"
- b" CompilerName: GCC"
- b" CompilerVersion: 40400"
- b" ",
- ]
- def test_read_triangular_locale():
- with setlocale("de_AT.utf8"):
- surface = Surface.read_triangular(SURFACE_FILE_PATH)
- assert surface.creation_datetime == datetime.datetime(2019, 5, 9, 22, 37, 41)
- @pytest.mark.parametrize(
- ("creation_datetime", "expected_str"),
- [
- (datetime.datetime(2019, 5, 9, 22, 37, 41), b"Thu May 9 22:37:41 2019"),
- (datetime.datetime(2019, 4, 24, 23, 29, 22), b"Wed Apr 24 23:29:22 2019"),
- ],
- )
- def test_triangular_strftime(creation_datetime, expected_str):
- # pylint: disable=protected-access
- assert expected_str == Surface._triangular_strftime(creation_datetime)
- def test_read_write_triangular_same(tmpdir):
- surface = Surface.read_triangular(SURFACE_FILE_PATH)
- output_path = tmpdir.join("surface").strpath
- surface.write_triangular(output_path, creation_datetime=surface.creation_datetime)
- with open(output_path, "rb") as output_file:
- with open(SURFACE_FILE_PATH, "rb") as expected_file:
- assert expected_file.read() == output_file.read()
- def test_read_write_datetime(tmpdir):
- surface = Surface.read_triangular(SURFACE_FILE_PATH)
- original_creation_datetime = surface.creation_datetime
- output_path = tmpdir.join("surface").strpath
- surface.write_triangular(output_path)
- assert original_creation_datetime == surface.creation_datetime
- new_surface = Surface.read_triangular(output_path)
- assert new_surface.creation_datetime > original_creation_datetime
- assert datetime.datetime.now() > new_surface.creation_datetime
- assert (
- datetime.datetime.now() - new_surface.creation_datetime
- ) < datetime.timedelta(seconds=20)
- def test_write_read_triangular_same(tmpdir):
- expected_surface = Surface()
- expected_surface.creator = b"pytest"
- expected_surface.creation_datetime = datetime.datetime.now().replace(microsecond=0)
- expected_surface.vertices = [
- Vertex(0.0, 0.0, 0.0),
- Vertex(1.0, 2.0, 3.0),
- Vertex(2.0, 4.0, 6.0),
- Vertex(3.0, 5.0, 7.0),
- ]
- expected_surface.triangles = [
- Triangle((0, 1, 2)),
- Triangle((0, 1, 3)),
- Triangle((3, 2, 1)),
- ]
- expected_surface.using_old_real_ras = False
- expected_surface.volume_geometry_info = tuple(b"?\n" for _ in range(8))
- expected_surface.command_lines = [b"?", b"!"]
- output_path = tmpdir.join("surface").strpath
- expected_surface.write_triangular(
- output_path, creation_datetime=expected_surface.creation_datetime
- )
- resulted_surface = Surface.read_triangular(output_path)
- assert numpy.array_equal(expected_surface.vertices, resulted_surface.vertices)
- expected_surface.vertices = resulted_surface.vertices = []
- assert vars(expected_surface) == vars(resulted_surface)
- def test_write_triangular_same_locale(tmpdir):
- surface = Surface()
- surface.creator = b"pytest"
- surface.volume_geometry_info = tuple(b"?" for _ in range(8))
- creation_datetime = datetime.datetime(2018, 12, 31, 21, 42)
- output_path = tmpdir.join("surface").strpath
- with setlocale("de_AT.utf8"):
- surface.write_triangular(output_path, creation_datetime=creation_datetime)
- resulted_surface = Surface.read_triangular(output_path)
- assert resulted_surface.creation_datetime == creation_datetime
- with open(output_path, "rb") as output_file:
- assert (
- output_file.read()
- .split(b" on ")[1]
- .startswith(b"Mon Dec 31 21:42:00 2018\n")
- )
- def test_load_annotation():
- surface = Surface.read_triangular(SURFACE_FILE_PATH)
- assert not surface.annotation
- surface.load_annotation_file(ANNOTATION_FILE_PATH)
- assert isinstance(surface.annotation, Annotation)
- assert len(surface.annotation.vertex_label_index) == 155622
- assert surface.annotation.vertex_label_index[0] == 5
- def test_add_vertex():
- surface = Surface()
- assert not surface.vertices
- assert surface.add_vertex(Vertex(1.0, 1.5, 2.0)) == 0
- assert len(surface.vertices) == 1
- assert surface.vertices[0].anterior == pytest.approx(1.5)
- assert surface.add_vertex(Vertex(-3.0, 0.0, 4.0)) == 1
- assert len(surface.vertices) == 2
- assert surface.vertices[1].right == pytest.approx(-3.0)
- @pytest.mark.parametrize(
- "vertices_coords",
- [
- ((0, 0, 0), (2, 4, 0), (2, 4, 3)),
- ((0, 0, 0), (2, 4, 0), (2, 4, 3), (0, 0, 3)),
- ((1, 1, 0), (3, 5, 0), (3, 5, 3), (1, 1, 3)),
- ((1, 1, 7), (3, 5, 7), (3, 5, 3), (1, 1, 3)),
- ((1, 1, 1), (3, 5, 7), (3, 5, 9), (1, 1, 3)),
- ((3, 5, 7), (1, 1, 1), (1, 1, 3)),
- ((3, 5, 7), (1, 1, 1), (1, 1, 3), (3, 5, 9)),
- ],
- )
- def test_add_rectangle(vertices_coords):
- surface = Surface()
- for vertex_coords in vertices_coords:
- surface.add_vertex(Vertex(*(float(c) for c in vertex_coords)))
- surface.add_rectangle(range(len(vertices_coords)))
- assert len(surface.vertices) == 4
- assert len(surface.triangles) == 2
- assert surface.triangles[0].vertex_indices == (0, 1, 2)
- assert surface.triangles[1].vertex_indices == (2, 3, 0)
- @pytest.mark.parametrize(
- ("vertices_coords", "expected_extra_vertex_coords"),
- [
- (((0, 0, 0), (2, 4, 0), (2, 4, 3)), (0, 0, 3)),
- (((1, 1, 0), (3, 5, 0), (3, 5, 3)), (1, 1, 3)),
- (((1, 1, 7), (3, 5, 7), (3, 5, 3)), (1, 1, 3)),
- (((1, 1, 1), (3, 5, 7), (3, 5, 9)), (1, 1, 3)),
- (((3, 5, 7), (1, 1, 1), (1, 1, 3)), (3, 5, 9)),
- ],
- )
- def test_add_rectangle_3(vertices_coords, expected_extra_vertex_coords):
- surface = Surface()
- for vertex_coords in vertices_coords:
- surface.add_vertex(Vertex(*(float(c) for c in vertex_coords)))
- surface.add_rectangle(range(3))
- assert tuple(surface.vertices[3]) == pytest.approx(expected_extra_vertex_coords)
- def test__triangle_count_by_adjacent_vertex_indices_empty():
- surface = Surface()
- assert surface._triangle_count_by_adjacent_vertex_indices() == {}
- def test__triangle_count_by_adjacent_vertex_indices_none():
- surface = Surface()
- surface.vertices.append(Vertex(1, 0, 0))
- surface.vertices.append(Vertex(2, 0, 0))
- surface.vertices.append(Vertex(3, 0, 0))
- assert surface._triangle_count_by_adjacent_vertex_indices() == {0: {}, 1: {}, 2: {}}
- def test__triangle_count_by_adjacent_vertex_indices_single():
- surface = Surface()
- surface.triangles.append(
- Triangle([surface.add_vertex(Vertex(i, 0, 0)) for i in range(3)])
- )
- assert surface._triangle_count_by_adjacent_vertex_indices() == {
- 0: {1: 1, 2: 1},
- 1: {0: 1, 2: 1},
- 2: {0: 1, 1: 1},
- }
- def test__triangle_count_by_adjacent_vertex_indices_multiple():
- surface = Surface()
- for i in range(5):
- surface.add_vertex(Vertex(i, 0, 0))
- surface.triangles.append(Triangle((0, 1, 2)))
- surface.triangles.append(Triangle((3, 1, 2)))
- assert surface._triangle_count_by_adjacent_vertex_indices() == {
- 0: {1: 1, 2: 1},
- 1: {0: 1, 2: 2, 3: 1},
- 2: {0: 1, 1: 2, 3: 1},
- 3: {1: 1, 2: 1},
- 4: {},
- }
- surface.triangles.append(Triangle((3, 4, 2)))
- assert surface._triangle_count_by_adjacent_vertex_indices() == {
- 0: {1: 1, 2: 1},
- 1: {0: 1, 2: 2, 3: 1},
- 2: {0: 1, 1: 2, 3: 2, 4: 1},
- 3: {1: 1, 2: 2, 4: 1},
- 4: {2: 1, 3: 1},
- }
- surface.triangles.append(Triangle((3, 0, 2)))
- assert surface._triangle_count_by_adjacent_vertex_indices() == {
- 0: {1: 1, 2: 2, 3: 1},
- 1: {0: 1, 2: 2, 3: 1},
- 2: {0: 2, 1: 2, 3: 3, 4: 1},
- 3: {0: 1, 1: 1, 2: 3, 4: 1},
- 4: {2: 1, 3: 1},
- }
- def test__triangle_count_by_adjacent_vertex_indices_real():
- surface = Surface.read_triangular(SURFACE_FILE_PATH)
- counts = surface._triangle_count_by_adjacent_vertex_indices()
- assert len(counts) == len(surface.vertices)
- assert all(counts.values())
- assert all(
- count == 2
- for vertex_counts in counts.values()
- for count in vertex_counts.values()
- )
- assert (
- sum(
- count
- for vertex_counts in counts.values()
- for count in vertex_counts.values()
- )
- == len(surface.triangles) * 6
- )
- def test_find_borders_none():
- surface = Surface.read_triangular(SURFACE_FILE_PATH)
- assert not list(surface.find_borders())
- def test_find_borders_single():
- surface = Surface.read_triangular(SURFACE_FILE_PATH)
- single_index = surface.add_vertex(Vertex(0, 21, 42))
- borders = list(surface.find_borders())
- assert len(borders) == 1
- assert borders[0] == PolygonalCircuit((single_index,))
- def test_find_borders_singles():
- surface = Surface.read_triangular(SURFACE_FILE_PATH)
- single_indices = [surface.add_vertex(Vertex(i, 21, 42)) for i in range(3)]
- borders = set(surface.find_borders())
- assert len(borders) == 3
- assert PolygonalCircuit((single_indices[0],)) in borders
- assert PolygonalCircuit((single_indices[1],)) in borders
- assert PolygonalCircuit((single_indices[2],)) in borders
- def test_find_borders_single_triangle_simple():
- surface = Surface()
- vertex_indices = [surface.add_vertex(Vertex(i, 21, 42)) for i in range(3)]
- surface.triangles.append(Triangle(vertex_indices))
- borders = set(surface.find_borders())
- assert len(borders) == 1
- assert PolygonalCircuit(vertex_indices) in borders
- def test_find_borders_single_triangle_real():
- surface = Surface.read_triangular(SURFACE_FILE_PATH)
- vertex_indices = [surface.add_vertex(Vertex(i, 21, 42)) for i in range(3)]
- surface.triangles.append(Triangle(vertex_indices))
- borders = set(surface.find_borders())
- assert len(borders) == 1
- assert PolygonalCircuit(vertex_indices) in borders
- def test_find_borders_remove_triangle():
- surface = Surface.read_triangular(SURFACE_FILE_PATH)
- triangle = surface.triangles.pop()
- borders = set(surface.find_borders())
- assert len(borders) == 1
- assert triangle in borders
- def test_find_borders_remove_non_adjacent_triangles():
- surface = Surface.read_triangular(SURFACE_FILE_PATH)
- triangles = [surface.triangles.pop(), surface.triangles.pop()]
- borders = set(surface.find_borders())
- assert len(borders) == 2
- assert triangles[0] in borders
- assert triangles[1] in borders
- def test_find_borders_remove_adjacent_triangles():
- surface = Surface.read_triangular(SURFACE_FILE_PATH)
- triangles = [surface.triangles.pop(), surface.triangles.pop()]
- triangles.append(surface.triangles.pop(270682))
- assert triangles[1] == Triangle((136141, 136142, 137076))
- assert triangles[2] == Triangle((136141, 136142, 135263))
- borders = set(surface.find_borders())
- assert len(borders) == 2
- assert triangles[0] in borders
- assert PolygonalCircuit((137076, 136141, 135263, 136142)) in borders
- surface.triangles.pop(270682)
- borders = set(surface.find_borders())
- assert len(borders) == 2
- assert triangles[0] in borders
- assert PolygonalCircuit((137076, 136141, 135263, 135264, 136142)) in borders
- surface.triangles.pop(274320)
- borders = set(surface.find_borders())
- assert len(borders) == 2
- assert PolygonalCircuit((136143, 138007, 138008, 137078)) in borders
- assert PolygonalCircuit((137076, 136141, 135263, 135264, 136142)) in borders
- @pytest.mark.parametrize(
- ("label_name", "expected_border_lens"),
- [
- ("precentral", [416]),
- ("postcentral", [395]),
- ("medialorbitofrontal", [6, 246]),
- # ...--2343 2347
- # \ / \
- # 2345 2348
- # / \ /
- # ...--2344 2346
- ("posteriorcingulate", [4, 190]),
- ("unknown", [3, 390]),
- ],
- )
- def test_find_borders_real(label_name, expected_border_lens):
- surface = Surface.read_triangular(SURFACE_FILE_PATH)
- surface.load_annotation_file(ANNOTATION_FILE_PATH)
- (label,) = filter(
- lambda l: l.name == label_name, surface.annotation.labels.values()
- )
- surface.triangles = list(
- filter(
- lambda t: all(
- surface.annotation.vertex_label_index[vertex_idx] == label.index
- for vertex_idx in t.vertex_indices
- ),
- surface.triangles,
- )
- )
- surface.remove_unused_vertices()
- borders = list(surface.find_borders())
- border_lens = [len(b.vertex_indices) for b in borders]
- # self-crossing borders may or may not be split into
- # separate polygonal circuits
- assert sorted(border_lens) == expected_border_lens or sum(border_lens) == sum(
- expected_border_lens
- )
- def test__get_vertex_label_index():
- surface = Surface.read_triangular(SURFACE_FILE_PATH)
- surface.load_annotation_file(ANNOTATION_FILE_PATH)
- # pylint: disable=protected-access
- assert surface._get_vertex_label_index(64290) == 22
- assert surface._get_vertex_label_index(72160) == 22
- assert surface._get_vertex_label_index(84028) == 24
- assert surface._get_vertex_label_index(97356) == 24
- assert surface._get_vertex_label_index(123173) == 27
- assert surface._get_vertex_label_index(140727) == 27
- assert surface._get_vertex_label_index(93859) == 28
- assert surface._get_vertex_label_index(78572) == 0
- assert surface._get_vertex_label_index(120377) == 0
- vertex_index = surface.add_vertex(Vertex(0.0, 21.0, 42.0))
- assert surface._get_vertex_label_index(vertex_index) is None
- del surface.annotation.vertex_label_index[140727]
- assert surface._get_vertex_label_index(140727) is None
- def test__find_label_border_segments():
- surface = Surface.read_triangular(SURFACE_FILE_PATH)
- surface.load_annotation_file(ANNOTATION_FILE_PATH)
- (precentral_label,) = filter(
- lambda l: l.name == "precentral", surface.annotation.labels.values()
- )
- # pylint: disable=protected-access
- border_segments = set(surface._find_label_border_segments(precentral_label))
- assert len(border_segments) == 417
- assert LineSegment((33450, 32065)) in border_segments
- assert LineSegment((33454, 33450)) in border_segments
- for border_vertex_index in [33450, 33454, 32065]:
- assert (
- surface.annotation.vertex_label_index[border_vertex_index]
- == precentral_label.index
- )
- for other_vertex_index in [32064, 33449, 33455, 33449, 33455]:
- assert (
- LineSegment((other_vertex_index, border_vertex_index))
- not in border_segments
- )
- assert (
- LineSegment((border_vertex_index, other_vertex_index))
- not in border_segments
- )
- def test__find_label_border_segments_incomplete_annotation():
- surface = Surface.read_triangular(SURFACE_FILE_PATH)
- surface.load_annotation_file(ANNOTATION_FILE_PATH)
- (precentral_label,) = filter(
- lambda l: l.name == "precentral", surface.annotation.labels.values()
- )
- # pylint: disable=protected-access
- assert surface._find_label_border_segments(precentral_label)
- surface.triangles.append(
- Triangle(
- [
- surface.add_vertex(Vertex(0.0, 21.0 * factor, 42.0 * factor))
- for factor in range(3)
- ]
- )
- )
- border_segments = set(surface._find_label_border_segments(precentral_label))
- assert len(border_segments) == 417
- def test_find_label_border_polygonal_chains():
- surface = Surface.read_triangular(SURFACE_FILE_PATH)
- surface.load_annotation_file(ANNOTATION_FILE_PATH)
- (precentral_label,) = filter(
- lambda l: l.name == "precentral", surface.annotation.labels.values()
- )
- (border_chain,) = surface.find_label_border_polygonal_chains(precentral_label)
- vertex_indices = list(border_chain.vertex_indices)
- assert len(vertex_indices) == 418
- min_index = vertex_indices.index(min(vertex_indices))
- vertex_indices_normalized = vertex_indices[min_index:] + vertex_indices[:min_index]
- if vertex_indices_normalized[-1] < vertex_indices_normalized[1]:
- vertex_indices_normalized.reverse()
- assert vertex_indices_normalized[346:353] == [
- 63264,
- 63255,
- 62118,
- 62107,
- 62118,
- 62119,
- 61044,
- ]
- assert vertex_indices_normalized[:4] == [32065, 33450, 33454, 34870]
- assert vertex_indices_normalized[-4:] == [33464, 32080, 32073, 32072]
- def test__unused_vertices():
- surface = Surface()
- assert not surface._unused_vertices()
- for i in range(4):
- surface.add_vertex(Vertex(i, i, i))
- assert surface._unused_vertices() == {0, 1, 2, 3}
- surface.triangles.append(Triangle((0, 2, 3)))
- assert surface._unused_vertices() == {1}
- surface.triangles.append(Triangle((0, 3, 1)))
- assert not surface._unused_vertices()
- del surface.triangles[0]
- assert surface._unused_vertices() == {2}
- def test__unused_vertices_real():
- surface = Surface.read_triangular(SURFACE_FILE_PATH)
- assert not surface._unused_vertices()
- surface.triangles = list(
- filter(lambda t: 42 not in t.vertex_indices, surface.triangles)
- )
- assert surface._unused_vertices() == {42}
- def test_remove_unused_vertices_all():
- surface = Surface()
- for i in range(5):
- surface.add_vertex(Vertex(i, i, i))
- assert len(surface.vertices) == 5
- surface.remove_unused_vertices()
- assert not surface.vertices
- surface.remove_unused_vertices()
- assert not surface.vertices
- def test_remove_unused_vertices_almost_all():
- surface = Surface()
- for i in range(5):
- surface.add_vertex(Vertex(i, i, i))
- assert len(surface.vertices) == 5
- surface.triangles.append(Triangle((0, 2, 3)))
- surface.remove_unused_vertices()
- assert len(surface.vertices) == 3
- assert surface.vertices[0] == pytest.approx(Vertex(0, 0, 0))
- assert surface.vertices[1] == pytest.approx(Vertex(2, 2, 2))
- assert surface.vertices[2] == pytest.approx(Vertex(3, 3, 3))
- assert len(surface.triangles) == 1
- assert surface.triangles[0] == Triangle((0, 1, 2))
- del surface.triangles[0]
- surface.remove_unused_vertices()
- assert not surface.vertices
- def test_remove_unused_vertices_some():
- surface = Surface()
- for i in range(9):
- surface.add_vertex(Vertex(i, i, i))
- surface.triangles.append(Triangle((0, 2, 3)))
- surface.triangles.append(Triangle((3, 4, 5)))
- surface.triangles.append(Triangle((3, 2, 5)))
- surface.triangles.append(Triangle((3, 2, 8)))
- surface.remove_unused_vertices()
- assert len(surface.vertices) == 6
- assert surface.vertices[0] == pytest.approx(Vertex(0, 0, 0))
- assert surface.vertices[1] == pytest.approx(Vertex(2, 2, 2))
- assert surface.vertices[2] == pytest.approx(Vertex(3, 3, 3))
- assert surface.vertices[3] == pytest.approx(Vertex(4, 4, 4))
- assert surface.vertices[4] == pytest.approx(Vertex(5, 5, 5))
- assert surface.vertices[5] == pytest.approx(Vertex(8, 8, 8))
- assert len(surface.triangles) == 4
- assert surface.triangles[0] == Triangle((0, 1, 2))
- assert surface.triangles[1] == Triangle((2, 3, 4))
- assert surface.triangles[2] == Triangle((2, 1, 4))
- assert surface.triangles[3] == Triangle((2, 1, 5))
- surface.remove_unused_vertices()
- assert len(surface.triangles) == 4
- def test_remove_unused_vertices_none():
- surface = Surface.read_triangular(SURFACE_FILE_PATH)
- assert len(surface.vertices) == 155622
- assert len(surface.triangles) == 311240
- surface.remove_unused_vertices()
- assert len(surface.vertices) == 155622
- assert len(surface.triangles) == 311240
- def test_remove_unused_vertices_single():
- surface = Surface.read_triangular(SURFACE_FILE_PATH)
- assert len(surface.vertices) == 155622
- assert len(surface.triangles) == 311240
- assert surface.triangles[-1] == Triangle((136143, 138007, 137078))
- surface.triangles = list(
- filter(lambda t: 42 not in t.vertex_indices, surface.triangles)
- )
- assert surface._unused_vertices() == {42}
- surface.remove_unused_vertices()
- assert len(surface.vertices) == 155622 - 1
- assert len(surface.triangles) == 311240 - 7
- assert surface.triangles[-1] == Triangle((136142, 138006, 137077))
- assert all(
- vertex_index < len(surface.vertices)
- for triangle in surface.triangles
- for vertex_index in triangle.vertex_indices
- )
- def test_select_vertices():
- surface = Surface()
- for i in range(4):
- surface.add_vertex(Vertex(i, i, i))
- assert numpy.allclose(
- surface.select_vertices([2, 1]), [surface.vertices[2], surface.vertices[1]]
- )
- assert numpy.allclose(
- surface.select_vertices([3, 2]), [surface.vertices[3], surface.vertices[2]]
- )
- assert numpy.allclose(surface.select_vertices((3, 2)), [[3, 3, 3], [2, 2, 2]])
- assert numpy.allclose(
- surface.select_vertices(filter(lambda i: i % 2 == 1, range(4))),
- [[1, 1, 1], [3, 3, 3]],
- )
- def test_unite_2():
- surface_a = Surface()
- for i in range(0, 4):
- surface_a.add_vertex(Vertex(i, i, i))
- surface_a.triangles.append(Triangle((0, 1, 2)))
- surface_a.triangles.append(Triangle((1, 2, 3)))
- surface_b = Surface()
- for i in range(10, 14):
- surface_b.add_vertex(Vertex(i, i, i))
- surface_b.triangles.append(Triangle((0, 1, 3)))
- surface_a_copy = copy.deepcopy(surface_a)
- surface_b_copy = copy.deepcopy(surface_b)
- union = Surface.unite([surface_a, surface_b])
- assert numpy.allclose(surface_a.vertices, surface_a_copy.vertices)
- assert numpy.allclose(surface_b.vertices, surface_b_copy.vertices)
- assert numpy.allclose(union.vertices[:4], surface_a.vertices)
- assert numpy.allclose(union.vertices[4:], surface_b.vertices)
- assert surface_a.triangles == surface_a_copy.triangles
- assert surface_b.triangles == surface_b_copy.triangles
- assert union.triangles[:2] == surface_a.triangles
- assert union.triangles[2:] == [Triangle((4, 5, 7))]
- def test_unite_3():
- surface_a = Surface()
- for i in range(0, 4):
- surface_a.add_vertex(Vertex(i, i, i))
- surface_a.triangles.append(Triangle((0, 1, 2)))
- surface_a.triangles.append(Triangle((1, 2, 3)))
- surface_b = Surface()
- for i in range(10, 14):
- surface_b.add_vertex(Vertex(i, i, i))
- surface_b.triangles.append(Triangle((0, 1, 3)))
- surface_c = Surface()
- for i in range(20, 23):
- surface_c.add_vertex(Vertex(i, i, i))
- surface_c.triangles.append(Triangle((0, 1, 2)))
- surface_c.triangles.append(Triangle((0, 1, 2)))
- union = Surface.unite(filter(None, [surface_a, surface_b, surface_c]))
- assert numpy.allclose(union.vertices[:4], surface_a.vertices)
- assert numpy.allclose(union.vertices[4:8], surface_b.vertices)
- assert numpy.allclose(union.vertices[8:], surface_c.vertices)
- assert union.triangles[:2] == surface_a.triangles
- assert union.triangles[2:3] == [Triangle((4, 5, 7))]
- assert union.triangles[3:] == [Triangle((8, 9, 10)), Triangle((8, 9, 10))]
- def test_unite_real():
- surface_a = Surface.read_triangular(SURFACE_FILE_PATH)
- surface_b = Surface()
- for i in range(5):
- surface_b.add_vertex(Vertex(i, i, i))
- surface_b.triangles.append(Triangle((0, 1, 3)))
- surface_b.triangles.append(Triangle((1, 3, 4)))
- union = Surface.unite((surface_a, surface_b))
- assert numpy.allclose(union.vertices[:-5], surface_a.vertices)
- assert numpy.allclose(union.vertices[-5:], surface_b.vertices)
- assert union.triangles[:-2] == surface_a.triangles
- assert union.triangles[-2:] == [
- Triangle((155622, 155623, 155625)),
- Triangle((155623, 155625, 155626)),
- ]
- assert union.creator == surface_a.creator
- assert union.creation_datetime == surface_a.creation_datetime
- assert union.using_old_real_ras == surface_a.using_old_real_ras
- assert union.volume_geometry_info == surface_a.volume_geometry_info
- assert union.command_lines == surface_a.command_lines
- assert union.annotation == surface_a.annotation
|