├── .gitignore ├── LICENSE ├── README.md ├── bin └── create-itk-app.js └── package.json /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules/ 2 | package-lock.json 3 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | 2 | Apache License 3 | Version 2.0, January 2004 4 | http://www.apache.org/licenses/ 5 | 6 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 7 | 8 | 1. Definitions. 9 | 10 | "License" shall mean the terms and conditions for use, reproduction, 11 | and distribution as defined by Sections 1 through 9 of this document. 12 | 13 | "Licensor" shall mean the copyright owner or entity authorized by 14 | the copyright owner that is granting the License. 15 | 16 | "Legal Entity" shall mean the union of the acting entity and all 17 | other entities that control, are controlled by, or are under common 18 | control with that entity. For the purposes of this definition, 19 | "control" means (i) the power, direct or indirect, to cause the 20 | direction or management of such entity, whether by contract or 21 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 22 | outstanding shares, or (iii) beneficial ownership of such entity. 23 | 24 | "You" (or "Your") shall mean an individual or Legal Entity 25 | exercising permissions granted by this License. 26 | 27 | "Source" form shall mean the preferred form for making modifications, 28 | including but not limited to software source code, documentation 29 | source, and configuration files. 30 | 31 | "Object" form shall mean any form resulting from mechanical 32 | transformation or translation of a Source form, including but 33 | not limited to compiled object code, generated documentation, 34 | and conversions to other media types. 35 | 36 | "Work" shall mean the work of authorship, whether in Source or 37 | Object form, made available under the License, as indicated by a 38 | copyright notice that is included in or attached to the work 39 | (an example is provided in the Appendix below). 40 | 41 | "Derivative Works" shall mean any work, whether in Source or Object 42 | form, that is based on (or derived from) the Work and for which the 43 | editorial revisions, annotations, elaborations, or other modifications 44 | represent, as a whole, an original work of authorship. For the purposes 45 | of this License, Derivative Works shall not include works that remain 46 | separable from, or merely link (or bind by name) to the interfaces of, 47 | the Work and Derivative Works thereof. 48 | 49 | "Contribution" shall mean any work of authorship, including 50 | the original version of the Work and any modifications or additions 51 | to that Work or Derivative Works thereof, that is intentionally 52 | submitted to Licensor for inclusion in the Work by the copyright owner 53 | or by an individual or Legal Entity authorized to submit on behalf of 54 | the copyright owner. For the purposes of this definition, "submitted" 55 | means any form of electronic, verbal, or written communication sent 56 | to the Licensor or its representatives, including but not limited to 57 | communication on electronic mailing lists, source code control systems, 58 | and issue tracking systems that are managed by, or on behalf of, the 59 | Licensor for the purpose of discussing and improving the Work, but 60 | excluding communication that is conspicuously marked or otherwise 61 | designated in writing by the copyright owner as "Not a Contribution." 62 | 63 | "Contributor" shall mean Licensor and any individual or Legal Entity 64 | on behalf of whom a Contribution has been received by Licensor and 65 | subsequently incorporated within the Work. 66 | 67 | 2. Grant of Copyright License. Subject to the terms and conditions of 68 | this License, each Contributor hereby grants to You a perpetual, 69 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 70 | copyright license to reproduce, prepare Derivative Works of, 71 | publicly display, publicly perform, sublicense, and distribute the 72 | Work and such Derivative Works in Source or Object form. 73 | 74 | 3. Grant of Patent License. Subject to the terms and conditions of 75 | this License, each Contributor hereby grants to You a perpetual, 76 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 77 | (except as stated in this section) patent license to make, have made, 78 | use, offer to sell, sell, import, and otherwise transfer the Work, 79 | where such license applies only to those patent claims licensable 80 | by such Contributor that are necessarily infringed by their 81 | Contribution(s) alone or by combination of their Contribution(s) 82 | with the Work to which such Contribution(s) was submitted. If You 83 | institute patent litigation against any entity (including a 84 | cross-claim or counterclaim in a lawsuit) alleging that the Work 85 | or a Contribution incorporated within the Work constitutes direct 86 | or contributory patent infringement, then any patent licenses 87 | granted to You under this License for that Work shall terminate 88 | as of the date such litigation is filed. 89 | 90 | 4. Redistribution. You may reproduce and distribute copies of the 91 | Work or Derivative Works thereof in any medium, with or without 92 | modifications, and in Source or Object form, provided that You 93 | meet the following conditions: 94 | 95 | (a) You must give any other recipients of the Work or 96 | Derivative Works a copy of this License; and 97 | 98 | (b) You must cause any modified files to carry prominent notices 99 | stating that You changed the files; and 100 | 101 | (c) You must retain, in the Source form of any Derivative Works 102 | that You distribute, all copyright, patent, trademark, and 103 | attribution notices from the Source form of the Work, 104 | excluding those notices that do not pertain to any part of 105 | the Derivative Works; and 106 | 107 | (d) If the Work includes a "NOTICE" text file as part of its 108 | distribution, then any Derivative Works that You distribute must 109 | include a readable copy of the attribution notices contained 110 | within such NOTICE file, excluding those notices that do not 111 | pertain to any part of the Derivative Works, in at least one 112 | of the following places: within a NOTICE text file distributed 113 | as part of the Derivative Works; within the Source form or 114 | documentation, if provided along with the Derivative Works; or, 115 | within a display generated by the Derivative Works, if and 116 | wherever such third-party notices normally appear. The contents 117 | of the NOTICE file are for informational purposes only and 118 | do not modify the License. You may add Your own attribution 119 | notices within Derivative Works that You distribute, alongside 120 | or as an addendum to the NOTICE text from the Work, provided 121 | that such additional attribution notices cannot be construed 122 | as modifying the License. 123 | 124 | You may add Your own copyright statement to Your modifications and 125 | may provide additional or different license terms and conditions 126 | for use, reproduction, or distribution of Your modifications, or 127 | for any such Derivative Works as a whole, provided Your use, 128 | reproduction, and distribution of the Work otherwise complies with 129 | the conditions stated in this License. 130 | 131 | 5. Submission of Contributions. Unless You explicitly state otherwise, 132 | any Contribution intentionally submitted for inclusion in the Work 133 | by You to the Licensor shall be under the terms and conditions of 134 | this License, without any additional terms or conditions. 135 | Notwithstanding the above, nothing herein shall supersede or modify 136 | the terms of any separate license agreement you may have executed 137 | with Licensor regarding such Contributions. 138 | 139 | 6. Trademarks. This License does not grant permission to use the trade 140 | names, trademarks, service marks, or product names of the Licensor, 141 | except as required for reasonable and customary use in describing the 142 | origin of the Work and reproducing the content of the NOTICE file. 143 | 144 | 7. Disclaimer of Warranty. Unless required by applicable law or 145 | agreed to in writing, Licensor provides the Work (and each 146 | Contributor provides its Contributions) on an "AS IS" BASIS, 147 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 148 | implied, including, without limitation, any warranties or conditions 149 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 150 | PARTICULAR PURPOSE. You are solely responsible for determining the 151 | appropriateness of using or redistributing the Work and assume any 152 | risks associated with Your exercise of permissions under this License. 153 | 154 | 8. Limitation of Liability. In no event and under no legal theory, 155 | whether in tort (including negligence), contract, or otherwise, 156 | unless required by applicable law (such as deliberate and grossly 157 | negligent acts) or agreed to in writing, shall any Contributor be 158 | liable to You for damages, including any direct, indirect, special, 159 | incidental, or consequential damages of any character arising as a 160 | result of this License or out of the use or inability to use the 161 | Work (including but not limited to damages for loss of goodwill, 162 | work stoppage, computer failure or malfunction, or any and all 163 | other commercial damages or losses), even if such Contributor 164 | has been advised of the possibility of such damages. 165 | 166 | 9. Accepting Warranty or Additional Liability. While redistributing 167 | the Work or Derivative Works thereof, You may choose to offer, 168 | and charge a fee for, acceptance of support, warranty, indemnity, 169 | or other liability obligations and/or rights consistent with this 170 | License. However, in accepting such obligations, You may act only 171 | on Your own behalf and on Your sole responsibility, not on behalf 172 | of any other Contributor, and only if You agree to indemnify, 173 | defend, and hold each Contributor harmless for any liability 174 | incurred by, or claims asserted against, such Contributor by reason 175 | of your accepting any such warranty or additional liability. 176 | 177 | END OF TERMS AND CONDITIONS 178 | 179 | APPENDIX: How to apply the Apache License to your work. 180 | 181 | To apply the Apache License to your work, attach the following 182 | boilerplate notice, with the fields enclosed by brackets "[]" 183 | replaced with your own identifying information. (Don't include 184 | the brackets!) The text should be enclosed in the appropriate 185 | comment syntax for the file format. We also recommend that a 186 | file or class name and description of purpose be included on the 187 | same "printed page" as the copyright notice for easier 188 | identification within third-party archives. 189 | 190 | Copyright [yyyy] [name of copyright owner] 191 | 192 | Licensed under the Apache License, Version 2.0 (the "License"); 193 | you may not use this file except in compliance with the License. 194 | You may obtain a copy of the License at 195 | 196 | http://www.apache.org/licenses/LICENSE-2.0 197 | 198 | Unless required by applicable law or agreed to in writing, software 199 | distributed under the License is distributed on an "AS IS" BASIS, 200 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 201 | See the License for the specific language governing permissions and 202 | limitations under the License. 203 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Create ITK App 2 | 3 | This project will generate a new application based on 4 | [itk.js](https://insightsoftwareconsortium.github.io/itk-js/), 5 | [vtk.js](https://kitware.github.io/vtk-js/index.html), and 6 | [React.js](https://reactjs.org/) with everything you need to get started. 7 | 8 | After [installing Node.js](https://nodejs.org/en/download/), 9 | 10 | ```sh 11 | npx create-itk-app my-first-app 12 | ``` 13 | -------------------------------------------------------------------------------- /bin/create-itk-app.js: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 3 | const path = require('path') 4 | const fs = require('fs') 5 | const inquirer = require('inquirer') 6 | const program = require('commander') 7 | const chalk = require('chalk') 8 | const kebabCase = require('lodash.kebabcase') 9 | const validatePackageName = require('validate-npm-package-name') 10 | const { guessEmail, guessAuthor, guessGitHubUsername } = require('conjecture') 11 | const stringifyAuthor = require('stringify-author') 12 | const spawn = require('cross-spawn') 13 | const editJsonFile = require('edit-json-file') 14 | const simpleGit = require('simple-git') 15 | 16 | program 17 | .usage('[options] [destination]') 18 | .option('-n, --appName ', 'App name') 19 | .option('-d, --desc ""', 20 | 'Description (contain in quotes)') 21 | .option('-a, --author ""', 22 | 'Author name (contain in quotes)') 23 | .option('-e, --email ', 'Author email address') 24 | .option('--homepage ', 'Project\'s homepage') 25 | .option('-u, --user ', 'GitHub username or org (repo owner)') 26 | .option('-r, --repo ', 'Repository name') 27 | .parse(process.argv) 28 | 29 | const destination = program.args.length 30 | ? path.resolve(process.cwd(), program.args.shift()) 31 | : process.cwd() 32 | 33 | const prompts = [ 34 | { 35 | type: 'input', 36 | name: 'appName', 37 | default (answers) { 38 | return answers.repo || kebabCase(path.basename(destination)) 39 | }, 40 | message: 'App name:', 41 | when: !program.appName, 42 | validate (appName) { 43 | const result = validatePackageName(appName) 44 | if (result.errors && result.errors.length > 0) { 45 | return result.errors.join(',') 46 | } 47 | 48 | return true 49 | } 50 | }, 51 | { 52 | type: 'input', 53 | name: 'description', 54 | default () { 55 | return 'An Insight Toolkit (ITK) app' 56 | }, 57 | message: 'Description of app:', 58 | when: !program.desc 59 | }, 60 | { 61 | type: 'input', 62 | name: 'author', 63 | default () { 64 | return guessAuthor() 65 | }, 66 | message: 'Author\'s full name:', 67 | when: !program.author 68 | }, 69 | { 70 | type: 'input', 71 | name: 'email', 72 | default () { 73 | return guessEmail() 74 | }, 75 | message: 'Author\'s email address:', 76 | when: !program.email 77 | }, 78 | { 79 | type: 'input', 80 | name: 'user', 81 | default (answers) { 82 | return guessGitHubUsername(answers.email) 83 | }, 84 | message: 'GitHub user or org name:', 85 | when: !program.user 86 | }, 87 | { 88 | type: 'input', 89 | name: 'repo', 90 | default (answers) { 91 | return answers.appName || kebabCase(path.basename(destination)) 92 | }, 93 | message: 'Repository name:', 94 | when: !program.repo 95 | }, 96 | { 97 | type: 'input', 98 | name: 'homepage', 99 | default (answers) { 100 | return `https://github.com/${answers.user}/${answers.repo}` 101 | }, 102 | message: 'Homepage:', 103 | when: !program.homepage 104 | } 105 | ] 106 | 107 | console.log(chalk.blue('\nLet\'s create a itk.js app!\n\nHit enter to accept the suggestion.\n')) 108 | 109 | inquirer.prompt(prompts) 110 | .then(answers => { 111 | answers.author = stringifyAuthor({ 112 | name: program.author || answers.author, 113 | email: program.email || answers.email 114 | }) 115 | answers.appName = program.appName || answers.appName 116 | answers.description = program.desc || answers.description 117 | answers.user = program.user || answers.user 118 | answers.repo = program.repo || answers.repo 119 | answers.homepage = program.homepage || answers.homepage 120 | 121 | console.log(chalk.blue('\nCreating React app!')) 122 | const craResult = spawn.sync('npx', ['create-react-app', destination], { stdio: ['ignore', 'inherit', 'inherit'] }) 123 | if (craResult.status !== 0) { 124 | console.log(chalk.red(`Could not run create-react-app.`)) 125 | return 126 | } 127 | 128 | console.log(chalk.blue('\nSetting up craco...')) 129 | const cracoResult = spawn.sync('yarn', ['add', 130 | '@craco/craco', 131 | 'craco-itk', 'itk', 132 | 'craco-vtk', 'vtk.js', 'shader-loader', 'worker-loader' 133 | ], 134 | { stdio: 'inherit', cwd: destination } 135 | ) 136 | if (cracoResult.status !== 0) { 137 | console.log(chalk.red(`Could not install craco.`)) 138 | return 139 | } 140 | 141 | const packageJson = path.resolve(destination, 'package.json') 142 | const editPackageJson = editJsonFile(packageJson) 143 | editPackageJson.set('name', answers.appName) 144 | editPackageJson.set('author', answers.author) 145 | editPackageJson.set('description', answers.description) 146 | editPackageJson.set('keywords', ['itk.js']) 147 | editPackageJson.set('license', ['Apache-2.0']) 148 | editPackageJson.set('repository', answers.repository) 149 | editPackageJson.set('homepage', answers.homepage) 150 | editPackageJson.set('scripts.start', 'craco start') 151 | editPackageJson.set('scripts.build', 'craco build') 152 | editPackageJson.set('scripts.test', 'craco test') 153 | editPackageJson.set('repository.type', 'git') 154 | editPackageJson.set('repository.url', `git+https://github.com/${answers.user}/${answers.repo}.git`) 155 | editPackageJson.save() 156 | 157 | const cracoConfig = ` 158 | const CracoItkPlugin = require("craco-itk") 159 | const CracoVtkPlugin = require("craco-vtk") 160 | 161 | module.exports = { 162 | plugins: [ 163 | { 164 | plugin: CracoItkPlugin() 165 | }, 166 | { 167 | plugin: CracoVtkPlugin() 168 | } 169 | ] 170 | } 171 | ` 172 | fs.writeFileSync(path.resolve(destination, 'craco.config.js'), cracoConfig) 173 | 174 | const appJs = ` 175 | import React, { Component } from 'react'; 176 | import './App.css'; 177 | 178 | import vtkActor from 'vtk.js/Sources/Rendering/Core/Actor'; 179 | import vtkSphereSource from 'vtk.js/Sources/Filters/Sources/SphereSource'; 180 | import vtkMapper from 'vtk.js/Sources/Rendering/Core/Mapper'; 181 | import vtkFullScreenRenderWindow from 'vtk.js/Sources/Rendering/Misc/FullScreenRenderWindow'; 182 | import vtkTubeFilter from 'vtk.js/Sources/Filters/General/TubeFilter'; 183 | import vtkPoints from 'vtk.js/Sources/Common/Core/Points'; 184 | import vtkPolyData from 'vtk.js/Sources/Common/DataModel/PolyData'; 185 | import { VtkDataTypes } from 'vtk.js/Sources/Common/Core/DataArray/Constants'; 186 | 187 | class App extends Component { 188 | constructor(props) { 189 | super(props); 190 | 191 | this.fullScreenRenderer = null; 192 | this.container = React.createRef(); 193 | this.pipeline = null; 194 | } 195 | 196 | createPipeline(resolution = 20) { 197 | const sphereSource = vtkSphereSource.newInstance({ radius: 1.5, thetaResolution: resolution, phiResolution: resolution }); 198 | 199 | const atomColorR = 0.380 200 | const atomColorG = 0.855 201 | const atomColorB = 0.984 202 | 203 | const sphereMapper = vtkMapper.newInstance(); 204 | sphereMapper.setInputConnection(sphereSource.getOutputPort()); 205 | 206 | const sphereActor = vtkActor.newInstance(); 207 | sphereActor.setMapper(sphereMapper); 208 | sphereActor.getProperty().setColor(atomColorR, atomColorG, atomColorB) 209 | 210 | 211 | const numberOfSegments = resolution; 212 | let pointType = VtkDataTypes.FLOAT; 213 | const tubeRadius = 5.0; 214 | 215 | const polyDataXY = vtkPolyData.newInstance(); 216 | const pointsXY = vtkPoints.newInstance({ dataType: pointType }); 217 | pointsXY.setNumberOfPoints(numberOfSegments + 1); 218 | const pointDataXY = new Float32Array(3 * (numberOfSegments + 1)); 219 | const vertsXY = new Uint32Array(2 * (numberOfSegments + 1)); 220 | const linesXY = new Uint32Array(numberOfSegments + 2); 221 | linesXY[0] = numberOfSegments + 1; 222 | 223 | for (let i = 0; i < numberOfSegments + 1; i++) { 224 | for (let j = 0; j < 3; j++) { 225 | const angle = i / (numberOfSegments - 1) * 2.0 * Math.PI; 226 | pointDataXY[3 * i + 0] = tubeRadius * Math.cos(angle); 227 | pointDataXY[3 * i + 1] = tubeRadius * Math.sin(angle); 228 | pointDataXY[3 * i + 2] = 0.0; 229 | } 230 | vertsXY[i] = 1; 231 | vertsXY[i + 1] = i; 232 | linesXY[i + 1] = i; 233 | } 234 | pointsXY.setData(pointDataXY); 235 | polyDataXY.setPoints(pointsXY); 236 | polyDataXY.getVerts().setData(vertsXY); 237 | polyDataXY.getLines().setData(linesXY); 238 | 239 | const tubeFilterXY = vtkTubeFilter.newInstance(); 240 | tubeFilterXY.setCapping(false); 241 | tubeFilterXY.setNumberOfSides(resolution); 242 | tubeFilterXY.setRadius(0.5); 243 | 244 | tubeFilterXY.setInputData(polyDataXY); 245 | 246 | const polyDataMapperXY = vtkMapper.newInstance(); 247 | polyDataMapperXY.setInputData(polyDataXY); 248 | 249 | const polyDataActorXY = vtkActor.newInstance(); 250 | polyDataActorXY.setMapper(polyDataMapperXY) 251 | 252 | const tubeMapperXY = vtkMapper.newInstance(); 253 | tubeMapperXY.setInputConnection(tubeFilterXY.getOutputPort()); 254 | 255 | const tubeActorXY = vtkActor.newInstance(); 256 | tubeActorXY.setMapper(tubeMapperXY) 257 | tubeActorXY.getProperty().setColor(atomColorR, atomColorG, atomColorB) 258 | 259 | const polyDataXZ = vtkPolyData.newInstance(); 260 | const pointsXZ = vtkPoints.newInstance({ dataType: pointType }); 261 | pointsXZ.setNumberOfPoints(numberOfSegments + 1); 262 | const pointDataXZ = new Float32Array(3 * (numberOfSegments + 1)); 263 | const vertsXZ = new Uint32Array(2 * (numberOfSegments + 1)); 264 | const linesXZ = new Uint32Array(numberOfSegments + 2); 265 | linesXZ[0] = numberOfSegments + 1; 266 | 267 | for (let i = 0; i < numberOfSegments + 1; i++) { 268 | for (let j = 0; j < 3; j++) { 269 | const angle = i / (numberOfSegments - 1) * 2.0 * Math.PI; 270 | pointDataXZ[3 * i + 0] = tubeRadius * Math.cos(angle); 271 | pointDataXZ[3 * i + 1] = 0.0; 272 | pointDataXZ[3 * i + 2] = tubeRadius * Math.sin(angle); 273 | } 274 | vertsXZ[i] = 1; 275 | vertsXZ[i + 1] = i; 276 | linesXZ[i + 1] = i; 277 | } 278 | pointsXZ.setData(pointDataXZ); 279 | polyDataXZ.setPoints(pointsXZ); 280 | polyDataXZ.getVerts().setData(vertsXZ); 281 | polyDataXZ.getLines().setData(linesXZ); 282 | 283 | const tubeFilterXZ = vtkTubeFilter.newInstance(); 284 | tubeFilterXZ.setCapping(false); 285 | tubeFilterXZ.setNumberOfSides(resolution); 286 | tubeFilterXZ.setRadius(0.5); 287 | 288 | tubeFilterXZ.setInputData(polyDataXZ); 289 | 290 | const polyDataMapperXZ = vtkMapper.newInstance(); 291 | polyDataMapperXZ.setInputData(polyDataXZ); 292 | 293 | const polyDataActorXZ = vtkActor.newInstance(); 294 | polyDataActorXZ.setMapper(polyDataMapperXZ) 295 | 296 | const tubeMapperXZ = vtkMapper.newInstance(); 297 | tubeMapperXZ.setInputConnection(tubeFilterXZ.getOutputPort()); 298 | 299 | const tubeActorXZ = vtkActor.newInstance(); 300 | tubeActorXZ.setMapper(tubeMapperXZ) 301 | tubeActorXZ.getProperty().setColor(atomColorR, atomColorG, atomColorB) 302 | 303 | const polyDataYZ = vtkPolyData.newInstance(); 304 | const pointsYZ = vtkPoints.newInstance({ dataType: pointType }); 305 | pointsYZ.setNumberOfPoints(numberOfSegments + 1); 306 | const pointDataYZ = new Float32Array(3 * (numberOfSegments + 1)); 307 | const vertsYZ = new Uint32Array(2 * (numberOfSegments + 1)); 308 | const linesYZ = new Uint32Array(numberOfSegments + 2); 309 | linesYZ[0] = numberOfSegments + 1; 310 | 311 | for (let i = 0; i < numberOfSegments + 1; i++) { 312 | for (let j = 0; j < 3; j++) { 313 | const angle = i / (numberOfSegments - 1) * 2.0 * Math.PI; 314 | pointDataYZ[3 * i + 0] = 0.0; 315 | pointDataYZ[3 * i + 1] = tubeRadius * Math.cos(angle); 316 | pointDataYZ[3 * i + 2] = tubeRadius * Math.sin(angle); 317 | } 318 | vertsYZ[i] = 1; 319 | vertsYZ[i + 1] = i; 320 | linesYZ[i + 1] = i; 321 | } 322 | pointsYZ.setData(pointDataYZ); 323 | polyDataYZ.setPoints(pointsYZ); 324 | polyDataYZ.getVerts().setData(vertsYZ); 325 | polyDataYZ.getLines().setData(linesYZ); 326 | 327 | const tubeFilterYZ = vtkTubeFilter.newInstance(); 328 | tubeFilterYZ.setCapping(false); 329 | tubeFilterYZ.setNumberOfSides(resolution); 330 | tubeFilterYZ.setRadius(0.5); 331 | 332 | tubeFilterYZ.setInputData(polyDataYZ); 333 | 334 | const polyDataMapperYZ = vtkMapper.newInstance(); 335 | polyDataMapperYZ.setInputData(polyDataYZ); 336 | 337 | const polyDataActorYZ = vtkActor.newInstance(); 338 | polyDataActorYZ.setMapper(polyDataMapperYZ) 339 | 340 | const tubeMapperYZ = vtkMapper.newInstance(); 341 | tubeMapperYZ.setInputConnection(tubeFilterYZ.getOutputPort()); 342 | 343 | const tubeActorYZ = vtkActor.newInstance(); 344 | tubeActorYZ.setMapper(tubeMapperYZ) 345 | tubeActorYZ.getProperty().setColor(atomColorR, atomColorG, atomColorB) 346 | 347 | return { sphereMapper, sphereActor, tubeActorXY, tubeMapperXY, tubeActorXZ, tubeMapperXZ, tubeActorYZ, tubeMapperYZ }; 348 | } 349 | 350 | updatePipeline() { 351 | const renderer = this.fullScreenRenderer.getRenderer(); 352 | const renderWindow = this.fullScreenRenderer.getRenderWindow(); 353 | 354 | if (this.pipeline) { 355 | renderer.removeActor(this.pipeline.actor); 356 | this.pipeline = null; 357 | } 358 | 359 | const resolution = this.props.resolution || 40 360 | this.pipeline = this.createPipeline(resolution); 361 | const pipeline = this.pipeline 362 | renderer.addActor(pipeline.sphereActor); 363 | renderer.addActor(pipeline.tubeActorXY); 364 | renderer.addActor(pipeline.tubeActorXZ); 365 | renderer.addActor(pipeline.tubeActorYZ); 366 | renderer.resetCamera(); 367 | renderWindow.render(); 368 | 369 | const camera = renderer.getActiveCamera(); 370 | camera.elevation(30.) 371 | camera.azimuth(30.) 372 | 373 | setInterval(function() { 374 | pipeline.tubeActorXY.rotateX(2.) 375 | pipeline.tubeActorXZ.rotateZ(3.) 376 | pipeline.tubeActorYZ.rotateY(5.) 377 | renderWindow.render(); 378 | }, 100) 379 | 380 | window.pipeline = this.pipeline; 381 | 382 | renderWindow.render(); 383 | } 384 | 385 | componentDidMount() { 386 | this.fullScreenRenderer = vtkFullScreenRenderWindow.newInstance({ 387 | background: [0.157, 0.172, 0.204], 388 | rootContainer: this.container.current, 389 | containerStyle: {}, 390 | }); 391 | this.updatePipeline(); 392 | } 393 | 394 | componentDidUpdate(prevProps) { 395 | if (prevProps.resolution !== this.props.resolution) { 396 | this.updatePipeline(); 397 | } 398 | } 399 | 400 | render() { 401 | return ( 402 |
403 |
404 |
405 |

406 | Edit src/App.js and save to reload. 407 |

408 | 414 | Learn itk.js 415 | 416 | 422 | Learn vtk.js 423 | 424 | 430 | Learn React 431 | 432 |
433 |
434 | ); 435 | } 436 | } 437 | 438 | export default App; 439 | ` 440 | fs.writeFileSync(path.resolve(destination, 'src', 'App.js'), appJs) 441 | 442 | const git = simpleGit(destination) 443 | git.add(['craco.config.js', 'package.json', 'yarn.lock', 'src/App.js']) 444 | git.commit('Updates from Create ITK App') 445 | 446 | console.log(chalk.green(`${chalk.bold('Enjoy building your itk.js app!')}`)) 447 | }) 448 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "create-itk-app", 3 | "version": "0.2.0", 4 | "description": "Create an application based on itk.js, vtk.js, and React.js.", 5 | "bin": { 6 | "create-itk-app": "./bin/create-itk-app.js" 7 | }, 8 | "scripts": { 9 | "test": "standard" 10 | }, 11 | "repository": { 12 | "type": "git", 13 | "url": "git+https://github.com/InsightSoftwareConsortium/create-itk-app.git" 14 | }, 15 | "keywords": [ 16 | "itk.js", 17 | "vtk.js", 18 | "react.js" 19 | ], 20 | "author": "Matt McCormick", 21 | "license": "Apache-2.0", 22 | "bugs": { 23 | "url": "https://github.com/InsightSoftwareConsortium/create-itk-app/issues" 24 | }, 25 | "homepage": "https://github.com/InsightSoftwareConsortium/create-itk-app#readme", 26 | "devDependencies": { 27 | "standard": "^12.0.1" 28 | }, 29 | "dependencies": { 30 | "chalk": "^2.4.2", 31 | "commander": "^2.20.0", 32 | "conjecture": "^0.1.2", 33 | "cross-spawn": "^6.0.5", 34 | "edit-json-file": "^1.2.1", 35 | "inquirer": "^6.3.1", 36 | "lodash.kebabcase": "^4.1.1", 37 | "simple-git": "^1.113.0", 38 | "stringify-author": "^0.1.3", 39 | "validate-npm-package-name": "^3.0.0" 40 | } 41 | } 42 | --------------------------------------------------------------------------------