Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
  • Loading branch information
jrb20008 committed Mar 25, 2025
2 parents 6b2a13d + 60d436b commit 46fe6aa
Show file tree
Hide file tree
Showing 27 changed files with 869 additions and 129 deletions.
6 changes: 3 additions & 3 deletions AUVSim/__init__.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
from .auv import (
AUV,
AUVPath,
AUVPathGen
AUV as AUV,
AUVPath as AUVPath,
AUVPathGen as AUVPathGen,
)
32 changes: 19 additions & 13 deletions AUVSim/auv.py
Original file line number Diff line number Diff line change
@@ -1,23 +1,31 @@
from Raytrace.TriangleMesh import TriangleMesh, Ray
from Raytrace import TriangleMesh
from Raytrace.SideScan import SideScan
import numpy as np
from typing import Any
from CustomTypes import Ray, Vector3, Vector3Array

class AUV:
ideal_distance:float # Currently unused
start_pos:np.ndarray
start_facing:np.ndarray
def __init__(self, position:np.ndarray, facing:np.ndarray):
start_pos:Vector3
start_facing:Vector3
def __init__(self,
position:Vector3,
facing:Vector3,
ideal_distance:float = -1,
):
self.start_pos = position
self.start_facing = facing
self.ideal_distance = ideal_distance
class AUVPath:
positions:np.ndarray[float, Any]
facings:np.ndarray[float, Any]
positions:Vector3Array
facings:Vector3Array

def __init__(self, positions:np.ndarray, facings:np.ndarray):
def __init__(self, positions:Vector3Array, facings:Vector3Array):
self.positions = positions
self.facings = facings
def as_rays(self):
return [Ray(i, j) for i, j in zip(self.facings, self.positions)]
@property
def rays(self) -> list[Ray]:
return list(map(Ray, self.facings, self.positions))

class AUVPathGen:
mesh:TriangleMesh
Expand Down Expand Up @@ -50,10 +58,8 @@ def get_path(self, travel_distance:float, samples:int) -> AUVPath:
# point in the direction that the hull is sloping
rise = (ray_dist - prev_dist) * side_ray.direction
if not (np.isfinite(ray_dist) and np.isfinite(prev_dist)):
rise = np.zeros(3)
rise = Vector3(0, 0, 0)
new_facing = normalize(facings[-1] + rise)
facings.append(new_facing)

np_positions = np.array(positions)
np_facings = np.array(facings)
return AUVPath(np_positions, np_facings)
return AUVPath(Vector3Array(positions), Vector3Array(facings))
1 change: 1 addition & 0 deletions CustomTypes/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
__pycache__/
11 changes: 11 additions & 0 deletions CustomTypes/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
from .custom_np import CustomNP as CustomNP
from .custom_types import (
Vector3 as Vector3,
Triangle as Triangle,
Ray as Ray,
)
from .custom_arrays import (
FloatArray as FloatArray,
TriangleArray as TriangleArray,
Vector3Array as Vector3Array,
)
54 changes: 54 additions & 0 deletions CustomTypes/custom_arrays.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
from typing import Any, Iterable, Literal, overload
import numpy as np

from . import CustomNP, Triangle, Vector3

class FloatArray(CustomNP):
def __new__(cls,
content: Iterable[float]|np.ndarray|None = None,
):
if isinstance(content, np.ndarray):
if content.ndim != 1: raise ValueError(content.shape) # must be 1d
return content.view(cls)
if content is None:
return np.ndarray((0,), float).view(cls)
return np.array(content).view(cls)
def __getitem__(self, index):
if isinstance(index, slice): return super().__getitem__(index).view(type(self))
return super().__getitem__(index)

class Vector3Array(CustomNP):
def __new__(cls,
content: Iterable[Vector3]|np.ndarray|None = None,
):
if isinstance(content, np.ndarray):
if content.ndim == 1: content = content.reshape((1,) + content.shape)
if content.ndim != 2: raise ValueError(content.shape) # must be 1d or 2d
if content.shape[1] != 3: raise ValueError(content.shape) # must be shape (n, 3)
return content.view(cls)
if content is None:
return np.ndarray((0, 3), float).view(cls)
return np.array(content).view(cls)
def __getitem__(self, index):
if isinstance(index, slice): return super().__getitem__(index).view(type(self))
return super().__getitem__(index)

class TriangleArray(CustomNP):
def __new__(cls,
content: Iterable[Triangle]|np.ndarray|None = None,
):
if isinstance(content, np.ndarray):
if content.ndim == 2: content = content.reshape((1,) + content.shape)
if content.ndim != 3: raise ValueError(content.shape) # must be 2d or 3d
if content.shape[1] != 3 or content.shape[2] != 3: raise ValueError(content.shape) # must be shape (n, 3, 3)
return content.view(cls)
if content is None:
return np.ndarray((0, 3, 3), float).view(cls)
return np.array(content).view(cls)
def __getitem__(self, index):
if isinstance(index, slice): return super().__getitem__(index).view(type(self))
return super().__getitem__(index)
@property
def verticies(self) -> tuple[Vector3Array, Vector3Array, Vector3Array]:
v0, v1, v2 = self.swapaxes(0, 1)
return (v0.view(Vector3Array), v1.view(Vector3Array), v2.view(Vector3Array))
53 changes: 53 additions & 0 deletions CustomTypes/custom_arrays.pyi
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
import numpy as np
from typing import Any, Iterable, Literal, Self, Type, TypeVar, overload

from . import CustomNP, Triangle, Vector3

class FloatArray(CustomNP[tuple[int, Literal[3]], np.dtype[np.float_]]):
@overload
def __new__(cls) -> FloatArray:...
@overload
def __new__(cls, content: Iterable[float]) -> FloatArray:...
@overload
def __new__(cls, content: np.ndarray[tuple[int], np.dtype[np.float_]]) -> FloatArray:...

@overload # type: ignore
def __getitem__(self, index:int) -> float: ...
@overload
def __getitem__(self, index:slice) -> Self: ...

class Vector3Array(CustomNP[tuple[int, Literal[3]], np.dtype[np.float_]]):
@overload
def __new__(cls) -> Vector3Array:...
@overload
def __new__(cls, content: Iterable[Vector3]) -> Vector3Array:...
@overload
def __new__(cls, content: np.ndarray[tuple[int, Literal[3]], np.dtype[np.float_]]) -> Vector3Array:...

@overload # type: ignore
def __getitem__(self, index:int) -> Vector3: ...
@overload
def __getitem__(self, index:tuple[int, Literal[0, 1, 2]]) -> float: ...
@overload
def __getitem__(self, index:slice) -> Self: ...

class TriangleArray(CustomNP[tuple[int, Literal[3], Literal[3]], np.dtype[np.float_]]):
@overload
def __new__(cls) -> TriangleArray:...
@overload
def __new__(cls, content: Iterable[Triangle]) -> TriangleArray:...
@overload
def __new__(cls, content: np.ndarray[tuple[int, Literal[3], Literal[3]], np.dtype[np.float_]]) -> TriangleArray:...

@overload # type: ignore
def __getitem__(self, index:int) -> Triangle: ...
@overload
def __getitem__(self, index:tuple[int, Literal[0, 1, 2]]) -> Vector3: ...
@overload
def __getitem__(self, index:tuple[int, Literal[0, 1, 2], Literal[0, 1, 2]]) -> float: ...
@overload
def __getitem__(self, index:slice) -> Self: ...

@property
def verticies(self) -> tuple[Vector3Array, Vector3Array, Vector3Array]: ...

21 changes: 21 additions & 0 deletions CustomTypes/custom_np.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@

from typing import Generic, TypeVar, Self
import numpy as np


_S = TypeVar('_S', bound=tuple)
_T = TypeVar('_T', bound=np.dtype)
class CustomNP(np.ndarray[_S, _T]):
def __add__(self, other):
return super().__add__(other).view(type(self))
def __sub__(self, other):
return super().__sub__(other).view(type(self))
def __mul__(self, other):
return super().__mul__(other).view(type(self))
def __truediv__(self, other):
return super().__truediv__(other).view(type(self))
def __rtruediv__(self, other):
return super().__rtruediv__(other).view(type(self))
@property
def nd(self):
return self.view(np.ndarray)
15 changes: 15 additions & 0 deletions CustomTypes/custom_np.pyi
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
from typing import TypeVar, Self
import numpy as np


_S = TypeVar('_S', bound=tuple)
_T = TypeVar('_T', bound=np.dtype)
class CustomNP(np.ndarray[_S, _T]):
def __add__(self, other:Self) -> Self: ... # type: ignore
def __sub__(self, other:Self) -> Self: ... # type: ignore
def __mul__(self, other:Self|float) -> Self: ... # type: ignore
def __truediv__(self, other:Self|float) -> Self: ... # type: ignore
def __rtruediv__(self, other:float) -> Self: ... # type: ignore

@property
def nd(self) -> np.ndarray: ...
42 changes: 42 additions & 0 deletions CustomTypes/custom_types.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
from typing import Any, Iterable, Literal, Self, overload
import numpy as np
from . import CustomNP

class Vector3(CustomNP):
def __new__(cls,
x: float | tuple[float, float, float] | Self, y = 0, z = 0):
if isinstance(x, tuple):
x, y, z = x
elif isinstance(x, Vector3):
x, y, z = x
assert isinstance(x, (float, int, np.floating))
return np.array([x, y, z]).view(cls)
def __str__(self):
return f"({self[0]}, {self[1]}, {self[2]})"
def __repr__(self):
return f"Vector3({self[0]}, {self[1]}, {self[2]})"

class Triangle(CustomNP):
def __new__(cls,
v0: Vector3 | tuple[Vector3, Vector3, Vector3],
v1: Vector3 = Vector3(0, 0, 0),
v2: Vector3 = Vector3(0, 0, 0),
) -> 'Triangle':
if isinstance(v0, tuple):
v0, v1, v2 = v0
return np.array([v0, v1, v2]).view(cls)

def __str__(self) -> str:
return f"({self[0]}, {self[1]}, {self[2]})"
def __repr__(self) -> str:
return f"Vector3({self[0]}, {self[1]}, {self[2]})"

class Ray:
direction:Vector3
origin:Vector3
def __init__(self,
direction:Vector3,
origin:Vector3,
) -> None:
self.direction = direction
self.origin = origin
40 changes: 40 additions & 0 deletions CustomTypes/custom_types.pyi
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
from typing import Any, Iterable, Iterator, Literal, TypeAlias, TypeVar, overload
import numpy as np
from . import CustomNP

class Vector3(CustomNP[tuple[Literal[3]], np.dtype[np.float_]]):
@overload
def __new__(cls, x: float, y: float, z: float) -> Vector3: ...
@overload
def __new__(cls, x: tuple[float, float, float]) -> Vector3: ...
@overload
def __new__(cls, x: Vector3) -> Vector3: ...

def __getitem__(self, index:Literal[0, 1, 2]) -> float: ... # type: ignore

class Triangle(CustomNP[tuple[Literal[3], Literal[3]], np.dtype[np.float_]], Iterable[Vector3]):
@overload
def __new__(cls, v0: Vector3, v1: Vector3, v2: Vector3) -> Triangle: ...
@overload
def __new__(cls, v0: tuple[Vector3, Vector3, Vector3]) -> Triangle: ...
@overload
def __new__(cls, v0: Triangle) -> Triangle: ...

@overload # type: ignore
def __getitem__(self, index:Literal[0, 1, 2]) -> Vector3: ...
@overload
def __getitem__(self, index:tuple[Literal[0, 1, 2], Literal[0, 1, 2]]) -> float: ...

def __add__(self, other:Triangle) -> Triangle: ... # type: ignore
def __sub__(self, other:Triangle) -> Triangle: ... # type: ignore

def __iter__(self) -> Iterator[Vector3]: ...
class Ray:
direction:Vector3
origin:Vector3
def __init__(self,
direction:Vector3,
origin:Vector3,
) -> None:
self.direction = direction
self.origin = origin
1 change: 1 addition & 0 deletions Generate/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
__pycache__/
13 changes: 13 additions & 0 deletions Generate/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
from .auv import(
place_auvs_over_points as place_auvs_over_points,
generate_paths as generate_paths,
scan_paths as scan_paths,
)
from .hull import (
generate_hulls as generate_hulls,
generate_points_on_hull as generate_points_on_hull,
generate_vertical_bounds as generate_vertical_bounds,
load_anomalies as load_anomalies,
pick_anomalies as pick_anomalies,
place_anomalies_at_points as place_anomalies_at_points,
)
Loading

0 comments on commit 46fe6aa

Please sign in to comment.