├── test
├── testset
│ ├── colorpool
│ │ └── .gitkeep
│ ├── primitives
│ │ ├── box.es.txt
│ │ ├── grid.es.txt
│ │ ├── line.es.txt
│ │ ├── sphere.es.txt
│ │ ├── cylinder.es.txt
│ │ ├── triangle.racket-notation.es.txt
│ │ └── triangle.es.txt
│ ├── geometric
│ │ ├── fz.es.txt
│ │ ├── m.es.txt
│ │ ├── matrix.es.txt
│ │ ├── m.def.es.txt
│ │ ├── matrix.def.es.txt
│ │ ├── x.es.txt
│ │ ├── y.es.txt
│ │ ├── z.es.txt
│ │ ├── fx.es.txt
│ │ ├── s.3.es.txt
│ │ ├── x.def.es.txt
│ │ ├── y.def.es.txt
│ │ ├── z.def.es.txt
│ │ ├── rx.es.txt
│ │ ├── ry.es.txt
│ │ ├── rz.es.txt
│ │ ├── s.1.es.txt
│ │ ├── rx.def.es.txt
│ │ ├── ry.def.es.txt
│ │ ├── rz.def.es.txt
│ │ ├── s.1.def.es.txt
│ │ └── fy.es.txt
│ ├── colorspace
│ │ ├── color.default_color.es.txt
│ │ ├── color.hex3.es.txt
│ │ ├── blend.hex3.es.txt
│ │ ├── blend.hex6.es.txt
│ │ ├── color.colorname.es.txt
│ │ ├── color.hex6.es.txt
│ │ ├── blend.colorname.es.txt
│ │ ├── color.random.es.txt
│ │ ├── blend.random.es.txt
│ │ ├── a.define.varname.es.txt
│ │ ├── color.hex3.define.es.txt
│ │ ├── hue.define.varname.es.txt
│ │ ├── b.define.varname.es.txt
│ │ ├── color.hex6.define.es.txt
│ │ ├── b.es.txt
│ │ ├── h.es.txt
│ │ ├── sat.es.txt
│ │ ├── hue.es.txt
│ │ ├── brightness.es.txt
│ │ ├── saturation.es.txt
│ │ ├── a.es.txt
│ │ ├── alpha.es.txt
│ │ ├── blend.hex.and.hsv.es.txt
│ │ └── sat.define.varname.es.txt
│ ├── comments
│ │ ├── single_line.es.txt
│ │ └── multiline.es.txt
│ ├── actions
│ │ ├── background
│ │ │ ├── background.hex3.es.txt
│ │ │ ├── background.colorname.es.txt
│ │ │ └── background.hex6.es.txt
│ │ ├── seed
│ │ │ └── seed.es.txt
│ │ ├── maxdepth
│ │ │ └── maxdepth.strange.es.txt
│ │ └── maxobjects
│ │ │ └── maxobjects.es.txt
│ └── modifiers
│ │ ├── maxdepth
│ │ ├── md.es.txt
│ │ ├── maxdepth.es.txt
│ │ ├── maxdepth.define.varname.es.txt
│ │ ├── maxdepth.nested_recursive_rule.es.txt
│ │ ├── maxdepth.parallel_traverse.es.txt
│ │ ├── maxdepth.alternate_rule.es.txt
│ │ ├── maxdepth.alternate_rule.define.varname.es.txt
│ │ └── maxdepth.nested_transform.es.txt
│ │ └── weight
│ │ └── w.es.txt
├── helpers
│ └── prettify.js
├── behavior
│ └── should_be_good_interpreter.js
└── interpreter_test.js
├── examples
├── js
│ ├── eisenscript.js
│ ├── render.js
│ └── loaders
│ │ └── OBJLoader.js
├── obj
│ └── box.obj
├── export.html
├── index.html
├── import.html
└── css
│ └── main.css
├── sample
├── sample1.png
├── sample2.png
├── sample3.png
├── sample4.png
├── sample5.png
├── sample6.png
└── sample7.png
├── src
├── math.js
├── index.js
├── exporter
│ ├── STLExporter.js
│ └── OBJExporter.js
├── Primitive.js
├── sprintf.js
├── Compiler.js
├── Symbol.js
├── csscolor.js
├── utils.js
├── Matrix4.js
├── mt.js
├── parser.jison
└── Interpreter.js
├── .editorconfig
├── .circleci
└── config.yml
├── .gitignore
├── webpack.config.js
├── LICENSE
├── README.md
├── package.json
└── gulpfile.js
/test/testset/colorpool/.gitkeep:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/examples/js/eisenscript.js:
--------------------------------------------------------------------------------
1 | ../../build/eisenscript.js
--------------------------------------------------------------------------------
/sample/sample1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/after12am/eisenscript/HEAD/sample/sample1.png
--------------------------------------------------------------------------------
/sample/sample2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/after12am/eisenscript/HEAD/sample/sample2.png
--------------------------------------------------------------------------------
/sample/sample3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/after12am/eisenscript/HEAD/sample/sample3.png
--------------------------------------------------------------------------------
/sample/sample4.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/after12am/eisenscript/HEAD/sample/sample4.png
--------------------------------------------------------------------------------
/sample/sample5.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/after12am/eisenscript/HEAD/sample/sample5.png
--------------------------------------------------------------------------------
/sample/sample6.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/after12am/eisenscript/HEAD/sample/sample6.png
--------------------------------------------------------------------------------
/sample/sample7.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/after12am/eisenscript/HEAD/sample/sample7.png
--------------------------------------------------------------------------------
/src/math.js:
--------------------------------------------------------------------------------
1 | module.exports.clamp = (x, a, b) => (x < a) ? a : ((x > b) ? b : x);
2 |
3 | module.exports.degToRad = (degrees) => degrees * Math.PI / 180;
4 |
--------------------------------------------------------------------------------
/src/index.js:
--------------------------------------------------------------------------------
1 | import Compiler from './Compiler';
2 | import OBJExporter from './exporter/OBJExporter';
3 |
4 | module.exports.Compiler = Compiler;
5 | module.exports.OBJExporter = OBJExporter;
6 |
--------------------------------------------------------------------------------
/src/exporter/STLExporter.js:
--------------------------------------------------------------------------------
1 | export default class STLExporter {
2 | constructor() {
3 | this.buff = '';
4 | }
5 |
6 | exports(meshes) {
7 | console.warn("not implemented");
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/test/helpers/prettify.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | // prettify json and dump
4 | module.exports = function(object, replacer, space) {
5 | replacer = replacer || null;
6 | space = space || 2;
7 | return JSON.stringify(object, replacer, space);
8 | }
9 |
--------------------------------------------------------------------------------
/.editorconfig:
--------------------------------------------------------------------------------
1 | root = true
2 |
3 | [*]
4 | indent_style = space
5 | indent_size = 2
6 | end_of_line = lf
7 | charset = utf-8
8 | trim_trailing_whitespace = true
9 | insert_final_newline = true
10 | block_comment_start = /**
11 | block_comment = *
12 | block_comment_end = */
13 |
14 | [*.md]
15 | indent_size = 4
16 |
--------------------------------------------------------------------------------
/test/testset/primitives/box.es.txt:
--------------------------------------------------------------------------------
1 | /+
2 | box
3 | +/
4 | {"minsize":0.2,"maxsize":1,"seed":"initial","objects":[{"type":"primitive","name":"box","matrix":{"elements":{"0":1,"1":0,"2":0,"3":0,"4":0,"5":1,"6":0,"7":0,"8":0,"9":0,"10":1,"11":0,"12":0,"13":0,"14":0,"15":1}},"color":"#FF0000","opacity":1,"depth":0}],"num":1}
5 |
--------------------------------------------------------------------------------
/test/testset/primitives/grid.es.txt:
--------------------------------------------------------------------------------
1 | /+
2 | grid
3 | +/
4 | {"minsize":0.2,"maxsize":1,"seed":"initial","objects":[{"type":"primitive","name":"grid","matrix":{"elements":{"0":1,"1":0,"2":0,"3":0,"4":0,"5":1,"6":0,"7":0,"8":0,"9":0,"10":1,"11":0,"12":0,"13":0,"14":0,"15":1}},"color":"#FF0000","opacity":1,"depth":0}],"num":1}
5 |
--------------------------------------------------------------------------------
/test/testset/primitives/line.es.txt:
--------------------------------------------------------------------------------
1 | /+
2 | line
3 | +/
4 | {"minsize":0.2,"maxsize":1,"seed":"initial","objects":[{"type":"primitive","name":"line","matrix":{"elements":{"0":1,"1":0,"2":0,"3":0,"4":0,"5":1,"6":0,"7":0,"8":0,"9":0,"10":1,"11":0,"12":0,"13":0,"14":0,"15":1}},"color":"#FF0000","opacity":1,"depth":0}],"num":1}
5 |
--------------------------------------------------------------------------------
/test/testset/geometric/fz.es.txt:
--------------------------------------------------------------------------------
1 | /+
2 | { fz x 1 } box
3 | +/
4 | {"minsize":0.2,"maxsize":1,"seed":"initial","objects":[{"type":"primitive","name":"box","matrix":{"elements":{"0":1,"1":0,"2":0,"3":0,"4":0,"5":1,"6":0,"7":0,"8":0,"9":0,"10":-1,"11":0,"12":1,"13":0,"14":0,"15":1}},"color":"#FF0000","opacity":1,"depth":1}],"num":1}
--------------------------------------------------------------------------------
/test/testset/primitives/sphere.es.txt:
--------------------------------------------------------------------------------
1 | /+
2 | sphere
3 | +/
4 | {"minsize":0.2,"maxsize":1,"seed":"initial","objects":[{"type":"primitive","name":"sphere","matrix":{"elements":{"0":1,"1":0,"2":0,"3":0,"4":0,"5":1,"6":0,"7":0,"8":0,"9":0,"10":1,"11":0,"12":0,"13":0,"14":0,"15":1}},"color":"#FF0000","opacity":1,"depth":0}],"num":1}
5 |
--------------------------------------------------------------------------------
/test/testset/colorspace/color.default_color.es.txt:
--------------------------------------------------------------------------------
1 | /+
2 | box
3 | +/
4 | {"minsize":0.2,"maxsize":1,"seed":"initial","objects":[{"type":"primitive","name":"box","matrix":{"elements":{"0":1,"1":0,"2":0,"3":0,"4":0,"5":1,"6":0,"7":0,"8":0,"9":0,"10":1,"11":0,"12":0,"13":0,"14":0,"15":1}},"color":"#FF0000","opacity":1,"depth":0}],"num":1}
5 |
--------------------------------------------------------------------------------
/test/testset/colorspace/color.hex3.es.txt:
--------------------------------------------------------------------------------
1 | /+
2 | { color #fff } box
3 | +/
4 | {"minsize":0.2,"maxsize":1,"seed":"initial","objects":[{"type":"primitive","name":"box","matrix":{"elements":{"0":1,"1":0,"2":0,"3":0,"4":0,"5":1,"6":0,"7":0,"8":0,"9":0,"10":1,"11":0,"12":0,"13":0,"14":0,"15":1}},"color":"#FFFFFF","opacity":1,"depth":1}],"num":1}
5 |
--------------------------------------------------------------------------------
/test/testset/geometric/m.es.txt:
--------------------------------------------------------------------------------
1 | /+
2 | { m 3 0 0 0 2 0 0 0 1 } box
3 | +/
4 | {"minsize":0.2,"maxsize":1,"seed":"initial","objects":[{"type":"primitive","name":"box","matrix":{"elements":{"0":3,"1":0,"2":0,"3":0,"4":0,"5":2,"6":0,"7":0,"8":0,"9":0,"10":1,"11":0,"12":0,"13":0,"14":0,"15":1}},"color":"#FF0000","opacity":1,"depth":1}],"num":1}
5 |
--------------------------------------------------------------------------------
/test/testset/colorspace/blend.hex3.es.txt:
--------------------------------------------------------------------------------
1 | /+
2 | { blend #fff 1 } box
3 | +/
4 | {"minsize":0.2,"maxsize":1,"seed":"initial","objects":[{"type":"primitive","name":"box","matrix":{"elements":{"0":1,"1":0,"2":0,"3":0,"4":0,"5":1,"6":0,"7":0,"8":0,"9":0,"10":1,"11":0,"12":0,"13":0,"14":0,"15":1}},"color":"#FF8080","opacity":1,"depth":1}],"num":1}
5 |
--------------------------------------------------------------------------------
/test/testset/colorspace/blend.hex6.es.txt:
--------------------------------------------------------------------------------
1 | /+
2 | { blend #ffffff 1 } box
3 | +/
4 | {"minsize":0.2,"maxsize":1,"seed":"initial","objects":[{"type":"primitive","name":"box","matrix":{"elements":{"0":1,"1":0,"2":0,"3":0,"4":0,"5":1,"6":0,"7":0,"8":0,"9":0,"10":1,"11":0,"12":0,"13":0,"14":0,"15":1}},"color":"#FF8080","opacity":1,"depth":1}],"num":1}
5 |
--------------------------------------------------------------------------------
/test/testset/colorspace/color.colorname.es.txt:
--------------------------------------------------------------------------------
1 | /+
2 | { color red } box
3 | +/
4 | {"minsize":0.2,"maxsize":1,"seed":"initial","objects":[{"type":"primitive","name":"box","matrix":{"elements":{"0":1,"1":0,"2":0,"3":0,"4":0,"5":1,"6":0,"7":0,"8":0,"9":0,"10":1,"11":0,"12":0,"13":0,"14":0,"15":1}},"color":"#FF0000","opacity":1,"depth":1}],"num":1}
5 |
--------------------------------------------------------------------------------
/test/testset/colorspace/color.hex6.es.txt:
--------------------------------------------------------------------------------
1 | /+
2 | { color #ffffff } box
3 | +/
4 | {"minsize":0.2,"maxsize":1,"seed":"initial","objects":[{"type":"primitive","name":"box","matrix":{"elements":{"0":1,"1":0,"2":0,"3":0,"4":0,"5":1,"6":0,"7":0,"8":0,"9":0,"10":1,"11":0,"12":0,"13":0,"14":0,"15":1}},"color":"#FFFFFF","opacity":1,"depth":1}],"num":1}
5 |
--------------------------------------------------------------------------------
/test/testset/colorspace/blend.colorname.es.txt:
--------------------------------------------------------------------------------
1 | /+
2 | { blend white 1 } box
3 | +/
4 | {"minsize":0.2,"maxsize":1,"seed":"initial","objects":[{"type":"primitive","name":"box","matrix":{"elements":{"0":1,"1":0,"2":0,"3":0,"4":0,"5":1,"6":0,"7":0,"8":0,"9":0,"10":1,"11":0,"12":0,"13":0,"14":0,"15":1}},"color":"#FF8080","opacity":1,"depth":1}],"num":1}
5 |
--------------------------------------------------------------------------------
/test/testset/colorspace/color.random.es.txt:
--------------------------------------------------------------------------------
1 | /+
2 | set seed 1
3 | { color random } box
4 | +/
5 | {"minsize":0.2,"maxsize":1,"seed":1,"objects":[{"type":"primitive","name":"box","matrix":{"elements":{"0":1,"1":0,"2":0,"3":0,"4":0,"5":1,"6":0,"7":0,"8":0,"9":0,"10":1,"11":0,"12":0,"13":0,"14":0,"15":1}},"color":"#6AC1F3","opacity":1,"depth":1}],"num":1}
6 |
--------------------------------------------------------------------------------
/test/testset/comments/single_line.es.txt:
--------------------------------------------------------------------------------
1 | /+
2 | // have a nice day
3 | box
4 | +/
5 | {"minsize":0.2,"maxsize":1,"seed":"initial","objects":[{"type":"primitive","name":"box","matrix":{"elements":{"0":1,"1":0,"2":0,"3":0,"4":0,"5":1,"6":0,"7":0,"8":0,"9":0,"10":1,"11":0,"12":0,"13":0,"14":0,"15":1}},"color":"#FF0000","opacity":1,"depth":0}],"num":1}
6 |
--------------------------------------------------------------------------------
/test/testset/geometric/matrix.es.txt:
--------------------------------------------------------------------------------
1 | /+
2 | { matrix 3 0 0 0 2 0 0 0 1 } box
3 | +/
4 | {"minsize":0.2,"maxsize":1,"seed":"initial","objects":[{"type":"primitive","name":"box","matrix":{"elements":{"0":3,"1":0,"2":0,"3":0,"4":0,"5":2,"6":0,"7":0,"8":0,"9":0,"10":1,"11":0,"12":0,"13":0,"14":0,"15":1}},"color":"#FF0000","opacity":1,"depth":1}],"num":1}
5 |
--------------------------------------------------------------------------------
/test/testset/colorspace/blend.random.es.txt:
--------------------------------------------------------------------------------
1 | /+
2 | set seed 1
3 | { blend random 1 } box
4 | +/
5 | {"minsize":0.2,"maxsize":1,"seed":1,"objects":[{"type":"primitive","name":"box","matrix":{"elements":{"0":1,"1":0,"2":0,"3":0,"4":0,"5":1,"6":0,"7":0,"8":0,"9":0,"10":1,"11":0,"12":0,"13":0,"14":0,"15":1}},"color":"#B5617A","opacity":1,"depth":1}],"num":1}
6 |
--------------------------------------------------------------------------------
/test/testset/comments/multiline.es.txt:
--------------------------------------------------------------------------------
1 | /+
2 | /*
3 | have a nice day
4 | */
5 | box
6 | +/
7 | {"minsize":0.2,"maxsize":1,"seed":"initial","objects":[{"type":"primitive","name":"box","matrix":{"elements":{"0":1,"1":0,"2":0,"3":0,"4":0,"5":1,"6":0,"7":0,"8":0,"9":0,"10":1,"11":0,"12":0,"13":0,"14":0,"15":1}},"color":"#FF0000","opacity":1,"depth":0}],"num":1}
8 |
--------------------------------------------------------------------------------
/test/testset/colorspace/a.define.varname.es.txt:
--------------------------------------------------------------------------------
1 | /+
2 | #define aa .1
3 |
4 | { a aa } box
5 | +/
6 | {"minsize":0.2,"maxsize":1,"seed":"initial","objects":[{"type":"primitive","name":"box","matrix":{"elements":{"0":1,"1":0,"2":0,"3":0,"4":0,"5":1,"6":0,"7":0,"8":0,"9":0,"10":1,"11":0,"12":0,"13":0,"14":0,"15":1}},"color":"#FF0000","opacity":0.1,"depth":1}],"num":1}
7 |
--------------------------------------------------------------------------------
/test/testset/colorspace/color.hex3.define.es.txt:
--------------------------------------------------------------------------------
1 | /+
2 | #define aa #f00
3 |
4 | { color aa } box
5 | +/
6 | {"minsize":0.2,"maxsize":1,"seed":"initial","objects":[{"type":"primitive","name":"box","matrix":{"elements":{"0":1,"1":0,"2":0,"3":0,"4":0,"5":1,"6":0,"7":0,"8":0,"9":0,"10":1,"11":0,"12":0,"13":0,"14":0,"15":1}},"color":"#FF0000","opacity":1,"depth":1}],"num":1}
7 |
--------------------------------------------------------------------------------
/test/testset/colorspace/hue.define.varname.es.txt:
--------------------------------------------------------------------------------
1 | /+
2 | #define aa 36
3 |
4 | { hue aa } grid
5 | +/
6 | {"minsize":0.2,"maxsize":1,"seed":"initial","objects":[{"type":"primitive","name":"grid","matrix":{"elements":{"0":1,"1":0,"2":0,"3":0,"4":0,"5":1,"6":0,"7":0,"8":0,"9":0,"10":1,"11":0,"12":0,"13":0,"14":0,"15":1}},"color":"#FF9900","opacity":1,"depth":1}],"num":1}
7 |
--------------------------------------------------------------------------------
/test/testset/colorspace/b.define.varname.es.txt:
--------------------------------------------------------------------------------
1 | /+
2 | #define aa 100
3 |
4 | { color #fff b aa } box
5 | +/
6 | {"minsize":0.2,"maxsize":1,"seed":"initial","objects":[{"type":"primitive","name":"box","matrix":{"elements":{"0":1,"1":0,"2":0,"3":0,"4":0,"5":1,"6":0,"7":0,"8":0,"9":0,"10":1,"11":0,"12":0,"13":0,"14":0,"15":1}},"color":"#FFFFFF","opacity":1,"depth":1}],"num":1}
7 |
--------------------------------------------------------------------------------
/test/testset/colorspace/color.hex6.define.es.txt:
--------------------------------------------------------------------------------
1 | /+
2 | #define aa #ff0000
3 |
4 | { color aa } box
5 | +/
6 | {"minsize":0.2,"maxsize":1,"seed":"initial","objects":[{"type":"primitive","name":"box","matrix":{"elements":{"0":1,"1":0,"2":0,"3":0,"4":0,"5":1,"6":0,"7":0,"8":0,"9":0,"10":1,"11":0,"12":0,"13":0,"14":0,"15":1}},"color":"#FF0000","opacity":1,"depth":1}],"num":1}
7 |
--------------------------------------------------------------------------------
/test/testset/actions/background/background.hex3.es.txt:
--------------------------------------------------------------------------------
1 | /+
2 | set background #fff
3 | box
4 | +/
5 | {"minsize":0.2,"maxsize":1,"seed":"initial","objects":[{"type":"background","color":"#fff"},{"type":"primitive","name":"box","matrix":{"elements":{"0":1,"1":0,"2":0,"3":0,"4":0,"5":1,"6":0,"7":0,"8":0,"9":0,"10":1,"11":0,"12":0,"13":0,"14":0,"15":1}},"color":"#FF0000","opacity":1,"depth":0}],"num":2}
6 |
--------------------------------------------------------------------------------
/examples/obj/box.obj:
--------------------------------------------------------------------------------
1 | # box example
2 | g cube
3 | v 0 0 0
4 | v 10 0 0
5 | v 0 10 0
6 | v 10 10 0
7 | v 0 0 10
8 | v 10 0 10
9 | v 0 10 10
10 | v 10 10 10
11 | vn 0 0 -1
12 | vn -1 0 0
13 | vn 1 0 0
14 | vn 0 -1 0
15 | vn 0 1 0
16 | vn 0 0 1
17 | f 1//1 3//1 4//1 2//1
18 | f 1//2 5//2 7//2 3//2
19 | f 2//3 4//3 8//3 6//3
20 | f 1//4 2//4 6//4 5//4
21 | f 3//5 7//5 8//5 4//5
22 | f 5//6 6//6 8//6 7//6
--------------------------------------------------------------------------------
/test/testset/actions/background/background.colorname.es.txt:
--------------------------------------------------------------------------------
1 | /+
2 | set background white
3 | box
4 | +/
5 | {"minsize":0.2,"maxsize":1,"seed":"initial","objects":[{"type":"background","color":"white"},{"type":"primitive","name":"box","matrix":{"elements":{"0":1,"1":0,"2":0,"3":0,"4":0,"5":1,"6":0,"7":0,"8":0,"9":0,"10":1,"11":0,"12":0,"13":0,"14":0,"15":1}},"color":"#FF0000","opacity":1,"depth":0}],"num":2}
6 |
--------------------------------------------------------------------------------
/test/testset/actions/background/background.hex6.es.txt:
--------------------------------------------------------------------------------
1 | /+
2 | set background #ffffff
3 | box
4 | +/
5 | {"minsize":0.2,"maxsize":1,"seed":"initial","objects":[{"type":"background","color":"#ffffff"},{"type":"primitive","name":"box","matrix":{"elements":{"0":1,"1":0,"2":0,"3":0,"4":0,"5":1,"6":0,"7":0,"8":0,"9":0,"10":1,"11":0,"12":0,"13":0,"14":0,"15":1}},"color":"#FF0000","opacity":1,"depth":0}],"num":2}
6 |
--------------------------------------------------------------------------------
/test/testset/geometric/m.def.es.txt:
--------------------------------------------------------------------------------
1 | /+
2 | #define zero 0
3 | #define one 1
4 | #define two 2
5 | #define three 3
6 | { m three zero zero zero two zero zero zero one } box
7 | +/
8 | {"minsize":0.2,"maxsize":1,"seed":"initial","objects":[{"type":"primitive","name":"box","matrix":{"elements":{"0":3,"1":0,"2":0,"3":0,"4":0,"5":2,"6":0,"7":0,"8":0,"9":0,"10":1,"11":0,"12":0,"13":0,"14":0,"15":1}},"color":"#FF0000","opacity":1,"depth":1}],"num":1}
9 |
--------------------------------------------------------------------------------
/test/testset/geometric/matrix.def.es.txt:
--------------------------------------------------------------------------------
1 | /+
2 | #define zero 0
3 | #define one 1
4 | #define two 2
5 | #define three 3
6 | { matrix three zero zero zero two zero zero zero one } box
7 | +/
8 | {"minsize":0.2,"maxsize":1,"seed":"initial","objects":[{"type":"primitive","name":"box","matrix":{"elements":{"0":3,"1":0,"2":0,"3":0,"4":0,"5":2,"6":0,"7":0,"8":0,"9":0,"10":1,"11":0,"12":0,"13":0,"14":0,"15":1}},"color":"#FF0000","opacity":1,"depth":1}],"num":1}
9 |
--------------------------------------------------------------------------------
/.circleci/config.yml:
--------------------------------------------------------------------------------
1 | version: 2.1
2 | orbs:
3 | node: circleci/node@1.1.6
4 | jobs:
5 | build-and-test:
6 | executor:
7 | name: node/default
8 | steps:
9 | - checkout
10 | - node/with-cache:
11 | steps:
12 | - run: npm install
13 | - run: npm test
14 | - store_artifacts:
15 | path: coverage
16 | workflows:
17 | build-and-test:
18 | jobs:
19 | - build-and-test
20 |
--------------------------------------------------------------------------------
/src/Primitive.js:
--------------------------------------------------------------------------------
1 | module.exports = class Primitive {
2 | static get Box() { return 'box'; }
3 | static get Grid() { return 'grid'; }
4 | static get Sphere() { return 'sphere'; }
5 | static get Line() { return 'line'; }
6 | static get Point() { return 'point'; }
7 | static get Triangle() { return 'triangle'; }
8 | static get Mesh() { return 'mesh'; }
9 | static get Cylinder() { return 'cylinder'; }
10 | static get Tube() { return 'tube'; }
11 | static get Squash() { return 'squash'; }
12 | }
13 |
--------------------------------------------------------------------------------
/test/testset/geometric/x.es.txt:
--------------------------------------------------------------------------------
1 | /+
2 | 2 * { x 2 } box
3 | +/
4 | {"minsize":0.2,"maxsize":1,"seed":"initial","objects":[{"type":"primitive","name":"box","matrix":{"elements":{"0":1,"1":0,"2":0,"3":0,"4":0,"5":1,"6":0,"7":0,"8":0,"9":0,"10":1,"11":0,"12":2,"13":0,"14":0,"15":1}},"color":"#FF0000","opacity":1,"depth":1},{"type":"primitive","name":"box","matrix":{"elements":{"0":1,"1":0,"2":0,"3":0,"4":0,"5":1,"6":0,"7":0,"8":0,"9":0,"10":1,"11":0,"12":4,"13":0,"14":0,"15":1}},"color":"#FF0000","opacity":1,"depth":1}],"num":2}
5 |
--------------------------------------------------------------------------------
/test/testset/geometric/y.es.txt:
--------------------------------------------------------------------------------
1 | /+
2 | 2 * { y 2 } box
3 | +/
4 | {"minsize":0.2,"maxsize":1,"seed":"initial","objects":[{"type":"primitive","name":"box","matrix":{"elements":{"0":1,"1":0,"2":0,"3":0,"4":0,"5":1,"6":0,"7":0,"8":0,"9":0,"10":1,"11":0,"12":0,"13":2,"14":0,"15":1}},"color":"#FF0000","opacity":1,"depth":1},{"type":"primitive","name":"box","matrix":{"elements":{"0":1,"1":0,"2":0,"3":0,"4":0,"5":1,"6":0,"7":0,"8":0,"9":0,"10":1,"11":0,"12":0,"13":4,"14":0,"15":1}},"color":"#FF0000","opacity":1,"depth":1}],"num":2}
5 |
--------------------------------------------------------------------------------
/test/testset/geometric/z.es.txt:
--------------------------------------------------------------------------------
1 | /+
2 | 2 * { z 2 } box
3 | +/
4 | {"minsize":0.2,"maxsize":1,"seed":"initial","objects":[{"type":"primitive","name":"box","matrix":{"elements":{"0":1,"1":0,"2":0,"3":0,"4":0,"5":1,"6":0,"7":0,"8":0,"9":0,"10":1,"11":0,"12":0,"13":0,"14":2,"15":1}},"color":"#FF0000","opacity":1,"depth":1},{"type":"primitive","name":"box","matrix":{"elements":{"0":1,"1":0,"2":0,"3":0,"4":0,"5":1,"6":0,"7":0,"8":0,"9":0,"10":1,"11":0,"12":0,"13":0,"14":4,"15":1}},"color":"#FF0000","opacity":1,"depth":1}],"num":2}
5 |
--------------------------------------------------------------------------------
/test/testset/geometric/fx.es.txt:
--------------------------------------------------------------------------------
1 | /+
2 | 2 * { fx } 1 * { x 5 } box
3 | +/
4 | {"minsize":0.2,"maxsize":1,"seed":"initial","objects":[{"type":"primitive","name":"box","matrix":{"elements":{"0":-1,"1":0,"2":0,"3":0,"4":0,"5":1,"6":0,"7":0,"8":0,"9":0,"10":1,"11":0,"12":-5,"13":0,"14":0,"15":1}},"color":"#FF0000","opacity":1,"depth":2},{"type":"primitive","name":"box","matrix":{"elements":{"0":1,"1":0,"2":0,"3":0,"4":0,"5":1,"6":0,"7":0,"8":0,"9":0,"10":1,"11":0,"12":5,"13":0,"14":0,"15":1}},"color":"#FF0000","opacity":1,"depth":2}],"num":2}
--------------------------------------------------------------------------------
/test/testset/geometric/s.3.es.txt:
--------------------------------------------------------------------------------
1 | /+
2 | 2 * { s 2 3 0.5 } box
3 | +/
4 | {"minsize":0.2,"maxsize":1,"seed":"initial","objects":[{"type":"primitive","name":"box","matrix":{"elements":{"0":2,"1":0,"2":0,"3":0,"4":0,"5":3,"6":0,"7":0,"8":0,"9":0,"10":0.5,"11":0,"12":0,"13":0,"14":0,"15":1}},"color":"#FF0000","opacity":1,"depth":1},{"type":"primitive","name":"box","matrix":{"elements":{"0":4,"1":0,"2":0,"3":0,"4":0,"5":9,"6":0,"7":0,"8":0,"9":0,"10":0.25,"11":0,"12":0,"13":0,"14":0,"15":1}},"color":"#FF0000","opacity":1,"depth":1}],"num":2}
5 |
--------------------------------------------------------------------------------
/test/testset/primitives/cylinder.es.txt:
--------------------------------------------------------------------------------
1 | /+
2 | box
3 | { x 1 } cylinder
4 | +/
5 | {"minsize":0.2,"maxsize":1,"seed":"initial","objects":[{"type":"primitive","name":"box","matrix":{"elements":{"0":1,"1":0,"2":0,"3":0,"4":0,"5":1,"6":0,"7":0,"8":0,"9":0,"10":1,"11":0,"12":0,"13":0,"14":0,"15":1}},"color":"#FF0000","opacity":1,"depth":0},{"type":"primitive","name":"cylinder","matrix":{"elements":{"0":1,"1":0,"2":0,"3":0,"4":0,"5":1,"6":0,"7":0,"8":0,"9":0,"10":1,"11":0,"12":1,"13":0,"14":0,"15":1}},"color":"#FF0000","opacity":1,"depth":1}],"num":2}
6 |
--------------------------------------------------------------------------------
/test/testset/geometric/x.def.es.txt:
--------------------------------------------------------------------------------
1 | /+
2 | #define dist 2
3 | 2 * { x dist } box
4 | +/
5 | {"minsize":0.2,"maxsize":1,"seed":"initial","objects":[{"type":"primitive","name":"box","matrix":{"elements":{"0":1,"1":0,"2":0,"3":0,"4":0,"5":1,"6":0,"7":0,"8":0,"9":0,"10":1,"11":0,"12":2,"13":0,"14":0,"15":1}},"color":"#FF0000","opacity":1,"depth":1},{"type":"primitive","name":"box","matrix":{"elements":{"0":1,"1":0,"2":0,"3":0,"4":0,"5":1,"6":0,"7":0,"8":0,"9":0,"10":1,"11":0,"12":4,"13":0,"14":0,"15":1}},"color":"#FF0000","opacity":1,"depth":1}],"num":2}
6 |
--------------------------------------------------------------------------------
/test/testset/geometric/y.def.es.txt:
--------------------------------------------------------------------------------
1 | /+
2 | #define dist 2
3 | 2 * { y dist } box
4 | +/
5 | {"minsize":0.2,"maxsize":1,"seed":"initial","objects":[{"type":"primitive","name":"box","matrix":{"elements":{"0":1,"1":0,"2":0,"3":0,"4":0,"5":1,"6":0,"7":0,"8":0,"9":0,"10":1,"11":0,"12":0,"13":2,"14":0,"15":1}},"color":"#FF0000","opacity":1,"depth":1},{"type":"primitive","name":"box","matrix":{"elements":{"0":1,"1":0,"2":0,"3":0,"4":0,"5":1,"6":0,"7":0,"8":0,"9":0,"10":1,"11":0,"12":0,"13":4,"14":0,"15":1}},"color":"#FF0000","opacity":1,"depth":1}],"num":2}
6 |
--------------------------------------------------------------------------------
/test/testset/geometric/z.def.es.txt:
--------------------------------------------------------------------------------
1 | /+
2 | #define dist 2
3 | 2 * { z dist } box
4 | +/
5 | {"minsize":0.2,"maxsize":1,"seed":"initial","objects":[{"type":"primitive","name":"box","matrix":{"elements":{"0":1,"1":0,"2":0,"3":0,"4":0,"5":1,"6":0,"7":0,"8":0,"9":0,"10":1,"11":0,"12":0,"13":0,"14":2,"15":1}},"color":"#FF0000","opacity":1,"depth":1},{"type":"primitive","name":"box","matrix":{"elements":{"0":1,"1":0,"2":0,"3":0,"4":0,"5":1,"6":0,"7":0,"8":0,"9":0,"10":1,"11":0,"12":0,"13":0,"14":4,"15":1}},"color":"#FF0000","opacity":1,"depth":1}],"num":2}
6 |
--------------------------------------------------------------------------------
/src/sprintf.js:
--------------------------------------------------------------------------------
1 | const makeArray = (array) => {
2 | const ret = [];
3 | if(array != null){
4 | let i = array.length;
5 | if ( i == null || array.split || array.setInterval || array.call ) {
6 | ret[0] = array;
7 | } else {
8 | while( i ) ret[--i] = array[i];
9 | }
10 | }
11 | return ret;
12 | };
13 |
14 | export default function sprintf() {
15 | let _arg = makeArray(arguments), template = _arg.shift(), i;
16 | for(i in _arg){
17 | template = template.replace('%s', _arg[i]);
18 | }
19 | return template;
20 | };
21 |
--------------------------------------------------------------------------------
/test/testset/modifiers/maxdepth/md.es.txt:
--------------------------------------------------------------------------------
1 | /+
2 | rule R1 md 2 {
3 | box
4 | { x 1 } R1
5 | }
6 |
7 | R1
8 | +/
9 | {"minsize":0.2,"maxsize":1,"seed":"initial","objects":[{"type":"primitive","name":"box","matrix":{"elements":{"0":1,"1":0,"2":0,"3":0,"4":0,"5":1,"6":0,"7":0,"8":0,"9":0,"10":1,"11":0,"12":0,"13":0,"14":0,"15":1}},"color":"#FF0000","opacity":1,"depth":0},{"type":"primitive","name":"box","matrix":{"elements":{"0":1,"1":0,"2":0,"3":0,"4":0,"5":1,"6":0,"7":0,"8":0,"9":0,"10":1,"11":0,"12":1,"13":0,"14":0,"15":1}},"color":"#FF0000","opacity":1,"depth":1}],"num":2}
10 |
--------------------------------------------------------------------------------
/test/testset/modifiers/maxdepth/maxdepth.es.txt:
--------------------------------------------------------------------------------
1 | /+
2 | rule R1 maxdepth 2 {
3 | box
4 | { x 1 } R1
5 | }
6 |
7 | R1
8 | +/
9 | {"minsize":0.2,"maxsize":1,"seed":"initial","objects":[{"type":"primitive","name":"box","matrix":{"elements":{"0":1,"1":0,"2":0,"3":0,"4":0,"5":1,"6":0,"7":0,"8":0,"9":0,"10":1,"11":0,"12":0,"13":0,"14":0,"15":1}},"color":"#FF0000","opacity":1,"depth":0},{"type":"primitive","name":"box","matrix":{"elements":{"0":1,"1":0,"2":0,"3":0,"4":0,"5":1,"6":0,"7":0,"8":0,"9":0,"10":1,"11":0,"12":1,"13":0,"14":0,"15":1}},"color":"#FF0000","opacity":1,"depth":1}],"num":2}
10 |
--------------------------------------------------------------------------------
/test/testset/geometric/rx.es.txt:
--------------------------------------------------------------------------------
1 | /+
2 | 2 * { rx 45 } box
3 | +/
4 | {"minsize":0.2,"maxsize":1,"seed":"initial","objects":[{"type":"primitive","name":"box","matrix":{"elements":{"0":1,"1":0,"2":0,"3":0,"4":0,"5":0.7071067690849304,"6":0.7071067690849304,"7":0,"8":0,"9":-0.7071067690849304,"10":0.7071067690849304,"11":0,"12":0,"13":0,"14":0,"15":1}},"color":"#FF0000","opacity":1,"depth":1},{"type":"primitive","name":"box","matrix":{"elements":{"0":1,"1":0,"2":0,"3":0,"4":0,"5":5.551115123125783e-17,"6":1,"7":0,"8":0,"9":-1,"10":5.551115123125783e-17,"11":0,"12":0,"13":0,"14":0,"15":1}},"color":"#FF0000","opacity":1,"depth":1}],"num":2}
5 |
--------------------------------------------------------------------------------
/test/testset/geometric/ry.es.txt:
--------------------------------------------------------------------------------
1 | /+
2 | 2 * { ry 45 } box
3 | +/
4 | {"minsize":0.2,"maxsize":1,"seed":"initial","objects":[{"type":"primitive","name":"box","matrix":{"elements":{"0":0.7071067690849304,"1":0,"2":-0.7071067690849304,"3":0,"4":0,"5":1,"6":0,"7":0,"8":0.7071067690849304,"9":0,"10":0.7071067690849304,"11":0,"12":0,"13":0,"14":0,"15":1}},"color":"#FF0000","opacity":1,"depth":1},{"type":"primitive","name":"box","matrix":{"elements":{"0":5.551115123125783e-17,"1":0,"2":-1,"3":0,"4":0,"5":1,"6":0,"7":0,"8":1,"9":0,"10":5.551115123125783e-17,"11":0,"12":0,"13":0,"14":0,"15":1}},"color":"#FF0000","opacity":1,"depth":1}],"num":2}
5 |
--------------------------------------------------------------------------------
/test/testset/geometric/rz.es.txt:
--------------------------------------------------------------------------------
1 | /+
2 | 2 * { rz 45 } box
3 | +/
4 | {"minsize":0.2,"maxsize":1,"seed":"initial","objects":[{"type":"primitive","name":"box","matrix":{"elements":{"0":0.7071067690849304,"1":0.7071067690849304,"2":0,"3":0,"4":-0.7071067690849304,"5":0.7071067690849304,"6":0,"7":0,"8":0,"9":0,"10":1,"11":0,"12":0,"13":0,"14":0,"15":1}},"color":"#FF0000","opacity":1,"depth":1},{"type":"primitive","name":"box","matrix":{"elements":{"0":5.551115123125783e-17,"1":1,"2":0,"3":0,"4":-1,"5":5.551115123125783e-17,"6":0,"7":0,"8":0,"9":0,"10":1,"11":0,"12":0,"13":0,"14":0,"15":1}},"color":"#FF0000","opacity":1,"depth":1}],"num":2}
5 |
--------------------------------------------------------------------------------
/test/testset/modifiers/maxdepth/maxdepth.define.varname.es.txt:
--------------------------------------------------------------------------------
1 | /+
2 | #define num 2
3 |
4 | rule R1 maxdepth num {
5 | box
6 | { x 1 } R1
7 | }
8 |
9 | R1
10 | +/
11 | {"minsize":0.2,"maxsize":1,"seed":"initial","objects":[{"type":"primitive","name":"box","matrix":{"elements":{"0":1,"1":0,"2":0,"3":0,"4":0,"5":1,"6":0,"7":0,"8":0,"9":0,"10":1,"11":0,"12":0,"13":0,"14":0,"15":1}},"color":"#FF0000","opacity":1,"depth":0},{"type":"primitive","name":"box","matrix":{"elements":{"0":1,"1":0,"2":0,"3":0,"4":0,"5":1,"6":0,"7":0,"8":0,"9":0,"10":1,"11":0,"12":1,"13":0,"14":0,"15":1}},"color":"#FF0000","opacity":1,"depth":1}],"num":2}
12 |
--------------------------------------------------------------------------------
/test/testset/geometric/s.1.es.txt:
--------------------------------------------------------------------------------
1 | /+
2 | 2 * { x -1 s 1.2 } box
3 | +/
4 | {"minsize":0.2,"maxsize":1,"seed":"initial","objects":[{"type":"primitive","name":"box","matrix":{"elements":{"0":1.2000000476837158,"1":0,"2":0,"3":0,"4":0,"5":1.2000000476837158,"6":0,"7":0,"8":0,"9":0,"10":1.2000000476837158,"11":0,"12":-1,"13":0,"14":0,"15":1}},"color":"#FF0000","opacity":1,"depth":1},{"type":"primitive","name":"box","matrix":{"elements":{"0":1.440000057220459,"1":0,"2":0,"3":0,"4":0,"5":1.440000057220459,"6":0,"7":0,"8":0,"9":0,"10":1.440000057220459,"11":0,"12":-2.200000047683716,"13":0,"14":0,"15":1}},"color":"#FF0000","opacity":1,"depth":1}],"num":2}
5 |
--------------------------------------------------------------------------------
/test/testset/geometric/rx.def.es.txt:
--------------------------------------------------------------------------------
1 | /+
2 | #define angle 45
3 | 2 * { rx angle } box
4 | +/
5 | {"minsize":0.2,"maxsize":1,"seed":"initial","objects":[{"type":"primitive","name":"box","matrix":{"elements":{"0":1,"1":0,"2":0,"3":0,"4":0,"5":0.7071067690849304,"6":0.7071067690849304,"7":0,"8":0,"9":-0.7071067690849304,"10":0.7071067690849304,"11":0,"12":0,"13":0,"14":0,"15":1}},"color":"#FF0000","opacity":1,"depth":1},{"type":"primitive","name":"box","matrix":{"elements":{"0":1,"1":0,"2":0,"3":0,"4":0,"5":5.551115123125783e-17,"6":1,"7":0,"8":0,"9":-1,"10":5.551115123125783e-17,"11":0,"12":0,"13":0,"14":0,"15":1}},"color":"#FF0000","opacity":1,"depth":1}],"num":2}
6 |
--------------------------------------------------------------------------------
/test/testset/geometric/ry.def.es.txt:
--------------------------------------------------------------------------------
1 | /+
2 | #define angle 45
3 | 2 * { ry angle } box
4 | +/
5 | {"minsize":0.2,"maxsize":1,"seed":"initial","objects":[{"type":"primitive","name":"box","matrix":{"elements":{"0":0.7071067690849304,"1":0,"2":-0.7071067690849304,"3":0,"4":0,"5":1,"6":0,"7":0,"8":0.7071067690849304,"9":0,"10":0.7071067690849304,"11":0,"12":0,"13":0,"14":0,"15":1}},"color":"#FF0000","opacity":1,"depth":1},{"type":"primitive","name":"box","matrix":{"elements":{"0":5.551115123125783e-17,"1":0,"2":-1,"3":0,"4":0,"5":1,"6":0,"7":0,"8":1,"9":0,"10":5.551115123125783e-17,"11":0,"12":0,"13":0,"14":0,"15":1}},"color":"#FF0000","opacity":1,"depth":1}],"num":2}
6 |
--------------------------------------------------------------------------------
/test/testset/geometric/rz.def.es.txt:
--------------------------------------------------------------------------------
1 | /+
2 | #define angle 45
3 | 2 * { rz angle } box
4 | +/
5 | {"minsize":0.2,"maxsize":1,"seed":"initial","objects":[{"type":"primitive","name":"box","matrix":{"elements":{"0":0.7071067690849304,"1":0.7071067690849304,"2":0,"3":0,"4":-0.7071067690849304,"5":0.7071067690849304,"6":0,"7":0,"8":0,"9":0,"10":1,"11":0,"12":0,"13":0,"14":0,"15":1}},"color":"#FF0000","opacity":1,"depth":1},{"type":"primitive","name":"box","matrix":{"elements":{"0":5.551115123125783e-17,"1":1,"2":0,"3":0,"4":-1,"5":5.551115123125783e-17,"6":0,"7":0,"8":0,"9":0,"10":1,"11":0,"12":0,"13":0,"14":0,"15":1}},"color":"#FF0000","opacity":1,"depth":1}],"num":2}
6 |
--------------------------------------------------------------------------------
/test/testset/geometric/s.1.def.es.txt:
--------------------------------------------------------------------------------
1 | /+
2 | #define scale 1.2
3 | 2 * { x -1 s scale } box
4 | +/
5 | {"minsize":0.2,"maxsize":1,"seed":"initial","objects":[{"type":"primitive","name":"box","matrix":{"elements":{"0":1.2000000476837158,"1":0,"2":0,"3":0,"4":0,"5":1.2000000476837158,"6":0,"7":0,"8":0,"9":0,"10":1.2000000476837158,"11":0,"12":-1,"13":0,"14":0,"15":1}},"color":"#FF0000","opacity":1,"depth":1},{"type":"primitive","name":"box","matrix":{"elements":{"0":1.440000057220459,"1":0,"2":0,"3":0,"4":0,"5":1.440000057220459,"6":0,"7":0,"8":0,"9":0,"10":1.440000057220459,"11":0,"12":-2.200000047683716,"13":0,"14":0,"15":1}},"color":"#FF0000","opacity":1,"depth":1}],"num":2}
6 |
--------------------------------------------------------------------------------
/test/testset/primitives/triangle.racket-notation.es.txt:
--------------------------------------------------------------------------------
1 | /+
2 | triangle [0,0,0;1,0,0;0.5,0.5,0.5]
3 | triangle[-1,0,1;0,1,0;1,0,1]
4 | +/
5 | {"minsize":0.2,"maxsize":1,"seed":"initial","objects":[{"type":"primitive","name":"triangle","matrix":{"elements":{"0":1,"1":0,"2":0,"3":0,"4":0,"5":1,"6":0,"7":0,"8":0,"9":0,"10":1,"11":0,"12":0,"13":0,"14":0,"15":1}},"color":"#FF0000","opacity":1,"depth":0,"coords":[[0,0,0],[1,0,0],[0.5,0.5,0.5]]},{"type":"primitive","name":"triangle","matrix":{"elements":{"0":1,"1":0,"2":0,"3":0,"4":0,"5":1,"6":0,"7":0,"8":0,"9":0,"10":1,"11":0,"12":0,"13":0,"14":0,"15":1}},"color":"#FF0000","opacity":1,"depth":0,"coords":[[-1,0,1],[0,1,0],[1,0,1]]}],"num":2}
6 |
--------------------------------------------------------------------------------
/test/testset/modifiers/maxdepth/maxdepth.nested_recursive_rule.es.txt:
--------------------------------------------------------------------------------
1 | /+
2 | corner
3 | rule corner md 2 {
4 | ARC
5 | {ry 36}corner
6 | }
7 | rule ARC md 1 {
8 | ARC
9 | box
10 | }
11 | +/
12 | {"minsize":0.2,"maxsize":1,"seed":"initial","objects":[{"type":"primitive","name":"box","matrix":{"elements":{"0":1,"1":0,"2":0,"3":0,"4":0,"5":1,"6":0,"7":0,"8":0,"9":0,"10":1,"11":0,"12":0,"13":0,"14":0,"15":1}},"color":"#FF0000","opacity":1,"depth":0},{"type":"primitive","name":"box","matrix":{"elements":{"0":0.80901700258255,"1":0,"2":-0.5877852439880371,"3":0,"4":0,"5":1,"6":0,"7":0,"8":0.5877852439880371,"9":0,"10":0.80901700258255,"11":0,"12":0,"13":0,"14":0,"15":1}},"color":"#FF0000","opacity":1,"depth":1}],"num":2}
13 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Logs
2 | logs
3 | *.log
4 | npm-debug.log*
5 |
6 | # Runtime data
7 | pids
8 | *.pid
9 | *.seed
10 | *.pid.lock
11 |
12 | # Directory for instrumented libs generated by jscoverage/JSCover
13 | lib-cov
14 |
15 | # Coverage directory used by tools like istanbul
16 | coverage
17 |
18 | # nyc test coverage
19 | .nyc_output
20 |
21 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
22 | .grunt
23 |
24 | # node-waf configuration
25 | .lock-wscript
26 |
27 | # Compiled binary addons (http://nodejs.org/api/addons.html)
28 | build/Release
29 |
30 | # Dependency directories
31 | node_modules
32 | jspm_packages
33 |
34 | # Optional npm cache directory
35 | .npm
36 |
37 | # Optional eslint cache
38 | .eslintcache
39 |
40 | # Optional REPL history
41 | .node_repl_history
42 |
43 | # Output of 'npm pack'
44 | *.tgz
45 |
46 |
47 | .DS_Store
48 | coverage
49 | _docpress
50 |
--------------------------------------------------------------------------------
/test/testset/geometric/fy.es.txt:
--------------------------------------------------------------------------------
1 | /+
2 | 2 * { fy } 2 * { fx } 1 * { x 1 y 3 } box
3 | +/
4 | {"minsize":0.2,"maxsize":1,"seed":"initial","objects":[{"type":"primitive","name":"box","matrix":{"elements":{"0":-1,"1":0,"2":0,"3":0,"4":0,"5":-1,"6":0,"7":0,"8":0,"9":0,"10":1,"11":0,"12":-1,"13":-3,"14":0,"15":1}},"color":"#FF0000","opacity":1,"depth":3},{"type":"primitive","name":"box","matrix":{"elements":{"0":1,"1":0,"2":0,"3":0,"4":0,"5":-1,"6":0,"7":0,"8":0,"9":0,"10":1,"11":0,"12":1,"13":-3,"14":0,"15":1}},"color":"#FF0000","opacity":1,"depth":3},{"type":"primitive","name":"box","matrix":{"elements":{"0":-1,"1":0,"2":0,"3":0,"4":0,"5":1,"6":0,"7":0,"8":0,"9":0,"10":1,"11":0,"12":-1,"13":3,"14":0,"15":1}},"color":"#FF0000","opacity":1,"depth":3},{"type":"primitive","name":"box","matrix":{"elements":{"0":1,"1":0,"2":0,"3":0,"4":0,"5":1,"6":0,"7":0,"8":0,"9":0,"10":1,"11":0,"12":1,"13":3,"14":0,"15":1}},"color":"#FF0000","opacity":1,"depth":3}],"num":4}
--------------------------------------------------------------------------------
/test/testset/modifiers/maxdepth/maxdepth.parallel_traverse.es.txt:
--------------------------------------------------------------------------------
1 | /+
2 | crate
3 | rule crate md 2 {
4 | box
5 | { s 0.5 x 0.9 z 0.9 y -0.9 } crate //1
6 | { s 0.5 x -0.9 z 0.9 y -0.9 } crate //2
7 | }
8 | +/
9 | {"minsize":0.2,"maxsize":1,"seed":"initial","objects":[{"type":"primitive","name":"box","matrix":{"elements":{"0":1,"1":0,"2":0,"3":0,"4":0,"5":1,"6":0,"7":0,"8":0,"9":0,"10":1,"11":0,"12":0,"13":0,"14":0,"15":1}},"color":"#FF0000","opacity":1,"depth":0},{"type":"primitive","name":"box","matrix":{"elements":{"0":0.5,"1":0,"2":0,"3":0,"4":0,"5":0.5,"6":0,"7":0,"8":0,"9":0,"10":0.5,"11":0,"12":0.44999998807907104,"13":-0.44999998807907104,"14":0.44999998807907104,"15":1}},"color":"#FF0000","opacity":1,"depth":1},{"type":"primitive","name":"box","matrix":{"elements":{"0":0.5,"1":0,"2":0,"3":0,"4":0,"5":0.5,"6":0,"7":0,"8":0,"9":0,"10":0.5,"11":0,"12":-0.44999998807907104,"13":-0.44999998807907104,"14":0.44999998807907104,"15":1}},"color":"#FF0000","opacity":1,"depth":1}],"num":3}
10 |
--------------------------------------------------------------------------------
/webpack.config.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | const webpack = require('webpack');
4 | const version = require('./package.json').version;
5 |
6 | const copyright = `eisenscript
7 | https://github.com/after12am/eisenscript
8 | (c)2013-2020 Satoshi Okami
9 | Released under the MIT license`;
10 |
11 | module.exports = {
12 |
13 | entry: {
14 | eisenscript: __dirname + '/src/index.js',
15 | },
16 |
17 | output: {
18 | path: __dirname + '/build',
19 | filename: '[name].js',
20 | library: 'eisen = EISEN',
21 | libraryTarget: 'var'
22 | },
23 |
24 | module: {
25 | loaders: [
26 | {
27 | loader: 'babel-loader',
28 | query: {
29 | presets: ['es2015']
30 | }
31 | },
32 | {
33 | test: /\.json$/,
34 | loader: 'json-loader',
35 | }
36 | ]
37 | },
38 |
39 | node: {
40 | fs: "empty"
41 | },
42 |
43 | resolve: {
44 | extensions: ['', '.js', '.jsx', '.json']
45 | },
46 |
47 | plugins: [
48 | new webpack.BannerPlugin(copyright)
49 | ]
50 | };
51 |
--------------------------------------------------------------------------------
/src/Compiler.js:
--------------------------------------------------------------------------------
1 | import parser from './parser';
2 | import Interpreter from './Interpreter';
3 |
4 | export default class Compiler {
5 | /**
6 | * convert eisenscript code to intermediate object that is possible to load 3d renderer.
7 | *
8 | * @description parse eisenscript code and interpret the result while scanning the ast.
9 | * @param {String} source eisenscript
10 | * @return {Object} execution result
11 | *
12 | * new Compiler().compile('2 * { x 1 } box');
13 | *
14 | */
15 | compile(source) {
16 | const interpreter = new Interpreter();
17 | return interpreter.generate(this.parse(source));
18 | }
19 |
20 | /**
21 | * parse eisenscript code
22 | *
23 | * @description parse eisenscript code and get [ast](https://en.wikipedia.org/wiki/Abstract_syntax_tree).
24 | * @param {String} source eisenscript
25 | * @return {Object} ast
26 | *
27 | * new Compiler().parse('2 * { x 1 } box');
28 | *
29 | */
30 | parse(source) {
31 | return parser.parse(source);
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License
2 |
3 | Copyright (C) 2013-2020 Satoshi Okami
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in
13 | all copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21 | THE SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | eisenscript
2 | ===========
3 |
4 | [](https://circleci.com/gh/after12am/eisenscript)
5 |
6 | [Demo](https://after12am.github.io/eisenscript-editor/?show=0)
7 |
8 | [Doc](https://after12am.github.io/eisenscript-docs/build/docs/getting-started-introduction)
9 |
10 | EisenScript is a programming language designed by Mikael Hvidtfeldt for generating 3d structures.
11 | This language shows you that even a simple system has a big possibility to generate surprising
12 | and complex structures, and then brings a big amazing to you. A set of those structures, you would
13 | get, has often been called ”generative art” for having both organic and mechanical in itself.
14 | If you want to create ”generative art” intuitively, this powerful language will be your best friend.
15 |
16 |
17 |
18 | ## Notes
19 |
20 | This is a javascript implementation for generating in real time in your browser.
21 | Original implementation is included in Structure Synth authored by Mikael Hvidtfeldt.
22 |
23 | ## License
24 |
25 | Copyright (c) 2013-2020 Satoshi Okami. See the LICENSE file for license rights and limitations (MIT).
26 |
--------------------------------------------------------------------------------
/test/behavior/should_be_good_interpreter.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | const { assert } = require('chai');
4 | const fs = require('fs');
5 | const parser = require('../../src/parser');
6 | const Interpreter = require('../../src/Interpreter');
7 |
8 | // read testset from testset directory
9 | function read(testset, encoding = 'utf8') {
10 | return Promise.resolve()
11 | .then(() => {
12 | return fs.readFileSync(testset, encoding);
13 | })
14 | .then((data) => {
15 | const m = data.trim().match(/^\/\+\n([\s\S.]*)\n\+\/\n([\s\S.]*)/);
16 | if (m) {
17 | return {
18 | source: m[1],
19 | expected: m[2]
20 | };
21 | }
22 | return Promise.reject(new Error(`testset format is not correct: ${testset}`));
23 | });
24 | }
25 |
26 | // compile eisenscript code and return intermediate object
27 | function compile(source) {
28 | const ast = parser.parse(source);
29 | const interpreter = new Interpreter();
30 | const object = interpreter.generate(ast);
31 | // console.log(JSON.stringify(object));
32 | return object;
33 | }
34 |
35 | module.exports = function(testset) {
36 | it(testset, function() {
37 | return read(testset)
38 | .then(({ source, expected }) => {
39 | const output = compile(source);
40 | assert.deepEqual(JSON.stringify(output), expected);
41 | });
42 | });
43 | }
44 |
45 | module.exports.compile = compile;
46 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "eisenscript",
3 | "version": "2.2.2",
4 | "scripts": {
5 | "start": "$(npm bin)/gulp serve",
6 | "test": "$(npm bin)/istanbul cover $(npm bin)/_mocha test -- --recursive",
7 | "jison": "$(npm bin)/jison src/parser.jison -o src/parser.js",
8 | "build": "$(npm bin)/webpack --config webpack.config.js -p",
9 | "release": "npm login && $(npm bin)/release-it",
10 | "serve-doc": "$(npm bin)/docpress serve",
11 | "build-doc": "$(npm bin)/docpress build"
12 | },
13 | "devDependencies": {
14 | "babel-core": "^6.17.0",
15 | "babel-loader": "^6.2.5",
16 | "babel-preset-es2015": "^6.16.0",
17 | "babel-register": "^6.16.3",
18 | "browser-sync": "^2.29.1",
19 | "chai": "^4.2.0",
20 | "color-js": "^1.0.3",
21 | "docpress": "^0.8.2",
22 | "gulp": "^4.0.2",
23 | "gulp-load-plugins": "^2.0.3",
24 | "gulp-plumber": "^1.0.1",
25 | "gulp-spawn-mocha": "^6.0.0",
26 | "istanbul": "^0.4.5",
27 | "jison": "^0.4.17",
28 | "mocha": "^7.1.1",
29 | "release-it": "^15.10.1",
30 | "webpack": "^1.13.2",
31 | "webpack-stream": "^3.2.0"
32 | },
33 | "dependencies": {},
34 | "eslintConfig": {
35 | "env": {
36 | "es6": true,
37 | "node": true,
38 | "browser": true
39 | },
40 | "rules": {
41 | "quotes": [
42 | 2,
43 | "single"
44 | ]
45 | }
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/gulpfile.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | const gulp = require('gulp');
4 | const gulpLoadPlugins = require('gulp-load-plugins');
5 | const webpack = require('webpack-stream');
6 | const browserSync = require('browser-sync');
7 | const $ = gulpLoadPlugins();
8 | const reload = browserSync.reload;
9 |
10 | /**
11 | * regression test
12 | */
13 | gulp.task('watch:test', () => {
14 | gulp.watch([
15 | 'src/**/*',
16 | 'test/**/*'
17 | ], gulp.series('test'));
18 | });
19 |
20 | /**
21 | * unit test
22 | */
23 | gulp.task('test', () => {
24 | return gulp.src('test/**/inter*.js')
25 | .pipe($.plumber())
26 | .pipe($.spawnMocha());
27 | });
28 |
29 | /**
30 | * build source code as eisenscript library
31 | */
32 | gulp.task('webpack', () => {
33 | const config = require('./webpack.config');
34 | const entry = Object.values(config.entry);
35 | return gulp.src(entry)
36 | .pipe(webpack(config))
37 | .pipe(gulp.dest('build/'));
38 | });
39 |
40 | /**
41 | * start web app
42 | */
43 | gulp.task('serve', () => {
44 | browserSync({
45 | notify: false,
46 | port: 9000,
47 | startPath: '/examples',
48 | open: 'external',
49 | server: {
50 | baseDir: ['.']
51 | }
52 | });
53 |
54 | gulp.watch([
55 | 'src/**/*'
56 | ], gulp.series('webpack'));
57 |
58 | gulp.watch([
59 | 'src/**/*',
60 | 'examples/**/*',
61 | ]).on('change', reload);
62 | });
63 |
64 | gulp.task('serve:dist', () => {
65 | browserSync({
66 | notify: false,
67 | port: 9000,
68 | server: {
69 | baseDir: ['dist']
70 | }
71 | });
72 | });
73 |
--------------------------------------------------------------------------------
/src/Symbol.js:
--------------------------------------------------------------------------------
1 | module.exports = class Symbol {
2 | static get Define() { return 'define'; }
3 | static get Set() { return 'set'; }
4 | static get Statement() { return 'statement'; }
5 | static get Primitive() { return 'primitive'; }
6 | static get Rule() { return 'rule'; }
7 | static get Modifier() { return 'modifier'; }
8 | static get Maxdepth() { return 'maxdepth'; }
9 | static get Maxobjects() { return 'maxobjects'; }
10 | static get Minsize() { return 'minsize'; }
11 | static get Maxsize() { return 'maxsize'; }
12 | static get Seed() { return 'seed'; }
13 | static get Weight() { return 'weight'; }
14 | static get Background() { return 'background'; }
15 | static get XShift() { return 'xshift'; }
16 | static get YShift() { return 'yshift'; }
17 | static get ZShift() { return 'zshift'; }
18 | static get RotateX() { return 'rotatex'; }
19 | static get RotateY() { return 'rotatey'; }
20 | static get RotateZ() { return 'rotatez'; }
21 | static get FX() { return 'fx'; }
22 | static get FY() { return 'fy'; }
23 | static get FZ() { return 'fz'; }
24 | static get Size() { return 'size'; }
25 | static get Matrix() { return 'matrix'; }
26 | static get Color() { return 'color'; }
27 | static get ColorPool() { return 'colorpool'; }
28 | static get Hue() { return 'hue'; }
29 | static get Saturation() { return 'saturation'; }
30 | static get Brightness() { return 'brightness'; }
31 | static get Blend() { return 'blend'; }
32 | static get Alpha() { return 'alpha'; }
33 | static get ColorList() { return 'list'; }
34 | static get ColorRandomhue() { return 'randomhue'; }
35 | static get ColorRandomrgb() { return 'randomrgb'; }
36 | static get ColorGreyscale() { return 'greyscale'; }
37 | }
38 |
--------------------------------------------------------------------------------
/test/testset/colorspace/b.es.txt:
--------------------------------------------------------------------------------
1 | /+
2 | 10 * { x 1 b 0.9 } box
3 | +/
4 | {"minsize":0.2,"maxsize":1,"seed":"initial","objects":[{"type":"primitive","name":"box","matrix":{"elements":{"0":1,"1":0,"2":0,"3":0,"4":0,"5":1,"6":0,"7":0,"8":0,"9":0,"10":1,"11":0,"12":1,"13":0,"14":0,"15":1}},"color":"#E60000","opacity":1,"depth":1},{"type":"primitive","name":"box","matrix":{"elements":{"0":1,"1":0,"2":0,"3":0,"4":0,"5":1,"6":0,"7":0,"8":0,"9":0,"10":1,"11":0,"12":2,"13":0,"14":0,"15":1}},"color":"#CF0000","opacity":1,"depth":1},{"type":"primitive","name":"box","matrix":{"elements":{"0":1,"1":0,"2":0,"3":0,"4":0,"5":1,"6":0,"7":0,"8":0,"9":0,"10":1,"11":0,"12":3,"13":0,"14":0,"15":1}},"color":"#BA0000","opacity":1,"depth":1},{"type":"primitive","name":"box","matrix":{"elements":{"0":1,"1":0,"2":0,"3":0,"4":0,"5":1,"6":0,"7":0,"8":0,"9":0,"10":1,"11":0,"12":4,"13":0,"14":0,"15":1}},"color":"#A70000","opacity":1,"depth":1},{"type":"primitive","name":"box","matrix":{"elements":{"0":1,"1":0,"2":0,"3":0,"4":0,"5":1,"6":0,"7":0,"8":0,"9":0,"10":1,"11":0,"12":5,"13":0,"14":0,"15":1}},"color":"#970000","opacity":1,"depth":1},{"type":"primitive","name":"box","matrix":{"elements":{"0":1,"1":0,"2":0,"3":0,"4":0,"5":1,"6":0,"7":0,"8":0,"9":0,"10":1,"11":0,"12":6,"13":0,"14":0,"15":1}},"color":"#880000","opacity":1,"depth":1},{"type":"primitive","name":"box","matrix":{"elements":{"0":1,"1":0,"2":0,"3":0,"4":0,"5":1,"6":0,"7":0,"8":0,"9":0,"10":1,"11":0,"12":7,"13":0,"14":0,"15":1}},"color":"#7A0000","opacity":1,"depth":1},{"type":"primitive","name":"box","matrix":{"elements":{"0":1,"1":0,"2":0,"3":0,"4":0,"5":1,"6":0,"7":0,"8":0,"9":0,"10":1,"11":0,"12":8,"13":0,"14":0,"15":1}},"color":"#6E0000","opacity":1,"depth":1},{"type":"primitive","name":"box","matrix":{"elements":{"0":1,"1":0,"2":0,"3":0,"4":0,"5":1,"6":0,"7":0,"8":0,"9":0,"10":1,"11":0,"12":9,"13":0,"14":0,"15":1}},"color":"#630000","opacity":1,"depth":1},{"type":"primitive","name":"box","matrix":{"elements":{"0":1,"1":0,"2":0,"3":0,"4":0,"5":1,"6":0,"7":0,"8":0,"9":0,"10":1,"11":0,"12":10,"13":0,"14":0,"15":1}},"color":"#590000","opacity":1,"depth":1}],"num":10}
5 |
--------------------------------------------------------------------------------
/test/testset/colorspace/h.es.txt:
--------------------------------------------------------------------------------
1 | /+
2 | 10 * { x 2 h 10 } box
3 | +/
4 | {"minsize":0.2,"maxsize":1,"seed":"initial","objects":[{"type":"primitive","name":"box","matrix":{"elements":{"0":1,"1":0,"2":0,"3":0,"4":0,"5":1,"6":0,"7":0,"8":0,"9":0,"10":1,"11":0,"12":2,"13":0,"14":0,"15":1}},"color":"#FF2A00","opacity":1,"depth":1},{"type":"primitive","name":"box","matrix":{"elements":{"0":1,"1":0,"2":0,"3":0,"4":0,"5":1,"6":0,"7":0,"8":0,"9":0,"10":1,"11":0,"12":4,"13":0,"14":0,"15":1}},"color":"#FF5500","opacity":1,"depth":1},{"type":"primitive","name":"box","matrix":{"elements":{"0":1,"1":0,"2":0,"3":0,"4":0,"5":1,"6":0,"7":0,"8":0,"9":0,"10":1,"11":0,"12":6,"13":0,"14":0,"15":1}},"color":"#FF8000","opacity":1,"depth":1},{"type":"primitive","name":"box","matrix":{"elements":{"0":1,"1":0,"2":0,"3":0,"4":0,"5":1,"6":0,"7":0,"8":0,"9":0,"10":1,"11":0,"12":8,"13":0,"14":0,"15":1}},"color":"#FFAA00","opacity":1,"depth":1},{"type":"primitive","name":"box","matrix":{"elements":{"0":1,"1":0,"2":0,"3":0,"4":0,"5":1,"6":0,"7":0,"8":0,"9":0,"10":1,"11":0,"12":10,"13":0,"14":0,"15":1}},"color":"#FFD500","opacity":1,"depth":1},{"type":"primitive","name":"box","matrix":{"elements":{"0":1,"1":0,"2":0,"3":0,"4":0,"5":1,"6":0,"7":0,"8":0,"9":0,"10":1,"11":0,"12":12,"13":0,"14":0,"15":1}},"color":"#FFFF00","opacity":1,"depth":1},{"type":"primitive","name":"box","matrix":{"elements":{"0":1,"1":0,"2":0,"3":0,"4":0,"5":1,"6":0,"7":0,"8":0,"9":0,"10":1,"11":0,"12":14,"13":0,"14":0,"15":1}},"color":"#D4FF00","opacity":1,"depth":1},{"type":"primitive","name":"box","matrix":{"elements":{"0":1,"1":0,"2":0,"3":0,"4":0,"5":1,"6":0,"7":0,"8":0,"9":0,"10":1,"11":0,"12":16,"13":0,"14":0,"15":1}},"color":"#AAFF00","opacity":1,"depth":1},{"type":"primitive","name":"box","matrix":{"elements":{"0":1,"1":0,"2":0,"3":0,"4":0,"5":1,"6":0,"7":0,"8":0,"9":0,"10":1,"11":0,"12":18,"13":0,"14":0,"15":1}},"color":"#80FF00","opacity":1,"depth":1},{"type":"primitive","name":"box","matrix":{"elements":{"0":1,"1":0,"2":0,"3":0,"4":0,"5":1,"6":0,"7":0,"8":0,"9":0,"10":1,"11":0,"12":20,"13":0,"14":0,"15":1}},"color":"#55FF00","opacity":1,"depth":1}],"num":10}
5 |
--------------------------------------------------------------------------------
/test/testset/colorspace/sat.es.txt:
--------------------------------------------------------------------------------
1 | /+
2 | 10 * { x 1 sat 0.9 } box
3 | +/
4 | {"minsize":0.2,"maxsize":1,"seed":"initial","objects":[{"type":"primitive","name":"box","matrix":{"elements":{"0":1,"1":0,"2":0,"3":0,"4":0,"5":1,"6":0,"7":0,"8":0,"9":0,"10":1,"11":0,"12":1,"13":0,"14":0,"15":1}},"color":"#FF1919","opacity":1,"depth":1},{"type":"primitive","name":"box","matrix":{"elements":{"0":1,"1":0,"2":0,"3":0,"4":0,"5":1,"6":0,"7":0,"8":0,"9":0,"10":1,"11":0,"12":2,"13":0,"14":0,"15":1}},"color":"#FF3030","opacity":1,"depth":1},{"type":"primitive","name":"box","matrix":{"elements":{"0":1,"1":0,"2":0,"3":0,"4":0,"5":1,"6":0,"7":0,"8":0,"9":0,"10":1,"11":0,"12":3,"13":0,"14":0,"15":1}},"color":"#FF4545","opacity":1,"depth":1},{"type":"primitive","name":"box","matrix":{"elements":{"0":1,"1":0,"2":0,"3":0,"4":0,"5":1,"6":0,"7":0,"8":0,"9":0,"10":1,"11":0,"12":4,"13":0,"14":0,"15":1}},"color":"#FF5858","opacity":1,"depth":1},{"type":"primitive","name":"box","matrix":{"elements":{"0":1,"1":0,"2":0,"3":0,"4":0,"5":1,"6":0,"7":0,"8":0,"9":0,"10":1,"11":0,"12":5,"13":0,"14":0,"15":1}},"color":"#FF6868","opacity":1,"depth":1},{"type":"primitive","name":"box","matrix":{"elements":{"0":1,"1":0,"2":0,"3":0,"4":0,"5":1,"6":0,"7":0,"8":0,"9":0,"10":1,"11":0,"12":6,"13":0,"14":0,"15":1}},"color":"#FF7777","opacity":1,"depth":1},{"type":"primitive","name":"box","matrix":{"elements":{"0":1,"1":0,"2":0,"3":0,"4":0,"5":1,"6":0,"7":0,"8":0,"9":0,"10":1,"11":0,"12":7,"13":0,"14":0,"15":1}},"color":"#FF8585","opacity":1,"depth":1},{"type":"primitive","name":"box","matrix":{"elements":{"0":1,"1":0,"2":0,"3":0,"4":0,"5":1,"6":0,"7":0,"8":0,"9":0,"10":1,"11":0,"12":8,"13":0,"14":0,"15":1}},"color":"#FF9191","opacity":1,"depth":1},{"type":"primitive","name":"box","matrix":{"elements":{"0":1,"1":0,"2":0,"3":0,"4":0,"5":1,"6":0,"7":0,"8":0,"9":0,"10":1,"11":0,"12":9,"13":0,"14":0,"15":1}},"color":"#FF9C9C","opacity":1,"depth":1},{"type":"primitive","name":"box","matrix":{"elements":{"0":1,"1":0,"2":0,"3":0,"4":0,"5":1,"6":0,"7":0,"8":0,"9":0,"10":1,"11":0,"12":10,"13":0,"14":0,"15":1}},"color":"#FFA6A6","opacity":1,"depth":1}],"num":10}
5 |
--------------------------------------------------------------------------------
/test/testset/colorspace/hue.es.txt:
--------------------------------------------------------------------------------
1 | /+
2 | 10 * { x 2 hue 10 } box
3 | +/
4 | {"minsize":0.2,"maxsize":1,"seed":"initial","objects":[{"type":"primitive","name":"box","matrix":{"elements":{"0":1,"1":0,"2":0,"3":0,"4":0,"5":1,"6":0,"7":0,"8":0,"9":0,"10":1,"11":0,"12":2,"13":0,"14":0,"15":1}},"color":"#FF2A00","opacity":1,"depth":1},{"type":"primitive","name":"box","matrix":{"elements":{"0":1,"1":0,"2":0,"3":0,"4":0,"5":1,"6":0,"7":0,"8":0,"9":0,"10":1,"11":0,"12":4,"13":0,"14":0,"15":1}},"color":"#FF5500","opacity":1,"depth":1},{"type":"primitive","name":"box","matrix":{"elements":{"0":1,"1":0,"2":0,"3":0,"4":0,"5":1,"6":0,"7":0,"8":0,"9":0,"10":1,"11":0,"12":6,"13":0,"14":0,"15":1}},"color":"#FF8000","opacity":1,"depth":1},{"type":"primitive","name":"box","matrix":{"elements":{"0":1,"1":0,"2":0,"3":0,"4":0,"5":1,"6":0,"7":0,"8":0,"9":0,"10":1,"11":0,"12":8,"13":0,"14":0,"15":1}},"color":"#FFAA00","opacity":1,"depth":1},{"type":"primitive","name":"box","matrix":{"elements":{"0":1,"1":0,"2":0,"3":0,"4":0,"5":1,"6":0,"7":0,"8":0,"9":0,"10":1,"11":0,"12":10,"13":0,"14":0,"15":1}},"color":"#FFD500","opacity":1,"depth":1},{"type":"primitive","name":"box","matrix":{"elements":{"0":1,"1":0,"2":0,"3":0,"4":0,"5":1,"6":0,"7":0,"8":0,"9":0,"10":1,"11":0,"12":12,"13":0,"14":0,"15":1}},"color":"#FFFF00","opacity":1,"depth":1},{"type":"primitive","name":"box","matrix":{"elements":{"0":1,"1":0,"2":0,"3":0,"4":0,"5":1,"6":0,"7":0,"8":0,"9":0,"10":1,"11":0,"12":14,"13":0,"14":0,"15":1}},"color":"#D4FF00","opacity":1,"depth":1},{"type":"primitive","name":"box","matrix":{"elements":{"0":1,"1":0,"2":0,"3":0,"4":0,"5":1,"6":0,"7":0,"8":0,"9":0,"10":1,"11":0,"12":16,"13":0,"14":0,"15":1}},"color":"#AAFF00","opacity":1,"depth":1},{"type":"primitive","name":"box","matrix":{"elements":{"0":1,"1":0,"2":0,"3":0,"4":0,"5":1,"6":0,"7":0,"8":0,"9":0,"10":1,"11":0,"12":18,"13":0,"14":0,"15":1}},"color":"#80FF00","opacity":1,"depth":1},{"type":"primitive","name":"box","matrix":{"elements":{"0":1,"1":0,"2":0,"3":0,"4":0,"5":1,"6":0,"7":0,"8":0,"9":0,"10":1,"11":0,"12":20,"13":0,"14":0,"15":1}},"color":"#55FF00","opacity":1,"depth":1}],"num":10}
5 |
--------------------------------------------------------------------------------
/test/testset/colorspace/brightness.es.txt:
--------------------------------------------------------------------------------
1 | /+
2 | 10 * { x 1 brightness 0.9 } box
3 | +/
4 | {"minsize":0.2,"maxsize":1,"seed":"initial","objects":[{"type":"primitive","name":"box","matrix":{"elements":{"0":1,"1":0,"2":0,"3":0,"4":0,"5":1,"6":0,"7":0,"8":0,"9":0,"10":1,"11":0,"12":1,"13":0,"14":0,"15":1}},"color":"#E60000","opacity":1,"depth":1},{"type":"primitive","name":"box","matrix":{"elements":{"0":1,"1":0,"2":0,"3":0,"4":0,"5":1,"6":0,"7":0,"8":0,"9":0,"10":1,"11":0,"12":2,"13":0,"14":0,"15":1}},"color":"#CF0000","opacity":1,"depth":1},{"type":"primitive","name":"box","matrix":{"elements":{"0":1,"1":0,"2":0,"3":0,"4":0,"5":1,"6":0,"7":0,"8":0,"9":0,"10":1,"11":0,"12":3,"13":0,"14":0,"15":1}},"color":"#BA0000","opacity":1,"depth":1},{"type":"primitive","name":"box","matrix":{"elements":{"0":1,"1":0,"2":0,"3":0,"4":0,"5":1,"6":0,"7":0,"8":0,"9":0,"10":1,"11":0,"12":4,"13":0,"14":0,"15":1}},"color":"#A70000","opacity":1,"depth":1},{"type":"primitive","name":"box","matrix":{"elements":{"0":1,"1":0,"2":0,"3":0,"4":0,"5":1,"6":0,"7":0,"8":0,"9":0,"10":1,"11":0,"12":5,"13":0,"14":0,"15":1}},"color":"#970000","opacity":1,"depth":1},{"type":"primitive","name":"box","matrix":{"elements":{"0":1,"1":0,"2":0,"3":0,"4":0,"5":1,"6":0,"7":0,"8":0,"9":0,"10":1,"11":0,"12":6,"13":0,"14":0,"15":1}},"color":"#880000","opacity":1,"depth":1},{"type":"primitive","name":"box","matrix":{"elements":{"0":1,"1":0,"2":0,"3":0,"4":0,"5":1,"6":0,"7":0,"8":0,"9":0,"10":1,"11":0,"12":7,"13":0,"14":0,"15":1}},"color":"#7A0000","opacity":1,"depth":1},{"type":"primitive","name":"box","matrix":{"elements":{"0":1,"1":0,"2":0,"3":0,"4":0,"5":1,"6":0,"7":0,"8":0,"9":0,"10":1,"11":0,"12":8,"13":0,"14":0,"15":1}},"color":"#6E0000","opacity":1,"depth":1},{"type":"primitive","name":"box","matrix":{"elements":{"0":1,"1":0,"2":0,"3":0,"4":0,"5":1,"6":0,"7":0,"8":0,"9":0,"10":1,"11":0,"12":9,"13":0,"14":0,"15":1}},"color":"#630000","opacity":1,"depth":1},{"type":"primitive","name":"box","matrix":{"elements":{"0":1,"1":0,"2":0,"3":0,"4":0,"5":1,"6":0,"7":0,"8":0,"9":0,"10":1,"11":0,"12":10,"13":0,"14":0,"15":1}},"color":"#590000","opacity":1,"depth":1}],"num":10}
5 |
--------------------------------------------------------------------------------
/test/testset/colorspace/saturation.es.txt:
--------------------------------------------------------------------------------
1 | /+
2 | 10 * { x 1 saturation 0.9 } box
3 | +/
4 | {"minsize":0.2,"maxsize":1,"seed":"initial","objects":[{"type":"primitive","name":"box","matrix":{"elements":{"0":1,"1":0,"2":0,"3":0,"4":0,"5":1,"6":0,"7":0,"8":0,"9":0,"10":1,"11":0,"12":1,"13":0,"14":0,"15":1}},"color":"#FF1919","opacity":1,"depth":1},{"type":"primitive","name":"box","matrix":{"elements":{"0":1,"1":0,"2":0,"3":0,"4":0,"5":1,"6":0,"7":0,"8":0,"9":0,"10":1,"11":0,"12":2,"13":0,"14":0,"15":1}},"color":"#FF3030","opacity":1,"depth":1},{"type":"primitive","name":"box","matrix":{"elements":{"0":1,"1":0,"2":0,"3":0,"4":0,"5":1,"6":0,"7":0,"8":0,"9":0,"10":1,"11":0,"12":3,"13":0,"14":0,"15":1}},"color":"#FF4545","opacity":1,"depth":1},{"type":"primitive","name":"box","matrix":{"elements":{"0":1,"1":0,"2":0,"3":0,"4":0,"5":1,"6":0,"7":0,"8":0,"9":0,"10":1,"11":0,"12":4,"13":0,"14":0,"15":1}},"color":"#FF5858","opacity":1,"depth":1},{"type":"primitive","name":"box","matrix":{"elements":{"0":1,"1":0,"2":0,"3":0,"4":0,"5":1,"6":0,"7":0,"8":0,"9":0,"10":1,"11":0,"12":5,"13":0,"14":0,"15":1}},"color":"#FF6868","opacity":1,"depth":1},{"type":"primitive","name":"box","matrix":{"elements":{"0":1,"1":0,"2":0,"3":0,"4":0,"5":1,"6":0,"7":0,"8":0,"9":0,"10":1,"11":0,"12":6,"13":0,"14":0,"15":1}},"color":"#FF7777","opacity":1,"depth":1},{"type":"primitive","name":"box","matrix":{"elements":{"0":1,"1":0,"2":0,"3":0,"4":0,"5":1,"6":0,"7":0,"8":0,"9":0,"10":1,"11":0,"12":7,"13":0,"14":0,"15":1}},"color":"#FF8585","opacity":1,"depth":1},{"type":"primitive","name":"box","matrix":{"elements":{"0":1,"1":0,"2":0,"3":0,"4":0,"5":1,"6":0,"7":0,"8":0,"9":0,"10":1,"11":0,"12":8,"13":0,"14":0,"15":1}},"color":"#FF9191","opacity":1,"depth":1},{"type":"primitive","name":"box","matrix":{"elements":{"0":1,"1":0,"2":0,"3":0,"4":0,"5":1,"6":0,"7":0,"8":0,"9":0,"10":1,"11":0,"12":9,"13":0,"14":0,"15":1}},"color":"#FF9C9C","opacity":1,"depth":1},{"type":"primitive","name":"box","matrix":{"elements":{"0":1,"1":0,"2":0,"3":0,"4":0,"5":1,"6":0,"7":0,"8":0,"9":0,"10":1,"11":0,"12":10,"13":0,"14":0,"15":1}},"color":"#FFA6A6","opacity":1,"depth":1}],"num":10}
5 |
--------------------------------------------------------------------------------
/test/testset/actions/seed/seed.es.txt:
--------------------------------------------------------------------------------
1 | /+
2 | set seed 1
3 |
4 | 10 * { x 1 color random } box
5 | +/
6 | {"minsize":0.2,"maxsize":1,"seed":1,"objects":[{"type":"primitive","name":"box","matrix":{"elements":{"0":1,"1":0,"2":0,"3":0,"4":0,"5":1,"6":0,"7":0,"8":0,"9":0,"10":1,"11":0,"12":1,"13":0,"14":0,"15":1}},"color":"#6AC1F3","opacity":1,"depth":1},{"type":"primitive","name":"box","matrix":{"elements":{"0":1,"1":0,"2":0,"3":0,"4":0,"5":1,"6":0,"7":0,"8":0,"9":0,"10":1,"11":0,"12":2,"13":0,"14":0,"15":1}},"color":"#B8672E","opacity":1,"depth":1},{"type":"primitive","name":"box","matrix":{"elements":{"0":1,"1":0,"2":0,"3":0,"4":0,"5":1,"6":0,"7":0,"8":0,"9":0,"10":1,"11":0,"12":3,"13":0,"14":0,"15":1}},"color":"#7777EE","opacity":1,"depth":1},{"type":"primitive","name":"box","matrix":{"elements":{"0":1,"1":0,"2":0,"3":0,"4":0,"5":1,"6":0,"7":0,"8":0,"9":0,"10":1,"11":0,"12":4,"13":0,"14":0,"15":1}},"color":"#4D65AA","opacity":1,"depth":1},{"type":"primitive","name":"box","matrix":{"elements":{"0":1,"1":0,"2":0,"3":0,"4":0,"5":1,"6":0,"7":0,"8":0,"9":0,"10":1,"11":0,"12":5,"13":0,"14":0,"15":1}},"color":"#2591CB","opacity":1,"depth":1},{"type":"primitive","name":"box","matrix":{"elements":{"0":1,"1":0,"2":0,"3":0,"4":0,"5":1,"6":0,"7":0,"8":0,"9":0,"10":1,"11":0,"12":6,"13":0,"14":0,"15":1}},"color":"#17A380","opacity":1,"depth":1},{"type":"primitive","name":"box","matrix":{"elements":{"0":1,"1":0,"2":0,"3":0,"4":0,"5":1,"6":0,"7":0,"8":0,"9":0,"10":1,"11":0,"12":7,"13":0,"14":0,"15":1}},"color":"#2FAEBF","opacity":1,"depth":1},{"type":"primitive","name":"box","matrix":{"elements":{"0":1,"1":0,"2":0,"3":0,"4":0,"5":1,"6":0,"7":0,"8":0,"9":0,"10":1,"11":0,"12":8,"13":0,"14":0,"15":1}},"color":"#5876AA","opacity":1,"depth":1},{"type":"primitive","name":"box","matrix":{"elements":{"0":1,"1":0,"2":0,"3":0,"4":0,"5":1,"6":0,"7":0,"8":0,"9":0,"10":1,"11":0,"12":9,"13":0,"14":0,"15":1}},"color":"#65928D","opacity":1,"depth":1},{"type":"primitive","name":"box","matrix":{"elements":{"0":1,"1":0,"2":0,"3":0,"4":0,"5":1,"6":0,"7":0,"8":0,"9":0,"10":1,"11":0,"12":10,"13":0,"14":0,"15":1}},"color":"#89EFE4","opacity":1,"depth":1}],"num":10}
7 |
--------------------------------------------------------------------------------
/test/testset/colorspace/a.es.txt:
--------------------------------------------------------------------------------
1 | /+
2 | 10 * { x 1 a 0.5 } box
3 | +/
4 | {"minsize":0.2,"maxsize":1,"seed":"initial","objects":[{"type":"primitive","name":"box","matrix":{"elements":{"0":1,"1":0,"2":0,"3":0,"4":0,"5":1,"6":0,"7":0,"8":0,"9":0,"10":1,"11":0,"12":1,"13":0,"14":0,"15":1}},"color":"#FF0000","opacity":0.5,"depth":1},{"type":"primitive","name":"box","matrix":{"elements":{"0":1,"1":0,"2":0,"3":0,"4":0,"5":1,"6":0,"7":0,"8":0,"9":0,"10":1,"11":0,"12":2,"13":0,"14":0,"15":1}},"color":"#FF0000","opacity":0.25,"depth":1},{"type":"primitive","name":"box","matrix":{"elements":{"0":1,"1":0,"2":0,"3":0,"4":0,"5":1,"6":0,"7":0,"8":0,"9":0,"10":1,"11":0,"12":3,"13":0,"14":0,"15":1}},"color":"#FF0000","opacity":0.125,"depth":1},{"type":"primitive","name":"box","matrix":{"elements":{"0":1,"1":0,"2":0,"3":0,"4":0,"5":1,"6":0,"7":0,"8":0,"9":0,"10":1,"11":0,"12":4,"13":0,"14":0,"15":1}},"color":"#FF0000","opacity":0.0625,"depth":1},{"type":"primitive","name":"box","matrix":{"elements":{"0":1,"1":0,"2":0,"3":0,"4":0,"5":1,"6":0,"7":0,"8":0,"9":0,"10":1,"11":0,"12":5,"13":0,"14":0,"15":1}},"color":"#FF0000","opacity":0.03125,"depth":1},{"type":"primitive","name":"box","matrix":{"elements":{"0":1,"1":0,"2":0,"3":0,"4":0,"5":1,"6":0,"7":0,"8":0,"9":0,"10":1,"11":0,"12":6,"13":0,"14":0,"15":1}},"color":"#FF0000","opacity":0.015625,"depth":1},{"type":"primitive","name":"box","matrix":{"elements":{"0":1,"1":0,"2":0,"3":0,"4":0,"5":1,"6":0,"7":0,"8":0,"9":0,"10":1,"11":0,"12":7,"13":0,"14":0,"15":1}},"color":"#FF0000","opacity":0.0078125,"depth":1},{"type":"primitive","name":"box","matrix":{"elements":{"0":1,"1":0,"2":0,"3":0,"4":0,"5":1,"6":0,"7":0,"8":0,"9":0,"10":1,"11":0,"12":8,"13":0,"14":0,"15":1}},"color":"#FF0000","opacity":0.00390625,"depth":1},{"type":"primitive","name":"box","matrix":{"elements":{"0":1,"1":0,"2":0,"3":0,"4":0,"5":1,"6":0,"7":0,"8":0,"9":0,"10":1,"11":0,"12":9,"13":0,"14":0,"15":1}},"color":"#FF0000","opacity":0.001953125,"depth":1},{"type":"primitive","name":"box","matrix":{"elements":{"0":1,"1":0,"2":0,"3":0,"4":0,"5":1,"6":0,"7":0,"8":0,"9":0,"10":1,"11":0,"12":10,"13":0,"14":0,"15":1}},"color":"#FF0000","opacity":0.0009765625,"depth":1}],"num":10}
5 |
--------------------------------------------------------------------------------
/test/testset/colorspace/alpha.es.txt:
--------------------------------------------------------------------------------
1 | /+
2 | 10 * { x 1 alpha 0.5 } box
3 | +/
4 | {"minsize":0.2,"maxsize":1,"seed":"initial","objects":[{"type":"primitive","name":"box","matrix":{"elements":{"0":1,"1":0,"2":0,"3":0,"4":0,"5":1,"6":0,"7":0,"8":0,"9":0,"10":1,"11":0,"12":1,"13":0,"14":0,"15":1}},"color":"#FF0000","opacity":0.5,"depth":1},{"type":"primitive","name":"box","matrix":{"elements":{"0":1,"1":0,"2":0,"3":0,"4":0,"5":1,"6":0,"7":0,"8":0,"9":0,"10":1,"11":0,"12":2,"13":0,"14":0,"15":1}},"color":"#FF0000","opacity":0.25,"depth":1},{"type":"primitive","name":"box","matrix":{"elements":{"0":1,"1":0,"2":0,"3":0,"4":0,"5":1,"6":0,"7":0,"8":0,"9":0,"10":1,"11":0,"12":3,"13":0,"14":0,"15":1}},"color":"#FF0000","opacity":0.125,"depth":1},{"type":"primitive","name":"box","matrix":{"elements":{"0":1,"1":0,"2":0,"3":0,"4":0,"5":1,"6":0,"7":0,"8":0,"9":0,"10":1,"11":0,"12":4,"13":0,"14":0,"15":1}},"color":"#FF0000","opacity":0.0625,"depth":1},{"type":"primitive","name":"box","matrix":{"elements":{"0":1,"1":0,"2":0,"3":0,"4":0,"5":1,"6":0,"7":0,"8":0,"9":0,"10":1,"11":0,"12":5,"13":0,"14":0,"15":1}},"color":"#FF0000","opacity":0.03125,"depth":1},{"type":"primitive","name":"box","matrix":{"elements":{"0":1,"1":0,"2":0,"3":0,"4":0,"5":1,"6":0,"7":0,"8":0,"9":0,"10":1,"11":0,"12":6,"13":0,"14":0,"15":1}},"color":"#FF0000","opacity":0.015625,"depth":1},{"type":"primitive","name":"box","matrix":{"elements":{"0":1,"1":0,"2":0,"3":0,"4":0,"5":1,"6":0,"7":0,"8":0,"9":0,"10":1,"11":0,"12":7,"13":0,"14":0,"15":1}},"color":"#FF0000","opacity":0.0078125,"depth":1},{"type":"primitive","name":"box","matrix":{"elements":{"0":1,"1":0,"2":0,"3":0,"4":0,"5":1,"6":0,"7":0,"8":0,"9":0,"10":1,"11":0,"12":8,"13":0,"14":0,"15":1}},"color":"#FF0000","opacity":0.00390625,"depth":1},{"type":"primitive","name":"box","matrix":{"elements":{"0":1,"1":0,"2":0,"3":0,"4":0,"5":1,"6":0,"7":0,"8":0,"9":0,"10":1,"11":0,"12":9,"13":0,"14":0,"15":1}},"color":"#FF0000","opacity":0.001953125,"depth":1},{"type":"primitive","name":"box","matrix":{"elements":{"0":1,"1":0,"2":0,"3":0,"4":0,"5":1,"6":0,"7":0,"8":0,"9":0,"10":1,"11":0,"12":10,"13":0,"14":0,"15":1}},"color":"#FF0000","opacity":0.0009765625,"depth":1}],"num":10}
5 |
--------------------------------------------------------------------------------
/test/testset/colorspace/blend.hex.and.hsv.es.txt:
--------------------------------------------------------------------------------
1 | /+
2 | rule R1 md 10 {
3 | { x 2 color blue hue 36 } R1
4 | box
5 | }
6 |
7 | R1
8 | +/
9 | {"minsize":0.2,"maxsize":1,"seed":"initial","objects":[{"type":"primitive","name":"box","matrix":{"elements":{"0":1,"1":0,"2":0,"3":0,"4":0,"5":1,"6":0,"7":0,"8":0,"9":0,"10":1,"11":0,"12":18,"13":0,"14":0,"15":1}},"color":"#9900FF","opacity":1,"depth":9},{"type":"primitive","name":"box","matrix":{"elements":{"0":1,"1":0,"2":0,"3":0,"4":0,"5":1,"6":0,"7":0,"8":0,"9":0,"10":1,"11":0,"12":16,"13":0,"14":0,"15":1}},"color":"#9900FF","opacity":1,"depth":8},{"type":"primitive","name":"box","matrix":{"elements":{"0":1,"1":0,"2":0,"3":0,"4":0,"5":1,"6":0,"7":0,"8":0,"9":0,"10":1,"11":0,"12":14,"13":0,"14":0,"15":1}},"color":"#9900FF","opacity":1,"depth":7},{"type":"primitive","name":"box","matrix":{"elements":{"0":1,"1":0,"2":0,"3":0,"4":0,"5":1,"6":0,"7":0,"8":0,"9":0,"10":1,"11":0,"12":12,"13":0,"14":0,"15":1}},"color":"#9900FF","opacity":1,"depth":6},{"type":"primitive","name":"box","matrix":{"elements":{"0":1,"1":0,"2":0,"3":0,"4":0,"5":1,"6":0,"7":0,"8":0,"9":0,"10":1,"11":0,"12":10,"13":0,"14":0,"15":1}},"color":"#9900FF","opacity":1,"depth":5},{"type":"primitive","name":"box","matrix":{"elements":{"0":1,"1":0,"2":0,"3":0,"4":0,"5":1,"6":0,"7":0,"8":0,"9":0,"10":1,"11":0,"12":8,"13":0,"14":0,"15":1}},"color":"#9900FF","opacity":1,"depth":4},{"type":"primitive","name":"box","matrix":{"elements":{"0":1,"1":0,"2":0,"3":0,"4":0,"5":1,"6":0,"7":0,"8":0,"9":0,"10":1,"11":0,"12":6,"13":0,"14":0,"15":1}},"color":"#9900FF","opacity":1,"depth":3},{"type":"primitive","name":"box","matrix":{"elements":{"0":1,"1":0,"2":0,"3":0,"4":0,"5":1,"6":0,"7":0,"8":0,"9":0,"10":1,"11":0,"12":4,"13":0,"14":0,"15":1}},"color":"#9900FF","opacity":1,"depth":2},{"type":"primitive","name":"box","matrix":{"elements":{"0":1,"1":0,"2":0,"3":0,"4":0,"5":1,"6":0,"7":0,"8":0,"9":0,"10":1,"11":0,"12":2,"13":0,"14":0,"15":1}},"color":"#9900FF","opacity":1,"depth":1},{"type":"primitive","name":"box","matrix":{"elements":{"0":1,"1":0,"2":0,"3":0,"4":0,"5":1,"6":0,"7":0,"8":0,"9":0,"10":1,"11":0,"12":0,"13":0,"14":0,"15":1}},"color":"#FF0000","opacity":1,"depth":0}],"num":10}
10 |
--------------------------------------------------------------------------------
/examples/export.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Export Test
5 |
6 |
16 |
17 |
18 | obj file
19 |
20 |
21 |
22 |
80 |
81 |
82 |
--------------------------------------------------------------------------------
/test/testset/actions/maxdepth/maxdepth.strange.es.txt:
--------------------------------------------------------------------------------
1 | /+
2 | set maxdepth 10
3 |
4 | rule R1 {
5 | box { x 1 hue 36 rx 10 } R1
6 | }
7 |
8 | R1
9 | +/
10 | {"maxdepth":10,"minsize":0.2,"maxsize":1,"seed":"initial","objects":[{"type":"primitive","name":"box","matrix":{"elements":{"0":1,"1":0,"2":0,"3":0,"4":0,"5":1,"6":0,"7":0,"8":0,"9":0,"10":1,"11":0,"12":0,"13":0,"14":0,"15":1}},"color":"#FF0000","opacity":1,"depth":0},{"type":"primitive","name":"box","matrix":{"elements":{"0":1,"1":0,"2":0,"3":0,"4":0,"5":0.9848077297210693,"6":0.1736481785774231,"7":0,"8":0,"9":-0.1736481785774231,"10":0.9848077297210693,"11":0,"12":1,"13":0,"14":0,"15":1}},"color":"#FF9900","opacity":1,"depth":1},{"type":"primitive","name":"box","matrix":{"elements":{"0":1,"1":0,"2":0,"3":0,"4":0,"5":0.9396926164627075,"6":0.3420201539993286,"7":0,"8":0,"9":-0.3420201539993286,"10":0.9396926164627075,"11":0,"12":2,"13":0,"14":0,"15":1}},"color":"#CCFF00","opacity":1,"depth":2},{"type":"primitive","name":"box","matrix":{"elements":{"0":1,"1":0,"2":0,"3":0,"4":0,"5":0.8660253882408142,"6":0.5,"7":0,"8":0,"9":-0.5,"10":0.8660253882408142,"11":0,"12":3,"13":0,"14":0,"15":1}},"color":"#33FF00","opacity":1,"depth":3},{"type":"primitive","name":"box","matrix":{"elements":{"0":1,"1":0,"2":0,"3":0,"4":0,"5":0.7660444378852844,"6":0.6427876353263855,"7":0,"8":0,"9":-0.6427876353263855,"10":0.7660444378852844,"11":0,"12":4,"13":0,"14":0,"15":1}},"color":"#00FF66","opacity":1,"depth":4},{"type":"primitive","name":"box","matrix":{"elements":{"0":1,"1":0,"2":0,"3":0,"4":0,"5":0.6427875757217407,"6":0.7660444378852844,"7":0,"8":0,"9":-0.7660444378852844,"10":0.6427875757217407,"11":0,"12":5,"13":0,"14":0,"15":1}},"color":"#00FFFF","opacity":1,"depth":5},{"type":"primitive","name":"box","matrix":{"elements":{"0":1,"1":0,"2":0,"3":0,"4":0,"5":0.4999999701976776,"6":0.8660253882408142,"7":0,"8":0,"9":-0.8660253882408142,"10":0.4999999701976776,"11":0,"12":6,"13":0,"14":0,"15":1}},"color":"#0066FF","opacity":1,"depth":6},{"type":"primitive","name":"box","matrix":{"elements":{"0":1,"1":0,"2":0,"3":0,"4":0,"5":0.3420201241970062,"6":0.9396926164627075,"7":0,"8":0,"9":-0.9396926164627075,"10":0.3420201241970062,"11":0,"12":7,"13":0,"14":0,"15":1}},"color":"#3300FF","opacity":1,"depth":7}],"num":8}
11 |
--------------------------------------------------------------------------------
/test/testset/modifiers/maxdepth/maxdepth.alternate_rule.es.txt:
--------------------------------------------------------------------------------
1 | /+
2 | 2 * { ry 60 } r
3 | rule r md 2 > k {
4 | sphere
5 | {x 2}r
6 | }
7 | rule k md 2 {
8 | box
9 | {y 2}k
10 | }
11 | +/
12 | {"minsize":0.2,"maxsize":1,"seed":"initial","objects":[{"type":"primitive","name":"sphere","matrix":{"elements":{"0":0.5,"1":0,"2":-0.8660253882408142,"3":0,"4":0,"5":1,"6":0,"7":0,"8":0.8660253882408142,"9":0,"10":0.5,"11":0,"12":0,"13":0,"14":0,"15":1}},"color":"#FF0000","opacity":1,"depth":1},{"type":"primitive","name":"sphere","matrix":{"elements":{"0":0.5,"1":0,"2":-0.8660253882408142,"3":0,"4":0,"5":1,"6":0,"7":0,"8":0.8660253882408142,"9":0,"10":0.5,"11":0,"12":1,"13":0,"14":-1.7320507764816284,"15":1}},"color":"#FF0000","opacity":1,"depth":2},{"type":"primitive","name":"box","matrix":{"elements":{"0":0.5,"1":0,"2":-0.8660253882408142,"3":0,"4":0,"5":1,"6":0,"7":0,"8":0.8660253882408142,"9":0,"10":0.5,"11":0,"12":2,"13":0,"14":-3.464101552963257,"15":1}},"color":"#FF0000","opacity":1,"depth":3},{"type":"primitive","name":"box","matrix":{"elements":{"0":0.5,"1":0,"2":-0.8660253882408142,"3":0,"4":0,"5":1,"6":0,"7":0,"8":0.8660253882408142,"9":0,"10":0.5,"11":0,"12":2,"13":2,"14":-3.464101552963257,"15":1}},"color":"#FF0000","opacity":1,"depth":4},{"type":"primitive","name":"sphere","matrix":{"elements":{"0":-0.5,"1":0,"2":-0.8660253882408142,"3":0,"4":0,"5":1,"6":0,"7":0,"8":0.8660253882408142,"9":0,"10":-0.5,"11":0,"12":0,"13":0,"14":0,"15":1}},"color":"#FF0000","opacity":1,"depth":1},{"type":"primitive","name":"sphere","matrix":{"elements":{"0":-0.5,"1":0,"2":-0.8660253882408142,"3":0,"4":0,"5":1,"6":0,"7":0,"8":0.8660253882408142,"9":0,"10":-0.5,"11":0,"12":-1,"13":0,"14":-1.7320507764816284,"15":1}},"color":"#FF0000","opacity":1,"depth":2},{"type":"primitive","name":"box","matrix":{"elements":{"0":-0.5,"1":0,"2":-0.8660253882408142,"3":0,"4":0,"5":1,"6":0,"7":0,"8":0.8660253882408142,"9":0,"10":-0.5,"11":0,"12":-2,"13":0,"14":-3.464101552963257,"15":1}},"color":"#FF0000","opacity":1,"depth":3},{"type":"primitive","name":"box","matrix":{"elements":{"0":-0.5,"1":0,"2":-0.8660253882408142,"3":0,"4":0,"5":1,"6":0,"7":0,"8":0.8660253882408142,"9":0,"10":-0.5,"11":0,"12":-2,"13":2,"14":-3.464101552963257,"15":1}},"color":"#FF0000","opacity":1,"depth":4}],"num":8}
13 |
--------------------------------------------------------------------------------
/examples/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
56 |
82 |
83 |
84 |
--------------------------------------------------------------------------------
/test/testset/modifiers/maxdepth/maxdepth.alternate_rule.define.varname.es.txt:
--------------------------------------------------------------------------------
1 | /+
2 | #define num 2
3 |
4 | 2 * { ry 60 } r
5 | rule r md num > k {
6 | sphere
7 | {x 2}r
8 | }
9 | rule k md 2 {
10 | box
11 | {y 2}k
12 | }
13 | +/
14 | {"minsize":0.2,"maxsize":1,"seed":"initial","objects":[{"type":"primitive","name":"sphere","matrix":{"elements":{"0":0.5,"1":0,"2":-0.8660253882408142,"3":0,"4":0,"5":1,"6":0,"7":0,"8":0.8660253882408142,"9":0,"10":0.5,"11":0,"12":0,"13":0,"14":0,"15":1}},"color":"#FF0000","opacity":1,"depth":1},{"type":"primitive","name":"sphere","matrix":{"elements":{"0":0.5,"1":0,"2":-0.8660253882408142,"3":0,"4":0,"5":1,"6":0,"7":0,"8":0.8660253882408142,"9":0,"10":0.5,"11":0,"12":1,"13":0,"14":-1.7320507764816284,"15":1}},"color":"#FF0000","opacity":1,"depth":2},{"type":"primitive","name":"box","matrix":{"elements":{"0":0.5,"1":0,"2":-0.8660253882408142,"3":0,"4":0,"5":1,"6":0,"7":0,"8":0.8660253882408142,"9":0,"10":0.5,"11":0,"12":2,"13":0,"14":-3.464101552963257,"15":1}},"color":"#FF0000","opacity":1,"depth":3},{"type":"primitive","name":"box","matrix":{"elements":{"0":0.5,"1":0,"2":-0.8660253882408142,"3":0,"4":0,"5":1,"6":0,"7":0,"8":0.8660253882408142,"9":0,"10":0.5,"11":0,"12":2,"13":2,"14":-3.464101552963257,"15":1}},"color":"#FF0000","opacity":1,"depth":4},{"type":"primitive","name":"sphere","matrix":{"elements":{"0":-0.5,"1":0,"2":-0.8660253882408142,"3":0,"4":0,"5":1,"6":0,"7":0,"8":0.8660253882408142,"9":0,"10":-0.5,"11":0,"12":0,"13":0,"14":0,"15":1}},"color":"#FF0000","opacity":1,"depth":1},{"type":"primitive","name":"sphere","matrix":{"elements":{"0":-0.5,"1":0,"2":-0.8660253882408142,"3":0,"4":0,"5":1,"6":0,"7":0,"8":0.8660253882408142,"9":0,"10":-0.5,"11":0,"12":-1,"13":0,"14":-1.7320507764816284,"15":1}},"color":"#FF0000","opacity":1,"depth":2},{"type":"primitive","name":"box","matrix":{"elements":{"0":-0.5,"1":0,"2":-0.8660253882408142,"3":0,"4":0,"5":1,"6":0,"7":0,"8":0.8660253882408142,"9":0,"10":-0.5,"11":0,"12":-2,"13":0,"14":-3.464101552963257,"15":1}},"color":"#FF0000","opacity":1,"depth":3},{"type":"primitive","name":"box","matrix":{"elements":{"0":-0.5,"1":0,"2":-0.8660253882408142,"3":0,"4":0,"5":1,"6":0,"7":0,"8":0.8660253882408142,"9":0,"10":-0.5,"11":0,"12":-2,"13":2,"14":-3.464101552963257,"15":1}},"color":"#FF0000","opacity":1,"depth":4}],"num":8}
15 |
--------------------------------------------------------------------------------
/test/testset/primitives/triangle.es.txt:
--------------------------------------------------------------------------------
1 | /+
2 | { x 2 } triangle
3 | 10 * { x 1 a 0.2 } box
4 | +/
5 | {"minsize":0.2,"maxsize":1,"seed":"initial","objects":[{"type":"primitive","name":"triangle","matrix":{"elements":{"0":1,"1":0,"2":0,"3":0,"4":0,"5":1,"6":0,"7":0,"8":0,"9":0,"10":1,"11":0,"12":2,"13":0,"14":0,"15":1}},"color":"#FF0000","opacity":1,"depth":1},{"type":"primitive","name":"box","matrix":{"elements":{"0":1,"1":0,"2":0,"3":0,"4":0,"5":1,"6":0,"7":0,"8":0,"9":0,"10":1,"11":0,"12":1,"13":0,"14":0,"15":1}},"color":"#FF0000","opacity":0.2,"depth":1},{"type":"primitive","name":"box","matrix":{"elements":{"0":1,"1":0,"2":0,"3":0,"4":0,"5":1,"6":0,"7":0,"8":0,"9":0,"10":1,"11":0,"12":2,"13":0,"14":0,"15":1}},"color":"#FF0000","opacity":0.04000000000000001,"depth":1},{"type":"primitive","name":"box","matrix":{"elements":{"0":1,"1":0,"2":0,"3":0,"4":0,"5":1,"6":0,"7":0,"8":0,"9":0,"10":1,"11":0,"12":3,"13":0,"14":0,"15":1}},"color":"#FF0000","opacity":0.008000000000000002,"depth":1},{"type":"primitive","name":"box","matrix":{"elements":{"0":1,"1":0,"2":0,"3":0,"4":0,"5":1,"6":0,"7":0,"8":0,"9":0,"10":1,"11":0,"12":4,"13":0,"14":0,"15":1}},"color":"#FF0000","opacity":0.0016000000000000005,"depth":1},{"type":"primitive","name":"box","matrix":{"elements":{"0":1,"1":0,"2":0,"3":0,"4":0,"5":1,"6":0,"7":0,"8":0,"9":0,"10":1,"11":0,"12":5,"13":0,"14":0,"15":1}},"color":"#FF0000","opacity":0.00032000000000000013,"depth":1},{"type":"primitive","name":"box","matrix":{"elements":{"0":1,"1":0,"2":0,"3":0,"4":0,"5":1,"6":0,"7":0,"8":0,"9":0,"10":1,"11":0,"12":6,"13":0,"14":0,"15":1}},"color":"#FF0000","opacity":0.00006400000000000002,"depth":1},{"type":"primitive","name":"box","matrix":{"elements":{"0":1,"1":0,"2":0,"3":0,"4":0,"5":1,"6":0,"7":0,"8":0,"9":0,"10":1,"11":0,"12":7,"13":0,"14":0,"15":1}},"color":"#FF0000","opacity":0.000012800000000000006,"depth":1},{"type":"primitive","name":"box","matrix":{"elements":{"0":1,"1":0,"2":0,"3":0,"4":0,"5":1,"6":0,"7":0,"8":0,"9":0,"10":1,"11":0,"12":8,"13":0,"14":0,"15":1}},"color":"#FF0000","opacity":0.0000025600000000000013,"depth":1},{"type":"primitive","name":"box","matrix":{"elements":{"0":1,"1":0,"2":0,"3":0,"4":0,"5":1,"6":0,"7":0,"8":0,"9":0,"10":1,"11":0,"12":9,"13":0,"14":0,"15":1}},"color":"#FF0000","opacity":5.120000000000002e-7,"depth":1},{"type":"primitive","name":"box","matrix":{"elements":{"0":1,"1":0,"2":0,"3":0,"4":0,"5":1,"6":0,"7":0,"8":0,"9":0,"10":1,"11":0,"12":10,"13":0,"14":0,"15":1}},"color":"#FF0000","opacity":1.0240000000000006e-7,"depth":1}],"num":11}
6 |
--------------------------------------------------------------------------------
/src/exporter/OBJExporter.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | import sprintf from '../sprintf';
4 |
5 | /**
6 | * @see http://paulbourke.net/dataformats/obj/
7 | */
8 | export default class OBJExporter {
9 | constructor() {
10 | this.header = "#\n# generated by eisenscript\n# https://github.com/after12am/eisenscript/\n#\n";
11 | this.buff = '';
12 | }
13 |
14 | // If function name change to 'export', google clousure complains about that.
15 | exports(meshes) {
16 | this.buff = sprintf(this.header);
17 | for (let i = 0; i < meshes.length; i++) this.exportMesh(meshes[i], i);
18 | return this.buff;
19 | }
20 |
21 | exportMesh(mesh, i) {
22 | const that = this;
23 | const m = mesh.matrix.elements;
24 |
25 | // group
26 | const group = mesh.name ? mesh.name : mesh.material.name + i;
27 | this.buff += sprintf("g %s\n", group);
28 |
29 | // material
30 | if (mesh.material.name) {
31 | this.buff += sprintf("usemtl %s\n", mesh.material.name);
32 | }
33 |
34 | // vetices
35 | mesh.geometry.vertices.forEach(function(v) {
36 | // test: v 1.0 2.0 3.0
37 | that.buff += sprintf(
38 | "v %s %s %s\n",
39 | m[0] * v.x + m[1] * v.y + m[2] * v.z + m[3] * 1,
40 | m[4] * v.x + m[5] * v.y + m[6] * v.z + m[7] * 1,
41 | m[8] * v.x + m[9] * v.y + m[10] * v.z + m[11] * 1
42 | );
43 | });
44 |
45 | // normals
46 | mesh.geometry.faces.forEach(function(face) {
47 | // test: vn 1.0 2.0 3.0
48 | that.buff += sprintf(
49 | "vn %s %s %s\n",
50 | face.normal.x,
51 | face.normal.y,
52 | face.normal.z
53 | );
54 | });
55 |
56 | // uvs
57 | mesh.geometry.faceVertexUvs.forEach(function(uvs) {
58 | // test: vt 0.1 0.2
59 | for (let i = 0; i < uvs.length; i++) {
60 | for (let j = 0; j < uvs[i].length; j++) {
61 | that.buff += sprintf(
62 | "vt %s %s\n",
63 | uvs[i][j].x,
64 | uvs[i][j].y
65 | );
66 | }
67 | }
68 | });
69 |
70 | // faces
71 | mesh.geometry.faces.forEach(function(face) {
72 | // test: f 1 2 3
73 | that.buff += sprintf(
74 | "f %s %s %s %s\n",
75 | face.a + 1,
76 | face.b + 1,
77 | face.c + 1,
78 | face.d !== undefined ? face.d + 1 : ''
79 | );
80 | });
81 | };
82 |
83 | exportObject(object, i) {
84 | // no need to implement because eisenscript.js does not support object loading
85 | console.warn("not implemented");
86 | };
87 | }
88 |
--------------------------------------------------------------------------------
/test/testset/actions/maxobjects/maxobjects.es.txt:
--------------------------------------------------------------------------------
1 | /+
2 | set maxobjects 10
3 |
4 | rule R1 {
5 | box { x 1 hue 36 rx 10 } R1
6 | }
7 |
8 | R1
9 | +/
10 | {"maxobjects":10,"minsize":0.2,"maxsize":1,"seed":"initial","objects":[{"type":"primitive","name":"box","matrix":{"elements":{"0":1,"1":0,"2":0,"3":0,"4":0,"5":1,"6":0,"7":0,"8":0,"9":0,"10":1,"11":0,"12":0,"13":0,"14":0,"15":1}},"color":"#FF0000","opacity":1,"depth":0},{"type":"primitive","name":"box","matrix":{"elements":{"0":1,"1":0,"2":0,"3":0,"4":0,"5":0.9848077297210693,"6":0.1736481785774231,"7":0,"8":0,"9":-0.1736481785774231,"10":0.9848077297210693,"11":0,"12":1,"13":0,"14":0,"15":1}},"color":"#FF9900","opacity":1,"depth":1},{"type":"primitive","name":"box","matrix":{"elements":{"0":1,"1":0,"2":0,"3":0,"4":0,"5":0.9396926164627075,"6":0.3420201539993286,"7":0,"8":0,"9":-0.3420201539993286,"10":0.9396926164627075,"11":0,"12":2,"13":0,"14":0,"15":1}},"color":"#CCFF00","opacity":1,"depth":2},{"type":"primitive","name":"box","matrix":{"elements":{"0":1,"1":0,"2":0,"3":0,"4":0,"5":0.8660253882408142,"6":0.5,"7":0,"8":0,"9":-0.5,"10":0.8660253882408142,"11":0,"12":3,"13":0,"14":0,"15":1}},"color":"#33FF00","opacity":1,"depth":3},{"type":"primitive","name":"box","matrix":{"elements":{"0":1,"1":0,"2":0,"3":0,"4":0,"5":0.7660444378852844,"6":0.6427876353263855,"7":0,"8":0,"9":-0.6427876353263855,"10":0.7660444378852844,"11":0,"12":4,"13":0,"14":0,"15":1}},"color":"#00FF66","opacity":1,"depth":4},{"type":"primitive","name":"box","matrix":{"elements":{"0":1,"1":0,"2":0,"3":0,"4":0,"5":0.6427875757217407,"6":0.7660444378852844,"7":0,"8":0,"9":-0.7660444378852844,"10":0.6427875757217407,"11":0,"12":5,"13":0,"14":0,"15":1}},"color":"#00FFFF","opacity":1,"depth":5},{"type":"primitive","name":"box","matrix":{"elements":{"0":1,"1":0,"2":0,"3":0,"4":0,"5":0.4999999701976776,"6":0.8660253882408142,"7":0,"8":0,"9":-0.8660253882408142,"10":0.4999999701976776,"11":0,"12":6,"13":0,"14":0,"15":1}},"color":"#0066FF","opacity":1,"depth":6},{"type":"primitive","name":"box","matrix":{"elements":{"0":1,"1":0,"2":0,"3":0,"4":0,"5":0.3420201241970062,"6":0.9396926164627075,"7":0,"8":0,"9":-0.9396926164627075,"10":0.3420201241970062,"11":0,"12":7,"13":0,"14":0,"15":1}},"color":"#3300FF","opacity":1,"depth":7},{"type":"primitive","name":"box","matrix":{"elements":{"0":1,"1":0,"2":0,"3":0,"4":0,"5":0.1736481636762619,"6":0.9848077297210693,"7":0,"8":0,"9":-0.9848077297210693,"10":0.1736481636762619,"11":0,"12":8,"13":0,"14":0,"15":1}},"color":"#CC00FF","opacity":1,"depth":8},{"type":"primitive","name":"box","matrix":{"elements":{"0":1,"1":0,"2":0,"3":0,"4":0,"5":-9.733654771082456e-9,"6":1,"7":0,"8":0,"9":-1,"10":-9.733654771082456e-9,"11":0,"12":9,"13":0,"14":0,"15":1}},"color":"#FF0099","opacity":1,"depth":9}],"num":10}
11 |
--------------------------------------------------------------------------------
/examples/import.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Import Test
6 |
12 |
13 |
14 |
15 |
16 |
17 |
103 |
104 |
105 |
--------------------------------------------------------------------------------
/test/testset/colorspace/sat.define.varname.es.txt:
--------------------------------------------------------------------------------
1 | /+
2 | #define aa 0.9
3 |
4 | 12 * { x 1 rz 30 sat aa } box
5 | +/
6 | {"minsize":0.2,"maxsize":1,"seed":"initial","objects":[{"type":"primitive","name":"box","matrix":{"elements":{"0":0.8660253882408142,"1":0.5,"2":0,"3":0,"4":-0.5,"5":0.8660253882408142,"6":0,"7":0,"8":0,"9":0,"10":1,"11":0,"12":1,"13":0,"14":0,"15":1}},"color":"#FF1919","opacity":1,"depth":1},{"type":"primitive","name":"box","matrix":{"elements":{"0":0.5,"1":0.8660253882408142,"2":0,"3":0,"4":-0.8660253882408142,"5":0.5,"6":0,"7":0,"8":0,"9":0,"10":1,"11":0,"12":1.866025447845459,"13":0.5,"14":0,"15":1}},"color":"#FF3030","opacity":1,"depth":1},{"type":"primitive","name":"box","matrix":{"elements":{"0":7.771812526868871e-9,"1":1,"2":0,"3":0,"4":-1,"5":7.771812526868871e-9,"6":0,"7":0,"8":0,"9":0,"10":1,"11":0,"12":2.366025447845459,"13":1.366025447845459,"14":0,"15":1}},"color":"#FF4545","opacity":1,"depth":1},{"type":"primitive","name":"box","matrix":{"elements":{"0":-0.5,"1":0.8660253882408142,"2":0,"3":0,"4":-0.8660253882408142,"5":-0.5,"6":0,"7":0,"8":0,"9":0,"10":1,"11":0,"12":2.366025447845459,"13":2.366025447845459,"14":0,"15":1}},"color":"#FF5858","opacity":1,"depth":1},{"type":"primitive","name":"box","matrix":{"elements":{"0":-0.8660253882408142,"1":0.5,"2":0,"3":0,"4":-0.5,"5":-0.8660253882408142,"6":0,"7":0,"8":0,"9":0,"10":1,"11":0,"12":1.866025447845459,"13":3.232050895690918,"14":0,"15":1}},"color":"#FF6868","opacity":1,"depth":1},{"type":"primitive","name":"box","matrix":{"elements":{"0":-1,"1":7.771812526868871e-9,"2":0,"3":0,"4":-7.771812526868871e-9,"5":-1,"6":0,"7":0,"8":0,"9":0,"10":1,"11":0,"12":1,"13":3.732050895690918,"14":0,"15":1}},"color":"#FF7777","opacity":1,"depth":1},{"type":"primitive","name":"box","matrix":{"elements":{"0":-0.8660253882408142,"1":-0.5,"2":0,"3":0,"4":0.5,"5":-0.8660253882408142,"6":0,"7":0,"8":0,"9":0,"10":1,"11":0,"12":0,"13":3.732050895690918,"14":0,"15":1}},"color":"#FF8585","opacity":1,"depth":1},{"type":"primitive","name":"box","matrix":{"elements":{"0":-0.5,"1":-0.8660253882408142,"2":0,"3":0,"4":0.8660253882408142,"5":-0.5,"6":0,"7":0,"8":0,"9":0,"10":1,"11":0,"12":-0.8660253882408142,"13":3.232050895690918,"14":0,"15":1}},"color":"#FF9191","opacity":1,"depth":1},{"type":"primitive","name":"box","matrix":{"elements":{"0":-7.771812526868871e-9,"1":-1,"2":0,"3":0,"4":1,"5":-7.771812526868871e-9,"6":0,"7":0,"8":0,"9":0,"10":1,"11":0,"12":-1.366025447845459,"13":2.366025447845459,"14":0,"15":1}},"color":"#FF9C9C","opacity":1,"depth":1},{"type":"primitive","name":"box","matrix":{"elements":{"0":0.5,"1":-0.8660253882408142,"2":0,"3":0,"4":0.8660253882408142,"5":0.5,"6":0,"7":0,"8":0,"9":0,"10":1,"11":0,"12":-1.366025447845459,"13":1.366025447845459,"14":0,"15":1}},"color":"#FFA6A6","opacity":1,"depth":1},{"type":"primitive","name":"box","matrix":{"elements":{"0":0.8660253882408142,"1":-0.5,"2":0,"3":0,"4":0.5,"5":0.8660253882408142,"6":0,"7":0,"8":0,"9":0,"10":1,"11":0,"12":-0.866025447845459,"13":0.5000000596046448,"14":0,"15":1}},"color":"#FFAFAF","opacity":1,"depth":1},{"type":"primitive","name":"box","matrix":{"elements":{"0":1,"1":-7.771812526868871e-9,"2":0,"3":0,"4":7.771812526868871e-9,"5":1,"6":0,"7":0,"8":0,"9":0,"10":1,"11":0,"12":-5.960464477539063e-8,"13":5.960464477539063e-8,"14":0,"15":1}},"color":"#FFB7B7","opacity":1,"depth":1}],"num":12}
7 |
--------------------------------------------------------------------------------
/test/testset/modifiers/maxdepth/maxdepth.nested_transform.es.txt:
--------------------------------------------------------------------------------
1 | /+
2 | // bug around three.js?
3 | corner
4 | rule corner md 4 {
5 | { s 1 2 1.2 }ARC
6 | {ry 36}corner
7 | }
8 | rule ARC md 3 {
9 | { z 0.85 rx 4.5 s 0.95 } ARC
10 | box
11 | }
12 | +/
13 | {"minsize":0.2,"maxsize":1,"seed":"initial","objects":[{"type":"primitive","name":"box","matrix":{"elements":{"0":0.9024999737739563,"1":0,"2":0,"3":0,"4":0,"5":1.7827774286270142,"6":0.16941852867603302,"7":0,"8":0,"9":-0.2823641896247864,"10":1.0696665048599243,"11":0,"12":0,"13":-0.12671144306659698,"14":1.9860129356384277,"15":1}},"color":"#FF0000","opacity":1,"depth":3},{"type":"primitive","name":"box","matrix":{"elements":{"0":0.949999988079071,"1":0,"2":0,"3":0,"4":0,"5":1.8941428661346436,"6":0.08944337069988251,"7":0,"8":0,"9":-0.1490722894668579,"10":1.1364858150482178,"11":0,"12":0,"13":0,"14":1.0199999809265137,"15":1}},"color":"#FF0000","opacity":1,"depth":2},{"type":"primitive","name":"box","matrix":{"elements":{"0":1,"1":0,"2":0,"3":0,"4":0,"5":2,"6":0,"7":0,"8":0,"9":0,"10":1.2000000476837158,"11":0,"12":0,"13":0,"14":0,"15":1}},"color":"#FF0000","opacity":1,"depth":1},{"type":"primitive","name":"box","matrix":{"elements":{"0":0.730137825012207,"1":0,"2":-0.5304762125015259,"3":0,"4":0.09958171099424362,"5":1.7827774286270142,"6":0.13706247508525848,"7":0,"8":0.6287342309951782,"9":-0.2823641896247864,"10":0.8653783798217773,"11":0,"12":1.167349100112915,"13":-0.12671144306659698,"14":1.6067181825637817,"15":1}},"color":"#FF0000","opacity":1,"depth":4},{"type":"primitive","name":"box","matrix":{"elements":{"0":0.7685661315917969,"1":0,"2":-0.5583959817886353,"3":0,"4":0.052573490887880325,"5":1.8941428661346436,"6":0.07236120849847794,"7":0,"8":0.6680095791816711,"9":-0.1490722894668579,"10":0.9194363355636597,"11":0,"12":0.5995409488677979,"13":0,"14":0.8251973390579224,"15":1}},"color":"#FF0000","opacity":1,"depth":3},{"type":"primitive","name":"box","matrix":{"elements":{"0":0.80901700258255,"1":0,"2":-0.5877852439880371,"3":0,"4":0,"5":2,"6":0,"7":0,"8":0.7053422927856445,"9":0,"10":0.970820426940918,"11":0,"12":0,"13":0,"14":0,"15":1}},"color":"#FF0000","opacity":1,"depth":2},{"type":"primitive","name":"box","matrix":{"elements":{"0":0.27888786792755127,"1":0,"2":-0.8583285212516785,"3":0,"4":0.16112661361694336,"5":1.7827774286270142,"6":0.05235320329666138,"7":0,"8":1.0173133611679077,"9":-0.2823641896247864,"10":0.3305450975894928,"11":0,"12":1.888810634613037,"13":-0.12671144306659698,"14":0.6137117147445679,"15":1}},"color":"#FF0000","opacity":1,"depth":5},{"type":"primitive","name":"box","matrix":{"elements":{"0":0.29356616735458374,"1":0,"2":-0.9035037159919739,"3":0,"4":0.08506570011377335,"5":1.8941428661346436,"6":0.027639523148536682,"7":0,"8":1.080862283706665,"9":-0.1490722894668579,"10":0.3511933982372284,"11":0,"12":0.9700776934623718,"13":0,"14":0.3151973485946655,"15":1}},"color":"#FF0000","opacity":1,"depth":4},{"type":"primitive","name":"box","matrix":{"elements":{"0":0.30901700258255005,"1":0,"2":-0.9510565400123596,"3":0,"4":0,"5":2,"6":0,"7":0,"8":1.1412678956985474,"9":0,"10":0.37082040309906006,"11":0,"12":0,"13":0,"14":0,"15":1}},"color":"#FF0000","opacity":1,"depth":3},{"type":"primitive","name":"box","matrix":{"elements":{"0":-0.27888786792755127,"1":0,"2":-0.8583285212516785,"3":0,"4":0.16112661361694336,"5":1.7827774286270142,"6":-0.05235320329666138,"7":0,"8":1.0173133611679077,"9":-0.2823641896247864,"10":-0.3305450975894928,"11":0,"12":1.888810634613037,"13":-0.12671144306659698,"14":-0.6137117147445679,"15":1}},"color":"#FF0000","opacity":1,"depth":6},{"type":"primitive","name":"box","matrix":{"elements":{"0":-0.29356616735458374,"1":0,"2":-0.9035037159919739,"3":0,"4":0.08506570011377335,"5":1.8941428661346436,"6":-0.027639523148536682,"7":0,"8":1.080862283706665,"9":-0.1490722894668579,"10":-0.3511933982372284,"11":0,"12":0.9700776934623718,"13":0,"14":-0.3151973485946655,"15":1}},"color":"#FF0000","opacity":1,"depth":5},{"type":"primitive","name":"box","matrix":{"elements":{"0":-0.30901700258255005,"1":0,"2":-0.9510565400123596,"3":0,"4":0,"5":2,"6":0,"7":0,"8":1.1412678956985474,"9":0,"10":-0.37082040309906006,"11":0,"12":0,"13":0,"14":0,"15":1}},"color":"#FF0000","opacity":1,"depth":4}],"num":12}
14 |
--------------------------------------------------------------------------------
/src/csscolor.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | aliceblue:'#F0F8FF',
3 | antiquewhite:'#FAEBD7',
4 | aqua:'#00FFFF',
5 | aquamarine:'#7FFFD4',
6 | azure:'#F0FFFF',
7 | beige:'#F5F5DC',
8 | bisque:'#FFE4C4',
9 | black:'#000000',
10 | blanchedalmond:'#FFEBCD',
11 | blue:'#0000FF',
12 | blueviolet:'#8A2BE2',
13 | brown:'#A52A2A',
14 | burlywood:'#DEB887',
15 | cadetblue:'#5F9EA0',
16 | chartreuse:'#7FFF00',
17 | chocolate:'#D2691E',
18 | coral:'#FF7F50',
19 | cornflowerblue:'#6495ED',
20 | cornsilk:'#FFF8DC',
21 | crimson:'#DC143C',
22 | cyan:'#00FFFF',
23 | darkblue:'#00008B',
24 | darkcyan:'#008B8B',
25 | darkgoldenrod:'#B8860B',
26 | darkgray:'#A9A9A9',
27 | darkgrey:'#A9A9A9',
28 | darkgreen:'#006400',
29 | darkkhaki:'#BDB76B',
30 | darkmagenta:'#8B008B',
31 | darkolivegreen:'#556B2F',
32 | darkorange:'#FF8C00',
33 | darkorchid:'#9932CC',
34 | darkred:'#8B0000',
35 | darksalmon:'#E9967A',
36 | darkseagreen:'#8FBC8F',
37 | darkslateblue:'#483D8B',
38 | darkslategray:'#2F4F4F',
39 | darkslategrey:'#2F4F4F',
40 | darkturquoise:'#00CED1',
41 | darkviolet:'#9400D3',
42 | deeppink:'#FF1493',
43 | deepskyblue:'#00BFFF',
44 | dimgray:'#696969',
45 | dimgrey:'#696969',
46 | dodgerblue:'#1E90FF',
47 | firebrick:'#B22222',
48 | floralwhite:'#FFFAF0',
49 | forestgreen:'#228B22',
50 | fuchsia:'#FF00FF',
51 | gainsboro:'#DCDCDC',
52 | ghostwhite:'#F8F8FF',
53 | gold:'#FFD700',
54 | goldenrod:'#DAA520',
55 | gray:'#808080',
56 | grey:'#808080',
57 | green:'#008000',
58 | greenyellow:'#ADFF2F',
59 | honeydew:'#F0FFF0',
60 | hotpink:'#FF69B4',
61 | indianred:'#CD5C5C',
62 | indigo:'#4B0082',
63 | ivory:'#FFFFF0',
64 | khaki:'#F0E68C',
65 | lavender:'#E6E6FA',
66 | lavenderblush:'#FFF0F5',
67 | lawngreen:'#7CFC00',
68 | lemonchiffon:'#FFFACD',
69 | lightblue:'#ADD8E6',
70 | lightcoral:'#F08080',
71 | lightcyan:'#E0FFFF',
72 | lightgoldenrodyellow:'#FAFAD2',
73 | lightgray:'#D3D3D3',
74 | lightgrey:'#D3D3D3',
75 | lightgreen:'#90EE90',
76 | lightpink:'#FFB6C1',
77 | lightsalmon:'#FFA07A',
78 | lightseagreen:'#20B2AA',
79 | lightskyblue:'#87CEFA',
80 | lightslategray:'#778899',
81 | lightslategrey:'#778899',
82 | lightsteelblue:'#B0C4DE',
83 | lightyellow:'#FFFFE0',
84 | lime:'#00FF00',
85 | limegreen:'#32CD32',
86 | linen:'#FAF0E6',
87 | magenta:'#FF00FF',
88 | maroon:'#800000',
89 | mediumaquamarine:'#66CDAA',
90 | mediumblue:'#0000CD',
91 | mediumorchid:'#BA55D3',
92 | mediumpurple:'#9370D8',
93 | mediumseagreen:'#3CB371',
94 | mediumslateblue:'#7B68EE',
95 | mediumspringgreen:'#00FA9A',
96 | mediumturquoise:'#48D1CC',
97 | mediumvioletred:'#C71585',
98 | midnightblue:'#191970',
99 | mintcream:'#F5FFFA',
100 | mistyrose:'#FFE4E1',
101 | moccasin:'#FFE4B5',
102 | navajowhite:'#FFDEAD',
103 | navy:'#000080',
104 | oldlace:'#FDF5E6',
105 | olive:'#808000',
106 | olivedrab:'#6B8E23',
107 | orange:'#FFA500',
108 | orangered:'#FF4500',
109 | orchid:'#DA70D6',
110 | palegoldenrod:'#EEE8AA',
111 | palegreen:'#98FB98',
112 | paleturquoise:'#AFEEEE',
113 | palevioletred:'#D87093',
114 | papayawhip:'#FFEFD5',
115 | peachpuff:'#FFDAB9',
116 | peru:'#CD853F',
117 | pink:'#FFC0CB',
118 | plum:'#DDA0DD',
119 | powderblue:'#B0E0E6',
120 | purple:'#800080',
121 | rebeccapurple:'#663399',
122 | red:'#FF0000',
123 | rosybrown:'#BC8F8F',
124 | royalblue:'#4169E1',
125 | saddlebrown:'#8B4513',
126 | salmon:'#FA8072',
127 | sandybrown:'#F4A460',
128 | seagreen:'#2E8B57',
129 | seashell:'#FFF5EE',
130 | sienna:'#A0522D',
131 | silver:'#C0C0C0',
132 | skyblue:'#87CEEB',
133 | slateblue:'#6A5ACD',
134 | slategray:'#708090',
135 | slategrey:'#708090',
136 | snow:'#FFFAFA',
137 | springgreen:'#00FF7F',
138 | steelblue:'#4682B4',
139 | tan:'#D2B48C',
140 | teal:'#008080',
141 | thistle:'#D8BFD8',
142 | tomato:'#FF6347',
143 | turquoise:'#40E0D0',
144 | violet:'#EE82EE',
145 | wheat:'#F5DEB3',
146 | white:'#FFFFFF',
147 | whitesmoke:'#F5F5F5',
148 | yellow:'#FFFF00',
149 | yellowgreen:'#9ACD32'
150 | };
151 |
--------------------------------------------------------------------------------
/src/utils.js:
--------------------------------------------------------------------------------
1 | const HCHARS = "0123456789ABCDEF"
2 |
3 | module.exports = {
4 | extend: function(destination, source) {
5 | for(let k in source) destination[k] = source[k];
6 | return destination;
7 | },
8 |
9 | /**
10 | * Converts 0-1 to 0-255
11 | * @method real2dec
12 | * @param n {float} the number to convert
13 | * @return {int} a number 0-255
14 | */
15 | real2dec: function(n) {
16 | return Math.min(255, Math.round(n*256));
17 | },
18 |
19 | /**
20 | * Converts HSV (h[0-360], s[0-1]), v[0-1] to RGB [255,255,255]
21 | * @method hsv2rgb
22 | * @param h {int|[int, float, float]} the hue, or an
23 | * array containing all three parameters
24 | * @param s {float} the saturation
25 | * @param v {float} the value/brightness
26 | * @return {[int, int, int]} the red, green, blue values in
27 | * decimal.
28 | */
29 | hsv2rgb: function(h, s, v) {
30 |
31 | var r, g, b, i, f, p, q, t;
32 | i = Math.floor((h/60)%6);
33 | f = (h/60)-i;
34 | p = v*(1-s);
35 | q = v*(1-f*s);
36 | t = v*(1-(1-f)*s);
37 | switch(i) {
38 | case 0: r=v; g=t; b=p; break;
39 | case 1: r=q; g=v; b=p; break;
40 | case 2: r=p; g=v; b=t; break;
41 | case 3: r=p; g=q; b=v; break;
42 | case 4: r=t; g=p; b=v; break;
43 | case 5: r=v; g=p; b=q; break;
44 | }
45 |
46 | var fn=this.real2dec;
47 |
48 | return [fn(r), fn(g), fn(b)];
49 | },
50 |
51 | /**
52 | * Converts to RGB [255,255,255] to HSV (h[0-360], s[0-1]), v[0-1]
53 | * @method rgb2hsv
54 | * @param r {int|[int, int, int]} the red value, or an
55 | * array containing all three parameters
56 | * @param g {int} the green value
57 | * @param b {int} the blue value
58 | * @return {[int, float, float]} the value converted to hsv
59 | */
60 | rgb2hsv: function(r, g, b) {
61 |
62 | r=r/255;
63 | g=g/255;
64 | b=b/255;
65 |
66 | var min,max,delta,h,s,v;
67 | min = Math.min(Math.min(r,g),b);
68 | max = Math.max(Math.max(r,g),b);
69 | delta = max-min;
70 |
71 | switch (max) {
72 | case min: h=0; break;
73 | case r: h=60*(g-b)/delta;
74 | if (g FFFFFF
92 | * @method rgb2hex
93 | * @param r {int|[int, int, int]} the red value, or an
94 | * array containing all three parameters
95 | * @param g {int} the green value
96 | * @param b {int} the blue value
97 | * @return {string} the hex string
98 | */
99 | rgb2hex: function(r, g, b) {
100 | var f=this.dec2hex;
101 | return f(r) + f(g) + f(b);
102 | },
103 |
104 | /**
105 | * Converts an int 0...255 to hex pair 00...FF
106 | * @method dec2hex
107 | * @param n {int} the number to convert
108 | * @return {string} the hex equivalent
109 | */
110 | dec2hex: function(n) {
111 | n = parseInt(n, 10);
112 | n = (typeof n === 'number') ? n : 0;
113 | n = (n > 255 || n < 0) ? 0 : n;
114 |
115 | return HCHARS.charAt((n - n % 16) / 16) + HCHARS.charAt(n % 16);
116 | },
117 |
118 | /**
119 | * Converts a hex pair 00...FF to an int 0...255
120 | * @method hex2dec
121 | * @param str {string} the hex pair to convert
122 | * @return {int} the decimal
123 | */
124 | hex2dec: function(str) {
125 | var f = function(c) {
126 | return HCHARS.indexOf(c.toUpperCase());
127 | };
128 |
129 | var s=str.split('');
130 |
131 | return ((f(s[0]) * 16) + f(s[1]));
132 | },
133 |
134 | /**
135 | * Converts a hex string to rgb
136 | * @method hex2rgb
137 | * @param str {string} the hex string
138 | * @return {[int, int, int]} an array containing the rgb values
139 | */
140 | hex2rgb: function(s) {
141 | var f = this.hex2dec;
142 | return [f(s.substr(0, 2)), f(s.substr(2, 2)), f(s.substr(4, 2))];
143 | }
144 | };
145 |
--------------------------------------------------------------------------------
/src/Matrix4.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @author mrdoob / http://mrdoob.com/
3 | * @author supereggbert / http://www.paulbrunt.co.uk/
4 | * @author philogb / http://blog.thejit.org/
5 | * @author jordi_ros / http://plattsoft.com
6 | * @author D1plo1d / http://github.com/D1plo1d
7 | * @author alteredq / http://alteredqualia.com/
8 | * @author mikael emtinger / http://gomo.se/
9 | * @author timknip / http://www.floorplanner.com/
10 | * @author bhouston / http://exocortex.com
11 | */
12 |
13 | module.exports = class Matrix4 {
14 |
15 | constructor( n11, n12, n13, n14, n21, n22, n23, n24, n31, n32, n33, n34, n41, n42, n43, n44 ) {
16 | const te = this.elements = new Float32Array( 16 );
17 |
18 | // TODO: if n11 is undefined, then just set to identity, otherwise copy all other values into matrix
19 | // we should not support semi specification of Matrix4, it is just weird.
20 |
21 | te[0] = ( n11 !== undefined ) ? n11 : 1; te[4] = n12 || 0; te[8] = n13 || 0; te[12] = n14 || 0;
22 | te[1] = n21 || 0; te[5] = ( n22 !== undefined ) ? n22 : 1; te[9] = n23 || 0; te[13] = n24 || 0;
23 | te[2] = n31 || 0; te[6] = n32 || 0; te[10] = ( n33 !== undefined ) ? n33 : 1; te[14] = n34 || 0;
24 | te[3] = n41 || 0; te[7] = n42 || 0; te[11] = n43 || 0; te[15] = ( n44 !== undefined ) ? n44 : 1;
25 | }
26 |
27 | set( n11, n12, n13, n14, n21, n22, n23, n24, n31, n32, n33, n34, n41, n42, n43, n44 ) {
28 |
29 | const te = this.elements;
30 |
31 | te[0] = n11; te[4] = n12; te[8] = n13; te[12] = n14;
32 | te[1] = n21; te[5] = n22; te[9] = n23; te[13] = n24;
33 | te[2] = n31; te[6] = n32; te[10] = n33; te[14] = n34;
34 | te[3] = n41; te[7] = n42; te[11] = n43; te[15] = n44;
35 |
36 | return this;
37 |
38 | }
39 |
40 | identity() {
41 |
42 | this.set(
43 |
44 | 1, 0, 0, 0,
45 | 0, 1, 0, 0,
46 | 0, 0, 1, 0,
47 | 0, 0, 0, 1
48 |
49 | );
50 |
51 | return this;
52 |
53 | }
54 |
55 | multiplyMatrices( a, b ) {
56 | var ae = a.elements;
57 | var be = b.elements;
58 | var te = this.elements;
59 |
60 | var a11 = ae[0], a12 = ae[4], a13 = ae[8], a14 = ae[12];
61 | var a21 = ae[1], a22 = ae[5], a23 = ae[9], a24 = ae[13];
62 | var a31 = ae[2], a32 = ae[6], a33 = ae[10], a34 = ae[14];
63 | var a41 = ae[3], a42 = ae[7], a43 = ae[11], a44 = ae[15];
64 |
65 | var b11 = be[0], b12 = be[4], b13 = be[8], b14 = be[12];
66 | var b21 = be[1], b22 = be[5], b23 = be[9], b24 = be[13];
67 | var b31 = be[2], b32 = be[6], b33 = be[10], b34 = be[14];
68 | var b41 = be[3], b42 = be[7], b43 = be[11], b44 = be[15];
69 |
70 | te[0] = a11 * b11 + a12 * b21 + a13 * b31 + a14 * b41;
71 | te[4] = a11 * b12 + a12 * b22 + a13 * b32 + a14 * b42;
72 | te[8] = a11 * b13 + a12 * b23 + a13 * b33 + a14 * b43;
73 | te[12] = a11 * b14 + a12 * b24 + a13 * b34 + a14 * b44;
74 |
75 | te[1] = a21 * b11 + a22 * b21 + a23 * b31 + a24 * b41;
76 | te[5] = a21 * b12 + a22 * b22 + a23 * b32 + a24 * b42;
77 | te[9] = a21 * b13 + a22 * b23 + a23 * b33 + a24 * b43;
78 | te[13] = a21 * b14 + a22 * b24 + a23 * b34 + a24 * b44;
79 |
80 | te[2] = a31 * b11 + a32 * b21 + a33 * b31 + a34 * b41;
81 | te[6] = a31 * b12 + a32 * b22 + a33 * b32 + a34 * b42;
82 | te[10] = a31 * b13 + a32 * b23 + a33 * b33 + a34 * b43;
83 | te[14] = a31 * b14 + a32 * b24 + a33 * b34 + a34 * b44;
84 |
85 | te[3] = a41 * b11 + a42 * b21 + a43 * b31 + a44 * b41;
86 | te[7] = a41 * b12 + a42 * b22 + a43 * b32 + a44 * b42;
87 | te[11] = a41 * b13 + a42 * b23 + a43 * b33 + a44 * b43;
88 | te[15] = a41 * b14 + a42 * b24 + a43 * b34 + a44 * b44;
89 |
90 | return this;
91 |
92 | }
93 |
94 | translate( v ) {
95 |
96 | const te = this.elements;
97 | const x = v.x, y = v.y, z = v.z;
98 |
99 | te[12] = te[0] * x + te[4] * y + te[8] * z + te[12];
100 | te[13] = te[1] * x + te[5] * y + te[9] * z + te[13];
101 | te[14] = te[2] * x + te[6] * y + te[10] * z + te[14];
102 | te[15] = te[3] * x + te[7] * y + te[11] * z + te[15];
103 |
104 | return this;
105 |
106 | }
107 |
108 | rotateX( angle ) {
109 |
110 | const te = this.elements;
111 | const m12 = te[4];
112 | const m22 = te[5];
113 | const m32 = te[6];
114 | const m42 = te[7];
115 | const m13 = te[8];
116 | const m23 = te[9];
117 | const m33 = te[10];
118 | const m43 = te[11];
119 | const c = Math.cos( angle );
120 | const s = Math.sin( angle );
121 |
122 | te[4] = c * m12 + s * m13;
123 | te[5] = c * m22 + s * m23;
124 | te[6] = c * m32 + s * m33;
125 | te[7] = c * m42 + s * m43;
126 |
127 | te[8] = c * m13 - s * m12;
128 | te[9] = c * m23 - s * m22;
129 | te[10] = c * m33 - s * m32;
130 | te[11] = c * m43 - s * m42;
131 |
132 | return this;
133 |
134 | }
135 |
136 | rotateY( angle ) {
137 |
138 | const te = this.elements;
139 | const m11 = te[0];
140 | const m21 = te[1];
141 | const m31 = te[2];
142 | const m41 = te[3];
143 | const m13 = te[8];
144 | const m23 = te[9];
145 | const m33 = te[10];
146 | const m43 = te[11];
147 | const c = Math.cos( angle );
148 | const s = Math.sin( angle );
149 |
150 | te[0] = c * m11 - s * m13;
151 | te[1] = c * m21 - s * m23;
152 | te[2] = c * m31 - s * m33;
153 | te[3] = c * m41 - s * m43;
154 |
155 | te[8] = c * m13 + s * m11;
156 | te[9] = c * m23 + s * m21;
157 | te[10] = c * m33 + s * m31;
158 | te[11] = c * m43 + s * m41;
159 |
160 | return this;
161 |
162 | }
163 |
164 | rotateZ( angle ) {
165 |
166 | const te = this.elements;
167 | const m11 = te[0];
168 | const m21 = te[1];
169 | const m31 = te[2];
170 | const m41 = te[3];
171 | const m12 = te[4];
172 | const m22 = te[5];
173 | const m32 = te[6];
174 | const m42 = te[7];
175 | const c = Math.cos( angle );
176 | const s = Math.sin( angle );
177 |
178 | te[0] = c * m11 + s * m12;
179 | te[1] = c * m21 + s * m22;
180 | te[2] = c * m31 + s * m32;
181 | te[3] = c * m41 + s * m42;
182 |
183 | te[4] = c * m12 - s * m11;
184 | te[5] = c * m22 - s * m21;
185 | te[6] = c * m32 - s * m31;
186 | te[7] = c * m42 - s * m41;
187 |
188 | return this;
189 |
190 | }
191 |
192 | scale( v ) {
193 |
194 | const te = this.elements;
195 | const x = v.x, y = v.y, z = v.z;
196 |
197 | te[0] *= x; te[4] *= y; te[8] *= z;
198 | te[1] *= x; te[5] *= y; te[9] *= z;
199 | te[2] *= x; te[6] *= y; te[10] *= z;
200 | te[3] *= x; te[7] *= y; te[11] *= z;
201 |
202 | return this;
203 |
204 | }
205 |
206 | clone() {
207 |
208 | const te = this.elements;
209 |
210 | return new Matrix4(
211 |
212 | te[0], te[4], te[8], te[12],
213 | te[1], te[5], te[9], te[13],
214 | te[2], te[6], te[10], te[14],
215 | te[3], te[7], te[11], te[15]
216 |
217 | );
218 | }
219 | }
220 |
--------------------------------------------------------------------------------
/test/interpreter_test.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | const fs = require('fs');
4 | const path = require('path');
5 | const shouldBeGoodInterpreter = require('./behavior/should_be_good_interpreter');
6 | const { assert } = require('chai');
7 | const parser = require('../src/parser');
8 | const Interpreter = require('../src/Interpreter');
9 | const utils = require('../src/utils');
10 |
11 | function readdir(dir) {
12 | return fs.readdirSync(dir).map(filename => path.join(dir, filename));
13 | }
14 |
15 | /**
16 | * TODO: more matrix tests
17 | * TODO: more color translation tests. blend
18 | */
19 | describe('Interpreter', function() {
20 | describe.skip('default', function() {
21 | const tests = [
22 |
23 | ];
24 | tests.forEach(shouldBeGoodInterpreter);
25 | });
26 |
27 | describe('comments', function() {
28 | const tests = readdir('test/testset/comments');
29 | tests.forEach(shouldBeGoodInterpreter);
30 | });
31 |
32 | describe('primitives', function() {
33 | const tests = readdir('test/testset/primitives');
34 | tests.forEach(shouldBeGoodInterpreter);
35 | });
36 |
37 | describe('modifiers', function() {
38 | describe('md / maxdepth [integer]', function() {
39 | const tests = readdir('test/testset/modifiers/maxdepth');
40 | tests.forEach(shouldBeGoodInterpreter);
41 | });
42 |
43 | describe('weight', function() {
44 | const tests = readdir('test/testset/modifiers/weight');
45 | tests.forEach(shouldBeGoodInterpreter);
46 | });
47 | });
48 |
49 | describe('actions', function() {
50 | describe('set background [color]', function() {
51 | const tests = readdir('test/testset/actions/background');
52 | tests.forEach(shouldBeGoodInterpreter);
53 |
54 | // disable to use random as background color
55 | const source = 'set background random';
56 | const ast = parser.parse(source);
57 | const interpreter = new Interpreter();
58 | assert.throws(() => interpreter.generate(ast));
59 | });
60 |
61 | describe('set seed [integer] / initial', function() {
62 | const tests = readdir('test/testset/actions/seed');
63 | tests.forEach(shouldBeGoodInterpreter);
64 |
65 | // The color is different every time if initial is set.
66 | const source = 'set seed initial\n10 * { x 1 color random } box';
67 | const ast = parser.parse(source);
68 | const interpreter = new Interpreter();
69 | const object = interpreter.generate(ast);
70 | assert.isFalse(JSON.stringify(interpreter.generate(ast)) === JSON.stringify(interpreter.generate(ast)));
71 | });
72 |
73 | describe('set maxobjects [integer]', function() {
74 | const tests = readdir('test/testset/actions/maxobjects');
75 | tests.forEach(shouldBeGoodInterpreter);
76 | });
77 |
78 | describe('set maxdepth [integer]', function() {
79 | const tests = readdir('test/testset/actions/maxdepth');
80 | tests.forEach(shouldBeGoodInterpreter);
81 | });
82 |
83 | // TODO: not implemented yet
84 | describe('set minsize [float]', function() {
85 | // it('set minsize 10.1', function() {
86 | // const source = 'set minsize 10.1';
87 | // });
88 | });
89 |
90 | // TODO: not implemented yet
91 | describe('set maxsize [float]', function() {
92 | // it('set maxsize 10.1', function() {
93 | // const source = 'set maxsize 10.1';
94 | // });
95 | });
96 | });
97 |
98 | // NOTE: If you want to express same color transformation in three.js, use basic material type.
99 | describe('colorspace', function() {
100 | const tests = readdir('test/testset/colorspace');
101 | tests.forEach(shouldBeGoodInterpreter);
102 | });
103 |
104 | describe('geometrical transformations', function() {
105 | const tests = readdir('test/testset/geometric');
106 | tests.forEach(shouldBeGoodInterpreter);
107 | });
108 |
109 | describe('preprocessor commands', function() {
110 | describe('define', function() {
111 | it('#define varname 10', function() {
112 | const source = '#define varname 10\n{ x varname } box';
113 | const ast = parser.parse(source);
114 | const interpreter = new Interpreter();
115 | const object = interpreter.generate(ast);
116 | const expected = [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 10, 0, 0, 1];
117 | assert.deepEqual(expected, Array.from(object.objects[0].matrix.elements))
118 | });
119 | });
120 | });
121 |
122 | // NOTE: not implement yet
123 | describe('colorpool', function() {
124 | it('{ set colorpool randomhue', function() {
125 | const source = 'set colorpool randomhue\n100 * { color random } box';
126 | const ast = parser.parse(source);
127 | const interpreter = new Interpreter();
128 | const object = interpreter.generate(ast);
129 | for (let i = 0; i < 100; i++) {
130 | const color = object.objects[i].color;
131 | const hex = color.substring(1, 7);
132 | const rgb = utils.hex2rgb(hex);
133 | const hsv = utils.rgb2hsv(rgb[0], rgb[1], rgb[2]);
134 | assert.ok(hsv[0] >= 0 && hsv[0] <= 360);
135 | assert.equal(hsv[1], 1);
136 | assert.equal(hsv[2], 1);
137 | }
138 | });
139 |
140 | it('{ set colorpool randomrgb', function() {
141 | const source = 'set colorpool randomrgb\n100 * { color random } box';
142 | const ast = parser.parse(source);
143 | const interpreter = new Interpreter();
144 | const object = interpreter.generate(ast);
145 | for (let i = 0; i < 100; i++) {
146 | const color = object.objects[i].color;
147 | const hex = color.substring(1, 7);
148 | const rgb = utils.hex2rgb(hex);
149 | assert.ok(rgb[0] >= 0 && rgb[0] <= 360);
150 | assert.ok(rgb[1] >= 0 && rgb[1] <= 360);
151 | assert.ok(rgb[2] >= 0 && rgb[2] <= 360);
152 | }
153 | });
154 |
155 | it('{ set colorpool greyscale', function() {
156 | const source = 'set colorpool greyscale\n100 * { color random } box';
157 | const ast = parser.parse(source);
158 | const interpreter = new Interpreter();
159 | const object = interpreter.generate(ast);
160 | for (let i = 0; i < 100; i++) {
161 | const color = object.objects[i].color;
162 | const r = color.substring(1, 3);
163 | assert.equal(color, `#${r}${r}${r}`);
164 | }
165 | });
166 | //
167 | // it('{ set colorpool image:filename.png', function() {
168 | // const source = 'set colorpool image:filename.png';
169 | // });
170 | //
171 | it('{ set colorpool list:orange,white,grey', function() {
172 | const source = 'set colorpool list:orange,white,grey\n100 * { color random } box';
173 | const ast = parser.parse(source);
174 | const interpreter = new Interpreter();
175 | const object = interpreter.generate(ast);
176 | for (let i = 0; i < 100; i++) {
177 | assert.ok(['#808080', '#FFFFFF', '#FFA500'].includes(object.objects[i].color));
178 | }
179 | });
180 | });
181 | });
182 |
183 |
184 |
185 |
186 |
--------------------------------------------------------------------------------
/src/mt.js:
--------------------------------------------------------------------------------
1 | // mt.js 0.2.4 (2005-12-23)
2 |
3 | /*
4 |
5 | Mersenne Twister in JavaScript based on "mt19937ar.c"
6 |
7 | * JavaScript version by Magicant: Copyright (C) 2005 Magicant
8 |
9 |
10 | * Original C version by Makoto Matsumoto and Takuji Nishimura
11 | http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/mt.html
12 |
13 | Copyright (C) 1997 - 2002, Makoto Matsumoto and Takuji Nishimura,
14 | All rights reserved.
15 |
16 | Redistribution and use in source and binary forms, with or without
17 | modification, are permitted provided that the following conditions
18 | are met:
19 |
20 | 1. Redistributions of source code must retain the above copyright
21 | notice, this list of conditions and the following disclaimer.
22 |
23 | 2. Redistributions in binary form must reproduce the above copyright
24 | notice, this list of conditions and the following disclaimer in the
25 | documentation and/or other materials provided with the distribution.
26 |
27 | 3. The names of its contributors may not be used to endorse or promote
28 | products derived from this software without specific prior written
29 | permission.
30 |
31 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
32 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
33 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
34 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
35 | CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
36 | EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
37 | PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
38 | PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
39 | LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
40 | NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
41 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
42 |
43 | */
44 |
45 |
46 | // Methods whose name starts with "_" are private methods.
47 | // Don't call them externally!
48 |
49 |
50 | /**
51 | * Constructor: MersenneTwister([integer/Array seed])
52 | * initializes the object with the given seed.
53 | * The seed may be an integer or an array of integers.
54 | * If the seed is not given, the object will be initialized with the current
55 | * time: new Date().getTime().
56 | * See also: setSeed(seed).
57 | */
58 | function MersenneTwister(seed) {
59 | if (arguments.length == 0)
60 | seed = new Date().getTime();
61 |
62 | this._mt = new Array(624);
63 | this.setSeed(seed);
64 | }
65 |
66 | /** multiplies two uint32 values and returns a uint32 result. */
67 | MersenneTwister._mulUint32 = function(a, b) {
68 | var a1 = a >>> 16, a2 = a & 0xffff;
69 | var b1 = b >>> 16, b2 = b & 0xffff;
70 | return (((a1 * b2 + a2 * b1) << 16) + a2 * b2) >>> 0;
71 | };
72 |
73 | /** returns ceil(value) if value is finite number, otherwise 0. */
74 | MersenneTwister._toNumber = function(x) {
75 | return (typeof x == "number" && !isNaN(x)) ? Math.ceil(x) : 0;
76 | };
77 |
78 | /**
79 | * Method: setSeed(integer/Array seed)
80 | * resets the seed. The seed may be an integer or an array of integers.
81 | * Elements in the seed array that are not numbers will be treated as 0.
82 | * Numbers that are not integers will be rounded down.
83 | * The integer(s) should be greater than or equal to 0 and less than 2^32.
84 | * This method is compatible with init_genrand and init_by_array function of
85 | * the original C version.
86 | */
87 | MersenneTwister.prototype.setSeed = function(seed) {
88 | var mt = this._mt;
89 | if (typeof seed == "number") {
90 | mt[0] = seed >>> 0;
91 | for (var i = 1; i < mt.length; i++) {
92 | var x = mt[i-1] ^ (mt[i-1] >>> 30);
93 | mt[i] = MersenneTwister._mulUint32(1812433253, x) + i;
94 | }
95 | this._index = mt.length;
96 | } else if (seed instanceof Array) {
97 | var i = 1, j = 0;
98 | this.setSeed(19650218);
99 | for (var k = Math.max(mt.length, seed.length); k > 0; k--) {
100 | var x = mt[i-1] ^ (mt[i-1] >>> 30);
101 | x = MersenneTwister._mulUint32(x, 1664525);
102 | mt[i] = (mt[i] ^ x) + (seed[j] >>> 0) + j;
103 | if (++i >= mt.length) {
104 | mt[0] = mt[mt.length-1];
105 | i = 1;
106 | }
107 | if (++j >= seed.length) {
108 | j = 0;
109 | }
110 | }
111 | for (var k = mt.length - 1; k > 0; k--) {
112 | var x = mt[i-1] ^ (mt[i-1] >>> 30);
113 | x = MersenneTwister._mulUint32(x, 1566083941);
114 | mt[i] = (mt[i] ^ x) - i;
115 | if (++i >= mt.length) {
116 | mt[0] = mt[mt.length-1];
117 | i = 1;
118 | }
119 | }
120 | mt[0] = 0x80000000;
121 | } else {
122 | throw new TypeError("MersenneTwister: illegal seed.");
123 | }
124 | };
125 |
126 | /** returns the next random Uint32 value. */
127 | MersenneTwister.prototype._nextInt = function() {
128 | var mt = this._mt, value;
129 |
130 | if (this._index >= mt.length) {
131 | var k = 0, N = mt.length, M = 397;
132 | do {
133 | value = (mt[k] & 0x80000000) | (mt[k+1] & 0x7fffffff);
134 | mt[k] = mt[k+M] ^ (value >>> 1) ^ ((value & 1) ? 0x9908b0df : 0);
135 | } while (++k < N-M);
136 | do {
137 | value = (mt[k] & 0x80000000) | (mt[k+1] & 0x7fffffff);
138 | mt[k] = mt[k+M-N] ^ (value >>> 1) ^ ((value & 1) ? 0x9908b0df : 0);
139 | } while (++k < N-1);
140 | value = (mt[N-1] & 0x80000000) | (mt[0] & 0x7fffffff);
141 | mt[N-1] = mt[M-1] ^ (value >>> 1) ^ ((value & 1) ? 0x9908b0df : 0);
142 | this._index = 0;
143 | }
144 |
145 | value = mt[this._index++];
146 | value ^= value >>> 11;
147 | value ^= (value << 7) & 0x9d2c5680;
148 | value ^= (value << 15) & 0xefc60000;
149 | value ^= value >>> 18;
150 | return value >>> 0;
151 | };
152 |
153 | /**
154 | * Method: nextInt([[number min,] number max])
155 | * returns a random integer that is greater than or equal to min and less than
156 | * max. The value of (max - min) must be positive number less or equal to 2^32.
157 | * If min is not given or not a number, this method uses 0 for min.
158 | * If neither of min and max is given or max is out of range, this method
159 | * uses 2^32 for max.
160 | * This method is compatible with genrand_int32 function of the original C
161 | * version for min=0 & max=2^32, but not with genrand_int31 function.
162 | */
163 | MersenneTwister.prototype.nextInt = function() {
164 | var min, sup;
165 | switch (arguments.length) {
166 | case 0:
167 | return this._nextInt();
168 | case 1:
169 | min = 0;
170 | sup = MersenneTwister._toNumber(arguments[0]);
171 | break;
172 | default:
173 | min = MersenneTwister._toNumber(arguments[0]);
174 | sup = MersenneTwister._toNumber(arguments[1]) - min;
175 | break;
176 | }
177 |
178 | if (!(0 < sup && sup < 0x100000000))
179 | return this._nextInt() + min;
180 | if ((sup & (~sup + 1)) == sup)
181 | return ((sup - 1) & this._nextInt()) + min;
182 |
183 | var value;
184 | do {
185 | value = this._nextInt();
186 | } while (sup > 4294967296 - (value - (value %= sup)));
187 | return value + min;
188 | };
189 |
190 | /**
191 | * Method: next()
192 | * returns a random number that is greater than or equal to 0 and less than 1.
193 | * This method is compatible with genrand_res53 function of the original C
194 | * version.
195 | */
196 | MersenneTwister.prototype.next = function() {
197 | var a = this._nextInt() >>> 5, b = this._nextInt() >>> 6;
198 | return (a * 0x4000000 + b) / 0x20000000000000;
199 | };
200 |
201 | if (module) {
202 | module.exports = MersenneTwister;
203 | }
204 |
--------------------------------------------------------------------------------
/examples/js/render.js:
--------------------------------------------------------------------------------
1 | var scene, camera, renderer, group;
2 |
3 | function toDataURL(format) {
4 | if (renderer) {
5 | const dom = renderer.domElement;
6 | switch (format) {
7 | case 'jpg':
8 | case 'jpeg': return dom.toDataURL("image/jpeg");
9 | case 'gif': return dom.toDataURL("image/gif");
10 | default: return dom.toDataURL("image/png");
11 | }
12 | }
13 | }
14 |
15 | function save(format) {
16 | window.open(toDataURL(format));
17 | }
18 |
19 | function render() {
20 | requestAnimationFrame( render );
21 |
22 | group.rotation.x += 0.005;
23 | group.rotation.y += 0.005;
24 |
25 | renderer.render( scene, camera );
26 | };
27 |
28 | function createGeometry(type) {
29 | switch (type) {
30 | case 'box': return new THREE.BoxBufferGeometry(1, 1, 1);
31 | // TODO https://threejs.org/docs/#api/en/geometries/WireframeGeometry
32 | case 'grid': return new THREE.BoxBufferGeometry(1, 1, 1);
33 | case 'sphere': return new THREE.SphereBufferGeometry(.5, 32, 32);
34 | case 'line':
35 | var points = [];
36 | points.push( new THREE.Vector3(-.5, 0, 0 ));
37 | points.push( new THREE.Vector3( .5, 0, 0 ));
38 | return new THREE.BufferGeometry().setFromPoints(points);
39 | case 'point':
40 | console.warn("point is not implemented yet"); return;
41 | case 'mesh': console.warn("mesh is not implemented yet"); return;
42 | case 'cylinder': return new THREE.CylinderBufferGeometry(.5, .5, 1, 32);
43 | case 'tube': console.warn("tube is not implemented yet"); return;
44 | case 'triangle':
45 | var geometry = new THREE.BufferGeometry();
46 | // default position if not specified
47 | var vertices = new Float32Array( [
48 | 0.0, .5, 0.0,
49 | -.5, -.5, 0.0,
50 | .5, -.5, 0.0
51 | ] );
52 | geometry.setAttribute( 'position', new THREE.BufferAttribute(vertices, 3));
53 | return geometry;
54 | case 'squash':
55 | var geometry = new THREE.SphereBufferGeometry(.5, 32, 32);
56 | geometry.scale(1, .5, 1);
57 | return geometry;
58 | }
59 | }
60 |
61 | function applyVertexColors(geometry, color) {
62 | var position = geometry.attributes.position;
63 | var colors = [];
64 |
65 | for ( var i = 0; i < position.count; i ++ ) {
66 | colors.push(color.r, color.g, color.b, -100);
67 | }
68 |
69 | geometry.setAttribute('color', new THREE.Float32BufferAttribute(colors, 4));
70 | }
71 |
72 | function init(objectCode) {
73 |
74 | ///////////////////////////////
75 | // SCENE
76 | ///////////////////////////////
77 | scene = new THREE.Scene();
78 | scene.background = new THREE.Color(0x444444);
79 |
80 |
81 | ///////////////////////////////
82 | // CAMERA
83 | ///////////////////////////////
84 | camera = new THREE.PerspectiveCamera(30, window.innerWidth / window.innerHeight, 1, 100000);
85 | camera.position.z = 10;
86 |
87 |
88 | ///////////////////////////////
89 | // RENDERER
90 | ///////////////////////////////
91 | renderer = new THREE.WebGLRenderer({ antialias: true });
92 | renderer.setPixelRatio(window.devicePixelRatio);
93 | renderer.setSize(window.innerWidth, window.innerHeight);
94 | document.body.appendChild(renderer.domElement);
95 |
96 |
97 | ///////////////////////////////
98 | // CONTROLLER
99 | ///////////////////////////////
100 | var orbit = new THREE.OrbitControls(camera, renderer.domElement);
101 |
102 |
103 | ///////////////////////////////
104 | // LIGHT
105 | ///////////////////////////////
106 | var lights = [];
107 | lights[0] = new THREE.PointLight(0xffffff, 1, 0);
108 | lights[1] = new THREE.PointLight(0xffffff, 1, 0);
109 | lights[2] = new THREE.PointLight(0xffffff, 1, 0);
110 |
111 | lights[0].position.set(0, 200, 0);
112 | lights[1].position.set(100, 200, 100);
113 | lights[2].position.set(- 100, - 200, - 100);
114 |
115 | scene.add(lights[0]);
116 | scene.add(lights[1]);
117 | scene.add(lights[2]);
118 |
119 | var light = new THREE.SpotLight( 0xffffff, .5 );
120 | light.position.set(0, 500, 2000);
121 | // scene.add( light );
122 |
123 | ///////////////////////////////
124 | // PRIMITIVE
125 | ///////////////////////////////
126 | group = new THREE.Group();
127 | scene.add(group);
128 |
129 | let transparent = false;
130 | for (let i = 0; i < objectCode.objects.length; i++) {
131 | let object = objectCode.objects[i]
132 | if (object.type === 'primitive') {
133 | if (object.opacity !== 1) {
134 | console.warn(`If you don't use transparency (alpha parameter), performance will be improved extremely.`);
135 | transparent = true;
136 | break;
137 | }
138 | }
139 | }
140 |
141 | var geometries = [];
142 | var count = 0;
143 | objectCode.objects.reverse().forEach(function(object) {
144 | switch (object.type) {
145 | case 'background':
146 | scene.background = new THREE.Color(object.color);
147 | break;
148 | case 'primitive':
149 | const geometry = createGeometry(object.name);
150 |
151 | // Used in the case of triangle primitive for now
152 | if (object.coords) {
153 | var c = object.coords;
154 | var vertices = new Float32Array([
155 | c[0][0], c[0][1], c[0][2],
156 | c[1][0], c[1][1], c[1][2],
157 | c[2][0], c[2][1], c[2][2],
158 | ]);
159 | geometry.setAttribute( 'position', new THREE.BufferAttribute(vertices, 3));
160 | }
161 |
162 | const matrix = new THREE.Matrix4();
163 | matrix.fromArray(object.matrix.elements)
164 | geometry.applyMatrix(matrix);
165 |
166 | if (transparent) {
167 | var meshMaterial = new THREE.MeshPhongMaterial({
168 | color: parseInt(object.color.replace(/^#/, '0x'), 16),
169 | specular: 0x999999,
170 | shininess: 30,
171 | flatShading: true,
172 | shininess: 0,
173 | opacity: object.opacity,
174 | transparent: true
175 | });
176 |
177 | if (object.name === 'grid') {
178 | meshMaterial.wireframe = true;
179 | }
180 |
181 | if (object.name === 'triangle') {
182 | meshMaterial.side = THREE.DoubleSide;
183 | }
184 |
185 | if (object.name === 'line') {
186 | group.add(new THREE.Line( geometry, meshMaterial ));
187 | } else {
188 | group.add(new THREE.Mesh(geometry, meshMaterial));
189 | }
190 |
191 | } else {
192 | // if not transparency, use this for performance
193 | // change hex color format to 0xFF7733 from #FF7733
194 | const color = new THREE.Color();
195 | applyVertexColors(geometry, color.setHex(object.color.replace(/^#/, '0x')));
196 | geometries.push(geometry);
197 | }
198 |
199 | count++;
200 | break;
201 | }
202 | });
203 |
204 | // if not transparency, use this for performance
205 | if (!transparent) {
206 | var defaultMaterial = new THREE.MeshPhongMaterial({
207 | color: 0xffffff,
208 | flatShading: true,
209 | vertexColors: true,
210 | emissive: 0x072534,
211 | transparent: true,
212 | opacity: 1,
213 | wireframe: true,
214 | side: THREE.DoubleSide
215 | });
216 | group.add(new THREE.Mesh(THREE.BufferGeometryUtils.mergeBufferGeometries(geometries), defaultMaterial));
217 | }
218 |
219 | console.log(`Build done. Created ${count} objects.`);
220 | }
221 |
222 |
223 |
224 | window.addEventListener('resize', function() {
225 |
226 | camera.aspect = window.innerWidth / window.innerHeight;
227 | camera.updateProjectionMatrix();
228 | renderer.setSize(window.innerWidth, window.innerHeight);
229 |
230 | }, false);
231 |
--------------------------------------------------------------------------------
/examples/css/main.css:
--------------------------------------------------------------------------------
1 | :root {
2 | color-scheme: light dark;
3 |
4 | --background-color: #fff;
5 |
6 | --color-blue: #049EF4;
7 | --text-color: #444;
8 | --secondary-text-color: #9e9e9e;
9 |
10 | --font-size: 16px;
11 | --line-height: 26px;
12 |
13 | --border-style: 1px solid #E8E8E8;
14 | --header-height: 48px;
15 | --panel-width: 300px;
16 | --panel-padding: 16px;
17 | --icon-size: 20px;
18 | }
19 |
20 | @media (prefers-color-scheme: dark) {
21 |
22 | :root {
23 | --background-color: #222;
24 |
25 | --text-color: #bbb;
26 | --secondary-text-color: #666;
27 |
28 | --border-style: 1px solid #444;
29 | }
30 |
31 | }
32 |
33 | @font-face {
34 | font-family: 'Roboto Mono';
35 | src: local('Roboto Mono'), local('RobotoMono-Regular'), url('../files/RobotoMono-Regular.woff2') format('woff2');
36 | font-style: normal;
37 | font-weight: 400;
38 | }
39 |
40 | @font-face {
41 | font-family: 'Roboto Mono';
42 | src: local('Roboto Mono Medium'), local('RobotoMono-Medium'), url('../files/RobotoMono-Medium.woff2') format('woff2');
43 | font-style: normal;
44 | font-weight: 500;
45 | }
46 |
47 | * {
48 | box-sizing: border-box;
49 | -webkit-font-smoothing: antialiased;
50 | -moz-osx-font-smoothing: grayscale;
51 | }
52 |
53 | html, body {
54 | height: 100%;
55 | }
56 |
57 | html {
58 | font-size: calc(var(--font-size) - 1px);
59 | line-height: calc(var(--line-height) - 1px);
60 | }
61 |
62 | body {
63 | font-family: 'Roboto Mono', monospace;
64 | margin: 0px;
65 | color: var(--text-color);
66 | background-color: var(--background-color);
67 | }
68 |
69 | a {
70 | text-decoration: none;
71 | }
72 |
73 | h1 {
74 | font-size: 18px;
75 | line-height: 24px;
76 | font-weight: 500;
77 | }
78 |
79 | h2 {
80 | padding: 0;
81 | margin: 16px 0;
82 | font-size: calc(var(--font-size) - 1px);
83 | line-height: var(--line-height);
84 | font-weight: 500;
85 | color: var(--color-blue);
86 | }
87 |
88 | h3 {
89 | margin: 0;
90 | font-weight: 500;
91 | font-size: calc(var(--font-size) - 1px);
92 | line-height: var(--line-height);
93 | color: var(--secondary-text-color);
94 | }
95 |
96 | h1 a {
97 | color: var(--color-blue);
98 | }
99 |
100 | #header {
101 | display: flex;
102 | height: var(--header-height);
103 | border-bottom: var(--border-style);
104 | align-items: center;
105 | }
106 | #header h1 {
107 | padding-left: var(--panel-padding);
108 | flex: 1;
109 | display: flex;
110 | align-items: center;
111 | color: var(--color-blue);
112 | }
113 | #header #version {
114 | border: 1px solid var(--color-blue);
115 | color: var(--color-blue);
116 | border-radius: 4px;
117 | line-height: 16px;
118 | padding: 0px 2px;
119 | margin-left: 6px;
120 | font-size: .9rem;
121 | }
122 |
123 | #panel {
124 | position: fixed;
125 | z-index: 100;
126 | left: 0px;
127 | width: var(--panel-width);
128 | height: 100%;
129 | overflow: auto;
130 | border-right: var(--border-style);
131 | display: flex;
132 | flex-direction: column;
133 | transition: 0s 0s height;
134 | }
135 |
136 | #panel #exitSearchButton {
137 | width: 48px;
138 | height: 48px;
139 | display: none;
140 | background-color: var(--text-color);
141 | background-size: var(--icon-size);
142 | -webkit-mask-image: url(../files/ic_close_black_24dp.svg);
143 | -webkit-mask-position: 50% 50%;
144 | -webkit-mask-repeat: no-repeat;
145 | mask-image: url(../files/ic_close_black_24dp.svg);
146 | mask-position: 50% 50%;
147 | mask-repeat: no-repeat;
148 | cursor: pointer;
149 | margin-right: 0px;
150 | }
151 |
152 | #panel.searchFocused #exitSearchButton {
153 | display: block;
154 | }
155 |
156 | #panel.searchFocused #language {
157 | display: none;
158 | }
159 |
160 | #panel.searchFocused #filter {
161 | -webkit-mask-image: none;
162 | mask-image: none;
163 | background-color: inherit;
164 | padding-left: 0;
165 | }
166 |
167 | #panel #expandButton {
168 | width: 48px;
169 | height: 48px;
170 | margin-right: 4px;
171 | margin-left: 4px;
172 | display: none;
173 | cursor: pointer;
174 | background-color: var(--text-color);
175 | background-size: var(--icon-size);
176 | -webkit-mask-image: url(../files/ic_menu_black_24dp.svg);
177 | -webkit-mask-position: 50% 50%;
178 | -webkit-mask-repeat: no-repeat;
179 | mask-image: url(../files/ic_menu_black_24dp.svg);
180 | mask-position: 50% 50%;
181 | mask-repeat: no-repeat;
182 | }
183 |
184 | #panel #sections {
185 | display: flex;
186 | justify-content: center;
187 | z-index: 1000;
188 | position: relative;
189 | height: 100%;
190 | align-items: center;
191 | font-weight: 500;
192 | }
193 |
194 | #panel #sections * {
195 | padding: 0 var(--panel-padding);
196 | height: 100%;
197 | position: relative;
198 | display: flex;
199 | justify-content: center;
200 | align-items: center;
201 | }
202 | #panel #sections .selected:after {
203 | content: "";
204 | position: absolute;
205 | left: 0;
206 | right: 0;
207 | bottom: -1px;
208 | border-bottom: 1px solid var(--text-color);
209 | }
210 | #panel #sections a {
211 | color: var(--secondary-text-color);
212 | }
213 |
214 | body.home #panel #sections {
215 | display: none;
216 | }
217 |
218 | #panel #inputWrapper {
219 | display: flex;
220 | align-items: center;
221 | height: var(--header-height);
222 | padding: 0 0 0 var(--panel-padding);
223 | position: relative;
224 | background: var(--background-color);
225 | }
226 | #panel #inputWrapper:after {
227 | position: absolute;
228 | left: 0;
229 | right: 0;
230 | bottom: 0;
231 | border-bottom: var(--border-style);
232 | content: "";
233 | }
234 |
235 | #panel #filter {
236 | flex: 1;
237 | width: 100%;
238 | padding: 0 36px;
239 | font-size: 1rem;
240 | font-weight: 500;
241 | color: var(--text-color);
242 | outline: none;
243 | border: 0px;
244 | background-color: var(--text-color);
245 | background-size: var(--icon-size);
246 | -webkit-mask-image: url(../files/ic_search_black_24dp.svg);
247 | -webkit-mask-position: 0 50%;
248 | -webkit-mask-repeat: no-repeat;
249 | mask-image: url(../files/ic_search_black_24dp.svg);
250 | mask-position: 0 50%;
251 | mask-repeat: no-repeat;
252 | font-family: 'Roboto Mono', monospace;
253 | }
254 |
255 | #panel #language {
256 | font-family: 'Roboto Mono', monospace;
257 | font-size: 1rem;
258 | line-height: 1rem;
259 | font-weight: 500;
260 | color: var(--text-color);
261 | border: 0px;
262 | background-image: url(ic_arrow_drop_down_black_24dp.svg);
263 | background-size: var(--icon-size);
264 | background-repeat: no-repeat;
265 | background-position: right center;
266 | background-color: var(--background-color);
267 | padding: 2px 24px 4px 24px;
268 | -webkit-appearance: none;
269 | -moz-appearance: none;
270 | appearance: none;
271 | margin-right: 10px;
272 | }
273 |
274 | #panel #language:focus {
275 | outline: none;
276 | }
277 |
278 | #contentWrapper {
279 | flex: 1;
280 | overflow: hidden;
281 | display: flex;
282 | flex-direction: column;
283 | transform: translate3d(0,0,0);
284 | }
285 | #panel #content {
286 | flex: 1;
287 | overflow-y: auto;
288 | overflow-x: hidden;
289 | -webkit-overflow-scrolling: touch;
290 | padding: 0 var(--panel-padding) var(--panel-padding) var(--panel-padding);
291 | }
292 |
293 | #panel #content ul {
294 | list-style-type: none;
295 | padding: 0px;
296 | margin: 0px 0 20px 0;
297 | }
298 | #panel #content ul li {
299 | margin: 1px 0;
300 | }
301 |
302 | #panel #content h2 {
303 | margin-top: 32px;
304 | border-top: var(--border-style);
305 | padding-top: 12px;
306 | }
307 |
308 | #panel #content h2:first-child {
309 | margin-top: 16px !important;
310 | border-top: none;
311 | padding-top: 0;
312 | }
313 |
314 | #panel #content a {
315 | position: relative;
316 | color: var(--text-color);
317 | }
318 |
319 | #panel #content a:hover,
320 | #panel #content a:hover .spacer,
321 | #panel #content .selected {
322 | color: var(--color-blue);
323 | }
324 |
325 | #panel #content .selected {
326 | text-decoration: underline;
327 | }
328 |
329 | #panel #content .hidden {
330 | display: none !important;
331 | }
332 |
333 | body.home #panel #content h2 {
334 | margin-bottom: 2px;
335 | padding-bottom: 0px;
336 | margin-top: 18px;
337 | border-top: none;
338 | padding-top: 6px;
339 | }
340 |
341 | .spacer {
342 | color: var(--secondary-text-color);
343 | margin-left: 2px;
344 | padding-right: 2px;
345 | }
346 |
347 | #viewer,
348 | iframe {
349 | position: absolute;
350 | border: 0px;
351 | left: 0;
352 | right: 0;
353 | width: 100%;
354 | height: 100%;
355 | overflow: auto;
356 | }
357 |
358 | #viewer {
359 | padding-left: var(--panel-width);
360 | }
361 |
362 | #button {
363 | position: fixed;
364 | bottom: 16px;
365 | right: 16px;
366 |
367 | padding: 12px;
368 | border-radius: 50%;
369 | margin-bottom: 0px;
370 |
371 | background-color: #FFF;
372 | opacity: .9;
373 | z-index: 999;
374 |
375 | box-shadow: 0 0 4px rgba(0,0,0,.15);
376 | }
377 | #button:hover {
378 | cursor: pointer;
379 | opacity: 1;
380 | }
381 | #button img {
382 | display: block;
383 | width: var(--icon-size);
384 | }
385 |
386 | #button.text {
387 | border-radius: 25px;
388 | padding-right: 20px;
389 | padding-left: 20px;
390 | color: var(--color-blue);
391 | opacity: 1;
392 | font-weight: 500;
393 | }
394 |
395 |
396 | #projects {
397 | display: grid;
398 | grid-template-columns: repeat(6, 1fr);
399 | line-height: 0;
400 | }
401 | #projects a {
402 | overflow: hidden;
403 | }
404 | #projects a img {
405 | width: 100%;
406 | transform: scale(1.0);
407 | transition: 0.15s transform;
408 | }
409 | #projects a:hover img {
410 | transform: scale(1.08);
411 | }
412 |
413 |
414 |
415 | @media all and ( min-width: 1500px ) {
416 | #projects {
417 | grid-template-columns: repeat(7, 1fr);
418 | }
419 | }
420 |
421 | @media all and ( min-width: 1700px ) {
422 | :root {
423 | --panel-width: 360px;
424 | --font-size: 18px;
425 | --line-height: 28px;
426 | --header-height: 56px;
427 | --icon-size: 24px;
428 | }
429 | #projects {
430 | grid-template-columns: repeat(8, 1fr);
431 | }
432 | }
433 |
434 | @media all and ( min-width: 1900px ) {
435 |
436 | #projects {
437 | grid-template-columns: repeat(9, 1fr);
438 | }
439 |
440 | }
441 |
442 | @media all and ( max-width: 1300px ) {
443 | #projects {
444 | grid-template-columns: repeat(6, 1fr);
445 | }
446 | }
447 |
448 | @media all and ( max-width: 1100px ) {
449 | #projects {
450 | grid-template-columns: repeat(5, 1fr);
451 | }
452 | }
453 |
454 | @media all and ( max-width: 900px ) {
455 | #projects {
456 | grid-template-columns: repeat(4, 1fr);
457 | }
458 | }
459 |
460 | @media all and ( max-width: 700px ) {
461 | #projects {
462 | grid-template-columns: repeat(3, 1fr);
463 | }
464 | }
465 |
466 |
467 | /* mobile */
468 |
469 | @media all and ( max-width: 640px ) {
470 |
471 | :root {
472 | --header-height: 56px;
473 | --icon-size: 24px;
474 | }
475 |
476 | #projects {
477 | grid-template-columns: repeat(2, 1fr);
478 | }
479 |
480 | #panel #expandButton {
481 | display: block;
482 | }
483 | #panel {
484 | position: absolute;
485 | left: 0;
486 | top: 0;
487 | width: 100%;
488 | right: 0;
489 | z-index: 1000;
490 | overflow-x: hidden;
491 | transition: 0s 0s height;
492 | border: none;
493 | height: var(--header-height);
494 | transition: 0s 0.2s height;
495 | }
496 | #panel.open {
497 | height: 100%;
498 | transition: 0s 0s height;
499 | }
500 |
501 | #panelScrim {
502 | pointer-events: none;
503 | background-color: rgba(0,0,0,0);
504 | position: absolute;
505 | left: 0;
506 | right: 0;
507 | top: 0;
508 | bottom: 0;
509 | z-index: 1000;
510 | pointer-events: none;
511 | transition: .2s background-color;
512 | }
513 | #panel.open #panelScrim {
514 | pointer-events: auto;
515 | background-color: rgba(0,0,0,0.4);
516 | }
517 |
518 | #contentWrapper {
519 | position: absolute;
520 | right: 0;
521 | top: 0;
522 | bottom: 0;
523 | background: var(--background-color);
524 | box-shadow: 0 0 8px rgba(0,0,0,.1);
525 | width: calc(100vw - 60px);
526 | max-width: 360px;
527 | z-index: 10000;
528 | transition: .25s transform;
529 | overflow-x: hidden;
530 | margin-right: -380px;
531 | line-height: 2rem;
532 | }
533 | #panel.open #contentWrapper {
534 | transform: translate3d(-380px, 0 ,0);
535 | }
536 | #viewer,
537 | iframe {
538 | left: 0;
539 | top: var(--header-height);
540 | width: 100%;
541 | height: calc(100% - var(--header-height));
542 | }
543 | #viewer {
544 | padding-left: 0;
545 | }
546 | }
547 |
--------------------------------------------------------------------------------
/examples/js/loaders/OBJLoader.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @author mrdoob / http://mrdoob.com/
3 | */
4 |
5 | THREE.OBJLoader = function () {
6 |
7 | THREE.EventDispatcher.call( this );
8 |
9 | };
10 |
11 | THREE.OBJLoader.prototype = {
12 |
13 | constructor: THREE.OBJLoader,
14 |
15 | load: function ( url, callback ) {
16 |
17 | var scope = this;
18 | var request = new XMLHttpRequest();
19 |
20 | request.addEventListener( 'load', function ( event ) {
21 |
22 | var hierarchy = scope.parse( event.target.responseText );
23 |
24 | scope.dispatchEvent( { type: 'load', content: hierarchy } );
25 |
26 | if ( callback ) callback( hierarchy );
27 |
28 | }, false );
29 |
30 | request.addEventListener( 'progress', function ( event ) {
31 |
32 | scope.dispatchEvent( { type: 'progress', loaded: event.loaded, total: event.total } );
33 |
34 | }, false );
35 |
36 | request.addEventListener( 'error', function () {
37 |
38 | scope.dispatchEvent( { type: 'error', message: 'Couldn\'t load URL [' + url + ']' } );
39 |
40 | }, false );
41 |
42 | request.open( 'GET', url, true );
43 | request.send( null );
44 |
45 | },
46 |
47 | parse: function ( data ) {
48 |
49 | // fixes
50 |
51 | data = data.replace( /\ \\\r\n/g, '' ); // rhino adds ' \\r\n' some times.
52 |
53 | //
54 |
55 | function vector( x, y, z ) {
56 |
57 | return new THREE.Vector3( x, y, z );
58 |
59 | }
60 |
61 | function uv( u, v ) {
62 |
63 | return new THREE.Vector2( u, v );
64 |
65 | }
66 |
67 | function face3( a, b, c, normals ) {
68 |
69 | return new THREE.Face3( a, b, c, normals );
70 |
71 | }
72 |
73 | function face4( a, b, c, d, normals ) {
74 |
75 | return new THREE.Face4( a, b, c, d, normals );
76 |
77 | }
78 |
79 | function meshN( meshName, materialName ) {
80 |
81 | if ( geometry.vertices.length > 0 ) {
82 |
83 | geometry.mergeVertices();
84 | geometry.computeCentroids();
85 | geometry.computeFaceNormals();
86 | geometry.computeBoundingSphere();
87 |
88 | object.add( mesh );
89 |
90 | geometry = new THREE.Geometry();
91 | mesh = new THREE.Mesh( geometry, material );
92 |
93 | verticesCount = 0;
94 |
95 | }
96 |
97 | if ( meshName !== undefined ) mesh.name = meshName;
98 | if ( materialName !== undefined ) {
99 |
100 | material = new THREE.MeshLambertMaterial();
101 | material.name = materialName;
102 |
103 | mesh.material = material;
104 |
105 | }
106 |
107 | }
108 |
109 | var group = new THREE.Object3D();
110 | var object = group;
111 |
112 | var geometry = new THREE.Geometry();
113 | var material = new THREE.MeshLambertMaterial();
114 | var mesh = new THREE.Mesh( geometry, material );
115 |
116 | var vertices = [];
117 | var verticesCount = 0;
118 | var normals = [];
119 | var uvs = [];
120 |
121 | // v float float float
122 |
123 | var vertex_pattern = /v( +[\d|\.|\+|\-|e]+)( [\d|\.|\+|\-|e]+)( [\d|\.|\+|\-|e]+)/;
124 |
125 | // vn float float float
126 |
127 | var normal_pattern = /vn( +[\d|\.|\+|\-|e]+)( [\d|\.|\+|\-|e]+)( [\d|\.|\+|\-|e]+)/;
128 |
129 | // vt float float
130 |
131 | var uv_pattern = /vt( +[\d|\.|\+|\-|e]+)( [\d|\.|\+|\-|e]+)/;
132 |
133 | // f vertex vertex vertex ...
134 |
135 | var face_pattern1 = /f( +[\d]+)( [\d]+)( [\d]+)( [\d]+)?/;
136 |
137 | // f vertex/uv vertex/uv vertex/uv ...
138 |
139 | var face_pattern2 = /f( +([\d]+)\/([\d]+))( ([\d]+)\/([\d]+))( ([\d]+)\/([\d]+))( ([\d]+)\/([\d]+))?/;
140 |
141 | // f vertex/uv/normal vertex/uv/normal vertex/uv/normal ...
142 |
143 | var face_pattern3 = /f( +([\d]+)\/([\d]+)\/([\d]+))( ([\d]+)\/([\d]+)\/([\d]+))( ([\d]+)\/([\d]+)\/([\d]+))( ([\d]+)\/([\d]+)\/([\d]+))?/;
144 |
145 | // f vertex//normal vertex//normal vertex//normal ...
146 |
147 | var face_pattern4 = /f( +([\d]+)\/\/([\d]+))( ([\d]+)\/\/([\d]+))( ([\d]+)\/\/([\d]+))( ([\d]+)\/\/([\d]+))?/;
148 |
149 | //
150 |
151 | var lines = data.split( "\n" );
152 |
153 | for ( var i = 0; i < lines.length; i ++ ) {
154 |
155 | var line = lines[ i ];
156 | line = line.trim();
157 |
158 | var result;
159 |
160 | if ( line.length === 0 || line.charAt( 0 ) === '#' ) {
161 |
162 | continue;
163 |
164 | } else if ( ( result = vertex_pattern.exec( line ) ) !== null ) {
165 |
166 | // ["v 1.0 2.0 3.0", "1.0", "2.0", "3.0"]
167 |
168 | vertices.push( vector(
169 | parseFloat( result[ 1 ] ),
170 | parseFloat( result[ 2 ] ),
171 | parseFloat( result[ 3 ] )
172 | ) );
173 |
174 | } else if ( ( result = normal_pattern.exec( line ) ) !== null ) {
175 |
176 | // ["vn 1.0 2.0 3.0", "1.0", "2.0", "3.0"]
177 |
178 | normals.push( vector(
179 | parseFloat( result[ 1 ] ),
180 | parseFloat( result[ 2 ] ),
181 | parseFloat( result[ 3 ] )
182 | ) );
183 |
184 | } else if ( ( result = uv_pattern.exec( line ) ) !== null ) {
185 |
186 | // ["vt 0.1 0.2", "0.1", "0.2"]
187 |
188 | uvs.push( uv(
189 | parseFloat( result[ 1 ] ),
190 | parseFloat( result[ 2 ] )
191 | ) );
192 |
193 | } else if ( ( result = face_pattern1.exec( line ) ) !== null ) {
194 |
195 | // ["f 1 2 3", "1", "2", "3", undefined]
196 |
197 | if ( result[ 4 ] === undefined ) {
198 |
199 | geometry.vertices.push(
200 | vertices[ parseInt( result[ 1 ] ) - 1 ],
201 | vertices[ parseInt( result[ 2 ] ) - 1 ],
202 | vertices[ parseInt( result[ 3 ] ) - 1 ]
203 | );
204 |
205 | geometry.faces.push( face3(
206 | verticesCount ++,
207 | verticesCount ++,
208 | verticesCount ++
209 | ) );
210 |
211 | } else {
212 |
213 | geometry.vertices.push(
214 | vertices[ parseInt( result[ 1 ] ) - 1 ],
215 | vertices[ parseInt( result[ 2 ] ) - 1 ],
216 | vertices[ parseInt( result[ 3 ] ) - 1 ],
217 | vertices[ parseInt( result[ 4 ] ) - 1 ]
218 | );
219 |
220 | geometry.faces.push( face4(
221 | verticesCount ++,
222 | verticesCount ++,
223 | verticesCount ++,
224 | verticesCount ++
225 | ) );
226 |
227 | }
228 |
229 | } else if ( ( result = face_pattern2.exec( line ) ) !== null ) {
230 |
231 | // ["f 1/1 2/2 3/3", " 1/1", "1", "1", " 2/2", "2", "2", " 3/3", "3", "3", undefined, undefined, undefined]
232 |
233 | if ( result[ 10 ] === undefined ) {
234 |
235 | geometry.vertices.push(
236 | vertices[ parseInt( result[ 2 ] ) - 1 ],
237 | vertices[ parseInt( result[ 5 ] ) - 1 ],
238 | vertices[ parseInt( result[ 8 ] ) - 1 ]
239 | );
240 |
241 | geometry.faces.push( face3(
242 | verticesCount ++,
243 | verticesCount ++,
244 | verticesCount ++
245 | ) );
246 |
247 | geometry.faceVertexUvs[ 0 ].push( [
248 | uvs[ parseInt( result[ 3 ] ) - 1 ],
249 | uvs[ parseInt( result[ 6 ] ) - 1 ],
250 | uvs[ parseInt( result[ 9 ] ) - 1 ]
251 | ] );
252 |
253 | } else {
254 |
255 | geometry.vertices.push(
256 | vertices[ parseInt( result[ 2 ] ) - 1 ],
257 | vertices[ parseInt( result[ 5 ] ) - 1 ],
258 | vertices[ parseInt( result[ 8 ] ) - 1 ],
259 | vertices[ parseInt( result[ 11 ] ) - 1 ]
260 | );
261 |
262 | geometry.faces.push( face4(
263 | verticesCount ++,
264 | verticesCount ++,
265 | verticesCount ++,
266 | verticesCount ++
267 | ) );
268 |
269 | geometry.faceVertexUvs[ 0 ].push( [
270 | uvs[ parseInt( result[ 3 ] ) - 1 ],
271 | uvs[ parseInt( result[ 6 ] ) - 1 ],
272 | uvs[ parseInt( result[ 9 ] ) - 1 ],
273 | uvs[ parseInt( result[ 12 ] ) - 1 ]
274 | ] );
275 |
276 | }
277 |
278 | } else if ( ( result = face_pattern3.exec( line ) ) !== null ) {
279 |
280 | // ["f 1/1/1 2/2/2 3/3/3", " 1/1/1", "1", "1", "1", " 2/2/2", "2", "2", "2", " 3/3/3", "3", "3", "3", undefined, undefined, undefined, undefined]
281 |
282 | if ( result[ 13 ] === undefined ) {
283 |
284 | geometry.vertices.push(
285 | vertices[ parseInt( result[ 2 ] ) - 1 ],
286 | vertices[ parseInt( result[ 6 ] ) - 1 ],
287 | vertices[ parseInt( result[ 10 ] ) - 1 ]
288 | );
289 |
290 | geometry.faces.push( face3(
291 | verticesCount ++,
292 | verticesCount ++,
293 | verticesCount ++,
294 | [
295 | normals[ parseInt( result[ 4 ] ) - 1 ],
296 | normals[ parseInt( result[ 8 ] ) - 1 ],
297 | normals[ parseInt( result[ 12 ] ) - 1 ]
298 | ]
299 | ) );
300 |
301 | geometry.faceVertexUvs[ 0 ].push( [
302 | uvs[ parseInt( result[ 3 ] ) - 1 ],
303 | uvs[ parseInt( result[ 7 ] ) - 1 ],
304 | uvs[ parseInt( result[ 11 ] ) - 1 ]
305 | ] );
306 |
307 | } else {
308 |
309 | geometry.vertices.push(
310 | vertices[ parseInt( result[ 2 ] ) - 1 ],
311 | vertices[ parseInt( result[ 6 ] ) - 1 ],
312 | vertices[ parseInt( result[ 10 ] ) - 1 ],
313 | vertices[ parseInt( result[ 14 ] ) - 1 ]
314 | );
315 |
316 | geometry.faces.push( face4(
317 | verticesCount ++,
318 | verticesCount ++,
319 | verticesCount ++,
320 | verticesCount ++,
321 | [
322 | normals[ parseInt( result[ 4 ] ) - 1 ],
323 | normals[ parseInt( result[ 8 ] ) - 1 ],
324 | normals[ parseInt( result[ 12 ] ) - 1 ],
325 | normals[ parseInt( result[ 16 ] ) - 1 ]
326 | ]
327 | ) );
328 |
329 | geometry.faceVertexUvs[ 0 ].push( [
330 | uvs[ parseInt( result[ 3 ] ) - 1 ],
331 | uvs[ parseInt( result[ 7 ] ) - 1 ],
332 | uvs[ parseInt( result[ 11 ] ) - 1 ],
333 | uvs[ parseInt( result[ 15 ] ) - 1 ]
334 | ] );
335 |
336 | }
337 |
338 | } else if ( ( result = face_pattern4.exec( line ) ) !== null ) {
339 |
340 | // ["f 1//1 2//2 3//3", " 1//1", "1", "1", " 2//2", "2", "2", " 3//3", "3", "3", undefined, undefined, undefined]
341 |
342 | if ( result[ 10 ] === undefined ) {
343 |
344 | geometry.vertices.push(
345 | vertices[ parseInt( result[ 2 ] ) - 1 ],
346 | vertices[ parseInt( result[ 5 ] ) - 1 ],
347 | vertices[ parseInt( result[ 8 ] ) - 1 ]
348 | );
349 |
350 | geometry.faces.push( face3(
351 | verticesCount ++,
352 | verticesCount ++,
353 | verticesCount ++,
354 | [
355 | normals[ parseInt( result[ 3 ] ) - 1 ],
356 | normals[ parseInt( result[ 6 ] ) - 1 ],
357 | normals[ parseInt( result[ 9 ] ) - 1 ]
358 | ]
359 | ) );
360 |
361 | } else {
362 |
363 | geometry.vertices.push(
364 | vertices[ parseInt( result[ 2 ] ) - 1 ],
365 | vertices[ parseInt( result[ 5 ] ) - 1 ],
366 | vertices[ parseInt( result[ 8 ] ) - 1 ],
367 | vertices[ parseInt( result[ 11 ] ) - 1 ]
368 | );
369 |
370 | geometry.faces.push( face4(
371 | verticesCount ++,
372 | verticesCount ++,
373 | verticesCount ++,
374 | verticesCount ++,
375 | [
376 | normals[ parseInt( result[ 3 ] ) - 1 ],
377 | normals[ parseInt( result[ 6 ] ) - 1 ],
378 | normals[ parseInt( result[ 9 ] ) - 1 ],
379 | normals[ parseInt( result[ 12 ] ) - 1 ]
380 | ]
381 | ) );
382 |
383 | }
384 |
385 | } else if ( /^o /.test( line ) ) {
386 |
387 | // object
388 |
389 | object = new THREE.Object3D();
390 | object.name = line.substring( 2 ).trim();
391 | group.add( object );
392 |
393 | } else if ( /^g /.test( line ) ) {
394 |
395 | // group
396 |
397 | meshN( line.substring( 2 ).trim(), undefined );
398 |
399 | } else if ( /^usemtl /.test( line ) ) {
400 |
401 | // material
402 |
403 | meshN( undefined, line.substring( 7 ).trim() );
404 |
405 | } else if ( /^mtllib /.test( line ) ) {
406 |
407 | // mtl file
408 |
409 | } else if ( /^s /.test( line ) ) {
410 |
411 | // smooth shading
412 |
413 | } else {
414 |
415 | // console.log( "THREE.OBJLoader: Unhandled line " + line );
416 |
417 | }
418 |
419 | }
420 |
421 | // add the last group
422 | meshN( undefined, undefined );
423 |
424 | return group;
425 |
426 | }
427 |
428 | }
429 |
--------------------------------------------------------------------------------
/src/parser.jison:
--------------------------------------------------------------------------------
1 | %lex
2 | %%
3 |
4 | \s+ /* skip */
5 | "//".* /* ignore comment */
6 | "/*"[\w\W]*?"*/" /* ignore comment */
7 |
8 | "set" return 'SET'
9 | "w" return 'WEIGHT';
10 | "weight" return 'WEIGHT';
11 | "md" return 'MAXDEPTH';
12 | "maxdepth" return 'MAXDEPTH';
13 | "maxobjects" return 'MAXOBJECTS';
14 | "minsize" return 'MINSIZE';
15 | "maxsize" return 'MAXSIZE';
16 | "seed" return 'SEED';
17 | "initial" return 'INITIAL';
18 | "background" return 'BACKGROUND';
19 | "colorpool" return 'COLORPOOL';
20 | "rule" return 'RULE';
21 | "Rule" return 'RULE';
22 | ">" return '>';
23 | "{" return '{';
24 | "}" return '}';
25 | "[" return '[';
26 | "]" return ']';
27 | "^" return '^';
28 | "*" return '*';
29 | "/" return '/';
30 | "+" return '+';
31 | "-" return '-';
32 | "(" return '(';
33 | ")" return ')';
34 | "," return ',';
35 | "x" return 'XSHIFT';
36 | "y" return 'YSHIFT';
37 | "z" return 'ZSHIFT';
38 | "rx" return 'ROTATEX';
39 | "ry" return 'ROTATEY';
40 | "rz" return 'ROTATEZ';
41 | "fx" return 'FX';
42 | "fy" return 'FY';
43 | "fz" return 'FZ';
44 | "s" return 'SIZE';
45 | "m" return 'MATRIX';
46 | "matrix" return 'MATRIX';
47 | "hue" return 'HUE';
48 | "h" return 'HUE';
49 | "saturation" return 'SATURATION';
50 | "sat" return 'SATURATION';
51 | "brightness" return 'BRIGHTNESS';
52 | "b" return 'BRIGHTNESS';
53 | "alpha" return 'ALPHA';
54 | "a" return 'ALPHA';
55 | "color" return 'COLOR';
56 | "random" return 'RANDOM';
57 | "blend" return 'BLEND';
58 | "randomhue" return 'RANDOMHUE';
59 | "randomrgb" return 'RANDOMRGB';
60 | "greyscale" return 'GREYSCALE';
61 | <> return 'EOF';
62 | [0-9]+("."[0-9]*)? return 'NUMBER';
63 | "."[0-9]+ return 'NUMBER';
64 | "list:"[\w,#]+ return 'COLORLIST';
65 | "image:"[\w\.\w]+ return 'IMAGE';
66 | "box" return 'BOX';
67 | "grid" return 'GRID';
68 | "sphere" return 'SPHERE';
69 | "line" return 'LINE';
70 | "point" return 'POINT';
71 | "triangle" return 'TRIANGLE';
72 | "mesh" return 'MESH';
73 | "cylinder" return 'CYLINDER';
74 | "tube" return 'TUBE';
75 | "squash" return 'SQUASH';
76 | [a-zA-Z_]+[a-zA-Z0-9_]* return 'STRING';
77 | "#define" return 'DEFINE';
78 | "#"[a-fA-F0-9]{6} return 'COLOR6';
79 | "#"[a-fA-F0-9]{3} return 'COLOR3';
80 | (aliceblue|antiquewhite|aqua|aquamarine|azure|beige|bisque|black|blanchedalmond|blue|blueviolet|brown|burlywood|cadetblue|chartreuse|chocolate|coral|cornflowerblue|cornsilk|crimson|cyan|darkblue|darkcyan|darkgoldenrod|darkgray|darkgrey|darkgreen|darkkhaki|darkmagenta|darkolivegreen|darkorange|darkorchid|darkred|darksalmon|darkseagreen|darkslateblue|darkslategray|darkslategrey|darkturquoise|darkviolet|deeppink|deepskyblue|dimgray|dimgrey|dodgerblue|firebrick|floralwhite|forestgreen|fuchsia|gainsboro|ghostwhite|gold|goldenrod|gray|grey|green|greenyellow|honeydew|hotpink|indianred|indigo|ivory|khaki|lavender|lavenderblush|lawngreen|lemonchiffon|lightblue|lightcoral|lightcyan|lightgoldenrodyellow|lightgray|lightgrey|lightgreen|lightpink|lightsalmon|lightseagreen|lightskyblue|lightslategray|lightslategrey|lightsteelblue|lightyellow|lime|limegreen|linen|magenta|maroon|mediumaquamarine|mediumblue|mediumorchid|mediumpurple|mediumseagreen|mediumslateblue|mediumspringgreen|mediumturquoise|mediumvioletred|midnightblue|mintcream|mistyrose|moccasin|navajowhite|navy|oldlace|olive|olivedrab|orange|orangered|orchid|palegoldenrod|palegreen|paleturquoise|palevioletred|papayawhip|peachpuff|peru|pink|plum|powderblue|purple|rebeccapurple|red|rosybrown|royalblue|saddlebrown|salmon|sandybrown|seagreen|seashell|sienna|silver|skyblue|slateblue|slategray|slategrey|snow|springgreen|steelblue|tan|teal|thistle|tomato|turquoise|violet|wheat|white|whitesmoke|yellow|yellowgreen) return 'COLORNAME';
81 | (ALICEBLUE|ANTIQUEWHITE|AQUA|AQUAMARINE|AZURE|BEIGE|BISQUE|BLACK|BLANCHEDALMOND|BLUE|BLUEVIOLET|BROWN|BURLYWOOD|CADETBLUE|CHARTREUSE|CHOCOLATE|CORAL|CORNFLOWERBLUE|CORNSILK|CRIMSON|CYAN|DARKBLUE|DARKCYAN|DARKGOLDENROD|DARKGRAY|DARKGREY|DARKGREEN|DARKKHAKI|DARKMAGENTA|DARKOLIVEGREEN|DARKORANGE|DARKORCHID|DARKRED|DARKSALMON|DARKSEAGREEN|DARKSLATEBLUE|DARKSLATEGRAY|DARKSLATEGREY|DARKTURQUOISE|DARKVIOLET|DEEPPINK|DEEPSKYBLUE|DIMGRAY|DIMGREY|DODGERBLUE|FIREBRICK|FLORALWHITE|FORESTGREEN|FUCHSIA|GAINSBORO|GHOSTWHITE|GOLD|GOLDENROD|GRAY|GREY|GREEN|GREENYELLOW|HONEYDEW|HOTPINK|INDIANRED|INDIGO|IVORY|KHAKI|LAVENDER|LAVENDERBLUSH|LAWNGREEN|LEMONCHIFFON|LIGHTBLUE|LIGHTCORAL|LIGHTCYAN|LIGHTGOLDENRODYELLOW|LIGHTGRAY|LIGHTGREY|LIGHTGREEN|LIGHTPINK|LIGHTSALMON|LIGHTSEAGREEN|LIGHTSKYBLUE|LIGHTSLATEGRAY|LIGHTSLATEGREY|LIGHTSTEELBLUE|LIGHTYELLOW|LIME|LIMEGREEN|LINEN|MAGENTA|MAROON|MEDIUMAQUAMARINE|MEDIUMBLUE|MEDIUMORCHID|MEDIUMPURPLE|MEDIUMSEAGREEN|MEDIUMSLATEBLUE|MEDIUMSPRINGGREEN|MEDIUMTURQUOISE|MEDIUMVIOLETRED|MIDNIGHTBLUE|MINTCREAM|MISTYROSE|MOCCASIN|NAVAJOWHITE|NAVY|OLDLACE|OLIVE|OLIVEDRAB|ORANGE|ORANGERED|ORCHID|PALEGOLDENROD|PALEGREEN|PALETURQUOISE|PALEVIOLETRED|PAPAYAWHIP|PEACHPUFF|PERU|PINK|PLUM|POWDERBLUE|PURPLE|REBECCAPURPLE|RED|ROSYBROWN|ROYALBLUE|SADDLEBROWN|SALMON|SANDYBROWN|SEAGREEN|SEASHELL|SIENNA|SILVER|SKYBLUE|SLATEBLUE|SLATEGRAY|SLATEGREY|SNOW|SPRINGGREEN|STEELBLUE|TAN|TEAL|THISTLE|TOMATO|TURQUOISE|VIOLET|WHEAT|WHITE|WHITESMOKE|YELLOW|YELLOWGREEN) return 'COLORNAME';
82 | ";" return 'COORD_DELIMITER'
83 |
84 | /lex
85 |
86 | %left '+' '-'
87 | %left '*' '/'
88 | %left '^'
89 | %left NEG POS
90 |
91 |
92 | ////////////////////////////////////////////////////
93 | // EISENSCRIPT
94 | ////////////////////////////////////////////////////
95 |
96 | %start eisenscript
97 |
98 | %% /* language grammar */
99 |
100 | eisenscript
101 | : lines EOF { $$ = $1; return $$; }
102 | ;
103 |
104 | lines
105 | : lines line { $$ = $1; $$.push($2); }
106 | | { $$ = []; }
107 | ;
108 |
109 | line
110 | : maxdepth { $$ = $1; }
111 | | maxobjects { $$ = $1; }
112 | | minsize { $$ = $1; }
113 | | maxsize { $$ = $1; }
114 | | seed { $$ = $1; }
115 | | background { $$ = $1; }
116 | | color { $$ = $1; }
117 | | colorpool { $$ = $1; }
118 | | define { $$ = $1; }
119 | | rule { $$ = $1; }
120 | | statement { $$ = $1; $1.computed = true; }
121 | ;
122 |
123 |
124 | ////////////////////////////////////////////////////
125 | // ACTION
126 | ////////////////////////////////////////////////////
127 |
128 | maxdepth
129 | : SET MAXDEPTH num { $$ = { type: 'set', key: 'maxdepth', value: $3 }; }
130 | ;
131 |
132 | maxobjects
133 | : SET MAXOBJECTS num { $$ = { type: 'set', key: 'maxobjects', value: $3 }; }
134 | ;
135 |
136 | minsize
137 | : SET MINSIZE num { $$ = { type: 'set', key: 'minsize', value: $3 }; }
138 | ;
139 |
140 | maxsize
141 | : SET MAXSIZE num { $$ = { type: 'set', key: 'maxsize', value: $3 }; }
142 | ;
143 |
144 | seed
145 | : SET SEED num { $$ = { type: 'set', key: 'seed', value: $3 }; }
146 | | SET SEED INITIAL { $$ = { type: 'set', key: 'seed', value: $3 }; }
147 | ;
148 |
149 | background
150 | : SET BACKGROUND COLOR3 { $$ = { type: 'set', key: 'background', value: $3.toLowerCase() }; }
151 | | SET BACKGROUND COLOR6 { $$ = { type: 'set', key: 'background', value: $3.toLowerCase() }; }
152 | | SET BACKGROUND COLORNAME { $$ = { type: 'set', key: 'background', value: $3.toLowerCase() }; }
153 | | SET BACKGROUND STRING { $$ = { type: 'set', key: 'background', value: $3.toLowerCase() }; }
154 | | SET BACKGROUND RANDOM { $$ = { type: 'set', key: 'background', value: $3.toLowerCase() }; }
155 | ;
156 |
157 | color
158 | : SET COLOR RANDOM { $$ = { type: 'set', key: 'color', value: $3.toLowerCase() }; }
159 | ;
160 |
161 | colorpool
162 | : SET COLORPOOL RANDOMHUE { $$ = { type: 'set', key: 'colorpool', value: $3.toLowerCase() }; }
163 | | SET COLORPOOL RANDOMRGB { $$ = { type: 'set', key: 'colorpool', value: $3.toLowerCase() }; }
164 | | SET COLORPOOL GREYSCALE { $$ = { type: 'set', key: 'colorpool', value: $3.toLowerCase() }; }
165 | | SET COLORPOOL COLORLIST { $$ = { type: 'set', key: 'colorpool', value: $3.toLowerCase() }; }
166 | | SET COLORPOOL IMAGE { $$ = { type: 'set', key: 'colorpool', value: $3.toLowerCase() }; }
167 | ;
168 |
169 | define
170 | : DEFINE STRING num { $$ = { type: 'define', varname: $2, value: $3 }; }
171 | | DEFINE STRING COLOR3 { $$ = { type: 'define', varname: $2, value: $3 }; }
172 | | DEFINE STRING COLOR6 { $$ = { type: 'define', varname: $2, value: $3 }; }
173 | | DEFINE STRING COLORNAME { $$ = { type: 'define', varname: $2, value: $3 }; }
174 | ;
175 |
176 | ////////////////////////////////////////////////////
177 | // RULE
178 | ////////////////////////////////////////////////////
179 |
180 | rule
181 | : RULE id modifiers '{' statements '}' { $$ = { type: 'rule', id: $2, params: $3, body: $5 }; }
182 | ;
183 |
184 | modifiers
185 | : modifiers modifier { $$ = $1; $$.push($2); }
186 | | { $$ = []; }
187 | ;
188 |
189 | modifier
190 | : WEIGHT num { $$ = { type: 'modifier', key: 'weight', value: $2 }; }
191 | | MAXDEPTH num { $$ = { type: 'modifier', key: 'maxdepth', value: $2 }; }
192 | | MAXDEPTH num '>' rulename { $$ = { type: 'modifier', key: 'maxdepth', value: $2, alternate: $4}; }
193 | | MAXDEPTH STRING { $$ = { type: 'modifier', key: 'maxdepth', value: $2, defined: true }; }
194 | | MAXDEPTH STRING '>' rulename { $$ = { type: 'modifier', key: 'maxdepth', value: $2, alternate: $4, defined: true}; }
195 | ;
196 |
197 | statements
198 | : statements statement { $$ = $1; $$.push($2); }
199 | | { $$ = []; }
200 | ;
201 |
202 | statement
203 | : expressions primitive { $$ = { type: 'primitive', id: $2, exprs: $1 }; }
204 | | expressions TRIANGLE '[' coords ']' { $$ = { type: 'primitive', coords: $4, id: $2, exprs: $1 }; }
205 | | expressions id { $$ = { type: 'statement', id: $2, exprs: $1 }; }
206 | ;
207 |
208 | expressions
209 | : expressions expression { $$ = $1; $$.push($2); }
210 | | { $$ = []; }
211 | ;
212 |
213 | expression
214 | : object { $$ = { type: 'expr', left: 1, right: $1 }; }
215 | | n '*' object { $$ = { type: 'expr', left: $1, right: $3 }; }
216 | | STRING '*' object { $$ = { type: 'expr', left: $1, right: $3 }; }
217 | ;
218 |
219 | object
220 | : '{' properties '}' { $$ = { type: 'object', properties: $2 }; }
221 | ;
222 |
223 | coords
224 | : coords COORD_DELIMITER coord { $$ = $1; $$.push($3); }
225 | | coords coord { $$ = $1; $$.push($2); }
226 | | { $$ = []; }
227 | ;
228 |
229 | coord
230 | : coord_point ',' coord_point ',' coord_point { $$ = [$1, $3, $5]; }
231 | ;
232 |
233 | coord_point
234 | : n
235 | | '+' n { $$ = $2; }
236 | | '-' n { $$ = -$2; }
237 | ;
238 |
239 | properties
240 | : properties property { type: 'property', $$ = $1; $$.push($2); }
241 | | { $$ = []; }
242 | ;
243 |
244 | property
245 | : geo
246 | | color
247 | ;
248 |
249 |
250 | ////////////////////////////////////////////////////
251 | // ATTRIBUTE
252 | ////////////////////////////////////////////////////
253 |
254 | geo
255 | : XSHIFT num { $$ = { type: 'property', key: 'xshift', value: $2 }; }
256 | | YSHIFT num { $$ = { type: 'property', key: 'yshift', value: $2 }; }
257 | | ZSHIFT num { $$ = { type: 'property', key: 'zshift', value: $2 }; }
258 | | ROTATEX num { $$ = { type: 'property', key: 'rotatex', value: $2 }; }
259 | | ROTATEY num { $$ = { type: 'property', key: 'rotatey', value: $2 }; }
260 | | ROTATEZ num { $$ = { type: 'property', key: 'rotatez', value: $2 }; }
261 | | SIZE num { $$ = { type: 'property', key: 'size', value: { x: $2, y: $2, z: $2 } }; }
262 | | SIZE num num num { $$ = { type: 'property', key: 'size', value: { x: $2, y: $3, z: $4 } }; }
263 | | MATRIX num num num num num num num num num { $$ = { type: 'property', key: 'matrix', value: [$2, $3, $4, $5, $6, $7, $8, $9, $10] }; }
264 | | XSHIFT STRING { $$ = { type: 'property', key: 'xshift', value: $2, defined: true }; }
265 | | YSHIFT STRING { $$ = { type: 'property', key: 'yshift', value: $2, defined: true }; }
266 | | ZSHIFT STRING { $$ = { type: 'property', key: 'zshift', value: $2, defined: true }; }
267 | | ROTATEX STRING { $$ = { type: 'property', key: 'rotatex', value: $2, defined: true }; }
268 | | ROTATEY STRING { $$ = { type: 'property', key: 'rotatey', value: $2, defined: true }; }
269 | | ROTATEZ STRING { $$ = { type: 'property', key: 'rotatez', value: $2, defined: true }; }
270 | | FX { $$ = { type: 'property', key: 'fx' }; }
271 | | FY { $$ = { type: 'property', key: 'fy' }; }
272 | | FZ { $$ = { type: 'property', key: 'fz' }; }
273 | | SIZE STRING { $$ = { type: 'property', key: 'size', value: { x: $2, y: $2, z: $2 }, defined: true }; }
274 | | SIZE STRING STRING STRING { $$ = { type: 'property', key: 'size', value: { x: $2, y: $3, z: $4 }, defined: true }; }
275 | | MATRIX STRING STRING STRING STRING STRING STRING STRING STRING STRING { $$ = { type: 'property', key: 'matrix', value: [$2, $3, $4, $5, $6, $7, $8, $9, $10], defined: true }; }
276 | ;
277 |
278 | color
279 | : HUE num { $$ = { type: 'property', key: 'hue', value: $2 }; }
280 | | HUE STRING { $$ = { type: 'property', key: 'hue', value: $2, defined: true }; }
281 | | ALPHA num { $$ = { type: 'property', key: 'alpha', value: $2 }; }
282 | | ALPHA STRING { $$ = { type: 'property', key: 'alpha', value: $2, defined: true }; }
283 | | COLOR COLOR3 { $$ = { type: 'property', key: 'color', value: $2.toLowerCase() }; }
284 | | COLOR COLOR6 { $$ = { type: 'property', key: 'color', value: $2.toLowerCase() }; }
285 | | COLOR RANDOM { $$ = { type: 'property', key: 'color', value: $2.toLowerCase() }; }
286 | | COLOR COLORNAME { $$ = { type: 'property', key: 'color', value: $2.toLowerCase() }; }
287 | | COLOR STRING { $$ = { type: 'property', key: 'color', value: $2.toLowerCase(), defined: true }; }
288 | | BLEND COLOR3 num { $$ = { type: 'property', key: 'blend', color: $2.toLowerCase(), strength: $3 }; }
289 | | BLEND COLOR6 num { $$ = { type: 'property', key: 'blend', color: $2.toLowerCase(), strength: $3 }; }
290 | | BLEND COLORNAME num { $$ = { type: 'property', key: 'blend', color: $2.toLowerCase(), strength: $3 }; }
291 | | BLEND RANDOM num { $$ = { type: 'property', key: 'blend', color: $2.toLowerCase(), strength: $3 }; }
292 | | BLEND STRING num { $$ = { type: 'property', key: 'blend', color: $2.toLowerCase(), strength: $3 }; }
293 | // TODO: make BLEND possible to use defined varname.
294 | | SATURATION num { $$ = { type: 'property', key: 'saturation', value: $2 }; }
295 | | SATURATION STRING { $$ = { type: 'property', key: 'saturation', value: $2, defined: true }; }
296 | | BRIGHTNESS num { $$ = { type: 'property', key: 'brightness', value: $2 }; }
297 | | BRIGHTNESS STRING { $$ = { type: 'property', key: 'brightness', value: $2, defined: true }; }
298 | ;
299 |
300 |
301 | ////////////////////////////////////////////////////
302 | // LITERAL
303 | ////////////////////////////////////////////////////
304 |
305 | num
306 | : n
307 | | '+' n { $$ = $2; }
308 | | '-' n { $$ = -$2; }
309 | | n '*' n { $$ = $1*$3; }
310 | | n '/' n { $$ = $1/$3; }
311 | | '-' n '*' n { $$ = -$2*$4; }
312 | | '-' n '/' n { $$ = -$2/$4; }
313 | | '(' e ')' { $$ = $2; }
314 | ;
315 |
316 | n
317 | : NUMBER { $$ = parseFloat(yytext); }
318 | ;
319 |
320 | id
321 | : STRING { $$ = yytext; }
322 | ;
323 |
324 | rulename
325 | : STRING {$$ = $1; }
326 | ;
327 |
328 | primitive
329 | : BOX { $$ = yytext; }
330 | | SPHERE { $$ = yytext; }
331 | | GRID { $$ = yytext; }
332 | | LINE { $$ = yytext; }
333 | | POINT { $$ = yytext; }
334 | | TRIANGLE { $$ = yytext; }
335 | | MESH { $$ = yytext; }
336 | | CYLINDER { $$ = yytext; }
337 | | TUBE { $$ = yytext; }
338 | | SQUASH { $$ = yytext; }
339 | ;
340 |
341 |
--------------------------------------------------------------------------------
/src/Interpreter.js:
--------------------------------------------------------------------------------
1 | const Symbol = require('./Symbol');
2 | const Color = require('color-js');
3 | const Matrix4 = require('./Matrix4');
4 | const utils = require('./utils');
5 | const MersenneTwister = require('./mt');
6 | const { degToRad, clamp } = require('./math');
7 | const csscolor = require('./csscolor');
8 | const Primitive = require('./Primitive');
9 |
10 | // module generate object code from ast
11 | module.exports = class Interpreter {
12 | constructor() {
13 | this.name = 'Interpreter';
14 | this.objects = [];
15 | this.define = [];
16 | this.rules = {};
17 | this.computed = [];
18 | this.maxdepth;
19 | this.depth = 0;
20 | this.maxobjects;
21 | this.objectnum = 0;
22 | this.minsize = .2;
23 | this.maxsize = 1.0;
24 | this.seed = 'initial'; // 'initial' represents random color
25 | this.stack = [];
26 | this.curr = {};
27 | this.curr.matrix = new Matrix4();
28 | this.curr.hsv = utils.extend(Color({ hue: 0, saturation: 1, value: 1 }), { computed: false });
29 | this.curr.blend = { color: null, strength: 0 };
30 | this.curr.alpha = 1;
31 | this.colorpool = null;
32 | this.colorscheme = [];
33 | this.mt = new MersenneTwister();
34 | }
35 |
36 | // termination criteria
37 | terminated() {
38 | if (!this.maxobjects && !this.maxdepth) {
39 | if (this.depth >= 1000) {
40 | console.warn('[eisenscript.js] terminated because maximum number of generations reached (1000)');
41 | return true;
42 | }
43 | }
44 | if (this.maxobjects && this.objectnum > this.maxobjects) return true;
45 |
46 | // NOTE: misterious working of structure synth
47 | // set maxdepth 10
48 | // rule R1 { box { x 1 hue 36 rx 10 } R1 } R1
49 | if (this.maxdepth && this.depth > this.maxdepth - 3) return true;
50 | return false;
51 | }
52 |
53 | // stack current transformation state
54 | pushState() {
55 | this.depth++;
56 | this.stack.push({
57 | matrix: this.curr.matrix.clone(),
58 | hsv: this.curr.hsv.clone(),
59 | blend: utils.extend({}, this.curr.blend),
60 | alpha: this.curr.alpha
61 | });
62 | return this;
63 | }
64 |
65 | // pull the parent transformation state
66 | popState() {
67 | if (this.stack.length > 0) {
68 | this.curr = this.stack.pop();
69 | this.depth--;
70 | }
71 | return this;
72 | }
73 |
74 | translate(x, y, z) {
75 | this.curr.matrix.translate({
76 | x: x,
77 | y: y,
78 | z: z
79 | });
80 | return this;
81 | }
82 |
83 | rotateX(angle) {
84 | this.curr.matrix.rotateX(angle);
85 | return this;
86 | }
87 |
88 | rotateY(angle) {
89 | this.curr.matrix.rotateY(angle);
90 | return this;
91 | }
92 |
93 | rotateZ(angle) {
94 | this.curr.matrix.rotateZ(angle);
95 | return this;
96 | }
97 |
98 | scale(x, y, z) {
99 | this.curr.matrix.scale({
100 | x: x,
101 | y: y,
102 | z: z
103 | });
104 | return this;
105 | }
106 |
107 | // make 3x3 rotation matrix to 4x4 matrix
108 | // test: { m 1 0 0 0 .53 -.85 0 .85 .53 } box
109 | matrix(v) {
110 | this.curr.matrix.set(
111 | v[0], v[1], v[2], 0,
112 | v[3], v[4], v[5], 0,
113 | v[6], v[7], v[8], 0,
114 | 0, 0, 0, 1
115 | );
116 | return this;
117 | }
118 |
119 | multiplyMatrices(v) {
120 | this.curr.matrix.multiplyMatrices(this.curr.matrix, new Matrix4(
121 | v[0], v[1], v[2], 0,
122 | v[3], v[4], v[5], 0,
123 | v[6], v[7], v[8], 0,
124 | 0, 0, 0, 1
125 | ));
126 | return this;
127 | }
128 |
129 | randomColor() {
130 | // if colorpool is set, choose from colorset
131 | if (this.colorpool === Symbol.ColorList) {
132 | if (this.colorscheme.length > 0) {
133 | const idx = Math.floor(this.mt.next() * this.colorpool.length);
134 | return this.colorscheme[idx];
135 | }
136 | }
137 | else if (this.colorpool === Symbol.ColorGreyscale) {
138 | // random r=g=b
139 | const r = this.mt.next() * 255;
140 | return `#${utils.rgb2hex(r, r, r)}`;
141 | }
142 | else if (this.colorpool === Symbol.ColorRandomhue) {
143 | const h = Math.floor(this.mt.next() * 360);
144 | const rgb = utils.hsv2rgb(h, 1, 1);
145 | return `#${utils.rgb2hex(rgb[0], rgb[1], rgb[2])}`;
146 | }
147 | else if (this.colorpool === Symbol.ColorRandomrgb) {
148 | const rgb = [
149 | this.mt.next() * 255,
150 | this.mt.next() * 255,
151 | this.mt.next() * 255
152 | ];
153 | return `#${utils.rgb2hex(rgb[0], rgb[1], rgb[2])}`;
154 | }
155 | const rand = this.mt.next() * 0xffffff;
156 | const color = Math.floor(rand).toString(16);
157 | return `#${color}`;
158 | }
159 |
160 | setColor(color) {
161 | this.curr.hsv = Color(color === 'random' ? this.randomColor() : color).toHSV();
162 | return this;
163 | }
164 |
165 | setHue(v) {
166 | this.curr.hsv.computed = true;
167 | this.curr.hsv.hue += v % 360;
168 | return this;
169 | }
170 |
171 | setSaturation(v) {
172 | this.curr.hsv.computed = true;
173 | const sat = this.curr.hsv.saturation;
174 | if (0 > sat * v || sat * v > 1) console.warn('[eisenscript.js] Saturation is measured from 0 to 1 and is clamped to this interval (i.e. values larger then 1 are set to 1.');
175 | this.curr.hsv.saturation = clamp(sat * v, 0, 1);
176 | return this;
177 | }
178 |
179 | setBrightness(v) {
180 | this.curr.hsv.computed = true;
181 | const brightness = this.curr.hsv.value;
182 | if (0 > brightness * v || brightness * v > 1) console.warn('[eisenscript.js] Brightness is measured from 0 to 1 and is clamped to this interval.');
183 | this.curr.hsv.value = clamp(brightness * v, 0, 1);
184 | return this;
185 | }
186 |
187 | setBlend(color, strength) {
188 | this.curr.blend.color = color;
189 | this.curr.blend.strength = this.curr.blend.strength + clamp(strength, 0, 1) / 2;
190 | // blend the current color with the specified color
191 | this.curr.hsv = this.curr.hsv.blend(
192 | Color(this.curr.blend.color === 'random' ? this.randomColor() : this.curr.blend.color).toHSV(),
193 | this.curr.blend.strength
194 | );
195 | return this;
196 | }
197 |
198 | setAlpha(v) {
199 | const alpha = this.curr.alpha;
200 | if (0 > alpha * v || alpha * v > 1) console.warn('[eisenscript.js] Alpha is measured from 0 to 1 and is clamped to this interval.');
201 | this.curr.alpha = clamp(this.curr.alpha * v, 0, 1);
202 | return this;
203 | }
204 |
205 | resolveVarname(symbol) {
206 | for (let i = 0; i < this.define.length; i++) {
207 | const statement = this.define[i];
208 | switch (statement.type) {
209 | case Symbol.Define:
210 | if (statement.varname === symbol) {
211 | return statement.value;
212 | }
213 | }
214 | }
215 | if (csscolor[symbol]) {
216 | return csscolor[symbol];
217 | }
218 | throw new Error(`Invalid symbol found: ${symbol}`);
219 | }
220 |
221 | // execute eisenscript
222 | generate(ast) {
223 | const that = this;
224 |
225 | // pull the defines
226 | ast.forEach(function(statement) {
227 | switch (statement.type) {
228 | case Symbol.Define: that.define.push(statement); break;
229 | case Symbol.Set: that.define.push(statement); break;
230 | case Symbol.Statement: if (statement.computed) that.computed.push(statement); break;
231 | case Symbol.Primitive: if (statement.computed) that.computed.push(statement); break;
232 | }
233 | });
234 |
235 | // creating intermediate code...
236 | // promise
237 | this.define.forEach(function(statement) {
238 | switch (statement.type) {
239 | case Symbol.Set:
240 | switch (statement.key) {
241 | case Symbol.Maxdepth: that.maxdepth = statement.value; break;
242 | case Symbol.Maxobjects: that.maxobjects = statement.value; break;
243 | case Symbol.Minsize:
244 | console.warn('[eisenscript.js] \'set minsize\' not implement yet');
245 | // that.minsize = statement.value;
246 | break;
247 | case Symbol.Maxsize:
248 | console.warn('[eisenscript.js] \'set maxsize\' not implement yet');
249 | // that.maxsize = statement.value;
250 | break;
251 | case Symbol.Seed: that.seed = statement.value; break;
252 | case Symbol.ColorPool:
253 | // colorpool
254 | const m = statement.value.match(/^list:(.*)/);
255 | if (m) {
256 | that.colorpool = Symbol.ColorList;
257 | that.colorscheme = m[1].split(',').map(color => color.trim());
258 | break;
259 | }
260 | if (statement.value === Symbol.ColorGreyscale
261 | || statement.value === Symbol.ColorRandomhue
262 | || statement.value === Symbol.ColorRandomrgb) {
263 | that.colorpool = statement.value;
264 | break;
265 | }
266 | break;
267 | }
268 | break;
269 | }
270 | });
271 |
272 | // rewriting ast
273 | ast.forEach(function(statement) {
274 | switch (statement.type) {
275 | case Symbol.Rule: that.rewriteRule(statement); break;
276 | }
277 | });
278 |
279 | // if 'initial' is set, set random to seed
280 | // @see https://sourceforge.net/p/structuresynth/news/
281 | if (this.seed === 'initial') {
282 | this.mt.setSeed(Math.floor(Math.random() * Number.MAX_SAFE_INTEGER));
283 | } else {
284 | this.mt.setSeed(this.seed);
285 | }
286 |
287 | // pull the statement of system environment
288 | this.define.forEach(function(statement) {
289 | switch (statement.type) {
290 | case Symbol.Set:
291 | if (statement.key === Symbol.Background) that.generateBackground(statement);
292 | break;
293 | }
294 | });
295 |
296 | // execute main
297 | this.parseStatements(this.computed);
298 |
299 | // return the intermediate code
300 | return {
301 | maxdepth: this.maxdepth,
302 | maxobjects: this.maxobjects,
303 | minsize: this.minsize,
304 | maxsize: this.maxsize,
305 | seed: this.seed,
306 | objects: this.objects,
307 | num: this.objects.length
308 | };
309 | }
310 |
311 | // rewrite subtree related to rule statement
312 | rewriteRule(rule) {
313 | const that = this;
314 | rule.params.forEach(function(param) {
315 | if (param.type === Symbol.Modifier) {
316 | switch (param.key) {
317 | case Symbol.Weight: rule.weight = param.value; break;
318 | case Symbol.Maxdepth:
319 | rule.maxdepth = param.defined ? +that.resolveVarname(param.value) : param.value;
320 | rule.alternate = param.alternate;
321 | break;
322 | }
323 | }
324 | });
325 | if (!this.rules[rule.id]) this.rules[rule.id] = [];
326 | this.rules[rule.id].push(rule);
327 | return this;
328 | }
329 |
330 | // execute statements
331 | parseStatements(statements) {
332 | let i = 0, len = statements.length;
333 | while (i < len) {
334 | if (this.terminated()) break;
335 | this.parseStatement(statements[i], 0);
336 | i++;
337 | }
338 | return this;
339 | }
340 |
341 | // execute a statement
342 | parseStatement(statement, index) {
343 | // parse transformation expression
344 | const expr = statement.exprs[index];
345 | if (expr) {
346 | this.pushState();
347 | let iterations = (typeof expr.left === 'number') ? expr.left : +this.resolveVarname(expr.left);
348 | for (let i = 0; i < iterations; i++) {
349 | if (this.terminated()) break;
350 | this.parseTransformStatement(expr.right);
351 | // if statement.exprs[index + 1] is undefined, it would break the transformation loops.
352 | this.parseStatement(statement, index + 1);
353 | }
354 | this.popState();
355 | return this;
356 | }
357 |
358 | // if not primitive, call rule and parse next transformation loops
359 | if (statement.type === 'statement') {
360 | this.rules[statement.id].depth = (this.rules[statement.id].depth || 0) + 1;
361 | let rule = this.sampling(statement.id);
362 | if (typeof rule === 'string') {
363 | const name = rule;
364 | this.rules[name].depth = (this.rules[name].depth || 0) + 1;
365 | rule = this.sampling(name);
366 | this.parseStatements(rule.body);
367 | this.rules[name].depth--;
368 | } else if (rule) {
369 | this.parseStatements(rule.body);
370 | }
371 | this.rules[statement.id].depth--;
372 | return this;
373 | }
374 |
375 | // achieve the end of nested transformation loops
376 | if (statement.type === 'primitive') {
377 | this.generatePrimitive(statement);
378 | return this
379 | }
380 |
381 | console.warn(`[eisenscript.js] Invalid statement found: ${JSON.stringify(statement)}`);
382 | return this;
383 | }
384 |
385 | // break down transformation set
386 | parseTransformStatement(transform) {
387 | let i = 0, len = transform.properties.length;
388 | while (i < len) {
389 | this.parseTransform(transform.properties[i]);
390 | i++;
391 | }
392 | return this;
393 | }
394 |
395 | // parse transformation property
396 | parseTransform(property) {
397 | const r = (p) => p.defined ? this.resolveVarname(p.value) : p.value;
398 | const p = property;
399 | const v = property.value;
400 | switch (property.key) {
401 | case Symbol.XShift: this.translate(r(p), 0, 0); break;
402 | case Symbol.YShift: this.translate(0, r(p), 0); break;
403 | case Symbol.ZShift: this.translate(0, 0, r(p)); break;
404 | case Symbol.RotateX: this.rotateX(degToRad(r(p))); break;
405 | case Symbol.RotateY: this.rotateY(degToRad(r(p))); break;
406 | case Symbol.RotateZ: this.rotateZ(degToRad(r(p))); break;
407 | case Symbol.FX: this.multiplyMatrices([-1, 0, 0, 0, 1, 0, 0, 0, 1]); break;
408 | case Symbol.FY: this.multiplyMatrices([1, 0, 0, 0, -1, 0, 0, 0, 1]); break;
409 | case Symbol.FZ: this.multiplyMatrices([1, 0, 0, 0, 1, 0, 0, 0, -1]); break;
410 | case Symbol.Size:
411 | if (p.defined) {
412 | this.scale(+this.resolveVarname(v.x), +this.resolveVarname(v.y), +this.resolveVarname(v.z));
413 | } else {
414 | this.scale(v.x, v.y, v.z);
415 | }
416 | break;
417 | case Symbol.Matrix:
418 | if (p.defined) {
419 | this.matrix(property.value.map(v => this.resolveVarname(v)));
420 | } else {
421 | this.matrix(property.value);
422 | }
423 | break;
424 | case Symbol.Color: this.setColor(r(p)); break;
425 | case Symbol.Hue: this.setHue(r(p)); break;
426 | case Symbol.Saturation: this.setSaturation(r(p)); break;
427 | case Symbol.Brightness: this.setBrightness(r(p)); break;
428 | case Symbol.Blend: this.setBlend(property.color, property.strength); break;
429 | case Symbol.Alpha: this.setAlpha(r(p)); break;
430 | }
431 | return this;
432 | }
433 |
434 | // create primitive object and stack it as intermediate code for renderer
435 | generatePrimitive(statement) {
436 | // if achieved maxobjects
437 | this.objectnum++;
438 | if (this.terminated()) return;
439 |
440 | const object = {
441 | type: Symbol.Primitive,
442 | name: statement.id,
443 | matrix: this.curr.matrix.clone(),
444 | color: this.curr.hsv.toCSS(),
445 | opacity: this.curr.alpha,
446 | depth: this.depth
447 | };
448 |
449 | if (statement.id === Primitive.Triangle) {
450 | if (statement.coords) {
451 | if (statement.coords.length !== 3) {
452 | throw new Error('The coordinates should be 3 points as follows: Triangle[0,0,0;1,0,0;0.5,0.5,0.5]');
453 | }
454 | object.coords = statement.coords;
455 | }
456 | }
457 |
458 | // primitive object
459 | this.objects.push(object);
460 | }
461 |
462 | // create background object code and stack it as intermediate code for renderer
463 | generateBackground(statement) {
464 | if (statement.value === 'random') {
465 | throw new Error('\'background\' expected a valid color identifier: Found: random');
466 | }
467 | this.objects.push({
468 | type: Symbol.Background,
469 | color: statement.value
470 | });
471 | }
472 |
473 | // randomly choose one of the rules according to their weights
474 | sampling(name, retry) {
475 | if (!this.rules[name]) {
476 | throw new Error(
477 | `ReferenceError: '${name}' is not defined. As reported by eisenscript interpreter.`,
478 | `${this.name}.js`
479 | );
480 | }
481 |
482 | // sum weights of each rules
483 | let sum = 0;
484 | this.rules[name].forEach(function(rule) {
485 | rule.weight = rule.weight || 1;
486 | sum += rule.weight;
487 | });
488 |
489 | // choosing...
490 | let rand = this.mt.next() * sum;
491 | let chosen;
492 | for (let i = 0; i < this.rules[name].length; i++) {
493 | const rule = this.rules[name][i];
494 | if (rand - rule.weight > 0) {
495 | rand -= rule.weight
496 | continue;
497 | }
498 | chosen = rule;
499 | break;
500 | }
501 |
502 | // if rule could not be selected, interpreter tries to choose until 3 times
503 | if (!chosen) {
504 | retry = retry || 0;
505 | if (retry < 3) return this.sampling(name, ++retry);
506 | // if achieve max retry count
507 | return false;
508 | }
509 |
510 | // if achieved maxdepth
511 | // NOTE: maybe alternative code
512 | // if (chosen.maxdepth && chosen.maxdepth < this.rules[name].depth) {
513 | // if (chosen.alternate) return chosen.alternate;
514 | // return false
515 | // }
516 | if (chosen.maxdepth && chosen.maxdepth < this.rules[name].depth) {
517 | if (chosen.alternate) return chosen.alternate;
518 | if (this.rules[name].depth >= chosen.maxdepth) return false;
519 | if (this.depth < chosen.maxdepth) return chosen;
520 | return false;
521 | }
522 |
523 | // the rule randomly chosen
524 | return chosen;
525 | }
526 | }
527 |
--------------------------------------------------------------------------------
/test/testset/modifiers/weight/w.es.txt:
--------------------------------------------------------------------------------
1 | /+
2 | set seed 1
3 | 1 * { x 1 } 10 * { y 1 } 10 * { z 1 } oneBox
4 |
5 | rule oneBox w 0.25
6 | {
7 | { color red } box
8 | }
9 |
10 | rule oneBox
11 | {
12 | { color white } box
13 | }
14 | +/
15 | {"minsize":0.2,"maxsize":1,"seed":1,"objects":[{"type":"primitive","name":"box","matrix":{"elements":{"0":1,"1":0,"2":0,"3":0,"4":0,"5":1,"6":0,"7":0,"8":0,"9":0,"10":1,"11":0,"12":1,"13":1,"14":1,"15":1}},"color":"#FFFFFF","opacity":1,"depth":4},{"type":"primitive","name":"box","matrix":{"elements":{"0":1,"1":0,"2":0,"3":0,"4":0,"5":1,"6":0,"7":0,"8":0,"9":0,"10":1,"11":0,"12":1,"13":1,"14":2,"15":1}},"color":"#FFFFFF","opacity":1,"depth":4},{"type":"primitive","name":"box","matrix":{"elements":{"0":1,"1":0,"2":0,"3":0,"4":0,"5":1,"6":0,"7":0,"8":0,"9":0,"10":1,"11":0,"12":1,"13":1,"14":3,"15":1}},"color":"#FF0000","opacity":1,"depth":4},{"type":"primitive","name":"box","matrix":{"elements":{"0":1,"1":0,"2":0,"3":0,"4":0,"5":1,"6":0,"7":0,"8":0,"9":0,"10":1,"11":0,"12":1,"13":1,"14":4,"15":1}},"color":"#FFFFFF","opacity":1,"depth":4},{"type":"primitive","name":"box","matrix":{"elements":{"0":1,"1":0,"2":0,"3":0,"4":0,"5":1,"6":0,"7":0,"8":0,"9":0,"10":1,"11":0,"12":1,"13":1,"14":5,"15":1}},"color":"#FF0000","opacity":1,"depth":4},{"type":"primitive","name":"box","matrix":{"elements":{"0":1,"1":0,"2":0,"3":0,"4":0,"5":1,"6":0,"7":0,"8":0,"9":0,"10":1,"11":0,"12":1,"13":1,"14":6,"15":1}},"color":"#FF0000","opacity":1,"depth":4},{"type":"primitive","name":"box","matrix":{"elements":{"0":1,"1":0,"2":0,"3":0,"4":0,"5":1,"6":0,"7":0,"8":0,"9":0,"10":1,"11":0,"12":1,"13":1,"14":7,"15":1}},"color":"#FF0000","opacity":1,"depth":4},{"type":"primitive","name":"box","matrix":{"elements":{"0":1,"1":0,"2":0,"3":0,"4":0,"5":1,"6":0,"7":0,"8":0,"9":0,"10":1,"11":0,"12":1,"13":1,"14":8,"15":1}},"color":"#FFFFFF","opacity":1,"depth":4},{"type":"primitive","name":"box","matrix":{"elements":{"0":1,"1":0,"2":0,"3":0,"4":0,"5":1,"6":0,"7":0,"8":0,"9":0,"10":1,"11":0,"12":1,"13":1,"14":9,"15":1}},"color":"#FFFFFF","opacity":1,"depth":4},{"type":"primitive","name":"box","matrix":{"elements":{"0":1,"1":0,"2":0,"3":0,"4":0,"5":1,"6":0,"7":0,"8":0,"9":0,"10":1,"11":0,"12":1,"13":1,"14":10,"15":1}},"color":"#FFFFFF","opacity":1,"depth":4},{"type":"primitive","name":"box","matrix":{"elements":{"0":1,"1":0,"2":0,"3":0,"4":0,"5":1,"6":0,"7":0,"8":0,"9":0,"10":1,"11":0,"12":1,"13":2,"14":1,"15":1}},"color":"#FFFFFF","opacity":1,"depth":4},{"type":"primitive","name":"box","matrix":{"elements":{"0":1,"1":0,"2":0,"3":0,"4":0,"5":1,"6":0,"7":0,"8":0,"9":0,"10":1,"11":0,"12":1,"13":2,"14":2,"15":1}},"color":"#FFFFFF","opacity":1,"depth":4},{"type":"primitive","name":"box","matrix":{"elements":{"0":1,"1":0,"2":0,"3":0,"4":0,"5":1,"6":0,"7":0,"8":0,"9":0,"10":1,"11":0,"12":1,"13":2,"14":3,"15":1}},"color":"#FFFFFF","opacity":1,"depth":4},{"type":"primitive","name":"box","matrix":{"elements":{"0":1,"1":0,"2":0,"3":0,"4":0,"5":1,"6":0,"7":0,"8":0,"9":0,"10":1,"11":0,"12":1,"13":2,"14":4,"15":1}},"color":"#FFFFFF","opacity":1,"depth":4},{"type":"primitive","name":"box","matrix":{"elements":{"0":1,"1":0,"2":0,"3":0,"4":0,"5":1,"6":0,"7":0,"8":0,"9":0,"10":1,"11":0,"12":1,"13":2,"14":5,"15":1}},"color":"#FF0000","opacity":1,"depth":4},{"type":"primitive","name":"box","matrix":{"elements":{"0":1,"1":0,"2":0,"3":0,"4":0,"5":1,"6":0,"7":0,"8":0,"9":0,"10":1,"11":0,"12":1,"13":2,"14":6,"15":1}},"color":"#FFFFFF","opacity":1,"depth":4},{"type":"primitive","name":"box","matrix":{"elements":{"0":1,"1":0,"2":0,"3":0,"4":0,"5":1,"6":0,"7":0,"8":0,"9":0,"10":1,"11":0,"12":1,"13":2,"14":7,"15":1}},"color":"#FFFFFF","opacity":1,"depth":4},{"type":"primitive","name":"box","matrix":{"elements":{"0":1,"1":0,"2":0,"3":0,"4":0,"5":1,"6":0,"7":0,"8":0,"9":0,"10":1,"11":0,"12":1,"13":2,"14":8,"15":1}},"color":"#FFFFFF","opacity":1,"depth":4},{"type":"primitive","name":"box","matrix":{"elements":{"0":1,"1":0,"2":0,"3":0,"4":0,"5":1,"6":0,"7":0,"8":0,"9":0,"10":1,"11":0,"12":1,"13":2,"14":9,"15":1}},"color":"#FF0000","opacity":1,"depth":4},{"type":"primitive","name":"box","matrix":{"elements":{"0":1,"1":0,"2":0,"3":0,"4":0,"5":1,"6":0,"7":0,"8":0,"9":0,"10":1,"11":0,"12":1,"13":2,"14":10,"15":1}},"color":"#FF0000","opacity":1,"depth":4},{"type":"primitive","name":"box","matrix":{"elements":{"0":1,"1":0,"2":0,"3":0,"4":0,"5":1,"6":0,"7":0,"8":0,"9":0,"10":1,"11":0,"12":1,"13":3,"14":1,"15":1}},"color":"#FFFFFF","opacity":1,"depth":4},{"type":"primitive","name":"box","matrix":{"elements":{"0":1,"1":0,"2":0,"3":0,"4":0,"5":1,"6":0,"7":0,"8":0,"9":0,"10":1,"11":0,"12":1,"13":3,"14":2,"15":1}},"color":"#FFFFFF","opacity":1,"depth":4},{"type":"primitive","name":"box","matrix":{"elements":{"0":1,"1":0,"2":0,"3":0,"4":0,"5":1,"6":0,"7":0,"8":0,"9":0,"10":1,"11":0,"12":1,"13":3,"14":3,"15":1}},"color":"#FFFFFF","opacity":1,"depth":4},{"type":"primitive","name":"box","matrix":{"elements":{"0":1,"1":0,"2":0,"3":0,"4":0,"5":1,"6":0,"7":0,"8":0,"9":0,"10":1,"11":0,"12":1,"13":3,"14":4,"15":1}},"color":"#FFFFFF","opacity":1,"depth":4},{"type":"primitive","name":"box","matrix":{"elements":{"0":1,"1":0,"2":0,"3":0,"4":0,"5":1,"6":0,"7":0,"8":0,"9":0,"10":1,"11":0,"12":1,"13":3,"14":5,"15":1}},"color":"#FFFFFF","opacity":1,"depth":4},{"type":"primitive","name":"box","matrix":{"elements":{"0":1,"1":0,"2":0,"3":0,"4":0,"5":1,"6":0,"7":0,"8":0,"9":0,"10":1,"11":0,"12":1,"13":3,"14":6,"15":1}},"color":"#FFFFFF","opacity":1,"depth":4},{"type":"primitive","name":"box","matrix":{"elements":{"0":1,"1":0,"2":0,"3":0,"4":0,"5":1,"6":0,"7":0,"8":0,"9":0,"10":1,"11":0,"12":1,"13":3,"14":7,"15":1}},"color":"#FF0000","opacity":1,"depth":4},{"type":"primitive","name":"box","matrix":{"elements":{"0":1,"1":0,"2":0,"3":0,"4":0,"5":1,"6":0,"7":0,"8":0,"9":0,"10":1,"11":0,"12":1,"13":3,"14":8,"15":1}},"color":"#FF0000","opacity":1,"depth":4},{"type":"primitive","name":"box","matrix":{"elements":{"0":1,"1":0,"2":0,"3":0,"4":0,"5":1,"6":0,"7":0,"8":0,"9":0,"10":1,"11":0,"12":1,"13":3,"14":9,"15":1}},"color":"#FF0000","opacity":1,"depth":4},{"type":"primitive","name":"box","matrix":{"elements":{"0":1,"1":0,"2":0,"3":0,"4":0,"5":1,"6":0,"7":0,"8":0,"9":0,"10":1,"11":0,"12":1,"13":3,"14":10,"15":1}},"color":"#FFFFFF","opacity":1,"depth":4},{"type":"primitive","name":"box","matrix":{"elements":{"0":1,"1":0,"2":0,"3":0,"4":0,"5":1,"6":0,"7":0,"8":0,"9":0,"10":1,"11":0,"12":1,"13":4,"14":1,"15":1}},"color":"#FF0000","opacity":1,"depth":4},{"type":"primitive","name":"box","matrix":{"elements":{"0":1,"1":0,"2":0,"3":0,"4":0,"5":1,"6":0,"7":0,"8":0,"9":0,"10":1,"11":0,"12":1,"13":4,"14":2,"15":1}},"color":"#FFFFFF","opacity":1,"depth":4},{"type":"primitive","name":"box","matrix":{"elements":{"0":1,"1":0,"2":0,"3":0,"4":0,"5":1,"6":0,"7":0,"8":0,"9":0,"10":1,"11":0,"12":1,"13":4,"14":3,"15":1}},"color":"#FFFFFF","opacity":1,"depth":4},{"type":"primitive","name":"box","matrix":{"elements":{"0":1,"1":0,"2":0,"3":0,"4":0,"5":1,"6":0,"7":0,"8":0,"9":0,"10":1,"11":0,"12":1,"13":4,"14":4,"15":1}},"color":"#FFFFFF","opacity":1,"depth":4},{"type":"primitive","name":"box","matrix":{"elements":{"0":1,"1":0,"2":0,"3":0,"4":0,"5":1,"6":0,"7":0,"8":0,"9":0,"10":1,"11":0,"12":1,"13":4,"14":5,"15":1}},"color":"#FFFFFF","opacity":1,"depth":4},{"type":"primitive","name":"box","matrix":{"elements":{"0":1,"1":0,"2":0,"3":0,"4":0,"5":1,"6":0,"7":0,"8":0,"9":0,"10":1,"11":0,"12":1,"13":4,"14":6,"15":1}},"color":"#FFFFFF","opacity":1,"depth":4},{"type":"primitive","name":"box","matrix":{"elements":{"0":1,"1":0,"2":0,"3":0,"4":0,"5":1,"6":0,"7":0,"8":0,"9":0,"10":1,"11":0,"12":1,"13":4,"14":7,"15":1}},"color":"#FFFFFF","opacity":1,"depth":4},{"type":"primitive","name":"box","matrix":{"elements":{"0":1,"1":0,"2":0,"3":0,"4":0,"5":1,"6":0,"7":0,"8":0,"9":0,"10":1,"11":0,"12":1,"13":4,"14":8,"15":1}},"color":"#FFFFFF","opacity":1,"depth":4},{"type":"primitive","name":"box","matrix":{"elements":{"0":1,"1":0,"2":0,"3":0,"4":0,"5":1,"6":0,"7":0,"8":0,"9":0,"10":1,"11":0,"12":1,"13":4,"14":9,"15":1}},"color":"#FF0000","opacity":1,"depth":4},{"type":"primitive","name":"box","matrix":{"elements":{"0":1,"1":0,"2":0,"3":0,"4":0,"5":1,"6":0,"7":0,"8":0,"9":0,"10":1,"11":0,"12":1,"13":4,"14":10,"15":1}},"color":"#FFFFFF","opacity":1,"depth":4},{"type":"primitive","name":"box","matrix":{"elements":{"0":1,"1":0,"2":0,"3":0,"4":0,"5":1,"6":0,"7":0,"8":0,"9":0,"10":1,"11":0,"12":1,"13":5,"14":1,"15":1}},"color":"#FFFFFF","opacity":1,"depth":4},{"type":"primitive","name":"box","matrix":{"elements":{"0":1,"1":0,"2":0,"3":0,"4":0,"5":1,"6":0,"7":0,"8":0,"9":0,"10":1,"11":0,"12":1,"13":5,"14":2,"15":1}},"color":"#FFFFFF","opacity":1,"depth":4},{"type":"primitive","name":"box","matrix":{"elements":{"0":1,"1":0,"2":0,"3":0,"4":0,"5":1,"6":0,"7":0,"8":0,"9":0,"10":1,"11":0,"12":1,"13":5,"14":3,"15":1}},"color":"#FFFFFF","opacity":1,"depth":4},{"type":"primitive","name":"box","matrix":{"elements":{"0":1,"1":0,"2":0,"3":0,"4":0,"5":1,"6":0,"7":0,"8":0,"9":0,"10":1,"11":0,"12":1,"13":5,"14":4,"15":1}},"color":"#FFFFFF","opacity":1,"depth":4},{"type":"primitive","name":"box","matrix":{"elements":{"0":1,"1":0,"2":0,"3":0,"4":0,"5":1,"6":0,"7":0,"8":0,"9":0,"10":1,"11":0,"12":1,"13":5,"14":5,"15":1}},"color":"#FF0000","opacity":1,"depth":4},{"type":"primitive","name":"box","matrix":{"elements":{"0":1,"1":0,"2":0,"3":0,"4":0,"5":1,"6":0,"7":0,"8":0,"9":0,"10":1,"11":0,"12":1,"13":5,"14":6,"15":1}},"color":"#FFFFFF","opacity":1,"depth":4},{"type":"primitive","name":"box","matrix":{"elements":{"0":1,"1":0,"2":0,"3":0,"4":0,"5":1,"6":0,"7":0,"8":0,"9":0,"10":1,"11":0,"12":1,"13":5,"14":7,"15":1}},"color":"#FFFFFF","opacity":1,"depth":4},{"type":"primitive","name":"box","matrix":{"elements":{"0":1,"1":0,"2":0,"3":0,"4":0,"5":1,"6":0,"7":0,"8":0,"9":0,"10":1,"11":0,"12":1,"13":5,"14":8,"15":1}},"color":"#FFFFFF","opacity":1,"depth":4},{"type":"primitive","name":"box","matrix":{"elements":{"0":1,"1":0,"2":0,"3":0,"4":0,"5":1,"6":0,"7":0,"8":0,"9":0,"10":1,"11":0,"12":1,"13":5,"14":9,"15":1}},"color":"#FFFFFF","opacity":1,"depth":4},{"type":"primitive","name":"box","matrix":{"elements":{"0":1,"1":0,"2":0,"3":0,"4":0,"5":1,"6":0,"7":0,"8":0,"9":0,"10":1,"11":0,"12":1,"13":5,"14":10,"15":1}},"color":"#FF0000","opacity":1,"depth":4},{"type":"primitive","name":"box","matrix":{"elements":{"0":1,"1":0,"2":0,"3":0,"4":0,"5":1,"6":0,"7":0,"8":0,"9":0,"10":1,"11":0,"12":1,"13":6,"14":1,"15":1}},"color":"#FF0000","opacity":1,"depth":4},{"type":"primitive","name":"box","matrix":{"elements":{"0":1,"1":0,"2":0,"3":0,"4":0,"5":1,"6":0,"7":0,"8":0,"9":0,"10":1,"11":0,"12":1,"13":6,"14":2,"15":1}},"color":"#FFFFFF","opacity":1,"depth":4},{"type":"primitive","name":"box","matrix":{"elements":{"0":1,"1":0,"2":0,"3":0,"4":0,"5":1,"6":0,"7":0,"8":0,"9":0,"10":1,"11":0,"12":1,"13":6,"14":3,"15":1}},"color":"#FFFFFF","opacity":1,"depth":4},{"type":"primitive","name":"box","matrix":{"elements":{"0":1,"1":0,"2":0,"3":0,"4":0,"5":1,"6":0,"7":0,"8":0,"9":0,"10":1,"11":0,"12":1,"13":6,"14":4,"15":1}},"color":"#FFFFFF","opacity":1,"depth":4},{"type":"primitive","name":"box","matrix":{"elements":{"0":1,"1":0,"2":0,"3":0,"4":0,"5":1,"6":0,"7":0,"8":0,"9":0,"10":1,"11":0,"12":1,"13":6,"14":5,"15":1}},"color":"#FFFFFF","opacity":1,"depth":4},{"type":"primitive","name":"box","matrix":{"elements":{"0":1,"1":0,"2":0,"3":0,"4":0,"5":1,"6":0,"7":0,"8":0,"9":0,"10":1,"11":0,"12":1,"13":6,"14":6,"15":1}},"color":"#FF0000","opacity":1,"depth":4},{"type":"primitive","name":"box","matrix":{"elements":{"0":1,"1":0,"2":0,"3":0,"4":0,"5":1,"6":0,"7":0,"8":0,"9":0,"10":1,"11":0,"12":1,"13":6,"14":7,"15":1}},"color":"#FFFFFF","opacity":1,"depth":4},{"type":"primitive","name":"box","matrix":{"elements":{"0":1,"1":0,"2":0,"3":0,"4":0,"5":1,"6":0,"7":0,"8":0,"9":0,"10":1,"11":0,"12":1,"13":6,"14":8,"15":1}},"color":"#FF0000","opacity":1,"depth":4},{"type":"primitive","name":"box","matrix":{"elements":{"0":1,"1":0,"2":0,"3":0,"4":0,"5":1,"6":0,"7":0,"8":0,"9":0,"10":1,"11":0,"12":1,"13":6,"14":9,"15":1}},"color":"#FFFFFF","opacity":1,"depth":4},{"type":"primitive","name":"box","matrix":{"elements":{"0":1,"1":0,"2":0,"3":0,"4":0,"5":1,"6":0,"7":0,"8":0,"9":0,"10":1,"11":0,"12":1,"13":6,"14":10,"15":1}},"color":"#FFFFFF","opacity":1,"depth":4},{"type":"primitive","name":"box","matrix":{"elements":{"0":1,"1":0,"2":0,"3":0,"4":0,"5":1,"6":0,"7":0,"8":0,"9":0,"10":1,"11":0,"12":1,"13":7,"14":1,"15":1}},"color":"#FF0000","opacity":1,"depth":4},{"type":"primitive","name":"box","matrix":{"elements":{"0":1,"1":0,"2":0,"3":0,"4":0,"5":1,"6":0,"7":0,"8":0,"9":0,"10":1,"11":0,"12":1,"13":7,"14":2,"15":1}},"color":"#FFFFFF","opacity":1,"depth":4},{"type":"primitive","name":"box","matrix":{"elements":{"0":1,"1":0,"2":0,"3":0,"4":0,"5":1,"6":0,"7":0,"8":0,"9":0,"10":1,"11":0,"12":1,"13":7,"14":3,"15":1}},"color":"#FFFFFF","opacity":1,"depth":4},{"type":"primitive","name":"box","matrix":{"elements":{"0":1,"1":0,"2":0,"3":0,"4":0,"5":1,"6":0,"7":0,"8":0,"9":0,"10":1,"11":0,"12":1,"13":7,"14":4,"15":1}},"color":"#FFFFFF","opacity":1,"depth":4},{"type":"primitive","name":"box","matrix":{"elements":{"0":1,"1":0,"2":0,"3":0,"4":0,"5":1,"6":0,"7":0,"8":0,"9":0,"10":1,"11":0,"12":1,"13":7,"14":5,"15":1}},"color":"#FF0000","opacity":1,"depth":4},{"type":"primitive","name":"box","matrix":{"elements":{"0":1,"1":0,"2":0,"3":0,"4":0,"5":1,"6":0,"7":0,"8":0,"9":0,"10":1,"11":0,"12":1,"13":7,"14":6,"15":1}},"color":"#FFFFFF","opacity":1,"depth":4},{"type":"primitive","name":"box","matrix":{"elements":{"0":1,"1":0,"2":0,"3":0,"4":0,"5":1,"6":0,"7":0,"8":0,"9":0,"10":1,"11":0,"12":1,"13":7,"14":7,"15":1}},"color":"#FFFFFF","opacity":1,"depth":4},{"type":"primitive","name":"box","matrix":{"elements":{"0":1,"1":0,"2":0,"3":0,"4":0,"5":1,"6":0,"7":0,"8":0,"9":0,"10":1,"11":0,"12":1,"13":7,"14":8,"15":1}},"color":"#FFFFFF","opacity":1,"depth":4},{"type":"primitive","name":"box","matrix":{"elements":{"0":1,"1":0,"2":0,"3":0,"4":0,"5":1,"6":0,"7":0,"8":0,"9":0,"10":1,"11":0,"12":1,"13":7,"14":9,"15":1}},"color":"#FFFFFF","opacity":1,"depth":4},{"type":"primitive","name":"box","matrix":{"elements":{"0":1,"1":0,"2":0,"3":0,"4":0,"5":1,"6":0,"7":0,"8":0,"9":0,"10":1,"11":0,"12":1,"13":7,"14":10,"15":1}},"color":"#FFFFFF","opacity":1,"depth":4},{"type":"primitive","name":"box","matrix":{"elements":{"0":1,"1":0,"2":0,"3":0,"4":0,"5":1,"6":0,"7":0,"8":0,"9":0,"10":1,"11":0,"12":1,"13":8,"14":1,"15":1}},"color":"#FFFFFF","opacity":1,"depth":4},{"type":"primitive","name":"box","matrix":{"elements":{"0":1,"1":0,"2":0,"3":0,"4":0,"5":1,"6":0,"7":0,"8":0,"9":0,"10":1,"11":0,"12":1,"13":8,"14":2,"15":1}},"color":"#FF0000","opacity":1,"depth":4},{"type":"primitive","name":"box","matrix":{"elements":{"0":1,"1":0,"2":0,"3":0,"4":0,"5":1,"6":0,"7":0,"8":0,"9":0,"10":1,"11":0,"12":1,"13":8,"14":3,"15":1}},"color":"#FF0000","opacity":1,"depth":4},{"type":"primitive","name":"box","matrix":{"elements":{"0":1,"1":0,"2":0,"3":0,"4":0,"5":1,"6":0,"7":0,"8":0,"9":0,"10":1,"11":0,"12":1,"13":8,"14":4,"15":1}},"color":"#FFFFFF","opacity":1,"depth":4},{"type":"primitive","name":"box","matrix":{"elements":{"0":1,"1":0,"2":0,"3":0,"4":0,"5":1,"6":0,"7":0,"8":0,"9":0,"10":1,"11":0,"12":1,"13":8,"14":5,"15":1}},"color":"#FFFFFF","opacity":1,"depth":4},{"type":"primitive","name":"box","matrix":{"elements":{"0":1,"1":0,"2":0,"3":0,"4":0,"5":1,"6":0,"7":0,"8":0,"9":0,"10":1,"11":0,"12":1,"13":8,"14":6,"15":1}},"color":"#FF0000","opacity":1,"depth":4},{"type":"primitive","name":"box","matrix":{"elements":{"0":1,"1":0,"2":0,"3":0,"4":0,"5":1,"6":0,"7":0,"8":0,"9":0,"10":1,"11":0,"12":1,"13":8,"14":7,"15":1}},"color":"#FFFFFF","opacity":1,"depth":4},{"type":"primitive","name":"box","matrix":{"elements":{"0":1,"1":0,"2":0,"3":0,"4":0,"5":1,"6":0,"7":0,"8":0,"9":0,"10":1,"11":0,"12":1,"13":8,"14":8,"15":1}},"color":"#FFFFFF","opacity":1,"depth":4},{"type":"primitive","name":"box","matrix":{"elements":{"0":1,"1":0,"2":0,"3":0,"4":0,"5":1,"6":0,"7":0,"8":0,"9":0,"10":1,"11":0,"12":1,"13":8,"14":9,"15":1}},"color":"#FFFFFF","opacity":1,"depth":4},{"type":"primitive","name":"box","matrix":{"elements":{"0":1,"1":0,"2":0,"3":0,"4":0,"5":1,"6":0,"7":0,"8":0,"9":0,"10":1,"11":0,"12":1,"13":8,"14":10,"15":1}},"color":"#FFFFFF","opacity":1,"depth":4},{"type":"primitive","name":"box","matrix":{"elements":{"0":1,"1":0,"2":0,"3":0,"4":0,"5":1,"6":0,"7":0,"8":0,"9":0,"10":1,"11":0,"12":1,"13":9,"14":1,"15":1}},"color":"#FFFFFF","opacity":1,"depth":4},{"type":"primitive","name":"box","matrix":{"elements":{"0":1,"1":0,"2":0,"3":0,"4":0,"5":1,"6":0,"7":0,"8":0,"9":0,"10":1,"11":0,"12":1,"13":9,"14":2,"15":1}},"color":"#FFFFFF","opacity":1,"depth":4},{"type":"primitive","name":"box","matrix":{"elements":{"0":1,"1":0,"2":0,"3":0,"4":0,"5":1,"6":0,"7":0,"8":0,"9":0,"10":1,"11":0,"12":1,"13":9,"14":3,"15":1}},"color":"#FFFFFF","opacity":1,"depth":4},{"type":"primitive","name":"box","matrix":{"elements":{"0":1,"1":0,"2":0,"3":0,"4":0,"5":1,"6":0,"7":0,"8":0,"9":0,"10":1,"11":0,"12":1,"13":9,"14":4,"15":1}},"color":"#FFFFFF","opacity":1,"depth":4},{"type":"primitive","name":"box","matrix":{"elements":{"0":1,"1":0,"2":0,"3":0,"4":0,"5":1,"6":0,"7":0,"8":0,"9":0,"10":1,"11":0,"12":1,"13":9,"14":5,"15":1}},"color":"#FFFFFF","opacity":1,"depth":4},{"type":"primitive","name":"box","matrix":{"elements":{"0":1,"1":0,"2":0,"3":0,"4":0,"5":1,"6":0,"7":0,"8":0,"9":0,"10":1,"11":0,"12":1,"13":9,"14":6,"15":1}},"color":"#FFFFFF","opacity":1,"depth":4},{"type":"primitive","name":"box","matrix":{"elements":{"0":1,"1":0,"2":0,"3":0,"4":0,"5":1,"6":0,"7":0,"8":0,"9":0,"10":1,"11":0,"12":1,"13":9,"14":7,"15":1}},"color":"#FFFFFF","opacity":1,"depth":4},{"type":"primitive","name":"box","matrix":{"elements":{"0":1,"1":0,"2":0,"3":0,"4":0,"5":1,"6":0,"7":0,"8":0,"9":0,"10":1,"11":0,"12":1,"13":9,"14":8,"15":1}},"color":"#FFFFFF","opacity":1,"depth":4},{"type":"primitive","name":"box","matrix":{"elements":{"0":1,"1":0,"2":0,"3":0,"4":0,"5":1,"6":0,"7":0,"8":0,"9":0,"10":1,"11":0,"12":1,"13":9,"14":9,"15":1}},"color":"#FFFFFF","opacity":1,"depth":4},{"type":"primitive","name":"box","matrix":{"elements":{"0":1,"1":0,"2":0,"3":0,"4":0,"5":1,"6":0,"7":0,"8":0,"9":0,"10":1,"11":0,"12":1,"13":9,"14":10,"15":1}},"color":"#FFFFFF","opacity":1,"depth":4},{"type":"primitive","name":"box","matrix":{"elements":{"0":1,"1":0,"2":0,"3":0,"4":0,"5":1,"6":0,"7":0,"8":0,"9":0,"10":1,"11":0,"12":1,"13":10,"14":1,"15":1}},"color":"#FF0000","opacity":1,"depth":4},{"type":"primitive","name":"box","matrix":{"elements":{"0":1,"1":0,"2":0,"3":0,"4":0,"5":1,"6":0,"7":0,"8":0,"9":0,"10":1,"11":0,"12":1,"13":10,"14":2,"15":1}},"color":"#FFFFFF","opacity":1,"depth":4},{"type":"primitive","name":"box","matrix":{"elements":{"0":1,"1":0,"2":0,"3":0,"4":0,"5":1,"6":0,"7":0,"8":0,"9":0,"10":1,"11":0,"12":1,"13":10,"14":3,"15":1}},"color":"#FFFFFF","opacity":1,"depth":4},{"type":"primitive","name":"box","matrix":{"elements":{"0":1,"1":0,"2":0,"3":0,"4":0,"5":1,"6":0,"7":0,"8":0,"9":0,"10":1,"11":0,"12":1,"13":10,"14":4,"15":1}},"color":"#FFFFFF","opacity":1,"depth":4},{"type":"primitive","name":"box","matrix":{"elements":{"0":1,"1":0,"2":0,"3":0,"4":0,"5":1,"6":0,"7":0,"8":0,"9":0,"10":1,"11":0,"12":1,"13":10,"14":5,"15":1}},"color":"#FFFFFF","opacity":1,"depth":4},{"type":"primitive","name":"box","matrix":{"elements":{"0":1,"1":0,"2":0,"3":0,"4":0,"5":1,"6":0,"7":0,"8":0,"9":0,"10":1,"11":0,"12":1,"13":10,"14":6,"15":1}},"color":"#FFFFFF","opacity":1,"depth":4},{"type":"primitive","name":"box","matrix":{"elements":{"0":1,"1":0,"2":0,"3":0,"4":0,"5":1,"6":0,"7":0,"8":0,"9":0,"10":1,"11":0,"12":1,"13":10,"14":7,"15":1}},"color":"#FFFFFF","opacity":1,"depth":4},{"type":"primitive","name":"box","matrix":{"elements":{"0":1,"1":0,"2":0,"3":0,"4":0,"5":1,"6":0,"7":0,"8":0,"9":0,"10":1,"11":0,"12":1,"13":10,"14":8,"15":1}},"color":"#FFFFFF","opacity":1,"depth":4},{"type":"primitive","name":"box","matrix":{"elements":{"0":1,"1":0,"2":0,"3":0,"4":0,"5":1,"6":0,"7":0,"8":0,"9":0,"10":1,"11":0,"12":1,"13":10,"14":9,"15":1}},"color":"#FF0000","opacity":1,"depth":4},{"type":"primitive","name":"box","matrix":{"elements":{"0":1,"1":0,"2":0,"3":0,"4":0,"5":1,"6":0,"7":0,"8":0,"9":0,"10":1,"11":0,"12":1,"13":10,"14":10,"15":1}},"color":"#FFFFFF","opacity":1,"depth":4}],"num":100}
16 |
--------------------------------------------------------------------------------