Skip to content

Instantly share code, notes, and snippets.

@fullcontrol-xyz
Last active June 11, 2024 08:14
Show Gist options
  • Save fullcontrol-xyz/34bfa6fe7de016bcfc909ae9b526470f to your computer and use it in GitHub Desktop.
Save fullcontrol-xyz/34bfa6fe7de016bcfc909ae9b526470f to your computer and use it in GitHub Desktop.
custom_start_end_gcode.ipynb
Display the source blob
Display the rendered blob
Raw
{
"cells": [
{
"cell_type": "markdown",
"metadata": {
"id": "view-in-github",
"colab_type": "text"
},
"source": [
"<a href=\"https://colab.research.google.com/gist/fullcontrol-xyz/34bfa6fe7de016bcfc909ae9b526470f/custom_start_end_gcode.ipynb\" target=\"_parent\"><img src=\"https://colab.research.google.com/assets/colab-badge.svg\" alt=\"Open In Colab\"/></a>"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "ac9_FmrCOwQL"
},
"source": [
"# Custom start/end gcode\n",
"\n",
"*<<< check out demo models [here](https://github.com/FullControlXYZ/fullcontrol/tree/master/models/README.md) >>>*\n",
" \n",
"press ctrl+F9 to run all cells in this notebook, or press shift+enter to run each cell sequentially\n",
"\n",
"if you change one of the code cells, make sure you run it and all subsequent cells again (in order)\n",
"\n",
"*this document is a jupyter notebook - if they're new to you, check out how they work: [link](https://www.google.com/search?q=ipynb+tutorial), [link](https://jupyter.org/try-jupyter/retro/notebooks/?path=notebooks/Intro.ipynb), [link](https://colab.research.google.com/)*\n",
"### be patient :)\n",
"\n",
"the next code cell may take a while because running it causes several things to happen:\n",
"- connect to a google colab server -> download the fullcontrol code -> install the fullcontrol code\n",
"\n",
"check out [other tutorials](https://github.com/FullControlXYZ/fullcontrol/blob/master/docs/README.md) to understand the python code for the FullControl design"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "57XXnogSOvDx",
"outputId": "05abd7be-7c8c-4bfd-e35e-12083249517e",
"colab": {
"base_uri": "https://localhost:8080/"
}
},
"outputs": [
{
"output_type": "stream",
"name": "stdout",
"text": [
" Installing build dependencies ... \u001b[?25l\u001b[?25hdone\n",
" Getting requirements to build wheel ... \u001b[?25l\u001b[?25hdone\n",
" Preparing metadata (pyproject.toml) ... \u001b[?25l\u001b[?25hdone\n",
"\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m3.1/3.1 MB\u001b[0m \u001b[31m8.7 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
"\u001b[?25h Building wheel for fullcontrol (pyproject.toml) ... \u001b[?25l\u001b[?25hdone\n"
]
}
],
"source": [
"if 'google.colab' in str(get_ipython()):\n",
" !pip install git+https://github.com/FullControlXYZ/fullcontrol --quiet\n",
"import fullcontrol as fc\n",
"from google.colab import files"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "kRjDdq81dUNn"
},
"outputs": [],
"source": [
"# printer/gcode parameters\n",
"\n",
"design_name = 'my_design'\n",
"nozzle_temp = 210\n",
"bed_temp = 40\n",
"print_speed = 1000\n",
"fan_percent = 100\n",
"printer_name='custom' # generic / ultimaker2plus / prusa_i3 / ender_3 / cr_10 / bambulab_x1 / toolchanger_T0"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "DeWKjlzbPC0u"
},
"outputs": [],
"source": [
"# design parameters\n",
"\n",
"EW = 0.8 # extrusion width\n",
"EH = 0.3 # extrusion height (and layer height)\n",
"initial_z = EH*0.6 # initial nozzle position is set to 0.6x the extrusion height to get a bit of 'squish' for good bed adhesion\n",
"layers = 2"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "kLPh7aTwQKrF"
},
"outputs": [],
"source": [
"# generate the design (make sure you've run the above cells before running this cell)\n",
"\n",
"steps = []\n",
"for layer in range(layers):\n",
" steps.append(fc.Point(x=50, y=50, z=initial_z+layer*EH))\n",
" steps.append(fc.Point(x=100, y=50, z=initial_z+layer*EH))\n",
" steps.append(fc.Point(x=100, y=100, z=initial_z+layer*EH))\n",
" steps.append(fc.Point(x=50, y=100, z=initial_z+layer*EH))\n",
" steps.append(fc.Point(x=50, y=50, z=initial_z+layer*EH))\n",
"\n",
"# instead of the above for-loop code, you can create the exact same design using built-in FullControl functions (uncomment the next two lines):\n",
"# rectangle_steps = fc.rectangleXY(fc.Point(x=50, y=50, z=initial_z), 50, 50)\n",
"# steps = fc.move(rectangle_steps, fc.Vector(z=EH), copy=True, copy_quantity=layers)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "ZVdfnpt5RSUi",
"outputId": "34ba0c9e-b1b2-44d1-f6a7-76493816880a",
"colab": {
"base_uri": "https://localhost:8080/",
"height": 517
}
},
"outputs": [
{
"output_type": "display_data",
"data": {
"text/html": [
"<html>\n",
"<head><meta charset=\"utf-8\" /></head>\n",
"<body>\n",
" <div> <script src=\"https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.5/MathJax.js?config=TeX-AMS-MML_SVG\"></script><script type=\"text/javascript\">if (window.MathJax && window.MathJax.Hub && window.MathJax.Hub.Config) {window.MathJax.Hub.Config({SVG: {font: \"STIX-Web\"}});}</script> <script type=\"text/javascript\">window.PlotlyConfig = {MathJaxConfig: 'local'};</script>\n",
" <script charset=\"utf-8\" src=\"https://cdn.plot.ly/plotly-2.24.1.min.js\"></script> <div id=\"1722da5a-fecb-4b9c-ab39-4ef3d427fb1d\" class=\"plotly-graph-div\" style=\"height:500px; width:800px;\"></div> <script type=\"text/javascript\"> window.PLOTLYENV=window.PLOTLYENV || {}; if (document.getElementById(\"1722da5a-fecb-4b9c-ab39-4ef3d427fb1d\")) { Plotly.newPlot( \"1722da5a-fecb-4b9c-ab39-4ef3d427fb1d\", [{\"line\":{\"color\":[\"rgb(0.00, 0.00, 255.00)\",\"rgb(0.00, 0.00, 255.00)\",\"rgb(0.00, 0.00, 255.00)\",\"rgb(0.00, 0.00, 255.00)\",\"rgb(0.00, 0.00, 255.00)\",\"rgb(0.00, 255.00, 255.00)\",\"rgb(0.00, 255.00, 255.00)\",\"rgb(0.00, 255.00, 255.00)\",\"rgb(0.00, 255.00, 255.00)\",\"rgb(0.00, 255.00, 255.00)\"],\"width\":4},\"mode\":\"lines\",\"showlegend\":false,\"x\":[50.0,100.0,100.0,50.0,50.0,50.0,100.0,100.0,50.0,50.0],\"y\":[50.0,50.0,100.0,100.0,50.0,50.0,50.0,100.0,100.0,50.0],\"z\":[0.18,0.18,0.18,0.18,0.18,0.48,0.48,0.48,0.48,0.48],\"type\":\"scatter3d\"},{\"marker\":{\"color\":\"red\",\"size\":2},\"mode\":\"markers\",\"showlegend\":false,\"x\":[],\"y\":[],\"z\":[],\"type\":\"scatter3d\"}], {\"template\":{\"data\":{\"barpolar\":[{\"marker\":{\"line\":{\"color\":\"rgb(17,17,17)\",\"width\":0.5},\"pattern\":{\"fillmode\":\"overlay\",\"size\":10,\"solidity\":0.2}},\"type\":\"barpolar\"}],\"bar\":[{\"error_x\":{\"color\":\"#f2f5fa\"},\"error_y\":{\"color\":\"#f2f5fa\"},\"marker\":{\"line\":{\"color\":\"rgb(17,17,17)\",\"width\":0.5},\"pattern\":{\"fillmode\":\"overlay\",\"size\":10,\"solidity\":0.2}},\"type\":\"bar\"}],\"carpet\":[{\"aaxis\":{\"endlinecolor\":\"#A2B1C6\",\"gridcolor\":\"#506784\",\"linecolor\":\"#506784\",\"minorgridcolor\":\"#506784\",\"startlinecolor\":\"#A2B1C6\"},\"baxis\":{\"endlinecolor\":\"#A2B1C6\",\"gridcolor\":\"#506784\",\"linecolor\":\"#506784\",\"minorgridcolor\":\"#506784\",\"startlinecolor\":\"#A2B1C6\"},\"type\":\"carpet\"}],\"choropleth\":[{\"colorbar\":{\"outlinewidth\":0,\"ticks\":\"\"},\"type\":\"choropleth\"}],\"contourcarpet\":[{\"colorbar\":{\"outlinewidth\":0,\"ticks\":\"\"},\"type\":\"contourcarpet\"}],\"contour\":[{\"colorbar\":{\"outlinewidth\":0,\"ticks\":\"\"},\"colorscale\":[[0.0,\"#0d0887\"],[0.1111111111111111,\"#46039f\"],[0.2222222222222222,\"#7201a8\"],[0.3333333333333333,\"#9c179e\"],[0.4444444444444444,\"#bd3786\"],[0.5555555555555556,\"#d8576b\"],[0.6666666666666666,\"#ed7953\"],[0.7777777777777778,\"#fb9f3a\"],[0.8888888888888888,\"#fdca26\"],[1.0,\"#f0f921\"]],\"type\":\"contour\"}],\"heatmapgl\":[{\"colorbar\":{\"outlinewidth\":0,\"ticks\":\"\"},\"colorscale\":[[0.0,\"#0d0887\"],[0.1111111111111111,\"#46039f\"],[0.2222222222222222,\"#7201a8\"],[0.3333333333333333,\"#9c179e\"],[0.4444444444444444,\"#bd3786\"],[0.5555555555555556,\"#d8576b\"],[0.6666666666666666,\"#ed7953\"],[0.7777777777777778,\"#fb9f3a\"],[0.8888888888888888,\"#fdca26\"],[1.0,\"#f0f921\"]],\"type\":\"heatmapgl\"}],\"heatmap\":[{\"colorbar\":{\"outlinewidth\":0,\"ticks\":\"\"},\"colorscale\":[[0.0,\"#0d0887\"],[0.1111111111111111,\"#46039f\"],[0.2222222222222222,\"#7201a8\"],[0.3333333333333333,\"#9c179e\"],[0.4444444444444444,\"#bd3786\"],[0.5555555555555556,\"#d8576b\"],[0.6666666666666666,\"#ed7953\"],[0.7777777777777778,\"#fb9f3a\"],[0.8888888888888888,\"#fdca26\"],[1.0,\"#f0f921\"]],\"type\":\"heatmap\"}],\"histogram2dcontour\":[{\"colorbar\":{\"outlinewidth\":0,\"ticks\":\"\"},\"colorscale\":[[0.0,\"#0d0887\"],[0.1111111111111111,\"#46039f\"],[0.2222222222222222,\"#7201a8\"],[0.3333333333333333,\"#9c179e\"],[0.4444444444444444,\"#bd3786\"],[0.5555555555555556,\"#d8576b\"],[0.6666666666666666,\"#ed7953\"],[0.7777777777777778,\"#fb9f3a\"],[0.8888888888888888,\"#fdca26\"],[1.0,\"#f0f921\"]],\"type\":\"histogram2dcontour\"}],\"histogram2d\":[{\"colorbar\":{\"outlinewidth\":0,\"ticks\":\"\"},\"colorscale\":[[0.0,\"#0d0887\"],[0.1111111111111111,\"#46039f\"],[0.2222222222222222,\"#7201a8\"],[0.3333333333333333,\"#9c179e\"],[0.4444444444444444,\"#bd3786\"],[0.5555555555555556,\"#d8576b\"],[0.6666666666666666,\"#ed7953\"],[0.7777777777777778,\"#fb9f3a\"],[0.8888888888888888,\"#fdca26\"],[1.0,\"#f0f921\"]],\"type\":\"histogram2d\"}],\"histogram\":[{\"marker\":{\"pattern\":{\"fillmode\":\"overlay\",\"size\":10,\"solidity\":0.2}},\"type\":\"histogram\"}],\"mesh3d\":[{\"colorbar\":{\"outlinewidth\":0,\"ticks\":\"\"},\"type\":\"mesh3d\"}],\"parcoords\":[{\"line\":{\"colorbar\":{\"outlinewidth\":0,\"ticks\":\"\"}},\"type\":\"parcoords\"}],\"pie\":[{\"automargin\":true,\"type\":\"pie\"}],\"scatter3d\":[{\"line\":{\"colorbar\":{\"outlinewidth\":0,\"ticks\":\"\"}},\"marker\":{\"colorbar\":{\"outlinewidth\":0,\"ticks\":\"\"}},\"type\":\"scatter3d\"}],\"scattercarpet\":[{\"marker\":{\"colorbar\":{\"outlinewidth\":0,\"ticks\":\"\"}},\"type\":\"scattercarpet\"}],\"scattergeo\":[{\"marker\":{\"colorbar\":{\"outlinewidth\":0,\"ticks\":\"\"}},\"type\":\"scattergeo\"}],\"scattergl\":[{\"marker\":{\"line\":{\"color\":\"#283442\"}},\"type\":\"scattergl\"}],\"scattermapbox\":[{\"marker\":{\"colorbar\":{\"outlinewidth\":0,\"ticks\":\"\"}},\"type\":\"scattermapbox\"}],\"scatterpolargl\":[{\"marker\":{\"colorbar\":{\"outlinewidth\":0,\"ticks\":\"\"}},\"type\":\"scatterpolargl\"}],\"scatterpolar\":[{\"marker\":{\"colorbar\":{\"outlinewidth\":0,\"ticks\":\"\"}},\"type\":\"scatterpolar\"}],\"scatter\":[{\"marker\":{\"line\":{\"color\":\"#283442\"}},\"type\":\"scatter\"}],\"scatterternary\":[{\"marker\":{\"colorbar\":{\"outlinewidth\":0,\"ticks\":\"\"}},\"type\":\"scatterternary\"}],\"surface\":[{\"colorbar\":{\"outlinewidth\":0,\"ticks\":\"\"},\"colorscale\":[[0.0,\"#0d0887\"],[0.1111111111111111,\"#46039f\"],[0.2222222222222222,\"#7201a8\"],[0.3333333333333333,\"#9c179e\"],[0.4444444444444444,\"#bd3786\"],[0.5555555555555556,\"#d8576b\"],[0.6666666666666666,\"#ed7953\"],[0.7777777777777778,\"#fb9f3a\"],[0.8888888888888888,\"#fdca26\"],[1.0,\"#f0f921\"]],\"type\":\"surface\"}],\"table\":[{\"cells\":{\"fill\":{\"color\":\"#506784\"},\"line\":{\"color\":\"rgb(17,17,17)\"}},\"header\":{\"fill\":{\"color\":\"#2a3f5f\"},\"line\":{\"color\":\"rgb(17,17,17)\"}},\"type\":\"table\"}]},\"layout\":{\"annotationdefaults\":{\"arrowcolor\":\"#f2f5fa\",\"arrowhead\":0,\"arrowwidth\":1},\"autotypenumbers\":\"strict\",\"coloraxis\":{\"colorbar\":{\"outlinewidth\":0,\"ticks\":\"\"}},\"colorscale\":{\"diverging\":[[0,\"#8e0152\"],[0.1,\"#c51b7d\"],[0.2,\"#de77ae\"],[0.3,\"#f1b6da\"],[0.4,\"#fde0ef\"],[0.5,\"#f7f7f7\"],[0.6,\"#e6f5d0\"],[0.7,\"#b8e186\"],[0.8,\"#7fbc41\"],[0.9,\"#4d9221\"],[1,\"#276419\"]],\"sequential\":[[0.0,\"#0d0887\"],[0.1111111111111111,\"#46039f\"],[0.2222222222222222,\"#7201a8\"],[0.3333333333333333,\"#9c179e\"],[0.4444444444444444,\"#bd3786\"],[0.5555555555555556,\"#d8576b\"],[0.6666666666666666,\"#ed7953\"],[0.7777777777777778,\"#fb9f3a\"],[0.8888888888888888,\"#fdca26\"],[1.0,\"#f0f921\"]],\"sequentialminus\":[[0.0,\"#0d0887\"],[0.1111111111111111,\"#46039f\"],[0.2222222222222222,\"#7201a8\"],[0.3333333333333333,\"#9c179e\"],[0.4444444444444444,\"#bd3786\"],[0.5555555555555556,\"#d8576b\"],[0.6666666666666666,\"#ed7953\"],[0.7777777777777778,\"#fb9f3a\"],[0.8888888888888888,\"#fdca26\"],[1.0,\"#f0f921\"]]},\"colorway\":[\"#636efa\",\"#EF553B\",\"#00cc96\",\"#ab63fa\",\"#FFA15A\",\"#19d3f3\",\"#FF6692\",\"#B6E880\",\"#FF97FF\",\"#FECB52\"],\"font\":{\"color\":\"#f2f5fa\"},\"geo\":{\"bgcolor\":\"rgb(17,17,17)\",\"lakecolor\":\"rgb(17,17,17)\",\"landcolor\":\"rgb(17,17,17)\",\"showlakes\":true,\"showland\":true,\"subunitcolor\":\"#506784\"},\"hoverlabel\":{\"align\":\"left\"},\"hovermode\":\"closest\",\"mapbox\":{\"style\":\"dark\"},\"paper_bgcolor\":\"rgb(17,17,17)\",\"plot_bgcolor\":\"rgb(17,17,17)\",\"polar\":{\"angularaxis\":{\"gridcolor\":\"#506784\",\"linecolor\":\"#506784\",\"ticks\":\"\"},\"bgcolor\":\"rgb(17,17,17)\",\"radialaxis\":{\"gridcolor\":\"#506784\",\"linecolor\":\"#506784\",\"ticks\":\"\"}},\"scene\":{\"xaxis\":{\"backgroundcolor\":\"rgb(17,17,17)\",\"gridcolor\":\"#506784\",\"gridwidth\":2,\"linecolor\":\"#506784\",\"showbackground\":true,\"ticks\":\"\",\"zerolinecolor\":\"#C8D4E3\"},\"yaxis\":{\"backgroundcolor\":\"rgb(17,17,17)\",\"gridcolor\":\"#506784\",\"gridwidth\":2,\"linecolor\":\"#506784\",\"showbackground\":true,\"ticks\":\"\",\"zerolinecolor\":\"#C8D4E3\"},\"zaxis\":{\"backgroundcolor\":\"rgb(17,17,17)\",\"gridcolor\":\"#506784\",\"gridwidth\":2,\"linecolor\":\"#506784\",\"showbackground\":true,\"ticks\":\"\",\"zerolinecolor\":\"#C8D4E3\"}},\"shapedefaults\":{\"line\":{\"color\":\"#f2f5fa\"}},\"sliderdefaults\":{\"bgcolor\":\"#C8D4E3\",\"bordercolor\":\"rgb(17,17,17)\",\"borderwidth\":1,\"tickwidth\":0},\"ternary\":{\"aaxis\":{\"gridcolor\":\"#506784\",\"linecolor\":\"#506784\",\"ticks\":\"\"},\"baxis\":{\"gridcolor\":\"#506784\",\"linecolor\":\"#506784\",\"ticks\":\"\"},\"bgcolor\":\"rgb(17,17,17)\",\"caxis\":{\"gridcolor\":\"#506784\",\"linecolor\":\"#506784\",\"ticks\":\"\"}},\"title\":{\"x\":0.05},\"updatemenudefaults\":{\"bgcolor\":\"#506784\",\"borderwidth\":0},\"xaxis\":{\"automargin\":true,\"gridcolor\":\"#283442\",\"linecolor\":\"#506784\",\"ticks\":\"\",\"title\":{\"standoff\":15},\"zerolinecolor\":\"#283442\",\"zerolinewidth\":2},\"yaxis\":{\"automargin\":true,\"gridcolor\":\"#283442\",\"linecolor\":\"#506784\",\"ticks\":\"\",\"title\":{\"standoff\":15},\"zerolinecolor\":\"#283442\",\"zerolinewidth\":2}}},\"scene\":{\"xaxis\":{\"backgroundcolor\":\"black\",\"nticks\":10,\"range\":[49.998999999999995,100.001]},\"yaxis\":{\"backgroundcolor\":\"black\",\"nticks\":10,\"range\":[49.998999999999995,100.001]},\"zaxis\":{\"backgroundcolor\":\"black\",\"nticks\":10,\"range\":[0,50.002]},\"camera\":{\"eye\":{\"x\":-0.7142857142857143,\"y\":-1.4285714285714286,\"z\":0.2142857142857143},\"center\":{\"x\":0,\"y\":0,\"z\":-0.5}},\"aspectmode\":\"cube\"},\"margin\":{\"l\":10,\"r\":10,\"b\":10,\"t\":10,\"pad\":4},\"paper_bgcolor\":\"black\",\"width\":800,\"height\":500}, {\"responsive\": true} ).then(function(){\n",
" \n",
"var gd = document.getElementById('1722da5a-fecb-4b9c-ab39-4ef3d427fb1d');\n",
"var x = new MutationObserver(function (mutations, observer) {{\n",
" var display = window.getComputedStyle(gd).display;\n",
" if (!display || display === 'none') {{\n",
" console.log([gd, 'removed!']);\n",
" Plotly.purge(gd);\n",
" observer.disconnect();\n",
" }}\n",
"}});\n",
"\n",
"// Listen for the removal of the full notebook cells\n",
"var notebookContainer = gd.closest('#notebook-container');\n",
"if (notebookContainer) {{\n",
" x.observe(notebookContainer, {childList: true});\n",
"}}\n",
"\n",
"// Listen for the clearing of the current output cell\n",
"var outputEl = gd.closest('.output');\n",
"if (outputEl) {{\n",
" x.observe(outputEl, {childList: true});\n",
"}}\n",
"\n",
" }) }; </script> </div>\n",
"</body>\n",
"</html>"
]
},
"metadata": {}
}
],
"source": [
"# preview the design\n",
"\n",
"fc.transform(steps, 'plot', fc.PlotControls(style='line', zoom=0.7))\n",
"# hover the cursor over the lines in the plot to check xyz positions of the points in the design\n",
"\n",
"# uncomment the next line to create a plot with real heights/widths for extruded lines to preview the real 3D printed geometry\n",
"# fc.transform(steps, 'plot', fc.PlotControls(style='tube', zoom=0.7, initialization_data={'extrusion_width': EW, 'extrusion_height': EH}))\n",
"\n",
"# uncomment the next line to create a neat preview (click the top-left button in the plot for a .png file) - post and tag @FullControlXYZ :)\n",
"# fc.transform(steps, 'plot', fc.PlotControls(neat_for_publishing=True, zoom=0.5, initialization_data={'extrusion_width': EW, 'extrusion_height': EH}))\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"colab": {
"base_uri": "https://localhost:8080/",
"height": 17
},
"id": "tggFoUeJReQR",
"outputId": "86b58374-3b30-4291-b4cd-fc02976da18c"
},
"outputs": [
{
"output_type": "display_data",
"data": {
"text/plain": [
"<IPython.core.display.Javascript object>"
],
"application/javascript": [
"\n",
" async function download(id, filename, size) {\n",
" if (!google.colab.kernel.accessAllowed) {\n",
" return;\n",
" }\n",
" const div = document.createElement('div');\n",
" const label = document.createElement('label');\n",
" label.textContent = `Downloading \"${filename}\": `;\n",
" div.appendChild(label);\n",
" const progress = document.createElement('progress');\n",
" progress.max = size;\n",
" div.appendChild(progress);\n",
" document.body.appendChild(div);\n",
"\n",
" const buffers = [];\n",
" let downloaded = 0;\n",
"\n",
" const channel = await google.colab.kernel.comms.open(id);\n",
" // Send a message to notify the kernel that we're ready.\n",
" channel.send({})\n",
"\n",
" for await (const message of channel.messages) {\n",
" // Send a message to notify the kernel that we're ready.\n",
" channel.send({})\n",
" if (message.buffers) {\n",
" for (const buffer of message.buffers) {\n",
" buffers.push(buffer);\n",
" downloaded += buffer.byteLength;\n",
" progress.value = downloaded;\n",
" }\n",
" }\n",
" }\n",
" const blob = new Blob(buffers, {type: 'application/binary'});\n",
" const a = document.createElement('a');\n",
" a.href = window.URL.createObjectURL(blob);\n",
" a.download = filename;\n",
" div.appendChild(a);\n",
" a.click();\n",
" div.remove();\n",
" }\n",
" "
]
},
"metadata": {}
},
{
"output_type": "display_data",
"data": {
"text/plain": [
"<IPython.core.display.Javascript object>"
],
"application/javascript": [
"download(\"download_a88565b3-e395-450e-b9bb-2720427e1380\", \"my_design.gcode\", 1041)"
]
},
"metadata": {}
}
],
"source": [
"# generate and save gcode\n",
"\n",
"gcode_controls = fc.GcodeControls(\n",
" printer_name=printer_name,\n",
"\n",
" initialization_data={\n",
" 'primer': 'travel',\n",
" 'print_speed': print_speed,\n",
" 'extrusion_width': EW,\n",
" 'extrusion_height': EH,\n",
" 'e_units': 'mm',\n",
" 'dia_feed': 1.75,\n",
" # 'manual_e_ratio': 2.5, # this over-rides the calculation of E in gcode - the value is ratio of extrusion_volume (mm3) to 'E' in gcode - see cell below this one\n",
" 'relative_e': True # it's best to keep this as True, but it can be set to False if you want to use absolute extrusion mode (M82 gcode command)\n",
" })\n",
"\n",
"gcode = fc.transform(steps, 'gcode', gcode_controls)\n",
"gcode = gcode.split('\\n')\n",
"del gcode[0:3]\n",
"\n",
"start_gcode = [f'''\n",
"M220 S100 ;Reset Feedrate\n",
"M221 S100 ;Reset Flowrate\n",
"\n",
"G28 ;Home\n",
"\n",
"G92 E0 ;Reset Extruder\n",
"G1 Z2.0 F3000 ;Move Z Axis up\n",
"G1 X10.1 Y20 Z0.28 F5000.0 ;Move to start position\n",
"M104 S{nozzle_temp}\n",
"M140 S{bed_temp}\n",
"M109 S{nozzle_temp}\n",
"M190 S{bed_temp}\n",
"G1 X10.1 Y145.0 Z0.28 F1500.0 E15 ;Draw the first line\n",
"G1 X10.4 Y145.0 Z0.28 F5000.0 ;Move to side a little\n",
"G1 X10.4 Y20 Z0.28 F1500.0 E30 ;Draw the second line\n",
"G92 E0 ;Reset Extruder\n",
"G1 E-1.0000 F1800 ;Retract a bit\n",
"G1 Z2.0 F3000 ;Move Z Axis up\n",
"G1 E0.0000 F1800\n",
"M106 S{255*fan_percent/100}\n",
"''']\n",
"\n",
"end_gcode = [f'''\n",
"G91 ;Relative positionning\n",
"G1 E-2 F2700 ;Retract a bit\n",
"G1 E-2 Z0.2 F2400 ;Retract and raise Z\n",
"G1 X5 Y5 F3000 ;Wipe out\n",
"G1 Z10 ;Raise Z more\n",
"G90 ;Absolute positionning\n",
"\n",
"G1 X0 Y0 ;Present print\n",
"M106 S0 ;Turn-off fan\n",
"M104 S0 ;Turn-off hotend\n",
"M140 S0 ;Turn-off bed\n",
"\n",
"M84 X Y E ;Disable all steppers but Z\n",
"''']\n",
"\n",
"gcode = start_gcode + ['; BEGINNING OF FULLCONTROL GCODE'] + gcode + ['; END OF FULLCONTROL GCODE'] + end_gcode\n",
"gcode = '\\n'.join(gcode)\n",
"open(f'{design_name}.gcode', 'w').write(gcode)\n",
"files.download(f'{design_name}.gcode')\n"
]
},
{
"cell_type": "markdown",
"source": [
"for some printers, the default methods in fullcontrol to calculate E in gcode based on the diameter of feedstock filament may not be appropriate - e.g. syringe extruders.\n",
"\n",
"in that case, the conversion from extrusion volume to 'E' can be controlled in fullcontrol with the 'manual_e_ratio' option in the initialization_data attribute of a fc.GcodeControls object (see previous cell)\n",
"\n",
"The next cell helps determine this ratio:\n",
"- choose two sequential G1 gcode commands for which you know what the extrusion width and layer height was set to\n",
"- if **both** lines of gcode omit x or y or z values, you can set their value to 0 for both points in the next cell\n",
"- if **one** line of gcode includes an x/y/z value but the other doesn't, you need to figure out what the omitted x/y/z value is, by looking back through the gcode, and use that value for both points in the next cell\n",
"- use the E value from the second line of gcode in the next cell\n",
"- after you run the cell, it should print out a value for 'manual_e_ratio' which you can use in the initialization_data dictionary in the previous code cell"
],
"metadata": {
"id": "CJwe7Mk3GOGo"
}
},
{
"cell_type": "code",
"source": [
"point_in_existing_gcode = fc.Point(x=0, y=0, z=0) # update x/y/z values\n",
"next_point_in_existing_gcode = fc.Point(x=20, y=0, z=0) # update x/y/z values\n",
"E_in_gcode_line_for_second_point = 500 # update this value\n",
"extrusion_width = 5 # update this value - it's the value you set in your slicer for the line_width of the line for the bit of gcode you're considering\n",
"extrusion_height = 2 # update this value - it's the value you set in your slicer for the line_width of the line for the bit of gcode you're considering\n",
"\n",
"volume = extrusion_width * extrusion_height * fc.distance(point_in_existing_gcode, next_point_in_existing_gcode)\n",
"print(f'manual_e_ratio = {round(E_in_gcode_line_for_second_point / volume, 6)}\\n(used in: fc.GcodeControls.initialization_data)')"
],
"metadata": {
"id": "urCVj8JyGKQ5",
"outputId": "0f6dda5c-12ce-4551-f10e-d9e6936d7407",
"colab": {
"base_uri": "https://localhost:8080/"
}
},
"execution_count": null,
"outputs": [
{
"output_type": "stream",
"name": "stdout",
"text": [
"manual_e_ratio = 2.5\n",
"(used in: fc.GcodeControls.initialization_data)\n"
]
}
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "JP3HY9QNdUNt"
},
"source": [
"#### please tell us what you're doing with FullControl!\n",
"\n",
"- tag FullControlXYZ on social media ([twitter](https://twitter.com/FullControlXYZ), [instagram](https://www.instagram.com/fullcontrolxyz/), [linkedin](https://www.linkedin.com/in/andrew-gleadall-068587119/), [tiktok](https://www.tiktok.com/@fullcontrolxyz))\n",
"- email [info@fullcontrol.xyz](mailto:info@fullcontrol.xyz)\n",
"- post on the [subreddit](https://reddit.com/r/fullcontrol)\n",
"- post in the [github discussions or issues tabs](https://github.com/FullControlXYZ/fullcontrol/issues)\n",
"\n",
"in publications, please cite the original FullControl paper and the github repo for the new python version:\n",
"\n",
"- Gleadall, A. (2021). FullControl GCode Designer: open-source software for unconstrained design in additive manufacturing. Additive Manufacturing, 46, 102109.\n",
"- Gleadall, A. and Leas, D. (2023). FullControl [electronic resource: python source code]. available at: https://github.com/FullControlXYZ/fullcontrol"
]
}
],
"metadata": {
"colab": {
"provenance": [],
"include_colab_link": true
},
"kernelspec": {
"display_name": "Python 3",
"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.11.3"
}
},
"nbformat": 4,
"nbformat_minor": 0
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment