510 lines
21 KiB
Plaintext
510 lines
21 KiB
Plaintext
|
{
|
||
|
"cells": [
|
||
|
{
|
||
|
"cell_type": "markdown",
|
||
|
"metadata": {},
|
||
|
"source": [
|
||
|
"# Interactive Design Tool for Asymptotic Grid-Shells "
|
||
|
]
|
||
|
},
|
||
|
{
|
||
|
"cell_type": "code",
|
||
|
"execution_count": 1,
|
||
|
"metadata": {},
|
||
|
"outputs": [],
|
||
|
"source": [
|
||
|
"import igl\n",
|
||
|
"import pyvista as pv\n",
|
||
|
"import numpy as np\n",
|
||
|
"\n",
|
||
|
"import sys\n",
|
||
|
"sys.path.append('../src')\n",
|
||
|
"\n",
|
||
|
"import importlib, fabrication_helper, tracer_tool\n",
|
||
|
"importlib.reload(fabrication_helper)\n",
|
||
|
"importlib.reload(tracer_tool)\n",
|
||
|
"from tracer_tool import AsymptoticTracer\n",
|
||
|
"from fabrication_helper import FabricationHelper"
|
||
|
]
|
||
|
},
|
||
|
{
|
||
|
"cell_type": "markdown",
|
||
|
"metadata": {},
|
||
|
"source": [
|
||
|
"### Load Mesh\n",
|
||
|
"Import your own mesh as an .obj.\n",
|
||
|
"<br>Note that the filename should not contain the file extension because it will be used as the basis for saving further data. "
|
||
|
]
|
||
|
},
|
||
|
{
|
||
|
"cell_type": "code",
|
||
|
"execution_count": 2,
|
||
|
"metadata": {},
|
||
|
"outputs": [],
|
||
|
"source": [
|
||
|
"filename = \"../data/final\""
|
||
|
]
|
||
|
},
|
||
|
{
|
||
|
"cell_type": "markdown",
|
||
|
"metadata": {},
|
||
|
"source": [
|
||
|
"### Initialize Interface\n",
|
||
|
"Don't modify this part. All parameters can be tuned with the interface."
|
||
|
]
|
||
|
},
|
||
|
{
|
||
|
"cell_type": "code",
|
||
|
"execution_count": null,
|
||
|
"metadata": {},
|
||
|
"outputs": [
|
||
|
{
|
||
|
"name": "stdout",
|
||
|
"output_type": "stream",
|
||
|
"text": [
|
||
|
"Hit Boundary\n",
|
||
|
"Duplicate Point\n",
|
||
|
"Hit Boundary\n",
|
||
|
"Hit Boundary\n",
|
||
|
"Hit Boundary\n",
|
||
|
"Hit Boundary\n",
|
||
|
"Hit Boundary\n",
|
||
|
"Hit Boundary\n",
|
||
|
"Duplicate Point\n",
|
||
|
"Hit Boundary\n",
|
||
|
"Hit Boundary\n",
|
||
|
"Hit Boundary\n",
|
||
|
"Hit Boundary\n",
|
||
|
"Hit Boundary\n",
|
||
|
"Hit Boundary\n",
|
||
|
"Hit Boundary\n",
|
||
|
"Hit Boundary\n",
|
||
|
"Hit Boundary\n",
|
||
|
"Hit Boundary\n",
|
||
|
"Hit Boundary\n",
|
||
|
"Duplicate Point\n",
|
||
|
"Hit Boundary\n",
|
||
|
"Hit Boundary\n",
|
||
|
"Hit Boundary\n",
|
||
|
"Hit Boundary\n",
|
||
|
"Hit Boundary\n",
|
||
|
"Hit Boundary\n",
|
||
|
"Hit Boundary\n",
|
||
|
"Hit Boundary\n",
|
||
|
"Hit Boundary\n",
|
||
|
"Hit Boundary\n"
|
||
|
]
|
||
|
}
|
||
|
],
|
||
|
"source": [
|
||
|
"# Fabrication parameters in cm\n",
|
||
|
"strips_scale = 3\n",
|
||
|
"strips_width = 2\n",
|
||
|
"strips_spacing = 0.2\n",
|
||
|
"strips_thickness = 0.3\n",
|
||
|
"board_width = 60\n",
|
||
|
"board_length = 100\n",
|
||
|
"# Creation parameters\n",
|
||
|
"sampling_distance = 1.0\n",
|
||
|
"num_neighbors = 4\n",
|
||
|
"iter_sampling = False\n",
|
||
|
"# Visualisation\n",
|
||
|
"strips_actor = []\n",
|
||
|
"points_actor = []\n",
|
||
|
"labels_actor = []\n",
|
||
|
"samples_actor = {}\n",
|
||
|
"pathA_actor = {}\n",
|
||
|
"pathA_indexes = {}\n",
|
||
|
"pathB_actor = {}\n",
|
||
|
"pathB_indexes = {}\n",
|
||
|
"intersections = np.empty((0,3), float)\n",
|
||
|
"visual_scaling = 0.2\n",
|
||
|
"\n",
|
||
|
"# Initialise tracer\n",
|
||
|
"mesh = pv.read(filename + \".obj\")\n",
|
||
|
"v,f = igl.read_triangle_mesh(filename + \".obj\")\n",
|
||
|
"tracer = AsymptoticTracer(filename + \".obj\")\n",
|
||
|
"helper = FabricationHelper(strips_width, strips_thickness, strips_spacing, strips_scale)\n",
|
||
|
"\n",
|
||
|
"plot = pv.Plotter(notebook=0)\n",
|
||
|
"\n",
|
||
|
"def add_pathA(pid):\n",
|
||
|
" points, samples = tracer.generate_asymptotic_path(pid, True, num_neighbors, sampling_distance) \n",
|
||
|
"\n",
|
||
|
" if len(points)> 1:\n",
|
||
|
" pathA_actor[pid] = plot.add_mesh(pv.Spline(points, 400), color='white', line_width=10, pickable=False)\n",
|
||
|
" pathA_indexes[pid] = tracer.num_pathsA()-1\n",
|
||
|
" tracer.samples_indexes[0].append(pid)\n",
|
||
|
" return samples\n",
|
||
|
"\n",
|
||
|
"def add_pathB(pid):\n",
|
||
|
" points, samples = tracer.generate_asymptotic_path(pid, False, num_neighbors, sampling_distance) \n",
|
||
|
" if len(points)> 1:\n",
|
||
|
" pathB_actor[pid] = plot.add_mesh(pv.Spline(points, 400), color='yellow', line_width=10, pickable=False)\n",
|
||
|
" pathB_indexes[pid] = tracer.num_pathsB()-1\n",
|
||
|
" tracer.samples_indexes[1].append(pid) \n",
|
||
|
" return samples\n",
|
||
|
"\n",
|
||
|
"def remove_pathA(pid):\n",
|
||
|
" plot.remove_actor(pathA_actor[pid])\n",
|
||
|
" tracer.delete_path(pathA_indexes[pid], True)\n",
|
||
|
" del pathA_actor[pid]\n",
|
||
|
" #Update indexes\n",
|
||
|
" update_indexes(pid, True)\n",
|
||
|
"\n",
|
||
|
"def remove_pathB(pid):\n",
|
||
|
" plot.remove_actor(pathB_actor[pid])\n",
|
||
|
" tracer.delete_path(pathB_indexes[pid], False)\n",
|
||
|
" del pathB_actor[pid]\n",
|
||
|
" #Update indexes\n",
|
||
|
" update_indexes(pid, False)\n",
|
||
|
"\n",
|
||
|
"def add_or_delete_sample_point(pid):\n",
|
||
|
" orig = v[pid]\n",
|
||
|
"\n",
|
||
|
" if pid not in pathB_actor.keys() and pid not in pathA_actor.keys():\n",
|
||
|
" if pid in samples_actor.keys():\n",
|
||
|
" plot.remove_actor(samples_actor[pid])\n",
|
||
|
" del samples_actor[pid]\n",
|
||
|
" clean_intersections()\n",
|
||
|
" else:\n",
|
||
|
" if pid not in samples_actor.keys():\n",
|
||
|
" color = 'blue'\n",
|
||
|
" if tracer.flagA and not tracer.flagB:\n",
|
||
|
" color = 'white'\n",
|
||
|
" elif tracer.flagB and not tracer.flagA:\n",
|
||
|
" color = 'yellow'\n",
|
||
|
"\n",
|
||
|
" samples_actor[pid] = plot.add_points(np.array(orig), color=color, render_points_as_spheres=True, point_size=20.0, pickable=False)\n",
|
||
|
" clean_intersections()\n",
|
||
|
" else:\n",
|
||
|
" plot.remove_actor(samples_actor[pid])\n",
|
||
|
" color = 'blue'\n",
|
||
|
" if pid not in pathB_actor.keys() and pid in pathA_actor.keys():\n",
|
||
|
" color = 'white'\n",
|
||
|
" elif pid in pathB_actor.keys() and pid not in pathA_actor.keys():\n",
|
||
|
" color = 'yellow'\n",
|
||
|
" samples_actor[pid] = plot.add_points(np.array(orig), color=color, render_points_as_spheres=True, point_size=20.0, pickable=False)\n",
|
||
|
" clean_intersections()\n",
|
||
|
"\n",
|
||
|
"def update_indexes(path_index, first_principal_direction):\n",
|
||
|
" if first_principal_direction:\n",
|
||
|
" if path_index in pathA_indexes.keys():\n",
|
||
|
" del pathA_indexes[path_index]\n",
|
||
|
" idx = 0\n",
|
||
|
" for key in pathA_indexes:\n",
|
||
|
" pathA_indexes[key] = idx\n",
|
||
|
" idx+=1\n",
|
||
|
" else:\n",
|
||
|
" if path_index in pathB_indexes.keys():\n",
|
||
|
" del pathB_indexes[path_index]\n",
|
||
|
" idx = 0\n",
|
||
|
" for key in pathB_indexes:\n",
|
||
|
" pathB_indexes[key] = idx\n",
|
||
|
" idx+=1\n",
|
||
|
"\n",
|
||
|
"def callback_first_family(value):\n",
|
||
|
" tracer.flagA = value\n",
|
||
|
"\n",
|
||
|
"def callback_second_family(value):\n",
|
||
|
" tracer.flagB = value\n",
|
||
|
"\n",
|
||
|
"def clean_intersections():\n",
|
||
|
" if len(points_actor)>0:\n",
|
||
|
" callback_remove_labels()\n",
|
||
|
" plot.remove_actor(points_actor)\n",
|
||
|
" points_actor.clear()\n",
|
||
|
" labels_actor.clear()\n",
|
||
|
" tracer.flag_intersections = False\n",
|
||
|
"\n",
|
||
|
"def callback_intersection():\n",
|
||
|
" clean_intersections() \n",
|
||
|
" global intersections\n",
|
||
|
" intersections = np.empty((0,3), float)\n",
|
||
|
" intersections = np.append(intersections, tracer.generate_intersection_network(), axis=0)\n",
|
||
|
" if len(tracer.intersection_points)>0:\n",
|
||
|
" points_actor.append(plot.add_points(tracer.intersection_points, color='red',point_size=13.0, pickable=False)) \n",
|
||
|
"\n",
|
||
|
"def callback_flatten():\n",
|
||
|
" if not tracer.flag_intersections:\n",
|
||
|
" callback_intersection()\n",
|
||
|
" \n",
|
||
|
" helper.generate_flatten_network(tracer)\n",
|
||
|
" \n",
|
||
|
" strips_num = helper.strips_numA if helper.strips_numA > helper.strips_numB else helper.strips_numB\n",
|
||
|
" plot.remove_actor(strips_actor)\n",
|
||
|
" strips_actor.clear()\n",
|
||
|
" if strips_num:\n",
|
||
|
" for i in range(strips_num):\n",
|
||
|
" if i<helper.strips_numA:\n",
|
||
|
" points = helper.paths_flatten[0][i] * visual_scaling\n",
|
||
|
" strips_actor.append(plot.add_lines(lines_from_points(points), color='white', width=3))\n",
|
||
|
" if i<helper.strips_numB:\n",
|
||
|
" points = helper.paths_flatten[1][i] * visual_scaling\n",
|
||
|
" strips_actor.append(plot.add_lines(lines_from_points(points), color='yellow', width=3))\n",
|
||
|
" # Board boundary\n",
|
||
|
" points = np.array([[0.,0.,0.],[board_length*visual_scaling,0.,0.],[board_length*visual_scaling, board_width*visual_scaling,0.],[0., board_width*visual_scaling,0],[0.,0.,0.]])\n",
|
||
|
" strips_actor.append(plot.add_lines(lines_from_points(points), color='red', width=3))\n",
|
||
|
" \n",
|
||
|
"def callback_save_indexes():\n",
|
||
|
" file = open(filename + \"_indexes.txt\", 'w')\n",
|
||
|
" for i in range(len(tracer.samples_indexes)):\n",
|
||
|
" for idx in tracer.samples_indexes[i]:\n",
|
||
|
" if i==0: \n",
|
||
|
" file.write(\"A\"+str(idx))\n",
|
||
|
" elif i==1:\n",
|
||
|
" file.write(\"B\"+str(idx))\n",
|
||
|
" file.write('\\n')\n",
|
||
|
" file.close()\n",
|
||
|
"\n",
|
||
|
"def callback_load_indexes():\n",
|
||
|
" indexes = np.loadtxt(filename + \"_indexes.txt\", dtype=str)\n",
|
||
|
" old_flagA = tracer.flagA\n",
|
||
|
" old_flagB = tracer.flagB\n",
|
||
|
"\n",
|
||
|
" for data in indexes:\n",
|
||
|
" pid = int(data[1:])\n",
|
||
|
"\n",
|
||
|
" tracer.flagA = True if data[0] == \"A\" else False\n",
|
||
|
" tracer.flagB = True if data[0] == \"B\" else False\n",
|
||
|
"\n",
|
||
|
" callback_picking(mesh,pid)\n",
|
||
|
"\n",
|
||
|
" tracer.flagA = old_flagA\n",
|
||
|
" tracer.flagB = old_flagB\n",
|
||
|
"\n",
|
||
|
"def lines_from_points(points):\n",
|
||
|
" cells = np.empty((len(points)-1, 2), dtype=np.int_)\n",
|
||
|
" cells[:,0] = np.arange(0, len(points)-1, dtype=np.int_)\n",
|
||
|
" cells[:,1] = np.arange(1, len(points), dtype=np.int_)\n",
|
||
|
" cells = cells.flatten()\n",
|
||
|
" return np.array([points[i] for i in cells])\n",
|
||
|
"\n",
|
||
|
"def callback_picking(mesh, pid, iterative_sampling=None):\n",
|
||
|
"\n",
|
||
|
" if(iterative_sampling==None):\n",
|
||
|
" iterative_sampling = iter_sampling\n",
|
||
|
"\n",
|
||
|
" old_flagA = tracer.flagA\n",
|
||
|
" old_flagB = tracer.flagB\n",
|
||
|
"\n",
|
||
|
" # Generate first family of asymptotic curves\n",
|
||
|
" if tracer.flagA:\n",
|
||
|
" if pid in pathA_actor.keys():\n",
|
||
|
" remove_pathA(pid)\n",
|
||
|
" else:\n",
|
||
|
" samples = add_pathA(pid)\n",
|
||
|
"\n",
|
||
|
" if iterative_sampling:\n",
|
||
|
" for pt in samples:\n",
|
||
|
" idx = tracer.mesh.kd_tree.query(pt)[1]\n",
|
||
|
" tracer.flagA = False\n",
|
||
|
" tracer.flagB = True\n",
|
||
|
" callback_picking(mesh, idx, iterative_sampling=False)\n",
|
||
|
"\n",
|
||
|
" tracer.flagA = old_flagA\n",
|
||
|
" tracer.flagB = old_flagB\n",
|
||
|
"\n",
|
||
|
" # Generate second family of asymptotic curves\n",
|
||
|
" if tracer.flagB:\n",
|
||
|
" if pid in pathB_actor.keys():\n",
|
||
|
" remove_pathB(pid)\n",
|
||
|
" else:\n",
|
||
|
" samples = add_pathB(pid)\n",
|
||
|
"\n",
|
||
|
" if iterative_sampling:\n",
|
||
|
" for pt in samples:\n",
|
||
|
" idx = tracer.mesh.kd_tree.query(pt)[1]\n",
|
||
|
" tracer.flagA = True\n",
|
||
|
" tracer.flagB = False\n",
|
||
|
" callback_picking(mesh, idx, iterative_sampling=False)\n",
|
||
|
"\n",
|
||
|
" tracer.flagA = old_flagA\n",
|
||
|
" tracer.flagB = old_flagB\n",
|
||
|
" \n",
|
||
|
" add_or_delete_sample_point(pid)\n",
|
||
|
" \n",
|
||
|
"def callback_save_svg():\n",
|
||
|
" cutting_color = \"red\"\n",
|
||
|
" engraving_color = \"black\"\n",
|
||
|
" font_size = 0.4\n",
|
||
|
" if helper.flag_flatten==False:\n",
|
||
|
" helper.generate_flatten_network()\n",
|
||
|
" helper.generate_svg_file(filename + \"_cutting.svg\", font_size, cutting_color, engraving_color, board_length, board_width)\n",
|
||
|
"\n",
|
||
|
"def callback_width(value):\n",
|
||
|
" helper.strips_width = value\n",
|
||
|
" callback_flatten()\n",
|
||
|
"\n",
|
||
|
"def callback_board_width(value):\n",
|
||
|
" global board_width\n",
|
||
|
" board_width = value\n",
|
||
|
" callback_flatten()\n",
|
||
|
"\n",
|
||
|
"def callback_thickness(value):\n",
|
||
|
" helper.strips_thickness = value\n",
|
||
|
" callback_flatten()\n",
|
||
|
"\n",
|
||
|
"def callback_length(value):\n",
|
||
|
" helper.scale_length = value\n",
|
||
|
" callback_flatten()\n",
|
||
|
"\n",
|
||
|
"def callback_spacing(value):\n",
|
||
|
" helper.strips_spacing = value\n",
|
||
|
" callback_flatten()\n",
|
||
|
"\n",
|
||
|
"def callback_board_length(value):\n",
|
||
|
" global board_length\n",
|
||
|
" board_length = value\n",
|
||
|
" callback_flatten()\n",
|
||
|
"\n",
|
||
|
"def callback_remove_labels():\n",
|
||
|
" plot.remove_actor(labels_actor)\n",
|
||
|
" labels_actor.clear()\n",
|
||
|
"\n",
|
||
|
"def callback_add_all_labels():\n",
|
||
|
" callback_add_labels(True, True)\n",
|
||
|
"\n",
|
||
|
"def callback_add_labelsA():\n",
|
||
|
" callback_add_labels(True, False)\n",
|
||
|
"\n",
|
||
|
"def callback_add_labelsB():\n",
|
||
|
" callback_add_labels(False, True)\n",
|
||
|
" \n",
|
||
|
"def callback_add_labels(labelsA, labelsB):\n",
|
||
|
" callback_remove_labels()\n",
|
||
|
"\n",
|
||
|
" if len(tracer.paths_indexes[0])>0 and labelsA:\n",
|
||
|
" labels = np.core.defchararray.add('A', np.arange(len(tracer.paths_indexes[0])).astype(str))\n",
|
||
|
" indexes = [idx[:1][0] for idx in tracer.paths_indexes[0]]\n",
|
||
|
" labels_actor.append(plot.add_point_labels(tracer.paths[0][indexes], labels, font_size=22, always_visible=True, show_points=False))\n",
|
||
|
"\n",
|
||
|
" indexes = np.unique(np.array([item for sublist in tracer.intersections[0] for item in sublist[:,2]], int).flatten())\n",
|
||
|
" labels = np.core.defchararray.add('c', indexes.astype(str))\n",
|
||
|
" labels_actor.append(plot.add_point_labels(tracer.intersection_points[indexes], labels, bold=False, font_size=18, always_visible=True, show_points=False))\n",
|
||
|
"\n",
|
||
|
" if len(tracer.paths_indexes[1])>0 and labelsB:\n",
|
||
|
" labels = np.core.defchararray.add('B', np.arange(len(tracer.paths_indexes[1])).astype(str))\n",
|
||
|
" indexes = [idx[:1][0] for idx in tracer.paths_indexes[1]]\n",
|
||
|
" labels_actor.append(plot.add_point_labels(tracer.paths[1][indexes], labels, font_size=22, always_visible=True, show_points=False))\n",
|
||
|
"\n",
|
||
|
" indexes = np.unique(np.array([item for sublist in tracer.intersections[1] for item in sublist[:,2]], int).flatten())\n",
|
||
|
" labels = np.core.defchararray.add('c', indexes.astype(str))\n",
|
||
|
" labels_actor.append(plot.add_point_labels(tracer.intersection_points[indexes], labels, bold=False, font_size=18, always_visible=True, show_points=False))\n",
|
||
|
"\n",
|
||
|
"def callback_save_network():\n",
|
||
|
" file = open(filename + \"_rhino.txt\", 'w')\n",
|
||
|
" for i in range(2):\n",
|
||
|
" label = \"A\"\n",
|
||
|
" if i==1:\n",
|
||
|
" label =\"B\"\n",
|
||
|
"\n",
|
||
|
" # positions\n",
|
||
|
" for j in range(len(tracer.paths_indexes[i])):\n",
|
||
|
" path = tracer.paths_indexes[i][j]\n",
|
||
|
" for idx in path:\n",
|
||
|
" pt = tracer.paths[i][idx]\n",
|
||
|
" file.write(label + str(j)+ \"_\" +str(pt[0]) + \",\" + str(pt[1]) + \",\" +str(pt[2]) + \"\\n\")\n",
|
||
|
"\n",
|
||
|
" # Intersections \n",
|
||
|
" for i in range( len(tracer.intersection_points) ):\n",
|
||
|
" pt = tracer.intersection_points[i]\n",
|
||
|
" file.write(\"C\" + str(i) + \"_\" +str(pt[0]) + \",\" + str(pt[1]) + \",\" +str(pt[2]) + \"\\n\")\n",
|
||
|
" file.close()\n",
|
||
|
"\n",
|
||
|
"def callback_sampling_distance(value):\n",
|
||
|
" global sampling_distance\n",
|
||
|
" sampling_distance = value\n",
|
||
|
"\n",
|
||
|
"def callback_iterative_sampling(value):\n",
|
||
|
" global iter_sampling\n",
|
||
|
" iter_sampling = value\n",
|
||
|
"\n",
|
||
|
"plot.add_mesh(mesh, show_edges=True)\n",
|
||
|
"plot.add_axes()\n",
|
||
|
"msg = \"Press <K> for saving indexes, <L> for loading indexes or <O> to save the curve network model.\\n\"\n",
|
||
|
"msg += \"Press <I> for computing intersections, <J> for generating the flatten strips and <H> for saving the laser-cutting file.\\n\"\n",
|
||
|
"msg += \"Press <M> for hiding labels, <N> for showing all labels, <U> for showing A labels or <Y> for showing B labels.\\n\"\n",
|
||
|
"plot.add_text(msg, position='lower_right', font_size=12, color=None, font=None, shadow=False, name=None, viewport=False)\n",
|
||
|
"plot.add_checkbox_button_widget(callback_first_family, value=tracer.flagA, position=(10, 200.0), size=40, border_size=1, color_on='white', color_off='grey', background_color='red')\n",
|
||
|
"plot.add_checkbox_button_widget(callback_second_family, value=tracer.flagB, position=(10, 300.0), size=40, border_size=1, color_on='yellow', color_off='grey', background_color='red')\n",
|
||
|
"plot.add_checkbox_button_widget(callback_iterative_sampling, value=iter_sampling, position=(10, 400.0), size=40, border_size=1, color_on='green', color_off='grey', background_color='red')\n",
|
||
|
"plot.add_text(\"First Family\", position=(80.0, 200.0), font_size=12, color=None, font=None, shadow=False, name=None, viewport=False)\n",
|
||
|
"plot.add_text(\"Second Family\", position=(80, 300.0), font_size=12, color=None, font=None, shadow=False, name=None, viewport=False)\n",
|
||
|
"plot.add_text(\"Iterative sampling\", position=(80, 400.0), font_size=12, color=None, font=None, shadow=False, name=None, viewport=False)\n",
|
||
|
"plot.add_key_event('i', callback_intersection)\n",
|
||
|
"plot.add_key_event('j', callback_flatten)\n",
|
||
|
"plot.add_key_event('k', callback_save_indexes)\n",
|
||
|
"plot.add_key_event('l', callback_load_indexes)\n",
|
||
|
"plot.add_key_event('h', callback_save_svg)\n",
|
||
|
"plot.add_key_event('m', callback_remove_labels)\n",
|
||
|
"plot.add_key_event('n', callback_add_all_labels)\n",
|
||
|
"plot.add_key_event('u', callback_add_labelsA)\n",
|
||
|
"plot.add_key_event('y', callback_add_labelsB)\n",
|
||
|
"plot.add_key_event('o', callback_save_network)\n",
|
||
|
"plot.enable_point_picking(callback=callback_picking, show_message=True, color='pink', point_size=10, use_mesh=True, show_point=True)\n",
|
||
|
"plot.add_slider_widget(callback_width, [0.1, 5.0], value=strips_width, title=\"Strip Width (cm)\", pointa=(.83, .15), pointb=(.98, .15), title_height=0.02, fmt=\"%0.1f\", style='modern')\n",
|
||
|
"plot.add_slider_widget(callback_thickness, [0.1, 1], value=strips_thickness, title=\"Strip Thickness (cm)\", pointa=(.67, .15), pointb=(.82, .15), title_height=0.02, fmt=\"%0.2f\", style='modern')\n",
|
||
|
"plot.add_slider_widget(callback_length, [1, 10], value=strips_scale, title=\"Scale Strip Length\", pointa=(.51, .15), pointb=(.66, .15), title_height=0.02, fmt=\"%0.1f\", style='modern')\n",
|
||
|
"plot.add_slider_widget(callback_spacing, [0., 0.5], value=strips_spacing, title=\"Strip spacing\", pointa=(.51, .88), pointb=(.66, .88), title_height=0.02, fmt=\"%0.1f\", style='modern')\n",
|
||
|
"plot.add_slider_widget(callback_board_width, [10, 100], value=board_width, title=\"Board width (cm)\", pointa=(.67, .88), pointb=(.82, .88), title_height=0.02, fmt=\"%0.0f\", style='modern')\n",
|
||
|
"plot.add_slider_widget(callback_board_length, [10, 100], value=board_length, title=\"Board length (cm)\", pointa=(.83, .88), pointb=(.98, .88), title_height=0.02, fmt=\"%0.0f\", style='modern')\n",
|
||
|
"plot.add_slider_widget(callback_sampling_distance, [0.1, 2.0], value=sampling_distance, title=\"Sampling distance\", pointa=(.005, .88), pointb=(.16, .88), title_height=0.02, fmt=\"%0.1f\", style='modern')\n",
|
||
|
"plot.show(\"Asymptotic GridShell\")\n"
|
||
|
]
|
||
|
},
|
||
|
{
|
||
|
"cell_type": "code",
|
||
|
"execution_count": null,
|
||
|
"metadata": {},
|
||
|
"outputs": [],
|
||
|
"source": []
|
||
|
},
|
||
|
{
|
||
|
"cell_type": "code",
|
||
|
"execution_count": null,
|
||
|
"metadata": {},
|
||
|
"outputs": [],
|
||
|
"source": []
|
||
|
},
|
||
|
{
|
||
|
"cell_type": "code",
|
||
|
"execution_count": null,
|
||
|
"metadata": {},
|
||
|
"outputs": [],
|
||
|
"source": []
|
||
|
},
|
||
|
{
|
||
|
"cell_type": "code",
|
||
|
"execution_count": null,
|
||
|
"metadata": {},
|
||
|
"outputs": [],
|
||
|
"source": []
|
||
|
}
|
||
|
],
|
||
|
"metadata": {
|
||
|
"interpreter": {
|
||
|
"hash": "294c9a689e437aa1430c5ffd3595515046a5cee981399d48a2291c079c814bc8"
|
||
|
},
|
||
|
"kernelspec": {
|
||
|
"display_name": "Python 3 (ipykernel)",
|
||
|
"language": "python",
|
||
|
"name": "python3"
|
||
|
},
|
||
|
"language_info": {
|
||
|
"codemirror_mode": {
|
||
|
"name": "ipython",
|
||
|
"version": 3
|
||
|
},
|
||
|
"file_extension": ".py",
|
||
|
"mimetype": "text/x-python",
|
||
|
"name": "python",
|
||
|
"nbconvert_exporter": "python",
|
||
|
"pygments_lexer": "ipython3",
|
||
|
"version": "3.9.7"
|
||
|
}
|
||
|
},
|
||
|
"nbformat": 4,
|
||
|
"nbformat_minor": 4
|
||
|
}
|