- 添加Blender插件核心文件:__init__.py、ui.py、property.py、preference.py - 添加插件工具模块:g.py、loop.py、generate_loop.py、const.py、op.py - 添加翻译工具:utils/trans.py - 添加PuLP线性规划库及其依赖文件,包括CBC求解器二进制文件 - 添加.gitignore和VSCode配置文件
1663 lines
44 KiB
Python
1663 lines
44 KiB
Python
from __future__ import annotations
|
||
import bmesh
|
||
import numpy as np
|
||
import os
|
||
import sys
|
||
import copy
|
||
|
||
from . import loop # 不要调用,仅作为提示
|
||
from .utils import functions
|
||
from . import g
|
||
|
||
lib_path = os.path.abspath(os.path.join(os.path.dirname(__file__), "utils"))
|
||
sys.path.append(lib_path)
|
||
from .utils import pulp
|
||
from .utils.trans import t
|
||
|
||
|
||
class Pattern:
|
||
def __init__(
|
||
self,
|
||
name,
|
||
A,
|
||
b_r,
|
||
pattern_check,
|
||
vert_coords,
|
||
edge_idxs,
|
||
face_idxs,
|
||
split_vert_idxs,
|
||
additional_edge_flow_info={},
|
||
):
|
||
self.name = name
|
||
self.A = A
|
||
self.b_r = b_r
|
||
self.loop = None
|
||
self.pattern_check = pattern_check
|
||
self.vert_coords = vert_coords
|
||
self.edge_idxs = edge_idxs
|
||
self.face_idxs = face_idxs
|
||
self.split_vert_idxs = split_vert_idxs
|
||
self.additional_edge_flow_info = additional_edge_flow_info
|
||
|
||
self.op_instance = None
|
||
self.rotation = 0
|
||
self.verts = []
|
||
self.edges = []
|
||
self.faces = []
|
||
self.interior_verts = []
|
||
self.interior_edges = []
|
||
self.solution = None
|
||
|
||
@property
|
||
def boundary_num(self):
|
||
return len(self.b_r)
|
||
|
||
def remove_mesh(self):
|
||
interior_verts = self.interior_verts
|
||
interior_edges = self.interior_edges
|
||
faces = self.faces
|
||
|
||
# 先置为空再删除,防止绘图先获取
|
||
self.interior_verts = []
|
||
self.interior_edges = []
|
||
|
||
functions.remove_bm_faces(g.obj_bm, faces)
|
||
functions.remove_bm_edges(g.obj_bm, interior_edges)
|
||
functions.delete_bm_verts(g.obj_bm, interior_verts)
|
||
bmesh.update_edit_mesh(g.obj_me)
|
||
|
||
def create_mesh(self, pattern_solution, rotation):
|
||
functions.log("creating patern mesh")
|
||
vert_coords = self.vert_coords
|
||
edge_idxs = self.edge_idxs
|
||
face_idxs = self.face_idxs
|
||
split_vert_idxs = self.split_vert_idxs
|
||
|
||
# pattern_solution符合input,需要旋转符合pattern,才能合并边缘
|
||
padding_list = functions.rotate_list(
|
||
pattern_solution[: self.boundary_num], rotation
|
||
)
|
||
|
||
# 用于检查形状
|
||
rotated_boundaries_verts = [
|
||
boundary.verts if d else boundary.verts[::-1]
|
||
for boundary, d in functions.rotate_list(self.loop.b_and_d_list, rotation)
|
||
]
|
||
patch_boundary_shape = [len(i) for i in rotated_boundaries_verts]
|
||
|
||
me = g.obj_me
|
||
bm = g.obj_bm
|
||
|
||
# 创建顶点
|
||
init_verts = []
|
||
for idx, coord in enumerate(vert_coords):
|
||
vert = bm.verts.new(coord)
|
||
init_verts.append(vert)
|
||
split_verts = [init_verts[idx] for idx in split_vert_idxs]
|
||
|
||
# 创建网格前确保顶点索引更新
|
||
bm.verts.ensure_lookup_table()
|
||
|
||
# 创建边
|
||
init_edges = []
|
||
for edge_indices in edge_idxs:
|
||
edge = bm.edges.new(
|
||
(init_verts[edge_indices[0]], init_verts[edge_indices[1]])
|
||
)
|
||
init_edges.append(edge)
|
||
|
||
# 创建面
|
||
init_faces = []
|
||
for face_indices in face_idxs:
|
||
face = bm.faces.new([init_verts[i] for i in face_indices])
|
||
init_faces.append(face)
|
||
|
||
# 细分创建附加边流
|
||
misc_edge_flow_verts = []
|
||
misc_edge_flow_edges = []
|
||
misc_edge_flow_faces = []
|
||
for key, idx in self.additional_edge_flow_info.items():
|
||
cut_num = 0
|
||
edge = init_edges[idx]
|
||
if key == "x":
|
||
cut_num = pattern_solution[self.boundary_num]
|
||
elif key == "y":
|
||
cut_num = pattern_solution[self.boundary_num + 1]
|
||
elif key == "z":
|
||
cut_num = pattern_solution[self.boundary_num + 2]
|
||
else:
|
||
continue
|
||
result = bmesh.ops.subdivide_edgering(
|
||
bm,
|
||
edges=functions.edge_loops(bm, edge),
|
||
cuts=int(cut_num),
|
||
profile_shape="INVERSE_SQUARE",
|
||
profile_shape_factor=0.0,
|
||
)
|
||
for face in result["faces"]:
|
||
for vert in face.verts:
|
||
misc_edge_flow_verts.append(vert)
|
||
for edge in face.edges:
|
||
misc_edge_flow_edges.append(edge)
|
||
misc_edge_flow_faces.append(face)
|
||
|
||
# 挤出
|
||
misc_extruded_subdivide_verts = []
|
||
misc_extruded_subdivide_edges = []
|
||
misc_extruded_subdivide_faces = []
|
||
for i, padding_num in enumerate(padding_list):
|
||
if padding_num == 0:
|
||
continue
|
||
start_split_vert = split_verts[i]
|
||
if i + 1 == len(padding_list):
|
||
end_split_vert = split_verts[0]
|
||
else:
|
||
end_split_vert = split_verts[i + 1]
|
||
|
||
boundary_edges = []
|
||
# 寻找需要挤出的边,2个边组的情况另算
|
||
# 这里是在细分之后,寻找方法是分割点寻找最近点,
|
||
if self.loop.length >= 3:
|
||
_, boundary_edges = functions.dijkstra(
|
||
bm, start_split_vert, end_split_vert
|
||
)
|
||
|
||
elif self.loop.length == 2:
|
||
# 第一个是边数多的,因为长度较短
|
||
first_boundary_verts, first_boundary_edges = functions.dijkstra(
|
||
bm,
|
||
start_split_vert,
|
||
end_split_vert,
|
||
exclude_edges=[],
|
||
is_along_boundary=True,
|
||
)
|
||
second_boundary_verts, second_boundary_edges = functions.dijkstra(
|
||
bm,
|
||
end_split_vert,
|
||
start_split_vert,
|
||
exclude_edges=first_boundary_edges,
|
||
is_along_boundary=True,
|
||
)
|
||
# 根据旋转赋值长短边
|
||
# pattern默认第一个边是下面那一个,也就是边数多的那一个
|
||
# dijk获取的边第一个是边数少的那个
|
||
if i == 0:
|
||
boundary_edges = second_boundary_edges
|
||
else:
|
||
boundary_edges = first_boundary_edges
|
||
|
||
# for i in bm.verts:
|
||
# i.select = False
|
||
# start_split_vert.select = True
|
||
# end_split_vert.select = True
|
||
# bmesh.update_edit_mesh(me)
|
||
# return
|
||
|
||
else:
|
||
raise Exception("Ivalide boundary num")
|
||
|
||
extruded = bmesh.ops.extrude_edge_only(bm, edges=boundary_edges)
|
||
extruded_verts = [
|
||
v for v in extruded["geom"] if isinstance(v, bmesh.types.BMVert)
|
||
]
|
||
extruded_edges = [
|
||
v for v in extruded["geom"] if isinstance(v, bmesh.types.BMEdge)
|
||
]
|
||
extruded_faces = [
|
||
v for v in extruded["geom"] if isinstance(v, bmesh.types.BMFace)
|
||
]
|
||
misc_extruded_subdivide_verts += extruded_verts
|
||
misc_extruded_subdivide_edges += extruded_edges
|
||
misc_extruded_subdivide_faces += extruded_faces
|
||
|
||
# 找新分割点
|
||
new_start_split_vert = None
|
||
new_end_split_vert = None
|
||
len_1 = float("inf")
|
||
len_2 = float("inf")
|
||
for vert in extruded_verts:
|
||
new_len_1 = len(functions.dijkstra(bm, start_split_vert, vert)[0])
|
||
if new_len_1 < len_1:
|
||
len_1 = new_len_1
|
||
new_start_split_vert = vert
|
||
new_len_2 = len(functions.dijkstra(bm, end_split_vert, vert)[0])
|
||
if new_len_2 < len_2:
|
||
len_2 = new_len_2
|
||
new_end_split_vert = vert
|
||
|
||
# 更新找分割点
|
||
for idx, vert in enumerate(split_verts):
|
||
if vert == start_split_vert:
|
||
split_verts[idx] = new_start_split_vert
|
||
if vert == end_split_vert:
|
||
split_verts[idx] = new_end_split_vert
|
||
|
||
# 细分挤出,作为作为挤出段数
|
||
if padding_num > 1:
|
||
first_extrudeedge = functions.dijkstra(
|
||
bm, start_split_vert, new_start_split_vert
|
||
)[1][0]
|
||
|
||
result = bmesh.ops.subdivide_edgering(
|
||
bm,
|
||
edges=functions.edge_loops(bm, first_extrudeedge),
|
||
cuts=int(padding_num - 1),
|
||
profile_shape="INVERSE_SQUARE",
|
||
profile_shape_factor=0.0,
|
||
)
|
||
|
||
for face in result["faces"]:
|
||
for vert in face.verts:
|
||
misc_extruded_subdivide_verts.append(vert)
|
||
for edge in face.edges:
|
||
misc_extruded_subdivide_edges.append(edge)
|
||
misc_extruded_subdivide_faces.append(face)
|
||
|
||
# 不能使用edge,获取内部边,因合并的问题,当内部edge连接到了要被合并的顶点,则该edge会被新的替代,
|
||
# 去除不存在和重复
|
||
edges = set(init_edges).union(
|
||
misc_extruded_subdivide_edges, misc_edge_flow_edges
|
||
)
|
||
verts = set(init_verts).union(
|
||
misc_extruded_subdivide_verts, misc_edge_flow_verts
|
||
)
|
||
faces = set(init_faces).union(
|
||
misc_extruded_subdivide_faces, misc_edge_flow_faces
|
||
)
|
||
|
||
# inter绘图用,verts删除用
|
||
# # 去除不存在的
|
||
# 合并点会破坏点和边的索引,需要用面找边
|
||
self.faces = [face for face in faces if face in bm.faces]
|
||
|
||
# 也要记录vert,因为重建boundary会把面破坏掉,
|
||
verts, edges = functions.get_verts_and_edges_from_faces(g.obj_bm, self.faces)
|
||
verts = [vert for vert in verts if vert in bm.verts]
|
||
edges = [edge for edge in edges if edge in bm.edges]
|
||
|
||
self.edges = edges
|
||
self.verts = verts
|
||
self.interior_verts = [vert for vert in verts if not vert.is_boundary]
|
||
|
||
# 获取将要合并的顶点列表,单独处理2个边的情况
|
||
pattern_boundaries_verts = []
|
||
if len(self.loop.shape) >= 3:
|
||
for i in range(len(split_verts)):
|
||
start_split_vert = split_verts[i]
|
||
if i + 1 == len(padding_list):
|
||
end_split_vert = split_verts[0]
|
||
else:
|
||
end_split_vert = split_verts[i + 1]
|
||
boundary_verts, _ = functions.dijkstra(
|
||
bm, start_split_vert, end_split_vert
|
||
)
|
||
pattern_boundaries_verts.append(boundary_verts)
|
||
|
||
elif len(self.loop.shape) == 2:
|
||
first_boundary_start_vert = split_verts[0]
|
||
first_boundary_end_vert = split_verts[1]
|
||
first_boundary_verts, first_boundary_edges = functions.dijkstra(
|
||
bm,
|
||
first_boundary_start_vert,
|
||
first_boundary_end_vert,
|
||
exclude_edges=[],
|
||
is_along_boundary=True,
|
||
)
|
||
|
||
second_boundary_start_vert = split_verts[1]
|
||
second_boundary_end_vert = split_verts[0]
|
||
second_boundary_verts, second_boundary_edges = functions.dijkstra(
|
||
bm,
|
||
second_boundary_start_vert,
|
||
second_boundary_end_vert,
|
||
exclude_edges=first_boundary_edges,
|
||
is_along_boundary=True,
|
||
)
|
||
|
||
pattern_boundaries_verts = [
|
||
first_boundary_verts,
|
||
second_boundary_verts,
|
||
]
|
||
|
||
# 两条边无法区分顺序,自行翻转顺序
|
||
pattern_boundary_shape = [len(i) for i in pattern_boundaries_verts]
|
||
if (
|
||
len(self.loop.shape) == 2
|
||
and pattern_boundary_shape != patch_boundary_shape
|
||
):
|
||
pattern_boundaries_verts = pattern_boundaries_verts[::-1]
|
||
|
||
else:
|
||
raise Exception("Ivalid boundary num")
|
||
|
||
# 检查形状
|
||
pattern_boundary_shape = [len(i) for i in pattern_boundaries_verts]
|
||
if len(self.loop.shape) >= 2 and pattern_boundary_shape != patch_boundary_shape:
|
||
self.remove_mesh()
|
||
msg = f"\n{self.name}\ninput {self.loop.shape}\nsolution {pattern_solution}\nrotation {rotation}\npattern shape {pattern_boundary_shape}\npatch shape {patch_boundary_shape}\nshape not match"
|
||
raise Exception(msg)
|
||
|
||
for i, (verts_1, verts_2) in enumerate(
|
||
zip(pattern_boundaries_verts, rotated_boundaries_verts)
|
||
):
|
||
for j, (vert_1, vert_2) in enumerate(zip(verts_1, verts_2)):
|
||
if j == len(verts_1) - 1:
|
||
continue
|
||
bmesh.ops.pointmerge(
|
||
bm, verts=[vert_2, vert_1], merge_co=vert_2.co
|
||
) # 会破坏点线面对象和索引
|
||
|
||
# 要在合并顶点后获取edges,合并会破坏edge对象
|
||
verts, edges = functions.get_verts_and_edges_from_faces(g.obj_bm, self.faces)
|
||
self.interior_edges = [
|
||
edge for edge in edges if edge in bm.edges and edge not in self.loop.edges
|
||
]
|
||
self.interior_verts = [
|
||
vert
|
||
for vert in verts
|
||
if vert in bm.verts and vert not in self.loop.boundary_verts_walk
|
||
]
|
||
|
||
functions.smooth_verts_by_normal(g.obj, bm, self.verts)
|
||
|
||
# 更新网格
|
||
# 计算法线方向
|
||
bmesh.ops.recalc_face_normals(
|
||
bm, faces=list([i for i in faces if i in bm.faces])
|
||
)
|
||
if g.is_snap_surface:
|
||
functions.snap_verts_to_surface_along_normal(
|
||
functions.get_edit_obj(),
|
||
g.obj_bm,
|
||
self.interior_verts,
|
||
g.snap_bvh_trees,
|
||
allow_opposite_direction=False,
|
||
)
|
||
bmesh.update_edit_mesh(me)
|
||
bm.normal_update()
|
||
|
||
# def clear(self):
|
||
# bmesh.ops.delete(
|
||
# self.op_instance.bm,
|
||
# geom=self.interior_verts,
|
||
# context="VERTS",
|
||
# )
|
||
|
||
# bmesh.update_edit_mesh(self.op_instance.me)
|
||
|
||
# self.boundary_verts = []
|
||
# self.interior_verts = []
|
||
|
||
def validate_input_and_get_rotation(self, boundary_shape):
|
||
all_reduced_inputs = functions.get_all_reduced_inputs(boundary_shape)
|
||
boundary_shape = all_reduced_inputs[0]
|
||
|
||
rotation = None
|
||
boundary_shape_temp = None
|
||
|
||
for r in range(len(boundary_shape)):
|
||
boundary_shape_temp = functions.rotate_list(boundary_shape, r)
|
||
rotation = r
|
||
|
||
for a, b in zip(self.pattern_check, boundary_shape_temp):
|
||
if isinstance(a, int) and a != b:
|
||
rotation = None
|
||
continue
|
||
|
||
if callable(a):
|
||
result = a(boundary_shape_temp)
|
||
if isinstance(result, int) and result < 0:
|
||
rotation = None
|
||
continue
|
||
|
||
if isinstance(result, float) and (
|
||
result < 0 or not result.is_integer()
|
||
):
|
||
rotation = None
|
||
continue
|
||
|
||
if rotation is None:
|
||
continue
|
||
else:
|
||
# 匹配
|
||
functions.log(f"reduce: {boundary_shape}")
|
||
functions.log(f"rotation: {r}")
|
||
return r
|
||
|
||
return None
|
||
|
||
def solve_pattern_lp(
|
||
self, boundary_shape, rotation, constraint_list=[], is_suggest=False
|
||
):
|
||
# TODO: ilp没加整数校验
|
||
boundary_input = functions.rotate_list(boundary_shape, rotation)
|
||
|
||
boundary_input_len = len(boundary_input)
|
||
constraint_list = (
|
||
functions.rotate_list(constraint_list[:boundary_input_len], rotation)
|
||
+ constraint_list[boundary_input_len:]
|
||
)
|
||
|
||
functions.log(f"solver shape input: {boundary_input}")
|
||
functions.log(f"solver constraint input: {constraint_list}")
|
||
functions.log(f"solver rotation input: {rotation}")
|
||
|
||
A = np.array(self.A)
|
||
b_l = np.array(boundary_input)
|
||
b_r = np.array(self.b_r)
|
||
b = b_l - b_r
|
||
|
||
num_cols = A.shape[1] # 列,变量数,p和边流
|
||
num_rows = A.shape[0] # 行,即约束数,p
|
||
indices = list(range(num_cols))
|
||
|
||
p = [
|
||
pulp.LpVariable(f"p_{i}", lowBound=0, cat=pulp.LpInteger)
|
||
for i in range(num_rows)
|
||
]
|
||
|
||
edge_flow_vars = []
|
||
if num_cols > num_rows:
|
||
for i in range(num_cols - num_rows):
|
||
var_name = None
|
||
if i == 0:
|
||
var_name = "x"
|
||
if i == 1:
|
||
var_name = "y"
|
||
if i == 2:
|
||
var_name = "z"
|
||
|
||
if var_name:
|
||
edge_flow_var = pulp.LpVariable(
|
||
var_name, lowBound=0, cat=pulp.LpInteger
|
||
)
|
||
edge_flow_vars.append(edge_flow_var)
|
||
|
||
vars = p + edge_flow_vars
|
||
|
||
if is_suggest:
|
||
# 软约束
|
||
prob = pulp.LpProblem("ProbLp", pulp.LpMinimize)
|
||
dev_pos_list = [
|
||
pulp.LpVariable(f"dev_{i}_pos", lowBound=0) for i in range(num_rows)
|
||
]
|
||
dev_neg_list = [
|
||
pulp.LpVariable(f"dev_{i}_neg", lowBound=0) for i in range(num_rows)
|
||
]
|
||
|
||
prob += pulp.lpSum(dev_pos_list) + pulp.lpSum(dev_neg_list)
|
||
|
||
for i in range(num_rows):
|
||
prob += (
|
||
pulp.lpSum([A[i][j] * vars[j] for j in indices])
|
||
== b[i] + dev_pos_list[i] - dev_neg_list[i]
|
||
)
|
||
|
||
# 用户附加约束
|
||
for i, j in zip(vars, constraint_list):
|
||
if j is None:
|
||
continue
|
||
prob += i == j
|
||
status = prob.solve(pulp.PULP_CBC_CMD(msg=0))
|
||
|
||
# 求的时候建议了旋转,解的时候转回来
|
||
solution = [
|
||
i.value() for i in functions.rotate_list(dev_pos_list, -rotation)
|
||
] + [i.value() for i in functions.rotate_list(dev_neg_list, -rotation)]
|
||
# solution = [i.value() for i in dev_pos_list] + [
|
||
# i.value() for i in dev_neg_list
|
||
# ]
|
||
|
||
else:
|
||
# 硬约束
|
||
prob = pulp.LpProblem("ProbLp", pulp.LpMaximize)
|
||
prob += pulp.lpSum(p)
|
||
|
||
b = b_l - b_r
|
||
for i in range(num_rows):
|
||
prob += pulp.lpSum([A[i][j] * vars[j] for j in indices]) == b[i]
|
||
|
||
# 用户附加约束
|
||
for i, j in zip(vars, constraint_list):
|
||
if j is None:
|
||
continue
|
||
prob += i == j
|
||
|
||
status = prob.solve(pulp.PULP_CBC_CMD(msg=0))
|
||
|
||
solution = [
|
||
i.value()
|
||
for i in (
|
||
functions.rotate_list(vars[:boundary_input_len], -rotation)
|
||
+ vars[boundary_input_len:]
|
||
)
|
||
]
|
||
# solution = [i.value() for i in vars]
|
||
|
||
if status != 1:
|
||
functions.log("no solution")
|
||
return None
|
||
|
||
# 如果edgeflow缺了,手动附加
|
||
if len(vars) - len(solution) > 0:
|
||
solution += [0.0 for _ in range(len(vars) - len(solution))]
|
||
|
||
if is_suggest:
|
||
functions.log(f"suggest: {solution}")
|
||
else:
|
||
functions.log(f"solution: {solution}")
|
||
|
||
return solution
|
||
|
||
|
||
# 这里写的很乱,理一理
|
||
def recreate_pattern(loop):
|
||
if not loop:
|
||
return None
|
||
|
||
if loop.pattern:
|
||
loop.pattern.remove_mesh()
|
||
loop.pattern = None
|
||
|
||
loop.solver_msg = ""
|
||
loop.suggest_solution = None
|
||
|
||
# 检查奇偶
|
||
if sum(loop.shape) % 2 != 0:
|
||
loop.solver_msg = t("not_even_num_edges")
|
||
return None
|
||
|
||
boundary_shape = loop.shape
|
||
pattern_instance = None
|
||
rotation = None
|
||
pattern_solution = None
|
||
|
||
constraint_pattern = loop.solver_constraint_pattern
|
||
constraint_list = loop.solver_constraint_list
|
||
|
||
# 有pattern约束且没有rotation约束,则搜索rotation,否则rotation就是当前约束
|
||
if constraint_pattern:
|
||
pattern_instance = copy.deepcopy(constraint_pattern)
|
||
constraint_rotation = loop.solver_constraint_rotation
|
||
# 没有约束但rotation没定义,则遍历搜索rotation,因此用户调整var的时候,如果没有rotation约束,会搜索n次,很慢
|
||
if constraint_rotation is None:
|
||
# 遍历rotation计算n次
|
||
for r in range(len(loop.shape)):
|
||
pattern_solution = pattern_instance.solve_pattern_lp(
|
||
loop.shape, r, constraint_list=constraint_list
|
||
)
|
||
if pattern_solution is not None:
|
||
rotation = r
|
||
break
|
||
else:
|
||
pattern_solution = pattern_instance.solve_pattern_lp(
|
||
loop.shape, constraint_rotation, constraint_list=constraint_list
|
||
)
|
||
rotation = constraint_rotation
|
||
|
||
else:
|
||
# 初始化遍历寻找符合的pattern
|
||
for pattern in pattern_list:
|
||
# 匹配长度
|
||
if len(boundary_shape) != pattern.boundary_num:
|
||
continue
|
||
|
||
rotation = pattern.validate_input_and_get_rotation(boundary_shape)
|
||
if rotation is None:
|
||
continue
|
||
|
||
pattern_instance = copy.deepcopy(pattern)
|
||
break
|
||
|
||
if not pattern_instance:
|
||
loop.solver_msg = t("no_match_pattern")
|
||
return None
|
||
|
||
pattern_solution = pattern_instance.solve_pattern_lp(loop.shape, rotation)
|
||
|
||
# 无解,给出建议
|
||
if pattern_solution is None:
|
||
# 这里的rotation变量是承接上文的,有可能是None
|
||
if rotation is not None:
|
||
suggest_rotation = rotation
|
||
else:
|
||
# 如果是带约束,到这一步之前会执行n次ilp,因为要解决旋转问题,如果不带约束,则在这之前只执行了一次
|
||
suggest_rotation = get_suggest_rotation(pattern_instance, loop.shape)
|
||
|
||
functions.log(f"suggest rotation: suggest_rotation")
|
||
suggest_solution = pattern_instance.solve_pattern_lp(
|
||
loop.shape,
|
||
suggest_rotation,
|
||
constraint_list=constraint_list,
|
||
is_suggest=True,
|
||
)
|
||
if suggest_solution:
|
||
loop.suggest_solution = suggest_solution
|
||
|
||
loop.solver_msg = t("no_solution")
|
||
return None
|
||
|
||
pattern_instance.rotation = rotation
|
||
|
||
pattern_instance.loop = loop
|
||
pattern_instance.solution = pattern_solution
|
||
|
||
pattern_instance.create_mesh(pattern_solution, rotation)
|
||
|
||
return pattern_instance
|
||
|
||
|
||
# 没有rotation的情况给建议,先找rotation,通过与pattern_check的差异查找
|
||
def get_suggest_rotation(pattern, boundary_shape):
|
||
all_reduced_inputs = functions.get_all_reduced_inputs(
|
||
boundary_shape, is_remove_duplicated_rotation=False
|
||
)
|
||
pattern_check = pattern.pattern_check
|
||
suggest_rotation = 0
|
||
dev_min = float("inf")
|
||
for boundary_shape in all_reduced_inputs:
|
||
for rotation in range(len(boundary_shape)):
|
||
boundary_shape_temp = functions.rotate_list(boundary_shape, rotation)
|
||
dev = 0
|
||
for a, b in zip(pattern_check, boundary_shape_temp):
|
||
if isinstance(a, int):
|
||
dev += abs(a - b)
|
||
|
||
if callable(a):
|
||
result = a(boundary_shape_temp)
|
||
dev += abs(result)
|
||
|
||
if dev < dev_min:
|
||
dev_min = dev
|
||
suggest_rotation = rotation
|
||
|
||
return suggest_rotation
|
||
|
||
|
||
def try_create_pattern():
|
||
pass
|
||
|
||
|
||
pattern_list = []
|
||
|
||
# 2-0
|
||
name = "2-0"
|
||
A = [
|
||
[0, 2, 2, 1],
|
||
[2, 0, 0, 1],
|
||
]
|
||
b_r = [3, 1]
|
||
pattern_check = [lambda i: (i[0] - i[1] - 2) / 2, lambda i: i[1] - 1]
|
||
vert_coords = [[2.0, 1.0, 0.0], [-2.0, 1.0, 0.0], [1.0, -1.0, 0.0], [-1.0, -1.0, 0.0]]
|
||
edge_idxs = [[3, 2], [0, 1], [2, 0], [1, 3]]
|
||
face_idxs = [[3, 2, 0, 1]]
|
||
split_vert_idxs = (1, 0)
|
||
additional_edge_flow_info = {"x": 3, "y": 0}
|
||
pattern_list.append(
|
||
Pattern(
|
||
name,
|
||
A,
|
||
b_r,
|
||
pattern_check,
|
||
vert_coords,
|
||
edge_idxs,
|
||
face_idxs,
|
||
split_vert_idxs,
|
||
additional_edge_flow_info,
|
||
)
|
||
)
|
||
|
||
# 2-1
|
||
name = "2-1"
|
||
A = [
|
||
[0, 2, 1, 1],
|
||
[2, 0, 1, 1],
|
||
]
|
||
b_r = [2, 2]
|
||
pattern_check = [lambda i: 0.999 * (i[0] - i[1]), lambda i: i[0] - 2]
|
||
vert_coords = [
|
||
[-1.4142135381698608, 0.0, 0.0],
|
||
[0.0, -2.4142136573791504, 0.0],
|
||
[0.0, 1.4142135381698608, 0.0],
|
||
[1.4142135381698608, 0.0, 0.0],
|
||
]
|
||
edge_idxs = [[0, 1], [2, 0], [3, 2], [1, 3]]
|
||
face_idxs = [[0, 1, 3, 2]]
|
||
split_vert_idxs = [0, 3]
|
||
additional_edge_flow_info = {"x": 0, "y": 3}
|
||
pattern_list.append(
|
||
Pattern(
|
||
name,
|
||
A,
|
||
b_r,
|
||
pattern_check,
|
||
vert_coords,
|
||
edge_idxs,
|
||
face_idxs,
|
||
split_vert_idxs,
|
||
additional_edge_flow_info,
|
||
)
|
||
)
|
||
|
||
# 3-0
|
||
name = "3-0"
|
||
A = [
|
||
[0, 1, 1],
|
||
[1, 0, 1],
|
||
[1, 1, 0],
|
||
]
|
||
b_r = [2, 1, 1]
|
||
pattern_check = [2, 1, 1]
|
||
vert_coords = [
|
||
(0.0, 1.0, 0.0),
|
||
(-0.8660253882408142, -0.5, 0.0),
|
||
(0.8660253882408142, -0.5, 0.0),
|
||
(0.0, -0.5, 0.0),
|
||
]
|
||
edge_idxs = [(1, 0), (3, 1), (0, 2), (2, 3)]
|
||
face_idxs = [[1, 3, 2, 0]]
|
||
split_vert_idxs = [1, 2, 0]
|
||
additional_edge_flow_info = {}
|
||
pattern_list.append(
|
||
Pattern(
|
||
name,
|
||
A,
|
||
b_r,
|
||
pattern_check,
|
||
vert_coords,
|
||
edge_idxs,
|
||
face_idxs,
|
||
split_vert_idxs,
|
||
additional_edge_flow_info,
|
||
)
|
||
)
|
||
|
||
|
||
# 3-1
|
||
name = "3-1"
|
||
A = (
|
||
(0, 1, 1, 2),
|
||
(1, 0, 1, 0),
|
||
(1, 1, 0, 0),
|
||
)
|
||
b_r = [4, 1, 1]
|
||
pattern_check = [lambda i: (i[0] - 4) / 2, 1, 1]
|
||
vert_coords = [
|
||
(0.0, 1.0, 0.0),
|
||
(-0.8660253882408142, -0.5, 0.0),
|
||
(0.8660253882408142, -0.5, 0.0),
|
||
(0.0, 0.0, 0.0),
|
||
(0.0, -0.5, 0.0),
|
||
(0.4330126941204071, -0.5, 0.0),
|
||
(-0.4330126941204071, -0.5, 0.0),
|
||
]
|
||
edge_idxs = [(1, 0), (6, 1), (0, 2), (4, 6), (5, 4), (2, 5), (3, 5), (3, 6), (0, 3)]
|
||
face_idxs = [[4, 5, 3, 6], [1, 6, 3, 0], [2, 0, 3, 5]]
|
||
split_vert_idxs = (1, 2, 0)
|
||
additional_edge_flow_info = {"x": 8}
|
||
pattern_list.append(
|
||
Pattern(
|
||
name,
|
||
A,
|
||
b_r,
|
||
pattern_check,
|
||
vert_coords,
|
||
edge_idxs,
|
||
face_idxs,
|
||
split_vert_idxs,
|
||
additional_edge_flow_info,
|
||
)
|
||
)
|
||
|
||
|
||
# 4-0
|
||
name = "4-0"
|
||
A = (
|
||
(0, 1, 0, 1),
|
||
(1, 0, 1, 0),
|
||
(0, 1, 0, 1),
|
||
(1, 0, 1, 0),
|
||
)
|
||
b_r = (1, 1, 1, 1)
|
||
pattern_check = (1, 1, 1, 1)
|
||
vert_coords = [(1.0, 1.0, 0.0), (-1.0, 1.0, 0.0), (1.0, -1.0, 0.0), (-1.0, -1.0, 0.0)]
|
||
edge_idxs = [(2, 0), (3, 2), (0, 1), (1, 3)]
|
||
face_idxs = [[3, 2, 0, 1]]
|
||
split_vert_idxs = [3, 2, 0, 1]
|
||
additional_edge_flow_info = {}
|
||
pattern_list.append(
|
||
Pattern(
|
||
name,
|
||
A,
|
||
b_r,
|
||
pattern_check,
|
||
vert_coords,
|
||
edge_idxs,
|
||
face_idxs,
|
||
split_vert_idxs,
|
||
additional_edge_flow_info,
|
||
)
|
||
)
|
||
|
||
# 4-1
|
||
name = "4-1"
|
||
A = (
|
||
(0, 1, 0, 1, 1),
|
||
(1, 0, 1, 0, 1),
|
||
(0, 1, 0, 1, 0),
|
||
(1, 0, 1, 0, 0),
|
||
)
|
||
b_r = (2, 2, 1, 1)
|
||
# pattern_check = (
|
||
# lambda i: 0.5 * (i[0] != i[1]),
|
||
# lambda i: i[1] - 2,
|
||
# 1,
|
||
# 1,
|
||
# )
|
||
pattern_check = (
|
||
lambda i: 0.999 * (i[0] - i[1]),
|
||
lambda i: i[1] - 2,
|
||
1,
|
||
1,
|
||
)
|
||
vert_coords = [
|
||
(1.0, 1.0, 0.0),
|
||
(-1.0, 1.0, 0.0),
|
||
(1.0, -1.0, 0.0),
|
||
(-1.0, -1.0, 0.0),
|
||
(0.0, 0.0, 0.0),
|
||
(1.0, 0.0, 0.0),
|
||
(0.0, -1.0, 0.0),
|
||
]
|
||
edge_idxs = [(0, 1), (6, 2), (1, 3), (5, 0), (4, 6), (4, 5), (2, 5), (3, 6), (1, 4)]
|
||
face_idxs = [[6, 4, 5, 2], [0, 5, 4, 1], [3, 1, 4, 6]]
|
||
split_vert_idxs = (3, 2, 0, 1)
|
||
additional_edge_flow_info = {"x": 8}
|
||
pattern_list.append(
|
||
Pattern(
|
||
name,
|
||
A,
|
||
b_r,
|
||
pattern_check,
|
||
vert_coords,
|
||
edge_idxs,
|
||
face_idxs,
|
||
split_vert_idxs,
|
||
additional_edge_flow_info,
|
||
)
|
||
)
|
||
|
||
|
||
# 4-2
|
||
name = "4-2"
|
||
A = (
|
||
(0, 1, 0, 1, 1, 1),
|
||
(1, 0, 1, 0, 1, 0),
|
||
(0, 1, 0, 1, 0, 0),
|
||
(1, 0, 1, 0, 0, 1),
|
||
)
|
||
b_r = (3, 1, 1, 1)
|
||
# pattern_check = [
|
||
# lambda i: i[1] - 1,
|
||
# lambda i: i[3] - 1,
|
||
# 1,
|
||
# lambda i: 0.5 * (i[0] - i[1] - i[3] != 1),
|
||
# ]
|
||
pattern_check = [
|
||
lambda i: i[1] - 1,
|
||
lambda i: i[3] - 1,
|
||
1,
|
||
lambda i: 0.999 * (i[0] - i[1] - i[3] - 1),
|
||
]
|
||
vert_coords = [
|
||
(0.3333333134651184, -1.0, 0.0),
|
||
(-0.3333333134651184, -1.0, 0.0),
|
||
(1.0, 1.0, 0.0),
|
||
(-1.0, 1.0, 0.0),
|
||
(1.0, -1.0, 0.0),
|
||
(-1.0, -1.0, 0.0),
|
||
]
|
||
edge_idxs = [(3, 5), (0, 4), (1, 0), (5, 1), (1, 2), (4, 2), (2, 3)]
|
||
face_idxs = [[3, 2, 1, 5], [0, 1, 2, 4]]
|
||
|
||
split_vert_idxs = (5, 4, 2, 3)
|
||
additional_edge_flow_info = {"x": 2, "y": 4}
|
||
pattern_list.append(
|
||
Pattern(
|
||
name,
|
||
A,
|
||
b_r,
|
||
pattern_check,
|
||
vert_coords,
|
||
edge_idxs,
|
||
face_idxs,
|
||
split_vert_idxs,
|
||
additional_edge_flow_info,
|
||
)
|
||
)
|
||
|
||
name = "4-2-i"
|
||
# pattern_check = [
|
||
# lambda i: 0.5 * (i[-1] - i[-2] - i[0] != 1),
|
||
# 1,
|
||
# lambda i: i[0] - 1,
|
||
# lambda i: i[-2] - 1,
|
||
# ]
|
||
pattern_check = [
|
||
lambda i: 0.999 * (i[-1] - i[-2] - i[0] - 1),
|
||
1,
|
||
lambda i: i[0] - 1,
|
||
lambda i: i[-2] - 1,
|
||
]
|
||
pattern_list.append(
|
||
Pattern(
|
||
name,
|
||
functions.flip_A(A),
|
||
b_r[::-1],
|
||
pattern_check,
|
||
vert_coords,
|
||
edge_idxs,
|
||
face_idxs,
|
||
(split_vert_idxs[0],) + split_vert_idxs[:0:-1],
|
||
additional_edge_flow_info,
|
||
)
|
||
)
|
||
|
||
# 4-3
|
||
name = "4-3"
|
||
A = (
|
||
(0, 1, 0, 1, 2, 1),
|
||
(1, 0, 1, 0, 0, 0),
|
||
(0, 1, 0, 1, 0, 1),
|
||
(1, 0, 1, 0, 0, 0),
|
||
)
|
||
b_r = (3, 1, 1, 1)
|
||
pattern_check = [lambda i: (i[0] - i[2] - 2) / 2, 1, lambda i: i[2] - 1, 1]
|
||
vert_coords = [
|
||
(1.0, 1.0, 0.0),
|
||
(-1.0, 1.0, 0.0),
|
||
(1.0, -1.0, 0.0),
|
||
(-1.0, -1.0, 0.0),
|
||
(-0.3333333134651184, -1.0, 0.0),
|
||
(0.3333333134651184, -1.0, 0.0),
|
||
(-0.3333333134651184, 0.0, 0.0),
|
||
(0.3333333134651184, 0.0, 0.0),
|
||
]
|
||
edge_idxs = [
|
||
(5, 2),
|
||
(1, 3),
|
||
(0, 1),
|
||
(2, 0),
|
||
(3, 4),
|
||
(4, 5),
|
||
(6, 7),
|
||
(4, 6),
|
||
(5, 7),
|
||
(0, 7),
|
||
(1, 6),
|
||
]
|
||
face_idxs = [[5, 7, 6, 4], [2, 0, 7, 5], [0, 1, 6, 7], [3, 4, 6, 1]]
|
||
split_vert_idxs = (3, 2, 0, 1)
|
||
additional_edge_flow_info = {"x": 10, "y": 6}
|
||
pattern_list.append(
|
||
Pattern(
|
||
name,
|
||
A,
|
||
b_r,
|
||
pattern_check,
|
||
vert_coords,
|
||
edge_idxs,
|
||
face_idxs,
|
||
split_vert_idxs,
|
||
additional_edge_flow_info,
|
||
)
|
||
)
|
||
|
||
|
||
# 4-4
|
||
name = "4-4"
|
||
A = (
|
||
(0, 1, 0, 1, 2, 1),
|
||
(1, 0, 1, 0, 0, 1),
|
||
(0, 1, 0, 1, 0, 0),
|
||
(1, 0, 1, 0, 0, 0),
|
||
)
|
||
b_r = (4, 2, 1, 1)
|
||
pattern_check = [lambda i: (i[0] - i[1] - 2) / 2, lambda i: i[1] - 2, 1, 1]
|
||
vert_coords = [
|
||
(-0.5, 0.0, 0.0),
|
||
(0.5, -0.5, 0.0),
|
||
(0.0, 0.0, 0.0),
|
||
(0.5, -1.0, 0.0),
|
||
(0.0, -1.0, 0.0),
|
||
(-0.5, -1.0, 0.0),
|
||
(1.0, 1.0, 0.0),
|
||
(-1.0, 1.0, 0.0),
|
||
(1.0, -1.0, 0.0),
|
||
(-1.0, -1.0, 0.0),
|
||
(1.0, 0.0, 0.0),
|
||
]
|
||
edge_idxs = [
|
||
(3, 8),
|
||
(4, 3),
|
||
(2, 4),
|
||
(0, 2),
|
||
(10, 6),
|
||
(5, 4),
|
||
(9, 5),
|
||
(0, 7),
|
||
(0, 5),
|
||
(1, 10),
|
||
(2, 6),
|
||
(7, 9),
|
||
(6, 7),
|
||
(1, 2),
|
||
(1, 3),
|
||
(8, 10),
|
||
]
|
||
face_idxs = [
|
||
[3, 1, 10, 8],
|
||
[6, 10, 1, 2],
|
||
[4, 5, 0, 2],
|
||
[4, 2, 1, 3],
|
||
[0, 7, 6, 2],
|
||
[9, 7, 0, 5],
|
||
]
|
||
split_vert_idxs = (9, 8, 6, 7)
|
||
additional_edge_flow_info = {"x": 7, "y": 13}
|
||
pattern_list.append(
|
||
Pattern(
|
||
name,
|
||
A,
|
||
b_r,
|
||
pattern_check,
|
||
vert_coords,
|
||
edge_idxs,
|
||
face_idxs,
|
||
split_vert_idxs,
|
||
additional_edge_flow_info,
|
||
)
|
||
)
|
||
|
||
name = "4-4-i"
|
||
pattern_check = [1, 1, lambda i: i[-2] - 2, lambda i: (i[-1] - i[-2] - 2) / 2]
|
||
pattern_list.append(
|
||
Pattern(
|
||
name,
|
||
functions.flip_A(A),
|
||
b_r[::-1],
|
||
pattern_check,
|
||
vert_coords,
|
||
edge_idxs,
|
||
face_idxs,
|
||
(split_vert_idxs[0],) + split_vert_idxs[:0:-1],
|
||
additional_edge_flow_info,
|
||
)
|
||
)
|
||
|
||
# # 4-circ
|
||
# name = "4-circ"
|
||
# A = (
|
||
# (0, 1, 0, 1, 0),
|
||
# (1, 0, 1, 0, 0),
|
||
# (0, 1, 0, 1, 0),
|
||
# (1, 0, 1, 0, 0),
|
||
# )
|
||
# b_r = (1, 1, 1, 1)
|
||
# pattern_check = (1, 1, 1, 1)
|
||
# vert_coords = [
|
||
# (-1.0, -1.0, 0.0),
|
||
# (1.0, -1.0, 0.0),
|
||
# (-1.0, 1.0, 0.0),
|
||
# (1.0, 1.0, 0.0),
|
||
# (-0.5, -0.5, 0.0),
|
||
# (0.5, -0.5, 0.0),
|
||
# (-0.5, 0.5, 0.0),
|
||
# (0.5, 0.5, 0.0),
|
||
# ]
|
||
# edge_idxs = [
|
||
# (2, 0),
|
||
# (0, 1),
|
||
# (1, 3),
|
||
# (3, 2),
|
||
# (6, 4),
|
||
# (4, 5),
|
||
# (5, 7),
|
||
# (7, 6),
|
||
# (0, 4),
|
||
# (6, 2),
|
||
# (7, 3),
|
||
# (1, 5),
|
||
# ]
|
||
# face_idxs = [
|
||
# [0, 2, 3, 1],
|
||
# [4, 5, 7, 6],
|
||
# [2, 0, 4, 6],
|
||
# [3, 2, 6, 7],
|
||
# [0, 1, 5, 4],
|
||
# [1, 3, 7, 5],
|
||
# ]
|
||
# split_vert_idxs = (0, 1, 3, 2)
|
||
# additional_edge_flow_info = {"x": 8}
|
||
# pattern_list.append(
|
||
# Pattern(
|
||
# name,
|
||
# A,
|
||
# b_r,
|
||
# pattern_check,
|
||
# vert_coords,
|
||
# edge_idxs,
|
||
# face_idxs,
|
||
# split_vert_idxs,
|
||
# additional_edge_flow_info,
|
||
# )
|
||
# )
|
||
|
||
|
||
# 5-0
|
||
name = "5-0"
|
||
A = (
|
||
(0, 1, 0, 0, 1),
|
||
(1, 0, 1, 0, 0),
|
||
(0, 1, 0, 1, 0),
|
||
(0, 0, 1, 0, 1),
|
||
(1, 0, 0, 1, 0),
|
||
)
|
||
b_r = (2, 1, 1, 1, 1)
|
||
pattern_check = [2, 1, 1, 1, 1]
|
||
vert_coords = [
|
||
(0.0, 1.0, 0.0),
|
||
(-0.9510565400123596, 0.30901700258255005, 0.0),
|
||
(-0.5877852439880371, -0.80901700258255, 0.0),
|
||
(0.5877852439880371, -0.80901700258255, 0.0),
|
||
(0.9510565400123596, 0.30901700258255005, 0.0),
|
||
(0.0, -0.80901700258255, 0.0),
|
||
]
|
||
edge_idxs = [(1, 0), (2, 1), (5, 2), (4, 3), (0, 4), (3, 5), (0, 5)]
|
||
face_idxs = [[1, 2, 5, 0], [4, 0, 5, 3]]
|
||
split_vert_idxs = (2, 3, 4, 0, 1)
|
||
additional_edge_flow_info = {}
|
||
pattern_list.append(
|
||
Pattern(
|
||
name,
|
||
A,
|
||
b_r,
|
||
pattern_check,
|
||
vert_coords,
|
||
edge_idxs,
|
||
face_idxs,
|
||
split_vert_idxs,
|
||
additional_edge_flow_info,
|
||
)
|
||
)
|
||
|
||
# 5-1
|
||
name = "5-1"
|
||
A = (
|
||
(0, 1, 0, 0, 1, 1),
|
||
(1, 0, 1, 0, 0, 1),
|
||
(0, 1, 0, 1, 0, 0),
|
||
(0, 0, 1, 0, 1, 0),
|
||
(1, 0, 0, 1, 0, 0),
|
||
)
|
||
b_r = (2, 1, 1, 1, 1)
|
||
# pattern_check = [lambda i: i[1] - 1, lambda i: 0.5 * (i[0] - i[1] != 1), 1, 1, 1]
|
||
pattern_check = [lambda i: i[1] - 1, lambda i: 0.999 * (i[0] - i[1] - 1), 1, 1, 1]
|
||
vert_coords = [
|
||
(0.0, -0.80901700258255, 0.0),
|
||
(0.9510565400123596, 0.30901700258255005, 0.0),
|
||
(0.5877852439880371, -0.80901700258255, 0.0),
|
||
(-0.5877852439880371, -0.80901700258255, 0.0),
|
||
(-0.9510565400123596, 0.30901700258255005, 0.0),
|
||
(0.0, 1.0, 0.0),
|
||
]
|
||
edge_idxs = [(1, 3), (1, 2), (0, 3), (3, 4), (2, 0), (4, 5), (5, 1)]
|
||
face_idxs = [[5, 4, 3, 1], [0, 2, 1, 3]]
|
||
split_vert_idxs = (3, 2, 1, 5, 4)
|
||
additional_edge_flow_info = {"x": 2}
|
||
pattern_list.append(
|
||
Pattern(
|
||
name,
|
||
A,
|
||
b_r,
|
||
pattern_check,
|
||
vert_coords,
|
||
edge_idxs,
|
||
face_idxs,
|
||
split_vert_idxs,
|
||
additional_edge_flow_info,
|
||
)
|
||
)
|
||
name = "5-1-i"
|
||
# pattern_check = [1, 1, 1, lambda i: 0.5 * (i[-1] - i[-2] != 1), lambda i: i[-2] - 1]
|
||
pattern_check = [1, 1, 1, lambda i: 0.999 * (i[-1] - i[-2] - 1), lambda i: i[-2] - 1]
|
||
pattern_list.append(
|
||
Pattern(
|
||
name,
|
||
functions.flip_A(A),
|
||
b_r[::-1],
|
||
pattern_check,
|
||
vert_coords,
|
||
edge_idxs,
|
||
face_idxs,
|
||
(split_vert_idxs[0],) + split_vert_idxs[:0:-1],
|
||
additional_edge_flow_info,
|
||
)
|
||
)
|
||
|
||
# 5-2
|
||
name = "5-2"
|
||
A = (
|
||
(0, 1, 0, 0, 1, 2),
|
||
(1, 0, 1, 0, 0, 0),
|
||
(0, 1, 0, 1, 0, 0),
|
||
(0, 0, 1, 0, 1, 0),
|
||
(1, 0, 0, 1, 0, 0),
|
||
)
|
||
b_r = (4, 1, 1, 1, 1)
|
||
pattern_check = (lambda i: (i[0] - 4) / 2, 1, 1, 1, 1)
|
||
vert_coords = [
|
||
(0.29389262199401855, -0.80901700258255, 0.0),
|
||
(0.9510565400123596, 0.30901700258255005, 0.0),
|
||
(0.5877852439880371, -0.80901700258255, 0.0),
|
||
(-0.5877852439880371, -0.80901700258255, 0.0),
|
||
(-0.9510565400123596, 0.30901700258255005, 0.0),
|
||
(0.0, 1.0, 0.0),
|
||
(0.0, -0.80901700258255, 0.0),
|
||
(-0.29389262199401855, -0.80901700258255, 0.0),
|
||
(0.0, 0.0, 0.0),
|
||
(0.0, -0.404508501291275, 0.0),
|
||
]
|
||
edge_idxs = [
|
||
(7, 3),
|
||
(5, 1),
|
||
(0, 6),
|
||
(3, 4),
|
||
(2, 0),
|
||
(4, 5),
|
||
(1, 2),
|
||
(6, 7),
|
||
(7, 9),
|
||
(0, 9),
|
||
(8, 9),
|
||
(3, 8),
|
||
(2, 8),
|
||
(5, 8),
|
||
]
|
||
face_idxs = [[7, 9, 8, 3], [0, 2, 8, 9], [6, 0, 9, 7], [1, 5, 8, 2], [4, 3, 8, 5]]
|
||
split_vert_idxs = (3, 2, 1, 5, 4)
|
||
additional_edge_flow_info = {"x": 10}
|
||
pattern_list.append(
|
||
Pattern(
|
||
name,
|
||
A,
|
||
b_r,
|
||
pattern_check,
|
||
vert_coords,
|
||
edge_idxs,
|
||
face_idxs,
|
||
split_vert_idxs,
|
||
additional_edge_flow_info,
|
||
)
|
||
)
|
||
|
||
# 5-3
|
||
name = "5-3"
|
||
A = (
|
||
(0, 1, 0, 0, 1, 2, 1),
|
||
(1, 0, 1, 0, 0, 0, 1),
|
||
(0, 1, 0, 1, 0, 0, 0),
|
||
(0, 0, 1, 0, 1, 0, 0),
|
||
(1, 0, 0, 1, 0, 0, 0),
|
||
)
|
||
b_r = (5, 2, 1, 1, 1)
|
||
pattern_check = [lambda i: (i[0] - i[1] - 3) / 2, lambda i: i[1] - 2, 1, 1, 1]
|
||
vert_coords = [
|
||
(-0.5089906454086304, 0.0, 0.0),
|
||
(-0.35267114639282227, -0.80901700258255, 0.0),
|
||
(-0.11755704879760742, -0.80901700258255, 0.0),
|
||
(0.11755704879760742, -0.80901700258255, 0.0),
|
||
(0.35267114639282227, -0.80901700258255, 0.0),
|
||
(0.9510565400123596, 0.30901700258255005, 0.0),
|
||
(0.5877852439880371, -0.80901700258255, 0.0),
|
||
(-0.5877852439880371, -0.80901700258255, 0.0),
|
||
(-0.9510565400123596, 0.30901700258255005, 0.0),
|
||
(0.0, 1.0, 0.0),
|
||
(-0.22425960004329681, 0.34856167435646057, 0.0),
|
||
(0.08892543613910675, 0.0, 0.0),
|
||
(0.31710362434387207, -0.24705025553703308, 0.0),
|
||
(0.769420862197876, -0.25, 0.0),
|
||
]
|
||
edge_idxs = [
|
||
(3, 2),
|
||
(10, 0),
|
||
(4, 3),
|
||
(9, 5),
|
||
(11, 10),
|
||
(1, 7),
|
||
(7, 8),
|
||
(0, 1),
|
||
(8, 9),
|
||
(6, 4),
|
||
(2, 1),
|
||
(13, 6),
|
||
(2, 10),
|
||
(3, 11),
|
||
(12, 4),
|
||
(12, 11),
|
||
(5, 13),
|
||
(13, 12),
|
||
(11, 5),
|
||
(9, 10),
|
||
(0, 8),
|
||
]
|
||
face_idxs = [
|
||
[10, 2, 1, 0],
|
||
[10, 11, 3, 2],
|
||
[11, 12, 4, 3],
|
||
[4, 12, 13, 6],
|
||
[12, 11, 5, 13],
|
||
[9, 5, 11, 10],
|
||
[10, 0, 8, 9],
|
||
[1, 7, 8, 0],
|
||
]
|
||
split_vert_idxs = (7, 6, 5, 9, 8)
|
||
additional_edge_flow_info = {"x": 20, "y": 15}
|
||
pattern_list.append(
|
||
Pattern(
|
||
name,
|
||
A,
|
||
b_r,
|
||
pattern_check,
|
||
vert_coords,
|
||
edge_idxs,
|
||
face_idxs,
|
||
split_vert_idxs,
|
||
additional_edge_flow_info,
|
||
)
|
||
)
|
||
|
||
name = "5-3-i"
|
||
pattern_check = [1, 1, 1, lambda i: i[-2] - 2, lambda i: (i[-1] - i[-2] - 3) / 2]
|
||
pattern_list.append(
|
||
Pattern(
|
||
name,
|
||
functions.flip_A(A),
|
||
b_r[::-1],
|
||
pattern_check,
|
||
vert_coords,
|
||
edge_idxs,
|
||
face_idxs,
|
||
(split_vert_idxs[0],) + split_vert_idxs[:0:-1],
|
||
additional_edge_flow_info,
|
||
)
|
||
)
|
||
|
||
|
||
# 6-0
|
||
name = "6-0"
|
||
A = (
|
||
(0, 1, 0, 0, 0, 1, 1),
|
||
(1, 0, 1, 0, 0, 0, 0),
|
||
(0, 1, 0, 1, 0, 0, 0),
|
||
(0, 0, 1, 0, 1, 0, 1),
|
||
(0, 0, 0, 1, 0, 1, 0),
|
||
(1, 0, 0, 0, 1, 0, 0),
|
||
)
|
||
b_r = (1, 1, 1, 1, 1, 1)
|
||
# pattern_check = [lambda i: i[0] - 1, 1, 1, lambda i: 0.5 * (i[0] != i[3]), 1, 1]
|
||
pattern_check = [lambda i: i[0] - 1, 1, 1, lambda i: 0.999 * (i[0] - i[3]), 1, 1]
|
||
vert_coords = [
|
||
(1.0, 0.0, 0.0),
|
||
(0.5000000596046448, 0.8660253882408142, 0.0),
|
||
(-0.4999999701976776, 0.866025447845459, 0.0),
|
||
(-1.0, 0.0, 0.0),
|
||
(-0.5000000596046448, -0.8660253882408142, 0.0),
|
||
(0.4999999701976776, -0.866025447845459, 0.0),
|
||
]
|
||
edge_idxs = [(1, 0), (2, 1), (3, 2), (4, 3), (5, 4), (0, 5), (3, 0)]
|
||
face_idxs = [[4, 5, 0, 3], [1, 2, 3, 0]]
|
||
split_vert_idxs = (4, 5, 0, 1, 2, 3)
|
||
additional_edge_flow_info = {"x": 6}
|
||
pattern_list.append(
|
||
Pattern(
|
||
name,
|
||
A,
|
||
b_r,
|
||
pattern_check,
|
||
vert_coords,
|
||
edge_idxs,
|
||
face_idxs,
|
||
split_vert_idxs,
|
||
additional_edge_flow_info,
|
||
)
|
||
)
|
||
|
||
# 6-1
|
||
name = "6-1"
|
||
A = (
|
||
(0, 1, 0, 0, 0, 1, 1),
|
||
(1, 0, 1, 0, 0, 0, 1),
|
||
(0, 1, 0, 1, 0, 0, 0),
|
||
(0, 0, 1, 0, 1, 0, 0),
|
||
(0, 0, 0, 1, 0, 1, 0),
|
||
(1, 0, 0, 0, 1, 0, 0),
|
||
)
|
||
b_r = (2, 2, 1, 1, 1, 1)
|
||
# pattern_check = [lambda i: i[0] - 2, lambda i: 0.5 * (i[0] != i[1]), 1, 1, 1, 1]
|
||
pattern_check = [lambda i: i[0] - 2, lambda i: 0.999 * (i[0] - i[1]), 1, 1, 1, 1]
|
||
vert_coords = [
|
||
(0.4999999701976776, -0.866025447845459, 0.0),
|
||
(-0.5000000596046448, -0.8660253882408142, 0.0),
|
||
(-1.0, 0.0, 0.0),
|
||
(-0.4999999701976776, 0.866025447845459, 0.0),
|
||
(0.5000000596046448, 0.8660253882408142, 0.0),
|
||
(1.0, 0.0, 0.0),
|
||
(0.0, -9.934107758624577e-09, 0.0),
|
||
(0.25, -0.4330127239227295, 0.0),
|
||
(0.75, -0.4330127239227295, 0.0),
|
||
(-2.9802322387695312e-08, -0.866025447845459, 0.0),
|
||
]
|
||
edge_idxs = [
|
||
(1, 2),
|
||
(2, 3),
|
||
(3, 4),
|
||
(4, 5),
|
||
(8, 0),
|
||
(9, 1),
|
||
(6, 7),
|
||
(7, 8),
|
||
(7, 9),
|
||
(5, 8),
|
||
(0, 9),
|
||
(1, 6),
|
||
(5, 6),
|
||
(3, 6),
|
||
]
|
||
face_idxs = [[9, 7, 6, 1], [8, 7, 9, 0], [7, 8, 5, 6], [4, 3, 6, 5], [2, 1, 6, 3]]
|
||
split_vert_idxs = (1, 0, 5, 4, 3, 2)
|
||
additional_edge_flow_info = {"x": 6}
|
||
pattern_list.append(
|
||
Pattern(
|
||
name,
|
||
A,
|
||
b_r,
|
||
pattern_check,
|
||
vert_coords,
|
||
edge_idxs,
|
||
face_idxs,
|
||
split_vert_idxs,
|
||
additional_edge_flow_info,
|
||
)
|
||
)
|
||
|
||
|
||
# 6-2
|
||
name = "6-2"
|
||
A = (
|
||
(0, 1, 0, 0, 0, 1, 2, 1),
|
||
(1, 0, 1, 0, 0, 0, 0, 0),
|
||
(0, 1, 0, 1, 0, 0, 0, 0),
|
||
(0, 0, 1, 0, 1, 0, 0, 1),
|
||
(0, 0, 0, 1, 0, 1, 0, 0),
|
||
(1, 0, 0, 0, 1, 0, 0, 0),
|
||
)
|
||
b_r = (3, 1, 1, 1, 1, 1)
|
||
pattern_check = [lambda i: i[3] - 1, 1, 1, lambda i: (i[0] - i[3] - 2) / 2, 1, 1]
|
||
vert_coords = [
|
||
(0.16666662693023682, -0.38941529393196106, 0.0),
|
||
(-0.16666671633720398, -0.38941529393196106, 0.0),
|
||
(-0.16666671633720398, -0.866025447845459, 0.0),
|
||
(0.16666662693023682, -0.866025447845459, 0.0),
|
||
(0.4999999701976776, -0.866025447845459, 0.0),
|
||
(-0.5000000596046448, -0.8660253882408142, 0.0),
|
||
(-1.0, 0.0, 0.0),
|
||
(-0.4999999701976776, 0.866025447845459, 0.0),
|
||
(0.5000000596046448, 0.8660253882408142, 0.0),
|
||
(1.0, 0.0, 0.0),
|
||
(0.28053152561187744, 0.0, 0.0),
|
||
(-0.2805315852165222, 0.0, 0.0),
|
||
]
|
||
edge_idxs = [
|
||
(11, 1),
|
||
(0, 1),
|
||
(3, 2),
|
||
(9, 4),
|
||
(0, 3),
|
||
(5, 11),
|
||
(6, 7),
|
||
(7, 8),
|
||
(8, 9),
|
||
(2, 5),
|
||
(1, 2),
|
||
(10, 11),
|
||
(5, 6),
|
||
(4, 3),
|
||
(10, 0),
|
||
(10, 4),
|
||
(8, 10),
|
||
(7, 11),
|
||
]
|
||
face_idxs = [
|
||
[3, 0, 10, 4],
|
||
[4, 10, 8, 9],
|
||
[5, 11, 1, 2],
|
||
[1, 0, 3, 2],
|
||
[1, 11, 10, 0],
|
||
[7, 8, 10, 11],
|
||
[7, 11, 5, 6],
|
||
]
|
||
split_vert_idxs = (5, 4, 9, 8, 7, 6)
|
||
additional_edge_flow_info = {"x": 0, "y": 1}
|
||
pattern_list.append(
|
||
Pattern(
|
||
name,
|
||
A,
|
||
b_r,
|
||
pattern_check,
|
||
vert_coords,
|
||
edge_idxs,
|
||
face_idxs,
|
||
split_vert_idxs,
|
||
additional_edge_flow_info,
|
||
)
|
||
)
|
||
|
||
|
||
# 6-3
|
||
name = "6-3"
|
||
A = (
|
||
(0, 1, 0, 0, 0, 1, 2, 1),
|
||
(1, 0, 1, 0, 0, 0, 0, 1),
|
||
(0, 1, 0, 1, 0, 0, 0, 0),
|
||
(0, 0, 1, 0, 1, 0, 0, 0),
|
||
(0, 0, 0, 1, 0, 1, 0, 0),
|
||
(1, 0, 0, 0, 1, 0, 0, 0),
|
||
)
|
||
b_r = (4, 2, 1, 1, 1, 1)
|
||
pattern_check = [lambda i: i[1] - 2, lambda i: (i[0] - i[1] - 2) / 2, 1, 1, 1, 1]
|
||
vert_coords = [
|
||
(0.75, -0.4330127239227295, 0.0),
|
||
(-2.9802322387695312e-08, -0.0053040385246276855, 0.0),
|
||
(-0.2500000298023224, -0.0053040385246276855, 0.0),
|
||
(-0.2500000298023224, -0.866025447845459, 0.0),
|
||
(-2.9802322387695312e-08, -0.866025447845459, 0.0),
|
||
(0.2499999701976776, -0.866025447845459, 0.0),
|
||
(0.4999999701976776, -0.866025447845459, 0.0),
|
||
(-0.5000000596046448, -0.8660253882408142, 0.0),
|
||
(-1.0, 0.0, 0.0),
|
||
(-0.4999999701976776, 0.866025447845459, 0.0),
|
||
(0.5000000596046448, 0.8660253882408142, 0.0),
|
||
(1.0, 0.0, 0.0),
|
||
(0.43703240156173706, -0.4330127239227295, 0.0),
|
||
(-2.9802322387695312e-08, 0.43600431084632874, 0.0),
|
||
(-0.2500000298023224, 0.43600431084632874, 0.0),
|
||
]
|
||
edge_idxs = [
|
||
(12, 5),
|
||
(2, 3),
|
||
(1, 2),
|
||
(1, 11),
|
||
(5, 4),
|
||
(0, 6),
|
||
(3, 7),
|
||
(8, 9),
|
||
(1, 4),
|
||
(12, 1),
|
||
(10, 11),
|
||
(6, 5),
|
||
(11, 0),
|
||
(12, 0),
|
||
(4, 3),
|
||
(9, 10),
|
||
(7, 8),
|
||
(14, 13),
|
||
(13, 1),
|
||
(13, 10),
|
||
(9, 14),
|
||
(2, 14),
|
||
(8, 2),
|
||
]
|
||
face_idxs = [
|
||
[6, 0, 12, 5],
|
||
[11, 1, 12, 0],
|
||
[3, 4, 1, 2],
|
||
[5, 12, 1, 4],
|
||
[11, 10, 13, 1],
|
||
[13, 10, 9, 14],
|
||
[1, 13, 14, 2],
|
||
[9, 8, 2, 14],
|
||
[7, 3, 2, 8],
|
||
]
|
||
split_vert_idxs = (7, 6, 11, 10, 9, 8)
|
||
additional_edge_flow_info = {"x": 22, "y": 9}
|
||
pattern_list.append(
|
||
Pattern(
|
||
name,
|
||
A,
|
||
b_r,
|
||
pattern_check,
|
||
vert_coords,
|
||
edge_idxs,
|
||
face_idxs,
|
||
split_vert_idxs,
|
||
additional_edge_flow_info,
|
||
)
|
||
)
|
||
|
||
name = "6-3-i"
|
||
pattern_check = [1, 1, 1, 1, lambda i: (i[-1] - i[-2] - 2) / 2, lambda i: i[-2] - 2]
|
||
pattern_list.append(
|
||
Pattern(
|
||
name,
|
||
functions.flip_A(A),
|
||
b_r[::-1],
|
||
pattern_check,
|
||
vert_coords,
|
||
edge_idxs,
|
||
face_idxs,
|
||
(split_vert_idxs[0],) + split_vert_idxs[:0:-1],
|
||
additional_edge_flow_info,
|
||
)
|
||
)
|