Skip to content

Commit

Permalink
finally fixed from_pointcloud!
Browse files Browse the repository at this point in the history
  • Loading branch information
tetov committed Aug 6, 2024
1 parent 1a563a9 commit 5d651c3
Show file tree
Hide file tree
Showing 11 changed files with 126 additions and 119 deletions.
4 changes: 2 additions & 2 deletions bdm_voxel_builder/__main__.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
from bdm_voxel_builder.config_setup import Config
from bdm_voxel_builder.environment import Environment
from bdm_voxel_builder.helpers import (
pointcloud_from_ndarray,
pointcloud_from_grid_array,
save_ndarray,
save_pointcloud,
)
Expand Down Expand Up @@ -45,7 +45,7 @@ def simulate(frame, config: Config = None, sim_state: Environment = None):

save_ndarray(a1, note=note)

pointcloud, values = pointcloud_from_ndarray(a1, return_values=True)
pointcloud, values = pointcloud_from_grid_array(a1, return_values=True)
save_pointcloud(pointcloud, values=values, note=note)

sim_state.grids[algo.grid_to_dump].save_vdb()
Expand Down
6 changes: 2 additions & 4 deletions bdm_voxel_builder/agent_algorithms/algo_10_a_slicer_agents.py
Original file line number Diff line number Diff line change
Expand Up @@ -347,7 +347,7 @@ def check_print_chance(self, agent: Agent, state: Environment):
if print_density_below >= 0.33:
agent.build_chance = 1
elif self.overhang_limit <= 45 and print_density_below >= 0.5:
agent.build_chance = 1
agent.build_chance = 1
# elif self.overhang_limit <= 60:
# if print_density_below >= 0.5 and print_density_below_2 >= 0.5:
# self.build_chance = 1
Expand All @@ -357,9 +357,7 @@ def check_print_chance(self, agent: Agent, state: Environment):
# build chance: {agent.build_chance}.
# """)


def print_build_3x3(self, agent: Agent, state: Environment):

"""add index the print_dot list, and fill 3x3 voxel in the printed_clay grid"""
built = False
printed_clay = state.grids["printed_clay"]
Expand Down Expand Up @@ -388,7 +386,7 @@ def print_build(self, agent: Agent, state: Environment):
"""add index the print_dot list, and fill either:
- one_voxel
- voxels in cross shape
- or voxels in 3x3 square
- or voxels in 3x3 square
of the printed_clay grid"""
built = False
printed_clay = state.grids["printed_clay"]
Expand Down
21 changes: 14 additions & 7 deletions bdm_voxel_builder/grid/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,15 @@

from bdm_voxel_builder import TEMP_DIR
from bdm_voxel_builder.helpers import (
convert_array_to_pts,
convert_grid_array_to_pts,
get_savepath,
get_xform_box2grid,
pointcloud_to_grid_array,
xform_to_compas,
xform_to_vdb,
)
from bdm_voxel_builder.helpers.geometry import (
_get_xform_box2grid,
)


class Grid:
Expand Down Expand Up @@ -125,7 +127,7 @@ def get_number_of_active_voxels(self):
return len(self.array[self.get_active_voxels()])

def get_index_pts(self) -> list[list[float]]:
return convert_array_to_pts(self.array, get_data=False)
return convert_grid_array_to_pts(self.array)

def get_index_pointcloud(self):
return cg.Pointcloud(self.get_index_pts())
Expand Down Expand Up @@ -198,13 +200,18 @@ def from_pointcloud(
if not grid_size:
grid_size = max(pointcloud.aabb.dimensions) // voxel_edge_length + 1

T = get_xform_box2grid(pointcloud.aabb, grid_size=grid_size)
# TODO: Replace with multiplied version
Sc, R, Tl = _get_xform_box2grid(pointcloud.aabb, grid_size=grid_size)

pointcloud_transformed = pointcloud.copy()

pointcloud_transformed_for_grid = pointcloud.transformed(T)
pointcloud_transformed.transform(Tl)
pointcloud_transformed.transform(R)
pointcloud_transformed.transform(Sc)

array = pointcloud_to_grid_array(pointcloud_transformed_for_grid, grid_size)
array = pointcloud_to_grid_array(pointcloud_transformed, grid_size)

return cls(grid_size=grid_size, name=name, xform=T, array=array)
return cls(grid_size=grid_size, name=name, xform=Tl * R * Sc, array=array)

@classmethod
def from_ply(
Expand Down
4 changes: 2 additions & 2 deletions bdm_voxel_builder/helpers/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,10 @@
)
from .geometry import (
box_from_corner_frame,
convert_array_to_pts,
convert_grid_array_to_pts,
get_xform_box2grid,
ply_to_compas,
pointcloud_from_ndarray,
pointcloud_from_grid_array,
pointcloud_to_grid_array,
)
from .math import remap, remap_trim
Expand Down
5 changes: 2 additions & 3 deletions bdm_voxel_builder/helpers/file.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,11 @@ def get_savepath(dir: Path, suffix: str, note: str = None):
return Path(dir) / filename


def get_nth_newest_file_in_folder(folder_path: os.PathLike, n = 0):
def get_nth_newest_file_in_folder(folder_path: os.PathLike, n=0):
folder_path = Path(folder_path)

# Get a list of files in the folder
files = list(folder_path.glob('*'))
files = list(folder_path.glob("*"))

# Sort the files by change time (modification time) in descending order
files.sort(key=lambda x: x.stat().st_mtime, reverse=True)
Expand All @@ -45,6 +45,5 @@ def save_pointcloud(
json_dump(dict_, get_savepath(TEMP_DIR, ".json", note=note))



def save_ndarray(arr: npt.NDArray, note: str = None):
np.save(get_savepath(TEMP_DIR, ".npy", note=note), arr)
70 changes: 44 additions & 26 deletions bdm_voxel_builder/helpers/geometry.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,19 +19,7 @@ def box_from_corner_frame(frame: cg.Frame, xsize: float, ysize: float, zsize: fl
return cg.Box(xsize=xsize, ysize=ysize, zsize=zsize, frame=center_frame)


def _convert_array_to_pts_wo_data(arr: npt.NDArray) -> list[list[float]]:
pts = []
for i, j, k in zip(*np.nonzero(arr), strict=False):
pts.append([i, j, k])
return pts


def convert_array_to_pts(
arr: npt.NDArray, get_data=True
) -> list[list[float] | npt.NDArray]:
if not get_data:
return _convert_array_to_pts_wo_data(arr)

def convert_grid_array_to_pts(arr: npt.NDArray) -> npt.NDArray:
indicies = np.indices(arr.shape)
pt_location = np.logical_not(arr == 0)

Expand All @@ -52,13 +40,45 @@ def get_xform_box2grid(

scale_factor = float(max(grid_size) - 1) / max(box.dimensions)

S = cg.Scale.from_factors([scale_factor] * 3)
Sc = cg.Scale.from_factors([scale_factor] * 3)

v = cg.Vector(box.xmin, box.ymin, box.zmin) * scale_factor

Tr = cg.Translation.from_vector(v.inverted())
Tl = cg.Translation.from_vector(v.inverted())

return Tl * R * Sc


def _get_xform_box2grid(
box: cg.Box, grid_size: tuple[int, int, int]
) -> cg.Transformation:
"""Get the linear transformation between two bounding boxes with uniform
scaling."""
Sc = get_scaling_box2grid(box, grid_size)
R = get_rotation_box2grid(box)
Tl = get_translation_box2grid(box, grid_size)

return Sc, R, Tl



def get_translation_box2grid(
box: cg.Box, grid_size: tuple[int, int, int]
) -> cg.Translation:
"""Get the translation between bounding box and grid."""
v = cg.Vector(box.xmin, box.ymin, box.zmin)

return cg.Translation.from_vector(v.inverted())


def get_scaling_box2grid(box: cg.Box, grid_size: tuple[int, int, int]) -> cg.Scale:
"""Get the scaling needed between bounding box and grid."""
return cg.Scale.from_factors([float(max(grid_size) - 1) / max(box.dimensions)] * 3)


return Tr * R * S
def get_rotation_box2grid(box: cg.Box) -> cg.Rotation:
"""Get the rotation needed between bounding box and grid."""
return cg.Rotation.from_frame_to_frame(box.frame, cg.Frame.worldXY())


def ply_to_array(ply_path: os.PathLike, precision: str = None):
Expand All @@ -75,7 +95,7 @@ def ply_to_compas(ply_path: os.PathLike, precision: str = None):
return cg.Pointcloud(ply.parser.vertices)


def pointcloud_from_ndarray(arr: npt.NDArray, return_values=False):
def pointcloud_from_grid_array(arr: npt.NDArray, return_values=False):
pts, values = sort_pts_by_values(arr)

pointcloud = cg.Pointcloud(pts)
Expand All @@ -87,25 +107,23 @@ def pointcloud_from_ndarray(arr: npt.NDArray, return_values=False):


def pointcloud_to_grid_array(
pointcloud: cg.Pointcloud, grid_size: tuple[int, int, int], dtype=int, value=1
pointcloud: cg.Pointcloud, grid_size: tuple[int, int, int], dtype=np.int8, value=1
):
"""Convert a pointcloud to a grid."""
if not isinstance(grid_size, Sequence):
grid_size = (grid_size, grid_size, grid_size)

grid_array = np.zeros(grid_size)

pts = np.array(pointcloud).floor().astype(dtype=dtype)
indices = np.array(pointcloud.points).round().astype(np.int8)

if pts.min() < 0:
if indices.min() < 0:
raise ValueError(
"Pointcloud contains negative values, needs to be transformed to index grid."
) # noqa: E501

for i, j, k in pts:
if (i, j, k) > grid_size:
raise ValueError(
"Pointcloud contains values that are larger than grid size."
)
for i, j, k in indices:
if max((i, j, k)) >= max(grid_size):
raise IndexError(f"Index out of bounds: {i,j,k} in {grid_size}")
grid_array[i, j, k] = value
return grid_array
return grid_array.astype(dtype)
1 change: 0 additions & 1 deletion bdm_voxel_builder/helpers/math.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@

def remap_trim(
x,
output_domain,
Expand Down
4 changes: 2 additions & 2 deletions bdm_voxel_builder/visualizer/compas_viewer.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
from compas_viewer import Viewer

from bdm_voxel_builder import TEMP_DIR
from bdm_voxel_builder.helpers import convert_array_to_pts, get_savepath
from bdm_voxel_builder.helpers import convert_grid_array_to_pts, get_savepath
from bdm_voxel_builder.visualizer.base import Visualizer


Expand Down Expand Up @@ -46,7 +46,7 @@ def draw(self, iteration_count=None):
continue
parent = self.scene.get_node_by_name(grid.name)

pts = convert_array_to_pts(grid.array, get_data=False)
pts = convert_grid_array_to_pts(grid.array)

iteration = iteration_count or len(parent.children)
name = f"{grid.name}_{iteration}"
Expand Down
4 changes: 2 additions & 2 deletions bdm_voxel_builder/visualizer/matplotlib.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
from bdm_voxel_builder import TEMP_DIR
from bdm_voxel_builder.config_setup import Config
from bdm_voxel_builder.environment import Environment
from bdm_voxel_builder.helpers import convert_array_to_pts, get_savepath
from bdm_voxel_builder.helpers import convert_grid_array_to_pts, get_savepath
from bdm_voxel_builder.visualizer.base import Visualizer


Expand Down Expand Up @@ -94,7 +94,7 @@ def clear(self):

def draw(self):
for grid in self.grids:
pts = np.array(convert_array_to_pts(grid.array)).transpose()
pts = np.array(convert_grid_array_to_pts(grid.array)).transpose()
self.ax1.scatter(
pts[0, :],
pts[1, :],
Expand Down
Loading

0 comments on commit 5d651c3

Please sign in to comment.