forked from kscience/visionforge
Composite Union is replaced by a Group. Colors for root
This commit is contained in:
parent
aea4eb7d45
commit
2e3b63c0f4
@ -105,6 +105,8 @@ public class DGeoVolume(meta: Meta, refCache: DObjectCache) : DNamed(meta, refCa
|
|||||||
public val fShape: DGeoShape? by dObject(::DGeoShape)
|
public val fShape: DGeoShape? by dObject(::DGeoShape)
|
||||||
public val fMedium: DGeoMedium? by dObject(::DGeoMedium)
|
public val fMedium: DGeoMedium? by dObject(::DGeoMedium)
|
||||||
|
|
||||||
|
public val fFillColor: Int? by meta.int()
|
||||||
|
|
||||||
override val name: Name by lazy { Name.parse(fName.ifEmpty { "volume[${meta.hashCode().toUInt()}]" }) }
|
override val name: Name by lazy { Name.parse(fName.ifEmpty { "volume[${meta.hashCode().toUInt()}]" }) }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,12 +1,11 @@
|
|||||||
package ru.mipt.npm.root
|
package ru.mipt.npm.root
|
||||||
|
|
||||||
import space.kscience.dataforge.meta.double
|
import space.kscience.dataforge.meta.*
|
||||||
import space.kscience.dataforge.meta.get
|
|
||||||
import space.kscience.dataforge.meta.int
|
|
||||||
import space.kscience.dataforge.meta.isEmpty
|
|
||||||
import space.kscience.dataforge.names.Name
|
import space.kscience.dataforge.names.Name
|
||||||
import space.kscience.dataforge.names.plus
|
import space.kscience.dataforge.names.plus
|
||||||
|
import space.kscience.dataforge.values.doubleArray
|
||||||
import space.kscience.visionforge.solid.*
|
import space.kscience.visionforge.solid.*
|
||||||
|
import space.kscience.visionforge.solid.SolidMaterial.Companion.MATERIAL_COLOR_KEY
|
||||||
import kotlin.math.*
|
import kotlin.math.*
|
||||||
|
|
||||||
private val volumesName = Name.EMPTY //"volumes".asName()
|
private val volumesName = Name.EMPTY //"volumes".asName()
|
||||||
@ -50,9 +49,8 @@ private fun Solid.useMatrix(matrix: DGeoMatrix?) {
|
|||||||
val fTranslation by matrix.meta.doubleArray()
|
val fTranslation by matrix.meta.doubleArray()
|
||||||
|
|
||||||
translate(fTranslation)
|
translate(fTranslation)
|
||||||
if (matrix.meta["fRotationMatrix"] != null) {
|
matrix.meta["fRotation.fRotationMatrix"]?.value?.let {
|
||||||
val fRotationMatrix by matrix.meta.doubleArray()
|
rotate(it.doubleArray)
|
||||||
rotate(fRotationMatrix)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
"TGeoHMatrix" -> {
|
"TGeoHMatrix" -> {
|
||||||
@ -77,15 +75,15 @@ private fun SolidGroup.addShape(
|
|||||||
val compositeType = when (node.typename) {
|
val compositeType = when (node.typename) {
|
||||||
"TGeoIntersection" -> CompositeType.INTERSECT
|
"TGeoIntersection" -> CompositeType.INTERSECT
|
||||||
"TGeoSubtraction" -> CompositeType.SUBTRACT
|
"TGeoSubtraction" -> CompositeType.SUBTRACT
|
||||||
"TGeoUnion" -> CompositeType.UNION
|
"TGeoUnion" -> CompositeType.GROUP
|
||||||
else -> error("Unknown bool node type ${node.typename}")
|
else -> error("Unknown bool node type ${node.typename}")
|
||||||
}
|
}
|
||||||
composite(compositeType, name = name) {
|
smartComposite(compositeType, name = name) {
|
||||||
addShape(node.fLeft!!, context, "left").also {
|
addShape(node.fLeft!!, context, null).also {
|
||||||
if (it == null) TODO()
|
if (it == null) TODO()
|
||||||
it.useMatrix(node.fLeftMat)
|
it.useMatrix(node.fLeftMat)
|
||||||
}
|
}
|
||||||
addShape(node.fRight!!, context, "right").also {
|
addShape(node.fRight!!, context, null).also {
|
||||||
if (it == null) TODO()
|
if (it == null) TODO()
|
||||||
it.useMatrix(node.fRightMat)
|
it.useMatrix(node.fRightMat)
|
||||||
}
|
}
|
||||||
@ -277,7 +275,11 @@ private fun SolidGroup.addRootVolume(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return ref(templateName, name)
|
ref(templateName, name)
|
||||||
|
}.apply {
|
||||||
|
volume.fFillColor?.let {
|
||||||
|
meta[MATERIAL_COLOR_KEY] = RootColors[it]
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -0,0 +1,42 @@
|
|||||||
|
package ru.mipt.npm.root
|
||||||
|
|
||||||
|
public object RootColors {
|
||||||
|
private val colorMap = Array<String>(924) { "white" }
|
||||||
|
|
||||||
|
//colorMap[110] = "white"
|
||||||
|
|
||||||
|
private val moreCol = listOf(
|
||||||
|
11 to "c1b7ad4d4d4d6666668080809a9a9ab3b3b3cdcdcde6e6e6f3f3f3cdc8accdc8acc3c0a9bbb6a4b3a697b8a49cae9a8d9c8f83886657b1cfc885c3a48aa9a1839f8daebdc87b8f9a768a926983976e7b857d9ad280809caca6c0d4cf88dfbb88bd9f83c89a7dc08378cf5f61ac8f94a6787b946971d45a549300ff7b00ff6300ff4b00ff3300ff1b00ff0300ff0014ff002cff0044ff005cff0074ff008cff00a4ff00bcff00d4ff00ecff00fffd00ffe500ffcd00ffb500ff9d00ff8500ff6d00ff5500ff3d00ff2600ff0e0aff0022ff003aff0052ff006aff0082ff009aff00b1ff00c9ff00e1ff00f9ff00ffef00ffd700ffbf00ffa700ff8f00ff7700ff6000ff4800ff3000ff1800ff0000",
|
||||||
|
201 to "5c5c5c7b7b7bb8b8b8d7d7d78a0f0fb81414ec4848f176760f8a0f14b81448ec4876f1760f0f8a1414b84848ec7676f18a8a0fb8b814ecec48f1f1768a0f8ab814b8ec48ecf176f10f8a8a14b8b848ecec76f1f1",
|
||||||
|
390 to "ffffcdffff9acdcd9affff66cdcd669a9a66ffff33cdcd339a9a33666633ffff00cdcd009a9a00666600333300",
|
||||||
|
406 to "cdffcd9aff9a9acd9a66ff6666cd66669a6633ff3333cd33339a3333663300ff0000cd00009a00006600003300",
|
||||||
|
422 to "cdffff9affff9acdcd66ffff66cdcd669a9a33ffff33cdcd339a9a33666600ffff00cdcd009a9a006666003333",
|
||||||
|
590 to "cdcdff9a9aff9a9acd6666ff6666cd66669a3333ff3333cd33339a3333660000ff0000cd00009a000066000033",
|
||||||
|
606 to "ffcdffff9affcd9acdff66ffcd66cd9a669aff33ffcd33cd9a339a663366ff00ffcd00cd9a009a660066330033",
|
||||||
|
622 to "ffcdcdff9a9acd9a9aff6666cd66669a6666ff3333cd33339a3333663333ff0000cd00009a0000660000330000",
|
||||||
|
791 to "ffcd9acd9a669a66339a6600cd9a33ffcd66ff9a00ffcd33cd9a00ffcd00ff9a33cd66006633009a3300cd6633ff9a66ff6600ff6633cd3300ff33009aff3366cd00336600339a0066cd339aff6666ff0066ff3333cd0033ff00cdff9a9acd66669a33669a009acd33cdff669aff00cdff339acd00cdff009affcd66cd9a339a66009a6633cd9a66ffcd00ff6633ffcd00cd9a00ffcd33ff9a00cd66006633009a3333cd6666ff9a00ff9a33ff6600cd3300ff339acdff669acd33669a00339a3366cd669aff0066ff3366ff0033cd0033ff339aff0066cd00336600669a339acd66cdff009aff33cdff009acd00cdffcd9aff9a66cd66339a66009a9a33cdcd66ff9a00ffcd33ff9a00cdcd00ff9a33ff6600cd33006633009a6633cd9a66ff6600ff6633ff3300cd3300ffff339acd00666600339a0033cd3366ff669aff0066ff3366cd0033ff0033ff9acdcd669a9a33669a0066cd339aff66cdff009acd009aff33cdff009a",
|
||||||
|
920 to "cdcdcd9a9a9a666666333333"
|
||||||
|
)
|
||||||
|
|
||||||
|
init {
|
||||||
|
colorMap[0] = "white"
|
||||||
|
colorMap[1] = "black"
|
||||||
|
colorMap[2] = "red"
|
||||||
|
colorMap[3] = "green"
|
||||||
|
colorMap[4] = "blue"
|
||||||
|
colorMap[5] = "yellow"
|
||||||
|
colorMap[6] = "magenta"
|
||||||
|
colorMap[7] = "cyan"
|
||||||
|
colorMap[8] = "rgb(89,212,84)"
|
||||||
|
colorMap[9] = "rgb(89,84,217)"
|
||||||
|
colorMap[10] = "white"
|
||||||
|
|
||||||
|
moreCol.forEach { (n, s) ->
|
||||||
|
for (i in 0 until (s.length / 6)) {
|
||||||
|
colorMap[n + i] = "#" + s.substring(i * 6, (i + 1) * 6)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public operator fun get(index: Int): String = colorMap[index]
|
||||||
|
}
|
@ -1,72 +0,0 @@
|
|||||||
package ru.mipt.npm.root
|
|
||||||
|
|
||||||
import kotlinx.serialization.json.JsonArray
|
|
||||||
import kotlinx.serialization.json.JsonElement
|
|
||||||
import kotlinx.serialization.json.JsonObject
|
|
||||||
import kotlinx.serialization.json.jsonPrimitive
|
|
||||||
import ru.mipt.npm.root.serialization.TGeoManager
|
|
||||||
import space.kscience.dataforge.meta.Meta
|
|
||||||
import space.kscience.dataforge.meta.get
|
|
||||||
import space.kscience.dataforge.meta.isLeaf
|
|
||||||
import space.kscience.dataforge.values.string
|
|
||||||
import space.kscience.visionforge.solid.Solids
|
|
||||||
import java.nio.file.Paths
|
|
||||||
import java.time.Duration
|
|
||||||
import kotlin.io.path.writeText
|
|
||||||
import kotlin.system.measureTimeMillis
|
|
||||||
|
|
||||||
private fun JsonElement.countTypes(): Sequence<String> = sequence {
|
|
||||||
when (val json = this@countTypes) {
|
|
||||||
is JsonObject -> {
|
|
||||||
json["_typename"]?.let { yield(it.jsonPrimitive.content) }
|
|
||||||
json.values.forEach { yieldAll(it.countTypes()) }
|
|
||||||
}
|
|
||||||
is JsonArray -> {
|
|
||||||
json.forEach {
|
|
||||||
yieldAll(it.countTypes())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else -> {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun Meta.countTypes() :Sequence<String> = sequence {
|
|
||||||
if(!isLeaf){
|
|
||||||
get("_typename")?.value?.let { yield(it.string) }
|
|
||||||
items.forEach { yieldAll(it.value.countTypes()) }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fun main() {
|
|
||||||
val string = TGeoManager::class.java.getResourceAsStream("/BM@N.root.json")!!
|
|
||||||
.readAllBytes().decodeToString()
|
|
||||||
val time = measureTimeMillis {
|
|
||||||
val geo = DGeoManager.parse(string)
|
|
||||||
|
|
||||||
val sizes = geo.meta.countTypes().groupBy { it }.mapValues { it.value.size }
|
|
||||||
sizes.forEach {
|
|
||||||
println(it)
|
|
||||||
}
|
|
||||||
|
|
||||||
val solid = geo.toSolid()
|
|
||||||
|
|
||||||
Paths.get("BM@N.vf.json").writeText(Solids.encodeToString(solid))
|
|
||||||
//println(Solids.encodeToString(solid))
|
|
||||||
}
|
|
||||||
|
|
||||||
// val json = Json.parseToJsonElement(string)
|
|
||||||
// val sizes = json.countTypes().groupBy { it }.mapValues { it.value.size }
|
|
||||||
// sizes.forEach {
|
|
||||||
// println(it)
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// val time = measureTimeMillis {
|
|
||||||
// val geo = TObject.decodeFromString(TGeoManager.serializer(), string)
|
|
||||||
// val solid = geo.toSolid()
|
|
||||||
//
|
|
||||||
// println(Solids.encodeToString(solid))
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
println(Duration.ofMillis(time))
|
|
||||||
}
|
|
@ -55,6 +55,7 @@ kotlin {
|
|||||||
api(project(":visionforge-gdml"))
|
api(project(":visionforge-gdml"))
|
||||||
api(project(":visionforge-plotly"))
|
api(project(":visionforge-plotly"))
|
||||||
api(projects.visionforge.visionforgeMarkdown)
|
api(projects.visionforge.visionforgeMarkdown)
|
||||||
|
api(projects.visionforge.cernRootLoader)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
104
demo/playground/src/jvmMain/kotlin/rootParser.kt
Normal file
104
demo/playground/src/jvmMain/kotlin/rootParser.kt
Normal file
@ -0,0 +1,104 @@
|
|||||||
|
package space.kscience.visionforge.examples
|
||||||
|
|
||||||
|
import ru.mipt.npm.root.DGeoManager
|
||||||
|
import ru.mipt.npm.root.serialization.TGeoManager
|
||||||
|
import ru.mipt.npm.root.toSolid
|
||||||
|
import space.kscience.dataforge.context.Context
|
||||||
|
import space.kscience.dataforge.meta.Meta
|
||||||
|
import space.kscience.dataforge.meta.get
|
||||||
|
import space.kscience.dataforge.meta.isLeaf
|
||||||
|
import space.kscience.dataforge.values.string
|
||||||
|
import space.kscience.visionforge.solid.Solids
|
||||||
|
|
||||||
|
|
||||||
|
private fun Meta.countTypes(): Sequence<String> = sequence {
|
||||||
|
if (!isLeaf) {
|
||||||
|
get("_typename")?.value?.let { yield(it.string) }
|
||||||
|
items.forEach { yieldAll(it.value.countTypes()) }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun main() {
|
||||||
|
val context = Context {
|
||||||
|
plugin(Solids)
|
||||||
|
}
|
||||||
|
|
||||||
|
val string = TGeoManager::class.java.getResourceAsStream("/root/BM@N.root.json")!!
|
||||||
|
.readAllBytes().decodeToString()
|
||||||
|
|
||||||
|
val geo = DGeoManager.parse(string)
|
||||||
|
|
||||||
|
|
||||||
|
val sizes = geo.meta.countTypes().groupBy { it }.mapValues { it.value.size }
|
||||||
|
sizes.forEach {
|
||||||
|
println(it)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
val solid = geo.toSolid()
|
||||||
|
|
||||||
|
//Paths.get("BM@N.vf.json").writeText(Solids.encodeToString(solid))
|
||||||
|
//println(Solids.encodeToString(solid))
|
||||||
|
|
||||||
|
context.makeVisionFile {
|
||||||
|
vision("canvas") {
|
||||||
|
solid
|
||||||
|
/* SolidGroup {
|
||||||
|
set(
|
||||||
|
"Coil",
|
||||||
|
solid.getPrototype("Coil".asName())!!.apply {
|
||||||
|
parent = null
|
||||||
|
}
|
||||||
|
)
|
||||||
|
*//* group("Shade") {
|
||||||
|
y = 200
|
||||||
|
color("red")
|
||||||
|
coneSurface(
|
||||||
|
bottomOuterRadius = 135,
|
||||||
|
bottomInnerRadius = 25,
|
||||||
|
height = 50,
|
||||||
|
topOuterRadius = 135,
|
||||||
|
topInnerRadius = 25,
|
||||||
|
angle = 1.5707964
|
||||||
|
) {
|
||||||
|
position = Point3D(79.6, 0, -122.1)
|
||||||
|
rotation = Point3D(-1.5707964, 0, 0)
|
||||||
|
}
|
||||||
|
coneSurface(
|
||||||
|
bottomOuterRadius = 135,
|
||||||
|
bottomInnerRadius = 25,
|
||||||
|
height = 50,
|
||||||
|
topOuterRadius = 135,
|
||||||
|
topInnerRadius = 25,
|
||||||
|
angle = 1.5707964
|
||||||
|
) {
|
||||||
|
position = Point3D(-79.6, 0, -122.1)
|
||||||
|
rotation = Point3D(1.5707964, 0, -3.1415927)
|
||||||
|
}
|
||||||
|
coneSurface(
|
||||||
|
bottomOuterRadius = 135,
|
||||||
|
bottomInnerRadius = 25,
|
||||||
|
height = 50,
|
||||||
|
topOuterRadius = 135,
|
||||||
|
topInnerRadius = 25,
|
||||||
|
angle = 1.5707964
|
||||||
|
) {
|
||||||
|
position = Point3D(79.6, 0, 122.1)
|
||||||
|
rotation = Point3D(1.5707964, 0, 0)
|
||||||
|
}
|
||||||
|
coneSurface(
|
||||||
|
bottomOuterRadius = 135,
|
||||||
|
bottomInnerRadius = 25,
|
||||||
|
height = 50,
|
||||||
|
topOuterRadius = 135,
|
||||||
|
topInnerRadius = 25,
|
||||||
|
angle = 1.5707964
|
||||||
|
) {
|
||||||
|
position = Point3D(-79.6, 0, 122.1)
|
||||||
|
rotation = Point3D(-1.5707964, 0, -3.1415927)
|
||||||
|
}
|
||||||
|
}*//*
|
||||||
|
}*/
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -48,7 +48,7 @@ public class FXCompositeFactory(public val plugin: FX3DPlugin) : FX3DFactory<Com
|
|||||||
val firstCSG = first.toCSG()
|
val firstCSG = first.toCSG()
|
||||||
val secondCSG = second.toCSG()
|
val secondCSG = second.toCSG()
|
||||||
val resultCSG = when (obj.compositeType) {
|
val resultCSG = when (obj.compositeType) {
|
||||||
CompositeType.SUM, CompositeType.UNION -> firstCSG.union(secondCSG)
|
CompositeType.GROUP, CompositeType.UNION -> firstCSG.union(secondCSG)
|
||||||
CompositeType.INTERSECT -> firstCSG.intersect(secondCSG)
|
CompositeType.INTERSECT -> firstCSG.intersect(secondCSG)
|
||||||
CompositeType.SUBTRACT -> firstCSG.difference(secondCSG)
|
CompositeType.SUBTRACT -> firstCSG.difference(secondCSG)
|
||||||
}
|
}
|
||||||
|
@ -215,12 +215,12 @@ private class GdmlLoader(val settings: GdmlLoaderOptions) {
|
|||||||
val first: GdmlSolid = solid.first.resolve(root) ?: error("")
|
val first: GdmlSolid = solid.first.resolve(root) ?: error("")
|
||||||
val second: GdmlSolid = solid.second.resolve(root) ?: error("")
|
val second: GdmlSolid = solid.second.resolve(root) ?: error("")
|
||||||
val type: CompositeType = when (solid) {
|
val type: CompositeType = when (solid) {
|
||||||
is GdmlUnion -> CompositeType.SUM // dumb sum for better performance
|
is GdmlUnion -> CompositeType.GROUP // dumb sum for better performance
|
||||||
is GdmlSubtraction -> CompositeType.SUBTRACT
|
is GdmlSubtraction -> CompositeType.SUBTRACT
|
||||||
is GdmlIntersection -> CompositeType.INTERSECT
|
is GdmlIntersection -> CompositeType.INTERSECT
|
||||||
}
|
}
|
||||||
|
|
||||||
return composite(type, name) {
|
return smartComposite(type, name) {
|
||||||
addSolid(root, first).withPosition(
|
addSolid(root, first).withPosition(
|
||||||
solid.resolveFirstPosition(root),
|
solid.resolveFirstPosition(root),
|
||||||
solid.resolveFirstRotation(root),
|
solid.resolveFirstRotation(root),
|
||||||
|
@ -2,6 +2,7 @@ package space.kscience.visionforge.solid
|
|||||||
|
|
||||||
import kotlinx.serialization.SerialName
|
import kotlinx.serialization.SerialName
|
||||||
import kotlinx.serialization.Serializable
|
import kotlinx.serialization.Serializable
|
||||||
|
import space.kscience.dataforge.meta.isEmpty
|
||||||
import space.kscience.dataforge.meta.update
|
import space.kscience.dataforge.meta.update
|
||||||
import space.kscience.visionforge.VisionBuilder
|
import space.kscience.visionforge.VisionBuilder
|
||||||
import space.kscience.visionforge.VisionContainerBuilder
|
import space.kscience.visionforge.VisionContainerBuilder
|
||||||
@ -9,7 +10,7 @@ import space.kscience.visionforge.VisionPropertyContainer
|
|||||||
import space.kscience.visionforge.set
|
import space.kscience.visionforge.set
|
||||||
|
|
||||||
public enum class CompositeType {
|
public enum class CompositeType {
|
||||||
SUM, // Dumb sum of meshes
|
GROUP, // Dumb sum of meshes
|
||||||
UNION, //CSG union
|
UNION, //CSG union
|
||||||
INTERSECT,
|
INTERSECT,
|
||||||
SUBTRACT
|
SUBTRACT
|
||||||
@ -50,6 +51,31 @@ public inline fun VisionContainerBuilder<Solid>.composite(
|
|||||||
return res
|
return res
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A smart form of [Composite] that in case of [CompositeType.GROUP] creates a static group instead
|
||||||
|
*/
|
||||||
|
@VisionBuilder
|
||||||
|
public fun SolidGroup.smartComposite(
|
||||||
|
type: CompositeType,
|
||||||
|
name: String? = null,
|
||||||
|
builder: SolidGroup.() -> Unit,
|
||||||
|
): Solid = if (type == CompositeType.GROUP) {
|
||||||
|
val group = SolidGroup(builder)
|
||||||
|
if (name == null && group.meta.isEmpty()) {
|
||||||
|
//append directly to group if no properties are defined
|
||||||
|
group.children.forEach { (key, value) ->
|
||||||
|
value.parent = null
|
||||||
|
set(null, value)
|
||||||
|
}
|
||||||
|
this
|
||||||
|
} else {
|
||||||
|
set(name, group)
|
||||||
|
group
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
composite(type, name, builder)
|
||||||
|
}
|
||||||
|
|
||||||
@VisionBuilder
|
@VisionBuilder
|
||||||
public inline fun VisionContainerBuilder<Solid>.union(
|
public inline fun VisionContainerBuilder<Solid>.union(
|
||||||
name: String? = null,
|
name: String? = null,
|
||||||
|
@ -82,8 +82,8 @@ public fun SolidGroup(block: SolidGroup.() -> Unit): SolidGroup {
|
|||||||
@VisionBuilder
|
@VisionBuilder
|
||||||
public fun VisionContainerBuilder<Vision>.group(
|
public fun VisionContainerBuilder<Vision>.group(
|
||||||
name: Name? = null,
|
name: Name? = null,
|
||||||
action: SolidGroup.() -> Unit = {},
|
builder: SolidGroup.() -> Unit = {},
|
||||||
): SolidGroup = SolidGroup().apply(action).also { set(name, it) }
|
): SolidGroup = SolidGroup().apply(builder).also { set(name, it) }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Define a group with given [name], attach it to this parent and return it.
|
* Define a group with given [name], attach it to this parent and return it.
|
||||||
|
@ -5,5 +5,5 @@ plugins {
|
|||||||
dependencies {
|
dependencies {
|
||||||
api(project(":visionforge-solid"))
|
api(project(":visionforge-solid"))
|
||||||
implementation(npm("three", "0.130.1"))
|
implementation(npm("three", "0.130.1"))
|
||||||
implementation(npm("three-csg-ts", "3.1.6"))
|
implementation(npm("three-csg-ts", "3.1.9"))
|
||||||
}
|
}
|
||||||
|
@ -273,18 +273,14 @@ public class ThreeCanvas(
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
if (this is Mesh) {
|
if (this is Mesh) {
|
||||||
if (highlight) {
|
val edges = getObjectByName(edgesName) ?: LineSegments(
|
||||||
val edges = LineSegments(
|
|
||||||
EdgesGeometry(geometry),
|
EdgesGeometry(geometry),
|
||||||
material
|
material
|
||||||
).apply {
|
).also {
|
||||||
name = edgesName
|
it.name = edgesName
|
||||||
}
|
add(it)
|
||||||
add(edges)
|
|
||||||
} else {
|
|
||||||
val highlightEdges = children.find { it.name == edgesName }
|
|
||||||
highlightEdges?.let { remove(it) }
|
|
||||||
}
|
}
|
||||||
|
edges.visible = highlight
|
||||||
} else {
|
} else {
|
||||||
children.filter { it.name != edgesName }.forEach {
|
children.filter { it.name != edgesName }.forEach {
|
||||||
it.toggleHighlight(highlight, edgesName, material)
|
it.toggleHighlight(highlight, edgesName, material)
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
package space.kscience.visionforge.solid.three
|
package space.kscience.visionforge.solid.three
|
||||||
|
|
||||||
import CSG
|
import CSG
|
||||||
import info.laht.threekt.core.Object3D
|
|
||||||
import info.laht.threekt.objects.Mesh
|
import info.laht.threekt.objects.Mesh
|
||||||
import space.kscience.dataforge.names.startsWith
|
import space.kscience.dataforge.names.startsWith
|
||||||
import space.kscience.visionforge.onPropertyChange
|
import space.kscience.visionforge.onPropertyChange
|
||||||
@ -38,11 +37,11 @@ public class ThreeCompositeFactory(public val three: ThreePlugin) : ThreeFactory
|
|||||||
|
|
||||||
override val type: KClass<in Composite> get() = Composite::class
|
override val type: KClass<in Composite> get() = Composite::class
|
||||||
|
|
||||||
override fun invoke(three: ThreePlugin, obj: Composite): Object3D {
|
override fun invoke(three: ThreePlugin, obj: Composite): Mesh {
|
||||||
val first = three.buildObject3D(obj.first) as? Mesh ?: error("First part of composite is not a mesh")
|
val first = three.buildObject3D(obj.first) as? Mesh ?: error("First part of composite is not a mesh")
|
||||||
val second = three.buildObject3D(obj.second) as? Mesh ?: error("Second part of composite is not a mesh")
|
val second = three.buildObject3D(obj.second) as? Mesh ?: error("Second part of composite is not a mesh")
|
||||||
return when (obj.compositeType) {
|
return when (obj.compositeType) {
|
||||||
CompositeType.SUM, CompositeType.UNION -> CSG.union(first, second)
|
CompositeType.GROUP, CompositeType.UNION -> CSG.union(first, second)
|
||||||
CompositeType.INTERSECT -> CSG.intersect(first, second)
|
CompositeType.INTERSECT -> CSG.intersect(first, second)
|
||||||
CompositeType.SUBTRACT -> CSG.subtract(first, second)
|
CompositeType.SUBTRACT -> CSG.subtract(first, second)
|
||||||
}.apply {
|
}.apply {
|
||||||
|
Loading…
Reference in New Issue
Block a user