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

master
Marius Kintel 2014-09-02 00:16:38 -04:00
commit 3a3ffc0118
547 changed files with 9851 additions and 2166 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

@ -2,6 +2,14 @@ language: cpp
cache: apt
compiler: gcc
notifications:
irc:
channels:
- "chat.freenode.net#openscad"
on_success: change
use_notice: true
skip_join: true
before_install:
- echo 'yes' | sudo add-apt-repository ppa:chrysn/openscad
- sudo apt-get update -qq
@ -24,7 +32,7 @@ before_script:
- base64 --decode --ignore-garbage ~/.ssh/openscad_rsa_base64 > ~/.ssh/id_rsa
- chmod 600 ~/.ssh/id_rsa
script: ./scripts/travis-ci.sh
script: if [ "${COVERITY_SCAN_BRANCH}" != 1 ]; then ./scripts/travis-ci.sh ; fi
env:
global:
@ -67,4 +75,15 @@ env:
- secure: "JsOTX5JsRAY3zyKa/5yYkd48Nejt9CAEraXVpN1NDW25jJmsOynyW5d2WYazJ1H0x1oR6Fhc4gstNxaj1MNh/gVM9O3UM2tyFnSxDY6fZnEGWaf17ln4dqi3KHXWU7h2Gdg1ah19NS0nWytooW6VcEXmk+cYSheTqyfc5gK7Sdo="
- secure: "mMc9MyopIjvzpDg3eN6owSmr2PI58JiPnlLhMNvOWW9axUzup5tthfqM+tvR/AqdLQSSMUC9JXwwQK0d543Q4YyoQ0jwVY2RT56VdEywxD5+yWRfXD+ANlJhdQWmlPVc3KsavKYmfQPBLbwe0nyhtQTWGeAgKTYvYT+k1/PD4rg="
- secure: "X7KDSiSOR3XcePJgTXNzwE1wU285yFsxB7crMLskD08wU8xdRqS8NL+1++/Lju6pypOkospI2AYH1JAJ7JK3Sx5QYM4MxgRJcrMHiTMirN3cm3KzkWUuv3iEZNJ7q6ANi5oFfHh3k0D4JhCEnA1ICTDPdq+r9+mOvgkrly8V0Dw="
# scan.coverity token
- secure: "CGHkiv3Aki3HF2xiNPbPEqB66Xcz8HrdhSpFYjQFqHsrseIXOmZGLaIdnkwCqoIHUMFVtqGVGSxRhhrSOrAq+uOgc6Wyst8u6ThN3HhRbvQgF2v7XvtGsTiAObxLvj5V91gqQwHxWPHf948Cm12QQgmEd+dbhyjPWsmVMDb4gNk="
addons:
coverity_scan:
project:
name: "openscad/openscad"
description: "The Programmers Solid 3D CAD Modeller"
notification_email: torsten.paul@gmx.de
build_command_prepend: qmake
build_command: make
branch_pattern: coverity_scan

View File

@ -1,4 +1,5 @@
[![Travis CI](https://api.travis-ci.org/openscad/openscad.png)](https://travis-ci.org/openscad/openscad)
[![Coverity Status](https://scan.coverity.com/projects/2510/badge.svg)](https://scan.coverity.com/projects/2510)
# What is OpenSCAD?
[![Flattr this git repo](http://api.flattr.com/button/flattr-badge-large.png)](https://flattr.com/submit/auto?user_id=openscad&url=http://openscad.org&title=OpenSCAD&language=&tags=github&category=software)

Binary file not shown.

Binary file not shown.

View File

@ -0,0 +1,48 @@
// Example for text() usage
// (c) 2014 Torsten Paul
// CC-BY-SA 4.0
echo(version=version());
$vpr = [90, 0, 0];
$vpt = [250, 0, 80];
$vpd = 500;
r = 60;
hole = 30;
module t(t, s = 18, style = "") {
rotate([90, 0, 0])
linear_extrude(height = 1)
text(t, size = s, font = str("Liberation Serif", style), $fn = 16);
}
module cut() {
cylinder(r = hole, h = 2.5 * r, center = true, $fn = 60);
}
module logo() {
difference() {
sphere(r = r, $fn = 120);
cut();
rotate([0, 90, 0]) cut();
#rotate([90, 0, 0]) cut();
}
}
module green() {
color([81/255, 142/255, 4/255]) children();
}
module black() {
color([0, 0, 0]) children();
}
translate([110, 0, 80]) {
translate([0, 0, 30]) rotate([25, 25, -40]) logo();
translate([100, 0, 40]) green() t("Open", 42, ":style=Bold");
translate([242, 0, 40]) black() t("SCAD", 42, ":style=Bold");
translate([100, 0, -10]) black() t("The Programmers");
translate([160, 0, -40]) black() t("Solid 3D CAD Modeller");
}

View File

@ -0,0 +1,40 @@
// Example for text() usage
// (c) 2014 Torsten Paul
// CC-BY-SA 4.0
echo(version=version());
font = "Liberation Sans";
cube_size = 60;
letter_size = 50;
letter_height = 5;
o = cube_size / 2 - letter_height / 2;
module letter(l) {
// Use linear_extrude() to make the letters 3D objects as they
// are only 2D shapes when only using text()
linear_extrude(height = letter_height) {
text(l, size = letter_size, font = font, halign = "center", valign = "center", $fn = 16);
}
}
difference() {
union() {
color("gray") cube(cube_size, center = true);
translate([0, -o, 0]) rotate([90, 0, 0]) letter("C");
translate([o, 0, 0]) rotate([90, 0, 90]) letter("U");
translate([0, o, 0]) rotate([90, 0, 180]) letter("B");
translate([-o, 0, 0]) rotate([90, 0, -90]) letter("E");
}
// Put some symbols on top and bottom using symbols from the
// Unicode symbols table.
// (see https://en.wikipedia.org/wiki/Miscellaneous_Symbols)
//
// Note that depending on the font used, not all the symbols
// are actually available.
translate([0, 0, o]) letter("\u263A");
translate([0, 0, -o - letter_height]) letter("\u263C");
}

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>

22
fonts/10-liberation.conf Normal file
View File

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

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

@ -237,8 +237,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 \
@ -308,6 +309,7 @@ HEADERS += src/typedefs.h \
src/system-gl.h \
src/stl-utils.h \
src/boost-utils.h \
src/LibraryInfo.h \
src/svg.h \
\
src/lodepng.h \
@ -366,6 +368,7 @@ SOURCES += src/version_check.cc \
src/stl-utils.cc \
src/boost-utils.cc \
src/PlatformUtils.cc \
src/LibraryInfo.cc \
\
src/nodedumper.cc \
src/traverser.cc \
@ -392,6 +395,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 \
@ -440,6 +444,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 \

33
releases/2014.QX.md Normal file
View File

@ -0,0 +1,33 @@
**Language Features:**
* surface() can now take PNG images as input
* List comprehensions, let()
* text() module
* offset()
* min() and max() can now take a wvector argument
* concat()
* 2D minkowski and holes
**Program Features:**
* Added --viewall cmd-line parameter
* MDI
* FIXME: Windows cmd-line fixes
* Qt5, retina
* SVG import/export
* AMF import/export
**Bugfixes/improvements:**
* Internal cavity fix
* Performance: 2D (clipper), preview, hull, minkowski, surface, n-ary-union, transforms (polyset)
* Performance: Reduce duplicate evaluation of identical expressions
* STL export/import fixes
* F6 stability fixes
* Better recursion behavior
* Reorganized examples a bit
* improved search() behavior
* Mac: Timestamps is output fixed
**Deprecations:**
* polyhedron triangles
**Misc:**

View File

@ -96,10 +96,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 +142,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

View File

@ -41,15 +41,6 @@ printUsage()
echo " -d Build for deployment"
}
create_dummy_cmd()
{
cmd="$1"
file="$2"
echo "$cmd" > "$file"
chmod 755 "$file"
}
patch_qt_disable_core_wlan()
{
version="$1"
@ -110,12 +101,18 @@ build_qt()
;;
esac
./configure -prefix $DEPLOYDIR -release $QT_32BIT -arch x86_64 -opensource -confirm-license $PLATFORM -fast -no-qt3support -no-svg -no-phonon -no-audio-backend -no-multimedia -no-javascript-jit -no-script -no-scripttools -no-declarative -no-xmlpatterns -nomake demos -nomake examples -nomake docs -nomake translations -no-webkit $MACOSX_RELEASE_OPTIONS
make -j6 install
make -j"$NUMCPU" install
}
build_qt5()
{
version=$1
if [ -d $DEPLOYDIR/lib/QtCore.framework ]; then
echo "Qt5 already installed. not building"
return
fi
echo "Building Qt" $version "..."
cd $BASEDIR/src
v=(${version//./ }) # Split into array
@ -125,8 +122,15 @@ build_qt5()
fi
tar xzf qt-everywhere-opensource-src-$version.tar.gz
cd qt-everywhere-opensource-src-$version
./configure -prefix $DEPLOYDIR -release -opensource -confirm-license -nomake examples -nomake tests -no-xcb -no-c++11 -no-glib
make -j6 install
./configure -prefix $DEPLOYDIR -release -opensource -confirm-license \
-nomake examples -nomake tests \
-no-xcb -no-c++11 -no-glib -no-harfbuzz -no-sql-db2 -no-sql-ibase -no-sql-mysql -no-sql-oci -no-sql-odbc \
-no-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
}
# Hack warning: gmplib is built separately in 32-bit and 64-bit mode
@ -310,7 +314,7 @@ build_boost()
BOOST_TOOLSET="toolset=clang"
echo "using clang ;" >> tools/build/v2/user-config.jam
fi
./b2 -j6 -d+2 $BOOST_TOOLSET cflags="-mmacosx-version-min=$MAC_OSX_VERSION_MIN -arch x86_64 $BOOST_EXTRA_FLAGS" linkflags="-mmacosx-version-min=$MAC_OSX_VERSION_MIN -arch x86_64 $BOOST_EXTRA_FLAGS -headerpad_max_install_names" install
./b2 -j"$NUMCPU" -d+2 $BOOST_TOOLSET cflags="-mmacosx-version-min=$MAC_OSX_VERSION_MIN -arch x86_64 $BOOST_EXTRA_FLAGS" linkflags="-mmacosx-version-min=$MAC_OSX_VERSION_MIN -arch x86_64 $BOOST_EXTRA_FLAGS -headerpad_max_install_names" install
install_name_tool -id $DEPLOYDIR/lib/libboost_thread.dylib $DEPLOYDIR/lib/libboost_thread.dylib
install_name_tool -change libboost_system.dylib $DEPLOYDIR/lib/libboost_system.dylib $DEPLOYDIR/lib/libboost_thread.dylib
install_name_tool -change libboost_chrono.dylib $DEPLOYDIR/lib/libboost_chrono.dylib $DEPLOYDIR/lib/libboost_thread.dylib
@ -354,7 +358,7 @@ build_cgal()
CGAL_EXTRA_FLAGS=";i386"
fi
cmake -DCMAKE_INSTALL_PREFIX=$DEPLOYDIR -DGMP_INCLUDE_DIR=$DEPLOYDIR/include -DGMP_LIBRARIES=$DEPLOYDIR/lib/libgmp.dylib -DGMPXX_LIBRARIES=$DEPLOYDIR/lib/libgmpxx.dylib -DGMPXX_INCLUDE_DIR=$DEPLOYDIR/include -DMPFR_INCLUDE_DIR=$DEPLOYDIR/include -DMPFR_LIBRARIES=$DEPLOYDIR/lib/libmpfr.dylib -DWITH_CGAL_Qt3=OFF -DWITH_CGAL_Qt4=OFF -DWITH_CGAL_ImageIO=OFF -DBUILD_SHARED_LIBS=TRUE -DCMAKE_OSX_DEPLOYMENT_TARGET="$MAC_OSX_VERSION_MIN" -DCMAKE_OSX_ARCHITECTURES="x86_64$CGAL_EXTRA_FLAGS" -DBOOST_ROOT=$DEPLOYDIR -DBoost_USE_MULTITHREADED=false
make -j4
make -j"$NUMCPU" install
make install
install_name_tool -id $DEPLOYDIR/lib/libCGAL.dylib $DEPLOYDIR/lib/libCGAL.dylib
install_name_tool -id $DEPLOYDIR/lib/libCGAL_Core.dylib $DEPLOYDIR/lib/libCGAL_Core.dylib
@ -414,10 +418,6 @@ build_eigen()
{
version=$1
if [ -d $DEPLOYDIR/include/eigen2 ]; then
echo "eigen2 already installed. not building"
return
fi
if [ -d $DEPLOYDIR/include/eigen3 ]; then
echo "eigen3 already installed. not building"
return
@ -431,7 +431,9 @@ build_eigen()
if [ $version = "3.1.2" ]; then EIGENDIR=eigen-eigen-5097c01bcdc4;
elif [ $version = "3.1.3" ]; then EIGENDIR=eigen-eigen-2249f9c22fe8;
elif [ $version = "3.1.4" ]; then EIGENDIR=eigen-eigen-36bf2ceaf8f5;
elif [ $version = "3.2.0" ]; then EIGENDIR=eigen-eigen-ffa86ffb5570; fi
elif [ $version = "3.2.0" ]; then EIGENDIR=eigen-eigen-ffa86ffb5570;
elif [ $version = "3.2.1" ]; then EIGENDIR=eigen-eigen-6b38706d90a9;
fi
if [ $EIGENDIR = "none" ]; then
echo Unknown eigen version. Please edit script.
@ -452,7 +454,7 @@ build_eigen()
EIGEN_EXTRA_FLAGS=";i386"
fi
cmake -DCMAKE_INSTALL_PREFIX=$DEPLOYDIR -DEIGEN_BUILD_LIB=ON -DBUILD_SHARED_LIBS=FALSE -DCMAKE_OSX_DEPLOYMENT_TARGET="$MAC_OSX_VERSION_MIN" -DCMAKE_OSX_ARCHITECTURES="x86_64$EIGEN_EXTRA_FLAGS" ..
make -j4
make -j"$NUMCPU" install
make install
}
@ -487,6 +489,11 @@ build_freetype()
version="$1"
extra_config_flags="$2"
if [ -f $DEPLOYDIR/lib/libfreetype.dylib ]; then
echo "freetype already installed. not building"
return
fi
echo "Building freetype $version..."
cd "$BASEDIR"/src
rm -rf "freetype-$version"
@ -504,6 +511,11 @@ build_libxml2()
{
version="$1"
if [ -f $DEPLOYDIR/lib/libxml2.dylib ]; then
echo "libxml2 already installed. not building"
return
fi
echo "Building libxml2 $version..."
cd "$BASEDIR"/src
rm -rf "libxml2-$version"
@ -521,6 +533,11 @@ build_fontconfig()
{
version=$1
if [ -f $DEPLOYDIR/lib/libfontconfig.dylib ]; then
echo "fontconfig already installed. not building"
return
fi
echo "Building fontconfig $version..."
cd "$BASEDIR"/src
rm -rf "fontconfig-$version"
@ -540,6 +557,11 @@ build_libffi()
{
version="$1"
if [ -f $DEPLOYDIR/lib/libffi.dylib ]; then
echo "libffi already installed. not building"
return
fi
echo "Building libffi $version..."
cd "$BASEDIR"/src
rm -rf "libffi-$version"
@ -557,6 +579,11 @@ build_gettext()
{
version="$1"
if [ -f $DEPLOYDIR/lib/libgettextlib.dylib ]; then
echo "gettext already installed. not building"
return
fi
echo "Building gettext $version..."
cd "$BASEDIR"/src
rm -rf "gettext-$version"
@ -575,6 +602,11 @@ build_glib2()
{
version="$1"
if [ -f $DEPLOYDIR/lib/libglib-2.0.dylib ]; then
echo "glib2 already installed. not building"
return
fi
echo "Building glib2 $version..."
cd "$BASEDIR"/src
@ -597,6 +629,11 @@ build_ragel()
{
version=$1
if [ -f $DEPLOYDIR/bin/ragel ]; then
echo "ragel already installed. not building"
return
fi
echo "Building ragel $version..."
cd "$BASEDIR"/src
rm -rf "ragel-$version"
@ -616,6 +653,11 @@ build_harfbuzz()
version=$1
extra_config_flags="$2"
if [ -f $DEPLOYDIR/lib/libharfbuzz.dylib ]; then
echo "harfbuzz already installed. not building"
return
fi
echo "Building harfbuzz $version..."
cd "$BASEDIR"/src
rm -rf "harfbuzz-$version"
@ -693,6 +735,7 @@ echo "Building for $MAC_OSX_VERSION_MIN or later"
if [ ! $NUMCPU ]; then
NUMCPU=$(sysctl -n hw.ncpu)
echo "Setting number of CPUs to $NUMCPU"
fi
if $OPTION_DEPLOY; then
@ -710,9 +753,9 @@ fi
echo "Using basedir:" $BASEDIR
mkdir -p $SRCDIR $DEPLOYDIR
build_qt5 5.3.0
build_qt5 5.3.1
# NB! For eigen, also update the path in the function
build_eigen 3.2.0
build_eigen 3.2.1
build_gmp 5.1.3
build_mpfr 3.1.2
build_boost 1.54.0
@ -724,14 +767,12 @@ build_libffi 3.1
build_glib2 2.40.0
build_opencsg 1.3.2
build_freetype 2.5.3 --without-png
build_ragel 6.8
build_harfbuzz 0.9.28 "--with-coretext=auto --with-glib=no"
export FREETYPE_CFLAGS="-I$DEPLOYDIR/include -I$DEPLOYDIR/include/freetype2"
export FREETYPE_LIBS="-L$DEPLOYDIR/lib -lfreetype"
build_libxml2 2.9.1
build_fontconfig 2.11.1
build_ragel 6.8
export PATH="$PATH:$DEPLOYDIR/bin"
create_dummy_cmd "touch gtk-doc.make" "$DEPLOYDIR/bin/gtkdocize"
if $OPTION_DEPLOY; then
# build_sparkle andymatuschak 0ed83cf9f2eeb425d4fdd141c01a29d843970c20
build_sparkle Cocoanetics 1e7dcb1a48b96d1a8c62100b5864bd50211cbae1

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

@ -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,11 @@ if [ -n $FONTDIR ]; then
echo $FONTDIR
mkdir -p $FONTDIR
cp -a fonts/* $FONTDIR
case $OS in
MACOSX)
cp -a fonts-osx/* $FONTDIR
;;
esac
fi
if [ -n $LIBRARYDIR ]; then
echo $LIBRARYDIR

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

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

@ -9,6 +9,11 @@ CGAL_Nef_polyhedron::CGAL_Nef_polyhedron(CGAL_Nef_polyhedron3 *p)
if (p) p3.reset(p);
}
// Copy constructor
CGAL_Nef_polyhedron::CGAL_Nef_polyhedron(const CGAL_Nef_polyhedron &src)
{
if (src.p3) this->p3.reset(new CGAL_Nef_polyhedron3(*src.p3));
}
CGAL_Nef_polyhedron& CGAL_Nef_polyhedron::operator+=(const CGAL_Nef_polyhedron &other)
{
@ -48,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);
@ -69,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);
@ -78,13 +85,48 @@ PolySet *CGAL_Nef_polyhedron::convertToPolyset() const
CGAL::set_error_behaviour(old_behaviour);
return ps;
}
#endif
/*!
Deep copy
*/
CGAL_Nef_polyhedron *CGAL_Nef_polyhedron::copy() const
void CGAL_Nef_polyhedron::resize(Vector3d newsize,
const Eigen::Matrix<bool,3,1> &autosize)
{
CGAL_Nef_polyhedron *copy = new CGAL_Nef_polyhedron(*this);
if (copy->p3) copy->p3.reset(new CGAL_Nef_polyhedron3(*copy->p3));
return copy;
// Based on resize() in Giles Bathgate's RapCAD (but not exactly)
if (this->isEmpty()) return;
CGAL_Iso_cuboid_3 bb = CGALUtils::boundingBox(*this->p3);
std::vector<NT3> scale, bbox_size;
for (unsigned int i=0;i<3;i++) {
scale.push_back(NT3(1));
bbox_size.push_back(bb.max_coord(i) - bb.min_coord(i));
}
int newsizemax_index = 0;
for (unsigned int i=0;i<this->getDimension();i++) {
if (newsize[i]) {
if (bbox_size[i] == NT3(0)) {
PRINT("WARNING: Resize in direction normal to flat object is not implemented");
return;
}
else {
scale[i] = NT3(newsize[i]) / bbox_size[i];
}
if (newsize[i] > newsize[newsizemax_index]) newsizemax_index = i;
}
}
NT3 autoscale = NT3(1);
if (newsize[newsizemax_index] != 0) {
autoscale = NT3(newsize[newsizemax_index]) / bbox_size[newsizemax_index];
}
for (unsigned int i=0;i<this->getDimension();i++) {
if (autosize[i] && newsize[i]==0) scale[i] = autoscale;
}
Eigen::Matrix4d t;
t << CGAL::to_double(scale[0]), 0, 0, 0,
0, CGAL::to_double(scale[1]), 0, 0,
0, 0, CGAL::to_double(scale[2]), 0,
0, 0, 0, 1;
this->transform(Transform3d(t));
}

View File

@ -10,6 +10,7 @@ class CGAL_Nef_polyhedron : public Geometry
{
public:
CGAL_Nef_polyhedron(CGAL_Nef_polyhedron3 *p = NULL);
CGAL_Nef_polyhedron(const CGAL_Nef_polyhedron &src);
~CGAL_Nef_polyhedron() {}
virtual size_t memsize() const;
@ -19,14 +20,17 @@ public:
virtual unsigned int getDimension() const { return 3; }
// Empty means it is a geometric node which has zero area/volume
virtual bool isEmpty() const { return !p3; }
virtual Geometry *copy() const { return new CGAL_Nef_polyhedron(*this); }
void reset() { p3.reset(); }
CGAL_Nef_polyhedron &operator+=(const CGAL_Nef_polyhedron &other);
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);
CGAL_Nef_polyhedron *copy() const;
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);
shared_ptr<CGAL_Nef_polyhedron3> p3;
};

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

@ -1,9 +1,11 @@
#include "Camera.h"
#include "rendersettings.h"
#include "printutils.h"
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;
@ -15,6 +17,7 @@ Camera::Camera(enum CameraType camtype) :
}
pixel_width = RenderSettings::inst()->img_width;
pixel_height = RenderSettings::inst()->img_height;
autocenter = false;
}
void Camera::setup(std::vector<double> params)
@ -24,6 +27,7 @@ void Camera::setup(std::vector<double> params)
object_trans << params[0], params[1], params[2];
object_rot << params[3], params[4], params[5];
viewer_distance = params[6];
height = params[6];
} else if (params.size() == 6) {
type = Camera::VECTOR;
eye << params[0], params[1], params[2];
@ -56,6 +60,18 @@ void Camera::viewAll(const BoundingBox &bbox, float scalefactor)
this->eye = this->center - Vector3d(1,1,-0.5);
}
if (this->autocenter) {
// autocenter = point camera at the center of the bounding box.
if (this->type == Camera::GIMBAL) {
this->object_trans = -bbox.center(); // for Gimbal cam
}
else if (this->type == Camera::VECTOR) {
Vector3d dir = this->center - this->eye;
this->center = bbox.center(); // for Vector cam
this->eye = this->center - dir;
}
}
switch (this->projection) {
case Camera::ORTHOGONAL:
this->height = bbox.diagonal().norm();
@ -77,4 +93,33 @@ 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)
{
if (this->projection == PERSPECTIVE) {
this->viewer_distance *= pow(0.9, delta / 120.0);
}
else {
this->height *= pow(0.9, delta / 120.0);
}
}
void Camera::setProjection(ProjectionType type)
{
if (this->projection != type) {
switch (type) {
case PERSPECTIVE:
this->viewer_distance = this->height;
break;
case ORTHOGONAL:
this->height = this->viewer_distance;
break;
}
this->projection = type;
}
}

View File

@ -28,6 +28,8 @@ public:
Camera(enum CameraType camtype = NONE);
void setup(std::vector<double> params);
void gimbalDefaultTranslate();
void setProjection(ProjectionType type);
void zoom(int delta);
void viewAll(const BoundingBox &bbox, float scalefactor = 1.0f);
// Vectorcam
@ -40,14 +42,20 @@ public:
Eigen::Vector3d object_rot;
double viewer_distance;
// Perspective settings
// Perspective settings
double fov; // Field of view
// Orthographic settings
// Orthographic settings
double height; // world-space height of viewport
// true if camera should try to view everything in a given
// bounding box.
bool viewall;
// true if camera should point at center of bounding box
// (normally it points at 0,0,0 or at given coordinates)
bool autocenter;
unsigned int pixel_width;
unsigned int pixel_height;
};

View File

@ -43,6 +43,7 @@ DrawingCallback::~DrawingCallback()
void DrawingCallback::start_glyph()
{
this->polygon = new Polygon2d();
this->polygon->setSanitized(true);
}
void DrawingCallback::finish_glyph()

View File

@ -31,9 +31,13 @@
#include <boost/algorithm/string.hpp>
#include "FontCache.h"
#include "PlatformUtils.h"
#include "parsersettings.h"
extern std::vector<std::string> librarypath;
std::vector<std::string> fontpath;
namespace fs = boost::filesystem;
static bool FontInfoSortPredicate(const FontInfo& fi1, const FontInfo& fi2)
@ -59,7 +63,7 @@ bool FontInfo::operator<(const FontInfo &rhs) const
}
return file < rhs.file;
}
std::string FontInfo::get_family() const
{
return family;
@ -76,42 +80,80 @@ std::string FontInfo::get_file() const
}
FontCache * FontCache::self = NULL;
const std::string FontCache::DEFAULT_FONT("Liberation Sans:style=Regular");
FontCache::FontCache()
{
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")) {
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
config = FcInitLoadConfig();
if (!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());
}
// Add the built-in fonts & config
fs::path builtinfontpath = fs::path(PlatformUtils::resourcesPath()) / "fonts";
if (fs::is_directory(builtinfontpath)) {
add_font_dir(boosty::stringy(boosty::canonical(builtinfontpath)));
FcConfigParseAndLoad(config, reinterpret_cast<const FcChar8 *>(boosty::stringy(builtinfontpath).c_str()), false);
}
add_font_dir("/System/Library/Fonts");
const char *home = getenv("HOME");
if (home) {
add_font_dir(std::string(home) + "/Library/Fonts");
add_font_dir(std::string(home) + "/.fonts");
}
#ifdef WIN32
// Add Window font folders.
const char *windir = getenv("WinDir");
if (windir) {
add_font_dir(std::string(windir) + "\\Fonts");
}
#endif
// Add Linux font folders, the system folders are expected to be
// configured by the system configuration for fontconfig.
if (home) {
add_font_dir(std::string(home) + "/.fonts");
}
const char *env_font_path = getenv("OPENSCAD_FONT_PATH");
if (env_font_path != NULL) {
std::string paths(env_font_path);
const std::string sep = PlatformUtils::pathSeparatorChar();
typedef boost::split_iterator<std::string::iterator> string_split_iterator;
for (string_split_iterator it = boost::make_split_iterator(paths, boost::first_finder(sep, boost::is_iequal())); it != string_split_iterator(); it++) {
const fs::path p(boost::copy_range<std::string>(*it));
if (fs::exists(p) && fs::is_directory(p)) {
std::string path = boosty::absolute(p).string();
add_font_dir(path);
}
}
}
// FIXME: Caching happens here. This would be a good place to notify the user
FcConfigBuildFonts(config);
// For use by LibraryInfo
FcStrList *dirs = FcConfigGetFontDirs(config);
while (FcChar8 *dir = FcStrListNext(dirs)) {
fontpath.push_back(std::string((const char *)dir));
}
FcStrListDone(dirs);
const FT_Error error = FT_Init_FreeType(&library);
if (error) {
PRINT("Can't initialize freetype library, text() objects will not be rendered");
return;
}
init_ok = true;
}
@ -127,48 +169,51 @@ FontCache * FontCache::instance()
return self;
}
void FontCache::register_font_file(std::string path) {
if (!FcConfigAppFontAddFile(config, reinterpret_cast<const FcChar8 *>(path.c_str()))) {
void FontCache::register_font_file(const std::string path)
{
if (!FcConfigAppFontAddFile(config, reinterpret_cast<const FcChar8 *> (path.c_str()))) {
PRINTB("Can't register font '%s'", path);
}
}
void FontCache::add_font_dir(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(config, reinterpret_cast<const FcChar8 *> (path.c_str()))) {
PRINTB("Can't register font directory '%s'", path);
}
}
FontInfoList * FontCache::list_fonts() {
FcObjectSet *object_set = FcObjectSetBuild (FC_FAMILY, FC_STYLE, FC_FILE, (char *)0);
FontInfoList * FontCache::list_fonts()
{
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);
FcObjectSetDestroy(object_set);
FcPatternDestroy(pattern);
FcObjectSetDestroy(object_set);
FcPatternDestroy(pattern);
FontInfoList *list = new FontInfoList();
for (int a = 0;a < font_set->nfont;a++) {
for (int a = 0; a < font_set->nfont; a++) {
FcValue file_value;
FcPatternGet(font_set->fonts[a], FC_FILE, 0, &file_value);
FcValue family_value;
FcPatternGet(font_set->fonts[a], FC_FAMILY, 0, &family_value);
FcValue style_value;
FcPatternGet(font_set->fonts[a], FC_STYLE, 0, &style_value);
std::string family((const char *)family_value.u.s);
std::string style((const char *)style_value.u.s);
std::string file((const char *)file_value.u.s);
std::string family((const char *) family_value.u.s);
std::string style((const char *) style_value.u.s);
std::string file((const char *) file_value.u.s);
list->push_back(FontInfo(family, style, file));
}
FcFontSetDestroy(font_set);
return list;
}
@ -182,10 +227,10 @@ void FontCache::clear()
cache.clear();
}
void FontCache::dump_cache(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 = cache.begin(); it != cache.end(); it++) {
std::cout << " " << (*it).first << " (" << (*it).second.second << ")";
}
std::cout << std::endl;
@ -198,7 +243,7 @@ void FontCache::check_cleanup()
}
cache_t::iterator pos = cache.begin()++;
for (cache_t::iterator it = cache.begin();it != cache.end();it++) {
for (cache_t::iterator it = cache.begin(); it != cache.end(); it++) {
if ((*pos).second.second > (*it).second.second) {
pos = it;
}
@ -207,7 +252,7 @@ void FontCache::check_cleanup()
cache.erase(pos);
}
FT_Face FontCache::get_font(std::string font)
FT_Face FontCache::get_font(const std::string font)
{
FT_Face face;
cache_t::iterator it = cache.find(font);
@ -224,31 +269,16 @@ FT_Face FontCache::get_font(std::string font)
return face;
}
FT_Face FontCache::find_face(std::string font)
FT_Face FontCache::find_face(const std::string font)
{
FT_Face face;
face = find_face_fontconfig(font);
return face ? face : find_face_in_path_list(font);
}
FT_Face FontCache::find_face_in_path_list(std::string font)
{
const char *env_font_path = getenv("OPENSCAD_FONT_PATH");
std::string paths = (env_font_path == NULL) ? "/usr/share/fonts/truetype" : env_font_path;
typedef boost::split_iterator<std::string::iterator> string_split_iterator;
for (string_split_iterator it = boost::make_split_iterator(paths, boost::first_finder(":", boost::is_iequal()));it != string_split_iterator();it++) {
fs::path p(boost::copy_range<std::string>(*it));
if (fs::exists(p)) {
std::string path = boosty::absolute(p).string();
FT_Face face = find_face_in_path(path, font);
if (face) {
return face;
}
}
}
return NULL;
std::string trimmed(font);
boost::algorithm::trim(trimmed);
const std::string lookup = trimmed.empty() ? DEFAULT_FONT : trimmed;
PRINTDB("font = \"%s\", lookup = \"%s\"", font % lookup);
FT_Face face = find_face_fontconfig(lookup);
PRINTDB("result = \"%s\", style = \"%s\"", face->family_name % face->style_name);
return face;
}
void FontCache::init_pattern(FcPattern *pattern)
@ -256,56 +286,100 @@ void FontCache::init_pattern(FcPattern *pattern)
FcValue true_value;
true_value.type = FcTypeBool;
true_value.u.b = true;
FcPatternAdd(pattern, FC_OUTLINE, true_value, true);
FcPatternAdd(pattern, FC_SCALABLE, true_value, true);
}
FT_Face FontCache::find_face_fontconfig(std::string font)
FT_Face FontCache::find_face_fontconfig(const std::string font)
{
FcResult result;
FcPattern *pattern = FcNameParse((unsigned char *)font.c_str());
FcPattern *pattern = FcNameParse((unsigned char *) font.c_str());
init_pattern(pattern);
FcDefaultSubstitute(pattern);
FcConfigSubstitute(config, pattern, FcMatchFont);
FcPattern *match = FcFontMatch(config, pattern, &result);
FcValue file_value;
FcPatternGet(match, FC_FILE, 0, &file_value);
FcValue file_value;
if (FcPatternGet(match, FC_FILE, 0, &file_value) != FcResultMatch) {
return NULL;
}
FcValue font_index;
if (FcPatternGet(match, FC_INDEX, 0, &font_index)) {
return NULL;
}
FT_Face face;
FT_Error error = FT_New_Face(library, (const char *)file_value.u.s, 0, &face);
FT_Error error = FT_New_Face(library, (const char *) file_value.u.s, font_index.u.i, &face);
FcPatternDestroy(pattern);
FcPatternDestroy(match);
for (int a = 0; a < face->num_charmaps; a++) {
FT_CharMap charmap = face->charmaps[a];
PRINTDB("charmap = %d: platform = %d, encoding = %d", a % charmap->platform_id % charmap->encoding_id);
}
if (FT_Select_Charmap(face, ft_encoding_unicode) == 0) {
PRINTDB("Successfully selected unicode charmap: %s/%s", face->family_name % face->style_name);
} else {
bool charmap_set = false;
if (!charmap_set)
charmap_set = try_charmap(face, TT_PLATFORM_MICROSOFT, TT_MS_ID_UNICODE_CS);
if (!charmap_set)
charmap_set = try_charmap(face, TT_PLATFORM_ISO, TT_ISO_ID_10646);
if (!charmap_set)
charmap_set = try_charmap(face, TT_PLATFORM_APPLE_UNICODE, -1);
if (!charmap_set)
charmap_set = try_charmap(face, TT_PLATFORM_MICROSOFT, TT_MS_ID_SYMBOL_CS);
if (!charmap_set)
charmap_set = try_charmap(face, TT_PLATFORM_MACINTOSH, TT_MAC_ID_ROMAN);
if (!charmap_set)
charmap_set = try_charmap(face, TT_PLATFORM_ISO, TT_ISO_ID_8859_1);
if (!charmap_set)
charmap_set = try_charmap(face, TT_PLATFORM_ISO, TT_ISO_ID_7BIT_ASCII);
if (!charmap_set)
PRINTB("Warning: Could not select a char map for font %s/%s", face->family_name % face->style_name);
}
return error ? NULL : face;
}
FT_Face FontCache::find_face_in_path(std::string path, std::string font)
bool FontCache::try_charmap(FT_Face face, int platform_id, int encoding_id)
{
FT_Error error;
if (!fs::is_directory(path)) {
PRINTB("Font path '%s' does not exist or is not a directory.", path);
}
for (fs::recursive_directory_iterator it(path);it != fs::recursive_directory_iterator();it++) {
fs::directory_entry entry = (*it);
if (fs::is_regular(entry.path())) {
FT_Face face;
error = FT_New_Face(library, entry.path().string().c_str(), 0, &face);
if (error) {
continue;
for (int idx = 0; idx < face->num_charmaps; idx++) {
FT_CharMap charmap = face->charmaps[idx];
if ((charmap->platform_id == platform_id) && ((encoding_id < 0) || (charmap->encoding_id == encoding_id))) {
if (FT_Set_Charmap(face, charmap) == 0) {
PRINTDB("Selected charmap: platform_id = %d, encoding_id = %d", charmap->platform_id % charmap->encoding_id);
if (is_windows_symbol_font(face)) {
PRINTDB("Detected windows symbol font with character codes in the Private Use Area of Unicode at 0xf000: %s/%s", face->family_name % face->style_name);
}
return true;
}
const char *name = FT_Get_Postscript_Name(face);
if (font == name) {
return face;
}
FT_Done_Face(face);
}
}
return NULL;
return false;
}
bool FontCache::is_windows_symbol_font(FT_Face face)
{
if (face->charmap->platform_id != TT_PLATFORM_MICROSOFT) {
return false;
}
if (face->charmap->encoding_id != TT_MS_ID_SYMBOL_CS) {
return false;
}
FT_UInt gindex;
FT_ULong charcode = FT_Get_First_Char(face, &gindex);
if ((gindex == 0) || (charcode < 0xf000)) {
return false;
}
return true;
}

View File

@ -33,6 +33,7 @@
#include <ft2build.h>
#include FT_FREETYPE_H
#include FT_TRUETYPE_IDS_H
#include <vector>
#include <string>
@ -60,6 +61,7 @@ typedef std::vector<FontInfo> FontInfoList;
class FontCache {
public:
const static std::string DEFAULT_FONT;
const static unsigned int MAX_NR_OF_CACHE_ENTRIES = 3;
FontCache();
@ -67,6 +69,7 @@ public:
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);
void clear();
FontInfoList * list_fonts();
@ -84,14 +87,13 @@ private:
FT_Library library;
void check_cleanup();
void dump_cache(std::string info);
void dump_cache(const std::string info);
void add_font_dir(std::string path);
void add_font_dir(const std::string path);
void init_pattern(FcPattern *pattern);
FT_Face find_face(std::string font);
FT_Face find_face_fontconfig(std::string font);
FT_Face find_face_in_path_list(std::string font);
FT_Face find_face_in_path(std::string path, std::string font);
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);
};

View File

@ -24,12 +24,16 @@
*
*/
#include <QClipboard>
#include <QSortFilterProxyModel>
#include "FontListDialog.h"
#include "FontCache.h"
FontListDialog::FontListDialog()
{
model = NULL;
proxy = NULL;
setupUi(this);
connect(this->okButton, SIGNAL(clicked()), this, SLOT(accept()));
}
@ -38,14 +42,48 @@ FontListDialog::~FontListDialog()
{
}
void FontListDialog::on_copyButton_clicked()
{
font_selected(selection);
QClipboard *clipboard = QApplication::clipboard();
clipboard->setText(selection);
}
void FontListDialog::on_filterLineEdit_textChanged(const QString &text)
{
proxy->setFilterWildcard(text);
}
void FontListDialog::selection_changed(const QItemSelection &current, const QItemSelection &)
{
if (current.count() == 0) {
copyButton->setEnabled(false);
return;
}
const QModelIndex &idx = proxy->mapToSource(current.indexes().at(0));
const QString name = model->item(idx.row(), 0)->text();
const QString style = model->item(idx.row(), 1)->text();
selection = QString("\"%1:style=%2\"").arg(name).arg(style);
copyButton->setEnabled(true);
}
void FontListDialog::update_font_list()
{
copyButton->setEnabled(false);
if (proxy) {
delete proxy;
proxy = NULL;
}
if (model) {
delete model;
model = NULL;
}
FontInfoList *list = FontCache::instance()->list_fonts();
QStandardItemModel *model = new QStandardItemModel(list->size(), 3, this);
model = new QStandardItemModel(list->size(), 3, this);
model->setHorizontalHeaderItem(0, new QStandardItem(QString("Font name")));
model->setHorizontalHeaderItem(1, new QStandardItem(QString("Font style")));
model->setHorizontalHeaderItem(2, new QStandardItem(QString("Filename")));
@ -63,9 +101,18 @@ void FontListDialog::update_font_list()
file->setEditable(false);
model->setItem(idx, 2, file);
}
this->tableView->setModel(model);
proxy = new QSortFilterProxyModel(this);
proxy->setSourceModel(model);
proxy->setFilterCaseSensitivity(Qt::CaseInsensitive);
this->tableView->setModel(proxy);
this->tableView->setSelectionMode(QAbstractItemView::SingleSelection);
this->tableView->sortByColumn(0, Qt::AscendingOrder);
this->tableView->resizeColumnsToContents();
this->tableView->setSortingEnabled(true);
connect(tableView->selectionModel(), SIGNAL(selectionChanged(const QItemSelection &, const QItemSelection &)), this, SLOT(selection_changed(const QItemSelection &, const QItemSelection &)));
delete list;
}

View File

@ -1,6 +1,7 @@
#pragma once
#include <QStandardItemModel>
#include <QSortFilterProxyModel>
#include "ui_FontListDialog.h"
@ -15,6 +16,17 @@ public:
virtual ~FontListDialog();
void update_font_list();
public slots:
void on_copyButton_clicked();
void on_filterLineEdit_textChanged(const QString &);
void selection_changed(const QItemSelection &, const QItemSelection &);
signals:
void font_selected(const QString font);
private:
QString selection;
QStandardItemModel *model;
QSortFilterProxyModel *proxy;
};

View File

@ -6,31 +6,21 @@
<rect>
<x>0</x>
<y>0</y>
<width>859</width>
<height>467</height>
<width>762</width>
<height>449</height>
</rect>
</property>
<property name="windowTitle">
<string>OpenSCAD Font List</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QLabel" name="label">
<property name="text">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;This list shows the fonts currently registered with OpenSCAD.&lt;/p&gt;&lt;p&gt;Example:&lt;/p&gt;&lt;pre style=&quot; margin-top:12px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-family:'Courier New,courier';&quot;&gt; text(t = &amp;quot;OpenSCAD&amp;quot;, font = &amp;quot;DejaVu Sans&amp;quot;);&lt;/span&gt;&lt;/pre&gt;&lt;pre style=&quot; margin-top:0px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-family:'Courier New,courier';&quot;&gt; text(t = &amp;quot;OpenSCAD&amp;quot;, font = &amp;quot;Liberation Sans:style=Italic&amp;quot;);&lt;/span&gt;&lt;/pre&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="textFormat">
<enum>Qt::RichText</enum>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QTableView" name="tableView"/>
</item>
<item alignment="Qt::AlignRight">
<layout class="QGridLayout" name="gridLayout">
<property name="horizontalSpacing">
<number>16</number>
</property>
<property name="verticalSpacing">
<number>6</number>
</property>
<item row="4" column="4">
<widget class="QPushButton" name="okButton">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Fixed">
@ -43,6 +33,74 @@
</property>
</widget>
</item>
<item row="4" column="3">
<widget class="QPushButton" name="copyButton">
<property name="toolTip">
<string>Paste font selector to Editor Window</string>
</property>
<property name="text">
<string>Copy to Clipboard</string>
</property>
</widget>
</item>
<item row="4" column="2">
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Fixed</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item row="4" column="1">
<widget class="QLineEdit" name="filterLineEdit"/>
</item>
<item row="4" column="0">
<widget class="QLabel" name="label_2">
<property name="text">
<string>Filter:</string>
</property>
</widget>
</item>
<item row="2" column="0" colspan="5">
<widget class="QTableView" name="tableView"/>
</item>
<item row="0" column="0" colspan="5">
<widget class="QLabel" name="label">
<property name="text">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;This list shows the fonts currently registered with OpenSCAD.&lt;/p&gt;&lt;p&gt;Example:&lt;/p&gt;&lt;pre style=&quot; margin-top:12px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-family:'Courier New,courier';&quot;&gt; text(t = &amp;quot;OpenSCAD&amp;quot;, font = &amp;quot;DejaVu Sans&amp;quot;);&lt;/span&gt;&lt;/pre&gt;&lt;pre style=&quot; margin-top:0px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-family:'Courier New,courier';&quot;&gt; text(t = &amp;quot;OpenSCAD&amp;quot;, font = &amp;quot;Liberation Sans:style=Italic&amp;quot;);&lt;/span&gt;&lt;/pre&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="textFormat">
<enum>Qt::RichText</enum>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
<item row="1" column="0">
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Fixed</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>6</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
<resources>

View File

@ -28,6 +28,8 @@
#include <iostream>
#include <glib.h>
#include <fontconfig/fontconfig.h>
#include "printutils.h"
@ -124,7 +126,7 @@ std::vector<const Geometry *> FreetypeRenderer::render(const FreetypeRenderer::P
{
FT_Face face;
FT_Error error;
DrawingCallback callback(params.fn);
DrawingCallback callback(params.segments);
FontCache *cache = FontCache::instance();
if (!cache->is_init_ok()) {
@ -148,7 +150,32 @@ std::vector<const Geometry *> FreetypeRenderer::render(const FreetypeRenderer::P
hb_buffer_set_direction(hb_buf, hb_direction_from_string(params.direction.c_str(), -1));
hb_buffer_set_script(hb_buf, hb_script_from_string(params.script.c_str(), -1));
hb_buffer_set_language(hb_buf, hb_language_from_string(params.language.c_str(), -1));
hb_buffer_add_utf8(hb_buf, params.text.c_str(), strlen(params.text.c_str()), 0, strlen(params.text.c_str()));
if (FontCache::instance()->is_windows_symbol_font(face)) {
// Special handling for symbol fonts like Webdings.
// see http://www.microsoft.com/typography/otspec/recom.htm
//
// We go through the string char by char and if the codepoint
// value is between 0x00 and 0xff, then the codepoint is translated
// to the 0xf000 page (Private Use Area of Unicode). All other
// values are untouched, so using the correct codepoint directly
// (e.g. \uf021 for the spider in Webdings) still works.
const char *p = params.text.c_str();
if (g_utf8_validate(p, -1, NULL)) {
char buf[8];
while (*p != 0) {
memset(buf, 0, 8);
gunichar c = g_utf8_get_char(p);
c = (c < 0x0100) ? 0xf000 + c : c;
g_unichar_to_utf8(c, buf);
hb_buffer_add_utf8(hb_buf, buf, strlen(buf), 0, strlen(buf));
p = g_utf8_next_char(p);
}
} else {
PRINTB("Warning: Ignoring text with invalid UTF-8 encoding: \"%s\"", params.text.c_str());
}
} else {
hb_buffer_add_utf8(hb_buf, params.text.c_str(), strlen(params.text.c_str()), 0, strlen(params.text.c_str()));
}
hb_shape(hb_ft_font, hb_buf, NULL, 0);
unsigned int glyph_count;

View File

@ -47,6 +47,15 @@ public:
void set_fn(double fn) {
this->fn = fn;
}
void set_fa(double fa) {
this->fa = fa;
}
void set_fs(double fs) {
this->fs = fs;
}
void set_segments(double segments) {
this->segments = segments;
}
void set_text(std::string text) {
this->text = text;
}
@ -70,20 +79,21 @@ public:
}
friend std::ostream & operator << (std::ostream &stream, const FreetypeRenderer::Params &params) {
return stream
<< "$fn = " << params.fn
<< ", text = '" << params.text
<< "', size = " << params.size
<< "text = \"" << params.text
<< "\", size = " << params.size
<< ", spacing = " << params.spacing
<< ", font = '" << params.font
<< "', direction = '" << params.direction
<< "', language = '" << params.language
<< "', script = '" << params.script
<< "', halign = '" << params.halign
<< "', valign = '" << params.valign
<< "'";
<< ", font = \"" << params.font
<< "\", direction = \"" << params.direction
<< "\", language = \"" << params.language
<< "\", script = \"" << params.script
<< "\", halign = \"" << params.halign
<< "\", valign = \"" << params.valign
<< "\", $fn = " << params.fn
<< ", $fa = " << params.fa
<< ", $fs = " << params.fs;
}
private:
double size, spacing, fn;
double size, spacing, fn, fa, fs, segments;
std::string text, font, direction, language, script, halign, valign;
friend class FreetypeRenderer;

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();
@ -424,7 +455,7 @@ void GLView::showAxes()
glLineWidth(this->getDPI());
glColor3d(0.5, 0.5, 0.5);
glBegin(GL_LINES);
double l = cam.viewer_distance;
double l = cam.projection == Camera::PERSPECTIVE ? cam.viewer_distance : cam.height;
glVertex3d(-l, 0, 0);
glVertex3d(+l, 0, 0);
glVertex3d(0, -l, 0);
@ -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

@ -21,6 +21,7 @@ public:
virtual std::string dump() const = 0;
virtual unsigned int getDimension() const = 0;
virtual bool isEmpty() const = 0;
virtual Geometry *copy() const = 0;
unsigned int getConvexity() const { return convexity; }
void setConvexity(int c) { this->convexity = c; }

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);
}
}
@ -161,53 +168,6 @@ Geometry *GeometryEvaluator::applyHull3D(const AbstractNode &node)
return NULL;
}
void GeometryEvaluator::applyResize3D(CGAL_Nef_polyhedron &N,
const Vector3d &newsize,
const Eigen::Matrix<bool,3,1> &autosize)
{
// Based on resize() in Giles Bathgate's RapCAD (but not exactly)
if (N.isEmpty()) return;
CGAL_Iso_cuboid_3 bb = CGALUtils::boundingBox(*N.p3);
std::vector<NT3> scale, bbox_size;
for (unsigned int i=0;i<3;i++) {
scale.push_back(NT3(1));
bbox_size.push_back(bb.max_coord(i) - bb.min_coord(i));
}
int newsizemax_index = 0;
for (unsigned int i=0;i<N.getDimension();i++) {
if (newsize[i]) {
if (bbox_size[i] == NT3(0)) {
PRINT("WARNING: Resize in direction normal to flat object is not implemented");
return;
}
else {
scale[i] = NT3(newsize[i]) / bbox_size[i];
}
if (newsize[i] > newsize[newsizemax_index]) newsizemax_index = i;
}
}
NT3 autoscale = NT3(1);
if (newsize[newsizemax_index] != 0) {
autoscale = NT3(newsize[newsizemax_index]) / bbox_size[newsizemax_index];
}
for (unsigned int i=0;i<N.getDimension();i++) {
if (autosize[i] && newsize[i]==0) scale[i] = autoscale;
}
Eigen::Matrix4d t;
t << CGAL::to_double(scale[0]), 0, 0, 0,
0, CGAL::to_double(scale[1]), 0, 0,
0, 0, CGAL::to_double(scale[2]), 0,
0, 0, 0, 1;
N.transform(Transform3d(t));
return;
}
Polygon2d *GeometryEvaluator::applyMinkowski2D(const AbstractNode &node)
{
std::vector<const Polygon2d *> children = collectChildren2D(node);
@ -457,7 +417,7 @@ Response GeometryEvaluator::visit(State &state, const RenderNode &node)
else if (shared_ptr<const CGAL_Nef_polyhedron> N = dynamic_pointer_cast<const CGAL_Nef_polyhedron>(geom)) {
// If we got a const object, make a copy
shared_ptr<CGAL_Nef_polyhedron> newN;
if (res.isConst()) newN.reset(N->copy());
if (res.isConst()) newN.reset((CGAL_Nef_polyhedron*)N->copy());
else newN = dynamic_pointer_cast<CGAL_Nef_polyhedron>(res.ptr());
newN->setConvexity(node.convexity);
geom = newN;
@ -594,7 +554,7 @@ Response GeometryEvaluator::visit(State &state, const TransformNode &node)
assert(N);
// If we got a const object, make a copy
shared_ptr<CGAL_Nef_polyhedron> newN;
if (res.isConst()) newN.reset(N->copy());
if (res.isConst()) newN.reset((CGAL_Nef_polyhedron*)N->copy());
else newN = dynamic_pointer_cast<CGAL_Nef_polyhedron>(res.ptr());
newN->transform(node.matrix);
geom = newN;
@ -707,7 +667,7 @@ static Geometry *extrudePolygon(const LinearExtrudeNode &node, const Polygon2d &
ps->append(*ps_top);
delete ps_top;
}
size_t slices = node.has_twist ? node.slices : 1;
size_t slices = node.slices;
for (unsigned int j = 0; j < slices; j++) {
double rot1 = node.twist*j / slices;
@ -920,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
@ -934,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);
@ -962,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);
@ -995,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: {
@ -1005,40 +982,31 @@ Response GeometryEvaluator::visit(State &state, const CgaladvNode &node)
case RESIZE: {
ResultObject res = applyToChildren(node, OPENSCAD_UNION);
geom = res.constptr();
shared_ptr<const CGAL_Nef_polyhedron> N = dynamic_pointer_cast<const CGAL_Nef_polyhedron>(res.constptr());
if (N) {
if (geom) {
shared_ptr<Geometry> editablegeom;
// If we got a const object, make a copy
shared_ptr<CGAL_Nef_polyhedron> newN;
if (res.isConst()) newN.reset(N->copy());
else newN = dynamic_pointer_cast<CGAL_Nef_polyhedron>(res.ptr());
applyResize3D(*newN, node.newsize, node.autosize);
geom = newN;
}
else {
shared_ptr<const Polygon2d> poly = dynamic_pointer_cast<const Polygon2d>(res.constptr());
if (poly) {
// If we got a const object, make a copy
shared_ptr<Polygon2d> newpoly;
if (res.isConst()) newpoly.reset(new Polygon2d(*poly));
else newpoly = dynamic_pointer_cast<Polygon2d>(res.ptr());
if (res.isConst()) editablegeom.reset(geom->copy());
else editablegeom = res.ptr();
geom = editablegeom;
newpoly->resize(Vector2d(node.newsize[0], node.newsize[1]),
Eigen::Matrix<bool,2,1>(node.autosize[0], node.autosize[1]));
shared_ptr<CGAL_Nef_polyhedron> N = dynamic_pointer_cast<CGAL_Nef_polyhedron>(editablegeom);
if (N) {
N->resize(node.newsize, node.autosize);
}
else {
shared_ptr<const PolySet> ps = dynamic_pointer_cast<const PolySet>(res.constptr());
if (ps) {
// If we got a const object, make a copy
shared_ptr<PolySet> newps;
if (res.isConst()) newps.reset(new PolySet(*ps));
else newps = dynamic_pointer_cast<PolySet>(res.ptr());
newps->resize(node.newsize, node.autosize);
geom = newps;
shared_ptr<Polygon2d> poly = dynamic_pointer_cast<Polygon2d>(editablegeom);
if (poly) {
poly->resize(Vector2d(node.newsize[0], node.newsize[1]),
Eigen::Matrix<bool,2,1>(node.autosize[0], node.autosize[1]));
}
else {
assert(false);
shared_ptr<PolySet> ps = dynamic_pointer_cast<PolySet>(editablegeom);
if (ps) {
ps->resize(node.newsize, node.autosize);
}
else {
assert(false);
}
}
}
}

102
src/LibraryInfo.cc Normal file
View File

@ -0,0 +1,102 @@
#include "LibraryInfo.h"
#include <glib.h>
#include <vector>
#include "version_check.h"
#define STRINGIFY(x) #x
#define TOSTRING(x) STRINGIFY(x)
#ifdef ENABLE_CGAL
#include "cgal.h"
#include <boost/algorithm/string.hpp>
#if defined(__GNUG__)
#define GCC_INT_VERSION (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 )
#if GCC_INT_VERSION > 40600 || defined(__clang__)
#include <cxxabi.h>
#define __openscad_info_demangle__ 1
#endif // GCC_INT_VERSION
#endif // GNUG
#endif // ENABLE_CGAL
extern std::vector<std::string> librarypath;
extern std::vector<std::string> fontpath;
std::string LibraryInfo::info()
{
std::stringstream s;
#if defined(__GNUG__) && !defined(__clang__)
std::string compiler_info( "GCC " + std::string(TOSTRING(__VERSION__)) );
#elif defined(_MSC_VER)
std::string compiler_info( "MSVC " + std::string(TOSTRING(_MSC_FULL_VER)) );
#elif defined(__clang__)
std::string compiler_info( "Clang " + std::string(TOSTRING(__clang_version__)) );
#else
std::string compiler_info( "unknown compiler" );
#endif
#if defined( __MINGW64__ )
std::string mingwstatus("MingW64");
#elif defined( __MINGW32__ )
std::string mingwstatus("MingW32");
#else
std::string mingwstatus("No");
#endif
#ifndef OPENCSG_VERSION_STRING
#define OPENCSG_VERSION_STRING "unknown, <1.3.2"
#endif
#ifdef QT_VERSION
std::string qtVersion = qVersion();
#else
std::string qtVersion = "Qt disabled - Commandline Test Version";
#endif
#ifdef ENABLE_CGAL
std::string cgal_3d_kernel = typeid(CGAL_Kernel3).name();
std::string cgal_2d_kernel = typeid(CGAL_Kernel2).name();
std::string cgal_2d_kernelEx = typeid(CGAL_ExactKernel2).name();
#if defined(__openscad_info_demangle__)
int status;
cgal_3d_kernel = std::string( abi::__cxa_demangle( cgal_3d_kernel.c_str(), 0, 0, &status ) );
cgal_2d_kernel = std::string( abi::__cxa_demangle( cgal_2d_kernel.c_str(), 0, 0, &status ) );
cgal_2d_kernelEx = std::string( abi::__cxa_demangle( cgal_2d_kernelEx.c_str(), 0, 0, &status ) );
#endif // demangle
boost::replace_all( cgal_3d_kernel, "CGAL::", "" );
boost::replace_all( cgal_2d_kernel, "CGAL::", "" );
boost::replace_all( cgal_2d_kernelEx, "CGAL::", "" );
#else // ENABLE_CGAL
std::string cgal_3d_kernel = "";
std::string cgal_2d_kernel = "";
std::string cgal_2d_kernelEx = "";
#endif // ENABLE_CGAL
const char *env_path = getenv("OPENSCADPATH");
const char *env_font_path = getenv("OPENSCAD_FONT_PATH");
s << "OpenSCAD Version: " << TOSTRING(OPENSCAD_VERSION)
<< "\nCompiler, build date: " << compiler_info << ", " << __DATE__
<< "\nBoost version: " << BOOST_LIB_VERSION
<< "\nEigen version: " << EIGEN_WORLD_VERSION << "." << EIGEN_MAJOR_VERSION << "." << EIGEN_MINOR_VERSION
<< "\nCGAL version, kernels: " << TOSTRING(CGAL_VERSION) << ", " << cgal_3d_kernel << ", " << cgal_2d_kernel << ", " << cgal_2d_kernelEx
<< "\nOpenCSG version: " << OPENCSG_VERSION_STRING
<< "\nQt version: " << qtVersion
<< "\nMingW build: " << mingwstatus
<< "\nGLib version: " << GLIB_MAJOR_VERSION << "." << GLIB_MINOR_VERSION << "." << GLIB_MICRO_VERSION
<< "\nOPENSCADPATH: " << (env_path == NULL ? "<not set>" : env_path)
<< "\nOpenSCAD library path:\n";
for (std::vector<std::string>::iterator it = librarypath.begin();it != librarypath.end();it++) {
s << " " << *it << "\n";
}
s << "\nOPENSCAD_FONT_PATH: " << (env_font_path == NULL ? "<not set>" : env_font_path)
<< "\nOpenSCAD font path:\n";
for (std::vector<std::string>::iterator it = fontpath.begin();it != fontpath.end();it++) {
s << " " << *it << "\n";
}
return s.str();
}

7
src/LibraryInfo.h Normal file
View File

@ -0,0 +1,7 @@
#pragma once
#include <string>
namespace LibraryInfo {
std::string info();
}

View File

@ -79,6 +79,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();

View File

@ -84,10 +84,10 @@ bool ModuleCache::evaluate(const std::string &filename, FileModule *&module)
if (shouldCompile) {
#ifdef DEBUG
if (found) {
PRINTB("Recompiling cached library: %s (%s)", filename % cache_id);
PRINTDB("Recompiling cached library: %s (%s)", filename % cache_id);
}
else {
PRINTB("Compiling library '%s'.", filename);
PRINTDB("Compiling library '%s'.", filename);
}
#endif
@ -108,7 +108,7 @@ bool ModuleCache::evaluate(const std::string &filename, FileModule *&module)
std::string pathname = boosty::stringy(fs::path(filename).parent_path());
lib_mod = dynamic_cast<FileModule*>(parse(textbuf.str().c_str(), pathname.c_str(), false));
PRINTB_NOCACHE(" compiled module: %p", lib_mod);
PRINTDB(" compiled module: %p", lib_mod);
// We defer deletion so we can ensure that the new module won't
// have the same address as the old

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,14 +1,27 @@
#include <glib.h>
#include "PlatformUtils.h"
#include "boosty.h"
#include <Eigen/Core>
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))) {
@ -24,7 +37,7 @@ bool PlatformUtils::createLibraryPath()
return OK;
}
std::string PlatformUtils::libraryPath()
std::string PlatformUtils::userLibraryPath()
{
fs::path path;
try {
@ -78,90 +91,36 @@ bool PlatformUtils::createBackupPath()
return OK;
}
#include "version_check.h"
#define STRINGIFY(x) #x
#define TOSTRING(x) STRINGIFY(x)
#ifdef ENABLE_CGAL
#include "cgal.h"
#include <boost/algorithm/string.hpp>
#if defined(__GNUG__)
#define GCC_INT_VERSION (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 )
#if GCC_INT_VERSION > 40600 || defined(__clang__)
#include <cxxabi.h>
#define __openscad_info_demangle__ 1
#endif // GCC_INT_VERSION
#endif // GNUG
#endif // ENABLE_CGAL
std::string PlatformUtils::info()
// This is the built-in read-only resources path
std::string PlatformUtils::resourcesPath()
{
std::stringstream s;
#if defined(__GNUG__) && !defined(__clang__)
std::string compiler_info( "GCC " + std::string(TOSTRING(__VERSION__)) );
#elif defined(_MSC_VER)
std::string compiler_info( "MSVC " + std::string(TOSTRING(_MSC_FULL_VER)) );
#elif defined(__clang__)
std::string compiler_info( "Clang " + std::string(TOSTRING(__clang_version__)) );
#else
std::string compiler_info( "unknown compiler" );
#endif
#if defined( __MINGW64__ )
std::string mingwstatus("MingW64");
#elif defined( __MINGW32__ )
std::string mingwstatus("MingW32");
#else
std::string mingwstatus("No");
#endif
#ifndef OPENCSG_VERSION_STRING
#define OPENCSG_VERSION_STRING "unknown, <1.3.2"
#endif
#ifdef QT_VERSION
std::string qtVersion = qVersion();
#else
std::string qtVersion = "Qt disabled - Commandline Test Version";
#endif
#ifdef ENABLE_CGAL
std::string cgal_3d_kernel = typeid(CGAL_Kernel3).name();
std::string cgal_2d_kernel = typeid(CGAL_Kernel2).name();
std::string cgal_2d_kernelEx = typeid(CGAL_ExactKernel2).name();
#if defined(__openscad_info_demangle__)
int status;
cgal_3d_kernel = std::string( abi::__cxa_demangle( cgal_3d_kernel.c_str(), 0, 0, &status ) );
cgal_2d_kernel = std::string( abi::__cxa_demangle( cgal_2d_kernel.c_str(), 0, 0, &status ) );
cgal_2d_kernelEx = std::string( abi::__cxa_demangle( cgal_2d_kernelEx.c_str(), 0, 0, &status ) );
#endif // demangle
boost::replace_all( cgal_3d_kernel, "CGAL::", "" );
boost::replace_all( cgal_2d_kernel, "CGAL::", "" );
boost::replace_all( cgal_2d_kernelEx, "CGAL::", "" );
#else // ENABLE_CGAL
std::string cgal_3d_kernel = "";
std::string cgal_2d_kernel = "";
std::string cgal_2d_kernelEx = "";
#endif // ENABLE_CGAL
const char *env_path = getenv("OPENSCADPATH");
s << "OpenSCAD Version: " << TOSTRING(OPENSCAD_VERSION)
<< "\nCompiler, build date: " << compiler_info << ", " << __DATE__
<< "\nBoost version: " << BOOST_LIB_VERSION
<< "\nEigen version: " << EIGEN_WORLD_VERSION << "." << EIGEN_MAJOR_VERSION << "." << EIGEN_MINOR_VERSION
<< "\nCGAL version, kernels: " << TOSTRING(CGAL_VERSION) << ", " << cgal_3d_kernel << ", " << cgal_2d_kernel << ", " << cgal_2d_kernelEx
<< "\nOpenCSG version: " << OPENCSG_VERSION_STRING
<< "\nQt version: " << qtVersion
<< "\nMingW build: " << mingwstatus
<< "\nGLib version: " << GLIB_MAJOR_VERSION << "." << GLIB_MINOR_VERSION << "." << GLIB_MICRO_VERSION
<< "\nOPENSCADPATH: " << (env_path == NULL ? "<not set>" : env_path)
<< "\nOpenSCAD library path:\n";
for (std::vector<std::string>::iterator it = librarypath.begin();it != librarypath.end();it++) {
s << " " << *it << "\n";
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 /= "../../..";
}
return s.str();
#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));
}

View File

@ -4,22 +4,25 @@
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();
std::string info();
/**
* 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();
/**
* 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;
@ -19,6 +23,7 @@ public:
virtual std::string dump() const;
virtual unsigned int getDimension() const { return 2; }
virtual bool isEmpty() const;
virtual Geometry *copy() const { return new Polygon2d(*this); }
void addOutline(const Outline2d &outline) { this->theoutlines.push_back(outline); }
class PolySet *tessellate() const;

View File

@ -37,6 +37,8 @@
#ifdef ENABLE_CGAL
#include "CGALCache.h"
#endif
#include "colormap.h"
#include "rendersettings.h"
Preferences *Preferences::instance = NULL;
@ -87,7 +89,6 @@ Preferences::Preferences(QWidget *parent) : QMainWindow(parent)
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 +121,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);
@ -163,8 +133,6 @@ Preferences::Preferences(QWidget *parent) : QMainWindow(parent)
setupFeaturesPage();
updateGUI();
RenderSettings::inst()->setColors(this->colorschemes[getValue("3dview/colorscheme").toString()]);
}
Preferences::~Preferences()
@ -275,10 +243,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)

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
{
@ -43,6 +41,7 @@ signals:
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);
@ -55,7 +54,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

@ -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>
@ -89,6 +115,9 @@
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Expanding</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
@ -170,7 +199,7 @@
<number>0</number>
</property>
<item>
<widget class="QLabel" name="label_9">
<widget class="QLabel" name="label_syntax_h">
<property name="font">
<font>
<weight>75</weight>

View File

@ -178,18 +178,44 @@ void QGLView::paintGL()
if (running_under_wine) swapBuffers();
}
void QGLView::wheelEvent(QWheelEvent *event)
{
cam.viewer_distance *= pow(0.9, event->delta() / 120.0);
updateGL();
}
void QGLView::mousePressEvent(QMouseEvent *event)
{
mouse_drag_active = true;
last_mouse = event->globalPos();
}
void QGLView::mouseDoubleClickEvent (QMouseEvent *event) {
setupCamera();
int viewport[4];
GLdouble modelview[16];
GLdouble projection[16];
glGetIntegerv( GL_VIEWPORT, viewport);
glGetDoublev(GL_MODELVIEW_MATRIX, modelview);
glGetDoublev(GL_PROJECTION_MATRIX, projection);
double x = event->pos().x();
double y = viewport[3] - event->pos().y();
GLfloat z = 0;
glReadPixels(x, y, 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT, &z);
if (z == 1) return; // outside object
GLdouble px, py, pz;
GLint success = gluUnProject(x, y, z, modelview, projection, viewport, &px, &py, &pz);
if (success == GL_TRUE) {
cam.object_trans.x() = -px;
cam.object_trans.y() = -py;
cam.object_trans.z() = -pz;
updateGL();
emit doAnimateUpdate();
}
}
void QGLView::normalizeAngle(GLdouble& angle)
{
while(angle < 0)
@ -286,14 +312,25 @@ bool QGLView::save(const char *filename)
return img.save(filename, "PNG");
}
void QGLView::wheelEvent(QWheelEvent *event)
{
this->cam.zoom(event->delta());
updateGL();
}
void QGLView::ZoomIn(void)
{
cam.viewer_distance *= 0.9;
this->cam.zoom(120);
updateGL();
}
void QGLView::ZoomOut(void)
{
cam.viewer_distance /= 0.9;
this->cam.zoom(-120);
updateGL();
}
void QGLView::setOrthoMode(bool enabled) {
if (enabled) this->cam.setProjection(Camera::ORTHOGONAL);
else this->cam.setProjection(Camera::PERSPECTIVE);
}

View File

@ -34,10 +34,7 @@ public:
bool showCrosshairs() const { return this->showcrosshairs; }
void setShowCrosshairs(bool enabled) { this->showcrosshairs = enabled; }
bool orthoMode() const { return (this->cam.projection == Camera::ORTHOGONAL); }
void setOrthoMode(bool enabled) {
if (enabled) this->cam.projection = Camera::ORTHOGONAL;
else this->cam.projection = Camera::PERSPECTIVE;
}
void setOrthoMode(bool enabled);
std::string getRendererInfo() const;
#if QT_VERSION >= 0x050100
float getDPI() { return this->devicePixelRatio(); }
@ -63,6 +60,7 @@ private:
void mousePressEvent(QMouseEvent *event);
void mouseMoveEvent(QMouseEvent *event);
void mouseReleaseEvent(QMouseEvent *event);
void mouseDoubleClickEvent(QMouseEvent *event);
void initializeGL();
void resizeGL(int w, int h);

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

@ -5,7 +5,7 @@
namespace ClipperUtils {
static const unsigned int CLIPPER_SCALE = 2 << 17;
static const unsigned int CLIPPER_SCALE = 1 << 16;
ClipperLib::Path fromOutline2d(const Outline2d &poly, bool keep_orientation);
ClipperLib::Paths fromPolygon2d(const Polygon2d &poly);

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,11 +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()) {
color = colormap[colorname];
node->color[0] = color[0];
node->color[1] = color[1];
node->color[2] = color[2];
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

@ -264,7 +264,12 @@ AbstractNode *ControlModule::instantiate(const Context* /*ctx*/, const ModuleIns
for (size_t i = 0; i < inst->arguments.size(); i++) {
if (i > 0) msg << ", ";
if (!evalctx->getArgName(i).empty()) msg << evalctx->getArgName(i) << " = ";
msg << evalctx->getArgValue(i);
Value val = evalctx->getArgValue(i);
if (val.type() == Value::STRING) {
msg << '"' << val.toString() << '"';
} else {
msg << val.toString();
}
}
PRINTB("%s", msg.str());
}

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
@ -230,10 +249,10 @@ void export_stl(const CGAL_Nef_polyhedron *root_N, std::ostream &output)
PRINT("Object isn't a valid 2-manifold! Modify your design.\n");
}
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

@ -8,19 +8,20 @@
#ifdef ENABLE_CGAL
#include "CGALRenderer.h"
#include "CGAL_renderer.h"
#include "cgal.h"
#include "cgalutils.h"
#include "CGAL_Nef_polyhedron.h"
static void setupCamera(Camera &cam, const BoundingBox &bbox, float scalefactor)
{
PRINTDB("setupCamera() %i",cam.type);
if (cam.type == Camera::NONE) cam.viewall = true;
if (cam.viewall) cam.viewAll(bbox, scalefactor);
}
void export_png(const Geometry *root_geom, Camera &cam, std::ostream &output)
{
PRINTD("export_png geom");
OffscreenView *glview;
try {
glview = new OffscreenView(cam.pixel_width, cam.pixel_height);
@ -36,6 +37,7 @@ void export_png(const Geometry *root_geom, Camera &cam, std::ostream &output)
glview->setCamera(cam);
glview->setRenderer(&cgalRenderer);
glview->setColorScheme(RenderSettings::inst()->colorscheme);
glview->paintGL();
glview->save(output);
}
@ -50,6 +52,7 @@ enum Previewer { OPENCSG, THROWNTOGETHER } previewer;
void export_png_preview_common(Tree &tree, Camera &cam, std::ostream &output, Previewer previewer = OPENCSG)
{
PRINTD("export_png_preview_common");
CsgInfo csgInfo = CsgInfo();
if (!csgInfo.compile_chains(tree)) {
fprintf(stderr,"Couldn't initialize CSG chains\n");
@ -82,12 +85,14 @@ 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);
}
void export_png_with_opencsg(Tree &tree, Camera &cam, std::ostream &output)
{
PRINTD("export_png_w_opencsg");
#ifdef ENABLE_OPENCSG
export_png_preview_common(tree, cam, output, OPENCSG);
#else
@ -97,6 +102,7 @@ void export_png_with_opencsg(Tree &tree, Camera &cam, std::ostream &output)
void export_png_with_throwntogether(Tree &tree, Camera &cam, std::ostream &output)
{
PRINTD("export_png_w_thrown");
export_png_preview_common(tree, cam, output, THROWNTOGETHER);
}

View File

@ -184,7 +184,11 @@ Value Expression::sub_evaluate_list_comprehension(const Context *context) const
if (this->call_funcname == "if") {
if (this->children[0]->evaluate(context)) {
vec.push_back(this->children[1]->evaluate(context));
if (this->children[1]->type == "c") {
return this->children[1]->evaluate(context);
} else {
vec.push_back(this->children[1]->evaluate(context));
}
}
return vec;
} else if (this->call_funcname == "for") {

View File

@ -18,7 +18,6 @@ Feature::list_t Feature::feature_list;
* argument to enable the option and for saving the option value in GUI
* context.
*/
const Feature Feature::ExperimentalConcatFunction("concat", "Enable the <code>concat()</code> function.");
const Feature Feature::ExperimentalTextModule("text", "Enable the <code>text()</code> module.");
Feature::Feature(const std::string &name, const std::string &description)

View File

@ -12,7 +12,6 @@ public:
typedef std::vector<Feature *> list_t;
typedef list_t::iterator iterator;
static const Feature ExperimentalConcatFunction;
static const Feature ExperimentalTextModule;
const std::string& get_name() const;

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,7 +939,8 @@ 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("concat", new BuiltinFunction(&builtin_concat, Feature::ExperimentalConcatFunction));
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));
Builtins::init("version", new BuiltinFunction(&builtin_version));

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.");

View File

@ -27,6 +27,5 @@ public:
int convexity;
double fn, fs, fa;
double origin_x, origin_y, scale;
virtual Geometry *evaluate_geometry(class PolySetEvaluator *) const { return createGeometry(); }
virtual Geometry *createGeometry() const;
virtual class Geometry *createGeometry() const;
};

View File

@ -26,6 +26,7 @@
%{
#include <glib.h>
#include "typedefs.h"
#include "handle_dep.h"
#include "printutils.h"
@ -77,6 +78,7 @@ extern FileModule *rootmodule;
} \
}
void to_utf8(const char *, char *);
void includefile();
fs::path sourcepath();
std::vector<fs::path> path_stack;
@ -91,12 +93,19 @@ std::string filepath;
%option yylineno
%option noyywrap
%x cond_comment cond_string
%x cond_comment cond_lcomment cond_string
%x cond_include
%x cond_use
D [0-9]
E [Ee][+-]?{D}+
H [0-9a-fA-F]
U [\x80-\xbf]
U2 [\xc2-\xdf]
U3 [\xe0-\xef]
U4 [\xf0-\xf4]
UNICODE {U2}{U}|{U3}{U}{U}|{U4}{U}{U}{U}
%%
@ -149,6 +158,16 @@ use[ \t\r\n>]*"<" { BEGIN(cond_use); }
"false" return TOK_FALSE;
"undef" return TOK_UNDEF;
%{/*
U+00A0 (UTF-8 encoded: C2A0) is no-break space. We support it since Qt's QTextEdit
automatically converts these to spaces and we want to be able to process the same
files on the cmd-line as in the editor.
*/%}
\xc2\xa0
{UNICODE}+ { parser_error_pos -= strlen(yytext); return TOK_ERROR; }
{D}+{E}? |
{D}*\.{D}+{E}? |
{D}+\.{D}*{E}? {
@ -166,22 +185,30 @@ use[ \t\r\n>]*"<" { BEGIN(cond_use); }
\\r { stringcontents += '\r'; }
\\\\ { stringcontents += '\\'; }
\\\" { stringcontents += '"'; }
[^\\\n\"]+ { stringcontents += lexertext; }
{UNICODE} { parser_error_pos -= strlen(lexertext) - 1; stringcontents += lexertext; }
\\x[0-7]{H} { unsigned long i = strtoul(lexertext + 2, NULL, 16); stringcontents += (i == 0 ? ' ' : (unsigned char)(i & 0xff)); }
\\u{H}{4}|\\U{H}{6} { char buf[8]; to_utf8(lexertext + 2, buf); stringcontents += buf; }
[^\\\n\"] { stringcontents += lexertext; }
\" { BEGIN(INITIAL);
parserlval.text = strdup(stringcontents.c_str());
return TOK_STRING; }
}
%{/*
C2A0 is no-break space. We support it since Qt's QTextEdit automatically converts these to
spaces and we want to be able to process the same files on the cmd-line as in the editor.
*/%}
[\n\r\t ]
\/\/ BEGIN(cond_lcomment);
<cond_lcomment>{
\n { BEGIN(INITIAL); }
{UNICODE} { parser_error_pos -= strlen(lexertext) - 1; }
[^\n]
}
[\n\r\t ]|\xc2\xa0
\/\/[^\n]*\n?
"/*" BEGIN(cond_comment);
<cond_comment>"*/" BEGIN(INITIAL);
<cond_comment>.|\n
<cond_comment>{
"*/" { BEGIN(INITIAL); }
{UNICODE} { parser_error_pos -= strlen(lexertext) - 1; }
.|\n
}
"<=" return LE;
">=" return GE;
@ -194,6 +221,22 @@ use[ \t\r\n>]*"<" { BEGIN(cond_use); }
%%
/*!
* Convert unicode codepoint given in hex notation
* into UTF8 encoding. The output buffer must be 8
* characters long.
*/
void to_utf8(const char *str, char *out)
{
memset(out, 0, 8);
const gunichar c = strtoul(str, NULL, 16);
if (g_unichar_validate(c) && (c != 0)) {
g_unichar_to_utf8(c, out);
} else {
out[0] = ' ';
}
}
fs::path sourcepath()
{
if (!path_stack.empty()) return path_stack.back();
@ -218,7 +261,6 @@ void includefile()
else {
rootmodule->registerInclude(boosty::stringy(localpath), boosty::stringy(localpath));
PRINTB("WARNING: Can't open include file '%s'.", boosty::stringy(localpath));
if (path_stack.size() > 0) path_stack.pop_back();
return;
};

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

@ -108,18 +108,19 @@ AbstractNode *LinearExtrudeModule::instantiate(const Context *ctx, const ModuleI
if (node->scale_x < 0) node->scale_x = 0;
if (node->scale_y < 0) node->scale_y = 0;
if (slices.type() == Value::NUMBER) node->slices = (int)slices.toDouble();
if (twist.type() == Value::NUMBER) {
node->twist = twist.toDouble();
if (node->twist != 0.0) {
if (slices.type() == Value::NUMBER) {
node->slices = (int)slices.toDouble();
} else {
if (node->slices == 0) {
node->slices = (int)fmax(2, fabs(Calc::get_fragments_from_r(node->height,
node->fn, node->fs, node->fa) * node->twist / 360));
}
node->has_twist = true;
}
}
node->slices = std::max(node->slices, 1);
if (node->filename.empty()) {
std::vector<AbstractNode *> instantiatednodes = inst->instantiateChildren(evalctx);
@ -152,7 +153,10 @@ std::string LinearExtrudeNode::toString() const
"convexity = " << this->convexity;
if (this->has_twist) {
stream << ", twist = " << this->twist << ", slices = " << this->slices;
stream << ", twist = " << this->twist;
}
if (this->slices > 1) {
stream << ", slices = " << this->slices;
}
stream << ", scale = [" << this->scale_x << ", " << this->scale_y << "]";
stream << ", $fn = " << this->fn << ", $fa = " << this->fa << ", $fs = " << this->fs << ")";

View File

@ -28,6 +28,7 @@
#include "ModuleCache.h"
#include "MainWindow.h"
#include "parsersettings.h"
#include "rendersettings.h"
#include "Preferences.h"
#include "printutils.h"
#include "node.h"
@ -55,6 +56,7 @@
#include "CocoaUtils.h"
#endif
#include "PlatformUtils.h"
#include "LibraryInfo.h"
#include <QMenu>
#include <QTime>
@ -97,10 +99,6 @@
#include "cgalworker.h"
#include "cgalutils.h"
#else
#include "PolySetEvaluator.h"
#endif // ENABLE_CGAL
#include "boosty.h"
@ -401,7 +399,6 @@ MainWindow::MainWindow(const QString &filename)
connect(editor->document(), SIGNAL(contentsChanged()), this, SLOT(animateUpdateDocChanged()));
connect(editor->document(), SIGNAL(modificationChanged(bool)), this, SLOT(setWindowModified(bool)));
connect(editor->document(), SIGNAL(modificationChanged(bool)), fileActionSave, SLOT(setEnabled(bool)));
connect(this->qglview, SIGNAL(doAnimateUpdate()), this, SLOT(animateUpdate()));
connect(Preferences::inst(), SIGNAL(requestRedraw()), this->qglview, SLOT(updateGL()));
@ -413,8 +410,13 @@ MainWindow::MainWindow(const QString &filename)
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);
connect(this->findTypeComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(selectFindType(int)));
connect(this->findInputField, SIGNAL(returnPressed()), this->nextButton, SLOT(animateClick()));
find_panel->installEventFilter(this);
@ -1171,6 +1173,8 @@ void MainWindow::actionSave()
actionSaveAs();
}
else {
if (!editor->isContentModified())
return;
setCurrentOutput();
QFile file(this->fileName);
if (!file.open(QIODevice::WriteOnly | QIODevice::Truncate | QIODevice::Text)) {
@ -1217,16 +1221,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()
@ -1381,17 +1385,24 @@ void MainWindow::updateCamera()
return;
bool camera_set = false;
double tx = qglview->cam.object_trans.x();
double ty = qglview->cam.object_trans.y();
double tz = qglview->cam.object_trans.z();
double rx = qglview->cam.object_rot.x();
double ry = qglview->cam.object_rot.y();
double rz = qglview->cam.object_rot.z();
double d = qglview->cam.viewer_distance;
Camera cam(qglview->cam);
cam.gimbalDefaultTranslate();
double tx = cam.object_trans.x();
double ty = cam.object_trans.y();
double tz = cam.object_trans.z();
double rx = cam.object_rot.x();
double ry = cam.object_rot.y();
double rz = cam.object_rot.z();
double d = cam.viewer_distance;
ModuleContext mc(&top_ctx, NULL);
mc.initializeModule(*root_module);
BOOST_FOREACH(const Assignment &a, root_module->scope.assignments) {
double x, y, z;
if ("$vpr" == a.first) {
const Value vpr = a.second.get()->evaluate(&top_ctx);
const Value vpr = a.second.get()->evaluate(&mc);
if (vpr.getVec3(x, y, z)) {
rx = x;
ry = y;
@ -1399,7 +1410,7 @@ void MainWindow::updateCamera()
camera_set = true;
}
} else if ("$vpt" == a.first) {
const Value vpt = a.second.get()->evaluate(&top_ctx);
const Value vpt = a.second.get()->evaluate(&mc);
if (vpt.getVec3(x, y, z)) {
tx = x;
ty = y;
@ -1407,7 +1418,7 @@ void MainWindow::updateCamera()
camera_set = true;
}
} else if ("$vpd" == a.first) {
const Value vpd = a.second.get()->evaluate(&top_ctx);
const Value vpd = a.second.get()->evaluate(&mc);
if (vpd.type() == Value::NUMBER) {
d = vpd.toDouble();
camera_set = true;
@ -1425,6 +1436,7 @@ void MainWindow::updateCamera()
params.push_back(rz);
params.push_back(d);
qglview->cam.setup(params);
qglview->cam.gimbalDefaultTranslate();
qglview->updateGL();
}
}
@ -1785,13 +1797,19 @@ 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("Object isn't a valid 2-manifold! Modify your design. See http://en.wikibooks.org/wiki/OpenSCAD_User_Manual/STL_Import_and_Export");
clearCurrentOutput();
return;
}
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;
@ -1911,7 +1929,7 @@ void MainWindow::actionExportCSG()
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());
}
@ -1973,6 +1991,7 @@ void MainWindow::viewModePreview()
viewModeActionsUncheck();
viewActionPreview->setChecked(true);
this->qglview->setRenderer(this->opencsgRenderer ? (Renderer *)this->opencsgRenderer : (Renderer *)this->thrownTogetherRenderer);
this->qglview->updateColorScheme();
this->qglview->updateGL();
} else {
viewModeThrownTogether();
@ -1989,6 +2008,7 @@ void MainWindow::viewModeSurface()
viewActionSurfaces->setChecked(true);
this->qglview->setShowFaces(true);
this->qglview->setRenderer(this->cgalRenderer);
this->qglview->updateColorScheme();
this->qglview->updateGL();
}
@ -1998,6 +2018,7 @@ void MainWindow::viewModeWireframe()
viewActionWireframe->setChecked(true);
this->qglview->setShowFaces(false);
this->qglview->setRenderer(this->cgalRenderer);
this->qglview->updateColorScheme();
this->qglview->updateGL();
}
@ -2008,6 +2029,7 @@ void MainWindow::viewModeThrownTogether()
viewModeActionsUncheck();
viewActionThrownTogether->setChecked(true);
this->qglview->setRenderer(this->thrownTogetherRenderer);
this->qglview->updateColorScheme();
this->qglview->updateGL();
}
@ -2265,14 +2287,14 @@ MainWindow::helpManual()
void MainWindow::helpLibrary()
{
QString info( PlatformUtils::info().c_str() );
info += QString( qglview->getRendererInfo().c_str() );
QString info(LibraryInfo::info().c_str());
info += QString(qglview->getRendererInfo().c_str());
if (!this->openglbox) {
this->openglbox = new QMessageBox(QMessageBox::Information,
"OpenGL Info", "OpenSCAD Detailed Library and Build Information",
QMessageBox::Ok, this);
}
this->openglbox->setDetailedText( info );
this->openglbox->setDetailedText(info);
this->openglbox->show();
}
@ -2346,6 +2368,13 @@ 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;

View File

@ -322,9 +322,7 @@ bool FileModule::handleDependencies()
// Detect appearance but not removal of files, and keep old module
// on compile errors (FIXME: Is this correct behavior?)
if (changed) {
#ifdef DEBUG
PRINTB_NOCACHE(" %s: %p -> %p", filename % oldmodule % newmodule);
#endif
PRINTDB(" %s: %p -> %p", filename % oldmodule % newmodule);
}
somethingchanged |= changed;
// Only print warning if we're not part of an automatic reload

View File

@ -34,10 +34,6 @@ public:
overloaded to provide specialization for e.g. CSG nodes, primitive nodes etc.
Used for human-readable output. */
virtual std::string name() const;
/*! Should return a Geometry instance describing the node. Returns NULL if smth.
goes wrong. This is only called by PolySetEvaluator, to make sure polysets
are inserted into the cache*/
virtual class Geometry *evaluate_geometry(class PolySetEvaluator *) const { return NULL; }
const std::vector<AbstractNode*> &getChildren() const {
return this->children;
@ -88,7 +84,7 @@ public:
LeafNode(const ModuleInstantiation *mi) : AbstractPolyNode(mi) { };
virtual ~LeafNode() { };
virtual Response accept(class State &state, class Visitor &visitor) const;
virtual Geometry *createGeometry() const = 0;
virtual class Geometry *createGeometry() const = 0;
};
std::ostream &operator<<(std::ostream &stream, const AbstractNode &node);

View File

@ -37,6 +37,7 @@
#include "parsersettings.h"
#include "rendersettings.h"
#include "PlatformUtils.h"
#include "LibraryInfo.h"
#include "nodedumper.h"
#include "CocoaUtils.h"
@ -80,6 +81,7 @@ 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
@ -109,9 +111,11 @@ static void help(const char *progname)
"%2%[ --version ] [ --info ] \\\n"
"%2%[ --camera=translatex,y,z,rotx,y,z,dist | \\\n"
"%2% --camera=eyex,y,z,centerx,y,z ] \\\n"
"%2%[ --autocenter ] \\\n"
"%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> ]"
@ -135,7 +139,7 @@ static void version()
static void info()
{
std::cout << PlatformUtils::info() << "\n\n";
std::cout << LibraryInfo::info() << "\n\n";
CsgInfo csgInfo = CsgInfo();
try {
@ -150,7 +154,7 @@ static void info()
exit(0);
}
Camera get_camera( po::variables_map vm )
Camera get_camera(po::variables_map vm)
{
Camera camera;
@ -158,13 +162,17 @@ Camera get_camera( po::variables_map vm )
vector<string> strs;
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 );
if ( strs.size()==6 || strs.size()==7 ) {
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);
}
}
@ -177,6 +185,10 @@ Camera get_camera( po::variables_map vm )
camera.viewall = true;
}
if (vm.count("autocenter")) {
camera.autocenter = true;
}
if (vm.count("projection")) {
string proj = vm["projection"].as<string>();
if (proj=="o" || proj=="ortho" || proj=="orthogonal")
@ -195,11 +207,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;
@ -222,6 +239,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;
}
@ -233,8 +254,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);
@ -517,28 +539,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();
@ -613,9 +619,11 @@ int main(int argc, char **argv)
("preview", po::value<string>(), "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")
@ -716,6 +724,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

@ -80,6 +80,8 @@ std::string parser_source_path;
AssignmentList *args;
}
%token TOK_ERROR
%token TOK_MODULE
%token TOK_FUNCTION
%token TOK_IF

View File

@ -77,10 +77,11 @@ fs::path find_valid_path(const fs::path &sourcepath,
const std::vector<std::string> *openfilenames)
{
if (boosty::is_absolute(localpath)) {
if (check_valid(localpath, openfilenames)) return boosty::absolute(localpath);
if (check_valid(localpath, openfilenames)) return boosty::canonical(localpath);
}
else {
fs::path fpath = sourcepath / localpath;
if (fs::exists(fpath)) fpath = boosty::canonical(fpath);
if (check_valid(fpath, openfilenames)) return fpath;
fpath = search_libs(localpath);
if (!fpath.empty() && check_valid(fpath, openfilenames)) return fpath;
@ -101,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

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

@ -26,6 +26,7 @@ public:
virtual std::string dump() const;
virtual unsigned int getDimension() const { return this->dim; }
virtual bool isEmpty() const { return polygons.size() == 0; }
virtual Geometry *copy() const { return new PolySet(*this); }
size_t numPolygons() const { return polygons.size(); }
void append_poly();

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.");
}
@ -528,7 +528,8 @@ Geometry *PrimitiveNode::createGeometry() const
case SQUARE: {
Polygon2d *p = new Polygon2d();
g = p;
if (this->x > 0 && this->y > 0) {
if (this->x > 0 && this->y > 0 &&
!isinf(this->x) && !isinf(this->y)) {
Vector2d v1(0, 0);
Vector2d v2(this->x, this->y);
if (this->center) {
@ -550,7 +551,7 @@ Geometry *PrimitiveNode::createGeometry() const
case CIRCLE: {
Polygon2d *p = new Polygon2d();
g = p;
if (this->r1 > 0) {
if (this->r1 > 0 && !isinf(this->r1)) {
int fragments = Calc::get_fragments_from_r(this->r1, this->fn, this->fs, this->fa);
Outline2d o;

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;
};

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