Skip to content

Commit 524f951

Browse files
authored
Merge pull request #24 from p-otto/cli-tool
Introduce new cli-tool
2 parents 64e2b13 + 74c23fa commit 524f951

31 files changed

+3037
-2
lines changed

README.md

Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,100 @@ ToDo
3232

3333
ToDo
3434

35+
## Tools
36+
37+
### glkernel-cli
38+
39+
The glkernel-cli tool provides a convenient way to generate and manipulate kernels using the command line.
40+
The usage is as follows:
41+
42+
```
43+
glkernel-cli [--force] [--beautify] [--output <outputFileName>] [--format <outputFileFormat>] <inputFileName>
44+
45+
Options:
46+
-b, --beautify Beautify the output (only applies to json output format)
47+
--force Override the output file, if it exists
48+
-f, --format File format for the generated / converted kernel (e.g., json, png, h)
49+
-o, --output File that the generated / converted kernel will be written to (defaults: <inputFileName>.json for generation, <inputFileName>.png for conversion)
50+
```
51+
52+
- The default output format for kernel generation is JSON
53+
- The default output format for kernel conversion is PNG
54+
- If not output file name is given, the output file name will be deduced from the input file name (here, it would be `kernel.json`)
55+
- If no output format is given, the output format will be deduced from the output file name (explicitly given or deduced)
56+
57+
#### Generating a kernel using JavaScript
58+
59+
Kernels can be generated from JavaScript by simply passing a `.js` file as input to the command line tool.
60+
Examples:
61+
62+
```
63+
$ glkernel-cli kernel.js
64+
65+
$ glkernel-cli kernel.js -o random_noise_kernel.json --force --beautify
66+
67+
$ glkernel-cli kernel.js -o sorted_kernel -f png
68+
```
69+
70+
A JavaScript interface (`JSInterface.h`, `JSInterface.cpp`, `glkernel.js`) allows calling glkernel functionality from user scripts.
71+
It is included in the tool's sources (C++ files), and in the `data/` directory (JavaScript file).
72+
The interface is automatically generated from the existing glkernel API.
73+
74+
__If you extend or change the glkernel API, please [re-generate the JavaScript interface](#generating-the-javascript-interface)!__
75+
76+
##### Writing kernel generation instructions in JavaScript
77+
78+
While the glkernel library uses free functions, the JavaScript API provides manipulation of kernels via object methods on kernel objects.
79+
The API method names are taken from the library.
80+
81+
The following script shows the usage of the JavaScript API by example (it can be found in `scripts/kernel.js`):
82+
83+
```javascript
84+
// create new Kernel2 object (i.e., a 3D kernel of dimensions 10x5x2, holding vec2's as values
85+
var kernel = new Kernel2(10, 5, 2);
86+
87+
// translates to glkernel::sequence::uniform(kernel, 0.0, 1.0)
88+
kernel.sequence.uniform(0.0, 1.0);
89+
90+
// examples for other kernel methods
91+
kernel.shuffle.random();
92+
kernel.scale.range(-1.0, 1.0);
93+
94+
// glkernel::sort::distance for a Kernel2 requires a vec2 as parameter
95+
// vec parameters can be passed as JavaScript arrays
96+
kernel.sort.distance([0.0, 0.0]);
97+
```
98+
99+
#### Converting an existing kernel
100+
101+
After generating a kernel in JSON format, that kernel can be read by the tool to be converted into another representation (e.g., PNG).
102+
This is achieved by simply passing a `.json` file as input to the command line tool.
103+
Examples:
104+
105+
```
106+
$ glkernel-cli kernel.json
107+
108+
$ glkernel-cli kernel.json -o sorted_kernel -f png --force
109+
```
110+
111+
If no output file or format is given, the default output format is PNG.
112+
113+
#### Generating the JavaScript interface
114+
115+
The JavaScript interface files can simply be re-generated using the CMake `generate` target, either from your IDE, or from the project's root folder using the following CMake command:
116+
117+
```
118+
$ cmake --build ./build --target generate
119+
```
120+
121+
This requires Python 2 or 3 to be installed on the system.
122+
Alternatively, the Python script can be executed manually (also from the root folder):
123+
124+
__TODO__: update this if the destination of JS and C++ files are different
125+
```
126+
$ python scripts/generate.py -t scripts/templates -d source/tools/glkernel-cli
127+
```
128+
35129
##### glkernel-cmd
36130

37131
Additionally to using glkernel as a library, there is a standalone command line tool to generate kernels from JSON descriptions.

data/glkernel.js

Lines changed: 192 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,192 @@
1+
2+
// THIS IS A GENERATED FILE!
3+
// DO NOT EDIT
4+
5+
GradientNoiseType = {
6+
Perlin: 0,
7+
Simplex: 1
8+
};
9+
10+
HemisphereMapping = {
11+
Uniform: 0,
12+
Cosine: 1
13+
};
14+
15+
OctaveType = {
16+
Standard: 0,
17+
Cloud: 1,
18+
CloudAbs: 2,
19+
Wood: 3,
20+
Paper: 4
21+
};
22+
23+
var _Kernel = function(x,y,z) {
24+
this._initialize = function(x,y,z) {
25+
var that = this;
26+
27+
this.kernel = this.generateKernel(x,y,z);
28+
29+
this.noise = {
30+
uniform: function(range_min, range_max) {
31+
_glkernel.noise_uniform(that.kernel, range_min, range_max);
32+
return that;
33+
},
34+
normal: function(mean, stddev) {
35+
_glkernel.noise_normal(that.kernel, mean, stddev);
36+
return that;
37+
},
38+
gradient: function(noise_type, octave_type, startFrequency, octaves) {
39+
// Defaults
40+
noise_type = (typeof noise_type !== 'undefined') ? noise_type : GradientNoiseType.Perlin;
41+
octave_type = (typeof octave_type !== 'undefined') ? octave_type : OctaveType.Standard;
42+
startFrequency = (typeof startFrequency !== 'undefined') ? startFrequency : 3;
43+
octaves = (typeof octaves !== 'undefined') ? octaves : 5;
44+
45+
_glkernel.noise_gradient(that.kernel, noise_type, octave_type, startFrequency, octaves);
46+
return that;
47+
}
48+
};
49+
this.sample = {
50+
poisson_square: function(num_probes) {
51+
// Defaults
52+
num_probes = (typeof num_probes !== 'undefined') ? num_probes : 32;
53+
54+
_glkernel.sample_poisson_square(that.kernel, num_probes);
55+
return that;
56+
},
57+
poisson_square: function(min_dist, num_probes) {
58+
// Defaults
59+
num_probes = (typeof num_probes !== 'undefined') ? num_probes : 32;
60+
61+
_glkernel.sample_poisson_square1(that.kernel, min_dist, num_probes);
62+
return that;
63+
},
64+
stratified: function() {
65+
_glkernel.sample_stratified(that.kernel);
66+
return that;
67+
},
68+
hammersley: function() {
69+
_glkernel.sample_hammersley(that.kernel);
70+
return that;
71+
},
72+
halton: function(base1, base2) {
73+
_glkernel.sample_halton(that.kernel, base1, base2);
74+
return that;
75+
},
76+
hammersley_sphere: function(type) {
77+
// Defaults
78+
type = (typeof type !== 'undefined') ? type : HemisphereMapping.Uniform;
79+
80+
_glkernel.sample_hammersley_sphere(that.kernel, type);
81+
return that;
82+
},
83+
halton_sphere: function(base1, base2, type) {
84+
// Defaults
85+
type = (typeof type !== 'undefined') ? type : HemisphereMapping.Uniform;
86+
87+
_glkernel.sample_halton_sphere(that.kernel, base1, base2, type);
88+
return that;
89+
},
90+
best_candidate: function(num_candidates) {
91+
// Defaults
92+
num_candidates = (typeof num_candidates !== 'undefined') ? num_candidates : 32;
93+
94+
_glkernel.sample_best_candidate(that.kernel, num_candidates);
95+
return that;
96+
},
97+
n_rooks: function() {
98+
_glkernel.sample_n_rooks(that.kernel);
99+
return that;
100+
},
101+
multi_jittered: function(correlated) {
102+
// Defaults
103+
correlated = (typeof correlated !== 'undefined') ? correlated : false;
104+
105+
_glkernel.sample_multi_jittered(that.kernel, correlated);
106+
return that;
107+
},
108+
golden_point_set: function() {
109+
_glkernel.sample_golden_point_set(that.kernel);
110+
return that;
111+
}
112+
};
113+
this.scale = {
114+
range: function(rangeToLower, rangeToUpper, rangeFromLower, rangeFromUpper) {
115+
// Defaults
116+
rangeFromLower = (typeof rangeFromLower !== 'undefined') ? rangeFromLower : 0;
117+
rangeFromUpper = (typeof rangeFromUpper !== 'undefined') ? rangeFromUpper : 1;
118+
119+
_glkernel.scale_range(that.kernel, rangeToLower, rangeToUpper, rangeFromLower, rangeFromUpper);
120+
return that;
121+
}
122+
};
123+
this.sequence = {
124+
uniform: function(range_min, range_max) {
125+
_glkernel.sequence_uniform(that.kernel, range_min, range_max);
126+
return that;
127+
}
128+
};
129+
this.shuffle = {
130+
bucket_permutate: function(subkernel_width, subkernel_height, subkernel_depth, permutate_per_bucket) {
131+
// Defaults
132+
subkernel_width = (typeof subkernel_width !== 'undefined') ? subkernel_width : 1;
133+
subkernel_height = (typeof subkernel_height !== 'undefined') ? subkernel_height : 1;
134+
subkernel_depth = (typeof subkernel_depth !== 'undefined') ? subkernel_depth : 1;
135+
permutate_per_bucket = (typeof permutate_per_bucket !== 'undefined') ? permutate_per_bucket : false;
136+
137+
_glkernel.shuffle_bucket_permutate(that.kernel, subkernel_width, subkernel_height, subkernel_depth, permutate_per_bucket);
138+
return that;
139+
},
140+
bayer: function() {
141+
_glkernel.shuffle_bayer(that.kernel);
142+
return that;
143+
},
144+
random: function(start) {
145+
// Defaults
146+
start = (typeof start !== 'undefined') ? start : 1;
147+
148+
_glkernel.shuffle_random(that.kernel, start);
149+
return that;
150+
}
151+
};
152+
this.sort = {
153+
distance: function(origin) {
154+
_glkernel.sort_distance(that.kernel, origin);
155+
return that;
156+
}
157+
};
158+
};
159+
};
160+
161+
var Kernel1 = function(x,y,z) {
162+
this.generateKernel = function(x,y,z) {
163+
return _glkernel.createKernel1(x,y,z);
164+
}
165+
this._initialize(x,y,z);
166+
};
167+
168+
var Kernel2 = function(x,y,z) {
169+
this.generateKernel = function(x,y,z) {
170+
return _glkernel.createKernel2(x,y,z);
171+
}
172+
this._initialize(x,y,z);
173+
};
174+
175+
var Kernel3 = function(x,y,z) {
176+
this.generateKernel = function(x,y,z) {
177+
return _glkernel.createKernel3(x,y,z);
178+
}
179+
this._initialize(x,y,z);
180+
};
181+
182+
var Kernel4 = function(x,y,z) {
183+
this.generateKernel = function(x,y,z) {
184+
return _glkernel.createKernel4(x,y,z);
185+
}
186+
this._initialize(x,y,z);
187+
};
188+
189+
Kernel1.prototype = new _Kernel;
190+
Kernel2.prototype = new _Kernel;
191+
Kernel3.prototype = new _Kernel;
192+
Kernel4.prototype = new _Kernel;

0 commit comments

Comments
 (0)