diff --git a/.github/workflows/CadZinho_CI.yml b/.github/workflows/CadZinho_CI.yml index 62b74e19..fa66764f 100644 --- a/.github/workflows/CadZinho_CI.yml +++ b/.github/workflows/CadZinho_CI.yml @@ -4,7 +4,7 @@ on: workflow_dispatch env: MAJOR: 0 - MINOR: 5 + MINOR: 6 MAN: 0 YEAR: 2024 LUA_V: 5.4.6 @@ -371,6 +371,8 @@ jobs: cp ./SDL2-${{ env.SDL_V }}/include/* ./glew-${{ env.GLEW_V }}/include/SDL2/ mv ./SDL2-${{ env.SDL_V }} ./SDL2 cp ./SDL2_net-${{ env.SDL_NET_V }}/include/* ./src/ + cp ./SDL2_net-${{ env.SDL_NET_V }}/include/* ./SDL2/include/ + cp ./SDL2_net-${{ env.SDL_NET_V }}/include/* ./glew-${{ env.GLEW_V }}/include/SDL2/ cp ./SDL2_net-${{ env.SDL_NET_V }}/lib/x64/* ./SDL2/ mv ./SDL2_net-${{ env.SDL_NET_V }}/lib ./lib mv ./glew-${{ env.GLEW_V }} ./glew @@ -469,7 +471,7 @@ jobs: steps: - uses: actions/checkout@v4.1.1 - uses: actions/download-artifact@v4.1.1 - - uses: softprops/action-gh-release@v0.1.15 + - uses: softprops/action-gh-release@v2.0.5 with: tag_name: ${{ env.MAJOR }}.${{ env.MINOR }}.${{ env.MAN }} draft: true diff --git a/.github/workflows/test2.yml b/.github/workflows/test2.yml index 800b7340..8b6e551d 100644 --- a/.github/workflows/test2.yml +++ b/.github/workflows/test2.yml @@ -4,94 +4,53 @@ on: workflow_dispatch env: MAJOR: 0 - MINOR: 4 + MINOR: 5 MAN: 0 - YEAR: 2023 + YEAR: 2024 + LUA_V: 5.4.6 + MESA_V: 23.1.1 + GLEW_V: 2.2.0 + SDL_V: 2.30.0 + SDL_NET_V: 2.2.0 + jobs: test: - runs-on: ubuntu-latest + runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v3 - - name: configure - run: | - sudo apt-get update - sudo apt-get install --yes libsdl2-dev libglvnd-dev libglew-dev fuse libfuse2 libarchive-tools - sudo gem install fpm + steps: + + - uses: actions/checkout@v4.1.1 + - name: configure SDK + uses: mymindstorm/setup-emsdk@v14 - name: download lua source - run: curl -R -O http://www.lua.org/ftp/lua-5.4.4.tar.gz + uses: suisei-cn/actions-download-file@v1.6.0 + with: + url: "http://www.lua.org/ftp/lua-${{ env.LUA_V }}.tar.gz" + target: . - name: extract lua - run: tar zxf lua-5.4.4.tar.gz + run: tar zxf lua-${{ env.LUA_V }}.tar.gz - name: remove main in lua - run: rm lua-5.4.4/src/lua.c lua-5.4.4/src/luac.c + run: rm lua-${{ env.LUA_V }}/src/lua.c lua-${{ env.LUA_V }}/src/luac.c - name: copy lua sources - run: cp lua-5.4.4/src/* ./src/ - - name: get make file - run: cp linux/Makefile ./Makefile - - name: make - run: make - - name: configure for fpm + run: cp lua-${{ env.LUA_V }}/src/* ./src/ + - name: clear samples run: | - mkdir pkg - mkdir pkg/usr - mkdir pkg/usr/bin - mkdir pkg/usr/share - mkdir pkg/usr/share/cadzinho - cp ./cadzinho ./pkg/usr/bin/ - cp -r ./linux/CadZinho/share/ ./pkg/usr/share/ - cp ./LICENSE.txt ./pkg/usr/share/cadzinho/ - cp -r ./lang/ ./pkg/usr/share/cadzinho/ - - name: Debian linux package + rm samples/*.pdf + rm samples/*.svg + rm samples/*.ps + rm samples/*.jpg + - name: get make and resources files run: | - cd ./pkg - fpm -s dir -t deb \ - --name cadzinho \ - --license MIT \ - --version $MAJOR.$MINOR.$MAN \ - --architecture native \ - --depends sdl2 --depends glew \ - --description "CadZinho - Minimalist computer aided design (CAD) software" \ - --url "https://github.com/zecruel/CadZinho" \ - --maintainer "Ezequiel Rabelo de Aguiar " ./ - cd .. - mv ./pkg/*.deb ./ - dpkg -c cadzinho_${{ env.MAJOR }}.${{ env.MINOR }}.${{ env.MAN }}_amd64.deb - - name: RedHat linux package - run: | - cd ./pkg - fpm -s dir -t rpm \ - --name cadzinho \ - --license MIT \ - --version $MAJOR.$MINOR.$MAN \ - --architecture native \ - --depends sdl2 --depends glew \ - --description "CadZinho - Minimalist computer aided design (CAD) software" \ - --url "https://github.com/zecruel/CadZinho" \ - --maintainer "Ezequiel Rabelo de Aguiar " ./ - cd .. - mv ./pkg/*.rpm ./ - - name: Arch linux package + cp emscripten/Makefile ./Makefile + cp emscripten/shell_minimal.html ./shell_minimal.html + - name: make + run: make + - name: create archive run: | - cd ./pkg - fpm -s dir -t pacman \ - --name cadzinho \ - --license MIT \ - --version $MAJOR.$MINOR.$MAN \ - --architecture native \ - --depends sdl2 --depends glew \ - --description "CadZinho - Minimalist computer aided design (CAD) software" \ - --url "https://github.com/zecruel/CadZinho" \ - --maintainer "Ezequiel Rabelo de Aguiar " ./ - cd .. - mv ./pkg/*.zst ./ - - name: List files - run: ls + zip -r emscripten cadzinho.js cadzinho.wasm cadzinho.html cadzinho.data - name: Upload the result - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4.3.0 with: - name: uploads - path: | - cadzinho-${{ env.MAJOR }}.${{ env.MINOR }}.${{ env.MAN }}-1-x86_64.pkg.tar.zst - cadzinho_${{ env.MAJOR }}.${{ env.MINOR }}.${{ env.MAN }}_amd64.deb - cadzinho-${{ env.MAJOR }}.${{ env.MINOR }}.${{ env.MAN }}-1.x86_64.rpm + name: emscripten + path: emscripten.zip retention-days: 5 diff --git a/emscripten/Makefile b/emscripten/Makefile index 6870822a..412508e3 100644 --- a/emscripten/Makefile +++ b/emscripten/Makefile @@ -1,7 +1,7 @@ SRC_PATH=./src/ CC=emcc COMPILER_FLAGS = -c -LINKER_FLAGS = -s USE_SDL=2 -s TOTAL_MEMORY=200MB -s STACK_SIZE=10MB -s ALLOW_MEMORY_GROWTH --preload-file lang --preload-file script --preload-file samples --shell-file shell_minimal.html +LINKER_FLAGS = -s USE_SDL=2 -s TOTAL_MEMORY=200MB -sFULL_ES2 -s STACK_SIZE=10MB -s ALLOW_MEMORY_GROWTH -s OFFSCREEN_FRAMEBUFFER --preload-file lang --preload-file script --preload-file samples --shell-file shell_minimal.html INCLUDE_PATHS = -I. -I./src/ -s USE_SDL=2 LIBRARY_PATHS = -L. EXE=cadzinho.html diff --git a/macos/CadZinho.app/Contents/Info.plist b/macos/CadZinho.app/Contents/Info.plist index 48b62645..86636022 100644 --- a/macos/CadZinho.app/Contents/Info.plist +++ b/macos/CadZinho.app/Contents/Info.plist @@ -19,11 +19,11 @@ CFBundlePackageType APPL CFBundleShortVersionString - 0.5.0 + 0.6.0 CFBundleSpokenName cad zinho CFBundleVersion - 0.5.0 + 0.6.0 NSHumanReadableCopyright CadZinho 2024 by Zecruel - MIT Licence diff --git a/src/draw_gl.c b/src/draw_gl.c index 81512ca8..3bf395e0 100644 --- a/src/draw_gl.c +++ b/src/draw_gl.c @@ -2,6 +2,13 @@ #include "gui.h" #define TOLERANCE 1e-6 +#ifdef __EMSCRIPTEN__ /* full HD */ + #define MAX_RESOL_X 1920 + #define MAX_RESOL_Y 1080 +#else /* 4K */ + #define MAX_RESOL_X 3840 + #define MAX_RESOL_Y 2160 +#endif /* mantain one unique element in a sorted array - array of integer values */ static int unique (int n, int * a) { @@ -173,10 +180,11 @@ int draw_gl_init (void *data, int clear){ /* init (or de-init) OpenGL */ #endif glLinkProgram(shaderProgram); glUseProgram(shaderProgram); - + /*texture */ - GLuint textures[2]; - glGenTextures(2, textures); + + GLuint textures[3]; + glGenTextures(3, textures); glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, textures[0]); @@ -199,7 +207,47 @@ int draw_gl_init (void *data, int clear){ /* init (or de-init) OpenGL */ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, gui->gl_ctx.tex_w, gui->gl_ctx.tex_h, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); - + + /* -------- frame buffer configuration --- */ + /* define max resolution to textures */ + glGetIntegerv(GL_MAX_VIEWPORT_DIMS, &gui->gl_ctx.fb_dims[0]); + gui->gl_ctx.fb_dims[0] = (gui->gl_ctx.fb_dims[0] < MAX_RESOL_X) ? gui->gl_ctx.fb_dims[0] : MAX_RESOL_X; + gui->gl_ctx.fb_dims[1] = (gui->gl_ctx.fb_dims[1] < MAX_RESOL_Y) ? gui->gl_ctx.fb_dims[1] : MAX_RESOL_Y; + + /* Create frame buffer */ + GLuint fbo = 0; + glGenFramebuffers(1, &fbo); + glBindFramebuffer(GL_FRAMEBUFFER, fbo); + + /* Create main texture to render drawing */ + glActiveTexture(GL_TEXTURE2); + glBindTexture(GL_TEXTURE_2D, textures[2]); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, gui->gl_ctx.fb_dims[0], gui->gl_ctx.fb_dims[1], 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); + /* attach it to currently bound framebuffer object */ + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, textures[2], 0); + + #ifndef __EMSCRIPTEN__ + /* The depth buffer */ + GLuint depthrenderbuffer; + glGenRenderbuffers(1, &depthrenderbuffer); + glBindRenderbuffer(GL_RENDERBUFFER, depthrenderbuffer); + glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT, gui->gl_ctx.fb_dims[0], gui->gl_ctx.fb_dims[1]); + /* attach it to currently bound framebuffer object */ + glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, depthrenderbuffer); + #endif + + if(glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE){ + printf("\nFail to generate frame buffer\n"); + } + glBindFramebuffer(GL_FRAMEBUFFER, 0); + gui->gl_ctx.fbo = fbo; + + /* -------- end frame buffer config --- */ + gui->gl_ctx.tex = textures[1]; gui->gl_ctx.tex_uni = glGetUniformLocation(shaderProgram, "tex"); @@ -1227,6 +1275,16 @@ int graph_draw_gl(graph_obj * master, struct ogl *gl_ctx, struct draw_param para /* verify if current graph is inside window*/ /* + x0 = xd0 * gl_ctx->transf[0][0] + yd0 * gl_ctx->transf[1][0] + zd0 * gl_ctx->transf[2][0] + gl_ctx->transf[3][0]; + y0 = xd0 * gl_ctx->transf[0][1] + yd0 * gl_ctx->transf[1][1] + zd0 * gl_ctx->transf[2][1] + gl_ctx->transf[3][1]; + z0 = xd0 * gl_ctx->transf[0][2] + yd0 * gl_ctx->transf[1][2] + zd0 * gl_ctx->transf[2][2] + gl_ctx->transf[3][2]; + x1 = xd1 * gl_ctx->transf[0][0] + yd1 * gl_ctx->transf[1][0] + zd1 * gl_ctx->transf[2][0] + gl_ctx->transf[3][0]; + y1 = xd1 * gl_ctx->transf[0][1] + yd1 * gl_ctx->transf[1][1] + zd1 * gl_ctx->transf[2][1] + gl_ctx->transf[3][1]; + z1 = xd1 * gl_ctx->transf[0][2] + yd1 * gl_ctx->transf[1][2] + zd1 * gl_ctx->transf[2][2] + gl_ctx->transf[3][2]; + + printf("corners = %.2f,%.2f,%.2f - %.2f,%.2f,%.2f\n", x0, y0, z0, x1, y1, z1); + */ + /* if ( (xd0 < 0 && xd1 < 0) || (xd0 > gl_ctx->win_w && xd1 > gl_ctx->win_w) || (yd0 < 0 && yd1 < 0) || @@ -1785,26 +1843,125 @@ int dxf_list_draw_gl(list_node *list, struct ogl *gl_ctx, struct draw_param par } } -int dxf_ents_draw_gl(dxf_drawing *drawing, struct ogl *gl_ctx, struct draw_param param){ - dxf_node *current = NULL; +dxf_node * dxf_ents_draw_gl(dxf_drawing *drawing, struct ogl *gl_ctx, dxf_node *current, struct draw_param param){ + //dxf_node *current = NULL; //int lay_idx = 0; + if (!drawing) return NULL; + if (!drawing->ents) return NULL; + if (!drawing->main_struct) return NULL; - if ((drawing->ents != NULL) && (drawing->main_struct != NULL)){ - current = drawing->ents->obj.content->next; + if (!current) current = drawing->ents->obj.content->next; - /* starts the content sweep */ - while (current != NULL){ - if (current->type == DXF_ENT){ /* DXF entity */ - /*verify if entity layer is on and thaw */ - if ((!drawing->layers[current->obj.layer].off) && - (!drawing->layers[current->obj.layer].frozen)){ - - /* draw each entity */ - graph_list_draw_gl2(current->obj.graphics, gl_ctx, param); - - } - } - current = current->next; - } - } + /* starts the content sweep */ + while (current != NULL && !gl_ctx->timer){ + if (current->type == DXF_ENT){ /* DXF entity */ + /*verify if entity layer is on and thaw */ + if ((!drawing->layers[current->obj.layer].off) && + (!drawing->layers[current->obj.layer].frozen)){ + + /* draw each entity */ + graph_list_draw_gl2(current->obj.graphics, gl_ctx, param); + + } + } + current = current->next; + } + + //if (gl_ctx->timer) { printf ("\nDraw too long\n");} + return current; + +} + +int dxf_draw_framebuffer(struct ogl *gl_ctx){ + + glBindFramebuffer(GL_FRAMEBUFFER, 0); + + /* prepare for new opengl commands */ + #ifndef GLES2 + if (gl_ctx->elems == NULL){ + gl_ctx->verts = glMapBuffer(GL_ARRAY_BUFFER, GL_WRITE_ONLY); + gl_ctx->elems = glMapBuffer(GL_ELEMENT_ARRAY_BUFFER, GL_WRITE_ONLY); + } + #endif + + glUniform1i(gl_ctx->tex_uni, 2); /* choose frame buffer texture with drawing rendered */ + + + /* create a quad for texture and store vertices - 4 vertices */ + /* 0 */ + int j = gl_ctx->vert_count; + gl_ctx->verts[j].pos[0] = 0.0; + gl_ctx->verts[j].pos[1] = 0.0; + gl_ctx->verts[j].pos[2] = 0.0; + gl_ctx->verts[j].norm[0] = 0.0; + gl_ctx->verts[j].norm[1] = 0.0; + gl_ctx->verts[j].norm[2] = 1.0; + gl_ctx->verts[j].col[0] = 255; + gl_ctx->verts[j].col[1] = 255; + gl_ctx->verts[j].col[2] = 255; + gl_ctx->verts[j].col[3] = 255; + gl_ctx->verts[j].uv[0] = 0.0; + gl_ctx->verts[j].uv[1] = 0.0; + gl_ctx->vert_count ++; + /* 1 */ + j = gl_ctx->vert_count; + gl_ctx->verts[j].pos[0] = 0.0; + gl_ctx->verts[j].pos[1] = (float) gl_ctx->fb_dims[1]; + gl_ctx->verts[j].pos[2] = 0.0; + gl_ctx->verts[j].norm[0] = 0.0; + gl_ctx->verts[j].norm[1] = 0.0; + gl_ctx->verts[j].norm[2] = 1.0; + gl_ctx->verts[j].col[0] = 255; + gl_ctx->verts[j].col[1] = 255; + gl_ctx->verts[j].col[2] = 255; + gl_ctx->verts[j].col[3] = 255; + gl_ctx->verts[j].uv[0] = 0.0; + gl_ctx->verts[j].uv[1] = 1.0; + gl_ctx->vert_count ++; + /* 2 */ + j = gl_ctx->vert_count; + gl_ctx->verts[j].pos[0] = (float) gl_ctx->fb_dims[0]; + gl_ctx->verts[j].pos[1] = 0.0; + gl_ctx->verts[j].pos[2] = 0.0; + gl_ctx->verts[j].norm[0] = 0.0; + gl_ctx->verts[j].norm[1] = 0.0; + gl_ctx->verts[j].norm[2] = 1.0; + gl_ctx->verts[j].col[0] = 255; + gl_ctx->verts[j].col[1] = 255; + gl_ctx->verts[j].col[2] = 255; + gl_ctx->verts[j].col[3] = 255; + gl_ctx->verts[j].uv[0] = 1.0; + gl_ctx->verts[j].uv[1] = 0.0; + gl_ctx->vert_count ++; + /* 3 */ + j = gl_ctx->vert_count; + gl_ctx->verts[j].pos[0] = (float) gl_ctx->fb_dims[0]; + gl_ctx->verts[j].pos[1] = (float) gl_ctx->fb_dims[1]; + gl_ctx->verts[j].pos[2] = 0.0; + gl_ctx->verts[j].norm[0] = 0.0; + gl_ctx->verts[j].norm[1] = 0.0; + gl_ctx->verts[j].norm[2] = 1.0; + gl_ctx->verts[j].col[0] = 255; + gl_ctx->verts[j].col[1] = 255; + gl_ctx->verts[j].col[2] = 255; + gl_ctx->verts[j].col[3] = 255; + gl_ctx->verts[j].uv[0] = 1.0; + gl_ctx->verts[j].uv[1] = 1.0; + gl_ctx->vert_count ++; + /* store vertex indexes in elements buffer - 2 triangles that share vertices */ + /* 0 */ + j = gl_ctx->elem_count * 3; + gl_ctx->elems[j] = gl_ctx->vert_count - 4; + gl_ctx->elems[j+1] = gl_ctx->vert_count - 3; + gl_ctx->elems[j+2] = gl_ctx->vert_count - 2; + /* 1 */ + gl_ctx->elems[j+3] = gl_ctx->vert_count - 3; + gl_ctx->elems[j+4] = gl_ctx->vert_count - 2; + gl_ctx->elems[j+5] = gl_ctx->vert_count - 1; + gl_ctx->elem_count+= 2; + + draw_gl (gl_ctx, 1); /* force draw and cleanup */ + glUniform1i(gl_ctx->tex_uni, 0); /* choose blank texture */ + + return 1; } \ No newline at end of file diff --git a/src/draw_gl.h b/src/draw_gl.h index 5b7f2134..2e8119a5 100644 --- a/src/draw_gl.h +++ b/src/draw_gl.h @@ -64,6 +64,11 @@ struct ogl { /* openGL context to pass main parameters */ GLfloat transf[4][4]; GLint model_uni; GLfloat model[3][3]; + + GLuint fbo; + GLuint fb_dims[2]; + + int timer; }; @@ -105,6 +110,8 @@ int graph_list_draw_gl2(list_node *list, struct ogl *gl_ctx, struct draw_param p int dxf_list_draw_gl(list_node *list, struct ogl *gl_ctx, struct draw_param param); -int dxf_ents_draw_gl(dxf_drawing *drawing, struct ogl *gl_ctx, struct draw_param param); +dxf_node * dxf_ents_draw_gl(dxf_drawing *drawing, struct ogl *gl_ctx, dxf_node *current, struct draw_param param); + +int dxf_draw_framebuffer(struct ogl *gl_ctx); #endif \ No newline at end of file diff --git a/src/dxf.c b/src/dxf.c index e797a824..1cc25550 100644 --- a/src/dxf.c +++ b/src/dxf.c @@ -2875,6 +2875,8 @@ dxf_node * dxf_find_dict(dxf_drawing *drawing, dxf_node * owner, char *name){ return NULL; /* error - not drawing */ if (!drawing->objs) return NULL; /* error - not drawing */ + if (!owner) + owner = drawing->main_dict; /* try to use main dictionary as owner */ if (!owner) return NULL; /* error - not owner */ if (owner->type != DXF_ENT) diff --git a/src/dxf.h b/src/dxf.h index 0b53f777..1fe6fb3c 100644 --- a/src/dxf.h +++ b/src/dxf.h @@ -18,7 +18,7 @@ #define DXF_MAX_PAT 12 #define DXF_POOL_PAGES 1000 -#define CZ_VERSION "0.5.0 - 2024" +#define CZ_VERSION "0.6.0 - 2024" extern strpool_t obj_pool; @@ -385,4 +385,4 @@ int dxf_find_last_blk (dxf_drawing *drawing, char *mark); dxf_node * dxf_find_dict(dxf_drawing *drawing, dxf_node * owner, char *name); -#endif \ No newline at end of file +#endif diff --git a/src/dxf_create.c b/src/dxf_create.c index a7ad199d..2de56c10 100644 --- a/src/dxf_create.c +++ b/src/dxf_create.c @@ -3203,28 +3203,28 @@ dxf_node * dxf_new_xrecord (dxf_drawing *drawing, dxf_node *owner, char *name){ if (hdl_obj) handle = (char*) strpool_cstr2( &value_pool, hdl_obj->value.str); - /* create a new DICTIONARY object */ + /* create a new XRECORD object */ const char *dxf_class = "AcDbXrecord"; int ok = 1; - dxf_node * new_dict = dxf_obj_new ("XRECORD", drawing->pool); - if (!new_dict) return NULL; /* error */ + dxf_node * new_xrec = dxf_obj_new ("XRECORD", drawing->pool); + if (!new_xrec) return NULL; /* error */ - ok &= dxf_attr_append(new_dict, 5, (void *) zero, drawing->pool); - ok &= dxf_attr_append(new_dict, 330, (void *) handle, drawing->pool); - ok &= dxf_attr_append(new_dict, 100, (void *) dxf_class, drawing->pool); - ok &= dxf_attr_append(new_dict, 281, (void *) (int[]){1}, drawing->pool); + ok &= dxf_attr_append(new_xrec, 5, (void *) zero, drawing->pool); + ok &= dxf_attr_append(new_xrec, 330, (void *) handle, drawing->pool); + ok &= dxf_attr_append(new_xrec, 100, (void *) dxf_class, drawing->pool); + ok &= dxf_attr_append(new_xrec, 281, (void *) (int[]){1}, drawing->pool); if(!ok) return NULL; - if(!ent_handle(drawing, new_dict)) return NULL; - dxf_obj_append(drawing->objs, new_dict); + if(!ent_handle(drawing, new_xrec)) return NULL; + dxf_obj_append(drawing->objs, new_xrec); - hdl_obj = dxf_find_attr2(new_dict, 5); + hdl_obj = dxf_find_attr2(new_xrec, 5); if (hdl_obj) handle = (char*) strpool_cstr2( &value_pool, hdl_obj->value.str); dxf_attr_append(owner, 3, (void *) name, drawing->pool); dxf_attr_append(owner, 350, (void *) handle, drawing->pool); - return new_dict; + return new_xrec; } int dxf_xrecord_append (dxf_node *owner, int group, void *value, int pool){ diff --git a/src/gui.c b/src/gui.c index 8bf72ca6..e53bf20e 100644 --- a/src/gui.c +++ b/src/gui.c @@ -33,6 +33,19 @@ void sel_list_clear (gui_obj *gui){ list_mem_pool(ZERO_LIST, SEL_LIFE); } +int gui_timer_thread(void* data){ + gui_obj *gui = (gui_obj *) data; + int delay; + while (gui->running){ + //Lock + SDL_SemWait( gui->timer_sem ); + delay = gui->delay - 2; + delay = (delay > 0) ? delay : 1; + SDL_Delay(gui->delay); + gui->gl_ctx.timer = 1; + } +} + /* *********************************************************** the fowling functions are for rendering text in gui, by rastering each glyphs in a monochrome image in memory. */ @@ -1974,6 +1987,11 @@ int gui_start(gui_obj *gui){ gui->grid_flags = 0; gui->grid_spc = 20.0; + + gui->gl_ctx.timer = 0; + gui->timer_sem = SDL_CreateSemaphore( 0 ); + gui->timer_thread_id = SDL_CreateThread( gui_timer_thread, + "gui_timer_thread", (void*)gui ); memset(gui->blank_tex, 0, 4*20*600); diff --git a/src/gui.h b/src/gui.h index 39cd06ff..a31479e9 100644 --- a/src/gui.h +++ b/src/gui.h @@ -533,6 +533,8 @@ struct Gui_obj { int grid_flags; double grid_spc; + SDL_Thread* timer_thread_id; + SDL_sem* timer_sem; }; typedef struct Gui_obj gui_obj; diff --git a/src/gui_loop.c b/src/gui_loop.c index 545cfbd6..054b3010 100644 --- a/src/gui_loop.c +++ b/src/gui_loop.c @@ -48,7 +48,14 @@ int gui_main_loop (gui_obj *gui) { static char function_key[20] = ""; - static int update_title = 0, changed = 0; + static int update_title = 0, changed = 0, framebuf = 1; + + static double prev_ofs_x, prev_ofs_y, prev_zoom; + static float prev_model_view[3][3]; + + static struct do_entry *prev_do = NULL; //gui->list_do.current; + + static dxf_node *curr_ent = NULL; static int open_prg = 0; static int progr_win = 0; @@ -430,12 +437,19 @@ int gui_main_loop (gui_obj *gui) { } break; case SDL_WINDOWEVENT: - if (event.window.event == SDL_WINDOWEVENT_RESIZED){ - gui->draw = 1; - } - if (event.window.event == SDL_WINDOWEVENT_SIZE_CHANGED){ - gui->draw = 1; - } + //if (event.window.event == SDL_WINDOWEVENT_RESIZED || + // event.window.event == SDL_WINDOWEVENT_SIZE_CHANGED) + //{ + /*get current window size and position*/ + SDL_GetWindowSize(gui->window, &gui->win_w, &gui->win_h); + SDL_GetWindowPosition (gui->window, &gui->win_x, &gui->win_y); + gui->win_w = (gui->win_w < gui->gl_ctx.fb_dims[0]) ? gui->win_w : gui->gl_ctx.fb_dims[0]; + gui->win_h = (gui->win_h < gui->gl_ctx.fb_dims[1]) ? gui->win_h : gui->gl_ctx.fb_dims[1]; + SDL_SetWindowSize(gui->window, gui->win_w, gui->win_h); + + + gui->draw = 1; + //} break; case SDL_DISPLAYEVENT: { @@ -684,6 +698,7 @@ int gui_main_loop (gui_obj *gui) { gui->zoom = 800.0 / h; gui->ofs_x = x - (gui->win_w - 800 * ar)/(2.0 * gui->zoom); gui->ofs_y = y - h / 2.0; + gui->draw = 2; } else gui->action = VIEW_ZOOM_EXT; @@ -711,6 +726,8 @@ int gui_main_loop (gui_obj *gui) { else gui->low_proc = 1; + + /*===============================*/ if(gui->action == EXIT) { gui->running = 0; @@ -1035,7 +1052,7 @@ int gui_main_loop (gui_obj *gui) { else if(gui->action == VIEW_ZOOM_EXT){ gui->action = NONE; zoom_ext(gui->drawing, 0, 0, gui->win_w, gui->win_h, &gui->zoom, &gui->ofs_x, &gui->ofs_y); - gui->draw = 1; + gui->draw = 2; } else if(gui->action == VIEW_ZOOM_P){ gui->action = NONE; @@ -1079,7 +1096,7 @@ int gui_main_loop (gui_obj *gui) { dxf_ents_parse(gui->drawing); - gui->draw = 1; + gui->draw = 2; } else if((gui->action == YANK || gui->action == CUT) && strlen(gui->clip_path) > 0) { if (gui->sel_list->next){ /* verify if has elements in list */ @@ -1213,7 +1230,7 @@ int gui_main_loop (gui_obj *gui) { else{ snprintf(gui->log_msg, 63, "No actions to undo"); } - gui->draw = 1; + gui->draw = 2; } else if(gui->action == REDO){ @@ -1226,7 +1243,7 @@ int gui_main_loop (gui_obj *gui) { else{ snprintf(gui->log_msg, 63, "No actions to redo"); } - gui->draw = 1; + gui->draw = 2; } else if(gui->action == LAYER_CHANGE){ @@ -1258,7 +1275,7 @@ int gui_main_loop (gui_obj *gui) { current = current->next; } } - gui->draw = 1; + gui->draw = 2; } else if(gui->action == COLOR_CHANGE){ @@ -1288,7 +1305,7 @@ int gui_main_loop (gui_obj *gui) { current = current->next; } } - gui->draw = 1; + gui->draw = 2; } else if(gui->action == LTYPE_CHANGE){ gui->action = NONE; @@ -1318,7 +1335,7 @@ int gui_main_loop (gui_obj *gui) { current = current->next; } } - gui->draw = 1; + gui->draw = 2; } else if(gui->action == LW_CHANGE){ gui->action = NONE; @@ -1347,7 +1364,7 @@ int gui_main_loop (gui_obj *gui) { current = current->next; } } - gui->draw = 1; + gui->draw = 2; } /**********************************/ @@ -1471,21 +1488,19 @@ int gui_main_loop (gui_obj *gui) { file_path_len = strlen(file_path); } - if (gui_check_draw(gui) != 0){ + if (gui_check_draw(gui) != 0 && gui->draw == 0){ gui->draw = 1; } + if(memcmp(prev_model_view, gui->model_view, sizeof(prev_model_view))){ + gui->draw = 2; + } - if (gui->draw != 0){ - /*get current window size and position*/ - SDL_GetWindowSize(gui->window, &gui->win_w, &gui->win_h); - SDL_GetWindowPosition (gui->window, &gui->win_x, &gui->win_y); - - - glUniform1i(gui->gl_ctx.tex_uni, 0); - - SDL_GetWindowSize(gui->window, &gui->gl_ctx.win_w, &gui->gl_ctx.win_h); - glViewport(0, 0, gui->gl_ctx.win_w, gui->gl_ctx.win_h); + if (gui->draw != 0 || curr_ent){ + d_param.w = gui->win_w; + d_param.h = gui->win_h; + gui->gl_ctx.win_w = gui->win_w; + gui->gl_ctx.win_h = gui->win_h; d_param.ofs_x = gui->ofs_x; d_param.ofs_y = gui->ofs_y; d_param.ofs_z = 0; @@ -1536,6 +1551,61 @@ int gui_main_loop (gui_obj *gui) { glDepthFunc(GL_LEQUAL); + /* ---------Render drawing in frame buffer ----------*/ + if (prev_ofs_x != gui->ofs_x || prev_ofs_y != gui->ofs_y || + prev_zoom != gui->zoom || prev_do != gui->list_do.current || + gui->draw == 2) + { /* check if render is needed */ + glBindFramebuffer(GL_FRAMEBUFFER, gui->gl_ctx.fbo); + glViewport(0, 0, gui->gl_ctx.win_w, gui->gl_ctx.win_h); + + /* Clear the screen to transparent color */ + glClearColor(1.0, 1.0, 1.0, 0.0); + glClear(GL_COLOR_BUFFER_BIT| GL_DEPTH_BUFFER_BIT); + #ifndef GLES2 + if (gui->gl_ctx.elems == NULL){ + gui->gl_ctx.verts = glMapBuffer(GL_ARRAY_BUFFER, GL_WRITE_ONLY); + gui->gl_ctx.elems = glMapBuffer(GL_ELEMENT_ARRAY_BUFFER, GL_WRITE_ONLY); + } + #endif + gui->gl_ctx.vert_count = 0; + gui->gl_ctx.elem_count = 0; + glUniform1i(gui->gl_ctx.tex_uni, 0); + + gui->gl_ctx.timer = 0; + SDL_SemPost( gui->timer_sem ); + + curr_ent = dxf_ents_draw_gl(gui->drawing, &gui->gl_ctx, NULL, d_param); + + draw_gl (&gui->gl_ctx, 1); /* force draw and cleanup */ + } + else if (curr_ent){ /* check if render is needed - pending entities */ + glBindFramebuffer(GL_FRAMEBUFFER, gui->gl_ctx.fbo); + glViewport(0, 0, gui->gl_ctx.win_w, gui->gl_ctx.win_h); + + + #ifndef GLES2 + if (gui->gl_ctx.elems == NULL){ + gui->gl_ctx.verts = glMapBuffer(GL_ARRAY_BUFFER, GL_WRITE_ONLY); + gui->gl_ctx.elems = glMapBuffer(GL_ELEMENT_ARRAY_BUFFER, GL_WRITE_ONLY); + } + #endif + gui->gl_ctx.vert_count = 0; + gui->gl_ctx.elem_count = 0; + glUniform1i(gui->gl_ctx.tex_uni, 0); + + gui->gl_ctx.timer = 0; + SDL_SemPost( gui->timer_sem ); + + curr_ent = dxf_ents_draw_gl(gui->drawing, &gui->gl_ctx, curr_ent, d_param); + + draw_gl (&gui->gl_ctx, 1); /* force draw and cleanup */ + } + glBindFramebuffer(GL_FRAMEBUFFER, 0); + glViewport(0, 0, gui->gl_ctx.win_w, gui->gl_ctx.win_h); + + /*------Draw frame buffer------*/ + /* Clear the screen to background color */ glClearColor((GLfloat) gui->background.r/255, (GLfloat) gui->background.g/255, (GLfloat) gui->background.b/255, 1.0); @@ -1548,23 +1618,79 @@ int gui_main_loop (gui_obj *gui) { #endif gui->gl_ctx.vert_count = 0; gui->gl_ctx.elem_count = 0; + + gui->gl_ctx.transf[0][0] = 1.0; + gui->gl_ctx.transf[0][1] = 0.0; + gui->gl_ctx.transf[0][2] = 0.0; + gui->gl_ctx.transf[0][3] = 0.0; + gui->gl_ctx.transf[1][0] = 0.0; + gui->gl_ctx.transf[1][1] = 1.0; + gui->gl_ctx.transf[1][2] = 0.0; + gui->gl_ctx.transf[1][3] = 0.0; + gui->gl_ctx.transf[2][0] = 0.0; + gui->gl_ctx.transf[2][1] = 0.0; + gui->gl_ctx.transf[2][2] = 1.0; + gui->gl_ctx.transf[2][3] = 0.0; + gui->gl_ctx.transf[3][0] = 0.0; + gui->gl_ctx.transf[3][1] = 0.0; + gui->gl_ctx.transf[3][2] = 0.0; + gui->gl_ctx.transf[3][3] = 1.0; + + gui->gl_ctx.model[0][0] = 1.0; + gui->gl_ctx.model[0][1] = 0.0; + gui->gl_ctx.model[0][2] = 0.0; + gui->gl_ctx.model[1][0] = 0.0; + gui->gl_ctx.model[1][1] = 1.0; + gui->gl_ctx.model[1][2] = 0.0; + gui->gl_ctx.model[2][0] = 0.0; + gui->gl_ctx.model[2][1] = 0.0; + gui->gl_ctx.model[2][2] = 1.0; + + + dxf_draw_framebuffer(&gui->gl_ctx); //----------- + glUniform1i(gui->gl_ctx.tex_uni, 0); + /* 3D test */ + gui->gl_ctx.transf[0][0] = gui->drwg_view[0][0]; + gui->gl_ctx.transf[0][1] = gui->drwg_view[0][1]; + gui->gl_ctx.transf[0][2] = gui->drwg_view[0][2]; + gui->gl_ctx.transf[0][3] = gui->drwg_view[0][3]; + gui->gl_ctx.transf[1][0] = gui->drwg_view[1][0]; + gui->gl_ctx.transf[1][1] = gui->drwg_view[1][1]; + gui->gl_ctx.transf[1][2] = gui->drwg_view[1][2]; + gui->gl_ctx.transf[1][3] = gui->drwg_view[1][3]; + gui->gl_ctx.transf[2][0] = gui->drwg_view[2][0]; + gui->gl_ctx.transf[2][1] = gui->drwg_view[2][1]; + gui->gl_ctx.transf[2][2] = gui->drwg_view[2][2]; + gui->gl_ctx.transf[2][3] = gui->drwg_view[2][3]; + gui->gl_ctx.transf[3][0] = gui->drwg_view[3][0]; + gui->gl_ctx.transf[3][1] = gui->drwg_view[3][1]; + gui->gl_ctx.transf[3][2] = gui->drwg_view[3][2]; + gui->gl_ctx.transf[3][3] = gui->drwg_view[3][3]; + + gui->gl_ctx.model[0][0] = gui->model_view[0][0]; + gui->gl_ctx.model[0][1] = gui->model_view[0][1]; + gui->gl_ctx.model[0][2] = gui->model_view[0][2]; + gui->gl_ctx.model[1][0] = gui->model_view[1][0]; + gui->gl_ctx.model[1][1] = gui->model_view[1][1]; + gui->gl_ctx.model[1][2] = gui->model_view[1][2]; + gui->gl_ctx.model[2][0] = gui->model_view[2][0]; + gui->gl_ctx.model[2][1] = gui->model_view[2][1]; + gui->gl_ctx.model[2][2] = gui->model_view[2][2]; + + glDepthFunc(GL_ALWAYS); + /* draw grid */ if (gui->grid_flags) draw_grid_gl(gui); draw_orign_gl(gui); - dxf_ents_draw_gl(gui->drawing, &gui->gl_ctx, d_param); - if (!gui->pan_mode) draw_cursor_gl(gui, gui->mouse_x, gui->mouse_y, gui->cursor); draw_gl (&gui->gl_ctx, 1); /* force draw and cleanup */ //glReadPixels(gui->mouse_x, gui->mouse_y, 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT, &gui->mouse_z); - glDepthFunc(GL_ALWAYS); - - /*hilite test */ if((gui->draw_tmp)&&(gui->element != NULL)){ gui->element->obj.graphics = dxf_graph_parse(gui->drawing, gui->element, 0 , 1); @@ -1675,5 +1801,11 @@ int gui_main_loop (gui_obj *gui) { } #endif + prev_ofs_x = gui->ofs_x; + prev_ofs_y = gui->ofs_y; + prev_zoom = gui->zoom; + prev_do = gui->list_do.current; + memcpy(prev_model_view, gui->model_view, sizeof(prev_model_view)); + return gui->running; } \ No newline at end of file diff --git a/src/gui_script.c b/src/gui_script.c index db914d7a..4a68ad89 100644 --- a/src/gui_script.c +++ b/src/gui_script.c @@ -1027,6 +1027,14 @@ int gui_script_prepare (gui_obj *gui, struct script_obj *script) { {"last_blk", script_last_blk}, {"pdf_new", script_pdf_new}, + + {"get_head_var", script_get_head_var}, + + {"get_dict", script_get_dict}, + {"set_dict", script_set_dict}, + {"set_dict_var", script_set_dict_var}, + {"set_xrec", script_set_xrec}, + {NULL, NULL} }; luaL_newlib(T, cz_lib); diff --git a/src/main.c b/src/main.c index bb385dbb..e1b1fe30 100644 --- a/src/main.c +++ b/src/main.c @@ -351,7 +351,7 @@ int main(int argc, char** argv){ /* ------------------------------ opengl --------------------------------------*/ gui->gl_ctx.ctx = SDL_GL_CreateContext(gui->window); #endif - + draw_gl_init ((void *)gui, 0); /* ------------------------------------------------------------------------------- */ @@ -672,6 +672,10 @@ int main(int argc, char** argv){ SDL_WaitThread(gui->debug_thread_id, NULL); SDLNet_Quit(); + + SDL_SemPost( gui->timer_sem ); + SDL_WaitThread(gui->timer_thread_id, NULL); + SDL_DestroySemaphore( gui->timer_sem ); /* safe quit */ diff --git a/src/script.c b/src/script.c index b380adca..4ba4713a 100644 --- a/src/script.c +++ b/src/script.c @@ -8227,5 +8227,470 @@ int script_do_changes (lua_State *L) { } + return 1; +} + +/* get drawing head variable */ +/* given parameters: + - Variable name, as string +returns: + - variable value, or nil if fails +*/ +int script_get_head_var (lua_State *L) { + /* get gui object from Lua instance */ + lua_pushstring(L, "cz_gui"); /* is indexed as "cz_gui" */ + lua_gettable(L, LUA_REGISTRYINDEX); + gui_obj *gui = lua_touserdata (L, -1); + lua_pop(L, 1); + + /* verify if gui is valid */ + if (!gui){ + lua_pushliteral(L, "Auto check: no access to CadZinho enviroment"); + lua_error(L); + } + + + /* verify passed arguments */ + int n = lua_gettop(L); /* number of arguments */ + if (n < 1){ + lua_pushliteral(L, "get_head_vart: invalid number of arguments"); + lua_error(L); + } + if (!lua_isstring(L, 1)) { + lua_pushliteral(L, "get_head_vart: incorrect argument type"); + lua_error(L); + } + + char name [DXF_MAX_CHARS + 1]; + + strncpy(name, lua_tostring(L, 1), DXF_MAX_CHARS); /* preserve original string */ + str_upp(name); /*upper case */ + + /* look for header variable */ + dxf_node *start = NULL, *end = NULL; + if(dxf_find_head_var(gui->drawing->head, name, &start, &end)){ + /* variable exists */ + if (end){ + if (end->type == DXF_ATTR){ + /* identify the type of attrib, according DXF group specification */ + int type = dxf_ident_attr_type(end->value.group); + if (type == DXF_FLOAT){ + lua_pushnumber(L, end->value.d_data); + return 1; + } + else if (type == DXF_INT){ + lua_pushinteger(L, end->value.i_data); + return 1; + } + else if (type == DXF_STR){ + if (end->value.group == 2 || (end->value.group > 5 && end->value.group < 9) ){ + lua_pushstring(L, strpool_cstr2( &name_pool, end->value.str)); + } else { + lua_pushstring(L, strpool_cstr2( &value_pool, end->value.str)); + } + return 1; + } + } + } + } + + lua_pushnil(L); /* fail to get variable */ + return 1; +} + +/* get a named data of an dictionary */ +/* given parameters: + - name of data, as string + - name of owner dictionary, as string +returns: + - table with data +*/ +int script_get_dict (lua_State *L) { + /* get gui object from Lua instance */ + lua_pushstring(L, "cz_gui"); /* is indexed as "cz_gui" */ + lua_gettable(L, LUA_REGISTRYINDEX); + gui_obj *gui = lua_touserdata (L, -1); + lua_pop(L, 1); + + /* verify if gui is valid */ + if (!gui){ + lua_pushliteral(L, "Auto check: no access to CadZinho enviroment"); + lua_error(L); + } + + /* verify passed arguments */ + int n = lua_gettop(L); /* number of arguments */ + if (n < 1){ + lua_pushliteral(L, "get_dict: invalid number of arguments"); + lua_error(L); + } + if (!lua_isstring(L, 1)) { + lua_pushliteral(L, "get_dict: incorrect argument type"); + lua_error(L); + } + + lua_newtable(L); /* table to store data */ + + dxf_node * owner = NULL; /* default owner is main dictionary */ + + if (lua_isstring(L, 2)) { /* Owner dictionary */ + /* try to find owner in main dictionary */ + owner = dxf_find_dict(gui->drawing, NULL, (char*)lua_tostring(L, 2)); + if (!owner) return 1; /* fail */ + } + + /* try to find data obj in owner dictionary */ + dxf_node * data = dxf_find_dict(gui->drawing, owner, (char*)lua_tostring(L, 1)); + if (!data) return 1; /* fail */ + + + STRPOOL_U64 xrec = strpool_inject(&obj_pool, "XRECORD", 7); + STRPOOL_U64 dvar = strpool_inject(&obj_pool, "DICTIONARYVAR", 13); + + if (data->obj.id == dvar){ /* data is a DICTIONARYVAR */ + data = dxf_find_attr2(data, 1); + if (data){ + lua_newtable(L); /* table to store data */ + lua_pushstring(L, "group"); + lua_pushinteger(L, 1); + lua_rawset(L, -3); /* store in table */ + + lua_pushstring(L, "value"); + lua_pushstring(L, strpool_cstr2( &value_pool, data->value.str)); + lua_rawset(L, -3); /* store in table */ + + lua_rawseti(L, -2, 1); /* store to main table */ + } + } + else if (data->obj.id == xrec){ /* data is a XRECORD */ + data = dxf_find_attr2(data, 281); + if (data) data = data->next; + int num_data = 0, type; + while (data){ + if (data->type == DXF_ATTR){ + lua_newtable(L); /* table to store data */ + lua_pushstring(L, "group"); + lua_pushinteger(L, data->value.group); + lua_rawset(L, -3); /* store in table */ + + lua_pushstring(L, "value"); + /* identify the type of attrib, according DXF group specification */ + type = dxf_ident_attr_type(data->value.group); + switch(type) { + /* change the data */ + case DXF_FLOAT : + lua_pushnumber(L, data->value.d_data); + break; + case DXF_INT : + lua_pushinteger(L, data->value.i_data); + break; + case DXF_STR : + if (data->value.group == 2 || (data->value.group > 5 && data->value.group < 9) ){ + lua_pushstring(L, strpool_cstr2( &name_pool, data->value.str)); + } else { + lua_pushstring(L, strpool_cstr2( &value_pool, data->value.str)); + } + } + lua_rawset(L, -3); /* store in table */ + num_data++; + lua_rawseti(L, -2, num_data); /* store to main table */ + } + else break; /* breaks if is found a entity */ + data = data->next; + } + } + else { /* not supported data object */ + return 1; + } + + + return 1; +} + +/* set DICTIONARY to the drawing */ +/* given parameters: + - dict name, as string +returns: + - success, as boolean +*/ +int script_set_dict (lua_State *L) { + /* get gui object from Lua instance */ + lua_pushstring(L, "cz_gui"); /* is indexed as "cz_gui" */ + lua_gettable(L, LUA_REGISTRYINDEX); + gui_obj *gui = lua_touserdata (L, -1); + lua_pop(L, 1); + + /* verify if gui is valid */ + if (!gui){ + lua_pushliteral(L, "Auto check: no access to CadZinho enviroment"); + lua_error(L); + } + + /* verify passed arguments */ + if (!lua_isstring(L, 1)) { + lua_pushliteral(L, "set_dict: incorrect argument type"); + lua_error(L); + } + + char dict [DXF_MAX_CHARS + 1]; + + strncpy(dict, lua_tostring(L, 1), DXF_MAX_CHARS); /* preserve original string */ + //str_upp(dict); /*upper case */ + + char *new_str; + new_str = trimwhitespace(dict); + /* verify if dict name contain spaces */ + if (strchr(new_str, ' ')){ + lua_pushliteral(L, "new_dict: No spaces allowed in dict"); + lua_error(L); + } + + /* check if exists an dict with same name */ + if (dxf_find_dict(gui->drawing, NULL, new_str)){ + lua_pushboolean(L, 1); /* return success */ + return 1; + } + + if (dxf_new_dict (gui->drawing, NULL, new_str)){ + lua_pushboolean(L, 1); /* return success */ + return 1; + } + + + lua_pushboolean(L, 0); /* return fail */ + return 1; +} + +/* set a DICTIONARYVAR to the drawing (create or change value) */ +/* given parameters: + - dict name, as string + - key, as string + - value, as string +returns: + - success, as boolean +*/ +int script_set_dict_var (lua_State *L) { + /* get gui object from Lua instance */ + lua_pushstring(L, "cz_gui"); /* is indexed as "cz_gui" */ + lua_gettable(L, LUA_REGISTRYINDEX); + gui_obj *gui = lua_touserdata (L, -1); + lua_pop(L, 1); + + /* verify if gui is valid */ + if (!gui){ + lua_pushliteral(L, "Auto check: no access to CadZinho enviroment"); + lua_error(L); + } + + /* verify passed arguments */ + int n = lua_gettop(L); /* number of arguments */ + if (n < 3){ + lua_pushliteral(L, "set_dict_var: invalid number of arguments"); + lua_error(L); + } + if (!lua_isstring(L, 1)) { + lua_pushliteral(L, "set_dict_var: incorrect argument type"); + lua_error(L); + } + if (!lua_isstring(L, 2)) { + lua_pushliteral(L, "set_dict_var: incorrect argument type"); + lua_error(L); + } + if (!lua_isstring(L, 3)) { + lua_pushliteral(L, "set_dict_var: incorrect argument type"); + lua_error(L); + } + + /* check if dict exists */ + dxf_node * owner, * data; + if (!(owner = dxf_find_dict(gui->drawing, NULL, (char*)lua_tostring(L, 1)))){ + lua_pushboolean(L, 0); /* return fail */ + return 1; + } + + /* check if already exists */ + if (data = dxf_find_dict(gui->drawing, owner, (char*)lua_tostring(L, 2))){ + STRPOOL_U64 dvar = strpool_inject(&obj_pool, "DICTIONARYVAR", 13); + if (data->obj.id == dvar){ /* check if a DICTIONARYVAR */ + data = dxf_find_attr2(data, 1); + if (data){ + size_t len; + const char * txt = lua_tolstring(L, 3, &len); + STRPOOL_U64 value = strpool_inject(&value_pool, txt, len); + data->value.str = value; + lua_pushboolean(L, 1); /* return success */ + return 1; + } + } + } + + /* create a new one */ + else if (dxf_new_dict_var (gui->drawing, owner, (char*)lua_tostring(L, 2), + (char*)lua_tostring(L, 3))){ + lua_pushboolean(L, 1); /* return success */ + return 1; + } + + lua_pushboolean(L, 0); /* return fail */ + return 1; +} + +/* set a XRECORD to the drawing (create or change) */ +/* given parameters: + - dict name, as string + - key, as string + - data values, as table (elements in table are tables too, + with "group" and "value" labeled DXF pairs) +returns: + - success, as boolean +*/ +int script_set_xrec (lua_State *L) { + /* get gui object from Lua instance */ + lua_pushstring(L, "cz_gui"); /* is indexed as "cz_gui" */ + lua_gettable(L, LUA_REGISTRYINDEX); + gui_obj *gui = lua_touserdata (L, -1); + lua_pop(L, 1); + + /* verify if gui is valid */ + if (!gui){ + lua_pushliteral(L, "Auto check: no access to CadZinho enviroment"); + lua_error(L); + } + + /* verify passed arguments */ + int n = lua_gettop(L); /* number of arguments */ + if (n < 3){ + lua_pushliteral(L, "set_dict_var: invalid number of arguments"); + lua_error(L); + } + if (!lua_isstring(L, 1)) { + lua_pushliteral(L, "set_dict_var: incorrect argument type"); + lua_error(L); + } + if (!lua_isstring(L, 2)) { + lua_pushliteral(L, "set_dict_var: incorrect argument type"); + lua_error(L); + } + if (!lua_istable(L, 3)) { + lua_pushliteral(L, "set_dict_var: incorrect argument type"); + lua_error(L); + } + + /* check if dict exists */ + dxf_node * owner, * data; + if (!(owner = dxf_find_dict(gui->drawing, NULL, (char*)lua_tostring(L, 1)))){ + lua_pushboolean(L, 0); /* return fail */ + return 1; + } + + /* check if already exists */ + if (data = dxf_find_dict(gui->drawing, owner, (char*)lua_tostring(L, 2))){ + STRPOOL_U64 xrec = strpool_inject(&obj_pool, "XRECORD", 7); + if (data->obj.id == xrec){ /* check if a XRECORD */ + /* clear previous data */ + dxf_node *current = NULL; + current = dxf_find_attr2(data, 281); + if (current) current = current->next; + while (current){ + if (current->type == DXF_ATTR){ + dxf_obj_subst(current, NULL); /* remove data*/ + } + /* breaks if is found a entity */ + else break; + current = current->next; + } + + int group, type, val_i; + double val_d; + + /* iterate over table */ + lua_pushnil(L); /* first key */ + while (lua_next(L, 3) != 0) { + /* uses 'key' (at index -2) and 'value' (at index -1) */ + if (lua_istable(L, -1)){ + /* get vertex coordinates */ + lua_getfield(L, -1, "group"); + group = lua_tonumber(L, -1); + lua_pop(L, 1); + lua_getfield(L, -1, "value"); + //value = lua_tonumber(L, -1); + /* identify the type of attrib, according DXF group specification */ + type = dxf_ident_attr_type(group); + switch(type) { + /* change the data */ + case DXF_FLOAT : + val_d = lua_tonumber(L, -1); + dxf_xrecord_append (data, group, (void*)&val_d, + gui->drawing->pool); + break; + case DXF_INT : + val_i = lua_tonumber(L, -1); + dxf_xrecord_append (data, group, (void*)&val_i, + gui->drawing->pool); + break; + case DXF_STR : + dxf_xrecord_append (data, group, (void*)lua_tostring(L, -1), + gui->drawing->pool); + } + lua_pop(L, 1); + } + /* removes 'value'; keeps 'key' for next iteration */ + lua_pop(L, 1); + } + + + lua_pushboolean(L, 1); /* return success */ + return 1; + + } + } + + /* create a new one */ + else if (data = dxf_new_xrecord (gui->drawing, owner, + (char*)lua_tostring(L, 2))) + { + int group, type, val_i; + double val_d; + + /* iterate over table */ + lua_pushnil(L); /* first key */ + while (lua_next(L, 3) != 0) { + /* uses 'key' (at index -2) and 'value' (at index -1) */ + if (lua_istable(L, -1)){ + /* get vertex coordinates */ + lua_getfield(L, -1, "group"); + group = lua_tonumber(L, -1); + lua_pop(L, 1); + lua_getfield(L, -1, "value"); + /* identify the type of attrib, according DXF group specification */ + type = dxf_ident_attr_type(group); + switch(type) { + /* change the data */ + case DXF_FLOAT : + val_d = lua_tonumber(L, -1); + dxf_xrecord_append (data, group, (void*)&val_d, + gui->drawing->pool); + break; + case DXF_INT : + val_i = lua_tonumber(L, -1); + dxf_xrecord_append (data, group, (void*)&val_i, + gui->drawing->pool); + break; + case DXF_STR : + dxf_xrecord_append (data, group, (void*)lua_tostring(L, -1), + gui->drawing->pool); + } + lua_pop(L, 1); + } + /* removes 'value'; keeps 'key' for next iteration */ + lua_pop(L, 1); + } + + + lua_pushboolean(L, 1); /* return success */ + return 1; + } + + lua_pushboolean(L, 0); /* return fail */ return 1; } \ No newline at end of file diff --git a/src/script.h b/src/script.h index 1d379a30..22a56d46 100644 --- a/src/script.h +++ b/src/script.h @@ -206,5 +206,12 @@ int script_do_get_data (lua_State *L); int script_do_sync (lua_State *L); int script_do_changes (lua_State *L); +int script_get_head_var (lua_State *L); + +int script_get_dict (lua_State *L); +int script_set_dict (lua_State *L); +int script_set_dict_var (lua_State *L); +int script_set_xrec (lua_State *L); + #endif \ No newline at end of file diff --git a/windows/cadzinho.wxs b/windows/cadzinho.wxs index 62ce5e67..673006ec 100644 --- a/windows/cadzinho.wxs +++ b/windows/cadzinho.wxs @@ -3,7 +3,7 @@ + Version='0.6.0' Manufacturer='ZeCruel'>