summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarius Kintel <marius@kintel.net>2011-12-19 14:41:11 (GMT)
committerMarius Kintel <marius@kintel.net>2011-12-19 14:41:11 (GMT)
commit87ce149df2581361e8975bd1a0addf2b6ef61e3d (patch)
treec68db815a72cc767b6d51be0a57e9946c5f0a619
parentba1f0b7489dd5fa9bdc8c44068040f13113b40d0 (diff)
parent638743e2201c6869b48857dd2db5ec01df665162 (diff)
Merge branch 'master' into boost_filesystem
Conflicts: boost.pri tests/CMakeLists.txt
-rw-r--r--README2
-rw-r--r--RELEASE_NOTES16
-rw-r--r--bison.pri46
-rw-r--r--boost.pri44
-rw-r--r--cgal.pri21
-rw-r--r--common.pri13
-rw-r--r--contrib/OpenSCAD.xml36
-rw-r--r--doc/TODO.txt7
-rw-r--r--doc/release-checklist.txt18
-rw-r--r--doc/testing.txt76
-rw-r--r--eigen2.pri38
-rw-r--r--flex.pri30
-rw-r--r--glew.pri21
-rw-r--r--mingw-cross-env.pri13
-rw-r--r--opencsg.pri20
-rw-r--r--openscad.pro141
-rwxr-xr-xscripts/macosx-build-dependencies.sh2
-rwxr-xr-xscripts/publish-macosx.sh4
-rwxr-xr-xscripts/release-linux.sh2
-rw-r--r--setenv_mjau.sh2
-rw-r--r--src/CGALEvaluator.cc22
-rw-r--r--src/CGALRenderer.cc5
-rw-r--r--src/CGAL_Nef_polyhedron.cc15
-rw-r--r--src/GLView.h5
-rw-r--r--src/MainWindow.h3
-rw-r--r--src/MainWindow.ui6
-rw-r--r--src/OpenCSGRenderer.cc35
-rw-r--r--src/OpenCSGWarningDialog.cc23
-rw-r--r--src/OpenCSGWarningDialog.h16
-rw-r--r--src/OpenCSGWarningDialog.ui93
-rw-r--r--src/PolySetCGALEvaluator.cc9
-rw-r--r--src/Preferences.cc108
-rw-r--r--src/Preferences.h17
-rw-r--r--src/Preferences.ui18
-rw-r--r--src/ThrownTogetherRenderer.cc57
-rw-r--r--src/cgaladv_convexhull2.cc54
-rw-r--r--src/glview.cc147
-rw-r--r--src/lexer.l58
-rw-r--r--src/mainwin.cc17
-rw-r--r--src/polyset.cc57
-rw-r--r--src/polyset.h12
-rw-r--r--src/primitives.cc2
-rw-r--r--src/renderer.cc66
-rw-r--r--src/renderer.h21
-rw-r--r--src/rendersettings.cc35
-rw-r--r--src/rendersettings.h35
-rw-r--r--testdata/scad/features/hull2-tests.scad9
-rw-r--r--tests/CMakeLists.txt173
-rw-r--r--tests/FindBoost.cmake872
-rw-r--r--tests/FindGLEW.cmake9
-rw-r--r--tests/OffscreenContext.h2
-rw-r--r--tests/OffscreenContext.mm28
-rw-r--r--tests/OffscreenContextGLX.cc (renamed from tests/OffscreenContext.cc)63
-rw-r--r--tests/OffscreenContextWGL.cc58
-rw-r--r--tests/OffscreenView.cc137
-rw-r--r--tests/OffscreenView.h4
-rw-r--r--tests/csgtestcore.cc202
-rw-r--r--tests/fbo.cc21
-rw-r--r--tests/regression/cgalpngtest/hull2-tests-expected.pngbin7531 -> 7121 bytes
-rw-r--r--tests/regression/dumptest/hull2-tests-expected.txt24
-rw-r--r--tests/regression/opencsgtest/color-tests-expected.pngbin11055 -> 10950 bytes
-rw-r--r--tests/regression/opencsgtest/hull2-tests-expected.pngbin8078 -> 7924 bytes
-rw-r--r--tests/regression/opencsgtest/sphere-tests-expected.pngbin18276 -> 18173 bytes
-rw-r--r--tests/regression/opencsgtest/testcolornames-expected.pngbin20822 -> 24453 bytes
-rw-r--r--tests/regression/throwntogethertest/color-tests-expected.pngbin9139 -> 10215 bytes
-rw-r--r--tests/regression/throwntogethertest/hull2-tests-expected.pngbin4151 -> 7924 bytes
-rw-r--r--tests/regression/throwntogethertest/sphere-tests-expected.pngbin13794 -> 18173 bytes
-rw-r--r--tests/system-gl.cc39
-rw-r--r--tests/system-gl.h3
-rwxr-xr-xtests/test_cmdline_tool.py59
-rwxr-xr-xtests/test_pretty_print.py503
-rw-r--r--tests/yee_compare.cpp681
-rw-r--r--tests/yee_compare.h126
-rw-r--r--version.pri3
-rw-r--r--win32.pri20
75 files changed, 2629 insertions, 1895 deletions
diff --git a/README b/README
index a818bf3..8c000fa 100644
--- a/README
+++ b/README
@@ -35,7 +35,7 @@ numbers in brackets specify the versions which have been used for
development. Other versions may or may not work as well..
* Qt4 (4.4 - 4.7):
- http://www.qtsoftware.com/
+ http://www.qt.nokia.com/
* CGAL (3.6 - 3.9):
http://www.cgal.org/
diff --git a/RELEASE_NOTES b/RELEASE_NOTES
index 2681482..ac89511 100644
--- a/RELEASE_NOTES
+++ b/RELEASE_NOTES
@@ -1,23 +1,24 @@
-OpenSCAD 20xx.yy
+OpenSCAD 2011.12
================
Features:
o The MCAD library is now bundled with OpenSCAD
+o Added len() function. Takes one vector or string parameter and returns its length.
+o The index operator [] now works on strings
+o The version() function will return the OpenSCAD version as a vector, e.g. [2011, 09]
+o The version_num() function will return the OpenSCAD version as a number, e.g. 20110923
o hull() Now supports 3D objects
-o Added import and export of the OFF file format
+o hull() with 2D object can now use for loops and boolean operations as children
o New import() statement reads the correct file format based on the filename extension
(.stl, .dxf and .off is supported)
o The color() statement now supports an alpha parameter, e.g. color(c=[1,0,0], alpha=0.4)
o The color() statement now supports specifying colors as strings, e.g. color("Red")
o if()/else() and the ternary operator can now take any value type as parameter. false, 0, empty string and empty vector or illegal value type will evaluate as false, everything else as true.
o Strings can now be lexographically compared using the <, <=, >, >= operators
-o The version() function will return the OpenSCAD version as a vector, e.g. [2011, 09]
-o The version_num() function will return the OpenSCAD version as a number, e.g. 20110923
o Added PI constant.
-o Now uses standard shortcuts for save, reload and quit on Linux and Windows. F2/F3 will still work but is deprecated.
o Number literals in scientific notation are now accepted by the parser
-o Added len() function. Takes one vector or string parameter and returns its length.
-o The index operator [] now works on strings
+o Added import and export of the OFF file format
+o Now uses standard shortcuts for save, reload and quit on Linux and Windows. F2/F3 will still work but is deprecated.
Bugfixes:
o square() crashed if any of the dimensions were zero
@@ -27,6 +28,7 @@ o Dropping a file into the editor under Windows didn't work (double C:/C:/ probl
o On some platforms it was possible to insertion rich text in the editor, causing confusion.
o Less crashes due to CGAL assertions
o OpenCSG should now work on systems with OpenGL 1.x, given that the right extensions are available
+o include now searches librarydir
Deprecations:
o dxf_linear_extrude() and dxf_rotate_extrude() are now deprecated.
diff --git a/bison.pri b/bison.pri
index 003e09b..7d3bed0 100644
--- a/bison.pri
+++ b/bison.pri
@@ -1,17 +1,29 @@
-#setup bison for qmake
-bison.name = Bison ${QMAKE_FILE_IN}
-bison.input = BISONSOURCES
-bison.output = ${QMAKE_FILE_PATH}/${QMAKE_FILE_BASE}_yacc.cpp
-bison.commands = bison -d -p ${QMAKE_FILE_BASE} -o ${QMAKE_FILE_PATH}/${QMAKE_FILE_BASE}_yacc.cpp ${QMAKE_FILE_IN}
-bison.commands += && mv ${QMAKE_FILE_PATH}/${QMAKE_FILE_BASE}_yacc.hpp ${QMAKE_FILE_PATH}/${QMAKE_FILE_BASE}_yacc.h
-bison.CONFIG += target_predeps
-bison.variable_out = GENERATED_SOURCES
-silent:bison.commands = @echo Bison ${QMAKE_FILE_IN} && $$bison.commands
-QMAKE_EXTRA_COMPILERS += bison
-bison_header.input = BISONSOURCES
-bison_header.output = ${QMAKE_FILE_PATH}/${QMAKE_FILE_BASE}_yacc.h
-bison_header.commands = bison -d -p ${QMAKE_FILE_BASE} -o ${QMAKE_FILE_PATH}/${QMAKE_FILE_BASE}_yacc.cpp ${QMAKE_FILE_IN}
-bison_header.commands += && mv ${QMAKE_FILE_PATH}/${QMAKE_FILE_BASE}_yacc.hpp ${QMAKE_FILE_PATH}/${QMAKE_FILE_BASE}_yacc.h
-bison_header.CONFIG += target_predeps no_link
-silent:bison_header.commands = @echo Bison ${QMAKE_FILE_IN} && $$bison.commands
-QMAKE_EXTRA_COMPILERS += bison_header
+win32 {
+ bison.name = Bison ${QMAKE_FILE_IN}
+ bison.input = BISONSOURCES
+ bison.output = ${QMAKE_FILE_PATH}/${QMAKE_FILE_BASE}_yacc.cpp
+ bison.commands = bison -d -p ${QMAKE_FILE_BASE} -o ${QMAKE_FILE_PATH}/${QMAKE_FILE_BASE}_yacc.cpp ${QMAKE_FILE_IN}
+ bison.commands += && mv ${QMAKE_FILE_PATH}/${QMAKE_FILE_BASE}_yacc.hpp ${QMAKE_FILE_PATH}/${QMAKE_FILE_BASE}_yacc.h
+ bison.CONFIG += target_predeps
+ bison.variable_out = GENERATED_SOURCES
+ silent:bison.commands = @echo Bison ${QMAKE_FILE_IN} && $$bison.commands
+ QMAKE_EXTRA_COMPILERS += bison
+ bison_header.input = BISONSOURCES
+ bison_header.output = ${QMAKE_FILE_PATH}/${QMAKE_FILE_BASE}_yacc.h
+ bison_header.commands = bison -d -p ${QMAKE_FILE_BASE} -o ${QMAKE_FILE_PATH}/${QMAKE_FILE_BASE}_yacc.cpp ${QMAKE_FILE_IN}
+ bison_header.commands += && mv ${QMAKE_FILE_PATH}/${QMAKE_FILE_BASE}_yacc.hpp ${QMAKE_FILE_PATH}/${QMAKE_FILE_BASE}_yacc.h
+ bison_header.CONFIG += target_predeps no_link
+ silent:bison_header.commands = @echo Bison ${QMAKE_FILE_IN} && $$bison.commands
+ QMAKE_EXTRA_COMPILERS += bison_header
+}
+
+unix:freebsd-g++ {
+ # on bsd /usr/bin/bison is outdated, dont use it
+ QMAKE_YACC = /usr/local/bin/bison
+}
+
+unix:linux* {
+ exists(/usr/bin/bison) {
+ QMAKE_YACC = /usr/bin/bison
+ }
+}
diff --git a/boost.pri b/boost.pri
index 400300b..c2dbbf2 100644
--- a/boost.pri
+++ b/boost.pri
@@ -1,28 +1,40 @@
boost {
- isEmpty(DEPLOYDIR) {
- # Optionally specify location of boost using the
- # BOOSTDIR env. variable
- BOOST_DIR = $$(BOOSTDIR)
- !isEmpty(BOOST_DIR) {
- INCLUDEPATH += $$BOOST_DIR
- message("boost location: $$BOOST_DIR")
- win32:LIBS += -L$$BOOST_DIR/lib
- }
+ # Optionally specify location of boost using the
+ # BOOSTDIR env. variable
+ BOOST_DIR = $$(BOOSTDIR)
+ !isEmpty(BOOST_DIR) {
+ QMAKE_INCDIR += $$BOOST_DIR
+ message("boost location: $$BOOST_DIR")
+ win32:QMAKE_LIBDIR += -L$$BOOST_DIR/lib
}
+ win32:!CONFIG(mingw-cross-env) {
+ LIBS += -llibboost_thread-vc90-mt-s-1_46_1 -llibboost_program_options-vc90-mt-s-1_46_1 -llibboost_filesystem-vc90-mt-s-1_46_1 -llibboost_system-vc90-mt-s-1_46_1
+ }
+
CONFIG(mingw-cross-env) {
DEFINES += BOOST_STATIC
DEFINES += BOOST_THREAD_USE_LIB
DEFINES += Boost_USE_STATIC_LIBS
- LIBS += -lboost_thread_win32-mt -lboost_program_options-mt -lboost_filesystem-mt -lboost_system-mt
- } else {
- win32 {
- LIBS += -llibboost_thread-vc90-mt-s-1_46_1 -llibboost_program_options-vc90-mt-s-1_46_1 -llibboost_filesystem-vc90-mt-s-1_46_1 -llibboost_system-vc90-mt-s-1_46_1
- } else {
- # some platforms have only '-mt' versions. uncomment if needed.
- # LIBS += -lboost_thread-mt -lboost_program_options-mt
+ LIBS += -lboost_thread_win32-mt -lboost_program_options-mt
+ }
+
+ unix {
+ BMT_TEST1 = /usr/lib64/libboost*thread-mt*
+ BMT_TEST2 = /usr/lib/libboost*thread-mt*
+ BMT_TEST3 = $$BOOST_DIR/lib/libboost*thread-mt*
+
+ exists($$BMT_TEST1)|exists($$BMT_TEST2)|exists($$BMT_TEST3) {
+ LIBS += -lboost_thread-mt -lboost_program_options-mt -lboost_filesystem-mt -lboost_system-mt -lboost_regex-mt
+ BOOST_IS_MT = true
+ }
+ }
+
+ unix|macx {
+ isEmpty(BOOST_IS_MT) {
LIBS += -lboost_thread -lboost_program_options -lboost_filesystem -lboost_system -lboost_regex
}
}
+
}
diff --git a/cgal.pri b/cgal.pri
index 1d9ef22..7cd5389 100644
--- a/cgal.pri
+++ b/cgal.pri
@@ -1,23 +1,21 @@
cgal {
DEFINES += ENABLE_CGAL
- isEmpty(DEPLOYDIR) {
- # Optionally specify location of CGAL using the
- # CGALDIR env. variable
- CGAL_DIR = $$(CGALDIR)
- !isEmpty(CGAL_DIR) {
- INCLUDEPATH += $$CGAL_DIR/include
- win32: INCLUDEPATH += $$CGAL_DIR/auxiliary/gmp/include
- LIBS += -L$$CGAL_DIR/lib
- message("CGAL location: $$CGAL_DIR")
- }
+ # Optionally specify location of CGAL using the
+ # CGALDIR env. variable
+ CGAL_DIR = $$(CGALDIR)
+ !isEmpty(CGAL_DIR) {
+ QMAKE_INCDIR += $$CGAL_DIR/include
+ win32: QMAKE_INCDIR += $$CGAL_DIR/auxiliary/gmp/include
+ QMAKE_LIBDIR += $$CGAL_DIR/lib
+ message("CGAL location: $$CGAL_DIR")
}
CONFIG(mingw-cross-env) {
LIBS += -lgmp -lmpfr -lCGAL
QMAKE_CXXFLAGS += -frounding-math
} else {
- windows {
+ win32 {
*-g++* {
QMAKE_CXXFLAGS += -frounding-math
}
@@ -27,5 +25,4 @@ cgal {
QMAKE_CXXFLAGS += -frounding-math
}
}
-
}
diff --git a/common.pri b/common.pri
new file mode 100644
index 0000000..d6e8480
--- /dev/null
+++ b/common.pri
@@ -0,0 +1,13 @@
+OBJECTS_DIR = objects
+MOC_DIR = objects
+UI_DIR = objects
+RCC_DIR = objects
+
+include(win32.pri)
+include(flex.pri)
+include(bison.pri)
+include(cgal.pri)
+include(opencsg.pri)
+include(glew.pri)
+include(eigen2.pri)
+include(boost.pri)
diff --git a/contrib/OpenSCAD.xml b/contrib/OpenSCAD.xml
new file mode 100644
index 0000000..7c6cf76
--- /dev/null
+++ b/contrib/OpenSCAD.xml
@@ -0,0 +1,36 @@
+<NotepadPlus>
+ <UserLang name="OpenSCAD" ext="scad">
+ <Settings>
+ <Global caseIgnored="yes" />
+ <TreatAsSymbol comment="yes" commentLine="yes" />
+ <Prefix words1="yes" words2="yes" words3="no" words4="no" />
+ </Settings>
+ <KeywordLists>
+ <Keywords name="Delimiters">000000</Keywords>
+ <Keywords name="Folder+">{</Keywords>
+ <Keywords name="Folder-">}</Keywords>
+ <Keywords name="Operators"># % ( ) ; [ ] &lt; &gt;</Keywords>
+ <Keywords name="Comment"> 1/* 2*/ 0//</Keywords>
+ <Keywords name="Words1">abs acos asin atan atan ceil cos exp floor ln log lookup max min pow rands round sign sin sqrt tan str scale rotate translate mirror multmatrix color minkowski hull union difference intersection render echo use include module builtin_dxf_cross for intersection_for if else assign surface</Keywords>
+ <Keywords name="Words2">sphere cylinder polyhedron cube</Keywords>
+ <Keywords name="Words3"></Keywords>
+ <Keywords name="Words4"></Keywords>
+ </KeywordLists>
+ <Styles>
+ <WordsStyle name="DEFAULT" styleID="11" fgColor="000000" bgColor="FFFFFF" fontStyle="0" />
+ <WordsStyle name="FOLDEROPEN" styleID="12" fgColor="000000" bgColor="FFFFFF" fontStyle="0" />
+ <WordsStyle name="FOLDERCLOSE" styleID="13" fgColor="000000" bgColor="FFFFFF" fontStyle="0" />
+ <WordsStyle name="KEYWORD1" styleID="5" fgColor="0000A0" bgColor="FFFFFF" fontStyle="1" />
+ <WordsStyle name="KEYWORD2" styleID="6" fgColor="800000" bgColor="FFFFFF" fontStyle="1" />
+ <WordsStyle name="KEYWORD3" styleID="7" fgColor="000000" bgColor="FFFFFF" fontStyle="0" />
+ <WordsStyle name="KEYWORD4" styleID="8" fgColor="000000" bgColor="FFFFFF" fontStyle="0" />
+ <WordsStyle name="COMMENT" styleID="1" fgColor="008000" bgColor="FFFFFF" fontStyle="0" />
+ <WordsStyle name="COMMENT LINE" styleID="2" fgColor="008000" bgColor="FFFFFF" fontStyle="0" />
+ <WordsStyle name="NUMBER" styleID="4" fgColor="000000" bgColor="FFFFFF" fontStyle="0" />
+ <WordsStyle name="OPERATOR" styleID="10" fgColor="000000" bgColor="FFFFFF" fontStyle="0" />
+ <WordsStyle name="DELIMINER1" styleID="14" fgColor="0080FF" bgColor="FFFFFF" fontStyle="0" />
+ <WordsStyle name="DELIMINER2" styleID="15" fgColor="000000" bgColor="FFFFFF" fontStyle="0" />
+ <WordsStyle name="DELIMINER3" styleID="16" fgColor="000000" bgColor="FFFFFF" fontStyle="0" />
+ </Styles>
+ </UserLang>
+</NotepadPlus>
diff --git a/doc/TODO.txt b/doc/TODO.txt
index 4212c21..6bb3a15 100644
--- a/doc/TODO.txt
+++ b/doc/TODO.txt
@@ -71,6 +71,8 @@ o 3D View
thicknesses, distances, slot thicknesses etc.
- Add option to change lights, e.g. add an optional camera light
- 2D objects are rendered at z = -0.1 - why?
+ - Rewrite to use VBOs or smth. - avoid inline calculations
+ - Rewrite to a higher-level library (e.g. OSG)?
o Editor wishlist
- More infrastructure for external editor (allow communication from the outside)
- Preferences GUI for the features below
@@ -88,6 +90,7 @@ o Editor wishlist
in the source code in the 3D view
- Tabbed editor for designs including other files
- C-c/C-v should work on the focused widget, not always in the editor
+ - Auto-indent on enter and on tab
o Error reporting/debugging
- Provide better error messages when polygon ordering causes CGAL errors:
o Supply syntax highlighting of the exact polygon indices which are
@@ -138,7 +141,6 @@ o 2D Subsystem
o Built-in modules
- extrude*: Allow the base 2D primitive to have a Z value
- rotate_extrude(): Allow for specification of start/stop/sweep angle?
- - Convex hull of 3D objects
o Advanced Transformations
- Add statement for refinement via surface subdivision
- Add statement for intersections in cartesian product of childs
@@ -236,7 +238,6 @@ MISSING TESTS:
o all functions
o mirror
o scale
-o 3D hull
o open polyline from dxf using new method
o linear_extrude DXF
o rotate_extrude DXF
@@ -244,7 +245,7 @@ o import_stl
o import_off
o import_*
- open polylines
-o include: test subdirs under librarydir (e.g. include <MCAD/gears.scad> doesn't work
+o include: test subdirs under librarydir (e.g. include <MCAD/gears.scad>)
o use: Basically same tests as include. + use restrictions
o include and use: remember filenames with space
o variants of module transparent() { %child(); }
diff --git a/doc/release-checklist.txt b/doc/release-checklist.txt
index a455ca9..2ff9593 100644
--- a/doc/release-checklist.txt
+++ b/doc/release-checklist.txt
@@ -9,24 +9,24 @@ o Update version
o Update RELEASE_NOTES
o Tag release
- git tag "openscad-2011.01"
+ git tag "openscad-2011.12"
o build source package
- git archive --format=tar openscad-2011.01 --prefix=openscad-2011.01/ | gzip > openscad-2011.01.src.tar.gz
+ git archive --format=tar openscad-2011.12 --prefix=openscad-2011.12/ | gzip > openscad-2011.12.src.tar.gz
o build binaries
- tar xzf openscad-2011.01.src.tar.gz
- cd openscad-2011.01
+ tar xzf openscad-2011.12.src.tar.gz
+ cd openscad-2011.12
Mac OS X
- For Qt-4.7.3: Remove /Developers/Applications/Qt/plugins/qmltooling
- ./scripts/publish-macosx.sh -> OpenSCAD-2011.01.dmg
+ (For Qt-4.7.3: Remove /Developers/Applications/Qt/plugins/qmltooling)
+ ./scripts/publish-macosx.sh -> OpenSCAD-2011.12.dmg
Linux: FIXME 32 vs. 64 bit
./scripts/release-linux.sh
Windows: FIXME 32 vs. 64 bit
o FIXME: Run some tests
-o Set back version: release-linux.sh, publish-macosx.sh, FIXME: Windows
+o Set back version to being date-tagged: release-linux.sh, publish-macosx.sh, FIXME: Windows
o git push --tags
@@ -37,3 +37,7 @@ o Upload
o Update web page
o Write email to mailing list
+o Update external resources:
+ - http://en.wikipedia.org/wiki/OpenSCAD
+o Notify package managers
+ - Ubuntu: https://launchpad.net/~chrysn
diff --git a/doc/testing.txt b/doc/testing.txt
index 66ceac2..67d14ba 100644
--- a/doc/testing.txt
+++ b/doc/testing.txt
@@ -1,7 +1,7 @@
Running regression tests:
-------------------------
-Prerequisites: cmake, python
+Prerequisites: cmake, python, ImageMagick 6.5.9.3 or newer
A) Building test environment
@@ -16,25 +16,14 @@ First, get a normal build working by following instructions at
http://en.wikibooks.org/wiki/OpenSCAD_User_Manual/Building_on_Windows
Then, from the QT command prompt:
-$ cd tests
-$ cmake . -DCMAKE_BUILD_TYPE=Release
-$ sed -i s/\/MD/\/MT/ CMakeCache.txt
-$ cmake .
-$ nmake -f Makefile
+> cd tests
+> cmake . -DCMAKE_BUILD_TYPE=Release
+> sed -i s/\/MD/\/MT/ CMakeCache.txt
+> cmake .
+> nmake -f Makefile
B) Running tests
-Easy version:
-$ make test
-
-Windows:
-$ nmake -f Makefile test
-
-Headless servers (no X11):
-$ Xvnc :5 -screen 0 800x600x24 &
-$ DISPLAY=:5 make test
-
-Partial or extended test runs:
$ ctest Runs tests enabled by default
$ ctest -R <regex> Runs only matching tests, e.g. ctest -R dxf
$ ctest -C <configs> Adds extended tests belonging to configs.
@@ -44,8 +33,7 @@ $ ctest -C <configs> Adds extended tests belonging to configs.
Examples - test all examples
All - test everything
-
-Adding a new regression test:
+Adding a new regression test:
------------------------------
1) create a test file at an appropriate location under testdata/
@@ -59,20 +47,52 @@ Adding a new regression test:
7) run the test normally and verify that it passes:
$ ctest -R mytest
-Troubleshooting a failed test:
+Troubleshooting:
------------------------------
-You can run a single test by passing the test name to ctest:
- $ ctest -R throwntogethertest_sphere
+0. Headless unix servers (no X11)
+
+$ Xvfb :5 -screen 0 800x600x24 &
+$ DISPLAY=:5 ctest
+
+1. Trouble finding libraries
+
+ To help CMAKE find eigen2, OpenCSG, CGAL, Boost, and GLEW, you can use
+ environment variables, just like for the main qmake & openscad.pro. Examples:
-You can run a series of tests by passing part of a name to ctest:
- $ ctest -R cgalpng # runs all cgalpng tests
- $ ctest -R sphere # runs all sphere tests
-
+ OPENCSGDIR=~/OpenCSG-1.3.2 EIGEN2DIR=~/eigen2 cmake .
+
+ Valid variables are as follows (see CMakeLists.txt for more info):
+
+ BOOSTDIR, CGALDIR, EIGEN2DIR, GLEWDIR, OPENCSGDIR, OPENSCAD_LIBRARIES
+
+2. Logs
+
Logs of test runs are found in tests/build/Testing/Temporary
+Pretty-printed index.html is in a subdir of tests/build/Testing/Temporary
Expected results are found in tests/regression/*
Actual results are found in tests/build/testname-output/*
-You can also compile a single test program:
+3. Cross-compiling
+
+Cross-compiling of tests has not been automated nor tested
+
+4. Image-based tests takes a long time, they fail, and it says 'return -11'
+
+Imagemagick may have crashed. You can try using the alternate IM comparator
+based on Normalized Cross Correlation. Pass -DCOMPARATOR=ncc to cmake
+
+5. Testing images fails with 'morphology' not found for ImageMagick
+
+Your version of imagemagick is old. Upgrade, or pass -DCOMPARATOR=old to
+cmake. The comparison will be of lowered reliability.
+
+6. Unexplained or bizarre errors.
+
+This can happen on dynamic-library systems (linux) where you try to use
+your own version of a library while the system still has another version
+under the system paths. You can diagnose this by looking at your cmake
+log as well as your sysinfo.txt file, as well as running 'ldd' against
+your binaries, to make sure that the proper versions of libraries are
+getting compiled and linked with the test binaries.
- $ make cgalpngtest
diff --git a/eigen2.pri b/eigen2.pri
index 4c71749..44649f8 100644
--- a/eigen2.pri
+++ b/eigen2.pri
@@ -1,15 +1,27 @@
-# Optionally specify location of Eigen2 using the
-# EIGEN2DIR env. variable
-EIGEN2_DIR = $$(EIGEN2DIR)
-!isEmpty(EIGEN2_DIR) {
- INCLUDEPATH += $$EIGEN2_DIR
-}
-else {
- CONFIG(mingw-cross-env) {
- INCLUDEPATH += mingw-cross-env/include/eigen2
- } else {
- freebsd-g++: INCLUDEPATH += /usr/local/include/eigen2
- macx: INCLUDEPATH += /opt/local/include/eigen2
- !macx:!freebsd-g++:INCLUDEPATH += /usr/include/eigen2
+eigen2 {
+ # Optionally specify location of Eigen2 using the
+ # EIGEN2DIR env. variable
+ EIGEN2_DIR = $$(EIGEN2DIR)
+ !isEmpty(EIGEN2_DIR) {
+ EIGEN2_INCLUDEPATH = $$EIGEN2_DIR
+ }
+ else {
+ CONFIG(mingw-cross-env) {
+ EIGEN2_INCLUDEPATH = mingw-cross-env/include/eigen2
+ } else {
+ freebsd-g++: EIGEN2_INCLUDEPATH *= /usr/local/include/eigen2
+ macx: EIGEN2_INCLUDEPATH *= /opt/local/include/eigen2
+ !macx:!freebsd-g++:!win32:EIGEN2_INCLUDEPATH *= /usr/include/eigen2
+ }
+ }
+
+ # eigen2 being under 'include/eigen2' needs special prepending
+ QMAKE_INCDIR_QT = $$EIGEN2_INCLUDEPATH $$QMAKE_INCDIR_QT
+
+ # disable Eigen SIMD optimizations for platforms where it breaks compilation
+ !macx {
+ !freebsd-g++ {
+ QMAKE_CXXFLAGS += -DEIGEN_DONT_ALIGN
+ }
}
}
diff --git a/flex.pri b/flex.pri
index 2042952..2e1559e 100644
--- a/flex.pri
+++ b/flex.pri
@@ -1,10 +1,20 @@
-#setup flex for qmake
-
-flex.name = Flex ${QMAKE_FILE_IN}
-flex.input = FLEXSOURCES
-flex.output = ${QMAKE_FILE_PATH}/${QMAKE_FILE_BASE}.lexer.cpp
-flex.commands = flex -P ${QMAKE_FILE_BASE} -o${QMAKE_FILE_PATH}/${QMAKE_FILE_BASE}.lexer.cpp ${QMAKE_FILE_IN}
-flex.CONFIG += target_predeps
-flex.variable_out = GENERATED_SOURCES
-silent:flex.commands = @echo Lex ${QMAKE_FILE_IN} && $$flex.commands
-QMAKE_EXTRA_COMPILERS += flex
+win32 {
+ flex.name = Flex ${QMAKE_FILE_IN}
+ flex.input = FLEXSOURCES
+ flex.output = ${QMAKE_FILE_PATH}/${QMAKE_FILE_BASE}.lexer.cpp
+ flex.commands = flex -P ${QMAKE_FILE_BASE} -o${QMAKE_FILE_PATH}/${QMAKE_FILE_BASE}.lexer.cpp ${QMAKE_FILE_IN}
+ flex.CONFIG += target_predeps
+ flex.variable_out = GENERATED_SOURCES
+ silent:flex.commands = @echo Lex ${QMAKE_FILE_IN} && $$flex.commands
+ QMAKE_EXTRA_COMPILERS += flex
+}
+
+unix:freebsd-g++ {
+ QMAKE_LEX = /usr/local/bin/flex
+}
+
+unix:linux* {
+ exists(/usr/bin/flex) {
+ QMAKE_LEX = /usr/bin/flex
+ }
+}
diff --git a/glew.pri b/glew.pri
index 84d9449..981d14b 100644
--- a/glew.pri
+++ b/glew.pri
@@ -1,21 +1,14 @@
glew {
- isEmpty(DEPLOYDIR) {
- # Optionally specify location of GLEW using the
- # GLEWDIR env. variable
- GLEW_DIR = $$(GLEWDIR)
- isEmpty(GLEW_DIR) {
- # Default to MacPorts on Mac OS X
- macx: GLEW_DIR = /opt/local
- }
- !isEmpty(GLEW_DIR) {
- INCLUDEPATH += $$GLEW_DIR/include
- LIBS += -L$$GLEW_DIR/lib
- message("GLEW location: $$GLEW_DIR")
- }
+ # Optionally specify location of GLEW using the
+ # GLEWDIR env. variable
+ GLEW_DIR = $$(GLEWDIR)
+ !isEmpty(GLEW_DIR) {
+ QMAKE_INCDIR += $$GLEW_DIR/include
+ QMAKE_LIBDIR += $$GLEW_DIR/lib
+ message("GLEW location: $$GLEW_DIR")
}
unix:LIBS += -lGLEW
win32:LIBS += -lglew32s
CONFIG(mingw-cross-env):DEFINES += GLEW_STATIC
}
-
diff --git a/mingw-cross-env.pri b/mingw-cross-env.pri
new file mode 100644
index 0000000..b0735a2
--- /dev/null
+++ b/mingw-cross-env.pri
@@ -0,0 +1,13 @@
+# cross compilation unix->win32
+CONFIG(mingw-cross-env) {
+ LIBS += mingw-cross-env/lib/libglew32s.a
+ LIBS += mingw-cross-env/lib/libglut.a
+ LIBS += mingw-cross-env/lib/libopengl32.a
+ LIBS += mingw-cross-env/lib/libGLEW.a
+ LIBS += mingw-cross-env/lib/libglaux.a
+ LIBS += mingw-cross-env/lib/libglu32.a
+ LIBS += mingw-cross-env/lib/libopencsg.a
+ LIBS += mingw-cross-env/lib/libmpfr.a
+ LIBS += mingw-cross-env/lib/libCGAL.a
+ QMAKE_CXXFLAGS += -fpermissive
+}
diff --git a/opencsg.pri b/opencsg.pri
index d34f11b..ff3bc4d 100644
--- a/opencsg.pri
+++ b/opencsg.pri
@@ -1,20 +1,14 @@
opencsg {
DEFINES += ENABLE_OPENCSG
CONFIG += glew
- include(glew.pri)
- HEADERS += src/OpenCSGRenderer.h
- SOURCES += src/OpenCSGRenderer.cc
-
- isEmpty(DEPLOYDIR) {
- # Optionally specify location of OpenCSG using the
- # OPENCSGDIR env. variable
- OPENCSG_DIR = $$(OPENCSGDIR)
- !isEmpty(OPENCSG_DIR) {
- INCLUDEPATH += $$OPENCSG_DIR/include
- LIBS += -L$$OPENCSG_DIR/lib
- message("OpenCSG location: $$OPENCSG_DIR")
- }
+ # Optionally specify location of OpenCSG using the
+ # OPENCSGDIR env. variable
+ OPENCSG_DIR = $$(OPENCSGDIR)
+ !isEmpty(OPENCSG_DIR) {
+ QMAKE_INCDIR += $$OPENCSG_DIR/include
+ QMAKE_LIBDIR += $$OPENCSG_DIR/lib
+ message("OpenCSG location: $$OPENCSG_DIR")
}
LIBS += -lopencsg
diff --git a/openscad.pro b/openscad.pro
index 4a1c0f3..e38251a 100644
--- a/openscad.pro
+++ b/openscad.pro
@@ -1,3 +1,13 @@
+# Environment variables which can be set to specify library locations:
+# MPIRDIR
+# MPFRDIR
+# BOOSTDIR
+# CGALDIR
+# EIGEN2DIR
+# GLEWDIR
+# OPENCSGDIR
+# OPENSCAD_LIBRARIES
+#
isEmpty(QT_VERSION) {
error("Please use qmake for Qt 4 (probably qmake-qt4)")
@@ -18,84 +28,30 @@ include(version.pri)
# for debugging link problems (use nmake -f Makefile.Release > log.txt)
win32 {
- # QMAKE_LFLAGS += -VERBOSE
+ # QMAKE_LFLAGS += -VERBOSE
}
debug: DEFINES += DEBUG
-# cross compilation unix->win32
-
-CONFIG(mingw-cross-env) {
- LIBS += mingw-cross-env/lib/libglew32s.a
- LIBS += mingw-cross-env/lib/libglut.a
- LIBS += mingw-cross-env/lib/libopengl32.a
- LIBS += mingw-cross-env/lib/libGLEW.a
- LIBS += mingw-cross-env/lib/libglaux.a
- LIBS += mingw-cross-env/lib/libglu32.a
- LIBS += mingw-cross-env/lib/libopencsg.a
- LIBS += mingw-cross-env/lib/libmpfr.a
- LIBS += mingw-cross-env/lib/libCGAL.a
- QMAKE_CXXFLAGS += -fpermissive
-}
-
-#configure lex / yacc
-unix:freebsd-g++ {
- QMAKE_LEX = /usr/local/bin/flex
- QMAKE_YACC = /usr/local/bin/bison
-}
-win32 {
- include(flex.pri)
- include(bison.pri)
- FLEXSOURCES = src/lexer.l
- BISONSOURCES = src/parser.y
-} else {
- LEXSOURCES += src/lexer.l
- YACCSOURCES += src/parser.y
-}
-
-#configure additional directories
-win32 {
- INCLUDEPATH += $$(MPIRDIR)
- INCLUDEPATH += $$(MPFRDIR)
-}
+TEMPLATE = app
-DEFINES += OPENSCAD_VERSION=$$VERSION OPENSCAD_YEAR=$$VERSION_YEAR OPENSCAD_MONTH=$$VERSION_MONTH
-!isEmpty(VERSION_DAY): DEFINES += OPENSCAD_DAY=$$VERSION_DAY
-win32:DEFINES += _USE_MATH_DEFINES NOMINMAX _CRT_SECURE_NO_WARNINGS YY_NO_UNISTD_H
+INCLUDEPATH += src
-# disable MSVC warnings that are of very low importance
-win32:*msvc* {
- # disable warning about too long decorated names
- QMAKE_CXXFLAGS += -wd4503
- # CGAL casting int to bool
- QMAKE_CXXFLAGS += -wd4800
- # CGAL's unreferenced formal parameters
- QMAKE_CXXFLAGS += -wd4100
- # lexer uses strdup() & other POSIX stuff
- QMAKE_CXXFLAGS += -D_CRT_NONSTDC_NO_DEPRECATE
+# Handle custom library location.
+# Used when manually installing 3rd party libraries
+OPENSCAD_LIBDIR = $$(OPENSCAD_LIBRARIES)
+!isEmpty(OPENSCAD_LIBDIR) {
+ QMAKE_INCDIR_QT = $$OPENSCAD_LIBDIR/include $$QMAKE_INCDIR_QT
+ QMAKE_LIBDIR = $$OPENSCAD_LIBDIR/lib $$QMAKE_LIBDIR
}
-
-# disable Eigen SIMD optimizations for non-Mac OSX
-!macx {
- !freebsd-g++ {
- QMAKE_CXXFLAGS += -DEIGEN_DONT_ALIGN
+else {
+ macx {
+ # Default to MacPorts on Mac OS X
+ QMAKE_INCDIR = /opt/local/include
+ QMAKE_LIBDIR = /opt/local/lib
}
}
-TEMPLATE = app
-RESOURCES = openscad.qrc
-
-OBJECTS_DIR = objects
-MOC_DIR = objects
-UI_DIR = objects
-RCC_DIR = objects
-INCLUDEPATH += src
-
macx {
- DEPLOYDIR = $$(MACOSX_DEPLOY_DIR)
- !isEmpty(DEPLOYDIR) {
- INCLUDEPATH += $$DEPLOYDIR/include
- LIBS += -L$$DEPLOYDIR/lib
- }
# add CONFIG+=deploy to the qmake command-line to make a deployment build
deploy {
message("Building deployment version")
@@ -121,21 +77,31 @@ win32 {
CONFIG += qt
QT += opengl
+# Fedora Linux + DSO fix
+linux*:exists(/usr/lib64/libGLU*)|linux*:exists(/usr/lib/libGLU*) {
+ LIBS += -lGLU
+}
+
+CONFIG(mingw-cross-env) {
+ include(mingw-cross-env.pri)
+}
+
# Application configuration
macx:CONFIG += mdi
CONFIG += cgal
CONFIG += opencsg
-CONFIG += progresswidget
CONFIG += boost
+CONFIG += eigen2
#Uncomment the following line to enable QCodeEdit
#CONFIG += qcodeedit
mdi {
- # MDI needs an OpenCSG library that is compiled with OpenCSG-Reset-Hack.patch applied
DEFINES += ENABLE_MDI
}
+# FIXME: This can be made default by now
+CONFIG += progresswidget
progresswidget {
DEFINES += USE_PROGRESSWIDGET
FORMS += src/ProgressWidget.ui
@@ -143,31 +109,31 @@ progresswidget {
SOURCES += src/ProgressWidget.cc
}
-include(cgal.pri)
-include(opencsg.pri)
-include(eigen2.pri)
-include(boost.pri)
-
-# Standard include path for misc external libs
-#macx {
-# INCLUDEPATH += /opt/local/include
-#}
+include(common.pri)
-# QMAKE_CFLAGS += -pg
-# QMAKE_CXXFLAGS += -pg
-# QMAKE_LFLAGS += -pg
+win32 {
+ FLEXSOURCES = src/lexer.l
+ BISONSOURCES = src/parser.y
+} else {
+ LEXSOURCES += src/lexer.l
+ YACCSOURCES += src/parser.y
+}
+RESOURCES = openscad.qrc
FORMS += src/MainWindow.ui \
- src/Preferences.ui
+ src/Preferences.ui \
+ src/OpenCSGWarningDialog.ui
HEADERS += src/renderer.h \
+ src/rendersettings.h \
src/ThrownTogetherRenderer.h \
src/CGAL_renderer.h \
src/OGL_helper.h \
src/GLView.h \
src/MainWindow.h \
src/Preferences.h \
+ src/OpenCSGWarningDialog.h \
src/builtin.h \
src/context.h \
src/csgterm.h \
@@ -215,6 +181,8 @@ HEADERS += src/renderer.h \
SOURCES += src/openscad.cc \
src/mainwin.cc \
src/handle_dep.cc \
+ src/renderer.cc \
+ src/rendersettings.cc \
src/ThrownTogetherRenderer.cc \
src/glview.cc \
src/export.cc \
@@ -247,6 +215,7 @@ SOURCES += src/openscad.cc \
src/highlighter.cc \
src/printutils.cc \
src/Preferences.cc \
+ src/OpenCSGWarningDialog.cc \
src/progress.cc \
src/editor.cc \
src/traverser.cc \
@@ -257,6 +226,11 @@ SOURCES += src/openscad.cc \
src/PolySetCache.cc \
src/PolySetEvaluator.cc
+opencsg {
+ HEADERS += src/OpenCSGRenderer.h
+ SOURCES += src/OpenCSGRenderer.cc
+}
+
cgal {
HEADERS += src/cgal.h \
src/cgalfwd.h \
@@ -274,7 +248,6 @@ SOURCES += src/cgalutils.cc \
src/CGALRenderer.cc \
src/CGAL_Nef_polyhedron.cc \
src/CGAL_Nef_polyhedron_DxfData.cc \
- src/cgaladv_convexhull2.cc \
src/cgaladv_minkowski2.cc
}
diff --git a/scripts/macosx-build-dependencies.sh b/scripts/macosx-build-dependencies.sh
index cd2b07f..42dbaac 100755
--- a/scripts/macosx-build-dependencies.sh
+++ b/scripts/macosx-build-dependencies.sh
@@ -192,7 +192,7 @@ build_opencsg()
tar xzf OpenCSG-$version.tar.gz
cd OpenCSG-$version
patch -p1 < $OPENSCADDIR/patches/OpenCSG-$version-MacOSX-port.patch
- MACOSX_DEPLOY_DIR=$DEPLOYDIR qmake -r CONFIG+="x86 x86_64"
+ OPENSCAD_LIBRARIES=$DEPLOYDIR qmake -r CONFIG+="x86 x86_64"
make install
}
diff --git a/scripts/publish-macosx.sh b/scripts/publish-macosx.sh
index 2036e3b..a2451fa 100755
--- a/scripts/publish-macosx.sh
+++ b/scripts/publish-macosx.sh
@@ -1,13 +1,13 @@
#!/bin/sh
VERSION=`date "+%Y.%m.%d"`
-#VERSION=2011.06
+#VERSION=2011.12
# Turn off ccache, just for safety
PATH=${PATH//\/opt\/local\/libexec\/ccache:}
# This is the same location as DEPLOYDIR in macosx-build-dependencies.sh
-export MACOSX_DEPLOY_DIR=$PWD/../libraries/install
+export OPENSCAD_LIBRARIES=$PWD/../libraries/install
`dirname $0`/release-common.sh -v $VERSION
if [[ $? != 0 ]]; then
diff --git a/scripts/release-linux.sh b/scripts/release-linux.sh
index 7675c07..e1eb001 100755
--- a/scripts/release-linux.sh
+++ b/scripts/release-linux.sh
@@ -2,7 +2,7 @@
# WARNING: This script might only work with the authors setup...
VERSION=`date "+%Y.%m.%d"`
-#VERSION=2011.06
+#VERSION=2011.12
set -ex
diff --git a/setenv_mjau.sh b/setenv_mjau.sh
index f6a16d2..599be0e 100644
--- a/setenv_mjau.sh
+++ b/setenv_mjau.sh
@@ -1,4 +1,4 @@
-export MACOSX_DEPLOY_DIR=$PWD/../libraries/install
+export OPENSCAD_LIBRARIES=$PWD/../libraries/install
export DYLD_LIBRARY_PATH=$MACOSX_DEPLOY_DIR/lib
#export OPENCSGDIR=$PWD/../OpenCSG-1.3.0
diff --git a/src/CGALEvaluator.cc b/src/CGALEvaluator.cc
index 1772354..684ab42 100644
--- a/src/CGALEvaluator.cc
+++ b/src/CGALEvaluator.cc
@@ -116,13 +116,12 @@ CGAL_Nef_polyhedron CGALEvaluator::applyToChildren(const AbstractNode &node, CGA
return N;
}
-extern CGAL_Nef_polyhedron2 *convexhull2(std::list<CGAL_Nef_polyhedron2*> a);
-
CGAL_Nef_polyhedron CGALEvaluator::applyHull(const CgaladvNode &node)
{
CGAL_Nef_polyhedron N;
std::list<CGAL_Nef_polyhedron2*> polys;
- std::list<CGAL_Polyhedron::Vertex::Point_3> points;
+ std::list<CGAL_Nef_polyhedron2::Point> points2d;
+ std::list<CGAL_Polyhedron::Vertex::Point_3> points3d;
int dim = 0;
BOOST_FOREACH(const ChildItem &item, this->visitedchildren[node.index()]) {
const AbstractNode *chnode = item.first;
@@ -137,23 +136,32 @@ CGAL_Nef_polyhedron CGALEvaluator::applyHull(const CgaladvNode &node)
continue;
}
if (dim == 2) {
- polys.push_back(chN.p2.get());
+ CGAL_Nef_polyhedron2::Explorer explorer = chN.p2->explorer();
+ BOOST_FOREACH(const CGAL_Nef_polyhedron2::Explorer::Vertex &vh,
+ std::make_pair(explorer.vertices_begin(), explorer.vertices_end())) {
+ if (explorer.is_standard(&vh)) {
+ points2d.push_back(explorer.point(&vh));
+ }
+ }
}
else if (dim == 3) {
CGAL_Polyhedron P;
chN.p3->convert_to_Polyhedron(P);
- std::transform(P.vertices_begin(), P.vertices_end(), std::back_inserter(points),
+ std::transform(P.vertices_begin(), P.vertices_end(), std::back_inserter(points3d),
boost::bind(static_cast<const CGAL_Polyhedron::Vertex::Point_3&(CGAL_Polyhedron::Vertex::*)() const>(&CGAL_Polyhedron::Vertex::point), _1));
}
chnode->progress_report();
}
if (dim == 2) {
- N = CGAL_Nef_polyhedron(convexhull2(polys));
+ std::list<CGAL_Nef_polyhedron2::Point> result;
+ CGAL::convex_hull_2(points2d.begin(), points2d.end(),std:: back_inserter(result));
+ N = CGAL_Nef_polyhedron(new CGAL_Nef_polyhedron2(result.begin(), result.end(),
+ CGAL_Nef_polyhedron2::INCLUDED));
}
else if (dim == 3) {
CGAL_Polyhedron P;
- CGAL::convex_hull_3(points.begin(), points.end(), P);
+ CGAL::convex_hull_3(points3d.begin(), points3d.end(), P);
N = CGAL_Nef_polyhedron(new CGAL_Nef_polyhedron3(P));
}
return N;
diff --git a/src/CGALRenderer.cc b/src/CGALRenderer.cc
index 95bcba1..bac25a6 100644
--- a/src/CGALRenderer.cc
+++ b/src/CGALRenderer.cc
@@ -24,6 +24,11 @@
*
*/
+#ifdef _MSC_VER
+// Boost conflicts with MPFR under MSVC (google it)
+#include <mpfr.h>
+#endif
+
// dxfdata.h must come first for Eigen SIMD alignment issues
#include "dxfdata.h"
#include "polyset.h"
diff --git a/src/CGAL_Nef_polyhedron.cc b/src/CGAL_Nef_polyhedron.cc
index 8c65777..6ed2d90 100644
--- a/src/CGAL_Nef_polyhedron.cc
+++ b/src/CGAL_Nef_polyhedron.cc
@@ -71,6 +71,8 @@ int CGAL_Nef_polyhedron::weight() const
This method is not const since convert_to_Polyhedron() wasn't const
in earlier versions of CGAL.
+
+ Note: Can return NULL if an error occurred
*/
PolySet *CGAL_Nef_polyhedron::convertToPolyset()
{
@@ -85,9 +87,16 @@ PolySet *CGAL_Nef_polyhedron::convertToPolyset()
delete dd;
}
else if (this->dim == 3) {
- CGAL_Polyhedron P;
- this->p3->convert_to_Polyhedron(P);
- ps = createPolySetFromPolyhedron(P);
+ CGAL::Failure_behaviour old_behaviour = CGAL::set_error_behaviour(CGAL::THROW_EXCEPTION);
+ try {
+ CGAL_Polyhedron P;
+ this->p3->convert_to_Polyhedron(P);
+ ps = createPolySetFromPolyhedron(P);
+ }
+ catch (CGAL::Precondition_exception e) {
+ PRINTF("CGAL error in CGAL_Nef_polyhedron::convertToPolyset(): %s", e.what());
+ }
+ CGAL::set_error_behaviour(old_behaviour);
}
return ps;
}
diff --git a/src/GLView.h b/src/GLView.h
index c31e7af..5552e4b 100644
--- a/src/GLView.h
+++ b/src/GLView.h
@@ -32,7 +32,8 @@ public:
void setShowCrosshairs(bool enabled) { this->showcrosshairs = enabled; }
bool orthoMode() const { return this->orthomode; }
void setOrthoMode(bool enabled) { this->orthomode = enabled; }
-
+ const QString &getRendererInfo() const { return this->rendererInfo; }
+
public:
QLabel *statusLabel;
double object_rot_x;
@@ -52,6 +53,8 @@ private:
void init();
Renderer *renderer;
+ QString rendererInfo;
+
bool showfaces;
bool showedges;
bool showaxes;
diff --git a/src/MainWindow.h b/src/MainWindow.h
index b2d0f60..0f2a922 100644
--- a/src/MainWindow.h
+++ b/src/MainWindow.h
@@ -86,6 +86,8 @@ private:
void loadViewSettings();
void loadDesignSettings();
+ class QMessageBox *openglbox;
+
private slots:
void actionNew();
void actionOpen();
@@ -156,6 +158,7 @@ public slots:
void helpAbout();
void helpHomepage();
void helpManual();
+ void helpOpenGL();
void quit();
void actionReloadCompile();
void checkAutoReload();
diff --git a/src/MainWindow.ui b/src/MainWindow.ui
index dc73c05..d1bdb00 100644
--- a/src/MainWindow.ui
+++ b/src/MainWindow.ui
@@ -218,6 +218,7 @@
<addaction name="helpActionAbout"/>
<addaction name="helpActionHomepage"/>
<addaction name="helpActionManual"/>
+ <addaction name="helpActionOpenGLInfo"/>
</widget>
<addaction name="menu_File"/>
<addaction name="menu_Edit"/>
@@ -666,6 +667,11 @@
<string>Export as CSG...</string>
</property>
</action>
+ <action name="helpActionOpenGLInfo">
+ <property name="text">
+ <string>OpenGL info</string>
+ </property>
+ </action>
</widget>
<customwidgets>
<customwidget>
diff --git a/src/OpenCSGRenderer.cc b/src/OpenCSGRenderer.cc
index a1aafc5..233124b 100644
--- a/src/OpenCSGRenderer.cc
+++ b/src/OpenCSGRenderer.cc
@@ -40,11 +40,11 @@ public:
OpenCSG::Primitive(operation, convexity) { }
shared_ptr<PolySet> ps;
Transform3d m;
- int csgmode;
+ PolySet::csgmode_e csgmode;
virtual void render() {
glPushMatrix();
glMultMatrixd(m.data());
- ps->render_surface(PolySet::COLORMODE_NONE, PolySet::csgmode_e(csgmode), m);
+ ps->render_surface(csgmode, m);
glPopMatrix();
}
};
@@ -89,24 +89,23 @@ void OpenCSGRenderer::renderCSGChain(CSGChain *chain, GLint *shaderinfo,
double *c = chain->colors[j];
glPushMatrix();
glMultMatrixd(m.data());
- int csgmode = chain->types[j] == CSGTerm::TYPE_DIFFERENCE ? PolySet::CSGMODE_DIFFERENCE : PolySet::CSGMODE_NORMAL;
+ PolySet::csgmode_e csgmode = chain->types[j] == CSGTerm::TYPE_DIFFERENCE ? PolySet::CSGMODE_DIFFERENCE : PolySet::CSGMODE_NORMAL;
if (highlight) {
- chain->polysets[j]->render_surface(PolySet::COLORMODE_HIGHLIGHT, PolySet::csgmode_e(csgmode + 20), m, shaderinfo);
- } else if (background) {
- chain->polysets[j]->render_surface(PolySet::COLORMODE_BACKGROUND, PolySet::csgmode_e(csgmode + 10), m, shaderinfo);
- } else if (c[0] >= 0 || c[1] >= 0 || c[2] >= 0) {
- // User-defined color from source
- glColor4dv(c);
- if (shaderinfo) {
- glUniform4f(shaderinfo[1], c[0], c[1], c[2], c[3]);
- glUniform4f(shaderinfo[2], (c[0]+1)/2, (c[1]+1)/2, (c[2]+1)/2, 1.0);
- }
- chain->polysets[j]->render_surface(PolySet::COLORMODE_NONE, PolySet::csgmode_e(csgmode), m, shaderinfo);
+ setColor(COLORMODE_HIGHLIGHT, shaderinfo);
+ csgmode = PolySet::csgmode_e(csgmode + 20);
+ }
+ else if (background) {
+ setColor(COLORMODE_BACKGROUND, shaderinfo);
+ csgmode = PolySet::csgmode_e(csgmode + 10);
+ } else if (c[0] >= 0 || c[1] >= 0 || c[2] >= 0 || c[3] >= 0) {
+ // User-defined color or alpha from source
+ setColor(c, shaderinfo);
} else if (chain->types[j] == CSGTerm::TYPE_DIFFERENCE) {
- chain->polysets[j]->render_surface(PolySet::COLORMODE_CUTOUT, PolySet::csgmode_e(csgmode), m, shaderinfo);
+ setColor(COLORMODE_CUTOUT, shaderinfo);
} else {
- chain->polysets[j]->render_surface(PolySet::COLORMODE_MATERIAL, PolySet::csgmode_e(csgmode), m, shaderinfo);
+ setColor(COLORMODE_MATERIAL, shaderinfo);
}
+ chain->polysets[j]->render_surface(csgmode, m, shaderinfo);
glPopMatrix();
}
if (shaderinfo) glUseProgram(0);
@@ -124,8 +123,8 @@ void OpenCSGRenderer::renderCSGChain(CSGChain *chain, GLint *shaderinfo,
prim->ps = chain->polysets[i];
prim->m = chain->matrices[i];
prim->csgmode = chain->types[i] == CSGTerm::TYPE_DIFFERENCE ? PolySet::CSGMODE_DIFFERENCE : PolySet::CSGMODE_NORMAL;
- if (highlight) prim->csgmode += 20;
- else if (background) prim->csgmode += 10;
+ if (highlight) prim->csgmode = PolySet::csgmode_e(prim->csgmode + 20);
+ else if (background) prim->csgmode = PolySet::csgmode_e(prim->csgmode + 10);
primitives.push_back(prim);
}
std::for_each(primitives.begin(), primitives.end(), del_fun<OpenCSG::Primitive>());
diff --git a/src/OpenCSGWarningDialog.cc b/src/OpenCSGWarningDialog.cc
new file mode 100644
index 0000000..fdaaa50
--- /dev/null
+++ b/src/OpenCSGWarningDialog.cc
@@ -0,0 +1,23 @@
+#include "OpenCSGWarningDialog.h"
+#include "Preferences.h"
+
+OpenCSGWarningDialog::OpenCSGWarningDialog(QWidget *parent)
+{
+ setupUi(this);
+
+ connect(this->showBox, SIGNAL(toggled(bool)),
+ Preferences::inst()->openCSGWarningBox, SLOT(setChecked(bool)));
+ connect(this->showBox, SIGNAL(toggled(bool)),
+ Preferences::inst(), SLOT(openCSGWarningChanged(bool)));
+
+ connect(this->enableOpenCSGBox, SIGNAL(toggled(bool)),
+ Preferences::inst()->enableOpenCSGBox, SLOT(setChecked(bool)));
+ connect(this->enableOpenCSGBox, SIGNAL(toggled(bool)),
+ Preferences::inst(), SLOT(enableOpenCSGChanged(bool)));
+}
+
+void OpenCSGWarningDialog::setText(const QString &text)
+{
+ this->warningText->setPlainText(text);
+}
+
diff --git a/src/OpenCSGWarningDialog.h b/src/OpenCSGWarningDialog.h
new file mode 100644
index 0000000..5d9c8fa
--- /dev/null
+++ b/src/OpenCSGWarningDialog.h
@@ -0,0 +1,16 @@
+#ifndef OPENCSGWARNINGDIALOG_H_
+#define OPENCSGWARNINGDIALOG_H_
+
+#include "ui_OpenCSGWarningDialog.h"
+
+class OpenCSGWarningDialog : public QDialog, public Ui::OpenCSGWarningDialog
+{
+ Q_OBJECT;
+public:
+ OpenCSGWarningDialog(QWidget *parent);
+
+public slots:
+ void setText(const QString &text);
+};
+
+#endif
diff --git a/src/OpenCSGWarningDialog.ui b/src/OpenCSGWarningDialog.ui
new file mode 100644
index 0000000..f902521
--- /dev/null
+++ b/src/OpenCSGWarningDialog.ui
@@ -0,0 +1,93 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>OpenCSGWarningDialog</class>
+ <widget class="QDialog" name="OpenCSGWarningDialog">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>412</width>
+ <height>275</height>
+ </rect>
+ </property>
+ <property name="windowTitle">
+ <string>OpenGL Warning</string>
+ </property>
+ <layout class="QVBoxLayout" name="verticalLayout">
+ <item>
+ <widget class="QTextEdit" name="warningText">
+ <property name="readOnly">
+ <bool>true</bool>
+ </property>
+ <property name="html">
+ <string>&lt;!DOCTYPE HTML PUBLIC &quot;-//W3C//DTD HTML 4.0//EN&quot; &quot;http://www.w3.org/TR/REC-html40/strict.dtd&quot;&gt;
+&lt;html&gt;&lt;head&gt;&lt;meta name=&quot;qrichtext&quot; content=&quot;1&quot; /&gt;&lt;style type=&quot;text/css&quot;&gt;
+p, li { white-space: pre-wrap; }
+&lt;/style&gt;&lt;/head&gt;&lt;body style=&quot; font-family:'Lucida Grande'; font-size:13pt; font-weight:400; font-style:normal;&quot;&gt;
+&lt;p style=&quot;-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QCheckBox" name="enableOpenCSGBox">
+ <property name="text">
+ <string>Enable OpenCSG</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout">
+ <item>
+ <widget class="QCheckBox" name="showBox">
+ <property name="text">
+ <string>Show this message again</string>
+ </property>
+ <property name="checked">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer name="horizontalSpacer">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item>
+ <widget class="QPushButton" name="closeButton">
+ <property name="text">
+ <string>Close</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </widget>
+ <resources/>
+ <connections>
+ <connection>
+ <sender>closeButton</sender>
+ <signal>clicked()</signal>
+ <receiver>OpenCSGWarningDialog</receiver>
+ <slot>accept()</slot>
+ <hints>
+ <hint type="sourcelabel">
+ <x>361</x>
+ <y>246</y>
+ </hint>
+ <hint type="destinationlabel">
+ <x>205</x>
+ <y>137</y>
+ </hint>
+ </hints>
+ </connection>
+ </connections>
+</ui>
diff --git a/src/PolySetCGALEvaluator.cc b/src/PolySetCGALEvaluator.cc
index 78d5704..7a9566b 100644
--- a/src/PolySetCGALEvaluator.cc
+++ b/src/PolySetCGALEvaluator.cc
@@ -396,8 +396,13 @@ PolySet *PolySetCGALEvaluator::evaluatePolySet(const RenderNode &node)
CGAL_Nef_polyhedron N = this->cgalevaluator.evaluateCGALMesh(node);
PolySet *ps = NULL;
if (!N.empty()) {
- ps = N.convertToPolyset();
- ps->convexity = node.convexity;
+ if (!N.p3->is_simple()) {
+ PRINTF("WARNING: Body of render() isn't valid 2-manifold!");
+ }
+ else {
+ ps = N.convertToPolyset();
+ ps->convexity = node.convexity;
+ }
}
return ps;
}
diff --git a/src/Preferences.cc b/src/Preferences.cc
index d240a9f..59f8d23 100644
--- a/src/Preferences.cc
+++ b/src/Preferences.cc
@@ -36,11 +36,21 @@ Preferences::Preferences(QWidget *parent) : QMainWindow(parent)
{
setupUi(this);
+ // Editor pane
+ QFontDatabase db;
+ foreach(int size, db.standardSizes()) {
+ this->fontSize->addItem(QString::number(size));
+ if (size == 12) {
+ this->fontSize->setCurrentIndex(this->fontSize->count()-1);
+ }
+ }
+
// Setup default settings
this->defaultmap["3dview/colorscheme"] = this->colorSchemeChooser->currentItem()->text();
this->defaultmap["editor/fontfamily"] = this->fontChooser->currentText();
this->defaultmap["editor/fontsize"] = this->fontSize->currentText().toUInt();
- this->defaultmap["editor/opengl20_warning_show"] = true;
+ this->defaultmap["advanced/opencsg_show_warning"] = true;
+ this->defaultmap["advanced/enable_opencsg_opengl1x"] = false;
// Toolbar
QActionGroup *group = new QActionGroup(this);
@@ -53,44 +63,38 @@ Preferences::Preferences(QWidget *parent) : QMainWindow(parent)
this->actionTriggered(this->prefsAction3DView);
// 3D View pane
- this->colorschemes["Cornfield"][BACKGROUND_COLOR] = QColor(0xff, 0xff, 0xe5);
- this->colorschemes["Cornfield"][OPENCSG_FACE_FRONT_COLOR] = QColor(0xf9, 0xd7, 0x2c);
- this->colorschemes["Cornfield"][OPENCSG_FACE_BACK_COLOR] = QColor(0x9d, 0xcb, 0x51);
- this->colorschemes["Cornfield"][CGAL_FACE_FRONT_COLOR] = QColor(0xf9, 0xd7, 0x2c);
- this->colorschemes["Cornfield"][CGAL_FACE_BACK_COLOR] = QColor(0x9d, 0xcb, 0x51);
- this->colorschemes["Cornfield"][CGAL_FACE_2D_COLOR] = QColor(0x00, 0xbf, 0x99);
- this->colorschemes["Cornfield"][CGAL_EDGE_FRONT_COLOR] = QColor(0xff, 0x00, 0x00);
- this->colorschemes["Cornfield"][CGAL_EDGE_BACK_COLOR] = QColor(0xff, 0x00, 0x00);
- this->colorschemes["Cornfield"][CGAL_EDGE_2D_COLOR] = QColor(0xff, 0x00, 0x00);
- this->colorschemes["Cornfield"][CROSSHAIR_COLOR] = QColor(0x80, 0x00, 0x00);
-
- this->colorschemes["Metallic"][BACKGROUND_COLOR] = QColor(0xaa, 0xaa, 0xff);
- this->colorschemes["Metallic"][OPENCSG_FACE_FRONT_COLOR] = QColor(0xdd, 0xdd, 0xff);
- this->colorschemes["Metallic"][OPENCSG_FACE_BACK_COLOR] = QColor(0xdd, 0x22, 0xdd);
- this->colorschemes["Metallic"][CGAL_FACE_FRONT_COLOR] = QColor(0xdd, 0xdd, 0xff);
- this->colorschemes["Metallic"][CGAL_FACE_BACK_COLOR] = QColor(0xdd, 0x22, 0xdd);
- this->colorschemes["Metallic"][CGAL_FACE_2D_COLOR] = QColor(0x00, 0xbf, 0x99);
- this->colorschemes["Metallic"][CGAL_EDGE_FRONT_COLOR] = QColor(0xff, 0x00, 0x00);
- this->colorschemes["Metallic"][CGAL_EDGE_BACK_COLOR] = QColor(0xff, 0x00, 0x00);
- this->colorschemes["Metallic"][CGAL_EDGE_2D_COLOR] = QColor(0xff, 0x00, 0x00);
- this->colorschemes["Metallic"][CROSSHAIR_COLOR] = QColor(0x80, 0x00, 0x00);
-
- this->colorschemes["Sunset"][BACKGROUND_COLOR] = QColor(0xaa, 0x44, 0x44);
- this->colorschemes["Sunset"][OPENCSG_FACE_FRONT_COLOR] = QColor(0xff, 0xaa, 0xaa);
- this->colorschemes["Sunset"][OPENCSG_FACE_BACK_COLOR] = QColor(0x88, 0x22, 0x33);
- this->colorschemes["Sunset"][CGAL_FACE_FRONT_COLOR] = QColor(0xff, 0xaa, 0xaa);
- this->colorschemes["Sunset"][CGAL_FACE_BACK_COLOR] = QColor(0x88, 0x22, 0x33);
- this->colorschemes["Sunset"][CGAL_FACE_2D_COLOR] = QColor(0x00, 0xbf, 0x99);
- this->colorschemes["Sunset"][CGAL_EDGE_FRONT_COLOR] = QColor(0xff, 0x00, 0x00);
- this->colorschemes["Sunset"][CGAL_EDGE_BACK_COLOR] = QColor(0xff, 0x00, 0x00);
- this->colorschemes["Sunset"][CGAL_EDGE_2D_COLOR] = QColor(0xff, 0x00, 0x00);
- this->colorschemes["Sunset"][CROSSHAIR_COLOR] = QColor(0x80, 0x00, 0x00);
-
- // Editor pane
- QFontDatabase db;
- foreach(int size, db.standardSizes()) {
- this->fontSize->addItem(QString::number(size));
- }
+ this->colorschemes["Cornfield"][RenderSettings::BACKGROUND_COLOR] = QColor(0xff, 0xff, 0xe5);
+ this->colorschemes["Cornfield"][RenderSettings::OPENCSG_FACE_FRONT_COLOR] = QColor(0xf9, 0xd7, 0x2c);
+ this->colorschemes["Cornfield"][RenderSettings::OPENCSG_FACE_BACK_COLOR] = QColor(0x9d, 0xcb, 0x51);
+ this->colorschemes["Cornfield"][RenderSettings::CGAL_FACE_FRONT_COLOR] = QColor(0xf9, 0xd7, 0x2c);
+ this->colorschemes["Cornfield"][RenderSettings::CGAL_FACE_BACK_COLOR] = QColor(0x9d, 0xcb, 0x51);
+ this->colorschemes["Cornfield"][RenderSettings::CGAL_FACE_2D_COLOR] = QColor(0x00, 0xbf, 0x99);
+ this->colorschemes["Cornfield"][RenderSettings::CGAL_EDGE_FRONT_COLOR] = QColor(0xff, 0x00, 0x00);
+ this->colorschemes["Cornfield"][RenderSettings::CGAL_EDGE_BACK_COLOR] = QColor(0xff, 0x00, 0x00);
+ this->colorschemes["Cornfield"][RenderSettings::CGAL_EDGE_2D_COLOR] = QColor(0xff, 0x00, 0x00);
+ this->colorschemes["Cornfield"][RenderSettings::CROSSHAIR_COLOR] = QColor(0x80, 0x00, 0x00);
+
+ this->colorschemes["Metallic"][RenderSettings::BACKGROUND_COLOR] = QColor(0xaa, 0xaa, 0xff);
+ this->colorschemes["Metallic"][RenderSettings::OPENCSG_FACE_FRONT_COLOR] = QColor(0xdd, 0xdd, 0xff);
+ this->colorschemes["Metallic"][RenderSettings::OPENCSG_FACE_BACK_COLOR] = QColor(0xdd, 0x22, 0xdd);
+ this->colorschemes["Metallic"][RenderSettings::CGAL_FACE_FRONT_COLOR] = QColor(0xdd, 0xdd, 0xff);
+ this->colorschemes["Metallic"][RenderSettings::CGAL_FACE_BACK_COLOR] = QColor(0xdd, 0x22, 0xdd);
+ this->colorschemes["Metallic"][RenderSettings::CGAL_FACE_2D_COLOR] = QColor(0x00, 0xbf, 0x99);
+ this->colorschemes["Metallic"][RenderSettings::CGAL_EDGE_FRONT_COLOR] = QColor(0xff, 0x00, 0x00);
+ this->colorschemes["Metallic"][RenderSettings::CGAL_EDGE_BACK_COLOR] = QColor(0xff, 0x00, 0x00);
+ this->colorschemes["Metallic"][RenderSettings::CGAL_EDGE_2D_COLOR] = QColor(0xff, 0x00, 0x00);
+ this->colorschemes["Metallic"][RenderSettings::CROSSHAIR_COLOR] = QColor(0x80, 0x00, 0x00);
+
+ this->colorschemes["Sunset"][RenderSettings::BACKGROUND_COLOR] = QColor(0xaa, 0x44, 0x44);
+ this->colorschemes["Sunset"][RenderSettings::OPENCSG_FACE_FRONT_COLOR] = QColor(0xff, 0xaa, 0xaa);
+ this->colorschemes["Sunset"][RenderSettings::OPENCSG_FACE_BACK_COLOR] = QColor(0x88, 0x22, 0x33);
+ this->colorschemes["Sunset"][RenderSettings::CGAL_FACE_FRONT_COLOR] = QColor(0xff, 0xaa, 0xaa);
+ this->colorschemes["Sunset"][RenderSettings::CGAL_FACE_BACK_COLOR] = QColor(0x88, 0x22, 0x33);
+ this->colorschemes["Sunset"][RenderSettings::CGAL_FACE_2D_COLOR] = QColor(0x00, 0xbf, 0x99);
+ this->colorschemes["Sunset"][RenderSettings::CGAL_EDGE_FRONT_COLOR] = QColor(0xff, 0x00, 0x00);
+ this->colorschemes["Sunset"][RenderSettings::CGAL_EDGE_BACK_COLOR] = QColor(0xff, 0x00, 0x00);
+ this->colorschemes["Sunset"][RenderSettings::CGAL_EDGE_2D_COLOR] = QColor(0xff, 0x00, 0x00);
+ this->colorschemes["Sunset"][RenderSettings::CROSSHAIR_COLOR] = QColor(0x80, 0x00, 0x00);
connect(this->colorSchemeChooser, SIGNAL(itemSelectionChanged()),
this, SLOT(colorSchemeChanged()));
@@ -98,9 +102,11 @@ Preferences::Preferences(QWidget *parent) : QMainWindow(parent)
this, SLOT(fontFamilyChanged(const QString &)));
connect(this->fontSize, SIGNAL(editTextChanged(const QString &)),
this, SLOT(fontSizeChanged(const QString &)));
- connect(this->openCSGWarningBox, SIGNAL(clicked(bool)),
+ connect(this->openCSGWarningBox, SIGNAL(toggled(bool)),
this, SLOT(openCSGWarningChanged(bool)));
updateGUI();
+
+ RenderSettings::inst()->setColors(this->colorschemes[getValue("3dview/colorscheme").toString()]);
}
Preferences::~Preferences()
@@ -124,15 +130,13 @@ Preferences::actionTriggered(QAction *action)
void Preferences::colorSchemeChanged()
{
+ QString scheme = this->colorSchemeChooser->currentItem()->text();
QSettings settings;
- settings.setValue("3dview/colorscheme", this->colorSchemeChooser->currentItem()->text());
+ settings.setValue("3dview/colorscheme", scheme);
- emit requestRedraw();
-}
+ RenderSettings::inst()->setColors(this->colorschemes[scheme]);
-const QColor &Preferences::color(RenderColor idx)
-{
- return this->colorschemes[getValue("3dview/colorscheme").toString()][idx];
+ emit requestRedraw();
}
void Preferences::fontFamilyChanged(const QString &family)
@@ -154,7 +158,14 @@ void
Preferences::openCSGWarningChanged(bool state)
{
QSettings settings;
- settings.setValue("editor/opengl20_warning_show",state);
+ settings.setValue("advanced/opencsg_show_warning",state);
+}
+
+void
+Preferences::enableOpenCSGChanged(bool state)
+{
+ QSettings settings;
+ settings.setValue("advanced/enable_opencsg_opengl1x", state);
}
void Preferences::keyPressEvent(QKeyEvent *e)
@@ -215,7 +226,8 @@ void Preferences::updateGUI()
this->fontSize->setEditText(fontsize);
}
- this->openCSGWarningBox->setChecked(getValue("editor/opengl20_warning_show").toBool());
+ this->openCSGWarningBox->setChecked(getValue("advanced/opencsg_show_warning").toBool());
+ this->enableOpenCSGBox->setChecked(getValue("advanced/enable_opencsg_opengl1x").toBool());
}
void Preferences::apply() const
diff --git a/src/Preferences.h b/src/Preferences.h
index bdc707d..7e22e63 100644
--- a/src/Preferences.h
+++ b/src/Preferences.h
@@ -4,6 +4,7 @@
#include <QMainWindow>
#include <QSettings>
#include "ui_Preferences.h"
+#include "rendersettings.h"
class Preferences : public QMainWindow, public Ui::Preferences
{
@@ -13,19 +14,6 @@ public:
~Preferences();
static Preferences *inst() { if (!instance) instance = new Preferences(); return instance; }
- enum RenderColor {
- BACKGROUND_COLOR,
- OPENCSG_FACE_FRONT_COLOR,
- OPENCSG_FACE_BACK_COLOR,
- CGAL_FACE_FRONT_COLOR,
- CGAL_FACE_2D_COLOR,
- CGAL_FACE_BACK_COLOR,
- CGAL_EDGE_FRONT_COLOR,
- CGAL_EDGE_BACK_COLOR,
- CGAL_EDGE_2D_COLOR,
- CROSSHAIR_COLOR
- };
- const QColor &color(RenderColor idx);
QVariant getValue(const QString &key) const;
void apply() const;
@@ -35,6 +23,7 @@ public slots:
void fontFamilyChanged(const QString &);
void fontSizeChanged(const QString &);
void openCSGWarningChanged(bool);
+ void enableOpenCSGChanged(bool);
signals:
void requestRedraw() const;
@@ -47,7 +36,7 @@ private:
void removeDefaultSettings();
QSettings::SettingsMap defaultmap;
- QHash<QString, QMap<RenderColor, QColor> > colorschemes;
+ QHash<QString, QMap<RenderSettings::RenderColor, QColor> > colorschemes;
static Preferences *instance;
};
diff --git a/src/Preferences.ui b/src/Preferences.ui
index 556172c..6b80674 100644
--- a/src/Preferences.ui
+++ b/src/Preferences.ui
@@ -185,6 +185,16 @@
<property name="text">
<string>Show OpenCSG capability warning</string>
</property>
+ <property name="checked">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QCheckBox" name="enableOpenCSGBox">
+ <property name="text">
+ <string>Enable OpenCSG for OpenGL 1.x</string>
+ </property>
</widget>
</item>
<item>
@@ -239,7 +249,7 @@
<bool>true</bool>
</property>
<property name="icon">
- <iconset>
+ <iconset resource="../openscad.qrc">
<normaloff>:/icons/prefs3DView.png</normaloff>:/icons/prefs3DView.png</iconset>
</property>
<property name="text">
@@ -251,7 +261,7 @@
<bool>true</bool>
</property>
<property name="icon">
- <iconset>
+ <iconset resource="../openscad.qrc">
<normaloff>:/icons/prefsAdvanced.png</normaloff>:/icons/prefsAdvanced.png</iconset>
</property>
<property name="text">
@@ -263,7 +273,7 @@
<bool>true</bool>
</property>
<property name="icon">
- <iconset>
+ <iconset resource="../openscad.qrc">
<normaloff>:/icons/prefsEditor.png</normaloff>:/icons/prefsEditor.png</iconset>
</property>
<property name="text">
@@ -272,7 +282,7 @@
</action>
</widget>
<resources>
- <include location="openscad.qrc"/>
+ <include location="../openscad.qrc"/>
</resources>
<connections/>
</ui>
diff --git a/src/ThrownTogetherRenderer.cc b/src/ThrownTogetherRenderer.cc
index 3ab13ea..36f7b95 100644
--- a/src/ThrownTogetherRenderer.cc
+++ b/src/ThrownTogetherRenderer.cc
@@ -70,51 +70,48 @@ void ThrownTogetherRenderer::renderCSGChain(CSGChain *chain, bool highlight,
double *c = chain->colors[i];
glPushMatrix();
glMultMatrixd(m.data());
- int csgmode = chain->types[i] == CSGTerm::TYPE_DIFFERENCE ? PolySet::CSGMODE_DIFFERENCE : PolySet::CSGMODE_NORMAL;
+ PolySet::csgmode_e csgmode = chain->types[i] == CSGTerm::TYPE_DIFFERENCE ? PolySet::CSGMODE_DIFFERENCE : PolySet::CSGMODE_NORMAL;
if (highlight) {
- chain->polysets[i]->render_surface(PolySet::COLORMODE_HIGHLIGHT, PolySet::csgmode_e(csgmode + 20), m);
+ csgmode = PolySet::csgmode_e(csgmode + 20);
+ setColor(COLORMODE_HIGHLIGHT);
+ chain->polysets[i]->render_surface(csgmode, m);
if (showedges) {
- glDisable(GL_LIGHTING);
- chain->polysets[i]->render_edges(PolySet::COLORMODE_HIGHLIGHT, PolySet::csgmode_e(csgmode + 20));
- glEnable(GL_LIGHTING);
+ setColor(COLORMODE_HIGHLIGHT_EDGES);
+ chain->polysets[i]->render_edges(csgmode);
}
} else if (background) {
- chain->polysets[i]->render_surface(PolySet::COLORMODE_BACKGROUND, PolySet::csgmode_e(csgmode + 10), m);
+ csgmode = PolySet::csgmode_e(csgmode + 10);
+ setColor(COLORMODE_BACKGROUND);
+ chain->polysets[i]->render_surface(csgmode, m);
if (showedges) {
- glDisable(GL_LIGHTING);
- chain->polysets[i]->render_edges(PolySet::COLORMODE_BACKGROUND, PolySet::csgmode_e(csgmode + 10));
- glEnable(GL_LIGHTING);
+ setColor(COLORMODE_BACKGROUND_EDGES);
+ chain->polysets[i]->render_edges(csgmode);
}
} else if (fberror) {
- if (highlight) {
- chain->polysets[i]->render_surface(PolySet::COLORMODE_NONE, PolySet::csgmode_e(csgmode + 20), m);
- } else if (background) {
- chain->polysets[i]->render_surface(PolySet::COLORMODE_NONE, PolySet::csgmode_e(csgmode + 10), m);
- } else {
- chain->polysets[i]->render_surface(PolySet::COLORMODE_NONE, PolySet::csgmode_e(csgmode), m);
- }
- } else if (c[0] >= 0 || c[1] >= 0 || c[2] >= 0) {
- glColor4dv(c);
- chain->polysets[i]->render_surface(PolySet::COLORMODE_NONE, PolySet::csgmode_e(csgmode), m);
+ if (highlight) csgmode = PolySet::csgmode_e(csgmode + 20);
+ else if (background) csgmode = PolySet::csgmode_e(csgmode + 10);
+ else csgmode = PolySet::csgmode_e(csgmode);
+ chain->polysets[i]->render_surface(csgmode, m);
+ } else if (c[0] >= 0 || c[1] >= 0 || c[2] >= 0 || c[3] >= 0) {
+ setColor(c);
+ chain->polysets[i]->render_surface(csgmode, m);
if (showedges) {
- glDisable(GL_LIGHTING);
glColor4d((c[0]+1)/2, (c[1]+1)/2, (c[2]+1)/2, 1.0);
- chain->polysets[i]->render_edges(PolySet::COLORMODE_NONE, PolySet::csgmode_e(csgmode));
- glEnable(GL_LIGHTING);
+ chain->polysets[i]->render_edges(csgmode);
}
} else if (chain->types[i] == CSGTerm::TYPE_DIFFERENCE) {
- chain->polysets[i]->render_surface(PolySet::COLORMODE_CUTOUT, PolySet::csgmode_e(csgmode), m);
+ setColor(COLORMODE_CUTOUT);
+ chain->polysets[i]->render_surface(csgmode, m);
if (showedges) {
- glDisable(GL_LIGHTING);
- chain->polysets[i]->render_edges(PolySet::COLORMODE_CUTOUT, PolySet::csgmode_e(csgmode));
- glEnable(GL_LIGHTING);
+ setColor(COLORMODE_CUTOUT_EDGES);
+ chain->polysets[i]->render_edges(csgmode);
}
} else {
- chain->polysets[i]->render_surface(PolySet::COLORMODE_MATERIAL, PolySet::csgmode_e(csgmode), m);
+ setColor(COLORMODE_MATERIAL);
+ chain->polysets[i]->render_surface(csgmode, m);
if (showedges) {
- glDisable(GL_LIGHTING);
- chain->polysets[i]->render_edges(PolySet::COLORMODE_MATERIAL, PolySet::csgmode_e(csgmode));
- glEnable(GL_LIGHTING);
+ setColor(COLORMODE_MATERIAL_EDGES);
+ chain->polysets[i]->render_edges(csgmode);
}
}
glPopMatrix();
diff --git a/src/cgaladv_convexhull2.cc b/src/cgaladv_convexhull2.cc
deleted file mode 100644
index 492df3c..0000000
--- a/src/cgaladv_convexhull2.cc
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * OpenSCAD (www.openscad.org)
- * Copyright (C) 2009-2011 Clifford Wolf <clifford@clifford.at> and
- * Marius Kintel <marius@kintel.net>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * As a special exception, you have permission to link this program
- * with the CGAL library and distribute executables, as long as you
- * follow the requirements of the GNU GPL in regard to all of the
- * software in the executable aside from CGAL.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-
-#ifdef ENABLE_CGAL
-
-#include "cgal.h"
-#include <CGAL/convex_hull_2.h>
-
-extern CGAL_Poly2 nef2p2(CGAL_Nef_polyhedron2 p);
-
-CGAL_Nef_polyhedron2 *convexhull2(std::list<CGAL_Nef_polyhedron2*> a)
-{
- std::list<CGAL_Nef_polyhedron2::Point> points;
-
- std::list<CGAL_Nef_polyhedron2*>::iterator i;
- for (i=a.begin(); i!=a.end(); i++) {
- CGAL_Poly2 ap=nef2p2(**i);
- for (size_t j=0;j<ap.size();j++) {
- double x=to_double(ap[j].x()),y=to_double(ap[j].y());
- CGAL_Nef_polyhedron2::Point p=CGAL_Nef_polyhedron2::Point(x,y);
- points.push_back(p);
- }
- }
-
- std::list<CGAL_Nef_polyhedron2::Point> result;
- CGAL::convex_hull_2(points.begin(),points.end(),std::back_inserter(result));
-
- return new CGAL_Nef_polyhedron2(result.begin(),result.end(),CGAL_Nef_polyhedron2::INCLUDED);
-}
-
-#endif
diff --git a/src/glview.cc b/src/glview.cc
index bc287b5..c96fe01 100644
--- a/src/glview.cc
+++ b/src/glview.cc
@@ -27,6 +27,7 @@
#include "GLView.h"
#include "Preferences.h"
#include "renderer.h"
+#include "rendersettings.h"
#include <QApplication>
#include <QWheelEvent>
@@ -39,6 +40,9 @@
#include <QTimer>
#include <QTextEdit>
#include <QVBoxLayout>
+#include <QErrorMessage>
+#include "OpenCSGWarningDialog.h"
+
#include "mathc99.h"
#include <stdio.h>
@@ -133,35 +137,84 @@ void GLView::initializeGL()
fprintf(stderr, "GLEW Error: %s\n", glewGetErrorString(err));
}
+ GLint rbits, gbits, bbits, abits, dbits, sbits;
+ glGetIntegerv(GL_RED_BITS, &rbits);
+ glGetIntegerv(GL_GREEN_BITS, &gbits);
+ glGetIntegerv(GL_BLUE_BITS, &bbits);
+ glGetIntegerv(GL_ALPHA_BITS, &abits);
+ glGetIntegerv(GL_DEPTH_BITS, &dbits);
+ glGetIntegerv(GL_STENCIL_BITS, &sbits);
+
+
+ this->rendererInfo.sprintf("GLEW version %s\n"
+ "OpenGL version %s\n"
+ "%s (%s)\n\n"
+ "RGBA(%d%d%d%d), depth(%d), stencil(%d)\n"
+ "Extensions:\n"
+ "%s\n",
+ glewGetString(GLEW_VERSION),
+ glGetString(GL_RENDERER),
+ glGetString(GL_VENDOR),
+ glGetString(GL_VERSION),
+ rbits, gbits, bbits, abits, dbits, sbits,
+ glGetString(GL_EXTENSIONS));
+// FIXME: glGetString(GL_EXTENSIONS) is deprecated in OpenGL 3.0.
+// Use: glGetIntegerv(GL_NUM_EXTENSIONS, &NumberOfExtensions) and
+// glGetStringi(GL_EXTENSIONS, i)
+
const char *openscad_disable_gl20_env = getenv("OPENSCAD_DISABLE_GL20");
if (openscad_disable_gl20_env && !strcmp(openscad_disable_gl20_env, "0")) {
openscad_disable_gl20_env = NULL;
}
// All OpenGL 2 contexts are OpenCSG capable
- if (GLEW_VERSION_2_0 && !openscad_disable_gl20_env) this->is_opencsg_capable = true;
- // If OpenGL < 2, check for extensions
- else if (GLEW_ARB_framebuffer_object) this->is_opencsg_capable = true;
- else if (GLEW_EXT_framebuffer_object && GLEW_EXT_packed_depth_stencil) {
- this->is_opencsg_capable = true;
+ if (GLEW_VERSION_2_0) {
+ if (!openscad_disable_gl20_env) {
+ this->is_opencsg_capable = true;
+ this->has_shaders = true;
+ }
}
+ // If OpenGL < 2, check for extensions
+ else {
+ if (GLEW_ARB_framebuffer_object) this->is_opencsg_capable = true;
+ else if (GLEW_EXT_framebuffer_object && GLEW_EXT_packed_depth_stencil) {
+ this->is_opencsg_capable = true;
+ }
#ifdef WIN32
- else if (WGLEW_ARB_pbuffer && WGLEW_ARB_pixel_format) this->is_opencsg_capable = true;
+ else if (WGLEW_ARB_pbuffer && WGLEW_ARB_pixel_format) this->is_opencsg_capable = true;
#elif !defined(__APPLE__)
- else if (GLXEW_SGIX_pbuffer && GLXEW_SGIX_fbconfig) this->is_opencsg_capable = true;
+ else if (GLXEW_SGIX_pbuffer && GLXEW_SGIX_fbconfig) this->is_opencsg_capable = true;
#endif
+ }
- if (GLEW_VERSION_2_0 && !openscad_disable_gl20_env) this->has_shaders = true;
-
- if (!this->is_opencsg_capable) {
- opencsg_support = false;
- QSettings settings;
- // FIXME: This should be an OpenCSG capability warning, not an OpenGL 2 warning
- if (settings.value("editor/opengl20_warning_show",true).toBool()) {
+ if (!GLEW_VERSION_2_0 || !this->is_opencsg_capable) {
+ if (Preferences::inst()->getValue("advanced/opencsg_show_warning").toBool()) {
QTimer::singleShot(0, this, SLOT(display_opencsg_warning()));
}
}
if (opencsg_support && this->has_shaders) {
+ /*
+ Uniforms:
+ 1 color1 - face color
+ 2 color2 - edge color
+ 7 xscale
+ 8 yscale
+
+ Attributes:
+ 3 trig
+ 4 pos_b
+ 5 pos_c
+ 6 mask
+
+ Other:
+ 9 width
+ 10 height
+
+ Outputs:
+ tp
+ tr
+ shading
+ */
const char *vs_source =
"uniform float xscale, yscale;\n"
"attribute vec3 pos_b, pos_c;\n"
@@ -187,6 +240,11 @@ void GLView::initializeGL()
" shading = abs(dot(normal, lightDir));\n"
"}\n";
+ /*
+ Inputs:
+ tp && tr - if any components of tp < tr, use color2 (edge color)
+ shading - multiplied by color1. color2 is is without lighting
+ */
const char *fs_source =
"uniform vec4 color1, color2;\n"
"varying vec3 tp, tr, tmp;\n"
@@ -252,9 +310,19 @@ void GLView::initializeGL()
#ifdef ENABLE_OPENCSG
void GLView::display_opencsg_warning()
{
- // data
- QString title = QString("OpenGL context is not OpenCSG capable");
+ OpenCSGWarningDialog *dialog = new OpenCSGWarningDialog(this);
+ QString message;
+ if (this->is_opencsg_capable) {
+ message += "Warning: You may experience OpenCSG rendering errors.\n\n";
+ }
+ else {
+ message += "Warning: Missing OpenGL capabilities for OpenCSG - OpenCSG has been disabled.\n\n";
+ dialog->enableOpenCSGBox->hide();
+ }
+ message += "It is highly recommended to use OpenSCAD on a system with "
+ "OpenGL 2.0 or later.\n"
+ "Your renderer information is as follows:\n";
QString rendererinfo;
rendererinfo.sprintf("GLEW version %s\n"
"%s (%s)\n"
@@ -262,44 +330,13 @@ void GLView::display_opencsg_warning()
glewGetString(GLEW_VERSION),
glGetString(GL_RENDERER), glGetString(GL_VENDOR),
glGetString(GL_VERSION));
+ message += rendererinfo;
- QString message = QString("Warning: Missing OpenGL capabilities for OpenCSG - OpenCSG has been disabled.\n\n"
- "It is highly recommended to use OpenSCAD on a system with OpenGL 2.0, "
- "or support for the framebuffer_object or pbuffer extensions. "
- "Your renderer information is as follows:\n\n%1").arg(rendererinfo);
-
- QString note = QString("Uncheck to hide this message in the future");
-
- // presentation
- QDialog *dialog = new QDialog(this);
- dialog->setSizeGripEnabled(true);
- dialog->setWindowTitle(title);
- dialog->resize(500,300);
-
- QVBoxLayout *layout = new QVBoxLayout(dialog);
- dialog->setLayout(layout);
-
- QTextEdit *textEdit = new QTextEdit(dialog);
- textEdit->setPlainText(message);
- layout->addWidget(textEdit);
-
- QCheckBox *checkbox = new QCheckBox(note,dialog);
- checkbox->setCheckState(Qt::Checked);
- layout->addWidget(checkbox);
-
- QDialogButtonBox *buttonbox =
- new QDialogButtonBox( QDialogButtonBox::Ok, Qt::Horizontal,dialog);
- layout->addWidget(buttonbox);
- buttonbox->button(QDialogButtonBox::Ok)->setFocus();
- buttonbox->button(QDialogButtonBox::Ok)->setDefault(true);
-
- // action
- connect(buttonbox, SIGNAL(accepted()), dialog, SLOT(accept()));
- connect(checkbox, SIGNAL(clicked(bool)),
- Preferences::inst()->openCSGWarningBox, SLOT(setChecked(bool)));
- connect(checkbox, SIGNAL(clicked(bool)),
- Preferences::inst(), SLOT(openCSGWarningChanged(bool)));
+ dialog->setText(message);
+ dialog->enableOpenCSGBox->setChecked(Preferences::inst()->getValue("advanced/enable_opencsg_opengl1x").toBool());
dialog->exec();
+
+ opencsg_support = this->is_opencsg_capable && Preferences::inst()->getValue("advanced/enable_opencsg_opengl1x").toBool();
}
#endif
@@ -344,7 +381,7 @@ void GLView::paintGL()
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
- const QColor &bgcol = Preferences::inst()->color(Preferences::BACKGROUND_COLOR);
+ const QColor &bgcol = RenderSettings::inst()->color(RenderSettings::BACKGROUND_COLOR);
glClearColor(bgcol.redF(), bgcol.greenF(), bgcol.blueF(), 0.0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
@@ -362,7 +399,7 @@ void GLView::paintGL()
if (showcrosshairs)
{
glLineWidth(3);
- const QColor &col = Preferences::inst()->color(Preferences::CROSSHAIR_COLOR);
+ const QColor &col = RenderSettings::inst()->color(RenderSettings::CROSSHAIR_COLOR);
glColor3f(col.redF(), col.greenF(), col.blueF());
glBegin(GL_LINES);
for (double xf = -1; xf <= +1; xf += 2)
@@ -463,7 +500,7 @@ void GLView::paintGL()
// FIXME: This was an attempt to keep contrast with background, but is suboptimal
// (e.g. nearly invisible against a gray background).
int r,g,b;
- bgcol.getRgb(&r, &g, &b);
+// bgcol.getRgb(&r, &g, &b);
glColor3d((255.0-r)/255.0, (255.0-g)/255.0, (255.0-b)/255.0);
glBegin(GL_LINES);
// X Label
diff --git a/src/lexer.l b/src/lexer.l
index 2760b07..c799028 100644
--- a/src/lexer.l
+++ b/src/lexer.l
@@ -200,35 +200,39 @@ QDir sourcepath()
return QDir(parser_source_path);
}
+/*
+ Rules for include <path/file>
+ 1) include <sourcepath/path/file>
+ 2) include <librarydir/path/file>
+ */
void includefile()
{
- if(filename.isEmpty())
- return;
-
- if(filepath.isEmpty()) {
- path_stack.push(sourcepath());
- } else {
- QFileInfo dirinfo(sourcepath(),filepath);
- path_stack.push(dirinfo.dir());
- filepath.clear();
- }
-
- QFileInfo finfo(sourcepath(), filename);
- if (!finfo.exists()) {
- finfo = QFileInfo(QDir(librarydir), filename);
- }
-
- handle_dep(finfo.absoluteFilePath().toStdString());
- yyin = fopen(finfo.absoluteFilePath().toLocal8Bit(), "r");
- if (!yyin) {
- PRINTA("WARNING: Can't open input file `%1'.", filename);
- path_stack.pop();
- return;
- }
- openfiles.append(yyin);
- filename.clear();
-
- yypush_buffer_state(yy_create_buffer( yyin, YY_BUF_SIZE ));
+ if (filename.isEmpty()) return;
+
+ QDir dirinfo(sourcepath());
+ if (!filepath.isEmpty()) {
+ dirinfo.cd(filepath);
+ }
+
+ QFileInfo finfo(dirinfo, filename);
+ if (!finfo.exists()) {
+ finfo = QFileInfo(QFileInfo(QDir(librarydir), filepath).dir(), filename);
+ }
+
+ filepath.clear();
+ path_stack.push(dirinfo);
+
+ handle_dep(finfo.absoluteFilePath().toStdString());
+ yyin = fopen(finfo.absoluteFilePath().toLocal8Bit(), "r");
+ if (!yyin) {
+ PRINTA("WARNING: Can't open input file `%1'.", filename);
+ path_stack.pop();
+ return;
+ }
+ openfiles.append(yyin);
+ filename.clear();
+
+ yypush_buffer_state(yy_create_buffer(yyin, YY_BUF_SIZE));
}
/*!
diff --git a/src/mainwin.cc b/src/mainwin.cc
index c81f2f2..3243847 100644
--- a/src/mainwin.cc
+++ b/src/mainwin.cc
@@ -145,6 +145,7 @@ MainWindow::MainWindow(const QString &filename)
register_builtin(root_ctx);
+ this->openglbox = NULL;
root_module = NULL;
absolute_root_node = NULL;
root_chain = NULL;
@@ -176,7 +177,7 @@ MainWindow::MainWindow(const QString &filename)
editor->setTabStopWidth(30);
#endif
editor->setLineWrapping(true); // Not designable
- setFont("", 0); // Init default font
+ setFont("", 12); // Init default font
this->glview->statusLabel = new QLabel(this);
statusBar()->addWidget(this->glview->statusLabel);
@@ -312,6 +313,7 @@ MainWindow::MainWindow(const QString &filename)
connect(this->helpActionAbout, SIGNAL(triggered()), this, SLOT(helpAbout()));
connect(this->helpActionHomepage, SIGNAL(triggered()), this, SLOT(helpHomepage()));
connect(this->helpActionManual, SIGNAL(triggered()), this, SLOT(helpManual()));
+ connect(this->helpActionOpenGLInfo, SIGNAL(triggered()), this, SLOT(helpOpenGL()));
console->setReadOnly(true);
@@ -1752,6 +1754,18 @@ MainWindow::helpManual()
QDesktopServices::openUrl(QUrl("http://en.wikibooks.org/wiki/OpenSCAD_User_Manual"));
}
+void MainWindow::helpOpenGL()
+{
+ if (!this->openglbox) {
+ this->openglbox = new QMessageBox(QMessageBox::Information,
+ "OpenGL Info", "Detailed OpenGL Info",
+ QMessageBox::Ok, this);
+
+ }
+ this->openglbox->setDetailedText(this->glview->getRendererInfo());
+ this->openglbox->show();
+}
+
/*!
FIXME: In MDI mode, should this be called on both reload functions?
*/
@@ -1822,3 +1836,4 @@ void MainWindow::clearCurrentOutput()
{
set_output_handler(NULL, NULL);
}
+
diff --git a/src/polyset.cc b/src/polyset.cc
index 742e425..481cbec 100644
--- a/src/polyset.cc
+++ b/src/polyset.cc
@@ -108,52 +108,9 @@ static void gl_draw_triangle(GLint *shaderinfo, const Vector3d &p0, const Vector
}
}
-void PolySet::render_surface(colormode_e colormode, csgmode_e csgmode, const Transform3d &m, GLint *shaderinfo) const
+void PolySet::render_surface(csgmode_e csgmode, const Transform3d &m, GLint *shaderinfo) const
{
bool mirrored = m.matrix().determinant() < 0;
-
- if (colormode == COLORMODE_MATERIAL) {
-// FIXME: Reenable/rewrite - don't be dependant on GUI
-// const QColor &col = Preferences::inst()->color(Preferences::OPENCSG_FACE_FRONT_COLOR);
- const QColor &col = QColor(0xf9, 0xd7, 0x2c);
- glColor3f(col.redF(), col.greenF(), col.blueF());
-#ifdef ENABLE_OPENCSG
- if (shaderinfo) {
- glUniform4f(shaderinfo[1], col.redF(), col.greenF(), col.blueF(), 1.0f);
- glUniform4f(shaderinfo[2], 255 / 255.0f, 236 / 255.0f, 94 / 255.0f, 1.0f);
- }
-#endif /* ENABLE_OPENCSG */
- }
- if (colormode == COLORMODE_CUTOUT) {
-// FIXME: Reenable/rewrite - don't be dependant on GUI
-// const QColor &col = Preferences::inst()->color(Preferences::OPENCSG_FACE_BACK_COLOR);
- const QColor &col = QColor(0x9d, 0xcb, 0x51);
- glColor3f(col.redF(), col.greenF(), col.blueF());
-#ifdef ENABLE_OPENCSG
- if (shaderinfo) {
- glUniform4f(shaderinfo[1], 157 / 255.0f, 203 / 255.0f, 81 / 255.0f, 1.0f);
- glUniform4f(shaderinfo[2], 171 / 255.0f, 216 / 255.0f, 86 / 255.0f, 1.0f);
- }
-#endif /* ENABLE_OPENCSG */
- }
- if (colormode == COLORMODE_HIGHLIGHT) {
- glColor4ub(255, 157, 81, 128);
-#ifdef ENABLE_OPENCSG
- if (shaderinfo) {
- glUniform4f(shaderinfo[1], 255 / 255.0f, 157 / 255.0f, 81 / 255.0f, 0.5f);
- glUniform4f(shaderinfo[2], 255 / 255.0f, 171 / 255.0f, 86 / 255.0f, 0.5f);
- }
-#endif /* ENABLE_OPENCSG */
- }
- if (colormode == COLORMODE_BACKGROUND) {
- glColor4ub(180, 180, 180, 128);
-#ifdef ENABLE_OPENCSG
- if (shaderinfo) {
- glUniform4f(shaderinfo[1], 180 / 255.0f, 180 / 255.0f, 180 / 255.0f, 0.5f);
- glUniform4f(shaderinfo[2], 150 / 255.0f, 150 / 255.0f, 150 / 255.0f, 0.5f);
- }
-#endif /* ENABLE_OPENCSG */
- }
#ifdef ENABLE_OPENCSG
if (shaderinfo) {
glUniform1f(shaderinfo[7], shaderinfo[9]);
@@ -248,16 +205,9 @@ void PolySet::render_surface(colormode_e colormode, csgmode_e csgmode, const Tra
}
}
-void PolySet::render_edges(colormode_e colormode, csgmode_e csgmode) const
+void PolySet::render_edges(csgmode_e csgmode) const
{
- if (colormode == COLORMODE_MATERIAL)
- glColor3ub(255, 236, 94);
- if (colormode == COLORMODE_CUTOUT)
- glColor3ub(171, 216, 86);
- if (colormode == COLORMODE_HIGHLIGHT)
- glColor4ub(255, 171, 86, 128);
- if (colormode == COLORMODE_BACKGROUND)
- glColor4ub(150, 150, 150, 128);
+ glDisable(GL_LIGHTING);
if (this->is2d) {
double zbase = csgmode;
for (double z = -zbase/2; z < zbase; z += zbase)
@@ -293,6 +243,7 @@ void PolySet::render_edges(colormode_e colormode, csgmode_e csgmode) const
glEnd();
}
}
+ glEnable(GL_LIGHTING);
}
BoundingBox PolySet::getBoundingBox() const
diff --git a/src/polyset.h b/src/polyset.h
index 57f5057..5698621 100644
--- a/src/polyset.h
+++ b/src/polyset.h
@@ -27,14 +27,6 @@ public:
BoundingBox getBoundingBox() const;
- enum colormode_e {
- COLORMODE_NONE,
- COLORMODE_MATERIAL,
- COLORMODE_CUTOUT,
- COLORMODE_HIGHLIGHT,
- COLORMODE_BACKGROUND
- };
-
enum csgmode_e {
CSGMODE_NONE,
CSGMODE_NORMAL = 1,
@@ -45,8 +37,8 @@ public:
CSGMODE_HIGHLIGHT_DIFFERENCE = 22
};
- void render_surface(colormode_e colormode, csgmode_e csgmode, const Transform3d &m, GLint *shaderinfo = NULL) const;
- void render_edges(colormode_e colormode, csgmode_e csgmode) const;
+ void render_surface(csgmode_e csgmode, const Transform3d &m, GLint *shaderinfo = NULL) const;
+ void render_edges(csgmode_e csgmode) const;
};
#endif
diff --git a/src/primitives.cc b/src/primitives.cc
index 67e19c3..b3fa45f 100644
--- a/src/primitives.cc
+++ b/src/primitives.cc
@@ -327,7 +327,7 @@ PolySet *PrimitiveNode::evaluate_polyset(class PolySetEvaluator *) const
};
int fragments = get_fragments_from_r(r1, fn, fs, fa);
- int rings = fragments/2;
+ int rings = (fragments+1)/2;
// Uncomment the following three lines to enable experimental sphere tesselation
// if (rings % 2 == 0) rings++; // To ensure that the middle ring is at phi == 0 degrees
diff --git a/src/renderer.cc b/src/renderer.cc
new file mode 100644
index 0000000..b791673
--- /dev/null
+++ b/src/renderer.cc
@@ -0,0 +1,66 @@
+#include "renderer.h"
+#include "rendersettings.h"
+#include <QColor>
+
+void Renderer::setColor(const double color[4], GLint *shaderinfo) const
+{
+ QColor col = RenderSettings::inst()->color(RenderSettings::OPENCSG_FACE_FRONT_COLOR);
+ double c[4] = {color[0], color[1], color[2], color[3]};
+ if (c[0] < 0) c[0] = col.redF();
+ if (c[1] < 0) c[1] = col.greenF();
+ if (c[2] < 0) c[2] = col.blueF();
+ if (c[3] < 0) c[3] = col.alphaF();
+ glColor4dv(c);
+ if (shaderinfo) {
+ glUniform4f(shaderinfo[1], c[0], c[1], c[2], c[3]);
+ glUniform4f(shaderinfo[2], (c[0]+1)/2, (c[1]+1)/2, (c[2]+1)/2, 1.0);
+ }
+}
+
+void Renderer::setColor(ColorMode colormode, GLint *shaderinfo) const
+{
+ QColor col;
+ switch (colormode) {
+ case COLORMODE_NONE:
+ return;
+ break;
+ case COLORMODE_MATERIAL:
+ col = RenderSettings::inst()->color(RenderSettings::OPENCSG_FACE_FRONT_COLOR);
+ break;
+ case COLORMODE_CUTOUT:
+ col = RenderSettings::inst()->color(RenderSettings::OPENCSG_FACE_BACK_COLOR);
+ break;
+ case COLORMODE_HIGHLIGHT:
+ col.setRgb(255, 157, 81, 128);
+ break;
+ case COLORMODE_BACKGROUND:
+ col.setRgb(180, 180, 180, 128);
+ break;
+ case COLORMODE_MATERIAL_EDGES:
+ col.setRgb(255, 236, 94);
+ break;
+ case COLORMODE_CUTOUT_EDGES:
+ col.setRgb(171, 216, 86);
+ break;
+ case COLORMODE_HIGHLIGHT_EDGES:
+ col.setRgb(255, 171, 86, 128);
+ break;
+ case COLORMODE_BACKGROUND_EDGES:
+ col.setRgb(150, 150, 150, 128);
+ break;
+ default:
+ break;
+ }
+ float rgba[4];
+ rgba[0] = col.redF();
+ rgba[1] = col.greenF();
+ rgba[2] = col.blueF();
+ rgba[3] = col.alphaF();
+ glColor4fv(rgba);
+#ifdef ENABLE_OPENCSG
+ if (shaderinfo) {
+ glUniform4f(shaderinfo[1], col.redF(), col.greenF(), col.blueF(), 1.0f);
+ glUniform4f(shaderinfo[2], (col.redF()+1)/2, (col.greenF()+1)/2, (col.blueF()+1)/2, 1.0f);
+ }
+#endif
+}
diff --git a/src/renderer.h b/src/renderer.h
index 3c25e98..8deabe8 100644
--- a/src/renderer.h
+++ b/src/renderer.h
@@ -1,11 +1,32 @@
#ifndef RENDERER_H_
#define RENDERER_H_
+#include "system-gl.h"
+
+#ifdef _MSC_VER // NULL
+#include <cstdlib>
+#endif
+
class Renderer
{
public:
virtual ~Renderer() {}
virtual void draw(bool showfaces, bool showedges) const = 0;
+
+ enum ColorMode {
+ COLORMODE_NONE,
+ COLORMODE_MATERIAL,
+ COLORMODE_CUTOUT,
+ COLORMODE_HIGHLIGHT,
+ COLORMODE_BACKGROUND,
+ COLORMODE_MATERIAL_EDGES,
+ COLORMODE_CUTOUT_EDGES,
+ COLORMODE_HIGHLIGHT_EDGES,
+ COLORMODE_BACKGROUND_EDGES
+ };
+
+ virtual void setColor(const double color[4], GLint *shaderinfo = NULL) const;
+ virtual void setColor(ColorMode colormode, GLint *shaderinfo = NULL) const;
};
#endif // RENDERER_H
diff --git a/src/rendersettings.cc b/src/rendersettings.cc
new file mode 100644
index 0000000..ee57c34
--- /dev/null
+++ b/src/rendersettings.cc
@@ -0,0 +1,35 @@
+#include "rendersettings.h"
+
+RenderSettings *RenderSettings::inst(bool erase)
+{
+ static RenderSettings *instance = new RenderSettings;
+ if (erase) {
+ delete instance;
+ instance = NULL;
+ }
+ return instance;
+}
+
+RenderSettings::RenderSettings()
+{
+ this->colors[BACKGROUND_COLOR] = QColor(0xff, 0xff, 0xe5);
+ this->colors[OPENCSG_FACE_FRONT_COLOR] = QColor(0xf9, 0xd7, 0x2c);
+ this->colors[OPENCSG_FACE_BACK_COLOR] = QColor(0x9d, 0xcb, 0x51);
+ this->colors[CGAL_FACE_FRONT_COLOR] = QColor(0xf9, 0xd7, 0x2c);
+ this->colors[CGAL_FACE_BACK_COLOR] = QColor(0x9d, 0xcb, 0x51);
+ this->colors[CGAL_FACE_2D_COLOR] = QColor(0x00, 0xbf, 0x99);
+ this->colors[CGAL_EDGE_FRONT_COLOR] = QColor(0xff, 0x00, 0x00);
+ this->colors[CGAL_EDGE_BACK_COLOR] = QColor(0xff, 0x00, 0x00);
+ this->colors[CGAL_EDGE_2D_COLOR] = QColor(0xff, 0x00, 0x00);
+ this->colors[CROSSHAIR_COLOR] = QColor(0x80, 0x00, 0x00);
+}
+
+QColor RenderSettings::color(RenderColor idx) const
+{
+ return this->colors[idx];
+}
+
+void RenderSettings::setColors(const QMap<RenderColor, QColor> &colors)
+{
+ this->colors = colors;
+}
diff --git a/src/rendersettings.h b/src/rendersettings.h
new file mode 100644
index 0000000..32e56f1
--- /dev/null
+++ b/src/rendersettings.h
@@ -0,0 +1,35 @@
+#ifndef RENDERSETTINGS_H_
+#define RENDERSETTINGS_H_
+
+#include <QColor>
+#include <QMap>
+
+class RenderSettings
+{
+public:
+ static RenderSettings *inst(bool erase = false);
+
+ enum RenderColor {
+ BACKGROUND_COLOR,
+ OPENCSG_FACE_FRONT_COLOR,
+ OPENCSG_FACE_BACK_COLOR,
+ CGAL_FACE_FRONT_COLOR,
+ CGAL_FACE_2D_COLOR,
+ CGAL_FACE_BACK_COLOR,
+ CGAL_EDGE_FRONT_COLOR,
+ CGAL_EDGE_BACK_COLOR,
+ CGAL_EDGE_2D_COLOR,
+ CROSSHAIR_COLOR
+ };
+
+ void setColors(const QMap<RenderColor, QColor> &colors);
+ QColor color(RenderColor idx) const;
+
+private:
+ RenderSettings();
+ ~RenderSettings() {}
+
+ QMap<RenderColor, QColor> colors;
+};
+
+#endif
diff --git a/testdata/scad/features/hull2-tests.scad b/testdata/scad/features/hull2-tests.scad
index 3bea3c5..e656e6a 100644
--- a/testdata/scad/features/hull2-tests.scad
+++ b/testdata/scad/features/hull2-tests.scad
@@ -13,7 +13,6 @@ module concave2dSimple() {
}
}
-// Works correctly
module convex2dHole() {
hull() {
translate([15,10,0]) circle(10);
@@ -24,7 +23,15 @@ module convex2dHole() {
}
}
+module hull2dForLoop() {
+ hull() {
+ for(x = [0,10])
+ for(y=[0,10])
+ translate([x,y]) circle(3);
+ }
+}
convex2dHole();
translate([40,0,0]) convex2dSimple();
translate([0,-20,0]) concave2dSimple();
+translate([30,-25,0]) hull2dForLoop();
diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt
index 75fb99c..d58791c 100644
--- a/tests/CMakeLists.txt
+++ b/tests/CMakeLists.txt
@@ -1,3 +1,5 @@
+# instructions - see ../doc/testing.txt
+
cmake_minimum_required(VERSION 2.8)
if("${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION}.${CMAKE_PATCH_VERSION}" VERSION_GREATER 2.8.3)
# Explicitly use new include policy to avoid globally shadowing included modules
@@ -10,7 +12,7 @@ set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}")
# Build debug build as default
if(NOT CMAKE_BUILD_TYPE)
- set(CMAKE_BUILD_TYPE Debug)
+ set(CMAKE_BUILD_TYPE RelWithDebInfo)
endif()
if(${CMAKE_BUILD_TYPE} STREQUAL "Debug")
@@ -27,11 +29,7 @@ endif()
if(WIN32_STATIC_BUILD)
if(${CMAKE_BUILD_TYPE} STREQUAL "Debug")
- set(EMSG "\nTo build Win32 STATIC OpenSCAD tests you must run")
- set(EMSG "${EMSG} \ncmake .. -DCMAKE_BUILD_TYPE=Release")
- set(EMSG "${EMSG} \nthen replace /MD with /MT in CMakeCache.txt")
- set(EMSG "${EMSG} \ni.e. sed -i s/\\/MD/\\/MT/ CMakeCache.txt")
- set(EMSG "${EMSG} \nthen re-run cmake ..")
+ set(EMSG "\nTo build Win32 STATIC OpenSCAD please see doc/testing.txt")
message(FATAL_ERROR ${EMSG})
endif()
endif()
@@ -61,38 +59,45 @@ if(WIN32)
# you have to pass -DCMAKE_VERBOSE_MAKEFILE=ON to cmake when you run it.
endif()
-
#
# Build test apps
#
# Boost
-#
-# usually it's found automatically, but some systems may need a custom install.
-# in that case, run cmake with -DBOOST_ROOT=/path/to/boost/install
-# (being the same path you passed to boost's --prefix when you built it)
-if (NOT $ENV{MACOSX_DEPLOY_DIR} STREQUAL "")
- set(BOOST_ROOT "$ENV{MACOSX_DEPLOY_DIR}")
+if (NOT $ENV{OPENSCAD_LIBRARIES} STREQUAL "")
+ set(BOOST_ROOT "$ENV{OPENSCAD_LIBRARIES}")
endif()
-if(BOOST_ROOT)
- #set(Boost_DEBUG TRUE)
- set(Boost_NO_SYSTEM_PATHS TRUE)
- set(Boost_ADDITIONAL_VERSIONS "1.47.0")
- find_package( Boost 1.35.0 COMPONENTS thread program_options filesystem system regex )
- if(Boost_FOUND)
- message(STATUS "Boost includes found: " ${Boost_INCLUDE_DIRS})
- message(STATUS "Boost libraries found:")
- foreach(boostlib ${Boost_LIBRARIES})
- message(STATUS " " ${boostlib})
- endforeach()
- include_directories(${Boost_INCLUDE_DIRS})
- else()
- message(STATUS "BOOST_ROOT:" ${BOOST_ROOT})
- message(FATAL_ERROR "BOOST_ROOT specified but no boost found")
- endif()
+if (NOT $ENV{BOOSTDIR} STREQUAL "")
+ set(BOOST_DIR "$ENV{BOOSTDIR}")
+endif()
+
+if (NOT ${BOOST_DIR} STREQUAL "")
+ set(BOOST_ROOT ${BOOST_DIR})
+ message(STATUS "BOOST_ROOT: " ${BOOST_ROOT})
+ set(Boost_NO_SYSTEM_PATHS "TRUE")
+ set(Boost_DEBUG TRUE)
+endif()
+
+
+if (WIN32)
+ set(Boost_USE_STATIC_LIBS TRUE)
+ set(BOOST_STATIC TRUE)
+ set(BOOST_THREAD_USE_LIB TRUE)
+endif()
+
+set(Boost_ADDITIONAL_VERSIONS "1.47.0" "1.46.0")
+find_package( Boost 1.35.0 COMPONENTS thread program_options filesystem system regex )
+if(Boost_FOUND)
+ message(STATUS "Boost includes found: " ${Boost_INCLUDE_DIRS})
+ message(STATUS "Boost libraries found:")
+ foreach(boostlib ${Boost_LIBRARIES})
+ message(STATUS " " ${boostlib})
+ endforeach()
+ include_directories(${Boost_INCLUDE_DIRS})
else()
- message(STATUS "BOOST_ROOT unset. Assuming it will be found automatically.")
+ message(STATUS "BOOST_ROOT: ${BOOST_ROOT}")
+ message(FATAL_ERROR "Boost not found.")
endif()
# Mac OS X
@@ -101,10 +106,20 @@ if(${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
endif(${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
# Qt4
+
+if(${CMAKE_SYSTEM_NAME} MATCHES "FreeBSD")
+ # make /usr/local/include/qt4 come before /usr/local/include (QT4 vs QT3)
+ set(CMAKE_INCLUDE_DIRECTORIES_BEFORE ON)
+endif()
+
find_package(OpenGL)
find_package(Qt4 COMPONENTS QtCore QtGui QtOpenGL REQUIRED)
include(${QT_USE_FILE})
+if(${CMAKE_SYSTEM_NAME} MATCHES "FreeBSD")
+ set(CMAKE_INCLUDE_DIRECTORIES_BEFORE OFF)
+endif()
+
# Eigen2
# Turn off Eigen SIMD optimization
@@ -117,11 +132,13 @@ endif()
if (NOT EIGEN2_INCLUDE_DIR)
find_path(EIGEN2_INCLUDE_DIR
Eigen/Core
- PATHS ENV EIGEN2DIR /opt/local/include/eigen2 /usr/include/eigen2)
+ HINTS $ENV{EIGEN2DIR}
+ PATHS /opt/local/include/eigen2 /usr/include/eigen2)
if (${CMAKE_SYSTEM_NAME} MATCHES "FreeBSD")
find_path(EIGEN2_INCLUDE_DIR
Eigen/Core
- PATHS ENV EIGEN2DIR /usr/local/include/eigen2 )
+ HINTS $ENV{EIGEN2DIR}
+ PATHS /usr/local/include/eigen2 )
endif()
if (NOT EIGEN2_INCLUDE_DIR)
message(FATAL_ERROR "Eigen2 not found")
@@ -132,19 +149,19 @@ endif()
include_directories(${EIGEN2_INCLUDE_DIR})
# OpenCSG
-if (NOT $ENV{OPENCSG_DIR} STREQUAL "")
- set(OPENCSG_DIR "$ENV{OPENCSG_DIR}")
-elseif (NOT $ENV{MACOSX_DEPLOY_DIR} STREQUAL "")
- set(OPENCSG_DIR "$ENV{MACOSX_DEPLOY_DIR}")
+if (NOT $ENV{OPENCSGDIR} STREQUAL "")
+ set(OPENCSG_DIR "$ENV{OPENCSGDIR}")
+elseif (NOT $ENV{OPENSCAD_LIBRARIES} STREQUAL "")
+ set(OPENCSG_DIR "$ENV{OPENSCAD_LIBRARIES}")
endif()
if (NOT OPENCSG_INCLUDE_DIR)
message(STATUS "OPENCSG_DIR: " ${OPENCSG_DIR})
find_path(OPENCSG_INCLUDE_DIR
opencsg.h
- PATHS ${OPENCSG_DIR}/include)
+ HINTS ${OPENCSG_DIR}/include)
find_library(OPENCSG_LIBRARY
opencsg
- PATHS ${OPENCSG_DIR}/lib)
+ HINTS ${OPENCSG_DIR}/lib)
if (NOT OPENCSG_INCLUDE_DIR OR NOT OPENCSG_LIBRARY)
message(FATAL_ERROR "OpenCSG not found")
else()
@@ -156,8 +173,10 @@ include_directories(${OPENCSG_INCLUDE_DIR})
# GLEW
-if (NOT $ENV{MACOSX_DEPLOY_DIR} STREQUAL "")
- set(GLEW_DIR "$ENV{MACOSX_DEPLOY_DIR}")
+if (NOT $ENV{GLEWDIR} STREQUAL "")
+ set(GLEW_DIR "$ENV{GLEWDIR}")
+elseif (NOT $ENV{OPENSCAD_LIBRARIES} STREQUAL "")
+ set(GLEW_DIR "$ENV{OPENSCAD_LIBRARIES}")
endif()
find_package(GLEW REQUIRED)
@@ -185,16 +204,35 @@ BISON_TARGET(OpenSCADparser ../src/parser.y ${CMAKE_CURRENT_BINARY_DIR}/parser_y
ADD_FLEX_BISON_DEPENDENCY(OpenSCADlexer OpenSCADparser)
set_source_files_properties(${CMAKE_CURRENT_BINARY_DIR}/parser_yacc.c PROPERTIES LANGUAGE "CXX")
-if (NOT $ENV{MACOSX_DEPLOY_DIR} STREQUAL "")
- set(CGAL_DIR "$ENV{MACOSX_DEPLOY_DIR}/lib/CGAL")
+# CGAL
+
+if (NOT $ENV{CGALDIR} STREQUAL "")
+ set(CGAL_DIR "$ENV{CGALDIR}")
+elseif (NOT $ENV{OPENSCAD_LIBRARIES} STREQUAL "")
+ set(CGAL_DIR "$ENV{OPENSCAD_LIBRARIES}/lib/CGAL")
set(CMAKE_MODULE_PATH "${CGAL_DIR}")
endif()
+message(STATUS "CGAL_DIR: " ${CGAL_DIR})
find_package(CGAL REQUIRED)
+message(STATUS "CGAL config found in " ${CGAL_USE_FILE} )
+foreach(cgal_incdir ${CGAL_INCLUDE_DIRS})
+ message(STATUS "CGAL include found in " ${cgal_incdir} )
+endforeach()
+message(STATUS "CGAL libraries found in " ${CGAL_LIBRARIES_DIR} )
if("${CGAL_MAJOR_VERSION}.${CGAL_MINOR_VERSION}" VERSION_LESS 3.6)
message(FATAL_ERROR "CGAL >= 3.6 required")
endif()
include_directories(${CGAL_INCLUDE_DIRS})
+# Imagemagick
+
+find_package(ImageMagick COMPONENTS convert)
+if (ImageMagick_convert_FOUND)
+ message(STATUS "ImageMagick convert executable found: " ${ImageMagick_convert_EXECUTABLE})
+else()
+ message(FATAL_ERROR "Couldn't find imagemagick 'convert' program")
+endif()
+
# Internal includes
include_directories(../src)
@@ -239,15 +277,14 @@ set(NOCGAL_SOURCES
set(CGAL_SOURCES
${NOCGAL_SOURCES}
- ../src/CSGTermEvaluator.cc
+ ../src/CSGTermEvaluator.cc
../src/CGAL_Nef_polyhedron.cc
../src/cgalutils.cc
../src/CGALEvaluator.cc
../src/CGALCache.cc
../src/PolySetCGALEvaluator.cc
../src/CGAL_Nef_polyhedron_DxfData.cc
- ../src/cgaladv_minkowski2.cc
- ../src/cgaladv_convexhull2.cc)
+ ../src/cgaladv_minkowski2.cc)
set(COMMON_SOURCES
../src/nodedumper.cc
@@ -262,13 +299,13 @@ set(COMMON_SOURCES
#
if(${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
message(STATUS "Offscreen OpenGL Context - using Apple CGL")
- set(OFFSCREEN_CTX_SOURCE "OffscreenContext.mm")
+ set(OFFSCREEN_CTX_SOURCE "OffscreenContext.mm" CACHE TYPE STRING)
elseif(UNIX)
message(STATUS "Offscreen OpenGL Context - using Unix GLX")
- set(OFFSCREEN_CTX_SOURCE "OffscreenContext.cc")
+ set(OFFSCREEN_CTX_SOURCE "OffscreenContextGLX.cc" CACHE TYPE STRING)
elseif(WIN32)
message(STATUS "Offscreen OpenGL Context - using Microsoft WGL")
- set(OFFSCREEN_CTX_SOURCE "OffscreenContextWGL.cc")
+ set(OFFSCREEN_CTX_SOURCE "OffscreenContextWGL.cc" CACHE TYPE STRING)
endif()
set(OFFSCREEN_SOURCES
@@ -287,6 +324,7 @@ target_link_libraries(tests-cgal tests-common)
add_library(tests-nocgal STATIC ${NOCGAL_SOURCES})
target_link_libraries(tests-nocgal tests-common)
add_library(tests-offscreen STATIC ${OFFSCREEN_SOURCES})
+# set_target_properties(tests-offscreen PROPERTIES COMPILE_FLAGS "-DENABLE_OPENCSG -DENABLE_CGAL ${CGAL_CXX_FLAGS_INIT}")
#
# echotest
@@ -295,11 +333,6 @@ add_executable(echotest echotest.cc)
target_link_libraries(echotest tests-nocgal tests-core ${QT_LIBRARIES} ${OPENGL_LIBRARY} ${Boost_LIBRARIES})
#
-# Yangli Hector Yee's PerceptualDiff code
-# FIXME: Disabled since we use ImageMagick now. Eventually remove this and the files.
-# add_executable(yee_compare yee_compare.cpp lodepng.cpp)
-
-#
# dumptest
#
add_executable(dumptest dumptest.cc)
@@ -327,7 +360,7 @@ target_link_libraries(cgaltest tests-cgal ${CGAL_LIBRARY} ${CGAL_3RD_PARTY_LIBRA
#
# cgalpngtest
#
-add_executable(cgalpngtest cgalpngtest.cc bboxhelp.cc ../src/CGALRenderer.cc)
+add_executable(cgalpngtest cgalpngtest.cc bboxhelp.cc ../src/CGALRenderer.cc ../src/renderer.cc ../src/rendersettings.cc)
set_target_properties(cgalpngtest PROPERTIES COMPILE_FLAGS "-DENABLE_CGAL ${CGAL_CXX_FLAGS_INIT}")
target_link_libraries(cgalpngtest tests-offscreen tests-cgal ${CGAL_LIBRARY} ${CGAL_3RD_PARTY_LIBRARIES} ${QT_LIBRARIES} ${GLEW_LIBRARY} ${COCOA_LIBRARY} ${OPENGL_LIBRARY} ${Boost_LIBRARIES})
@@ -335,7 +368,7 @@ target_link_libraries(cgalpngtest tests-offscreen tests-cgal ${CGAL_LIBRARY} ${C
# opencsgtest
#
-add_executable(opencsgtest opencsgtest.cc csgtestcore.cc ../src/OpenCSGRenderer.cc ../src/ThrownTogetherRenderer.cc)
+add_executable(opencsgtest opencsgtest.cc csgtestcore.cc ../src/OpenCSGRenderer.cc ../src/ThrownTogetherRenderer.cc ../src/renderer.cc ../src/rendersettings.cc)
set_target_properties(opencsgtest PROPERTIES COMPILE_FLAGS "-DENABLE_OPENCSG -DENABLE_CGAL ${CGAL_CXX_FLAGS_INIT}")
target_link_libraries(opencsgtest tests-offscreen tests-cgal ${CGAL_LIBRARY} ${CGAL_3RD_PARTY_LIBRARIES} ${QT_LIBRARIES} ${OPENCSG_LIBRARY} ${GLEW_LIBRARY} ${COCOA_LIBRARY} ${OPENGL_LIBRARY} ${Boost_LIBRARIES})
@@ -343,7 +376,7 @@ target_link_libraries(opencsgtest tests-offscreen tests-cgal ${CGAL_LIBRARY} ${C
# throwntogethertest
#
-add_executable(throwntogethertest throwntogethertest.cc csgtestcore.cc ../src/OpenCSGRenderer.cc ../src/ThrownTogetherRenderer.cc)
+add_executable(throwntogethertest throwntogethertest.cc csgtestcore.cc ../src/OpenCSGRenderer.cc ../src/ThrownTogetherRenderer.cc ../src/renderer.cc ../src/rendersettings.cc)
set_target_properties(throwntogethertest PROPERTIES COMPILE_FLAGS "-DENABLE_OPENCSG -DENABLE_CGAL ${CGAL_CXX_FLAGS_INIT}")
target_link_libraries(throwntogethertest tests-offscreen tests-cgal ${CGAL_LIBRARY} ${CGAL_3RD_PARTY_LIBRARIES} ${QT_LIBRARIES} ${OPENCSG_LIBRARY} ${GLEW_LIBRARY} ${COCOA_LIBRARY} ${OPENGL_LIBRARY} ${Boost_LIBRARIES})
@@ -407,6 +440,12 @@ function(get_test_fullname TESTCMD FILENAME FULLNAME)
set(${FULLNAME} ${${FULLNAME}} PARENT_SCOPE)
endfunction()
+# comparison method to use
+if (NOT $ENV{COMPARATOR} STREQUAL "")
+ set(COMPARATOR "$ENV{COMPARATOR}")
+endif()
+message(STATUS "COMPARATOR: " ${COMPARATOR})
+
#
# This functions adds cmd-line tests given files.
# Files are sent as the parameters following TESTSUFFIX
@@ -437,13 +476,30 @@ macro(add_cmdline_test TESTCMD TESTSUFFIX)
set(CONFARG CONFIGURATIONS)
set(CONFVAL ${FOUNDCONFIGS})
- add_test(NAME ${TEST_FULLNAME} ${CONFARG} ${CONFVAL} COMMAND ${PYTHON_EXECUTABLE} ${tests_SOURCE_DIR}/test_cmdline_tool.py -s ${TESTSUFFIX} ${CMAKE_BINARY_DIR}/${TESTCMD} "${SCADFILE}")
+ add_test(NAME ${TEST_FULLNAME} ${CONFARG} ${CONFVAL} COMMAND ${PYTHON_EXECUTABLE} ${tests_SOURCE_DIR}/test_cmdline_tool.py --comparator=${COMPARATOR} -c ${ImageMagick_convert_EXECUTABLE} -s ${TESTSUFFIX} ${CMAKE_BINARY_DIR}/${TESTCMD} "${SCADFILE}")
endif()
endforeach()
endmacro()
enable_testing()
+# set up custom pretty printing of results
+
+set(INFOCMD "execute_process(COMMAND ${CMAKE_CURRENT_BINARY_DIR}/opencsgtest --info OUTPUT_FILE sysinfo.txt)")
+set(PRETTYCMD "\"${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/test_pretty_print.py --builddir=${CMAKE_CURRENT_BINARY_DIR}\"")
+set(CTEST_CUSTOM_FILE ${CMAKE_CURRENT_BINARY_DIR}/CTestCustom.cmake)
+set(CTEST_CUSTOM_TXT "\n
+ message(\"running 'opencsgtest --info' to generate sysinfo.txt\")\n
+ ${INFOCMD}\n
+ set(CTEST_CUSTOM_POST_TEST ${PRETTYCMD})\n
+")
+file(WRITE ${CTEST_CUSTOM_FILE} ${CTEST_CUSTOM_TXT})
+
+foreach(FILE test_pretty_print.py)
+ configure_file(${CMAKE_CURRENT_SOURCE_DIR}/${FILE}
+ ${CMAKE_CURRENT_BINARY_DIR}/${FILE} COPYONLY)
+endforeach()
+
set_directory_properties(PROPERTIES TEST_INCLUDE_FILE "${CMAKE_SOURCE_DIR}/EnforceConfig.cmake")
# Find all scad files
@@ -493,6 +549,9 @@ disable_tests(dumptest_transform-tests
# Reenable it when this is improved
disable_tests(opencsgtest_child-background)
+# FIXME: This single test takes over an hour to run on a 2.7 GHz P4
+disable_tests(opencsgtest_example006 cgalpngtest_example006)
+
# These tests only makes sense in OpenCSG mode
disable_tests(cgalpngtest_child-background
cgalpngtest_highlight-and-background-modifier
diff --git a/tests/FindBoost.cmake b/tests/FindBoost.cmake
index dfaf660..ea60354 100644
--- a/tests/FindBoost.cmake
+++ b/tests/FindBoost.cmake
@@ -17,8 +17,9 @@
#
# == Using actual libraries from within Boost: ==
#
-# set(Boost_USE_STATIC_LIBS ON)
-# set(Boost_USE_MULTITHREADED ON)
+# set(Boost_USE_STATIC_LIBS ON)
+# set(Boost_USE_MULTITHREADED ON)
+# set(Boost_USE_STATIC_RUNTIME OFF)
# find_package( Boost 1.36.0 COMPONENTS date_time filesystem system ... )
#
# if(Boost_FOUND)
@@ -33,7 +34,7 @@
# Boost that contain header files only (e.g. foreach) you do not need to
# specify COMPONENTS.
#
-# You should provide a minimum version number that should be used. If you provide this
+# You should provide a minimum version number that should be used. If you provide this
# version number and specify the REQUIRED attribute, this module will fail if it
# can't find the specified or a later version. If you specify a version number this is
# automatically put into the considered list of version numbers and thus doesn't need
@@ -63,14 +64,15 @@
# Currently this module searches for the following version numbers:
# 1.33, 1.33.0, 1.33.1, 1.34, 1.34.0, 1.34.1, 1.35, 1.35.0, 1.35.1,
# 1.36, 1.36.0, 1.36.1, 1.37, 1.37.0, 1.38, 1.38.0, 1.39, 1.39.0,
-# 1.40, 1.40.0, 1.41, 1.41.0
+# 1.40, 1.40.0, 1.41, 1.41.0, 1.42, 1.42.0, 1.43, 1.43.0, 1.44, 1.44.0,
+# 1.45, 1.45.0, 1.46, 1.46.0, 1.46.1, 1.47, 1.47.0, 1.48, 1.48.0
#
# NOTE: If you add a new major 1.x version in Boost_ADDITIONAL_VERSIONS you should
# add both 1.x and 1.x.0 as shown above. Official Boost include directories
# omit the 3rd version number from include paths if it is 0 although not all
# binary Boost releases do so.
#
-# SET(Boost_ADDITIONAL_VERSIONS "1.78" "1.78.0" "1.79" "1.79.0")
+# set(Boost_ADDITIONAL_VERSIONS "1.78" "1.78.0" "1.79" "1.79.0")
#
# ===================================== ============= ========================
#
@@ -84,6 +86,43 @@
# Boost_USE_STATIC_LIBS Can be set to ON to force the use of the static
# boost libraries. Defaults to OFF.
#
+# Boost_NO_SYSTEM_PATHS Set to TRUE to suppress searching in system
+# paths (or other locations outside of BOOST_ROOT
+# or BOOST_INCLUDEDIR). Useful when specifying
+# BOOST_ROOT. Defaults to OFF.
+# [Since CMake 2.8.3]
+#
+# Boost_NO_BOOST_CMAKE Do not do a find_package call in config mode
+# before searching for a regular boost install.
+# This will avoid finding boost-cmake installs.
+# Defaults to OFF.
+# [Since CMake 2.8.6]
+#
+# Boost_USE_STATIC_RUNTIME If enabled, searches for boost libraries
+# linked against a static C++ standard library
+# ('s' ABI tag). This option should be set to
+# ON or OFF because the default behavior
+# if not specified is platform dependent
+# for backwards compatibility.
+# [Since CMake 2.8.3]
+#
+# Boost_USE_DEBUG_PYTHON If enabled, searches for boost libraries
+# compiled against a special debug build of
+# Python ('y' ABI tag). Defaults to OFF.
+# [Since CMake 2.8.3]
+#
+# Boost_USE_STLPORT If enabled, searches for boost libraries
+# compiled against the STLPort standard
+# library ('p' ABI tag). Defaults to OFF.
+# [Since CMake 2.8.3]
+#
+# Boost_USE_STLPORT_DEPRECATED_NATIVE_IOSTREAMS
+# If enabled, searches for boost libraries
+# compiled against the deprecated STLPort
+# "native iostreams" feature ('n' ABI tag).
+# Defaults to OFF.
+# [Since CMake 2.8.3]
+#
# Other Variables used by this module which you may want to set.
#
# Boost_ADDITIONAL_VERSIONS A list of version numbers to use for searching
@@ -101,17 +140,58 @@
# unless this is set to TRUE or the REQUIRED
# keyword is specified in find_package().
# [Since CMake 2.8.0]
-#
+#
# Boost_COMPILER Set this to the compiler suffix used by Boost
# (e.g. "-gcc43") if FindBoost has problems finding
# the proper Boost installation
#
+# Boost_THREADAPI When building boost.thread, sometimes the name of the
+# library contains an additional "pthread" or "win32"
+# string known as the threadapi. This can happen when
+# compiling against pthreads on Windows or win32 threads
+# on Cygwin. You may specify this variable and if set
+# when FindBoost searches for the Boost threading library
+# it will first try to match the threadapi you specify.
+# For Example: libboost_thread_win32-mgw45-mt-1_43.a
+# might be found if you specified "win32" here before
+# falling back on libboost_thread-mgw45-mt-1_43.a.
+# [Since CMake 2.8.3]
+#
+# Boost_REALPATH Resolves symbolic links for discovered boost libraries
+# to assist with packaging. For example, instead of
+# Boost_SYSTEM_LIBRARY_RELEASE being resolved to
+# "/usr/lib/libboost_system.so" it would be
+# "/usr/lib/libboost_system.so.1.42.0" instead.
+# This does not affect linking and should not be
+# enabled unless the user needs this information.
+# [Since CMake 2.8.3]
+#
+
+
+#
# These last three variables are available also as environment variables:
+# Also, note they are completely UPPERCASE, except Boost_DIR.
#
-# BOOST_ROOT or BOOSTROOT The preferred installation prefix for searching for
-# Boost. Set this if the module has problems finding
+# Boost_DIR or The preferred installation prefix for searching for
+# BOOST_ROOT or BOOSTROOT Boost. Set this if the module has problems finding
# the proper Boost installation.
#
+# Note that Boost_DIR behaves exactly as <package>_DIR
+# variables are documented to behave in find_package's
+# Config mode. That is, if it is set as a -D argument
+# to CMake, it must point to the location of the
+# BoostConfig.cmake or Boost-config.cmake file. If it
+# is set as an environment variable, it must point to
+# the root of the boost installation. BOOST_ROOT and
+# BOOSTROOT, on the other hand, will point to the root
+# in either case.
+#
+# To prevent falling back on the system paths, set
+# Boost_NO_SYSTEM_PATHS to true.
+#
+# To avoid finding boost-cmake installations, set
+# Boost_NO_BOOST_CMAKE to true.
+#
# BOOST_INCLUDEDIR Set this to the include directory of Boost, if the
# module has problems finding the proper Boost installation
#
@@ -165,7 +245,7 @@
# Copyright 2007 Wengo
# Copyright 2007 Mike Jackson
# Copyright 2008 Andreas Pakulat <apaku@gmx.de>
-# Copyright 2008-2009 Philip Lowman <philip@yhbt.com>
+# Copyright 2008-2010 Philip Lowman <philip@yhbt.com>
#
# Distributed under the OSI-approved BSD License (the "License");
# see accompanying file Copyright.txt for details.
@@ -174,9 +254,46 @@
# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
# See the License for more information.
#=============================================================================
-# (To distributed this file outside of CMake, substitute the full
+# (To distribute this file outside of CMake, substitute the full
# License text for the above reference.)
+
+#-------------------------------------------------------------------------------
+# Before we go searching, check whether boost-cmake is avaialble, unless the
+# user specifically asked NOT to search for boost-cmake.
+#
+# If Boost_DIR is set, this behaves as any find_package call would. If not,
+# it looks at BOOST_ROOT and BOOSTROOT to find Boost.
+#
+if (NOT Boost_NO_BOOST_CMAKE)
+ # If Boost_DIR is not set, look for BOOSTROOT and BOOST_ROOT as alternatives,
+ # since these are more conventional for Boost.
+ if ("$ENV{Boost_DIR}" STREQUAL "")
+ if (NOT "$ENV{BOOST_ROOT}" STREQUAL "")
+ set(ENV{Boost_DIR} $ENV{BOOST_ROOT})
+ elseif (NOT "$ENV{BOOSTROOT}" STREQUAL "")
+ set(ENV{Boost_DIR} $ENV{BOOSTROOT})
+ endif()
+ endif()
+
+ # Do the same find_package call but look specifically for the CMake version.
+ # Note that args are passed in the Boost_FIND_xxxxx variables, so there is no
+ # need to delegate them to this find_package call.
+ find_package(Boost QUIET NO_MODULE)
+
+ # If we found boost-cmake, then we're done. Print out what we found.
+ # Otherwise let the rest of the module try to find it.
+ if (Boost_FOUND)
+ message("Boost ${Boost_FIND_VERSION} found.")
+ if (Boost_FIND_COMPONENTS)
+ message("Found Boost components:")
+ message(" ${Boost_FIND_COMPONENTS}")
+ endif()
+ return()
+ endif()
+endif()
+
+
#-------------------------------------------------------------------------------
# FindBoost functions & macros
#
@@ -192,59 +309,65 @@
# And ELSE/ENDIF pairs were removed for readability.
#########################################################################
-MACRO (_Boost_ADJUST_LIB_VARS basename)
- IF (Boost_INCLUDE_DIR )
- IF (Boost_${basename}_LIBRARY_DEBUG AND Boost_${basename}_LIBRARY_RELEASE)
+macro(_Boost_ADJUST_LIB_VARS basename)
+ if(Boost_INCLUDE_DIR )
+ if(Boost_${basename}_LIBRARY_DEBUG AND Boost_${basename}_LIBRARY_RELEASE)
# if the generator supports configuration types then set
# optimized and debug libraries, or if the CMAKE_BUILD_TYPE has a value
- IF (CMAKE_CONFIGURATION_TYPES OR CMAKE_BUILD_TYPE)
- SET(Boost_${basename}_LIBRARY optimized ${Boost_${basename}_LIBRARY_RELEASE} debug ${Boost_${basename}_LIBRARY_DEBUG})
- ELSE()
+ if(CMAKE_CONFIGURATION_TYPES OR CMAKE_BUILD_TYPE)
+ set(Boost_${basename}_LIBRARY optimized ${Boost_${basename}_LIBRARY_RELEASE} debug ${Boost_${basename}_LIBRARY_DEBUG})
+ else()
# if there are no configuration types and CMAKE_BUILD_TYPE has no value
# then just use the release libraries
- SET(Boost_${basename}_LIBRARY ${Boost_${basename}_LIBRARY_RELEASE} )
- ENDIF()
+ set(Boost_${basename}_LIBRARY ${Boost_${basename}_LIBRARY_RELEASE} )
+ endif()
# FIXME: This probably should be set for both cases
- SET(Boost_${basename}_LIBRARIES optimized ${Boost_${basename}_LIBRARY_RELEASE} debug ${Boost_${basename}_LIBRARY_DEBUG})
- ENDIF()
+ set(Boost_${basename}_LIBRARIES optimized ${Boost_${basename}_LIBRARY_RELEASE} debug ${Boost_${basename}_LIBRARY_DEBUG})
+ endif()
# if only the release version was found, set the debug variable also to the release version
- IF (Boost_${basename}_LIBRARY_RELEASE AND NOT Boost_${basename}_LIBRARY_DEBUG)
- SET(Boost_${basename}_LIBRARY_DEBUG ${Boost_${basename}_LIBRARY_RELEASE})
- SET(Boost_${basename}_LIBRARY ${Boost_${basename}_LIBRARY_RELEASE})
- SET(Boost_${basename}_LIBRARIES ${Boost_${basename}_LIBRARY_RELEASE})
- ENDIF()
+ if(Boost_${basename}_LIBRARY_RELEASE AND NOT Boost_${basename}_LIBRARY_DEBUG)
+ set(Boost_${basename}_LIBRARY_DEBUG ${Boost_${basename}_LIBRARY_RELEASE})
+ set(Boost_${basename}_LIBRARY ${Boost_${basename}_LIBRARY_RELEASE})
+ set(Boost_${basename}_LIBRARIES ${Boost_${basename}_LIBRARY_RELEASE})
+ endif()
# if only the debug version was found, set the release variable also to the debug version
- IF (Boost_${basename}_LIBRARY_DEBUG AND NOT Boost_${basename}_LIBRARY_RELEASE)
- SET(Boost_${basename}_LIBRARY_RELEASE ${Boost_${basename}_LIBRARY_DEBUG})
- SET(Boost_${basename}_LIBRARY ${Boost_${basename}_LIBRARY_DEBUG})
- SET(Boost_${basename}_LIBRARIES ${Boost_${basename}_LIBRARY_DEBUG})
- ENDIF()
-
- IF (Boost_${basename}_LIBRARY)
+ if(Boost_${basename}_LIBRARY_DEBUG AND NOT Boost_${basename}_LIBRARY_RELEASE)
+ set(Boost_${basename}_LIBRARY_RELEASE ${Boost_${basename}_LIBRARY_DEBUG})
+ set(Boost_${basename}_LIBRARY ${Boost_${basename}_LIBRARY_DEBUG})
+ set(Boost_${basename}_LIBRARIES ${Boost_${basename}_LIBRARY_DEBUG})
+ endif()
+
+ # If the debug & release library ends up being the same, omit the keywords
+ if(${Boost_${basename}_LIBRARY_RELEASE} STREQUAL ${Boost_${basename}_LIBRARY_DEBUG})
+ set(Boost_${basename}_LIBRARY ${Boost_${basename}_LIBRARY_RELEASE} )
+ set(Boost_${basename}_LIBRARIES ${Boost_${basename}_LIBRARY_RELEASE} )
+ endif()
+
+ if(Boost_${basename}_LIBRARY)
set(Boost_${basename}_LIBRARY ${Boost_${basename}_LIBRARY} CACHE FILEPATH "The Boost ${basename} library")
# Remove superfluous "debug" / "optimized" keywords from
# Boost_LIBRARY_DIRS
- FOREACH(_boost_my_lib ${Boost_${basename}_LIBRARY})
- GET_FILENAME_COMPONENT(_boost_my_lib_path "${_boost_my_lib}" PATH)
- LIST(APPEND Boost_LIBRARY_DIRS ${_boost_my_lib_path})
- ENDFOREACH()
- LIST(REMOVE_DUPLICATES Boost_LIBRARY_DIRS)
+ foreach(_boost_my_lib ${Boost_${basename}_LIBRARY})
+ get_filename_component(_boost_my_lib_path "${_boost_my_lib}" PATH)
+ list(APPEND Boost_LIBRARY_DIRS ${_boost_my_lib_path})
+ endforeach()
+ list(REMOVE_DUPLICATES Boost_LIBRARY_DIRS)
set(Boost_LIBRARY_DIRS ${Boost_LIBRARY_DIRS} CACHE FILEPATH "Boost library directory")
- SET(Boost_${basename}_FOUND ON CACHE INTERNAL "Whether the Boost ${basename} library found")
- ENDIF(Boost_${basename}_LIBRARY)
+ set(Boost_${basename}_FOUND ON CACHE INTERNAL "Whether the Boost ${basename} library found")
+ endif(Boost_${basename}_LIBRARY)
- ENDIF (Boost_INCLUDE_DIR )
+ endif(Boost_INCLUDE_DIR )
# Make variables changeble to the advanced user
- MARK_AS_ADVANCED(
+ mark_as_advanced(
Boost_${basename}_LIBRARY
Boost_${basename}_LIBRARY_RELEASE
Boost_${basename}_LIBRARY_DEBUG
)
-ENDMACRO (_Boost_ADJUST_LIB_VARS)
+endmacro(_Boost_ADJUST_LIB_VARS)
#-------------------------------------------------------------------------------
@@ -252,17 +375,17 @@ ENDMACRO (_Boost_ADJUST_LIB_VARS)
# Runs compiler with "-dumpversion" and parses major/minor
# version with a regex.
#
-FUNCTION(_Boost_COMPILER_DUMPVERSION _OUTPUT_VERSION)
+function(_Boost_COMPILER_DUMPVERSION _OUTPUT_VERSION)
- EXEC_PROGRAM(${CMAKE_CXX_COMPILER}
+ exec_program(${CMAKE_CXX_COMPILER}
ARGS ${CMAKE_CXX_COMPILER_ARG1} -dumpversion
OUTPUT_VARIABLE _boost_COMPILER_VERSION
)
- STRING(REGEX REPLACE "([0-9])\\.([0-9])(\\.[0-9])?" "\\1\\2"
+ string(REGEX REPLACE "([0-9])\\.([0-9])(\\.[0-9])?" "\\1\\2"
_boost_COMPILER_VERSION ${_boost_COMPILER_VERSION})
- SET(${_OUTPUT_VERSION} ${_boost_COMPILER_VERSION} PARENT_SCOPE)
-ENDFUNCTION()
+ set(${_OUTPUT_VERSION} ${_boost_COMPILER_VERSION} PARENT_SCOPE)
+endfunction()
#
# A convenience function for marking desired components
@@ -276,16 +399,45 @@ function(_Boost_MARK_COMPONENTS_FOUND _yes_or_no)
endfunction()
#
+# Take a list of libraries with "thread" in it
+# and prepend duplicates with "thread_${Boost_THREADAPI}"
+# at the front of the list
+#
+function(_Boost_PREPEND_LIST_WITH_THREADAPI _output)
+ set(_orig_libnames ${ARGN})
+ string(REPLACE "thread" "thread_${Boost_THREADAPI}" _threadapi_libnames ${_orig_libnames})
+ set(${_output} ${_threadapi_libnames} ${_orig_libnames} PARENT_SCOPE)
+endfunction()
+
+#
+# If a library is found, replace its cache entry with its REALPATH
+#
+function(_Boost_SWAP_WITH_REALPATH _library _docstring)
+ if(${_library})
+ get_filename_component(_boost_filepathreal ${${_library}} REALPATH)
+ unset(${_library} CACHE)
+ set(${_library} ${_boost_filepathreal} CACHE FILEPATH "${_docstring}")
+ endif()
+endfunction()
+
+function(_Boost_CHECK_SPELLING _var)
+ if(${_var})
+ string(TOUPPER ${_var} _var_UC)
+ message(FATAL_ERROR "ERROR: ${_var} is not the correct spelling. The proper spelling is ${_var_UC}.")
+ endif()
+endfunction()
+
+#
# End functions/macros
-#
+#
#-------------------------------------------------------------------------------
-IF(NOT DEFINED Boost_USE_MULTITHREADED)
- SET(Boost_USE_MULTITHREADED TRUE)
-ENDIF()
+if(NOT DEFINED Boost_USE_MULTITHREADED)
+ set(Boost_USE_MULTITHREADED TRUE)
+endif()
if(Boost_FIND_VERSION_EXACT)
# The version may appear in a directory with or without the patch
@@ -297,6 +449,8 @@ else(Boost_FIND_VERSION_EXACT)
# The user has not requested an exact version. Among known
# versions, find those that are acceptable to the user request.
set(_Boost_KNOWN_VERSIONS ${Boost_ADDITIONAL_VERSIONS}
+ "1.48.0" "1.48" "1.47.0" "1.47" "1.46.1"
+ "1.46.0" "1.46" "1.45.0" "1.45" "1.44.0" "1.44" "1.43.0" "1.43" "1.42.0" "1.42"
"1.41.0" "1.41" "1.40.0" "1.40" "1.39.0" "1.39" "1.38.0" "1.38" "1.37.0" "1.37"
"1.36.1" "1.36.0" "1.36" "1.35.1" "1.35.0" "1.35" "1.34.1" "1.34.0"
"1.34" "1.33.1" "1.33.0" "1.33")
@@ -325,49 +479,47 @@ endif(Boost_FIND_VERSION_EXACT)
# Boost.
set(Boost_ERROR_REASON)
-SET( _boost_IN_CACHE TRUE)
-IF(Boost_INCLUDE_DIR)
+set( _boost_IN_CACHE TRUE)
+if(Boost_INCLUDE_DIR)
# On versions < 1.35, remove the System library from the considered list
# since it wasn't added until 1.35.
if(Boost_VERSION AND Boost_FIND_COMPONENTS)
- math(EXPR _boost_maj "${Boost_VERSION} / 100000")
- math(EXPR _boost_min "${Boost_VERSION} / 100 % 1000")
- if(${_boost_maj}.${_boost_min} VERSION_LESS 1.35)
+ if(Boost_VERSION LESS 103500)
list(REMOVE_ITEM Boost_FIND_COMPONENTS system)
endif()
endif()
- FOREACH(COMPONENT ${Boost_FIND_COMPONENTS})
- STRING(TOUPPER ${COMPONENT} COMPONENT)
- IF(NOT Boost_${COMPONENT}_FOUND)
- SET( _boost_IN_CACHE FALSE)
- ENDIF(NOT Boost_${COMPONENT}_FOUND)
- ENDFOREACH(COMPONENT)
-ELSE(Boost_INCLUDE_DIR)
- SET( _boost_IN_CACHE FALSE)
-ENDIF(Boost_INCLUDE_DIR)
-
-IF (_boost_IN_CACHE)
+ foreach(COMPONENT ${Boost_FIND_COMPONENTS})
+ string(TOUPPER ${COMPONENT} COMPONENT)
+ if(NOT Boost_${COMPONENT}_FOUND)
+ set( _boost_IN_CACHE FALSE)
+ endif(NOT Boost_${COMPONENT}_FOUND)
+ endforeach(COMPONENT)
+else(Boost_INCLUDE_DIR)
+ set( _boost_IN_CACHE FALSE)
+endif(Boost_INCLUDE_DIR)
+
+if(_boost_IN_CACHE)
# in cache already
- SET(Boost_FOUND TRUE)
- FOREACH(COMPONENT ${Boost_FIND_COMPONENTS})
- STRING(TOUPPER ${COMPONENT} COMPONENT)
+ set(Boost_FOUND TRUE)
+ foreach(COMPONENT ${Boost_FIND_COMPONENTS})
+ string(TOUPPER ${COMPONENT} COMPONENT)
_Boost_ADJUST_LIB_VARS( ${COMPONENT} )
- SET(Boost_LIBRARIES ${Boost_LIBRARIES} ${Boost_${COMPONENT}_LIBRARY})
- ENDFOREACH(COMPONENT)
- SET(Boost_INCLUDE_DIRS ${Boost_INCLUDE_DIR})
- IF(Boost_VERSION AND NOT "${Boost_VERSION}" STREQUAL "0")
- MATH(EXPR Boost_MAJOR_VERSION "${Boost_VERSION} / 100000")
- MATH(EXPR Boost_MINOR_VERSION "${Boost_VERSION} / 100 % 1000")
- MATH(EXPR Boost_SUBMINOR_VERSION "${Boost_VERSION} % 100")
- ENDIF(Boost_VERSION AND NOT "${Boost_VERSION}" STREQUAL "0")
+ set(Boost_LIBRARIES ${Boost_LIBRARIES} ${Boost_${COMPONENT}_LIBRARY})
+ endforeach(COMPONENT)
+ set(Boost_INCLUDE_DIRS ${Boost_INCLUDE_DIR})
+ if(Boost_VERSION AND NOT "${Boost_VERSION}" STREQUAL "0")
+ math(EXPR Boost_MAJOR_VERSION "${Boost_VERSION} / 100000")
+ math(EXPR Boost_MINOR_VERSION "${Boost_VERSION} / 100 % 1000")
+ math(EXPR Boost_SUBMINOR_VERSION "${Boost_VERSION} % 100")
+ endif(Boost_VERSION AND NOT "${Boost_VERSION}" STREQUAL "0")
if(Boost_DEBUG)
message(STATUS "[ ${CMAKE_CURRENT_LIST_FILE}:${CMAKE_CURRENT_LIST_LINE} ] "
"boost ${Boost_MAJOR_VERSION}.${Boost_MINOR_VERSION}.${Boost_SUBMINOR_VERSION} "
- "is already in the cache. For debugging messages, please clear the cache.")
+ "is already in the cache. To view debugging messages, please clear the cache.")
endif()
-ELSE (_boost_IN_CACHE)
+else(_boost_IN_CACHE)
# Need to search for boost
if(Boost_DEBUG)
message(STATUS "[ ${CMAKE_CURRENT_LIST_FILE}:${CMAKE_CURRENT_LIST_LINE} ] "
@@ -379,9 +531,15 @@ ELSE (_boost_IN_CACHE)
"Boost_USE_MULTITHREADED = ${Boost_USE_MULTITHREADED}")
message(STATUS "[ ${CMAKE_CURRENT_LIST_FILE}:${CMAKE_CURRENT_LIST_LINE} ] "
"Boost_USE_STATIC_LIBS = ${Boost_USE_STATIC_LIBS}")
+ message(STATUS "[ ${CMAKE_CURRENT_LIST_FILE}:${CMAKE_CURRENT_LIST_LINE} ] "
+ "Boost_USE_STATIC_RUNTIME = ${Boost_USE_STATIC_RUNTIME}")
+ message(STATUS "[ ${CMAKE_CURRENT_LIST_FILE}:${CMAKE_CURRENT_LIST_LINE} ] "
+ "Boost_ADDITIONAL_VERSIONS = ${Boost_ADDITIONAL_VERSIONS}")
+ message(STATUS "[ ${CMAKE_CURRENT_LIST_FILE}:${CMAKE_CURRENT_LIST_LINE} ] "
+ "Boost_NO_SYSTEM_PATHS = ${Boost_NO_SYSTEM_PATHS}")
endif()
- IF(WIN32)
+ if(WIN32)
# In windows, automatic linking is performed, so you do not have
# to specify the libraries. If you are linking to a dynamic
# runtime, then you can choose to link to either a static or a
@@ -390,20 +548,20 @@ ELSE (_boost_IN_CACHE)
# BOOST_WHATEVER_DYN_LINK to force Boost library "whatever" to be
# linked dynamically. Alternatively you can force all Boost
# libraries to dynamic link by defining BOOST_ALL_DYN_LINK.
-
+
# This feature can be disabled for Boost library "whatever" by
# defining BOOST_WHATEVER_NO_LIB, or for all of Boost by defining
# BOOST_ALL_NO_LIB.
-
+
# If you want to observe which libraries are being linked against
# then defining BOOST_LIB_DIAGNOSTIC will cause the auto-linking
# code to emit a #pragma message each time a library is selected
# for linking.
- SET(Boost_LIB_DIAGNOSTIC_DEFINITIONS
+ set(Boost_LIB_DIAGNOSTIC_DEFINITIONS
"-DBOOST_LIB_DIAGNOSTIC" CACHE STRING "Boost diagnostic define")
- ENDIF(WIN32)
+ endif(WIN32)
- SET(_boost_INCLUDE_SEARCH_DIRS
+ set(_boost_INCLUDE_SEARCH_DIRS_SYSTEM
C:/boost/include
C:/boost
"$ENV{ProgramFiles}/boost/include"
@@ -411,29 +569,38 @@ ELSE (_boost_IN_CACHE)
/sw/local/include
)
+ _Boost_CHECK_SPELLING(Boost_ROOT)
+ _Boost_CHECK_SPELLING(Boost_LIBRARYDIR)
+ _Boost_CHECK_SPELLING(Boost_INCLUDEDIR)
+
+ # If BOOST_ROOT was defined in the environment, use it.
+ if (NOT BOOST_ROOT AND NOT $ENV{Boost_DIR} STREQUAL "")
+ set(BOOST_ROOT $ENV{Boost_DIR})
+ endif()
+
# If BOOST_ROOT was defined in the environment, use it.
if (NOT BOOST_ROOT AND NOT $ENV{BOOST_ROOT} STREQUAL "")
set(BOOST_ROOT $ENV{BOOST_ROOT})
- endif(NOT BOOST_ROOT AND NOT $ENV{BOOST_ROOT} STREQUAL "")
+ endif()
# If BOOSTROOT was defined in the environment, use it.
if (NOT BOOST_ROOT AND NOT $ENV{BOOSTROOT} STREQUAL "")
set(BOOST_ROOT $ENV{BOOSTROOT})
- endif(NOT BOOST_ROOT AND NOT $ENV{BOOSTROOT} STREQUAL "")
+ endif()
# If BOOST_INCLUDEDIR was defined in the environment, use it.
- IF( NOT $ENV{BOOST_INCLUDEDIR} STREQUAL "" )
+ if( NOT $ENV{BOOST_INCLUDEDIR} STREQUAL "" )
set(BOOST_INCLUDEDIR $ENV{BOOST_INCLUDEDIR})
- ENDIF( NOT $ENV{BOOST_INCLUDEDIR} STREQUAL "" )
-
+ endif()
+
# If BOOST_LIBRARYDIR was defined in the environment, use it.
- IF( NOT $ENV{BOOST_LIBRARYDIR} STREQUAL "" )
+ if( NOT $ENV{BOOST_LIBRARYDIR} STREQUAL "" )
set(BOOST_LIBRARYDIR $ENV{BOOST_LIBRARYDIR})
- ENDIF( NOT $ENV{BOOST_LIBRARYDIR} STREQUAL "" )
-
- IF( BOOST_ROOT )
+ endif()
+
+ if( BOOST_ROOT )
file(TO_CMAKE_PATH ${BOOST_ROOT} BOOST_ROOT)
- ENDIF( BOOST_ROOT )
+ endif()
if(Boost_DEBUG)
message(STATUS "[ ${CMAKE_CURRENT_LIST_FILE}:${CMAKE_CURRENT_LIST_LINE} ] "
@@ -448,50 +615,54 @@ ELSE (_boost_IN_CACHE)
"_boost_TEST_VERSIONS = ${_boost_TEST_VERSIONS}")
endif()
- IF( BOOST_ROOT )
- SET(_boost_INCLUDE_SEARCH_DIRS
- ${BOOST_ROOT}/include
+ if( Boost_NO_SYSTEM_PATHS)
+ set(_boost_FIND_OPTIONS NO_CMAKE_SYSTEM_PATH)
+ else()
+ set(_boost_INCLUDE_SEARCH_DIRS ${_boost_INCLUDE_SEARCH_DIRS_SYSTEM})
+ endif()
+
+ if( BOOST_ROOT )
+ set(_boost_INCLUDE_SEARCH_DIRS
+ ${BOOST_ROOT}/include
${BOOST_ROOT}
${_boost_INCLUDE_SEARCH_DIRS})
- ENDIF( BOOST_ROOT )
+ endif()
- IF( BOOST_INCLUDEDIR )
+ # prepend BOOST_INCLUDEDIR to search path if specified
+ if( BOOST_INCLUDEDIR )
file(TO_CMAKE_PATH ${BOOST_INCLUDEDIR} BOOST_INCLUDEDIR)
- SET(_boost_INCLUDE_SEARCH_DIRS
+ set(_boost_INCLUDE_SEARCH_DIRS
${BOOST_INCLUDEDIR} ${_boost_INCLUDE_SEARCH_DIRS})
- ENDIF( BOOST_INCLUDEDIR )
+ endif( BOOST_INCLUDEDIR )
# ------------------------------------------------------------------------
- # Search for Boost include DIR
+ # Search for Boost include DIR
# ------------------------------------------------------------------------
# Try to find Boost by stepping backwards through the Boost versions
# we know about.
- IF( NOT Boost_INCLUDE_DIR )
+ if( NOT Boost_INCLUDE_DIR )
# Build a list of path suffixes for each version.
- SET(_boost_PATH_SUFFIXES)
- FOREACH(_boost_VER ${_boost_TEST_VERSIONS})
+ set(_boost_PATH_SUFFIXES)
+ foreach(_boost_VER ${_boost_TEST_VERSIONS})
# Add in a path suffix, based on the required version, ideally
# we could read this from version.hpp, but for that to work we'd
# need to know the include dir already
set(_boost_BOOSTIFIED_VERSION)
# Transform 1.35 => 1_35 and 1.36.0 => 1_36_0
- IF(_boost_VER MATCHES "[0-9]+\\.[0-9]+\\.[0-9]+")
- STRING(REGEX REPLACE "([0-9]+)\\.([0-9]+)\\.([0-9]+)" "\\1_\\2_\\3"
+ if(_boost_VER MATCHES "[0-9]+\\.[0-9]+\\.[0-9]+")
+ string(REGEX REPLACE "([0-9]+)\\.([0-9]+)\\.([0-9]+)" "\\1_\\2_\\3"
_boost_BOOSTIFIED_VERSION ${_boost_VER})
- ELSEIF(_boost_VER MATCHES "[0-9]+\\.[0-9]+")
- STRING(REGEX REPLACE "([0-9]+)\\.([0-9]+)" "\\1_\\2"
+ elseif(_boost_VER MATCHES "[0-9]+\\.[0-9]+")
+ string(REGEX REPLACE "([0-9]+)\\.([0-9]+)" "\\1_\\2"
_boost_BOOSTIFIED_VERSION ${_boost_VER})
- ENDIF()
-
- list(APPEND _boost_PATH_SUFFIXES "boost-${_boost_BOOSTIFIED_VERSION}")
- if(WIN32)
- # For BoostPro's underscores (and others?)
- list(APPEND _boost_PATH_SUFFIXES "boost_${_boost_BOOSTIFIED_VERSION}")
endif()
- ENDFOREACH(_boost_VER)
-
+ list(APPEND _boost_PATH_SUFFIXES "boost-${_boost_BOOSTIFIED_VERSION}")
+ list(APPEND _boost_PATH_SUFFIXES "boost_${_boost_BOOSTIFIED_VERSION}")
+
+ endforeach(_boost_VER)
+
if(Boost_DEBUG)
message(STATUS "[ ${CMAKE_CURRENT_LIST_FILE}:${CMAKE_CURRENT_LIST_LINE} ] "
"Include debugging info:")
@@ -502,61 +673,62 @@ ELSE (_boost_IN_CACHE)
endif()
# Look for a standard boost header file.
- FIND_PATH(Boost_INCLUDE_DIR
+ find_path(Boost_INCLUDE_DIR
NAMES boost/config.hpp
HINTS ${_boost_INCLUDE_SEARCH_DIRS}
PATH_SUFFIXES ${_boost_PATH_SUFFIXES}
+ ${_boost_FIND_OPTIONS}
)
- ENDIF( NOT Boost_INCLUDE_DIR )
-
+ endif( NOT Boost_INCLUDE_DIR )
+
# ------------------------------------------------------------------------
# Extract version information from version.hpp
# ------------------------------------------------------------------------
- IF(Boost_INCLUDE_DIR)
+ if(Boost_INCLUDE_DIR)
# Extract Boost_VERSION and Boost_LIB_VERSION from version.hpp
# Read the whole file:
#
- SET(BOOST_VERSION 0)
- SET(BOOST_LIB_VERSION "")
- FILE(READ "${Boost_INCLUDE_DIR}/boost/version.hpp" _boost_VERSION_HPP_CONTENTS)
+ set(BOOST_VERSION 0)
+ set(BOOST_LIB_VERSION "")
+ file(READ "${Boost_INCLUDE_DIR}/boost/version.hpp" _boost_VERSION_HPP_CONTENTS)
if(Boost_DEBUG)
message(STATUS "[ ${CMAKE_CURRENT_LIST_FILE}:${CMAKE_CURRENT_LIST_LINE} ] "
"location of version.hpp: ${Boost_INCLUDE_DIR}/boost/version.hpp")
endif()
-
- STRING(REGEX REPLACE ".*#define BOOST_VERSION ([0-9]+).*" "\\1" Boost_VERSION "${_boost_VERSION_HPP_CONTENTS}")
- STRING(REGEX REPLACE ".*#define BOOST_LIB_VERSION \"([0-9_]+)\".*" "\\1" Boost_LIB_VERSION "${_boost_VERSION_HPP_CONTENTS}")
-
- SET(Boost_LIB_VERSION ${Boost_LIB_VERSION} CACHE INTERNAL "The library version string for boost libraries")
- SET(Boost_VERSION ${Boost_VERSION} CACHE INTERNAL "The version number for boost libraries")
-
- IF(NOT "${Boost_VERSION}" STREQUAL "0")
- MATH(EXPR Boost_MAJOR_VERSION "${Boost_VERSION} / 100000")
- MATH(EXPR Boost_MINOR_VERSION "${Boost_VERSION} / 100 % 1000")
- MATH(EXPR Boost_SUBMINOR_VERSION "${Boost_VERSION} % 100")
+
+ string(REGEX REPLACE ".*#define BOOST_VERSION ([0-9]+).*" "\\1" Boost_VERSION "${_boost_VERSION_HPP_CONTENTS}")
+ string(REGEX REPLACE ".*#define BOOST_LIB_VERSION \"([0-9_]+)\".*" "\\1" Boost_LIB_VERSION "${_boost_VERSION_HPP_CONTENTS}")
+
+ set(Boost_LIB_VERSION ${Boost_LIB_VERSION} CACHE INTERNAL "The library version string for boost libraries")
+ set(Boost_VERSION ${Boost_VERSION} CACHE INTERNAL "The version number for boost libraries")
+
+ if(NOT "${Boost_VERSION}" STREQUAL "0")
+ math(EXPR Boost_MAJOR_VERSION "${Boost_VERSION} / 100000")
+ math(EXPR Boost_MINOR_VERSION "${Boost_VERSION} / 100 % 1000")
+ math(EXPR Boost_SUBMINOR_VERSION "${Boost_VERSION} % 100")
set(Boost_ERROR_REASON
"${Boost_ERROR_REASON}Boost version: ${Boost_MAJOR_VERSION}.${Boost_MINOR_VERSION}.${Boost_SUBMINOR_VERSION}\nBoost include path: ${Boost_INCLUDE_DIR}")
- ENDIF(NOT "${Boost_VERSION}" STREQUAL "0")
+ endif(NOT "${Boost_VERSION}" STREQUAL "0")
if(Boost_DEBUG)
message(STATUS "[ ${CMAKE_CURRENT_LIST_FILE}:${CMAKE_CURRENT_LIST_LINE} ] "
"version.hpp reveals boost "
"${Boost_MAJOR_VERSION}.${Boost_MINOR_VERSION}.${Boost_SUBMINOR_VERSION}")
endif()
- ELSE(Boost_INCLUDE_DIR)
+ else(Boost_INCLUDE_DIR)
set(Boost_ERROR_REASON
"${Boost_ERROR_REASON}Unable to find the Boost header files. Please set BOOST_ROOT to the root directory containing Boost or BOOST_INCLUDEDIR to the directory containing Boost's headers.")
- ENDIF(Boost_INCLUDE_DIR)
-
+ endif(Boost_INCLUDE_DIR)
+
# ------------------------------------------------------------------------
# Suffix initialization and compiler suffix detection.
# ------------------------------------------------------------------------
# Setting some more suffixes for the library
- SET (Boost_LIB_PREFIX "")
- if ( WIN32 AND Boost_USE_STATIC_LIBS )
- SET (Boost_LIB_PREFIX "lib")
+ set(Boost_LIB_PREFIX "")
+ if ( WIN32 AND Boost_USE_STATIC_LIBS AND NOT CYGWIN)
+ set(Boost_LIB_PREFIX "lib")
endif()
if (Boost_COMPILER)
@@ -571,62 +743,64 @@ ELSE (_boost_IN_CACHE)
# please report them and use the Boost_COMPILER variable
# to work around the problems.
if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Intel"
- OR "${CMAKE_CXX_COMPILER}" MATCHES "icl"
+ OR "${CMAKE_CXX_COMPILER}" MATCHES "icl"
OR "${CMAKE_CXX_COMPILER}" MATCHES "icpc")
if(WIN32)
set (_boost_COMPILER "-iw")
else()
set (_boost_COMPILER "-il")
endif()
- elseif (MSVC90)
- SET (_boost_COMPILER "-vc90")
+ elseif (MSVC11)
+ set(_boost_COMPILER "-vc110")
elseif (MSVC10)
- SET (_boost_COMPILER "-vc100")
+ set(_boost_COMPILER "-vc100")
+ elseif (MSVC90)
+ set(_boost_COMPILER "-vc90")
elseif (MSVC80)
- SET (_boost_COMPILER "-vc80")
+ set(_boost_COMPILER "-vc80")
elseif (MSVC71)
- SET (_boost_COMPILER "-vc71")
+ set(_boost_COMPILER "-vc71")
elseif (MSVC70) # Good luck!
- SET (_boost_COMPILER "-vc7") # yes, this is correct
+ set(_boost_COMPILER "-vc7") # yes, this is correct
elseif (MSVC60) # Good luck!
- SET (_boost_COMPILER "-vc6") # yes, this is correct
+ set(_boost_COMPILER "-vc6") # yes, this is correct
elseif (BORLAND)
- SET (_boost_COMPILER "-bcb")
+ set(_boost_COMPILER "-bcb")
elseif("${CMAKE_CXX_COMPILER_ID}" STREQUAL "SunPro")
set(_boost_COMPILER "-sw")
elseif (MINGW)
if(${Boost_MAJOR_VERSION}.${Boost_MINOR_VERSION} VERSION_LESS 1.34)
- SET(_boost_COMPILER "-mgw") # no GCC version encoding prior to 1.34
+ set(_boost_COMPILER "-mgw") # no GCC version encoding prior to 1.34
else()
_Boost_COMPILER_DUMPVERSION(_boost_COMPILER_VERSION)
- SET (_boost_COMPILER "-mgw${_boost_COMPILER_VERSION}")
+ set(_boost_COMPILER "-mgw${_boost_COMPILER_VERSION}")
endif()
elseif (UNIX)
if (CMAKE_COMPILER_IS_GNUCXX)
if(${Boost_MAJOR_VERSION}.${Boost_MINOR_VERSION} VERSION_LESS 1.34)
- SET(_boost_COMPILER "-gcc") # no GCC version encoding prior to 1.34
+ set(_boost_COMPILER "-gcc") # no GCC version encoding prior to 1.34
else()
_Boost_COMPILER_DUMPVERSION(_boost_COMPILER_VERSION)
# Determine which version of GCC we have.
- IF(APPLE)
- IF(Boost_MINOR_VERSION)
- IF(${Boost_MINOR_VERSION} GREATER 35)
+ if(APPLE)
+ if(Boost_MINOR_VERSION)
+ if(${Boost_MINOR_VERSION} GREATER 35)
# In Boost 1.36.0 and newer, the mangled compiler name used
# on Mac OS X/Darwin is "xgcc".
- SET(_boost_COMPILER "-xgcc${_boost_COMPILER_VERSION}")
- ELSE(${Boost_MINOR_VERSION} GREATER 35)
+ set(_boost_COMPILER "-xgcc${_boost_COMPILER_VERSION}")
+ else(${Boost_MINOR_VERSION} GREATER 35)
# In Boost <= 1.35.0, there is no mangled compiler name for
# the Mac OS X/Darwin version of GCC.
- SET(_boost_COMPILER "")
- ENDIF(${Boost_MINOR_VERSION} GREATER 35)
- ELSE(Boost_MINOR_VERSION)
+ set(_boost_COMPILER "")
+ endif(${Boost_MINOR_VERSION} GREATER 35)
+ else(Boost_MINOR_VERSION)
# We don't know the Boost version, so assume it's
# pre-1.36.0.
- SET(_boost_COMPILER "")
- ENDIF(Boost_MINOR_VERSION)
- ELSE()
- SET (_boost_COMPILER "-gcc${_boost_COMPILER_VERSION}")
- ENDIF()
+ set(_boost_COMPILER "")
+ endif(Boost_MINOR_VERSION)
+ else()
+ set(_boost_COMPILER "-gcc${_boost_COMPILER_VERSION}")
+ endif()
endif()
endif (CMAKE_COMPILER_IS_GNUCXX)
endif()
@@ -636,7 +810,7 @@ ELSE (_boost_IN_CACHE)
endif()
endif(Boost_COMPILER)
- SET (_boost_MULTITHREADED "-mt")
+ set (_boost_MULTITHREADED "-mt")
if( NOT Boost_USE_MULTITHREADED )
set (_boost_MULTITHREADED "")
endif()
@@ -645,32 +819,67 @@ ELSE (_boost_IN_CACHE)
"_boost_MULTITHREADED = ${_boost_MULTITHREADED}")
endif()
- SET( _boost_STATIC_TAG "")
- set( _boost_ABI_TAG "")
- IF (WIN32)
- IF(MSVC OR "${CMAKE_CXX_COMPILER}" MATCHES "icl"
+ #======================
+ # Systematically build up the Boost ABI tag
+ # http://boost.org/doc/libs/1_41_0/more/getting_started/windows.html#library-naming
+ set( _boost_RELEASE_ABI_TAG "-")
+ set( _boost_DEBUG_ABI_TAG "-")
+ # Key Use this library when:
+ # s linking statically to the C++ standard library and
+ # compiler runtime support libraries.
+ if(Boost_USE_STATIC_RUNTIME)
+ set( _boost_RELEASE_ABI_TAG "${_boost_RELEASE_ABI_TAG}s")
+ set( _boost_DEBUG_ABI_TAG "${_boost_DEBUG_ABI_TAG}s")
+ endif()
+ # g using debug versions of the standard and runtime
+ # support libraries
+ if(WIN32)
+ if(MSVC OR "${CMAKE_CXX_COMPILER}" MATCHES "icl"
OR "${CMAKE_CXX_COMPILER}" MATCHES "icpc")
- SET (_boost_ABI_TAG "g")
- ENDIF()
- IF( Boost_USE_STATIC_LIBS )
- SET( _boost_STATIC_TAG "-s")
- ENDIF( Boost_USE_STATIC_LIBS )
- ENDIF(WIN32)
- SET (_boost_ABI_TAG "${_boost_ABI_TAG}d")
+ set(_boost_DEBUG_ABI_TAG "${_boost_DEBUG_ABI_TAG}g")
+ endif()
+ endif()
+ # y using special debug build of python
+ if(Boost_USE_DEBUG_PYTHON)
+ set(_boost_DEBUG_ABI_TAG "${_boost_DEBUG_ABI_TAG}y")
+ endif()
+ # d using a debug version of your code
+ set(_boost_DEBUG_ABI_TAG "${_boost_DEBUG_ABI_TAG}d")
+ # p using the STLport standard library rather than the
+ # default one supplied with your compiler
+ if(Boost_USE_STLPORT)
+ set( _boost_RELEASE_ABI_TAG "${_boost_RELEASE_ABI_TAG}p")
+ set( _boost_DEBUG_ABI_TAG "${_boost_DEBUG_ABI_TAG}p")
+ endif()
+ # n using the STLport deprecated "native iostreams" feature
+ if(Boost_USE_STLPORT_DEPRECATED_NATIVE_IOSTREAMS)
+ set( _boost_RELEASE_ABI_TAG "${_boost_RELEASE_ABI_TAG}n")
+ set( _boost_DEBUG_ABI_TAG "${_boost_DEBUG_ABI_TAG}n")
+ endif()
+
if(Boost_DEBUG)
message(STATUS "[ ${CMAKE_CURRENT_LIST_FILE}:${CMAKE_CURRENT_LIST_LINE} ] "
- "_boost_STATIC_TAG = ${_boost_STATIC_TAG}")
+ "_boost_RELEASE_ABI_TAG = ${_boost_RELEASE_ABI_TAG}")
message(STATUS "[ ${CMAKE_CURRENT_LIST_FILE}:${CMAKE_CURRENT_LIST_LINE} ] "
- "_boost_ABI_TAG = ${_boost_ABI_TAG}")
+ "_boost_DEBUG_ABI_TAG = ${_boost_DEBUG_ABI_TAG}")
endif()
# ------------------------------------------------------------------------
# Begin finding boost libraries
# ------------------------------------------------------------------------
- SET(_boost_LIBRARIES_SEARCH_DIRS
+ if(BOOST_ROOT)
+ set(_boost_LIBRARY_SEARCH_DIRS_ALWAYS
+ ${BOOST_ROOT}/lib
+ ${BOOST_ROOT}/stage/lib)
+ endif()
+ set(_boost_LIBRARY_SEARCH_DIRS_ALWAYS
+ ${_boost_LIBRARY_SEARCH_DIRS_ALWAYS}
${Boost_INCLUDE_DIR}/lib
${Boost_INCLUDE_DIR}/../lib
+ ${Boost_INCLUDE_DIR}/stage/lib
+ )
+ set(_boost_LIBRARY_SEARCH_DIRS_SYSTEM
C:/boost/lib
C:/boost
"$ENV{ProgramFiles}/boost/boost_${Boost_MAJOR_VERSION}_${Boost_MINOR_VERSION}_${Boost_SUBMINOR_VERSION}/lib"
@@ -679,78 +888,158 @@ ELSE (_boost_IN_CACHE)
"$ENV{ProgramFiles}/boost"
/sw/local/lib
)
- IF( BOOST_ROOT )
- SET(_boost_LIBRARIES_SEARCH_DIRS
- ${BOOST_ROOT}/lib
- ${BOOST_ROOT}/stage/lib
- ${_boost_LIBRARIES_SEARCH_DIRS})
- ENDIF( BOOST_ROOT )
-
- IF( BOOST_LIBRARYDIR )
+ set(_boost_LIBRARY_SEARCH_DIRS ${_boost_LIBRARY_SEARCH_DIRS_ALWAYS})
+ if( Boost_NO_SYSTEM_PATHS )
+ set(_boost_FIND_OPTIONS NO_CMAKE_SYSTEM_PATH)
+ else()
+ list(APPEND _boost_LIBRARY_SEARCH_DIRS ${_boost_LIBRARY_SEARCH_DIRS_SYSTEM})
+ endif()
+
+ # prepend BOOST_LIBRARYDIR to search path if specified
+ if( BOOST_LIBRARYDIR )
file(TO_CMAKE_PATH ${BOOST_LIBRARYDIR} BOOST_LIBRARYDIR)
- SET(_boost_LIBRARIES_SEARCH_DIRS
- ${BOOST_LIBRARYDIR} ${_boost_LIBRARIES_SEARCH_DIRS})
- ENDIF( BOOST_LIBRARYDIR )
+ set(_boost_LIBRARY_SEARCH_DIRS
+ ${BOOST_LIBRARYDIR} ${_boost_LIBRARY_SEARCH_DIRS})
+ endif()
if(Boost_DEBUG)
message(STATUS "[ ${CMAKE_CURRENT_LIST_FILE}:${CMAKE_CURRENT_LIST_LINE} ] "
- "_boost_LIBRARIES_SEARCH_DIRS = ${_boost_LIBRARIES_SEARCH_DIRS}")
- endif()
-
- FOREACH(COMPONENT ${Boost_FIND_COMPONENTS})
- STRING(TOUPPER ${COMPONENT} UPPERCOMPONENT)
- SET( Boost_${UPPERCOMPONENT}_LIBRARY "Boost_${UPPERCOMPONENT}_LIBRARY-NOTFOUND" )
- SET( Boost_${UPPERCOMPONENT}_LIBRARY_RELEASE "Boost_${UPPERCOMPONENT}_LIBRARY_RELEASE-NOTFOUND" )
- SET( Boost_${UPPERCOMPONENT}_LIBRARY_DEBUG "Boost_${UPPERCOMPONENT}_LIBRARY_DEBUG-NOTFOUND")
-
- # Support preference of static libs by adjusting CMAKE_FIND_LIBRARY_SUFFIXES
- IF( Boost_USE_STATIC_LIBS )
- SET( _boost_ORIG_CMAKE_FIND_LIBRARY_SUFFIXES ${CMAKE_FIND_LIBRARY_SUFFIXES})
- IF(WIN32)
- SET(CMAKE_FIND_LIBRARY_SUFFIXES .lib .a ${CMAKE_FIND_LIBRARY_SUFFIXES})
- ELSE(WIN32)
- SET(CMAKE_FIND_LIBRARY_SUFFIXES .a ${CMAKE_FIND_LIBRARY_SUFFIXES})
- ENDIF(WIN32)
- ENDIF( Boost_USE_STATIC_LIBS )
-
- FIND_LIBRARY(Boost_${UPPERCOMPONENT}_LIBRARY_RELEASE
- NAMES ${Boost_LIB_PREFIX}boost_${COMPONENT}${_boost_COMPILER}${_boost_MULTITHREADED}-${Boost_LIB_VERSION}
- ${Boost_LIB_PREFIX}boost_${COMPONENT}${_boost_COMPILER}${_boost_MULTITHREADED}${_boost_STATIC_TAG}-${Boost_LIB_VERSION}
- ${Boost_LIB_PREFIX}boost_${COMPONENT}
- ${Boost_LIB_PREFIX}boost_${COMPONENT}${_boost_MULTITHREADED}-${Boost_LIB_VERSION}
- ${Boost_LIB_PREFIX}boost_${COMPONENT}${_boost_MULTITHREADED}${_boost_STATIC_TAG}-${Boost_LIB_VERSION}
- ${Boost_LIB_PREFIX}boost_${COMPONENT}${_boost_MULTITHREADED}
- ${Boost_LIB_PREFIX}boost_${COMPONENT}${_boost_MULTITHREADED}${_boost_STATIC_TAG}
- HINTS ${_boost_LIBRARIES_SEARCH_DIRS}
+ "_boost_LIBRARY_SEARCH_DIRS = ${_boost_LIBRARY_SEARCH_DIRS}")
+ endif()
+
+ # Support preference of static libs by adjusting CMAKE_FIND_LIBRARY_SUFFIXES
+ if( Boost_USE_STATIC_LIBS )
+ set( _boost_ORIG_CMAKE_FIND_LIBRARY_SUFFIXES ${CMAKE_FIND_LIBRARY_SUFFIXES})
+ if(WIN32)
+ set(CMAKE_FIND_LIBRARY_SUFFIXES .lib .a ${CMAKE_FIND_LIBRARY_SUFFIXES})
+ else()
+ set(CMAKE_FIND_LIBRARY_SUFFIXES .a )
+ endif()
+ endif()
+
+ # We want to use the tag inline below without risking double dashes
+ if(_boost_RELEASE_ABI_TAG)
+ if(${_boost_RELEASE_ABI_TAG} STREQUAL "-")
+ set(_boost_RELEASE_ABI_TAG "")
+ endif()
+ endif()
+ if(_boost_DEBUG_ABI_TAG)
+ if(${_boost_DEBUG_ABI_TAG} STREQUAL "-")
+ set(_boost_DEBUG_ABI_TAG "")
+ endif()
+ endif()
+
+ # The previous behavior of FindBoost when Boost_USE_STATIC_LIBS was enabled
+ # on WIN32 was to:
+ # 1. Search for static libs compiled against a SHARED C++ standard runtime library (use if found)
+ # 2. Search for static libs compiled against a STATIC C++ standard runtime library (use if found)
+ # We maintain this behavior since changing it could break people's builds.
+ # To disable the ambiguous behavior, the user need only
+ # set Boost_USE_STATIC_RUNTIME either ON or OFF.
+ set(_boost_STATIC_RUNTIME_WORKAROUND false)
+ if(WIN32 AND Boost_USE_STATIC_LIBS)
+ if(NOT DEFINED Boost_USE_STATIC_RUNTIME)
+ set(_boost_STATIC_RUNTIME_WORKAROUND true)
+ endif()
+ endif()
+
+
+ foreach(COMPONENT ${Boost_FIND_COMPONENTS})
+ string(TOUPPER ${COMPONENT} UPPERCOMPONENT)
+ set( Boost_${UPPERCOMPONENT}_LIBRARY "Boost_${UPPERCOMPONENT}_LIBRARY-NOTFOUND" )
+ set( Boost_${UPPERCOMPONENT}_LIBRARY_RELEASE "Boost_${UPPERCOMPONENT}_LIBRARY_RELEASE-NOTFOUND" )
+ set( Boost_${UPPERCOMPONENT}_LIBRARY_DEBUG "Boost_${UPPERCOMPONENT}_LIBRARY_DEBUG-NOTFOUND")
+
+ set( _boost_docstring_release "Boost ${COMPONENT} library (release)")
+ set( _boost_docstring_debug "Boost ${COMPONENT} library (debug)")
+
+ #
+ # Find RELEASE libraries
+ #
+ set(_boost_RELEASE_NAMES
+ ${Boost_LIB_PREFIX}boost_${COMPONENT}${_boost_COMPILER}${_boost_MULTITHREADED}${_boost_RELEASE_ABI_TAG}-${Boost_LIB_VERSION}
+ ${Boost_LIB_PREFIX}boost_${COMPONENT}${_boost_COMPILER}${_boost_MULTITHREADED}${_boost_RELEASE_ABI_TAG}
+ ${Boost_LIB_PREFIX}boost_${COMPONENT}${_boost_MULTITHREADED}${_boost_RELEASE_ABI_TAG}-${Boost_LIB_VERSION}
+ ${Boost_LIB_PREFIX}boost_${COMPONENT}${_boost_MULTITHREADED}${_boost_RELEASE_ABI_TAG}
+ ${Boost_LIB_PREFIX}boost_${COMPONENT} )
+ if(_boost_STATIC_RUNTIME_WORKAROUND)
+ set(_boost_RELEASE_STATIC_ABI_TAG "-s${_boost_RELEASE_ABI_TAG}")
+ list(APPEND _boost_RELEASE_NAMES
+ ${Boost_LIB_PREFIX}boost_${COMPONENT}${_boost_COMPILER}${_boost_MULTITHREADED}${_boost_RELEASE_STATIC_ABI_TAG}-${Boost_LIB_VERSION}
+ ${Boost_LIB_PREFIX}boost_${COMPONENT}${_boost_COMPILER}${_boost_MULTITHREADED}${_boost_RELEASE_STATIC_ABI_TAG}
+ ${Boost_LIB_PREFIX}boost_${COMPONENT}${_boost_MULTITHREADED}${_boost_RELEASE_STATIC_ABI_TAG}-${Boost_LIB_VERSION}
+ ${Boost_LIB_PREFIX}boost_${COMPONENT}${_boost_MULTITHREADED}${_boost_RELEASE_STATIC_ABI_TAG} )
+ endif()
+ if(Boost_THREADAPI AND ${COMPONENT} STREQUAL "thread")
+ _Boost_PREPEND_LIST_WITH_THREADAPI(_boost_RELEASE_NAMES ${_boost_RELEASE_NAMES})
+ endif()
+ if(Boost_DEBUG)
+ message(STATUS "[ ${CMAKE_CURRENT_LIST_FILE}:${CMAKE_CURRENT_LIST_LINE} ] "
+ "Searching for ${UPPERCOMPONENT}_LIBRARY_RELEASE: ${_boost_RELEASE_NAMES}")
+ endif()
+ find_library(Boost_${UPPERCOMPONENT}_LIBRARY_RELEASE
+ NAMES ${_boost_RELEASE_NAMES}
+ HINTS ${_boost_LIBRARY_SEARCH_DIRS}
+ ${_boost_FIND_OPTIONS}
+ DOC "${_boost_docstring_release}"
)
- FIND_LIBRARY(Boost_${UPPERCOMPONENT}_LIBRARY_DEBUG
- NAMES ${Boost_LIB_PREFIX}boost_${COMPONENT}${_boost_COMPILER}${_boost_MULTITHREADED}-${_boost_ABI_TAG}-${Boost_LIB_VERSION}
- ${Boost_LIB_PREFIX}boost_${COMPONENT}${_boost_COMPILER}${_boost_MULTITHREADED}${_boost_STATIC_TAG}${_boost_ABI_TAG}-${Boost_LIB_VERSION}
- ${Boost_LIB_PREFIX}boost_${COMPONENT}${_boost_MULTITHREADED}-${_boost_ABI_TAG}-${Boost_LIB_VERSION}
- ${Boost_LIB_PREFIX}boost_${COMPONENT}${_boost_MULTITHREADED}${_boost_STATIC_TAG}${_boost_ABI_TAG}-${Boost_LIB_VERSION}
- ${Boost_LIB_PREFIX}boost_${COMPONENT}${_boost_MULTITHREADED}-${_boost_ABI_TAG}
- ${Boost_LIB_PREFIX}boost_${COMPONENT}${_boost_MULTITHREADED}${_boost_STATIC_TAG}${_boost_ABI_TAG}
- ${Boost_LIB_PREFIX}boost_${COMPONENT}-${_boost_ABI_TAG}
- HINTS ${_boost_LIBRARIES_SEARCH_DIRS}
+ #
+ # Find DEBUG libraries
+ #
+ set(_boost_DEBUG_NAMES
+ ${Boost_LIB_PREFIX}boost_${COMPONENT}${_boost_COMPILER}${_boost_MULTITHREADED}${_boost_DEBUG_ABI_TAG}-${Boost_LIB_VERSION}
+ ${Boost_LIB_PREFIX}boost_${COMPONENT}${_boost_COMPILER}${_boost_MULTITHREADED}${_boost_DEBUG_ABI_TAG}
+ ${Boost_LIB_PREFIX}boost_${COMPONENT}${_boost_MULTITHREADED}${_boost_DEBUG_ABI_TAG}-${Boost_LIB_VERSION}
+ ${Boost_LIB_PREFIX}boost_${COMPONENT}${_boost_MULTITHREADED}${_boost_DEBUG_ABI_TAG}
+ ${Boost_LIB_PREFIX}boost_${COMPONENT}${_boost_MULTITHREADED}
+ ${Boost_LIB_PREFIX}boost_${COMPONENT} )
+ if(_boost_STATIC_RUNTIME_WORKAROUND)
+ set(_boost_DEBUG_STATIC_ABI_TAG "-s${_boost_DEBUG_ABI_TAG}")
+ list(APPEND _boost_DEBUG_NAMES
+ ${Boost_LIB_PREFIX}boost_${COMPONENT}${_boost_COMPILER}${_boost_MULTITHREADED}${_boost_DEBUG_STATIC_ABI_TAG}-${Boost_LIB_VERSION}
+ ${Boost_LIB_PREFIX}boost_${COMPONENT}${_boost_COMPILER}${_boost_MULTITHREADED}${_boost_DEBUG_STATIC_ABI_TAG}
+ ${Boost_LIB_PREFIX}boost_${COMPONENT}${_boost_MULTITHREADED}${_boost_DEBUG_STATIC_ABI_TAG}-${Boost_LIB_VERSION}
+ ${Boost_LIB_PREFIX}boost_${COMPONENT}${_boost_MULTITHREADED}${_boost_DEBUG_STATIC_ABI_TAG} )
+ endif()
+ if(Boost_THREADAPI AND ${COMPONENT} STREQUAL "thread")
+ _Boost_PREPEND_LIST_WITH_THREADAPI(_boost_DEBUG_NAMES ${_boost_DEBUG_NAMES})
+ endif()
+ if(Boost_DEBUG)
+ message(STATUS "[ ${CMAKE_CURRENT_LIST_FILE}:${CMAKE_CURRENT_LIST_LINE} ] "
+ "Searching for ${UPPERCOMPONENT}_LIBRARY_DEBUG: ${_boost_DEBUG_NAMES}")
+ endif()
+ find_library(Boost_${UPPERCOMPONENT}_LIBRARY_DEBUG
+ NAMES ${_boost_DEBUG_NAMES}
+ HINTS ${_boost_LIBRARY_SEARCH_DIRS}
+ ${_boost_FIND_OPTIONS}
+ DOC "${_boost_docstring_debug}"
)
+ if(Boost_REALPATH)
+ _Boost_SWAP_WITH_REALPATH(Boost_${UPPERCOMPONENT}_LIBRARY_RELEASE "${_boost_docstring_release}")
+ _Boost_SWAP_WITH_REALPATH(Boost_${UPPERCOMPONENT}_LIBRARY_DEBUG "${_boost_docstring_debug}" )
+ endif()
+
_Boost_ADJUST_LIB_VARS(${UPPERCOMPONENT})
- IF( Boost_USE_STATIC_LIBS )
- SET(CMAKE_FIND_LIBRARY_SUFFIXES ${_boost_ORIG_CMAKE_FIND_LIBRARY_SUFFIXES})
- ENDIF( Boost_USE_STATIC_LIBS )
- ENDFOREACH(COMPONENT)
+
+ endforeach(COMPONENT)
+
+ # Restore the original find library ordering
+ if( Boost_USE_STATIC_LIBS )
+ set(CMAKE_FIND_LIBRARY_SUFFIXES ${_boost_ORIG_CMAKE_FIND_LIBRARY_SUFFIXES})
+ endif()
# ------------------------------------------------------------------------
# End finding boost libraries
# ------------------------------------------------------------------------
- SET(Boost_INCLUDE_DIRS
+ set(Boost_INCLUDE_DIRS
${Boost_INCLUDE_DIR}
)
- SET(Boost_FOUND FALSE)
- IF(Boost_INCLUDE_DIR)
- SET( Boost_FOUND TRUE )
+ set(Boost_FOUND FALSE)
+ if(Boost_INCLUDE_DIR)
+ set( Boost_FOUND TRUE )
# Check the version of Boost against the requested version.
if (Boost_FIND_VERSION AND NOT Boost_FIND_VERSION_MINOR)
@@ -785,7 +1074,7 @@ ELSE (_boost_IN_CACHE)
if (NOT Boost_FIND_VERSION_PATCH)
set(Boost_FIND_VERSION_PATCH 0)
endif (NOT Boost_FIND_VERSION_PATCH)
-
+
# We'll set Boost_FOUND true again if we have an exact version match.
set(Boost_FOUND FALSE)
_Boost_MARK_COMPONENTS_FOUND(OFF)
@@ -804,7 +1093,7 @@ ELSE (_boost_IN_CACHE)
set(Boost_ERROR_REASON
"${Boost_ERROR_REASON}\nDetected version of Boost is too ${_Boost_VERSION_AGE}. Requested version was ${Boost_FIND_VERSION_MAJOR}.${Boost_FIND_VERSION_MINOR}")
if (Boost_FIND_VERSION_PATCH)
- set(Boost_ERROR_REASON
+ set(Boost_ERROR_REASON
"${Boost_ERROR_REASON}.${Boost_FIND_VERSION_PATCH}")
endif (Boost_FIND_VERSION_PATCH)
if (NOT Boost_FIND_VERSION_EXACT)
@@ -823,7 +1112,7 @@ ELSE (_boost_IN_CACHE)
string(TOLOWER ${COMPONENT} COMPONENT)
list(APPEND _Boost_MISSING_COMPONENTS ${COMPONENT})
set( Boost_FOUND FALSE)
- endif(NOT Boost_${COMPONENT}_FOUND)
+ endif()
endforeach(COMPONENT)
if(Boost_DEBUG)
@@ -844,67 +1133,67 @@ ELSE (_boost_IN_CACHE)
list(LENGTH _Boost_MISSING_COMPONENTS Boost_NUM_MISSING_COMPONENTS)
if (${Boost_NUM_COMPONENTS_WANTED} EQUAL ${Boost_NUM_MISSING_COMPONENTS})
set(Boost_ERROR_REASON
- "${Boost_ERROR_REASON}No Boost libraries were found. You may need to set Boost_LIBRARYDIR to the directory containing Boost libraries or BOOST_ROOT to the location of Boost.")
+ "${Boost_ERROR_REASON}No Boost libraries were found. You may need to set BOOST_LIBRARYDIR to the directory containing Boost libraries or BOOST_ROOT to the location of Boost.")
else (${Boost_NUM_COMPONENTS_WANTED} EQUAL ${Boost_NUM_MISSING_COMPONENTS})
set(Boost_ERROR_REASON
- "${Boost_ERROR_REASON}Some (but not all) of the required Boost libraries were found. You may need to install these additional Boost libraries. Alternatively, set Boost_LIBRARYDIR to the directory containing Boost libraries or BOOST_ROOT to the location of Boost.")
+ "${Boost_ERROR_REASON}Some (but not all) of the required Boost libraries were found. You may need to install these additional Boost libraries. Alternatively, set BOOST_LIBRARYDIR to the directory containing Boost libraries or BOOST_ROOT to the location of Boost.")
endif (${Boost_NUM_COMPONENTS_WANTED} EQUAL ${Boost_NUM_MISSING_COMPONENTS})
endif (_Boost_MISSING_COMPONENTS)
- IF( NOT Boost_LIBRARY_DIRS AND NOT _boost_CHECKED_COMPONENT )
+ if( NOT Boost_LIBRARY_DIRS AND NOT _boost_CHECKED_COMPONENT )
# Compatibility Code for backwards compatibility with CMake
# 2.4's FindBoost module.
# Look for the boost library path.
# Note that the user may not have installed any libraries
# so it is quite possible the Boost_LIBRARY_PATH may not exist.
- SET(_boost_LIB_DIR ${Boost_INCLUDE_DIR})
-
- IF("${_boost_LIB_DIR}" MATCHES "boost-[0-9]+")
- GET_FILENAME_COMPONENT(_boost_LIB_DIR ${_boost_LIB_DIR} PATH)
- ENDIF ("${_boost_LIB_DIR}" MATCHES "boost-[0-9]+")
-
- IF("${_boost_LIB_DIR}" MATCHES "/include$")
+ set(_boost_LIB_DIR ${Boost_INCLUDE_DIR})
+
+ if("${_boost_LIB_DIR}" MATCHES "boost-[0-9]+")
+ get_filename_component(_boost_LIB_DIR ${_boost_LIB_DIR} PATH)
+ endif()
+
+ if("${_boost_LIB_DIR}" MATCHES "/include$")
# Strip off the trailing "/include" in the path.
- GET_FILENAME_COMPONENT(_boost_LIB_DIR ${_boost_LIB_DIR} PATH)
- ENDIF("${_boost_LIB_DIR}" MATCHES "/include$")
-
- IF(EXISTS "${_boost_LIB_DIR}/lib")
- SET (_boost_LIB_DIR ${_boost_LIB_DIR}/lib)
- ELSE(EXISTS "${_boost_LIB_DIR}/lib")
- IF(EXISTS "${_boost_LIB_DIR}/stage/lib")
- SET(_boost_LIB_DIR ${_boost_LIB_DIR}/stage/lib)
- ELSE(EXISTS "${_boost_LIB_DIR}/stage/lib")
- SET(_boost_LIB_DIR "")
- ENDIF(EXISTS "${_boost_LIB_DIR}/stage/lib")
- ENDIF(EXISTS "${_boost_LIB_DIR}/lib")
-
- IF(_boost_LIB_DIR AND EXISTS "${_boost_LIB_DIR}")
- SET(Boost_LIBRARY_DIRS ${_boost_LIB_DIR} CACHE FILEPATH "Boost library directory")
- ENDIF(_boost_LIB_DIR AND EXISTS "${_boost_LIB_DIR}")
-
- ENDIF( NOT Boost_LIBRARY_DIRS AND NOT _boost_CHECKED_COMPONENT )
-
- ELSE(Boost_INCLUDE_DIR)
- SET( Boost_FOUND FALSE)
- ENDIF(Boost_INCLUDE_DIR)
-
- IF (Boost_FOUND)
- IF (NOT Boost_FIND_QUIETLY)
- MESSAGE(STATUS "Boost version: ${Boost_MAJOR_VERSION}.${Boost_MINOR_VERSION}.${Boost_SUBMINOR_VERSION}")
+ get_filename_component(_boost_LIB_DIR ${_boost_LIB_DIR} PATH)
+ endif()
+
+ if(EXISTS "${_boost_LIB_DIR}/lib")
+ set(_boost_LIB_DIR ${_boost_LIB_DIR}/lib)
+ else()
+ if(EXISTS "${_boost_LIB_DIR}/stage/lib")
+ set(_boost_LIB_DIR ${_boost_LIB_DIR}/stage/lib)
+ else()
+ set(_boost_LIB_DIR "")
+ endif()
+ endif()
+
+ if(_boost_LIB_DIR AND EXISTS "${_boost_LIB_DIR}")
+ set(Boost_LIBRARY_DIRS ${_boost_LIB_DIR} CACHE FILEPATH "Boost library directory")
+ endif()
+
+ endif( NOT Boost_LIBRARY_DIRS AND NOT _boost_CHECKED_COMPONENT )
+
+ else(Boost_INCLUDE_DIR)
+ set( Boost_FOUND FALSE)
+ endif(Boost_INCLUDE_DIR)
+
+ if(Boost_FOUND)
+ if(NOT Boost_FIND_QUIETLY)
+ message(STATUS "Boost version: ${Boost_MAJOR_VERSION}.${Boost_MINOR_VERSION}.${Boost_SUBMINOR_VERSION}")
if(Boost_FIND_COMPONENTS)
message(STATUS "Found the following Boost libraries:")
endif()
- ENDIF(NOT Boost_FIND_QUIETLY)
- FOREACH ( COMPONENT ${Boost_FIND_COMPONENTS} )
- STRING( TOUPPER ${COMPONENT} UPPERCOMPONENT )
- IF ( Boost_${UPPERCOMPONENT}_FOUND )
- IF (NOT Boost_FIND_QUIETLY)
- MESSAGE (STATUS " ${COMPONENT}")
- ENDIF(NOT Boost_FIND_QUIETLY)
- SET(Boost_LIBRARIES ${Boost_LIBRARIES} ${Boost_${UPPERCOMPONENT}_LIBRARY})
- ENDIF ( Boost_${UPPERCOMPONENT}_FOUND )
- ENDFOREACH(COMPONENT)
+ endif(NOT Boost_FIND_QUIETLY)
+ foreach( COMPONENT ${Boost_FIND_COMPONENTS} )
+ string( TOUPPER ${COMPONENT} UPPERCOMPONENT )
+ if( Boost_${UPPERCOMPONENT}_FOUND )
+ if(NOT Boost_FIND_QUIETLY)
+ message (STATUS " ${COMPONENT}")
+ endif(NOT Boost_FIND_QUIETLY)
+ set(Boost_LIBRARIES ${Boost_LIBRARIES} ${Boost_${UPPERCOMPONENT}_LIBRARY})
+ endif( Boost_${UPPERCOMPONENT}_FOUND )
+ endforeach(COMPONENT)
else()
if(Boost_FIND_REQUIRED)
message(SEND_ERROR "Unable to find the requested Boost libraries.\n${Boost_ERROR_REASON}")
@@ -924,9 +1213,8 @@ ELSE (_boost_IN_CACHE)
endif()
# show the Boost_INCLUDE_DIRS AND Boost_LIBRARIES variables only in the advanced view
- MARK_AS_ADVANCED(Boost_INCLUDE_DIR
+ mark_as_advanced(Boost_INCLUDE_DIR
Boost_INCLUDE_DIRS
Boost_LIBRARY_DIRS
)
-ENDIF(_boost_IN_CACHE)
-
+endif(_boost_IN_CACHE)
diff --git a/tests/FindGLEW.cmake b/tests/FindGLEW.cmake
index 32c2d6e..fa3071f 100644
--- a/tests/FindGLEW.cmake
+++ b/tests/FindGLEW.cmake
@@ -32,19 +32,22 @@ IF (WIN32)
ELSE (WIN32)
message(STATUS "GLEW_DIR: " ${GLEW_DIR})
FIND_PATH( GLEW_INCLUDE_PATH GL/glew.h
- PATHS ${GLEW_DIR}/include /usr/include /usr/local/include
+ HINTS ${GLEW_DIR}/include
+ PATHS /usr/include /usr/local/include
NO_DEFAULT_PATH
DOC "The directory where GL/glew.h resides")
FIND_LIBRARY( GLEW_LIBRARY
NAMES GLEW glew
- PATHS ${GLEW_DIR}/lib /usr/lib /usr/local/lib
+ HINTS ${GLEW_DIR}/lib
+ PATHS /usr/lib /usr/local/lib
NO_DEFAULT_PATH
DOC "The GLEW library")
ENDIF (WIN32)
IF (GLEW_INCLUDE_PATH)
SET( GLEW_FOUND 1 CACHE STRING "Set to 1 if GLEW is found, 0 otherwise")
- MESSAGE(STATUS "GLEW found in " ${GLEW_INCLUDE_PATH} " " ${GLEW_LIBRARY})
+ MESSAGE(STATUS "GLEW include found in " ${GLEW_INCLUDE_PATH} )
+ MESSAGE(STATUS "GLEW library found in " ${GLEW_LIBRARY} )
ELSE (GLEW_INCLUDE_PATH)
SET( GLEW_FOUND 0 CACHE STRING "Set to 1 if GLEW is found, 0 otherwise")
ENDIF (GLEW_INCLUDE_PATH)
diff --git a/tests/OffscreenContext.h b/tests/OffscreenContext.h
index a079c3f..6eebcba 100644
--- a/tests/OffscreenContext.h
+++ b/tests/OffscreenContext.h
@@ -2,10 +2,12 @@
#define OFFSCREENCONTEXT_H_
#include <iostream> // for error output
+#include <string>
struct OffscreenContext *create_offscreen_context(int w, int h);
void bind_offscreen_context(OffscreenContext *ctx);
bool teardown_offscreen_context(OffscreenContext *ctx);
bool save_framebuffer(OffscreenContext *ctx, const char *filename);
+std::string offscreen_context_getinfo(OffscreenContext *ctx);
#endif
diff --git a/tests/OffscreenContext.mm b/tests/OffscreenContext.mm
index 0c44d7d..990d3a4 100644
--- a/tests/OffscreenContext.mm
+++ b/tests/OffscreenContext.mm
@@ -2,9 +2,11 @@
#include "imageutils.h"
#include "fbo.h"
#include <iostream>
+#include <sstream>
#import <AppKit/AppKit.h> // for NSOpenGL...
-
+#include <CoreServices/CoreServices.h>
+#include <sys/utsname.h>
#define REPORTGLERROR(task) { GLenum tGLErr = glGetError(); if (tGLErr != GL_NO_ERROR) { std::cout << "OpenGL error " << tGLErr << " while " << task << "\n"; } }
@@ -17,6 +19,29 @@ struct OffscreenContext
fbo_t *fbo;
};
+std::string offscreen_context_getinfo(OffscreenContext *ctx)
+{
+ std::stringstream out;
+
+ struct utsname name;
+ uname(&name);
+
+ SInt32 majorVersion,minorVersion,bugFixVersion;
+
+ Gestalt(gestaltSystemVersionMajor, &majorVersion);
+ Gestalt(gestaltSystemVersionMinor, &minorVersion);
+ Gestalt(gestaltSystemVersionBugFix, &bugFixVersion);
+
+ const char *arch = "unknown";
+ if (sizeof(int*) == 4) arch = "32-bit";
+ else if (sizeof(int*) == 8) arch = "64-bit";
+
+ out << "GL context creator: Cocoa / CGL\n"
+ << "PNG generator: Core Foundation\n"
+ << "OS info: Mac OS X " << majorVersion << "." << minorVersion << "." << bugFixVersion << " (" << name.machine << " kernel)\n"
+ << "Machine: " << arch << "\n";
+ return out.str();
+}
OffscreenContext *create_offscreen_context(int w, int h)
{
@@ -84,6 +109,7 @@ bool teardown_offscreen_context(OffscreenContext *ctx)
*/
bool save_framebuffer(OffscreenContext *ctx, const char *filename)
{
+ if (!ctx || !filename) return false;
// Read pixels from OpenGL
int samplesPerPixel = 4; // R, G, B and A
int rowBytes = samplesPerPixel * ctx->width;
diff --git a/tests/OffscreenContext.cc b/tests/OffscreenContextGLX.cc
index 839eea9..e607593 100644
--- a/tests/OffscreenContext.cc
+++ b/tests/OffscreenContextGLX.cc
@@ -44,6 +44,11 @@ See Also
#include <GL/gl.h>
#include <GL/glx.h>
+#include <assert.h>
+#include <sstream>
+
+#include <sys/utsname.h> // for uname
+
using namespace std;
struct OffscreenContext
@@ -66,6 +71,42 @@ void offscreen_context_init(OffscreenContext &ctx, int width, int height)
ctx.fbo = NULL;
}
+string get_os_info()
+{
+ struct utsname u;
+ stringstream out;
+
+ if (uname(&u) < 0)
+ out << "OS info: unknown, uname() error\n";
+ else {
+ out << "OS info: "
+ << u.sysname << " "
+ << u.release << " "
+ << u.version << "\n";
+ out << "Machine: " << u.machine;
+ }
+ return out.str();
+}
+
+string offscreen_context_getinfo(OffscreenContext *ctx)
+{
+ assert(ctx);
+
+ if (!ctx->xdisplay)
+ return string("No GL Context initialized. No information to report\n");
+
+ int major, minor;
+ glXQueryVersion(ctx->xdisplay, &major, &minor);
+
+ stringstream out;
+ out << "GL context creator: GLX\n"
+ << "PNG generator: lodepng\n"
+ << "GLX version: " << major << "." << minor << "\n"
+ << get_os_info();
+
+ return out.str();
+}
+
static XErrorHandler original_xlib_handler = (XErrorHandler) NULL;
static bool XCreateWindow_failed = false;
static int XCreateWindow_error(Display *dpy, XErrorEvent *event)
@@ -94,11 +135,15 @@ bool create_glx_dummy_window(OffscreenContext &ctx)
*/
int attributes[] = {
- GLX_DRAWABLE_TYPE, GLX_WINDOW_BIT,
+ GLX_DRAWABLE_TYPE, GLX_WINDOW_BIT | GLX_PIXMAP_BIT | GLX_PBUFFER_BIT, //support all 3, for OpenCSG
GLX_RENDER_TYPE, GLX_RGBA_BIT,
- GLX_RED_SIZE, 1,
- GLX_GREEN_SIZE, 1,
- GLX_BLUE_SIZE, 1,
+ GLX_RED_SIZE, 8,
+ GLX_GREEN_SIZE, 8,
+ GLX_BLUE_SIZE, 8,
+ GLX_ALPHA_SIZE, 8,
+ GLX_DEPTH_SIZE, 24, // depth-stencil for OpenCSG
+ GLX_STENCIL_SIZE, 8,
+ GLX_DOUBLEBUFFER, True,
None
};
@@ -123,8 +168,9 @@ bool create_glx_dummy_window(OffscreenContext &ctx)
Window root = DefaultRootWindow( dpy );
XSetWindowAttributes xwin_attr;
- int width = 42;
- int height = 42;
+ int width = ctx.width;
+ int height = ctx.height;
+ xwin_attr.background_pixmap = None;
xwin_attr.background_pixel = 0;
xwin_attr.border_pixel = 0;
xwin_attr.colormap = XCreateColormap( dpy, root, visinfo->visual, AllocNone);
@@ -137,7 +183,6 @@ bool create_glx_dummy_window(OffscreenContext &ctx)
// Window xWin = XCreateSimpleWindow( dpy, DefaultRootWindow(dpy), 0,0,42,42, 0,0,0 );
-
XSync( dpy, false );
if ( XCreateWindow_failed ) {
XFree( visinfo );
@@ -227,7 +272,6 @@ OffscreenContext *create_offscreen_context(int w, int h)
cerr << "Unable to init GLEW: " << glewGetErrorString(err) << endl;
return NULL;
}
- glew_dump();
ctx->fbo = fbo_new();
if (!fbo_init(ctx->fbo, w, h)) {
@@ -256,6 +300,7 @@ bool teardown_offscreen_context(OffscreenContext *ctx)
*/
bool save_framebuffer(OffscreenContext *ctx, const char *filename)
{
+ glXSwapBuffers(ctx->xdisplay, ctx->xwindow);
if (!ctx || !filename) return false;
int samplesPerPixel = 4; // R, G, B and A
GLubyte pixels[ctx->width * ctx->height * samplesPerPixel];
@@ -265,7 +310,7 @@ bool save_framebuffer(OffscreenContext *ctx, const char *filename)
int rowBytes = samplesPerPixel * ctx->width;
unsigned char *flippedBuffer = (unsigned char *)malloc(rowBytes * ctx->height);
if (!flippedBuffer) {
- std::cerr << "Unable to allocate flipped buffer for corrected image.";
+ cerr << "Unable to allocate flipped buffer for corrected image.";
return 1;
}
flip_image(pixels, flippedBuffer, samplesPerPixel, ctx->width, ctx->height);
diff --git a/tests/OffscreenContextWGL.cc b/tests/OffscreenContextWGL.cc
index 3b966e2..f36671c 100644
--- a/tests/OffscreenContextWGL.cc
+++ b/tests/OffscreenContextWGL.cc
@@ -22,6 +22,10 @@ For more info:
#include <GL/gl.h> // must be included after glew.h
+#include <map>
+#include <string>
+#include <sstream>
+
using namespace std;
struct OffscreenContext
@@ -44,6 +48,45 @@ void offscreen_context_init(OffscreenContext &ctx, int width, int height)
ctx.fbo = NULL;
}
+string get_os_info()
+{
+ OSVERSIONINFO osvi;
+
+ ZeroMemory(&osvi, sizeof(OSVERSIONINFO));
+ osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
+ GetVersionEx(&osvi);
+
+ SYSTEM_INFO si;
+ GetSystemInfo(&si);
+ map<WORD,const char*> archs;
+ archs[PROCESSOR_ARCHITECTURE_AMD64] = "amd64";
+ archs[PROCESSOR_ARCHITECTURE_IA64] = "itanium";
+ archs[PROCESSOR_ARCHITECTURE_INTEL] = "x86";
+ archs[PROCESSOR_ARCHITECTURE_UNKNOWN] = "unknown";
+
+ stringstream out;
+ out << "OS info: "
+ << "Microsoft(TM) Windows(TM) " << osvi.dwMajorVersion << " "
+ << osvi.dwMinorVersion << " " << osvi.dwBuildNumber << " "
+ << osvi.szCSDVersion;
+ if (archs.find(si.wProcessorArchitecture) != archs.end())
+ out << " " << archs[si.wProcessorArchitecture];
+ out << "\n";
+
+ out << "Machine: " << si.dwProcessorType;
+
+ return out.str();
+}
+
+string offscreen_context_getinfo(OffscreenContext *ctx)
+{
+ stringstream out;
+ out << "GL context creator: WGL\n"
+ << "PNG generator: lodepng\n"
+ << get_os_info();
+ return out.str();
+}
+
LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam)
{
return DefWindowProc( hwnd, message, wparam, lparam );
@@ -87,11 +130,15 @@ bool create_wgl_dummy_context(OffscreenContext &ctx)
ZeroMemory( &pixformat, sizeof( pixformat ) );
pixformat.nSize = sizeof( pixformat );
pixformat.nVersion = 1;
- pixformat.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL;
+ pixformat.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER;
pixformat.iPixelType = PFD_TYPE_RGBA;
- pixformat.cColorBits = 24;
- pixformat.cDepthBits = 16;
- pixformat.iLayerType = PFD_MAIN_PLANE;
+ pixformat.cGreenBits = 8;
+ pixformat.cRedBits = 8;
+ pixformat.cBlueBits = 8;
+ pixformat.cAlphaBits = 8;
+ pixformat.cDepthBits = 24;
+ pixformat.cStencilBits = 8;
+
chosenformat = ChoosePixelFormat( dev_context, &pixformat );
if (chosenformat==0) {
cerr << "MS GDI - ChoosePixelFormat failed\n";
@@ -142,7 +189,7 @@ OffscreenContext *create_offscreen_context(int w, int h)
cerr << "Unable to init GLEW: " << glewGetErrorString(err) << "\n";
return NULL;
}
- glew_dump();
+ //cerr << glew_dump(0);
ctx->fbo = fbo_new();
if (!fbo_init(ctx->fbo, w, h)) {
@@ -172,6 +219,7 @@ bool teardown_offscreen_context(OffscreenContext *ctx)
*/
bool save_framebuffer(OffscreenContext *ctx, const char *filename)
{
+ wglSwapLayerBuffers( ctx->dev_context, WGL_SWAP_MAIN_PLANE );
if (!ctx || !filename) return false;
int samplesPerPixel = 4; // R, G, B and A
vector<GLubyte> pixels(ctx->width * ctx->height * samplesPerPixel);
diff --git a/tests/OffscreenView.cc b/tests/OffscreenView.cc
index 46951c1..61d5818 100644
--- a/tests/OffscreenView.cc
+++ b/tests/OffscreenView.cc
@@ -1,11 +1,12 @@
#include <GL/glew.h>
#include "OffscreenView.h"
-#include <opencsg.h>
+#include "system-gl.h"
#include "renderer.h"
#include <math.h>
#include <stdio.h>
#include <string.h>
#include <cstdlib>
+#include <sstream>
#define FAR_FAR_AWAY 100000.0
@@ -17,19 +18,6 @@ OffscreenView::OffscreenView(size_t width, size_t height)
this->ctx = create_offscreen_context(width, height);
if ( this->ctx == NULL ) throw -1;
-#ifdef DEBUG
- GLint rbits, gbits, bbits, abits, dbits, sbits;
- glGetIntegerv(GL_RED_BITS, &rbits);
- glGetIntegerv(GL_GREEN_BITS, &gbits);
- glGetIntegerv(GL_BLUE_BITS, &bbits);
- glGetIntegerv(GL_ALPHA_BITS, &abits);
- glGetIntegerv(GL_DEPTH_BITS, &dbits);
- glGetIntegerv(GL_STENCIL_BITS, &sbits);
-
- fprintf(stderr, "FBO: RGBA(%d%d%d%d), depth(%d), stencil(%d)\n",
- rbits, gbits, bbits, abits, dbits, sbits);
-#endif
-
initializeGL();
resizeGL(width, height);
}
@@ -68,105 +56,13 @@ void OffscreenView::initializeGL()
glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE);
glEnable(GL_COLOR_MATERIAL);
-#ifdef ENABLE_OPENCSG
- const char *openscad_disable_gl20_env = getenv("OPENSCAD_DISABLE_GL20");
- if (openscad_disable_gl20_env && !strcmp(openscad_disable_gl20_env, "0"))
- openscad_disable_gl20_env = NULL;
- if (glewIsSupported("GL_VERSION_2_0") && openscad_disable_gl20_env == NULL)
- {
- const char *vs_source =
- "uniform float xscale, yscale;\n"
- "attribute vec3 pos_b, pos_c;\n"
- "attribute vec3 trig, mask;\n"
- "varying vec3 tp, tr;\n"
- "varying float shading;\n"
- "void main() {\n"
- " vec4 p0 = gl_ModelViewProjectionMatrix * gl_Vertex;\n"
- " vec4 p1 = gl_ModelViewProjectionMatrix * vec4(pos_b, 1.0);\n"
- " vec4 p2 = gl_ModelViewProjectionMatrix * vec4(pos_c, 1.0);\n"
- " float a = distance(vec2(xscale*p1.x/p1.w, yscale*p1.y/p1.w), vec2(xscale*p2.x/p2.w, yscale*p2.y/p2.w));\n"
- " float b = distance(vec2(xscale*p0.x/p0.w, yscale*p0.y/p0.w), vec2(xscale*p1.x/p1.w, yscale*p1.y/p1.w));\n"
- " float c = distance(vec2(xscale*p0.x/p0.w, yscale*p0.y/p0.w), vec2(xscale*p2.x/p2.w, yscale*p2.y/p2.w));\n"
- " float s = (a + b + c) / 2.0;\n"
- " float A = sqrt(s*(s-a)*(s-b)*(s-c));\n"
- " float ha = 2.0*A/a;\n"
- " gl_Position = p0;\n"
- " tp = mask * ha;\n"
- " tr = trig;\n"
- " vec3 normal, lightDir;\n"
- " normal = normalize(gl_NormalMatrix * gl_Normal);\n"
- " lightDir = normalize(vec3(gl_LightSource[0].position));\n"
- " shading = abs(dot(normal, lightDir));\n"
- "}\n";
-
- const char *fs_source =
- "uniform vec4 color1, color2;\n"
- "varying vec3 tp, tr, tmp;\n"
- "varying float shading;\n"
- "void main() {\n"
- " gl_FragColor = vec4(color1.r * shading, color1.g * shading, color1.b * shading, color1.a);\n"
- " if (tp.x < tr.x || tp.y < tr.y || tp.z < tr.z)\n"
- " gl_FragColor = color2;\n"
- "}\n";
-
- GLuint vs = glCreateShader(GL_VERTEX_SHADER);
- glShaderSource(vs, 1, (const GLchar**)&vs_source, NULL);
- glCompileShader(vs);
-
- GLuint fs = glCreateShader(GL_FRAGMENT_SHADER);
- glShaderSource(fs, 1, (const GLchar**)&fs_source, NULL);
- glCompileShader(fs);
-
- GLuint edgeshader_prog = glCreateProgram();
- glAttachShader(edgeshader_prog, vs);
- glAttachShader(edgeshader_prog, fs);
- glLinkProgram(edgeshader_prog);
-
- shaderinfo[0] = edgeshader_prog;
- shaderinfo[1] = glGetUniformLocation(edgeshader_prog, "color1");
- shaderinfo[2] = glGetUniformLocation(edgeshader_prog, "color2");
- shaderinfo[3] = glGetAttribLocation(edgeshader_prog, "trig");
- shaderinfo[4] = glGetAttribLocation(edgeshader_prog, "pos_b");
- shaderinfo[5] = glGetAttribLocation(edgeshader_prog, "pos_c");
- shaderinfo[6] = glGetAttribLocation(edgeshader_prog, "mask");
- shaderinfo[7] = glGetUniformLocation(edgeshader_prog, "xscale");
- shaderinfo[8] = glGetUniformLocation(edgeshader_prog, "yscale");
-
- GLenum err = glGetError();
- if (err != GL_NO_ERROR) {
- fprintf(stderr, "OpenGL Error: %s\n", gluErrorString(err));
- }
-
- GLint status;
- glGetProgramiv(edgeshader_prog, GL_LINK_STATUS, &status);
- if (status == GL_FALSE) {
- int loglen;
- char logbuffer[1000];
- glGetProgramInfoLog(edgeshader_prog, sizeof(logbuffer), &loglen, logbuffer);
- fprintf(stderr, "OpenGL Program Linker Error:\n%.*s", loglen, logbuffer);
- } else {
- int loglen;
- char logbuffer[1000];
- glGetProgramInfoLog(edgeshader_prog, sizeof(logbuffer), &loglen, logbuffer);
- if (loglen > 0) {
- fprintf(stderr, "OpenGL Program Link OK:\n%.*s", loglen, logbuffer);
- }
- glValidateProgram(edgeshader_prog);
- glGetProgramInfoLog(edgeshader_prog, sizeof(logbuffer), &loglen, logbuffer);
- if (loglen > 0) {
- fprintf(stderr, "OpenGL Program Validation results:\n%.*s", loglen, logbuffer);
- }
- }
- }
-#endif /* ENABLE_OPENCSG */
+
}
void OffscreenView::resizeGL(int w, int h)
{
-#ifdef ENABLE_OPENCSG
- shaderinfo[9] = w;
- shaderinfo[10] = h;
-#endif
+ this->width = w;
+ this->height = h;
glViewport(0, 0, w, h);
w_h_ratio = sqrt((double)w / (double)h);
}
@@ -237,9 +133,6 @@ void OffscreenView::paintGL()
glColor3d(1.0, 0.0, 0.0);
if (this->renderer) {
-#ifdef ENABLE_OPENCSG
- OpenCSG::setContext(0);
-#endif
this->renderer->draw(showfaces, showedges);
}
}
@@ -249,6 +142,26 @@ bool OffscreenView::save(const char *filename)
return save_framebuffer(this->ctx, filename);
}
+std::string OffscreenView::getInfo()
+{
+ std::stringstream out;
+ GLint rbits, gbits, bbits, abits, dbits, sbits;
+ glGetIntegerv(GL_RED_BITS, &rbits);
+ glGetIntegerv(GL_GREEN_BITS, &gbits);
+ glGetIntegerv(GL_BLUE_BITS, &bbits);
+ glGetIntegerv(GL_ALPHA_BITS, &abits);
+ glGetIntegerv(GL_DEPTH_BITS, &dbits);
+ glGetIntegerv(GL_STENCIL_BITS, &sbits);
+
+ out << glew_dump(false)
+ << "FBO: RGBA(" << rbits << gbits << bbits << abits
+ << "), depth(" << dbits
+ << "), stencil(" << sbits << ")\n"
+ << offscreen_context_getinfo(this->ctx);
+
+ return out.str();
+}
+
void OffscreenView::setCamera(const Eigen::Vector3d &pos, const Eigen::Vector3d &center)
{
this->camera_eye = pos;
diff --git a/tests/OffscreenView.h b/tests/OffscreenView.h
index e3c8579..8b98b29 100644
--- a/tests/OffscreenView.h
+++ b/tests/OffscreenView.h
@@ -4,6 +4,7 @@
#include "OffscreenContext.h"
#include <Eigen/Core>
#include <Eigen/Geometry>
+#include <string>
#ifndef _MSC_VER
#include <stdint.h>
#endif
@@ -22,9 +23,12 @@ public:
void setupOrtho(bool offset=false);
void paintGL();
bool save(const char *filename);
+ std::string getInfo();
GLint shaderinfo[11];
OffscreenContext *ctx;
+ size_t width;
+ size_t height;
private:
Renderer *renderer;
double w_h_ratio;
diff --git a/tests/csgtestcore.cc b/tests/csgtestcore.cc
index 864d40e..a58c1fd 100644
--- a/tests/csgtestcore.cc
+++ b/tests/csgtestcore.cc
@@ -14,6 +14,7 @@
#include "CGALEvaluator.h"
#include "PolySetCGALEvaluator.h"
+#include <opencsg.h>
#include "OpenCSGRenderer.h"
#include "ThrownTogetherRenderer.h"
@@ -25,8 +26,15 @@
#include <QDir>
#include <QSet>
#include <QTimer>
+
#include <sstream>
+#include <vector>
+
+#include <boost/program_options.hpp>
+namespace po = boost::program_options;
+using std::string;
+using std::vector;
using std::cerr;
using std::cout;
@@ -64,16 +72,181 @@ AbstractNode *find_root_tag(AbstractNode *n)
return NULL;
}
+string info_dump(OffscreenView *glview)
+{
+ assert(glview);
+
+#ifdef __GNUG__
+#define compiler_info "GCC " << __VERSION__
+#elif defined(_MSC_VER)
+#define compiler_info "MSVC " << _MSC_FULL_VER
+#else
+#define compiler_info "unknown compiler"
+#endif
+
+#ifndef OPENCSG_VERSION_STRING
+#define OPENCSG_VERSION_STRING "unknown, <1.3.2"
+#endif
+
+ std::stringstream out;
+#define STRINGIFY(x) #x
+#define TOSTRING(x) STRINGIFY(x)
+ out << "\nOpenSCAD Version: " << TOSTRING(OPENSCAD_VERSION)
+ << "\nCompiled by: " << compiler_info
+ << "\nCompile date: " << __DATE__
+ << "\nBoost version: " << BOOST_LIB_VERSION
+ << "\nEigen version: " << EIGEN_WORLD_VERSION << "."
+ << EIGEN_MAJOR_VERSION << "." << EIGEN_MINOR_VERSION
+ << "\nCGAL version: " << TOSTRING(CGAL_VERSION)
+ << "\nOpenCSG version: " << OPENCSG_VERSION_STRING
+ << "\n" << glview->getInfo()
+ << "\n";
+
+ return out.str();
+}
+
+po::variables_map parse_options(int argc, char *argv[])
+{
+ po::options_description desc("Allowed options");
+ desc.add_options()
+ ("help,h", "help message")//;
+ ("info,i", "information on GLEW, OpenGL, OpenSCAD, and OS")//;
+
+// po::options_description hidden("Hidden options");
+// hidden.add_options()
+ ("input-file", po::value< vector<string> >(), "input file")
+ ("output-file", po::value< vector<string> >(), "ouput file");
+
+ po::positional_options_description p;
+ p.add("input-file", 1).add("output-file", 1);
+
+ po::options_description all_options;
+ all_options.add(desc); // .add(hidden);
+
+ po::variables_map vm;
+ po::store(po::command_line_parser(argc, argv).options(all_options).positional(p).run(), vm);
+ po::notify(vm);
+
+ return vm;
+}
+
+void enable_opencsg_shaders( OffscreenView *glview )
+{
+ bool ignore_gl_version = true;
+ const char *openscad_disable_gl20_env = getenv("OPENSCAD_DISABLE_GL20");
+ if (openscad_disable_gl20_env && !strcmp(openscad_disable_gl20_env, "0"))
+ openscad_disable_gl20_env = NULL;
+ if (glewIsSupported("GL_VERSION_2_0") && openscad_disable_gl20_env == NULL )
+ {
+ const char *vs_source =
+ "uniform float xscale, yscale;\n"
+ "attribute vec3 pos_b, pos_c;\n"
+ "attribute vec3 trig, mask;\n"
+ "varying vec3 tp, tr;\n"
+ "varying float shading;\n"
+ "void main() {\n"
+ " vec4 p0 = gl_ModelViewProjectionMatrix * gl_Vertex;\n"
+ " vec4 p1 = gl_ModelViewProjectionMatrix * vec4(pos_b, 1.0);\n"
+ " vec4 p2 = gl_ModelViewProjectionMatrix * vec4(pos_c, 1.0);\n"
+ " float a = distance(vec2(xscale*p1.x/p1.w, yscale*p1.y/p1.w), vec2(xscale*p2.x/p2.w, yscale*p2.y/p2.w));\n"
+ " float b = distance(vec2(xscale*p0.x/p0.w, yscale*p0.y/p0.w), vec2(xscale*p1.x/p1.w, yscale*p1.y/p1.w));\n"
+ " float c = distance(vec2(xscale*p0.x/p0.w, yscale*p0.y/p0.w), vec2(xscale*p2.x/p2.w, yscale*p2.y/p2.w));\n"
+ " float s = (a + b + c) / 2.0;\n"
+ " float A = sqrt(s*(s-a)*(s-b)*(s-c));\n"
+ " float ha = 2.0*A/a;\n"
+ " gl_Position = p0;\n"
+ " tp = mask * ha;\n"
+ " tr = trig;\n"
+ " vec3 normal, lightDir;\n"
+ " normal = normalize(gl_NormalMatrix * gl_Normal);\n"
+ " lightDir = normalize(vec3(gl_LightSource[0].position));\n"
+ " shading = abs(dot(normal, lightDir));\n"
+ "}\n";
+
+ const char *fs_source =
+ "uniform vec4 color1, color2;\n"
+ "varying vec3 tp, tr, tmp;\n"
+ "varying float shading;\n"
+ "void main() {\n"
+ " gl_FragColor = vec4(color1.r * shading, color1.g * shading, color1.b * shading, color1.a);\n"
+ " if (tp.x < tr.x || tp.y < tr.y || tp.z < tr.z)\n"
+ " gl_FragColor = color2;\n"
+ "}\n";
+
+ GLuint vs = glCreateShader(GL_VERTEX_SHADER);
+ glShaderSource(vs, 1, (const GLchar**)&vs_source, NULL);
+ glCompileShader(vs);
+
+ GLuint fs = glCreateShader(GL_FRAGMENT_SHADER);
+ glShaderSource(fs, 1, (const GLchar**)&fs_source, NULL);
+ glCompileShader(fs);
+
+ GLuint edgeshader_prog = glCreateProgram();
+ glAttachShader(edgeshader_prog, vs);
+ glAttachShader(edgeshader_prog, fs);
+ glLinkProgram(edgeshader_prog);
+
+ glview->shaderinfo[0] = edgeshader_prog;
+ glview->shaderinfo[1] = glGetUniformLocation(edgeshader_prog, "color1");
+ glview->shaderinfo[2] = glGetUniformLocation(edgeshader_prog, "color2");
+ glview->shaderinfo[3] = glGetAttribLocation(edgeshader_prog, "trig");
+ glview->shaderinfo[4] = glGetAttribLocation(edgeshader_prog, "pos_b");
+ glview->shaderinfo[5] = glGetAttribLocation(edgeshader_prog, "pos_c");
+ glview->shaderinfo[6] = glGetAttribLocation(edgeshader_prog, "mask");
+ glview->shaderinfo[7] = glGetUniformLocation(edgeshader_prog, "xscale");
+ glview->shaderinfo[8] = glGetUniformLocation(edgeshader_prog, "yscale");
+
+ GLenum err = glGetError();
+ if (err != GL_NO_ERROR) {
+ fprintf(stderr, "OpenGL Error: %s\n", gluErrorString(err));
+ }
+
+ GLint status;
+ glGetProgramiv(edgeshader_prog, GL_LINK_STATUS, &status);
+ if (status == GL_FALSE) {
+ int loglen;
+ char logbuffer[1000];
+ glGetProgramInfoLog(edgeshader_prog, sizeof(logbuffer), &loglen, logbuffer);
+ fprintf(stderr, "OpenGL Program Linker Error:\n%.*s", loglen, logbuffer);
+ } else {
+ int loglen;
+ char logbuffer[1000];
+ glGetProgramInfoLog(edgeshader_prog, sizeof(logbuffer), &loglen, logbuffer);
+ if (loglen > 0) {
+ fprintf(stderr, "OpenGL Program Link OK:\n%.*s", loglen, logbuffer);
+ }
+ glValidateProgram(edgeshader_prog);
+ glGetProgramInfoLog(edgeshader_prog, sizeof(logbuffer), &loglen, logbuffer);
+ if (loglen > 0) {
+ fprintf(stderr, "OpenGL Program Validation results:\n%.*s", loglen, logbuffer);
+ }
+ }
+ }
+ glview->shaderinfo[9] = glview->width;
+ glview->shaderinfo[10] = glview->height;
+}
+
int csgtestcore(int argc, char *argv[], test_type_e test_type)
{
- if (argc != 3) {
- fprintf(stderr, "Usage: %s <file.scad> <output.png>\n", argv[0]);
+ bool sysinfo_dump = false;
+ const char *filename, *outfilename = NULL;
+ po::variables_map vm;
+ try {
+ vm = parse_options(argc, argv);
+ } catch ( po::error e ) {
+ cerr << "error parsing options\n";
+ }
+ if (vm.count("info")) sysinfo_dump = true;
+ if (vm.count("input-file"))
+ filename = vm["input-file"].as< vector<string> >().begin()->c_str();
+ if (vm.count("output-file"))
+ outfilename = vm["output-file"].as< vector<string> >().begin()->c_str();
+
+ if ((!filename || !outfilename) && !sysinfo_dump) {
+ cerr << "Usage: " << argv[0] << " <file.scad> <output.png>\n";
exit(1);
}
- const char *filename = argv[1];
- const char *outfilename = argv[2];
-
Builtins::instance()->initialize();
QApplication app(argc, argv, false);
@@ -107,13 +280,18 @@ int csgtestcore(int argc, char *argv[], test_type_e test_type)
AbstractModule *root_module;
ModuleInstantiation root_inst;
- root_module = parsefile(filename);
+ if (sysinfo_dump)
+ root_module = parse("sphere();","",false);
+ else
+ root_module = parsefile(filename);
+
if (!root_module) {
exit(1);
}
QFileInfo fileInfo(filename);
- QDir::setCurrent(fileInfo.absolutePath());
+ if (!sysinfo_dump)
+ QDir::setCurrent(fileInfo.absolutePath());
AbstractNode::resetIndexCounter();
AbstractNode *absolute_root_node = root_module->evaluate(&root_ctx, &root_inst);
@@ -150,7 +328,7 @@ int csgtestcore(int argc, char *argv[], test_type_e test_type)
csgInfo.root_chain = new CSGChain();
csgInfo.root_chain->import(csgInfo.root_norm_term);
- fprintf(stderr, "Normalized CSG tree has %d elements\n", csgInfo.root_chain->polysets.size());
+ fprintf(stderr, "Normalized CSG tree has %d elements\n", int(csgInfo.root_chain->polysets.size()));
if (csgInfo.highlight_terms.size() > 0) {
cerr << "Compiling highlights (" << csgInfo.highlight_terms.size() << " CSG Trees)...\n";
@@ -188,6 +366,9 @@ int csgtestcore(int argc, char *argv[], test_type_e test_type)
fprintf(stderr,"Can't create OpenGL OffscreenView. Code: %i. Exiting.\n", error);
exit(1);
}
+ enable_opencsg_shaders(csgInfo.glview);
+
+ if (sysinfo_dump) cout << info_dump(csgInfo.glview);
BoundingBox bbox = csgInfo.root_chain->getBoundingBox();
Vector3d center = (bbox.min() + bbox.max()) / 2;
@@ -206,8 +387,11 @@ int csgtestcore(int argc, char *argv[], test_type_e test_type)
else
csgInfo.glview->setRenderer(&opencsgRenderer);
- csgInfo.glview->paintGL();
+ OpenCSG::setContext(0);
+ OpenCSG::setOption(OpenCSG::OffscreenSetting, OpenCSG::FrameBufferObject);
+ csgInfo.glview->paintGL();
+
csgInfo.glview->save(outfilename);
delete root_node;
diff --git a/tests/fbo.cc b/tests/fbo.cc
index 2a3342d..a6677c1 100644
--- a/tests/fbo.cc
+++ b/tests/fbo.cc
@@ -93,6 +93,7 @@ bool fbo_ext_init(fbo_t *fbo, size_t width, size_t height)
glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT,
GL_RENDERBUFFER_EXT, fbo->depthbuf_id);
if (report_glerror("specifying depth render buffer EXT")) return false;
+
glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_STENCIL_ATTACHMENT_EXT,
GL_RENDERBUFFER_EXT, fbo->depthbuf_id);
if (report_glerror("specifying stencil render buffer EXT")) return false;
@@ -142,7 +143,12 @@ bool fbo_arb_init(fbo_t *fbo, size_t width, size_t height)
return false;
}
- glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT,
+ //glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT,
+ // to prevent Mesa's software renderer from crashing, do this in two stages.
+ // ie. instead of using GL_DEPTH_STENCIL_ATTACHMENT, do DEPTH then STENCIL.
+ glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT,
+ GL_RENDERBUFFER, fbo->depthbuf_id);
+ glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT,
GL_RENDERBUFFER, fbo->depthbuf_id);
if (report_glerror("specifying depth stencil render buffer")) return false;
@@ -183,24 +189,25 @@ bool fbo_resize(fbo_t *fbo, size_t width, size_t height)
glBindRenderbufferEXT(GL_RENDERBUFFER, fbo->depthbuf_id);
if (glewIsSupported("GL_EXT_packed_depth_stencil")) {
glRenderbufferStorageEXT(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, width, height);
- if (report_glerror("creating depth stencil render buffer")) return false;
+ if (report_glerror("creating EXT depth stencil render buffer")) return false;
}
else {
glRenderbufferStorageEXT(GL_RENDERBUFFER, GL_DEPTH_COMPONENT24, width, height);
- if (report_glerror("creating depth render buffer")) return false;
+ if (report_glerror("creating EXT depth render buffer")) return false;
}
glBindRenderbufferEXT(GL_RENDERBUFFER, fbo->renderbuf_id);
glRenderbufferStorageEXT(GL_RENDERBUFFER, GL_RGBA8, width, height);
- if (report_glerror("creating color render buffer")) return false;
+ if (report_glerror("creating EXT color render buffer")) return false;
} else {
+ glBindRenderbuffer(GL_RENDERBUFFER, fbo->renderbuf_id);
+ glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA8, width, height);
+ if (report_glerror("creating color render buffer")) return false;
+
glBindRenderbuffer(GL_RENDERBUFFER, fbo->depthbuf_id);
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, width, height);
if (report_glerror("creating depth stencil render buffer")) return false;
- glBindRenderbuffer(GL_RENDERBUFFER, fbo->renderbuf_id);
- glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA8, width, height);
- if (report_glerror("creating color render buffer")) return false;
}
return true;
diff --git a/tests/regression/cgalpngtest/hull2-tests-expected.png b/tests/regression/cgalpngtest/hull2-tests-expected.png
index 256b349..508974f 100644
--- a/tests/regression/cgalpngtest/hull2-tests-expected.png
+++ b/tests/regression/cgalpngtest/hull2-tests-expected.png
Binary files differ
diff --git a/tests/regression/dumptest/hull2-tests-expected.txt b/tests/regression/dumptest/hull2-tests-expected.txt
index 87365a6..d060d1d 100644
--- a/tests/regression/dumptest/hull2-tests-expected.txt
+++ b/tests/regression/dumptest/hull2-tests-expected.txt
@@ -32,4 +32,28 @@
}
}
}
+ multmatrix([[1, 0, 0, 30], [0, 1, 0, -25], [0, 0, 1, 0], [0, 0, 0, 1]]) {
+ group() {
+ hull() {
+ group() {
+ group() {
+ multmatrix([[1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1]]) {
+ circle($fn = 0, $fa = 12, $fs = 1, r = 3);
+ }
+ multmatrix([[1, 0, 0, 0], [0, 1, 0, 10], [0, 0, 1, 0], [0, 0, 0, 1]]) {
+ circle($fn = 0, $fa = 12, $fs = 1, r = 3);
+ }
+ }
+ group() {
+ multmatrix([[1, 0, 0, 10], [0, 1, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1]]) {
+ circle($fn = 0, $fa = 12, $fs = 1, r = 3);
+ }
+ multmatrix([[1, 0, 0, 10], [0, 1, 0, 10], [0, 0, 1, 0], [0, 0, 0, 1]]) {
+ circle($fn = 0, $fa = 12, $fs = 1, r = 3);
+ }
+ }
+ }
+ }
+ }
+ }
diff --git a/tests/regression/opencsgtest/color-tests-expected.png b/tests/regression/opencsgtest/color-tests-expected.png
index b2ef8dd..82ba36a 100644
--- a/tests/regression/opencsgtest/color-tests-expected.png
+++ b/tests/regression/opencsgtest/color-tests-expected.png
Binary files differ
diff --git a/tests/regression/opencsgtest/hull2-tests-expected.png b/tests/regression/opencsgtest/hull2-tests-expected.png
index 66ee6b2..46b266b 100644
--- a/tests/regression/opencsgtest/hull2-tests-expected.png
+++ b/tests/regression/opencsgtest/hull2-tests-expected.png
Binary files differ
diff --git a/tests/regression/opencsgtest/sphere-tests-expected.png b/tests/regression/opencsgtest/sphere-tests-expected.png
index 06161f3..d11e3bf 100644
--- a/tests/regression/opencsgtest/sphere-tests-expected.png
+++ b/tests/regression/opencsgtest/sphere-tests-expected.png
Binary files differ
diff --git a/tests/regression/opencsgtest/testcolornames-expected.png b/tests/regression/opencsgtest/testcolornames-expected.png
index 6fc6569..6c1b107 100644
--- a/tests/regression/opencsgtest/testcolornames-expected.png
+++ b/tests/regression/opencsgtest/testcolornames-expected.png
Binary files differ
diff --git a/tests/regression/throwntogethertest/color-tests-expected.png b/tests/regression/throwntogethertest/color-tests-expected.png
index 6b50080..5d4ed89 100644
--- a/tests/regression/throwntogethertest/color-tests-expected.png
+++ b/tests/regression/throwntogethertest/color-tests-expected.png
Binary files differ
diff --git a/tests/regression/throwntogethertest/hull2-tests-expected.png b/tests/regression/throwntogethertest/hull2-tests-expected.png
index 221cbaf..46b266b 100644
--- a/tests/regression/throwntogethertest/hull2-tests-expected.png
+++ b/tests/regression/throwntogethertest/hull2-tests-expected.png
Binary files differ
diff --git a/tests/regression/throwntogethertest/sphere-tests-expected.png b/tests/regression/throwntogethertest/sphere-tests-expected.png
index 4792668..d11e3bf 100644
--- a/tests/regression/throwntogethertest/sphere-tests-expected.png
+++ b/tests/regression/throwntogethertest/sphere-tests-expected.png
Binary files differ
diff --git a/tests/system-gl.cc b/tests/system-gl.cc
index bdf3bf9..2e3f3bc 100644
--- a/tests/system-gl.cc
+++ b/tests/system-gl.cc
@@ -2,35 +2,40 @@
/* OpenGL helper functions */
#include <iostream>
+#include <sstream>
+#include <string>
#include "system-gl.h"
#include <boost/algorithm/string.hpp>
using namespace std;
using namespace boost;
-void glew_dump(bool dumpall) {
-#ifdef DEBUG
- cerr << "GLEW version: " << glewGetString(GLEW_VERSION) << endl
- << "Renderer: " << (const char *)glGetString(GL_RENDERER) << endl
- << "Vendor: " << (const char *)glGetString(GL_VENDOR) << endl
- << "OpenGL version: " << (const char *)glGetString(GL_VERSION) << endl;
+string glew_dump(bool dumpall)
+{
+ stringstream out;
+ out << "GLEW version: " << glewGetString(GLEW_VERSION) << endl
+ << "GL Renderer: " << (const char *)glGetString(GL_RENDERER) << endl
+ << "GL Vendor: " << (const char *)glGetString(GL_VENDOR) << endl
+ << "OpenGL Version: " << (const char *)glGetString(GL_VERSION) << endl;
+ out << "GL Extensions: " << endl;
if (dumpall) {
string extensions((const char *)glGetString(GL_EXTENSIONS));
replace_all( extensions, " ", "\n " );
- cerr << "Extensions: " << endl << " " << extensions << endl;
+ out << " " << extensions << endl;
}
- cerr << " GL_ARB_framebuffer_object: "
- << (glewIsSupported("GL_ARB_framebuffer_object") ? "yes" : "no")
- << endl
- << " GL_EXT_framebuffer_object: "
- << (glewIsSupported("GL_EXT_framebuffer_object") ? "yes" : "no")
- << endl
- << " GL_EXT_packed_depth_stencil: "
- << (glewIsSupported("GL_EXT_packed_depth_stencil") ? "yes" : "no")
- << endl;
-#endif
+ out << "GL_ARB_framebuffer_object: "
+ << (glewIsSupported("GL_ARB_framebuffer_object") ? "yes" : "no")
+ << endl
+ << "GL_EXT_framebuffer_object: "
+ << (glewIsSupported("GL_EXT_framebuffer_object") ? "yes" : "no")
+ << endl
+ << "GL_EXT_packed_depth_stencil: "
+ << (glewIsSupported("GL_EXT_packed_depth_stencil") ? "yes" : "no")
+ << endl;
+
+ return out.str();
};
bool report_glerror(const char * function)
diff --git a/tests/system-gl.h b/tests/system-gl.h
index b41e32c..4a8ccac 100644
--- a/tests/system-gl.h
+++ b/tests/system-gl.h
@@ -2,8 +2,9 @@
#define SYSTEMGL_H_
#include <GL/glew.h>
+#include <string>
-void glew_dump(bool dumpall = false);
+std::string glew_dump(bool dumpall=false);
bool report_glerror(const char *task);
#endif
diff --git a/tests/test_cmdline_tool.py b/tests/test_cmdline_tool.py
index 8b49f78..848a6eb 100755
--- a/tests/test_cmdline_tool.py
+++ b/tests/test_cmdline_tool.py
@@ -26,6 +26,7 @@ import re
import getopt
import shutil
import platform
+import string
def initialize_environment():
if not options.generate: options.generate = bool(os.getenv("TEST_GENERATE"))
@@ -35,6 +36,7 @@ def init_expected_filename(testname, cmd):
global expecteddir, expectedfilename
expecteddir = os.path.join(options.regressiondir, os.path.split(cmd)[1])
expectedfilename = os.path.join(expecteddir, testname + "-expected." + options.suffix)
+ expectedfilename = os.path.normpath( expectedfilename )
def verify_test(testname, cmd):
global expectedfilename
@@ -47,7 +49,7 @@ def verify_test(testname, cmd):
def execute_and_redirect(cmd, params, outfile):
retval = -1
try:
- proc = subprocess.Popen([cmd] + params, stdout=outfile)
+ proc = subprocess.Popen([cmd] + params, stdout=outfile, stderr=subprocess.STDOUT)
out = proc.communicate()[0]
retval = proc.wait()
except:
@@ -66,32 +68,52 @@ def compare_text(expected, actual):
return get_normalized_text(expected) == get_normalized_text(actual)
def compare_default(resultfilename):
+ print >> sys.stderr, 'diff text compare: '
+ print >> sys.stderr, ' expected textfile: ', expectedfilename
+ print >> sys.stderr, ' actual textfile: ', resultfilename
if not compare_text(expectedfilename, resultfilename):
execute_and_redirect("diff", [expectedfilename, resultfilename], sys.stderr)
return False
return True
def compare_png(resultfilename):
+ compare_method = 'pixel'
+ #args = [expectedfilename, resultfilename, "-alpha", "Off", "-compose", "difference", "-composite", "-threshold", "10%", "-blur", "2", "-threshold", "30%", "-format", "%[fx:w*h*mean]", "info:"]
+ args = [expectedfilename, resultfilename, "-alpha", "Off", "-compose", "difference", "-composite", "-threshold", "10%", "-morphology", "Erode", "Square", "-format", "%[fx:w*h*mean]", "info:"]
+
+ # for systems with older imagemagick that doesnt support '-morphology'
+ # http://www.imagemagick.org/Usage/morphology/#alturnative
+ if options.comparator == 'old':
+ args = [expectedfilename, resultfilename, "-alpha", "Off", "-compose", "difference", "-composite", "-threshold", "10%", "-gaussian-blur","3x65535", "-threshold", "99.99%", "-format", "%[fx:w*h*mean]", "info:"]
+
+ if options.comparator == 'ncc':
+ # for systems where imagemagick crashes when using the above comparators
+ args = [expectedfilename, resultfilename, "-alpha", "Off", "-compose", "difference", "-metric", "NCC", "tmp.png"]
+ options.convert_exec = 'compare'
+ compare_method = 'NCC'
+
+ msg = 'ImageMagick image comparison: ' + options.convert_exec + ' '+ ' '.join(args[2:])
+ msg += '\nexpected image: ' + expectedfilename + '\n'
+ print >> sys.stderr, msg
if not resultfilename:
- print >> sys.stderr, "Error: OpenSCAD did not generate an image"
+ print >> sys.stderr, "Error: OpenSCAD did not generate an image to test"
return False
+ print >> sys.stderr, ' actual image: ', resultfilename
-# args = [expectedfilename, resultfilename, "-alpha", "Off", "-compose", "difference", "-composite", "-threshold", "10%", "-blur", "2", "-threshold", "30%", "-format", "%[fx:w*h*mean]", "info:"]
- args = [expectedfilename, resultfilename, "-alpha", "Off", "-compose", "difference", "-composite", "-threshold", "10%", "-morphology", "Erode", "Square", "-format", "%[fx:w*h*mean]", "info:"]
- print >> sys.stderr, 'convert ', ' '.join(args)
- (retval, output) = execute_and_redirect("convert", args, subprocess.PIPE)
+ (retval, output) = execute_and_redirect(options.convert_exec, args, subprocess.PIPE)
+ print "Imagemagick return", retval, "output:", output
if retval == 0:
- pixelerr = int(float(output.strip()))
- if pixelerr < 32: return True
- else: print >> sys.stderr, pixelerr, ' pixel errors'
+ if compare_method=='pixel':
+ pixelerr = int(float(output.strip()))
+ if pixelerr < 32: return True
+ else: print >> sys.stderr, pixelerr, ' pixel errors'
+ elif compare_method=='NCC':
+ thresh = 0.95
+ ncc_err = float(output.strip())
+ if ncc_err > thresh: return True
+ else: print >> sys.stderr, ncc_err, ' Images differ: NCC comparison < ', thresh
return False
-# Old compare solution, based on yee_compare
-# print >> sys.stderr, 'Yee image compare: ', expectedfilename, ' ', resultfilename
-# if execute_and_redirect("./yee_compare", [expectedfilename, resultfilename, "-downsample", "1", "-threshold", "150"], sys.stderr) != 0:
-# return False
-# return True
-
def compare_with_expected(resultfilename):
if not options.generate:
if "compare_" + options.suffix in globals(): return globals()["compare_" + options.suffix](resultfilename)
@@ -143,11 +165,12 @@ def usage():
print >> sys.stderr, " -g, --generate Generate expected output for the given tests"
print >> sys.stderr, " -s, --suffix=<suffix> Write -expected and -actual files with the given suffix instead of .txt"
print >> sys.stderr, " -t, --test=<name> Specify test name instead of deducting it from the argument"
+ print >> sys.stderr, " -c, --convexec=<name> Path to ImageMagick 'convert' executable"
if __name__ == '__main__':
# Handle command-line arguments
try:
- opts, args = getopt.getopt(sys.argv[1:], "gs:t:", ["generate", "suffix=", "test="])
+ opts, args = getopt.getopt(sys.argv[1:], "gs:c:t:m:", ["generate", "convexec=", "suffix=", "test=", "comparator="])
except getopt.GetoptError, err:
usage()
sys.exit(2)
@@ -165,6 +188,10 @@ if __name__ == '__main__':
else: options.suffix = a
elif o in ("-t", "--test"):
options.testname = a
+ elif o in ("-c", "--convexec"):
+ options.convert_exec = os.path.normpath( a )
+ elif o in ("-m", "--comparator"):
+ options.comparator = a
# <cmdline-tool> and <argument>
if len(args) < 2:
diff --git a/tests/test_pretty_print.py b/tests/test_pretty_print.py
new file mode 100755
index 0000000..53fcc37
--- /dev/null
+++ b/tests/test_pretty_print.py
@@ -0,0 +1,503 @@
+#!/usr/bin/python
+
+# Copyright (C) 2011 Don Bright <hugh.m.bright@gmail.com>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+#
+# This program 'pretty prints' the ctest output, namely
+# files from builddir/Testing/Temporary.
+# html & wiki output are produced in Testing/Temporary/sysid_report
+#
+# experimental wiki uploading is available by running
+#
+# python test_pretty_print.py --upload
+#
+
+# Design philosophy
+#
+# 1. parse the data (images, logs) into easy-to-use data structures
+# 2. wikifiy the data
+# 3. save the wikified data to disk
+
+# todo
+# deal better with the situation where Offscreen rendering fails
+# do something if tests for GL extensions for OpenCSG fail (test fail, no image production)
+# copy all images, sysinfo.txt to bundle for html/upload (images
+# can be altered by subsequent runs)
+# why is hash differing
+# fix windows so that it won't keep asking 'this program crashed' over and over.
+# (you can set this in the registry to never happen, but itd be better if the program
+# itself was able to disable that temporarily in it's own process)
+
+import string,sys,re,os,hashlib,subprocess,textwrap,time,platform
+
+def tryread(filename):
+ data = None
+ try:
+ f = open(filename,'rb')
+ data = f.read()
+ f.close()
+ except:
+ print 'couldn\'t open ',filename
+ return data
+
+def trysave(filename,data):
+ try:
+ if not os.path.isdir(os.path.dirname(filename)):
+ #print 'creating',os.path.dirname(filename)
+ os.mkdir(os.path.dirname(filename))
+ f=open(filename,'wb')
+ f.write(data)
+ f.close()
+ except:
+ print 'problem writing to',filename
+ return None
+ return True
+
+def ezsearch(pattern,str):
+ x = re.search(pattern,str,re.DOTALL|re.MULTILINE)
+ if x and len(x.groups())>0: return x.group(1).strip()
+ return ''
+
+def read_gitinfo():
+ # won't work if run from outside of branch.
+ data = subprocess.Popen(['git','remote','-v'],stdout=subprocess.PIPE).stdout.read()
+ origin = ezsearch('^origin *?(.*?)\(fetch.*?$',data)
+ upstream = ezsearch('^upstream *?(.*?)\(fetch.*?$',data)
+ data = subprocess.Popen(['git','branch'],stdout=subprocess.PIPE).stdout.read()
+ branch = ezsearch('^\*(.*?)$',data)
+ out = 'Git branch: ' + branch + ' from origin ' + origin + '\n'
+ out += 'Git upstream: ' + upstream + '\n'
+ return out
+
+def read_sysinfo(filename):
+ data = tryread(filename)
+ if not data:
+ sinfo = platform.sys.platform
+ sinfo += '\nsystem cannot create offscreen GL framebuffer object'
+ sinfo += '\nsystem cannot create images'
+ sysid = platform.sys.platform+'_no_images'
+ return sinfo, sysid
+
+ machine = ezsearch('Machine:(.*?)\n',data)
+ machine = machine.replace(' ','-').replace('/','-')
+
+ osinfo = ezsearch('OS info:(.*?)\n',data)
+ osplain = osinfo.split(' ')[0].strip().replace('/','-')
+ if 'windows' in osinfo.lower(): osplain = 'win'
+
+ renderer = ezsearch('GL Renderer:(.*?)\n',data)
+ tmp = renderer.split(' ')
+ tmp = string.join(tmp[0:3],'-')
+ tmp = tmp.split('/')[0]
+ renderer = tmp
+
+ data += read_gitinfo()
+
+ data += 'Image comparison: ImageMagick'
+
+ data = data.strip()
+
+ # create 4 letter hash and stick on end of sysid
+ nondate_data = re.sub("\n.*?ompile date.*?\n","\n",data).strip()
+ hexhash = hashlib.md5()
+ hexhash.update(nondate_data)
+ hexhash = hexhash.hexdigest()[-4:].upper()
+ hash = ''
+ for c in hexhash: hash += chr(ord(c)+97-48)
+
+ sysid = osplain + '_' + machine + '_' + renderer + '_' + hash
+ sysid = sysid.lower()
+
+ return data, sysid
+
+class Test:
+ def __init__(self,fullname,time,passed,output,type,actualfile,expectedfile,scadfile,log):
+ self.fullname,self.time,self.passed,self.output = \
+ fullname, time, passed, output
+ self.type, self.actualfile, self.expectedfile, self.scadfile = \
+ type, actualfile, expectedfile, scadfile
+ self.fulltestlog = log
+
+ def __str__(self):
+ x = 'fullname: ' + self.fullname
+ x+= '\nactualfile: ' + self.actualfile
+ x+= '\nexpectedfile: ' + self.expectedfile
+ x+= '\ntesttime: ' + self.time
+ x+= '\ntesttype: ' + self.type
+ x+= '\npassed: ' + str(self.passed)
+ x+= '\nscadfile: ' + self.scadfile
+ x+= '\noutput bytes: ' + str(len(self.output))
+ x+= '\ntestlog bytes: ' + str(len(self.fulltestlog))
+ x+= '\n'
+ return x
+
+def parsetest(teststring):
+ patterns = ["Test:(.*?)\n", # fullname
+ "Test time =(.*?) sec\n",
+ "Test time.*?Test (Passed)", # pass/fail
+ "Output:(.*?)<end of output>",
+ 'Command:.*?-s" "(.*?)"', # type
+ "actual .*?:(.*?)\n",
+ "expected .*?:(.*?)\n",
+ 'Command:.*?(testdata.*?)"' # scadfile
+ ]
+ hits = map( lambda pattern: ezsearch(pattern,teststring), patterns )
+ test = Test(hits[0],hits[1],hits[2]=='Passed',hits[3],hits[4],hits[5],hits[6],hits[7],teststring)
+ test.actualfile_data = tryread(test.actualfile)
+ test.expectedfile_data = tryread(test.expectedfile)
+ return test
+
+def parselog(data):
+ startdate = ezsearch('Start testing: (.*?)\n',data)
+ enddate = ezsearch('End testing: (.*?)\n',data)
+ pattern = '([0-9]*/[0-9]* Testing:.*?time elapsed.*?\n)'
+ test_chunks = re.findall(pattern,data,re.S)
+ tests = map( parsetest, test_chunks )
+ tests = sorted(tests, key = lambda t:t.passed)
+ return startdate, tests, enddate
+
+def load_makefiles(builddir):
+ filelist = []
+ for root, dirs, files in os.walk(builddir):
+ for fname in files: filelist += [ os.path.join(root, fname) ]
+ files = filter(lambda x: 'build.make' in os.path.basename(x), filelist)
+ files += filter(lambda x: 'flags.make' in os.path.basename(x), filelist)
+ files = filter(lambda x: 'esting' not in x and 'emporary' not in x, files)
+ result = {}
+ for fname in files:
+ result[fname.replace(builddir,'')] = open(fname,'rb').read()
+ return result
+
+def wikify_filename(fname, wiki_rootpath, sysid):
+ wikifname = fname.replace('/','_').replace('\\','_').strip('.')
+ return wiki_rootpath + '_' + sysid + '_' + wikifname
+
+def towiki(wiki_rootpath, startdate, tests, enddate, sysinfo, sysid, makefiles):
+
+ wiki_template = """
+<h3>[[WIKI_ROOTPATH]] test run report</h3>
+
+'''Sysid''': SYSID
+
+'''Result summary''': NUMPASSED / NUMTESTS tests passed ( PERCENTPASSED % ) <br>
+
+'''System info''':
+<pre>
+SYSINFO
+</pre>
+
+start time: STARTDATE <br>
+end time : ENDDATE <br>
+
+'''Image tests'''
+
+<REPEAT1>
+{| border=1 cellspacing=0 cellpadding=1
+|-
+| colspan=2 | FTESTNAME
+|-
+| Expected image || Actual image
+|-
+| [[File:EXPECTEDFILE|250px]] || ACTUALFILE_WIKI
+|}
+
+<pre>
+TESTLOG
+</pre>
+
+
+
+</REPEAT1>
+
+
+'''Text tests'''
+
+<REPEAT2>
+{|border=1 cellspacing=0 cellpadding=1
+|-
+| FTESTNAME
+|}
+
+<pre>
+TESTLOG
+</pre>
+
+
+</REPEAT2>
+
+'''build.make and flags.make'''
+<REPEAT3>
+*[[MAKEFILE_NAME]]
+</REPEAT3>
+"""
+ txtpages = {}
+ imgs = {}
+ passed_tests = filter(lambda x: x.passed, tests)
+ failed_tests = filter(lambda x: not x.passed, tests)
+
+ tests_to_report = tests
+ if failed_only: tests_to_report = failed_tests
+
+ try: percent = str(int(100.0*len(passed_tests) / len(tests)))
+ except ZeroDivisionError: percent = 'n/a'
+ s = wiki_template
+ repeat1 = ezsearch('(<REPEAT1>.*?</REPEAT1>)',s)
+ repeat2 = ezsearch('(<REPEAT2>.*?</REPEAT2>)',s)
+ repeat3 = ezsearch('(<REPEAT3>.*?</REPEAT3>)',s)
+ dic = { 'STARTDATE': startdate, 'ENDDATE': enddate, 'WIKI_ROOTPATH': wiki_rootpath,
+ 'SYSINFO': sysinfo, 'SYSID':sysid,
+ 'NUMTESTS':len(tests), 'NUMPASSED':len(passed_tests), 'PERCENTPASSED':percent }
+ for key in dic.keys():
+ s = s.replace(key,str(dic[key]))
+
+ for t in tests_to_report:
+ if t.type=='txt':
+ newchunk = re.sub('FTESTNAME',t.fullname,repeat2)
+ newchunk = newchunk.replace('TESTLOG',t.fulltestlog)
+ s = s.replace(repeat2, newchunk+repeat2)
+ elif t.type=='png':
+ tmp = t.actualfile.replace(builddir,'')
+ wikiname_a = wikify_filename(tmp,wiki_rootpath,sysid)
+ tmp = t.expectedfile.replace(os.path.dirname(builddir),'')
+ wikiname_e = wikify_filename(tmp,wiki_rootpath,sysid)
+ imgs[wikiname_e] = t.expectedfile_data
+ if t.actualfile:
+ actualfile_wiki = '[[File:'+wikiname_a+'|250px]]'
+ imgs[wikiname_a] = t.actualfile_data
+ else:
+ actualfile_wiki = 'No image generated.'
+ newchunk = re.sub('FTESTNAME',t.fullname,repeat1)
+ newchunk = newchunk.replace('ACTUALFILE_WIKI',actualfile_wiki)
+ newchunk = newchunk.replace('EXPECTEDFILE',wikiname_e)
+ newchunk = newchunk.replace('TESTLOG',t.fulltestlog)
+ s = s.replace(repeat1, newchunk+repeat1)
+
+ makefiles_wikinames = {}
+ for mf in sorted(makefiles.keys()):
+ tmp = mf.replace('CMakeFiles','').replace('.dir','')
+ wikiname = wikify_filename(tmp,wiki_rootpath,sysid)
+ newchunk = re.sub('MAKEFILE_NAME',wikiname,repeat3)
+ s = s.replace(repeat3, newchunk+repeat3)
+ makefiles_wikinames[mf] = wikiname
+
+ s = s.replace(repeat1,'')
+ s = s.replace(repeat2,'')
+ s = s.replace(repeat3,'')
+ s = re.sub('<REPEAT.*?>\n','',s)
+ s = re.sub('</REPEAT.*?>','',s)
+
+ mainpage_wikiname = wiki_rootpath + '_' + sysid + '_test_report'
+ txtpages[ mainpage_wikiname ] = s
+ for mf in sorted(makefiles.keys()):
+ txtpages[ makefiles_wikinames[ mf ] ] = '\n*Subreport from [['+mainpage_wikiname+']]\n\n\n<pre>\n'+makefiles[mf]+'\n</pre>'
+
+ return imgs, txtpages
+
+def tohtml(wiki_rootpath, startdate, tests, enddate, sysinfo, sysid, makefiles):
+ # kludge. assume wiki stuff has alreayd run and dumped files properly
+ head = '<html><head><title>'+wiki_rootpath+' test run for '+sysid +'</title></head><body>'
+ tail = '</body></html>'
+
+ passed_tests = filter(lambda x: x.passed, tests)
+ failed_tests = filter(lambda x: not x.passed, tests)
+ try: percent = str(int(100.0*len(passed_tests) / len(tests)))
+ except ZeroDivisionError: percent = 'n/a'
+
+ tests_to_report = tests
+ if failed_only: tests_to_report = failed_tests
+
+ s=''
+
+ s+= '\n<pre>'
+ s+= '\nSYSINFO\n'+ sysinfo
+ s+= '\n</pre><p>'
+
+ s+= '\n<pre>'
+ s+= '\nSTARTDATE: '+ startdate
+ s+= '\nENDDATE: '+ enddate
+ s+= '\nWIKI_ROOTPATH: '+ wiki_rootpath
+ s+= '\nSYSID: '+sysid
+ s+= '\nNUMTESTS: '+str(len(tests))
+ s+= '\nNUMPASSED: '+str(len(passed_tests))
+ s+= '\nPERCENTPASSED: '+ percent
+ s+= '\n</pre>'
+
+ for t in tests_to_report:
+ if t.type=='txt':
+ s+='\n<pre>'+t.fullname+'</pre>\n'
+ s+='<p><pre>'+t.fulltestlog+'</pre>\n\n'
+ elif t.type=='png':
+ tmp = t.actualfile.replace(builddir,'')
+ wikiname_a = wikify_filename(tmp,wiki_rootpath,sysid)
+ tmp = t.expectedfile.replace(os.path.dirname(builddir),'')
+ wikiname_e = wikify_filename(tmp,wiki_rootpath,sysid)
+ s+='<table>'
+ s+='\n<tr><td colspan=2>'+t.fullname
+ s+='\n<tr><td>Expected<td>Actual'
+ s+='\n<tr><td><img src='+wikiname_e+' width=250/>'
+ s+='\n <td><img src='+wikiname_a+' width=250/>'
+ s+='\n</table>'
+ s+='\n<pre>'
+ s+=t.fulltestlog
+ s+='\n</pre>'
+
+ s+='\n\n<p>\n\n'
+ makefiles_wikinames = {}
+ for mf in sorted(makefiles.keys()):
+ tmp = mf.replace('CMakeFiles','').replace('.dir','')
+ wikiname = wikify_filename(tmp,wiki_rootpath,sysid)
+ s += '\n<a href='+wikiname+'>'+wikiname+'</a><br>'
+ s+='\n'
+
+ return head + s + tail
+
+def wiki_login(wikiurl,api_php_path,botname,botpass):
+ site = mwclient.Site(wikiurl,api_php_path)
+ site.login(botname,botpass)
+ return site
+
+def wiki_upload(wikiurl,api_php_path,botname,botpass,filedata,wikipgname):
+ counter = 0
+ done = False
+ descrip = 'test'
+ time.sleep(1)
+ while not done:
+ try:
+ print 'login',botname,'to',wikiurl
+ site = wiki_login(wikiurl,api_php_path,botname,botpass)
+ print 'uploading...',
+ if wikipgname.endswith('png'):
+ site.upload(filedata,wikipgname,descrip,ignore=True)
+ else:
+ page = site.Pages[wikipgname]
+ text = page.edit()
+ page.save(filedata)
+ done = True
+ print 'transfer ok'
+ except Exception, e:
+ print 'Error:', type(e),e
+ counter += 1
+ if counter>maxretry:
+ print 'giving up. please try a different wiki site'
+ done = True
+ else:
+ print 'wiki',wikiurl,'down. retrying in 15 seconds'
+ time.sleep(15)
+
+def upload(wikiurl,api_php_path='/',wiki_rootpath='test', sysid='null', botname='cakebaby',botpass='anniew',wikidir='.',dryrun=True):
+ wetrun = not dryrun
+ if dryrun: print 'dry run'
+ try:
+ global mwclient
+ import mwclient
+ except:
+ print 'please download mwclient 0.6.5 and unpack here:', os.getcwd()
+ sys.exit()
+
+ if wetrun: site = wiki_login(wikiurl,api_php_path,botname,botpass)
+
+ wikifiles = os.listdir(wikidir)
+ testreport_page = filter( lambda x: 'test_report' in x, wikifiles )
+ if (len(testreport_page)>1):
+ print 'multiple test reports found, please clean dir',wikidir
+ sys.exit()
+
+ rootpage = testreport_page[0]
+ print 'add',rootpage,' to main report page ',wiki_rootpath
+ if wetrun:
+ page = site.Pages[wiki_rootpath]
+ text = page.edit()
+ if not '[['+rootpage+']]' in text:
+ page.save(text +'\n*[['+rootpage+']]\n')
+
+ wikifiles = os.listdir(wikidir)
+ wikifiles = filter(lambda x: not x.endswith('html'), wikifiles)
+
+ print 'upload wiki pages:'
+ for wikiname in wikifiles:
+ filename = os.path.join(wikidir,wikiname)
+ filedata = tryread(filename)
+ print 'upload',len(filedata),'bytes from',wikiname
+ if wetrun and len(filedata)>0:
+ wiki_upload(wikiurl,api_php_path,botname,botpass,filedata,wikiname)
+ if len(filedata)==0:
+ print 'cancelling empty upload'
+
+def findlogfile(builddir):
+ logpath = os.path.join(builddir,'Testing','Temporary')
+ logfilename = os.path.join(logpath,'LastTest.log.tmp')
+ if not os.path.isfile(logfilename):
+ logfilename = os.path.join(logpath,'LastTest.log')
+ if not os.path.isfile(logfilename):
+ print 'cant find and/or open logfile',logfilename
+ sys.exit()
+ return logpath, logfilename
+
+def main():
+ dry = False
+ if verbose: print 'running test_pretty_print'
+ if '--dryrun' in sys.argv: dry=True
+ suffix = ezsearch('--suffix=(.*?) ',string.join(sys.argv)+' ')
+ builddir = ezsearch('--builddir=(.*?) ',string.join(sys.argv)+' ')
+ if builddir=='': builddir=os.getcwd()
+ if verbose: print 'build dir set to', builddir
+
+ sysinfo, sysid = read_sysinfo(os.path.join(builddir,'sysinfo.txt'))
+ makefiles = load_makefiles(builddir)
+ logpath, logfilename = findlogfile(builddir)
+ testlog = tryread(logfilename)
+ startdate, tests, enddate = parselog(testlog)
+ if verbose:
+ print 'found sysinfo.txt,',
+ print 'found', len(makefiles),'makefiles,',
+ print 'found', len(tests),'test results'
+
+ imgs, txtpages = towiki(wiki_rootpath, startdate, tests, enddate, sysinfo, sysid, makefiles)
+
+ wikidir = os.path.join(logpath,sysid+'_report')
+ if verbose: print 'erasing files in',wikidir
+ try: map(lambda x:os.remove(os.path.join(wikidir,x)), os.listdir(wikidir))
+ except: pass
+ print 'writing',len(imgs),'images, ',len(txtpages)-1,'text pages, and index.html to:\n', ' .'+wikidir.replace(os.getcwd(),'')
+ for pgname in sorted(imgs): trysave( os.path.join(wikidir,pgname), imgs[pgname])
+ for pgname in sorted(txtpages): trysave( os.path.join(wikidir,pgname), txtpages[pgname])
+
+ htmldata = tohtml(wiki_rootpath, startdate, tests, enddate, sysinfo, sysid, makefiles)
+ trysave( os.path.join(wikidir,'index.html'), htmldata )
+
+ if '--upload' in sys.argv:
+ upload(wikisite,wiki_api_path,wiki_rootpath,sysid,'openscadbot',
+ 'tobdacsnepo',wikidir,dryrun=dry)
+ print 'upload attempt complete'
+
+ if verbose: print 'test_pretty_print complete'
+
+#wikisite = 'cakebaby.referata.com'
+#wiki_api_path = ''
+wikisite = 'cakebaby.wikia.com'
+wiki_api_path = '/'
+wiki_rootpath = 'OpenSCAD'
+builddir = os.getcwd() # os.getcwd()+'/build'
+verbose = False
+maxretry = 10
+
+if bool(os.getenv("TEST_GENERATE")): sys.exit(0)
+
+failed_only = False
+if '--failed-only' in sys.argv: failed_only = True
+
+main()
diff --git a/tests/yee_compare.cpp b/tests/yee_compare.cpp
deleted file mode 100644
index 9de4720..0000000
--- a/tests/yee_compare.cpp
+++ /dev/null
@@ -1,681 +0,0 @@
-// modified from PerceptualDiff source for OpenSCAD, 2011 September
-
-#include "yee_compare.h"
-#include "lodepng.h"
-#include <cstdlib>
-#include <cstring>
-#include <cstdio>
-#include <math.h>
-
-static const char* copyright =
-"PerceptualDiff version 1.1.1, Copyright (C) 2006 Yangli Hector Yee\n\
-PerceptualDiff comes with ABSOLUTELY NO WARRANTY;\n\
-This is free software, and you are welcome\n\
-to redistribute it under certain conditions;\n\
-See the GPL page for details: http://www.gnu.org/copyleft/gpl.html\n\n";
-
-static const char *usage =
-"PeceptualDiff image1.tif image2.tif\n\n\
- Compares image1.tif and image2.tif using a perceptually based image metric\n\
- Options:\n\
-\t-verbose : Turns on verbose mode\n\
-\t-fov deg : Field of view in degrees (0.1 to 89.9)\n\
-\t-threshold p : #pixels p below which differences are ignored\n\
-\t-gamma g : Value to convert rgb into linear space (default 2.2)\n\
-\t-luminance l : White luminance (default 100.0 cdm^-2)\n\
-\t-luminanceonly : Only consider luminance; ignore chroma (color) in the comparison\n\
-\t-colorfactor : How much of color to use, 0.0 to 1.0, 0.0 = ignore color.\n\
-\t-downsample : How many powers of two to down sample the image.\n\
-\t-output o.ppm : Write difference to the file o.ppm\n\
-\n\
-\n Note: Input or Output files can also be in the PNG or JPG format or any format\
-\n that FreeImage supports.\
-\n";
-
-CompareArgs::CompareArgs()
-{
- ImgA = NULL;
- ImgB = NULL;
- ImgDiff = NULL;
- Verbose = false;
- LuminanceOnly = false;
- FieldOfView = 45.0f;
- Gamma = 2.2f;
- ThresholdPixels = 100;
- Luminance = 100.0f;
- ColorFactor = 1.0f;
- DownSample = 0;
-}
-
-CompareArgs::~CompareArgs()
-{
- if (ImgA) delete ImgA;
- if (ImgB) delete ImgB;
- if (ImgDiff) delete ImgDiff;
-}
-
-bool CompareArgs::Parse_Args(int argc, char **argv)
-{
- if (argc < 3) {
- ErrorStr = copyright;
- ErrorStr += usage;
- return false;
- }
- int image_count = 0;
- const char* output_file_name = NULL;
- for (int i = 1; i < argc; i++) {
- if (strcmp(argv[i], "-fov") == 0) {
- if (++i < argc) {
- FieldOfView = (float) atof(argv[i]);
- }
- } else if (strcmp(argv[i], "-verbose") == 0) {
- Verbose = true;
- } else if (strcmp(argv[i], "-threshold") == 0) {
- if (++i < argc) {
- ThresholdPixels = atoi(argv[i]);
- }
- } else if (strcmp(argv[i], "-gamma") == 0) {
- if (++i < argc) {
- Gamma = (float) atof(argv[i]);
- }
- } else if (strcmp(argv[i], "-luminance") == 0) {
- if (++i < argc) {
- Luminance = (float) atof(argv[i]);
- }
- } else if (strcmp(argv[i], "-luminanceonly") == 0) {
- LuminanceOnly = true;
- } else if (strcmp(argv[i], "-colorfactor") == 0) {
- if (++i < argc) {
- ColorFactor = (float) atof(argv[i]);
- }
- } else if (strcmp(argv[i], "-downsample") == 0) {
- if (++i < argc) {
- DownSample = (int) atoi(argv[i]);
- }
- } else if (strcmp(argv[i], "-output") == 0) {
- if (++i < argc) {
- output_file_name = argv[i];
- }
- } else if (image_count < 2) {
- RGBAImage* img = RGBAImage::ReadFromFile(argv[i]);
- if (!img) {
- ErrorStr = "FAIL: Cannot open ";
- ErrorStr += argv[i];
- ErrorStr += "\n";
- return false;
- } else {
- ++image_count;
- if(image_count == 1)
- ImgA = img;
- else
- ImgB = img;
- }
- } else {
- fprintf(stderr, "Warning: option/file \"%s\" ignored\n", argv[i]);
- }
- } // i
- if(!ImgA || !ImgB) {
- ErrorStr = "FAIL: Not enough image files specified\n";
- return false;
- }
- for (int i = 0; i < DownSample; i++) {
- if (Verbose) printf("Downsampling by %d\n", 1 << (i+1));
- RGBAImage *tmp = ImgA->DownSample();
- if (tmp) {
- delete ImgA;
- ImgA = tmp;
- }
- tmp = ImgB->DownSample();
- if (tmp) {
- delete ImgB;
- ImgB = tmp;
- }
- }
- if(output_file_name) {
- ImgDiff = new RGBAImage(ImgA->Get_Width(), ImgA->Get_Height(), output_file_name);
- }
- return true;
-}
-
-void CompareArgs::Print_Args()
-{
- printf("Field of view is %f degrees\n", FieldOfView);
- printf("Threshold pixels is %d pixels\n", ThresholdPixels);
- printf("The Gamma is %f\n", Gamma);
- printf("The Display's luminance is %f candela per meter squared\n", Luminance);
-}
-
-//////////////////////////////////////////////////////////////////////
-// Construction/Destruction
-//////////////////////////////////////////////////////////////////////
-
-LPyramid::LPyramid(float *image, int width, int height) :
- Width(width),
- Height(height)
-{
- // Make the Laplacian pyramid by successively
- // copying the earlier levels and blurring them
- for (int i=0; i<MAX_PYR_LEVELS; i++) {
- if (i == 0) {
- Levels[i] = Copy(image);
- } else {
- Levels[i] = new float[Width * Height];
- Convolve(Levels[i], Levels[i - 1]);
- }
- }
-}
-
-LPyramid::~LPyramid()
-{
- for (int i=0; i<MAX_PYR_LEVELS; i++) {
- if (Levels[i]) delete Levels[i];
- }
-}
-
-float *LPyramid::Copy(float *img)
-{
- int max = Width * Height;
- float *out = new float[max];
- for (int i = 0; i < max; i++) out[i] = img[i];
-
- return out;
-}
-
-void LPyramid::Convolve(float *a, float *b)
-// convolves image b with the filter kernel and stores it in a
-{
- int y,x,i,j,nx,ny;
- const float Kernel[] = {0.05f, 0.25f, 0.4f, 0.25f, 0.05f};
-
- for (y=0; y<Height; y++) {
- for (x=0; x<Width; x++) {
- int index = y * Width + x;
- a[index] = 0.0f;
- for (i=-2; i<=2; i++) {
- for (j=-2; j<=2; j++) {
- nx=x+i;
- ny=y+j;
- if (nx<0) nx=-nx;
- if (ny<0) ny=-ny;
- if (nx>=Width) nx=2*Width-nx-1;
- if (ny>=Height) ny=2*Height-ny-1;
- a[index] += Kernel[i+2] * Kernel[j+2] * b[ny * Width + nx];
- }
- }
- }
- }
-}
-
-float LPyramid::Get_Value(int x, int y, int level)
-{
- int index = x + y * Width;
- int l = level;
- if (l > MAX_PYR_LEVELS) l = MAX_PYR_LEVELS;
- return Levels[level][index];
-}
-
-
-
-#ifndef M_PI
-#define M_PI 3.14159265f
-#endif
-
-/*
-* Given the adaptation luminance, this function returns the
-* threshold of visibility in cd per m^2
-* TVI means Threshold vs Intensity function
-* This version comes from Ward Larson Siggraph 1997
-*/
-
-float tvi(float adaptation_luminance)
-{
- // returns the threshold luminance given the adaptation luminance
- // units are candelas per meter squared
-
- float log_a, r, result;
- log_a = log10f(adaptation_luminance);
-
- if (log_a < -3.94f) {
- r = -2.86f;
- } else if (log_a < -1.44f) {
- r = powf(0.405f * log_a + 1.6f , 2.18f) - 2.86f;
- } else if (log_a < -0.0184f) {
- r = log_a - 0.395f;
- } else if (log_a < 1.9f) {
- r = powf(0.249f * log_a + 0.65f, 2.7f) - 0.72f;
- } else {
- r = log_a - 1.255f;
- }
-
- result = powf(10.0f , r);
-
- return result;
-
-}
-
-// computes the contrast sensitivity function (Barten SPIE 1989)
-// given the cycles per degree (cpd) and luminance (lum)
-float csf(float cpd, float lum)
-{
- float a, b, result;
-
- a = 440.0f * powf((1.0f + 0.7f / lum), -0.2f);
- b = 0.3f * powf((1.0f + 100.0f / lum), 0.15f);
-
- result = a * cpd * expf(-b * cpd) * sqrtf(1.0f + 0.06f * expf(b * cpd));
-
- return result;
-}
-
-/*
-* Visual Masking Function
-* from Daly 1993
-*/
-float mask(float contrast)
-{
- float a, b, result;
- a = powf(392.498f * contrast, 0.7f);
- b = powf(0.0153f * a, 4.0f);
- result = powf(1.0f + b, 0.25f);
-
- return result;
-}
-
-// convert Adobe RGB (1998) with reference white D65 to XYZ
-void AdobeRGBToXYZ(float r, float g, float b, float &x, float &y, float &z)
-{
- // matrix is from http://www.brucelindbloom.com/
- x = r * 0.576700f + g * 0.185556f + b * 0.188212f;
- y = r * 0.297361f + g * 0.627355f + b * 0.0752847f;
- z = r * 0.0270328f + g * 0.0706879f + b * 0.991248f;
-}
-
-void XYZToLAB(float x, float y, float z, float &L, float &A, float &B)
-{
- static float xw = -1;
- static float yw;
- static float zw;
- // reference white
- if (xw < 0) {
- AdobeRGBToXYZ(1, 1, 1, xw, yw, zw);
- }
- const float epsilon = 216.0f / 24389.0f;
- const float kappa = 24389.0f / 27.0f;
- float f[3];
- float r[3];
- r[0] = x / xw;
- r[1] = y / yw;
- r[2] = z / zw;
- for (int i = 0; i < 3; i++) {
- if (r[i] > epsilon) {
- f[i] = powf(r[i], 1.0f / 3.0f);
- } else {
- f[i] = (kappa * r[i] + 16.0f) / 116.0f;
- }
- }
- L = 116.0f * f[1] - 16.0f;
- A = 500.0f * (f[0] - f[1]);
- B = 200.0f * (f[1] - f[2]);
-}
-
-bool Yee_Compare(CompareArgs &args)
-{
- if ((args.ImgA->Get_Width() != args.ImgB->Get_Width()) ||
- (args.ImgA->Get_Height() != args.ImgB->Get_Height())) {
- args.ErrorStr = "Image dimensions do not match\n";
- return false;
- }
-
- unsigned int i, dim;
- dim = args.ImgA->Get_Width() * args.ImgA->Get_Height();
- bool identical = true;
- for (i = 0; i < dim; i++) {
- if (args.ImgA->Get(i) != args.ImgB->Get(i)) {
- identical = false;
- break;
- }
- }
- if (identical) {
- args.ErrorStr = "Images are binary identical\n";
- return true;
- }
-
- // assuming colorspaces are in Adobe RGB (1998) convert to XYZ
- float *aX = new float[dim];
- float *aY = new float[dim];
- float *aZ = new float[dim];
- float *bX = new float[dim];
- float *bY = new float[dim];
- float *bZ = new float[dim];
- float *aLum = new float[dim];
- float *bLum = new float[dim];
-
- float *aA = new float[dim];
- float *bA = new float[dim];
- float *aB = new float[dim];
- float *bB = new float[dim];
-
- if (args.Verbose) printf("Converting RGB to XYZ\n");
-
- unsigned int x, y, w, h;
- w = args.ImgA->Get_Width();
- h = args.ImgA->Get_Height();
- for (y = 0; y < h; y++) {
- for (x = 0; x < w; x++) {
- float r, g, b, l;
- i = x + y * w;
- r = powf(args.ImgA->Get_Red(i) / 255.0f, args.Gamma);
- g = powf(args.ImgA->Get_Green(i) / 255.0f, args.Gamma);
- b = powf(args.ImgA->Get_Blue(i) / 255.0f, args.Gamma);
- AdobeRGBToXYZ(r,g,b,aX[i],aY[i],aZ[i]);
- XYZToLAB(aX[i], aY[i], aZ[i], l, aA[i], aB[i]);
- r = powf(args.ImgB->Get_Red(i) / 255.0f, args.Gamma);
- g = powf(args.ImgB->Get_Green(i) / 255.0f, args.Gamma);
- b = powf(args.ImgB->Get_Blue(i) / 255.0f, args.Gamma);
- AdobeRGBToXYZ(r,g,b,bX[i],bY[i],bZ[i]);
- XYZToLAB(bX[i], bY[i], bZ[i], l, bA[i], bB[i]);
- aLum[i] = aY[i] * args.Luminance;
- bLum[i] = bY[i] * args.Luminance;
- }
- }
-
- if (args.Verbose) printf("Constructing Laplacian Pyramids\n");
-
- LPyramid *la = new LPyramid(aLum, w, h);
- LPyramid *lb = new LPyramid(bLum, w, h);
-
- float num_one_degree_pixels = (float) (2 * tan( args.FieldOfView * 0.5 * M_PI / 180) * 180 / M_PI);
- float pixels_per_degree = w / num_one_degree_pixels;
-
- if (args.Verbose) printf("Performing test\n");
-
- float num_pixels = 1;
- unsigned int adaptation_level = 0;
- for (i = 0; i < MAX_PYR_LEVELS; i++) {
- adaptation_level = i;
- if (num_pixels > num_one_degree_pixels) break;
- num_pixels *= 2;
- }
-
- float cpd[MAX_PYR_LEVELS];
- cpd[0] = 0.5f * pixels_per_degree;
- for (i = 1; i < MAX_PYR_LEVELS; i++) cpd[i] = 0.5f * cpd[i - 1];
- float csf_max = csf(3.248f, 100.0f);
-
- float F_freq[MAX_PYR_LEVELS - 2];
- for (i = 0; i < MAX_PYR_LEVELS - 2; i++) F_freq[i] = csf_max / csf( cpd[i], 100.0f);
-
- unsigned int pixels_failed = 0;
- for (y = 0; y < h; y++) {
- for (x = 0; x < w; x++) {
- int index = x + y * w;
- float contrast[MAX_PYR_LEVELS - 2];
- float sum_contrast = 0;
- for (i = 0; i < MAX_PYR_LEVELS - 2; i++) {
- float n1 = fabsf(la->Get_Value(x,y,i) - la->Get_Value(x,y,i + 1));
- float n2 = fabsf(lb->Get_Value(x,y,i) - lb->Get_Value(x,y,i + 1));
- float numerator = (n1 > n2) ? n1 : n2;
- float d1 = fabsf(la->Get_Value(x,y,i+2));
- float d2 = fabsf(lb->Get_Value(x,y,i+2));
- float denominator = (d1 > d2) ? d1 : d2;
- if (denominator < 1e-5f) denominator = 1e-5f;
- contrast[i] = numerator / denominator;
- sum_contrast += contrast[i];
- }
- if (sum_contrast < 1e-5) sum_contrast = 1e-5f;
- float F_mask[MAX_PYR_LEVELS - 2];
- float adapt = la->Get_Value(x,y,adaptation_level) + lb->Get_Value(x,y,adaptation_level);
- adapt *= 0.5f;
- if (adapt < 1e-5) adapt = 1e-5f;
- for (i = 0; i < MAX_PYR_LEVELS - 2; i++) {
- F_mask[i] = mask(contrast[i] * csf(cpd[i], adapt));
- }
- float factor = 0;
- for (i = 0; i < MAX_PYR_LEVELS - 2; i++) {
- factor += contrast[i] * F_freq[i] * F_mask[i] / sum_contrast;
- }
- if (factor < 1) factor = 1;
- if (factor > 10) factor = 10;
- float delta = fabsf(la->Get_Value(x,y,0) - lb->Get_Value(x,y,0));
- bool pass = true;
- // pure luminance test
- if (delta > factor * tvi(adapt)) {
- pass = false;
- } else if (!args.LuminanceOnly) {
- // CIE delta E test with modifications
- float color_scale = args.ColorFactor;
- // ramp down the color test in scotopic regions
- if (adapt < 10.0f) {
- // Don't do color test at all.
- color_scale = 0.0;
- }
- float da = aA[index] - bA[index];
- float db = aB[index] - bB[index];
- da = da * da;
- db = db * db;
- float delta_e = (da + db) * color_scale;
- if (delta_e > factor) {
- pass = false;
- }
- }
- if (!pass) {
- pixels_failed++;
- if (args.ImgDiff) {
- args.ImgDiff->Set(255, 0, 0, 255, index);
- }
- } else {
- if (args.ImgDiff) {
- args.ImgDiff->Set(0, 0, 0, 255, index);
- }
- }
- }
- }
-
- if (aX) delete[] aX;
- if (aY) delete[] aY;
- if (aZ) delete[] aZ;
- if (bX) delete[] bX;
- if (bY) delete[] bY;
- if (bZ) delete[] bZ;
- if (aLum) delete[] aLum;
- if (bLum) delete[] bLum;
- if (la) delete la;
- if (lb) delete lb;
- if (aA) delete aA;
- if (bA) delete bA;
- if (aB) delete aB;
- if (bB) delete bB;
-
- char different[100];
- sprintf(different, "%d pixels are different\n", pixels_failed);
-
- // Always output image difference if requested.
- if (args.ImgDiff) {
- if (args.ImgDiff->WriteToFile(args.ImgDiff->Get_Name().c_str())) {
- args.ErrorStr += "Wrote difference image to ";
- args.ErrorStr+= args.ImgDiff->Get_Name();
- args.ErrorStr += "\n";
- } else {
- args.ErrorStr += "Could not write difference image to ";
- args.ErrorStr+= args.ImgDiff->Get_Name();
- args.ErrorStr += "\n";
- }
- }
-
- if (pixels_failed < args.ThresholdPixels) {
- args.ErrorStr = "Images are perceptually indistinguishable\n";
- args.ErrorStr += different;
- return true;
- }
-
- args.ErrorStr = "Images are visibly different\n";
- args.ErrorStr += different;
-
- return false;
-}
-
-RGBAImage* RGBAImage::DownSample() const {
- if (Width <=1 || Height <=1) return NULL;
- int nw = Width / 2;
- int nh = Height / 2;
- RGBAImage* img = new RGBAImage(nw, nh, Name.c_str());
- for (int y = 0; y < nh; y++) {
- for (int x = 0; x < nw; x++) {
- int d[4];
- // Sample a 2x2 patch from the parent image.
- d[0] = Get(2 * x + 0, 2 * y + 0);
- d[1] = Get(2 * x + 1, 2 * y + 0);
- d[2] = Get(2 * x + 0, 2 * y + 1);
- d[3] = Get(2 * x + 1, 2 * y + 1);
- int rgba = 0;
- // Find the average color.
- for (int i = 0; i < 4; i++) {
- int c = (d[0] >> (8 * i)) & 0xFF;
- c += (d[1] >> (8 * i)) & 0xFF;
- c += (d[2] >> (8 * i)) & 0xFF;
- c += (d[3] >> (8 * i)) & 0xFF;
- c /= 4;
- rgba |= (c & 0xFF) << (8 * i);
- }
- img->Set(x, y, rgba);
- }
- }
- return img;
-}
-
-
-bool RGBAImage::WriteToFile(const char* filename)
-{
- LodePNG::Encoder encoder;
- encoder.addText("Comment","lodepng");
- encoder.getSettings().zlibsettings.windowSize = 2048;
-
-
-/*
- const FREE_IMAGE_FORMAT fileType = FreeImage_GetFIFFromFilename(filename);
- if(FIF_UNKNOWN == fileType)
- {
- printf("Can't save to unknown filetype %s\n", filename);
- return false;
- }
-
- FIBITMAP* bitmap = FreeImage_Allocate(Width, Height, 32, 0x000000ff, 0x0000ff00, 0x00ff0000);
- if(!bitmap)
- {
- printf("Failed to create freeimage for %s\n", filename);
- return false;
- }
-
- const unsigned int* source = Data;
- for( int y=0; y < Height; y++, source += Width )
- {
- unsigned int* scanline = (unsigned int*)FreeImage_GetScanLine(bitmap, Height - y - 1 );
- memcpy(scanline, source, sizeof(source[0]) * Width);
- }
-
- FreeImage_SetTransparent(bitmap, false);
- FIBITMAP* converted = FreeImage_ConvertTo24Bits(bitmap);
-
-
- const bool result = !!FreeImage_Save(fileType, converted, filename);
- if(!result)
- printf("Failed to save to %s\n", filename);
-
- FreeImage_Unload(converted);
- FreeImage_Unload(bitmap);
- return result;
-*/
- return true;
-}
-
-RGBAImage* RGBAImage::ReadFromFile(const char* filename)
-{
- unsigned char* buffer;
- unsigned char* image;
- size_t buffersize, imagesize, i;
- LodePNG_Decoder decoder;
-
- LodePNG_loadFile(&buffer, &buffersize, filename); /*load the image file with given filename*/
- LodePNG_Decoder_init(&decoder);
- LodePNG_Decoder_decode(&decoder, &image, &imagesize, buffer, buffersize); /*decode the png*/
-
- /*load and decode*/
- /*if there's an error, display it, otherwise display information about the image*/
- if(decoder.error) printf("error %u: %s\n", decoder.error, LodePNG_error_text(decoder.error));
-
- int w = decoder.infoPng.width;
- int h = decoder.infoPng.height;
-
-
- RGBAImage* result = new RGBAImage(w, h, filename);
- // Copy the image over to our internal format, FreeImage has the scanlines bottom to top though.
- unsigned int* dest = result->Data;
- memcpy(dest, (void *)image, h*w*4);
-
- /*cleanup decoder*/
- free(image);
- free(buffer);
- LodePNG_Decoder_cleanup(&decoder);
-
- return result;
-/*
- const FREE_IMAGE_FORMAT fileType = FreeImage_GetFileType(filename);
- if(FIF_UNKNOWN == fileType)
- {
- printf("Unknown filetype %s\n", filename);
- return 0;
- }
-
- FIBITMAP* freeImage = 0;
- if(FIBITMAP* temporary = FreeImage_Load(fileType, filename, 0))
- {
- freeImage = FreeImage_ConvertTo32Bits(temporary);
- FreeImage_Unload(temporary);
- }
- if(!freeImage)
- {
- printf( "Failed to load the image %s\n", filename);
- return 0;
- }
-
- const int w = FreeImage_GetWidth(freeImage);
- const int h = FreeImage_GetHeight(freeImage);
-
- RGBAImage* result = new RGBAImage(w, h, filename);
- // Copy the image over to our internal format, FreeImage has the scanlines bottom to top though.
- unsigned int* dest = result->Data;
- for( int y=0; y < h; y++, dest += w )
- {
- const unsigned int* scanline = (const unsigned int*)FreeImage_GetScanLine(freeImage, h - y - 1 );
- memcpy(dest, scanline, sizeof(dest[0]) * w);
- }
-
- FreeImage_Unload(freeImage);
- return result;
- return NULL;
-*/
-}
-
-
-int main(int argc, char **argv)
-{
- CompareArgs args;
-
- if (!args.Parse_Args(argc, argv)) {
- printf("%s", args.ErrorStr.c_str());
- return -1;
- } else {
- if (args.Verbose) args.Print_Args();
- }
-
- const bool passed = Yee_Compare(args);
- if (passed) {
- if(args.Verbose)
- printf("PASS: %s\n", args.ErrorStr.c_str());
- } else {
- printf("FAIL: %s\n", args.ErrorStr.c_str());
- }
-
- return passed ? 0 : 1;
-}
-
diff --git a/tests/yee_compare.h b/tests/yee_compare.h
deleted file mode 100644
index 041ae4c..0000000
--- a/tests/yee_compare.h
+++ /dev/null
@@ -1,126 +0,0 @@
-#ifndef _yee_compare_h
-#define _yee_compare_h
-
-// source code modified for OpenSCAD, Sept 2011
-// original copyright notice follows:
-/*
-Metric
-RGBAImage.h
-Comapre Args
-Laplacian Pyramid
-Copyright (C) 2006 Yangli Hector Yee
-
-This program is free software; you can redistribute it and/or modify it under the terms of the
-GNU General Public License as published by the Free Software Foundation; either version 2 of the License,
-or (at your option) any later version.
-
-This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
-without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-See the GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License along with this program;
-if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-*/
-
-#include <string>
-
-class RGBAImage;
-
-// Args to pass into the comparison function
-class CompareArgs
-{
-public:
- CompareArgs();
- ~CompareArgs();
- bool Parse_Args(int argc, char **argv);
- void Print_Args();
-
- RGBAImage *ImgA; // Image A
- RGBAImage *ImgB; // Image B
- RGBAImage *ImgDiff; // Diff image
- bool Verbose; // Print lots of text or not
- bool LuminanceOnly; // Only consider luminance; ignore chroma channels in the comparison.
- float FieldOfView; // Field of view in degrees
- float Gamma; // The gamma to convert to linear color space
- float Luminance; // the display's luminance
- unsigned int ThresholdPixels; // How many pixels different to ignore
- std::string ErrorStr; // Error string
- // How much color to use in the metric.
- // 0.0 is the same as LuminanceOnly = true,
- // 1.0 means full strength.
- float ColorFactor;
- // How much to down sample image before comparing, in powers of 2.
- int DownSample;
-};
-
-#define MAX_PYR_LEVELS 8
-
-class LPyramid
-{
-public:
- LPyramid(float *image, int width, int height);
- virtual ~LPyramid();
- float Get_Value(int x, int y, int level);
-protected:
- float *Copy(float *img);
- void Convolve(float *a, float *b);
-
- // Succesively blurred versions of the original image
- float *Levels[MAX_PYR_LEVELS];
-
- int Width;
- int Height;
-};
-
-class CompareArgs;
-
-// Image comparison metric using Yee's method
-// References: A Perceptual Metric for Production Testing, Hector Yee, Journal of Graphics Tools 2004
-bool Yee_Compare(CompareArgs &args);
-
-/** Class encapsulating an image containing R,G,B,A channels.
- *
- * Internal representation assumes data is in the ABGR format, with the RGB
- * color channels premultiplied by the alpha value. Premultiplied alpha is
- * often also called "associated alpha" - see the tiff 6 specification for some
- * discussion - http://partners.adobe.com/asn/developer/PDFS/TN/TIFF6.pdf
- *
- */
-class RGBAImage
-{
- RGBAImage(const RGBAImage&);
- RGBAImage& operator=(const RGBAImage&);
-public:
- RGBAImage(int w, int h, const char *name = 0)
- {
- Width = w;
- Height = h;
- if (name) Name = name;
- Data = new unsigned int[w * h];
- };
- ~RGBAImage() { if (Data) delete[] Data; }
- unsigned char Get_Red(unsigned int i) { return (Data[i] & 0xFF); }
- unsigned char Get_Green(unsigned int i) { return ((Data[i]>>8) & 0xFF); }
- unsigned char Get_Blue(unsigned int i) { return ((Data[i]>>16) & 0xFF); }
- unsigned char Get_Alpha(unsigned int i) { return ((Data[i]>>24) & 0xFF); }
- void Set(unsigned char r, unsigned char g, unsigned char b, unsigned char a, unsigned int i)
- { Data[i] = r | (g << 8) | (b << 16) | (a << 24); }
- int Get_Width(void) const { return Width; }
- int Get_Height(void) const { return Height; }
- void Set(int x, int y, unsigned int d) { Data[x + y * Width] = d; }
- unsigned int Get(int x, int y) const { return Data[x + y * Width]; }
- unsigned int Get(int i) const { return Data[i]; }
- const std::string &Get_Name(void) const { return Name; }
- RGBAImage* DownSample() const;
-
- bool WriteToFile(const char* filename);
- static RGBAImage* ReadFromFile(const char* filename);
-
-protected:
- int Width;
- int Height;
- std::string Name;
- unsigned int *Data;
-};
-
-#endif
diff --git a/version.pri b/version.pri
index 195c51a..c94ab82 100644
--- a/version.pri
+++ b/version.pri
@@ -62,3 +62,6 @@ isEmpty(VERSION) {
VERSION_MONTH=$${VERSION_MONTH}.0
VERSION_DAY=$${VERSION_DAY}.0
}
+
+DEFINES += OPENSCAD_VERSION=$$VERSION OPENSCAD_YEAR=$$VERSION_YEAR OPENSCAD_MONTH=$$VERSION_MONTH
+!isEmpty(VERSION_DAY): DEFINES += OPENSCAD_DAY=$$VERSION_DAY
diff --git a/win32.pri b/win32.pri
new file mode 100644
index 0000000..bb41b09
--- /dev/null
+++ b/win32.pri
@@ -0,0 +1,20 @@
+# win32-specific MSVC compiler general settings
+
+win32*msvc* {
+ #configure additional directories
+ INCLUDEPATH += $$(MPIRDIR)
+ INCLUDEPATH += $$(MPFRDIR)
+
+ DEFINES += _USE_MATH_DEFINES NOMINMAX _CRT_SECURE_NO_WARNINGS YY_NO_UNISTD_H
+
+ # disable MSVC warnings that are of very low importance
+ # disable warning about too long decorated names
+ QMAKE_CXXFLAGS += -wd4503
+ # CGAL casting int to bool
+ QMAKE_CXXFLAGS += -wd4800
+ # CGAL's unreferenced formal parameters
+ QMAKE_CXXFLAGS += -wd4100
+ # lexer uses strdup() & other POSIX stuff
+ QMAKE_CXXFLAGS += -D_CRT_NONSTDC_NO_DEPRECATE
+
+}
contact: Jan Huwald // Impressum