Index: js/human_3d_alignment/.eslintrc
===================================================================
--- js/human_3d_alignment/.eslintrc	(revision 881)
+++ js/human_3d_alignment/.eslintrc	(revision 881)
@@ -0,0 +1,90 @@
+{
+  "plugins": [
+    "react"
+  ],
+  "parserOptions": {
+    "ecmaVersion": 6,
+    "sourceType": "module",
+    "ecmaFeatures": {
+      "jsx": true,
+      "experimentalObjectRestSpread": true
+    }
+  },
+  "env": {
+    "es6": true,
+    "browser": true,
+    "node": true,
+    "mocha": true
+  },
+  "extends": [
+    "eslint:recommended",
+    "plugin:react/recommended"
+  ],
+  "rules": {
+    "no-debugger": 2,
+    "brace-style": [
+      0,
+      "1tbs",
+      {
+        "allowSingleLine": true
+      }
+    ],
+    "no-trailing-spaces": 0,
+    "keyword-spacing": 2,
+    "space-before-function-paren": [
+      2,
+      "never"
+    ],
+    "spaced-comment": [
+      0,
+      "always"
+    ],
+    "vars-on-top": 2,
+    "no-undef": 2,
+    "no-undefined": 2,
+    "comma-dangle": [
+      0,
+      "never"
+    ],
+    "semi": [
+      1,
+      "always"
+    ],
+    "guard-for-in": 2,
+    "no-eval": 2,
+    "no-with": 2,
+    "no-var": 2,
+    "valid-typeof": 2,
+    "no-unused-vars": 1,
+    "no-continue": 1,
+    "no-extra-semi": 1,
+    "no-unreachable": 1,
+    "no-unused-expressions": 1,
+    "no-magic-numbers": 0,
+    "react/prefer-es6-class": 1,
+    "react/prop-types": 0,
+    "react/no-find-dom-node": 0,
+    "no-console": 1,
+    "require-jsdoc": [
+      "warn",
+      {
+        "require": {
+          "FunctionDeclaration": true,
+          "MethodDefinition": true,
+          "ClassDeclaration": true,
+          "ArrowFunctionExpression": false,
+          "FunctionExpression": false
+        }
+      }
+    ],
+    "valid-jsdoc": [
+      "warn",
+      {
+        "prefer": {
+          "return": "returns"
+        },
+        "requireReturn": false
+      }
+    ]
+  }
+}
Index: js/human_3d_alignment/.vscode/launch.json
===================================================================
--- js/human_3d_alignment/.vscode/launch.json	(revision 881)
+++ js/human_3d_alignment/.vscode/launch.json	(revision 881)
@@ -0,0 +1,20 @@
+{
+    // Use IntelliSense to learn about possible attributes.
+    // Hover to view descriptions of existing attributes.
+    // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
+    "version": "0.2.0",
+    "configurations": [
+        {
+            "type": "chrome",
+            "request": "launch",
+            "name": "Launch Chrome",
+            "url": "http://localhost:3000",
+            "webRoot": "${workspaceFolder}",
+            "sourceMaps": true,
+            "sourceMapPathOverrides": {
+                "src\\*": "${workspaceFolder}\\src\\*",
+                "external\\*": "${workspaceFolder}\\external\\*"
+            },
+        }
+    ]
+}
Index: js/human_3d_alignment/README.txt
===================================================================
--- js/human_3d_alignment/README.txt	(revision 881)
+++ js/human_3d_alignment/README.txt	(revision 881)
@@ -0,0 +1,40 @@
+This project is the app for performing an experiment where humans align two 3D ball-and-stick structures (models).
+
+
+Before creating any widgets or other components that use Framsticks SDK,
+the SDK needs to be prepared and present - see ../sdk/README.txt.
+
+Once you have Framsticks SDK compiled to js, run the following commands in project root:
+	bash
+	npm install # for installing all required dependencies and preparing gulp task manager
+	gulp        # for compiling all JSX and ES2015 files
+	
+To generate documentation:
+	bash
+	gulp doc
+
+To synchronize the browser with your builds:
+	bash
+	gulp browser-sync
+
+To just check the code for potential errors, use ESLint:
+	bash
+	gulp eslint
+
+To make ESLint more or less strict, edit the .eslintrc file. Popular options for ES2015 and React:
+ - Official ESLint rules: https://eslint.org/docs/rules/
+ - Use ESLint Like a Pro with ES6 and React: http://www.zsoltnagy.eu/use-eslint-like-a-pro-with-es6-and-react/
+ - eslint-plugin-react: https://www.npmjs.com/package/eslint-plugin-react
+ - eslint-plugin-babel: https://github.com/babel/eslint-plugin-babel
+
+
+You can edit sources with Visual Studio Code. It will allow you to debug with 
+Google Chrome after a basic setup. Debugging (using Debugger for Chrome Extension)
+is facilitated by the JSON file in the .vscode directory. 
+
+The .vscode directory is optional and can be removed or replaced by an automatic JSON generator.
+Still, it already contains a universal configuration for easy debugging.
+
+If breakpoints do not work for you, there may be a problem with source 
+mapping - look for solutions in gulp-sourcemaps documentation (https://github.com/gulp-sourcemaps/gulp-sourcemaps) 
+and VS Code Debugger for Chrome (https://github.com/Microsoft/vscode-chrome-debug).
Index: js/human_3d_alignment/gulpfile.js
===================================================================
--- js/human_3d_alignment/gulpfile.js	(revision 881)
+++ js/human_3d_alignment/gulpfile.js	(revision 881)
@@ -0,0 +1,51 @@
+var gulp = require('gulp');
+var browserify = require('browserify');
+var eslint = require('gulp-eslint');
+var babelify = require('babelify');
+var source = require('vinyl-source-stream');
+var buffer = require('vinyl-buffer');
+var browserSync = require('browser-sync').create();
+var sourcemaps = require('gulp-sourcemaps');
+var jsdoc = require('gulp-jsdoc3');
+
+gulp.task('eslint', function() {
+    return gulp.src(['src/**/*.jsx','src/**/*.js', 'src/*.jsx'])
+        .pipe(eslint())
+        .pipe(eslint.format())
+        .pipe(eslint.failOnError());
+});
+
+gulp.task('build', function () {
+    return browserify({entries: './src/app.jsx', extensions: ['.jsx'], debug: true})
+        .ignore('./sdk-core/frams_sdk.js', './external/physijs/*')
+        .transform(babelify, {presets: ['es2015', 'react']})
+        .bundle()
+        .pipe(source('bundle.js'))
+        .pipe(buffer())
+        .pipe(sourcemaps.init({loadMaps: true}))
+        .pipe(sourcemaps.write('.', {
+            includeContent: true,
+            sourceRoot: '.'
+        }))
+        .pipe(gulp.dest('dist'));
+});
+
+gulp.task('watch', ['eslint', 'build'], function () {
+    gulp.watch(['src/**/*.jsx','src/**/*.js'], ['build']);
+});
+
+gulp.task('browser-sync', function() {
+    browserSync.init({
+        server: {
+            baseDir: "./"
+        }
+    });
+    gulp.watch("dist/*").on('change',browserSync.reload);
+});
+
+gulp.task('doc', function(cb) {
+    gulp.src(['DOCUMENTATION.md', './src/**/*.jsx', './src/**/*.js'], {read: false})
+        .pipe(jsdoc(cb));
+});
+
+gulp.task('default', ['eslint', 'build']);
Index: js/human_3d_alignment/index.html
===================================================================
--- js/human_3d_alignment/index.html	(revision 881)
+++ js/human_3d_alignment/index.html	(revision 881)
@@ -0,0 +1,24 @@
+<!DOCTYPE html>
+<html>
+<head lang="en">
+    <meta charset="UTF-8">
+    <title>Framsticks JS</title>
+    <link rel="stylesheet" type="text/css" href="node_modules/react-grid-layout/css/styles.css">
+    <link rel="stylesheet" type="text/css" href="node_modules/react-resizable/css/styles.css">
+    <link rel="stylesheet" type="text/css" href="node_modules/react-table/react-table.css">
+    <meta name='viewport' content="width=device-width, user-scalable=no"/>
+</head>
+<body>
+	<script type="text/javascript">
+        var Module = { onRuntimeInitialized: function() {
+          console.log('loaded Framsticks');
+          var event = new Event('emReady');
+          //window.geneticsObject = new Module.PreconfiguredGenetics();
+          document.dispatchEvent(event);
+        } };
+    </script>
+	<div class="root"></div>
+    <script type="text/javascript" src="../sdk/frams-sdk.js"></script>
+    <script type="text/javascript" src="dist/bundle.js"></script>
+</body>
+</html>
Index: js/human_3d_alignment/package.json
===================================================================
--- js/human_3d_alignment/package.json	(revision 881)
+++ js/human_3d_alignment/package.json	(revision 881)
@@ -0,0 +1,68 @@
+{
+  "name": "matching-js",
+  "version": "0.0.1",
+  "description": "GUI for the 3D matching experiment",
+  "main": "index.js",
+  "scripts": {
+    "test": "test",
+    "start": "gulp"
+  },
+  "repository": {
+    "type": "svn",
+    "url": "https://www.framsticks.com/svn/framsticks/js/human_3d_alignment/"
+  },
+  "keywords": [
+    "evolutionary design",
+    "3D model",
+    "alignment",
+    "Framsticks",
+    "artificial life",
+    "simulation",
+    "evolution",
+    "similarity",
+    "global convexity"
+  ],
+  "contributors": [
+    "Maciej Komosinski <maciej.komosinski@cs.put.poznan.pl>",
+    "Grzegorz Latosiński",
+    "Agnieszka Mensfelt <agnieszka.mensfelt@cs.put.poznan.pl>",
+    "Szymon Ulatowski"
+  ],
+  "license": "ISC",
+  "bugs": {
+    "url": "http://framsticks.com/trac/framsticks/report"
+  },
+  "dependencies": {
+    "babel-core": "^6.26.0",
+    "babel-preset-es2015": "^6.24.1",
+    "eslint-plugin-react": "^7.5.1",
+    "gulp-eslint": "^4.0.1",
+    "gulp-sourcemaps": "^2.6.3",
+    "immutability-helper": "^2.6.0",
+    "lodash": "^4.17.4",
+    "notevil": "^1.1.0",
+    "prop-types": "^15.6.0",
+    "react": "^16.2.0",
+    "react-contenteditable": "^2.0.5",
+    "react-dom": "^16.2.0",
+    "react-grid-layout": "^0.16.6",
+    "react-icons": "^2.2.7",
+    "react-treebeard": "^2.1.0",
+    "strip-comment": "^1.1.3",
+    "three": "^0.88.0",
+    "three-orbit-controls": "^82.1.0"
+  },
+  "devDependencies": {
+    "babel-plugin-undeclared-variables-check": "^6.22.0",
+    "babel-preset-es2015": "^6.24.1",
+    "babel-preset-react": "^6.24.1",
+    "babelify": "^8.0.0",
+    "browser-sync": "^2.18.13",
+    "browserify": "^16.1.1",
+    "gulp": "^3.9.1",
+    "gulp-jsdoc3": "^1.0.1",
+    "gulp-sourcemaps": "^2.6.3",
+    "vinyl-buffer": "^1.0.1",
+    "vinyl-source-stream": "^2.0.0"
+  }
+}
Index: js/human_3d_alignment/src/app.jsx
===================================================================
--- js/human_3d_alignment/src/app.jsx	(revision 881)
+++ js/human_3d_alignment/src/app.jsx	(revision 881)
@@ -0,0 +1,8 @@
+import MainView from './index';
+import React from 'react';
+import ReactDOM from 'react-dom';
+
+ReactDOM.render(
+    <MainView />,
+    document.querySelector('.root')
+);
Index: js/human_3d_alignment/src/index.jsx
===================================================================
--- js/human_3d_alignment/src/index.jsx	(revision 881)
+++ js/human_3d_alignment/src/index.jsx	(revision 881)
@@ -0,0 +1,120 @@
+/*global Module*/
+"use strict";
+import React from 'react';
+import TitlePanel from './viewskeleton/titlepanel';
+import WidgetsContainer from './viewskeleton/widgetscontainer';
+import SimilViewer from './widgets/similviewer';
+
+const styles = {
+    contentHeaderMenuLink: {
+        textDecoration: 'none',
+        color: 'white',
+        padding: 8,
+    },
+    content: {
+        padding: '16px',
+    },
+    sidebarLink: {
+        display: 'block',
+        padding: '16px 0px',
+        color: 'gray',
+        textDecoration: 'none',
+    },
+    divider: {
+        margin: '8px 0',
+        height: 1,
+        backgroundColor: 'gray',
+    },
+};
+
+//const mql = window.matchMedia('(min-width: 800px)');
+
+/**
+ * Main class running Framsticks.JS page.
+ */
+class MainView extends React.Component {
+    /**
+     * Basic constructor holding informations about sidebar states
+     * @param {any} props component properties
+     */
+    constructor(props) {
+        super(props);
+        this.onLayoutChange = this.onLayoutChange.bind(this);
+
+        window.genetics = new Module.PreconfiguredGenetics();
+        this.layout = [
+            {name:'0,similviewer', x: 0, y: 0, w: 12, h: 4}
+        ];
+
+        this.container = <WidgetsContainer onRef={ref => (this.widgetscontainer = ref)} onLayoutChange={this.onLayoutChange} />;
+
+        this.state = {
+            parametersmodal: false
+        };
+    }
+
+    /** 
+     * Uses default layout.
+    */
+    componentDidMount() {
+        this.useLayout(this.layout);
+    }
+
+    /** 
+     * Calls resize event in order to properly set layout
+    */
+    componentDidUpdate() {
+        window.dispatchEvent(new Event('resize'));
+    }
+
+    /**
+     * Stores layout, for LocalStorage layout saving
+     * @param {any} layout layout to be saved
+     */
+    onLayoutChange(layout) {
+        let newlayout = [];
+        for (let i = 0; i < layout.length; i++) {
+            newlayout.push({name: layout[i].i, x: layout[i].x, y: layout[i].y, w: layout[i].w, h: layout[i].h});
+        }
+    }
+    /**
+     * Passes layout to widgetscontainer.
+     * @param {any} layout layout to be used
+     */
+    useLayout(layout) {
+        let items = [];
+        for (let i = 0; i < layout.length; i++) {
+            let name = layout[i].name.split(',')[1];
+            switch (name) {
+                case 'similviewer':
+                    items.push({content: <SimilViewer/>, i: "" + i + 'similviewer',
+                        x: layout[i].x, y: layout[i].y, w: layout[i].w, h: layout[i].h});
+                    break;
+            }
+        }
+        this.widgetscontainer.addMultipleItems(items);
+    }
+
+    /**
+     * Render function.
+     * @returns {JSX.Element} main page of Framsticks.JS
+     */
+    render() {
+        
+        const contentHeader = (
+            <span>   
+                <span style={{marginLeft: '20px'}}>Matching in 3D</span> 
+            </span>
+        );
+        
+        return (
+                <TitlePanel title={contentHeader}>
+                    <div style={styles.content}>
+                        {this.container}
+                    </div>
+                </TitlePanel>
+        );
+    }
+}
+
+export default MainView;
Index: js/human_3d_alignment/src/utils/genotypeparser.js
===================================================================
--- js/human_3d_alignment/src/utils/genotypeparser.js	(revision 881)
+++ js/human_3d_alignment/src/utils/genotypeparser.js	(revision 881)
@@ -0,0 +1,68 @@
+/*global Module*/
+"use strict";
+
+/**
+ * Static class containing tools for genotype parsing.
+ */
+class GenotypeParser {
+    /**
+     * Methods for checking if the given genotype is valid
+     * @param {string} genotype input genotype
+     * @returns {boolean} true if genotype is valid, false otherwise
+     */
+    static parseGeno(genotype) {
+        //let genetics = new Module.PreconfiguredGenetics();
+        let stringObj = new Module.SString();
+        stringObj.set(genotype);
+    
+        let genoObj = new Module.Geno(stringObj);
+        let result = genoObj.isValid();
+        Module.destroy(genoObj);
+        Module.destroy(stringObj);
+        //Module.destroy(genetics);
+        return result;
+    }
+
+    /**
+     * HTML-ize genotype for syntax highlighting. The generated genotype is ready to use.
+     * Based on Genman::HTMLize method from Framsticks SDK.
+     * @param {string} genotype input genotype
+     * @returns {string} HTML code that displays highlighted genotype code
+     */
+    static generateHighlights(genotype) {
+        //let genetics = new Module.PreconfiguredGenetics();
+        //let stringObj = new Module.SString();
+        //stringObj.set(genotype);
+        let resultObj = window.genetics.get_genman().HTMLize(genotype);
+        let result = resultObj.c_str();
+        //Module.destroy(resultObj);
+        //Module.destroy(stringObj);
+        //Module.destroy(genetics);
+        return result;
+    }
+
+    /**
+     * Method that parse genotype and returns Framsticks Model.
+     * @param {string} genotype string code for Framsticks creature
+     * @returns {Module.Model} Model from genotype, or undefined if genotype is not valid
+     */
+    static getModelFromGenotype(genotype) {
+        //let genetics = new Module.PreconfiguredGenetics();
+        let stringObj = new Module.SString();
+        stringObj.set(genotype);
+        let genoObj = new Module.Geno(stringObj);
+        if (!genoObj.isValid()) {
+            Module.destroy(stringObj);
+            Module.destroy(genoObj);
+            //Module.destroy(genetics);
+            return; //undefined
+        }
+        let model = new Module.Model(genoObj, true);
+        Module.destroy(stringObj);
+        Module.destroy(genoObj);
+        //Module.destroy(genetics);
+        return model;
+    }
+}
+
+export default GenotypeParser;
Index: js/human_3d_alignment/src/viewskeleton/titlepanel.jsx
===================================================================
--- js/human_3d_alignment/src/viewskeleton/titlepanel.jsx	(revision 881)
+++ js/human_3d_alignment/src/viewskeleton/titlepanel.jsx	(revision 881)
@@ -0,0 +1,46 @@
+"use strict";
+import React from 'react';
+import update from 'immutability-helper';
+
+const styles = {
+    root: {
+        fontFamily: '"HelveticaNeue-Light", "Helvetica Neue Light", "Helvetica Neue", Helvetica, Arial, "Lucida Grande", sans-serif',
+        fontWeight: 300,
+    },
+    header: {
+        width: '100%',
+        backgroundColor: 'black',
+        color: 'white',
+        padding: '16px 0px 16px 0px',
+        fontSize: '1.5em',
+    }
+};
+
+/**
+ * Class for rendering main top panel of Framsticks.JS site.
+ */
+class TitlePanel extends React.Component {
+    /**
+     * Basic constructor for TitlePanel
+     * @param {any} props props for titlepanel
+     */
+    constructor(props) {
+        super(props);
+        this.rootStyle = props.style ? update(styles.root, {$merge: props.style}) : styles.root;
+    }
+
+    /**
+     * Render method
+     * @returns {JSX.Element} new title panel
+     */
+    render() {
+        return (
+        <div style={this.rootStyle}>
+            <div style={styles.header}>{this.props.title}</div>
+            {this.props.children}
+        </div>
+        );
+    }
+}
+
+export default TitlePanel;
Index: js/human_3d_alignment/src/viewskeleton/widgetscontainer.jsx
===================================================================
--- js/human_3d_alignment/src/viewskeleton/widgetscontainer.jsx	(revision 881)
+++ js/human_3d_alignment/src/viewskeleton/widgetscontainer.jsx	(revision 881)
@@ -0,0 +1,176 @@
+"use strict";
+import React from 'react';
+import { WidthProvider, Responsive} from 'react-grid-layout';
+import _ from 'lodash';
+
+const ResponsiveReactGridLayout = WidthProvider(Responsive);
+
+/**
+ * Component holding all widgets of Framsticks-JS. It bases on 'react-grid-layout'
+ * component, making it possible to create mini-windows within website.
+ */
+class WidgetsContainer extends React.Component {
+    /**
+     * Creates instance of WidgetsContainer. It starts in the beginning with no 
+     * items. To add items you need to explicitly call object method addItem 
+     * with React.Component.
+     * @param {any} props Basic props for React Components
+     */
+    constructor(props) {
+        super(props);
+
+        this.state = {
+            items: [],
+            widgetCounter: 0,
+        };
+        this.props = props;
+        //this.onAddItem = this.onAddItem.bind(this);
+        this.onBreakpointChange = this.onBreakpointChange.bind(this);
+        this.onLayoutChange = this.onLayoutChange.bind(this);
+    }
+
+    /**
+     * Initializes references.
+     */
+    componentDidMount() {
+        this.props.onRef(this);
+    }
+
+    /**
+     * Unmounts references
+     */
+    componentWillUnmount() {
+        this.props.onRef(void 0);
+    }
+
+    /**
+     * Creates widgets in Framsticks-JS. It is strictly internal method for
+     * this Component and should not be called outside. It is used in
+     * render() function. It holds default styles for widgets windows.
+     * @param {React.Component} el widget to be added to board
+     * @returns {JSX.Element} new widget
+     */
+    createElement(el) {
+        const removeStyle = {
+            right: "2px",
+            marginRight: "10px",
+            top: 0,
+            cursor: "pointer",
+        };
+        const content = el.content ? el.content : "none";
+        let gridStyle = {
+            backgroundColor: '#AAAAAA',
+            display: 'table',
+            padding: 0,
+            boxShadow: "0 4px 8px 0 rgba(0, 0, 0, 0.2), 0 6px 20px 0 rgba(0, 0, 0, 0.19)"
+        };
+        return (
+            <div key={el.i} data-grid={el} style={gridStyle}>
+                {/* <span className="text" style={gridStyle}>{el.content}</span> */}
+                <div style={{display: 'table-row', textAlign: 'right'}}>
+                <span
+                    className="remove"
+                    style={removeStyle}
+                    onClick={this.onRemoveItem.bind(this,el.i)}
+                >&#10006;</span>
+                </div>
+                <div style={{display: 'table-row', height: '100%'}}>
+                    {content}
+                </div>
+            </div>
+        );
+    }
+
+    /**
+     * Adds new React.Component to Framsticks-JS board. This method should
+     * be used externally instead of createElement to add new element. It
+     * holds and remembers newly added components.
+     * @param {React.Component} item new widget to be added to board
+     * @param {string} name name of used component, useful for remembering layout
+     * @param {number} x OX position of widget
+     * @param {number} y OY position of widget
+     * @param {number} w width of widget
+     * @param {number} h height of widget
+     * @example <caption>Example of using addItem with GenoChecker widget</caption>
+     * this.widgetscontainer.addItem(<GenoChecker />);
+     */
+    addItem(item, name, x=0, y=Infinity, w=2, h=2) {
+        this.setState({
+            items: this.state.items.concat({
+                i: ""+this.state.widgetCounter+","+name,
+                content: item,
+                //x: (this.state.items.length) % (this.state.cols || 12),
+                //y: Infinity,
+                x: x,
+                y: y,
+                w: w,
+                h: h
+            }),
+            widgetCounter: this.state.widgetCounter+1,
+        });
+    }
+
+    /**
+     * Uses list of layout items to be distributed on site.
+     * @param {any} layoutitems list of items.
+     */
+    addMultipleItems(layoutitems) {
+        this.setState({
+            items: layoutitems,
+            widgetCounter: layoutitems.length
+        });
+    }
+
+    /**
+     * Method implemented for responsive behaviour of 'react-grid-layout'.
+     * @param {any} breakpoint new breakpoint for layout
+     * @param {any} cols new number of columns in grid
+     */
+    onBreakpointChange(breakpoint, cols) {
+        this.setState({
+            breakpoint: breakpoint,
+            cols: cols
+        });
+    }
+
+    /**
+     * Event running on change of 'react-grid-layout' Component.
+     * @param {any} layout layout which should be selected next
+     */
+    onLayoutChange(layout) {
+        if (this.props.onLayoutChange) this.props.onLayoutChange(layout);
+        //this.props.onLayoutChange(layout);
+        this.setState({layout: layout});
+    }
+
+    /**
+     * This events run on removing i-th item in 'react-grid-layout'.
+     * @param {number} i id of item to be removed
+     */
+    onRemoveItem(i) {
+        this.setState({items: _.reject(this.state.items, {i:i})});
+    }
+
+    /**
+     * WidgetsContainer render method.
+     * @returns {JSX.Element} WidgetsContainer
+     */
+    render() {
+        return (
+            <div>
+                <ResponsiveReactGridLayout
+                    layout={this.state.layout}
+                    onLayoutChange={this.onLayoutChange}
+                    onBreakpointChange={this.onBreakpointChange}
+                    cols={{ lg: 12, md: 10, sm: 6, xs: 4, xxs: 2 }}
+                    className="layout"
+                    {...this.props}
+                >
+                    {_.map(this.state.items, el=>this.createElement(el))}
+                </ResponsiveReactGridLayout>
+            </div>
+        );
+    }
+}
+
+export default WidgetsContainer;
Index: js/human_3d_alignment/src/visualization/camera.js
===================================================================
--- js/human_3d_alignment/src/visualization/camera.js	(revision 881)
+++ js/human_3d_alignment/src/visualization/camera.js	(revision 881)
@@ -0,0 +1,140 @@
+"use strict";
+import * as THREE from 'three';
+
+const OrbitControls = require('three-orbit-controls')(THREE);
+
+/**
+ * Class for creating camera object in THREE.js view. it uses OrbitControls for
+ * user moving. It is designed to work with model analysis.
+ */
+class Camera {
+    /**
+     * Method for Camera initialization. It's adjusting the view according to
+     * camera resize, prepares OrbitControls as default controller.
+     */
+    init() {
+        this.perspectiveCamera = new THREE.PerspectiveCamera(
+            this.config.fieldOfView,
+            window.innerWidth / window.innerHeight,
+            this.config.near,
+            this.config.far
+        );
+        this.perspectiveCamera.up.set(0,0,1);
+        this.cameraControl = new OrbitControls(this.perspectiveCamera, this.rendererDOMElement);
+        this.cameraControl.autoRotate = this.autoRotate;
+        this.cameraControl.autoRotateSpeed = this.config.autoRotateSpeed;
+        this.cameraControl.enableKeys = false;
+    }
+
+    /**
+     * Creates instance of camera, then initalizes it with init() method
+     * @param {{fieldOfView: number, near: number, far: number}} config Configuration of Camera view
+     * @param {Element} rendererDOMElement Canvas in which element will be drawn.
+     * @param {boolean} autoRotate true if camera should rotate, false otherwise
+     */
+    constructor(config, rendererDOMElement, autoRotate) {
+        this.config = config;
+        this.rendererDOMElement = rendererDOMElement;
+        this.autoRotate = autoRotate;
+        this.perspectiveCamera = null;
+        this.cameraControl = null;
+        this.init();
+    }
+
+    /**
+     * Method for updating modelBox coordinates
+     * @param {{min: {x: number, y: number, z: number}, max: {x: number, y: number, z: number}}} modelBox Bounding box of Model
+     * @param {{min: {x: number, y: number, z: number}, max: {x: number, y: number, z: number}}} box update of bounding box
+     */
+    updateModelBox(modelBox, box) {
+        modelBox.min.x = Math.min( modelBox.min.x, box.min.x );
+        modelBox.min.y = Math.min( modelBox.min.y, box.min.y );
+        modelBox.min.z = Math.min( modelBox.min.z, box.min.z );
+
+        modelBox.max.x = Math.max( modelBox.max.x, box.max.x );
+        modelBox.max.y = Math.max( modelBox.max.y, box.max.y );
+        modelBox.max.z = Math.max( modelBox.max.z, box.max.z );
+    }
+
+    /**
+     * Extracts bounding box of given object.
+     * @param {Object3D} object object for which bounding box is extracted
+     * @returns {Box3} bounding box of object
+     */
+    getBoundingBox(object) {
+        let box = new THREE.Box3();
+        box.setFromObject(object);
+        return box;
+    }
+
+    /**
+     * Calculates Camera position and rotation that should be used in order to see all meshes in scene.
+     * @param {Mesh[]} meshes list of meshes to be bound by camera.
+     * @returns {{target: {x: number, y: number, z: number}, position: {x: number, y: number, z: number}}} new position of Camera and target, to which Camera should point
+     */
+    calculateCameraSetting(meshes) {
+        if (meshes.length == 0) {
+            return this.config.defaultSettings;
+        }
+
+        let modelBox = new THREE.Box3();
+        for (let i = 0; i < meshes.length; i++) {
+            let mesh = meshes[i];
+            let box = this.getBoundingBox(mesh);
+            this.updateModelBox(modelBox, box);
+        }
+
+        let modelSphere = modelBox.getBoundingSphere();
+
+        return {
+            target: {
+                x: modelSphere.center.x,
+                y: modelSphere.center.y,
+                z: modelSphere.center.z
+            },
+            position: {
+                x: modelSphere.center.x + modelSphere.radius,
+                y: modelSphere.center.y + modelSphere.radius,
+                z: modelSphere.center.z + modelSphere.radius
+            }
+        };
+    }
+
+    /**
+     * Moves Camera to cover all selected meshes in canvas.
+     * @param {Mesh[]} meshes list of meshes to be seen
+     */
+    zoomAll(meshes) {
+        let settings = this.calculateCameraSetting(meshes);
+        this.cameraControl.target.set(settings.target.x, settings.target.y, settings.target.z);
+        this.perspectiveCamera.position.set(settings.position.x, settings.position.y, settings.position.z);
+        this.cameraControl.update();
+    }
+
+    /**
+     * Getter for THREE.js perspective camera logic.
+     * @returns {PerspectiveCamera} reference to Camera perspective camera
+     */
+    getPerspectiveCamera() {
+        return this.perspectiveCamera;
+    }
+
+    /**
+     * Getter for THREE.js orbit controls logic.
+     * @returns {OrbitControls} reference to Camera orbit controls
+     */
+    getCameraControl() {
+        return this.cameraControl;
+    }
+
+    /**
+     * Sets the camera autorotation property.
+     * @param {boolean} autoRotate true if camera should autorotate, false otherwise
+     */
+    setAutoRotate(autoRotate) {
+        this.autoRotate = autoRotate;
+        this.cameraControl.autoRotate = this.autoRotate;
+    }
+}
+
+export default Camera;
Index: js/human_3d_alignment/src/visualization/jointmeshfactory.js
===================================================================
--- js/human_3d_alignment/src/visualization/jointmeshfactory.js	(revision 881)
+++ js/human_3d_alignment/src/visualization/jointmeshfactory.js	(revision 881)
@@ -0,0 +1,135 @@
+"use strict";
+import * as THREE from 'three';
+import Transformations from './transformations';
+
+/**
+ * Helper class for creating meshes for joints in Framsticks-SDK. It combines 
+ * Framsticks-SDK logic with THREE.js logic.
+ * 
+ * For now shape versions of joints are hard-coded. It may need redefinition in 
+ * the future.
+ */
+class JointMeshFactory {
+    /**
+     * Basic constructor that takes information of how joints should be drawn.
+     * @param {object} config basic config for joints drawing
+     * @param {boolean} physics determines if created objects should by Physijs based
+     */
+    constructor(config, physics = false) {
+        this.config = config;
+        this.transformations = new Transformations();
+        this.jointShapes = this.transformations.getJointShapes();
+        this.physics = physics;
+    }
+
+    /**
+     * Creates Mesh for a given Joint.
+     * @param {Module.Joint} joint Framsticks-SDK Joint class object
+     * @param {object}  shapeConfig object holding following fields
+     * @param {number}  shapeConfig.radius radius of mesh
+     * @param {number}  shapeConfig.radiusSegments number of segments for mesh
+     * @param {boolean} shapeConfig.isTransparent true if transparent, false otherwise
+     * @param {number}  shapeConfig.opacity opacity of mesh
+     * @returns {Mesh}  Mesh for a given joint
+     */
+    getNewJointMesh(joint, shapeConfig) {
+        let firstPartPosVec = new THREE.Vector3(
+            joint.get_part1().get_p().get_x(), 
+            joint.get_part1().get_p().get_y(), 
+            joint.get_part1().get_p().get_z());
+        let secondPartPosVec = new THREE.Vector3(
+            joint.get_part2().get_p().get_x(), 
+            joint.get_part2().get_p().get_y(), 
+            joint.get_part2().get_p().get_z());
+        //let line = new THREE.LineCurve3(firstPartPosVec, secondPartPosVec);
+        //let geometry = new THREE.TubeGeometry(line, numsegmentstube, shapeConfig.radius, 
+        //    shapeConfig.radiusSegments, false);
+
+        let direction = new THREE.Vector3().subVectors(secondPartPosVec, firstPartPosVec);
+        let orientation = new THREE.Matrix4();
+
+        let geometry = new THREE.CylinderGeometry(shapeConfig.radius, shapeConfig.radius, direction.length(), shapeConfig.radiusSegments);
+        
+
+        let material = this.transformations.getNewMaterial(
+            joint.get_vcolor().get_x(), 
+            joint.get_vcolor().get_y(), 
+            joint.get_vcolor().get_z());
+        material.transparent = shapeConfig.isTransparent;
+        material.opacity = shapeConfig.opacity;
+        //let mesh = new THREE.Mesh(geometry, material);
+        
+        let mesh = new THREE.Mesh( geometry, material ); //new Physijs.CylinderMesh( geometry, Physijs.createMaterial(material) ); //new THREE.Mesh( geometry, material );
+
+        orientation.lookAt(firstPartPosVec, secondPartPosVec, new THREE.Object3D().up);
+        orientation.multiply(new THREE.Matrix4().set(
+            1, 0, 0, 0, 
+            0, 0, 1, 0, 
+            0, -1, 0, 0, 
+            0, 0, 0, 1
+        ));
+
+        mesh.applyMatrix(orientation);
+        mesh.position.x = (secondPartPosVec.x + firstPartPosVec.x) / 2;
+        mesh.position.y = (secondPartPosVec.y + firstPartPosVec.y) / 2;
+        mesh.position.z = (secondPartPosVec.z + firstPartPosVec.z) / 2;
+        
+        
+        mesh.userData = { 
+            isBodyElement: true, 
+            type: 'j', 
+            data: joint, 
+            mesh: mesh, 
+            connectedParts: [], 
+            showTransparent: shapeConfig.isTransparent 
+        };
+        return mesh;
+    }
+
+    /**
+     * Method finds for a given jointMesh all attached partMeshes and updates 
+     * respectively for those objects their connectedParts and connectedJoints 
+     * fields.
+     * @param {JointMesh}  jointMesh joint for which attached parts will be searched
+     * @param {PartMesh}  partMeshes list of available parts
+     */
+    addConnectionInfo(jointMesh, partMeshes) {
+        let p1 = jointMesh.data.get_part1();
+        let p2 = jointMesh.data.get_part2();
+        let count = 0;
+        for (let i = 0; i < partMeshes.length && count < 2; ++i) {
+            if (partMeshes[i].data === p1 || partMeshes[i].data === p2) {
+                jointMesh.connectedParts.push(partMeshes[i]);
+                partMeshes[i].connectedJoints.push(jointMesh);
+                ++count;
+            }
+        }
+    }
+
+    /**
+     * Creates mesh for a given Joint. Additional parameter partMeshes is 
+     * provided to update both Joint and connected Parts with info about 
+     * their connectivity.
+     * @param {Module.Joint} joint joint for which mesh is created
+     * @param {PartMesh}  partMeshes list of available parts
+     * @returns {JointMesh} new joint mesh, for properties of Object look at addConnectionInfo jointMesh param documentation
+     */
+    create(joint, partMeshes) {
+        let result;
+        let shape = joint.get_shape();
+
+        if (this.jointShapes['SHAPE_FIXED'].value == shape) {
+            result = this.getNewJointMesh(joint, this.config.linkShape);
+        } else {
+            result = this.getNewJointMesh(joint, this.config.cylinderShape);
+        }
+
+        if (partMeshes) {
+            this.addConnectionInfo(result.userData, partMeshes);
+        }
+
+        return result;
+    }
+}
+
+export default JointMeshFactory;
Index: js/human_3d_alignment/src/visualization/partmeshfactory.js
===================================================================
--- js/human_3d_alignment/src/visualization/partmeshfactory.js	(revision 881)
+++ js/human_3d_alignment/src/visualization/partmeshfactory.js	(revision 881)
@@ -0,0 +1,206 @@
+"use strict";
+import * as THREE from 'three';
+import Transformations from './transformations';
+
+/**
+ * Helper class for creating meshes for parts in Framsticks-SDK. 
+ * It combines Framsticks-SDK logic with THREE.js logic.
+ * 
+ * For now shape versions of parts are hard-coded. It may need redefinition 
+ * in the future.
+ */
+class PartMeshFactory {
+    /**
+     * Basic constructor that takes information of how parts should be drawn.
+     * @param {object} config object holding following fields
+     * @param {object} config.defaultShape object holding following fields
+     * @param {number} config.defaultShape.radius radius of part cylinder
+     * @param {number} config.defaultShape.segments number of segments on cylinder
+     * @param {object} config.ellipsoidShape object holding following fields
+     * @param {number} config.ellipsoidShape.radius radius of part ellipsoid
+     * @param {number} config.ellipsoidShape.segments number of segments on ellipsoid
+     * 
+     */
+    constructor(config) {
+        this.config = config;
+        this.transformations = new Transformations();
+        this.partShapes = this.transformations.getPartShapes();
+    }
+
+    /**
+     * Creates sphere mesh for a given part.
+     * @param {Module.Part} part part, for which Mesh is generated
+     * @param {number} sphereRadius radius of part sphere
+     * @param {number} segments number of created segments
+     * @param {boolean} applyScale true if scale for this mesh should be applied from Module.Part
+     * @returns {PartMesh} info about part mesh
+     */
+    getNewSphereMesh(part, sphereRadius, segments, applyScale) {
+        let geometry = new THREE.SphereGeometry(sphereRadius, segments, segments);
+        let material = this.transformations.getNewMaterial(
+            part.get_vcolor().get_x(), 
+            part.get_vcolor().get_y(), 
+            part.get_vcolor().get_z());
+        let mesh = null;
+        if (applyScale) {
+            geometry.scale(
+                part.get_scale().get_x(), 
+                part.get_scale().get_y(), 
+                part.get_scale().get_z());
+            if (part.get_scale().get_x() == part.get_scale().get_y() && 
+                part.get_scale().get_x() == part.get_scale().get_z()) {
+                mesh = new THREE.Mesh(geometry, material);
+            } else {
+                mesh = new THREE.Mesh(geometry, material);
+            }
+        }
+        else {
+            mesh = new THREE.Mesh(geometry, material);
+        }
+        mesh.position.set(
+            part.get_p().get_x(), 
+            part.get_p().get_y(), 
+            part.get_p().get_z());
+
+        // if (applyScale) {
+        //     mesh.scale.set(
+        //         part.get_scale().get_x(), 
+        //         part.get_scale().get_y(), 
+        //         part.get_scale().get_z());
+        // }
+
+        let angles = part.get_o().getAngles();
+        mesh.rotation.copy(
+            this.transformations.getPartRotation(
+                angles.get_x(), 
+                angles.get_y(), 
+                angles.get_z())
+        );
+
+        mesh.userData = { 
+            isBodyElement: true, 
+            type: 'p', 
+            data: part, 
+            mesh: mesh, 
+            isPhysical: this.physics,
+            connectedJoints: [] 
+        };
+        return mesh;
+    }
+
+    /**
+     * Creates box mesh for a given part
+     * @param {Module.Part} part part, for which Mesh is generated
+     * @returns {PartMesh} info about part mesh
+     */
+    getNewBoxMesh(part) {
+        let geometry = new THREE.BoxGeometry(2, 2, 2);
+        geometry.scale(
+            part.get_scale().get_x(), 
+            part.get_scale().get_y(), 
+            part.get_scale().get_z());
+
+        let material = this.transformations.getNewMaterial(
+            part.get_vcolor().get_x(), 
+            part.get_vcolor().get_y(), 
+            part.get_vcolor().get_z());
+        let mesh = new THREE.Mesh(geometry, material);
+        mesh.position.set(
+            part.get_p().get_x(), 
+            part.get_p().get_y(), 
+            part.get_p().get_z());
+
+        let angles = part.get_o().getAngles();
+        mesh.rotation.copy(this.transformations.getPartRotation(
+            angles.get_x(), 
+            angles.get_y(), 
+            angles.get_z()));
+
+        mesh.userData = { 
+            isBodyElement: true, 
+            type: 'p', 
+            data: part, 
+            mesh: mesh, 
+            isPhysical: this.physics,
+            connectedJoints: [] 
+        };
+        return mesh;
+    }
+
+    /**
+     * Creates cylinder mesh for a given part
+     * @param {Module.Part} part part, for which Mesh is generated
+     * @returns {PartMesh} info about part mesh
+     */
+    getNewCylinderMesh(part) {
+        let geometry = new THREE.CylinderGeometry(1, 1, 2, 32);
+        let material = this.transformations.getNewMaterial(
+            part.get_vcolor().get_x(), 
+            part.get_vcolor().get_y(), 
+            part.get_vcolor().get_z());
+
+        geometry.scale(
+            part.get_scale().get_y(), 
+            part.get_scale().get_x(), 
+            part.get_scale().get_z());
+
+        let mesh = null;
+        if (part.get_scale().get_y() == part.get_scale().get_z()) {
+            mesh = new THREE.Mesh(geometry, material);
+        } else {
+            mesh = new THREE.Mesh(geometry, material);
+        }
+        mesh.position.set(
+            part.get_p().get_x(), 
+            part.get_p().get_y(), 
+            part.get_p().get_z());
+
+        let angles = part.get_o().getAngles();
+        let m = this.transformations.getCylinderPartRotationMatrix(
+            angles.get_x(), 
+            angles.get_y(), 
+            angles.get_z());
+
+        mesh.rotation.setFromRotationMatrix(m);
+
+        mesh.userData = { 
+            isBodyElement: true, 
+            type: 'p', 
+            data: part, 
+            mesh: mesh, 
+            isPhysical: this.physics,
+            connectedJoints: [] 
+        };
+        return mesh;
+    }
+
+    /**
+     * Creates part mesh according to which shape should be applied for a given 
+     * part.
+     * @param {Module.Part} part part, for which Mesh is generated
+     * @returns {PartMesh} info about part mesh
+     */
+    create(part) {
+
+        let shape = part.get_shape();
+        if (this.partShapes['SHAPE_ELLIPSOID'].value == shape) {
+            return this.getNewSphereMesh(
+                part, 
+                this.config.ellipsoidShape.radius, 
+                this.config.ellipsoidShape.segments, true);
+        }
+        else if (this.partShapes['SHAPE_CUBOID'].value == shape) {
+            return this.getNewBoxMesh(part);
+        }
+        else if (this.partShapes['SHAPE_CYLINDER'].value == shape) {
+            return this.getNewCylinderMesh(part);
+        }
+        return this.getNewSphereMesh(
+            part, 
+            this.config.defaultShape.radius, 
+            this.config.defaultShape.segments, 
+            false);
+    }
+}
+
+export default PartMeshFactory;
Index: js/human_3d_alignment/src/visualization/readme.txt
===================================================================
--- js/human_3d_alignment/src/visualization/readme.txt	(revision 881)
+++ js/human_3d_alignment/src/visualization/readme.txt	(revision 881)
@@ -0,0 +1,1 @@
+These source files should be shared and not copied, as they are used in other projects too.
Index: js/human_3d_alignment/src/visualization/scene.js
===================================================================
--- js/human_3d_alignment/src/visualization/scene.js	(revision 881)
+++ js/human_3d_alignment/src/visualization/scene.js	(revision 881)
@@ -0,0 +1,89 @@
+"use strict";
+import * as THREE from 'three';
+
+/**
+ * Class helper for creating a THREE.js scene with multiple meshes.
+ */
+class Scene {
+    /**
+     * Basic constructor setting THREE.js Scene object
+     */
+    constructor() {
+        this.scene = new THREE.Scene();
+    }
+
+    /**
+     * Adds new element (or more elements) to THREE.js Scene
+     * @param {...Object3D[]} obj list of objects to be added to the Scene
+     */
+    add(obj) {
+        this.scene.add(obj);
+    }
+
+    /**
+     * Removes object from Scene by reference. If object was geometry or material, 
+     * then it disposes their data
+     * @param {Object3D} obj object to be removed from Scene
+     */
+    remove(obj) {
+        this.scene.remove(obj);
+        if (obj.geometry) {
+            obj.geometry.dispose();
+            obj.geometry = null;
+        }
+        if (obj.material) {
+            obj.material.dispose();
+            obj.material = null;
+        }
+    }
+
+    /**
+     * Getter for Scene children
+     * @returns {Object3D} children of Scene
+     */
+    getChildren() {
+        return this.scene.children;
+    }
+
+    /**
+     * Getter of meshes of Scene
+     * @returns {Mesh} only meshes objects from Scene
+     */
+    getMeshes() {
+        let meshes = [];
+        for (let i = 0; i < this.scene.children.length; i++) {
+            let child = this.scene.children[i];
+            if (child instanceof THREE.Mesh) {
+                meshes.push(child);
+            }
+        }
+        return meshes;
+    }
+
+    /**
+     * Removes all elements from Scene.
+     */
+    clear() {
+        let toRemove = [];
+        for (let i = 0; i < this.scene.children.length; i++) {
+            let obj = this.scene.children[i];
+            if (obj.userData && obj.userData.isBodyElement) {
+                toRemove.push(obj);
+            }
+        }
+        for (let i = 0; i < toRemove.length; i++) {
+            this.remove(toRemove[i]);
+        }
+    }
+
+    /**
+     * Render scene with renderer
+     * @param {WebGLRenderer} renderer Renderer for scene
+     * @param {PerspectiveCamera} camera Perspective camera for scene
+     */
+    render(renderer, camera) {
+        renderer.render(this.scene, camera);
+    }
+}
+
+export default Scene;
Index: js/human_3d_alignment/src/visualization/sviewer.js
===================================================================
--- js/human_3d_alignment/src/visualization/sviewer.js	(revision 881)
+++ js/human_3d_alignment/src/visualization/sviewer.js	(revision 881)
@@ -0,0 +1,322 @@
+/*global Module*/
+"use strict";
+
+import * as THREE from 'three';
+import TrackballControls from 'three-trackballcontrols';
+import PartMeshFactory from './partmeshfactory';
+import JointMeshFactory from './jointmeshfactory';
+import Scene from './scene';
+import Camera from './camera';
+import { geometry } from './transformations';
+
+/** Camera class configuration for Viewer */
+export const cameraconfig = {
+    fieldOfView: 75,
+    near: 0.1,
+    far: 1000,
+    autoRotateSpeed: 2,
+    defaultSettings: {
+        target: {
+            x: 0,
+            y: 0,
+            z: 0
+        },
+        position: {
+            x: 0.56,
+            y: 0.56,
+            z: 0.56
+        },
+    }
+};
+
+/** Light configuration for Viewer */
+export const lightconfig = {
+    ambient: {
+        color: 0x303030
+    },
+    directional: {
+        top: {
+            color: 0x808080,
+            intensity: 1.0,
+            positionZ: 1000
+        },
+        bottom: {
+            color: 0x808080,
+            intensity: 1.0,
+            positionZ: -1000
+        }
+    }
+};
+
+/**
+ * Class for visualizing static Framsticks creatures. Connects all visualization 
+ * classes and render scene in given HTML canvas. For resizing it is recommended 
+ * to put canvas in resizable div and then compute new widths and heights from 
+ * this parent.
+ */
+class Viewer {
+    /**
+     * Default constructor for Viewer. It initializes all 3D visualization objects 
+     * in Scene  without creature Meshes. It needs canvas to be created in 
+     * HTML - it does not create canvas on its own, like default WebGLRenderer. 
+     * Width and height should be taken from canvas parent
+     * @param {number} width width of canvas
+     * @param {number} height height of canvas
+     * @param {Element} canvasdom DOM reference to canvas.
+     */
+    constructor(width, height, canvasdom) {
+        this.parts = [];
+        this.joints = [];
+        this.meshes = [];
+        this.parts2 = [];
+        this.joints2 = [];
+        this.meshes2 = [];
+        this.creature1 = new THREE.Group();
+        this.creature2 = new THREE.Group();
+        this.partfactory = new PartMeshFactory(geometry.part);
+        this.jointfactory = new JointMeshFactory(geometry.joint);
+        this.renderer = new THREE.WebGLRenderer({
+            antialias: true,
+            devicePixelRatio: window.devicePixelRatio || 1,
+            canvas: canvasdom
+        });
+        this.renderer.setSize(width, height);
+        this.raycaster = new THREE.Raycaster();
+        this.scene = new Scene();
+        this.camera = new Camera(cameraconfig, this.renderer.domElement, false);
+        //console.log(this.camera);
+        let ambientLight = new THREE.AmbientLight(lightconfig.ambient.color);
+        this.scene.add(ambientLight);
+
+        let topDirectionalLight = new THREE.DirectionalLight(
+            lightconfig.directional.top.color, 
+            lightconfig.directional.top.intensity);
+        topDirectionalLight.position.set(0, 0, lightconfig.directional.top.positionZ);
+        this.scene.add(topDirectionalLight);
+
+        let bottomDirectionalLight = new THREE.DirectionalLight(
+            lightconfig.directional.bottom.color, 
+            lightconfig.directional.bottom.intensity);
+        bottomDirectionalLight.position.set(0, 0, lightconfig.directional.bottom.positionZ);
+        this.scene.add(bottomDirectionalLight);
+        this.renderer.setClearColor('gray');
+        this.rezoom = true;
+        this.renderScene = this.renderScene.bind(this);
+        this.selectedelements = [];
+
+        this.mouse = new THREE.Vector2();
+        this.offset = new THREE.Vector3();
+        this.INTERSECTED = null;
+        this.SELECTED = null;
+
+        this.plane = new THREE.Mesh( new THREE.PlaneGeometry(500, 500, 8, 8 ), new THREE.MeshBasicMaterial( { color: 0x000000, opacity: 0.25, transparent: true, wireframe: true } ) );
+        this.plane.visible = true;
+        this.scene.add( this.plane ); 
+
+        this.controls = new TrackballControls( this.camera.getPerspectiveCamera() );
+        this.projector = new THREE.Projector();
+        this.controls.target = new THREE.Vector3(0, 0, 0);
+        this.controls.maxDistance = 150;
+        this.controls2 = null;
+    }
+
+    addMesh(meshes, parts, joints, model, creature)
+    {
+        let partsforjoints = [];
+        meshes = [];
+        parts = [];
+        joints = [];
+        for (let i = 0; i < model.getPartCount(); i++) {
+            let mesh = this.partfactory.create(model.getPart(i));
+            partsforjoints.push(mesh.userData);
+            meshes.push(mesh);
+            parts.push(mesh);
+            creature.add(mesh);
+        }
+
+        for (let i = 0; i < model.getJointCount(); i++) {
+            let mesh = this.jointfactory.create(model.getJoint(i), partsforjoints);
+            meshes.push(mesh);
+            joints.push(mesh);
+            creature.add(mesh);
+        }
+    }
+
+    /**
+     * Selects object from scene according to current mouse position. The position
+     * of mouse should be transformed to screen space, which has values from -1 to 1
+     * for each dimension.
+     * @param {{x: number, y: number}} position position of mouse in canvas normalized to [-1,1]x[-1,1] space
+     */
+    handleMouseDown(position) {
+      this.raycaster.setFromCamera( position, this.camera.getPerspectiveCamera() );  
+      let intersectsC1 = this.raycaster.intersectObjects( this.creature1.children );
+            let intersectsC2 = this.raycaster.intersectObjects( this.creature2.children );
+
+				if ( intersectsC1.length > 0 || intersectsC2.length > 0 ) {
+                    
+					this.controls.enabled = false;
+                    let obj = intersectsC1.length > 0 ? this.creature1 : this.creature2;
+					this.SELECTED = obj;
+					let intersects = this.raycaster.intersectObject( this.plane );
+					this.offset.copy( intersects[ 0 ].point ).sub( this.plane.position );
+				}
+    }
+
+    handleMouseUp() {
+        this.controls.enabled = true;
+        this.SELECTED = null;
+
+        if (this.INTERSECTED)
+        {
+            this.plane.position.copy(this.INTERSECTED.position);
+            this.SELECTED = null;
+        }
+    }
+
+    handleMouseMove(position) {
+        this.raycaster.setFromCamera( position, this.camera.getPerspectiveCamera() );
+        if ( this.SELECTED ) {
+            let intersects = this.raycaster.intersectObject( this.plane );
+            if (intersects[ 0 ])
+                {this.SELECTED.position.copy( intersects[ 0 ].point.sub( this.offset ) );}
+            return;
+        }
+
+            let intersectsC1 = this.raycaster.intersectObjects(this.creature1.children);
+            let intersectsC2 = this.raycaster.intersectObjects(this.creature2.children);
+            if (intersectsC1.length > 0 || intersectsC2.length > 0)
+            {
+                let obj = intersectsC1.length > 0 ? this.creature1 : this.creature2;
+                this.INTERSECTED = obj;
+                this.plane.position.copy( obj.position );
+                this.plane.lookAt( this.camera.getPerspectiveCamera().position );
+            }
+            else
+            {
+                this.INTERSECTED = null;
+            }
+        
+    }
+
+    /**
+     * Method uses ready Model to create and add meshes to the scene. If model is 
+     * undefined, an empty scene will be rendered.
+     * @param {Module.Model} model input model 1
+     * @param {Module.Model} model input model 2
+     */
+    loadMeshesFromModel(model, model2) {
+        this.clearView();
+        if (typeof model !== 'undefined') {
+
+            this.addMesh(this.meshes, this.parts, this.joints, model, this.creature1);
+            this.addMesh(this.meshes2, this.parts2, this.joints2, model2, this.creature2);
+            this.creature2.position.set( 0, 0, 0 );
+            this.creature2.position.set( 0, -1, 0 );
+            this.scene.add(this.creature1);
+            this.scene.add(this.creature2);
+            if (this.rezoom) {
+                this.camera.zoomAll(this.meshes);
+            }
+        }
+    }
+
+    /**
+     * Method for rendering Scene. It should be passed as drawing element in 
+     * owners method.
+     * 
+     * Example of usage is visible in GenoViewer Component.
+     * @returns {number} frameId of animation
+     */
+    renderScene() {
+        this.camera.getCameraControl().update();
+
+        let frameId = window.requestAnimationFrame(this.renderScene);
+        this.scene.render(this.renderer, this.camera.getPerspectiveCamera());
+        return frameId;
+    }
+
+    /**
+     * Resizes scene. Use with caution - this is performance-consuming function, 
+     * so it should only be used when necessary. To perform resize, the canvas 
+     * should have absolute position within parent, otherwise it
+     * will change size on its own.
+     * @param {number} width new width of canvas
+     * @param {number} height new height of canvas
+     */
+    resizeView(width, height) {
+        this.renderer.context.canvas.width = width;
+        this.renderer.context.canvas.height = height;
+        this.camera.getPerspectiveCamera().aspect = width / height;
+        this.camera.getPerspectiveCamera().updateProjectionMatrix();
+        this.renderer.setSize(width, height);
+        //console.log(this.renderer.getSize());
+        this.renderer.setPixelRatio(window.devicePixelRatio || 1);
+    }
+
+    /**
+     * Determines whether camera should change position in order to show all body
+     * or not.
+     * @param {boolean} rezoom true if should rezoom, false otherwise
+     */
+    setRezoom(rezoom) {
+        this.rezoom = rezoom;
+        this.camera.zoomAll(this.meshes);
+    }
+
+    /**
+     * Determines whether camera should rotate automatically.
+     * @param {boolean} autorotate true if should autorotate, false otherwise
+     */
+    setAutoRotate(autorotate) {
+        this.camera.setAutoRotate(autorotate);
+    }
+
+    /**
+     * Clears scene from meshes.
+     */
+    clearView() {
+        this.scene.clear();
+    }
+
+    /**
+     * Returns reference to renderer DOM Element.
+     * @returns {Element} DOM Element of Viewer.
+     */
+    getDOM() {
+        return this.renderer.domElement;
+    }
+
+    /**
+     * Highlights all parts and joints presented in selectedelements argument.
+     * @param {SelectedElements} selectedelements object of class SelectedElements defined in mappingresolver.js, determines which parts and joints should be highlighted
+     */
+    highlightElements(selectedelements) {
+        this.selectedelements = [];
+        for (let i = 0; i < selectedelements.parts.length; i++) {
+            this.parts[selectedelements.parts[i]].material.transparent = false;
+            this.parts[selectedelements.parts[i]].material.emissive.set('green');
+            this.selectedelements.push(this.parts[selectedelements.parts[i]]);
+        }
+        for (let i = 0; i < selectedelements.joints.length; i++) {
+            this.joints[selectedelements.joints[i]].material.transparent = false;
+            this.joints[selectedelements.joints[i]].material.emissive.set('green');
+            this.selectedelements.push(this.joints[selectedelements.joints[i]]);
+        }
+    } 
+
+    /**
+     * Removes all highlights from objects.
+     */
+    clearHighlights() {
+        for (let i = 0; i < this.selectedelements.length; i++) {
+            if (this.selectedelements[i] && this.selectedelements[i].material) {
+                this.selectedelements[i].material.transparent = this.selectedelements[i].userData.showTransparent;
+                this.selectedelements[i].material.emissive.set('black');
+            }
+        }
+        this.selectedelements = [];
+    }
+}
+
+export default Viewer;
Index: js/human_3d_alignment/src/visualization/transformations.js
===================================================================
--- js/human_3d_alignment/src/visualization/transformations.js	(revision 881)
+++ js/human_3d_alignment/src/visualization/transformations.js	(revision 881)
@@ -0,0 +1,406 @@
+/*global Module*/
+"use strict";
+
+import * as THREE from 'three';
+import JointMeshFactory from './jointmeshfactory';
+import PartMeshFactory from './partmeshfactory';
+
+/**@typedef {object} BodyElement
+ * @property {boolean} isBodyElement checked if element is body element
+ * @property {string} type should be 'p' for parts, 'j' for joints
+ * @property {object} data model logic for part or joint
+ * @property {Mesh} mesh mesh for a given part
+*/
+
+/**@typedef {BodyElement} PartMesh
+ * @property {Module.Part} data model logic for part
+ * @property {Module.Joint[]} connectedJoints list of joints connected to part
+ */
+
+/**@typedef {BodyElement} JointMesh
+ * @property {Module.Joint} data reference to model logic joint
+ * @property {Module.Part[]} connectedParts list of parts connected by this joint
+ * @property {boolean} showTransparent true if joint should be transparent
+ */
+
+/**
+ * @typedef {object} ShapeInfo
+ * @property {string} name full name of shape
+ * @property {number} value enum for part shape
+ */
+
+/** Parts and Joints geometry info for viewer */
+export const geometry = {
+    part: {
+        defaultShape: {
+            radius: 0.213,
+            segments: 16
+        },
+        ellipsoidShape: {
+            radius: 1,
+            segments: 32
+        }
+    },
+    joint: {
+        cylinderShape: {
+            radius: 0.1,
+            radiusSegments: 10,
+            isTransparent: false,
+            opacity: 1
+        },
+        linkShape: {
+            radius: 0.04,
+            radiusSegments: 10,
+            isTransparent: true,
+            opacity: 0.2
+        }
+    }
+};
+
+/**
+ * Class for creating various transformations on Framsticks-SDK joints and parts 
+ * meshes. It contains helpers for conversions between Joint/Part logic and THREE.js 
+ * visualization. 
+ * 
+ * Any constants and methods considering shapes should go here.
+ */
+class Transformations {
+
+    /**
+     * Basic constructor for Transformations class. 
+     * Initializes fields partShapes and jointShapes with getPartShapes and 
+     * getJointsShapes results.
+     */
+    constructor() {
+        this.partShapes = this.getPartShapes();
+        this.jointShapes = this.getJointShapes();
+    }
+
+    /**
+     * Getter for Part shapes informations.
+     * @returns {ShapeInfo[]} basic info about shapes of parts
+     */
+    getPartShapes() {
+        let shapes = [];
+        shapes["SHAPE_BALL_AND_STICK"] = { name: "Ball & Stick", value: Module.Part["SHAPE_BALL_AND_STICK"] };
+        shapes["SHAPE_ELLIPSOID"] = { name: "Elipsoid", value: Module.Part["SHAPE_ELLIPSOID"] };
+        shapes["SHAPE_CUBOID"] = { name: "Cuboid", value: Module.Part["SHAPE_CUBOID"] };
+        shapes["SHAPE_CYLINDER"] = { name: "Cylinder", value: Module.Part["SHAPE_CYLINDER"] };
+        return shapes;
+    }
+
+    /**
+     * Getter for Joint shapes informations.
+     * @returns {ShapeInfo[]} basic info about shapes of joints
+     */
+    getJointShapes() {
+        let shapes = [];
+        shapes["SHAPE_BALL_AND_STICK"] = { name: "Ball & Stick", value: Module.Joint["SHAPE_BALL_AND_STICK"] };
+        shapes["SHAPE_FIXED"] = { name: "Fixed", value: Module.Joint["SHAPE_FIXED"] };
+        return shapes;
+    }
+
+    /**
+     * Recursive method for checking which elements are affected by transformations of object.
+     * This is internal method that should not be called.
+     * @param {BodyElement} bodyElement bodyelement, for which connected elements are checked for affection 
+     * @param {object} result {partElements: PartMesh[], jointElements: JointMesh[]} that is result of recursive call
+     */
+    getAffectedElements_r(bodyElement, result) {
+        if (bodyElement.marked) {
+            return;
+        }
+
+        if (bodyElement.type == "p") {
+
+            bodyElement.marked = true;
+            result.partElements.push(bodyElement);
+
+            for (let i = 0; i < bodyElement.connectedJoints.length; ++i) {
+                let joint = bodyElement.connectedJoints[i];
+                if (!joint.marked) {
+                    joint.marked = true;
+                    result.jointElements.push(joint);
+                    if (joint.data.get_usedelta()) {
+                        this.getAffectedElements_r(joint.connectedParts[1], result);
+                    }
+                }
+            }
+
+        }
+        else if (bodyElement.type == "j") {
+            bodyElement.marked = true;
+            result.jointElements.push(bodyElement);
+
+            this.getAffectedElements_r(bodyElement.connectedParts[1], result);
+        }
+    }
+
+    /**
+     * Function that finds affected elements with function getAffectedElements_r 
+     * and returns all affected parts and joints
+     * @param {BodyElement} bodyElement bodyelement, for which connected elements are checked for affection 
+     * @returns {object} {partElements: PartMesh[], jointElements: JointMesh[]} that is result of recursive call
+     */
+    getAffectedElements(bodyElement) {
+        let result = {
+            partElements: [],
+            jointElements: []
+        };
+
+        this.getAffectedElements_r(bodyElement, result);
+
+        for (let j = 0; j < result.partElements.length; ++j) {
+            result.partElements[j].marked = false;
+        }
+        for (let k = 0; k < result.jointElements.length; ++k) {
+            result.jointElements[k].marked = false;
+        }
+        return result;
+    }
+
+    /**
+     * Helper for clamping colors from Framsticks-SDK to 0-1 values
+     * @param {number} value density of color
+     * @returns {number} clamped color
+     */
+    calcColorComponent(value) {
+        return THREE.Math.clamp(value, 0, 1);
+    }
+
+    /**
+     * Applies color for a given element
+     * @param {BodyElement} bodyElement body element to color
+     * @param {number} component which component should be changed
+     * @param {number} value new value of component
+     */
+    applyColor(bodyElement, component, value) {
+        bodyElement.mesh.material.color[component] = this.calcColorComponent(value);
+    }
+
+    /**
+     * Creates new phong material for Mesh
+     * @param {number} r color red
+     * @param {number} g color green
+     * @param {number} b color blue
+     * @returns {MeshPhongMaterial} new material for Mesh
+     */
+    getNewMaterial(r, g, b) {
+        let color = new THREE.Color(
+            this.calcColorComponent(r), 
+            this.calcColorComponent(g), 
+            this.calcColorComponent(b));
+        return new THREE.MeshPhongMaterial({ color: color });
+    }
+
+    /**
+     * Returns THREE.js object representing rotation matrix based on XYZ axis
+     * rotation angles.
+     * @param {number} rotAngleX angle of rotation for X axis
+     * @param {number} rotAngleY angle of rotation for Y axis
+     * @param {number} rotAngleZ angle of rotation for Z axis
+     * @returns {THREE.Euler} rotation matrix to be applied for model
+     */
+    getPartRotation(rotAngleX, rotAngleY, rotAngleZ) {
+        return new THREE.Euler(rotAngleX, -rotAngleY, rotAngleZ, "ZYX");
+    }
+
+    /**
+     * Creates rotation matrix for cylinder Part
+     * @param {number} rotAngleX rotate coordinate
+     * @param {number} rotAngleY rotate coordinate
+     * @param {number} rotAngleZ rotate coordinate
+     * @returns {Matrix4} rotation matrix for cylinder Part
+     */
+    getCylinderPartRotationMatrix(rotAngleX, rotAngleY, rotAngleZ) {
+        let rot = this.getPartRotation(rotAngleX, rotAngleY, rotAngleZ);
+
+        let m = new THREE.Matrix4();
+        m.makeRotationZ(THREE.Math.degToRad(90));
+
+        let m2 = new THREE.Matrix4();
+        m2.makeRotationFromEuler(rot);
+        m2.multiply(m);
+        return m2;
+    }
+
+    /**
+     * Applies rotation on a single part
+     * @param {BodyElement} bodyElement element on which rotation will be performed
+     */
+    applySinglePartRotation(bodyElement) {
+        let shape = bodyElement.data.get_shape();
+        let rot = bodyElement.data.get_o().getAngles();
+
+        if (this.partShapes['SHAPE_CYLINDER'].value == shape) {
+            let m = this.getCylinderPartRotationMatrix(
+                rot.get_x(), 
+                rot.get_y(), 
+                rot.get_z());
+            bodyElement.mesh.rotation.setFromRotationMatrix(m);
+        }
+        else {
+            let r = this.getPartRotation(rot.get_x(), rot.get_y(), rot.get_z());
+            bodyElement.mesh.rotation.copy(r);
+        }
+    }
+
+    /**
+     * Applies rotation on a bodyElement part and all other affected elements.
+     * @param {BodyElement} bodyElement element on which rotation will be performed
+     */
+    applyPartRotation(bodyElement) {
+
+        let affectedElements = this.getAffectedElements(bodyElement);
+
+        if (affectedElements.partElements.length > 1) {
+            for (let i = 0; i < affectedElements.partElements.length; ++i) {
+                let part = affectedElements.partElements[i];
+                part.mesh.position.x = part.data.get_p().get_x();
+                part.mesh.position.y = part.data.get_p().get_y();
+                part.mesh.position.z = part.data.get_p().get_z();
+                this.applySinglePartRotation(part);
+            }
+            let jointMeshFactory = new JointMeshFactory(this.jointShapes);
+            for (let j = 0; j < affectedElements.jointElements.length; ++j) {
+                let newJointMesh = jointMeshFactory.create(affectedElements.jointElements[j].data);
+                this.changeBodyElementMesh(affectedElements.jointElements[j], newJointMesh);
+            }
+        } else {
+            this.applySinglePartRotation(bodyElement);
+        }
+
+    }
+
+    /**
+     * Redefines all affected joints due to part changes
+     * @param {BodyElement} bodyElement starting element
+     */
+    applyJointDeltaChange(bodyElement) {
+
+        let affectedElements = this.getAffectedElements(bodyElement);
+
+        for (let i = 0; i < affectedElements.partElements.length; ++i) {
+            let part = affectedElements.partElements[i];
+            part.mesh.position.x = part.data.get_p().get_x();
+            part.mesh.position.y = part.data.get_p().get_y();
+            part.mesh.position.z = part.data.get_p().get_z();
+            this.applySinglePartRotation(part);
+        }
+        let jointMeshFactory = new JointMeshFactory(this.jointShapes);
+        for (let j = 0; j < affectedElements.jointElements.length; ++j) {
+            let newJointMesh = jointMeshFactory.create(affectedElements.jointElements[j].data);
+            this.changeBodyElementMesh(affectedElements.jointElements[j], newJointMesh);
+        }
+
+    }
+
+    /**
+     * Applies scale to a part
+     * @param {BodyElement} bodyElement element to be scaled
+     */
+    applyPartScale(bodyElement) {
+        let part = bodyElement.data;
+        let shape = part.get_shape();
+        if (this.partShapes['SHAPE_CYLINDER'].value == shape) {
+            bodyElement.mesh.scale.set(
+                part.get_scale().get_y(), 
+                part.get_scale().get_x(), 
+                part.get_scale().get_z());
+        } else if (this.partShapes['SHAPE_BALL_AND_STICK'].value != shape) {
+            bodyElement.mesh.scale.set(
+                part.get_scale().get_x(), 
+                part.get_scale().get_y(), 
+                part.get_scale().get_z());
+        }
+    }
+
+    /**
+     * Replaces old mesh of an element with a new mesh
+     * @param {BodyElement} element Element to be changed
+     * @param {Mesh} newMesh New mesh for element
+     */
+    changeBodyElementMesh(element, newMesh) {
+        let scene = element.mesh.parent;
+        let oldMesh = element.mesh;
+
+        let userData = oldMesh.userData;
+        userData.showTransparent = newMesh.userData.showTransparent;
+        userData.mesh = newMesh.userData.mesh;
+        newMesh.userData = userData;
+
+        scene.remove(oldMesh);
+        scene.add(newMesh);
+
+        oldMesh.geometry.dispose();
+        oldMesh.geometry = null;
+        oldMesh.material.dispose();
+        oldMesh.material = null;
+    }
+
+    /**
+     * Changes Part position.
+     * @param {BodyElement} bodyElement element to be changed
+     * @param {string} axis which axis should be changed
+     */
+    applyPartPosition(bodyElement, axis) {
+        let jointMeshFactory = new JointMeshFactory(this.jointShapes);
+
+        let affectedElements = this.getAffectedElements(bodyElement);
+        for (let i = 0; i < affectedElements.partElements.length; ++i) {
+            affectedElements.partElements[i].mesh.position[axis] = 
+                affectedElements.partElements[i].data.get_p()["get_" + axis]();
+        }
+        for (let j = 0; j < affectedElements.jointElements.length; ++j) {
+            let newJointMesh = jointMeshFactory.create(affectedElements.jointElements[j].data);
+            this.changeBodyElementMesh(affectedElements.jointElements[j], newJointMesh);
+        }
+    }
+
+    /**
+     * Updates all affected elements positions.
+     * @param {BodyElement} bodyElement beginning element
+     */
+    updateAfterPartTranslation(bodyElement) {
+        let jointMeshFactory = new JointMeshFactory(this.jointShapes);
+
+        let affectedElements = this.getAffectedElements(bodyElement);
+        for (let i = 0; i < affectedElements.partElements.length; ++i) {
+            let currentElement = affectedElements.partElements[i];
+            if (currentElement !== bodyElement) {
+                affectedElements.partElements[i].mesh.position.x = 
+                    affectedElements.partElements[i].data.get_p().get_x();
+                affectedElements.partElements[i].mesh.position.y = 
+                    affectedElements.partElements[i].data.get_p().get_y();
+                affectedElements.partElements[i].mesh.position.z = 
+                    affectedElements.partElements[i].data.get_p().get_z();
+            }
+        }
+        for (let j = 0; j < affectedElements.jointElements.length; ++j) {
+            let newJointMesh = jointMeshFactory.create(affectedElements.jointElements[j].data);
+            this.changeBodyElementMesh(affectedElements.jointElements[j], newJointMesh);
+        }
+    }
+
+    /**
+     * Creates Part shape and removes old shape.
+     * @param {PartMesh} bodyElement part to be applied
+     */
+    applyPartShape(bodyElement) {
+        let partMeshFactory = new PartMeshFactory(this.partShapes);
+        let newPartMesh = partMeshFactory.create(bodyElement.data);
+        this.changeBodyElementMesh(bodyElement, newPartMesh);
+    }
+
+    /**
+     * Creates Joint shape and removes old shape.
+     * @param {JointMesh} bodyElement joint to be applied
+     */
+    applyJointShape(bodyElement) {
+        let jointMeshFactory = new JointMeshFactory(this.jointShapes);
+        let newJointMesh = jointMeshFactory.create(bodyElement.data);
+        this.changeBodyElementMesh(bodyElement, newJointMesh);
+    }
+}
+
+export default Transformations;
Index: js/human_3d_alignment/src/widgets/similviewer.jsx
===================================================================
--- js/human_3d_alignment/src/widgets/similviewer.jsx	(revision 881)
+++ js/human_3d_alignment/src/widgets/similviewer.jsx	(revision 881)
@@ -0,0 +1,185 @@
+/*global Module*/
+"use strict";
+import React from 'react';
+import ReactDOM from 'react-dom';
+import Sviewer from '../visualization/sviewer';
+import { Md3dRotation, MdYoutubeSearchedFor } from 'react-icons/lib/md';
+import GenotypeParser from '../utils/genotypeparser';
+import _ from 'lodash';
+import * as THREE from 'three';
+
+/**
+ * Component for assesing genotypes matching.
+ */
+class GenoViewer extends React.Component {
+    /**
+     * Basic constructor.
+     * @param {any} props properties of Component
+     */
+    constructor(props) {
+        super(props);
+        this.props = props;
+        this.state = {
+            autorotate: false,
+            rezoom: true,
+            valid: true,
+            clicked: false
+        };
+        this.start = this.start.bind(this);
+        this.stop = this.stop.bind(this);
+        this.animate = this.animate.bind(this);
+    }
+
+    /**
+     * Method initializes all visualizations and binds their methods and events with SViewer.
+     */
+    componentDidMount() {
+        let temp = ReactDOM.findDOMNode(this.mount);
+        let temp2 = ReactDOM.findDOMNode(this.mount).parentNode;
+        this.viewer = new Sviewer(temp2.clientWidth, temp2.clientHeight, temp);
+        if (this.model) {
+            //Module.destroy(this.model);
+        }
+        this.model = GenotypeParser.getModelFromGenotype("X(X,X)");
+        this.model2 = GenotypeParser.getModelFromGenotype("XX");
+        this.viewer.loadMeshesFromModel(this.model, this.model2);
+        this.viewer.setAutoRotate(this.state.autorotate);
+        this.viewer.setRezoom(this.state.rezoom);
+        //this.elementspicker = new ElementsPicker(this.viewer.scene, this.viewer.camera.getPerspectiveCamera());
+        this.renderScene = this.viewer.renderScene.bind(this.viewer);
+        this.lastw = temp2.clientWidth;
+        this.lasth = temp2.clientHeight;
+        this.start();
+    }
+
+    /**
+     * Method stops animation of Framsticks.
+     */
+    componentWillUnmount() {
+        this.stop();
+    }
+
+    /**
+     * After update of state all visualizations are refreshed
+     */
+    componentDidUpdate() {
+        let temp = ReactDOM.findDOMNode(this.mount).parentNode;
+        this.viewer.resizeView(temp.clientWidth, temp.clientHeight);
+    }
+
+    /**
+     * Method starts animation process. Internal method, used by componentDidMount.
+     */
+    start() {
+        if (!this.frameId) {
+            this.frameId = requestAnimationFrame(this.animate);
+        }
+    }
+
+    /**
+     * Main animation loop. If any change was applied to genotype, this method loads new
+     * models and brains.
+     */
+    animate() {
+        let temp = ReactDOM.findDOMNode(this.mount).parentNode;
+        if (this.lasth != temp.clientHeight || this.lastw != temp.clientWidth) {
+            this.viewer.resizeView(temp.clientWidth, temp.clientHeight);
+            this.lastw = temp.clientWidth;
+            this.lasth = temp.clientHeight;
+        }
+        
+        this.viewer.camera.getCameraControl().update();
+        this.frameId = window.requestAnimationFrame(this.animate);
+        this.viewer.scene.render(
+            this.viewer.renderer, 
+            this.viewer.camera.getPerspectiveCamera());
+    }
+
+    /**
+     * Method cancels animation.
+     */
+    stop() {
+        cancelAnimationFrame(this.frameId);
+    }
+
+    /**
+     * Turns on/off rezoom property of viewer
+     */
+    switchRezoom() {
+        this.setState({rezoom: !this.state.rezoom});
+        this.viewer.setRezoom(!this.state.rezoom);
+    }
+
+    /**
+     * Turns on/off autorotate property of viewer
+     */
+    switchAutorotate() {
+        this.setState({autorotate: !this.state.autorotate});
+        this.viewer.setAutoRotate(!this.state.autorotate);
+    }
+
+    /**
+     * Gets position of mouse
+     */
+    getMousePosition(evt){
+        let bound = this.mount.getBoundingClientRect();
+        let mousePosition = {x: 0, y: 0};
+        mousePosition.x = ((evt.clientX - bound.left) / bound.width) * 2 - 1;
+        mousePosition.y = -((evt.clientY - bound.top) / bound.height) * 2 + 1;
+        //let vector = new THREE.Vector3(mousePosition.x, mousePosition.y, 0.5);
+        let vector = new THREE.Vector2(mousePosition.x, mousePosition.y);
+        return vector;
+    }
+
+       /**
+     * Event function for using mouse within viewer.
+     * @param {any} evt object holding event data
+     */
+    handleMouseDown(evt) {
+        evt.preventDefault();
+        let mousePosition = this.getMousePosition(evt);
+        this.viewer.handleMouseDown(mousePosition);
+    }
+
+           /**
+     * Event function for using mouse within viewer.
+     * @param {any} evt object holding event data
+     */
+    handleMouseUp(evt) {
+        evt.preventDefault();
+        let mousePosition = this.getMousePosition(evt);
+        this.viewer.handleMouseUp(mousePosition);
+    }
+
+               /**
+     * Event function for using mouse within viewer.
+     * @param {any} evt object holding event data
+     */
+    handleMouseMove(evt) {
+        evt.preventDefault();
+        let mousePosition = this.getMousePosition(evt);
+        this.viewer.handleMouseMove(mousePosition);
+    }
+
+    
+     
+    render() {
+        return (
+            <table {...this.props} style={{height: '100%', width: '100%'}}>
+                <tbody>
+                    <tr onMouseDown={ev => {if (ev) ev.stopPropagation();}}>
+                        <td rowSpan={2} style={{position:'relative', verticalAlign: 'top', alignContent: 'left'}}>
+                            <div style={{height: '100%', width: '100%', position: 'absolute', transform: 'translateZ(0)'}} onMouseDown={ev => {if (ev) ev.stopPropagation();}} onTouchStart={ev => {if (ev) ev.stopPropagation();}}>
+                                <canvas ref={(mount) => {this.mount = mount;}} onMouseDown={(evt) => this.handleMouseDown(evt)} onMouseUp={(evt) => this.handleMouseUp(evt)} onMouseMove={(evt) => this.handleMouseMove(evt)} style={{position: 'absolute', zIndex: 1}}></canvas>
+                                <Md3dRotation onClick={() => this.switchAutorotate()}  style={{zIndex: 2, position: 'absolute', left: '5%', bottom: 0, width: '20%', height: '20%', maxWidth: '40px', maxHeight: '40px', minWidth: '15px', minHeight: '15px', color: this.state.autorotate ? 'green' : 'black'}} />
+                                <MdYoutubeSearchedFor onClick={() => this.switchRezoom()} style={{zIndex: 2, position: 'absolute', right: '5%', bottom: 0, width: '20%', height: '20%', maxWidth: '40px', maxHeight: '40px', minWidth: '15px', minHeight: '15px', color: this.state.rezoom ? 'green' : 'black' }} />
+                            </div>
+                        </td>
+                    </tr>  
+                </tbody>
+            </table>
+        );
+    }
+}
+
+export default GenoViewer;
