Skip to content

Commit

Permalink
build and tests
Browse files Browse the repository at this point in the history
  • Loading branch information
glyg committed Dec 28, 2023
1 parent 4584914 commit a8d12c4
Show file tree
Hide file tree
Showing 8 changed files with 261 additions and 163 deletions.
11 changes: 7 additions & 4 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
project(tyssue)

cmake_minimum_required(VERSION 3.5.0)
set(CMAKE_VERBOSE_MAKEFILE ON)

cmake_minimum_required(VERSION 3.5...3.26)

project(tyssue)
find_package(Python COMPONENTS Interpreter Development.Module REQUIRED)



Expand All @@ -28,6 +27,7 @@ if (NOT CGAL_FOUND)
endif()



# include helper file
include( ${CGAL_USE_FILE})

Expand All @@ -40,6 +40,9 @@ include_directories (${COLLISION_SRCE} ${GENERATION_SRCE})
# Assumes pybind11 is a subdirectory at the project root
# Make sure you git cloned tyssue recursively
add_subdirectory(pybind11)



pybind11_add_module(c_collisions ${SOURCES} "${COLLISION_SRCE}/c_collisions.cpp" )
pybind11_add_module(mesh_generation ${SOURCES} "${GENERATION_SRCE}/mesh_generation.cpp" )
# pybind11_add_module(tyssue.collisions.cpp.c_collisions src/tyssue/collisions/cpp/c_collisions)
Expand Down
2 changes: 1 addition & 1 deletion doc/notebooks
8 changes: 8 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -65,11 +65,19 @@ cmake.minimum-version = "3.26.1"
ninja.minimum-version = "1.11"
wheel.expand-macos-universal-tags = true
sdist.include = [
"CMakeLists.txt",
"pybind11/tools",
"pybind11/include",
"pybind11/CMakeLists.txt",
]
build-dir = "build"
cmake.args = [
"-DCMAKE_LIBRARY_OUTPUT_DIRECTORY=${SOURCES}",
"-DCMAKE_BUILD_TYPE=Debug",
]

cmake.verbose = true


[tool.setuptools]
include_package_data = true
Expand Down
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -163,7 +163,7 @@ def build_extension(self, ext):
]


write_version_py()
# write_version_py()
setup(
name=DISTNAME,
description=DESCRIPTION,
Expand Down
231 changes: 158 additions & 73 deletions src/tyssue/collisions/solvers.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,21 +48,27 @@ def solve_self_intersect_face(eptm):
face_self_intersect = eptm.edge_df.groupby("face").apply(_do_face_self_intersect)

for f in face_self_intersect[face_self_intersect].index:
sorted_edge = np.array(_ordered_edges(
eptm.edge_df[eptm.edge_df["face"] == f][["srce", "trgt", "face"]])).flatten()[3::4]
sorted_edge = np.array(
_ordered_edges(
eptm.edge_df[eptm.edge_df["face"] == f][["srce", "trgt", "face"]]
)
).flatten()[3::4]
angle_list = np.arctan2(
eptm.edge_df.loc[sorted_edge]["sy"].to_numpy() - eptm.edge_df.loc[sorted_edge]["fy"].to_numpy(),
eptm.edge_df.loc[sorted_edge]["sx"].to_numpy() - eptm.edge_df.loc[sorted_edge][
"fx"].to_numpy())
eptm.edge_df.loc[sorted_edge]["sy"].to_numpy()
- eptm.edge_df.loc[sorted_edge]["fy"].to_numpy(),
eptm.edge_df.loc[sorted_edge]["sx"].to_numpy()
- eptm.edge_df.loc[sorted_edge]["fx"].to_numpy(),
)

angle_e = pd.DataFrame(angle_list, index=sorted_edge, columns=['angle'])
angle_e = pd.DataFrame(angle_list, index=sorted_edge, columns=["angle"])

if np.argmin(angle_e["angle"]) != 0:
pos_s = np.argmin(angle_e["angle"])
angle_e = pd.concat([angle_e.iloc[pos_s:], angle_e.iloc[:pos_s]])
# Fix if the swap is between the 2 lowest angle value
if ((angle_e.iloc[-1]["angle"] > angle_e.iloc[0]["angle"]) and (
angle_e.iloc[-1]["angle"] < angle_e.iloc[-2]["angle"])):
if (angle_e.iloc[-1]["angle"] > angle_e.iloc[0]["angle"]) and (
angle_e.iloc[-1]["angle"] < angle_e.iloc[-2]["angle"]
):
pos_s = angle_e.shape[0] - 1
angle_e = pd.concat([angle_e.iloc[pos_s:], angle_e.iloc[:pos_s]])

Expand All @@ -73,15 +79,15 @@ def solve_self_intersect_face(eptm):
v1 = eptm.edge_df.loc[angle_e.index[pos_s]]["srce"]
v2 = eptm.edge_df.loc[angle_e.index[pos_s - 1]]["srce"]

v1_x, v1_y = eptm.vert_df.loc[v1][['x', 'y']]
v2_x, v2_y = eptm.vert_df.loc[v2][['x', 'y']]
eptm.vert_df.loc[v1, ['x', 'y']] = v2_x, v2_y
eptm.vert_df.loc[v2, ['x', 'y']] = v1_x, v1_y
v1_x, v1_y = eptm.vert_df.loc[v1][["x", "y"]]
v2_x, v2_y = eptm.vert_df.loc[v2][["x", "y"]]
eptm.vert_df.loc[v1, ["x", "y"]] = v2_x, v2_y
eptm.vert_df.loc[v2, ["x", "y"]] = v1_x, v1_y
mask = np.repeat(False, eptm.Nf)
mask[f] = True
if self_intersections(eptm.extract(mask)).size > 0:
eptm.vert_df.loc[v1, ['x', 'y']] = v1_x, v1_y
eptm.vert_df.loc[v2, ['x', 'y']] = v2_x, v2_y
eptm.vert_df.loc[v1, ["x", "y"]] = v1_x, v1_y
eptm.vert_df.loc[v2, ["x", "y"]] = v2_x, v2_y


def _check_convexity(polygon):
Expand All @@ -96,31 +102,33 @@ def _check_convexity(polygon):
res = u[0] * v_y - u[1] * v_x + v_x * p[1] - v_y * p[0]
else:
newres = u[0] * v_y - u[1] * v_x + v_x * p[1] - v_y * p[0]
if ((newres > 0 and res < 0) or (newres < 0 and res > 0)):
if (newres > 0 and res < 0) or (newres < 0 and res > 0):
return False

return True


def _do_face_self_intersect(edge):
sorted_edge = np.array(_ordered_edges(
edge[['srce', 'trgt', 'face']])).flatten()[3::4]
sorted_edge = np.array(_ordered_edges(edge[["srce", "trgt", "face"]])).flatten()[
3::4
]
angle_list = np.arctan2(
edge.loc[sorted_edge]['sy'].to_numpy() - edge.loc[sorted_edge]['fy'].to_numpy(),
edge.loc[sorted_edge]['sx'].to_numpy() - edge.loc[sorted_edge][
'fx'].to_numpy())
edge.loc[sorted_edge]["sy"].to_numpy() - edge.loc[sorted_edge]["fy"].to_numpy(),
edge.loc[sorted_edge]["sx"].to_numpy() - edge.loc[sorted_edge]["fx"].to_numpy(),
)

angle_e = pd.DataFrame(angle_list, index=sorted_edge, columns=['angle'])
angle_e = pd.DataFrame(angle_list, index=sorted_edge, columns=["angle"])

if np.argmin(angle_e['angle']) != 0:
pos_s = np.argmin(angle_e['angle'])
if np.argmin(angle_e["angle"]) != 0:
pos_s = np.argmin(angle_e["angle"])
angle_e = pd.concat([angle_e.iloc[pos_s:], angle_e.iloc[:pos_s]])

angle_e = pd.concat([angle_e, angle_e.iloc[[0]]])
angle_e.iloc[-1]['angle'] += 2 * np.pi
angle_e.iloc[-1]["angle"] += 2 * np.pi

if (not pd.Series(angle_e['angle']).is_monotonic_increasing) and (
_check_convexity(edge.loc[sorted_edge][['sx', 'sy']].to_numpy())):
if (not pd.Series(angle_e["angle"]).is_monotonic_increasing) and (
_check_convexity(edge.loc[sorted_edge][["sx", "sy"]].to_numpy())
):
return True
return False

Expand Down Expand Up @@ -222,46 +230,109 @@ def __init__(self, sheet, position_buffer, intersecting_edges):
CollidingBoxes.__init__(self, sheet, position_buffer, intersecting_edges)

def _find_vert_inside(self, edge1, edge2):
triangle1 = [self.sheet.edge_df.loc[edge1][['sx', 'sy']].to_numpy(),
self.sheet.edge_df.loc[edge1][['tx', 'ty']].to_numpy(),
self.sheet.edge_df.loc[edge1][['fx', 'fy']].to_numpy()]
triangle2 = [self.sheet.edge_df.loc[edge2][['sx', 'sy']].to_numpy(),
self.sheet.edge_df.loc[edge2][['tx', 'ty']].to_numpy(),
self.sheet.edge_df.loc[edge2][['fx', 'fy']].to_numpy()]

if _point_in_triangle(self.sheet.edge_df.loc[edge1][['sx', 'sy']].to_numpy(), triangle2):
return self.sheet.edge_df.loc[edge1]['srce'], self.sheet.edge_df.loc[edge2]['face'], edge2
if _point_in_triangle(self.sheet.edge_df.loc[edge1][['tx', 'ty']].to_numpy(), triangle2):
return self.sheet.edge_df.loc[edge1]['trgt'], self.sheet.edge_df.loc[edge2]['face'], edge2
if _point_in_triangle(self.sheet.edge_df.loc[edge2][['sx', 'sy']].to_numpy(), triangle1):
return self.sheet.edge_df.loc[edge2]['srce'], self.sheet.edge_df.loc[edge1]['face'], edge1
if _point_in_triangle(self.sheet.edge_df.loc[edge2][['tx', 'ty']].to_numpy(), triangle1):
return self.sheet.edge_df.loc[edge2]['trgt'], self.sheet.edge_df.loc[edge1]['face'], edge1
triangle1 = [
self.sheet.edge_df.loc[edge1][["sx", "sy"]].to_numpy(),
self.sheet.edge_df.loc[edge1][["tx", "ty"]].to_numpy(),
self.sheet.edge_df.loc[edge1][["fx", "fy"]].to_numpy(),
]
triangle2 = [
self.sheet.edge_df.loc[edge2][["sx", "sy"]].to_numpy(),
self.sheet.edge_df.loc[edge2][["tx", "ty"]].to_numpy(),
self.sheet.edge_df.loc[edge2][["fx", "fy"]].to_numpy(),
]

if _point_in_triangle(
self.sheet.edge_df.loc[edge1][["sx", "sy"]].to_numpy(), triangle2
):
return (
self.sheet.edge_df.loc[edge1]["srce"],
self.sheet.edge_df.loc[edge2]["face"],
edge2,
)
if _point_in_triangle(
self.sheet.edge_df.loc[edge1][["tx", "ty"]].to_numpy(), triangle2
):
return (
self.sheet.edge_df.loc[edge1]["trgt"],
self.sheet.edge_df.loc[edge2]["face"],
edge2,
)
if _point_in_triangle(
self.sheet.edge_df.loc[edge2][["sx", "sy"]].to_numpy(), triangle1
):
return (
self.sheet.edge_df.loc[edge2]["srce"],
self.sheet.edge_df.loc[edge1]["face"],
edge1,
)
if _point_in_triangle(
self.sheet.edge_df.loc[edge2][["tx", "ty"]].to_numpy(), triangle1
):
return (
self.sheet.edge_df.loc[edge2]["trgt"],
self.sheet.edge_df.loc[edge1]["face"],
edge1,
)

# search inside full face
if _point_in_polygon(self.sheet, self.sheet.edge_df.loc[edge1][['sx', 'sy']].to_numpy(),
self.sheet.edge_df.loc[edge2]['face']):
return self.sheet.edge_df.loc[edge1]['srce'], self.sheet.edge_df.loc[edge2]['face'], edge2
if _point_in_polygon(self.sheet, self.sheet.edge_df.loc[edge1][['tx', 'ty']].to_numpy(),
self.sheet.edge_df.loc[edge2]['face']):
return self.sheet.edge_df.loc[edge1]['trgt'], self.sheet.edge_df.loc[edge2]['face'], edge2
if _point_in_polygon(self.sheet, self.sheet.edge_df.loc[edge2][['sx', 'sy']].to_numpy(),
self.sheet.edge_df.loc[edge1]['face']):
return self.sheet.edge_df.loc[edge2]['srce'], self.sheet.edge_df.loc[edge1]['face'], edge1
if _point_in_polygon(self.sheet, self.sheet.edge_df.loc[edge2][['tx', 'ty']].to_numpy(),
self.sheet.edge_df.loc[edge1]['face']):
return self.sheet.edge_df.loc[edge2]['trgt'], self.sheet.edge_df.loc[edge1]['face'], edge1
if _point_in_polygon(
self.sheet,
self.sheet.edge_df.loc[edge1][["sx", "sy"]].to_numpy(),
self.sheet.edge_df.loc[edge2]["face"],
):
return (
self.sheet.edge_df.loc[edge1]["srce"],
self.sheet.edge_df.loc[edge2]["face"],
edge2,
)
if _point_in_polygon(
self.sheet,
self.sheet.edge_df.loc[edge1][["tx", "ty"]].to_numpy(),
self.sheet.edge_df.loc[edge2]["face"],
):
return (
self.sheet.edge_df.loc[edge1]["trgt"],
self.sheet.edge_df.loc[edge2]["face"],
edge2,
)
if _point_in_polygon(
self.sheet,
self.sheet.edge_df.loc[edge2][["sx", "sy"]].to_numpy(),
self.sheet.edge_df.loc[edge1]["face"],
):
return (
self.sheet.edge_df.loc[edge2]["srce"],
self.sheet.edge_df.loc[edge1]["face"],
edge1,
)
if _point_in_polygon(
self.sheet,
self.sheet.edge_df.loc[edge2][["tx", "ty"]].to_numpy(),
self.sheet.edge_df.loc[edge1]["face"],
):
return (
self.sheet.edge_df.loc[edge2]["trgt"],
self.sheet.edge_df.loc[edge1]["face"],
edge1,
)

return np.NaN, np.NaN, np.NaN

def solve_collisions(self, shyness=1e-10):
id_vert_change = []
for e1, e2 in self.edge_pairs:
# Dont fix if crossing occur between two neighboring cells or between "2 same" cell.
if (self.sheet.edge_df.loc[e1]['face'] != self.sheet.edge_df.loc[e2]['face']) and (
self.sheet.edge_df.loc[e1]['face'] not in self.sheet.get_neighbors(
self.sheet.edge_df.loc[e2]['face'])):
vertices = self.sheet.edge_df.loc[[e1, e2]][['srce', 'trgt']].to_numpy().flatten()
if (
self.sheet.edge_df.loc[e1]["face"] != self.sheet.edge_df.loc[e2]["face"]
) and (
self.sheet.edge_df.loc[e1]["face"]
not in self.sheet.get_neighbors(self.sheet.edge_df.loc[e2]["face"])
):
vertices = (
self.sheet.edge_df.loc[[e1, e2]][["srce", "trgt"]]
.to_numpy()
.flatten()
)
if vertices.all() not in id_vert_change:
vert_inside, face, edge = self._find_vert_inside(e1, e2)
if not np.isnan(vert_inside):
Expand All @@ -274,7 +345,9 @@ def solve_collisions(self, shyness=1e-10):
# self.sheet.edge_df.loc[edge][['sx', 'sy']],
# self.sheet.edge_df.loc[edge][['tx', 'ty']]))
if not np.isnan(new_pos[0]):
self.sheet.vert_df.loc[vert_inside, self.sheet.coords] = new_pos
self.sheet.vert_df.loc[
vert_inside, self.sheet.coords
] = new_pos
id_vert_change.append(vert_inside)
return True

Expand Down Expand Up @@ -389,10 +462,10 @@ def _collision_plane(self, face_pair, shyness):
fe0p = self.edge_buffer[self.sheet.edge_df["face"] == f0].copy()
fe1p = self.edge_buffer[self.sheet.edge_df["face"] == f1].copy()

bb0c = _face_bbox(fe0c)
bb1c = _face_bbox(fe1c)
bb0p = _face_bbox(fe0p)
bb1p = _face_bbox(fe1p)
bb0c = self._face_bbox(fe0c)
bb1c = self._face_bbox(fe1c)
bb0p = self._face_bbox(fe0p)
bb1p = self._face_bbox(fe1p)

dr0 = bb0c - bb0p
dr1 = bb1c - bb1p
Expand Down Expand Up @@ -456,7 +529,10 @@ def _face_bbox(self, face_edges):
lower = points.min(axis=0)
upper = points.max(axis=0)
return pd.DataFrame(
[lower, upper], index=list("lh"), columns=self.coord[:len(lower)], dtype=float
[lower, upper],
index=list("lh"),
columns=self.coord[: len(lower)],
dtype=float,
).T


Expand Down Expand Up @@ -491,28 +567,37 @@ def _point_in_triangle(point, triangle):


def _point_in_polygon(sheet, point, face):
edge_index = sheet.edge_df[sheet.edge_df['face'] == face].index
ordered_vert_index = np.array(_ordered_edges(sheet.edge_df.loc[edge_index][['srce', 'trgt', 'face']])).flatten()[
0::4]
poly_path = mplPath.Path(np.array(sheet.vert_df.loc[ordered_vert_index][['x', 'y']]))
edge_index = sheet.edge_df[sheet.edge_df["face"] == face].index
ordered_vert_index = np.array(
_ordered_edges(sheet.edge_df.loc[edge_index][["srce", "trgt", "face"]])
).flatten()[0::4]
poly_path = mplPath.Path(
np.array(sheet.vert_df.loc[ordered_vert_index][["x", "y"]])
)
# point = np.array(sheet.edge_df.loc[8][['tx', 'ty']])
return poly_path.contains_point(point)


def vertex_repulse(eptm, vertex):
try:
face1, face2 = eptm.edge_df[eptm.edge_df['srce'] == vertex]["face"].to_numpy()
face1, face2 = eptm.edge_df[eptm.edge_df["srce"] == vertex]["face"].to_numpy()
except:
# print("vertex at border")
return np.nan, np.nan

vec1 = [eptm.vert_df.loc[vertex]['x'] - eptm.face_df.loc[face1]['x'],
eptm.vert_df.loc[vertex]['y'] - eptm.face_df.loc[face1]['y'], ]
vec1 = [
eptm.vert_df.loc[vertex]["x"] - eptm.face_df.loc[face1]["x"],
eptm.vert_df.loc[vertex]["y"] - eptm.face_df.loc[face1]["y"],
]

vec2 = [eptm.vert_df.loc[vertex]['x'] - eptm.face_df.loc[face2]['x'],
eptm.vert_df.loc[vertex]['y'] - eptm.face_df.loc[face2]['y'], ]
vec2 = [
eptm.vert_df.loc[vertex]["x"] - eptm.face_df.loc[face2]["x"],
eptm.vert_df.loc[vertex]["y"] - eptm.face_df.loc[face2]["y"],
]

new_pos = eptm.vert_df.loc[vertex][list('xy')].to_numpy() - np.add(vec1, vec2) / 2 * 0.5
new_pos = (
eptm.vert_df.loc[vertex][list("xy")].to_numpy() - np.add(vec1, vec2) / 2 * 0.5
)
return new_pos


Expand Down
Loading

0 comments on commit a8d12c4

Please sign in to comment.