Merge branch 'master' into translation2

master
Torsten Paul 2014-11-12 23:21:42 +01:00
commit 59c4dec623
87 changed files with 1497 additions and 722 deletions

View File

@ -0,0 +1,31 @@
{
"name" : "For Dark Background",
"index" : 1100,
"paper" : "#272822",
"text" : "#ffffff",
"caret" : {
"width" : 2,
"foreground" : "#ffff00",
"line-background" : "#68e1687f"
},
"colors" : {
"keyword1" : "#f12971",
"keyword2" : "#56dbf0",
"keyword3" : "#56d8f0",
"comment" : "#ccdf32",
"number" : "#af7dff",
"string" : "#e6db74",
"operator" : "#d8d8d8",
"commentline" : "#e6db74",
"selection-foreground" : "#ffff00",
"selection-background" : "#a0a0ff",
"margin-background" : "#14141496",
"margin-foreground" : "#fff",
"matched-brace-background" : "#333",
"matched-brace-foreground" : "#fff",
"unmatched-brace-background" : "#333",
"unmatched-brace-foreground" : "#fff",
"error-marker" : "#ff0000",
"edge" : "#ffffff"
}
}

View File

@ -0,0 +1,31 @@
{
"name" : "For Light Background",
"index" : 1000,
"paper" : "#fff",
"text" : "#272822",
"caret" : {
"width" : 2,
"foreground" : "#000000",
"line-background" : "#ffe4e4"
},
"colors" : {
"keyword1" : "Green",
"keyword2" : "Green",
"keyword3" : "DarkBlue",
"comment" : "DarkCyan",
"number" : "DarkRed",
"string" : "DarkMagenta",
"operator" : "Blue",
"commentline" : "DarkCyan",
"selection-foreground" : "#ffff00",
"selection-background" : "#a0a0ff",
"margin-background" : "#ccc",
"margin-foreground" : "#111",
"matched-brace-background" : "#333",
"matched-brace-foreground" : "#fff",
"unmatched-brace-background" : "#333",
"unmatched-brace-foreground" : "#fff",
"error-marker" : "#ff0000",
"edge" : "#ffffff"
}
}

View File

@ -0,0 +1,31 @@
{
"name" : "Monokai",
"index" : 1200,
"paper" : "#272822",
"text" : "#f8f8f2",
"caret" : {
"width" : 2,
"foreground" : "#ffff00",
"line-background" : "#3e3d32"
},
"colors" : {
"keyword1" : "#66c3b3",
"keyword2" : "#79abff",
"keyword3" : "#ffffff",
"comment" : "#ccdf32",
"number" : "#7fb347",
"string" : "#e6db74",
"operator" : "#d8d8d8",
"commentline" : "#75715e",
"selection-foreground" : "#ffff00",
"selection-background" : "#a0a0ff",
"margin-background" : "#757575",
"margin-foreground" : "#f8f8f2",
"matched-brace-background" : "#333",
"matched-brace-foreground" : "#fff",
"unmatched-brace-background" : "#333",
"unmatched-brace-foreground" : "#fff",
"error-marker" : "#ff0000",
"edge" : "#ffffff"
}
}

View File

@ -0,0 +1,31 @@
{
"name" : "Solarized",
"index" : 1300,
"paper" : "#fdf6e3",
"text" : "#657b83",
"caret" : {
"width" : 2,
"foreground" : "#0000ff",
"line-background" : "#eeead5"
},
"colors" : {
"keyword1" : "#268ad1",
"keyword2" : "#6c71c4",
"keyword3" : "#b58800",
"comment" : "#b58900",
"number" : "#cb4b16",
"string" : "#2aa198",
"operator" : "#859900",
"commentline" : "#b58800",
"selection-foreground" : "#fdf6e3",
"selection-background" : "#657b83",
"margin-background" : "#eee8d5",
"margin-foreground" : "#93a1a1",
"matched-brace-background" : "#333",
"matched-brace-foreground" : "#fff",
"unmatched-brace-background" : "#333",
"unmatched-brace-foreground" : "#fff",
"error-marker" : "#ff0000",
"edge" : "#ffffff"
}
}

View File

@ -0,0 +1,18 @@
{
"name" : "BeforeDawn",
"index" : 1400,
"show-in-gui" : true,
"colors" : {
"background" : "#333333",
"opencsg-face-front" : "#cccccc",
"opencsg-face-back" : "#5563dd",
"cgal-face-front" : "#cccccc",
"cgal-face-back" : "#5563dd",
"cgal-face-2d" : "#00bf99",
"cgal-edge-front" : "#ff0000",
"cgal-edge-back" : "#ff0000",
"cgal-edge-2d" : "#ff0000",
"crosshair" : "#f0f0f0"
}
}

View File

@ -0,0 +1,18 @@
{
"name" : "DeepOcean",
"index" : 1600,
"show-in-gui" : true,
"colors" : {
"background" : "#333333",
"opencsg-face-front" : "#eeeeee",
"opencsg-face-back" : "#0babc8",
"cgal-face-front" : "#eeeeee",
"cgal-face-back" : "#0babc8",
"cgal-face-2d" : "#9370db",
"cgal-edge-front" : "#0000ff",
"cgal-edge-back" : "#0000ff",
"cgal-edge-2d" : "#ff00ff",
"crosshair" : "#f0f0f0"
}
}

View File

@ -0,0 +1,18 @@
{
"name" : "Metallic",
"index" : 1100,
"show-in-gui" : true,
"colors" : {
"background" : "#aaaaff",
"opencsg-face-front" : "#ddddff",
"opencsg-face-back" : "#dd22dd",
"cgal-face-front" : "#ddddff",
"cgal-face-back" : "#dd22dd",
"cgal-face-2d" : "#00bf99",
"cgal-edge-front" : "#ff0000",
"cgal-edge-back" : "#ff0000",
"cgal-edge-2d" : "#ff0000",
"crosshair" : "#800000"
}
}

View File

@ -0,0 +1,19 @@
{
"name" : "Monotone",
"index" : 9999,
"show-in-gui" : false,
"description" : "Color scheme with no difference between 'back face' and 'front face'",
"colors" : {
"background" : "#ffffe5",
"opencsg-face-front" : "#f9d72c",
"opencsg-face-back" : "#f9d72c",
"cgal-face-front" : "#f9d72c",
"cgal-face-back" : "#f9d72c",
"cgal-face-2d" : "#00bf99",
"cgal-edge-front" : "#ff0000",
"cgal-edge-back" : "#ff0000",
"cgal-edge-2d" : "#ff0000",
"crosshair" : "#800000"
}
}

View File

@ -0,0 +1,18 @@
{
"name" : "Nature",
"index" : 1500,
"show-in-gui" : true,
"colors" : {
"background" : "#fafafa",
"opencsg-face-front" : "#16a085",
"opencsg-face-back" : "#dbf4da",
"cgal-face-front" : "#16a085",
"cgal-face-back" : "#dbf4da",
"cgal-face-2d" : "#00bf99",
"cgal-edge-front" : "#ff0000",
"cgal-edge-back" : "#ff0000",
"cgal-edge-2d" : "#ff0000",
"crosshair" : "#111111"
}
}

View File

@ -0,0 +1,18 @@
{
"name" : "Solarized",
"index" : 1700,
"show-in-gui" : true,
"colors" : {
"background" : "#fdf6e3",
"opencsg-face-front" : "#b58800",
"opencsg-face-back" : "#882233",
"cgal-face-front" : "#b58800",
"cgal-face-back" : "#882233",
"cgal-face-2d" : "#6c71c4",
"cgal-edge-front" : "#b58800",
"cgal-edge-back" : "#b58800",
"cgal-edge-2d" : "#b58800",
"crosshair" : "#800000"
}
}

View File

@ -0,0 +1,18 @@
{
"name" : "Starnight",
"index" : 1300,
"show-in-gui" : true,
"colors" : {
"background" : "#000000",
"opencsg-face-front" : "#ffffe0",
"opencsg-face-back" : "#00ffff",
"cgal-face-front" : "#ffffe0",
"cgal-face-back" : "#00ffff",
"cgal-face-2d" : "#9370db",
"cgal-edge-front" : "#0000ff",
"cgal-edge-back" : "#0000ff",
"cgal-edge-2d" : "#ff00ff",
"crosshair" : "#f0f0f0"
}
}

View File

@ -0,0 +1,18 @@
{
"name" : "Sunset",
"index" : 1200,
"show-in-gui" : true,
"colors" : {
"background" : "#aa4444",
"opencsg-face-front" : "#ffaaaa",
"opencsg-face-back" : "#882233",
"cgal-face-front" : "#ffaaaa",
"cgal-face-back" : "#882233",
"cgal-face-2d" : "#00bf99",
"cgal-edge-front" : "#ff0000",
"cgal-edge-back" : "#ff0000",
"cgal-edge-2d" : "#ff0000",
"crosshair" : "#800000"
}
}

View File

@ -329,6 +329,7 @@ src/FontCache.h \
src/system-gl.h \
src/CsgInfo.h \
\
src/Dock.h \
src/AutoUpdater.h \
src/launchingscreen.h \
src/legacyeditor.h \
@ -419,6 +420,7 @@ SOURCES += src/version_check.cc \
src/openscad.cc \
src/mainwin.cc \
src/UIUtils.cc \
src/Dock.cc \
src/FontListDialog.cc \
src/launchingscreen.cc \
src/legacyeditor.cc \
@ -521,6 +523,10 @@ fonts.path = $$PREFIX/share/openscad/fonts/
fonts.files = fonts/*
INSTALLS += fonts
colorschemes.path = $$PREFIX/share/openscad/color-schemes/
colorschemes.files = color-schemes/*
INSTALLS += colorschemes
applications.path = $$PREFIX/share/applications
applications.files = icons/openscad.desktop
INSTALLS += applications

View File

@ -14,6 +14,7 @@ File /r /x mingw-cross-env examples
File /r /x mingw-cross-env libraries
File /r /x mingw-cross-env fonts
File /r /x mingw-cross-env locale
File /r /x mingw-cross-env color-schemes
${registerExtension} "$INSTDIR\openscad.exe" ".scad" "OpenSCAD_File"
CreateShortCut $SMPROGRAMS\OpenSCAD.lnk $INSTDIR\openscad.exe
WriteUninstaller $INSTDIR\Uninstall.exe
@ -28,6 +29,7 @@ Delete $INSTDIR\MyProg.exe
Delete $SMPROGRAMS\OpenSCAD.lnk
DeleteRegKey HKEY_LOCAL_MACHINE "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\OpenSCAD"
RMDir /r $INSTDIR\fonts
RMDir /r $INSTDIR\color-schemes
RMDir /r $INSTDIR\examples
RMDir /r $INSTDIR\libraries\mcad
RMDir /r $INSTDIR\locale

View File

@ -356,8 +356,9 @@ build_cgal()
cd $BASEDIR/src
rm -rf CGAL-$version
if [ ! -f CGAL-$version.tar.gz ]; then
# 4.4
curl -O https://gforge.inria.fr/frs/download.php/file/33525/CGAL-$version.tar.gz
# 4.5
curl -O https://gforge.inria.fr/frs/download.php/file/34149/CGAL-$version.tar.gz
# 4.4 curl -O https://gforge.inria.fr/frs/download.php/file/33525/CGAL-$version.tar.gz
# 4.3 curl -O https://gforge.inria.fr/frs/download.php/32994/CGAL-$version.tar.gz
# 4.2 curl -O https://gforge.inria.fr/frs/download.php/32359/CGAL-$version.tar.gz
# 4.1 curl -O https://gforge.inria.fr/frs/download.php/31641/CGAL-$version.tar.gz
@ -426,7 +427,7 @@ build_opencsg()
if $OPTION_32BIT; then
OPENCSG_EXTRA_FLAGS="x86"
fi
qmake -r QMAKE_CXXFLAGS+="-I$DEPLOYDIR/include" QMAKE_LFLAGS+="-L$DEPLOYDIR/lib" CONFIG+="x86_64 $OPENCSG_EXTRA_FLAGS"
qmake -r QMAKE_CXXFLAGS+="-I$DEPLOYDIR/include" QMAKE_LFLAGS+="-L$DEPLOYDIR/lib" CONFIG+="x86_64 $OPENCSG_EXTRA_FLAGS" DESTDIR=$DEPLOYDIR
make install
}
@ -654,7 +655,7 @@ build_ragel()
cd "$BASEDIR"/src
rm -rf "ragel-$version"
if [ ! -f "ragel-$version.tar.gz" ]; then
curl --insecure -LO "http://www.complang.org/ragel/ragel-$version.tar.gz"
curl --insecure -LO "http://www.colm.net/wp-content/uploads/2014/10/ragel-$version.tar.gz"
fi
tar xzf "ragel-$version.tar.gz"
cd "ragel-$version"
@ -770,22 +771,22 @@ fi
echo "Using basedir:" $BASEDIR
mkdir -p $SRCDIR $DEPLOYDIR
build_qt5 5.3.1
build_qscintilla 2.8.3
build_qscintilla 2.8.4
# NB! For eigen, also update the path in the function
build_eigen 3.2.1
build_gmp 5.1.3
build_mpfr 3.1.2
build_boost 1.54.0
# NB! For CGAL, also update the actual download URL in the function
build_cgal 4.4
build_cgal 4.5
build_glew 1.10.0
build_gettext 0.18.3.2
build_libffi 3.1
build_glib2 2.40.0
build_opencsg 1.4.0
build_freetype 2.5.3 --without-png
build_ragel 6.8
build_harfbuzz 0.9.28 "--with-coretext=auto --with-glib=no"
build_ragel 6.9
build_harfbuzz 0.9.35 "--with-coretext=auto --with-glib=no"
export FREETYPE_CFLAGS="-I$DEPLOYDIR/include -I$DEPLOYDIR/include/freetype2"
export FREETYPE_LIBS="-L$DEPLOYDIR/lib -lfreetype"
build_libxml2 2.9.1

View File

@ -2,6 +2,11 @@
# NB! To build a release build, the VERSION and VERSIONDATE environment variables needs to be set.
# See doc/release-checklist.txt
#
# Usage:
# ./scripts/publish-macosx.sh [buildonly]
#
export NUMCPU=$(sysctl -n hw.ncpu)
human_filesize()
@ -40,6 +45,13 @@ update_www_download_links()
fi
}
# Cmd-line parameters
DOUPLOAD=1
if [ "`echo $* | grep buildonly`" ]; then
echo "Build only, no upload"
DOUPLOAD=
fi
if test -z "$VERSIONDATE"; then
VERSIONDATE=`date "+%Y.%m.%d"`
fi
@ -76,6 +88,10 @@ if [[ $? != 0 ]]; then
exit 1
fi
if [ ! $DOUPLOAD ]; then
exit 0
fi
SIGNATURE=$(openssl dgst -sha1 -binary < OpenSCAD-$VERSION.dmg | openssl dgst -dss1 -sign $HOME/.ssh/openscad-appcast.pem | openssl enc -base64)
if [[ $VERSION == $VERSIONDATE ]]; then

View File

@ -327,6 +327,7 @@ case $OS in
LIBRARYDIR=OpenSCAD.app/Contents/Resources/libraries
FONTDIR=OpenSCAD.app/Contents/Resources/fonts
TRANSLATIONDIR=OpenSCAD.app/Contents/Resources/locale
COLORSCHEMESDIR=OpenSCAD.app/Contents/Resources/color-schemes
;;
UNIX_CROSS_WIN)
cd $OPENSCADDIR
@ -334,6 +335,7 @@ case $OS in
LIBRARYDIR=$DEPLOYDIR/openscad-$VERSION/libraries/
FONTDIR=$DEPLOYDIR/openscad-$VERSION/fonts/
TRANSLATIONDIR=$DEPLOYDIR/openscad-$VERSION/locale/
COLORSCHEMESDIR=$DEPLOYDIR/openscad-$VERSION/color-schemes/
rm -rf $DEPLOYDIR/openscad-$VERSION
mkdir $DEPLOYDIR/openscad-$VERSION
;;
@ -342,6 +344,7 @@ case $OS in
LIBRARYDIR=openscad-$VERSION/libraries/
FONTDIR=openscad-$VERSION/fonts/
TRANSLATIONDIR=openscad-$VERSION/locale/
COLORSCHEMESDIR=openscad-$VERSION/color-schemes/
rm -rf openscad-$VERSION
mkdir openscad-$VERSION
;;
@ -369,6 +372,11 @@ if [ -n $FONTDIR ]; then
;;
esac
fi
if [ -n $COLORSCHEMESDIR ]; then
echo $COLORSCHEMESDIR
mkdir -p $COLORSCHEMESDIR
cp -a color-schemes/* $COLORSCHEMESDIR
fi
if [ -n $LIBRARYDIR ]; then
echo $LIBRARYDIR
mkdir -p $LIBRARYDIR

View File

@ -113,8 +113,10 @@ Response CSGTermEvaluator::visit(State &state, const AbstractPolyNode &node)
shared_ptr<CSGTerm> t1;
if (this->geomevaluator) {
shared_ptr<const Geometry> geom = this->geomevaluator->evaluateGeometry(node, false);
t1 = evaluate_csg_term_from_geometry(state, this->highlights, this->background,
geom, node.modinst, node);
if (geom) {
t1 = evaluate_csg_term_from_geometry(state, this->highlights, this->background,
geom, node.modinst, node);
}
node.progress_report();
}
this->stored_term[node.index()] = t1;
@ -178,8 +180,10 @@ Response CSGTermEvaluator::visit(State &state, const RenderNode &node)
shared_ptr<const Geometry> geom;
if (this->geomevaluator) {
geom = this->geomevaluator->evaluateGeometry(node, false);
t1 = evaluate_csg_term_from_geometry(state, this->highlights, this->background,
geom, node.modinst, node);
if (geom) {
t1 = evaluate_csg_term_from_geometry(state, this->highlights, this->background,
geom, node.modinst, node);
}
node.progress_report();
}
this->stored_term[node.index()] = t1;
@ -196,8 +200,10 @@ Response CSGTermEvaluator::visit(State &state, const CgaladvNode &node)
shared_ptr<const Geometry> geom;
if (this->geomevaluator) {
geom = this->geomevaluator->evaluateGeometry(node, false);
t1 = evaluate_csg_term_from_geometry(state, this->highlights, this->background,
geom, node.modinst, node);
if (geom) {
t1 = evaluate_csg_term_from_geometry(state, this->highlights, this->background,
geom, node.modinst, node);
}
node.progress_report();
}
this->stored_term[node.index()] = t1;

View File

@ -43,8 +43,8 @@ public:
CSGTermEvaluator evaluator(tree, &geomevaluator);
boost::shared_ptr<CSGTerm> root_raw_term = evaluator.evaluateCSGTerm( *root_node, this->highlight_terms, this->background_terms );
if (!root_raw_term) {
PRINT("Error: CSG generation failed! (no top level object found)");
if (!root_raw_term && this->background_terms.empty()) {
PRINT("Error: CSG generation failed! (no objects found)");
call_progress_function();
return false;
}
@ -52,16 +52,18 @@ public:
PRINT("Compiling design (CSG Products normalization)...");
call_progress_function();
CSGTermNormalizer normalizer( normalizelimit );
this->root_norm_term = normalizer.normalize(root_raw_term);
if (this->root_norm_term) {
this->root_chain = new CSGChain();
this->root_chain->import(this->root_norm_term);
PRINTB("Normalized CSG tree has %d elements", int(this->root_chain->objects.size()));
}
else {
this->root_chain = NULL;
PRINT("WARNING: CSG normalization resulted in an empty tree");
call_progress_function();
if (root_raw_term) {
this->root_norm_term = normalizer.normalize(root_raw_term);
if (this->root_norm_term) {
this->root_chain = new CSGChain();
this->root_chain->import(this->root_norm_term);
PRINTB("Normalized CSG tree has %d elements", int(this->root_chain->objects.size()));
}
else {
this->root_chain = NULL;
PRINT("WARNING: CSG normalization resulted in an empty tree");
call_progress_function();
}
}
if (this->highlight_terms.size() > 0) {

32
src/Dock.cc Normal file
View File

@ -0,0 +1,32 @@
#include <iostream>
#include <QSettings>
#include "Dock.h"
Dock::Dock(QWidget *parent) : QDockWidget(parent), action(NULL)
{
}
Dock::~Dock()
{
}
void Dock::setVisible(bool visible)
{
QSettings settings;
settings.setValue(configKey, !visible);
if (action != NULL) {
action->setChecked(!visible);
}
QDockWidget::setVisible(visible);
}
void Dock::setConfigKey(const QString configKey)
{
this->configKey = configKey;
}
void Dock::setAction(QAction *action)
{
this->action = action;
}

23
src/Dock.h Normal file
View File

@ -0,0 +1,23 @@
#pragma once
#include <QString>
#include <QAction>
#include <QDockWidget>
class Dock : public QDockWidget
{
Q_OBJECT
public:
Dock(QWidget *parent = NULL);
virtual ~Dock();
void setConfigKey(const QString configKey);
void setAction(QAction *action);
public slots:
void setVisible(bool visible);
private:
QString configKey;
QAction *action;
};

View File

@ -80,7 +80,7 @@ GeometryEvaluator::ResultObject GeometryEvaluator::applyToChildren(const Abstrac
{
unsigned int dim = 0;
BOOST_FOREACH(const Geometry::ChildItem &item, this->visitedchildren[node.index()]) {
if (item.second) {
if (!item.first->modinst->isBackground() && item.second) {
if (!dim) dim = item.second->getDimension();
else if (dim != item.second->getDimension()) {
PRINT("WARNING: Mixing 2D and 3D objects is not supported.");

View File

@ -68,6 +68,9 @@ public:
QAction *actionRecentFile[UIUtils::maxRecentFiles];
QMap<QString, QString> knownFileExtensions;
QWidget *editorDockTitleWidget;
QWidget *consoleDockTitleWidget;
QString editortype;
bool useScintilla;
@ -82,6 +85,7 @@ private slots:
void updateTVal();
void updateMdiMode(bool mdi);
void updateUndockMode(bool undockMode);
void updateReorderMode(bool reorderMode);
void setFileName(const QString &filename);
void setFont(const QString &family, uint size);
void setColorScheme(const QString &cs);
@ -231,20 +235,22 @@ public slots:
void checkAutoReload();
void waitAfterReload();
void autoReloadSet(bool);
void setContentsChanged();
private:
static void report_func(const class AbstractNode*, void *vp, int mark);
static bool mdiMode;
static bool undockMode;
static bool reorderMode;
static QSet<MainWindow*> *windows;
char const * afterCompileSlot;
bool procevents;
bool isClosing;
class QTemporaryFile *tempFile;
class ProgressWidget *progresswidget;
class CGALWorker *cgalworker;
QMutex consolemutex;
bool contentschanged; // Set if the source code has changes since the last render (F6)
signals:
void highlightError(int);

View File

@ -289,7 +289,7 @@
<addaction name="menuHelp"/>
</widget>
<widget class="QStatusBar" name="statusbar"/>
<widget class="QDockWidget" name="editorDock">
<widget class="Dock" name="editorDock">
<attribute name="dockWidgetArea">
<number>1</number>
</attribute>
@ -412,7 +412,7 @@
</layout>
</widget>
</widget>
<widget class="QDockWidget" name="consoleDock">
<widget class="Dock" name="consoleDock">
<attribute name="dockWidgetArea">
<number>8</number>
</attribute>
@ -423,6 +423,12 @@
</property>
<item>
<widget class="QTextEdit" name="console">
<property name="minimumSize">
<size>
<width>10</width>
<height>10</height>
</size>
</property>
<property name="focusPolicy">
<enum>Qt::ClickFocus</enum>
</property>
@ -1094,6 +1100,12 @@
<header>QGLView.h</header>
<container>1</container>
</customwidget>
<customwidget>
<class>Dock</class>
<extends>QDockWidget</extends>
<header>Dock.h</header>
<container>1</container>
</customwidget>
</customwidgets>
<resources>
<include location="../openscad.qrc"/>

View File

@ -58,16 +58,16 @@ OpenCSGRenderer::OpenCSGRenderer(CSGChain *root_chain, CSGChain *highlights_chai
void OpenCSGRenderer::draw(bool /*showfaces*/, bool showedges) const
{
GLint *shaderinfo = this->shaderinfo;
if (!shaderinfo[0]) shaderinfo = NULL;
if (this->root_chain) {
GLint *shaderinfo = this->shaderinfo;
if (!shaderinfo[0]) shaderinfo = NULL;
renderCSGChain(this->root_chain, showedges ? shaderinfo : NULL, false, false);
if (this->background_chain) {
renderCSGChain(this->background_chain, showedges ? shaderinfo : NULL, false, true);
}
if (this->highlights_chain) {
renderCSGChain(this->highlights_chain, showedges ? shaderinfo : NULL, true, false);
}
}
if (this->background_chain) {
renderCSGChain(this->background_chain, showedges ? shaderinfo : NULL, false, true);
}
if (this->highlights_chain) {
renderCSGChain(this->highlights_chain, showedges ? shaderinfo : NULL, true, false);
}
}
@ -152,5 +152,7 @@ BoundingBox OpenCSGRenderer::getBoundingBox() const
{
BoundingBox bbox;
if (this->root_chain) bbox = this->root_chain->getBoundingBox();
if (this->background_chain) bbox.extend(this->background_chain->getBoundingBox());
return bbox;
}

View File

@ -11,5 +11,12 @@ std::string PlatformUtils::documentsPath()
return std::string([[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject] UTF8String]);
}
std::string PlatformUtils::userConfigPath()
{
NSError *error;
NSURL *appSupportDir = [[NSFileManager defaultManager] URLForDirectory:NSApplicationSupportDirectory inDomain:NSUserDomainMask appropriateForURL:nil create:YES error:&error];
return std::string([[appSupportDir path] UTF8String]) + std::string("/") + PlatformUtils::OPENSCAD_FOLDER_NAME;
}
void PlatformUtils::ensureStdIO(void) {}

View File

@ -19,5 +19,27 @@ std::string PlatformUtils::documentsPath()
}
}
// see http://standards.freedesktop.org/basedir-spec/basedir-spec-latest.html
std::string PlatformUtils::userConfigPath()
{
fs::path config_path;
const char *xdg_env = getenv("XDG_CONFIG_HOME");
if (xdg_env && fs::exists(fs::path(xdg_env))) {
config_path = fs::path(xdg_env) / OPENSCAD_FOLDER_NAME;
} else {
const char *home = getenv("HOME");
if (home) {
config_path = fs::path(home) / ".config" / OPENSCAD_FOLDER_NAME;
}
}
if (fs::is_directory(config_path)) {
return boosty::stringy(boosty::absolute(config_path));
}
return "";
}
void PlatformUtils::ensureStdIO(void) {}

View File

@ -47,6 +47,27 @@ std::string winapi_wstr_to_utf8( std::wstring wstr )
return utf8_str;
}
// see http://msdn.microsoft.com/en-us/library/windows/desktop/bb762494%28v=vs.85%29.aspx
static const std::string getFolderPath(int nFolder)
{
std::wstring path(MAX_PATH,0);
HWND hwndOwner = 0;
HANDLE hToken = NULL;
DWORD dwFlags = SHGFP_TYPE_CURRENT;
LPTSTR pszPath = &path[0];
int result = SHGetFolderPathW( hwndOwner, nFolder, hToken, dwFlags, pszPath );
if (result == S_OK) {
path = std::wstring( path.c_str() ); // strip extra NULLs
//std::wcerr << "wchar path:" << "\n";
const std::string retval = winapi_wstr_to_utf8( path );
//PRINTB("Path found: %s",retval);
return retval;
}
return "";
}
// retrieve the path to 'My Documents' for the current user under windows
// In XP this is 'c:\documents and settings\username\my documents'
@ -55,29 +76,22 @@ std::string winapi_wstr_to_utf8( std::wstring wstr )
// Mingw does not provide access to the updated SHGetKnownFolderPath
std::string PlatformUtils::documentsPath()
{
std::string retval;
std::wstring path(MAX_PATH,0);
HWND hwndOwner = 0;
int nFolder = CSIDL_PERSONAL;
HANDLE hToken = NULL;
DWORD dwFlags = SHGFP_TYPE_CURRENT;
LPTSTR pszPath = &path[0];
int result = SHGetFolderPathW( hwndOwner, nFolder, hToken, dwFlags, pszPath );
if (result == S_OK) {
path = std::wstring( path.c_str() ); // stip extra NULLs
//std::wcerr << "wchar path:" << "\n";
retval = winapi_wstr_to_utf8( path );
//PRINTB("Path found: %s",retval);
} else {
PRINT("ERROR: Could not find My Documents location");
retval = "";
const std::string retval = getFolderPath(CSIDL_PERSONAL);
if (retval.empty()) {
PRINT("ERROR: Could not find My Documents location");
}
return retval;
}
std::string PlatformUtils::userConfigPath()
{
const std::string retval = getFolderPath(CSIDL_LOCAL_APPDATA);
if (retval.empty()) {
PRINT("ERROR: Could not find Local AppData location");
}
return retval + std::string("/") + PlatformUtils::OPENSCAD_FOLDER_NAME;
}
#include <io.h>
#include <stdio.h>
#include <fstream>

View File

@ -13,6 +13,8 @@ namespace {
std::string applicationpath;
}
const char *PlatformUtils::OPENSCAD_FOLDER_NAME = "OpenSCAD";
void PlatformUtils::registerApplicationPath(const std::string &apppath)
{
applicationpath = apppath;
@ -51,7 +53,7 @@ std::string PlatformUtils::userLibraryPath()
//PRINTB("path size %i",boosty::stringy(path).size());
//PRINTB("lib path found: [%s]", path );
if (path.empty()) return "";
path /= "OpenSCAD";
path /= OPENSCAD_FOLDER_NAME;
path /= "libraries";
//PRINTB("Appended path %s", path );
//PRINTB("Exists: %i", fs::exists(path) );
@ -70,7 +72,7 @@ std::string PlatformUtils::backupPath()
if (pathstr=="") return "";
path = boosty::canonical(fs::path( pathstr ));
if (path.empty()) return "";
path /= "OpenSCAD";
path /= OPENSCAD_FOLDER_NAME;
path /= "backups";
} catch (const fs::filesystem_error& ex) {
PRINTB("ERROR: %s",ex.what());
@ -100,31 +102,32 @@ std::string PlatformUtils::resourceBasePath()
{
fs::path resourcedir(applicationPath());
fs::path tmpdir;
#ifndef WIN32
#ifdef __APPLE__
// Resources can be bundled on Mac. If not, fall back to development layout
bool isbundle = is_directory(resourcedir / ".." / "Resources");
if (isbundle) {
resourcedir /= "../Resources";
// Fall back to dev layout
if (!is_directory(resourcedir / "libraries")) resourcedir /= "../../..";
}
#elif !defined(WIN32)
tmpdir = resourcedir / "../share/openscad";
if (is_directory(tmpdir / "libraries")) {
const char *searchpath[] = {
"../Resources", // Resources can be bundled on Mac.
"../../..", // Dev location
"..", // Test location
NULL
};
#else
const char *searchpath[] = {
"../share/openscad",
"../../share/openscad",
".",
"..",
"../..",
NULL
};
#endif
for (int a = 0;searchpath[a] != NULL;a++) {
tmpdir = resourcedir / searchpath[a];
if (is_directory(tmpdir / "libraries")) {
resourcedir = tmpdir;
break;
}
}
else {
tmpdir = resourcedir / "../../share/openscad";
if (is_directory(tmpdir / "libraries")) {
resourcedir = tmpdir;
} else {
tmpdir = resourcedir / "../..";
if (is_directory(tmpdir / "libraries")) {
resourcedir = tmpdir;
}
}
}
#endif
#endif // !WIN32
// resourcedir defaults to applicationPath
return boosty::stringy(boosty::canonical(resourcedir));
}

View File

@ -5,6 +5,7 @@
#include "boosty.h"
namespace PlatformUtils {
extern const char *OPENSCAD_FOLDER_NAME;
void registerApplicationPath(const std::string &applicationpath);
std::string applicationPath();
@ -13,6 +14,19 @@ namespace PlatformUtils {
std::string resourceBasePath();
fs::path resourcePath(const std::string& resource);
std::string userLibraryPath();
/**
* Base path where user configuration can be read and written to. On
* Linux this is the $XDG_CONFIG_HOME, on Windows the local AppData
* folder CSIDL_LOCAL_APPDATA.
* On success the returned path can be used directly as base folder
* as it already includes an OpenSCAD specific part.
*
* @return absolute path to the writable configuration folder or
* an empty string if the config path does not exist.
*/
std::string userConfigPath();
bool createUserLibraryPath();
std::string backupPath();
bool createBackupPath();

View File

@ -48,7 +48,10 @@ Q_DECLARE_METATYPE(Feature *);
Preferences::Preferences(QWidget *parent) : QMainWindow(parent)
{
setupUi(this);
}
void Preferences::init() {
// Editor pane
// Setup default font (Try to use a nice monospace font)
QString fontfamily;
@ -103,6 +106,7 @@ Preferences::Preferences(QWidget *parent) : QMainWindow(parent)
this->defaultmap["advanced/forceGoldfeather"] = false;
this->defaultmap["advanced/mdi"] = true;
this->defaultmap["advanced/undockableWindows"] = false;
this->defaultmap["advanced/reorderWindows"] = true;
this->defaultmap["launcher/showOnStartup"] = true;
this->defaultmap["advanced/localization"] = true;
@ -136,9 +140,6 @@ Preferences::Preferences(QWidget *parent) : QMainWindow(parent)
#endif
this->polysetCacheSizeEdit->setValidator(validator);
this->opencsgLimitEdit->setValidator(validator);
setupFeaturesPage();
updateGUI();
}
Preferences::~Preferences()
@ -273,7 +274,7 @@ void Preferences::on_editorType_editTextChanged(const QString &type)
settings.setValue("editor/editortype", type);
}
void Preferences::on_syntaxHighlight_currentIndexChanged(const QString &s)
void Preferences::on_syntaxHighlight_activated(const QString &s)
{
QSettings settings;
settings.setValue("editor/syntaxhighlight", s);
@ -322,6 +323,18 @@ Preferences::on_mdiCheckBox_toggled(bool state)
emit updateMdiMode(state);
}
void
Preferences::on_reorderCheckBox_toggled(bool state)
{
if (!state) {
undockCheckBox->setChecked(false);
}
undockCheckBox->setEnabled(state);
QSettings settings;
settings.setValue("advanced/reorderWindows", state);
emit updateReorderMode(state);
}
void
Preferences::on_undockCheckBox_toggled(bool state)
{
@ -453,7 +466,14 @@ void Preferences::updateGUI()
QString shighlight = getValue("editor/syntaxhighlight").toString();
int shidx = this->syntaxHighlight->findText(shighlight);
if (shidx >= 0) this->syntaxHighlight->setCurrentIndex(shidx);
if (shidx >= 0) {
this->syntaxHighlight->setCurrentIndex(shidx);
} else {
int offidx = this->syntaxHighlight->findText("Off");
if (offidx >= 0) {
this->syntaxHighlight->setCurrentIndex(offidx);
}
}
QString editortypevar = getValue("editor/editortype").toString();
int edidx = this->editorType->findText(editortypevar);
@ -475,7 +495,9 @@ void Preferences::updateGUI()
this->localizationCheckBox->setChecked(getValue("advanced/localization").toBool());
this->forceGoldfeatherBox->setChecked(getValue("advanced/forceGoldfeather").toBool());
this->mdiCheckBox->setChecked(getValue("advanced/mdi").toBool());
this->reorderCheckBox->setChecked(getValue("advanced/reorderWindows").toBool());
this->undockCheckBox->setChecked(getValue("advanced/undockableWindows").toBool());
this->undockCheckBox->setEnabled(this->reorderCheckBox->isChecked());
this->launcherBox->setChecked(getValue("launcher/showOnStartup").toBool());
}
@ -484,4 +506,29 @@ void Preferences::apply() const
emit fontChanged(getValue("editor/fontfamily").toString(), getValue("editor/fontsize").toUInt());
emit requestRedraw();
emit openCSGSettingsChanged();
emit syntaxHighlightChanged(getValue("editor/syntaxhighlight").toString());
}
void Preferences::create(QWidget *parent, QStringList colorSchemes)
{
std::list<std::string> names = ColorMap::inst()->colorSchemeNames(true);
QStringList renderColorSchemes;
foreach (std::string name, names) {
renderColorSchemes << name.c_str();
}
instance = new Preferences(parent);
instance->syntaxHighlight->clear();
instance->syntaxHighlight->addItems(colorSchemes);
instance->colorSchemeChooser->clear();
instance->colorSchemeChooser->addItems(renderColorSchemes);
instance->init();
instance->setupFeaturesPage();
instance->updateGUI();
}
Preferences *Preferences::inst() {
assert(instance != NULL);
return instance;
}

View File

@ -4,7 +4,6 @@
#include <QMainWindow>
#include <QSettings>
#include "ui_Preferences.h"
#include "colormap.h"
class Preferences : public QMainWindow, public Ui::Preferences
{
@ -12,9 +11,12 @@ class Preferences : public QMainWindow, public Ui::Preferences
public:
~Preferences();
static Preferences *inst() { if (!instance) instance = new Preferences(); return instance; }
static void create(QWidget *parent, QStringList colorSchemes);
static Preferences *inst();
QVariant getValue(const QString &key) const;
void init();
void apply() const;
public slots:
@ -23,7 +25,7 @@ public slots:
void on_colorSchemeChooser_itemSelectionChanged();
void on_fontChooser_activated(const QString &);
void on_fontSize_editTextChanged(const QString &);
void on_syntaxHighlight_currentIndexChanged(const QString &);
void on_syntaxHighlight_activated(const QString &);
void on_openCSGWarningBox_toggled(bool);
void on_enableOpenCSGBox_toggled(bool);
void on_cgalCacheSizeEdit_textChanged(const QString &);
@ -35,6 +37,7 @@ public slots:
void on_updateCheckBox_toggled(bool);
void on_snapshotCheckBox_toggled(bool);
void on_mdiCheckBox_toggled(bool);
void on_reorderCheckBox_toggled(bool);
void on_undockCheckBox_toggled(bool);
void on_checkNowButton_clicked();
void on_launcherBox_toggled(bool);
@ -43,11 +46,12 @@ public slots:
signals:
void requestRedraw() const;
void updateMdiMode(bool mdi) const;
void updateUndockMode(bool mdi) const;
void updateUndockMode(bool undockMode) const;
void updateReorderMode(bool undockMode) const;
void fontChanged(const QString &family, uint size) const;
void colorSchemeChanged(const QString &scheme) const;
void openCSGSettingsChanged() const;
void syntaxHighlightChanged(const QString &s);
void syntaxHighlightChanged(const QString &s) const;
void editorTypeChanged(const QString &type);
private:

View File

@ -7,7 +7,7 @@
<x>0</x>
<y>0</y>
<width>852</width>
<height>550</height>
<height>554</height>
</rect>
</property>
<property name="sizePolicy">
@ -27,7 +27,7 @@
<item>
<widget class="QStackedWidget" name="stackedWidget">
<property name="currentIndex">
<number>3</number>
<number>4</number>
</property>
<widget class="QWidget" name="page3DView">
<layout class="QVBoxLayout" name="verticalLayout_4">
@ -54,43 +54,8 @@
<bool>false</bool>
</property>
<property name="currentRow">
<number>0</number>
<number>-1</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>
<item>
<property name="text">
<string>Starnight</string>
</property>
</item>
<item>
<property name="text">
<string>BeforeDawn</string>
</property>
</item>
<item>
<property name="text">
<string>Nature</string>
</property>
</item>
<item>
<property name="text">
<string>DeepOcean</string>
</property>
</item>
</widget>
</item>
</layout>
@ -264,31 +229,6 @@
<verstretch>0</verstretch>
</sizepolicy>
</property>
<item>
<property name="text">
<string>For Light Background</string>
</property>
</item>
<item>
<property name="text">
<string>For Dark Background</string>
</property>
</item>
<item>
<property name="text">
<string>Monokai</string>
</property>
</item>
<item>
<property name="text">
<string>Solarized</string>
</property>
</item>
<item>
<property name="text">
<string>Off</string>
</property>
</item>
</widget>
</item>
<item>
@ -547,8 +487,8 @@
<rect>
<x>0</x>
<y>0</y>
<width>832</width>
<height>420</height>
<width>100</width>
<height>30</height>
</rect>
</property>
<layout class="QVBoxLayout" name="verticalLayout_10">
@ -685,10 +625,17 @@
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="reorderCheckBox">
<property name="text">
<string>Enable docking of Editor and Console in different places</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="undockCheckBox">
<property name="text">
<string>Enable undocking of Editor and Console</string>
<string>Enable undocking of Editor and Console to separate windows</string>
</property>
</widget>
</item>

View File

@ -365,8 +365,10 @@ namespace CGALUtils {
const shared_ptr<const Geometry> &chgeom = item.second;
const CGAL_Nef_polyhedron *N = dynamic_cast<const CGAL_Nef_polyhedron *>(chgeom.get());
if (N) {
for (CGAL_Nef_polyhedron3::Vertex_const_iterator i = N->p3->vertices_begin(); i != N->p3->vertices_end(); ++i) {
points.insert(K::Point_3(to_double(i->point()[0]),to_double(i->point()[1]),to_double(i->point()[2])));
if (!N->isEmpty()) {
for (CGAL_Nef_polyhedron3::Vertex_const_iterator i = N->p3->vertices_begin(); i != N->p3->vertices_end(); ++i) {
points.insert(K::Point_3(to_double(i->point()[0]),to_double(i->point()[1]),to_double(i->point()[2])));
}
}
} else {
const PolySet *ps = dynamic_cast<const PolySet *>(chgeom.get());

View File

@ -31,22 +31,180 @@
#include "printutils.h"
#include <sstream>
#include <assert.h>
#include <boost/unordered/unordered_map.hpp>
#include <boost/algorithm/string/case_conv.hpp>
#include <boost/assign/std/vector.hpp>
#include <boost/assign/list_of.hpp>
using namespace boost::assign; // bring 'operator+=()' into scope
#include "colormap.h"
class ColorModule : public AbstractModule
{
public:
ColorModule() : webcolors(ColorMap::inst()->webColors()) { }
ColorModule();
virtual ~ColorModule();
virtual AbstractNode *instantiate(const Context *ctx, const ModuleInstantiation *inst, const EvalContext *evalctx) const;
private:
const boost::unordered_map<std::string, Color4f> &webcolors;
boost::unordered_map<std::string, Color4f> webcolors;
};
ColorModule::ColorModule()
{
webcolors = map_list_of
("aliceblue", Color4f(240, 248, 255))
("antiquewhite", Color4f(250, 235, 215))
("aqua", Color4f(0, 255, 255))
("aquamarine", Color4f(127, 255, 212))
("azure", Color4f(240, 255, 255))
("beige", Color4f(245, 245, 220))
("bisque", Color4f(255, 228, 196))
("black", Color4f(0, 0, 0))
("blanchedalmond", Color4f(255, 235, 205))
("blue", Color4f(0, 0, 255))
("blueviolet", Color4f(138, 43, 226))
("brown", Color4f(165, 42, 42))
("burlywood", Color4f(222, 184, 135))
("cadetblue", Color4f(95, 158, 160))
("chartreuse", Color4f(127, 255, 0))
("chocolate", Color4f(210, 105, 30))
("coral", Color4f(255, 127, 80))
("cornflowerblue", Color4f(100, 149, 237))
("cornsilk", Color4f(255, 248, 220))
("crimson", Color4f(220, 20, 60))
("cyan", Color4f(0, 255, 255))
("darkblue", Color4f(0, 0, 139))
("darkcyan", Color4f(0, 139, 139))
("darkgoldenrod", Color4f(184, 134, 11))
("darkgray", Color4f(169, 169, 169))
("darkgreen", Color4f(0, 100, 0))
("darkgrey", Color4f(169, 169, 169))
("darkkhaki", Color4f(189, 183, 107))
("darkmagenta", Color4f(139, 0, 139))
("darkolivegreen", Color4f(85, 107, 47))
("darkorange", Color4f(255, 140, 0))
("darkorchid", Color4f(153, 50, 204))
("darkred", Color4f(139, 0, 0))
("darksalmon", Color4f(233, 150, 122))
("darkseagreen", Color4f(143, 188, 143))
("darkslateblue", Color4f(72, 61, 139))
("darkslategray", Color4f(47, 79, 79))
("darkslategrey", Color4f(47, 79, 79))
("darkturquoise", Color4f(0, 206, 209))
("darkviolet", Color4f(148, 0, 211))
("deeppink", Color4f(255, 20, 147))
("deepskyblue", Color4f(0, 191, 255))
("dimgray", Color4f(105, 105, 105))
("dimgrey", Color4f(105, 105, 105))
("dodgerblue", Color4f(30, 144, 255))
("firebrick", Color4f(178, 34, 34))
("floralwhite", Color4f(255, 250, 240))
("forestgreen", Color4f(34, 139, 34))
("fuchsia", Color4f(255, 0, 255))
("gainsboro", Color4f(220, 220, 220))
("ghostwhite", Color4f(248, 248, 255))
("gold", Color4f(255, 215, 0))
("goldenrod", Color4f(218, 165, 32))
("gray", Color4f(128, 128, 128))
("green", Color4f(0, 128, 0))
("greenyellow", Color4f(173, 255, 47))
("grey", Color4f(128, 128, 128))
("honeydew", Color4f(240, 255, 240))
("hotpink", Color4f(255, 105, 180))
("indianred", Color4f(205, 92, 92))
("indigo", Color4f(75, 0, 130))
("ivory", Color4f(255, 255, 240))
("khaki", Color4f(240, 230, 140))
("lavender", Color4f(230, 230, 250))
("lavenderblush", Color4f(255, 240, 245))
("lawngreen", Color4f(124, 252, 0))
("lemonchiffon", Color4f(255, 250, 205))
("lightblue", Color4f(173, 216, 230))
("lightcoral", Color4f(240, 128, 128))
("lightcyan", Color4f(224, 255, 255))
("lightgoldenrodyellow", Color4f(250, 250, 210))
("lightgray", Color4f(211, 211, 211))
("lightgreen", Color4f(144, 238, 144))
("lightgrey", Color4f(211, 211, 211))
("lightpink", Color4f(255, 182, 193))
("lightsalmon", Color4f(255, 160, 122))
("lightseagreen", Color4f(32, 178, 170))
("lightskyblue", Color4f(135, 206, 250))
("lightslategray", Color4f(119, 136, 153))
("lightslategrey", Color4f(119, 136, 153))
("lightsteelblue", Color4f(176, 196, 222))
("lightyellow", Color4f(255, 255, 224))
("lime", Color4f(0, 255, 0))
("limegreen", Color4f(50, 205, 50))
("linen", Color4f(250, 240, 230))
("magenta", Color4f(255, 0, 255))
("maroon", Color4f(128, 0, 0))
("mediumaquamarine", Color4f(102, 205, 170))
("mediumblue", Color4f(0, 0, 205))
("mediumorchid", Color4f(186, 85, 211))
("mediumpurple", Color4f(147, 112, 219))
("mediumseagreen", Color4f(60, 179, 113))
("mediumslateblue", Color4f(123, 104, 238))
("mediumspringgreen", Color4f(0, 250, 154))
("mediumturquoise", Color4f(72, 209, 204))
("mediumvioletred", Color4f(199, 21, 133))
("midnightblue", Color4f(25, 25, 112))
("mintcream", Color4f(245, 255, 250))
("mistyrose", Color4f(255, 228, 225))
("moccasin", Color4f(255, 228, 181))
("navajowhite", Color4f(255, 222, 173))
("navy", Color4f(0, 0, 128))
("oldlace", Color4f(253, 245, 230))
("olive", Color4f(128, 128, 0))
("olivedrab", Color4f(107, 142, 35))
("orange", Color4f(255, 165, 0))
("orangered", Color4f(255, 69, 0))
("orchid", Color4f(218, 112, 214))
("palegoldenrod", Color4f(238, 232, 170))
("palegreen", Color4f(152, 251, 152))
("paleturquoise", Color4f(175, 238, 238))
("palevioletred", Color4f(219, 112, 147))
("papayawhip", Color4f(255, 239, 213))
("peachpuff", Color4f(255, 218, 185))
("peru", Color4f(205, 133, 63))
("pink", Color4f(255, 192, 203))
("plum", Color4f(221, 160, 221))
("powderblue", Color4f(176, 224, 230))
("purple", Color4f(128, 0, 128))
("red", Color4f(255, 0, 0))
("rosybrown", Color4f(188, 143, 143))
("royalblue", Color4f(65, 105, 225))
("saddlebrown", Color4f(139, 69, 19))
("salmon", Color4f(250, 128, 114))
("sandybrown", Color4f(244, 164, 96))
("seagreen", Color4f(46, 139, 87))
("seashell", Color4f(255, 245, 238))
("sienna", Color4f(160, 82, 45))
("silver", Color4f(192, 192, 192))
("skyblue", Color4f(135, 206, 235))
("slateblue", Color4f(106, 90, 205))
("slategray", Color4f(112, 128, 144))
("slategrey", Color4f(112, 128, 144))
("snow", Color4f(255, 250, 250))
("springgreen", Color4f(0, 255, 127))
("steelblue", Color4f(70, 130, 180))
("tan", Color4f(210, 180, 140))
("teal", Color4f(0, 128, 128))
("thistle", Color4f(216, 191, 216))
("tomato", Color4f(255, 99, 71))
("transparent", Color4f(0, 0, 0, 0))
("turquoise", Color4f(64, 224, 208))
("violet", Color4f(238, 130, 238))
("wheat", Color4f(245, 222, 179))
("white", Color4f(255, 255, 255))
("whitesmoke", Color4f(245, 245, 245))
("yellow", Color4f(255, 255, 0))
("yellowgreen", Color4f(154, 205, 50));
}
ColorModule::~ColorModule()
{
}
AbstractNode *ColorModule::instantiate(const Context *ctx, const ModuleInstantiation *inst, const EvalContext *evalctx) const
{
ColorNode *node = new ColorNode(inst);

View File

@ -1,8 +1,108 @@
#include "colormap.h"
#include <boost/lexical_cast.hpp>
#include <boost/assign/list_of.hpp>
#include "boosty.h"
#include "printutils.h"
#include "PlatformUtils.h"
using namespace boost::assign; // bring map_list_of() into scope
static const char *DEFAULT_COLOR_SCHEME_NAME = "Cornfield";
RenderColorScheme::RenderColorScheme() : path("")
{
_name = DEFAULT_COLOR_SCHEME_NAME;
_index = 1000;
_show_in_gui = true;
_color_scheme.insert(ColorScheme::value_type(BACKGROUND_COLOR, Color4f(0xff, 0xff, 0xe5)));
_color_scheme.insert(ColorScheme::value_type(OPENCSG_FACE_FRONT_COLOR, Color4f(0xf9, 0xd7, 0x2c)));
_color_scheme.insert(ColorScheme::value_type(OPENCSG_FACE_BACK_COLOR, Color4f(0x9d, 0xcb, 0x51)));
_color_scheme.insert(ColorScheme::value_type(CGAL_FACE_FRONT_COLOR, Color4f(0xf9, 0xd7, 0x2c)));
_color_scheme.insert(ColorScheme::value_type(CGAL_FACE_2D_COLOR, Color4f(0x00, 0xbf, 0x99)));
_color_scheme.insert(ColorScheme::value_type(CGAL_FACE_BACK_COLOR, Color4f(0x9d, 0xcb, 0x51)));
_color_scheme.insert(ColorScheme::value_type(CGAL_EDGE_FRONT_COLOR, Color4f(0xff, 0xec, 0x5e)));
_color_scheme.insert(ColorScheme::value_type(CGAL_EDGE_BACK_COLOR, Color4f(0xab, 0xd8, 0x56)));
_color_scheme.insert(ColorScheme::value_type(CGAL_EDGE_2D_COLOR, Color4f(0xff, 0x00, 0x00)));
_color_scheme.insert(ColorScheme::value_type(CROSSHAIR_COLOR, Color4f(0x80, 0x00, 0x00)));
}
RenderColorScheme::RenderColorScheme(fs::path path) : path(path)
{
try {
boost::property_tree::read_json(boosty::stringy(path).c_str(), pt);
_name = pt.get<std::string>("name");
_index = pt.get<int>("index");
_show_in_gui = pt.get<bool>("show-in-gui");
addColor(BACKGROUND_COLOR, "background");
addColor(OPENCSG_FACE_FRONT_COLOR, "opencsg-face-front");
addColor(OPENCSG_FACE_BACK_COLOR, "opencsg-face-back");
addColor(CGAL_FACE_FRONT_COLOR, "cgal-face-front");
addColor(CGAL_FACE_2D_COLOR, "cgal-face-2d");
addColor(CGAL_FACE_BACK_COLOR, "cgal-face-back");
addColor(CGAL_EDGE_FRONT_COLOR, "cgal-edge-front");
addColor(CGAL_EDGE_BACK_COLOR, "cgal-edge-back");
addColor(CGAL_EDGE_2D_COLOR, "cgal-edge-2d");
addColor(CROSSHAIR_COLOR, "crosshair");
} catch (const std::exception & e) {
PRINTB("Error reading color scheme file '%s': %s", path.c_str() % e.what());
_name = "";
_index = 0;
_show_in_gui = false;
}
}
RenderColorScheme::~RenderColorScheme()
{
}
bool RenderColorScheme::valid() const
{
return !_name.empty();
}
const std::string & RenderColorScheme::name() const
{
return _name;
}
int RenderColorScheme::index() const
{
return _index;
}
bool RenderColorScheme::showInGui() const
{
return _show_in_gui;
}
ColorScheme & RenderColorScheme::colorScheme()
{
return _color_scheme;
}
const boost::property_tree::ptree & RenderColorScheme::propertyTree() const
{
return pt;
}
void RenderColorScheme::addColor(RenderColor colorKey, std::string key)
{
const boost::property_tree::ptree& colors = pt.get_child("colors");
std::string color = colors.get<std::string>(key);
if ((color.length() == 7) && (color.at(0) == '#')) {
char *endptr;
unsigned int val = strtol(color.substr(1).c_str(), &endptr, 16);
int r = (val >> 16) & 0xff;
int g = (val >> 8) & 0xff;
int b = val & 0xff;
_color_scheme.insert(ColorScheme::value_type(colorKey, Color4f(r, g, b)));
} else {
throw std::invalid_argument(std::string("invalid color value for key '") + key + "': '" + color + "'");
}
}
ColorMap *ColorMap::inst(bool erase)
{
static ColorMap *instance = new ColorMap;
@ -13,286 +113,44 @@ ColorMap *ColorMap::inst(bool erase)
return instance;
}
ColorMap::ColorMap() {
boost::unordered_map<std::string, Color4f> tmpwebcolors = map_list_of
("aliceblue", Color4f(240, 248, 255))
("antiquewhite", Color4f(250, 235, 215))
("aqua", Color4f(0, 255, 255))
("aquamarine", Color4f(127, 255, 212))
("azure", Color4f(240, 255, 255))
("beige", Color4f(245, 245, 220))
("bisque", Color4f(255, 228, 196))
("black", Color4f(0, 0, 0))
("blanchedalmond", Color4f(255, 235, 205))
("blue", Color4f(0, 0, 255))
("blueviolet", Color4f(138, 43, 226))
("brown", Color4f(165, 42, 42))
("burlywood", Color4f(222, 184, 135))
("cadetblue", Color4f(95, 158, 160))
("chartreuse", Color4f(127, 255, 0))
("chocolate", Color4f(210, 105, 30))
("coral", Color4f(255, 127, 80))
("cornflowerblue", Color4f(100, 149, 237))
("cornsilk", Color4f(255, 248, 220))
("crimson", Color4f(220, 20, 60))
("cyan", Color4f(0, 255, 255))
("darkblue", Color4f(0, 0, 139))
("darkcyan", Color4f(0, 139, 139))
("darkgoldenrod", Color4f(184, 134, 11))
("darkgray", Color4f(169, 169, 169))
("darkgreen", Color4f(0, 100, 0))
("darkgrey", Color4f(169, 169, 169))
("darkkhaki", Color4f(189, 183, 107))
("darkmagenta", Color4f(139, 0, 139))
("darkolivegreen", Color4f(85, 107, 47))
("darkorange", Color4f(255, 140, 0))
("darkorchid", Color4f(153, 50, 204))
("darkred", Color4f(139, 0, 0))
("darksalmon", Color4f(233, 150, 122))
("darkseagreen", Color4f(143, 188, 143))
("darkslateblue", Color4f(72, 61, 139))
("darkslategray", Color4f(47, 79, 79))
("darkslategrey", Color4f(47, 79, 79))
("darkturquoise", Color4f(0, 206, 209))
("darkviolet", Color4f(148, 0, 211))
("deeppink", Color4f(255, 20, 147))
("deepskyblue", Color4f(0, 191, 255))
("dimgray", Color4f(105, 105, 105))
("dimgrey", Color4f(105, 105, 105))
("dodgerblue", Color4f(30, 144, 255))
("firebrick", Color4f(178, 34, 34))
("floralwhite", Color4f(255, 250, 240))
("forestgreen", Color4f(34, 139, 34))
("fuchsia", Color4f(255, 0, 255))
("gainsboro", Color4f(220, 220, 220))
("ghostwhite", Color4f(248, 248, 255))
("gold", Color4f(255, 215, 0))
("goldenrod", Color4f(218, 165, 32))
("gray", Color4f(128, 128, 128))
("green", Color4f(0, 128, 0))
("greenyellow", Color4f(173, 255, 47))
("grey", Color4f(128, 128, 128))
("honeydew", Color4f(240, 255, 240))
("hotpink", Color4f(255, 105, 180))
("indianred", Color4f(205, 92, 92))
("indigo", Color4f(75, 0, 130))
("ivory", Color4f(255, 255, 240))
("khaki", Color4f(240, 230, 140))
("lavender", Color4f(230, 230, 250))
("lavenderblush", Color4f(255, 240, 245))
("lawngreen", Color4f(124, 252, 0))
("lemonchiffon", Color4f(255, 250, 205))
("lightblue", Color4f(173, 216, 230))
("lightcoral", Color4f(240, 128, 128))
("lightcyan", Color4f(224, 255, 255))
("lightgoldenrodyellow", Color4f(250, 250, 210))
("lightgray", Color4f(211, 211, 211))
("lightgreen", Color4f(144, 238, 144))
("lightgrey", Color4f(211, 211, 211))
("lightpink", Color4f(255, 182, 193))
("lightsalmon", Color4f(255, 160, 122))
("lightseagreen", Color4f(32, 178, 170))
("lightskyblue", Color4f(135, 206, 250))
("lightslategray", Color4f(119, 136, 153))
("lightslategrey", Color4f(119, 136, 153))
("lightsteelblue", Color4f(176, 196, 222))
("lightyellow", Color4f(255, 255, 224))
("lime", Color4f(0, 255, 0))
("limegreen", Color4f(50, 205, 50))
("linen", Color4f(250, 240, 230))
("magenta", Color4f(255, 0, 255))
("maroon", Color4f(128, 0, 0))
("mediumaquamarine", Color4f(102, 205, 170))
("mediumblue", Color4f(0, 0, 205))
("mediumorchid", Color4f(186, 85, 211))
("mediumpurple", Color4f(147, 112, 219))
("mediumseagreen", Color4f(60, 179, 113))
("mediumslateblue", Color4f(123, 104, 238))
("mediumspringgreen", Color4f(0, 250, 154))
("mediumturquoise", Color4f(72, 209, 204))
("mediumvioletred", Color4f(199, 21, 133))
("midnightblue", Color4f(25, 25, 112))
("mintcream", Color4f(245, 255, 250))
("mistyrose", Color4f(255, 228, 225))
("moccasin", Color4f(255, 228, 181))
("navajowhite", Color4f(255, 222, 173))
("navy", Color4f(0, 0, 128))
("oldlace", Color4f(253, 245, 230))
("olive", Color4f(128, 128, 0))
("olivedrab", Color4f(107, 142, 35))
("orange", Color4f(255, 165, 0))
("orangered", Color4f(255, 69, 0))
("orchid", Color4f(218, 112, 214))
("palegoldenrod", Color4f(238, 232, 170))
("palegreen", Color4f(152, 251, 152))
("paleturquoise", Color4f(175, 238, 238))
("palevioletred", Color4f(219, 112, 147))
("papayawhip", Color4f(255, 239, 213))
("peachpuff", Color4f(255, 218, 185))
("peru", Color4f(205, 133, 63))
("pink", Color4f(255, 192, 203))
("plum", Color4f(221, 160, 221))
("powderblue", Color4f(176, 224, 230))
("purple", Color4f(128, 0, 128))
("red", Color4f(255, 0, 0))
("rosybrown", Color4f(188, 143, 143))
("royalblue", Color4f(65, 105, 225))
("saddlebrown", Color4f(139, 69, 19))
("salmon", Color4f(250, 128, 114))
("sandybrown", Color4f(244, 164, 96))
("seagreen", Color4f(46, 139, 87))
("seashell", Color4f(255, 245, 238))
("sienna", Color4f(160, 82, 45))
("silver", Color4f(192, 192, 192))
("skyblue", Color4f(135, 206, 235))
("slateblue", Color4f(106, 90, 205))
("slategray", Color4f(112, 128, 144))
("slategrey", Color4f(112, 128, 144))
("snow", Color4f(255, 250, 250))
("springgreen", Color4f(0, 255, 127))
("steelblue", Color4f(70, 130, 180))
("tan", Color4f(210, 180, 140))
("teal", Color4f(0, 128, 128))
("thistle", Color4f(216, 191, 216))
("tomato", Color4f(255, 99, 71))
("transparent", Color4f(0, 0, 0, 0))
("turquoise", Color4f(64, 224, 208))
("violet", Color4f(238, 130, 238))
("wheat", Color4f(245, 222, 179))
("white", Color4f(255, 255, 255))
("whitesmoke", Color4f(245, 245, 245))
("yellow", Color4f(255, 255, 0))
("yellowgreen", Color4f(154, 205, 50));
webcolors = tmpwebcolors;
ColorScheme cornfield = map_list_of
(BACKGROUND_COLOR, Color4f(0xff, 0xff, 0xe5))
(OPENCSG_FACE_FRONT_COLOR, Color4f(0xf9, 0xd7, 0x2c))
(OPENCSG_FACE_BACK_COLOR, Color4f(0x9d, 0xcb, 0x51))
(CGAL_FACE_FRONT_COLOR, Color4f(0xf9, 0xd7, 0x2c))
(CGAL_FACE_BACK_COLOR, Color4f(0x9d, 0xcb, 0x51))
(CGAL_FACE_2D_COLOR, Color4f(0x00, 0xbf, 0x99))
(CGAL_EDGE_FRONT_COLOR, Color4f(0xff, 0xec, 0x5e))
(CGAL_EDGE_BACK_COLOR, Color4f(0xab, 0xd8, 0x56))
(CGAL_EDGE_2D_COLOR, Color4f(0xff, 0x00, 0x00))
(CROSSHAIR_COLOR, Color4f(0x80, 0x00, 0x00));
ColorScheme metallic = map_list_of
(BACKGROUND_COLOR, Color4f(0xaa, 0xaa, 0xff))
(OPENCSG_FACE_FRONT_COLOR, Color4f(0xdd, 0xdd, 0xff))
(OPENCSG_FACE_BACK_COLOR, Color4f(0xdd, 0x22, 0xdd))
(CGAL_FACE_FRONT_COLOR, Color4f(0xdd, 0xdd, 0xff))
(CGAL_FACE_BACK_COLOR, Color4f(0xdd, 0x22, 0xdd))
(CGAL_FACE_2D_COLOR, Color4f(0x00, 0xbf, 0x99))
(CGAL_EDGE_FRONT_COLOR, Color4f(0xff, 0x00, 0x00))
(CGAL_EDGE_BACK_COLOR, Color4f(0xff, 0x00, 0x00))
(CGAL_EDGE_2D_COLOR, Color4f(0xff, 0x00, 0x00))
(CROSSHAIR_COLOR, Color4f(0x80, 0x00, 0x00));
ColorScheme sunset = map_list_of
(BACKGROUND_COLOR, Color4f(0xaa, 0x44, 0x44))
(OPENCSG_FACE_FRONT_COLOR, Color4f(0xff, 0xaa, 0xaa))
(OPENCSG_FACE_BACK_COLOR, Color4f(0x88, 0x22, 0x33))
(CGAL_FACE_FRONT_COLOR, Color4f(0xff, 0xaa, 0xaa))
(CGAL_FACE_BACK_COLOR, Color4f(0x88, 0x22, 0x33))
(CGAL_FACE_2D_COLOR, Color4f(0x00, 0xbf, 0x99))
(CGAL_EDGE_FRONT_COLOR, Color4f(0xff, 0x00, 0x00))
(CGAL_EDGE_BACK_COLOR, Color4f(0xff, 0x00, 0x00))
(CGAL_EDGE_2D_COLOR, Color4f(0xff, 0x00, 0x00))
(CROSSHAIR_COLOR, Color4f(0x80, 0x00, 0x00));
ColorScheme starnight = map_list_of
(BACKGROUND_COLOR, webcolors["black"])
(OPENCSG_FACE_FRONT_COLOR, webcolors["lightyellow"])
(OPENCSG_FACE_BACK_COLOR, webcolors["cyan"])
(CGAL_FACE_FRONT_COLOR, webcolors["lightyellow"])
(CGAL_FACE_BACK_COLOR, webcolors["cyan"])
(CGAL_FACE_2D_COLOR, webcolors["mediumpurple"])
(CGAL_EDGE_FRONT_COLOR, Color4f(0x00, 0x00, 0xff))
(CGAL_EDGE_BACK_COLOR, Color4f(0x00, 0x00, 0xff))
(CGAL_EDGE_2D_COLOR, webcolors["magenta"])
(CROSSHAIR_COLOR, Color4f(0xf0, 0xf0, 0xf0));
ColorScheme beforedawn = map_list_of
(BACKGROUND_COLOR, Color4f(0x33, 0x33, 0x33))
(OPENCSG_FACE_FRONT_COLOR, Color4f(0xcc, 0xcc, 0xcc))
(OPENCSG_FACE_BACK_COLOR, Color4f(0x55, 0x63, 0xdd))
(CGAL_FACE_FRONT_COLOR, Color4f(0xcc, 0xcc, 0xcc))
(CGAL_FACE_BACK_COLOR, Color4f(0x55, 0x63, 0xdd))
(CGAL_FACE_2D_COLOR, Color4f(0x00, 0xbf, 0x99))
(CGAL_EDGE_FRONT_COLOR, Color4f(0xff, 0x00, 0x00))
(CGAL_EDGE_BACK_COLOR, Color4f(0xff, 0x00, 0x00))
(CGAL_EDGE_2D_COLOR, Color4f(0xff, 0x00, 0x00))
(CROSSHAIR_COLOR, Color4f(0xf0, 0xf0, 0xf0));
ColorScheme nature = map_list_of
(BACKGROUND_COLOR, Color4f(0xfa, 0xfa, 0xfa))
(OPENCSG_FACE_FRONT_COLOR, Color4f(0x16, 0xa0, 0x85))
(OPENCSG_FACE_BACK_COLOR, Color4f(0xdb, 0xf4, 0xda))
(CGAL_FACE_FRONT_COLOR, Color4f(0x16, 0xa0, 0x85))
(CGAL_FACE_BACK_COLOR, Color4f(0xdb, 0xf4, 0xda))
(CGAL_FACE_2D_COLOR, Color4f(0x00, 0xbf, 0x99))
(CGAL_EDGE_FRONT_COLOR, Color4f(0xff, 0x00, 0x00))
(CGAL_EDGE_BACK_COLOR, Color4f(0xff, 0x00, 0x00))
(CGAL_EDGE_2D_COLOR, Color4f(0xff, 0x00, 0x00))
(CROSSHAIR_COLOR, Color4f(0x11, 0x11, 0x11));
ColorScheme deepocean = map_list_of
(BACKGROUND_COLOR, Color4f(0x33, 0x33, 0x33))
(OPENCSG_FACE_FRONT_COLOR, Color4f(0xee, 0xee, 0xee))
(OPENCSG_FACE_BACK_COLOR, Color4f(0x0b, 0xab, 0xc8))
(CGAL_FACE_FRONT_COLOR, Color4f(0xee, 0xee, 0xee))
(CGAL_FACE_BACK_COLOR, Color4f(0x0b, 0xab, 0xc8))
(CGAL_FACE_2D_COLOR, webcolors["mediumpurple"])
(CGAL_EDGE_FRONT_COLOR, Color4f(0x00, 0x00, 0xff))
(CGAL_EDGE_BACK_COLOR, Color4f(0x00, 0x00, 0xff))
(CGAL_EDGE_2D_COLOR, webcolors["magenta"])
(CROSSHAIR_COLOR, Color4f(0xf0, 0xf0, 0xf0));
// Monotone - no difference between 'back face' and 'front face'
ColorScheme monotone = map_list_of
(BACKGROUND_COLOR, Color4f(0xff, 0xff, 0xe5))
(OPENCSG_FACE_FRONT_COLOR, Color4f(0xf9, 0xd7, 0x2c))
(OPENCSG_FACE_BACK_COLOR, Color4f(0xf9, 0xd7, 0x2c))
(CGAL_FACE_FRONT_COLOR, Color4f(0xf9, 0xd7, 0x2c))
(CGAL_FACE_BACK_COLOR, Color4f(0xf9, 0xd7, 0x2c))
(CGAL_FACE_2D_COLOR, Color4f(0x00, 0xbf, 0x99))
(CGAL_EDGE_FRONT_COLOR, Color4f(0xff, 0x00, 0x00))
(CGAL_EDGE_BACK_COLOR, Color4f(0xff, 0x00, 0x00))
(CGAL_EDGE_2D_COLOR, Color4f(0xff, 0x00, 0x00))
(CROSSHAIR_COLOR, Color4f(0x80, 0x00, 0x00));
boost::unordered_map<std::string, ColorScheme> tmpcolorschemes = map_list_of
("Cornfield", cornfield)
("Metallic", metallic)
("Sunset", sunset)
("Starnight", starnight)
("BeforeDawn", beforedawn)
("Nature", nature)
("DeepOcean", deepocean)
("Monotone", monotone); // Hidden, not in GUI
colorschemes = tmpcolorschemes;
ColorMap::ColorMap()
{
colorSchemeSet = enumerateColorSchemes();
}
ColorMap::~ColorMap()
{
}
const ColorScheme &ColorMap::defaultColorScheme() const
{
return colorschemes.at("Cornfield");
return *findColorScheme(DEFAULT_COLOR_SCHEME_NAME);
}
const ColorScheme *ColorMap::findColorScheme(const std::string &name) const
{
if (colorschemes.find(name) != colorschemes.end()) return &colorschemes.at(name);
return NULL;
for (colorscheme_set_t::const_iterator it = colorSchemeSet.begin();it != colorSchemeSet.end();it++) {
RenderColorScheme *scheme = (*it).second.get();
if (name == scheme->name()) {
return &scheme->colorScheme();
}
}
return NULL;
}
std::list<std::string> ColorMap::colorSchemeNames() const
std::list<std::string> ColorMap::colorSchemeNames(bool guiOnly) const
{
std::list<std::string> names;
for (boost::unordered_map<std::string, ColorScheme>::const_iterator iter=colorschemes.begin(); iter!=colorschemes.end(); iter++) {
names.push_back(iter->first);
std::list<std::string> colorSchemeNames;
for (colorscheme_set_t::const_iterator it = colorSchemeSet.begin();it != colorSchemeSet.end();it++) {
RenderColorScheme *scheme = (*it).second.get();
if (guiOnly && !scheme->showInGui()) {
continue;
}
return names;
colorSchemeNames.push_back(scheme->name());
}
return colorSchemeNames;
}
Color4f ColorMap::getColor(const ColorScheme &cs, const RenderColor rc)
@ -302,19 +160,42 @@ Color4f ColorMap::getColor(const ColorScheme &cs, const RenderColor rc)
return Color4f(0, 0, 0, 127);
}
/*
void printcolorscheme(const ColorScheme &cs)
{
for (ColorScheme::const_iterator j=cs.begin();j!=cs.end();j++)
PRINTB("%i %s",j->first % j->second.transpose());
void ColorMap::enumerateColorSchemesInPath(colorscheme_set_t &result_set, const fs::path path)
{
const fs::path color_schemes = path / "color-schemes" / "render";
fs::directory_iterator end_iter;
if (fs::exists(color_schemes) && fs::is_directory(color_schemes)) {
for (fs::directory_iterator dir_iter(color_schemes); dir_iter != end_iter; ++dir_iter) {
if (!fs::is_regular_file(dir_iter->status())) {
continue;
}
const fs::path path = (*dir_iter).path();
if (!(path.extension().string() == ".json")) {
continue;
}
RenderColorScheme *colorScheme = new RenderColorScheme(path);
if (colorScheme->valid() && (findColorScheme(colorScheme->name()) == 0)) {
result_set.insert(colorscheme_set_t::value_type(colorScheme->index(), boost::shared_ptr<RenderColorScheme>(colorScheme)));
} else {
delete colorScheme;
}
}
}
}
void printcolorschemes()
{
for (boost::unordered_map<std::string, ColorScheme>::const_iterator i=colorschemes.begin();i!=colorschemes.end();i++) {
PRINTB("-- %s --", i->first);
for (ColorScheme::const_iterator j=i->second.begin();j!=i->second.end();j++)
PRINTB("%i %s",j->first % j->second.transpose());
}
}
*/
ColorMap::colorscheme_set_t ColorMap::enumerateColorSchemes()
{
colorscheme_set_t result_set;
RenderColorScheme *defaultColorScheme = new RenderColorScheme();
result_set.insert(colorscheme_set_t::value_type(defaultColorScheme->index(),
boost::shared_ptr<RenderColorScheme>(defaultColorScheme)));
enumerateColorSchemesInPath(result_set, PlatformUtils::resourcesPath());
enumerateColorSchemesInPath(result_set, PlatformUtils::userConfigPath());
return result_set;
}

View File

@ -4,7 +4,13 @@
#include <string>
#include <list>
#include "linalg.h"
#include <boost/unordered/unordered_map.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/filesystem.hpp>
#include <boost/property_tree/ptree.hpp>
#include <boost/property_tree/json_parser.hpp>
namespace fs = boost::filesystem;
enum RenderColor {
BACKGROUND_COLOR,
@ -21,23 +27,59 @@ enum RenderColor {
typedef std::map<RenderColor, Color4f> ColorScheme;
class RenderColorScheme
{
private:
const fs::path path;
boost::property_tree::ptree pt;
std::string _name;
int _index;
bool _show_in_gui;
ColorScheme _color_scheme;
public:
/**
* Constructor for the default color scheme Cornfield.
*/
RenderColorScheme();
/**
* Constructor for reading external JSON files.
*/
RenderColorScheme(const fs::path path);
virtual ~RenderColorScheme();
const std::string & name() const;
int index() const;
bool valid() const;
bool showInGui() const;
ColorScheme & colorScheme();
const boost::property_tree::ptree & propertyTree() const;
private:
void addColor(RenderColor colorKey, std::string key);
friend class ColorMap;
};
class ColorMap
{
typedef std::multimap<int, boost::shared_ptr<RenderColorScheme>, std::less<int> > colorscheme_set_t;
public:
static ColorMap *inst(bool erase = false);
const ColorScheme &defaultColorScheme() const;
const boost::unordered_map<std::string, Color4f> &webColors() const { return webcolors; }
const ColorScheme & defaultColorScheme() const;
const ColorScheme *findColorScheme(const std::string &name) const;
std::list<std::string> colorSchemeNames() const;
std::list<std::string> colorSchemeNames(bool guiOnly = false) const;
static Color4f getColor(const ColorScheme &cs, const RenderColor rc);
private:
ColorMap();
~ColorMap() {}
boost::unordered_map<std::string, Color4f> webcolors;
boost::unordered_map<std::string, ColorScheme> colorschemes;
virtual ~ColorMap();
colorscheme_set_t enumerateColorSchemes();
void enumerateColorSchemesInPath(colorscheme_set_t &result_set, const fs::path path);
colorscheme_set_t colorSchemeSet;
};

View File

@ -21,6 +21,7 @@ public:
virtual QString selectedText() = 0;
virtual bool find(const QString &, bool findNext = false, bool findBackwards = false) = 0;
virtual void replaceSelectedText(const QString &) = 0;
virtual QStringList colorSchemes() = 0;
signals:
void contentsChanged();

View File

@ -235,9 +235,6 @@ Highlighter::Highlighter(QTextDocument *parent)
tokentypes["_$quote"] << "_$quote";
tokentypes["_$number"] << "_$number";
QString syntaxhighlight = Preferences::inst()->getValue("editor/syntaxhighlight").toString();
this->assignFormatsToTokens(syntaxhighlight);
errorFormat.setBackground(Qt::red);
errorState = false;
errorPos = -1;

View File

@ -271,3 +271,15 @@ bool LegacyEditor::isContentModified()
{
return textedit->document()->isModified();
}
QStringList LegacyEditor::colorSchemes()
{
QStringList colorSchemes;
colorSchemes
<< "For Light Background"
<< "For Dark Background"
<< "Off";
return colorSchemes;
}

View File

@ -15,6 +15,7 @@ public:
bool find(const QString &, bool findNext = false, bool findBackwards = false);
void replaceSelectedText(const QString &newText);
bool findString(const QString & exp, bool findBackwards) const;
QStringList colorSchemes();
public slots:
void zoomIn();

View File

@ -86,6 +86,7 @@
#include <QTemporaryFile>
#include <QDockWidget>
#include <QClipboard>
#include <QDesktopWidget>
#include <fstream>
@ -171,14 +172,24 @@ settings_valueList(const QString &key, const QList<int> &defaultList = QList<int
bool MainWindow::mdiMode = false;
bool MainWindow::undockMode = false;
bool MainWindow::reorderMode = false;
MainWindow::MainWindow(const QString &filename)
: root_inst("group"), library_info_dialog(NULL), font_list_dialog(NULL), tempFile(NULL), progresswidget(NULL)
: root_inst("group"), library_info_dialog(NULL), font_list_dialog(NULL), tempFile(NULL), progresswidget(NULL), contentschanged(false)
{
setupUi(this);
editortype = Preferences::inst()->getValue("editor/editortype").toString();
useScintilla = (editortype == "QScintilla Editor");
editorDockTitleWidget = new QWidget();
consoleDockTitleWidget = new QWidget();
this->editorDock->setConfigKey("view/hideEditor");
this->editorDock->setAction(this->viewActionHideEditor);
this->consoleDock->setConfigKey("view/hideConsole");
this->consoleDock->setAction(this->viewActionHideConsole);
QSettings settings;
editortype = settings.value("editor/editortype").toString();
useScintilla = (editortype != "Simple Editor");
#ifdef USE_SCINTILLA_EDITOR
if (useScintilla) {
@ -188,6 +199,8 @@ MainWindow::MainWindow(const QString &filename)
#endif
editor = new LegacyEditor(editorDockContents);
Preferences::create(this, editor->colorSchemes());
editorDockContents->layout()->addWidget(editor);
setCorner(Qt::TopLeftCorner, Qt::LeftDockWidgetArea);
@ -225,7 +238,6 @@ MainWindow::MainWindow(const QString &filename)
tval = 0;
fps = 0;
fsteps = 1;
isClosing = false;
const QString importStatement = "import(\"%1\");\n";
const QString surfaceStatement = "surface(\"%1\");\n";
@ -412,11 +424,13 @@ MainWindow::MainWindow(const QString &filename)
updateRecentFileActions();
connect(editor, SIGNAL(contentsChanged()), this, SLOT(animateUpdateDocChanged()));
connect(editor, SIGNAL(contentsChanged()), this, SLOT(setContentsChanged()));
connect(editor, SIGNAL(modificationChanged(bool)), this, SLOT(setWindowModified(bool)));
connect(this->qglview, SIGNAL(doAnimateUpdate()), this, SLOT(animateUpdate()));
connect(Preferences::inst(), SIGNAL(requestRedraw()), this->qglview, SLOT(updateGL()));
connect(Preferences::inst(), SIGNAL(updateMdiMode(bool)), this, SLOT(updateMdiMode(bool)));
connect(Preferences::inst(), SIGNAL(updateReorderMode(bool)), this, SLOT(updateReorderMode(bool)));
connect(Preferences::inst(), SIGNAL(updateUndockMode(bool)), this, SLOT(updateUndockMode(bool)));
connect(Preferences::inst(), SIGNAL(fontChanged(const QString&,uint)),
editor, SLOT(initFont(const QString&,uint)));
@ -510,7 +524,6 @@ MainWindow::MainWindow(const QString &filename)
}
// make sure it looks nice..
QSettings settings;
QByteArray windowState = settings.value("window/state", QByteArray()).toByteArray();
restoreState(windowState);
resize(settings.value("window/size", QSize(800, 600)).toSize());
@ -530,6 +543,24 @@ MainWindow::MainWindow(const QString &filename)
* fill the available space.
*/
editor->setInitialSizeHint(QSize((5 * this->width() / 11), 100));
} else {
#ifdef Q_OS_WIN
// Try moving the main window into the display range, this
// can occur when closing OpenSCAD on a second monitor which
// is not available at the time the application is started
// again.
// On Windows that causes the main window to open in a not
// easily reachable place.
QDesktopWidget *desktop = QApplication::desktop();
QRect desktopRect = desktop->frameGeometry().adjusted(250, 150, -250, -150).normalized();
QRect windowRect = frameGeometry();
if (!desktopRect.intersects(windowRect)) {
windowRect.moveCenter(desktopRect.center());
windowRect = windowRect.intersected(desktopRect);
move(windowRect.topLeft());
resize(windowRect.size());
}
#endif
}
connect(this->editorDock, SIGNAL(topLevelChanged(bool)), this, SLOT(editorTopLevelChanged(bool)));
@ -596,6 +627,7 @@ void MainWindow::loadViewSettings(){
hideToolbars();
updateMdiMode(settings.value("advanced/mdi").toBool());
updateUndockMode(settings.value("advanced/undockableWindows").toBool());
updateReorderMode(settings.value("advanced/reorderWindows").toBool());
}
void MainWindow::loadDesignSettings()
@ -624,11 +656,24 @@ void MainWindow::updateUndockMode(bool undockMode)
editorDock->setFeatures(editorDock->features() | QDockWidget::DockWidgetFloatable);
consoleDock->setFeatures(consoleDock->features() | QDockWidget::DockWidgetFloatable);
} else {
if (editorDock->isFloating()) {
editorDock->setFloating(false);
}
editorDock->setFeatures(editorDock->features() & ~QDockWidget::DockWidgetFloatable);
if (consoleDock->isFloating()) {
consoleDock->setFloating(false);
}
consoleDock->setFeatures(consoleDock->features() & ~QDockWidget::DockWidgetFloatable);
}
}
void MainWindow::updateReorderMode(bool reorderMode)
{
MainWindow::reorderMode = reorderMode;
editorDock->setTitleBarWidget(reorderMode ? 0 : editorDockTitleWidget);
consoleDock->setTitleBarWidget(reorderMode ? 0 : consoleDockTitleWidget);
}
MainWindow::~MainWindow()
{
if (root_module) delete root_module;
@ -805,8 +850,10 @@ void MainWindow::refreshDocument()
reader.setCodec("UTF-8");
QString text = reader.readAll();
PRINTB("Loaded design '%s'.", this->fileName.toLocal8Bit().constData());
if (editor->toPlainText() != text)
if (editor->toPlainText() != text) {
editor->setPlainText(text);
this->contentschanged = true;
}
}
}
setCurrentOutput();
@ -1008,8 +1055,8 @@ void MainWindow::compileCSG(bool procevents)
CSGTermEvaluator csgrenderer(this->tree, &geomevaluator);
if (procevents) QApplication::processEvents();
this->root_raw_term = csgrenderer.evaluateCSGTerm(*root_node, highlight_terms, background_terms);
if (!root_raw_term) {
PRINT("ERROR: CSG generation failed! (no top level object found)");
if (!root_raw_term && background_terms.empty()) {
PRINT("ERROR: CSG generation failed! (no objects found)");
}
GeometryCache::instance()->print();
#ifdef ENABLE_CGAL
@ -1025,12 +1072,13 @@ void MainWindow::compileCSG(bool procevents)
delete this->progresswidget;
this->progresswidget = NULL;
if (root_raw_term) {
PRINT("Compiling design (CSG Products normalization)...");
if (procevents) QApplication::processEvents();
PRINT("Compiling design (CSG Products normalization)...");
if (procevents) QApplication::processEvents();
size_t normalizelimit = 2 * Preferences::inst()->getValue("advanced/openCSGLimit").toUInt();
CSGTermNormalizer normalizer(normalizelimit);
size_t normalizelimit = 2 * Preferences::inst()->getValue("advanced/openCSGLimit").toUInt();
CSGTermNormalizer normalizer(normalizelimit);
if (root_raw_term) {
this->root_norm_term = normalizer.normalize(this->root_raw_term);
if (this->root_norm_term) {
this->root_chain = new CSGChain();
@ -1041,53 +1089,51 @@ void MainWindow::compileCSG(bool procevents)
PRINT("WARNING: CSG normalization resulted in an empty tree");
if (procevents) QApplication::processEvents();
}
if (highlight_terms.size() > 0)
{
PRINTB("Compiling highlights (%d CSG Trees)...", highlight_terms.size());
if (procevents) QApplication::processEvents();
highlights_chain = new CSGChain();
for (unsigned int i = 0; i < highlight_terms.size(); i++) {
highlight_terms[i] = normalizer.normalize(highlight_terms[i]);
highlights_chain->import(highlight_terms[i]);
}
}
if (background_terms.size() > 0)
{
PRINTB("Compiling background (%d CSG Trees)...", background_terms.size());
if (procevents) QApplication::processEvents();
background_chain = new CSGChain();
for (unsigned int i = 0; i < background_terms.size(); i++) {
background_terms[i] = normalizer.normalize(background_terms[i]);
background_chain->import(background_terms[i]);
}
}
if (this->root_chain &&
(this->root_chain->objects.size() >
Preferences::inst()->getValue("advanced/openCSGLimit").toUInt())) {
PRINTB("WARNING: Normalized tree has %d elements!", this->root_chain->objects.size());
PRINT("WARNING: OpenCSG rendering has been disabled.");
}
else {
PRINTB("Normalized CSG tree has %d elements",
(this->root_chain ? this->root_chain->objects.size() : 0));
this->opencsgRenderer = new OpenCSGRenderer(this->root_chain,
this->highlights_chain,
this->background_chain,
this->qglview->shaderinfo);
}
this->thrownTogetherRenderer = new ThrownTogetherRenderer(this->root_chain,
this->highlights_chain,
this->background_chain);
PRINT("CSG generation finished.");
int s = t.elapsed() / 1000;
PRINTB("Total rendering time: %d hours, %d minutes, %d seconds", (s / (60*60)) % ((s / 60) % 60) % (s % 60));
if (procevents) QApplication::processEvents();
}
if (highlight_terms.size() > 0) {
PRINTB("Compiling highlights (%d CSG Trees)...", highlight_terms.size());
if (procevents) QApplication::processEvents();
highlights_chain = new CSGChain();
for (unsigned int i = 0; i < highlight_terms.size(); i++) {
highlight_terms[i] = normalizer.normalize(highlight_terms[i]);
highlights_chain->import(highlight_terms[i]);
}
}
if (background_terms.size() > 0) {
PRINTB("Compiling background (%d CSG Trees)...", background_terms.size());
if (procevents) QApplication::processEvents();
background_chain = new CSGChain();
for (unsigned int i = 0; i < background_terms.size(); i++) {
background_terms[i] = normalizer.normalize(background_terms[i]);
background_chain->import(background_terms[i]);
}
}
if (this->root_chain &&
(this->root_chain->objects.size() >
Preferences::inst()->getValue("advanced/openCSGLimit").toUInt())) {
PRINTB("WARNING: Normalized tree has %d elements!", this->root_chain->objects.size());
PRINT("WARNING: OpenCSG rendering has been disabled.");
}
else {
PRINTB("Normalized CSG tree has %d elements",
(this->root_chain ? this->root_chain->objects.size() : 0));
this->opencsgRenderer = new OpenCSGRenderer(this->root_chain,
this->highlights_chain,
this->background_chain,
this->qglview->shaderinfo);
}
this->thrownTogetherRenderer = new ThrownTogetherRenderer(this->root_chain,
this->highlights_chain,
this->background_chain);
PRINT("CSG generation finished.");
int s = t.elapsed() / 1000;
PRINTB("Total rendering time: %d hours, %d minutes, %d seconds", (s / (60*60)) % ((s / 60) % 60) % (s % 60));
if (procevents) QApplication::processEvents();
}
void MainWindow::actionUpdateCheck()
@ -1781,6 +1827,7 @@ void MainWindow::actionRenderDone(shared_ptr<const Geometry> root_geom)
this->statusBar()->removeWidget(this->progresswidget);
delete this->progresswidget;
this->progresswidget = NULL;
this->contentschanged = false;
compileEnded();
}
@ -1887,6 +1934,18 @@ void MainWindow::actionExport(export_type_e, QString, QString)
return;
}
// editor has changed since last F6
if (this->contentschanged) {
QMessageBox::StandardButton ret;
ret = QMessageBox::warning(this, "Application",
"The document has been modified since the last render (F6).\n"
"Do you really want to export the previous content?",
QMessageBox::Yes | QMessageBox::No);
if (ret != QMessageBox::Yes) {
return;
}
}
if (this->root_geom->getDimension() != 3) {
PRINT("Current top level object is not a 3D object.");
clearCurrentOutput();
@ -2265,25 +2324,13 @@ void MainWindow::viewAll()
this->qglview->updateGL();
}
void MainWindow::on_editorDock_visibilityChanged(bool visible)
void MainWindow::on_editorDock_visibilityChanged(bool)
{
if (isClosing) {
return;
}
QSettings settings;
settings.setValue("view/hideEditor", !visible);
viewActionHideEditor->setChecked(!visible);
editorTopLevelChanged(editorDock->isFloating());
}
void MainWindow::on_consoleDock_visibilityChanged(bool visible)
void MainWindow::on_consoleDock_visibilityChanged(bool)
{
if (isClosing) {
return;
}
QSettings settings;
settings.setValue("view/hideConsole", !visible);
viewActionHideConsole->setChecked(!visible);
consoleTopLevelChanged(consoleDock->isFloating());
}
@ -2309,7 +2356,11 @@ void MainWindow::setDockWidgetTitle(QDockWidget *dockWidget, QString prefix, boo
void MainWindow::hideToolbars()
{
if (viewActionHideToolBars->isChecked()) {
QSettings settings;
bool shouldHide = viewActionHideToolBars->isChecked();
settings.setValue("view/hideToolbar", shouldHide);
if (shouldHide) {
viewerToolBar->hide();
editortoolbar->hide();
} else {
@ -2453,7 +2504,6 @@ void MainWindow::closeEvent(QCloseEvent *event)
delete this->tempFile;
this->tempFile = NULL;
}
isClosing = true;
event->accept();
} else {
event->ignore();
@ -2522,3 +2572,8 @@ void MainWindow::openCSGSettingsChanged()
OpenCSG::Goldfeather : OpenCSG::Automatic);
#endif
}
void MainWindow::setContentsChanged()
{
this->contentschanged = true;
}

View File

@ -56,13 +56,6 @@
#include <sstream>
#ifdef __APPLE__
#include "AppleEvents.h"
#ifdef OPENSCAD_DEPLOY
#include "SparkleAutoUpdater.h"
#endif
#endif
#include "Camera.h"
#include <boost/algorithm/string.hpp>
#include <boost/program_options.hpp>
@ -70,6 +63,13 @@
#include <boost/foreach.hpp>
#include "boosty.h"
#ifdef __APPLE__
#include "AppleEvents.h"
#ifdef OPENSCAD_DEPLOY
#include "SparkleAutoUpdater.h"
#endif
#endif
#ifdef _MSC_VER
#define snprintf _snprintf
#endif
@ -590,9 +590,9 @@ int gui(vector<string> &inputFiles, const fs::path &original_path, int argc, cha
#endif
#if defined(OPENSCAD_DEPLOY) && defined(Q_OS_MAC)
AutoUpdater *updater = new SparkleAutoUpdater;
AutoUpdater::setUpdater(updater);
if (updater->automaticallyChecksForUpdates()) updater->checkForUpdates();
// AutoUpdater *updater = new SparkleAutoUpdater;
// AutoUpdater::setUpdater(updater);
// if (updater->automaticallyChecksForUpdates()) updater->checkForUpdates();
#endif
#if 0 /*** disabled by clifford wolf: adds rendering artefacts with OpenCSG ***/

View File

@ -1,5 +1,4 @@
#include "rendersettings.h"
#include "colormap.h"
#include "printutils.h"
RenderSettings *RenderSettings::inst(bool erase)

View File

@ -2,7 +2,6 @@
#include <map>
#include "linalg.h"
#include "colormap.h"
class RenderSettings
{

View File

@ -4,6 +4,45 @@
#include "scintillaeditor.h"
#include <Qsci/qscicommandset.h>
#include "Preferences.h"
#include "PlatformUtils.h"
EditorColorScheme::EditorColorScheme(fs::path path) : path(path)
{
try {
boost::property_tree::read_json(boosty::stringy(path).c_str(), pt);
_name = QString(pt.get<std::string>("name").c_str());
_index = pt.get<int>("index");
} catch (const std::exception & e) {
PRINTB("Error reading color scheme file '%s': %s", path.c_str() % e.what());
_name = "";
_index = 0;
}
}
EditorColorScheme::~EditorColorScheme()
{
}
bool EditorColorScheme::valid() const
{
return !_name.isEmpty();
}
const QString & EditorColorScheme::name() const
{
return _name;
}
int EditorColorScheme::index() const
{
return _index;
}
const boost::property_tree::ptree & EditorColorScheme::propertyTree() const
{
return pt;
}
ScintillaEditor::ScintillaEditor(QWidget *parent) : EditorInterface(parent)
{
@ -51,7 +90,6 @@ ScintillaEditor::ScintillaEditor(QWidget *parent) : EditorInterface(parent)
initMargin();
qsci->setFolding(QsciScintilla::BoxedTreeFoldStyle, 4);
qsci->setCaretLineVisible(true);
this->setHighlightScheme(Preferences::inst()->getValue("editor/syntaxhighlight").toString());
connect(qsci, SIGNAL(textChanged()), this, SIGNAL(contentsChanged()));
connect(qsci, SIGNAL(modificationChanged(bool)), this, SIGNAL(modificationChanged(bool)));
@ -87,7 +125,6 @@ void ScintillaEditor::highlightError(int error_pos)
int line, index;
qsci->lineIndexFromPosition(error_pos, &line, &index);
qsci->fillIndicatorRange(line, index, line, index+1, indicatorNumber);
qsci->setIndicatorForegroundColor(QColor(255,0,0,100));
qsci->markerAdd(line, markerNumber);
}
@ -100,115 +137,155 @@ void ScintillaEditor::unhighlightLastError()
qsci->markerDeleteAll(markerNumber);
}
//Editor themes
void ScintillaEditor::forLightBackground()
QColor ScintillaEditor::readColor(const boost::property_tree::ptree &pt, const std::string name, const QColor defaultColor)
{
lexer->setPaper("#fff");
lexer->setColor(QColor("#272822")); // -> Style: Default text
lexer->setColor(QColor("Green"), QsciLexerCPP::Keyword); // -> Style: Keyword
lexer->setColor(QColor("Green"), QsciLexerCPP::KeywordSet2); // -> Style: KeywordSet2
lexer->setColor(Qt::blue, QsciLexerCPP::CommentDocKeyword); // -> used in comments only like /*! \cube */
lexer->setColor(QColor("DarkBlue"), QsciLexerCPP::GlobalClass); // -> Style: GlobalClass
lexer->setColor(Qt::blue, QsciLexerCPP::Operator);
lexer->setColor(Qt::darkMagenta, QsciLexerCPP::DoubleQuotedString);
lexer->setColor(Qt::darkCyan, QsciLexerCPP::Comment);
lexer->setColor(Qt::darkCyan, QsciLexerCPP::CommentLine);
lexer->setColor(QColor("DarkRed"), QsciLexerCPP::Number);
qsci->setMarkerBackgroundColor(QColor(255, 0, 0, 100), markerNumber);
qsci->setCaretLineBackgroundColor(QColor("#ffe4e4"));
qsci->setMarginsBackgroundColor(QColor("#ccc"));
qsci->setMarginsForegroundColor(QColor("#111"));
qsci->setMatchedBraceBackgroundColor(QColor("#333"));
qsci->setMatchedBraceForegroundColor(QColor("#fff"));
try {
const std::string val = pt.get<std::string>(name);
return QColor(val.c_str());
} catch (std::exception e) {
return defaultColor;
}
}
void ScintillaEditor::forDarkBackground()
int ScintillaEditor::readInt(const boost::property_tree::ptree &pt, const std::string name, const int defaultValue)
{
lexer->setPaper(QColor("#272822"));
lexer->setColor(QColor(Qt::white));
lexer->setColor(QColor("#f12971"), QsciLexerCPP::Keyword);
lexer->setColor(QColor("#56dbf0"),QsciLexerCPP::KeywordSet2);
lexer->setColor(QColor("#ccdf32"), QsciLexerCPP::CommentDocKeyword);
lexer->setColor(QColor("#56d8f0"), QsciLexerCPP::GlobalClass);
lexer->setColor(QColor("#d8d8d8"), QsciLexerCPP::Operator);
lexer->setColor(QColor("#e6db74"), QsciLexerCPP::DoubleQuotedString);
lexer->setColor(QColor("#e6db74"), QsciLexerCPP::CommentLine);
lexer->setColor(QColor("#af7dff"), QsciLexerCPP::Number);
qsci->setCaretLineBackgroundColor(QColor(104,225,104, 127));
qsci->setMarkerBackgroundColor(QColor(255, 0, 0, 100), markerNumber);
qsci->setMarginsBackgroundColor(QColor("20,20,20,150"));
qsci->setMarginsForegroundColor(QColor("#fff"));
qsci->setCaretWidth(2);
qsci->setCaretForegroundColor(QColor("#ffff00"));
try {
const int val = pt.get<int>(name);
return val;
} catch (std::exception e) {
return defaultValue;
}
}
void ScintillaEditor::Monokai()
void ScintillaEditor::setColormap(const EditorColorScheme *colorScheme)
{
lexer->setPaper("#272822");
lexer->setColor(QColor("#f8f8f2")); // -> Style: Default text
lexer->setColor(QColor("#66c3b3"), QsciLexerCPP::Keyword); // -> Style: Keyword
lexer->setColor(QColor("#79abff"), QsciLexerCPP::KeywordSet2); // -> Style: KeywordSet2
lexer->setColor(QColor("#ccdf32"), QsciLexerCPP::CommentDocKeyword); // -> used in comments only like /*! \cube */
lexer->setColor(QColor("#ffffff"), QsciLexerCPP::GlobalClass); // -> Style: GlobalClass
lexer->setColor(QColor("#d8d8d8"), QsciLexerCPP::Operator);
lexer->setColor(QColor("#e6db74"), QsciLexerCPP::DoubleQuotedString);
lexer->setColor(QColor("#75715e"), QsciLexerCPP::CommentLine);
lexer->setColor(QColor("#7fb347"), QsciLexerCPP::Number);
qsci->setMarkerBackgroundColor(QColor(255, 0, 0, 100), markerNumber);
qsci->setCaretLineBackgroundColor(QColor("#3e3d32"));
qsci->setMarginsBackgroundColor(QColor("#757575"));
qsci->setMarginsForegroundColor(QColor("#f8f8f2"));
qsci->setCaretWidth(2);
qsci->setCaretForegroundColor(QColor("#ffff00"));
}
const boost::property_tree::ptree & pt = colorScheme->propertyTree();
void ScintillaEditor::Solarized_light()
{
lexer->setPaper("#fdf6e3");
lexer->setColor(QColor("#657b83")); // -> Style: Default text
lexer->setColor(QColor("#268ad1"), QsciLexerCPP::Keyword); // -> Style: Keyword
lexer->setColor(QColor("#6c71c4"), QsciLexerCPP::KeywordSet2); // -> Style: KeywordSet2
lexer->setColor(QColor("#b58900"), QsciLexerCPP::CommentDocKeyword); // -> used in comments only like /*! \cube */
lexer->setColor(QColor("#b58800"), QsciLexerCPP::GlobalClass); // -> Style: GlobalClass
lexer->setColor(QColor("#859900"), QsciLexerCPP::Operator);
lexer->setColor(QColor("#2aa198"), QsciLexerCPP::DoubleQuotedString);
lexer->setColor(QColor("#b58800"), QsciLexerCPP::CommentLine);
lexer->setColor(QColor("#cb4b16"), QsciLexerCPP::Number);
qsci->setMarkerBackgroundColor(QColor(255, 0, 0, 100), markerNumber);
qsci->setCaretLineBackgroundColor(QColor("#eeead5"));
qsci->setMarginsBackgroundColor(QColor("#eee8d5"));
qsci->setMarginsForegroundColor(QColor("#93a1a1"));
qsci->setMatchedBraceBackgroundColor(QColor("#0000ff"));
qsci->setMatchedBraceBackgroundColor(QColor("#333"));
qsci->setMatchedBraceForegroundColor(QColor("#fff"));
try {
const QColor textColor(pt.get<std::string>("text").c_str());
const QColor paperColor(pt.get<std::string>("paper").c_str());
lexer->setColor(textColor);
lexer->setPaper(paperColor);
const boost::property_tree::ptree& colors = pt.get_child("colors");
lexer->setColor(readColor(colors, "keyword1", textColor), QsciLexerCPP::Keyword);
lexer->setColor(readColor(colors, "keyword2", textColor), QsciLexerCPP::KeywordSet2);
lexer->setColor(readColor(colors, "keyword3", textColor), QsciLexerCPP::GlobalClass);
lexer->setColor(readColor(colors, "comment", textColor), QsciLexerCPP::CommentDocKeyword);
lexer->setColor(readColor(colors, "number", textColor), QsciLexerCPP::Number);
lexer->setColor(readColor(colors, "string", textColor), QsciLexerCPP::DoubleQuotedString);
lexer->setColor(readColor(colors, "operator", textColor), QsciLexerCPP::Operator);
lexer->setColor(readColor(colors, "commentline", textColor), QsciLexerCPP::CommentLine);
const boost::property_tree::ptree& caret = pt.get_child("caret");
qsci->setCaretWidth(readInt(caret, "width", 1));
qsci->setCaretForegroundColor(readColor(caret, "foreground", textColor));
qsci->setCaretLineBackgroundColor(readColor(caret, "line-background", paperColor));
qsci->setMarkerBackgroundColor(readColor(colors, "error-marker", QColor(255, 0, 0, 100)), markerNumber);
qsci->setMarginsBackgroundColor(readColor(colors, "margin-background", paperColor));
qsci->setMarginsForegroundColor(readColor(colors, "margin-foreground", textColor));
qsci->setMatchedBraceBackgroundColor(readColor(colors, "matched-brace-background", paperColor));
qsci->setMatchedBraceForegroundColor(readColor(colors, "matched-brace-foreground", textColor));
qsci->setUnmatchedBraceBackgroundColor(readColor(colors, "unmatched-brace-background", paperColor));
qsci->setUnmatchedBraceForegroundColor(readColor(colors, "unmatched-brace-foreground", textColor));
qsci->setSelectionForegroundColor(readColor(colors, "selection-foreground", paperColor));
qsci->setSelectionBackgroundColor(readColor(colors, "selection-background", textColor));
qsci->setFoldMarginColors(readColor(colors, "margin-foreground", textColor),
readColor(colors, "margin-background", paperColor));
qsci->setEdgeColor(readColor(colors, "edge", textColor));
} catch (std::exception e) {
noColor();
}
}
void ScintillaEditor::noColor()
{
lexer->setPaper(Qt::white);
lexer->setColor(Qt::black);
qsci->setMarginsBackgroundColor(QColor("#ccc"));
qsci->setMarginsForegroundColor(QColor("#111"));
lexer->setPaper(Qt::white);
lexer->setColor(Qt::black);
qsci->setCaretWidth(2);
qsci->setCaretForegroundColor(Qt::black);
qsci->setMarkerBackgroundColor(QColor(255, 0, 0, 100), markerNumber);
qsci->setCaretLineBackgroundColor(Qt::white);
qsci->setMarginsBackgroundColor(Qt::white);
qsci->setMarginsForegroundColor(Qt::black);
qsci->setSelectionForegroundColor(Qt::white);
qsci->setSelectionBackgroundColor(Qt::black);
qsci->setMatchedBraceBackgroundColor(Qt::white);
qsci->setMatchedBraceForegroundColor(Qt::black);
qsci->setUnmatchedBraceBackgroundColor(Qt::white);
qsci->setUnmatchedBraceForegroundColor(Qt::black);
qsci->setMarginsBackgroundColor(Qt::lightGray);
qsci->setMarginsForegroundColor(Qt::black);
qsci->setFoldMarginColors(Qt::black, Qt::lightGray);
qsci->setEdgeColor(Qt::black);
}
void ScintillaEditor::enumerateColorSchemesInPath(ScintillaEditor::colorscheme_set_t &result_set, const fs::path path)
{
const fs::path color_schemes = path / "color-schemes" / "editor";
fs::directory_iterator end_iter;
if (fs::exists(color_schemes) && fs::is_directory(color_schemes)) {
for (fs::directory_iterator dir_iter(color_schemes); dir_iter != end_iter; ++dir_iter) {
if (!fs::is_regular_file(dir_iter->status())) {
continue;
}
const fs::path path = (*dir_iter).path();
if (!(path.extension().string() == ".json")) {
continue;
}
EditorColorScheme *colorScheme = new EditorColorScheme(path);
if (colorScheme->valid()) {
result_set.insert(colorscheme_set_t::value_type(colorScheme->index(), boost::shared_ptr<EditorColorScheme>(colorScheme)));
} else {
delete colorScheme;
}
}
}
}
ScintillaEditor::colorscheme_set_t ScintillaEditor::enumerateColorSchemes()
{
colorscheme_set_t result_set;
enumerateColorSchemesInPath(result_set, PlatformUtils::resourcesPath());
enumerateColorSchemesInPath(result_set, PlatformUtils::userConfigPath());
return result_set;
}
QStringList ScintillaEditor::colorSchemes()
{
const colorscheme_set_t colorscheme_set = enumerateColorSchemes();
QStringList colorSchemes;
for (colorscheme_set_t::const_iterator it = colorscheme_set.begin();it != colorscheme_set.end();it++) {
colorSchemes << (*it).second.get()->name();
}
colorSchemes << "Off";
return colorSchemes;
}
void ScintillaEditor::setHighlightScheme(const QString &name)
{
if(name == "For Light Background") {
forLightBackground();
}
else if(name == "For Dark Background") {
forDarkBackground();
}
else if(name == "Monokai") {
Monokai();
}
else if(name == "Solarized") {
Solarized_light();
}
else if(name == "Off") {
const colorscheme_set_t colorscheme_set = enumerateColorSchemes();
for (colorscheme_set_t::const_iterator it = colorscheme_set.begin();it != colorscheme_set.end();it++) {
const EditorColorScheme *colorScheme = (*it).second.get();
if (colorScheme->name() == name) {
setColormap(colorScheme);
return;
}
}
noColor();
}
}
void ScintillaEditor::insert(const QString &text)
@ -307,7 +384,7 @@ void ScintillaEditor::replaceSelectedText(const QString &newText)
if (qsci->selectedText() != newText) qsci->replaceSelectedText(newText);
}
void ScintillaEditor::get_range(int *lineFrom, int *lineTo)
void ScintillaEditor::getRange(int *lineFrom, int *lineTo)
{
int indexFrom, indexTo;
if (qsci->hasSelectedText()) {
@ -324,7 +401,7 @@ void ScintillaEditor::get_range(int *lineFrom, int *lineTo)
void ScintillaEditor::indentSelection()
{
int lineFrom, lineTo;
get_range(&lineFrom, &lineTo);
getRange(&lineFrom, &lineTo);
for (int line = lineFrom;line <= lineTo;line++) {
qsci->indent(line);
}
@ -333,7 +410,7 @@ void ScintillaEditor::indentSelection()
void ScintillaEditor::unindentSelection()
{
int lineFrom, lineTo;
get_range(&lineFrom, &lineTo);
getRange(&lineFrom, &lineTo);
for (int line = lineFrom;line <= lineTo;line++) {
qsci->unindent(line);
}
@ -344,7 +421,7 @@ void ScintillaEditor::commentSelection()
bool hasSelection = qsci->hasSelectedText();
int lineFrom, lineTo;
get_range(&lineFrom, &lineTo);
getRange(&lineFrom, &lineTo);
for (int line = lineFrom;line <= lineTo;line++) {
qsci->insertAt("//", line, 0);
}
@ -359,7 +436,7 @@ void ScintillaEditor::uncommentSelection()
bool hasSelection = qsci->hasSelectedText();
int lineFrom, lineTo;
get_range(&lineFrom, &lineTo);
getRange(&lineFrom, &lineTo);
for (int line = lineFrom;line <= lineTo;line++) {
QString lineText = qsci->text(line);
if (lineText.startsWith("//")) {

View File

@ -1,16 +1,46 @@
#pragma once
#include <QMap>
#include <QObject>
#include <QString>
#include <QWidget>
#include <QVBoxLayout>
#include <Qsci/qsciscintilla.h>
#include <QVBoxLayout>
#include "editor.h"
#include "scadlexer.h"
#include "parsersettings.h"
#include <boost/shared_ptr.hpp>
#include <boost/property_tree/ptree.hpp>
#include <boost/property_tree/json_parser.hpp>
class EditorColorScheme
{
private:
const fs::path path;
boost::property_tree::ptree pt;
QString _name;
int _index;
public:
EditorColorScheme(const fs::path path);
virtual ~EditorColorScheme();
const QString & name() const;
int index() const;
bool valid() const;
const boost::property_tree::ptree & propertyTree() const;
};
class ScintillaEditor : public EditorInterface
{
{
Q_OBJECT;
typedef std::multimap<int, boost::shared_ptr<EditorColorScheme>, std::less<int> > colorscheme_set_t;
public:
ScintillaEditor(QWidget *parent);
virtual ~ScintillaEditor() {}
@ -18,17 +48,19 @@ public:
QString toPlainText();
void initMargin();
void initLexer();
void forLightBackground();
void forDarkBackground();
void Monokai();
void Solarized_light();
void noColor();
QString selectedText();
bool find(const QString &, bool findNext = false, bool findBackwards = false);
void replaceSelectedText(const QString&);
QStringList colorSchemes();
private:
void get_range(int *lineFrom, int *lineTo);
void getRange(int *lineFrom, int *lineTo);
void setColormap(const EditorColorScheme *colorScheme);
int readInt(const boost::property_tree::ptree &pt, const std::string name, const int defaultValue);
QColor readColor(const boost::property_tree::ptree &pt, const std::string name, const QColor defaultColor);
void enumerateColorSchemesInPath(colorscheme_set_t &result_set, const fs::path path);
colorscheme_set_t enumerateColorSchemes();
public slots:
void zoomIn();

View File

@ -46,6 +46,20 @@ translate([0,-12,0]) intersection() {
cube(0);
}
// Intersecting something with nothing (issue 996)
translate([0,-12,0]) intersection() {
cube(4, center=true);
linear_extrude();
}
translate([0,-16,0]) intersection() {
cube(4, center=true);
render();
}
translate([0,-20,0]) intersection() {
cube(4, center=true);
minkowski();
}
// Intersecting 2D with 3D
translate([12,-12,0]) intersection() {
cube([5,5,5], center=true);

16
testdata/scad/bugs/issue1000.scad vendored Normal file
View File

@ -0,0 +1,16 @@
//
// CSG rendering issue:
// This results in a blue sphere rather than a sphere consisting of red/blue half spheres
// The reason is likely that OpenCSG doesn't track
// which positive object is the source of what depth fragment and thus lets the last rendered object win.
//
color([1,0,0]) translate([0,0,0]) intersection() {
sphere(10);
translate([0,0,10]) cube([20,20,20],center=true);
}
color([0,0,1]) difference() {
sphere(10);
translate([0,0,10]) cube([20,20,20],center=true);
}

2
testdata/scad/bugs/issue1004.scad vendored Normal file
View File

@ -0,0 +1,2 @@
%square(20);
cube(10);

1
testdata/scad/bugs/issue1005.scad vendored Normal file
View File

@ -0,0 +1 @@
%sphere(10);

10
testdata/scad/bugs/issue791.scad vendored Normal file
View File

@ -0,0 +1,10 @@
difference() {
linear_extrude(height = 2, twist = 0, convexity=2) {
polygon(points = [[0, 0],
[1, -1],
[2, 0.2],
[2, -0.2],
[1, 1]]);
}
cube(center=true);
}

View File

@ -1,6 +1,3 @@
union() {
cube(5);
translate([ 88.7-5, 87-10, -34-1]) cube(5);
polyhedron( points = [
[153.898,59.513,-32.4658] ,
[163.267,30.683,-34.429] ,
@ -109,86 +106,70 @@ union() {
[8,9,14] ,
[8,19,23] ,
]);
translate([0,0,0]) polyhedron( points = [
[153.898,59.513,-32.4658] ,
[163.267,30.683,-34.429] ,
[175.611,59.513,-24.8805] ,
[184.981,30.683,-26.8437] ,
[166.57,-1.77636e-15,-35.1211] ,
[188.284,-1.77636e-15,-27.5359] ,
[163.267,-30.683,-34.429] ,
[184.981,-30.683,-26.8437] ,
[153.898,-59.513,-32.4658] ,
[175.611,-59.513,-24.8805] ,
[181.898,59.513,-27.7158] ,
[191.267,30.683,-29.679] ,
[194.57,-1.77636e-15,-30.3711] ,
[191.267,-30.683,-29.679] ,
[181.898,-59.513,-27.7158] ,
[163.961,59.513,-33.9819] ,
[173.33,30.683,-35.9451] ,
[176.633,-1.77636e-15,-36.6372] ,
[173.33,-30.683,-35.9451] ,
[163.961,-59.513,-33.9819] ,
[148.845,69.513,-31.6884] ,
polyhedron( points = [
[0,0,0],
[148.845,-69.513,-31.6884] ,
[148.845,74.513,-31.6884] ,
[0,0,0],
[148.845,-74.513,-31.6884] ,
[162.25,59.513,-45.946] ,
[162.25,-59.513,-45.946] ,
[0,0,0],
[0,0,0],
[147.116,-74.513,-43.7824] ,
[147.116,74.513,-43.7824] ,
[0,0,0],
[80.3015,-54.0118,-33.5692] ,
[147.116,-69.513,-43.7824] ,
[80.3015,-59.0118,-33.5692] ,
[81.2307,-54.0118,-27.0692] ,
[81.2307,-59.0118,-27.0692] ,
[2.52448,-36,-22.6917] ,
[80.054,-54.0118,-33.5338] ,
[80.054,-59.0118,-33.5338] ,
[2.52448,-41,-22.6917] ,
[80.9832,-59.0118,-27.0338] ,
[80.9832,-54.0118,-27.0338] ,
[2.666,-36,-21.7018] ,
[2.666,-41,-21.7018] ,
[0,0,0],
[0,0,0],
[0,0,0],
[0,0,0],
[0,0,0],
[0,0,0],
[0,0,0],
[0,0,0],
[147.116,69.513,-43.7824] ,
[80.3015,59.0998,-33.5692] ,
[80.3015,64.0998,-33.5692] ,
[81.2307,59.0998,-27.0692] ,
[81.2307,64.0998,-27.0692] ,
[80.054,64.0998,-33.5338] ,
[80.054,59.0998,-33.5338] ,
[2.52448,47,-22.6917] ,
[2.52448,52,-22.6917] ,
[2.666,47,-21.7018] ,
[80.9832,59.0998,-27.0338] ,
[80.9832,64.0998,-27.0338] ,
[2.666,52,-21.7018] ,
[0,0,0],
[0,0,0],
[0,0,0],
[0,0,0],
[0,0,0],
[0,0,0],
[0,0,0],
[0,0,0],
[148.845,69.513,-31.6884] ,
[148.845,74.513,-31.6884] ,
[147.116,74.513,-43.7824] ,
],
faces = [
[26,29,28] ,
[26,28,30] ,
[31,21,23] ,
[32,31,23] ,
[23,26,30] ,
[23,30,32] ,
[28,32,30] ,
[28,29,21] ,
[31,28,21] ,
[28,31,32] ,
[22,20,44] ,
[22,44,45] ,
[20,42,44] ,
[45,44,42] ,
[43,45,42] ,
[42,41,27] ,
[43,42,27] ,
[20,41,42] ,
[43,27,22] ,
[45,43,22] ,
[41,22,27] ,
[20,22,41] ,
[26,23,29] ,
[29,23,21] ,
[6,9,8] ,
[6,8,10] ,
[11,1,3] ,
[12,11,3] ,
[3,6,10] ,
[3,10,12] ,
[8,12,10] ,
[8,9,1] ,
[11,8,1] ,
[8,11,12] ,
[6,3,9] ,
[9,3,1] ,
[35,34,24] ,
[35,24,25] ,
[34,22,24] ,
[25,24,22] ,
[23,25,22] ,
[22,21,36] ,
[23,22,36] ,
[34,21,22] ,
[23,36,25] ,
[25,36,35] ,
[21,35,36] ,
[34,35,21] ,
]);
}

2
testdata/scad/bugs/issue945.scad vendored Normal file
View File

@ -0,0 +1,2 @@
rotate([0, 45, 0]) cube(50, true);
rotate([0, 0, 45]) cube(50, true);

8
testdata/scad/bugs/issue990.scad vendored Normal file
View File

@ -0,0 +1,8 @@
hull() {
for (i = [0:1]) {
cylinder(h=0);
}
}
translate([-5, 0, 0]) cube();
translate([5, 0, 0]) cube();

View File

@ -0,0 +1,10 @@
module letter(c) {
text(c, size = 50, font = "Liberation Sans", halign = "center", valign = "center");
}
linear_extrude(height = 10) {
letter("C", $fn=8);
translate([50,0]) letter("C", $fn=16);
translate([0,50]) letter("C", $fn=24);
translate([50,50]) letter("C", $fn=32);
}

View File

@ -1086,7 +1086,8 @@ list(APPEND CGALPNGTEST_3D_FILES ${CMAKE_SOURCE_DIR}/../testdata/scad/misc/inclu
${CMAKE_SOURCE_DIR}/../testdata/scad/misc/bad-stl-pcbvicebar.scad
${CMAKE_SOURCE_DIR}/../testdata/scad/misc/bad-stl-tardis.scad
${CMAKE_SOURCE_DIR}/../testdata/scad/misc/bad-stl-wing.scad
${CMAKE_SOURCE_DIR}/../testdata/scad/misc/rotate_extrude-hole.scad)
${CMAKE_SOURCE_DIR}/../testdata/scad/misc/rotate_extrude-hole.scad
${CMAKE_SOURCE_DIR}/../testdata/scad/experimental/tessellation-text-test.scad)
list(APPEND CGALPNGTEST_FILES ${CGALPNGTEST_2D_FILES} ${CGALPNGTEST_3D_FILES})
list(APPEND OPENCSGTEST_FILES ${CGALPNGTEST_FILES})
@ -1197,6 +1198,7 @@ set_test_config(Heavy cgalpngtest_rotate_extrude-tests
list(APPEND BUGS_FILES ${CMAKE_SOURCE_DIR}/../testdata/scad/bugs/issue584.scad
${CMAKE_SOURCE_DIR}/../testdata/scad/bugs/issue591.scad
${CMAKE_SOURCE_DIR}/../testdata/scad/bugs/issue666.scad
${CMAKE_SOURCE_DIR}/../testdata/scad/bugs/issue791.scad
${CMAKE_SOURCE_DIR}/../testdata/scad/bugs/issue802.scad
${CMAKE_SOURCE_DIR}/../testdata/scad/bugs/issue835.scad
${CMAKE_SOURCE_DIR}/../testdata/scad/bugs/issue899.scad
@ -1204,8 +1206,12 @@ list(APPEND BUGS_FILES ${CMAKE_SOURCE_DIR}/../testdata/scad/bugs/issue584.scad
${CMAKE_SOURCE_DIR}/../testdata/scad/bugs/issue911.scad
${CMAKE_SOURCE_DIR}/../testdata/scad/bugs/issue913.scad
${CMAKE_SOURCE_DIR}/../testdata/scad/bugs/issue936.scad
${CMAKE_SOURCE_DIR}/../testdata/scad/bugs/issue945.scad
${CMAKE_SOURCE_DIR}/../testdata/scad/bugs/issue964.scad
${CMAKE_SOURCE_DIR}/../testdata/scad/bugs/issue964b.scad)
${CMAKE_SOURCE_DIR}/../testdata/scad/bugs/issue964b.scad
${CMAKE_SOURCE_DIR}/../testdata/scad/bugs/issue990.scad
${CMAKE_SOURCE_DIR}/../testdata/scad/bugs/issue1004.scad
${CMAKE_SOURCE_DIR}/../testdata/scad/bugs/issue1005.scad)
list(APPEND EXPORT3D_TEST_FILES ${BUGS_FILES})
list(APPEND OPENCSGTEST_FILES ${BUGS_FILES})

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.7 KiB

After

Width:  |  Height:  |  Size: 7.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.1 KiB

After

Width:  |  Height:  |  Size: 7.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

View File

@ -60,6 +60,24 @@ group() {
cube(size = [0, 0, 0], center = false);
}
}
multmatrix([[1, 0, 0, 0], [0, 1, 0, -12], [0, 0, 1, 0], [0, 0, 0, 1]]) {
intersection() {
cube(size = [4, 4, 4], center = true);
linear_extrude(height = 100, center = false, convexity = 1, scale = [1, 1], $fn = 0, $fa = 12, $fs = 2);
}
}
multmatrix([[1, 0, 0, 0], [0, 1, 0, -16], [0, 0, 1, 0], [0, 0, 0, 1]]) {
intersection() {
cube(size = [4, 4, 4], center = true);
render(convexity = 1);
}
}
multmatrix([[1, 0, 0, 0], [0, 1, 0, -20], [0, 0, 1, 0], [0, 0, 0, 1]]) {
intersection() {
cube(size = [4, 4, 4], center = true);
minkowski(convexity = 0);
}
}
multmatrix([[1, 0, 0, 12], [0, 1, 0, -12], [0, 0, 1, 0], [0, 0, 0, 1]]) {
intersection() {
cube(size = [5, 5, 5], center = true);

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 17 KiB

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 24 KiB

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.2 KiB

After

Width:  |  Height:  |  Size: 7.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.1 KiB

After

Width:  |  Height:  |  Size: 7.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

View File

@ -9,6 +9,11 @@
# Any generated output is written to the file `basename <argument`-actual.<suffix>
# Any warning or errors are written to stderr.
#
# The test is run with OPENSCAD_FONT_PATH set to the testdata/ttf directory. This
# should ensure we fetch the fonts from there even if they are also installed
# on the system. (E.g. the C glyph is actually different from Debian/Jessie
# installation and what we ship as Liberation-2.00.1).
#
# Returns 0 on passed test
# 1 on error
# 2 on invalid cmd-line options
@ -195,8 +200,12 @@ def run_test(testname, cmd, args):
try:
cmdline = [cmd] + args + [outputname]
print 'run_test() cmdline:',cmdline
fontdir = os.path.join(os.path.dirname(cmd), "..", "testdata")
fontenv = os.environ.copy()
fontenv["OPENSCAD_FONT_PATH"] = fontdir
print 'using font directory:', fontdir
sys.stdout.flush()
proc = subprocess.Popen(cmdline, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
proc = subprocess.Popen(cmdline, env = fontenv, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
comresult = proc.communicate()
stdouttext, errtext = comresult[0],comresult[1]
if errtext != None and len(errtext) > 0:
@ -206,7 +215,6 @@ def run_test(testname, cmd, args):
outfile.close()
if proc.returncode != 0:
print >> sys.stderr, "Error: %s failed with return code %d" % (cmdname, proc.returncode)
return None
return outputname
except OSError, err:

View File

@ -638,7 +638,7 @@
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "rm -rf \"$BUILT_PRODUCTS_DIR/$FULL_PRODUCT_NAME\"\ncp -Rf \"$PROJECT_DIR/../$FULL_PRODUCT_NAME\" \"$PROJECT_DIR/../libraries\" \"$PROJECT_DIR/../examples\" \"$PROJECT_DIR/../fonts\" \"$BUILT_PRODUCTS_DIR\"";
shellScript = "rm -rf \"$BUILT_PRODUCTS_DIR/$FULL_PRODUCT_NAME\"\ncp -Rf \"$PROJECT_DIR/../$FULL_PRODUCT_NAME\" \"$PROJECT_DIR/../libraries\" \"$PROJECT_DIR/../examples\" \"$PROJECT_DIR/../fonts\" \"$PROJECT_DIR/../color-schemes\" \"$BUILT_PRODUCTS_DIR\"";
};
E0395E7C19AA884F00E43D12 /* ShellScript */ = {
isa = PBXShellScriptBuildPhase;
@ -651,7 +651,7 @@
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "rm -rf \"$BUILT_PRODUCTS_DIR/$FULL_PRODUCT_NAME\"\ncp -Rf \"$PROJECT_DIR/../tests/$FULL_PRODUCT_NAME\" \"$PROJECT_DIR/../libraries\" \"$PROJECT_DIR/../examples\" \"$PROJECT_DIR/../fonts\" \"$BUILT_PRODUCTS_DIR\"";
shellScript = "rm -rf \"$BUILT_PRODUCTS_DIR/$FULL_PRODUCT_NAME\"\ncp -Rf \"$PROJECT_DIR/../tests/$FULL_PRODUCT_NAME\" \"$PROJECT_DIR/../libraries\" \"$PROJECT_DIR/../examples\" \"$PROJECT_DIR/../fonts\" \"$PROJECT_DIR/../color-schemes\" \"$BUILT_PRODUCTS_DIR\"";
};
/* End PBXShellScriptBuildPhase section */