diff --git a/ipyvolume-java/build.gradle b/ipyvolume-java/build.gradle new file mode 100644 index 00000000..6c844816 --- /dev/null +++ b/ipyvolume-java/build.gradle @@ -0,0 +1,19 @@ +group 'ipyvolume-java' +version '1.0-SNAPSHOT' + +apply plugin: 'java' + +sourceCompatibility = 1.8 + +repositories { + allprojects { + repositories { + mavenCentral() + maven { url 'https://jitpack.io' } + } + } +} + +dependencies { + compile 'com.github.twosigma.beakerx:beaker-kernel-base:0.15.2' +} diff --git a/ipyvolume-java/gradlew b/ipyvolume-java/gradlew new file mode 100755 index 00000000..4453ccea --- /dev/null +++ b/ipyvolume-java/gradlew @@ -0,0 +1,172 @@ +#!/usr/bin/env sh + +############################################################################## +## +## Gradle start up script for UN*X +## +############################################################################## + +# Attempt to set APP_HOME +# Resolve links: $0 may be a link +PRG="$0" +# Need this for relative symlinks. +while [ -h "$PRG" ] ; do + ls=`ls -ld "$PRG"` + link=`expr "$ls" : '.*-> \(.*\)$'` + if expr "$link" : '/.*' > /dev/null; then + PRG="$link" + else + PRG=`dirname "$PRG"`"/$link" + fi +done +SAVED="`pwd`" +cd "`dirname \"$PRG\"`/" >/dev/null +APP_HOME="`pwd -P`" +cd "$SAVED" >/dev/null + +APP_NAME="Gradle" +APP_BASE_NAME=`basename "$0"` + +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS="" + +# Use the maximum available, or set MAX_FD != -1 to use that value. +MAX_FD="maximum" + +warn ( ) { + echo "$*" +} + +die ( ) { + echo + echo "$*" + echo + exit 1 +} + +# OS specific support (must be 'true' or 'false'). +cygwin=false +msys=false +darwin=false +nonstop=false +case "`uname`" in + CYGWIN* ) + cygwin=true + ;; + Darwin* ) + darwin=true + ;; + MINGW* ) + msys=true + ;; + NONSTOP* ) + nonstop=true + ;; +esac + +CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar + +# Determine the Java command to use to start the JVM. +if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD="$JAVA_HOME/jre/sh/java" + else + JAVACMD="$JAVA_HOME/bin/java" + fi + if [ ! -x "$JAVACMD" ] ; then + die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +else + JAVACMD="java" + which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." +fi + +# Increase the maximum file descriptors if we can. +if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then + MAX_FD_LIMIT=`ulimit -H -n` + if [ $? -eq 0 ] ; then + if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then + MAX_FD="$MAX_FD_LIMIT" + fi + ulimit -n $MAX_FD + if [ $? -ne 0 ] ; then + warn "Could not set maximum file descriptor limit: $MAX_FD" + fi + else + warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" + fi +fi + +# For Darwin, add options to specify how the application appears in the dock +if $darwin; then + GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" +fi + +# For Cygwin, switch paths to Windows format before running java +if $cygwin ; then + APP_HOME=`cygpath --path --mixed "$APP_HOME"` + CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` + JAVACMD=`cygpath --unix "$JAVACMD"` + + # We build the pattern for arguments to be converted via cygpath + ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` + SEP="" + for dir in $ROOTDIRSRAW ; do + ROOTDIRS="$ROOTDIRS$SEP$dir" + SEP="|" + done + OURCYGPATTERN="(^($ROOTDIRS))" + # Add a user-defined pattern to the cygpath arguments + if [ "$GRADLE_CYGPATTERN" != "" ] ; then + OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" + fi + # Now convert the arguments - kludge to limit ourselves to /bin/sh + i=0 + for arg in "$@" ; do + CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` + CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option + + if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition + eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` + else + eval `echo args$i`="\"$arg\"" + fi + i=$((i+1)) + done + case $i in + (0) set -- ;; + (1) set -- "$args0" ;; + (2) set -- "$args0" "$args1" ;; + (3) set -- "$args0" "$args1" "$args2" ;; + (4) set -- "$args0" "$args1" "$args2" "$args3" ;; + (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; + (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; + (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; + (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; + (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; + esac +fi + +# Escape application args +save ( ) { + for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done + echo " " +} +APP_ARGS=$(save "$@") + +# Collect all arguments for the java command, following the shell quoting and substitution rules +eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" + +# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong +if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then + cd "$(dirname "$0")" +fi + +exec "$JAVACMD" "$@" diff --git a/ipyvolume-java/gradlew.bat b/ipyvolume-java/gradlew.bat new file mode 100644 index 00000000..e95643d6 --- /dev/null +++ b/ipyvolume-java/gradlew.bat @@ -0,0 +1,84 @@ +@if "%DEBUG%" == "" @echo off +@rem ########################################################################## +@rem +@rem Gradle startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +set DIRNAME=%~dp0 +if "%DIRNAME%" == "" set DIRNAME=. +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS= + +@rem Find java.exe +if defined JAVA_HOME goto findJavaFromJavaHome + +set JAVA_EXE=java.exe +%JAVA_EXE% -version >NUL 2>&1 +if "%ERRORLEVEL%" == "0" goto init + +echo. +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:findJavaFromJavaHome +set JAVA_HOME=%JAVA_HOME:"=% +set JAVA_EXE=%JAVA_HOME%/bin/java.exe + +if exist "%JAVA_EXE%" goto init + +echo. +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:init +@rem Get command-line arguments, handling Windows variants + +if not "%OS%" == "Windows_NT" goto win9xME_args + +:win9xME_args +@rem Slurp the command line arguments. +set CMD_LINE_ARGS= +set _SKIP=2 + +:win9xME_args_slurp +if "x%~1" == "x" goto execute + +set CMD_LINE_ARGS=%* + +:execute +@rem Setup the command line + +set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar + +@rem Execute Gradle +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% + +:end +@rem End local scope for the variables with windows NT shell +if "%ERRORLEVEL%"=="0" goto mainEnd + +:fail +rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of +rem the _cmd.exe /c_ return code! +if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 +exit /b 1 + +:mainEnd +if "%OS%"=="Windows_NT" endlocal + +:omega diff --git a/ipyvolume-java/settings.gradle b/ipyvolume-java/settings.gradle new file mode 100644 index 00000000..61fc6f7b --- /dev/null +++ b/ipyvolume-java/settings.gradle @@ -0,0 +1 @@ +rootProject.name = 'ipyvolume-java' \ No newline at end of file diff --git a/ipyvolume-java/src/main/java/ipyvolume/Figure.java b/ipyvolume-java/src/main/java/ipyvolume/Figure.java new file mode 100644 index 00000000..3d48f495 --- /dev/null +++ b/ipyvolume-java/src/main/java/ipyvolume/Figure.java @@ -0,0 +1,429 @@ +package ipyvolume; + + +import com.twosigma.beakerx.widget.Style; +import ipywebrtc.MediaStream; +import org.apache.commons.lang3.ArrayUtils; +import org.assertj.core.internal.Bytes; + +import java.io.BufferedInputStream; +import java.io.File; +import java.io.FileNotFoundException; +import java.io.FileReader; +import java.io.IOException; +import java.io.InputStream; +import java.io.Serializable; +import java.net.URISyntaxException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; + +public class Figure extends MediaStream { + + + + public static final String MODEL_MODULE_VALUE = "ipyvolume"; + public static final String MODEL_MODULE_VERSION_VALUE = "~0.4.5"; + public static final String MODEL_NAME_VALUE = "FigureModel"; + public static final String VIEW_MODULE_VALUE = "ipyvolume"; + public static final String VIEW_MODULE_VERSION_VALUE = "~0.4.5"; + public static final String VIEW_NAME_VALUE = "FigureView"; + public static final String AMBIENT_COEFFICIENT = "ambient_coefficient"; + public static final String ANGLE_ORDER = "angle_order"; + public static final String ANGLEX = "anglex"; + public static final String ANGLEY = "angley"; + public static final String ANGLEZ = "anglez"; + public static final String ANIMATION = "animation"; + public static final String ANIMATION_EXPONENT = "animation_exponent"; + public static final String CAMERA_CENTER = "camera_center"; + public static final String CAMERA_CONTROL = "camera_control"; + public static final String CAMERA_FOV = "camera_fov"; + public static final String DATA_MAX = "data_max"; + public static final String DATA_MIN = "data_min"; + public static final String DIFFUSE_COEFFICIENT = "diffuse_coefficient"; + public static final String DOWNSCALE = "downscale"; + public static final String EXTENT = "extent"; + public static final String EYE_SEPARATION = "eye_separation"; + public static final String HEIGHT = "height"; + public static final String MATRIX_PROJECTION = "matrix_projection"; + public static final String MATRIX_WORLD = "matrix_world"; + public static final String RENDER_CONTINUOUS = "render_continuous"; + public static final String SELECTION_MODE = "selection_mode"; + public static final String SELECTOR = "selector"; + public static final String SHOW = "show"; + public static final String SPECULAR_COEFFICIENT = "specular_coefficient"; + public static final String SPECULAR_EXPONENT = "specular_exponent"; + public static final String STEREO = "stereo"; + public static final String STYLE = "style"; + public static final String TF = "tf"; + public static final String VOLUME_DATA = "volume_data"; + public static final String WIDTH = "width"; + public static final String XLABEL = "xlabel"; + public static final String XLIM = "xlim"; + public static final String YLABEL = "ylabel"; + public static final String YLIM = "ylim"; + public static final String ZLABEL = "zlabel"; + public static final String ZLIM = "zlim"; + + private double ambientCoefficient = 0.5; + private String angleOrder = "XYZ"; + private double anglex = 0; + private double angley = 0; + private double anglez = 0; + private double animation = 1000; + private double animationExponent = 0.5; + private List cameraCenter = Arrays.asList(0, 0, 0); + private String cameraControl = "trackball"; + private double cameraFov = 45; + private double dataMax = 0; + private double dataMin = 0; + private double diffuseCoefficient = 0.8; + private int downscale = 1; + private Object extent = null; + private double eyeSeparation = 6.4; + private int height = 400; + private List matrixProjection = Arrays.asList(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); + private List matrixWorld = Arrays.asList(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); + private boolean renderContinuous = false; + private String selectionMode = "replace"; + private String selector = "lasso"; + private String show = "Volume"; + private double specularCoefficient = 0.5; + private double specularExponent = 5; + private boolean stereo = false; + private Style style = null; + private TransferFunction tf = null; + private int width = 500; + private String xlabel = "x"; + private List xlim = Arrays.asList(0, 1); + private String ylabel = "y"; + private List ylim = Arrays.asList(0, 1); + private String zlabel = "z"; + private List zlim = Arrays.asList(0, 1); + private VolumeData volumeData; + + public Figure() { + super(); + openComm(); + } + + public String getModelModuleValue(){ + return MODEL_MODULE_VALUE; + } + + public String getModelModuleVersionValue(){ + return MODEL_MODULE_VERSION_VALUE; + } + + public String getModelNameValue(){ + return MODEL_NAME_VALUE; + } + + public String getViewModuleValue(){ + return VIEW_MODULE_VALUE; + } + + public String getViewModuleVersionValue(){ + return VIEW_MODULE_VERSION_VALUE; + } + + public String getViewNameValue(){ + return VIEW_NAME_VALUE; + } + + public double getAmbientCoefficient() { + return ambientCoefficient; + } + public void setAmbientCoefficient(double ambientCoefficient){ + this.ambientCoefficient = ambientCoefficient; + sendUpdate(AMBIENT_COEFFICIENT, ambientCoefficient); + } + + public String getAngleOrder() { + return angleOrder; + } + public void setAngleOrder(String angleOrder){ + this.angleOrder = angleOrder; + sendUpdate(ANGLE_ORDER, angleOrder); + } + + public double getAnglex() { + return anglex; + } + public void setAnglex(double anglex){ + this.anglex = anglex; + sendUpdate(ANGLEX, anglex); + } + + public double getAngley() { + return angley; + } + public void setAngley(double angley){ + this.angley = angley; + sendUpdate(ANGLEY, angley); + } + + public double getAnglez() { + return anglez; + } + public void setAnglez(double anglez){ + this.anglez = anglez; + sendUpdate(ANGLEZ, anglez); + } + + public double getAnimation() { + return animation; + } + public void setAnimation(double animation){ + this.animation = animation; + sendUpdate(ANIMATION, animation); + } + + public double getAnimationExponent() { + return animationExponent; + } + public void setAnimationExponent(double animationExponent){ + this.animationExponent = animationExponent; + sendUpdate(ANIMATION_EXPONENT, animationExponent); + } + + public List getCameraCenter() { + return cameraCenter; + } + public void setCameraCenter(List cameraCenter){ + this.cameraCenter = cameraCenter; + sendUpdate(CAMERA_CENTER, cameraCenter); + } + + public String getCameraControl() { + return cameraControl; + } + public void setCameraControl(String cameraControl){ + this.cameraControl = cameraControl; + sendUpdate(CAMERA_CONTROL, cameraControl); + } + + public double getCameraFov() { + return cameraFov; + } + public void setCameraFov(double cameraFov){ + this.cameraFov = cameraFov; + sendUpdate(CAMERA_FOV, cameraFov); + } + + public double getDataMax() { + return dataMax; + } + public void setDataMax(double dataMax){ + this.dataMax = dataMax; + sendUpdate(DATA_MAX, dataMax); + } + + public double getDataMin() { + return dataMin; + } + public void setDataMin(double dataMin){ + this.dataMin = dataMin; + sendUpdate(DATA_MIN, dataMin); + } + + public double getDiffuseCoefficient() { + return diffuseCoefficient; + } + public void setDiffuseCoefficient(double diffuseCoefficient){ + this.diffuseCoefficient = diffuseCoefficient; + sendUpdate(DIFFUSE_COEFFICIENT, diffuseCoefficient); + } + + public int getDownscale() { + return downscale; + } + public void setDownscale(int downscale){ + this.downscale = downscale; + sendUpdate(DOWNSCALE, downscale); + } + + public Object getExtent() { + return extent; + } + public void setExtent(Object extent){ + this.extent = extent; + sendUpdate(EXTENT, extent); + } + + public double getEyeSeparation() { + return eyeSeparation; + } + public void setEyeSeparation(double eyeSeparation){ + this.eyeSeparation = eyeSeparation; + sendUpdate(EYE_SEPARATION, eyeSeparation); + } + + public int getHeight() { + return height; + } + public void setHeight(int height){ + this.height = height; + sendUpdate(HEIGHT, height); + } + + public List getMatrixProjection() { + return matrixProjection; + } + public void setMatrixProjection(List matrixProjection){ + this.matrixProjection = matrixProjection; + sendUpdate(MATRIX_PROJECTION, matrixProjection); + } + + public List getMatrixWorld() { + return matrixWorld; + } + public void setMatrixWorld(List matrixWorld){ + this.matrixWorld = matrixWorld; + sendUpdate(MATRIX_WORLD, matrixWorld); + } + + public boolean getRenderContinuous() { + return renderContinuous; + } + public void setRenderContinuous(boolean renderContinuous){ + this.renderContinuous = renderContinuous; + sendUpdate(RENDER_CONTINUOUS, renderContinuous); + } + + public String getSelectionMode() { + return selectionMode; + } + public void setSelectionMode(String selectionMode){ + this.selectionMode = selectionMode; + sendUpdate(SELECTION_MODE, selectionMode); + } + + public String getSelector() { + return selector; + } + public void setSelector(String selector){ + this.selector = selector; + sendUpdate(SELECTOR, selector); + } + + public String getShow() { + return show; + } + public void setShow(String show){ + this.show = show; + sendUpdate(SHOW, show); + } + + public double getSpecularCoefficient() { + return specularCoefficient; + } + public void setSpecularCoefficient(double specularCoefficient){ + this.specularCoefficient = specularCoefficient; + sendUpdate(SPECULAR_COEFFICIENT, specularCoefficient); + } + + public double getSpecularExponent() { + return specularExponent; + } + public void setSpecularExponent(double specularExponent){ + this.specularExponent = specularExponent; + sendUpdate(SPECULAR_EXPONENT, specularExponent); + } + + public boolean getStereo() { + return stereo; + } + public void setStereo(boolean stereo){ + this.stereo = stereo; + sendUpdate(STEREO, stereo); + } + + public Style getStyle() { + return style; + } + public void setStyle(Style style){ + this.style = style; + sendUpdate(STYLE, style); + } + + public int getWidth() { + return width; + } + public void setWidth(int width){ + this.width = width; + sendUpdate(WIDTH, width); + } + + public String getXlabel() { + return xlabel; + } + public void setXlabel(String xlabel){ + this.xlabel = xlabel; + sendUpdate(XLABEL, xlabel); + } + + public List getXlim() { + return xlim; + } + public void setXlim(List xlim){ + this.xlim = xlim; + sendUpdate(XLIM, xlim); + } + + public String getYlabel() { + return ylabel; + } + public void setYlabel(String ylabel){ + this.ylabel = ylabel; + sendUpdate(YLABEL, ylabel); + } + + public List getYlim() { + return ylim; + } + public void setYlim(List ylim){ + this.ylim = ylim; + sendUpdate(YLIM, ylim); + } + + public String getZlabel() { + return zlabel; + } + public void setZlabel(String zlabel){ + this.zlabel = zlabel; + sendUpdate(ZLABEL, zlabel); + } + + public List getZlim() { + return zlim; + } + public void setZlim(List zlim){ + this.zlim = zlim; + sendUpdate(ZLIM, zlim); + } + + public VolumeData getVolumeData(){ + return volumeData; + } + + public void setVolumeData(float[][][] volumeData) { + + VolumeData vol = new VolumeData(volumeData); + this.volumeData = vol; + sendUpdate(VOLUME_DATA, vol.serializeToJson()); + } + + public TransferFunction getTf() { + return tf; + } + + public void setTf(TransferFunction tf) { + this.tf = tf; + sendUpdate(TF, "IPY_MODEL_" + tf.getComm().getCommId()); + } +} diff --git a/ipyvolume-java/src/main/java/ipyvolume/Mesh.java b/ipyvolume-java/src/main/java/ipyvolume/Mesh.java new file mode 100644 index 00000000..292e88f9 --- /dev/null +++ b/ipyvolume-java/src/main/java/ipyvolume/Mesh.java @@ -0,0 +1,102 @@ +package ipyvolume; + + +import com.twosigma.beakerx.widget.DOMWidget; + +public class Mesh extends DOMWidget { + + + + public static final String MODEL_MODULE_VALUE = "ipyvolume"; + public static final String MODEL_MODULE_VERSION_VALUE = "~0.4.5"; + public static final String MODEL_NAME_VALUE = "MeshModel"; + public static final String VIEW_MODULE_VALUE = "ipyvolume"; + public static final String VIEW_MODULE_VERSION_VALUE = "~0.4.5"; + public static final String VIEW_NAME_VALUE = "MeshView"; + public static final String SEQUENCE_INDEX = "sequence_index"; + public static final String SIDE = "side"; + public static final String VISIBLE = "visible"; + public static final String VISIBLE_FACES = "visible_faces"; + public static final String VISIBLE_LINES = "visible_lines"; + + private int sequenceIndex = Integer.parseInt(null); + private Object side = "both"; + private boolean visible = true; + private boolean visibleFaces = true; + private boolean visibleLines = true; + + public Mesh() { + super(); + openComm(); + } + + @Override + public void updateValue(Object value) { + + } + + public String getModelModuleValue(){ + return MODEL_MODULE_VALUE; + } + + public String getModelModuleVersionValue(){ + return MODEL_MODULE_VERSION_VALUE; + } + + public String getModelNameValue(){ + return MODEL_NAME_VALUE; + } + + public String getViewModuleValue(){ + return VIEW_MODULE_VALUE; + } + + public String getViewModuleVersionValue(){ + return VIEW_MODULE_VERSION_VALUE; + } + + public String getViewNameValue(){ + return VIEW_NAME_VALUE; + } + + public int getSequenceIndex() { + return sequenceIndex; + } + public void setSequenceIndex(int sequenceIndex){ + this.sequenceIndex = sequenceIndex; + sendUpdate(SEQUENCE_INDEX, sequenceIndex); + } + + public Object getSide() { + return side; + } + public void setSide(Object side){ + this.side = side; + sendUpdate(SIDE, side); + } + + public boolean getVisible() { + return visible; + } + public void setVisible(boolean visible){ + this.visible = visible; + sendUpdate(VISIBLE, visible); + } + + public boolean getVisibleFaces() { + return visibleFaces; + } + public void setVisibleFaces(boolean visibleFaces){ + this.visibleFaces = visibleFaces; + sendUpdate(VISIBLE_FACES, visibleFaces); + } + + public boolean getVisibleLines() { + return visibleLines; + } + public void setVisibleLines(boolean visibleLines){ + this.visibleLines = visibleLines; + sendUpdate(VISIBLE_LINES, visibleLines); + } + +} diff --git a/ipyvolume-java/src/main/java/ipyvolume/PyLab.java b/ipyvolume-java/src/main/java/ipyvolume/PyLab.java new file mode 100644 index 00000000..0dc4fcba --- /dev/null +++ b/ipyvolume-java/src/main/java/ipyvolume/PyLab.java @@ -0,0 +1,206 @@ +/* + * Copyright 2017 TWO SIGMA OPEN SOURCE, LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *import static org.assertj.core.api.Assertions.assertThat; + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package ipyvolume; + +import com.twosigma.beakerx.widget.Box; +import com.twosigma.beakerx.widget.FloatSlider; +import com.twosigma.beakerx.widget.HBox; +import com.twosigma.beakerx.widget.ToggleButton; +import com.twosigma.beakerx.widget.ToggleButtons; +import com.twosigma.beakerx.widget.VBox; +import com.twosigma.beakerx.widget.Widget; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.UUID; + +public class PyLab { + + private static Current current = new Current(); + + public static Figure volShow(float[][][] data) { + boolean lighting = false; + Float dataMin = null; + Float dataMax = null; + boolean stereo = false; + float ambientCoefficient = 0.5f; + float diffuseCoefficient = 0.8f; + float specularCoefficient = 0.5f; + int specularExponent = 5; + float downscale = 1; + List level = Arrays.asList(0.1f, 0.5f, 0.9f); + List opacity = Arrays.asList(0.01f, 0.05f, 0.1f); + float levelWidth= 0.1f; + boolean controls = true; + float maxOpacity = 0.2f; + Object extent = null; + + Figure vol = gcf(); + + if (dataMin == null) { + dataMin = nanmin(data); + } + if (dataMax == null) { + dataMax = nanmax(data); + } + vol.setTf(transferFunction()); + vol.setVolumeData(data); + vol.setDataMin(dataMin); + vol.setDataMax(dataMax); + vol.setStereo(stereo); + vol.setAmbientCoefficient(ambientCoefficient); + vol.setDiffuseCoefficient(diffuseCoefficient); + vol.setSpecularCoefficient(specularCoefficient); + vol.setSpecularExponent(specularExponent); + vol.setExtent(extent); + if (extent != null) { + } + if (controls) { + FloatSlider ambientCoefficientControl = new FloatSlider(); + ambientCoefficientControl.setStep(0.01); + ambientCoefficientControl.setMax(1); + ambientCoefficientControl.setMin(0); + ambientCoefficientControl.setValue(ambientCoefficient); + ambientCoefficientControl.setDescription("ambient"); + FloatSlider diffuseCoefficientControl = new FloatSlider(); + diffuseCoefficientControl.setStep(0.01); + diffuseCoefficientControl.setMax(1); + diffuseCoefficientControl.setMin(0); + diffuseCoefficientControl.setValue(diffuseCoefficient); + diffuseCoefficientControl.setDescription("diffuse"); + FloatSlider specularCoefficientControl = new FloatSlider(); + specularCoefficientControl.setStep(0.01); + specularCoefficientControl.setMax(1); + specularCoefficientControl.setMin(0); + specularCoefficientControl.setValue(specularCoefficient); + specularCoefficientControl.setDescription("specular"); + FloatSlider specularExponentControl = new FloatSlider(); + specularExponentControl.setStep(0.01); + specularExponentControl.setMax(1); + specularExponentControl.setMin(0); + specularExponentControl.setValue(specularExponent); + specularExponentControl.setDescription("specular exp"); + new HBox(Arrays.asList(ambientCoefficientControl, diffuseCoefficientControl)); + List widgets_bottom = Arrays.asList( + new HBox(Arrays.asList(ambientCoefficientControl, diffuseCoefficientControl)), + new HBox(Arrays.asList(specularCoefficientControl, specularExponentControl)) + ); + current.container = new VBox(widgets_bottom); + } + return vol; + } + + + private static TransferFunction transferFunction() { + TransferFunctionWidgetJs3 tf = new TransferFunctionWidgetJs3(); + Figure fig = gcf(); + return tf; + } + + private static Figure figure(String key, boolean controls, boolean controls_vr, boolean debug) { + if (!key.isEmpty() && current.figures.containsKey(key)) { + current.figure = current.figures.get(key); + current.container = current.containers.get(key); + } else { + current.figure = new Figure(); + List widgetList = new ArrayList<>(); + if (key.isEmpty()) { + key = UUID.randomUUID().toString(); + } + if (controls) { + ToggleButton stereo = new ToggleButton(); + stereo.setValue(current.figure.getStereo()); + stereo.setDescription("stereo"); + stereo.setIcon("eye"); + widgetList.add(stereo); + } + if (controls_vr) { + FloatSlider eyeSeparation = new FloatSlider(); + eyeSeparation.setValue(current.figure.getEyeSeparation()); + eyeSeparation.setMin(-10); + eyeSeparation.setMax(10); + widgetList.add(eyeSeparation); + } + if (debug) { + ToggleButtons show = new ToggleButtons(); + show.setOptions(Arrays.asList("Volume", "Back", "Front")); + widgetList.add(show); + } + current.containers.put(key, new VBox(widgetList)); + } + return current.figure; + } + + private static Figure gcf() { + if (current.figure == null){ + return new Figure(); + } + else { + return current.figure; + } + } + + public static float nanmax(float[][][] data) { + return maxmin(data, true); + } + + public static float nanmin(float[][][] data) { + return maxmin(data, false); + } + + private static float maxmin(float[][][] data, boolean max) { + int size = data.length; + float ext = data[0][0][0]; + for (int x = 0; x < size; x++) { + for (int y=0; y < size; y++){ + for (int z=0; z < size; z++) { + float curr = data[x][y][z]; + if (max && curr > ext) { + ext = curr; + } else if (curr < ext) { + ext = curr; + } + } + } + } + return ext; + } + + public static void show(Widget ... extraWidgets) { + gcf(); + gcc().display(); + for (Widget widget : extraWidgets) { + widget.display(); + } + + } + + private static Box gcc() { + gcf(); + return current.container; + } + + private static class Current { + Figure figure = null; + Box container = null; + Map figures = new HashMap<>(); + Map containers = new HashMap<>(); + } +} \ No newline at end of file diff --git a/ipyvolume-java/src/main/java/ipyvolume/Rgba.java b/ipyvolume-java/src/main/java/ipyvolume/Rgba.java new file mode 100644 index 00000000..af439720 --- /dev/null +++ b/ipyvolume-java/src/main/java/ipyvolume/Rgba.java @@ -0,0 +1,81 @@ +/* + * Copyright 2017 TWO SIGMA OPEN SOURCE, LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *import static org.assertj.core.api.Assertions.assertThat; + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package ipyvolume; + +import com.fasterxml.jackson.core.Version; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.module.SimpleModule; +import ipyvolume.serializers.RgbaSerializer; + +import java.util.Arrays; +import java.util.List; +import java.util.Map; + +import static com.fasterxml.jackson.databind.SerializationFeature.WRITE_ENUMS_USING_TO_STRING; + +public class Rgba { + + private static ObjectMapper mapper; + static { + SimpleModule module = new SimpleModule("SimpleModule", + new Version(1,0,0, null)); + module.addSerializer(Rgba.class, new RgbaSerializer()); + mapper = new ObjectMapper(); + mapper.registerModule(module); + } + + private float[] data = new float[1024]; + private int offset = 0; + private List shape = Arrays.asList(256, 4); + private List stride = Arrays.asList(4, 1); + + public float[] getData() { + return data; + } + + public void setData(float[] data) { + this.data = data; + } + + + public int getOffset() { + return offset; + } + + public void setOffset(int offset) { + this.offset = offset; + } + + public List getShape() { + return shape; + } + + public void setShape(List shape) { + this.shape = shape; + } + + public List getStride() { + return stride; + } + + public void setStride(List stride) { + this.stride = stride; + } + public Object serializeToJson() { + return mapper.convertValue(this, Map.class); + } +} diff --git a/ipyvolume-java/src/main/java/ipyvolume/Scatter.java b/ipyvolume-java/src/main/java/ipyvolume/Scatter.java new file mode 100644 index 00000000..1992bc9c --- /dev/null +++ b/ipyvolume-java/src/main/java/ipyvolume/Scatter.java @@ -0,0 +1,144 @@ +package ipyvolume; + + +import com.twosigma.beakerx.widget.DOMWidget; + +import java.util.ArrayList; + +public class Scatter extends DOMWidget { + + + + public static final String MODEL_MODULE_VALUE = "ipyvolume"; + public static final String MODEL_MODULE_VERSION_VALUE = "~0.4.5"; + public static final String MODEL_NAME_VALUE = "ScatterModel"; + public static final String VIEW_MODULE_VALUE = "ipyvolume"; + public static final String VIEW_MODULE_VERSION_VALUE = "~0.4.5"; + public static final String VIEW_NAME_VALUE = "ScatterView"; + public static final String COLOR_SELECTED = "color_selected"; + public static final String CONNECTED = "connected"; + public static final String GEO = "geo"; + public static final String SEQUENCE_INDEX = "sequence_index"; + public static final String SIZE = "size"; + public static final String SIZE_SELECTED = "size_selected"; + public static final String VISIBLE = "visible"; + public static final String VISIBLE_LINES = "visible_lines"; + public static final String VISIBLE_MARKERS = "visible_markers"; + + private Object colorSelected = new ArrayList<>(); + private boolean connected = false; + private String geo = "diamond"; + private int sequenceIndex = 0; + private Object size = new ArrayList<>(); + private Object sizeSelected = new ArrayList<>(); + private boolean visible = true; + private boolean visibleLines = false; + private boolean visibleMarkers = true; + + public Scatter() { + super(); + openComm(); + } + + @Override + public void updateValue(Object value) { + + } + + public String getModelModuleValue(){ + return MODEL_MODULE_VALUE; + } + + public String getModelModuleVersionValue(){ + return MODEL_MODULE_VERSION_VALUE; + } + + public String getModelNameValue(){ + return MODEL_NAME_VALUE; + } + + public String getViewModuleValue(){ + return VIEW_MODULE_VALUE; + } + + public String getViewModuleVersionValue(){ + return VIEW_MODULE_VERSION_VALUE; + } + + public String getViewNameValue(){ + return VIEW_NAME_VALUE; + } + + public Object getColorSelected() { + return colorSelected; + } + public void setColorSelected(Object colorSelected){ + this.colorSelected = colorSelected; + sendUpdate(COLOR_SELECTED, colorSelected); + } + + public boolean getConnected() { + return connected; + } + public void setConnected(boolean connected){ + this.connected = connected; + sendUpdate(CONNECTED, connected); + } + + public String getGeo() { + return geo; + } + public void setGeo(String geo){ + this.geo = geo; + sendUpdate(GEO, geo); + } + + public int getSequenceIndex() { + return sequenceIndex; + } + public void setSequenceIndex(int sequenceIndex){ + this.sequenceIndex = sequenceIndex; + sendUpdate(SEQUENCE_INDEX, sequenceIndex); + } + + public Object getSize() { + return size; + } + public void setSize(Object size){ + this.size = size; + sendUpdate(SIZE, size); + } + + public Object getSizeSelected() { + return sizeSelected; + } + public void setSizeSelected(Object sizeSelected){ + this.sizeSelected = sizeSelected; + sendUpdate(SIZE_SELECTED, sizeSelected); + } + + public boolean getVisible() { + return visible; + } + public void setVisible(boolean visible){ + this.visible = visible; + sendUpdate(VISIBLE, visible); + } + + public boolean getVisibleLines() { + return visibleLines; + } + public void setVisibleLines(boolean visibleLines){ + this.visibleLines = visibleLines; + sendUpdate(VISIBLE_LINES, visibleLines); + } + + public boolean getVisibleMarkers() { + return visibleMarkers; + } + public void setVisibleMarkers(boolean visibleMarkers){ + this.visibleMarkers = visibleMarkers; + sendUpdate(VISIBLE_MARKERS, visibleMarkers); + } + +} diff --git a/ipyvolume-java/src/main/java/ipyvolume/TransferFunction.java b/ipyvolume-java/src/main/java/ipyvolume/TransferFunction.java new file mode 100644 index 00000000..2f82a6cb --- /dev/null +++ b/ipyvolume-java/src/main/java/ipyvolume/TransferFunction.java @@ -0,0 +1,74 @@ +package ipyvolume; + + +import com.twosigma.beakerx.widget.DOMWidget; +import com.twosigma.beakerx.widget.Style; + +import java.io.Serializable; +import java.util.HashMap; + +public class TransferFunction extends DOMWidget { + + public static final String MODEL_MODULE_VALUE = "ipyvolume"; + public static final String MODEL_MODULE_VERSION_VALUE = "~0.4.5"; + public static final String MODEL_NAME_VALUE = "TransferFunctionModel"; + public static final String VIEW_MODULE_VALUE = "ipyvolume"; + public static final String VIEW_MODULE_VERSION_VALUE = "~0.4.5"; + public static final String VIEW_NAME_VALUE = "TransferFunctionView"; + public static final String RGBA = "rgba"; + public static final String STYLE = "style"; + private Object rgba = null; + private Style style = null; + + public TransferFunction() { + super(); + openComm(); + } + + @Override + public void updateValue(Object value) { + + } + + public String getModelModuleValue(){ + return MODEL_MODULE_VALUE; + } + + public String getModelModuleVersionValue(){ + return MODEL_MODULE_VERSION_VALUE; + } + + public String getModelNameValue(){ + return MODEL_NAME_VALUE; + } + + public String getViewModuleValue(){ + return VIEW_MODULE_VALUE; + } + + public String getViewModuleVersionValue(){ + return VIEW_MODULE_VERSION_VALUE; + } + + public String getViewNameValue(){ + return VIEW_NAME_VALUE; + } + + public Object getRgba() { + return rgba; + } + public void setRgba(Rgba rgba){ + this.rgba = rgba; + sendUpdate(RGBA, rgba.serializeToJson()); + } + + public Style getStyle() { + return style; + } + + public void setStyle(Style style){ + this.style = style; + sendUpdate(STYLE, style); + } + +} diff --git a/ipyvolume-java/src/main/java/ipyvolume/TransferFunctionJsBumps.java b/ipyvolume-java/src/main/java/ipyvolume/TransferFunctionJsBumps.java new file mode 100644 index 00000000..83b2161f --- /dev/null +++ b/ipyvolume-java/src/main/java/ipyvolume/TransferFunctionJsBumps.java @@ -0,0 +1,58 @@ +package ipyvolume; + + +import java.util.Arrays; +import java.util.List; + +public class TransferFunctionJsBumps extends TransferFunction { + + + + public static final String MODEL_MODULE_VALUE = "ipyvolume"; + public static final String MODEL_NAME_VALUE = "TransferFunctionJsBumpsModel"; + public static final String LEVELS = "levels"; + public static final String OPACITIES = "opacities"; + public static final String WIDTHS = "widths"; + + private List levels = Arrays.asList(0.1, 0.5, 0.8); + private List opacities = Arrays.asList(0.01, 0.05, 0.1); + private List widths = Arrays.asList(0.1, 0.1, 0.1); + + public TransferFunctionJsBumps() { + super(); + openComm(); + } + + public String getModelModuleValue(){ + return MODEL_MODULE_VALUE; + } + + public String getModelNameValue(){ + return MODEL_NAME_VALUE; + } + + public List getLevels() { + return levels; + } + public void setLevels(List levels){ + this.levels = levels; + sendUpdate(LEVELS, levels); + } + + public List getOpacities() { + return opacities; + } + public void setOpacities(List opacities){ + this.opacities = opacities; + sendUpdate(OPACITIES, opacities); + } + + public List getWidths() { + return widths; + } + public void setWidths(List widths){ + this.widths = widths; + sendUpdate(WIDTHS, widths); + } + +} diff --git a/ipyvolume-java/src/main/java/ipyvolume/TransferFunctionWidget3.java b/ipyvolume-java/src/main/java/ipyvolume/TransferFunctionWidget3.java new file mode 100644 index 00000000..880f1ec1 --- /dev/null +++ b/ipyvolume-java/src/main/java/ipyvolume/TransferFunctionWidget3.java @@ -0,0 +1,104 @@ +package ipyvolume; + +public class TransferFunctionWidget3 extends TransferFunction { + + + + public static final String LEVEL1 = "level1"; + public static final String LEVEL2 = "level2"; + public static final String LEVEL3 = "level3"; + public static final String OPACITY1 = "opacity1"; + public static final String OPACITY2 = "opacity2"; + public static final String OPACITY3 = "opacity3"; + public static final String WIDTH1 = "width1"; + public static final String WIDTH2 = "width2"; + public static final String WIDTH3 = "width3"; + + private double level1 = 0.1; + private double level2 = 0.5; + private double level3 = 0.8; + private double opacity1 = 0.4; + private double opacity2 = 0.1; + private double opacity3 = 0.1; + private double width1 = 0.1; + private double width2 = 0.1; + private double width3 = 0.1; + + public TransferFunctionWidget3() { + super(); + openComm(); + } + + public double getLevel1() { + return level1; + } + public void setLevel1(double level1){ + this.level1 = level1; + sendUpdate(LEVEL1, level1); + } + + public double getLevel2() { + return level2; + } + public void setLevel2(double level2){ + this.level2 = level2; + sendUpdate(LEVEL2, level2); + } + + public double getLevel3() { + return level3; + } + public void setLevel3(double level3){ + this.level3 = level3; + sendUpdate(LEVEL3, level3); + } + + public double getOpacity1() { + return opacity1; + } + public void setOpacity1(double opacity1){ + this.opacity1 = opacity1; + sendUpdate(OPACITY1, opacity1); + } + + public double getOpacity2() { + return opacity2; + } + public void setOpacity2(double opacity2){ + this.opacity2 = opacity2; + sendUpdate(OPACITY2, opacity2); + } + + public double getOpacity3() { + return opacity3; + } + public void setOpacity3(double opacity3){ + this.opacity3 = opacity3; + sendUpdate(OPACITY3, opacity3); + } + + public double getWidth1() { + return width1; + } + public void setWidth1(double width1){ + this.width1 = width1; + sendUpdate(WIDTH1, width1); + } + + public double getWidth2() { + return width2; + } + public void setWidth2(double width2){ + this.width2 = width2; + sendUpdate(WIDTH2, width2); + } + + public double getWidth3() { + return width3; + } + public void setWidth3(double width3){ + this.width3 = width3; + sendUpdate(WIDTH3, width3); + } + +} diff --git a/ipyvolume-java/src/main/java/ipyvolume/TransferFunctionWidgetJs3.java b/ipyvolume-java/src/main/java/ipyvolume/TransferFunctionWidgetJs3.java new file mode 100644 index 00000000..f194c1da --- /dev/null +++ b/ipyvolume-java/src/main/java/ipyvolume/TransferFunctionWidgetJs3.java @@ -0,0 +1,161 @@ +package ipyvolume; + + +import com.twosigma.beakerx.widget.Box; +import com.twosigma.beakerx.widget.FloatSlider; +import com.twosigma.beakerx.widget.HBox; +import com.twosigma.beakerx.widget.Label; +import com.twosigma.beakerx.widget.VBox; + +import java.util.Arrays; + +public class TransferFunctionWidgetJs3 extends TransferFunction { + + + + public static final String MODEL_MODULE_VALUE = "ipyvolume"; + public static final String MODEL_NAME_VALUE = "TransferFunctionWidgetJs3Model"; + public static final String LEVEL1 = "level1"; + public static final String LEVEL2 = "level2"; + public static final String LEVEL3 = "level3"; + public static final String OPACITY1 = "opacity1"; + public static final String OPACITY2 = "opacity2"; + public static final String OPACITY3 = "opacity3"; + public static final String WIDTH1 = "width1"; + public static final String WIDTH2 = "width2"; + public static final String WIDTH3 = "width3"; + + private double level1 = 0.1; + private double level2 = 0.5; + private double level3 = 0.8; + private double opacity1 = 0.01; + private double opacity2 = 0.05; + private double opacity3 = 0.1; + private double width1 = 0.1; + private double width2 = 0.1; + private double width3 = 0.1; + + public TransferFunctionWidgetJs3() { + super(); + openComm(); + } + + public String getModelModuleValue(){ + return MODEL_MODULE_VALUE; + } + + public String getModelNameValue(){ + return MODEL_NAME_VALUE; + } + + public double getLevel1() { + return level1; + } + public void setLevel1(double level1){ + this.level1 = level1; + sendUpdate(LEVEL1, level1); + } + + public double getLevel2() { + return level2; + } + public void setLevel2(double level2){ + this.level2 = level2; + sendUpdate(LEVEL2, level2); + } + + public double getLevel3() { + return level3; + } + public void setLevel3(double level3){ + this.level3 = level3; + sendUpdate(LEVEL3, level3); + } + + public double getOpacity1() { + return opacity1; + } + public void setOpacity1(double opacity1){ + this.opacity1 = opacity1; + sendUpdate(OPACITY1, opacity1); + } + + public double getOpacity2() { + return opacity2; + } + public void setOpacity2(double opacity2){ + this.opacity2 = opacity2; + sendUpdate(OPACITY2, opacity2); + } + + public double getOpacity3() { + return opacity3; + } + public void setOpacity3(double opacity3){ + this.opacity3 = opacity3; + sendUpdate(OPACITY3, opacity3); + } + + public double getWidth1() { + return width1; + } + public void setWidth1(double width1){ + this.width1 = width1; + sendUpdate(WIDTH1, width1); + } + + public double getWidth2() { + return width2; + } + public void setWidth2(double width2){ + this.width2 = width2; + sendUpdate(WIDTH2, width2); + } + + public double getWidth3() { + return width3; + } + public void setWidth3(double width3){ + this.width3 = width3; + sendUpdate(WIDTH3, width3); + } + + public Box control(){ + FloatSlider l1 = new FloatSlider(); + l1.setMin(0); + l1.setMax(1); + l1.setStep(0.001); + l1.setValue(level1); + FloatSlider l2 = new FloatSlider(); + l2.setMin(0); + l2.setMax(1); + l2.setStep(0.001); + l2.setValue(level2); + FloatSlider l3 = new FloatSlider(); + l3.setMin(0); + l3.setMax(1); + l3.setStep(0.001); + l3.setValue(level3); + FloatSlider o1 = new FloatSlider(); + o1.setMin(0); + o1.setMax(1); + o1.setStep(0.001); + o1.setValue(opacity1); + FloatSlider o2 = new FloatSlider(); + o2.setMin(0); + o2.setMax(1); + o2.setStep(0.001); + o2.setValue(opacity2); + FloatSlider o3 = new FloatSlider(); + o3.setMin(0); + o3.setMax(1); + o3.setStep(0.001); + o3.setValue(opacity3); + Label label1 = new Label(); + label1.setDescription("Levels"); + Label label2 = new Label(); + label2.setDescription("Opacities"); + return new VBox(Arrays.asList(new HBox(Arrays.asList(label1, l1, l2, l3)), new HBox(Arrays.asList(label2, o1, o2, o3)))); + } + +} diff --git a/ipyvolume-java/src/main/java/ipyvolume/VolumeData.java b/ipyvolume-java/src/main/java/ipyvolume/VolumeData.java new file mode 100644 index 00000000..57bcbd4f --- /dev/null +++ b/ipyvolume-java/src/main/java/ipyvolume/VolumeData.java @@ -0,0 +1,114 @@ +/* + * Copyright 2017 TWO SIGMA OPEN SOURCE, LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *import static org.assertj.core.api.Assertions.assertThat; + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package ipyvolume; + +import com.fasterxml.jackson.core.Version; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.module.SimpleModule; +import ipyvolume.serializers.VolumeDataSerializer; + +import java.util.Arrays; +import java.util.List; +import java.util.Map; + +public class VolumeData { + + private static int MIN_TEXTURE_WIDTH = 256; + private static int MAX_TEXTURE_WIDTH = 2048 * 8; + + private static ObjectMapper mapper; + static { + SimpleModule module = new SimpleModule("SimpleModule", new Version(1,0,0, null)); + module.addSerializer(VolumeData.class, new VolumeDataSerializer()); + mapper = new ObjectMapper(); + mapper.registerModule(module); + } + + private List imageShape; + private List sliceShape; + private int rows; + private int columns; + private int slices; + private float[][][] tiles; + + public VolumeData(float[][][] data) { + this.slices = data.length; + int approxRows = (int) Math.round(Math.sqrt(this.slices)); + int imgWidth = Math.max(MIN_TEXTURE_WIDTH, Math.min(MAX_TEXTURE_WIDTH, getNextPowOf2(approxRows * data[0].length))); + this.columns = imgWidth/ data[0][0].length; + this.rows = (int) Math.ceil(this.slices/ (float) this.columns); + int imgHeight = Math.max(MIN_TEXTURE_WIDTH, getNextPowOf2(this.rows * data[0].length)); + this.imageShape = Arrays.asList(imgWidth, imgHeight); + this.sliceShape = Arrays.asList(data.length, data.length); + this.tiles = data; + } + + private int getNextPowOf2(int value) { + return (int) Math.pow(2, 32 - Integer.numberOfLeadingZeros(value - 1)); + } + + public List getImageShape() { + return imageShape; + } + + public void setImageShape(List imageShape) { + this.imageShape = imageShape; + } + + public List getSliceShape() { + return sliceShape; + } + + public void setSliceShape(List sliceShape) { + this.sliceShape = sliceShape; + } + + public int getRows() { + return rows; + } + + public void setRows(int rows) { + this.rows = rows; + } + + public int getColumns() { + return columns; + } + + public void setColumns(int columns) { + this.columns = columns; + } + + public int getSlices() { + return slices; + } + + public void setSlices(int slices) { + this.slices = slices; + } + + public float[][][] getTiles() { + return tiles; + } + + public void setTiles(float[][][] tiles) { + this.tiles = tiles; + } + + public Object serializeToJson() { + return mapper.convertValue(this, Map.class); + } +} diff --git a/ipyvolume-java/src/main/java/ipyvolume/serializers/RgbaSerializer.java b/ipyvolume-java/src/main/java/ipyvolume/serializers/RgbaSerializer.java new file mode 100644 index 00000000..2d45cfd2 --- /dev/null +++ b/ipyvolume-java/src/main/java/ipyvolume/serializers/RgbaSerializer.java @@ -0,0 +1,40 @@ +/* + * Copyright 2017 TWO SIGMA OPEN SOURCE, LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *import static org.assertj.core.api.Assertions.assertThat; + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package ipyvolume.serializers; +import com.fasterxml.jackson.core.JsonGenerator; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.JsonSerializer; +import com.fasterxml.jackson.databind.SerializerProvider; +import ipyvolume.Rgba; + +import java.io.IOException; + +public class RgbaSerializer extends JsonSerializer { + @Override + public void serialize(Rgba value, JsonGenerator jgen, SerializerProvider provider) + throws IOException, JsonProcessingException { + + synchronized (value) { + jgen.writeStartObject(); + jgen.writeObjectField("data", value.getData()); + jgen.writeObjectField("offset", value.getOffset()); + jgen.writeObjectField("shape", value.getShape()); + jgen.writeObjectField("stride", value.getStride()); + jgen.writeEndObject(); + } + + } +} diff --git a/ipyvolume-java/src/main/java/ipyvolume/serializers/VolumeDataSerializer.java b/ipyvolume-java/src/main/java/ipyvolume/serializers/VolumeDataSerializer.java new file mode 100644 index 00000000..4388df16 --- /dev/null +++ b/ipyvolume-java/src/main/java/ipyvolume/serializers/VolumeDataSerializer.java @@ -0,0 +1,70 @@ +/* + * Copyright 2017 TWO SIGMA OPEN SOURCE, LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *import static org.assertj.core.api.Assertions.assertThat; + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package ipyvolume.serializers; + +import com.fasterxml.jackson.core.JsonGenerator; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.JsonSerializer; +import com.fasterxml.jackson.databind.SerializerProvider; +import ipyvolume.VolumeData; + +import javax.imageio.ImageIO; +import java.awt.*; +import java.awt.image.BufferedImage; +import java.io.ByteArrayOutputStream; +import java.io.IOException; + +public class VolumeDataSerializer extends JsonSerializer{ + @Override + public void serialize(VolumeData value, JsonGenerator jgen, SerializerProvider provider) + throws IOException, JsonProcessingException { + + synchronized (value) { + jgen.writeStartObject(); + jgen.writeObjectField("image_shape", value.getImageShape()); + jgen.writeObjectField("slice_shape", value.getSliceShape()); + jgen.writeObjectField("rows", value.getRows()); + jgen.writeObjectField("columns", value.getColumns()); + jgen.writeObjectField("slices", value.getSlices()); + jgen.writeObjectField("src", dataToPng(value)); + jgen.writeEndObject(); + } + } + + private String dataToPng(VolumeData volumeData) throws IOException { + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + BufferedImage bi = new BufferedImage( + volumeData.getImageShape().get(0), + volumeData.getImageShape().get(1), + BufferedImage.TYPE_4BYTE_ABGR); + Graphics gc = bi.getGraphics(); + int yOffset = volumeData.getImageShape().get(1) - (volumeData.getRows() * volumeData.getSliceShape().get(1)); + for (int slice = 0; slice < volumeData.getSlices(); slice++) { + int sliceRow = volumeData.getRows() - 1 - slice / volumeData.getColumns(); + int sliceCol = slice % volumeData.getColumns(); + int sliceXStart = sliceCol * volumeData.getSliceShape().get(0); + int sliceYStart = sliceRow * volumeData.getSliceShape().get(1); + for (int x = 0; x < volumeData.getSliceShape().get(0); x++) { + for (int y = 0; y < volumeData.getSliceShape().get(1); y++) { + gc.setColor(new java.awt.Color(0, 0, 0, (int) (255 * volumeData.getTiles()[slice][x][y]))); + gc.fillRect(sliceXStart + x, sliceYStart + y + yOffset, 1, 1); + } + } + } + ImageIO.write(bi, "png", baos); + return "data:image/png;base64," + java.util.Base64.getEncoder().encodeToString(baos.toByteArray()); + } +} diff --git a/ipyvolume-java/src/main/java/ipywebrtc/CameraStream.java b/ipyvolume-java/src/main/java/ipywebrtc/CameraStream.java new file mode 100644 index 00000000..2dcb7187 --- /dev/null +++ b/ipyvolume-java/src/main/java/ipywebrtc/CameraStream.java @@ -0,0 +1,40 @@ +package ipywebrtc; + + +public class CameraStream extends MediaStream { + + + + public static final String MODEL_NAME_VALUE = "CameraStreamModel"; + public static final String AUDIO = "audio"; + public static final String VIDEO = "video"; + + private boolean audio = true; + private boolean video = true; + + public CameraStream() { + super(); + openComm(); + } + + public String getModelNameValue(){ + return MODEL_NAME_VALUE; + } + + public boolean getAudio() { + return audio; + } + public void setAudio(boolean audio){ + this.audio = audio; + sendUpdate(AUDIO, audio); + } + + public boolean getVideo() { + return video; + } + public void setVideo(boolean video){ + this.video = video; + sendUpdate(VIDEO, video); + } + +} diff --git a/ipyvolume-java/src/main/java/ipywebrtc/MediaRecorder.java b/ipyvolume-java/src/main/java/ipywebrtc/MediaRecorder.java new file mode 100644 index 00000000..359a7dc6 --- /dev/null +++ b/ipyvolume-java/src/main/java/ipywebrtc/MediaRecorder.java @@ -0,0 +1,90 @@ +package ipywebrtc; + + +import com.twosigma.beakerx.widget.Widget; + +import java.io.Serializable; +import java.util.HashMap; + +public class MediaRecorder extends Widget { + + + + public static final String MODEL_MODULE_VALUE = "jupyter-webrtc"; + public static final String MODEL_MODULE_VERSION_VALUE = "~0.3.0"; + public static final String MODEL_NAME_VALUE = "MediaRecorderModel"; + public static final String DATA = "data"; + public static final String MIME_TYPE = "mime_type"; + public static final String RECORD = "record"; + public static final String STREAM = "stream"; + + private Object data = null; + private String mimeType = "video/webm"; + private boolean record = false; + private Object stream = null; + + public MediaRecorder() { + super(); + openComm(); + } + + public String getModelModuleValue(){ + return MODEL_MODULE_VALUE; + } + + @Override + protected void addValueChangeMsgCallback() { + + } + + @Override + protected HashMap content(HashMap content) { + return null; + } + + public String getModelModuleVersionValue(){ + return MODEL_MODULE_VERSION_VALUE; + } + + public String getModelNameValue(){ + return MODEL_NAME_VALUE; + } + + @Override + public String getViewNameValue() { + return null; + } + + public Object getData() { + return data; + } + public void setData(Object data){ + this.data = data; + sendUpdate(DATA, data); + } + + public String getMimeType() { + return mimeType; + } + public void setMimeType(String mimeType){ + this.mimeType = mimeType; + sendUpdate(MIME_TYPE, mimeType); + } + + public boolean getRecord() { + return record; + } + public void setRecord(boolean record){ + this.record = record; + sendUpdate(RECORD, record); + } + + public Object getStream() { + return stream; + } + public void setStream(Object stream){ + this.stream = stream; + sendUpdate(STREAM, stream); + } + +} diff --git a/ipyvolume-java/src/main/java/ipywebrtc/MediaStream.java b/ipyvolume-java/src/main/java/ipywebrtc/MediaStream.java new file mode 100644 index 00000000..d1e56bb6 --- /dev/null +++ b/ipyvolume-java/src/main/java/ipywebrtc/MediaStream.java @@ -0,0 +1,52 @@ +package ipywebrtc; + + +import com.twosigma.beakerx.widget.DOMWidget; + +public class MediaStream extends DOMWidget { + + + + public static final String MODEL_MODULE_VALUE = "jupyter-webrtc"; + public static final String MODEL_MODULE_VERSION_VALUE = "~0.3.0"; + public static final String MODEL_NAME_VALUE = "MediaStreamModel"; + public static final String VIEW_MODULE_VALUE = "jupyter-webrtc"; + public static final String VIEW_MODULE_VERSION_VALUE = "~0.3.0"; + public static final String VIEW_NAME_VALUE = "MediaStreamView"; + + + public MediaStream() { + super(); + openComm(); + } + + @Override + public void updateValue(Object value) { + + } + + public String getModelModuleValue(){ + return MODEL_MODULE_VALUE; + } + + public String getModelModuleVersionValue(){ + return MODEL_MODULE_VERSION_VALUE; + } + + public String getModelNameValue(){ + return MODEL_NAME_VALUE; + } + + public String getViewModuleValue(){ + return VIEW_MODULE_VALUE; + } + + public String getViewModuleVersionValue(){ + return VIEW_MODULE_VERSION_VALUE; + } + + public String getViewNameValue(){ + return VIEW_NAME_VALUE; + } + +} diff --git a/ipyvolume-java/src/main/java/ipywebrtc/VideoStream.java b/ipyvolume-java/src/main/java/ipywebrtc/VideoStream.java new file mode 100644 index 00000000..3b63b3b8 --- /dev/null +++ b/ipyvolume-java/src/main/java/ipywebrtc/VideoStream.java @@ -0,0 +1,59 @@ +package ipywebrtc; + +public class VideoStream extends MediaStream { + + + + public static final String MODEL_NAME_VALUE = "VideoStreamModel"; + public static final String DATA = "data"; + public static final String LOOP = "loop"; + public static final String PLAY = "play"; + public static final String URL = "url"; + + private Object data = null; + private boolean loop = true; + private boolean play = true; + private String url = "https://webrtc.github.io/samples/src/video/chrome.mp4"; + + public VideoStream() { + super(); + openComm(); + } + + public String getModelNameValue(){ + return MODEL_NAME_VALUE; + } + + public Object getData() { + return data; + } + public void setData(Object data){ + this.data = data; + sendUpdate(DATA, data); + } + + public boolean getLoop() { + return loop; + } + public void setLoop(boolean loop){ + this.loop = loop; + sendUpdate(LOOP, loop); + } + + public boolean getPlay() { + return play; + } + public void setPlay(boolean play){ + this.play = play; + sendUpdate(PLAY, play); + } + + public String getUrl() { + return url; + } + public void setUrl(String url){ + this.url = url; + sendUpdate(URL, url); + } + +} diff --git a/ipyvolume-java/src/main/java/ipywebrtc/WebRTCPeer.java b/ipyvolume-java/src/main/java/ipywebrtc/WebRTCPeer.java new file mode 100644 index 00000000..9a12d638 --- /dev/null +++ b/ipyvolume-java/src/main/java/ipywebrtc/WebRTCPeer.java @@ -0,0 +1,95 @@ +package ipywebrtc; + + +public class WebRTCPeer extends MediaStream { + + + + public static final String MODEL_MODULE_VALUE = "jupyter-webrtc"; + public static final String MODEL_NAME_VALUE = "WebRTCPeerModel"; + public static final String VIEW_MODULE_VALUE = "jupyter-webrtc"; + public static final String VIEW_NAME_VALUE = "WebRTCPeerView"; + public static final String CONNECTED = "connected"; + public static final String FAILED = "failed"; + public static final String ID_LOCAL = "id_local"; + public static final String ID_REMOTE = "id_remote"; + public static final String STREAM_LOCAL = "stream_local"; + public static final String STREAM_REMOTE = "stream_remote"; + + private boolean connected = false; + private boolean failed = false; + private String idLocal = "lala"; + private String idRemote = "lala"; + private Object streamLocal = null; + private Object streamRemote = null; + + public WebRTCPeer() { + super(); + openComm(); + } + + public String getModelModuleValue(){ + return MODEL_MODULE_VALUE; + } + + public String getModelNameValue(){ + return MODEL_NAME_VALUE; + } + + public String getViewModuleValue(){ + return VIEW_MODULE_VALUE; + } + + public String getViewNameValue(){ + return VIEW_NAME_VALUE; + } + + public boolean getConnected() { + return connected; + } + public void setConnected(boolean connected){ + this.connected = connected; + sendUpdate(CONNECTED, connected); + } + + public boolean getFailed() { + return failed; + } + public void setFailed(boolean failed){ + this.failed = failed; + sendUpdate(FAILED, failed); + } + + public String getIdLocal() { + return idLocal; + } + public void setIdLocal(String idLocal){ + this.idLocal = idLocal; + sendUpdate(ID_LOCAL, idLocal); + } + + public String getIdRemote() { + return idRemote; + } + public void setIdRemote(String idRemote){ + this.idRemote = idRemote; + sendUpdate(ID_REMOTE, idRemote); + } + + public Object getStreamLocal() { + return streamLocal; + } + public void setStreamLocal(Object streamLocal){ + this.streamLocal = streamLocal; + sendUpdate(STREAM_LOCAL, streamLocal); + } + + public Object getStreamRemote() { + return streamRemote; + } + public void setStreamRemote(Object streamRemote){ + this.streamRemote = streamRemote; + sendUpdate(STREAM_REMOTE, streamRemote); + } + +} diff --git a/ipyvolume-java/src/main/java/ipywebrtc/WebRTCRoom.java b/ipyvolume-java/src/main/java/ipywebrtc/WebRTCRoom.java new file mode 100644 index 00000000..08784dd5 --- /dev/null +++ b/ipyvolume-java/src/main/java/ipywebrtc/WebRTCRoom.java @@ -0,0 +1,105 @@ +package ipywebrtc; + + +import com.twosigma.beakerx.widget.DOMWidget; + +import java.util.ArrayList; +import java.util.List; + +public class WebRTCRoom extends DOMWidget { + + + + public static final String MODEL_MODULE_VALUE = "jupyter-webrtc"; + public static final String MODEL_MODULE_VERSION_VALUE = "~0.3.0"; + public static final String MODEL_NAME_VALUE = "WebRTCRoomModel"; + public static final String ID = "id"; + public static final String NICKNAME = "nickname"; + public static final String PEERS = "peers"; + public static final String ROOM = "room"; + public static final String STREAM = "stream"; + public static final String STREAMS = "streams"; + + private String id = null; + private String nickname = "anonymous"; + private List peers = new ArrayList<>(); + private String room = "room"; + private Object stream = null; + private List streams = new ArrayList<>(); + + public WebRTCRoom() { + super(); + openComm(); + } + + @Override + public void updateValue(Object value) { + + } + + public String getModelModuleValue(){ + return MODEL_MODULE_VALUE; + } + + public String getModelModuleVersionValue(){ + return MODEL_MODULE_VERSION_VALUE; + } + + public String getModelNameValue(){ + return MODEL_NAME_VALUE; + } + + @Override + public String getViewNameValue() { + return null; + } + + public String getId() { + return id; + } + public void setId(String id){ + this.id = id; + sendUpdate(ID, id); + } + + public String getNickname() { + return nickname; + } + public void setNickname(String nickname){ + this.nickname = nickname; + sendUpdate(NICKNAME, nickname); + } + + public List getPeers() { + return peers; + } + public void setPeers(List peers){ + this.peers = peers; + sendUpdate(PEERS, peers); + } + + public String getRoom() { + return room; + } + public void setRoom(String room){ + this.room = room; + sendUpdate(ROOM, room); + } + + public Object getStream() { + return stream; + } + public void setStream(Object stream){ + this.stream = stream; + sendUpdate(STREAM, stream); + } + + public List getStreams() { + return streams; + } + public void setStreams(List streams){ + this.streams = streams; + sendUpdate(STREAMS, streams); + } + +} diff --git a/ipyvolume-java/src/main/java/ipywebrtc/WebRTCRoomLocal.java b/ipyvolume-java/src/main/java/ipywebrtc/WebRTCRoomLocal.java new file mode 100644 index 00000000..38d0120e --- /dev/null +++ b/ipyvolume-java/src/main/java/ipywebrtc/WebRTCRoomLocal.java @@ -0,0 +1,20 @@ +package ipywebrtc; + + +public class WebRTCRoomLocal extends WebRTCRoom { + + + + public static final String MODEL_NAME_VALUE = "WebRTCRoomLocalModel"; + + + public WebRTCRoomLocal() { + super(); + openComm(); + } + + public String getModelNameValue(){ + return MODEL_NAME_VALUE; + } + +} diff --git a/ipyvolume-java/src/main/java/ipywebrtc/WebRTCRoomMqtt.java b/ipyvolume-java/src/main/java/ipywebrtc/WebRTCRoomMqtt.java new file mode 100644 index 00000000..71a843db --- /dev/null +++ b/ipyvolume-java/src/main/java/ipywebrtc/WebRTCRoomMqtt.java @@ -0,0 +1,30 @@ +package ipywebrtc; + + +public class WebRTCRoomMqtt extends WebRTCRoom { + + + + public static final String MODEL_NAME_VALUE = "WebRTCRoomMqttModel"; + public static final String SERVER = "server"; + + private String server = "wss://iot.eclipse.org:443/ws"; + + public WebRTCRoomMqtt() { + super(); + openComm(); + } + + public String getModelNameValue(){ + return MODEL_NAME_VALUE; + } + + public String getServer() { + return server; + } + public void setServer(String server){ + this.server = server; + sendUpdate(SERVER, server); + } + +}