From 191dc4857c852f1867e80cd9d03a6d1c0921dcb1 Mon Sep 17 00:00:00 2001 From: kintel Date: Sat, 30 Jan 2010 04:26:05 +0000 Subject: header file reorg git-svn-id: http://svn.clifford.at/openscad/trunk@365 b57f626f-c46c-0410-a088-ec61d464b74c diff --git a/MainWindow.ui b/MainWindow.ui deleted file mode 100644 index 656e908..0000000 --- a/MainWindow.ui +++ /dev/null @@ -1,675 +0,0 @@ - - - MainWindow - - - - 0 - 0 - 681 - 647 - - - - MainWindow - - - - - 0 - - - - - Qt::Horizontal - - - - - Monaco - 8 - - - - 30 - - - Qt::LinksAccessibleByMouse|Qt::TextEditable|Qt::TextEditorInteraction|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse - - - - - - - - Qt::Vertical - - - - - - - - - true - - - QFrame::NoFrame - - - QFrame::Raised - - - 0 - - - - 0 - - - - - Time: - - - - - - - - - - FPS: - - - - - - - - - - Steps: - - - - - - - - - - Dump Pictures - - - - - - - - - - - - - - - - 0 - 0 - 681 - 22 - - - - - &File - - - - Open Recent - - - - - Examples - - - - - - - - - - - - - - - - &Edit - - - - - - - - - - - - - - - - - - - - - - - - &Design - - - - - - - - - - - - - - - &View - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Help - - - - - - - - - - - - - - &New - - - Ctrl+N - - - - - &Open... - - - Ctrl+O - - - - - &Save - - - Ctrl+S - - - - - Save &As... - - - Ctrl+Shift+S - - - - - &Reload - - - Ctrl+R - - - - - &Quit - - - - - &Undo - - - Ctrl+Z - - - - - &Redo - - - Ctrl+Shift+Z - - - - - Cu&t - - - Ctrl+X - - - - - &Copy - - - Ctrl+C - - - - - &Paste - - - Ctrl+V - - - - - &Indent - - - Ctrl+I - - - - - U&nindent - - - Ctrl+Shift+I - - - - - C&omment - - - Ctrl+D - - - - - Unco&mment - - - Ctrl+Shift+D - - - - - Paste viewport translation - - - Ctrl+T - - - - - Paste viewport rotation - - - - - Zoom In - - - Ctrl++ - - - - - Zoom Out - - - Ctrl+- - - - - - true - - - Hide editor - - - - - &Reload and Compile - - - F4 - - - - - &Compile - - - F5 - - - - - Compile and &Render (CGAL) - - - F6 - - - - - Display &AST... - - - - - Display CSG &Tree... - - - - - Display CSG &Products... - - - - - Export as &STL... - - - - - Export as &OFF... - - - - - true - - - OpenCSG - - - F9 - - - - - true - - - CGAL Surfaces - - - F10 - - - - - true - - - CGAL Grid Only - - - F11 - - - - - true - - - Thrown Together - - - F12 - - - - - true - - - Show Edges - - - Ctrl+1 - - - - - true - - - Show Axes - - - Ctrl+2 - - - - - true - - - Show Crosshairs - - - Ctrl+3 - - - - - true - - - Animate - - - - - Top - - - Ctrl+4 - - - - - Bottom - - - Ctrl+5 - - - - - Left - - - Ctrl+6 - - - - - Right - - - Ctrl+7 - - - - - Front - - - Ctrl+8 - - - - - Back - - - Ctrl+9 - - - - - Diagonal - - - Ctrl+0 - - - - - Center - - - Ctrl+P - - - - - true - - - Perspective - - - - - true - - - Orthogonal - - - - - true - - - Hide console - - - - - About - - - - - OpenSCAD Manual - - - - - Clear Recent - - - - - Export as DXF... - - - - - Close - - - Ctrl+W - - - - - Preferences - - - - - Flush Caches - - - - - - GLView - QWidget -
GLView.h
- 1 -
-
- - - - - - fileActionClose - triggered() - MainWindow - close() - - - -1 - -1 - - - 340 - 323 - - - - -
diff --git a/Preferences.ui b/Preferences.ui deleted file mode 100644 index e210d1b..0000000 --- a/Preferences.ui +++ /dev/null @@ -1,321 +0,0 @@ - - - Preferences - - - - 0 - 0 - 384 - 243 - - - - Preferences - - - true - - - - - - - 1 - - - - - - - - - - - Color scheme: - - - - - - - false - - - 0 - - - - Cornfield - - - - - Metallic - - - - - Sunset - - - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - Qt::Vertical - - - - 20 - 645 - - - - - - - - - - - - - - - 75 - true - - - - Font - - - false - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - Monaco - 12 - - - - - - - - true - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - Qt::Vertical - - - - 20 - 77 - - - - - - - - - - 0 - - - - - Qt::Vertical - - - - 20 - 120 - - - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - false - - - advanced - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - Qt::Vertical - - - - 20 - 120 - - - - - - - - - - - - - toolBar - - - false - - - Qt::TopToolBarArea - - - Qt::ToolButtonTextUnderIcon - - - false - - - TopToolBarArea - - - false - - - - - - - - true - - - - :/prefs3DView.png - :/openscad.ico:/prefs3DView.png - - - 3D View - - - - - true - - - - :/prefsAdvanced.png:/prefsAdvanced.png - - - Advanced - - - - - true - - - - :/prefsEditor.png:/prefsEditor.png - - - Editor - - - - - - - - diff --git a/chrpath_linux.c b/chrpath_linux.c deleted file mode 100644 index 000244a..0000000 --- a/chrpath_linux.c +++ /dev/null @@ -1,769 +0,0 @@ -/*************************************************************************** - * * - * This is a pre-configured single file version of chrpath for linux. * - * It is used in the binary installer for OpenSCAD on Linux. * - * * - * This file has been created by running * - * cat *.h *.c | sed 's, *# *include *",//&,' > ../chrpath_linux.c * - * in the configured chrpath-0.13 source directory (as found in the debian * - * package repository as the original download site seams to be down). * - * * - * chrpath is licensed under the terms of GPLv2: * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * The Authors are: * - * * - * Geoffrey Keating * - * Implemented first version of chrpath.c based on first version of * - * killrpath. * - * Peeter Joot * - * Implemented first version of killrpath.c. * - * Petter Reinholdtsen * - * Collected both implementations and made userfriendly wrapper. * - * * - * With patches from: * - * * - * Darren Salt * - * David Hull * - * Bradford W. Johnson * - * Thomas Anders * - * Tollef Fog Heen * - * * - ***************************************************************************/ - - -/* config.h. Generated by configure. */ -/* config.h.in. Generated from configure.ac by autoheader. */ - -/* Define to 1 if you have the header file. */ -#define HAVE_ELF_H 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_FCNTL_H 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_GETOPT_H 1 - -/* Define to 1 if you have the `getopt_long' function. */ -#define HAVE_GETOPT_LONG 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_INTTYPES_H 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_LINK_H 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_MEMORY_H 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_STDINT_H 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_STDLIB_H 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_STRINGS_H 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_STRING_H 1 - -/* Define to 1 if you have the header file. */ -/* #undef HAVE_SYS_LINK_H */ - -/* Define to 1 if you have the header file. */ -#define HAVE_SYS_STAT_H 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_SYS_TYPES_H 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_UNISTD_H 1 - -/* Name of package */ -#define PACKAGE "chrpath" - -/* Define to the address where bug reports for this package should be sent. */ -#define PACKAGE_BUGREPORT "pere@hungry.com" - -/* Define to the full name of this package. */ -#define PACKAGE_NAME ""chrpath"" - -/* Define to the full name and version of this package. */ -#define PACKAGE_STRING ""chrpath" "0.13"" - -/* Define to the one symbol short name of this package. */ -#define PACKAGE_TARNAME "-chrpath-" - -/* Define to the version of this package. */ -#define PACKAGE_VERSION ""0.13"" - -/* The size of a `void *', as computed by sizeof. */ -#define SIZEOF_VOID_P 4 - -/* Define to 1 if you have the ANSI C header files. */ -#define STDC_HEADERS 1 - -/* Version number of package */ -#define VERSION "0.13" - -/* Define to 1 if your processor stores words with the most significant byte - first (like Motorola and SPARC, unlike Intel and VAX). */ -/* #undef WORDS_BIGENDIAN */ - -/* Define to empty if `const' does not conform to ANSI C. */ -/* #undef const */ -#ifndef PROTOS_H -#define PROTOS_H - -#include -//#include "config.h" - -#ifdef WORDS_BIGENDIAN -#define ELFDATA2 ELFDATA2MSB -#else -#define ELFDATA2 ELFDATA2LSB -#endif -#if SIZEOF_VOID_P == 8 -#define Elf_Ehdr Elf64_Ehdr -#define ELFCLASS ELFCLASS64 -#define Elf_Phdr Elf64_Phdr -#define Elf_Shdr Elf64_Shdr -#define Elf_Dyn Elf64_Dyn -#elif SIZEOF_VOID_P == 4 -#define Elf_Ehdr Elf32_Ehdr -#define ELFCLASS ELFCLASS32 -#define Elf_Phdr Elf32_Phdr -#define Elf_Shdr Elf32_Shdr -#define Elf_Dyn Elf32_Dyn -#else -#error "Unknown word size (SIZEOF_VOID_P)!" -#endif - -int killrpath(const char *filename); -int chrpath(const char *filename, const char *newpath, int convert); - -int elf_open(const char *filename, int flags, Elf_Ehdr *ehdr); -void elf_close(int fd); -int elf_find_dynamic_section(int fd, Elf_Ehdr *ehdr, Elf_Phdr *phdr); -const char *elf_tagname(int tag); -int elf_dynpath_tag(int tag); - -#endif /* PROTOS_H */ -/* - - -Re: changing embedded RPATH in existing executables. - - To: geoffk@ozemail.com.au - Subject: Re: changing embedded RPATH in existing executables. - From: (peeter joot) - Date: Fri, 30 Apr 1999 16:14:44 -0400 (EDT) - Cc: peeterj@ca.ibm.com, egcs@cygnus.com, libc-hacker@cygnus.com, linux-gcc@vger.rutgers.edu - Reply-To: - -> _Changing_ is a little tricky, but the attached program strips rpaths -> from executables (I find it essential for debugging the binutils). -> It's endian-dependent, if you want this for x86 you can just change -> the occurrences of 'MSB' to 'LSB' and compile (I should really fix -> that). - -Hi Geoff, - -With your program as a guide (and some peeks into libbfd, elf.h, a bit -of the glibc dynamic loader code, objdump, and a hex-editor) I was able to -figure out enough to find and change the rpath string. That was fun! - -This program assumes (unlike your original program) that there is only -one DT_RPATH tag in the dynamic section as even with multiple '-Wl,-rpath,' -commands in the link this seems to occur (they all get concatonated into -a : separated path). - -Thanks for your help. If you want to use this on non-x86 you have to change -the occurances of LSB back to MSB:) - -Peeter --- -*/ - -#ifdef HAVE_CONFIG_H -//# include "config.h" -#endif - -#include -#include -#include -#include -#if defined(HAVE_LINK_H) -# include -#endif /* HAVE_LINK_H */ -#include -#include -#include -//#include "protos.h" - -/** - * Reads an ELF file, and reads or alters the RPATH setting. - * - * TODO: - * modify to add RPATH setting if none exists. - */ - - -int -chrpath(const char *filename, const char *newpath, int convert) -{ - int fd; - Elf_Ehdr ehdr; - int i; - Elf_Phdr phdr; - Elf_Shdr shdr; - Elf_Dyn *dyns; - int rpathoff; - char * strtab; - char * rpath; - unsigned int rpathlen; - int oflags; - int rpath_dyns_index; - - if (NULL == newpath && 0 == convert) - oflags = O_RDONLY; - else - oflags = O_RDWR; - - fd = elf_open(filename, oflags, &ehdr); - if (fd == -1) - { - perror ("elf_open"); - return 1; - } - - if (0 != elf_find_dynamic_section(fd, &ehdr, &phdr)) - { - perror("found no dynamic section"); - return 1; - } - - dyns = malloc(phdr.p_filesz); - if (dyns == NULL) - { - perror ("allocating memory for dynamic section"); - return 1; - } - memset(dyns, 0, phdr.p_filesz); - if (lseek(fd, phdr.p_offset, SEEK_SET) == -1 - || read(fd, dyns, phdr.p_filesz) != (int)phdr.p_filesz) - { - perror ("reading dynamic section"); - free(dyns); - return 1; - } - - rpathoff = -1; - for ( rpath_dyns_index = 0; dyns[rpath_dyns_index].d_tag != DT_NULL; - ++rpath_dyns_index ) - { - if ( elf_dynpath_tag(dyns[rpath_dyns_index].d_tag) ) - { - rpathoff = dyns[rpath_dyns_index].d_un.d_ptr; - break; - } - } - if (rpathoff == -1) - { - printf("%s: no rpath or runpath tag found.\n", filename); - free(dyns); - return 2; - } - - if (lseek(fd, ehdr.e_shoff, SEEK_SET) == -1) - { - perror ("positioning for sections"); - free(dyns); - return 1; - } - - for (i = 0; i < ehdr.e_shnum; i++) - { - if (read(fd, &shdr, sizeof(shdr)) != sizeof(shdr)) - { - perror ("reading section header"); - free(dyns); - return 1; - } - if (shdr.sh_type == SHT_STRTAB) - break; - } - if (i == ehdr.e_shnum) - { - fprintf (stderr, "No string table found.\n"); - free(dyns); - return 2; - } - strtab = (char *)malloc(shdr.sh_size); - if (strtab == NULL) - { - perror ("allocating memory for string table"); - free(dyns); - return 1; - } - memset(strtab, 0, shdr.sh_size); - - if (lseek(fd, shdr.sh_offset, SEEK_SET) == -1) - { - perror ("positioning for string table"); - free(strtab); - free(dyns); - return 1; - } - if (read(fd, strtab, shdr.sh_size) != (int)shdr.sh_size) - { - perror ("reading string table"); - free(strtab); - free(dyns); - return 1; - } - - if ((int)shdr.sh_size < rpathoff) - { - fprintf(stderr, "%s string offset not contained in string table", - elf_tagname(dyns[rpath_dyns_index].d_tag)); - free(strtab); - free(dyns); - return 5; - } - rpath = strtab+rpathoff; - -#if defined(DT_RUNPATH) - if (convert && dyns[rpath_dyns_index].d_tag == DT_RPATH) - { - dyns[rpath_dyns_index].d_tag = DT_RUNPATH; - if (lseek(fd, phdr.p_offset, SEEK_SET) == -1 - || write(fd, dyns, phdr.p_filesz) != (int)phdr.p_filesz) - { - perror ("converting RPATH to RUNPATH"); - return 1; - } - printf("%s: RPATH converted to RUNPATH\n", filename); - } -#endif /* DT_RUNPATH */ - - printf("%s: %s=%s\n", filename, elf_tagname(dyns[rpath_dyns_index].d_tag), - rpath); - - if (NULL == newpath) - { - free(dyns); - free(strtab); - return 0; - } - - rpathlen = strlen(rpath); - - /* - * Calculate the maximum rpath length (will be equal to rpathlen unless - * we have previously truncated it). - */ - for ( i = rpathoff + rpathlen ; (i < (int)shdr.sh_size - && strtab[i] == '\0') ; i++ ) - ; - i--; - - if (i > (int)(rpathoff + rpathlen)) - rpathlen = i - rpathoff; - - if (strlen(newpath) > rpathlen) - { - fprintf(stderr, "new rpath '%s' too large; maximum length %i\n", - newpath, rpathlen); - free(dyns); - free(strtab); - return 7; - } - - memset(rpath, 0, rpathlen); - strcpy(rpath, newpath); - - if (lseek(fd, shdr.sh_offset+rpathoff, SEEK_SET) == -1) - { - perror ("positioning for RPATH"); - free(dyns); - free(strtab); - return 1; - } - if (write(fd, rpath, rpathlen) != (int)rpathlen) - { - perror ("writing RPATH"); - free(dyns); - free(strtab); - return 1; - } - printf("%s: new %s: %s\n", filename, - elf_tagname(dyns[rpath_dyns_index].d_tag), rpath); - - elf_close(fd); - - free(dyns); - dyns = NULL; - - free(strtab); - - return 0; -} - -#ifdef HAVE_CONFIG_H -//# include "config.h" -#endif - -#include -#if defined(HAVE_SYS_LINK_H) -# include /* Find DT_RPATH on Solaris 2.6 */ -#endif /* HAVE_SYS_LINK_H */ -#include -#include -#include -#include -#include -#include -#include -//#include "protos.h" - -int -elf_open(const char *filename, int flags, Elf_Ehdr *ehdr) -{ - int fd; - - fd = open(filename, flags); - if (fd == -1) - { - perror ("open"); - return -1; - } - - if (read(fd, ehdr, sizeof(*ehdr)) != sizeof(*ehdr)) - { - perror ("reading header"); - close(fd); - return -1; - } - - if (0 != memcmp(ehdr->e_ident, ELFMAG, SELFMAG) || - ehdr->e_ident[EI_CLASS] != ELFCLASS || - ehdr->e_ident[EI_DATA] != ELFDATA2 || - ehdr->e_ident[EI_VERSION] != EV_CURRENT) - { - fprintf(stderr, -#ifdef WORDS_BIGENDIAN - "`%s' probably isn't a %d-bit MSB-first ELF file.\n", -#else /* not WORD_BIGENDIAN */ - "`%s' probably isn't a %d-bit LSB-first ELF file.\n", -#endif /* not WORD_BIGENDIAN */ - filename, SIZEOF_VOID_P * 8); - close(fd); - errno = ENOEXEC; /* Hm, is this the best errno code to use? */ - return -1; - } - - if (ehdr->e_phentsize != sizeof(Elf_Phdr)) - { - fprintf(stderr, "section size was read as %d, not %d!\n", - ehdr->e_phentsize, sizeof(Elf_Phdr)); - close(fd); - return -1; - } - return fd; -} - -int -elf_find_dynamic_section(int fd, Elf_Ehdr *ehdr, Elf_Phdr *phdr) -{ - int i; - if (lseek(fd, ehdr->e_phoff, SEEK_SET) == -1) - { - perror ("positioning for sections"); - return 1; - } - - for (i = 0; i < ehdr->e_phnum; i++) - { - if (read(fd, phdr, sizeof(*phdr)) != sizeof(*phdr)) - { - perror ("reading section header"); - return 1; - } - if (phdr->p_type == PT_DYNAMIC) - break; - } - if (i == ehdr->e_phnum) - { - fprintf (stderr, "No dynamic section found.\n"); - return 2; - } - - if (0 == phdr->p_filesz) - { - fprintf (stderr, "Length of dynamic section is zero.\n"); - return 3; - } - - return 0; -} - -void -elf_close(int fd) -{ - close(fd); -} - -const char * -elf_tagname(int tag) -{ - switch (tag) { - case DT_RPATH: - return "RPATH"; - break; -#if defined(DT_RUNPATH) - case DT_RUNPATH: - return "RUNPATH"; - break; -#endif /* DT_RUNPATH */ - } - return "UNKNOWN"; -} - -int -elf_dynpath_tag(int tag) -{ - return ( tag == DT_RPATH -#if defined(DT_RUNPATH) - || tag == DT_RUNPATH -#endif /* DT_RUNPATH */ - ); -} -/* -Taken from another list: - -_Changing_ is a little tricky, but the attached program strips rpaths -from executables (I find it essential for debugging the binutils). -It's endian-dependent, if you want this for x86 you can just change -the occurrences of 'MSB' to 'LSB' and compile (I should really fix -that). - --- -Geoffrey Keating -*/ - -#ifdef HAVE_CONFIG_H -//# include "config.h" -#endif - -#include -#include -#include -#include -#if defined(HAVE_LINK_H) -# include -#endif /* HAVE_LINK_H */ -#include -//#include "protos.h" -#include - -/* Reads an ELF file, nukes all the RPATH entries. */ - -int -killrpath(const char *filename) -{ - int fd; - Elf_Ehdr ehdr; - int i; - Elf_Phdr phdr; - Elf_Dyn *dyns; - int dynpos; - - fd = elf_open(filename, O_RDWR, &ehdr); - - if (fd == -1) - { - perror ("elf_open"); - return 1; - } - - if (0 != elf_find_dynamic_section(fd, &ehdr, &phdr)) - { - perror("found no dynamic section"); - return 1; - } - - dyns = malloc(phdr.p_memsz); - if (dyns == NULL) - { - perror ("allocating memory for dynamic section"); - return 1; - } - memset(dyns, 0, phdr.p_memsz); - if (lseek(fd, phdr.p_offset, SEEK_SET) == -1 - || read(fd, dyns, phdr.p_filesz) != (int)phdr.p_filesz) - { - perror ("reading dynamic section"); - return 1; - } - - dynpos = 0; - for (i = 0; dyns[i].d_tag != DT_NULL; i++) - { - dyns[dynpos] = dyns[i]; - if ( ! elf_dynpath_tag(dyns[i].d_tag) ) - dynpos++; - } - for (; dynpos < i; dynpos++) - dyns[dynpos].d_tag = DT_NULL; - - if (lseek(fd, phdr.p_offset, SEEK_SET) == -1 - || write(fd, dyns, phdr.p_filesz) != (int)phdr.p_filesz) - { - perror ("writing dynamic section"); - return 1; - } - - elf_close(fd); - - return 0; -} -/* - * Author: Petter Reinholdtsen - * date: 2001-01-20 - * - * Alter ELF rpath information (insert, modify, remove). - * - * Based on source from Peeter Joot and Geoffrey - * Keating . - */ - -#ifdef HAVE_CONFIG_H -//# include "config.h" -#endif - -#include -#include -#include -#ifdef HAVE_GETOPT_H -#include -#endif -//#include "protos.h" - -#ifdef HAVE_GETOPT_LONG -# define GETOPT_LONG getopt_long - -static struct option long_options[] = -{ - {"convert", 0, 0, 'c'}, - {"delete", 0, 0, 'd'}, - {"help", 0, 0, 'h'}, - {"keepgoing", 0, 0, 'k'}, - {"list", 0, 0, 'l'}, - {"replace", 1, 0, 'r'}, - {"version", 0, 0, 'v'} -}; - -#else /* not HAVE_GETOPT_LONG */ -# define GETOPT_LONG(argc,argv,optstr,lopts,lidx) getopt(argc,argv,optstr) -#endif /* not HAVE_GETOPT_LONG */ - -static void -usage(char *progname) -{ - printf("Usage: %s [-v|-d|-c|-r ] [ ...]\n\n", - progname); - printf(" -v|--version Display program version number\n"); - printf(" -d|--delete Delete current rpath/runpath setting\n"); -#if defined(DT_RUNPATH) - printf(" -c|--convert Convert rpath to runpath\n"); -#endif /* DT_RUNPATH */ - printf(" -r |--replace Replace current rpath/runpath setting\n"); - printf(" with the path given\n"); - printf(" -l|--list List the current rpath/runpath (default)\n"); - printf(" -h|--help Show this usage information.\n"); -#ifndef HAVE_GETOPT_LONG - printf("\n *** The long options are not available on this platform"); -#endif /* not HAVE_GETOPT_LONG */ -#if !defined(DT_RUNPATH) - printf("\n *** There is no support for runpath on this platform"); -#endif /* DT_RUNPATH */ - printf("\n"); -} - -int -main(int argc, char * const argv[]) -{ - int retval = 0; - int convert = 0; /* convert to given type */ - int remove = 0; /* remove or not */ - int keep_going = 0; /* Break on first error, or keep going? */ - char *newpath = NULL; /* insert this path */ - int opt; -#ifdef HAVE_GETOPT_LONG - int option_index = 0; -#endif /* HAVE_GETOPT_LONG */ - - if (argc < 2) - { - usage(argv[0]); - return 1; - } - - do { - opt = GETOPT_LONG(argc, argv, "cdhklr:v", long_options, &option_index); - switch (opt) - { -#if defined(DT_RUNPATH) - case 'c': - convert = 1; - break; -#endif /* DT_RUNPATH */ - case 'd': - remove = 1; - break; - case 'k': - keep_going = 1; - break; - case 'r': - newpath = optarg; - break; - case 'v': - printf("%s version %s\n", PACKAGE, VERSION); - exit(0); - break; - case 'l': /* This is the default action */ - newpath = NULL; - break; - case -1: - break; - default: - printf("Invalid argument '%c'\n", opt); - case 'h': - usage(argv[0]); - exit(0); - break; - } - } while (-1 != opt); - - while (optind < argc && (!retval || keep_going)) - { - if (remove) - retval |= killrpath(argv[optind++]); - else - /* list by default, replace if path is set */ - retval |= chrpath(argv[optind++], newpath, convert); - } - - return retval; -} diff --git a/lexer.l b/lexer.l deleted file mode 100644 index c9e9332..0000000 --- a/lexer.l +++ /dev/null @@ -1,114 +0,0 @@ -/* - * OpenSCAD (www.openscad.at) - * Copyright (C) 2009 Clifford Wolf - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - */ - -%{ - -#include "openscad.h" -#include "printutils.h" -#include "parser_yacc.h" - -int lexerget_lineno(void); -#ifdef __GNUC__ -static void yyunput(int, char*) __attribute__((unused)); -#endif -extern const char *parser_input_buffer; - -#define YY_INPUT(buf,result,max_size) { \ - if (yyin && yyin != stdin) { \ - int c = fgetc(yyin); \ - if (c >= 0) { \ - result = 1; \ - buf[0] = c; \ - } else { \ - result = YY_NULL; \ - } \ - } else { \ - if (*parser_input_buffer) { \ - result = 1; \ - buf[0] = *(parser_input_buffer++); \ - parser_error_pos++; \ - } else { \ - result = YY_NULL; \ - } \ - } \ -} - -%} - -%option yylineno -%option noyywrap - -%x comment - -%% - -"<"[^ \t\n>]+">" { - char *filename = strdup(yytext+1); - filename[strlen(filename)-1] = 0; - handle_dep(filename); - yyin = fopen(filename, "r"); - if (!yyin) { - PRINTF("WARNING: Can't open input file `%s'.", filename); - } else { - yypush_buffer_state(yy_create_buffer( yyin, YY_BUF_SIZE )); - BEGIN(INITIAL); - } - free(filename); -} - -<> { - if (yyin && yyin != stdin) - fclose(yyin); - yypop_buffer_state(); - if (!YY_CURRENT_BUFFER) - yyterminate(); -} - -"module" return TOK_MODULE; -"function" return TOK_FUNCTION; - -"true" return TOK_TRUE; -"false" return TOK_FALSE; -"undef" return TOK_UNDEF; - -[0-9][0-9.]* { parserlval.number = QString(yytext).toDouble(); return TOK_NUMBER; } -"$"?[a-zA-Z0-9_]+ { parserlval.text = strdup(yytext); return TOK_ID; } - -\"[^"]*\" { - parserlval.text = strdup(yytext+1); - parserlval.text[strlen(parserlval.text)-1] = 0; - return TOK_STRING; -} - -[\n\r\t ] -\/\/[^\n]*\n? -"/*" BEGIN(comment); -"*/" BEGIN(INITIAL); -.|\n - -"<=" return LE; -">=" return GE; -"==" return EQ; -"!=" return NE; -"&&" return AND; -"||" return OR; - -. { return yytext[0]; } - diff --git a/parser.y b/parser.y deleted file mode 100644 index c4cd3d4..0000000 --- a/parser.y +++ /dev/null @@ -1,524 +0,0 @@ -/* - * OpenSCAD (www.openscad.at) - * Copyright (C) 2009 Clifford Wolf - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - */ - -%{ - -#include "openscad.h" -#include "printutils.h" - -int parser_error_pos = -1; - -int parserlex(void); -void yyerror(char const *s); - -int lexerget_lineno(void); -int lexerlex_destroy(void); -int lexerlex(void); - -QVector module_stack; -Module *module; - -class ArgContainer { -public: - QString argname; - Expression *argexpr; -}; -class ArgsContainer { -public: - QVector argnames; - QVector argexpr; -}; - -%} - -%union { - char *text; - double number; - class Value *value; - class Expression *expr; - class ModuleInstantiation *inst; - class ArgContainer *arg; - class ArgsContainer *args; -} - -%token TOK_MODULE -%token TOK_FUNCTION - -%token TOK_ID -%token TOK_STRING -%token TOK_NUMBER - -%token TOK_TRUE -%token TOK_FALSE -%token TOK_UNDEF - -%token LE GE EQ NE AND OR - -%left OR -%left AND - -%left '<' LE GE '>' -%left EQ NE - -%left '!' '+' '-' -%left '*' '/' '%' -%left '[' ']' -%left '.' - -%right '?' ':' - -%type expr -%type vector_expr - -%type module_instantiation -%type module_instantiation_list -%type single_module_instantiation - -%type arguments_call -%type arguments_decl - -%type argument_call -%type argument_decl - -%debug - -%% - -input: - /* empty */ | - statement input ; - -statement: - ';' | - '{' input '}' | - module_instantiation { - if ($1) { - module->children.append($1); - } else { - delete $1; - } - } | - TOK_ID '=' expr ';' { - bool add_new_assignment = true; - for (int i = 0; i < module->assignments_var.size(); i++) { - if (module->assignments_var[i] != QString($1)) - continue; - delete module->assignments_expr[i]; - module->assignments_expr[i] = $3; - add_new_assignment = false; - } - if (add_new_assignment) { - module->assignments_var.append($1); - module->assignments_expr.append($3); - free($1); - } - } | - TOK_MODULE TOK_ID '(' arguments_decl optional_commas ')' { - Module *p = module; - module_stack.append(module); - module = new Module(); - p->modules[$2] = module; - module->argnames = $4->argnames; - module->argexpr = $4->argexpr; - free($2); - delete $4; - } statement { - module = module_stack.last(); - module_stack.pop_back(); - } | - TOK_FUNCTION TOK_ID '(' arguments_decl optional_commas ')' '=' expr { - Function *func = new Function(); - func->argnames = $4->argnames; - func->argexpr = $4->argexpr; - func->expr = $8; - module->functions[$2] = func; - free($2); - delete $4; - } ';' ; - -module_instantiation: - single_module_instantiation ';' { - $$ = $1; - } | - single_module_instantiation '{' module_instantiation_list '}' { - $$ = $1; - if ($$) { - $$->children = $3->children; - } else { - for (int i = 0; i < $3->children.count(); i++) - delete $3->children[i]; - } - $3->children.clear(); - delete $3; - } | - single_module_instantiation module_instantiation { - $$ = $1; - if ($$) { - if ($2) - $$->children.append($2); - } else { - delete $2; - } - } ; - -module_instantiation_list: - /* empty */ { - $$ = new ModuleInstantiation(); - } | - module_instantiation_list module_instantiation { - $$ = $1; - if ($$) { - if ($2) - $$->children.append($2); - } else { - delete $2; - } - } ; - -single_module_instantiation: - TOK_ID '(' arguments_call ')' { - $$ = new ModuleInstantiation(); - $$->modname = QString($1); - $$->argnames = $3->argnames; - $$->argexpr = $3->argexpr; - free($1); - delete $3; - } | - TOK_ID ':' single_module_instantiation { - $$ = $3; - if ($$) - $$->label = QString($1); - free($1); - } | - '!' single_module_instantiation { - $$ = $2; - if ($$) - $$->tag_root = true; - } | - '#' single_module_instantiation { - $$ = $2; - if ($$) - $$->tag_highlight = true; - } | - '%' single_module_instantiation { - $$ = $2; - if ($$) - $$->tag_background = true; - } | - '*' single_module_instantiation { - delete $2; - $$ = NULL; - }; - -expr: - TOK_TRUE { - $$ = new Expression(); - $$->type = "C"; - $$->const_value = new Value(true); - } | - TOK_FALSE { - $$ = new Expression(); - $$->type = "C"; - $$->const_value = new Value(false); - } | - TOK_UNDEF { - $$ = new Expression(); - $$->type = "C"; - $$->const_value = new Value(); - } | - TOK_ID { - $$ = new Expression(); - $$->type = "L"; - $$->var_name = QString($1); - free($1); - } | - expr '.' TOK_ID { - $$ = new Expression(); - $$->type = "N"; - $$->children.append($1); - $$->var_name = QString($3); - free($3); - } | - TOK_STRING { - $$ = new Expression(); - $$->type = "C"; - $$->const_value = new Value(QString($1)); - free($1); - } | - TOK_NUMBER { - $$ = new Expression(); - $$->type = "C"; - $$->const_value = new Value($1); - } | - '[' expr ':' expr ']' { - Expression *e_one = new Expression(); - e_one->type = "C"; - e_one->const_value = new Value(1.0); - $$ = new Expression(); - $$->type = "R"; - $$->children.append($2); - $$->children.append(e_one); - $$->children.append($4); - } | - '[' expr ':' expr ':' expr ']' { - $$ = new Expression(); - $$->type = "R"; - $$->children.append($2); - $$->children.append($4); - $$->children.append($6); - } | - '[' optional_commas ']' { - $$ = new Expression(); - $$->type = "C"; - $$->const_value = new Value(); - $$->const_value->type = Value::VECTOR; - } | - '[' vector_expr optional_commas ']' { - $$ = $2; - } | - expr '*' expr { - $$ = new Expression(); - $$->type = "*"; - $$->children.append($1); - $$->children.append($3); - } | - expr '/' expr { - $$ = new Expression(); - $$->type = "/"; - $$->children.append($1); - $$->children.append($3); - } | - expr '%' expr { - $$ = new Expression(); - $$->type = "%"; - $$->children.append($1); - $$->children.append($3); - } | - expr '+' expr { - $$ = new Expression(); - $$->type = "+"; - $$->children.append($1); - $$->children.append($3); - } | - expr '-' expr { - $$ = new Expression(); - $$->type = "-"; - $$->children.append($1); - $$->children.append($3); - } | - expr '<' expr { - $$ = new Expression(); - $$->type = "<"; - $$->children.append($1); - $$->children.append($3); - } | - expr LE expr { - $$ = new Expression(); - $$->type = "<="; - $$->children.append($1); - $$->children.append($3); - } | - expr EQ expr { - $$ = new Expression(); - $$->type = "=="; - $$->children.append($1); - $$->children.append($3); - } | - expr NE expr { - $$ = new Expression(); - $$->type = "!="; - $$->children.append($1); - $$->children.append($3); - } | - expr GE expr { - $$ = new Expression(); - $$->type = ">="; - $$->children.append($1); - $$->children.append($3); - } | - expr '>' expr { - $$ = new Expression(); - $$->type = ">"; - $$->children.append($1); - $$->children.append($3); - } | - expr AND expr { - $$ = new Expression(); - $$->type = "&&"; - $$->children.append($1); - $$->children.append($3); - } | - expr OR expr { - $$ = new Expression(); - $$->type = "||"; - $$->children.append($1); - $$->children.append($3); - } | - '+' expr { - $$ = $2; - } | - '-' expr { - $$ = new Expression(); - $$->type = "I"; - $$->children.append($2); - } | - '!' expr { - $$ = new Expression(); - $$->type = "!"; - $$->children.append($2); - } | - '(' expr ')' { - $$ = $2; - } | - expr '?' expr ':' expr { - $$ = new Expression(); - $$->type = "?:"; - $$->children.append($1); - $$->children.append($3); - $$->children.append($5); - } | - expr '[' expr ']' { - $$ = new Expression(); - $$->type = "[]"; - $$->children.append($1); - $$->children.append($3); - } | - TOK_ID '(' arguments_call ')' { - $$ = new Expression(); - $$->type = "F"; - $$->call_funcname = QString($1); - $$->call_argnames = $3->argnames; - $$->children = $3->argexpr; - free($1); - delete $3; - } ; - -optional_commas: - ',' optional_commas | ; - -vector_expr: - expr { - $$ = new Expression(); - $$->type = 'V'; - $$->children.append($1); - } | - vector_expr ',' optional_commas expr { - $$ = $1; - $$->children.append($4); - } ; - -arguments_decl: - /* empty */ { - $$ = new ArgsContainer(); - } | - argument_decl { - $$ = new ArgsContainer(); - $$->argnames.append($1->argname); - $$->argexpr.append($1->argexpr); - delete $1; - } | - arguments_decl ',' optional_commas argument_decl { - $$ = $1; - $$->argnames.append($4->argname); - $$->argexpr.append($4->argexpr); - delete $4; - } ; - -argument_decl: - TOK_ID { - $$ = new ArgContainer(); - $$->argname = QString($1); - $$->argexpr = NULL; - free($1); - } | - TOK_ID '=' expr { - $$ = new ArgContainer(); - $$->argname = QString($1); - $$->argexpr = $3; - free($1); - } ; - -arguments_call: - /* empty */ { - $$ = new ArgsContainer(); - } | - argument_call { - $$ = new ArgsContainer(); - $$->argnames.append($1->argname); - $$->argexpr.append($1->argexpr); - delete $1; - } | - arguments_call ',' optional_commas argument_call { - $$ = $1; - $$->argnames.append($4->argname); - $$->argexpr.append($4->argexpr); - delete $4; - } ; - -argument_call: - expr { - $$ = new ArgContainer(); - $$->argexpr = $1; - } | - TOK_ID '=' expr { - $$ = new ArgContainer(); - $$->argname = QString($1); - $$->argexpr = $3; - free($1); - } ; - -%% - -int parserlex(void) -{ - return lexerlex(); -} - -void yyerror (char const *s) -{ - // FIXME: We leak memory on parser errors... - PRINTF("Parser error in line %d: %s\n", lexerget_lineno(), s); - module = NULL; -} - -extern FILE *lexerin; -extern const char *parser_input_buffer; -const char *parser_input_buffer; - -AbstractModule *parse(const char *text, int debug) -{ - lexerin = NULL; - parser_error_pos = -1; - parser_input_buffer = text; - - module_stack.clear(); - module = new Module(); - - parserdebug = debug; - parserparse(); - - lexerlex_destroy(); - - if (module) - parser_error_pos = -1; - - return module; -} - diff --git a/src/CGAL_renderer.h b/src/CGAL_renderer.h index 3c36db4..0758339 100644 --- a/src/CGAL_renderer.h +++ b/src/CGAL_renderer.h @@ -237,7 +237,7 @@ namespace OpenSCAD { glVertex3dv(pc); } - inline void CGAL_GLU_TESS_CALLBACK combineCallback(GLdouble coords[3], GLvoid *d[4], GLfloat w[4], GLvoid **dataOut) + inline void CGAL_GLU_TESS_CALLBACK combineCallback(GLdouble coords[3], GLvoid *[4], GLfloat [4], GLvoid **dataOut) { static std::list pcache; if (dataOut) { diff --git a/src/MainWindow.h b/src/MainWindow.h index bb1bdc4..1dc2153 100644 --- a/src/MainWindow.h +++ b/src/MainWindow.h @@ -4,6 +4,10 @@ #include #include "ui_MainWindow.h" #include "openscad.h" +#include "context.h" +#include "module.h" +#include "polyset.h" +#include class MainWindow : public QMainWindow, public Ui::MainWindow { @@ -27,11 +31,11 @@ public: AbstractNode *absolute_root_node; // Result of tree evaluation AbstractNode *root_node; // Root if the root modifier (!) is used - CSGTerm *root_raw_term; // Result of CSG term rendering + class CSGTerm *root_raw_term; // Result of CSG term rendering CSGTerm *root_norm_term; // Normalized CSG products - CSGChain *root_chain; + class CSGChain *root_chain; #ifdef ENABLE_CGAL - CGAL_Nef_polyhedron *root_N; + class CGAL_Nef_polyhedron *root_N; bool recreate_cgal_ogl_p; void *cgal_ogl_p; PolySet *cgal_ogl_ps; diff --git a/src/MainWindow.ui b/src/MainWindow.ui new file mode 100644 index 0000000..656e908 --- /dev/null +++ b/src/MainWindow.ui @@ -0,0 +1,675 @@ + + + MainWindow + + + + 0 + 0 + 681 + 647 + + + + MainWindow + + + + + 0 + + + + + Qt::Horizontal + + + + + Monaco + 8 + + + + 30 + + + Qt::LinksAccessibleByMouse|Qt::TextEditable|Qt::TextEditorInteraction|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse + + + + + + + + Qt::Vertical + + + + + + + + + true + + + QFrame::NoFrame + + + QFrame::Raised + + + 0 + + + + 0 + + + + + Time: + + + + + + + + + + FPS: + + + + + + + + + + Steps: + + + + + + + + + + Dump Pictures + + + + + + + + + + + + + + + + 0 + 0 + 681 + 22 + + + + + &File + + + + Open Recent + + + + + Examples + + + + + + + + + + + + + + + + &Edit + + + + + + + + + + + + + + + + + + + + + + + + &Design + + + + + + + + + + + + + + + &View + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Help + + + + + + + + + + + + + + &New + + + Ctrl+N + + + + + &Open... + + + Ctrl+O + + + + + &Save + + + Ctrl+S + + + + + Save &As... + + + Ctrl+Shift+S + + + + + &Reload + + + Ctrl+R + + + + + &Quit + + + + + &Undo + + + Ctrl+Z + + + + + &Redo + + + Ctrl+Shift+Z + + + + + Cu&t + + + Ctrl+X + + + + + &Copy + + + Ctrl+C + + + + + &Paste + + + Ctrl+V + + + + + &Indent + + + Ctrl+I + + + + + U&nindent + + + Ctrl+Shift+I + + + + + C&omment + + + Ctrl+D + + + + + Unco&mment + + + Ctrl+Shift+D + + + + + Paste viewport translation + + + Ctrl+T + + + + + Paste viewport rotation + + + + + Zoom In + + + Ctrl++ + + + + + Zoom Out + + + Ctrl+- + + + + + true + + + Hide editor + + + + + &Reload and Compile + + + F4 + + + + + &Compile + + + F5 + + + + + Compile and &Render (CGAL) + + + F6 + + + + + Display &AST... + + + + + Display CSG &Tree... + + + + + Display CSG &Products... + + + + + Export as &STL... + + + + + Export as &OFF... + + + + + true + + + OpenCSG + + + F9 + + + + + true + + + CGAL Surfaces + + + F10 + + + + + true + + + CGAL Grid Only + + + F11 + + + + + true + + + Thrown Together + + + F12 + + + + + true + + + Show Edges + + + Ctrl+1 + + + + + true + + + Show Axes + + + Ctrl+2 + + + + + true + + + Show Crosshairs + + + Ctrl+3 + + + + + true + + + Animate + + + + + Top + + + Ctrl+4 + + + + + Bottom + + + Ctrl+5 + + + + + Left + + + Ctrl+6 + + + + + Right + + + Ctrl+7 + + + + + Front + + + Ctrl+8 + + + + + Back + + + Ctrl+9 + + + + + Diagonal + + + Ctrl+0 + + + + + Center + + + Ctrl+P + + + + + true + + + Perspective + + + + + true + + + Orthogonal + + + + + true + + + Hide console + + + + + About + + + + + OpenSCAD Manual + + + + + Clear Recent + + + + + Export as DXF... + + + + + Close + + + Ctrl+W + + + + + Preferences + + + + + Flush Caches + + + + + + GLView + QWidget +
GLView.h
+ 1 +
+
+ + + + + + fileActionClose + triggered() + MainWindow + close() + + + -1 + -1 + + + 340 + 323 + + + + +
diff --git a/src/Preferences.ui b/src/Preferences.ui new file mode 100644 index 0000000..e210d1b --- /dev/null +++ b/src/Preferences.ui @@ -0,0 +1,321 @@ + + + Preferences + + + + 0 + 0 + 384 + 243 + + + + Preferences + + + true + + + + + + + 1 + + + + + + + + + + + Color scheme: + + + + + + + false + + + 0 + + + + Cornfield + + + + + Metallic + + + + + Sunset + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + Qt::Vertical + + + + 20 + 645 + + + + + + + + + + + + + + + 75 + true + + + + Font + + + false + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + Monaco + 12 + + + + + + + + true + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + Qt::Vertical + + + + 20 + 77 + + + + + + + + + + 0 + + + + + Qt::Vertical + + + + 20 + 120 + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + false + + + advanced + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + Qt::Vertical + + + + 20 + 120 + + + + + + + + + + + + + toolBar + + + false + + + Qt::TopToolBarArea + + + Qt::ToolButtonTextUnderIcon + + + false + + + TopToolBarArea + + + false + + + + + + + + true + + + + :/prefs3DView.png + :/openscad.ico:/prefs3DView.png + + + 3D View + + + + + true + + + + :/prefsAdvanced.png:/prefsAdvanced.png + + + Advanced + + + + + true + + + + :/prefsEditor.png:/prefsEditor.png + + + Editor + + + + + + + + diff --git a/src/builtin.h b/src/builtin.h new file mode 100644 index 0000000..dbdd818 --- /dev/null +++ b/src/builtin.h @@ -0,0 +1,25 @@ +#ifndef BUILTIN_H_ +#define BUILTIN_H_ + +#include + +extern QHash builtin_functions; +extern void initialize_builtin_functions(); +extern void destroy_builtin_functions(); + +extern QHash builtin_modules; +extern void initialize_builtin_modules(); +extern void destroy_builtin_modules(); + +extern void register_builtin_csgops(); +extern void register_builtin_transform(); +extern void register_builtin_primitives(); +extern void register_builtin_surface(); +extern void register_builtin_control(); +extern void register_builtin_render(); +extern void register_builtin_import(); +extern void register_builtin_dxf_linear_extrude(); +extern void register_builtin_dxf_rotate_extrude(); +extern void initialize_builtin_dxf_dim(); + +#endif diff --git a/src/cgal.h b/src/cgal.h new file mode 100644 index 0000000..de942e7 --- /dev/null +++ b/src/cgal.h @@ -0,0 +1,59 @@ +#ifndef CGAL_H_ +#define CGAL_H_ + +#ifdef ENABLE_CGAL + +#include +#include +#include +#include +#include +#include +#include + +typedef CGAL::Extended_cartesian CGAL_Kernel2; +typedef CGAL::Nef_polyhedron_2 CGAL_Nef_polyhedron2; +typedef CGAL_Kernel2::Aff_transformation_2 CGAL_Aff_transformation2; + +typedef CGAL::Cartesian CGAL_Kernel3; +typedef CGAL::Polyhedron_3 CGAL_Polyhedron; +typedef CGAL_Polyhedron::HalfedgeDS CGAL_HDS; +typedef CGAL::Polyhedron_incremental_builder_3 CGAL_Polybuilder; +typedef CGAL::Nef_polyhedron_3 CGAL_Nef_polyhedron3; +typedef CGAL_Nef_polyhedron3::Aff_transformation_3 CGAL_Aff_transformation; +typedef CGAL_Nef_polyhedron3::Vector_3 CGAL_Vector; +typedef CGAL_Nef_polyhedron3::Plane_3 CGAL_Plane; +typedef CGAL_Nef_polyhedron3::Point_3 CGAL_Point; + +struct CGAL_Nef_polyhedron +{ + int dim; + CGAL_Nef_polyhedron2 p2; + CGAL_Nef_polyhedron3 p3; + + CGAL_Nef_polyhedron() { + dim = 0; + } + + CGAL_Nef_polyhedron(const CGAL_Nef_polyhedron2 &p) { + dim = 2; + p2 = p; + } + + CGAL_Nef_polyhedron(const CGAL_Nef_polyhedron3 &p) { + dim = 3; + p3 = p; + } + + int weight() { + if (dim == 2) + return p2.explorer().number_of_vertices(); + if (dim == 3) + return p3.number_of_vertices(); + return 0; + } +}; + +#endif /* ENABLE_CGAL */ + +#endif diff --git a/src/chrpath_linux.c b/src/chrpath_linux.c new file mode 100644 index 0000000..000244a --- /dev/null +++ b/src/chrpath_linux.c @@ -0,0 +1,769 @@ +/*************************************************************************** + * * + * This is a pre-configured single file version of chrpath for linux. * + * It is used in the binary installer for OpenSCAD on Linux. * + * * + * This file has been created by running * + * cat *.h *.c | sed 's, *# *include *",//&,' > ../chrpath_linux.c * + * in the configured chrpath-0.13 source directory (as found in the debian * + * package repository as the original download site seams to be down). * + * * + * chrpath is licensed under the terms of GPLv2: * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * The Authors are: * + * * + * Geoffrey Keating * + * Implemented first version of chrpath.c based on first version of * + * killrpath. * + * Peeter Joot * + * Implemented first version of killrpath.c. * + * Petter Reinholdtsen * + * Collected both implementations and made userfriendly wrapper. * + * * + * With patches from: * + * * + * Darren Salt * + * David Hull * + * Bradford W. Johnson * + * Thomas Anders * + * Tollef Fog Heen * + * * + ***************************************************************************/ + + +/* config.h. Generated by configure. */ +/* config.h.in. Generated from configure.ac by autoheader. */ + +/* Define to 1 if you have the header file. */ +#define HAVE_ELF_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_FCNTL_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_GETOPT_H 1 + +/* Define to 1 if you have the `getopt_long' function. */ +#define HAVE_GETOPT_LONG 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_INTTYPES_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_LINK_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_MEMORY_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_STDINT_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_STDLIB_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_STRINGS_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_STRING_H 1 + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_SYS_LINK_H */ + +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_STAT_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_TYPES_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_UNISTD_H 1 + +/* Name of package */ +#define PACKAGE "chrpath" + +/* Define to the address where bug reports for this package should be sent. */ +#define PACKAGE_BUGREPORT "pere@hungry.com" + +/* Define to the full name of this package. */ +#define PACKAGE_NAME ""chrpath"" + +/* Define to the full name and version of this package. */ +#define PACKAGE_STRING ""chrpath" "0.13"" + +/* Define to the one symbol short name of this package. */ +#define PACKAGE_TARNAME "-chrpath-" + +/* Define to the version of this package. */ +#define PACKAGE_VERSION ""0.13"" + +/* The size of a `void *', as computed by sizeof. */ +#define SIZEOF_VOID_P 4 + +/* Define to 1 if you have the ANSI C header files. */ +#define STDC_HEADERS 1 + +/* Version number of package */ +#define VERSION "0.13" + +/* Define to 1 if your processor stores words with the most significant byte + first (like Motorola and SPARC, unlike Intel and VAX). */ +/* #undef WORDS_BIGENDIAN */ + +/* Define to empty if `const' does not conform to ANSI C. */ +/* #undef const */ +#ifndef PROTOS_H +#define PROTOS_H + +#include +//#include "config.h" + +#ifdef WORDS_BIGENDIAN +#define ELFDATA2 ELFDATA2MSB +#else +#define ELFDATA2 ELFDATA2LSB +#endif +#if SIZEOF_VOID_P == 8 +#define Elf_Ehdr Elf64_Ehdr +#define ELFCLASS ELFCLASS64 +#define Elf_Phdr Elf64_Phdr +#define Elf_Shdr Elf64_Shdr +#define Elf_Dyn Elf64_Dyn +#elif SIZEOF_VOID_P == 4 +#define Elf_Ehdr Elf32_Ehdr +#define ELFCLASS ELFCLASS32 +#define Elf_Phdr Elf32_Phdr +#define Elf_Shdr Elf32_Shdr +#define Elf_Dyn Elf32_Dyn +#else +#error "Unknown word size (SIZEOF_VOID_P)!" +#endif + +int killrpath(const char *filename); +int chrpath(const char *filename, const char *newpath, int convert); + +int elf_open(const char *filename, int flags, Elf_Ehdr *ehdr); +void elf_close(int fd); +int elf_find_dynamic_section(int fd, Elf_Ehdr *ehdr, Elf_Phdr *phdr); +const char *elf_tagname(int tag); +int elf_dynpath_tag(int tag); + +#endif /* PROTOS_H */ +/* + + +Re: changing embedded RPATH in existing executables. + + To: geoffk@ozemail.com.au + Subject: Re: changing embedded RPATH in existing executables. + From: (peeter joot) + Date: Fri, 30 Apr 1999 16:14:44 -0400 (EDT) + Cc: peeterj@ca.ibm.com, egcs@cygnus.com, libc-hacker@cygnus.com, linux-gcc@vger.rutgers.edu + Reply-To: + +> _Changing_ is a little tricky, but the attached program strips rpaths +> from executables (I find it essential for debugging the binutils). +> It's endian-dependent, if you want this for x86 you can just change +> the occurrences of 'MSB' to 'LSB' and compile (I should really fix +> that). + +Hi Geoff, + +With your program as a guide (and some peeks into libbfd, elf.h, a bit +of the glibc dynamic loader code, objdump, and a hex-editor) I was able to +figure out enough to find and change the rpath string. That was fun! + +This program assumes (unlike your original program) that there is only +one DT_RPATH tag in the dynamic section as even with multiple '-Wl,-rpath,' +commands in the link this seems to occur (they all get concatonated into +a : separated path). + +Thanks for your help. If you want to use this on non-x86 you have to change +the occurances of LSB back to MSB:) + +Peeter +-- +*/ + +#ifdef HAVE_CONFIG_H +//# include "config.h" +#endif + +#include +#include +#include +#include +#if defined(HAVE_LINK_H) +# include +#endif /* HAVE_LINK_H */ +#include +#include +#include +//#include "protos.h" + +/** + * Reads an ELF file, and reads or alters the RPATH setting. + * + * TODO: + * modify to add RPATH setting if none exists. + */ + + +int +chrpath(const char *filename, const char *newpath, int convert) +{ + int fd; + Elf_Ehdr ehdr; + int i; + Elf_Phdr phdr; + Elf_Shdr shdr; + Elf_Dyn *dyns; + int rpathoff; + char * strtab; + char * rpath; + unsigned int rpathlen; + int oflags; + int rpath_dyns_index; + + if (NULL == newpath && 0 == convert) + oflags = O_RDONLY; + else + oflags = O_RDWR; + + fd = elf_open(filename, oflags, &ehdr); + if (fd == -1) + { + perror ("elf_open"); + return 1; + } + + if (0 != elf_find_dynamic_section(fd, &ehdr, &phdr)) + { + perror("found no dynamic section"); + return 1; + } + + dyns = malloc(phdr.p_filesz); + if (dyns == NULL) + { + perror ("allocating memory for dynamic section"); + return 1; + } + memset(dyns, 0, phdr.p_filesz); + if (lseek(fd, phdr.p_offset, SEEK_SET) == -1 + || read(fd, dyns, phdr.p_filesz) != (int)phdr.p_filesz) + { + perror ("reading dynamic section"); + free(dyns); + return 1; + } + + rpathoff = -1; + for ( rpath_dyns_index = 0; dyns[rpath_dyns_index].d_tag != DT_NULL; + ++rpath_dyns_index ) + { + if ( elf_dynpath_tag(dyns[rpath_dyns_index].d_tag) ) + { + rpathoff = dyns[rpath_dyns_index].d_un.d_ptr; + break; + } + } + if (rpathoff == -1) + { + printf("%s: no rpath or runpath tag found.\n", filename); + free(dyns); + return 2; + } + + if (lseek(fd, ehdr.e_shoff, SEEK_SET) == -1) + { + perror ("positioning for sections"); + free(dyns); + return 1; + } + + for (i = 0; i < ehdr.e_shnum; i++) + { + if (read(fd, &shdr, sizeof(shdr)) != sizeof(shdr)) + { + perror ("reading section header"); + free(dyns); + return 1; + } + if (shdr.sh_type == SHT_STRTAB) + break; + } + if (i == ehdr.e_shnum) + { + fprintf (stderr, "No string table found.\n"); + free(dyns); + return 2; + } + strtab = (char *)malloc(shdr.sh_size); + if (strtab == NULL) + { + perror ("allocating memory for string table"); + free(dyns); + return 1; + } + memset(strtab, 0, shdr.sh_size); + + if (lseek(fd, shdr.sh_offset, SEEK_SET) == -1) + { + perror ("positioning for string table"); + free(strtab); + free(dyns); + return 1; + } + if (read(fd, strtab, shdr.sh_size) != (int)shdr.sh_size) + { + perror ("reading string table"); + free(strtab); + free(dyns); + return 1; + } + + if ((int)shdr.sh_size < rpathoff) + { + fprintf(stderr, "%s string offset not contained in string table", + elf_tagname(dyns[rpath_dyns_index].d_tag)); + free(strtab); + free(dyns); + return 5; + } + rpath = strtab+rpathoff; + +#if defined(DT_RUNPATH) + if (convert && dyns[rpath_dyns_index].d_tag == DT_RPATH) + { + dyns[rpath_dyns_index].d_tag = DT_RUNPATH; + if (lseek(fd, phdr.p_offset, SEEK_SET) == -1 + || write(fd, dyns, phdr.p_filesz) != (int)phdr.p_filesz) + { + perror ("converting RPATH to RUNPATH"); + return 1; + } + printf("%s: RPATH converted to RUNPATH\n", filename); + } +#endif /* DT_RUNPATH */ + + printf("%s: %s=%s\n", filename, elf_tagname(dyns[rpath_dyns_index].d_tag), + rpath); + + if (NULL == newpath) + { + free(dyns); + free(strtab); + return 0; + } + + rpathlen = strlen(rpath); + + /* + * Calculate the maximum rpath length (will be equal to rpathlen unless + * we have previously truncated it). + */ + for ( i = rpathoff + rpathlen ; (i < (int)shdr.sh_size + && strtab[i] == '\0') ; i++ ) + ; + i--; + + if (i > (int)(rpathoff + rpathlen)) + rpathlen = i - rpathoff; + + if (strlen(newpath) > rpathlen) + { + fprintf(stderr, "new rpath '%s' too large; maximum length %i\n", + newpath, rpathlen); + free(dyns); + free(strtab); + return 7; + } + + memset(rpath, 0, rpathlen); + strcpy(rpath, newpath); + + if (lseek(fd, shdr.sh_offset+rpathoff, SEEK_SET) == -1) + { + perror ("positioning for RPATH"); + free(dyns); + free(strtab); + return 1; + } + if (write(fd, rpath, rpathlen) != (int)rpathlen) + { + perror ("writing RPATH"); + free(dyns); + free(strtab); + return 1; + } + printf("%s: new %s: %s\n", filename, + elf_tagname(dyns[rpath_dyns_index].d_tag), rpath); + + elf_close(fd); + + free(dyns); + dyns = NULL; + + free(strtab); + + return 0; +} + +#ifdef HAVE_CONFIG_H +//# include "config.h" +#endif + +#include +#if defined(HAVE_SYS_LINK_H) +# include /* Find DT_RPATH on Solaris 2.6 */ +#endif /* HAVE_SYS_LINK_H */ +#include +#include +#include +#include +#include +#include +#include +//#include "protos.h" + +int +elf_open(const char *filename, int flags, Elf_Ehdr *ehdr) +{ + int fd; + + fd = open(filename, flags); + if (fd == -1) + { + perror ("open"); + return -1; + } + + if (read(fd, ehdr, sizeof(*ehdr)) != sizeof(*ehdr)) + { + perror ("reading header"); + close(fd); + return -1; + } + + if (0 != memcmp(ehdr->e_ident, ELFMAG, SELFMAG) || + ehdr->e_ident[EI_CLASS] != ELFCLASS || + ehdr->e_ident[EI_DATA] != ELFDATA2 || + ehdr->e_ident[EI_VERSION] != EV_CURRENT) + { + fprintf(stderr, +#ifdef WORDS_BIGENDIAN + "`%s' probably isn't a %d-bit MSB-first ELF file.\n", +#else /* not WORD_BIGENDIAN */ + "`%s' probably isn't a %d-bit LSB-first ELF file.\n", +#endif /* not WORD_BIGENDIAN */ + filename, SIZEOF_VOID_P * 8); + close(fd); + errno = ENOEXEC; /* Hm, is this the best errno code to use? */ + return -1; + } + + if (ehdr->e_phentsize != sizeof(Elf_Phdr)) + { + fprintf(stderr, "section size was read as %d, not %d!\n", + ehdr->e_phentsize, sizeof(Elf_Phdr)); + close(fd); + return -1; + } + return fd; +} + +int +elf_find_dynamic_section(int fd, Elf_Ehdr *ehdr, Elf_Phdr *phdr) +{ + int i; + if (lseek(fd, ehdr->e_phoff, SEEK_SET) == -1) + { + perror ("positioning for sections"); + return 1; + } + + for (i = 0; i < ehdr->e_phnum; i++) + { + if (read(fd, phdr, sizeof(*phdr)) != sizeof(*phdr)) + { + perror ("reading section header"); + return 1; + } + if (phdr->p_type == PT_DYNAMIC) + break; + } + if (i == ehdr->e_phnum) + { + fprintf (stderr, "No dynamic section found.\n"); + return 2; + } + + if (0 == phdr->p_filesz) + { + fprintf (stderr, "Length of dynamic section is zero.\n"); + return 3; + } + + return 0; +} + +void +elf_close(int fd) +{ + close(fd); +} + +const char * +elf_tagname(int tag) +{ + switch (tag) { + case DT_RPATH: + return "RPATH"; + break; +#if defined(DT_RUNPATH) + case DT_RUNPATH: + return "RUNPATH"; + break; +#endif /* DT_RUNPATH */ + } + return "UNKNOWN"; +} + +int +elf_dynpath_tag(int tag) +{ + return ( tag == DT_RPATH +#if defined(DT_RUNPATH) + || tag == DT_RUNPATH +#endif /* DT_RUNPATH */ + ); +} +/* +Taken from another list: + +_Changing_ is a little tricky, but the attached program strips rpaths +from executables (I find it essential for debugging the binutils). +It's endian-dependent, if you want this for x86 you can just change +the occurrences of 'MSB' to 'LSB' and compile (I should really fix +that). + +-- +Geoffrey Keating +*/ + +#ifdef HAVE_CONFIG_H +//# include "config.h" +#endif + +#include +#include +#include +#include +#if defined(HAVE_LINK_H) +# include +#endif /* HAVE_LINK_H */ +#include +//#include "protos.h" +#include + +/* Reads an ELF file, nukes all the RPATH entries. */ + +int +killrpath(const char *filename) +{ + int fd; + Elf_Ehdr ehdr; + int i; + Elf_Phdr phdr; + Elf_Dyn *dyns; + int dynpos; + + fd = elf_open(filename, O_RDWR, &ehdr); + + if (fd == -1) + { + perror ("elf_open"); + return 1; + } + + if (0 != elf_find_dynamic_section(fd, &ehdr, &phdr)) + { + perror("found no dynamic section"); + return 1; + } + + dyns = malloc(phdr.p_memsz); + if (dyns == NULL) + { + perror ("allocating memory for dynamic section"); + return 1; + } + memset(dyns, 0, phdr.p_memsz); + if (lseek(fd, phdr.p_offset, SEEK_SET) == -1 + || read(fd, dyns, phdr.p_filesz) != (int)phdr.p_filesz) + { + perror ("reading dynamic section"); + return 1; + } + + dynpos = 0; + for (i = 0; dyns[i].d_tag != DT_NULL; i++) + { + dyns[dynpos] = dyns[i]; + if ( ! elf_dynpath_tag(dyns[i].d_tag) ) + dynpos++; + } + for (; dynpos < i; dynpos++) + dyns[dynpos].d_tag = DT_NULL; + + if (lseek(fd, phdr.p_offset, SEEK_SET) == -1 + || write(fd, dyns, phdr.p_filesz) != (int)phdr.p_filesz) + { + perror ("writing dynamic section"); + return 1; + } + + elf_close(fd); + + return 0; +} +/* + * Author: Petter Reinholdtsen + * date: 2001-01-20 + * + * Alter ELF rpath information (insert, modify, remove). + * + * Based on source from Peeter Joot and Geoffrey + * Keating . + */ + +#ifdef HAVE_CONFIG_H +//# include "config.h" +#endif + +#include +#include +#include +#ifdef HAVE_GETOPT_H +#include +#endif +//#include "protos.h" + +#ifdef HAVE_GETOPT_LONG +# define GETOPT_LONG getopt_long + +static struct option long_options[] = +{ + {"convert", 0, 0, 'c'}, + {"delete", 0, 0, 'd'}, + {"help", 0, 0, 'h'}, + {"keepgoing", 0, 0, 'k'}, + {"list", 0, 0, 'l'}, + {"replace", 1, 0, 'r'}, + {"version", 0, 0, 'v'} +}; + +#else /* not HAVE_GETOPT_LONG */ +# define GETOPT_LONG(argc,argv,optstr,lopts,lidx) getopt(argc,argv,optstr) +#endif /* not HAVE_GETOPT_LONG */ + +static void +usage(char *progname) +{ + printf("Usage: %s [-v|-d|-c|-r ] [ ...]\n\n", + progname); + printf(" -v|--version Display program version number\n"); + printf(" -d|--delete Delete current rpath/runpath setting\n"); +#if defined(DT_RUNPATH) + printf(" -c|--convert Convert rpath to runpath\n"); +#endif /* DT_RUNPATH */ + printf(" -r |--replace Replace current rpath/runpath setting\n"); + printf(" with the path given\n"); + printf(" -l|--list List the current rpath/runpath (default)\n"); + printf(" -h|--help Show this usage information.\n"); +#ifndef HAVE_GETOPT_LONG + printf("\n *** The long options are not available on this platform"); +#endif /* not HAVE_GETOPT_LONG */ +#if !defined(DT_RUNPATH) + printf("\n *** There is no support for runpath on this platform"); +#endif /* DT_RUNPATH */ + printf("\n"); +} + +int +main(int argc, char * const argv[]) +{ + int retval = 0; + int convert = 0; /* convert to given type */ + int remove = 0; /* remove or not */ + int keep_going = 0; /* Break on first error, or keep going? */ + char *newpath = NULL; /* insert this path */ + int opt; +#ifdef HAVE_GETOPT_LONG + int option_index = 0; +#endif /* HAVE_GETOPT_LONG */ + + if (argc < 2) + { + usage(argv[0]); + return 1; + } + + do { + opt = GETOPT_LONG(argc, argv, "cdhklr:v", long_options, &option_index); + switch (opt) + { +#if defined(DT_RUNPATH) + case 'c': + convert = 1; + break; +#endif /* DT_RUNPATH */ + case 'd': + remove = 1; + break; + case 'k': + keep_going = 1; + break; + case 'r': + newpath = optarg; + break; + case 'v': + printf("%s version %s\n", PACKAGE, VERSION); + exit(0); + break; + case 'l': /* This is the default action */ + newpath = NULL; + break; + case -1: + break; + default: + printf("Invalid argument '%c'\n", opt); + case 'h': + usage(argv[0]); + exit(0); + break; + } + } while (-1 != opt); + + while (optind < argc && (!retval || keep_going)) + { + if (remove) + retval |= killrpath(argv[optind++]); + else + /* list by default, replace if path is set */ + retval |= chrpath(argv[optind++], newpath, convert); + } + + return retval; +} diff --git a/src/context.cc b/src/context.cc index 15a2ea6..961c107 100644 --- a/src/context.cc +++ b/src/context.cc @@ -18,7 +18,10 @@ * */ -#include "openscad.h" +#include "context.h" +#include "expression.h" +#include "function.h" +#include "module.h" #include "printutils.h" Context::Context(const Context *parent) diff --git a/src/context.h b/src/context.h new file mode 100644 index 0000000..e78c883 --- /dev/null +++ b/src/context.h @@ -0,0 +1,32 @@ +#ifndef CONTEXT_H_ +#define CONTEXT_H_ + +#include +#include +#include "value.h" + +class Context +{ +public: + const Context *parent; + QHash variables; + QHash config_variables; + const QHash *functions_p; + const QHash *modules_p; + const class ModuleInstantiation *inst_p; + + static QVector ctx_stack; + + Context(const Context *parent = NULL); + ~Context(); + + void args(const QVector &argnames, const QVector &argexpr, const QVector &call_argnames, const QVector &call_argvalues); + + void set_variable(QString name, Value value); + Value lookup_variable(QString name, bool silent = false) const; + + Value evaluate_function(QString name, const QVector &argnames, const QVector &argvalues) const; + class AbstractNode *evaluate_module(const ModuleInstantiation *inst) const; +}; + +#endif diff --git a/src/control.cc b/src/control.cc index 19c5255..f1f53da 100644 --- a/src/control.cc +++ b/src/control.cc @@ -18,9 +18,10 @@ * */ -#define INCLUDE_ABSTRACT_NODE_DETAILS - -#include "openscad.h" +#include "module.h" +#include "node.h" +#include "context.h" +#include "builtin.h" #include "printutils.h" enum control_type_e { diff --git a/src/csgops.cc b/src/csgops.cc index be29ede..a4780a1 100644 --- a/src/csgops.cc +++ b/src/csgops.cc @@ -18,10 +18,14 @@ * */ -#define INCLUDE_ABSTRACT_NODE_DETAILS - -#include "openscad.h" +#include "module.h" +#include "node.h" +#include "csgterm.h" +#include "builtin.h" #include "printutils.h" +#ifdef ENABLE_CGAL +# include "cgal.h" +#endif enum csg_type_e { CSG_TYPE_UNION, diff --git a/src/csgterm.cc b/src/csgterm.cc index ebad060..bc22511 100644 --- a/src/csgterm.cc +++ b/src/csgterm.cc @@ -18,9 +18,8 @@ * */ -#define INCLUDE_ABSTRACT_NODE_DETAILS - -#include "openscad.h" +#include "csgterm.h" +#include "polyset.h" CSGTerm::CSGTerm(PolySet *polyset, double m[20], QString label) { diff --git a/src/csgterm.h b/src/csgterm.h new file mode 100644 index 0000000..35d071d --- /dev/null +++ b/src/csgterm.h @@ -0,0 +1,51 @@ +#ifndef CSGTERM_H_ +#define CSGTERM_H_ + +#include +#include + +class CSGTerm +{ +public: + enum type_e { + TYPE_PRIMITIVE, + TYPE_UNION, + TYPE_INTERSECTION, + TYPE_DIFFERENCE + }; + + type_e type; + class PolySet *polyset; + QString label; + CSGTerm *left; + CSGTerm *right; + double m[20]; + int refcounter; + + CSGTerm(PolySet *polyset, double m[20], QString label); + CSGTerm(type_e type, CSGTerm *left, CSGTerm *right); + + CSGTerm *normalize(); + CSGTerm *normalize_tail(); + + CSGTerm *link(); + void unlink(); + QString dump(); +}; + +class CSGChain +{ +public: + QVector polysets; + QVector matrices; + QVector types; + QVector labels; + + CSGChain(); + + void add(PolySet *polyset, double *m, CSGTerm::type_e type, QString label); + void import(CSGTerm *term, CSGTerm::type_e type = CSGTerm::TYPE_UNION); + QString dump(); +}; + +#endif diff --git a/src/dxfdata.cc b/src/dxfdata.cc index 864ee7b..a8768d7 100644 --- a/src/dxfdata.cc +++ b/src/dxfdata.cc @@ -18,11 +18,16 @@ * */ -#include "openscad.h" +#include "dxfdata.h" +#include "grid.h" #include "printutils.h" +#include "openscad.h" // handle_dep() #include #include +#include +#include +#include struct Line { typedef DxfData::Point Point; diff --git a/src/dxfdata.h b/src/dxfdata.h new file mode 100644 index 0000000..e88fafd --- /dev/null +++ b/src/dxfdata.h @@ -0,0 +1,50 @@ +#ifndef DXFDATA_H_ +#define DXFDATA_H_ + +#include +#include + +class DxfData +{ +public: + struct Point { + double x, y; + Point() : x(0), y(0) { } + Point(double x, double y) : x(x), y(y) { } + }; + struct Path { + QList points; + bool is_closed, is_inner; + Path() : is_closed(false), is_inner(false) { } + }; + struct Dim { + unsigned int type; + double coords[7][2]; + double angle; + double length; + QString name; + Dim() { + for (int i = 0; i < 7; i++) + for (int j = 0; j < 2; j++) + coords[i][j] = 0; + type = 0; + angle = 0; + length = 0; + } + }; + + QList points; + QList paths; + QList dims; + + DxfData(); + DxfData(double fn, double fs, double fa, QString filename, QString layername = QString(), double xorigin = 0.0, double yorigin = 0.0, double scale = 1.0); + DxfData(const struct CGAL_Nef_polyhedron &N); + + Point *addPoint(double x, double y); + +private: + void fixup_path_direction(); +}; + +#endif diff --git a/src/dxfdim.cc b/src/dxfdim.cc index 359606a..5741df3 100644 --- a/src/dxfdim.cc +++ b/src/dxfdim.cc @@ -18,12 +18,18 @@ * */ -#include "openscad.h" +#include "dxfdim.h" +#include "value.h" +#include "function.h" +#include "dxfdata.h" +#include "builtin.h" #include "printutils.h" +#include #include #include #include +#include QHash dxf_dim_cache; QHash dxf_cross_cache; diff --git a/src/dxfdim.h b/src/dxfdim.h new file mode 100644 index 0000000..9686760 --- /dev/null +++ b/src/dxfdim.h @@ -0,0 +1,10 @@ +#ifndef DXFDIM_H_ +#define DXFDIM_H_ + +#include +#include "value.h" + +extern QHash dxf_cross_cache; +extern QHash dxf_dim_cache; + +#endif diff --git a/src/dxflinextrude.cc b/src/dxflinextrude.cc index f7a1d24..94b6904 100644 --- a/src/dxflinextrude.cc +++ b/src/dxflinextrude.cc @@ -18,10 +18,15 @@ * */ -#define INCLUDE_ABSTRACT_NODE_DETAILS - -#include "openscad.h" +#include "module.h" +#include "node.h" +#include "context.h" #include "printutils.h" +#include "builtin.h" +#include "dxfdata.h" +#include "dxftess.h" +#include "polyset.h" +#include "openscad.h" // get_fragments_from_r() #include #include @@ -29,6 +34,7 @@ #include #include +#include class DxfLinearExtrudeModule : public AbstractModule { diff --git a/src/dxfrotextrude.cc b/src/dxfrotextrude.cc index 427bcb0..ae32a67 100644 --- a/src/dxfrotextrude.cc +++ b/src/dxfrotextrude.cc @@ -18,10 +18,14 @@ * */ -#define INCLUDE_ABSTRACT_NODE_DETAILS - -#include "openscad.h" +#include "module.h" +#include "node.h" +#include "context.h" #include "printutils.h" +#include "builtin.h" +#include "polyset.h" +#include "dxfdata.h" +#include "openscad.h" // get_fragments_from_r() #include #include @@ -29,6 +33,7 @@ #include #include +#include class DxfRotateExtrudeModule : public AbstractModule { diff --git a/src/dxftess-cgal.cc b/src/dxftess-cgal.cc index fa879b6..14fbc5e 100644 --- a/src/dxftess-cgal.cc +++ b/src/dxftess-cgal.cc @@ -1,4 +1,3 @@ -#include "openscad.h" #include "printutils.h" #include diff --git a/src/dxftess-glu.cc b/src/dxftess-glu.cc index 9e5f530..73eae63 100644 --- a/src/dxftess-glu.cc +++ b/src/dxftess-glu.cc @@ -1,3 +1,15 @@ +#include "dxftess.h" +#include "dxfdata.h" +#include "polyset.h" +#include "grid.h" + +#ifdef ENABLE_OPENCSG +// this must be included before the GL headers +# include +#endif +#include +#include + #ifdef WIN32 # define STDCALL __stdcall #else diff --git a/src/dxftess.cc b/src/dxftess.cc index c0d4c0c..5c91924 100644 --- a/src/dxftess.cc +++ b/src/dxftess.cc @@ -18,9 +18,6 @@ * */ -#define INCLUDE_ABSTRACT_NODE_DETAILS - -#include "openscad.h" #include "printutils.h" #ifdef CGAL_TESSELATE diff --git a/src/dxftess.h b/src/dxftess.h new file mode 100644 index 0000000..19fca7d --- /dev/null +++ b/src/dxftess.h @@ -0,0 +1,9 @@ +#ifndef DXFTESS_H_ +#define DXFTESS_H_ + +class DxfData; +class PolySet; +void dxf_tesselate(PolySet *ps, DxfData *dxf, double rot, bool up, bool do_triangle_splitting, double h); +void dxf_border_to_ps(PolySet *ps, DxfData *dxf); + +#endif diff --git a/src/export.cc b/src/export.cc index cdfbef6..9bb5816 100644 --- a/src/export.cc +++ b/src/export.cc @@ -18,15 +18,15 @@ * */ -#define INCLUDE_ABSTRACT_NODE_DETAILS - -#include "openscad.h" #include "printutils.h" #include "MainWindow.h" +#include "dxfdata.h" #include +#include #ifdef ENABLE_CGAL +#include "cgal.h" void export_stl(CGAL_Nef_polyhedron *root_N, QString filename, QProgressDialog *pd) { diff --git a/src/export.h b/src/export.h new file mode 100644 index 0000000..49319ba --- /dev/null +++ b/src/export.h @@ -0,0 +1,10 @@ +#ifndef EXPORT_H_ +#define EXPORT_H_ + +#ifdef ENABLE_CGAL +void export_stl(class CGAL_Nef_polyhedron *root_N, QString filename, class QProgressDialog *pd); +void export_off(CGAL_Nef_polyhedron *root_N, QString filename, QProgressDialog *pd); +void export_dxf(CGAL_Nef_polyhedron *root_N, QString filename, QProgressDialog *pd); +#endif + +#endif diff --git a/src/expr.cc b/src/expr.cc index e20e977..860cb96 100644 --- a/src/expr.cc +++ b/src/expr.cc @@ -18,7 +18,9 @@ * */ -#include "openscad.h" +#include "expression.h" +#include "value.h" +#include "context.h" Expression::Expression() { diff --git a/src/expression.h b/src/expression.h new file mode 100644 index 0000000..dadcea0 --- /dev/null +++ b/src/expression.h @@ -0,0 +1,40 @@ +#ifndef EXPRESSION_H_ +#define EXPRESSION_H_ + +#include +#include + +class Expression +{ +public: + QVector children; + + class Value *const_value; + QString var_name; + + QString call_funcname; + QVector call_argnames; + + // Boolean: ! && || + // Operators: * / % + - + // Relations: < <= == != >= > + // Vector element: [] + // Condition operator: ?: + // Invert (prefix '-'): I + // Constant value: C + // Create Range: R + // Create Vector: V + // Create Matrix: M + // Lookup Variable: L + // Lookup member per name: N + // Function call: F + QString type; + + Expression(); + ~Expression(); + + Value evaluate(const class Context *context) const; + QString dump() const; +}; + +#endif diff --git a/src/func.cc b/src/func.cc index 1d70d98..f92d0b4 100644 --- a/src/func.cc +++ b/src/func.cc @@ -18,7 +18,12 @@ * */ -#include "openscad.h" +#include "function.h" +#include "expression.h" +#include "context.h" +#include "dxfdim.h" +#include "builtin.h" +#include AbstractFunction::~AbstractFunction() { diff --git a/src/function.h b/src/function.h new file mode 100644 index 0000000..31ca2d6 --- /dev/null +++ b/src/function.h @@ -0,0 +1,43 @@ +#ifndef FUNCTION_H_ +#define FUNCTION_H_ + +#include "value.h" +#include + +class AbstractFunction +{ +public: + virtual ~AbstractFunction(); + virtual Value evaluate(const class Context *ctx, const QVector &call_argnames, const QVector &call_argvalues) const; + virtual QString dump(QString indent, QString name) const; +}; + +class BuiltinFunction : public AbstractFunction +{ +public: + typedef Value (*eval_func_t)(const QVector &argnames, const QVector &args); + eval_func_t eval_func; + + BuiltinFunction(eval_func_t f) : eval_func(f) { } + virtual ~BuiltinFunction(); + + virtual Value evaluate(const Context *ctx, const QVector &call_argnames, const QVector &call_argvalues) const; + virtual QString dump(QString indent, QString name) const; +}; + +class Function : public AbstractFunction +{ +public: + QVector argnames; + QVector argexpr; + + Expression *expr; + + Function() { } + virtual ~Function(); + + virtual Value evaluate(const Context *ctx, const QVector &call_argnames, const QVector &call_argvalues) const; + virtual QString dump(QString indent, QString name) const; +}; + +#endif diff --git a/src/glview.cc b/src/glview.cc index 1068318..72e9ff2 100644 --- a/src/glview.cc +++ b/src/glview.cc @@ -18,7 +18,6 @@ * */ -#include "openscad.h" #include "GLView.h" #include "Preferences.h" @@ -27,6 +26,7 @@ #include #include #include +#include #define FAR_FAR_AWAY 100000.0 diff --git a/src/grid.h b/src/grid.h new file mode 100644 index 0000000..2b461f4 --- /dev/null +++ b/src/grid.h @@ -0,0 +1,136 @@ +#ifndef GRID_H_ +#define GRID_H_ + +#include +#include + +const double GRID_COARSE = 0.001; +const double GRID_FINE = 0.000001; + +template +class Grid2d +{ +public: + double res; + QHash, T> db; + + Grid2d(double resolution) { + res = resolution; + } + /*! + Aligns x,y to the grid or to existing point if one close enough exists. + Returns the value stored if a point already existing or an uninitialized new value + if not. + */ + T &align(double &x, double &y) { + int64_t ix = (int64_t)round(x / res); + int64_t iy = (int64_t)round(y / res); + if (!db.contains(QPair(ix, iy))) { + int dist = 10; + for (int64_t jx = ix - 1; jx <= ix + 1; jx++) { + for (int64_t jy = iy - 1; jy <= iy + 1; jy++) { + if (!db.contains(QPair(jx, jy))) + continue; + if (abs(ix-jx) + abs(iy-jy) < dist) { + dist = abs(ix-jx) + abs(iy-jy); + ix = jx; + iy = jy; + } + } + } + } + x = ix * res, y = iy * res; + return db[QPair(ix, iy)]; + } + bool has(double x, double y) const { + int64_t ix = (int64_t)round(x / res); + int64_t iy = (int64_t)round(y / res); + if (db.contains(QPair(ix, iy))) + return true; + for (int64_t jx = ix - 1; jx <= ix + 1; jx++) + for (int64_t jy = iy - 1; jy <= iy + 1; jy++) { + if (db.contains(QPair(jx, jy))) + return true; + } + return false; + } + bool eq(double x1, double y1, double x2, double y2) { + align(x1, y1); + align(x2, y2); + if (fabs(x1 - x2) < res && fabs(y1 - y2) < res) + return true; + return false; + } + T &data(double x, double y) { + return align(x, y); + } + T &operator()(double x, double y) { + return align(x, y); + } +}; + +template +class Grid3d +{ +public: + double res; + QHash,int64_t>, T> db; + + Grid3d(double resolution) { + res = resolution; + } + T &align(double &x, double &y, double &z) { + int64_t ix = (int64_t)round(x / res); + int64_t iy = (int64_t)round(y / res); + int64_t iz = (int64_t)round(z / res); + if (!db.contains(QPair,int64_t>(QPair(ix, iy), iz))) { + int dist = 10; + for (int64_t jx = ix - 1; jx <= ix + 1; jx++) { + for (int64_t jy = iy - 1; jy <= iy + 1; jy++) { + for (int64_t jz = iz - 1; jz <= iz + 1; jz++) { + if (!db.contains(QPair,int64_t>(QPair(jx, jy), jz))) + continue; + if (abs(ix-jx) + abs(iy-jy) + abs(iz-jz) < dist) { + dist = abs(ix-jx) + abs(iy-jy) + abs(iz-jz); + ix = jx; + iy = jy; + iz = jz; + } + } + } + } + } + x = ix * res, y = iy * res, z = iz * res; + return db[QPair,int64_t>(QPair(ix, iy), iz)]; + } + bool has(double x, double y, double z) { + int64_t ix = (int64_t)round(x / res); + int64_t iy = (int64_t)round(y / res); + int64_t iz = (int64_t)round(z / res); + if (db.contains(QPair,int64_t>(QPair(ix, iy), iz))) + return true; + for (int64_t jx = ix - 1; jx <= ix + 1; jx++) + for (int64_t jy = iy - 1; jy <= iy + 1; jy++) + for (int64_t jz = iz - 1; jz <= iz + 1; jz++) { + if (db.contains(QPair,int64_t>(QPair(jx, jy), jz))) + return true; + } + return false; + + } + bool eq(double x1, double y1, double z1, double x2, double y2, double z2) { + align(x1, y1, z1); + align(x2, y2, z2); + if (fabs(x1 - x2) < res && fabs(y1 - y2) < res && fabs(z1 - z2) < res) + return true; + return false; + } + T &data(double x, double y, double z) { + return align(x, y, z); + } + T &operator()(double x, double y, double z) { + return align(x, y, z); + } +}; + +#endif diff --git a/src/highlighter.cc b/src/highlighter.cc index 5e15867..5a9f7b1 100644 --- a/src/highlighter.cc +++ b/src/highlighter.cc @@ -18,7 +18,8 @@ * */ -#include "openscad.h" +#include "highlighter.h" +#include "openscad.h" // extern int parser_error_pos; Highlighter::Highlighter(QTextDocument *parent) : QSyntaxHighlighter(parent) diff --git a/src/highlighter.h b/src/highlighter.h new file mode 100644 index 0000000..2eead6d --- /dev/null +++ b/src/highlighter.h @@ -0,0 +1,13 @@ +#ifndef HIGHLIGHTER_H_ +#define HIGHLIGHTER_H_ + +#include + +class Highlighter : public QSyntaxHighlighter +{ +public: + Highlighter(QTextDocument *parent); + void highlightBlock(const QString &text); +}; + +#endif diff --git a/src/import.cc b/src/import.cc index c9b1a66..4fe6c09 100644 --- a/src/import.cc +++ b/src/import.cc @@ -18,10 +18,15 @@ * */ -#define INCLUDE_ABSTRACT_NODE_DETAILS - -#include "openscad.h" +#include "module.h" +#include "node.h" +#include "polyset.h" +#include "context.h" +#include "builtin.h" +#include "dxfdata.h" +#include "dxftess.h" #include "printutils.h" +#include "openscad.h" // handle_dep() #include #include diff --git a/src/lexer.l b/src/lexer.l new file mode 100644 index 0000000..c9e9332 --- /dev/null +++ b/src/lexer.l @@ -0,0 +1,114 @@ +/* + * OpenSCAD (www.openscad.at) + * Copyright (C) 2009 Clifford Wolf + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +%{ + +#include "openscad.h" +#include "printutils.h" +#include "parser_yacc.h" + +int lexerget_lineno(void); +#ifdef __GNUC__ +static void yyunput(int, char*) __attribute__((unused)); +#endif +extern const char *parser_input_buffer; + +#define YY_INPUT(buf,result,max_size) { \ + if (yyin && yyin != stdin) { \ + int c = fgetc(yyin); \ + if (c >= 0) { \ + result = 1; \ + buf[0] = c; \ + } else { \ + result = YY_NULL; \ + } \ + } else { \ + if (*parser_input_buffer) { \ + result = 1; \ + buf[0] = *(parser_input_buffer++); \ + parser_error_pos++; \ + } else { \ + result = YY_NULL; \ + } \ + } \ +} + +%} + +%option yylineno +%option noyywrap + +%x comment + +%% + +"<"[^ \t\n>]+">" { + char *filename = strdup(yytext+1); + filename[strlen(filename)-1] = 0; + handle_dep(filename); + yyin = fopen(filename, "r"); + if (!yyin) { + PRINTF("WARNING: Can't open input file `%s'.", filename); + } else { + yypush_buffer_state(yy_create_buffer( yyin, YY_BUF_SIZE )); + BEGIN(INITIAL); + } + free(filename); +} + +<> { + if (yyin && yyin != stdin) + fclose(yyin); + yypop_buffer_state(); + if (!YY_CURRENT_BUFFER) + yyterminate(); +} + +"module" return TOK_MODULE; +"function" return TOK_FUNCTION; + +"true" return TOK_TRUE; +"false" return TOK_FALSE; +"undef" return TOK_UNDEF; + +[0-9][0-9.]* { parserlval.number = QString(yytext).toDouble(); return TOK_NUMBER; } +"$"?[a-zA-Z0-9_]+ { parserlval.text = strdup(yytext); return TOK_ID; } + +\"[^"]*\" { + parserlval.text = strdup(yytext+1); + parserlval.text[strlen(parserlval.text)-1] = 0; + return TOK_STRING; +} + +[\n\r\t ] +\/\/[^\n]*\n? +"/*" BEGIN(comment); +"*/" BEGIN(INITIAL); +.|\n + +"<=" return LE; +">=" return GE; +"==" return EQ; +"!=" return NE; +"&&" return AND; +"||" return OR; + +. { return yytext[0]; } + diff --git a/src/mainwin.cc b/src/mainwin.cc index 7abb4ed..0e10812 100644 --- a/src/mainwin.cc +++ b/src/mainwin.cc @@ -18,12 +18,19 @@ * */ -#define INCLUDE_ABSTRACT_NODE_DETAILS - -#include "openscad.h" #include "MainWindow.h" #include "Preferences.h" #include "printutils.h" +#include "node.h" +#include "polyset.h" +#include "csgterm.h" +#include "highlighter.h" +#include "grid.h" +#include "dxfdata.h" +#include "dxfdim.h" +#include "export.h" +#include "builtin.h" +#include "dxftess.h" #include #include diff --git a/src/module.cc b/src/module.cc index a319e1e..6352658 100644 --- a/src/module.cc +++ b/src/module.cc @@ -18,9 +18,12 @@ * */ -#define INCLUDE_ABSTRACT_NODE_DETAILS - -#include "openscad.h" +#include "module.h" +#include "node.h" +#include "context.h" +#include "expression.h" +#include "function.h" +#include "builtin.h" #include "printutils.h" AbstractModule::~AbstractModule() @@ -201,174 +204,3 @@ void destroy_builtin_modules() delete v; builtin_modules.clear(); } - -int AbstractNode::idx_counter; - -AbstractNode::AbstractNode(const ModuleInstantiation *mi) -{ - modinst = mi; - idx = idx_counter++; -} - -AbstractNode::~AbstractNode() -{ - foreach (AbstractNode *v, children) - delete v; -} - -QString AbstractNode::mk_cache_id() const -{ - QString cache_id = dump(""); - cache_id.remove(QRegExp("[a-zA-Z_][a-zA-Z_0-9]*:")); - cache_id.remove(' '); - cache_id.remove('\t'); - cache_id.remove('\n'); - return cache_id; -} - -#ifdef ENABLE_CGAL - -AbstractNode::cgal_nef_cache_entry::cgal_nef_cache_entry(CGAL_Nef_polyhedron N) : - N(N), msg(print_messages_stack.last()) { }; - -QCache AbstractNode::cgal_nef_cache(100000); - -static CGAL_Nef_polyhedron render_cgal_nef_polyhedron_backend(const AbstractNode *that, bool intersect) -{ - QString cache_id = that->mk_cache_id(); - if (that->cgal_nef_cache.contains(cache_id)) { - that->progress_report(); - PRINT(that->cgal_nef_cache[cache_id]->msg); - return that->cgal_nef_cache[cache_id]->N; - } - - print_messages_push(); - - bool first = true; - CGAL_Nef_polyhedron N; - foreach (AbstractNode *v, that->children) { - if (v->modinst->tag_background) - continue; - if (first) { - N = v->render_cgal_nef_polyhedron(); - if (N.dim != 0) - first = false; - } else if (N.dim == 2) { - if (intersect) - N.p2 *= v->render_cgal_nef_polyhedron().p2; - else - N.p2 += v->render_cgal_nef_polyhedron().p2; - } else { - if (intersect) - N.p3 *= v->render_cgal_nef_polyhedron().p3; - else - N.p3 += v->render_cgal_nef_polyhedron().p3; - } - } - - that->cgal_nef_cache.insert(cache_id, new AbstractNode::cgal_nef_cache_entry(N), N.weight()); - that->progress_report(); - print_messages_pop(); - - return N; -} - -CGAL_Nef_polyhedron AbstractNode::render_cgal_nef_polyhedron() const -{ - return render_cgal_nef_polyhedron_backend(this, false); -} - -CGAL_Nef_polyhedron AbstractIntersectionNode::render_cgal_nef_polyhedron() const -{ - return render_cgal_nef_polyhedron_backend(this, true); -} - -#endif /* ENABLE_CGAL */ - -static CSGTerm *render_csg_term_backend(const AbstractNode *that, bool intersect, double m[20], QVector *highlights, QVector *background) -{ - CSGTerm *t1 = NULL; - foreach(AbstractNode *v, that->children) { - CSGTerm *t2 = v->render_csg_term(m, highlights, background); - if (t2 && !t1) { - t1 = t2; - } else if (t2 && t1) { - if (intersect) - t1 = new CSGTerm(CSGTerm::TYPE_INTERSECTION, t1, t2); - else - t1 = new CSGTerm(CSGTerm::TYPE_UNION, t1, t2); - } - } - if (t1 && that->modinst->tag_highlight && highlights) - highlights->append(t1->link()); - if (t1 && that->modinst->tag_background && background) { - background->append(t1); - return NULL; - } - return t1; -} - -CSGTerm *AbstractNode::render_csg_term(double m[20], QVector *highlights, QVector *background) const -{ - return render_csg_term_backend(this, false, m, highlights, background); -} - -CSGTerm *AbstractIntersectionNode::render_csg_term(double m[20], QVector *highlights, QVector *background) const -{ - return render_csg_term_backend(this, true, m, highlights, background); -} - -QString AbstractNode::dump(QString indent) const -{ - if (dump_cache.isEmpty()) { - QString text = indent + QString("n%1: group() {\n").arg(idx); - foreach (AbstractNode *v, children) - text += v->dump(indent + QString("\t")); - ((AbstractNode*)this)->dump_cache = text + indent + "}\n"; - } - return dump_cache; -} - -QString AbstractIntersectionNode::dump(QString indent) const -{ - if (dump_cache.isEmpty()) { - QString text = indent + QString("n%1: intersection() {\n").arg(idx); - foreach (AbstractNode *v, children) - text += v->dump(indent + QString("\t")); - ((AbstractNode*)this)->dump_cache = text + indent + "}\n"; - } - return dump_cache; -} - -int progress_report_count; -void (*progress_report_f)(const class AbstractNode*, void*, int); -void *progress_report_vp; - -void AbstractNode::progress_prepare() -{ - foreach (AbstractNode *v, children) - v->progress_prepare(); - progress_mark = ++progress_report_count; -} - -void AbstractNode::progress_report() const -{ - if (progress_report_f) - progress_report_f(this, progress_report_vp, progress_mark); -} - -void progress_report_prep(AbstractNode *root, void (*f)(const class AbstractNode *node, void *vp, int mark), void *vp) -{ - progress_report_count = 0; - progress_report_f = f; - progress_report_vp = vp; - root->progress_prepare(); -} - -void progress_report_fin() -{ - progress_report_count = 0; - progress_report_f = NULL; - progress_report_vp = NULL; -} - diff --git a/src/module.h b/src/module.h new file mode 100644 index 0000000..35cc872 --- /dev/null +++ b/src/module.h @@ -0,0 +1,60 @@ +#ifndef MODULE_H_ +#define MODULE_H_ + +#include +#include +#include +#include "value.h" + +class ModuleInstantiation +{ +public: + QString label; + QString modname; + QVector argnames; + QVector argexpr; + QVector argvalues; + QVector children; + + bool tag_root; + bool tag_highlight; + bool tag_background; + const class Context *ctx; + + ModuleInstantiation() : tag_root(false), tag_highlight(false), tag_background(false), ctx(NULL) { } + ~ModuleInstantiation(); + + QString dump(QString indent) const; + class AbstractNode *evaluate(const Context *ctx) const; +}; + +class AbstractModule +{ +public: + virtual ~AbstractModule(); + virtual class AbstractNode *evaluate(const Context *ctx, const ModuleInstantiation *inst) const; + virtual QString dump(QString indent, QString name) const; +}; + +class Module : public AbstractModule +{ +public: + QVector argnames; + QVector argexpr; + + QVector assignments_var; + QVector assignments_expr; + + QHash functions; + QHash modules; + + QVector children; + + Module() { } + virtual ~Module(); + + virtual AbstractNode *evaluate(const Context *ctx, const ModuleInstantiation *inst) const; + virtual QString dump(QString indent, QString name) const; +}; + +#endif diff --git a/src/nef2dxf.cc b/src/nef2dxf.cc index 9c69e84..6b60536 100644 --- a/src/nef2dxf.cc +++ b/src/nef2dxf.cc @@ -18,9 +18,9 @@ * */ -#define INCLUDE_ABSTRACT_NODE_DETAILS - -#include "openscad.h" +#include "dxfdata.h" +#include "grid.h" +#include "cgal.h" DxfData::DxfData(const struct CGAL_Nef_polyhedron &N) { diff --git a/src/node.cc b/src/node.cc new file mode 100644 index 0000000..e969be2 --- /dev/null +++ b/src/node.cc @@ -0,0 +1,196 @@ +/* + * OpenSCAD (www.openscad.at) + * Copyright (C) 2009 Clifford Wolf + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#include "printutils.h" +#include "node.h" +#include "module.h" +#include "csgterm.h" +#include + +int AbstractNode::idx_counter; + +AbstractNode::AbstractNode(const ModuleInstantiation *mi) +{ + modinst = mi; + idx = idx_counter++; +} + +AbstractNode::~AbstractNode() +{ + foreach (AbstractNode *v, children) + delete v; +} + +QString AbstractNode::mk_cache_id() const +{ + QString cache_id = dump(""); + cache_id.remove(QRegExp("[a-zA-Z_][a-zA-Z_0-9]*:")); + cache_id.remove(' '); + cache_id.remove('\t'); + cache_id.remove('\n'); + return cache_id; +} + +#ifdef ENABLE_CGAL + +AbstractNode::cgal_nef_cache_entry::cgal_nef_cache_entry(CGAL_Nef_polyhedron N) : + N(N), msg(print_messages_stack.last()) { }; + +QCache AbstractNode::cgal_nef_cache(100000); + +static CGAL_Nef_polyhedron render_cgal_nef_polyhedron_backend(const AbstractNode *that, bool intersect) +{ + QString cache_id = that->mk_cache_id(); + if (that->cgal_nef_cache.contains(cache_id)) { + that->progress_report(); + PRINT(that->cgal_nef_cache[cache_id]->msg); + return that->cgal_nef_cache[cache_id]->N; + } + + print_messages_push(); + + bool first = true; + CGAL_Nef_polyhedron N; + foreach (AbstractNode *v, that->children) { + if (v->modinst->tag_background) + continue; + if (first) { + N = v->render_cgal_nef_polyhedron(); + if (N.dim != 0) + first = false; + } else if (N.dim == 2) { + if (intersect) + N.p2 *= v->render_cgal_nef_polyhedron().p2; + else + N.p2 += v->render_cgal_nef_polyhedron().p2; + } else { + if (intersect) + N.p3 *= v->render_cgal_nef_polyhedron().p3; + else + N.p3 += v->render_cgal_nef_polyhedron().p3; + } + } + + that->cgal_nef_cache.insert(cache_id, new AbstractNode::cgal_nef_cache_entry(N), N.weight()); + that->progress_report(); + print_messages_pop(); + + return N; +} + +CGAL_Nef_polyhedron AbstractNode::render_cgal_nef_polyhedron() const +{ + return render_cgal_nef_polyhedron_backend(this, false); +} + +CGAL_Nef_polyhedron AbstractIntersectionNode::render_cgal_nef_polyhedron() const +{ + return render_cgal_nef_polyhedron_backend(this, true); +} + +#endif /* ENABLE_CGAL */ + +static CSGTerm *render_csg_term_backend(const AbstractNode *that, bool intersect, double m[20], QVector *highlights, QVector *background) +{ + CSGTerm *t1 = NULL; + foreach(AbstractNode *v, that->children) { + CSGTerm *t2 = v->render_csg_term(m, highlights, background); + if (t2 && !t1) { + t1 = t2; + } else if (t2 && t1) { + if (intersect) + t1 = new CSGTerm(CSGTerm::TYPE_INTERSECTION, t1, t2); + else + t1 = new CSGTerm(CSGTerm::TYPE_UNION, t1, t2); + } + } + if (t1 && that->modinst->tag_highlight && highlights) + highlights->append(t1->link()); + if (t1 && that->modinst->tag_background && background) { + background->append(t1); + return NULL; + } + return t1; +} + +CSGTerm *AbstractNode::render_csg_term(double m[20], QVector *highlights, QVector *background) const +{ + return render_csg_term_backend(this, false, m, highlights, background); +} + +CSGTerm *AbstractIntersectionNode::render_csg_term(double m[20], QVector *highlights, QVector *background) const +{ + return render_csg_term_backend(this, true, m, highlights, background); +} + +QString AbstractNode::dump(QString indent) const +{ + if (dump_cache.isEmpty()) { + QString text = indent + QString("n%1: group() {\n").arg(idx); + foreach (AbstractNode *v, children) + text += v->dump(indent + QString("\t")); + ((AbstractNode*)this)->dump_cache = text + indent + "}\n"; + } + return dump_cache; +} + +QString AbstractIntersectionNode::dump(QString indent) const +{ + if (dump_cache.isEmpty()) { + QString text = indent + QString("n%1: intersection() {\n").arg(idx); + foreach (AbstractNode *v, children) + text += v->dump(indent + QString("\t")); + ((AbstractNode*)this)->dump_cache = text + indent + "}\n"; + } + return dump_cache; +} + +int progress_report_count; +void (*progress_report_f)(const class AbstractNode*, void*, int); +void *progress_report_vp; + +void AbstractNode::progress_prepare() +{ + foreach (AbstractNode *v, children) + v->progress_prepare(); + progress_mark = ++progress_report_count; +} + +void AbstractNode::progress_report() const +{ + if (progress_report_f) + progress_report_f(this, progress_report_vp, progress_mark); +} + +void progress_report_prep(AbstractNode *root, void (*f)(const class AbstractNode *node, void *vp, int mark), void *vp) +{ + progress_report_count = 0; + progress_report_f = f; + progress_report_vp = vp; + root->progress_prepare(); +} + +void progress_report_fin() +{ + progress_report_count = 0; + progress_report_f = NULL; + progress_report_vp = NULL; +} + diff --git a/src/node.h b/src/node.h new file mode 100644 index 0000000..9121a3b --- /dev/null +++ b/src/node.h @@ -0,0 +1,75 @@ +#ifndef NODE_H_ +#define NODE_H_ + +#include +#include + +#ifdef ENABLE_CGAL +#include "cgal.h" +#endif + +extern int progress_report_count; +extern void (*progress_report_f)(const class AbstractNode*, void*, int); +extern void *progress_report_vp; + +void progress_report_prep(AbstractNode *root, void (*f)(const class AbstractNode *node, void *vp, int mark), void *vp); +void progress_report_fin(); + +class AbstractNode +{ +public: + QVector children; + const class ModuleInstantiation *modinst; + + int progress_mark; + void progress_prepare(); + void progress_report() const; + + int idx; + static int idx_counter; + QString dump_cache; + + AbstractNode(const ModuleInstantiation *mi); + virtual ~AbstractNode(); + virtual QString mk_cache_id() const; +#ifdef ENABLE_CGAL + struct cgal_nef_cache_entry { + CGAL_Nef_polyhedron N; + QString msg; + cgal_nef_cache_entry(CGAL_Nef_polyhedron N); + }; + static QCache cgal_nef_cache; + virtual CGAL_Nef_polyhedron render_cgal_nef_polyhedron() const; +#endif + virtual class CSGTerm *render_csg_term(double m[20], QVector *highlights, QVector *background) const; + virtual QString dump(QString indent) const; +}; + +class AbstractIntersectionNode : public AbstractNode +{ +public: + AbstractIntersectionNode(const ModuleInstantiation *mi) : AbstractNode(mi) { }; +#ifdef ENABLE_CGAL + virtual CGAL_Nef_polyhedron render_cgal_nef_polyhedron() const; +#endif + virtual CSGTerm *render_csg_term(double m[20], QVector *highlights, QVector *background) const; + virtual QString dump(QString indent) const; +}; + +class AbstractPolyNode : public AbstractNode +{ +public: + enum render_mode_e { + RENDER_CGAL, + RENDER_OPENCSG + }; + AbstractPolyNode(const ModuleInstantiation *mi) : AbstractNode(mi) { }; + virtual class PolySet *render_polyset(render_mode_e mode) const; +#ifdef ENABLE_CGAL + virtual CGAL_Nef_polyhedron render_cgal_nef_polyhedron() const; +#endif + virtual CSGTerm *render_csg_term(double m[20], QVector *highlights, QVector *background) const; + static CSGTerm *render_csg_term_from_ps(double m[20], QVector *highlights, QVector *background, PolySet *ps, const ModuleInstantiation *modinst, int idx); +}; + +#endif diff --git a/src/openscad.cc b/src/openscad.cc index 8c521b6..05b673b 100644 --- a/src/openscad.cc +++ b/src/openscad.cc @@ -22,6 +22,16 @@ #include "openscad.h" #include "MainWindow.h" +#include "node.h" +#include "module.h" +#include "context.h" +#include "value.h" +#include "export.h" +#include "builtin.h" + +#ifdef ENABLE_CGAL +#include "cgal.h" +#endif #include #include @@ -162,6 +172,7 @@ int main(int argc, char **argv) root_ctx.set_variable("$vpt", zero3); root_ctx.set_variable("$vpr", zero3); + AbstractModule *root_module; ModuleInstantiation root_inst; AbstractNode *root_node; diff --git a/src/openscad.h b/src/openscad.h index 03ea1cb..5e2f19c 100644 --- a/src/openscad.h +++ b/src/openscad.h @@ -26,712 +26,19 @@ # include #endif -#include - -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include - -#include -#include - // for win32 and maybe others.. #ifndef M_PI # define M_PI 3.14159265358979323846 #endif -class Value; -class Expression; - -class AbstractFunction; -class BuiltinFunction; -class Function; - -class AbstractModule; -class ModuleInstantiation; -class Module; - -class Context; -class PolySet; -class CSGTerm; -class CSGChain; -class AbstractNode; -class AbstractIntersectionNode; -class AbstractPolyNode; -struct CGAL_Nef_polyhedron; - -const double GRID_COARSE = 0.001; -const double GRID_FINE = 0.000001; - -template -class Grid2d -{ -public: - double res; - QHash, T> db; - - Grid2d(double resolution) { - res = resolution; - } - /*! - Aligns x,y to the grid or to existing point if one close enough exists. - Returns the value stored if a point already existing or an uninitialized new value - if not. - */ - T &align(double &x, double &y) { - int64_t ix = (int64_t)round(x / res); - int64_t iy = (int64_t)round(y / res); - if (!db.contains(QPair(ix, iy))) { - int dist = 10; - for (int64_t jx = ix - 1; jx <= ix + 1; jx++) { - for (int64_t jy = iy - 1; jy <= iy + 1; jy++) { - if (!db.contains(QPair(jx, jy))) - continue; - if (abs(ix-jx) + abs(iy-jy) < dist) { - dist = abs(ix-jx) + abs(iy-jy); - ix = jx; - iy = jy; - } - } - } - } - x = ix * res, y = iy * res; - return db[QPair(ix, iy)]; - } - bool has(double x, double y) const { - int64_t ix = (int64_t)round(x / res); - int64_t iy = (int64_t)round(y / res); - if (db.contains(QPair(ix, iy))) - return true; - for (int64_t jx = ix - 1; jx <= ix + 1; jx++) - for (int64_t jy = iy - 1; jy <= iy + 1; jy++) { - if (db.contains(QPair(jx, jy))) - return true; - } - return false; - } - bool eq(double x1, double y1, double x2, double y2) { - align(x1, y1); - align(x2, y2); - if (fabs(x1 - x2) < res && fabs(y1 - y2) < res) - return true; - return false; - } - T &data(double x, double y) { - return align(x, y); - } - T &operator()(double x, double y) { - return align(x, y); - } -}; - -template -class Grid3d -{ -public: - double res; - QHash,int64_t>, T> db; - - Grid3d(double resolution) { - res = resolution; - } - T &align(double &x, double &y, double &z) { - int64_t ix = (int64_t)round(x / res); - int64_t iy = (int64_t)round(y / res); - int64_t iz = (int64_t)round(z / res); - if (!db.contains(QPair,int64_t>(QPair(ix, iy), iz))) { - int dist = 10; - for (int64_t jx = ix - 1; jx <= ix + 1; jx++) { - for (int64_t jy = iy - 1; jy <= iy + 1; jy++) { - for (int64_t jz = iz - 1; jz <= iz + 1; jz++) { - if (!db.contains(QPair,int64_t>(QPair(jx, jy), jz))) - continue; - if (abs(ix-jx) + abs(iy-jy) + abs(iz-jz) < dist) { - dist = abs(ix-jx) + abs(iy-jy) + abs(iz-jz); - ix = jx; - iy = jy; - iz = jz; - } - } - } - } - } - x = ix * res, y = iy * res, z = iz * res; - return db[QPair,int64_t>(QPair(ix, iy), iz)]; - } - bool has(double x, double y, double z) { - int64_t ix = (int64_t)round(x / res); - int64_t iy = (int64_t)round(y / res); - int64_t iz = (int64_t)round(z / res); - if (db.contains(QPair,int64_t>(QPair(ix, iy), iz))) - return true; - for (int64_t jx = ix - 1; jx <= ix + 1; jx++) - for (int64_t jy = iy - 1; jy <= iy + 1; jy++) - for (int64_t jz = iz - 1; jz <= iz + 1; jz++) { - if (db.contains(QPair,int64_t>(QPair(jx, jy), jz))) - return true; - } - return false; - - } - bool eq(double x1, double y1, double z1, double x2, double y2, double z2) { - align(x1, y1, z1); - align(x2, y2, z2); - if (fabs(x1 - x2) < res && fabs(y1 - y2) < res && fabs(z1 - z2) < res) - return true; - return false; - } - T &data(double x, double y, double z) { - return align(x, y, z); - } - T &operator()(double x, double y, double z) { - return align(x, y, z); - } -}; - -class Value -{ -public: - enum type_e { - UNDEFINED, - BOOL, - NUMBER, - RANGE, - VECTOR, - STRING - }; - - enum type_e type; - - bool b; - double num; - QVector vec; - double range_begin; - double range_step; - double range_end; - QString text; - - Value(); - ~Value(); - - Value(bool v); - Value(double v); - Value(const QString &t); - - Value(const Value &v); - Value& operator = (const Value &v); - - Value operator ! () const; - Value operator && (const Value &v) const; - Value operator || (const Value &v) const; - - Value operator + (const Value &v) const; - Value operator - (const Value &v) const; - Value operator * (const Value &v) const; - Value operator / (const Value &v) const; - Value operator % (const Value &v) const; - - Value operator < (const Value &v) const; - Value operator <= (const Value &v) const; - Value operator == (const Value &v) const; - Value operator != (const Value &v) const; - Value operator >= (const Value &v) const; - Value operator > (const Value &v) const; - - Value inv() const; - - bool getnum(double &v) const; - bool getv2(double &x, double &y) const; - bool getv3(double &x, double &y, double &z) const; - - QString dump() const; - -private: - void reset_undef(); -}; - -class Expression -{ -public: - QVector children; - - Value *const_value; - QString var_name; - - QString call_funcname; - QVector call_argnames; - - // Boolean: ! && || - // Operators: * / % + - - // Relations: < <= == != >= > - // Vector element: [] - // Condition operator: ?: - // Invert (prefix '-'): I - // Constant value: C - // Create Range: R - // Create Vector: V - // Create Matrix: M - // Lookup Variable: L - // Lookup member per name: N - // Function call: F - QString type; - - Expression(); - ~Expression(); - - Value evaluate(const Context *context) const; - QString dump() const; -}; - -class AbstractFunction -{ -public: - virtual ~AbstractFunction(); - virtual Value evaluate(const Context *ctx, const QVector &call_argnames, const QVector &call_argvalues) const; - virtual QString dump(QString indent, QString name) const; -}; - -class BuiltinFunction : public AbstractFunction -{ -public: - typedef Value (*eval_func_t)(const QVector &argnames, const QVector &args); - eval_func_t eval_func; - - BuiltinFunction(eval_func_t f) : eval_func(f) { } - virtual ~BuiltinFunction(); - - virtual Value evaluate(const Context *ctx, const QVector &call_argnames, const QVector &call_argvalues) const; - virtual QString dump(QString indent, QString name) const; -}; - -class Function : public AbstractFunction -{ -public: - QVector argnames; - QVector argexpr; - - Expression *expr; - - Function() { } - virtual ~Function(); - - virtual Value evaluate(const Context *ctx, const QVector &call_argnames, const QVector &call_argvalues) const; - virtual QString dump(QString indent, QString name) const; -}; - -extern QHash builtin_functions; -extern void initialize_builtin_functions(); -extern void initialize_builtin_dxf_dim(); -extern void destroy_builtin_functions(); - -class AbstractModule -{ -public: - virtual ~AbstractModule(); - virtual AbstractNode *evaluate(const Context *ctx, const ModuleInstantiation *inst) const; - virtual QString dump(QString indent, QString name) const; -}; - -class ModuleInstantiation -{ -public: - QString label; - QString modname; - QVector argnames; - QVector argexpr; - QVector argvalues; - QVector children; - - bool tag_root; - bool tag_highlight; - bool tag_background; - const Context *ctx; - - ModuleInstantiation() : tag_root(false), tag_highlight(false), tag_background(false), ctx(NULL) { } - ~ModuleInstantiation(); - - QString dump(QString indent) const; - AbstractNode *evaluate(const Context *ctx) const; -}; - -class Module : public AbstractModule -{ -public: - QVector argnames; - QVector argexpr; - - QVector assignments_var; - QVector assignments_expr; - - QHash functions; - QHash modules; - - QVector children; - - Module() { } - virtual ~Module(); - - virtual AbstractNode *evaluate(const Context *ctx, const ModuleInstantiation *inst) const; - virtual QString dump(QString indent, QString name) const; -}; - -extern QHash builtin_modules; -extern void initialize_builtin_modules(); -extern void destroy_builtin_modules(); - -extern void register_builtin_csgops(); -extern void register_builtin_transform(); -extern void register_builtin_primitives(); -extern void register_builtin_surface(); -extern void register_builtin_control(); -extern void register_builtin_render(); -extern void register_builtin_import(); -extern void register_builtin_dxf_linear_extrude(); -extern void register_builtin_dxf_rotate_extrude(); - -class Context -{ -public: - const Context *parent; - QHash variables; - QHash config_variables; - const QHash *functions_p; - const QHash *modules_p; - const ModuleInstantiation *inst_p; - - static QVector ctx_stack; - - Context(const Context *parent = NULL); - ~Context(); - - void args(const QVector &argnames, const QVector &argexpr, const QVector &call_argnames, const QVector &call_argvalues); - - void set_variable(QString name, Value value); - Value lookup_variable(QString name, bool silent = false) const; - Value evaluate_function(QString name, const QVector &argnames, const QVector &argvalues) const; - AbstractNode *evaluate_module(const ModuleInstantiation *inst) const; -}; - -class DxfData -{ -public: - struct Point { - double x, y; - Point() : x(0), y(0) { } - Point(double x, double y) : x(x), y(y) { } - }; - struct Path { - QList points; - bool is_closed, is_inner; - Path() : is_closed(false), is_inner(false) { } - }; - struct Dim { - unsigned int type; - double coords[7][2]; - double angle; - double length; - QString name; - Dim() { - for (int i = 0; i < 7; i++) - for (int j = 0; j < 2; j++) - coords[i][j] = 0; - type = 0; - angle = 0; - length = 0; - } - }; - - QList points; - QList paths; - QList dims; - - DxfData(); - DxfData(double fn, double fs, double fa, QString filename, QString layername = QString(), double xorigin = 0.0, double yorigin = 0.0, double scale = 1.0); - DxfData(const struct CGAL_Nef_polyhedron &N); - - Point *addPoint(double x, double y); - -private: - void fixup_path_direction(); -}; - -// The CGAL template magic slows down the compilation process by a factor of 5. -// So we only include the declaration of AbstractNode where it is needed... -#ifdef INCLUDE_ABSTRACT_NODE_DETAILS - -#ifdef ENABLE_CGAL - -#include -#include -#include -#include -#include -#include -#include - -typedef CGAL::Extended_cartesian CGAL_Kernel2; -typedef CGAL::Nef_polyhedron_2 CGAL_Nef_polyhedron2; -typedef CGAL_Kernel2::Aff_transformation_2 CGAL_Aff_transformation2; - -typedef CGAL::Cartesian CGAL_Kernel3; -typedef CGAL::Polyhedron_3 CGAL_Polyhedron; -typedef CGAL_Polyhedron::HalfedgeDS CGAL_HDS; -typedef CGAL::Polyhedron_incremental_builder_3 CGAL_Polybuilder; -typedef CGAL::Nef_polyhedron_3 CGAL_Nef_polyhedron3; -typedef CGAL_Nef_polyhedron3::Aff_transformation_3 CGAL_Aff_transformation; -typedef CGAL_Nef_polyhedron3::Vector_3 CGAL_Vector; -typedef CGAL_Nef_polyhedron3::Plane_3 CGAL_Plane; -typedef CGAL_Nef_polyhedron3::Point_3 CGAL_Point; - -struct CGAL_Nef_polyhedron -{ - int dim; - CGAL_Nef_polyhedron2 p2; - CGAL_Nef_polyhedron3 p3; - - CGAL_Nef_polyhedron() { - dim = 0; - } - - CGAL_Nef_polyhedron(const CGAL_Nef_polyhedron2 &p) { - dim = 2; - p2 = p; - } - - CGAL_Nef_polyhedron(const CGAL_Nef_polyhedron3 &p) { - dim = 3; - p3 = p; - } - - int weight() { - if (dim == 2) - return p2.explorer().number_of_vertices(); - if (dim == 3) - return p3.number_of_vertices(); - return 0; - } -}; - -#endif /* ENABLE_CGAL */ - -#ifdef ENABLE_OPENCSG -# include -#endif - -class PolySet -{ -public: - struct Point { - double x, y, z; - Point() : x(0), y(0), z(0) { } - Point(double x, double y, double z) : x(x), y(y), z(z) { } - }; - typedef QList Polygon; - QVector polygons; - QVector borders; - Grid3d grid; - - bool is2d; - int convexity; - - PolySet(); - ~PolySet(); - - void append_poly(); - void append_vertex(double x, double y, double z); - void insert_vertex(double x, double y, double z); - - void append_vertex(double x, double y) { - append_vertex(x, y, 0.0); - } - void insert_vertex(double x, double y) { - insert_vertex(x, y, 0.0); - } - - enum colormode_e { - COLORMODE_NONE, - COLORMODE_MATERIAL, - COLORMODE_CUTOUT, - COLORMODE_HIGHLIGHT, - COLORMODE_BACKGROUND - }; - - enum csgmode_e { - CSGMODE_NONE, - CSGMODE_NORMAL = 1, - CSGMODE_DIFFERENCE = 2, - CSGMODE_BACKGROUND = 11, - CSGMODE_BACKGROUND_DIFFERENCE = 12, - CSGMODE_HIGHLIGHT = 21, - CSGMODE_HIGHLIGHT_DIFFERENCE = 22 - }; - - struct ps_cache_entry { - PolySet *ps; - QString msg; - ps_cache_entry(PolySet *ps); - ~ps_cache_entry(); - }; - - static QCache ps_cache; - - void render_surface(colormode_e colormode, csgmode_e csgmode, double *m, GLint *shaderinfo = NULL) const; - void render_edges(colormode_e colormode, csgmode_e csgmode) const; - -#ifdef ENABLE_CGAL - CGAL_Nef_polyhedron render_cgal_nef_polyhedron() const; -#endif - - int refcount; - PolySet *link(); - void unlink(); -}; - -class CSGTerm -{ -public: - enum type_e { - TYPE_PRIMITIVE, - TYPE_UNION, - TYPE_INTERSECTION, - TYPE_DIFFERENCE - }; - - type_e type; - PolySet *polyset; - QString label; - CSGTerm *left; - CSGTerm *right; - double m[20]; - int refcounter; - - CSGTerm(PolySet *polyset, double m[20], QString label); - CSGTerm(type_e type, CSGTerm *left, CSGTerm *right); - - CSGTerm *normalize(); - CSGTerm *normalize_tail(); - - CSGTerm *link(); - void unlink(); - QString dump(); -}; - -class CSGChain -{ -public: - QVector polysets; - QVector matrices; - QVector types; - QVector labels; - - CSGChain(); - - void add(PolySet *polyset, double *m, CSGTerm::type_e type, QString label); - void import(CSGTerm *term, CSGTerm::type_e type = CSGTerm::TYPE_UNION); - QString dump(); -}; - -class AbstractNode -{ -public: - QVector children; - const ModuleInstantiation *modinst; - - int progress_mark; - void progress_prepare(); - void progress_report() const; - - int idx; - static int idx_counter; - QString dump_cache; - - AbstractNode(const ModuleInstantiation *mi); - virtual ~AbstractNode(); - virtual QString mk_cache_id() const; -#ifdef ENABLE_CGAL - struct cgal_nef_cache_entry { - CGAL_Nef_polyhedron N; - QString msg; - cgal_nef_cache_entry(CGAL_Nef_polyhedron N); - }; - static QCache cgal_nef_cache; - virtual CGAL_Nef_polyhedron render_cgal_nef_polyhedron() const; -#endif - virtual CSGTerm *render_csg_term(double m[20], QVector *highlights, QVector *background) const; - virtual QString dump(QString indent) const; -}; - -class AbstractIntersectionNode : public AbstractNode -{ -public: - AbstractIntersectionNode(const ModuleInstantiation *mi) : AbstractNode(mi) { }; -#ifdef ENABLE_CGAL - virtual CGAL_Nef_polyhedron render_cgal_nef_polyhedron() const; -#endif - virtual CSGTerm *render_csg_term(double m[20], QVector *highlights, QVector *background) const; - virtual QString dump(QString indent) const; -}; - -class AbstractPolyNode : public AbstractNode -{ -public: - enum render_mode_e { - RENDER_CGAL, - RENDER_OPENCSG - }; - AbstractPolyNode(const ModuleInstantiation *mi) : AbstractNode(mi) { }; - virtual PolySet *render_polyset(render_mode_e mode) const; -#ifdef ENABLE_CGAL - virtual CGAL_Nef_polyhedron render_cgal_nef_polyhedron() const; -#endif - virtual CSGTerm *render_csg_term(double m[20], QVector *highlights, QVector *background) const; - static CSGTerm *render_csg_term_from_ps(double m[20], QVector *highlights, QVector *background, PolySet *ps, const ModuleInstantiation *modinst, int idx); -}; - -extern QHash dxf_dim_cache; -extern QHash dxf_cross_cache; - -extern int progress_report_count; -extern void (*progress_report_f)(const class AbstractNode*, void*, int); -extern void *progress_report_vp; - -void progress_report_prep(AbstractNode *root, void (*f)(const class AbstractNode *node, void *vp, int mark), void *vp); -void progress_report_fin(); - -void dxf_tesselate(PolySet *ps, DxfData *dxf, double rot, bool up, bool do_triangle_splitting, double h); -void dxf_border_to_ps(PolySet *ps, DxfData *dxf); - -#endif /* INCLUDE_ABSTRACT_NODE_DETAILS */ - -class Highlighter : public QSyntaxHighlighter -{ -public: - Highlighter(QTextDocument *parent); - void highlightBlock(const QString &text); -}; - -extern AbstractModule *parse(const char *text, int debug); +extern class AbstractModule *parse(const char *text, int debug); extern int get_fragments_from_r(double r, double fn, double fs, double fa); +#include extern QString commandline_commands; extern int parser_error_pos; -#ifdef ENABLE_CGAL -void export_stl(CGAL_Nef_polyhedron *root_N, QString filename, QProgressDialog *pd); -void export_off(CGAL_Nef_polyhedron *root_N, QString filename, QProgressDialog *pd); -void export_dxf(CGAL_Nef_polyhedron *root_N, QString filename, QProgressDialog *pd); -#endif extern void handle_dep(QString filename); #endif diff --git a/src/parser.y b/src/parser.y new file mode 100644 index 0000000..c4cd3d4 --- /dev/null +++ b/src/parser.y @@ -0,0 +1,524 @@ +/* + * OpenSCAD (www.openscad.at) + * Copyright (C) 2009 Clifford Wolf + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +%{ + +#include "openscad.h" +#include "printutils.h" + +int parser_error_pos = -1; + +int parserlex(void); +void yyerror(char const *s); + +int lexerget_lineno(void); +int lexerlex_destroy(void); +int lexerlex(void); + +QVector module_stack; +Module *module; + +class ArgContainer { +public: + QString argname; + Expression *argexpr; +}; +class ArgsContainer { +public: + QVector argnames; + QVector argexpr; +}; + +%} + +%union { + char *text; + double number; + class Value *value; + class Expression *expr; + class ModuleInstantiation *inst; + class ArgContainer *arg; + class ArgsContainer *args; +} + +%token TOK_MODULE +%token TOK_FUNCTION + +%token TOK_ID +%token TOK_STRING +%token TOK_NUMBER + +%token TOK_TRUE +%token TOK_FALSE +%token TOK_UNDEF + +%token LE GE EQ NE AND OR + +%left OR +%left AND + +%left '<' LE GE '>' +%left EQ NE + +%left '!' '+' '-' +%left '*' '/' '%' +%left '[' ']' +%left '.' + +%right '?' ':' + +%type expr +%type vector_expr + +%type module_instantiation +%type module_instantiation_list +%type single_module_instantiation + +%type arguments_call +%type arguments_decl + +%type argument_call +%type argument_decl + +%debug + +%% + +input: + /* empty */ | + statement input ; + +statement: + ';' | + '{' input '}' | + module_instantiation { + if ($1) { + module->children.append($1); + } else { + delete $1; + } + } | + TOK_ID '=' expr ';' { + bool add_new_assignment = true; + for (int i = 0; i < module->assignments_var.size(); i++) { + if (module->assignments_var[i] != QString($1)) + continue; + delete module->assignments_expr[i]; + module->assignments_expr[i] = $3; + add_new_assignment = false; + } + if (add_new_assignment) { + module->assignments_var.append($1); + module->assignments_expr.append($3); + free($1); + } + } | + TOK_MODULE TOK_ID '(' arguments_decl optional_commas ')' { + Module *p = module; + module_stack.append(module); + module = new Module(); + p->modules[$2] = module; + module->argnames = $4->argnames; + module->argexpr = $4->argexpr; + free($2); + delete $4; + } statement { + module = module_stack.last(); + module_stack.pop_back(); + } | + TOK_FUNCTION TOK_ID '(' arguments_decl optional_commas ')' '=' expr { + Function *func = new Function(); + func->argnames = $4->argnames; + func->argexpr = $4->argexpr; + func->expr = $8; + module->functions[$2] = func; + free($2); + delete $4; + } ';' ; + +module_instantiation: + single_module_instantiation ';' { + $$ = $1; + } | + single_module_instantiation '{' module_instantiation_list '}' { + $$ = $1; + if ($$) { + $$->children = $3->children; + } else { + for (int i = 0; i < $3->children.count(); i++) + delete $3->children[i]; + } + $3->children.clear(); + delete $3; + } | + single_module_instantiation module_instantiation { + $$ = $1; + if ($$) { + if ($2) + $$->children.append($2); + } else { + delete $2; + } + } ; + +module_instantiation_list: + /* empty */ { + $$ = new ModuleInstantiation(); + } | + module_instantiation_list module_instantiation { + $$ = $1; + if ($$) { + if ($2) + $$->children.append($2); + } else { + delete $2; + } + } ; + +single_module_instantiation: + TOK_ID '(' arguments_call ')' { + $$ = new ModuleInstantiation(); + $$->modname = QString($1); + $$->argnames = $3->argnames; + $$->argexpr = $3->argexpr; + free($1); + delete $3; + } | + TOK_ID ':' single_module_instantiation { + $$ = $3; + if ($$) + $$->label = QString($1); + free($1); + } | + '!' single_module_instantiation { + $$ = $2; + if ($$) + $$->tag_root = true; + } | + '#' single_module_instantiation { + $$ = $2; + if ($$) + $$->tag_highlight = true; + } | + '%' single_module_instantiation { + $$ = $2; + if ($$) + $$->tag_background = true; + } | + '*' single_module_instantiation { + delete $2; + $$ = NULL; + }; + +expr: + TOK_TRUE { + $$ = new Expression(); + $$->type = "C"; + $$->const_value = new Value(true); + } | + TOK_FALSE { + $$ = new Expression(); + $$->type = "C"; + $$->const_value = new Value(false); + } | + TOK_UNDEF { + $$ = new Expression(); + $$->type = "C"; + $$->const_value = new Value(); + } | + TOK_ID { + $$ = new Expression(); + $$->type = "L"; + $$->var_name = QString($1); + free($1); + } | + expr '.' TOK_ID { + $$ = new Expression(); + $$->type = "N"; + $$->children.append($1); + $$->var_name = QString($3); + free($3); + } | + TOK_STRING { + $$ = new Expression(); + $$->type = "C"; + $$->const_value = new Value(QString($1)); + free($1); + } | + TOK_NUMBER { + $$ = new Expression(); + $$->type = "C"; + $$->const_value = new Value($1); + } | + '[' expr ':' expr ']' { + Expression *e_one = new Expression(); + e_one->type = "C"; + e_one->const_value = new Value(1.0); + $$ = new Expression(); + $$->type = "R"; + $$->children.append($2); + $$->children.append(e_one); + $$->children.append($4); + } | + '[' expr ':' expr ':' expr ']' { + $$ = new Expression(); + $$->type = "R"; + $$->children.append($2); + $$->children.append($4); + $$->children.append($6); + } | + '[' optional_commas ']' { + $$ = new Expression(); + $$->type = "C"; + $$->const_value = new Value(); + $$->const_value->type = Value::VECTOR; + } | + '[' vector_expr optional_commas ']' { + $$ = $2; + } | + expr '*' expr { + $$ = new Expression(); + $$->type = "*"; + $$->children.append($1); + $$->children.append($3); + } | + expr '/' expr { + $$ = new Expression(); + $$->type = "/"; + $$->children.append($1); + $$->children.append($3); + } | + expr '%' expr { + $$ = new Expression(); + $$->type = "%"; + $$->children.append($1); + $$->children.append($3); + } | + expr '+' expr { + $$ = new Expression(); + $$->type = "+"; + $$->children.append($1); + $$->children.append($3); + } | + expr '-' expr { + $$ = new Expression(); + $$->type = "-"; + $$->children.append($1); + $$->children.append($3); + } | + expr '<' expr { + $$ = new Expression(); + $$->type = "<"; + $$->children.append($1); + $$->children.append($3); + } | + expr LE expr { + $$ = new Expression(); + $$->type = "<="; + $$->children.append($1); + $$->children.append($3); + } | + expr EQ expr { + $$ = new Expression(); + $$->type = "=="; + $$->children.append($1); + $$->children.append($3); + } | + expr NE expr { + $$ = new Expression(); + $$->type = "!="; + $$->children.append($1); + $$->children.append($3); + } | + expr GE expr { + $$ = new Expression(); + $$->type = ">="; + $$->children.append($1); + $$->children.append($3); + } | + expr '>' expr { + $$ = new Expression(); + $$->type = ">"; + $$->children.append($1); + $$->children.append($3); + } | + expr AND expr { + $$ = new Expression(); + $$->type = "&&"; + $$->children.append($1); + $$->children.append($3); + } | + expr OR expr { + $$ = new Expression(); + $$->type = "||"; + $$->children.append($1); + $$->children.append($3); + } | + '+' expr { + $$ = $2; + } | + '-' expr { + $$ = new Expression(); + $$->type = "I"; + $$->children.append($2); + } | + '!' expr { + $$ = new Expression(); + $$->type = "!"; + $$->children.append($2); + } | + '(' expr ')' { + $$ = $2; + } | + expr '?' expr ':' expr { + $$ = new Expression(); + $$->type = "?:"; + $$->children.append($1); + $$->children.append($3); + $$->children.append($5); + } | + expr '[' expr ']' { + $$ = new Expression(); + $$->type = "[]"; + $$->children.append($1); + $$->children.append($3); + } | + TOK_ID '(' arguments_call ')' { + $$ = new Expression(); + $$->type = "F"; + $$->call_funcname = QString($1); + $$->call_argnames = $3->argnames; + $$->children = $3->argexpr; + free($1); + delete $3; + } ; + +optional_commas: + ',' optional_commas | ; + +vector_expr: + expr { + $$ = new Expression(); + $$->type = 'V'; + $$->children.append($1); + } | + vector_expr ',' optional_commas expr { + $$ = $1; + $$->children.append($4); + } ; + +arguments_decl: + /* empty */ { + $$ = new ArgsContainer(); + } | + argument_decl { + $$ = new ArgsContainer(); + $$->argnames.append($1->argname); + $$->argexpr.append($1->argexpr); + delete $1; + } | + arguments_decl ',' optional_commas argument_decl { + $$ = $1; + $$->argnames.append($4->argname); + $$->argexpr.append($4->argexpr); + delete $4; + } ; + +argument_decl: + TOK_ID { + $$ = new ArgContainer(); + $$->argname = QString($1); + $$->argexpr = NULL; + free($1); + } | + TOK_ID '=' expr { + $$ = new ArgContainer(); + $$->argname = QString($1); + $$->argexpr = $3; + free($1); + } ; + +arguments_call: + /* empty */ { + $$ = new ArgsContainer(); + } | + argument_call { + $$ = new ArgsContainer(); + $$->argnames.append($1->argname); + $$->argexpr.append($1->argexpr); + delete $1; + } | + arguments_call ',' optional_commas argument_call { + $$ = $1; + $$->argnames.append($4->argname); + $$->argexpr.append($4->argexpr); + delete $4; + } ; + +argument_call: + expr { + $$ = new ArgContainer(); + $$->argexpr = $1; + } | + TOK_ID '=' expr { + $$ = new ArgContainer(); + $$->argname = QString($1); + $$->argexpr = $3; + free($1); + } ; + +%% + +int parserlex(void) +{ + return lexerlex(); +} + +void yyerror (char const *s) +{ + // FIXME: We leak memory on parser errors... + PRINTF("Parser error in line %d: %s\n", lexerget_lineno(), s); + module = NULL; +} + +extern FILE *lexerin; +extern const char *parser_input_buffer; +const char *parser_input_buffer; + +AbstractModule *parse(const char *text, int debug) +{ + lexerin = NULL; + parser_error_pos = -1; + parser_input_buffer = text; + + module_stack.clear(); + module = new Module(); + + parserdebug = debug; + parserparse(); + + lexerlex_destroy(); + + if (module) + parser_error_pos = -1; + + return module; +} + diff --git a/src/polyset.cc b/src/polyset.cc index 5f22fde..7110f95 100644 --- a/src/polyset.cc +++ b/src/polyset.cc @@ -18,9 +18,10 @@ * */ -#define INCLUDE_ABSTRACT_NODE_DETAILS - -#include "openscad.h" +#include "polyset.h" +#include "node.h" +#include "module.h" +#include "csgterm.h" #include "printutils.h" #include "Preferences.h" diff --git a/src/polyset.h b/src/polyset.h new file mode 100644 index 0000000..2196d1b --- /dev/null +++ b/src/polyset.h @@ -0,0 +1,89 @@ +#ifndef POLYSET_H_ +#define POLYSET_H_ + +#ifdef ENABLE_OPENCSG +// this must be included before the GL headers +# include +#endif +#include + +#include "grid.h" +#ifdef ENABLE_OPENCSG +# include +#endif +#ifdef ENABLE_CGAL +# include "cgal.h" +#endif + +#include + +class PolySet +{ +public: + struct Point { + double x, y, z; + Point() : x(0), y(0), z(0) { } + Point(double x, double y, double z) : x(x), y(y), z(z) { } + }; + typedef QList Polygon; + QVector polygons; + QVector borders; + Grid3d grid; + + bool is2d; + int convexity; + + PolySet(); + ~PolySet(); + + void append_poly(); + void append_vertex(double x, double y, double z); + void insert_vertex(double x, double y, double z); + + void append_vertex(double x, double y) { + append_vertex(x, y, 0.0); + } + void insert_vertex(double x, double y) { + insert_vertex(x, y, 0.0); + } + + enum colormode_e { + COLORMODE_NONE, + COLORMODE_MATERIAL, + COLORMODE_CUTOUT, + COLORMODE_HIGHLIGHT, + COLORMODE_BACKGROUND + }; + + enum csgmode_e { + CSGMODE_NONE, + CSGMODE_NORMAL = 1, + CSGMODE_DIFFERENCE = 2, + CSGMODE_BACKGROUND = 11, + CSGMODE_BACKGROUND_DIFFERENCE = 12, + CSGMODE_HIGHLIGHT = 21, + CSGMODE_HIGHLIGHT_DIFFERENCE = 22 + }; + + struct ps_cache_entry { + PolySet *ps; + QString msg; + ps_cache_entry(PolySet *ps); + ~ps_cache_entry(); + }; + + static QCache ps_cache; + + void render_surface(colormode_e colormode, csgmode_e csgmode, double *m, GLint *shaderinfo = NULL) const; + void render_edges(colormode_e colormode, csgmode_e csgmode) const; + +#ifdef ENABLE_CGAL + CGAL_Nef_polyhedron render_cgal_nef_polyhedron() const; +#endif + + int refcount; + PolySet *link(); + void unlink(); +}; + +#endif diff --git a/src/primitives.cc b/src/primitives.cc index 2f50578..4aeec53 100644 --- a/src/primitives.cc +++ b/src/primitives.cc @@ -18,9 +18,13 @@ * */ -#define INCLUDE_ABSTRACT_NODE_DETAILS - -#include "openscad.h" +#include "module.h" +#include "node.h" +#include "polyset.h" +#include "context.h" +#include "dxfdata.h" +#include "dxftess.h" +#include "builtin.h" enum primitive_type_e { CUBE, diff --git a/src/render.cc b/src/render.cc index 7c82d92..5d73575 100644 --- a/src/render.cc +++ b/src/render.cc @@ -18,10 +18,18 @@ * */ -#define INCLUDE_ABSTRACT_NODE_DETAILS - -#include "openscad.h" +#include "module.h" +#include "node.h" +#include "polyset.h" +#include "context.h" +#include "dxfdata.h" +#include "dxftess.h" +#include "csgterm.h" +#include "builtin.h" #include "printutils.h" +#ifdef ENABLE_CGAL +# include "cgal.h" +#endif #include #include diff --git a/src/surface.cc b/src/surface.cc index 4dc3d98..2a3b4b5 100644 --- a/src/surface.cc +++ b/src/surface.cc @@ -18,10 +18,14 @@ * */ -#define INCLUDE_ABSTRACT_NODE_DETAILS - -#include "openscad.h" +#include "module.h" +#include "node.h" +#include "polyset.h" +#include "context.h" +#include "builtin.h" +#include "dxftess.h" #include "printutils.h" +#include "openscad.h" // handle_dep() #include diff --git a/src/transform.cc b/src/transform.cc index ecbfcc2..3ffc2a6 100644 --- a/src/transform.cc +++ b/src/transform.cc @@ -18,9 +18,14 @@ * */ -#define INCLUDE_ABSTRACT_NODE_DETAILS - -#include "openscad.h" +#include "module.h" +#include "node.h" +#include "context.h" +#include "dxfdata.h" +#include "csgterm.h" +#include "polyset.h" +#include "dxftess.h" +#include "builtin.h" #include "printutils.h" enum transform_type_e { diff --git a/src/value.cc b/src/value.cc index a02a27f..3aae9e5 100644 --- a/src/value.cc +++ b/src/value.cc @@ -18,7 +18,8 @@ * */ -#include "openscad.h" +#include "value.h" +#include Value::Value() { diff --git a/src/value.h b/src/value.h new file mode 100644 index 0000000..3491cbb --- /dev/null +++ b/src/value.h @@ -0,0 +1,68 @@ +#ifndef VALUE_H_ +#define VALUE_H_ + +#include +#include + +class Value +{ +public: + enum type_e { + UNDEFINED, + BOOL, + NUMBER, + RANGE, + VECTOR, + STRING + }; + + enum type_e type; + + bool b; + double num; + QVector vec; + double range_begin; + double range_step; + double range_end; + QString text; + + Value(); + ~Value(); + + Value(bool v); + Value(double v); + Value(const QString &t); + + Value(const Value &v); + Value& operator = (const Value &v); + + Value operator ! () const; + Value operator && (const Value &v) const; + Value operator || (const Value &v) const; + + Value operator + (const Value &v) const; + Value operator - (const Value &v) const; + Value operator * (const Value &v) const; + Value operator / (const Value &v) const; + Value operator % (const Value &v) const; + + Value operator < (const Value &v) const; + Value operator <= (const Value &v) const; + Value operator == (const Value &v) const; + Value operator != (const Value &v) const; + Value operator >= (const Value &v) const; + Value operator > (const Value &v) const; + + Value inv() const; + + bool getnum(double &v) const; + bool getv2(double &x, double &y) const; + bool getv3(double &x, double &y, double &z) const; + + QString dump() const; + +private: + void reset_undef(); +}; + +#endif -- cgit v0.10.1