diff options
author | kintel <kintel@b57f626f-c46c-0410-a088-ec61d464b74c> | 2010-01-30 04:26:05 (GMT) |
---|---|---|
committer | kintel <kintel@b57f626f-c46c-0410-a088-ec61d464b74c> | 2010-01-30 04:26:05 (GMT) |
commit | 191dc4857c852f1867e80cd9d03a6d1c0921dcb1 (patch) | |
tree | 4a6421d50eb6cf70924fc0ba06afccf10df00650 /src | |
parent | 6940d171812565209efe679a5d923417c3f47d4a (diff) |
header file reorg
git-svn-id: http://svn.clifford.at/openscad/trunk@365 b57f626f-c46c-0410-a088-ec61d464b74c
Diffstat (limited to 'src')
52 files changed, 3530 insertions, 927 deletions
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<GLdouble*> 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 <QMainWindow> #include "ui_MainWindow.h" #include "openscad.h" +#include "context.h" +#include "module.h" +#include "polyset.h" +#include <QPointer> 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 @@ +<?xml version="1.0" encoding="UTF-8"?> +<ui version="4.0"> + <class>MainWindow</class> + <widget class="QMainWindow" name="MainWindow"> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>681</width> + <height>647</height> + </rect> + </property> + <property name="windowTitle"> + <string>MainWindow</string> + </property> + <widget class="QWidget" name="centralwidget"> + <layout class="QVBoxLayout" name="verticalLayout_2"> + <property name="margin"> + <number>0</number> + </property> + <item> + <widget class="QSplitter" name="splitter1"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <widget class="QTextEdit" name="editor"> + <property name="font"> + <font> + <family>Monaco</family> + <pointsize>8</pointsize> + </font> + </property> + <property name="tabStopWidth"> + <number>30</number> + </property> + <property name="textInteractionFlags"> + <set>Qt::LinksAccessibleByMouse|Qt::TextEditable|Qt::TextEditorInteraction|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse</set> + </property> + </widget> + <widget class="QWidget" name="layoutWidget"> + <layout class="QVBoxLayout" name="verticalLayout"> + <item> + <widget class="QSplitter" name="splitter2"> + <property name="orientation"> + <enum>Qt::Vertical</enum> + </property> + <widget class="GLView" name="screen" native="true"/> + <widget class="QTextEdit" name="console"/> + </widget> + </item> + <item> + <widget class="QFrame" name="animate_panel"> + <property name="enabled"> + <bool>true</bool> + </property> + <property name="frameShape"> + <enum>QFrame::NoFrame</enum> + </property> + <property name="frameShadow"> + <enum>QFrame::Raised</enum> + </property> + <property name="lineWidth"> + <number>0</number> + </property> + <layout class="QHBoxLayout" name="horizontalLayout"> + <property name="margin"> + <number>0</number> + </property> + <item> + <widget class="QLabel" name="label"> + <property name="text"> + <string>Time:</string> + </property> + </widget> + </item> + <item> + <widget class="QLineEdit" name="e_tval"/> + </item> + <item> + <widget class="QLabel" name="label_2"> + <property name="text"> + <string>FPS:</string> + </property> + </widget> + </item> + <item> + <widget class="QLineEdit" name="e_fps"/> + </item> + <item> + <widget class="QLabel" name="label_3"> + <property name="text"> + <string>Steps:</string> + </property> + </widget> + </item> + <item> + <widget class="QLineEdit" name="e_fsteps"/> + </item> + <item> + <widget class="QCheckBox" name="e_dump"> + <property name="text"> + <string>Dump Pictures</string> + </property> + </widget> + </item> + </layout> + </widget> + </item> + </layout> + </widget> + </widget> + </item> + </layout> + </widget> + <widget class="QMenuBar" name="menubar"> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>681</width> + <height>22</height> + </rect> + </property> + <widget class="QMenu" name="menu_File"> + <property name="title"> + <string>&File</string> + </property> + <widget class="QMenu" name="menuOpenRecent"> + <property name="title"> + <string>Open Recent</string> + </property> + </widget> + <widget class="QMenu" name="menuExamples"> + <property name="title"> + <string>Examples</string> + </property> + </widget> + <addaction name="fileActionNew"/> + <addaction name="fileActionOpen"/> + <addaction name="menuOpenRecent"/> + <addaction name="menuExamples"/> + <addaction name="separator"/> + <addaction name="fileActionClose"/> + <addaction name="fileActionSave"/> + <addaction name="fileActionSaveAs"/> + <addaction name="fileActionReload"/> + <addaction name="fileActionQuit"/> + </widget> + <widget class="QMenu" name="menu_Edit"> + <property name="title"> + <string>&Edit</string> + </property> + <addaction name="editActionUndo"/> + <addaction name="editActionRedo"/> + <addaction name="separator"/> + <addaction name="editActionCut"/> + <addaction name="editActionCopy"/> + <addaction name="editActionPaste"/> + <addaction name="separator"/> + <addaction name="editActionIndent"/> + <addaction name="editActionUnindent"/> + <addaction name="separator"/> + <addaction name="editActionComment"/> + <addaction name="editActionUncomment"/> + <addaction name="separator"/> + <addaction name="editActionPasteVPT"/> + <addaction name="editActionPasteVPR"/> + <addaction name="separator"/> + <addaction name="editActionZoomIn"/> + <addaction name="editActionZoomOut"/> + <addaction name="editActionPreferences"/> + </widget> + <widget class="QMenu" name="menu_Design"> + <property name="title"> + <string>&Design</string> + </property> + <addaction name="designActionReloadAndCompile"/> + <addaction name="designActionCompile"/> + <addaction name="designActionCompileAndRender"/> + <addaction name="designActionDisplayAST"/> + <addaction name="designActionDisplayCSGTree"/> + <addaction name="designActionDisplayCSGProducts"/> + <addaction name="designActionExportSTL"/> + <addaction name="designActionExportOFF"/> + <addaction name="designActionExportDXF"/> + <addaction name="designActionFlushCaches"/> + </widget> + <widget class="QMenu" name="menu_View"> + <property name="title"> + <string>&View</string> + </property> + <addaction name="viewActionOpenCSG"/> + <addaction name="viewActionCGALSurfaces"/> + <addaction name="viewActionCGALGrid"/> + <addaction name="viewActionThrownTogether"/> + <addaction name="separator"/> + <addaction name="viewActionShowEdges"/> + <addaction name="viewActionShowAxes"/> + <addaction name="viewActionShowCrosshairs"/> + <addaction name="viewActionAnimate"/> + <addaction name="separator"/> + <addaction name="viewActionTop"/> + <addaction name="viewActionBottom"/> + <addaction name="viewActionLeft"/> + <addaction name="viewActionRight"/> + <addaction name="viewActionFront"/> + <addaction name="viewActionBack"/> + <addaction name="viewActionDiagonal"/> + <addaction name="viewActionCenter"/> + <addaction name="separator"/> + <addaction name="viewActionPerspective"/> + <addaction name="viewActionOrthogonal"/> + <addaction name="separator"/> + <addaction name="editActionHide"/> + <addaction name="viewActionHide"/> + </widget> + <widget class="QMenu" name="menuHelp"> + <property name="title"> + <string>Help</string> + </property> + <addaction name="helpActionAbout"/> + <addaction name="helpActionManual"/> + </widget> + <addaction name="menu_File"/> + <addaction name="menu_Edit"/> + <addaction name="menu_Design"/> + <addaction name="menu_View"/> + <addaction name="menuHelp"/> + </widget> + <widget class="QStatusBar" name="statusbar"/> + <action name="fileActionNew"> + <property name="text"> + <string>&New</string> + </property> + <property name="shortcut"> + <string>Ctrl+N</string> + </property> + </action> + <action name="fileActionOpen"> + <property name="text"> + <string>&Open...</string> + </property> + <property name="shortcut"> + <string>Ctrl+O</string> + </property> + </action> + <action name="fileActionSave"> + <property name="text"> + <string>&Save</string> + </property> + <property name="shortcut"> + <string>Ctrl+S</string> + </property> + </action> + <action name="fileActionSaveAs"> + <property name="text"> + <string>Save &As...</string> + </property> + <property name="shortcut"> + <string>Ctrl+Shift+S</string> + </property> + </action> + <action name="fileActionReload"> + <property name="text"> + <string>&Reload</string> + </property> + <property name="shortcut"> + <string>Ctrl+R</string> + </property> + </action> + <action name="fileActionQuit"> + <property name="text"> + <string>&Quit</string> + </property> + </action> + <action name="editActionUndo"> + <property name="text"> + <string>&Undo</string> + </property> + <property name="shortcut"> + <string>Ctrl+Z</string> + </property> + </action> + <action name="editActionRedo"> + <property name="text"> + <string>&Redo</string> + </property> + <property name="shortcut"> + <string>Ctrl+Shift+Z</string> + </property> + </action> + <action name="editActionCut"> + <property name="text"> + <string>Cu&t</string> + </property> + <property name="shortcut"> + <string>Ctrl+X</string> + </property> + </action> + <action name="editActionCopy"> + <property name="text"> + <string>&Copy</string> + </property> + <property name="shortcut"> + <string>Ctrl+C</string> + </property> + </action> + <action name="editActionPaste"> + <property name="text"> + <string>&Paste</string> + </property> + <property name="shortcut"> + <string>Ctrl+V</string> + </property> + </action> + <action name="editActionIndent"> + <property name="text"> + <string>&Indent</string> + </property> + <property name="shortcut"> + <string>Ctrl+I</string> + </property> + </action> + <action name="editActionUnindent"> + <property name="text"> + <string>U&nindent</string> + </property> + <property name="shortcut"> + <string>Ctrl+Shift+I</string> + </property> + </action> + <action name="editActionComment"> + <property name="text"> + <string>C&omment</string> + </property> + <property name="shortcut"> + <string>Ctrl+D</string> + </property> + </action> + <action name="editActionUncomment"> + <property name="text"> + <string>Unco&mment</string> + </property> + <property name="shortcut"> + <string>Ctrl+Shift+D</string> + </property> + </action> + <action name="editActionPasteVPT"> + <property name="text"> + <string>Paste viewport translation</string> + </property> + <property name="shortcut"> + <string>Ctrl+T</string> + </property> + </action> + <action name="editActionPasteVPR"> + <property name="text"> + <string>Paste viewport rotation</string> + </property> + </action> + <action name="editActionZoomIn"> + <property name="text"> + <string>Zoom In</string> + </property> + <property name="shortcut"> + <string>Ctrl++</string> + </property> + </action> + <action name="editActionZoomOut"> + <property name="text"> + <string>Zoom Out</string> + </property> + <property name="shortcut"> + <string>Ctrl+-</string> + </property> + </action> + <action name="editActionHide"> + <property name="checkable"> + <bool>true</bool> + </property> + <property name="text"> + <string>Hide editor</string> + </property> + </action> + <action name="designActionReloadAndCompile"> + <property name="text"> + <string>&Reload and Compile</string> + </property> + <property name="shortcut"> + <string>F4</string> + </property> + </action> + <action name="designActionCompile"> + <property name="text"> + <string>&Compile</string> + </property> + <property name="shortcut"> + <string>F5</string> + </property> + </action> + <action name="designActionCompileAndRender"> + <property name="text"> + <string>Compile and &Render (CGAL)</string> + </property> + <property name="shortcut"> + <string>F6</string> + </property> + </action> + <action name="designActionDisplayAST"> + <property name="text"> + <string>Display &AST...</string> + </property> + </action> + <action name="designActionDisplayCSGTree"> + <property name="text"> + <string>Display CSG &Tree...</string> + </property> + </action> + <action name="designActionDisplayCSGProducts"> + <property name="text"> + <string>Display CSG &Products...</string> + </property> + </action> + <action name="designActionExportSTL"> + <property name="text"> + <string>Export as &STL...</string> + </property> + </action> + <action name="designActionExportOFF"> + <property name="text"> + <string>Export as &OFF...</string> + </property> + </action> + <action name="viewActionOpenCSG"> + <property name="checkable"> + <bool>true</bool> + </property> + <property name="text"> + <string>OpenCSG</string> + </property> + <property name="shortcut"> + <string>F9</string> + </property> + </action> + <action name="viewActionCGALSurfaces"> + <property name="checkable"> + <bool>true</bool> + </property> + <property name="text"> + <string>CGAL Surfaces</string> + </property> + <property name="shortcut"> + <string>F10</string> + </property> + </action> + <action name="viewActionCGALGrid"> + <property name="checkable"> + <bool>true</bool> + </property> + <property name="text"> + <string>CGAL Grid Only</string> + </property> + <property name="shortcut"> + <string>F11</string> + </property> + </action> + <action name="viewActionThrownTogether"> + <property name="checkable"> + <bool>true</bool> + </property> + <property name="text"> + <string>Thrown Together</string> + </property> + <property name="shortcut"> + <string>F12</string> + </property> + </action> + <action name="viewActionShowEdges"> + <property name="checkable"> + <bool>true</bool> + </property> + <property name="text"> + <string>Show Edges</string> + </property> + <property name="shortcut"> + <string>Ctrl+1</string> + </property> + </action> + <action name="viewActionShowAxes"> + <property name="checkable"> + <bool>true</bool> + </property> + <property name="text"> + <string>Show Axes</string> + </property> + <property name="shortcut"> + <string>Ctrl+2</string> + </property> + </action> + <action name="viewActionShowCrosshairs"> + <property name="checkable"> + <bool>true</bool> + </property> + <property name="text"> + <string>Show Crosshairs</string> + </property> + <property name="shortcut"> + <string>Ctrl+3</string> + </property> + </action> + <action name="viewActionAnimate"> + <property name="checkable"> + <bool>true</bool> + </property> + <property name="text"> + <string>Animate</string> + </property> + </action> + <action name="viewActionTop"> + <property name="text"> + <string>Top</string> + </property> + <property name="shortcut"> + <string>Ctrl+4</string> + </property> + </action> + <action name="viewActionBottom"> + <property name="text"> + <string>Bottom</string> + </property> + <property name="shortcut"> + <string>Ctrl+5</string> + </property> + </action> + <action name="viewActionLeft"> + <property name="text"> + <string>Left</string> + </property> + <property name="shortcut"> + <string>Ctrl+6</string> + </property> + </action> + <action name="viewActionRight"> + <property name="text"> + <string>Right</string> + </property> + <property name="shortcut"> + <string>Ctrl+7</string> + </property> + </action> + <action name="viewActionFront"> + <property name="text"> + <string>Front</string> + </property> + <property name="shortcut"> + <string>Ctrl+8</string> + </property> + </action> + <action name="viewActionBack"> + <property name="text"> + <string>Back</string> + </property> + <property name="shortcut"> + <string>Ctrl+9</string> + </property> + </action> + <action name="viewActionDiagonal"> + <property name="text"> + <string>Diagonal</string> + </property> + <property name="shortcut"> + <string>Ctrl+0</string> + </property> + </action> + <action name="viewActionCenter"> + <property name="text"> + <string>Center</string> + </property> + <property name="shortcut"> + <string>Ctrl+P</string> + </property> + </action> + <action name="viewActionPerspective"> + <property name="checkable"> + <bool>true</bool> + </property> + <property name="text"> + <string>Perspective</string> + </property> + </action> + <action name="viewActionOrthogonal"> + <property name="checkable"> + <bool>true</bool> + </property> + <property name="text"> + <string>Orthogonal</string> + </property> + </action> + <action name="viewActionHide"> + <property name="checkable"> + <bool>true</bool> + </property> + <property name="text"> + <string>Hide console</string> + </property> + </action> + <action name="helpActionAbout"> + <property name="text"> + <string>About</string> + </property> + </action> + <action name="helpActionManual"> + <property name="text"> + <string>OpenSCAD Manual</string> + </property> + </action> + <action name="fileActionClearRecent"> + <property name="text"> + <string>Clear Recent</string> + </property> + </action> + <action name="designActionExportDXF"> + <property name="text"> + <string>Export as DXF...</string> + </property> + </action> + <action name="fileActionClose"> + <property name="text"> + <string>Close</string> + </property> + <property name="shortcut"> + <string>Ctrl+W</string> + </property> + </action> + <action name="editActionPreferences"> + <property name="text"> + <string>Preferences</string> + </property> + </action> + <action name="designActionFlushCaches"> + <property name="text"> + <string>Flush Caches</string> + </property> + </action> + </widget> + <customwidgets> + <customwidget> + <class>GLView</class> + <extends>QWidget</extends> + <header>GLView.h</header> + <container>1</container> + </customwidget> + </customwidgets> + <resources> + <include location="openscad.qrc"/> + </resources> + <connections> + <connection> + <sender>fileActionClose</sender> + <signal>triggered()</signal> + <receiver>MainWindow</receiver> + <slot>close()</slot> + <hints> + <hint type="sourcelabel"> + <x>-1</x> + <y>-1</y> + </hint> + <hint type="destinationlabel"> + <x>340</x> + <y>323</y> + </hint> + </hints> + </connection> + </connections> +</ui> 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 @@ +<?xml version="1.0" encoding="UTF-8"?> +<ui version="4.0"> + <class>Preferences</class> + <widget class="QMainWindow" name="Preferences"> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>384</width> + <height>243</height> + </rect> + </property> + <property name="windowTitle"> + <string>Preferences</string> + </property> + <property name="unifiedTitleAndToolBarOnMac"> + <bool>true</bool> + </property> + <widget class="QWidget" name="centralwidget"> + <layout class="QVBoxLayout" name="verticalLayout"> + <item> + <widget class="QStackedWidget" name="stackedWidget"> + <property name="currentIndex"> + <number>1</number> + </property> + <widget class="QWidget" name="page3DView"> + <layout class="QVBoxLayout" name="verticalLayout_4"> + <item> + <layout class="QHBoxLayout" name="horizontalLayout" stretch="1,3"> + <item> + <layout class="QVBoxLayout" name="verticalLayout_2"> + <item> + <widget class="QLabel" name="label"> + <property name="text"> + <string>Color scheme:</string> + </property> + </widget> + </item> + <item> + <widget class="QListWidget" name="colorSchemeChooser"> + <property name="alternatingRowColors"> + <bool>false</bool> + </property> + <property name="currentRow"> + <number>0</number> + </property> + <item> + <property name="text"> + <string>Cornfield</string> + </property> + </item> + <item> + <property name="text"> + <string>Metallic</string> + </property> + </item> + <item> + <property name="text"> + <string>Sunset</string> + </property> + </item> + </widget> + </item> + </layout> + </item> + <item> + <spacer name="horizontalSpacer"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>40</width> + <height>20</height> + </size> + </property> + </spacer> + </item> + </layout> + </item> + <item> + <spacer name="verticalSpacer"> + <property name="orientation"> + <enum>Qt::Vertical</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>20</width> + <height>645</height> + </size> + </property> + </spacer> + </item> + </layout> + </widget> + <widget class="QWidget" name="pageEditor"> + <layout class="QVBoxLayout" name="verticalLayout_5"> + <item> + <layout class="QGridLayout" name="gridLayout"> + <item row="0" column="0"> + <widget class="QLabel" name="label_3"> + <property name="font"> + <font> + <weight>75</weight> + <bold>true</bold> + </font> + </property> + <property name="text"> + <string>Font</string> + </property> + <property name="scaledContents"> + <bool>false</bool> + </property> + </widget> + </item> + <item row="0" column="1"> + <spacer name="horizontalSpacer_4"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>40</width> + <height>20</height> + </size> + </property> + </spacer> + </item> + <item row="1" column="0" colspan="2"> + <widget class="QFontComboBox" name="fontChooser"> + <property name="currentFont"> + <font> + <family>Monaco</family> + <pointsize>12</pointsize> + </font> + </property> + </widget> + </item> + <item row="1" column="2"> + <widget class="QComboBox" name="fontSize"> + <property name="editable"> + <bool>true</bool> + </property> + </widget> + </item> + <item row="1" column="3"> + <spacer name="horizontalSpacer_5"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>40</width> + <height>20</height> + </size> + </property> + </spacer> + </item> + </layout> + </item> + <item> + <spacer name="verticalSpacer_4"> + <property name="orientation"> + <enum>Qt::Vertical</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>20</width> + <height>77</height> + </size> + </property> + </spacer> + </item> + </layout> + </widget> + <widget class="QWidget" name="pageAdvanced"> + <layout class="QVBoxLayout" name="verticalLayout_3"> + <property name="margin"> + <number>0</number> + </property> + <item> + <spacer name="verticalSpacer_2"> + <property name="orientation"> + <enum>Qt::Vertical</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>20</width> + <height>120</height> + </size> + </property> + </spacer> + </item> + <item> + <layout class="QHBoxLayout" name="horizontalLayout_2"> + <item> + <spacer name="horizontalSpacer_2"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>40</width> + <height>20</height> + </size> + </property> + </spacer> + </item> + <item> + <widget class="QLabel" name="label_2"> + <property name="enabled"> + <bool>false</bool> + </property> + <property name="text"> + <string>advanced</string> + </property> + </widget> + </item> + <item> + <spacer name="horizontalSpacer_3"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>40</width> + <height>20</height> + </size> + </property> + </spacer> + </item> + </layout> + </item> + <item> + <spacer name="verticalSpacer_3"> + <property name="orientation"> + <enum>Qt::Vertical</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>20</width> + <height>120</height> + </size> + </property> + </spacer> + </item> + </layout> + </widget> + </widget> + </item> + </layout> + </widget> + <widget class="QToolBar" name="toolBar"> + <property name="windowTitle"> + <string>toolBar</string> + </property> + <property name="movable"> + <bool>false</bool> + </property> + <property name="allowedAreas"> + <set>Qt::TopToolBarArea</set> + </property> + <property name="toolButtonStyle"> + <enum>Qt::ToolButtonTextUnderIcon</enum> + </property> + <property name="floatable"> + <bool>false</bool> + </property> + <attribute name="toolBarArea"> + <enum>TopToolBarArea</enum> + </attribute> + <attribute name="toolBarBreak"> + <bool>false</bool> + </attribute> + <addaction name="prefsAction3DView"/> + <addaction name="prefsActionEditor"/> + <addaction name="prefsActionAdvanced"/> + </widget> + <action name="prefsAction3DView"> + <property name="checkable"> + <bool>true</bool> + </property> + <property name="icon"> + <iconset resource="openscad.qrc"> + <normaloff>:/prefs3DView.png</normaloff> + <normalon>:/openscad.ico</normalon>:/prefs3DView.png</iconset> + </property> + <property name="text"> + <string>3D View</string> + </property> + </action> + <action name="prefsActionAdvanced"> + <property name="checkable"> + <bool>true</bool> + </property> + <property name="icon"> + <iconset resource="openscad.qrc"> + <normaloff>:/prefsAdvanced.png</normaloff>:/prefsAdvanced.png</iconset> + </property> + <property name="text"> + <string>Advanced</string> + </property> + </action> + <action name="prefsActionEditor"> + <property name="checkable"> + <bool>true</bool> + </property> + <property name="icon"> + <iconset resource="openscad.qrc"> + <normaloff>:/prefsEditor.png</normaloff>:/prefsEditor.png</iconset> + </property> + <property name="text"> + <string>Editor</string> + </property> + </action> + </widget> + <resources> + <include location="openscad.qrc"/> + </resources> + <connections/> +</ui> 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 <QHash> + +extern QHash<QString, class AbstractFunction*> builtin_functions; +extern void initialize_builtin_functions(); +extern void destroy_builtin_functions(); + +extern QHash<QString, class AbstractModule*> 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 <CGAL/Gmpq.h> +#include <CGAL/Extended_cartesian.h> +#include <CGAL/Nef_polyhedron_2.h> +#include <CGAL/Cartesian.h> +#include <CGAL/Polyhedron_3.h> +#include <CGAL/Nef_polyhedron_3.h> +#include <CGAL/IO/Polyhedron_iostream.h> + +typedef CGAL::Extended_cartesian<CGAL::Gmpq> CGAL_Kernel2; +typedef CGAL::Nef_polyhedron_2<CGAL_Kernel2> CGAL_Nef_polyhedron2; +typedef CGAL_Kernel2::Aff_transformation_2 CGAL_Aff_transformation2; + +typedef CGAL::Cartesian<CGAL::Gmpq> CGAL_Kernel3; +typedef CGAL::Polyhedron_3<CGAL_Kernel3> CGAL_Polyhedron; +typedef CGAL_Polyhedron::HalfedgeDS CGAL_HDS; +typedef CGAL::Polyhedron_incremental_builder_3<CGAL_HDS> CGAL_Polybuilder; +typedef CGAL::Nef_polyhedron_3<CGAL_Kernel3> 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 <geoffk@ozemail.com.au> * + * Implemented first version of chrpath.c based on first version of * + * killrpath. * + * Peeter Joot <peeterj@ca.ibm.com> * + * Implemented first version of killrpath.c. * + * Petter Reinholdtsen <pere@hungry.com> * + * Collected both implementations and made userfriendly wrapper. * + * * + * With patches from: * + * * + * Darren Salt <linux@youmustbejoking.demon.co.uk> * + * David Hull <hull@paracel.com> * + * Bradford W. Johnson <bradford@math.umn.edu> * + * Thomas Anders <anders@hmi.de> * + * Tollef Fog Heen <tollef@add.no> * + * * + ***************************************************************************/ + + +/* config.h. Generated by configure. */ +/* config.h.in. Generated from configure.ac by autoheader. */ + +/* Define to 1 if you have the <elf.h> header file. */ +#define HAVE_ELF_H 1 + +/* Define to 1 if you have the <fcntl.h> header file. */ +#define HAVE_FCNTL_H 1 + +/* Define to 1 if you have the <getopt.h> 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 <inttypes.h> header file. */ +#define HAVE_INTTYPES_H 1 + +/* Define to 1 if you have the <link.h> header file. */ +#define HAVE_LINK_H 1 + +/* Define to 1 if you have the <memory.h> header file. */ +#define HAVE_MEMORY_H 1 + +/* Define to 1 if you have the <stdint.h> header file. */ +#define HAVE_STDINT_H 1 + +/* Define to 1 if you have the <stdlib.h> header file. */ +#define HAVE_STDLIB_H 1 + +/* Define to 1 if you have the <strings.h> header file. */ +#define HAVE_STRINGS_H 1 + +/* Define to 1 if you have the <string.h> header file. */ +#define HAVE_STRING_H 1 + +/* Define to 1 if you have the <sys/link.h> header file. */ +/* #undef HAVE_SYS_LINK_H */ + +/* Define to 1 if you have the <sys/stat.h> header file. */ +#define HAVE_SYS_STAT_H 1 + +/* Define to 1 if you have the <sys/types.h> header file. */ +#define HAVE_SYS_TYPES_H 1 + +/* Define to 1 if you have the <unistd.h> 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 <elf.h> +//#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 */ +/* +<URL:http://gcc.gnu.org/ml/gcc/1999-04n/msg01105.html> + +Re: changing embedded RPATH in existing executables. + + To: geoffk@ozemail.com.au + Subject: Re: changing embedded RPATH in existing executables. + From: <peeter_joot@VNET.IBM.COM> (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: <peeter_joot@VNET.IBM.COM> + +> _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 <stdio.h> +#include <unistd.h> +#include <fcntl.h> +#include <elf.h> +#if defined(HAVE_LINK_H) +# include <link.h> +#endif /* HAVE_LINK_H */ +#include <stdlib.h> +#include <string.h> +#include <sys/stat.h> +//#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 <elf.h> +#if defined(HAVE_SYS_LINK_H) +# include <sys/link.h> /* Find DT_RPATH on Solaris 2.6 */ +#endif /* HAVE_SYS_LINK_H */ +#include <stdio.h> +#include <string.h> +#include <unistd.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <errno.h> +#include <fcntl.h> +//#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 <geoffk@ozemail.com.au> +*/ + +#ifdef HAVE_CONFIG_H +//# include "config.h" +#endif + +#include <stdio.h> +#include <unistd.h> +#include <fcntl.h> +#include <elf.h> +#if defined(HAVE_LINK_H) +# include <link.h> +#endif /* HAVE_LINK_H */ +#include <stdlib.h> +//#include "protos.h" +#include <string.h> + +/* 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 <pere@hungry.com> + * date: 2001-01-20 + * + * Alter ELF rpath information (insert, modify, remove). + * + * Based on source from Peeter Joot <peeterj@ca.ibm.com> and Geoffrey + * Keating <geoffk@ozemail.com.au>. + */ + +#ifdef HAVE_CONFIG_H +//# include "config.h" +#endif + +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> +#ifdef HAVE_GETOPT_H +#include <getopt.h> +#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 <path>] <program> [<program> ...]\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 <path>|--replace <path> 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 <QHash> +#include <QString> +#include "value.h" + +class Context +{ +public: + const Context *parent; + QHash<QString, Value> variables; + QHash<QString, Value> config_variables; + const QHash<QString, class AbstractFunction*> *functions_p; + const QHash<QString, class AbstractModule*> *modules_p; + const class ModuleInstantiation *inst_p; + + static QVector<const Context*> ctx_stack; + + Context(const Context *parent = NULL); + ~Context(); + + void args(const QVector<QString> &argnames, const QVector<class Expression*> &argexpr, const QVector<QString> &call_argnames, const QVector<Value> &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<QString> &argnames, const QVector<Value> &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 <QString> +#include <QVector> + +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<PolySet*> polysets; + QVector<double*> matrices; + QVector<CSGTerm::type_e> types; + QVector<QString> 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 <QFile> #include <QTextStream> +#include <QHash> +#include <QVector> +#include <math.h> 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 <QList> +#include <QString> + +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<Point*> 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<Point> points; + QList<Path> paths; + QList<Dim> 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 <math.h> #include <sys/types.h> #include <sys/stat.h> #include <unistd.h> +#include <QHash> QHash<QString,Value> dxf_dim_cache; QHash<QString,Value> 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 <QHash> +#include "value.h" + +extern QHash<QString,Value> dxf_cross_cache; +extern QHash<QString,Value> 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 <sys/types.h> #include <sys/stat.h> @@ -29,6 +34,7 @@ #include <QApplication> #include <QTime> +#include <QProgressDialog> 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 <sys/types.h> #include <sys/stat.h> @@ -29,6 +33,7 @@ #include <QTime> #include <QApplication> +#include <QProgressDialog> 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 <CGAL/Exact_predicates_inexact_constructions_kernel.h> 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 <GL/glew.h> +#endif +#include <qgl.h> +#include <math.h> + #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 <QApplication> +#include <QProgressDialog> #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 <QVector> +#include <QString> + +class Expression +{ +public: + QVector<Expression*> children; + + class Value *const_value; + QString var_name; + + QString call_funcname; + QVector<QString> 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 <math.h> 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 <QString> + +class AbstractFunction +{ +public: + virtual ~AbstractFunction(); + virtual Value evaluate(const class Context *ctx, const QVector<QString> &call_argnames, const QVector<Value> &call_argvalues) const; + virtual QString dump(QString indent, QString name) const; +}; + +class BuiltinFunction : public AbstractFunction +{ +public: + typedef Value (*eval_func_t)(const QVector<QString> &argnames, const QVector<Value> &args); + eval_func_t eval_func; + + BuiltinFunction(eval_func_t f) : eval_func(f) { } + virtual ~BuiltinFunction(); + + virtual Value evaluate(const Context *ctx, const QVector<QString> &call_argnames, const QVector<Value> &call_argvalues) const; + virtual QString dump(QString indent, QString name) const; +}; + +class Function : public AbstractFunction +{ +public: + QVector<QString> argnames; + QVector<class Expression*> argexpr; + + Expression *expr; + + Function() { } + virtual ~Function(); + + virtual Value evaluate(const Context *ctx, const QVector<QString> &call_argnames, const QVector<Value> &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 <QMouseEvent> #include <QMessageBox> #include <QTimer> +#include <math.h> #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 <math.h> +#include <QHash> + +const double GRID_COARSE = 0.001; +const double GRID_FINE = 0.000001; + +template <typename T> +class Grid2d +{ +public: + double res; + QHash<QPair<int64_t,int64_t>, 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<int64_t,int64_t>(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<int64_t,int64_t>(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<int64_t,int64_t>(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<int64_t,int64_t>(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<int64_t,int64_t>(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 <typename T> +class Grid3d +{ +public: + double res; + QHash<QPair<QPair<int64_t,int64_t>,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<QPair<int64_t,int64_t>,int64_t>(QPair<int64_t,int64_t>(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<QPair<int64_t,int64_t>,int64_t>(QPair<int64_t,int64_t>(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<QPair<int64_t,int64_t>,int64_t>(QPair<int64_t,int64_t>(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<QPair<int64_t,int64_t>,int64_t>(QPair<int64_t,int64_t>(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<QPair<int64_t,int64_t>,int64_t>(QPair<int64_t,int64_t>(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 <QSyntaxHighlighter> + +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 <QFile> #include <sys/types.h> 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 <clifford@clifford.at> + * + * 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); +} + +<<EOF>> { + 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); +<comment>"*/" BEGIN(INITIAL); +<comment>.|\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 <QMenu> #include <QTime> 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<QString, AbstractNode::cgal_nef_cache_entry> 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<CSGTerm*> *highlights, QVector<CSGTerm*> *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<CSGTerm*> *highlights, QVector<CSGTerm*> *background) const -{ - return render_csg_term_backend(this, false, m, highlights, background); -} - -CSGTerm *AbstractIntersectionNode::render_csg_term(double m[20], QVector<CSGTerm*> *highlights, QVector<CSGTerm*> *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 <QString> +#include <QVector> +#include <QHash> +#include "value.h" + +class ModuleInstantiation +{ +public: + QString label; + QString modname; + QVector<QString> argnames; + QVector<class Expression*> argexpr; + QVector<Value> argvalues; + QVector<ModuleInstantiation*> 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<QString> argnames; + QVector<Expression*> argexpr; + + QVector<QString> assignments_var; + QVector<Expression*> assignments_expr; + + QHash<QString, class AbstractFunction*> functions; + QHash<QString, AbstractModule*> modules; + + QVector<ModuleInstantiation*> 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 <clifford@clifford.at> + * + * 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 <QRegExp> + +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<QString, AbstractNode::cgal_nef_cache_entry> 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<CSGTerm*> *highlights, QVector<CSGTerm*> *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<CSGTerm*> *highlights, QVector<CSGTerm*> *background) const +{ + return render_csg_term_backend(this, false, m, highlights, background); +} + +CSGTerm *AbstractIntersectionNode::render_csg_term(double m[20], QVector<CSGTerm*> *highlights, QVector<CSGTerm*> *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 <QCache> +#include <QVector> + +#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<AbstractNode*> 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<QString, cgal_nef_cache_entry> cgal_nef_cache; + virtual CGAL_Nef_polyhedron render_cgal_nef_polyhedron() const; +#endif + virtual class CSGTerm *render_csg_term(double m[20], QVector<CSGTerm*> *highlights, QVector<CSGTerm*> *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<CSGTerm*> *highlights, QVector<CSGTerm*> *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<CSGTerm*> *highlights, QVector<CSGTerm*> *background) const; + static CSGTerm *render_csg_term_from_ps(double m[20], QVector<CSGTerm*> *highlights, QVector<CSGTerm*> *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 <QApplication> #include <QFile> @@ -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 <GL/glew.h> #endif -#include <qgl.h> - -#include <QHash> -#include <QCache> -#include <QVector> -#include <QProgressDialog> -#include <QSyntaxHighlighter> -#include <QPointer> - -#include <stdio.h> -#include <errno.h> -#include <stdlib.h> -#include <string.h> -#include <assert.h> -#include <math.h> - -#include <fstream> -#include <iostream> - // 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 <typename T> -class Grid2d -{ -public: - double res; - QHash<QPair<int64_t,int64_t>, 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<int64_t,int64_t>(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<int64_t,int64_t>(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<int64_t,int64_t>(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<int64_t,int64_t>(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<int64_t,int64_t>(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 <typename T> -class Grid3d -{ -public: - double res; - QHash<QPair<QPair<int64_t,int64_t>,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<QPair<int64_t,int64_t>,int64_t>(QPair<int64_t,int64_t>(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<QPair<int64_t,int64_t>,int64_t>(QPair<int64_t,int64_t>(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<QPair<int64_t,int64_t>,int64_t>(QPair<int64_t,int64_t>(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<QPair<int64_t,int64_t>,int64_t>(QPair<int64_t,int64_t>(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<QPair<int64_t,int64_t>,int64_t>(QPair<int64_t,int64_t>(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<Value*> 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<Expression*> children; - - Value *const_value; - QString var_name; - - QString call_funcname; - QVector<QString> 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<QString> &call_argnames, const QVector<Value> &call_argvalues) const; - virtual QString dump(QString indent, QString name) const; -}; - -class BuiltinFunction : public AbstractFunction -{ -public: - typedef Value (*eval_func_t)(const QVector<QString> &argnames, const QVector<Value> &args); - eval_func_t eval_func; - - BuiltinFunction(eval_func_t f) : eval_func(f) { } - virtual ~BuiltinFunction(); - - virtual Value evaluate(const Context *ctx, const QVector<QString> &call_argnames, const QVector<Value> &call_argvalues) const; - virtual QString dump(QString indent, QString name) const; -}; - -class Function : public AbstractFunction -{ -public: - QVector<QString> argnames; - QVector<Expression*> argexpr; - - Expression *expr; - - Function() { } - virtual ~Function(); - - virtual Value evaluate(const Context *ctx, const QVector<QString> &call_argnames, const QVector<Value> &call_argvalues) const; - virtual QString dump(QString indent, QString name) const; -}; - -extern QHash<QString, AbstractFunction*> 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<QString> argnames; - QVector<Expression*> argexpr; - QVector<Value> argvalues; - QVector<ModuleInstantiation*> 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<QString> argnames; - QVector<Expression*> argexpr; - - QVector<QString> assignments_var; - QVector<Expression*> assignments_expr; - - QHash<QString, AbstractFunction*> functions; - QHash<QString, AbstractModule*> modules; - - QVector<ModuleInstantiation*> children; - - Module() { } - virtual ~Module(); - - virtual AbstractNode *evaluate(const Context *ctx, const ModuleInstantiation *inst) const; - virtual QString dump(QString indent, QString name) const; -}; - -extern QHash<QString, AbstractModule*> 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<QString, Value> variables; - QHash<QString, Value> config_variables; - const QHash<QString, AbstractFunction*> *functions_p; - const QHash<QString, AbstractModule*> *modules_p; - const ModuleInstantiation *inst_p; - - static QVector<const Context*> ctx_stack; - - Context(const Context *parent = NULL); - ~Context(); - - void args(const QVector<QString> &argnames, const QVector<Expression*> &argexpr, const QVector<QString> &call_argnames, const QVector<Value> &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<QString> &argnames, const QVector<Value> &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<Point*> 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<Point> points; - QList<Path> paths; - QList<Dim> 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 <CGAL/Gmpq.h> -#include <CGAL/Extended_cartesian.h> -#include <CGAL/Nef_polyhedron_2.h> -#include <CGAL/Cartesian.h> -#include <CGAL/Polyhedron_3.h> -#include <CGAL/Nef_polyhedron_3.h> -#include <CGAL/IO/Polyhedron_iostream.h> - -typedef CGAL::Extended_cartesian<CGAL::Gmpq> CGAL_Kernel2; -typedef CGAL::Nef_polyhedron_2<CGAL_Kernel2> CGAL_Nef_polyhedron2; -typedef CGAL_Kernel2::Aff_transformation_2 CGAL_Aff_transformation2; - -typedef CGAL::Cartesian<CGAL::Gmpq> CGAL_Kernel3; -typedef CGAL::Polyhedron_3<CGAL_Kernel3> CGAL_Polyhedron; -typedef CGAL_Polyhedron::HalfedgeDS CGAL_HDS; -typedef CGAL::Polyhedron_incremental_builder_3<CGAL_HDS> CGAL_Polybuilder; -typedef CGAL::Nef_polyhedron_3<CGAL_Kernel3> 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 <opencsg.h> -#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<Point> Polygon; - QVector<Polygon> polygons; - QVector<Polygon> borders; - Grid3d<void*> 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<QString,ps_cache_entry> 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<PolySet*> polysets; - QVector<double*> matrices; - QVector<CSGTerm::type_e> types; - QVector<QString> 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<AbstractNode*> 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<QString, cgal_nef_cache_entry> cgal_nef_cache; - virtual CGAL_Nef_polyhedron render_cgal_nef_polyhedron() const; -#endif - virtual CSGTerm *render_csg_term(double m[20], QVector<CSGTerm*> *highlights, QVector<CSGTerm*> *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<CSGTerm*> *highlights, QVector<CSGTerm*> *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<CSGTerm*> *highlights, QVector<CSGTerm*> *background) const; - static CSGTerm *render_csg_term_from_ps(double m[20], QVector<CSGTerm*> *highlights, QVector<CSGTerm*> *background, PolySet *ps, const ModuleInstantiation *modinst, int idx); -}; - -extern QHash<QString,Value> dxf_dim_cache; -extern QHash<QString,Value> 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 <QString> 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 <clifford@clifford.at> + * + * 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*> module_stack; +Module *module; + +class ArgContainer { +public: + QString argname; + Expression *argexpr; +}; +class ArgsContainer { +public: + QVector<QString> argnames; + QVector<Expression*> 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 <text> TOK_ID +%token <text> TOK_STRING +%token <number> 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> expr +%type <expr> vector_expr + +%type <inst> module_instantiation +%type <inst> module_instantiation_list +%type <inst> single_module_instantiation + +%type <args> arguments_call +%type <args> arguments_decl + +%type <arg> argument_call +%type <arg> 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 <GL/glew.h> +#endif +#include <qgl.h> + +#include "grid.h" +#ifdef ENABLE_OPENCSG +# include <opencsg.h> +#endif +#ifdef ENABLE_CGAL +# include "cgal.h" +#endif + +#include <QCache.h> + +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<Point> Polygon; + QVector<Polygon> polygons; + QVector<Polygon> borders; + Grid3d<void*> 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<QString,ps_cache_entry> 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 <QProgressDialog> #include <QApplication> 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 <QFile> 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 <math.h> 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 <QVector> +#include <QString> + +class Value +{ +public: + enum type_e { + UNDEFINED, + BOOL, + NUMBER, + RANGE, + VECTOR, + STRING + }; + + enum type_e type; + + bool b; + double num; + QVector<Value*> 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 |