├── .gitignore ├── .npmignore ├── LICENSE ├── assets └── images │ ├── colormaps.png │ ├── double1.png │ ├── double2.png │ ├── favicon.png │ ├── qv_logo.afdesign │ ├── qv_logo_cube.afdesign │ ├── qv_logo_cube.png │ ├── qv_logo_cube_512.png │ ├── qv_logo_horizontal.afdesign │ ├── qv_logo_horizontal.png │ ├── simple.png │ └── test.afdesign ├── data ├── functional.nii.gz └── structural.nii.gz ├── dist ├── quickvoxelcore.es6.js ├── quickvoxelcore.es6.js.map ├── quickvoxelcore.js ├── quickvoxelcore.js.map └── quickvoxelcore.min.js ├── doc ├── assets │ ├── anchor.js │ ├── bass-addons.css │ ├── bass.css │ ├── favicon.png │ ├── fonts │ │ ├── EOT │ │ │ ├── SourceCodePro-Bold.eot │ │ │ └── SourceCodePro-Regular.eot │ │ ├── LICENSE.txt │ │ ├── OTF │ │ │ ├── SourceCodePro-Bold.otf │ │ │ └── SourceCodePro-Regular.otf │ │ ├── TTF │ │ │ ├── SourceCodePro-Bold.ttf │ │ │ └── SourceCodePro-Regular.ttf │ │ ├── WOFF │ │ │ ├── OTF │ │ │ │ ├── SourceCodePro-Bold.otf.woff │ │ │ │ └── SourceCodePro-Regular.otf.woff │ │ │ └── TTF │ │ │ │ ├── SourceCodePro-Bold.ttf.woff │ │ │ │ └── SourceCodePro-Regular.ttf.woff │ │ ├── WOFF2 │ │ │ ├── OTF │ │ │ │ ├── SourceCodePro-Bold.otf.woff2 │ │ │ │ └── SourceCodePro-Regular.otf.woff2 │ │ │ └── TTF │ │ │ │ ├── SourceCodePro-Bold.ttf.woff2 │ │ │ │ └── SourceCodePro-Regular.ttf.woff2 │ │ └── source-code-pro.css │ ├── github.css │ ├── images │ │ ├── colormaps.png │ │ ├── double1.png │ │ ├── double2.png │ │ ├── favicon.png │ │ ├── qv_logo.afdesign │ │ ├── qv_logo_cube.afdesign │ │ ├── qv_logo_cube.png │ │ ├── qv_logo_horizontal.afdesign │ │ ├── qv_logo_horizontal.png │ │ ├── simple.png │ │ └── test.afdesign │ ├── name_1000.png │ ├── site.js │ ├── split.css │ ├── split.js │ └── style.css └── index.html ├── docgen ├── config.yml └── custom_theme │ ├── README.md │ ├── assets │ ├── anchor.js │ ├── bass-addons.css │ ├── bass.css │ ├── favicon.png │ ├── fonts │ │ ├── EOT │ │ │ ├── SourceCodePro-Bold.eot │ │ │ └── SourceCodePro-Regular.eot │ │ ├── LICENSE.txt │ │ ├── OTF │ │ │ ├── SourceCodePro-Bold.otf │ │ │ └── SourceCodePro-Regular.otf │ │ ├── TTF │ │ │ ├── SourceCodePro-Bold.ttf │ │ │ └── SourceCodePro-Regular.ttf │ │ ├── WOFF │ │ │ ├── OTF │ │ │ │ ├── SourceCodePro-Bold.otf.woff │ │ │ │ └── SourceCodePro-Regular.otf.woff │ │ │ └── TTF │ │ │ │ ├── SourceCodePro-Bold.ttf.woff │ │ │ │ └── SourceCodePro-Regular.ttf.woff │ │ ├── WOFF2 │ │ │ ├── OTF │ │ │ │ ├── SourceCodePro-Bold.otf.woff2 │ │ │ │ └── SourceCodePro-Regular.otf.woff2 │ │ │ └── TTF │ │ │ │ ├── SourceCodePro-Bold.ttf.woff2 │ │ │ │ └── SourceCodePro-Regular.ttf.woff2 │ │ └── source-code-pro.css │ ├── github.css │ ├── images │ │ ├── colormaps.png │ │ ├── double1.png │ │ ├── double2.png │ │ ├── favicon.png │ │ ├── qv_logo.afdesign │ │ ├── qv_logo_cube.afdesign │ │ ├── qv_logo_cube.png │ │ ├── qv_logo_horizontal.afdesign │ │ ├── qv_logo_horizontal.png │ │ ├── simple.png │ │ └── test.afdesign │ ├── name_1000.png │ ├── site.js │ ├── split.css │ ├── split.js │ └── style.css │ ├── index._ │ ├── index.js │ ├── note._ │ ├── paramProperty._ │ ├── section._ │ └── section_list._ ├── documentation.md ├── examples ├── _doubleRotateCamCrew.html ├── _simpleCamCrew.html ├── axes.html ├── chosecamera.html ├── colormaps.html ├── css │ └── main.css ├── double.html ├── doubleRotate.html ├── doubleSpinner.html ├── doubleTranslate.html ├── doubleTranslateCameraCrew.html ├── images │ └── lego_spinner.gif ├── js │ └── addsourcelink.js ├── oblique.html ├── oblique2.html ├── simple.html ├── simpleFile.html ├── simpleSpinner.html ├── time.html └── translate.html ├── package-lock.json ├── package.json ├── readme.md ├── rollup.config.dev.js ├── rollup.config.js └── src ├── CameraCrew.js ├── ColormapManager.js ├── EventManager.js ├── QuickvoxelCore.js ├── RenderEngine.js ├── Tools.js ├── Volume.js ├── VolumeCollection.js ├── _info.js ├── constants.js ├── main.js └── shaders ├── worldcoordtexture3d.frag.glsl └── worldcoordtexture3d.vert.glsl /.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | 6 | # Runtime data 7 | pids 8 | *.pid 9 | *.seed 10 | 11 | # Directory for instrumented libs generated by jscoverage/JSCover 12 | lib-cov 13 | 14 | # Coverage directory used by tools like istanbul 15 | coverage 16 | 17 | # nyc test coverage 18 | .nyc_output 19 | 20 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) 21 | .grunt 22 | 23 | # node-waf configuration 24 | .lock-wscript 25 | 26 | # Compiled binary addons (http://nodejs.org/api/addons.html) 27 | build/Release 28 | 29 | # Dependency directories 30 | node_modules 31 | jspm_packages 32 | 33 | # Optional npm cache directory 34 | .npm 35 | 36 | # Optional REPL history 37 | .node_repl_history 38 | 39 | .DS_Store 40 | -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | doc 2 | examples 3 | .DS_Store 4 | data 5 | assets 6 | testdata 7 | docgen 8 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2016 Jonathan Lurie 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 all 13 | 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 THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /assets/images/colormaps.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Pixpipe/quickvoxelcore/88e0bfec82b3bf497cd091dbee2e8284867a440b/assets/images/colormaps.png -------------------------------------------------------------------------------- /assets/images/double1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Pixpipe/quickvoxelcore/88e0bfec82b3bf497cd091dbee2e8284867a440b/assets/images/double1.png -------------------------------------------------------------------------------- /assets/images/double2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Pixpipe/quickvoxelcore/88e0bfec82b3bf497cd091dbee2e8284867a440b/assets/images/double2.png -------------------------------------------------------------------------------- /assets/images/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Pixpipe/quickvoxelcore/88e0bfec82b3bf497cd091dbee2e8284867a440b/assets/images/favicon.png -------------------------------------------------------------------------------- /assets/images/qv_logo.afdesign: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Pixpipe/quickvoxelcore/88e0bfec82b3bf497cd091dbee2e8284867a440b/assets/images/qv_logo.afdesign -------------------------------------------------------------------------------- /assets/images/qv_logo_cube.afdesign: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Pixpipe/quickvoxelcore/88e0bfec82b3bf497cd091dbee2e8284867a440b/assets/images/qv_logo_cube.afdesign -------------------------------------------------------------------------------- /assets/images/qv_logo_cube.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Pixpipe/quickvoxelcore/88e0bfec82b3bf497cd091dbee2e8284867a440b/assets/images/qv_logo_cube.png -------------------------------------------------------------------------------- /assets/images/qv_logo_cube_512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Pixpipe/quickvoxelcore/88e0bfec82b3bf497cd091dbee2e8284867a440b/assets/images/qv_logo_cube_512.png -------------------------------------------------------------------------------- /assets/images/qv_logo_horizontal.afdesign: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Pixpipe/quickvoxelcore/88e0bfec82b3bf497cd091dbee2e8284867a440b/assets/images/qv_logo_horizontal.afdesign -------------------------------------------------------------------------------- /assets/images/qv_logo_horizontal.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Pixpipe/quickvoxelcore/88e0bfec82b3bf497cd091dbee2e8284867a440b/assets/images/qv_logo_horizontal.png -------------------------------------------------------------------------------- /assets/images/simple.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Pixpipe/quickvoxelcore/88e0bfec82b3bf497cd091dbee2e8284867a440b/assets/images/simple.png -------------------------------------------------------------------------------- /assets/images/test.afdesign: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Pixpipe/quickvoxelcore/88e0bfec82b3bf497cd091dbee2e8284867a440b/assets/images/test.afdesign -------------------------------------------------------------------------------- /data/functional.nii.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Pixpipe/quickvoxelcore/88e0bfec82b3bf497cd091dbee2e8284867a440b/data/functional.nii.gz -------------------------------------------------------------------------------- /data/structural.nii.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Pixpipe/quickvoxelcore/88e0bfec82b3bf497cd091dbee2e8284867a440b/data/structural.nii.gz -------------------------------------------------------------------------------- /doc/assets/anchor.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * AnchorJS - v4.0.0 - 2017-06-02 3 | * https://github.com/bryanbraun/anchorjs 4 | * Copyright (c) 2017 Bryan Braun; Licensed MIT 5 | */ 6 | /* eslint-env amd, node */ 7 | 8 | // https://github.com/umdjs/umd/blob/master/templates/returnExports.js 9 | (function(root, factory) { 10 | 'use strict'; 11 | if (typeof define === 'function' && define.amd) { 12 | // AMD. Register as an anonymous module. 13 | define([], factory); 14 | } else if (typeof module === 'object' && module.exports) { 15 | // Node. Does not work with strict CommonJS, but 16 | // only CommonJS-like environments that support module.exports, 17 | // like Node. 18 | module.exports = factory(); 19 | } else { 20 | // Browser globals (root is window) 21 | root.AnchorJS = factory(); 22 | root.anchors = new root.AnchorJS(); 23 | } 24 | })(this, function() { 25 | 'use strict'; 26 | function AnchorJS(options) { 27 | this.options = options || {}; 28 | this.elements = []; 29 | 30 | /** 31 | * Assigns options to the internal options object, and provides defaults. 32 | * @param {Object} opts - Options object 33 | */ 34 | function _applyRemainingDefaultOptions(opts) { 35 | opts.icon = opts.hasOwnProperty('icon') ? opts.icon : '\ue9cb'; // Accepts characters (and also URLs?), like '#', '¶', '❡', or '§'. 36 | opts.visible = opts.hasOwnProperty('visible') ? opts.visible : 'hover'; // Also accepts 'always' & 'touch' 37 | opts.placement = opts.hasOwnProperty('placement') 38 | ? opts.placement 39 | : 'right'; // Also accepts 'left' 40 | opts.class = opts.hasOwnProperty('class') ? opts.class : ''; // Accepts any class name. 41 | // Using Math.floor here will ensure the value is Number-cast and an integer. 42 | opts.truncate = opts.hasOwnProperty('truncate') 43 | ? Math.floor(opts.truncate) 44 | : 64; // Accepts any value that can be typecast to a number. 45 | } 46 | 47 | _applyRemainingDefaultOptions(this.options); 48 | 49 | /** 50 | * Checks to see if this device supports touch. Uses criteria pulled from Modernizr: 51 | * https://github.com/Modernizr/Modernizr/blob/da22eb27631fc4957f67607fe6042e85c0a84656/feature-detects/touchevents.js#L40 52 | * @returns {Boolean} - true if the current device supports touch. 53 | */ 54 | this.isTouchDevice = function() { 55 | return !!( 56 | 'ontouchstart' in window || 57 | (window.DocumentTouch && document instanceof DocumentTouch) 58 | ); 59 | }; 60 | 61 | /** 62 | * Add anchor links to page elements. 63 | * @param {String|Array|Nodelist} selector - A CSS selector for targeting the elements you wish to add anchor links 64 | * to. Also accepts an array or nodeList containing the relavant elements. 65 | * @returns {this} - The AnchorJS object 66 | */ 67 | this.add = function(selector) { 68 | var elements, 69 | elsWithIds, 70 | idList, 71 | elementID, 72 | i, 73 | index, 74 | count, 75 | tidyText, 76 | newTidyText, 77 | readableID, 78 | anchor, 79 | visibleOptionToUse, 80 | indexesToDrop = []; 81 | 82 | // We reapply options here because somebody may have overwritten the default options object when setting options. 83 | // For example, this overwrites all options but visible: 84 | // 85 | // anchors.options = { visible: 'always'; } 86 | _applyRemainingDefaultOptions(this.options); 87 | 88 | visibleOptionToUse = this.options.visible; 89 | if (visibleOptionToUse === 'touch') { 90 | visibleOptionToUse = this.isTouchDevice() ? 'always' : 'hover'; 91 | } 92 | 93 | // Provide a sensible default selector, if none is given. 94 | if (!selector) { 95 | selector = 'h2, h3, h4, h5, h6'; 96 | } 97 | 98 | elements = _getElements(selector); 99 | 100 | if (elements.length === 0) { 101 | return this; 102 | } 103 | 104 | _addBaselineStyles(); 105 | 106 | // We produce a list of existing IDs so we don't generate a duplicate. 107 | elsWithIds = document.querySelectorAll('[id]'); 108 | idList = [].map.call(elsWithIds, function assign(el) { 109 | return el.id; 110 | }); 111 | 112 | for (i = 0; i < elements.length; i++) { 113 | if (this.hasAnchorJSLink(elements[i])) { 114 | indexesToDrop.push(i); 115 | continue; 116 | } 117 | 118 | if (elements[i].hasAttribute('id')) { 119 | elementID = elements[i].getAttribute('id'); 120 | } else if (elements[i].hasAttribute('data-anchor-id')) { 121 | elementID = elements[i].getAttribute('data-anchor-id'); 122 | } else { 123 | tidyText = this.urlify(elements[i].textContent); 124 | 125 | // Compare our generated ID to existing IDs (and increment it if needed) 126 | // before we add it to the page. 127 | newTidyText = tidyText; 128 | count = 0; 129 | do { 130 | if (index !== undefined) { 131 | newTidyText = tidyText + '-' + count; 132 | } 133 | 134 | index = idList.indexOf(newTidyText); 135 | count += 1; 136 | } while (index !== -1); 137 | index = undefined; 138 | idList.push(newTidyText); 139 | 140 | elements[i].setAttribute('id', newTidyText); 141 | elementID = newTidyText; 142 | } 143 | 144 | readableID = elementID.replace(/-/g, ' '); 145 | 146 | // The following code builds the following DOM structure in a more effiecient (albeit opaque) way. 147 | // ''; 148 | anchor = document.createElement('a'); 149 | anchor.className = 'anchorjs-link ' + this.options.class; 150 | anchor.href = '#' + elementID; 151 | anchor.setAttribute('aria-label', 'Anchor link for: ' + readableID); 152 | anchor.setAttribute('data-anchorjs-icon', this.options.icon); 153 | 154 | if (visibleOptionToUse === 'always') { 155 | anchor.style.opacity = '1'; 156 | } 157 | 158 | if (this.options.icon === '\ue9cb') { 159 | anchor.style.font = '1em/1 anchorjs-icons'; 160 | 161 | // We set lineHeight = 1 here because the `anchorjs-icons` font family could otherwise affect the 162 | // height of the heading. This isn't the case for icons with `placement: left`, so we restore 163 | // line-height: inherit in that case, ensuring they remain positioned correctly. For more info, 164 | // see https://github.com/bryanbraun/anchorjs/issues/39. 165 | if (this.options.placement === 'left') { 166 | anchor.style.lineHeight = 'inherit'; 167 | } 168 | } 169 | 170 | if (this.options.placement === 'left') { 171 | anchor.style.position = 'absolute'; 172 | anchor.style.marginLeft = '-1em'; 173 | anchor.style.paddingRight = '0.5em'; 174 | elements[i].insertBefore(anchor, elements[i].firstChild); 175 | } else { 176 | // if the option provided is `right` (or anything else). 177 | anchor.style.paddingLeft = '0.375em'; 178 | elements[i].appendChild(anchor); 179 | } 180 | } 181 | 182 | for (i = 0; i < indexesToDrop.length; i++) { 183 | elements.splice(indexesToDrop[i] - i, 1); 184 | } 185 | this.elements = this.elements.concat(elements); 186 | 187 | return this; 188 | }; 189 | 190 | /** 191 | * Removes all anchorjs-links from elements targed by the selector. 192 | * @param {String|Array|Nodelist} selector - A CSS selector string targeting elements with anchor links, 193 | * OR a nodeList / array containing the DOM elements. 194 | * @returns {this} - The AnchorJS object 195 | */ 196 | this.remove = function(selector) { 197 | var index, 198 | domAnchor, 199 | elements = _getElements(selector); 200 | 201 | for (var i = 0; i < elements.length; i++) { 202 | domAnchor = elements[i].querySelector('.anchorjs-link'); 203 | if (domAnchor) { 204 | // Drop the element from our main list, if it's in there. 205 | index = this.elements.indexOf(elements[i]); 206 | if (index !== -1) { 207 | this.elements.splice(index, 1); 208 | } 209 | // Remove the anchor from the DOM. 210 | elements[i].removeChild(domAnchor); 211 | } 212 | } 213 | return this; 214 | }; 215 | 216 | /** 217 | * Removes all anchorjs links. Mostly used for tests. 218 | */ 219 | this.removeAll = function() { 220 | this.remove(this.elements); 221 | }; 222 | 223 | /** 224 | * Urlify - Refine text so it makes a good ID. 225 | * 226 | * To do this, we remove apostrophes, replace nonsafe characters with hyphens, 227 | * remove extra hyphens, truncate, trim hyphens, and make lowercase. 228 | * 229 | * @param {String} text - Any text. Usually pulled from the webpage element we are linking to. 230 | * @returns {String} - hyphen-delimited text for use in IDs and URLs. 231 | */ 232 | this.urlify = function(text) { 233 | // Regex for finding the nonsafe URL characters (many need escaping): & +$,:;=?@"#{}|^~[`%!'<>]./()*\ 234 | var nonsafeChars = /[& +$,:;=?@"#{}|^~[`%!'<>\]\.\/\(\)\*\\]/g, 235 | urlText; 236 | 237 | // The reason we include this _applyRemainingDefaultOptions is so urlify can be called independently, 238 | // even after setting options. This can be useful for tests or other applications. 239 | if (!this.options.truncate) { 240 | _applyRemainingDefaultOptions(this.options); 241 | } 242 | 243 | // Note: we trim hyphens after truncating because truncating can cause dangling hyphens. 244 | // Example string: // " ⚡⚡ Don't forget: URL fragments should be i18n-friendly, hyphenated, short, and clean." 245 | urlText = text 246 | .trim() // "⚡⚡ Don't forget: URL fragments should be i18n-friendly, hyphenated, short, and clean." 247 | .replace(/\'/gi, '') // "⚡⚡ Dont forget: URL fragments should be i18n-friendly, hyphenated, short, and clean." 248 | .replace(nonsafeChars, '-') // "⚡⚡-Dont-forget--URL-fragments-should-be-i18n-friendly--hyphenated--short--and-clean-" 249 | .replace(/-{2,}/g, '-') // "⚡⚡-Dont-forget-URL-fragments-should-be-i18n-friendly-hyphenated-short-and-clean-" 250 | .substring(0, this.options.truncate) // "⚡⚡-Dont-forget-URL-fragments-should-be-i18n-friendly-hyphenated-" 251 | .replace(/^-+|-+$/gm, '') // "⚡⚡-Dont-forget-URL-fragments-should-be-i18n-friendly-hyphenated" 252 | .toLowerCase(); // "⚡⚡-dont-forget-url-fragments-should-be-i18n-friendly-hyphenated" 253 | 254 | return urlText; 255 | }; 256 | 257 | /** 258 | * Determines if this element already has an AnchorJS link on it. 259 | * Uses this technique: http://stackoverflow.com/a/5898748/1154642 260 | * @param {HTMLElemnt} el - a DOM node 261 | * @returns {Boolean} true/false 262 | */ 263 | this.hasAnchorJSLink = function(el) { 264 | var hasLeftAnchor = 265 | el.firstChild && 266 | (' ' + el.firstChild.className + ' ').indexOf(' anchorjs-link ') > -1, 267 | hasRightAnchor = 268 | el.lastChild && 269 | (' ' + el.lastChild.className + ' ').indexOf(' anchorjs-link ') > -1; 270 | 271 | return hasLeftAnchor || hasRightAnchor || false; 272 | }; 273 | 274 | /** 275 | * Turns a selector, nodeList, or array of elements into an array of elements (so we can use array methods). 276 | * It also throws errors on any other inputs. Used to handle inputs to .add and .remove. 277 | * @param {String|Array|Nodelist} input - A CSS selector string targeting elements with anchor links, 278 | * OR a nodeList / array containing the DOM elements. 279 | * @returns {Array} - An array containing the elements we want. 280 | */ 281 | function _getElements(input) { 282 | var elements; 283 | if (typeof input === 'string' || input instanceof String) { 284 | // See https://davidwalsh.name/nodelist-array for the technique transforming nodeList -> Array. 285 | elements = [].slice.call(document.querySelectorAll(input)); 286 | // I checked the 'input instanceof NodeList' test in IE9 and modern browsers and it worked for me. 287 | } else if (Array.isArray(input) || input instanceof NodeList) { 288 | elements = [].slice.call(input); 289 | } else { 290 | throw new Error('The selector provided to AnchorJS was invalid.'); 291 | } 292 | return elements; 293 | } 294 | 295 | /** 296 | * _addBaselineStyles 297 | * Adds baseline styles to the page, used by all AnchorJS links irregardless of configuration. 298 | */ 299 | function _addBaselineStyles() { 300 | // We don't want to add global baseline styles if they've been added before. 301 | if (document.head.querySelector('style.anchorjs') !== null) { 302 | return; 303 | } 304 | 305 | var style = document.createElement('style'), 306 | linkRule = 307 | ' .anchorjs-link {' + 308 | ' opacity: 0;' + 309 | ' text-decoration: none;' + 310 | ' -webkit-font-smoothing: antialiased;' + 311 | ' -moz-osx-font-smoothing: grayscale;' + 312 | ' }', 313 | hoverRule = 314 | ' *:hover > .anchorjs-link,' + 315 | ' .anchorjs-link:focus {' + 316 | ' opacity: 1;' + 317 | ' }', 318 | anchorjsLinkFontFace = 319 | ' @font-face {' + 320 | ' font-family: "anchorjs-icons";' + // Icon from icomoon; 10px wide & 10px tall; 2 empty below & 4 above 321 | ' src: url(data:n/a;base64,AAEAAAALAIAAAwAwT1MvMg8yG2cAAAE4AAAAYGNtYXDp3gC3AAABpAAAAExnYXNwAAAAEAAAA9wAAAAIZ2x5ZlQCcfwAAAH4AAABCGhlYWQHFvHyAAAAvAAAADZoaGVhBnACFwAAAPQAAAAkaG10eASAADEAAAGYAAAADGxvY2EACACEAAAB8AAAAAhtYXhwAAYAVwAAARgAAAAgbmFtZQGOH9cAAAMAAAAAunBvc3QAAwAAAAADvAAAACAAAQAAAAEAAHzE2p9fDzz1AAkEAAAAAADRecUWAAAAANQA6R8AAAAAAoACwAAAAAgAAgAAAAAAAAABAAADwP/AAAACgAAA/9MCrQABAAAAAAAAAAAAAAAAAAAAAwABAAAAAwBVAAIAAAAAAAIAAAAAAAAAAAAAAAAAAAAAAAMCQAGQAAUAAAKZAswAAACPApkCzAAAAesAMwEJAAAAAAAAAAAAAAAAAAAAARAAAAAAAAAAAAAAAAAAAAAAQAAg//0DwP/AAEADwABAAAAAAQAAAAAAAAAAAAAAIAAAAAAAAAIAAAACgAAxAAAAAwAAAAMAAAAcAAEAAwAAABwAAwABAAAAHAAEADAAAAAIAAgAAgAAACDpy//9//8AAAAg6cv//f///+EWNwADAAEAAAAAAAAAAAAAAAAACACEAAEAAAAAAAAAAAAAAAAxAAACAAQARAKAAsAAKwBUAAABIiYnJjQ3NzY2MzIWFxYUBwcGIicmNDc3NjQnJiYjIgYHBwYUFxYUBwYGIwciJicmNDc3NjIXFhQHBwYUFxYWMzI2Nzc2NCcmNDc2MhcWFAcHBgYjARQGDAUtLXoWOR8fORYtLTgKGwoKCjgaGg0gEhIgDXoaGgkJBQwHdR85Fi0tOAobCgoKOBoaDSASEiANehoaCQkKGwotLXoWOR8BMwUFLYEuehYXFxYugC44CQkKGwo4GkoaDQ0NDXoaShoKGwoFBe8XFi6ALjgJCQobCjgaShoNDQ0NehpKGgobCgoKLYEuehYXAAAADACWAAEAAAAAAAEACAAAAAEAAAAAAAIAAwAIAAEAAAAAAAMACAAAAAEAAAAAAAQACAAAAAEAAAAAAAUAAQALAAEAAAAAAAYACAAAAAMAAQQJAAEAEAAMAAMAAQQJAAIABgAcAAMAAQQJAAMAEAAMAAMAAQQJAAQAEAAMAAMAAQQJAAUAAgAiAAMAAQQJAAYAEAAMYW5jaG9yanM0MDBAAGEAbgBjAGgAbwByAGoAcwA0ADAAMABAAAAAAwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAH//wAP) format("truetype");' + 322 | ' }', 323 | pseudoElContent = 324 | ' [data-anchorjs-icon]::after {' + 325 | ' content: attr(data-anchorjs-icon);' + 326 | ' }', 327 | firstStyleEl; 328 | 329 | style.className = 'anchorjs'; 330 | style.appendChild(document.createTextNode('')); // Necessary for Webkit. 331 | 332 | // We place it in the head with the other style tags, if possible, so as to 333 | // not look out of place. We insert before the others so these styles can be 334 | // overridden if necessary. 335 | firstStyleEl = document.head.querySelector('[rel="stylesheet"], style'); 336 | if (firstStyleEl === undefined) { 337 | document.head.appendChild(style); 338 | } else { 339 | document.head.insertBefore(style, firstStyleEl); 340 | } 341 | 342 | style.sheet.insertRule(linkRule, style.sheet.cssRules.length); 343 | style.sheet.insertRule(hoverRule, style.sheet.cssRules.length); 344 | style.sheet.insertRule(pseudoElContent, style.sheet.cssRules.length); 345 | style.sheet.insertRule(anchorjsLinkFontFace, style.sheet.cssRules.length); 346 | } 347 | } 348 | 349 | return AnchorJS; 350 | }); 351 | -------------------------------------------------------------------------------- /doc/assets/bass-addons.css: -------------------------------------------------------------------------------- 1 | .input { 2 | font-family: inherit; 3 | display: block; 4 | width: 100%; 5 | height: 2rem; 6 | padding: .5rem; 7 | margin-bottom: 1rem; 8 | border: 1px solid #ccc; 9 | font-size: .875rem; 10 | border-radius: 3px; 11 | box-sizing: border-box; 12 | } 13 | -------------------------------------------------------------------------------- /doc/assets/bass.css: -------------------------------------------------------------------------------- 1 | /*! Basscss | http://basscss.com | MIT License */ 2 | 3 | .h1{ font-size: 2rem } 4 | .h2{ font-size: 1.5rem } 5 | .h3{ font-size: 1.25rem } 6 | .h4{ font-size: 1rem } 7 | .h5{ font-size: .875rem } 8 | .h6{ font-size: .75rem } 9 | 10 | .font-family-inherit{ font-family:inherit } 11 | .font-size-inherit{ font-size:inherit } 12 | .text-decoration-none{ text-decoration:none } 13 | 14 | .bold{ font-weight: bold; font-weight: bold } 15 | .regular{ font-weight:normal } 16 | .italic{ font-style:italic } 17 | .caps{ text-transform:uppercase; letter-spacing: .2em; } 18 | 19 | .left-align{ text-align:left } 20 | .center{ text-align:center } 21 | .right-align{ text-align:right } 22 | .justify{ text-align:justify } 23 | 24 | .nowrap{ white-space:nowrap } 25 | .break-word{ word-wrap:break-word } 26 | 27 | .line-height-1{ line-height: 1 } 28 | .line-height-2{ line-height: 1.125 } 29 | .line-height-3{ line-height: 1.25 } 30 | .line-height-4{ line-height: 1.5 } 31 | 32 | .list-style-none{ list-style:none } 33 | .underline{ text-decoration:underline } 34 | 35 | .truncate{ 36 | max-width:100%; 37 | overflow:hidden; 38 | text-overflow:ellipsis; 39 | white-space:nowrap; 40 | } 41 | 42 | .list-reset{ 43 | list-style:none; 44 | padding-left:0; 45 | } 46 | 47 | .inline{ display:inline } 48 | .block{ display:block } 49 | .inline-block{ display:inline-block } 50 | .table{ display:table } 51 | .table-cell{ display:table-cell } 52 | 53 | .overflow-hidden{ overflow:hidden } 54 | .overflow-scroll{ overflow:scroll } 55 | .overflow-auto{ overflow:auto } 56 | 57 | .clearfix:before, 58 | .clearfix:after{ 59 | content:" "; 60 | display:table 61 | } 62 | .clearfix:after{ clear:both } 63 | 64 | .left{ float:left } 65 | .right{ float:right } 66 | 67 | .fit{ max-width:100% } 68 | 69 | .max-width-1{ max-width: 24rem } 70 | .max-width-2{ max-width: 32rem } 71 | .max-width-3{ max-width: 48rem } 72 | .max-width-4{ max-width: 64rem } 73 | 74 | .border-box{ box-sizing:border-box } 75 | 76 | .align-baseline{ vertical-align:baseline } 77 | .align-top{ vertical-align:top } 78 | .align-middle{ vertical-align:middle } 79 | .align-bottom{ vertical-align:bottom } 80 | 81 | .m0{ margin:0 } 82 | .mt0{ margin-top:0 } 83 | .mr0{ margin-right:0 } 84 | .mb0{ margin-bottom:0 } 85 | .ml0{ margin-left:0 } 86 | .mx0{ margin-left:0; margin-right:0 } 87 | .my0{ margin-top:0; margin-bottom:0 } 88 | 89 | .m1{ margin: .5rem } 90 | .mt1{ margin-top: .5rem } 91 | .mr1{ margin-right: .5rem } 92 | .mb1{ margin-bottom: .5rem } 93 | .ml1{ margin-left: .5rem } 94 | .mx1{ margin-left: .5rem; margin-right: .5rem } 95 | .my1{ margin-top: .5rem; margin-bottom: .5rem } 96 | 97 | .m2{ margin: 1rem } 98 | .mt2{ margin-top: 1rem } 99 | .mr2{ margin-right: 1rem } 100 | .mb2{ margin-bottom: 1rem } 101 | .ml2{ margin-left: 1rem } 102 | .mx2{ margin-left: 1rem; margin-right: 1rem } 103 | .my2{ margin-top: 1rem; margin-bottom: 1rem } 104 | 105 | .m3{ margin: 2rem } 106 | .mt3{ margin-top: 2rem } 107 | .mr3{ margin-right: 2rem } 108 | .mb3{ margin-bottom: 2rem } 109 | .ml3{ margin-left: 2rem } 110 | .mx3{ margin-left: 2rem; margin-right: 2rem } 111 | .my3{ margin-top: 2rem; margin-bottom: 2rem } 112 | 113 | .m4{ margin: 4rem } 114 | .mt4{ margin-top: 4rem } 115 | .mr4{ margin-right: 4rem } 116 | .mb4{ margin-bottom: 4rem } 117 | .ml4{ margin-left: 4rem } 118 | .mx4{ margin-left: 4rem; margin-right: 4rem } 119 | .my4{ margin-top: 4rem; margin-bottom: 4rem } 120 | 121 | .mxn1{ margin-left: -.5rem; margin-right: -.5rem; } 122 | .mxn2{ margin-left: -1rem; margin-right: -1rem; } 123 | .mxn3{ margin-left: -2rem; margin-right: -2rem; } 124 | .mxn4{ margin-left: -4rem; margin-right: -4rem; } 125 | 126 | .ml-auto{ margin-left:auto } 127 | .mr-auto{ margin-right:auto } 128 | .mx-auto{ margin-left:auto; margin-right:auto; } 129 | 130 | .p0{ padding:0 } 131 | .pt0{ padding-top:0 } 132 | .pr0{ padding-right:0 } 133 | .pb0{ padding-bottom:0 } 134 | .pl0{ padding-left:0 } 135 | .px0{ padding-left:0; padding-right:0 } 136 | .py0{ padding-top:0; padding-bottom:0 } 137 | 138 | .p1{ padding: .5rem } 139 | .pt1{ padding-top: .5rem } 140 | .pr1{ padding-right: .5rem } 141 | .pb1{ padding-bottom: .5rem } 142 | .pl1{ padding-left: .5rem } 143 | .py1{ padding-top: .5rem; padding-bottom: .5rem } 144 | .px1{ padding-left: .5rem; padding-right: .5rem } 145 | 146 | .p2{ padding: 1rem } 147 | .pt2{ padding-top: 1rem } 148 | .pr2{ padding-right: 1rem } 149 | .pb2{ padding-bottom: 1rem } 150 | .pl2{ padding-left: 1rem } 151 | .py2{ padding-top: 1rem; padding-bottom: 1rem } 152 | .px2{ padding-left: 1rem; padding-right: 1rem } 153 | 154 | .p3{ padding: 2rem } 155 | .pt3{ padding-top: 2rem } 156 | .pr3{ padding-right: 2rem } 157 | .pb3{ padding-bottom: 2rem } 158 | .pl3{ padding-left: 2rem } 159 | .py3{ padding-top: 2rem; padding-bottom: 2rem } 160 | .px3{ padding-left: 2rem; padding-right: 2rem } 161 | 162 | .p4{ padding: 4rem } 163 | .pt4{ padding-top: 4rem } 164 | .pr4{ padding-right: 4rem } 165 | .pb4{ padding-bottom: 4rem } 166 | .pl4{ padding-left: 4rem } 167 | .py4{ padding-top: 4rem; padding-bottom: 4rem } 168 | .px4{ padding-left: 4rem; padding-right: 4rem } 169 | 170 | .col{ 171 | float:left; 172 | box-sizing:border-box; 173 | } 174 | 175 | .col-right{ 176 | float:right; 177 | box-sizing:border-box; 178 | } 179 | 180 | .col-1{ 181 | width:8. 182 | 333%; 183 | } 184 | 185 | .col-2{ 186 | width:16.66667%; 187 | } 188 | 189 | .col-3{ 190 | width:25%; 191 | } 192 | 193 | .col-4{ 194 | width:33.33333%; 195 | } 196 | 197 | .col-5{ 198 | width:41.66667%; 199 | } 200 | 201 | .col-6{ 202 | width:50%; 203 | } 204 | 205 | .col-7{ 206 | width:58.33333%; 207 | } 208 | 209 | .col-8{ 210 | width:66.66667%; 211 | } 212 | 213 | .col-9{ 214 | width:75%; 215 | } 216 | 217 | .col-10{ 218 | width:83.33333%; 219 | } 220 | 221 | .col-11{ 222 | width:91.66667%; 223 | } 224 | 225 | .col-12{ 226 | width:100%; 227 | } 228 | @media (min-width: 40em){ 229 | 230 | .sm-col{ 231 | float:left; 232 | box-sizing:border-box; 233 | } 234 | 235 | .sm-col-right{ 236 | float:right; 237 | box-sizing:border-box; 238 | } 239 | 240 | .sm-col-1{ 241 | width:8.33333%; 242 | } 243 | 244 | .sm-col-2{ 245 | width:16.66667%; 246 | } 247 | 248 | .sm-col-3{ 249 | width:25%; 250 | } 251 | 252 | .sm-col-4{ 253 | width:33.33333%; 254 | } 255 | 256 | .sm-col-5{ 257 | width:41.66667%; 258 | } 259 | 260 | .sm-col-6{ 261 | width:50%; 262 | } 263 | 264 | .sm-col-7{ 265 | width:58.33333%; 266 | } 267 | 268 | .sm-col-8{ 269 | width:66.66667%; 270 | } 271 | 272 | .sm-col-9{ 273 | width:75%; 274 | } 275 | 276 | .sm-col-10{ 277 | width:83.33333%; 278 | } 279 | 280 | .sm-col-11{ 281 | width:91.66667%; 282 | } 283 | 284 | .sm-col-12{ 285 | width:100%; 286 | } 287 | 288 | } 289 | @media (min-width: 52em){ 290 | 291 | .md-col{ 292 | float:left; 293 | box-sizing:border-box; 294 | } 295 | 296 | .md-col-right{ 297 | float:right; 298 | box-sizing:border-box; 299 | } 300 | 301 | .md-col-1{ 302 | width:8.33333%; 303 | } 304 | 305 | .md-col-2{ 306 | width:16.66667%; 307 | } 308 | 309 | .md-col-3{ 310 | width:25%; 311 | } 312 | 313 | .md-col-4{ 314 | width:33.33333%; 315 | } 316 | 317 | .md-col-5{ 318 | width:41.66667%; 319 | } 320 | 321 | .md-col-6{ 322 | width:50%; 323 | } 324 | 325 | .md-col-7{ 326 | width:58.33333%; 327 | } 328 | 329 | .md-col-8{ 330 | width:66.66667%; 331 | } 332 | 333 | .md-col-9{ 334 | width:75%; 335 | } 336 | 337 | .md-col-10{ 338 | width:83.33333%; 339 | } 340 | 341 | .md-col-11{ 342 | width:91.66667%; 343 | } 344 | 345 | .md-col-12{ 346 | width:100%; 347 | } 348 | 349 | } 350 | @media (min-width: 64em){ 351 | 352 | .lg-col{ 353 | float:left; 354 | box-sizing:border-box; 355 | } 356 | 357 | .lg-col-right{ 358 | float:right; 359 | box-sizing:border-box; 360 | } 361 | 362 | .lg-col-1{ 363 | width:8.33333%; 364 | } 365 | 366 | .lg-col-2{ 367 | width:16.66667%; 368 | } 369 | 370 | .lg-col-3{ 371 | width:25%; 372 | } 373 | 374 | .lg-col-4{ 375 | width:33.33333%; 376 | } 377 | 378 | .lg-col-5{ 379 | width:41.66667%; 380 | } 381 | 382 | .lg-col-6{ 383 | width:50%; 384 | } 385 | 386 | .lg-col-7{ 387 | width:58.33333%; 388 | } 389 | 390 | .lg-col-8{ 391 | width:66.66667%; 392 | } 393 | 394 | .lg-col-9{ 395 | width:75%; 396 | } 397 | 398 | .lg-col-10{ 399 | width:83.33333%; 400 | } 401 | 402 | .lg-col-11{ 403 | width:91.66667%; 404 | } 405 | 406 | .lg-col-12{ 407 | width:100%; 408 | } 409 | 410 | } 411 | .flex{ display:-webkit-box; display:-webkit-flex; display:-ms-flexbox; display:flex } 412 | 413 | @media (min-width: 40em){ 414 | .sm-flex{ display:-webkit-box; display:-webkit-flex; display:-ms-flexbox; display:flex } 415 | } 416 | 417 | @media (min-width: 52em){ 418 | .md-flex{ display:-webkit-box; display:-webkit-flex; display:-ms-flexbox; display:flex } 419 | } 420 | 421 | @media (min-width: 64em){ 422 | .lg-flex{ display:-webkit-box; display:-webkit-flex; display:-ms-flexbox; display:flex } 423 | } 424 | 425 | .flex-column{ -webkit-box-orient:vertical; -webkit-box-direction:normal; -webkit-flex-direction:column; -ms-flex-direction:column; flex-direction:column } 426 | .flex-wrap{ -webkit-flex-wrap:wrap; -ms-flex-wrap:wrap; flex-wrap:wrap } 427 | 428 | .items-start{ -webkit-box-align:start; -webkit-align-items:flex-start; -ms-flex-align:start; -ms-grid-row-align:flex-start; align-items:flex-start } 429 | .items-end{ -webkit-box-align:end; -webkit-align-items:flex-end; -ms-flex-align:end; -ms-grid-row-align:flex-end; align-items:flex-end } 430 | .items-center{ -webkit-box-align:center; -webkit-align-items:center; -ms-flex-align:center; -ms-grid-row-align:center; align-items:center } 431 | .items-baseline{ -webkit-box-align:baseline; -webkit-align-items:baseline; -ms-flex-align:baseline; -ms-grid-row-align:baseline; align-items:baseline } 432 | .items-stretch{ -webkit-box-align:stretch; -webkit-align-items:stretch; -ms-flex-align:stretch; -ms-grid-row-align:stretch; align-items:stretch } 433 | 434 | .self-start{ -webkit-align-self:flex-start; -ms-flex-item-align:start; align-self:flex-start } 435 | .self-end{ -webkit-align-self:flex-end; -ms-flex-item-align:end; align-self:flex-end } 436 | .self-center{ -webkit-align-self:center; -ms-flex-item-align:center; align-self:center } 437 | .self-baseline{ -webkit-align-self:baseline; -ms-flex-item-align:baseline; align-self:baseline } 438 | .self-stretch{ -webkit-align-self:stretch; -ms-flex-item-align:stretch; align-self:stretch } 439 | 440 | .justify-start{ -webkit-box-pack:start; -webkit-justify-content:flex-start; -ms-flex-pack:start; justify-content:flex-start } 441 | .justify-end{ -webkit-box-pack:end; -webkit-justify-content:flex-end; -ms-flex-pack:end; justify-content:flex-end } 442 | .justify-center{ -webkit-box-pack:center; -webkit-justify-content:center; -ms-flex-pack:center; justify-content:center } 443 | .justify-between{ -webkit-box-pack:justify; -webkit-justify-content:space-between; -ms-flex-pack:justify; justify-content:space-between } 444 | .justify-around{ -webkit-justify-content:space-around; -ms-flex-pack:distribute; justify-content:space-around } 445 | 446 | .content-start{ -webkit-align-content:flex-start; -ms-flex-line-pack:start; align-content:flex-start } 447 | .content-end{ -webkit-align-content:flex-end; -ms-flex-line-pack:end; align-content:flex-end } 448 | .content-center{ -webkit-align-content:center; -ms-flex-line-pack:center; align-content:center } 449 | .content-between{ -webkit-align-content:space-between; -ms-flex-line-pack:justify; align-content:space-between } 450 | .content-around{ -webkit-align-content:space-around; -ms-flex-line-pack:distribute; align-content:space-around } 451 | .content-stretch{ -webkit-align-content:stretch; -ms-flex-line-pack:stretch; align-content:stretch } 452 | .flex-auto{ 453 | -webkit-box-flex:1; 454 | -webkit-flex:1 1 auto; 455 | -ms-flex:1 1 auto; 456 | flex:1 1 auto; 457 | min-width:0; 458 | min-height:0; 459 | } 460 | .flex-none{ -webkit-box-flex:0; -webkit-flex:none; -ms-flex:none; flex:none } 461 | .fs0{ flex-shrink: 0 } 462 | 463 | .order-0{ -webkit-box-ordinal-group:1; -webkit-order:0; -ms-flex-order:0; order:0 } 464 | .order-1{ -webkit-box-ordinal-group:2; -webkit-order:1; -ms-flex-order:1; order:1 } 465 | .order-2{ -webkit-box-ordinal-group:3; -webkit-order:2; -ms-flex-order:2; order:2 } 466 | .order-3{ -webkit-box-ordinal-group:4; -webkit-order:3; -ms-flex-order:3; order:3 } 467 | .order-last{ -webkit-box-ordinal-group:100000; -webkit-order:99999; -ms-flex-order:99999; order:99999 } 468 | 469 | .relative{ position:relative } 470 | .absolute{ position:absolute } 471 | .fixed{ position:fixed } 472 | 473 | .top-0{ top:0 } 474 | .right-0{ right:0 } 475 | .bottom-0{ bottom:0 } 476 | .left-0{ left:0 } 477 | 478 | .z1{ z-index: 1 } 479 | .z2{ z-index: 2 } 480 | .z3{ z-index: 3 } 481 | .z4{ z-index: 4 } 482 | 483 | .border{ 484 | border-style:solid; 485 | border-width: 1px; 486 | } 487 | 488 | .border-top{ 489 | border-top-style:solid; 490 | border-top-width: 1px; 491 | } 492 | 493 | .border-right{ 494 | border-right-style:solid; 495 | border-right-width: 1px; 496 | } 497 | 498 | .border-bottom{ 499 | border-bottom-style:solid; 500 | border-bottom-width: 1px; 501 | } 502 | 503 | .border-left{ 504 | border-left-style:solid; 505 | border-left-width: 1px; 506 | } 507 | 508 | .border-none{ border:0 } 509 | 510 | .rounded{ border-radius: 3px } 511 | .circle{ border-radius:50% } 512 | 513 | .rounded-top{ border-radius: 3px 3px 0 0 } 514 | .rounded-right{ border-radius: 0 3px 3px 0 } 515 | .rounded-bottom{ border-radius: 0 0 3px 3px } 516 | .rounded-left{ border-radius: 3px 0 0 3px } 517 | 518 | .not-rounded{ border-radius:0 } 519 | 520 | .hide{ 521 | position:absolute !important; 522 | height:1px; 523 | width:1px; 524 | overflow:hidden; 525 | clip:rect(1px, 1px, 1px, 1px); 526 | } 527 | 528 | @media (max-width: 40em){ 529 | .xs-hide{ display:none !important } 530 | } 531 | 532 | @media (min-width: 40em) and (max-width: 52em){ 533 | .sm-hide{ display:none !important } 534 | } 535 | 536 | @media (min-width: 52em) and (max-width: 64em){ 537 | .md-hide{ display:none !important } 538 | } 539 | 540 | @media (min-width: 64em){ 541 | .lg-hide{ display:none !important } 542 | } 543 | 544 | .display-none{ display:none !important } 545 | -------------------------------------------------------------------------------- /doc/assets/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Pixpipe/quickvoxelcore/88e0bfec82b3bf497cd091dbee2e8284867a440b/doc/assets/favicon.png -------------------------------------------------------------------------------- /doc/assets/fonts/EOT/SourceCodePro-Bold.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Pixpipe/quickvoxelcore/88e0bfec82b3bf497cd091dbee2e8284867a440b/doc/assets/fonts/EOT/SourceCodePro-Bold.eot -------------------------------------------------------------------------------- /doc/assets/fonts/EOT/SourceCodePro-Regular.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Pixpipe/quickvoxelcore/88e0bfec82b3bf497cd091dbee2e8284867a440b/doc/assets/fonts/EOT/SourceCodePro-Regular.eot -------------------------------------------------------------------------------- /doc/assets/fonts/LICENSE.txt: -------------------------------------------------------------------------------- 1 | Copyright 2010, 2012 Adobe Systems Incorporated (http://www.adobe.com/), with Reserved Font Name 'Source'. All Rights Reserved. Source is a trademark of Adobe Systems Incorporated in the United States and/or other countries. 2 | 3 | This Font Software is licensed under the SIL Open Font License, Version 1.1. 4 | 5 | This license is copied below, and is also available with a FAQ at: http://scripts.sil.org/OFL 6 | 7 | 8 | ----------------------------------------------------------- 9 | SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007 10 | ----------------------------------------------------------- 11 | 12 | PREAMBLE 13 | The goals of the Open Font License (OFL) are to stimulate worldwide 14 | development of collaborative font projects, to support the font creation 15 | efforts of academic and linguistic communities, and to provide a free and 16 | open framework in which fonts may be shared and improved in partnership 17 | with others. 18 | 19 | The OFL allows the licensed fonts to be used, studied, modified and 20 | redistributed freely as long as they are not sold by themselves. The 21 | fonts, including any derivative works, can be bundled, embedded, 22 | redistributed and/or sold with any software provided that any reserved 23 | names are not used by derivative works. The fonts and derivatives, 24 | however, cannot be released under any other type of license. The 25 | requirement for fonts to remain under this license does not apply 26 | to any document created using the fonts or their derivatives. 27 | 28 | DEFINITIONS 29 | "Font Software" refers to the set of files released by the Copyright 30 | Holder(s) under this license and clearly marked as such. This may 31 | include source files, build scripts and documentation. 32 | 33 | "Reserved Font Name" refers to any names specified as such after the 34 | copyright statement(s). 35 | 36 | "Original Version" refers to the collection of Font Software components as 37 | distributed by the Copyright Holder(s). 38 | 39 | "Modified Version" refers to any derivative made by adding to, deleting, 40 | or substituting -- in part or in whole -- any of the components of the 41 | Original Version, by changing formats or by porting the Font Software to a 42 | new environment. 43 | 44 | "Author" refers to any designer, engineer, programmer, technical 45 | writer or other person who contributed to the Font Software. 46 | 47 | PERMISSION & CONDITIONS 48 | Permission is hereby granted, free of charge, to any person obtaining 49 | a copy of the Font Software, to use, study, copy, merge, embed, modify, 50 | redistribute, and sell modified and unmodified copies of the Font 51 | Software, subject to the following conditions: 52 | 53 | 1) Neither the Font Software nor any of its individual components, 54 | in Original or Modified Versions, may be sold by itself. 55 | 56 | 2) Original or Modified Versions of the Font Software may be bundled, 57 | redistributed and/or sold with any software, provided that each copy 58 | contains the above copyright notice and this license. These can be 59 | included either as stand-alone text files, human-readable headers or 60 | in the appropriate machine-readable metadata fields within text or 61 | binary files as long as those fields can be easily viewed by the user. 62 | 63 | 3) No Modified Version of the Font Software may use the Reserved Font 64 | Name(s) unless explicit written permission is granted by the corresponding 65 | Copyright Holder. This restriction only applies to the primary font name as 66 | presented to the users. 67 | 68 | 4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font 69 | Software shall not be used to promote, endorse or advertise any 70 | Modified Version, except to acknowledge the contribution(s) of the 71 | Copyright Holder(s) and the Author(s) or with their explicit written 72 | permission. 73 | 74 | 5) The Font Software, modified or unmodified, in part or in whole, 75 | must be distributed entirely under this license, and must not be 76 | distributed under any other license. The requirement for fonts to 77 | remain under this license does not apply to any document created 78 | using the Font Software. 79 | 80 | TERMINATION 81 | This license becomes null and void if any of the above conditions are 82 | not met. 83 | 84 | DISCLAIMER 85 | THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 86 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF 87 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT 88 | OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE 89 | COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 90 | INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL 91 | DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 92 | FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM 93 | OTHER DEALINGS IN THE FONT SOFTWARE. 94 | -------------------------------------------------------------------------------- /doc/assets/fonts/OTF/SourceCodePro-Bold.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Pixpipe/quickvoxelcore/88e0bfec82b3bf497cd091dbee2e8284867a440b/doc/assets/fonts/OTF/SourceCodePro-Bold.otf -------------------------------------------------------------------------------- /doc/assets/fonts/OTF/SourceCodePro-Regular.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Pixpipe/quickvoxelcore/88e0bfec82b3bf497cd091dbee2e8284867a440b/doc/assets/fonts/OTF/SourceCodePro-Regular.otf -------------------------------------------------------------------------------- /doc/assets/fonts/TTF/SourceCodePro-Bold.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Pixpipe/quickvoxelcore/88e0bfec82b3bf497cd091dbee2e8284867a440b/doc/assets/fonts/TTF/SourceCodePro-Bold.ttf -------------------------------------------------------------------------------- /doc/assets/fonts/TTF/SourceCodePro-Regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Pixpipe/quickvoxelcore/88e0bfec82b3bf497cd091dbee2e8284867a440b/doc/assets/fonts/TTF/SourceCodePro-Regular.ttf -------------------------------------------------------------------------------- /doc/assets/fonts/WOFF/OTF/SourceCodePro-Bold.otf.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Pixpipe/quickvoxelcore/88e0bfec82b3bf497cd091dbee2e8284867a440b/doc/assets/fonts/WOFF/OTF/SourceCodePro-Bold.otf.woff -------------------------------------------------------------------------------- /doc/assets/fonts/WOFF/OTF/SourceCodePro-Regular.otf.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Pixpipe/quickvoxelcore/88e0bfec82b3bf497cd091dbee2e8284867a440b/doc/assets/fonts/WOFF/OTF/SourceCodePro-Regular.otf.woff -------------------------------------------------------------------------------- /doc/assets/fonts/WOFF/TTF/SourceCodePro-Bold.ttf.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Pixpipe/quickvoxelcore/88e0bfec82b3bf497cd091dbee2e8284867a440b/doc/assets/fonts/WOFF/TTF/SourceCodePro-Bold.ttf.woff -------------------------------------------------------------------------------- /doc/assets/fonts/WOFF/TTF/SourceCodePro-Regular.ttf.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Pixpipe/quickvoxelcore/88e0bfec82b3bf497cd091dbee2e8284867a440b/doc/assets/fonts/WOFF/TTF/SourceCodePro-Regular.ttf.woff -------------------------------------------------------------------------------- /doc/assets/fonts/WOFF2/OTF/SourceCodePro-Bold.otf.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Pixpipe/quickvoxelcore/88e0bfec82b3bf497cd091dbee2e8284867a440b/doc/assets/fonts/WOFF2/OTF/SourceCodePro-Bold.otf.woff2 -------------------------------------------------------------------------------- /doc/assets/fonts/WOFF2/OTF/SourceCodePro-Regular.otf.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Pixpipe/quickvoxelcore/88e0bfec82b3bf497cd091dbee2e8284867a440b/doc/assets/fonts/WOFF2/OTF/SourceCodePro-Regular.otf.woff2 -------------------------------------------------------------------------------- /doc/assets/fonts/WOFF2/TTF/SourceCodePro-Bold.ttf.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Pixpipe/quickvoxelcore/88e0bfec82b3bf497cd091dbee2e8284867a440b/doc/assets/fonts/WOFF2/TTF/SourceCodePro-Bold.ttf.woff2 -------------------------------------------------------------------------------- /doc/assets/fonts/WOFF2/TTF/SourceCodePro-Regular.ttf.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Pixpipe/quickvoxelcore/88e0bfec82b3bf497cd091dbee2e8284867a440b/doc/assets/fonts/WOFF2/TTF/SourceCodePro-Regular.ttf.woff2 -------------------------------------------------------------------------------- /doc/assets/fonts/source-code-pro.css: -------------------------------------------------------------------------------- 1 | @font-face{ 2 | font-family: 'Source Code Pro'; 3 | font-weight: 400; 4 | font-style: normal; 5 | font-stretch: normal; 6 | src: url('EOT/SourceCodePro-Regular.eot') format('embedded-opentype'), 7 | url('WOFF2/TTF/SourceCodePro-Regular.ttf.woff2') format('woff2'), 8 | url('WOFF/OTF/SourceCodePro-Regular.otf.woff') format('woff'), 9 | url('OTF/SourceCodePro-Regular.otf') format('opentype'), 10 | url('TTF/SourceCodePro-Regular.ttf') format('truetype'); 11 | } 12 | 13 | @font-face{ 14 | font-family: 'Source Code Pro'; 15 | font-weight: 700; 16 | font-style: normal; 17 | font-stretch: normal; 18 | src: url('EOT/SourceCodePro-Bold.eot') format('embedded-opentype'), 19 | url('WOFF2/TTF/SourceCodePro-Bold.ttf.woff2') format('woff2'), 20 | url('WOFF/OTF/SourceCodePro-Bold.otf.woff') format('woff'), 21 | url('OTF/SourceCodePro-Bold.otf') format('opentype'), 22 | url('TTF/SourceCodePro-Bold.ttf') format('truetype'); 23 | } 24 | -------------------------------------------------------------------------------- /doc/assets/github.css: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | github.com style (c) Vasily Polovnyov 4 | 5 | */ 6 | 7 | .hljs { 8 | display: block; 9 | overflow-x: auto; 10 | padding: 0.5em; 11 | color: #333; 12 | background: #f8f8f8; 13 | -webkit-text-size-adjust: none; 14 | } 15 | 16 | .hljs-comment, 17 | .diff .hljs-header, 18 | .hljs-javadoc { 19 | color: #998; 20 | font-style: italic; 21 | } 22 | 23 | .hljs-keyword, 24 | .css .rule .hljs-keyword, 25 | .hljs-winutils, 26 | .nginx .hljs-title, 27 | .hljs-subst, 28 | .hljs-request, 29 | .hljs-status { 30 | color: #1184CE; 31 | } 32 | 33 | .hljs-number, 34 | .hljs-hexcolor, 35 | .ruby .hljs-constant { 36 | color: #ed225d; 37 | } 38 | 39 | .hljs-string, 40 | .hljs-tag .hljs-value, 41 | .hljs-phpdoc, 42 | .hljs-dartdoc, 43 | .tex .hljs-formula { 44 | color: #ed225d; 45 | } 46 | 47 | .hljs-title, 48 | .hljs-id, 49 | .scss .hljs-preprocessor { 50 | color: #900; 51 | font-weight: bold; 52 | } 53 | 54 | .hljs-list .hljs-keyword, 55 | .hljs-subst { 56 | font-weight: normal; 57 | } 58 | 59 | .hljs-class .hljs-title, 60 | .hljs-type, 61 | .vhdl .hljs-literal, 62 | .tex .hljs-command { 63 | color: #458; 64 | font-weight: bold; 65 | } 66 | 67 | .hljs-tag, 68 | .hljs-tag .hljs-title, 69 | .hljs-rules .hljs-property, 70 | .django .hljs-tag .hljs-keyword { 71 | color: #000080; 72 | font-weight: normal; 73 | } 74 | 75 | .hljs-attribute, 76 | .hljs-variable, 77 | .lisp .hljs-body { 78 | color: #008080; 79 | } 80 | 81 | .hljs-regexp { 82 | color: #009926; 83 | } 84 | 85 | .hljs-symbol, 86 | .ruby .hljs-symbol .hljs-string, 87 | .lisp .hljs-keyword, 88 | .clojure .hljs-keyword, 89 | .scheme .hljs-keyword, 90 | .tex .hljs-special, 91 | .hljs-prompt { 92 | color: #990073; 93 | } 94 | 95 | .hljs-built_in { 96 | color: #0086b3; 97 | } 98 | 99 | .hljs-preprocessor, 100 | .hljs-pragma, 101 | .hljs-pi, 102 | .hljs-doctype, 103 | .hljs-shebang, 104 | .hljs-cdata { 105 | color: #999; 106 | font-weight: bold; 107 | } 108 | 109 | .hljs-deletion { 110 | background: #fdd; 111 | } 112 | 113 | .hljs-addition { 114 | background: #dfd; 115 | } 116 | 117 | .diff .hljs-change { 118 | background: #0086b3; 119 | } 120 | 121 | .hljs-chunk { 122 | color: #aaa; 123 | } 124 | -------------------------------------------------------------------------------- /doc/assets/images/colormaps.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Pixpipe/quickvoxelcore/88e0bfec82b3bf497cd091dbee2e8284867a440b/doc/assets/images/colormaps.png -------------------------------------------------------------------------------- /doc/assets/images/double1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Pixpipe/quickvoxelcore/88e0bfec82b3bf497cd091dbee2e8284867a440b/doc/assets/images/double1.png -------------------------------------------------------------------------------- /doc/assets/images/double2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Pixpipe/quickvoxelcore/88e0bfec82b3bf497cd091dbee2e8284867a440b/doc/assets/images/double2.png -------------------------------------------------------------------------------- /doc/assets/images/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Pixpipe/quickvoxelcore/88e0bfec82b3bf497cd091dbee2e8284867a440b/doc/assets/images/favicon.png -------------------------------------------------------------------------------- /doc/assets/images/qv_logo.afdesign: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Pixpipe/quickvoxelcore/88e0bfec82b3bf497cd091dbee2e8284867a440b/doc/assets/images/qv_logo.afdesign -------------------------------------------------------------------------------- /doc/assets/images/qv_logo_cube.afdesign: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Pixpipe/quickvoxelcore/88e0bfec82b3bf497cd091dbee2e8284867a440b/doc/assets/images/qv_logo_cube.afdesign -------------------------------------------------------------------------------- /doc/assets/images/qv_logo_cube.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Pixpipe/quickvoxelcore/88e0bfec82b3bf497cd091dbee2e8284867a440b/doc/assets/images/qv_logo_cube.png -------------------------------------------------------------------------------- /doc/assets/images/qv_logo_horizontal.afdesign: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Pixpipe/quickvoxelcore/88e0bfec82b3bf497cd091dbee2e8284867a440b/doc/assets/images/qv_logo_horizontal.afdesign -------------------------------------------------------------------------------- /doc/assets/images/qv_logo_horizontal.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Pixpipe/quickvoxelcore/88e0bfec82b3bf497cd091dbee2e8284867a440b/doc/assets/images/qv_logo_horizontal.png -------------------------------------------------------------------------------- /doc/assets/images/simple.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Pixpipe/quickvoxelcore/88e0bfec82b3bf497cd091dbee2e8284867a440b/doc/assets/images/simple.png -------------------------------------------------------------------------------- /doc/assets/images/test.afdesign: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Pixpipe/quickvoxelcore/88e0bfec82b3bf497cd091dbee2e8284867a440b/doc/assets/images/test.afdesign -------------------------------------------------------------------------------- /doc/assets/name_1000.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Pixpipe/quickvoxelcore/88e0bfec82b3bf497cd091dbee2e8284867a440b/doc/assets/name_1000.png -------------------------------------------------------------------------------- /doc/assets/site.js: -------------------------------------------------------------------------------- 1 | /* global anchors */ 2 | 3 | // add anchor links to headers 4 | anchors.options.placement = 'left'; 5 | anchors.add('h3'); 6 | 7 | // Filter UI 8 | var tocElements = document.getElementById('toc').getElementsByTagName('li'); 9 | 10 | document.getElementById('filter-input').addEventListener('keyup', function(e) { 11 | var i, element, children; 12 | 13 | // enter key 14 | if (e.keyCode === 13) { 15 | // go to the first displayed item in the toc 16 | for (i = 0; i < tocElements.length; i++) { 17 | element = tocElements[i]; 18 | if (!element.classList.contains('display-none')) { 19 | location.replace(element.firstChild.href); 20 | return e.preventDefault(); 21 | } 22 | } 23 | } 24 | 25 | var match = function() { 26 | return true; 27 | }; 28 | 29 | var value = this.value.toLowerCase(); 30 | 31 | if (!value.match(/^\s*$/)) { 32 | match = function(element) { 33 | var html = element.firstChild.innerHTML; 34 | return html && html.toLowerCase().indexOf(value) !== -1; 35 | }; 36 | } 37 | 38 | for (i = 0; i < tocElements.length; i++) { 39 | element = tocElements[i]; 40 | children = Array.from(element.getElementsByTagName('li')); 41 | if (match(element) || children.some(match)) { 42 | element.classList.remove('display-none'); 43 | } else { 44 | element.classList.add('display-none'); 45 | } 46 | } 47 | }); 48 | 49 | var items = document.getElementsByClassName('toggle-sibling'); 50 | for (var j = 0; j < items.length; j++) { 51 | items[j].addEventListener('click', toggleSibling); 52 | } 53 | 54 | function toggleSibling() { 55 | var stepSibling = this.parentNode.getElementsByClassName('toggle-target')[0]; 56 | var icon = this.getElementsByClassName('icon')[0]; 57 | var klass = 'display-none'; 58 | if (stepSibling.classList.contains(klass)) { 59 | stepSibling.classList.remove(klass); 60 | icon.innerHTML = '▾'; 61 | } else { 62 | stepSibling.classList.add(klass); 63 | icon.innerHTML = '▸'; 64 | } 65 | } 66 | 67 | function showHashTarget(targetId) { 68 | if (targetId) { 69 | var hashTarget = document.getElementById(targetId); 70 | // new target is hidden 71 | if ( 72 | hashTarget && 73 | hashTarget.offsetHeight === 0 && 74 | hashTarget.parentNode.parentNode.classList.contains('display-none') 75 | ) { 76 | hashTarget.parentNode.parentNode.classList.remove('display-none'); 77 | } 78 | } 79 | } 80 | 81 | function scrollIntoView(targetId) { 82 | // Only scroll to element if we don't have a stored scroll position. 83 | if (targetId && !history.state) { 84 | var hashTarget = document.getElementById(targetId); 85 | if (hashTarget) { 86 | hashTarget.scrollIntoView(); 87 | } 88 | } 89 | } 90 | 91 | function gotoCurrentTarget() { 92 | showHashTarget(location.hash.substring(1)); 93 | scrollIntoView(location.hash.substring(1)); 94 | } 95 | 96 | window.addEventListener('hashchange', gotoCurrentTarget); 97 | gotoCurrentTarget(); 98 | 99 | var toclinks = document.getElementsByClassName('pre-open'); 100 | for (var k = 0; k < toclinks.length; k++) { 101 | toclinks[k].addEventListener('mousedown', preOpen, false); 102 | } 103 | 104 | function preOpen() { 105 | showHashTarget(this.hash.substring(1)); 106 | } 107 | 108 | var split_left = document.querySelector('#split-left'); 109 | var split_right = document.querySelector('#split-right'); 110 | var split_parent = split_left.parentNode; 111 | var cw_with_sb = split_left.clientWidth; 112 | split_left.style.overflow = 'hidden'; 113 | var cw_without_sb = split_left.clientWidth; 114 | split_left.style.overflow = ''; 115 | 116 | Split(['#split-left', '#split-right'], { 117 | elementStyle: function(dimension, size, gutterSize) { 118 | return { 119 | 'flex-basis': 'calc(' + size + '% - ' + gutterSize + 'px)' 120 | }; 121 | }, 122 | gutterStyle: function(dimension, gutterSize) { 123 | return { 124 | 'flex-basis': gutterSize + 'px' 125 | }; 126 | }, 127 | gutterSize: 20, 128 | sizes: [20, 80] 129 | }); 130 | 131 | // Chrome doesn't remember scroll position properly so do it ourselves. 132 | // Also works on Firefox and Edge. 133 | 134 | function updateState() { 135 | history.replaceState( 136 | { 137 | left_top: split_left.scrollTop, 138 | right_top: split_right.scrollTop 139 | }, 140 | document.title 141 | ); 142 | } 143 | 144 | function loadState(ev) { 145 | if (ev) { 146 | // Edge doesn't replace change history.state on popstate. 147 | history.replaceState(ev.state, document.title); 148 | } 149 | if (history.state) { 150 | split_left.scrollTop = history.state.left_top; 151 | split_right.scrollTop = history.state.right_top; 152 | } 153 | } 154 | 155 | window.addEventListener('load', function() { 156 | // Restore after Firefox scrolls to hash. 157 | setTimeout(function() { 158 | loadState(); 159 | // Update with initial scroll position. 160 | updateState(); 161 | // Update scroll positions only after we've loaded because Firefox 162 | // emits an initial scroll event with 0. 163 | split_left.addEventListener('scroll', updateState); 164 | split_right.addEventListener('scroll', updateState); 165 | }, 1); 166 | }); 167 | 168 | window.addEventListener('popstate', loadState); 169 | -------------------------------------------------------------------------------- /doc/assets/split.css: -------------------------------------------------------------------------------- 1 | .gutter { 2 | background-color: #f5f5f5; 3 | background-repeat: no-repeat; 4 | background-position: 50%; 5 | } 6 | 7 | .gutter.gutter-vertical { 8 | background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAB4AAAAFAQMAAABo7865AAAABlBMVEVHcEzMzMzyAv2sAAAAAXRSTlMAQObYZgAAABBJREFUeF5jOAMEEAIEEFwAn3kMwcB6I2AAAAAASUVORK5CYII='); 9 | cursor: ns-resize; 10 | } 11 | 12 | .gutter.gutter-horizontal { 13 | background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAeCAYAAADkftS9AAAAIklEQVQoU2M4c+bMfxAGAgYYmwGrIIiDjrELjpo5aiZeMwF+yNnOs5KSvgAAAABJRU5ErkJggg=='); 14 | cursor: ew-resize; 15 | } 16 | -------------------------------------------------------------------------------- /doc/assets/style.css: -------------------------------------------------------------------------------- 1 | .documentation { 2 | font-family: Helvetica, sans-serif; 3 | color: #666; 4 | line-height: 1.5; 5 | background: #f5f5f5; 6 | } 7 | 8 | .black { 9 | color: #666; 10 | } 11 | 12 | .bg-white { 13 | background-color: #fff; 14 | } 15 | 16 | h4 { 17 | margin: 20px 0 10px 0; 18 | } 19 | 20 | .documentation h3 { 21 | color: #000; 22 | } 23 | 24 | .border-bottom { 25 | border-color: #ddd; 26 | } 27 | 28 | /* JO */ 29 | a { 30 | color: #4bbd87; 31 | text-decoration: none; 32 | } 33 | 34 | /* JO */ 35 | #split-left { 36 | background: #FFF; 37 | } 38 | 39 | /* JO */ 40 | .keyline-top-not { 41 | background: #FFF; 42 | margin-bottom: 2em; 43 | } 44 | 45 | .documentation a[href]:hover { 46 | text-decoration: underline; 47 | } 48 | 49 | a:hover { 50 | cursor: pointer; 51 | } 52 | 53 | .py1-ul li { 54 | padding: 5px 0; 55 | } 56 | 57 | .max-height-100 { 58 | max-height: 100%; 59 | } 60 | 61 | .height-viewport-100 { 62 | height: 100vh; 63 | } 64 | 65 | section:target h3 { 66 | font-weight:700; 67 | } 68 | 69 | .documentation td, 70 | .documentation th { 71 | padding: .25rem .25rem; 72 | } 73 | 74 | h1:hover .anchorjs-link, 75 | h2:hover .anchorjs-link, 76 | h3:hover .anchorjs-link, 77 | h4:hover .anchorjs-link { 78 | opacity: 1; 79 | } 80 | 81 | .fix-3 { 82 | width: 25%; 83 | max-width: 244px; 84 | } 85 | 86 | .fix-3 { 87 | width: 25%; 88 | max-width: 244px; 89 | } 90 | 91 | @media (min-width: 52em) { 92 | .fix-margin-3 { 93 | margin-left: 25%; 94 | } 95 | } 96 | 97 | .pre, pre, code, .code { 98 | font-family: Source Code Pro,Menlo,Consolas,Liberation Mono,monospace; 99 | font-size: 14px; 100 | } 101 | 102 | .fill-light { 103 | background: #F9F9F9; 104 | } 105 | 106 | .width2 { 107 | width: 1rem; 108 | } 109 | 110 | .input { 111 | font-family: inherit; 112 | display: block; 113 | width: 100%; 114 | height: 2rem; 115 | padding: .5rem; 116 | margin-bottom: 1rem; 117 | border: 1px solid #ccc; 118 | font-size: .875rem; 119 | border-radius: 3px; 120 | box-sizing: border-box; 121 | } 122 | 123 | table { 124 | border-collapse: collapse; 125 | } 126 | 127 | .prose table th, 128 | .prose table td { 129 | text-align: left; 130 | padding:8px; 131 | border:1px solid #ddd; 132 | } 133 | 134 | .prose table th:nth-child(1) { border-right: none; } 135 | .prose table th:nth-child(2) { border-left: none; } 136 | 137 | .prose table { 138 | border:1px solid #ddd; 139 | } 140 | 141 | .prose-big { 142 | font-size: 18px; 143 | line-height: 30px; 144 | } 145 | 146 | .quiet { 147 | opacity: 0.7; 148 | } 149 | 150 | .minishadow { 151 | box-shadow: 2px 2px 10px #f3f3f3; 152 | } 153 | 154 | 155 | textarea, input, button { outline: none; } 156 | 157 | .width100pc { 158 | width: 100%; 159 | } 160 | 161 | p code { 162 | padding: 2px 4px; 163 | border-radius: 3px; 164 | background: #f5f5f5; 165 | font-family: monospace; 166 | } 167 | -------------------------------------------------------------------------------- /docgen/config.yml: -------------------------------------------------------------------------------- 1 | toc: 2 | - 3 | name: Quickvoxel Core 4 | file: ../readme.md 5 | - QuickvoxelCore 6 | - VolumeCollection 7 | - RenderEngine 8 | - Volume 9 | - ColormapManager 10 | -------------------------------------------------------------------------------- /docgen/custom_theme/README.md: -------------------------------------------------------------------------------- 1 | # the default theme 2 | 3 | ![](screenshot.png) 4 | 5 | This is the default theme for [documentationjs](https://github.com/documentationjs): 6 | it consists of underscore templates and a few assets: a [highlight.js](https://highlightjs.org/) 7 | theme and [basscss](http://www.basscss.com/) as a basic CSS framework. 8 | 9 | This is bundled by default in documentation: it is the default theme. 10 | 11 | The contents are the following: 12 | 13 | * `index._`, the main template that defines the document structure 14 | * `section._`, a partial used to render each chunk of documentation 15 | * `assets/*`, any assets, including CSS & JS 16 | -------------------------------------------------------------------------------- /docgen/custom_theme/assets/bass-addons.css: -------------------------------------------------------------------------------- 1 | .input { 2 | font-family: inherit; 3 | display: block; 4 | width: 100%; 5 | height: 2rem; 6 | padding: .5rem; 7 | margin-bottom: 1rem; 8 | border: 1px solid #ccc; 9 | font-size: .875rem; 10 | border-radius: 3px; 11 | box-sizing: border-box; 12 | } 13 | -------------------------------------------------------------------------------- /docgen/custom_theme/assets/bass.css: -------------------------------------------------------------------------------- 1 | /*! Basscss | http://basscss.com | MIT License */ 2 | 3 | .h1{ font-size: 2rem } 4 | .h2{ font-size: 1.5rem } 5 | .h3{ font-size: 1.25rem } 6 | .h4{ font-size: 1rem } 7 | .h5{ font-size: .875rem } 8 | .h6{ font-size: .75rem } 9 | 10 | .font-family-inherit{ font-family:inherit } 11 | .font-size-inherit{ font-size:inherit } 12 | .text-decoration-none{ text-decoration:none } 13 | 14 | .bold{ font-weight: bold; font-weight: bold } 15 | .regular{ font-weight:normal } 16 | .italic{ font-style:italic } 17 | .caps{ text-transform:uppercase; letter-spacing: .2em; } 18 | 19 | .left-align{ text-align:left } 20 | .center{ text-align:center } 21 | .right-align{ text-align:right } 22 | .justify{ text-align:justify } 23 | 24 | .nowrap{ white-space:nowrap } 25 | .break-word{ word-wrap:break-word } 26 | 27 | .line-height-1{ line-height: 1 } 28 | .line-height-2{ line-height: 1.125 } 29 | .line-height-3{ line-height: 1.25 } 30 | .line-height-4{ line-height: 1.5 } 31 | 32 | .list-style-none{ list-style:none } 33 | .underline{ text-decoration:underline } 34 | 35 | .truncate{ 36 | max-width:100%; 37 | overflow:hidden; 38 | text-overflow:ellipsis; 39 | white-space:nowrap; 40 | } 41 | 42 | .list-reset{ 43 | list-style:none; 44 | padding-left:0; 45 | } 46 | 47 | .inline{ display:inline } 48 | .block{ display:block } 49 | .inline-block{ display:inline-block } 50 | .table{ display:table } 51 | .table-cell{ display:table-cell } 52 | 53 | .overflow-hidden{ overflow:hidden } 54 | .overflow-scroll{ overflow:scroll } 55 | .overflow-auto{ overflow:auto } 56 | 57 | .clearfix:before, 58 | .clearfix:after{ 59 | content:" "; 60 | display:table 61 | } 62 | .clearfix:after{ clear:both } 63 | 64 | .left{ float:left } 65 | .right{ float:right } 66 | 67 | .fit{ max-width:100% } 68 | 69 | .max-width-1{ max-width: 24rem } 70 | .max-width-2{ max-width: 32rem } 71 | .max-width-3{ max-width: 48rem } 72 | .max-width-4{ max-width: 64rem } 73 | 74 | .border-box{ box-sizing:border-box } 75 | 76 | .align-baseline{ vertical-align:baseline } 77 | .align-top{ vertical-align:top } 78 | .align-middle{ vertical-align:middle } 79 | .align-bottom{ vertical-align:bottom } 80 | 81 | .m0{ margin:0 } 82 | .mt0{ margin-top:0 } 83 | .mr0{ margin-right:0 } 84 | .mb0{ margin-bottom:0 } 85 | .ml0{ margin-left:0 } 86 | .mx0{ margin-left:0; margin-right:0 } 87 | .my0{ margin-top:0; margin-bottom:0 } 88 | 89 | .m1{ margin: .5rem } 90 | .mt1{ margin-top: .5rem } 91 | .mr1{ margin-right: .5rem } 92 | .mb1{ margin-bottom: .5rem } 93 | .ml1{ margin-left: .5rem } 94 | .mx1{ margin-left: .5rem; margin-right: .5rem } 95 | .my1{ margin-top: .5rem; margin-bottom: .5rem } 96 | 97 | .m2{ margin: 1rem } 98 | .mt2{ margin-top: 1rem } 99 | .mr2{ margin-right: 1rem } 100 | .mb2{ margin-bottom: 1rem } 101 | .ml2{ margin-left: 1rem } 102 | .mx2{ margin-left: 1rem; margin-right: 1rem } 103 | .my2{ margin-top: 1rem; margin-bottom: 1rem } 104 | 105 | .m3{ margin: 2rem } 106 | .mt3{ margin-top: 2rem } 107 | .mr3{ margin-right: 2rem } 108 | .mb3{ margin-bottom: 2rem } 109 | .ml3{ margin-left: 2rem } 110 | .mx3{ margin-left: 2rem; margin-right: 2rem } 111 | .my3{ margin-top: 2rem; margin-bottom: 2rem } 112 | 113 | .m4{ margin: 4rem } 114 | .mt4{ margin-top: 4rem } 115 | .mr4{ margin-right: 4rem } 116 | .mb4{ margin-bottom: 4rem } 117 | .ml4{ margin-left: 4rem } 118 | .mx4{ margin-left: 4rem; margin-right: 4rem } 119 | .my4{ margin-top: 4rem; margin-bottom: 4rem } 120 | 121 | .mxn1{ margin-left: -.5rem; margin-right: -.5rem; } 122 | .mxn2{ margin-left: -1rem; margin-right: -1rem; } 123 | .mxn3{ margin-left: -2rem; margin-right: -2rem; } 124 | .mxn4{ margin-left: -4rem; margin-right: -4rem; } 125 | 126 | .ml-auto{ margin-left:auto } 127 | .mr-auto{ margin-right:auto } 128 | .mx-auto{ margin-left:auto; margin-right:auto; } 129 | 130 | .p0{ padding:0 } 131 | .pt0{ padding-top:0 } 132 | .pr0{ padding-right:0 } 133 | .pb0{ padding-bottom:0 } 134 | .pl0{ padding-left:0 } 135 | .px0{ padding-left:0; padding-right:0 } 136 | .py0{ padding-top:0; padding-bottom:0 } 137 | 138 | .p1{ padding: .5rem } 139 | .pt1{ padding-top: .5rem } 140 | .pr1{ padding-right: .5rem } 141 | .pb1{ padding-bottom: .5rem } 142 | .pl1{ padding-left: .5rem } 143 | .py1{ padding-top: .5rem; padding-bottom: .5rem } 144 | .px1{ padding-left: .5rem; padding-right: .5rem } 145 | 146 | .p2{ padding: 1rem } 147 | .pt2{ padding-top: 1rem } 148 | .pr2{ padding-right: 1rem } 149 | .pb2{ padding-bottom: 1rem } 150 | .pl2{ padding-left: 1rem } 151 | .py2{ padding-top: 1rem; padding-bottom: 1rem } 152 | .px2{ padding-left: 1rem; padding-right: 1rem } 153 | 154 | .p3{ padding: 2rem } 155 | .pt3{ padding-top: 2rem } 156 | .pr3{ padding-right: 2rem } 157 | .pb3{ padding-bottom: 2rem } 158 | .pl3{ padding-left: 2rem } 159 | .py3{ padding-top: 2rem; padding-bottom: 2rem } 160 | .px3{ padding-left: 2rem; padding-right: 2rem } 161 | 162 | .p4{ padding: 4rem } 163 | .pt4{ padding-top: 4rem } 164 | .pr4{ padding-right: 4rem } 165 | .pb4{ padding-bottom: 4rem } 166 | .pl4{ padding-left: 4rem } 167 | .py4{ padding-top: 4rem; padding-bottom: 4rem } 168 | .px4{ padding-left: 4rem; padding-right: 4rem } 169 | 170 | .col{ 171 | float:left; 172 | box-sizing:border-box; 173 | } 174 | 175 | .col-right{ 176 | float:right; 177 | box-sizing:border-box; 178 | } 179 | 180 | .col-1{ 181 | width:8. 182 | 333%; 183 | } 184 | 185 | .col-2{ 186 | width:16.66667%; 187 | } 188 | 189 | .col-3{ 190 | width:25%; 191 | } 192 | 193 | .col-4{ 194 | width:33.33333%; 195 | } 196 | 197 | .col-5{ 198 | width:41.66667%; 199 | } 200 | 201 | .col-6{ 202 | width:50%; 203 | } 204 | 205 | .col-7{ 206 | width:58.33333%; 207 | } 208 | 209 | .col-8{ 210 | width:66.66667%; 211 | } 212 | 213 | .col-9{ 214 | width:75%; 215 | } 216 | 217 | .col-10{ 218 | width:83.33333%; 219 | } 220 | 221 | .col-11{ 222 | width:91.66667%; 223 | } 224 | 225 | .col-12{ 226 | width:100%; 227 | } 228 | @media (min-width: 40em){ 229 | 230 | .sm-col{ 231 | float:left; 232 | box-sizing:border-box; 233 | } 234 | 235 | .sm-col-right{ 236 | float:right; 237 | box-sizing:border-box; 238 | } 239 | 240 | .sm-col-1{ 241 | width:8.33333%; 242 | } 243 | 244 | .sm-col-2{ 245 | width:16.66667%; 246 | } 247 | 248 | .sm-col-3{ 249 | width:25%; 250 | } 251 | 252 | .sm-col-4{ 253 | width:33.33333%; 254 | } 255 | 256 | .sm-col-5{ 257 | width:41.66667%; 258 | } 259 | 260 | .sm-col-6{ 261 | width:50%; 262 | } 263 | 264 | .sm-col-7{ 265 | width:58.33333%; 266 | } 267 | 268 | .sm-col-8{ 269 | width:66.66667%; 270 | } 271 | 272 | .sm-col-9{ 273 | width:75%; 274 | } 275 | 276 | .sm-col-10{ 277 | width:83.33333%; 278 | } 279 | 280 | .sm-col-11{ 281 | width:91.66667%; 282 | } 283 | 284 | .sm-col-12{ 285 | width:100%; 286 | } 287 | 288 | } 289 | @media (min-width: 52em){ 290 | 291 | .md-col{ 292 | float:left; 293 | box-sizing:border-box; 294 | } 295 | 296 | .md-col-right{ 297 | float:right; 298 | box-sizing:border-box; 299 | } 300 | 301 | .md-col-1{ 302 | width:8.33333%; 303 | } 304 | 305 | .md-col-2{ 306 | width:16.66667%; 307 | } 308 | 309 | .md-col-3{ 310 | width:25%; 311 | } 312 | 313 | .md-col-4{ 314 | width:33.33333%; 315 | } 316 | 317 | .md-col-5{ 318 | width:41.66667%; 319 | } 320 | 321 | .md-col-6{ 322 | width:50%; 323 | } 324 | 325 | .md-col-7{ 326 | width:58.33333%; 327 | } 328 | 329 | .md-col-8{ 330 | width:66.66667%; 331 | } 332 | 333 | .md-col-9{ 334 | width:75%; 335 | } 336 | 337 | .md-col-10{ 338 | width:83.33333%; 339 | } 340 | 341 | .md-col-11{ 342 | width:91.66667%; 343 | } 344 | 345 | .md-col-12{ 346 | width:100%; 347 | } 348 | 349 | } 350 | @media (min-width: 64em){ 351 | 352 | .lg-col{ 353 | float:left; 354 | box-sizing:border-box; 355 | } 356 | 357 | .lg-col-right{ 358 | float:right; 359 | box-sizing:border-box; 360 | } 361 | 362 | .lg-col-1{ 363 | width:8.33333%; 364 | } 365 | 366 | .lg-col-2{ 367 | width:16.66667%; 368 | } 369 | 370 | .lg-col-3{ 371 | width:25%; 372 | } 373 | 374 | .lg-col-4{ 375 | width:33.33333%; 376 | } 377 | 378 | .lg-col-5{ 379 | width:41.66667%; 380 | } 381 | 382 | .lg-col-6{ 383 | width:50%; 384 | } 385 | 386 | .lg-col-7{ 387 | width:58.33333%; 388 | } 389 | 390 | .lg-col-8{ 391 | width:66.66667%; 392 | } 393 | 394 | .lg-col-9{ 395 | width:75%; 396 | } 397 | 398 | .lg-col-10{ 399 | width:83.33333%; 400 | } 401 | 402 | .lg-col-11{ 403 | width:91.66667%; 404 | } 405 | 406 | .lg-col-12{ 407 | width:100%; 408 | } 409 | 410 | } 411 | .flex{ display:-webkit-box; display:-webkit-flex; display:-ms-flexbox; display:flex } 412 | 413 | @media (min-width: 40em){ 414 | .sm-flex{ display:-webkit-box; display:-webkit-flex; display:-ms-flexbox; display:flex } 415 | } 416 | 417 | @media (min-width: 52em){ 418 | .md-flex{ display:-webkit-box; display:-webkit-flex; display:-ms-flexbox; display:flex } 419 | } 420 | 421 | @media (min-width: 64em){ 422 | .lg-flex{ display:-webkit-box; display:-webkit-flex; display:-ms-flexbox; display:flex } 423 | } 424 | 425 | .flex-column{ -webkit-box-orient:vertical; -webkit-box-direction:normal; -webkit-flex-direction:column; -ms-flex-direction:column; flex-direction:column } 426 | .flex-wrap{ -webkit-flex-wrap:wrap; -ms-flex-wrap:wrap; flex-wrap:wrap } 427 | 428 | .items-start{ -webkit-box-align:start; -webkit-align-items:flex-start; -ms-flex-align:start; -ms-grid-row-align:flex-start; align-items:flex-start } 429 | .items-end{ -webkit-box-align:end; -webkit-align-items:flex-end; -ms-flex-align:end; -ms-grid-row-align:flex-end; align-items:flex-end } 430 | .items-center{ -webkit-box-align:center; -webkit-align-items:center; -ms-flex-align:center; -ms-grid-row-align:center; align-items:center } 431 | .items-baseline{ -webkit-box-align:baseline; -webkit-align-items:baseline; -ms-flex-align:baseline; -ms-grid-row-align:baseline; align-items:baseline } 432 | .items-stretch{ -webkit-box-align:stretch; -webkit-align-items:stretch; -ms-flex-align:stretch; -ms-grid-row-align:stretch; align-items:stretch } 433 | 434 | .self-start{ -webkit-align-self:flex-start; -ms-flex-item-align:start; align-self:flex-start } 435 | .self-end{ -webkit-align-self:flex-end; -ms-flex-item-align:end; align-self:flex-end } 436 | .self-center{ -webkit-align-self:center; -ms-flex-item-align:center; align-self:center } 437 | .self-baseline{ -webkit-align-self:baseline; -ms-flex-item-align:baseline; align-self:baseline } 438 | .self-stretch{ -webkit-align-self:stretch; -ms-flex-item-align:stretch; align-self:stretch } 439 | 440 | .justify-start{ -webkit-box-pack:start; -webkit-justify-content:flex-start; -ms-flex-pack:start; justify-content:flex-start } 441 | .justify-end{ -webkit-box-pack:end; -webkit-justify-content:flex-end; -ms-flex-pack:end; justify-content:flex-end } 442 | .justify-center{ -webkit-box-pack:center; -webkit-justify-content:center; -ms-flex-pack:center; justify-content:center } 443 | .justify-between{ -webkit-box-pack:justify; -webkit-justify-content:space-between; -ms-flex-pack:justify; justify-content:space-between } 444 | .justify-around{ -webkit-justify-content:space-around; -ms-flex-pack:distribute; justify-content:space-around } 445 | 446 | .content-start{ -webkit-align-content:flex-start; -ms-flex-line-pack:start; align-content:flex-start } 447 | .content-end{ -webkit-align-content:flex-end; -ms-flex-line-pack:end; align-content:flex-end } 448 | .content-center{ -webkit-align-content:center; -ms-flex-line-pack:center; align-content:center } 449 | .content-between{ -webkit-align-content:space-between; -ms-flex-line-pack:justify; align-content:space-between } 450 | .content-around{ -webkit-align-content:space-around; -ms-flex-line-pack:distribute; align-content:space-around } 451 | .content-stretch{ -webkit-align-content:stretch; -ms-flex-line-pack:stretch; align-content:stretch } 452 | .flex-auto{ 453 | -webkit-box-flex:1; 454 | -webkit-flex:1 1 auto; 455 | -ms-flex:1 1 auto; 456 | flex:1 1 auto; 457 | min-width:0; 458 | min-height:0; 459 | } 460 | .flex-none{ -webkit-box-flex:0; -webkit-flex:none; -ms-flex:none; flex:none } 461 | .fs0{ flex-shrink: 0 } 462 | 463 | .order-0{ -webkit-box-ordinal-group:1; -webkit-order:0; -ms-flex-order:0; order:0 } 464 | .order-1{ -webkit-box-ordinal-group:2; -webkit-order:1; -ms-flex-order:1; order:1 } 465 | .order-2{ -webkit-box-ordinal-group:3; -webkit-order:2; -ms-flex-order:2; order:2 } 466 | .order-3{ -webkit-box-ordinal-group:4; -webkit-order:3; -ms-flex-order:3; order:3 } 467 | .order-last{ -webkit-box-ordinal-group:100000; -webkit-order:99999; -ms-flex-order:99999; order:99999 } 468 | 469 | .relative{ position:relative } 470 | .absolute{ position:absolute } 471 | .fixed{ position:fixed } 472 | 473 | .top-0{ top:0 } 474 | .right-0{ right:0 } 475 | .bottom-0{ bottom:0 } 476 | .left-0{ left:0 } 477 | 478 | .z1{ z-index: 1 } 479 | .z2{ z-index: 2 } 480 | .z3{ z-index: 3 } 481 | .z4{ z-index: 4 } 482 | 483 | .border{ 484 | border-style:solid; 485 | border-width: 1px; 486 | } 487 | 488 | .border-top{ 489 | border-top-style:solid; 490 | border-top-width: 1px; 491 | } 492 | 493 | .border-right{ 494 | border-right-style:solid; 495 | border-right-width: 1px; 496 | } 497 | 498 | .border-bottom{ 499 | border-bottom-style:solid; 500 | border-bottom-width: 1px; 501 | } 502 | 503 | .border-left{ 504 | border-left-style:solid; 505 | border-left-width: 1px; 506 | } 507 | 508 | .border-none{ border:0 } 509 | 510 | .rounded{ border-radius: 3px } 511 | .circle{ border-radius:50% } 512 | 513 | .rounded-top{ border-radius: 3px 3px 0 0 } 514 | .rounded-right{ border-radius: 0 3px 3px 0 } 515 | .rounded-bottom{ border-radius: 0 0 3px 3px } 516 | .rounded-left{ border-radius: 3px 0 0 3px } 517 | 518 | .not-rounded{ border-radius:0 } 519 | 520 | .hide{ 521 | position:absolute !important; 522 | height:1px; 523 | width:1px; 524 | overflow:hidden; 525 | clip:rect(1px, 1px, 1px, 1px); 526 | } 527 | 528 | @media (max-width: 40em){ 529 | .xs-hide{ display:none !important } 530 | } 531 | 532 | @media (min-width: 40em) and (max-width: 52em){ 533 | .sm-hide{ display:none !important } 534 | } 535 | 536 | @media (min-width: 52em) and (max-width: 64em){ 537 | .md-hide{ display:none !important } 538 | } 539 | 540 | @media (min-width: 64em){ 541 | .lg-hide{ display:none !important } 542 | } 543 | 544 | .display-none{ display:none !important } 545 | -------------------------------------------------------------------------------- /docgen/custom_theme/assets/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Pixpipe/quickvoxelcore/88e0bfec82b3bf497cd091dbee2e8284867a440b/docgen/custom_theme/assets/favicon.png -------------------------------------------------------------------------------- /docgen/custom_theme/assets/fonts/EOT/SourceCodePro-Bold.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Pixpipe/quickvoxelcore/88e0bfec82b3bf497cd091dbee2e8284867a440b/docgen/custom_theme/assets/fonts/EOT/SourceCodePro-Bold.eot -------------------------------------------------------------------------------- /docgen/custom_theme/assets/fonts/EOT/SourceCodePro-Regular.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Pixpipe/quickvoxelcore/88e0bfec82b3bf497cd091dbee2e8284867a440b/docgen/custom_theme/assets/fonts/EOT/SourceCodePro-Regular.eot -------------------------------------------------------------------------------- /docgen/custom_theme/assets/fonts/LICENSE.txt: -------------------------------------------------------------------------------- 1 | Copyright 2010, 2012 Adobe Systems Incorporated (http://www.adobe.com/), with Reserved Font Name 'Source'. All Rights Reserved. Source is a trademark of Adobe Systems Incorporated in the United States and/or other countries. 2 | 3 | This Font Software is licensed under the SIL Open Font License, Version 1.1. 4 | 5 | This license is copied below, and is also available with a FAQ at: http://scripts.sil.org/OFL 6 | 7 | 8 | ----------------------------------------------------------- 9 | SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007 10 | ----------------------------------------------------------- 11 | 12 | PREAMBLE 13 | The goals of the Open Font License (OFL) are to stimulate worldwide 14 | development of collaborative font projects, to support the font creation 15 | efforts of academic and linguistic communities, and to provide a free and 16 | open framework in which fonts may be shared and improved in partnership 17 | with others. 18 | 19 | The OFL allows the licensed fonts to be used, studied, modified and 20 | redistributed freely as long as they are not sold by themselves. The 21 | fonts, including any derivative works, can be bundled, embedded, 22 | redistributed and/or sold with any software provided that any reserved 23 | names are not used by derivative works. The fonts and derivatives, 24 | however, cannot be released under any other type of license. The 25 | requirement for fonts to remain under this license does not apply 26 | to any document created using the fonts or their derivatives. 27 | 28 | DEFINITIONS 29 | "Font Software" refers to the set of files released by the Copyright 30 | Holder(s) under this license and clearly marked as such. This may 31 | include source files, build scripts and documentation. 32 | 33 | "Reserved Font Name" refers to any names specified as such after the 34 | copyright statement(s). 35 | 36 | "Original Version" refers to the collection of Font Software components as 37 | distributed by the Copyright Holder(s). 38 | 39 | "Modified Version" refers to any derivative made by adding to, deleting, 40 | or substituting -- in part or in whole -- any of the components of the 41 | Original Version, by changing formats or by porting the Font Software to a 42 | new environment. 43 | 44 | "Author" refers to any designer, engineer, programmer, technical 45 | writer or other person who contributed to the Font Software. 46 | 47 | PERMISSION & CONDITIONS 48 | Permission is hereby granted, free of charge, to any person obtaining 49 | a copy of the Font Software, to use, study, copy, merge, embed, modify, 50 | redistribute, and sell modified and unmodified copies of the Font 51 | Software, subject to the following conditions: 52 | 53 | 1) Neither the Font Software nor any of its individual components, 54 | in Original or Modified Versions, may be sold by itself. 55 | 56 | 2) Original or Modified Versions of the Font Software may be bundled, 57 | redistributed and/or sold with any software, provided that each copy 58 | contains the above copyright notice and this license. These can be 59 | included either as stand-alone text files, human-readable headers or 60 | in the appropriate machine-readable metadata fields within text or 61 | binary files as long as those fields can be easily viewed by the user. 62 | 63 | 3) No Modified Version of the Font Software may use the Reserved Font 64 | Name(s) unless explicit written permission is granted by the corresponding 65 | Copyright Holder. This restriction only applies to the primary font name as 66 | presented to the users. 67 | 68 | 4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font 69 | Software shall not be used to promote, endorse or advertise any 70 | Modified Version, except to acknowledge the contribution(s) of the 71 | Copyright Holder(s) and the Author(s) or with their explicit written 72 | permission. 73 | 74 | 5) The Font Software, modified or unmodified, in part or in whole, 75 | must be distributed entirely under this license, and must not be 76 | distributed under any other license. The requirement for fonts to 77 | remain under this license does not apply to any document created 78 | using the Font Software. 79 | 80 | TERMINATION 81 | This license becomes null and void if any of the above conditions are 82 | not met. 83 | 84 | DISCLAIMER 85 | THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 86 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF 87 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT 88 | OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE 89 | COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 90 | INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL 91 | DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 92 | FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM 93 | OTHER DEALINGS IN THE FONT SOFTWARE. 94 | -------------------------------------------------------------------------------- /docgen/custom_theme/assets/fonts/OTF/SourceCodePro-Bold.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Pixpipe/quickvoxelcore/88e0bfec82b3bf497cd091dbee2e8284867a440b/docgen/custom_theme/assets/fonts/OTF/SourceCodePro-Bold.otf -------------------------------------------------------------------------------- /docgen/custom_theme/assets/fonts/OTF/SourceCodePro-Regular.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Pixpipe/quickvoxelcore/88e0bfec82b3bf497cd091dbee2e8284867a440b/docgen/custom_theme/assets/fonts/OTF/SourceCodePro-Regular.otf -------------------------------------------------------------------------------- /docgen/custom_theme/assets/fonts/TTF/SourceCodePro-Bold.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Pixpipe/quickvoxelcore/88e0bfec82b3bf497cd091dbee2e8284867a440b/docgen/custom_theme/assets/fonts/TTF/SourceCodePro-Bold.ttf -------------------------------------------------------------------------------- /docgen/custom_theme/assets/fonts/TTF/SourceCodePro-Regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Pixpipe/quickvoxelcore/88e0bfec82b3bf497cd091dbee2e8284867a440b/docgen/custom_theme/assets/fonts/TTF/SourceCodePro-Regular.ttf -------------------------------------------------------------------------------- /docgen/custom_theme/assets/fonts/WOFF/OTF/SourceCodePro-Bold.otf.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Pixpipe/quickvoxelcore/88e0bfec82b3bf497cd091dbee2e8284867a440b/docgen/custom_theme/assets/fonts/WOFF/OTF/SourceCodePro-Bold.otf.woff -------------------------------------------------------------------------------- /docgen/custom_theme/assets/fonts/WOFF/OTF/SourceCodePro-Regular.otf.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Pixpipe/quickvoxelcore/88e0bfec82b3bf497cd091dbee2e8284867a440b/docgen/custom_theme/assets/fonts/WOFF/OTF/SourceCodePro-Regular.otf.woff -------------------------------------------------------------------------------- /docgen/custom_theme/assets/fonts/WOFF/TTF/SourceCodePro-Bold.ttf.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Pixpipe/quickvoxelcore/88e0bfec82b3bf497cd091dbee2e8284867a440b/docgen/custom_theme/assets/fonts/WOFF/TTF/SourceCodePro-Bold.ttf.woff -------------------------------------------------------------------------------- /docgen/custom_theme/assets/fonts/WOFF/TTF/SourceCodePro-Regular.ttf.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Pixpipe/quickvoxelcore/88e0bfec82b3bf497cd091dbee2e8284867a440b/docgen/custom_theme/assets/fonts/WOFF/TTF/SourceCodePro-Regular.ttf.woff -------------------------------------------------------------------------------- /docgen/custom_theme/assets/fonts/WOFF2/OTF/SourceCodePro-Bold.otf.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Pixpipe/quickvoxelcore/88e0bfec82b3bf497cd091dbee2e8284867a440b/docgen/custom_theme/assets/fonts/WOFF2/OTF/SourceCodePro-Bold.otf.woff2 -------------------------------------------------------------------------------- /docgen/custom_theme/assets/fonts/WOFF2/OTF/SourceCodePro-Regular.otf.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Pixpipe/quickvoxelcore/88e0bfec82b3bf497cd091dbee2e8284867a440b/docgen/custom_theme/assets/fonts/WOFF2/OTF/SourceCodePro-Regular.otf.woff2 -------------------------------------------------------------------------------- /docgen/custom_theme/assets/fonts/WOFF2/TTF/SourceCodePro-Bold.ttf.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Pixpipe/quickvoxelcore/88e0bfec82b3bf497cd091dbee2e8284867a440b/docgen/custom_theme/assets/fonts/WOFF2/TTF/SourceCodePro-Bold.ttf.woff2 -------------------------------------------------------------------------------- /docgen/custom_theme/assets/fonts/WOFF2/TTF/SourceCodePro-Regular.ttf.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Pixpipe/quickvoxelcore/88e0bfec82b3bf497cd091dbee2e8284867a440b/docgen/custom_theme/assets/fonts/WOFF2/TTF/SourceCodePro-Regular.ttf.woff2 -------------------------------------------------------------------------------- /docgen/custom_theme/assets/fonts/source-code-pro.css: -------------------------------------------------------------------------------- 1 | @font-face{ 2 | font-family: 'Source Code Pro'; 3 | font-weight: 400; 4 | font-style: normal; 5 | font-stretch: normal; 6 | src: url('EOT/SourceCodePro-Regular.eot') format('embedded-opentype'), 7 | url('WOFF2/TTF/SourceCodePro-Regular.ttf.woff2') format('woff2'), 8 | url('WOFF/OTF/SourceCodePro-Regular.otf.woff') format('woff'), 9 | url('OTF/SourceCodePro-Regular.otf') format('opentype'), 10 | url('TTF/SourceCodePro-Regular.ttf') format('truetype'); 11 | } 12 | 13 | @font-face{ 14 | font-family: 'Source Code Pro'; 15 | font-weight: 700; 16 | font-style: normal; 17 | font-stretch: normal; 18 | src: url('EOT/SourceCodePro-Bold.eot') format('embedded-opentype'), 19 | url('WOFF2/TTF/SourceCodePro-Bold.ttf.woff2') format('woff2'), 20 | url('WOFF/OTF/SourceCodePro-Bold.otf.woff') format('woff'), 21 | url('OTF/SourceCodePro-Bold.otf') format('opentype'), 22 | url('TTF/SourceCodePro-Bold.ttf') format('truetype'); 23 | } 24 | -------------------------------------------------------------------------------- /docgen/custom_theme/assets/github.css: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | github.com style (c) Vasily Polovnyov 4 | 5 | */ 6 | 7 | .hljs { 8 | display: block; 9 | overflow-x: auto; 10 | padding: 0.5em; 11 | color: #333; 12 | background: #f8f8f8; 13 | -webkit-text-size-adjust: none; 14 | } 15 | 16 | .hljs-comment, 17 | .diff .hljs-header, 18 | .hljs-javadoc { 19 | color: #998; 20 | font-style: italic; 21 | } 22 | 23 | .hljs-keyword, 24 | .css .rule .hljs-keyword, 25 | .hljs-winutils, 26 | .nginx .hljs-title, 27 | .hljs-subst, 28 | .hljs-request, 29 | .hljs-status { 30 | color: #1184CE; 31 | } 32 | 33 | .hljs-number, 34 | .hljs-hexcolor, 35 | .ruby .hljs-constant { 36 | color: #ed225d; 37 | } 38 | 39 | .hljs-string, 40 | .hljs-tag .hljs-value, 41 | .hljs-phpdoc, 42 | .hljs-dartdoc, 43 | .tex .hljs-formula { 44 | color: #ed225d; 45 | } 46 | 47 | .hljs-title, 48 | .hljs-id, 49 | .scss .hljs-preprocessor { 50 | color: #900; 51 | font-weight: bold; 52 | } 53 | 54 | .hljs-list .hljs-keyword, 55 | .hljs-subst { 56 | font-weight: normal; 57 | } 58 | 59 | .hljs-class .hljs-title, 60 | .hljs-type, 61 | .vhdl .hljs-literal, 62 | .tex .hljs-command { 63 | color: #458; 64 | font-weight: bold; 65 | } 66 | 67 | .hljs-tag, 68 | .hljs-tag .hljs-title, 69 | .hljs-rules .hljs-property, 70 | .django .hljs-tag .hljs-keyword { 71 | color: #000080; 72 | font-weight: normal; 73 | } 74 | 75 | .hljs-attribute, 76 | .hljs-variable, 77 | .lisp .hljs-body { 78 | color: #008080; 79 | } 80 | 81 | .hljs-regexp { 82 | color: #009926; 83 | } 84 | 85 | .hljs-symbol, 86 | .ruby .hljs-symbol .hljs-string, 87 | .lisp .hljs-keyword, 88 | .clojure .hljs-keyword, 89 | .scheme .hljs-keyword, 90 | .tex .hljs-special, 91 | .hljs-prompt { 92 | color: #990073; 93 | } 94 | 95 | .hljs-built_in { 96 | color: #0086b3; 97 | } 98 | 99 | .hljs-preprocessor, 100 | .hljs-pragma, 101 | .hljs-pi, 102 | .hljs-doctype, 103 | .hljs-shebang, 104 | .hljs-cdata { 105 | color: #999; 106 | font-weight: bold; 107 | } 108 | 109 | .hljs-deletion { 110 | background: #fdd; 111 | } 112 | 113 | .hljs-addition { 114 | background: #dfd; 115 | } 116 | 117 | .diff .hljs-change { 118 | background: #0086b3; 119 | } 120 | 121 | .hljs-chunk { 122 | color: #aaa; 123 | } 124 | -------------------------------------------------------------------------------- /docgen/custom_theme/assets/images/colormaps.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Pixpipe/quickvoxelcore/88e0bfec82b3bf497cd091dbee2e8284867a440b/docgen/custom_theme/assets/images/colormaps.png -------------------------------------------------------------------------------- /docgen/custom_theme/assets/images/double1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Pixpipe/quickvoxelcore/88e0bfec82b3bf497cd091dbee2e8284867a440b/docgen/custom_theme/assets/images/double1.png -------------------------------------------------------------------------------- /docgen/custom_theme/assets/images/double2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Pixpipe/quickvoxelcore/88e0bfec82b3bf497cd091dbee2e8284867a440b/docgen/custom_theme/assets/images/double2.png -------------------------------------------------------------------------------- /docgen/custom_theme/assets/images/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Pixpipe/quickvoxelcore/88e0bfec82b3bf497cd091dbee2e8284867a440b/docgen/custom_theme/assets/images/favicon.png -------------------------------------------------------------------------------- /docgen/custom_theme/assets/images/qv_logo.afdesign: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Pixpipe/quickvoxelcore/88e0bfec82b3bf497cd091dbee2e8284867a440b/docgen/custom_theme/assets/images/qv_logo.afdesign -------------------------------------------------------------------------------- /docgen/custom_theme/assets/images/qv_logo_cube.afdesign: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Pixpipe/quickvoxelcore/88e0bfec82b3bf497cd091dbee2e8284867a440b/docgen/custom_theme/assets/images/qv_logo_cube.afdesign -------------------------------------------------------------------------------- /docgen/custom_theme/assets/images/qv_logo_cube.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Pixpipe/quickvoxelcore/88e0bfec82b3bf497cd091dbee2e8284867a440b/docgen/custom_theme/assets/images/qv_logo_cube.png -------------------------------------------------------------------------------- /docgen/custom_theme/assets/images/qv_logo_horizontal.afdesign: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Pixpipe/quickvoxelcore/88e0bfec82b3bf497cd091dbee2e8284867a440b/docgen/custom_theme/assets/images/qv_logo_horizontal.afdesign -------------------------------------------------------------------------------- /docgen/custom_theme/assets/images/qv_logo_horizontal.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Pixpipe/quickvoxelcore/88e0bfec82b3bf497cd091dbee2e8284867a440b/docgen/custom_theme/assets/images/qv_logo_horizontal.png -------------------------------------------------------------------------------- /docgen/custom_theme/assets/images/simple.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Pixpipe/quickvoxelcore/88e0bfec82b3bf497cd091dbee2e8284867a440b/docgen/custom_theme/assets/images/simple.png -------------------------------------------------------------------------------- /docgen/custom_theme/assets/images/test.afdesign: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Pixpipe/quickvoxelcore/88e0bfec82b3bf497cd091dbee2e8284867a440b/docgen/custom_theme/assets/images/test.afdesign -------------------------------------------------------------------------------- /docgen/custom_theme/assets/name_1000.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Pixpipe/quickvoxelcore/88e0bfec82b3bf497cd091dbee2e8284867a440b/docgen/custom_theme/assets/name_1000.png -------------------------------------------------------------------------------- /docgen/custom_theme/assets/site.js: -------------------------------------------------------------------------------- 1 | /* global anchors */ 2 | 3 | // add anchor links to headers 4 | anchors.options.placement = 'left'; 5 | anchors.add('h3'); 6 | 7 | // Filter UI 8 | var tocElements = document.getElementById('toc').getElementsByTagName('li'); 9 | 10 | document.getElementById('filter-input').addEventListener('keyup', function(e) { 11 | var i, element, children; 12 | 13 | // enter key 14 | if (e.keyCode === 13) { 15 | // go to the first displayed item in the toc 16 | for (i = 0; i < tocElements.length; i++) { 17 | element = tocElements[i]; 18 | if (!element.classList.contains('display-none')) { 19 | location.replace(element.firstChild.href); 20 | return e.preventDefault(); 21 | } 22 | } 23 | } 24 | 25 | var match = function() { 26 | return true; 27 | }; 28 | 29 | var value = this.value.toLowerCase(); 30 | 31 | if (!value.match(/^\s*$/)) { 32 | match = function(element) { 33 | var html = element.firstChild.innerHTML; 34 | return html && html.toLowerCase().indexOf(value) !== -1; 35 | }; 36 | } 37 | 38 | for (i = 0; i < tocElements.length; i++) { 39 | element = tocElements[i]; 40 | children = Array.from(element.getElementsByTagName('li')); 41 | if (match(element) || children.some(match)) { 42 | element.classList.remove('display-none'); 43 | } else { 44 | element.classList.add('display-none'); 45 | } 46 | } 47 | }); 48 | 49 | var items = document.getElementsByClassName('toggle-sibling'); 50 | for (var j = 0; j < items.length; j++) { 51 | items[j].addEventListener('click', toggleSibling); 52 | } 53 | 54 | function toggleSibling() { 55 | var stepSibling = this.parentNode.getElementsByClassName('toggle-target')[0]; 56 | var icon = this.getElementsByClassName('icon')[0]; 57 | var klass = 'display-none'; 58 | if (stepSibling.classList.contains(klass)) { 59 | stepSibling.classList.remove(klass); 60 | icon.innerHTML = '▾'; 61 | } else { 62 | stepSibling.classList.add(klass); 63 | icon.innerHTML = '▸'; 64 | } 65 | } 66 | 67 | function showHashTarget(targetId) { 68 | if (targetId) { 69 | var hashTarget = document.getElementById(targetId); 70 | // new target is hidden 71 | if ( 72 | hashTarget && 73 | hashTarget.offsetHeight === 0 && 74 | hashTarget.parentNode.parentNode.classList.contains('display-none') 75 | ) { 76 | hashTarget.parentNode.parentNode.classList.remove('display-none'); 77 | } 78 | } 79 | } 80 | 81 | function scrollIntoView(targetId) { 82 | // Only scroll to element if we don't have a stored scroll position. 83 | if (targetId && !history.state) { 84 | var hashTarget = document.getElementById(targetId); 85 | if (hashTarget) { 86 | hashTarget.scrollIntoView(); 87 | } 88 | } 89 | } 90 | 91 | function gotoCurrentTarget() { 92 | showHashTarget(location.hash.substring(1)); 93 | scrollIntoView(location.hash.substring(1)); 94 | } 95 | 96 | window.addEventListener('hashchange', gotoCurrentTarget); 97 | gotoCurrentTarget(); 98 | 99 | var toclinks = document.getElementsByClassName('pre-open'); 100 | for (var k = 0; k < toclinks.length; k++) { 101 | toclinks[k].addEventListener('mousedown', preOpen, false); 102 | } 103 | 104 | function preOpen() { 105 | showHashTarget(this.hash.substring(1)); 106 | } 107 | 108 | var split_left = document.querySelector('#split-left'); 109 | var split_right = document.querySelector('#split-right'); 110 | var split_parent = split_left.parentNode; 111 | var cw_with_sb = split_left.clientWidth; 112 | split_left.style.overflow = 'hidden'; 113 | var cw_without_sb = split_left.clientWidth; 114 | split_left.style.overflow = ''; 115 | 116 | Split(['#split-left', '#split-right'], { 117 | elementStyle: function(dimension, size, gutterSize) { 118 | return { 119 | 'flex-basis': 'calc(' + size + '% - ' + gutterSize + 'px)' 120 | }; 121 | }, 122 | gutterStyle: function(dimension, gutterSize) { 123 | return { 124 | 'flex-basis': gutterSize + 'px' 125 | }; 126 | }, 127 | gutterSize: 20, 128 | sizes: [20, 80] 129 | }); 130 | 131 | // Chrome doesn't remember scroll position properly so do it ourselves. 132 | // Also works on Firefox and Edge. 133 | 134 | function updateState() { 135 | history.replaceState( 136 | { 137 | left_top: split_left.scrollTop, 138 | right_top: split_right.scrollTop 139 | }, 140 | document.title 141 | ); 142 | } 143 | 144 | function loadState(ev) { 145 | if (ev) { 146 | // Edge doesn't replace change history.state on popstate. 147 | history.replaceState(ev.state, document.title); 148 | } 149 | if (history.state) { 150 | split_left.scrollTop = history.state.left_top; 151 | split_right.scrollTop = history.state.right_top; 152 | } 153 | } 154 | 155 | window.addEventListener('load', function() { 156 | // Restore after Firefox scrolls to hash. 157 | setTimeout(function() { 158 | loadState(); 159 | // Update with initial scroll position. 160 | updateState(); 161 | // Update scroll positions only after we've loaded because Firefox 162 | // emits an initial scroll event with 0. 163 | split_left.addEventListener('scroll', updateState); 164 | split_right.addEventListener('scroll', updateState); 165 | }, 1); 166 | }); 167 | 168 | window.addEventListener('popstate', loadState); 169 | -------------------------------------------------------------------------------- /docgen/custom_theme/assets/split.css: -------------------------------------------------------------------------------- 1 | .gutter { 2 | background-color: #f5f5f5; 3 | background-repeat: no-repeat; 4 | background-position: 50%; 5 | } 6 | 7 | .gutter.gutter-vertical { 8 | background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAB4AAAAFAQMAAABo7865AAAABlBMVEVHcEzMzMzyAv2sAAAAAXRSTlMAQObYZgAAABBJREFUeF5jOAMEEAIEEFwAn3kMwcB6I2AAAAAASUVORK5CYII='); 9 | cursor: ns-resize; 10 | } 11 | 12 | .gutter.gutter-horizontal { 13 | background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAeCAYAAADkftS9AAAAIklEQVQoU2M4c+bMfxAGAgYYmwGrIIiDjrELjpo5aiZeMwF+yNnOs5KSvgAAAABJRU5ErkJggg=='); 14 | cursor: ew-resize; 15 | } 16 | -------------------------------------------------------------------------------- /docgen/custom_theme/assets/style.css: -------------------------------------------------------------------------------- 1 | .documentation { 2 | font-family: Helvetica, sans-serif; 3 | color: #666; 4 | line-height: 1.5; 5 | background: #f5f5f5; 6 | } 7 | 8 | .black { 9 | color: #666; 10 | } 11 | 12 | .bg-white { 13 | background-color: #fff; 14 | } 15 | 16 | h4 { 17 | margin: 20px 0 10px 0; 18 | } 19 | 20 | .documentation h3 { 21 | color: #000; 22 | } 23 | 24 | .border-bottom { 25 | border-color: #ddd; 26 | } 27 | 28 | /* JO */ 29 | a { 30 | color: #4bbd87; 31 | text-decoration: none; 32 | } 33 | 34 | /* JO */ 35 | #split-left { 36 | background: #FFF; 37 | } 38 | 39 | /* JO */ 40 | .keyline-top-not { 41 | background: #FFF; 42 | margin-bottom: 2em; 43 | } 44 | 45 | .documentation a[href]:hover { 46 | text-decoration: underline; 47 | } 48 | 49 | a:hover { 50 | cursor: pointer; 51 | } 52 | 53 | .py1-ul li { 54 | padding: 5px 0; 55 | } 56 | 57 | .max-height-100 { 58 | max-height: 100%; 59 | } 60 | 61 | .height-viewport-100 { 62 | height: 100vh; 63 | } 64 | 65 | section:target h3 { 66 | font-weight:700; 67 | } 68 | 69 | .documentation td, 70 | .documentation th { 71 | padding: .25rem .25rem; 72 | } 73 | 74 | h1:hover .anchorjs-link, 75 | h2:hover .anchorjs-link, 76 | h3:hover .anchorjs-link, 77 | h4:hover .anchorjs-link { 78 | opacity: 1; 79 | } 80 | 81 | .fix-3 { 82 | width: 25%; 83 | max-width: 244px; 84 | } 85 | 86 | .fix-3 { 87 | width: 25%; 88 | max-width: 244px; 89 | } 90 | 91 | @media (min-width: 52em) { 92 | .fix-margin-3 { 93 | margin-left: 25%; 94 | } 95 | } 96 | 97 | .pre, pre, code, .code { 98 | font-family: Source Code Pro,Menlo,Consolas,Liberation Mono,monospace; 99 | font-size: 14px; 100 | } 101 | 102 | .fill-light { 103 | background: #F9F9F9; 104 | } 105 | 106 | .width2 { 107 | width: 1rem; 108 | } 109 | 110 | .input { 111 | font-family: inherit; 112 | display: block; 113 | width: 100%; 114 | height: 2rem; 115 | padding: .5rem; 116 | margin-bottom: 1rem; 117 | border: 1px solid #ccc; 118 | font-size: .875rem; 119 | border-radius: 3px; 120 | box-sizing: border-box; 121 | } 122 | 123 | table { 124 | border-collapse: collapse; 125 | } 126 | 127 | .prose table th, 128 | .prose table td { 129 | text-align: left; 130 | padding:8px; 131 | border:1px solid #ddd; 132 | } 133 | 134 | .prose table th:nth-child(1) { border-right: none; } 135 | .prose table th:nth-child(2) { border-left: none; } 136 | 137 | .prose table { 138 | border:1px solid #ddd; 139 | } 140 | 141 | .prose-big { 142 | font-size: 18px; 143 | line-height: 30px; 144 | } 145 | 146 | .quiet { 147 | opacity: 0.7; 148 | } 149 | 150 | .minishadow { 151 | box-shadow: 2px 2px 10px #f3f3f3; 152 | } 153 | 154 | 155 | textarea, input, button { outline: none; } 156 | 157 | .width100pc { 158 | width: 100%; 159 | } 160 | 161 | p code { 162 | padding: 2px 4px; 163 | border-radius: 3px; 164 | background: #f5f5f5; 165 | font-family: monospace; 166 | } 167 | -------------------------------------------------------------------------------- /docgen/custom_theme/index._: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | <%- config['project-name'] %> <%- config['project-version'] %> | Documentation 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 |
17 |
18 |

<%- config['project-name'] %>

19 |
v<%- config['project-version'] %>
20 | 25 |
26 |
    27 | <% docs.forEach(function(doc) { %> 28 | <% var hasMembers = doc.members.static.length || doc.members.instance.length %> 29 |
  • 32 | <%- doc.name %> 33 | <% if (hasMembers) { %><% } %> 34 | 35 | <% if (hasMembers) { %> 36 | 86 | <% } %> 87 |
  • 88 | <% }) %> 89 |
90 |
91 |
92 | See on GitHub 93 |
94 |
95 |
96 |
97 | <% docs.forEach(function(s) { %> 98 | <% if (s.kind !== 'note') { %> 99 | <%= renderSection({ 100 | section: s, 101 | renderSection: renderSection, 102 | renderSectionList: renderSectionList, 103 | renderParamProperty: renderParamProperty 104 | }) %> 105 | <% } else { %> 106 |
<%=renderNote({ note: s })%>
107 | <% } %> 108 | <% }) %> 109 |
110 |
111 | 112 | 113 | 114 | 115 | 116 | -------------------------------------------------------------------------------- /docgen/custom_theme/index.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var fs = require('fs'), 4 | path = require('path'), 5 | File = require('vinyl'), 6 | vfs = require('vinyl-fs'), 7 | _ = require('lodash'), 8 | concat = require('concat-stream'), 9 | GithubSlugger = require('github-slugger'), 10 | createFormatters = require('documentation').util.createFormatters, 11 | LinkerStack = require('documentation').util.LinkerStack, 12 | hljs = require('highlight.js'); 13 | 14 | function isFunction(section) { 15 | return section.kind === 'function' || section.kind === 'typedef' && section.type.type === 'NameExpression' && section.type.name === 'Function'; 16 | } 17 | 18 | module.exports = function (comments, config) { 19 | var linkerStack = new LinkerStack(config).namespaceResolver(comments, function (namespace) { 20 | var slugger = new GithubSlugger(); 21 | return '#' + slugger.slug(namespace); 22 | }); 23 | 24 | var formatters = createFormatters(linkerStack.link); 25 | 26 | hljs.configure(config.hljs || {}); 27 | 28 | var sharedImports = { 29 | imports: { 30 | slug(str) { 31 | var slugger = new GithubSlugger(); 32 | return slugger.slug(str); 33 | }, 34 | shortSignature(section) { 35 | var prefix = ''; 36 | if (section.kind === 'class') { 37 | prefix = 'new '; 38 | } else if (!isFunction(section)) { 39 | return section.name; 40 | } 41 | return prefix + section.name + formatters.parameters(section, true); 42 | }, 43 | signature(section) { 44 | var returns = ''; 45 | var prefix = ''; 46 | if (section.kind === 'class') { 47 | prefix = 'new '; 48 | } else if (!isFunction(section)) { 49 | return section.name; 50 | } 51 | if (section.returns.length) { 52 | returns = ': ' + formatters.type(section.returns[0].type); 53 | } 54 | return prefix + section.name + formatters.parameters(section) + returns; 55 | }, 56 | md(ast, inline) { 57 | if (inline && ast && ast.children.length && ast.children[0].type === 'paragraph') { 58 | ast = { 59 | type: 'root', 60 | children: ast.children[0].children.concat(ast.children.slice(1)) 61 | }; 62 | } 63 | return formatters.markdown(ast); 64 | }, 65 | formatType: formatters.type, 66 | autolink: formatters.autolink, 67 | highlight(example) { 68 | if (config.hljs && config.hljs.highlightAuto) { 69 | return hljs.highlightAuto(example).value; 70 | } 71 | return hljs.highlight('js', example).value; 72 | } 73 | } 74 | }; 75 | 76 | sharedImports.imports.renderSectionList = _.template(fs.readFileSync(path.join(__dirname, 'section_list._'), 'utf8'), sharedImports); 77 | sharedImports.imports.renderSection = _.template(fs.readFileSync(path.join(__dirname, 'section._'), 'utf8'), sharedImports); 78 | sharedImports.imports.renderNote = _.template(fs.readFileSync(path.join(__dirname, 'note._'), 'utf8'), sharedImports); 79 | sharedImports.imports.renderParamProperty = _.template(fs.readFileSync(path.join(__dirname, 'paramProperty._'), 'utf8'), sharedImports); 80 | 81 | var pageTemplate = _.template(fs.readFileSync(path.join(__dirname, 'index._'), 'utf8'), sharedImports); 82 | 83 | // push assets into the pipeline as well. 84 | return new Promise(resolve => { 85 | vfs.src([__dirname + '/assets/**'], { base: __dirname }).pipe(concat(function (files) { 86 | resolve(files.concat(new File({ 87 | path: 'index.html', 88 | contents: new Buffer(pageTemplate({ 89 | docs: comments, 90 | config 91 | }), 'utf8') 92 | }))); 93 | })); 94 | }); 95 | }; 96 | -------------------------------------------------------------------------------- /docgen/custom_theme/note._: -------------------------------------------------------------------------------- 1 |
2 | 3 | 8 | 9 | <% if (note.description) { %> 10 | <%= md(note.description) %> 11 | <% } %> 12 |
13 | -------------------------------------------------------------------------------- /docgen/custom_theme/paramProperty._: -------------------------------------------------------------------------------- 1 | 2 | <%- property.name %> <%= formatType(property.type) %> 3 | <% if (property.default) { %> 4 | (default <%- property.default %>) 5 | <% } %> 6 | <%= md(property.description, true) %> 7 | 8 | <% if(property.properties && property.properties.length) { %> 9 | <% property.properties.forEach(function(childProperty) { %> 10 | <%= renderParamProperty({ 11 | property: childProperty, 12 | renderParamProperty: renderParamProperty 13 | }) %> 14 | <% }) %> 15 | <% } %> 16 | -------------------------------------------------------------------------------- /docgen/custom_theme/section._: -------------------------------------------------------------------------------- 1 |
2 | 3 | <% if (typeof nested === 'undefined' || (section.context && section.context.github)) { %> 4 |
5 | <% if (typeof nested === 'undefined') { %> 6 |

7 | <%- section.name %> 8 |

9 | <% } %> 10 | <% if (section.context && section.context.github) { %> 11 | 12 | <%= section.context.github.path %> 13 | 14 | <% } %> 15 |
16 | <% } %> 17 | 18 | <%= md(section.description) %> 19 | 20 |
<%= signature(section) %>
21 | <% if (section.type) { %> 22 |

23 | Type: 24 | <%= formatType(section.type) %> 25 |

26 | <% } %> 27 | <% if (section.augments.length) { %> 28 |

29 | Extends 30 | <% if (section.augments) { %> 31 | <%= section.augments.map(function(tag) { 32 | return autolink(tag.name); 33 | }).join(', ') %> 34 | <% } %> 35 |

36 | <% } %> 37 | 38 | <% if (section.deprecated) { %>
Deprecated: <%= md(section.deprecated, true) %>
<% }%> 39 | <% if (section.version) { %>
Version: <%- section.version %>
<% }%> 40 | <% if (section.license) { %>
License: <%- section.license %>
<% }%> 41 | <% if (section.author) { %>
Author: <%- section.author %>
<% }%> 42 | <% if (section.copyright) { %>
Copyright: <%= md(section.copyright, true) %>
<% }%> 43 | <% if (section.since) { %>
Since: <%- section.since %>
<% }%> 44 | 45 | <% if (section.params.length) { %> 46 |
Parameters
47 |
48 | <% section.params.forEach(function(param) { %> 49 |
50 |
51 | <%- param.name%> (<%= formatType(param.type) %><% if (param.default) { %> 52 | = <%- param.default %><% } %>) 53 | <%= md(param.description, true) %> 54 |
55 | <% if (param.properties && param.properties.length) { %> 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | <% param.properties.forEach(function(property) { %> 69 | <%= renderParamProperty({ 70 | property: property, 71 | renderParamProperty: renderParamProperty 72 | }) %> 73 | <% }) %> 74 | 75 |
NameDescription
76 | <% } %> 77 |
78 | <% }) %> 79 |
80 | <% } %> 81 | 82 | <% if (section.properties.length) { %> 83 |
Properties
84 |
85 | <% section.properties.forEach(function(property) { %> 86 |
87 | <%- property.name%> (<%= formatType(property.type) %>) 88 | <% if (property.default) { %> 89 | (default <%- property.default %>) 90 | <% } %><% if (property.description) { 91 | %>: <%= md(property.description, true) %><% 92 | } %> 93 | <% if (property.properties && property.properties.length) { %> 94 |
    95 | <% property.properties.forEach(function(property) { %> 96 |
  • <%- property.name %> <%= formatType(property.type) %> 97 | <% if (property.default) { %> 98 | (default <%- property.default %>) 99 | <% } %> 100 | <%= md(property.description) %>
  • 101 | <% }) %> 102 |
103 | <% } %> 104 |
105 | <% }) %> 106 |
107 | <% } %> 108 | 109 | <% if (section.returns.length) { %> 110 | <% section.returns.forEach(function(ret) { %> 111 |
Returns
112 | <%= formatType(ret.type) %><% if (ret.description) { %>: 113 | <%= md(ret.description, true) %> 114 | <% }%> 115 | <% }) %> 116 | <% } %> 117 | 118 | <% if (section.throws.length) { %> 119 |
Throws
120 |
    121 | <% section.throws.forEach(function(throws) { %> 122 |
  • <%= formatType(throws.type) %>: <%= md(throws.description, true) %>
  • 123 | <% }); %> 124 |
125 | <% } %> 126 | 127 | <% if (section.examples.length) { %> 128 |
Example
129 | <% section.examples.forEach(function(example) { %> 130 | <% if (example.caption) { %>

<%= md(example.caption) %>

<% } %> 131 |
<%= highlight(example.description) %>
132 | <% }) %> 133 | <% } %> 134 | 135 | <% if (section.members.static && section.members.static.length) { %> 136 |
Static Members
137 | <%= renderSectionList({ members: section.members.static, renderSection: renderSection, renderParamProperty: renderParamProperty, noun: 'Static Member' }) %> 138 | <% } %> 139 | 140 | <% if (section.members.instance && section.members.instance.length) { %> 141 |
Instance Members
142 | <%= renderSectionList({ members: section.members.instance, renderSection: renderSection, renderParamProperty: renderParamProperty, noun: 'Instance Member' }) %> 143 | <% } %> 144 | 145 | <% if (section.members.events && section.members.events.length) { %> 146 |
Events
147 | <%= renderSectionList({ members: section.members.events, renderSection: renderSection, renderParamProperty: renderParamProperty, noun: 'Event' }) %> 148 | <% } %> 149 |
150 | -------------------------------------------------------------------------------- /docgen/custom_theme/section_list._: -------------------------------------------------------------------------------- 1 |
2 | <% members.forEach(function(member) { %> 3 |
4 |
5 |
6 | 7 | <%= shortSignature(member) %> 8 |
9 |
10 | 18 |
19 | <% }) %> 20 |
21 | -------------------------------------------------------------------------------- /examples/_doubleRotateCamCrew.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | Double Rotate Camera Crew 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 64 | 65 | 66 | 67 | -------------------------------------------------------------------------------- /examples/_simpleCamCrew.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | Simple Camera Crew 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 38 | 39 | 40 | 41 | -------------------------------------------------------------------------------- /examples/axes.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | Axes 4 | 5 | 6 | 7 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 83 | 84 | 85 | 86 | -------------------------------------------------------------------------------- /examples/chosecamera.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | Choose Camera 4 | 5 | 6 | 54 | 55 | 56 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 |
74 |
perspective
75 |
axial
76 |
coronal
77 |
sagittal
78 |
79 | 80 | 241 | 242 | 243 | 244 | -------------------------------------------------------------------------------- /examples/colormaps.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | Colormap 4 | 5 | 22 | 23 | 24 | 25 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 |
44 | 45 | 93 | 94 | 95 | 96 | -------------------------------------------------------------------------------- /examples/css/main.css: -------------------------------------------------------------------------------- 1 | body { 2 | overflow: hidden; 3 | width: 100%; 4 | height: 100%; 5 | margin: 0; 6 | font-family: monospace; 7 | } 8 | 9 | a { 10 | text-decoration: none; 11 | color: #FF91D7; 12 | } 13 | 14 | code { 15 | background: #d6ffec; 16 | padding: 2px 6px 2px 6px; 17 | border-radius: 3px; 18 | color: #256948; 19 | } 20 | 21 | #renderCanvas { 22 | width: 100%; 23 | height: 100%; 24 | } 25 | 26 | #spinner { 27 | display: none; 28 | pointer-events: none; 29 | position: absolute; 30 | width: 100px; 31 | height: 100px; 32 | background: #ffffff; 33 | border-radius: 50%; 34 | padding: 15px; 35 | bottom: 0; 36 | left: 0; 37 | right: 0; 38 | margin: auto; 39 | top: 0; 40 | -webkit-box-shadow: 0px 0px 43px 0px rgba(0,0,0,0.19); 41 | -moz-box-shadow: 0px 0px 43px 0px rgba(0,0,0,0.19); 42 | box-shadow: 0px 0px 43px 0px rgba(0,0,0,0.19); 43 | } 44 | 45 | #fileInput { 46 | /*position: absolute; 47 | margin: 10px;*/ 48 | } 49 | 50 | #info { 51 | pointer-events: none; 52 | position: fixed; 53 | width: 100vw; 54 | height: 10vh; 55 | background: rgba(255, 255, 255, 0.75); 56 | color: #5a5a5a; 57 | bottom: 0; 58 | font-size: 2em; 59 | text-align: center; 60 | line-height: 10vh; 61 | } 62 | 63 | 64 | #header { 65 | position: fixed; 66 | top: 0; 67 | left: 0; 68 | right: 0; 69 | width: 100vw; 70 | background-color: white; 71 | display: inline; 72 | } 73 | 74 | #header img { 75 | width: 230px; 76 | padding: 10px; 77 | } 78 | 79 | #header .description { 80 | float: right; 81 | width: calc(100vw - 270px); 82 | text-align: right; 83 | padding: 17px 15px 15px 0px; 84 | } 85 | 86 | #header a { 87 | color: #27dd85; 88 | } 89 | -------------------------------------------------------------------------------- /examples/double.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | Double 4 | 5 | 6 | 7 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 73 | 74 | 75 | 76 | -------------------------------------------------------------------------------- /examples/doubleRotate.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | Double Rotate 4 | 5 | 6 | 7 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 78 | 79 | 80 | 81 | -------------------------------------------------------------------------------- /examples/doubleSpinner.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | Double Spinner 4 | 5 | 6 | 7 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 95 | 96 | 97 | 98 | -------------------------------------------------------------------------------- /examples/doubleTranslate.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | Double Translate 4 | 5 | 6 | 7 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 84 | 85 | 86 | 87 | -------------------------------------------------------------------------------- /examples/doubleTranslateCameraCrew.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | Double Translate Camera Crew 4 | 5 | 6 | 7 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 |
23 | 24 | 25 | 100 | 101 | 102 | 103 | -------------------------------------------------------------------------------- /examples/images/lego_spinner.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Pixpipe/quickvoxelcore/88e0bfec82b3bf497cd091dbee2e8284867a440b/examples/images/lego_spinner.gif -------------------------------------------------------------------------------- /examples/js/addsourcelink.js: -------------------------------------------------------------------------------- 1 | let sourcelinkEl = document.getElementById('sourcelink') 2 | let repoBaseUrl = 'https://github.com/Pixpipe/quickvoxelcore/blob/master/examples/' 3 | let filenameSplit = window.location.pathname.split('/') 4 | let basename = filenameSplit[filenameSplit.length-1] 5 | 6 | sourcelinkEl.href = repoBaseUrl + basename 7 | 8 | 9 | // evaluate boolean 10 | function bool(v){ return v==="false" || v==="null" || v==="NaN" || v==="undefined" || v==="0" ? false : !!v; } 11 | 12 | // hides the header with a GET argument (convenient for iframed demos) 13 | var url = new URL(window.location.href) 14 | var hideheader = bool(url.searchParams.get("hideheader")) 15 | 16 | if (hideheader) { 17 | document.getElementById('header').style.display = 'none' 18 | } 19 | -------------------------------------------------------------------------------- /examples/oblique.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | Oblique 4 | 5 | 6 | 7 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 62 | 63 | 64 | 65 | -------------------------------------------------------------------------------- /examples/oblique2.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | Oblique 4 | 5 | 6 | 7 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 63 | 64 | 65 | 66 | -------------------------------------------------------------------------------- /examples/simple.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | Simple 4 | 5 | 6 | 7 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 57 | 58 | 59 | 60 | -------------------------------------------------------------------------------- /examples/simpleFile.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | Simple File 4 | 5 | 6 | 7 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 67 | 68 | 69 | 70 | -------------------------------------------------------------------------------- /examples/simpleSpinner.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | Simple Spinner 4 | 5 | 6 | 7 | 8 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 70 | 71 | 72 | 73 | -------------------------------------------------------------------------------- /examples/time.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | Time 4 | 5 | 6 | 7 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 81 | 82 | 83 | 84 | -------------------------------------------------------------------------------- /examples/translate.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | Translate 4 | 5 | 6 | 7 | 8 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 59 | 60 | 61 | 62 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "quickvoxelcore", 3 | "version": "0.1.6", 4 | "description": "The core for QuickVoxel app", 5 | "homepage": "https://github.com/Pixpipe/quickvoxelcore", 6 | "repository": "jonathanlurie/quickvoxelcore", 7 | "moduleName": "quickvoxelcore", 8 | "entry": "src/main.js", 9 | "main": "dist/quickvoxelcore.js", 10 | "es6": "dist/quickvoxelcore.es6.js", 11 | "min": "dist/quickvoxelcore.min.js", 12 | "scripts": { 13 | "test": "echo \"Error: no test specified\" && exit 1", 14 | "build": "rollup -c", 15 | "dev": "serve . & rollup -w -c rollup.config.dev.js", 16 | "doc": "documentation build src/main.js --project-name 'Quickvoxel Core' --config ./docgen/config.yml --sort-order 'alpha' --theme ./docgen/custom_theme/ -o ./doc/ -f html; documentation build src/main.js --project-name 'Quickvoxel Core' --config ./docgen/config.yml --sort-order 'alpha' -f md > documentation.md", 17 | "lintfix": "standard --fix src/**/*.js", 18 | "lint": "standard src/**/*.js" 19 | }, 20 | "author": "Jonathan Lurie", 21 | "license": "MIT", 22 | "devDependencies": { 23 | "babel-core": "^6.26.0", 24 | "babel-plugin-external-helpers": "^6.22.0", 25 | "babel-preset-es2015-rollup": "^3.0.0", 26 | "babylonjs": "^3.2.0-rc.2", 27 | "documentation": "^6.1.0", 28 | "pixpipe": "^0.2.0", 29 | "rollup": "^0.57.0", 30 | "rollup-plugin-babel": "^3.0.2", 31 | "rollup-plugin-commonjs": "^9.1.0", 32 | "rollup-plugin-glsl": "^1.2.0", 33 | "rollup-plugin-node-builtins": "^2.1.2", 34 | "rollup-plugin-node-globals": "^1.1.0", 35 | "rollup-plugin-node-resolve": "^3.0.0", 36 | "rollup-plugin-replace": "^2.0.0", 37 | "rollup-plugin-uglify": "^3.0.0", 38 | "serve": "^6.3.1", 39 | "standard": "^11.0.1" 40 | }, 41 | "dependencies": {} 42 | } 43 | -------------------------------------------------------------------------------- /rollup.config.dev.js: -------------------------------------------------------------------------------- 1 | import pkg from './package.json' 2 | 3 | /* 4 | The dev version of the Rollup config does not transpile to ES5 5 | and outputs a single umd package. 6 | */ 7 | 8 | import commonjs from 'rollup-plugin-commonjs' 9 | import nodeResolve from 'rollup-plugin-node-resolve' 10 | import builtins from 'rollup-plugin-node-builtins' 11 | import globals from 'rollup-plugin-node-globals' 12 | import glsl from 'rollup-plugin-glsl' 13 | import replace from 'rollup-plugin-replace' 14 | 15 | export default [ 16 | { 17 | input: pkg.entry, 18 | output: { 19 | file: pkg.es6, 20 | name: pkg.name, 21 | sourcemap: true, 22 | format: 'umd' 23 | }, 24 | 25 | plugins: [ 26 | replace({ 27 | exclude: 'node_modules/**', 28 | delimiters: ['<@', '@>'], 29 | APP_NAME: pkg.name, 30 | APP_VERSION: pkg.version 31 | }), 32 | nodeResolve({ 33 | preferBuiltins: false 34 | }), 35 | commonjs(), 36 | globals(), 37 | builtins(), 38 | glsl({ 39 | include: 'src/shaders/*.glsl', 40 | }) 41 | ] 42 | } 43 | ]; 44 | -------------------------------------------------------------------------------- /rollup.config.js: -------------------------------------------------------------------------------- 1 | import pkg from './package.json' 2 | 3 | import builtins from 'rollup-plugin-node-builtins' 4 | import globals from 'rollup-plugin-node-globals' 5 | import commonjs from 'rollup-plugin-commonjs' 6 | import nodeResolve from 'rollup-plugin-node-resolve' 7 | import babel from 'rollup-plugin-babel' 8 | import uglify from 'rollup-plugin-uglify' 9 | import glsl from 'rollup-plugin-glsl' 10 | import replace from 'rollup-plugin-replace' 11 | 12 | export default [ 13 | 14 | // bundle UMD ES6 15 | { 16 | input: pkg.entry, 17 | output: { 18 | file: pkg.es6, 19 | name: pkg.name, 20 | sourcemap: true, 21 | format: 'umd' 22 | }, 23 | 24 | plugins: [ 25 | replace({ 26 | exclude: 'node_modules/**', 27 | delimiters: ['<@', '@>'], 28 | APP_NAME: pkg.name, 29 | APP_VERSION: pkg.version 30 | }), 31 | nodeResolve({ 32 | preferBuiltins: false 33 | }), 34 | commonjs(), 35 | globals(), 36 | builtins(), 37 | glsl({ 38 | include: 'src/shaders/*.glsl', 39 | }) 40 | ] 41 | }, 42 | 43 | // bundle UMD ES5 44 | { 45 | input: pkg.entry, 46 | output: { 47 | file: pkg.main, 48 | name: pkg.name, 49 | sourcemap: true, 50 | format: 'umd' 51 | }, 52 | 53 | plugins: [ 54 | replace({ 55 | exclude: 'node_modules/**', 56 | delimiters: ['<@', '@>'], 57 | APP_NAME: pkg.name, 58 | APP_VERSION: pkg.version 59 | }), 60 | nodeResolve({ 61 | preferBuiltins: false 62 | }), 63 | commonjs({ include: 'node_modules/**' }), // so Rollup can convert other modules to ES module 64 | globals(), 65 | builtins(), 66 | glsl({ 67 | include: 'src/shaders/*.glsl', 68 | }), 69 | babel({ 70 | exclude: 'node_modules/**', 71 | babelrc: false, 72 | presets: [ 'es2015-rollup' ] 73 | }) 74 | ] 75 | }, 76 | 77 | // bundle UMD ES5 MINIFIED 78 | { 79 | input: pkg.entry, 80 | output: { 81 | file: pkg.min, 82 | name: pkg.name, 83 | sourcemap: false, 84 | format: 'umd' 85 | }, 86 | 87 | plugins: [ 88 | replace({ 89 | exclude: 'node_modules/**', 90 | delimiters: ['<@', '@>'], 91 | APP_NAME: pkg.name, 92 | APP_VERSION: pkg.version 93 | }), 94 | nodeResolve({ 95 | preferBuiltins: false 96 | }), 97 | commonjs({ include: 'node_modules/**' }), // so Rollup can convert other modules to ES module 98 | globals(), 99 | builtins(), 100 | glsl({ 101 | include: 'src/shaders/*.glsl', 102 | }), 103 | babel({ 104 | exclude: 'node_modules/**', 105 | babelrc: false, 106 | presets: [ 'es2015-rollup' ] 107 | }), 108 | uglify() 109 | ] 110 | } 111 | 112 | ] 113 | -------------------------------------------------------------------------------- /src/ColormapManager.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Author Jonathan Lurie - http://me.jonathanlurie.fr 3 | * License MIT 4 | * Link https://github.com/Pixpipe/quickvoxelcore 5 | * Lab MCIN - Montreal Neurological Institute 6 | */ 7 | 8 | import { Colormap } from 'pixpipe/dist/pixpipe.esmodule.js' 9 | import { RawTexture as BJSRawTexture, Engine as BJSEngine, Texture as BJSTexture} from 'babylonjs/es6.js' 10 | 11 | 12 | /** 13 | * An instance of ColormapManager is used by RenderEngine so generate colormaps to apply on the volume. 14 | * Several types of colormaps are available, they are generated as `pixpipe.Image2D`, from which are made 15 | * `BABYLON.RawTexture` (2D) and HTML5 `Canvas`. The texture is to be sent to the shader while the canvas 16 | * can be used for UI purpose. Note that the original `pixpipe.Image2D` colormap is just used temporary 17 | * and is not kept in memory. 18 | */ 19 | class ColormapManager { 20 | 21 | /** 22 | * Constructor 23 | * @param {BABYLON.Scene} scene - the babylonjs scene (necessary to generate textures) 24 | * @param {Number} [nbSamples=512] - number of samples generated per colormap 25 | */ 26 | constructor (scene, nbSamples=512) { 27 | this._scene = scene 28 | this._nbSamples = nbSamples 29 | this._colormapTextures = {} 30 | this._colormapCanvas = {} 31 | 32 | this._createColormapTextures() 33 | this._defaultColormap = 'greys' 34 | } 35 | 36 | 37 | /** 38 | * @private 39 | * Generate BabylonJS textures correcponding to Pixpipe builtin colormaps 40 | */ 41 | _createColormapTextures () { 42 | var styles = Colormap.getAvailableStyles() 43 | var cm = new Colormap() 44 | 45 | for (let i=0; i0) ){ 42 | let events = this._events[ eventName ] 43 | for (let i=0; i make sure it no longer shows in the render engine 54 | this._volumeCollection.on('volumeRemoved', function( id ){ 55 | console.log(`Volume ${id} removed from collection.`); 56 | let mountedIndex = that.unmountVolumeWithId( id ); 57 | if (mountedIndex >= 0) 58 | console.log("+ removed from the render engine."); 59 | }) 60 | 61 | } 62 | 63 | 64 | /** 65 | * Get the volume collection, to access to some features such as adding/removing a volume 66 | * @return {VolumeCollection} 67 | */ 68 | getVolumeCollection () { 69 | return this._volumeCollection; 70 | } 71 | 72 | 73 | /** 74 | * Get the rendering engine to perform some 3D tasks, such as interacting with the view 75 | * @return {RenderingEngine} 76 | */ 77 | getRenderEngine () { 78 | return this._renderEngine; 79 | } 80 | 81 | 82 | /** 83 | * Get the CameraCrew instance in order to perform some camera manipulations 84 | * @return {CameraCrew} 85 | */ 86 | getCameraCrew () { 87 | return this._cameraCrew 88 | } 89 | 90 | 91 | /** 92 | * Mount the volume of the given id on the slot with the given index on the rendering engine 93 | * @param {Number} n - the slot index 94 | * @param {String} volumeId - the id of the volume within the collection 95 | */ 96 | mountVolumeOnSlotN (n, volumeId) { 97 | let volume = this._volumeCollection.getVolume( volumeId ); 98 | if (volume) { 99 | this._renderEngine.mountVolumeN( n, volume ) 100 | }else{ 101 | console.warn("The volume " + volumeId + " does not exist"); 102 | } 103 | } 104 | 105 | 106 | /** 107 | * Unmount the volume from the slot n in the rendering engine. 108 | * Note: this method is jsut a call to the rendering engine, since the volume 109 | * itself is not needed to be unmounted. 110 | * @param {[type]} n [description] 111 | * @return {[type]} [description] 112 | */ 113 | unmountVolumeFromSlotN (n) { 114 | this._renderEngine.unmountVolumeN( n ) 115 | } 116 | 117 | 118 | /** 119 | * [unmountVolumeWIthId description] 120 | * @param {[type]} id [description] 121 | * @return {[type]} [description] 122 | */ 123 | unmountVolumeWithId (id) { 124 | let mountedIndex = this._renderEngine.getSlotIndexFromVolumeId( id ) 125 | if( mountedIndex >= 0){ 126 | this._renderEngine.unmountVolumeN( mountedIndex ) 127 | } 128 | return mountedIndex; 129 | } 130 | 131 | 132 | } 133 | 134 | export { QuickvoxelCore } 135 | -------------------------------------------------------------------------------- /src/Tools.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Author Jonathan Lurie - http://me.jonathanlurie.fr 3 | * License MIT 4 | * Link https://github.com/Pixpipe/quickvoxelcore 5 | * Lab MCIN - Montreal Neurological Institute 6 | */ 7 | 8 | 9 | /** 10 | * Know if the current environment is webGL2 compatible. 11 | * Usage: 12 | * ```Javascript 13 | * if (!quickvoxelcore.webGL2()){ 14 | * alert( 'Quickvoxel Core cannot run here because this web browser is not compatible with WebGL2.' ) 15 | * } else { 16 | * // call the main app 17 | * } 18 | * ``` 19 | * @return {Boolean} true if compatible with WebGL2, false if not 20 | */ 21 | export function webGL2 () { 22 | var dummyGL = document.createElement("canvas").getContext("webgl2") 23 | return !!dummyGL; 24 | } 25 | 26 | 27 | /** 28 | * Gives the property name in the object that has the given value 29 | * @param {Object} object - an object that may contain a property associated with a specific value 30 | * @param {Object} value - a value to look for 31 | * @return {String} Name of the first property that has the given value. Or null if not found 32 | */ 33 | export function getKeyFromValue (object, value) { 34 | for (let key in object) { 35 | if (object[key] === value) 36 | return key 37 | } 38 | return null 39 | } 40 | -------------------------------------------------------------------------------- /src/Volume.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Author Jonathan Lurie - http://me.jonathanlurie.fr 3 | * License MIT 4 | * Link https://github.com/Pixpipe/quickvoxelcore 5 | * Lab MCIN - Montreal Neurological Institute 6 | */ 7 | 8 | 9 | import { 10 | Matrix as BJSMatrix, 11 | RawTexture3D as BJSRawTexture3D, 12 | Engine as BJSEngine, 13 | Texture as BJSTexture 14 | } from 'babylonjs/es6.js' 15 | 16 | /** 17 | * A Volume instance is a volumetric representation of some data that can be queried, displayed and identified. 18 | * - To be queried, a Volume embeds a `pixpipe.Image3DAlt` 19 | * - To be displayed, a Volume generates a WebGL 3D texture from the `pixpipe.Image3DAlt` 20 | * - To be identified, a Volume instance has an id, unique in the `VolumeCollection` 21 | * 22 | */ 23 | class Volume { 24 | /** 25 | * Constructor 26 | */ 27 | constructor (id, image3D) { 28 | this._id = id 29 | this._image3D = image3D 30 | this._texture3D = null 31 | 32 | this._transfoMatrices = { 33 | v2t: null, // from v to world, the center is based on world offset 34 | v2t_center: null // fallback if the offset are corrupted. The center becomes the center of the volume 35 | } 36 | 37 | this._computeV2Tmatrices(); 38 | } 39 | 40 | 41 | /** 42 | * @private 43 | * Compute the affine transformation matrix to go from world coord to unit texture 44 | */ 45 | _computeV2Tmatrices(){ 46 | let img3D = this._image3D 47 | let centerVoxel = img3D.getPositionWorldToVoxel({x:0, y:0, z:0}, false) 48 | 49 | let pixpipe_w2vSwappedMatrix = img3D.getW2VMatrixSwapped() 50 | 51 | let w2v = BJSMatrix.FromArray( pixpipe_w2vSwappedMatrix ).transpose() 52 | 53 | // flipping the x axis is necessary because conventions are different between 54 | // WebGL and Pixpipe 55 | let flipX = new BJSMatrix.FromValues( 56 | -1, 0, 0, 0, 57 | 0, 1, 0, 0, 58 | 0, 0, 1, 0, 59 | 0, 0, 0, 1 60 | ) 61 | 62 | let scalingMat = new BJSMatrix.FromValues( 63 | 1/img3D.getDimensionSize("x"), 0, 0, 0, 64 | 0, 1/img3D.getDimensionSize("y"), 0, 0, 65 | 0, 0, 1/img3D.getDimensionSize("z"), 0, 66 | 0, 0, 0, 1 67 | ) 68 | 69 | // the texture must be addressed as [k, j, i], which is the opposite of how 70 | // Pixpipe does, so we just reverse the dimensionality in the transform 71 | let reverseDimensionality = new BJSMatrix.FromValues( 72 | 0, 0, 1, 0, 73 | 0, 1, 0, 0, 74 | 1, 0, 0, 0, 75 | 0, 0, 0, 1 76 | ) 77 | 78 | let w2v_scaled = w2v.multiply( scalingMat ) 79 | 80 | // the X (left to right) axis is fliped, so we unflip it 81 | let w2v_scaled_flipedX = w2v_scaled.multiply(flipX); // ok 82 | 83 | // with JUST reverseDimensionality 84 | let transfoMat = reverseDimensionality.multiply( w2v_scaled_flipedX ) 85 | 86 | // putting the center at the center 87 | transfoMat.m[3] = centerVoxel.k / img3D.getDimensionSize("k") 88 | transfoMat.m[7] = centerVoxel.j / img3D.getDimensionSize("j") 89 | transfoMat.m[11] = centerVoxel.i / img3D.getDimensionSize("i") 90 | 91 | this._transfoMatrices.v2t = transfoMat; 92 | 93 | // sometimes, one of the offset (or more) is zero, which makes no 94 | // sens in this brain context (weither it's Talairach or MNI space). 95 | // Then, we arbitrarily set the origin at the center of the volume. 96 | // In this case, the world origin is no longer valid but we still 97 | // keep relative size ok. 98 | this._transfoMatrices.v2t_center = this._transfoMatrices.v2t.clone(); 99 | this._transfoMatrices.v2t_center.m[3] = 0.5; 100 | this._transfoMatrices.v2t_center.m[7] = 0.5; 101 | this._transfoMatrices.v2t_center.m[11] = 0.5; 102 | } 103 | 104 | 105 | 106 | /** 107 | * Build the texture corresponding to this volume. This requires a scene instance 108 | * @param {[type]} bjsScene [description] 109 | * @return {[type]} [description] 110 | */ 111 | buildTexture( bjsScene ){ 112 | let dimK = this._image3D.getDimensionSize("k"); 113 | let dimJ = this._image3D.getDimensionSize("j"); 114 | let dimI = this._image3D.getDimensionSize("i"); 115 | let dimT = this._image3D.getTimeLength(); 116 | 117 | this._texture3D = new BJSRawTexture3D( 118 | this._image3D.getDataUint8(), 119 | dimK , 120 | dimJ , 121 | dimI * dimT, 122 | BJSEngine.TEXTUREFORMAT_LUMINANCE, 123 | bjsScene, 124 | false, // generate mipmaps 125 | false, // invertY 126 | //BJSTexture.NEAREST_SAMPLINGMODE 127 | BJSTexture.TRILINEAR_SAMPLINGMODE 128 | ) 129 | } 130 | 131 | 132 | /** 133 | * Get the id of this volume 134 | * @return {String} the id 135 | */ 136 | getId () { 137 | return this._id; 138 | } 139 | 140 | 141 | /** 142 | * get the babylonjs texture3d object 143 | * @return {BABYLON.RawTexture3D} the texture corresponding to this volume 144 | */ 145 | getTexture3D () { 146 | return this._texture3D; 147 | } 148 | 149 | 150 | /** 151 | * Get the Pixpipe Image3DAlt object 152 | * @return {pixpipe.Image3DAlt} The volume data as loaded by Pixpipe 153 | */ 154 | getImage3D () { 155 | return this._image3D; 156 | } 157 | 158 | 159 | /** 160 | * Get the transformation matrix with the given name 161 | * @param {String} name - name of the transform (most likely "v2t" or "v2t_center") 162 | * @return {BABYLON.Matrix} the matrix 163 | */ 164 | getMatrix (name) { 165 | if (name in this._transfoMatrices) { 166 | return this._transfoMatrices[name] 167 | }else{ 168 | return null; 169 | } 170 | } 171 | 172 | 173 | /** 174 | * Get a list of all available matrices for this volume, as strings 175 | * @return {Array} 176 | */ 177 | getAvaialableMatrices () { 178 | return Object.keys( this._transfoMatrices ) 179 | } 180 | 181 | 182 | /** 183 | * Get the number of time samples. fMRI (or diffusion) will have more than one 184 | * while structural MRI will usually have only one. 185 | * @return {Number} 186 | */ 187 | getTimeLength () { 188 | return this._image3D.getTimeLength() 189 | } 190 | 191 | 192 | /** 193 | * Get the voxel value at the given world position. 194 | * Note: the world coordinates are floating point and this method perform a lookup 195 | * in voxel coordinates in the `pixpipe.Image3DAlt` data. Voxel coordinates being integer, 196 | * no interpolation from worl to voxel is performed by this method. 197 | * This just gives the value of the closest voxel. 198 | * @param {Object} [position={x:0, y:0, z:0}] - position in world coordinates 199 | * @param {Number} [time=0] - time index (makes sense only for time series) 200 | * @return {Number} the voxel intensity 201 | */ 202 | getValue (position={x:0, y:0, z:0}, time=0) { 203 | return this._image3D.getVoxelTransfoSpace( "w2v", position, time ) 204 | } 205 | 206 | 207 | } 208 | 209 | export { Volume } 210 | -------------------------------------------------------------------------------- /src/VolumeCollection.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Author Jonathan Lurie - http://me.jonathanlurie.fr 3 | * License MIT 4 | * Link https://github.com/Pixpipe/quickvoxelcore 5 | * Lab MCIN - Montreal Neurological Institute 6 | */ 7 | 8 | 9 | import { UrlToArrayBufferReader, FileToArrayBufferReader, Image3DGenericDecoder } from 'pixpipe/dist/pixpipe.esmodule.js' 10 | import { Volume } from './Volume.js' 11 | import { EventManager } from './EventManager.js' 12 | 13 | /** 14 | * The VolumeCollection is automatically initialized by the constructor of QuickVoxelCore. 15 | * When the QuickVoxelCore object is created, the VolumeCollection can be fetched to perform actions directly on it. 16 | * 17 | * A instance of VolumeCollection manages and identifies Volume instances. 18 | * A `Volume` can be added to the collection using `.addVolumeFromUrl()` and `.addVolumeFromFile()`. 19 | * Once one of these two method is called, a `Volume` instance is created (itself generating a 3D texture) 20 | * and added to the collection with a given index. 21 | * 22 | * VolumeCollection provides some events, so that actions can be triggered during the lifecycle of a `Volume`: 23 | * - `startAddingVolume` is called when a new volume is about to be added. This event is convenient mostly for UI purpose so that we can for example show a loading spinner, that then will be hidden when the event `volumeAdded` or `errorAddingVolume` are called 24 | * - `volumeAdded` is called when the volume is parsed and added to the collection. But its webGL texture is not ready yet! The callbacks attached to this event will have the volume object as argument. 25 | * - `volumeReady`called after `volumeAdded`, at the moment the added volume has its WegGL 3D texture ready. At this stage, a volume is ready to be displayed.The callbacks attached to this event will have the volume object as argument. 26 | * - `volumeRemoved` is called when a volume is removed from the collection with the method `.removeVolume(id)`. The callbacks attached to this event will have the volume id (string) as argument. 27 | * - `errorAddingVolume` is called when a volume failled to be added with `.addVolumeFromUrl()` and `.addVolumeFromFile()`. The callbacks attached to this event will have the url or the filename (if opened from file dialog) as argument. 28 | * 29 | * To each event can be attached multiple callbacks, they will simply be called successivelly in the order the were declared. To assiciate a callback function to an event, just do: 30 | * ``` 31 | * myVolumeCollection.on("volumeReady", function(volume){ 32 | * // Do something with this volume 33 | * }) 34 | * ``` 35 | * 36 | */ 37 | class VolumeCollection extends EventManager { 38 | /** 39 | * The constuctor for the VolumeCollection 40 | */ 41 | constructor () { 42 | super() 43 | this._volume = {} 44 | 45 | this._events = { 46 | volumeAdded: [], // called when the volume is parsed and added to the collection 47 | volumeReady: [], // called just after "volumeAdded", means the volume has its texture ready 48 | volumeRemoved: [], // called when a volume is removed from the collection 49 | errorAddingVolume: [], // called when a volume could not be added to the collection 50 | }; 51 | } 52 | 53 | 54 | /** 55 | * Get the volume of the given id 56 | * @param {String} id - unique id of the volume within the collection 57 | * @return {Volume|null} the volume if existing, or null if not existing 58 | */ 59 | getVolume (id) { 60 | if( id in this._volume ){ 61 | return this._volume[ id ]; 62 | }else{ 63 | return null; 64 | } 65 | } 66 | 67 | 68 | /** 69 | * @private 70 | * Add a new volume to the collection. 71 | * Once the volume is added to the collection, the even "volumeAdded" is called with the volume in argument 72 | * @param {Volume} volume - a volumetric object 73 | */ 74 | _addToCollection (volume) { 75 | let id = volume.getId() 76 | this._volume[ id ] = volume; 77 | this.emit( 'volumeAdded', [volume] ); 78 | this.emit( 'volumeReady', [volume] ); 79 | } 80 | 81 | 82 | /** 83 | * @private 84 | * Find a non existing name by appending an index to the filename 85 | * @param {String} filename - the filename 86 | * @return {String} the id, which is the filename, possibly appended with a number 87 | */ 88 | _generateID( filename ){ 89 | // if the name does not already exist, then we just use it 90 | if( !(filename in this._volume) ){ 91 | return filename; 92 | } 93 | 94 | // otherwise, we append a number to it 95 | let i = 0 96 | while ((filename+"_"+i) in this._volume) { 97 | i++ 98 | } 99 | return (filename+"_"+i); 100 | } 101 | 102 | 103 | /** 104 | * Add a volume file to the collection, using an URL 105 | * @param {String} url - url of the file 106 | */ 107 | addVolumeFromUrl (url) { 108 | let that = this 109 | let urlArrBuff = new UrlToArrayBufferReader() 110 | 111 | urlArrBuff.addInput( url, 0 ) 112 | 113 | urlArrBuff.on("ready", function(){ 114 | let arrBuff = this.getOutput() 115 | let generic3DDecoder = new Image3DGenericDecoder(); 116 | generic3DDecoder.addInput( arrBuff ) 117 | generic3DDecoder.update() 118 | let img3D = generic3DDecoder.getOutput() 119 | 120 | if( img3D ){ 121 | console.log( img3D ) 122 | let id = that._generateID( urlArrBuff.getMetadata("filenames")[0] ) 123 | let volume = new Volume( id, img3D ) 124 | that._addToCollection( volume ) 125 | }else{ 126 | that.emit( 'errorAddingVolume', [url] ) 127 | } 128 | }); 129 | 130 | that.emit( 'startAddingVolume', [url] ) 131 | urlArrBuff.update() 132 | } 133 | 134 | 135 | /** 136 | * Add a volume to the collection from a file (most likely using a file dialog) 137 | * @param {File} file - a compatible volumetric file 138 | */ 139 | addVolumeFromFile (file) { 140 | let that = this 141 | let file2Buff = new FileToArrayBufferReader() 142 | let filename = file.name 143 | 144 | file2Buff.on("ready", function(){ 145 | let arrBuff = this.getOutput() 146 | let generic3DDecoder = new Image3DGenericDecoder() 147 | generic3DDecoder.addInput( arrBuff ) 148 | generic3DDecoder.update() 149 | let img3D = generic3DDecoder.getOutput() 150 | 151 | if( img3D ){ 152 | console.log( img3D ) 153 | let id = that._generateID( filename ) 154 | let volume = new Volume( id, img3D ) 155 | that._addToCollection( volume ) 156 | }else{ 157 | that.emit( 'errorAddingVolume', [filename]) 158 | } 159 | }); 160 | 161 | that.emit( 'startAddingVolume', [filename] ) 162 | file2Buff.addInput(file) 163 | file2Buff.update() 164 | } 165 | 166 | 167 | /** 168 | * Get the list of all volume ids available in this collection 169 | * @return {[type]} [description] 170 | */ 171 | getVolumeIds () { 172 | return Object.keys( this._volume ) 173 | } 174 | 175 | 176 | /** 177 | * Get the `Volume` with the given id 178 | * @param {String} id - id of a `Volume` within the collection 179 | * @return {Volume} the Volume instance with such id, or `null` if not found 180 | */ 181 | getVolume (id) { 182 | if( id in this._volume ){ 183 | return this._volume[ id ] 184 | }else{ 185 | return null; 186 | } 187 | } 188 | 189 | 190 | /** 191 | * Remove a volume fron the collection. If succesful, the event "volumeRemoved" is called 192 | * with the id of the volume in argument 193 | * @param {String} id - id of the volume to remove 194 | */ 195 | removeVolume (id) { 196 | if( id in this._volume ){ 197 | delete this._volume[ id ] 198 | this.emit( "volumeRemoved", [id] ) 199 | }else{ 200 | console.warn("The volume " + id + " cannot be removed because it does not exist."); 201 | } 202 | } 203 | 204 | } // END of class VolumeCollection 205 | 206 | export { VolumeCollection } 207 | -------------------------------------------------------------------------------- /src/_info.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Author Jonathan Lurie - http://me.jonathanlurie.fr 3 | * License MIT 4 | * Link https://github.com/Pixpipe/quickvoxelcore 5 | * Lab MCIN - Montreal Neurological Institute 6 | */ 7 | 8 | 9 | export const APP_INFO = { 10 | name: '<@APP_NAME@>', 11 | version: '<@APP_VERSION@>' 12 | } 13 | -------------------------------------------------------------------------------- /src/constants.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Author Jonathan Lurie - http://me.jonathanlurie.fr 3 | * License MIT 4 | * Link https://github.com/Pixpipe/quickvoxelcore 5 | * Lab MCIN - Montreal Neurological Institute 6 | */ 7 | 8 | export const CONSTANTS = { 9 | BLENDING_METHODS: { 10 | 'ratio': 0, 11 | 'added-weighted': 1, 12 | 'multiply': 2 13 | }, 14 | GEOMETRY: { 15 | DEFAULT_PLANE_SIZE: 1000 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/main.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Author Jonathan Lurie - http://me.jonathanlurie.fr 3 | * License MIT 4 | * Link https://github.com/Pixpipe/quickvoxelcore 5 | * Lab MCIN - Montreal Neurological Institute 6 | */ 7 | 8 | import { APP_INFO } from './_info.js' 9 | 10 | // fancy display 11 | console.log( '█▓▒░ running ', APP_INFO.name, APP_INFO.version, ' ░▒▓█' ) 12 | 13 | export { CONSTANTS } from './constants.js' 14 | export { QuickvoxelCore } from './QuickvoxelCore.js' 15 | export { webGL2 } from './Tools.js' 16 | -------------------------------------------------------------------------------- /src/shaders/worldcoordtexture3d.frag.glsl: -------------------------------------------------------------------------------- 1 | precision highp float; 2 | precision highp sampler3D; 3 | 4 | 5 | varying vec3 vPositionW; 6 | 7 | uniform int blendMethod; 8 | // must be in [0, 1]. 9 | // if closer to 0, the primary volume is more visible 10 | // if closer to 1, the secondary volume is more visible 11 | uniform float vol_0_vol_1_blendRatio; 12 | 13 | // the primary 3D texture 14 | uniform sampler3D vol_0_texture3D; 15 | // the affine transformation matrix for the primary 3D texture 16 | uniform mat4 vol_0_transfoMat; 17 | // says if the primary 3D texture is ready 18 | uniform int vol_0_textureReady; 19 | // once it's ready, do we wish to display the primary volume? 20 | uniform int vol_0_display; 21 | // the current time position within the primary 3D texture 22 | uniform int vol_0_timeVal; 23 | // the number of time position available in the primary 3D texture 24 | uniform int vol_0_timeSize; 25 | // colormap used for the primary 3D texture 26 | uniform sampler2D vol_0_colormap; 27 | // Boolean of flipping or not the colormap of the primary 3D texture 28 | uniform int vol_0_colormapFlip; 29 | // Float value that represent the brightness of the primary volume 30 | uniform float vol_0_brightness; 31 | // Float value that represent the contrast of the primary volume 32 | uniform float vol_0_contrast; 33 | 34 | 35 | // the secondary 3D texture 36 | uniform sampler3D vol_1_texture3D; 37 | // the affine transformation matrix for the secondary 3D texture 38 | uniform mat4 vol_1_transfoMat; 39 | // says if the secondary 3D texture is ready 40 | uniform int vol_1_textureReady; 41 | // once it's ready, do we wish to display the secondary volume? 42 | uniform int vol_1_display; 43 | // the current time position within the secondary 3D texture 44 | uniform int vol_1_timeVal; 45 | // the number of time position available in the secondary 3D texture 46 | uniform int vol_1_timeSize; 47 | // colormap used for the primary 3D texture 48 | uniform sampler2D vol_1_colormap; 49 | // Boolean of flipping or not the colormap of the primary 3D texture 50 | uniform int vol_1_colormapFlip; 51 | // Float value that represent the brightness of the secondary volume 52 | uniform float vol_1_brightness; 53 | // Float value that represent the contrast of the secondary volume 54 | uniform float vol_1_contrast; 55 | 56 | 57 | 58 | // Get the color from the texture 0 (at the current worl coord). 59 | // The out argument shouldDisplay will be 0 if this world coord is outside of 60 | // the volume range and 1 if inside. To be used to know wether of not to use the 61 | // returned color. 62 | vec4 getColorVol_0( out int shouldDisplay, out float intensity){ 63 | if( vol_0_textureReady == 0 || vol_0_display == 0){ 64 | shouldDisplay = 0; 65 | return vec4(0., 0., 0., 0.); 66 | } 67 | 68 | vec4 v4PositionW = vec4( vPositionW, 1.0 ); 69 | vec4 unitPositionV4 = v4PositionW * vol_0_transfoMat; 70 | vec3 unitPositionV3 = vec3( unitPositionV4.x , unitPositionV4.y, (unitPositionV4.z + float(vol_0_timeVal))/ float(vol_0_timeSize) ) ; 71 | 72 | if( unitPositionV3.x < 0. || unitPositionV3.x > 1. || 73 | unitPositionV3.y < 0. || unitPositionV3.y > 1. || 74 | unitPositionV3.z < (float(vol_0_timeVal)/ float(vol_0_timeSize)) || unitPositionV3.z > ((1. + float(vol_0_timeVal))/ float(vol_0_timeSize)) ) 75 | { 76 | shouldDisplay = 0; 77 | return vec4(0., 0., 0., 0.); 78 | }else{ 79 | shouldDisplay = 1; 80 | intensity = texture( vol_0_texture3D, unitPositionV3 ).r; 81 | 82 | // adding the contrast and brightness 83 | float intensityCB = vol_0_contrast * (intensity - 0.5) + 0.5 + vol_0_brightness; 84 | 85 | float positionOnColormap = (vol_0_colormapFlip == 0) ? intensityCB : (1. - intensityCB); 86 | vec4 color = texture( vol_0_colormap, vec2(positionOnColormap, 0.5) ); 87 | return color; 88 | } 89 | } 90 | 91 | 92 | // Get the color from the texture 0 (at the current worl coord). 93 | // The out argument shouldDisplay will be 0 if this world coord is outside of 94 | // the volume range and 1 if inside. To be used to know wether of not to use the 95 | // returned color. 96 | vec4 getColorVol_1( out int shouldDisplay, out float intensity ){ 97 | if( vol_1_textureReady == 0 || vol_1_display == 0){ 98 | shouldDisplay = 0; 99 | return vec4(0., 0., 0., 0.); 100 | } 101 | 102 | vec4 v4PositionW = vec4( vPositionW, 1.0 ); 103 | vec4 unitPositionV4 = v4PositionW * vol_1_transfoMat; 104 | vec3 unitPositionV3 = vec3( unitPositionV4.x , unitPositionV4.y, (unitPositionV4.z + float(vol_1_timeVal))/ float(vol_1_timeSize) ) ; 105 | 106 | if( unitPositionV3.x < 0. || unitPositionV3.x > 1. || 107 | unitPositionV3.y < 0. || unitPositionV3.y > 1. || 108 | unitPositionV3.z < (float(vol_1_timeVal)/ float(vol_1_timeSize)) || unitPositionV3.z > ((1. + float(vol_1_timeVal))/ float(vol_1_timeSize)) ) 109 | { 110 | shouldDisplay = 0; 111 | return vec4(0., 0., 0., 0.); 112 | }else{ 113 | shouldDisplay = 1; 114 | intensity = texture( vol_1_texture3D, unitPositionV3 ).r; 115 | 116 | // adding the contrast and brightness 117 | float intensityCB = vol_1_contrast * (intensity - 0.5) + 0.5 + vol_1_brightness; 118 | 119 | float positionOnColormap = (vol_1_colormapFlip == 0) ? intensityCB : (1. - intensityCB); 120 | vec4 color = texture( vol_1_colormap, vec2(positionOnColormap, 0.5) ); 121 | return color; 122 | } 123 | } 124 | 125 | 126 | // Blend two colors using different methods. 127 | vec4 blend( vec4 color0, vec4 color1, float intensity0, float intensity1, int method){ 128 | vec4 color = vec4(0., 0., 0., 0.); 129 | 130 | switch( method ){ 131 | 132 | // ratio 133 | case 0: 134 | color = color0 * (1. - vol_0_vol_1_blendRatio) + (color1 * vol_0_vol_1_blendRatio); 135 | break; 136 | 137 | 138 | // adding weighted 139 | case 1: 140 | color = color0 + color1*vol_0_vol_1_blendRatio; 141 | break; 142 | 143 | 144 | // multiply 145 | case 2: 146 | color = color0 * color1; 147 | 148 | default: 149 | break; 150 | } 151 | 152 | return color; 153 | } 154 | 155 | 156 | 157 | void main(void) { 158 | vec4 colorToDisplay = vec4(0., 0., 0., 0.); 159 | 160 | int displayColorVol_0 = 0; 161 | float intensityVol_0 = 0.; 162 | vec4 colorVol_0 = getColorVol_0( displayColorVol_0, intensityVol_0); 163 | 164 | int displayColorVol_1 = 0; 165 | float intensityVol_1 = 0.; 166 | vec4 colorVol_1 = getColorVol_1( displayColorVol_1, intensityVol_1 ); 167 | 168 | // None of the textures can display 169 | if( displayColorVol_0 == 0 && displayColorVol_1 == 0 ){ 170 | discard; 171 | return; 172 | } 173 | 174 | // only the texture 0 can display 175 | if( displayColorVol_0 == 1 && displayColorVol_1 == 0 ){ 176 | colorToDisplay = colorVol_0; 177 | 178 | // only the texture 1 can display 179 | }else if( displayColorVol_0 == 0 && displayColorVol_1 == 1 ){ 180 | colorToDisplay = colorVol_1; 181 | } 182 | 183 | // both texture can display 184 | else{ 185 | colorToDisplay = blend( colorVol_0, colorVol_1, intensityVol_0, intensityVol_1, blendMethod); 186 | } 187 | 188 | gl_FragColor = colorToDisplay; 189 | } 190 | -------------------------------------------------------------------------------- /src/shaders/worldcoordtexture3d.vert.glsl: -------------------------------------------------------------------------------- 1 | precision highp float; 2 | 3 | // Attributes 4 | attribute vec3 position; 5 | 6 | // Uniforms 7 | uniform mat4 world; 8 | uniform mat4 worldViewProjection; 9 | 10 | // Varying 11 | varying vec3 vPositionW; 12 | 13 | void main(void) { 14 | vec4 outPosition = worldViewProjection * vec4(position, 1.0); 15 | gl_Position = outPosition; 16 | 17 | vPositionW = vec3(world * vec4(position, 1.0)); 18 | } 19 | --------------------------------------------------------------------------------