From 5669f0d95f332b9b2c49a0725bfc088929811fcd Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Sun, 19 Oct 2014 17:56:51 -0400 Subject: [PATCH 01/47] Bumped CGAL to 4.5 --- scripts/macosx-build-dependencies.sh | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/scripts/macosx-build-dependencies.sh b/scripts/macosx-build-dependencies.sh index 52441051..1e290f8a 100755 --- a/scripts/macosx-build-dependencies.sh +++ b/scripts/macosx-build-dependencies.sh @@ -356,8 +356,9 @@ build_cgal() cd $BASEDIR/src rm -rf CGAL-$version if [ ! -f CGAL-$version.tar.gz ]; then - # 4.4 - curl -O https://gforge.inria.fr/frs/download.php/file/33525/CGAL-$version.tar.gz + # 4.5 + curl -O https://gforge.inria.fr/frs/download.php/file/34149/CGAL-$version.tar.gz + # 4.4 curl -O https://gforge.inria.fr/frs/download.php/file/33525/CGAL-$version.tar.gz # 4.3 curl -O https://gforge.inria.fr/frs/download.php/32994/CGAL-$version.tar.gz # 4.2 curl -O https://gforge.inria.fr/frs/download.php/32359/CGAL-$version.tar.gz # 4.1 curl -O https://gforge.inria.fr/frs/download.php/31641/CGAL-$version.tar.gz @@ -777,7 +778,7 @@ build_gmp 5.1.3 build_mpfr 3.1.2 build_boost 1.54.0 # NB! For CGAL, also update the actual download URL in the function -build_cgal 4.4 +build_cgal 4.5 build_glew 1.10.0 build_gettext 0.18.3.2 build_libffi 3.1 From ebb7dde012e6409a617e9c8765bf932bcb6d9aa5 Mon Sep 17 00:00:00 2001 From: Torsten Paul Date: Mon, 20 Oct 2014 00:21:06 +0200 Subject: [PATCH 02/47] Fix status handling for docked windows. Especially for the case where the windows are docked as tabs in the same position, the "visibility-changed" signal does not work as close indicator. The window is also treated as invisible when just the tab is invisible, not only in case the window is closed. --- openscad.pro | 2 ++ src/Dock.cc | 32 ++++++++++++++++++++++++++++++++ src/Dock.h | 23 +++++++++++++++++++++++ src/MainWindow.h | 1 - src/MainWindow.ui | 12 ++++++++++-- src/mainwin.cc | 22 ++++++---------------- 6 files changed, 73 insertions(+), 19 deletions(-) create mode 100644 src/Dock.cc create mode 100644 src/Dock.h diff --git a/openscad.pro b/openscad.pro index 067576f1..a2692b66 100644 --- a/openscad.pro +++ b/openscad.pro @@ -307,6 +307,7 @@ src/FontCache.h \ src/system-gl.h \ src/CsgInfo.h \ \ + src/Dock.h \ src/AutoUpdater.h \ src/launchingscreen.h \ src/legacyeditor.h \ @@ -397,6 +398,7 @@ SOURCES += src/version_check.cc \ src/openscad.cc \ src/mainwin.cc \ src/UIUtils.cc \ + src/Dock.cc \ src/FontListDialog.cc \ src/launchingscreen.cc \ src/legacyeditor.cc \ diff --git a/src/Dock.cc b/src/Dock.cc new file mode 100644 index 00000000..17ba9e20 --- /dev/null +++ b/src/Dock.cc @@ -0,0 +1,32 @@ +#include +#include + +#include "Dock.h" + +Dock::Dock(QWidget *parent) : QDockWidget(parent), action(NULL) +{ +} + +Dock::~Dock() +{ +} + +void Dock::setVisible(bool visible) +{ + QSettings settings; + settings.setValue(configKey, !visible); + if (action != NULL) { + action->setChecked(!visible); + } + QDockWidget::setVisible(visible); +} + +void Dock::setConfigKey(const QString configKey) +{ + this->configKey = configKey; +} + +void Dock::setAction(QAction *action) +{ + this->action = action; +} \ No newline at end of file diff --git a/src/Dock.h b/src/Dock.h new file mode 100644 index 00000000..58334b3d --- /dev/null +++ b/src/Dock.h @@ -0,0 +1,23 @@ +#pragma once + +#include +#include +#include + +class Dock : public QDockWidget +{ + Q_OBJECT + +public: + Dock(QWidget *parent = NULL); + virtual ~Dock(); + void setConfigKey(const QString configKey); + void setAction(QAction *action); + +public slots: + void setVisible(bool visible); + +private: + QString configKey; + QAction *action; +}; diff --git a/src/MainWindow.h b/src/MainWindow.h index 482cb205..7b976f82 100644 --- a/src/MainWindow.h +++ b/src/MainWindow.h @@ -239,7 +239,6 @@ private: char const * afterCompileSlot; bool procevents; - bool isClosing; class QTemporaryFile *tempFile; class ProgressWidget *progresswidget; class CGALWorker *cgalworker; diff --git a/src/MainWindow.ui b/src/MainWindow.ui index 22b80e3d..8553e8e4 100644 --- a/src/MainWindow.ui +++ b/src/MainWindow.ui @@ -142,6 +142,8 @@ 0 0 + 1397 + 33 @@ -287,7 +289,7 @@ - + 1 @@ -410,7 +412,7 @@ - + 8 @@ -1092,6 +1094,12 @@
QGLView.h
1 + + Dock + QDockWidget +
Dock.h
+ 1 +
diff --git a/src/mainwin.cc b/src/mainwin.cc index 23651190..c94d370b 100644 --- a/src/mainwin.cc +++ b/src/mainwin.cc @@ -225,7 +225,6 @@ MainWindow::MainWindow(const QString &filename) tval = 0; fps = 0; fsteps = 1; - isClosing = false; const QString importStatement = "import(\"%1\");\n"; const QString surfaceStatement = "surface(\"%1\");\n"; @@ -532,6 +531,10 @@ MainWindow::MainWindow(const QString &filename) editor->setInitialSizeHint(QSize((5 * this->width() / 11), 100)); } + this->editorDock->setConfigKey("view/hideEditor"); + this->editorDock->setAction(this->viewActionHideEditor); + this->consoleDock->setConfigKey("view/hideConsole"); + this->consoleDock->setAction(this->viewActionHideConsole); connect(this->editorDock, SIGNAL(topLevelChanged(bool)), this, SLOT(editorTopLevelChanged(bool))); connect(this->consoleDock, SIGNAL(topLevelChanged(bool)), this, SLOT(consoleTopLevelChanged(bool))); @@ -2265,25 +2268,13 @@ void MainWindow::viewAll() this->qglview->updateGL(); } -void MainWindow::on_editorDock_visibilityChanged(bool visible) +void MainWindow::on_editorDock_visibilityChanged(bool) { - if (isClosing) { - return; - } - QSettings settings; - settings.setValue("view/hideEditor", !visible); - viewActionHideEditor->setChecked(!visible); editorTopLevelChanged(editorDock->isFloating()); } -void MainWindow::on_consoleDock_visibilityChanged(bool visible) +void MainWindow::on_consoleDock_visibilityChanged(bool) { - if (isClosing) { - return; - } - QSettings settings; - settings.setValue("view/hideConsole", !visible); - viewActionHideConsole->setChecked(!visible); consoleTopLevelChanged(consoleDock->isFloating()); } @@ -2453,7 +2444,6 @@ void MainWindow::closeEvent(QCloseEvent *event) delete this->tempFile; this->tempFile = NULL; } - isClosing = true; event->accept(); } else { event->ignore(); From ea39c70471c1547dc52e4a348635ba6f2460cc13 Mon Sep 17 00:00:00 2001 From: Torsten Paul Date: Mon, 20 Oct 2014 00:22:22 +0200 Subject: [PATCH 03/47] Ensure window is visible after restoring the window state (fixes #976). --- src/mainwin.cc | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/src/mainwin.cc b/src/mainwin.cc index c94d370b..e5069f98 100644 --- a/src/mainwin.cc +++ b/src/mainwin.cc @@ -86,6 +86,7 @@ #include #include #include +#include #include @@ -529,6 +530,24 @@ MainWindow::MainWindow(const QString &filename) * fill the available space. */ editor->setInitialSizeHint(QSize((5 * this->width() / 11), 100)); + } else { +#ifdef Q_OS_WIN + // Try moving the main window into the display range, this + // can occur when closing OpenSCAD on a second monitor which + // is not available at the time the application is started + // again. + // On Windows that causes the main window to open in a not + // easily reachable place. + QDesktopWidget *desktop = QApplication::desktop(); + QRect desktopRect = desktop->frameGeometry().adjusted(250, 150, -250, -150).normalized(); + QRect windowRect = frameGeometry(); + if (!desktopRect.intersects(windowRect)) { + windowRect.moveCenter(desktopRect.center()); + windowRect = windowRect.intersected(desktopRect); + move(windowRect.topLeft()); + resize(windowRect.size()); + } +#endif } this->editorDock->setConfigKey("view/hideEditor"); From a23d463020e1d4c1bb1ed73af3e9c54bfe21654a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miro=20Hron=C4=8Dok?= Date: Tue, 21 Oct 2014 11:50:43 +0200 Subject: [PATCH 04/47] Test case for #990 --- testdata/scad/bugs/issue990.scad | 5 +++++ tests/CMakeLists.txt | 3 ++- .../regression/cgalpngtest/issue990-expected.png | Bin 0 -> 1548 bytes .../regression/opencsgtest/issue990-expected.png | Bin 0 -> 1548 bytes 4 files changed, 7 insertions(+), 1 deletion(-) create mode 100644 testdata/scad/bugs/issue990.scad create mode 100644 tests/regression/cgalpngtest/issue990-expected.png create mode 100644 tests/regression/opencsgtest/issue990-expected.png diff --git a/testdata/scad/bugs/issue990.scad b/testdata/scad/bugs/issue990.scad new file mode 100644 index 00000000..172da17f --- /dev/null +++ b/testdata/scad/bugs/issue990.scad @@ -0,0 +1,5 @@ +hull() { + for (i = [0:1]) { + cylinder(h=0); + } +} diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index ac5626fc..a4130dc9 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -1205,7 +1205,8 @@ list(APPEND BUGS_FILES ${CMAKE_SOURCE_DIR}/../testdata/scad/bugs/issue584.scad ${CMAKE_SOURCE_DIR}/../testdata/scad/bugs/issue913.scad ${CMAKE_SOURCE_DIR}/../testdata/scad/bugs/issue936.scad ${CMAKE_SOURCE_DIR}/../testdata/scad/bugs/issue964.scad - ${CMAKE_SOURCE_DIR}/../testdata/scad/bugs/issue964b.scad) + ${CMAKE_SOURCE_DIR}/../testdata/scad/bugs/issue964b.scad + ${CMAKE_SOURCE_DIR}/../testdata/scad/bugs/issue990.scad) list(APPEND EXPORT3D_TEST_FILES ${BUGS_FILES}) list(APPEND OPENCSGTEST_FILES ${BUGS_FILES}) diff --git a/tests/regression/cgalpngtest/issue990-expected.png b/tests/regression/cgalpngtest/issue990-expected.png new file mode 100644 index 0000000000000000000000000000000000000000..57f7f9d6b6dfef3a7b121c50b6b2a479ba3f8bbd GIT binary patch literal 1548 zcmeAS@N?(olHy`uVBq!ia0y~yU;;9k7&t&wwUqN(AjOvC?e4YL|0KPSh)z&g{@#WAGf*4wLwj0_Ac431yc zYqHC(d8hQ}ljUW`1NN$n4U7y43=BZsYz*Wu$ Date: Tue, 21 Oct 2014 20:11:19 +0200 Subject: [PATCH 05/47] Fix crash in hull() with empty CGAL child geometry (fixes #990). --- src/cgalutils.cc | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/cgalutils.cc b/src/cgalutils.cc index 1a56f127..dd156720 100644 --- a/src/cgalutils.cc +++ b/src/cgalutils.cc @@ -365,8 +365,10 @@ namespace CGALUtils { const shared_ptr &chgeom = item.second; const CGAL_Nef_polyhedron *N = dynamic_cast(chgeom.get()); if (N) { - for (CGAL_Nef_polyhedron3::Vertex_const_iterator i = N->p3->vertices_begin(); i != N->p3->vertices_end(); ++i) { - points.insert(K::Point_3(to_double(i->point()[0]),to_double(i->point()[1]),to_double(i->point()[2]))); + if (!N->isEmpty()) { + for (CGAL_Nef_polyhedron3::Vertex_const_iterator i = N->p3->vertices_begin(); i != N->p3->vertices_end(); ++i) { + points.insert(K::Point_3(to_double(i->point()[0]),to_double(i->point()[1]),to_double(i->point()[2]))); + } } } else { const PolySet *ps = dynamic_cast(chgeom.get()); From f66d274c6e409e8480ef071763f6df4f0afb9b6c Mon Sep 17 00:00:00 2001 From: Torsten Paul Date: Tue, 21 Oct 2014 20:27:10 +0200 Subject: [PATCH 06/47] Add cubes to test case to ensure something is rendered. --- testdata/scad/bugs/issue990.scad | 3 +++ .../cgalpngtest/issue990-expected.png | Bin 1548 -> 2804 bytes .../monotonepngtest/issue990-expected.png | Bin 0 -> 2804 bytes .../opencsgtest/issue990-expected.png | Bin 1548 -> 2919 bytes 4 files changed, 3 insertions(+) create mode 100644 tests/regression/monotonepngtest/issue990-expected.png diff --git a/testdata/scad/bugs/issue990.scad b/testdata/scad/bugs/issue990.scad index 172da17f..f5da189a 100644 --- a/testdata/scad/bugs/issue990.scad +++ b/testdata/scad/bugs/issue990.scad @@ -3,3 +3,6 @@ hull() { cylinder(h=0); } } + +translate([-5, 0, 0]) cube(); +translate([5, 0, 0]) cube(); diff --git a/tests/regression/cgalpngtest/issue990-expected.png b/tests/regression/cgalpngtest/issue990-expected.png index 57f7f9d6b6dfef3a7b121c50b6b2a479ba3f8bbd..2118236dc964daa501eb9627a8c2d5da3ef2aa99 100644 GIT binary patch literal 2804 zcmds3eKeF=7=PZGF=J#z*bHf=r7e|ZoGi)5D?_A{k2p$bn%xSq?6yV5@KV0gx5}Ip z(wCHsvr3XoX=VGumV<;j$EG2MT{FluGy9^m+t!}_XV3mof8F=Jzk8qi{GQ))pXX-z zu31UbGS&hBnwKZrAAo>=50%%oxv0Ve=k%1N#B4X-_&|vjf&4|8nQp2g# zsMn9%XJGls4uH|gpt~8s@6#J%Ah*WB2#*Jc`D;v#+Te;gf$4!WB|zpZK#u|xkwAAo zU<(moQ-QhaqlNhJb(szcCu&4~y`ex%TAT%$x}OxoxAItFVtUm zP?h4I#C0tR;(KRJ;>Ghp6nId@;>Pl``w_H8-s)3VFxH*4aj?ZD$vH5Y|0Mz{+kx9@ zT(Ptg1#E3POHflyktR)=*u80H{XJ1buZ9qX8mPT{T|t}tZK=gliw zIC%-*xnBFE>Y^a7^K=3cG`=mNfUn#8 zgx>M%L$=JP+mP|PFw>s%dhVNyG}wKHz8AbsS)O%or>%1J(knl~tgPrea>7txSXhyh z<+0bm+D4qB=z6|==?a7Tkm_+4Amb4{g3~^Wt8RgS=YRX{5~?OH@{7tq(tSN5tSDw- zb5--kM1>*W7g`%|k$omE|ms%zm+CVvqOL>Tajz47kZP z=8G(EkS_-*ByM3_e@j^uK*!cZ(1i*#bde6az>&C) z(l{R(L#t``cTaAzyJO4i-rQk?l#MziMGs}ywo50JX<#StV8qVOei0>;YRhgZz@2XQ z$XiBhwSQQqynB@%FOtSwtL7zZi1N-iQ=WHnmzjhfN}&umqkicO>~WQL8=qOa1d&wG z!%a9cBsfPxoLd@=%BbM(IUB%%0Eh6~Y96=&^7GGFfl=l&0-!#)niuyWZHa1Ko+!7G zaYju63nGX-0e*Q$?2W`aydTu(W?Dg1w2GM32Vd?s#t`0Wd zrVlI>%z1L1hP%UsjWF>00zUMZ?3NEr7t0w_d=+)BLSjCd}Xt|b8l zh@NRF-Z9p%4-+&|$>zcW zavPr$1lR%>fbqa7L4>&iar4WRX^x|z;AH~5Y1kRsB z9#OW4q(mo&ha)u;=|KrcQy#Q3^3>N9Xe)l;&9=T#Az~s(;=maSC)l{@%|Sfg9CHL& zcU3zo8tbH_8|Y&Z5$MQj{8($@S-2cbo@2z87hwD38Xa7gAku09g+p!vNe|6RkwXYJ|sxT_VulQ)Y`M*3x yLW%2mJD7N<7oiQ^33IBgvcP`9C-8vzfHIjg67j^=AW9Qg6};Tnu&=D(r2YXx3LIGg literal 1548 zcmeAS@N?(olHy`uVBq!ia0y~yU;;9k7&t&wwUqN(AjOvC?e4YL|0KPSh)z&g{@#WAGf*4wLwj0_Ac431yc zYqHC(d8hQ}ljUW`1NN$n4U7y43=BZsYz*Wu$=50%%oxv0Ve=k%1N#B4X-_&|vjf&4|8nQp2g# zsMn9%XJGls4uH|gpt~8s@6#J%Ah*WB2#*Jc`D;v#+Te;gf$4!WB|zpZK#u|xkwAAo zU<(moQ-QhaqlNhJb(szcCu&4~y`ex%TAT%$x}OxoxAItFVtUm zP?h4I#C0tR;(KRJ;>Ghp6nId@;>Pl``w_H8-s)3VFxH*4aj?ZD$vH5Y|0Mz{+kx9@ zT(Ptg1#E3POHflyktR)=*u80H{XJ1buZ9qX8mPT{T|t}tZK=gliw zIC%-*xnBFE>Y^a7^K=3cG`=mNfUn#8 zgx>M%L$=JP+mP|PFw>s%dhVNyG}wKHz8AbsS)O%or>%1J(knl~tgPrea>7txSXhyh z<+0bm+D4qB=z6|==?a7Tkm_+4Amb4{g3~^Wt8RgS=YRX{5~?OH@{7tq(tSN5tSDw- zb5--kM1>*W7g`%|k$omE|ms%zm+CVvqOL>Tajz47kZP z=8G(EkS_-*ByM3_e@j^uK*!cZ(1i*#bde6az>&C) z(l{R(L#t``cTaAzyJO4i-rQk?l#MziMGs}ywo50JX<#StV8qVOei0>;YRhgZz@2XQ z$XiBhwSQQqynB@%FOtSwtL7zZi1N-iQ=WHnmzjhfN}&umqkicO>~WQL8=qOa1d&wG z!%a9cBsfPxoLd@=%BbM(IUB%%0Eh6~Y96=&^7GGFfl=l&0-!#)niuyWZHa1Ko+!7G zaYju63nGX-0e*Q$?2W`aydTu(W?Dg1w2GM32Vd?s#t`0Wd zrVlI>%z1L1hP%UsjWF>00zUMZ?3NEr7t0w_d=+)BLSjCd}Xt|b8l zh@NRF-Z9p%4-+&|$>zcW zavPr$1lR%>fbqa7L4>&iar4WRX^x|z;AH~5Y1kRsB z9#OW4q(mo&ha)u;=|KrcQy#Q3^3>N9Xe)l;&9=T#Az~s(;=maSC)l{@%|Sfg9CHL& zcU3zo8tbH_8|Y&Z5$MQj{8($@S-2cbo@2z87hwD38Xa7gAku09g+p!vNe|6RkwXYJ|sxT_VulQ)Y`M*3x yLW%2mJD7N<7oiQ^33IBgvcP`9C-8vzfHIjg67j^=AW9Qg6};Tnu&=D(r2YXx3LIGg literal 0 HcmV?d00001 diff --git a/tests/regression/opencsgtest/issue990-expected.png b/tests/regression/opencsgtest/issue990-expected.png index 3bada54b8cdcfe759d8ffdc1dcc3ee7838f160bd..3241a08b1d9e6a995be1950aa0a243c3a19388a7 100644 GIT binary patch literal 2919 zcmds3X;4#F6h1G(K#&*^mju+%1w{o+kw8&_L_kr?q9Rlg2qGe)hNVR`Ja`dDQ7KlW zLeT;h(YUZERz!+M(a{=3KoBG>Iy#jlfN0V{Afz|8!`M#ytNo+D?!E7<-?`tp@9g*W zUP?1GGXwzIGEeta03@^}fq`xjnzV+7IR3UVK^u1%itdPu6O4*RLSVKig53FHUPg>415^PgzQJsl-$ zm6$}iGf`Wtc_O5bw&0YHK~kaa7PYay2XKy3Jqeg< z-KP9#BsKsC;OKz`BI}-sK=>jIh^C9F5Ix<$$4g0F{Rv3KI$i3>On@KtptJN?K!~LD zpG>%j=LVK)!xiR zv3JLW@l|&|0*N_|Nq*!y6N8%C)kg9pDh9jiZ#{i6v01Z@1d5{BH@qT@zR+4;Y3mO; zD*(HZG+rgm&lKU<(Wno;Zf}vilh#<=F_?cBszV^DR7ZiYRxN6Vy zPgKi{|LM4eiF1QwKCFALkMpj3bdcCKO{X7)DQMNg7R?MMB-DFDuDK@84x$^m5PWUe z*$zH+l*0N&>X#eAGs+udM5}~ox0!;8%XQL|c6E^E@K(BE9cIv~^O7@_MRcW&Ix)d) z$`oRDf6^f%@G|4Td^4SA`%P(Zf0xe7<|RdN$zJVj2A6(Z4C&{3e>K(wPsWGTRm1Jh z@&Y=RaKsSnoEFd)5XQ8s)Vc#v5!fJ9sQVn$y_DMCq#<_}iCr4rcsh%+)p1{EQzGXe z-M(Zy9AJh^`p7%2mkbwXh$6e=uP2_MV~mHf_gQmk&D$r`2{cD4^fSyk;IWk=cj3n1 z3!MFTzKT&kbY+%dDgC2;p{^|hz_BJL3-KMoHBRJ|ei!ciVxQA@=FnY=gOx9A9lOiHZQNU9LpAkE3o8DT~1A-OApecMbvTm389oU7m2ye z3Ho4VhA6JBFUv-A#Q<^T@S19!2^ct@PK~w&cgG{JmQ+;J3U> z144?A^y3ODWF6x{y!QG*7c8I0AxFotH1V+L+$Ml*Hlj>-AvSm;c=~fOZBHm;#>dN9 zDSL%m&2OyaZI3%-FN;l4v>z@ye?mTIt+{OeZ`wtc<3`*Dsz9Cwpof}^M+L6$c>Vmy zh@qU}-b*)=G2?qTG068Py~>nID^PS(od)7R>i97ODKc1b-GuP5W)a`F3QpJ00{Oj7 zB#``!0O-0J@p$({A|fcbrqBnnH+%>7+qxo1ugceufQw(AL=5-(sr3j=Ga3`J>tYH! zB3l$a!mc|t^3mrJU8ZmfJy~Z2+{+rHW}MIRHI}Cr-Yow&SZs1`~o*R(SOl%KGAx@j;;~k#Bk-y_3@`rrfVlkg-M+ zor^$6ay%>bd=41JQjQ9UHhs^=aTZG2-J`z{UHS-)CAUD98vh&kcgbOMVR#@iY?Owc?zx#LW Date: Fri, 31 Oct 2014 10:08:07 +0400 Subject: [PATCH 07/47] Added testcase for #1000 --- testdata/scad/bugs/issue1000.scad | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) create mode 100644 testdata/scad/bugs/issue1000.scad diff --git a/testdata/scad/bugs/issue1000.scad b/testdata/scad/bugs/issue1000.scad new file mode 100644 index 00000000..bcd97935 --- /dev/null +++ b/testdata/scad/bugs/issue1000.scad @@ -0,0 +1,16 @@ +// +// CSG rendering issue: +// This results in a blue sphere rather than a sphere consisting of red/blue half spheres +// The reason is likely that OpenCSG doesn't track +// which positive object is the source of what depth fragment and thus lets the last rendered object win. +// + +color([1,0,0]) translate([0,0,0]) intersection() { + sphere(10); + translate([0,0,10]) cube([20,20,20],center=true); +} + +color([0,0,1]) difference() { + sphere(10); + translate([0,0,10]) cube([20,20,20],center=true); +} From a93196eb7ed99f4d8cb23d66bb2f0c25a86e7d4e Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Fri, 31 Oct 2014 11:45:04 +0400 Subject: [PATCH 08/47] Update settings for show/hide toolbars. Fixes #1001 --- src/mainwin.cc | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/src/mainwin.cc b/src/mainwin.cc index e5069f98..cd61ec8a 100644 --- a/src/mainwin.cc +++ b/src/mainwin.cc @@ -178,6 +178,11 @@ MainWindow::MainWindow(const QString &filename) { setupUi(this); + this->editorDock->setConfigKey("view/hideEditor"); + this->editorDock->setAction(this->viewActionHideEditor); + this->consoleDock->setConfigKey("view/hideConsole"); + this->consoleDock->setAction(this->viewActionHideConsole); + editortype = Preferences::inst()->getValue("editor/editortype").toString(); useScintilla = (editortype == "QScintilla Editor"); @@ -550,10 +555,6 @@ MainWindow::MainWindow(const QString &filename) #endif } - this->editorDock->setConfigKey("view/hideEditor"); - this->editorDock->setAction(this->viewActionHideEditor); - this->consoleDock->setConfigKey("view/hideConsole"); - this->consoleDock->setAction(this->viewActionHideConsole); connect(this->editorDock, SIGNAL(topLevelChanged(bool)), this, SLOT(editorTopLevelChanged(bool))); connect(this->consoleDock, SIGNAL(topLevelChanged(bool)), this, SLOT(consoleTopLevelChanged(bool))); @@ -2319,7 +2320,11 @@ void MainWindow::setDockWidgetTitle(QDockWidget *dockWidget, QString prefix, boo void MainWindow::hideToolbars() { - if (viewActionHideToolBars->isChecked()) { + QSettings settings; + bool shouldHide = viewActionHideToolBars->isChecked(); + settings.setValue("view/hideToolbar", shouldHide); + + if (shouldHide) { viewerToolBar->hide(); editortoolbar->hide(); } else { From 6c703ab3ef50ee235cfff6515470a48b78f8e7b3 Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Fri, 31 Oct 2014 12:34:19 +0400 Subject: [PATCH 09/47] Bugfix: OpenCSG-1.4.0 installed the lib in the wrong location. Fixes #997 --- scripts/macosx-build-dependencies.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/macosx-build-dependencies.sh b/scripts/macosx-build-dependencies.sh index 1e290f8a..a5d4dbb0 100755 --- a/scripts/macosx-build-dependencies.sh +++ b/scripts/macosx-build-dependencies.sh @@ -427,7 +427,7 @@ build_opencsg() if $OPTION_32BIT; then OPENCSG_EXTRA_FLAGS="x86" fi - qmake -r QMAKE_CXXFLAGS+="-I$DEPLOYDIR/include" QMAKE_LFLAGS+="-L$DEPLOYDIR/lib" CONFIG+="x86_64 $OPENCSG_EXTRA_FLAGS" + qmake -r QMAKE_CXXFLAGS+="-I$DEPLOYDIR/include" QMAKE_LFLAGS+="-L$DEPLOYDIR/lib" CONFIG+="x86_64 $OPENCSG_EXTRA_FLAGS" DESTDIR=$DEPLOYDIR make install } From cf979b3900ab28864913dbca2c8ba5c842ef1c31 Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Fri, 31 Oct 2014 12:34:54 +0400 Subject: [PATCH 10/47] Bumped Ragel to 6.9 and harfbuzz to 0.9.35 --- scripts/macosx-build-dependencies.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/scripts/macosx-build-dependencies.sh b/scripts/macosx-build-dependencies.sh index a5d4dbb0..0d46f60b 100755 --- a/scripts/macosx-build-dependencies.sh +++ b/scripts/macosx-build-dependencies.sh @@ -655,7 +655,7 @@ build_ragel() cd "$BASEDIR"/src rm -rf "ragel-$version" if [ ! -f "ragel-$version.tar.gz" ]; then - curl --insecure -LO "http://www.complang.org/ragel/ragel-$version.tar.gz" + curl --insecure -LO "http://www.colm.net/wp-content/uploads/2014/10/ragel-$version.tar.gz" fi tar xzf "ragel-$version.tar.gz" cd "ragel-$version" @@ -785,8 +785,8 @@ build_libffi 3.1 build_glib2 2.40.0 build_opencsg 1.4.0 build_freetype 2.5.3 --without-png -build_ragel 6.8 -build_harfbuzz 0.9.28 "--with-coretext=auto --with-glib=no" +build_ragel 6.9 +build_harfbuzz 0.9.35 "--with-coretext=auto --with-glib=no" export FREETYPE_CFLAGS="-I$DEPLOYDIR/include -I$DEPLOYDIR/include/freetype2" export FREETYPE_LIBS="-L$DEPLOYDIR/lib -lfreetype" build_libxml2 2.9.1 From a68b39ead7f2b719da621be936a8be97bf75c6a7 Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Fri, 31 Oct 2014 15:28:26 +0400 Subject: [PATCH 11/47] Fix regression related to intersection with empty shapes. Fixes #996 --- src/CSGTermEvaluator.cc | 18 ++++++++++++------ .../scad/3D/features/intersection-tests.scad | 14 ++++++++++++++ .../intersection-tests-expected.png | Bin 7853 -> 7973 bytes .../dumptest/intersection-tests-expected.csg | 18 ++++++++++++++++++ .../intersection-tests-expected.png | Bin 4292 -> 7776 bytes .../intersection-tests-expected.png | Bin 12180 -> 11680 bytes 6 files changed, 44 insertions(+), 6 deletions(-) diff --git a/src/CSGTermEvaluator.cc b/src/CSGTermEvaluator.cc index e298bf7e..eef880f8 100644 --- a/src/CSGTermEvaluator.cc +++ b/src/CSGTermEvaluator.cc @@ -113,8 +113,10 @@ Response CSGTermEvaluator::visit(State &state, const AbstractPolyNode &node) shared_ptr t1; if (this->geomevaluator) { shared_ptr geom = this->geomevaluator->evaluateGeometry(node, false); - t1 = evaluate_csg_term_from_geometry(state, this->highlights, this->background, - geom, node.modinst, node); + if (geom) { + t1 = evaluate_csg_term_from_geometry(state, this->highlights, this->background, + geom, node.modinst, node); + } node.progress_report(); } this->stored_term[node.index()] = t1; @@ -178,8 +180,10 @@ Response CSGTermEvaluator::visit(State &state, const RenderNode &node) shared_ptr geom; if (this->geomevaluator) { geom = this->geomevaluator->evaluateGeometry(node, false); - t1 = evaluate_csg_term_from_geometry(state, this->highlights, this->background, - geom, node.modinst, node); + if (geom) { + t1 = evaluate_csg_term_from_geometry(state, this->highlights, this->background, + geom, node.modinst, node); + } node.progress_report(); } this->stored_term[node.index()] = t1; @@ -196,8 +200,10 @@ Response CSGTermEvaluator::visit(State &state, const CgaladvNode &node) shared_ptr geom; if (this->geomevaluator) { geom = this->geomevaluator->evaluateGeometry(node, false); - t1 = evaluate_csg_term_from_geometry(state, this->highlights, this->background, - geom, node.modinst, node); + if (geom) { + t1 = evaluate_csg_term_from_geometry(state, this->highlights, this->background, + geom, node.modinst, node); + } node.progress_report(); } this->stored_term[node.index()] = t1; diff --git a/testdata/scad/3D/features/intersection-tests.scad b/testdata/scad/3D/features/intersection-tests.scad index d4e32dbd..bd02b952 100644 --- a/testdata/scad/3D/features/intersection-tests.scad +++ b/testdata/scad/3D/features/intersection-tests.scad @@ -46,6 +46,20 @@ translate([0,-12,0]) intersection() { cube(0); } +// Intersecting something with nothing (issue 996) +translate([0,-12,0]) intersection() { + cube(4, center=true); + linear_extrude(); +} +translate([0,-16,0]) intersection() { + cube(4, center=true); + render(); +} +translate([0,-20,0]) intersection() { + cube(4, center=true); + minkowski(); +} + // Intersecting 2D with 3D translate([12,-12,0]) intersection() { cube([5,5,5], center=true); diff --git a/tests/regression/cgalpngtest/intersection-tests-expected.png b/tests/regression/cgalpngtest/intersection-tests-expected.png index 0d40a99b29fa8e7cc6d7639a5330398f11f0d5b7..de241da26694f9a13cad8c57f8ee8f3fba27a21c 100644 GIT binary patch literal 7973 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 F{SPS|XLJAn literal 7853 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 diff --git a/tests/regression/dumptest/intersection-tests-expected.csg b/tests/regression/dumptest/intersection-tests-expected.csg index 1091c8d8..5c3eb7f8 100644 --- a/tests/regression/dumptest/intersection-tests-expected.csg +++ b/tests/regression/dumptest/intersection-tests-expected.csg @@ -60,6 +60,24 @@ group() { cube(size = [0, 0, 0], center = false); } } + multmatrix([[1, 0, 0, 0], [0, 1, 0, -12], [0, 0, 1, 0], [0, 0, 0, 1]]) { + intersection() { + cube(size = [4, 4, 4], center = true); + linear_extrude(height = 100, center = false, convexity = 1, scale = [1, 1], $fn = 0, $fa = 12, $fs = 2); + } + } + multmatrix([[1, 0, 0, 0], [0, 1, 0, -16], [0, 0, 1, 0], [0, 0, 0, 1]]) { + intersection() { + cube(size = [4, 4, 4], center = true); + render(convexity = 1); + } + } + multmatrix([[1, 0, 0, 0], [0, 1, 0, -20], [0, 0, 1, 0], [0, 0, 0, 1]]) { + intersection() { + cube(size = [4, 4, 4], center = true); + minkowski(convexity = 0); + } + } multmatrix([[1, 0, 0, 12], [0, 1, 0, -12], [0, 0, 1, 0], [0, 0, 0, 1]]) { intersection() { cube(size = [5, 5, 5], center = true); diff --git a/tests/regression/opencsgtest/intersection-tests-expected.png b/tests/regression/opencsgtest/intersection-tests-expected.png index 1285ea394fd71b4442aa57cd5bcf01713c16408f..8d4ca7a7845392ca72c47e19156f4d2468201c3c 100644 GIT binary patch literal 7776 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 GCjAeFtrG13 literal 4292 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 literal 12180 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 z Date: Sat, 1 Nov 2014 17:24:28 +0100 Subject: [PATCH 12/47] Change console minimum size to 10x10. --- src/MainWindow.ui | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/MainWindow.ui b/src/MainWindow.ui index 8553e8e4..66cdd4e9 100644 --- a/src/MainWindow.ui +++ b/src/MainWindow.ui @@ -423,6 +423,12 @@ + + + 10 + 10 + + Qt::ClickFocus From 63201e25fdfb95ee59fc9e1c7a7c3a69faa086c9 Mon Sep 17 00:00:00 2001 From: Torsten Paul Date: Sat, 1 Nov 2014 18:55:48 +0100 Subject: [PATCH 13/47] Add option to disable window reordering by removing the dock window title bar. --- src/MainWindow.h | 5 +++++ src/Preferences.cc | 15 +++++++++++++++ src/Preferences.h | 4 +++- src/Preferences.ui | 17 ++++++++++++----- src/mainwin.cc | 19 +++++++++++++++++++ 5 files changed, 54 insertions(+), 6 deletions(-) diff --git a/src/MainWindow.h b/src/MainWindow.h index 7b976f82..4506a3d3 100644 --- a/src/MainWindow.h +++ b/src/MainWindow.h @@ -67,6 +67,9 @@ public: QAction *actionRecentFile[UIUtils::maxRecentFiles]; QMap knownFileExtensions; + QWidget *editorDockTitleWidget; + QWidget *consoleDockTitleWidget; + QString editortype; bool useScintilla; @@ -81,6 +84,7 @@ private slots: void updateTVal(); void updateMdiMode(bool mdi); void updateUndockMode(bool undockMode); + void updateReorderMode(bool reorderMode); void setFileName(const QString &filename); void setFont(const QString &family, uint size); void setColorScheme(const QString &cs); @@ -235,6 +239,7 @@ private: static void report_func(const class AbstractNode*, void *vp, int mark); static bool mdiMode; static bool undockMode; + static bool reorderMode; static QSet *windows; char const * afterCompileSlot; diff --git a/src/Preferences.cc b/src/Preferences.cc index a48314ea..ac6d3e6e 100644 --- a/src/Preferences.cc +++ b/src/Preferences.cc @@ -103,6 +103,7 @@ Preferences::Preferences(QWidget *parent) : QMainWindow(parent) this->defaultmap["advanced/forceGoldfeather"] = false; this->defaultmap["advanced/mdi"] = true; this->defaultmap["advanced/undockableWindows"] = false; + this->defaultmap["advanced/reorderWindows"] = true; this->defaultmap["launcher/showOnStartup"] = true; // Toolbar @@ -321,6 +322,18 @@ Preferences::on_mdiCheckBox_toggled(bool state) emit updateMdiMode(state); } +void +Preferences::on_reorderCheckBox_toggled(bool state) +{ + if (!state) { + undockCheckBox->setChecked(false); + } + undockCheckBox->setEnabled(state); + QSettings settings; + settings.setValue("advanced/reorderWindows", state); + emit updateReorderMode(state); +} + void Preferences::on_undockCheckBox_toggled(bool state) { @@ -467,7 +480,9 @@ void Preferences::updateGUI() this->opencsgLimitEdit->setText(getValue("advanced/openCSGLimit").toString()); this->forceGoldfeatherBox->setChecked(getValue("advanced/forceGoldfeather").toBool()); this->mdiCheckBox->setChecked(getValue("advanced/mdi").toBool()); + this->reorderCheckBox->setChecked(getValue("advanced/reorderWindows").toBool()); this->undockCheckBox->setChecked(getValue("advanced/undockableWindows").toBool()); + this->undockCheckBox->setEnabled(this->reorderCheckBox->isChecked()); this->launcherBox->setChecked(getValue("launcher/showOnStartup").toBool()); } diff --git a/src/Preferences.h b/src/Preferences.h index 881814e2..bfa7d144 100644 --- a/src/Preferences.h +++ b/src/Preferences.h @@ -33,6 +33,7 @@ public slots: void on_updateCheckBox_toggled(bool); void on_snapshotCheckBox_toggled(bool); void on_mdiCheckBox_toggled(bool); + void on_reorderCheckBox_toggled(bool); void on_undockCheckBox_toggled(bool); void on_checkNowButton_clicked(); void on_launcherBox_toggled(bool); @@ -41,7 +42,8 @@ public slots: signals: void requestRedraw() const; void updateMdiMode(bool mdi) const; - void updateUndockMode(bool mdi) const; + void updateUndockMode(bool undockMode) const; + void updateReorderMode(bool undockMode) const; void fontChanged(const QString &family, uint size) const; void colorSchemeChanged(const QString &scheme) const; void openCSGSettingsChanged() const; diff --git a/src/Preferences.ui b/src/Preferences.ui index 9828bc33..0988b3c4 100644 --- a/src/Preferences.ui +++ b/src/Preferences.ui @@ -7,7 +7,7 @@ 0 0 852 - 550 + 554 @@ -27,7 +27,7 @@ - 3 + 4 @@ -547,8 +547,8 @@ 0 0 - 832 - 420 + 100 + 30 @@ -685,10 +685,17 @@ + + + + Enable docking of Editor and Console in different places + + + - Enable undocking of Editor and Console + Enable undocking of Editor and Console to separate windows diff --git a/src/mainwin.cc b/src/mainwin.cc index cd61ec8a..b7625345 100644 --- a/src/mainwin.cc +++ b/src/mainwin.cc @@ -172,12 +172,16 @@ settings_valueList(const QString &key, const QList &defaultList = QListeditorDock->setConfigKey("view/hideEditor"); this->editorDock->setAction(this->viewActionHideEditor); this->consoleDock->setConfigKey("view/hideConsole"); @@ -422,6 +426,7 @@ MainWindow::MainWindow(const QString &filename) connect(Preferences::inst(), SIGNAL(requestRedraw()), this->qglview, SLOT(updateGL())); connect(Preferences::inst(), SIGNAL(updateMdiMode(bool)), this, SLOT(updateMdiMode(bool))); + connect(Preferences::inst(), SIGNAL(updateReorderMode(bool)), this, SLOT(updateReorderMode(bool))); connect(Preferences::inst(), SIGNAL(updateUndockMode(bool)), this, SLOT(updateUndockMode(bool))); connect(Preferences::inst(), SIGNAL(fontChanged(const QString&,uint)), editor, SLOT(initFont(const QString&,uint))); @@ -619,6 +624,7 @@ void MainWindow::loadViewSettings(){ hideToolbars(); updateMdiMode(settings.value("advanced/mdi").toBool()); updateUndockMode(settings.value("advanced/undockableWindows").toBool()); + updateReorderMode(settings.value("advanced/reorderWindows").toBool()); } void MainWindow::loadDesignSettings() @@ -647,11 +653,24 @@ void MainWindow::updateUndockMode(bool undockMode) editorDock->setFeatures(editorDock->features() | QDockWidget::DockWidgetFloatable); consoleDock->setFeatures(consoleDock->features() | QDockWidget::DockWidgetFloatable); } else { + if (editorDock->isFloating()) { + editorDock->setFloating(false); + } editorDock->setFeatures(editorDock->features() & ~QDockWidget::DockWidgetFloatable); + if (consoleDock->isFloating()) { + consoleDock->setFloating(false); + } consoleDock->setFeatures(consoleDock->features() & ~QDockWidget::DockWidgetFloatable); } } +void MainWindow::updateReorderMode(bool reorderMode) +{ + MainWindow::reorderMode = reorderMode; + editorDock->setTitleBarWidget(reorderMode ? 0 : editorDockTitleWidget); + consoleDock->setTitleBarWidget(reorderMode ? 0 : consoleDockTitleWidget); +} + MainWindow::~MainWindow() { if (root_module) delete root_module; From 395795949e0b653bf2a1b07a76829b19df1c875d Mon Sep 17 00:00:00 2001 From: Torsten Paul Date: Thu, 4 Sep 2014 20:05:26 +0200 Subject: [PATCH 14/47] Move color scheme values into resource files. --- color-schemes/editor/dark-background.json | 29 ++++ color-schemes/editor/light-background.json | 29 ++++ color-schemes/editor/monokai.json | 29 ++++ color-schemes/editor/solarized.json | 29 ++++ src/scintillaeditor.cpp | 184 ++++++++++----------- src/scintillaeditor.h | 11 +- 6 files changed, 212 insertions(+), 99 deletions(-) create mode 100644 color-schemes/editor/dark-background.json create mode 100644 color-schemes/editor/light-background.json create mode 100644 color-schemes/editor/monokai.json create mode 100644 color-schemes/editor/solarized.json diff --git a/color-schemes/editor/dark-background.json b/color-schemes/editor/dark-background.json new file mode 100644 index 00000000..3de15f2d --- /dev/null +++ b/color-schemes/editor/dark-background.json @@ -0,0 +1,29 @@ +{ + "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" + } +} \ No newline at end of file diff --git a/color-schemes/editor/light-background.json b/color-schemes/editor/light-background.json new file mode 100644 index 00000000..3009a1c8 --- /dev/null +++ b/color-schemes/editor/light-background.json @@ -0,0 +1,29 @@ +{ + "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" + } +} \ No newline at end of file diff --git a/color-schemes/editor/monokai.json b/color-schemes/editor/monokai.json new file mode 100644 index 00000000..9211ee63 --- /dev/null +++ b/color-schemes/editor/monokai.json @@ -0,0 +1,29 @@ +{ + "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" + } +} \ No newline at end of file diff --git a/color-schemes/editor/solarized.json b/color-schemes/editor/solarized.json new file mode 100644 index 00000000..6b323e46 --- /dev/null +++ b/color-schemes/editor/solarized.json @@ -0,0 +1,29 @@ +{ + "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" + } +} \ No newline at end of file diff --git a/src/scintillaeditor.cpp b/src/scintillaeditor.cpp index 37fce125..d72249f0 100644 --- a/src/scintillaeditor.cpp +++ b/src/scintillaeditor.cpp @@ -4,6 +4,7 @@ #include "scintillaeditor.h" #include #include "Preferences.h" +#include "PlatformUtils.h" ScintillaEditor::ScintillaEditor(QWidget *parent) : EditorInterface(parent) { @@ -51,7 +52,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 +87,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 +99,110 @@ void ScintillaEditor::unhighlightLastError() qsci->markerDeleteAll(markerNumber); } -//Editor themes -void ScintillaEditor::forLightBackground() +QColor ScintillaEditor::read_color(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(name); + return QColor(val.c_str()); + } catch (std::exception e) { + //std::cout << "read_color('" << name << "') failed" << std::endl; + return defaultColor; + } } -void ScintillaEditor::forDarkBackground() +int ScintillaEditor::read_int(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(name); + return val; + } catch (std::exception e) { + return defaultValue; + } } -void ScintillaEditor::Monokai() +void ScintillaEditor::read_colormap(const fs::path path) { - 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")); -} + boost::property_tree::ptree pt; -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 { + boost::property_tree::read_json(boosty::stringy(path).c_str(), pt); + const QColor textColor(pt.get("text").c_str()); + const QColor paperColor(pt.get("paper").c_str()); + + lexer->setColor(textColor); + lexer->setPaper(paperColor); + + boost::property_tree::ptree& colors = pt.get_child("colors"); + lexer->setColor(read_color(colors, "keyword1", textColor), QsciLexerCPP::Keyword); + lexer->setColor(read_color(colors, "keyword2", textColor), QsciLexerCPP::KeywordSet2); + lexer->setColor(read_color(colors, "keyword3", textColor), QsciLexerCPP::GlobalClass); + lexer->setColor(read_color(colors, "comment", textColor), QsciLexerCPP::CommentDocKeyword); + lexer->setColor(read_color(colors, "number", textColor), QsciLexerCPP::Number); + lexer->setColor(read_color(colors, "string", textColor), QsciLexerCPP::DoubleQuotedString); + lexer->setColor(read_color(colors, "operator", textColor), QsciLexerCPP::Operator); + lexer->setColor(read_color(colors, "commentline", textColor), QsciLexerCPP::CommentLine); + + boost::property_tree::ptree& caret = pt.get_child("caret"); + + qsci->setCaretWidth(read_int(caret, "width", 1)); + qsci->setCaretForegroundColor(read_color(caret, "foreground", textColor)); + qsci->setCaretLineBackgroundColor(read_color(caret, "line-background", paperColor)); + + qsci->setMarkerBackgroundColor(read_color(colors, "error-marker", QColor(255, 0, 0, 100)), markerNumber); + qsci->setMarginsBackgroundColor(read_color(colors, "margin-background", paperColor)); + qsci->setMarginsForegroundColor(read_color(colors, "margin-foreground", textColor)); + qsci->setMatchedBraceBackgroundColor(read_color(colors, "matched-brace-background", paperColor)); + qsci->setMatchedBraceForegroundColor(read_color(colors, "matched-brace-foreground", textColor)); + qsci->setUnmatchedBraceBackgroundColor(read_color(colors, "unmatched-brace-background", paperColor)); + qsci->setUnmatchedBraceForegroundColor(read_color(colors, "unmatched-brace-foreground", textColor)); + qsci->setSelectionForegroundColor(read_color(colors, "selection-foreground", paperColor)); + qsci->setSelectionBackgroundColor(read_color(colors, "selection-background", textColor)); + qsci->setFoldMarginColors(read_color(colors, "margin-foreground", textColor), + read_color(colors, "margin-background", paperColor)); + qsci->setEdgeColor(read_color(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::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") { - noColor(); - } + fs::path resources = PlatformUtils::resourcesPath(); + fs::path color_schemes = resources / "color-schemes" / "editor"; + + if (name == "For Light Background") { + read_colormap(color_schemes / "light-background.json"); + } else if (name == "For Dark Background") { + read_colormap(color_schemes / "dark-background.json"); + } else if (name == "Monokai") { + read_colormap(color_schemes / "monokai.json"); + } else if (name == "Solarized") { + read_colormap(color_schemes / "solarized.json"); + } else if (name == "Off") { + noColor(); + } } void ScintillaEditor::insert(const QString &text) diff --git a/src/scintillaeditor.h b/src/scintillaeditor.h index 38193eb6..eb05aba4 100644 --- a/src/scintillaeditor.h +++ b/src/scintillaeditor.h @@ -7,6 +7,10 @@ #include #include "editor.h" #include "scadlexer.h" +#include "parsersettings.h" + +#include +#include class ScintillaEditor : public EditorInterface { @@ -18,10 +22,6 @@ 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); @@ -29,6 +29,9 @@ public: private: void get_range(int *lineFrom, int *lineTo); + void read_colormap(const boost::filesystem::path path); + int read_int(boost::property_tree::ptree &pt, const std::string name, const int defaultValue); + QColor read_color(boost::property_tree::ptree &pt, const std::string name, const QColor defaultColor); public slots: void zoomIn(); From 23275dc92782ed68d5b37b5edefb39f0e8c98228 Mon Sep 17 00:00:00 2001 From: Torsten Paul Date: Fri, 31 Oct 2014 23:30:52 +0100 Subject: [PATCH 15/47] Get color schemes from editor; Enumerate from resource folder for scintilla. --- color-schemes/editor/dark-background.json | 2 + color-schemes/editor/light-background.json | 2 + color-schemes/editor/monokai.json | 2 + color-schemes/editor/solarized.json | 2 + src/Preferences.cc | 34 ++++++++++++++--- src/Preferences.h | 9 +++-- src/Preferences.ui | 25 ------------ src/editor.h | 1 + src/highlighter.cc | 3 -- src/legacyeditor.cc | 12 ++++++ src/legacyeditor.h | 1 + src/mainwin.cc | 8 ++-- src/scintillaeditor.cpp | 44 ++++++++++++++++++++++ src/scintillaeditor.h | 1 + 14 files changed, 107 insertions(+), 39 deletions(-) diff --git a/color-schemes/editor/dark-background.json b/color-schemes/editor/dark-background.json index 3de15f2d..c9fc3e01 100644 --- a/color-schemes/editor/dark-background.json +++ b/color-schemes/editor/dark-background.json @@ -1,4 +1,6 @@ { + "name" : "For Dark Background", + "index" : 1100, "paper" : "#272822", "text" : "#ffffff", "caret" : { diff --git a/color-schemes/editor/light-background.json b/color-schemes/editor/light-background.json index 3009a1c8..35471b50 100644 --- a/color-schemes/editor/light-background.json +++ b/color-schemes/editor/light-background.json @@ -1,4 +1,6 @@ { + "name" : "For Light Background", + "index" : 1000, "paper" : "#fff", "text" : "#272822", "caret" : { diff --git a/color-schemes/editor/monokai.json b/color-schemes/editor/monokai.json index 9211ee63..17bf8f9a 100644 --- a/color-schemes/editor/monokai.json +++ b/color-schemes/editor/monokai.json @@ -1,4 +1,6 @@ { + "name" : "Monokai", + "index" : 1200, "paper" : "#272822", "text" : "#f8f8f2", "caret" : { diff --git a/color-schemes/editor/solarized.json b/color-schemes/editor/solarized.json index 6b323e46..c9ee3dd3 100644 --- a/color-schemes/editor/solarized.json +++ b/color-schemes/editor/solarized.json @@ -1,4 +1,6 @@ { + "name" : "Solarized", + "index" : 1300, "paper" : "#fdf6e3", "text" : "#657b83", "caret" : { diff --git a/src/Preferences.cc b/src/Preferences.cc index a48314ea..c9a59388 100644 --- a/src/Preferences.cc +++ b/src/Preferences.cc @@ -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; @@ -135,9 +138,6 @@ Preferences::Preferences(QWidget *parent) : QMainWindow(parent) #endif this->polysetCacheSizeEdit->setValidator(validator); this->opencsgLimitEdit->setValidator(validator); - - setupFeaturesPage(); - updateGUI(); } Preferences::~Preferences() @@ -272,7 +272,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); @@ -446,7 +446,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); @@ -476,4 +483,21 @@ void Preferences::apply() const emit fontChanged(getValue("editor/fontfamily").toString(), getValue("editor/fontsize").toUInt()); emit requestRedraw(); emit openCSGSettingsChanged(); + emit syntaxHighlightChanged(getValue("editor/syntaxhighlight").toString()); +} + +void Preferences::create(QWidget *parent, QStringList colorSchemes) +{ + instance = new Preferences(parent); + instance->syntaxHighlight->clear(); + instance->syntaxHighlight->addItems(colorSchemes); + instance->init(); + instance->setupFeaturesPage(); + instance->updateGUI(); +} + +Preferences *Preferences::inst() { + assert(instance != NULL); + + return instance; } diff --git a/src/Preferences.h b/src/Preferences.h index 881814e2..96001d25 100644 --- a/src/Preferences.h +++ b/src/Preferences.h @@ -11,9 +11,12 @@ class Preferences : public QMainWindow, public Ui::Preferences public: ~Preferences(); - static Preferences *inst() { if (!instance) instance = new Preferences(); return instance; } + + static void create(QWidget *parent, QStringList colorSchemes); + static Preferences *inst(); QVariant getValue(const QString &key) const; + void init(); void apply() const; public slots: @@ -22,7 +25,7 @@ public slots: void on_colorSchemeChooser_itemSelectionChanged(); void on_fontChooser_activated(const QString &); void on_fontSize_editTextChanged(const QString &); - void on_syntaxHighlight_currentIndexChanged(const QString &); + void on_syntaxHighlight_activated(const QString &); void on_openCSGWarningBox_toggled(bool); void on_enableOpenCSGBox_toggled(bool); void on_cgalCacheSizeEdit_textChanged(const QString &); @@ -45,7 +48,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: diff --git a/src/Preferences.ui b/src/Preferences.ui index 9828bc33..8a0b3aa6 100644 --- a/src/Preferences.ui +++ b/src/Preferences.ui @@ -264,31 +264,6 @@ 0 - - - For Light Background - - - - - For Dark Background - - - - - Monokai - - - - - Solarized - - - - - Off - -
diff --git a/src/editor.h b/src/editor.h index 7dbea023..553e42a8 100644 --- a/src/editor.h +++ b/src/editor.h @@ -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(); diff --git a/src/highlighter.cc b/src/highlighter.cc index 67c343e2..2db4b3da 100644 --- a/src/highlighter.cc +++ b/src/highlighter.cc @@ -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; diff --git a/src/legacyeditor.cc b/src/legacyeditor.cc index 09c71a37..abb50007 100644 --- a/src/legacyeditor.cc +++ b/src/legacyeditor.cc @@ -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; +} diff --git a/src/legacyeditor.h b/src/legacyeditor.h index 663cc307..1b37e14f 100644 --- a/src/legacyeditor.h +++ b/src/legacyeditor.h @@ -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(); diff --git a/src/mainwin.cc b/src/mainwin.cc index cd61ec8a..68693625 100644 --- a/src/mainwin.cc +++ b/src/mainwin.cc @@ -183,8 +183,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) { @@ -194,6 +195,8 @@ MainWindow::MainWindow(const QString &filename) #endif editor = new LegacyEditor(editorDockContents); + Preferences::create(this, editor->colorSchemes()); + editorDockContents->layout()->addWidget(editor); setCorner(Qt::TopLeftCorner, Qt::LeftDockWidgetArea); @@ -515,7 +518,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()); diff --git a/src/scintillaeditor.cpp b/src/scintillaeditor.cpp index d72249f0..7343ef82 100644 --- a/src/scintillaeditor.cpp +++ b/src/scintillaeditor.cpp @@ -187,6 +187,50 @@ void ScintillaEditor::noColor() qsci->setEdgeColor(Qt::black); } +QStringList ScintillaEditor::colorSchemes() +{ + typedef std::multimap result_set_t; + result_set_t result_set; + + const fs::path resources = PlatformUtils::resourcesPath(); + const fs::path color_schemes = resources / "color-schemes" / "editor"; + + QStringList colorSchemes; + 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(); + const fs::path ext = path.extension(); + if (!(path.extension().string() == ".json")) { + continue; + } + + boost::property_tree::ptree pt; + try { + boost::property_tree::read_json(boosty::stringy(path).c_str(), pt); + QString name = QString(pt.get("name").c_str()); + int index = pt.get("index"); + result_set.insert(result_set_t::value_type(index, name)); + } catch (const std::exception & e) { + PRINTB("Error reading color scheme file '%s': %s", path.c_str() % e.what()); + } + } + } + + for (result_set_t::iterator it = result_set.begin();it != result_set.end();it++) { + colorSchemes << (*it).second; + } + + colorSchemes << "Off"; + + return colorSchemes; +} + void ScintillaEditor::setHighlightScheme(const QString &name) { fs::path resources = PlatformUtils::resourcesPath(); diff --git a/src/scintillaeditor.h b/src/scintillaeditor.h index eb05aba4..a3ebdc87 100644 --- a/src/scintillaeditor.h +++ b/src/scintillaeditor.h @@ -26,6 +26,7 @@ public: 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); From 0886944fcd9aca3d5033b1572cbc9bae7cfe79a7 Mon Sep 17 00:00:00 2001 From: Torsten Paul Date: Fri, 5 Sep 2014 00:31:09 +0200 Subject: [PATCH 16/47] Handle setting of additional color schemes. --- src/scintillaeditor.cpp | 167 ++++++++++++++++++++++++---------------- src/scintillaeditor.h | 37 +++++++-- 2 files changed, 132 insertions(+), 72 deletions(-) diff --git a/src/scintillaeditor.cpp b/src/scintillaeditor.cpp index 7343ef82..dfdc70a3 100644 --- a/src/scintillaeditor.cpp +++ b/src/scintillaeditor.cpp @@ -6,6 +6,44 @@ #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("name").c_str()); + _index = pt.get("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) { scintillaLayout = new QVBoxLayout(this); @@ -99,18 +137,17 @@ void ScintillaEditor::unhighlightLastError() qsci->markerDeleteAll(markerNumber); } -QColor ScintillaEditor::read_color(boost::property_tree::ptree &pt, const std::string name, const QColor defaultColor) +QColor ScintillaEditor::readColor(const boost::property_tree::ptree &pt, const std::string name, const QColor defaultColor) { try { const std::string val = pt.get(name); return QColor(val.c_str()); } catch (std::exception e) { - //std::cout << "read_color('" << name << "') failed" << std::endl; return defaultColor; } } -int ScintillaEditor::read_int(boost::property_tree::ptree &pt, const std::string name, const int defaultValue) +int ScintillaEditor::readInt(const boost::property_tree::ptree &pt, const std::string name, const int defaultValue) { try { const int val = pt.get(name); @@ -120,46 +157,45 @@ int ScintillaEditor::read_int(boost::property_tree::ptree &pt, const std::string } } -void ScintillaEditor::read_colormap(const fs::path path) +void ScintillaEditor::setColormap(const EditorColorScheme *colorScheme) { - boost::property_tree::ptree pt; + const boost::property_tree::ptree & pt = colorScheme->propertyTree(); try { - boost::property_tree::read_json(boosty::stringy(path).c_str(), pt); const QColor textColor(pt.get("text").c_str()); const QColor paperColor(pt.get("paper").c_str()); lexer->setColor(textColor); lexer->setPaper(paperColor); - boost::property_tree::ptree& colors = pt.get_child("colors"); - lexer->setColor(read_color(colors, "keyword1", textColor), QsciLexerCPP::Keyword); - lexer->setColor(read_color(colors, "keyword2", textColor), QsciLexerCPP::KeywordSet2); - lexer->setColor(read_color(colors, "keyword3", textColor), QsciLexerCPP::GlobalClass); - lexer->setColor(read_color(colors, "comment", textColor), QsciLexerCPP::CommentDocKeyword); - lexer->setColor(read_color(colors, "number", textColor), QsciLexerCPP::Number); - lexer->setColor(read_color(colors, "string", textColor), QsciLexerCPP::DoubleQuotedString); - lexer->setColor(read_color(colors, "operator", textColor), QsciLexerCPP::Operator); - lexer->setColor(read_color(colors, "commentline", textColor), QsciLexerCPP::CommentLine); + 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); - boost::property_tree::ptree& caret = pt.get_child("caret"); + const boost::property_tree::ptree& caret = pt.get_child("caret"); - qsci->setCaretWidth(read_int(caret, "width", 1)); - qsci->setCaretForegroundColor(read_color(caret, "foreground", textColor)); - qsci->setCaretLineBackgroundColor(read_color(caret, "line-background", paperColor)); + qsci->setCaretWidth(readInt(caret, "width", 1)); + qsci->setCaretForegroundColor(readColor(caret, "foreground", textColor)); + qsci->setCaretLineBackgroundColor(readColor(caret, "line-background", paperColor)); - qsci->setMarkerBackgroundColor(read_color(colors, "error-marker", QColor(255, 0, 0, 100)), markerNumber); - qsci->setMarginsBackgroundColor(read_color(colors, "margin-background", paperColor)); - qsci->setMarginsForegroundColor(read_color(colors, "margin-foreground", textColor)); - qsci->setMatchedBraceBackgroundColor(read_color(colors, "matched-brace-background", paperColor)); - qsci->setMatchedBraceForegroundColor(read_color(colors, "matched-brace-foreground", textColor)); - qsci->setUnmatchedBraceBackgroundColor(read_color(colors, "unmatched-brace-background", paperColor)); - qsci->setUnmatchedBraceForegroundColor(read_color(colors, "unmatched-brace-foreground", textColor)); - qsci->setSelectionForegroundColor(read_color(colors, "selection-foreground", paperColor)); - qsci->setSelectionBackgroundColor(read_color(colors, "selection-background", textColor)); - qsci->setFoldMarginColors(read_color(colors, "margin-foreground", textColor), - read_color(colors, "margin-background", paperColor)); - qsci->setEdgeColor(read_color(colors, "edge", textColor)); + 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(); } @@ -187,15 +223,12 @@ void ScintillaEditor::noColor() qsci->setEdgeColor(Qt::black); } -QStringList ScintillaEditor::colorSchemes() +ScintillaEditor::colorscheme_set_t ScintillaEditor::enumerateColorSchemes() { - typedef std::multimap result_set_t; - result_set_t result_set; - const fs::path resources = PlatformUtils::resourcesPath(); const fs::path color_schemes = resources / "color-schemes" / "editor"; - QStringList colorSchemes; + colorscheme_set_t result_set; fs::directory_iterator end_iter; if (fs::exists(color_schemes) && fs::is_directory(color_schemes)) { @@ -205,27 +238,30 @@ QStringList ScintillaEditor::colorSchemes() } const fs::path path = (*dir_iter).path(); - const fs::path ext = path.extension(); if (!(path.extension().string() == ".json")) { continue; } - - boost::property_tree::ptree pt; - try { - boost::property_tree::read_json(boosty::stringy(path).c_str(), pt); - QString name = QString(pt.get("name").c_str()); - int index = pt.get("index"); - result_set.insert(result_set_t::value_type(index, name)); - } catch (const std::exception & e) { - PRINTB("Error reading color scheme file '%s': %s", path.c_str() % e.what()); + + EditorColorScheme *colorScheme = new EditorColorScheme(path); + if (colorScheme->valid()) { + result_set.insert(colorscheme_set_t::value_type(colorScheme->index(), boost::shared_ptr(colorScheme))); + } else { + delete colorScheme; } } } - for (result_set_t::iterator it = result_set.begin();it != result_set.end();it++) { - colorSchemes << (*it).second; - } + 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; @@ -233,20 +269,17 @@ QStringList ScintillaEditor::colorSchemes() void ScintillaEditor::setHighlightScheme(const QString &name) { - fs::path resources = PlatformUtils::resourcesPath(); - fs::path color_schemes = resources / "color-schemes" / "editor"; - - if (name == "For Light Background") { - read_colormap(color_schemes / "light-background.json"); - } else if (name == "For Dark Background") { - read_colormap(color_schemes / "dark-background.json"); - } else if (name == "Monokai") { - read_colormap(color_schemes / "monokai.json"); - } else if (name == "Solarized") { - read_colormap(color_schemes / "solarized.json"); - } else if (name == "Off") { - noColor(); + 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) @@ -345,7 +378,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()) { @@ -362,7 +395,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); } @@ -371,7 +404,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); } @@ -382,7 +415,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); } @@ -397,7 +430,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("//")) { diff --git a/src/scintillaeditor.h b/src/scintillaeditor.h index a3ebdc87..87c10026 100644 --- a/src/scintillaeditor.h +++ b/src/scintillaeditor.h @@ -1,6 +1,8 @@ #pragma once +#include #include +#include #include #include #include @@ -9,12 +11,36 @@ #include "scadlexer.h" #include "parsersettings.h" +#include #include #include -class ScintillaEditor : public EditorInterface +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, std::less > colorscheme_set_t; + public: ScintillaEditor(QWidget *parent); virtual ~ScintillaEditor() {} @@ -29,10 +55,11 @@ public: QStringList colorSchemes(); private: - void get_range(int *lineFrom, int *lineTo); - void read_colormap(const boost::filesystem::path path); - int read_int(boost::property_tree::ptree &pt, const std::string name, const int defaultValue); - QColor read_color(boost::property_tree::ptree &pt, const std::string name, const QColor defaultColor); + 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); + colorscheme_set_t enumerateColorSchemes(); public slots: void zoomIn(); From df119fec7512b8e13bc100aa08309dbd0324fdc8 Mon Sep 17 00:00:00 2001 From: Torsten Paul Date: Tue, 16 Sep 2014 20:31:23 +0200 Subject: [PATCH 17/47] Add solarized render color map to match the editor color scheme. --- src/Preferences.ui | 11 ++++++++--- src/colormap.cc | 13 +++++++++++++ 2 files changed, 21 insertions(+), 3 deletions(-) diff --git a/src/Preferences.ui b/src/Preferences.ui index 8a0b3aa6..e55e2a5f 100644 --- a/src/Preferences.ui +++ b/src/Preferences.ui @@ -54,7 +54,7 @@ false - 0 + -1 @@ -91,6 +91,11 @@ DeepOcean + + + Solarized + +
@@ -522,8 +527,8 @@ 0 0 - 832 - 420 + 100 + 30 diff --git a/src/colormap.cc b/src/colormap.cc index 8aea7e99..3abe8972 100644 --- a/src/colormap.cc +++ b/src/colormap.cc @@ -249,6 +249,18 @@ ColorMap::ColorMap() { (CGAL_EDGE_2D_COLOR, webcolors["magenta"]) (CROSSHAIR_COLOR, Color4f(0xf0, 0xf0, 0xf0)); + ColorScheme solarized = map_list_of + (BACKGROUND_COLOR, Color4f(0xfd, 0xf6, 0xe3)) + (OPENCSG_FACE_FRONT_COLOR, Color4f(0xb5, 0x88, 0x00)) + (OPENCSG_FACE_BACK_COLOR, Color4f(0x88, 0x22, 0x33)) + (CGAL_FACE_FRONT_COLOR, Color4f(0xb5, 0x88, 0x00)) + (CGAL_FACE_BACK_COLOR, Color4f(0x88, 0x22, 0x33)) + (CGAL_FACE_2D_COLOR, Color4f(0x6c, 0x71, 0xc4)) + (CGAL_EDGE_FRONT_COLOR, Color4f(0xb5, 0x88, 0x00)) + (CGAL_EDGE_BACK_COLOR, Color4f(0xb5, 0x88, 0x00)) + (CGAL_EDGE_2D_COLOR, Color4f(0xb5, 0x88, 0x00)) + (CROSSHAIR_COLOR, Color4f(0x80, 0x00, 0x00)); + // Monotone - no difference between 'back face' and 'front face' ColorScheme monotone = map_list_of (BACKGROUND_COLOR, Color4f(0xff, 0xff, 0xe5)) @@ -270,6 +282,7 @@ ColorMap::ColorMap() { ("BeforeDawn", beforedawn) ("Nature", nature) ("DeepOcean", deepocean) + ("Solarized", solarized) ("Monotone", monotone); // Hidden, not in GUI colorschemes = tmpcolorschemes; From 2ee58893f54bbe60867980ee72a3f21eeb3d4c0c Mon Sep 17 00:00:00 2001 From: Torsten Paul Date: Tue, 16 Sep 2014 23:27:54 +0200 Subject: [PATCH 18/47] Move render color schemes to separate files. --- color-schemes/render/beforedawn.json | 18 ++ color-schemes/render/cornfield.json | 18 ++ color-schemes/render/deepocean.json | 18 ++ color-schemes/render/metallic.json | 18 ++ color-schemes/render/monotone.json | 19 ++ color-schemes/render/nature.json | 18 ++ color-schemes/render/solarized.json | 18 ++ color-schemes/render/starnight.json | 18 ++ color-schemes/render/sunset.json | 18 ++ src/Preferences.cc | 8 + src/Preferences.ui | 40 ---- src/colormap.cc | 273 +++++++++++++-------------- src/colormap.h | 41 +++- 13 files changed, 339 insertions(+), 186 deletions(-) create mode 100644 color-schemes/render/beforedawn.json create mode 100644 color-schemes/render/cornfield.json create mode 100644 color-schemes/render/deepocean.json create mode 100644 color-schemes/render/metallic.json create mode 100644 color-schemes/render/monotone.json create mode 100644 color-schemes/render/nature.json create mode 100644 color-schemes/render/solarized.json create mode 100644 color-schemes/render/starnight.json create mode 100644 color-schemes/render/sunset.json diff --git a/color-schemes/render/beforedawn.json b/color-schemes/render/beforedawn.json new file mode 100644 index 00000000..9e09fcca --- /dev/null +++ b/color-schemes/render/beforedawn.json @@ -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" + } +} diff --git a/color-schemes/render/cornfield.json b/color-schemes/render/cornfield.json new file mode 100644 index 00000000..dda82ffd --- /dev/null +++ b/color-schemes/render/cornfield.json @@ -0,0 +1,18 @@ +{ + "name" : "Cornfield", + "index" : 1000, + "show-in-gui" : true, + + "colors" : { + "background" : "#ffffe5", + "opencsg-face-front" : "#f9d72c", + "opencsg-face-back" : "#9dcb51", + "cgal-face-front" : "#f9d72c", + "cgal-face-back" : "#9dcb51", + "cgal-face-2d" : "#00bf99", + "cgal-edge-front" : "#ffec5e", + "cgal-edge-back" : "#abd856", + "cgal-edge-2d" : "#ff0000", + "crosshair" : "#800000" + } +} diff --git a/color-schemes/render/deepocean.json b/color-schemes/render/deepocean.json new file mode 100644 index 00000000..c325db8e --- /dev/null +++ b/color-schemes/render/deepocean.json @@ -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" + } +} diff --git a/color-schemes/render/metallic.json b/color-schemes/render/metallic.json new file mode 100644 index 00000000..f2582e46 --- /dev/null +++ b/color-schemes/render/metallic.json @@ -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" + } +} diff --git a/color-schemes/render/monotone.json b/color-schemes/render/monotone.json new file mode 100644 index 00000000..1ce30005 --- /dev/null +++ b/color-schemes/render/monotone.json @@ -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" + } +} diff --git a/color-schemes/render/nature.json b/color-schemes/render/nature.json new file mode 100644 index 00000000..9e19932e --- /dev/null +++ b/color-schemes/render/nature.json @@ -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" + } +} diff --git a/color-schemes/render/solarized.json b/color-schemes/render/solarized.json new file mode 100644 index 00000000..06190ee9 --- /dev/null +++ b/color-schemes/render/solarized.json @@ -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" + } +} diff --git a/color-schemes/render/starnight.json b/color-schemes/render/starnight.json new file mode 100644 index 00000000..0dbe702d --- /dev/null +++ b/color-schemes/render/starnight.json @@ -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" + } +} diff --git a/color-schemes/render/sunset.json b/color-schemes/render/sunset.json new file mode 100644 index 00000000..072c361c --- /dev/null +++ b/color-schemes/render/sunset.json @@ -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" + } +} diff --git a/src/Preferences.cc b/src/Preferences.cc index c9a59388..7e43ff9a 100644 --- a/src/Preferences.cc +++ b/src/Preferences.cc @@ -488,9 +488,17 @@ void Preferences::apply() const void Preferences::create(QWidget *parent, QStringList colorSchemes) { + std::list names = ColorMap::inst()->colorSchemeNames(true); + QStringList renderColorSchemes; + foreach (std::string name, names) { + renderColorSchemes << name.c_str(); + } + instance = new Preferences(parent); instance->syntaxHighlight->clear(); instance->syntaxHighlight->addItems(colorSchemes); + instance->colorSchemeChooser->clear(); + instance->colorSchemeChooser->addItems(renderColorSchemes); instance->init(); instance->setupFeaturesPage(); instance->updateGUI(); diff --git a/src/Preferences.ui b/src/Preferences.ui index e55e2a5f..1a65831a 100644 --- a/src/Preferences.ui +++ b/src/Preferences.ui @@ -56,46 +56,6 @@ -1 - - - Cornfield - - - - - Metallic - - - - - Sunset - - - - - Starnight - - - - - BeforeDawn - - - - - Nature - - - - - DeepOcean - - - - - Solarized - -
diff --git a/src/colormap.cc b/src/colormap.cc index 3abe8972..53bba012 100644 --- a/src/colormap.cc +++ b/src/colormap.cc @@ -1,8 +1,88 @@ #include "colormap.h" +#include #include +#include "boosty.h" #include "printutils.h" +#include "PlatformUtils.h" + using namespace boost::assign; // bring map_list_of() into scope +RenderColorScheme::RenderColorScheme(fs::path path) : path(path) +{ + try { + boost::property_tree::read_json(boosty::stringy(path).c_str(), pt); + _name = pt.get("name"); + _index = pt.get("index"); + _show_in_gui = pt.get("show-in-gui"); + + addColor(BACKGROUND_COLOR, "background"); + addColor(OPENCSG_FACE_FRONT_COLOR, "opencsg-face-front"); + addColor(OPENCSG_FACE_BACK_COLOR, "opencsg-face-back"); + addColor(CGAL_FACE_FRONT_COLOR, "cgal-face-front"); + addColor(CGAL_FACE_2D_COLOR, "cgal-face-2d"); + addColor(CGAL_FACE_BACK_COLOR, "cgal-face-back"); + addColor(CGAL_EDGE_FRONT_COLOR, "cgal-edge-front"); + addColor(CGAL_EDGE_BACK_COLOR, "cgal-edge-back"); + addColor(CGAL_EDGE_2D_COLOR, "cgal-edge-2d"); + addColor(CROSSHAIR_COLOR, "crosshair"); + } catch (const std::exception & e) { + PRINTB("Error reading color scheme file '%s': %s", path.c_str() % e.what()); + _name = ""; + _index = 0; + _show_in_gui = false; + } +} + +RenderColorScheme::~RenderColorScheme() +{ +} + +bool RenderColorScheme::valid() const +{ + return !_name.empty(); +} + +const std::string & RenderColorScheme::name() const +{ + return _name; +} + +int RenderColorScheme::index() const +{ + return _index; +} + +bool RenderColorScheme::showInGui() const +{ + return _show_in_gui; +} + +ColorScheme & RenderColorScheme::colorScheme() +{ + return _color_scheme; +} + +const boost::property_tree::ptree & RenderColorScheme::propertyTree() const +{ + return pt; +} + +void RenderColorScheme::addColor(RenderColor colorKey, std::string key) +{ + const boost::property_tree::ptree& colors = pt.get_child("colors"); + std::string color = colors.get(key); + if ((color.length() == 7) && (color.at(0) == '#')) { + char *endptr; + unsigned int val = strtol(color.substr(1).c_str(), &endptr, 16); + int r = (val >> 16) & 0xff; + int g = (val >> 8) & 0xff; + int b = val & 0xff; + _color_scheme.insert(ColorScheme::value_type(colorKey, Color4f(r, g, b))); + } else { + throw std::invalid_argument(std::string("invalid color value for key '") + key + "': '" + color + "'"); + } +} + ColorMap *ColorMap::inst(bool erase) { static ColorMap *instance = new ColorMap; @@ -164,148 +244,39 @@ ColorMap::ColorMap() { ("yellow", Color4f(255, 255, 0)) ("yellowgreen", Color4f(154, 205, 50)); webcolors = tmpwebcolors; - - ColorScheme cornfield = map_list_of - (BACKGROUND_COLOR, Color4f(0xff, 0xff, 0xe5)) - (OPENCSG_FACE_FRONT_COLOR, Color4f(0xf9, 0xd7, 0x2c)) - (OPENCSG_FACE_BACK_COLOR, Color4f(0x9d, 0xcb, 0x51)) - (CGAL_FACE_FRONT_COLOR, Color4f(0xf9, 0xd7, 0x2c)) - (CGAL_FACE_BACK_COLOR, Color4f(0x9d, 0xcb, 0x51)) - (CGAL_FACE_2D_COLOR, Color4f(0x00, 0xbf, 0x99)) - (CGAL_EDGE_FRONT_COLOR, Color4f(0xff, 0xec, 0x5e)) - (CGAL_EDGE_BACK_COLOR, Color4f(0xab, 0xd8, 0x56)) - (CGAL_EDGE_2D_COLOR, Color4f(0xff, 0x00, 0x00)) - (CROSSHAIR_COLOR, Color4f(0x80, 0x00, 0x00)); - - ColorScheme metallic = map_list_of - (BACKGROUND_COLOR, Color4f(0xaa, 0xaa, 0xff)) - (OPENCSG_FACE_FRONT_COLOR, Color4f(0xdd, 0xdd, 0xff)) - (OPENCSG_FACE_BACK_COLOR, Color4f(0xdd, 0x22, 0xdd)) - (CGAL_FACE_FRONT_COLOR, Color4f(0xdd, 0xdd, 0xff)) - (CGAL_FACE_BACK_COLOR, Color4f(0xdd, 0x22, 0xdd)) - (CGAL_FACE_2D_COLOR, Color4f(0x00, 0xbf, 0x99)) - (CGAL_EDGE_FRONT_COLOR, Color4f(0xff, 0x00, 0x00)) - (CGAL_EDGE_BACK_COLOR, Color4f(0xff, 0x00, 0x00)) - (CGAL_EDGE_2D_COLOR, Color4f(0xff, 0x00, 0x00)) - (CROSSHAIR_COLOR, Color4f(0x80, 0x00, 0x00)); - - ColorScheme sunset = map_list_of - (BACKGROUND_COLOR, Color4f(0xaa, 0x44, 0x44)) - (OPENCSG_FACE_FRONT_COLOR, Color4f(0xff, 0xaa, 0xaa)) - (OPENCSG_FACE_BACK_COLOR, Color4f(0x88, 0x22, 0x33)) - (CGAL_FACE_FRONT_COLOR, Color4f(0xff, 0xaa, 0xaa)) - (CGAL_FACE_BACK_COLOR, Color4f(0x88, 0x22, 0x33)) - (CGAL_FACE_2D_COLOR, Color4f(0x00, 0xbf, 0x99)) - (CGAL_EDGE_FRONT_COLOR, Color4f(0xff, 0x00, 0x00)) - (CGAL_EDGE_BACK_COLOR, Color4f(0xff, 0x00, 0x00)) - (CGAL_EDGE_2D_COLOR, Color4f(0xff, 0x00, 0x00)) - (CROSSHAIR_COLOR, Color4f(0x80, 0x00, 0x00)); - - ColorScheme starnight = map_list_of - (BACKGROUND_COLOR, webcolors["black"]) - (OPENCSG_FACE_FRONT_COLOR, webcolors["lightyellow"]) - (OPENCSG_FACE_BACK_COLOR, webcolors["cyan"]) - (CGAL_FACE_FRONT_COLOR, webcolors["lightyellow"]) - (CGAL_FACE_BACK_COLOR, webcolors["cyan"]) - (CGAL_FACE_2D_COLOR, webcolors["mediumpurple"]) - (CGAL_EDGE_FRONT_COLOR, Color4f(0x00, 0x00, 0xff)) - (CGAL_EDGE_BACK_COLOR, Color4f(0x00, 0x00, 0xff)) - (CGAL_EDGE_2D_COLOR, webcolors["magenta"]) - (CROSSHAIR_COLOR, Color4f(0xf0, 0xf0, 0xf0)); - - ColorScheme beforedawn = map_list_of - (BACKGROUND_COLOR, Color4f(0x33, 0x33, 0x33)) - (OPENCSG_FACE_FRONT_COLOR, Color4f(0xcc, 0xcc, 0xcc)) - (OPENCSG_FACE_BACK_COLOR, Color4f(0x55, 0x63, 0xdd)) - (CGAL_FACE_FRONT_COLOR, Color4f(0xcc, 0xcc, 0xcc)) - (CGAL_FACE_BACK_COLOR, Color4f(0x55, 0x63, 0xdd)) - (CGAL_FACE_2D_COLOR, Color4f(0x00, 0xbf, 0x99)) - (CGAL_EDGE_FRONT_COLOR, Color4f(0xff, 0x00, 0x00)) - (CGAL_EDGE_BACK_COLOR, Color4f(0xff, 0x00, 0x00)) - (CGAL_EDGE_2D_COLOR, Color4f(0xff, 0x00, 0x00)) - (CROSSHAIR_COLOR, Color4f(0xf0, 0xf0, 0xf0)); - - ColorScheme nature = map_list_of - (BACKGROUND_COLOR, Color4f(0xfa, 0xfa, 0xfa)) - (OPENCSG_FACE_FRONT_COLOR, Color4f(0x16, 0xa0, 0x85)) - (OPENCSG_FACE_BACK_COLOR, Color4f(0xdb, 0xf4, 0xda)) - (CGAL_FACE_FRONT_COLOR, Color4f(0x16, 0xa0, 0x85)) - (CGAL_FACE_BACK_COLOR, Color4f(0xdb, 0xf4, 0xda)) - (CGAL_FACE_2D_COLOR, Color4f(0x00, 0xbf, 0x99)) - (CGAL_EDGE_FRONT_COLOR, Color4f(0xff, 0x00, 0x00)) - (CGAL_EDGE_BACK_COLOR, Color4f(0xff, 0x00, 0x00)) - (CGAL_EDGE_2D_COLOR, Color4f(0xff, 0x00, 0x00)) - (CROSSHAIR_COLOR, Color4f(0x11, 0x11, 0x11)); - - ColorScheme deepocean = map_list_of - (BACKGROUND_COLOR, Color4f(0x33, 0x33, 0x33)) - (OPENCSG_FACE_FRONT_COLOR, Color4f(0xee, 0xee, 0xee)) - (OPENCSG_FACE_BACK_COLOR, Color4f(0x0b, 0xab, 0xc8)) - (CGAL_FACE_FRONT_COLOR, Color4f(0xee, 0xee, 0xee)) - (CGAL_FACE_BACK_COLOR, Color4f(0x0b, 0xab, 0xc8)) - (CGAL_FACE_2D_COLOR, webcolors["mediumpurple"]) - (CGAL_EDGE_FRONT_COLOR, Color4f(0x00, 0x00, 0xff)) - (CGAL_EDGE_BACK_COLOR, Color4f(0x00, 0x00, 0xff)) - (CGAL_EDGE_2D_COLOR, webcolors["magenta"]) - (CROSSHAIR_COLOR, Color4f(0xf0, 0xf0, 0xf0)); - - ColorScheme solarized = map_list_of - (BACKGROUND_COLOR, Color4f(0xfd, 0xf6, 0xe3)) - (OPENCSG_FACE_FRONT_COLOR, Color4f(0xb5, 0x88, 0x00)) - (OPENCSG_FACE_BACK_COLOR, Color4f(0x88, 0x22, 0x33)) - (CGAL_FACE_FRONT_COLOR, Color4f(0xb5, 0x88, 0x00)) - (CGAL_FACE_BACK_COLOR, Color4f(0x88, 0x22, 0x33)) - (CGAL_FACE_2D_COLOR, Color4f(0x6c, 0x71, 0xc4)) - (CGAL_EDGE_FRONT_COLOR, Color4f(0xb5, 0x88, 0x00)) - (CGAL_EDGE_BACK_COLOR, Color4f(0xb5, 0x88, 0x00)) - (CGAL_EDGE_2D_COLOR, Color4f(0xb5, 0x88, 0x00)) - (CROSSHAIR_COLOR, Color4f(0x80, 0x00, 0x00)); - - // 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 tmpcolorschemes = map_list_of - ("Cornfield", cornfield) - ("Metallic", metallic) - ("Sunset", sunset) - ("Starnight", starnight) - ("BeforeDawn", beforedawn) - ("Nature", nature) - ("DeepOcean", deepocean) - ("Solarized", solarized) - ("Monotone", monotone); // Hidden, not in GUI - colorschemes = tmpcolorschemes; - + + colorschemes = enumerateColorSchemes(); } const ColorScheme &ColorMap::defaultColorScheme() const { - return colorschemes.at("Cornfield"); + return *findColorScheme("Cornfield"); } 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 = colorschemes.begin();it != colorschemes.end();it++) { + RenderColorScheme *scheme = (*it).second.get(); + if (name == scheme->name()) { + return &scheme->colorScheme(); + } + } + + return NULL; } -std::list ColorMap::colorSchemeNames() const +std::list ColorMap::colorSchemeNames(bool guiOnly) const { - std::list names; - for (boost::unordered_map::const_iterator iter=colorschemes.begin(); iter!=colorschemes.end(); iter++) { - names.push_back(iter->first); + std::list colorSchemes; + for (colorscheme_set_t::const_iterator it = colorschemes.begin();it != colorschemes.end();it++) { + RenderColorScheme *scheme = (*it).second.get(); + if (guiOnly && !scheme->showInGui()) { + continue; } - return names; + colorSchemes.push_back(scheme->name()); + } + + return colorSchemes; } Color4f ColorMap::getColor(const ColorScheme &cs, const RenderColor rc) @@ -315,19 +286,33 @@ 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()); - } +ColorMap::colorscheme_set_t ColorMap::enumerateColorSchemes() +{ + const fs::path resources = PlatformUtils::resourcesPath(); + const fs::path color_schemes = resources / "color-schemes" / "render"; - void printcolorschemes() - { - for (boost::unordered_map::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()); + colorscheme_set_t result_set; + 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()) { + result_set.insert(colorscheme_set_t::value_type(colorScheme->index(), boost::shared_ptr(colorScheme))); + } else { + delete colorScheme; + } } - } -*/ + } + + return result_set; +} \ No newline at end of file diff --git a/src/colormap.h b/src/colormap.h index 9f305efd..807b33a1 100644 --- a/src/colormap.h +++ b/src/colormap.h @@ -6,6 +6,13 @@ #include "linalg.h" #include +#include +#include +#include +#include + +namespace fs = boost::filesystem; + enum RenderColor { BACKGROUND_COLOR, OPENCSG_FACE_FRONT_COLOR, @@ -21,8 +28,37 @@ enum RenderColor { typedef std::map ColorScheme; +class RenderColorScheme +{ +private: + const fs::path path; + + boost::property_tree::ptree pt; + std::string _name; + int _index; + bool _show_in_gui; + + ColorScheme _color_scheme; + +public: + RenderColorScheme(const fs::path path); + virtual ~RenderColorScheme(); + + const std::string & name() const; + int index() const; + bool valid() const; + bool showInGui() const; + ColorScheme & colorScheme(); + const boost::property_tree::ptree & propertyTree() const; + +private: + void addColor(RenderColor colorKey, std::string key); +}; + class ColorMap { + typedef std::multimap, std::less > colorscheme_set_t; + public: static ColorMap *inst(bool erase = false); @@ -30,14 +66,15 @@ public: const boost::unordered_map &webColors() const { return webcolors; } const ColorScheme *findColorScheme(const std::string &name) const; - std::list colorSchemeNames() const; + std::list colorSchemeNames(bool guiOnly = false) const; static Color4f getColor(const ColorScheme &cs, const RenderColor rc); private: ColorMap(); ~ColorMap() {} + colorscheme_set_t enumerateColorSchemes(); boost::unordered_map webcolors; - boost::unordered_map colorschemes; + colorscheme_set_t colorschemes; }; From e59a2f035e5622ae6c60bd0bf4a02f1f72b5c853 Mon Sep 17 00:00:00 2001 From: Torsten Paul Date: Fri, 31 Oct 2014 23:20:12 +0100 Subject: [PATCH 19/47] Handle color scheme lookup in test cases. --- src/PlatformUtils.cc | 27 +++---- src/color.cc | 164 ++++++++++++++++++++++++++++++++++++++++- src/colormap.cc | 170 +++---------------------------------------- src/colormap.h | 11 +-- 4 files changed, 190 insertions(+), 182 deletions(-) diff --git a/src/PlatformUtils.cc b/src/PlatformUtils.cc index a7f6c61a..a49aed9a 100644 --- a/src/PlatformUtils.cc +++ b/src/PlatformUtils.cc @@ -110,20 +110,21 @@ std::string PlatformUtils::resourcesPath() if (!is_directory(resourcedir / "libraries")) resourcedir /= "../../.."; } #elif !defined(WIN32) - tmpdir = resourcedir / "../share/openscad"; - if (is_directory(tmpdir / "libraries")) { + const char *searchpath[] = { + "../share/openscad", + "../../share/openscad", + ".", + "..", + "../..", + NULL + }; + + for (int a = 0;searchpath[a] != NULL;a++) { + tmpdir = resourcedir / searchpath[a]; + 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; - } - } + break; + } } #endif // resourcedir defaults to applicationPath diff --git a/src/color.cc b/src/color.cc index 390a11d4..7792f0bf 100644 --- a/src/color.cc +++ b/src/color.cc @@ -31,22 +31,180 @@ #include "printutils.h" #include #include +#include #include #include #include using namespace boost::assign; // bring 'operator+=()' into scope -#include "colormap.h" class ColorModule : public AbstractModule { public: - ColorModule() : webcolors(ColorMap::inst()->webColors()) { } + ColorModule(); + virtual ~ColorModule(); virtual AbstractNode *instantiate(const Context *ctx, const ModuleInstantiation *inst, const EvalContext *evalctx) const; private: - const boost::unordered_map &webcolors; + boost::unordered_map webcolors; }; +ColorModule::ColorModule() +{ + webcolors = map_list_of + ("aliceblue", Color4f(240, 248, 255)) + ("antiquewhite", Color4f(250, 235, 215)) + ("aqua", Color4f(0, 255, 255)) + ("aquamarine", Color4f(127, 255, 212)) + ("azure", Color4f(240, 255, 255)) + ("beige", Color4f(245, 245, 220)) + ("bisque", Color4f(255, 228, 196)) + ("black", Color4f(0, 0, 0)) + ("blanchedalmond", Color4f(255, 235, 205)) + ("blue", Color4f(0, 0, 255)) + ("blueviolet", Color4f(138, 43, 226)) + ("brown", Color4f(165, 42, 42)) + ("burlywood", Color4f(222, 184, 135)) + ("cadetblue", Color4f(95, 158, 160)) + ("chartreuse", Color4f(127, 255, 0)) + ("chocolate", Color4f(210, 105, 30)) + ("coral", Color4f(255, 127, 80)) + ("cornflowerblue", Color4f(100, 149, 237)) + ("cornsilk", Color4f(255, 248, 220)) + ("crimson", Color4f(220, 20, 60)) + ("cyan", Color4f(0, 255, 255)) + ("darkblue", Color4f(0, 0, 139)) + ("darkcyan", Color4f(0, 139, 139)) + ("darkgoldenrod", Color4f(184, 134, 11)) + ("darkgray", Color4f(169, 169, 169)) + ("darkgreen", Color4f(0, 100, 0)) + ("darkgrey", Color4f(169, 169, 169)) + ("darkkhaki", Color4f(189, 183, 107)) + ("darkmagenta", Color4f(139, 0, 139)) + ("darkolivegreen", Color4f(85, 107, 47)) + ("darkorange", Color4f(255, 140, 0)) + ("darkorchid", Color4f(153, 50, 204)) + ("darkred", Color4f(139, 0, 0)) + ("darksalmon", Color4f(233, 150, 122)) + ("darkseagreen", Color4f(143, 188, 143)) + ("darkslateblue", Color4f(72, 61, 139)) + ("darkslategray", Color4f(47, 79, 79)) + ("darkslategrey", Color4f(47, 79, 79)) + ("darkturquoise", Color4f(0, 206, 209)) + ("darkviolet", Color4f(148, 0, 211)) + ("deeppink", Color4f(255, 20, 147)) + ("deepskyblue", Color4f(0, 191, 255)) + ("dimgray", Color4f(105, 105, 105)) + ("dimgrey", Color4f(105, 105, 105)) + ("dodgerblue", Color4f(30, 144, 255)) + ("firebrick", Color4f(178, 34, 34)) + ("floralwhite", Color4f(255, 250, 240)) + ("forestgreen", Color4f(34, 139, 34)) + ("fuchsia", Color4f(255, 0, 255)) + ("gainsboro", Color4f(220, 220, 220)) + ("ghostwhite", Color4f(248, 248, 255)) + ("gold", Color4f(255, 215, 0)) + ("goldenrod", Color4f(218, 165, 32)) + ("gray", Color4f(128, 128, 128)) + ("green", Color4f(0, 128, 0)) + ("greenyellow", Color4f(173, 255, 47)) + ("grey", Color4f(128, 128, 128)) + ("honeydew", Color4f(240, 255, 240)) + ("hotpink", Color4f(255, 105, 180)) + ("indianred", Color4f(205, 92, 92)) + ("indigo", Color4f(75, 0, 130)) + ("ivory", Color4f(255, 255, 240)) + ("khaki", Color4f(240, 230, 140)) + ("lavender", Color4f(230, 230, 250)) + ("lavenderblush", Color4f(255, 240, 245)) + ("lawngreen", Color4f(124, 252, 0)) + ("lemonchiffon", Color4f(255, 250, 205)) + ("lightblue", Color4f(173, 216, 230)) + ("lightcoral", Color4f(240, 128, 128)) + ("lightcyan", Color4f(224, 255, 255)) + ("lightgoldenrodyellow", Color4f(250, 250, 210)) + ("lightgray", Color4f(211, 211, 211)) + ("lightgreen", Color4f(144, 238, 144)) + ("lightgrey", Color4f(211, 211, 211)) + ("lightpink", Color4f(255, 182, 193)) + ("lightsalmon", Color4f(255, 160, 122)) + ("lightseagreen", Color4f(32, 178, 170)) + ("lightskyblue", Color4f(135, 206, 250)) + ("lightslategray", Color4f(119, 136, 153)) + ("lightslategrey", Color4f(119, 136, 153)) + ("lightsteelblue", Color4f(176, 196, 222)) + ("lightyellow", Color4f(255, 255, 224)) + ("lime", Color4f(0, 255, 0)) + ("limegreen", Color4f(50, 205, 50)) + ("linen", Color4f(250, 240, 230)) + ("magenta", Color4f(255, 0, 255)) + ("maroon", Color4f(128, 0, 0)) + ("mediumaquamarine", Color4f(102, 205, 170)) + ("mediumblue", Color4f(0, 0, 205)) + ("mediumorchid", Color4f(186, 85, 211)) + ("mediumpurple", Color4f(147, 112, 219)) + ("mediumseagreen", Color4f(60, 179, 113)) + ("mediumslateblue", Color4f(123, 104, 238)) + ("mediumspringgreen", Color4f(0, 250, 154)) + ("mediumturquoise", Color4f(72, 209, 204)) + ("mediumvioletred", Color4f(199, 21, 133)) + ("midnightblue", Color4f(25, 25, 112)) + ("mintcream", Color4f(245, 255, 250)) + ("mistyrose", Color4f(255, 228, 225)) + ("moccasin", Color4f(255, 228, 181)) + ("navajowhite", Color4f(255, 222, 173)) + ("navy", Color4f(0, 0, 128)) + ("oldlace", Color4f(253, 245, 230)) + ("olive", Color4f(128, 128, 0)) + ("olivedrab", Color4f(107, 142, 35)) + ("orange", Color4f(255, 165, 0)) + ("orangered", Color4f(255, 69, 0)) + ("orchid", Color4f(218, 112, 214)) + ("palegoldenrod", Color4f(238, 232, 170)) + ("palegreen", Color4f(152, 251, 152)) + ("paleturquoise", Color4f(175, 238, 238)) + ("palevioletred", Color4f(219, 112, 147)) + ("papayawhip", Color4f(255, 239, 213)) + ("peachpuff", Color4f(255, 218, 185)) + ("peru", Color4f(205, 133, 63)) + ("pink", Color4f(255, 192, 203)) + ("plum", Color4f(221, 160, 221)) + ("powderblue", Color4f(176, 224, 230)) + ("purple", Color4f(128, 0, 128)) + ("red", Color4f(255, 0, 0)) + ("rosybrown", Color4f(188, 143, 143)) + ("royalblue", Color4f(65, 105, 225)) + ("saddlebrown", Color4f(139, 69, 19)) + ("salmon", Color4f(250, 128, 114)) + ("sandybrown", Color4f(244, 164, 96)) + ("seagreen", Color4f(46, 139, 87)) + ("seashell", Color4f(255, 245, 238)) + ("sienna", Color4f(160, 82, 45)) + ("silver", Color4f(192, 192, 192)) + ("skyblue", Color4f(135, 206, 235)) + ("slateblue", Color4f(106, 90, 205)) + ("slategray", Color4f(112, 128, 144)) + ("slategrey", Color4f(112, 128, 144)) + ("snow", Color4f(255, 250, 250)) + ("springgreen", Color4f(0, 255, 127)) + ("steelblue", Color4f(70, 130, 180)) + ("tan", Color4f(210, 180, 140)) + ("teal", Color4f(0, 128, 128)) + ("thistle", Color4f(216, 191, 216)) + ("tomato", Color4f(255, 99, 71)) + ("transparent", Color4f(0, 0, 0, 0)) + ("turquoise", Color4f(64, 224, 208)) + ("violet", Color4f(238, 130, 238)) + ("wheat", Color4f(245, 222, 179)) + ("white", Color4f(255, 255, 255)) + ("whitesmoke", Color4f(245, 245, 245)) + ("yellow", Color4f(255, 255, 0)) + ("yellowgreen", Color4f(154, 205, 50)); +} + +ColorModule::~ColorModule() +{ +} + AbstractNode *ColorModule::instantiate(const Context *ctx, const ModuleInstantiation *inst, const EvalContext *evalctx) const { ColorNode *node = new ColorNode(inst); diff --git a/src/colormap.cc b/src/colormap.cc index 53bba012..0eaf5817 100644 --- a/src/colormap.cc +++ b/src/colormap.cc @@ -93,159 +93,13 @@ ColorMap *ColorMap::inst(bool erase) return instance; } -ColorMap::ColorMap() { - boost::unordered_map 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; - - colorschemes = enumerateColorSchemes(); +ColorMap::ColorMap() +{ + colorSchemeSet = enumerateColorSchemes(); +} + +ColorMap::~ColorMap() +{ } const ColorScheme &ColorMap::defaultColorScheme() const @@ -255,7 +109,7 @@ const ColorScheme &ColorMap::defaultColorScheme() const const ColorScheme *ColorMap::findColorScheme(const std::string &name) const { - for (colorscheme_set_t::const_iterator it = colorschemes.begin();it != colorschemes.end();it++) { + 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(); @@ -267,16 +121,16 @@ const ColorScheme *ColorMap::findColorScheme(const std::string &name) const std::list ColorMap::colorSchemeNames(bool guiOnly) const { - std::list colorSchemes; - for (colorscheme_set_t::const_iterator it = colorschemes.begin();it != colorschemes.end();it++) { + std::list colorSchemeNames; + for (colorscheme_set_t::const_iterator it = colorSchemeSet.begin();it != colorSchemeSet.end();it++) { RenderColorScheme *scheme = (*it).second.get(); if (guiOnly && !scheme->showInGui()) { continue; } - colorSchemes.push_back(scheme->name()); + colorSchemeNames.push_back(scheme->name()); } - return colorSchemes; + return colorSchemeNames; } Color4f ColorMap::getColor(const ColorScheme &cs, const RenderColor rc) diff --git a/src/colormap.h b/src/colormap.h index 807b33a1..90ca66fd 100644 --- a/src/colormap.h +++ b/src/colormap.h @@ -4,7 +4,6 @@ #include #include #include "linalg.h" -#include #include #include @@ -62,9 +61,7 @@ class ColorMap public: static ColorMap *inst(bool erase = false); - const ColorScheme &defaultColorScheme() const; - - const boost::unordered_map &webColors() const { return webcolors; } + const ColorScheme & defaultColorScheme() const; const ColorScheme *findColorScheme(const std::string &name) const; std::list colorSchemeNames(bool guiOnly = false) const; @@ -72,9 +69,7 @@ public: private: ColorMap(); - ~ColorMap() {} + virtual ~ColorMap(); colorscheme_set_t enumerateColorSchemes(); - - boost::unordered_map webcolors; - colorscheme_set_t colorschemes; + colorscheme_set_t colorSchemeSet; }; From 42fab36a05590e68dcd3828e11721ac5b62aebab Mon Sep 17 00:00:00 2001 From: Torsten Paul Date: Sat, 1 Nov 2014 22:20:32 +0100 Subject: [PATCH 20/47] Add color schemes to "make install". --- openscad.pro | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/openscad.pro b/openscad.pro index a2692b66..f926ac56 100644 --- a/openscad.pro +++ b/openscad.pro @@ -480,6 +480,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 From 7c3077b0f24cfcac7d65df56c14e1c3c246eaed4 Mon Sep 17 00:00:00 2001 From: Torsten Paul Date: Sat, 1 Nov 2014 23:06:36 +0100 Subject: [PATCH 21/47] Read color schemes from additional user config path. --- src/PlatformUtils-mac.mm | 5 +++++ src/PlatformUtils-posix.cc | 22 ++++++++++++++++++++++ src/PlatformUtils-win.cc | 5 +++++ src/PlatformUtils.h | 10 ++++++++++ src/colormap.cc | 18 ++++++++++++------ src/colormap.h | 1 + src/scintillaeditor.cpp | 14 ++++++++++---- src/scintillaeditor.h | 1 + 8 files changed, 66 insertions(+), 10 deletions(-) diff --git a/src/PlatformUtils-mac.mm b/src/PlatformUtils-mac.mm index 418bbfed..a58b2c67 100644 --- a/src/PlatformUtils-mac.mm +++ b/src/PlatformUtils-mac.mm @@ -11,5 +11,10 @@ std::string PlatformUtils::documentsPath() return std::string([[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject] UTF8String]); } +std::string PlatformUtils::userConfigPath() +{ + return ""; +} + void PlatformUtils::ensureStdIO(void) {} diff --git a/src/PlatformUtils-posix.cc b/src/PlatformUtils-posix.cc index ab0dd9bd..bc29a32c 100644 --- a/src/PlatformUtils-posix.cc +++ b/src/PlatformUtils-posix.cc @@ -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"; + } else { + const char *home = getenv("HOME"); + if (home) { + config_path = fs::path(home) / ".config" / "OpenSCAD"; + } + } + + if (fs::is_directory(config_path)) { + return boosty::stringy(boosty::absolute(config_path)); + } + + return ""; +} + void PlatformUtils::ensureStdIO(void) {} diff --git a/src/PlatformUtils-win.cc b/src/PlatformUtils-win.cc index 1091a229..58240855 100644 --- a/src/PlatformUtils-win.cc +++ b/src/PlatformUtils-win.cc @@ -78,6 +78,11 @@ std::string PlatformUtils::documentsPath() return retval; } +std::string PlatformUtils::userConfigPath() +{ + return ""; +} + #include #include #include diff --git a/src/PlatformUtils.h b/src/PlatformUtils.h index ca28134c..6f3b67bb 100644 --- a/src/PlatformUtils.h +++ b/src/PlatformUtils.h @@ -10,6 +10,16 @@ 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. + * + * @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(); diff --git a/src/colormap.cc b/src/colormap.cc index 0eaf5817..0723bbda 100644 --- a/src/colormap.cc +++ b/src/colormap.cc @@ -140,12 +140,10 @@ Color4f ColorMap::getColor(const ColorScheme &cs, const RenderColor rc) return Color4f(0, 0, 0, 127); } -ColorMap::colorscheme_set_t ColorMap::enumerateColorSchemes() +void ColorMap::enumerateColorSchemesInPath(colorscheme_set_t &result_set, const fs::path path) { - const fs::path resources = PlatformUtils::resourcesPath(); - const fs::path color_schemes = resources / "color-schemes" / "render"; - - colorscheme_set_t result_set; + const fs::path color_schemes = path / "color-schemes" / "render"; + fs::directory_iterator end_iter; if (fs::exists(color_schemes) && fs::is_directory(color_schemes)) { @@ -160,13 +158,21 @@ ColorMap::colorscheme_set_t ColorMap::enumerateColorSchemes() } RenderColorScheme *colorScheme = new RenderColorScheme(path); - if (colorScheme->valid()) { + if (colorScheme->valid() && (findColorScheme(colorScheme->name()) == 0)) { result_set.insert(colorscheme_set_t::value_type(colorScheme->index(), boost::shared_ptr(colorScheme))); } else { delete colorScheme; } } } +} + +ColorMap::colorscheme_set_t ColorMap::enumerateColorSchemes() +{ + colorscheme_set_t result_set; + + enumerateColorSchemesInPath(result_set, PlatformUtils::resourcesPath()); + enumerateColorSchemesInPath(result_set, PlatformUtils::userConfigPath()); return result_set; } \ No newline at end of file diff --git a/src/colormap.h b/src/colormap.h index 90ca66fd..216afae2 100644 --- a/src/colormap.h +++ b/src/colormap.h @@ -71,5 +71,6 @@ private: ColorMap(); virtual ~ColorMap(); colorscheme_set_t enumerateColorSchemes(); + void enumerateColorSchemesInPath(colorscheme_set_t &result_set, const fs::path path); colorscheme_set_t colorSchemeSet; }; diff --git a/src/scintillaeditor.cpp b/src/scintillaeditor.cpp index dfdc70a3..d29d28f3 100644 --- a/src/scintillaeditor.cpp +++ b/src/scintillaeditor.cpp @@ -223,12 +223,10 @@ void ScintillaEditor::noColor() qsci->setEdgeColor(Qt::black); } -ScintillaEditor::colorscheme_set_t ScintillaEditor::enumerateColorSchemes() +void ScintillaEditor::enumerateColorSchemesInPath(ScintillaEditor::colorscheme_set_t &result_set, const fs::path path) { - const fs::path resources = PlatformUtils::resourcesPath(); - const fs::path color_schemes = resources / "color-schemes" / "editor"; + const fs::path color_schemes = path / "color-schemes" / "editor"; - colorscheme_set_t result_set; fs::directory_iterator end_iter; if (fs::exists(color_schemes) && fs::is_directory(color_schemes)) { @@ -250,6 +248,14 @@ ScintillaEditor::colorscheme_set_t ScintillaEditor::enumerateColorSchemes() } } } +} + +ScintillaEditor::colorscheme_set_t ScintillaEditor::enumerateColorSchemes() +{ + colorscheme_set_t result_set; + + enumerateColorSchemesInPath(result_set, PlatformUtils::resourcesPath()); + enumerateColorSchemesInPath(result_set, PlatformUtils::userConfigPath()); return result_set; } diff --git a/src/scintillaeditor.h b/src/scintillaeditor.h index 87c10026..3b582ea6 100644 --- a/src/scintillaeditor.h +++ b/src/scintillaeditor.h @@ -59,6 +59,7 @@ private: 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: From 073c6fe2b3d9352b869d4ed002790707e130cf7f Mon Sep 17 00:00:00 2001 From: Torsten Paul Date: Sun, 2 Nov 2014 16:39:03 +0100 Subject: [PATCH 22/47] Add color schemes to Windows installer. --- scripts/installer.nsi | 2 ++ scripts/release-common.sh | 8 ++++++++ 2 files changed, 10 insertions(+) diff --git a/scripts/installer.nsi b/scripts/installer.nsi index 96396169..d1fb7712 100644 --- a/scripts/installer.nsi +++ b/scripts/installer.nsi @@ -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 diff --git a/scripts/release-common.sh b/scripts/release-common.sh index 80402ef2..f3ab9f81 100755 --- a/scripts/release-common.sh +++ b/scripts/release-common.sh @@ -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 From 34981284fca2ade56558ec9b98c9f9a22c4f910f Mon Sep 17 00:00:00 2001 From: Torsten Paul Date: Sun, 2 Nov 2014 16:39:51 +0100 Subject: [PATCH 23/47] Use local AppData folder for user config on Windows. --- src/PlatformUtils-posix.cc | 4 ++-- src/PlatformUtils-win.cc | 49 ++++++++++++++++++++++---------------- src/PlatformUtils.cc | 6 +++-- src/PlatformUtils.h | 6 ++++- 4 files changed, 40 insertions(+), 25 deletions(-) diff --git a/src/PlatformUtils-posix.cc b/src/PlatformUtils-posix.cc index bc29a32c..64cc5dbe 100644 --- a/src/PlatformUtils-posix.cc +++ b/src/PlatformUtils-posix.cc @@ -26,11 +26,11 @@ std::string PlatformUtils::userConfigPath() const char *xdg_env = getenv("XDG_CONFIG_HOME"); if (xdg_env && fs::exists(fs::path(xdg_env))) { - config_path = fs::path(xdg_env) / "OpenSCAD"; + config_path = fs::path(xdg_env) / OPENSCAD_FOLDER_NAME; } else { const char *home = getenv("HOME"); if (home) { - config_path = fs::path(home) / ".config" / "OpenSCAD"; + config_path = fs::path(home) / ".config" / OPENSCAD_FOLDER_NAME; } } diff --git a/src/PlatformUtils-win.cc b/src/PlatformUtils-win.cc index 58240855..a504bb1f 100644 --- a/src/PlatformUtils-win.cc +++ b/src/PlatformUtils-win.cc @@ -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,32 +76,20 @@ 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() { - return ""; + 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 diff --git a/src/PlatformUtils.cc b/src/PlatformUtils.cc index a49aed9a..54c6cd9c 100644 --- a/src/PlatformUtils.cc +++ b/src/PlatformUtils.cc @@ -14,6 +14,8 @@ namespace { std::string applicationpath; } +const char *PlatformUtils::OPENSCAD_FOLDER_NAME = "OpenSCAD"; + void PlatformUtils::registerApplicationPath(const std::string &apppath) { applicationpath = apppath; @@ -52,7 +54,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 +73,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()); diff --git a/src/PlatformUtils.h b/src/PlatformUtils.h index 6f3b67bb..11b58b08 100644 --- a/src/PlatformUtils.h +++ b/src/PlatformUtils.h @@ -3,6 +3,7 @@ #include namespace PlatformUtils { + extern const char *OPENSCAD_FOLDER_NAME; void registerApplicationPath(const std::string &applicationpath); std::string applicationPath(); @@ -13,7 +14,10 @@ namespace PlatformUtils { /** * Base path where user configuration can be read and written to. On - * Linux this is the $XDG_CONFIG_HOME. + * 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. From 7c677c968f41bed13f7bdb81e656e817f41eceaf Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Sun, 2 Nov 2014 23:59:15 +0400 Subject: [PATCH 24/47] Added text tessellation test --- .../experimental/tessellation-text-test.scad | 10 ++++++++++ tests/CMakeLists.txt | 3 ++- .../tessellation-text-test-expected.png | Bin 0 -> 10724 bytes .../tessellation-text-test-expected.png | Bin 0 -> 11214 bytes .../tessellation-text-test-expected.png | Bin 0 -> 11214 bytes 5 files changed, 12 insertions(+), 1 deletion(-) create mode 100644 testdata/scad/experimental/tessellation-text-test.scad create mode 100644 tests/regression/cgalpngtest/tessellation-text-test-expected.png create mode 100644 tests/regression/opencsgtest/tessellation-text-test-expected.png create mode 100644 tests/regression/throwntogethertest/tessellation-text-test-expected.png diff --git a/testdata/scad/experimental/tessellation-text-test.scad b/testdata/scad/experimental/tessellation-text-test.scad new file mode 100644 index 00000000..92c270bd --- /dev/null +++ b/testdata/scad/experimental/tessellation-text-test.scad @@ -0,0 +1,10 @@ +module letter(c) { + text(c, size = 50, font = "Liberation Sans", halign = "center", valign = "center"); +} + +linear_extrude(height = 10) { + letter("C", $fn=8); + translate([50,0]) letter("C", $fn=16); + translate([0,50]) letter("C", $fn=24); + translate([50,50]) letter("C", $fn=32); +} diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index a4130dc9..e5c53072 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -1086,7 +1086,8 @@ list(APPEND CGALPNGTEST_3D_FILES ${CMAKE_SOURCE_DIR}/../testdata/scad/misc/inclu ${CMAKE_SOURCE_DIR}/../testdata/scad/misc/bad-stl-pcbvicebar.scad ${CMAKE_SOURCE_DIR}/../testdata/scad/misc/bad-stl-tardis.scad ${CMAKE_SOURCE_DIR}/../testdata/scad/misc/bad-stl-wing.scad - ${CMAKE_SOURCE_DIR}/../testdata/scad/misc/rotate_extrude-hole.scad) + ${CMAKE_SOURCE_DIR}/../testdata/scad/misc/rotate_extrude-hole.scad + ${CMAKE_SOURCE_DIR}/../testdata/scad/experimental/tessellation-text-test.scad) list(APPEND CGALPNGTEST_FILES ${CGALPNGTEST_2D_FILES} ${CGALPNGTEST_3D_FILES}) list(APPEND OPENCSGTEST_FILES ${CGALPNGTEST_FILES}) diff --git a/tests/regression/cgalpngtest/tessellation-text-test-expected.png b/tests/regression/cgalpngtest/tessellation-text-test-expected.png new file mode 100644 index 0000000000000000000000000000000000000000..1363c904594ce2577282fddc9451da7f0e857d56 GIT binary patch literal 10724 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 M*1J)3-8%Gt08yimTmS$7 literal 0 HcmV?d00001 diff --git a/tests/regression/opencsgtest/tessellation-text-test-expected.png b/tests/regression/opencsgtest/tessellation-text-test-expected.png new file mode 100644 index 0000000000000000000000000000000000000000..233cf9ab359102f950e32988ffbf4fb92fd70846 GIT binary patch literal 11214 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 Shd)62X{hMjExu#%^uGYB-p&aC literal 0 HcmV?d00001 diff --git a/tests/regression/throwntogethertest/tessellation-text-test-expected.png b/tests/regression/throwntogethertest/tessellation-text-test-expected.png new file mode 100644 index 0000000000000000000000000000000000000000..233cf9ab359102f950e32988ffbf4fb92fd70846 GIT binary patch literal 11214 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 Shd)62X{hMjExu#%^uGYB-p&aC literal 0 HcmV?d00001 From 4306586adffecbd6ac5235a74eb2206c3caeb912 Mon Sep 17 00:00:00 2001 From: Torsten Paul Date: Sun, 2 Nov 2014 22:18:23 +0100 Subject: [PATCH 25/47] Set OPENSCAD_FONT_PATH also for the normal test cases. This was already set for the export/import test cases as the exported CSG files do not have the use statements. Due to differences in the glyphs between the Liberation 2.00.1 we ship and the system installed fonts some test cases (e.g. text_on_cube) did also fail. --- tests/test_cmdline_tool.py | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/tests/test_cmdline_tool.py b/tests/test_cmdline_tool.py index 3a2a539c..45cd0b3b 100755 --- a/tests/test_cmdline_tool.py +++ b/tests/test_cmdline_tool.py @@ -9,6 +9,11 @@ # Any generated output is written to the file `basename # Any warning or errors are written to stderr. # +# The test is run with OPENSCAD_FONT_PATH set to the testdata/ttf directory. This +# should ensure we fetch the fonts from there even if they are also installed +# on the system. (E.g. the C glyph is actually different from Debian/Jessie +# installation and what we ship as Liberation-2.00.1). +# # Returns 0 on passed test # 1 on error # 2 on invalid cmd-line options @@ -195,8 +200,12 @@ def run_test(testname, cmd, args): try: cmdline = [cmd] + args + [outputname] print 'run_test() cmdline:',cmdline + fontdir = os.path.join(os.path.dirname(cmd), "..", "testdata") + fontenv = os.environ.copy() + fontenv["OPENSCAD_FONT_PATH"] = fontdir + print 'using font directory:', fontdir sys.stdout.flush() - proc = subprocess.Popen(cmdline, stdout=subprocess.PIPE, stderr=subprocess.PIPE) + proc = subprocess.Popen(cmdline, env = fontenv, stdout=subprocess.PIPE, stderr=subprocess.PIPE) comresult = proc.communicate() stdouttext, errtext = comresult[0],comresult[1] if errtext != None and len(errtext) > 0: From 46bffd3f4c5f8901e414aa30f58a9c032eb451bb Mon Sep 17 00:00:00 2001 From: Torsten Paul Date: Sun, 2 Nov 2014 23:36:23 +0100 Subject: [PATCH 26/47] Move default color scheme back into code. --- color-schemes/render/cornfield.json | 18 ------------------ src/colormap.cc | 25 ++++++++++++++++++++++++- src/colormap.h | 11 ++++++++++- 3 files changed, 34 insertions(+), 20 deletions(-) delete mode 100644 color-schemes/render/cornfield.json diff --git a/color-schemes/render/cornfield.json b/color-schemes/render/cornfield.json deleted file mode 100644 index dda82ffd..00000000 --- a/color-schemes/render/cornfield.json +++ /dev/null @@ -1,18 +0,0 @@ -{ - "name" : "Cornfield", - "index" : 1000, - "show-in-gui" : true, - - "colors" : { - "background" : "#ffffe5", - "opencsg-face-front" : "#f9d72c", - "opencsg-face-back" : "#9dcb51", - "cgal-face-front" : "#f9d72c", - "cgal-face-back" : "#9dcb51", - "cgal-face-2d" : "#00bf99", - "cgal-edge-front" : "#ffec5e", - "cgal-edge-back" : "#abd856", - "cgal-edge-2d" : "#ff0000", - "crosshair" : "#800000" - } -} diff --git a/src/colormap.cc b/src/colormap.cc index 0723bbda..c3a1b18a 100644 --- a/src/colormap.cc +++ b/src/colormap.cc @@ -7,6 +7,26 @@ using namespace boost::assign; // bring map_list_of() into scope +static const char *DEFAULT_COLOR_SCHEME_NAME = "Cornfield"; + +RenderColorScheme::RenderColorScheme() : path("") +{ + _name = DEFAULT_COLOR_SCHEME_NAME; + _index = 1000; + _show_in_gui = true; + + _color_scheme.insert(ColorScheme::value_type(BACKGROUND_COLOR, Color4f(0xff, 0xff, 0xe5))); + _color_scheme.insert(ColorScheme::value_type(OPENCSG_FACE_FRONT_COLOR, Color4f(0xf9, 0xd7, 0x2c))); + _color_scheme.insert(ColorScheme::value_type(OPENCSG_FACE_BACK_COLOR, Color4f(0x9d, 0xcb, 0x51))); + _color_scheme.insert(ColorScheme::value_type(CGAL_FACE_FRONT_COLOR, Color4f(0xf9, 0xd7, 0x2c))); + _color_scheme.insert(ColorScheme::value_type(CGAL_FACE_2D_COLOR, Color4f(0x00, 0xbf, 0x99))); + _color_scheme.insert(ColorScheme::value_type(CGAL_FACE_BACK_COLOR, Color4f(0x9d, 0xcb, 0x51))); + _color_scheme.insert(ColorScheme::value_type(CGAL_EDGE_FRONT_COLOR, Color4f(0xff, 0xec, 0x5e))); + _color_scheme.insert(ColorScheme::value_type(CGAL_EDGE_BACK_COLOR, Color4f(0xab, 0xd8, 0x56))); + _color_scheme.insert(ColorScheme::value_type(CGAL_EDGE_2D_COLOR, Color4f(0xff, 0x00, 0x00))); + _color_scheme.insert(ColorScheme::value_type(CROSSHAIR_COLOR, Color4f(0x80, 0x00, 0x00))); +} + RenderColorScheme::RenderColorScheme(fs::path path) : path(path) { try { @@ -104,7 +124,7 @@ ColorMap::~ColorMap() const ColorScheme &ColorMap::defaultColorScheme() const { - return *findColorScheme("Cornfield"); + return *findColorScheme(DEFAULT_COLOR_SCHEME_NAME); } const ColorScheme *ColorMap::findColorScheme(const std::string &name) const @@ -171,6 +191,9 @@ 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(defaultColorScheme))); enumerateColorSchemesInPath(result_set, PlatformUtils::resourcesPath()); enumerateColorSchemesInPath(result_set, PlatformUtils::userConfigPath()); diff --git a/src/colormap.h b/src/colormap.h index 216afae2..168fa463 100644 --- a/src/colormap.h +++ b/src/colormap.h @@ -40,9 +40,16 @@ private: 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; @@ -52,6 +59,8 @@ public: private: void addColor(RenderColor colorKey, std::string key); + + friend class ColorMap; }; class ColorMap From a9cbabdbc2859a6b6072a43bd3c1cdbdbcbb6fc1 Mon Sep 17 00:00:00 2001 From: Torsten Paul Date: Sun, 2 Nov 2014 23:42:24 +0100 Subject: [PATCH 27/47] Remove some obsolete dependencies to colormap.h. --- src/Preferences.h | 1 - src/rendersettings.cc | 1 - src/rendersettings.h | 1 - 3 files changed, 3 deletions(-) diff --git a/src/Preferences.h b/src/Preferences.h index 96001d25..b5fa6523 100644 --- a/src/Preferences.h +++ b/src/Preferences.h @@ -3,7 +3,6 @@ #include #include #include "ui_Preferences.h" -#include "colormap.h" class Preferences : public QMainWindow, public Ui::Preferences { diff --git a/src/rendersettings.cc b/src/rendersettings.cc index b3eb86b2..36c69293 100644 --- a/src/rendersettings.cc +++ b/src/rendersettings.cc @@ -1,5 +1,4 @@ #include "rendersettings.h" -#include "colormap.h" #include "printutils.h" RenderSettings *RenderSettings::inst(bool erase) diff --git a/src/rendersettings.h b/src/rendersettings.h index 09be9ded..4320dad0 100644 --- a/src/rendersettings.h +++ b/src/rendersettings.h @@ -2,7 +2,6 @@ #include #include "linalg.h" -#include "colormap.h" class RenderSettings { From 728f1337a267670b4670feb889dbe55513bee91a Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Wed, 5 Nov 2014 14:33:36 +0400 Subject: [PATCH 28/47] #1006 Added testcase --- testdata/scad/bugs/issue1006.scad | 2 ++ tests/CMakeLists.txt | 3 ++- .../cgalpngtest/issue1006-expected.png | Bin 0 -> 8930 bytes .../monotonepngtest/issue1006-expected.png | Bin 0 -> 8930 bytes .../opencsgtest/issue1006-expected.png | Bin 0 -> 9108 bytes 5 files changed, 4 insertions(+), 1 deletion(-) create mode 100644 testdata/scad/bugs/issue1006.scad create mode 100644 tests/regression/cgalpngtest/issue1006-expected.png create mode 100644 tests/regression/monotonepngtest/issue1006-expected.png create mode 100644 tests/regression/opencsgtest/issue1006-expected.png diff --git a/testdata/scad/bugs/issue1006.scad b/testdata/scad/bugs/issue1006.scad new file mode 100644 index 00000000..b3f75d0a --- /dev/null +++ b/testdata/scad/bugs/issue1006.scad @@ -0,0 +1,2 @@ +rotate([0, 45, 0]) cube(50, true); +rotate([0, 0, 45]) cube(50, true); diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index e5c53072..29e1af74 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -1207,7 +1207,8 @@ list(APPEND BUGS_FILES ${CMAKE_SOURCE_DIR}/../testdata/scad/bugs/issue584.scad ${CMAKE_SOURCE_DIR}/../testdata/scad/bugs/issue936.scad ${CMAKE_SOURCE_DIR}/../testdata/scad/bugs/issue964.scad ${CMAKE_SOURCE_DIR}/../testdata/scad/bugs/issue964b.scad - ${CMAKE_SOURCE_DIR}/../testdata/scad/bugs/issue990.scad) + ${CMAKE_SOURCE_DIR}/../testdata/scad/bugs/issue990.scad + ${CMAKE_SOURCE_DIR}/../testdata/scad/bugs/issue1006.scad) list(APPEND EXPORT3D_TEST_FILES ${BUGS_FILES}) list(APPEND OPENCSGTEST_FILES ${BUGS_FILES}) diff --git a/tests/regression/cgalpngtest/issue1006-expected.png b/tests/regression/cgalpngtest/issue1006-expected.png new file mode 100644 index 0000000000000000000000000000000000000000..88ee57b229e26577e137fc2a688996bcc7ddcdf3 GIT binary patch literal 8930 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 E0LNe>r2qf` literal 0 HcmV?d00001 From 9205a378c49524943b10dbe677d154fd1980f2ab Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Wed, 5 Nov 2014 16:14:14 +0400 Subject: [PATCH 29/47] Added ~/Library/Application Support as user config path on Mac --- src/PlatformUtils-mac.mm | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/PlatformUtils-mac.mm b/src/PlatformUtils-mac.mm index a58b2c67..c6ba6277 100644 --- a/src/PlatformUtils-mac.mm +++ b/src/PlatformUtils-mac.mm @@ -13,7 +13,9 @@ std::string PlatformUtils::documentsPath() std::string PlatformUtils::userConfigPath() { - return ""; + 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) {} From 3fd7d9da3cf2a1e132b43f3eb7db9337c82a395b Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Wed, 5 Nov 2014 16:45:14 +0400 Subject: [PATCH 30/47] Unify resource path location, correctly find resources for the test suite on Mac --- src/PlatformUtils.cc | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/src/PlatformUtils.cc b/src/PlatformUtils.cc index 54c6cd9c..91f2b97a 100644 --- a/src/PlatformUtils.cc +++ b/src/PlatformUtils.cc @@ -103,15 +103,15 @@ std::string PlatformUtils::resourcesPath() { fs::path resourcedir(applicationPath()); fs::path tmpdir; +#ifndef WIN32 #ifdef __APPLE__ - // Resources can be bundled on Mac. If not, fall back to development layout - bool isbundle = is_directory(resourcedir / ".." / "Resources"); - if (isbundle) { - resourcedir /= "../Resources"; - // Fall back to dev layout - if (!is_directory(resourcedir / "libraries")) resourcedir /= "../../.."; - } -#elif !defined(WIN32) + const char *searchpath[] = { + "../Resources", // Resources can be bundled on Mac. + "../../..", // Dev location + "..", // Test location + NULL + }; +#else const char *searchpath[] = { "../share/openscad", "../../share/openscad", @@ -120,7 +120,7 @@ std::string PlatformUtils::resourcesPath() "../..", NULL }; - +#endif for (int a = 0;searchpath[a] != NULL;a++) { tmpdir = resourcedir / searchpath[a]; if (is_directory(tmpdir / "libraries")) { @@ -128,7 +128,7 @@ std::string PlatformUtils::resourcesPath() break; } } -#endif +#endif // !WIN32 // resourcedir defaults to applicationPath return boosty::stringy(boosty::canonical(resourcedir)); } From 9e882be3198ccd9975aa4cda0086a9fbb9bb60fd Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Wed, 5 Nov 2014 18:16:05 +0400 Subject: [PATCH 31/47] #1005 Added testcase --- testdata/scad/bugs/issue1005.scad | 1 + tests/CMakeLists.txt | 1 + .../cgalpngtest/issue1005-expected.png | Bin 0 -> 4408 bytes .../monotonepngtest/issue1005-expected.png | Bin 0 -> 4408 bytes .../opencsgtest/issue1005-expected.png | Bin 0 -> 14603 bytes 5 files changed, 2 insertions(+) create mode 100644 testdata/scad/bugs/issue1005.scad create mode 100644 tests/regression/cgalpngtest/issue1005-expected.png create mode 100644 tests/regression/monotonepngtest/issue1005-expected.png create mode 100644 tests/regression/opencsgtest/issue1005-expected.png diff --git a/testdata/scad/bugs/issue1005.scad b/testdata/scad/bugs/issue1005.scad new file mode 100644 index 00000000..993dae9b --- /dev/null +++ b/testdata/scad/bugs/issue1005.scad @@ -0,0 +1 @@ +%sphere(10); diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 29e1af74..c6042cb5 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -1208,6 +1208,7 @@ list(APPEND BUGS_FILES ${CMAKE_SOURCE_DIR}/../testdata/scad/bugs/issue584.scad ${CMAKE_SOURCE_DIR}/../testdata/scad/bugs/issue964.scad ${CMAKE_SOURCE_DIR}/../testdata/scad/bugs/issue964b.scad ${CMAKE_SOURCE_DIR}/../testdata/scad/bugs/issue990.scad + ${CMAKE_SOURCE_DIR}/../testdata/scad/bugs/issue1005.scad ${CMAKE_SOURCE_DIR}/../testdata/scad/bugs/issue1006.scad) list(APPEND EXPORT3D_TEST_FILES ${BUGS_FILES}) diff --git a/tests/regression/cgalpngtest/issue1005-expected.png b/tests/regression/cgalpngtest/issue1005-expected.png new file mode 100644 index 0000000000000000000000000000000000000000..08ee92b2216f45ca6b83efbc3b78c9fdabf45a71 GIT binary patch literal 4408 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 F{{Ym)bJhR= literal 0 HcmV?d00001 From 26da9ca983224caf15f90649e86dda339c582a03 Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Wed, 5 Nov 2014 18:22:08 +0400 Subject: [PATCH 32/47] Include debug objects in View All --- src/OpenCSGRenderer.cc | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/OpenCSGRenderer.cc b/src/OpenCSGRenderer.cc index 0c1aa4e0..4c41e059 100644 --- a/src/OpenCSGRenderer.cc +++ b/src/OpenCSGRenderer.cc @@ -152,5 +152,7 @@ BoundingBox OpenCSGRenderer::getBoundingBox() const { BoundingBox bbox; if (this->root_chain) bbox = this->root_chain->getBoundingBox(); + if (this->background_chain) bbox.extend(this->background_chain->getBoundingBox()); + return bbox; } From 44af2b86ce8708330348a8deae469a3d252850e7 Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Wed, 5 Nov 2014 18:25:55 +0400 Subject: [PATCH 33/47] Added color-schemes folder --- xcode/OpenSCAD.xcodeproj/project.pbxproj | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/xcode/OpenSCAD.xcodeproj/project.pbxproj b/xcode/OpenSCAD.xcodeproj/project.pbxproj index e878f77e..418fa3fc 100644 --- a/xcode/OpenSCAD.xcodeproj/project.pbxproj +++ b/xcode/OpenSCAD.xcodeproj/project.pbxproj @@ -638,7 +638,7 @@ ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "rm -rf \"$BUILT_PRODUCTS_DIR/$FULL_PRODUCT_NAME\"\ncp -Rf \"$PROJECT_DIR/../$FULL_PRODUCT_NAME\" \"$PROJECT_DIR/../libraries\" \"$PROJECT_DIR/../examples\" \"$PROJECT_DIR/../fonts\" \"$BUILT_PRODUCTS_DIR\""; + shellScript = "rm -rf \"$BUILT_PRODUCTS_DIR/$FULL_PRODUCT_NAME\"\ncp -Rf \"$PROJECT_DIR/../$FULL_PRODUCT_NAME\" \"$PROJECT_DIR/../libraries\" \"$PROJECT_DIR/../examples\" \"$PROJECT_DIR/../fonts\" \"$PROJECT_DIR/../color-schemes\" \"$BUILT_PRODUCTS_DIR\""; }; E0395E7C19AA884F00E43D12 /* ShellScript */ = { isa = PBXShellScriptBuildPhase; @@ -651,7 +651,7 @@ ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "rm -rf \"$BUILT_PRODUCTS_DIR/$FULL_PRODUCT_NAME\"\ncp -Rf \"$PROJECT_DIR/../tests/$FULL_PRODUCT_NAME\" \"$PROJECT_DIR/../libraries\" \"$PROJECT_DIR/../examples\" \"$PROJECT_DIR/../fonts\" \"$BUILT_PRODUCTS_DIR\""; + shellScript = "rm -rf \"$BUILT_PRODUCTS_DIR/$FULL_PRODUCT_NAME\"\ncp -Rf \"$PROJECT_DIR/../tests/$FULL_PRODUCT_NAME\" \"$PROJECT_DIR/../libraries\" \"$PROJECT_DIR/../examples\" \"$PROJECT_DIR/../fonts\" \"$PROJECT_DIR/../color-schemes\" \"$BUILT_PRODUCTS_DIR\""; }; /* End PBXShellScriptBuildPhase section */ From 1342db57cf5b4890cb9cb1837480dbe04c0e5c8b Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Wed, 5 Nov 2014 18:33:30 +0400 Subject: [PATCH 34/47] Include debug objects in View All --- .../background-modifier-expected.png | Bin 17135 -> 15605 bytes ...light-and-background-modifier-expected.png | Bin 25034 -> 23054 bytes 2 files changed, 0 insertions(+), 0 deletions(-) diff --git a/tests/regression/opencsgtest/background-modifier-expected.png b/tests/regression/opencsgtest/background-modifier-expected.png index bd5df80fd817e262113116e2748d962be6df3fd0..335ed57d1bc8a9dddd7bd6d9ce0303220f9c8c27 100644 GIT binary patch literal 15605 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 k{pUsht%Ls;D)34h($ literal 17135 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 diff --git a/tests/regression/opencsgtest/highlight-and-background-modifier-expected.png b/tests/regression/opencsgtest/highlight-and-background-modifier-expected.png index c1c731309c6ce63afb2fea453221aacd61f27625..0548d56792c9070a141ae702a2e32074d6a7ba7a 100644 GIT binary patch literal 23054 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 JTxCd(`wyH+WDo!V literal 25034 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%0Ak}3Mi`YR_sfLxbeM74P> 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 From 7086f5fc3737e66fa8c99113e120159f328366f9 Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Wed, 5 Nov 2014 18:58:45 +0400 Subject: [PATCH 35/47] Fixed build issue related to https://svn.boost.org/trac/boost/ticket/6455 --- src/openscad.cc | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/src/openscad.cc b/src/openscad.cc index 433f9aa1..5f660284 100644 --- a/src/openscad.cc +++ b/src/openscad.cc @@ -56,13 +56,6 @@ #include -#ifdef __APPLE__ -#include "AppleEvents.h" -#ifdef OPENSCAD_DEPLOY - #include "SparkleAutoUpdater.h" -#endif -#endif - #include "Camera.h" #include #include @@ -70,6 +63,13 @@ #include #include "boosty.h" +#ifdef __APPLE__ +#include "AppleEvents.h" +#ifdef OPENSCAD_DEPLOY + #include "SparkleAutoUpdater.h" +#endif +#endif + #ifdef _MSC_VER #define snprintf _snprintf #endif @@ -557,9 +557,9 @@ int gui(vector &inputFiles, const fs::path &original_path, int argc, cha #endif #if defined(OPENSCAD_DEPLOY) && defined(Q_OS_MAC) - AutoUpdater *updater = new SparkleAutoUpdater; - AutoUpdater::setUpdater(updater); - if (updater->automaticallyChecksForUpdates()) updater->checkForUpdates(); +// AutoUpdater *updater = new SparkleAutoUpdater; +// AutoUpdater::setUpdater(updater); +// if (updater->automaticallyChecksForUpdates()) updater->checkForUpdates(); #endif #if 0 /*** disabled by clifford wolf: adds rendering artefacts with OpenCSG ***/ From 01b845397a82b2934dc9548baf9fecf655968bb1 Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Wed, 5 Nov 2014 18:59:06 +0400 Subject: [PATCH 36/47] Added buildonly option --- scripts/publish-macosx.sh | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/scripts/publish-macosx.sh b/scripts/publish-macosx.sh index de4713a1..5814529b 100755 --- a/scripts/publish-macosx.sh +++ b/scripts/publish-macosx.sh @@ -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 From 56866bc3d848412bf446abf9d5fdb807200a466a Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Wed, 5 Nov 2014 19:05:56 +0400 Subject: [PATCH 37/47] #1006 is a duplicate of #945 --- .../scad/bugs/{issue1006.scad => issue945.scad} | 0 tests/CMakeLists.txt | 4 ++-- ...issue1006-expected.png => issue945-expected.png} | Bin ...issue1006-expected.png => issue945-expected.png} | Bin ...issue1006-expected.png => issue945-expected.png} | Bin 5 files changed, 2 insertions(+), 2 deletions(-) rename testdata/scad/bugs/{issue1006.scad => issue945.scad} (100%) rename tests/regression/cgalpngtest/{issue1006-expected.png => issue945-expected.png} (100%) rename tests/regression/monotonepngtest/{issue1006-expected.png => issue945-expected.png} (100%) rename tests/regression/opencsgtest/{issue1006-expected.png => issue945-expected.png} (100%) diff --git a/testdata/scad/bugs/issue1006.scad b/testdata/scad/bugs/issue945.scad similarity index 100% rename from testdata/scad/bugs/issue1006.scad rename to testdata/scad/bugs/issue945.scad diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index c6042cb5..299c851a 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -1205,11 +1205,11 @@ list(APPEND BUGS_FILES ${CMAKE_SOURCE_DIR}/../testdata/scad/bugs/issue584.scad ${CMAKE_SOURCE_DIR}/../testdata/scad/bugs/issue911.scad ${CMAKE_SOURCE_DIR}/../testdata/scad/bugs/issue913.scad ${CMAKE_SOURCE_DIR}/../testdata/scad/bugs/issue936.scad + ${CMAKE_SOURCE_DIR}/../testdata/scad/bugs/issue945.scad ${CMAKE_SOURCE_DIR}/../testdata/scad/bugs/issue964.scad ${CMAKE_SOURCE_DIR}/../testdata/scad/bugs/issue964b.scad ${CMAKE_SOURCE_DIR}/../testdata/scad/bugs/issue990.scad - ${CMAKE_SOURCE_DIR}/../testdata/scad/bugs/issue1005.scad - ${CMAKE_SOURCE_DIR}/../testdata/scad/bugs/issue1006.scad) + ${CMAKE_SOURCE_DIR}/../testdata/scad/bugs/issue1005.scad) list(APPEND EXPORT3D_TEST_FILES ${BUGS_FILES}) list(APPEND OPENCSGTEST_FILES ${BUGS_FILES}) diff --git a/tests/regression/cgalpngtest/issue1006-expected.png b/tests/regression/cgalpngtest/issue945-expected.png similarity index 100% rename from tests/regression/cgalpngtest/issue1006-expected.png rename to tests/regression/cgalpngtest/issue945-expected.png diff --git a/tests/regression/monotonepngtest/issue1006-expected.png b/tests/regression/monotonepngtest/issue945-expected.png similarity index 100% rename from tests/regression/monotonepngtest/issue1006-expected.png rename to tests/regression/monotonepngtest/issue945-expected.png diff --git a/tests/regression/opencsgtest/issue1006-expected.png b/tests/regression/opencsgtest/issue945-expected.png similarity index 100% rename from tests/regression/opencsgtest/issue1006-expected.png rename to tests/regression/opencsgtest/issue945-expected.png From d74450eaadce0f1cebe7553f105b22eb1954db7a Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Wed, 5 Nov 2014 19:25:05 +0400 Subject: [PATCH 38/47] Allow pretty print of tests which fail with a non-zero return code --- tests/test_cmdline_tool.py | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/test_cmdline_tool.py b/tests/test_cmdline_tool.py index 45cd0b3b..d0e7fa2b 100755 --- a/tests/test_cmdline_tool.py +++ b/tests/test_cmdline_tool.py @@ -215,7 +215,6 @@ def run_test(testname, cmd, args): outfile.close() if proc.returncode != 0: print >> sys.stderr, "Error: %s failed with return code %d" % (cmdname, proc.returncode) - return None return outputname except OSError, err: From 4bc3d98509c8a4a706c4e6728d14c9a4121adb8f Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Wed, 5 Nov 2014 19:25:45 +0400 Subject: [PATCH 39/47] #1004 Added testcase --- testdata/scad/bugs/issue1004.scad | 2 ++ tests/CMakeLists.txt | 1 + .../cgalpngtest/issue1004-expected.png | Bin 0 -> 7079 bytes .../monotonepngtest/issue1004-expected.png | Bin 0 -> 7079 bytes .../opencsgtest/issue1004-expected.png | Bin 0 -> 8771 bytes 5 files changed, 3 insertions(+) create mode 100644 testdata/scad/bugs/issue1004.scad create mode 100644 tests/regression/cgalpngtest/issue1004-expected.png create mode 100644 tests/regression/monotonepngtest/issue1004-expected.png create mode 100644 tests/regression/opencsgtest/issue1004-expected.png diff --git a/testdata/scad/bugs/issue1004.scad b/testdata/scad/bugs/issue1004.scad new file mode 100644 index 00000000..c4118712 --- /dev/null +++ b/testdata/scad/bugs/issue1004.scad @@ -0,0 +1,2 @@ +%square(20); +cube(10); diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 299c851a..d72c3c97 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -1209,6 +1209,7 @@ list(APPEND BUGS_FILES ${CMAKE_SOURCE_DIR}/../testdata/scad/bugs/issue584.scad ${CMAKE_SOURCE_DIR}/../testdata/scad/bugs/issue964.scad ${CMAKE_SOURCE_DIR}/../testdata/scad/bugs/issue964b.scad ${CMAKE_SOURCE_DIR}/../testdata/scad/bugs/issue990.scad + ${CMAKE_SOURCE_DIR}/../testdata/scad/bugs/issue1004.scad ${CMAKE_SOURCE_DIR}/../testdata/scad/bugs/issue1005.scad) list(APPEND EXPORT3D_TEST_FILES ${BUGS_FILES}) diff --git a/tests/regression/cgalpngtest/issue1004-expected.png b/tests/regression/cgalpngtest/issue1004-expected.png new file mode 100644 index 0000000000000000000000000000000000000000..677d52ca8bc001554d27e59b4decd40abbad783a GIT binary patch literal 7079 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 XY6R=pD>nQC4zb(nxTRndBl^DpPSBy0 literal 0 HcmV?d00001 diff --git a/tests/regression/monotonepngtest/issue1004-expected.png b/tests/regression/monotonepngtest/issue1004-expected.png new file mode 100644 index 0000000000000000000000000000000000000000..677d52ca8bc001554d27e59b4decd40abbad783a GIT binary patch literal 7079 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 XY6R=pD>nQC4zb(nxTRndBl^DpPSBy0 literal 0 HcmV?d00001 diff --git a/tests/regression/opencsgtest/issue1004-expected.png b/tests/regression/opencsgtest/issue1004-expected.png new file mode 100644 index 0000000000000000000000000000000000000000..8b815e152dc9319f0ed6ae5ec2905dcf1a238a0c GIT binary patch literal 8771 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 literal 0 HcmV?d00001 From a3a6b66061faf6e4447c959f7a3de99f2e51e26f Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Wed, 5 Nov 2014 19:35:00 +0400 Subject: [PATCH 40/47] Ignore background nodes when checking for mixed 2D and 3D objects. Fixes #1004 --- src/GeometryEvaluator.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/GeometryEvaluator.cc b/src/GeometryEvaluator.cc index 7c26cfe8..5e82897f 100644 --- a/src/GeometryEvaluator.cc +++ b/src/GeometryEvaluator.cc @@ -80,7 +80,7 @@ GeometryEvaluator::ResultObject GeometryEvaluator::applyToChildren(const Abstrac { unsigned int dim = 0; BOOST_FOREACH(const Geometry::ChildItem &item, this->visitedchildren[node.index()]) { - if (item.second) { + if (!item.first->modinst->isBackground() && item.second) { if (!dim) dim = item.second->getDimension(); else if (dim != item.second->getDimension()) { PRINT("WARNING: Mixing 2D and 3D objects is not supported."); From 90f58ced7dd48c5df7be89a875c092e69f91e72d Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Wed, 5 Nov 2014 21:24:09 +0400 Subject: [PATCH 41/47] Allow preview of designs with only background or highlight objects. Fixes #1005 --- src/CsgInfo.h | 26 +++++----- src/OpenCSGRenderer.cc | 16 +++---- src/mainwin.cc | 105 ++++++++++++++++++++--------------------- 3 files changed, 74 insertions(+), 73 deletions(-) diff --git a/src/CsgInfo.h b/src/CsgInfo.h index bb054aea..c50ab4d4 100644 --- a/src/CsgInfo.h +++ b/src/CsgInfo.h @@ -43,8 +43,8 @@ public: CSGTermEvaluator evaluator(tree, &geomevaluator); boost::shared_ptr root_raw_term = evaluator.evaluateCSGTerm( *root_node, this->highlight_terms, this->background_terms ); - if (!root_raw_term) { - PRINT("Error: CSG generation failed! (no top level object found)"); + if (!root_raw_term && this->background_terms.empty()) { + PRINT("Error: CSG generation failed! (no objects found)"); call_progress_function(); return false; } @@ -52,16 +52,18 @@ public: PRINT("Compiling design (CSG Products normalization)..."); call_progress_function(); CSGTermNormalizer normalizer( normalizelimit ); - this->root_norm_term = normalizer.normalize(root_raw_term); - if (this->root_norm_term) { - this->root_chain = new CSGChain(); - this->root_chain->import(this->root_norm_term); - PRINTB("Normalized CSG tree has %d elements", int(this->root_chain->objects.size())); - } - else { - this->root_chain = NULL; - PRINT("WARNING: CSG normalization resulted in an empty tree"); - call_progress_function(); + if (root_raw_term) { + this->root_norm_term = normalizer.normalize(root_raw_term); + if (this->root_norm_term) { + this->root_chain = new CSGChain(); + this->root_chain->import(this->root_norm_term); + PRINTB("Normalized CSG tree has %d elements", int(this->root_chain->objects.size())); + } + else { + this->root_chain = NULL; + PRINT("WARNING: CSG normalization resulted in an empty tree"); + call_progress_function(); + } } if (this->highlight_terms.size() > 0) { diff --git a/src/OpenCSGRenderer.cc b/src/OpenCSGRenderer.cc index 4c41e059..3c6f0b48 100644 --- a/src/OpenCSGRenderer.cc +++ b/src/OpenCSGRenderer.cc @@ -58,16 +58,16 @@ OpenCSGRenderer::OpenCSGRenderer(CSGChain *root_chain, CSGChain *highlights_chai void OpenCSGRenderer::draw(bool /*showfaces*/, bool showedges) const { + GLint *shaderinfo = this->shaderinfo; + if (!shaderinfo[0]) shaderinfo = NULL; if (this->root_chain) { - GLint *shaderinfo = this->shaderinfo; - if (!shaderinfo[0]) shaderinfo = NULL; renderCSGChain(this->root_chain, showedges ? shaderinfo : NULL, false, false); - if (this->background_chain) { - renderCSGChain(this->background_chain, showedges ? shaderinfo : NULL, false, true); - } - if (this->highlights_chain) { - renderCSGChain(this->highlights_chain, showedges ? shaderinfo : NULL, true, false); - } + } + if (this->background_chain) { + renderCSGChain(this->background_chain, showedges ? shaderinfo : NULL, false, true); + } + if (this->highlights_chain) { + renderCSGChain(this->highlights_chain, showedges ? shaderinfo : NULL, true, false); } } diff --git a/src/mainwin.cc b/src/mainwin.cc index cd61ec8a..223e7727 100644 --- a/src/mainwin.cc +++ b/src/mainwin.cc @@ -1031,8 +1031,8 @@ void MainWindow::compileCSG(bool procevents) CSGTermEvaluator csgrenderer(this->tree, &geomevaluator); if (procevents) QApplication::processEvents(); this->root_raw_term = csgrenderer.evaluateCSGTerm(*root_node, highlight_terms, background_terms); - if (!root_raw_term) { - PRINT("ERROR: CSG generation failed! (no top level object found)"); + if (!root_raw_term && background_terms.empty()) { + PRINT("ERROR: CSG generation failed! (no objects found)"); } GeometryCache::instance()->print(); #ifdef ENABLE_CGAL @@ -1048,12 +1048,13 @@ void MainWindow::compileCSG(bool procevents) delete this->progresswidget; this->progresswidget = NULL; - if (root_raw_term) { - PRINT("Compiling design (CSG Products normalization)..."); - if (procevents) QApplication::processEvents(); + PRINT("Compiling design (CSG Products normalization)..."); + if (procevents) QApplication::processEvents(); - size_t normalizelimit = 2 * Preferences::inst()->getValue("advanced/openCSGLimit").toUInt(); - CSGTermNormalizer normalizer(normalizelimit); + size_t normalizelimit = 2 * Preferences::inst()->getValue("advanced/openCSGLimit").toUInt(); + CSGTermNormalizer normalizer(normalizelimit); + + if (root_raw_term) { this->root_norm_term = normalizer.normalize(this->root_raw_term); if (this->root_norm_term) { this->root_chain = new CSGChain(); @@ -1064,53 +1065,51 @@ void MainWindow::compileCSG(bool procevents) PRINT("WARNING: CSG normalization resulted in an empty tree"); if (procevents) QApplication::processEvents(); } - - if (highlight_terms.size() > 0) - { - PRINTB("Compiling highlights (%d CSG Trees)...", highlight_terms.size()); - if (procevents) QApplication::processEvents(); - - highlights_chain = new CSGChain(); - for (unsigned int i = 0; i < highlight_terms.size(); i++) { - highlight_terms[i] = normalizer.normalize(highlight_terms[i]); - highlights_chain->import(highlight_terms[i]); - } - } - - if (background_terms.size() > 0) - { - PRINTB("Compiling background (%d CSG Trees)...", background_terms.size()); - if (procevents) QApplication::processEvents(); - - background_chain = new CSGChain(); - for (unsigned int i = 0; i < background_terms.size(); i++) { - background_terms[i] = normalizer.normalize(background_terms[i]); - background_chain->import(background_terms[i]); - } - } - - if (this->root_chain && - (this->root_chain->objects.size() > - Preferences::inst()->getValue("advanced/openCSGLimit").toUInt())) { - PRINTB("WARNING: Normalized tree has %d elements!", this->root_chain->objects.size()); - PRINT("WARNING: OpenCSG rendering has been disabled."); - } - else { - PRINTB("Normalized CSG tree has %d elements", - (this->root_chain ? this->root_chain->objects.size() : 0)); - this->opencsgRenderer = new OpenCSGRenderer(this->root_chain, - this->highlights_chain, - this->background_chain, - this->qglview->shaderinfo); - } - this->thrownTogetherRenderer = new ThrownTogetherRenderer(this->root_chain, - this->highlights_chain, - this->background_chain); - PRINT("CSG generation finished."); - int s = t.elapsed() / 1000; - PRINTB("Total rendering time: %d hours, %d minutes, %d seconds", (s / (60*60)) % ((s / 60) % 60) % (s % 60)); - if (procevents) QApplication::processEvents(); } + + if (highlight_terms.size() > 0) { + PRINTB("Compiling highlights (%d CSG Trees)...", highlight_terms.size()); + if (procevents) QApplication::processEvents(); + + highlights_chain = new CSGChain(); + for (unsigned int i = 0; i < highlight_terms.size(); i++) { + highlight_terms[i] = normalizer.normalize(highlight_terms[i]); + highlights_chain->import(highlight_terms[i]); + } + } + + if (background_terms.size() > 0) { + PRINTB("Compiling background (%d CSG Trees)...", background_terms.size()); + if (procevents) QApplication::processEvents(); + + background_chain = new CSGChain(); + for (unsigned int i = 0; i < background_terms.size(); i++) { + background_terms[i] = normalizer.normalize(background_terms[i]); + background_chain->import(background_terms[i]); + } + } + + if (this->root_chain && + (this->root_chain->objects.size() > + Preferences::inst()->getValue("advanced/openCSGLimit").toUInt())) { + PRINTB("WARNING: Normalized tree has %d elements!", this->root_chain->objects.size()); + PRINT("WARNING: OpenCSG rendering has been disabled."); + } + else { + PRINTB("Normalized CSG tree has %d elements", + (this->root_chain ? this->root_chain->objects.size() : 0)); + this->opencsgRenderer = new OpenCSGRenderer(this->root_chain, + this->highlights_chain, + this->background_chain, + this->qglview->shaderinfo); + } + this->thrownTogetherRenderer = new ThrownTogetherRenderer(this->root_chain, + this->highlights_chain, + this->background_chain); + PRINT("CSG generation finished."); + int s = t.elapsed() / 1000; + PRINTB("Total rendering time: %d hours, %d minutes, %d seconds", (s / (60*60)) % ((s / 60) % 60) % (s % 60)); + if (procevents) QApplication::processEvents(); } void MainWindow::actionUpdateCheck() From 28d7d5450211a1f231d5f32edc4a4b93035ab0d0 Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Thu, 6 Nov 2014 08:14:04 +0100 Subject: [PATCH 42/47] Issue warning if trying to export previous F6 state. Fixes #48 --- src/MainWindow.h | 2 ++ src/mainwin.cc | 25 +++++++++++++++++++++++-- 2 files changed, 25 insertions(+), 2 deletions(-) diff --git a/src/MainWindow.h b/src/MainWindow.h index 4506a3d3..d6cb7bb7 100644 --- a/src/MainWindow.h +++ b/src/MainWindow.h @@ -234,6 +234,7 @@ public slots: void checkAutoReload(); void waitAfterReload(); void autoReloadSet(bool); + void setContentsChanged(); private: static void report_func(const class AbstractNode*, void *vp, int mark); @@ -248,6 +249,7 @@ private: class ProgressWidget *progresswidget; class CGALWorker *cgalworker; QMutex consolemutex; + bool contentschanged; // Set if the source code has changes since the last render (F6) signals: void highlightError(int); diff --git a/src/mainwin.cc b/src/mainwin.cc index 715be8cb..a9099946 100644 --- a/src/mainwin.cc +++ b/src/mainwin.cc @@ -175,7 +175,7 @@ bool MainWindow::undockMode = false; bool MainWindow::reorderMode = false; MainWindow::MainWindow(const QString &filename) - : root_inst("group"), library_info_dialog(NULL), font_list_dialog(NULL), tempFile(NULL), progresswidget(NULL) + : root_inst("group"), library_info_dialog(NULL), font_list_dialog(NULL), tempFile(NULL), progresswidget(NULL), contentschanged(false) { setupUi(this); @@ -421,6 +421,7 @@ MainWindow::MainWindow(const QString &filename) updateRecentFileActions(); connect(editor, SIGNAL(contentsChanged()), this, SLOT(animateUpdateDocChanged())); + connect(editor, SIGNAL(contentsChanged()), this, SLOT(setContentsChanged())); connect(editor, SIGNAL(modificationChanged(bool)), this, SLOT(setWindowModified(bool))); connect(this->qglview, SIGNAL(doAnimateUpdate()), this, SLOT(animateUpdate())); @@ -847,8 +848,10 @@ void MainWindow::refreshDocument() reader.setCodec("UTF-8"); QString text = reader.readAll(); PRINTB("Loaded design '%s'.", this->fileName.toLocal8Bit().constData()); - if (editor->toPlainText() != text) + if (editor->toPlainText() != text) { editor->setPlainText(text); + this->contentschanged = true; + } } } setCurrentOutput(); @@ -1822,6 +1825,7 @@ void MainWindow::actionRenderDone(shared_ptr root_geom) this->statusBar()->removeWidget(this->progresswidget); delete this->progresswidget; this->progresswidget = NULL; + this->contentschanged = false; compileEnded(); } @@ -1928,6 +1932,18 @@ void MainWindow::actionExport(export_type_e, QString, QString) return; } + // editor has changed since last F6 + if (this->contentschanged) { + QMessageBox::StandardButton ret; + ret = QMessageBox::warning(this, "Application", + "The document has been modified since the last render (F6).\n" + "Do you really want to export the previous content?", + QMessageBox::Yes | QMessageBox::No); + if (ret != QMessageBox::Yes) { + return; + } + } + if (this->root_geom->getDimension() != 3) { PRINT("Current top level object is not a 3D object."); clearCurrentOutput(); @@ -2554,3 +2570,8 @@ void MainWindow::openCSGSettingsChanged() OpenCSG::Goldfeather : OpenCSG::Automatic); #endif } + +void MainWindow::setContentsChanged() +{ + this->contentschanged = true; +} From aba7ba76655dde42e66501492db8fecd82c052e1 Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Fri, 7 Nov 2014 09:37:25 -0500 Subject: [PATCH 43/47] #584 updated test results --- .../monotonepngtest/issue584-expected.png | Bin 0 -> 7243 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 tests/regression/monotonepngtest/issue584-expected.png diff --git a/tests/regression/monotonepngtest/issue584-expected.png b/tests/regression/monotonepngtest/issue584-expected.png new file mode 100644 index 0000000000000000000000000000000000000000..b191b942f6bb2e13deaaabc8e2eb9ba28b2e83d1 GIT binary patch literal 7243 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 O5ZSMEv?*B5j` Date: Fri, 7 Nov 2014 09:54:01 -0500 Subject: [PATCH 44/47] #791 Added testcase --- testdata/scad/bugs/issue791.scad | 10 ++++++++++ tests/CMakeLists.txt | 1 + .../regression/cgalpngtest/issue791-expected.png | Bin 0 -> 6146 bytes .../monotonepngtest/issue791-expected.png | Bin 0 -> 6146 bytes .../regression/opencsgtest/issue791-expected.png | Bin 0 -> 6193 bytes 5 files changed, 11 insertions(+) create mode 100644 testdata/scad/bugs/issue791.scad create mode 100644 tests/regression/cgalpngtest/issue791-expected.png create mode 100644 tests/regression/monotonepngtest/issue791-expected.png create mode 100644 tests/regression/opencsgtest/issue791-expected.png diff --git a/testdata/scad/bugs/issue791.scad b/testdata/scad/bugs/issue791.scad new file mode 100644 index 00000000..f6605c43 --- /dev/null +++ b/testdata/scad/bugs/issue791.scad @@ -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); +} diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index d72c3c97..a165c87a 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -1198,6 +1198,7 @@ set_test_config(Heavy cgalpngtest_rotate_extrude-tests list(APPEND BUGS_FILES ${CMAKE_SOURCE_DIR}/../testdata/scad/bugs/issue584.scad ${CMAKE_SOURCE_DIR}/../testdata/scad/bugs/issue591.scad ${CMAKE_SOURCE_DIR}/../testdata/scad/bugs/issue666.scad + ${CMAKE_SOURCE_DIR}/../testdata/scad/bugs/issue791.scad ${CMAKE_SOURCE_DIR}/../testdata/scad/bugs/issue802.scad ${CMAKE_SOURCE_DIR}/../testdata/scad/bugs/issue835.scad ${CMAKE_SOURCE_DIR}/../testdata/scad/bugs/issue899.scad diff --git a/tests/regression/cgalpngtest/issue791-expected.png b/tests/regression/cgalpngtest/issue791-expected.png new file mode 100644 index 0000000000000000000000000000000000000000..9a16fecb36d9ec943a431e6756dc6baa8983091c GIT binary patch literal 6146 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 M>|AVbZDbt&7pCEb8UO$Q literal 0 HcmV?d00001 From 877c010269a47589e6388bbc64b4526a69d3443f Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Fri, 7 Nov 2014 10:03:15 -0500 Subject: [PATCH 45/47] #802 Updated test results --- .../cgalpngtest/issue802-expected.png | Bin 7279 -> 7779 bytes .../monotonepngtest/issue802-expected.png | Bin 0 -> 7779 bytes .../opencsgtest/issue802-expected.png | Bin 7279 -> 7779 bytes 3 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 tests/regression/monotonepngtest/issue802-expected.png diff --git a/tests/regression/cgalpngtest/issue802-expected.png b/tests/regression/cgalpngtest/issue802-expected.png index 4d1ceb8c765ee3cd70a4d3555c3a5e101cd70c6c..a4e7fb30441fd06e2ce05fba181f92652609d4ce 100644 GIT binary patch literal 7779 zcmeHM`9E9f_kVJ8k=Q4Spsln`=?5*URBcIX+Da+9*;UMFbw&q8i7g4*nwDZv-7J~z zJGE3P5;bkAinPX3TWF|#7qKPzT%YeB@cjq+Q_kx-=RVK5=Q;PB^M2>DtMfr6d2M+B zfD*;w=c52XhzJ49+E1*u{c`{|8c=@Tdz^-v=&5cdy1U6yW4WeYkyokV7DV#Cr(&Jl zO?$R(B77x5C@%$K@%}iE4*@?Di;A~wCYEYI6Ng|2@~fTS>o6f_bNZXIA3orZPL7V+ zwYHw0j9yQB@^q{%b}D=_mw%jHXd7b3kkso)Hj$YiAqMh$TpnPkws5XX){W|EJf zP_CuZIft15g`%pc63DDaOt8(1)_|BXL6ICrmEd}u4AyP0I;BP+lR*a>#;9&HAb=|x zy~S8n0s)MpAQ-bwT@~zC2>FUARlx#4mafQSn0GFgpGA}y5Q}UN?U#YcpWk|0AWE2N zyXM6m2x6V--+miWLY$31-1!lmAG!16%lc7wepKbPCegc(OdW#QvyN=boBe#LfbHBw zqcAy2(Epm6Qk~+aqN|*9B9f$Xwy)zKEyxjuIk>IuHV3E_5h?$sjitr8OB@Oc6`J|3 zUQVIAZP~@yYh!M}xlFQ}DtJ{p3A>F;xItNRT)n1jq#NehB9}=gQxYg$~5U4{w*iTm|y(DYU|@D_FR&C^4Mypr-=VrsM}7) zufJ`nwoVo7<@lAHf|d1=0MvBj9)KcUI+9j>s!@7O4f$E#FIKNNpWu<1yx zEHNg6FwObzX(Z1DJV+k$#+P2V-&mTYfz_Pri;^y~m8W>MGrf{=#$U(rKE$xvZ3J-O z$}Tx~bMZ{`;#`BZ77%1?!ge-j$WHJlmZ-F`AwRpVid-*gUr{-uA*uRAfcxA};Ee%y zq`v#Ez@_F(97xqnr|_B-{dvmoZ5B)1b+=t@AF_22$w{L}1C815=E|jgj1#-2j!*ic ziny76tutMahQyR{`mqAKZ(2FopV#EFQMvPGRW$FEi1f_YT0>SX}m#^Am2t}M9DJXu9<;*&)*Yb9OAi$+k?*mwW66S(j(yBzVddM`-z zoB0J-YN(IAeD@ZW2{L{k=j7L%uFxH9-d2;zEuKU_{j1$ZBQ@;3ZOU%h@( zq@8Ar6WDQyq1Ul4rDUBa@Y&G?JwP^1b zfcFe`PV86as>sFCcMg}Wq_>`x%j|O%yx?9&levCDfdMMa&zo+*6Lwi99p1R(!;)Xk zlhOVrC{NL;V(|L!krgw^yA3UeL8{?Z{k?Bmd*8CCB3*?}Wn%5$@4dLODoh*7res0)}Z@ZqB^yErF|tShM#AQ zag9E_D3Ge)XNc`oDql-P#y#O$M2JX4E?vh$RF77oY{aV0mH1$XzX1L^`xl&|X#E^j zsE=gfv(D87lN+KvqTpKquQ5Flwfekm=upM*DwmWi6SwrCZ1_O6Pw9{ePaM*5DzndE z7b;ZU{XvTH{PNBF|E45ddKrT&ja7D$Ew|MemY7*b)O%-AFJ}UeJEfwa;3?spVHP}R z=U&q_OQql=+Lm>`Tq#)bqe#AmQB0Eb!0FJ1#kT4g@v4`j-rg-0++S-6@jDbFq)U1D zICs1gkm0}q2aR=G#)eSD+N$Q~Q<5g#szs^$n52B!*VY-Q7y$K+J`Ybv#f}T-#>)zWgWEEU&*pUxI)P6h9iQ>3wI(_6s7VB~M6#7o&+&CrU&WdjE z#4QQ|D2q5Bxz)nu=#3PUsqmIJ6W%gxk^YhdN{T?bf#v;7GFYD@c`xv~D%qS#eC-e+ zmZ@{eo+K$AEtgO{4TuTg#yas^$7%`0>+ial#WL*{pzmyw?Q9g?gl*4D3&b}A1t%p9 zY{|o!*Cl9F=qpx?*z;BpKLc*R;#)~irtpG9x{jYuDPowK!qzdaFP)pzY09Ho)AfdH zR?^wVRw)T#C{}yA_mV%7e02rSQb=~HrCq_&k&H=puz7h^R}Gp)S-&eKNa_+ABhIlN z$tgVV+UIGm|09b>|cvC*!KJ zy~bWrGvSHeS}xSX7;)|uorkD=p{X@xI!xtRCd@VEO~%{fh9y0#NVV(9E*4#MNW892 zry)zWVrMmAd!ppM7qRxKm0Vrl0DA8mQAJ>4KGFfd_cO*;4$apW`qJA)_40h0J#Zpd zecD36o^1U+iO3WC`9}$#g5f8*>Y7_*m7mZb5*NiJ@pxa#J<@!j^yLMJdM`A?hm5n? z-q+|KI(heR#!9+WJU7LV%%=>*-e1vea{}vsx18L!W+E7+WQY>TB1WZooC@_@|0x$J zv+p;~!hAv=j!q6vR^K&BJ5kJgUWK2pU6ylZ+0c2z;K8B)%9`De3 z+c#iVn~wyXWUz8wALi`Q8hWFV0UsQ!w!jwu!<=LsA8kjLgA@*`%Mfdiv?mEDBMK(9$_r3$f8+k5=a|%T<3EHJAn@lPCIJB=)de+>T{U6}`#?rA*9#N%~?M1G)MBQ@b0kCuw zC_(ND4vC({H;I4RAZM41hKI;A_iUK@>GcsZ?$g`tl*F0vzat;soKkO&lKQQ*7QX7A zq7TWHv^++hf8-r&$VcwT=ct{Qtb#5k?TwT-lg@siXle0VAk3j?=wqL4Ct!D6Zql!v zLD%xc&F5DIg?i{Tq-`PN7(A&*kk#Nd5o`SwtHfo23c(8lIIZamb!waob&ik@)*!E>%?cElBe^5viW+o4kUGqwvcYZzbdYFx98jXMHWO}Q^Y@pIS&0yjy-aD zJ0*2Q{6_13(qgQYtbycVS}fFH4)Sm*f(+n!4JcVa~U_!F`a5CQ>1?Sr=>5 zN#bw6C?0PDsL;ksVcQe(Fb;`9@-yyy>1vAcNrv|P@^I_nkEfY{RwlE0h;Wxl^l&Q^ zkrto%E(!~4Bq3ZqQ&%%&*Ww9*0TipDiayw?WhMDM(yo8W#4UtE^0ahel7C4EiJKoBus)R7 zYAv}}BNZ>Xkd{Qoy?MD4%lE->WtGN3LO8Dbji9{evlV^Nb~7+==XV-n100|Y48ex~ z01H{sAjZavx|>q8_f1IKJ83G3-34>1(xb5RhDFi1;luKSTC7BN~A>qjo|_djkCr zeZVK>b7PRD*v|D3>*4QS3JF4)Ug>0c8++uj_42vAV+JByeK0vTHVJ=0ruW6x8gzH$ z1K=R)YPo=YX5{)xP&j^LIuauIe|EY_b|Q1rmxN|sVE&k+;igb$GMA)(Y_$q(t3esD z?GqY1<4fl9y8hL10QYtj)T_}pu>@Um?GJG@`px#j|*u8~c)mVANEw3DSTx)5>7-{fkG>=tG zpM;>klf{#c)Xgk`3%M!|!4WhX)`{hf+CXyrEl7fKeVPV76z^{|OJJrIupA!H5K2(l zWIgWnQ8Jf}`!u+Mz>}3H$zR7kse(xUw$*1%`67F{a5b=D-Dlk7R+fP8*cLC^L;wp% zWvH6K6gr^4vo@&k&D2yx?=2kA3&8CC0ee%o~ zktOeZRBtFT{m1cWD~Zgf+z`#F#jHD6CW69z6^t;{s_mjtQ#<2Pp_*>Hw@z~>Lvx4T zh?|+h$*qvlyG`}A>ZYPe{G!bK&GMFmdES~8t9n#tG-{B z3}nbdGOwx>AbZ8qlqNLIpBG2G(u_<5crtLytF1gWr7c0d*%@C zo9s#kFiJ@uk=#(IjIyxr2t}U2Vj?uYwlg9qmKSRooQNn`u*#Mi&?Tt R$e+i6vfugV7yGD*{{^R2s}%qM literal 7279 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 M*&p6t^*cH7Kj;XD6#xJL diff --git a/tests/regression/monotonepngtest/issue802-expected.png b/tests/regression/monotonepngtest/issue802-expected.png new file mode 100644 index 0000000000000000000000000000000000000000..a4e7fb30441fd06e2ce05fba181f92652609d4ce GIT binary patch literal 7779 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 R$e+i6vfugV7yGD*{{^R2s}%qM literal 0 HcmV?d00001 diff --git a/tests/regression/opencsgtest/issue802-expected.png b/tests/regression/opencsgtest/issue802-expected.png index 4d1ceb8c765ee3cd70a4d3555c3a5e101cd70c6c..a4e7fb30441fd06e2ce05fba181f92652609d4ce 100644 GIT binary patch literal 7779 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 R$e+i6vfugV7yGD*{{^R2s}%qM literal 7279 zcmeHM`9G9v|G(xo%t(x-kjl)lmUXI=oGddP2~m`_$PD$MvbAU|nHiicInhHRSw<># ztc57cjC4{YBg%v^(qbnXMl)vSxzF?c{`~z1zJ9vjulsdhpY6J?&+@+0+zvY^uG3lv z08n&t+S+46VlSxn1s3`cuUW4q3P(7TP48q>; zsg@=_ecP#NgY?uF^;dQ7srtCB^EO=K%zS zEJCA!hz=urStPOdrSWYTLM&|@kxo26!G^Hr$MVWJ9GHO@ zqc?0+2KJk)Lt%&pacg4MVzYK`)-Jus+!RyA>2*_d^W3xwo=yQEqvJ^ ziMgN4--%RLZIrGo2-IVZBkXX6M1mM&oQ+B`(EgZD2b|*$em%Cx#9mq*h>5)MchdAa zG(Ae(A~KUTE0m}morQh~2ZDQHE$omRt`lQ!e6T_OXy)@4HfXI-sfBO)@3tO-0bu(v$nL@qw z2XL*{MmUi1IJ)K;tEx=;Am%w4Io9P*1pEz3XloVD%tXY%2U|Y#vD5R>gRE1o8sN3o z@$!NJTk*dG+U98spFXz@V5R-ON!12h!!HR*1YsuZQ^w=|7&p*A8I^U=!H(wfewrld z*(3cH%v{Wo3X7%UBfeVS+9uw#M?bI-JK$iIM?X0u+)BEds&{A$E1N9@A{}4A@0ev= zX~WR?D^{5!KOg4$qZdbONt_9(y5N9xj-a>KT3s&1U^`X?Y#++M`yhG_lOm}ZJp%a7 zrt*X5G~~ERgrD!S37C_$rOXpUMt#ioNvYZT*sGUO5RT+3IB~?9?;BS3jY?X62qs)7 zvKXTCc_`YB#%mL<{tIMUNd1v?2M=pC>cDJM9&p(71~{?Mc}PtHpqoNjQ8o6 zw1#VjM)D~k7_4o(XwX-p`z2V*%0?Afh503SWu#Eczu$SvOZVFV#I?yzZ0%5r9QWN~ zOilVEuc=^R`zGo3$d;LKp&*=_0NW9| z3fr+Dr~kA$dZIz6x>(fGpMzjC4_l?SGYZ*rn4mXFEw0jEPFShS>0Vc)ZU+{e8+y5Q zU)b2JZcQNW(ms^n5|H%BQ>`t_~1t5OR>S ze*|dOnU{^X1v${l16NM)v_Iv`1VmmNnd#XGYO}pAx4loHW>Whmc}!<3bQZ%ZEKvJK zzQm3QJLEI%11j{3KgBof62x`?4KZjPmm*JV)|IXHj!Rp_Ei-)VRQ<^SJalXZ_D3@+ zYtP^)8{1i>3dFJnhY~M+n|RBxS-eHyeUM%WT+WP-Ev`jnjhgf}8=~nkHVsQ>ibaJO z>4#uulz4aHR^hB^(CUt&vu4p;Fj0N^pz1}#%ti7N-shZ95c}V-4Uah^A{E~6Ce)YDdH*b%|uk#m9pW*e+3ELOFyZ2kQDn@>$S-}p4km0gjo!X?_&j;(KWa3CmP z_+@&t_zZ393Dvq19^su*B7pTaSo2eMhyMnI)6LuDp9L?)M8fJN{Q0H-?uFk46HwJV z#JPY%u&ZWHG8ZwW)0<^kA4_;et+`Kmp2BZDs%WIt`+#S}YM1FBZLRmEH6>Z(2j@~w zA|g?Bm9}5~K;1OeTt>TPad4VP@O+t(EXhuzO?fBih1?_2f@^q_gqdb|*IfwepszBc z;A4Epk`j+(vv_=faM20y=RX*>nSG=Fx**CrfZCnKFn;#6&AwPAEK-Oe@Uc0@WmS<8PVA}1cGUj(rE~w>js|1q zd7+@b;h*zv8D#7SwV! z5-Xm_qzqhch)Ybt%t<8?)S9>}>TZgPtaA zY}V+dKAKMi%|t$S9fIxt2g+53K{##cFG7iu7Fe?y7U#dOHaDFHp%=%B&%F4tv+V8Q z;AijTwr5T?-}&=#hH_e0GU-C`C|NF{@S3RoDrIHT&3H_RNu>(**m43HE&b1nl`40O zeec<7ok2s4Usj?h30&7z_j?1*iOcbc$&XH{R#=Kt!sfF^4XHDqK12+sXxQ{U%B0`l z7bHYajJju}+d>De7J9<}kZGvx;k=Tki0BWRehJYZo+u*g_A#fA+?KQly?25rpuN?~ zR>zGpmWf}Eab;g^9765qD(;IDMo5LIy=j}W$z6TSjlSckpGaaugR$6V%c+;*pOwl` z5lt8y9I7X8VJr5fO${Sf&>@2n9WGeJp>obK4fM=%Uy0Y}dsyWqtYZE6$fqI}pGhWh zB_0TTw-0c+@E7%_9-2a*#4c9UYyB zcIX5MeX`rkq?!olJg#z`zhpA^uw>Kz^r%?=4+&S~C81a%YB(c54j`3~Q~GUJcaVkH z8D<!(>tp+0{0sQcI0eGjjwmCPGnNK!M{%cB3!ZJhju4w^0Glf^&{x@a z`fU{LmJ7eiogy|2$P$0@egO2Ab$SOAy@oYf`C{04^2#h?6Pu{L<;jRH678W8{qtHJ zm$V(HZQTfyC@TS?X{xBLqikdR&mQXBWB`};Oy!(?UJ)q+fC1cQOGQ$P{@^ zKa*yVRvqa1Ou*@hu=GAi_Dn#k(L9-^txo|b(A!Tf!4#dh;ydyDQ1w1Ad}AP8jgw7J zW0r+?pR0t(O7_+J$i=W^Tam?(rvm-swie}tS%tinq50k{?`_~_|FS>wraFGXHBF?# zFwg~u!!Vg@oO`f@t|yfjdm*xZbc8e60HH=Rcy-lW7Z_bS(cPpG&F{>So-K@$DpYVq z!P|-8)a2d0SLH7+s+mV^bcJKc_j@S?eGPmzHVM;b<8P1l;N09<3?7vy%UX{6vQFMbbtS3CI{)HGh2gEm+Vf`OK!|+$+`I!h z6Ot2aH(grJmt`H(F;wQ{vAQCLo4PU3t;NmL{BCmxFkHadtei(;{EH}x8qmZ~jL*Na zB^?1XwGmbMM74=P#?}HyC~3qZO?H(>Jc%twqLm$uN2PN4PwLm{!qg4i><9kuTO4@z z#47;)AQdJCXHMq8BkgGz4Sq2C6NZoIAT_>16-UHX(t+d9@hd7YR96O%GCg4~@GeXX zp7t%r!|(+J;g%mAq=SSy7=@kPcmRg~GbO+@;&m?~xEoga93~f);b{U+S1_yi4jyaj zDm^t}7>Gb9i+uE9%Z?)u*Vl|(i{#pwwDnrMIBO|rEl>Xct2nC!gGtj(Mbudg{38)K M*&p6t^*cH7Kj;XD6#xJL From 03ac045802ee81af1c05f51c06553253c9794d30 Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Fri, 7 Nov 2014 10:56:58 -0500 Subject: [PATCH 46/47] #802 Slimmed down testcase --- testdata/scad/bugs/issue802.scad | 121 +++++++++++++------------------ 1 file changed, 51 insertions(+), 70 deletions(-) diff --git a/testdata/scad/bugs/issue802.scad b/testdata/scad/bugs/issue802.scad index e82e85b5..b7d0eba6 100644 --- a/testdata/scad/bugs/issue802.scad +++ b/testdata/scad/bugs/issue802.scad @@ -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] , ]); -} From 4ef9f3e817da5a5d494a77cceda1904d22d4361d Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Sat, 8 Nov 2014 19:45:02 -0500 Subject: [PATCH 47/47] Bumped QScintilla to 2.8.4 --- scripts/macosx-build-dependencies.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/macosx-build-dependencies.sh b/scripts/macosx-build-dependencies.sh index 0d46f60b..e91123cc 100755 --- a/scripts/macosx-build-dependencies.sh +++ b/scripts/macosx-build-dependencies.sh @@ -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