Roll back prototypes location

This commit is contained in:
Alexander Nozik 2020-02-28 21:07:09 +03:00
parent ef42327cc5
commit 6b455b57aa
8 changed files with 80 additions and 515 deletions

View File

@ -169,7 +169,9 @@ fun VisualGroup3D.proxy(
): Proxy { ): Proxy {
val existing = getPrototype(templateName) val existing = getPrototype(templateName)
if (existing == null) { if (existing == null) {
setPrototype(templateName, obj) prototypes{
this[templateName] = obj
}
} else if (existing != obj) { } else if (existing != obj) {
error("Can't add different prototype on top of existing one") error("Can't add different prototype on top of existing one")
} }

View File

@ -20,7 +20,6 @@ import hep.dataforge.vis.common.AbstractVisualGroup
import hep.dataforge.vis.common.StyleSheet import hep.dataforge.vis.common.StyleSheet
import hep.dataforge.vis.common.VisualObject import hep.dataforge.vis.common.VisualObject
import hep.dataforge.vis.common.set import hep.dataforge.vis.common.set
import hep.dataforge.vis.spatial.VisualGroup3D.Companion.PROTOTYPES_KEY
import kotlinx.serialization.SerialName import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable import kotlinx.serialization.Serializable
import kotlinx.serialization.UseSerializers import kotlinx.serialization.UseSerializers
@ -36,6 +35,15 @@ class VisualGroup3D : AbstractVisualGroup(), VisualObject3D {
override var styleSheet: StyleSheet? = null override var styleSheet: StyleSheet? = null
private set private set
/**
* A container for templates visible inside this group
*/
var prototypes: VisualGroup3D? = null
set(value) {
value?.parent = this
field = value
}
//FIXME to be lifted to AbstractVisualGroup after https://github.com/Kotlin/kotlinx.serialization/issues/378 is fixed //FIXME to be lifted to AbstractVisualGroup after https://github.com/Kotlin/kotlinx.serialization/issues/378 is fixed
override var properties: Config? = null override var properties: Config? = null
@ -45,18 +53,23 @@ class VisualGroup3D : AbstractVisualGroup(), VisualObject3D {
@SerialName("children") @SerialName("children")
private val _children = HashMap<NameToken, VisualObject>() private val _children = HashMap<NameToken, VisualObject>()
override val children: Map<NameToken, VisualObject> get() = _children.filterKeys { it != PROTOTYPES_KEY } override val children: Map<NameToken, VisualObject> get() = _children
// init { // init {
// //Do after deserialization // //Do after deserialization
// attachChildren() // attachChildren()
// } // }
override fun attachChildren() {
prototypes?.parent = this
super.attachChildren()
}
/** /**
* Update or create stylesheet * Update or create stylesheet
*/ */
fun styleSheet(block: StyleSheet.() -> Unit) { fun styleSheet(block: StyleSheet.() -> Unit) {
val res = this.styleSheet ?: StyleSheet(this).also { this.styleSheet = it } val res = styleSheet ?: StyleSheet(this).also { styleSheet = it }
res.block() res.block()
} }
@ -95,42 +108,25 @@ class VisualGroup3D : AbstractVisualGroup(), VisualObject3D {
} }
} }
override fun attachChildren() {
prototypes?.let {
it.parent = this
it.attachChildren()
}
super.attachChildren()
}
companion object { companion object {
val PROTOTYPES_KEY = NameToken("@prototypes") // val PROTOTYPES_KEY = NameToken("@prototypes")
fun fromJson(json: String): VisualGroup3D = fun fromJson(json: String): VisualGroup3D =
Visual3DPlugin.json.parse(serializer(), json).also { it.attachChildren() } Visual3DPlugin.json.parse(serializer(), json).also { it.attachChildren() }
} }
} }
/**
* A container for templates visible inside this group
*/
var VisualGroup3D.prototypes: VisualGroup3D?
get() = children[PROTOTYPES_KEY] as? VisualGroup3D
set(value) {
this[PROTOTYPES_KEY.asName()] = value
}
/** /**
* Ger a prototype redirecting the request to the parent if prototype is not found * Ger a prototype redirecting the request to the parent if prototype is not found
*/ */
fun VisualGroup3D.getPrototype(name: Name): VisualObject3D? = tailrec fun VisualGroup3D.getPrototype(name: Name): VisualObject3D? =
prototypes?.get(name) as? VisualObject3D ?: (parent as? VisualGroup3D)?.getPrototype(name) prototypes?.get(name) as? VisualObject3D ?: (parent as? VisualGroup3D)?.getPrototype(name)
/** /**
* Defined a prototype inside current group * Create or edit prototype node as a group
*/ */
fun VisualGroup3D.setPrototype(name: Name, obj: VisualObject3D) { inline fun VisualGroup3D.prototypes(builder: VisualGroup3D.() -> Unit): Unit {
(prototypes ?: VisualGroup3D().also { this.prototypes = it })[name] = obj (prototypes ?: VisualGroup3D().also { prototypes = it }).run(builder)
} }
/** /**
@ -139,10 +135,3 @@ fun VisualGroup3D.setPrototype(name: Name, obj: VisualObject3D) {
fun VisualGroup3D.group(key: String = "", action: VisualGroup3D.() -> Unit = {}): VisualGroup3D = fun VisualGroup3D.group(key: String = "", action: VisualGroup3D.() -> Unit = {}): VisualGroup3D =
VisualGroup3D().apply(action).also { set(key, it) } VisualGroup3D().apply(action).also { set(key, it) }
/**
* Create or edit prototype node as a group
*/
inline fun VisualGroup3D.prototypes(builder: VisualGroup3D.() -> Unit): Unit {
(prototypes ?: VisualGroup3D().also { this.prototypes = it }).run(builder)
}

View File

@ -51,7 +51,9 @@ object RemoveSingleChild : VisualTreeTransform<VisualGroup3D>() {
} }
replaceChildren() replaceChildren()
prototypes?.replaceChildren() prototypes {
replaceChildren()
}
} }
override fun VisualGroup3D.clone(): VisualGroup3D { override fun VisualGroup3D.clone(): VisualGroup3D {

View File

@ -24,11 +24,7 @@ import hep.dataforge.vis.spatial.three.ThreePlugin
import hep.dataforge.vis.spatial.three.displayCanvasControls import hep.dataforge.vis.spatial.three.displayCanvasControls
import hep.dataforge.vis.spatial.three.output import hep.dataforge.vis.spatial.three.output
import hep.dataforge.vis.spatial.visible import hep.dataforge.vis.spatial.visible
import kotlinx.html.dom.append import org.w3c.dom.*
import kotlinx.html.js.p
import org.w3c.dom.DragEvent
import org.w3c.dom.HTMLDivElement
import org.w3c.dom.HTMLElement
import org.w3c.files.FileList import org.w3c.files.FileList
import org.w3c.files.FileReader import org.w3c.files.FileReader
import org.w3c.files.get import org.w3c.files.get
@ -80,17 +76,18 @@ private class GDMLDemoApp : Application {
} }
private fun message(message: String?) { private fun message(message: String?) {
document.getElementById("messages")?.let { element -> console.log(message)
if (message == null) { // document.getElementById("messages")?.let { element ->
element.clear() // if (message == null) {
} else { // element.clear()
element.append { // } else {
p { // element.append {
+message // p {
} // +message
} // }
} // }
} // }
// }
} }
private val gdmlConfiguration: GDMLTransformer.() -> Unit = { private val gdmlConfiguration: GDMLTransformer.() -> Unit = {
@ -202,6 +199,19 @@ private class GDMLDemoApp : Application {
addEventListener("dragover", { handleDragOver(it as DragEvent) }, false) addEventListener("dragover", { handleDragOver(it as DragEvent) }, false)
addEventListener("drop", { loadData(it as DragEvent, action) }, false) addEventListener("drop", { loadData(it as DragEvent, action) }, false)
} }
(document.getElementById("file_load_button") as? HTMLInputElement)?.apply {
addEventListener("change", {
(it.target as HTMLInputElement).files?.asList()?.first()?.let { file ->
FileReader().apply {
onload = {
val string = result as String
action(file.name, string)
}
readAsText(file)
}
}
}, false)
}
} }
} }

View File

@ -1,3 +1,7 @@
.drop_zone {
outline: 1px solid orange;
}
.loader { .loader {
border: 16px solid #f3f3f3; /* Light grey */ border: 16px solid #f3f3f3; /* Light grey */
border-top: 16px solid #3498db; /* Blue */ border-top: 16px solid #3498db; /* Blue */

View File

@ -11,17 +11,30 @@
<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 class="container" id="drop_zone" data-toggle="tooltip" data-placement="right" <div class="container">
title="To load data in text format, drag-and-drop file here"> <div class="row">
Load data <div class="col-6">
<br/> <div class="card">
(drag file here) <div class="card-body">
<a>Load file:</a>
<input type="file" id="file_load_button" accept=".gdml, application/xml, application/json"/>
</div>
</div>
</div>
<div class="col-6">
<div class="card">
<div class="card-body" id="drop_zone">
Load data
<br/>
(drag file here)
</div>
</div>
</div>
</div>
</div> </div>
<div class="container"> <div class="container">
<h1>GDML demo</h1> <h1>GDML demo</h1>
</div> </div>
<!--<div class="container loader" id="loader" style="display:none;"></div>-->
<div class="container animate-bottom" id="messages"></div>
<div class="container-fluid"> <div class="container-fluid">
<div class="row"> <div class="row">
@ -33,5 +46,6 @@
<div class="col-lg-3" id="editor"></div> <div class="col-lg-3" id="editor"></div>
</div> </div>
</div> </div>
</body> </body>
</html> </html>

View File

@ -2,9 +2,11 @@ package hep.dataforge.vis.spatial
import hep.dataforge.names.asName import hep.dataforge.names.asName
import org.junit.Test import org.junit.Test
import kotlin.test.Ignore
class FileSerializationTest { class FileSerializationTest {
@Test @Test
@Ignore
fun testFileRead(){ fun testFileRead(){
val text = this::class.java.getResourceAsStream("/cubes.json").readAllBytes().decodeToString() val text = this::class.java.getResourceAsStream("/cubes.json").readAllBytes().decodeToString()
val visual = VisualGroup3D.fromJson(text) val visual = VisualGroup3D.fromJson(text)

View File

@ -1,458 +0,0 @@
{
"templates": {
"children": {
"segment": {
"type": "hep.dataforge.vis.spatial.Tube",
"radius": 20.0,
"height": 5.0,
"innerRadius": 17.0,
"angle": 1.0471976,
"properties": {
"@style": "material[G4_WATER]"
}
},
"cave": {
"type": "3d.box",
"xSize": 200.0,
"ySize": 200.0,
"zSize": 200.0,
"properties": {
"@style": [
"material[G4_AIR]",
"opaque"
]
}
},
"volumes": {
"type": "group.3d",
"children": {
"composite": {
"type": "group.3d",
"children": {
"segment_1": {
"type": "3d.proxy",
"templateName": "volumes.segment_vol",
"rotation": {
"z": 1.0471975803375244
}
},
"segment_2": {
"type": "3d.proxy",
"templateName": "volumes.segment_vol",
"rotation": {
"z": 2.094395160675049
}
},
"segment_3": {
"type": "3d.proxy",
"templateName": "volumes.segment_vol",
"rotation": {
"z": 3.1415927410125732
}
},
"segment_4": {
"type": "3d.proxy",
"templateName": "volumes.segment_vol",
"rotation": {
"z": 4.188790321350098
}
},
"segment_0": {
"type": "3d.proxy",
"templateName": "volumes.segment_vol"
},
"box": {
"type": "3d.proxy",
"templateName": "box"
},
"segment_5": {
"type": "3d.proxy",
"templateName": "volumes.segment_vol",
"rotation": {
"z": 5.235987663269043
}
}
}
},
"segment_vol": {
"type": "group.3d",
"children": {
"segment": {
"type": "3d.proxy",
"templateName": "segment"
}
}
}
}
},
"box": {
"type": "3d.box",
"xSize": 30.0,
"ySize": 30.0,
"zSize": 30.0,
"properties": {
"@style": [
"material[G4_AIR]",
"opaque"
]
}
}
}
},
"styleSheet": {
"styleMap": {
"material[G4_WATER]": {
"material": {
"color": 1710240
},
"gdml": {
"material": "G4_WATER"
}
},
"opaque": {
"material": {
"opacity": 0.3
}
},
"material[G4_AIR]": {
"material": {
"color": 6376463
},
"gdml": {
"material": "G4_AIR"
}
}
}
},
"properties": {
"rotation": {
"order": "ZXY"
}
},
"children": {
"@static(1529060733)": {
"type": "3d.proxy",
"templateName": "volumes.composite",
"position": {
"y": 50.0
},
"rotation": {
"x": 2.094395160675049,
"y": 4.188790321350098,
"z": 2.094395160675049
}
},
"@static(1496355635)": {
"type": "3d.proxy",
"templateName": "volumes.composite",
"rotation": {
"x": 2.094395160675049,
"y": 2.094395160675049,
"z": 2.094395160675049
}
},
"@static(166794956)": {
"type": "3d.proxy",
"templateName": "volumes.composite",
"position": {
"y": -50.0
},
"rotation": {
"x": 2.094395160675049,
"z": 2.094395160675049
}
},
"@static(609962972)": {
"type": "3d.proxy",
"templateName": "volumes.composite",
"position": {
"x": 50.0,
"y": 50.0
},
"rotation": {
"x": 4.188790321350098,
"y": 4.188790321350098,
"z": 2.094395160675049
}
},
"@static(1741979653)": {
"type": "3d.proxy",
"templateName": "volumes.composite",
"position": {
"y": -50.0,
"z": -50.0
},
"rotation": {
"x": 2.094395160675049
}
},
"@static(1484171695)": {
"type": "3d.proxy",
"templateName": "volumes.composite",
"position": {
"z": 50.0
},
"rotation": {
"x": 2.094395160675049,
"y": 2.094395160675049,
"z": 4.188790321350098
}
},
"composite_003": {
"type": "3d.proxy",
"templateName": "volumes.composite",
"position": {
"x": -50.0,
"z": -50.0
},
"rotation": {
"y": 2.094395160675049
}
},
"@static(6519275)": {
"type": "3d.proxy",
"templateName": "volumes.composite",
"position": {
"x": -50.0,
"y": 50.0
},
"rotation": {
"y": 4.188790321350098,
"z": 2.094395160675049
}
},
"composite_001": {
"type": "3d.proxy",
"templateName": "volumes.composite",
"position": {
"x": -50.0,
"y": -50.0
},
"rotation": {
"z": 2.094395160675049
}
},
"@static(934275857)": {
"type": "3d.proxy",
"templateName": "volumes.composite",
"position": {
"x": 50.0
},
"rotation": {
"x": 4.188790321350098,
"y": 2.094395160675049,
"z": 2.094395160675049
}
},
"composite_005": {
"type": "3d.proxy",
"templateName": "volumes.composite",
"position": {
"x": -50.0,
"z": 50.0
},
"rotation": {
"y": 2.094395160675049,
"z": 4.188790321350098
}
},
"@static(712609105)": {
"type": "3d.proxy",
"templateName": "volumes.composite",
"position": {
"x": 50.0,
"y": -50.0
},
"rotation": {
"x": 4.188790321350098,
"z": 2.094395160675049
}
},
"@static(1364913072)": {
"type": "3d.proxy",
"templateName": "volumes.composite",
"position": {
"x": 50.0,
"z": 50.0
},
"rotation": {
"x": 4.188790321350098,
"y": 2.094395160675049,
"z": 4.188790321350098
}
},
"@static(232307208)": {
"type": "3d.proxy",
"templateName": "volumes.composite",
"position": {
"x": 50.0,
"y": 50.0,
"z": -50.0
},
"rotation": {
"x": 4.188790321350098,
"y": 4.188790321350098
}
},
"@static(1388278453)": {
"type": "3d.proxy",
"templateName": "volumes.composite",
"position": {
"x": 50.0,
"z": -50.0
},
"rotation": {
"x": 4.188790321350098,
"y": 2.094395160675049
}
},
"@static(1803669141)": {
"type": "3d.proxy",
"templateName": "volumes.composite",
"position": {
"x": 50.0,
"y": -50.0,
"z": -50.0
},
"rotation": {
"x": 4.188790321350098
}
},
"@static(692331943)": {
"type": "3d.proxy",
"templateName": "volumes.composite",
"position": {
"x": -50.0,
"y": 50.0,
"z": 50.0
},
"rotation": {
"y": 4.188790321350098,
"z": 4.188790321350098
}
},
"@static(106374177)": {
"type": "3d.proxy",
"templateName": "volumes.composite",
"position": {
"y": 50.0,
"z": 50.0
},
"rotation": {
"x": 2.094395160675049,
"y": 4.188790321350098,
"z": 4.188790321350098
}
},
"composite_004": {
"type": "3d.proxy",
"templateName": "volumes.composite",
"position": {
"x": -50.0
},
"rotation": {
"y": 2.094395160675049,
"z": 2.094395160675049
}
},
"cave": {
"type": "3d.proxy",
"templateName": "cave"
},
"composite_002": {
"type": "3d.proxy",
"templateName": "volumes.composite",
"position": {
"x": -50.0,
"y": -50.0,
"z": 50.0
},
"rotation": {
"z": 4.188790321350098
}
},
"@static(1836463382)": {
"type": "3d.proxy",
"templateName": "volumes.composite",
"position": {
"x": 50.0,
"y": -50.0,
"z": 50.0
},
"rotation": {
"x": 4.188790321350098,
"z": 4.188790321350098
}
},
"composite_006": {
"type": "3d.proxy",
"templateName": "volumes.composite",
"position": {
"x": -50.0,
"y": 50.0,
"z": -50.0
},
"rotation": {
"y": 4.188790321350098
}
},
"@static(306612792)": {
"type": "3d.proxy",
"templateName": "volumes.composite",
"position": {
"y": -50.0,
"z": 50.0
},
"rotation": {
"x": 2.094395160675049,
"z": 4.188790321350098
}
},
"@static(1818544933)": {
"type": "3d.proxy",
"templateName": "volumes.composite",
"position": {
"x": 50.0,
"y": 50.0,
"z": 50.0
},
"rotation": {
"x": 4.188790321350098,
"y": 4.188790321350098,
"z": 4.188790321350098
}
},
"@static(447212746)": {
"type": "3d.proxy",
"templateName": "volumes.composite",
"position": {
"z": -50.0
},
"rotation": {
"x": 2.094395160675049,
"y": 2.094395160675049
}
},
"@static(2127036371)": {
"type": "3d.proxy",
"templateName": "volumes.composite",
"position": {
"y": 50.0,
"z": -50.0
},
"rotation": {
"x": 2.094395160675049,
"y": 4.188790321350098
}
},
"composite_000": {
"type": "3d.proxy",
"templateName": "volumes.composite",
"position": {
"x": -50.0,
"y": -50.0,
"z": -50.0
}
}
}
}