Disabled external gits
This commit is contained in:
@@ -0,0 +1,457 @@
|
||||
{
|
||||
"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/Model01\""
|
||||
]
|
||||
},
|
||||
{
|
||||
"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": [],
|
||||
"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": []
|
||||
}
|
||||
],
|
||||
"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
|
||||
}
|
@@ -0,0 +1,171 @@
|
||||
{
|
||||
"cells": [
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 1,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"import numpy as np\n",
|
||||
"from meshplot import plot"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 2,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"import sys\n",
|
||||
"sys.path.append('../src')"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 3,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"import importlib, tracer_helper, tracer_utils\n",
|
||||
"importlib.reload(tracer_helper)\n",
|
||||
"importlib.reload(tracer_utils)\n",
|
||||
"from tracer_utils import asymptotic_path\n",
|
||||
"from tracer_helper import Mesh"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"# Example\n",
|
||||
"Build mesh from file"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 4,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"application/vnd.jupyter.widget-view+json": {
|
||||
"model_id": "f19ce42be2f6405796de381ba4b89b42",
|
||||
"version_major": 2,
|
||||
"version_minor": 0
|
||||
},
|
||||
"text/plain": [
|
||||
"Renderer(camera=PerspectiveCamera(aspect=1.5, children=(DirectionalLight(color='white', intensity=0.6, positio…"
|
||||
]
|
||||
},
|
||||
"metadata": {},
|
||||
"output_type": "display_data"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"mesh = Mesh(\"../data/Model01.obj\")\n",
|
||||
"p = plot(mesh.V, mesh.F, shading={\"wireframe\": True,\"width\": 900, \"height\": 600}, return_plot=True, c=np.array([0,0.7,1]))"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"### Trace first asymptotic curve\n",
|
||||
"Use principal directions V1"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 5,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# Set tracing parameters\n",
|
||||
"num_steps = 1000\n",
|
||||
"step_size = 1e-6\n",
|
||||
"num_neighbors = 4\n",
|
||||
"first_principal_direction = False\n",
|
||||
"\n",
|
||||
"# Pre-selection of vertices\n",
|
||||
"idxA = [167,173,178,146,159,291,49,40,254,57,15,65,268,341,283]\n",
|
||||
"# Tracing\n",
|
||||
"for idx in idxA:\n",
|
||||
" P, A, PP = asymptotic_path(idx, mesh, num_steps, step_size, first_principal_direction, num_neighbors)\n",
|
||||
"\n",
|
||||
" # Plot starting vertex\n",
|
||||
" p.add_points(np.array([mesh.V[idx]]), shading={\"point_size\": 0.7, \"point_color\": \"black\"})\n",
|
||||
" # Plot edge-points shaping the asymptotic path\n",
|
||||
" p.add_points(P, shading={\"point_size\": 0.2,\"point_color\": \"white\"})\n",
|
||||
" # Plot asymptotic curve\n",
|
||||
" if(len(P)>1): \n",
|
||||
" p.add_lines(P[:-1], P[1:], shading={\"line_color\": \"white\"})"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"### Trace second asymptotic curve\n",
|
||||
"Use principal directions V2"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 6,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# Set tracing parameters\n",
|
||||
"num_steps = 1000\n",
|
||||
"step_size = 1e-6\n",
|
||||
"num_neighbors = 4\n",
|
||||
"first_principal_direction = True\n",
|
||||
"\n",
|
||||
"# Pre-selection of vertices\n",
|
||||
"idxB = [119,203,188,129,95,66,308,298,290,282,335,143,81,73,33]\n",
|
||||
"# Tracing\n",
|
||||
"for idx in idxB:\n",
|
||||
" P, A, PP = asymptotic_path(idx, mesh, num_steps, step_size, first_principal_direction, num_neighbors)\n",
|
||||
" \n",
|
||||
" # Plot starting vertex\n",
|
||||
" p.add_points(np.array([mesh.V[idx]]), shading={\"point_size\": 0.7, \"point_color\": \"black\"})\n",
|
||||
" # Plot edge-points shaping the asymptotic path\n",
|
||||
" p.add_points(P, shading={\"point_size\": 0.2,\"point_color\": \"yellow\"})\n",
|
||||
" # Plot asymptotic curve\n",
|
||||
" if(len(P)>1): \n",
|
||||
" p.add_lines(P[:-1], P[1:], shading={\"line_color\": \"yellow\"})"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": []
|
||||
}
|
||||
],
|
||||
"metadata": {
|
||||
"interpreter": {
|
||||
"hash": "d74ce2d711eca57e47550fdd427f707c5faa08517318f0967f4aae699c902c0e"
|
||||
},
|
||||
"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
|
||||
}
|
509
cs457-gc/assignment_3_3/notebook/design_tool.ipynb
Normal file
509
cs457-gc/assignment_3_3/notebook/design_tool.ipynb
Normal file
@@ -0,0 +1,509 @@
|
||||
{
|
||||
"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
|
||||
}
|
171
cs457-gc/assignment_3_3/notebook/tracing_test.ipynb
Normal file
171
cs457-gc/assignment_3_3/notebook/tracing_test.ipynb
Normal file
@@ -0,0 +1,171 @@
|
||||
{
|
||||
"cells": [
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 1,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"import numpy as np\n",
|
||||
"from meshplot import plot"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 2,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"import sys\n",
|
||||
"sys.path.append('../src')"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 3,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"import importlib, tracer_helper, tracer_utils\n",
|
||||
"importlib.reload(tracer_helper)\n",
|
||||
"importlib.reload(tracer_utils)\n",
|
||||
"from tracer_utils import asymptotic_path\n",
|
||||
"from tracer_helper import Mesh"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"# Example\n",
|
||||
"Build mesh from file"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 4,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"application/vnd.jupyter.widget-view+json": {
|
||||
"model_id": "f19ce42be2f6405796de381ba4b89b42",
|
||||
"version_major": 2,
|
||||
"version_minor": 0
|
||||
},
|
||||
"text/plain": [
|
||||
"Renderer(camera=PerspectiveCamera(aspect=1.5, children=(DirectionalLight(color='white', intensity=0.6, positio…"
|
||||
]
|
||||
},
|
||||
"metadata": {},
|
||||
"output_type": "display_data"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"mesh = Mesh(\"../data/Model01.obj\")\n",
|
||||
"p = plot(mesh.V, mesh.F, shading={\"wireframe\": True,\"width\": 900, \"height\": 600}, return_plot=True, c=np.array([0,0.7,1]))"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"### Trace first asymptotic curve\n",
|
||||
"Use principal directions V1"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 7,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# Set tracing parameters\n",
|
||||
"num_steps = 1000\n",
|
||||
"step_size = 1e-6\n",
|
||||
"num_neighbors = 4\n",
|
||||
"first_principal_direction = False\n",
|
||||
"\n",
|
||||
"# Pre-selection of vertices\n",
|
||||
"idxA = [167,173,178,146,159,291,49,40,254,57,15,65,268,341,283]\n",
|
||||
"# Tracing\n",
|
||||
"for idx in idxA:\n",
|
||||
" P, A, PP = asymptotic_path(idx, mesh, num_steps, step_size, first_principal_direction, num_neighbors)\n",
|
||||
"\n",
|
||||
" # Plot starting vertex\n",
|
||||
" p.add_points(np.array([mesh.V[idx]]), shading={\"point_size\": 0.7, \"point_color\": \"black\"})\n",
|
||||
" # Plot edge-points shaping the asymptotic path\n",
|
||||
" p.add_points(P, shading={\"point_size\": 0.2,\"point_color\": \"white\"})\n",
|
||||
" # Plot asymptotic curve\n",
|
||||
" if(len(P)>1): \n",
|
||||
" p.add_lines(P[:-1], P[1:], shading={\"line_color\": \"white\"})"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"### Trace second asymptotic curve\n",
|
||||
"Use principal directions V2"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 8,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# Set tracing parameters\n",
|
||||
"num_steps = 1000\n",
|
||||
"step_size = 1e-6\n",
|
||||
"num_neighbors = 4\n",
|
||||
"first_principal_direction = True\n",
|
||||
"\n",
|
||||
"# Pre-selection of vertices\n",
|
||||
"idxB = [119,203,188,129,95,66,308,298,290,282,335,143,81,73,33]\n",
|
||||
"# Tracing\n",
|
||||
"for idx in idxB:\n",
|
||||
" P, A, PP = asymptotic_path(idx, mesh, num_steps, step_size, first_principal_direction, num_neighbors)\n",
|
||||
" \n",
|
||||
" # Plot starting vertex\n",
|
||||
" p.add_points(np.array([mesh.V[idx]]), shading={\"point_size\": 0.7, \"point_color\": \"black\"})\n",
|
||||
" # Plot edge-points shaping the asymptotic path\n",
|
||||
" p.add_points(P, shading={\"point_size\": 0.2,\"point_color\": \"yellow\"})\n",
|
||||
" # Plot asymptotic curve\n",
|
||||
" if(len(P)>1): \n",
|
||||
" p.add_lines(P[:-1], P[1:], shading={\"line_color\": \"yellow\"})"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": []
|
||||
}
|
||||
],
|
||||
"metadata": {
|
||||
"interpreter": {
|
||||
"hash": "d74ce2d711eca57e47550fdd427f707c5faa08517318f0967f4aae699c902c0e"
|
||||
},
|
||||
"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
|
||||
}
|
Reference in New Issue
Block a user