Compare commits
248 commits
2015.03
...
pull-travi
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
823a8d2600 | ||
|
|
53cbfe1008 | ||
|
|
8819d6bde6 | ||
|
|
9e43ca1299 | ||
|
|
1b030d7b71 | ||
|
|
c12ab83d22 | ||
|
|
46e79118b1 | ||
|
|
16026cfed7 | ||
|
|
e15c36f53f | ||
|
|
fbb5e895ab | ||
|
|
5639962224 | ||
|
|
2794123deb | ||
|
|
b9ff5fc5a7 | ||
|
|
ab73c8c8a2 | ||
|
|
a2814e11a7 | ||
|
|
f65cc7816c | ||
|
|
53c255d4fd | ||
|
|
6736b1e3a3 | ||
|
|
e3c1a90a97 | ||
|
|
5bdc9383f5 | ||
|
|
24124f62bf | ||
|
|
65cc670385 | ||
|
|
da426df8c7 | ||
|
|
a667eba60c | ||
|
|
0dded01c37 | ||
|
|
fa34694af4 | ||
|
|
cb69ab404f | ||
|
|
5a3d81d553 | ||
|
|
280ae53f8e | ||
|
|
9a83b0bacf | ||
|
|
7310cd7aab | ||
|
|
5b92c90f9b | ||
|
|
24408ef220 | ||
|
|
6c8bff81d3 | ||
|
|
2b5c3ef70d | ||
|
|
ab8278416a | ||
|
|
2ff35fed0c | ||
|
|
b40e492d87 | ||
|
|
f1e8f2c1a5 | ||
|
|
e6e933d844 | ||
|
|
e225f2d341 | ||
|
|
29d472b691 | ||
|
|
8baea085c6 | ||
|
|
42dba75497 | ||
|
|
c1e12e4782 | ||
|
|
3bab13d2ee | ||
|
|
19b9f99ee8 | ||
|
|
d2d273895e | ||
|
|
3327231847 | ||
|
|
b8ec2c2bc8 | ||
|
|
ff4debec77 | ||
|
|
a675ef6e4e | ||
|
|
600a96f3f4 | ||
|
|
25c31d124e | ||
|
|
6144d45457 | ||
|
|
7f9e7f9c83 | ||
|
|
ed637eb6d5 | ||
|
|
c8097fd604 | ||
|
|
5e1df90c55 | ||
|
|
3fa0046638 | ||
|
|
78234a10ac | ||
|
|
847cc76f20 | ||
|
|
e98a6de11f | ||
|
|
23b6faa17c | ||
|
|
32a2f3aeaf | ||
|
|
b6e55ad66c | ||
|
|
b152acb9e4 | ||
|
|
6441ac4da2 | ||
|
|
4cd1bf9541 | ||
|
|
a2a1f23d6d | ||
|
|
dcbab229c6 | ||
|
|
f7a5313917 | ||
|
|
2f4091b1b7 | ||
|
|
90a660d718 | ||
|
|
d60691b995 | ||
|
|
a17b894316 | ||
|
|
2aaafa44bc | ||
|
|
e4c25bc2f6 | ||
|
|
211b795326 | ||
|
|
1c5ac3b6fd | ||
|
|
a06c44a333 | ||
|
|
1f5367bd46 | ||
|
|
1ef90ace3d | ||
|
|
68e41af144 | ||
|
|
68a296b408 | ||
|
|
1beeb4880e | ||
|
|
012ef6624c | ||
|
|
1522dae4cf | ||
|
|
6bd23abdab | ||
|
|
f9e7c945ba | ||
|
|
9a113b9407 | ||
|
|
310b8fa693 | ||
|
|
ae9ab8fd5e | ||
|
|
058330b0ad | ||
|
|
38dbd49613 | ||
|
|
02c1cf322f | ||
|
|
1514514a76 | ||
|
|
31de8e0f8e | ||
|
|
b1caaaa344 | ||
|
|
3ca9b32849 | ||
|
|
d1d7bb21c4 | ||
|
|
d2e05710e2 | ||
|
|
3b9d1ca4d8 | ||
|
|
f85ace9dd0 | ||
|
|
1b30f641ad | ||
|
|
2227b5cbb8 | ||
|
|
87e32efc18 | ||
|
|
2745b8534c | ||
|
|
662a57a7bd | ||
|
|
7b39f455b5 | ||
|
|
cbccc87677 | ||
|
|
dad1566ffa | ||
|
|
db206e78de | ||
|
|
357e7db66b | ||
|
|
51c4622ca0 | ||
|
|
1bf93e1c77 | ||
|
|
892510b47b | ||
|
|
47f93e3f44 | ||
|
|
574f6e7d33 | ||
|
|
d3494d66b1 | ||
|
|
f993361f8b | ||
|
|
75f10648c9 | ||
|
|
5b917adff9 | ||
|
|
4db4aa5563 | ||
|
|
0a2556304f | ||
|
|
e1e3dae220 | ||
|
|
515c77b949 | ||
|
|
7279c1c019 | ||
|
|
42d6629156 | ||
|
|
ff2427cc1e | ||
|
|
5451fabcc1 | ||
|
|
9641e9bd7f | ||
|
|
365c562a17 | ||
|
|
a1a238a9cd | ||
|
|
7223f2ac05 | ||
|
|
1752fcee8c | ||
|
|
4f1132e5a6 | ||
|
|
306cece150 | ||
|
|
289d84aac0 | ||
|
|
38b93fe7a7 | ||
|
|
031e016df7 | ||
|
|
52f5fe2e92 | ||
|
|
f71e0acbbb | ||
|
|
59f63b5e17 | ||
|
|
cd4ced5456 | ||
|
|
2c6d783eb7 | ||
|
|
1ab390d115 | ||
|
|
c31a96454c | ||
|
|
5239121706 | ||
|
|
061537e773 | ||
|
|
02db2e15a4 | ||
|
|
4f4ddb938a | ||
|
|
17f9941a08 | ||
|
|
591c98e979 | ||
|
|
ca9f9d9d9c | ||
|
|
0c2af2defa | ||
|
|
8e53c29612 | ||
|
|
e6cd3fdda1 | ||
|
|
f9b074c473 | ||
|
|
3511e7079f | ||
|
|
7fb626fb08 | ||
|
|
55affd0273 | ||
|
|
c2f2ba5293 | ||
|
|
69e6707c62 | ||
|
|
9fb5893540 | ||
|
|
cdbd08a4d3 | ||
|
|
98b6cf3d19 | ||
|
|
5e3cd59eeb | ||
|
|
9f372cff41 | ||
|
|
89371f60cf | ||
|
|
c94e62878a | ||
|
|
2dbf9755c3 | ||
|
|
0e1b0daf36 | ||
|
|
e21b321323 | ||
|
|
cc4b633e43 | ||
|
|
c45f2b5f36 | ||
|
|
2b3392266f | ||
|
|
12a43fd942 | ||
|
|
b3ae7fa1ff | ||
|
|
a1bece5c51 | ||
|
|
4d3800cc89 | ||
|
|
c32e271a0c | ||
|
|
6e5315b430 | ||
|
|
9897174a03 | ||
|
|
e87dab0bc6 | ||
|
|
e5e9f20f95 | ||
|
|
b9c8985377 | ||
|
|
e8c8bda674 | ||
|
|
dee5885d9f | ||
|
|
bb183558ae | ||
|
|
ed2f4c2e22 | ||
|
|
7e5394c6fa | ||
|
|
330b41656b | ||
|
|
3adfdad66d | ||
|
|
82f85cd328 | ||
|
|
f53b3a3ac1 | ||
|
|
90094fff25 | ||
|
|
38ef9fddde | ||
|
|
6c3c2de264 | ||
|
|
7632b065c6 | ||
|
|
b43734c3e5 | ||
|
|
a5ec4587b6 | ||
|
|
1b840be127 | ||
|
|
85290e4d51 | ||
|
|
3ac213d649 | ||
|
|
2001f1302e | ||
|
|
c71e70c0f9 | ||
|
|
d37f4fbbab | ||
|
|
c5e1e2b9af | ||
|
|
c037625b65 | ||
|
|
9660ba84a0 | ||
|
|
067eec8743 | ||
|
|
e78206d2aa | ||
|
|
394cc15fba | ||
|
|
54239a2534 | ||
|
|
6ac8d017b7 | ||
|
|
8216e98afd | ||
|
|
b567f844ad | ||
|
|
137928fced | ||
|
|
7c2db84fe6 | ||
|
|
65935b4466 | ||
|
|
6576ee7d05 | ||
|
|
a41c8716ec | ||
|
|
e1da26bd8b | ||
|
|
437aa69292 | ||
|
|
2bdf02d352 | ||
|
|
637244d59e | ||
|
|
3a3ffc0118 | ||
|
|
67c68634b6 | ||
|
|
b394da33c7 | ||
|
|
a0875c845c | ||
|
|
c4f369fbf8 | ||
|
|
da56dff89d | ||
|
|
1d6b7923bd | ||
|
|
7b4411bbcc | ||
|
|
2de378bef5 | ||
|
|
35222064c1 | ||
|
|
7f782832d7 | ||
|
|
c5bc92d97c | ||
|
|
19cea6f3a8 | ||
|
|
2eb96a2a88 | ||
|
|
2cf6dcacf2 | ||
|
|
b2b3306205 | ||
|
|
d6340b18db | ||
|
|
fd1ae57c16 | ||
|
|
086f231d5a | ||
|
|
c259e5275c | ||
|
|
ec3743dc9a |
160 changed files with 5495 additions and 2439 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
|
@ -37,6 +37,7 @@ testdata/scad/misc/use-tests.scad
|
||||||
/lexer_lex.cpp
|
/lexer_lex.cpp
|
||||||
/parser_yacc.cpp
|
/parser_yacc.cpp
|
||||||
/OpenSCAD.app
|
/OpenSCAD.app
|
||||||
|
/openscad.appdata.xml
|
||||||
/openscad.pro.user
|
/openscad.pro.user
|
||||||
/openscad
|
/openscad
|
||||||
/locale/*/*/*.mo
|
/locale/*/*/*.mo
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,8 @@
|
||||||
[](https://scan.coverity.com/projects/2510)
|
[](https://scan.coverity.com/projects/2510)
|
||||||
[](https://bitdeli.com/free "Bitdeli Badge")
|
[](https://bitdeli.com/free "Bitdeli Badge")
|
||||||
|
|
||||||
|
[](https://kiwiirc.com/client/irc.freenode.net/#openscad)
|
||||||
|
|
||||||
# What is OpenSCAD?
|
# What is OpenSCAD?
|
||||||
[](https://flattr.com/submit/auto?user_id=openscad&url=http://openscad.org&title=OpenSCAD&language=&tags=github&category=software)
|
[](https://flattr.com/submit/auto?user_id=openscad&url=http://openscad.org&title=OpenSCAD&language=&tags=github&category=software)
|
||||||
|
|
||||||
|
|
@ -147,7 +149,7 @@ For the adventurous, it might be possible to build OpenSCAD using _MacPorts_ or
|
||||||
|
|
||||||
```sudo port install opencsg qscintilla boost cgal pkgconfig eigen3 harfbuzz fontconfig```
|
```sudo port install opencsg qscintilla boost cgal pkgconfig eigen3 harfbuzz fontconfig```
|
||||||
|
|
||||||
1. **Homebrew** (assumes [Homebrew](http://brew.sh)) is already installed)
|
1. **Homebrew** (assumes [Homebrew](http://brew.sh) is already installed)
|
||||||
|
|
||||||
NB! Homebrew's ```qscintilla2``` component doesn't support Qt5, so using Qt4 is currently necessary.
|
NB! Homebrew's ```qscintilla2``` component doesn't support Qt5, so using Qt4 is currently necessary.
|
||||||
However, Homebrew's Qt4 has a broken ```moc``` command, causing OpenSCAD compilation to
|
However, Homebrew's Qt4 has a broken ```moc``` command, causing OpenSCAD compilation to
|
||||||
|
|
@ -231,9 +233,9 @@ For a 64-bit Windows cross-build, replace 32 with 64 in the above instructions.
|
||||||
|
|
||||||
### Compilation
|
### Compilation
|
||||||
|
|
||||||
First, run 'qmake openscad.pro' from Qt4 to generate a Makefile.
|
First, run 'qmake openscad.pro' from Qt to generate a Makefile.
|
||||||
|
|
||||||
On some systems, depending on which version(s) of Qt you have installed, you may need to specify which version you want to use, e.g. by running 'qmake4', 'qmake-qt4' or something alike.
|
On some systems, depending on which version(s) of Qt you have installed, you may need to specify which version you want to use, e.g. by running 'qmake4', 'qmake-qt4', 'qmake -qt=qt5', or something alike.
|
||||||
|
|
||||||
Then run make. Finally you might run 'make install' as root or simply copy the
|
Then run make. Finally you might run 'make install' as root or simply copy the
|
||||||
'openscad' binary (OpenSCAD.app on Mac OS X) to the bin directory of your choice.
|
'openscad' binary (OpenSCAD.app on Mac OS X) to the bin directory of your choice.
|
||||||
|
|
|
||||||
|
|
@ -13,10 +13,12 @@ boost {
|
||||||
macx: DEFINES += __ASSERT_MACROS_DEFINE_VERSIONS_WITHOUT_UNDERSCORES=0
|
macx: DEFINES += __ASSERT_MACROS_DEFINE_VERSIONS_WITHOUT_UNDERSCORES=0
|
||||||
|
|
||||||
# MXE cross build
|
# MXE cross build
|
||||||
CONFIG(mingw-cross-env) {
|
CONFIG(mingw-cross-env)|CONFIG(mingw-cross-env-shared) {
|
||||||
DEFINES += BOOST_STATIC
|
|
||||||
DEFINES += BOOST_THREAD_USE_LIB
|
DEFINES += BOOST_THREAD_USE_LIB
|
||||||
DEFINES += Boost_USE_STATIC_LIBS
|
!CONFIG(mingw-cross-env-shared) {
|
||||||
|
DEFINES += BOOST_STATIC
|
||||||
|
DEFINES += Boost_USE_STATIC_LIBS
|
||||||
|
}
|
||||||
BOOST_LINK_FLAGS = -lboost_thread_win32-mt -lboost_program_options-mt -lboost_filesystem-mt -lboost_system-mt -lboost_regex-mt -lboost_chrono-mt
|
BOOST_LINK_FLAGS = -lboost_thread_win32-mt -lboost_program_options-mt -lboost_filesystem-mt -lboost_system-mt -lboost_regex-mt -lboost_chrono-mt
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
38
c++11.pri
Normal file
38
c++11.pri
Normal file
|
|
@ -0,0 +1,38 @@
|
||||||
|
macx {
|
||||||
|
# Mac needs special care to link against the correct C++ library
|
||||||
|
# We attempt to auto-detect it by inspecting Boost
|
||||||
|
dirs = $${BOOSTDIR} $${QMAKE_LIBDIR}
|
||||||
|
for(dir, dirs) {
|
||||||
|
system(grep -q __112basic_string $${dir}/libboost_thread* >& /dev/null) {
|
||||||
|
message("Using libc++11")
|
||||||
|
CONFIG += libc++
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
message("Using libstdc++")
|
||||||
|
CONFIG += libstdc++
|
||||||
|
c++11 {
|
||||||
|
# libc++ is a requirement for using C++11
|
||||||
|
warning("Disabling C++11 since libstdc++ dependencies were found")
|
||||||
|
CONFIG -= c++11
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
libc++ {
|
||||||
|
QMAKE_CXXFLAGS += -stdlib=libc++
|
||||||
|
QMAKE_LFLAGS += -stdlib=libc++
|
||||||
|
QMAKE_OBJECTIVE_CFLAGS += -stdlib=libc++
|
||||||
|
# libc++ on requires Mac OS X 10.7+
|
||||||
|
QMAKE_MACOSX_DEPLOYMENT_TARGET = 10.7
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
c++11 {
|
||||||
|
QMAKE_CXXFLAGS += -std=c++11
|
||||||
|
message("Using C++11")
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
*clang* {
|
||||||
|
QMAKE_CXXFLAGS_WARN_ON += -Wno-c++11-extensions
|
||||||
|
}
|
||||||
|
}
|
||||||
2
cgal.pri
2
cgal.pri
|
|
@ -10,7 +10,7 @@ cgal {
|
||||||
message("CGAL location: $$CGAL_DIR")
|
message("CGAL location: $$CGAL_DIR")
|
||||||
}
|
}
|
||||||
|
|
||||||
CONFIG(mingw-cross-env) {
|
CONFIG(mingw-cross-env)|CONFIG(mingw-cross-env-shared) {
|
||||||
LIBS += -lgmp -lmpfr -lCGAL
|
LIBS += -lgmp -lmpfr -lCGAL
|
||||||
QMAKE_CXXFLAGS += -frounding-math
|
QMAKE_CXXFLAGS += -frounding-math
|
||||||
} else {
|
} else {
|
||||||
|
|
|
||||||
203
cgal/data/issue1455.nef3
Normal file
203
cgal/data/issue1455.nef3
Normal file
|
|
@ -0,0 +1,203 @@
|
||||||
|
Selective Nef Complex
|
||||||
|
standard
|
||||||
|
vertices 15
|
||||||
|
halfedges 42
|
||||||
|
facets 18
|
||||||
|
volumes 2
|
||||||
|
shalfedges 84
|
||||||
|
shalfloops 2
|
||||||
|
sfaces 30
|
||||||
|
0 { 0 2, 0 5, 0 1, -2 | 0 0 5 1 } 1
|
||||||
|
1 { 3 5, 6 11, 2 3, -2 | 5 0 5 1 } 1
|
||||||
|
2 { 6 8, 12 17, 4 5, -2 | 5 5 5 1 } 1
|
||||||
|
3 { 9 11, 18 23, 6 7, -2 | 0 5 0 1 } 1
|
||||||
|
4 { 12 14, 24 29, 8 9, -2 | 5 0 0 1 } 1
|
||||||
|
5 { 15 17, 30 35, 10 11, -2 | 5 5 0 1 } 1
|
||||||
|
6 { 18 20, 36 41, 12 13, -2 | 0 5 5 1 } 1
|
||||||
|
7 { 21 23, 42 47, 14 15, -2 | 0 0 3 1 } 0
|
||||||
|
8 { 24 26, 48 53, 16 17, -2 | 3 0 3 1 } 0
|
||||||
|
9 { 27 29, 54 59, 18 19, -2 | 3 3 3 1 } 0
|
||||||
|
10 { 30 32, 60 65, 20 21, -2 | 0 3 0 1 } 0
|
||||||
|
11 { 33 35, 66 71, 22 23, -2 | 3 0 0 1 } 0
|
||||||
|
12 { 36 38, 72 77, 24 25, -2 | 3 3 0 1 } 0
|
||||||
|
13 { 39 41, 78 83, 26 27, -2 | 0 3 3 1 } 0
|
||||||
|
14 { -2 -2, -2 -2, 28 29, 0 | 2 2 3 1 } 1
|
||||||
|
0 { 3, 0, 0 0 | 1 0 0 1 } 1
|
||||||
|
1 { 18, 0, 0 5 | 0 1 0 1 } 1
|
||||||
|
2 { 21, 0, 0 4 | 0 0 -1 1 } 1
|
||||||
|
3 { 0, 1, 0 6 | -1 0 0 1 } 1
|
||||||
|
4 { 6, 1, 0 7 | 0 1 0 1 } 1
|
||||||
|
5 { 13, 1, 0 10 | 0 0 -1 1 } 1
|
||||||
|
6 { 4, 2, 0 14 | 0 -1 0 1 } 1
|
||||||
|
7 { 19, 2, 0 13 | -1 0 0 1 } 1
|
||||||
|
8 { 17, 2, 0 16 | 0 0 -1 1 } 1
|
||||||
|
9 { 32, 3, 0 20 | 0 -1 0 1 } 1
|
||||||
|
10 { 20, 3, 0 22 | 0 0 1 1 } 1
|
||||||
|
11 { 16, 3, 0 21 | 1 0 0 1 } 1
|
||||||
|
12 { 34, 4, 0 26 | -1 0 0 1 } 1
|
||||||
|
13 { 5, 4, 0 28 | 0 0 1 1 } 1
|
||||||
|
14 { 15, 4, 0 25 | 0 1 0 1 } 1
|
||||||
|
15 { 14, 5, 0 30 | 0 -1 0 1 } 1
|
||||||
|
16 { 11, 5, 0 34 | -1 0 0 1 } 1
|
||||||
|
17 { 8, 5, 0 35 | 0 0 1 1 } 1
|
||||||
|
18 { 1, 6, 0 36 | 0 -1 0 1 } 1
|
||||||
|
19 { 7, 6, 0 40 | 1 0 0 1 } 1
|
||||||
|
20 { 10, 6, 0 41 | 0 0 -1 1 } 1
|
||||||
|
21 { 2, 7, 0 44 | 0 0 1 1 } 1
|
||||||
|
22 { 24, 7, 0 46 | 1 0 0 1 } 0
|
||||||
|
23 { 39, 7, 0 47 | 0 1 0 1 } 0
|
||||||
|
24 { 22, 8, 0 50 | -1 0 0 1 } 0
|
||||||
|
25 { 27, 8, 0 49 | 0 1 0 1 } 0
|
||||||
|
26 { 33, 8, 0 52 | 0 0 -1 1 } 0
|
||||||
|
27 { 25, 9, 0 56 | 0 -1 0 1 } 0
|
||||||
|
28 { 40, 9, 0 55 | -1 0 0 1 } 0
|
||||||
|
29 { 38, 9, 0 58 | 0 0 -1 1 } 0
|
||||||
|
30 { 41, 10, 0 62 | 0 0 1 1 } 0
|
||||||
|
31 { 37, 10, 0 64 | 1 0 0 1 } 0
|
||||||
|
32 { 9, 10, 0 65 | 0 1 0 1 } 1
|
||||||
|
33 { 26, 11, 0 68 | 0 0 1 1 } 0
|
||||||
|
34 { 12, 11, 0 70 | 1 0 0 1 } 1
|
||||||
|
35 { 36, 11, 0 71 | 0 1 0 1 } 0
|
||||||
|
36 { 35, 12, 0 74 | 0 -1 0 1 } 0
|
||||||
|
37 { 31, 12, 0 76 | -1 0 0 1 } 0
|
||||||
|
38 { 29, 12, 0 77 | 0 0 1 1 } 0
|
||||||
|
39 { 23, 13, 0 80 | 0 -1 0 1 } 0
|
||||||
|
40 { 28, 13, 0 82 | 1 0 0 1 } 0
|
||||||
|
41 { 30, 13, 0 79 | 0 0 -1 1 } 0
|
||||||
|
0 { 1, 79 , , 0 | -1 0 0 0 } 1
|
||||||
|
1 { 0, 78 , , 1 | 1 0 0 0 } 1
|
||||||
|
2 { 3, 37 , , 0 | 0 0 1 -5 } 1
|
||||||
|
3 { 2, 36 , , 1 | 0 0 -1 5 } 1
|
||||||
|
4 { 5, 9 , , 0 | 1 0 0 -5 } 1
|
||||||
|
5 { 4, 8 , , 1 | -1 0 0 5 } 1
|
||||||
|
6 { 7, 35 , , 0 | 0 1 0 -5 } 1
|
||||||
|
7 { 6, 34 , , 1 | 0 -1 0 5 } 1
|
||||||
|
8 { 9, 74 , , 0 | 0 0 -1 0 } 1
|
||||||
|
9 { 8, 75 , , 1 | 0 0 1 0 } 1
|
||||||
|
10 { 11, 2 , , 0 | 0 -1 0 0 } 1
|
||||||
|
11 { 10, 3 , , 1 | 0 1 0 0 } 1
|
||||||
|
12 { 13, 81 , 1 , 1 | 0 0 1 -3 } 0
|
||||||
|
13 { 12, 80 , 0 , 0 | 0 0 -1 3 } 0
|
||||||
|
14 { 15, 53 , , 1 | 1 0 0 -3 } 0
|
||||||
|
15 { 14, 52 , , 0 | -1 0 0 3 } 0
|
||||||
|
16 { 17, 77 , , 1 | 0 1 0 -3 } 0
|
||||||
|
17 { 16, 76 , , 0 | 0 -1 0 3 } 0
|
||||||
|
0 { 0 } 0
|
||||||
|
1 { 15 } 1
|
||||||
|
0 { 1, 3, 5, 0, 0, 7, 36, 3 | 0 0 1 0 } 1
|
||||||
|
1 { 0, 4, 2, 1, 1, 37, 6, 2 | 0 0 -1 0 } 1
|
||||||
|
2 { 3, 1, 4, 0, 1, 10, 44, 10 | 0 1 0 0 } 1
|
||||||
|
3 { 2, 5, 0, 2, 0, 45, 11, 11 | 0 -1 0 0 } 1
|
||||||
|
4 { 5, 2, 1, 2, 1, 43, 38, 0 | 1 0 0 0 } 1
|
||||||
|
5 { 4, 0, 3, 1, 0, 39, 42, 1 | -1 0 0 0 } 1
|
||||||
|
6 { 7, 10, 9, 3, 3, 1, 12, 2 | 0 0 -1 0 } 1
|
||||||
|
7 { 6, 8, 11, 4, 2, 13, 0, 3 | 0 0 1 0 } 1
|
||||||
|
8 { 9, 11, 7, 5, 2, 29, 14, 5 | 1 0 0 0 } 1
|
||||||
|
9 { 8, 6, 10, 4, 3, 15, 28, 4 | -1 0 0 0 } 1
|
||||||
|
10 { 11, 9, 6, 5, 3, 26, 2, 10 | 0 1 0 0 } 1
|
||||||
|
11 { 10, 7, 8, 3, 2, 3, 27, 11 | 0 -1 0 0 } 1
|
||||||
|
12 { 13, 15, 17, 6, 5, 6, 37, 2 | 0 0 -1 0 } 1
|
||||||
|
13 { 12, 16, 14, 7, 4, 36, 7, 3 | 0 0 1 0 } 1
|
||||||
|
14 { 15, 13, 16, 6, 4, 8, 33, 5 | 1 0 0 0 } 1
|
||||||
|
15 { 14, 17, 12, 8, 5, 32, 9, 4 | -1 0 0 0 } 1
|
||||||
|
16 { 17, 14, 13, 8, 4, 34, 40, 7 | 0 1 0 0 } 1
|
||||||
|
17 { 16, 12, 15, 7, 5, 41, 35, 6 | 0 -1 0 0 } 1
|
||||||
|
18 { 19, 21, 22, 9, 6, 60, 39, 1 | -1 0 0 0 } 1
|
||||||
|
19 { 18, 23, 20, 10, 7, 38, 61, 0 | 1 0 0 0 } 1
|
||||||
|
20 { 21, 19, 23, 9, 7, 64, 31, 8 | 0 0 1 0 } 1
|
||||||
|
21 { 20, 22, 18, 11, 6, 30, 65, 9 | 0 0 -1 0 } 1
|
||||||
|
22 { 23, 18, 21, 10, 6, 40, 34, 7 | 0 1 0 0 } 1
|
||||||
|
23 { 22, 20, 19, 11, 7, 35, 41, 6 | 0 -1 0 0 } 1
|
||||||
|
24 { 25, 27, 29, 12, 8, 71, 30, 9 | 0 0 -1 0 } 1
|
||||||
|
25 { 24, 28, 26, 14, 9, 31, 70, 8 | 0 0 1 0 } 1
|
||||||
|
26 { 27, 25, 28, 12, 9, 68, 10, 10 | 0 1 0 0 } 1
|
||||||
|
27 { 26, 29, 24, 13, 8, 11, 69, 11 | 0 -1 0 0 } 1
|
||||||
|
28 { 29, 26, 25, 13, 9, 9, 32, 4 | -1 0 0 0 } 1
|
||||||
|
29 { 28, 24, 27, 14, 8, 33, 8, 5 | 1 0 0 0 } 1
|
||||||
|
30 { 31, 33, 34, 15, 11, 24, 21, 9 | 0 0 -1 0 } 1
|
||||||
|
31 { 30, 35, 32, 16, 10, 20, 25, 8 | 0 0 1 0 } 1
|
||||||
|
32 { 33, 31, 35, 15, 10, 28, 15, 4 | -1 0 0 0 } 1
|
||||||
|
33 { 32, 34, 30, 17, 11, 14, 29, 5 | 1 0 0 0 } 1
|
||||||
|
34 { 35, 30, 33, 16, 11, 22, 16, 7 | 0 1 0 0 } 1
|
||||||
|
35 { 34, 32, 31, 17, 10, 17, 23, 6 | 0 -1 0 0 } 1
|
||||||
|
36 { 37, 39, 40, 18, 12, 0, 13, 3 | 0 0 1 0 } 1
|
||||||
|
37 { 36, 41, 38, 19, 13, 12, 1, 2 | 0 0 -1 0 } 1
|
||||||
|
38 { 39, 37, 41, 18, 13, 4, 19, 0 | 1 0 0 0 } 1
|
||||||
|
39 { 38, 40, 36, 20, 12, 18, 5, 1 | -1 0 0 0 } 1
|
||||||
|
40 { 41, 36, 39, 19, 12, 16, 22, 7 | 0 1 0 0 } 1
|
||||||
|
41 { 40, 38, 37, 20, 13, 23, 17, 6 | 0 -1 0 0 } 1
|
||||||
|
42 { 43, 45, 47, 21, 14, 5, 78, 1 | -1 0 0 0 } 1
|
||||||
|
43 { 42, 46, 44, 23, 15, 79, 4, 0 | 1 0 0 0 } 1
|
||||||
|
44 { 45, 43, 46, 21, 15, 2, 50, 10 | 0 1 0 0 } 1
|
||||||
|
45 { 44, 47, 42, 22, 14, 51, 3, 11 | 0 -1 0 0 } 1
|
||||||
|
46 { 47, 44, 43, 22, 15, 49, 80, 13 | 0 0 1 0 } 0
|
||||||
|
47 { 46, 42, 45, 23, 14, 81, 48, 12 | 0 0 -1 0 } 0
|
||||||
|
48 { 49, 51, 53, 24, 16, 47, 54, 12 | 0 0 -1 0 } 0
|
||||||
|
49 { 48, 52, 50, 25, 17, 55, 46, 13 | 0 0 1 0 } 0
|
||||||
|
50 { 51, 49, 52, 24, 17, 44, 68, 10 | 0 1 0 0 } 1
|
||||||
|
51 { 50, 53, 48, 26, 16, 69, 45, 11 | 0 -1 0 0 } 1
|
||||||
|
52 { 53, 50, 49, 26, 17, 67, 56, 15 | 1 0 0 0 } 0
|
||||||
|
53 { 52, 48, 51, 25, 16, 57, 66, 14 | -1 0 0 0 } 0
|
||||||
|
54 { 55, 57, 59, 27, 19, 48, 81, 12 | 0 0 -1 0 } 0
|
||||||
|
55 { 54, 58, 56, 28, 18, 80, 49, 13 | 0 0 1 0 } 0
|
||||||
|
56 { 57, 55, 58, 27, 18, 52, 73, 15 | 1 0 0 0 } 0
|
||||||
|
57 { 56, 59, 54, 29, 19, 72, 53, 14 | -1 0 0 0 } 0
|
||||||
|
58 { 59, 56, 55, 29, 18, 76, 82, 17 | 0 1 0 0 } 0
|
||||||
|
59 { 58, 54, 57, 28, 19, 83, 77, 16 | 0 -1 0 0 } 0
|
||||||
|
60 { 61, 63, 65, 30, 20, 78, 18, 1 | -1 0 0 0 } 1
|
||||||
|
61 { 60, 64, 62, 32, 21, 19, 79, 0 | 1 0 0 0 } 1
|
||||||
|
62 { 63, 61, 64, 30, 21, 82, 76, 17 | 0 1 0 0 } 0
|
||||||
|
63 { 62, 65, 60, 31, 20, 77, 83, 16 | 0 -1 0 0 } 0
|
||||||
|
64 { 65, 62, 61, 31, 21, 74, 20, 8 | 0 0 1 0 } 1
|
||||||
|
65 { 64, 60, 63, 32, 20, 21, 75, 9 | 0 0 -1 0 } 1
|
||||||
|
66 { 67, 69, 71, 33, 22, 53, 72, 14 | -1 0 0 0 } 0
|
||||||
|
67 { 66, 70, 68, 35, 23, 73, 52, 15 | 1 0 0 0 } 0
|
||||||
|
68 { 69, 67, 70, 33, 23, 50, 26, 10 | 0 1 0 0 } 1
|
||||||
|
69 { 68, 71, 66, 34, 22, 27, 51, 11 | 0 -1 0 0 } 1
|
||||||
|
70 { 71, 68, 67, 34, 23, 25, 74, 8 | 0 0 1 0 } 1
|
||||||
|
71 { 70, 66, 69, 35, 22, 75, 24, 9 | 0 0 -1 0 } 1
|
||||||
|
72 { 73, 75, 77, 36, 24, 66, 57, 14 | -1 0 0 0 } 0
|
||||||
|
73 { 72, 76, 74, 38, 25, 56, 67, 15 | 1 0 0 0 } 0
|
||||||
|
74 { 75, 73, 76, 36, 25, 70, 64, 8 | 0 0 1 0 } 1
|
||||||
|
75 { 74, 77, 72, 37, 24, 65, 71, 9 | 0 0 -1 0 } 1
|
||||||
|
76 { 77, 74, 73, 37, 25, 62, 58, 17 | 0 1 0 0 } 0
|
||||||
|
77 { 76, 72, 75, 38, 24, 59, 63, 16 | 0 -1 0 0 } 0
|
||||||
|
78 { 79, 81, 83, 39, 26, 42, 60, 1 | -1 0 0 0 } 1
|
||||||
|
79 { 78, 82, 80, 41, 27, 61, 43, 0 | 1 0 0 0 } 1
|
||||||
|
80 { 81, 79, 82, 39, 27, 46, 55, 13 | 0 0 1 0 } 0
|
||||||
|
81 { 80, 83, 78, 40, 26, 54, 47, 12 | 0 0 -1 0 } 0
|
||||||
|
82 { 83, 80, 79, 40, 27, 58, 62, 17 | 0 1 0 0 } 0
|
||||||
|
83 { 82, 78, 81, 41, 26, 63, 59, 16 | 0 -1 0 0 } 0
|
||||||
|
0 { 1, 28, 13 | 0 0 1 0 } 0
|
||||||
|
1 { 0, 29, 12 | 0 0 -1 0 } 0
|
||||||
|
0 { 0, 0 , , , 0 } 0
|
||||||
|
1 { 0, 1 , , , 1 } 1
|
||||||
|
2 { 1, 7 , , , 0 } 0
|
||||||
|
3 { 1, 6 , , , 1 } 1
|
||||||
|
4 { 2, 13 , , , 0 } 0
|
||||||
|
5 { 2, 12 , , , 1 } 1
|
||||||
|
6 { 3, 18 , , , 0 } 0
|
||||||
|
7 { 3, 19 , , , 1 } 1
|
||||||
|
8 { 4, 24 , , , 0 } 0
|
||||||
|
9 { 4, 25 , , , 1 } 1
|
||||||
|
10 { 5, 31 , , , 1 } 1
|
||||||
|
11 { 5, 30 , , , 0 } 0
|
||||||
|
12 { 6, 36 , , , 0 } 0
|
||||||
|
13 { 6, 37 , , , 1 } 1
|
||||||
|
14 { 7, 42 , , , 0 } 0
|
||||||
|
15 { 7, 43 , , , 1 } 1
|
||||||
|
16 { 8, 48 , , , 0 } 0
|
||||||
|
17 { 8, 49 , , , 1 } 1
|
||||||
|
18 { 9, 55 , , , 1 } 1
|
||||||
|
19 { 9, 54 , , , 0 } 0
|
||||||
|
20 { 10, 60 , , , 0 } 0
|
||||||
|
21 { 10, 61 , , , 1 } 1
|
||||||
|
22 { 11, 66 , , , 0 } 0
|
||||||
|
23 { 11, 67 , , , 1 } 1
|
||||||
|
24 { 12, 72 , , , 0 } 0
|
||||||
|
25 { 12, 73 , , , 1 } 1
|
||||||
|
26 { 13, 78 , , , 0 } 0
|
||||||
|
27 { 13, 79 , , , 1 } 1
|
||||||
|
28 { 14, , , 0, 1 } 1
|
||||||
|
29 { 14, , , 1, 0 } 0
|
||||||
|
/* end Selective Nef complex */
|
||||||
|
|
@ -8,6 +8,9 @@
|
||||||
#include "export.h"
|
#include "export.h"
|
||||||
#include "polyset.h"
|
#include "polyset.h"
|
||||||
#include "CGAL_Nef_polyhedron.h"
|
#include "CGAL_Nef_polyhedron.h"
|
||||||
|
#include "boosty.h"
|
||||||
|
|
||||||
|
#include <CGAL/IO/Nef_polyhedron_iostream_3.h>
|
||||||
|
|
||||||
using namespace CGALUtils;
|
using namespace CGALUtils;
|
||||||
|
|
||||||
|
|
@ -16,6 +19,7 @@ using namespace CGALUtils;
|
||||||
typedef CGAL::Epick K;
|
typedef CGAL::Epick K;
|
||||||
typedef CGAL::Polyhedron_3<K> PolyhedronK;
|
typedef CGAL::Polyhedron_3<K> PolyhedronK;
|
||||||
|
|
||||||
|
#include <boost/algorithm/string.hpp>
|
||||||
#include <boost/assign/std/vector.hpp>
|
#include <boost/assign/std/vector.hpp>
|
||||||
#include <boost/assign/list_of.hpp>
|
#include <boost/assign/list_of.hpp>
|
||||||
using namespace boost::assign; // bring 'operator+=()' into scope
|
using namespace boost::assign; // bring 'operator+=()' into scope
|
||||||
|
|
@ -629,21 +633,30 @@ int main(int argc, char *argv[])
|
||||||
OpenSCAD::debug = "decompose";
|
OpenSCAD::debug = "decompose";
|
||||||
|
|
||||||
PolySet *ps = NULL;
|
PolySet *ps = NULL;
|
||||||
|
CGAL_Nef_polyhedron *N = NULL;
|
||||||
if (argc == 2) {
|
if (argc == 2) {
|
||||||
if (!(ps = import_stl(argv[1]))) {
|
std::string filename(argv[1]);
|
||||||
std::cerr << "Error importing STL " << argv[1] << std::endl;
|
std::string suffix = boosty::extension_str(filename);
|
||||||
exit(1);
|
if (suffix == ".stl") {
|
||||||
|
if (!(ps = import_stl(filename))) {
|
||||||
|
std::cerr << "Error importing STL " << filename << std::endl;
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
std::cerr << "Imported " << ps->numPolygons() << " polygons" << std::endl;
|
||||||
|
}
|
||||||
|
else if (suffix == ".nef3") {
|
||||||
|
N = new CGAL_Nef_polyhedron(new CGAL_Nef_polyhedron3);
|
||||||
|
std::ifstream stream(filename.c_str());
|
||||||
|
stream >> *N->p3;
|
||||||
|
std::cerr << "Imported Nef polyhedron" << std::endl;
|
||||||
}
|
}
|
||||||
std::cerr << "Imported " << ps->numPolygons() << " polygons" << std::endl;
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
std::cerr << "Usage: " << argv[0] << " <file.stl> <file.stl>" << std::endl;
|
std::cerr << "Usage: " << argv[0] << " <file.stl> <file.stl>" << std::endl;
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
Geometry::ChildList children;
|
if (ps && !N) N = createNefPolyhedronFromGeometry(*ps);
|
||||||
|
|
||||||
CGAL_Nef_polyhedron *N = createNefPolyhedronFromGeometry(*ps);
|
|
||||||
|
|
||||||
std::vector<PolyhedronK> result;
|
std::vector<PolyhedronK> result;
|
||||||
decompose(N->p3.get(), std::back_inserter(result));
|
decompose(N->p3.get(), std::back_inserter(result));
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@ debug: DEFINES += DEBUG
|
||||||
|
|
||||||
TEMPLATE = app
|
TEMPLATE = app
|
||||||
|
|
||||||
INCLUDEPATH += ../src
|
INCLUDEPATH += ../src ../src/libtess2/Include
|
||||||
DEPENDPATH += ../src
|
DEPENDPATH += ../src
|
||||||
|
|
||||||
# Handle custom library location.
|
# Handle custom library location.
|
||||||
|
|
@ -87,22 +87,42 @@ include(../common.pri)
|
||||||
HEADERS += ../src/cgal.h \
|
HEADERS += ../src/cgal.h \
|
||||||
../src/cgalutils.h \
|
../src/cgalutils.h \
|
||||||
../src/linalg.h \
|
../src/linalg.h \
|
||||||
|
../src/grid.h \
|
||||||
../src/polyset.h \
|
../src/polyset.h \
|
||||||
../src/polyset-utils.h \
|
../src/polyset-utils.h \
|
||||||
../src/printutils.h
|
../src/printutils.h \
|
||||||
|
../src/GeometryUtils.h \
|
||||||
|
../src/libtess2/Include/tesselator.h \
|
||||||
|
../src/libtess2/Source/bucketalloc.h \
|
||||||
|
../src/libtess2/Source/dict.h \
|
||||||
|
../src/libtess2/Source/geom.h \
|
||||||
|
../src/libtess2/Source/mesh.h \
|
||||||
|
../src/libtess2/Source/priorityq.h \
|
||||||
|
../src/libtess2/Source/sweep.h \
|
||||||
|
../src/libtess2/Source/tess.h
|
||||||
|
|
||||||
SOURCES += decompose.cpp \
|
SOURCES += decompose.cpp \
|
||||||
../src/polygon2d.cc \
|
../src/polygon2d.cc \
|
||||||
../src/polygon2d-CGAL.cc \
|
../src/polygon2d-CGAL.cc \
|
||||||
../src/CGAL_Nef_polyhedron.cc \
|
../src/CGAL_Nef_polyhedron.cc \
|
||||||
../src/CGAL_Nef_polyhedron_DxfData.cc \
|
|
||||||
../src/cgalutils.cc \
|
../src/cgalutils.cc \
|
||||||
|
../src/cgalutils-applyops.cc \
|
||||||
../src/cgalutils-tess.cc \
|
../src/cgalutils-tess.cc \
|
||||||
../src/cgalutils-polyhedron.cc \
|
../src/cgalutils-polyhedron.cc \
|
||||||
../src/polyset.cc \
|
../src/polyset.cc \
|
||||||
|
../src/polyset-gl.cc \
|
||||||
|
../src/GeometryUtils.cc \
|
||||||
../src/svg.cc \
|
../src/svg.cc \
|
||||||
|
../src/grid.cc \
|
||||||
../src/node.cc \
|
../src/node.cc \
|
||||||
../src/export.cc \
|
../src/export.cc \
|
||||||
../src/polyset-utils.cc \
|
../src/polyset-utils.cc \
|
||||||
../src/progress.cc \
|
../src/progress.cc \
|
||||||
../src/printutils.cc
|
../src/printutils.cc \
|
||||||
|
../src/libtess2/Source/bucketalloc.c \
|
||||||
|
../src/libtess2/Source/dict.c \
|
||||||
|
../src/libtess2/Source/geom.c \
|
||||||
|
../src/libtess2/Source/mesh.c \
|
||||||
|
../src/libtess2/Source/priorityq.c \
|
||||||
|
../src/libtess2/Source/sweep.c \
|
||||||
|
../src/libtess2/Source/tess.c
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@ debug: DEFINES += DEBUG
|
||||||
|
|
||||||
TEMPLATE = app
|
TEMPLATE = app
|
||||||
|
|
||||||
INCLUDEPATH += ../src
|
INCLUDEPATH += ../src ../src/libtess2/Include
|
||||||
DEPENDPATH += ../src
|
DEPENDPATH += ../src
|
||||||
|
|
||||||
# Handle custom library location.
|
# Handle custom library location.
|
||||||
|
|
@ -87,23 +87,42 @@ include(../common.pri)
|
||||||
HEADERS += ../src/cgal.h \
|
HEADERS += ../src/cgal.h \
|
||||||
../src/cgalutils.h \
|
../src/cgalutils.h \
|
||||||
../src/linalg.h \
|
../src/linalg.h \
|
||||||
|
../src/grid.h \
|
||||||
../src/polyset.h \
|
../src/polyset.h \
|
||||||
../src/polyset-utils.h \
|
../src/polyset-utils.h \
|
||||||
../src/printutils.h
|
../src/printutils.h \
|
||||||
|
../src/GeometryUtils.h \
|
||||||
|
../src/libtess2/Include/tesselator.h \
|
||||||
|
../src/libtess2/Source/bucketalloc.h \
|
||||||
|
../src/libtess2/Source/dict.h \
|
||||||
|
../src/libtess2/Source/geom.h \
|
||||||
|
../src/libtess2/Source/mesh.h \
|
||||||
|
../src/libtess2/Source/priorityq.h \
|
||||||
|
../src/libtess2/Source/sweep.h \
|
||||||
|
../src/libtess2/Source/tess.h
|
||||||
|
|
||||||
SOURCES += export_nef.cpp \
|
SOURCES += export_nef.cpp \
|
||||||
../src/polygon2d.cc \
|
../src/polygon2d.cc \
|
||||||
../src/polygon2d-CGAL.cc \
|
../src/polygon2d-CGAL.cc \
|
||||||
../src/CGAL_Nef_polyhedron.cc \
|
../src/CGAL_Nef_polyhedron.cc \
|
||||||
../src/CGAL_Nef_polyhedron_DxfData.cc \
|
|
||||||
../src/cgalutils.cc \
|
../src/cgalutils.cc \
|
||||||
|
../src/cgalutils-applyops.cc \
|
||||||
../src/cgalutils-tess.cc \
|
../src/cgalutils-tess.cc \
|
||||||
../src/cgalutils-polyhedron.cc \
|
../src/cgalutils-polyhedron.cc \
|
||||||
../src/polyset.cc \
|
../src/polyset.cc \
|
||||||
|
../src/polyset-gl.cc \
|
||||||
|
../src/GeometryUtils.cc \
|
||||||
../src/svg.cc \
|
../src/svg.cc \
|
||||||
|
../src/grid.cc \
|
||||||
../src/node.cc \
|
../src/node.cc \
|
||||||
../src/export.cc \
|
../src/export.cc \
|
||||||
../src/polyset-utils.cc \
|
../src/polyset-utils.cc \
|
||||||
../src/progress.cc \
|
../src/progress.cc \
|
||||||
../src/printutils.cc \
|
../src/printutils.cc \
|
||||||
../src/grid.cc
|
../src/libtess2/Source/bucketalloc.c \
|
||||||
|
../src/libtess2/Source/dict.c \
|
||||||
|
../src/libtess2/Source/geom.c \
|
||||||
|
../src/libtess2/Source/mesh.c \
|
||||||
|
../src/libtess2/Source/priorityq.c \
|
||||||
|
../src/libtess2/Source/sweep.c \
|
||||||
|
../src/libtess2/Source/tess.c
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@
|
||||||
|
|
||||||
"colors" : {
|
"colors" : {
|
||||||
"background" : "#333333",
|
"background" : "#333333",
|
||||||
|
"axes-color" : "#c1c1c1",
|
||||||
"opencsg-face-front" : "#cccccc",
|
"opencsg-face-front" : "#cccccc",
|
||||||
"opencsg-face-back" : "#5563dd",
|
"opencsg-face-back" : "#5563dd",
|
||||||
"cgal-face-front" : "#cccccc",
|
"cgal-face-front" : "#cccccc",
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@
|
||||||
|
|
||||||
"colors" : {
|
"colors" : {
|
||||||
"background" : "#333333",
|
"background" : "#333333",
|
||||||
|
"axes-color" : "#c1c1c1",
|
||||||
"opencsg-face-front" : "#eeeeee",
|
"opencsg-face-front" : "#eeeeee",
|
||||||
"opencsg-face-back" : "#0babc8",
|
"opencsg-face-back" : "#0babc8",
|
||||||
"cgal-face-front" : "#eeeeee",
|
"cgal-face-front" : "#eeeeee",
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@
|
||||||
|
|
||||||
"colors" : {
|
"colors" : {
|
||||||
"background" : "#aaaaff",
|
"background" : "#aaaaff",
|
||||||
|
"axes-color" : "#222233",
|
||||||
"opencsg-face-front" : "#ddddff",
|
"opencsg-face-front" : "#ddddff",
|
||||||
"opencsg-face-back" : "#dd22dd",
|
"opencsg-face-back" : "#dd22dd",
|
||||||
"cgal-face-front" : "#ddddff",
|
"cgal-face-front" : "#ddddff",
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,7 @@
|
||||||
|
|
||||||
"colors" : {
|
"colors" : {
|
||||||
"background" : "#ffffe5",
|
"background" : "#ffffe5",
|
||||||
|
"axes-color" : "#191916",
|
||||||
"opencsg-face-front" : "#f9d72c",
|
"opencsg-face-front" : "#f9d72c",
|
||||||
"opencsg-face-back" : "#f9d72c",
|
"opencsg-face-back" : "#f9d72c",
|
||||||
"cgal-face-front" : "#f9d72c",
|
"cgal-face-front" : "#f9d72c",
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@
|
||||||
|
|
||||||
"colors" : {
|
"colors" : {
|
||||||
"background" : "#fafafa",
|
"background" : "#fafafa",
|
||||||
|
"axes-color" : "#323232",
|
||||||
"opencsg-face-front" : "#16a085",
|
"opencsg-face-front" : "#16a085",
|
||||||
"opencsg-face-back" : "#dbf4da",
|
"opencsg-face-back" : "#dbf4da",
|
||||||
"cgal-face-front" : "#16a085",
|
"cgal-face-front" : "#16a085",
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@
|
||||||
|
|
||||||
"colors" : {
|
"colors" : {
|
||||||
"background" : "#fdf6e3",
|
"background" : "#fdf6e3",
|
||||||
|
"axes-color" : "#191816",
|
||||||
"opencsg-face-front" : "#b58800",
|
"opencsg-face-front" : "#b58800",
|
||||||
"opencsg-face-back" : "#882233",
|
"opencsg-face-back" : "#882233",
|
||||||
"cgal-face-front" : "#b58800",
|
"cgal-face-front" : "#b58800",
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@
|
||||||
|
|
||||||
"colors" : {
|
"colors" : {
|
||||||
"background" : "#000000",
|
"background" : "#000000",
|
||||||
|
"axes-color" : "#e5e5e5",
|
||||||
"opencsg-face-front" : "#ffffe0",
|
"opencsg-face-front" : "#ffffe0",
|
||||||
"opencsg-face-back" : "#00ffff",
|
"opencsg-face-back" : "#00ffff",
|
||||||
"cgal-face-front" : "#ffffe0",
|
"cgal-face-front" : "#ffffe0",
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@
|
||||||
|
|
||||||
"colors" : {
|
"colors" : {
|
||||||
"background" : "#aa4444",
|
"background" : "#aa4444",
|
||||||
|
"axes-color" : "#220d0d",
|
||||||
"opencsg-face-front" : "#ffaaaa",
|
"opencsg-face-front" : "#ffaaaa",
|
||||||
"opencsg-face-back" : "#882233",
|
"opencsg-face-back" : "#882233",
|
||||||
"cgal-face-front" : "#ffaaaa",
|
"cgal-face-front" : "#ffaaaa",
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@
|
||||||
|
|
||||||
"colors" : {
|
"colors" : {
|
||||||
"background" : "#1d1f21",
|
"background" : "#1d1f21",
|
||||||
|
"axes-color" : "#e8e8e8",
|
||||||
"opencsg-face-front" : "#81a2be",
|
"opencsg-face-front" : "#81a2be",
|
||||||
"opencsg-face-back" : "#de935f",
|
"opencsg-face-back" : "#de935f",
|
||||||
"cgal-face-front" : "#8abeb7",
|
"cgal-face-front" : "#8abeb7",
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@
|
||||||
|
|
||||||
"colors" : {
|
"colors" : {
|
||||||
"background" : "#f8f8f8",
|
"background" : "#f8f8f8",
|
||||||
|
"axes-color" : "#181818",
|
||||||
"opencsg-face-front" : "#4271ae",
|
"opencsg-face-front" : "#4271ae",
|
||||||
"opencsg-face-back" : "#f5871f",
|
"opencsg-face-back" : "#f5871f",
|
||||||
"cgal-face-front" : "#3e999f",
|
"cgal-face-front" : "#3e999f",
|
||||||
|
|
|
||||||
|
|
@ -18,3 +18,4 @@ include(harfbuzz.pri)
|
||||||
include(freetype.pri)
|
include(freetype.pri)
|
||||||
include(fontconfig.pri)
|
include(fontconfig.pri)
|
||||||
include(scintilla.pri)
|
include(scintilla.pri)
|
||||||
|
include(c++11.pri)
|
||||||
|
|
|
||||||
9
contrib/appdata.its
Normal file
9
contrib/appdata.its
Normal file
|
|
@ -0,0 +1,9 @@
|
||||||
|
<!-- Copyright 2013 Richard Hughes <richard@hughsie.com> -->
|
||||||
|
<its:rules
|
||||||
|
xmlns:its="http://www.w3.org/2005/11/its"
|
||||||
|
version="1.0">
|
||||||
|
<its:translateRule translate="no" selector="/component"/>
|
||||||
|
<its:translateRule translate="yes"
|
||||||
|
selector="/component/summary |
|
||||||
|
/component/description"/>
|
||||||
|
</its:rules>
|
||||||
|
|
@ -1,9 +1,9 @@
|
||||||
;;; scad-mode.el --- Major mode for editing SCAD files
|
;;; scad-mode.el --- A major mode for editing OpenSCAD code
|
||||||
|
|
||||||
;; Author: Len Trigg
|
;; Author: Len Trigg, Łukasz Stelmach
|
||||||
;; Maintainer: Len Trigg <lenbok@gmail.com>
|
;; Maintainer: Len Trigg <lenbok@gmail.com>
|
||||||
;; Created: March 2010
|
;; Created: March 2010
|
||||||
;; Modified: 24 May 2014
|
;; Modified: 28 Mar 2015
|
||||||
;; Keywords: languages
|
;; Keywords: languages
|
||||||
;; URL: https://raw.github.com/openscad/openscad/master/contrib/scad-mode.el
|
;; URL: https://raw.github.com/openscad/openscad/master/contrib/scad-mode.el
|
||||||
;; Version: 91.0
|
;; Version: 91.0
|
||||||
|
|
@ -26,11 +26,11 @@
|
||||||
;;; Commentary:
|
;;; Commentary:
|
||||||
;;
|
;;
|
||||||
;; This is a major-mode to implement the SCAD constructs and
|
;; This is a major-mode to implement the SCAD constructs and
|
||||||
;; font-locking for openscad
|
;; font-locking for OpenSCAD
|
||||||
;;
|
;;
|
||||||
;; If installing manually, insert the following into your emacs startup:
|
;; If installing manually, insert the following into your emacs startup:
|
||||||
;;
|
;;
|
||||||
;; (autoload 'scad-mode "scad-mode" "Major mode for editing SCAD code." t)
|
;; (autoload 'scad-mode "scad-mode" "A major mode for editing OpenSCAD code." t)
|
||||||
;; (add-to-list 'auto-mode-alist '("\\.scad$" . scad-mode))
|
;; (add-to-list 'auto-mode-alist '("\\.scad$" . scad-mode))
|
||||||
;;
|
;;
|
||||||
;; or
|
;; or
|
||||||
|
|
@ -48,6 +48,8 @@
|
||||||
;;;###autoload
|
;;;###autoload
|
||||||
(add-to-list 'auto-mode-alist '("\\.scad$" . scad-mode))
|
(add-to-list 'auto-mode-alist '("\\.scad$" . scad-mode))
|
||||||
|
|
||||||
|
(require 'cc-mode)
|
||||||
|
|
||||||
(defcustom scad-command
|
(defcustom scad-command
|
||||||
'"openscad"
|
'"openscad"
|
||||||
"Path to openscad executable"
|
"Path to openscad executable"
|
||||||
|
|
@ -68,30 +70,41 @@
|
||||||
"str"
|
"str"
|
||||||
"lookup" "version" "version_num" "len" "search"
|
"lookup" "version" "version_num" "len" "search"
|
||||||
"dxf_dim" "dxf_cross" ;;dxfdim.cc
|
"dxf_dim" "dxf_cross" ;;dxfdim.cc
|
||||||
|
"norm" "cross" ;;2014.03
|
||||||
|
"concat" "chr" ;;2015.03
|
||||||
)
|
)
|
||||||
"SCAD functions."
|
"SCAD functions."
|
||||||
:type 'list
|
:type 'list
|
||||||
:group 'scad-font-lock)
|
:group 'scad-font-lock)
|
||||||
|
|
||||||
(defcustom scad-modules
|
(defcustom scad-modules
|
||||||
'("child" "children" "echo" "assign" "for" "intersection_for" "if" "else" ;;control.cc
|
'("children" "echo" "for" "intersection_for" "if" "else" ;;control.cc
|
||||||
"cube" "sphere" "cylinder" "polyhedron" "square" "circle" "polygon" ;;primitives.cc
|
"cube" "sphere" "cylinder" "polyhedron" "square" "circle" "polygon" ;;primitives.cc
|
||||||
"scale" "rotate" "translate" "mirror" "multmatrix" ;;transform.cc
|
"scale" "rotate" "translate" "mirror" "multmatrix" ;;transform.cc
|
||||||
"union" "difference" "intersection" ;;csgops.cc
|
"union" "difference" "intersection" ;;csgops.cc
|
||||||
"render" ;;render.cc
|
"render" ;;render.cc
|
||||||
"color" ;;color.cc
|
"color" ;;color.cc
|
||||||
"surface" ;;surface.cc
|
"surface" ;;surface.cc
|
||||||
"dxf_linear_extrude" "linear_extrude" ;;linearextrude.cc
|
"linear_extrude" ;;linearextrude.cc
|
||||||
"dxf_rotate_extrude" "rotate_extrude" ;;rotateextrude.cc
|
"rotate_extrude" ;;rotateextrude.cc
|
||||||
"import_stl" "import_off" "import_dxf" "import" ;;import.cc
|
"import" ;;import.cc
|
||||||
"group" ;;builtin.cc
|
"group" ;;builtin.cc
|
||||||
"projection" ;;projection.cc
|
"projection" ;;projection.cc
|
||||||
"minkowski" "glide" "subdiv" "hull" "resize" ;;cgaladv.cc
|
"minkowski" "glide" "subdiv" "hull" "resize" ;;cgaladv.cc
|
||||||
|
"parent_module" ;;2014.03
|
||||||
|
"let" "offset" "text" ;;2015.03
|
||||||
)
|
)
|
||||||
"SCAD modules."
|
"SCAD modules."
|
||||||
:type 'list
|
:type 'list
|
||||||
:group 'scad-font-lock)
|
:group 'scad-font-lock)
|
||||||
|
|
||||||
|
(defcustom scad-deprecated
|
||||||
|
'("child" "assign" "dxf_linear_extrude" "dxf_rotate_extrude"
|
||||||
|
"import_stl" "import_off" "import_dxf")
|
||||||
|
"SCAD deprecated modules and functions."
|
||||||
|
:type 'list
|
||||||
|
:group 'scad-font-lock)
|
||||||
|
|
||||||
(defcustom scad-operators
|
(defcustom scad-operators
|
||||||
'("+" "-" "*" "/" "%"
|
'("+" "-" "*" "/" "%"
|
||||||
"&&" "||" "!"
|
"&&" "||" "!"
|
||||||
|
|
@ -103,9 +116,9 @@
|
||||||
|
|
||||||
(defvar scad-mode-map
|
(defvar scad-mode-map
|
||||||
(let ((map (make-sparse-keymap)))
|
(let ((map (make-sparse-keymap)))
|
||||||
(define-key map "\t" 'scad-indent-line)
|
|
||||||
(define-key map [(control c) (control o)] 'scad-open-current-buffer)
|
(define-key map [(control c) (control o)] 'scad-open-current-buffer)
|
||||||
(define-key map [return] 'newline-and-indent)
|
(define-key map [return] 'newline-and-indent)
|
||||||
|
;;(define-key map [(control c) (control s)] 'c-show-syntactic-information) ;; Debugging info
|
||||||
map)
|
map)
|
||||||
"Keymap for `scad-mode'.")
|
"Keymap for `scad-mode'.")
|
||||||
|
|
||||||
|
|
@ -138,6 +151,7 @@
|
||||||
(defvar scad-keywords-regexp (regexp-opt scad-keywords 'words))
|
(defvar scad-keywords-regexp (regexp-opt scad-keywords 'words))
|
||||||
(defvar scad-modules-regexp (regexp-opt scad-modules 'words))
|
(defvar scad-modules-regexp (regexp-opt scad-modules 'words))
|
||||||
(defvar scad-functions-regexp (regexp-opt scad-functions 'words))
|
(defvar scad-functions-regexp (regexp-opt scad-functions 'words))
|
||||||
|
(defvar scad-deprecated-regexp (regexp-opt scad-deprecated 'words))
|
||||||
(defvar scad-operators-regexp (regexp-opt scad-operators))
|
(defvar scad-operators-regexp (regexp-opt scad-operators))
|
||||||
|
|
||||||
(defvar scad-font-lock-keywords
|
(defvar scad-font-lock-keywords
|
||||||
|
|
@ -149,30 +163,41 @@
|
||||||
(,scad-keywords-regexp . font-lock-keyword-face)
|
(,scad-keywords-regexp . font-lock-keyword-face)
|
||||||
(,scad-modules-regexp . font-lock-builtin-face)
|
(,scad-modules-regexp . font-lock-builtin-face)
|
||||||
(,scad-functions-regexp . font-lock-function-name-face)
|
(,scad-functions-regexp . font-lock-function-name-face)
|
||||||
|
(,scad-deprecated-regexp . font-lock-warning-face)
|
||||||
;(,scad-operators-regexp . font-lock-operator-face) ;; This actually looks pretty ugly
|
;(,scad-operators-regexp . font-lock-operator-face) ;; This actually looks pretty ugly
|
||||||
;("\\(\\<\\S +\\>\\)\\s *(" 1 font-lock-function-name-face t) ;; Seems to override other stuff (e.g. in comments and builtins)
|
;("\\(\\<\\S +\\>\\)\\s *(" 1 font-lock-function-name-face t) ;; Seems to override other stuff (e.g. in comments and builtins)
|
||||||
)
|
)
|
||||||
"Keyword highlighting specification for `scad-mode'.")
|
"Keyword highlighting specification for `scad-mode'.")
|
||||||
|
(defconst scad-font-lock-keywords-1 scad-font-lock-keywords)
|
||||||
|
(defconst scad-font-lock-keywords-2 scad-font-lock-keywords)
|
||||||
|
(defconst scad-font-lock-keywords-3 scad-font-lock-keywords)
|
||||||
|
|
||||||
;(defvar scad-imenu-generic-expression ...)
|
(defvar scad-indent-style nil
|
||||||
;(defvar scad-outline-regexp ...)
|
"The style of indentation for scad-mode. Defaults to \"k&r\" if
|
||||||
|
nil. If you want to set the style with file local variables use
|
||||||
|
the `c-file-style' variable")
|
||||||
|
|
||||||
|
(put 'scad-mode 'c-mode-prefix "scad-")
|
||||||
;;;###autoload
|
;;;###autoload
|
||||||
(define-derived-mode scad-mode fundamental-mode "SCAD"
|
(define-derived-mode scad-mode prog-mode "SCAD"
|
||||||
"A major mode for editing SCAD files."
|
"Major mode for editing OpenSCAD code.
|
||||||
:syntax-table scad-mode-syntax-table
|
|
||||||
(set (make-local-variable 'font-lock-defaults) '(scad-font-lock-keywords))
|
|
||||||
(set (make-local-variable 'indent-line-function) 'scad-indent-line)
|
|
||||||
;(set (make-local-variable 'imenu-generic-expression) scad-imenu-generic-expression)
|
|
||||||
;(set (make-local-variable 'outline-regexp) scad-outline-regexp)
|
|
||||||
;; set comment styles for scad mode
|
|
||||||
(set (make-local-variable 'comment-start) "//")
|
|
||||||
(set (make-local-variable 'comment-end) "")
|
|
||||||
(set (make-local-variable 'block-comment-start) "/*")
|
|
||||||
(set (make-local-variable 'block-comment-end) "*/")
|
|
||||||
|
|
||||||
)
|
To see what version of CC Mode you are running, enter `\\[c-version]'.
|
||||||
|
|
||||||
|
The hook `c-mode-common-hook' is run with no args at mode
|
||||||
|
initialization, then `scad-mode-hook'.
|
||||||
|
|
||||||
|
Key bindings:
|
||||||
|
\\{scad-mode-map}"
|
||||||
|
(c-initialize-cc-mode)
|
||||||
|
;; (setq local-abbrev-table scad-mode-abbrev-table
|
||||||
|
;; abbrev-mode t)
|
||||||
|
(use-local-map scad-mode-map)
|
||||||
|
(c-set-offset (quote cpp-macro) 0 nil)
|
||||||
|
(c-basic-common-init 'scad-mode (or scad-indent-style "k&r"))
|
||||||
|
(c-font-lock-init)
|
||||||
|
(c-run-mode-hooks 'c-mode-common-hook 'scad-mode-hook)
|
||||||
|
(c-update-modeline))
|
||||||
|
|
||||||
;; From: http://stackoverflow.com/questions/14520073/add-words-for-dynamic-expansion-to-emacs-mode
|
;; From: http://stackoverflow.com/questions/14520073/add-words-for-dynamic-expansion-to-emacs-mode
|
||||||
(defun scad-prime-dabbrev ()
|
(defun scad-prime-dabbrev ()
|
||||||
|
|
@ -181,66 +206,9 @@
|
||||||
(with-current-buffer (get-buffer-create " *scad words*")
|
(with-current-buffer (get-buffer-create " *scad words*")
|
||||||
(scad-mode)
|
(scad-mode)
|
||||||
(insert "module function use include") ; Explicitly add these -- they're not in the below vars
|
(insert "module function use include") ; Explicitly add these -- they're not in the below vars
|
||||||
(insert (mapconcat 'identity (append scad-keywords scad-functions scad-modules) " ")))))
|
(insert (mapconcat 'identity (append scad-keywords scad-functions scad-modules scad-deprecated) " ")))))
|
||||||
(add-hook 'scad-mode-hook 'scad-prime-dabbrev)
|
(add-hook 'scad-mode-hook 'scad-prime-dabbrev)
|
||||||
|
|
||||||
|
|
||||||
;;; Indentation, based on http://www.emacswiki.org/emacs/download/actionscript-mode-haas-7.0.el
|
|
||||||
|
|
||||||
(defun scad-indent-line ()
|
|
||||||
"Indent current line of SCAD code."
|
|
||||||
(interactive)
|
|
||||||
(let ((savep (> (current-column) (current-indentation)))
|
|
||||||
(indent (max (scad-calculate-indentation) 0)))
|
|
||||||
(if savep
|
|
||||||
(save-excursion (indent-line-to indent))
|
|
||||||
(indent-line-to indent))))
|
|
||||||
|
|
||||||
(defun scad-calculate-indentation ()
|
|
||||||
"Return the column to which the current line should be indented."
|
|
||||||
(save-excursion
|
|
||||||
(scad-maybe-skip-leading-close-delim)
|
|
||||||
(let ((pos (point)))
|
|
||||||
(beginning-of-line)
|
|
||||||
(if (not (search-backward-regexp "[^\n\t\r ]" 1 0))
|
|
||||||
0
|
|
||||||
(progn
|
|
||||||
(scad-maybe-skip-leading-close-delim)
|
|
||||||
(+ (current-indentation) (* standard-indent (scad-count-scope-depth (point) pos))))))))
|
|
||||||
|
|
||||||
(defun scad-maybe-skip-leading-close-delim ()
|
|
||||||
(beginning-of-line)
|
|
||||||
(forward-to-indentation 0)
|
|
||||||
(if (looking-at "\\s)")
|
|
||||||
(forward-char)
|
|
||||||
(beginning-of-line)))
|
|
||||||
|
|
||||||
(defun scad-face-at-point (pos)
|
|
||||||
"Return face descriptor for char at point."
|
|
||||||
(plist-get (text-properties-at pos) 'face))
|
|
||||||
|
|
||||||
(defun scad-count-scope-depth (rstart rend)
|
|
||||||
"Return difference between open and close scope delimeters."
|
|
||||||
(save-excursion
|
|
||||||
(goto-char rstart)
|
|
||||||
(let ((open-count 0)
|
|
||||||
(close-count 0)
|
|
||||||
opoint)
|
|
||||||
(while (and (< (point) rend)
|
|
||||||
(progn (setq opoint (point))
|
|
||||||
(re-search-forward "\\s)\\|\\s(" rend t)))
|
|
||||||
(if (= opoint (point))
|
|
||||||
(forward-char 1)
|
|
||||||
(cond
|
|
||||||
;; Don't count if in string or comment.
|
|
||||||
((scad-face-at-point (- (point) 1)))
|
|
||||||
((looking-back "\\s)")
|
|
||||||
(setq close-count (+ close-count 1)))
|
|
||||||
((looking-back "\\s(")
|
|
||||||
(setq open-count (+ open-count 1)))
|
|
||||||
)))
|
|
||||||
(- open-count close-count))))
|
|
||||||
|
|
||||||
(defun scad-open-current-buffer ()
|
(defun scad-open-current-buffer ()
|
||||||
(interactive)
|
(interactive)
|
||||||
(call-process scad-command nil 0 nil (buffer-file-name)))
|
(call-process scad-command nil 0 nil (buffer-file-name)))
|
||||||
|
|
|
||||||
259
doc/Python-LICENSE.txt
Normal file
259
doc/Python-LICENSE.txt
Normal file
|
|
@ -0,0 +1,259 @@
|
||||||
|
Part of OpenSCAD is copied from Python (linalg.cc/hash_floating_point()),
|
||||||
|
so the python license is included below.
|
||||||
|
|
||||||
|
----
|
||||||
|
|
||||||
|
A. HISTORY OF THE SOFTWARE
|
||||||
|
==========================
|
||||||
|
|
||||||
|
Python was created in the early 1990s by Guido van Rossum at Stichting
|
||||||
|
Mathematisch Centrum (CWI, see http://www.cwi.nl) in the Netherlands
|
||||||
|
as a successor of a language called ABC. Guido remains Python's
|
||||||
|
principal author, although it includes many contributions from others.
|
||||||
|
|
||||||
|
In 1995, Guido continued his work on Python at the Corporation for
|
||||||
|
National Research Initiatives (CNRI, see http://www.cnri.reston.va.us)
|
||||||
|
in Reston, Virginia where he released several versions of the
|
||||||
|
software.
|
||||||
|
|
||||||
|
In May 2000, Guido and the Python core development team moved to
|
||||||
|
BeOpen.com to form the BeOpen PythonLabs team. In October of the same
|
||||||
|
year, the PythonLabs team moved to Digital Creations (now Zope
|
||||||
|
Corporation, see http://www.zope.com). In 2001, the Python Software
|
||||||
|
Foundation (PSF, see http://www.python.org/psf/) was formed, a
|
||||||
|
non-profit organization created specifically to own Python-related
|
||||||
|
Intellectual Property. Zope Corporation is a sponsoring member of
|
||||||
|
the PSF.
|
||||||
|
|
||||||
|
All Python releases are Open Source (see http://www.opensource.org for
|
||||||
|
the Open Source Definition). Historically, most, but not all, Python
|
||||||
|
releases have also been GPL-compatible; the table below summarizes
|
||||||
|
the various releases.
|
||||||
|
|
||||||
|
Release Derived Year Owner GPL-
|
||||||
|
from compatible? (1)
|
||||||
|
|
||||||
|
0.9.0 thru 1.2 1991-1995 CWI yes
|
||||||
|
1.3 thru 1.5.2 1.2 1995-1999 CNRI yes
|
||||||
|
1.6 1.5.2 2000 CNRI no
|
||||||
|
2.0 1.6 2000 BeOpen.com no
|
||||||
|
1.6.1 1.6 2001 CNRI yes (2)
|
||||||
|
2.1 2.0+1.6.1 2001 PSF no
|
||||||
|
2.0.1 2.0+1.6.1 2001 PSF yes
|
||||||
|
2.1.1 2.1+2.0.1 2001 PSF yes
|
||||||
|
2.1.2 2.1.1 2002 PSF yes
|
||||||
|
2.1.3 2.1.2 2002 PSF yes
|
||||||
|
2.2 and above 2.1.1 2001-now PSF yes
|
||||||
|
|
||||||
|
Footnotes:
|
||||||
|
|
||||||
|
(1) GPL-compatible doesn't mean that we're distributing Python under
|
||||||
|
the GPL. All Python licenses, unlike the GPL, let you distribute
|
||||||
|
a modified version without making your changes open source. The
|
||||||
|
GPL-compatible licenses make it possible to combine Python with
|
||||||
|
other software that is released under the GPL; the others don't.
|
||||||
|
|
||||||
|
(2) According to Richard Stallman, 1.6.1 is not GPL-compatible,
|
||||||
|
because its license has a choice of law clause. According to
|
||||||
|
CNRI, however, Stallman's lawyer has told CNRI's lawyer that 1.6.1
|
||||||
|
is "not incompatible" with the GPL.
|
||||||
|
|
||||||
|
Thanks to the many outside volunteers who have worked under Guido's
|
||||||
|
direction to make these releases possible.
|
||||||
|
|
||||||
|
|
||||||
|
B. TERMS AND CONDITIONS FOR ACCESSING OR OTHERWISE USING PYTHON
|
||||||
|
===============================================================
|
||||||
|
|
||||||
|
PYTHON SOFTWARE FOUNDATION LICENSE VERSION 2
|
||||||
|
--------------------------------------------
|
||||||
|
|
||||||
|
1. This LICENSE AGREEMENT is between the Python Software Foundation
|
||||||
|
("PSF"), and the Individual or Organization ("Licensee") accessing and
|
||||||
|
otherwise using this software ("Python") in source or binary form and
|
||||||
|
its associated documentation.
|
||||||
|
|
||||||
|
2. Subject to the terms and conditions of this License Agreement, PSF hereby
|
||||||
|
grants Licensee a nonexclusive, royalty-free, world-wide license to reproduce,
|
||||||
|
analyze, test, perform and/or display publicly, prepare derivative works,
|
||||||
|
distribute, and otherwise use Python alone or in any derivative version,
|
||||||
|
provided, however, that PSF's License Agreement and PSF's notice of copyright,
|
||||||
|
i.e., "Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
|
||||||
|
2011, 2012, 2013, 2014, 2015 Python Software Foundation; All Rights Reserved"
|
||||||
|
are retained in Python alone or in any derivative version prepared by Licensee.
|
||||||
|
|
||||||
|
3. In the event Licensee prepares a derivative work that is based on
|
||||||
|
or incorporates Python or any part thereof, and wants to make
|
||||||
|
the derivative work available to others as provided herein, then
|
||||||
|
Licensee hereby agrees to include in any such work a brief summary of
|
||||||
|
the changes made to Python.
|
||||||
|
|
||||||
|
4. PSF is making Python available to Licensee on an "AS IS"
|
||||||
|
basis. PSF MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR
|
||||||
|
IMPLIED. BY WAY OF EXAMPLE, BUT NOT LIMITATION, PSF MAKES NO AND
|
||||||
|
DISCLAIMS ANY REPRESENTATION OR WARRANTY OF MERCHANTABILITY OR FITNESS
|
||||||
|
FOR ANY PARTICULAR PURPOSE OR THAT THE USE OF PYTHON WILL NOT
|
||||||
|
INFRINGE ANY THIRD PARTY RIGHTS.
|
||||||
|
|
||||||
|
5. PSF SHALL NOT BE LIABLE TO LICENSEE OR ANY OTHER USERS OF PYTHON
|
||||||
|
FOR ANY INCIDENTAL, SPECIAL, OR CONSEQUENTIAL DAMAGES OR LOSS AS
|
||||||
|
A RESULT OF MODIFYING, DISTRIBUTING, OR OTHERWISE USING PYTHON,
|
||||||
|
OR ANY DERIVATIVE THEREOF, EVEN IF ADVISED OF THE POSSIBILITY THEREOF.
|
||||||
|
|
||||||
|
6. This License Agreement will automatically terminate upon a material
|
||||||
|
breach of its terms and conditions.
|
||||||
|
|
||||||
|
7. Nothing in this License Agreement shall be deemed to create any
|
||||||
|
relationship of agency, partnership, or joint venture between PSF and
|
||||||
|
Licensee. This License Agreement does not grant permission to use PSF
|
||||||
|
trademarks or trade name in a trademark sense to endorse or promote
|
||||||
|
products or services of Licensee, or any third party.
|
||||||
|
|
||||||
|
8. By copying, installing or otherwise using Python, Licensee
|
||||||
|
agrees to be bound by the terms and conditions of this License
|
||||||
|
Agreement.
|
||||||
|
|
||||||
|
|
||||||
|
BEOPEN.COM LICENSE AGREEMENT FOR PYTHON 2.0
|
||||||
|
-------------------------------------------
|
||||||
|
|
||||||
|
BEOPEN PYTHON OPEN SOURCE LICENSE AGREEMENT VERSION 1
|
||||||
|
|
||||||
|
1. This LICENSE AGREEMENT is between BeOpen.com ("BeOpen"), having an
|
||||||
|
office at 160 Saratoga Avenue, Santa Clara, CA 95051, and the
|
||||||
|
Individual or Organization ("Licensee") accessing and otherwise using
|
||||||
|
this software in source or binary form and its associated
|
||||||
|
documentation ("the Software").
|
||||||
|
|
||||||
|
2. Subject to the terms and conditions of this BeOpen Python License
|
||||||
|
Agreement, BeOpen hereby grants Licensee a non-exclusive,
|
||||||
|
royalty-free, world-wide license to reproduce, analyze, test, perform
|
||||||
|
and/or display publicly, prepare derivative works, distribute, and
|
||||||
|
otherwise use the Software alone or in any derivative version,
|
||||||
|
provided, however, that the BeOpen Python License is retained in the
|
||||||
|
Software, alone or in any derivative version prepared by Licensee.
|
||||||
|
|
||||||
|
3. BeOpen is making the Software available to Licensee on an "AS IS"
|
||||||
|
basis. BEOPEN MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR
|
||||||
|
IMPLIED. BY WAY OF EXAMPLE, BUT NOT LIMITATION, BEOPEN MAKES NO AND
|
||||||
|
DISCLAIMS ANY REPRESENTATION OR WARRANTY OF MERCHANTABILITY OR FITNESS
|
||||||
|
FOR ANY PARTICULAR PURPOSE OR THAT THE USE OF THE SOFTWARE WILL NOT
|
||||||
|
INFRINGE ANY THIRD PARTY RIGHTS.
|
||||||
|
|
||||||
|
4. BEOPEN SHALL NOT BE LIABLE TO LICENSEE OR ANY OTHER USERS OF THE
|
||||||
|
SOFTWARE FOR ANY INCIDENTAL, SPECIAL, OR CONSEQUENTIAL DAMAGES OR LOSS
|
||||||
|
AS A RESULT OF USING, MODIFYING OR DISTRIBUTING THE SOFTWARE, OR ANY
|
||||||
|
DERIVATIVE THEREOF, EVEN IF ADVISED OF THE POSSIBILITY THEREOF.
|
||||||
|
|
||||||
|
5. This License Agreement will automatically terminate upon a material
|
||||||
|
breach of its terms and conditions.
|
||||||
|
|
||||||
|
6. This License Agreement shall be governed by and interpreted in all
|
||||||
|
respects by the law of the State of California, excluding conflict of
|
||||||
|
law provisions. Nothing in this License Agreement shall be deemed to
|
||||||
|
create any relationship of agency, partnership, or joint venture
|
||||||
|
between BeOpen and Licensee. This License Agreement does not grant
|
||||||
|
permission to use BeOpen trademarks or trade names in a trademark
|
||||||
|
sense to endorse or promote products or services of Licensee, or any
|
||||||
|
third party. As an exception, the "BeOpen Python" logos available at
|
||||||
|
http://www.pythonlabs.com/logos.html may be used according to the
|
||||||
|
permissions granted on that web page.
|
||||||
|
|
||||||
|
7. By copying, installing or otherwise using the software, Licensee
|
||||||
|
agrees to be bound by the terms and conditions of this License
|
||||||
|
Agreement.
|
||||||
|
|
||||||
|
|
||||||
|
CNRI LICENSE AGREEMENT FOR PYTHON 1.6.1
|
||||||
|
---------------------------------------
|
||||||
|
|
||||||
|
1. This LICENSE AGREEMENT is between the Corporation for National
|
||||||
|
Research Initiatives, having an office at 1895 Preston White Drive,
|
||||||
|
Reston, VA 20191 ("CNRI"), and the Individual or Organization
|
||||||
|
("Licensee") accessing and otherwise using Python 1.6.1 software in
|
||||||
|
source or binary form and its associated documentation.
|
||||||
|
|
||||||
|
2. Subject to the terms and conditions of this License Agreement, CNRI
|
||||||
|
hereby grants Licensee a nonexclusive, royalty-free, world-wide
|
||||||
|
license to reproduce, analyze, test, perform and/or display publicly,
|
||||||
|
prepare derivative works, distribute, and otherwise use Python 1.6.1
|
||||||
|
alone or in any derivative version, provided, however, that CNRI's
|
||||||
|
License Agreement and CNRI's notice of copyright, i.e., "Copyright (c)
|
||||||
|
1995-2001 Corporation for National Research Initiatives; All Rights
|
||||||
|
Reserved" are retained in Python 1.6.1 alone or in any derivative
|
||||||
|
version prepared by Licensee. Alternately, in lieu of CNRI's License
|
||||||
|
Agreement, Licensee may substitute the following text (omitting the
|
||||||
|
quotes): "Python 1.6.1 is made available subject to the terms and
|
||||||
|
conditions in CNRI's License Agreement. This Agreement together with
|
||||||
|
Python 1.6.1 may be located on the Internet using the following
|
||||||
|
unique, persistent identifier (known as a handle): 1895.22/1013. This
|
||||||
|
Agreement may also be obtained from a proxy server on the Internet
|
||||||
|
using the following URL: http://hdl.handle.net/1895.22/1013".
|
||||||
|
|
||||||
|
3. In the event Licensee prepares a derivative work that is based on
|
||||||
|
or incorporates Python 1.6.1 or any part thereof, and wants to make
|
||||||
|
the derivative work available to others as provided herein, then
|
||||||
|
Licensee hereby agrees to include in any such work a brief summary of
|
||||||
|
the changes made to Python 1.6.1.
|
||||||
|
|
||||||
|
4. CNRI is making Python 1.6.1 available to Licensee on an "AS IS"
|
||||||
|
basis. CNRI MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR
|
||||||
|
IMPLIED. BY WAY OF EXAMPLE, BUT NOT LIMITATION, CNRI MAKES NO AND
|
||||||
|
DISCLAIMS ANY REPRESENTATION OR WARRANTY OF MERCHANTABILITY OR FITNESS
|
||||||
|
FOR ANY PARTICULAR PURPOSE OR THAT THE USE OF PYTHON 1.6.1 WILL NOT
|
||||||
|
INFRINGE ANY THIRD PARTY RIGHTS.
|
||||||
|
|
||||||
|
5. CNRI SHALL NOT BE LIABLE TO LICENSEE OR ANY OTHER USERS OF PYTHON
|
||||||
|
1.6.1 FOR ANY INCIDENTAL, SPECIAL, OR CONSEQUENTIAL DAMAGES OR LOSS AS
|
||||||
|
A RESULT OF MODIFYING, DISTRIBUTING, OR OTHERWISE USING PYTHON 1.6.1,
|
||||||
|
OR ANY DERIVATIVE THEREOF, EVEN IF ADVISED OF THE POSSIBILITY THEREOF.
|
||||||
|
|
||||||
|
6. This License Agreement will automatically terminate upon a material
|
||||||
|
breach of its terms and conditions.
|
||||||
|
|
||||||
|
7. This License Agreement shall be governed by the federal
|
||||||
|
intellectual property law of the United States, including without
|
||||||
|
limitation the federal copyright law, and, to the extent such
|
||||||
|
U.S. federal law does not apply, by the law of the Commonwealth of
|
||||||
|
Virginia, excluding Virginia's conflict of law provisions.
|
||||||
|
Notwithstanding the foregoing, with regard to derivative works based
|
||||||
|
on Python 1.6.1 that incorporate non-separable material that was
|
||||||
|
previously distributed under the GNU General Public License (GPL), the
|
||||||
|
law of the Commonwealth of Virginia shall govern this License
|
||||||
|
Agreement only as to issues arising under or with respect to
|
||||||
|
Paragraphs 4, 5, and 7 of this License Agreement. Nothing in this
|
||||||
|
License Agreement shall be deemed to create any relationship of
|
||||||
|
agency, partnership, or joint venture between CNRI and Licensee. This
|
||||||
|
License Agreement does not grant permission to use CNRI trademarks or
|
||||||
|
trade name in a trademark sense to endorse or promote products or
|
||||||
|
services of Licensee, or any third party.
|
||||||
|
|
||||||
|
8. By clicking on the "ACCEPT" button where indicated, or by copying,
|
||||||
|
installing or otherwise using Python 1.6.1, Licensee agrees to be
|
||||||
|
bound by the terms and conditions of this License Agreement.
|
||||||
|
|
||||||
|
ACCEPT
|
||||||
|
|
||||||
|
|
||||||
|
CWI LICENSE AGREEMENT FOR PYTHON 0.9.0 THROUGH 1.2
|
||||||
|
--------------------------------------------------
|
||||||
|
|
||||||
|
Copyright (c) 1991 - 1995, Stichting Mathematisch Centrum Amsterdam,
|
||||||
|
The Netherlands. All rights reserved.
|
||||||
|
|
||||||
|
Permission to use, copy, modify, and distribute this software and its
|
||||||
|
documentation for any purpose and without fee is hereby granted,
|
||||||
|
provided that the above copyright notice appear in all copies and that
|
||||||
|
both that copyright notice and this permission notice appear in
|
||||||
|
supporting documentation, and that the name of Stichting Mathematisch
|
||||||
|
Centrum or CWI not be used in advertising or publicity pertaining to
|
||||||
|
distribution of the software without specific, written prior
|
||||||
|
permission.
|
||||||
|
|
||||||
|
STICHTING MATHEMATISCH CENTRUM DISCLAIMS ALL WARRANTIES WITH REGARD TO
|
||||||
|
THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||||
|
FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH CENTRUM BE LIABLE
|
||||||
|
FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||||
|
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||||
|
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
|
||||||
|
OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
|
|
@ -82,8 +82,10 @@ If exporting an image, specify the pixel width and height
|
||||||
If exporting an image, specify whether to use orthographic or perspective
|
If exporting an image, specify whether to use orthographic or perspective
|
||||||
projection
|
projection
|
||||||
.TP
|
.TP
|
||||||
.B \-\-colorscheme=[Cornfield|Sunset|Metallic|Starnight|BeforeDawn|Nature|DeepOcean]
|
.B \-\-colorscheme=\fIscheme
|
||||||
If exporting an image, use the specified color scheme for the rendering.
|
If exporting an image, use the specified color scheme for the rendering.
|
||||||
|
\fIscheme\fP can be any of \fBCornfield\fP, \fBSunset\fP, \fBMetallic\fP,
|
||||||
|
\fBStarnight\fP, \fBBeforeDawn\fP, \fBNature\fP or \fBDeepOcean\fP.
|
||||||
.TP
|
.TP
|
||||||
.B \-v, \-\-version
|
.B \-v, \-\-version
|
||||||
Show version of program.
|
Show version of program.
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,6 @@
|
||||||
Given:
|
Given a version, e.g. 2015.03, and a patchlevel release, e.g. 2015.03-1
|
||||||
VERSION (e.g. 2015.03-1)
|
|
||||||
|
|
||||||
o Make sure we have a $VERSION branch. If not, create one
|
o Make sure we have an "openscad-$VERSION-branch" branch. If not, create one
|
||||||
|
|
||||||
o Update VERSION and VERSIONDATE in
|
o Update VERSION and VERSIONDATE in
|
||||||
openscad.pro
|
openscad.pro
|
||||||
|
|
|
||||||
|
|
@ -50,6 +50,7 @@ files.
|
||||||
$ make clean && qmake && make
|
$ make clean && qmake && make
|
||||||
|
|
||||||
Then run the script to scan the source files, and regenerate .pot & .po files.
|
Then run the script to scan the source files, and regenerate .pot & .po files.
|
||||||
|
You'll need itstool (http://itstool.org/) installed.
|
||||||
|
|
||||||
$ ./scripts/translation-update.sh
|
$ ./scripts/translation-update.sh
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -11,11 +11,13 @@ y_shift=thisFont[0][1];
|
||||||
hours=["one","two","three","four","five","six","seven","eight","nine","ten","eleven","twelve"];
|
hours=["one","two","three","four","five","six","seven","eight","nine","ten","eleven","twelve"];
|
||||||
|
|
||||||
module clock_hour_words(word_offset=20.0,word_height=2.0) {
|
module clock_hour_words(word_offset=20.0,word_height=2.0) {
|
||||||
for(i=[0:(len(hours)-1)]) assign( hourHandAngle=(i+1)*360/len(hours), theseIndicies=search(hours[i],thisFont[2],1,1) ) {
|
for(i=[0:(len(hours)-1)]) {
|
||||||
|
hourHandAngle=(i+1)*360/len(hours);
|
||||||
|
theseIndicies=search(hours[i],thisFont[2],1,1);
|
||||||
rotate(90-hourHandAngle) translate([word_offset,0])
|
rotate(90-hourHandAngle) translate([word_offset,0])
|
||||||
for( j=[0:(len(theseIndicies)-1)] ) translate([j*x_shift,-y_shift/2]) {
|
for( j=[0:(len(theseIndicies)-1)] ) translate([j*x_shift,-y_shift/2]) {
|
||||||
linear_extrude(height=word_height) polygon(points=thisFont[2][theseIndicies[j]][6][0],paths=thisFont[2][theseIndicies[j]][6][1]);
|
linear_extrude(height=word_height) polygon(points=thisFont[2][theseIndicies[j]][6][0],paths=thisFont[2][theseIndicies[j]][6][1]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
4
glew.pri
4
glew.pri
|
|
@ -10,7 +10,9 @@ glew {
|
||||||
|
|
||||||
unix:LIBS += -lGLEW
|
unix:LIBS += -lGLEW
|
||||||
CONFIG(mingw-cross-env): {
|
CONFIG(mingw-cross-env): {
|
||||||
DEFINES += GLEW_STATIC
|
!CONFIG(mingw-cross-env-shared) {
|
||||||
|
DEFINES += GLEW_STATIC
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
win32:LIBS += -lglew32
|
win32:LIBS += -lglew32
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -40,7 +40,7 @@ isEmpty(GLIB2_LIBPATH) {
|
||||||
GLIB2_LIBS = -L$$GLIB2_LIBPATH -lglib-2.0
|
GLIB2_LIBS = -L$$GLIB2_LIBPATH -lglib-2.0
|
||||||
}
|
}
|
||||||
|
|
||||||
CONFIG(mingw-cross-env) {
|
CONFIG(mingw-cross-env)|CONFIG(mingw-cross-env-shared) {
|
||||||
#message("mingw")
|
#message("mingw")
|
||||||
isEmpty(GLIB2_INCLUDEPATH) {
|
isEmpty(GLIB2_INCLUDEPATH) {
|
||||||
MXE_TARGET_DIR=$$(MXETARGETDIR)
|
MXE_TARGET_DIR=$$(MXETARGETDIR)
|
||||||
|
|
|
||||||
BIN
icons/flattr.png
BIN
icons/flattr.png
Binary file not shown.
|
Before Width: | Height: | Size: 1.6 KiB |
|
|
@ -6,3 +6,4 @@ Icon=openscad
|
||||||
Exec=openscad %f
|
Exec=openscad %f
|
||||||
MimeType=application/x-openscad;
|
MimeType=application/x-openscad;
|
||||||
Categories=Graphics;3DGraphics;Engineering;
|
Categories=Graphics;3DGraphics;Engineering;
|
||||||
|
Keywords=3d;solid;geometry;csg;model;stl;
|
||||||
|
|
|
||||||
Binary file not shown.
|
Before Width: | Height: | Size: 570 B After Width: | Height: | Size: 979 B |
Binary file not shown.
|
Before Width: | Height: | Size: 518 B After Width: | Height: | Size: 991 B |
|
|
@ -936,7 +936,7 @@ msgid "PolySet Cache size"
|
||||||
msgstr "Velikost PolySet cache"
|
msgstr "Velikost PolySet cache"
|
||||||
|
|
||||||
#: objects/ui_Preferences.h:1158
|
#: objects/ui_Preferences.h:1158
|
||||||
msgid "Allow to open multiple documents"
|
msgid "Allow opening multiple documents"
|
||||||
msgstr "Povolit současné otevření více dokumentů"
|
msgstr "Povolit současné otevření více dokumentů"
|
||||||
|
|
||||||
#: objects/ui_Preferences.h:1159
|
#: objects/ui_Preferences.h:1159
|
||||||
|
|
@ -1086,7 +1086,7 @@ msgstr[2] "Kompilace vyvolala %1 varování."
|
||||||
|
|
||||||
#: src/mainwin.cc:990
|
#: src/mainwin.cc:990
|
||||||
msgid " For details see <a href=\"#console\">console window</a>."
|
msgid " For details see <a href=\"#console\">console window</a>."
|
||||||
msgstr "Pro podrobnosti nahlédněte do <a href=\"#console\">konzole</a>."
|
msgstr " Pro podrobnosti nahlédněte do <a href=\"#console\">konzole</a>."
|
||||||
|
|
||||||
#: src/mainwin.cc:1355
|
#: src/mainwin.cc:1355
|
||||||
msgid "Save File"
|
msgid "Save File"
|
||||||
|
|
|
||||||
|
|
@ -956,7 +956,7 @@ msgid "PolySet Cache size"
|
||||||
msgstr "PolySet Cache Größe"
|
msgstr "PolySet Cache Größe"
|
||||||
|
|
||||||
#: objects/ui_Preferences.h:1158
|
#: objects/ui_Preferences.h:1158
|
||||||
msgid "Allow to open multiple documents"
|
msgid "Allow opening multiple documents"
|
||||||
msgstr "Öffnen von mehreren Dokumenten erlauben"
|
msgstr "Öffnen von mehreren Dokumenten erlauben"
|
||||||
|
|
||||||
#: objects/ui_Preferences.h:1159
|
#: objects/ui_Preferences.h:1159
|
||||||
|
|
|
||||||
|
|
@ -993,7 +993,7 @@ msgid "PolySet Cache size"
|
||||||
msgstr "Tamaño de cache de PolySet"
|
msgstr "Tamaño de cache de PolySet"
|
||||||
|
|
||||||
#: objects/ui_Preferences.h:1159
|
#: objects/ui_Preferences.h:1159
|
||||||
msgid "Allow to open multiple documents"
|
msgid "Allow opening multiple documents"
|
||||||
msgstr "Permitir a abrir varios documentos"
|
msgstr "Permitir a abrir varios documentos"
|
||||||
|
|
||||||
#: objects/ui_Preferences.h:1160
|
#: objects/ui_Preferences.h:1160
|
||||||
|
|
|
||||||
|
|
@ -956,7 +956,7 @@ msgid "PolySet Cache size"
|
||||||
msgstr "Taille du Cache PolySet"
|
msgstr "Taille du Cache PolySet"
|
||||||
|
|
||||||
#: objects/ui_Preferences.h:1158
|
#: objects/ui_Preferences.h:1158
|
||||||
msgid "Allow to open multiple documents"
|
msgid "Allow opening multiple documents"
|
||||||
msgstr "Autoriser l'ouverture de plusieurs documents"
|
msgstr "Autoriser l'ouverture de plusieurs documents"
|
||||||
|
|
||||||
#: objects/ui_Preferences.h:1159
|
#: objects/ui_Preferences.h:1159
|
||||||
|
|
|
||||||
|
|
@ -926,7 +926,7 @@ msgid "PolySet Cache size"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: objects/ui_Preferences.h:1158
|
#: objects/ui_Preferences.h:1158
|
||||||
msgid "Allow to open multiple documents"
|
msgid "Allow opening multiple documents"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: objects/ui_Preferences.h:1159
|
#: objects/ui_Preferences.h:1159
|
||||||
|
|
|
||||||
|
|
@ -954,7 +954,7 @@ msgid "PolySet Cache size"
|
||||||
msgstr "Размер кэша PolySet"
|
msgstr "Размер кэша PolySet"
|
||||||
|
|
||||||
#: objects/ui_Preferences.h:1158
|
#: objects/ui_Preferences.h:1158
|
||||||
msgid "Allow to open multiple documents"
|
msgid "Allow opening multiple documents"
|
||||||
msgstr "Разрешить открытие нескольких документов"
|
msgstr "Разрешить открытие нескольких документов"
|
||||||
|
|
||||||
#: objects/ui_Preferences.h:1159
|
#: objects/ui_Preferences.h:1159
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,6 @@
|
||||||
# cross compilation unix->win32
|
# cross compilation unix->win32
|
||||||
|
# To use static linking, pass CONFIG+=mingw-cross-env to qmake
|
||||||
|
# To use shared linking, pass CONFIG+=mingw-cross-env-shared to qmake
|
||||||
CONFIG(mingw-cross-env) {
|
CONFIG(mingw-cross-env) {
|
||||||
LIBS += mingw-cross-env/lib/libglew32s.a
|
LIBS += mingw-cross-env/lib/libglew32s.a
|
||||||
LIBS += mingw-cross-env/lib/libglut.a
|
LIBS += mingw-cross-env/lib/libglut.a
|
||||||
|
|
@ -19,6 +21,17 @@ CONFIG(mingw-cross-env) {
|
||||||
LIBS += mingw-cross-env/lib/libexpat.a
|
LIBS += mingw-cross-env/lib/libexpat.a
|
||||||
LIBS += mingw-cross-env/lib/libintl.a
|
LIBS += mingw-cross-env/lib/libintl.a
|
||||||
LIBS += mingw-cross-env/lib/libiconv.a
|
LIBS += mingw-cross-env/lib/libiconv.a
|
||||||
|
}
|
||||||
|
|
||||||
|
CONFIG(mingw-cross-env-shared) {
|
||||||
|
# on MXE, the shared library .dll files are under 'bin' not 'lib'.
|
||||||
|
QMAKE_LFLAGS += -L./mingw-cross-env/bin
|
||||||
|
LIBS += -lglew32 -lglut -lopengl32 -lGLEW -lglu32
|
||||||
|
LIBS += -lopencsg -lmpfr -lgmp -lCGAL
|
||||||
|
LIBS += -lfontconfig -lfreetype -lharfbuzz -lbz2 -lexpat -lintl -liconv
|
||||||
|
}
|
||||||
|
|
||||||
|
CONFIG(mingw-cross-env)|CONFIG(mingw-cross-env-shared) {
|
||||||
QMAKE_CXXFLAGS += -fpermissive
|
QMAKE_CXXFLAGS += -fpermissive
|
||||||
WINSTACKSIZE = 8388608 # 8MB # github issue 116
|
WINSTACKSIZE = 8388608 # 8MB # github issue 116
|
||||||
QMAKE_CXXFLAGS += -Wl,--stack,$$WINSTACKSIZE
|
QMAKE_CXXFLAGS += -Wl,--stack,$$WINSTACKSIZE
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,5 @@
|
||||||
opencsg {
|
opencsg {
|
||||||
DEFINES += ENABLE_OPENCSG
|
DEFINES += ENABLE_OPENCSG
|
||||||
CONFIG += glew
|
|
||||||
|
|
||||||
# Optionally specify location of OpenCSG using the
|
# Optionally specify location of OpenCSG using the
|
||||||
# OPENCSGDIR env. variable
|
# OPENCSGDIR env. variable
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,9 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<application>
|
<component type="desktop">
|
||||||
<id type="desktop">openscad.desktop</id>
|
<id>openscad.desktop</id>
|
||||||
<licence>CC0</licence>
|
<metadata_license>CC0-1.0</metadata_license>
|
||||||
|
<project_license>GPL-2.0+ and CC0-1.0</project_license>
|
||||||
|
<name>OpenSCAD</name>
|
||||||
<summary>The Programmers Solid 3D CAD Modeller</summary>
|
<summary>The Programmers Solid 3D CAD Modeller</summary>
|
||||||
<description>
|
<description>
|
||||||
<p>OpenSCAD is a software for creating solid 3D CAD models. Unlike most free software for creating 3D models (such as Blender) it does not focus on the artistic aspects of 3D modelling but instead on the CAD aspects. Thus it might be the application you are looking for when you are planning to create 3D models of machine parts but pretty sure is not what you are looking for when you are more interested in creating computer-animated movies.</p>
|
<p>OpenSCAD is a software for creating solid 3D CAD models. Unlike most free software for creating 3D models (such as Blender) it does not focus on the artistic aspects of 3D modelling but instead on the CAD aspects. Thus it might be the application you are looking for when you are planning to create 3D models of machine parts but pretty sure is not what you are looking for when you are more interested in creating computer-animated movies.</p>
|
||||||
|
|
@ -9,8 +11,12 @@
|
||||||
<p>OpenSCAD provides two main modelling techniques: First there is constructive solid geometry (aka CSG) and second there is extrusion of 2D outlines. As data exchange format format for this 2D outlines Autocad DXF files are used. In addition to 2D paths for extrusion it is also possible to read design parameters from DXF files. Besides DXF files OpenSCAD can read and create 3D models in the STL and OFF file formats.</p>
|
<p>OpenSCAD provides two main modelling techniques: First there is constructive solid geometry (aka CSG) and second there is extrusion of 2D outlines. As data exchange format format for this 2D outlines Autocad DXF files are used. In addition to 2D paths for extrusion it is also possible to read design parameters from DXF files. Besides DXF files OpenSCAD can read and create 3D models in the STL and OFF file formats.</p>
|
||||||
</description>
|
</description>
|
||||||
<screenshots>
|
<screenshots>
|
||||||
<screenshot type="default" width="800" height="437">http://www.openscad.org/images/appdata-screenshot-1.png</screenshot>
|
<screenshot type="default">
|
||||||
<screenshot width="800" height="465">http://www.openscad.org/images/appdata-screenshot-2.png</screenshot>
|
<image>http://www.openscad.org/images/appdata-screenshot-1.png</image>
|
||||||
|
</screenshot>
|
||||||
|
<screenshot>
|
||||||
|
<image>http://www.openscad.org/images/appdata-screenshot-2.png</image>
|
||||||
|
</screenshot>
|
||||||
</screenshots>
|
</screenshots>
|
||||||
<url type="homepage">http://www.openscad.org/</url>
|
<url type="homepage">http://www.openscad.org/</url>
|
||||||
</application>
|
</component>
|
||||||
36
openscad.pro
36
openscad.pro
|
|
@ -100,26 +100,9 @@ macx {
|
||||||
APP_RESOURCES.files = OpenSCAD.sdef dsa_pub.pem icons/SCAD.icns
|
APP_RESOURCES.files = OpenSCAD.sdef dsa_pub.pem icons/SCAD.icns
|
||||||
QMAKE_BUNDLE_DATA += APP_RESOURCES
|
QMAKE_BUNDLE_DATA += APP_RESOURCES
|
||||||
LIBS += -framework Cocoa -framework ApplicationServices
|
LIBS += -framework Cocoa -framework ApplicationServices
|
||||||
|
|
||||||
# Mac needs special care to link against the correct C++ library
|
|
||||||
# We attempt to auto-detect it by inspecting Boost
|
|
||||||
dirs = $${BOOSTDIR} $${QMAKE_LIBDIR}
|
|
||||||
for(dir, dirs) {
|
|
||||||
system(grep -q __112basic_string $${dir}/libboost_thread* >& /dev/null) {
|
|
||||||
message("Detected libc++-linked boost in $${dir}")
|
|
||||||
CONFIG += libc++
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
libc++ {
|
|
||||||
QMAKE_CXXFLAGS += -stdlib=libc++
|
|
||||||
QMAKE_LFLAGS += -stdlib=libc++
|
|
||||||
QMAKE_OBJECTIVE_CFLAGS += -stdlib=libc++
|
|
||||||
# libc++ on requires Mac OS X 10.7+
|
|
||||||
QMAKE_MACOSX_DEPLOYMENT_TARGET = 10.7
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
win* {
|
win* {
|
||||||
RC_FILE = openscad_win32.rc
|
RC_FILE = openscad_win32.rc
|
||||||
QMAKE_CXXFLAGS += -DNOGDI
|
QMAKE_CXXFLAGS += -DNOGDI
|
||||||
|
|
@ -147,7 +130,6 @@ netbsd* {
|
||||||
QMAKE_LFLAGS += -L/usr/X11R7/lib
|
QMAKE_LFLAGS += -L/usr/X11R7/lib
|
||||||
QMAKE_LFLAGS += -Wl,-R/usr/X11R7/lib
|
QMAKE_LFLAGS += -Wl,-R/usr/X11R7/lib
|
||||||
QMAKE_LFLAGS += -Wl,-R/usr/pkg/lib
|
QMAKE_LFLAGS += -Wl,-R/usr/pkg/lib
|
||||||
!clang: { QMAKE_CXXFLAGS += -std=c++0x }
|
|
||||||
# FIXME: Can the lines below be removed in favour of the OPENSCAD_LIBDIR handling above?
|
# FIXME: Can the lines below be removed in favour of the OPENSCAD_LIBDIR handling above?
|
||||||
!isEmpty(OPENSCAD_LIBDIR) {
|
!isEmpty(OPENSCAD_LIBDIR) {
|
||||||
QMAKE_CFLAGS = -I$$OPENSCAD_LIBDIR/include $$QMAKE_CFLAGS
|
QMAKE_CFLAGS = -I$$OPENSCAD_LIBDIR/include $$QMAKE_CFLAGS
|
||||||
|
|
@ -181,7 +163,6 @@ netbsd* {
|
||||||
QMAKE_CXXFLAGS_WARN_ON += -Wno-unused-parameter
|
QMAKE_CXXFLAGS_WARN_ON += -Wno-unused-parameter
|
||||||
QMAKE_CXXFLAGS_WARN_ON += -Wno-unused-variable
|
QMAKE_CXXFLAGS_WARN_ON += -Wno-unused-variable
|
||||||
QMAKE_CXXFLAGS_WARN_ON += -Wno-unused-function
|
QMAKE_CXXFLAGS_WARN_ON += -Wno-unused-function
|
||||||
QMAKE_CXXFLAGS_WARN_ON += -Wno-c++11-extensions
|
|
||||||
# gettext
|
# gettext
|
||||||
QMAKE_CXXFLAGS_WARN_ON += -Wno-format-security
|
QMAKE_CXXFLAGS_WARN_ON += -Wno-format-security
|
||||||
# might want to actually turn this on once in a while
|
# might want to actually turn this on once in a while
|
||||||
|
|
@ -195,8 +176,10 @@ CONFIG(skip-version-check) {
|
||||||
|
|
||||||
# Application configuration
|
# Application configuration
|
||||||
macx:CONFIG += mdi
|
macx:CONFIG += mdi
|
||||||
|
#CONFIG += c++11
|
||||||
CONFIG += cgal
|
CONFIG += cgal
|
||||||
CONFIG += opencsg
|
CONFIG += opencsg
|
||||||
|
CONFIG += glew
|
||||||
CONFIG += boost
|
CONFIG += boost
|
||||||
CONFIG += eigen
|
CONFIG += eigen
|
||||||
CONFIG += glib-2.0
|
CONFIG += glib-2.0
|
||||||
|
|
@ -206,13 +189,19 @@ CONFIG += fontconfig
|
||||||
CONFIG += gettext
|
CONFIG += gettext
|
||||||
|
|
||||||
#Uncomment the following line to enable the QScintilla editor
|
#Uncomment the following line to enable the QScintilla editor
|
||||||
CONFIG += scintilla
|
!nogui {
|
||||||
|
CONFIG += scintilla
|
||||||
|
}
|
||||||
|
|
||||||
# Make experimental features available
|
# Make experimental features available
|
||||||
experimental {
|
experimental {
|
||||||
DEFINES += ENABLE_EXPERIMENTAL
|
DEFINES += ENABLE_EXPERIMENTAL
|
||||||
}
|
}
|
||||||
|
|
||||||
|
nogui {
|
||||||
|
DEFINES += OPENSCAD_NOGUI
|
||||||
|
}
|
||||||
|
|
||||||
mdi {
|
mdi {
|
||||||
DEFINES += ENABLE_MDI
|
DEFINES += ENABLE_MDI
|
||||||
}
|
}
|
||||||
|
|
@ -220,7 +209,7 @@ mdi {
|
||||||
include(common.pri)
|
include(common.pri)
|
||||||
|
|
||||||
# mingw has to come after other items so OBJECT_DIRS will work properly
|
# mingw has to come after other items so OBJECT_DIRS will work properly
|
||||||
CONFIG(mingw-cross-env) {
|
CONFIG(mingw-cross-env)|CONFIG(mingw-cross-env-shared) {
|
||||||
include(mingw-cross-env.pri)
|
include(mingw-cross-env.pri)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -374,6 +363,7 @@ SOURCES += src/version_check.cc \
|
||||||
src/polyset-utils.cc \
|
src/polyset-utils.cc \
|
||||||
src/GeometryUtils.cc \
|
src/GeometryUtils.cc \
|
||||||
src/polyset.cc \
|
src/polyset.cc \
|
||||||
|
src/polyset-gl.cc \
|
||||||
src/csgops.cc \
|
src/csgops.cc \
|
||||||
src/transform.cc \
|
src/transform.cc \
|
||||||
src/color.cc \
|
src/color.cc \
|
||||||
|
|
@ -499,6 +489,8 @@ HEADERS += src/cgal.h \
|
||||||
src/Polygon2d-CGAL.h
|
src/Polygon2d-CGAL.h
|
||||||
|
|
||||||
SOURCES += src/cgalutils.cc \
|
SOURCES += src/cgalutils.cc \
|
||||||
|
src/cgalutils-applyops.cc \
|
||||||
|
src/cgalutils-project.cc \
|
||||||
src/cgalutils-tess.cc \
|
src/cgalutils-tess.cc \
|
||||||
src/cgalutils-polyhedron.cc \
|
src/cgalutils-polyhedron.cc \
|
||||||
src/CGALCache.cc \
|
src/CGALCache.cc \
|
||||||
|
|
|
||||||
|
|
@ -29,7 +29,6 @@
|
||||||
<file>icons/prefs3DView.png</file>
|
<file>icons/prefs3DView.png</file>
|
||||||
<file>icons/prefsEditor.png</file>
|
<file>icons/prefsEditor.png</file>
|
||||||
<file>icons/prefsUpdate.png</file>
|
<file>icons/prefsUpdate.png</file>
|
||||||
<file>icons/flattr.png</file>
|
|
||||||
<file>src/AboutDialog.html</file>
|
<file>src/AboutDialog.html</file>
|
||||||
<file>images/export.png</file>
|
<file>images/export.png</file>
|
||||||
<file>images/axes.png</file>
|
<file>images/axes.png</file>
|
||||||
|
|
|
||||||
23
patches/qt5/QTBUG-46846.patch
Normal file
23
patches/qt5/QTBUG-46846.patch
Normal file
|
|
@ -0,0 +1,23 @@
|
||||||
|
diff --git a/src/widgets/widgets/qlabel.cpp b/src/widgets/widgets/qlabel.cpp
|
||||||
|
index 83e94c4..80957e6 100644
|
||||||
|
--- a/src/widgets/widgets/qlabel.cpp
|
||||||
|
+++ b/src/widgets/widgets/qlabel.cpp
|
||||||
|
@@ -1076,14 +1076,16 @@ void QLabel::paintEvent(QPaintEvent *)
|
||||||
|
if (d->pixmap && !d->pixmap->isNull()) {
|
||||||
|
QPixmap pix;
|
||||||
|
if (d->scaledcontents) {
|
||||||
|
- if (!d->scaledpixmap || d->scaledpixmap->size() != cr.size()) {
|
||||||
|
+ QSize scaledSize = cr.size() * devicePixelRatio();
|
||||||
|
+ if (!d->scaledpixmap || d->scaledpixmap->size() != scaledSize) {
|
||||||
|
if (!d->cachedimage)
|
||||||
|
d->cachedimage = new QImage(d->pixmap->toImage());
|
||||||
|
delete d->scaledpixmap;
|
||||||
|
QImage scaledImage =
|
||||||
|
- d->cachedimage->scaled(cr.size() * devicePixelRatio(),
|
||||||
|
+ d->cachedimage->scaled(scaledSize,
|
||||||
|
Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
|
||||||
|
d->scaledpixmap = new QPixmap(QPixmap::fromImage(scaledImage));
|
||||||
|
+ d->scaledpixmap->setDevicePixelRatio(devicePixelRatio());
|
||||||
|
}
|
||||||
|
pix = *d->scaledpixmap;
|
||||||
|
} else
|
||||||
|
|
@ -10,6 +10,16 @@ INCLUDEPATH += $$[QT_INSTALL_HEADERS]
|
||||||
|
|
||||||
LIBS += -L$$[QT_INSTALL_LIBS]
|
LIBS += -L$$[QT_INSTALL_LIBS]
|
||||||
|
|
||||||
|
QT5LIB=qt5scintilla2
|
||||||
|
|
||||||
|
unix:linux* {
|
||||||
|
FEDORA32LIBS=/usr/lib/libqscintilla2-qt5.so
|
||||||
|
FEDORA64LIBS=/usr/lib64/libqscintilla2-qt5.so
|
||||||
|
exists($$FEDORA32LIBS) | exists($$FEDORA64LIBS) {
|
||||||
|
QT5LIB=qscintilla2-qt5
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
CONFIG(debug, debug|release) {
|
CONFIG(debug, debug|release) {
|
||||||
mac: {
|
mac: {
|
||||||
#LIBS += -lqscintilla2_debug
|
#LIBS += -lqscintilla2_debug
|
||||||
|
|
@ -19,7 +29,8 @@ CONFIG(debug, debug|release) {
|
||||||
LIBS += -lqscintilla2d
|
LIBS += -lqscintilla2d
|
||||||
} else {
|
} else {
|
||||||
greaterThan(QT_MAJOR_VERSION, 4) {
|
greaterThan(QT_MAJOR_VERSION, 4) {
|
||||||
LIBS += -lqt5scintilla2
|
message("Using $$QT5LIB as library name")
|
||||||
|
LIBS += -l$$QT5LIB
|
||||||
} else {
|
} else {
|
||||||
LIBS += -lqscintilla2
|
LIBS += -lqscintilla2
|
||||||
}
|
}
|
||||||
|
|
@ -33,7 +44,8 @@ CONFIG(debug, debug|release) {
|
||||||
LIBS += -lqscintilla2
|
LIBS += -lqscintilla2
|
||||||
} else {
|
} else {
|
||||||
greaterThan(QT_MAJOR_VERSION, 4) {
|
greaterThan(QT_MAJOR_VERSION, 4) {
|
||||||
LIBS += -lqt5scintilla2
|
message("Using $$QT5LIB as library name")
|
||||||
|
LIBS += -l$$QT5LIB
|
||||||
} else {
|
} else {
|
||||||
LIBS += -lqscintilla2
|
LIBS += -lqscintilla2
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -120,6 +120,17 @@ check_nsis()
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
|
check_zip()
|
||||||
|
if [ ! "`command -v zip`" ]; then
|
||||||
|
echo the zip command was not found. please install zip
|
||||||
|
echo on debian, sudo apt-get install zip
|
||||||
|
exit 1
|
||||||
|
else
|
||||||
|
echo zip found.
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
get_openscad_source_code()
|
get_openscad_source_code()
|
||||||
{
|
{
|
||||||
if [ -d openscad ]; then
|
if [ -d openscad ]; then
|
||||||
|
|
@ -251,7 +262,7 @@ upload_win32()
|
||||||
SUMMARY1="Windows x86-32 Snapshot Installer"
|
SUMMARY1="Windows x86-32 Snapshot Installer"
|
||||||
SUMMARY2="Windows x86-32 Snapshot Zipfile"
|
SUMMARY2="Windows x86-32 Snapshot Zipfile"
|
||||||
SUMMARY3="Windows x86-32 Snapshot Tests"
|
SUMMARY3="Windows x86-32 Snapshot Tests"
|
||||||
BASEDIR=./mingw32/
|
BASEDIR=./mingw32.static/
|
||||||
WIN32_PACKAGEFILE1=OpenSCAD-$DATECODE-x86-32-Installer.exe
|
WIN32_PACKAGEFILE1=OpenSCAD-$DATECODE-x86-32-Installer.exe
|
||||||
WIN32_PACKAGEFILE2=OpenSCAD-$DATECODE-x86-32.zip
|
WIN32_PACKAGEFILE2=OpenSCAD-$DATECODE-x86-32.zip
|
||||||
WIN32_PACKAGEFILE3=OpenSCAD-Tests-$DATECODE-x86-32.zip
|
WIN32_PACKAGEFILE3=OpenSCAD-Tests-$DATECODE-x86-32.zip
|
||||||
|
|
@ -277,7 +288,7 @@ upload_win64()
|
||||||
SUMMARY1="Windows x86-64 Snapshot Zipfile"
|
SUMMARY1="Windows x86-64 Snapshot Zipfile"
|
||||||
SUMMARY2="Windows x86-64 Snapshot Installer"
|
SUMMARY2="Windows x86-64 Snapshot Installer"
|
||||||
SUMMARY3="Windows x86-64 Snapshot Tests"
|
SUMMARY3="Windows x86-64 Snapshot Tests"
|
||||||
BASEDIR=./mingw64/
|
BASEDIR=./mingw64.static/
|
||||||
WIN64_PACKAGEFILE1=OpenSCAD-$DATECODE-x86-64-Installer.exe
|
WIN64_PACKAGEFILE1=OpenSCAD-$DATECODE-x86-64-Installer.exe
|
||||||
WIN64_PACKAGEFILE2=OpenSCAD-$DATECODE-x86-64.zip
|
WIN64_PACKAGEFILE2=OpenSCAD-$DATECODE-x86-64.zip
|
||||||
WIN64_PACKAGEFILE3=OpenSCAD-Tests-$DATECODE-x86-64.zip
|
WIN64_PACKAGEFILE3=OpenSCAD-Tests-$DATECODE-x86-64.zip
|
||||||
|
|
@ -409,6 +420,7 @@ main()
|
||||||
fi
|
fi
|
||||||
check_starting_path
|
check_starting_path
|
||||||
check_nsis
|
check_nsis
|
||||||
|
check_zip
|
||||||
read_username_from_user
|
read_username_from_user
|
||||||
read_password_from_user
|
read_password_from_user
|
||||||
get_openscad_source_code
|
get_openscad_source_code
|
||||||
|
|
|
||||||
|
|
@ -18,7 +18,13 @@ File /r /x mingw-cross-env color-schemes
|
||||||
${registerExtension} "$INSTDIR\openscad.exe" ".scad" "OpenSCAD_File"
|
${registerExtension} "$INSTDIR\openscad.exe" ".scad" "OpenSCAD_File"
|
||||||
CreateShortCut $SMPROGRAMS\OpenSCAD.lnk $INSTDIR\openscad.exe
|
CreateShortCut $SMPROGRAMS\OpenSCAD.lnk $INSTDIR\openscad.exe
|
||||||
WriteUninstaller $INSTDIR\Uninstall.exe
|
WriteUninstaller $INSTDIR\Uninstall.exe
|
||||||
|
# see https://msdn.microsoft.com/en-us/library/aa372105(v=vs.85).aspx
|
||||||
WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\OpenSCAD" "DisplayName" "OpenSCAD (remove only)"
|
WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\OpenSCAD" "DisplayName" "OpenSCAD (remove only)"
|
||||||
|
WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\OpenSCAD" "DisplayVersion" "${VERSION}"
|
||||||
|
WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\OpenSCAD" "Publisher" "The OpenSCAD Developers"
|
||||||
|
WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\OpenSCAD" "URLInfoAbout" "http://www.openscad.org/"
|
||||||
|
WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\OpenSCAD" "URLUpdateInfo" "http://www.openscad.org/downloads.html"
|
||||||
|
WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\OpenSCAD" "HelpLink" "http://forum.openscad.org/"
|
||||||
WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\OpenSCAD" "UninstallString" "$INSTDIR\Uninstall.exe"
|
WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\OpenSCAD" "UninstallString" "$INSTDIR\Uninstall.exe"
|
||||||
WriteRegStr HKCR ".scad" "PerceivedType" "text"
|
WriteRegStr HKCR ".scad" "PerceivedType" "text"
|
||||||
SectionEnd
|
SectionEnd
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,8 @@
|
||||||
#
|
#
|
||||||
# This script must be run from the OpenSCAD source root directory
|
# This script must be run from the OpenSCAD source root directory
|
||||||
#
|
#
|
||||||
# Usage: macosx-build-dependencies.sh [-6lcd] [<package>]
|
# Usage: macosx-build-dependencies.sh [-16lcdf] [<package>]
|
||||||
|
# -3 Build using C++03 and libstdc++
|
||||||
# -6 Build only 64-bit binaries
|
# -6 Build only 64-bit binaries
|
||||||
# -l Force use of LLVM compiler
|
# -l Force use of LLVM compiler
|
||||||
# -c Force use of clang compiler
|
# -c Force use of clang compiler
|
||||||
|
|
@ -31,36 +32,38 @@ OPTION_CLANG=false
|
||||||
OPTION_GCC=false
|
OPTION_GCC=false
|
||||||
OPTION_DEPLOY=false
|
OPTION_DEPLOY=false
|
||||||
OPTION_FORCE=0
|
OPTION_FORCE=0
|
||||||
|
OPTION_CXX11=true
|
||||||
|
|
||||||
PACKAGES=(
|
PACKAGES=(
|
||||||
"eigen 3.2.4"
|
|
||||||
"gmp 5.1.3"
|
|
||||||
"mpfr 3.1.2"
|
|
||||||
"boost 1.57.0"
|
|
||||||
"qt5 5.4.1"
|
|
||||||
"qscintilla 2.8.4"
|
|
||||||
# NB! For eigen, also update the path in the function
|
# NB! For eigen, also update the path in the function
|
||||||
|
"eigen 3.2.6"
|
||||||
|
"gmp 5.1.3"
|
||||||
|
"mpfr 3.1.3"
|
||||||
|
"boost 1.59.0"
|
||||||
|
"qt5 5.5.1"
|
||||||
|
"qscintilla 2.9"
|
||||||
# NB! For CGAL, also update the actual download URL in the function
|
# NB! For CGAL, also update the actual download URL in the function
|
||||||
"cgal 4.5.2"
|
"cgal 4.6.3"
|
||||||
"glew 1.12.0"
|
"glew 1.13.0"
|
||||||
"gettext 0.19.4"
|
"gettext 0.19.6"
|
||||||
"libffi 3.2.1"
|
"libffi 3.2.1"
|
||||||
"glib2 2.42.1"
|
"glib2 2.46.1"
|
||||||
"opencsg 1.4.0"
|
"opencsg 1.4.0"
|
||||||
"freetype 2.5.5"
|
"freetype 2.6.1"
|
||||||
"ragel 6.9"
|
"ragel 6.9"
|
||||||
"harfbuzz 0.9.37"
|
"harfbuzz 1.0.6"
|
||||||
"libxml2 2.9.2"
|
"libxml2 2.9.2"
|
||||||
"fontconfig 2.11.1"
|
"fontconfig 2.11.1"
|
||||||
)
|
)
|
||||||
DEPLOY_PACKAGES=(
|
DEPLOY_PACKAGES=(
|
||||||
"sparkle Cocoanetics:1e7dcb1a48b96d1a8c62100b5864bd50211cbae1"
|
"sparkle 1.11.0"
|
||||||
)
|
)
|
||||||
|
|
||||||
printUsage()
|
printUsage()
|
||||||
{
|
{
|
||||||
echo "Usage: $0 [-6lcd] [<package>]"
|
echo "Usage: $0 [-36lcdf] [<package>]"
|
||||||
echo
|
echo
|
||||||
|
echo " -3 Build using C++03 and libstdc++"
|
||||||
echo " -6 Build only 64-bit binaries"
|
echo " -6 Build only 64-bit binaries"
|
||||||
echo " -l Force use of LLVM compiler"
|
echo " -l Force use of LLVM compiler"
|
||||||
echo " -c Force use of clang compiler"
|
echo " -c Force use of clang compiler"
|
||||||
|
|
@ -221,9 +224,13 @@ build_qt5()
|
||||||
fi
|
fi
|
||||||
tar xzf qt-everywhere-opensource-src-$version.tar.gz
|
tar xzf qt-everywhere-opensource-src-$version.tar.gz
|
||||||
cd qt-everywhere-opensource-src-$version
|
cd qt-everywhere-opensource-src-$version
|
||||||
./configure -prefix $DEPLOYDIR -release -opensource -confirm-license \
|
patch -d qtbase -p1 < $OPENSCADDIR/patches/qt5/QTBUG-46846.patch
|
||||||
|
if ! $USING_CXX11; then
|
||||||
|
QT_EXTRA_FLAGS="-no-c++11"
|
||||||
|
fi
|
||||||
|
CXXFLAGS="$CXXSTDFLAGS" ./configure -prefix $DEPLOYDIR $QT_EXTRA_FLAGS -release -opensource -confirm-license \
|
||||||
-nomake examples -nomake tests \
|
-nomake examples -nomake tests \
|
||||||
-no-xcb -no-c++11 -no-glib -no-harfbuzz -no-sql-db2 -no-sql-ibase -no-sql-mysql -no-sql-oci -no-sql-odbc \
|
-no-xcb -no-glib -no-harfbuzz -no-sql-db2 -no-sql-ibase -no-sql-mysql -no-sql-oci -no-sql-odbc \
|
||||||
-no-sql-psql -no-sql-sqlite2 -no-sql-tds -no-cups -no-qml-debug \
|
-no-sql-psql -no-sql-sqlite2 -no-sql-tds -no-cups -no-qml-debug \
|
||||||
-skip activeqt -skip connectivity -skip declarative -skip doc \
|
-skip activeqt -skip connectivity -skip declarative -skip doc \
|
||||||
-skip enginio -skip graphicaleffects -skip location -skip multimedia \
|
-skip enginio -skip graphicaleffects -skip location -skip multimedia \
|
||||||
|
|
@ -248,7 +255,7 @@ build_qscintilla()
|
||||||
fi
|
fi
|
||||||
tar xzf QScintilla-gpl-$version.tar.gz
|
tar xzf QScintilla-gpl-$version.tar.gz
|
||||||
cd QScintilla-gpl-$version/Qt4Qt5
|
cd QScintilla-gpl-$version/Qt4Qt5
|
||||||
qmake qscintilla.pro
|
qmake QMAKE_CXXFLAGS+="$CXXSTDFLAGS" QMAKE_LFLAGS+="$CXXSTDFLAGS" qscintilla.pro
|
||||||
make -j6 install
|
make -j6 install
|
||||||
install_name_tool -id $DEPLOYDIR/lib/libqscintilla2.dylib $DEPLOYDIR/lib/libqscintilla2.dylib
|
install_name_tool -id $DEPLOYDIR/lib/libqscintilla2.dylib $DEPLOYDIR/lib/libqscintilla2.dylib
|
||||||
}
|
}
|
||||||
|
|
@ -321,7 +328,7 @@ EOF
|
||||||
if $OPTION_32BIT; then
|
if $OPTION_32BIT; then
|
||||||
mkdir build-i386
|
mkdir build-i386
|
||||||
cd build-i386
|
cd build-i386
|
||||||
../configure --prefix=$DEPLOYDIR/i386 "CFLAGS=-mmacosx-version-min=$MAC_OSX_VERSION_MIN -arch i386" LDFLAGS="-mmacosx-version-min=$MAC_OSX_VERSION_MIN -arch i386" ABI=32 --enable-cxx
|
../configure --prefix=$DEPLOYDIR/i386 CXXFLAGS="$CXXSTDFLAGS" CFLAGS="-mmacosx-version-min=$MAC_OSX_VERSION_MIN -arch i386" LDFLAGS="$LDSTDFLAGS -mmacosx-version-min=$MAC_OSX_VERSION_MIN -arch i386" ABI=32 --enable-cxx
|
||||||
make install
|
make install
|
||||||
cd ..
|
cd ..
|
||||||
fi
|
fi
|
||||||
|
|
@ -329,7 +336,7 @@ EOF
|
||||||
# 64-bit version
|
# 64-bit version
|
||||||
mkdir build-x86_64
|
mkdir build-x86_64
|
||||||
cd build-x86_64
|
cd build-x86_64
|
||||||
../configure --prefix=$DEPLOYDIR/x86_64 "CFLAGS=-mmacosx-version-min=$MAC_OSX_VERSION_MIN -arch x86_64" LDFLAGS="-mmacosx-version-min=$MAC_OSX_VERSION_MIN -arch x86_64" ABI=64 --enable-cxx
|
../configure --prefix=$DEPLOYDIR/x86_64 CXXFLAGS="$CXXSTDFLAGS" CFLAGS="-mmacosx-version-min=$MAC_OSX_VERSION_MIN -arch x86_64" LDFLAGS="$LDSTDFLAGS -mmacosx-version-min=$MAC_OSX_VERSION_MIN -arch x86_64" ABI=64 --enable-cxx
|
||||||
make install
|
make install
|
||||||
|
|
||||||
# merge
|
# merge
|
||||||
|
|
@ -434,7 +441,7 @@ build_boost()
|
||||||
BOOST_TOOLSET="toolset=clang"
|
BOOST_TOOLSET="toolset=clang"
|
||||||
echo "using clang ;" >> tools/build/user-config.jam
|
echo "using clang ;" >> tools/build/user-config.jam
|
||||||
fi
|
fi
|
||||||
./b2 -j"$NUMCPU" -d+2 $BOOST_TOOLSET cflags="-mmacosx-version-min=$MAC_OSX_VERSION_MIN -arch x86_64 $BOOST_EXTRA_FLAGS" linkflags="-mmacosx-version-min=$MAC_OSX_VERSION_MIN -arch x86_64 $BOOST_EXTRA_FLAGS -headerpad_max_install_names" install
|
./b2 -j"$NUMCPU" -d+2 $BOOST_TOOLSET cflags="-mmacosx-version-min=$MAC_OSX_VERSION_MIN -arch x86_64 $BOOST_EXTRA_FLAGS $CXXSTDFLAGS" linkflags="-mmacosx-version-min=$MAC_OSX_VERSION_MIN -arch x86_64 $BOOST_EXTRA_FLAGS $LDSTDFLAGS -headerpad_max_install_names" install
|
||||||
install_name_tool -id $DEPLOYDIR/lib/libboost_thread.dylib $DEPLOYDIR/lib/libboost_thread.dylib
|
install_name_tool -id $DEPLOYDIR/lib/libboost_thread.dylib $DEPLOYDIR/lib/libboost_thread.dylib
|
||||||
install_name_tool -change libboost_system.dylib $DEPLOYDIR/lib/libboost_system.dylib $DEPLOYDIR/lib/libboost_thread.dylib
|
install_name_tool -change libboost_system.dylib $DEPLOYDIR/lib/libboost_system.dylib $DEPLOYDIR/lib/libboost_thread.dylib
|
||||||
install_name_tool -change libboost_chrono.dylib $DEPLOYDIR/lib/libboost_chrono.dylib $DEPLOYDIR/lib/libboost_thread.dylib
|
install_name_tool -change libboost_chrono.dylib $DEPLOYDIR/lib/libboost_chrono.dylib $DEPLOYDIR/lib/libboost_thread.dylib
|
||||||
|
|
@ -460,8 +467,9 @@ build_cgal()
|
||||||
cd $BASEDIR/src
|
cd $BASEDIR/src
|
||||||
rm -rf CGAL-$version
|
rm -rf CGAL-$version
|
||||||
if [ ! -f CGAL-$version.tar.gz ]; then
|
if [ ! -f CGAL-$version.tar.gz ]; then
|
||||||
# 4.5.2
|
# 4.6.3
|
||||||
curl -O https://gforge.inria.fr/frs/download.php/file/34512/CGAL-$version.tar.gz
|
curl -O https://gforge.inria.fr/frs/download.php/file/35138/CGAL-$version.tar.gz
|
||||||
|
# 4.5.2 curl -O https://gforge.inria.fr/frs/download.php/file/34512/CGAL-$version.tar.gz
|
||||||
# 4.5.1 curl -O https://gforge.inria.fr/frs/download.php/file/34400/CGAL-$version.tar.gz
|
# 4.5.1 curl -O https://gforge.inria.fr/frs/download.php/file/34400/CGAL-$version.tar.gz
|
||||||
# 4.5 curl -O https://gforge.inria.fr/frs/download.php/file/34149/CGAL-$version.tar.gz
|
# 4.5 curl -O https://gforge.inria.fr/frs/download.php/file/34149/CGAL-$version.tar.gz
|
||||||
# 4.4 curl -O https://gforge.inria.fr/frs/download.php/file/33525/CGAL-$version.tar.gz
|
# 4.4 curl -O https://gforge.inria.fr/frs/download.php/file/33525/CGAL-$version.tar.gz
|
||||||
|
|
@ -480,7 +488,7 @@ build_cgal()
|
||||||
if $OPTION_32BIT; then
|
if $OPTION_32BIT; then
|
||||||
CGAL_EXTRA_FLAGS=";i386"
|
CGAL_EXTRA_FLAGS=";i386"
|
||||||
fi
|
fi
|
||||||
cmake -DCMAKE_INSTALL_PREFIX=$DEPLOYDIR -DGMP_INCLUDE_DIR=$DEPLOYDIR/include -DGMP_LIBRARIES=$DEPLOYDIR/lib/libgmp.dylib -DGMPXX_LIBRARIES=$DEPLOYDIR/lib/libgmpxx.dylib -DGMPXX_INCLUDE_DIR=$DEPLOYDIR/include -DMPFR_INCLUDE_DIR=$DEPLOYDIR/include -DMPFR_LIBRARIES=$DEPLOYDIR/lib/libmpfr.dylib -DWITH_CGAL_Qt3=OFF -DWITH_CGAL_Qt4=OFF -DWITH_CGAL_ImageIO=OFF -DBUILD_SHARED_LIBS=TRUE -DCMAKE_OSX_DEPLOYMENT_TARGET="$MAC_OSX_VERSION_MIN" -DCMAKE_OSX_ARCHITECTURES="x86_64$CGAL_EXTRA_FLAGS" -DBOOST_ROOT=$DEPLOYDIR -DBoost_USE_MULTITHREADED=false
|
CXXFLAGS="$CXXSTDFLAGS" cmake -DCMAKE_INSTALL_PREFIX=$DEPLOYDIR -DGMP_INCLUDE_DIR=$DEPLOYDIR/include -DGMP_LIBRARIES=$DEPLOYDIR/lib/libgmp.dylib -DGMPXX_LIBRARIES=$DEPLOYDIR/lib/libgmpxx.dylib -DGMPXX_INCLUDE_DIR=$DEPLOYDIR/include -DMPFR_INCLUDE_DIR=$DEPLOYDIR/include -DMPFR_LIBRARIES=$DEPLOYDIR/lib/libmpfr.dylib -DWITH_CGAL_Qt3=OFF -DWITH_CGAL_Qt4=OFF -DWITH_CGAL_ImageIO=OFF -DBUILD_SHARED_LIBS=TRUE -DCMAKE_OSX_DEPLOYMENT_TARGET="$MAC_OSX_VERSION_MIN" -DCMAKE_OSX_ARCHITECTURES="x86_64$CGAL_EXTRA_FLAGS" -DBOOST_ROOT=$DEPLOYDIR -DBoost_USE_MULTITHREADED=false
|
||||||
make -j"$NUMCPU" install
|
make -j"$NUMCPU" install
|
||||||
make install
|
make install
|
||||||
install_name_tool -id $DEPLOYDIR/lib/libCGAL.dylib $DEPLOYDIR/lib/libCGAL.dylib
|
install_name_tool -id $DEPLOYDIR/lib/libCGAL.dylib $DEPLOYDIR/lib/libCGAL.dylib
|
||||||
|
|
@ -533,7 +541,7 @@ build_opencsg()
|
||||||
if $OPTION_32BIT; then
|
if $OPTION_32BIT; then
|
||||||
OPENCSG_EXTRA_FLAGS="x86"
|
OPENCSG_EXTRA_FLAGS="x86"
|
||||||
fi
|
fi
|
||||||
qmake -r QMAKE_CXXFLAGS+="-I$DEPLOYDIR/include" QMAKE_LFLAGS+="-L$DEPLOYDIR/lib" CONFIG+="x86_64 $OPENCSG_EXTRA_FLAGS" DESTDIR=$DEPLOYDIR
|
qmake -r QMAKE_CXXFLAGS+="-I$DEPLOYDIR/include $CXXSTDFLAGS" QMAKE_LFLAGS+="-L$DEPLOYDIR/lib $LDSTDFLAGS" CONFIG+="x86_64 $OPENCSG_EXTRA_FLAGS" DESTDIR=$DEPLOYDIR
|
||||||
make install
|
make install
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -567,6 +575,7 @@ build_eigen()
|
||||||
elif [ $version = "3.2.2" ]; then EIGENDIR=eigen-eigen-1306d75b4a21;
|
elif [ $version = "3.2.2" ]; then EIGENDIR=eigen-eigen-1306d75b4a21;
|
||||||
elif [ $version = "3.2.3" ]; then EIGENDIR=eigen-eigen-36fd1ba04c12;
|
elif [ $version = "3.2.3" ]; then EIGENDIR=eigen-eigen-36fd1ba04c12;
|
||||||
elif [ $version = "3.2.4" ]; then EIGENDIR=eigen-eigen-10219c95fe65;
|
elif [ $version = "3.2.4" ]; then EIGENDIR=eigen-eigen-10219c95fe65;
|
||||||
|
elif [ $version = "3.2.6" ]; then EIGENDIR=eigen-eigen-c58038c56923;
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [ $EIGENDIR = "none" ]; then
|
if [ $EIGENDIR = "none" ]; then
|
||||||
|
|
@ -587,7 +596,7 @@ build_eigen()
|
||||||
if $OPTION_32BIT; then
|
if $OPTION_32BIT; then
|
||||||
EIGEN_EXTRA_FLAGS=";i386"
|
EIGEN_EXTRA_FLAGS=";i386"
|
||||||
fi
|
fi
|
||||||
cmake -DCMAKE_INSTALL_PREFIX=$DEPLOYDIR -DEIGEN_TEST_NOQT=TRUE -DCMAKE_OSX_DEPLOYMENT_TARGET="$MAC_OSX_VERSION_MIN" -DCMAKE_OSX_ARCHITECTURES="x86_64$EIGEN_EXTRA_FLAGS" ..
|
CXXFLAGS="$CXXSTDFLAGS" cmake -DCMAKE_INSTALL_PREFIX=$DEPLOYDIR -DEIGEN_TEST_NOQT=TRUE -DCMAKE_OSX_DEPLOYMENT_TARGET="$MAC_OSX_VERSION_MIN" -DCMAKE_OSX_ARCHITECTURES="x86_64$EIGEN_EXTRA_FLAGS" ..
|
||||||
make -j"$NUMCPU" install
|
make -j"$NUMCPU" install
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -596,35 +605,51 @@ check_sparkle()
|
||||||
check_file lib/Sparkle.framework/Sparkle
|
check_file lib/Sparkle.framework/Sparkle
|
||||||
}
|
}
|
||||||
|
|
||||||
# Usage: build_sparkle <githubuser>:<commitID>
|
# Usage:
|
||||||
|
# build_sparkle <githubuser>:<commitID>
|
||||||
|
# build_sparkle <version>
|
||||||
|
|
||||||
build_sparkle()
|
build_sparkle()
|
||||||
{
|
{
|
||||||
v=$1
|
# Binary install:
|
||||||
github=${1%%:*} # Cut at first colon
|
version=$1
|
||||||
version=${1#*:} # cut until first colon
|
|
||||||
|
|
||||||
echo "Building Sparkle" $version "..."
|
|
||||||
|
|
||||||
# Let Sparkle use the default compiler
|
|
||||||
unset CC
|
|
||||||
unset CXX
|
|
||||||
|
|
||||||
cd $BASEDIR/src
|
cd $BASEDIR/src
|
||||||
rm -rf Sparkle-$version
|
rm -rf Sparkle-$version
|
||||||
if [ ! -f Sparkle-$version.zip ]; then
|
if [ ! -f Sparkle-$version.zip ]; then
|
||||||
curl -o Sparkle-$version.zip https://nodeload.github.com/$github/Sparkle/zip/$version
|
curl -LO https://github.com/sparkle-project/Sparkle/releases/download/$version/Sparkle-$version.tar.bz2
|
||||||
fi
|
fi
|
||||||
unzip -q Sparkle-$version.zip
|
mkdir Sparkle-$version
|
||||||
cd Sparkle-$version
|
cd Sparkle-$version
|
||||||
patch -p1 < $OPENSCADDIR/patches/sparkle.patch
|
tar xjf ../Sparkle-$version.tar.bz2
|
||||||
if $OPTION_32BIT; then
|
cp -Rf Sparkle.framework $DEPLOYDIR/lib/
|
||||||
SPARKLE_EXTRA_FLAGS="-arch i386"
|
|
||||||
fi
|
# Build from source:
|
||||||
xcodebuild clean
|
# v=$1
|
||||||
xcodebuild -arch x86_64 $SPARKLE_EXTRA_FLAGS
|
# github=${1%%:*} # Cut at first colon
|
||||||
rm -rf $DEPLOYDIR/lib/Sparkle.framework
|
# version=${1#*:} # cut until first colon
|
||||||
cp -Rf build/Release/Sparkle.framework $DEPLOYDIR/lib/
|
#
|
||||||
install_name_tool -id $DEPLOYDIR/lib/Sparkle.framework/Versions/A/Sparkle $DEPLOYDIR/lib/Sparkle.framework/Sparkle
|
# echo "Building Sparkle" $version "..."
|
||||||
|
#
|
||||||
|
# # Let Sparkle use the default compiler
|
||||||
|
# unset CC
|
||||||
|
# unset CXX
|
||||||
|
#
|
||||||
|
# cd $BASEDIR/src
|
||||||
|
# rm -rf Sparkle-$version
|
||||||
|
# if [ ! -f Sparkle-$version.zip ]; then
|
||||||
|
# curl -o Sparkle-$version.zip https://nodeload.github.com/$github/Sparkle/zip/$version
|
||||||
|
# fi
|
||||||
|
# unzip -q Sparkle-$version.zip
|
||||||
|
# cd Sparkle-$version
|
||||||
|
# patch -p1 < $OPENSCADDIR/patches/sparkle.patch
|
||||||
|
# if $OPTION_32BIT; then
|
||||||
|
# SPARKLE_EXTRA_FLAGS="-arch i386"
|
||||||
|
# fi
|
||||||
|
# xcodebuild clean
|
||||||
|
# xcodebuild -arch x86_64 $SPARKLE_EXTRA_FLAGS
|
||||||
|
# rm -rf $DEPLOYDIR/lib/Sparkle.framework
|
||||||
|
# cp -Rf build/Release/Sparkle.framework $DEPLOYDIR/lib/
|
||||||
|
# Install_name_tool -id $DEPLOYDIR/lib/Sparkle.framework/Versions/A/Sparkle $DEPLOYDIR/lib/Sparkle.framework/Sparkle
|
||||||
}
|
}
|
||||||
|
|
||||||
check_freetype()
|
check_freetype()
|
||||||
|
|
@ -815,7 +840,7 @@ build_harfbuzz()
|
||||||
# disable doc directories as they make problems on Mac OS Build
|
# disable doc directories as they make problems on Mac OS Build
|
||||||
sed -e "s/SUBDIRS = src util test docs/SUBDIRS = src util test/g" Makefile.am > Makefile.am.bak && mv Makefile.am.bak Makefile.am
|
sed -e "s/SUBDIRS = src util test docs/SUBDIRS = src util test/g" Makefile.am > Makefile.am.bak && mv Makefile.am.bak Makefile.am
|
||||||
sed -e "s/^docs.*$//" configure.ac > configure.ac.bak && mv configure.ac.bak configure.ac
|
sed -e "s/^docs.*$//" configure.ac > configure.ac.bak && mv configure.ac.bak configure.ac
|
||||||
PKG_CONFIG_LIBDIR="$DEPLOYDIR/lib/pkgconfig" ./autogen.sh --prefix="$DEPLOYDIR" --with-freetype=yes --with-gobject=no --with-cairo=no --with-icu=no CFLAGS=-mmacosx-version-min=$MAC_OSX_VERSION_MIN CXXFLAGS=-mmacosx-version-min=$MAC_OSX_VERSION_MIN LDFLAGS=-mmacosx-version-min=$MAC_OSX_VERSION_MIN $extra_config_flags
|
PKG_CONFIG_LIBDIR="$DEPLOYDIR/lib/pkgconfig" ./autogen.sh --prefix="$DEPLOYDIR" --with-freetype=yes --with-gobject=no --with-cairo=no --with-icu=no CFLAGS=-mmacosx-version-min=$MAC_OSX_VERSION_MIN CXXFLAGS="$CXXFLAGS -mmacosx-version-min=$MAC_OSX_VERSION_MIN" LDFLAGS="$CXXFLAGS -mmacosx-version-min=$MAC_OSX_VERSION_MIN" $extra_config_flags
|
||||||
make -j$NUMCPU
|
make -j$NUMCPU
|
||||||
make install
|
make install
|
||||||
}
|
}
|
||||||
|
|
@ -826,9 +851,10 @@ if [ ! -f $OPENSCADDIR/openscad.pro ]; then
|
||||||
fi
|
fi
|
||||||
OPENSCAD_SCRIPTDIR=$PWD/scripts
|
OPENSCAD_SCRIPTDIR=$PWD/scripts
|
||||||
|
|
||||||
while getopts '6lcdf' c
|
while getopts '36lcdf' c
|
||||||
do
|
do
|
||||||
case $c in
|
case $c in
|
||||||
|
3) USING_CXX11=false;;
|
||||||
6) OPTION_32BIT=false;;
|
6) OPTION_32BIT=false;;
|
||||||
l) OPTION_LLVM=true;;
|
l) OPTION_LLVM=true;;
|
||||||
c) OPTION_CLANG=true;;
|
c) OPTION_CLANG=true;;
|
||||||
|
|
@ -841,7 +867,9 @@ done
|
||||||
OPTION_PACKAGES="${@:$OPTIND}"
|
OPTION_PACKAGES="${@:$OPTIND}"
|
||||||
|
|
||||||
OSX_VERSION=`sw_vers -productVersion | cut -d. -f2`
|
OSX_VERSION=`sw_vers -productVersion | cut -d. -f2`
|
||||||
if (( $OSX_VERSION >= 10 )); then
|
if (( $OSX_VERSION >= 11 )); then
|
||||||
|
echo "Detected El Capitan (10.11) or later"
|
||||||
|
elif (( $OSX_VERSION >= 10 )); then
|
||||||
echo "Detected Yosemite (10.10) or later"
|
echo "Detected Yosemite (10.10) or later"
|
||||||
elif (( $OSX_VERSION >= 9 )); then
|
elif (( $OSX_VERSION >= 9 )); then
|
||||||
echo "Detected Mavericks (10.9)"
|
echo "Detected Mavericks (10.9)"
|
||||||
|
|
@ -885,6 +913,14 @@ elif $USING_CLANG; then
|
||||||
export CXX=clang++
|
export CXX=clang++
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
if $USING_CXX11; then
|
||||||
|
export CXXSTDFLAGS="-std=c++11 -stdlib=libc++"
|
||||||
|
export LDSTDFLAGS="-stdlib=libc++"
|
||||||
|
else
|
||||||
|
export CXXSTDFLAGS="-std=c++03 -stdlib=libstdc++"
|
||||||
|
export LDSTDFLAGS="-stdlib=libstdc++"
|
||||||
|
fi
|
||||||
|
|
||||||
echo "Building for $MAC_OSX_VERSION_MIN or later"
|
echo "Building for $MAC_OSX_VERSION_MIN or later"
|
||||||
|
|
||||||
if [ ! $NUMCPU ]; then
|
if [ ! $NUMCPU ]; then
|
||||||
|
|
@ -917,6 +953,7 @@ fi
|
||||||
|
|
||||||
# Build specified (or all) packages
|
# Build specified (or all) packages
|
||||||
ALL_PACKAGES=$(all_packages)
|
ALL_PACKAGES=$(all_packages)
|
||||||
|
echo $ALL_PACKAGES
|
||||||
if [ -z "$OPTION_PACKAGES" ]; then
|
if [ -z "$OPTION_PACKAGES" ]; then
|
||||||
OPTION_PACKAGES=$ALL_PACKAGES
|
OPTION_PACKAGES=$ALL_PACKAGES
|
||||||
fi
|
fi
|
||||||
|
|
|
||||||
|
|
@ -20,6 +20,8 @@ import re
|
||||||
|
|
||||||
DEBUG = False
|
DEBUG = False
|
||||||
|
|
||||||
|
cxxlib = None
|
||||||
|
|
||||||
def usage():
|
def usage():
|
||||||
print >> sys.stderr, "Usage: " + sys.argv[0] + " <executable>"
|
print >> sys.stderr, "Usage: " + sys.argv[0] + " <executable>"
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
@ -62,12 +64,17 @@ def find_dependencies(file):
|
||||||
return None
|
return None
|
||||||
deps = output.split('\n')
|
deps = output.split('\n')
|
||||||
for dep in deps:
|
for dep in deps:
|
||||||
#print dep
|
# print dep
|
||||||
# Fail if anything is linked with libc++, as that's not backwards compatible
|
# Fail if libstc++ and libc++ was mixed
|
||||||
# with Mac OS X 10.6
|
global cxxlib
|
||||||
if re.search("libc\+\+", dep):
|
match = re.search("lib(std)?c\+\+", dep)
|
||||||
print "Error: clang's libc++ is used by " + file
|
if match:
|
||||||
return None
|
if not cxxlib:
|
||||||
|
cxxlib = match.group(0)
|
||||||
|
else:
|
||||||
|
if cxxlib != match.group(0):
|
||||||
|
print "Error: Mixing libc++ and libstdc++"
|
||||||
|
return None
|
||||||
dep = re.sub(".*:$", "", dep) # Take away header line
|
dep = re.sub(".*:$", "", dep) # Take away header line
|
||||||
dep = re.sub("^\t", "", dep) # Remove initial tabs
|
dep = re.sub("^\t", "", dep) # Remove initial tabs
|
||||||
dep = re.sub(" \(.*\)$", "", dep) # Remove trailing parentheses
|
dep = re.sub(" \(.*\)$", "", dep) # Remove trailing parentheses
|
||||||
|
|
|
||||||
|
|
@ -20,8 +20,21 @@
|
||||||
#
|
#
|
||||||
# Also see http://en.wikibooks.org/wiki/OpenSCAD_User_Manual/Cross-compiling_for_Windows_on_Linux_or_Mac_OS_X
|
# Also see http://en.wikibooks.org/wiki/OpenSCAD_User_Manual/Cross-compiling_for_Windows_on_Linux_or_Mac_OS_X
|
||||||
#
|
#
|
||||||
# Also note the 64 bit is built on the branch of mxe by Tony Theodore
|
# Notes:
|
||||||
# which hasnt been merged to official mxe as of writing
|
#
|
||||||
|
# Originally this was based on Tony Theodore's branch of MXE, which is now
|
||||||
|
# integrated into official MXE.
|
||||||
|
#
|
||||||
|
# Targets:
|
||||||
|
#
|
||||||
|
# MXE allows 4 separate targets with the MXE_TARGETS environment variable.
|
||||||
|
# As of 2015 shared are not guaranteed to work.
|
||||||
|
#
|
||||||
|
# 64 bit static linked libraries MXE_TARGETS=x86_64-w64-mingw32.static
|
||||||
|
# 32 bit static linked libraries MXE_TARGETS=i686-w64-mingw32.static
|
||||||
|
# 64 bit shared libraries MXE_TARGETS=x86_64-w64-mingw32.shared
|
||||||
|
# 32 bit shared libraries MXE_TARGETS=i686-w64-mingw32.shared
|
||||||
|
#
|
||||||
|
|
||||||
OPENSCADDIR=$PWD
|
OPENSCADDIR=$PWD
|
||||||
if [ ! -f $OPENSCADDIR/openscad.pro ]; then
|
if [ ! -f $OPENSCADDIR/openscad.pro ]; then
|
||||||
|
|
|
||||||
|
|
@ -72,16 +72,17 @@ elif [[ $OSTYPE == "linux-gnu" ]]; then
|
||||||
echo "Detected build-machine ARCH: $ARCH"
|
echo "Detected build-machine ARCH: $ARCH"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [ "`echo $* | grep mingw32`" ]; then
|
if [ "`echo $* | grep mingw`" ]; then
|
||||||
OS=UNIX_CROSS_WIN
|
OS=UNIX_CROSS_WIN
|
||||||
ARCH=32
|
ARCH=32
|
||||||
echo Mingw-cross build using ARCH=32
|
MXELIBTYPE=static
|
||||||
fi
|
if [ "`echo $* | grep mingw64`" ]; then
|
||||||
|
ARCH=64
|
||||||
if [ "`echo $* | grep mingw64`" ]; then
|
fi
|
||||||
OS=UNIX_CROSS_WIN
|
if [ "`echo $* | grep shared`" ]; then
|
||||||
ARCH=64
|
MXELIBTYPE=shared
|
||||||
echo Mingw-cross build using ARCH=64
|
fi
|
||||||
|
echo Mingw-cross build using ARCH=$ARCH MXELIBTYPE=$MXELIBTYPE
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [ "`echo $* | grep snapshot`" ]; then
|
if [ "`echo $* | grep snapshot`" ]; then
|
||||||
|
|
@ -188,7 +189,7 @@ case $OS in
|
||||||
TARGET=release
|
TARGET=release
|
||||||
;;
|
;;
|
||||||
UNIX_CROSS_WIN)
|
UNIX_CROSS_WIN)
|
||||||
. ./scripts/setenv-mingw-xbuild.sh $ARCH
|
. ./scripts/setenv-mingw-xbuild.sh $ARCH $MXELIBTYPE
|
||||||
TARGET=release
|
TARGET=release
|
||||||
ZIP="zip"
|
ZIP="zip"
|
||||||
ZIPARGS="-r -q"
|
ZIPARGS="-r -q"
|
||||||
|
|
@ -198,7 +199,12 @@ esac
|
||||||
|
|
||||||
case $OS in
|
case $OS in
|
||||||
UNIX_CROSS_WIN)
|
UNIX_CROSS_WIN)
|
||||||
cd $DEPLOYDIR && qmake VERSION=$VERSION OPENSCAD_COMMIT=$OPENSCAD_COMMIT CONFIG+="$CONFIG" CONFIG+=mingw-cross-env CONFIG-=debug ../openscad.pro
|
cd $DEPLOYDIR
|
||||||
|
MINGWCONFIG=mingw-cross-env
|
||||||
|
if [ $MXELIBTYPE = "shared" ]; then
|
||||||
|
MINGWCONFIG=mingw-cross-env-shared
|
||||||
|
fi
|
||||||
|
qmake VERSION=$VERSION OPENSCAD_COMMIT=$OPENSCAD_COMMIT CONFIG+="$CONFIG" CONFIG+=$MINGWCONFIG CONFIG-=debug ../openscad.pro
|
||||||
cd $OPENSCADDIR
|
cd $OPENSCADDIR
|
||||||
;;
|
;;
|
||||||
*)
|
*)
|
||||||
|
|
@ -425,9 +431,78 @@ case $OS in
|
||||||
INSTFILE=$DEPLOYDIR/OpenSCAD-$VERSION-x86-$ARCH-Installer.exe
|
INSTFILE=$DEPLOYDIR/OpenSCAD-$VERSION-x86-$ARCH-Installer.exe
|
||||||
|
|
||||||
#package
|
#package
|
||||||
|
if [ $MXELIBTYPE = "shared" ]; then
|
||||||
|
flprefix=$DEPLOYDIR/mingw-cross-env/bin
|
||||||
|
echo Copying dlls for shared library build
|
||||||
|
echo from $flprefix
|
||||||
|
echo to $DEPLOYDIR/$TARGET
|
||||||
|
flist=
|
||||||
|
# fl="$fl opengl.dll" # use Windows version?
|
||||||
|
# fl="$fl libmpfr.dll" # does not exist
|
||||||
|
fl="$fl libgmp-10.dll"
|
||||||
|
fl="$fl libgmpxx-4.dll"
|
||||||
|
fl="$fl libboost_filesystem-mt.dll"
|
||||||
|
fl="$fl libboost_program_options-mt.dll"
|
||||||
|
fl="$fl libboost_regex-mt.dll"
|
||||||
|
fl="$fl libboost_chrono-mt.dll"
|
||||||
|
fl="$fl libboost_system-mt.dll"
|
||||||
|
fl="$fl libboost_thread_win32-mt.dll"
|
||||||
|
fl="$fl libCGAL.dll"
|
||||||
|
fl="$fl libCGAL_Core.dll"
|
||||||
|
fl="$fl GLEW.dll"
|
||||||
|
fl="$fl libglib-2.0-0.dll"
|
||||||
|
fl="$fl libopencsg-1.dll"
|
||||||
|
fl="$fl libharfbuzz-0.dll"
|
||||||
|
# fl="$fl libharfbuzz-gobject-0.dll" # ????
|
||||||
|
fl="$fl libfontconfig-1.dll"
|
||||||
|
fl="$fl libexpat-1.dll"
|
||||||
|
fl="$fl libbz2.dll"
|
||||||
|
fl="$fl libintl-8.dll"
|
||||||
|
fl="$fl libiconv-2.dll"
|
||||||
|
fl="$fl libfreetype-6.dll"
|
||||||
|
fl="$fl libpcre16-0.dll"
|
||||||
|
fl="$fl zlib1.dll"
|
||||||
|
fl="$fl libpng16-16.dll"
|
||||||
|
fl="$fl icudt54.dll"
|
||||||
|
fl="$fl icudt.dll"
|
||||||
|
fl="$fl icuin.dll"
|
||||||
|
fl="$fl libstdc++-6.dll"
|
||||||
|
fl="$fl ../qt5/lib/qscintilla2.dll"
|
||||||
|
fl="$fl ../qt5/bin/Qt5PrintSupport.dll"
|
||||||
|
fl="$fl ../qt5/bin/Qt5Core.dll"
|
||||||
|
fl="$fl ../qt5/bin/Qt5Gui.dll"
|
||||||
|
fl="$fl ../qt5/bin/Qt5OpenGL.dll"
|
||||||
|
# fl="$fl ../qt5/bin/QtSvg4.dll" # why is this here?
|
||||||
|
fl="$fl ../qt5/bin/Qt5Widgets.dll"
|
||||||
|
fl="$fl ../qt5/bin/Qt5PrintSupport.dll"
|
||||||
|
fl="$fl ../qt5/bin/Qt5PrintSupport.dll"
|
||||||
|
for dllfile in $fl; do
|
||||||
|
if [ -e $flprefix/$dllfile ]; then
|
||||||
|
echo $flprefix/$dllfile
|
||||||
|
cp $flprefix/$dllfile $DEPLOYDIR/$TARGET/
|
||||||
|
else
|
||||||
|
echo cannot find $flprefix/$dllfile
|
||||||
|
echo stopping build.
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "Copying main binary .exe, .com, and dlls"
|
||||||
|
echo "from $DEPLOYDIR/$TARGET"
|
||||||
|
echo "to $DEPLOYDIR/openscad-$VERSION"
|
||||||
|
TMPTAR=$DEPLOYDIR/tmpmingw.$ARCH.$MXELIBTYPE.tar
|
||||||
|
cd $DEPLOYDIR
|
||||||
|
cd $TARGET
|
||||||
|
tar cvf $TMPTAR --exclude=winconsole.o .
|
||||||
|
cd $DEPLOYDIR
|
||||||
|
cd ./openscad-$VERSION
|
||||||
|
tar xvf $TMPTAR
|
||||||
|
cd $DEPLOYDIR
|
||||||
|
rm -f $TMPTAR
|
||||||
|
|
||||||
|
|
||||||
echo "Creating binary zip package"
|
echo "Creating binary zip package"
|
||||||
cp $TARGET/openscad.exe openscad-$VERSION
|
|
||||||
cp $TARGET/openscad.com openscad-$VERSION
|
|
||||||
rm -f OpenSCAD-$VERSION.x86-$ARCH.zip
|
rm -f OpenSCAD-$VERSION.x86-$ARCH.zip
|
||||||
"$ZIP" $ZIPARGS $BINFILE openscad-$VERSION
|
"$ZIP" $ZIPARGS $BINFILE openscad-$VERSION
|
||||||
cd $OPENSCADDIR
|
cd $OPENSCADDIR
|
||||||
|
|
@ -443,8 +518,8 @@ case $OS in
|
||||||
cd $DEPLOYDIR/openscad-$VERSION
|
cd $DEPLOYDIR/openscad-$VERSION
|
||||||
NSISDEBUG=-V2
|
NSISDEBUG=-V2
|
||||||
# NSISDEBUG= # leave blank for full log
|
# NSISDEBUG= # leave blank for full log
|
||||||
echo $MAKENSIS $NSISDEBUG installer.nsi
|
echo $MAKENSIS $NSISDEBUG "-DVERSION=$VERSION" installer.nsi
|
||||||
$MAKENSIS $NSISDEBUG installer.nsi
|
$MAKENSIS $NSISDEBUG "-DVERSION=$VERSION" installer.nsi
|
||||||
cp $DEPLOYDIR/openscad-$VERSION/openscad_setup.exe $INSTFILE
|
cp $DEPLOYDIR/openscad-$VERSION/openscad_setup.exe $INSTFILE
|
||||||
cd $OPENSCADDIR
|
cd $OPENSCADDIR
|
||||||
|
|
||||||
|
|
@ -528,7 +603,7 @@ if [ $BUILD_TESTS ]; then
|
||||||
# while copying.
|
# while copying.
|
||||||
rm -f ./ostests.tar
|
rm -f ./ostests.tar
|
||||||
for subdir in tests testdata libraries examples doc; do
|
for subdir in tests testdata libraries examples doc; do
|
||||||
tar prvf ./ostests.tar --exclude=.git* --exclude=*/mingw64/* --exclude=*/mingw32/* --exclude=*.cc.obj --exclude=*.a $subdir
|
tar prvf ./ostests.tar --exclude=.git* --exclude=*/mingw* --exclude=*.cc.obj --exclude=*.a $subdir
|
||||||
done
|
done
|
||||||
cd $DEPLOYDIR
|
cd $DEPLOYDIR
|
||||||
tar prvf $OPENSCADDIR/ostests.tar --exclude=.git* --exclude=*/mingw* --exclude=*.cc.obj --exclude=*.a $TESTBINDIR
|
tar prvf $OPENSCADDIR/ostests.tar --exclude=.git* --exclude=*/mingw* --exclude=*.cc.obj --exclude=*.a $TESTBINDIR
|
||||||
|
|
|
||||||
|
|
@ -4,10 +4,12 @@
|
||||||
#
|
#
|
||||||
# Usage:
|
# Usage:
|
||||||
#
|
#
|
||||||
# source ./scripts/setenv-mingw-xbuild.sh # 32 bit build
|
# source ./scripts/setenv-mingw-xbuild.sh # 32 bit build
|
||||||
# source ./scripts/setenv-mingw-xbuild.sh 64 # 64 bit build
|
# source ./scripts/setenv-mingw-xbuild.sh shared # 32 bit build, shared libs
|
||||||
# source ./scripts/setenv-mingw-xbuild.sh clean # Clean up exported variables
|
# source ./scripts/setenv-mingw-xbuild.sh 64 # 64 bit build
|
||||||
# source ./scripts/setenv-mingw-xbuild.sh qt5 # use qt5 (experimental)
|
# source ./scripts/setenv-mingw-xbuild.sh 64 shared # 64 bit build, shared libs
|
||||||
|
# source ./scripts/setenv-mingw-xbuild.sh clean # Clean up exported variables
|
||||||
|
# source ./scripts/setenv-mingw-xbuild.sh qt5 # use qt5 (experimental)
|
||||||
#
|
#
|
||||||
# Prerequisites:
|
# Prerequisites:
|
||||||
#
|
#
|
||||||
|
|
@ -22,8 +24,14 @@ if [ ! $BASEDIR ]; then
|
||||||
BASEDIR=$HOME/openscad_deps
|
BASEDIR=$HOME/openscad_deps
|
||||||
fi
|
fi
|
||||||
|
|
||||||
DEPLOYDIR64=$OPENSCADDIR/mingw64
|
MXELIBTYPE=static
|
||||||
DEPLOYDIR32=$OPENSCADDIR/mingw32
|
if [ "`echo $* | grep shared `" ]; then
|
||||||
|
MXELIBTYPE=shared
|
||||||
|
fi
|
||||||
|
|
||||||
|
|
||||||
|
DEPLOYDIR64=$OPENSCADDIR/mingw64.$MXELIBTYPE
|
||||||
|
DEPLOYDIR32=$OPENSCADDIR/mingw32.$MXELIBTYPE
|
||||||
|
|
||||||
if [ ! $DEPLOYDIR ]; then
|
if [ ! $DEPLOYDIR ]; then
|
||||||
if [ "`echo $* | grep 64 `" ]; then
|
if [ "`echo $* | grep 64 `" ]; then
|
||||||
|
|
@ -39,6 +47,11 @@ if [ ! $MXEDIR ]; then
|
||||||
else
|
else
|
||||||
MXEDIR=$BASEDIR/mxe
|
MXEDIR=$BASEDIR/mxe
|
||||||
fi
|
fi
|
||||||
|
if [ ! -e $MXEDIR ]; then
|
||||||
|
if [ -e /opt/mxe ]; then
|
||||||
|
MXEDIR=/opt/mxe
|
||||||
|
fi
|
||||||
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [ ! $MXEQTSUBDIR ]; then
|
if [ ! $MXEQTSUBDIR ]; then
|
||||||
|
|
@ -56,9 +69,9 @@ if [ ! -e $DEPLOYDIR ]; then
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [ "`echo $* | grep 64 `" ]; then
|
if [ "`echo $* | grep 64 `" ]; then
|
||||||
MXETARGETDIR=$MXEDIR/usr/x86_64-w64-mingw32.static
|
MXETARGETDIR=$MXEDIR/usr/x86_64-w64-mingw32.$MXELIBTYPE
|
||||||
else
|
else
|
||||||
MXETARGETDIR=$MXEDIR/usr/i686-w64-mingw32.static
|
MXETARGETDIR=$MXEDIR/usr/i686-w64-mingw32.$MXELIBTYPE
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [ ! $MINGWX_SAVED_ORIGINAL_PATH ]; then
|
if [ ! $MINGWX_SAVED_ORIGINAL_PATH ]; then
|
||||||
|
|
@ -91,6 +104,7 @@ export OPENSCAD_LIBRARIES
|
||||||
export BASEDIR
|
export BASEDIR
|
||||||
export MXEDIR
|
export MXEDIR
|
||||||
export MXETARGETDIR
|
export MXETARGETDIR
|
||||||
|
export MXELIBTYPE
|
||||||
export DEPLOYDIR
|
export DEPLOYDIR
|
||||||
export PATH
|
export PATH
|
||||||
export MINGWX_SAVED_ORIGINAL_PATH
|
export MINGWX_SAVED_ORIGINAL_PATH
|
||||||
|
|
@ -100,6 +114,7 @@ echo OPENSCAD_LIBRARIES: $OPENSCAD_LIBRARIES
|
||||||
echo BASEDIR: $BASEDIR
|
echo BASEDIR: $BASEDIR
|
||||||
echo MXEDIR: $MXEDIR
|
echo MXEDIR: $MXEDIR
|
||||||
echo MXETARGETDIR: $MXETARGETDIR
|
echo MXETARGETDIR: $MXETARGETDIR
|
||||||
|
echo MXELIBTYPE: $MXELIBTYPE
|
||||||
echo DEPLOYDIR: $DEPLOYDIR
|
echo DEPLOYDIR: $DEPLOYDIR
|
||||||
echo MXEQTSUBDIR: $MXEQTSUBDIR
|
echo MXEQTSUBDIR: $MXEQTSUBDIR
|
||||||
if [ "`echo $* | grep clean`" ]; then
|
if [ "`echo $* | grep clean`" ]; then
|
||||||
|
|
|
||||||
|
|
@ -25,6 +25,9 @@ updatepot()
|
||||||
| awk '{ printf "#: examples/examples.json:%d\nmsgid %s\nmsgstr \"\"\n\n", $1, $2 }' \
|
| awk '{ printf "#: examples/examples.json:%d\nmsgid %s\nmsgstr \"\"\n\n", $1, $2 }' \
|
||||||
> ./locale/json-strings.pot
|
> ./locale/json-strings.pot
|
||||||
|
|
||||||
|
# extract strings from appdata file
|
||||||
|
itstool -o ./locale/appdata-strings.pot ./openscad.appdata.xml.in --its=./contrib/appdata.its
|
||||||
|
|
||||||
VER=`date +"%Y.%m.%d"`
|
VER=`date +"%Y.%m.%d"`
|
||||||
OPTS=
|
OPTS=
|
||||||
OPTS=$OPTS' --package-name=OpenSCAD'
|
OPTS=$OPTS' --package-name=OpenSCAD'
|
||||||
|
|
@ -41,7 +44,7 @@ updatepot()
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
cmd="${GETTEXT_PATH}msgcat -o ./locale/openscad.pot ./locale/openscad-tmp.pot ./locale/json-strings.pot"
|
cmd="${GETTEXT_PATH}msgcat -o ./locale/openscad.pot ./locale/openscad-tmp.pot ./locale/json-strings.pot ./locale/appdata-strings.pot"
|
||||||
echo $cmd
|
echo $cmd
|
||||||
$cmd
|
$cmd
|
||||||
if [ ! $? = 0 ]; then
|
if [ ! $? = 0 ]; then
|
||||||
|
|
@ -50,7 +53,7 @@ updatepot()
|
||||||
fi
|
fi
|
||||||
|
|
||||||
sed -e s/"CHARSET"/"UTF-8"/g ./locale/openscad.pot > ./locale/openscad.pot.new && mv ./locale/openscad.pot.new ./locale/openscad.pot
|
sed -e s/"CHARSET"/"UTF-8"/g ./locale/openscad.pot > ./locale/openscad.pot.new && mv ./locale/openscad.pot.new ./locale/openscad.pot
|
||||||
rm -f ./locale/json-strings.pot ./locale/openscad-tmp.pot
|
rm -f ./locale/json-strings.pot ./locale/openscad-tmp.pot ./locale/appdata-strings.pot
|
||||||
}
|
}
|
||||||
|
|
||||||
updatepo()
|
updatepo()
|
||||||
|
|
@ -80,6 +83,26 @@ updatemo()
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
|
|
||||||
|
if which itstool > /dev/null 2>&1; then
|
||||||
|
# ugly workaround for bug https://bugs.freedesktop.org/show_bug.cgi?id=90937
|
||||||
|
for LANGCODE in `cat locale/LINGUAS | grep -v "#"`; do
|
||||||
|
ln -s openscad.mo ./locale/$LANGCODE/LC_MESSAGES/$LANGCODE.mo
|
||||||
|
done
|
||||||
|
|
||||||
|
# generate translated appdata file
|
||||||
|
itstool -j ./openscad.appdata.xml.in -o ./openscad.appdata.xml ./locale/*/LC_MESSAGES/[a-z][a-z].mo
|
||||||
|
|
||||||
|
# clean the mess
|
||||||
|
for LANGCODE in `cat locale/LINGUAS | grep -v "#"`; do
|
||||||
|
unlink ./locale/$LANGCODE/LC_MESSAGES/$LANGCODE.mo
|
||||||
|
done
|
||||||
|
else
|
||||||
|
if [ x"$(uname -s)" = x"Linux" ]; then
|
||||||
|
echo "itstool missing, won't apply translations to openscad.appdata.xml"
|
||||||
|
fi
|
||||||
|
cp -f ./openscad.appdata.xml.in ./openscad.appdata.xml
|
||||||
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
GETTEXT_PATH=""
|
GETTEXT_PATH=""
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,8 @@
|
||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
|
||||||
|
qmake CONFIG+=experimental CONFIG+=nogui
|
||||||
|
make
|
||||||
|
|
||||||
cd tests
|
cd tests
|
||||||
cmake .
|
cmake .
|
||||||
if [[ $? != 0 ]]; then
|
if [[ $? != 0 ]]; then
|
||||||
|
|
|
||||||
|
|
@ -79,10 +79,22 @@ check_env()
|
||||||
detect_glu()
|
detect_glu()
|
||||||
{
|
{
|
||||||
detect_glu_result=
|
detect_glu_result=
|
||||||
if [ -e $DEPLOYDIR/include/GL/glu.h ]; then detect_glu_result=1; fi
|
if [ -e $DEPLOYDIR/include/GL/glu.h ]; then
|
||||||
if [ -e /usr/include/GL/glu.h ]; then detect_glu_result=1; fi
|
detect_glu_include=$DEPLOYDIR/include
|
||||||
if [ -e /usr/local/include/GL/glu.h ]; then detect_glu_result=1; fi
|
detect_glu_result=1;
|
||||||
if [ -e /usr/pkg/X11R7/include/GL/glu.h ]; then detect_glu_result=1; fi
|
fi
|
||||||
|
if [ -e /usr/include/GL/glu.h ]; then
|
||||||
|
detect_glu_include=/usr/include
|
||||||
|
detect_glu_result=1;
|
||||||
|
fi
|
||||||
|
if [ -e /usr/local/include/GL/glu.h ]; then
|
||||||
|
detect_glu_include=/usr/local/include
|
||||||
|
detect_glu_result=1;
|
||||||
|
fi
|
||||||
|
if [ -e /usr/pkg/X11R7/include/GL/glu.h ]; then
|
||||||
|
detect_glu_include=/usr/pkg/X11R7/include
|
||||||
|
detect_glu_result=1;
|
||||||
|
fi
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -505,10 +517,20 @@ build_opencsg()
|
||||||
cp opencsg.pro opencsg.pro.bak
|
cp opencsg.pro opencsg.pro.bak
|
||||||
cat opencsg.pro.bak | sed s/example// > opencsg.pro
|
cat opencsg.pro.bak | sed s/example// > opencsg.pro
|
||||||
|
|
||||||
|
detect_glu
|
||||||
|
GLU_INCLUDE=$detect_glu_include
|
||||||
|
if [ ! $detect_glu_result ]; then
|
||||||
|
build_glu 9.0.0
|
||||||
|
fi
|
||||||
|
|
||||||
if [ "`command -v qmake-qt4`" ]; then
|
if [ "`command -v qmake-qt4`" ]; then
|
||||||
OPENCSG_QMAKE=qmake-qt4
|
OPENCSG_QMAKE=qmake-qt4
|
||||||
elif [ "`command -v qmake4`" ]; then
|
elif [ "`command -v qmake4`" ]; then
|
||||||
OPENCSG_QMAKE=qmake4
|
OPENCSG_QMAKE=qmake4
|
||||||
|
elif [ "`command -v qmake-qt5`" ]; then
|
||||||
|
OPENCSG_QMAKE=qmake-qt5
|
||||||
|
elif [ "`command -v qmake5`" ]; then
|
||||||
|
OPENCSG_QMAKE=qmake5
|
||||||
elif [ "`command -v qmake`" ]; then
|
elif [ "`command -v qmake`" ]; then
|
||||||
OPENCSG_QMAKE=qmake
|
OPENCSG_QMAKE=qmake
|
||||||
else
|
else
|
||||||
|
|
@ -518,15 +540,18 @@ build_opencsg()
|
||||||
cp src/Makefile src/Makefile.bak
|
cp src/Makefile src/Makefile.bak
|
||||||
|
|
||||||
cat Makefile.bak | sed s/example// |sed s/glew// > Makefile
|
cat Makefile.bak | sed s/example// |sed s/glew// > Makefile
|
||||||
cat src/Makefile.bak | sed s@^INCPATH.*@INCPATH\ =\ -I$BASEDIR/include\ -I../include\ -I..\ -I.@ > src/Makefile
|
cat src/Makefile.bak | sed s@^INCPATH.*@INCPATH\ =\ -I$BASEDIR/include\ -I../include\ -I..\ -I$GLU_INCLUDE -I.@ > src/Makefile
|
||||||
cp src/Makefile src/Makefile.bak2
|
cp src/Makefile src/Makefile.bak2
|
||||||
cat src/Makefile.bak2 | sed s@^LIBS.*@LIBS\ =\ -L$BASEDIR/lib\ -L/usr/X11R6/lib\ -lGLU\ -lGL@ > src/Makefile
|
cat src/Makefile.bak2 | sed s@^LIBS.*@LIBS\ =\ -L$BASEDIR/lib\ -L/usr/X11R6/lib\ -lGLU\ -lGL@ > src/Makefile
|
||||||
tmp=$version
|
tmp=$version
|
||||||
detect_glu
|
|
||||||
if [ ! $detect_glu_result ]; then build_glu 9.0.0 ; fi
|
|
||||||
version=$tmp
|
version=$tmp
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
if [ ! $OPENCSG_QMAKE = "make" ]; then
|
||||||
|
OPENCSG_QMAKE=$OPENCSG_QMAKE' "QMAKE_CXXFLAGS+=-I'$GLU_INCLUDE'"'
|
||||||
|
fi
|
||||||
|
echo OPENCSG_QMAKE: $OPENCSG_QMAKE
|
||||||
|
|
||||||
cd $BASEDIR/src/OpenCSG-$version/src
|
cd $BASEDIR/src/OpenCSG-$version/src
|
||||||
$OPENCSG_QMAKE
|
$OPENCSG_QMAKE
|
||||||
|
|
||||||
|
|
@ -776,6 +801,11 @@ if [ $1 ]; then
|
||||||
build_gettext 0.18.3.1
|
build_gettext 0.18.3.1
|
||||||
exit $?
|
exit $?
|
||||||
fi
|
fi
|
||||||
|
if [ $1 = "harfbuzz" ]; then
|
||||||
|
# debian 7 lacks only harfbuzz
|
||||||
|
build_harfbuzz 0.9.23 --with-glib=yes
|
||||||
|
exit $?
|
||||||
|
fi
|
||||||
if [ $1 = "glib2" ]; then
|
if [ $1 = "glib2" ]; then
|
||||||
# such a huge build, put here by itself
|
# such a huge build, put here by itself
|
||||||
build_pkgconfig 0.28
|
build_pkgconfig 0.28
|
||||||
|
|
|
||||||
|
|
@ -4,13 +4,24 @@
|
||||||
# this assumes you have sudo installed and running, or are running as root.
|
# this assumes you have sudo installed and running, or are running as root.
|
||||||
#
|
#
|
||||||
|
|
||||||
get_fedora_deps()
|
get_fedora_deps_yum()
|
||||||
{
|
{
|
||||||
yum -y install qt5-qtbase-devel bison flex eigen3-devel harfbuzz-devel \
|
yum -y install qt5-qtbase-devel bison flex eigen3-devel harfbuzz-devel \
|
||||||
fontconfig-devel freetype-devel \
|
fontconfig-devel freetype-devel \
|
||||||
boost-devel mpfr-devel gmp-devel glew-devel CGAL-devel gcc gcc-c++ pkgconfig \
|
boost-devel mpfr-devel gmp-devel glew-devel CGAL-devel gcc gcc-c++ pkgconfig \
|
||||||
opencsg-devel git libXmu-devel curl imagemagick ImageMagick glib2-devel make \
|
opencsg-devel git libXmu-devel curl imagemagick ImageMagick glib2-devel make \
|
||||||
xorg-x11-server-Xvfb gettext
|
xorg-x11-server-Xvfb gettext qscintilla-devel qscintilla-qt5-devel \
|
||||||
|
mesa-dri-drivers
|
||||||
|
}
|
||||||
|
|
||||||
|
get_fedora_deps_dnf()
|
||||||
|
{
|
||||||
|
dnf -y install qt5-qtbase-devel bison flex eigen3-devel harfbuzz-devel \
|
||||||
|
fontconfig-devel freetype-devel \
|
||||||
|
boost-devel mpfr-devel gmp-devel glew-devel CGAL-devel gcc gcc-c++ pkgconfig \
|
||||||
|
opencsg-devel git libXmu-devel curl ImageMagick glib2-devel make \
|
||||||
|
xorg-x11-server-Xvfb gettext qscintilla-devel qscintilla-qt5-devel \
|
||||||
|
mesa-dri-drivers
|
||||||
}
|
}
|
||||||
|
|
||||||
get_qomo_deps()
|
get_qomo_deps()
|
||||||
|
|
@ -43,8 +54,13 @@ get_netbsd_deps()
|
||||||
get_opensuse_deps()
|
get_opensuse_deps()
|
||||||
{
|
{
|
||||||
zypper install libeigen3-devel mpfr-devel gmp-devel boost-devel \
|
zypper install libeigen3-devel mpfr-devel gmp-devel boost-devel \
|
||||||
libqt4-devel glew-devel cmake git bison flex cgal-devel opencsg-devel curl \
|
libqt4-devel glew-devel cmake git bison flex cgal-devel curl \
|
||||||
glib2-devel gettext
|
glib2-devel gettext freetype-devel harfbuzz-devel libqscintilla-devel \
|
||||||
|
xvfb-run imagemagick opencsg-devel
|
||||||
|
echo if you are missing opencsg, please add the -graphics- repository
|
||||||
|
echo find your version from cat /etc/issue, then replace it below, then run
|
||||||
|
echo " zypper ar -f http://download.opensuse.org/repositories/graphics/openSUSE_13.2 graphics"
|
||||||
|
echo " zypper install opencsg-devel"
|
||||||
}
|
}
|
||||||
|
|
||||||
get_mageia_deps()
|
get_mageia_deps()
|
||||||
|
|
@ -58,12 +74,34 @@ get_mageia_deps()
|
||||||
get_debian_deps()
|
get_debian_deps()
|
||||||
{
|
{
|
||||||
apt-get -y install \
|
apt-get -y install \
|
||||||
build-essential curl libffi-dev qtbase5-dev libqt5scintilla2-dev \
|
build-essential curl libffi-dev \
|
||||||
libxmu-dev cmake bison flex git-core libboost-all-dev \
|
libxmu-dev cmake bison flex git-core libboost-all-dev \
|
||||||
libXi-dev libmpfr-dev libboost-dev libglew-dev \
|
libXi-dev libmpfr-dev libboost-dev libglew-dev \
|
||||||
libeigen3-dev libcgal-dev libopencsg-dev libgmp3-dev libgmp-dev \
|
libeigen3-dev libcgal-dev libopencsg-dev libgmp3-dev libgmp-dev \
|
||||||
imagemagick libfontconfig-dev libfreetype6-dev \
|
imagemagick libfontconfig-dev libfreetype6-dev \
|
||||||
libharfbuzz-dev gtk-doc-tools libglib2.0-dev gettext
|
gtk-doc-tools libglib2.0-dev gettext xvfb pkg-config ragel
|
||||||
|
}
|
||||||
|
|
||||||
|
get_debian_8_deps()
|
||||||
|
{
|
||||||
|
get_debian_deps
|
||||||
|
apt-get -y install libharfbuzz-dev qtbase5-dev libqt5scintilla2-dev
|
||||||
|
}
|
||||||
|
|
||||||
|
get_debian_7_deps()
|
||||||
|
{
|
||||||
|
get_debian_deps
|
||||||
|
apt-get -y install libqt4-dev libqscintilla2-dev
|
||||||
|
echo "debian 7 detected"
|
||||||
|
echo "please build harfbuzz & see the README on building dependencies"
|
||||||
|
echo ". ./scripts/setenv-unibuild.sh"
|
||||||
|
echo "./scripts/uni-build-dependencies.sh harfbuzz"
|
||||||
|
}
|
||||||
|
|
||||||
|
get_ubuntu_14_deps()
|
||||||
|
{
|
||||||
|
get_debian_8_deps
|
||||||
|
apt-get -y install qt5-qmake
|
||||||
}
|
}
|
||||||
|
|
||||||
unknown()
|
unknown()
|
||||||
|
|
@ -73,18 +111,28 @@ unknown()
|
||||||
}
|
}
|
||||||
|
|
||||||
if [ -e /etc/issue ]; then
|
if [ -e /etc/issue ]; then
|
||||||
if [ "`grep -i ubuntu /etc/issue`" ]; then
|
if [ "`grep -i ubuntu.1[4-9] /etc/issue`" ]; then
|
||||||
|
get_ubuntu_14_deps
|
||||||
|
elif [ "`grep -i ubuntu /etc/issue`" ]; then
|
||||||
get_debian_deps
|
get_debian_deps
|
||||||
|
elif [ "`grep -i debian.GNU.Linux.7 /etc/issue`" ]; then
|
||||||
|
get_debian_7_deps
|
||||||
elif [ "`grep -i debian /etc/issue`" ]; then
|
elif [ "`grep -i debian /etc/issue`" ]; then
|
||||||
get_debian_deps
|
get_debian_8_deps
|
||||||
elif [ "`grep -i raspbian /etc/issue`" ]; then
|
elif [ "`grep -i raspbian /etc/issue`" ]; then
|
||||||
get_debian_deps
|
get_debian_deps
|
||||||
elif [ "`grep -i mint /etc/issue`" ]; then
|
elif [ "`grep -i mint /etc/issue`" ]; then
|
||||||
get_debian_deps
|
get_debian_7_deps
|
||||||
elif [ "`grep -i suse /etc/issue`" ]; then
|
elif [ "`grep -i suse /etc/issue`" ]; then
|
||||||
get_opensuse_deps
|
get_opensuse_deps
|
||||||
|
elif [ "`grep -i fedora.release.2[2-9] /etc/issue`" ]; then
|
||||||
|
get_fedora_deps_dnf
|
||||||
|
elif [ "`grep -i fedora.release.[3-9][0-9] /etc/issue`" ]; then
|
||||||
|
get_fedora_deps_dnf
|
||||||
|
elif [ "`grep -i fedora.release.2[0-1] /etc/issue`" ]; then
|
||||||
|
get_fedora_deps_yum
|
||||||
elif [ "`grep -i fedora /etc/issue`" ]; then
|
elif [ "`grep -i fedora /etc/issue`" ]; then
|
||||||
get_fedora_deps
|
get_fedora_deps_yum
|
||||||
elif [ "`grep -i red.hat /etc/issue`" ]; then
|
elif [ "`grep -i red.hat /etc/issue`" ]; then
|
||||||
get_fedora_deps
|
get_fedora_deps
|
||||||
elif [ "`grep -i mageia /etc/issue`" ]; then
|
elif [ "`grep -i mageia /etc/issue`" ]; then
|
||||||
|
|
|
||||||
|
|
@ -11,8 +11,6 @@ public:
|
||||||
AboutDialog(QWidget *) {
|
AboutDialog(QWidget *) {
|
||||||
setupUi(this);
|
setupUi(this);
|
||||||
this->setWindowTitle( QString(_("About OpenSCAD")) + " " + openscad_shortversionnumber.c_str());
|
this->setWindowTitle( QString(_("About OpenSCAD")) + " " + openscad_shortversionnumber.c_str());
|
||||||
QUrl flattr_qurl(":icons/flattr.png" );
|
|
||||||
this->aboutText->loadResource( QTextDocument::ImageResource, flattr_qurl );
|
|
||||||
QString tmp = this->aboutText->toHtml();
|
QString tmp = this->aboutText->toHtml();
|
||||||
tmp.replace("__VERSION__", openscad_detailedversionnumber.c_str());
|
tmp.replace("__VERSION__", openscad_detailedversionnumber.c_str());
|
||||||
this->aboutText->setHtml(tmp);
|
this->aboutText->setHtml(tmp);
|
||||||
|
|
|
||||||
|
|
@ -9,13 +9,29 @@
|
||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8"/>
|
<meta charset="UTF-8"/>
|
||||||
<meta http-equiv="Content-Type" content="text/html;charset=utf-8"/>
|
<meta http-equiv="Content-Type" content="text/html;charset=utf-8"/>
|
||||||
|
|
||||||
|
<style type=text/css>
|
||||||
|
body {
|
||||||
|
font: 13pt Arial,sans-serif;
|
||||||
|
}
|
||||||
|
.flattr-link {
|
||||||
|
color: white;
|
||||||
|
background: #88B058;
|
||||||
|
font: bold 14px Helvetica,sans-serif;
|
||||||
|
}
|
||||||
|
.donate-link {
|
||||||
|
color: white;
|
||||||
|
background: dodgerblue;
|
||||||
|
font: bold 14px Helvetica,sans-serif;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
|
||||||
<body style="font-family:'Arial'; font-size:13pt;">
|
<p align="right">
|
||||||
|
<a class="flattr-link" href="https://flattr.com/submit/auto?user_id=openscad&url=http://openscad.org&title=OpenSCAD&language=&tags=github&category=software"> Flattr this! </a>
|
||||||
<p>
|
<a class="donate-link" href="http://www.openscad.org/community.html"> Donate </a>
|
||||||
<a align=right href="https://flattr.com/submit/auto?user_id=openscad&url=http://openscad.org&title=OpenSCAD&language=&tags=github&category=software"><img align=right src=":icons/flattr.png" /></a>
|
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
|
|
|
||||||
|
|
@ -40,6 +40,8 @@
|
||||||
|
|
||||||
#include FT_OUTLINE_H
|
#include FT_OUTLINE_H
|
||||||
|
|
||||||
|
#define SCRIPT_UNTAG(tag) ((uint8_t)((tag)>>24)) % ((uint8_t)((tag)>>16)) % ((uint8_t)((tag)>>8)) % ((uint8_t)(tag))
|
||||||
|
|
||||||
static inline Vector2d get_scaled_vector(const FT_Vector *ft_vector, double scale) {
|
static inline Vector2d get_scaled_vector(const FT_Vector *ft_vector, double scale) {
|
||||||
return Vector2d(ft_vector->x / scale, ft_vector->y / scale);
|
return Vector2d(ft_vector->x / scale, ft_vector->y / scale);
|
||||||
}
|
}
|
||||||
|
|
@ -122,6 +124,75 @@ double FreetypeRenderer::calc_y_offset(std::string valign, double ascend, double
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
hb_direction_t FreetypeRenderer::get_direction(const FreetypeRenderer::Params ¶ms, const hb_script_t script) const
|
||||||
|
{
|
||||||
|
hb_direction_t param_direction = hb_direction_from_string(params.direction.c_str(), -1);
|
||||||
|
if (param_direction != HB_DIRECTION_INVALID) {
|
||||||
|
return param_direction;
|
||||||
|
}
|
||||||
|
|
||||||
|
hb_direction_t direction = hb_script_get_horizontal_direction(script);
|
||||||
|
PRINTDB("Detected direction '%s' for %s", hb_direction_to_string(direction) % params.text.c_str());
|
||||||
|
return direction;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool FreetypeRenderer::is_ignored_script(const hb_script_t script) const
|
||||||
|
{
|
||||||
|
switch (script) {
|
||||||
|
case HB_SCRIPT_COMMON:
|
||||||
|
case HB_SCRIPT_INHERITED:
|
||||||
|
case HB_SCRIPT_UNKNOWN:
|
||||||
|
case HB_SCRIPT_INVALID:
|
||||||
|
return true;
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
hb_script_t FreetypeRenderer::get_script(const FreetypeRenderer::Params ¶ms, hb_glyph_info_t *glyph_info, unsigned int glyph_count) const
|
||||||
|
{
|
||||||
|
hb_script_t param_script = hb_script_from_string(params.script.c_str(), -1);
|
||||||
|
if (param_script != HB_SCRIPT_INVALID) {
|
||||||
|
return param_script;
|
||||||
|
}
|
||||||
|
|
||||||
|
hb_script_t script = HB_SCRIPT_INVALID;
|
||||||
|
for (unsigned int idx = 0;idx < glyph_count;idx++) {
|
||||||
|
hb_codepoint_t cp = glyph_info[idx].codepoint;
|
||||||
|
hb_script_t s = hb_unicode_script(hb_unicode_funcs_get_default(), cp);
|
||||||
|
if (!is_ignored_script(s)) {
|
||||||
|
if (script == HB_SCRIPT_INVALID) {
|
||||||
|
script = s;
|
||||||
|
} else if ((script != s) && (script != HB_SCRIPT_UNKNOWN)) {
|
||||||
|
script = HB_SCRIPT_UNKNOWN;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
PRINTDB("Detected script '%c%c%c%c' for %s", SCRIPT_UNTAG(script) % params.text.c_str());
|
||||||
|
return script;
|
||||||
|
}
|
||||||
|
|
||||||
|
void FreetypeRenderer::detect_properties(FreetypeRenderer::Params ¶ms) const
|
||||||
|
{
|
||||||
|
hb_buffer_t *hb_buf = hb_buffer_create();
|
||||||
|
hb_buffer_add_utf8(hb_buf, params.text.c_str(), strlen(params.text.c_str()), 0, strlen(params.text.c_str()));
|
||||||
|
|
||||||
|
unsigned int glyph_count;
|
||||||
|
hb_glyph_info_t *glyph_info = hb_buffer_get_glyph_infos(hb_buf, &glyph_count);
|
||||||
|
|
||||||
|
hb_script_t script = get_script(params, glyph_info, glyph_count);
|
||||||
|
hb_buffer_destroy(hb_buf);
|
||||||
|
|
||||||
|
if (!is_ignored_script(script)) {
|
||||||
|
char script_buf[5] = { 0, };
|
||||||
|
hb_tag_to_string(hb_script_to_iso15924_tag(script), script_buf);
|
||||||
|
params.set_script(script_buf);
|
||||||
|
}
|
||||||
|
|
||||||
|
hb_direction_t direction = get_direction(params, script);
|
||||||
|
params.set_direction(hb_direction_to_string(direction));
|
||||||
|
}
|
||||||
|
|
||||||
std::vector<const Geometry *> FreetypeRenderer::render(const FreetypeRenderer::Params ¶ms) const
|
std::vector<const Geometry *> FreetypeRenderer::render(const FreetypeRenderer::Params ¶ms) const
|
||||||
{
|
{
|
||||||
FT_Face face;
|
FT_Face face;
|
||||||
|
|
|
||||||
|
|
@ -85,7 +85,7 @@ public:
|
||||||
<< ", font = \"" << params.font
|
<< ", font = \"" << params.font
|
||||||
<< "\", direction = \"" << params.direction
|
<< "\", direction = \"" << params.direction
|
||||||
<< "\", language = \"" << params.language
|
<< "\", language = \"" << params.language
|
||||||
<< "\", script = \"" << params.script
|
<< (params.script.empty() ? "" : "\", script = \"") << params.script
|
||||||
<< "\", halign = \"" << params.halign
|
<< "\", halign = \"" << params.halign
|
||||||
<< "\", valign = \"" << params.valign
|
<< "\", valign = \"" << params.valign
|
||||||
<< "\", $fn = " << params.fn
|
<< "\", $fn = " << params.fn
|
||||||
|
|
@ -102,6 +102,7 @@ public:
|
||||||
FreetypeRenderer();
|
FreetypeRenderer();
|
||||||
virtual ~FreetypeRenderer();
|
virtual ~FreetypeRenderer();
|
||||||
|
|
||||||
|
void detect_properties(FreetypeRenderer::Params ¶ms) const;
|
||||||
std::vector<const class Geometry *> render(const FreetypeRenderer::Params ¶ms) const;
|
std::vector<const class Geometry *> render(const FreetypeRenderer::Params ¶ms) const;
|
||||||
private:
|
private:
|
||||||
const static double scale;
|
const static double scale;
|
||||||
|
|
@ -136,6 +137,10 @@ private:
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
bool is_ignored_script(const hb_script_t script) const;
|
||||||
|
hb_script_t get_script(const FreetypeRenderer::Params ¶ms, hb_glyph_info_t *glyph_info, unsigned int glyph_count) const;
|
||||||
|
hb_direction_t get_direction(const FreetypeRenderer::Params ¶ms, const hb_script_t script) const;
|
||||||
|
|
||||||
double calc_x_offset(std::string halign, double width) const;
|
double calc_x_offset(std::string halign, double width) const;
|
||||||
double calc_y_offset(std::string valign, double ascend, double descend) const;
|
double calc_y_offset(std::string valign, double ascend, double descend) const;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -158,7 +158,7 @@ void GLView::paintGL()
|
||||||
glDisable(GL_LIGHTING);
|
glDisable(GL_LIGHTING);
|
||||||
|
|
||||||
Color4f bgcol = ColorMap::getColor(*this->colorscheme, BACKGROUND_COLOR);
|
Color4f bgcol = ColorMap::getColor(*this->colorscheme, BACKGROUND_COLOR);
|
||||||
Color4f bgcontrast = ColorMap::getContrastColor(bgcol);
|
Color4f axescolor = ColorMap::getColor(*this->colorscheme, AXES_COLOR);
|
||||||
glClearColor(bgcol[0], bgcol[1], bgcol[2], 1.0);
|
glClearColor(bgcol[0], bgcol[1], bgcol[2], 1.0);
|
||||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
|
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
|
||||||
|
|
||||||
|
|
@ -169,9 +169,9 @@ void GLView::paintGL()
|
||||||
if (showcrosshairs) GLView::showCrosshairs();
|
if (showcrosshairs) GLView::showCrosshairs();
|
||||||
glTranslated(cam.object_trans.x(), cam.object_trans.y(), cam.object_trans.z());
|
glTranslated(cam.object_trans.x(), cam.object_trans.y(), cam.object_trans.z());
|
||||||
// ...the axis lines need to follow the object translation.
|
// ...the axis lines need to follow the object translation.
|
||||||
if (showaxes) GLView::showAxes(bgcontrast);
|
if (showaxes) GLView::showAxes(axescolor);
|
||||||
// mark the scale along the axis lines
|
// mark the scale along the axis lines
|
||||||
if (showaxes && showscale) GLView::showScalemarkers(bgcontrast);
|
if (showaxes && showscale) GLView::showScalemarkers(axescolor);
|
||||||
}
|
}
|
||||||
|
|
||||||
glEnable(GL_LIGHTING);
|
glEnable(GL_LIGHTING);
|
||||||
|
|
@ -191,7 +191,7 @@ void GLView::paintGL()
|
||||||
|
|
||||||
// Only for GIMBAL
|
// Only for GIMBAL
|
||||||
glDisable(GL_LIGHTING);
|
glDisable(GL_LIGHTING);
|
||||||
if (showaxes) GLView::showSmallaxes(bgcontrast);
|
if (showaxes) GLView::showSmallaxes(axescolor);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef ENABLE_OPENCSG
|
#ifdef ENABLE_OPENCSG
|
||||||
|
|
@ -216,7 +216,7 @@ void GLView::enable_opencsg_shaders()
|
||||||
else if (GLEW_EXT_framebuffer_object && GLEW_EXT_packed_depth_stencil) {
|
else if (GLEW_EXT_framebuffer_object && GLEW_EXT_packed_depth_stencil) {
|
||||||
this->is_opencsg_capable = true;
|
this->is_opencsg_capable = true;
|
||||||
}
|
}
|
||||||
#ifdef WIN32
|
#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__)
|
#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;
|
||||||
|
|
|
||||||
|
|
@ -740,6 +740,7 @@ Response GeometryEvaluator::visit(State &state, const LinearExtrudeNode &node)
|
||||||
|
|
||||||
Polygon2d *p2d = dxf.toPolygon2d();
|
Polygon2d *p2d = dxf.toPolygon2d();
|
||||||
if (p2d) geometry = ClipperUtils::sanitize(*p2d);
|
if (p2d) geometry = ClipperUtils::sanitize(*p2d);
|
||||||
|
delete p2d;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
geometry = applyToChildren2D(node, OPENSCAD_UNION);
|
geometry = applyToChildren2D(node, OPENSCAD_UNION);
|
||||||
|
|
@ -849,6 +850,7 @@ Response GeometryEvaluator::visit(State &state, const RotateExtrudeNode &node)
|
||||||
DxfData dxf(node.fn, node.fs, node.fa, node.filename, node.layername, node.origin_x, node.origin_y, node.scale);
|
DxfData dxf(node.fn, node.fs, node.fa, node.filename, node.layername, node.origin_x, node.origin_y, node.scale);
|
||||||
Polygon2d *p2d = dxf.toPolygon2d();
|
Polygon2d *p2d = dxf.toPolygon2d();
|
||||||
if (p2d) geometry = ClipperUtils::sanitize(*p2d);
|
if (p2d) geometry = ClipperUtils::sanitize(*p2d);
|
||||||
|
delete p2d;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
geometry = applyToChildren2D(node, OPENSCAD_UNION);
|
geometry = applyToChildren2D(node, OPENSCAD_UNION);
|
||||||
|
|
@ -954,6 +956,8 @@ Response GeometryEvaluator::visit(State &state, const ProjectionNode &node)
|
||||||
// Add correctly winded polygons to the main clipper
|
// Add correctly winded polygons to the main clipper
|
||||||
sumclipper.AddPaths(result, ClipperLib::ptSubject, true);
|
sumclipper.AddPaths(result, ClipperLib::ptSubject, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
delete poly;
|
||||||
}
|
}
|
||||||
ClipperLib::PolyTree sumresult;
|
ClipperLib::PolyTree sumresult;
|
||||||
// This is key - without StrictlySimple, we tend to get self-intersecting results
|
// This is key - without StrictlySimple, we tend to get self-intersecting results
|
||||||
|
|
|
||||||
|
|
@ -15,6 +15,7 @@
|
||||||
#include <QMutex>
|
#include <QMutex>
|
||||||
#include <QSet>
|
#include <QSet>
|
||||||
#include <QTime>
|
#include <QTime>
|
||||||
|
#include <QIODevice>
|
||||||
|
|
||||||
enum export_type_e {
|
enum export_type_e {
|
||||||
EXPORT_TYPE_UNKNOWN,
|
EXPORT_TYPE_UNKNOWN,
|
||||||
|
|
@ -35,7 +36,11 @@ public:
|
||||||
class Preferences *prefs;
|
class Preferences *prefs;
|
||||||
|
|
||||||
QTimer *animate_timer;
|
QTimer *animate_timer;
|
||||||
double tval, fps, fsteps;
|
int anim_step;
|
||||||
|
int anim_numsteps;
|
||||||
|
double anim_tval;
|
||||||
|
bool anim_dumping;
|
||||||
|
int anim_dump_start_step;
|
||||||
|
|
||||||
QTimer *autoReloadTimer;
|
QTimer *autoReloadTimer;
|
||||||
std::string autoReloadId;
|
std::string autoReloadId;
|
||||||
|
|
@ -88,7 +93,10 @@ protected:
|
||||||
void closeEvent(QCloseEvent *event);
|
void closeEvent(QCloseEvent *event);
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void updatedFps();
|
void updatedAnimTval();
|
||||||
|
void updatedAnimFps();
|
||||||
|
void updatedAnimSteps();
|
||||||
|
void updatedAnimDump(bool checked);
|
||||||
void updateTVal();
|
void updateTVal();
|
||||||
void updateMdiMode(bool mdi);
|
void updateMdiMode(bool mdi);
|
||||||
void updateUndockMode(bool undockMode);
|
void updateUndockMode(bool undockMode);
|
||||||
|
|
@ -113,6 +121,7 @@ private:
|
||||||
void compile(bool reload, bool forcedone = false);
|
void compile(bool reload, bool forcedone = false);
|
||||||
void compileCSG(bool procevents);
|
void compileCSG(bool procevents);
|
||||||
bool maybeSave();
|
bool maybeSave();
|
||||||
|
void saveError(const QIODevice &file, const std::string &msg);
|
||||||
bool checkEditorModified();
|
bool checkEditorModified();
|
||||||
QString dumpCSGTree(AbstractNode *root);
|
QString dumpCSGTree(AbstractNode *root);
|
||||||
static void consoleOutput(const std::string &msg, void *userdata);
|
static void consoleOutput(const std::string &msg, void *userdata);
|
||||||
|
|
@ -196,6 +205,7 @@ private slots:
|
||||||
void actionExportSVG();
|
void actionExportSVG();
|
||||||
void actionExportCSG();
|
void actionExportCSG();
|
||||||
void actionExportImage();
|
void actionExportImage();
|
||||||
|
void actionCopyViewport();
|
||||||
void actionFlushCaches();
|
void actionFlushCaches();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
|
||||||
|
|
@ -302,6 +302,8 @@
|
||||||
<addaction name="editActionCopy"/>
|
<addaction name="editActionCopy"/>
|
||||||
<addaction name="editActionPaste"/>
|
<addaction name="editActionPaste"/>
|
||||||
<addaction name="separator"/>
|
<addaction name="separator"/>
|
||||||
|
<addaction name="editActionCopyViewport"/>
|
||||||
|
<addaction name="separator"/>
|
||||||
<addaction name="editActionIndent"/>
|
<addaction name="editActionIndent"/>
|
||||||
<addaction name="editActionUnindent"/>
|
<addaction name="editActionUnindent"/>
|
||||||
<addaction name="editActionComment"/>
|
<addaction name="editActionComment"/>
|
||||||
|
|
@ -1261,6 +1263,14 @@
|
||||||
<string>&Cheat Sheet</string>
|
<string>&Cheat Sheet</string>
|
||||||
</property>
|
</property>
|
||||||
</action>
|
</action>
|
||||||
|
<action name="editActionCopyViewport">
|
||||||
|
<property name="text">
|
||||||
|
<string>Copy Viewport</string>
|
||||||
|
</property>
|
||||||
|
<property name="shortcut">
|
||||||
|
<string>Ctrl+Shift+C</string>
|
||||||
|
</property>
|
||||||
|
</action>
|
||||||
</widget>
|
</widget>
|
||||||
<customwidgets>
|
<customwidgets>
|
||||||
<customwidget>
|
<customwidget>
|
||||||
|
|
|
||||||
|
|
@ -237,6 +237,7 @@ bool create_glx_dummy_window(OffscreenContext &ctx)
|
||||||
// this call alters ctx->xDisplay and ctx->openGLContext
|
// this call alters ctx->xDisplay and ctx->openGLContext
|
||||||
// and ctx->xwindow if successfull
|
// and ctx->xwindow if successfull
|
||||||
if (!create_glx_dummy_context( *ctx )) {
|
if (!create_glx_dummy_context( *ctx )) {
|
||||||
|
delete ctx;
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -31,7 +31,6 @@
|
||||||
#include "stl-utils.h"
|
#include "stl-utils.h"
|
||||||
#ifdef ENABLE_OPENCSG
|
#ifdef ENABLE_OPENCSG
|
||||||
# include <opencsg.h>
|
# include <opencsg.h>
|
||||||
#endif
|
|
||||||
|
|
||||||
class OpenCSGPrim : public OpenCSG::Primitive
|
class OpenCSGPrim : public OpenCSG::Primitive
|
||||||
{
|
{
|
||||||
|
|
@ -49,6 +48,8 @@ public:
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
OpenCSGRenderer::OpenCSGRenderer(CSGChain *root_chain, CSGChain *highlights_chain,
|
OpenCSGRenderer::OpenCSGRenderer(CSGChain *root_chain, CSGChain *highlights_chain,
|
||||||
CSGChain *background_chain, GLint *shaderinfo)
|
CSGChain *background_chain, GLint *shaderinfo)
|
||||||
: root_chain(root_chain), highlights_chain(highlights_chain),
|
: root_chain(root_chain), highlights_chain(highlights_chain),
|
||||||
|
|
@ -74,6 +75,7 @@ void OpenCSGRenderer::draw(bool /*showfaces*/, bool showedges) const
|
||||||
void OpenCSGRenderer::renderCSGChain(CSGChain *chain, GLint *shaderinfo,
|
void OpenCSGRenderer::renderCSGChain(CSGChain *chain, GLint *shaderinfo,
|
||||||
bool highlight, bool background) const
|
bool highlight, bool background) const
|
||||||
{
|
{
|
||||||
|
#ifdef ENABLE_OPENCSG
|
||||||
std::vector<OpenCSG::Primitive*> primitives;
|
std::vector<OpenCSG::Primitive*> primitives;
|
||||||
size_t j = 0;
|
size_t j = 0;
|
||||||
for (size_t i = 0;; i++) {
|
for (size_t i = 0;; i++) {
|
||||||
|
|
@ -151,6 +153,7 @@ void OpenCSGRenderer::renderCSGChain(CSGChain *chain, GLint *shaderinfo,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
std::for_each(primitives.begin(), primitives.end(), del_fun<OpenCSG::Primitive>());
|
std::for_each(primitives.begin(), primitives.end(), del_fun<OpenCSG::Primitive>());
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
BoundingBox OpenCSGRenderer::getBoundingBox() const
|
BoundingBox OpenCSGRenderer::getBoundingBox() const
|
||||||
|
|
|
||||||
|
|
@ -23,7 +23,7 @@ const char *PlatformUtils::OPENSCAD_FOLDER_NAME = "OpenSCAD";
|
||||||
static std::string lookupResourcesPath()
|
static std::string lookupResourcesPath()
|
||||||
{
|
{
|
||||||
fs::path resourcedir(applicationpath);
|
fs::path resourcedir(applicationpath);
|
||||||
PRINTDB("Looking up resource folder with application path '%s'", resourcedir.c_str());
|
PRINTDB("Looking up resource folder with application path '%s'", boosty::stringy(resourcedir).c_str());
|
||||||
|
|
||||||
#ifdef __APPLE__
|
#ifdef __APPLE__
|
||||||
const char *searchpath[] = {
|
const char *searchpath[] = {
|
||||||
|
|
@ -33,7 +33,7 @@ static std::string lookupResourcesPath()
|
||||||
NULL
|
NULL
|
||||||
};
|
};
|
||||||
#else
|
#else
|
||||||
#ifdef WIN32
|
#ifdef _WIN32
|
||||||
const char *searchpath[] = {
|
const char *searchpath[] = {
|
||||||
".", // Release location
|
".", // Release location
|
||||||
RESOURCE_FOLDER("../share/openscad"), // MSYS2 location
|
RESOURCE_FOLDER("../share/openscad"), // MSYS2 location
|
||||||
|
|
@ -56,12 +56,14 @@ static std::string lookupResourcesPath()
|
||||||
for (int a = 0;searchpath[a] != NULL;a++) {
|
for (int a = 0;searchpath[a] != NULL;a++) {
|
||||||
tmpdir = resourcedir / searchpath[a];
|
tmpdir = resourcedir / searchpath[a];
|
||||||
|
|
||||||
const fs::path checkdir = tmpdir / "libraries";
|
// The resource folder is the folder which contains "color-schemes" (as well as
|
||||||
PRINTDB("Checking '%s'", checkdir.c_str());
|
// "examples" and "locale", and optionally "libraries" and "fonts")
|
||||||
|
const fs::path checkdir = tmpdir / "color-schemes";
|
||||||
|
PRINTDB("Checking '%s'", boosty::stringy(checkdir).c_str());
|
||||||
|
|
||||||
if (is_directory(checkdir)) {
|
if (is_directory(checkdir)) {
|
||||||
resourcedir = tmpdir;
|
resourcedir = tmpdir;
|
||||||
PRINTDB("Found resource folder '%s'", tmpdir.c_str());
|
PRINTDB("Found resource folder '%s'", boosty::stringy(tmpdir).c_str());
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -111,7 +113,9 @@ std::string PlatformUtils::userLibraryPath()
|
||||||
try {
|
try {
|
||||||
std::string pathstr = PlatformUtils::documentsPath();
|
std::string pathstr = PlatformUtils::documentsPath();
|
||||||
if (pathstr=="") return "";
|
if (pathstr=="") return "";
|
||||||
path = boosty::canonical(fs::path( pathstr ));
|
path = fs::path( pathstr );
|
||||||
|
if (!fs::exists(path)) return "";
|
||||||
|
path = boosty::canonical( path );
|
||||||
//PRINTB("path size %i",boosty::stringy(path).size());
|
//PRINTB("path size %i",boosty::stringy(path).size());
|
||||||
//PRINTB("lib path found: [%s]", path );
|
//PRINTB("lib path found: [%s]", path );
|
||||||
if (path.empty()) return "";
|
if (path.empty()) return "";
|
||||||
|
|
@ -132,7 +136,9 @@ std::string PlatformUtils::backupPath()
|
||||||
try {
|
try {
|
||||||
std::string pathstr = PlatformUtils::documentsPath();
|
std::string pathstr = PlatformUtils::documentsPath();
|
||||||
if (pathstr=="") return "";
|
if (pathstr=="") return "";
|
||||||
path = boosty::canonical(fs::path( pathstr ));
|
path = fs::path( pathstr );
|
||||||
|
if (!fs::exists(path)) return "";
|
||||||
|
path = boosty::canonical( path );
|
||||||
if (path.empty()) return "";
|
if (path.empty()) return "";
|
||||||
path /= OPENSCAD_FOLDER_NAME;
|
path /= OPENSCAD_FOLDER_NAME;
|
||||||
path /= "backups";
|
path /= "backups";
|
||||||
|
|
@ -185,7 +191,7 @@ fs::path PlatformUtils::resourcePath(const std::string &resource)
|
||||||
|
|
||||||
int PlatformUtils::setenv(const char *name, const char *value, int overwrite)
|
int PlatformUtils::setenv(const char *name, const char *value, int overwrite)
|
||||||
{
|
{
|
||||||
#if defined(WIN32)
|
#if defined(_WIN32)
|
||||||
const char *ptr = getenv(name);
|
const char *ptr = getenv(name);
|
||||||
if ((overwrite == 0) && (ptr != NULL)) {
|
if ((overwrite == 0) && (ptr != NULL)) {
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
||||||
|
|
@ -32,6 +32,7 @@
|
||||||
#include <QSettings>
|
#include <QSettings>
|
||||||
#include <QStatusBar>
|
#include <QStatusBar>
|
||||||
#include <boost/algorithm/string.hpp>
|
#include <boost/algorithm/string.hpp>
|
||||||
|
#include <boost/foreach.hpp>
|
||||||
#include "GeometryCache.h"
|
#include "GeometryCache.h"
|
||||||
#include "AutoUpdater.h"
|
#include "AutoUpdater.h"
|
||||||
#include "feature.h"
|
#include "feature.h"
|
||||||
|
|
@ -49,7 +50,7 @@ Q_DECLARE_METATYPE(Feature *);
|
||||||
class SettingsReader : public Settings::Visitor
|
class SettingsReader : public Settings::Visitor
|
||||||
{
|
{
|
||||||
QSettings settings;
|
QSettings settings;
|
||||||
const Value getValue(const Settings::SettingsEntry& entry, const std::string& value) const {
|
Value getValue(const Settings::SettingsEntry& entry, const std::string& value) const {
|
||||||
std::string trimmed_value(value);
|
std::string trimmed_value(value);
|
||||||
boost::trim(trimmed_value);
|
boost::trim(trimmed_value);
|
||||||
|
|
||||||
|
|
@ -101,7 +102,7 @@ class SettingsWriter : public Settings::Visitor
|
||||||
settings.remove(key);
|
settings.remove(key);
|
||||||
PRINTDB("SettingsWriter D: %s", key.toStdString().c_str());
|
PRINTDB("SettingsWriter D: %s", key.toStdString().c_str());
|
||||||
} else {
|
} else {
|
||||||
Value value = s->get(entry);
|
const Value &value = s->get(entry);
|
||||||
settings.setValue(key, QString::fromStdString(value.toString()));
|
settings.setValue(key, QString::fromStdString(value.toString()));
|
||||||
PRINTDB("SettingsWriter W: %s = '%s'", key.toStdString().c_str() % value.toString().c_str());
|
PRINTDB("SettingsWriter W: %s = '%s'", key.toStdString().c_str() % value.toString().c_str());
|
||||||
}
|
}
|
||||||
|
|
@ -689,18 +690,17 @@ void Preferences::updateGUI()
|
||||||
void Preferences::initComboBox(QComboBox *comboBox, const Settings::SettingsEntry& entry)
|
void Preferences::initComboBox(QComboBox *comboBox, const Settings::SettingsEntry& entry)
|
||||||
{
|
{
|
||||||
comboBox->clear();
|
comboBox->clear();
|
||||||
Value::VectorType vector = entry.range().toVector();
|
// Range is a vector of 2D vectors: [[name, value], ...]
|
||||||
for (Value::VectorType::iterator it = vector.begin();it != vector.end();it++) {
|
BOOST_FOREACH(const ValuePtr &v, entry.range().toVector()) {
|
||||||
QString val = QString::fromStdString((*it)[0].toString());
|
QString val = QString::fromStdString(v[0]->toString());
|
||||||
std::string text((*it)[1].toString());
|
QString qtext = QString::fromStdString(gettext(v[1]->toString().c_str()));
|
||||||
QString qtext = QString::fromStdString(gettext(text.c_str()));
|
|
||||||
comboBox->addItem(qtext, val);
|
comboBox->addItem(qtext, val);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Preferences::initSpinBox(QSpinBox *spinBox, const Settings::SettingsEntry& entry)
|
void Preferences::initSpinBox(QSpinBox *spinBox, const Settings::SettingsEntry& entry)
|
||||||
{
|
{
|
||||||
Value::RangeType range = entry.range().toRange();
|
RangeType range = entry.range().toRange();
|
||||||
spinBox->setMinimum(range.begin_value());
|
spinBox->setMinimum(range.begin_value());
|
||||||
spinBox->setMaximum(range.end_value());
|
spinBox->setMaximum(range.end_value());
|
||||||
}
|
}
|
||||||
|
|
@ -709,13 +709,13 @@ void Preferences::updateComboBox(QComboBox *comboBox, const Settings::SettingsEn
|
||||||
{
|
{
|
||||||
Settings::Settings *s = Settings::Settings::inst();
|
Settings::Settings *s = Settings::Settings::inst();
|
||||||
|
|
||||||
Value value = s->get(entry);
|
const Value &value = s->get(entry);
|
||||||
QString text = QString::fromStdString(value.toString());
|
QString text = QString::fromStdString(value.toString());
|
||||||
int idx = comboBox->findData(text);
|
int idx = comboBox->findData(text);
|
||||||
if (idx >= 0) {
|
if (idx >= 0) {
|
||||||
comboBox->setCurrentIndex(idx);
|
comboBox->setCurrentIndex(idx);
|
||||||
} else {
|
} else {
|
||||||
Value defaultValue = entry.defaultValue();
|
const Value &defaultValue = entry.defaultValue();
|
||||||
QString defaultText = QString::fromStdString(defaultValue.toString());
|
QString defaultText = QString::fromStdString(defaultValue.toString());
|
||||||
int defIdx = comboBox->findData(defaultText);
|
int defIdx = comboBox->findData(defaultText);
|
||||||
if (defIdx >= 0) {
|
if (defIdx >= 0) {
|
||||||
|
|
|
||||||
|
|
@ -1333,7 +1333,7 @@
|
||||||
<item>
|
<item>
|
||||||
<widget class="QCheckBox" name="mdiCheckBox">
|
<widget class="QCheckBox" name="mdiCheckBox">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Allow to open multiple documents</string>
|
<string>Allow opening multiple documents</string>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
|
|
||||||
|
|
@ -135,14 +135,11 @@ void QGLView::display_opencsg_warning_dialog()
|
||||||
message += _("It is highly recommended to use OpenSCAD on a system with "
|
message += _("It is highly recommended to use OpenSCAD on a system with "
|
||||||
"OpenGL 2.0 or later.\n"
|
"OpenGL 2.0 or later.\n"
|
||||||
"Your renderer information is as follows:\n");
|
"Your renderer information is as follows:\n");
|
||||||
QString rendererinfo;
|
QString rendererinfo(_("GLEW version %1\n%2 (%3)\nOpenGL version %4\n"));
|
||||||
rendererinfo.sprintf(_("GLEW version %s\n"
|
message += rendererinfo.arg((const char *)glewGetString(GLEW_VERSION),
|
||||||
"%s (%s)\n"
|
(const char *)glGetString(GL_RENDERER),
|
||||||
"OpenGL version %s\n"),
|
(const char *)glGetString(GL_VENDOR),
|
||||||
glewGetString(GLEW_VERSION),
|
(const char *)glGetString(GL_VERSION));
|
||||||
glGetString(GL_RENDERER), glGetString(GL_VENDOR),
|
|
||||||
glGetString(GL_VERSION));
|
|
||||||
message += rendererinfo;
|
|
||||||
|
|
||||||
dialog->setText(message);
|
dialog->setText(message);
|
||||||
dialog->enableOpenCSGBox->setChecked(Preferences::inst()->getValue("advanced/enable_opencsg_opengl1x").toBool());
|
dialog->enableOpenCSGBox->setChecked(Preferences::inst()->getValue("advanced/enable_opencsg_opengl1x").toBool());
|
||||||
|
|
@ -297,11 +294,12 @@ void QGLView::mouseReleaseEvent(QMouseEvent*)
|
||||||
releaseMouse();
|
releaseMouse();
|
||||||
}
|
}
|
||||||
|
|
||||||
void QGLView::grabFrame()
|
const QImage & QGLView::grabFrame()
|
||||||
{
|
{
|
||||||
// Force reading from front buffer. Some configurations will read from the back buffer here.
|
// Force reading from front buffer. Some configurations will read from the back buffer here.
|
||||||
glReadBuffer(GL_FRONT);
|
glReadBuffer(GL_FRONT);
|
||||||
this->frame = grabFrameBuffer();
|
this->frame = grabFrameBuffer();
|
||||||
|
return this->frame;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool QGLView::save(const char *filename)
|
bool QGLView::save(const char *filename)
|
||||||
|
|
|
||||||
|
|
@ -43,7 +43,7 @@ public:
|
||||||
float getDPI() { return this->devicePixelRatio(); }
|
float getDPI() { return this->devicePixelRatio(); }
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void grabFrame();
|
const QImage & grabFrame();
|
||||||
bool save(const char *filename);
|
bool save(const char *filename);
|
||||||
void resetView();
|
void resetView();
|
||||||
void viewAll();
|
void viewAll();
|
||||||
|
|
|
||||||
|
|
@ -8,3 +8,42 @@ namespace fs = boost::filesystem;
|
||||||
fs::path boostfs_relative_path(const fs::path &path, const fs::path &relative_to);
|
fs::path boostfs_relative_path(const fs::path &path, const fs::path &relative_to);
|
||||||
fs::path boostfs_normalize(const fs::path &path);
|
fs::path boostfs_normalize(const fs::path &path);
|
||||||
fs::path boostfs_uncomplete(fs::path const p, fs::path const base);
|
fs::path boostfs_uncomplete(fs::path const p, fs::path const base);
|
||||||
|
|
||||||
|
#include <boost/cast.hpp>
|
||||||
|
#include <sstream>
|
||||||
|
|
||||||
|
/* Convert number types but print WARNING for failures during
|
||||||
|
conversion. This is useful for situations where it is important to not
|
||||||
|
fail silently during casting or conversion. (For example, accidentally
|
||||||
|
converting 64 bit types to 32 bit types, float to int, etc).
|
||||||
|
For positive overflow, return max of Tout template type
|
||||||
|
For negative overflow, return min of Tout template type
|
||||||
|
On other conversion failures, return 0. */
|
||||||
|
template <class Tout,class Tin> Tout boost_numeric_cast( Tin input )
|
||||||
|
{
|
||||||
|
Tout result = 0;
|
||||||
|
std::stringstream status;
|
||||||
|
status.str("ok");
|
||||||
|
try {
|
||||||
|
result = boost::numeric_cast<Tout>(input);
|
||||||
|
} catch (boost::numeric::negative_overflow& e) {
|
||||||
|
status << e.what();
|
||||||
|
result = std::numeric_limits<Tout>::min();
|
||||||
|
} catch (boost::numeric::positive_overflow& e) {
|
||||||
|
status << e.what();
|
||||||
|
result = std::numeric_limits<Tout>::max();
|
||||||
|
} catch (boost::numeric::bad_numeric_cast& e) {
|
||||||
|
status << e.what();
|
||||||
|
result = 0;
|
||||||
|
}
|
||||||
|
if (status.str()!="ok") {
|
||||||
|
std::stringstream tmp;
|
||||||
|
tmp << input;
|
||||||
|
PRINTB("WARNING: problem converting this number: %s",tmp.str());
|
||||||
|
PRINTB("WARNING: %s", status.str() );
|
||||||
|
PRINTB("WARNING: setting result to %u",result);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -101,9 +101,9 @@ Builtins::Builtins()
|
||||||
this->globalscope.assignments.push_back(Assignment("$t", boost::shared_ptr<Expression>(new ExpressionConst(ValuePtr(0.0)))));
|
this->globalscope.assignments.push_back(Assignment("$t", boost::shared_ptr<Expression>(new ExpressionConst(ValuePtr(0.0)))));
|
||||||
|
|
||||||
Value::VectorType zero3;
|
Value::VectorType zero3;
|
||||||
zero3.push_back(Value(0.0));
|
zero3.push_back(ValuePtr(0.0));
|
||||||
zero3.push_back(Value(0.0));
|
zero3.push_back(ValuePtr(0.0));
|
||||||
zero3.push_back(Value(0.0));
|
zero3.push_back(ValuePtr(0.0));
|
||||||
ValuePtr zero3val(zero3);
|
ValuePtr zero3val(zero3);
|
||||||
this->globalscope.assignments.push_back(Assignment("$vpt", boost::shared_ptr<Expression>(new ExpressionConst(zero3val))));
|
this->globalscope.assignments.push_back(Assignment("$vpt", boost::shared_ptr<Expression>(new ExpressionConst(zero3val))));
|
||||||
this->globalscope.assignments.push_back(Assignment("$vpr", boost::shared_ptr<Expression>(new ExpressionConst(zero3val))));
|
this->globalscope.assignments.push_back(Assignment("$vpr", boost::shared_ptr<Expression>(new ExpressionConst(zero3val))));
|
||||||
|
|
|
||||||
|
|
@ -89,17 +89,17 @@ AbstractNode *CgaladvModule::instantiate(const Context *ctx, const ModuleInstant
|
||||||
node->newsize << 0,0,0;
|
node->newsize << 0,0,0;
|
||||||
if ( ns->type() == Value::VECTOR ) {
|
if ( ns->type() == Value::VECTOR ) {
|
||||||
const Value::VectorType &vs = ns->toVector();
|
const Value::VectorType &vs = ns->toVector();
|
||||||
if ( vs.size() >= 1 ) node->newsize[0] = vs[0].toDouble();
|
if ( vs.size() >= 1 ) node->newsize[0] = vs[0]->toDouble();
|
||||||
if ( vs.size() >= 2 ) node->newsize[1] = vs[1].toDouble();
|
if ( vs.size() >= 2 ) node->newsize[1] = vs[1]->toDouble();
|
||||||
if ( vs.size() >= 3 ) node->newsize[2] = vs[2].toDouble();
|
if ( vs.size() >= 3 ) node->newsize[2] = vs[2]->toDouble();
|
||||||
}
|
}
|
||||||
ValuePtr autosize = c.lookup_variable("auto");
|
ValuePtr autosize = c.lookup_variable("auto");
|
||||||
node->autosize << false, false, false;
|
node->autosize << false, false, false;
|
||||||
if ( autosize->type() == Value::VECTOR ) {
|
if ( autosize->type() == Value::VECTOR ) {
|
||||||
const Value::VectorType &va = autosize->toVector();
|
const Value::VectorType &va = autosize->toVector();
|
||||||
if ( va.size() >= 1 ) node->autosize[0] = va[0].toBool();
|
if ( va.size() >= 1 ) node->autosize[0] = va[0]->toBool();
|
||||||
if ( va.size() >= 2 ) node->autosize[1] = va[1].toBool();
|
if ( va.size() >= 2 ) node->autosize[1] = va[1]->toBool();
|
||||||
if ( va.size() >= 3 ) node->autosize[2] = va[2].toBool();
|
if ( va.size() >= 3 ) node->autosize[2] = va[2]->toBool();
|
||||||
}
|
}
|
||||||
else if ( autosize->type() == Value::BOOL ) {
|
else if ( autosize->type() == Value::BOOL ) {
|
||||||
node->autosize << autosize->toBool(),autosize->toBool(),autosize->toBool();
|
node->autosize << autosize->toBool(),autosize->toBool(),autosize->toBool();
|
||||||
|
|
|
||||||
422
src/cgalutils-applyops.cc
Normal file
422
src/cgalutils-applyops.cc
Normal file
|
|
@ -0,0 +1,422 @@
|
||||||
|
// this file is split into many separate cgalutils* files
|
||||||
|
// in order to workaround gcc 4.9.1 crashing on systems with only 2GB of RAM
|
||||||
|
|
||||||
|
#ifdef ENABLE_CGAL
|
||||||
|
|
||||||
|
#include "cgalutils.h"
|
||||||
|
#include "polyset.h"
|
||||||
|
#include "printutils.h"
|
||||||
|
#include "Polygon2d.h"
|
||||||
|
#include "polyset-utils.h"
|
||||||
|
#include "grid.h"
|
||||||
|
#include "node.h"
|
||||||
|
|
||||||
|
#include "cgal.h"
|
||||||
|
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
|
||||||
|
#include <CGAL/normal_vector_newell_3.h>
|
||||||
|
#include <CGAL/Handle_hash_function.h>
|
||||||
|
|
||||||
|
#include <CGAL/config.h>
|
||||||
|
#include <CGAL/version.h>
|
||||||
|
|
||||||
|
// Apply CGAL bugfix for CGAL-4.5.x
|
||||||
|
#if CGAL_VERSION_NR > CGAL_VERSION_NUMBER(4,5,1) || CGAL_VERSION_NR < CGAL_VERSION_NUMBER(4,5,0)
|
||||||
|
#include <CGAL/convex_hull_3.h>
|
||||||
|
#else
|
||||||
|
#include "convex_hull_3_bugfix.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "svg.h"
|
||||||
|
#include "Reindexer.h"
|
||||||
|
#include "GeometryUtils.h"
|
||||||
|
|
||||||
|
#include <map>
|
||||||
|
#include <queue>
|
||||||
|
#include <boost/foreach.hpp>
|
||||||
|
#include <boost/unordered_set.hpp>
|
||||||
|
|
||||||
|
namespace CGALUtils {
|
||||||
|
|
||||||
|
template<typename Polyhedron>
|
||||||
|
bool is_weakly_convex(Polyhedron const& p) {
|
||||||
|
for (typename Polyhedron::Edge_const_iterator i = p.edges_begin(); i != p.edges_end(); ++i) {
|
||||||
|
typename Polyhedron::Plane_3 p(i->opposite()->vertex()->point(), i->vertex()->point(), i->next()->vertex()->point());
|
||||||
|
if (p.has_on_positive_side(i->opposite()->next()->vertex()->point()) &&
|
||||||
|
CGAL::squared_distance(p, i->opposite()->next()->vertex()->point()) > 1e-8) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Also make sure that there is only one shell:
|
||||||
|
boost::unordered_set<typename Polyhedron::Facet_const_handle, typename CGAL::Handle_hash_function> visited;
|
||||||
|
// c++11
|
||||||
|
// visited.reserve(p.size_of_facets());
|
||||||
|
|
||||||
|
std::queue<typename Polyhedron::Facet_const_handle> to_explore;
|
||||||
|
to_explore.push(p.facets_begin()); // One arbitrary facet
|
||||||
|
visited.insert(to_explore.front());
|
||||||
|
|
||||||
|
while (!to_explore.empty()) {
|
||||||
|
typename Polyhedron::Facet_const_handle f = to_explore.front();
|
||||||
|
to_explore.pop();
|
||||||
|
typename Polyhedron::Facet::Halfedge_around_facet_const_circulator he, end;
|
||||||
|
end = he = f->facet_begin();
|
||||||
|
CGAL_For_all(he,end) {
|
||||||
|
typename Polyhedron::Facet_const_handle o = he->opposite()->facet();
|
||||||
|
|
||||||
|
if (!visited.count(o)) {
|
||||||
|
visited.insert(o);
|
||||||
|
to_explore.push(o);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return visited.size() == p.size_of_facets();
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
Applies op to all children and returns the result.
|
||||||
|
The child list should be guaranteed to contain non-NULL 3D or empty Geometry objects
|
||||||
|
*/
|
||||||
|
CGAL_Nef_polyhedron *applyOperator(const Geometry::ChildList &children, OpenSCADOperator op)
|
||||||
|
{
|
||||||
|
CGAL_Nef_polyhedron *N = NULL;
|
||||||
|
CGAL::Failure_behaviour old_behaviour = CGAL::set_error_behaviour(CGAL::THROW_EXCEPTION);
|
||||||
|
try {
|
||||||
|
// Speeds up n-ary union operations significantly
|
||||||
|
CGAL::Nef_nary_union_3<CGAL_Nef_polyhedron3> nary_union;
|
||||||
|
int nary_union_num_inserted = 0;
|
||||||
|
|
||||||
|
BOOST_FOREACH(const Geometry::ChildItem &item, children) {
|
||||||
|
const shared_ptr<const Geometry> &chgeom = item.second;
|
||||||
|
shared_ptr<const CGAL_Nef_polyhedron> chN =
|
||||||
|
dynamic_pointer_cast<const CGAL_Nef_polyhedron>(chgeom);
|
||||||
|
if (!chN) {
|
||||||
|
const PolySet *chps = dynamic_cast<const PolySet*>(chgeom.get());
|
||||||
|
if (chps) chN.reset(createNefPolyhedronFromGeometry(*chps));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (op == OPENSCAD_UNION) {
|
||||||
|
if (!chN->isEmpty()) {
|
||||||
|
// nary_union.add_polyhedron() can issue assertion errors:
|
||||||
|
// https://github.com/openscad/openscad/issues/802
|
||||||
|
nary_union.add_polyhedron(*chN->p3);
|
||||||
|
nary_union_num_inserted++;
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
// Initialize N with first expected geometric object
|
||||||
|
if (!N) {
|
||||||
|
N = new CGAL_Nef_polyhedron(*chN);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Intersecting something with nothing results in nothing
|
||||||
|
if (chN->isEmpty()) {
|
||||||
|
if (op == OPENSCAD_INTERSECTION) *N = *chN;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// empty op <something> => empty
|
||||||
|
if (N->isEmpty()) continue;
|
||||||
|
|
||||||
|
switch (op) {
|
||||||
|
case OPENSCAD_INTERSECTION:
|
||||||
|
*N *= *chN;
|
||||||
|
break;
|
||||||
|
case OPENSCAD_DIFFERENCE:
|
||||||
|
*N -= *chN;
|
||||||
|
break;
|
||||||
|
case OPENSCAD_MINKOWSKI:
|
||||||
|
N->minkowski(*chN);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
PRINTB("ERROR: Unsupported CGAL operator: %d", op);
|
||||||
|
}
|
||||||
|
item.first->progress_report();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (op == OPENSCAD_UNION && nary_union_num_inserted > 0) {
|
||||||
|
N = new CGAL_Nef_polyhedron(new CGAL_Nef_polyhedron3(nary_union.get_union()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// union && difference assert triggered by testdata/scad/bugs/rotate-diff-nonmanifold-crash.scad and testdata/scad/bugs/issue204.scad
|
||||||
|
catch (const CGAL::Failure_exception &e) {
|
||||||
|
std::string opstr = op == OPENSCAD_INTERSECTION ? "intersection" : op == OPENSCAD_DIFFERENCE ? "difference" : op == OPENSCAD_UNION ? "union" : "UNKNOWN";
|
||||||
|
PRINTB("ERROR: CGAL error in CGALUtils::applyBinaryOperator %s: %s", opstr % e.what());
|
||||||
|
}
|
||||||
|
CGAL::set_error_behaviour(old_behaviour);
|
||||||
|
return N;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
bool applyHull(const Geometry::ChildList &children, PolySet &result)
|
||||||
|
{
|
||||||
|
typedef CGAL::Epick K;
|
||||||
|
// Collect point cloud
|
||||||
|
// NB! CGAL's convex_hull_3() doesn't like std::set iterators, so we use a list
|
||||||
|
// instead.
|
||||||
|
std::list<K::Point_3> points;
|
||||||
|
|
||||||
|
BOOST_FOREACH(const Geometry::ChildItem &item, children) {
|
||||||
|
const shared_ptr<const Geometry> &chgeom = item.second;
|
||||||
|
const CGAL_Nef_polyhedron *N = dynamic_cast<const CGAL_Nef_polyhedron *>(chgeom.get());
|
||||||
|
if (N) {
|
||||||
|
if (!N->isEmpty()) {
|
||||||
|
for (CGAL_Nef_polyhedron3::Vertex_const_iterator i = N->p3->vertices_begin(); i != N->p3->vertices_end(); ++i) {
|
||||||
|
points.push_back(vector_convert<K::Point_3>(i->point()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
const PolySet *ps = dynamic_cast<const PolySet *>(chgeom.get());
|
||||||
|
if (ps) {
|
||||||
|
BOOST_FOREACH(const Polygon &p, ps->polygons) {
|
||||||
|
BOOST_FOREACH(const Vector3d &v, p) {
|
||||||
|
points.push_back(K::Point_3(v[0], v[1], v[2]));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (points.size() <= 3) return false;
|
||||||
|
|
||||||
|
// Apply hull
|
||||||
|
bool success = false;
|
||||||
|
if (points.size() >= 4) {
|
||||||
|
CGAL::Failure_behaviour old_behaviour = CGAL::set_error_behaviour(CGAL::THROW_EXCEPTION);
|
||||||
|
try {
|
||||||
|
CGAL::Polyhedron_3<K> r;
|
||||||
|
CGAL::convex_hull_3(points.begin(), points.end(), r);
|
||||||
|
PRINTDB("After hull vertices: %d", r.size_of_vertices());
|
||||||
|
PRINTDB("After hull facets: %d", r.size_of_facets());
|
||||||
|
PRINTDB("After hull closed: %d", r.is_closed());
|
||||||
|
PRINTDB("After hull valid: %d", r.is_valid());
|
||||||
|
success = !createPolySetFromPolyhedron(r, result);
|
||||||
|
}
|
||||||
|
catch (const CGAL::Assertion_exception &e) {
|
||||||
|
PRINTB("ERROR: CGAL error in applyHull(): %s", e.what());
|
||||||
|
}
|
||||||
|
CGAL::set_error_behaviour(old_behaviour);
|
||||||
|
}
|
||||||
|
return success;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
children cannot contain NULL objects
|
||||||
|
*/
|
||||||
|
Geometry const * applyMinkowski(const Geometry::ChildList &children)
|
||||||
|
{
|
||||||
|
CGAL::Timer t,t_tot;
|
||||||
|
assert(children.size() >= 2);
|
||||||
|
Geometry::ChildList::const_iterator it = children.begin();
|
||||||
|
t_tot.start();
|
||||||
|
Geometry const* operands[2] = {it->second.get(), NULL};
|
||||||
|
try {
|
||||||
|
while (++it != children.end()) {
|
||||||
|
operands[1] = it->second.get();
|
||||||
|
|
||||||
|
typedef CGAL::Epick Hull_kernel;
|
||||||
|
|
||||||
|
std::list<CGAL_Polyhedron> P[2];
|
||||||
|
std::list<CGAL::Polyhedron_3<Hull_kernel> > result_parts;
|
||||||
|
|
||||||
|
for (size_t i = 0; i < 2; i++) {
|
||||||
|
CGAL_Polyhedron poly;
|
||||||
|
|
||||||
|
const PolySet * ps = dynamic_cast<const PolySet *>(operands[i]);
|
||||||
|
|
||||||
|
const CGAL_Nef_polyhedron * nef = dynamic_cast<const CGAL_Nef_polyhedron *>(operands[i]);
|
||||||
|
|
||||||
|
if (ps) CGALUtils::createPolyhedronFromPolySet(*ps, poly);
|
||||||
|
else if (nef && nef->p3->is_simple()) nefworkaround::convert_to_Polyhedron<CGAL_Kernel3>(*nef->p3, poly);
|
||||||
|
else throw 0;
|
||||||
|
|
||||||
|
if ((ps && ps->is_convex()) ||
|
||||||
|
(!ps && is_weakly_convex(poly))) {
|
||||||
|
PRINTDB("Minkowski: child %d is convex and %s",i % (ps?"PolySet":"Nef"));
|
||||||
|
P[i].push_back(poly);
|
||||||
|
} else {
|
||||||
|
CGAL_Nef_polyhedron3 decomposed_nef;
|
||||||
|
|
||||||
|
if (ps) {
|
||||||
|
PRINTDB("Minkowski: child %d is nonconvex PolySet, transforming to Nef and decomposing...", i);
|
||||||
|
CGAL_Nef_polyhedron *p = createNefPolyhedronFromGeometry(*ps);
|
||||||
|
if (!p->isEmpty()) decomposed_nef = *p->p3;
|
||||||
|
delete p;
|
||||||
|
} else {
|
||||||
|
PRINTDB("Minkowski: child %d is nonconvex Nef, decomposing...",i);
|
||||||
|
decomposed_nef = *nef->p3;
|
||||||
|
}
|
||||||
|
|
||||||
|
t.start();
|
||||||
|
CGAL::convex_decomposition_3(decomposed_nef);
|
||||||
|
|
||||||
|
// the first volume is the outer volume, which ignored in the decomposition
|
||||||
|
CGAL_Nef_polyhedron3::Volume_const_iterator ci = ++decomposed_nef.volumes_begin();
|
||||||
|
for(; ci != decomposed_nef.volumes_end(); ++ci) {
|
||||||
|
if(ci->mark()) {
|
||||||
|
CGAL_Polyhedron poly;
|
||||||
|
decomposed_nef.convert_inner_shell_to_polyhedron(ci->shells_begin(), poly);
|
||||||
|
P[i].push_back(poly);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
PRINTDB("Minkowski: decomposed into %d convex parts", P[i].size());
|
||||||
|
t.stop();
|
||||||
|
PRINTDB("Minkowski: decomposition took %f s", t.time());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<Hull_kernel::Point_3> points[2];
|
||||||
|
std::vector<Hull_kernel::Point_3> minkowski_points;
|
||||||
|
|
||||||
|
for (size_t i = 0; i < P[0].size(); i++) {
|
||||||
|
for (size_t j = 0; j < P[1].size(); j++) {
|
||||||
|
t.start();
|
||||||
|
points[0].clear();
|
||||||
|
points[1].clear();
|
||||||
|
|
||||||
|
for (int k = 0; k < 2; k++) {
|
||||||
|
std::list<CGAL_Polyhedron>::iterator it = P[k].begin();
|
||||||
|
std::advance(it, k==0?i:j);
|
||||||
|
|
||||||
|
CGAL_Polyhedron const& poly = *it;
|
||||||
|
points[k].reserve(poly.size_of_vertices());
|
||||||
|
|
||||||
|
for (CGAL_Polyhedron::Vertex_const_iterator pi = poly.vertices_begin(); pi != poly.vertices_end(); ++pi) {
|
||||||
|
CGAL_Polyhedron::Point_3 const& p = pi->point();
|
||||||
|
points[k].push_back(Hull_kernel::Point_3(to_double(p[0]),to_double(p[1]),to_double(p[2])));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
minkowski_points.clear();
|
||||||
|
minkowski_points.reserve(points[0].size() * points[1].size());
|
||||||
|
for (size_t i = 0; i < points[0].size(); i++) {
|
||||||
|
for (size_t j = 0; j < points[1].size(); j++) {
|
||||||
|
minkowski_points.push_back(points[0][i]+(points[1][j]-CGAL::ORIGIN));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (minkowski_points.size() <= 3) {
|
||||||
|
t.stop();
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
CGAL::Polyhedron_3<Hull_kernel> result;
|
||||||
|
t.stop();
|
||||||
|
PRINTDB("Minkowski: Point cloud creation (%d ⨉ %d -> %d) took %f ms", points[0].size() % points[1].size() % minkowski_points.size() % (t.time()*1000));
|
||||||
|
t.reset();
|
||||||
|
|
||||||
|
t.start();
|
||||||
|
|
||||||
|
CGAL::convex_hull_3(minkowski_points.begin(), minkowski_points.end(), result);
|
||||||
|
|
||||||
|
std::vector<Hull_kernel::Point_3> strict_points;
|
||||||
|
strict_points.reserve(minkowski_points.size());
|
||||||
|
|
||||||
|
for (CGAL::Polyhedron_3<Hull_kernel>::Vertex_iterator i = result.vertices_begin(); i != result.vertices_end(); ++i) {
|
||||||
|
Hull_kernel::Point_3 const& p = i->point();
|
||||||
|
|
||||||
|
CGAL::Polyhedron_3<Hull_kernel>::Vertex::Halfedge_handle h,e;
|
||||||
|
h = i->halfedge();
|
||||||
|
e = h;
|
||||||
|
bool collinear = false;
|
||||||
|
bool coplanar = true;
|
||||||
|
|
||||||
|
do {
|
||||||
|
Hull_kernel::Point_3 const& q = h->opposite()->vertex()->point();
|
||||||
|
if (coplanar && !CGAL::coplanar(p,q,
|
||||||
|
h->next_on_vertex()->opposite()->vertex()->point(),
|
||||||
|
h->next_on_vertex()->next_on_vertex()->opposite()->vertex()->point())) {
|
||||||
|
coplanar = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
for (CGAL::Polyhedron_3<Hull_kernel>::Vertex::Halfedge_handle j = h->next_on_vertex();
|
||||||
|
j != h && !collinear && ! coplanar;
|
||||||
|
j = j->next_on_vertex()) {
|
||||||
|
|
||||||
|
Hull_kernel::Point_3 const& r = j->opposite()->vertex()->point();
|
||||||
|
if (CGAL::collinear(p,q,r)) {
|
||||||
|
collinear = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
h = h->next_on_vertex();
|
||||||
|
} while (h != e && !collinear);
|
||||||
|
|
||||||
|
if (!collinear && !coplanar)
|
||||||
|
strict_points.push_back(p);
|
||||||
|
}
|
||||||
|
|
||||||
|
result.clear();
|
||||||
|
CGAL::convex_hull_3(strict_points.begin(), strict_points.end(), result);
|
||||||
|
|
||||||
|
|
||||||
|
t.stop();
|
||||||
|
PRINTDB("Minkowski: Computing convex hull took %f s", t.time());
|
||||||
|
t.reset();
|
||||||
|
|
||||||
|
result_parts.push_back(result);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (it != boost::next(children.begin()))
|
||||||
|
delete operands[0];
|
||||||
|
|
||||||
|
if (result_parts.size() == 1) {
|
||||||
|
PolySet *ps = new PolySet(3,true);
|
||||||
|
createPolySetFromPolyhedron(*result_parts.begin(), *ps);
|
||||||
|
operands[0] = ps;
|
||||||
|
} else if (!result_parts.empty()) {
|
||||||
|
t.start();
|
||||||
|
PRINTDB("Minkowski: Computing union of %d parts",result_parts.size());
|
||||||
|
Geometry::ChildList fake_children;
|
||||||
|
for (std::list<CGAL::Polyhedron_3<Hull_kernel> >::iterator i = result_parts.begin(); i != result_parts.end(); ++i) {
|
||||||
|
PolySet ps(3,true);
|
||||||
|
createPolySetFromPolyhedron(*i, ps);
|
||||||
|
fake_children.push_back(std::make_pair((const AbstractNode*)NULL,
|
||||||
|
shared_ptr<const Geometry>(createNefPolyhedronFromGeometry(ps))));
|
||||||
|
}
|
||||||
|
CGAL_Nef_polyhedron *N = CGALUtils::applyOperator(fake_children, OPENSCAD_UNION);
|
||||||
|
// FIXME: This hould really never throw.
|
||||||
|
// Assert once we figured out what went wrong with issue #1069?
|
||||||
|
if (!N) throw 0;
|
||||||
|
t.stop();
|
||||||
|
PRINTDB("Minkowski: Union done: %f s",t.time());
|
||||||
|
t.reset();
|
||||||
|
operands[0] = N;
|
||||||
|
} else {
|
||||||
|
operands[0] = new CGAL_Nef_polyhedron();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
t_tot.stop();
|
||||||
|
PRINTDB("Minkowski: Total execution time %f s", t_tot.time());
|
||||||
|
t_tot.reset();
|
||||||
|
return operands[0];
|
||||||
|
}
|
||||||
|
catch (...) {
|
||||||
|
// If anything throws we simply fall back to Nef Minkowski
|
||||||
|
PRINTD("Minkowski: Falling back to Nef Minkowski");
|
||||||
|
|
||||||
|
CGAL_Nef_polyhedron *N = applyOperator(children, OPENSCAD_MINKOWSKI);
|
||||||
|
return N;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}; // namespace CGALUtils
|
||||||
|
|
||||||
|
|
||||||
|
#endif // ENABLE_CGAL
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -11,13 +11,8 @@
|
||||||
|
|
||||||
#include <boost/foreach.hpp>
|
#include <boost/foreach.hpp>
|
||||||
|
|
||||||
namespace /* anonymous */ {
|
|
||||||
template<typename Result, typename V>
|
|
||||||
Result vector_convert(V const& v) {
|
|
||||||
return Result(CGAL::to_double(v[0]),CGAL::to_double(v[1]),CGAL::to_double(v[2]));
|
|
||||||
}
|
|
||||||
|
|
||||||
#undef GEN_SURFACE_DEBUG
|
#undef GEN_SURFACE_DEBUG
|
||||||
|
namespace /* anonymous */ {
|
||||||
|
|
||||||
template <typename Polyhedron>
|
template <typename Polyhedron>
|
||||||
class CGAL_Build_PolySet : public CGAL::Modifier_base<typename Polyhedron::HalfedgeDS>
|
class CGAL_Build_PolySet : public CGAL::Modifier_base<typename Polyhedron::HalfedgeDS>
|
||||||
|
|
|
||||||
266
src/cgalutils-project.cc
Normal file
266
src/cgalutils-project.cc
Normal file
|
|
@ -0,0 +1,266 @@
|
||||||
|
// this file is split into many separate cgalutils* files
|
||||||
|
// in order to workaround gcc 4.9.1 crashing on systems with only 2GB of RAM
|
||||||
|
|
||||||
|
#ifdef ENABLE_CGAL
|
||||||
|
|
||||||
|
#include "cgalutils.h"
|
||||||
|
#include "polyset.h"
|
||||||
|
#include "printutils.h"
|
||||||
|
#include "Polygon2d.h"
|
||||||
|
#include "polyset-utils.h"
|
||||||
|
#include "grid.h"
|
||||||
|
#include "node.h"
|
||||||
|
|
||||||
|
#include "cgal.h"
|
||||||
|
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
|
||||||
|
#include <CGAL/normal_vector_newell_3.h>
|
||||||
|
#include <CGAL/Handle_hash_function.h>
|
||||||
|
|
||||||
|
#include <CGAL/config.h>
|
||||||
|
#include <CGAL/version.h>
|
||||||
|
|
||||||
|
// Apply CGAL bugfix for CGAL-4.5.x
|
||||||
|
#if CGAL_VERSION_NR > CGAL_VERSION_NUMBER(4,5,1) || CGAL_VERSION_NR < CGAL_VERSION_NUMBER(4,5,0)
|
||||||
|
#include <CGAL/convex_hull_3.h>
|
||||||
|
#else
|
||||||
|
#include "convex_hull_3_bugfix.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "svg.h"
|
||||||
|
#include "Reindexer.h"
|
||||||
|
#include "GeometryUtils.h"
|
||||||
|
|
||||||
|
#include <map>
|
||||||
|
#include <queue>
|
||||||
|
#include <boost/foreach.hpp>
|
||||||
|
#include <boost/unordered_set.hpp>
|
||||||
|
|
||||||
|
|
||||||
|
static void add_outline_to_poly(CGAL_Nef_polyhedron2::Explorer &explorer,
|
||||||
|
CGAL_Nef_polyhedron2::Explorer::Halfedge_around_face_const_circulator circ,
|
||||||
|
CGAL_Nef_polyhedron2::Explorer::Halfedge_around_face_const_circulator end,
|
||||||
|
bool positive,
|
||||||
|
Polygon2d *poly) {
|
||||||
|
Outline2d outline;
|
||||||
|
|
||||||
|
CGAL_For_all(circ, end) {
|
||||||
|
if (explorer.is_standard(explorer.target(circ))) {
|
||||||
|
CGAL_Nef_polyhedron2::Explorer::Point ep = explorer.point(explorer.target(circ));
|
||||||
|
outline.vertices.push_back(Vector2d(to_double(ep.x()),
|
||||||
|
to_double(ep.y())));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!outline.vertices.empty()) {
|
||||||
|
outline.positive = positive;
|
||||||
|
poly->addOutline(outline);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static Polygon2d *convertToPolygon2d(const CGAL_Nef_polyhedron2 &p2)
|
||||||
|
{
|
||||||
|
Polygon2d *poly = new Polygon2d;
|
||||||
|
|
||||||
|
typedef CGAL_Nef_polyhedron2::Explorer Explorer;
|
||||||
|
typedef Explorer::Face_const_iterator fci_t;
|
||||||
|
typedef Explorer::Halfedge_around_face_const_circulator heafcc_t;
|
||||||
|
Explorer E = p2.explorer();
|
||||||
|
for (fci_t fit = E.faces_begin(), facesend = E.faces_end(); fit != facesend; ++fit) {
|
||||||
|
if (!fit->mark()) continue;
|
||||||
|
heafcc_t fcirc(E.face_cycle(fit)), fend(fcirc);
|
||||||
|
add_outline_to_poly(E, fcirc, fend, true, poly);
|
||||||
|
for (CGAL_Nef_polyhedron2::Explorer::Hole_const_iterator j = E.holes_begin(fit);j != E.holes_end(fit); ++j) {
|
||||||
|
CGAL_Nef_polyhedron2::Explorer::Halfedge_around_face_const_circulator hcirc(j), hend(hcirc);
|
||||||
|
add_outline_to_poly(E, hcirc, hend, false, poly);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
poly->setSanitized(true);
|
||||||
|
return poly;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
|
||||||
|
ZRemover
|
||||||
|
|
||||||
|
This class converts one or more Nef3 polyhedra into a Nef2 polyhedron by
|
||||||
|
stripping off the 'z' coordinates from the vertices. The resulting Nef2
|
||||||
|
poly is accumulated in the 'output_nefpoly2d' member variable.
|
||||||
|
|
||||||
|
The 'z' coordinates will either be all 0s, for an xy-plane intersected Nef3,
|
||||||
|
or, they will be a mixture of -eps and +eps, for a thin-box intersected Nef3.
|
||||||
|
|
||||||
|
Notes on CGAL's Nef Polyhedron2:
|
||||||
|
|
||||||
|
1. The 'mark' on a 2d Nef face is important when doing unions/intersections.
|
||||||
|
If the 'mark' of a face is wrong the resulting nef2 poly will be unexpected.
|
||||||
|
2. The 'mark' can be dependent on the points fed to the Nef2 constructor.
|
||||||
|
This is why we iterate through the 3d faces using the halfedge cycle
|
||||||
|
source()->target() instead of the ordinary source()->source(). The
|
||||||
|
the latter can generate sequences of points that will fail the
|
||||||
|
the CGAL::is_simple_2() test, resulting in improperly marked nef2 polys.
|
||||||
|
3. 3d facets have 'two sides'. we throw out the 'down' side to prevent dups.
|
||||||
|
|
||||||
|
The class uses the 'visitor' pattern from the CGAL manual. See also
|
||||||
|
http://www.cgal.org/Manual/latest/doc_html/cgal_manual/Nef_3/Chapter_main.html
|
||||||
|
http://www.cgal.org/Manual/latest/doc_html/cgal_manual/Nef_3_ref/Class_Nef_polyhedron3.html
|
||||||
|
OGL_helper.h
|
||||||
|
*/
|
||||||
|
|
||||||
|
class ZRemover {
|
||||||
|
public:
|
||||||
|
CGAL_Nef_polyhedron2::Boundary boundary;
|
||||||
|
boost::shared_ptr<CGAL_Nef_polyhedron2> tmpnef2d;
|
||||||
|
boost::shared_ptr<CGAL_Nef_polyhedron2> output_nefpoly2d;
|
||||||
|
CGAL::Direction_3<CGAL_Kernel3> up;
|
||||||
|
ZRemover()
|
||||||
|
{
|
||||||
|
output_nefpoly2d.reset( new CGAL_Nef_polyhedron2() );
|
||||||
|
boundary = CGAL_Nef_polyhedron2::INCLUDED;
|
||||||
|
up = CGAL::Direction_3<CGAL_Kernel3>(0,0,1);
|
||||||
|
}
|
||||||
|
void visit( CGAL_Nef_polyhedron3::Vertex_const_handle ) {}
|
||||||
|
void visit( CGAL_Nef_polyhedron3::Halfedge_const_handle ) {}
|
||||||
|
void visit( CGAL_Nef_polyhedron3::SHalfedge_const_handle ) {}
|
||||||
|
void visit( CGAL_Nef_polyhedron3::SHalfloop_const_handle ) {}
|
||||||
|
void visit( CGAL_Nef_polyhedron3::SFace_const_handle ) {}
|
||||||
|
void visit( CGAL_Nef_polyhedron3::Halffacet_const_handle hfacet );
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
void ZRemover::visit(CGAL_Nef_polyhedron3::Halffacet_const_handle hfacet)
|
||||||
|
{
|
||||||
|
PRINTDB(" <!-- ZRemover Halffacet visit. Mark: %i --> ",hfacet->mark());
|
||||||
|
if (hfacet->plane().orthogonal_direction() != this->up) {
|
||||||
|
PRINTD(" <!-- ZRemover down-facing half-facet. skipping -->");
|
||||||
|
PRINTD(" <!-- ZRemover Halffacet visit end-->");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// possible optimization - throw out facets that are vertically oriented
|
||||||
|
|
||||||
|
CGAL_Nef_polyhedron3::Halffacet_cycle_const_iterator fci;
|
||||||
|
int contour_counter = 0;
|
||||||
|
CGAL_forall_facet_cycles_of(fci, hfacet) {
|
||||||
|
if (fci.is_shalfedge()) {
|
||||||
|
PRINTD(" <!-- ZRemover Halffacet cycle begin -->");
|
||||||
|
CGAL_Nef_polyhedron3::SHalfedge_around_facet_const_circulator c1(fci), cend(c1);
|
||||||
|
std::vector<CGAL_Nef_polyhedron2::Explorer::Point> contour;
|
||||||
|
CGAL_For_all(c1, cend) {
|
||||||
|
CGAL_Nef_polyhedron3::Point_3 point3d = c1->source()->target()->point();
|
||||||
|
CGAL_Nef_polyhedron2::Explorer::Point point2d(CGAL::to_double(point3d.x()),
|
||||||
|
CGAL::to_double(point3d.y()));
|
||||||
|
contour.push_back(point2d);
|
||||||
|
}
|
||||||
|
if (contour.size()==0) continue;
|
||||||
|
|
||||||
|
if (OpenSCAD::debug!="")
|
||||||
|
PRINTDB(" <!-- is_simple_2: %i -->", CGAL::is_simple_2(contour.begin(), contour.end()));
|
||||||
|
|
||||||
|
tmpnef2d.reset(new CGAL_Nef_polyhedron2(contour.begin(), contour.end(), boundary));
|
||||||
|
|
||||||
|
if (contour_counter == 0) {
|
||||||
|
PRINTDB(" <!-- contour is a body. make union(). %i points -->", contour.size());
|
||||||
|
*(output_nefpoly2d) += *(tmpnef2d);
|
||||||
|
} else {
|
||||||
|
PRINTDB(" <!-- contour is a hole. make intersection(). %i points -->", contour.size());
|
||||||
|
*(output_nefpoly2d) *= *(tmpnef2d);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*log << "\n<!-- ======== output tmp nef: ==== -->\n"
|
||||||
|
<< OpenSCAD::dump_svg(*tmpnef2d) << "\n"
|
||||||
|
<< "\n<!-- ======== output accumulator: ==== -->\n"
|
||||||
|
<< OpenSCAD::dump_svg(*output_nefpoly2d) << "\n";*/
|
||||||
|
|
||||||
|
contour_counter++;
|
||||||
|
} else {
|
||||||
|
PRINTD(" <!-- ZRemover trivial facet cycle skipped -->");
|
||||||
|
}
|
||||||
|
PRINTD(" <!-- ZRemover Halffacet cycle end -->");
|
||||||
|
}
|
||||||
|
PRINTD(" <!-- ZRemover Halffacet visit end -->");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
namespace CGALUtils {
|
||||||
|
|
||||||
|
Polygon2d *project(const CGAL_Nef_polyhedron &N, bool cut)
|
||||||
|
{
|
||||||
|
Polygon2d *poly = NULL;
|
||||||
|
if (N.getDimension() != 3) return poly;
|
||||||
|
|
||||||
|
CGAL_Nef_polyhedron newN;
|
||||||
|
if (cut) {
|
||||||
|
CGAL::Failure_behaviour old_behaviour = CGAL::set_error_behaviour(CGAL::THROW_EXCEPTION);
|
||||||
|
try {
|
||||||
|
CGAL_Nef_polyhedron3::Plane_3 xy_plane = CGAL_Nef_polyhedron3::Plane_3(0,0,1,0);
|
||||||
|
newN.p3.reset(new CGAL_Nef_polyhedron3(N.p3->intersection(xy_plane, CGAL_Nef_polyhedron3::PLANE_ONLY)));
|
||||||
|
}
|
||||||
|
catch (const CGAL::Failure_exception &e) {
|
||||||
|
PRINTDB("CGALUtils::project during plane intersection: %s", e.what());
|
||||||
|
try {
|
||||||
|
PRINTD("Trying alternative intersection using very large thin box: ");
|
||||||
|
std::vector<CGAL_Point_3> pts;
|
||||||
|
// dont use z of 0. there are bugs in CGAL.
|
||||||
|
double inf = 1e8;
|
||||||
|
double eps = 0.001;
|
||||||
|
CGAL_Point_3 minpt(-inf, -inf, -eps);
|
||||||
|
CGAL_Point_3 maxpt( inf, inf, eps);
|
||||||
|
CGAL_Iso_cuboid_3 bigcuboid(minpt, maxpt);
|
||||||
|
for (int i=0;i<8;i++) pts.push_back(bigcuboid.vertex(i));
|
||||||
|
CGAL_Polyhedron bigbox;
|
||||||
|
CGAL::convex_hull_3(pts.begin(), pts.end(), bigbox);
|
||||||
|
CGAL_Nef_polyhedron3 nef_bigbox(bigbox);
|
||||||
|
newN.p3.reset(new CGAL_Nef_polyhedron3(nef_bigbox.intersection(*N.p3)));
|
||||||
|
}
|
||||||
|
catch (const CGAL::Failure_exception &e) {
|
||||||
|
PRINTB("ERROR: CGAL error in CGALUtils::project during bigbox intersection: %s", e.what());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!newN.p3 || newN.p3->is_empty()) {
|
||||||
|
CGAL::set_error_behaviour(old_behaviour);
|
||||||
|
PRINT("WARNING: projection() failed.");
|
||||||
|
return poly;
|
||||||
|
}
|
||||||
|
|
||||||
|
PRINTDB("%s",OpenSCAD::svg_header(480, 100000));
|
||||||
|
try {
|
||||||
|
ZRemover zremover;
|
||||||
|
CGAL_Nef_polyhedron3::Volume_const_iterator i;
|
||||||
|
CGAL_Nef_polyhedron3::Shell_entry_const_iterator j;
|
||||||
|
CGAL_Nef_polyhedron3::SFace_const_handle sface_handle;
|
||||||
|
for (i = newN.p3->volumes_begin(); i != newN.p3->volumes_end(); ++i) {
|
||||||
|
PRINTDB("<!-- volume. mark: %s -->",i->mark());
|
||||||
|
for (j = i->shells_begin(); j != i->shells_end(); ++j) {
|
||||||
|
PRINTDB("<!-- shell. (vol mark was: %i)", i->mark());;
|
||||||
|
sface_handle = CGAL_Nef_polyhedron3::SFace_const_handle(j);
|
||||||
|
newN.p3->visit_shell_objects(sface_handle , zremover);
|
||||||
|
PRINTD("<!-- shell. end. -->");
|
||||||
|
}
|
||||||
|
PRINTD("<!-- volume end. -->");
|
||||||
|
}
|
||||||
|
poly = convertToPolygon2d(*zremover.output_nefpoly2d);
|
||||||
|
} catch (const CGAL::Failure_exception &e) {
|
||||||
|
PRINTB("ERROR: CGAL error in CGALUtils::project while flattening: %s", e.what());
|
||||||
|
}
|
||||||
|
PRINTD("</svg>");
|
||||||
|
|
||||||
|
CGAL::set_error_behaviour(old_behaviour);
|
||||||
|
}
|
||||||
|
// In projection mode all the triangles are projected manually into the XY plane
|
||||||
|
else {
|
||||||
|
PolySet ps(3);
|
||||||
|
bool err = CGALUtils::createPolySetFromNefPolyhedron3(*N.p3, ps);
|
||||||
|
if (err) {
|
||||||
|
PRINT("ERROR: Nef->PolySet failed");
|
||||||
|
return poly;
|
||||||
|
}
|
||||||
|
poly = PolysetUtils::project(ps);
|
||||||
|
}
|
||||||
|
return poly;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
#endif // ENABLE_CGAL
|
||||||
1320
src/cgalutils.cc
1320
src/cgalutils.cc
File diff suppressed because it is too large
Load diff
|
|
@ -11,6 +11,13 @@ typedef CGAL::Point_3<K> Vertex3K;
|
||||||
typedef std::vector<Vertex3K> PolygonK;
|
typedef std::vector<Vertex3K> PolygonK;
|
||||||
typedef std::vector<PolygonK> PolyholeK;
|
typedef std::vector<PolygonK> PolyholeK;
|
||||||
|
|
||||||
|
namespace /* anonymous */ {
|
||||||
|
template<typename Result, typename V>
|
||||||
|
Result vector_convert(V const& v) {
|
||||||
|
return Result(CGAL::to_double(v[0]),CGAL::to_double(v[1]),CGAL::to_double(v[2]));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
namespace CGALUtils {
|
namespace CGALUtils {
|
||||||
bool applyHull(const Geometry::ChildList &children, PolySet &P);
|
bool applyHull(const Geometry::ChildList &children, PolySet &P);
|
||||||
CGAL_Nef_polyhedron *applyOperator(const Geometry::ChildList &children, OpenSCADOperator op);
|
CGAL_Nef_polyhedron *applyOperator(const Geometry::ChildList &children, OpenSCADOperator op);
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
#include "clipper-utils.h"
|
#include "clipper-utils.h"
|
||||||
|
#include "printutils.h"
|
||||||
#include <boost/foreach.hpp>
|
#include <boost/foreach.hpp>
|
||||||
|
|
||||||
namespace ClipperUtils {
|
namespace ClipperUtils {
|
||||||
|
|
@ -30,7 +31,15 @@ namespace ClipperUtils {
|
||||||
ClipperLib::PolyTree sanitize(const ClipperLib::Paths &paths) {
|
ClipperLib::PolyTree sanitize(const ClipperLib::Paths &paths) {
|
||||||
ClipperLib::PolyTree result;
|
ClipperLib::PolyTree result;
|
||||||
ClipperLib::Clipper clipper;
|
ClipperLib::Clipper clipper;
|
||||||
clipper.AddPaths(paths, ClipperLib::ptSubject, true);
|
try {
|
||||||
|
clipper.AddPaths(paths, ClipperLib::ptSubject, true);
|
||||||
|
}
|
||||||
|
catch(...) {
|
||||||
|
// Most likely caught a RangeTest exception from clipper
|
||||||
|
// Note that Clipper up to v6.2.1 incorrectly throws
|
||||||
|
// an exception of type char* rather than a clipperException()
|
||||||
|
PRINT("WARNING: Range check failed for polygon. skipping");
|
||||||
|
}
|
||||||
clipper.Execute(ClipperLib::ctUnion, result, ClipperLib::pftEvenOdd);
|
clipper.Execute(ClipperLib::ctUnion, result, ClipperLib::pftEvenOdd);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -50,6 +50,8 @@ private:
|
||||||
|
|
||||||
ColorModule::ColorModule()
|
ColorModule::ColorModule()
|
||||||
{
|
{
|
||||||
|
// Colors extracted from https://drafts.csswg.org/css-color/ on 2015-08-02
|
||||||
|
// CSS Color Module Level 4 - Editor’s Draft, 29 May 2015
|
||||||
webcolors = map_list_of
|
webcolors = map_list_of
|
||||||
("aliceblue", Color4f(240, 248, 255))
|
("aliceblue", Color4f(240, 248, 255))
|
||||||
("antiquewhite", Color4f(250, 235, 215))
|
("antiquewhite", Color4f(250, 235, 215))
|
||||||
|
|
@ -170,6 +172,7 @@ ColorModule::ColorModule()
|
||||||
("plum", Color4f(221, 160, 221))
|
("plum", Color4f(221, 160, 221))
|
||||||
("powderblue", Color4f(176, 224, 230))
|
("powderblue", Color4f(176, 224, 230))
|
||||||
("purple", Color4f(128, 0, 128))
|
("purple", Color4f(128, 0, 128))
|
||||||
|
("rebeccapurple", Color4f(102, 51, 153))
|
||||||
("red", Color4f(255, 0, 0))
|
("red", Color4f(255, 0, 0))
|
||||||
("rosybrown", Color4f(188, 143, 143))
|
("rosybrown", Color4f(188, 143, 143))
|
||||||
("royalblue", Color4f(65, 105, 225))
|
("royalblue", Color4f(65, 105, 225))
|
||||||
|
|
@ -191,7 +194,6 @@ ColorModule::ColorModule()
|
||||||
("teal", Color4f(0, 128, 128))
|
("teal", Color4f(0, 128, 128))
|
||||||
("thistle", Color4f(216, 191, 216))
|
("thistle", Color4f(216, 191, 216))
|
||||||
("tomato", Color4f(255, 99, 71))
|
("tomato", Color4f(255, 99, 71))
|
||||||
("transparent", Color4f(0, 0, 0, 0))
|
|
||||||
("turquoise", Color4f(64, 224, 208))
|
("turquoise", Color4f(64, 224, 208))
|
||||||
("violet", Color4f(238, 130, 238))
|
("violet", Color4f(238, 130, 238))
|
||||||
("wheat", Color4f(245, 222, 179))
|
("wheat", Color4f(245, 222, 179))
|
||||||
|
|
@ -199,6 +201,9 @@ ColorModule::ColorModule()
|
||||||
("whitesmoke", Color4f(245, 245, 245))
|
("whitesmoke", Color4f(245, 245, 245))
|
||||||
("yellow", Color4f(255, 255, 0))
|
("yellow", Color4f(255, 255, 0))
|
||||||
("yellowgreen", Color4f(154, 205, 50))
|
("yellowgreen", Color4f(154, 205, 50))
|
||||||
|
|
||||||
|
// additional OpenSCAD specific entry
|
||||||
|
("transparent", Color4f(0, 0, 0, 0))
|
||||||
.convert_to_container<boost::unordered_map<std::string, Color4f> >();
|
.convert_to_container<boost::unordered_map<std::string, Color4f> >();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -224,7 +229,7 @@ AbstractNode *ColorModule::instantiate(const Context *ctx, const ModuleInstantia
|
||||||
ValuePtr v = c.lookup_variable("c");
|
ValuePtr v = c.lookup_variable("c");
|
||||||
if (v->type() == Value::VECTOR) {
|
if (v->type() == Value::VECTOR) {
|
||||||
for (size_t i = 0; i < 4; i++) {
|
for (size_t i = 0; i < 4; i++) {
|
||||||
node->color[i] = i < v->toVector().size() ? v->toVector()[i].toDouble() : 1.0;
|
node->color[i] = i < v->toVector().size() ? v->toVector()[i]->toDouble() : 1.0;
|
||||||
if (node->color[i] > 1)
|
if (node->color[i] > 1)
|
||||||
PRINTB_NOCACHE("WARNING: color() expects numbers between 0.0 and 1.0. Value of %.1f is too large.", node->color[i]);
|
PRINTB_NOCACHE("WARNING: color() expects numbers between 0.0 and 1.0. Value of %.1f is too large.", node->color[i]);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -37,6 +37,7 @@ RenderColorScheme::RenderColorScheme() : _path("")
|
||||||
_show_in_gui = true;
|
_show_in_gui = true;
|
||||||
|
|
||||||
_color_scheme.insert(ColorScheme::value_type(BACKGROUND_COLOR, Color4f(0xff, 0xff, 0xe5)));
|
_color_scheme.insert(ColorScheme::value_type(BACKGROUND_COLOR, Color4f(0xff, 0xff, 0xe5)));
|
||||||
|
_color_scheme.insert(ColorScheme::value_type(AXES_COLOR, Color4f(0x00, 0x00, 0x00)));
|
||||||
_color_scheme.insert(ColorScheme::value_type(OPENCSG_FACE_FRONT_COLOR, Color4f(0xf9, 0xd7, 0x2c)));
|
_color_scheme.insert(ColorScheme::value_type(OPENCSG_FACE_FRONT_COLOR, Color4f(0xf9, 0xd7, 0x2c)));
|
||||||
_color_scheme.insert(ColorScheme::value_type(OPENCSG_FACE_BACK_COLOR, Color4f(0x9d, 0xcb, 0x51)));
|
_color_scheme.insert(ColorScheme::value_type(OPENCSG_FACE_BACK_COLOR, Color4f(0x9d, 0xcb, 0x51)));
|
||||||
_color_scheme.insert(ColorScheme::value_type(CGAL_FACE_FRONT_COLOR, Color4f(0xf9, 0xd7, 0x2c)));
|
_color_scheme.insert(ColorScheme::value_type(CGAL_FACE_FRONT_COLOR, Color4f(0xf9, 0xd7, 0x2c)));
|
||||||
|
|
@ -57,6 +58,7 @@ RenderColorScheme::RenderColorScheme(fs::path path) : _path(path)
|
||||||
_show_in_gui = pt.get<bool>("show-in-gui");
|
_show_in_gui = pt.get<bool>("show-in-gui");
|
||||||
|
|
||||||
addColor(BACKGROUND_COLOR, "background");
|
addColor(BACKGROUND_COLOR, "background");
|
||||||
|
addColor(AXES_COLOR, "axes-color");
|
||||||
addColor(OPENCSG_FACE_FRONT_COLOR, "opencsg-face-front");
|
addColor(OPENCSG_FACE_FRONT_COLOR, "opencsg-face-front");
|
||||||
addColor(OPENCSG_FACE_BACK_COLOR, "opencsg-face-back");
|
addColor(OPENCSG_FACE_BACK_COLOR, "opencsg-face-back");
|
||||||
addColor(CGAL_FACE_FRONT_COLOR, "cgal-face-front");
|
addColor(CGAL_FACE_FRONT_COLOR, "cgal-face-front");
|
||||||
|
|
@ -67,7 +69,7 @@ RenderColorScheme::RenderColorScheme(fs::path path) : _path(path)
|
||||||
addColor(CGAL_EDGE_2D_COLOR, "cgal-edge-2d");
|
addColor(CGAL_EDGE_2D_COLOR, "cgal-edge-2d");
|
||||||
addColor(CROSSHAIR_COLOR, "crosshair");
|
addColor(CROSSHAIR_COLOR, "crosshair");
|
||||||
} catch (const std::exception & e) {
|
} catch (const std::exception & e) {
|
||||||
PRINTB("Error reading color scheme file '%s': %s", path.c_str() % e.what());
|
PRINTB("Error reading color scheme file '%s': %s", boosty::stringy(path).c_str() % e.what());
|
||||||
_error = e.what();
|
_error = e.what();
|
||||||
_name = "";
|
_name = "";
|
||||||
_index = 0;
|
_index = 0;
|
||||||
|
|
@ -261,7 +263,7 @@ void ColorMap::enumerateColorSchemesInPath(colorscheme_set_t &result_set, const
|
||||||
{
|
{
|
||||||
const fs::path color_schemes = basePath / "color-schemes" / "render";
|
const fs::path color_schemes = basePath / "color-schemes" / "render";
|
||||||
|
|
||||||
PRINTDB("Enumerating color schemes from '%s'", color_schemes.string().c_str());
|
PRINTDB("Enumerating color schemes from '%s'", boosty::stringy(color_schemes).c_str());
|
||||||
|
|
||||||
fs::directory_iterator end_iter;
|
fs::directory_iterator end_iter;
|
||||||
|
|
||||||
|
|
@ -272,7 +274,7 @@ void ColorMap::enumerateColorSchemesInPath(colorscheme_set_t &result_set, const
|
||||||
}
|
}
|
||||||
|
|
||||||
const fs::path path = (*dir_iter).path();
|
const fs::path path = (*dir_iter).path();
|
||||||
if (!(path.extension().string() == ".json")) {
|
if (!(path.extension() == ".json")) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -13,6 +13,7 @@ namespace fs = boost::filesystem;
|
||||||
|
|
||||||
enum RenderColor {
|
enum RenderColor {
|
||||||
BACKGROUND_COLOR,
|
BACKGROUND_COLOR,
|
||||||
|
AXES_COLOR,
|
||||||
OPENCSG_FACE_FRONT_COLOR,
|
OPENCSG_FACE_FRONT_COLOR,
|
||||||
OPENCSG_FACE_BACK_COLOR,
|
OPENCSG_FACE_BACK_COLOR,
|
||||||
CGAL_FACE_FRONT_COLOR,
|
CGAL_FACE_FRONT_COLOR,
|
||||||
|
|
|
||||||
|
|
@ -63,7 +63,7 @@ public: // methods
|
||||||
|
|
||||||
static const EvalContext* getLastModuleCtx(const EvalContext *evalctx);
|
static const EvalContext* getLastModuleCtx(const EvalContext *evalctx);
|
||||||
|
|
||||||
static AbstractNode* getChild(const Value &value, const EvalContext* modulectx);
|
static AbstractNode* getChild(const ValuePtr &value, const EvalContext* modulectx);
|
||||||
|
|
||||||
private: // data
|
private: // data
|
||||||
Type type;
|
Type type;
|
||||||
|
|
@ -78,15 +78,15 @@ void ControlModule::for_eval(AbstractNode &node, const ModuleInstantiation &inst
|
||||||
ValuePtr it_values = evalctx->getArgValue(l, ctx);
|
ValuePtr it_values = evalctx->getArgValue(l, ctx);
|
||||||
Context c(ctx);
|
Context c(ctx);
|
||||||
if (it_values->type() == Value::RANGE) {
|
if (it_values->type() == Value::RANGE) {
|
||||||
Value::RangeType range = it_values->toRange();
|
RangeType range = it_values->toRange();
|
||||||
boost::uint32_t steps = range.nbsteps();
|
boost::uint32_t steps = range.numValues();
|
||||||
if (steps >= 10000) {
|
if (steps >= 10000) {
|
||||||
PRINTB("WARNING: Bad range parameter in for statement: too many elements (%lu).", steps);
|
PRINTB("WARNING: Bad range parameter in for statement: too many elements (%lu).", steps);
|
||||||
} else {
|
} else {
|
||||||
for (Value::RangeType::iterator it = range.begin();it != range.end();it++) {
|
for (RangeType::iterator it = range.begin();it != range.end();it++) {
|
||||||
c.set_variable(it_name, ValuePtr(*it));
|
c.set_variable(it_name, ValuePtr(*it));
|
||||||
for_eval(node, inst, l+1, &c, evalctx);
|
for_eval(node, inst, l+1, &c, evalctx);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (it_values->type() == Value::VECTOR) {
|
else if (it_values->type() == Value::VECTOR) {
|
||||||
|
|
@ -133,17 +133,17 @@ const EvalContext* ControlModule::getLastModuleCtx(const EvalContext *evalctx)
|
||||||
}
|
}
|
||||||
|
|
||||||
// static
|
// static
|
||||||
AbstractNode* ControlModule::getChild(const Value& value, const EvalContext* modulectx)
|
AbstractNode* ControlModule::getChild(const ValuePtr &value, const EvalContext* modulectx)
|
||||||
{
|
{
|
||||||
if (value.type()!=Value::NUMBER) {
|
if (value->type()!=Value::NUMBER) {
|
||||||
// Invalid parameter
|
// Invalid parameter
|
||||||
// (e.g. first child of difference is invalid)
|
// (e.g. first child of difference is invalid)
|
||||||
PRINTB("WARNING: Bad parameter type (%s) for children, only accept: empty, number, vector, range.", value.toString());
|
PRINTB("WARNING: Bad parameter type (%s) for children, only accept: empty, number, vector, range.", value->toString());
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
double v;
|
double v;
|
||||||
if (!value.getDouble(v)) {
|
if (!value->getDouble(v)) {
|
||||||
PRINTB("WARNING: Bad parameter type (%s) for children, only accept: empty, number, vector, range.", value.toString());
|
PRINTB("WARNING: Bad parameter type (%s) for children, only accept: empty, number, vector, range.", value->toString());
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -223,12 +223,12 @@ AbstractNode *ControlModule::instantiate(const Context* /*ctx*/, const ModuleIns
|
||||||
// one (or more ignored) parameter
|
// one (or more ignored) parameter
|
||||||
ValuePtr value = evalctx->getArgValue(0);
|
ValuePtr value = evalctx->getArgValue(0);
|
||||||
if (value->type() == Value::NUMBER) {
|
if (value->type() == Value::NUMBER) {
|
||||||
return getChild(*value, modulectx);
|
return getChild(value, modulectx);
|
||||||
}
|
}
|
||||||
else if (value->type() == Value::VECTOR) {
|
else if (value->type() == Value::VECTOR) {
|
||||||
AbstractNode* node = new AbstractNode(inst);
|
AbstractNode* node = new AbstractNode(inst);
|
||||||
const Value::VectorType& vect = value->toVector();
|
const Value::VectorType& vect = value->toVector();
|
||||||
foreach (const Value::VectorType::value_type& vectvalue, vect) {
|
foreach (const ValuePtr &vectvalue, vect) {
|
||||||
AbstractNode* childnode = getChild(vectvalue,modulectx);
|
AbstractNode* childnode = getChild(vectvalue,modulectx);
|
||||||
if (childnode==NULL) continue; // error
|
if (childnode==NULL) continue; // error
|
||||||
node->children.push_back(childnode);
|
node->children.push_back(childnode);
|
||||||
|
|
@ -236,15 +236,15 @@ AbstractNode *ControlModule::instantiate(const Context* /*ctx*/, const ModuleIns
|
||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
else if (value->type() == Value::RANGE) {
|
else if (value->type() == Value::RANGE) {
|
||||||
AbstractNode* node = new AbstractNode(inst);
|
RangeType range = value->toRange();
|
||||||
Value::RangeType range = value->toRange();
|
boost::uint32_t steps = range.numValues();
|
||||||
boost::uint32_t steps = range.nbsteps();
|
|
||||||
if (steps >= 10000) {
|
if (steps >= 10000) {
|
||||||
PRINTB("WARNING: Bad range parameter for children: too many elements (%lu).", steps);
|
PRINTB("WARNING: Bad range parameter for children: too many elements (%lu).", steps);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
for (Value::RangeType::iterator it = range.begin();it != range.end();it++) {
|
AbstractNode* node = new AbstractNode(inst);
|
||||||
AbstractNode* childnode = getChild(Value(*it),modulectx); // with error cases
|
for (RangeType::iterator it = range.begin();it != range.end();it++) {
|
||||||
|
AbstractNode* childnode = getChild(ValuePtr(*it),modulectx); // with error cases
|
||||||
if (childnode==NULL) continue; // error
|
if (childnode==NULL) continue; // error
|
||||||
node->children.push_back(childnode);
|
node->children.push_back(childnode);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -68,7 +68,7 @@ shared_ptr<CSGTerm> CSGTerm::createCSGTerm(type_e type, shared_ptr<CSGTerm> left
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Pruning the tree. For details, see:
|
// Pruning the tree. For details, see "Solid Modeling" by Goldfeather:
|
||||||
// http://www.cc.gatech.edu/~turk/my_papers/pxpl_csg.pdf
|
// http://www.cc.gatech.edu/~turk/my_papers/pxpl_csg.pdf
|
||||||
const BoundingBox &leftbox = left->getBoundingBox();
|
const BoundingBox &leftbox = left->getBoundingBox();
|
||||||
const BoundingBox &rightbox = right->getBoundingBox();
|
const BoundingBox &rightbox = right->getBoundingBox();
|
||||||
|
|
|
||||||
|
|
@ -200,8 +200,8 @@ ValuePtr builtin_dxf_cross(const Context *ctx, const EvalContext *evalctx)
|
||||||
double x = x1 + ua*(x2 - x1);
|
double x = x1 + ua*(x2 - x1);
|
||||||
double y = y1 + ua*(y2 - y1);
|
double y = y1 + ua*(y2 - y1);
|
||||||
Value::VectorType ret;
|
Value::VectorType ret;
|
||||||
ret.push_back(Value(x));
|
ret.push_back(ValuePtr(x));
|
||||||
ret.push_back(Value(y));
|
ret.push_back(ValuePtr(y));
|
||||||
return dxf_cross_cache[key] = ValuePtr(ret);
|
return dxf_cross_cache[key] = ValuePtr(ret);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -106,7 +106,7 @@ void exportFileByName(const class Geometry *root_geom, FileFormat format,
|
||||||
{
|
{
|
||||||
std::ofstream fstream(name2open);
|
std::ofstream fstream(name2open);
|
||||||
if (!fstream.is_open()) {
|
if (!fstream.is_open()) {
|
||||||
PRINTB("Can't open file \"%s\" for export", name2display);
|
PRINTB(_("Can't open file \"%s\" for export"), name2display);
|
||||||
} else {
|
} else {
|
||||||
bool onerror = false;
|
bool onerror = false;
|
||||||
fstream.exceptions(std::ios::badbit|std::ios::failbit);
|
fstream.exceptions(std::ios::badbit|std::ios::failbit);
|
||||||
|
|
@ -121,7 +121,7 @@ void exportFileByName(const class Geometry *root_geom, FileFormat format,
|
||||||
onerror = true;
|
onerror = true;
|
||||||
}
|
}
|
||||||
if (onerror) {
|
if (onerror) {
|
||||||
PRINTB("ERROR: \"%s\" write error. (Disk full?)", name2display);
|
PRINTB(_("ERROR: \"%s\" write error. (Disk full?)"), name2display);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -424,6 +424,7 @@ void export_amf(const CGAL_Nef_polyhedron *root_N, std::ostream &output)
|
||||||
coords = strtok(NULL, " ");
|
coords = strtok(NULL, " ");
|
||||||
output << " <z>" << coords << "</z>\r\n";
|
output << " <z>" << coords << "</z>\r\n";
|
||||||
output << " </coordinates></vertex>\r\n";
|
output << " </coordinates></vertex>\r\n";
|
||||||
|
delete[] chrs;
|
||||||
}
|
}
|
||||||
output << " </vertices>\r\n";
|
output << " </vertices>\r\n";
|
||||||
output << " <volume>\r\n";
|
output << " <volume>\r\n";
|
||||||
|
|
|
||||||
29
src/expr.cc
29
src/expr.cc
|
|
@ -41,12 +41,12 @@ namespace {
|
||||||
Value::VectorType flatten(Value::VectorType const& vec) {
|
Value::VectorType flatten(Value::VectorType const& vec) {
|
||||||
int n = 0;
|
int n = 0;
|
||||||
for (unsigned int i = 0; i < vec.size(); i++) {
|
for (unsigned int i = 0; i < vec.size(); i++) {
|
||||||
assert(vec[i].type() == Value::VECTOR);
|
assert(vec[i]->type() == Value::VECTOR);
|
||||||
n += vec[i].toVector().size();
|
n += vec[i]->toVector().size();
|
||||||
}
|
}
|
||||||
Value::VectorType ret; ret.reserve(n);
|
Value::VectorType ret; ret.reserve(n);
|
||||||
for (unsigned int i = 0; i < vec.size(); i++) {
|
for (unsigned int i = 0; i < vec.size(); i++) {
|
||||||
std::copy(vec[i].toVector().begin(),vec[i].toVector().end(),std::back_inserter(ret));
|
std::copy(vec[i]->toVector().begin(),vec[i]->toVector().end(),std::back_inserter(ret));
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
@ -357,7 +357,7 @@ ExpressionConst::ExpressionConst(const ValuePtr &val) : const_value(val)
|
||||||
|
|
||||||
ValuePtr ExpressionConst::evaluate(const class Context *) const
|
ValuePtr ExpressionConst::evaluate(const class Context *) const
|
||||||
{
|
{
|
||||||
return ValuePtr(this->const_value);
|
return this->const_value;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ExpressionConst::print(std::ostream &stream) const
|
void ExpressionConst::print(std::ostream &stream) const
|
||||||
|
|
@ -380,12 +380,12 @@ ValuePtr ExpressionRange::evaluate(const Context *context) const
|
||||||
ValuePtr v2 = this->second->evaluate(context);
|
ValuePtr v2 = this->second->evaluate(context);
|
||||||
if (v2->type() == Value::NUMBER) {
|
if (v2->type() == Value::NUMBER) {
|
||||||
if (this->children.size() == 2) {
|
if (this->children.size() == 2) {
|
||||||
Value::RangeType range(v1->toDouble(), v2->toDouble());
|
RangeType range(v1->toDouble(), v2->toDouble());
|
||||||
return ValuePtr(range);
|
return ValuePtr(range);
|
||||||
} else {
|
} else {
|
||||||
ValuePtr v3 = this->third->evaluate(context);
|
ValuePtr v3 = this->third->evaluate(context);
|
||||||
if (v3->type() == Value::NUMBER) {
|
if (v3->type() == Value::NUMBER) {
|
||||||
Value::RangeType range(v1->toDouble(), v2->toDouble(), v3->toDouble());
|
RangeType range(v1->toDouble(), v2->toDouble(), v3->toDouble());
|
||||||
return ValuePtr(range);
|
return ValuePtr(range);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -409,7 +409,8 @@ ValuePtr ExpressionVector::evaluate(const Context *context) const
|
||||||
{
|
{
|
||||||
Value::VectorType vec;
|
Value::VectorType vec;
|
||||||
BOOST_FOREACH(const Expression *e, this->children) {
|
BOOST_FOREACH(const Expression *e, this->children) {
|
||||||
vec.push_back(*(e->evaluate(context)));
|
ValuePtr tmpval = e->evaluate(context);
|
||||||
|
vec.push_back(tmpval);
|
||||||
}
|
}
|
||||||
return ValuePtr(vec);
|
return ValuePtr(vec);
|
||||||
}
|
}
|
||||||
|
|
@ -545,7 +546,7 @@ ValuePtr ExpressionLc::evaluate(const Context *context) const
|
||||||
if (this->second->isListComprehension()) {
|
if (this->second->isListComprehension()) {
|
||||||
return this->second->evaluate(context);
|
return this->second->evaluate(context);
|
||||||
} else {
|
} else {
|
||||||
vec.push_back((*this->second->evaluate(context)));
|
vec.push_back(this->second->evaluate(context));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return ValuePtr(vec);
|
return ValuePtr(vec);
|
||||||
|
|
@ -561,26 +562,26 @@ ValuePtr ExpressionLc::evaluate(const Context *context) const
|
||||||
Context c(context);
|
Context c(context);
|
||||||
|
|
||||||
if (it_values->type() == Value::RANGE) {
|
if (it_values->type() == Value::RANGE) {
|
||||||
Value::RangeType range = it_values->toRange();
|
RangeType range = it_values->toRange();
|
||||||
boost::uint32_t steps = range.nbsteps();
|
boost::uint32_t steps = range.numValues();
|
||||||
if (steps >= 1000000) {
|
if (steps >= 1000000) {
|
||||||
PRINTB("WARNING: Bad range parameter in for statement: too many elements (%lu).", steps);
|
PRINTB("WARNING: Bad range parameter in for statement: too many elements (%lu).", steps);
|
||||||
} else {
|
} else {
|
||||||
for (Value::RangeType::iterator it = range.begin();it != range.end();it++) {
|
for (RangeType::iterator it = range.begin();it != range.end();it++) {
|
||||||
c.set_variable(it_name, ValuePtr(*it));
|
c.set_variable(it_name, ValuePtr(*it));
|
||||||
vec.push_back((*this->first->evaluate(&c)));
|
vec.push_back(this->first->evaluate(&c));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (it_values->type() == Value::VECTOR) {
|
else if (it_values->type() == Value::VECTOR) {
|
||||||
for (size_t i = 0; i < it_values->toVector().size(); i++) {
|
for (size_t i = 0; i < it_values->toVector().size(); i++) {
|
||||||
c.set_variable(it_name, it_values->toVector()[i]);
|
c.set_variable(it_name, it_values->toVector()[i]);
|
||||||
vec.push_back((*this->first->evaluate(&c)));
|
vec.push_back(this->first->evaluate(&c));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (it_values->type() != Value::UNDEFINED) {
|
else if (it_values->type() != Value::UNDEFINED) {
|
||||||
c.set_variable(it_name, it_values);
|
c.set_variable(it_name, it_values);
|
||||||
vec.push_back((*this->first->evaluate(&c)));
|
vec.push_back(this->first->evaluate(&c));
|
||||||
}
|
}
|
||||||
if (this->first->isListComprehension()) {
|
if (this->first->isListComprehension()) {
|
||||||
return ValuePtr(flatten(vec));
|
return ValuePtr(flatten(vec));
|
||||||
|
|
|
||||||
135
src/func.cc
135
src/func.cc
|
|
@ -24,13 +24,13 @@
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include "mathc99.h"
|
||||||
#include "function.h"
|
#include "function.h"
|
||||||
#include "expression.h"
|
#include "expression.h"
|
||||||
#include "evalcontext.h"
|
#include "evalcontext.h"
|
||||||
#include "builtin.h"
|
#include "builtin.h"
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
#include <ctime>
|
#include <ctime>
|
||||||
#include "mathc99.h"
|
|
||||||
#include <limits>
|
#include <limits>
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include "stl-utils.h"
|
#include "stl-utils.h"
|
||||||
|
|
@ -50,10 +50,13 @@ using boost::math::isinf;
|
||||||
auto/bind()s for random function objects, but we are supporting older systems.
|
auto/bind()s for random function objects, but we are supporting older systems.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include"boost-utils.h"
|
||||||
#include <boost/random/mersenne_twister.hpp>
|
#include <boost/random/mersenne_twister.hpp>
|
||||||
#include <boost/random/uniform_real.hpp>
|
#include <boost/random/uniform_real.hpp>
|
||||||
/*Unicode support for string lengths and array accesses*/
|
/*Unicode support for string lengths and array accesses*/
|
||||||
#include <glib.h>
|
#include <glib.h>
|
||||||
|
// hash double
|
||||||
|
#include "linalg.h"
|
||||||
|
|
||||||
#ifdef __WIN32__
|
#ifdef __WIN32__
|
||||||
#include <process.h>
|
#include <process.h>
|
||||||
|
|
@ -238,34 +241,51 @@ ValuePtr builtin_rands(const Context *, const EvalContext *evalctx)
|
||||||
if (v0->type() != Value::NUMBER) goto quit;
|
if (v0->type() != Value::NUMBER) goto quit;
|
||||||
double min = v0->toDouble();
|
double min = v0->toDouble();
|
||||||
|
|
||||||
|
if (boost::math::isinf(min)) {
|
||||||
|
PRINT("WARNING: rands() range min cannot be infinite");
|
||||||
|
min = -std::numeric_limits<double>::max()/2;
|
||||||
|
PRINTB("WARNING: resetting to %f",min);
|
||||||
|
}
|
||||||
ValuePtr v1 = evalctx->getArgValue(1);
|
ValuePtr v1 = evalctx->getArgValue(1);
|
||||||
if (v1->type() != Value::NUMBER) goto quit;
|
if (v1->type() != Value::NUMBER) goto quit;
|
||||||
double max = v1->toDouble();
|
double max = v1->toDouble();
|
||||||
|
if (boost::math::isinf(max)) {
|
||||||
|
PRINT("WARNING: rands() range max cannot be infinite");
|
||||||
|
max = std::numeric_limits<double>::max()/2;
|
||||||
|
PRINTB("WARNING: resetting to %f",max);
|
||||||
|
}
|
||||||
if (max < min) {
|
if (max < min) {
|
||||||
register double tmp = min; min = max; max = tmp;
|
register double tmp = min; min = max; max = tmp;
|
||||||
}
|
}
|
||||||
ValuePtr v2 = evalctx->getArgValue(2);
|
ValuePtr v2 = evalctx->getArgValue(2);
|
||||||
if (v2->type() != Value::NUMBER) goto quit;
|
if (v2->type() != Value::NUMBER) goto quit;
|
||||||
size_t numresults = std::max(0, static_cast<int>(v2->toDouble()));
|
double numresultsd = std::abs( v2->toDouble() );
|
||||||
|
if (boost::math::isinf(numresultsd)) {
|
||||||
|
PRINT("WARNING: rands() cannot create an infinite number of results");
|
||||||
|
PRINT("WARNING: resetting number of results to 1");
|
||||||
|
numresultsd = 1;
|
||||||
|
}
|
||||||
|
size_t numresults = boost_numeric_cast<size_t,double>( numresultsd );
|
||||||
|
|
||||||
bool deterministic = false;
|
bool deterministic = false;
|
||||||
if (n > 3) {
|
if (n > 3) {
|
||||||
ValuePtr v3 = evalctx->getArgValue(3);
|
ValuePtr v3 = evalctx->getArgValue(3);
|
||||||
if (v3->type() != Value::NUMBER) goto quit;
|
if (v3->type() != Value::NUMBER) goto quit;
|
||||||
deterministic_rng.seed((unsigned int) v3->toDouble());
|
uint32_t seed = static_cast<uint32_t>(hash_floating_point( v3->toDouble() ));
|
||||||
|
deterministic_rng.seed( seed );
|
||||||
deterministic = true;
|
deterministic = true;
|
||||||
}
|
}
|
||||||
Value::VectorType vec;
|
Value::VectorType vec;
|
||||||
if (min==max) { // Boost doesn't allow min == max
|
if (min==max) { // Boost doesn't allow min == max
|
||||||
for (size_t i=0; i < numresults; i++)
|
for (size_t i=0; i < numresults; i++)
|
||||||
vec.push_back( Value( min ) );
|
vec.push_back(ValuePtr(min));
|
||||||
} else {
|
} else {
|
||||||
boost::uniform_real<> distributor( min, max );
|
boost::uniform_real<> distributor( min, max );
|
||||||
for (size_t i=0; i < numresults; i++) {
|
for (size_t i=0; i < numresults; i++) {
|
||||||
if ( deterministic ) {
|
if ( deterministic ) {
|
||||||
vec.push_back(Value(distributor(deterministic_rng)));
|
vec.push_back(ValuePtr(distributor(deterministic_rng)));
|
||||||
} else {
|
} else {
|
||||||
vec.push_back(Value(distributor(lessdeterministic_rng)));
|
vec.push_back(ValuePtr(distributor(lessdeterministic_rng)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -285,11 +305,11 @@ ValuePtr builtin_min(const Context *, const EvalContext *evalctx)
|
||||||
ValuePtr v0 = evalctx->getArgValue(0);
|
ValuePtr v0 = evalctx->getArgValue(0);
|
||||||
|
|
||||||
if (n == 1 && v0->type() == Value::VECTOR && !v0->toVector().empty()) {
|
if (n == 1 && v0->type() == Value::VECTOR && !v0->toVector().empty()) {
|
||||||
Value min = v0->toVector()[0];
|
ValuePtr min = v0->toVector()[0];
|
||||||
for (size_t i = 1; i < v0->toVector().size(); i++) {
|
for (size_t i = 1; i < v0->toVector().size(); i++) {
|
||||||
if (v0->toVector()[i] < min) min = v0->toVector()[i];
|
if (v0->toVector()[i] < min) min = v0->toVector()[i];
|
||||||
}
|
}
|
||||||
return ValuePtr(min);
|
return min;
|
||||||
}
|
}
|
||||||
if (v0->type() == Value::NUMBER) {
|
if (v0->type() == Value::NUMBER) {
|
||||||
double val = v0->toDouble();
|
double val = v0->toDouble();
|
||||||
|
|
@ -317,11 +337,11 @@ ValuePtr builtin_max(const Context *, const EvalContext *evalctx)
|
||||||
ValuePtr v0 = evalctx->getArgValue(0);
|
ValuePtr v0 = evalctx->getArgValue(0);
|
||||||
|
|
||||||
if (n == 1 && v0->type() == Value::VECTOR && !v0->toVector().empty()) {
|
if (n == 1 && v0->type() == Value::VECTOR && !v0->toVector().empty()) {
|
||||||
Value max = v0->toVector()[0];
|
ValuePtr max = v0->toVector()[0];
|
||||||
for (size_t i = 1; i < v0->toVector().size(); i++) {
|
for (size_t i = 1; i < v0->toVector().size(); i++) {
|
||||||
if (v0->toVector()[i] > max) max = v0->toVector()[i];
|
if (v0->toVector()[i] > max) max = v0->toVector()[i];
|
||||||
}
|
}
|
||||||
return ValuePtr(max);
|
return max;
|
||||||
}
|
}
|
||||||
if (v0->type() == Value::NUMBER) {
|
if (v0->type() == Value::NUMBER) {
|
||||||
double val = v0->toDouble();
|
double val = v0->toDouble();
|
||||||
|
|
@ -614,14 +634,13 @@ ValuePtr builtin_concat(const Context *, const EvalContext *evalctx)
|
||||||
Value::VectorType result;
|
Value::VectorType result;
|
||||||
|
|
||||||
for (size_t i = 0; i < evalctx->numArgs(); i++) {
|
for (size_t i = 0; i < evalctx->numArgs(); i++) {
|
||||||
ValuePtr v = evalctx->getArgValue(i);
|
ValuePtr val = evalctx->getArgValue(i);
|
||||||
if (v->type() == Value::VECTOR) {
|
if (val->type() == Value::VECTOR) {
|
||||||
Value::VectorType vec = v->toVector();
|
BOOST_FOREACH(const ValuePtr &v, val->toVector()) {
|
||||||
for (Value::VectorType::const_iterator it = vec.begin(); it != vec.end(); it++) {
|
result.push_back(v);
|
||||||
result.push_back(*it);
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
result.push_back(*v);
|
result.push_back(val);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return ValuePtr(result);
|
return ValuePtr(result);
|
||||||
|
|
@ -636,13 +655,13 @@ ValuePtr builtin_lookup(const Context *, const EvalContext *evalctx)
|
||||||
|
|
||||||
ValuePtr v1 = evalctx->getArgValue(1);
|
ValuePtr v1 = evalctx->getArgValue(1);
|
||||||
const Value::VectorType &vec = v1->toVector();
|
const Value::VectorType &vec = v1->toVector();
|
||||||
if (vec[0].toVector().size() < 2) // Second must be a vector of vectors
|
if (vec[0]->toVector().size() < 2) // Second must be a vector of vectors
|
||||||
return ValuePtr::undefined;
|
return ValuePtr::undefined;
|
||||||
if (!vec[0].getVec2(low_p, low_v) || !vec[0].getVec2(high_p, high_v))
|
if (!vec[0]->getVec2(low_p, low_v) || !vec[0]->getVec2(high_p, high_v))
|
||||||
return ValuePtr::undefined;
|
return ValuePtr::undefined;
|
||||||
for (size_t i = 1; i < vec.size(); i++) {
|
for (size_t i = 1; i < vec.size(); i++) {
|
||||||
double this_p, this_v;
|
double this_p, this_v;
|
||||||
if (vec[i].getVec2(this_p, this_v)) {
|
if (vec[i]->getVec2(this_p, this_v)) {
|
||||||
if (this_p <= p && (this_p > low_p || low_p > p)) {
|
if (this_p <= p && (this_p > low_p || low_p > p)) {
|
||||||
low_p = this_p;
|
low_p = this_p;
|
||||||
low_v = this_v;
|
low_v = this_v;
|
||||||
|
|
@ -727,10 +746,10 @@ static Value::VectorType search(const std::string &find, const std::string &tabl
|
||||||
if (ptr_ft && ptr_st && (g_utf8_get_char(ptr_ft) == g_utf8_get_char(ptr_st)) ) {
|
if (ptr_ft && ptr_st && (g_utf8_get_char(ptr_ft) == g_utf8_get_char(ptr_st)) ) {
|
||||||
matchCount++;
|
matchCount++;
|
||||||
if (num_returns_per_match == 1) {
|
if (num_returns_per_match == 1) {
|
||||||
returnvec.push_back(Value(double(j)));
|
returnvec.push_back(ValuePtr(double(j)));
|
||||||
break;
|
break;
|
||||||
} else {
|
} else {
|
||||||
resultvec.push_back(Value(double(j)));
|
resultvec.push_back(ValuePtr(double(j)));
|
||||||
}
|
}
|
||||||
if (num_returns_per_match > 1 && matchCount >= num_returns_per_match) {
|
if (num_returns_per_match > 1 && matchCount >= num_returns_per_match) {
|
||||||
break;
|
break;
|
||||||
|
|
@ -740,10 +759,9 @@ static Value::VectorType search(const std::string &find, const std::string &tabl
|
||||||
if (matchCount == 0) {
|
if (matchCount == 0) {
|
||||||
gchar utf8_of_cp[6] = ""; //A buffer for a single unicode character to be copied into
|
gchar utf8_of_cp[6] = ""; //A buffer for a single unicode character to be copied into
|
||||||
if (ptr_ft) g_utf8_strncpy(utf8_of_cp, ptr_ft, 1);
|
if (ptr_ft) g_utf8_strncpy(utf8_of_cp, ptr_ft, 1);
|
||||||
PRINTB(" WARNING: search term not found: \"%s\"", utf8_of_cp);
|
|
||||||
}
|
}
|
||||||
if (num_returns_per_match == 0 || num_returns_per_match > 1) {
|
if (num_returns_per_match == 0 || num_returns_per_match > 1) {
|
||||||
returnvec.push_back(Value(resultvec));
|
returnvec.push_back(ValuePtr(resultvec));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return returnvec;
|
return returnvec;
|
||||||
|
|
@ -761,19 +779,19 @@ static Value::VectorType search(const std::string &find, const Value::VectorType
|
||||||
Value::VectorType resultvec;
|
Value::VectorType resultvec;
|
||||||
const gchar *ptr_ft = g_utf8_offset_to_pointer(find.c_str(), i);
|
const gchar *ptr_ft = g_utf8_offset_to_pointer(find.c_str(), i);
|
||||||
for (size_t j = 0; j < searchTableSize; j++) {
|
for (size_t j = 0; j < searchTableSize; j++) {
|
||||||
Value::VectorType entryVec = table[j].toVector();
|
const Value::VectorType &entryVec = table[j]->toVector();
|
||||||
if (entryVec.size() <= index_col_num) {
|
if (entryVec.size() <= index_col_num) {
|
||||||
PRINTB("WARNING: Invalid entry in search vector at index %d, required number of values in the entry: %d. Invalid entry: %s", j % (index_col_num + 1) % table[j]);
|
PRINTB("WARNING: Invalid entry in search vector at index %d, required number of values in the entry: %d. Invalid entry: %s", j % (index_col_num + 1) % table[j]);
|
||||||
return Value::VectorType();
|
return Value::VectorType();
|
||||||
}
|
}
|
||||||
const gchar *ptr_st = g_utf8_offset_to_pointer(entryVec[index_col_num].toString().c_str(), 0);
|
const gchar *ptr_st = g_utf8_offset_to_pointer(entryVec[index_col_num]->toString().c_str(), 0);
|
||||||
if (ptr_ft && ptr_st && (g_utf8_get_char(ptr_ft) == g_utf8_get_char(ptr_st)) ) {
|
if (ptr_ft && ptr_st && (g_utf8_get_char(ptr_ft) == g_utf8_get_char(ptr_st)) ) {
|
||||||
matchCount++;
|
matchCount++;
|
||||||
if (num_returns_per_match == 1) {
|
if (num_returns_per_match == 1) {
|
||||||
returnvec.push_back(Value(double(j)));
|
returnvec.push_back(ValuePtr(double(j)));
|
||||||
break;
|
break;
|
||||||
} else {
|
} else {
|
||||||
resultvec.push_back(Value(double(j)));
|
resultvec.push_back(ValuePtr(double(j)));
|
||||||
}
|
}
|
||||||
if (num_returns_per_match > 1 && matchCount >= num_returns_per_match) {
|
if (num_returns_per_match > 1 && matchCount >= num_returns_per_match) {
|
||||||
break;
|
break;
|
||||||
|
|
@ -786,7 +804,7 @@ static Value::VectorType search(const std::string &find, const Value::VectorType
|
||||||
PRINTB(" WARNING: search term not found: \"%s\"", utf8_of_cp);
|
PRINTB(" WARNING: search term not found: \"%s\"", utf8_of_cp);
|
||||||
}
|
}
|
||||||
if (num_returns_per_match == 0 || num_returns_per_match > 1) {
|
if (num_returns_per_match == 0 || num_returns_per_match > 1) {
|
||||||
returnvec.push_back(Value(resultvec));
|
returnvec.push_back(ValuePtr(resultvec));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return returnvec;
|
return returnvec;
|
||||||
|
|
@ -807,12 +825,12 @@ ValuePtr builtin_search(const Context *, const EvalContext *evalctx)
|
||||||
unsigned int matchCount = 0;
|
unsigned int matchCount = 0;
|
||||||
|
|
||||||
for (size_t j = 0; j < searchTable->toVector().size(); j++) {
|
for (size_t j = 0; j < searchTable->toVector().size(); j++) {
|
||||||
const Value &search_element = searchTable->toVector()[j];
|
const ValuePtr &search_element = searchTable->toVector()[j];
|
||||||
|
|
||||||
if ((index_col_num == 0 && *findThis == search_element) ||
|
if ((index_col_num == 0 && findThis == search_element) ||
|
||||||
(index_col_num < search_element.toVector().size() &&
|
(index_col_num < search_element->toVector().size() &&
|
||||||
*findThis == search_element.toVector()[index_col_num])) {
|
findThis == search_element->toVector()[index_col_num])) {
|
||||||
returnvec.push_back(Value(double(j)));
|
returnvec.push_back(ValuePtr(double(j)));
|
||||||
matchCount++;
|
matchCount++;
|
||||||
if (num_returns_per_match != 0 && matchCount >= num_returns_per_match) break;
|
if (num_returns_per_match != 0 && matchCount >= num_returns_per_match) break;
|
||||||
}
|
}
|
||||||
|
|
@ -829,16 +847,16 @@ ValuePtr builtin_search(const Context *, const EvalContext *evalctx)
|
||||||
unsigned int matchCount = 0;
|
unsigned int matchCount = 0;
|
||||||
Value::VectorType resultvec;
|
Value::VectorType resultvec;
|
||||||
|
|
||||||
Value const& find_value = findThis->toVector()[i];
|
const ValuePtr &find_value = findThis->toVector()[i];
|
||||||
|
|
||||||
for (size_t j = 0; j < searchTable->toVector().size(); j++) {
|
for (size_t j = 0; j < searchTable->toVector().size(); j++) {
|
||||||
|
|
||||||
Value const& search_element = searchTable->toVector()[j];
|
const ValuePtr &search_element = searchTable->toVector()[j];
|
||||||
|
|
||||||
if ((index_col_num == 0 && find_value == search_element) ||
|
if ((index_col_num == 0 && find_value == search_element) ||
|
||||||
(index_col_num < search_element.toVector().size() &&
|
(index_col_num < search_element->toVector().size() &&
|
||||||
find_value == search_element.toVector()[index_col_num])) {
|
find_value == search_element->toVector()[index_col_num])) {
|
||||||
Value resultValue((double(j)));
|
ValuePtr resultValue((double(j)));
|
||||||
matchCount++;
|
matchCount++;
|
||||||
if (num_returns_per_match == 1) {
|
if (num_returns_per_match == 1) {
|
||||||
returnvec.push_back(resultValue);
|
returnvec.push_back(resultValue);
|
||||||
|
|
@ -850,20 +868,13 @@ ValuePtr builtin_search(const Context *, const EvalContext *evalctx)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (num_returns_per_match == 1 && matchCount == 0) {
|
if (num_returns_per_match == 1 && matchCount == 0) {
|
||||||
if (findThis->toVector()[i].type() == Value::NUMBER) {
|
returnvec.push_back(ValuePtr(resultvec));
|
||||||
PRINTB(" WARNING: search term not found: %s",findThis->toVector()[i].toDouble());
|
|
||||||
}
|
|
||||||
else if (findThis->toVector()[i].type() == Value::STRING) {
|
|
||||||
PRINTB(" WARNING: search term not found: \"%s\"",findThis->toVector()[i].toString());
|
|
||||||
}
|
|
||||||
returnvec.push_back(resultvec);
|
|
||||||
}
|
}
|
||||||
if (num_returns_per_match == 0 || num_returns_per_match > 1) {
|
if (num_returns_per_match == 0 || num_returns_per_match > 1) {
|
||||||
returnvec.push_back(resultvec);
|
returnvec.push_back(ValuePtr(resultvec));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
PRINTB(" WARNING: search: none performed on input %s", findThis);
|
|
||||||
return ValuePtr::undefined;
|
return ValuePtr::undefined;
|
||||||
}
|
}
|
||||||
return ValuePtr(returnvec);
|
return ValuePtr(returnvec);
|
||||||
|
|
@ -927,12 +938,12 @@ ValuePtr builtin_norm(const Context *, const EvalContext *evalctx)
|
||||||
ValuePtr val = evalctx->getArgValue(0);
|
ValuePtr val = evalctx->getArgValue(0);
|
||||||
if (val->type() == Value::VECTOR) {
|
if (val->type() == Value::VECTOR) {
|
||||||
double sum = 0;
|
double sum = 0;
|
||||||
Value::VectorType v = val->toVector();
|
const Value::VectorType &v = val->toVector();
|
||||||
size_t n = v.size();
|
size_t n = v.size();
|
||||||
for (size_t i = 0; i < n; i++)
|
for (size_t i = 0; i < n; i++)
|
||||||
if (v[i].type() == Value::NUMBER) {
|
if (v[i]->type() == Value::NUMBER) {
|
||||||
// sum += pow(v[i].toDouble(),2);
|
// sum += pow(v[i].toDouble(),2);
|
||||||
register double x = v[i].toDouble();
|
register double x = v[i]->toDouble();
|
||||||
sum += x*x;
|
sum += x*x;
|
||||||
} else {
|
} else {
|
||||||
PRINT("WARNING: Incorrect arguments to norm()");
|
PRINT("WARNING: Incorrect arguments to norm()");
|
||||||
|
|
@ -958,10 +969,10 @@ ValuePtr builtin_cross(const Context *, const EvalContext *evalctx)
|
||||||
return ValuePtr::undefined;
|
return ValuePtr::undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
Value::VectorType v0 = arg0->toVector();
|
const Value::VectorType &v0 = arg0->toVector();
|
||||||
Value::VectorType v1 = arg1->toVector();
|
const Value::VectorType &v1 = arg1->toVector();
|
||||||
if ((v0.size() == 2) && (v1.size() == 2)) {
|
if ((v0.size() == 2) && (v1.size() == 2)) {
|
||||||
return ValuePtr(Value(v0[0].toDouble() * v1[1].toDouble() - v0[1].toDouble() * v1[0].toDouble()));
|
return ValuePtr(v0[0]->toDouble() * v1[1]->toDouble() - v0[1]->toDouble() * v1[0]->toDouble());
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((v0.size() != 3) || (v1.size() != 3)) {
|
if ((v0.size() != 3) || (v1.size() != 3)) {
|
||||||
|
|
@ -969,12 +980,12 @@ ValuePtr builtin_cross(const Context *, const EvalContext *evalctx)
|
||||||
return ValuePtr::undefined;
|
return ValuePtr::undefined;
|
||||||
}
|
}
|
||||||
for (unsigned int a = 0;a < 3;a++) {
|
for (unsigned int a = 0;a < 3;a++) {
|
||||||
if ((v0[a].type() != Value::NUMBER) || (v1[a].type() != Value::NUMBER)) {
|
if ((v0[a]->type() != Value::NUMBER) || (v1[a]->type() != Value::NUMBER)) {
|
||||||
PRINT("WARNING: Invalid value in parameter vector for cross()");
|
PRINT("WARNING: Invalid value in parameter vector for cross()");
|
||||||
return ValuePtr::undefined;
|
return ValuePtr::undefined;
|
||||||
}
|
}
|
||||||
double d0 = v0[a].toDouble();
|
double d0 = v0[a]->toDouble();
|
||||||
double d1 = v1[a].toDouble();
|
double d1 = v1[a]->toDouble();
|
||||||
if (boost::math::isnan(d0) || boost::math::isnan(d1)) {
|
if (boost::math::isnan(d0) || boost::math::isnan(d1)) {
|
||||||
PRINT("WARNING: Invalid value (NaN) in parameter vector for cross()");
|
PRINT("WARNING: Invalid value (NaN) in parameter vector for cross()");
|
||||||
return ValuePtr::undefined;
|
return ValuePtr::undefined;
|
||||||
|
|
@ -985,14 +996,14 @@ ValuePtr builtin_cross(const Context *, const EvalContext *evalctx)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
double x = v0[1].toDouble() * v1[2].toDouble() - v0[2].toDouble() * v1[1].toDouble();
|
double x = v0[1]->toDouble() * v1[2]->toDouble() - v0[2]->toDouble() * v1[1]->toDouble();
|
||||||
double y = v0[2].toDouble() * v1[0].toDouble() - v0[0].toDouble() * v1[2].toDouble();
|
double y = v0[2]->toDouble() * v1[0]->toDouble() - v0[0]->toDouble() * v1[2]->toDouble();
|
||||||
double z = v0[0].toDouble() * v1[1].toDouble() - v0[1].toDouble() * v1[0].toDouble();
|
double z = v0[0]->toDouble() * v1[1]->toDouble() - v0[1]->toDouble() * v1[0]->toDouble();
|
||||||
|
|
||||||
Value::VectorType result;
|
Value::VectorType result;
|
||||||
result.push_back(Value(x));
|
result.push_back(ValuePtr(x));
|
||||||
result.push_back(Value(y));
|
result.push_back(ValuePtr(y));
|
||||||
result.push_back(Value(z));
|
result.push_back(ValuePtr(z));
|
||||||
return ValuePtr(result);
|
return ValuePtr(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@
|
||||||
#include "mathc99.h"
|
#include "mathc99.h"
|
||||||
#include "linalg.h"
|
#include "linalg.h"
|
||||||
|
|
||||||
#ifdef WIN32
|
#ifdef _WIN32
|
||||||
typedef __int64 int64_t;
|
typedef __int64 int64_t;
|
||||||
#else
|
#else
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
|
||||||
|
|
@ -319,10 +319,7 @@ std::string ImportNode::toString() const
|
||||||
"scale = " << this->scale << ", "
|
"scale = " << this->scale << ", "
|
||||||
"convexity = " << this->convexity << ", "
|
"convexity = " << this->convexity << ", "
|
||||||
"$fn = " << this->fn << ", $fa = " << this->fa << ", $fs = " << this->fs
|
"$fn = " << this->fn << ", $fa = " << this->fa << ", $fs = " << this->fs
|
||||||
#ifndef OPENSCAD_TESTING
|
|
||||||
// timestamp is needed for caching, but disturbs the test framework
|
|
||||||
<< ", " "timestamp = " << (fs::exists(path) ? fs::last_write_time(path) : 0)
|
<< ", " "timestamp = " << (fs::exists(path) ? fs::last_write_time(path) : 0)
|
||||||
#endif
|
|
||||||
<< ")";
|
<< ")";
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -46,3 +46,72 @@ bool matrix_contains_nan( const Transform3d &m )
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Hash a floating point number, copied almost line by line from
|
||||||
|
Python's pyhash.c, originally by the Python team, Mark Dickinson, et al.
|
||||||
|
The copyright License for this code can be found in under
|
||||||
|
../doc/Python-LICENSE.TXT. Changes from the original code include
|
||||||
|
de-scattering typedefs, and removing the -1 special return case.
|
||||||
|
|
||||||
|
This is designed so srand() will work better with floating point
|
||||||
|
numbers. An oversimplified explanation is that the code calculates the
|
||||||
|
Remainder of the input divided by 2^31, in a very portable way. See also:
|
||||||
|
|
||||||
|
http://bob.ippoli.to/archives/2010/03/23/py3k-unified-numeric-hash/
|
||||||
|
https://github.com/python/cpython/blob/master/Python/pyhash.c
|
||||||
|
https://github.com/python/cpython/blob/master/Include/pyhash.h
|
||||||
|
http://stackoverflow.com/questions/4238122/hash-function-for-floats
|
||||||
|
http://betterexplained.com/articles/fun-with-modular-arithmetic/
|
||||||
|
*/
|
||||||
|
typedef int32_t Py_hash_t;
|
||||||
|
typedef uint32_t Py_uhash_t;
|
||||||
|
typedef double Float_t;
|
||||||
|
Py_hash_t hash_floating_point(Float_t v)
|
||||||
|
{
|
||||||
|
int _PyHASH_BITS = 31;
|
||||||
|
//if (sizeof(Py_uhash_t)==8) _PyHASH_BITS=61;
|
||||||
|
|
||||||
|
Py_uhash_t _PyHASH_MODULUS = (((Py_uhash_t)1 << _PyHASH_BITS) - 1);
|
||||||
|
Py_uhash_t _PyHASH_INF = 314159;
|
||||||
|
Py_uhash_t _PyHASH_NAN = 0;
|
||||||
|
|
||||||
|
int e, sign;
|
||||||
|
Float_t m;
|
||||||
|
Py_uhash_t x, y;
|
||||||
|
|
||||||
|
if (!std::isfinite(v)) {
|
||||||
|
if (std::isinf(v))
|
||||||
|
return v > 0 ? _PyHASH_INF : -_PyHASH_INF;
|
||||||
|
else
|
||||||
|
return _PyHASH_NAN;
|
||||||
|
}
|
||||||
|
|
||||||
|
m = frexp(v, &e);
|
||||||
|
|
||||||
|
sign = 1;
|
||||||
|
if (m < 0) {
|
||||||
|
sign = -1;
|
||||||
|
m = -m;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* process 28 bits at a time; this should work well both for binary
|
||||||
|
and hexadecimal floating point. */
|
||||||
|
x = 0;
|
||||||
|
while (m) {
|
||||||
|
x = ((x << 28) & _PyHASH_MODULUS) | x >> (_PyHASH_BITS - 28);
|
||||||
|
m *= 268435456.0; // 2**28
|
||||||
|
e -= 28;
|
||||||
|
y = (Py_uhash_t)m; /* pull out integer part */
|
||||||
|
m -= y;
|
||||||
|
x += y;
|
||||||
|
if (x >= _PyHASH_MODULUS)
|
||||||
|
x -= _PyHASH_MODULUS;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* adjust for the exponent; first reduce it modulo _PyHASH_BITS */
|
||||||
|
e = e >= 0 ? e % _PyHASH_BITS : _PyHASH_BITS-1-((-1-e) % _PyHASH_BITS);
|
||||||
|
x = ((x << e) & _PyHASH_MODULUS) | x >> (_PyHASH_BITS - e);
|
||||||
|
|
||||||
|
x = x * sign;
|
||||||
|
return (Py_hash_t)x;
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,7 @@
|
||||||
#include <Eigen/Geometry>
|
#include <Eigen/Geometry>
|
||||||
#include <Eigen/Dense>
|
#include <Eigen/Dense>
|
||||||
#include <Eigen/StdVector>
|
#include <Eigen/StdVector>
|
||||||
|
#include <boost/cstdint.hpp>
|
||||||
|
|
||||||
EIGEN_DEFINE_STL_VECTOR_SPECIALIZATION(Eigen::Vector2d)
|
EIGEN_DEFINE_STL_VECTOR_SPECIALIZATION(Eigen::Vector2d)
|
||||||
using Eigen::Vector2d;
|
using Eigen::Vector2d;
|
||||||
|
|
@ -23,6 +24,7 @@ using Eigen::Matrix4d;
|
||||||
|
|
||||||
bool matrix_contains_infinity( const Transform3d &m );
|
bool matrix_contains_infinity( const Transform3d &m );
|
||||||
bool matrix_contains_nan( const Transform3d &m );
|
bool matrix_contains_nan( const Transform3d &m );
|
||||||
|
int32_t hash_floating_point( double v );
|
||||||
|
|
||||||
template<typename Derived> bool is_finite(const Eigen::MatrixBase<Derived>& x) {
|
template<typename Derived> bool is_finite(const Eigen::MatrixBase<Derived>& x) {
|
||||||
return ( (x - x).array() == (x - x).array()).all();
|
return ( (x - x).array() == (x - x).array()).all();
|
||||||
|
|
|
||||||
|
|
@ -90,13 +90,13 @@ AbstractNode *LinearExtrudeModule::instantiate(const Context *ctx, const ModuleI
|
||||||
|
|
||||||
node->layername = layer->isUndefined() ? "" : layer->toString();
|
node->layername = layer->isUndefined() ? "" : layer->toString();
|
||||||
node->height = 100;
|
node->height = 100;
|
||||||
height->getDouble(node->height);
|
height->getFiniteDouble(node->height);
|
||||||
node->convexity = (int)convexity->toDouble();
|
node->convexity = (int)convexity->toDouble();
|
||||||
origin->getVec2(node->origin_x, node->origin_y);
|
origin->getVec2(node->origin_x, node->origin_y, true);
|
||||||
node->scale_x = node->scale_y = 1;
|
node->scale_x = node->scale_y = 1;
|
||||||
scale->getDouble(node->scale_x);
|
scale->getFiniteDouble(node->scale_x);
|
||||||
scale->getDouble(node->scale_y);
|
scale->getFiniteDouble(node->scale_y);
|
||||||
scale->getVec2(node->scale_x, node->scale_y);
|
scale->getVec2(node->scale_x, node->scale_y, true);
|
||||||
|
|
||||||
if (center->type() == Value::BOOL)
|
if (center->type() == Value::BOOL)
|
||||||
node->center = center->toBool();
|
node->center = center->toBool();
|
||||||
|
|
@ -109,17 +109,17 @@ AbstractNode *LinearExtrudeModule::instantiate(const Context *ctx, const ModuleI
|
||||||
if (node->scale_x < 0) node->scale_x = 0;
|
if (node->scale_x < 0) node->scale_x = 0;
|
||||||
if (node->scale_y < 0) node->scale_y = 0;
|
if (node->scale_y < 0) node->scale_y = 0;
|
||||||
|
|
||||||
if (slices->type() == Value::NUMBER) node->slices = (int)slices->toDouble();
|
double slicesVal = 0;
|
||||||
|
slices->getFiniteDouble(slicesVal);
|
||||||
|
node->slices = (int)slicesVal;
|
||||||
|
|
||||||
if (twist->type() == Value::NUMBER) {
|
node->twist = 0.0;
|
||||||
node->twist = twist->toDouble();
|
twist->getFiniteDouble(node->twist);
|
||||||
if (node->twist != 0.0) {
|
if (node->twist != 0.0) {
|
||||||
if (node->slices == 0) {
|
if (node->slices == 0) {
|
||||||
node->slices = (int)fmax(2, fabs(Calc::get_fragments_from_r(node->height,
|
node->slices = (int)fmax(2, fabs(Calc::get_fragments_from_r(node->height, node->fn, node->fs, node->fa) * node->twist / 360));
|
||||||
node->fn, node->fs, node->fa) * node->twist / 360));
|
|
||||||
}
|
|
||||||
node->has_twist = true;
|
|
||||||
}
|
}
|
||||||
|
node->has_twist = true;
|
||||||
}
|
}
|
||||||
node->slices = std::max(node->slices, 1);
|
node->slices = std::max(node->slices, 1);
|
||||||
|
|
||||||
|
|
@ -142,10 +142,7 @@ std::string LinearExtrudeNode::toString() const
|
||||||
"file = " << this->filename << ", "
|
"file = " << this->filename << ", "
|
||||||
"layer = " << QuotedString(this->layername) << ", "
|
"layer = " << QuotedString(this->layername) << ", "
|
||||||
"origin = [" << this->origin_x << ", " << this->origin_y << "], "
|
"origin = [" << this->origin_x << ", " << this->origin_y << "], "
|
||||||
#ifndef OPENSCAD_TESTING
|
|
||||||
// timestamp is needed for caching, but disturbs the test framework
|
|
||||||
<< "timestamp = " << (fs::exists(path) ? fs::last_write_time(path) : 0) << ", "
|
<< "timestamp = " << (fs::exists(path) ? fs::last_write_time(path) : 0) << ", "
|
||||||
#endif
|
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
stream <<
|
stream <<
|
||||||
|
|
|
||||||
199
src/mainwin.cc
199
src/mainwin.cc
|
|
@ -93,6 +93,16 @@
|
||||||
#include <QClipboard>
|
#include <QClipboard>
|
||||||
#include <QDesktopWidget>
|
#include <QDesktopWidget>
|
||||||
|
|
||||||
|
#if (QT_VERSION < QT_VERSION_CHECK(5, 1, 0))
|
||||||
|
// Set dummy for Qt versions that do not have QSaveFile
|
||||||
|
#define QT_FILE_SAVE_CLASS QFile
|
||||||
|
#define QT_FILE_SAVE_COMMIT true
|
||||||
|
#else
|
||||||
|
#include <QSaveFile>
|
||||||
|
#define QT_FILE_SAVE_CLASS QSaveFile
|
||||||
|
#define QT_FILE_SAVE_COMMIT if (saveOk) { saveOk = file.commit(); } else { file.cancelWriting(); }
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
|
@ -243,9 +253,11 @@ MainWindow::MainWindow(const QString &filename)
|
||||||
background_chain = NULL;
|
background_chain = NULL;
|
||||||
root_node = NULL;
|
root_node = NULL;
|
||||||
|
|
||||||
tval = 0;
|
this->anim_step = 0;
|
||||||
fps = 0;
|
this->anim_numsteps = 0;
|
||||||
fsteps = 1;
|
this->anim_tval = 0.0;
|
||||||
|
this->anim_dumping = false;
|
||||||
|
this->anim_dump_start_step = 0;
|
||||||
|
|
||||||
const QString importStatement = "import(\"%1\");\n";
|
const QString importStatement = "import(\"%1\");\n";
|
||||||
const QString surfaceStatement = "surface(\"%1\");\n";
|
const QString surfaceStatement = "surface(\"%1\");\n";
|
||||||
|
|
@ -279,8 +291,10 @@ MainWindow::MainWindow(const QString &filename)
|
||||||
waitAfterReloadTimer->setInterval(200);
|
waitAfterReloadTimer->setInterval(200);
|
||||||
connect(waitAfterReloadTimer, SIGNAL(timeout()), this, SLOT(waitAfterReload()));
|
connect(waitAfterReloadTimer, SIGNAL(timeout()), this, SLOT(waitAfterReload()));
|
||||||
|
|
||||||
connect(this->e_tval, SIGNAL(textChanged(QString)), this, SLOT(actionRenderPreview()));
|
connect(this->e_tval, SIGNAL(textChanged(QString)), this, SLOT(updatedAnimTval()));
|
||||||
connect(this->e_fps, SIGNAL(textChanged(QString)), this, SLOT(updatedFps()));
|
connect(this->e_fps, SIGNAL(textChanged(QString)), this, SLOT(updatedAnimFps()));
|
||||||
|
connect(this->e_fsteps, SIGNAL(textChanged(QString)), this, SLOT(updatedAnimSteps()));
|
||||||
|
connect(this->e_dump, SIGNAL(toggled(bool)), this, SLOT(updatedAnimDump(bool)));
|
||||||
|
|
||||||
animate_panel->hide();
|
animate_panel->hide();
|
||||||
find_panel->hide();
|
find_panel->hide();
|
||||||
|
|
@ -325,6 +339,7 @@ MainWindow::MainWindow(const QString &filename)
|
||||||
connect(this->editActionCut, SIGNAL(triggered()), editor, SLOT(cut()));
|
connect(this->editActionCut, SIGNAL(triggered()), editor, SLOT(cut()));
|
||||||
connect(this->editActionCopy, SIGNAL(triggered()), editor, SLOT(copy()));
|
connect(this->editActionCopy, SIGNAL(triggered()), editor, SLOT(copy()));
|
||||||
connect(this->editActionPaste, SIGNAL(triggered()), editor, SLOT(paste()));
|
connect(this->editActionPaste, SIGNAL(triggered()), editor, SLOT(paste()));
|
||||||
|
connect(this->editActionCopyViewport, SIGNAL(triggered()), this, SLOT(actionCopyViewport()));
|
||||||
connect(this->editActionIndent, SIGNAL(triggered()), editor, SLOT(indentSelection()));
|
connect(this->editActionIndent, SIGNAL(triggered()), editor, SLOT(indentSelection()));
|
||||||
connect(this->editActionUnindent, SIGNAL(triggered()), editor, SLOT(unindentSelection()));
|
connect(this->editActionUnindent, SIGNAL(triggered()), editor, SLOT(unindentSelection()));
|
||||||
connect(this->editActionComment, SIGNAL(triggered()), editor, SLOT(commentSelection()));
|
connect(this->editActionComment, SIGNAL(triggered()), editor, SLOT(commentSelection()));
|
||||||
|
|
@ -814,33 +829,67 @@ void MainWindow::updateRecentFiles()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::updatedFps()
|
void MainWindow::updatedAnimTval()
|
||||||
|
{
|
||||||
|
bool t_ok;
|
||||||
|
double t = this->e_tval->text().toDouble(&t_ok);
|
||||||
|
// Clamp t to 0-1
|
||||||
|
if (t_ok) {
|
||||||
|
this->anim_tval = t < 0 ? 0.0 : ((t > 1.0) ? 1.0 : t);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
this->anim_tval = 0.0;
|
||||||
|
}
|
||||||
|
actionRenderPreview();
|
||||||
|
}
|
||||||
|
|
||||||
|
void MainWindow::updatedAnimFps()
|
||||||
{
|
{
|
||||||
bool fps_ok;
|
bool fps_ok;
|
||||||
double fps = this->e_fps->text().toDouble(&fps_ok);
|
double fps = this->e_fps->text().toDouble(&fps_ok);
|
||||||
animate_timer->stop();
|
animate_timer->stop();
|
||||||
if (fps_ok && fps > 0) {
|
if (fps_ok && fps > 0) {
|
||||||
|
this->anim_step = int(this->anim_tval * this->anim_numsteps) % this->anim_numsteps;
|
||||||
animate_timer->setSingleShot(false);
|
animate_timer->setSingleShot(false);
|
||||||
animate_timer->setInterval(int(1000 / this->e_fps->text().toDouble()));
|
animate_timer->setInterval(int(1000 / fps));
|
||||||
animate_timer->start();
|
animate_timer->start();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MainWindow::updatedAnimSteps()
|
||||||
|
{
|
||||||
|
bool steps_ok;
|
||||||
|
int numsteps = this->e_fsteps->text().toInt(&steps_ok);
|
||||||
|
if (steps_ok) {
|
||||||
|
this->anim_numsteps = numsteps;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
this->anim_numsteps = 0;
|
||||||
|
}
|
||||||
|
anim_dumping=false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MainWindow::updatedAnimDump(bool checked)
|
||||||
|
{
|
||||||
|
if (!checked) this->anim_dumping = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Only called from animate_timer
|
||||||
void MainWindow::updateTVal()
|
void MainWindow::updateTVal()
|
||||||
{
|
{
|
||||||
bool fps_ok;
|
if (this->anim_numsteps == 0) return;
|
||||||
double fps = this->e_fps->text().toDouble(&fps_ok);
|
|
||||||
if (fps_ok) {
|
if (this->anim_numsteps > 1) {
|
||||||
if (fps <= 0) {
|
this->anim_step = (this->anim_step + 1) % this->anim_numsteps;
|
||||||
actionReloadRenderPreview();
|
this->anim_tval = 1.0 * this->anim_step / this->anim_numsteps;
|
||||||
} else {
|
|
||||||
double s = this->e_fsteps->text().toDouble();
|
|
||||||
double t = this->e_tval->text().toDouble() + 1/s;
|
|
||||||
QString txt;
|
|
||||||
txt.sprintf("%.5f", t >= 1.0 ? 0.0 : t);
|
|
||||||
this->e_tval->setText(txt);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
else if (this->anim_numsteps > 0) {
|
||||||
|
this->anim_step = 0;
|
||||||
|
this->anim_tval = 0.0;
|
||||||
|
}
|
||||||
|
QString txt;
|
||||||
|
txt.sprintf("%.5f", this->anim_tval);
|
||||||
|
this->e_tval->setText(txt);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::refreshDocument()
|
void MainWindow::refreshDocument()
|
||||||
|
|
@ -1024,8 +1073,10 @@ void MainWindow::instantiateRoot()
|
||||||
|
|
||||||
// Invalidate renderers before we kill the CSG tree
|
// Invalidate renderers before we kill the CSG tree
|
||||||
this->qglview->setRenderer(NULL);
|
this->qglview->setRenderer(NULL);
|
||||||
|
#ifdef ENABLE_OPENCSG
|
||||||
delete this->opencsgRenderer;
|
delete this->opencsgRenderer;
|
||||||
this->opencsgRenderer = NULL;
|
this->opencsgRenderer = NULL;
|
||||||
|
#endif
|
||||||
delete this->thrownTogetherRenderer;
|
delete this->thrownTogetherRenderer;
|
||||||
this->thrownTogetherRenderer = NULL;
|
this->thrownTogetherRenderer = NULL;
|
||||||
|
|
||||||
|
|
@ -1107,9 +1158,11 @@ void MainWindow::compileCSG(bool procevents)
|
||||||
#else
|
#else
|
||||||
// FIXME: Will we support this?
|
// FIXME: Will we support this?
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef ENABLE_OPENCSG
|
||||||
CSGTermEvaluator csgrenderer(this->tree, &geomevaluator);
|
CSGTermEvaluator csgrenderer(this->tree, &geomevaluator);
|
||||||
if (procevents) QApplication::processEvents();
|
if (procevents) QApplication::processEvents();
|
||||||
this->root_raw_term = csgrenderer.evaluateCSGTerm(*root_node, highlight_terms, background_terms);
|
this->root_raw_term = csgrenderer.evaluateCSGTerm(*root_node, highlight_terms, background_terms);
|
||||||
|
#endif
|
||||||
GeometryCache::instance()->print();
|
GeometryCache::instance()->print();
|
||||||
#ifdef ENABLE_CGAL
|
#ifdef ENABLE_CGAL
|
||||||
CGALCache::instance()->print();
|
CGALCache::instance()->print();
|
||||||
|
|
@ -1169,6 +1222,7 @@ void MainWindow::compileCSG(bool procevents)
|
||||||
PRINTB("WARNING: Normalized tree has %d elements!", this->root_chain->objects.size());
|
PRINTB("WARNING: Normalized tree has %d elements!", this->root_chain->objects.size());
|
||||||
PRINT("WARNING: OpenCSG rendering has been disabled.");
|
PRINT("WARNING: OpenCSG rendering has been disabled.");
|
||||||
}
|
}
|
||||||
|
#ifdef ENABLE_OPENCSG
|
||||||
else {
|
else {
|
||||||
PRINTB("Normalized CSG tree has %d elements",
|
PRINTB("Normalized CSG tree has %d elements",
|
||||||
(this->root_chain ? this->root_chain->objects.size() : 0));
|
(this->root_chain ? this->root_chain->objects.size() : 0));
|
||||||
|
|
@ -1177,6 +1231,7 @@ void MainWindow::compileCSG(bool procevents)
|
||||||
this->background_chain,
|
this->background_chain,
|
||||||
this->qglview->shaderinfo);
|
this->qglview->shaderinfo);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
this->thrownTogetherRenderer = new ThrownTogetherRenderer(this->root_chain,
|
this->thrownTogetherRenderer = new ThrownTogetherRenderer(this->root_chain,
|
||||||
this->highlights_chain,
|
this->highlights_chain,
|
||||||
this->background_chain);
|
this->background_chain);
|
||||||
|
|
@ -1321,6 +1376,16 @@ void MainWindow::saveBackup()
|
||||||
return writeBackup(this->tempFile);
|
return writeBackup(this->tempFile);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MainWindow::saveError(const QIODevice &file, const std::string &msg) {
|
||||||
|
const std::string messageFormat = msg + " %s (%s)";
|
||||||
|
const char *fileName = this->fileName.toLocal8Bit().constData();
|
||||||
|
PRINTB(messageFormat.c_str(), fileName % file.errorString().toLocal8Bit().constData());
|
||||||
|
|
||||||
|
const std::string dialogFormatStr = msg + "\n\"%1\"\n(%2)";
|
||||||
|
const QString dialogFormat(dialogFormatStr.c_str());
|
||||||
|
QMessageBox::warning(this, windowTitle(), dialogFormat.arg(this->fileName).arg(file.errorString()));
|
||||||
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
Save current document.
|
Save current document.
|
||||||
Should _always_ write to disk, since this is called by SaveAs - i.e. don't try to be
|
Should _always_ write to disk, since this is called by SaveAs - i.e. don't try to be
|
||||||
|
|
@ -1330,26 +1395,37 @@ void MainWindow::actionSave()
|
||||||
{
|
{
|
||||||
if (this->fileName.isEmpty()) {
|
if (this->fileName.isEmpty()) {
|
||||||
actionSaveAs();
|
actionSaveAs();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
setCurrentOutput();
|
||||||
|
|
||||||
|
// If available (>= Qt 5.1), use QSaveFile to ensure the file is not
|
||||||
|
// destroyed if the device is full. Unfortunately this is not working
|
||||||
|
// as advertised (at least in Qt 5.3) as it does not detect the device
|
||||||
|
// full properly and happily commits a 0 byte file.
|
||||||
|
// Checking the QTextStream status flag after flush() seems to catch
|
||||||
|
// this condition.
|
||||||
|
QT_FILE_SAVE_CLASS file(this->fileName);
|
||||||
|
if (!file.open(QIODevice::WriteOnly | QIODevice::Truncate | QIODevice::Text)) {
|
||||||
|
saveError(file, _("Failed to open file for writing"));
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
setCurrentOutput();
|
QTextStream writer(&file);
|
||||||
QFile file(this->fileName);
|
writer.setCodec("UTF-8");
|
||||||
if (!file.open(QIODevice::WriteOnly | QIODevice::Truncate | QIODevice::Text)) {
|
writer << this->editor->toPlainText();
|
||||||
PRINTB("Failed to open file for writing: %s (%s)",
|
writer.flush();
|
||||||
this->fileName.toLocal8Bit().constData() % file.errorString().toLocal8Bit().constData());
|
bool saveOk = writer.status() == QTextStream::Ok;
|
||||||
QMessageBox::warning(this, windowTitle(), tr("Failed to open file for writing:\n %1 (%2)")
|
QT_FILE_SAVE_COMMIT;
|
||||||
.arg(this->fileName).arg(file.errorString()));
|
if (saveOk) {
|
||||||
}
|
PRINTB(_("Saved design '%s'."), this->fileName.toLocal8Bit().constData());
|
||||||
else {
|
|
||||||
QTextStream writer(&file);
|
|
||||||
writer.setCodec("UTF-8");
|
|
||||||
writer << this->editor->toPlainText();
|
|
||||||
PRINTB("Saved design '%s'.", this->fileName.toLocal8Bit().constData());
|
|
||||||
this->editor->setContentModified(false);
|
this->editor->setContentModified(false);
|
||||||
|
} else {
|
||||||
|
saveError(file, _("Error saving design"));
|
||||||
}
|
}
|
||||||
clearCurrentOutput();
|
|
||||||
updateRecentFiles();
|
|
||||||
}
|
}
|
||||||
|
clearCurrentOutput();
|
||||||
|
updateRecentFiles();
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::actionSaveAs()
|
void MainWindow::actionSaveAs()
|
||||||
|
|
@ -1538,18 +1614,18 @@ bool MainWindow::eventFilter(QObject* obj, QEvent *event)
|
||||||
|
|
||||||
void MainWindow::updateTemporalVariables()
|
void MainWindow::updateTemporalVariables()
|
||||||
{
|
{
|
||||||
this->top_ctx.set_variable("$t", ValuePtr(this->e_tval->text().toDouble()));
|
this->top_ctx.set_variable("$t", ValuePtr(this->anim_tval));
|
||||||
|
|
||||||
Value::VectorType vpt;
|
Value::VectorType vpt;
|
||||||
vpt.push_back(Value(-qglview->cam.object_trans.x()));
|
vpt.push_back(ValuePtr(-qglview->cam.object_trans.x()));
|
||||||
vpt.push_back(Value(-qglview->cam.object_trans.y()));
|
vpt.push_back(ValuePtr(-qglview->cam.object_trans.y()));
|
||||||
vpt.push_back(Value(-qglview->cam.object_trans.z()));
|
vpt.push_back(ValuePtr(-qglview->cam.object_trans.z()));
|
||||||
this->top_ctx.set_variable("$vpt", Value(vpt));
|
this->top_ctx.set_variable("$vpt", ValuePtr(vpt));
|
||||||
|
|
||||||
Value::VectorType vpr;
|
Value::VectorType vpr;
|
||||||
vpr.push_back(Value(fmodf(360 - qglview->cam.object_rot.x() + 90, 360)));
|
vpr.push_back(ValuePtr(fmodf(360 - qglview->cam.object_rot.x() + 90, 360)));
|
||||||
vpr.push_back(Value(fmodf(360 - qglview->cam.object_rot.y(), 360)));
|
vpr.push_back(ValuePtr(fmodf(360 - qglview->cam.object_rot.y(), 360)));
|
||||||
vpr.push_back(Value(fmodf(360 - qglview->cam.object_rot.z(), 360)));
|
vpr.push_back(ValuePtr(fmodf(360 - qglview->cam.object_rot.z(), 360)));
|
||||||
top_ctx.set_variable("$vpr", ValuePtr(vpr));
|
top_ctx.set_variable("$vpr", ValuePtr(vpr));
|
||||||
|
|
||||||
top_ctx.set_variable("$vpd", ValuePtr(qglview->cam.zoomValue()));
|
top_ctx.set_variable("$vpd", ValuePtr(qglview->cam.zoomValue()));
|
||||||
|
|
@ -1755,15 +1831,22 @@ void MainWindow::csgRender()
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
if (viewActionAnimate->isChecked() && e_dump->isChecked()) {
|
if (e_dump->isChecked() && animate_timer->isActive()) {
|
||||||
// Force reading from front buffer. Some configurations will read from the back buffer here.
|
if (anim_dumping && anim_dump_start_step == anim_step) {
|
||||||
glReadBuffer(GL_FRONT);
|
anim_dumping=false;
|
||||||
QImage img = this->qglview->grabFrameBuffer();
|
e_dump->setChecked(false);
|
||||||
QString filename;
|
} else {
|
||||||
double s = this->e_fsteps->text().toDouble();
|
if (!anim_dumping) {
|
||||||
double t = this->e_tval->text().toDouble();
|
anim_dumping = true;
|
||||||
filename.sprintf("frame%05d.png", int(round(s*t)));
|
anim_dump_start_step = anim_step;
|
||||||
img.save(filename, "PNG");
|
}
|
||||||
|
// Force reading from front buffer. Some configurations will read from the back buffer here.
|
||||||
|
glReadBuffer(GL_FRONT);
|
||||||
|
QImage img = this->qglview->grabFrameBuffer();
|
||||||
|
QString filename;
|
||||||
|
filename.sprintf("frame%05d.png", this->anim_step);
|
||||||
|
img.save(filename, "PNG");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
compileEnded();
|
compileEnded();
|
||||||
|
|
@ -2053,8 +2136,9 @@ void MainWindow::actionExport(export_type_e, QString, QString)
|
||||||
assert(false && "Unknown export type");
|
assert(false && "Unknown export type");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
exportFileByName(this->root_geom.get(), format, export_filename.toUtf8(),
|
exportFileByName(this->root_geom.get(), format,
|
||||||
export_filename.toLocal8Bit().constData());
|
export_filename.toLocal8Bit().constData(),
|
||||||
|
export_filename.toUtf8());
|
||||||
PRINTB("%s export finished.", type_name);
|
PRINTB("%s export finished.", type_name);
|
||||||
|
|
||||||
clearCurrentOutput();
|
clearCurrentOutput();
|
||||||
|
|
@ -2184,6 +2268,13 @@ void MainWindow::actionExportImage()
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MainWindow::actionCopyViewport()
|
||||||
|
{
|
||||||
|
const QImage & image = qglview->grabFrame();
|
||||||
|
QClipboard *clipboard = QApplication::clipboard();
|
||||||
|
clipboard->setImage(image);
|
||||||
|
}
|
||||||
|
|
||||||
void MainWindow::actionFlushCaches()
|
void MainWindow::actionFlushCaches()
|
||||||
{
|
{
|
||||||
GeometryCache::instance()->clear();
|
GeometryCache::instance()->clear();
|
||||||
|
|
@ -2299,7 +2390,7 @@ void MainWindow::viewModeAnimate()
|
||||||
if (viewActionAnimate->isChecked()) {
|
if (viewActionAnimate->isChecked()) {
|
||||||
animate_panel->show();
|
animate_panel->show();
|
||||||
actionRenderPreview();
|
actionRenderPreview();
|
||||||
updatedFps();
|
updatedAnimFps();
|
||||||
} else {
|
} else {
|
||||||
animate_panel->hide();
|
animate_panel->hide();
|
||||||
animate_timer->stop();
|
animate_timer->stop();
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,8 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#ifdef WIN32
|
#if defined(_MSC_VER)
|
||||||
|
|
||||||
|
// only for native windows builds, not MXE
|
||||||
|
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
//for native win32 builds we need to provide C99 math functions by ourselves
|
//for native win32 builds we need to provide C99 math functions by ourselves
|
||||||
|
|
@ -11,6 +13,7 @@ float fmax(float a, float b);
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
|
#define _USE_MATH_DEFINES
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,4 @@
|
||||||
|
#include "mathc99.h"
|
||||||
#include "modcontext.h"
|
#include "modcontext.h"
|
||||||
#include "module.h"
|
#include "module.h"
|
||||||
#include "expression.h"
|
#include "expression.h"
|
||||||
|
|
|
||||||
|
|
@ -272,12 +272,10 @@ Camera get_camera(po::variables_map vm)
|
||||||
return camera;
|
return camera;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef OPENSCAD_TESTING
|
#ifndef OPENSCAD_NOGUI
|
||||||
#undef OPENSCAD_QTGUI
|
|
||||||
#else
|
|
||||||
#define OPENSCAD_QTGUI 1
|
|
||||||
#include <QApplication>
|
#include <QApplication>
|
||||||
#include <QSettings>
|
#include <QSettings>
|
||||||
|
#define OPENSCAD_QTGUI 1
|
||||||
#endif
|
#endif
|
||||||
static bool checkAndExport(shared_ptr<const Geometry> root_geom, unsigned nd,
|
static bool checkAndExport(shared_ptr<const Geometry> root_geom, unsigned nd,
|
||||||
enum FileFormat format, const char *filename)
|
enum FileFormat format, const char *filename)
|
||||||
|
|
@ -383,7 +381,7 @@ int cmdline(const char *deps_output_file, const std::string &filename, Camera &c
|
||||||
AbstractNode *absolute_root_node;
|
AbstractNode *absolute_root_node;
|
||||||
shared_ptr<const Geometry> root_geom;
|
shared_ptr<const Geometry> root_geom;
|
||||||
|
|
||||||
handle_dep(filename.c_str());
|
handle_dep(filename);
|
||||||
|
|
||||||
std::ifstream ifs(filename.c_str());
|
std::ifstream ifs(filename.c_str());
|
||||||
if (!ifs.is_open()) {
|
if (!ifs.is_open()) {
|
||||||
|
|
@ -800,6 +798,7 @@ int main(int argc, char **argv)
|
||||||
("projection", po::value<string>(), "(o)rtho or (p)erspective when exporting png")
|
("projection", po::value<string>(), "(o)rtho or (p)erspective when exporting png")
|
||||||
("colorscheme", po::value<string>(), "colorscheme")
|
("colorscheme", po::value<string>(), "colorscheme")
|
||||||
("debug", po::value<string>(), "special debug info")
|
("debug", po::value<string>(), "special debug info")
|
||||||
|
("quiet,q", "quiet mode (don't print anything *except* errors)")
|
||||||
("o,o", po::value<string>(), "out-file")
|
("o,o", po::value<string>(), "out-file")
|
||||||
("s,s", po::value<string>(), "stl-file")
|
("s,s", po::value<string>(), "stl-file")
|
||||||
("x,x", po::value<string>(), "dxf-file")
|
("x,x", po::value<string>(), "dxf-file")
|
||||||
|
|
@ -835,6 +834,9 @@ int main(int argc, char **argv)
|
||||||
OpenSCAD::debug = vm["debug"].as<string>();
|
OpenSCAD::debug = vm["debug"].as<string>();
|
||||||
PRINTB("Debug on. --debug=%s",OpenSCAD::debug);
|
PRINTB("Debug on. --debug=%s",OpenSCAD::debug);
|
||||||
}
|
}
|
||||||
|
if (vm.count("quiet")) {
|
||||||
|
OpenSCAD::quiet = true;
|
||||||
|
}
|
||||||
if (vm.count("help")) help(argv[0]);
|
if (vm.count("help")) help(argv[0]);
|
||||||
if (vm.count("version")) version();
|
if (vm.count("version")) version();
|
||||||
if (vm.count("info")) arg_info = true;
|
if (vm.count("info")) arg_info = true;
|
||||||
|
|
|
||||||
|
|
@ -102,9 +102,7 @@ void parser_init()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef OPENSCAD_TESTING
|
|
||||||
add_librarydir(PlatformUtils::userLibraryPath());
|
add_librarydir(PlatformUtils::userLibraryPath());
|
||||||
#endif
|
|
||||||
|
|
||||||
add_librarydir(boosty::absolute(PlatformUtils::resourcePath("libraries")).string());
|
add_librarydir(boosty::absolute(PlatformUtils::resourcePath("libraries")).string());
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue