Merge branch 'master' into launchingscreen

Conflicts:
	openscad.pro
	openscad.pro.user
	src/MainWindow.h
	src/Preferences.cc
	src/Preferences.h
	src/Preferences.ui
	src/mainwin.cc
	src/openscad.cc
master
Torsten Paul 2014-09-13 21:19:44 +02:00
commit e7d3025753
346 changed files with 7995 additions and 1968 deletions

2
.gitignore vendored
View File

@ -24,3 +24,5 @@ testdata/scad/misc/include-tests.scad
testdata/scad/misc/use-tests.scad
/mingw32
/mingw64
**/project.xcworkspace
**/xcuserdata

View File

@ -88,6 +88,7 @@ are build scripts that download and compile the libraries from source.
Follow the instructions for the platform you're compiling on below.
* [Qt4 (4.4 - 5.3)](http://www.qt.nokia.com/)
* [QScintilla2 (2.7)](http://www.riverbankcomputing.co.uk/software/qscintilla/)
* [CGAL (3.6 - 4.4)](http://www.cgal.org/)
* [GMP (5.x)](http://www.gmplib.org/)
* [MPFR (3.x)](http://www.mpfr.org/)

View File

@ -16,3 +16,4 @@ include(sparkle.pri)
include(harfbuzz.pri)
include(freetype.pri)
include(fontconfig.pri)
include(scintilla.pri)

Binary file not shown.

View File

@ -0,0 +1,81 @@
<?xml version="1.0"?>
<!DOCTYPE fontconfig SYSTEM "fonts.dtd">
<fontconfig>
<match target="font">
<test name="scalable" compare="eq">
<bool>false</bool>
</test>
<edit name="pixelsizefixupfactor" mode="assign">
<divide>
<name target="pattern">pixelsize</name>
<name target="font" >pixelsize</name>
</divide>
</edit>
</match>
<match target="font">
<test name="scalable" compare="eq">
<bool>false</bool>
</test>
<edit name="scalingnotneeded" mode="assign">
<and>
<less>
<name>pixelsizefixupfactor</name>
<double>1.2</double>
</less>
<more>
<name>pixelsizefixupfactor</name>
<double>0.8</double>
</more>
</and>
</edit>
</match>
<!--
So far we determined the scale factor. Now, check and if
scaling is NOT desirable, just reset the scale factor to 1.0.
-->
<match target="font">
<test name="scalable" compare="eq">
<bool>false</bool>
</test>
<test name="pixelsize" target="pattern" compare="less">
<double>64</double>
</test>
<test name="hinting" compare="eq">
<bool>true</bool>
</test>
<test name="scalingnotneeded" compare="eq">
<bool>true</bool>
</test>
<edit name="pixelsizefixupfactor" mode="assign">
<double>1.0</double>
</edit>
</match>
<!--
If we *are* going to scale, go ahead and do it.
-->
<match target="font">
<test name="scalable" compare="eq">
<bool>false</bool>
</test>
<test name="pixelsizefixupfactor" compare="not_eq">
<double>1.0</double>
</test>
<edit name="matrix" mode="assign">
<times>
<name>matrix</name>
<matrix>
<name>pixelsizefixupfactor</name> <double>0</double>
<double>0</double> <name>pixelsizefixupfactor</name>
</matrix>
</times>
</edit>
<edit name="size" mode="assign">
<divide>
<name>size</name>
<name>pixelsizefixupfactor</name>
</divide>
</edit>
</match>
</fontconfig>

View File

@ -0,0 +1,48 @@
<?xml version="1.0"?>
<!DOCTYPE fontconfig SYSTEM "fonts.dtd">
<fontconfig>
<!--
The Bitstream Vera fonts have GASP entries suggesting that hinting be
disabled below 8 ppem, but FreeType ignores those, preferring to use
the data found in the instructed hints. The initial Vera release
didn't include the right instructions in the 'prep' table. Fix this
by disabling hinting manually at smaller sizes (< 8ppem)
-->
<match target="font">
<test name="family" compare="eq" ignore-blanks="true">
<string>Bitstream Vera Sans</string>
</test>
<test name="pixelsize" compare="less">
<double>7.5</double>
</test>
<edit name="hinting">
<bool>false</bool>
</edit>
</match>
<match target="font">
<test name="family" compare="eq" ignore-blanks="true">
<string>Bitstream Vera Serif</string>
</test>
<test name="pixelsize" compare="less">
<double>7.5</double>
</test>
<edit name="hinting">
<bool>false</bool>
</edit>
</match>
<match target="font">
<test name="family" compare="eq" ignore-blanks="true">
<string>Bitstream Vera Sans Mono</string>
</test>
<test name="pixelsize" compare="less">
<double>7.5</double>
</test>
<edit name="hinting">
<bool>false</bool>
</edit>
</match>
</fontconfig>

View File

@ -0,0 +1,546 @@
<?xml version="1.0"?>
<!DOCTYPE fontconfig SYSTEM "fonts.dtd">
<fontconfig>
<!--
Alias similar/metric-compatible families from various sources:
PostScript fonts: URW fonts: GUST fonts: Windows fonts:
====================== ==================== ================= ==================
Helvetica Nimbus Sans L TeX Gyre Heros
Helvetica Condensed TeX Gyre Heros Cn
Times Nimbus Roman No9 L TeX Gyre Termes
Courier Nimbus Mono L TeX Gyre Cursor
ITC Avant Garde Gothic URW Gothic L TeX Gyre Adventor
ITC Bookman URW Bookman L TeX Gyre Bonum Bookman Old Style
ITC Zapf Chancery URW Chancery L TeX Gyre Chorus
Palatino URW Palladio L TeX Gyre Pagella Palatino Linotype
New Century Schoolbook Century Schoolbook L TeX Gyre Schola Century Schoolbook
Microsoft fonts: Liberation fonts: Google CrOS core fonts: StarOffice fonts: AMT fonts:
================ ====================== ======================= ================= ==============
Arial Liberation Sans Arimo Albany Albany AMT
Arial Narrow Liberation Sans Narrow
Times New Roman Liberation Serif Tinos Thorndale Thorndale AMT
Courier New Liberation Mono Cousine Cumberland Cumberland AMT
Cambria Caladea
Calibri Carlito
Symbol SymbolNeu
Microsoft fonts: Other fonts:
================ ============
Georgia Gelasio
We want for each of them to fallback to any of these available,
but in an order preferring similar designs first. We do this in three steps:
1) Alias each specific to its generic family.
e.g. Liberation Sans to Arial
2) Weak alias each generic to the other generic of its family.
e.g. Arial to Helvetica
3) Alias each generic to its specifics.
e.g. Arial to Liberation Sans, Arimo, Albany, and Albany AMT
-->
<!-- Map specifics to generics -->
<!-- PostScript -->
<alias binding="same">
<family>Nimbus Sans L</family>
<default>
<family>Helvetica</family>
</default>
</alias>
<alias binding="same">
<family>TeX Gyre Heros</family>
<default>
<family>Helvetica</family>
</default>
</alias>
<alias binding="same">
<family>TeX Gyre Heros Cn</family>
<default>
<family>Helvetica Condensed</family>
</default>
</alias>
<alias binding="same">
<family>Nimbus Roman No9 L</family>
<default>
<family>Times</family>
</default>
</alias>
<!--
Due to Bug#73291, commented out those lines until the broken font are fixed.
<alias binding="same">
<family>TeX Gyre Termes</family>
<default>
<family>Times</family>
</default>
</alias>
-->
<alias binding="same">
<family>Nimbus Mono L</family>
<default>
<family>Courier</family>
</default>
</alias>
<alias binding="same">
<family>TeX Gyre Cursor</family>
<default>
<family>Courier</family>
</default>
</alias>
<alias binding="same">
<family>Avant Garde</family>
<default>
<family>ITC Avant Garde Gothic</family>
</default>
</alias>
<alias binding="same">
<family>URW Gothic L</family>
<default>
<family>ITC Avant Garde Gothic</family>
</default>
</alias>
<alias binding="same">
<family>TeX Gyre Adventor</family>
<default>
<family>ITC Avant Garde Gothic</family>
</default>
</alias>
<alias binding="same">
<family>Bookman</family>
<default>
<family>ITC Bookman</family>
</default>
</alias>
<alias binding="same">
<family>URW Bookman L</family>
<default>
<family>ITC Bookman</family>
</default>
</alias>
<alias binding="same">
<family>TeX Gyre Bonum</family>
<default>
<family>ITC Bookman</family>
</default>
</alias>
<alias binding="same">
<family>Bookman Old Style</family>
<default>
<family>ITC Bookman</family>
</default>
</alias>
<alias binding="same">
<family>Zapf Chancery</family>
<default>
<family>ITC Zapf Chancery</family>
</default>
</alias>
<alias binding="same">
<family>URW Chancery L</family>
<default>
<family>ITC Zapf Chancery</family>
</default>
</alias>
<alias binding="same">
<family>TeX Gyre Chorus</family>
<default>
<family>ITC Zapf Chancery</family>
</default>
</alias>
<alias binding="same">
<family>URW Palladio L</family>
<default>
<family>Palatino</family>
</default>
</alias>
<alias binding="same">
<family>TeX Gyre Pagella</family>
<default>
<family>Palatino</family>
</default>
</alias>
<alias binding="same">
<family>Palatino Linotype</family>
<default>
<family>Palatino</family>
</default>
</alias>
<alias binding="same">
<family>Century Schoolbook L</family>
<default>
<family>New Century Schoolbook</family>
</default>
</alias>
<alias binding="same">
<family>TeX Gyre Schola</family>
<default>
<family>New Century Schoolbook</family>
</default>
</alias>
<alias binding="same">
<family>Century Schoolbook</family>
<default>
<family>New Century Schoolbook</family>
</default>
</alias>
<!-- Microsoft -->
<alias binding="same">
<family>Arimo</family>
<default>
<family>Arial</family>
</default>
</alias>
<alias binding="same">
<family>Liberation Sans</family>
<default>
<family>Arial</family>
</default>
</alias>
<alias binding="same">
<family>Liberation Sans Narrow</family>
<default>
<family>Arial Narrow</family>
</default>
</alias>
<alias binding="same">
<family>Albany</family>
<default>
<family>Arial</family>
</default>
</alias>
<alias binding="same">
<family>Albany AMT</family>
<default>
<family>Arial</family>
</default>
</alias>
<alias binding="same">
<family>Tinos</family>
<default>
<family>Times New Roman</family>
</default>
</alias>
<alias binding="same">
<family>Liberation Serif</family>
<default>
<family>Times New Roman</family>
</default>
</alias>
<alias binding="same">
<family>Thorndale</family>
<default>
<family>Times New Roman</family>
</default>
</alias>
<alias binding="same">
<family>Thorndale AMT</family>
<default>
<family>Times New Roman</family>
</default>
</alias>
<alias binding="same">
<family>Cousine</family>
<default>
<family>Courier New</family>
</default>
</alias>
<alias binding="same">
<family>Liberation Mono</family>
<default>
<family>Courier New</family>
</default>
</alias>
<alias binding="same">
<family>Cumberland</family>
<default>
<family>Courier New</family>
</default>
</alias>
<alias binding="same">
<family>Cumberland AMT</family>
<default>
<family>Courier New</family>
</default>
</alias>
<alias binding="same">
<family>Gelasio</family>
<default>
<family>Georgia</family>
</default>
</alias>
<alias binding="same">
<family>Caladea</family>
<default>
<family>Cambria</family>
</default>
</alias>
<alias binding="same">
<family>Carlito</family>
<default>
<family>Calibri</family>
</default>
</alias>
<alias binding="same">
<family>SymbolNeu</family>
<default>
<family>Symbol</family>
</default>
</alias>
<!-- Accept the other group as fallback -->
<!-- PostScript -->
<alias>
<family>Helvetica</family>
<default>
<family>Arial</family>
</default>
</alias>
<alias>
<family>Helvetica Condensed</family>
<default>
<family>Arial Narrow</family>
</default>
</alias>
<alias>
<family>Times</family>
<default>
<family>Times New Roman</family>
</default>
</alias>
<alias>
<family>Courier</family>
<default>
<family>Courier New</family>
</default>
</alias>
<!-- Microsoft -->
<alias>
<family>Arial</family>
<default>
<family>Helvetica</family>
</default>
</alias>
<alias>
<family>Arial Narrow</family>
<default>
<family>Helvetica Condensed</family>
</default>
</alias>
<alias>
<family>Times New Roman</family>
<default>
<family>Times</family>
</default>
</alias>
<alias>
<family>Courier New</family>
<default>
<family>Courier</family>
</default>
</alias>
<!-- Map generics to specifics -->
<!-- PostScript -->
<alias binding="same">
<family>Helvetica</family>
<accept>
<family>TeX Gyre Heros</family>
<family>Nimbus Sans L</family>
</accept>
</alias>
<alias binding="same">
<family>Helvetica Condensed</family>
<accept>
<family>TeX Gyre Heros Cn</family>
</accept>
</alias>
<alias binding="same">
<family>Times</family>
<accept>
<!--
Due to Bug#73291, commented out this line until the broken font are fixed.
<family>TeX Gyre Termes</family>
-->
<family>Nimbus Roman No9 L</family>
</accept>
</alias>
<alias binding="same">
<family>Courier</family>
<accept>
<family>TeX Gyre Cursor</family>
<family>Nimbus Mono L</family>
</accept>
</alias>
<alias binding="same">
<family>ITC Avant Garde Gothic</family>
<accept>
<family>TeX Gyre Adventor</family>
<family>URW Gothic L</family>
</accept>
</alias>
<alias binding="same">
<family>ITC Bookman</family>
<accept>
<family>Bookman Old Style</family>
<family>TeX Gyre Bonum</family>
<family>URW Bookman L</family>
</accept>
</alias>
<alias binding="same">
<family>ITC Zapf Chancery</family>
<accept>
<family>TeX Gyre Chorus</family>
<family>URW Chancery L</family>
</accept>
</alias>
<alias binding="same">
<family>Palatino</family>
<accept>
<family>Palatino Linotype</family>
<family>TeX Gyre Pagella</family>
<family>URW Palladio L</family>
</accept>
</alias>
<alias binding="same">
<family>New Century Schoolbook</family>
<accept>
<family>Century Schoolbook</family>
<family>TeX Gyre Schola</family>
<family>Century Schoolbook L</family>
</accept>
</alias>
<!-- Microsoft -->
<alias binding="same">
<family>Arial</family>
<accept>
<family>Arimo</family>
<family>Liberation Sans</family>
<family>Albany</family>
<family>Albany AMT</family>
</accept>
</alias>
<alias binding="same">
<family>Arial Narrow</family>
<accept>
<family>Liberation Sans Narrow</family>
</accept>
</alias>
<alias binding="same">
<family>Times New Roman</family>
<accept>
<family>Tinos</family>
<family>Liberation Serif</family>
<family>Thorndale</family>
<family>Thorndale AMT</family>
</accept>
</alias>
<alias binding="same">
<family>Courier New</family>
<accept>
<family>Cousine</family>
<family>Liberation Mono</family>
<family>Cumberland</family>
<family>Cumberland AMT</family>
</accept>
</alias>
<alias binding="same">
<family>Georgia</family>
<accept>
<family>Gelasio</family>
</accept>
</alias>
<alias binding="same">
<family>Cambria</family>
<accept>
<family>Caladea</family>
</accept>
</alias>
<alias binding="same">
<family>Calibri</family>
<accept>
<family>Carlito</family>
</accept>
</alias>
<alias binding="same">
<family>Symbol</family>
<accept>
<family>SymbolNeu</family>
</accept>
</alias>
</fontconfig>

View File

@ -0,0 +1,24 @@
<?xml version="1.0"?>
<!DOCTYPE fontconfig SYSTEM "fonts.dtd">
<fontconfig>
<!--
URW provides metric and shape compatible fonts for some Adobe families.
Most of these are handled in 30-metric-aliases.conf.
-->
<alias binding="same">
<family>Zapf Dingbats</family>
<accept><family>Dingbats</family></accept>
</alias>
<alias binding="same">
<family>ITC Zapf Dingbats</family>
<accept><family>Dingbats</family></accept>
</alias>
<match target="pattern">
<test name="family" compare="eq" ignore-blanks="true">
<string>Symbol</string>
</test>
<edit name="family" mode="append" binding="same">
<string>Standard Symbols L</string>
</edit>
</match>
</fontconfig>

View File

@ -0,0 +1,231 @@
<?xml version="1.0"?>
<!DOCTYPE fontconfig SYSTEM "fonts.dtd">
<fontconfig>
<!--
Mark common families with their generics so we'll get
something reasonable
-->
<!--
Serif faces
-->
<alias>
<family>Nazli</family>
<default><family>serif</family></default>
</alias>
<alias>
<family>Lotoos</family>
<default><family>serif</family></default>
</alias>
<alias>
<family>Mitra</family>
<default><family>serif</family></default>
</alias>
<alias>
<family>Ferdosi</family>
<default><family>serif</family></default>
</alias>
<alias>
<family>Badr</family>
<default><family>serif</family></default>
</alias>
<alias>
<family>Zar</family>
<default><family>serif</family></default>
</alias>
<alias>
<family>Titr</family>
<default><family>serif</family></default>
</alias>
<alias>
<family>Jadid</family>
<default><family>serif</family></default>
</alias>
<alias>
<family>Kochi Mincho</family>
<default><family>serif</family></default>
</alias>
<alias>
<family>AR PL SungtiL GB</family>
<default><family>serif</family></default>
</alias>
<alias>
<family>AR PL Mingti2L Big5</family>
<default><family>serif</family></default>
</alias>
<alias>
<family> 明朝</family>
<default><family>serif</family></default>
</alias>
<alias>
<family>NanumMyeongjo</family>
<default><family>serif</family></default>
</alias>
<alias>
<family>UnBatang</family>
<default><family>serif</family></default>
</alias>
<alias>
<family>Baekmuk Batang</family>
<default><family>serif</family></default>
</alias>
<alias>
<family>MgOpen Canonica</family>
<default><family>serif</family></default>
</alias>
<alias>
<family>Sazanami Mincho</family>
<default><family>serif</family></default>
</alias>
<alias>
<family>AR PL ZenKai Uni</family>
<default><family>serif</family></default>
</alias>
<alias>
<family>ZYSong18030</family>
<default><family>serif</family></default>
</alias>
<alias>
<family>FreeSerif</family>
<default><family>serif</family></default>
</alias>
<alias>
<family>SimSun</family>
<default><family>serif</family></default>
</alias>
<!--
Sans-serif faces
-->
<alias>
<family>Arshia</family>
<default><family>sans-serif</family></default>
</alias>
<alias>
<family>Elham</family>
<default><family>sans-serif</family></default>
</alias>
<alias>
<family>Farnaz</family>
<default><family>sans-serif</family></default>
</alias>
<alias>
<family>Nasim</family>
<default><family>sans-serif</family></default>
</alias>
<alias>
<family>Sina</family>
<default><family>sans-serif</family></default>
</alias>
<alias>
<family>Roya</family>
<default><family>sans-serif</family></default>
</alias>
<alias>
<family>Koodak</family>
<default><family>sans-serif</family></default>
</alias>
<alias>
<family>Terafik</family>
<default><family>sans-serif</family></default>
</alias>
<alias>
<family>Kochi Gothic</family>
<default><family>sans-serif</family></default>
</alias>
<alias>
<family>AR PL KaitiM GB</family>
<default><family>sans-serif</family></default>
</alias>
<alias>
<family>AR PL KaitiM Big5</family>
<default><family>sans-serif</family></default>
</alias>
<alias>
<family> ゴシック</family>
<default><family>sans-serif</family></default>
</alias>
<alias>
<family>NanumGothic</family>
<default><family>sans-serif</family></default>
</alias>
<alias>
<family>UnDotum</family>
<default><family>sans-serif</family></default>
</alias>
<alias>
<family>Baekmuk Dotum</family>
<default><family>sans-serif</family></default>
</alias>
<alias>
<family>MgOpen Modata</family>
<default><family>sans-serif</family></default>
</alias>
<alias>
<family>Sazanami Gothic</family>
<default><family>sans-serif</family></default>
</alias>
<alias>
<family>AR PL ShanHeiSun Uni</family>
<default><family>sans-serif</family></default>
</alias>
<alias>
<family>ZYSong18030</family>
<default><family>sans-serif</family></default>
</alias>
<alias>
<family>FreeSans</family>
<default><family>sans-serif</family></default>
</alias>
<!--
Monospace faces
-->
<alias>
<family>NSimSun</family>
<default><family>monospace</family></default>
</alias>
<alias>
<family>ZYSong18030</family>
<default><family>monospace</family></default>
</alias>
<alias>
<family>NanumGothicCoding</family>
<default><family>monospace</family></default>
</alias>
<alias>
<family>FreeMono</family>
<default><family>monospace</family></default>
</alias>
<!--
Fantasy faces
-->
<alias>
<family>Homa</family>
<default><family>fantasy</family></default>
</alias>
<alias>
<family>Kamran</family>
<default><family>fantasy</family></default>
</alias>
<alias>
<family>Fantezi</family>
<default><family>fantasy</family></default>
</alias>
<alias>
<family>Tabassom</family>
<default><family>fantasy</family></default>
</alias>
<!--
Cursive faces
-->
<alias>
<family>IranNastaliq</family>
<default><family>cursive</family></default>
</alias>
<alias>
<family>Nafees Nastaleeq</family>
<default><family>cursive</family></default>
</alias>
</fontconfig>

View File

@ -0,0 +1,189 @@
<?xml version="1.0"?>
<!DOCTYPE fontconfig SYSTEM "fonts.dtd">
<fontconfig>
<!--
Mark common families with their generics so we'll get
something reasonable
-->
<!--
Serif faces
-->
<alias>
<family>Bitstream Vera Serif</family>
<default><family>serif</family></default>
</alias>
<alias>
<family>DejaVu Serif</family>
<default><family>serif</family></default>
</alias>
<alias>
<family>Liberation Serif</family>
<default><family>serif</family></default>
</alias>
<alias>
<family>Times New Roman</family>
<default><family>serif</family></default>
</alias>
<alias>
<family>Times</family>
<default><family>serif</family></default>
</alias>
<alias>
<family>Nimbus Roman No9 L</family>
<default><family>serif</family></default>
</alias>
<alias>
<family>Luxi Serif</family>
<default><family>serif</family></default>
</alias>
<alias>
<family>Thorndale AMT</family>
<default><family>serif</family></default>
</alias>
<alias>
<family>Thorndale</family>
<default><family>serif</family></default>
</alias>
<alias>
<family>Georgia</family>
<default><family>serif</family></default>
</alias>
<alias>
<family>Garamond</family>
<default><family>serif</family></default>
</alias>
<alias>
<family>Palatino Linotype</family>
<default><family>serif</family></default>
</alias>
<alias>
<family>Trebuchet MS</family>
<default><family>serif</family></default>
</alias>
<!--
Sans-serif faces
-->
<alias>
<family>Bitstream Vera Sans</family>
<default><family>sans-serif</family></default>
</alias>
<alias>
<family>DejaVu Sans</family>
<default><family>sans-serif</family></default>
</alias>
<alias>
<family>Liberation Sans</family>
<default><family>sans-serif</family></default>
</alias>
<alias>
<family>Arial</family>
<default><family>sans-serif</family></default>
</alias>
<alias>
<family>Helvetica</family>
<default><family>sans-serif</family></default>
</alias>
<alias>
<family>Verdana</family>
<default><family>sans-serif</family></default>
</alias>
<alias>
<family>Albany AMT</family>
<default><family>sans-serif</family></default>
</alias>
<alias>
<family>Albany</family>
<default><family>sans-serif</family></default>
</alias>
<alias>
<family>Nimbus Sans L</family>
<default><family>sans-serif</family></default>
</alias>
<alias>
<family>Luxi Sans</family>
<default><family>sans-serif</family></default>
</alias>
<!--
Monospace faces
-->
<alias>
<family>Bitstream Vera Sans Mono</family>
<default><family>monospace</family></default>
</alias>
<alias>
<family>DejaVu Sans Mono</family>
<default><family>monospace</family></default>
</alias>
<alias>
<family>Liberation Mono</family>
<default><family>monospace</family></default>
</alias>
<alias>
<family>Inconsolata</family>
<default><family>monospace</family></default>
</alias>
<alias>
<family>Courier New</family>
<default><family>monospace</family></default>
</alias>
<alias>
<family>Courier</family>
<default><family>monospace</family></default>
</alias>
<alias>
<family>Andale Mono</family>
<default><family>monospace</family></default>
</alias>
<alias>
<family>Luxi Mono</family>
<default><family>monospace</family></default>
</alias>
<alias>
<family>Cumberland AMT</family>
<default><family>monospace</family></default>
</alias>
<alias>
<family>Cumberland</family>
<default><family>monospace</family></default>
</alias>
<alias>
<family>Nimbus Mono L</family>
<default><family>monospace</family></default>
</alias>
<!--
Fantasy faces
-->
<alias>
<family>Impact</family>
<default><family>fantasy</family></default>
</alias>
<alias>
<family>Copperplate Gothic Std</family>
<default><family>fantasy</family></default>
</alias>
<alias>
<family>Cooper Std</family>
<default><family>fantasy</family></default>
</alias>
<alias>
<family>Bauhaus Std</family>
<default><family>fantasy</family></default>
</alias>
<!--
Cursive faces
-->
<alias>
<family>ITC Zapf Chancery Std</family>
<default><family>cursive</family></default>
</alias>
<alias>
<family>Zapfino</family>
<default><family>cursive</family></default>
</alias>
<alias>
<family>Comic Sans MS</family>
<default><family>cursive</family></default>
</alias>
</fontconfig>

View File

@ -0,0 +1,21 @@
<?xml version="1.0"?>
<!DOCTYPE fontconfig SYSTEM "fonts.dtd">
<fontconfig>
<!--
If the font still has no generic name, add sans-serif
-->
<match target="pattern">
<test qual="all" name="family" compare="not_eq">
<string>sans-serif</string>
</test>
<test qual="all" name="family" compare="not_eq">
<string>serif</string>
</test>
<test qual="all" name="family" compare="not_eq">
<string>monospace</string>
</test>
<edit name="family" mode="append_last">
<string>sans-serif</string>
</edit>
</match>
</fontconfig>

View File

@ -0,0 +1,15 @@
<?xml version="1.0"?>
<!DOCTYPE fontconfig SYSTEM "fonts.dtd">
<fontconfig>
<!--
Load per-user customization files where stored on XDG Base Directory
specification compliant places. it should be usually:
$HOME/.config/fontconfig/conf.d
$HOME/.config/fontconfig/fonts.conf
-->
<include ignore_missing="yes" prefix="xdg">fontconfig/conf.d</include>
<include ignore_missing="yes" prefix="xdg">fontconfig/fonts.conf</include>
<!-- the following elements will be removed in the future -->
<include ignore_missing="yes" deprecated="yes">~/.fonts.conf.d</include>
<include ignore_missing="yes" deprecated="yes">~/.fonts.conf</include>
</fontconfig>

View File

@ -0,0 +1,6 @@
<?xml version="1.0"?>
<!DOCTYPE fontconfig SYSTEM "fonts.dtd">
<fontconfig>
<!-- Load local system customization file -->
<include ignore_missing="yes">local.conf</include>
</fontconfig>

View File

@ -0,0 +1,70 @@
<?xml version="1.0"?>
<!DOCTYPE fontconfig SYSTEM "fonts.dtd">
<fontconfig>
<alias>
<family>serif</family>
<prefer>
<family>Bitstream Vera Serif</family>
<family>DejaVu Serif</family>
<family>Times New Roman</family>
<family>Thorndale AMT</family>
<family>Luxi Serif</family>
<family>Nimbus Roman No9 L</family>
<family>Times</family>
</prefer>
</alias>
<alias>
<family>sans-serif</family>
<prefer>
<family>Bitstream Vera Sans</family>
<family>DejaVu Sans</family>
<family>Verdana</family>
<family>Arial</family>
<family>Albany AMT</family>
<family>Luxi Sans</family>
<family>Nimbus Sans L</family>
<family>Helvetica</family>
<family>Lucida Sans Unicode</family>
<family>BPG Glaho International</family> <!-- lat,cyr,arab,geor -->
<family>Tahoma</family> <!-- lat,cyr,greek,heb,arab,thai -->
</prefer>
</alias>
<alias>
<family>monospace</family>
<prefer>
<family>Bitstream Vera Sans Mono</family>
<family>DejaVu Sans Mono</family>
<family>Inconsolata</family>
<family>Andale Mono</family>
<family>Courier New</family>
<family>Cumberland AMT</family>
<family>Luxi Mono</family>
<family>Nimbus Mono L</family>
<family>Courier</family>
</prefer>
</alias>
<!--
Fantasy faces
-->
<alias>
<family>fantasy</family>
<prefer>
<family>Impact</family>
<family>Copperplate Gothic Std</family>
<family>Cooper Std</family>
<family>Bauhaus Std</family>
</prefer>
</alias>
<!--
Cursive faces
-->
<alias>
<family>cursive</family>
<prefer>
<family>ITC Zapf Chancery Std</family>
<family>Zapfino</family>
<family>Comic Sans MS</family>
</prefer>
</alias>
</fontconfig>

View File

@ -0,0 +1,419 @@
<?xml version="1.0"?>
<!DOCTYPE fontconfig SYSTEM "fonts.dtd">
<!--
fonts-persian.conf
To configure Persian fonts from The FarsiWeb Project.
Copyright (C) 2005 Sharif FarsiWeb, Inc. <license@farsiweb.info>
Permission to use, copy, modify, distribute, and sell this software and its
documentation for any purpose is hereby granted without fee, 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 Sharif FarsiWeb, Inc. not be used in
advertising or publicity pertaining to distribution of the software without
specific, written prior permission. Sharif FarsiWeb, Inc. makes no
representations about the suitability of this software for any purpose. It
is provided "as is" without express or implied warranty.
SHARIF FARSIWEB, INC. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
EVENT SHALL THE AUTHOR(S) 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.
ChangeLog:
2005-04-03 Behdad Esfahbod: Initial revision.
2005-10-09 Behdad Esfahbod: Turned off back-slant and Tahoma sections.
2005-11-30 Behdad Esfahbod: Set Titr susbtitution size to 24 points.
2008 Behdad Esfahbod: Cleanup. Add fantasy and cursive.
-->
<fontconfig>
<!-- Deprecated fonts are discouraged -->
<!-- Nesf[2] is officially deprecated and has problematic tables -->
<alias binding="same">
<family>Nesf</family>
<accept><family>Nesf2</family></accept>
</alias>
<alias binding="same">
<family>Nesf2</family>
<accept><family>Persian_sansserif_default</family></accept>
</alias>
<!-- Name changes and spelling variant aliases -->
<alias binding="same">
<family>Nazanin</family>
<accept><family>Nazli</family></accept>
</alias>
<alias binding="same">
<family>Lotus</family>
<accept><family>Lotoos</family></accept>
</alias>
<alias binding="same">
<family>Yaqut</family>
<accept><family>Yaghoot</family></accept>
</alias>
<alias binding="same">
<family>Yaghut</family>
<accept><family>Yaghoot</family></accept>
</alias>
<alias binding="same">
<family>Traffic</family>
<accept><family>Terafik</family></accept>
</alias>
<alias binding="same">
<family>Ferdowsi</family>
<accept><family>Ferdosi</family></accept>
</alias>
<alias binding="same">
<family>Fantezy</family>
<accept><family>Fantezi</family></accept>
</alias>
<!-- Classify fonts. -->
<!-- Persian_title class -->
<alias binding="same">
<family>Jadid</family>
<accept><family>Persian_title</family></accept>
</alias>
<alias binding="same">
<family>Titr</family>
<accept><family>Persian_title</family></accept>
</alias>
<!-- Persian_fantasy class -->
<alias binding="same">
<family>Kamran</family>
<accept>
<family>Persian_fantasy</family>
<family>Homa</family>
</accept>
</alias>
<alias binding="same">
<family>Homa</family>
<accept>
<family>Persian_fantasy</family>
<family>Kamran</family>
</accept>
</alias>
<alias binding="same">
<family>Fantezi</family>
<accept><family>Persian_fantasy</family></accept>
</alias>
<alias binding="same">
<family>Tabassom</family>
<accept><family>Persian_fantasy</family></accept>
</alias>
<!-- Persian_square class -->
<alias binding="same">
<family>Arshia</family>
<accept><family>Persian_square</family></accept>
</alias>
<alias binding="same">
<family>Nasim</family>
<accept><family>Persian_square</family></accept>
</alias>
<alias binding="same">
<family>Elham</family>
<accept>
<family>Persian_square</family>
<family>Farnaz</family>
</accept>
</alias>
<alias binding="same">
<family>Farnaz</family>
<accept>
<family>Persian_square</family>
<family>Elham</family>
</accept>
</alias>
<alias binding="same">
<family>Sina</family>
<accept><family>Persian_square</family></accept>
</alias>
<!-- Font ordering per class -->
<!-- Persian_title class -->
<alias binding="same">
<family>Persian_title</family>
<accept>
<family>Titr</family>
<family>Jadid</family>
<family>Persian_serif</family>
</accept>
</alias>
<!-- Persian_fantasy class -->
<alias binding="same">
<family>Persian_fantasy</family>
<accept>
<family>Homa</family>
<family>Kamran</family>
<family>Fantezi</family>
<family>Tabassom</family>
<family>Persian_square</family>
</accept>
</alias>
<!-- Persian_square class -->
<alias binding="same">
<family>Persian_square</family>
<accept>
<family>Arshia</family>
<family>Elham</family>
<family>Farnaz</family>
<family>Nasim</family>
<family>Sina</family>
<family>Persian_serif</family>
</accept>
</alias>
<!-- Register the fonts that we actually do have -->
<match target="scan">
<test name="family" compare="eq" ignore-blanks="true">
<string>Elham</string>
</test>
<edit name="foundry">
<string>farsiweb</string>
</edit>
</match>
<match target="scan">
<test name="family" compare="eq" ignore-blanks="true">
<string>Homa</string>
</test>
<edit name="foundry">
<string>farsiweb</string>
</edit>
</match>
<match target="scan">
<test name="family" compare="eq" ignore-blanks="true">
<string>Koodak</string>
</test>
<edit name="foundry">
<string>farsiweb</string>
</edit>
</match>
<match target="scan">
<test name="family" compare="eq" ignore-blanks="true">
<string>Nazli</string>
</test>
<edit name="foundry">
<string>farsiweb</string>
</edit>
</match>
<match target="scan">
<test name="family" compare="eq" ignore-blanks="true">
<string>Roya</string>
</test>
<edit name="foundry">
<string>farsiweb</string>
</edit>
</match>
<match target="scan">
<test name="family" compare="eq" ignore-blanks="true">
<string>Terafik</string>
</test>
<edit name="foundry">
<string>farsiweb</string>
</edit>
</match>
<match target="scan">
<test name="family" compare="eq" ignore-blanks="true">
<string>Titr</string>
</test>
<edit name="foundry">
<string>farsiweb</string>
</edit>
</match>
<!-- Our fonts should oblique to the other side (TURNED-OFF) -->
<match target="font">
<test name="foundry">
<!--string>farsiweb</string-->
<string>TURNED-OFF</string>
</test>
<test name="foundry">
<string>farsiweb</string>
</test>
<!-- check to see if the font is roman -->
<test name="slant">
<const>roman</const>
</test>
<!-- check to see if the pattern requested non-roman -->
<test target="pattern" name="slant" compare="not_eq">
<const>roman</const>
</test>
<!-- multiply the matrix to slant the font -->
<edit name="matrix" mode="assign">
<times>
<name>matrix</name>
<matrix><double>1</double><double>-0.2</double>
<double>0</double><double>1</double>
</matrix>
</times>
</edit>
<!-- pretend the font is oblique now -->
<edit name="slant" mode="assign">
<const>oblique</const>
</edit>
</match>
<!--
We can't hint our fonts well, so turn off hinting.
Moreover, the bitmaps we have designed (well, they
have designed), suck, so disable them too.
-->
<match target="font">
<test name="foundry">
<string>farsiweb</string>
</test>
<edit name="autohint">
<bool>false</bool>
</edit>
<edit name="hinting">
<bool>false</bool>
</edit>
<edit name="embeddedbitmap">
<bool>false</bool>
</edit>
</match>
<!-- Alias our fonts to common families -->
<!-- Persian serif fonts -->
<alias>
<family>serif</family>
<accept>
<family>Nazli</family>
<family>Lotoos</family>
<family>Mitra</family>
<family>Ferdosi</family>
<family>Badr</family>
<family>Zar</family>
</accept>
</alias>
<!-- Persian sans-serif fonts -->
<alias>
<family>sans-serif</family>
<accept>
<family>Roya</family>
<family>Koodak</family>
<family>Terafik</family>
</accept>
</alias>
<!-- Persian monospace fonts -->
<alias>
<family>monospace</family>
<accept>
<!-- Not really monospace -->
<family>Terafik</family>
</accept>
</alias>
<!-- Persian fantasy fonts -->
<alias>
<family>fantasy</family>
<accept>
<family>Homa</family>
<family>Kamran</family>
<family>Fantezi</family>
<family>Tabassom</family>
</accept>
</alias>
<!-- Persian (and Urdu) Nastaliq/cursive fonts -->
<alias>
<family>cursive</family>
<accept>
<family>IranNastaliq</family>
<family>Nafees Nastaleeq</family>
</accept>
</alias>
<!-- Use Titr in titles -->
<!-- Both serif... -->
<match>
<test name="family">
<string>serif</string>
</test>
<test name="weight" compare="more_eq">
<int>200</int>
</test>
<test name="size" compare="more_eq">
<double>24</double>
</test>
<edit name="family" mode="prepend">
<string>Titr</string>
</edit>
</match>
<!-- and sans-serif. -->
<match>
<test name="family">
<string>sans-serif</string>
</test>
<test name="weight" compare="more_eq">
<int>200</int>
</test>
<test name="size" compare="more_eq">
<double>24</double>
</test>
<edit name="family" mode="prepend">
<string>Titr</string>
</edit>
</match>
<!-- and more. -->
<match>
<test name="family">
<string>Persian_sansserif_default</string>
</test>
<test name="weight" compare="more_eq">
<int>200</int>
</test>
<test name="size" compare="more_eq">
<double>24</double>
</test>
<edit name="family" mode="prepend" binding="same">
<string>Titr</string>
</edit>
</match>
<!-- Default substituted for deprecated sans-serif fonts -->
<match>
<test name="family">
<string>Persian_sansserif_default</string>
</test>
<edit name="family" mode="assign" binding="same">
<string>Roya</string>
</edit>
</match>
</fontconfig>

View File

@ -0,0 +1,196 @@
<?xml version="1.0"?>
<!DOCTYPE fontconfig SYSTEM "fonts.dtd">
<fontconfig>
<alias>
<family>serif</family>
<prefer>
<family>Artsounk</family> <!-- armenian -->
<family>BPG UTF8 M</family> <!-- georgian -->
<family>Kinnari</family> <!-- thai -->
<family>Norasi</family> <!-- thai -->
<family>Frank Ruehl</family> <!-- hebrew -->
<family>Dror</family> <!-- hebrew -->
<family>JG LaoTimes</family> <!-- lao -->
<family>Saysettha Unicode</family> <!-- lao -->
<family>Pigiarniq</family> <!-- canadian syllabics -->
<family>B Davat</family> <!-- arabic (fa) -->
<family>B Compset</family> <!-- arabic (fa) -->
<family>Kacst-Qr</family> <!-- arabic (ar) -->
<family>Urdu Nastaliq Unicode</family> <!-- arabic (ur) -->
<family>Raghindi</family> <!-- devanagari -->
<family>Mukti Narrow</family> <!-- bengali -->
<family>malayalam</family> <!-- malayalam -->
<family>Sampige</family> <!-- kannada -->
<family>padmaa</family> <!-- gujarati -->
<family>Hapax Berbère</family> <!-- tifinagh -->
<family>MS Mincho</family> <!-- han (ja) -->
<family>SimSun</family> <!-- han (zh-cn,zh-tw) -->
<family>PMingLiu</family> <!-- han (zh-tw) -->
<family>WenQuanYi Zen Hei</family> <!-- han (zh-cn,zh-tw) -->
<family>WenQuanYi Bitmap Song</family> <!-- han (zh-cn,zh-tw) -->
<family>AR PL ShanHeiSun Uni</family> <!-- han (ja,zh-cn,zh-tw) -->
<family>AR PL New Sung</family> <!-- han (zh-cn,zh-tw) -->
<family>ZYSong18030</family> <!-- han (zh-cn,zh-tw) -->
<family>HanyiSong</family> <!-- han (zh-cn,zh-tw) -->
<family>MgOpen Canonica</family>
<family>Sazanami Mincho</family>
<family>IPAMonaMincho</family>
<family>IPAMincho</family>
<family>Kochi Mincho</family>
<family>AR PL SungtiL GB</family>
<family>AR PL Mingti2L Big5</family>
<family>AR PL Zenkai Uni</family>
<family> 明朝</family>
<family>ZYSong18030</family>
<family>NanumMyeongjo</family> <!-- hangul (ko) -->
<family>UnBatang</family> <!-- hangul (ko) -->
<family>Baekmuk Batang</family> <!-- hangul (ko) -->
<family>KacstQura</family>
<family>Frank Ruehl CLM</family>
<family>Lohit Bengali</family>
<family>Lohit Gujarati</family>
<family>Lohit Hindi</family>
<family>Lohit Marathi</family>
<family>Lohit Maithili</family>
<family>Lohit Kashmiri</family>
<family>Lohit Konkani</family>
<family>Lohit Nepali</family>
<family>Lohit Sindhi</family>
<family>Lohit Punjabi</family>
<family>Lohit Tamil</family>
<family>Meera</family>
<family>Lohit Malayalam</family>
<family>Lohit Kannada</family>
<family>Lohit Telugu</family>
<family>Lohit Oriya</family>
<family>LKLUG</family>
</prefer>
</alias>
<alias>
<family>sans-serif</family>
<prefer>
<family>Nachlieli</family> <!-- hebrew -->
<family>Lucida Sans Unicode</family>
<family>Yudit Unicode</family>
<family>Kerkis</family> <!-- greek -->
<family>ArmNet Helvetica</family> <!-- armenian -->
<family>Artsounk</family> <!-- armenian -->
<family>BPG UTF8 M</family> <!-- georgian -->
<family>Waree</family> <!-- thai -->
<family>Loma</family> <!-- thai -->
<family>Garuda</family> <!-- thai -->
<family>Umpush</family> <!-- thai -->
<family>Saysettha Unicode</family> <!-- lao? -->
<family>JG Lao Old Arial</family> <!-- lao -->
<family>GF Zemen Unicode</family> <!-- ethiopic -->
<family>Pigiarniq</family> <!-- canadian syllabics -->
<family>B Davat</family> <!-- arabic (fa) -->
<family>B Compset</family> <!-- arabic (fa) -->
<family>Kacst-Qr</family> <!-- arabic (ar) -->
<family>Urdu Nastaliq Unicode</family> <!-- arabic (ur) -->
<family>Raghindi</family> <!-- devanagari -->
<family>Mukti Narrow</family> <!-- bengali -->
<family>malayalam</family> <!-- malayalam -->
<family>Sampige</family> <!-- kannada -->
<family>padmaa</family> <!-- gujarati -->
<family>Hapax Berbère</family> <!-- tifinagh -->
<family>MS Gothic</family> <!-- han (ja) -->
<family>UmePlus P Gothic</family> <!-- han (ja) -->
<!-- chinese fonts are actually serifed -->
<family>SimSun</family> <!-- han (zh-cn,zh-tw) -->
<family>PMingLiu</family> <!-- han (zh-tw) -->
<family>WenQuanYi Zen Hei</family> <!-- han (zh-cn,zh-tw) -->
<family>WenQuanYi Bitmap Song</family> <!-- han (zh-cn,zh-tw) -->
<family>AR PL ShanHeiSun Uni</family> <!--han (ja,zh-cn,zh-tw) -->
<family>AR PL New Sung</family> <!-- han (zh-cn,zh-tw) -->
<family>MgOpen Modata</family>
<family>VL Gothic</family>
<family>IPAMonaGothic</family>
<family>IPAGothic</family>
<family>Sazanami Gothic</family>
<family>Kochi Gothic</family>
<family>AR PL KaitiM GB</family>
<family>AR PL KaitiM Big5</family>
<family>AR PL ShanHeiSun Uni</family>
<family>AR PL SungtiL GB</family>
<family>AR PL Mingti2L Big5</family>
<family> ゴシック</family>
<family>ZYSong18030</family> <!-- han (zh-cn,zh-tw) -->
<family>TSCu_Paranar</family> <!-- tamil -->
<family>NanumGothic</family> <!-- hangul (ko) -->
<family>UnDotum</family> <!-- hangul (ko) -->
<family>Baekmuk Dotum</family> <!-- hangul (ko) -->
<family>Baekmuk Gulim</family> <!-- hangul (ko) -->
<family>KacstQura</family>
<family>Lohit Bengali</family>
<family>Lohit Gujarati</family>
<family>Lohit Hindi</family>
<family>Lohit Marathi</family>
<family>Lohit Maithili</family>
<family>Lohit Kashmiri</family>
<family>Lohit Konkani</family>
<family>Lohit Nepali</family>
<family>Lohit Sindhi</family>
<family>Lohit Punjabi</family>
<family>Lohit Tamil</family>
<family>Meera</family>
<family>Lohit Malayalam</family>
<family>Lohit Kannada</family>
<family>Lohit Telugu</family>
<family>Lohit Oriya</family>
<family>LKLUG</family>
</prefer>
</alias>
<alias>
<family>monospace</family>
<prefer>
<family>Miriam Mono</family> <!-- hebrew -->
<family>VL Gothic</family>
<family>IPAMonaGothic</family>
<family>IPAGothic</family>
<family>Sazanami Gothic</family>
<family>Kochi Gothic</family>
<family>AR PL KaitiM GB</family>
<family>MS Gothic</family> <!-- han (ja) -->
<family>UmePlus Gothic</family> <!-- han (ja) -->
<family>NSimSun</family> <!-- han (zh-cn,zh-tw) -->
<family>MingLiu</family> <!-- han (zh-tw) -->
<family>AR PL ShanHeiSun Uni</family> <!-- han (ja,zh-cn,zh-tw) -->
<family>AR PL New Sung Mono</family> <!-- han (zh-cn,zh-tw) -->
<family>HanyiSong</family> <!-- han (zh-cn) -->
<family>AR PL SungtiL GB</family>
<family>AR PL Mingti2L Big5</family>
<family>ZYSong18030</family> <!-- han (zh-cn,zh-tw) -->
<family>NanumGothicCoding</family> <!-- hangul (ko) -->
<family>NanumGothic</family> <!-- hangul (ko) -->
<family>UnDotum</family> <!-- hangul (ko) -->
<family>Baekmuk Dotum</family> <!-- hangul (ko) -->
<family>Baekmuk Gulim</family> <!-- hangul (ko) -->
<family>TlwgTypo</family> <!-- thai -->
<family>TlwgTypist</family> <!-- thai -->
<family>TlwgTypewriter</family> <!-- thai -->
<family>TlwgMono</family> <!-- thai -->
<family>Hasida</family> <!-- hebrew -->
<family>Mitra Mono</family> <!-- bengali -->
<family>GF Zemen Unicode</family> <!-- ethiopic -->
<family>Hapax Berbère</family> <!-- tifinagh -->
<family>Lohit Bengali</family>
<family>Lohit Gujarati</family>
<family>Lohit Hindi</family>
<family>Lohit Marathi</family>
<family>Lohit Maithili</family>
<family>Lohit Kashmiri</family>
<family>Lohit Konkani</family>
<family>Lohit Nepali</family>
<family>Lohit Sindhi</family>
<family>Lohit Punjabi</family>
<family>Lohit Tamil</family>
<family>Meera</family>
<family>Lohit Malayalam</family>
<family>Lohit Kannada</family>
<family>Lohit Telugu</family>
<family>Lohit Oriya</family>
<family>LKLUG</family>
</prefer>
</alias>
</fontconfig>

View File

@ -0,0 +1,28 @@
<?xml version="1.0"?>
<!DOCTYPE fontconfig SYSTEM "fonts.dtd">
<fontconfig>
<alias>
<family>serif</family>
<prefer>
<family>FreeSerif</family>
<family>Code2000</family>
<family>Code2001</family> <!-- plane1 and beyond -->
</prefer>
</alias>
<alias>
<family>sans-serif</family>
<prefer>
<family>FreeSans</family>
<family>Arial Unicode MS</family>
<family>Arial Unicode</family>
<family>Code2000</family> <!-- almost everything; serif actually -->
<family>Code2001</family> <!-- plane1 and beyond -->
</prefer>
</alias>
<alias>
<family>monospace</family>
<prefer>
<family>FreeMono</family>
</prefer>
</alias>
</fontconfig>

View File

@ -0,0 +1,19 @@
<?xml version="1.0"?>
<!DOCTYPE fontconfig SYSTEM "fonts.dtd">
<fontconfig>
<!-- Fix-ups for Delicious family -->
<!-- Delicious 'heavy' variant says its Medium weight -->
<match target="scan">
<test name="family" compare="eq" ignore-blanks="true">
<string>Delicious</string>
</test>
<test name="style">
<string>Heavy</string>
</test>
<edit name="weight">
<const>heavy</const>
</edit>
</match>
</fontconfig>

View File

@ -0,0 +1,64 @@
<?xml version="1.0"?>
<!DOCTYPE fontconfig SYSTEM "fonts.dtd">
<fontconfig>
<!--
Artificial oblique for fonts without an italic or oblique version
-->
<match target="font">
<!-- check to see if the font is roman -->
<test name="slant">
<const>roman</const>
</test>
<!-- check to see if the pattern requested non-roman -->
<test target="pattern" name="slant" compare="not_eq">
<const>roman</const>
</test>
<!-- multiply the matrix to slant the font -->
<edit name="matrix" mode="assign">
<times>
<name>matrix</name>
<matrix><double>1</double><double>0.2</double>
<double>0</double><double>1</double>
</matrix>
</times>
</edit>
<!-- pretend the font is oblique now -->
<edit name="slant" mode="assign">
<const>oblique</const>
</edit>
<!-- and disable embedded bitmaps for artificial oblique -->
<edit name="embeddedbitmap" mode="assign">
<bool>false</bool>
</edit>
</match>
<!--
Synthetic emboldening for fonts that do not have bold face available
-->
<match target="font">
<!-- check to see if the font is just regular -->
<test name="weight" compare="less_eq">
<const>medium</const>
</test>
<!-- check to see if the pattern requests bold -->
<test target="pattern" name="weight" compare="more">
<const>medium</const>
</test>
<!--
set the embolden flag
needed for applications using cairo, e.g. gucharmap, gedit, ...
-->
<edit name="embolden" mode="assign">
<bool>true</bool>
</edit>
<!--
set weight to bold
needed for applications using Xft directly, e.g. Firefox, ...
-->
<edit name="weight" mode="assign">
<const>bold</const>
</edit>
</match>
</fontconfig>

23
fonts-osx/conf.d/README Normal file
View File

@ -0,0 +1,23 @@
conf.d/README
Each file in this directory is a fontconfig configuration file. Fontconfig
scans this directory, loading all files of the form [0-9][0-9]*.conf.
These files are normally installed in /usr/share/fontconfig/conf.avail
and then symlinked here, allowing them to be easily installed and then
enabled/disabled by adjusting the symlinks.
The files are loaded in numeric order, the structure of the configuration
has led to the following conventions in usage:
Files begining with: Contain:
00 through 09 Font directories
10 through 19 system rendering defaults (AA, etc)
20 through 29 font rendering options
30 through 39 family substitution
40 through 49 generic identification, map family->generic
50 through 59 alternate config file loading
60 through 69 generic aliases, map generic->family
70 through 79 select font (adjust which fonts are available)
80 through 89 match target="scan" (modify scanned patterns)
90 through 99 font synthesis

153
fonts-osx/fonts.conf Normal file
View File

@ -0,0 +1,153 @@
<?xml version="1.0"?>
<!DOCTYPE fontconfig SYSTEM "fonts.dtd">
<!-- /etc/fonts/fonts.conf file to configure system font access -->
<fontconfig>
<!--
DO NOT EDIT THIS FILE.
IT WILL BE REPLACED WHEN FONTCONFIG IS UPDATED.
LOCAL CHANGES BELONG IN 'local.conf'.
The intent of this standard configuration file is to be adequate for
most environments. If you have a reasonably normal environment and
have found problems with this configuration, they are probably
things that others will also want fixed. Please submit any
problems to the fontconfig bugzilla system located at fontconfig.org
Note that the normal 'make install' procedure for fontconfig is to
replace any existing fonts.conf file with the new version. Place
any local customizations in local.conf which this file references.
Keith Packard
-->
<!-- Font directory list -->
<dir>/usr/share/fonts</dir>
<dir prefix="xdg">fonts</dir>
<!-- the following element will be removed in the future -->
<dir>~/.fonts</dir>
<!--
Accept deprecated 'mono' alias, replacing it with 'monospace'
-->
<match target="pattern">
<test qual="any" name="family">
<string>mono</string>
</test>
<edit name="family" mode="assign" binding="same">
<string>monospace</string>
</edit>
</match>
<!--
Accept alternate 'sans serif' spelling, replacing it with 'sans-serif'
-->
<match target="pattern">
<test qual="any" name="family">
<string>sans serif</string>
</test>
<edit name="family" mode="assign" binding="same">
<string>sans-serif</string>
</edit>
</match>
<!--
Accept deprecated 'sans' alias, replacing it with 'sans-serif'
-->
<match target="pattern">
<test qual="any" name="family">
<string>sans</string>
</test>
<edit name="family" mode="assign" binding="same">
<string>sans-serif</string>
</edit>
</match>
<!--
Load local system customization file
-->
<include ignore_missing="yes">conf.d</include>
<!-- Font cache directory list -->
<cachedir prefix="xdg">fontconfig</cachedir>
<!-- the following element will be removed in the future -->
<cachedir>~/.fontconfig</cachedir>
<config>
<!--
These are the default Unicode chars that are expected to be blank
in fonts. All other blank chars are assumed to be broken and
won't appear in the resulting charsets
-->
<blank>
<int>0x0020</int> <!-- SPACE -->
<int>0x00A0</int> <!-- NO-BREAK SPACE -->
<int>0x00AD</int> <!-- SOFT HYPHEN -->
<int>0x034F</int> <!-- COMBINING GRAPHEME JOINER -->
<int>0x0600</int> <!-- ARABIC NUMBER SIGN -->
<int>0x0601</int> <!-- ARABIC SIGN SANAH -->
<int>0x0602</int> <!-- ARABIC FOOTNOTE MARKER -->
<int>0x0603</int> <!-- ARABIC SIGN SAFHA -->
<int>0x06DD</int> <!-- ARABIC END OF AYAH -->
<int>0x070F</int> <!-- SYRIAC ABBREVIATION MARK -->
<int>0x115F</int> <!-- HANGUL CHOSEONG FILLER -->
<int>0x1160</int> <!-- HANGUL JUNGSEONG FILLER -->
<int>0x1680</int> <!-- OGHAM SPACE MARK -->
<int>0x17B4</int> <!-- KHMER VOWEL INHERENT AQ -->
<int>0x17B5</int> <!-- KHMER VOWEL INHERENT AA -->
<int>0x180E</int> <!-- MONGOLIAN VOWEL SEPARATOR -->
<int>0x2000</int> <!-- EN QUAD -->
<int>0x2001</int> <!-- EM QUAD -->
<int>0x2002</int> <!-- EN SPACE -->
<int>0x2003</int> <!-- EM SPACE -->
<int>0x2004</int> <!-- THREE-PER-EM SPACE -->
<int>0x2005</int> <!-- FOUR-PER-EM SPACE -->
<int>0x2006</int> <!-- SIX-PER-EM SPACE -->
<int>0x2007</int> <!-- FIGURE SPACE -->
<int>0x2008</int> <!-- PUNCTUATION SPACE -->
<int>0x2009</int> <!-- THIN SPACE -->
<int>0x200A</int> <!-- HAIR SPACE -->
<int>0x200B</int> <!-- ZERO WIDTH SPACE -->
<int>0x200C</int> <!-- ZERO WIDTH NON-JOINER -->
<int>0x200D</int> <!-- ZERO WIDTH JOINER -->
<int>0x200E</int> <!-- LEFT-TO-RIGHT MARK -->
<int>0x200F</int> <!-- RIGHT-TO-LEFT MARK -->
<int>0x2028</int> <!-- LINE SEPARATOR -->
<int>0x2029</int> <!-- PARAGRAPH SEPARATOR -->
<int>0x202A</int> <!-- LEFT-TO-RIGHT EMBEDDING -->
<int>0x202B</int> <!-- RIGHT-TO-LEFT EMBEDDING -->
<int>0x202C</int> <!-- POP DIRECTIONAL FORMATTING -->
<int>0x202D</int> <!-- LEFT-TO-RIGHT OVERRIDE -->
<int>0x202E</int> <!-- RIGHT-TO-LEFT OVERRIDE -->
<int>0x202F</int> <!-- NARROW NO-BREAK SPACE -->
<int>0x205F</int> <!-- MEDIUM MATHEMATICAL SPACE -->
<int>0x2060</int> <!-- WORD JOINER -->
<int>0x2061</int> <!-- FUNCTION APPLICATION -->
<int>0x2062</int> <!-- INVISIBLE TIMES -->
<int>0x2063</int> <!-- INVISIBLE SEPARATOR -->
<int>0x206A</int> <!-- INHIBIT SYMMETRIC SWAPPING -->
<int>0x206B</int> <!-- ACTIVATE SYMMETRIC SWAPPING -->
<int>0x206C</int> <!-- INHIBIT ARABIC FORM SHAPING -->
<int>0x206D</int> <!-- ACTIVATE ARABIC FORM SHAPING -->
<int>0x206E</int> <!-- NATIONAL DIGIT SHAPES -->
<int>0x206F</int> <!-- NOMINAL DIGIT SHAPES -->
<int>0x2800</int> <!-- BRAILLE PATTERN BLANK -->
<int>0x3000</int> <!-- IDEOGRAPHIC SPACE -->
<int>0x3164</int> <!-- HANGUL FILLER -->
<int>0xFEFF</int> <!-- ZERO WIDTH NO-BREAK SPACE -->
<int>0xFFA0</int> <!-- HALFWIDTH HANGUL FILLER -->
<int>0xFFF9</int> <!-- INTERLINEAR ANNOTATION ANCHOR -->
<int>0xFFFA</int> <!-- INTERLINEAR ANNOTATION SEPARATOR -->
<int>0xFFFB</int> <!-- INTERLINEAR ANNOTATION TERMINATOR -->
</blank>
<!--
Rescan configuration every 30 seconds when FcFontSetList is called
-->
<rescan>
<int>30</int>
</rescan>
</config>
</fontconfig>

11
fonts/05-osx-fonts.conf Normal file
View File

@ -0,0 +1,11 @@
<?xml version="1.0"?>
<!DOCTYPE fontconfig SYSTEM "fonts.dtd">
<fontconfig>
<dir>/usr/X11/lib/X11/fonts</dir>
<dir>/System/Library/Fonts</dir>
<dir>/Library/Fonts</dir>
<dir>~/Library/Fonts</dir>
<cachedir>/usr/local/var/cache/fontconfig</cachedir>
<cachedir>/opt/local/var/cache/fontconfig</cachedir>
<cachedir>/usr/X11/var/cache/fontconfig</cachedir>
</fontconfig>

View File

@ -1,19 +1,19 @@
<?xml version="1.0"?>
<!DOCTYPE fontconfig SYSTEM "fonts.dtd">
<fontconfig>
<alias>
<alias binding="strong">
<family>sans-serif</family>
<prefer>
<family>Liberation Sans</family>
</prefer>
</alias>
<alias>
<alias binding="strong">
<family>serif</family>
<prefer>
<family>Liberation Serif</family>
</prefer>
</alias>
<alias>
<alias binding="strong">
<family>monospace</family>
<prefer>
<family>Liberation Mono</family>

View File

@ -14,8 +14,10 @@ FREETYPE_DIR = $$(FREETYPEDIR)
!isEmpty(OPENSCAD_LIBRARIES_DIR) {
isEmpty(FREETYPE_INCLUDEPATH) {
FREETYPE_INCLUDEPATH = $$OPENSCAD_LIBRARIES_DIR/include/freetype2
FREETYPE_LIBPATH = $$OPENSCAD_LIBRARIES_DIR/lib
exists($$OPENSCAD_LIBRARIES_DIR/include/freetype2) {
FREETYPE_INCLUDEPATH = $$OPENSCAD_LIBRARIES_DIR/include/freetype2
FREETYPE_LIBPATH = $$OPENSCAD_LIBRARIES_DIR/lib
}
}
}

View File

@ -14,8 +14,10 @@ HARFBUZZ_DIR = $$(HARFBUZZDIR)
!isEmpty(OPENSCAD_LIBRARIES_DIR) {
isEmpty(HARFBUZZ_INCLUDEPATH) {
HARFBUZZ_INCLUDEPATH = $$OPENSCAD_LIBRARIES_DIR/include/harfbuzz
HARFBUZZ_LIBPATH = $$OPENSCAD_LIBRARIES_DIR/lib
exists($$OPENSCAD_LIBRARIES_DIR/include/harfbuzz) {
HARFBUZZ_INCLUDEPATH = $$OPENSCAD_LIBRARIES_DIR/include/harfbuzz
HARFBUZZ_LIBPATH = $$OPENSCAD_LIBRARIES_DIR/lib
}
}
}

View File

@ -1,14 +1,14 @@
# Environment variables which can be set to specify library locations:
# MPIRDIR
# MPFRDIR
# BOOSTDIR
# CGALDIR
# EIGENDIR
# GLEWDIR
# OPENCSGDIR
# OPENSCAD_LIBRARIES
# MPIRDIR
# MPFRDIR
# BOOSTDIR
# CGALDIR
# EIGENDIR
# GLEWDIR
# OPENCSGDIR
# OPENSCAD_LIBRARIES
#
# Please see the 'Building' sections of the OpenSCAD user manual
# Please see the 'Building' sections of the OpenSCAD user manual
# for updated tips & workarounds.
#
# http://en.wikibooks.org/wiki/OpenSCAD_User_Manual
@ -135,13 +135,13 @@ netbsd* {
}
# Prevent LD_LIBRARY_PATH problems when running the openscad binary
# on systems where uni-build-dependencies.sh was used.
# on systems where uni-build-dependencies.sh was used.
# Will not affect 'normal' builds.
!isEmpty(OPENSCAD_LIBDIR) {
unix:!macx {
QMAKE_LFLAGS = -Wl,-R$$OPENSCAD_LIBDIR/lib $$QMAKE_LFLAGS
# need /lib64 beause GLEW installs itself there on 64 bit machines
QMAKE_LFLAGS = -Wl,-R$$OPENSCAD_LIBDIR/lib64 $$QMAKE_LFLAGS
QMAKE_LFLAGS = -Wl,-R$$OPENSCAD_LIBDIR/lib64 $$QMAKE_LFLAGS
}
}
@ -179,8 +179,8 @@ CONFIG += harfbuzz
CONFIG += freetype
CONFIG += fontconfig
#Uncomment the following line to enable QCodeEdit
#CONFIG += qcodeedit
#Uncomment the following line to enable the QScintilla editor
CONFIG += scintilla
# Make experimental features available
experimental {
@ -208,7 +208,7 @@ win* {
RESOURCES = openscad.qrc
FORMS += src/MainWindow.ui \
FORMS += src/MainWindow.ui \
src/Preferences.ui \
src/OpenCSGWarningDialog.ui \
src/AboutDialog.ui \
@ -222,8 +222,9 @@ HEADERS += src/typedefs.h \
src/parsersettings.h \
src/renderer.h \
src/rendersettings.h \
src/colormap.h \
src/ThrownTogetherRenderer.h \
src/CGAL_renderer.h \
src/CGAL_OGL_Polyhedron.h \
src/OGL_helper.h \
src/QGLView.h \
src/GLView.h \
@ -283,9 +284,9 @@ HEADERS += src/typedefs.h \
src/GeometryEvaluator.h \
src/CSGTermEvaluator.h \
src/Tree.h \
src/DrawingCallback.h \
src/FreetypeRenderer.h \
src/FontCache.h \
src/DrawingCallback.h \
src/FreetypeRenderer.h \
src/FontCache.h \
src/mathc99.h \
src/memory.h \
src/linalg.h \
@ -306,7 +307,8 @@ HEADERS += src/typedefs.h \
src/CsgInfo.h \
\
src/AutoUpdater.h \
src/launchingscreen.h
src/launchingscreen.h \
src/legacyeditor.h
SOURCES += src/version_check.cc \
src/ProgressWidget.cc \
@ -361,9 +363,9 @@ SOURCES += src/version_check.cc \
src/ModuleCache.cc \
src/GeometryCache.cc \
src/Tree.cc \
src/DrawingCallback.cc \
src/FreetypeRenderer.cc \
src/FontCache.cc \
src/DrawingCallback.cc \
src/FreetypeRenderer.cc \
src/FontCache.cc \
\
src/rendersettings.cc \
src/highlighter.cc \
@ -380,6 +382,7 @@ SOURCES += src/version_check.cc \
src/export_png.cc \
src/import.cc \
src/renderer.cc \
src/colormap.cc \
src/ThrownTogetherRenderer.cc \
src/CSGTermEvaluator.cc \
src/svg.cc \
@ -392,7 +395,8 @@ SOURCES += src/version_check.cc \
src/openscad.cc \
src/mainwin.cc \
src/FontListDialog.cc \
src/launchingscreen.cpp
src/launchingscreen.cpp \
src/legacyeditor.cc
# ClipperLib
SOURCES += src/polyclipping/clipper.cpp
@ -429,6 +433,7 @@ HEADERS += src/cgal.h \
src/Polygon2d-CGAL.h
SOURCES += src/cgalutils.cc \
src/cgalutils-tess.cc \
src/CGALCache.cc \
src/CGALRenderer.cc \
src/CGAL_Nef_polyhedron.cc \
@ -488,4 +493,3 @@ INSTALLS += man
CONFIG(winconsole) {
include(winconsole.pri)
}

View File

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE QtCreatorProject>
<!-- Written by QtCreator 3.0.1, 2014-08-05T22:42:15. -->
<!-- Written by QtCreator 3.0.1, 2014-08-11T22:59:13. -->
<qtcreator>
<data>
<variable>ProjectExplorer.Project.ActiveTarget</variable>
@ -170,7 +170,7 @@
<valuelist type="QVariantList" key="PE.EnvironmentAspect.Changes"/>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">openscad</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.Qt4RunConfiguration:/home/shaina/openscad/openscad.pro</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.Qt4RunConfiguration:/home/shaina/letsbegin/openscad/openscad.pro</value>
<value type="QString" key="Qt4ProjectManager.Qt4RunConfiguration.CommandLineArguments"></value>
<value type="QString" key="Qt4ProjectManager.Qt4RunConfiguration.ProFile">openscad.pro</value>
<value type="bool" key="Qt4ProjectManager.Qt4RunConfiguration.UseDyldImageSuffix">false</value>

12
qscintilla2.prf Normal file
View File

@ -0,0 +1,12 @@
greaterThan(QT_MAJOR_VERSION, 4) {
QT += widgets printsupport
greaterThan(QT_MINOR_VERSION, 1) {
macx:QT += macextras
}
}
INCLUDEPATH += $$[QT_INSTALL_HEADERS]
LIBS += -L$$[QT_INSTALL_LIBS]
LIBS += -lqscintilla2

18
scintilla.pri Normal file
View File

@ -0,0 +1,18 @@
scintilla {
HEADERS += src/scintillaeditor.h src/scadlexer.h
SOURCES += src/scintillaeditor.cpp src/scadlexer.cpp
DEFINES += USE_SCINTILLA_EDITOR
# The qscintilla2.prf which ships with QScintilla is broken for Mac/Windows
# debug builds, so we supply our own
win32|macx: include(qscintilla2.prf)
else: CONFIG += qscintilla2
# Older scintilla libs (e.g. 2.7.2 on fedora20) do not provide the
# prf file, so if no lib added at this point, we still fall back to
# the included qscintilla2.prf
!contains(LIBS, ".*scintilla.*") {
include(qscintilla2.prf)
}
}

View File

@ -83,6 +83,9 @@ glib2_sysver()
if [ ! -e $glib2path ]; then
glib2path=$1/lib/glib-2.0/include/glibconfig.h
fi
if [ ! -e $glib2path ]; then
glib2path=$1/lib64/glib-2.0/include/glibconfig.h
fi
if [ ! -e $glib2path ]; then
return
fi
@ -96,10 +99,10 @@ fontconfig_sysver()
{
fcpath=$1/include/fontconfig/fontconfig.h
if [ ! -e $fcpath ]; then return; fi
fcmajor=`grep "define *FC_MAJOR *[0-9.]*" $fcpath | awk '{print $3}'`
fcminor=`grep "define *FC_MINOR *[0-9.]*" $fcpath | awk '{print $3}'`
fcrevison=`grep "define *FC_REVISION *[0-9.]*" $fcpath | awk '{print $3}'`
fontconfig_sysver="${fcmajor}.${fcminor}.${fcrevision}"
fcmajor=`grep "define *FC_MAJOR.*[0-9.]*" $fcpath | awk '{print $3}'`
fcminor=`grep "define *FC_MINOR.*[0-9.]*" $fcpath | awk '{print $3}'`
fcrevison=`grep "define *FC_REVISION.*[0-9.]*" $fcpath | awk '{print $3}'`
fontconfig_sysver_result="${fcmajor}.${fcminor}.${fcrevision}"
}
freetype2_sysver()
@ -142,7 +145,7 @@ mpfr_sysver()
gmp_sysver()
{
gmppaths="`find $1 -name 'gmp.h' -o -name 'gmp-*.h'`"
gmppaths="`find $1 -name 'gmp.h' -o -name 'gmp-*.h' 2>/dev/null`"
if [ ! "$gmppaths" ]; then
debug "gmp_sysver no gmp.h beneath $1"
return
@ -173,6 +176,24 @@ qt4_sysver()
qt4_sysver_result=$qt4ver
}
qscintilla2_sysver()
{
QMAKE=qmake
if [ "`command -v qmake-qt4`" ]; then
QMAKE=qmake-qt4
fi
qt4incdir="`$QMAKE -query QT_INSTALL_HEADERS`"
qscipath="$qt4incdir/Qsci/qsciglobal.h"
if [ ! -e $qscipath ]; then
return
fi
qsciver=`grep define.*QSCINTILLA_VERSION_STR "$qscipath" | awk '{print $3}'`
qsciver=`echo $qsciver | sed s/'"'//g`
qscintilla2_sysver_result="$qsciver"
}
glew_sysver()
{
glewh=$1/include/GL/glew.h
@ -586,7 +607,7 @@ checkargs()
main()
{
deps="qt4 cgal gmp mpfr boost opencsg glew eigen glib2 fontconfig freetype2 harfbuzz gcc bison flex make"
deps="qt4 qscintilla2 cgal gmp mpfr boost opencsg glew eigen glib2 fontconfig freetype2 harfbuzz gcc bison flex make"
#deps="$deps curl git" # not technically necessary for build
#deps="$deps python cmake imagemagick" # only needed for tests
#deps="cgal"

View File

@ -55,6 +55,7 @@ build_libxml2()
build_fontconfig()
{
version=$1
extra_config_flags="$2"
if [ -e $DEPLOYDIR/include/fontconfig ]; then
echo "fontconfig already installed. not building"
@ -70,10 +71,10 @@ build_fontconfig()
tar xzf "fontconfig-$version.tar.gz"
cd "fontconfig-$version"
export PKG_CONFIG_PATH="$DEPLOYDIR/lib/pkgconfig"
./configure --prefix="$DEPLOYDIR" --enable-libxml2 --disable-docs
./configure --prefix=/ --enable-libxml2 --disable-docs $extra_config_flags
unset PKG_CONFIG_PATH
make -j$NUMCPU
make install
DESTDIR="$DEPLOYDIR" make -j$NUMCPU
DESTDIR="$DEPLOYDIR" make install
}
build_libffi()

View File

@ -133,6 +133,22 @@ build_qt5()
make -j"$NUMCPU" install
}
build_qscintilla()
{
version=$1
echo "Building QScintilla" $version "..."
cd $BASEDIR/src
rm -rf QScintilla-gpl-$version
if [ ! -f QScintilla-gpl-$version.tar.gz ]; then
curl -LO http://downloads.sourceforge.net/project/pyqt/QScintilla2/QScintilla-$version/QScintilla-gpl-$version.tar.gz
fi
tar xzf QScintilla-gpl-$version.tar.gz
cd QScintilla-gpl-$version/Qt4Qt5
qmake qscintilla.pro
make -j6 install
install_name_tool -id $DEPLOYDIR/lib/libqscintilla2.dylib $DEPLOYDIR/lib/libqscintilla2.dylib
}
# Hack warning: gmplib is built separately in 32-bit and 64-bit mode
# and then merged afterwards. gmplib's header files are dependent on
# the CPU architecture on which configure was run and will be patched accordingly.
@ -754,6 +770,7 @@ fi
echo "Using basedir:" $BASEDIR
mkdir -p $SRCDIR $DEPLOYDIR
build_qt5 5.3.1
build_qscintilla 2.8.3
# NB! For eigen, also update the path in the function
build_eigen 3.2.1
build_gmp 5.1.3

View File

@ -32,18 +32,18 @@ def lookup_library(file):
if re.search("@executable_path", file):
abs = re.sub("^@executable_path", executable_path, file)
if os.path.exists(abs): found = abs
if DEBUG: print "Lib in @executable_path found: " + found
if DEBUG: print "Lib in @executable_path found: " + str(found)
elif re.search("\.app/", file):
found = file
if DEBUG: print "App found: " + found
if DEBUG: print "App found: " + str(found)
elif re.search("\.framework/", file):
found = os.path.join("/Library/Frameworks", file)
if DEBUG: print "Framework found: " + found
if DEBUG: print "Framework found: " + str(found)
else:
for path in os.getenv("DYLD_LIBRARY_PATH").split(':'):
abs = os.path.join(path, file)
if os.path.exists(abs): found = abs
if DEBUG: print "Library found: " + found
if DEBUG: print "Library found: " + str(found)
else:
found = file
return found

View File

@ -58,21 +58,21 @@ fi
echo "entering" $MXEDIR
cd $MXEDIR
echo 'checkout stable branch'
git checkout stable
echo 'checkout master branch'
git checkout master
if [ "`echo $* | grep 64`" ]; then
MXE_TARGETS='x86_64-w64-mingw32'
MXE_TARGETS='x86_64-w64-mingw32.static'
if [ "`echo $* | grep download`" ]; then
PACKAGES='download-mpfr download-eigen download-opencsg download-cgal download-qt download-qt5 download-glib download-freetype download-fontconfig download-harfbuzz'
PACKAGES='download-mpfr download-eigen download-opencsg download-cgal download-qtbase download-glib download-freetype download-fontconfig download-harfbuzz'
else
PACKAGES='qt qt5 mpfr eigen opencsg cgal glib freetype fontconfig harfbuzz'
PACKAGES='qtbase qscintilla2 mpfr eigen opencsg cgal glib freetype fontconfig harfbuzz'
fi
else
MXE_TARGETS='i686-pc-mingw32'
MXE_TARGETS='i686-w64-mingw32.static'
if [ "`echo $* | grep download`" ]; then
PACKAGES='download-mpfr download-eigen download-opencsg download-cgal download-qt download-qt5 download-nsis download-glib download-freetype download-fontconfig download-harfbuzz'
PACKAGES='download-mpfr download-eigen download-opencsg download-cgal download-qtbase download-nsis download-glib download-freetype download-fontconfig download-harfbuzz'
else
PACKAGES='qt qt5 mpfr eigen opencsg cgal nsis glib freetype fontconfig harfbuzz'
PACKAGES='qtbase qscintilla2 mpfr eigen opencsg cgal nsis glib freetype fontconfig harfbuzz'
fi
fi
echo make $PACKAGES MXE_TARGETS=$MXE_TARGETS -j $NUMCPU JOBS=$NUMJOBS

View File

@ -4,5 +4,6 @@ cd "$( dirname "$( type -p $0 )" )"
libdir=$PWD/../lib/openscad/
cd "$OLDPWD"
export LIBGL_DRIVERS_PATH="$libdir"/dri
export LD_LIBRARY_PATH="$libdir${LD_LIBRARY_PATH:+:}$LD_LIBRARY_PATH"
exec $libdir/openscad "$@"

View File

@ -202,7 +202,12 @@ case $OS in
cd $OPENSCADDIR
;;
*)
qmake VERSION=$VERSION OPENSCAD_COMMIT=$OPENSCAD_COMMIT CONFIG+="$CONFIG" CONFIG-=debug openscad.pro
QMAKE="`command -v qmake-qt5`"
if [ ! -x "$QMAKE" ]
then
QMAKE=qmake
fi
"$QMAKE" VERSION=$VERSION OPENSCAD_COMMIT=$OPENSCAD_COMMIT CONFIG+="$CONFIG" CONFIG-=debug openscad.pro
;;
esac
@ -352,6 +357,14 @@ if [ -n $FONTDIR ]; then
echo $FONTDIR
mkdir -p $FONTDIR
cp -a fonts/* $FONTDIR
case $OS in
MACOSX)
cp -a fonts-osx/* $FONTDIR
;;
UNIX_CROSS_WIN)
cp -a "$DEPLOYDIR"/mingw-cross-env/etc/fonts/. "$FONTDIR"
;;
esac
fi
if [ -n $LIBRARYDIR ]; then
echo $LIBRARYDIR
@ -442,12 +455,26 @@ case $OS in
gcc -o chrpath_linux -DSIZEOF_VOID_P=4 scripts/chrpath_linux.c
fi
./chrpath_linux -d openscad-$VERSION/lib/openscad/openscad
ldd openscad | sed -re 's,.* => ,,; s,[\t ].*,,;' -e '/Qt|boost/ { p; d; };' \
-e '/lib(icu.*|stdc.*|audio|CGAL|GLEW|opencsg|png|gmp|gmpxx|mpfr)\.so/ { p; d; };' \
-e 'd;' | xargs cp -vt openscad-$VERSION/lib/openscad/
QTLIBDIR=$(dirname $(ldd openscad | grep Qt5Gui | head -n 1 | awk '{print $3;}'))
( ldd openscad ; ldd "$QTLIBDIR"/qt5/plugins/platforms/libqxcb.so ) \
| sed -re 's,.* => ,,; s,[\t ].*,,;' -e '/^$/d' -e '/libc\.so|libm\.so|libdl\.so|libgcc_|libpthread\.so/d' \
| sort -u \
| xargs cp -vt "openscad-$VERSION/lib/openscad/"
PLATFORMDIR="openscad-$VERSION/lib/openscad/platforms/"
mkdir -p "$PLATFORMDIR"
cp -av "$QTLIBDIR"/qt5/plugins/platforms/libqxcb.so "$PLATFORMDIR"
DRIDRIVERDIR=$(find /usr/lib -xdev -type d -name dri)
if [ -d "$DRIDRIVERDIR" ]
then
DRILIB="openscad-$VERSION/lib/openscad/dri/"
mkdir -p "$DRILIB"
cp -av "$DRIDRIVERDIR"/swrast_dri.so "$DRILIB"
fi
strip openscad-$VERSION/lib/openscad/*
mkdir -p openscad-$VERSION/share/appdata
cp openscad.appdata.xml openscad-$VERSION/share/appdata
cp icons/openscad.{desktop,png,xml} openscad-$VERSION/share/appdata
cp scripts/installer-linux.sh openscad-$VERSION/install.sh
chmod 755 -R openscad-$VERSION/
PACKAGEFILE=openscad-$VERSION.x86-$ARCH.tar.gz

View File

@ -56,9 +56,9 @@ if [ ! -e $DEPLOYDIR ]; then
fi
if [ "`echo $* | grep 64 `" ]; then
MXETARGETDIR=$MXEDIR/usr/x86_64-w64-mingw32
MXETARGETDIR=$MXEDIR/usr/x86_64-w64-mingw32.static
else
MXETARGETDIR=$MXEDIR/usr/i686-pc-mingw32
MXETARGETDIR=$MXEDIR/usr/i686-w64-mingw32.static
fi
if [ ! $MINGWX_SAVED_ORIGINAL_PATH ]; then

View File

@ -13,7 +13,7 @@ if [[ $? != 0 ]]; then
fi
# Exclude tests known the cause issues on Travis
# opencsgtest_rotate_extrude-tests - Fails on Ubuntu 12.04 using Gallium 0.4 drivers
ctest -j8 -E "opencsgtest_rotate_extrude-tests|opencsgtest_render-tests"
ctest -j8 -E "opencsgtest_rotate_extrude-tests|opencsgtest_render-tests|opencsgtest_rotate_extrude-hole|opencsgtest_internal-cavity|opencsgtest_internal-cavity-polyhedron|opencsgtest_minkowski3-erosion"
if [[ $? != 0 ]]; then
echo "Test failure"
exit 1

View File

@ -131,6 +131,56 @@ build_qt4()
echo "----------"
}
build_qt5()
{
version=$1
if [ -f $DEPLOYDIR/lib/libQt5Core.a ]; then
echo "Qt5 already installed. not building"
return
fi
echo "Building Qt" $version "..."
cd $BASEDIR/src
rm -rf qt-everywhere-opensource-src-$version
v=`echo "$version" | sed -e 's/\.[0-9]$//'`
if [ ! -f qt-everywhere-opensource-src-$version.tar.gz ]; then
curl -O -L http://download.qt-project.org/official_releases/qt/$v/$version/single/qt-everywhere-opensource-src-$version.tar.gz
fi
tar xzf qt-everywhere-opensource-src-$version.tar.gz
cd qt-everywhere-opensource-src-$version
./configure -prefix $DEPLOYDIR -release -static -opensource -confirm-license \
-nomake examples -nomake tests \
-qt-xcb -no-c++11 -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 \
-skip activeqt -skip connectivity -skip declarative -skip doc \
-skip enginio -skip graphicaleffects -skip location -skip multimedia \
-skip quick1 -skip quickcontrols -skip script -skip sensors -skip serialport \
-skip svg -skip webkit -skip webkit-examples -skip websockets -skip xmlpatterns
make -j"$NUMCPU" install
}
build_qt5scintilla2()
{
version=$1
if [ -d $DEPLOYDIR/lib/libqt5scintilla2.a ]; then
echo "Qt5Scintilla2 already installed. not building"
return
fi
echo "Building Qt5Scintilla2" $version "..."
cd $BASEDIR/src
#rm -rf QScintilla-gpl-$version.tar.gz
if [ ! -f QScintilla-gpl-$version.tar.gz ]; then
curl -L -o "QScintilla-gpl-$version.tar.gz" "http://downloads.sourceforge.net/project/pyqt/QScintilla2/QScintilla-$version/QScintilla-gpl-$version.tar.gz?use_mirror=switch"
fi
tar xzf QScintilla-gpl-$version.tar.gz
cd QScintilla-gpl-$version/Qt4Qt5/
qmake CONFIG+=staticlib
make -j"$NUMCPU" install
}
build_bison()
{
version=$1
@ -210,7 +260,7 @@ build_gmp()
cd $BASEDIR/src
rm -rf gmp-$version
if [ ! -f gmp-$version.tar.bz2 ]; then
curl --insecure -O ftp://ftp.gmplib.org/pub/gmp-$version/gmp-$version.tar.bz2
curl --insecure -O https://gmplib.org/download/gmp/gmp-$version.tar.bz2
fi
tar xjf gmp-$version.tar.bz2
cd gmp-$version
@ -315,6 +365,7 @@ build_cgal()
echo "Building CGAL" $version "..."
cd $BASEDIR/src
rm -rf CGAL-$version
ver4_4="curl --insecure -O https://gforge.inria.fr/frs/download.php/file/33524/CGAL-4.4.tar.bz2"
ver4_2="curl --insecure -O https://gforge.inria.fr/frs/download.php/32360/CGAL-4.2.tar.bz2"
ver4_1="curl --insecure -O https://gforge.inria.fr/frs/download.php/31640/CGAL-4.1.tar.bz2"
ver4_0_2="curl --insecure -O https://gforge.inria.fr/frs/download.php/31174/CGAL-4.0.2.tar.bz2"
@ -509,6 +560,7 @@ build_eigen()
cd $BASEDIR/src
rm -rf eigen-$version
EIGENDIR="none"
if [ $version = "3.2.2" ]; then EIGENDIR=eigen-eigen-1306d75b4a21; fi
if [ $version = "3.1.1" ]; then EIGENDIR=eigen-eigen-43d9075b23ef; fi
if [ $EIGENDIR = "none" ]; then
echo Unknown eigen version. Please edit script.
@ -697,7 +749,7 @@ if [ $1 ]; then
exit $?
fi
if [ $1 = "cgal" ]; then
build_cgal 4.0.2 use-sys-libs
build_cgal 4.4 use-sys-libs
exit $?
fi
if [ $1 = "opencsg" ]; then
@ -709,6 +761,11 @@ if [ $1 ]; then
build_qt4 4.8.4
exit $?
fi
if [ $1 = "qt5" ]; then
build_qt5 5.3.1
build_qt5scintilla2 2.8.3
exit $?
fi
if [ $1 = "glu" ]; then
# Mesa and GLU split in late 2012, so it's not on some systems
build_glu 9.0.0
@ -741,21 +798,21 @@ fi
#
# Some of these are defined in scripts/common-build-dependencies.sh
build_eigen 3.1.1
build_eigen 3.2.2
build_gmp 5.0.5
build_mpfr 3.1.1
build_boost 1.53.0
build_boost 1.56.0
# NB! For CGAL, also update the actual download URL in the function
build_cgal 4.0.2
build_cgal 4.4
build_glew 1.9.0
build_opencsg 1.3.2
build_gettext 0.18.3.1
build_glib2 2.38.2
# the following are only needed for text()
build_freetype 2.5.0.1
build_freetype 2.5.0.1 --without-png
build_libxml2 2.9.1
build_fontconfig 2.11.0
build_fontconfig 2.11.0 --with-add-fonts=/usr/X11R6/lib/X11/fonts,/usr/local/share/fonts
build_ragel 6.8
build_harfbuzz 0.9.23 --with-glib=yes

View File

@ -6,7 +6,8 @@
get_fedora_deps()
{
yum install qt-devel bison flex eigen3-devel \
yum -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 ImageMagick glib2-devel make \
xorg-x11-server-Xvfb gettext
@ -56,7 +57,7 @@ get_mageia_deps()
get_debian_deps()
{
for pkg in build-essential libqt4-dev libqt4-opengl-dev \
for pkg in build-essential curl libffi-dev qtbase5-dev \
libxmu-dev cmake bison flex git-core libboost-all-dev \
libXi-dev libmpfr-dev libboost-dev libglew-dev \
libeigen3-dev libcgal-dev libopencsg-dev libgmp3-dev libgmp-dev \
@ -64,6 +65,15 @@ get_debian_deps()
libharfbuzz-dev gtk-doc-tools libglib2.0-dev gettext; do
sudo apt-get -y install $pkg;
done
# The following packages are only needed to build the static
# Qt5 version for release builds / older distributions.
for pkg in libdbus-1-dev \
libxcb1-dev libx11-xcb-dev libxcb-keysyms1-dev libxcb-image0-dev \
libxcb-shm0-dev libxcb-icccm4-dev libxcb-sync0-dev libxcb-xfixes0-dev \
libxrender-dev libxcb-shape0-dev libxcb-randr0-dev libxcb-glx0-dev; do
sudo apt-get -y install $pkg;
done
}
unknown()

View File

@ -1,4 +1,4 @@
export OPENSCAD_LIBRARIES=$PWD/../libraries/install
export OPENSCAD_LIBRARIES=$PWD/../libraries/install-qt4
export DYLD_LIBRARY_PATH=$OPENSCAD_LIBRARIES/lib
export DYLD_FRAMEWORK_PATH=$OPENSCAD_LIBRARIES/lib
export QMAKESPEC=unsupported/macx-clang

View File

@ -32,9 +32,10 @@
// dxfdata.h must come first for Eigen SIMD alignment issues
#include "dxfdata.h"
#include "polyset.h"
#include "printutils.h"
#include "CGALRenderer.h"
#include "CGAL_renderer.h"
#include "CGAL_OGL_Polyhedron.h"
#include "CGAL_Nef_polyhedron.h"
#include "cgal.h"
@ -51,19 +52,7 @@ CGALRenderer::CGALRenderer(shared_ptr<const class Geometry> geom)
else if (shared_ptr<const CGAL_Nef_polyhedron> new_N = dynamic_pointer_cast<const CGAL_Nef_polyhedron>(geom)) {
assert(new_N->getDimension() == 3);
if (!new_N->isEmpty()) {
this->polyhedron.reset(new Polyhedron());
// FIXME: Make independent of Preferences
// this->polyhedron->setColor(Polyhedron::CGAL_NEF3_MARKED_FACET_COLOR,
// Preferences::inst()->color(Preferences::CGAL_FACE_BACK_COLOR).red(),
// Preferences::inst()->color(Preferences::CGAL_FACE_BACK_COLOR).green(),
// Preferences::inst()->color(Preferences::CGAL_FACE_BACK_COLOR).blue());
// this->polyhedron->setColor(Polyhedron::CGAL_NEF3_UNMARKED_FACET_COLOR,
// Preferences::inst()->color(Preferences::CGAL_FACE_FRONT_COLOR).red(),
// Preferences::inst()->color(Preferences::CGAL_FACE_FRONT_COLOR).green(),
// Preferences::inst()->color(Preferences::CGAL_FACE_FRONT_COLOR).blue());
CGAL::OGL::Nef3_Converter<CGAL_Nef_polyhedron3>::convert_to_OGLPolyhedron(*new_N->p3, this->polyhedron.get());
this->polyhedron->init();
this->N = new_N;
}
}
}
@ -72,9 +61,37 @@ CGALRenderer::~CGALRenderer()
{
}
shared_ptr<class CGAL_OGL_Polyhedron> CGALRenderer::getPolyhedron() const
{
if (this->N && !this->polyhedron) buildPolyhedron();
return this->polyhedron;
}
void CGALRenderer::buildPolyhedron() const
{
PRINTD("buildPolyhedron");
this->polyhedron.reset(new CGAL_OGL_Polyhedron(*this->colorscheme));
CGAL::OGL::Nef3_Converter<CGAL_Nef_polyhedron3>::convert_to_OGLPolyhedron(*this->N->p3, this->polyhedron.get());
// CGAL_NEF3_MARKED_FACET_COLOR <- CGAL_FACE_BACK_COLOR
// CGAL_NEF3_UNMARKED_FACET_COLOR <- CGAL_FACE_FRONT_COLOR
this->polyhedron->init();
PRINTD("buildPolyhedron() end");
}
// Overridden from Renderer
void CGALRenderer::setColorScheme(const ColorScheme &cs)
{
PRINTD("setColorScheme");
Renderer::setColorScheme(cs);
this->polyhedron.reset(); // Mark as dirty
PRINTD("setColorScheme done");
}
void CGALRenderer::draw(bool showfaces, bool showedges) const
{
PRINTD("draw()");
if (this->polyset) {
PRINTD("draw() polyset");
if (this->polyset->getDimension() == 2) {
// Draw 2D polygons
glDisable(GL_LIGHTING);
@ -106,27 +123,33 @@ void CGALRenderer::draw(bool showfaces, bool showedges) const
this->polyset->render_surface(CSGMODE_NORMAL, Transform3d::Identity(), NULL);
}
}
else if (this->polyhedron) {
if (showfaces) this->polyhedron->set_style(SNC_BOUNDARY);
else this->polyhedron->set_style(SNC_SKELETON);
this->polyhedron->draw(showfaces && showedges);
}
else {
shared_ptr<class CGAL_OGL_Polyhedron> polyhedron = getPolyhedron();
if (polyhedron) {
PRINTD("draw() polyhedron");
if (showfaces) polyhedron->set_style(SNC_BOUNDARY);
else polyhedron->set_style(SNC_SKELETON);
polyhedron->draw(showfaces && showedges);
}
}
PRINTD("draw() end");
}
BoundingBox CGALRenderer::getBoundingBox() const
{
BoundingBox bbox;
if (this->polyhedron) {
CGAL::Bbox_3 cgalbbox = this->polyhedron->bbox();
bbox = BoundingBox(
Vector3d(cgalbbox.xmin(), cgalbbox.ymin(), cgalbbox.zmin()),
Vector3d(cgalbbox.xmax(), cgalbbox.ymax(), cgalbbox.zmax()) );
}
else if (this->polyset) {
if (this->polyset) {
bbox = this->polyset->getBoundingBox();
}
else {
shared_ptr<class CGAL_OGL_Polyhedron> polyhedron = getPolyhedron();
if (polyhedron) {
CGAL::Bbox_3 cgalbbox = polyhedron->bbox();
bbox = BoundingBox(
Vector3d(cgalbbox.xmin(), cgalbbox.ymin(), cgalbbox.zmin()),
Vector3d(cgalbbox.xmax(), cgalbbox.ymax(), cgalbbox.zmax()));
}
}
return bbox;
}

View File

@ -1,16 +1,22 @@
#pragma once
#include "renderer.h"
#include "CGAL_Nef_polyhedron.h"
class CGALRenderer : public Renderer
{
public:
CGALRenderer(shared_ptr<const class Geometry> geom);
virtual ~CGALRenderer();
~CGALRenderer();
virtual void draw(bool showfaces, bool showedges) const;
virtual void setColorScheme(const ColorScheme &cs);
virtual BoundingBox getBoundingBox() const;
public:
shared_ptr<class Polyhedron> polyhedron;
private:
shared_ptr<class CGAL_OGL_Polyhedron> getPolyhedron() const;
void buildPolyhedron() const;
mutable shared_ptr<class CGAL_OGL_Polyhedron> polyhedron;
shared_ptr<const CGAL_Nef_polyhedron> N;
shared_ptr<const class PolySet> polyset;
};

View File

@ -53,6 +53,8 @@ size_t CGAL_Nef_polyhedron::memsize() const
Note: Can return NULL if an error occurred
*/
// FIXME: Deprecated by CGALUtils::createPolySetFromNefPolyhedron3
#if 0
PolySet *CGAL_Nef_polyhedron::convertToPolyset() const
{
if (this->isEmpty()) return new PolySet(3);
@ -74,7 +76,7 @@ PolySet *CGAL_Nef_polyhedron::convertToPolyset() const
err = true;
errmsg = std::string(e.what());
}
if (!err) err = createPolySetFromPolyhedron(P, *ps);
if (!err) err = CGALUtils::createPolySetFromPolyhedron(P, *ps);
if (err) {
PRINT("ERROR: CGAL NefPolyhedron->Polyhedron conversion failed.");
if (errmsg!="") PRINTB("ERROR: %s",errmsg);
@ -83,6 +85,7 @@ PolySet *CGAL_Nef_polyhedron::convertToPolyset() const
CGAL::set_error_behaviour(old_behaviour);
return ps;
}
#endif
void CGAL_Nef_polyhedron::resize(Vector3d newsize,
const Eigen::Matrix<bool,3,1> &autosize)

View File

@ -27,7 +27,8 @@ public:
CGAL_Nef_polyhedron &operator*=(const CGAL_Nef_polyhedron &other);
CGAL_Nef_polyhedron &operator-=(const CGAL_Nef_polyhedron &other);
CGAL_Nef_polyhedron &minkowski(const CGAL_Nef_polyhedron &other);
class PolySet *convertToPolyset() const;
// FIXME: Deprecated by CGALUtils::createPolySetFromNefPolyhedron3
// class PolySet *convertToPolyset() const;
void transform( const Transform3d &matrix );
void resize(Vector3d newsize, const Eigen::Matrix<bool,3,1> &autosize);

View File

@ -27,19 +27,16 @@
#pragma once
#ifndef NULLGL
#include "OGL_helper.h"
#undef CGAL_NEF3_MARKED_VERTEX_COLOR
#undef CGAL_NEF3_MARKED_EDGE_COLOR
#undef CGAL_NEF3_MARKED_FACET_COLOR
#undef CGAL_NEF3_UNMARKED_VERTEX_COLOR
#undef CGAL_NEF3_UNMARKED_EDGE_COLOR
#undef CGAL_NEF3_UNMARKED_FACET_COLOR
#include "colormap.h"
#include "rendersettings.h"
#include "OGL_helper.h"
#include "printutils.h"
using CGAL::OGL::SNC_BOUNDARY;
using CGAL::OGL::SNC_SKELETON;
class Polyhedron : public CGAL::OGL::Polyhedron
class CGAL_OGL_Polyhedron : public CGAL::OGL::Polyhedron
{
public:
@ -53,16 +50,18 @@ public:
NUM_COLORS
};
Polyhedron() {
CGAL_OGL_Polyhedron(const ColorScheme &cs) {
PRINTD("CGAL_OGL_Polyhedron()");
// Set default colors.
setColor(CGAL_NEF3_MARKED_VERTEX_COLOR,0xb7,0xe8,0x5c);
setColor(CGAL_NEF3_MARKED_EDGE_COLOR,0xab,0xd8,0x56);
setColor(CGAL_NEF3_MARKED_FACET_COLOR,0x9d,0xcb,0x51);
setColor(CGAL_NEF3_UNMARKED_VERTEX_COLOR,0xff,0xf6,0x7c);
setColor(CGAL_NEF3_UNMARKED_EDGE_COLOR,0xff,0xec,0x5e);
setColor(CGAL_NEF3_UNMARKED_FACET_COLOR,0xf9,0xd7,0x2c);
// Face and Edge colors are taken from default colorscheme
setColorScheme(cs);
PRINTD("CGAL_OGL_Polyhedron() end");
}
void draw(bool showedges) const {
PRINTD("draw()");
if(this->style == SNC_BOUNDARY) {
glCallList(this->object_list_+2);
if(showedges) {
@ -75,31 +74,55 @@ public:
glCallList(this->object_list_+1);
glCallList(this->object_list_);
}
PRINTD("draw() end");
}
// overrides function in OGL_helper.h
CGAL::Color getVertexColor(Vertex_iterator v) const {
PRINTD("getVertexColor");
CGAL::Color c = v->mark() ? colors[CGAL_NEF3_UNMARKED_VERTEX_COLOR] : colors[CGAL_NEF3_MARKED_VERTEX_COLOR];
return c;
}
// overrides function in OGL_helper.h
CGAL::Color getEdgeColor(Edge_iterator e) const {
PRINTD("getEdgeColor");
CGAL::Color c = e->mark() ? colors[CGAL_NEF3_UNMARKED_EDGE_COLOR] : colors[CGAL_NEF3_MARKED_EDGE_COLOR];
return c;
}
CGAL::Color getFacetColor(Halffacet_iterator f) const {
// overrides function in OGL_helper.h
CGAL::Color getFacetColor(Halffacet_iterator f, bool is_back_facing) const {
PRINTD("getFacetColor");
CGAL::Color c = f->mark() ? colors[CGAL_NEF3_UNMARKED_FACET_COLOR] : colors[CGAL_NEF3_MARKED_FACET_COLOR];
return c;
}
void setColor(Polyhedron::RenderColor color_index,
void setColor(CGAL_OGL_Polyhedron::RenderColor color_index, const Color4f &c) {
PRINTDB("setColor %i %f %f %f",color_index%c[0]%c[1]%c[2]);
this->colors[color_index] = CGAL::Color(c[0]*255,c[1]*255,c[2]*255);
}
void setColor(CGAL_OGL_Polyhedron::RenderColor color_index,
unsigned char r, unsigned char g, unsigned char b) {
assert(color_index < Polyhedron::NUM_COLORS);
PRINTDB("setColor %i %i %i %i",color_index%r%g%b);
this->colors[color_index] = CGAL::Color(r,g,b);
}
// set this->colors based on the given colorscheme. vertex colors
// are not set here as colorscheme doesnt yet hold vertex colors.
void setColorScheme(const ColorScheme &cs) {
PRINTD("setColorScheme");
setColor(CGAL_NEF3_MARKED_FACET_COLOR, ColorMap::getColor(cs, CGAL_FACE_BACK_COLOR));
setColor(CGAL_NEF3_UNMARKED_FACET_COLOR, ColorMap::getColor(cs, CGAL_FACE_FRONT_COLOR));
setColor(CGAL_NEF3_MARKED_EDGE_COLOR, ColorMap::getColor(cs, CGAL_EDGE_BACK_COLOR));
setColor(CGAL_NEF3_UNMARKED_EDGE_COLOR, ColorMap::getColor(cs, CGAL_EDGE_FRONT_COLOR));
}
private:
CGAL::Color colors[NUM_COLORS];
}; // Polyhedron
}; // CGAL_OGL_Polyhedron
@ -108,10 +131,10 @@ private:
#include <CGAL/Bbox_3.h>
class Polyhedron
class CGAL_OGL_Polyhedron
{
public:
Polyhedron() {}
CGAL_OGL_Polyhedron() {}
void draw(bool showedges) const {}
CGAL::Bbox_3 bbox() const { return CGAL::Bbox_3(-1,-1,-1,1,1,1); }
};

View File

@ -5,6 +5,7 @@
Camera::Camera(enum CameraType camtype) :
type(camtype), projection(Camera::PERSPECTIVE), fov(45), height(60), viewall(false)
{
PRINTD("Camera()");
if (this->type == Camera::GIMBAL) {
object_trans << 0,0,0;
object_rot << 35,0,25;
@ -92,6 +93,10 @@ void Camera::viewAll(const BoundingBox &bbox, float scalefactor)
}
break;
}
PRINTDB("modified center x y z %f %f %f",center.x() % center.y() % center.z());
PRINTDB("modified eye x y z %f %f %f",eye.x() % eye.y() % eye.z());
PRINTDB("modified obj trans x y z %f %f %f",object_trans.x() % object_trans.y() % object_trans.z());
PRINTDB("modified obj rot x y z %f %f %f",object_rot.x() % object_rot.y() % object_rot.z());
}
void Camera::zoom(int delta)

View File

@ -45,7 +45,7 @@ static bool FontInfoSortPredicate(const FontInfo& fi1, const FontInfo& fi2)
return (fi1 < fi2);
}
FontInfo::FontInfo(std::string family, std::string style, std::string file) : family(family), style(style), file(file)
FontInfo::FontInfo(const std::string &family, const std::string &style, const std::string &file) : family(family), style(style), file(file)
{
}
@ -64,63 +64,52 @@ bool FontInfo::operator<(const FontInfo &rhs) const
return file < rhs.file;
}
std::string FontInfo::get_family() const
const std::string &FontInfo::get_family() const
{
return family;
}
std::string FontInfo::get_style() const
const std::string &FontInfo::get_style() const
{
return style;
}
std::string FontInfo::get_file() const
const std::string &FontInfo::get_file() const
{
return file;
}
FontCache * FontCache::self = NULL;
const std::string FontCache::DEFAULT_FONT("Liberation Sans:style=Regular");
const std::string FontCache::DEFAULT_FONT("XXX");
FontCache::FontCache()
{
init_ok = false;
this->init_ok = false;
config = FcInitLoadConfigAndFonts();
if (!config) {
// If we've got a bundled fonts.conf, initialize fontconfig with our own config
// by overriding the built-in fontconfig path.
// For system installs and dev environments, we leave this alone
fs::path fontdir(fs::path(PlatformUtils::resourcesPath()) / "fonts");
if (fs::is_regular_file(fontdir / "fonts.conf")) {
PlatformUtils::setenv("FONTCONFIG_PATH", boosty::stringy(boosty::absolute(fontdir)).c_str(), 0);
}
// Just load the configs. We'll build the fonts once all configs are loaded
this->config = FcInitLoadConfig();
if (!this->config) {
PRINT("Can't initialize fontconfig library, text() objects will not be rendered");
return;
}
BOOST_FOREACH(const std::string &dir, librarypath)
{
fs::path fontpath = fs::path(dir) / "../fonts";
if (fs::exists(fontpath) && fs::is_directory(fontpath)) {
fs::path path = boosty::canonical(fontpath);
add_font_dir(path.string());
fs::path fontconf = fontpath / "fonts.conf";
if (fs::exists(fontconf) && fs::is_regular(fontconf)) {
FcConfigParseAndLoad(config, (unsigned char *) fontconf.string().c_str(), false);
}
}
// Add the built-in fonts & config
fs::path builtinfontpath = fs::path(PlatformUtils::resourcesPath()) / "fonts";
if (fs::is_directory(builtinfontpath)) {
FcConfigParseAndLoad(this->config, reinterpret_cast<const FcChar8 *>(boosty::stringy(builtinfontpath).c_str()), false);
add_font_dir(boosty::stringy(boosty::canonical(builtinfontpath)));
}
const char *home = getenv("HOME");
// Add MacOS font folders. (see http://support.apple.com/kb/HT2435)
add_font_dir("/Library/Fonts");
add_font_dir("/System/Library/Fonts");
if (home) {
add_font_dir(std::string(home) + "/Library/Fonts");
}
// Add Window font folders.
const char *windir = getenv("WinDir");
if (windir) {
add_font_dir(std::string(windir) + "\\Fonts");
}
// Add Linux font folders, the system folders are expected to be
// configured by the system configuration for fontconfig.
if (home) {
@ -141,23 +130,23 @@ FontCache::FontCache()
}
}
FcStrList *dirs = FcConfigGetFontDirs(config);
while (true) {
FcChar8 *dir = FcStrListNext(dirs);
if (dir == NULL) {
break;
}
fontpath.push_back(std::string((const char *) dir));
// FIXME: Caching happens here. This would be a good place to notify the user
FcConfigBuildFonts(this->config);
// For use by LibraryInfo
FcStrList *dirs = FcConfigGetFontDirs(this->config);
while (FcChar8 *dir = FcStrListNext(dirs)) {
fontpath.push_back(std::string((const char *)dir));
}
FcStrListDone(dirs);
const FT_Error error = FT_Init_FreeType(&library);
const FT_Error error = FT_Init_FreeType(&this->library);
if (error) {
PRINT("Can't initialize freetype library, text() objects will not be rendered");
return;
}
init_ok = true;
this->init_ok = true;
}
FontCache::~FontCache()
@ -172,29 +161,29 @@ FontCache * FontCache::instance()
return self;
}
void FontCache::register_font_file(const std::string path)
void FontCache::register_font_file(const std::string &path)
{
if (!FcConfigAppFontAddFile(config, reinterpret_cast<const FcChar8 *> (path.c_str()))) {
if (!FcConfigAppFontAddFile(this->config, reinterpret_cast<const FcChar8 *> (path.c_str()))) {
PRINTB("Can't register font '%s'", path);
}
}
void FontCache::add_font_dir(const std::string path)
void FontCache::add_font_dir(const std::string &path)
{
if (!fs::is_directory(path)) {
return;
}
if (!FcConfigAppFontAddDir(config, reinterpret_cast<const FcChar8 *> (path.c_str()))) {
if (!FcConfigAppFontAddDir(this->config, reinterpret_cast<const FcChar8 *> (path.c_str()))) {
PRINTB("Can't register font directory '%s'", path);
}
}
FontInfoList * FontCache::list_fonts()
FontInfoList *FontCache::list_fonts() const
{
FcObjectSet *object_set = FcObjectSetBuild(FC_FAMILY, FC_STYLE, FC_FILE, (char *) 0);
FcPattern *pattern = FcPatternCreate();
init_pattern(pattern);
FcFontSet *font_set = FcFontList(config, pattern, object_set);
FcFontSet *font_set = FcFontList(this->config, pattern, object_set);
FcObjectSetDestroy(object_set);
FcPatternDestroy(pattern);
@ -220,20 +209,20 @@ FontInfoList * FontCache::list_fonts()
return list;
}
bool FontCache::is_init_ok()
bool FontCache::is_init_ok() const
{
return init_ok;
return this->init_ok;
}
void FontCache::clear()
{
cache.clear();
this->cache.clear();
}
void FontCache::dump_cache(const std::string info)
void FontCache::dump_cache(const std::string &info)
{
std::cout << info << ":";
for (cache_t::iterator it = cache.begin(); it != cache.end(); it++) {
for (cache_t::iterator it = this->cache.begin(); it != this->cache.end(); it++) {
std::cout << " " << (*it).first << " (" << (*it).second.second << ")";
}
std::cout << std::endl;
@ -241,25 +230,25 @@ void FontCache::dump_cache(const std::string info)
void FontCache::check_cleanup()
{
if (cache.size() < MAX_NR_OF_CACHE_ENTRIES) {
if (this->cache.size() < MAX_NR_OF_CACHE_ENTRIES) {
return;
}
cache_t::iterator pos = cache.begin()++;
for (cache_t::iterator it = cache.begin(); it != cache.end(); it++) {
cache_t::iterator pos = this->cache.begin()++;
for (cache_t::iterator it = this->cache.begin(); it != this->cache.end(); it++) {
if ((*pos).second.second > (*it).second.second) {
pos = it;
}
}
FT_Done_Face((*pos).second.first);
cache.erase(pos);
this->cache.erase(pos);
}
FT_Face FontCache::get_font(const std::string font)
FT_Face FontCache::get_font(const std::string &font)
{
FT_Face face;
cache_t::iterator it = cache.find(font);
if (it == cache.end()) {
cache_t::iterator it = this->cache.find(font);
if (it == this->cache.end()) {
face = find_face(font);
if (!face) {
return NULL;
@ -268,11 +257,11 @@ FT_Face FontCache::get_font(const std::string font)
} else {
face = (*it).second.first;
}
cache[font] = cache_entry_t(face, time(NULL));
this->cache[font] = cache_entry_t(face, time(NULL));
return face;
}
FT_Face FontCache::find_face(const std::string font)
FT_Face FontCache::find_face(const std::string &font) const
{
std::string trimmed(font);
boost::algorithm::trim(trimmed);
@ -284,7 +273,7 @@ FT_Face FontCache::find_face(const std::string font)
return face;
}
void FontCache::init_pattern(FcPattern *pattern)
void FontCache::init_pattern(FcPattern *pattern) const
{
FcValue true_value;
true_value.type = FcTypeBool;
@ -294,16 +283,17 @@ void FontCache::init_pattern(FcPattern *pattern)
FcPatternAdd(pattern, FC_SCALABLE, true_value, true);
}
FT_Face FontCache::find_face_fontconfig(const std::string font)
FT_Face FontCache::find_face_fontconfig(const std::string &font) const
{
FcResult result;
FcPattern *pattern = FcNameParse((unsigned char *) font.c_str());
FcPattern *pattern = FcNameParse((unsigned char *)font.c_str());
init_pattern(pattern);
FcConfigSubstitute(this->config, pattern, FcMatchPattern);
FcDefaultSubstitute(pattern);
FcConfigSubstitute(config, pattern, FcMatchFont);
FcPattern *match = FcFontMatch(config, pattern, &result);
FcPattern *match = FcFontMatch(this->config, pattern, &result);
FcValue file_value;
if (FcPatternGet(match, FC_FILE, 0, &file_value) != FcResultMatch) {
@ -316,7 +306,7 @@ FT_Face FontCache::find_face_fontconfig(const std::string font)
}
FT_Face face;
FT_Error error = FT_New_Face(library, (const char *) file_value.u.s, font_index.u.i, &face);
FT_Error error = FT_New_Face(this->library, (const char *) file_value.u.s, font_index.u.i, &face);
FcPatternDestroy(pattern);
FcPatternDestroy(match);
@ -351,7 +341,7 @@ FT_Face FontCache::find_face_fontconfig(const std::string font)
return error ? NULL : face;
}
bool FontCache::try_charmap(FT_Face face, int platform_id, int encoding_id)
bool FontCache::try_charmap(FT_Face face, int platform_id, int encoding_id) const
{
for (int idx = 0; idx < face->num_charmaps; idx++) {
FT_CharMap charmap = face->charmaps[idx];
@ -368,7 +358,7 @@ bool FontCache::try_charmap(FT_Face face, int platform_id, int encoding_id)
return false;
}
bool FontCache::is_windows_symbol_font(FT_Face face)
bool FontCache::is_windows_symbol_font(const FT_Face &face) const
{
if (face->charmap->platform_id != TT_PLATFORM_MICROSOFT) {
return false;

View File

@ -44,12 +44,12 @@
class FontInfo {
public:
FontInfo(std::string family, std::string style, std::string file);
FontInfo(const std::string &family, const std::string &style, const std::string &file);
virtual ~FontInfo();
std::string get_family() const;
std::string get_style() const;
std::string get_file() const;
const std::string &get_family() const;
const std::string &get_style() const;
const std::string &get_file() const;
bool operator<(const FontInfo &rhs) const;
private:
std::string family;
@ -67,14 +67,14 @@ public:
FontCache();
virtual ~FontCache();
bool is_init_ok();
FT_Face get_font(std::string font);
bool is_windows_symbol_font(FT_Face face);
void register_font_file(std::string path);
bool is_init_ok() const;
FT_Face get_font(const std::string &font);
bool is_windows_symbol_font(const FT_Face &face) const;
void register_font_file(const std::string &path);
void clear();
FontInfoList * list_fonts();
FontInfoList *list_fonts() const;
static FontCache * instance();
static FontCache *instance();
private:
typedef std::pair<FT_Face, time_t> cache_entry_t;
typedef std::map<std::string, cache_entry_t> cache_t;
@ -87,13 +87,13 @@ private:
FT_Library library;
void check_cleanup();
void dump_cache(const std::string info);
void dump_cache(const std::string &info);
void add_font_dir(const std::string path);
void init_pattern(FcPattern *pattern);
void add_font_dir(const std::string &path);
void init_pattern(FcPattern *pattern) const;
FT_Face find_face(const std::string font);
FT_Face find_face_fontconfig(const std::string font);
bool try_charmap(FT_Face face, int platform_id, int encoding_id);
FT_Face find_face(const std::string &font) const;
FT_Face find_face_fontconfig(const std::string &font) const;
bool try_charmap(FT_Face face, int platform_id, int encoding_id) const;
};

View File

@ -1,8 +1,10 @@
#include "GLView.h"
#include "stdio.h"
#include "colormap.h"
#include "rendersettings.h"
#include "mathc99.h"
#include "printutils.h"
#include "renderer.h"
#ifdef _WIN32
@ -22,6 +24,7 @@ GLView::GLView()
showaxes = false;
showcrosshairs = false;
renderer = NULL;
colorscheme = &ColorMap::inst()->defaultColorScheme();
cam = Camera();
far_far_away = RenderSettings::inst()->far_gl_clip_limit;
#ifdef ENABLE_OPENCSG
@ -39,6 +42,32 @@ void GLView::setRenderer(Renderer* r)
renderer = r;
}
/* update the color schemes of the Renderer attached to this GLView
to match the colorscheme of this GLView.*/
void GLView::updateColorScheme()
{
if (this->renderer) this->renderer->setColorScheme(*this->colorscheme);
}
/* change this GLView's colorscheme to the one given, and update the
Renderer attached to this GLView as well. */
void GLView::setColorScheme(const ColorScheme &cs)
{
this->colorscheme = &cs;
this->updateColorScheme();
}
void GLView::setColorScheme(const std::string &cs)
{
const ColorScheme *colorscheme = ColorMap::inst()->findColorScheme(cs);
if (colorscheme) {
setColorScheme(*colorscheme);
}
else {
PRINTB("WARNING: GLView: unknown colorscheme %s", cs);
}
}
void GLView::resizeGL(int w, int h)
{
#ifdef ENABLE_OPENCSG
@ -125,7 +154,7 @@ void GLView::paintGL()
setupCamera();
Color4f bgcol = RenderSettings::inst()->color(RenderSettings::BACKGROUND_COLOR);
Color4f bgcol = ColorMap::getColor(*this->colorscheme, BACKGROUND_COLOR);
glClearColor(bgcol[0], bgcol[1], bgcol[2], 1.0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
@ -321,6 +350,8 @@ void GLView::initializeGL()
glEnable(GL_NORMALIZE);
glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE);
// The following line is reported to fix issue #71
glMateriali(GL_FRONT_AND_BACK, GL_SHININESS, 64);
glEnable(GL_COLOR_MATERIAL);
#ifdef ENABLE_OPENCSG
enable_opencsg_shaders();
@ -440,7 +471,7 @@ void GLView::showCrosshairs()
// FIXME: Crosshairs and axes are lighted, this doesn't make sense and causes them
// to change color based on view orientation.
glLineWidth(3);
Color4f col = RenderSettings::inst()->color(RenderSettings::CROSSHAIR_COLOR);
Color4f col = ColorMap::getColor(*this->colorscheme, CROSSHAIR_COLOR);
glColor3f(col[0], col[1], col[2]);
glBegin(GL_LINES);
for (double xf = -1; xf <= +1; xf += 2)

View File

@ -26,6 +26,7 @@ Some actions (showCrossHairs) only work properly on Gimbal Camera.
#include "system-gl.h"
#include <iostream>
#include "Camera.h"
#include "colormap.h"
class GLView
{
@ -45,11 +46,16 @@ public:
void showAxes();
void showSmallaxes();
void setColorScheme(const ColorScheme &cs);
void setColorScheme(const std::string &cs);
void updateColorScheme();
virtual bool save(const char *filename) = 0;
virtual std::string getRendererInfo() const = 0;
virtual float getDPI() { return 1.0f; }
Renderer *renderer;
const ColorScheme *colorscheme;
Camera cam;
double far_far_away;
size_t width;

View File

@ -60,7 +60,14 @@ shared_ptr<const Geometry> GeometryEvaluator::evaluateGeometry(const AbstractNod
if (!allownef) {
if (shared_ptr<const CGAL_Nef_polyhedron> N = dynamic_pointer_cast<const CGAL_Nef_polyhedron>(this->root)) {
this->root.reset(N->convertToPolyset());
PolySet *ps = new PolySet(3);
ps->setConvexity(N->getConvexity());
this->root.reset(ps);
bool err = CGALUtils::createPolySetFromNefPolyhedron3(*N->p3, *ps);
if (err) {
PRINT("ERROR: Nef->PolySet failed");
}
smartCacheInsert(node, this->root);
}
}
@ -873,7 +880,7 @@ Response GeometryEvaluator::visit(State &state, const ProjectionNode &node)
if (chN) chPS.reset(chN->convertToPolyset());
if (chPS) ps2d = PolysetUtils::flatten(*chPS);
if (ps2d) {
CGAL_Nef_polyhedron *N2d = createNefPolyhedronFromGeometry(*ps2d);
CGAL_Nef_polyhedron *N2d = CGALUtils::createNefPolyhedronFromGeometry(*ps2d);
poly = N2d->convertToPolygon2d();
}
#endif
@ -887,7 +894,14 @@ Response GeometryEvaluator::visit(State &state, const ProjectionNode &node)
if (!chPS) {
shared_ptr<const CGAL_Nef_polyhedron> chN = dynamic_pointer_cast<const CGAL_Nef_polyhedron>(chgeom);
if (chN) {
chPS.reset(chN->convertToPolyset());
PolySet *ps = new PolySet(3);
bool err = CGALUtils::createPolySetFromNefPolyhedron3(*chN->p3, *ps);
if (err) {
PRINT("ERROR: Nef->PolySet failed");
}
else {
chPS.reset(ps);
}
}
}
if (chPS) poly = PolysetUtils::project(*chPS);
@ -915,7 +929,7 @@ Response GeometryEvaluator::visit(State &state, const ProjectionNode &node)
if (newgeom) {
shared_ptr<const CGAL_Nef_polyhedron> Nptr = dynamic_pointer_cast<const CGAL_Nef_polyhedron>(newgeom);
if (!Nptr) {
Nptr.reset(createNefPolyhedronFromGeometry(*newgeom));
Nptr.reset(CGALUtils::createNefPolyhedronFromGeometry(*newgeom));
}
if (!Nptr->isEmpty()) {
Polygon2d *poly = CGALUtils::project(*Nptr, node.cut_mode);
@ -948,7 +962,17 @@ Response GeometryEvaluator::visit(State &state, const CgaladvNode &node)
if (!isSmartCached(node)) {
switch (node.type) {
case MINKOWSKI: {
geom = applyToChildren(node, OPENSCAD_MINKOWSKI).constptr();
ResultObject res = applyToChildren(node, OPENSCAD_MINKOWSKI);
geom = res.constptr();
// If we added convexity, we need to pass it on
if (geom && geom->getConvexity() != node.convexity) {
shared_ptr<Geometry> editablegeom;
// If we got a const object, make a copy
if (res.isConst()) editablegeom.reset(geom->copy());
else editablegeom = res.ptr();
geom = editablegeom;
editablegeom->setConvexity(node.convexity);
}
break;
}
case HULL: {

View File

@ -1,6 +1,9 @@
#include "LibraryInfo.h"
#include <glib.h>
#include <vector>
#ifdef USE_SCINTILLA_EDITOR
#include <Qsci/qsciglobal.h>
#endif
#include "version_check.h"
#define STRINGIFY(x) #x
@ -82,6 +85,9 @@ std::string LibraryInfo::info()
<< "\nCGAL version, kernels: " << TOSTRING(CGAL_VERSION) << ", " << cgal_3d_kernel << ", " << cgal_2d_kernel << ", " << cgal_2d_kernelEx
<< "\nOpenCSG version: " << OPENCSG_VERSION_STRING
<< "\nQt version: " << qtVersion
#ifdef USE_SCINTILLA_EDITOR
<< "\nQScintilla version: " << QSCINTILLA_VERSION_STR
#endif
<< "\nMingW build: " << mingwstatus
<< "\nGLib version: " << GLIB_MAJOR_VERSION << "." << GLIB_MINOR_VERSION << "." << GLIB_MICRO_VERSION
<< "\nOPENSCADPATH: " << (env_path == NULL ? "<not set>" : env_path)

View File

@ -9,6 +9,7 @@
#include "module.h"
#include "Tree.h"
#include "memory.h"
#include "editor.h"
#include <vector>
#include <QMutex>
#include <QSet>
@ -67,11 +68,15 @@ public:
static const int maxRecentFiles = 10;
QAction *actionRecentFile[maxRecentFiles];
QMap<QString, QString> knownFileExtensions;
QMap<QString, QString> recentFilesMap;
LaunchingScreen *launcher;
QTreeWidgetItem *itm;
void show_launcher_examples(QString);
void add_child(QTreeWidgetItem*, QString);
QString editortype;
bool useScintilla;
MainWindow(const QString &filename);
~MainWindow();
@ -86,6 +91,7 @@ private slots:
void updateUndockMode(bool undockMode);
void setFileName(const QString &filename);
void setFont(const QString &family, uint size);
void setColorScheme(const QString &cs);
void showProgress();
void openCSGSettingsChanged();
void launcherOpenRecent();
@ -115,6 +121,8 @@ private:
void show_examples();
void setDockWidgetTitle(QDockWidget *dockWidget, QString prefix, bool topLevel);
EditorInterface *editor;
class QMessageBox *openglbox;
class FontListDialog *font_list_dialog;
@ -145,14 +153,13 @@ private slots:
private slots:
void selectFindType(int);
void find();
void findString(QString);
void findAndReplace();
void findNext();
void findPrev();
void useSelectionForFind();
void replace();
void replaceAll();
protected:
bool findOperation(QTextDocument::FindFlags options = 0);
virtual bool eventFilter(QObject* obj, QEvent *event);
private slots:

View File

@ -179,7 +179,6 @@
<addaction name="separator"/>
<addaction name="editActionIndent"/>
<addaction name="editActionUnindent"/>
<addaction name="separator"/>
<addaction name="editActionComment"/>
<addaction name="editActionUncomment"/>
<addaction name="separator"/>
@ -295,6 +294,15 @@
<number>0</number>
</property>
<layout class="QGridLayout" name="gridLayout">
<property name="topMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<property name="verticalSpacing">
<number>0</number>
</property>
<item row="0" column="0">
<widget class="QComboBox" name="findTypeComboBox">
<item>
@ -361,25 +369,6 @@
</layout>
</widget>
</item>
<item>
<widget class="Editor" name="editor" native="true">
<property name="minimumSize">
<size>
<width>100</width>
<height>100</height>
</size>
</property>
<property name="font">
<font>
<family>Monaco</family>
<pointsize>8</pointsize>
</font>
</property>
<property name="focusPolicy">
<enum>Qt::WheelFocus</enum>
</property>
</widget>
</item>
</layout>
</widget>
</widget>
@ -461,7 +450,7 @@
<string>Ctrl+Z</string>
</property>
<property name="shortcutContext">
<enum>Qt::WidgetWithChildrenShortcut</enum>
<enum>Qt::WindowShortcut</enum>
</property>
</action>
<action name="editActionRedo">
@ -472,7 +461,7 @@
<string>Ctrl+Shift+Z</string>
</property>
<property name="shortcutContext">
<enum>Qt::WidgetWithChildrenShortcut</enum>
<enum>Qt::WindowShortcut</enum>
</property>
</action>
<action name="editActionCut">
@ -483,7 +472,7 @@
<string>Ctrl+X</string>
</property>
<property name="shortcutContext">
<enum>Qt::WidgetWithChildrenShortcut</enum>
<enum>Qt::WindowShortcut</enum>
</property>
</action>
<action name="editActionCopy">
@ -494,7 +483,7 @@
<string>Ctrl+C</string>
</property>
<property name="shortcutContext">
<enum>Qt::WidgetWithChildrenShortcut</enum>
<enum>Qt::WindowShortcut</enum>
</property>
</action>
<action name="editActionPaste">
@ -505,7 +494,7 @@
<string>Ctrl+V</string>
</property>
<property name="shortcutContext">
<enum>Qt::WidgetWithChildrenShortcut</enum>
<enum>Qt::WindowShortcut</enum>
</property>
</action>
<action name="editActionIndent">
@ -776,9 +765,6 @@
<property name="text">
<string>Center</string>
</property>
<property name="shortcut">
<string>Ctrl+P</string>
</property>
</action>
<action name="viewActionPerspective">
<property name="checkable">
@ -975,15 +961,8 @@
<header>QGLView.h</header>
<container>1</container>
</customwidget>
<customwidget>
<class>Editor</class>
<extends>QWidget</extends>
<header>editor.h</header>
</customwidget>
</customwidgets>
<resources>
<include location="../openscad.qrc"/>
</resources>
<resources/>
<connections>
<connection>
<sender>fileActionClose</sender>

View File

@ -17,6 +17,8 @@
//
// Author(s) : Peter Hachenberger <hachenberger@mpi-sb.mpg.de>
// Modified for OpenSCAD
#pragma once
#include <CGAL/Nef_S2/OGL_base_object.h>
@ -25,16 +27,18 @@
#include "system-gl.h"
#include <cstdlib>
#define CGAL_NEF3_MARKED_VERTEX_COLOR 183,232,92
#define CGAL_NEF3_MARKED_EDGE_COLOR 171,216,86
#define CGAL_NEF3_MARKED_FACET_COLOR 157,203,81
#define CGAL_NEF3_MARKED_BACK_FACET_COLOR 157,103,181
#define CGAL_NEF3_UNMARKED_VERTEX_COLOR 255,246,124
#define CGAL_NEF3_UNMARKED_EDGE_COLOR 255,236,94
#define CGAL_NEF3_UNMARKED_FACET_COLOR 249,215,44
#define CGAL_NEF3_UNMARKED_BACK_FACET_COLOR 249,115,144
// Overridden in CGAL_renderer
/*
#define CGAL_NEF3_OGL_MARKED_VERTEX_COLOR 183,232,92
#define CGAL_NEF3_OGL_MARKED_EDGE_COLOR 171,216,86
#define CGAL_NEF3_OGL_MARKED_FACET_COLOR 157,203,81
#define CGAL_NEF3_OGL_MARKED_BACK_FACET_COLOR 157,103,181
#define CGAL_NEF3_OGL_UNMARKED_VERTEX_COLOR 255,246,124
#define CGAL_NEF3_OGL_UNMARKED_EDGE_COLOR 255,236,94
#define CGAL_NEF3_OGL_UNMARKED_FACET_COLOR 249,215,44
#define CGAL_NEF3_OGL_UNMARKED_BACK_FACET_COLOR 249,115,144
*/
const bool cull_backfaces = false;
const bool color_backfaces = false;
@ -362,18 +366,24 @@ namespace OGL {
Bbox_3 bbox() const { return bbox_; }
Bbox_3& bbox() { return bbox_; }
// Overridden in CGAL_renderer
virtual CGAL::Color getVertexColor(Vertex_iterator v) const
{
CGAL::Color cf(CGAL_NEF3_MARKED_VERTEX_COLOR),
ct(CGAL_NEF3_UNMARKED_VERTEX_COLOR); // more blue-ish
CGAL::Color c = v->mark() ? ct : cf;
PRINTD("getVertexColor()");
(void)v;
// CGAL::Color cf(CGAL_NEF3_OGL_MARKED_VERTEX_COLOR),
// ct(CGAL_NEF3_OGL_UNMARKED_VERTEX_COLOR); // more blue-ish
// CGAL::Color c = v->mark() ? ct : cf;
CGAL::Color c(0,0,200);
return c;
}
void draw(Vertex_iterator v) const {
PRINTD("draw( Vertex_iterator )");
// CGAL_NEF_TRACEN("drawing vertex "<<*v);
CGAL::Color c = getVertexColor(v);
glPointSize(10);
//glPointSize(1);
glColor3ub(c.red(), c.green(), c.blue());
glBegin(GL_POINTS);
glVertex3d(v->x(),v->y(),v->z());
@ -384,19 +394,26 @@ namespace OGL {
glEnd();
}
// Overridden in CGAL_renderer
virtual CGAL::Color getEdgeColor(Edge_iterator e) const
{
CGAL::Color cf(CGAL_NEF3_MARKED_EDGE_COLOR),
ct(CGAL_NEF3_UNMARKED_EDGE_COLOR); // more blue-ish
CGAL::Color c = e->mark() ? ct : cf;
PRINTD("getEdgeColor)");
(void)e;
// CGAL::Color cf(CGAL_NEF3_OGL_MARKED_EDGE_COLOR),
// ct(CGAL_NEF3_OGL_UNMARKED_EDGE_COLOR); // more blue-ish
// CGAL::Color c = e->mark() ? ct : cf;
// Overridden in CGAL_renderer
CGAL::Color c(200,0,0);
return c;
}
void draw(Edge_iterator e) const {
PRINTD("draw(Edge_iterator)");
// CGAL_NEF_TRACEN("drawing edge "<<*e);
Double_point p = e->source(), q = e->target();
CGAL::Color c = getEdgeColor(e);
glLineWidth(5);
//glLineWidth(1);
glColor3ub(c.red(),c.green(),c.blue());
glBegin(GL_LINE_STRIP);
glVertex3d(p.x(), p.y(), p.z());
@ -404,18 +421,32 @@ namespace OGL {
glEnd();
}
// Overridden in CGAL_renderer
virtual CGAL::Color getFacetColor(Halffacet_iterator f, bool is_back_facing) const
{
PRINTD("getFacetColor");
/*
(void)f;
// CGAL::Color cf(CGAL_NEF3_OGL_MARKED_FACET_COLOR),
// ct(CGAL_NEF3_OGL_UNMARKED_FACET_COLOR); // more blue-ish
// CGAL::Color c = (f->mark() ? ct : cf);
*/
CGAL::Color c(0,200,0);
return c;
/*
if (is_back_facing) return !f->mark()
? CGAL::Color(CGAL_NEF3_MARKED_BACK_FACET_COLOR)
: CGAL::Color(CGAL_NEF3_UNMARKED_BACK_FACET_COLOR);
? CGAL::Color(CGAL_NEF3_OGL_MARKED_BACK_FACET_COLOR)
: CGAL::Color(CGAL_NEF3_OGL_UNMARKED_BACK_FACET_COLOR);
else return !f->mark()
? CGAL::Color(CGAL_NEF3_MARKED_FACET_COLOR)
: CGAL::Color(CGAL_NEF3_UNMARKED_FACET_COLOR);
? CGAL::Color(CGAL_NEF3_OGL_MARKED_FACET_COLOR)
: CGAL::Color(CGAL_NEF3_OGL_UNMARKED_FACET_COLOR);
*/
}
void draw(Halffacet_iterator f, bool is_back_facing) const {
PRINTD("draw(Halffacet_iterator)");
// CGAL_NEF_TRACEN("drawing facet "<<(f->debug(),""));
GLUtesselator* tess_ = gluNewTess();
gluTessCallback(tess_, GLenum(GLU_TESS_VERTEX_DATA),
@ -458,6 +489,7 @@ namespace OGL {
void construct_axes() const
{
PRINTD("construct_axes");
glLineWidth(2.0);
// red x-axis
glColor3f(1.0,0.0,0.0);
@ -491,6 +523,7 @@ namespace OGL {
void fill_display_lists() {
PRINTD("fill_display_lists");
glNewList(object_list_, GL_COMPILE);
Vertex_iterator v;
for(v=vertices_.begin();v!=vertices_.end();++v)
@ -528,6 +561,7 @@ namespace OGL {
}
void init() {
PRINTD("init()");
if (init_) return;
init_ = true;
switches[SNC_AXES] = false;
@ -535,11 +569,13 @@ namespace OGL {
object_list_ = glGenLists(4);
CGAL_assertion(object_list_);
fill_display_lists();
PRINTD("init() end");
}
void draw() const
{
PRINTD("draw()");
if (!is_initialized()) const_cast<Polyhedron&>(*this).init();
double l = (std::max)( (std::max)( bbox().xmax() - bbox().xmin(),
bbox().ymax() - bbox().ymin()),
@ -562,6 +598,7 @@ namespace OGL {
glCallList(object_list_+1); // edges
glCallList(object_list_); // vertices
if (switches[SNC_AXES]) glCallList(object_list_+3); // axis
PRINTD("draw() end");
}
void debug(std::ostream& os = std::cerr) const

View File

@ -1,13 +1,32 @@
#include <stdlib.h>
#include "PlatformUtils.h"
#include "boosty.h"
#include <Eigen/Core>
#ifdef USE_SCINTILLA_EDITOR
#include <Qsci/qsciglobal.h>
#endif
extern std::vector<std::string> librarypath;
extern std::vector<std::string> fontpath;
bool PlatformUtils::createLibraryPath()
namespace {
std::string applicationpath;
}
void PlatformUtils::registerApplicationPath(const std::string &apppath)
{
std::string path = PlatformUtils::libraryPath();
applicationpath = apppath;
}
std::string PlatformUtils::applicationPath()
{
return applicationpath;
}
bool PlatformUtils::createUserLibraryPath()
{
std::string path = PlatformUtils::userLibraryPath();
bool OK = false;
try {
if (!fs::exists(fs::path(path))) {
@ -23,7 +42,7 @@ bool PlatformUtils::createLibraryPath()
return OK;
}
std::string PlatformUtils::libraryPath()
std::string PlatformUtils::userLibraryPath()
{
fs::path path;
try {
@ -76,3 +95,53 @@ bool PlatformUtils::createBackupPath()
}
return OK;
}
// This is the built-in read-only resources path
std::string PlatformUtils::resourcesPath()
{
fs::path resourcedir(applicationPath());
fs::path tmpdir;
#ifdef __APPLE__
// Resources can be bundled on Mac. If not, fall back to development layout
bool isbundle = is_directory(resourcedir / ".." / "Resources");
if (isbundle) {
resourcedir /= "../Resources";
// Fall back to dev layout
if (!is_directory(resourcedir / "libraries")) resourcedir /= "../../..";
}
#elif !defined(WIN32)
tmpdir = resourcedir / "../share/openscad";
if (is_directory(tmpdir / "libraries")) {
resourcedir = tmpdir;
}
else {
tmpdir = resourcedir / "../../share/openscad";
if (is_directory(tmpdir / "libraries")) {
resourcedir = tmpdir;
} else {
tmpdir = resourcedir / "../..";
if (is_directory(tmpdir / "libraries")) {
resourcedir = tmpdir;
}
}
}
#endif
// resourcedir defaults to applicationPath
return boosty::stringy(boosty::canonical(resourcedir));
}
int PlatformUtils::setenv(const char *name, const char *value, int overwrite)
{
#if defined(WIN32)
const char *ptr = getenv(name);
if ((overwrite == 0) && (ptr != NULL)) {
return 0;
}
char buf[4096];
snprintf(buf, sizeof(buf), "%s=%s", name, value);
return _putenv(buf);
#else
return ::setenv(name, value, overwrite);
#endif
}

View File

@ -4,21 +4,35 @@
namespace PlatformUtils {
void registerApplicationPath(const std::string &applicationpath);
std::string applicationPath();
std::string documentsPath();
std::string libraryPath();
bool createLibraryPath();
std::string resourcesPath();
std::string userLibraryPath();
bool createUserLibraryPath();
std::string backupPath();
bool createBackupPath();
/**
* Single character separating path specifications in a list
* (e.g. OPENSCADPATH). On Windows that's ';' and on most other
* systems ':'.
*
* @return the path separator
*/
std::string pathSeparatorChar();
/**
* Platform abstraction to set environment variables. Windows/MinGW
* does not support setenv(), but needs _putenv().
*
* @param name name of the environment variable.
* @param value the value to set for the environment variable.
* @return 0 on success.
*/
int setenv(const char *name, const char *value, int overwrite);
/**
* Single character separating path specifications in a list
* (e.g. OPENSCADPATH). On Windows that's ';' and on most other
* systems ':'.
*
* @return the path separator
*/
std::string pathSeparatorChar();
/* Provide stdout/stderr if not available.
* Currently limited to MS Windows GUI application console only.
*/

View File

@ -4,6 +4,10 @@
#include "linalg.h"
#include <vector>
/*!
A single contour.
positive is (optionally) used to distinguish between polygon contours and hold contours.
*/
struct Outline2d {
Outline2d() : positive(true) {}
std::vector<Vector2d> vertices;

View File

@ -37,6 +37,8 @@
#ifdef ENABLE_CGAL
#include "CGALCache.h"
#endif
#include "colormap.h"
#include "rendersettings.h"
Preferences *Preferences::instance = NULL;
@ -64,6 +66,7 @@ Preferences::Preferences(QWidget *parent) : QMainWindow(parent)
this->defaultmap["editor/fontfamily"] = found_family;
this->defaultmap["editor/fontsize"] = 12;
this->defaultmap["editor/syntaxhighlight"] = "For Light Background";
this->defaultmap["editor/editortype"] = "QScintilla Editor";
#if defined (Q_OS_MAC)
this->defaultmap["editor/ctrlmousewheelzoom"] = false;
@ -83,11 +86,13 @@ Preferences::Preferences(QWidget *parent) : QMainWindow(parent)
connect(this->fontSize, SIGNAL(currentIndexChanged(const QString&)),
this, SLOT(on_fontSize_editTextChanged(const QString &)));
connect(this->editorType, SIGNAL(currentIndexChanged(const QString&)),
this, SLOT(on_editorType_editTextChanged(const QString &)));
// reset GUI fontsize if fontSize->addItem emitted signals that changed it.
this->fontSize->setEditText( QString("%1").arg( savedsize ) );
// Setup default settings
this->defaultmap["3dview/colorscheme"] = this->colorSchemeChooser->currentItem()->text();
this->defaultmap["advanced/opencsg_show_warning"] = true;
this->defaultmap["advanced/enable_opencsg_opengl1x"] = true;
this->defaultmap["advanced/polysetCacheSize"] = uint(GeometryCache::instance()->maxSize());
@ -120,38 +125,7 @@ Preferences::Preferences(QWidget *parent) : QMainWindow(parent)
this->actionTriggered(this->prefsAction3DView);
// 3D View pane
this->colorschemes["Cornfield"][RenderSettings::BACKGROUND_COLOR] = Color4f(0xff, 0xff, 0xe5);
this->colorschemes["Cornfield"][RenderSettings::OPENCSG_FACE_FRONT_COLOR] = Color4f(0xf9, 0xd7, 0x2c);
this->colorschemes["Cornfield"][RenderSettings::OPENCSG_FACE_BACK_COLOR] = Color4f(0x9d, 0xcb, 0x51);
this->colorschemes["Cornfield"][RenderSettings::CGAL_FACE_FRONT_COLOR] = Color4f(0xf9, 0xd7, 0x2c);
this->colorschemes["Cornfield"][RenderSettings::CGAL_FACE_BACK_COLOR] = Color4f(0x9d, 0xcb, 0x51);
this->colorschemes["Cornfield"][RenderSettings::CGAL_FACE_2D_COLOR] = Color4f(0x00, 0xbf, 0x99);
this->colorschemes["Cornfield"][RenderSettings::CGAL_EDGE_FRONT_COLOR] = Color4f(0xff, 0x00, 0x00);
this->colorschemes["Cornfield"][RenderSettings::CGAL_EDGE_BACK_COLOR] = Color4f(0xff, 0x00, 0x00);
this->colorschemes["Cornfield"][RenderSettings::CGAL_EDGE_2D_COLOR] = Color4f(0xff, 0x00, 0x00);
this->colorschemes["Cornfield"][RenderSettings::CROSSHAIR_COLOR] = Color4f(0x80, 0x00, 0x00);
this->colorschemes["Metallic"][RenderSettings::BACKGROUND_COLOR] = Color4f(0xaa, 0xaa, 0xff);
this->colorschemes["Metallic"][RenderSettings::OPENCSG_FACE_FRONT_COLOR] = Color4f(0xdd, 0xdd, 0xff);
this->colorschemes["Metallic"][RenderSettings::OPENCSG_FACE_BACK_COLOR] = Color4f(0xdd, 0x22, 0xdd);
this->colorschemes["Metallic"][RenderSettings::CGAL_FACE_FRONT_COLOR] = Color4f(0xdd, 0xdd, 0xff);
this->colorschemes["Metallic"][RenderSettings::CGAL_FACE_BACK_COLOR] = Color4f(0xdd, 0x22, 0xdd);
this->colorschemes["Metallic"][RenderSettings::CGAL_FACE_2D_COLOR] = Color4f(0x00, 0xbf, 0x99);
this->colorschemes["Metallic"][RenderSettings::CGAL_EDGE_FRONT_COLOR] = Color4f(0xff, 0x00, 0x00);
this->colorschemes["Metallic"][RenderSettings::CGAL_EDGE_BACK_COLOR] = Color4f(0xff, 0x00, 0x00);
this->colorschemes["Metallic"][RenderSettings::CGAL_EDGE_2D_COLOR] = Color4f(0xff, 0x00, 0x00);
this->colorschemes["Metallic"][RenderSettings::CROSSHAIR_COLOR] = Color4f(0x80, 0x00, 0x00);
this->colorschemes["Sunset"][RenderSettings::BACKGROUND_COLOR] = Color4f(0xaa, 0x44, 0x44);
this->colorschemes["Sunset"][RenderSettings::OPENCSG_FACE_FRONT_COLOR] = Color4f(0xff, 0xaa, 0xaa);
this->colorschemes["Sunset"][RenderSettings::OPENCSG_FACE_BACK_COLOR] = Color4f(0x88, 0x22, 0x33);
this->colorschemes["Sunset"][RenderSettings::CGAL_FACE_FRONT_COLOR] = Color4f(0xff, 0xaa, 0xaa);
this->colorschemes["Sunset"][RenderSettings::CGAL_FACE_BACK_COLOR] = Color4f(0x88, 0x22, 0x33);
this->colorschemes["Sunset"][RenderSettings::CGAL_FACE_2D_COLOR] = Color4f(0x00, 0xbf, 0x99);
this->colorschemes["Sunset"][RenderSettings::CGAL_EDGE_FRONT_COLOR] = Color4f(0xff, 0x00, 0x00);
this->colorschemes["Sunset"][RenderSettings::CGAL_EDGE_BACK_COLOR] = Color4f(0xff, 0x00, 0x00);
this->colorschemes["Sunset"][RenderSettings::CGAL_EDGE_2D_COLOR] = Color4f(0xff, 0x00, 0x00);
this->colorschemes["Sunset"][RenderSettings::CROSSHAIR_COLOR] = Color4f(0x80, 0x00, 0x00);
this->defaultmap["3dview/colorscheme"] = "Cornfield";
// Advanced pane
QValidator *validator = new QIntValidator(this);
@ -164,10 +138,7 @@ Preferences::Preferences(QWidget *parent) : QMainWindow(parent)
setupFeaturesPage();
updateGUI();
RenderSettings::inst()->setColors(this->colorschemes[getValue("3dview/colorscheme").toString()]);
//launcher Settings
connect(this->launcherBox, SIGNAL(stateChanged(int)), SLOT(launcherSettings(int)));
}
Preferences::~Preferences()
@ -286,10 +257,7 @@ void Preferences::on_colorSchemeChooser_itemSelectionChanged()
QString scheme = this->colorSchemeChooser->currentItem()->text();
QSettings settings;
settings.setValue("3dview/colorscheme", scheme);
RenderSettings::inst()->setColors(this->colorschemes[scheme]);
emit requestRedraw();
emit colorSchemeChanged( scheme );
}
void Preferences::on_fontChooser_activated(const QString &family)
@ -307,6 +275,12 @@ void Preferences::on_fontSize_editTextChanged(const QString &size)
emit fontChanged(getValue("editor/fontfamily").toString(), intsize);
}
void Preferences::on_editorType_editTextChanged(const QString &type)
{
QSettings settings;
settings.setValue("editor/editortype", type);
}
void Preferences::on_syntaxHighlight_currentIndexChanged(const QString &s)
{
QSettings settings;
@ -476,6 +450,10 @@ void Preferences::updateGUI()
int shidx = this->syntaxHighlight->findText(shighlight);
if (shidx >= 0) this->syntaxHighlight->setCurrentIndex(shidx);
QString editortypevar = getValue("editor/editortype").toString();
int edidx = this->editorType->findText(editortypevar);
if (edidx >=0) this->editorType->setCurrentIndex(edidx);
this->mouseWheelZoomBox->setChecked(getValue("editor/ctrlmousewheelzoom").toBool());
if (AutoUpdater *updater = AutoUpdater::updater()) {

View File

@ -3,9 +3,7 @@
#include <QMainWindow>
#include <QSettings>
#include "ui_Preferences.h"
#include "rendersettings.h"
#include "linalg.h"
#include <map>
#include "colormap.h"
class Preferences : public QMainWindow, public Ui::Preferences
{
@ -38,14 +36,17 @@ public slots:
void on_undockCheckBox_toggled(bool);
void on_checkNowButton_clicked();
void launcherSettings(int);
void on_editorType_editTextChanged(const QString &);
signals:
void requestRedraw() const;
void updateMdiMode(bool mdi) const;
void updateUndockMode(bool mdi) const;
void fontChanged(const QString &family, uint size) const;
void colorSchemeChanged(const QString &scheme) const;
void openCSGSettingsChanged() const;
void syntaxHighlightChanged(const QString &s);
void editorTypeChanged(const QString &type);
private:
Preferences(QWidget *parent = NULL);
@ -56,7 +57,6 @@ private:
void addPrefPage(QActionGroup *group, QAction *action, QWidget *widget);
QSettings::SettingsMap defaultmap;
QHash<QString, std::map<RenderSettings::RenderColor, Color4f> > colorschemes;
QHash<const QAction *, QWidget *> prefPages;
static Preferences *instance;

View File

@ -6,8 +6,8 @@
<rect>
<x>0</x>
<y>0</y>
<width>823</width>
<height>440</height>
<width>544</width>
<height>389</height>
</rect>
</property>
<property name="sizePolicy">
@ -23,11 +23,11 @@
<bool>true</bool>
</property>
<widget class="QWidget" name="centralwidget">
<layout class="QVBoxLayout" name="verticalLayout">
<layout class="QVBoxLayout" name="verticalLayout_5">
<item>
<widget class="QStackedWidget" name="stackedWidget">
<property name="currentIndex">
<number>3</number>
<number>2</number>
</property>
<widget class="QWidget" name="page3DView">
<layout class="QVBoxLayout" name="verticalLayout_4">
@ -44,6 +44,12 @@
</item>
<item>
<widget class="QListWidget" name="colorSchemeChooser">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="MinimumExpanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="alternatingRowColors">
<bool>false</bool>
</property>
@ -65,6 +71,26 @@
<string>Sunset</string>
</property>
</item>
<item>
<property name="text">
<string>Starnight</string>
</property>
</item>
<item>
<property name="text">
<string>BeforeDawn</string>
</property>
</item>
<item>
<property name="text">
<string>Nature</string>
</property>
</item>
<item>
<property name="text">
<string>DeepOcean</string>
</property>
</item>
</widget>
</item>
</layout>
@ -100,10 +126,71 @@
</layout>
</widget>
<widget class="QWidget" name="pageEditor">
<layout class="QVBoxLayout" name="verticalLayout_5">
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="0">
<layout class="QHBoxLayout" name="horizontalLayout_5">
<item>
<widget class="QLabel" name="label_12">
<property name="font">
<font>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
<property name="text">
<string>Editor Type</string>
</property>
</widget>
</item>
<item>
<widget class="QComboBox" name="editorType">
<item>
<property name="text">
<string>Simple Editor</string>
</property>
</item>
<item>
<property name="text">
<string>QScintilla Editor</string>
</property>
</item>
</widget>
</item>
<item>
<widget class="QLabel" name="label_13">
<property name="font">
<font>
<pointsize>10</pointsize>
<weight>50</weight>
<bold>false</bold>
</font>
</property>
<property name="text">
<string>(requires restart)</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_7">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Expanding</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>30</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_6">
<item>
<widget class="QLabel" name="label_3">
<property name="font">
<font>
@ -119,37 +206,24 @@
</property>
</widget>
</item>
<item row="0" column="1">
<spacer name="horizontalSpacer_4">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item row="1" column="0" colspan="2">
<item>
<widget class="QFontComboBox" name="fontChooser">
<property name="currentFont">
<font>
<family>DejaVu Sans</family>
<family>Helvetica</family>
<pointsize>12</pointsize>
</font>
</property>
</widget>
</item>
<item row="1" column="2">
<item>
<widget class="QComboBox" name="fontSize">
<property name="editable">
<bool>true</bool>
</property>
</widget>
</item>
<item row="1" column="3">
<item>
<spacer name="horizontalSpacer_5">
<property name="orientation">
<enum>Qt::Horizontal</enum>
@ -200,6 +274,16 @@
<string>For Dark Background</string>
</property>
</item>
<item>
<property name="text">
<string>Monokai</string>
</property>
</item>
<item>
<property name="text">
<string>Solarized</string>
</property>
</item>
<item>
<property name="text">
<string>Off</string>
@ -273,7 +357,7 @@
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>77</height>
<height>723</height>
</size>
</property>
</spacer>
@ -365,7 +449,7 @@
<item>
<layout class="QHBoxLayout" name="horizontalLayout_10">
<item>
<spacer name="horizontalSpacer_11">
<spacer name="horizontalSpacer_31">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
@ -472,8 +556,8 @@
<rect>
<x>0</x>
<y>0</y>
<width>803</width>
<height>332</height>
<width>518</width>
<height>278</height>
</rect>
</property>
<layout class="QVBoxLayout" name="verticalLayout_10">

View File

@ -27,6 +27,7 @@
#include "ThrownTogetherRenderer.h"
#include "polyset.h"
#include "csgterm.h"
#include "printutils.h"
#include "system-gl.h"
@ -43,6 +44,7 @@ ThrownTogetherRenderer::ThrownTogetherRenderer(CSGChain *root_chain,
void ThrownTogetherRenderer::draw(bool /*showfaces*/, bool showedges) const
{
PRINTD("Thrown draw");
if (this->root_chain) {
glEnable(GL_CULL_FACE);
glCullFace(GL_BACK);
@ -62,6 +64,7 @@ void ThrownTogetherRenderer::renderCSGChain(CSGChain *chain, bool highlight,
bool background, bool showedges,
bool fberror) const
{
PRINTD("Thrown renderCSGChain");
glDepthFunc(GL_LEQUAL);
boost::unordered_map<std::pair<const Geometry*,const Transform3d*>,int> geomVisitMark;
BOOST_FOREACH(const CSGChainObject &obj, chain->objects) {

433
src/cgalutils-tess.cc Normal file
View File

@ -0,0 +1,433 @@
/*
This is our custom tessellator of Nef Polyhedron faces. The problem with
Nef faces is that sometimes the 'default' tessellator of Nef Polyhedron
doesnt work. This is particularly true with situations where the polygon
face is not, actually, 'simple', according to CGAL itself. This can
occur on a bad quality STL import but also for other reasons. The
resulting Nef face will appear to the average human eye as an ordinary,
simple polygon... but in reality it has multiple edges that are
slightly-out-of-alignment and sometimes they backtrack on themselves.
When the triangulator is fed a polygon with self-intersecting edges,
it's default behavior is to throw an exception. The other terminology
for this is to say that the 'constraints' in the triangulation are
'intersecting'. The 'constraints' represent the edges of the polygon.
The 'triangulation' is the covering of all the polygon points with
triangles.
How do we allow interseting constraints during triangulation? We use an
'Itag' for the triangulation, per the CGAL docs. This allows the
triangulator to run without throwing an exception when it encounters
self-intersecting polygon edges. The trick here is that when it finds
an intersection, it actually creates a new point.
The triangulator creates new points in 2d, but they aren't matched to
any 3d points on our 3d polygon plane. (The plane of the Nef face). How
to fix this problem? We actually 'project back up' or 'lift' into the 3d
plane from the 2d point. This is handled in the 'deproject()' function.
There is also the issue of the Simplicity of Nef Polyhedron face
polygons. They are often not simple. The intersecting-constraints
Triangulation can triangulate non-simple polygons, but of course it's
result is also non-simple. This means that CGAL functions like
orientation_2() and bounded_side() simply will not work on the resulting
polygons because they all require input polygons to pass the
'is_simple2()' test. We have to use alternatives in order to create our
triangles.
There is also the question of which underlying number type to use. Some
of the CGAL functions simply dont guarantee good results with a type
like double. Although much the math here is somewhat simple, like
line-line intersection, and involves only simple algebra, the
approximations required when using floating-point types can cause the
answers to be wrong. For example questions like 'is a point inside a
triangle' do not have good answers under floating-point systems where a
line may have a slope that is not expressible exactly as a floating
point number. There are ways to deal with floating point inaccuracy but
it is much, much simpler to use Rational numbers, although potentially
much slower in many cases.
*/
#include "cgalutils.h"
#include <CGAL/Delaunay_mesher_no_edge_refinement_2.h>
#include <CGAL/Delaunay_mesh_face_base_2.h>
typedef CGAL_Kernel3 Kernel;
//typedef CGAL::Triangulation_vertex_base_2<Kernel> Vb;
typedef CGAL::Triangulation_vertex_base_2<Kernel> Vb;
//typedef CGAL::Constrained_triangulation_face_base_2<Kernel> Fb;
typedef CGAL::Delaunay_mesh_face_base_2<Kernel> Fb;
typedef CGAL::Triangulation_data_structure_2<Vb,Fb> TDS;
typedef CGAL::Exact_intersections_tag ITAG;
typedef CGAL::Constrained_Delaunay_triangulation_2<Kernel,TDS,ITAG> CDT;
//typedef CGAL::Constrained_Delaunay_triangulation_2<Kernel,TDS> CDT;
typedef CDT::Vertex_handle Vertex_handle;
typedef CDT::Point CDTPoint;
typedef CGAL::Ray_2<Kernel> CGAL_Ray_2;
typedef CGAL::Line_3<Kernel> CGAL_Line_3;
typedef CGAL::Point_2<Kernel> CGAL_Point_2;
typedef CGAL::Vector_2<Kernel> CGAL_Vector_2;
typedef CGAL::Segment_2<Kernel> CGAL_Segment_2;
typedef CGAL::Direction_2<Kernel> CGAL_Direction_2;
typedef CGAL::Direction_3<Kernel> CGAL_Direction_3;
typedef CGAL::Plane_3<Kernel> CGAL_Plane_3;
/* The idea of 'projection' is how we make 3d points appear as though
they were 2d points to the tessellation algorithm. We take the 3-d plane
on which the polygon lies, and then 'project' or 'cast its shadow' onto
one of three standard planes, the xyplane, the yzplane, or the xzplane,
depending on which projection will prevent the polygon looking like a
flat line. (imagine, the triangle 0,0,1 0,1,1 0,1,0 ... if viewed from
the 'top' it looks line a flat line. so we want to view it from the
side). Thus we create a sequence of x,y points to feed to the algorithm,
but those points might actually be x,z pairs or y,z pairs... it is an
illusion we present to the triangulation algorithm by way of 'projection'.
We get a resulting sequence of triangles with x,y coordinates, which we
then 'deproject' back to x,z or y,z, in 3d space as needed. For example
the square 0,0,0 0,0,1 0,1,1 0,1,0 becomes '0,0 0,1 1,1 1,0', is then
split into two triangles, 0,0 1,0 1,1 and 0,0 1,1 0,1. those two triangles
then are projected back to 3d as 0,0,0 0,1,0 0,1,1 and 0,0 0,1,1 0,0,1.
There is an additional trick we do with projection related to Polygon
orientation and the orientation of our output triangles, and thus, which
way they are facing in space (aka their 'normals' or 'oriented side').
The basic issues is this: every 3d flat polygon can be thought of as
having two sides. In Computer Graphics the convention is that the
'outside' or 'oriented side' or 'normal' is determined by looking at the
triangle in terms of the 'ordering' or 'winding' of the points. If the
points come in a 'clockwise' order, you must be looking at the triangle
from 'inside'. If the points come in a 'counterclockwise' order, you
must be looking at the triangle from the outside. For example, the
triangle 0,0,0 1,0,0 0,1,0, when viewed from the 'top', has points in a
counterclockwise order, so the 'up' side is the 'normal' or 'outside'.
if you look at that same triangle from the 'bottom' side, the points
will appear to be 'clockwise', so the 'down' side is the 'inside', and is the
opposite of the 'normal' side.
How do we keep track of all that when doing a triangulation? We could
check each triangle as it was generated, and fix it's orientation before
we feed it back to our output list. That is done by, for example, checking
the orientation of the input polygon and then forcing the triangle to
match that orientation during output. This is what CGAL's Nef Polyhedron
does, you can read it inside /usr/include/CGAL/Nef_polyhedron_3.h.
Or.... we could actually add an additional 'projection' to the incoming
polygon points so that our triangulation algorithm is guaranteed to
create triangles with the proper orientation in the first place. How?
First, we assume that the triangulation algorithm will always produce
'counterclockwise' triangles in our plain old x-y plane.
The method is based on the following curious fact: That is, if you take
the points of a polygon, and flip the x,y coordinate of each point,
making y:=x and x:=y, then you essentially get a 'mirror image' of the
original polygon... but the orientation will be flipped. Given a
clockwise polygon, the 'flip' will result in a 'counterclockwise'
polygon mirror-image and vice versa.
Now, there is a second curious fact that helps us here. In 3d, we are
using the plane equation of ax+by+cz+d=0, where a,b,c determine its
direction. If you notice, there are actually mutiple sets of numbers
a:b:c that will describe the exact same plane. For example the 'ground'
plane, called the XYplane, where z is everywhere 0, has the equation
0x+0y+1z+0=0, simplifying to a solution for x,y,z of z=0 and x,y = any
numbers in your number system. However you can also express this as
0x+0y+-1z=0. The x,y,z solution is the same: z is everywhere 0, x and y
are any number, even though a,b,c are different. We can say that the
plane is 'oriented' differently, if we wish.
But how can we link that concept to the points on the polygon? Well, if
you generate a plane using the standard plane-equation generation
formula, given three points M,N,P, then you will get a plane equation
with <a:b:c:d>. However if you feed the points in the reverse order,
P,N,M, so that they are now oriented in the opposite order, you will get
a plane equation with the signs flipped. <-a:-b:-c:-d> This means you
can essentially consider that a plane has an 'orientation' based on it's
equation, by looking at the signs of a,b,c relative to some other
quantity.
This means that you can 'flip' the projection of the input polygon
points so that the projection will match the orientation of the input
plane, thus guaranteeing that the output triangles will be oriented in
the same direction as the input polygon was. In other words, even though
we technically 'lose information' when we project from 3d->2d, we can
actually keep the concept of 'orientation' through the whole
triangulation process, and not have to recalculate the proper
orientation during output.
For example take two side-squares of a cube and the plane equations
formed by feeding the points in counterclockwise, as if looking in from
outside the cube:
0,0,0 0,1,0 0,1,1 0,0,1 <-1:0:0:0>
1,0,0 1,1,0 1,1,1 1,0,1 <1:0:0:1>
They are both projected onto the YZ plane. They look the same:
0,0 1,0 1,1 0,1
0,0 1,0 1,1 0,1
But the second square plane has opposite orientation, so we flip the x
and y for each point:
0,0 1,0 1,1 0,1
0,0 0,1 1,1 1,0
Only now do we feed these two 2-d squares to the tessellation algorithm.
The result is 4 triangles. When de-projected back to 3d, they will have
the appropriate winding that will match that of the original 3d faces.
And the first two triangles will have opposite orientation from the last two.
*/
typedef enum { XYPLANE, YZPLANE, XZPLANE, NONE } plane_t;
struct projection_t {
plane_t plane;
bool flip;
};
CGAL_Point_2 get_projected_point( CGAL_Point_3 &p3, projection_t projection ) {
NT3 x,y;
if (projection.plane == XYPLANE) { x = p3.x(); y = p3.y(); }
else if (projection.plane == XZPLANE) { x = p3.x(); y = p3.z(); }
else if (projection.plane == YZPLANE) { x = p3.y(); y = p3.z(); }
else if (projection.plane == NONE) { x = 0; y = 0; }
if (projection.flip) return CGAL_Point_2( y,x );
return CGAL_Point_2( x,y );
}
/* given 2d point, 3d plane, and 3d->2d projection, 'deproject' from
2d back onto a point on the 3d plane. true on failure, false on success */
bool deproject( CGAL_Point_2 &p2, projection_t &projection, CGAL_Plane_3 &plane, CGAL_Point_3 &p3 )
{
NT3 x,y;
CGAL_Line_3 l;
CGAL_Point_3 p;
CGAL_Point_2 pf( p2.x(), p2.y() );
if (projection.flip) pf = CGAL_Point_2( p2.y(), p2.x() );
if (projection.plane == XYPLANE) {
p = CGAL_Point_3( pf.x(), pf.y(), 0 );
l = CGAL_Line_3( p, CGAL_Direction_3(0,0,1) );
} else if (projection.plane == XZPLANE) {
p = CGAL_Point_3( pf.x(), 0, pf.y() );
l = CGAL_Line_3( p, CGAL_Direction_3(0,1,0) );
} else if (projection.plane == YZPLANE) {
p = CGAL_Point_3( 0, pf.x(), pf.y() );
l = CGAL_Line_3( p, CGAL_Direction_3(1,0,0) );
}
CGAL::Object obj = CGAL::intersection( l, plane );
const CGAL_Point_3 *point_test = CGAL::object_cast<CGAL_Point_3>(&obj);
if (point_test) {
p3 = *point_test;
return false;
}
PRINT("ERROR: deproject failure");
return true;
}
/* this simple criteria guarantees CGALs triangulation algorithm will
terminate (i.e. not lock up and freeze the program) */
template <class T> class DummyCriteria {
public:
typedef double Quality;
class Is_bad {
public:
CGAL::Mesh_2::Face_badness operator()(const Quality) const {
return CGAL::Mesh_2::NOT_BAD;
}
CGAL::Mesh_2::Face_badness operator()(const typename T::Face_handle&, Quality&q) const {
q = 1;
return CGAL::Mesh_2::NOT_BAD;
}
};
Is_bad is_bad_object() const { return Is_bad(); }
};
NT3 sign( const NT3 &n )
{
if (n>0) return NT3(1);
if (n<0) return NT3(-1);
return NT3(0);
}
/* wedge, also related to 'determinant', 'signed parallelogram area',
'side', 'turn', 'winding', '2d portion of cross-product', etc etc. this
function can tell you whether v1 is 'counterclockwise' or 'clockwise'
from v2, based on the sign of the result. when the input Vectors are
formed from three points, A-B and B-C, it can tell you if the path along
the points A->B->C is turning left or right.*/
NT3 wedge( CGAL_Vector_2 &v1, CGAL_Vector_2 &v2 ) {
return v1.x()*v2.y()-v2.x()*v1.y();
}
/* given a point and a possibly non-simple polygon, determine if the
point is inside the polygon or not, using the given winding rule. note
that even_odd is not implemented. */
typedef enum { NONZERO_WINDING, EVEN_ODD } winding_rule_t;
bool inside(CGAL_Point_2 &p1,std::vector<CGAL_Point_2> &pgon, winding_rule_t winding_rule)
{
NT3 winding_sum = NT3(0);
CGAL_Point_2 p2;
CGAL_Ray_2 eastray(p1,CGAL_Direction_2(1,0));
for (size_t i=0;i<pgon.size();i++) {
CGAL_Point_2 tail = pgon[i];
CGAL_Point_2 head = pgon[(i+1)%pgon.size()];
CGAL_Segment_2 seg( tail, head );
CGAL::Object obj = intersection( eastray, seg );
const CGAL_Point_2 *point_test = CGAL::object_cast<CGAL_Point_2>(&obj);
if (point_test) {
p2 = *point_test;
CGAL_Vector_2 v1( p1, p2 );
CGAL_Vector_2 v2( p2, head );
NT3 this_winding = wedge( v1, v2 );
winding_sum += sign(this_winding);
} else {
continue;
}
}
if (winding_sum != NT3(0) && winding_rule == NONZERO_WINDING ) return true;
return false;
}
projection_t find_good_projection( CGAL_Plane_3 &plane )
{
projection_t goodproj;
goodproj.plane = NONE;
goodproj.flip = false;
NT3 qxy = plane.a()*plane.a()+plane.b()*plane.b();
NT3 qyz = plane.b()*plane.b()+plane.c()*plane.c();
NT3 qxz = plane.a()*plane.a()+plane.c()*plane.c();
NT3 min = std::min(qxy,std::min(qyz,qxz));
if (min==qxy) {
goodproj.plane = XYPLANE;
if (sign(plane.c())>0) goodproj.flip = true;
} else if (min==qyz) {
goodproj.plane = YZPLANE;
if (sign(plane.a())>0) goodproj.flip = true;
} else if (min==qxz) {
goodproj.plane = XZPLANE;
if (sign(plane.b())<0) goodproj.flip = true;
} else PRINT("ERROR: failed to find projection");
return goodproj;
}
namespace CGALUtils {
/* given a single near-planar 3d polygon with holes, tessellate into a
sequence of polygons without holes. as of writing, this means conversion
into a sequence of 3d triangles. the given plane should be the same plane
holding the polygon and it's holes. */
bool tessellate3DFaceWithHoles(std::vector<CGAL_Polygon_3> &polygons,
std::vector<CGAL_Polygon_3> &triangles,
CGAL_Plane_3 &plane)
{
if (polygons.size()==1 && polygons[0].size()==3) {
PRINTD("input polygon has 3 points. shortcut tessellation.");
CGAL_Polygon_3 t;
t.push_back(polygons[0][2]);
t.push_back(polygons[0][1]);
t.push_back(polygons[0][0]);
triangles.push_back( t );
return false;
}
bool err = false;
CDT cdt;
std::map<CDTPoint,CGAL_Point_3> vertmap;
PRINTD("finding good projection");
projection_t goodproj = find_good_projection( plane );
PRINTDB("plane %s",plane );
PRINTDB("proj: %i %i",goodproj.plane % goodproj.flip);
PRINTD("Inserting points and edges into Constrained Delaunay Triangulation");
std::vector< std::vector<CGAL_Point_2> > polygons2d;
for (size_t i=0;i<polygons.size();i++) {
std::vector<Vertex_handle> vhandles;
std::vector<CGAL_Point_2> polygon2d;
for (size_t j=0;j<polygons[i].size();j++) {
CGAL_Point_3 p3 = polygons[i][j];
CGAL_Point_2 p2 = get_projected_point( p3, goodproj );
CDTPoint cdtpoint = CDTPoint( p2.x(), p2.y() );
vertmap[ cdtpoint ] = p3;
Vertex_handle vh = cdt.push_back( cdtpoint );
vhandles.push_back( vh );
polygon2d.push_back( p2 );
}
polygons2d.push_back( polygon2d );
for (size_t k=0;k<vhandles.size();k++) {
int vindex1 = (k+0);
int vindex2 = (k+1)%vhandles.size();
CGAL::Failure_behaviour old_behaviour = CGAL::set_error_behaviour(CGAL::THROW_EXCEPTION);
try {
cdt.insert_constraint( vhandles[vindex1], vhandles[vindex2] );
} catch (const CGAL::Failure_exception &e) {
PRINTB("WARNING: Constraint insertion failure %s", e.what());
}
CGAL::set_error_behaviour(old_behaviour);
}
}
size_t numholes = polygons2d.size()-1;
PRINTDB("seeding %i holes",numholes);
std::list<CDTPoint> list_of_seeds;
for (size_t i=1;i<polygons2d.size();i++) {
std::vector<CGAL_Point_2> &pgon = polygons2d[i];
for (size_t j=0;j<pgon.size();j++) {
CGAL_Point_2 p1 = pgon[(j+0)];
CGAL_Point_2 p2 = pgon[(j+1)%pgon.size()];
CGAL_Point_2 p3 = pgon[(j+2)%pgon.size()];
CGAL_Point_2 mp = CGAL::midpoint(p1,CGAL::midpoint(p2,p3));
if (inside(mp,pgon,NONZERO_WINDING)) {
CDTPoint cdtpt( mp.x(), mp.y() );
list_of_seeds.push_back( cdtpt );
break;
}
}
}
std::list<CDTPoint>::iterator li = list_of_seeds.begin();
for (;li!=list_of_seeds.end();li++) {
//PRINTB("seed %s",*li);
double x = CGAL::to_double( li->x() );
double y = CGAL::to_double( li->y() );
PRINTDB("seed %f,%f",x%y);
}
PRINTD("seeding done");
PRINTD( "meshing" );
CGAL::refine_Delaunay_mesh_2_without_edge_refinement( cdt,
list_of_seeds.begin(), list_of_seeds.end(),
DummyCriteria<CDT>() );
PRINTD("meshing done");
// this fails because it calls is_simple and is_simple fails on many
// Nef Polyhedron faces
//CGAL::Orientation original_orientation =
// CGAL::orientation_2( orienpgon.begin(), orienpgon.end() );
CDT::Finite_faces_iterator fit;
for( fit=cdt.finite_faces_begin(); fit!=cdt.finite_faces_end(); fit++ )
{
if(fit->is_in_domain()) {
CDTPoint p1 = cdt.triangle( fit )[0];
CDTPoint p2 = cdt.triangle( fit )[1];
CDTPoint p3 = cdt.triangle( fit )[2];
CGAL_Point_3 cp1,cp2,cp3;
CGAL_Polygon_3 pgon;
if (vertmap.count(p1)) cp1 = vertmap[p1];
else err = deproject( p1, goodproj, plane, cp1 );
if (vertmap.count(p2)) cp2 = vertmap[p2];
else err = deproject( p2, goodproj, plane, cp2 );
if (vertmap.count(p3)) cp3 = vertmap[p3];
else err = deproject( p3, goodproj, plane, cp3 );
if (err) PRINT("WARNING: 2d->3d deprojection failure");
pgon.push_back( cp1 );
pgon.push_back( cp2 );
pgon.push_back( cp3 );
triangles.push_back( pgon );
}
}
PRINTDB("built %i triangles",triangles.size());
return err;
}
};

File diff suppressed because it is too large Load Diff

View File

@ -1,6 +1,6 @@
#pragma once
#include <cgal.h>
#include "cgal.h"
#include "polyset.h"
#include "CGAL_Nef_polyhedron.h"
#include "enums.h"
@ -13,12 +13,17 @@ namespace CGALUtils {
CGAL_Iso_cuboid_3 boundingBox(const CGAL_Nef_polyhedron3 &N);
bool is_approximately_convex(const PolySet &ps);
Geometry const* applyMinkowski(const Geometry::ChildList &children);
};
CGAL_Nef_polyhedron *createNefPolyhedronFromGeometry(const class Geometry &geom);
template <typename Polyhedron> bool createPolySetFromPolyhedron(const Polyhedron &p, PolySet &ps);
bool createPolySetFromNefPolyhedron3(const CGAL_Nef_polyhedron3 &N, PolySet &ps);
bool createPolyhedronFromPolySet(const PolySet &ps, CGAL_Polyhedron &p);
CGAL_Nef_polyhedron *createNefPolyhedronFromGeometry(const class Geometry &geom);
template <typename Polyhedron> bool createPolySetFromPolyhedron(const Polyhedron &p, PolySet &ps);
bool createPolySetFromNefPolyhedron3(const CGAL_Nef_polyhedron3 &N, PolySet &ps);
bool createPolyhedronFromPolySet(const PolySet &ps, CGAL_Polyhedron &p);
typedef std::vector<CGAL_Point_3> CGAL_Polygon_3;
bool tessellate3DFaceWithHoles(std::vector<CGAL_Polygon_3> &polygons,
std::vector<CGAL_Polygon_3> &triangles,
CGAL::Plane_3<CGAL_Kernel3> &plane);
};
#include "svg.h"
#include "printutils.h"

View File

@ -35,18 +35,18 @@
#include <boost/assign/std/vector.hpp>
#include <boost/assign/list_of.hpp>
using namespace boost::assign; // bring 'operator+=()' into scope
#include "colormap.h"
class ColorModule : public AbstractModule
{
public:
ColorModule() { }
ColorModule() : webcolors(ColorMap::inst()->webColors()) { }
virtual AbstractNode *instantiate(const Context *ctx, const ModuleInstantiation *inst, const EvalContext *evalctx) const;
private:
static boost::unordered_map<std::string, Color4f> colormap;
const boost::unordered_map<std::string, Color4f> &webcolors;
};
#include "colormap.h"
AbstractNode *ColorModule::instantiate(const Context *ctx, const ModuleInstantiation *inst, const EvalContext *evalctx) const
{
ColorNode *node = new ColorNode(inst);
@ -72,8 +72,8 @@ AbstractNode *ColorModule::instantiate(const Context *ctx, const ModuleInstantia
std::string colorname = v.toString();
boost::algorithm::to_lower(colorname);
Color4f color;
if (colormap.find(colorname) != colormap.end()) {
node->color = colormap[colorname];
if (webcolors.find(colorname) != webcolors.end()) {
node->color = webcolors.at(colorname);
} else {
PRINTB_NOCACHE("WARNING: Color name \"%s\" unknown. Please see", colorname);
PRINT_NOCACHE("WARNING: http://en.wikipedia.org/wiki/Web_colors");

320
src/colormap.cc Normal file
View File

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

View File

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

View File

@ -1,173 +1,16 @@
#include "editor.h"
#include "Preferences.h"
Editor::Editor(QWidget *parent) : QTextEdit(parent)
{
setAcceptRichText(false);
// This needed to avoid QTextEdit accepting filename drops as we want
// to handle these ourselves in MainWindow
setAcceptDrops(false);
this->highlighter = new Highlighter(this->document());
}
void Editor::indentSelection()
{
QTextCursor cursor = textCursor();
int p1 = cursor.selectionStart();
QString txt = cursor.selectedText();
txt.replace(QString(QChar(8233)), QString(QChar(8233)) + QString("\t"));
if (txt.endsWith(QString(QChar(8233)) + QString("\t")))
txt.chop(1);
txt = QString("\t") + txt;
cursor.insertText(txt);
int p2 = cursor.position();
cursor.setPosition(p1, QTextCursor::MoveAnchor);
cursor.setPosition(p2, QTextCursor::KeepAnchor);
setTextCursor(cursor);
}
void Editor::unindentSelection()
{
QTextCursor cursor = textCursor();
int p1 = cursor.selectionStart();
QString txt = cursor.selectedText();
txt.replace(QString(QChar(8233)) + QString("\t"), QString(QChar(8233)));
if (txt.startsWith(QString("\t")))
txt.remove(0, 1);
cursor.insertText(txt);
int p2 = cursor.position();
cursor.setPosition(p1, QTextCursor::MoveAnchor);
cursor.setPosition(p2, QTextCursor::KeepAnchor);
setTextCursor(cursor);
}
void Editor::commentSelection()
{
QTextCursor cursor = textCursor();
int p1 = cursor.selectionStart();
QString txt = cursor.selectedText();
txt.replace(QString(QChar(8233)), QString(QChar(8233)) + QString("//"));
if (txt.endsWith(QString(QChar(8233)) + QString("//")))
txt.chop(2);
txt = QString("//") + txt;
cursor.insertText(txt);
int p2 = cursor.position();
cursor.setPosition(p1, QTextCursor::MoveAnchor);
cursor.setPosition(p2, QTextCursor::KeepAnchor);
setTextCursor(cursor);
}
void Editor::uncommentSelection()
{
QTextCursor cursor = textCursor();
int p1 = cursor.selectionStart();
QString txt = cursor.selectedText();
txt.replace(QString(QChar(8233)) + QString("//"), QString(QChar(8233)));
if (txt.startsWith(QString("//")))
txt.remove(0, 2);
cursor.insertText(txt);
int p2 = cursor.position();
cursor.setPosition(p1, QTextCursor::MoveAnchor);
cursor.setPosition(p2, QTextCursor::KeepAnchor);
setTextCursor(cursor);
}
void Editor::zoomIn()
{
// See also QT's implementation in QEditor.cpp
QSettings settings;
QFont tmp_font = this->font() ;
if ( font().pointSize() >= 1 )
tmp_font.setPointSize( 1 + font().pointSize() );
else
tmp_font.setPointSize( 1 );
settings.setValue("editor/fontsize", tmp_font.pointSize());
this->setFont( tmp_font );
}
void Editor::zoomOut()
{
QSettings settings;
QFont tmp_font = this->font();
if ( font().pointSize() >= 2 )
tmp_font.setPointSize( -1 + font().pointSize() );
else
tmp_font.setPointSize( 1 );
settings.setValue("editor/fontsize", tmp_font.pointSize());
this->setFont( tmp_font );
}
void Editor::wheelEvent ( QWheelEvent * event )
void EditorInterface::wheelEvent(QWheelEvent *event)
{
QSettings settings;
bool wheelzoom_enabled = Preferences::inst()->getValue("editor/ctrlmousewheelzoom").toBool();
if ((event->modifiers() == Qt::ControlModifier) && wheelzoom_enabled ) {
if (event->delta() > 0 )
if ((event->modifiers() == Qt::ControlModifier) && wheelzoom_enabled) {
if (event->delta() > 0)
zoomIn();
else if (event->delta() < 0 )
else if (event->delta() < 0)
zoomOut();
} else {
QTextEdit::wheelEvent( event );
QWidget::wheelEvent(event);
}
}
void Editor::setPlainText(const QString &text)
{
int y = verticalScrollBar()->sliderPosition();
// Save current cursor position
QTextCursor cursor = textCursor();
int n = cursor.position();
QTextEdit::setPlainText(text);
// Restore cursor position
if (n < text.length()) {
cursor.setPosition(n);
setTextCursor(cursor);
verticalScrollBar()->setSliderPosition(y);
}
}
void Editor::highlightError(int error_pos)
{
highlighter->highlightError( error_pos );
QTextCursor cursor = this->textCursor();
cursor.setPosition( error_pos );
this->setTextCursor( cursor );
}
void Editor::unhighlightLastError()
{
highlighter->unhighlightLastError();
}
void Editor::setHighlightScheme(const QString &name)
{
highlighter->assignFormatsToTokens( name );
highlighter->rehighlight(); // slow on large files
}
QSize Editor::sizeHint() const
{
if (initialSizeHint.width() <= 0) {
return QTextEdit::sizeHint();
} else {
return initialSizeHint;
}
}
void Editor::setInitialSizeHint(const QSize &size)
{
initialSizeHint = size;
}
Editor::~Editor()
{
delete highlighter;
}

View File

@ -1,35 +1,52 @@
#pragma once
#include <QObject>
#include <QString>
#include <QWidget>
#include <QWheelEvent>
#include <QScrollBar>
#include <QTextEdit>
#include "highlighter.h"
class Editor : public QTextEdit
class EditorInterface : public QWidget
{
Q_OBJECT
public:
Editor(QWidget *parent);
~Editor();
QSize sizeHint() const;
void setInitialSizeHint(const QSize &size);
EditorInterface(QWidget *parent) : QWidget(parent) {}
virtual ~EditorInterface() {}
virtual QSize sizeHint(){ QSize size; return size;}
virtual void setInitialSizeHint(const QSize&) { }
virtual void wheelEvent(QWheelEvent*);
virtual QString toPlainText() = 0;
virtual QTextDocument *document(){QTextDocument *t = new QTextDocument; return t;}
virtual QString selectedText() = 0;
virtual bool find(const QString &, bool findNext = false, bool findBackwards = false) = 0;
virtual void replaceSelectedText(const QString &) = 0;
signals:
void contentsChanged();
void modificationChanged(bool);
public slots:
void zoomIn();
void zoomOut();
void setLineWrapping(bool on) { if(on) setWordWrapMode(QTextOption::WrapAnywhere); }
void setContentModified(bool y) { document()->setModified(y); }
bool isContentModified() { return document()->isModified(); }
void indentSelection();
void unindentSelection();
void commentSelection();
void uncommentSelection();
void setPlainText(const QString &text);
void highlightError(int error_pos);
void unhighlightLastError();
void setHighlightScheme(const QString &name);
virtual void zoomIn() = 0;
virtual void zoomOut() = 0;
virtual void setContentModified(bool) = 0;
virtual bool isContentModified() = 0;
virtual void indentSelection() = 0;
virtual void unindentSelection() = 0;
virtual void commentSelection() = 0;
virtual void uncommentSelection() = 0;
virtual void setPlainText(const QString &) = 0;
virtual void highlightError(int) = 0;
virtual void unhighlightLastError() = 0;
virtual void setHighlightScheme(const QString&) = 0;
virtual void insert(const QString&) = 0;
virtual void undo() = 0;
virtual void redo() = 0;
virtual void cut() = 0;
virtual void copy() = 0;
virtual void paste() = 0;
virtual void initFont(const QString&, uint) = 0;
private:
void wheelEvent ( QWheelEvent * event );
Highlighter *highlighter;
QSize initialSizeHint;
QSize initialSizeHint;
};

View File

@ -134,14 +134,33 @@ void export_stl(const PolySet &ps, std::ostream &output)
setlocale(LC_NUMERIC, "C"); // Ensure radix is . (not ,) in output
output << "solid OpenSCAD_Model\n";
BOOST_FOREACH(const PolySet::Polygon &p, triangulated.polygons) {
output << " facet normal 0 0 0\n";
output << " outer loop\n";
assert(p.size() == 3); // STL only allows triangles
BOOST_FOREACH(const Vector3d &v, p) {
output << "vertex " << v[0] << " " << v[1] << " " << v[2] << "\n";
std::stringstream stream;
stream << p[0][0] << " " << p[0][1] << " " << p[0][2];
std::string vs1 = stream.str();
stream.str("");
stream << p[1][0] << " " << p[1][1] << " " << p[1][2];
std::string vs2 = stream.str();
stream.str("");
stream << p[2][0] << " " << p[2][1] << " " << p[2][2];
std::string vs3 = stream.str();
if (vs1 != vs2 && vs1 != vs3 && vs2 != vs3) {
// The above condition ensures that there are 3 distinct vertices, but
// they may be collinear. If they are, the unit normal is meaningless
// so the default value of "1 0 0" can be used. If the vertices are not
// collinear then the unit normal must be calculated from the
// components.
Vector3d normal = (p[1] - p[0]).cross(p[2] - p[0]);
normal.normalize();
output << " facet normal " << normal[0] << " " << normal[1] << " " << normal[2] << "\n";
output << " outer loop\n";
BOOST_FOREACH(const Vector3d &v, p) {
output << " vertex " << v[0] << " " << v[1] << " " << v[2] << "\n";
}
output << " endloop\n";
output << " endfacet\n";
}
output << " endloop\n";
output << " endfacet\n";
}
output << "endsolid OpenSCAD_Model\n";
setlocale(LC_NUMERIC, ""); // Set default locale
@ -227,13 +246,13 @@ static void export_stl(const CGAL_Polyhedron &P, std::ostream &output)
void export_stl(const CGAL_Nef_polyhedron *root_N, std::ostream &output)
{
if (!root_N->p3->is_simple()) {
PRINT("Object isn't a valid 2-manifold! Modify your design.\n");
PRINT("Warning: Exported object may not be a valid 2-manifold and may need repair");
}
bool usePolySet = false;
bool usePolySet = true;
if (usePolySet) {
PolySet ps(3);
bool err = createPolySetFromNefPolyhedron3(*(root_N->p3), ps);
bool err = CGALUtils::createPolySetFromNefPolyhedron3(*(root_N->p3), ps);
if (err) { PRINT("ERROR: Nef->PolySet failed"); }
else {
export_stl(ps, output);
@ -264,7 +283,7 @@ void export_stl(const CGAL_Nef_polyhedron *root_N, std::ostream &output)
void export_off(const class PolySet &ps, std::ostream &output)
{
// FIXME: Implement this without creating a Nef polyhedron
CGAL_Nef_polyhedron *N = createNefPolyhedronFromGeometry(ps);
CGAL_Nef_polyhedron *N = CGALUtils::createNefPolyhedronFromGeometry(ps);
export_off(N, output);
delete N;
}
@ -290,7 +309,7 @@ void export_off(const CGAL_Nef_polyhedron *root_N, std::ostream &output)
void export_amf(const class PolySet &ps, std::ostream &output)
{
// FIXME: Implement this without creating a Nef polyhedron
CGAL_Nef_polyhedron *N = createNefPolyhedronFromGeometry(ps);
CGAL_Nef_polyhedron *N = CGALUtils::createNefPolyhedronFromGeometry(ps);
export_amf(N, output);
delete N;
}

View File

@ -3,6 +3,7 @@
#include <iostream>
#include "Tree.h"
#include "Camera.h"
#include "memory.h"
#ifdef ENABLE_CGAL
@ -17,7 +18,7 @@ enum FileFormat {
// void exportFile(const class Geometry *root_geom, std::ostream &output, FileFormat format);
void exportFileByName(const class Geometry *root_geom, FileFormat format,
const char *name2open, const char *name2display);
void export_png(const class Geometry *root_geom, Camera &c, std::ostream &output);
void export_png(shared_ptr<const class Geometry> root_geom, Camera &c, std::ostream &output);
void export_stl(const class CGAL_Nef_polyhedron *root_N, std::ostream &output);
void export_stl(const class PolySet &ps, std::ostream &output);

View File

@ -8,7 +8,6 @@
#ifdef ENABLE_CGAL
#include "CGALRenderer.h"
#include "CGAL_renderer.h"
#include "cgal.h"
#include "cgalutils.h"
#include "CGAL_Nef_polyhedron.h"
@ -20,7 +19,7 @@ static void setupCamera(Camera &cam, const BoundingBox &bbox, float scalefactor)
if (cam.viewall) cam.viewAll(bbox, scalefactor);
}
void export_png(const Geometry *root_geom, Camera &cam, std::ostream &output)
void export_png(shared_ptr<const Geometry> root_geom, Camera &cam, std::ostream &output)
{
PRINTD("export_png geom");
OffscreenView *glview;
@ -30,14 +29,14 @@ void export_png(const Geometry *root_geom, Camera &cam, std::ostream &output)
fprintf(stderr,"Can't create OpenGL OffscreenView. Code: %i.\n", error);
return;
}
shared_ptr<const Geometry> ptr(root_geom);
CGALRenderer cgalRenderer(ptr);
CGALRenderer cgalRenderer(root_geom);
BoundingBox bbox = cgalRenderer.getBoundingBox();
setupCamera(cam, bbox, 3);
glview->setCamera(cam);
glview->setRenderer(&cgalRenderer);
glview->setColorScheme(RenderSettings::inst()->colorscheme);
glview->paintGL();
glview->save(output);
}
@ -85,6 +84,7 @@ void export_png_preview_common(Tree &tree, Camera &cam, std::ostream &output, Pr
OpenCSG::setContext(0);
OpenCSG::setOption(OpenCSG::OffscreenSetting, OpenCSG::FrameBufferObject);
#endif
csgInfo.glview->setColorScheme(RenderSettings::inst()->colorscheme);
csgInfo.glview->paintGL();
csgInfo.glview->save(output);
}

View File

@ -527,6 +527,17 @@ Value builtin_str(const Context *, const EvalContext *evalctx)
return Value(stream.str());
}
Value builtin_chr(const Context *, const EvalContext *evalctx)
{
std::stringstream stream;
for (size_t i = 0; i < evalctx->numArgs(); i++) {
const Value v = evalctx->getArgValue(i);
stream << v.chrString();
}
return Value(stream.str());
}
Value builtin_concat(const Context *, const EvalContext *evalctx)
{
Value::VectorType result;
@ -928,6 +939,7 @@ void register_builtin_functions()
Builtins::init("log", new BuiltinFunction(&builtin_log));
Builtins::init("ln", new BuiltinFunction(&builtin_ln));
Builtins::init("str", new BuiltinFunction(&builtin_str));
Builtins::init("chr", new BuiltinFunction(&builtin_chr));
Builtins::init("concat", new BuiltinFunction(&builtin_concat));
Builtins::init("lookup", new BuiltinFunction(&builtin_lookup));
Builtins::init("search", new BuiltinFunction(&builtin_search));

View File

@ -287,7 +287,7 @@ Geometry *ImportNode::createGeometry() const
else {
file >> poly;
file.close();
bool err = createPolySetFromPolyhedron(poly, *p);
bool err = CGALUtils::createPolySetFromPolyhedron(poly, *p);
}
#else
PRINT("WARNING: OFF import requires CGAL.");

267
src/legacyeditor.cc Normal file
View File

@ -0,0 +1,267 @@
#include "legacyeditor.h"
#include "Preferences.h"
#include "highlighter.h"
LegacyEditor::LegacyEditor(QWidget *parent) : EditorInterface(parent)
{
QVBoxLayout *legacyeditorLayout = new QVBoxLayout(this);
legacyeditorLayout->setContentsMargins(0, 0, 0, 0);
this->textedit = new QTextEdit(this);
legacyeditorLayout->addWidget(this->textedit);
this->textedit->setAcceptRichText(false);
// This needed to avoid the editor accepting filename drops as we want
// to handle these ourselves in MainWindow
this->textedit->setAcceptDrops(false);
this->textedit->setWordWrapMode(QTextOption::WrapAnywhere);
this->textedit->setTabStopWidth(30);
this->highlighter = new Highlighter(this->textedit->document());
connect(this->textedit, SIGNAL(textChanged()), this, SIGNAL(contentsChanged()));
connect(this->textedit->document(), SIGNAL(modificationChanged(bool)), this, SIGNAL(modificationChanged(bool)));
}
void LegacyEditor::indentSelection()
{
QTextCursor cursor = textedit->textCursor();
int p1 = cursor.selectionStart();
QString txt = cursor.selectedText();
txt.replace(QString(QChar(8233)), QString(QChar(8233)) + QString("\t"));
if (txt.endsWith(QString(QChar(8233)) + QString("\t")))
txt.chop(1);
txt = QString("\t") + txt;
cursor.insertText(txt);
int p2 = cursor.position();
cursor.setPosition(p1, QTextCursor::MoveAnchor);
cursor.setPosition(p2, QTextCursor::KeepAnchor);
textedit->setTextCursor(cursor);
}
void LegacyEditor::unindentSelection()
{
QTextCursor cursor = textedit->textCursor();
int p1 = cursor.selectionStart();
QString txt = cursor.selectedText();
txt.replace(QString(QChar(8233)) + QString("\t"), QString(QChar(8233)));
if (txt.startsWith(QString("\t")))
txt.remove(0, 1);
cursor.insertText(txt);
int p2 = cursor.position();
cursor.setPosition(p1, QTextCursor::MoveAnchor);
cursor.setPosition(p2, QTextCursor::KeepAnchor);
textedit->setTextCursor(cursor);
}
void LegacyEditor::commentSelection()
{
QTextCursor cursor = textedit->textCursor();
int p1 = cursor.selectionStart();
QString txt = cursor.selectedText();
txt.replace(QString(QChar(8233)), QString(QChar(8233)) + QString("//"));
if (txt.endsWith(QString(QChar(8233)) + QString("//")))
txt.chop(2);
txt = QString("//") + txt;
cursor.insertText(txt);
int p2 = cursor.position();
cursor.setPosition(p1, QTextCursor::MoveAnchor);
cursor.setPosition(p2, QTextCursor::KeepAnchor);
textedit->setTextCursor(cursor);
}
void LegacyEditor::uncommentSelection()
{
QTextCursor cursor = textedit->textCursor();
int p1 = cursor.selectionStart();
QString txt = cursor.selectedText();
txt.replace(QString(QChar(8233)) + QString("//"), QString(QChar(8233)));
if (txt.startsWith(QString("//")))
txt.remove(0, 2);
cursor.insertText(txt);
int p2 = cursor.position();
cursor.setPosition(p1, QTextCursor::MoveAnchor);
cursor.setPosition(p2, QTextCursor::KeepAnchor);
textedit->setTextCursor(cursor);
}
void LegacyEditor::zoomIn()
{
// See also QT's implementation in QLegacyEditor.cpp
QSettings settings;
QFont tmp_font = this->font() ;
if (font().pointSize() >= 1)
tmp_font.setPointSize(1 + font().pointSize());
else
tmp_font.setPointSize(1);
settings.setValue("editor/fontsize", tmp_font.pointSize());
this->setFont(tmp_font);
}
void LegacyEditor::zoomOut()
{
QSettings settings;
QFont tmp_font = this->font();
if (font().pointSize() >= 2)
tmp_font.setPointSize(-1 + font().pointSize());
else
tmp_font.setPointSize(1);
settings.setValue("editor/fontsize", tmp_font.pointSize());
this->setFont(tmp_font);
}
void LegacyEditor::setPlainText(const QString &text)
{
int y = textedit->verticalScrollBar()->sliderPosition();
// Save current cursor position
QTextCursor cursor = textedit->textCursor();
int n = cursor.position();
textedit->setPlainText(text);
// Restore cursor position
if (n < text.length()) {
cursor.setPosition(n);
textedit->setTextCursor(cursor);
textedit->verticalScrollBar()->setSliderPosition(y);
}
}
void LegacyEditor::highlightError(int error_pos)
{
highlighter->highlightError(error_pos);
QTextCursor cursor = this->textedit->textCursor();
cursor.setPosition(error_pos);
this->textedit->setTextCursor(cursor);
}
void LegacyEditor::unhighlightLastError()
{
highlighter->unhighlightLastError();
}
void LegacyEditor::setHighlightScheme(const QString &name)
{
highlighter->assignFormatsToTokens(name);
highlighter->rehighlight(); // slow on large files
}
QSize LegacyEditor::sizeHint() const
{
if (initialSizeHint.width() <= 0) {
return textedit->sizeHint();
} else {
return initialSizeHint;
}
}
void LegacyEditor::setInitialSizeHint(const QSize &size)
{
initialSizeHint = size;
}
QString LegacyEditor::toPlainText()
{
return textedit->toPlainText();
}
void LegacyEditor::insert(const QString &text)
{
textedit->insertPlainText(text);
}
void LegacyEditor::undo()
{
textedit->undo();
}
void LegacyEditor::redo()
{
textedit->redo();
}
void LegacyEditor::cut()
{
textedit->cut();
}
void LegacyEditor::copy()
{
textedit->copy();
}
void LegacyEditor::paste()
{
textedit->paste();
}
LegacyEditor::~LegacyEditor()
{
delete highlighter;
}
void LegacyEditor::replaceSelectedText(const QString &newText)
{
QTextCursor cursor = this->textedit->textCursor();
if (cursor.selectedText() != newText) {
cursor.insertText(newText);
}
}
bool LegacyEditor::findString(const QString & exp, bool findBackwards) const
{
return textedit->find(exp, findBackwards ? QTextDocument::FindBackward : QTextDocument::FindFlags(0));
}
bool LegacyEditor::find(const QString &newText, bool findNext, bool findBackwards)
{
bool success = this->findString(newText, findBackwards);
if (!success) { // Implement wrap-around search behavior
QTextCursor old_cursor = this->textedit->textCursor();
QTextCursor tmp_cursor = old_cursor;
tmp_cursor.movePosition(findBackwards ? QTextCursor::End : QTextCursor::Start);
this->textedit->setTextCursor(tmp_cursor);
bool success = this->findString(newText, findBackwards);
if (!success) {
this->textedit->setTextCursor(old_cursor);
}
return success;
}
return true;
}
void LegacyEditor::initFont(const QString& family, uint size)
{
QFont font;
if (!family.isEmpty()) font.setFamily(family);
else font.setFixedPitch(true);
if (size > 0) font.setPointSize(size);
font.setStyleHint(QFont::TypeWriter);
this->setFont(font);
}
QString LegacyEditor::selectedText()
{
return textedit->textCursor().selectedText();
}
void LegacyEditor::setContentModified(bool y)
{
textedit->document()->setModified(y);
}
bool LegacyEditor::isContentModified()
{
return textedit->document()->isModified();
}

43
src/legacyeditor.h Normal file
View File

@ -0,0 +1,43 @@
#pragma once
#include "editor.h"
class LegacyEditor : public EditorInterface
{
Q_OBJECT
public:
LegacyEditor(class QWidget *parent);
virtual ~LegacyEditor();
QSize sizeHint() const;
void setInitialSizeHint(const QSize&);
QString toPlainText();
QString selectedText();
bool find(const QString &, bool findNext = false, bool findBackwards = false);
void replaceSelectedText(const QString &newText);
bool findString(const QString & exp, bool findBackwards) const;
public slots:
void zoomIn();
void zoomOut();
void setContentModified(bool);
bool isContentModified();
void indentSelection();
void unindentSelection();
void commentSelection();
void uncommentSelection();
void setPlainText(const QString&);
void highlightError(int);
void unhighlightLastError();
void setHighlightScheme(const QString&);
void insert(const QString&);
void undo();
void redo();
void cut();
void copy();
void paste();
void initFont(const QString&, uint);
private:
class QTextEdit *textedit;
class Highlighter *highlighter;
QSize initialSizeHint;
};

View File

@ -3,7 +3,7 @@
#include <Eigen/Core>
#include <Eigen/Geometry>
#include <Eigen/Dense>
#include<Eigen/StdVector>
#include <Eigen/StdVector>
EIGEN_DEFINE_STL_VECTOR_SPECIALIZATION(Eigen::Vector2d)
using Eigen::Vector2d;

View File

@ -27,6 +27,7 @@
#include "ModuleCache.h"
#include "MainWindow.h"
#include "parsersettings.h"
#include "rendersettings.h"
#include "Preferences.h"
#include "printutils.h"
#include "node.h"
@ -38,6 +39,10 @@
#include "expression.h"
#include "progress.h"
#include "dxfdim.h"
#include "legacyeditor.h"
#ifdef USE_SCINTILLA_EDITOR
#include "scintillaeditor.h"
#endif
#include "AboutDialog.h"
#include "FontListDialog.h"
#ifdef ENABLE_OPENCSG
@ -165,6 +170,19 @@ MainWindow::MainWindow(const QString &filename)
{
setupUi(this);
editortype = Preferences::inst()->getValue("editor/editortype").toString();
useScintilla = (editortype == "QScintilla Editor");
#ifdef USE_SCINTILLA_EDITOR
if (useScintilla) {
editor = new ScintillaEditor(editorDockContents);
}
else
#endif
editor = new LegacyEditor(editorDockContents);
editorDockContents->layout()->addWidget(editor);
setCorner(Qt::TopLeftCorner, Qt::LeftDockWidgetArea);
setCorner(Qt::TopRightCorner, Qt::RightDockWidgetArea);
setCorner(Qt::BottomLeftCorner, Qt::LeftDockWidgetArea);
@ -218,8 +236,6 @@ MainWindow::MainWindow(const QString &filename)
connect(this, SIGNAL(highlightError(int)), editor, SLOT(highlightError(int)));
connect(this, SIGNAL(unhighlightLastError()), editor, SLOT(unhighlightLastError()));
editor->setTabStopWidth(30);
editor->setLineWrapping(true); // Not designable
this->qglview->statusLabel = new QLabel(this);
statusBar()->addWidget(this->qglview->statusLabel);
@ -328,7 +344,6 @@ MainWindow::MainWindow(const QString &filename)
connect(this->editActionFindAndReplace, SIGNAL(triggered()), this, SLOT(findAndReplace()));
connect(this->editActionFindNext, SIGNAL(triggered()), this, SLOT(findNext()));
connect(this->editActionFindPrevious, SIGNAL(triggered()), this, SLOT(findPrev()));
connect(this->editActionUseSelectionForFind, SIGNAL(triggered()), this, SLOT(useSelectionForFind()));
// Design menu
connect(this->designActionAutoReload, SIGNAL(toggled(bool)), this, SLOT(autoReloadSet(bool)));
@ -410,22 +425,29 @@ MainWindow::MainWindow(const QString &filename)
}
updateRecentFileActions();
connect(editor->document(), SIGNAL(contentsChanged()), this, SLOT(animateUpdateDocChanged()));
connect(editor->document(), SIGNAL(modificationChanged(bool)), this, SLOT(setWindowModified(bool)));
connect(editor, SIGNAL(contentsChanged()), this, SLOT(animateUpdateDocChanged()));
connect(editor, SIGNAL(modificationChanged(bool)), this, SLOT(setWindowModified(bool)));
connect(this->qglview, SIGNAL(doAnimateUpdate()), this, SLOT(animateUpdate()));
connect(Preferences::inst(), SIGNAL(requestRedraw()), this->qglview, SLOT(updateGL()));
connect(Preferences::inst(), SIGNAL(updateMdiMode(bool)), this, SLOT(updateMdiMode(bool)));
connect(Preferences::inst(), SIGNAL(updateUndockMode(bool)), this, SLOT(updateUndockMode(bool)));
connect(Preferences::inst(), SIGNAL(fontChanged(const QString&,uint)),
this, SLOT(setFont(const QString&,uint)));
editor, SLOT(initFont(const QString&,uint)));
connect(Preferences::inst(), SIGNAL(openCSGSettingsChanged()),
this, SLOT(openCSGSettingsChanged()));
connect(Preferences::inst(), SIGNAL(syntaxHighlightChanged(const QString&)),
editor, SLOT(setHighlightScheme(const QString&)));
connect(Preferences::inst(), SIGNAL(colorSchemeChanged(const QString&)),
this, SLOT(setColorScheme(const QString&)));
Preferences::inst()->apply();
QString cs = Preferences::inst()->getValue("3dview/colorscheme").toString();
this->setColorScheme(cs);
//find and replace panel
connect(this->findTypeComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(selectFindType(int)));
connect(this->findInputField, SIGNAL(textChanged(QString)), this, SLOT(findString(QString)));
connect(this->findInputField, SIGNAL(returnPressed()), this->nextButton, SLOT(animateClick()));
find_panel->installEventFilter(this);
@ -478,8 +500,7 @@ MainWindow::MainWindow(const QString &filename)
clearCurrentOutput();
}
void
MainWindow::loadViewSettings(){
void MainWindow::loadViewSettings(){
QSettings settings;
if (settings.value("view/showEdges").toBool()) {
viewActionShowEdges->setChecked(true);
@ -506,8 +527,7 @@ MainWindow::loadViewSettings(){
updateUndockMode(settings.value("advanced/undockableWindows").toBool());
}
void
MainWindow::loadDesignSettings()
void MainWindow::loadDesignSettings()
{
QSettings settings;
if (settings.value("design/autoReload").toBool()) {
@ -599,8 +619,8 @@ void MainWindow::requestOpenFile(const QString &filename)
one is not empty. Otherwise the current window content is overwritten.
Any check whether to replace the content have to be made before.
*/
void
MainWindow::openFile(const QString &new_filename)
void MainWindow::openFile(const QString &new_filename)
{
if (MainWindow::mdiMode) {
if (!editor->toPlainText().isEmpty()) {
@ -630,8 +650,7 @@ MainWindow::openFile(const QString &new_filename)
clearCurrentOutput();
}
void
MainWindow::setFileName(const QString &filename)
void MainWindow::setFileName(const QString &filename)
{
if (filename.isEmpty()) {
this->fileName.clear();
@ -1287,16 +1306,16 @@ void MainWindow::actionSaveAs()
void MainWindow::actionShowLibraryFolder()
{
std::string path = PlatformUtils::libraryPath();
std::string path = PlatformUtils::userLibraryPath();
if (!fs::exists(path)) {
PRINTB("WARNING: Library path %s doesnt exist. Creating", path);
if (!PlatformUtils::createLibraryPath()) {
if (!PlatformUtils::createUserLibraryPath()) {
PRINTB("ERROR: Cannot create library path: %s",path);
}
}
QString url = QString::fromStdString( path );
QString url = QString::fromStdString(path);
//PRINTB("Opening file browser for %s", url.toStdString() );
QDesktopServices::openUrl(QUrl::fromLocalFile( url ));
QDesktopServices::openUrl(QUrl::fromLocalFile(url));
}
void MainWindow::actionReload()
@ -1309,22 +1328,19 @@ void MainWindow::actionReload()
void MainWindow::pasteViewportTranslation()
{
QTextCursor cursor = editor->textCursor();
QString txt;
txt.sprintf("[ %.2f, %.2f, %.2f ]", -qglview->cam.object_trans.x(),
-qglview->cam.object_trans.y(), -qglview->cam.object_trans.z());
cursor.insertText(txt);
txt.sprintf("[ %.2f, %.2f, %.2f ]", -qglview->cam.object_trans.x(), -qglview->cam.object_trans.y(), -qglview->cam.object_trans.z());
this->editor->insert(txt);
}
void MainWindow::pasteViewportRotation()
{
QTextCursor cursor = editor->textCursor();
QString txt;
txt.sprintf("[ %.2f, %.2f, %.2f ]",
fmodf(360 - qglview->cam.object_rot.x() + 90, 360),
fmodf(360 - qglview->cam.object_rot.y(), 360), fmodf(360 - qglview->cam.object_rot.z(), 360));
cursor.insertText(txt);
fmodf(360 - qglview->cam.object_rot.x() + 90, 360),
fmodf(360 - qglview->cam.object_rot.y(), 360),
fmodf(360 - qglview->cam.object_rot.z(), 360));
this->editor->insert(txt);
}
void MainWindow::find()
@ -1334,10 +1350,16 @@ void MainWindow::find()
replaceButton->hide();
replaceAllButton->hide();
find_panel->show();
findInputField->setText(editor->selectedText());
findInputField->setFocus();
findInputField->selectAll();
}
void MainWindow::findString(QString textToFind)
{
editor->find(textToFind, false, false);
}
void MainWindow::findAndReplace()
{
findTypeComboBox->setCurrentIndex(1);
@ -1354,55 +1376,25 @@ void MainWindow::selectFindType(int type) {
if (type == 1) findAndReplace();
}
bool MainWindow::findOperation(QTextDocument::FindFlags options) {
bool success = editor->find(findInputField->text(), options);
if (!success) { // Implement wrap-around search behavior
QTextCursor old_cursor = editor->textCursor();
QTextCursor tmp_cursor = old_cursor;
tmp_cursor.movePosition((options & QTextDocument::FindBackward) ? QTextCursor::End : QTextCursor::Start);
editor->setTextCursor(tmp_cursor);
bool success = editor->find(findInputField->text(), options);
if (!success) {
editor->setTextCursor(old_cursor);
}
return success;
}
return true;
}
void MainWindow::replace() {
QTextCursor cursor = editor->textCursor();
QString selectedText = cursor.selectedText();
if (selectedText == findInputField->text()) {
cursor.insertText(replaceInputField->text());
}
findNext();
this->editor->replaceSelectedText(this->replaceInputField->text());
this->editor->find(this->findInputField->text());
}
void MainWindow::replaceAll() {
QTextCursor old_cursor = editor->textCursor();
QTextCursor tmp_cursor = old_cursor;
tmp_cursor.movePosition(QTextCursor::Start);
editor->setTextCursor(tmp_cursor);
while (editor->find(findInputField->text())) {
editor->textCursor().insertText(replaceInputField->text());
while (this->editor->find(this->findInputField->text(), true)) {
this->editor->replaceSelectedText(this->replaceInputField->text());
}
editor->setTextCursor(old_cursor);
}
void MainWindow::findNext()
{
findOperation();
editor->find(this->findInputField->text(), true);
}
void MainWindow::findPrev()
{
findOperation(QTextDocument::FindBackward);
}
void MainWindow::useSelectionForFind()
{
findInputField->setText(editor->textCursor().selectedText());
editor->find(this->findInputField->text(), true, true);
}
bool MainWindow::eventFilter(QObject* obj, QEvent *event)
@ -1542,6 +1534,7 @@ void MainWindow::compileTopLevelDocument()
resetPrintedDeprecations();
this->last_compiled_doc = editor->toPlainText();
std::string fulltext =
std::string(this->last_compiled_doc.toLocal8Bit().constData()) +
"\n" + commandline_commands;
@ -1549,7 +1542,8 @@ void MainWindow::compileTopLevelDocument()
delete this->root_module;
this->root_module = NULL;
this->root_module = parse(fulltext.c_str(), this->fileName.isEmpty() ? "" :
this->root_module = parse(fulltext.c_str(),
this->fileName.isEmpty() ? "" :
QFileInfo(this->fileName).absolutePath().toLocal8Bit(), false);
updateCamera();
@ -1865,13 +1859,17 @@ void MainWindow::actionExport(export_type_e, QString, QString)
return;
}
const CGAL_Nef_polyhedron *N = dynamic_cast<const CGAL_Nef_polyhedron *>(this->root_geom.get());
if (N && !N->p3->is_simple()) {
PRINT("Object isn't a valid 2-manifold! Modify your design. See http://en.wikibooks.org/wiki/OpenSCAD_User_Manual/STL_Import_and_Export");
if (this->root_geom->isEmpty()) {
PRINT("Current top level object is empty.");
clearCurrentOutput();
return;
}
const CGAL_Nef_polyhedron *N = dynamic_cast<const CGAL_Nef_polyhedron *>(this->root_geom.get());
if (N && !N->p3->is_simple()) {
PRINT("Warning: Object may not be a valid 2-manifold and may need repair! See http://en.wikibooks.org/wiki/OpenSCAD_User_Manual/STL_Import_and_Export");
}
QString title = QString("Export %1 File").arg(type_name);
QString filter = QString("%1 Files (*%2)").arg(type_name, suffix);
QString filename = this->fileName.isEmpty() ? QString("Untitled") + suffix : QFileInfo(this->fileName).baseName() + suffix;
@ -1983,15 +1981,16 @@ void MainWindow::actionExportCSG()
}
QString csg_filename = QFileDialog::getSaveFileName(this, "Export CSG File",
this->fileName.isEmpty() ? "Untitled.csg" : QFileInfo(this->fileName).baseName()+".csg", "CSG Files (*.csg)");
this->fileName.isEmpty() ? "Untitled.csg" : QFileInfo(this->fileName).baseName()+".csg",
"CSG Files (*.csg)");
if (csg_filename.isEmpty()) {
PRINT("No filename specified. CSG export aborted.");
clearCurrentOutput();
return;
}
std::ofstream fstream(csg_filename.toUtf8());
std::ofstream fstream(csg_filename.toLocal8Bit());
if (!fstream.is_open()) {
PRINTB("Can't open file \"%s\" for export", csg_filename.toLocal8Bit().constData());
}
@ -2052,9 +2051,8 @@ void MainWindow::viewModePreview()
if (this->qglview->hasOpenCSGSupport()) {
viewModeActionsUncheck();
viewActionPreview->setChecked(true);
this->qglview->setRenderer(this->opencsgRenderer ? (Renderer *)this->opencsgRenderer :
(Renderer *)this->thrownTogetherRenderer);
this->qglview->setRenderer(this->opencsgRenderer ? (Renderer *)this->opencsgRenderer : (Renderer *)this->thrownTogetherRenderer);
this->qglview->updateColorScheme();
this->qglview->updateGL();
} else {
viewModeThrownTogether();
@ -2071,6 +2069,7 @@ void MainWindow::viewModeSurface()
viewActionSurfaces->setChecked(true);
this->qglview->setShowFaces(true);
this->qglview->setRenderer(this->cgalRenderer);
this->qglview->updateColorScheme();
this->qglview->updateGL();
}
@ -2080,6 +2079,7 @@ void MainWindow::viewModeWireframe()
viewActionWireframe->setChecked(true);
this->qglview->setShowFaces(false);
this->qglview->setRenderer(this->cgalRenderer);
this->qglview->updateColorScheme();
this->qglview->updateGL();
}
@ -2090,6 +2090,7 @@ void MainWindow::viewModeThrownTogether()
viewModeActionsUncheck();
viewActionThrownTogether->setChecked(true);
this->qglview->setRenderer(this->thrownTogetherRenderer);
this->qglview->updateColorScheme();
this->qglview->updateGL();
}
@ -2131,7 +2132,7 @@ void MainWindow::viewModeAnimate()
void MainWindow::animateUpdateDocChanged()
{
QString current_doc = editor->toPlainText();
QString current_doc = editor->toPlainText();
if (current_doc != last_compiled_doc)
animateUpdate();
}
@ -2320,7 +2321,7 @@ void MainWindow::handleFileDrop(const QString &filename)
}
openFile(filename);
} else {
editor->insertPlainText(cmd.arg(filename));
editor->insert(cmd.arg(filename));
}
}
@ -2424,6 +2425,13 @@ void MainWindow::preferences()
Preferences::inst()->raise();
}
void MainWindow::setColorScheme(const QString &scheme)
{
RenderSettings::inst()->colorscheme = scheme.toStdString();
this->qglview->setColorScheme(scheme.toStdString());
this->qglview->updateGL();
}
void MainWindow::setFont(const QString &family, uint size)
{
QFont font;
@ -2452,7 +2460,6 @@ void MainWindow::consoleOutput(const std::string &msg, void *userdata)
MainWindow *thisp = static_cast<MainWindow*>(userdata);
QMetaObject::invokeMethod(thisp->console, "append", Qt::QueuedConnection,
Q_ARG(QString, QString::fromLocal8Bit(msg.c_str())));
if (thisp->procevents) QApplication::processEvents();
}

View File

@ -47,6 +47,7 @@
#ifdef ENABLE_CGAL
#include "CGAL_Nef_polyhedron.h"
#include "cgalutils.h"
#endif
#include "csgterm.h"
@ -75,12 +76,13 @@
namespace po = boost::program_options;
namespace fs = boost::filesystem;
namespace Render { enum type { CGAL, OPENCSG, THROWNTOGETHER }; };
namespace Render { enum type { GEOMETRY, CGAL, OPENCSG, THROWNTOGETHER }; };
std::string commandline_commands;
std::string currentdir;
using std::string;
using std::vector;
using boost::lexical_cast;
using boost::bad_lexical_cast;
using boost::is_any_of;
class Echostream : public std::ofstream
@ -114,6 +116,7 @@ static void help(const char *progname)
"%2%[ --viewall ] \\\n"
"%2%[ --imgsize=width,height ] [ --projection=(o)rtho|(p)ersp] \\\n"
"%2%[ --render | --preview[=throwntogether] ] \\\n"
"%2%[ --colorscheme=[Cornfield|Sunset|Metallic|Starnight|BeforeDawn|Nature|DeepOcean] ] \\\n"
"%2%[ --csglimit=num ]"
#ifdef ENABLE_EXPERIMENTAL
" [ --enable=<feature> ]"
@ -152,7 +155,7 @@ static void info()
exit(0);
}
Camera get_camera( po::variables_map vm )
Camera get_camera(po::variables_map vm)
{
Camera camera;
@ -161,12 +164,16 @@ Camera get_camera( po::variables_map vm )
vector<double> cam_parameters;
split(strs, vm["camera"].as<string>(), is_any_of(","));
if ( strs.size()==6 || strs.size()==7 ) {
BOOST_FOREACH(string &s, strs)
cam_parameters.push_back(lexical_cast<double>(s));
camera.setup( cam_parameters );
try {
BOOST_FOREACH(string &s, strs) cam_parameters.push_back(lexical_cast<double>(s));
camera.setup(cam_parameters);
}
catch (bad_lexical_cast &) {
PRINT("Camera setup requires numbers as parameters");
}
} else {
PRINT("Camera setup requires either 7 numbers for Gimbal Camera\n");
PRINT("or 6 numbers for Vector Camera\n");
PRINT("Camera setup requires either 7 numbers for Gimbal Camera");
PRINT("or 6 numbers for Vector Camera");
exit(1);
}
}
@ -201,11 +208,16 @@ Camera get_camera( po::variables_map vm )
vector<string> strs;
split(strs, vm["imgsize"].as<string>(), is_any_of(","));
if ( strs.size() != 2 ) {
PRINT("Need 2 numbers for imgsize\n");
PRINT("Need 2 numbers for imgsize");
exit(1);
} else {
w = lexical_cast<int>( strs[0] );
h = lexical_cast<int>( strs[1] );
try {
w = lexical_cast<int>(strs[0]);
h = lexical_cast<int>(strs[1]);
}
catch (bad_lexical_cast &) {
PRINT("Need 2 numbers for imgsize");
}
}
}
camera.pixel_width = w;
@ -228,6 +240,10 @@ static bool checkAndExport(shared_ptr<const Geometry> root_geom, unsigned nd,
PRINTB("Current top level object is not a %dD object.", nd);
return false;
}
if (root_geom->isEmpty()) {
PRINT("Current top level object is empty.");
return false;
}
exportFileByName(root_geom.get(), format, filename, filename);
return true;
}
@ -239,8 +255,9 @@ int cmdline(const char *deps_output_file, const std::string &filename, Camera &c
const std::string application_path = QApplication::instance()->applicationDirPath().toLocal8Bit().constData();
#else
const std::string application_path = boosty::stringy(boosty::absolute(boost::filesystem::path(argv[0]).parent_path()));
#endif
parser_init(application_path);
#endif
PlatformUtils::registerApplicationPath(application_path);
parser_init(PlatformUtils::applicationPath());
Tree tree;
#ifdef ENABLE_CGAL
GeometryEvaluator geomevaluator(tree);
@ -369,15 +386,22 @@ int cmdline(const char *deps_output_file, const std::string &filename, Camera &c
}
else {
#ifdef ENABLE_CGAL
if ((echo_output_file || png_output_file) && !(renderer==Render::CGAL)) {
// echo or OpenCSG png -> don't necessarily need CGALMesh evaluation
if ((echo_output_file || png_output_file) &&
(renderer==Render::OPENCSG || renderer==Render::THROWNTOGETHER)) {
// echo or OpenCSG png -> don't necessarily need geometry evaluation
} else {
root_geom = geomevaluator.evaluateGeometry(*tree.root(), true);
if (!root_geom) {
PRINT("No top-level object found.");
return 1;
}
const CGAL_Nef_polyhedron *N = dynamic_cast<const CGAL_Nef_polyhedron*>(root_geom.get());
if (renderer == Render::CGAL && root_geom->getDimension() == 3) {
const CGAL_Nef_polyhedron *N = dynamic_cast<const CGAL_Nef_polyhedron*>(root_geom.get());
if (!N) {
root_geom.reset(CGALUtils::createNefPolyhedronFromGeometry(*root_geom));
PRINT("Converted to Nef polyhedron");
}
}
}
fs::current_path(original_path);
@ -434,8 +458,8 @@ int cmdline(const char *deps_output_file, const std::string &filename, Camera &c
PRINTB("Can't open file \"%s\" for export", png_output_file);
}
else {
if (renderer==Render::CGAL) {
export_png(root_geom.get(), camera, fstream);
if (renderer==Render::CGAL || renderer==Render::GEOMETRY) {
export_png(root_geom, camera, fstream);
} else if (renderer==Render::THROWNTOGETHER) {
export_png_with_throwntogether(tree, camera, fstream);
} else {
@ -523,28 +547,12 @@ int gui(vector<string> &inputFiles, const fs::path &original_path, int argc, cha
qRegisterMetaType<shared_ptr<const Geometry> >();
const QString &app_path = app.applicationDirPath();
PlatformUtils::registerApplicationPath(app_path.toLocal8Bit().constData());
QDir exdir(app_path);
QString qexamplesdir;
#ifdef Q_OS_MAC
exdir.cd("../Resources"); // Examples can be bundled
if (!exdir.exists("examples")) exdir.cd("../../..");
#elif defined(Q_OS_UNIX)
if (exdir.cd("../share/openscad/examples")) {
qexamplesdir = exdir.path();
} else
if (exdir.cd("../../share/openscad/examples")) {
qexamplesdir = exdir.path();
} else
if (exdir.cd("../../examples")) {
qexamplesdir = exdir.path();
} else
#endif
if (exdir.cd("examples")) {
qexamplesdir = exdir.path();
}
MainWindow::setExamplesDir(qexamplesdir);
parser_init(app_path.toLocal8Bit().constData());
QDir exdir(QString::fromStdString(PlatformUtils::resourcesPath()));
exdir.cd("examples");
MainWindow::setExamplesDir(exdir.path());
parser_init(PlatformUtils::applicationPath());
#ifdef Q_OS_MAC
installAppleEventHandlers();
@ -624,14 +632,15 @@ int main(int argc, char **argv)
("help,h", "help message")
("version,v", "print the version")
("info", "print information about the building process")
("render", "if exporting a png image, do a full CGAL render")
("preview", po::value<string>(), "if exporting a png image, do an OpenCSG(default) or ThrownTogether preview")
("render", po::value<string>()->implicit_value(""), "if exporting a png image, do a full geometry evaluation")
("preview", po::value<string>()->implicit_value(""), "if exporting a png image, do an OpenCSG(default) or ThrownTogether preview")
("csglimit", po::value<unsigned int>(), "if exporting a png image, stop rendering at the given number of CSG elements")
("camera", po::value<string>(), "parameters for camera when exporting png")
("autocenter", "adjust camera to look at object center")
("viewall", "adjust camera to fit object")
("imgsize", po::value<string>(), "=width,height for exporting png")
("projection", po::value<string>(), "(o)rtho or (p)erspective when exporting png")
("colorscheme", po::value<string>(), "colorscheme")
("debug", po::value<string>(), "special debug info")
("o,o", po::value<string>(), "out-file")
("s,s", po::value<string>(), "stl-file")
@ -673,11 +682,14 @@ int main(int argc, char **argv)
if (vm.count("info")) info();
Render::type renderer = Render::OPENCSG;
if (vm.count("render"))
renderer = Render::CGAL;
if (vm.count("preview"))
if (vm.count("preview")) {
if (vm["preview"].as<string>() == "throwntogether")
renderer = Render::THROWNTOGETHER;
}
else if (vm.count("render")) {
if (vm["render"].as<string>() == "cgal") renderer = Render::CGAL;
else renderer = Render::GEOMETRY;
}
if (vm.count("csglimit")) {
RenderSettings::inst()->openCSGTermLimit = vm["csglimit"].as<unsigned int>();
@ -732,6 +744,19 @@ int main(int argc, char **argv)
}
#endif
if (vm.count("colorscheme")) {
std::string colorscheme = vm["colorscheme"].as<string>();
if (ColorMap::inst()->findColorScheme(colorscheme)) {
RenderSettings::inst()->colorscheme = colorscheme;
} else {
PRINT("Unknown color scheme. Valid schemes:");
BOOST_FOREACH (const std::string &name, ColorMap::inst()->colorSchemeNames()) {
PRINT(name);
}
exit(1);
}
}
currentdir = boosty::stringy(fs::current_path());
Camera camera = get_camera(vm);

View File

@ -102,37 +102,9 @@ void parser_init(const std::string &applicationpath)
}
}
// This is the built-in user-writable library path
#ifndef OPENSCAD_TESTING
// This will resolve to ~/Documents on Mac, "My Documents" on Windows and
// ~/.local/share on Linux
fs::path docdir(PlatformUtils::documentsPath());
add_librarydir(boosty::stringy(docdir / "OpenSCAD" / "libraries"));
add_librarydir(PlatformUtils::userLibraryPath());
#endif
// This is the built-in read-only library path
std::string librarydir;
fs::path libdir(applicationpath);
fs::path tmpdir;
#ifdef __APPLE__
// Libraries can be bundled on Mac. If not, fall back to development layout
bool isbundle = is_directory(libdir / ".." / "Resources");
if (isbundle) {
libdir /= "../Resources";
if (!is_directory(libdir / "libraries")) libdir /= "../../..";
}
#elif !defined(WIN32)
if (is_directory(tmpdir = libdir / "../share/openscad/libraries")) {
librarydir = boosty::stringy(tmpdir);
} else if (is_directory(tmpdir = libdir / "../../share/openscad/libraries")) {
librarydir = boosty::stringy(tmpdir);
} else if (is_directory(tmpdir = libdir / "../../libraries")) {
librarydir = boosty::stringy(tmpdir);
} else
#endif
if (is_directory(tmpdir = libdir / "libraries")) {
librarydir = boosty::stringy(tmpdir);
}
if (!librarydir.empty()) add_librarydir(librarydir);
add_librarydir(boosty::absolute(fs::path(PlatformUtils::resourcesPath()) / "libraries").string());
}

View File

@ -213,15 +213,16 @@ namespace PolysetUtils {
polyset has simple polygon faces with no holes, no self intersections, no
duplicate points, and proper orientation. */
void tessellate_faces(const PolySet &inps, PolySet &outps) {
int degeneratePolygons = 0;
for (size_t i = 0; i < inps.polygons.size(); i++) {
const PolySet::Polygon pgon = inps.polygons[i];
if (pgon.size()<3) {
PRINT("WARNING: PolySet has polygon with <3 points");
if (pgon.size() < 3) {
degeneratePolygons++;
continue;
}
projection_t goodproj = find_good_projection( pgon );
if (goodproj==NONE) {
PRINT("WARNING: PolySet has degenerate polygon");
degeneratePolygons++;
continue;
}
std::vector<PolySet::Polygon> triangles;
@ -234,6 +235,7 @@ namespace PolysetUtils {
outps.append_vertex(t[2].x(),t[2].y(),t[2].z());
}
}
if (degeneratePolygons > 0) PRINT("WARNING: PolySet has degenerate polygons");
}
}

View File

@ -239,6 +239,7 @@ static void gl_draw_triangle(GLint *shaderinfo, const Vector3d &p0, const Vector
void PolySet::render_surface(Renderer::csgmode_e csgmode, const Transform3d &m, GLint *shaderinfo) const
{
PRINTD("Polyset render");
bool mirrored = m.matrix().determinant() < 0;
#ifdef ENABLE_OPENCSG
if (shaderinfo) {

View File

@ -243,7 +243,7 @@ AbstractNode *PrimitiveModule::instantiate(const Context *ctx, const ModuleInsta
node->faces = c.lookup_variable("faces");
if (node->faces.type() == Value::UNDEFINED) {
// backwards compatible
node->faces = c.lookup_variable("triangles");
node->faces = c.lookup_variable("triangles", true);
if (node->faces.type() != Value::UNDEFINED) {
printDeprecation("DEPRECATED: polyhedron(triangles=[]) will be removed in future releases. Use polyhedron(faces=[]) instead.");
}

View File

@ -3,47 +3,46 @@
#include "Geometry.h"
#include "polyset.h"
#include "Polygon2d.h"
#include "colormap.h"
#include "printutils.h"
bool Renderer::getColor(Renderer::ColorMode colormode, Color4f &col) const
{
switch (colormode) {
case COLORMODE_NONE:
return false;
break;
case COLORMODE_MATERIAL:
col = RenderSettings::inst()->color(RenderSettings::OPENCSG_FACE_FRONT_COLOR);
break;
case COLORMODE_CUTOUT:
col = RenderSettings::inst()->color(RenderSettings::OPENCSG_FACE_BACK_COLOR);
break;
case COLORMODE_HIGHLIGHT:
col.setRgb(255, 81, 81, 128);
break;
case COLORMODE_BACKGROUND:
col.setRgb(180, 180, 180, 128);
break;
case COLORMODE_MATERIAL_EDGES:
col.setRgb(255, 236, 94);
break;
case COLORMODE_CUTOUT_EDGES:
col.setRgb(171, 216, 86);
break;
case COLORMODE_HIGHLIGHT_EDGES:
col.setRgb(255, 171, 86, 128);
break;
case COLORMODE_BACKGROUND_EDGES:
col.setRgb(150, 150, 150, 128);
break;
default:
return false;
break;
if (colormode==COLORMODE_NONE) return false;
if (colormap.count(colormode) > 0) {
col = colormap.at(colormode);
return true;
}
return true;
return false;
}
Renderer::Renderer() : colorscheme(NULL)
{
PRINTD("Renderer() start");
// Setup default colors
// The main colors, MATERIAL and CUTOUT, come from this object's
// colorscheme. Colorschemes don't currently hold information
// for Highlight/Background colors
// but it wouldn't be too hard to make them do so.
// MATERIAL is set by this object's colorscheme
// CUTOUT is set by this object's colorscheme
colormap[COLORMODE_HIGHLIGHT] = Color4f(255, 81, 81, 128);
colormap[COLORMODE_BACKGROUND] = Color4f(180, 180, 180, 128);
// MATERIAL_EDGES is set by this object's colorscheme
// CUTOUT_EDGES is set by this object's colorscheme
colormap[COLORMODE_HIGHLIGHT_EDGES] = Color4f(255, 171, 86, 128);
colormap[COLORMODE_BACKGROUND_EDGES] = Color4f(150, 150, 150, 128);
setColorScheme(ColorMap::inst()->defaultColorScheme());
PRINTD("Renderer() end");
}
void Renderer::setColor(const float color[4], GLint *shaderinfo) const
{
Color4f col = RenderSettings::inst()->color(RenderSettings::OPENCSG_FACE_FRONT_COLOR);
PRINTD("setColor a");
Color4f col;
getColor(COLORMODE_MATERIAL,col);
float c[4] = {color[0], color[1], color[2], color[3]};
if (c[0] < 0) c[0] = col[0];
if (c[1] < 0) c[1] = col[1];
@ -60,6 +59,7 @@ void Renderer::setColor(const float color[4], GLint *shaderinfo) const
void Renderer::setColor(ColorMode colormode, const float color[4], GLint *shaderinfo) const
{
PRINTD("setColor b");
Color4f basecol;
if (getColor(colormode, basecol)) {
if (colormode == COLORMODE_BACKGROUND) {
@ -80,10 +80,25 @@ void Renderer::setColor(ColorMode colormode, const float color[4], GLint *shader
void Renderer::setColor(ColorMode colormode, GLint *shaderinfo) const
{
PRINTD("setColor c");
float c[4] = {-1,-1,-1,-1};
setColor(colormode, c, shaderinfo);
}
/* fill this->colormap with matching entries from the colorscheme. note
this does not change Highlight or Background colors as they are not
represented in the colorscheme (yet). Also edgecolors are currently the
same for CGAL & OpenCSG */
void Renderer::setColorScheme(const ColorScheme &cs) {
PRINTD("setColorScheme");
colormap[COLORMODE_MATERIAL] = ColorMap::getColor(cs, OPENCSG_FACE_FRONT_COLOR);
colormap[COLORMODE_CUTOUT] = ColorMap::getColor(cs, OPENCSG_FACE_BACK_COLOR);
colormap[COLORMODE_MATERIAL_EDGES] = ColorMap::getColor(cs, CGAL_EDGE_FRONT_COLOR);
colormap[COLORMODE_CUTOUT_EDGES] = ColorMap::getColor(cs, CGAL_EDGE_BACK_COLOR);
colormap[COLORMODE_EMPTY_SPACE] = ColorMap::getColor(cs, BACKGROUND_COLOR);
this->colorscheme = &cs;
}
void Renderer::render_surface(shared_ptr<const Geometry> geom, csgmode_e csgmode, const Transform3d &m, GLint *shaderinfo)
{
shared_ptr<const PolySet> ps;

View File

@ -3,6 +3,7 @@
#include "system-gl.h"
#include "linalg.h"
#include "memory.h"
#include "colormap.h"
#ifdef _MSC_VER // NULL
#include <cstdlib>
@ -11,6 +12,7 @@
class Renderer
{
public:
Renderer();
virtual ~Renderer() {}
virtual void draw(bool showfaces, bool showedges) const = 0;
virtual BoundingBox getBoundingBox() const = 0;
@ -35,14 +37,20 @@ public:
COLORMODE_MATERIAL_EDGES,
COLORMODE_CUTOUT_EDGES,
COLORMODE_HIGHLIGHT_EDGES,
COLORMODE_BACKGROUND_EDGES
COLORMODE_BACKGROUND_EDGES,
COLORMODE_EMPTY_SPACE
};
virtual bool getColor(ColorMode colormode, Color4f &col) const;
virtual void setColor(const float color[4], GLint *shaderinfo = NULL) const;
virtual void setColor(ColorMode colormode, GLint *shaderinfo = NULL) const;
virtual void setColor(ColorMode colormode, const float color[4], GLint *shaderinfo = NULL) const;
virtual void setColorScheme(const ColorScheme &cs);
static void render_surface(shared_ptr<const class Geometry> geom, csgmode_e csgmode, const Transform3d &m, GLint *shaderinfo = NULL);
static void render_edges(shared_ptr<const Geometry> geom, csgmode_e csgmode);
protected:
std::map<ColorMode,Color4f> colormap;
const ColorScheme *colorscheme;
};

View File

@ -1,4 +1,6 @@
#include "rendersettings.h"
#include "colormap.h"
#include "printutils.h"
RenderSettings *RenderSettings::inst(bool erase)
{
@ -16,24 +18,5 @@ RenderSettings::RenderSettings()
far_gl_clip_limit = 100000.0;
img_width = 512;
img_height = 512;
this->colors[BACKGROUND_COLOR] = Color4f(0xff, 0xff, 0xe5);
this->colors[OPENCSG_FACE_FRONT_COLOR] = Color4f(0xf9, 0xd7, 0x2c);
this->colors[OPENCSG_FACE_BACK_COLOR] = Color4f(0x9d, 0xcb, 0x51);
this->colors[CGAL_FACE_FRONT_COLOR] = Color4f(0xf9, 0xd7, 0x2c);
this->colors[CGAL_FACE_BACK_COLOR] = Color4f(0x9d, 0xcb, 0x51);
this->colors[CGAL_FACE_2D_COLOR] = Color4f(0x00, 0xbf, 0x99);
this->colors[CGAL_EDGE_FRONT_COLOR] = Color4f(0xff, 0x00, 0x00);
this->colors[CGAL_EDGE_BACK_COLOR] = Color4f(0xff, 0x00, 0x00);
this->colors[CGAL_EDGE_2D_COLOR] = Color4f(0xff, 0x00, 0x00);
this->colors[CROSSHAIR_COLOR] = Color4f(0x80, 0x00, 0x00);
}
Color4f RenderSettings::color(RenderColor idx)
{
return this->colors[idx];
}
void RenderSettings::setColors(const std::map<RenderColor, Color4f> &colors)
{
this->colors = colors;
colorscheme = "Cornfield";
}

View File

@ -2,33 +2,17 @@
#include <map>
#include "linalg.h"
#include "colormap.h"
class RenderSettings
{
public:
static RenderSettings *inst(bool erase = false);
enum RenderColor {
BACKGROUND_COLOR,
OPENCSG_FACE_FRONT_COLOR,
OPENCSG_FACE_BACK_COLOR,
CGAL_FACE_FRONT_COLOR,
CGAL_FACE_2D_COLOR,
CGAL_FACE_BACK_COLOR,
CGAL_EDGE_FRONT_COLOR,
CGAL_EDGE_BACK_COLOR,
CGAL_EDGE_2D_COLOR,
CROSSHAIR_COLOR
};
void setColors(const std::map<RenderColor, Color4f> &colors);
Color4f color(RenderColor idx);
unsigned int openCSGTermLimit, img_width, img_height;
double far_gl_clip_limit;
std::string colorscheme;
private:
RenderSettings();
~RenderSettings() {}
std::map<RenderColor, Color4f> colors;
};

38
src/scadlexer.cpp Normal file
View File

@ -0,0 +1,38 @@
#include "scadlexer.h"
ScadLexer::ScadLexer(QObject *parent)
: QsciLexerCPP(parent)
{ }
ScadLexer::~ScadLexer()
{ }
const char *ScadLexer::language() const
{
return "SCAD";
}
const char *ScadLexer::keywords(int set) const
{
if (set == 1)
return "if else for module function intersection_for assign echo search "
" str let true false "; // -> Style: Keyword
if (set == 2)
return " abs sign acos asin atan atan2 sin cos tan floor round ceil len ln "
" log lookup min max pow sqrt exp rands version version_num "
" group difference union intersection render translate rotate scale multmatrix color "
" projection hull resize mirror minkowski glide subdiv child "
" include use dxf_dim dxf_cross "
" linear_extrude rotate_extrude "; // -> Style: KeywordSet2
if (set == 3)
return " param author "; // -> used in comments only like /*! \cube */
if (set == 4)
return "cube circle cylinder polygon polyhedron square sphere "
"surface import "; // -> Style: GlobalClass
return 0;
}

19
src/scadlexer.h Normal file
View File

@ -0,0 +1,19 @@
#pragma once
#include <qobject.h>
#include <Qsci/qsciglobal.h>
#include <Qsci/qscilexercpp.h>
class ScadLexer : public QsciLexerCPP
{
public:
ScadLexer(QObject *parent);
virtual ~ScadLexer();
const char *language() const;
const char *keywords(int set) const;
private:
ScadLexer(const ScadLexer &);
ScadLexer &operator=(const ScadLexer &);
};

349
src/scintillaeditor.cpp Normal file
View File

@ -0,0 +1,349 @@
#include <algorithm>
#include <QString>
#include <QChar>
#include "scintillaeditor.h"
#include <Qsci/qscicommandset.h>
#include "Preferences.h"
ScintillaEditor::ScintillaEditor(QWidget *parent) : EditorInterface(parent)
{
scintillaLayout = new QVBoxLayout(this);
qsci = new QsciScintilla(this);
//
// Remapping some scintilla key binding which conflict with OpenSCAD global
// key bindings, as well as some minor scintilla bugs
//
QsciCommand *c;
#ifdef Q_OS_MAC
// Alt-Backspace should delete left word (Alt-Delete already deletes right word)
c= qsci->standardCommands()->find(QsciCommand::DeleteWordLeft);
c->setKey(Qt::Key_Backspace | Qt::ALT);
#endif
// Cmd/Ctrl-T is handled by the menu
c = qsci->standardCommands()->boundTo(Qt::Key_T | Qt::CTRL);
c->setKey(0);
// Cmd/Ctrl-D is handled by the menu
c = qsci->standardCommands()->boundTo(Qt::Key_D | Qt::CTRL);
c->setKey(0);
// Ctrl-Shift-Z should redo on all platforms
c= qsci->standardCommands()->find(QsciCommand::Redo);
c->setKey(Qt::Key_Z | Qt::CTRL | Qt::SHIFT);
scintillaLayout->setContentsMargins(0, 0, 0, 0);
scintillaLayout->addWidget(qsci);
qsci->setBraceMatching (QsciScintilla::SloppyBraceMatch);
qsci->setWrapMode(QsciScintilla::WrapCharacter);
qsci->setWrapVisualFlags(QsciScintilla::WrapFlagByBorder, QsciScintilla::WrapFlagNone, 0);
qsci->setAutoIndent(true);
qsci->indicatorDefine(QsciScintilla::RoundBoxIndicator, indicatorNumber);
qsci->markerDefine(QsciScintilla::Circle, markerNumber);
qsci->setUtf8(true);
lexer = new ScadLexer(this);
initLexer();
initMargin();
qsci->setFolding(QsciScintilla::BoxedTreeFoldStyle, 4);
qsci->setCaretLineVisible(true);
this->setHighlightScheme(Preferences::inst()->getValue("editor/syntaxhighlight").toString());
connect(qsci, SIGNAL(textChanged()), this, SIGNAL(contentsChanged()));
connect(qsci, SIGNAL(modificationChanged(bool)), this, SIGNAL(modificationChanged(bool)));
}
void ScintillaEditor::setPlainText(const QString &text)
{
qsci->setText(text);
setContentModified(false);
}
QString ScintillaEditor::toPlainText()
{
return qsci->text();
}
void ScintillaEditor::setContentModified(bool modified)
{
qsci->setModified(modified);
}
bool ScintillaEditor::isContentModified()
{
return qsci->isModified();
}
void ScintillaEditor::highlightError(int error_pos)
{
int line, index;
qsci->lineIndexFromPosition(error_pos, &line, &index);
qsci->fillIndicatorRange(line, index, line, index+1, indicatorNumber);
qsci->setIndicatorForegroundColor(QColor(255,0,0,100));
qsci->markerAdd(line, markerNumber);
}
void ScintillaEditor::unhighlightLastError()
{
int totalLength = qsci->text().length();
int line, index;
qsci->lineIndexFromPosition(totalLength, &line, &index);
qsci->clearIndicatorRange(0, 0, line, index, indicatorNumber);
qsci->markerDeleteAll(markerNumber);
}
//Editor themes
void ScintillaEditor::forLightBackground()
{
lexer->setPaper("#fff");
lexer->setColor(QColor("#272822")); // -> Style: Default text
lexer->setColor(QColor("Green"), QsciLexerCPP::Keyword); // -> Style: Keyword
lexer->setColor(QColor("Green"), QsciLexerCPP::KeywordSet2); // -> Style: KeywordSet2
lexer->setColor(Qt::blue, QsciLexerCPP::CommentDocKeyword); // -> used in comments only like /*! \cube */
lexer->setColor(QColor("DarkBlue"), QsciLexerCPP::GlobalClass); // -> Style: GlobalClass
lexer->setColor(Qt::blue, QsciLexerCPP::Operator);
lexer->setColor(Qt::darkMagenta, QsciLexerCPP::DoubleQuotedString);
lexer->setColor(Qt::darkCyan, QsciLexerCPP::Comment);
lexer->setColor(Qt::darkCyan, QsciLexerCPP::CommentLine);
lexer->setColor(QColor("DarkRed"), QsciLexerCPP::Number);
qsci->setMarkerBackgroundColor(QColor(255, 0, 0, 100), markerNumber);
qsci->setCaretLineBackgroundColor(QColor("#ffe4e4"));
qsci->setMarginsBackgroundColor(QColor("#ccc"));
qsci->setMarginsForegroundColor(QColor("#111"));
qsci->setMatchedBraceBackgroundColor(QColor("#333"));
qsci->setMatchedBraceForegroundColor(QColor("#fff"));
}
void ScintillaEditor::forDarkBackground()
{
lexer->setPaper(QColor("#272822"));
lexer->setColor(QColor(Qt::white));
lexer->setColor(QColor("#f12971"), QsciLexerCPP::Keyword);
lexer->setColor(QColor("#56dbf0"),QsciLexerCPP::KeywordSet2);
lexer->setColor(QColor("#ccdf32"), QsciLexerCPP::CommentDocKeyword);
lexer->setColor(QColor("#56d8f0"), QsciLexerCPP::GlobalClass);
lexer->setColor(QColor("#d8d8d8"), QsciLexerCPP::Operator);
lexer->setColor(QColor("#e6db74"), QsciLexerCPP::DoubleQuotedString);
lexer->setColor(QColor("#e6db74"), QsciLexerCPP::CommentLine);
lexer->setColor(QColor("#af7dff"), QsciLexerCPP::Number);
qsci->setCaretLineBackgroundColor(QColor(104,225,104, 127));
qsci->setMarkerBackgroundColor(QColor(255, 0, 0, 100), markerNumber);
qsci->setMarginsBackgroundColor(QColor("20,20,20,150"));
qsci->setMarginsForegroundColor(QColor("#fff"));
qsci->setCaretWidth(2);
qsci->setCaretForegroundColor(QColor("#ffff00"));
}
void ScintillaEditor::Monokai()
{
lexer->setPaper("#272822");
lexer->setColor(QColor("#f8f8f2")); // -> Style: Default text
lexer->setColor(QColor("#66c3b3"), QsciLexerCPP::Keyword); // -> Style: Keyword
lexer->setColor(QColor("#79abff"), QsciLexerCPP::KeywordSet2); // -> Style: KeywordSet2
lexer->setColor(QColor("#ccdf32"), QsciLexerCPP::CommentDocKeyword); // -> used in comments only like /*! \cube */
lexer->setColor(QColor("#ffffff"), QsciLexerCPP::GlobalClass); // -> Style: GlobalClass
lexer->setColor(QColor("#d8d8d8"), QsciLexerCPP::Operator);
lexer->setColor(QColor("#e6db74"), QsciLexerCPP::DoubleQuotedString);
lexer->setColor(QColor("#75715e"), QsciLexerCPP::CommentLine);
lexer->setColor(QColor("#7fb347"), QsciLexerCPP::Number);
qsci->setMarkerBackgroundColor(QColor(255, 0, 0, 100), markerNumber);
qsci->setCaretLineBackgroundColor(QColor("#3e3d32"));
qsci->setMarginsBackgroundColor(QColor("#757575"));
qsci->setMarginsForegroundColor(QColor("#f8f8f2"));
qsci->setCaretWidth(2);
qsci->setCaretForegroundColor(QColor("#ffff00"));
}
void ScintillaEditor::Solarized_light()
{
lexer->setPaper("#fdf6e3");
lexer->setColor(QColor("#657b83")); // -> Style: Default text
lexer->setColor(QColor("#268ad1"), QsciLexerCPP::Keyword); // -> Style: Keyword
lexer->setColor(QColor("#6c71c4"), QsciLexerCPP::KeywordSet2); // -> Style: KeywordSet2
lexer->setColor(QColor("#b58900"), QsciLexerCPP::CommentDocKeyword); // -> used in comments only like /*! \cube */
lexer->setColor(QColor("#b58800"), QsciLexerCPP::GlobalClass); // -> Style: GlobalClass
lexer->setColor(QColor("#859900"), QsciLexerCPP::Operator);
lexer->setColor(QColor("#2aa198"), QsciLexerCPP::DoubleQuotedString);
lexer->setColor(QColor("#b58800"), QsciLexerCPP::CommentLine);
lexer->setColor(QColor("#cb4b16"), QsciLexerCPP::Number);
qsci->setMarkerBackgroundColor(QColor(255, 0, 0, 100), markerNumber);
qsci->setCaretLineBackgroundColor(QColor("#eeead5"));
qsci->setMarginsBackgroundColor(QColor("#eee8d5"));
qsci->setMarginsForegroundColor(QColor("#93a1a1"));
qsci->setMatchedBraceBackgroundColor(QColor("#0000ff"));
qsci->setMatchedBraceBackgroundColor(QColor("#333"));
qsci->setMatchedBraceForegroundColor(QColor("#fff"));
}
void ScintillaEditor::noColor()
{
lexer->setPaper(Qt::white);
lexer->setColor(Qt::black);
qsci->setMarginsBackgroundColor(QColor("#ccc"));
qsci->setMarginsForegroundColor(QColor("#111"));
}
void ScintillaEditor::setHighlightScheme(const QString &name)
{
if(name == "For Light Background") {
forLightBackground();
}
else if(name == "For Dark Background") {
forDarkBackground();
}
else if(name == "Monokai") {
Monokai();
}
else if(name == "Solarized") {
Solarized_light();
}
else if(name == "Off") {
noColor();
}
}
void ScintillaEditor::insert(const QString &text)
{
qsci->insert(text);
}
void ScintillaEditor::undo()
{
qsci->undo();
}
void ScintillaEditor::redo()
{
qsci->redo();
}
void ScintillaEditor::cut()
{
qsci->cut();
}
void ScintillaEditor::copy()
{
qsci->copy();
}
void ScintillaEditor::paste()
{
qsci->paste();
}
void ScintillaEditor::zoomIn()
{
qsci->zoomIn();
}
void ScintillaEditor::zoomOut()
{
qsci->zoomOut();
}
void ScintillaEditor::initFont(const QString& fontName, uint size)
{
QFont font(fontName, size);
font.setFixedPitch(true);
lexer->setFont(font);
}
void ScintillaEditor::initLexer()
{
qsci->setLexer(lexer);
}
void ScintillaEditor::initMargin()
{
QFontMetrics fontmetrics = QFontMetrics(qsci->font());
qsci->setMarginsFont(qsci->font());
qsci->setMarginWidth(1, fontmetrics.width(QString::number(qsci->lines())) + 6);
qsci->setMarginLineNumbers(1, true);
connect(qsci, SIGNAL(textChanged()), this, SLOT(onTextChanged()));
}
void ScintillaEditor::onTextChanged()
{
QFontMetrics fontmetrics = qsci->fontMetrics();
qsci->setMarginWidth(1, fontmetrics.width(QString::number(qsci->lines())) + 6);
}
bool ScintillaEditor::find(const QString &expr, bool findNext, bool findBackwards)
{
int startline = -1, startindex = -1;
// If findNext, start from the end of the current selection
if (qsci->hasSelectedText()) {
int lineFrom, indexFrom, lineTo, indexTo;
qsci->getSelection(&lineFrom, &indexFrom, &lineTo, &indexTo);
startline = !(findBackwards xor findNext) ? std::min(lineFrom, lineTo) : std::max(lineFrom, lineTo);
startindex = !(findBackwards xor findNext) ? std::min(indexFrom, indexTo) : std::max(indexFrom, indexTo);
}
return qsci->findFirst(expr, false, false, false, true,
!findBackwards, startline, startindex);
}
void ScintillaEditor::replaceSelectedText(const QString &newText)
{
if (qsci->selectedText() != newText) qsci->replaceSelectedText(newText);
}
void ScintillaEditor::get_range(int *lineFrom, int *lineTo)
{
int indexFrom, indexTo;
if (qsci->hasSelectedText()) {
qsci->getSelection(lineFrom, &indexFrom, lineTo, &indexTo);
} else {
qsci->getCursorPosition(lineFrom, &indexFrom);
*lineTo = *lineFrom;
}
}
void ScintillaEditor::indentSelection()
{
int lineFrom, lineTo;
get_range(&lineFrom, &lineTo);
for (int line = lineFrom;line <= lineTo;line++) {
qsci->indent(line);
}
}
void ScintillaEditor::unindentSelection()
{
int lineFrom, lineTo;
get_range(&lineFrom, &lineTo);
for (int line = lineFrom;line <= lineTo;line++) {
qsci->unindent(line);
}
}
void ScintillaEditor::commentSelection()
{
int lineFrom, lineTo;
get_range(&lineFrom, &lineTo);
for (int line = lineFrom;line <= lineTo;line++) {
qsci->insertAt("//", line, 0);
}
}
void ScintillaEditor::uncommentSelection()
{
int lineFrom, lineTo;
get_range(&lineFrom, &lineTo);
for (int line = lineFrom;line <= lineTo;line++) {
QString lineText = qsci->text(line);
if (lineText.startsWith("//")) {
qsci->setSelection(line, 0, line, 2);
qsci->removeSelectedText();
}
}
}
QString ScintillaEditor::selectedText()
{
return qsci->selectedText();
}

62
src/scintillaeditor.h Normal file
View File

@ -0,0 +1,62 @@
#pragma once
#include <QObject>
#include <QWidget>
#include <QVBoxLayout>
#include <Qsci/qsciscintilla.h>
#include <QVBoxLayout>
#include "editor.h"
#include "scadlexer.h"
class ScintillaEditor : public EditorInterface
{
Q_OBJECT;
public:
ScintillaEditor(QWidget *parent);
virtual ~ScintillaEditor() {}
QsciScintilla *qsci;
QString toPlainText();
void initMargin();
void initLexer();
void forLightBackground();
void forDarkBackground();
void Monokai();
void Solarized_light();
void noColor();
QString selectedText();
bool find(const QString &, bool findNext = false, bool findBackwards = false);
void replaceSelectedText(const QString&);
private:
void get_range(int *lineFrom, int *lineTo);
public slots:
void zoomIn();
void zoomOut();
void setPlainText(const QString&);
void setContentModified(bool);
bool isContentModified();
void highlightError(int);
void unhighlightLastError();
void setHighlightScheme(const QString&);
void indentSelection();
void unindentSelection();
void commentSelection();
void uncommentSelection();
void insert(const QString&);
void undo();
void redo();
void cut();
void copy();
void paste();
void initFont(const QString&, uint);
private slots:
void onTextChanged();
private:
QVBoxLayout *scintillaLayout;
static const int indicatorNumber = 1;
static const int markerNumber = 2;
ScadLexer *lexer;
};

View File

@ -2,13 +2,14 @@
#include <string>
#include <vector>
#include <utility>
#include <boost/shared_ptr.hpp>
class Assignment : public std::pair<std::string, boost::shared_ptr<class Expression> >
{
public:
Assignment(std::string name) : pair(name, boost::shared_ptr<class Expression>()) {}
Assignment(std::string name, boost::shared_ptr<class Expression> expr) : pair(name, expr) {}
Assignment(std::string name) { first = name; second = boost::shared_ptr<class Expression>(); }
Assignment(std::string name, boost::shared_ptr<class Expression> expr) { first = name; second = expr; }
};
typedef std::vector<Assignment> AssignmentList;

View File

@ -248,6 +248,58 @@ std::string Value::toString() const
return boost::apply_visitor(tostring_visitor(), this->value);
}
class chr_visitor : public boost::static_visitor<std::string> {
public:
template <typename S> std::string operator()(const S &) const
{
return "";
}
std::string operator()(const double &v) const
{
char buf[8];
memset(buf, 0, 8);
if (v > 0) {
const gunichar c = v;
if (g_unichar_validate(c) && (c != 0)) {
g_unichar_to_utf8(c, buf);
}
}
return std::string(buf);
}
std::string operator()(const Value::VectorType &v) const
{
std::stringstream stream;
for (size_t i = 0; i < v.size(); i++) {
stream << v[i].chrString();
}
return stream.str();
}
std::string operator()(const Value::RangeType &v) const
{
const boost::uint32_t steps = v.nbsteps();
if (steps >= 10000) {
PRINTB("WARNING: Bad range parameter in for statement: too many elements (%lu).", steps);
return "";
}
std::stringstream stream;
Value::RangeType range = v;
for (Value::RangeType::iterator it = range.begin();it != range.end();it++) {
const Value value(*it);
stream << value.chrString();
}
return stream.str();
}
};
std::string Value::chrString() const
{
return boost::apply_visitor(chr_visitor(), this->value);
}
const Value::VectorType &Value::toVector() const
{
static VectorType empty;
@ -331,6 +383,18 @@ public:\
template <typename T, typename U> bool operator()(const T &, const U &) const {\
return false;\
}\
\
bool operator()(const bool &op1, const bool &op2) const {\
return op1 op op2;\
}\
\
bool operator()(const bool &op1, const double &op2) const {\
return op1 op op2;\
}\
\
bool operator()(const double &op1, const bool &op2) const {\
return op1 op op2;\
}\
\
bool operator()(const double &op1, const double &op2) const {\
return op1 op op2;\

View File

@ -87,6 +87,7 @@ public:
/// return number of steps, max uint32_t value if step is 0
boost::uint32_t nbsteps() const;
friend class chr_visitor;
friend class tostring_visitor;
friend class bracket_visitor;
};
@ -121,6 +122,7 @@ public:
bool getDouble(double &v) const;
bool toBool() const;
std::string toString() const;
std::string chrString() const;
const VectorType &toVector() const;
bool getVec2(double &x, double &y) const;
bool getVec3(double &x, double &y, double &z, double defaultval = 0.0) const;

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