mirror of https://github.com/vitalif/openscad
merged in recent changes in master
commit
21ac6c05d1
|
@ -1,3 +1,22 @@
|
|||
OpenSCAD 20xx.yy
|
||||
================
|
||||
|
||||
|
||||
OpenSCAD 2011.06
|
||||
================
|
||||
|
||||
o Added "Export as Image" menu.
|
||||
|
||||
Bugfixes:
|
||||
o Cylinder tesselation broke existing models which are using cylinders
|
||||
for e.g. captured nut slots and are dependent on the orientation not
|
||||
changing.
|
||||
o DXF output couldn't be imported into e.g. AutoCAD and Solidworks after updating
|
||||
to using the AutoCAD 2000 (AC1015) format. Reverted to the old entity-only output,
|
||||
causing LWPOLYLINES to not exported allowed anymore.
|
||||
|
||||
|
||||
|
||||
OpenSCAD 2011.04
|
||||
================
|
||||
|
||||
|
|
2
cgal.pri
2
cgal.pri
|
@ -14,7 +14,7 @@ cgal {
|
|||
}
|
||||
|
||||
win32 {
|
||||
LIBS += $$CGAL_DIR/auxiliary/gmp/lib/libmpfr-4.lib -lCGAL-vc90-mt-gd
|
||||
LIBS += $$CGAL_DIR/auxiliary/gmp/lib/libmpfr-4.lib -lCGAL-vc90-mt-s
|
||||
} else {
|
||||
LIBS += -lgmp -lmpfr -lCGAL
|
||||
}
|
||||
|
|
|
@ -5,6 +5,7 @@ o Some invalid DXF data gets pass the import checks and breaks the tessing code
|
|||
o Tesselation via GLU sometimes produces strange results
|
||||
o Export STL: Exports existing CGAL model even though the current model is changed, but not CGAL rendered
|
||||
o Look into the polygon winding and rotate_extrude() problem reported by Britton
|
||||
o CGAL Aff_transformation_3 doesn't support non-affine transformations (non-aff-matrix.scad)
|
||||
|
||||
STL Import BUGS
|
||||
---------------
|
||||
|
@ -148,7 +149,7 @@ o Language Frontend
|
|||
- Rethink for vs. intersection_for vs. group. Should for loops
|
||||
generate child lists instead, and make these passable to other
|
||||
modules or accessible by child()?
|
||||
- constants: PI
|
||||
- constants: PI, OpenSCAD version
|
||||
o DXF Import/Export
|
||||
- Use dxflib from RibbonSoft for import/export? -> investigate
|
||||
- Import
|
||||
|
@ -161,7 +162,6 @@ o Mesh optimization on STL export
|
|||
- Remove super small triangles (all sides are short)
|
||||
- Replace super thin triangles (one h is short)
|
||||
o Misc
|
||||
- Add symbolic colors to the color() statement
|
||||
- When specifying a transparency with the color() statement,
|
||||
the object is not sorted and will be rendered wrongly
|
||||
- Go through default values of parameters (e.g. cube() has x,y,z=1 while linear_extrude() has height=100)
|
||||
|
@ -230,6 +230,7 @@ o Collect "all" available OpenSCAD scripts from the internets and run the integr
|
|||
tests on them all
|
||||
o dumptest tests:
|
||||
- filename are dumped as absolute filenames - this will fail on other systems
|
||||
o Write a regression test for the hexagonal cylinder orientation issue
|
||||
|
||||
INFRASTRUCTURE
|
||||
--------------
|
||||
|
|
|
@ -15,16 +15,21 @@ o build source package
|
|||
git archive --format=tar openscad-2011.01 --prefix=openscad-2011.01/ | gzip > openscad-2011.01.src.tar.gz
|
||||
|
||||
o build binaries
|
||||
tar xzf openscad-2011.01.src.tar.gz
|
||||
cd openscad-2011.01
|
||||
Mac OS X
|
||||
- publish-macosx.sh -> OpenSCAD-2011.01.dmg
|
||||
For Qt-4.7.3: Remove /Developers/Applications/Qt/plugins/qmltooling
|
||||
./scripts/publish-macosx.sh -> OpenSCAD-2011.01.dmg
|
||||
Linux: FIXME 32 vs. 64 bit
|
||||
- release-linux.sh
|
||||
./scripts/release-linux.sh
|
||||
Windows: FIXME 32 vs. 64 bit
|
||||
|
||||
o FIXME: Run some tests
|
||||
|
||||
o Set back version: release-linux.sh, publish-macosx.sh, FIXME: Windows
|
||||
|
||||
o git push --tags
|
||||
|
||||
o Upload
|
||||
- Github
|
||||
Upload manually here: https://github.com/openscad/openscad/downloads
|
||||
|
|
2
flex.pri
2
flex.pri
|
@ -3,7 +3,7 @@
|
|||
flex.name = Flex ${QMAKE_FILE_IN}
|
||||
flex.input = FLEXSOURCES
|
||||
flex.output = ${QMAKE_FILE_PATH}/${QMAKE_FILE_BASE}.lexer.cpp
|
||||
flex.commands = flex -P ${QMAKE_FILE_BASE} -o ${QMAKE_FILE_PATH}/${QMAKE_FILE_BASE}.lexer.cpp ${QMAKE_FILE_IN}
|
||||
flex.commands = flex -P ${QMAKE_FILE_BASE} -o${QMAKE_FILE_PATH}/${QMAKE_FILE_BASE}.lexer.cpp ${QMAKE_FILE_IN}
|
||||
flex.CONFIG += target_predeps
|
||||
flex.variable_out = GENERATED_SOURCES
|
||||
silent:flex.commands = @echo Lex ${QMAKE_FILE_IN} && $$flex.commands
|
||||
|
|
|
@ -0,0 +1,30 @@
|
|||
!include "FileAssociation.nsh"
|
||||
Name "OpenSCAD"
|
||||
OutFile "openscad_setup.exe"
|
||||
InstallDir $PROGRAMFILES\OpenSCAD
|
||||
DirText "This will install OpenSCAD on your computer. Choose a directory"
|
||||
Section "install"
|
||||
SetOutPath $INSTDIR
|
||||
File openscad.exe
|
||||
File /r examples
|
||||
File /r libraries
|
||||
${registerExtension} "$INSTDIR\openscad.exe" ".scad" "OpenSCAD_File"
|
||||
CreateShortCut $SMPROGRAMS\OpenSCAD.lnk $INSTDIR\openscad.exe
|
||||
WriteUninstaller $INSTDIR\Uninstall.exe
|
||||
WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\OpenSCAD" "DisplayName" "OpenSCAD (remove only)"
|
||||
WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\OpenSCAD" "UninstallString" "$INSTDIR\Uninstall.exe"
|
||||
SectionEnd
|
||||
Section "Uninstall"
|
||||
${unregisterExtension} ".scad" "OpenSCAD_File"
|
||||
Delete $INSTDIR\Uninstall.exe
|
||||
Delete $INSTDIR\MyProg.exe
|
||||
Delete $SMPROGRAMS\OpenSCAD.lnk
|
||||
DeleteRegKey HKEY_LOCAL_MACHINE "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\OpenSCAD"
|
||||
RMDir /r $INSTDIR\examples
|
||||
RMDir /r $INSTDIR\libraries\mcad
|
||||
Delete $INSTDIR\libraries\boxes.scad
|
||||
Delete $INSTDIR\libraries\shapes.scad
|
||||
RMDir $INSTDIR\libraries
|
||||
Delete $INSTDIR\openscad.exe
|
||||
RMDir $INSTDIR
|
||||
SectionEnd
|
|
@ -17,8 +17,8 @@
|
|||
# o Port to other platforms?
|
||||
#
|
||||
|
||||
BASEDIR=/Users/kintel/code/metalab/checkout/OpenSCAD/libraries
|
||||
OPENSCADDIR=/Users/kintel/code/metalab/checkout/OpenSCAD/openscad-release
|
||||
BASEDIR=/Users/kintel/code/OpenSCAD/libraries
|
||||
OPENSCADDIR=/Users/kintel/code/OpenSCAD/openscad
|
||||
SRCDIR=$BASEDIR/src
|
||||
DEPLOYDIR=$BASEDIR/install
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
#!/bin/sh
|
||||
|
||||
VERSION=`date "+%Y.%m.%d"`
|
||||
#VERSION=2011.04
|
||||
#VERSION=2011.06
|
||||
|
||||
# This is the same location as DEPLOYDIR in macosx-build-dependencies.sh
|
||||
export MACOSX_DEPLOY_DIR=$PWD/../libraries/install
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
# WARNING: This script might only work with the authors setup...
|
||||
|
||||
VERSION=`date "+%Y.%m.%d"`
|
||||
#VERSION=2011.04
|
||||
#VERSION=2011.06
|
||||
|
||||
set -ex
|
||||
|
||||
|
|
|
@ -83,6 +83,8 @@ private:
|
|||
static void consoleOutput(const QString &msg, void *userdata) {
|
||||
static_cast<MainWindow*>(userdata)->console->append(msg);
|
||||
}
|
||||
void loadViewSettings();
|
||||
void loadDesignSettings();
|
||||
|
||||
private slots:
|
||||
void actionNew();
|
||||
|
@ -113,6 +115,7 @@ private slots:
|
|||
void actionExportSTL();
|
||||
void actionExportOFF();
|
||||
void actionExportDXF();
|
||||
void actionExportImage();
|
||||
void actionFlushCaches();
|
||||
|
||||
public:
|
||||
|
|
|
@ -112,7 +112,7 @@
|
|||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>681</width>
|
||||
<height>25</height>
|
||||
<height>22</height>
|
||||
</rect>
|
||||
</property>
|
||||
<widget class="QMenu" name="menu_File">
|
||||
|
@ -178,6 +178,7 @@
|
|||
<addaction name="designActionExportSTL"/>
|
||||
<addaction name="designActionExportOFF"/>
|
||||
<addaction name="designActionExportDXF"/>
|
||||
<addaction name="designActionExportImage"/>
|
||||
<addaction name="designActionFlushCaches"/>
|
||||
</widget>
|
||||
<widget class="QMenu" name="menu_View">
|
||||
|
@ -651,6 +652,11 @@
|
|||
<string>Automatic Reload and Compile</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="designActionExportImage">
|
||||
<property name="text">
|
||||
<string>Export as Image...</string>
|
||||
</property>
|
||||
</action>
|
||||
</widget>
|
||||
<customwidgets>
|
||||
<customwidget>
|
||||
|
|
|
@ -40,6 +40,7 @@ Preferences::Preferences(QWidget *parent) : QMainWindow(parent)
|
|||
this->defaultmap["3dview/colorscheme"] = this->colorSchemeChooser->currentItem()->text();
|
||||
this->defaultmap["editor/fontfamily"] = this->fontChooser->currentText();
|
||||
this->defaultmap["editor/fontsize"] = this->fontSize->currentText().toUInt();
|
||||
this->defaultmap["editor/opengl20_warning_show"] = true;
|
||||
|
||||
// Toolbar
|
||||
QActionGroup *group = new QActionGroup(this);
|
||||
|
@ -97,7 +98,8 @@ Preferences::Preferences(QWidget *parent) : QMainWindow(parent)
|
|||
this, SLOT(fontFamilyChanged(const QString &)));
|
||||
connect(this->fontSize, SIGNAL(editTextChanged(const QString &)),
|
||||
this, SLOT(fontSizeChanged(const QString &)));
|
||||
|
||||
connect(this->OpenGL20WarningCheckbox, SIGNAL(clicked(bool)),
|
||||
this, SLOT(OpenGL20WarningChanged(bool)));
|
||||
updateGUI();
|
||||
}
|
||||
|
||||
|
@ -148,6 +150,13 @@ void Preferences::fontSizeChanged(const QString &size)
|
|||
emit fontChanged(getValue("editor/fontfamily").toString(), intsize);
|
||||
}
|
||||
|
||||
void
|
||||
Preferences::OpenGL20WarningChanged(bool state)
|
||||
{
|
||||
QSettings settings;
|
||||
settings.setValue("editor/opengl20_warning_show",state);
|
||||
}
|
||||
|
||||
void Preferences::keyPressEvent(QKeyEvent *e)
|
||||
{
|
||||
#ifdef Q_WS_MAC
|
||||
|
@ -185,6 +194,7 @@ QVariant Preferences::getValue(const QString &key) const
|
|||
|
||||
void Preferences::updateGUI()
|
||||
{
|
||||
QSettings settings;
|
||||
QList<QListWidgetItem *> found =
|
||||
this->colorSchemeChooser->findItems(getValue("3dview/colorscheme").toString(),
|
||||
Qt::MatchExactly);
|
||||
|
@ -204,6 +214,9 @@ void Preferences::updateGUI()
|
|||
else {
|
||||
this->fontSize->setEditText(fontsize);
|
||||
}
|
||||
|
||||
bool opengl20_warning_show = getValue("editor/opengl20_warning_show").toBool();
|
||||
this->OpenGL20WarningCheckbox->setChecked(opengl20_warning_show);
|
||||
}
|
||||
|
||||
void Preferences::apply() const
|
||||
|
@ -211,4 +224,3 @@ void Preferences::apply() const
|
|||
emit fontChanged(getValue("editor/fontfamily").toString(), getValue("editor/fontsize").toUInt());
|
||||
emit requestRedraw();
|
||||
}
|
||||
|
||||
|
|
|
@ -34,6 +34,7 @@ public slots:
|
|||
void colorSchemeChanged();
|
||||
void fontFamilyChanged(const QString &);
|
||||
void fontSizeChanged(const QString &);
|
||||
void OpenGL20WarningChanged(bool);
|
||||
|
||||
signals:
|
||||
void requestRedraw() const;
|
||||
|
|
|
@ -179,71 +179,29 @@
|
|||
<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">
|
||||
<layout class="QVBoxLayout" name="verticalLayout_6">
|
||||
<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>
|
||||
<widget class="QCheckBox" name="OpenGL20WarningCheckbox">
|
||||
<property name="text">
|
||||
<string>advanced</string>
|
||||
<string>Show OpenGL 2.0 warning && rendering info</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer_3">
|
||||
<spacer name="verticalSpacer_2">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
<width>20</width>
|
||||
<height>40</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>
|
||||
|
|
|
@ -85,7 +85,7 @@ CGAL_Poly2 nef2p2(CGAL_Nef_polyhedron2 p)
|
|||
typedef Explorer::Halfedge_around_face_const_circulator heafcc_t;
|
||||
Explorer E = p.explorer();
|
||||
|
||||
for (fci_t fit = E.faces_begin(), fend = E.faces_end(); fit != fend; ++fit)
|
||||
for (fci_t fit = E.faces_begin(), facesend = E.faces_end(); fit != facesend; ++fit)
|
||||
{
|
||||
if (!E.mark(fit)) {
|
||||
continue;
|
||||
|
|
|
@ -155,20 +155,6 @@ void export_off(CGAL_Nef_polyhedron*, QTextStream&, QProgressDialog*)
|
|||
void export_dxf(CGAL_Nef_polyhedron *root_N, QTextStream &output, QProgressDialog *)
|
||||
{
|
||||
setlocale(LC_NUMERIC, "C"); // Ensure radix is . (not ,) in output
|
||||
|
||||
// Some importers (e.g. QCAD) needs a HEADER section specifying AutoCAD 2000 as
|
||||
// the file format for LWPOLYLINE entities to work
|
||||
output << " 0\n"
|
||||
<< "SECTION\n"
|
||||
<< " 2\n"
|
||||
<< "HEADER\n"
|
||||
<< " 9\n"
|
||||
<< "$ACADVER\n"
|
||||
<< " 1\n"
|
||||
<< "AC1015\n"
|
||||
<< " 0\n"
|
||||
<< "ENDSEC\n";
|
||||
|
||||
// Some importers (e.g. Inkscape) needs a BLOCKS section to be present
|
||||
output << " 0\n"
|
||||
<< "SECTION\n"
|
||||
|
@ -184,27 +170,26 @@ void export_dxf(CGAL_Nef_polyhedron *root_N, QTextStream &output, QProgressDialo
|
|||
DxfData dd(*root_N);
|
||||
for (int i=0; i<dd.paths.size(); i++)
|
||||
{
|
||||
if (dd.paths[i].points.size() < 2) {
|
||||
// not a valid polygon
|
||||
continue;
|
||||
}
|
||||
// Use the LWPOLYLINE class - this makes it easier to handle complete
|
||||
// objects (as paths) in Inkscape.
|
||||
output << " 0\n"
|
||||
<< "LWPOLYLINE\n"
|
||||
<< " 8\n" // Some importers (e.g. Inkscape) need a layer to be specified
|
||||
<< "0\n"
|
||||
<< " 90\n" // number of vertices
|
||||
<< dd.paths[i].points.size() << "\n"
|
||||
<< " 70\n" // polygon flag (closed, ...)
|
||||
<< (dd.paths[i].is_closed ? 1 : 0) << "\n";
|
||||
// add all points
|
||||
for (int j=0; j<dd.paths[i].points.size(); j++) {
|
||||
DxfData::Point *p = dd.paths[i].points[j];
|
||||
output <<" 10\n"
|
||||
<< p->x << "\n"
|
||||
for (int j=1; j<dd.paths[i].points.size(); j++) {
|
||||
DxfData::Point *p1 = dd.paths[i].points[j-1];
|
||||
DxfData::Point *p2 = dd.paths[i].points[j];
|
||||
double x1 = p1->x;
|
||||
double y1 = p1->y;
|
||||
double x2 = p2->x;
|
||||
double y2 = p2->y;
|
||||
output << " 0\n"
|
||||
<< "LINE\n";
|
||||
// Some importers (e.g. Inkscape) needs a layer to be specified
|
||||
output << " 8\n"
|
||||
<< "0\n"
|
||||
<< " 10\n"
|
||||
<< x1 << "\n"
|
||||
<< " 11\n"
|
||||
<< x2 << "\n"
|
||||
<< " 20\n"
|
||||
<< p->y << "\n";
|
||||
<< y1 << "\n"
|
||||
<< " 21\n"
|
||||
<< y2 << "\n";
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -30,9 +30,15 @@
|
|||
|
||||
#include <QApplication>
|
||||
#include <QWheelEvent>
|
||||
#include <QCheckBox>
|
||||
#include <QDialogButtonBox>
|
||||
#include <QMouseEvent>
|
||||
#include <QMessageBox>
|
||||
#include <QPushButton>
|
||||
#include <QSettings>
|
||||
#include <QTimer>
|
||||
#include <QTextEdit>
|
||||
#include <QVBoxLayout>
|
||||
#include "mathc99.h"
|
||||
#include <stdio.h>
|
||||
|
||||
|
@ -191,7 +197,10 @@ void GLView::initializeGL()
|
|||
}
|
||||
} else {
|
||||
opencsg_support = false;
|
||||
QTimer::singleShot(0, this, SLOT(display_opengl20_warning()));
|
||||
QSettings settings;
|
||||
if (settings.value("editor/opengl20_warning_show",true).toBool()) {
|
||||
QTimer::singleShot(0, this, SLOT(display_opengl20_warning()));
|
||||
}
|
||||
}
|
||||
#endif /* ENABLE_OPENCSG */
|
||||
}
|
||||
|
@ -199,6 +208,9 @@ void GLView::initializeGL()
|
|||
#ifdef ENABLE_OPENCSG
|
||||
void GLView::display_opengl20_warning()
|
||||
{
|
||||
// data
|
||||
QString title = QString("GLEW: GL_VERSION_2_0 is not supported!");
|
||||
|
||||
QString rendererinfo;
|
||||
rendererinfo.sprintf("GLEW version %s\n"
|
||||
"%s (%s)\n"
|
||||
|
@ -207,11 +219,43 @@ void GLView::display_opengl20_warning()
|
|||
glGetString(GL_RENDERER), glGetString(GL_VENDOR),
|
||||
glGetString(GL_VERSION));
|
||||
|
||||
QMessageBox::warning(NULL, "GLEW: GL_VERSION_2_0 is not supported!",
|
||||
QString("Warning: No support for OpenGL 2.0 found! OpenCSG View has been disabled.\n\n"
|
||||
QString message = QString("Warning: No support for OpenGL 2.0 found! OpenCSG View has been disabled.\n\n"
|
||||
"It is highly recommended to use OpenSCAD on a system with OpenGL 2.0 "
|
||||
"support. Please check if OpenGL 2.0 drivers are available for your "
|
||||
"graphics hardware.\n\n%1").arg(rendererinfo));
|
||||
"graphics hardware. Your renderer information is as follows:\n\n%1").arg(rendererinfo);
|
||||
|
||||
QString note = QString("Uncheck to hide this message in the future");
|
||||
|
||||
// presentation
|
||||
QDialog *dialog = new QDialog(this);
|
||||
dialog->setSizeGripEnabled(true);
|
||||
dialog->setWindowTitle(title);
|
||||
dialog->resize(500,300);
|
||||
|
||||
QVBoxLayout *layout = new QVBoxLayout(dialog);
|
||||
dialog->setLayout(layout);
|
||||
|
||||
QTextEdit *textEdit = new QTextEdit(dialog);
|
||||
textEdit->setPlainText(message);
|
||||
layout->addWidget(textEdit);
|
||||
|
||||
QCheckBox *checkbox = new QCheckBox(note,dialog);
|
||||
checkbox->setCheckState(Qt::Checked);
|
||||
layout->addWidget(checkbox);
|
||||
|
||||
QDialogButtonBox *buttonbox =
|
||||
new QDialogButtonBox( QDialogButtonBox::Ok, Qt::Horizontal,dialog);
|
||||
layout->addWidget(buttonbox);
|
||||
buttonbox->button(QDialogButtonBox::Ok)->setFocus();
|
||||
buttonbox->button(QDialogButtonBox::Ok)->setDefault(true);
|
||||
|
||||
// action
|
||||
connect(buttonbox, SIGNAL(accepted()), dialog, SLOT(accept()));
|
||||
connect(checkbox, SIGNAL(clicked(bool)),
|
||||
Preferences::inst()->OpenGL20WarningCheckbox, SLOT(setChecked(bool)));
|
||||
connect(checkbox, SIGNAL(clicked(bool)),
|
||||
Preferences::inst(), SLOT(OpenGL20WarningChanged(bool)));
|
||||
dialog->exec();
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
127
src/mainwin.cc
127
src/mainwin.cc
|
@ -128,6 +128,37 @@ static char copyrighttext[] =
|
|||
"the Free Software Foundation; either version 2 of the License, or"
|
||||
"(at your option) any later version.";
|
||||
|
||||
static void
|
||||
settings_setValueList(const QString &key,const QList<int> &list)
|
||||
{
|
||||
QSettings settings;
|
||||
settings.beginWriteArray(key);
|
||||
for (int i=0;i<list.size(); ++i) {
|
||||
settings.setArrayIndex(i);
|
||||
settings.setValue("entry",list[i]);
|
||||
}
|
||||
settings.endArray();
|
||||
}
|
||||
|
||||
QList<int>
|
||||
settings_valueList(const QString &key, const QList<int> &defaultList = QList<int>())
|
||||
{
|
||||
QSettings settings;
|
||||
QList<int> result;
|
||||
if (settings.contains(key+"/size")){
|
||||
int length = settings.beginReadArray(key);
|
||||
for (int i = 0; i < length; ++i) {
|
||||
settings.setArrayIndex(i);
|
||||
result += settings.value("entry").toInt();
|
||||
}
|
||||
settings.endArray();
|
||||
return result;
|
||||
} else {
|
||||
return defaultList;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
MainWindow::MainWindow(const QString &filename)
|
||||
{
|
||||
setupUi(this);
|
||||
|
@ -271,6 +302,7 @@ MainWindow::MainWindow(const QString &filename)
|
|||
connect(this->designActionExportSTL, SIGNAL(triggered()), this, SLOT(actionExportSTL()));
|
||||
connect(this->designActionExportOFF, SIGNAL(triggered()), this, SLOT(actionExportOFF()));
|
||||
connect(this->designActionExportDXF, SIGNAL(triggered()), this, SLOT(actionExportDXF()));
|
||||
connect(this->designActionExportImage, SIGNAL(triggered()), this, SLOT(actionExportImage()));
|
||||
connect(this->designActionFlushCaches, SIGNAL(triggered()), this, SLOT(actionFlushCaches()));
|
||||
|
||||
// View menu
|
||||
|
@ -346,27 +378,69 @@ MainWindow::MainWindow(const QString &filename)
|
|||
this, SLOT(setFont(const QString&,uint)));
|
||||
Preferences::inst()->apply();
|
||||
|
||||
// make sure it looks nice..
|
||||
QSettings settings;
|
||||
resize(settings.value("window/size", QSize(800, 600)).toSize());
|
||||
move(settings.value("window/position", QPoint(0, 0)).toPoint());
|
||||
QList<int> s1sizes = settings_valueList("window/splitter1sizes",QList<int>()<<400<<400);
|
||||
QList<int> s2sizes = settings_valueList("window/splitter2sizes",QList<int>()<<400<<200);
|
||||
splitter1->setSizes(s1sizes);
|
||||
splitter2->setSizes(s2sizes);
|
||||
|
||||
// display this window and check for OpenGL 2.0 (OpenCSG) support
|
||||
viewModeThrownTogether();
|
||||
show();
|
||||
|
||||
// make sure it looks nice..
|
||||
resize(800, 600);
|
||||
splitter1->setSizes(QList<int>() << 400 << 400);
|
||||
splitter2->setSizes(QList<int>() << 400 << 200);
|
||||
|
||||
#ifdef ENABLE_OPENCSG
|
||||
viewModeOpenCSG();
|
||||
#else
|
||||
viewModeThrownTogether();
|
||||
#endif
|
||||
viewPerspective();
|
||||
loadViewSettings();
|
||||
loadDesignSettings();
|
||||
|
||||
setAcceptDrops(true);
|
||||
clearCurrentOutput();
|
||||
}
|
||||
|
||||
void
|
||||
MainWindow::loadViewSettings(){
|
||||
QSettings settings;
|
||||
if (settings.value("view/showEdges").toBool()) {
|
||||
viewActionShowEdges->setChecked(true);
|
||||
viewModeShowEdges();
|
||||
}
|
||||
if (settings.value("view/showAxes").toBool()) {
|
||||
viewActionShowAxes->setChecked(true);
|
||||
viewModeShowAxes();
|
||||
}
|
||||
if (settings.value("view/showCrosshairs").toBool()) {
|
||||
viewActionShowCrosshairs->setChecked(true);
|
||||
viewModeShowCrosshairs();
|
||||
}
|
||||
if (settings.value("view/orthogonalProjection").toBool()) {
|
||||
viewOrthogonal();
|
||||
} else {
|
||||
viewPerspective();
|
||||
}
|
||||
if (settings.value("view/hideConsole").toBool()) {
|
||||
viewActionHide->setChecked(true);
|
||||
hideConsole();
|
||||
}
|
||||
if (settings.value("view/hideEditor").toBool()) {
|
||||
editActionHide->setChecked(true);
|
||||
hideEditor();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
MainWindow::loadDesignSettings()
|
||||
{
|
||||
QSettings settings;
|
||||
if (settings.value("design/autoReload").toBool())
|
||||
designActionAutoReload->setChecked(true);
|
||||
}
|
||||
|
||||
MainWindow::~MainWindow()
|
||||
{
|
||||
if (root_module)
|
||||
|
@ -968,10 +1042,13 @@ void MainWindow::actionReload()
|
|||
|
||||
void MainWindow::hideEditor()
|
||||
{
|
||||
QSettings settings;
|
||||
if (editActionHide->isChecked()) {
|
||||
editor->hide();
|
||||
settings.setValue("view/hideEditor",true);
|
||||
} else {
|
||||
editor->show();
|
||||
settings.setValue("view/hideEditor",false);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1012,6 +1089,8 @@ void MainWindow::checkAutoReload()
|
|||
|
||||
void MainWindow::autoReloadSet(bool on)
|
||||
{
|
||||
QSettings settings;
|
||||
settings.setValue("design/autoReload",designActionAutoReload->isChecked());
|
||||
if (on) {
|
||||
autoReloadInfo = QString();
|
||||
autoReloadTimer->start(200);
|
||||
|
@ -1392,6 +1471,24 @@ void MainWindow::actionExportDXF()
|
|||
#endif /* ENABLE_CGAL */
|
||||
}
|
||||
|
||||
void MainWindow::actionExportImage()
|
||||
{
|
||||
QImage img = this->glview->grabFrameBuffer();
|
||||
setCurrentOutput();
|
||||
|
||||
QString img_filename = QFileDialog::getSaveFileName(this,
|
||||
"Export Image", "", "PNG Files (*.png)");
|
||||
if (img_filename.isEmpty()) {
|
||||
PRINTF("No filename specified. Image export aborted.");
|
||||
clearCurrentOutput();
|
||||
return;
|
||||
}
|
||||
|
||||
img.save(img_filename, "PNG");
|
||||
|
||||
clearCurrentOutput();
|
||||
}
|
||||
|
||||
void MainWindow::actionFlushCaches()
|
||||
{
|
||||
// FIXME: Polycache -> PolySetRenderer
|
||||
|
@ -1690,17 +1787,23 @@ void MainWindow::viewModeThrownTogether()
|
|||
|
||||
void MainWindow::viewModeShowEdges()
|
||||
{
|
||||
QSettings settings;
|
||||
settings.setValue("view/showEdges",viewActionShowEdges->isChecked());
|
||||
this->glview->updateGL();
|
||||
}
|
||||
|
||||
void MainWindow::viewModeShowAxes()
|
||||
{
|
||||
QSettings settings;
|
||||
settings.setValue("view/showAxes",viewActionShowAxes->isChecked());
|
||||
this->glview->setShowAxes(viewActionShowAxes->isChecked());
|
||||
this->glview->updateGL();
|
||||
}
|
||||
|
||||
void MainWindow::viewModeShowCrosshairs()
|
||||
{
|
||||
QSettings settings;
|
||||
settings.setValue("view/showCrosshairs",viewActionShowCrosshairs->isChecked());
|
||||
this->glview->setShowCrosshairs(viewActionShowCrosshairs->isChecked());
|
||||
this->glview->updateGL();
|
||||
}
|
||||
|
@ -1804,6 +1907,8 @@ void MainWindow::viewCenter()
|
|||
|
||||
void MainWindow::viewPerspective()
|
||||
{
|
||||
QSettings settings;
|
||||
settings.setValue("view/orthogonalProjection",false);
|
||||
viewActionPerspective->setChecked(true);
|
||||
viewActionOrthogonal->setChecked(false);
|
||||
this->glview->setOrthoMode(false);
|
||||
|
@ -1812,6 +1917,8 @@ void MainWindow::viewPerspective()
|
|||
|
||||
void MainWindow::viewOrthogonal()
|
||||
{
|
||||
QSettings settings;
|
||||
settings.setValue("view/orthogonalProjection",true);
|
||||
viewActionPerspective->setChecked(false);
|
||||
viewActionOrthogonal->setChecked(true);
|
||||
this->glview->setOrthoMode(true);
|
||||
|
@ -1820,10 +1927,13 @@ void MainWindow::viewOrthogonal()
|
|||
|
||||
void MainWindow::hideConsole()
|
||||
{
|
||||
QSettings settings;
|
||||
if (viewActionHide->isChecked()) {
|
||||
console->hide();
|
||||
settings.setValue("view/hideConsole",true);
|
||||
} else {
|
||||
console->show();
|
||||
settings.setValue("view/hideConsole",false);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1890,6 +2000,11 @@ MainWindow::maybeSave()
|
|||
void MainWindow::closeEvent(QCloseEvent *event)
|
||||
{
|
||||
if (maybeSave()) {
|
||||
QSettings settings;
|
||||
settings.setValue("window/size", size());
|
||||
settings.setValue("window/position", pos());
|
||||
settings_setValueList("window/splitter1sizes",splitter1->sizes());
|
||||
settings_setValueList("window/splitter2sizes",splitter2->sizes());
|
||||
event->accept();
|
||||
} else {
|
||||
event->ignore();
|
||||
|
|
|
@ -37,6 +37,8 @@
|
|||
#include <sstream>
|
||||
#include <assert.h>
|
||||
|
||||
#define F_MINIMUM 0.01
|
||||
|
||||
enum primitive_type_e {
|
||||
CUBE,
|
||||
SPHERE,
|
||||
|
@ -94,7 +96,6 @@ public:
|
|||
|
||||
bool center;
|
||||
double x, y, z, h, r1, r2;
|
||||
static const double F_MINIMUM = 0.01;
|
||||
double fn, fs, fa;
|
||||
primitive_type_e type;
|
||||
int convexity;
|
||||
|
@ -145,13 +146,13 @@ AbstractNode *PrimitiveModule::evaluate(const Context *ctx, const ModuleInstanti
|
|||
node->fs = c.lookup_variable("$fs").num;
|
||||
node->fa = c.lookup_variable("$fa").num;
|
||||
|
||||
if (node->fs < PrimitiveNode::F_MINIMUM) {
|
||||
PRINTF("WARNING: $fs too small - clamping to %f", PrimitiveNode::F_MINIMUM);
|
||||
node->fs = PrimitiveNode::F_MINIMUM;
|
||||
if (node->fs < F_MINIMUM) {
|
||||
PRINTF("WARNING: $fs too small - clamping to %f", F_MINIMUM);
|
||||
node->fs = F_MINIMUM;
|
||||
}
|
||||
if (node->fa < PrimitiveNode::F_MINIMUM) {
|
||||
PRINTF("WARNING: $fa too small - clamping to %f", PrimitiveNode::F_MINIMUM);
|
||||
node->fa = PrimitiveNode::F_MINIMUM;
|
||||
if (node->fa < F_MINIMUM) {
|
||||
PRINTF("WARNING: $fa too small - clamping to %f", F_MINIMUM);
|
||||
node->fa = F_MINIMUM;
|
||||
}
|
||||
|
||||
|
||||
|
@ -265,7 +266,7 @@ struct point2d {
|
|||
static void generate_circle(point2d *circle, double r, int fragments)
|
||||
{
|
||||
for (int i=0; i<fragments; i++) {
|
||||
double phi = (M_PI*2* (i + 0.5)) / fragments;
|
||||
double phi = (M_PI*2*i) / fragments;
|
||||
circle[i].x = r*cos(phi);
|
||||
circle[i].y = r*sin(phi);
|
||||
}
|
||||
|
|
|
@ -35,6 +35,7 @@
|
|||
#include "printutils.h"
|
||||
#include "visitor.h"
|
||||
#include <sstream>
|
||||
#include <vector>
|
||||
#include <assert.h>
|
||||
|
||||
enum transform_type_e {
|
||||
|
@ -54,6 +55,31 @@ public:
|
|||
virtual AbstractNode *evaluate(const Context *ctx, const ModuleInstantiation *inst) const;
|
||||
};
|
||||
|
||||
using std::string;
|
||||
using std::vector;
|
||||
|
||||
static vector<string> split(const string &str, const string &delim)
|
||||
{
|
||||
assert(delim.size() > 0);
|
||||
|
||||
vector<string> strvec;
|
||||
size_t start = 0, end = 0;
|
||||
while (end != string::npos) {
|
||||
end = str.find(delim, start);
|
||||
// If at end, use length=maxLength. Else use length=end-start.
|
||||
strvec.push_back(str.substr(start, (end == string::npos) ? string::npos : end - start));
|
||||
// If at end, use start=maxSize. Else use start=end+delimiter.
|
||||
start = ((end > (string::npos - delim.size())) ? string::npos : end + delim.size());
|
||||
}
|
||||
return strvec;
|
||||
}
|
||||
|
||||
template <class T> static bool from_string(T &t, const string &s)
|
||||
{
|
||||
std::istringstream iss(s);
|
||||
return !(iss >> t).fail();
|
||||
}
|
||||
|
||||
AbstractNode *TransformModule::evaluate(const Context *ctx, const ModuleInstantiation *inst) const
|
||||
{
|
||||
TransformNode *node = new TransformNode(inst);
|
||||
|
@ -222,6 +248,25 @@ AbstractNode *TransformModule::evaluate(const Context *ctx, const ModuleInstanti
|
|||
if (v.type == Value::VECTOR) {
|
||||
for (int i = 0; i < 4; i++)
|
||||
node->matrix[16+i] = i < v.vec.size() ? v.vec[i]->num : 1.0;
|
||||
// FIXME: Port to non-Qt
|
||||
#if 0
|
||||
} else if (v.type == Value::STRING) {
|
||||
double alpha = 1.0;
|
||||
vector<string> chunks = split(v.text, ",");
|
||||
string colorname = chunks[0];
|
||||
if (chunks.size() < 2 || !from_string(alpha, chunks[1])) alpha = 1.0;
|
||||
QColor color;
|
||||
color.setNamedColor(colorname);
|
||||
if (color.isValid()) {
|
||||
node->m[16+0] = color.redF();
|
||||
node->m[16+1] = color.greenF();
|
||||
node->m[16+2] = color.blueF();
|
||||
node->m[16+3] = alpha;
|
||||
} else {
|
||||
PRINTF_NOCACHE("WARNING: Color name \"%s\" unknown. Please see",v.text.toUtf8().data());
|
||||
PRINTF_NOCACHE("WARNING: http://en.wikipedia.org/wiki/Web_colors");
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -234,7 +279,7 @@ AbstractNode *TransformModule::evaluate(const Context *ctx, const ModuleInstanti
|
|||
return node;
|
||||
}
|
||||
|
||||
std::string TransformNode::toString() const
|
||||
string TransformNode::toString() const
|
||||
{
|
||||
std::stringstream stream;
|
||||
|
||||
|
@ -259,7 +304,7 @@ std::string TransformNode::toString() const
|
|||
return stream.str();
|
||||
}
|
||||
|
||||
std::string TransformNode::name() const
|
||||
string TransformNode::name() const
|
||||
{
|
||||
return "transform";
|
||||
}
|
||||
|
|
|
@ -0,0 +1,6 @@
|
|||
multmatrix(m = [[1, 0, 0, 0],
|
||||
[0, 1, 0, 0],
|
||||
[0, 0, 1, 0],
|
||||
[0, 0, -0.02, 1]])
|
||||
linear_extrude(height=20) circle(r=10);
|
||||
|
|
@ -0,0 +1,159 @@
|
|||
/* color samples for SVG named colors, for OpenSCAD
|
||||
Please see http://en.wikipedia.org/wiki/Web_colors
|
||||
and http://www.w3.org/TR/SVG/types.html#ColorKeywords
|
||||
for more information. */
|
||||
|
||||
$fn=5;
|
||||
radius=0.8;
|
||||
//translate([0,0]) color("Red colors") sphere(radius);
|
||||
translate([1,0]) color("IndianRed") sphere(radius);
|
||||
translate([2,0]) color("LightCoral") sphere(radius);
|
||||
translate([3,0]) color("Salmon") sphere(radius);
|
||||
translate([4,0]) color("DarkSalmon") sphere(radius);
|
||||
translate([5,0]) color("LightSalmon") sphere(radius);
|
||||
translate([6,0]) color("Red") sphere(radius);
|
||||
translate([7,0]) color("Crimson") sphere(radius);
|
||||
translate([8,0]) color("FireBrick") sphere(radius);
|
||||
translate([9,0]) color("DarkRed") sphere(radius);
|
||||
//translate([10,0]) color("Pink colors") sphere(radius);
|
||||
translate([0,1]) color("Pink") sphere(radius);
|
||||
translate([1,1]) color("LightPink") sphere(radius);
|
||||
translate([2,1]) color("HotPink") sphere(radius);
|
||||
translate([3,1]) color("DeepPink") sphere(radius);
|
||||
translate([4,1]) color("MediumVioletRed") sphere(radius);
|
||||
translate([5,1]) color("PaleVioletRed") sphere(radius);
|
||||
//translate([6,1]) color("Orange colors") sphere(radius);
|
||||
translate([7,1]) color("LightSalmon") sphere(radius);
|
||||
translate([8,1]) color("Coral") sphere(radius);
|
||||
translate([9,1]) color("Tomato") sphere(radius);
|
||||
translate([10,1]) color("OrangeRed") sphere(radius);
|
||||
translate([0,2]) color("DarkOrange") sphere(radius);
|
||||
translate([1,2]) color("Orange") sphere(radius);
|
||||
//translate([2,2]) color("Yellow colors") sphere(radius);
|
||||
translate([3,2]) color("Gold") sphere(radius);
|
||||
translate([4,2]) color("Yellow") sphere(radius);
|
||||
translate([5,2]) color("LightYellow") sphere(radius);
|
||||
translate([6,2]) color("LemonChiffon") sphere(radius);
|
||||
translate([7,2]) color("LightGoldenrodYellow") sphere(radius);
|
||||
translate([8,2]) color("PapayaWhip") sphere(radius);
|
||||
translate([9,2]) color("Moccasin") sphere(radius);
|
||||
translate([10,2]) color("PeachPuff") sphere(radius);
|
||||
translate([0,3]) color("PaleGoldenrod") sphere(radius);
|
||||
translate([1,3]) color("Khaki") sphere(radius);
|
||||
translate([2,3]) color("DarkKhaki") sphere(radius);
|
||||
//translate([3,3]) color("Purple colors") sphere(radius);
|
||||
translate([4,3]) color("Lavender") sphere(radius);
|
||||
translate([5,3]) color("Thistle") sphere(radius);
|
||||
translate([6,3]) color("Plum") sphere(radius);
|
||||
translate([7,3]) color("Violet") sphere(radius);
|
||||
translate([8,3]) color("Orchid") sphere(radius);
|
||||
translate([9,3]) color("Fuchsia") sphere(radius);
|
||||
translate([10,3]) color("Magenta") sphere(radius);
|
||||
translate([0,4]) color("MediumOrchid") sphere(radius);
|
||||
translate([1,4]) color("MediumPurple") sphere(radius);
|
||||
translate([2,4]) color("BlueViolet") sphere(radius);
|
||||
translate([3,4]) color("DarkViolet") sphere(radius);
|
||||
translate([4,4]) color("DarkOrchid") sphere(radius);
|
||||
translate([5,4]) color("DarkMagenta") sphere(radius);
|
||||
translate([6,4]) color("Purple") sphere(radius);
|
||||
translate([7,4]) color("Indigo") sphere(radius);
|
||||
translate([8,4]) color("DarkSlateBlue") sphere(radius);
|
||||
translate([9,4]) color("SlateBlue") sphere(radius);
|
||||
translate([10,4]) color("MediumSlateBlue") sphere(radius);
|
||||
//translate([0,5]) color("Green colors") sphere(radius);
|
||||
translate([1,5]) color("GreenYellow") sphere(radius);
|
||||
translate([2,5]) color("Chartreuse") sphere(radius);
|
||||
translate([3,5]) color("LawnGreen") sphere(radius);
|
||||
translate([4,5]) color("Lime") sphere(radius);
|
||||
translate([5,5]) color("LimeGreen") sphere(radius);
|
||||
translate([6,5]) color("PaleGreen") sphere(radius);
|
||||
translate([7,5]) color("LightGreen") sphere(radius);
|
||||
translate([8,5]) color("MediumSpringGreen") sphere(radius);
|
||||
translate([9,5]) color("SpringGreen") sphere(radius);
|
||||
translate([10,5]) color("MediumSeaGreen") sphere(radius);
|
||||
translate([0,6]) color("SeaGreen") sphere(radius);
|
||||
translate([1,6]) color("ForestGreen") sphere(radius);
|
||||
translate([2,6]) color("Green") sphere(radius);
|
||||
translate([3,6]) color("DarkGreen") sphere(radius);
|
||||
translate([4,6]) color("YellowGreen") sphere(radius);
|
||||
translate([5,6]) color("OliveDrab") sphere(radius);
|
||||
translate([6,6]) color("Olive") sphere(radius);
|
||||
translate([7,6]) color("DarkOliveGreen") sphere(radius);
|
||||
translate([8,6]) color("MediumAquamarine") sphere(radius);
|
||||
translate([9,6]) color("DarkSeaGreen") sphere(radius);
|
||||
translate([10,6]) color("LightSeaGreen") sphere(radius);
|
||||
translate([0,7]) color("DarkCyan") sphere(radius);
|
||||
translate([1,7]) color("Teal") sphere(radius);
|
||||
//translate([2,7]) color("Blue/Cyan colors") sphere(radius);
|
||||
translate([3,7]) color("Aqua") sphere(radius);
|
||||
translate([4,7]) color("Cyan") sphere(radius);
|
||||
translate([5,7]) color("LightCyan") sphere(radius);
|
||||
translate([6,7]) color("PaleTurquoise") sphere(radius);
|
||||
translate([7,7]) color("Aquamarine") sphere(radius);
|
||||
translate([8,7]) color("Turquoise") sphere(radius);
|
||||
translate([9,7]) color("MediumTurquoise") sphere(radius);
|
||||
translate([10,7]) color("DarkTurquoise") sphere(radius);
|
||||
translate([0,8]) color("CadetBlue") sphere(radius);
|
||||
translate([1,8]) color("SteelBlue") sphere(radius);
|
||||
translate([2,8]) color("LightSteelBlue") sphere(radius);
|
||||
translate([3,8]) color("PowderBlue") sphere(radius);
|
||||
translate([4,8]) color("LightBlue") sphere(radius);
|
||||
translate([5,8]) color("SkyBlue") sphere(radius);
|
||||
translate([6,8]) color("LightSkyBlue") sphere(radius);
|
||||
translate([7,8]) color("DeepSkyBlue") sphere(radius);
|
||||
translate([8,8]) color("DodgerBlue") sphere(radius);
|
||||
translate([9,8]) color("CornflowerBlue") sphere(radius);
|
||||
translate([10,8]) color("RoyalBlue") sphere(radius);
|
||||
translate([0,9]) color("Blue") sphere(radius);
|
||||
translate([1,9]) color("MediumBlue") sphere(radius);
|
||||
translate([2,9]) color("DarkBlue") sphere(radius);
|
||||
translate([3,9]) color("Navy") sphere(radius);
|
||||
translate([4,9]) color("MidnightBlue") sphere(radius);
|
||||
//translate([5,9]) color("Brown colors") sphere(radius);
|
||||
translate([6,9]) color("Cornsilk") sphere(radius);
|
||||
translate([7,9]) color("BlanchedAlmond") sphere(radius);
|
||||
translate([8,9]) color("Bisque") sphere(radius);
|
||||
translate([9,9]) color("NavajoWhite") sphere(radius);
|
||||
translate([10,9]) color("Wheat") sphere(radius);
|
||||
translate([0,10]) color("BurlyWood") sphere(radius);
|
||||
translate([1,10]) color("Tan") sphere(radius);
|
||||
translate([2,10]) color("RosyBrown") sphere(radius);
|
||||
translate([3,10]) color("SandyBrown") sphere(radius);
|
||||
translate([4,10]) color("Goldenrod") sphere(radius);
|
||||
translate([5,10]) color("DarkGoldenrod") sphere(radius);
|
||||
translate([6,10]) color("Peru") sphere(radius);
|
||||
translate([7,10]) color("Chocolate") sphere(radius);
|
||||
translate([8,10]) color("SaddleBrown") sphere(radius);
|
||||
translate([9,10]) color("Sienna") sphere(radius);
|
||||
translate([10,10]) color("Brown") sphere(radius);
|
||||
translate([0,11]) color("Maroon") sphere(radius);
|
||||
//translate([1,11]) color("White colors") sphere(radius);
|
||||
translate([2,11]) color("White") sphere(radius);
|
||||
translate([3,11]) color("Snow") sphere(radius);
|
||||
translate([4,11]) color("Honeydew") sphere(radius);
|
||||
translate([5,11]) color("MintCream") sphere(radius);
|
||||
translate([6,11]) color("Azure") sphere(radius);
|
||||
translate([7,11]) color("AliceBlue") sphere(radius);
|
||||
translate([8,11]) color("GhostWhite") sphere(radius);
|
||||
translate([9,11]) color("WhiteSmoke") sphere(radius);
|
||||
translate([10,11]) color("Seashell") sphere(radius);
|
||||
translate([0,12]) color("Beige") sphere(radius);
|
||||
translate([1,12]) color("OldLace") sphere(radius);
|
||||
translate([2,12]) color("FloralWhite") sphere(radius);
|
||||
translate([3,12]) color("Ivory") sphere(radius);
|
||||
translate([4,12]) color("AntiqueWhite") sphere(radius);
|
||||
translate([5,12]) color("Linen") sphere(radius);
|
||||
translate([6,12]) color("LavenderBlush") sphere(radius);
|
||||
translate([7,12]) color("MistyRose") sphere(radius);
|
||||
//translate([8,12]) color("Gray colors") sphere(radius);
|
||||
translate([9,12]) color("Gainsboro") sphere(radius);
|
||||
translate([10,12]) color("LightGrey") sphere(radius);
|
||||
translate([0,13]) color("Silver") sphere(radius);
|
||||
translate([1,13]) color("DarkGray") sphere(radius);
|
||||
translate([2,13]) color("Gray") sphere(radius);
|
||||
translate([3,13]) color("DimGray") sphere(radius);
|
||||
translate([4,13]) color("LightSlateGray") sphere(radius);
|
||||
translate([5,13]) color("SlateGray") sphere(radius);
|
||||
translate([6,13]) color("DarkSlateGray") sphere(radius);
|
||||
translate([7,13]) color("Black") sphere(radius);
|
||||
|
Loading…
Reference in New Issue