Merge remote-tracking branch 'origin/master' into c++11

master
Marius Kintel 2014-11-25 17:13:01 -05:00
commit 437aa69292
107 changed files with 1662 additions and 791 deletions

View File

@ -83,7 +83,7 @@ addons:
project:
name: "openscad/openscad"
description: "The Programmers Solid 3D CAD Modeller"
notification_email: torsten.paul@gmx.de
notification_email: dev@openscad.org
build_command_prepend: qmake
build_command: make
branch_pattern: coverity_scan

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

@ -29,6 +29,12 @@
<true/>
<key>BBLMColorsSyntax</key>
<true/>
<key>BBLMCommentLineDefault</key>
<string>//</string>
<key>BBLMCommentPrefixDefault</key>
<string>/*</string>
<key>BBLMCommentSuffixDefault</key>
<string>*/</string>
<key>BBLMIsCaseSensitive</key>
<true/>
<key>BBLMPredefinedNameList</key>

View File

@ -462,6 +462,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

@ -6,6 +6,7 @@
* min() and max() can now take a wvector argument
* concat()
* 2D minkowski and holes
* chr()
**Program Features:**
* Added --viewall cmd-line parameter
@ -14,6 +15,12 @@
* Qt5, retina
* SVG import/export
* AMF import/export
* Color schemes for viewer and editor can be user-edited
* Improved editor
* Splash screen
* Docking of GUI components
* Toolbar
* More robust STL export
**Bugfixes/improvements:**
* Internal cavity fix

View File

@ -13,6 +13,7 @@ File openscad.com
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 color-schemes
${registerExtension} "$INSTDIR\openscad.exe" ".scad" "OpenSCAD_File"
CreateShortCut $SMPROGRAMS\OpenSCAD.lnk $INSTDIR\openscad.exe
WriteUninstaller $INSTDIR\Uninstall.exe
@ -27,6 +28,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
Delete $INSTDIR\libraries\boxes.scad

View File

@ -771,7 +771,7 @@ 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

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

@ -326,12 +326,14 @@ case $OS in
EXAMPLESDIR=OpenSCAD.app/Contents/Resources/examples
LIBRARYDIR=OpenSCAD.app/Contents/Resources/libraries
FONTDIR=OpenSCAD.app/Contents/Resources/fonts
COLORSCHEMESDIR=OpenSCAD.app/Contents/Resources/color-schemes
;;
UNIX_CROSS_WIN)
cd $OPENSCADDIR
EXAMPLESDIR=$DEPLOYDIR/openscad-$VERSION/examples/
LIBRARYDIR=$DEPLOYDIR/openscad-$VERSION/libraries/
FONTDIR=$DEPLOYDIR/openscad-$VERSION/fonts/
COLORSCHEMESDIR=$DEPLOYDIR/openscad-$VERSION/color-schemes/
rm -rf $DEPLOYDIR/openscad-$VERSION
mkdir $DEPLOYDIR/openscad-$VERSION
;;
@ -339,6 +341,7 @@ case $OS in
EXAMPLESDIR=openscad-$VERSION/examples/
LIBRARYDIR=openscad-$VERSION/libraries/
FONTDIR=openscad-$VERSION/fonts/
COLORSCHEMESDIR=openscad-$VERSION/color-schemes/
rm -rf openscad-$VERSION
mkdir openscad-$VERSION
;;
@ -366,6 +369,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

@ -8,4 +8,5 @@ sparkle {
LIBS += -framework Sparkle
HEADERS += src/SparkleAutoUpdater.h
OBJECTIVE_SOURCES += src/SparkleAutoUpdater.mm
DEFINES += OPENSCAD_UPDATER
}

View File

@ -1,3 +1,23 @@
#include "AutoUpdater.h"
#include <QAction>
#include <QMenuBar>
AutoUpdater *AutoUpdater::updater_instance = NULL;
void AutoUpdater::init()
{
#ifdef OPENSCAD_UPDATER
if (!this->updateAction) {
QMenuBar *mb = new QMenuBar();
this->updateMenu = mb->addMenu("special");
this->updateAction = new QAction("Check for Update..", this);
// Add to application menu
this->updateAction->setMenuRole(QAction::ApplicationSpecificRole);
this->updateAction->setEnabled(true);
this->connect(this->updateAction, SIGNAL(triggered()), this, SLOT(checkForUpdates()));
this->updateMenu->addAction(this->updateAction);
}
#endif
}

View File

@ -1,22 +1,34 @@
#pragma once
#include <QString>
#include <QObject>
class AutoUpdater
class AutoUpdater : public QObject
{
Q_OBJECT;
public:
AutoUpdater() : updateAction(NULL) {}
virtual ~AutoUpdater() {}
virtual void checkForUpdates() = 0;
virtual void setAutomaticallyChecksForUpdates(bool on) = 0;
virtual bool automaticallyChecksForUpdates() = 0;
virtual void setEnableSnapshots(bool on) = 0;
virtual bool enableSnapshots() = 0;
virtual QString lastUpdateCheckDate() = 0;
virtual void init();
static AutoUpdater *updater() { return updater_instance; }
static void setUpdater(AutoUpdater *updater) { updater_instance = updater; }
public slots:
virtual void checkForUpdates() = 0;
public:
class QAction *updateAction;
class QMenu *updateMenu;
protected:
static AutoUpdater *updater_instance;
};

View File

@ -6,6 +6,7 @@
#endif
#include "version_check.h"
#include "PlatformUtils.h"
#define STRINGIFY(x) #x
#define TOSTRING(x) STRINGIFY(x)
@ -90,6 +91,12 @@ std::string LibraryInfo::info()
#endif
<< "\nMingW build: " << mingwstatus
<< "\nGLib version: " << GLIB_MAJOR_VERSION << "." << GLIB_MINOR_VERSION << "." << GLIB_MICRO_VERSION
<< "\nApplication Path: " << PlatformUtils::applicationPath()
<< "\nDocuments Path: " << PlatformUtils::documentsPath()
<< "\nResource Path: " << PlatformUtils::resourcesPath()
<< "\nUser Library Path: " << PlatformUtils::userLibraryPath()
<< "\nUser Config Path: " << PlatformUtils::userConfigPath()
<< "\nBackup Path: " << PlatformUtils::backupPath()
<< "\nOPENSCADPATH: " << (env_path == NULL ? "<not set>" : env_path)
<< "\nOpenSCAD library path:\n";

View File

@ -119,7 +119,6 @@ private:
class FontListDialog *font_list_dialog;
private slots:
void actionUpdateCheck();
void actionNew();
void actionOpen();
void actionOpenRecent();

View File

@ -15,7 +15,16 @@
<property name="spacing">
<number>0</number>
</property>
<property name="margin">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
@ -30,7 +39,16 @@
<property name="spacing">
<number>0</number>
</property>
<property name="margin">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
@ -64,7 +82,16 @@
<number>0</number>
</property>
<layout class="QHBoxLayout" name="horizontalLayoutAnimate">
<property name="margin">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
@ -143,7 +170,7 @@
<x>0</x>
<y>0</y>
<width>1397</width>
<height>33</height>
<height>22</height>
</rect>
</property>
<widget class="QMenu" name="menu_File">
@ -280,7 +307,6 @@
<addaction name="helpActionManual"/>
<addaction name="helpActionLibraryInfo"/>
<addaction name="helpActionFontInfo"/>
<addaction name="appActionUpdateCheck"/>
</widget>
<addaction name="menu_File"/>
<addaction name="menu_Edit"/>
@ -298,7 +324,16 @@
<property name="spacing">
<number>0</number>
</property>
<property name="margin">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
@ -418,7 +453,16 @@
</attribute>
<widget class="QWidget" name="consoleDockContents">
<layout class="QVBoxLayout" name="verticalLayout_5">
<property name="margin">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
@ -1013,14 +1057,6 @@
<string>Library info</string>
</property>
</action>
<action name="appActionUpdateCheck">
<property name="enabled">
<bool>false</bool>
</property>
<property name="text">
<string>Check for Update..</string>
</property>
</action>
<action name="fileShowLibraryFolder">
<property name="text">
<string>Show Library Folder...</string>

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

@ -11,16 +11,70 @@ extern std::vector<std::string> librarypath;
extern std::vector<std::string> fontpath;
namespace {
bool path_initialized = false;
std::string applicationpath;
std::string resourcespath;
}
const char *PlatformUtils::OPENSCAD_FOLDER_NAME = "OpenSCAD";
static std::string lookupResourcesPath()
{
fs::path resourcedir(applicationpath);
PRINTDB("Looking up resource folder with application path '%s'", resourcedir.c_str());
#ifndef WIN32
#ifdef __APPLE__
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
fs::path tmpdir;
for (int a = 0;searchpath[a] != NULL;a++) {
tmpdir = resourcedir / searchpath[a];
const fs::path checkdir = tmpdir / "libraries";
PRINTDB("Checking '%s'", checkdir.c_str());
if (is_directory(checkdir)) {
resourcedir = tmpdir;
PRINTDB("Found resource folder '%s'", tmpdir.c_str());
break;
}
}
#endif // !WIN32
// resourcedir defaults to applicationPath
std::string result = boosty::stringy(boosty::canonical(resourcedir));
PRINTDB("Using resource folder '%s'", result);
return result;
}
void PlatformUtils::registerApplicationPath(const std::string &apppath)
{
applicationpath = apppath;
resourcespath = lookupResourcesPath();
path_initialized = true;
}
std::string PlatformUtils::applicationPath()
{
if (!path_initialized) {
throw std::runtime_error("PlatformUtils::applicationPath(): application path not initialized!");
}
return applicationpath;
}
@ -52,7 +106,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) );
@ -71,7 +125,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());
@ -99,35 +153,10 @@ bool PlatformUtils::createBackupPath()
// This is the built-in read-only resources path
std::string PlatformUtils::resourcesPath()
{
fs::path resourcedir(applicationPath());
fs::path tmpdir;
#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 /= "../../..";
if (!path_initialized) {
throw std::runtime_error("PlatformUtils::resourcesPath(): application path not initialized!");
}
#elif !defined(WIN32)
tmpdir = resourcedir / "../share/openscad";
if (is_directory(tmpdir / "libraries")) {
resourcedir = tmpdir;
}
else {
tmpdir = resourcedir / "../../share/openscad";
if (is_directory(tmpdir / "libraries")) {
resourcedir = tmpdir;
} else {
tmpdir = resourcedir / "../..";
if (is_directory(tmpdir / "libraries")) {
resourcedir = tmpdir;
}
}
}
#endif
// resourcedir defaults to applicationPath
return boosty::stringy(boosty::canonical(resourcedir));
return resourcespath;
}
int PlatformUtils::setenv(const char *name, const char *value, int overwrite)

View File

@ -3,6 +3,7 @@
#include <string>
namespace PlatformUtils {
extern const char *OPENSCAD_FOLDER_NAME;
void registerApplicationPath(const std::string &applicationpath);
std::string applicationPath();
@ -10,6 +11,19 @@ namespace PlatformUtils {
std::string documentsPath();
std::string resourcesPath();
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;
@ -110,7 +113,7 @@ Preferences::Preferences(QWidget *parent) : QMainWindow(parent)
QActionGroup *group = new QActionGroup(this);
addPrefPage(group, prefsAction3DView, page3DView);
addPrefPage(group, prefsActionEditor, pageEditor);
#if defined(OPENSCAD_DEPLOY) && defined(Q_OS_MAC)
#ifdef OPENSCAD_UPDATER
addPrefPage(group, prefsActionUpdate, pageUpdate);
#else
this->toolBar->removeAction(prefsActionUpdate);
@ -136,14 +139,12 @@ Preferences::Preferences(QWidget *parent) : QMainWindow(parent)
#endif
this->polysetCacheSizeEdit->setValidator(validator);
this->opencsgLimitEdit->setValidator(validator);
setupFeaturesPage();
updateGUI();
}
Preferences::~Preferences()
{
removeDefaultSettings();
instance = NULL;
}
/**
@ -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);
@ -307,7 +308,7 @@ void Preferences::on_snapshotCheckBox_toggled(bool on)
void Preferences::on_checkNowButton_clicked()
{
if (AutoUpdater *updater =AutoUpdater::updater()) {
if (AutoUpdater *updater = AutoUpdater::updater()) {
updater->checkForUpdates();
} else {
unimplemented_msg();
@ -459,7 +460,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);
@ -491,4 +499,33 @@ 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(QStringList colorSchemes)
{
if (instance != NULL) {
return;
}
std::list<std::string> names = ColorMap::inst()->colorSchemeNames(true);
QStringList renderColorSchemes;
foreach (std::string name, names) {
renderColorSchemes << name.c_str();
}
instance = new Preferences();
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

@ -3,7 +3,6 @@
#include <QMainWindow>
#include <QSettings>
#include "ui_Preferences.h"
#include "colormap.h"
class Preferences : public QMainWindow, public Ui::Preferences
{
@ -11,9 +10,12 @@ class Preferences : public QMainWindow, public Ui::Preferences
public:
~Preferences();
static Preferences *inst() { if (!instance) instance = new Preferences(); return instance; }
static void create(QStringList colorSchemes);
static Preferences *inst();
QVariant getValue(const QString &key) const;
void init();
void apply() const;
public slots:
@ -22,7 +24,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 &);
@ -47,7 +49,7 @@ signals:
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

@ -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>

View File

@ -10,6 +10,7 @@
class SparkleAutoUpdater : public AutoUpdater
{
Q_OBJECT;
public:
SparkleAutoUpdater();
~SparkleAutoUpdater();

View File

@ -77,11 +77,12 @@ void Builtins::initialize()
register_builtin_dxf_rotate_extrude();
register_builtin_text();
this->deprecations["dxf_linear_extrude"] = "linear_extrude";
this->deprecations["dxf_rotate_extrude"] = "rotate_extrude";
this->deprecations["import_stl"] = "import";
this->deprecations["import_dxf"] = "import";
this->deprecations["import_off"] = "import";
this->deprecations["dxf_linear_extrude"] = "linear_extrude()";
this->deprecations["dxf_rotate_extrude"] = "rotate_extrude()";
this->deprecations["import_stl"] = "import()";
this->deprecations["import_dxf"] = "import()";
this->deprecations["import_off"] = "import()";
this->deprecations["assign"] = "a regular assignment";
}
std::string Builtins::isDeprecated(const std::string &name)

View File

@ -39,10 +39,10 @@ class CgaladvModule : public AbstractModule
public:
cgaladv_type_e type;
CgaladvModule(cgaladv_type_e type) : type(type) { }
virtual AbstractNode *instantiate(const Context *ctx, const ModuleInstantiation *inst, const EvalContext *evalctx) const;
virtual AbstractNode *instantiate(const Context *ctx, const ModuleInstantiation *inst, EvalContext *evalctx) const;
};
AbstractNode *CgaladvModule::instantiate(const Context *ctx, const ModuleInstantiation *inst, const EvalContext *evalctx) const
AbstractNode *CgaladvModule::instantiate(const Context *ctx, const ModuleInstantiation *inst, EvalContext *evalctx) const
{
CgaladvNode *node = new CgaladvNode(inst, type);
@ -62,6 +62,7 @@ AbstractNode *CgaladvModule::instantiate(const Context *ctx, const ModuleInstant
Context c(ctx);
c.setVariables(args, evalctx);
inst->scope.apply(*evalctx);
Value convexity, path, subdiv_type, level;

View File

@ -31,23 +31,181 @@
#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()) { }
virtual AbstractNode *instantiate(const Context *ctx, const ModuleInstantiation *inst, const EvalContext *evalctx) const;
ColorModule();
virtual ~ColorModule();
virtual AbstractNode *instantiate(const Context *ctx, const ModuleInstantiation *inst, EvalContext *evalctx) const;
private:
const boost::unordered_map<std::string, Color4f> &webcolors;
boost::unordered_map<std::string, Color4f> webcolors;
};
AbstractNode *ColorModule::instantiate(const Context *ctx, const ModuleInstantiation *inst, const EvalContext *evalctx) const
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, EvalContext *evalctx) const
{
ColorNode *node = new ColorNode(inst);
@ -60,6 +218,7 @@ AbstractNode *ColorModule::instantiate(const Context *ctx, const ModuleInstantia
Context c(ctx);
c.setVariables(args, evalctx);
inst->scope.apply(*evalctx);
Value v = c.lookup_variable("c");
if (v.type() == Value::VECTOR) {

View File

@ -1,7 +1,114 @@
#include "colormap.h"
#include <boost/assign/list_of.hpp>
#include "boosty.h"
#include "printutils.h"
using namespace boost::assign; // bring map_list_of() into scope
#include "PlatformUtils.h"
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());
_error = 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;
}
std::string RenderColorScheme::path() const
{
return _path.string();
}
std::string RenderColorScheme::error() const
{
return _error;
}
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)
{
@ -13,286 +120,73 @@ 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;
ColorMap::ColorMap()
{
colorSchemeSet = enumerateColorSchemes();
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));
dump();
}
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()
{
}
const char * ColorMap::defaultColorSchemeName() const
{
return DEFAULT_COLOR_SCHEME_NAME;
}
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
void ColorMap::dump() 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);
PRINTD("Listing available color schemes...");
std::list<std::string> names = colorSchemeNames();
unsigned int length = 0;
for (std::list<std::string>::const_iterator it = names.begin();it != names.end();it++) {
length = (*it).length() > length ? (*it).length() : length;
}
for (colorscheme_set_t::const_iterator it = colorSchemeSet.begin();it != colorSchemeSet.end();it++) {
const RenderColorScheme *cs = (*it).second.get();
const char gui = cs->showInGui() ? 'G' : '-';
if (cs->path().empty()) {
PRINTDB("%6d:%c: %s (built-in)", cs->index() % gui % boost::io::group(std::setw(length), cs->name()));
} else {
PRINTDB("%6d:%c: %s from %s", cs->index() % gui % boost::io::group(std::setw(length), cs->name()) % cs->path());
}
return names;
}
PRINTD("done.");
}
std::list<std::string> ColorMap::colorSchemeNames(bool guiOnly) const
{
std::list<std::string> colorSchemeNames;
for (colorscheme_set_t::const_iterator it = colorSchemeSet.begin();it != colorSchemeSet.end();it++) {
const RenderColorScheme *scheme = (*it).second.get();
if (guiOnly && !scheme->showInGui()) {
continue;
}
colorSchemeNames.push_back(scheme->name());
}
return colorSchemeNames;
}
Color4f ColorMap::getColor(const ColorScheme &cs, const RenderColor rc)
@ -302,19 +196,47 @@ 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 basePath)
{
const fs::path color_schemes = basePath / "color-schemes" / "render";
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());
PRINTDB("Enumerating color schemes from '%s'", color_schemes.string().c_str());
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)));
PRINTDB("Found file '%s' with color scheme '%s' and index %d",
colorScheme->path() % colorScheme->name() % colorScheme->index());
} else {
PRINTDB("Invalid file '%s': %s", colorScheme->path() % colorScheme->error());
delete colorScheme;
}
}
}
*/
}
}
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,64 @@ enum RenderColor {
typedef std::map<RenderColor, Color4f> ColorScheme;
class RenderColorScheme
{
private:
const fs::path _path;
boost::property_tree::ptree pt;
std::string _name;
std::string _error;
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:
std::string path() const;
std::string error() const;
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 char * defaultColorSchemeName() const;
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();
void dump() const;
colorscheme_set_t enumerateColorSchemes();
void enumerateColorSchemesInPath(colorscheme_set_t &result_set, const fs::path path);
colorscheme_set_t colorSchemeSet;
};

View File

@ -152,7 +152,7 @@ Value Context::evaluate_function(const std::string &name, const EvalContext *eva
return Value();
}
AbstractNode *Context::instantiate_module(const ModuleInstantiation &inst, const EvalContext *evalctx) const
AbstractNode *Context::instantiate_module(const ModuleInstantiation &inst, EvalContext *evalctx) const
{
if (this->parent) return this->parent->instantiate_module(inst, evalctx);
PRINTB("WARNING: Ignoring unknown module '%s'.", inst.name());

View File

@ -15,7 +15,7 @@ public:
const Context *getParent() const { return this->parent; }
virtual Value evaluate_function(const std::string &name, const class EvalContext *evalctx) const;
virtual class AbstractNode *instantiate_module(const class ModuleInstantiation &inst, const EvalContext *evalctx) const;
virtual class AbstractNode *instantiate_module(const class ModuleInstantiation &inst, EvalContext *evalctx) const;
void setVariables(const AssignmentList &args,
const class EvalContext *evalctx = NULL);

View File

@ -29,6 +29,7 @@
#include "node.h"
#include "evalcontext.h"
#include "modcontext.h"
#include "expression.h"
#include "builtin.h"
#include "printutils.h"
#include <sstream>
@ -55,7 +56,7 @@ public: // methods
: type(type)
{ }
virtual AbstractNode *instantiate(const Context *ctx, const ModuleInstantiation *inst, const EvalContext *evalctx) const;
virtual AbstractNode *instantiate(const Context *ctx, const ModuleInstantiation *inst, EvalContext *evalctx) const;
static void for_eval(AbstractNode &node, const ModuleInstantiation &inst, size_t l,
const Context *ctx, const EvalContext *evalctx);
@ -99,7 +100,14 @@ void ControlModule::for_eval(AbstractNode &node, const ModuleInstantiation &inst
for_eval(node, inst, l+1, &c, evalctx);
}
} else if (l > 0) {
std::vector<AbstractNode *> instantiatednodes = inst.instantiateChildren(ctx);
// At this point, the for loop variables have been set and we can initialize
// the local scope (as they may depend on the for loop variables
Context c(ctx);
BOOST_FOREACH(const Assignment &ass, inst.scope.assignments) {
c.set_variable(ass.first, ass.second->evaluate(&c));
}
std::vector<AbstractNode *> instantiatednodes = inst.instantiateChildren(&c);
node.children.insert(node.children.end(), instantiatednodes.begin(), instantiatednodes.end());
}
}
@ -155,12 +163,12 @@ AbstractNode* ControlModule::getChild(const Value& value, const EvalContext* mod
return modulectx->getChild(n)->evaluate(modulectx);
}
AbstractNode *ControlModule::instantiate(const Context* /*ctx*/, const ModuleInstantiation *inst, const EvalContext *evalctx) const
AbstractNode *ControlModule::instantiate(const Context* /*ctx*/, const ModuleInstantiation *inst, EvalContext *evalctx) const
{
AbstractNode *node = NULL;
if (type == CHILD)
{
switch (this->type) {
case CHILD: {
printDeprecation("DEPRECATED: child() will be removed in future releases. Use children() instead.");
int n = 0;
if (evalctx->numArgs() > 0) {
@ -192,9 +200,9 @@ AbstractNode *ControlModule::instantiate(const Context* /*ctx*/, const ModuleIns
}
return node;
}
break;
if (type == CHILDREN)
{
case CHILDREN: {
const EvalContext *modulectx = getLastModuleCtx(evalctx);
if (modulectx==NULL) {
return NULL;
@ -251,14 +259,10 @@ AbstractNode *ControlModule::instantiate(const Context* /*ctx*/, const ModuleIns
}
return NULL;
}
break;
if (type == INT_FOR)
node = new AbstractIntersectionNode(inst);
else
case ECHO: {
node = new AbstractNode(inst);
if (type == ECHO)
{
std::stringstream msg;
msg << "ECHO: ";
for (size_t i = 0; i < inst->arguments.size(); i++) {
@ -273,36 +277,50 @@ AbstractNode *ControlModule::instantiate(const Context* /*ctx*/, const ModuleIns
}
PRINTB("%s", msg.str());
}
break;
if (type == ASSIGN)
{
case ASSIGN: {
node = new AbstractNode(inst);
// We create a new context to avoid parameters from influencing each other
// -> parallel evaluation. This is to be backwards compatible.
Context c(evalctx);
for (size_t i = 0; i < evalctx->numArgs(); i++) {
if (!evalctx->getArgName(i).empty())
c.set_variable(evalctx->getArgName(i), evalctx->getArgValue(i));
}
// Let any local variables override the parameters
inst->scope.apply(c);
std::vector<AbstractNode *> instantiatednodes = inst->instantiateChildren(&c);
node->children.insert(node->children.end(), instantiatednodes.begin(), instantiatednodes.end());
}
break;
if (type == FOR || type == INT_FOR)
{
case FOR:
node = new AbstractNode(inst);
for_eval(*node, *inst, 0, evalctx, evalctx);
}
break;
if (type == IF)
{
case INT_FOR:
node = new AbstractIntersectionNode(inst);
for_eval(*node, *inst, 0, evalctx, evalctx);
break;
case IF: {
node = new AbstractNode(inst);
const IfElseModuleInstantiation *ifelse = dynamic_cast<const IfElseModuleInstantiation*>(inst);
if (evalctx->numArgs() > 0 && evalctx->getArgValue(0).toBool()) {
inst->scope.apply(*evalctx);
std::vector<AbstractNode *> instantiatednodes = ifelse->instantiateChildren(evalctx);
node->children.insert(node->children.end(), instantiatednodes.begin(), instantiatednodes.end());
}
else {
ifelse->else_scope.apply(*evalctx);
std::vector<AbstractNode *> instantiatednodes = ifelse->instantiateElseChildren(evalctx);
node->children.insert(node->children.end(), instantiatednodes.begin(), instantiatednodes.end());
}
}
break;
}
return node;
}

View File

@ -38,11 +38,12 @@ class CsgModule : public AbstractModule
public:
OpenSCADOperator type;
CsgModule(OpenSCADOperator type) : type(type) { }
virtual AbstractNode *instantiate(const Context *ctx, const ModuleInstantiation *inst, const EvalContext *evalctx) const;
virtual AbstractNode *instantiate(const Context *ctx, const ModuleInstantiation *inst, EvalContext *evalctx) const;
};
AbstractNode *CsgModule::instantiate(const Context*, const ModuleInstantiation *inst, const EvalContext *evalctx) const
AbstractNode *CsgModule::instantiate(const Context*, const ModuleInstantiation *inst, EvalContext *evalctx) const
{
inst->scope.apply(*evalctx);
CsgNode *node = new CsgNode(inst, type);
std::vector<AbstractNode *> instantiatednodes = inst->instantiateChildren(evalctx);
node->children.insert(node->children.end(), instantiatednodes.begin(), instantiatednodes.end());

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

@ -8,6 +8,12 @@
#include <boost/foreach.hpp>
EvalContext::EvalContext(const Context *parent,
const AssignmentList &args, const class LocalScope *const scope)
: Context(parent), eval_arguments(args), scope(scope)
{
}
const std::string &EvalContext::getArgName(size_t i) const
{
assert(i < this->eval_arguments.size());

View File

@ -12,8 +12,7 @@ public:
typedef std::vector<class ModuleInstantiation *> InstanceList;
EvalContext(const Context *parent,
const AssignmentList &args, const class LocalScope *const scope = NULL)
: Context(parent), eval_arguments(args), scope(scope) {}
const AssignmentList &args, const class LocalScope *const scope = NULL);
virtual ~EvalContext() {}
size_t numArgs() const { return this->eval_arguments.size(); }
@ -29,6 +28,5 @@ public:
private:
const AssignmentList &eval_arguments;
std::vector<std::pair<std::string, Value> > eval_values;
const LocalScope *const scope;
};

View File

@ -468,10 +468,10 @@ void export_dxf(const Polygon2d &poly, std::ostream &output)
<< "0\n"
<< " 10\n"
<< x1 << "\n"
<< " 11\n"
<< x2 << "\n"
<< " 20\n"
<< y1 << "\n"
<< " 11\n"
<< x2 << "\n"
<< " 21\n"
<< y2 << "\n";
}

View File

@ -375,7 +375,7 @@ std::string Expression::toString() const
stream << "for(" << c->call_arguments << ") ";
c = c->children[0];
} else if (c->call_funcname == "if") {
stream << "if(" << c->children[0] << ") ";
stream << "if(" << *c->children[0] << ") ";
c = c->children[1];
} else if (c->call_funcname == "let") {
stream << "let(" << c->call_arguments << ") ";

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

@ -61,10 +61,10 @@ class ImportModule : public AbstractModule
public:
import_type_e type;
ImportModule(import_type_e type = TYPE_UNKNOWN) : type(type) { }
virtual AbstractNode *instantiate(const Context *ctx, const ModuleInstantiation *inst, const EvalContext *evalctx) const;
virtual AbstractNode *instantiate(const Context *ctx, const ModuleInstantiation *inst, EvalContext *evalctx) const;
};
AbstractNode *ImportModule::instantiate(const Context *ctx, const ModuleInstantiation *inst, const EvalContext *evalctx) const
AbstractNode *ImportModule::instantiate(const Context *ctx, const ModuleInstantiation *inst, EvalContext *evalctx) const
{
AssignmentList args;
args += Assignment("file"), Assignment("layer"), Assignment("convexity"), Assignment("origin"), Assignment("scale");

View File

@ -33,7 +33,7 @@ LaunchingScreen::LaunchingScreen(QWidget *parent) : QDialog(parent)
QListWidgetItem *item = new QListWidgetItem(fileInfo.fileName());
item->setData(Qt::ToolTipRole, fileInfo.canonicalPath());
item->setData(Qt::UserRole, fileInfo.canonicalFilePath());
this->recentList->insertItem(1, item);
this->recentList->addItem(item);
}
foreach(const QString &category, UIUtils::exampleCategories())

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

@ -46,10 +46,10 @@ class LinearExtrudeModule : public AbstractModule
{
public:
LinearExtrudeModule() { }
virtual AbstractNode *instantiate(const Context *ctx, const ModuleInstantiation *inst, const EvalContext *evalctx) const;
virtual AbstractNode *instantiate(const Context *ctx, const ModuleInstantiation *inst, EvalContext *evalctx) const;
};
AbstractNode *LinearExtrudeModule::instantiate(const Context *ctx, const ModuleInstantiation *inst, const EvalContext *evalctx) const
AbstractNode *LinearExtrudeModule::instantiate(const Context *ctx, const ModuleInstantiation *inst, EvalContext *evalctx) const
{
LinearExtrudeNode *node = new LinearExtrudeNode(inst);
@ -58,6 +58,7 @@ AbstractNode *LinearExtrudeModule::instantiate(const Context *ctx, const ModuleI
Context c(ctx);
c.setVariables(args, evalctx);
inst->scope.apply(*evalctx);
node->fn = c.lookup_variable("$fn").toDouble();
node->fs = c.lookup_variable("$fs").toDouble();

View File

@ -43,32 +43,27 @@ std::string LocalScope::dump(const std::string &indent) const
}
// FIXME: Two parameters here is a hack. Rather have separate types of scopes, or check the type of the first parameter. Note const vs. non-const
std::vector<AbstractNode*> LocalScope::instantiateChildren(const Context *evalctx, FileContext *filectx) const
std::vector<AbstractNode*> LocalScope::instantiateChildren(const Context *evalctx) const
{
Context *c = filectx;
if (!c) {
c = new Context(evalctx);
// FIXME: If we make c a ModuleContext, child() doesn't work anymore
// c->functions_p = &this->functions;
// c->modules_p = &this->modules;
// Uncommenting the following would allow assignments in local scopes,
// but would cause duplicate evaluation of module scopes
// BOOST_FOREACH (const Assignment &ass, this->assignments) {
// c->set_variable(ass.first, ass.second->evaluate(c));
// }
}
std::vector<AbstractNode*> childnodes;
BOOST_FOREACH (ModuleInstantiation *modinst, this->children) {
AbstractNode *node = modinst->evaluate(c);
AbstractNode *node = modinst->evaluate(evalctx);
if (node) childnodes.push_back(node);
}
if (c != filectx) delete c;
return childnodes;
}
/*!
When instantiating a module which can take a scope as parameter (i.e. non-leaf nodes),
use this method to apply the local scope definitions to the evaluation context.
This will enable variables defined in local blocks.
NB! for loops are special as the local block may depend on variables evaluated by the
for loop parameters. The for loop code will handle this specially.
*/
void LocalScope::apply(Context &ctx) const
{
BOOST_FOREACH(const Assignment &ass, this->assignments) {
ctx.set_variable(ass.first, ass.second->evaluate(&ctx));
}
}

View File

@ -11,8 +11,9 @@ public:
size_t numElements() const { return assignments.size() + children.size(); }
std::string dump(const std::string &indent) const;
std::vector<class AbstractNode*> instantiateChildren(const class Context *evalctx, class FileContext *filectx = NULL) const;
std::vector<class AbstractNode*> instantiateChildren(const class Context *evalctx) const;
void addChild(ModuleInstantiation *ch);
void apply(Context &ctx) const;
AssignmentList assignments;
ModuleInstantiationList children;

View File

@ -56,11 +56,13 @@
#include "ThrownTogetherRenderer.h"
#include "csgtermnormalizer.h"
#include "QGLView.h"
#include "AutoUpdater.h"
#ifdef Q_OS_MAC
#include "CocoaUtils.h"
#endif
#include "PlatformUtils.h"
#ifdef OPENSCAD_UPDATER
#include "AutoUpdater.h"
#endif
#include <QMenu>
#include <QTime>
@ -187,8 +189,9 @@ MainWindow::MainWindow(const QString &filename)
this->consoleDock->setConfigKey("view/hideConsole");
this->consoleDock->setAction(this->viewActionHideConsole);
editortype = Preferences::inst()->getValue("editor/editortype").toString();
useScintilla = (editortype == "QScintilla Editor");
QSettings settings;
editortype = settings.value("editor/editortype").toString();
useScintilla = (editortype != "Simple Editor");
#ifdef USE_SCINTILLA_EDITOR
if (useScintilla) {
@ -198,6 +201,8 @@ MainWindow::MainWindow(const QString &filename)
#endif
editor = new LegacyEditor(editorDockContents);
Preferences::create(editor->colorSchemes());
editorDockContents->layout()->addWidget(editor);
setCorner(Qt::TopLeftCorner, Qt::LeftDockWidgetArea);
@ -273,17 +278,6 @@ MainWindow::MainWindow(const QString &filename)
animate_panel->hide();
find_panel->hide();
// Application menu
#ifdef DEBUG
this->appActionUpdateCheck->setEnabled(false);
#else
#ifdef Q_OS_MAC
this->appActionUpdateCheck->setMenuRole(QAction::ApplicationSpecificRole);
this->appActionUpdateCheck->setEnabled(true);
connect(this->appActionUpdateCheck, SIGNAL(triggered()), this, SLOT(actionUpdateCheck()));
#endif
#endif
// File menu
connect(this->fileActionNew, SIGNAL(triggered()), this, SLOT(actionNew()));
connect(this->fileActionOpen, SIGNAL(triggered()), this, SLOT(actionOpen()));
@ -407,6 +401,10 @@ MainWindow::MainWindow(const QString &filename)
connect(this->helpActionLibraryInfo, SIGNAL(triggered()), this, SLOT(helpLibrary()));
connect(this->helpActionFontInfo, SIGNAL(triggered()), this, SLOT(helpFontInfo()));
#ifdef OPENSCAD_UPDATER
this->menuBar()->addMenu(AutoUpdater::updater()->updateMenu);
#endif
setCurrentOutput();
PRINT(helptitle);
@ -521,7 +519,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());
@ -1134,13 +1131,6 @@ void MainWindow::compileCSG(bool procevents)
if (procevents) QApplication::processEvents();
}
void MainWindow::actionUpdateCheck()
{
if (AutoUpdater *updater =AutoUpdater::updater()) {
updater->checkForUpdates();
}
}
void MainWindow::actionNew()
{
if (MainWindow::mdiMode) {

View File

@ -71,6 +71,7 @@ void ModuleContext::initializeModule(const class Module &module)
BOOST_FOREACH(const Assignment &ass, module.scope.assignments) {
this->set_variable(ass.first, ass.second->evaluate(this));
}
// Experimental code. See issue #399
// evaluateAssignments(module.scope.assignments);
}
@ -115,7 +116,7 @@ const AbstractModule *ModuleContext::findLocalModule(const std::string &name) co
}
std::string replacement = Builtins::instance()->isDeprecated(name);
if (!replacement.empty()) {
PRINT_DEPRECATION("DEPRECATED: The %s() module will be removed in future releases. Use %s() instead.", name % replacement);
PRINT_DEPRECATION("DEPRECATED: The %s() module will be removed in future releases. Use %s instead.", name % replacement);
}
return m;
}
@ -130,7 +131,7 @@ Value ModuleContext::evaluate_function(const std::string &name, const EvalContex
return Context::evaluate_function(name, evalctx);
}
AbstractNode *ModuleContext::instantiate_module(const ModuleInstantiation &inst, const EvalContext *evalctx) const
AbstractNode *ModuleContext::instantiate_module(const ModuleInstantiation &inst, EvalContext *evalctx) const
{
const AbstractModule *foundm = this->findLocalModule(inst.name());
if (foundm) return foundm->instantiate(this, &inst, evalctx);
@ -207,7 +208,7 @@ Value FileContext::evaluate_function(const std::string &name, const EvalContext
return ModuleContext::evaluate_function(name, evalctx);
}
AbstractNode *FileContext::instantiate_module(const ModuleInstantiation &inst, const EvalContext *evalctx) const
AbstractNode *FileContext::instantiate_module(const ModuleInstantiation &inst, EvalContext *evalctx) const
{
const AbstractModule *foundm = this->findLocalModule(inst.name());
if (foundm) return foundm->instantiate(this, &inst, evalctx);

View File

@ -21,7 +21,7 @@ public:
virtual Value evaluate_function(const std::string &name,
const EvalContext *evalctx) const;
virtual AbstractNode *instantiate_module(const ModuleInstantiation &inst,
const EvalContext *evalctx) const;
EvalContext *evalctx) const;
const AbstractModule *findLocalModule(const std::string &name) const;
const AbstractFunction *findLocalFunction(const std::string &name) const;
@ -47,7 +47,7 @@ public:
virtual ~FileContext() {}
virtual Value evaluate_function(const std::string &name, const EvalContext *evalctx) const;
virtual AbstractNode *instantiate_module(const ModuleInstantiation &inst,
const EvalContext *evalctx) const;
EvalContext *evalctx) const;
private:
const FileModule::ModuleContainer &usedlibs;

View File

@ -46,7 +46,7 @@ AbstractModule::~AbstractModule()
{
}
AbstractNode *AbstractModule::instantiate(const Context *ctx, const ModuleInstantiation *inst, const EvalContext *evalctx) const
AbstractNode *AbstractModule::instantiate(const Context *ctx, const ModuleInstantiation *inst, EvalContext *evalctx) const
{
(void)ctx; // avoid unusued parameter warning
@ -185,7 +185,7 @@ private:
const ModuleInstantiation &inst;
};
AbstractNode *Module::instantiate(const Context *ctx, const ModuleInstantiation *inst, const EvalContext *evalctx) const
AbstractNode *Module::instantiate(const Context *ctx, const ModuleInstantiation *inst, EvalContext *evalctx) const
{
ModRecursionGuard g(*inst);
if (g.recursion_detected()) {
@ -193,6 +193,10 @@ AbstractNode *Module::instantiate(const Context *ctx, const ModuleInstantiation
return NULL;
}
// At this point we know that nobody will modify the dependencies of the local scope
// passed to this instance, so we can populate the context
inst->scope.apply(*evalctx);
ModuleContext c(ctx, evalctx);
// set $children first since we might have variables depending on it
c.set_variable("$children", Value(double(inst->scope.children.size())));
@ -342,7 +346,7 @@ bool FileModule::handleDependencies()
return somethingchanged;
}
AbstractNode *FileModule::instantiate(const Context *ctx, const ModuleInstantiation *inst, const EvalContext *evalctx) const
AbstractNode *FileModule::instantiate(const Context *ctx, const ModuleInstantiation *inst, EvalContext *evalctx) const
{
assert(evalctx == NULL);
FileContext c(*this, ctx);
@ -353,7 +357,7 @@ AbstractNode *FileModule::instantiate(const Context *ctx, const ModuleInstantiat
#endif
AbstractNode *node = new AbstractNode(inst);
std::vector<AbstractNode *> instantiatednodes = this->scope.instantiateChildren(ctx, &c);
std::vector<AbstractNode *> instantiatednodes = this->scope.instantiateChildren(&c);
node->children.insert(node->children.end(), instantiatednodes.begin(), instantiatednodes.end());
return node;

View File

@ -68,7 +68,7 @@ public:
virtual ~AbstractModule();
virtual bool is_experimental() const { return feature != NULL; }
virtual bool is_enabled() const { return (feature == NULL) || feature->is_enabled(); }
virtual class AbstractNode *instantiate(const Context *ctx, const ModuleInstantiation *inst, const class EvalContext *evalctx = NULL) const;
virtual class AbstractNode *instantiate(const Context *ctx, const ModuleInstantiation *inst, class EvalContext *evalctx = NULL) const;
virtual std::string dump(const std::string &indent, const std::string &name) const;
virtual double lookup_double_variable_with_default(Context &c, std::string variable, double def) const;
virtual std::string lookup_string_variable_with_default(Context &c, std::string variable, std::string def) const;
@ -81,7 +81,7 @@ public:
Module(const Feature& feature) : AbstractModule(feature) { }
virtual ~Module();
virtual AbstractNode *instantiate(const Context *ctx, const ModuleInstantiation *inst, const EvalContext *evalctx = NULL) const;
virtual AbstractNode *instantiate(const Context *ctx, const ModuleInstantiation *inst, EvalContext *evalctx = NULL) const;
virtual std::string dump(const std::string &indent, const std::string &name) const;
static const std::string& stack_element(int n) { return module_stack[n]; };
static int stack_size() { return module_stack.size(); };
@ -108,7 +108,7 @@ public:
void registerInclude(const std::string &localpath, const std::string &fullpath);
bool includesChanged() const;
bool handleDependencies();
virtual AbstractNode *instantiate(const Context *ctx, const ModuleInstantiation *inst, const EvalContext *evalctx = NULL) const;
virtual AbstractNode *instantiate(const Context *ctx, const ModuleInstantiation *inst, EvalContext *evalctx = NULL) const;
bool hasIncludes() const { return !this->includes.empty(); }
bool usesLibraries() const { return !this->usedlibs.empty(); }
bool isHandlingDependencies() const { return this->is_handling_dependencies; }

View File

@ -46,10 +46,10 @@ class OffsetModule : public AbstractModule
{
public:
OffsetModule() { }
virtual AbstractNode *instantiate(const Context *ctx, const ModuleInstantiation *inst, const EvalContext *evalctx) const;
virtual AbstractNode *instantiate(const Context *ctx, const ModuleInstantiation *inst, EvalContext *evalctx) const;
};
AbstractNode *OffsetModule::instantiate(const Context *ctx, const ModuleInstantiation *inst, const EvalContext *evalctx) const
AbstractNode *OffsetModule::instantiate(const Context *ctx, const ModuleInstantiation *inst, EvalContext *evalctx) const
{
OffsetNode *node = new OffsetNode(inst);
@ -58,6 +58,7 @@ AbstractNode *OffsetModule::instantiate(const Context *ctx, const ModuleInstanti
Context c(ctx);
c.setVariables(args, evalctx);
inst->scope.apply(*evalctx);
node->fn = c.lookup_variable("$fn").toDouble();
node->fs = c.lookup_variable("$fs").toDouble();

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_UPDATER
#include "SparkleAutoUpdater.h"
#endif
#endif
#ifdef _MSC_VER
#define snprintf _snprintf
#endif
@ -77,14 +77,17 @@
namespace po = boost::program_options;
namespace fs = boost::filesystem;
namespace Render { enum type { GEOMETRY, CGAL, OPENCSG, THROWNTOGETHER }; };
std::string commandline_commands;
std::string currentdir;
using std::string;
using std::vector;
using boost::lexical_cast;
using boost::bad_lexical_cast;
using boost::is_any_of;
std::string commandline_commands;
std::string currentdir;
static bool arg_info = false;
static std::string arg_colorscheme;
class Echostream : public std::ofstream
{
public:
@ -248,6 +251,28 @@ static bool checkAndExport(shared_ptr<const Geometry> root_geom, unsigned nd,
return true;
}
void set_render_color_scheme(const std::string color_scheme, const bool exit_if_not_found)
{
if (color_scheme.empty()) {
return;
}
if (ColorMap::inst()->findColorScheme(color_scheme)) {
RenderSettings::inst()->colorscheme = color_scheme;
return;
}
if (exit_if_not_found) {
PRINTB("Unknown color scheme '%s'. Valid schemes:", color_scheme);
BOOST_FOREACH (const std::string &name, ColorMap::inst()->colorSchemeNames()) {
PRINT(name);
}
exit(1);
} else {
PRINTB("Unknown color scheme '%s', using default '%s'.", arg_colorscheme % ColorMap::inst()->defaultColorSchemeName());
}
}
int cmdline(const char *deps_output_file, const std::string &filename, Camera &camera, const char *output_file, const fs::path &original_path, Render::type renderer, int argc, char ** argv )
{
#ifdef OPENSCAD_QTGUI
@ -262,6 +287,10 @@ int cmdline(const char *deps_output_file, const std::string &filename, Camera &c
#ifdef ENABLE_CGAL
GeometryEvaluator geomevaluator(tree);
#endif
if (arg_info) {
info();
}
const char *stl_output_file = NULL;
const char *off_output_file = NULL;
const char *amf_output_file = NULL;
@ -291,6 +320,8 @@ int cmdline(const char *deps_output_file, const std::string &filename, Camera &c
return 1;
}
set_render_color_scheme(arg_colorscheme, true);
// Top context - this context only holds builtins
ModuleContext top_ctx;
top_ctx.registerBuiltin();
@ -556,10 +587,11 @@ int gui(vector<string> &inputFiles, const fs::path &original_path, int argc, cha
installAppleEventHandlers();
#endif
#if defined(OPENSCAD_DEPLOY) && defined(Q_OS_MAC)
#ifdef OPENSCAD_UPDATER
AutoUpdater *updater = new SparkleAutoUpdater;
AutoUpdater::setUpdater(updater);
if (updater->automaticallyChecksForUpdates()) updater->checkForUpdates();
updater->init();
#endif
#if 0 /*** disabled by clifford wolf: adds rendering artefacts with OpenCSG ***/
@ -569,6 +601,9 @@ int gui(vector<string> &inputFiles, const fs::path &original_path, int argc, cha
f.setSamples(4);
QGLFormat::setDefaultFormat(f);
#endif
set_render_color_scheme(arg_colorscheme, false);
bool noInputFiles = false;
if (!inputFiles.size()) {
noInputFiles = true;
@ -590,13 +625,14 @@ int gui(vector<string> &inputFiles, const fs::path &original_path, int argc, cha
}
MainWindow *mainwin;
#ifdef ENABLE_MDI
BOOST_FOREACH(const string &infile, inputFiles) {
mainwin = new MainWindow(assemblePath(original_path, infile));
bool isMdi = settings.value("advanced/mdi", true).toBool();
if (isMdi) {
BOOST_FOREACH(const string &infile, inputFiles) {
mainwin = new MainWindow(assemblePath(original_path, infile));
}
} else {
mainwin = new MainWindow(assemblePath(original_path, inputFiles[0]));
}
#else
mainwin = new MainWindow(assemblePath(original_path, inputFiles[0]));
#endif
app.connect(&app, SIGNAL(lastWindowClosed()), &app, SLOT(quit()));
int rc = app.exec();
@ -688,7 +724,7 @@ int main(int argc, char **argv)
}
if (vm.count("help")) help(argv[0]);
if (vm.count("version")) version();
if (vm.count("info")) info();
if (vm.count("info")) arg_info = true;
Render::type renderer = Render::OPENCSG;
if (vm.count("preview")) {
@ -747,23 +783,9 @@ int main(int argc, char **argv)
if (vm.count("input-file")) {
inputFiles = vm["input-file"].as<vector<string> >();
}
#ifndef ENABLE_MDI
if (inputFiles.size() > 1) {
help(argv[0]);
}
#endif
if (vm.count("colorscheme")) {
std::string colorscheme = vm["colorscheme"].as<string>();
if (ColorMap::inst()->findColorScheme(colorscheme)) {
RenderSettings::inst()->colorscheme = colorscheme;
} else {
PRINT("Unknown color scheme. Valid schemes:");
BOOST_FOREACH (const std::string &name, ColorMap::inst()->colorSchemeNames()) {
PRINT(name);
}
exit(1);
}
arg_colorscheme = vm["colorscheme"].as<string>();
}
currentdir = boosty::stringy(fs::current_path());
@ -780,7 +802,10 @@ int main(int argc, char **argv)
if (!inputFiles.size()) help(argv[0]);
}
if (cmdlinemode) {
if (arg_info || cmdlinemode) {
if (inputFiles.size() > 1) {
help(argv[0]);
}
rc = cmdline(deps_output_file, inputFiles[0], camera, output_file, original_path, renderer, argc, argv);
}
else if (QtUseGUI()) {

View File

@ -270,6 +270,7 @@ if_statement:
child_statements:
/* empty */
| child_statements child_statement
| child_statements assignment
;
child_statement:
@ -281,13 +282,6 @@ child_statement:
}
;
/*
FIXME: This allows for variable declaration in child blocks, not activated yet
|
assignment ;
*/
// "for" is a valid module identifier
module_id:
TOK_ID { $$ = $1; }

View File

@ -61,7 +61,7 @@ class PrimitiveModule : public AbstractModule
public:
primitive_type_e type;
PrimitiveModule(primitive_type_e type) : type(type) { }
virtual AbstractNode *instantiate(const Context *ctx, const ModuleInstantiation *inst, const EvalContext *evalctx) const;
virtual AbstractNode *instantiate(const Context *ctx, const ModuleInstantiation *inst, EvalContext *evalctx) const;
private:
Value lookup_radius(const Context &ctx, const std::string &radius_var, const std::string &diameter_var) const;
};
@ -141,7 +141,7 @@ Value PrimitiveModule::lookup_radius(const Context &ctx, const std::string &diam
}
}
AbstractNode *PrimitiveModule::instantiate(const Context *ctx, const ModuleInstantiation *inst, const EvalContext *evalctx) const
AbstractNode *PrimitiveModule::instantiate(const Context *ctx, const ModuleInstantiation *inst, EvalContext *evalctx) const
{
PrimitiveNode *node = new PrimitiveNode(inst, this->type);

View File

@ -41,10 +41,10 @@ class ProjectionModule : public AbstractModule
{
public:
ProjectionModule() { }
virtual AbstractNode *instantiate(const Context *ctx, const ModuleInstantiation *inst, const EvalContext *evalctx) const;
virtual AbstractNode *instantiate(const Context *ctx, const ModuleInstantiation *inst, EvalContext *evalctx) const;
};
AbstractNode *ProjectionModule::instantiate(const Context *ctx, const ModuleInstantiation *inst, const EvalContext *evalctx) const
AbstractNode *ProjectionModule::instantiate(const Context *ctx, const ModuleInstantiation *inst, EvalContext *evalctx) const
{
ProjectionNode *node = new ProjectionNode(inst);
@ -53,6 +53,7 @@ AbstractNode *ProjectionModule::instantiate(const Context *ctx, const ModuleInst
Context c(ctx);
c.setVariables(args, evalctx);
inst->scope.apply(*evalctx);
Value convexity = c.lookup_variable("convexity", true);
Value cut = c.lookup_variable("cut", true);

View File

@ -38,10 +38,10 @@ class RenderModule : public AbstractModule
{
public:
RenderModule() { }
virtual AbstractNode *instantiate(const Context *ctx, const ModuleInstantiation *inst, const EvalContext *evalctx) const;
virtual AbstractNode *instantiate(const Context *ctx, const ModuleInstantiation *inst, EvalContext *evalctx) const;
};
AbstractNode *RenderModule::instantiate(const Context *ctx, const ModuleInstantiation *inst, const EvalContext *evalctx) const
AbstractNode *RenderModule::instantiate(const Context *ctx, const ModuleInstantiation *inst, EvalContext *evalctx) const
{
RenderNode *node = new RenderNode(inst);
@ -50,6 +50,7 @@ AbstractNode *RenderModule::instantiate(const Context *ctx, const ModuleInstanti
Context c(ctx);
c.setVariables(args, evalctx);
inst->scope.apply(*evalctx);
Value v = c.lookup_variable("convexity");
if (v.type() == Value::NUMBER)

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

@ -44,10 +44,10 @@ class RotateExtrudeModule : public AbstractModule
{
public:
RotateExtrudeModule() { }
virtual AbstractNode *instantiate(const Context *ctx, const ModuleInstantiation *inst, const EvalContext *evalctx) const;
virtual AbstractNode *instantiate(const Context *ctx, const ModuleInstantiation *inst, EvalContext *evalctx) const;
};
AbstractNode *RotateExtrudeModule::instantiate(const Context *ctx, const ModuleInstantiation *inst, const EvalContext *evalctx) const
AbstractNode *RotateExtrudeModule::instantiate(const Context *ctx, const ModuleInstantiation *inst, EvalContext *evalctx) const
{
RotateExtrudeNode *node = new RotateExtrudeNode(inst);
@ -56,6 +56,7 @@ AbstractNode *RotateExtrudeModule::instantiate(const Context *ctx, const ModuleI
Context c(ctx);
c.setVariables(args, evalctx);
inst->scope.apply(*evalctx);
node->fn = c.lookup_variable("$fn").toDouble();
node->fs = c.lookup_variable("$fs").toDouble();

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

@ -52,7 +52,7 @@ class SurfaceModule : public AbstractModule
{
public:
SurfaceModule() { }
virtual AbstractNode *instantiate(const Context *ctx, const ModuleInstantiation *inst, const EvalContext *evalctx) const;
virtual AbstractNode *instantiate(const Context *ctx, const ModuleInstantiation *inst, EvalContext *evalctx) const;
};
typedef boost::unordered_map<std::pair<int,int>,double> img_data_t;
@ -80,7 +80,7 @@ private:
img_data_t read_png_or_dat(std::string filename) const;
};
AbstractNode *SurfaceModule::instantiate(const Context *ctx, const ModuleInstantiation *inst, const EvalContext *evalctx) const
AbstractNode *SurfaceModule::instantiate(const Context *ctx, const ModuleInstantiation *inst, EvalContext *evalctx) const
{
SurfaceNode *node = new SurfaceNode(inst);
node->center = false;

View File

@ -41,10 +41,10 @@ class TextModule : public AbstractModule
{
public:
TextModule() : AbstractModule(Feature::ExperimentalTextModule) { }
virtual AbstractNode *instantiate(const Context *ctx, const ModuleInstantiation *inst, const EvalContext *evalctx) const;
virtual AbstractNode *instantiate(const Context *ctx, const ModuleInstantiation *inst, EvalContext *evalctx) const;
};
AbstractNode *TextModule::instantiate(const Context *ctx, const ModuleInstantiation *inst, const EvalContext *evalctx) const
AbstractNode *TextModule::instantiate(const Context *ctx, const ModuleInstantiation *inst, EvalContext *evalctx) const
{
TextNode *node = new TextNode(inst);

View File

@ -50,10 +50,10 @@ class TransformModule : public AbstractModule
public:
transform_type_e type;
TransformModule(transform_type_e type) : type(type) { }
virtual AbstractNode *instantiate(const Context *ctx, const ModuleInstantiation *inst, const EvalContext *evalctx) const;
virtual AbstractNode *instantiate(const Context *ctx, const ModuleInstantiation *inst, EvalContext *evalctx) const;
};
AbstractNode *TransformModule::instantiate(const Context *ctx, const ModuleInstantiation *inst, const EvalContext *evalctx) const
AbstractNode *TransformModule::instantiate(const Context *ctx, const ModuleInstantiation *inst, EvalContext *evalctx) const
{
TransformNode *node = new TransformNode(inst);
@ -83,6 +83,7 @@ AbstractNode *TransformModule::instantiate(const Context *ctx, const ModuleInsta
Context c(ctx);
c.setVariables(args, evalctx);
inst->scope.apply(*evalctx);
if (this->type == SCALE)
{

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] ,
]);
}

View File

@ -28,3 +28,5 @@ y = !i;
z = (j);
aa = k ? l : m;
bb = n[o];
cc = let(a=1) a;
dd = [for (a=[0,1]) let(b=a) if (true) b];

View File

@ -16,13 +16,18 @@ o = floor();
p = pow();
q = sqrt();
r = exp();
ra = len();
s = log();
t = ln();
u = str();
ua = chr();
ub = concat();
v = lookup();
w = dxf_dim();
x = dxf_cross();
va = search();
y = version();
z = version_num();
aa = len();
bb = search();
za = norm();
zb = cross();
zc = parent_module();
w = dxf_dim();
x = dxf_cross();

View File

@ -37,3 +37,5 @@ mirror();
translate();
multmatrix();
color();
offset();
text();

View File

@ -0,0 +1,85 @@
echo("union scope");
a = 4;
union() {
a = 5;
echo("local a (5):", a);
}
echo("global a (4):", a);
echo("module scope:");
module mymodule(b=6) {
b = 7;
echo("local b (7)", b);
}
mymodule();
mymodule(8);
echo("module children scope:");
module mymodule2(b2=6) {
b2 = 2;
children(0);
}
mymodule2(b2=7) {
b2 = 3;
echo("b2 (3)", b2);
}
echo("for loop (c = 0,1,25):");
for (i=[0:2]) {
c = (i > 1) ? i + 23 : i;
echo("c", c);
}
echo("if scope:");
if (true) {
d = 8;
echo("d (8)", d);
}
echo("else scope:");
if (false) {
} else {
d = 9;
echo("d (9)", d);
}
echo("anonymous inner scope (scope ignored):");
union() {
e = 2;
echo("outer e (3)", e);
{
e = 3;
echo("inner e (3)", e);
}
}
echo("anonymous scope (scope ignored):");
f=1;
echo("outer f (2)", f);
{
f=2;
echo("inner f (2)", f);
}
echo("anonymous scope reassign:");
{
g=1;
echo("g (2)", g);
g=2;
}
echo("anonymous reassign using outer (scope ignored)", h);
h=5;
{
h=h*2; // Not allowed
echo("h (undef)", h);
}
echo("override variable in assign scope:");
assign(i=9) {
i=10;
echo("i (10)", i);
}

View File

@ -2,16 +2,13 @@
//Helper function that pretty prints our search test
//Expected result is checked against execution of a search() invocation and OK/FAIL is indicated
module test_search_and_echo( exp_res, search_to_find, search_to_search, search_up_to_num_matches = undef)
{
if(undef != search_up_to_num_matches)
{
assign( test_res = search(search_to_find, search_to_search, search_up_to_num_matches) )
module test_search_and_echo( exp_res, search_to_find, search_to_search, search_up_to_num_matches = undef) {
if (undef != search_up_to_num_matches) {
test_res = search(search_to_find, search_to_search, search_up_to_num_matches);
echo(str("Expect ", exp_res, " for search(", search_to_find, ", ", search_to_search, ", ", search_up_to_num_matches, ")=", test_res, ". ", (exp_res == test_res)?"OK":"FAIL" ));
}
else
{
assign( test_res = search(search_to_find, search_to_search) )
else {
test_res = search(search_to_find, search_to_search);
echo(str("Expect ", exp_res, " for search(", search_to_find, ", ", search_to_search, ")=", test_res, ". ", (exp_res == test_res)?"OK":"FAIL" ));
}
}

View File

@ -1046,6 +1046,7 @@ list(APPEND ECHO_FILES ${FUNCTION_FILES}
${CMAKE_SOURCE_DIR}/../testdata/scad/misc/value-reassignment-tests.scad
${CMAKE_SOURCE_DIR}/../testdata/scad/misc/value-reassignment-tests2.scad
${CMAKE_SOURCE_DIR}/../testdata/scad/misc/variable-scope-tests.scad
${CMAKE_SOURCE_DIR}/../testdata/scad/misc/scope-assignment-tests.scad
${CMAKE_SOURCE_DIR}/../testdata/scad/misc/lookup-tests.scad
${CMAKE_SOURCE_DIR}/../testdata/scad/misc/expression-shortcircuit-tests.scad
${CMAKE_SOURCE_DIR}/../testdata/scad/misc/parent_module-tests.scad
@ -1135,7 +1136,8 @@ disable_tests(
)
# 2D tests
list(APPEND ALL_2D_FILES ${FEATURES_2D_FILES} ${SCAD_DXF_FILES} ${EXAMPLE_2D_FILES} ${EXPERIMENTAL_TEXT_FILES})
list(APPEND FILES_2D ${FEATURES_2D_FILES} ${SCAD_DXF_FILES} ${EXAMPLE_2D_FILES} ${EXPERIMENTAL_TEXT_FILES})
list(APPEND ALL_2D_FILES ${FILES_2D})
# FIXME: This test illustrates a weakness in child() combined with modifiers.
# Reenable it when this is improved
@ -1198,6 +1200,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
@ -1212,6 +1215,8 @@ list(APPEND BUGS_FILES ${CMAKE_SOURCE_DIR}/../testdata/scad/bugs/issue584.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(REMOVE_ITEM EXPORT3D_TEST_FILES ${CMAKE_SOURCE_DIR}/../testdata/scad/bugs/issue899.scad)
list(APPEND ALL_2D_FILES ${CMAKE_SOURCE_DIR}/../testdata/scad/bugs/issue899.scad)
list(APPEND OPENCSGTEST_FILES ${BUGS_FILES})
list(APPEND CGALPNGTEST_FILES ${BUGS_FILES})
@ -1346,7 +1351,7 @@ set_test_config(Bugs offpngtest_polyhedron-tests
add_cmdline_test(monotonepngtest EXE ${OPENSCAD_BINPATH} ARGS --colorscheme=Monotone --enable=text --render -o SUFFIX png FILES ${EXPORT3D_TEST_FILES})
add_cmdline_test(stlpngtest EXE ${PYTHON_EXECUTABLE} SCRIPT ${CMAKE_SOURCE_DIR}/export_import_pngtest.py ARGS --openscad=${OPENSCAD_BINPATH} --format=STL --render=cgal EXPECTEDDIR monotonepngtest SUFFIX png FILES ${EXPORT3D_TEST_FILES})
add_cmdline_test(offpngtest EXE ${PYTHON_EXECUTABLE} SCRIPT ${CMAKE_SOURCE_DIR}/export_import_pngtest.py ARGS --openscad=${OPENSCAD_BINPATH} --format=OFF --render=cgal EXPECTEDDIR monotonepngtest SUFFIX png FILES ${EXPORT3D_TEST_FILES})
add_cmdline_test(dxfpngtest EXE ${PYTHON_EXECUTABLE} SCRIPT ${CMAKE_SOURCE_DIR}/export_import_pngtest.py ARGS --openscad=${OPENSCAD_BINPATH} --format=DXF --render=cgal EXPECTEDDIR cgalpngtest SUFFIX png FILES ${ALL_2D_FILES})
add_cmdline_test(dxfpngtest EXE ${PYTHON_EXECUTABLE} SCRIPT ${CMAKE_SOURCE_DIR}/export_import_pngtest.py ARGS --openscad=${OPENSCAD_BINPATH} --format=DXF --render=cgal EXPECTEDDIR cgalpngtest SUFFIX png FILES ${FILES_2D})
#

View File

@ -36,6 +36,7 @@
#include "export.h"
#include "builtin.h"
#include "Tree.h"
#include "PlatformUtils.h"
#ifndef _MSC_VER
#include <getopt.h>
@ -77,7 +78,9 @@ int main(int argc, char **argv)
currentdir = boosty::stringy( fs::current_path() );
parser_init(boosty::stringy(fs::path(argv[0]).branch_path()));
std::string appicationpath = boosty::stringy(fs::path(argv[0]).branch_path());
PlatformUtils::registerApplicationPath(appicationpath);
parser_init(appicationpath);
add_librarydir(boosty::stringy(fs::path(argv[0]).branch_path() / "../libraries"));
ModuleContext top_ctx;

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.

Before

Width:  |  Height:  |  Size: 7.3 KiB

After

Width:  |  Height:  |  Size: 8.1 KiB

View File

@ -1 +1 @@
group1(minkowski2+glide3+subdiv4+hull5+resize6+group7+group7+group7+intersection10+group11(sphere)+union13+difference14+intersection10+linear_extrude+linear_extrude+rotate_extrude+rotate_extrude+import+import+import+import+group7+cube+sphere+cylinder+polyhedron+square+circle+polygon+projection+render33+surface+transform35+transform35+transform37+transform35+transform35+color40)
group1(minkowski2+glide3+subdiv4+hull5+resize6+group7+group7+group7+intersection10+group11(sphere)+union13+difference14+intersection10+linear_extrude+linear_extrude+rotate_extrude+rotate_extrude+import+import+import+import+group7+cube+sphere+cylinder+polyhedron+square+circle+polygon+projection+render33+surface+transform35+transform35+transform37+transform35+transform35+color40+offset)

View File

@ -39,4 +39,5 @@ group() {
multmatrix([[1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1]]);
multmatrix([[1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1]]);
color([-1, -1, -1, 1]);
offset(delta = 1, join_type = "miter", miter_limit = 2, $fn = 0, $fa = 12, $fs = 2);
}

View File

@ -0,0 +1,30 @@
WARNING: Ignoring unknown variable 'h'.
ECHO: "union scope"
ECHO: "local a (5):", 5
ECHO: "global a (4):", 4
ECHO: "module scope:"
ECHO: "local b (7)", 7
ECHO: "local b (7)", 7
ECHO: "module children scope:"
ECHO: "b2 (3)", 3
ECHO: "for loop (c = 0,1,25):"
ECHO: "c", 0
ECHO: "c", 1
ECHO: "c", 25
ECHO: "if scope:"
ECHO: "d (8)", 8
ECHO: "else scope:"
ECHO: "d (9)", 9
ECHO: "anonymous inner scope (scope ignored):"
ECHO: "outer e (3)", 3
ECHO: "inner e (3)", 3
ECHO: "anonymous scope (scope ignored):"
ECHO: "outer f (2)", 2
ECHO: "inner f (2)", 2
ECHO: "anonymous scope reassign:"
ECHO: "g (2)", 2
ECHO: "anonymous reassign using outer (scope ignored)", undef
ECHO: "h (undef)", undef
ECHO: "override variable in assign scope:"
DEPRECATED: The assign() module will be removed in future releases. Use a regular assignment instead.
ECHO: "i (10)", 10

View File

@ -18,6 +18,7 @@ ECHO: "user-defined special variables as parameter"
ECHO: 7
ECHO: 7
ECHO: "assign only visible in children's scope"
DEPRECATED: The assign() module will be removed in future releases. Use a regular assignment instead.
WARNING: Ignoring unknown variable 'c'.
ECHO: undef
ECHO: 5

View File

@ -28,4 +28,6 @@ y = !i;
z = j;
aa = (k ? l : m);
bb = n[o];
cc = let(a = 1) a;
dd = [for(a = [0, 1]) let(b = a) if(true) b];

View File

@ -16,14 +16,19 @@ o = floor();
p = pow();
q = sqrt();
r = exp();
ra = len();
s = log();
t = ln();
u = str();
ua = chr();
ub = concat();
v = lookup();
w = dxf_dim();
x = dxf_cross();
va = search();
y = version();
z = version_num();
aa = len();
bb = search();
za = norm();
zb = cross();
zc = parent_module();
w = dxf_dim();
x = dxf_cross();

View File

@ -38,4 +38,6 @@ mirror();
translate();
multmatrix();
color();
offset();
text();

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.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 20 KiB

After

Width:  |  Height:  |  Size: 20 KiB

Some files were not shown because too many files have changed in this diff Show More