{"id":509,"date":"2017-09-12T20:41:08","date_gmt":"2017-09-12T18:41:08","guid":{"rendered":"http:\/\/www.joanillo.org\/?p=509"},"modified":"2020-09-24T20:42:36","modified_gmt":"2020-09-24T18:42:36","slug":"script-cncstroke-millorant-la-conversio-dxf-a-g-code-i","status":"publish","type":"post","link":"https:\/\/www.joanillo.org\/?p=509","title":{"rendered":"script cncstroke: millorant la conversi\u00f3 DXF a G-Code, I"},"content":{"rendered":"<p><a href=\"http:\/\/www.joanillo.org\/wp-content\/uploads\/2017\/09\/einstein.jpg\"><img loading=\"lazy\" src=\"http:\/\/www.joanillo.org\/wp-content\/uploads\/2017\/09\/einstein-300x296.jpg\" alt=\"\" title=\"einstein black and white\" width=\"300\" height=\"296\" class=\"alignright size-medium wp-image-1505\"><\/a>Un dels treballs t\u00edpics que es fan amb la <strong>CNC<\/strong> \u00e9s el retrat de personatges en format blanc i negre. Per exemple, s\u00f3n coneguts els retrats del Che Guevara o l&#8217;Albert Einstein. Aquests dies estic treballant en la imatge de l&#8217;<strong>Ovidi Montllor<\/strong> [1].<\/p>\n<p>La idea \u00e9s senzilla i coneguda. Importo la imatge en <strong>LibreCAD<\/strong> [2] (el software CAD que utilitzo, que es open source), defineixo la silueta, i defineixo unes \u00e0rees de <em>hatching<\/em> que seran fresades (rebaixades). Faig servir el programa <em>dxf2gcode<\/em> [3] per exportar a G-Code, i freso tot el treball a una profunditat de 1.5mm. La limitaci\u00f3 que tinc \u00e9s que la fresa que faig servir \u00e9s de 2mm de di\u00e0metre, i aix\u00f2 limita la resoluci\u00f3 final que puc tenir.<\/p>\n<p>Estic programant un petit script (<strong>cncstroke<\/strong> [4]) per tal de millorar la resoluci\u00f3 dels meus treballs. Imaginem per exemple els cabells de l&#8217;Albert Einstein. All\u00f2 ideal \u00e9s que les metxes de cabell acabin en punta, fent un tra\u00e7 que passi de gruixut a fi. Aix\u00f2 s&#8217;aconsegueix fent que la profunditat d&#8217;atac de la broca sigui variable, des de 1.5mm de profunditat en l&#8217;inici del tra\u00e7 fins a 0mm al final del tra\u00e7. Per\u00f2 per tal de qu\u00e8 l&#8217;invent funcioni, no he de fer servir una broca normal, sin\u00f3 una broca <a href=\"https:\/\/www.google.es\/search?q=V-Shape+bit&amp;safe=strict&amp;client=ubuntu&amp;hs=U6T&amp;channel=fs&amp;dcr=0&amp;source=lnms&amp;tbm=isch&amp;sa=X&amp;ved=0ahUKEwimuriG7Z_WAhVGBBoKHeJQCiwQ_AUICigB&amp;biw=1366&amp;bih=591\">V-Shape<\/a> (amb punta de 40 graus). D&#8217;aquesta manera aconseguir\u00e9 l&#8217;efecte de fer un tra\u00e7 que passi de 2mm d&#8217;ample en l&#8217;origen a 0mm en l&#8217;extrem. Aquesta t\u00e8cnica tamb\u00e9 ser\u00e0 molt \u00fatil per fresar lletres que simulin tra\u00e7os variables.<\/p>\n<p>La idea \u00e9s que en els meus projectes de LibreCAD tindr\u00e9 una capa amb la silueta b\u00e0sica (que fresar\u00e9 amb una broca de 2mm), i una capa (que sempre anomenar\u00e9 <em>stroke<\/em>) que constar\u00e0 de <em>polil\u00ednies<\/em> que representaran el tra\u00e7 variable des de 2mm fins a 0 mm d&#8217;ample. Amb aquesta segona capa podr\u00e9 fer els detalls com ara cabells o caligrafia de lletres.<\/p>\n<p>En aquest primer article nom\u00e9s exposo l&#8217;estructura de dades que em permetr\u00e0 gestionar la generaci\u00f3 del G-Code a partir del projecte de LibreCAD. Quan recorri (program\u00e0ticament) el contingut d&#8217;un projecte LibreCAD (format <em>dxf<\/em>), haur\u00e9 de cercar la definici\u00f3 de la capa <em>stroke<\/em> i dels punts que cont\u00e9. Aix\u00f2 \u00e9s relativament f\u00e0cil de fer. Aquesta successi\u00f3 de punts es poden agrupar en polil\u00ednies, entenent que una polil\u00ednia \u00e9s un conjunt de l\u00ednies que van empalmades.<\/p>\n<p>Com que el n\u00famero de poli\u00ednies \u00e9s variable, i el n\u00famero de l\u00ednies que cont\u00e9 una polil\u00ednia tamb\u00e9 \u00e9s variable, la millor manera de programar aquesta estructura amb llenguatge C++ \u00e9s utilitzar vectors.<br \/>\n<code><br \/>\nstruct linia {<br \/>\n\\tint x0;<br \/>\n\\tint y0;<br \/>\n\\tint x1;<br \/>\n\\tint y1;<br \/>\n\\tdouble dist;<br \/>\n};<\/code><\/p>\n<p><code>struct polilinia {<br \/>\n\\tstd::vector  \t<linia> vlinia;<br \/>\n\\tdouble dist;<br \/>\n};<\/linia>\n<p><\/code><code>std::vector <polilinia> vpolilinia;\n<\/polilinia><\/code><\/p>\n<p>Una l\u00ednia consta d&#8217;un punt origen i un punt final (f\u00e0cilment es podr\u00e0 calcular la longitud d&#8217;aquesta l\u00ednia). Una polil\u00ednia consta d&#8217;un conjunt de l\u00ednies, i la longitud de la polil\u00ednia ser\u00e0 la suma de les longituds individuals.<\/p>\n<p>A continuaci\u00f3 mostrem l&#8217;exemple m\u00ednim de com es poden gestionar diferents polil\u00ednies, cadascuna de les quals amb un n\u00famero variable de l\u00ednies.<br \/>\n<code><br \/>\n\/\/ g++ -o polilinia polilinia.cpp<br \/>\n#include <iostream><br \/>\n#include <string><br \/>\n#include <sstream><br \/>\n#include <vector><br \/>\n#include <math.h>\n<\/math.h><\/vector><\/sstream><\/string><\/iostream><\/code><\/p>\n<p><code>struct linia {<br \/>\n\\tint x0;<br \/>\n\\tint y0;<br \/>\n\\tint x1;<br \/>\n\\tint y1;<br \/>\n\\tdouble length;<br \/>\n};<\/code><\/p>\n<p><code>struct polilinia {<br \/>\n\\tstd::vector  \t<linia> vlinia;<br \/>\n\\tdouble length;<br \/>\n};<\/linia>\n<p>std::vector <polilinia> vpolilinia;<\/polilinia>\n<p>using namespace std;<\/p>\n<p>int main() {<br \/>\n\\t<br \/>\n\\tdouble lengthlinia,lengthpolilinia;<br \/>\n\\tpolilinia polilinia1;\\t<br \/>\n\\tlinia linia1;<\/p>\n<p>\\tlengthpolilinia=0;<\/p>\n<p>\\tlinia1.x0=34;<br \/>\n\\tlinia1.y0=30;<br \/>\n\\tlinia1.x1=120;<br \/>\n\\tlinia1.y1=122;<br \/>\n\\tlengthlinia = sqrt(pow(linia1.x1-linia1.x0,2) + pow(linia1.y1-linia1.y0,2));<br \/>\n\\tlinia1.length=lengthlinia;<br \/>\n\\tlengthpolilinia += lengthlinia;<\/p>\n<p>\\tpolilinia1.vlinia.push_back(linia1);<\/p>\n<p>\\tlinia1.x0=320;<br \/>\n\\tlinia1.y0=322;<br \/>\n\\tlinia1.x1=420;<br \/>\n\\tlinia1.y1=422;<br \/>\n\\tlengthlinia = sqrt(pow(linia1.x1-linia1.x0,2) + pow(linia1.y1-linia1.y0,2));<br \/>\n\\tlinia1.length=lengthlinia;<br \/>\n\\tlengthpolilinia += lengthlinia;<\/p>\n<p>\\tpolilinia1.vlinia.push_back(linia1);<br \/>\n\\t<br \/>\n\\tpolilinia1.length = lengthpolilinia;<br \/>\n\\t<br \/>\n\\tvpolilinia.push_back(polilinia1);<br \/>\n\\t<br \/>\n\\t\/\/cout &lt;&lt; vpolilinia.at(0).vlinia.size() &lt;&lt; endl;<\/p>\n<p>\\t\/\/anem per una altra polilinia<br \/>\n\\tpolilinia1.vlinia.clear();<br \/>\n\\tlengthpolilinia=0;<\/p>\n<p>\\tlinia1.x0=134;<br \/>\n\\tlinia1.y0=130;<br \/>\n\\tlinia1.x1=220;<br \/>\n\\tlinia1.y1=222;<br \/>\n\\tlengthlinia = sqrt(pow(linia1.x1-linia1.x0,2) + pow(linia1.y1-linia1.y0,2));<br \/>\n\\tlinia1.length=lengthlinia;<br \/>\n\\tlengthpolilinia += lengthlinia;<\/p>\n<p>\\tpolilinia1.vlinia.push_back(linia1);<\/p>\n<p>\\tlinia1.x0=220;<br \/>\n\\tlinia1.y0=222;<br \/>\n\\tlinia1.x1=320;<br \/>\n\\tlinia1.y1=322;<br \/>\n\\tlengthlinia = sqrt(pow(linia1.x1-linia1.x0,2) + pow(linia1.y1-linia1.y0,2));<br \/>\n\\tlinia1.length=lengthlinia;<br \/>\n\\tlengthpolilinia += lengthlinia;<\/p>\n<p>\\tpolilinia1.vlinia.push_back(linia1);<\/p>\n<p>\\tlinia1.x0=220;<br \/>\n\\tlinia1.y0=222;<br \/>\n\\tlinia1.x1=320;<br \/>\n\\tlinia1.y1=322;<br \/>\n\\tlengthlinia = sqrt(pow(linia1.x1-linia1.x0,2) + pow(linia1.y1-linia1.y0,2));<br \/>\n\\tlinia1.length=lengthlinia;<br \/>\n\\tlengthpolilinia += lengthlinia;<\/p>\n<p>\\tpolilinia1.vlinia.push_back(linia1);<\/p>\n<p>\\tpolilinia1.length = lengthpolilinia;<\/p>\n<p>\\tvpolilinia.push_back(polilinia1);\\t<\/p>\n<p>\\t\/\/cout &lt;&lt; vpolilinia.at(1).vlinia.size() &lt;&lt; endl;<br \/>\n\\t\/\/cout &lt;&lt; vpolilinia.size() &lt;&lt; endl;<\/p>\n<p>\\t\/\/recorrem totes les polil\u00ednies<br \/>\n\\tfor (int i=0; i<vpolilinia.size(); i++)=\"\" {=\"\" \\t\\tcout=\"\" <<=\"\" \"polilinia=\"\" #\"=\"\" i=\"\" \".=\"\" length:=\"\" \"=\"\" vpolilinia.at(i).length=\"\" endl;=\"\" \\t\\t=\"\" dins=\"\" de=\"\" cada=\"\" polilinia,=\"\" recorrem=\"\" les=\"\" l\u00ednies:=\"\" \\t\\tfor=\"\" (int=\"\" j=\"0;\" j<vpolilinia.at(i).vlinia.size();=\"\" j++)=\"\" \\t\\t\\tcout=\"\" \"linia=\"\" vpolilinia.at(i).vlinia.at(j).length=\"\" endl;\\t\\t\\t=\"\" \\t\\t}=\"\" \\t}=\"\" }=\"\" <=\"\" code=\"\"><br \/>\nI la sortida per pantalla:<br \/>\n<code><br \/>\n$ .\/polilinia<br \/>\npolilinia #0. length: 267.358<br \/>\nlinia #0. length: 125.936<br \/>\nlinia #1. length: 141.421<br \/>\npolilinia #1. length: 408.779<br \/>\nlinia #0. length: 125.936<br \/>\nlinia #1. length: 141.421<br \/>\nlinia #2. length: 141.421<br \/>\n<\/code><\/vpolilinia.size();><\/p>\n<p>En el seg\u00fcent <a href=\"http:\/\/www.joanillo.org\/?p=1493\">article<\/a> [5] s'explica la implementaci\u00f3 del projecte <strong>cncstroke<\/strong> per tal de generar G-Code amb <em>z-depth<\/em> variable.<\/p>\n<p>Refer\u00e8ncies:<\/p>\n<ul>\n\\t<\/p>\n<li>[1]. <a href=\"https:\/\/ca.wikipedia.org\/wiki\/Ovidi_Montllor_i_Mengual\" title=\"Ovidi Montllor\">https:\/\/ca.wikipedia.org\/wiki\/Ovidi_Montllor_i_Mengual<\/a><\/li>\n<p>\\t<\/p>\n<li>[2]. <a href=\"http:\/\/librecad.org\/cms\/home.html\" title=\"LibreCAD\">LibreCAD<\/a><\/li>\n<p>\\t<\/p>\n<li>[3]. <a href=\"https:\/\/sourceforge.net\/projects\/dxf2gcode\" title=\"dfx2gcode\">dfx2gcode<\/a><\/li>\n<p>\\t<\/p>\n<li>[4]. <a href=\"http:\/\/wiki.joanillo.org\/index.php\/Script_CNC_stroke\" title=\"cncstroke a wik.joanillo.org\">cncstroke a wiki.joanillo.org<\/a><\/li>\n<p>\\t<\/p>\n<li>[5]. <a href=\"http:\/\/www.joanillo.org\/?p=1493\">Millorant la conversi\u00f3 DXF a G-Code, II<\/a><\/li>\n<\/ul>\n<p><strong>Nota aclarativa<\/strong>:  En el projecte <strong>cncstroke<\/strong> utilitzem el terme <em>polil\u00ednia<\/em> com a successi\u00f3 de l\u00ednies enlla\u00e7ades. Ara b\u00e9, per generar aquestes l\u00ednies enlla\u00e7ades, a LibreCAD, utilitzem l'eina <em>l\u00ednia<\/em> (i no pas l'eina <em>polil\u00ednia<\/em>) (En una futura versi\u00f3 s'estudiar\u00e0 la possibilitat d'utilitzar l'eina <em>polil\u00ednia<\/em>, o ambdues).<\/p>\n<p><\/code><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Un dels treballs t\u00edpics que es fan amb la CNC \u00e9s el retrat de personatges en format blanc i negre. Per exemple, s\u00f3n coneguts els retrats del Che Guevara o l&#8217;Albert Einstein. Aquests dies estic treballant en la imatge de l&#8217;Ovidi Montllor [1]. La idea \u00e9s senzilla i coneguda. Importo la imatge en LibreCAD [2] [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":[],"categories":[33,18,16,36],"tags":[],"_links":{"self":[{"href":"https:\/\/www.joanillo.org\/index.php?rest_route=\/wp\/v2\/posts\/509"}],"collection":[{"href":"https:\/\/www.joanillo.org\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.joanillo.org\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.joanillo.org\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.joanillo.org\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=509"}],"version-history":[{"count":1,"href":"https:\/\/www.joanillo.org\/index.php?rest_route=\/wp\/v2\/posts\/509\/revisions"}],"predecessor-version":[{"id":510,"href":"https:\/\/www.joanillo.org\/index.php?rest_route=\/wp\/v2\/posts\/509\/revisions\/510"}],"wp:attachment":[{"href":"https:\/\/www.joanillo.org\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=509"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.joanillo.org\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=509"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.joanillo.org\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=509"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}