summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorkintel <kintel@b57f626f-c46c-0410-a088-ec61d464b74c>2010-01-30 04:26:05 (GMT)
committerkintel <kintel@b57f626f-c46c-0410-a088-ec61d464b74c>2010-01-30 04:26:05 (GMT)
commit191dc4857c852f1867e80cd9d03a6d1c0921dcb1 (patch)
tree4a6421d50eb6cf70924fc0ba06afccf10df00650 /src
parent6940d171812565209efe679a5d923417c3f47d4a (diff)
header file reorg
git-svn-id: http://svn.clifford.at/openscad/trunk@365 b57f626f-c46c-0410-a088-ec61d464b74c
Diffstat (limited to 'src')
-rw-r--r--src/CGAL_renderer.h2
-rw-r--r--src/MainWindow.h10
-rw-r--r--src/MainWindow.ui675
-rw-r--r--src/Preferences.ui321
-rw-r--r--src/builtin.h25
-rw-r--r--src/cgal.h59
-rw-r--r--src/chrpath_linux.c769
-rw-r--r--src/context.cc5
-rw-r--r--src/context.h32
-rw-r--r--src/control.cc7
-rw-r--r--src/csgops.cc10
-rw-r--r--src/csgterm.cc5
-rw-r--r--src/csgterm.h51
-rw-r--r--src/dxfdata.cc7
-rw-r--r--src/dxfdata.h50
-rw-r--r--src/dxfdim.cc8
-rw-r--r--src/dxfdim.h10
-rw-r--r--src/dxflinextrude.cc12
-rw-r--r--src/dxfrotextrude.cc11
-rw-r--r--src/dxftess-cgal.cc1
-rw-r--r--src/dxftess-glu.cc12
-rw-r--r--src/dxftess.cc3
-rw-r--r--src/dxftess.h9
-rw-r--r--src/export.cc6
-rw-r--r--src/export.h10
-rw-r--r--src/expr.cc4
-rw-r--r--src/expression.h40
-rw-r--r--src/func.cc7
-rw-r--r--src/function.h43
-rw-r--r--src/glview.cc2
-rw-r--r--src/grid.h136
-rw-r--r--src/highlighter.cc3
-rw-r--r--src/highlighter.h13
-rw-r--r--src/import.cc11
-rw-r--r--src/lexer.l114
-rw-r--r--src/mainwin.cc13
-rw-r--r--src/module.cc180
-rw-r--r--src/module.h60
-rw-r--r--src/nef2dxf.cc6
-rw-r--r--src/node.cc196
-rw-r--r--src/node.h75
-rw-r--r--src/openscad.cc11
-rw-r--r--src/openscad.h697
-rw-r--r--src/parser.y524
-rw-r--r--src/polyset.cc7
-rw-r--r--src/polyset.h89
-rw-r--r--src/primitives.cc10
-rw-r--r--src/render.cc14
-rw-r--r--src/surface.cc10
-rw-r--r--src/transform.cc11
-rw-r--r--src/value.cc3
-rw-r--r--src/value.h68
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>&amp;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>&amp;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>&amp;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>&amp;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>&amp;New</string>
+ </property>
+ <property name="shortcut">
+ <string>Ctrl+N</string>
+ </property>
+ </action>
+ <action name="fileActionOpen">
+ <property name="text">
+ <string>&amp;Open...</string>
+ </property>
+ <property name="shortcut">
+ <string>Ctrl+O</string>
+ </property>
+ </action>
+ <action name="fileActionSave">
+ <property name="text">
+ <string>&amp;Save</string>
+ </property>
+ <property name="shortcut">
+ <string>Ctrl+S</string>
+ </property>
+ </action>
+ <action name="fileActionSaveAs">
+ <property name="text">
+ <string>Save &amp;As...</string>
+ </property>
+ <property name="shortcut">
+ <string>Ctrl+Shift+S</string>
+ </property>
+ </action>
+ <action name="fileActionReload">
+ <property name="text">
+ <string>&amp;Reload</string>
+ </property>
+ <property name="shortcut">
+ <string>Ctrl+R</string>
+ </property>
+ </action>
+ <action name="fileActionQuit">
+ <property name="text">
+ <string>&amp;Quit</string>
+ </property>
+ </action>
+ <action name="editActionUndo">
+ <property name="text">
+ <string>&amp;Undo</string>
+ </property>
+ <property name="shortcut">
+ <string>Ctrl+Z</string>
+ </property>
+ </action>
+ <action name="editActionRedo">
+ <property name="text">
+ <string>&amp;Redo</string>
+ </property>
+ <property name="shortcut">
+ <string>Ctrl+Shift+Z</string>
+ </property>
+ </action>
+ <action name="editActionCut">
+ <property name="text">
+ <string>Cu&amp;t</string>
+ </property>
+ <property name="shortcut">
+ <string>Ctrl+X</string>
+ </property>
+ </action>
+ <action name="editActionCopy">
+ <property name="text">
+ <string>&amp;Copy</string>
+ </property>
+ <property name="shortcut">
+ <string>Ctrl+C</string>
+ </property>
+ </action>
+ <action name="editActionPaste">
+ <property name="text">
+ <string>&amp;Paste</string>
+ </property>
+ <property name="shortcut">
+ <string>Ctrl+V</string>
+ </property>
+ </action>
+ <action name="editActionIndent">
+ <property name="text">
+ <string>&amp;Indent</string>
+ </property>
+ <property name="shortcut">
+ <string>Ctrl+I</string>
+ </property>
+ </action>
+ <action name="editActionUnindent">
+ <property name="text">
+ <string>U&amp;nindent</string>
+ </property>
+ <property name="shortcut">
+ <string>Ctrl+Shift+I</string>
+ </property>
+ </action>
+ <action name="editActionComment">
+ <property name="text">
+ <string>C&amp;omment</string>
+ </property>
+ <property name="shortcut">
+ <string>Ctrl+D</string>
+ </property>
+ </action>
+ <action name="editActionUncomment">
+ <property name="text">
+ <string>Unco&amp;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>&amp;Reload and Compile</string>
+ </property>
+ <property name="shortcut">
+ <string>F4</string>
+ </property>
+ </action>
+ <action name="designActionCompile">
+ <property name="text">
+ <string>&amp;Compile</string>
+ </property>
+ <property name="shortcut">
+ <string>F5</string>
+ </property>
+ </action>
+ <action name="designActionCompileAndRender">
+ <property name="text">
+ <string>Compile and &amp;Render (CGAL)</string>
+ </property>
+ <property name="shortcut">
+ <string>F6</string>
+ </property>
+ </action>
+ <action name="designActionDisplayAST">
+ <property name="text">
+ <string>Display &amp;AST...</string>
+ </property>
+ </action>
+ <action name="designActionDisplayCSGTree">
+ <property name="text">
+ <string>Display CSG &amp;Tree...</string>
+ </property>
+ </action>
+ <action name="designActionDisplayCSGProducts">
+ <property name="text">
+ <string>Display CSG &amp;Products...</string>
+ </property>
+ </action>
+ <action name="designActionExportSTL">
+ <property name="text">
+ <string>Export as &amp;STL...</string>
+ </property>
+ </action>
+ <action name="designActionExportOFF">
+ <property name="text">
+ <string>Export as &amp;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
contact: Jan Huwald // Impressum