Demo app
This commit is contained in:
parent
b5164916bb
commit
598030f970
@ -1,5 +1,13 @@
|
|||||||
val dataforgeVersion by extra("0.1.3-dev-7")
|
val dataforgeVersion by extra("0.1.3-dev-7")
|
||||||
|
|
||||||
|
plugins{
|
||||||
|
kotlin("jvm") version "1.3.40" apply false
|
||||||
|
id("kotlin2js") version "1.3.40" apply false
|
||||||
|
id("kotlin-dce-js") version "1.3.40" apply false
|
||||||
|
id("org.jetbrains.kotlin.frontend") version "0.0.45" apply false
|
||||||
|
id("scientifik.mpp") version "0.1.0" apply false
|
||||||
|
}
|
||||||
|
|
||||||
allprojects {
|
allprojects {
|
||||||
repositories {
|
repositories {
|
||||||
mavenLocal()
|
mavenLocal()
|
||||||
|
@ -1,22 +0,0 @@
|
|||||||
plugins {
|
|
||||||
`kotlin-dsl`
|
|
||||||
}
|
|
||||||
|
|
||||||
repositories {
|
|
||||||
gradlePluginPortal()
|
|
||||||
jcenter()
|
|
||||||
maven("https://dl.bintray.com/kotlin/kotlin-eap")
|
|
||||||
}
|
|
||||||
|
|
||||||
val kotlinVersion = "1.3.40"
|
|
||||||
|
|
||||||
// Add plugins used in buildSrc as dependencies, also we should specify version only here
|
|
||||||
dependencies {
|
|
||||||
implementation("org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlinVersion")
|
|
||||||
implementation("org.jfrog.buildinfo:build-info-extractor-gradle:4.9.6")
|
|
||||||
implementation("com.jfrog.bintray.gradle:gradle-bintray-plugin:1.8.4")
|
|
||||||
implementation("org.jetbrains.dokka:dokka-gradle-plugin:0.9.18")
|
|
||||||
implementation("com.moowork.gradle:gradle-node-plugin:1.3.1")
|
|
||||||
implementation("org.openjfx:javafx-plugin:0.0.7")
|
|
||||||
implementation("org.jetbrains.kotlin:kotlin-frontend-plugin:0.0.45")
|
|
||||||
}
|
|
@ -1,9 +0,0 @@
|
|||||||
// Instead of defining runtime properties and use them dynamically
|
|
||||||
// define version in buildSrc and have autocompletion and compile-time check
|
|
||||||
// Also dependencies itself can be moved here
|
|
||||||
object Versions {
|
|
||||||
val ioVersion = "0.1.10"
|
|
||||||
val coroutinesVersion = "1.2.1"
|
|
||||||
val atomicfuVersion = "0.12.6"
|
|
||||||
val serializationVersion = "0.11.1"
|
|
||||||
}
|
|
@ -1,75 +0,0 @@
|
|||||||
import org.jetbrains.dokka.gradle.DokkaTask
|
|
||||||
import org.jetbrains.kotlin.gradle.dsl.KotlinJvmProjectExtension
|
|
||||||
import org.jetbrains.kotlin.gradle.dsl.KotlinMultiplatformExtension
|
|
||||||
|
|
||||||
plugins {
|
|
||||||
id("org.jetbrains.dokka")
|
|
||||||
`maven-publish`
|
|
||||||
}
|
|
||||||
|
|
||||||
afterEvaluate {
|
|
||||||
|
|
||||||
extensions.findByType<KotlinMultiplatformExtension>()?.apply{
|
|
||||||
val dokka by tasks.getting(DokkaTask::class) {
|
|
||||||
outputFormat = "html"
|
|
||||||
outputDirectory = "$buildDir/javadoc"
|
|
||||||
jdkVersion = 8
|
|
||||||
|
|
||||||
kotlinTasks {
|
|
||||||
// dokka fails to retrieve sources from MPP-tasks so we only define the jvm task
|
|
||||||
listOf(tasks.getByPath("compileKotlinJvm"))
|
|
||||||
}
|
|
||||||
sourceRoot {
|
|
||||||
// assuming only single source dir
|
|
||||||
path = sourceSets["commonMain"].kotlin.srcDirs.first().toString()
|
|
||||||
platforms = listOf("Common")
|
|
||||||
}
|
|
||||||
// although the JVM sources are now taken from the task,
|
|
||||||
// we still define the jvm source root to get the JVM marker in the generated html
|
|
||||||
sourceRoot {
|
|
||||||
// assuming only single source dir
|
|
||||||
path = sourceSets["jvmMain"].kotlin.srcDirs.first().toString()
|
|
||||||
platforms = listOf("JVM")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
val kdocJar by tasks.registering(Jar::class) {
|
|
||||||
group = JavaBasePlugin.DOCUMENTATION_GROUP
|
|
||||||
dependsOn(dokka)
|
|
||||||
archiveClassifier.set("javadoc")
|
|
||||||
from("$buildDir/javadoc")
|
|
||||||
}
|
|
||||||
|
|
||||||
configure<PublishingExtension> {
|
|
||||||
|
|
||||||
targets.all {
|
|
||||||
val publication = publications.findByName(name) as MavenPublication
|
|
||||||
|
|
||||||
// Patch publications with fake javadoc
|
|
||||||
publication.artifact(kdocJar.get())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
extensions.findByType<KotlinJvmProjectExtension>()?.apply{
|
|
||||||
val dokka by tasks.getting(DokkaTask::class) {
|
|
||||||
outputFormat = "html"
|
|
||||||
outputDirectory = "$buildDir/javadoc"
|
|
||||||
jdkVersion = 8
|
|
||||||
}
|
|
||||||
|
|
||||||
val kdocJar by tasks.registering(Jar::class) {
|
|
||||||
group = JavaBasePlugin.DOCUMENTATION_GROUP
|
|
||||||
dependsOn(dokka)
|
|
||||||
archiveClassifier.set("javadoc")
|
|
||||||
from("$buildDir/javadoc")
|
|
||||||
}
|
|
||||||
|
|
||||||
configure<PublishingExtension> {
|
|
||||||
publications.filterIsInstance<MavenPublication>().forEach { publication ->
|
|
||||||
publication.artifact(kdocJar.get())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,43 +0,0 @@
|
|||||||
import com.moowork.gradle.node.npm.NpmTask
|
|
||||||
import com.moowork.gradle.node.task.NodeTask
|
|
||||||
import org.jetbrains.kotlin.gradle.tasks.Kotlin2JsCompile
|
|
||||||
|
|
||||||
plugins {
|
|
||||||
id("com.moowork.node")
|
|
||||||
kotlin("multiplatform")
|
|
||||||
}
|
|
||||||
|
|
||||||
node {
|
|
||||||
nodeModulesDir = file("$buildDir/node_modules")
|
|
||||||
}
|
|
||||||
|
|
||||||
val compileKotlinJs by tasks.getting(Kotlin2JsCompile::class)
|
|
||||||
val compileTestKotlinJs by tasks.getting(Kotlin2JsCompile::class)
|
|
||||||
|
|
||||||
val populateNodeModules by tasks.registering(Copy::class) {
|
|
||||||
dependsOn(compileKotlinJs)
|
|
||||||
from(compileKotlinJs.destinationDir)
|
|
||||||
|
|
||||||
kotlin.js().compilations["test"].runtimeDependencyFiles.forEach {
|
|
||||||
if (it.exists() && !it.isDirectory) {
|
|
||||||
from(zipTree(it.absolutePath).matching { include("*.js") })
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
into("$buildDir/node_modules")
|
|
||||||
}
|
|
||||||
|
|
||||||
val installMocha by tasks.registering(NpmTask::class) {
|
|
||||||
setWorkingDir(buildDir)
|
|
||||||
setArgs(listOf("install", "mocha"))
|
|
||||||
}
|
|
||||||
|
|
||||||
val runMocha by tasks.registering(NodeTask::class) {
|
|
||||||
dependsOn(compileTestKotlinJs, populateNodeModules, installMocha)
|
|
||||||
setScript(file("$buildDir/node_modules/mocha/bin/mocha"))
|
|
||||||
setArgs(listOf(compileTestKotlinJs.outputFile))
|
|
||||||
}
|
|
||||||
|
|
||||||
tasks["jsTest"].dependsOn(runMocha)
|
|
||||||
|
|
||||||
|
|
@ -1,82 +0,0 @@
|
|||||||
plugins {
|
|
||||||
kotlin("multiplatform")
|
|
||||||
`maven-publish`
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
kotlin {
|
|
||||||
jvm {
|
|
||||||
compilations.all {
|
|
||||||
kotlinOptions {
|
|
||||||
jvmTarget = "1.8"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
js {
|
|
||||||
compilations.all {
|
|
||||||
kotlinOptions {
|
|
||||||
metaInfo = true
|
|
||||||
sourceMap = true
|
|
||||||
sourceMapEmbedSources = "always"
|
|
||||||
moduleKind = "commonjs"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
compilations.named("main") {
|
|
||||||
kotlinOptions {
|
|
||||||
main = "call"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
sourceSets {
|
|
||||||
val commonMain by getting {
|
|
||||||
dependencies {
|
|
||||||
api(kotlin("stdlib"))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
val commonTest by getting {
|
|
||||||
dependencies {
|
|
||||||
implementation(kotlin("test-common"))
|
|
||||||
implementation(kotlin("test-annotations-common"))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
val jvmMain by getting {
|
|
||||||
dependencies {
|
|
||||||
api(kotlin("stdlib-jdk8"))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
val jvmTest by getting {
|
|
||||||
dependencies {
|
|
||||||
implementation(kotlin("test"))
|
|
||||||
implementation(kotlin("test-junit"))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
val jsMain by getting {
|
|
||||||
dependencies {
|
|
||||||
api(kotlin("stdlib-js"))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
val jsTest by getting {
|
|
||||||
dependencies {
|
|
||||||
implementation(kotlin("test-js"))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
targets.all {
|
|
||||||
sourceSets.all {
|
|
||||||
languageSettings.progressiveMode = true
|
|
||||||
languageSettings.enableLanguageFeature("InlineClasses")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Apply JS test configuration
|
|
||||||
val runJsTests by ext(false)
|
|
||||||
|
|
||||||
if (runJsTests) {
|
|
||||||
apply(plugin = "js-test")
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,136 +0,0 @@
|
|||||||
@file:Suppress("UnstableApiUsage")
|
|
||||||
|
|
||||||
import com.jfrog.bintray.gradle.tasks.BintrayUploadTask
|
|
||||||
import groovy.lang.GroovyObject
|
|
||||||
import org.gradle.api.publish.maven.internal.artifact.FileBasedMavenArtifact
|
|
||||||
import org.jfrog.gradle.plugin.artifactory.dsl.PublisherConfig
|
|
||||||
import org.jfrog.gradle.plugin.artifactory.dsl.ResolverConfig
|
|
||||||
|
|
||||||
// Old bintray.gradle script converted to real Gradle plugin (precompiled script plugin)
|
|
||||||
// It now has own dependencies and support type safe accessors
|
|
||||||
// Syntax is pretty close to what we had in Groovy
|
|
||||||
// (excluding Property.set and bintray dynamic configs)
|
|
||||||
|
|
||||||
plugins {
|
|
||||||
`maven-publish`
|
|
||||||
id("com.jfrog.bintray")
|
|
||||||
id("com.jfrog.artifactory")
|
|
||||||
}
|
|
||||||
|
|
||||||
val vcs = "https://github.com/altavir/dataforge-core"
|
|
||||||
val bintrayRepo = "https://bintray.com/mipt-npm/dataforge"
|
|
||||||
|
|
||||||
// Configure publishing
|
|
||||||
publishing {
|
|
||||||
repositories {
|
|
||||||
maven(bintrayRepo)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Process each publication we have in this project
|
|
||||||
publications.filterIsInstance<MavenPublication>().forEach { publication ->
|
|
||||||
|
|
||||||
// use type safe pom config GSL instead of old dynamic
|
|
||||||
publication.pom {
|
|
||||||
name.set(project.name)
|
|
||||||
description.set(project.description)
|
|
||||||
url.set(vcs)
|
|
||||||
|
|
||||||
licenses {
|
|
||||||
license {
|
|
||||||
name.set("The Apache Software License, Version 2.0")
|
|
||||||
url.set("http://www.apache.org/licenses/LICENSE-2.0.txt")
|
|
||||||
distribution.set("repo")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
developers {
|
|
||||||
developer {
|
|
||||||
id.set("MIPT-NPM")
|
|
||||||
name.set("MIPT nuclear physics methods laboratory")
|
|
||||||
organization.set("MIPT")
|
|
||||||
organizationUrl.set("http://npm.mipt.ru")
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
scm {
|
|
||||||
url.set(vcs)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
bintray {
|
|
||||||
user = findProperty("bintrayUser") as? String ?: System.getenv("BINTRAY_USER")
|
|
||||||
key = findProperty("bintrayApiKey") as? String? ?: System.getenv("BINTRAY_API_KEY")
|
|
||||||
publish = true
|
|
||||||
override = true // for multi-platform Kotlin/Native publishing
|
|
||||||
|
|
||||||
// We have to use delegateClosureOf because bintray supports only dynamic groovy syntax
|
|
||||||
// this is a problem of this plugin
|
|
||||||
pkg.apply {
|
|
||||||
userOrg = "mipt-npm"
|
|
||||||
repo = "dataforge"
|
|
||||||
name = project.name
|
|
||||||
issueTrackerUrl = "$vcs/issues"
|
|
||||||
setLicenses("Apache-2.0")
|
|
||||||
vcsUrl = vcs
|
|
||||||
version.apply {
|
|
||||||
name = project.version.toString()
|
|
||||||
vcsTag = project.version.toString()
|
|
||||||
released = java.util.Date().toString()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//workaround bintray bug
|
|
||||||
afterEvaluate {
|
|
||||||
setPublications(*publishing.publications.names.toTypedArray())
|
|
||||||
}
|
|
||||||
|
|
||||||
tasks {
|
|
||||||
bintrayUpload {
|
|
||||||
dependsOn(publishToMavenLocal)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//workaround for bintray
|
|
||||||
tasks.withType<BintrayUploadTask> {
|
|
||||||
doFirst {
|
|
||||||
publishing.publications
|
|
||||||
.filterIsInstance<MavenPublication>()
|
|
||||||
.forEach { publication ->
|
|
||||||
val moduleFile = buildDir.resolve("publications/${publication.name}/module.json")
|
|
||||||
if (moduleFile.exists()) {
|
|
||||||
publication.artifact(object : FileBasedMavenArtifact(moduleFile) {
|
|
||||||
override fun getDefaultExtension() = "module"
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
artifactory {
|
|
||||||
val artifactoryUser: String? by project
|
|
||||||
val artifactoryPassword: String? by project
|
|
||||||
val artifactoryContextUrl = "http://npm.mipt.ru:8081/artifactory"
|
|
||||||
|
|
||||||
setContextUrl(artifactoryContextUrl)//The base Artifactory URL if not overridden by the publisher/resolver
|
|
||||||
publish(delegateClosureOf<PublisherConfig> {
|
|
||||||
repository(delegateClosureOf<GroovyObject> {
|
|
||||||
setProperty("repoKey", "gradle-dev-local")
|
|
||||||
setProperty("username", artifactoryUser)
|
|
||||||
setProperty("password", artifactoryPassword)
|
|
||||||
})
|
|
||||||
|
|
||||||
defaults(delegateClosureOf<GroovyObject> {
|
|
||||||
invokeMethod("publications", arrayOf("jvm", "js", "kotlinMultiplatform", "metadata"))
|
|
||||||
})
|
|
||||||
})
|
|
||||||
resolve(delegateClosureOf<ResolverConfig> {
|
|
||||||
repository(delegateClosureOf<GroovyObject> {
|
|
||||||
setProperty("repoKey", "gradle-dev")
|
|
||||||
setProperty("username", artifactoryUser)
|
|
||||||
setProperty("password", artifactoryPassword)
|
|
||||||
})
|
|
||||||
})
|
|
||||||
}
|
|
@ -1,5 +1,5 @@
|
|||||||
plugins {
|
plugins {
|
||||||
`npm-multiplatform`
|
id("scientifik.mpp")
|
||||||
}
|
}
|
||||||
|
|
||||||
val dataforgeVersion: String by rootProject.extra
|
val dataforgeVersion: String by rootProject.extra
|
||||||
@ -19,6 +19,7 @@ kotlin {
|
|||||||
}
|
}
|
||||||
val jsMain by getting {
|
val jsMain by getting {
|
||||||
dependencies {
|
dependencies {
|
||||||
|
api("hep.dataforge:dataforge-output-html:$dataforgeVersion")
|
||||||
// api("hep.dataforge:dataforge-output-js:$dataforgeVersion")
|
// api("hep.dataforge:dataforge-output-js:$dataforgeVersion")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,177 @@
|
|||||||
|
package hep.dataforge.vis.common
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Taken from https://github.com/markaren/three.kt/blob/master/threejs-wrapper/src/main/kotlin/info/laht/threekt/math/ColorConstants.kt
|
||||||
|
*/
|
||||||
|
object Colors {
|
||||||
|
const val aliceblue = 0xF0F8FF
|
||||||
|
const val antiquewhite = 0xFAEBD7
|
||||||
|
const val aqua = 0x00FFFF
|
||||||
|
const val aquamarine = 0x7FFFD4
|
||||||
|
const val azure = 0xF0FFFF
|
||||||
|
|
||||||
|
const val beige = 0xF5F5DC
|
||||||
|
const val bisque = 0xFFE4C4
|
||||||
|
const val black = 0x000000
|
||||||
|
const val blanchedalmond = 0xFFEBCD
|
||||||
|
const val blue = 0x0000FF
|
||||||
|
const val blueviolet = 0x8A2BE2
|
||||||
|
|
||||||
|
const val brown = 0xA52A2A
|
||||||
|
const val burlywood = 0xDEB887
|
||||||
|
const val cadetblue = 0x5F9EA0
|
||||||
|
const val chartreuse = 0x7FFF00
|
||||||
|
const val chocolate = 0xD2691E
|
||||||
|
const val coral = 0xFF7F50
|
||||||
|
|
||||||
|
const val cornflowerblue = 0x6495ED
|
||||||
|
const val cornsilk = 0xFFF8DC
|
||||||
|
const val crimson = 0xDC143C
|
||||||
|
const val cyan = 0x00FFFF
|
||||||
|
const val darkblue = 0x00008B
|
||||||
|
const val darkcyan = 0x008B8B
|
||||||
|
|
||||||
|
const val darkgoldenrod = 0xB8860B
|
||||||
|
const val darkgray = 0xA9A9A9
|
||||||
|
const val darkgreen = 0x006400
|
||||||
|
const val darkgrey = 0xA9A9A9
|
||||||
|
const val darkkhaki = 0xBDB76B
|
||||||
|
const val darkmagenta = 0x8B008B
|
||||||
|
|
||||||
|
const val darkolivegreen = 0x556B2F
|
||||||
|
const val darkorange = 0xFF8C00
|
||||||
|
const val darkorchid = 0x9932CC
|
||||||
|
const val darkred = 0x8B0000
|
||||||
|
const val darksalmon = 0xE9967A
|
||||||
|
const val darkseagreen = 0x8FBC8F
|
||||||
|
|
||||||
|
const val darkslateblue = 0x483D8B
|
||||||
|
const val darkslategray = 0x2F4F4F
|
||||||
|
const val darkslategrey = 0x2F4F4F
|
||||||
|
const val darkturquoise = 0x00CED1
|
||||||
|
const val darkviolet = 0x9400D3
|
||||||
|
|
||||||
|
const val deeppink = 0xFF1493
|
||||||
|
const val deepskyblue = 0x00BFFF
|
||||||
|
const val dimgray = 0x696969
|
||||||
|
const val dimgrey = 0x696969
|
||||||
|
const val dodgerblue = 0x1E90FF
|
||||||
|
const val firebrick = 0xB22222
|
||||||
|
|
||||||
|
const val floralwhite = 0xFFFAF0
|
||||||
|
const val forestgreen = 0x228B22
|
||||||
|
const val fuchsia = 0xFF00FF
|
||||||
|
const val gainsboro = 0xDCDCDC
|
||||||
|
const val ghostwhite = 0xF8F8FF
|
||||||
|
const val gold = 0xFFD700
|
||||||
|
|
||||||
|
const val goldenrod = 0xDAA520
|
||||||
|
const val gray = 0x808080
|
||||||
|
const val green = 0x008000
|
||||||
|
const val greenyellow = 0xADFF2F
|
||||||
|
const val grey = 0x808080
|
||||||
|
const val honeydew = 0xF0FFF0
|
||||||
|
const val hotpink = 0xFF69B4
|
||||||
|
|
||||||
|
const val indianred = 0xCD5C5C
|
||||||
|
const val indigo = 0x4B0082
|
||||||
|
const val ivory = 0xFFFFF0
|
||||||
|
const val khaki = 0xF0E68C
|
||||||
|
const val lavender = 0xE6E6FA
|
||||||
|
const val lavenderblush = 0xFFF0F5
|
||||||
|
const val lawngreen = 0x7CFC00
|
||||||
|
|
||||||
|
const val lemonchiffon = 0xFFFACD
|
||||||
|
const val lightblue = 0xADD8E6
|
||||||
|
const val lightcoral = 0xF08080
|
||||||
|
const val lightcyan = 0xE0FFFF
|
||||||
|
const val lightgoldenrodyellow = 0xFAFAD2
|
||||||
|
const val lightgray = 0xD3D3D3
|
||||||
|
|
||||||
|
const val lightgreen = 0x90EE90
|
||||||
|
const val lightgrey = 0xD3D3D3
|
||||||
|
const val lightpink = 0xFFB6C1
|
||||||
|
const val lightsalmon = 0xFFA07A
|
||||||
|
const val lightseagreen = 0x20B2AA
|
||||||
|
const val lightskyblue = 0x87CEFA
|
||||||
|
|
||||||
|
const val lightslategray = 0x778899
|
||||||
|
const val lightslategrey = 0x778899
|
||||||
|
const val lightsteelblue = 0xB0C4DE
|
||||||
|
const val lightyellow = 0xFFFFE0
|
||||||
|
const val lime = 0x00FF00
|
||||||
|
const val limegreen = 0x32CD32
|
||||||
|
|
||||||
|
const val linen = 0xFAF0E6
|
||||||
|
const val magenta = 0xFF00FF
|
||||||
|
const val maroon = 0x800000
|
||||||
|
const val mediumaquamarine = 0x66CDAA
|
||||||
|
const val mediumblue = 0x0000CD
|
||||||
|
const val mediumorchid = 0xBA55D3
|
||||||
|
|
||||||
|
const val mediumpurple = 0x9370DB
|
||||||
|
const val mediumseagreen = 0x3CB371
|
||||||
|
const val mediumslateblue = 0x7B68EE
|
||||||
|
const val mediumspringgreen = 0x00FA9A
|
||||||
|
const val mediumturquoise = 0x48D1CC
|
||||||
|
|
||||||
|
const val mediumvioletred = 0xC71585
|
||||||
|
const val midnightblue = 0x191970
|
||||||
|
const val mintcream = 0xF5FFFA
|
||||||
|
const val mistyrose = 0xFFE4E1
|
||||||
|
const val moccasin = 0xFFE4B5
|
||||||
|
const val navajowhite = 0xFFDEAD
|
||||||
|
|
||||||
|
const val navy = 0x000080
|
||||||
|
const val oldlace = 0xFDF5E6
|
||||||
|
const val olive = 0x808000
|
||||||
|
const val olivedrab = 0x6B8E23
|
||||||
|
const val orange = 0xFFA500
|
||||||
|
const val orangered = 0xFF4500
|
||||||
|
const val orchid = 0xDA70D6
|
||||||
|
|
||||||
|
const val palegoldenrod = 0xEEE8AA
|
||||||
|
const val palegreen = 0x98FB98
|
||||||
|
const val paleturquoise = 0xAFEEEE
|
||||||
|
const val palevioletred = 0xDB7093
|
||||||
|
const val papayawhip = 0xFFEFD5
|
||||||
|
const val peachpuff = 0xFFDAB9
|
||||||
|
const val peru = 0xCD853F
|
||||||
|
const val pink = 0xFFC0CB
|
||||||
|
const val plum = 0xDDA0DD
|
||||||
|
const val powderblue = 0xB0E0E6
|
||||||
|
const val purple = 0x800080
|
||||||
|
const val rebeccapurple = 0x663399
|
||||||
|
const val red = 0xFF0000
|
||||||
|
const val rosybrown = 0xBC8F8F
|
||||||
|
|
||||||
|
const val royalblue = 0x4169E1
|
||||||
|
const val saddlebrown = 0x8B4513
|
||||||
|
const val salmon = 0xFA8072
|
||||||
|
const val sandybrown = 0xF4A460
|
||||||
|
const val seagreen = 0x2E8B57
|
||||||
|
const val seashell = 0xFFF5EE
|
||||||
|
|
||||||
|
const val sienna = 0xA0522D
|
||||||
|
const val silver = 0xC0C0C0
|
||||||
|
const val skyblue = 0x87CEEB
|
||||||
|
const val slateblue = 0x6A5ACD
|
||||||
|
const val slategray = 0x708090
|
||||||
|
const val slategrey = 0x708090
|
||||||
|
const val snow = 0xFFFAFA
|
||||||
|
|
||||||
|
const val springgreen = 0x00FF7F
|
||||||
|
const val steelblue = 0x4682B4
|
||||||
|
const val tan = 0xD2B48C
|
||||||
|
const val teal = 0x008080
|
||||||
|
const val thistle = 0xD8BFD8
|
||||||
|
const val tomato = 0xFF6347
|
||||||
|
const val turquoise = 0x40E0D0
|
||||||
|
|
||||||
|
const val violet = 0xEE82EE
|
||||||
|
const val wheat = 0xF5DEB3
|
||||||
|
const val white = 0xFFFFFF
|
||||||
|
const val whitesmoke = 0xF5F5F5
|
||||||
|
const val yellow = 0xFFFF00
|
||||||
|
const val yellowgreen = 0x9ACD32
|
||||||
|
}
|
@ -2,7 +2,7 @@ import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
|
|||||||
import org.openjfx.gradle.JavaFXOptions
|
import org.openjfx.gradle.JavaFXOptions
|
||||||
|
|
||||||
plugins {
|
plugins {
|
||||||
kotlin("jvm")
|
kotlin("jvm")
|
||||||
id("org.openjfx.javafxplugin")
|
id("org.openjfx.javafxplugin")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,70 +0,0 @@
|
|||||||
import org.jetbrains.kotlin.gradle.frontend.KotlinFrontendExtension
|
|
||||||
import org.jetbrains.kotlin.gradle.frontend.npm.NpmExtension
|
|
||||||
import org.jetbrains.kotlin.gradle.frontend.webpack.WebPackExtension
|
|
||||||
import org.jetbrains.kotlin.gradle.tasks.Kotlin2JsCompile
|
|
||||||
|
|
||||||
plugins {
|
|
||||||
id("kotlin2js")
|
|
||||||
id("kotlin-dce-js")
|
|
||||||
id("org.jetbrains.kotlin.frontend")
|
|
||||||
}
|
|
||||||
|
|
||||||
repositories {
|
|
||||||
maven("https://kotlin.bintray.com/kotlin-js-wrappers")
|
|
||||||
}
|
|
||||||
|
|
||||||
val kotlinVersion: String by rootProject.extra
|
|
||||||
|
|
||||||
dependencies {
|
|
||||||
implementation(kotlin("stdlib-js"))
|
|
||||||
implementation(project(":dataforge-vis-common"))
|
|
||||||
implementation("org.jetbrains:kotlin-react:16.6.0-pre.73-kotlin-1.3.40")
|
|
||||||
implementation("org.jetbrains:kotlin-react-dom:16.6.0-pre.73-kotlin-1.3.40")
|
|
||||||
testCompile(kotlin("test-js"))
|
|
||||||
}
|
|
||||||
|
|
||||||
configure<KotlinFrontendExtension> {
|
|
||||||
downloadNodeJsVersion = "latest"
|
|
||||||
|
|
||||||
configure<NpmExtension> {
|
|
||||||
dependency("core-js", "3.1.4")
|
|
||||||
dependency("cp-react-tree-table","1.0.0-beta.6")
|
|
||||||
dependency("react")
|
|
||||||
dependency("react-dom")
|
|
||||||
devDependency("karma")
|
|
||||||
}
|
|
||||||
|
|
||||||
sourceMaps = true
|
|
||||||
|
|
||||||
bundle<WebPackExtension>("webpack") {
|
|
||||||
this as WebPackExtension
|
|
||||||
bundleName = "main"
|
|
||||||
contentPath = file("src/main/web")
|
|
||||||
sourceMapEnabled = true
|
|
||||||
//mode = "production"
|
|
||||||
mode = "development"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
tasks {
|
|
||||||
"compileKotlin2Js"(Kotlin2JsCompile::class) {
|
|
||||||
kotlinOptions {
|
|
||||||
metaInfo = true
|
|
||||||
outputFile = "${project.buildDir.path}/js/${project.name}.js"
|
|
||||||
sourceMap = true
|
|
||||||
moduleKind = "commonjs"
|
|
||||||
main = "call"
|
|
||||||
kotlinOptions.sourceMapEmbedSources = "always"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
"compileTestKotlin2Js"(Kotlin2JsCompile::class) {
|
|
||||||
kotlinOptions {
|
|
||||||
metaInfo = true
|
|
||||||
outputFile = "${project.buildDir.path}/js/${project.name}-test.js"
|
|
||||||
sourceMap = true
|
|
||||||
moduleKind = "commonjs"
|
|
||||||
kotlinOptions.sourceMapEmbedSources = "always"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,19 +0,0 @@
|
|||||||
package hep.dataforge.vis.js.tree
|
|
||||||
|
|
||||||
import react.RBuilder
|
|
||||||
import react.RComponent
|
|
||||||
import react.RProps
|
|
||||||
import react.RState
|
|
||||||
|
|
||||||
class MetaEditorState : RState {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
class MetaEditorProps : RProps
|
|
||||||
|
|
||||||
class MetaEditor(props: MetaEditorProps) : RComponent<MetaEditorProps, MetaEditorState>(props) {
|
|
||||||
override fun RBuilder.render() {
|
|
||||||
//this.
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,85 +0,0 @@
|
|||||||
@file:JsModule("cp-react-tree-table")
|
|
||||||
@file:JsNonModule
|
|
||||||
|
|
||||||
package hep.dataforge.vis.js.tree
|
|
||||||
|
|
||||||
import react.Component
|
|
||||||
|
|
||||||
external interface RowMetadata {
|
|
||||||
var depth: Number
|
|
||||||
var index: Number
|
|
||||||
var height: Number
|
|
||||||
var hasChildren: Boolean
|
|
||||||
}
|
|
||||||
|
|
||||||
external interface RowState {
|
|
||||||
var isVisible: Boolean
|
|
||||||
var top: Number
|
|
||||||
}
|
|
||||||
|
|
||||||
open external class RowModel(data: RowData, metadata: RowMetadata, state: RowState) {
|
|
||||||
var data: RowData
|
|
||||||
var metadata: RowMetadata
|
|
||||||
var `$state`: RowState
|
|
||||||
|
|
||||||
companion object {
|
|
||||||
var DEFAULT_HEIGHT: Number
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
external interface RowAPI {
|
|
||||||
var toggleChildren: () -> Unit
|
|
||||||
var updateData: (newData: RowData) -> Unit
|
|
||||||
}
|
|
||||||
|
|
||||||
external class Row(model: RowModel, api: RowAPI) : RowModel, RowAPI {
|
|
||||||
override var toggleChildren: () -> Unit
|
|
||||||
override var updateData: (newData: RowData) -> Unit
|
|
||||||
}
|
|
||||||
|
|
||||||
external class Column : Component<ColumnProps, dynamic> {
|
|
||||||
override fun render(): dynamic
|
|
||||||
|
|
||||||
companion object {
|
|
||||||
var displayName: String
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
external interface TreeNode {
|
|
||||||
val data: Any
|
|
||||||
val children: Array<TreeNode>?
|
|
||||||
val height: Number?
|
|
||||||
}
|
|
||||||
|
|
||||||
external class TreeState(data: Array<RowModel>) {
|
|
||||||
var data: Array<RowModel>
|
|
||||||
var height: Number
|
|
||||||
var hasData: Boolean
|
|
||||||
fun findRowModel(node: TreeNode): RowModel?
|
|
||||||
fun indexAtYPos(yPos: Number): Number
|
|
||||||
fun yPosAtIndex(index: Number): Number
|
|
||||||
|
|
||||||
companion object {
|
|
||||||
fun create(data: Array<TreeNode>): TreeState
|
|
||||||
fun createEmpty(): TreeState
|
|
||||||
fun sliceRows(source: TreeState, from: Number, to: Number): Array<RowModel>
|
|
||||||
var _hideRowsInRange: Any
|
|
||||||
var _showRowsInRange: Any
|
|
||||||
fun expandAll(source: TreeState, depthLimit: Number? = definedExternally /* null */): TreeState
|
|
||||||
fun collapseAll(source: TreeState): TreeState
|
|
||||||
fun expandAncestors(source: TreeState, model: RowModel): TreeState
|
|
||||||
fun toggleChildren(source: TreeState, model: RowModel): TreeState
|
|
||||||
fun updateData(source: TreeState, model: RowModel, newData: RowData): TreeState
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
external class TreeTable : Component<TreeTableProps, dynamic> {
|
|
||||||
var vListRef: Any
|
|
||||||
override fun render(): dynamic
|
|
||||||
var handleChange: Any
|
|
||||||
fun scrollTo(posY: Number): Unit
|
|
||||||
|
|
||||||
companion object {
|
|
||||||
val Column: Column
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,19 +0,0 @@
|
|||||||
package hep.dataforge.vis.js.tree.demo
|
|
||||||
|
|
||||||
external val module: Module
|
|
||||||
|
|
||||||
external interface Module {
|
|
||||||
val hot: Hot?
|
|
||||||
}
|
|
||||||
|
|
||||||
external interface Hot {
|
|
||||||
val data: dynamic
|
|
||||||
|
|
||||||
fun accept()
|
|
||||||
fun accept(dependency: String, callback: () -> Unit)
|
|
||||||
fun accept(dependencies: Array<String>, callback: (updated: Array<String>) -> Unit)
|
|
||||||
|
|
||||||
fun dispose(callback: (data: dynamic) -> Unit)
|
|
||||||
}
|
|
||||||
|
|
||||||
external fun require(name: String): dynamic
|
|
@ -1,54 +0,0 @@
|
|||||||
package hep.dataforge.vis.js.tree.demo
|
|
||||||
|
|
||||||
import hep.dataforge.vis.js.tree.ApplicationBase
|
|
||||||
import hep.dataforge.vis.js.tree.TreeTable
|
|
||||||
import hep.dataforge.vis.js.tree.column
|
|
||||||
import hep.dataforge.vis.js.tree.tree
|
|
||||||
import react.dom.render
|
|
||||||
import react.dom.span
|
|
||||||
import kotlin.browser.document
|
|
||||||
|
|
||||||
|
|
||||||
data class TableData(val name: String, val col1: String, val col2: Int)
|
|
||||||
|
|
||||||
class TreeDemoApp : ApplicationBase() {
|
|
||||||
|
|
||||||
override val stateKeys: List<String> = emptyList()
|
|
||||||
|
|
||||||
override fun start(state: Map<String, Any>) {
|
|
||||||
|
|
||||||
println("Starting application")
|
|
||||||
val element = document.getElementById("demo")!!
|
|
||||||
|
|
||||||
println("Started application")
|
|
||||||
|
|
||||||
println("${TreeTable::class} is loaded")
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
render(element) {
|
|
||||||
child(TreeTable::class) {
|
|
||||||
attrs {
|
|
||||||
tree<TableData> {
|
|
||||||
child(TableData("aaa", "bbb", 2))
|
|
||||||
child(TableData("ccc", "ddd", 66)) {
|
|
||||||
child(TableData("ddd", "ggg", 22))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
onScroll = {}
|
|
||||||
}
|
|
||||||
column<TableData>("title"){
|
|
||||||
span { +(it.data as TableData).name }
|
|
||||||
}
|
|
||||||
column<TableData>("col1"){
|
|
||||||
span { +(it.data as TableData).col1 }
|
|
||||||
}
|
|
||||||
column<TableData>("col2"){
|
|
||||||
span { +(it.data as TableData).col2 }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun dispose() = emptyMap<String, Any>()//mapOf("lines" to presenter.dispose())
|
|
||||||
}
|
|
@ -1,52 +0,0 @@
|
|||||||
package hep.dataforge.vis.js.tree
|
|
||||||
|
|
||||||
import hep.dataforge.vis.js.tree.demo.TreeDemoApp
|
|
||||||
import hep.dataforge.vis.js.tree.demo.module
|
|
||||||
import kotlin.browser.document
|
|
||||||
import kotlin.dom.hasClass
|
|
||||||
|
|
||||||
|
|
||||||
abstract class ApplicationBase {
|
|
||||||
abstract val stateKeys: List<String>
|
|
||||||
|
|
||||||
abstract fun start(state: Map<String, Any>)
|
|
||||||
abstract fun dispose(): Map<String, Any>
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
fun main() {
|
|
||||||
var application: ApplicationBase? = null
|
|
||||||
|
|
||||||
val state: dynamic = module.hot?.let { hot ->
|
|
||||||
hot.accept()
|
|
||||||
|
|
||||||
hot.dispose { data ->
|
|
||||||
data.appState = application?.dispose()
|
|
||||||
application = null
|
|
||||||
}
|
|
||||||
|
|
||||||
hot.data
|
|
||||||
}
|
|
||||||
|
|
||||||
if (document.body != null) {
|
|
||||||
application = start(state)
|
|
||||||
} else {
|
|
||||||
application = null
|
|
||||||
document.addEventListener("DOMContentLoaded", {
|
|
||||||
application = start(state) }
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fun start(state: dynamic): ApplicationBase? {
|
|
||||||
return if (document.body?.hasClass("testApp") == true) {
|
|
||||||
val application = TreeDemoApp()
|
|
||||||
|
|
||||||
@Suppress("UnsafeCastFromDynamic")
|
|
||||||
application.start(state?.appState ?: emptyMap<String, Any>())
|
|
||||||
|
|
||||||
application
|
|
||||||
} else {
|
|
||||||
null
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,25 +0,0 @@
|
|||||||
package hep.dataforge.vis.js.tree
|
|
||||||
|
|
||||||
import react.RProps
|
|
||||||
import react.ReactElement
|
|
||||||
|
|
||||||
class ColumnProps(
|
|
||||||
var renderCell: (row: Row) -> ReactElement,
|
|
||||||
var renderHeaderCell: () -> ReactElement,
|
|
||||||
var grow: Number? = null,
|
|
||||||
var basis: String? = null // <CSS size> | auto
|
|
||||||
) : RProps
|
|
||||||
|
|
||||||
class TreeTableProps(
|
|
||||||
// Model properties
|
|
||||||
var value: TreeState,
|
|
||||||
var children: Array<ReactElement>,
|
|
||||||
var onChange: ((TreeState) -> Unit)? = null,
|
|
||||||
// View callbacks
|
|
||||||
var onScroll: ((scrollTop: Number) -> Unit)? = null,
|
|
||||||
|
|
||||||
// View properties
|
|
||||||
var height: Number? = null, // view height (px)
|
|
||||||
var headerHeight: Number? = null, // header height (px)
|
|
||||||
var className: String? = null
|
|
||||||
) : RProps
|
|
@ -1,49 +0,0 @@
|
|||||||
package hep.dataforge.vis.js.tree
|
|
||||||
|
|
||||||
import react.RElementBuilder
|
|
||||||
import react.ReactElement
|
|
||||||
import react.createElement
|
|
||||||
import react.dom.span
|
|
||||||
|
|
||||||
typealias RowData = Any
|
|
||||||
|
|
||||||
class TreeNodeBuilder<D : Any>(override val data: D, override var height: Number? = null) : TreeNode {
|
|
||||||
private val _children = ArrayList<TreeNodeBuilder<D>>()
|
|
||||||
override val children: Array<TreeNode> get() = _children.toTypedArray()
|
|
||||||
|
|
||||||
fun child(data: D, block: TreeNodeBuilder<D>.() -> Unit = {}) {
|
|
||||||
val child = TreeNodeBuilder(data).apply(block)
|
|
||||||
_children.add(child)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
class TreeTableBuilder<D : Any> {
|
|
||||||
private val children = ArrayList<TreeNode>()
|
|
||||||
|
|
||||||
fun child(data: D, height: Number? = null, block: TreeNodeBuilder<D>.() -> Unit = {}) {
|
|
||||||
this.children.add(TreeNodeBuilder(data, height).apply(block))
|
|
||||||
}
|
|
||||||
|
|
||||||
fun build(): TreeState = TreeState.create(children.toTypedArray())
|
|
||||||
}
|
|
||||||
|
|
||||||
fun <D : Any> TreeState.Companion.build(block: TreeTableBuilder<D>.() -> Unit): TreeState {
|
|
||||||
return TreeTableBuilder<D>().apply(block).build()
|
|
||||||
}
|
|
||||||
|
|
||||||
fun <D : Any> TreeTableProps.tree(block: TreeTableBuilder<D>.() -> Unit) {
|
|
||||||
value = TreeTableBuilder<D>().apply(block).build()
|
|
||||||
}
|
|
||||||
|
|
||||||
fun <D : Any> RElementBuilder<TreeTableProps>.column(
|
|
||||||
name: String,
|
|
||||||
renderer: (Row) -> ReactElement
|
|
||||||
): ReactElement {
|
|
||||||
val props = ColumnProps(
|
|
||||||
renderHeaderCell = { span { +name } },
|
|
||||||
renderCell = { row -> renderer.invoke(row) }
|
|
||||||
)
|
|
||||||
return createElement(TreeTable.Column, props = props)
|
|
||||||
}
|
|
||||||
|
|
@ -1,11 +0,0 @@
|
|||||||
<!DOCTYPE html>
|
|
||||||
<html>
|
|
||||||
<head>
|
|
||||||
<title>Three js demo for tree</title>
|
|
||||||
<script type="text/javascript" src="main.bundle.js"></script>
|
|
||||||
</head>
|
|
||||||
<body class="testApp">
|
|
||||||
<h1>Tree demo</h1>
|
|
||||||
<div id="demo"></div>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
@ -14,6 +14,7 @@ val kotlinVersion: String by rootProject.extra
|
|||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
implementation(project(":dataforge-vis-spatial"))
|
implementation(project(":dataforge-vis-spatial"))
|
||||||
|
//implementation("ch.viseon.threejs:wrapper:105.0.0")
|
||||||
implementation("info.laht.threekt:threejs-wrapper:0.88-npm-2")
|
implementation("info.laht.threekt:threejs-wrapper:0.88-npm-2")
|
||||||
testCompile(kotlin("test-js"))
|
testCompile(kotlin("test-js"))
|
||||||
}
|
}
|
||||||
|
@ -5,14 +5,15 @@ import hep.dataforge.meta.double
|
|||||||
import hep.dataforge.meta.get
|
import hep.dataforge.meta.get
|
||||||
import hep.dataforge.meta.int
|
import hep.dataforge.meta.int
|
||||||
import hep.dataforge.values.ValueType
|
import hep.dataforge.values.ValueType
|
||||||
|
import hep.dataforge.vis.common.Colors
|
||||||
import info.laht.threekt.materials.Material
|
import info.laht.threekt.materials.Material
|
||||||
import info.laht.threekt.materials.MeshPhongMaterial
|
import info.laht.threekt.materials.MeshPhongMaterial
|
||||||
import info.laht.threekt.math.Color
|
import info.laht.threekt.math.Color
|
||||||
import info.laht.threekt.math.ColorConstants
|
|
||||||
|
|
||||||
object Materials {
|
object Materials {
|
||||||
val DEFAULT = MeshPhongMaterial().apply {
|
val DEFAULT = MeshPhongMaterial().apply {
|
||||||
this.color.set(ColorConstants.darkgreen)
|
this.color.set(Colors.darkgreen)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,98 +0,0 @@
|
|||||||
package hep.dataforge.vis.spatial
|
|
||||||
|
|
||||||
import hep.dataforge.context.Global
|
|
||||||
import hep.dataforge.meta.number
|
|
||||||
import hep.dataforge.vis.ApplicationBase
|
|
||||||
import hep.dataforge.vis.common.DisplayGroup
|
|
||||||
import hep.dataforge.vis.require
|
|
||||||
import hep.dataforge.vis.spatial.jsroot.JSRootPlugin
|
|
||||||
import hep.dataforge.vis.spatial.jsroot.jsRootGeometry
|
|
||||||
|
|
||||||
import kotlinx.coroutines.GlobalScope
|
|
||||||
import kotlinx.coroutines.delay
|
|
||||||
import kotlinx.coroutines.isActive
|
|
||||||
import kotlinx.coroutines.launch
|
|
||||||
import kotlin.browser.document
|
|
||||||
import kotlin.random.Random
|
|
||||||
|
|
||||||
|
|
||||||
class ThreeDemoApp : ApplicationBase() {
|
|
||||||
|
|
||||||
override val stateKeys: List<String> = emptyList()
|
|
||||||
|
|
||||||
override fun start(state: Map<String, Any>) {
|
|
||||||
require("JSRootGeoBase.js")
|
|
||||||
|
|
||||||
|
|
||||||
//TODO remove after DI fix
|
|
||||||
// Global.plugins.load(ThreePlugin())
|
|
||||||
// Global.plugins.load(JSRootPlugin())
|
|
||||||
|
|
||||||
Global.plugins.load(JSRootPlugin)
|
|
||||||
|
|
||||||
val renderer = ThreeOutput(Global)
|
|
||||||
renderer.start(document.getElementById("canvas")!!)
|
|
||||||
println("started")
|
|
||||||
|
|
||||||
lateinit var group: DisplayGroup
|
|
||||||
|
|
||||||
renderer.render {
|
|
||||||
group = group {
|
|
||||||
box {
|
|
||||||
z = 110.0
|
|
||||||
xSize = 100.0
|
|
||||||
ySize = 100.0
|
|
||||||
zSize = 100.0
|
|
||||||
}
|
|
||||||
box {
|
|
||||||
visible = false
|
|
||||||
x = 110.0
|
|
||||||
xSize = 100.0
|
|
||||||
ySize = 100.0
|
|
||||||
zSize = 100.0
|
|
||||||
color(1530)
|
|
||||||
|
|
||||||
GlobalScope.launch {
|
|
||||||
while (isActive) {
|
|
||||||
delay(500)
|
|
||||||
visible = !visible
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
convex {
|
|
||||||
point(50, 50, 50)
|
|
||||||
point(-50, -50, 50)
|
|
||||||
point(-50, 50, -50)
|
|
||||||
point(50, -50, -50)
|
|
||||||
}
|
|
||||||
jsRootGeometry {
|
|
||||||
y = 110.0
|
|
||||||
shape = box(50, 50, 50)
|
|
||||||
color(12285)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var color by group.properties.number(1530).int
|
|
||||||
|
|
||||||
GlobalScope.launch {
|
|
||||||
val random = Random(111)
|
|
||||||
while (isActive) {
|
|
||||||
delay(1000)
|
|
||||||
color = random.nextInt(0, Int.MAX_VALUE)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// view.animate()
|
|
||||||
|
|
||||||
// view = WebLinesView(document.getElementById("lines")!!, document.getElementById("addForm")!!)
|
|
||||||
// presenter = LinesPresenter(view)
|
|
||||||
//
|
|
||||||
// state["lines"]?.let { linesState ->
|
|
||||||
// @Suppress("UNCHECKED_CAST")
|
|
||||||
// presenter.restore(linesState as Array<String>)
|
|
||||||
// }
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun dispose() = emptyMap<String, Any>()//mapOf("lines" to presenter.dispose())
|
|
||||||
}
|
|
@ -11,6 +11,7 @@ import hep.dataforge.vis.spatial.ThreeFactory.Companion.updateMesh
|
|||||||
import hep.dataforge.vis.spatial.three.ConvexBufferGeometry
|
import hep.dataforge.vis.spatial.three.ConvexBufferGeometry
|
||||||
import hep.dataforge.vis.spatial.three.EdgesGeometry
|
import hep.dataforge.vis.spatial.three.EdgesGeometry
|
||||||
import hep.dataforge.vis.spatial.three.euler
|
import hep.dataforge.vis.spatial.three.euler
|
||||||
|
import hep.dataforge.vis.spatial.three.toBufferGeometry
|
||||||
import info.laht.threekt.core.BufferGeometry
|
import info.laht.threekt.core.BufferGeometry
|
||||||
import info.laht.threekt.core.Object3D
|
import info.laht.threekt.core.Object3D
|
||||||
import info.laht.threekt.geometries.BoxBufferGeometry
|
import info.laht.threekt.geometries.BoxBufferGeometry
|
||||||
@ -68,6 +69,14 @@ interface ThreeFactory<T : DisplayObject> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
operator fun <T : DisplayObject> ThreeFactory<T>.invoke(obj: Any): Object3D {
|
||||||
|
if (type.isInstance(obj)) {
|
||||||
|
return invoke(obj as T)
|
||||||
|
} else {
|
||||||
|
error("The object of type ${obj::class} could not be rendered by this factory")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
abstract class MeshThreeFactory<T : DisplayObject>(override val type: KClass<out T>) : ThreeFactory<T> {
|
abstract class MeshThreeFactory<T : DisplayObject>(override val type: KClass<out T>) : ThreeFactory<T> {
|
||||||
/**
|
/**
|
||||||
* Build an object
|
* Build an object
|
||||||
@ -90,6 +99,17 @@ abstract class MeshThreeFactory<T : DisplayObject>(override val type: KClass<out
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generic factory for elements which provide inside geometry builder
|
||||||
|
*/
|
||||||
|
object ThreeShapeFactory : MeshThreeFactory<Shape>(Shape::class) {
|
||||||
|
override fun buildGeometry(obj: Shape): BufferGeometry {
|
||||||
|
return obj.run {
|
||||||
|
ThreeGeometryBuilder().apply { buildGeometry() }.build()
|
||||||
|
}.toBufferGeometry()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
object ThreeBoxFactory : MeshThreeFactory<Box>(Box::class) {
|
object ThreeBoxFactory : MeshThreeFactory<Box>(Box::class) {
|
||||||
override fun buildGeometry(obj: Box) =
|
override fun buildGeometry(obj: Box) =
|
||||||
BoxBufferGeometry(obj.xSize, obj.ySize, obj.zSize)
|
BoxBufferGeometry(obj.xSize, obj.ySize, obj.zSize)
|
||||||
|
@ -0,0 +1,47 @@
|
|||||||
|
package hep.dataforge.vis.spatial
|
||||||
|
|
||||||
|
import hep.dataforge.meta.Meta
|
||||||
|
import hep.dataforge.meta.get
|
||||||
|
import hep.dataforge.meta.int
|
||||||
|
import info.laht.threekt.core.Face3
|
||||||
|
import info.laht.threekt.core.Geometry
|
||||||
|
import info.laht.threekt.math.Color
|
||||||
|
import info.laht.threekt.math.Vector3
|
||||||
|
|
||||||
|
class ThreeGeometryBuilder : GeometryBuilder<Geometry> {
|
||||||
|
|
||||||
|
private val vertices = ArrayList<Point3D>()
|
||||||
|
private val faces = ArrayList<Face3>()
|
||||||
|
|
||||||
|
private fun append(vertex: Point3D): Int {
|
||||||
|
val index = vertices.indexOf(vertex)
|
||||||
|
return if (index > 0) {
|
||||||
|
index
|
||||||
|
} else {
|
||||||
|
vertices.add(vertex)
|
||||||
|
vertices.size - 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun face(vertex1: Point3D, vertex2: Point3D, vertex3: Point3D, normal: Point3D?, meta: Meta) {
|
||||||
|
val materialIndex = meta["materialIndex"].int ?: 0
|
||||||
|
val color = meta["color"]?.color() ?: Color()
|
||||||
|
faces.add(
|
||||||
|
Face3(
|
||||||
|
append(vertex1),
|
||||||
|
append(vertex2),
|
||||||
|
append(vertex3),
|
||||||
|
normal?.asVector() ?: Vector3(0, 0, 0),
|
||||||
|
color,
|
||||||
|
materialIndex
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun build(): Geometry {
|
||||||
|
return Geometry().apply {
|
||||||
|
vertices = this@ThreeGeometryBuilder.vertices.map { it.asVector() }.toTypedArray()
|
||||||
|
faces = this@ThreeGeometryBuilder.faces.toTypedArray()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -11,114 +11,89 @@ import info.laht.threekt.WebGLRenderer
|
|||||||
import info.laht.threekt.cameras.PerspectiveCamera
|
import info.laht.threekt.cameras.PerspectiveCamera
|
||||||
import info.laht.threekt.core.Object3D
|
import info.laht.threekt.core.Object3D
|
||||||
import info.laht.threekt.external.controls.OrbitControls
|
import info.laht.threekt.external.controls.OrbitControls
|
||||||
|
import info.laht.threekt.helpers.AxesHelper
|
||||||
import info.laht.threekt.lights.AmbientLight
|
import info.laht.threekt.lights.AmbientLight
|
||||||
import info.laht.threekt.math.ColorConstants
|
import info.laht.threekt.math.ColorConstants
|
||||||
import info.laht.threekt.scenes.Scene
|
import info.laht.threekt.scenes.Scene
|
||||||
import org.w3c.dom.Element
|
import org.w3c.dom.Element
|
||||||
import kotlin.browser.window
|
import kotlin.browser.window
|
||||||
import kotlin.reflect.KClass
|
|
||||||
|
|
||||||
class ThreeOutput(override val context: Context, val meta: Meta = EmptyMeta) : Output<DisplayObject> {
|
class ThreeOutput(override val context: Context, val meta: Meta = EmptyMeta) : Output<DisplayObject> {
|
||||||
|
|
||||||
private val renderer = WebGLRenderer { antialias = true }.apply {
|
private val aspectRatio by meta.number(1.0).double
|
||||||
setClearColor(ColorConstants.skyblue, 1)
|
|
||||||
setSize(window.innerWidth, window.innerHeight)
|
|
||||||
}
|
|
||||||
|
|
||||||
val scene: Scene = Scene().apply {
|
val scene: Scene = Scene().apply {
|
||||||
add(AmbientLight())
|
add(AmbientLight())
|
||||||
|
if (meta["axis"] != null) {
|
||||||
|
val axesHelper = AxesHelper(meta["axis.size"].int ?: 1)
|
||||||
|
add(axesHelper)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
val camera = PerspectiveCamera(
|
val camera = PerspectiveCamera(
|
||||||
meta["fov"].int ?: 75,
|
meta["camera.fov"].int ?: 75,
|
||||||
window.innerWidth.toDouble() / window.innerHeight,
|
aspectRatio,
|
||||||
meta["camera.nearClip"].double?: World.CAMERA_NEAR_CLIP,
|
meta["camera.nearClip"].double ?: World.CAMERA_NEAR_CLIP,
|
||||||
meta["camera.farClip"].double?: World.CAMERA_FAR_CLIP
|
meta["camera.farClip"].double ?: World.CAMERA_FAR_CLIP
|
||||||
).apply {
|
).apply {
|
||||||
position.setZ(World.CAMERA_INITIAL_DISTANCE)
|
position.setZ(World.CAMERA_INITIAL_DISTANCE)
|
||||||
rotation.set(World.CAMERA_INITIAL_X_ANGLE, World.CAMERA_INITIAL_Y_ANGLE, World.CAMERA_INITIAL_Z_ANGLE)
|
rotation.set(World.CAMERA_INITIAL_X_ANGLE, World.CAMERA_INITIAL_Y_ANGLE, World.CAMERA_INITIAL_Z_ANGLE)
|
||||||
}
|
}
|
||||||
|
|
||||||
val controls: OrbitControls = OrbitControls(camera, renderer.domElement)
|
fun attach(element: Element, computeWidth: Element.() -> Int = { element.clientWidth }) {
|
||||||
|
|
||||||
val root get() = renderer.domElement
|
val width by meta.number(computeWidth(element)).int
|
||||||
|
|
||||||
private fun animate() {
|
val height: Int = (width / aspectRatio).toInt()
|
||||||
window.requestAnimationFrame {
|
|
||||||
animate()
|
val renderer = WebGLRenderer { antialias = true }.apply {
|
||||||
|
setClearColor(ColorConstants.skyblue, 1)
|
||||||
|
setSize(width, height)
|
||||||
|
}
|
||||||
|
|
||||||
|
val controls: OrbitControls = OrbitControls(camera, renderer.domElement)
|
||||||
|
|
||||||
|
fun animate() {
|
||||||
|
window.requestAnimationFrame {
|
||||||
|
animate()
|
||||||
|
}
|
||||||
|
renderer.render(scene, camera)
|
||||||
}
|
}
|
||||||
renderer.render(scene, camera)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun start(element: Element) {
|
|
||||||
window.addEventListener("resize", {
|
window.addEventListener("resize", {
|
||||||
camera.aspect = window.innerWidth.toDouble() / window.innerHeight;
|
camera.updateProjectionMatrix()
|
||||||
camera.updateProjectionMatrix();
|
|
||||||
|
|
||||||
renderer.setSize(window.innerWidth, window.innerHeight)
|
val width by meta.number(computeWidth(element)).int
|
||||||
|
|
||||||
|
renderer.setSize(width, (width / aspectRatio).toInt())
|
||||||
}, false)
|
}, false)
|
||||||
element.appendChild(root)
|
|
||||||
|
element.replaceWith(renderer.domElement)
|
||||||
animate()
|
animate()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private fun buildNode(obj: DisplayObject): Object3D? {
|
private fun buildNode(obj: DisplayObject): Object3D? {
|
||||||
return when (obj) {
|
return if (obj is DisplayGroup) Group(obj.mapNotNull { buildNode(it) }).apply {
|
||||||
is DisplayGroup -> Group(obj.mapNotNull { buildNode(it) }).apply {
|
ThreeFactory.updatePosition(obj, this)
|
||||||
ThreeFactory.updatePosition(obj, this)
|
} else {
|
||||||
|
val factory = context.content<ThreeFactory<*>>(ThreeFactory.TYPE).values.find { it.type == obj::class }
|
||||||
|
when {
|
||||||
|
factory != null -> factory(obj)
|
||||||
|
obj is Shape -> ThreeShapeFactory(obj)
|
||||||
|
else -> error("Renderer for ${obj::class} not found")
|
||||||
}
|
}
|
||||||
//is Box -> ThreeBoxFactory(obj)
|
|
||||||
//is JSRootObject -> ThreeJSRootFactory(obj)
|
|
||||||
//is Convex -> ThreeConvexFactory(obj)
|
|
||||||
else -> findFactory(obj::class)?.invoke(obj) ?: error("Factory not found")
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun <T : DisplayObject> findFactory(type: KClass<out T>): ThreeFactory<T>? {
|
|
||||||
return context.content<ThreeFactory<*>>(ThreeFactory.TYPE).values.find { it.type == type } as? ThreeFactory<T>?
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun render(obj: DisplayObject, meta: Meta) {
|
override fun render(obj: DisplayObject, meta: Meta) {
|
||||||
buildNode(obj)?.let {
|
buildNode(obj)?.let {
|
||||||
scene.add(it)
|
scene.add(it)
|
||||||
} ?: error("Renderer for ${obj::class} not found")
|
} ?: error("Renderer for ${obj::class} not found")
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
// init {
|
companion object {
|
||||||
// val cube: Mesh
|
fun build(context: Context, meta: Meta = EmptyMeta, override: MetaBuilder.() -> Unit) =
|
||||||
//
|
ThreeOutput(context, buildMeta(meta,override))
|
||||||
// cube = Mesh(
|
}
|
||||||
// BoxBufferGeometry(1, 1, 1),
|
}
|
||||||
// MeshPhongMaterial().apply {
|
|
||||||
// this.color.set(ColorConstants.darkgreen)
|
|
||||||
// }
|
|
||||||
// ).also(scene::add)
|
|
||||||
//
|
|
||||||
// Mesh(cube.geometry as BufferGeometry,
|
|
||||||
// MeshBasicMaterial().apply {
|
|
||||||
// this.wireframe = true
|
|
||||||
// this.color.set(ColorConstants.black)
|
|
||||||
// }
|
|
||||||
// ).also(cube::add)
|
|
||||||
//
|
|
||||||
// val points = CatmullRomCurve3(
|
|
||||||
// arrayOf(
|
|
||||||
// Vector3(-10, 0, 10),
|
|
||||||
// Vector3(-5, 5, 5),
|
|
||||||
// Vector3(0, 0, 0),
|
|
||||||
// Vector3(5, -5, 5),
|
|
||||||
// Vector3(10, 0, 10)
|
|
||||||
// )
|
|
||||||
// ).getPoints(50)
|
|
||||||
//
|
|
||||||
// val geometry = BufferGeometry().setFromPoints(points)
|
|
||||||
//
|
|
||||||
// val material = LineBasicMaterial().apply {
|
|
||||||
// color.set(0xff0000)
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// // Create the final object to add to the scene
|
|
||||||
// Line(geometry, material).apply(scene::add)
|
|
||||||
// }
|
|
@ -13,12 +13,10 @@ class ThreePlugin : AbstractPlugin() {
|
|||||||
val factories = HashMap<Name, ThreeFactory<*>>()
|
val factories = HashMap<Name, ThreeFactory<*>>()
|
||||||
|
|
||||||
init {
|
init {
|
||||||
factories["box".toName()] = ThreeBoxFactory
|
//factories["box".toName()] = ThreeBoxFactory
|
||||||
factories["convex".toName()] = ThreeConvexFactory
|
factories["convex".toName()] = ThreeConvexFactory
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
override fun listNames(target: String): Sequence<Name> {
|
override fun listNames(target: String): Sequence<Name> {
|
||||||
return when (target) {
|
return when (target) {
|
||||||
ThreeFactory.TYPE -> factories.keys.asSequence()
|
ThreeFactory.TYPE -> factories.keys.asSequence()
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
package hep.dataforge.vis
|
package hep.dataforge.vis.spatial.demo
|
||||||
|
|
||||||
external val module: Module
|
external val module: Module
|
||||||
|
|
@ -0,0 +1,77 @@
|
|||||||
|
package hep.dataforge.vis.spatial.demo
|
||||||
|
|
||||||
|
import hep.dataforge.context.ContextBuilder
|
||||||
|
import hep.dataforge.meta.number
|
||||||
|
import hep.dataforge.vis.spatial.*
|
||||||
|
import hep.dataforge.vis.spatial.jsroot.JSRootPlugin
|
||||||
|
import hep.dataforge.vis.spatial.jsroot.jsRootGeometry
|
||||||
|
import kotlinx.coroutines.GlobalScope
|
||||||
|
import kotlinx.coroutines.delay
|
||||||
|
import kotlinx.coroutines.isActive
|
||||||
|
import kotlinx.coroutines.launch
|
||||||
|
import kotlin.random.Random
|
||||||
|
|
||||||
|
|
||||||
|
class ThreeDemoApp : ApplicationBase() {
|
||||||
|
|
||||||
|
override val stateKeys: List<String> = emptyList()
|
||||||
|
|
||||||
|
override fun start(state: Map<String, Any>) {
|
||||||
|
require("JSRootGeoBase.js")
|
||||||
|
|
||||||
|
//TODO replace by optimized builder after dataforge 0.1.3-dev-8
|
||||||
|
val context = ContextBuilder("three-demo").apply {
|
||||||
|
plugin(JSRootPlugin())
|
||||||
|
}.build()
|
||||||
|
|
||||||
|
val grid = context.plugins.load(ThreeDemoGrid()).apply {
|
||||||
|
demo("group", "Group demo") {
|
||||||
|
val group = group {
|
||||||
|
box {
|
||||||
|
z = 110.0
|
||||||
|
xSize = 100.0
|
||||||
|
ySize = 100.0
|
||||||
|
zSize = 100.0
|
||||||
|
}
|
||||||
|
box {
|
||||||
|
visible = false
|
||||||
|
x = 110.0
|
||||||
|
xSize = 100.0
|
||||||
|
ySize = 100.0
|
||||||
|
zSize = 100.0
|
||||||
|
color(1530)
|
||||||
|
|
||||||
|
GlobalScope.launch {
|
||||||
|
while (isActive) {
|
||||||
|
delay(500)
|
||||||
|
visible = !visible
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var color by group.properties.number(1530).int
|
||||||
|
|
||||||
|
GlobalScope.launch {
|
||||||
|
val random = Random(111)
|
||||||
|
while (isActive) {
|
||||||
|
delay(1000)
|
||||||
|
color = random.nextInt(0, Int.MAX_VALUE)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
demo("jsroot", "JSROOT cube"){
|
||||||
|
jsRootGeometry {
|
||||||
|
y = 110.0
|
||||||
|
shape = box(50, 50, 50)
|
||||||
|
color(12285)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun dispose() = emptyMap<String, Any>()//mapOf("lines" to presenter.dispose())
|
||||||
|
}
|
@ -0,0 +1,80 @@
|
|||||||
|
package hep.dataforge.vis.spatial.demo
|
||||||
|
|
||||||
|
import hep.dataforge.context.AbstractPlugin
|
||||||
|
import hep.dataforge.context.Context
|
||||||
|
import hep.dataforge.context.PluginFactory
|
||||||
|
import hep.dataforge.context.PluginTag
|
||||||
|
import hep.dataforge.meta.Meta
|
||||||
|
import hep.dataforge.meta.buildMeta
|
||||||
|
import hep.dataforge.meta.get
|
||||||
|
import hep.dataforge.meta.string
|
||||||
|
import hep.dataforge.names.Name
|
||||||
|
import hep.dataforge.names.toName
|
||||||
|
import hep.dataforge.output.Output
|
||||||
|
import hep.dataforge.output.OutputManager
|
||||||
|
import hep.dataforge.vis.common.DisplayObject
|
||||||
|
import hep.dataforge.vis.common.DisplayObjectList
|
||||||
|
import hep.dataforge.vis.spatial.ThreeOutput
|
||||||
|
import hep.dataforge.vis.spatial.render
|
||||||
|
import kotlinx.html.dom.append
|
||||||
|
import kotlinx.html.dom.create
|
||||||
|
import kotlinx.html.h2
|
||||||
|
import kotlinx.html.hr
|
||||||
|
import kotlinx.html.id
|
||||||
|
import kotlinx.html.js.div
|
||||||
|
import kotlinx.html.span
|
||||||
|
import kotlin.browser.document
|
||||||
|
import kotlin.reflect.KClass
|
||||||
|
|
||||||
|
class ThreeDemoGrid(meta: Meta) : AbstractPlugin(meta), OutputManager {
|
||||||
|
override val tag: PluginTag get() = Companion.tag
|
||||||
|
|
||||||
|
private val gridRoot = document.create.div("row")
|
||||||
|
private val outputs: MutableMap<Name, ThreeOutput> = HashMap()
|
||||||
|
|
||||||
|
override fun attach(context: Context) {
|
||||||
|
super.attach(context)
|
||||||
|
val elementId = meta["elementID"].string ?: "canvas"
|
||||||
|
val element = document.getElementById(elementId) ?: error("Element with id $elementId not found on page")
|
||||||
|
element.append(gridRoot)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun <T : Any> get(type: KClass<out T>, name: Name, stage: Name, meta: Meta): Output<T> {
|
||||||
|
return outputs.getOrPut(name) {
|
||||||
|
if (type != DisplayObject::class) error("Supports only DisplayObject")
|
||||||
|
val output = ThreeOutput.build(context, meta) {
|
||||||
|
"axis" to {
|
||||||
|
"size" to 500
|
||||||
|
}
|
||||||
|
}
|
||||||
|
gridRoot.append {
|
||||||
|
span("border") {
|
||||||
|
div("col-4") {
|
||||||
|
h2 { +(meta["title"].string ?: name.toString()) }
|
||||||
|
hr()
|
||||||
|
val id = "output-$name"
|
||||||
|
output.attach(div { this.id = id }) { 300 }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
output
|
||||||
|
} as Output<T>
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object : PluginFactory<ThreeDemoGrid> {
|
||||||
|
override val tag: PluginTag = PluginTag(group = "hep.dataforge", name = "vis.js.spatial.demo")
|
||||||
|
|
||||||
|
override val type: KClass<out ThreeDemoGrid> = ThreeDemoGrid::class
|
||||||
|
|
||||||
|
override fun invoke(meta: Meta): ThreeDemoGrid = ThreeDemoGrid(meta)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun ThreeDemoGrid.demo(name: String, title: String = name, block: DisplayObjectList.() -> Unit) {
|
||||||
|
val meta = buildMeta {
|
||||||
|
"title" to title
|
||||||
|
}
|
||||||
|
val output = get<DisplayObject>(DisplayObject::class, name.toName(), meta = meta)
|
||||||
|
output.render(action = block)
|
||||||
|
}
|
@ -1,6 +1,5 @@
|
|||||||
package hep.dataforge.vis
|
package hep.dataforge.vis.spatial.demo
|
||||||
|
|
||||||
import hep.dataforge.vis.spatial.ThreeDemoApp
|
|
||||||
import kotlin.browser.document
|
import kotlin.browser.document
|
||||||
import kotlin.dom.hasClass
|
import kotlin.dom.hasClass
|
||||||
|
|
@ -2,8 +2,8 @@ package hep.dataforge.vis.spatial.jsroot
|
|||||||
|
|
||||||
import hep.dataforge.context.Global
|
import hep.dataforge.context.Global
|
||||||
import hep.dataforge.meta.EmptyMeta
|
import hep.dataforge.meta.EmptyMeta
|
||||||
import hep.dataforge.vis.ApplicationBase
|
|
||||||
import hep.dataforge.vis.spatial.ThreeOutput
|
import hep.dataforge.vis.spatial.ThreeOutput
|
||||||
|
import hep.dataforge.vis.spatial.demo.ApplicationBase
|
||||||
import hep.dataforge.vis.spatial.render
|
import hep.dataforge.vis.spatial.render
|
||||||
import org.w3c.dom.HTMLDivElement
|
import org.w3c.dom.HTMLDivElement
|
||||||
import org.w3c.dom.events.Event
|
import org.w3c.dom.events.Event
|
||||||
@ -62,7 +62,7 @@ class JSRootDemoApp : ApplicationBase() {
|
|||||||
val renderer = ThreeOutput(Global)
|
val renderer = ThreeOutput(Global)
|
||||||
val canvas = document.getElementById("canvas")!!
|
val canvas = document.getElementById("canvas")!!
|
||||||
canvas.clear()
|
canvas.clear()
|
||||||
renderer.start(canvas)
|
renderer.attach(canvas)
|
||||||
println("started")
|
println("started")
|
||||||
|
|
||||||
renderer.render {
|
renderer.render {
|
||||||
|
@ -1,29 +1,47 @@
|
|||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html>
|
<html>
|
||||||
<head>
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
|
||||||
<title>Three js demo for particle physics</title>
|
<title>Three js demo for particle physics</title>
|
||||||
<style>
|
<!-- <style>-->
|
||||||
body {
|
<!-- body {-->
|
||||||
margin: 0;
|
<!-- margin: 0;-->
|
||||||
overflow: hidden;
|
<!-- overflow: hidden;-->
|
||||||
}
|
<!-- }-->
|
||||||
</style>
|
<!-- </style>-->
|
||||||
<!--<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/three.js/88/three.min.js"></script>-->
|
<!--<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/three.js/88/three.min.js"></script>-->
|
||||||
<!--<script type="text/javascript" src="js/OrbitControls.js"></script>-->
|
<!--<script type="text/javascript" src="js/OrbitControls.js"></script>-->
|
||||||
<!--<script type="text/javascript" src="js/three.min.js"></script>-->
|
<!--<script type="text/javascript" src="js/three.min.js"></script>-->
|
||||||
<!--<script type="text/javascript" src="js/ThreeCSG.js"></script>-->
|
<!--<script type="text/javascript" src="js/ThreeCSG.js"></script>-->
|
||||||
<!--<script type="text/javascript" src="js/JSRootCore.js"></script>-->
|
<!--<script type="text/javascript" src="js/JSRootCore.js"></script>-->
|
||||||
<!--<script type="text/javascript" src="js/JSRootGeoBase.js"></script>-->
|
<!--<script type="text/javascript" src="js/JSRootGeoBase.js"></script>-->
|
||||||
|
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css"
|
||||||
|
integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">
|
||||||
<script type="text/javascript" src="main.bundle.js"></script>
|
<script type="text/javascript" src="main.bundle.js"></script>
|
||||||
</head>
|
</head>
|
||||||
<body class="testApp">
|
<body class="testApp">
|
||||||
<div id="drop_zone" data-toggle="tooltip" data-placement="right"
|
<!--
|
||||||
|
<div class="container" id="drop_zone" data-toggle="tooltip" data-placement="right"
|
||||||
title="Для загрузки данных в текстовом формате, надо перетащить файл сюда">
|
title="Для загрузки данных в текстовом формате, надо перетащить файл сюда">
|
||||||
Загрузить данные
|
Загрузить данные
|
||||||
<br/>
|
<br/>
|
||||||
(перетащить файл сюда)
|
(перетащить файл сюда)
|
||||||
</div>
|
</div>
|
||||||
<h1>Demo canvas</h1>
|
-->
|
||||||
<div id="canvas"></div>
|
<div class="container">
|
||||||
|
<h1>Demo grid</h1>
|
||||||
|
</div>
|
||||||
|
<div class="container" id="canvas"></div>
|
||||||
|
|
||||||
|
<script src="https://code.jquery.com/jquery-3.3.1.slim.min.js"
|
||||||
|
integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo"
|
||||||
|
crossorigin="anonymous"></script>
|
||||||
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js"
|
||||||
|
integrity="sha384-UO2eT0CpHqdSJQ6hJty5KVphtPhzWj9WO1clHTMGa3JDZwrnQq4sF86dIHNDz0W1"
|
||||||
|
crossorigin="anonymous"></script>
|
||||||
|
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js"
|
||||||
|
integrity="sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM+B07jRM"
|
||||||
|
crossorigin="anonymous"></script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
@ -1,5 +1,5 @@
|
|||||||
plugins {
|
plugins {
|
||||||
`npm-multiplatform`
|
id("scientifik.mpp")
|
||||||
}
|
}
|
||||||
|
|
||||||
kotlin {
|
kotlin {
|
||||||
|
@ -7,13 +7,33 @@ import hep.dataforge.vis.common.DisplayObject
|
|||||||
import hep.dataforge.vis.common.DisplayObjectList
|
import hep.dataforge.vis.common.DisplayObjectList
|
||||||
import hep.dataforge.vis.common.double
|
import hep.dataforge.vis.common.double
|
||||||
|
|
||||||
class Box(parent: DisplayObject?, meta: Meta) : DisplayLeaf(parent, meta) {
|
class Box(parent: DisplayObject?, meta: Meta) : DisplayLeaf(parent, meta), Shape {
|
||||||
var xSize by double(1.0)
|
var xSize by double(1.0)
|
||||||
var ySize by double(1.0)
|
var ySize by double(1.0)
|
||||||
var zSize by double(1.0)
|
var zSize by double(1.0)
|
||||||
|
|
||||||
//TODO add helper for color configuration
|
//TODO add helper for color configuration
|
||||||
|
|
||||||
|
override fun <T : Any> GeometryBuilder<T>.buildGeometry() {
|
||||||
|
val dx = xSize / 2
|
||||||
|
val dy = ySize / 2
|
||||||
|
val dz = zSize / 2
|
||||||
|
val node1 = Point3D(-dx, -dy, -dz)
|
||||||
|
val node2 = Point3D(dx, -dy, -dz)
|
||||||
|
val node3 = Point3D(dx, dy, -dz)
|
||||||
|
val node4 = Point3D(-dx, dy, -dz)
|
||||||
|
val node5 = Point3D(-dx, -dy, dz)
|
||||||
|
val node6 = Point3D(dx, -dy, dz)
|
||||||
|
val node7 = Point3D(dx, dy, dz)
|
||||||
|
val node8 = Point3D(-dx, dy, dz)
|
||||||
|
face4(node1, node4, node3, node2, Point3D(0, 0, -1))
|
||||||
|
face4(node1, node2, node6, node5, Point3D(0, -1, 0))
|
||||||
|
face4(node2, node3, node7, node6, Point3D(1, 0, 0))
|
||||||
|
face4(node4, node8, node7, node3, Point3D(0, 1, 0))
|
||||||
|
face4(node1, node5, node8, node4, Point3D(-1, 0, 0))
|
||||||
|
face4(node8, node5, node6, node7, Point3D(0, 0, 1))
|
||||||
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
const val TYPE = "geometry.3d.box"
|
const val TYPE = "geometry.3d.box"
|
||||||
}
|
}
|
||||||
|
@ -1,18 +0,0 @@
|
|||||||
package hep.dataforge.vis.spatial
|
|
||||||
|
|
||||||
import hep.dataforge.meta.Meta
|
|
||||||
import hep.dataforge.meta.MetaRepr
|
|
||||||
import hep.dataforge.meta.buildMeta
|
|
||||||
|
|
||||||
|
|
||||||
data class Point2D(val x: Number, val y: Number)
|
|
||||||
|
|
||||||
typealias Shape2D = List<Point2D>
|
|
||||||
|
|
||||||
data class Point3D(val x: Number, val y: Number, val z: Number): MetaRepr{
|
|
||||||
override fun toMeta(): Meta = buildMeta {
|
|
||||||
"x" to x
|
|
||||||
"y" to y
|
|
||||||
"z" to z
|
|
||||||
}
|
|
||||||
}
|
|
@ -0,0 +1,52 @@
|
|||||||
|
package hep.dataforge.vis.spatial
|
||||||
|
|
||||||
|
import hep.dataforge.meta.EmptyMeta
|
||||||
|
import hep.dataforge.meta.Meta
|
||||||
|
import hep.dataforge.meta.MetaRepr
|
||||||
|
import hep.dataforge.meta.buildMeta
|
||||||
|
import hep.dataforge.vis.common.DisplayObject
|
||||||
|
|
||||||
|
data class Point2D(val x: Number, val y: Number)
|
||||||
|
|
||||||
|
typealias Shape2D = List<Point2D>
|
||||||
|
|
||||||
|
data class Point3D(val x: Number, val y: Number, val z: Number) : MetaRepr {
|
||||||
|
override fun toMeta(): Meta = buildMeta {
|
||||||
|
"x" to x
|
||||||
|
"y" to y
|
||||||
|
"z" to z
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param T the type of resulting geometry
|
||||||
|
*/
|
||||||
|
interface GeometryBuilder<T: Any> {
|
||||||
|
/**
|
||||||
|
* Add a face to 3D model. If one of the vertices is not present in the current geometry model list of vertices,
|
||||||
|
* it is added automatically.
|
||||||
|
*
|
||||||
|
* @param normal optional external normal to the face
|
||||||
|
* @param meta optional additional platform-specific parameters like color or texture index
|
||||||
|
*/
|
||||||
|
fun face(vertex1: Point3D, vertex2: Point3D, vertex3: Point3D, normal: Point3D? = null, meta: Meta = EmptyMeta)
|
||||||
|
|
||||||
|
fun build(): T
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
fun GeometryBuilder<*>.face4(
|
||||||
|
vertex1: Point3D,
|
||||||
|
vertex2: Point3D,
|
||||||
|
vertex3: Point3D,
|
||||||
|
vertex4: Point3D,
|
||||||
|
normal: Point3D? = null,
|
||||||
|
meta: Meta = EmptyMeta
|
||||||
|
) {
|
||||||
|
face(vertex1, vertex2, vertex3, normal, meta)
|
||||||
|
face(vertex1, vertex3, vertex4, normal, meta)
|
||||||
|
}
|
||||||
|
|
||||||
|
interface Shape: DisplayObject {
|
||||||
|
fun <T: Any> GeometryBuilder<T>.buildGeometry()
|
||||||
|
}
|
@ -3,14 +3,22 @@ pluginManagement {
|
|||||||
jcenter()
|
jcenter()
|
||||||
gradlePluginPortal()
|
gradlePluginPortal()
|
||||||
maven("https://dl.bintray.com/kotlin/kotlin-eap")
|
maven("https://dl.bintray.com/kotlin/kotlin-eap")
|
||||||
|
maven("https://dl.bintray.com/mipt-npm/scientifik")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
val kotlinVersion = "1.3.40"
|
||||||
resolutionStrategy {
|
resolutionStrategy {
|
||||||
eachPlugin {
|
eachPlugin {
|
||||||
when (requested.id.id) {
|
when (requested.id.id) {
|
||||||
"kotlinx-atomicfu" -> useModule("org.jetbrains.kotlinx:atomicfu-gradle-plugin:${requested.version}")
|
"kotlinx-atomicfu" -> useModule("org.jetbrains.kotlinx:atomicfu-gradle-plugin:${requested.version}")
|
||||||
"kotlin-multiplatform" -> useModule("org.jetbrains.kotlin:kotlin-gradle-plugin:${requested.version}")
|
"kotlin-multiplatform" -> useModule("org.jetbrains.kotlin:kotlin-gradle-plugin:${requested.version}")
|
||||||
|
"org.jetbrains.kotlin.jvm" -> useModule("org.jetbrains.kotlin:kotlin-gradle-plugin:${requested.version}")
|
||||||
|
"org.jetbrains.kotlin.js" -> useModule("org.jetbrains.kotlin:kotlin-gradle-plugin:${requested.version}")
|
||||||
|
"kotlin-dce-js" -> useModule("org.jetbrains.kotlin:kotlin-gradle-plugin:${requested.version}")
|
||||||
"kotlin2js" -> useModule("org.jetbrains.kotlin:kotlin-gradle-plugin:${requested.version}")
|
"kotlin2js" -> useModule("org.jetbrains.kotlin:kotlin-gradle-plugin:${requested.version}")
|
||||||
"org.jetbrains.kotlin.frontend" -> useModule("org.jetbrains.kotlin:kotlin-frontend-plugin:0.0.45")
|
"org.jetbrains.kotlin.frontend" -> useModule("org.jetbrains.kotlin:kotlin-frontend-plugin:${requested.version}")
|
||||||
|
"scientifik.mpp", "scientifik.publish" -> useModule("scientifik:gradle-tools:${requested.version}")
|
||||||
|
"org.openjfx.javafxplugin" -> useModule("org.openjfx:javafx-plugin:${requested.version}")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -25,8 +33,7 @@ include(
|
|||||||
":dataforge-vis-fx",
|
":dataforge-vis-fx",
|
||||||
":dataforge-vis-spatial",
|
":dataforge-vis-spatial",
|
||||||
":dataforge-vis-spatial-fx",
|
":dataforge-vis-spatial-fx",
|
||||||
":dataforge-vis-spatial-js",
|
":dataforge-vis-spatial-js"
|
||||||
":dataforge-vis-js-tree"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
//if(file("../dataforge-core").exists()) {
|
//if(file("../dataforge-core").exists()) {
|
||||||
|
Loading…
Reference in New Issue
Block a user