diff --git a/ATTRIBUTION.md b/ATTRIBUTION.md index e6d5a0f..1db11fa 100644 --- a/ATTRIBUTION.md +++ b/ATTRIBUTION.md @@ -15,6 +15,106 @@ is committed and listed here with its exports. | File | Author | Source | Licence | |---|---|---|---| | crates/decks/tests/golden/nastran/*.bdf | ModelCraft contributors | Written by our Nastran writer from our own test models (crates/decks/tests/nastran.rs) | MIT OR Apache-2.0 | +| assets/icons/assembly.instance.svg, assets/icons/assembly.instance.vectorcraft | ModelCraft contributors | Original toolbar icon drawn with VectorCraft from `assets/icons/src/assembly.instance.json` (`cargo xtask icons`) | MIT OR Apache-2.0 | +| assets/icons/deck.read.svg, assets/icons/deck.read.vectorcraft | ModelCraft contributors | Original toolbar icon drawn with VectorCraft from `assets/icons/src/deck.read.json` (`cargo xtask icons`) | MIT OR Apache-2.0 | +| assets/icons/deck.write.abaqus.svg, assets/icons/deck.write.abaqus.vectorcraft | ModelCraft contributors | Original toolbar icon drawn with VectorCraft from `assets/icons/src/deck.write.abaqus.json` (`cargo xtask icons`) | MIT OR Apache-2.0 | +| assets/icons/deck.write.lsdyna.svg, assets/icons/deck.write.lsdyna.vectorcraft | ModelCraft contributors | Original toolbar icon drawn with VectorCraft from `assets/icons/src/deck.write.lsdyna.json` (`cargo xtask icons`) | MIT OR Apache-2.0 | +| assets/icons/deck.write.nastran.svg, assets/icons/deck.write.nastran.vectorcraft | ModelCraft contributors | Original toolbar icon drawn with VectorCraft from `assets/icons/src/deck.write.nastran.json` (`cargo xtask icons`) | MIT OR Apache-2.0 | +| assets/icons/edit.redo.svg, assets/icons/edit.redo.vectorcraft | ModelCraft contributors | Original toolbar icon drawn with VectorCraft from `assets/icons/src/edit.redo.json` (`cargo xtask icons`) | MIT OR Apache-2.0 | +| assets/icons/edit.undo.svg, assets/icons/edit.undo.vectorcraft | ModelCraft contributors | Original toolbar icon drawn with VectorCraft from `assets/icons/src/edit.undo.json` (`cargo xtask icons`) | MIT OR Apache-2.0 | +| assets/icons/file.open.svg, assets/icons/file.open.vectorcraft | ModelCraft contributors | Original toolbar icon drawn with VectorCraft from `assets/icons/src/file.open.json` (`cargo xtask icons`) | MIT OR Apache-2.0 | +| assets/icons/file.recover.svg, assets/icons/file.recover.vectorcraft | ModelCraft contributors | Original toolbar icon drawn with VectorCraft from `assets/icons/src/file.recover.json` (`cargo xtask icons`) | MIT OR Apache-2.0 | +| assets/icons/file.save_as.svg, assets/icons/file.save_as.vectorcraft | ModelCraft contributors | Original toolbar icon drawn with VectorCraft from `assets/icons/src/file.save_as.json` (`cargo xtask icons`) | MIT OR Apache-2.0 | +| assets/icons/file.save.svg, assets/icons/file.save.vectorcraft | ModelCraft contributors | Original toolbar icon drawn with VectorCraft from `assets/icons/src/file.save.json` (`cargo xtask icons`) | MIT OR Apache-2.0 | +| assets/icons/flow.boundary.svg, assets/icons/flow.boundary.vectorcraft | ModelCraft contributors | Original toolbar icon drawn with VectorCraft from `assets/icons/src/flow.boundary.json` (`cargo xtask icons`) | MIT OR Apache-2.0 | +| assets/icons/flow.domain.svg, assets/icons/flow.domain.vectorcraft | ModelCraft contributors | Original toolbar icon drawn with VectorCraft from `assets/icons/src/flow.domain.json` (`cargo xtask icons`) | MIT OR Apache-2.0 | +| assets/icons/geometry.bodies.svg, assets/icons/geometry.bodies.vectorcraft | ModelCraft contributors | Original toolbar icon drawn with VectorCraft from `assets/icons/src/geometry.bodies.json` (`cargo xtask icons`) | MIT OR Apache-2.0 | +| assets/icons/geometry.datum.svg, assets/icons/geometry.datum.vectorcraft | ModelCraft contributors | Original toolbar icon drawn with VectorCraft from `assets/icons/src/geometry.datum.json` (`cargo xtask icons`) | MIT OR Apache-2.0 | +| assets/icons/geometry.import.mesh.svg, assets/icons/geometry.import.mesh.vectorcraft | ModelCraft contributors | Original toolbar icon drawn with VectorCraft from `assets/icons/src/geometry.import.mesh.json` (`cargo xtask icons`) | MIT OR Apache-2.0 | +| assets/icons/geometry.midsurface.svg, assets/icons/geometry.midsurface.vectorcraft | ModelCraft contributors | Original toolbar icon drawn with VectorCraft from `assets/icons/src/geometry.midsurface.json` (`cargo xtask icons`) | MIT OR Apache-2.0 | +| assets/icons/geometry.open.svg, assets/icons/geometry.open.vectorcraft | ModelCraft contributors | Original toolbar icon drawn with VectorCraft from `assets/icons/src/geometry.open.json` (`cargo xtask icons`) | MIT OR Apache-2.0 | +| assets/icons/geometry.partition.svg, assets/icons/geometry.partition.vectorcraft | ModelCraft contributors | Original toolbar icon drawn with VectorCraft from `assets/icons/src/geometry.partition.json` (`cargo xtask icons`) | MIT OR Apache-2.0 | +| assets/icons/geometry.tessellate.svg, assets/icons/geometry.tessellate.vectorcraft | ModelCraft contributors | Original toolbar icon drawn with VectorCraft from `assets/icons/src/geometry.tessellate.json` (`cargo xtask icons`) | MIT OR Apache-2.0 | +| assets/icons/interaction.bolt.svg, assets/icons/interaction.bolt.vectorcraft | ModelCraft contributors | Original toolbar icon drawn with VectorCraft from `assets/icons/src/interaction.bolt.json` (`cargo xtask icons`) | MIT OR Apache-2.0 | +| assets/icons/interaction.connector.svg, assets/icons/interaction.connector.vectorcraft | ModelCraft contributors | Original toolbar icon drawn with VectorCraft from `assets/icons/src/interaction.connector.json` (`cargo xtask icons`) | MIT OR Apache-2.0 | +| assets/icons/interaction.contact.find.svg, assets/icons/interaction.contact.find.vectorcraft | ModelCraft contributors | Original toolbar icon drawn with VectorCraft from `assets/icons/src/interaction.contact.find.json` (`cargo xtask icons`) | MIT OR Apache-2.0 | +| assets/icons/interaction.contact.general.svg, assets/icons/interaction.contact.general.vectorcraft | ModelCraft contributors | Original toolbar icon drawn with VectorCraft from `assets/icons/src/interaction.contact.general.json` (`cargo xtask icons`) | MIT OR Apache-2.0 | +| assets/icons/interaction.contact.pair.svg, assets/icons/interaction.contact.pair.vectorcraft | ModelCraft contributors | Original toolbar icon drawn with VectorCraft from `assets/icons/src/interaction.contact.pair.json` (`cargo xtask icons`) | MIT OR Apache-2.0 | +| assets/icons/interaction.fsi.svg, assets/icons/interaction.fsi.vectorcraft | ModelCraft contributors | Original toolbar icon drawn with VectorCraft from `assets/icons/src/interaction.fsi.json` (`cargo xtask icons`) | MIT OR Apache-2.0 | +| assets/icons/interaction.mass.svg, assets/icons/interaction.mass.vectorcraft | ModelCraft contributors | Original toolbar icon drawn with VectorCraft from `assets/icons/src/interaction.mass.json` (`cargo xtask icons`) | MIT OR Apache-2.0 | +| assets/icons/interaction.rigid_wall.svg, assets/icons/interaction.rigid_wall.vectorcraft | ModelCraft contributors | Original toolbar icon drawn with VectorCraft from `assets/icons/src/interaction.rigid_wall.json` (`cargo xtask icons`) | MIT OR Apache-2.0 | +| assets/icons/interaction.spring.svg, assets/icons/interaction.spring.vectorcraft | ModelCraft contributors | Original toolbar icon drawn with VectorCraft from `assets/icons/src/interaction.spring.json` (`cargo xtask icons`) | MIT OR Apache-2.0 | +| assets/icons/interaction.tie.svg, assets/icons/interaction.tie.vectorcraft | ModelCraft contributors | Original toolbar icon drawn with VectorCraft from `assets/icons/src/interaction.tie.json` (`cargo xtask icons`) | MIT OR Apache-2.0 | +| assets/icons/mesh.delaunay.points.svg, assets/icons/mesh.delaunay.points.vectorcraft | ModelCraft contributors | Original toolbar icon drawn with VectorCraft from `assets/icons/src/mesh.delaunay.points.json` (`cargo xtask icons`) | MIT OR Apache-2.0 | +| assets/icons/mesh.element.add.svg, assets/icons/mesh.element.add.vectorcraft | ModelCraft contributors | Original toolbar icon drawn with VectorCraft from `assets/icons/src/mesh.element.add.json` (`cargo xtask icons`) | MIT OR Apache-2.0 | +| assets/icons/mesh.hex.decompose.svg, assets/icons/mesh.hex.decompose.vectorcraft | ModelCraft contributors | Original toolbar icon drawn with VectorCraft from `assets/icons/src/mesh.hex.decompose.json` (`cargo xtask icons`) | MIT OR Apache-2.0 | +| assets/icons/mesh.hex.dominant.svg, assets/icons/mesh.hex.dominant.vectorcraft | ModelCraft contributors | Original toolbar icon drawn with VectorCraft from `assets/icons/src/mesh.hex.dominant.json` (`cargo xtask icons`) | MIT OR Apache-2.0 | +| assets/icons/mesh.hex.generate.svg, assets/icons/mesh.hex.generate.vectorcraft | ModelCraft contributors | Original toolbar icon drawn with VectorCraft from `assets/icons/src/mesh.hex.generate.json` (`cargo xtask icons`) | MIT OR Apache-2.0 | +| assets/icons/mesh.hex.mapped.svg, assets/icons/mesh.hex.mapped.vectorcraft | ModelCraft contributors | Original toolbar icon drawn with VectorCraft from `assets/icons/src/mesh.hex.mapped.json` (`cargo xtask icons`) | MIT OR Apache-2.0 | +| assets/icons/mesh.hex.polycube.svg, assets/icons/mesh.hex.polycube.vectorcraft | ModelCraft contributors | Original toolbar icon drawn with VectorCraft from `assets/icons/src/mesh.hex.polycube.json` (`cargo xtask icons`) | MIT OR Apache-2.0 | +| assets/icons/mesh.hex.sweep.svg, assets/icons/mesh.hex.sweep.vectorcraft | ModelCraft contributors | Original toolbar icon drawn with VectorCraft from `assets/icons/src/mesh.hex.sweep.json` (`cargo xtask icons`) | MIT OR Apache-2.0 | +| assets/icons/mesh.import.orphan.svg, assets/icons/mesh.import.orphan.vectorcraft | ModelCraft contributors | Original toolbar icon drawn with VectorCraft from `assets/icons/src/mesh.import.orphan.json` (`cargo xtask icons`) | MIT OR Apache-2.0 | +| assets/icons/mesh.layers.svg, assets/icons/mesh.layers.vectorcraft | ModelCraft contributors | Original toolbar icon drawn with VectorCraft from `assets/icons/src/mesh.layers.json` (`cargo xtask icons`) | MIT OR Apache-2.0 | +| assets/icons/mesh.node.add.svg, assets/icons/mesh.node.add.vectorcraft | ModelCraft contributors | Original toolbar icon drawn with VectorCraft from `assets/icons/src/mesh.node.add.json` (`cargo xtask icons`) | MIT OR Apache-2.0 | +| assets/icons/mesh.node.merge.svg, assets/icons/mesh.node.merge.vectorcraft | ModelCraft contributors | Original toolbar icon drawn with VectorCraft from `assets/icons/src/mesh.node.merge.json` (`cargo xtask icons`) | MIT OR Apache-2.0 | +| assets/icons/mesh.order.quadratic.svg, assets/icons/mesh.order.quadratic.vectorcraft | ModelCraft contributors | Original toolbar icon drawn with VectorCraft from `assets/icons/src/mesh.order.quadratic.json` (`cargo xtask icons`) | MIT OR Apache-2.0 | +| assets/icons/mesh.quad.faces.svg, assets/icons/mesh.quad.faces.vectorcraft | ModelCraft contributors | Original toolbar icon drawn with VectorCraft from `assets/icons/src/mesh.quad.faces.json` (`cargo xtask icons`) | MIT OR Apache-2.0 | +| assets/icons/mesh.quality.svg, assets/icons/mesh.quality.vectorcraft | ModelCraft contributors | Original toolbar icon drawn with VectorCraft from `assets/icons/src/mesh.quality.json` (`cargo xtask icons`) | MIT OR Apache-2.0 | +| assets/icons/mesh.region.remesh.svg, assets/icons/mesh.region.remesh.vectorcraft | ModelCraft contributors | Original toolbar icon drawn with VectorCraft from `assets/icons/src/mesh.region.remesh.json` (`cargo xtask icons`) | MIT OR Apache-2.0 | +| assets/icons/mesh.size.adapt.svg, assets/icons/mesh.size.adapt.vectorcraft | ModelCraft contributors | Original toolbar icon drawn with VectorCraft from `assets/icons/src/mesh.size.adapt.json` (`cargo xtask icons`) | MIT OR Apache-2.0 | +| assets/icons/mesh.size.global.svg, assets/icons/mesh.size.global.vectorcraft | ModelCraft contributors | Original toolbar icon drawn with VectorCraft from `assets/icons/src/mesh.size.global.json` (`cargo xtask icons`) | MIT OR Apache-2.0 | +| assets/icons/mesh.size.seed.svg, assets/icons/mesh.size.seed.vectorcraft | ModelCraft contributors | Original toolbar icon drawn with VectorCraft from `assets/icons/src/mesh.size.seed.json` (`cargo xtask icons`) | MIT OR Apache-2.0 | +| assets/icons/mesh.smooth.svg, assets/icons/mesh.smooth.vectorcraft | ModelCraft contributors | Original toolbar icon drawn with VectorCraft from `assets/icons/src/mesh.smooth.json` (`cargo xtask icons`) | MIT OR Apache-2.0 | +| assets/icons/mesh.surface.check.svg, assets/icons/mesh.surface.check.vectorcraft | ModelCraft contributors | Original toolbar icon drawn with VectorCraft from `assets/icons/src/mesh.surface.check.json` (`cargo xtask icons`) | MIT OR Apache-2.0 | +| assets/icons/mesh.tag.svg, assets/icons/mesh.tag.vectorcraft | ModelCraft contributors | Original toolbar icon drawn with VectorCraft from `assets/icons/src/mesh.tag.json` (`cargo xtask icons`) | MIT OR Apache-2.0 | +| assets/icons/mesh.tet.generate.svg, assets/icons/mesh.tet.generate.vectorcraft | ModelCraft contributors | Original toolbar icon drawn with VectorCraft from `assets/icons/src/mesh.tet.generate.json` (`cargo xtask icons`) | MIT OR Apache-2.0 | +| assets/icons/mesh.transition.svg, assets/icons/mesh.transition.vectorcraft | ModelCraft contributors | Original toolbar icon drawn with VectorCraft from `assets/icons/src/mesh.transition.json` (`cargo xtask icons`) | MIT OR Apache-2.0 | +| assets/icons/mesh.untangle.svg, assets/icons/mesh.untangle.vectorcraft | ModelCraft contributors | Original toolbar icon drawn with VectorCraft from `assets/icons/src/mesh.untangle.json` (`cargo xtask icons`) | MIT OR Apache-2.0 | +| assets/icons/mesh.verify.svg, assets/icons/mesh.verify.vectorcraft | ModelCraft contributors | Original toolbar icon drawn with VectorCraft from `assets/icons/src/mesh.verify.json` (`cargo xtask icons`) | MIT OR Apache-2.0 | +| assets/icons/model.activity.svg, assets/icons/model.activity.vectorcraft | ModelCraft contributors | Original toolbar icon drawn with VectorCraft from `assets/icons/src/model.activity.json` (`cargo xtask icons`) | MIT OR Apache-2.0 | +| assets/icons/model.amplitude.svg, assets/icons/model.amplitude.vectorcraft | ModelCraft contributors | Original toolbar icon drawn with VectorCraft from `assets/icons/src/model.amplitude.json` (`cargo xtask icons`) | MIT OR Apache-2.0 | +| assets/icons/model.boundary_condition.create.svg, assets/icons/model.boundary_condition.create.vectorcraft | ModelCraft contributors | Original toolbar icon drawn with VectorCraft from `assets/icons/src/model.boundary_condition.create.json` (`cargo xtask icons`) | MIT OR Apache-2.0 | +| assets/icons/model.check.svg, assets/icons/model.check.vectorcraft | ModelCraft contributors | Original toolbar icon drawn with VectorCraft from `assets/icons/src/model.check.json` (`cargo xtask icons`) | MIT OR Apache-2.0 | +| assets/icons/model.coupling.create.svg, assets/icons/model.coupling.create.vectorcraft | ModelCraft contributors | Original toolbar icon drawn with VectorCraft from `assets/icons/src/model.coupling.create.json` (`cargo xtask icons`) | MIT OR Apache-2.0 | +| assets/icons/model.info.svg, assets/icons/model.info.vectorcraft | ModelCraft contributors | Original toolbar icon drawn with VectorCraft from `assets/icons/src/model.info.json` (`cargo xtask icons`) | MIT OR Apache-2.0 | +| assets/icons/model.load.create.svg, assets/icons/model.load.create.vectorcraft | ModelCraft contributors | Original toolbar icon drawn with VectorCraft from `assets/icons/src/model.load.create.json` (`cargo xtask icons`) | MIT OR Apache-2.0 | +| assets/icons/model.material.create.svg, assets/icons/model.material.create.vectorcraft | ModelCraft contributors | Original toolbar icon drawn with VectorCraft from `assets/icons/src/model.material.create.json` (`cargo xtask icons`) | MIT OR Apache-2.0 | +| assets/icons/model.material.damage.svg, assets/icons/model.material.damage.vectorcraft | ModelCraft contributors | Original toolbar icon drawn with VectorCraft from `assets/icons/src/model.material.damage.json` (`cargo xtask icons`) | MIT OR Apache-2.0 | +| assets/icons/model.material.eos.svg, assets/icons/model.material.eos.vectorcraft | ModelCraft contributors | Original toolbar icon drawn with VectorCraft from `assets/icons/src/model.material.eos.json` (`cargo xtask icons`) | MIT OR Apache-2.0 | +| assets/icons/model.material.hyperelastic.svg, assets/icons/model.material.hyperelastic.vectorcraft | ModelCraft contributors | Original toolbar icon drawn with VectorCraft from `assets/icons/src/model.material.hyperelastic.json` (`cargo xtask icons`) | MIT OR Apache-2.0 | +| assets/icons/model.material.plasticity.svg, assets/icons/model.material.plasticity.vectorcraft | ModelCraft contributors | Original toolbar icon drawn with VectorCraft from `assets/icons/src/model.material.plasticity.json` (`cargo xtask icons`) | MIT OR Apache-2.0 | +| assets/icons/model.material.thermal.svg, assets/icons/model.material.thermal.vectorcraft | ModelCraft contributors | Original toolbar icon drawn with VectorCraft from `assets/icons/src/model.material.thermal.json` (`cargo xtask icons`) | MIT OR Apache-2.0 | +| assets/icons/model.orientation.svg, assets/icons/model.orientation.vectorcraft | ModelCraft contributors | Original toolbar icon drawn with VectorCraft from `assets/icons/src/model.orientation.json` (`cargo xtask icons`) | MIT OR Apache-2.0 | +| assets/icons/model.reference_point.create.svg, assets/icons/model.reference_point.create.vectorcraft | ModelCraft contributors | Original toolbar icon drawn with VectorCraft from `assets/icons/src/model.reference_point.create.json` (`cargo xtask icons`) | MIT OR Apache-2.0 | +| assets/icons/model.section.composite.svg, assets/icons/model.section.composite.vectorcraft | ModelCraft contributors | Original toolbar icon drawn with VectorCraft from `assets/icons/src/model.section.composite.json` (`cargo xtask icons`) | MIT OR Apache-2.0 | +| assets/icons/model.section.create.svg, assets/icons/model.section.create.vectorcraft | ModelCraft contributors | Original toolbar icon drawn with VectorCraft from `assets/icons/src/model.section.create.json` (`cargo xtask icons`) | MIT OR Apache-2.0 | +| assets/icons/model.set.create.svg, assets/icons/model.set.create.vectorcraft | ModelCraft contributors | Original toolbar icon drawn with VectorCraft from `assets/icons/src/model.set.create.json` (`cargo xtask icons`) | MIT OR Apache-2.0 | +| assets/icons/model.step.activate.svg, assets/icons/model.step.activate.vectorcraft | ModelCraft contributors | Original toolbar icon drawn with VectorCraft from `assets/icons/src/model.step.activate.json` (`cargo xtask icons`) | MIT OR Apache-2.0 | +| assets/icons/model.step.create.svg, assets/icons/model.step.create.vectorcraft | ModelCraft contributors | Original toolbar icon drawn with VectorCraft from `assets/icons/src/model.step.create.json` (`cargo xtask icons`) | MIT OR Apache-2.0 | +| assets/icons/model.step.explicit.svg, assets/icons/model.step.explicit.vectorcraft | ModelCraft contributors | Original toolbar icon drawn with VectorCraft from `assets/icons/src/model.step.explicit.json` (`cargo xtask icons`) | MIT OR Apache-2.0 | +| assets/icons/model.step.heat.svg, assets/icons/model.step.heat.vectorcraft | ModelCraft contributors | Original toolbar icon drawn with VectorCraft from `assets/icons/src/model.step.heat.json` (`cargo xtask icons`) | MIT OR Apache-2.0 | +| assets/icons/model.step.nonlinear.svg, assets/icons/model.step.nonlinear.vectorcraft | ModelCraft contributors | Original toolbar icon drawn with VectorCraft from `assets/icons/src/model.step.nonlinear.json` (`cargo xtask icons`) | MIT OR Apache-2.0 | +| assets/icons/model.units.svg, assets/icons/model.units.vectorcraft | ModelCraft contributors | Original toolbar icon drawn with VectorCraft from `assets/icons/src/model.units.json` (`cargo xtask icons`) | MIT OR Apache-2.0 | +| assets/icons/results.animate.svg, assets/icons/results.animate.vectorcraft | ModelCraft contributors | Original toolbar icon drawn with VectorCraft from `assets/icons/src/results.animate.json` (`cargo xtask icons`) | MIT OR Apache-2.0 | +| assets/icons/results.contour.svg, assets/icons/results.contour.vectorcraft | ModelCraft contributors | Original toolbar icon drawn with VectorCraft from `assets/icons/src/results.contour.json` (`cargo xtask icons`) | MIT OR Apache-2.0 | +| assets/icons/results.convergence.svg, assets/icons/results.convergence.vectorcraft | ModelCraft contributors | Original toolbar icon drawn with VectorCraft from `assets/icons/src/results.convergence.json` (`cargo xtask icons`) | MIT OR Apache-2.0 | +| assets/icons/results.cut.svg, assets/icons/results.cut.vectorcraft | ModelCraft contributors | Original toolbar icon drawn with VectorCraft from `assets/icons/src/results.cut.json` (`cargo xtask icons`) | MIT OR Apache-2.0 | +| assets/icons/results.deformed.svg, assets/icons/results.deformed.vectorcraft | ModelCraft contributors | Original toolbar icon drawn with VectorCraft from `assets/icons/src/results.deformed.json` (`cargo xtask icons`) | MIT OR Apache-2.0 | +| assets/icons/results.display_group.svg, assets/icons/results.display_group.vectorcraft | ModelCraft contributors | Original toolbar icon drawn with VectorCraft from `assets/icons/src/results.display_group.json` (`cargo xtask icons`) | MIT OR Apache-2.0 | +| assets/icons/results.free_body.svg, assets/icons/results.free_body.vectorcraft | ModelCraft contributors | Original toolbar icon drawn with VectorCraft from `assets/icons/src/results.free_body.json` (`cargo xtask icons`) | MIT OR Apache-2.0 | +| assets/icons/results.modes.svg, assets/icons/results.modes.vectorcraft | ModelCraft contributors | Original toolbar icon drawn with VectorCraft from `assets/icons/src/results.modes.json` (`cargo xtask icons`) | MIT OR Apache-2.0 | +| assets/icons/results.path.svg, assets/icons/results.path.vectorcraft | ModelCraft contributors | Original toolbar icon drawn with VectorCraft from `assets/icons/src/results.path.json` (`cargo xtask icons`) | MIT OR Apache-2.0 | +| assets/icons/solve.probe.svg, assets/icons/solve.probe.vectorcraft | ModelCraft contributors | Original toolbar icon drawn with VectorCraft from `assets/icons/src/solve.probe.json` (`cargo xtask icons`) | MIT OR Apache-2.0 | +| assets/icons/results.reactions.svg, assets/icons/results.reactions.vectorcraft | ModelCraft contributors | Original toolbar icon drawn with VectorCraft from `assets/icons/src/results.reactions.json` (`cargo xtask icons`) | MIT OR Apache-2.0 | +| assets/icons/results.read.svg, assets/icons/results.read.vectorcraft | ModelCraft contributors | Original toolbar icon drawn with VectorCraft from `assets/icons/src/results.read.json` (`cargo xtask icons`) | MIT OR Apache-2.0 | +| assets/icons/results.streamlines.svg, assets/icons/results.streamlines.vectorcraft | ModelCraft contributors | Original toolbar icon drawn with VectorCraft from `assets/icons/src/results.streamlines.json` (`cargo xtask icons`) | MIT OR Apache-2.0 | +| assets/icons/results.xy.svg, assets/icons/results.xy.vectorcraft | ModelCraft contributors | Original toolbar icon drawn with VectorCraft from `assets/icons/src/results.xy.json` (`cargo xtask icons`) | MIT OR Apache-2.0 | +| assets/icons/solve.blast.svg, assets/icons/solve.blast.vectorcraft | ModelCraft contributors | Original toolbar icon drawn with VectorCraft from `assets/icons/src/solve.blast.json` (`cargo xtask icons`) | MIT OR Apache-2.0 | +| assets/icons/solve.explicit.svg, assets/icons/solve.explicit.vectorcraft | ModelCraft contributors | Original toolbar icon drawn with VectorCraft from `assets/icons/src/solve.explicit.json` (`cargo xtask icons`) | MIT OR Apache-2.0 | +| assets/icons/solve.flow.svg, assets/icons/solve.flow.vectorcraft | ModelCraft contributors | Original toolbar icon drawn with VectorCraft from `assets/icons/src/solve.flow.json` (`cargo xtask icons`) | MIT OR Apache-2.0 | +| assets/icons/solve.frequency.svg, assets/icons/solve.frequency.vectorcraft | ModelCraft contributors | Original toolbar icon drawn with VectorCraft from `assets/icons/src/solve.frequency.json` (`cargo xtask icons`) | MIT OR Apache-2.0 | +| assets/icons/solve.fsi.svg, assets/icons/solve.fsi.vectorcraft | ModelCraft contributors | Original toolbar icon drawn with VectorCraft from `assets/icons/src/solve.fsi.json` (`cargo xtask icons`) | MIT OR Apache-2.0 | +| assets/icons/solve.static.svg, assets/icons/solve.static.vectorcraft | ModelCraft contributors | Original toolbar icon drawn with VectorCraft from `assets/icons/src/solve.static.json` (`cargo xtask icons`) | MIT OR Apache-2.0 | ## Adapted code @@ -25,7 +125,7 @@ is committed and listed here with its exports. | clippy.toml, rustfmt.toml | SolidCraft | MIT OR Apache-2.0 | | crates/geometry/src/tagged_mesh.rs (package and part reading, transforms, units, caps) | SolidCraft `crates/io/src/threemf.rs` | MIT OR Apache-2.0 | | crates/render/src/camera.rs, crates/render/src/raster.rs | SolidCraft `crates/render/src/camera.rs`, `raster.rs` | MIT OR Apache-2.0 | -| crates/ui-egui/src/gpu.rs, crates/ui-egui/src/theme.rs, crates/ui-egui/src/control.rs, crates/ui-egui/src/lib.rs (input injection, screenshots) | SolidCraft `crates/ui-egui/src/` | MIT OR Apache-2.0 | +| crates/ui-egui/src/gpu.rs, crates/ui-egui/src/theme.rs, crates/ui-egui/src/control.rs, crates/ui-egui/src/lib.rs (input injection, screenshots), crates/ui-egui/src/toolbar.rs (tabs of panels of buttons) | SolidCraft `crates/ui-egui/src/` | MIT OR Apache-2.0 | | crates/io/src/fs.rs (atomic writes) | SolidCraft `crates/io/src/safe_write.rs` | MIT OR Apache-2.0 | | crates/io/src/recovery.rs (recovery folder, entries, locks) | SolidCraft `crates/engine/src/recovery.rs` | MIT OR Apache-2.0 | | apps/modelcraft/src/control_server.rs | SolidCraft `apps/solidcraft/src/control_server.rs` | MIT OR Apache-2.0 | diff --git a/Cargo.lock b/Cargo.lock index b5f52d9..2de351c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -218,6 +218,12 @@ version = "2.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "220a2c618ab466efe41d0eace94dfeff1c35e3aa47891bdb95e1c0fefffd3c99" +[[package]] +name = "arrayref" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76a2e8124351fda1ef8aaaa3bbd7ebbcb486bbcd4225aca0aa0d84bb2db8fecb" + [[package]] name = "arrayvec" version = "0.7.8" @@ -799,6 +805,12 @@ version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f27ae1dd37df86211c42e150270f82743308803d90a6f6e6651cd730d5e1732f" +[[package]] +name = "data-url" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "be1e0bca6c3637f992fc1cc7cbc52a78c1ef6db076dbf1059c4323d6a2048376" + [[package]] name = "derive_arbitrary" version = "1.5.0" @@ -1084,7 +1096,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb" dependencies = [ "libc", - "windows-sys 0.60.2", + "windows-sys 0.61.2", ] [[package]] @@ -1166,6 +1178,12 @@ dependencies = [ "zlib-rs", ] +[[package]] +name = "float-cmp" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "98de4bbd547a563b716d8dfa9aad1cb19bfab00f4fa09a6a4ed21dbcf44ce9c4" + [[package]] name = "foldhash" version = "0.2.0" @@ -1541,6 +1559,12 @@ dependencies = [ "tiff", ] +[[package]] +name = "imagesize" +version = "0.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "65b27460c2c92b037f3f94c538ed9a3342f3fdf923606781629ccb35f82d042a" + [[package]] name = "indexmap" version = "2.14.2" @@ -1965,6 +1989,7 @@ dependencies = [ "modelcraft-engine", "modelcraft-model", "modelcraft-render", + "resvg", "serde", "serde_json", ] @@ -2560,6 +2585,12 @@ dependencies = [ "siphasher", ] +[[package]] +name = "pico-args" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5be167a7af36ee22fe3115051bc51f6e6c7054c9348e28deb4f49bd6f705a315" + [[package]] name = "pin-project" version = "1.1.13" @@ -2898,12 +2929,45 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "19b30a45b0cd0bcca8037f3d0dc3421eaf95327a17cad11964fb8179b4fc4832" +[[package]] +name = "resvg" +version = "0.48.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67e3803f97b999e80cbf7c6ecdd07a8102204d92e1633cf48783720c521196bd" +dependencies = [ + "bytemuck", + "log", + "pico-args", + "rgb", + "svgtypes", + "tiny-skia", + "usvg", +] + +[[package]] +name = "rgb" +version = "0.8.53" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "47b34b781b31e5d73e9fbc8689c70551fd1ade9a19e3e28cfec8580a79290cc4" +dependencies = [ + "bytemuck", +] + [[package]] name = "robust" version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4e27ee8bb91ca0adcf0ecb116293afa12d393f9c2b9b9cd54d33e8078fe19839" +[[package]] +name = "roxmltree" +version = "0.21.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1964b10c76125c36f8afe190065a4bf9a87bf324842c05701330bba9f1cacbb" +dependencies = [ + "memchr", +] + [[package]] name = "rustc-hash" version = "1.1.0" @@ -2948,7 +3012,7 @@ dependencies = [ "errno", "libc", "linux-raw-sys 0.12.1", - "windows-sys 0.60.2", + "windows-sys 0.61.2", ] [[package]] @@ -3093,6 +3157,15 @@ version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e3a9fe34e3e7a50316060351f37187a3f546bce95496156754b601a5fa71b76e" +[[package]] +name = "simplecss" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a9c6883ca9c3c7c90e888de77b7a5c849c779d25d74a1269b0218b14e8b136c" +dependencies = [ + "log", +] + [[package]] name = "siphasher" version = "1.0.4" @@ -3325,6 +3398,25 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" +[[package]] +name = "strict-num" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6637bab7722d379c8b41ba849228d680cc12d0a45ba1fa2b48f2a30577a06731" +dependencies = [ + "float-cmp", +] + +[[package]] +name = "svgtypes" +version = "0.16.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "695b5790b3131dafa99b3bbfd25a216edb3d216dad9ca208d4657bfb8f2abc3d" +dependencies = [ + "kurbo", + "siphasher", +] + [[package]] name = "syn" version = "1.0.109" @@ -3367,7 +3459,7 @@ dependencies = [ "getrandom 0.4.3", "once_cell", "rustix 1.1.5", - "windows-sys 0.60.2", + "windows-sys 0.61.2", ] [[package]] @@ -3433,6 +3525,32 @@ dependencies = [ "zune-jpeg", ] +[[package]] +name = "tiny-skia" +version = "0.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "47ffee5eaaf5527f630fb0e356b90ebdec84d5d18d937c5e440350f88c5a91ea" +dependencies = [ + "arrayref", + "arrayvec", + "bytemuck", + "cfg-if", + "log", + "png", + "tiny-skia-path", +] + +[[package]] +name = "tiny-skia-path" +version = "0.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "edca365c3faccca67d06593c5980fa6c57687de727a03131735bb85f01fdeeb9" +dependencies = [ + "arrayref", + "bytemuck", + "strict-num", +] + [[package]] name = "tokio" version = "1.53.2" @@ -3675,7 +3793,7 @@ checksum = "f2f6fb2847f6742cd76af783a2a2c49e9375d0a111c7bef6f71cd9e738c72d6e" dependencies = [ "memoffset", "tempfile", - "windows-sys 0.60.2", + "windows-sys 0.61.2", ] [[package]] @@ -3702,6 +3820,25 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b4ac048d71ede7ee76d585517add45da530660ef4390e49b098733c6e897f254" +[[package]] +name = "usvg" +version = "0.48.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "977d0a4abdef933f424a99fe09f95576e089b90aebc6f016a3bc813762493e91" +dependencies = [ + "data-url", + "imagesize", + "kurbo", + "log", + "pico-args", + "roxmltree", + "simplecss", + "siphasher", + "strict-num", + "svgtypes", + "tiny-skia-path", +] + [[package]] name = "uuid" version = "1.28.0" @@ -4177,7 +4314,7 @@ version = "0.1.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c2a7b1c03c876122aa43f3020e6c3c3ee5c05081c9a00739faf7503aeba10d22" dependencies = [ - "windows-sys 0.60.2", + "windows-sys 0.61.2", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index a3e232f..93f2e69 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -39,6 +39,8 @@ sha2 = "0.10" # images (PNG snapshots and screenshots) png = "0.18" +# SVG toolbar icons rasterised in the UI (no text, fonts or raster images in icons) +resvg = { version = "0.48", default-features = false } # ui: the same egui/eframe/egui-wgpu line as SolidCraft egui = "0.36" diff --git a/ROADMAP.md b/ROADMAP.md index 40316c2..b513f7e 100644 --- a/ROADMAP.md +++ b/ROADMAP.md @@ -33,4 +33,4 @@ hex meshes today and it gives the best elements where stresses are read. | M12 CFD: lattice Boltzmann | D3Q19/D3Q27 on grids voxelised from the face-tagged surface; TRT, regularised and cumulant collision; interpolated walls, inlets and outlets; LES; octree refinement shared with the hex mesher; wgpu backend (deterministic per device, checked against the CPU) | planned | | M13 Fluid–structure interaction | Immersed-boundary coupling of the lattice Boltzmann fluid with the explicit or implicit structure; interface force transfer; sub-cycling; Aitken then interface quasi-Newton coupling; free-surface flow | planned | | M14 Blast and impact fluids | EOS-driven fluids in the explicit solver: ALE multi-material or SPH, with fluid–structure contact | planned | -| Continuous: desktop and agents | Desktop app (viewport, model tree, commands, control channel: done), MCP server, browser build, command schema as the public API | started | +| Continuous: desktop and agents | Desktop app (viewport, model tree, commands, control channel: done; toolbar of every capability from the catalogue, ready or coming soon with its milestone, icons drawn with VectorCraft, docs/features.md: done), MCP server, browser build, command schema as the public API | started | diff --git a/THIRD-PARTY-LICENSES.txt b/THIRD-PARTY-LICENSES.txt index c23199e..0d7cdb5 100644 --- a/THIRD-PARTY-LICENSES.txt +++ b/THIRD-PARTY-LICENSES.txt @@ -1,6 +1,6 @@ Third-party software in ModelCraft -ModelCraft (the desktop app, modelcraft-cli and the web app) is built from the 427 crates below. +ModelCraft (the desktop app, modelcraft-cli and the web app) is built from the 441 crates below. Generated by `cargo xtask licences` from Cargo.lock and the crates' own licence files. ModelCraft's own licence is in LICENSE-MIT and LICENSE-APACHE, and NOTICE. @@ -23,6 +23,7 @@ approx 0.4.0 (Apache-2.0) arbitrary 1.5.0 (MIT OR Apache-2.0) arboard 3.6.1 (MIT OR Apache-2.0) array-macro 2.1.8 (MIT OR Apache-2.0) +arrayref 0.3.9 (BSD-2-Clause) arrayvec 0.7.8 (MIT OR Apache-2.0) as-raw-xcb-connection 1.0.1 (MIT OR Apache-2.0) ash 0.38.0+1.3.281 (MIT OR Apache-2.0) @@ -80,6 +81,7 @@ crossbeam-utils 0.8.23 (MIT OR Apache-2.0) crunchy 0.2.4 (MIT) crypto-common 0.1.7 (MIT OR Apache-2.0) cursor-icon 1.2.0 (MIT OR Apache-2.0 OR Zlib) +data-url 0.3.2 (MIT OR Apache-2.0) derive_arbitrary 1.5.0 (MIT OR Apache-2.0) derive_more 0.99.20 (MIT) digest 0.10.7 (MIT OR Apache-2.0) @@ -113,6 +115,7 @@ fax 0.2.7 (MIT) fdeflate 0.3.7 (MIT OR Apache-2.0) fearless_simd 0.4.1 (Apache-2.0 OR MIT) flate2 1.1.10 (MIT OR Apache-2.0) +float-cmp 0.9.0 (MIT) foldhash 0.2.0 (Zlib) font-types 0.12.6 (MIT OR Apache-2.0) foreign-types 0.5.0 (MIT/Apache-2.0) @@ -147,6 +150,7 @@ hex 0.4.3 (MIT OR Apache-2.0) iana-time-zone 0.1.65 (MIT OR Apache-2.0) iana-time-zone-haiku 0.1.2 (MIT OR Apache-2.0) image 0.25.10 (MIT OR Apache-2.0) +imagesize 0.15.0 (MIT) indexmap 2.14.2 (Apache-2.0 OR MIT) itertools 0.13.0 (MIT OR Apache-2.0) itertools 0.15.0 (MIT OR Apache-2.0) @@ -226,6 +230,7 @@ phf 0.13.1 (MIT) phf_generator 0.13.1 (MIT) phf_macros 0.13.1 (MIT) phf_shared 0.13.1 (MIT) +pico-args 0.5.0 (MIT) pin-project 1.1.13 (Apache-2.0 OR MIT) pin-project-internal 1.1.13 (Apache-2.0 OR MIT) pin-project-lite 0.2.17 (Apache-2.0 OR MIT) @@ -264,7 +269,10 @@ redox_syscall 0.4.1 (MIT) redox_syscall 0.5.18 (MIT) redox_syscall 0.9.4 (MIT) renderdoc-sys 1.1.0 (MIT OR Apache-2.0) +resvg 0.48.1 (Apache-2.0 OR MIT) +rgb 0.8.53 (MIT) robust 1.2.0 (MIT OR Apache-2.0) +roxmltree 0.21.1 (MIT OR Apache-2.0) rustc-hash 1.1.0 (Apache-2.0/MIT) rustc-hash 2.1.3 (Apache-2.0 OR MIT) rustix 0.38.44 (Apache-2.0 WITH LLVM-exception OR Apache-2.0 OR MIT) @@ -283,6 +291,7 @@ signal-hook-registry 1.4.8 (MIT OR Apache-2.0) simd-adler32 0.3.10 (MIT) simd_cesu8 1.2.0 (Apache-2.0 OR MIT) simdutf8 0.1.5 (MIT OR Apache-2.0) +simplecss 0.2.2 (Apache-2.0 OR MIT) siphasher 1.0.4 (MIT OR Apache-2.0) skrifa 0.44.0 (MIT OR Apache-2.0) slab 0.4.12 (MIT) @@ -302,6 +311,8 @@ solidcraft-sketch 0.8.0 (MIT OR Apache-2.0) spade 2.15.1 (MIT OR Apache-2.0) spirv 0.4.0+sdk-1.4.341.0 (Apache-2.0) static_assertions 1.1.0 (MIT OR Apache-2.0) +strict-num 0.1.1 (MIT) +svgtypes 0.16.1 (Apache-2.0 OR MIT) syn 1.0.109 (MIT OR Apache-2.0) syn 2.0.119 (MIT OR Apache-2.0) syn 3.0.9 (MIT OR Apache-2.0) @@ -312,6 +323,8 @@ thiserror 2.0.21 (MIT OR Apache-2.0) thiserror-impl 1.0.69 (MIT OR Apache-2.0) thiserror-impl 2.0.21 (MIT OR Apache-2.0) tiff 0.11.3 (MIT) +tiny-skia 0.12.0 (BSD-3-Clause) +tiny-skia-path 0.12.0 (BSD-3-Clause) tokio 1.53.2 (MIT) toml_datetime 1.1.2+spec-1.1.0 (MIT OR Apache-2.0) toml_edit 0.25.17+spec-1.1.0 (MIT OR Apache-2.0) @@ -337,6 +350,7 @@ unicode-general-category 1.1.0 (Apache-2.0) unicode-ident 1.0.27 ((MIT OR Apache-2.0) AND Unicode-3.0) unicode-segmentation 1.13.3 (MIT OR Apache-2.0) unicode-width 0.2.2 (MIT OR Apache-2.0) +usvg 0.48.1 (Apache-2.0 OR MIT) uuid 1.28.0 (Apache-2.0 OR MIT) vello_common 0.1.0 (Apache-2.0 OR MIT) vello_cpu 0.1.0 (Apache-2.0 OR MIT) @@ -732,20 +746,21 @@ ahash 0.8.12, arbitrary 1.5.0, arrayvec 0.7.8, async-channel 2.5.0, async-execut 4.7.1, atomic-waker 1.1.2, bitflags 1.3.2, bitflags 2.13.2, blocking 1.7.0, bumpalo 3.20.3, cfg-if 1.0.5, cgl 0.3.2, concurrent-queue 2.5.0, core-foundation 0.9.4, core-foundation-sys 0.8.7, core-graphics 0.23.2, core-graphics-types 0.1.3, crossbeam-deque 0.8.8, crossbeam-epoch 0.9.21, -crossbeam-utils 0.8.23, derive_arbitrary 1.5.0, either 1.19.0, equivalent 1.0.2, errno 0.3.14, -euclid 0.22.14, event-listener 5.4.2, event-listener-strategy 0.5.4, fastrand 2.5.0, flate2 1.1.10, -futures-lite 2.6.1, gethostname 1.1.0, glow 0.17.0, hashbrown 0.16.1, hashbrown 0.17.1, hermit-abi -0.5.3, indexmap 2.14.2, itertools 0.13.0, itertools 0.15.0, js-sys 0.3.106, khronos-egl 6.0.0, -linux-raw-sys 0.12.1, linux-raw-sys 0.4.15, lock_api 0.4.14, log 0.4.34, num-complex 0.4.6, -num-traits 0.2.19, once_cell 1.21.4, ordered-stream 0.2.0, parking 2.2.1, parking_lot 0.12.5, -parking_lot_core 0.9.12, percent-encoding 2.3.2, piper 0.2.5, plain 0.2.3, png 0.18.1, polling -3.11.0, pollster 1.0.1, rayon 1.12.0, rayon-core 1.13.0, renderdoc-sys 1.1.0, robust 1.2.0, -rustc-hash 1.1.0, rustix 0.38.44, rustix 1.1.5, scoped-tls 1.0.1, scopeguard 1.2.0, -signal-hook-registry 1.4.8, simd_cesu8 1.2.0, smallvec 1.16.3, smol_str 0.2.2, syn 1.0.109, tempfile -3.27.0, ttf-parser 0.25.1, unicode-segmentation 1.13.3, unicode-width 0.2.2, uuid 1.28.0, wasi -0.11.1+wasi-snapshot-preview1, wasip2 1.0.4+wasi-0.2.12, wasm-bindgen 0.2.129, wasm-bindgen-futures -0.4.79, wasm-bindgen-macro 0.2.129, wasm-bindgen-macro-support 0.2.129, wasm-bindgen-shared 0.2.129, -web-sys 0.3.106, weezl 0.1.12, wit-bindgen 0.57.1 +crossbeam-utils 0.8.23, data-url 0.3.2, derive_arbitrary 1.5.0, either 1.19.0, equivalent 1.0.2, +errno 0.3.14, euclid 0.22.14, event-listener 5.4.2, event-listener-strategy 0.5.4, fastrand 2.5.0, +flate2 1.1.10, futures-lite 2.6.1, gethostname 1.1.0, glow 0.17.0, hashbrown 0.16.1, hashbrown +0.17.1, hermit-abi 0.5.3, indexmap 2.14.2, itertools 0.13.0, itertools 0.15.0, js-sys 0.3.106, +khronos-egl 6.0.0, linux-raw-sys 0.12.1, linux-raw-sys 0.4.15, lock_api 0.4.14, log 0.4.34, +num-complex 0.4.6, num-traits 0.2.19, once_cell 1.21.4, ordered-stream 0.2.0, parking 2.2.1, +parking_lot 0.12.5, parking_lot_core 0.9.12, percent-encoding 2.3.2, piper 0.2.5, plain 0.2.3, png +0.18.1, polling 3.11.0, pollster 1.0.1, rayon 1.12.0, rayon-core 1.13.0, renderdoc-sys 1.1.0, robust +1.2.0, roxmltree 0.21.1, rustc-hash 1.1.0, rustix 0.38.44, rustix 1.1.5, scoped-tls 1.0.1, +scopeguard 1.2.0, signal-hook-registry 1.4.8, simd_cesu8 1.2.0, simplecss 0.2.2, smallvec 1.16.3, +smol_str 0.2.2, svgtypes 0.16.1, syn 1.0.109, tempfile 3.27.0, ttf-parser 0.25.1, +unicode-segmentation 1.13.3, unicode-width 0.2.2, uuid 1.28.0, wasi 0.11.1+wasi-snapshot-preview1, +wasip2 1.0.4+wasi-0.2.12, wasm-bindgen 0.2.129, wasm-bindgen-futures 0.4.79, wasm-bindgen-macro +0.2.129, wasm-bindgen-macro-support 0.2.129, wasm-bindgen-shared 0.2.129, web-sys 0.3.106, weezl +0.1.12, wit-bindgen 0.57.1 ================================================================================ Apache License @@ -1169,10 +1184,11 @@ android-activity 0.6.1, arboard 3.6.1, color 0.3.3, fdeflate 0.3.7, fearless_sim image 0.25.10, linebender_resource_handle 0.1.1, miniz_oxide 0.8.9, miniz_oxide 0.9.1, naga 30.0.1, naga-types 30.0.1, pin-project 1.1.13, pin-project-internal 1.1.13, pin-project-lite 0.2.17, portable-atomic 1.15.0, portable-atomic-util 0.2.8, range-alloc 0.1.5, raw-window-handle 0.6.2, -simdutf8 0.1.5, truck-meshalgo 0.4.0, truck-shapeops 0.4.0, truck-stepio 0.3.0, vello_common 0.1.0, -vello_cpu 0.1.0, wgpu 30.0.1, wgpu-core 30.0.1, wgpu-core-deps-apple 30.0.1, -wgpu-core-deps-emscripten 30.0.1, wgpu-core-deps-wasm 30.0.1, wgpu-core-deps-windows-linux-android -30.0.1, wgpu-hal 30.0.1, wgpu-naga-bridge 30.0.1, wgpu-types 30.0.1 +resvg 0.48.1, simdutf8 0.1.5, truck-meshalgo 0.4.0, truck-shapeops 0.4.0, truck-stepio 0.3.0, usvg +0.48.1, vello_common 0.1.0, vello_cpu 0.1.0, wgpu 30.0.1, wgpu-core 30.0.1, wgpu-core-deps-apple +30.0.1, wgpu-core-deps-emscripten 30.0.1, wgpu-core-deps-wasm 30.0.1, +wgpu-core-deps-windows-linux-android 30.0.1, wgpu-hal 30.0.1, wgpu-naga-bridge 30.0.1, wgpu-types +30.0.1 ================================================================================ Apache License @@ -1712,6 +1728,37 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +================================================================================ +arrayref 0.3.9 +================================================================================ + +Copyright (c) 2015 David Roundy +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + +1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + +2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the + distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + ================================================================================ arrayvec 0.7.8 ================================================================================ @@ -3927,6 +3974,36 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +================================================================================ +data-url 0.3.2, percent-encoding 2.3.2 +================================================================================ + +Copyright (c) 2013-2025 The rust-url developers + +Permission is hereby granted, free of charge, to any +person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the +Software without restriction, including without +limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software +is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice +shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT +SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR +IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. + ================================================================================ derive_more 0.99.20 ================================================================================ @@ -4651,6 +4728,30 @@ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +================================================================================ +float-cmp 0.9.0 +================================================================================ + +Copyright (c) 2014-2020 Optimal Computing (NZ) Ltd + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies +of the Software, and to permit persons to whom the Software is furnished to do +so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +IN THE SOFTWARE. + ================================================================================ foldhash 0.2.0 ================================================================================ @@ -6225,6 +6326,32 @@ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +================================================================================ +imagesize 0.15.0 +================================================================================ + +MIT License + +Copyright (c) 2017 Maiddog + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + ================================================================================ indexmap 2.14.2 ================================================================================ @@ -7876,36 +8003,6 @@ http://www.apache.org/licenses/LICENSE-2.0> or the MIT license option. All files in the project carrying such notice may not be copied, modified, or distributed except according to those terms. -================================================================================ -percent-encoding 2.3.2 -================================================================================ - -Copyright (c) 2013-2025 The rust-url developers - -Permission is hereby granted, free of charge, to any -person obtaining a copy of this software and associated -documentation files (the "Software"), to deal in the -Software without restriction, including without -limitation the rights to use, copy, modify, merge, -publish, distribute, sublicense, and/or sell copies of -the Software, and to permit persons to whom the Software -is furnished to do so, subject to the following -conditions: - -The above copyright notice and this permission notice -shall be included in all copies or substantial portions -of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF -ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED -TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A -PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT -SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY -CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR -IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -DEALINGS IN THE SOFTWARE. - ================================================================================ phf 0.13.1, phf_generator 0.13.1, phf_macros 0.13.1, phf_shared 0.13.1 ================================================================================ @@ -7931,6 +8028,30 @@ COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +================================================================================ +pico-args 0.5.0 +================================================================================ + +Copyright (c) 2019 Yevhenii Reizner + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + ================================================================================ plain 0.2.3 ================================================================================ @@ -9187,6 +9308,62 @@ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +================================================================================ +resvg 0.48.1, usvg 0.48.1 +================================================================================ + +Copyright 2017 the Resvg Authors + +Permission is hereby granted, free of charge, to any +person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the +Software without restriction, including without +limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software +is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice +shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT +SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR +IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. + +================================================================================ +rgb 0.8.53 +================================================================================ + +MIT License + +Copyright (c) 2019 Kornel + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + ================================================================================ robust 1.2.0 ================================================================================ @@ -9218,6 +9395,32 @@ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +================================================================================ +roxmltree 0.21.1 +================================================================================ + +The MIT License (MIT) + +Copyright (c) 2018 Yevhenii Reizner + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + ================================================================================ rustix 0.38.44, rustix 1.1.5 ================================================================================ @@ -9714,6 +9917,32 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +================================================================================ +simplecss 0.2.2 +================================================================================ + +The MIT License (MIT) + +Copyright (c) 2018 Reizner Evgeniy + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + ================================================================================ siphasher 1.0.4 ================================================================================ @@ -9890,6 +10119,54 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +================================================================================ +strict-num 0.1.1 +================================================================================ + +Copyright (c) 2022 Yevhenii Reizner + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +================================================================================ +svgtypes 0.16.1, ttf-parser 0.25.1 +================================================================================ + +Copyright (c) 2018 Yevhenii Reizner + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + ================================================================================ tempfile 3.27.0 ================================================================================ @@ -9946,6 +10223,41 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +================================================================================ +tiny-skia 0.12.0, tiny-skia-path 0.12.0 +================================================================================ + +Copyright (c) 2011 Google Inc. All rights reserved. +Copyright (c) 2020 Yevhenii Reizner All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the + distribution. + + * Neither the name of the copyright holder nor the names of its + contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + ================================================================================ tokio 1.53.2 ================================================================================ @@ -10232,30 +10544,6 @@ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -================================================================================ -ttf-parser 0.25.1 -================================================================================ - -Copyright (c) 2018 Yevhenii Reizner - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. - ================================================================================ type-map 0.5.1 ================================================================================ diff --git a/apps/modelcraft-cli/src/main.rs b/apps/modelcraft-cli/src/main.rs index acefeef..c2ca1f3 100644 --- a/apps/modelcraft-cli/src/main.rs +++ b/apps/modelcraft-cli/src/main.rs @@ -1,5 +1,6 @@ //! modelcraft-cli commands //! modelcraft-cli run +//! modelcraft-cli features #![deny(clippy::unwrap_used, clippy::expect_used, clippy::panic, clippy::unimplemented, clippy::todo, clippy::unreachable)] #![forbid(unsafe_code)] @@ -13,6 +14,8 @@ usage: modelcraft-cli commands list every command with its parameters modelcraft-cli run run a script (a JSON array of {\"command\", \"params\"}) and print the model summary + modelcraft-cli features print docs/features.md (every capability, ready or + coming soon) from the capability catalogue "; /// Largest script accepted (bytes). @@ -27,6 +30,10 @@ fn main() -> ExitCode { } Ok(()) } + Some("features") => { + print!("{}", modelcraft_engine::catalogue::features_page()); + Ok(()) + } Some("run") => args.get(1).ok_or_else(|| format!("run needs a script\n\n{USAGE}")).and_then(|p| run(p)), Some("-h" | "--help" | "help") | None => { print!("{USAGE}"); diff --git a/assets/icons/assembly.instance.svg b/assets/icons/assembly.instance.svg new file mode 100644 index 0000000..053b890 --- /dev/null +++ b/assets/icons/assembly.instance.svg @@ -0,0 +1,11 @@ + + + assembly.instance + + + + + + + + diff --git a/assets/icons/assembly.instance.vectorcraft b/assets/icons/assembly.instance.vectorcraft new file mode 100644 index 0000000..43057eb Binary files /dev/null and b/assets/icons/assembly.instance.vectorcraft differ diff --git a/assets/icons/deck.read.svg b/assets/icons/deck.read.svg new file mode 100644 index 0000000..c5554be --- /dev/null +++ b/assets/icons/deck.read.svg @@ -0,0 +1,10 @@ + + + deck.read + + + + + + + diff --git a/assets/icons/deck.read.vectorcraft b/assets/icons/deck.read.vectorcraft new file mode 100644 index 0000000..3f188bd Binary files /dev/null and b/assets/icons/deck.read.vectorcraft differ diff --git a/assets/icons/deck.write.abaqus.svg b/assets/icons/deck.write.abaqus.svg new file mode 100644 index 0000000..6758847 --- /dev/null +++ b/assets/icons/deck.write.abaqus.svg @@ -0,0 +1,11 @@ + + + deck.write.abaqus + + + + + + + + diff --git a/assets/icons/deck.write.abaqus.vectorcraft b/assets/icons/deck.write.abaqus.vectorcraft new file mode 100644 index 0000000..3aa7720 Binary files /dev/null and b/assets/icons/deck.write.abaqus.vectorcraft differ diff --git a/assets/icons/deck.write.lsdyna.svg b/assets/icons/deck.write.lsdyna.svg new file mode 100644 index 0000000..3d971a0 --- /dev/null +++ b/assets/icons/deck.write.lsdyna.svg @@ -0,0 +1,11 @@ + + + deck.write.lsdyna + + + + + + + + diff --git a/assets/icons/deck.write.lsdyna.vectorcraft b/assets/icons/deck.write.lsdyna.vectorcraft new file mode 100644 index 0000000..5124c40 Binary files /dev/null and b/assets/icons/deck.write.lsdyna.vectorcraft differ diff --git a/assets/icons/deck.write.nastran.svg b/assets/icons/deck.write.nastran.svg new file mode 100644 index 0000000..2098161 --- /dev/null +++ b/assets/icons/deck.write.nastran.svg @@ -0,0 +1,11 @@ + + + deck.write.nastran + + + + + + + + diff --git a/assets/icons/deck.write.nastran.vectorcraft b/assets/icons/deck.write.nastran.vectorcraft new file mode 100644 index 0000000..3bd0091 Binary files /dev/null and b/assets/icons/deck.write.nastran.vectorcraft differ diff --git a/assets/icons/edit.redo.svg b/assets/icons/edit.redo.svg new file mode 100644 index 0000000..102d14d --- /dev/null +++ b/assets/icons/edit.redo.svg @@ -0,0 +1,8 @@ + + + edit.redo + + + + + diff --git a/assets/icons/edit.redo.vectorcraft b/assets/icons/edit.redo.vectorcraft new file mode 100644 index 0000000..9569c94 Binary files /dev/null and b/assets/icons/edit.redo.vectorcraft differ diff --git a/assets/icons/edit.undo.svg b/assets/icons/edit.undo.svg new file mode 100644 index 0000000..53521ee --- /dev/null +++ b/assets/icons/edit.undo.svg @@ -0,0 +1,8 @@ + + + edit.undo + + + + + diff --git a/assets/icons/edit.undo.vectorcraft b/assets/icons/edit.undo.vectorcraft new file mode 100644 index 0000000..5a09ea7 Binary files /dev/null and b/assets/icons/edit.undo.vectorcraft differ diff --git a/assets/icons/file.open.svg b/assets/icons/file.open.svg new file mode 100644 index 0000000..cbd89da --- /dev/null +++ b/assets/icons/file.open.svg @@ -0,0 +1,8 @@ + + + file.open + + + + + diff --git a/assets/icons/file.open.vectorcraft b/assets/icons/file.open.vectorcraft new file mode 100644 index 0000000..7f963d5 Binary files /dev/null and b/assets/icons/file.open.vectorcraft differ diff --git a/assets/icons/file.recover.svg b/assets/icons/file.recover.svg new file mode 100644 index 0000000..5addee1 --- /dev/null +++ b/assets/icons/file.recover.svg @@ -0,0 +1,9 @@ + + + file.recover + + + + + + diff --git a/assets/icons/file.recover.vectorcraft b/assets/icons/file.recover.vectorcraft new file mode 100644 index 0000000..46b0143 Binary files /dev/null and b/assets/icons/file.recover.vectorcraft differ diff --git a/assets/icons/file.save.svg b/assets/icons/file.save.svg new file mode 100644 index 0000000..55b90ce --- /dev/null +++ b/assets/icons/file.save.svg @@ -0,0 +1,8 @@ + + + file.save + + + + + diff --git a/assets/icons/file.save.vectorcraft b/assets/icons/file.save.vectorcraft new file mode 100644 index 0000000..ab12ae0 Binary files /dev/null and b/assets/icons/file.save.vectorcraft differ diff --git a/assets/icons/file.save_as.svg b/assets/icons/file.save_as.svg new file mode 100644 index 0000000..5233574 --- /dev/null +++ b/assets/icons/file.save_as.svg @@ -0,0 +1,9 @@ + + + file.save_as + + + + + + diff --git a/assets/icons/file.save_as.vectorcraft b/assets/icons/file.save_as.vectorcraft new file mode 100644 index 0000000..4989edc Binary files /dev/null and b/assets/icons/file.save_as.vectorcraft differ diff --git a/assets/icons/flow.boundary.svg b/assets/icons/flow.boundary.svg new file mode 100644 index 0000000..62755a1 --- /dev/null +++ b/assets/icons/flow.boundary.svg @@ -0,0 +1,10 @@ + + + flow.boundary + + + + + + + diff --git a/assets/icons/flow.boundary.vectorcraft b/assets/icons/flow.boundary.vectorcraft new file mode 100644 index 0000000..930f96c Binary files /dev/null and b/assets/icons/flow.boundary.vectorcraft differ diff --git a/assets/icons/flow.domain.svg b/assets/icons/flow.domain.svg new file mode 100644 index 0000000..7c362ae --- /dev/null +++ b/assets/icons/flow.domain.svg @@ -0,0 +1,9 @@ + + + flow.domain + + + + + + diff --git a/assets/icons/flow.domain.vectorcraft b/assets/icons/flow.domain.vectorcraft new file mode 100644 index 0000000..60bc6ad Binary files /dev/null and b/assets/icons/flow.domain.vectorcraft differ diff --git a/assets/icons/geometry.bodies.svg b/assets/icons/geometry.bodies.svg new file mode 100644 index 0000000..1d326aa --- /dev/null +++ b/assets/icons/geometry.bodies.svg @@ -0,0 +1,10 @@ + + + geometry.bodies + + + + + + + diff --git a/assets/icons/geometry.bodies.vectorcraft b/assets/icons/geometry.bodies.vectorcraft new file mode 100644 index 0000000..f2f0e08 Binary files /dev/null and b/assets/icons/geometry.bodies.vectorcraft differ diff --git a/assets/icons/geometry.datum.svg b/assets/icons/geometry.datum.svg new file mode 100644 index 0000000..c6f00ae --- /dev/null +++ b/assets/icons/geometry.datum.svg @@ -0,0 +1,10 @@ + + + geometry.datum + + + + + + + diff --git a/assets/icons/geometry.datum.vectorcraft b/assets/icons/geometry.datum.vectorcraft new file mode 100644 index 0000000..f5ad7a7 Binary files /dev/null and b/assets/icons/geometry.datum.vectorcraft differ diff --git a/assets/icons/geometry.import.mesh.svg b/assets/icons/geometry.import.mesh.svg new file mode 100644 index 0000000..ce11283 --- /dev/null +++ b/assets/icons/geometry.import.mesh.svg @@ -0,0 +1,10 @@ + + + geometry.import.mesh + + + + + + + diff --git a/assets/icons/geometry.import.mesh.vectorcraft b/assets/icons/geometry.import.mesh.vectorcraft new file mode 100644 index 0000000..aefa82a Binary files /dev/null and b/assets/icons/geometry.import.mesh.vectorcraft differ diff --git a/assets/icons/geometry.midsurface.svg b/assets/icons/geometry.midsurface.svg new file mode 100644 index 0000000..ea6ad0b --- /dev/null +++ b/assets/icons/geometry.midsurface.svg @@ -0,0 +1,9 @@ + + + geometry.midsurface + + + + + + diff --git a/assets/icons/geometry.midsurface.vectorcraft b/assets/icons/geometry.midsurface.vectorcraft new file mode 100644 index 0000000..7acbc93 Binary files /dev/null and b/assets/icons/geometry.midsurface.vectorcraft differ diff --git a/assets/icons/geometry.open.svg b/assets/icons/geometry.open.svg new file mode 100644 index 0000000..de5321d --- /dev/null +++ b/assets/icons/geometry.open.svg @@ -0,0 +1,9 @@ + + + geometry.open + + + + + + diff --git a/assets/icons/geometry.open.vectorcraft b/assets/icons/geometry.open.vectorcraft new file mode 100644 index 0000000..3be0492 Binary files /dev/null and b/assets/icons/geometry.open.vectorcraft differ diff --git a/assets/icons/geometry.partition.svg b/assets/icons/geometry.partition.svg new file mode 100644 index 0000000..b567193 --- /dev/null +++ b/assets/icons/geometry.partition.svg @@ -0,0 +1,10 @@ + + + geometry.partition + + + + + + + diff --git a/assets/icons/geometry.partition.vectorcraft b/assets/icons/geometry.partition.vectorcraft new file mode 100644 index 0000000..186ccce Binary files /dev/null and b/assets/icons/geometry.partition.vectorcraft differ diff --git a/assets/icons/geometry.tessellate.svg b/assets/icons/geometry.tessellate.svg new file mode 100644 index 0000000..7111335 --- /dev/null +++ b/assets/icons/geometry.tessellate.svg @@ -0,0 +1,9 @@ + + + geometry.tessellate + + + + + + diff --git a/assets/icons/geometry.tessellate.vectorcraft b/assets/icons/geometry.tessellate.vectorcraft new file mode 100644 index 0000000..f03e24c Binary files /dev/null and b/assets/icons/geometry.tessellate.vectorcraft differ diff --git a/assets/icons/interaction.bolt.svg b/assets/icons/interaction.bolt.svg new file mode 100644 index 0000000..924f10a --- /dev/null +++ b/assets/icons/interaction.bolt.svg @@ -0,0 +1,11 @@ + + + interaction.bolt + + + + + + + + diff --git a/assets/icons/interaction.bolt.vectorcraft b/assets/icons/interaction.bolt.vectorcraft new file mode 100644 index 0000000..50142c2 Binary files /dev/null and b/assets/icons/interaction.bolt.vectorcraft differ diff --git a/assets/icons/interaction.connector.svg b/assets/icons/interaction.connector.svg new file mode 100644 index 0000000..0327bf2 --- /dev/null +++ b/assets/icons/interaction.connector.svg @@ -0,0 +1,10 @@ + + + interaction.connector + + + + + + + diff --git a/assets/icons/interaction.connector.vectorcraft b/assets/icons/interaction.connector.vectorcraft new file mode 100644 index 0000000..089c8ee Binary files /dev/null and b/assets/icons/interaction.connector.vectorcraft differ diff --git a/assets/icons/interaction.contact.find.svg b/assets/icons/interaction.contact.find.svg new file mode 100644 index 0000000..0a7781f --- /dev/null +++ b/assets/icons/interaction.contact.find.svg @@ -0,0 +1,10 @@ + + + interaction.contact.find + + + + + + + diff --git a/assets/icons/interaction.contact.find.vectorcraft b/assets/icons/interaction.contact.find.vectorcraft new file mode 100644 index 0000000..065baf0 Binary files /dev/null and b/assets/icons/interaction.contact.find.vectorcraft differ diff --git a/assets/icons/interaction.contact.general.svg b/assets/icons/interaction.contact.general.svg new file mode 100644 index 0000000..3d2839a --- /dev/null +++ b/assets/icons/interaction.contact.general.svg @@ -0,0 +1,11 @@ + + + interaction.contact.general + + + + + + + + diff --git a/assets/icons/interaction.contact.general.vectorcraft b/assets/icons/interaction.contact.general.vectorcraft new file mode 100644 index 0000000..10a2287 Binary files /dev/null and b/assets/icons/interaction.contact.general.vectorcraft differ diff --git a/assets/icons/interaction.contact.pair.svg b/assets/icons/interaction.contact.pair.svg new file mode 100644 index 0000000..c2cc8ec --- /dev/null +++ b/assets/icons/interaction.contact.pair.svg @@ -0,0 +1,9 @@ + + + interaction.contact.pair + + + + + + diff --git a/assets/icons/interaction.contact.pair.vectorcraft b/assets/icons/interaction.contact.pair.vectorcraft new file mode 100644 index 0000000..edd5210 Binary files /dev/null and b/assets/icons/interaction.contact.pair.vectorcraft differ diff --git a/assets/icons/interaction.fsi.svg b/assets/icons/interaction.fsi.svg new file mode 100644 index 0000000..9ea6f21 --- /dev/null +++ b/assets/icons/interaction.fsi.svg @@ -0,0 +1,11 @@ + + + interaction.fsi + + + + + + + + diff --git a/assets/icons/interaction.fsi.vectorcraft b/assets/icons/interaction.fsi.vectorcraft new file mode 100644 index 0000000..69a04f2 Binary files /dev/null and b/assets/icons/interaction.fsi.vectorcraft differ diff --git a/assets/icons/interaction.mass.svg b/assets/icons/interaction.mass.svg new file mode 100644 index 0000000..b4111b2 --- /dev/null +++ b/assets/icons/interaction.mass.svg @@ -0,0 +1,9 @@ + + + interaction.mass + + + + + + diff --git a/assets/icons/interaction.mass.vectorcraft b/assets/icons/interaction.mass.vectorcraft new file mode 100644 index 0000000..47cfda1 Binary files /dev/null and b/assets/icons/interaction.mass.vectorcraft differ diff --git a/assets/icons/interaction.rigid_wall.svg b/assets/icons/interaction.rigid_wall.svg new file mode 100644 index 0000000..db9a8d8 --- /dev/null +++ b/assets/icons/interaction.rigid_wall.svg @@ -0,0 +1,11 @@ + + + interaction.rigid_wall + + + + + + + + diff --git a/assets/icons/interaction.rigid_wall.vectorcraft b/assets/icons/interaction.rigid_wall.vectorcraft new file mode 100644 index 0000000..ce34f3c Binary files /dev/null and b/assets/icons/interaction.rigid_wall.vectorcraft differ diff --git a/assets/icons/interaction.spring.svg b/assets/icons/interaction.spring.svg new file mode 100644 index 0000000..8e42a97 --- /dev/null +++ b/assets/icons/interaction.spring.svg @@ -0,0 +1,9 @@ + + + interaction.spring + + + + + + diff --git a/assets/icons/interaction.spring.vectorcraft b/assets/icons/interaction.spring.vectorcraft new file mode 100644 index 0000000..caf2653 Binary files /dev/null and b/assets/icons/interaction.spring.vectorcraft differ diff --git a/assets/icons/interaction.tie.svg b/assets/icons/interaction.tie.svg new file mode 100644 index 0000000..3c8dc79 --- /dev/null +++ b/assets/icons/interaction.tie.svg @@ -0,0 +1,11 @@ + + + interaction.tie + + + + + + + + diff --git a/assets/icons/interaction.tie.vectorcraft b/assets/icons/interaction.tie.vectorcraft new file mode 100644 index 0000000..be400d5 Binary files /dev/null and b/assets/icons/interaction.tie.vectorcraft differ diff --git a/assets/icons/mesh.delaunay.points.svg b/assets/icons/mesh.delaunay.points.svg new file mode 100644 index 0000000..96103ae --- /dev/null +++ b/assets/icons/mesh.delaunay.points.svg @@ -0,0 +1,12 @@ + + + mesh.delaunay.points + + + + + + + + + diff --git a/assets/icons/mesh.delaunay.points.vectorcraft b/assets/icons/mesh.delaunay.points.vectorcraft new file mode 100644 index 0000000..f5bec51 Binary files /dev/null and b/assets/icons/mesh.delaunay.points.vectorcraft differ diff --git a/assets/icons/mesh.element.add.svg b/assets/icons/mesh.element.add.svg new file mode 100644 index 0000000..a83fd8a --- /dev/null +++ b/assets/icons/mesh.element.add.svg @@ -0,0 +1,12 @@ + + + mesh.element.add + + + + + + + + + diff --git a/assets/icons/mesh.element.add.vectorcraft b/assets/icons/mesh.element.add.vectorcraft new file mode 100644 index 0000000..720312a Binary files /dev/null and b/assets/icons/mesh.element.add.vectorcraft differ diff --git a/assets/icons/mesh.hex.decompose.svg b/assets/icons/mesh.hex.decompose.svg new file mode 100644 index 0000000..73ded3c --- /dev/null +++ b/assets/icons/mesh.hex.decompose.svg @@ -0,0 +1,8 @@ + + + mesh.hex.decompose + + + + + diff --git a/assets/icons/mesh.hex.decompose.vectorcraft b/assets/icons/mesh.hex.decompose.vectorcraft new file mode 100644 index 0000000..249ea4f Binary files /dev/null and b/assets/icons/mesh.hex.decompose.vectorcraft differ diff --git a/assets/icons/mesh.hex.dominant.svg b/assets/icons/mesh.hex.dominant.svg new file mode 100644 index 0000000..97174a9 --- /dev/null +++ b/assets/icons/mesh.hex.dominant.svg @@ -0,0 +1,9 @@ + + + mesh.hex.dominant + + + + + + diff --git a/assets/icons/mesh.hex.dominant.vectorcraft b/assets/icons/mesh.hex.dominant.vectorcraft new file mode 100644 index 0000000..dd3bce1 Binary files /dev/null and b/assets/icons/mesh.hex.dominant.vectorcraft differ diff --git a/assets/icons/mesh.hex.generate.svg b/assets/icons/mesh.hex.generate.svg new file mode 100644 index 0000000..d83bdbe --- /dev/null +++ b/assets/icons/mesh.hex.generate.svg @@ -0,0 +1,9 @@ + + + mesh.hex.generate + + + + + + diff --git a/assets/icons/mesh.hex.generate.vectorcraft b/assets/icons/mesh.hex.generate.vectorcraft new file mode 100644 index 0000000..8625d88 Binary files /dev/null and b/assets/icons/mesh.hex.generate.vectorcraft differ diff --git a/assets/icons/mesh.hex.mapped.svg b/assets/icons/mesh.hex.mapped.svg new file mode 100644 index 0000000..3dc91d9 --- /dev/null +++ b/assets/icons/mesh.hex.mapped.svg @@ -0,0 +1,9 @@ + + + mesh.hex.mapped + + + + + + diff --git a/assets/icons/mesh.hex.mapped.vectorcraft b/assets/icons/mesh.hex.mapped.vectorcraft new file mode 100644 index 0000000..9408d67 Binary files /dev/null and b/assets/icons/mesh.hex.mapped.vectorcraft differ diff --git a/assets/icons/mesh.hex.polycube.svg b/assets/icons/mesh.hex.polycube.svg new file mode 100644 index 0000000..121c916 --- /dev/null +++ b/assets/icons/mesh.hex.polycube.svg @@ -0,0 +1,12 @@ + + + mesh.hex.polycube + + + + + + + + + diff --git a/assets/icons/mesh.hex.polycube.vectorcraft b/assets/icons/mesh.hex.polycube.vectorcraft new file mode 100644 index 0000000..3eddbca Binary files /dev/null and b/assets/icons/mesh.hex.polycube.vectorcraft differ diff --git a/assets/icons/mesh.hex.sweep.svg b/assets/icons/mesh.hex.sweep.svg new file mode 100644 index 0000000..4a5494e --- /dev/null +++ b/assets/icons/mesh.hex.sweep.svg @@ -0,0 +1,10 @@ + + + mesh.hex.sweep + + + + + + + diff --git a/assets/icons/mesh.hex.sweep.vectorcraft b/assets/icons/mesh.hex.sweep.vectorcraft new file mode 100644 index 0000000..82fb4de Binary files /dev/null and b/assets/icons/mesh.hex.sweep.vectorcraft differ diff --git a/assets/icons/mesh.import.orphan.svg b/assets/icons/mesh.import.orphan.svg new file mode 100644 index 0000000..c821fab --- /dev/null +++ b/assets/icons/mesh.import.orphan.svg @@ -0,0 +1,9 @@ + + + mesh.import.orphan + + + + + + diff --git a/assets/icons/mesh.import.orphan.vectorcraft b/assets/icons/mesh.import.orphan.vectorcraft new file mode 100644 index 0000000..ccfeb6f Binary files /dev/null and b/assets/icons/mesh.import.orphan.vectorcraft differ diff --git a/assets/icons/mesh.layers.svg b/assets/icons/mesh.layers.svg new file mode 100644 index 0000000..92c4687 --- /dev/null +++ b/assets/icons/mesh.layers.svg @@ -0,0 +1,9 @@ + + + mesh.layers + + + + + + diff --git a/assets/icons/mesh.layers.vectorcraft b/assets/icons/mesh.layers.vectorcraft new file mode 100644 index 0000000..802f16b Binary files /dev/null and b/assets/icons/mesh.layers.vectorcraft differ diff --git a/assets/icons/mesh.node.add.svg b/assets/icons/mesh.node.add.svg new file mode 100644 index 0000000..30221ef --- /dev/null +++ b/assets/icons/mesh.node.add.svg @@ -0,0 +1,11 @@ + + + mesh.node.add + + + + + + + + diff --git a/assets/icons/mesh.node.add.vectorcraft b/assets/icons/mesh.node.add.vectorcraft new file mode 100644 index 0000000..d8703f0 Binary files /dev/null and b/assets/icons/mesh.node.add.vectorcraft differ diff --git a/assets/icons/mesh.node.merge.svg b/assets/icons/mesh.node.merge.svg new file mode 100644 index 0000000..8818316 --- /dev/null +++ b/assets/icons/mesh.node.merge.svg @@ -0,0 +1,12 @@ + + + mesh.node.merge + + + + + + + + + diff --git a/assets/icons/mesh.node.merge.vectorcraft b/assets/icons/mesh.node.merge.vectorcraft new file mode 100644 index 0000000..d37a3f7 Binary files /dev/null and b/assets/icons/mesh.node.merge.vectorcraft differ diff --git a/assets/icons/mesh.order.quadratic.svg b/assets/icons/mesh.order.quadratic.svg new file mode 100644 index 0000000..8ec3ba6 --- /dev/null +++ b/assets/icons/mesh.order.quadratic.svg @@ -0,0 +1,13 @@ + + + mesh.order.quadratic + + + + + + + + + + diff --git a/assets/icons/mesh.order.quadratic.vectorcraft b/assets/icons/mesh.order.quadratic.vectorcraft new file mode 100644 index 0000000..d2ee728 Binary files /dev/null and b/assets/icons/mesh.order.quadratic.vectorcraft differ diff --git a/assets/icons/mesh.quad.faces.svg b/assets/icons/mesh.quad.faces.svg new file mode 100644 index 0000000..e6f79ec --- /dev/null +++ b/assets/icons/mesh.quad.faces.svg @@ -0,0 +1,8 @@ + + + mesh.quad.faces + + + + + diff --git a/assets/icons/mesh.quad.faces.vectorcraft b/assets/icons/mesh.quad.faces.vectorcraft new file mode 100644 index 0000000..cf06eb9 Binary files /dev/null and b/assets/icons/mesh.quad.faces.vectorcraft differ diff --git a/assets/icons/mesh.quality.svg b/assets/icons/mesh.quality.svg new file mode 100644 index 0000000..ddee3f4 --- /dev/null +++ b/assets/icons/mesh.quality.svg @@ -0,0 +1,10 @@ + + + mesh.quality + + + + + + + diff --git a/assets/icons/mesh.quality.vectorcraft b/assets/icons/mesh.quality.vectorcraft new file mode 100644 index 0000000..8115d5d Binary files /dev/null and b/assets/icons/mesh.quality.vectorcraft differ diff --git a/assets/icons/mesh.region.remesh.svg b/assets/icons/mesh.region.remesh.svg new file mode 100644 index 0000000..f714ecd --- /dev/null +++ b/assets/icons/mesh.region.remesh.svg @@ -0,0 +1,10 @@ + + + mesh.region.remesh + + + + + + + diff --git a/assets/icons/mesh.region.remesh.vectorcraft b/assets/icons/mesh.region.remesh.vectorcraft new file mode 100644 index 0000000..f6f9993 Binary files /dev/null and b/assets/icons/mesh.region.remesh.vectorcraft differ diff --git a/assets/icons/mesh.size.adapt.svg b/assets/icons/mesh.size.adapt.svg new file mode 100644 index 0000000..402fbf9 --- /dev/null +++ b/assets/icons/mesh.size.adapt.svg @@ -0,0 +1,15 @@ + + + mesh.size.adapt + + + + + + + + + + + + diff --git a/assets/icons/mesh.size.adapt.vectorcraft b/assets/icons/mesh.size.adapt.vectorcraft new file mode 100644 index 0000000..af263a7 Binary files /dev/null and b/assets/icons/mesh.size.adapt.vectorcraft differ diff --git a/assets/icons/mesh.size.global.svg b/assets/icons/mesh.size.global.svg new file mode 100644 index 0000000..b5f9d5f --- /dev/null +++ b/assets/icons/mesh.size.global.svg @@ -0,0 +1,11 @@ + + + mesh.size.global + + + + + + + + diff --git a/assets/icons/mesh.size.global.vectorcraft b/assets/icons/mesh.size.global.vectorcraft new file mode 100644 index 0000000..6da7c55 Binary files /dev/null and b/assets/icons/mesh.size.global.vectorcraft differ diff --git a/assets/icons/mesh.size.seed.svg b/assets/icons/mesh.size.seed.svg new file mode 100644 index 0000000..8da5903 --- /dev/null +++ b/assets/icons/mesh.size.seed.svg @@ -0,0 +1,13 @@ + + + mesh.size.seed + + + + + + + + + + diff --git a/assets/icons/mesh.size.seed.vectorcraft b/assets/icons/mesh.size.seed.vectorcraft new file mode 100644 index 0000000..ec5854b Binary files /dev/null and b/assets/icons/mesh.size.seed.vectorcraft differ diff --git a/assets/icons/mesh.smooth.svg b/assets/icons/mesh.smooth.svg new file mode 100644 index 0000000..40d3a2e --- /dev/null +++ b/assets/icons/mesh.smooth.svg @@ -0,0 +1,8 @@ + + + mesh.smooth + + + + + diff --git a/assets/icons/mesh.smooth.vectorcraft b/assets/icons/mesh.smooth.vectorcraft new file mode 100644 index 0000000..de79eb4 Binary files /dev/null and b/assets/icons/mesh.smooth.vectorcraft differ diff --git a/assets/icons/mesh.surface.check.svg b/assets/icons/mesh.surface.check.svg new file mode 100644 index 0000000..366142c --- /dev/null +++ b/assets/icons/mesh.surface.check.svg @@ -0,0 +1,9 @@ + + + mesh.surface.check + + + + + + diff --git a/assets/icons/mesh.surface.check.vectorcraft b/assets/icons/mesh.surface.check.vectorcraft new file mode 100644 index 0000000..e438024 Binary files /dev/null and b/assets/icons/mesh.surface.check.vectorcraft differ diff --git a/assets/icons/mesh.tag.svg b/assets/icons/mesh.tag.svg new file mode 100644 index 0000000..9bafef1 --- /dev/null +++ b/assets/icons/mesh.tag.svg @@ -0,0 +1,9 @@ + + + mesh.tag + + + + + + diff --git a/assets/icons/mesh.tag.vectorcraft b/assets/icons/mesh.tag.vectorcraft new file mode 100644 index 0000000..5dc23a9 Binary files /dev/null and b/assets/icons/mesh.tag.vectorcraft differ diff --git a/assets/icons/mesh.tet.generate.svg b/assets/icons/mesh.tet.generate.svg new file mode 100644 index 0000000..c16964f --- /dev/null +++ b/assets/icons/mesh.tet.generate.svg @@ -0,0 +1,8 @@ + + + mesh.tet.generate + + + + + diff --git a/assets/icons/mesh.tet.generate.vectorcraft b/assets/icons/mesh.tet.generate.vectorcraft new file mode 100644 index 0000000..d66ab15 Binary files /dev/null and b/assets/icons/mesh.tet.generate.vectorcraft differ diff --git a/assets/icons/mesh.transition.svg b/assets/icons/mesh.transition.svg new file mode 100644 index 0000000..b3eab75 --- /dev/null +++ b/assets/icons/mesh.transition.svg @@ -0,0 +1,10 @@ + + + mesh.transition + + + + + + + diff --git a/assets/icons/mesh.transition.vectorcraft b/assets/icons/mesh.transition.vectorcraft new file mode 100644 index 0000000..e0a32a8 Binary files /dev/null and b/assets/icons/mesh.transition.vectorcraft differ diff --git a/assets/icons/mesh.untangle.svg b/assets/icons/mesh.untangle.svg new file mode 100644 index 0000000..1082f25 --- /dev/null +++ b/assets/icons/mesh.untangle.svg @@ -0,0 +1,9 @@ + + + mesh.untangle + + + + + + diff --git a/assets/icons/mesh.untangle.vectorcraft b/assets/icons/mesh.untangle.vectorcraft new file mode 100644 index 0000000..0d1e5c3 Binary files /dev/null and b/assets/icons/mesh.untangle.vectorcraft differ diff --git a/assets/icons/mesh.verify.svg b/assets/icons/mesh.verify.svg new file mode 100644 index 0000000..a7ce1e0 --- /dev/null +++ b/assets/icons/mesh.verify.svg @@ -0,0 +1,9 @@ + + + mesh.verify + + + + + + diff --git a/assets/icons/mesh.verify.vectorcraft b/assets/icons/mesh.verify.vectorcraft new file mode 100644 index 0000000..2c414db Binary files /dev/null and b/assets/icons/mesh.verify.vectorcraft differ diff --git a/assets/icons/model.activity.svg b/assets/icons/model.activity.svg new file mode 100644 index 0000000..bc16e02 --- /dev/null +++ b/assets/icons/model.activity.svg @@ -0,0 +1,10 @@ + + + model.activity + + + + + + + diff --git a/assets/icons/model.activity.vectorcraft b/assets/icons/model.activity.vectorcraft new file mode 100644 index 0000000..4276310 Binary files /dev/null and b/assets/icons/model.activity.vectorcraft differ diff --git a/assets/icons/model.amplitude.svg b/assets/icons/model.amplitude.svg new file mode 100644 index 0000000..4d61587 --- /dev/null +++ b/assets/icons/model.amplitude.svg @@ -0,0 +1,8 @@ + + + model.amplitude + + + + + diff --git a/assets/icons/model.amplitude.vectorcraft b/assets/icons/model.amplitude.vectorcraft new file mode 100644 index 0000000..e39cd49 Binary files /dev/null and b/assets/icons/model.amplitude.vectorcraft differ diff --git a/assets/icons/model.boundary_condition.create.svg b/assets/icons/model.boundary_condition.create.svg new file mode 100644 index 0000000..2bd4d4c --- /dev/null +++ b/assets/icons/model.boundary_condition.create.svg @@ -0,0 +1,9 @@ + + + model.boundary_condition.create + + + + + + diff --git a/assets/icons/model.boundary_condition.create.vectorcraft b/assets/icons/model.boundary_condition.create.vectorcraft new file mode 100644 index 0000000..0fbeaff Binary files /dev/null and b/assets/icons/model.boundary_condition.create.vectorcraft differ diff --git a/assets/icons/model.check.svg b/assets/icons/model.check.svg new file mode 100644 index 0000000..c47e755 --- /dev/null +++ b/assets/icons/model.check.svg @@ -0,0 +1,9 @@ + + + model.check + + + + + + diff --git a/assets/icons/model.check.vectorcraft b/assets/icons/model.check.vectorcraft new file mode 100644 index 0000000..1afe2b6 Binary files /dev/null and b/assets/icons/model.check.vectorcraft differ diff --git a/assets/icons/model.coupling.create.svg b/assets/icons/model.coupling.create.svg new file mode 100644 index 0000000..5681727 --- /dev/null +++ b/assets/icons/model.coupling.create.svg @@ -0,0 +1,14 @@ + + + model.coupling.create + + + + + + + + + + + diff --git a/assets/icons/model.coupling.create.vectorcraft b/assets/icons/model.coupling.create.vectorcraft new file mode 100644 index 0000000..a51d006 Binary files /dev/null and b/assets/icons/model.coupling.create.vectorcraft differ diff --git a/assets/icons/model.info.svg b/assets/icons/model.info.svg new file mode 100644 index 0000000..bddb8cd --- /dev/null +++ b/assets/icons/model.info.svg @@ -0,0 +1,9 @@ + + + model.info + + + + + + diff --git a/assets/icons/model.info.vectorcraft b/assets/icons/model.info.vectorcraft new file mode 100644 index 0000000..8f279e7 Binary files /dev/null and b/assets/icons/model.info.vectorcraft differ diff --git a/assets/icons/model.load.create.svg b/assets/icons/model.load.create.svg new file mode 100644 index 0000000..6598812 --- /dev/null +++ b/assets/icons/model.load.create.svg @@ -0,0 +1,10 @@ + + + model.load.create + + + + + + + diff --git a/assets/icons/model.load.create.vectorcraft b/assets/icons/model.load.create.vectorcraft new file mode 100644 index 0000000..f576b43 Binary files /dev/null and b/assets/icons/model.load.create.vectorcraft differ diff --git a/assets/icons/model.material.create.svg b/assets/icons/model.material.create.svg new file mode 100644 index 0000000..2b8d775 --- /dev/null +++ b/assets/icons/model.material.create.svg @@ -0,0 +1,9 @@ + + + model.material.create + + + + + + diff --git a/assets/icons/model.material.create.vectorcraft b/assets/icons/model.material.create.vectorcraft new file mode 100644 index 0000000..36d400e Binary files /dev/null and b/assets/icons/model.material.create.vectorcraft differ diff --git a/assets/icons/model.material.damage.svg b/assets/icons/model.material.damage.svg new file mode 100644 index 0000000..a952f6a --- /dev/null +++ b/assets/icons/model.material.damage.svg @@ -0,0 +1,8 @@ + + + model.material.damage + + + + + diff --git a/assets/icons/model.material.damage.vectorcraft b/assets/icons/model.material.damage.vectorcraft new file mode 100644 index 0000000..2c581de Binary files /dev/null and b/assets/icons/model.material.damage.vectorcraft differ diff --git a/assets/icons/model.material.eos.svg b/assets/icons/model.material.eos.svg new file mode 100644 index 0000000..e8c8f72 --- /dev/null +++ b/assets/icons/model.material.eos.svg @@ -0,0 +1,9 @@ + + + model.material.eos + + + + + + diff --git a/assets/icons/model.material.eos.vectorcraft b/assets/icons/model.material.eos.vectorcraft new file mode 100644 index 0000000..1d4783e Binary files /dev/null and b/assets/icons/model.material.eos.vectorcraft differ diff --git a/assets/icons/model.material.hyperelastic.svg b/assets/icons/model.material.hyperelastic.svg new file mode 100644 index 0000000..8ccd91f --- /dev/null +++ b/assets/icons/model.material.hyperelastic.svg @@ -0,0 +1,8 @@ + + + model.material.hyperelastic + + + + + diff --git a/assets/icons/model.material.hyperelastic.vectorcraft b/assets/icons/model.material.hyperelastic.vectorcraft new file mode 100644 index 0000000..b6d6c47 Binary files /dev/null and b/assets/icons/model.material.hyperelastic.vectorcraft differ diff --git a/assets/icons/model.material.plasticity.svg b/assets/icons/model.material.plasticity.svg new file mode 100644 index 0000000..0b1ab62 --- /dev/null +++ b/assets/icons/model.material.plasticity.svg @@ -0,0 +1,9 @@ + + + model.material.plasticity + + + + + + diff --git a/assets/icons/model.material.plasticity.vectorcraft b/assets/icons/model.material.plasticity.vectorcraft new file mode 100644 index 0000000..af32a11 Binary files /dev/null and b/assets/icons/model.material.plasticity.vectorcraft differ diff --git a/assets/icons/model.material.thermal.svg b/assets/icons/model.material.thermal.svg new file mode 100644 index 0000000..f08a9b4 --- /dev/null +++ b/assets/icons/model.material.thermal.svg @@ -0,0 +1,10 @@ + + + model.material.thermal + + + + + + + diff --git a/assets/icons/model.material.thermal.vectorcraft b/assets/icons/model.material.thermal.vectorcraft new file mode 100644 index 0000000..a0baada Binary files /dev/null and b/assets/icons/model.material.thermal.vectorcraft differ diff --git a/assets/icons/model.orientation.svg b/assets/icons/model.orientation.svg new file mode 100644 index 0000000..3a4e481 --- /dev/null +++ b/assets/icons/model.orientation.svg @@ -0,0 +1,10 @@ + + + model.orientation + + + + + + + diff --git a/assets/icons/model.orientation.vectorcraft b/assets/icons/model.orientation.vectorcraft new file mode 100644 index 0000000..1076f3f Binary files /dev/null and b/assets/icons/model.orientation.vectorcraft differ diff --git a/assets/icons/model.reference_point.create.svg b/assets/icons/model.reference_point.create.svg new file mode 100644 index 0000000..7780238 --- /dev/null +++ b/assets/icons/model.reference_point.create.svg @@ -0,0 +1,9 @@ + + + model.reference_point.create + + + + + + diff --git a/assets/icons/model.reference_point.create.vectorcraft b/assets/icons/model.reference_point.create.vectorcraft new file mode 100644 index 0000000..17add91 Binary files /dev/null and b/assets/icons/model.reference_point.create.vectorcraft differ diff --git a/assets/icons/model.section.composite.svg b/assets/icons/model.section.composite.svg new file mode 100644 index 0000000..d0dbf3f --- /dev/null +++ b/assets/icons/model.section.composite.svg @@ -0,0 +1,12 @@ + + + model.section.composite + + + + + + + + + diff --git a/assets/icons/model.section.composite.vectorcraft b/assets/icons/model.section.composite.vectorcraft new file mode 100644 index 0000000..255a931 Binary files /dev/null and b/assets/icons/model.section.composite.vectorcraft differ diff --git a/assets/icons/model.section.create.svg b/assets/icons/model.section.create.svg new file mode 100644 index 0000000..bf81b24 --- /dev/null +++ b/assets/icons/model.section.create.svg @@ -0,0 +1,7 @@ + + + model.section.create + + + + diff --git a/assets/icons/model.section.create.vectorcraft b/assets/icons/model.section.create.vectorcraft new file mode 100644 index 0000000..5e17ef7 Binary files /dev/null and b/assets/icons/model.section.create.vectorcraft differ diff --git a/assets/icons/model.set.create.svg b/assets/icons/model.set.create.svg new file mode 100644 index 0000000..d32e3dd --- /dev/null +++ b/assets/icons/model.set.create.svg @@ -0,0 +1,11 @@ + + + model.set.create + + + + + + + + diff --git a/assets/icons/model.set.create.vectorcraft b/assets/icons/model.set.create.vectorcraft new file mode 100644 index 0000000..bdad8b6 Binary files /dev/null and b/assets/icons/model.set.create.vectorcraft differ diff --git a/assets/icons/model.step.activate.svg b/assets/icons/model.step.activate.svg new file mode 100644 index 0000000..80dae24 --- /dev/null +++ b/assets/icons/model.step.activate.svg @@ -0,0 +1,8 @@ + + + model.step.activate + + + + + diff --git a/assets/icons/model.step.activate.vectorcraft b/assets/icons/model.step.activate.vectorcraft new file mode 100644 index 0000000..7feaa96 Binary files /dev/null and b/assets/icons/model.step.activate.vectorcraft differ diff --git a/assets/icons/model.step.create.svg b/assets/icons/model.step.create.svg new file mode 100644 index 0000000..c035dc4 --- /dev/null +++ b/assets/icons/model.step.create.svg @@ -0,0 +1,8 @@ + + + model.step.create + + + + + diff --git a/assets/icons/model.step.create.vectorcraft b/assets/icons/model.step.create.vectorcraft new file mode 100644 index 0000000..dd088a4 Binary files /dev/null and b/assets/icons/model.step.create.vectorcraft differ diff --git a/assets/icons/model.step.explicit.svg b/assets/icons/model.step.explicit.svg new file mode 100644 index 0000000..a03d286 --- /dev/null +++ b/assets/icons/model.step.explicit.svg @@ -0,0 +1,10 @@ + + + model.step.explicit + + + + + + + diff --git a/assets/icons/model.step.explicit.vectorcraft b/assets/icons/model.step.explicit.vectorcraft new file mode 100644 index 0000000..9f84780 Binary files /dev/null and b/assets/icons/model.step.explicit.vectorcraft differ diff --git a/assets/icons/model.step.heat.svg b/assets/icons/model.step.heat.svg new file mode 100644 index 0000000..37326c0 --- /dev/null +++ b/assets/icons/model.step.heat.svg @@ -0,0 +1,7 @@ + + + model.step.heat + + + + diff --git a/assets/icons/model.step.heat.vectorcraft b/assets/icons/model.step.heat.vectorcraft new file mode 100644 index 0000000..b1fb214 Binary files /dev/null and b/assets/icons/model.step.heat.vectorcraft differ diff --git a/assets/icons/model.step.nonlinear.svg b/assets/icons/model.step.nonlinear.svg new file mode 100644 index 0000000..a42c1b3 --- /dev/null +++ b/assets/icons/model.step.nonlinear.svg @@ -0,0 +1,11 @@ + + + model.step.nonlinear + + + + + + + + diff --git a/assets/icons/model.step.nonlinear.vectorcraft b/assets/icons/model.step.nonlinear.vectorcraft new file mode 100644 index 0000000..374fc27 Binary files /dev/null and b/assets/icons/model.step.nonlinear.vectorcraft differ diff --git a/assets/icons/model.units.svg b/assets/icons/model.units.svg new file mode 100644 index 0000000..fa2622b --- /dev/null +++ b/assets/icons/model.units.svg @@ -0,0 +1,8 @@ + + + model.units + + + + + diff --git a/assets/icons/model.units.vectorcraft b/assets/icons/model.units.vectorcraft new file mode 100644 index 0000000..edaf7f7 Binary files /dev/null and b/assets/icons/model.units.vectorcraft differ diff --git a/assets/icons/results.animate.svg b/assets/icons/results.animate.svg new file mode 100644 index 0000000..ef3990d --- /dev/null +++ b/assets/icons/results.animate.svg @@ -0,0 +1,9 @@ + + + results.animate + + + + + + diff --git a/assets/icons/results.animate.vectorcraft b/assets/icons/results.animate.vectorcraft new file mode 100644 index 0000000..4d2b7b7 Binary files /dev/null and b/assets/icons/results.animate.vectorcraft differ diff --git a/assets/icons/results.contour.svg b/assets/icons/results.contour.svg new file mode 100644 index 0000000..ad0c658 --- /dev/null +++ b/assets/icons/results.contour.svg @@ -0,0 +1,10 @@ + + + results.contour + + + + + + + diff --git a/assets/icons/results.contour.vectorcraft b/assets/icons/results.contour.vectorcraft new file mode 100644 index 0000000..ccf6b28 Binary files /dev/null and b/assets/icons/results.contour.vectorcraft differ diff --git a/assets/icons/results.convergence.svg b/assets/icons/results.convergence.svg new file mode 100644 index 0000000..b5159f9 --- /dev/null +++ b/assets/icons/results.convergence.svg @@ -0,0 +1,12 @@ + + + results.convergence + + + + + + + + + diff --git a/assets/icons/results.convergence.vectorcraft b/assets/icons/results.convergence.vectorcraft new file mode 100644 index 0000000..755d4d8 Binary files /dev/null and b/assets/icons/results.convergence.vectorcraft differ diff --git a/assets/icons/results.cut.svg b/assets/icons/results.cut.svg new file mode 100644 index 0000000..d902bce --- /dev/null +++ b/assets/icons/results.cut.svg @@ -0,0 +1,9 @@ + + + results.cut + + + + + + diff --git a/assets/icons/results.cut.vectorcraft b/assets/icons/results.cut.vectorcraft new file mode 100644 index 0000000..ce401b5 Binary files /dev/null and b/assets/icons/results.cut.vectorcraft differ diff --git a/assets/icons/results.deformed.svg b/assets/icons/results.deformed.svg new file mode 100644 index 0000000..62e59b2 --- /dev/null +++ b/assets/icons/results.deformed.svg @@ -0,0 +1,8 @@ + + + results.deformed + + + + + diff --git a/assets/icons/results.deformed.vectorcraft b/assets/icons/results.deformed.vectorcraft new file mode 100644 index 0000000..673130a Binary files /dev/null and b/assets/icons/results.deformed.vectorcraft differ diff --git a/assets/icons/results.display_group.svg b/assets/icons/results.display_group.svg new file mode 100644 index 0000000..404d301 --- /dev/null +++ b/assets/icons/results.display_group.svg @@ -0,0 +1,8 @@ + + + results.display_group + + + + + diff --git a/assets/icons/results.display_group.vectorcraft b/assets/icons/results.display_group.vectorcraft new file mode 100644 index 0000000..b754648 Binary files /dev/null and b/assets/icons/results.display_group.vectorcraft differ diff --git a/assets/icons/results.free_body.svg b/assets/icons/results.free_body.svg new file mode 100644 index 0000000..283aab5 --- /dev/null +++ b/assets/icons/results.free_body.svg @@ -0,0 +1,10 @@ + + + results.free_body + + + + + + + diff --git a/assets/icons/results.free_body.vectorcraft b/assets/icons/results.free_body.vectorcraft new file mode 100644 index 0000000..8230e0c Binary files /dev/null and b/assets/icons/results.free_body.vectorcraft differ diff --git a/assets/icons/results.modes.svg b/assets/icons/results.modes.svg new file mode 100644 index 0000000..6f557f8 --- /dev/null +++ b/assets/icons/results.modes.svg @@ -0,0 +1,11 @@ + + + results.modes + + + + + + + + diff --git a/assets/icons/results.modes.vectorcraft b/assets/icons/results.modes.vectorcraft new file mode 100644 index 0000000..4f75900 Binary files /dev/null and b/assets/icons/results.modes.vectorcraft differ diff --git a/assets/icons/results.path.svg b/assets/icons/results.path.svg new file mode 100644 index 0000000..fb93125 --- /dev/null +++ b/assets/icons/results.path.svg @@ -0,0 +1,12 @@ + + + results.path + + + + + + + + + diff --git a/assets/icons/results.path.vectorcraft b/assets/icons/results.path.vectorcraft new file mode 100644 index 0000000..12be616 Binary files /dev/null and b/assets/icons/results.path.vectorcraft differ diff --git a/assets/icons/results.reactions.svg b/assets/icons/results.reactions.svg new file mode 100644 index 0000000..a428db9 --- /dev/null +++ b/assets/icons/results.reactions.svg @@ -0,0 +1,10 @@ + + + results.reactions + + + + + + + diff --git a/assets/icons/results.reactions.vectorcraft b/assets/icons/results.reactions.vectorcraft new file mode 100644 index 0000000..c3f78ca Binary files /dev/null and b/assets/icons/results.reactions.vectorcraft differ diff --git a/assets/icons/results.read.svg b/assets/icons/results.read.svg new file mode 100644 index 0000000..bab61a7 --- /dev/null +++ b/assets/icons/results.read.svg @@ -0,0 +1,11 @@ + + + results.read + + + + + + + + diff --git a/assets/icons/results.read.vectorcraft b/assets/icons/results.read.vectorcraft new file mode 100644 index 0000000..04934fa Binary files /dev/null and b/assets/icons/results.read.vectorcraft differ diff --git a/assets/icons/results.streamlines.svg b/assets/icons/results.streamlines.svg new file mode 100644 index 0000000..e3a0a4b --- /dev/null +++ b/assets/icons/results.streamlines.svg @@ -0,0 +1,11 @@ + + + results.streamlines + + + + + + + + diff --git a/assets/icons/results.streamlines.vectorcraft b/assets/icons/results.streamlines.vectorcraft new file mode 100644 index 0000000..e491014 Binary files /dev/null and b/assets/icons/results.streamlines.vectorcraft differ diff --git a/assets/icons/results.xy.svg b/assets/icons/results.xy.svg new file mode 100644 index 0000000..7210e5e --- /dev/null +++ b/assets/icons/results.xy.svg @@ -0,0 +1,11 @@ + + + results.xy + + + + + + + + diff --git a/assets/icons/results.xy.vectorcraft b/assets/icons/results.xy.vectorcraft new file mode 100644 index 0000000..dd31cf1 Binary files /dev/null and b/assets/icons/results.xy.vectorcraft differ diff --git a/assets/icons/solve.blast.svg b/assets/icons/solve.blast.svg new file mode 100644 index 0000000..dfe35ce --- /dev/null +++ b/assets/icons/solve.blast.svg @@ -0,0 +1,8 @@ + + + solve.blast + + + + + diff --git a/assets/icons/solve.blast.vectorcraft b/assets/icons/solve.blast.vectorcraft new file mode 100644 index 0000000..28bd938 Binary files /dev/null and b/assets/icons/solve.blast.vectorcraft differ diff --git a/assets/icons/solve.explicit.svg b/assets/icons/solve.explicit.svg new file mode 100644 index 0000000..ae7c14a --- /dev/null +++ b/assets/icons/solve.explicit.svg @@ -0,0 +1,10 @@ + + + solve.explicit + + + + + + + diff --git a/assets/icons/solve.explicit.vectorcraft b/assets/icons/solve.explicit.vectorcraft new file mode 100644 index 0000000..e82e6f7 Binary files /dev/null and b/assets/icons/solve.explicit.vectorcraft differ diff --git a/assets/icons/solve.flow.svg b/assets/icons/solve.flow.svg new file mode 100644 index 0000000..2de5b8b --- /dev/null +++ b/assets/icons/solve.flow.svg @@ -0,0 +1,10 @@ + + + solve.flow + + + + + + + diff --git a/assets/icons/solve.flow.vectorcraft b/assets/icons/solve.flow.vectorcraft new file mode 100644 index 0000000..f4ae396 Binary files /dev/null and b/assets/icons/solve.flow.vectorcraft differ diff --git a/assets/icons/solve.frequency.svg b/assets/icons/solve.frequency.svg new file mode 100644 index 0000000..66524e6 --- /dev/null +++ b/assets/icons/solve.frequency.svg @@ -0,0 +1,11 @@ + + + solve.frequency + + + + + + + + diff --git a/assets/icons/solve.frequency.vectorcraft b/assets/icons/solve.frequency.vectorcraft new file mode 100644 index 0000000..0672d01 Binary files /dev/null and b/assets/icons/solve.frequency.vectorcraft differ diff --git a/assets/icons/solve.fsi.svg b/assets/icons/solve.fsi.svg new file mode 100644 index 0000000..1c85402 --- /dev/null +++ b/assets/icons/solve.fsi.svg @@ -0,0 +1,12 @@ + + + solve.fsi + + + + + + + + + diff --git a/assets/icons/solve.fsi.vectorcraft b/assets/icons/solve.fsi.vectorcraft new file mode 100644 index 0000000..6336af7 Binary files /dev/null and b/assets/icons/solve.fsi.vectorcraft differ diff --git a/assets/icons/solve.probe.svg b/assets/icons/solve.probe.svg new file mode 100644 index 0000000..6bd270c --- /dev/null +++ b/assets/icons/solve.probe.svg @@ -0,0 +1,11 @@ + + + solve.probe + + + + + + + + diff --git a/assets/icons/solve.probe.vectorcraft b/assets/icons/solve.probe.vectorcraft new file mode 100644 index 0000000..718be5b Binary files /dev/null and b/assets/icons/solve.probe.vectorcraft differ diff --git a/assets/icons/solve.static.svg b/assets/icons/solve.static.svg new file mode 100644 index 0000000..8557c16 --- /dev/null +++ b/assets/icons/solve.static.svg @@ -0,0 +1,11 @@ + + + solve.static + + + + + + + + diff --git a/assets/icons/solve.static.vectorcraft b/assets/icons/solve.static.vectorcraft new file mode 100644 index 0000000..83ae546 Binary files /dev/null and b/assets/icons/solve.static.vectorcraft differ diff --git a/assets/icons/src/assembly.instance.json b/assets/icons/src/assembly.instance.json new file mode 100644 index 0000000..bcb5451 --- /dev/null +++ b/assets/icons/src/assembly.instance.json @@ -0,0 +1 @@ +{"shapes": [{"d": "M8 10 L13 12.5 L13 17.5 L8 20 L3 17.5 L3 12.5 Z", "fill": "soft", "stroke": "line"}, {"d": "M3 12.5 L8 15 L13 12.5 M8 15 L8 20", "stroke": "line"}, {"d": "M16 4 L21 6.5 L21 11.5 L16 14 L11 11.5 L11 6.5 Z", "stroke": "accent"}, {"d": "M11 6.5 L16 9 L21 6.5 M16 9 L16 14", "stroke": "accent"}, {"d": "M10 8 L13.5 6 M12.19 8.13 L13.5 6 L11 6.05", "stroke": "line", "width": 1.25}]} diff --git a/assets/icons/src/deck.read.json b/assets/icons/src/deck.read.json new file mode 100644 index 0000000..c71ed73 --- /dev/null +++ b/assets/icons/src/deck.read.json @@ -0,0 +1 @@ +{"shapes": [{"d": "M8 3 L16 3 L20 7 L20 21 L8 21 Z", "fill": "soft", "stroke": "line"}, {"d": "M16 3 L16 7 L20 7", "stroke": "line"}, {"d": "M11 10 L17 10 M11 13 L17 13 M11 16 L15 16", "stroke": "line", "width": 1}, {"d": "M2 15 L9 15 M6.19 16.53 L9 15 L6.19 13.47", "stroke": "accent", "width": 1.5}]} diff --git a/assets/icons/src/deck.write.abaqus.json b/assets/icons/src/deck.write.abaqus.json new file mode 100644 index 0000000..7854b3e --- /dev/null +++ b/assets/icons/src/deck.write.abaqus.json @@ -0,0 +1 @@ +{"shapes": [{"d": "M4 3 L12 3 L16 7 L16 21 L4 21 Z", "fill": "soft", "stroke": "line"}, {"d": "M12 3 L12 7 L16 7", "stroke": "line"}, {"d": "M7 10 L13 10 M7 13 L13 13 M7 16 L11 16", "stroke": "line", "width": 1}, {"d": "M15 15 L21 15 M18.19 16.53 L21 15 L18.19 13.47", "stroke": "accent", "width": 1.5}, {"circle": [18.5, 6, 2.5], "fill": "accent", "stroke": "accent"}]} diff --git a/assets/icons/src/deck.write.lsdyna.json b/assets/icons/src/deck.write.lsdyna.json new file mode 100644 index 0000000..540af5e --- /dev/null +++ b/assets/icons/src/deck.write.lsdyna.json @@ -0,0 +1 @@ +{"shapes": [{"d": "M4 3 L12 3 L16 7 L16 21 L4 21 Z", "fill": "soft", "stroke": "line"}, {"d": "M12 3 L12 7 L16 7", "stroke": "line"}, {"d": "M7 10 L13 10 M7 13 L13 13 M7 16 L11 16", "stroke": "line", "width": 1}, {"d": "M15 15 L21 15 M18.19 16.53 L21 15 L18.19 13.47", "stroke": "accent", "width": 1.5}, {"d": "M18.5 3 L21.3 8.2 L15.7 8.2 Z", "fill": "accent", "stroke": "accent"}]} diff --git a/assets/icons/src/deck.write.nastran.json b/assets/icons/src/deck.write.nastran.json new file mode 100644 index 0000000..fbeb8e8 --- /dev/null +++ b/assets/icons/src/deck.write.nastran.json @@ -0,0 +1 @@ +{"shapes": [{"d": "M4 3 L12 3 L16 7 L16 21 L4 21 Z", "fill": "soft", "stroke": "line"}, {"d": "M12 3 L12 7 L16 7", "stroke": "line"}, {"d": "M7 10 L13 10 M7 13 L13 13 M7 16 L11 16", "stroke": "line", "width": 1}, {"d": "M15 15 L21 15 M18.19 16.53 L21 15 L18.19 13.47", "stroke": "accent", "width": 1.5}, {"rect": [16, 3.5, 5, 5], "fill": "accent", "stroke": "accent"}]} diff --git a/assets/icons/src/edit.redo.json b/assets/icons/src/edit.redo.json new file mode 100644 index 0000000..3dc08c3 --- /dev/null +++ b/assets/icons/src/edit.redo.json @@ -0,0 +1 @@ +{"shapes": [{"d": "M19 9 H10 A5 5 0 0 0 10 19 H16", "stroke": "accent", "width": 1.75}, {"d": "M16 5.5 L19.5 9 L16 12.5", "stroke": "accent", "width": 1.75}]} diff --git a/assets/icons/src/edit.undo.json b/assets/icons/src/edit.undo.json new file mode 100644 index 0000000..cc938dd --- /dev/null +++ b/assets/icons/src/edit.undo.json @@ -0,0 +1 @@ +{"shapes": [{"d": "M5 9 H14 A5 5 0 0 1 14 19 H8", "stroke": "accent", "width": 1.75}, {"d": "M8 5.5 L4.5 9 L8 12.5", "stroke": "accent", "width": 1.75}]} diff --git a/assets/icons/src/file.open.json b/assets/icons/src/file.open.json new file mode 100644 index 0000000..86e3410 --- /dev/null +++ b/assets/icons/src/file.open.json @@ -0,0 +1 @@ +{"shapes": [{"d": "M3 5 L9 5 L11 7 L20 7 L20 19 L3 19 Z", "fill": "soft", "stroke": "line"}, {"d": "M12 17 L12 10 M13.53 12.81 L12 10 L10.47 12.81", "stroke": "accent", "width": 1.75}]} diff --git a/assets/icons/src/file.recover.json b/assets/icons/src/file.recover.json new file mode 100644 index 0000000..dd08e92 --- /dev/null +++ b/assets/icons/src/file.recover.json @@ -0,0 +1 @@ +{"shapes": [{"d": "M4.5 12 A7.5 7.5 0 1 0 7 6.4", "stroke": "accent", "width": 1.75}, {"d": "M3.4 4.6 L7 6.4 L5.6 10.2", "stroke": "accent", "width": 1.75}, {"d": "M12 8 L12 12 L15 14", "stroke": "line", "width": 1.75}]} diff --git a/assets/icons/src/file.save.json b/assets/icons/src/file.save.json new file mode 100644 index 0000000..18e89ef --- /dev/null +++ b/assets/icons/src/file.save.json @@ -0,0 +1 @@ +{"shapes": [{"d": "M3 14 L3 20 L21 20 L21 14", "stroke": "line", "width": 1.75}, {"d": "M12 3 L12 15 M10.47 12.19 L12 15 L13.53 12.19", "stroke": "accent", "width": 1.75}]} diff --git a/assets/icons/src/file.save_as.json b/assets/icons/src/file.save_as.json new file mode 100644 index 0000000..0f962cb --- /dev/null +++ b/assets/icons/src/file.save_as.json @@ -0,0 +1 @@ +{"shapes": [{"d": "M3 14 L3 20 L21 20 L21 14", "stroke": "line", "width": 1.75}, {"d": "M9 3 L9 15 M5.8 12 L9 15 L12.2 12", "stroke": "accent", "width": 1.75}, {"d": "M14 12 L19.5 6.5 L21.5 8.5 L16 14 L13.5 14.5 Z", "fill": "soft", "stroke": "warm", "width": 1.25}]} diff --git a/assets/icons/src/flow.boundary.json b/assets/icons/src/flow.boundary.json new file mode 100644 index 0000000..5dd2e0a --- /dev/null +++ b/assets/icons/src/flow.boundary.json @@ -0,0 +1 @@ +{"shapes": [{"d": "M3 5 L21 5 M3 19 L21 19", "stroke": "line"}, {"d": "M3 9.5 L9 9.5 M6.19 11.03 L9 9.5 L6.19 7.97", "stroke": "warm", "width": 1.5}, {"d": "M3 14.5 L9 14.5 M6.19 16.03 L9 14.5 L6.19 12.97", "stroke": "warm", "width": 1.5}, {"d": "M15 12 L21 12 M18.19 13.53 L21 12 L18.19 10.47", "stroke": "accent", "width": 1.5}]} diff --git a/assets/icons/src/flow.domain.json b/assets/icons/src/flow.domain.json new file mode 100644 index 0000000..a1559d8 --- /dev/null +++ b/assets/icons/src/flow.domain.json @@ -0,0 +1 @@ +{"shapes": [{"rect": [3, 3, 18, 18], "stroke": "line"}, {"d": "M7.5 3 L7.5 21 M3 7.5 L21 7.5 M12 3 L12 21 M3 12 L21 12 M16.5 3 L16.5 21 M3 16.5 L21 16.5", "stroke": "line", "width": 1}, {"circle": [12, 12, 4.5], "fill": "soft", "stroke": "accent"}]} diff --git a/assets/icons/src/geometry.bodies.json b/assets/icons/src/geometry.bodies.json new file mode 100644 index 0000000..f01f712 --- /dev/null +++ b/assets/icons/src/geometry.bodies.json @@ -0,0 +1 @@ +{"shapes": [{"d": "M9 8 L15 11 L15 18 L9 21 L3 18 L3 11 Z", "fill": "soft", "stroke": "line"}, {"d": "M3 11 L9 14 L15 11 M9 14 L9 21", "stroke": "line"}, {"d": "M14 4 L19 6.5 L19 13 L16 14.5", "stroke": "accent"}, {"d": "M14 4 L9 6.5 L9 7", "stroke": "accent"}]} diff --git a/assets/icons/src/geometry.datum.json b/assets/icons/src/geometry.datum.json new file mode 100644 index 0000000..4d8a486 --- /dev/null +++ b/assets/icons/src/geometry.datum.json @@ -0,0 +1 @@ +{"shapes": [{"d": "M3 15 L9 9 L21 9 L15 15 Z", "fill": "soft", "stroke": "accent"}, {"d": "M12 12 L12 3 M13.53 5.81 L12 3 L10.47 5.81", "stroke": "line", "width": 1.5}, {"circle": [12, 12, 1.5], "fill": "accent", "stroke": null}, {"d": "M12 15 L12 21", "stroke": "line", "dash": [1.5, 2]}]} diff --git a/assets/icons/src/geometry.import.mesh.json b/assets/icons/src/geometry.import.mesh.json new file mode 100644 index 0000000..88e789a --- /dev/null +++ b/assets/icons/src/geometry.import.mesh.json @@ -0,0 +1 @@ +{"shapes": [{"d": "M3 13 L12 9 L21 13 L12 17 Z", "fill": "soft", "stroke": "line"}, {"d": "M7.5 11 L16.5 15 M7.5 15 L16.5 11 M12 9 L12 17", "stroke": "line", "width": 1}, {"d": "M3 13 L3 16 L12 20 L21 16 L21 13", "stroke": "line"}, {"d": "M12 2 L12 8 M10.47 5.19 L12 8 L13.53 5.19", "stroke": "accent", "width": 1.75}]} diff --git a/assets/icons/src/geometry.midsurface.json b/assets/icons/src/geometry.midsurface.json new file mode 100644 index 0000000..3c5ef07 --- /dev/null +++ b/assets/icons/src/geometry.midsurface.json @@ -0,0 +1 @@ +{"shapes": [{"d": "M3 9 L9 4 L21 4 L15 9 Z", "stroke": "line"}, {"d": "M3 14 L9 9 L21 9 L15 14 Z", "fill": "soft", "stroke": "accent"}, {"d": "M3 19 L9 14 L21 14 L15 19 Z", "stroke": "line"}]} diff --git a/assets/icons/src/geometry.open.json b/assets/icons/src/geometry.open.json new file mode 100644 index 0000000..cfad45d --- /dev/null +++ b/assets/icons/src/geometry.open.json @@ -0,0 +1 @@ +{"shapes": [{"d": "M13 6 L20 9.5 L20 17.5 L13 21 L6 17.5 L6 9.5 Z", "fill": "soft", "stroke": "line"}, {"d": "M6 9.5 L13 13 L20 9.5 M13 13 L13 21", "stroke": "line"}, {"d": "M3 3 L9 9 M5.93 8.1 L9 9 L8.1 5.93", "stroke": "accent", "width": 1.75}]} diff --git a/assets/icons/src/geometry.partition.json b/assets/icons/src/geometry.partition.json new file mode 100644 index 0000000..ba320ae --- /dev/null +++ b/assets/icons/src/geometry.partition.json @@ -0,0 +1 @@ +{"shapes": [{"d": "M12 3 L20 7 L20 16 L12 20 L4 16 L4 7 Z", "fill": "soft", "stroke": "line"}, {"d": "M4 7 L12 11 L20 7 M12 11 L12 20", "stroke": "line"}, {"d": "M8 5 L16 9 M16 9 L16 18 M16 9 L16 9", "stroke": "accent", "width": 1.75}, {"d": "M8 5 L8 14 L16 18", "stroke": "accent", "width": 1.75}]} diff --git a/assets/icons/src/geometry.tessellate.json b/assets/icons/src/geometry.tessellate.json new file mode 100644 index 0000000..2e645a9 --- /dev/null +++ b/assets/icons/src/geometry.tessellate.json @@ -0,0 +1 @@ +{"shapes": [{"circle": [12, 12, 9], "fill": "soft", "stroke": "line"}, {"d": "M12 12 L19.79 16.5 M12 12 L12 21 M12 12 L4.21 16.5 M12 12 L4.21 7.5 M12 12 L12 3 M12 12 L19.79 7.5", "stroke": "accent", "width": 1}, {"d": "M19.79 16.5 L12 21 L4.21 16.5 L4.21 7.5 L12 3 L19.79 7.5 Z", "stroke": "accent", "width": 1}]} diff --git a/assets/icons/src/interaction.bolt.json b/assets/icons/src/interaction.bolt.json new file mode 100644 index 0000000..28c4593 --- /dev/null +++ b/assets/icons/src/interaction.bolt.json @@ -0,0 +1 @@ +{"shapes": [{"d": "M7 3 L17 3 L17 7 L7 7 Z", "fill": "soft", "stroke": "line"}, {"rect": [9.5, 7, 5, 14], "fill": "soft", "stroke": "line"}, {"d": "M9.5 11 L14.5 12.5 M9.5 14 L14.5 15.5 M9.5 17 L14.5 18.5", "stroke": "line", "width": 1}, {"d": "M4 13 L4 6 M5.2 8.19 L4 6 L2.8 8.19", "stroke": "warm", "width": 1.5}, {"d": "M20 13 L20 20 M18.8 17.81 L20 20 L21.2 17.81", "stroke": "warm", "width": 1.5}]} diff --git a/assets/icons/src/interaction.connector.json b/assets/icons/src/interaction.connector.json new file mode 100644 index 0000000..57789d2 --- /dev/null +++ b/assets/icons/src/interaction.connector.json @@ -0,0 +1 @@ +{"shapes": [{"circle": [4, 18, 1.8], "fill": "line", "stroke": null}, {"circle": [20, 6, 1.8], "fill": "line", "stroke": null}, {"d": "M4 18 L10 14 M14 10 L20 6", "stroke": "line", "width": 1.5}, {"circle": [12, 12, 2.8], "stroke": "accent", "width": 1.75}]} diff --git a/assets/icons/src/interaction.contact.find.json b/assets/icons/src/interaction.contact.find.json new file mode 100644 index 0000000..c237534 --- /dev/null +++ b/assets/icons/src/interaction.contact.find.json @@ -0,0 +1 @@ +{"shapes": [{"circle": [8, 8, 5], "fill": "soft", "stroke": "line"}, {"rect": [3, 13, 10, 8], "fill": "soft", "stroke": "line"}, {"circle": [16, 15, 4], "stroke": "accent"}, {"d": "M18.83 17.83 L21.83 20.83", "stroke": "accent", "width": 2}]} diff --git a/assets/icons/src/interaction.contact.general.json b/assets/icons/src/interaction.contact.general.json new file mode 100644 index 0000000..2fc1b05 --- /dev/null +++ b/assets/icons/src/interaction.contact.general.json @@ -0,0 +1 @@ +{"shapes": [{"circle": [8, 8, 5], "fill": "soft", "stroke": "line"}, {"rect": [3, 15, 18, 6], "fill": "soft", "stroke": "line"}, {"d": "M14 3 L21 3 L21 10 L14 10 Z", "fill": "soft", "stroke": "line"}, {"d": "M6.5 14.3 A5 5 0 0 0 9.5 14.3", "stroke": "accent", "width": 2}, {"d": "M13 6 L13 10", "stroke": "accent", "width": 2}]} diff --git a/assets/icons/src/interaction.contact.pair.json b/assets/icons/src/interaction.contact.pair.json new file mode 100644 index 0000000..ab8652a --- /dev/null +++ b/assets/icons/src/interaction.contact.pair.json @@ -0,0 +1 @@ +{"shapes": [{"circle": [12, 9, 6], "fill": "soft", "stroke": "line"}, {"rect": [3, 15, 18, 6], "fill": "soft", "stroke": "line"}, {"d": "M8 15 L16 15", "stroke": "accent", "width": 2.25}]} diff --git a/assets/icons/src/interaction.fsi.json b/assets/icons/src/interaction.fsi.json new file mode 100644 index 0000000..9111f38 --- /dev/null +++ b/assets/icons/src/interaction.fsi.json @@ -0,0 +1 @@ +{"shapes": [{"d": "M3 7 L3.23 6.71 L3.46 6.43 L3.69 6.17 L3.92 5.94 L4.15 5.75 L4.38 5.61 L4.6 5.53 L4.83 5.5 L5.06 5.53 L5.29 5.61 L5.52 5.75 L5.75 5.94 L5.98 6.17 L6.21 6.43 L6.44 6.71 L6.67 7 L6.9 7.29 L7.12 7.57 L7.35 7.83 L7.58 8.06 L7.81 8.25 L8.04 8.39 L8.27 8.47 L8.5 8.5 L8.73 8.47 L8.96 8.39 L9.19 8.25 L9.42 8.06 L9.65 7.83 L9.88 7.57 L10.1 7.29 L10.33 7 L10.56 6.71 L10.79 6.43 L11.02 6.17 L11.25 5.94 L11.48 5.75 L11.71 5.61 L11.94 5.53 L12.17 5.5 L12.4 5.53 L12.62 5.61 L12.85 5.75 L13.08 5.94 L13.31 6.17 L13.54 6.43 L13.77 6.71 L14 7", "stroke": "accent", "width": 1.5}, {"d": "M3 12 L3.23 11.71 L3.46 11.43 L3.69 11.17 L3.92 10.94 L4.15 10.75 L4.38 10.61 L4.6 10.53 L4.83 10.5 L5.06 10.53 L5.29 10.61 L5.52 10.75 L5.75 10.94 L5.98 11.17 L6.21 11.43 L6.44 11.71 L6.67 12 L6.9 12.29 L7.12 12.57 L7.35 12.83 L7.58 13.06 L7.81 13.25 L8.04 13.39 L8.27 13.47 L8.5 13.5 L8.73 13.47 L8.96 13.39 L9.19 13.25 L9.42 13.06 L9.65 12.83 L9.88 12.57 L10.1 12.29 L10.33 12 L10.56 11.71 L10.79 11.43 L11.02 11.17 L11.25 10.94 L11.48 10.75 L11.71 10.61 L11.94 10.53 L12.17 10.5 L12.4 10.53 L12.62 10.61 L12.85 10.75 L13.08 10.94 L13.31 11.17 L13.54 11.43 L13.77 11.71 L14 12", "stroke": "accent", "width": 1.5}, {"d": "M3 17 L3.23 16.71 L3.46 16.43 L3.69 16.17 L3.92 15.94 L4.15 15.75 L4.38 15.61 L4.6 15.53 L4.83 15.5 L5.06 15.53 L5.29 15.61 L5.52 15.75 L5.75 15.94 L5.98 16.17 L6.21 16.43 L6.44 16.71 L6.67 17 L6.9 17.29 L7.12 17.57 L7.35 17.83 L7.58 18.06 L7.81 18.25 L8.04 18.39 L8.27 18.47 L8.5 18.5 L8.73 18.47 L8.96 18.39 L9.19 18.25 L9.42 18.06 L9.65 17.83 L9.88 17.57 L10.1 17.29 L10.33 17 L10.56 16.71 L10.79 16.43 L11.02 16.17 L11.25 15.94 L11.48 15.75 L11.71 15.61 L11.94 15.53 L12.17 15.5 L12.4 15.53 L12.62 15.61 L12.85 15.75 L13.08 15.94 L13.31 16.17 L13.54 16.43 L13.77 16.71 L14 17", "stroke": "accent", "width": 1.5}, {"d": "M17 21 C17 15 18 9 20 3", "stroke": "line", "width": 2.25}, {"d": "M15 21 L21 21", "stroke": "line", "width": 1.5}]} diff --git a/assets/icons/src/interaction.mass.json b/assets/icons/src/interaction.mass.json new file mode 100644 index 0000000..8b6ee18 --- /dev/null +++ b/assets/icons/src/interaction.mass.json @@ -0,0 +1 @@ +{"shapes": [{"d": "M5 21 L7 9 L17 9 L19 21 Z", "fill": "soft", "stroke": "line"}, {"d": "M9 9 A3 3 0 0 1 15 9", "stroke": "line", "width": 1.75}, {"circle": [12, 15, 2], "fill": "accent", "stroke": null}]} diff --git a/assets/icons/src/interaction.rigid_wall.json b/assets/icons/src/interaction.rigid_wall.json new file mode 100644 index 0000000..eb05c46 --- /dev/null +++ b/assets/icons/src/interaction.rigid_wall.json @@ -0,0 +1 @@ +{"shapes": [{"d": "M18 3 L18 21", "stroke": "line", "width": 2}, {"d": "M18 4 L21 6.5 M18 8 L21 10.5 M18 12 L21 14.5 M18 16 L21 18.5", "stroke": "line", "width": 1.25}, {"circle": [7, 12, 4], "fill": "soft", "stroke": "line"}, {"d": "M11.5 12 L15.5 12 M13.22 13.25 L15.5 12 L13.22 10.75", "stroke": "warm", "width": 1.5}, {"d": "M2 9 L4 9 M1.5 15 L3.5 15", "stroke": "line", "width": 1}]} diff --git a/assets/icons/src/interaction.spring.json b/assets/icons/src/interaction.spring.json new file mode 100644 index 0000000..b40d168 --- /dev/null +++ b/assets/icons/src/interaction.spring.json @@ -0,0 +1 @@ +{"shapes": [{"circle": [3, 12, 1.8], "fill": "line", "stroke": null}, {"circle": [21, 12, 1.8], "fill": "line", "stroke": null}, {"d": "M3 12 L6 12 L7.5 7 L10.5 17 L13.5 7 L16.5 17 L18 12 L21 12", "stroke": "accent", "width": 1.5}]} diff --git a/assets/icons/src/interaction.tie.json b/assets/icons/src/interaction.tie.json new file mode 100644 index 0000000..57a8262 --- /dev/null +++ b/assets/icons/src/interaction.tie.json @@ -0,0 +1 @@ +{"shapes": [{"rect": [3, 4, 9, 16], "fill": "soft", "stroke": "line"}, {"d": "M7.5 4 L7.5 20 M3 12 L12 12", "stroke": "line", "width": 1}, {"rect": [12, 4, 9, 16], "fill": "soft", "stroke": "line"}, {"d": "M15 4 L15 20 M12 9.33 L21 9.33 M18 4 L18 20 M12 14.67 L21 14.67", "stroke": "line", "width": 1}, {"d": "M12 4 L12 20", "stroke": "accent", "width": 2}]} diff --git a/assets/icons/src/mesh.delaunay.points.json b/assets/icons/src/mesh.delaunay.points.json new file mode 100644 index 0000000..500e0f0 --- /dev/null +++ b/assets/icons/src/mesh.delaunay.points.json @@ -0,0 +1 @@ +{"shapes": [{"d": "M5 17 L11 6 L19 15 Z M5 17 L19 15 L14 21", "stroke": "line", "width": 1}, {"circle": [11.6, 13.4, 7.8], "stroke": "accent", "width": 1.25}, {"circle": [5, 17, 1.5], "fill": "line", "stroke": null}, {"circle": [11, 6, 1.5], "fill": "line", "stroke": null}, {"circle": [19, 15, 1.5], "fill": "line", "stroke": null}, {"circle": [14, 21, 1.5], "fill": "line", "stroke": null}]} diff --git a/assets/icons/src/mesh.element.add.json b/assets/icons/src/mesh.element.add.json new file mode 100644 index 0000000..43cc39f --- /dev/null +++ b/assets/icons/src/mesh.element.add.json @@ -0,0 +1 @@ +{"shapes": [{"d": "M3 7 L13 4 L15 15 L5 17 Z", "fill": "soft", "stroke": "line"}, {"circle": [3, 7, 1.5], "fill": "line", "stroke": null}, {"circle": [13, 4, 1.5], "fill": "line", "stroke": null}, {"circle": [15, 15, 1.5], "fill": "line", "stroke": null}, {"circle": [5, 17, 1.5], "fill": "line", "stroke": null}, {"d": "M15.5 18.5 L21.5 18.5 M18.5 15.5 L18.5 21.5", "stroke": "accent", "width": 1.75}]} diff --git a/assets/icons/src/mesh.hex.decompose.json b/assets/icons/src/mesh.hex.decompose.json new file mode 100644 index 0000000..b6a51fa --- /dev/null +++ b/assets/icons/src/mesh.hex.decompose.json @@ -0,0 +1 @@ +{"shapes": [{"d": "M3 4 L11 4 L11 12 L21 12 L21 20 L3 20 Z", "fill": "soft", "stroke": "line"}, {"d": "M11 12 L11 20 M3 12 L11 12", "stroke": "accent", "width": 1.75, "dash": [2, 2.5]}]} diff --git a/assets/icons/src/mesh.hex.dominant.json b/assets/icons/src/mesh.hex.dominant.json new file mode 100644 index 0000000..76bb513 --- /dev/null +++ b/assets/icons/src/mesh.hex.dominant.json @@ -0,0 +1 @@ +{"shapes": [{"rect": [3, 3, 18, 18], "fill": "soft", "stroke": "line"}, {"d": "M9 3 L9 21 M15 3 L15 21 M3 9 L21 9 M3 15 L21 15", "stroke": "line", "width": 1}, {"d": "M15 15 L21 21 M9 21 L15 15", "stroke": "accent", "width": 1.25}]} diff --git a/assets/icons/src/mesh.hex.generate.json b/assets/icons/src/mesh.hex.generate.json new file mode 100644 index 0000000..1bb734c --- /dev/null +++ b/assets/icons/src/mesh.hex.generate.json @@ -0,0 +1 @@ +{"shapes": [{"rect": [3, 3, 18, 18], "fill": "soft", "stroke": "line"}, {"d": "M12 3 L12 21 M3 12 L21 12", "stroke": "line", "width": 1.25}, {"d": "M16.5 3 L16.5 12 M12 7.5 L21 7.5 M14.25 3 L14.25 7.5 M12 5.25 L16.5 5.25", "stroke": "accent", "width": 1}]} diff --git a/assets/icons/src/mesh.hex.mapped.json b/assets/icons/src/mesh.hex.mapped.json new file mode 100644 index 0000000..28cebe7 --- /dev/null +++ b/assets/icons/src/mesh.hex.mapped.json @@ -0,0 +1 @@ +{"shapes": [{"d": "M12 3 L20 7 L20 16 L12 20 L4 16 L4 7 Z", "fill": "soft", "stroke": "line"}, {"d": "M4 7 L12 11 L20 7 M12 11 L12 20", "stroke": "line"}, {"d": "M9.33 4.33 L17.33 8.33 M14.67 4.33 L6.67 8.33 M6.67 8.33 L6.67 17.33 M4 10 L12 14 M14.67 9.67 L14.67 18.67 M12 14 L20 10 M6.67 5.67 L14.67 9.67 M17.33 5.67 L9.33 9.67 M9.33 9.67 L9.33 18.67 M4 13 L12 17 M17.33 8.33 L17.33 17.33 M12 17 L20 13", "stroke": "accent", "width": 1}]} diff --git a/assets/icons/src/mesh.hex.polycube.json b/assets/icons/src/mesh.hex.polycube.json new file mode 100644 index 0000000..a5682dd --- /dev/null +++ b/assets/icons/src/mesh.hex.polycube.json @@ -0,0 +1 @@ +{"shapes": [{"d": "M8 9 L13 11.5 L13 16.5 L8 19 L3 16.5 L3 11.5 Z", "fill": "soft", "stroke": "line"}, {"d": "M3 11.5 L8 14 L13 11.5 M8 14 L8 19", "stroke": "line"}, {"d": "M16 9 L21 11.5 L21 16.5 L16 19 L11 16.5 L11 11.5 Z", "fill": "soft", "stroke": "line"}, {"d": "M11 11.5 L16 14 L21 11.5 M16 14 L16 19", "stroke": "line"}, {"d": "M12 3 L17 5.5 L17 10.5 L12 13 L7 10.5 L7 5.5 Z", "fill": "soft", "stroke": "accent"}, {"d": "M7 5.5 L12 8 L17 5.5 M12 8 L12 13", "stroke": "accent"}]} diff --git a/assets/icons/src/mesh.hex.sweep.json b/assets/icons/src/mesh.hex.sweep.json new file mode 100644 index 0000000..571b39a --- /dev/null +++ b/assets/icons/src/mesh.hex.sweep.json @@ -0,0 +1 @@ +{"shapes": [{"rect": [3, 8, 9, 9], "fill": "soft", "stroke": "line"}, {"d": "M7.5 8 L7.5 17 M3 12.5 L12 12.5", "stroke": "line", "width": 1}, {"d": "M3 8 L8 4 L21 4 L21 13 L12 17 M12 8 L21 4", "stroke": "line", "width": 1.25}, {"d": "M14 13 L20 10 M18.17 12.63 L20 10 L16.8 9.88", "stroke": "accent", "width": 1.5}]} diff --git a/assets/icons/src/mesh.import.orphan.json b/assets/icons/src/mesh.import.orphan.json new file mode 100644 index 0000000..599efdf --- /dev/null +++ b/assets/icons/src/mesh.import.orphan.json @@ -0,0 +1 @@ +{"shapes": [{"rect": [3, 10, 18, 11], "stroke": "line"}, {"d": "M9 10 L9 21 M3 13.67 L21 13.67 M15 10 L15 21 M3 17.33 L21 17.33 M3 13.67 L9 10 M3 17.33 L9 13.67 M3 21 L9 17.33 M9 13.67 L15 10 M9 17.33 L15 13.67 M9 21 L15 17.33 M15 13.67 L21 10 M15 17.33 L21 13.67 M15 21 L21 17.33", "stroke": "line", "width": 1}, {"d": "M12 2 L12 8 M10.47 5.19 L12 8 L13.53 5.19", "stroke": "accent", "width": 1.75}]} diff --git a/assets/icons/src/mesh.layers.json b/assets/icons/src/mesh.layers.json new file mode 100644 index 0000000..7b3bfea --- /dev/null +++ b/assets/icons/src/mesh.layers.json @@ -0,0 +1 @@ +{"shapes": [{"d": "M3 20 L21 20", "stroke": "line", "width": 2.25}, {"d": "M3 17.8 L21 17.8 M3 15.3 L21 15.3 M3 12.3 L21 12.3 M3 8.5 L21 8.5 M3 4 L21 4", "stroke": "accent", "width": 1}, {"d": "M9 4 L9 20 M15 4 L15 20", "stroke": "line", "width": 1}]} diff --git a/assets/icons/src/mesh.node.add.json b/assets/icons/src/mesh.node.add.json new file mode 100644 index 0000000..8cf2f44 --- /dev/null +++ b/assets/icons/src/mesh.node.add.json @@ -0,0 +1 @@ +{"shapes": [{"d": "M3 15 L8 6 L14 13", "stroke": "line", "width": 1}, {"circle": [8, 6, 1.6], "fill": "line", "stroke": null}, {"circle": [3, 15, 1.6], "fill": "line", "stroke": null}, {"circle": [14, 13, 2.4], "fill": "accent", "stroke": "accent"}, {"d": "M15.5 5.5 L21.5 5.5 M18.5 2.5 L18.5 8.5", "stroke": "accent", "width": 1.75}]} diff --git a/assets/icons/src/mesh.node.merge.json b/assets/icons/src/mesh.node.merge.json new file mode 100644 index 0000000..904171d --- /dev/null +++ b/assets/icons/src/mesh.node.merge.json @@ -0,0 +1 @@ +{"shapes": [{"d": "M4 5 L9.5 10.5 M6.43 9.6 L9.5 10.5 L8.6 7.43", "stroke": "line", "width": 1.25}, {"d": "M4 19 L9.5 13.5 M8.6 16.57 L9.5 13.5 L6.43 14.4", "stroke": "line", "width": 1.25}, {"circle": [4, 5, 1.6], "fill": "line", "stroke": null}, {"circle": [4, 19, 1.6], "fill": "line", "stroke": null}, {"circle": [13, 12, 2.6], "fill": "accent", "stroke": "accent"}, {"d": "M15.6 12 L21 12", "stroke": "line", "width": 1.25}]} diff --git a/assets/icons/src/mesh.order.quadratic.json b/assets/icons/src/mesh.order.quadratic.json new file mode 100644 index 0000000..9283df9 --- /dev/null +++ b/assets/icons/src/mesh.order.quadratic.json @@ -0,0 +1 @@ +{"shapes": [{"d": "M12 4 L3 19 L21 19 Z", "fill": "soft", "stroke": "line"}, {"circle": [12, 4, 1.5], "fill": "line", "stroke": null}, {"circle": [3, 19, 1.5], "fill": "line", "stroke": null}, {"circle": [21, 19, 1.5], "fill": "line", "stroke": null}, {"circle": [7.5, 11.5, 1.6], "fill": "accent", "stroke": null}, {"circle": [16.5, 11.5, 1.6], "fill": "accent", "stroke": null}, {"circle": [12, 19, 1.6], "fill": "accent", "stroke": null}]} diff --git a/assets/icons/src/mesh.quad.faces.json b/assets/icons/src/mesh.quad.faces.json new file mode 100644 index 0000000..fd4a0e2 --- /dev/null +++ b/assets/icons/src/mesh.quad.faces.json @@ -0,0 +1 @@ +{"shapes": [{"rect": [4, 4, 16, 16], "fill": "soft", "stroke": "accent"}, {"d": "M9.33 4 L9.33 20 M4 9.33 L20 9.33 M14.67 4 L14.67 20 M4 14.67 L20 14.67", "stroke": "line", "width": 1}]} diff --git a/assets/icons/src/mesh.quality.json b/assets/icons/src/mesh.quality.json new file mode 100644 index 0000000..bbb8ec1 --- /dev/null +++ b/assets/icons/src/mesh.quality.json @@ -0,0 +1 @@ +{"shapes": [{"d": "M3 17 A9 9 0 0 1 21 17", "stroke": "line"}, {"d": "M12 17 L17 10", "stroke": "accent", "width": 2}, {"circle": [12, 17, 1.8], "fill": "accent", "stroke": null}, {"d": "M5.5 12.5 L7 13.5 M12 8 L12 9.8 M18.5 12.5 L17 13.5", "stroke": "line", "width": 1.25}]} diff --git a/assets/icons/src/mesh.region.remesh.json b/assets/icons/src/mesh.region.remesh.json new file mode 100644 index 0000000..47d3e7d --- /dev/null +++ b/assets/icons/src/mesh.region.remesh.json @@ -0,0 +1 @@ +{"shapes": [{"rect": [3, 3, 18, 18], "fill": "soft", "stroke": "line"}, {"d": "M12 3 L12 21 M3 12 L21 12 M3 12 L12 3 M3 21 L12 12 M12 12 L21 3 M12 21 L21 12", "stroke": "line", "width": 1}, {"circle": [16.5, 16.5, 4.5], "stroke": "accent"}, {"d": "M12 16.5 L21 16.5 M16.5 12 L16.5 21", "stroke": "accent", "width": 1}]} diff --git a/assets/icons/src/mesh.size.adapt.json b/assets/icons/src/mesh.size.adapt.json new file mode 100644 index 0000000..7753dce --- /dev/null +++ b/assets/icons/src/mesh.size.adapt.json @@ -0,0 +1 @@ +{"shapes": [{"d": "M3 20 C3 10 10 4 21 4", "stroke": "line"}, {"circle": [3, 20, 1.2], "fill": "accent", "stroke": null}, {"circle": [3.2972159999999997, 16.576255999999997, 1.2], "fill": "accent", "stroke": null}, {"circle": [4.168128, 13.518848000000002, 1.2], "fill": "accent", "stroke": null}, {"circle": [5.3096879999999995, 11.265807999999996, 1.2], "fill": "accent", "stroke": null}, {"circle": [6.810048000000001, 9.293568, 1.2], "fill": "accent", "stroke": null}, {"circle": [8.651208, 7.614127999999999, 1.2], "fill": "accent", "stroke": null}, {"circle": [12.261, 5.566000000000001, 1.2], "fill": "accent", "stroke": null}, {"circle": [21.0, 4.0, 1.2], "fill": "accent", "stroke": null}]} diff --git a/assets/icons/src/mesh.size.global.json b/assets/icons/src/mesh.size.global.json new file mode 100644 index 0000000..1fdf482 --- /dev/null +++ b/assets/icons/src/mesh.size.global.json @@ -0,0 +1 @@ +{"shapes": [{"rect": [4, 9, 16, 12], "fill": "soft", "stroke": "line"}, {"d": "M9.33 9 L9.33 21 M4 13 L20 13 M14.67 9 L14.67 21 M4 17 L20 17", "stroke": "line", "width": 1}, {"d": "M4 3 L4 7 M20 3 L20 7", "stroke": "accent"}, {"d": "M12 5 L5.2 5 M8.01 3.47 L5.2 5 L8.01 6.53", "stroke": "accent", "width": 1.25}, {"d": "M12 5 L18.8 5 M15.99 6.53 L18.8 5 L15.99 3.47", "stroke": "accent", "width": 1.25}]} diff --git a/assets/icons/src/mesh.size.seed.json b/assets/icons/src/mesh.size.seed.json new file mode 100644 index 0000000..af09642 --- /dev/null +++ b/assets/icons/src/mesh.size.seed.json @@ -0,0 +1 @@ +{"shapes": [{"d": "M3 19 C7 5 17 5 21 19", "stroke": "line"}, {"circle": [3, 19, 1.3], "fill": "accent", "stroke": null}, {"circle": [6.024000000000002, 12.280000000000001, 1.3], "fill": "accent", "stroke": null}, {"circle": [9.912000000000003, 8.919999999999998, 1.3], "fill": "accent", "stroke": null}, {"circle": [14.088000000000001, 8.92, 1.3], "fill": "accent", "stroke": null}, {"circle": [17.976000000000003, 12.280000000000001, 1.3], "fill": "accent", "stroke": null}, {"circle": [21.0, 19.0, 1.3], "fill": "accent", "stroke": null}]} diff --git a/assets/icons/src/mesh.smooth.json b/assets/icons/src/mesh.smooth.json new file mode 100644 index 0000000..a69af5b --- /dev/null +++ b/assets/icons/src/mesh.smooth.json @@ -0,0 +1 @@ +{"shapes": [{"d": "M3 9 L6 5 L8 11 L11 6 L13 10 L16 4 L21 8", "stroke": "line", "width": 1.25}, {"d": "M3 17 C8 12 16 22 21 16", "stroke": "accent", "width": 1.75}]} diff --git a/assets/icons/src/mesh.surface.check.json b/assets/icons/src/mesh.surface.check.json new file mode 100644 index 0000000..cae0223 --- /dev/null +++ b/assets/icons/src/mesh.surface.check.json @@ -0,0 +1 @@ +{"shapes": [{"d": "M10 3 L17 6.5 L17 14.5 L10 18 L3 14.5 L3 6.5 Z", "fill": "soft", "stroke": "line"}, {"d": "M3 6.5 L10 10 L17 6.5 M10 10 L10 18", "stroke": "line"}, {"d": "M13.5 17 L16 19.5 L21 14", "stroke": "accent", "width": 1.75}]} diff --git a/assets/icons/src/mesh.tag.json b/assets/icons/src/mesh.tag.json new file mode 100644 index 0000000..f72c765 --- /dev/null +++ b/assets/icons/src/mesh.tag.json @@ -0,0 +1 @@ +{"shapes": [{"d": "M3 3 L12 3 L21 12 L12 21 L3 12 Z", "fill": "soft", "stroke": "accent"}, {"circle": [7.5, 7.5, 1.6], "stroke": "line"}, {"d": "M10 12 L14 16 M12 10 L16 14", "stroke": "line", "width": 1.25}]} diff --git a/assets/icons/src/mesh.tet.generate.json b/assets/icons/src/mesh.tet.generate.json new file mode 100644 index 0000000..7ecd4cb --- /dev/null +++ b/assets/icons/src/mesh.tet.generate.json @@ -0,0 +1 @@ +{"shapes": [{"d": "M12 3 L3 19 L21 19 Z", "fill": "soft", "stroke": "line"}, {"d": "M12 3 L14 14 M3 19 L14 14 M21 19 L14 14", "stroke": "accent", "width": 1.25}]} diff --git a/assets/icons/src/mesh.transition.json b/assets/icons/src/mesh.transition.json new file mode 100644 index 0000000..569ba12 --- /dev/null +++ b/assets/icons/src/mesh.transition.json @@ -0,0 +1 @@ +{"shapes": [{"rect": [3, 4, 18, 16], "fill": "soft", "stroke": "line"}, {"d": "M7.5 4 L7.5 20 M3 9.33 L12 9.33 M3 14.67 L12 14.67", "stroke": "line", "width": 1}, {"d": "M12 4 L21 9.33 L12 14.67 L21 20 M12 14.67 L21 14.67 M12 4 L21 4", "stroke": "line", "width": 1}, {"d": "M12 4 L12 20", "stroke": "accent", "width": 1.75}]} diff --git a/assets/icons/src/mesh.untangle.json b/assets/icons/src/mesh.untangle.json new file mode 100644 index 0000000..53113f3 --- /dev/null +++ b/assets/icons/src/mesh.untangle.json @@ -0,0 +1 @@ +{"shapes": [{"d": "M3 4 L11 11 L11 4 L3 11 Z", "stroke": "line", "width": 1.25}, {"d": "M8 14 L12 18 M8.93 17.1 L12 18 L11.1 14.93", "stroke": "accent", "width": 1.5}, {"rect": [13, 12, 8, 8], "fill": "soft", "stroke": "accent"}]} diff --git a/assets/icons/src/mesh.verify.json b/assets/icons/src/mesh.verify.json new file mode 100644 index 0000000..dc9e79c --- /dev/null +++ b/assets/icons/src/mesh.verify.json @@ -0,0 +1 @@ +{"shapes": [{"rect": [3, 3, 12, 12], "fill": "soft", "stroke": "line"}, {"d": "M9 3 L9 15 M3 9 L15 9 M3 9 L9 3 M3 15 L9 9 M9 9 L15 3 M9 15 L15 9", "stroke": "line", "width": 1}, {"d": "M13.5 17 L16 19.5 L21 14", "stroke": "accent", "width": 1.75}]} diff --git a/assets/icons/src/model.activity.json b/assets/icons/src/model.activity.json new file mode 100644 index 0000000..01ccf0a --- /dev/null +++ b/assets/icons/src/model.activity.json @@ -0,0 +1 @@ +{"shapes": [{"rect": [3, 4, 18, 16], "radius": 1, "stroke": "line"}, {"d": "M3 9 L21 9 M3 14.5 L21 14.5 M9 4 L9 20 M15 4 L15 20", "stroke": "line", "width": 1}, {"rect": [10, 10, 4, 3.5], "fill": "accent", "stroke": null}, {"rect": [16, 15.5, 4, 3.5], "fill": "accent", "stroke": null}]} diff --git a/assets/icons/src/model.amplitude.json b/assets/icons/src/model.amplitude.json new file mode 100644 index 0000000..a0964cc --- /dev/null +++ b/assets/icons/src/model.amplitude.json @@ -0,0 +1 @@ +{"shapes": [{"d": "M3 12 L21 12 M3 4 L3 20", "stroke": "line", "width": 1}, {"d": "M3 12 L3.38 10.83 L3.75 9.7 L4.12 8.67 L4.5 7.76 L4.88 7.01 L5.25 6.46 L5.62 6.12 L6 6 L6.38 6.12 L6.75 6.46 L7.12 7.01 L7.5 7.76 L7.88 8.67 L8.25 9.7 L8.62 10.83 L9 12 L9.38 13.17 L9.75 14.3 L10.12 15.33 L10.5 16.24 L10.88 16.99 L11.25 17.54 L11.62 17.88 L12 18 L12.38 17.88 L12.75 17.54 L13.12 16.99 L13.5 16.24 L13.88 15.33 L14.25 14.3 L14.62 13.17 L15 12 L15.38 10.83 L15.75 9.7 L16.12 8.67 L16.5 7.76 L16.88 7.01 L17.25 6.46 L17.62 6.12 L18 6 L18.38 6.12 L18.75 6.46 L19.12 7.01 L19.5 7.76 L19.88 8.67 L20.25 9.7 L20.62 10.83 L21 12", "stroke": "accent", "width": 1.75}]} diff --git a/assets/icons/src/model.boundary_condition.create.json b/assets/icons/src/model.boundary_condition.create.json new file mode 100644 index 0000000..4a454b6 --- /dev/null +++ b/assets/icons/src/model.boundary_condition.create.json @@ -0,0 +1 @@ +{"shapes": [{"d": "M12 6 L6 16 L18 16 Z", "fill": "soft", "stroke": "accent"}, {"circle": [12, 6, 1.8], "fill": "accent", "stroke": null}, {"d": "M4 19 L20 19 M5 19 L3 21.5 M8 19 L6 21.5 M11 19 L9 21.5 M14 19 L12 21.5 M17 19 L15 21.5 M20 19 L18 21.5", "stroke": "line"}]} diff --git a/assets/icons/src/model.check.json b/assets/icons/src/model.check.json new file mode 100644 index 0000000..8609be7 --- /dev/null +++ b/assets/icons/src/model.check.json @@ -0,0 +1 @@ +{"shapes": [{"rect": [5, 4, 14, 17], "radius": 1.5, "fill": "soft", "stroke": "line"}, {"rect": [9, 2.5, 6, 3], "radius": 1, "fill": "soft", "stroke": "line"}, {"d": "M8.5 13.5 L11 16 L16 10.5", "stroke": "accent", "width": 1.75}]} diff --git a/assets/icons/src/model.coupling.create.json b/assets/icons/src/model.coupling.create.json new file mode 100644 index 0000000..c6ee9e2 --- /dev/null +++ b/assets/icons/src/model.coupling.create.json @@ -0,0 +1 @@ +{"shapes": [{"d": "M3 20 C8 15 16 15 21 20", "stroke": "line", "width": 1.25}, {"d": "M12 5 L4.5 18.5 M12 5 L8.5 16.3 M12 5 L12 15.8 M12 5 L15.5 16.3 M12 5 L19.5 18.5", "stroke": "accent", "width": 1}, {"circle": [12, 5, 2], "fill": "accent", "stroke": null}, {"circle": [4.5, 18.5, 1.2], "fill": "line", "stroke": null}, {"circle": [8.5, 16.3, 1.2], "fill": "line", "stroke": null}, {"circle": [12, 15.8, 1.2], "fill": "line", "stroke": null}, {"circle": [15.5, 16.3, 1.2], "fill": "line", "stroke": null}, {"circle": [19.5, 18.5, 1.2], "fill": "line", "stroke": null}]} diff --git a/assets/icons/src/model.info.json b/assets/icons/src/model.info.json new file mode 100644 index 0000000..fbea847 --- /dev/null +++ b/assets/icons/src/model.info.json @@ -0,0 +1 @@ +{"shapes": [{"circle": [12, 12, 9], "fill": "soft", "stroke": "line"}, {"circle": [12, 7.5, 1.5], "fill": "accent", "stroke": null}, {"d": "M12 11 L12 17", "stroke": "accent", "width": 2}]} diff --git a/assets/icons/src/model.load.create.json b/assets/icons/src/model.load.create.json new file mode 100644 index 0000000..de7097b --- /dev/null +++ b/assets/icons/src/model.load.create.json @@ -0,0 +1 @@ +{"shapes": [{"rect": [3, 16, 18, 4], "fill": "soft", "stroke": "line"}, {"d": "M12 3 L12 14 M10.32 10.93 L12 14 L13.68 10.93", "stroke": "warm", "width": 1.75}, {"d": "M6 7 L6 14 M4.8 11.81 L6 14 L7.2 11.81", "stroke": "warm", "width": 1.25}, {"d": "M18 7 L18 14 M16.8 11.81 L18 14 L19.2 11.81", "stroke": "warm", "width": 1.25}]} diff --git a/assets/icons/src/model.material.create.json b/assets/icons/src/model.material.create.json new file mode 100644 index 0000000..85e2b03 --- /dev/null +++ b/assets/icons/src/model.material.create.json @@ -0,0 +1 @@ +{"shapes": [{"circle": [12, 12, 9], "fill": "soft", "stroke": "line"}, {"d": "M7 9 A6 6 0 0 1 12 6", "stroke": "accent", "width": 1.75}, {"d": "M3.5 13 C8 16 16 16 20.5 13", "stroke": "line", "width": 1}]} diff --git a/assets/icons/src/model.material.damage.json b/assets/icons/src/model.material.damage.json new file mode 100644 index 0000000..e54217a --- /dev/null +++ b/assets/icons/src/model.material.damage.json @@ -0,0 +1 @@ +{"shapes": [{"rect": [4, 3, 16, 18], "fill": "soft", "stroke": "line"}, {"d": "M8 3 L11 9 L9 12 L13 16 L12 21", "stroke": "accent", "width": 1.75}]} diff --git a/assets/icons/src/model.material.eos.json b/assets/icons/src/model.material.eos.json new file mode 100644 index 0000000..a497848 --- /dev/null +++ b/assets/icons/src/model.material.eos.json @@ -0,0 +1 @@ +{"shapes": [{"d": "M4 3 L4 20 L21 20", "stroke": "line"}, {"d": "M6 4 C7 13 11 17 21 18", "stroke": "accent", "width": 1.75}, {"circle": [9.5, 12.6, 1.7], "fill": "warm", "stroke": null}]} diff --git a/assets/icons/src/model.material.hyperelastic.json b/assets/icons/src/model.material.hyperelastic.json new file mode 100644 index 0000000..d2385d8 --- /dev/null +++ b/assets/icons/src/model.material.hyperelastic.json @@ -0,0 +1 @@ +{"shapes": [{"d": "M4 3 L4 20 L21 20", "stroke": "line"}, {"d": "M4 20 C8 14 11 13 14 12 C17 11 19 7 20.5 3", "stroke": "accent", "width": 1.75}]} diff --git a/assets/icons/src/model.material.plasticity.json b/assets/icons/src/model.material.plasticity.json new file mode 100644 index 0000000..4ec7e0f --- /dev/null +++ b/assets/icons/src/model.material.plasticity.json @@ -0,0 +1 @@ +{"shapes": [{"d": "M4 3 L4 20 L21 20", "stroke": "line"}, {"d": "M4 20 L9 8 C11 5 14 5 21 4.5", "stroke": "accent", "width": 1.75}, {"d": "M9 8 L14 20", "stroke": "line", "width": 1, "dash": [1.5, 2]}]} diff --git a/assets/icons/src/model.material.thermal.json b/assets/icons/src/model.material.thermal.json new file mode 100644 index 0000000..bf016f5 --- /dev/null +++ b/assets/icons/src/model.material.thermal.json @@ -0,0 +1 @@ +{"shapes": [{"d": "M10 15 V5 A2 2 0 0 1 14 5 V15", "stroke": "line"}, {"circle": [12, 17.5, 3.5], "fill": "warm", "stroke": "line"}, {"d": "M12 9 L12 15", "stroke": "warm", "width": 2}, {"d": "M16 6 L18 6 M16 9 L18 9 M16 12 L18 12", "stroke": "line", "width": 1.25}]} diff --git a/assets/icons/src/model.orientation.json b/assets/icons/src/model.orientation.json new file mode 100644 index 0000000..2b7151d --- /dev/null +++ b/assets/icons/src/model.orientation.json @@ -0,0 +1 @@ +{"shapes": [{"d": "M8 16 L20 16 M17.19 17.53 L20 16 L17.19 14.47", "stroke": "accent", "width": 1.75}, {"d": "M8 16 L8 3 M9.53 5.81 L8 3 L6.47 5.81", "stroke": "line"}, {"d": "M8 16 L3 21 M3.9 17.93 L3 21 L6.07 20.1", "stroke": "line"}, {"circle": [8, 16, 1.5], "fill": "line", "stroke": null}]} diff --git a/assets/icons/src/model.reference_point.create.json b/assets/icons/src/model.reference_point.create.json new file mode 100644 index 0000000..638c3dc --- /dev/null +++ b/assets/icons/src/model.reference_point.create.json @@ -0,0 +1 @@ +{"shapes": [{"circle": [12, 12, 5.5], "stroke": "line"}, {"circle": [12, 12, 2], "fill": "accent", "stroke": null}, {"d": "M12 2.5 L12 6 M12 18 L12 21.5 M2.5 12 L6 12 M18 12 L21.5 12", "stroke": "line", "width": 1.5}]} diff --git a/assets/icons/src/model.section.composite.json b/assets/icons/src/model.section.composite.json new file mode 100644 index 0000000..683c0f4 --- /dev/null +++ b/assets/icons/src/model.section.composite.json @@ -0,0 +1 @@ +{"shapes": [{"d": "M3 8 L9 4 L21 4 L15 8 Z", "fill": "soft", "stroke": "line"}, {"d": "M3 13 L9 9 L21 9 L15 13 Z", "fill": "soft", "stroke": "line"}, {"d": "M3 18 L9 14 L21 14 L15 18 Z", "fill": "soft", "stroke": "line"}, {"d": "M8 5.5 L12 5.5 M11 7 L15 4.5", "stroke": "accent", "width": 1}, {"d": "M7 16.5 L16 16.5 M10 15 L13 15", "stroke": "accent", "width": 1}, {"d": "M7 11 L14 11", "stroke": "accent", "width": 1}]} diff --git a/assets/icons/src/model.section.create.json b/assets/icons/src/model.section.create.json new file mode 100644 index 0000000..e8f4649 --- /dev/null +++ b/assets/icons/src/model.section.create.json @@ -0,0 +1 @@ +{"shapes": [{"d": "M5 3 L19 3 L19 7 L14 7 L14 17 L19 17 L19 21 L5 21 L5 17 L10 17 L10 7 L5 7 Z", "fill": "soft", "stroke": "accent"}]} diff --git a/assets/icons/src/model.set.create.json b/assets/icons/src/model.set.create.json new file mode 100644 index 0000000..3908301 --- /dev/null +++ b/assets/icons/src/model.set.create.json @@ -0,0 +1 @@ +{"shapes": [{"d": "M5 7 C8 2 18 3 20 8 C22 13 19 21 12 20 C5 19 2 12 5 7 Z", "fill": "soft", "stroke": "accent", "dash": [2.2, 2]}, {"circle": [9, 9, 1.6], "fill": "line", "stroke": null}, {"circle": [15, 8, 1.6], "fill": "line", "stroke": null}, {"circle": [13, 14, 1.6], "fill": "line", "stroke": null}, {"circle": [8, 15, 1.6], "fill": "line", "stroke": null}]} diff --git a/assets/icons/src/model.step.activate.json b/assets/icons/src/model.step.activate.json new file mode 100644 index 0000000..6faebde --- /dev/null +++ b/assets/icons/src/model.step.activate.json @@ -0,0 +1 @@ +{"shapes": [{"rect": [3, 7, 18, 10], "radius": 5, "fill": "soft", "stroke": "line"}, {"circle": [16, 12, 3.2], "fill": "accent", "stroke": "accent"}]} diff --git a/assets/icons/src/model.step.create.json b/assets/icons/src/model.step.create.json new file mode 100644 index 0000000..8df36a3 --- /dev/null +++ b/assets/icons/src/model.step.create.json @@ -0,0 +1 @@ +{"shapes": [{"d": "M3 20 L8 20 L8 14 L13 14 L13 8 L18 8 L18 3", "stroke": "accent", "width": 1.75}, {"d": "M3 20 L21 20 M3 20 L3 3", "stroke": "line", "width": 1}]} diff --git a/assets/icons/src/model.step.explicit.json b/assets/icons/src/model.step.explicit.json new file mode 100644 index 0000000..183ab62 --- /dev/null +++ b/assets/icons/src/model.step.explicit.json @@ -0,0 +1 @@ +{"shapes": [{"circle": [12, 13.5, 7.5], "fill": "soft", "stroke": "line"}, {"d": "M10 3 L14 3 M12 3 L12 6", "stroke": "line", "width": 1.5}, {"d": "M12 13.5 L15.5 9.5", "stroke": "accent", "width": 1.75}, {"circle": [12, 13.5, 1.4], "fill": "accent", "stroke": null}]} diff --git a/assets/icons/src/model.step.heat.json b/assets/icons/src/model.step.heat.json new file mode 100644 index 0000000..7d66578 --- /dev/null +++ b/assets/icons/src/model.step.heat.json @@ -0,0 +1 @@ +{"shapes": [{"d": "M12 3 C15 7 19 10 18 15 C17 19 14 21 12 21 C9 21 6 19 6 15 C6 12 8 11 9 8 C10 10 11 11 12 11 C12 8 11 6 12 3 Z", "fill": "warm", "stroke": "line"}]} diff --git a/assets/icons/src/model.step.nonlinear.json b/assets/icons/src/model.step.nonlinear.json new file mode 100644 index 0000000..03822a0 --- /dev/null +++ b/assets/icons/src/model.step.nonlinear.json @@ -0,0 +1 @@ +{"shapes": [{"d": "M4 3 L4 20 L21 20", "stroke": "line"}, {"d": "M4 20 C10 12 14 8 21 6", "stroke": "accent", "width": 1.75}, {"circle": [8, 15.5, 1.3], "fill": "line", "stroke": null}, {"circle": [12.5, 11.3, 1.3], "fill": "line", "stroke": null}, {"circle": [17, 8.2, 1.3], "fill": "line", "stroke": null}]} diff --git a/assets/icons/src/model.units.json b/assets/icons/src/model.units.json new file mode 100644 index 0000000..bb7aeb0 --- /dev/null +++ b/assets/icons/src/model.units.json @@ -0,0 +1 @@ +{"shapes": [{"d": "M3 15 L15 3 L21 9 L9 21 Z", "fill": "soft", "stroke": "line"}, {"d": "M6 12 L8.5 14.5 M8.25 9.75 L9.75 11.25 M10.5 7.5 L13 10 M12.75 5.25 L14.25 6.75 M15 3 L17.5 5.5", "stroke": "accent", "width": 1.25}]} diff --git a/assets/icons/src/results.animate.json b/assets/icons/src/results.animate.json new file mode 100644 index 0000000..d3d2a81 --- /dev/null +++ b/assets/icons/src/results.animate.json @@ -0,0 +1 @@ +{"shapes": [{"rect": [3, 5, 18, 14], "radius": 2, "fill": "soft", "stroke": "line"}, {"d": "M10 9 L15.5 12 L10 15 Z", "fill": "accent", "stroke": "accent"}, {"d": "M3 8 L6 8 M3 16 L6 16 M18 8 L21 8 M18 16 L21 16", "stroke": "line", "width": 1}]} diff --git a/assets/icons/src/results.contour.json b/assets/icons/src/results.contour.json new file mode 100644 index 0000000..f6ffb4f --- /dev/null +++ b/assets/icons/src/results.contour.json @@ -0,0 +1 @@ +{"shapes": [{"rect": [3, 3, 18, 18], "fill": "soft", "stroke": "line"}, {"d": "M3 9 C9 6 13 13 21 9 L21 3 L3 3 Z", "fill": "warm", "stroke": null}, {"d": "M3 15 C9 12 13 19 21 15 L21 9 C13 13 9 6 3 9 Z", "fill": "accent", "stroke": null}, {"rect": [3, 3, 18, 18], "stroke": "line"}]} diff --git a/assets/icons/src/results.convergence.json b/assets/icons/src/results.convergence.json new file mode 100644 index 0000000..03cbf92 --- /dev/null +++ b/assets/icons/src/results.convergence.json @@ -0,0 +1 @@ +{"shapes": [{"d": "M4 3 L4 20 L21 20", "stroke": "line"}, {"d": "M4 7 L21 7", "stroke": "line", "width": 1, "dash": [1.5, 1.5]}, {"d": "M5 19 C8 10 12 8 21 7.5", "stroke": "accent", "width": 1.5}, {"circle": [6, 15.6, 1.4], "fill": "accent", "stroke": null}, {"circle": [9, 11.4, 1.4], "fill": "accent", "stroke": null}, {"circle": [14, 8.6, 1.4], "fill": "accent", "stroke": null}]} diff --git a/assets/icons/src/results.cut.json b/assets/icons/src/results.cut.json new file mode 100644 index 0000000..4a6b178 --- /dev/null +++ b/assets/icons/src/results.cut.json @@ -0,0 +1 @@ +{"shapes": [{"d": "M12 3 L20 7 L20 16 L12 20 L4 16 L4 7 Z", "fill": "soft", "stroke": "line"}, {"d": "M4 7 L12 11 L20 7 M12 11 L12 20", "stroke": "line"}, {"d": "M8 3 L8 14 L16 22 L16 11 Z", "fill": "accent", "stroke": "accent", "width": 1}]} diff --git a/assets/icons/src/results.deformed.json b/assets/icons/src/results.deformed.json new file mode 100644 index 0000000..e5a02fe --- /dev/null +++ b/assets/icons/src/results.deformed.json @@ -0,0 +1 @@ +{"shapes": [{"rect": [3, 6, 18, 6], "dash": [1.5, 1.5], "stroke": "line", "width": 1}, {"d": "M3 6 C9 6 15 8 21 13 L21 19 C15 14 9 12 3 12 Z", "fill": "soft", "stroke": "accent"}]} diff --git a/assets/icons/src/results.display_group.json b/assets/icons/src/results.display_group.json new file mode 100644 index 0000000..c03ebbc --- /dev/null +++ b/assets/icons/src/results.display_group.json @@ -0,0 +1 @@ +{"shapes": [{"d": "M2.5 12 C6 5.5 18 5.5 21.5 12 C18 18.5 6 18.5 2.5 12 Z", "fill": "soft", "stroke": "line"}, {"circle": [12, 12, 3.5], "fill": "accent", "stroke": "accent"}]} diff --git a/assets/icons/src/results.free_body.json b/assets/icons/src/results.free_body.json new file mode 100644 index 0000000..a461ccc --- /dev/null +++ b/assets/icons/src/results.free_body.json @@ -0,0 +1 @@ +{"shapes": [{"d": "M3 6 L13 6 L13 18 L3 18 Z", "fill": "soft", "stroke": "line"}, {"d": "M13 4 L13 20", "stroke": "accent", "width": 1, "dash": [1.5, 1.5]}, {"d": "M13 9 L20 9 M17.81 10.2 L20 9 L17.81 7.8", "stroke": "warm", "width": 1.5}, {"d": "M13 15 L20 15 M17.81 16.2 L20 15 L17.81 13.8", "stroke": "warm", "width": 1.5}]} diff --git a/assets/icons/src/results.modes.json b/assets/icons/src/results.modes.json new file mode 100644 index 0000000..e31ef99 --- /dev/null +++ b/assets/icons/src/results.modes.json @@ -0,0 +1 @@ +{"shapes": [{"d": "M3 12 L21 12", "stroke": "line", "width": 1, "dash": [1.5, 1.5]}, {"d": "M3 12 C6 4 9 4 12 12 C15 20 18 20 21 12", "stroke": "accent", "width": 1.75}, {"d": "M3 12 C7 6 17 6 21 12", "stroke": "line", "width": 1.25}, {"circle": [3, 12, 1.6], "fill": "line", "stroke": null}, {"circle": [21, 12, 1.6], "fill": "line", "stroke": null}]} diff --git a/assets/icons/src/results.path.json b/assets/icons/src/results.path.json new file mode 100644 index 0000000..ec00f13 --- /dev/null +++ b/assets/icons/src/results.path.json @@ -0,0 +1 @@ +{"shapes": [{"rect": [3, 3, 18, 18], "radius": 2, "fill": "soft", "stroke": "line"}, {"d": "M6 18 L10 9 L14 14 L18 6", "stroke": "accent", "width": 1.5}, {"circle": [6, 18, 1.6], "fill": "accent", "stroke": null}, {"circle": [10, 9, 1.6], "fill": "accent", "stroke": null}, {"circle": [14, 14, 1.6], "fill": "accent", "stroke": null}, {"circle": [18, 6, 1.6], "fill": "accent", "stroke": null}]} diff --git a/assets/icons/src/results.reactions.json b/assets/icons/src/results.reactions.json new file mode 100644 index 0000000..b0831eb --- /dev/null +++ b/assets/icons/src/results.reactions.json @@ -0,0 +1 @@ +{"shapes": [{"d": "M7 12 L3 19 L11 19 Z", "fill": "soft", "stroke": "line"}, {"d": "M2 21 L12 21", "stroke": "line", "width": 1.5}, {"d": "M7 11 L7 3 M8.34 5.46 L7 3 L5.66 5.46", "stroke": "warm", "width": 1.75}, {"d": "M20 4 L14 4 L17.5 8.5 L14 13 L20 13", "stroke": "accent", "width": 1.5}]} diff --git a/assets/icons/src/results.read.json b/assets/icons/src/results.read.json new file mode 100644 index 0000000..89864ab --- /dev/null +++ b/assets/icons/src/results.read.json @@ -0,0 +1 @@ +{"shapes": [{"d": "M8 3 L16 3 L20 7 L20 21 L8 21 Z", "fill": "soft", "stroke": "line"}, {"d": "M16 3 L16 7 L20 7", "stroke": "line"}, {"rect": [11, 13, 2, 5], "fill": "accent", "stroke": null}, {"rect": [14, 10, 2, 8], "fill": "accent", "stroke": null}, {"d": "M2 9 L9 9 M6.19 10.53 L9 9 L6.19 7.47", "stroke": "accent", "width": 1.5}]} diff --git a/assets/icons/src/results.streamlines.json b/assets/icons/src/results.streamlines.json new file mode 100644 index 0000000..a014aef --- /dev/null +++ b/assets/icons/src/results.streamlines.json @@ -0,0 +1 @@ +{"shapes": [{"d": "M3 7 C9 7 9 4 13 4 C17 4 17 7 21 7", "stroke": "accent", "width": 1.5}, {"d": "M3 12 C9 12 9 9 13 9 C17 9 17 12 21 12", "stroke": "accent", "width": 1.5}, {"d": "M3 17 C9 17 9 14 13 14 C17 14 17 17 21 17", "stroke": "accent", "width": 1.5}, {"d": "M18.72 18.25 L21 17 L18.72 15.75", "stroke": "accent"}, {"d": "M3 21 L21 21", "stroke": "line", "width": 1}]} diff --git a/assets/icons/src/results.xy.json b/assets/icons/src/results.xy.json new file mode 100644 index 0000000..bf5a98c --- /dev/null +++ b/assets/icons/src/results.xy.json @@ -0,0 +1 @@ +{"shapes": [{"d": "M4 3 L4 20 L21 20", "stroke": "line"}, {"d": "M5 17 L9 12 L13 13 L17 7 L21 5", "stroke": "accent", "width": 1.5}, {"circle": [9, 12, 1.4], "fill": "accent", "stroke": null}, {"circle": [13, 13, 1.4], "fill": "accent", "stroke": null}, {"circle": [17, 7, 1.4], "fill": "accent", "stroke": null}]} diff --git a/assets/icons/src/solve.blast.json b/assets/icons/src/solve.blast.json new file mode 100644 index 0000000..3a56940 --- /dev/null +++ b/assets/icons/src/solve.blast.json @@ -0,0 +1 @@ +{"shapes": [{"star": [12, 12, 9.5, 4.5, 9], "fill": "warm", "stroke": "line", "width": 1.25}, {"circle": [12, 12, 2], "fill": "soft", "stroke": null}]} diff --git a/assets/icons/src/solve.explicit.json b/assets/icons/src/solve.explicit.json new file mode 100644 index 0000000..94baf45 --- /dev/null +++ b/assets/icons/src/solve.explicit.json @@ -0,0 +1 @@ +{"shapes": [{"d": "M19 3 L19 21", "stroke": "line", "width": 2}, {"circle": [10, 12, 4], "fill": "soft", "stroke": "accent"}, {"d": "M2 9 L5 9 M1.5 12 L4.5 12 M2 15 L5 15", "stroke": "line", "width": 1.25}, {"d": "M15 8 L17 6 M15 16 L17 18", "stroke": "warm", "width": 1.25}]} diff --git a/assets/icons/src/solve.flow.json b/assets/icons/src/solve.flow.json new file mode 100644 index 0000000..05a3415 --- /dev/null +++ b/assets/icons/src/solve.flow.json @@ -0,0 +1 @@ +{"shapes": [{"circle": [12, 12, 3.5], "fill": "soft", "stroke": "line"}, {"d": "M3 6 C8 6 9 4.5 12 4.5 C15 4.5 16 6 21 6", "stroke": "accent", "width": 1.5}, {"d": "M3 18 C8 18 9 19.5 12 19.5 C15 19.5 16 18 21 18", "stroke": "accent", "width": 1.5}, {"d": "M3 12 L7 12 M17 12 L21 12", "stroke": "accent", "width": 1.5}]} diff --git a/assets/icons/src/solve.frequency.json b/assets/icons/src/solve.frequency.json new file mode 100644 index 0000000..66c5b4b --- /dev/null +++ b/assets/icons/src/solve.frequency.json @@ -0,0 +1 @@ +{"shapes": [{"d": "M3 12 L21 12", "stroke": "line", "width": 1, "dash": [1.5, 1.5]}, {"d": "M3 12 C7 3 17 3 21 12", "stroke": "accent", "width": 1.75}, {"d": "M3 12 C7 21 17 21 21 12", "stroke": "line", "width": 1.25}, {"circle": [3, 12, 1.6], "fill": "line", "stroke": null}, {"circle": [21, 12, 1.6], "fill": "line", "stroke": null}]} diff --git a/assets/icons/src/solve.fsi.json b/assets/icons/src/solve.fsi.json new file mode 100644 index 0000000..0714e67 --- /dev/null +++ b/assets/icons/src/solve.fsi.json @@ -0,0 +1 @@ +{"shapes": [{"d": "M3 6 L3.19 5.8 L3.38 5.61 L3.56 5.43 L3.75 5.25 L3.94 5.09 L4.12 4.94 L4.31 4.81 L4.5 4.7 L4.69 4.61 L4.88 4.55 L5.06 4.51 L5.25 4.5 L5.44 4.51 L5.62 4.55 L5.81 4.61 L6 4.7 L6.19 4.81 L6.38 4.94 L6.56 5.09 L6.75 5.25 L6.94 5.43 L7.12 5.61 L7.31 5.8 L7.5 6 L7.69 6.2 L7.88 6.39 L8.06 6.57 L8.25 6.75 L8.44 6.91 L8.62 7.06 L8.81 7.19 L9 7.3 L9.19 7.39 L9.38 7.45 L9.56 7.49 L9.75 7.5 L9.94 7.49 L10.12 7.45 L10.31 7.39 L10.5 7.3 L10.69 7.19 L10.88 7.06 L11.06 6.91 L11.25 6.75 L11.44 6.57 L11.62 6.39 L11.81 6.2 L12 6", "stroke": "accent", "width": 1.5}, {"d": "M3 12 L3.19 11.8 L3.38 11.61 L3.56 11.43 L3.75 11.25 L3.94 11.09 L4.12 10.94 L4.31 10.81 L4.5 10.7 L4.69 10.61 L4.88 10.55 L5.06 10.51 L5.25 10.5 L5.44 10.51 L5.62 10.55 L5.81 10.61 L6 10.7 L6.19 10.81 L6.38 10.94 L6.56 11.09 L6.75 11.25 L6.94 11.43 L7.12 11.61 L7.31 11.8 L7.5 12 L7.69 12.2 L7.88 12.39 L8.06 12.57 L8.25 12.75 L8.44 12.91 L8.62 13.06 L8.81 13.19 L9 13.3 L9.19 13.39 L9.38 13.45 L9.56 13.49 L9.75 13.5 L9.94 13.49 L10.12 13.45 L10.31 13.39 L10.5 13.3 L10.69 13.19 L10.88 13.06 L11.06 12.91 L11.25 12.75 L11.44 12.57 L11.62 12.39 L11.81 12.2 L12 12", "stroke": "accent", "width": 1.5}, {"d": "M3 18 L3.19 17.8 L3.38 17.61 L3.56 17.43 L3.75 17.25 L3.94 17.09 L4.12 16.94 L4.31 16.81 L4.5 16.7 L4.69 16.61 L4.88 16.55 L5.06 16.51 L5.25 16.5 L5.44 16.51 L5.62 16.55 L5.81 16.61 L6 16.7 L6.19 16.81 L6.38 16.94 L6.56 17.09 L6.75 17.25 L6.94 17.43 L7.12 17.61 L7.31 17.8 L7.5 18 L7.69 18.2 L7.88 18.39 L8.06 18.57 L8.25 18.75 L8.44 18.91 L8.62 19.06 L8.81 19.19 L9 19.3 L9.19 19.39 L9.38 19.45 L9.56 19.49 L9.75 19.5 L9.94 19.49 L10.12 19.45 L10.31 19.39 L10.5 19.3 L10.69 19.19 L10.88 19.06 L11.06 18.91 L11.25 18.75 L11.44 18.57 L11.62 18.39 L11.81 18.2 L12 18", "stroke": "accent", "width": 1.5}, {"d": "M15 21 C15 15 16 8 19 3", "stroke": "accent", "width": 2.25}, {"d": "M13 21 L19 21", "stroke": "line", "width": 1.5}, {"d": "M14 8 L17 8 M15.24 8.96 L17 8 L15.24 7.04", "stroke": "warm", "width": 1.25}]} diff --git a/assets/icons/src/solve.probe.json b/assets/icons/src/solve.probe.json new file mode 100644 index 0000000..e1156eb --- /dev/null +++ b/assets/icons/src/solve.probe.json @@ -0,0 +1 @@ +{"shapes": [{"d": "M3 21 L10 14", "stroke": "line", "width": 1.75}, {"circle": [10, 14, 2], "fill": "accent", "stroke": null}, {"rect": [12, 3, 9, 7], "radius": 1.5, "fill": "soft", "stroke": "line"}, {"d": "M10 14 L13 10", "stroke": "line", "width": 1}, {"d": "M14.5 6.5 L18.5 6.5", "stroke": "accent", "width": 1.25}]} diff --git a/assets/icons/src/solve.static.json b/assets/icons/src/solve.static.json new file mode 100644 index 0000000..4387abb --- /dev/null +++ b/assets/icons/src/solve.static.json @@ -0,0 +1 @@ +{"shapes": [{"d": "M3 4 L3 14", "stroke": "line", "width": 2}, {"d": "M3 5 L1 7 M3 8 L1 10 M3 11 L1 13", "stroke": "line", "width": 1}, {"d": "M3 7 L21 7 L21 11 L3 11", "stroke": "line", "width": 1, "dash": [1.5, 1.5]}, {"d": "M3 7 C10 7 16 9 21 13 L21 17 C16 13 10 11 3 11 Z", "fill": "soft", "stroke": "accent"}, {"d": "M21 15 L21 21 M19.8 18.81 L21 21 L22.2 18.81", "stroke": "warm", "width": 1.5}]} diff --git a/crates/engine/src/catalogue.rs b/crates/engine/src/catalogue.rs new file mode 100644 index 0000000..5ef2803 --- /dev/null +++ b/crates/engine/src/catalogue.rs @@ -0,0 +1,450 @@ +//! The capability catalogue: everything ModelCraft does or will do, in one table. +//! +//! Each [`Capability`] is a toolbar entry: its tab and panel, its label and one-line tip, and +//! either the command of the same id it runs ([`Status::Ready`]) or the milestone that brings it +//! ([`Status::Planned`], shown greyed as "Coming soon"). Planned entries are not commands: a +//! command always runs. The icon of an entry is `assets/icons/.svg`. +//! +//! Every registered command is claimed here, as an entry's command or as one of its related +//! commands ([`Capability::more`], the entry's drop-down); the tests check it. A new command +//! claims its place by turning its planned entry into a ready one (or by adding an entry with +//! an icon), see `docs/features.md`. + +use std::fmt::Write; + +use serde::{Deserialize, Serialize}; + +/// The toolbar tabs, in the order of an analyst's workflow. +#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash, Serialize, Deserialize)] +#[serde(rename_all = "snake_case")] +pub enum Tab { + #[default] + Geometry, + Mesh, + Properties, + Assembly, + Steps, + Loads, + Interactions, + Solve, + Results, + Tools, +} + +impl Tab { + pub const ALL: [Tab; 10] = + [Tab::Geometry, Tab::Mesh, Tab::Properties, Tab::Assembly, Tab::Steps, Tab::Loads, Tab::Interactions, Tab::Solve, Tab::Results, Tab::Tools]; + + pub fn label(self) -> &'static str { + match self { + Tab::Geometry => "Geometry", + Tab::Mesh => "Mesh", + Tab::Properties => "Properties", + Tab::Assembly => "Assembly", + Tab::Steps => "Steps", + Tab::Loads => "Loads & BCs", + Tab::Interactions => "Interactions", + Tab::Solve => "Solve", + Tab::Results => "Results", + Tab::Tools => "Tools", + } + } +} + +/// Whether an entry runs today. +#[derive(Clone, Copy, Debug, PartialEq, Eq)] +pub enum Status { + /// Runs the command whose id is the entry's. + Ready, + /// Coming in this roadmap milestone (`M2`…). + Planned { milestone: &'static str }, + /// Runs `deck.write` with this `format` once `modelcraft_decks::FORMATS` has a writer for it; + /// until then coming in `milestone`. + Deck { format: &'static str, milestone: &'static str }, +} + +#[derive(Clone, Copy, Debug, PartialEq, Eq)] +pub struct Capability { + /// Our own dotted id; also the icon's file name. + pub id: &'static str, + pub label: &'static str, + pub tab: Tab, + pub panel: &'static str, + /// One line: what it does. + pub tip: &'static str, + pub status: Status, + /// Related commands in the entry's drop-down (edit, delete…). + pub more: &'static [&'static str], +} + +impl Capability { + /// The command it runs; `None` while it is coming soon. + pub fn command(&self) -> Option<&'static str> { + match self.status { + Status::Ready => Some(self.id), + Status::Planned { .. } => None, + Status::Deck { format, .. } => modelcraft_decks::format(format).map(|_| crate::cmd::deck::WRITE.id), + } + } + + /// The parameters its command starts with (an object; empty for most entries). + pub fn preset(&self) -> serde_json::Value { + match self.status { + Status::Deck { format, .. } => serde_json::json!({ "format": format }), + Status::Ready | Status::Planned { .. } => serde_json::json!({}), + } + } + + /// The milestone that brings it, while it is coming soon. + pub fn milestone(&self) -> Option<&'static str> { + match self.status { + Status::Planned { milestone } => Some(milestone), + Status::Deck { milestone, .. } if self.command().is_none() => Some(milestone), + Status::Ready | Status::Deck { .. } => None, + } + } + + /// The hover text: label, tip and command, or when it comes. + pub fn tooltip(&self) -> String { + match (self.command(), self.milestone()) { + (Some(command), _) => format!("{}\n{}\n{command}", self.label, self.tip), + (None, m) => format!("{} — coming soon ({})\n{}", self.label, m.unwrap_or("later"), self.tip), + } + } +} + +const fn ready(id: &'static str, label: &'static str, tab: Tab, panel: &'static str, tip: &'static str) -> Capability { + Capability { id, label, tab, panel, tip, status: Status::Ready, more: &[] } +} + +const fn ready_more( + id: &'static str, + label: &'static str, + tab: Tab, + panel: &'static str, + tip: &'static str, + more: &'static [&'static str], +) -> Capability { + Capability { more, ..ready(id, label, tab, panel, tip) } +} + +const fn soon(id: &'static str, label: &'static str, tab: Tab, panel: &'static str, milestone: &'static str, tip: &'static str) -> Capability { + Capability { id, label, tab, panel, tip, status: Status::Planned { milestone }, more: &[] } +} + +const fn deck(id: &'static str, label: &'static str, format: &'static str, tip: &'static str) -> Capability { + Capability { id, label, tab: Tab::Solve, panel: "Decks", tip, status: Status::Deck { format, milestone: "M3" }, more: &[] } +} + +use Tab::*; + +/// Every capability in toolbar order: grouped by tab (in [`Tab::ALL`] order), then by panel. +pub static CATALOGUE: &[Capability] = &[ + // ---- Geometry ---- + ready("geometry.open", "Open Design", Geometry, "Import", "Open a SolidCraft design: its bodies with persistent face names"), + ready("geometry.import.mesh", "Tagged Mesh", Geometry, "Import", "Read a face-tagged surface mesh (3MF)"), + ready("geometry.bodies", "Bodies", Geometry, "Inspect", "List the open design's bodies, volumes and named faces"), + ready("geometry.tessellate", "Tessellate", Geometry, "Inspect", "Tessellate a body into a face-tagged boundary surface"), + ready( + "mesh.surface.check", + "Check Surface", + Geometry, + "Inspect", + "Weld, closed, manifold, orientation and self-intersection checks; feature edges", + ), + soon("geometry.partition", "Partition", Geometry, "Prepare", "M5", "Split bodies and faces as SolidCraft features"), + soon("geometry.datum", "Datum Plane", Geometry, "Prepare", "M5", "Construction planes for partitions"), + soon("geometry.midsurface", "Midsurface", Geometry, "Prepare", "M8", "Extract midsurfaces of thin parts for shell meshes"), + // ---- Mesh ---- + soon("mesh.size.global", "Global Size", Mesh, "Size", "M2", "One element size for the whole part"), + soon("mesh.size.seed", "Seed Edges", Mesh, "Size", "M2", "Element counts, sizes and bias per edge and face"), + soon("mesh.size.adapt", "Curvature", Mesh, "Size", "M2", "Refine by curvature and proximity"), + soon("mesh.tet.generate", "Tet Mesh", Mesh, "Tet", "M2", "Delaunay tetrahedral mesh of a body, boundary recovered and refined"), + soon("mesh.order.quadratic", "Quadratic", Mesh, "Tet", "M2", "Second-order elements with mid-side nodes on the geometry"), + ready("mesh.delaunay.points", "Delaunay Points", Mesh, "Tet", "Delaunay tetrahedralization of a point list (debugging aid)"), + soon("mesh.quad.faces", "Quad Faces", Mesh, "Structured Hex", "M5", "All-quad meshes of faces on shared edge nodes"), + soon("mesh.hex.mapped", "Mapped Hex", Mesh, "Structured Hex", "M5", "Mapped hex mesh of six-sided regions"), + soon("mesh.hex.sweep", "Sweep Hex", Mesh, "Structured Hex", "M5", "Hex mesh swept along extrusions and revolutions"), + soon("mesh.hex.decompose", "Decompose", Mesh, "Structured Hex", "M5", "Find sweepable and mappable regions and propose the splits"), + soon("mesh.transition", "Transition", Mesh, "Structured Hex", "M5", "Conforming tet–hex interfaces with pyramids"), + soon("mesh.hex.generate", "All-Hex", Mesh, "Automatic Hex", "M6", "Octree dual all-hex mesh of any part"), + soon("mesh.hex.dominant", "Hex-Dominant", Mesh, "Automatic Hex", "M6", "Hex-dominant mesh by recombining tets"), + soon("mesh.hex.polycube", "Polycube", Mesh, "Automatic Hex", "M6", "Polycube hex mesh of blocky parts"), + soon("mesh.smooth", "Smooth", Mesh, "Improve", "M6", "Smooth node positions, keeping every element valid"), + soon("mesh.untangle", "Untangle", Mesh, "Improve", "M6", "Repair inverted elements"), + soon("mesh.layers", "Layers", Mesh, "Improve", "M6", "Boundary padding and layers through thin walls"), + ready_more("mesh.node.add", "Node", Mesh, "Edit", "Add a node", &["mesh.node.remove"]), + ready_more("mesh.element.add", "Element", Mesh, "Edit", "Add an element on existing nodes", &["mesh.element.remove"]), + soon("mesh.node.merge", "Merge Nodes", Mesh, "Edit", "M6", "Merge coincident nodes"), + soon("mesh.region.remesh", "Remesh Region", Mesh, "Edit", "M6", "Remesh a region in place; split and collapse elements"), + soon("mesh.import.orphan", "Orphan Mesh", Mesh, "Edit", "M6", "Import a mesh without geometry"), + ready("mesh.quality", "Quality", Mesh, "Verify", "Quality metrics and the certified validity check, failing elements listed"), + soon("mesh.verify", "Verify Set", Mesh, "Verify", "M2", "Quality and validity per set"), + ready_more("mesh.tag", "Tag Geometry", Mesh, "Verify", "Tag elements, faces, edges and nodes with the geometry they mesh", &["mesh.tag.clear"]), + // ---- Properties ---- + ready_more( + "model.material.create", + "Material", + Properties, + "Materials", + "Elastic (isotropic, orthotropic) material with density", + &["model.material.edit", "model.material.delete"], + ), + soon("model.material.plasticity", "Plasticity", Properties, "Materials", "M8", "Plastic hardening data"), + soon("model.material.hyperelastic", "Hyperelastic", Properties, "Materials", "M8", "Hyperelastic material models"), + soon("model.material.damage", "Damage", Properties, "Materials", "M8", "Damage initiation and evolution"), + soon("model.material.thermal", "Thermal", Properties, "Materials", "M8", "Conductivity, specific heat and expansion"), + soon( + "model.material.eos", + "Equation of State", + Properties, + "Materials", + "M11", + "Polynomial, ideal gas, Mie–Grüneisen, JWL and tabulated equations of state", + ), + ready_more( + "model.section.create", + "Section", + Properties, + "Sections", + "Solid, shell, beam or rod section assigned to a set, with its element formulation", + &["model.section.edit", "model.section.delete"], + ), + soon("model.section.composite", "Composite", Properties, "Sections", "M8", "Composite layups and continuum shells"), + soon("model.orientation", "Orientation", Properties, "Sections", "M8", "Material orientations"), + ready_more( + "model.set.create", + "Set", + Properties, + "Sets", + "A set of nodes, elements and faces, or of named geometry that survives remeshing", + &["model.set.edit", "model.set.delete", "model.set.resolve"], + ), + ready("model.units", "Units", Properties, "Model", "The model's unit system (never converted)"), + // ---- Assembly ---- + soon("assembly.instance", "Instances", Assembly, "Instances", "M7", "Part instances placed from SolidCraft occurrences"), + // ---- Steps ---- + ready_more( + "model.step.create", + "Step", + Steps, + "Steps", + "A linear static or frequency step with its output", + &["model.step.edit", "model.step.delete"], + ), + ready("model.step.activate", "Activate", Steps, "Steps", "Choose which loads and boundary conditions act in a step"), + ready("model.activity", "Step Table", Steps, "Steps", "The step by load and boundary condition table"), + soon("model.amplitude", "Amplitude", Steps, "Procedures", "M7", "Time and frequency amplitudes"), + soon("model.step.nonlinear", "Nonlinear", Steps, "Procedures", "M7", "Nonlinear static steps"), + soon("model.step.explicit", "Explicit", Steps, "Procedures", "M8", "Explicit dynamic steps"), + soon("model.step.heat", "Heat Transfer", Steps, "Procedures", "M8", "Heat transfer steps"), + // ---- Loads & BCs ---- + ready_more( + "model.boundary_condition.create", + "Boundary Condition", + Loads, + "Boundary Conditions", + "Fixed, displacement or symmetry condition on a set or reference point", + &["model.boundary_condition.edit", "model.boundary_condition.delete"], + ), + ready_more( + "model.load.create", + "Load", + Loads, + "Loads", + "Force, moment, pressure, traction, gravity or body force", + &["model.load.edit", "model.load.delete"], + ), + soon("flow.domain", "Fluid Domain", Loads, "Flow", "M12", "The fluid grid voxelised from the face-tagged surface"), + soon("flow.boundary", "Inlet & Outlet", Loads, "Flow", "M12", "Velocity inlets, pressure outlets and walls"), + // ---- Interactions ---- + ready_more( + "model.reference_point.create", + "Reference Point", + Interactions, + "Constraints", + "A reference point for couplings, loads and boundary conditions", + &["model.reference_point.edit", "model.reference_point.delete"], + ), + ready_more( + "model.coupling.create", + "Coupling", + Interactions, + "Constraints", + "Kinematic or distributing coupling of a set to a reference point", + &["model.coupling.edit", "model.coupling.delete"], + ), + soon("interaction.tie", "Tie", Interactions, "Constraints", "M7", "Tie non-matching meshes together"), + soon("interaction.contact.general", "General Contact", Interactions, "Contact", "M7", "Contact between everything that touches, with friction"), + soon("interaction.contact.pair", "Contact Pair", Interactions, "Contact", "M7", "Contact between two surfaces"), + soon("interaction.contact.find", "Find Contacts", Interactions, "Contact", "M7", "Detect contact pairs automatically"), + soon("interaction.rigid_wall", "Rigid Wall", Interactions, "Contact", "M10", "Rigid walls for explicit dynamics"), + soon("interaction.bolt", "Bolt Load", Interactions, "Connectors", "M7", "Bolt pretension"), + soon("interaction.spring", "Spring", Interactions, "Connectors", "M7", "Springs and dashpots"), + soon("interaction.mass", "Point Mass", Interactions, "Connectors", "M7", "Point masses and inertia"), + soon("interaction.connector", "Connector", Interactions, "Connectors", "M7", "Connector elements between points"), + soon("interaction.fsi", "FSI Interface", Interactions, "Coupled", "M13", "The fluid–structure interface"), + // ---- Solve ---- + ready("model.check", "Check Model", Solve, "Check", "Name every missing or bad definition before writing or solving"), + deck("deck.write.abaqus", "Abaqus Input", "abaqus", "Write an Abaqus input file (.inp)"), + deck("deck.write.nastran", "Nastran Deck", "nastran", "Write Nastran bulk data (SOL 101, 103)"), + deck("deck.write.lsdyna", "LS-DYNA Deck", "lsdyna", "Write an LS-DYNA keyword file"), + soon("deck.read", "Read Deck", Solve, "Decks", "M9", "Read a deck, keeping keywords ModelCraft does not know"), + ready("solve.static", "Static", Solve, "Implicit", "Linear static solve of a step with ModelCraft's own solver"), + ready("solve.frequency", "Frequency", Solve, "Implicit", "Natural frequencies and mode shapes of a frequency step"), + soon("solve.explicit", "Explicit", Solve, "Explicit", "M10", "Explicit dynamics: central differences, contact, erosion"), + soon("solve.blast", "Blast & Impact", Solve, "Explicit", "M14", "EOS-driven fluids with fluid–structure contact (ALE or SPH)"), + soon("solve.flow", "Lattice Boltzmann", Solve, "Fluids", "M12", "Lattice Boltzmann flow on the CPU or the GPU"), + soon("solve.fsi", "Fluid–Structure", Solve, "Fluids", "M13", "Coupled fluid and structure solve"), + // ---- Results ---- + soon("results.deformed", "Deformed", Results, "Display", "M4", "The deformed shape"), + soon("results.contour", "Contours", Results, "Display", "M4", "Contour plots of stress, strain and displacement"), + soon("results.modes", "Mode Shapes", Results, "Display", "M4", "Mode shapes of a frequency step"), + soon("results.animate", "Animate", Results, "Display", "M9", "Animate modes and time histories"), + ready("solve.probe", "Probe", Results, "Query", "Displacement, reaction and stress at nodes, or a mode shape"), + soon("results.reactions", "Reactions", Results, "Query", "M4", "Reaction force and moment sums"), + soon("results.free_body", "Free Body", Results, "Query", "M9", "Free-body forces across a cut"), + soon("results.xy", "XY Plot", Results, "Plots", "M9", "Plot a quantity against time or another"), + soon("results.path", "Path Plot", Results, "Plots", "M9", "Plot a quantity along a path"), + soon("results.cut", "Cut", Results, "Plots", "M9", "Section cuts through the model"), + soon("results.display_group", "Display Group", Results, "Plots", "M9", "Show and hide parts of the model"), + soon("results.streamlines", "Streamlines", Results, "Plots", "M12", "Streamlines and flow fields"), + soon("results.read", "Read Results", Results, "Files", "M9", "Read results in public formats"), + soon("results.convergence", "Convergence", Results, "Files", "M9", "Mesh convergence studies"), + // ---- Tools ---- + ready("model.info", "Model Info", Tools, "Model", "Node and element counts and the model summary"), + ready("file.open", "Open Model", Tools, "File", "Open a .modelcraft model"), + ready("file.save", "Save", Tools, "File", "Save the model to its .modelcraft file"), + ready("file.save_as", "Save As", Tools, "File", "Save the model to a new .modelcraft file"), + ready_more( + "file.recover", + "Recover", + Tools, + "File", + "Open a model autosaved by an app that crashed or closed with unsaved changes", + &["file.recovery.list", "file.recovery.discard"], + ), + ready("edit.undo", "Undo", Tools, "History", "Undo the last command that changed the model"), + ready("edit.redo", "Redo", Tools, "History", "Redo the command undone last"), +]; + +/// The catalogue entry with this id. +pub fn find(id: &str) -> Option<&'static Capability> { + CATALOGUE.iter().find(|c| c.id == id) +} + +/// The entries of a tab (one run of the catalogue). +pub fn tab_entries(tab: Tab) -> &'static [Capability] { + let start = CATALOGUE.iter().position(|c| c.tab == tab).unwrap_or(CATALOGUE.len()); + let rest = CATALOGUE.get(start..).unwrap_or_default(); + rest.get(..rest.iter().take_while(|c| c.tab == tab).count()).unwrap_or_default() +} + +/// The panels of a tab in order, each the run of its entries (never empty). +pub fn panels(tab: Tab) -> impl Iterator { + tab_entries(tab).chunk_by(|a, b| a.panel == b.panel) +} + +/// `docs/features.md`: every capability by tab and panel, ready or coming soon. +pub fn features_page() -> String { + let ready = CATALOGUE.iter().filter(|c| c.command().is_some()).count(); + let mut md = String::from( + "# Features\n\n\ + Generated from the capability catalogue (`crates/engine/src/catalogue.rs`) by\n\ + `cargo run -p modelcraft-cli -- features > docs/features.md`; a test fails when it is out of date.\n\ + Every entry is a toolbar button. **Ready** entries run their command; **coming soon** entries are\n\ + shown greyed with the roadmap milestone that brings them (ROADMAP.md).\n\n", + ); + let _ = writeln!(md, "{ready} ready, {} coming soon.", CATALOGUE.len() - ready); + for tab in Tab::ALL { + let _ = write!(md, "\n## {}\n\n| Panel | Capability | Status | Command |\n|---|---|---|---|\n", tab.label()); + for c in tab_entries(tab) { + let status = c.milestone().map_or_else(|| "ready".to_string(), |m| format!("coming soon ({m})")); + let preset = c.preset(); + let main = + c.command().map(|id| if preset.as_object().is_some_and(|o| !o.is_empty()) { format!("`{id} {preset}`") } else { format!("`{id}`") }); + let commands: Vec = main.into_iter().chain(c.more.iter().map(|id| format!("`{id}`"))).collect(); + let _ = writeln!(md, "| {} | {} — {} | {status} | {} |", c.panel, c.label, c.tip, commands.join(", ")); + } + } + md +} + +#[cfg(test)] +mod tests { + use super::*; + use crate::{commands, find_command}; + + #[test] + fn every_command_is_claimed_and_every_ready_entry_runs_a_command() { + let mut claimed: Vec<&str> = Vec::new(); + for c in CATALOGUE { + if let Some(command) = c.command() { + assert!(find_command(command).is_some(), "{}: `{command}` is not a registered command", c.id); + claimed.push(command); + } else { + assert!(c.more.is_empty(), "{}: a planned entry has no commands", c.id); + } + for m in c.more { + assert!(find_command(m).is_some(), "{}: `{m}` is not a registered command", c.id); + claimed.push(m); + } + } + for spec in commands() { + let n = claimed.iter().filter(|c| **c == spec.id).count(); + assert!(n >= 1, "command `{}` has no catalogue entry (a ready entry or an entry's `more`)", spec.id); + } + } + + /// Deck entries follow the writers: one entry per format, ready exactly when its writer is in + /// `modelcraft_decks::FORMATS`, running `deck.write` with its format. + #[test] + fn deck_entries_follow_the_writers() { + let decks: Vec<(&Capability, &str)> = + CATALOGUE.iter().filter_map(|c| if let Status::Deck { format, .. } = c.status { Some((c, format)) } else { None }).collect(); + for f in modelcraft_decks::FORMATS { + assert!(decks.iter().any(|(_, name)| *name == f.name), "deck format `{}` has no catalogue entry", f.name); + } + for (c, format) in decks { + let written = modelcraft_decks::format(format).is_some(); + assert_eq!(c.command(), written.then_some("deck.write"), "{}", c.id); + assert_eq!(c.milestone().is_none(), written, "{}", c.id); + assert_eq!(c.preset(), serde_json::json!({"format": format})); + } + assert_eq!(find("deck.write.abaqus").and_then(Capability::command), Some("deck.write")); + } + + #[test] + fn entries_are_well_formed() { + let mut ids: Vec<&str> = CATALOGUE.iter().map(|c| c.id).collect(); + for c in CATALOGUE { + assert!(c.id.split('.').count() >= 2 && c.id.chars().all(|ch| ch.is_ascii_lowercase() || ch == '.' || ch == '_'), "{}", c.id); + assert!(!c.label.is_empty() && !c.panel.is_empty() && !c.tip.is_empty(), "{}", c.id); + if let Some(m) = c.milestone() { + assert!(m.strip_prefix('M').is_some_and(|n| n.parse::().is_ok_and(|n| (1..=14).contains(&n))), "{}: {m}", c.id); + } + } + ids.sort_unstable(); + let n = ids.len(); + ids.dedup(); + assert_eq!(ids.len(), n, "catalogue ids are unique"); + // Tabs are runs in Tab::ALL order, and each panel is one run within its tab. + let total: usize = Tab::ALL.iter().map(|t| tab_entries(*t).len()).sum(); + assert_eq!(total, CATALOGUE.len(), "every tab's entries are together, in Tab::ALL order"); + let order: Vec = + CATALOGUE.iter().map(|c| c.tab).collect::>().chunk_by(|a, b| a == b).filter_map(|r| r.first().copied()).collect(); + assert_eq!(order, Tab::ALL); + for tab in Tab::ALL { + let names: Vec<&str> = panels(tab).filter_map(|p| p.first().map(|c| c.panel)).collect(); + assert!(!names.is_empty(), "{tab:?} has no entries"); + assert!(names.iter().enumerate().all(|(i, n)| !names[..i].contains(n)), "{tab:?}: a panel's entries are together: {names:?}"); + } + } + + #[test] + fn features_page_is_current() { + let path = std::path::Path::new(env!("CARGO_MANIFEST_DIR")).join("../../docs/features.md"); + let committed = std::fs::read_to_string(&path).unwrap_or_default().replace("\r\n", "\n"); + assert!(committed == features_page(), "docs/features.md is out of date: run `cargo run -p modelcraft-cli -- features > docs/features.md`"); + } +} diff --git a/crates/engine/src/lib.rs b/crates/engine/src/lib.rs index 1dab7e5..6f2f318 100644 --- a/crates/engine/src/lib.rs +++ b/crates/engine/src/lib.rs @@ -13,6 +13,7 @@ #![forbid(unsafe_code)] pub mod autosave; +pub mod catalogue; pub mod cmd; pub mod history; pub mod sample; diff --git a/crates/ui-egui/Cargo.toml b/crates/ui-egui/Cargo.toml index 91cd008..b8aeb7a 100644 --- a/crates/ui-egui/Cargo.toml +++ b/crates/ui-egui/Cargo.toml @@ -17,3 +17,4 @@ egui-wgpu = { workspace = true } serde = { workspace = true } serde_json = { workspace = true } log = { workspace = true } +resvg = { workspace = true } diff --git a/crates/ui-egui/build.rs b/crates/ui-egui/build.rs new file mode 100644 index 0000000..31e05fd --- /dev/null +++ b/crates/ui-egui/build.rs @@ -0,0 +1,23 @@ +//! Embeds the toolbar icons: `assets/icons/*.svg` become `ICONS`, a sorted `(id, svg)` table +//! (`src/icons.rs`). + +use std::fmt::Write; +use std::path::PathBuf; + +fn main() -> Result<(), Box> { + let manifest = PathBuf::from(std::env::var("CARGO_MANIFEST_DIR")?); + let dir = manifest.join("../../assets/icons"); + println!("cargo:rerun-if-changed={}", dir.display()); + let mut ids: Vec = + std::fs::read_dir(&dir)?.flatten().filter_map(|e| e.file_name().to_str().and_then(|n| n.strip_suffix(".svg")).map(str::to_string)).collect(); + ids.sort(); + let mut out = String::from("/// Every toolbar icon by catalogue id, sorted by id.\npub static ICONS: &[(&str, &str)] = &[\n"); + for id in &ids { + let path = dir.join(format!("{id}.svg")); + println!("cargo:rerun-if-changed={}", path.display()); + let _ = writeln!(out, " ({id:?}, include_str!({:?})),", path.display().to_string()); + } + out.push_str("];\n"); + std::fs::write(PathBuf::from(std::env::var("OUT_DIR")?).join("icons.rs"), out)?; + Ok(()) +} diff --git a/crates/ui-egui/src/control.rs b/crates/ui-egui/src/control.rs index 880f5d0..3b1f079 100644 --- a/crates/ui-egui/src/control.rs +++ b/crates/ui-egui/src/control.rs @@ -114,6 +114,7 @@ pub fn handle(app: &mut ModelApp, ctx: &egui::Context, req: &ControlRequest) -> "model": {"nodes": app.session.model.nodes().len(), "elements": app.session.model.elements().len()}, "version": crate::VERSION, })), + "ui.toolbar" => ok(crate::toolbar::describe(app)), "ui.set" => { let mut cur = serde_json::to_value(&app.ui).unwrap_or(json!({})); if let (Some(o), Some(src)) = (cur.as_object_mut(), p.as_object()) { @@ -367,6 +368,8 @@ mod tests { json!({"width": 1e12, "height": -5, "path": ""}), json!({"command": 5, "params": "x", "commands": {"a": 1}}), json!({"key": "NoSuchKey", "text": 7, "view": null, "points": [[1], "x", null]}), + json!({"tab": "nope", "command": "mesh.tet.generate"}), + json!({"tab": 3}), ]; for method in [ "engine.execute", @@ -384,6 +387,7 @@ mod tests { "ui.worldToScreen", "ui.resize", "ui.render", + "ui.toolbar", ] { for p in &hostile { let _ = call(&mut app, method, p.clone()); @@ -392,6 +396,21 @@ mod tests { assert!(app.synthetic.len() < 1000); } + #[test] + fn the_toolbar_lists_every_entry_and_switches_tabs() { + let mut app = ModelApp::new(Session::default()); + assert_eq!(call(&mut app, "ui.set", json!({"tab": "mesh"}))["ok"], true); + let r = call(&mut app, "ui.toolbar", json!({})); + assert_eq!(r["result"]["tab"], "mesh", "{r}"); + let entries = r["result"]["entries"].as_array().unwrap(); + assert_eq!(entries.len(), modelcraft_engine::catalogue::CATALOGUE.len()); + let tet = entries.iter().find(|e| e["id"] == "mesh.tet.generate").unwrap(); + assert_eq!((tet["coming_soon"].as_str(), tet["command"].is_null()), (Some("M2"), true)); + assert_eq!(call(&mut app, "ui.set", json!({"tab": "nope"}))["ok"], false); + let r = call(&mut app, "ui.start", json!({"command": "mesh.tet.generate"})); + assert_eq!((r["ok"].as_bool(), r["error"].as_str()), (Some(false), Some("Tet Mesh is coming soon (M2)"))); + } + #[test] fn screenshots_are_saved_as_png() { let image = egui::ColorImage::filled([4, 3], egui::Color32::RED); diff --git a/crates/ui-egui/src/icons.rs b/crates/ui-egui/src/icons.rs new file mode 100644 index 0000000..5cf1ee6 --- /dev/null +++ b/crates/ui-egui/src/icons.rs @@ -0,0 +1,132 @@ +//! Toolbar icons: original artwork drawn with VectorCraft (`assets/icons`, `cargo xtask icons`), +//! embedded at build time and rasterised with resvg. +//! +//! Icons are drawn in four palette roles, each in one fixed colour (the dark theme's). Before +//! rasterising, every role colour is replaced by the theme token it stands for, so the same SVG +//! serves the dark and light themes and the greyed "coming soon" state. Textures are cached per +//! icon, theme, state and pixel size. + +use std::collections::HashMap; + +use egui::{Color32, TextureHandle}; +use resvg::{tiny_skia, usvg}; + +use crate::theme::Tokens; + +include!(concat!(env!("OUT_DIR"), "/icons.rs")); + +/// The palette roles' colours in the SVG files. Keep in step with `PALETTE` in +/// `xtask/src/icons.rs`. +pub const PALETTE: [&str; 4] = ["#dde2ea", "#4f9ce8", "#2d4e70", "#f0b44a"]; + +/// Largest icon side rasterised (pixels). +const MAX_PX: u32 = 256; + +/// The icon's SVG text. +pub fn svg(id: &str) -> Option<&'static str> { + ICONS.binary_search_by(|(k, _)| (*k).cmp(id)).ok().and_then(|i| ICONS.get(i)).map(|(_, s)| *s) +} + +/// The colours the palette roles (line, accent, soft, warm) take in a theme, greyed when the +/// entry is not available yet. +pub fn colours(t: &Tokens, enabled: bool) -> [Color32; 4] { + if enabled { [t.text, t.accent, t.accent_soft, t.warm] } else { [t.text_dim, t.text_dim, t.panel_header, t.text_dim] } +} + +/// The SVG with each palette colour replaced by its role's colour. +pub fn recolour(svg: &str, colours: [Color32; 4]) -> String { + let mut out = svg.to_string(); + for (from, to) in PALETTE.iter().zip(colours) { + let hex = format!("#{:02x}{:02x}{:02x}", to.r(), to.g(), to.b()); + out = out.replace(&format!("\"{from}\""), &format!("\"{hex}\"")); + } + out +} + +/// Rasterise an SVG to a `px` × `px` image. +pub fn rasterise(svg: &str, px: u32) -> Result { + let px = px.clamp(1, MAX_PX); + let tree = usvg::Tree::from_str(svg, &usvg::Options::default()).map_err(|e| e.to_string())?; + let mut pixmap = tiny_skia::Pixmap::new(px, px).ok_or("empty icon")?; + let size = tree.size(); + let scale = px as f32 / size.width().max(size.height()).max(f32::EPSILON); + resvg::render(&tree, tiny_skia::Transform::from_scale(scale, scale), &mut pixmap.as_mut()); + Ok(egui::ColorImage::from_rgba_premultiplied([px as usize, px as usize], pixmap.data())) +} + +/// Icon textures by (id, enabled) for one theme and pixel size; `None` when the icon is missing +/// or does not rasterise, so it is not tried again every frame. A change of theme or size +/// (zoom) drops the old textures. +#[derive(Default)] +pub struct IconCache { + theme_px: Option<(bool, u32)>, + textures: HashMap<(&'static str, bool), Option>, +} + +impl IconCache { + pub fn get(&mut self, ctx: &egui::Context, id: &'static str, dark: bool, enabled: bool, px: u32) -> Option { + if self.theme_px != Some((dark, px)) { + self.textures.clear(); + self.theme_px = Some((dark, px)); + } + self.textures + .entry((id, enabled)) + .or_insert_with(|| { + let svg = svg(id)?; + let image = rasterise(&recolour(svg, colours(&Tokens::get(dark), enabled)), px).map_err(|e| log::warn!("icon {id}: {e}")).ok()?; + Some(ctx.load_texture(format!("icon:{id}:{dark}:{enabled}:{px}"), image, egui::TextureOptions::LINEAR)) + }) + .clone() + } +} + +#[cfg(test)] +mod tests { + use super::*; + use modelcraft_engine::catalogue::CATALOGUE; + + #[test] + fn every_catalogue_entry_has_an_icon_and_every_icon_an_entry() { + for c in CATALOGUE { + assert!(svg(c.id).is_some(), "no icon assets/icons/{}.svg", c.id); + } + for (id, _) in ICONS { + assert!(CATALOGUE.iter().any(|c| c.id == *id), "assets/icons/{id}.svg belongs to no catalogue entry"); + } + assert!(ICONS.windows(2).all(|w| w[0].0 < w[1].0), "sorted for the binary search"); + } + + /// Icons use only the palette, so recolouring reaches every colour, and they rasterise. + #[test] + fn icons_use_only_palette_colours_and_rasterise() { + for (id, text) in ICONS { + for part in text.split('"').skip(1).step_by(2) { + if part.starts_with('#') { + assert!(PALETTE.contains(&part), "{id}: colour {part} is not in the palette"); + } + } + let image = rasterise(text, 24).unwrap(); + assert!(image.pixels.iter().any(|p| p.a() > 0), "{id} draws nothing"); + } + } + + /// The SVG colours are the dark theme's own, so the dark theme draws icons as authored. + #[test] + fn the_palette_is_the_dark_themes_colours() { + let hex: Vec = colours(&Tokens::dark(), true).iter().map(|c| format!("#{:02x}{:02x}{:02x}", c.r(), c.g(), c.b())).collect(); + assert_eq!(hex, PALETTE); + } + + #[test] + fn recolouring_follows_the_theme_and_greys_planned_entries() { + let svg = r##""##; + let light = Tokens::light(); + let out = recolour(svg, colours(&light, true)); + assert!(out.contains("stroke=\"#1f6fc4\"") && out.contains("fill=\"#c6dcf4\""), "{out}"); + let grey = recolour(svg, colours(&light, false)); + let dim = light.text_dim; + assert!(grey.contains(&format!("stroke=\"#{:02x}{:02x}{:02x}\"", dim.r(), dim.g(), dim.b())), "{grey}"); + assert!(rasterise("not svg", 24).is_err()); + assert_eq!(rasterise(svg, 100_000).unwrap().size, [MAX_PX as usize; 2]); + } +} diff --git a/crates/ui-egui/src/lib.rs b/crates/ui-egui/src/lib.rs index b9be209..c42e30b 100644 --- a/crates/ui-egui/src/lib.rs +++ b/crates/ui-egui/src/lib.rs @@ -13,14 +13,17 @@ pub mod control; pub mod gpu; +pub mod icons; pub mod panels; pub mod scene; pub mod theme; +pub mod toolbar; pub mod viewport; use std::sync::mpsc::{Receiver, Sender}; use modelcraft_engine::Session; +use modelcraft_engine::catalogue::{self, Tab}; use modelcraft_render::{Camera, DisplayMesh, Scene, StandardView}; use serde::{Deserialize, Serialize}; use serde_json::{Value, json}; @@ -41,11 +44,21 @@ pub struct UiState { pub dark: bool, pub show_tree: bool, pub show_commands: bool, + /// The toolbar tab shown. + pub tab: Tab, } impl Default for UiState { fn default() -> Self { - UiState { style: Style::ShadedEdges, show_nodes: false, perspective: false, dark: true, show_tree: true, show_commands: true } + UiState { + style: Style::ShadedEdges, + show_nodes: false, + perspective: false, + dark: true, + show_tree: true, + show_commands: true, + tab: Tab::default(), + } } } @@ -102,6 +115,9 @@ pub struct ModelApp { pub status: Option, pub dialog: Option, pub viewport: Viewport, + pub icons: icons::IconCache, + /// The toolbar's buttons drawn last frame, by catalogue id (for the control channel). + pub toolbar_rects: Vec<(&'static str, egui::Rect, toolbar::Fit)>, /// The GPU adapter, for the status bar and diagnostics. pub gpu_info: Option, /// Bumped whenever the model may have changed. @@ -131,6 +147,8 @@ impl ModelApp { status: None, dialog: None, viewport: Viewport::default(), + icons: icons::IconCache::default(), + toolbar_rects: Vec::new(), gpu_info: None, revision: 0, display: (None, DisplayMesh::default()), @@ -200,15 +218,29 @@ impl ModelApp { r } - /// What clicking a command in the Commands panel does: a command without parameters runs, - /// one with parameters opens its form. Programmatic calls use [`ModelApp::run`] instead. + /// What clicking a toolbar entry or a command in the Commands panel does: a command without + /// parameters runs, one with parameters opens its form. `id` is a command or a catalogue + /// entry; an entry that is coming soon does nothing and says when it comes. Programmatic calls + /// use [`ModelApp::run`] instead. pub fn start(&mut self, id: &str) -> Result<(), String> { - let spec = modelcraft_engine::find_command(id).ok_or_else(|| format!("unknown command `{id}`"))?; + let (command, preset) = match catalogue::find(id) { + Some(c) => match c.command() { + Some(command) => (command, c.preset()), + None => { + let e = format!("{} is coming soon ({})", c.label, c.milestone().unwrap_or("later")); + self.set_status(e.clone(), false); + return Err(e); + } + }, + None => (id, json!({})), + }; + let spec = modelcraft_engine::find_command(command).ok_or_else(|| format!("unknown command `{command}`"))?; if spec.params.trim() == "{}" { self.dialog = None; self.run(spec.id, json!({})).map(|_| ()) } else { - self.dialog = Some(ParamsDialog { command: spec.id, text: "{}".into(), error: None }); + // The form starts with the entry's preset; the rest (a path…) is filled in there. + self.dialog = Some(ParamsDialog { command: spec.id, text: preset.to_string(), error: None }); Ok(()) } } @@ -360,6 +392,7 @@ impl ModelApp { pub fn ui(&mut self, ui: &mut egui::Ui) { self.show_gpu_errors(); panels::menu_bar(self, ui); + toolbar::toolbar(self, ui); panels::status_bar(self, ui); if self.ui.show_tree { panels::model_tree(self, ui); @@ -480,6 +513,24 @@ mod tests { assert!(app.start("no.such").is_err()); } + #[test] + fn toolbar_entries_start_their_command_and_planned_ones_do_nothing() { + let mut app = ModelApp::new(Session::default()); + app.start("model.material.create").unwrap(); + assert_eq!(app.dialog.as_ref().map(|d| d.command), Some("model.material.create")); + app.dialog = None; + let journal = app.session.journal.len(); + let err = app.start("mesh.tet.generate").unwrap_err(); + assert_eq!(err, "Tet Mesh is coming soon (M2)"); + assert!(app.dialog.is_none()); + assert_eq!(app.session.journal.len(), journal); + assert_eq!(app.status.as_ref().map(|s| s.error), Some(false)); + // A deck entry opens deck.write's form with its format filled in. + app.start("deck.write.abaqus").unwrap(); + let d = app.dialog.as_ref().unwrap(); + assert_eq!((d.command, d.text.as_str()), ("deck.write", r#"{"format":"abaqus"}"#)); + } + #[test] fn the_sample_fills_the_view_and_renders() { let mut app = ModelApp::new(Session::default()); diff --git a/crates/ui-egui/src/theme.rs b/crates/ui-egui/src/theme.rs index 053aa9c..9f25a60 100644 --- a/crates/ui-egui/src/theme.rs +++ b/crates/ui-egui/src/theme.rs @@ -22,6 +22,8 @@ pub struct Tokens { pub hover: Color32, pub error: Color32, pub ok: Color32, + /// Loads and heat in icons. + pub warm: Color32, // ---- viewport ---- /// Background gradient, top and bottom. pub viewport_top: Color32, @@ -62,6 +64,7 @@ impl Tokens { hover: Color32::from_rgb(0x3c, 0x43, 0x4f), error: Color32::from_rgb(0xf0, 0x6c, 0x64), ok: Color32::from_rgb(0x8c, 0xc8, 0x8c), + warm: Color32::from_rgb(0xf0, 0xb4, 0x4a), viewport_top: Color32::from_rgb(0x3a, 0x41, 0x4d), viewport_bottom: Color32::from_rgb(0x1e, 0x22, 0x28), overlay: Color32::from_rgba_unmultiplied_const(0x1c, 0x20, 0x26, 0xd0), @@ -93,6 +96,7 @@ impl Tokens { hover: Color32::from_rgb(0xd8, 0xde, 0xe6), error: Color32::from_rgb(0xc0, 0x30, 0x28), ok: Color32::from_rgb(0x2c, 0x7a, 0x3a), + warm: Color32::from_rgb(0xc0, 0x7a, 0x14), viewport_top: Color32::from_rgb(0xf0, 0xf3, 0xf7), viewport_bottom: Color32::from_rgb(0xc8, 0xd0, 0xdc), overlay: Color32::from_rgba_unmultiplied_const(0xea, 0xee, 0xf3, 0xe0), diff --git a/crates/ui-egui/src/toolbar.rs b/crates/ui-egui/src/toolbar.rs new file mode 100644 index 0000000..0d40cbb --- /dev/null +++ b/crates/ui-egui/src/toolbar.rs @@ -0,0 +1,283 @@ +//! The toolbar: one tab per stage of the analyst's workflow, each a row of panels of icon buttons, +//! all from the capability catalogue (`modelcraft_engine::catalogue`). +//! +//! When the window is too narrow for labelled buttons, every panel goes icon-only (the label is +//! in the tooltip), then panels collapse from the right into one drop-down button each. +//! +//! A ready entry starts its command (the same as the Commands panel: a command without +//! parameters runs, one with parameters opens its form); its related commands (edit, delete…) +//! are in the drop-down beside it. A planned entry is drawn greyed with its milestone and does +//! nothing; its tooltip says when it comes. Structure follows SolidCraft's +//! `crates/ui-egui/src/toolbar.rs` (MIT OR Apache-2.0), see ATTRIBUTION.md. + +use std::sync::Arc; + +use egui::{Align2, FontId, Galley, Rect, RichText, Sense, Stroke, vec2}; +use modelcraft_engine::catalogue::{self, Capability, Tab}; +use serde::Serialize; + +use crate::ModelApp; +use crate::theme::Tokens; + +/// Icon side (points). +const ICON: f32 = 24.0; +/// Button height with its label, and the width the label wraps at (points). +const BUTTON_H: f32 = 60.0; +const LABEL_W: f32 = 64.0; +/// A button without its label (compact panels). +const COMPACT: f32 = ICON + 12.0; +/// The drop-down strip beside a button with related commands. +const ARROW_W: f32 = 12.0; +/// A collapsed panel: one button that opens the list of its entries. +const COLLAPSED_W: f32 = COMPACT + ARROW_W; +/// Room a panel separator takes. +const PANEL_GAP: f32 = 13.0; +/// Room between buttons of a panel. +const BUTTON_GAP: f32 = 2.0; + +/// How a panel is drawn on a toolbar that may be too narrow for every labelled button. +#[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize)] +#[serde(rename_all = "snake_case")] +pub enum Fit { + /// Icon and label. + Full, + /// Icon only; the label is in the tooltip. + Compact, + /// One button that lists the panel's entries. + Collapsed, +} + +/// Fit panels into `room`: every panel in full when they all fit; otherwise every panel compact, +/// then panels wider than a collapsed one collapse from the right until the row fits. Nothing is +/// dropped. +pub fn fit(full: &[f32], compact: &[f32], room: f32) -> Vec { + let total = |widths: &mut dyn Iterator| -> f32 { widths.map(|w| w + PANEL_GAP).sum() }; + if total(&mut full.iter().copied()) <= room { + return vec![Fit::Full; full.len()]; + } + let mut fits = vec![Fit::Compact; compact.len()]; + for i in (0..fits.len()).rev() { + let width = total(&mut compact.iter().zip(&fits).map(|(w, f)| if *f == Fit::Collapsed { COLLAPSED_W } else { *w })); + if width <= room { + break; + } + if let (Some(f), Some(w)) = (fits.get_mut(i), compact.get(i)) + && *w > COLLAPSED_W + { + *f = Fit::Collapsed; + } + } + fits +} + +/// An entry's label laid out under its icon (at most two lines). +fn label(ui: &egui::Ui, t: &Tokens, c: &Capability) -> Arc { + let colour = if c.command().is_some() { t.text } else { t.text_dim }; + let mut job = egui::text::LayoutJob::simple(c.label.to_string(), FontId::proportional(11.0), colour, LABEL_W); + job.wrap.max_rows = 2; + job.halign = egui::Align::Center; + ui.painter().layout_job(job) +} + +fn arrow_w(c: &Capability) -> f32 { + if c.command().is_some() && !c.more.is_empty() { ARROW_W } else { 0.0 } +} + +fn panel_width(widths: impl Iterator) -> f32 { + let (sum, n) = widths.fold((0.0, 0usize), |(s, n), w| (s + w, n + 1)); + sum + BUTTON_GAP * n.saturating_sub(1) as f32 +} + +pub fn toolbar(app: &mut ModelApp, ui: &mut egui::Ui) { + let t = Tokens::get(app.ui.dark); + let mut action = None; + egui::Panel::top("mc_toolbar").frame(egui::Frame::NONE.fill(t.panel).inner_margin(egui::Margin::symmetric(8, 4))).show(ui, |ui| { + ui.horizontal(|ui| { + for tab in Tab::ALL { + let text = RichText::new(tab.label()).color(if app.ui.tab == tab { t.accent } else { t.text }); + if ui.selectable_label(app.ui.tab == tab, text).clicked() { + app.ui.tab = tab; + } + } + }); + ui.add_space(2.0); + app.toolbar_rects.clear(); + let panels: Vec<&'static [Capability]> = catalogue::panels(app.ui.tab).collect(); + let labels: Vec>> = panels.iter().map(|p| p.iter().map(|c| label(ui, &t, c)).collect()).collect(); + let full: Vec = panels + .iter() + .zip(&labels) + .map(|(p, l)| panel_width(p.iter().zip(l).map(|(c, g)| g.size().x.max(ICON + 12.0) + 8.0 + arrow_w(c)))) + .collect(); + let compact: Vec = panels.iter().map(|p| panel_width(p.iter().map(|c| COMPACT + arrow_w(c)))).collect(); + let fits = fit(&full, &compact, ui.available_width()); + ui.horizontal(|ui| { + for (i, ((entries, galleys), fit)) in panels.iter().zip(labels).zip(&fits).enumerate() { + let Some(panel) = entries.first().map(|c| c.panel) else { continue }; + if i > 0 { + ui.separator(); + } + ui.vertical(|ui| { + ui.horizontal(|ui| { + ui.spacing_mut().item_spacing.x = BUTTON_GAP; + let clicked = match fit { + Fit::Collapsed => collapsed(app, ui, &t, panel, entries), + Fit::Full | Fit::Compact => { + let mut clicked = None; + for (c, galley) in entries.iter().zip(galleys) { + let galley = (*fit == Fit::Full).then_some(galley); + clicked = button(app, ui, &t, c, galley).or(clicked); + } + clicked + } + }; + action = clicked.or(action); + }); + let width = ui.min_rect().width(); + ui.allocate_ui(vec2(width, 14.0), |ui| { + ui.centered_and_justified(|ui| ui.add(egui::Label::new(RichText::new(panel).small().color(t.text_dim)).truncate())); + }); + }); + } + }); + }); + if let Some(id) = action { + // Errors already show in the status bar. + let _ = app.start(id); + } +} + +fn icon(app: &mut ModelApp, ui: &egui::Ui, t: &Tokens, c: &'static Capability, rect: Rect) { + let px = (ICON * ui.ctx().pixels_per_point()).round() as u32; + let p = ui.painter(); + match app.icons.get(ui.ctx(), c.id, app.ui.dark, c.command().is_some(), px) { + Some(tex) => p.image(tex.id(), rect, Rect::from_min_max(egui::pos2(0.0, 0.0), egui::pos2(1.0, 1.0)), egui::Color32::WHITE), + None => p.rect_stroke(rect.shrink(3.0), 3.0, Stroke::new(1.0, t.text_dim), egui::StrokeKind::Inside), + }; +} + +/// One entry's button, with its label when `label` is given; returns the id to start when it +/// (or its drop-down) was clicked. +fn button(app: &mut ModelApp, ui: &mut egui::Ui, t: &Tokens, c: &'static Capability, label: Option>) -> Option<&'static str> { + let enabled = c.command().is_some(); + let size = match &label { + Some(g) => vec2(g.size().x.max(ICON + 12.0) + 8.0, BUTTON_H), + None => vec2(COMPACT, COMPACT), + }; + let (rect, resp) = ui.allocate_exact_size(size, if enabled { Sense::click() } else { Sense::hover() }); + app.toolbar_rects.push((c.id, rect, if label.is_some() { Fit::Full } else { Fit::Compact })); + if resp.hovered() && enabled { + ui.painter().rect_filled(rect, 4.0, t.hover); + } + let icon_rect = Rect::from_center_size(egui::pos2(rect.center().x, rect.top() + 6.0 + ICON / 2.0), vec2(ICON, ICON)); + icon(app, ui, t, c, icon_rect); + let p = ui.painter(); + if let Some(g) = label { + p.galley(egui::pos2(rect.center().x, icon_rect.bottom() + 4.0), g, t.text); + } + if let Some(m) = c.milestone() { + let text = p.layout_no_wrap(m.to_string(), FontId::proportional(9.0), t.text); + let badge = Rect::from_min_size(egui::pos2(rect.right() - text.size().x - 4.0, rect.top()), text.size() + vec2(4.0, 0.0)); + p.rect_filled(badge, 3.0, t.panel_header); + p.rect_stroke(badge, 3.0, Stroke::new(1.0, t.border), egui::StrokeKind::Inside); + p.galley(badge.min + vec2(2.0, 0.0), text, t.text); + } + let resp = resp.on_hover_ui(|ui| { + ui.label(c.tooltip()); + }); + let mut action = resp.clicked().then_some(c.id); + if enabled && !c.more.is_empty() { + let (arrow, arrow_resp) = ui.allocate_exact_size(vec2(ARROW_W, size.y), Sense::click()); + if arrow_resp.hovered() { + ui.painter().rect_filled(arrow, 4.0, t.hover); + } + ui.painter().text(arrow.center(), Align2::CENTER_CENTER, "▾", FontId::proportional(11.0), t.text_dim); + let arrow_resp = arrow_resp.on_hover_text(format!("More {} commands", c.label)); + egui::Popup::menu(&arrow_resp).show(|ui| { + for id in c.more { + if ui.button(crate::command_label(id)).clicked() { + action = Some(*id); + } + } + }); + } + action +} + +/// A collapsed panel: its first entry's icon and a drop-down listing every entry (and their +/// related commands), coming-soon ones greyed with their milestone. +fn collapsed(app: &mut ModelApp, ui: &mut egui::Ui, t: &Tokens, panel: &str, entries: &'static [Capability]) -> Option<&'static str> { + let first = entries.first()?; + let (rect, resp) = ui.allocate_exact_size(vec2(COLLAPSED_W, COMPACT), Sense::click()); + for c in entries { + app.toolbar_rects.push((c.id, rect, Fit::Collapsed)); + } + if resp.hovered() { + ui.painter().rect_filled(rect, 4.0, t.hover); + } + icon(app, ui, t, first, Rect::from_min_size(rect.min + vec2(6.0, 6.0), vec2(ICON, ICON))); + ui.painter().text(egui::pos2(rect.right() - ARROW_W / 2.0, rect.center().y), Align2::CENTER_CENTER, "▾", FontId::proportional(11.0), t.text_dim); + let resp = resp.on_hover_text(panel); + let mut action = None; + egui::Popup::menu(&resp).show(|ui| { + for c in entries { + match c.milestone() { + Some(m) => { + ui.add_enabled(false, egui::Button::new(format!("{} — coming soon ({m})", c.label))); + } + None => { + if ui.button(c.label).on_hover_text(c.tip).clicked() { + action = Some(c.id); + } + for id in c.more { + if ui.button(format!(" {}", crate::command_label(id))).clicked() { + action = Some(*id); + } + } + } + } + } + }); + action +} + +/// The toolbar as the control channel reports it: the tabs, the current tab, and every entry +/// with its status and, on the current tab, its button (screen points, last frame). +pub fn describe(app: &ModelApp) -> serde_json::Value { + let entries: Vec = catalogue::CATALOGUE + .iter() + .map(|c| { + let shown = app.toolbar_rects.iter().find(|(id, ..)| *id == c.id); + let rect = shown.map(|(_, r, _)| [r.left(), r.top(), r.width(), r.height()]); + serde_json::json!({ + "id": c.id, + "label": c.label, + "tab": c.tab, + "panel": c.panel, + "command": c.command(), + "more": c.more, + "coming_soon": c.milestone(), + "rect": rect, + "fit": shown.map(|(.., f)| f), + }) + }) + .collect(); + serde_json::json!({"tab": app.ui.tab, "tabs": Tab::ALL, "entries": entries}) +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn panels_go_compact_then_collapse_from_the_right() { + let full = [200.0, 300.0, 100.0]; + let compact = [80.0, 120.0, 40.0]; + assert_eq!(fit(&full, &compact, 700.0), vec![Fit::Full; 3]); + assert_eq!(fit(&full, &compact, 400.0), vec![Fit::Compact; 3]); + // The last panel is narrower compact than collapsed, so the middle one goes first. + assert_eq!(fit(&full, &compact, 230.0), vec![Fit::Compact, Fit::Collapsed, Fit::Compact]); + assert_eq!(fit(&full, &compact, 10.0), vec![Fit::Collapsed, Fit::Collapsed, Fit::Compact], "nothing is dropped"); + assert!(fit(&[], &[], 0.0).is_empty()); + } +} diff --git a/docs/control-protocol.md b/docs/control-protocol.md index 86dfb27..e53d285 100644 --- a/docs/control-protocol.md +++ b/docs/control-protocol.md @@ -35,9 +35,10 @@ Commands never open forms when run this way. `modelcraft-cli commands` prints th | Method | Params | Notes | |---|---|---| | `ui.inspect` | — | view settings (`ui`), camera, viewport rect (points), renderer (`gpu`/`cpu`) and adapter, open command form, status bar, node and element counts, version | -| `ui.set` | any view setting: `style` (`shaded_edges`, `shaded`, `wireframe`), `show_nodes`, `perspective`, `dark`, `show_tree`, `show_commands` | an unknown setting or value is an error; returns the settings | +| `ui.set` | any view setting: `style` (`shaded_edges`, `shaded`, `wireframe`), `show_nodes`, `perspective`, `dark`, `show_tree`, `show_commands`, `tab` (the toolbar tab: `geometry`, `mesh`, `properties`, `assembly`, `steps`, `loads`, `interactions`, `solve`, `results`, `tools`) | an unknown setting or value is an error; returns the settings | | `ui.view` | `view`: `front`, `back`, `left`, `right`, `top`, `bottom`, `iso`, `home` (iso and fit), `fit` | returns the camera | -| `ui.start` | `command` | like clicking the command in the Commands panel: a command without parameters runs, one with parameters opens its form | +| `ui.toolbar` | — | the toolbar (`ui.set {tab}` switches tabs): `tab`, `tabs`, and every catalogue entry (docs/features.md) with `id`, `label`, `tab`, `panel`, `command` (null while coming soon), `more` (its drop-down's commands), `coming_soon` (the milestone, or null), `rect` (its button in screen points last frame, on the shown tab; a collapsed panel's entries share its drop-down button) and `fit` (`full`, `compact` icon-only, or `collapsed` into the panel's drop-down, by window width) | +| `ui.start` | `command`: a command or toolbar entry id | like clicking it on the toolbar or in the Commands panel: a command without parameters runs, one with parameters opens its form; an entry that is coming soon is an error naming its milestone | | `ui.dialog` | `params?` (JSON object, fills the form), `run?`, `cancel?` | drives the open command form; `run` returns the command's result and closes the form on success | | `ui.click` | `x`, `y` (screen points), `button?`: `left`/`right`/`middle`, `shift?`, `ctrl?`, `alt?`, `double?` | real pointer input | | `ui.move` | `x`, `y` | | diff --git a/docs/features.md b/docs/features.md new file mode 100644 index 0000000..3468cc0 --- /dev/null +++ b/docs/features.md @@ -0,0 +1,158 @@ +# Features + +Generated from the capability catalogue (`crates/engine/src/catalogue.rs`) by +`cargo run -p modelcraft-cli -- features > docs/features.md`; a test fails when it is out of date. +Every entry is a toolbar button. **Ready** entries run their command; **coming soon** entries are +shown greyed with the roadmap milestone that brings them (ROADMAP.md). + +35 ready, 65 coming soon. + +## Geometry + +| Panel | Capability | Status | Command | +|---|---|---|---| +| Import | Open Design — Open a SolidCraft design: its bodies with persistent face names | ready | `geometry.open` | +| Import | Tagged Mesh — Read a face-tagged surface mesh (3MF) | ready | `geometry.import.mesh` | +| Inspect | Bodies — List the open design's bodies, volumes and named faces | ready | `geometry.bodies` | +| Inspect | Tessellate — Tessellate a body into a face-tagged boundary surface | ready | `geometry.tessellate` | +| Inspect | Check Surface — Weld, closed, manifold, orientation and self-intersection checks; feature edges | ready | `mesh.surface.check` | +| Prepare | Partition — Split bodies and faces as SolidCraft features | coming soon (M5) | | +| Prepare | Datum Plane — Construction planes for partitions | coming soon (M5) | | +| Prepare | Midsurface — Extract midsurfaces of thin parts for shell meshes | coming soon (M8) | | + +## Mesh + +| Panel | Capability | Status | Command | +|---|---|---|---| +| Size | Global Size — One element size for the whole part | coming soon (M2) | | +| Size | Seed Edges — Element counts, sizes and bias per edge and face | coming soon (M2) | | +| Size | Curvature — Refine by curvature and proximity | coming soon (M2) | | +| Tet | Tet Mesh — Delaunay tetrahedral mesh of a body, boundary recovered and refined | coming soon (M2) | | +| Tet | Quadratic — Second-order elements with mid-side nodes on the geometry | coming soon (M2) | | +| Tet | Delaunay Points — Delaunay tetrahedralization of a point list (debugging aid) | ready | `mesh.delaunay.points` | +| Structured Hex | Quad Faces — All-quad meshes of faces on shared edge nodes | coming soon (M5) | | +| Structured Hex | Mapped Hex — Mapped hex mesh of six-sided regions | coming soon (M5) | | +| Structured Hex | Sweep Hex — Hex mesh swept along extrusions and revolutions | coming soon (M5) | | +| Structured Hex | Decompose — Find sweepable and mappable regions and propose the splits | coming soon (M5) | | +| Structured Hex | Transition — Conforming tet–hex interfaces with pyramids | coming soon (M5) | | +| Automatic Hex | All-Hex — Octree dual all-hex mesh of any part | coming soon (M6) | | +| Automatic Hex | Hex-Dominant — Hex-dominant mesh by recombining tets | coming soon (M6) | | +| Automatic Hex | Polycube — Polycube hex mesh of blocky parts | coming soon (M6) | | +| Improve | Smooth — Smooth node positions, keeping every element valid | coming soon (M6) | | +| Improve | Untangle — Repair inverted elements | coming soon (M6) | | +| Improve | Layers — Boundary padding and layers through thin walls | coming soon (M6) | | +| Edit | Node — Add a node | ready | `mesh.node.add`, `mesh.node.remove` | +| Edit | Element — Add an element on existing nodes | ready | `mesh.element.add`, `mesh.element.remove` | +| Edit | Merge Nodes — Merge coincident nodes | coming soon (M6) | | +| Edit | Remesh Region — Remesh a region in place; split and collapse elements | coming soon (M6) | | +| Edit | Orphan Mesh — Import a mesh without geometry | coming soon (M6) | | +| Verify | Quality — Quality metrics and the certified validity check, failing elements listed | ready | `mesh.quality` | +| Verify | Verify Set — Quality and validity per set | coming soon (M2) | | +| Verify | Tag Geometry — Tag elements, faces, edges and nodes with the geometry they mesh | ready | `mesh.tag`, `mesh.tag.clear` | + +## Properties + +| Panel | Capability | Status | Command | +|---|---|---|---| +| Materials | Material — Elastic (isotropic, orthotropic) material with density | ready | `model.material.create`, `model.material.edit`, `model.material.delete` | +| Materials | Plasticity — Plastic hardening data | coming soon (M8) | | +| Materials | Hyperelastic — Hyperelastic material models | coming soon (M8) | | +| Materials | Damage — Damage initiation and evolution | coming soon (M8) | | +| Materials | Thermal — Conductivity, specific heat and expansion | coming soon (M8) | | +| Materials | Equation of State — Polynomial, ideal gas, Mie–Grüneisen, JWL and tabulated equations of state | coming soon (M11) | | +| Sections | Section — Solid, shell, beam or rod section assigned to a set, with its element formulation | ready | `model.section.create`, `model.section.edit`, `model.section.delete` | +| Sections | Composite — Composite layups and continuum shells | coming soon (M8) | | +| Sections | Orientation — Material orientations | coming soon (M8) | | +| Sets | Set — A set of nodes, elements and faces, or of named geometry that survives remeshing | ready | `model.set.create`, `model.set.edit`, `model.set.delete`, `model.set.resolve` | +| Model | Units — The model's unit system (never converted) | ready | `model.units` | + +## Assembly + +| Panel | Capability | Status | Command | +|---|---|---|---| +| Instances | Instances — Part instances placed from SolidCraft occurrences | coming soon (M7) | | + +## Steps + +| Panel | Capability | Status | Command | +|---|---|---|---| +| Steps | Step — A linear static or frequency step with its output | ready | `model.step.create`, `model.step.edit`, `model.step.delete` | +| Steps | Activate — Choose which loads and boundary conditions act in a step | ready | `model.step.activate` | +| Steps | Step Table — The step by load and boundary condition table | ready | `model.activity` | +| Procedures | Amplitude — Time and frequency amplitudes | coming soon (M7) | | +| Procedures | Nonlinear — Nonlinear static steps | coming soon (M7) | | +| Procedures | Explicit — Explicit dynamic steps | coming soon (M8) | | +| Procedures | Heat Transfer — Heat transfer steps | coming soon (M8) | | + +## Loads & BCs + +| Panel | Capability | Status | Command | +|---|---|---|---| +| Boundary Conditions | Boundary Condition — Fixed, displacement or symmetry condition on a set or reference point | ready | `model.boundary_condition.create`, `model.boundary_condition.edit`, `model.boundary_condition.delete` | +| Loads | Load — Force, moment, pressure, traction, gravity or body force | ready | `model.load.create`, `model.load.edit`, `model.load.delete` | +| Flow | Fluid Domain — The fluid grid voxelised from the face-tagged surface | coming soon (M12) | | +| Flow | Inlet & Outlet — Velocity inlets, pressure outlets and walls | coming soon (M12) | | + +## Interactions + +| Panel | Capability | Status | Command | +|---|---|---|---| +| Constraints | Reference Point — A reference point for couplings, loads and boundary conditions | ready | `model.reference_point.create`, `model.reference_point.edit`, `model.reference_point.delete` | +| Constraints | Coupling — Kinematic or distributing coupling of a set to a reference point | ready | `model.coupling.create`, `model.coupling.edit`, `model.coupling.delete` | +| Constraints | Tie — Tie non-matching meshes together | coming soon (M7) | | +| Contact | General Contact — Contact between everything that touches, with friction | coming soon (M7) | | +| Contact | Contact Pair — Contact between two surfaces | coming soon (M7) | | +| Contact | Find Contacts — Detect contact pairs automatically | coming soon (M7) | | +| Contact | Rigid Wall — Rigid walls for explicit dynamics | coming soon (M10) | | +| Connectors | Bolt Load — Bolt pretension | coming soon (M7) | | +| Connectors | Spring — Springs and dashpots | coming soon (M7) | | +| Connectors | Point Mass — Point masses and inertia | coming soon (M7) | | +| Connectors | Connector — Connector elements between points | coming soon (M7) | | +| Coupled | FSI Interface — The fluid–structure interface | coming soon (M13) | | + +## Solve + +| Panel | Capability | Status | Command | +|---|---|---|---| +| Check | Check Model — Name every missing or bad definition before writing or solving | ready | `model.check` | +| Decks | Abaqus Input — Write an Abaqus input file (.inp) | ready | `deck.write {"format":"abaqus"}` | +| Decks | Nastran Deck — Write Nastran bulk data (SOL 101, 103) | ready | `deck.write {"format":"nastran"}` | +| Decks | LS-DYNA Deck — Write an LS-DYNA keyword file | ready | `deck.write {"format":"lsdyna"}` | +| Decks | Read Deck — Read a deck, keeping keywords ModelCraft does not know | coming soon (M9) | | +| Implicit | Static — Linear static solve of a step with ModelCraft's own solver | ready | `solve.static` | +| Implicit | Frequency — Natural frequencies and mode shapes of a frequency step | ready | `solve.frequency` | +| Explicit | Explicit — Explicit dynamics: central differences, contact, erosion | coming soon (M10) | | +| Explicit | Blast & Impact — EOS-driven fluids with fluid–structure contact (ALE or SPH) | coming soon (M14) | | +| Fluids | Lattice Boltzmann — Lattice Boltzmann flow on the CPU or the GPU | coming soon (M12) | | +| Fluids | Fluid–Structure — Coupled fluid and structure solve | coming soon (M13) | | + +## Results + +| Panel | Capability | Status | Command | +|---|---|---|---| +| Display | Deformed — The deformed shape | coming soon (M4) | | +| Display | Contours — Contour plots of stress, strain and displacement | coming soon (M4) | | +| Display | Mode Shapes — Mode shapes of a frequency step | coming soon (M4) | | +| Display | Animate — Animate modes and time histories | coming soon (M9) | | +| Query | Probe — Displacement, reaction and stress at nodes, or a mode shape | ready | `solve.probe` | +| Query | Reactions — Reaction force and moment sums | coming soon (M4) | | +| Query | Free Body — Free-body forces across a cut | coming soon (M9) | | +| Plots | XY Plot — Plot a quantity against time or another | coming soon (M9) | | +| Plots | Path Plot — Plot a quantity along a path | coming soon (M9) | | +| Plots | Cut — Section cuts through the model | coming soon (M9) | | +| Plots | Display Group — Show and hide parts of the model | coming soon (M9) | | +| Plots | Streamlines — Streamlines and flow fields | coming soon (M12) | | +| Files | Read Results — Read results in public formats | coming soon (M9) | | +| Files | Convergence — Mesh convergence studies | coming soon (M9) | | + +## Tools + +| Panel | Capability | Status | Command | +|---|---|---|---| +| Model | Model Info — Node and element counts and the model summary | ready | `model.info` | +| File | Open Model — Open a .modelcraft model | ready | `file.open` | +| File | Save — Save the model to its .modelcraft file | ready | `file.save` | +| File | Save As — Save the model to a new .modelcraft file | ready | `file.save_as` | +| File | Recover — Open a model autosaved by an app that crashed or closed with unsaved changes | ready | `file.recover`, `file.recovery.list`, `file.recovery.discard` | +| History | Undo — Undo the last command that changed the model | ready | `edit.undo` | +| History | Redo — Redo the command undone last | ready | `edit.redo` | diff --git a/xtask/src/assets.rs b/xtask/src/assets.rs index b446d1d..e62655b 100644 --- a/xtask/src/assets.rs +++ b/xtask/src/assets.rs @@ -1,5 +1,5 @@ //! `cargo xtask assets`: every non-code asset in the repository must have a row in -//! ATTRIBUTION.md (author, source, licence). Icons are drawn in code and need no file. +//! ATTRIBUTION.md (author, source, licence), toolbar icons (`assets/icons`) included. use std::path::Path; diff --git a/xtask/src/icons.rs b/xtask/src/icons.rs new file mode 100644 index 0000000..7ef4724 --- /dev/null +++ b/xtask/src/icons.rs @@ -0,0 +1,156 @@ +//! `cargo xtask icons [ID…]`: draw the toolbar icons with VectorCraft. +//! +//! Each icon is a recipe, `assets/icons/src/.json`: a list of shapes on a 24 × 24 pixel +//! artboard, each a path (`d`), `circle` `[cx, cy, r]`, `rect` `[x, y, w, h]` (optional +//! `radius`), `line` `[x1, y1, x2, y2]` or `star` `[cx, cy, outer, inner, points]`, painted with +//! palette roles (`fill`, `stroke`: `line`, `accent`, `soft`, `warm`; a shape with neither is +//! stroked with `line`), an optional stroke `width` (default 1.5; round caps and joins) and +//! `dash` (`[dash, gap]`). The task turns every recipe into VectorCraft +//! commands, runs them headlessly with `vectorcraft-cli run` (`VECTORCRAFT_CLI`, else +//! `vectorcraft-cli` on the PATH) and writes `assets/icons/.vectorcraft` (the editable +//! source) and `assets/icons/.svg` (what the app draws). The roles' colours are the dark +//! theme's; the app recolours each role with its theme tokens (`crates/ui-egui/src/icons.rs`). + +use std::path::Path; +use std::process::Command; + +use serde_json::{Value, json}; + +/// Palette roles and the colour each is drawn in (the dark theme's tokens). Keep in step with +/// `PALETTE` in `crates/ui-egui/src/icons.rs`. +pub const PALETTE: &[(&str, &str)] = &[("line", "#dde2ea"), ("accent", "#4f9ce8"), ("soft", "#2d4e70"), ("warm", "#f0b44a")]; + +/// The artboard side (pixels) and the default stroke weight. +const SIZE: f64 = 24.0; +const STROKE: f64 = 1.5; + +pub fn run(root: &Path, only: &[&str]) -> Result<(), String> { + let dir = root.join("assets/icons"); + let src = dir.join("src"); + let mut recipes: Vec = std::fs::read_dir(&src) + .map_err(|e| format!("{}: {e}", src.display()))? + .flatten() + .filter_map(|e| e.file_name().to_str().and_then(|n| n.strip_suffix(".json")).map(str::to_string)) + .filter(|id| only.is_empty() || only.contains(&id.as_str())) + .collect(); + recipes.sort(); + if recipes.is_empty() { + return Err("no icon recipes to draw".into()); + } + let cli = std::env::var("VECTORCRAFT_CLI").unwrap_or_else(|_| "vectorcraft-cli".into()); + for id in &recipes { + let path = src.join(format!("{id}.json")); + let text = std::fs::read_to_string(&path).map_err(|e| format!("{}: {e}", path.display()))?; + let recipe: Value = serde_json::from_str(&text).map_err(|e| format!("{}: {e}", path.display()))?; + let steps = commands(id, &recipe, &dir.join(format!("{id}.vectorcraft"))).map_err(|e| format!("{id}: {e}"))?; + let mut c = Command::new(&cli); + c.arg("run"); + for (cmd, params) in &steps { + c.args(["--cmd", cmd, "--params", ¶ms.to_string()]); + } + c.arg("--export").arg(dir.join(format!("{id}.svg"))); + let out = c.output().map_err(|e| format!("{cli}: {e} (set VECTORCRAFT_CLI to the vectorcraft-cli binary)"))?; + if !out.status.success() { + return Err(format!("{id}: vectorcraft-cli failed:\n{}{}", String::from_utf8_lossy(&out.stdout), String::from_utf8_lossy(&out.stderr))); + } + } + println!("icons: drew {} icon(s) into assets/icons", recipes.len()); + Ok(()) +} + +fn colour(role: &Value) -> Result { + match role { + Value::Null => Ok(json!({"none": true})), + Value::String(r) => { + PALETTE.iter().find(|(name, _)| name == r).map(|(_, hex)| json!({"color": hex})).ok_or_else(|| format!("unknown role `{r}`")) + } + other => Err(format!("a role is a name, not {other}")), + } +} + +fn numbers(v: &Value) -> Result<[f64; N], String> { + let a = v.as_array().filter(|a| a.len() == N).ok_or_else(|| format!("expected {N} numbers, got {v}"))?; + let mut out = [0.0; N]; + for (o, x) in out.iter_mut().zip(a) { + *o = x.as_f64().filter(|x| x.is_finite()).ok_or_else(|| format!("expected numbers, got {v}"))?; + } + Ok(out) +} + +/// The VectorCraft commands that draw one recipe and save it to `source`. +fn commands(id: &str, recipe: &Value, source: &Path) -> Result, String> { + let shapes = recipe.get("shapes").and_then(Value::as_array).ok_or("a recipe is {\"shapes\": [...]}")?; + let mut out = vec![("file.new".to_string(), json!({"width": SIZE, "height": SIZE, "units": "Pixels", "name": id, "created": null}))]; + for s in shapes { + let create = if let Some(d) = s.get("d").and_then(Value::as_str) { + ("path.create", json!({"d": d})) + } else if let Some(c) = s.get("circle") { + let [cx, cy, r] = numbers::<3>(c)?; + ("shape.ellipse", json!({"x": cx - r, "y": cy - r, "width": 2.0 * r, "height": 2.0 * r})) + } else if let Some(r) = s.get("rect") { + let [x, y, width, height] = numbers::<4>(r)?; + let radius = s.get("radius").and_then(Value::as_f64).unwrap_or(0.0); + ("shape.rectangle", json!({"x": x, "y": y, "width": width, "height": height, "radius": radius})) + } else if let Some(l) = s.get("line") { + let [x1, y1, x2, y2] = numbers::<4>(l)?; + ("shape.line", json!({"x1": x1, "y1": y1, "x2": x2, "y2": y2})) + } else if let Some(st) = s.get("star") { + let [cx, cy, radius1, radius2, points] = numbers::<5>(st)?; + ("shape.star", json!({"cx": cx, "cy": cy, "radius1": radius1, "radius2": radius2, "points": points})) + } else { + return Err(format!("a shape needs `d`, `circle`, `rect`, `line` or `star`: {s}")); + }; + out.push((create.0.to_string(), create.1)); + let (fill, stroke) = match (s.get("fill"), s.get("stroke")) { + (None, None) => (Value::Null, json!("line")), + (f, st) => (f.cloned().unwrap_or(Value::Null), st.cloned().unwrap_or(Value::Null)), + }; + out.push(("paint.setFill".into(), colour(&fill)?)); + out.push(("paint.setStroke".into(), colour(&stroke)?)); + if !stroke.is_null() { + let width = s.get("width").and_then(Value::as_f64).unwrap_or(STROKE); + let dash = s.get("dash").cloned().unwrap_or(Value::Null); + out.push(("stroke.set".into(), json!({"weight": width, "cap": "round", "join": "round", "dash": dash}))); + } + } + out.push(("document.save".into(), json!({"path": source, "compress": true, "modified": null}))); + Ok(out) +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn a_recipe_becomes_vectorcraft_commands() { + let recipe = json!({"shapes": [ + {"d": "M4 4 L20 20"}, + {"circle": [12, 12, 3], "fill": "accent"}, + {"rect": [2, 2, 4, 4], "radius": 1, "fill": "soft", "stroke": "line", "width": 1}, + ]}); + let steps = commands("x.y", &recipe, Path::new("/tmp/x.y.vectorcraft")).unwrap(); + let ids: Vec<&str> = steps.iter().map(|(c, _)| c.as_str()).collect(); + assert_eq!( + ids, + [ + "file.new", + "path.create", + "paint.setFill", + "paint.setStroke", + "stroke.set", + "shape.ellipse", + "paint.setFill", + "paint.setStroke", + "shape.rectangle", + "paint.setFill", + "paint.setStroke", + "stroke.set", + "document.save" + ] + ); + assert_eq!(steps[5].1, json!({"x": 9.0, "y": 9.0, "width": 6.0, "height": 6.0})); + assert_eq!(steps[3].1, json!({"color": "#dde2ea"})); + assert!(commands("x", &json!({"shapes": [{"d": "M0 0", "fill": "pink"}]}), Path::new("x")).is_err()); + assert!(commands("x", &json!({"shapes": [{"circle": [1, 2]}]}), Path::new("x")).is_err()); + } +} diff --git a/xtask/src/main.rs b/xtask/src/main.rs index c13f9cf..9804a6b 100644 --- a/xtask/src/main.rs +++ b/xtask/src/main.rs @@ -6,6 +6,7 @@ #![deny(clippy::unwrap_used, clippy::expect_used, clippy::panic, clippy::unimplemented, clippy::todo, clippy::unreachable)] mod assets; +mod icons; mod layers; mod licences; mod test; @@ -19,6 +20,9 @@ usage: cargo xtask commands: layers enforce the crate dependency layering (docs/architecture.md) assets check that every non-code asset file is attributed in ATTRIBUTION.md + icons [ID…] draw the toolbar icons from their recipes (assets/icons/src/*.json) with + VectorCraft (VECTORCRAFT_CLI, else vectorcraft-cli on the PATH): writes each + icon's .vectorcraft source and .svg export licences [--check] write THIRD-PARTY-LICENSES.txt (the licences of every shipped crate); --check fails when it is out of date @@ -39,6 +43,7 @@ fn main() -> ExitCode { let result = match args.first().map(String::as_str) { Some("layers") => cmd_layers(), Some("assets") => assets::run(&root()), + Some("icons") => icons::run(&root(), &rest), Some("licences") => licences::run(&root(), rest.contains(&"--check")), Some("test") => { let (cargo_args, test_args) = rest.iter().position(|a| *a == "--").map_or((&rest[..], &[][..]), |i| (&rest[..i], &rest[i + 1..]));