Compare commits

..
185 Commits
Author SHA1 Message Date
jyvikoandClaude Opus 5.5 e1c7a13bb6 issue media: Pi 5 Base corner, current layout and a notched all-hex frame (#475)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UhhZMBTviDQxZvwnyP89fo
2026-10-16 08:06:51 -04:00
Irakli Kourtis 4c4fe5d764 media: ui-f-quality-worst.png 2026-10-15 11:01:10 -04:00
Irakli Kourtis 3d5ce92ea5 media: ui-f-quality-panel.png 2026-10-15 11:01:08 -04:00
Irakli Kourtis 2cc6cbe52e media: ui-f-probe-form.png 2026-10-15 11:01:06 -04:00
Irakli Kourtis 54df16b4bc media: ui-f-probe-form-filled.png 2026-10-15 11:01:04 -04:00
Irakli Kourtis e84efab24b media: ui-f-legend-before.png 2026-10-15 11:01:02 -04:00
Irakli Kourtis be9f7e4113 media: ui-f-legend-after.png 2026-10-15 11:01:00 -04:00
Irakli Kourtis 00db48a872 media: ui-f-ibeam-solved.png 2026-10-15 11:00:59 -04:00
Irakli Kourtis 96f10074bd media: ui-f-crash-reports.png 2026-10-15 11:00:57 -04:00
Irakli Kourtis 6b8ebf85c0 media: ui-f-crash-reports-deleted.png 2026-10-15 11:00:55 -04:00
jyviko 4892e7f8eb media: before/after captures for the ui-older bundle 2026-10-15 10:15:41 -04:00
Irakli Kourtis 84f433f650 media: ui-picking/after-350-browser-crop.png 2026-10-15 09:23:44 -04:00
Irakli Kourtis a7c03b78cf media: ui-picking/after-350-rigid-wall.png 2026-10-15 09:23:43 -04:00
Irakli Kourtis 2f164db4dc media: ui-picking/before-350-interactions.png 2026-10-15 09:23:41 -04:00
Irakli Kourtis e5808eabf6 media: ui-picking/after-351-rp.png 2026-10-15 09:23:39 -04:00
Irakli Kourtis c11135569f media: ui-picking/before-351-rp.png 2026-10-15 09:23:38 -04:00
Irakli Kourtis 5dfdf5f077 media: ui-picking/after-346-datum.png 2026-10-15 09:23:37 -04:00
Irakli Kourtis 2180d816c6 media: ui-picking/before-346-datum.png 2026-10-15 09:23:35 -04:00
Irakli Kourtis 3f5c3b8bcc media: ui-picking/after-344-hover-s.png 2026-10-15 09:23:33 -04:00
Irakli Kourtis 5b0bd418b3 media: ui-picking/before-344-cells.png 2026-10-15 09:23:32 -04:00
Irakli Kourtis 3890086b26 media: ui-picking/after-338-edge.png 2026-10-15 09:23:30 -04:00
Irakli Kourtis 37ab0f0afa media: ui-picking/before-338-edge.png 2026-10-15 09:23:29 -04:00
Irakli Kourtis f28c55ba58 media: ui-forms menus 2026-10-15 09:13:54 -04:00
Irakli Kourtis 1f61fe16ea media: ui-forms after-362-crop 2026-10-15 09:12:13 -04:00
Irakli Kourtis e619c5644b media: ui-forms after-343-remesh-form-crop 2026-10-15 09:12:12 -04:00
Irakli Kourtis 12d0f5f25b media: ui-forms after-342-crop 2026-10-15 09:12:11 -04:00
Irakli Kourtis 7a9f5d1f6c media: ui-forms after-323-tet-refused 2026-10-15 09:12:09 -04:00
Irakli Kourtis f70fe23c28 media: ui-forms after-323-solve-refused 2026-10-15 09:12:08 -04:00
Irakli Kourtis aa568b2938 media: ui-forms after-357-mesh-progress 2026-10-15 09:12:06 -04:00
Irakli Kourtis d7cbee38a1 media: ui-forms after-322-solve-progress 2026-10-15 09:12:05 -04:00
Irakli Kourtis 4ce89c2a40 media: ui-forms after-341-seed-filter 2026-10-15 09:12:04 -04:00
Irakli Kourtis 361ff9a366 media: ui-forms after-347-partition 2026-10-15 09:12:02 -04:00
Irakli Kourtis cfc460fd99 media: ui-forms after-347-datum-preview 2026-10-15 09:12:00 -04:00
Irakli Kourtis f23dd670f1 media: ui-forms after-340-step-form 2026-10-15 09:11:59 -04:00
Irakli Kourtis 64993629a0 media: ui-forms after-353-tet-form 2026-10-15 09:11:57 -04:00
Irakli Kourtis ca83583dfe media: ui-forms after-339-load-form 2026-10-15 09:11:56 -04:00
Irakli Kourtis a64e321ccd media: remove x.png 2026-10-15 09:00:31 -04:00
Irakli Kourtis f90d48644d media: remove top.png 2026-10-15 09:00:31 -04:00
Irakli Kourtis 53bfc8e0c4 media: remove top-s.png 2026-10-15 09:00:30 -04:00
Irakli Kourtis 5e501897cd media: remove tm.png 2026-10-15 09:00:29 -04:00
Irakli Kourtis 7fa8e34eef media: remove thumbs.png 2026-10-15 09:00:28 -04:00
Irakli Kourtis 8bd0b2dcb7 media: remove t-s.png 2026-10-15 09:00:27 -04:00
Irakli Kourtis 094d36a2e1 media: remove symbols-out.png 2026-10-15 09:00:26 -04:00
Irakli Kourtis 4a9696f661 media: remove symbols-in.png 2026-10-15 09:00:25 -04:00
Irakli Kourtis 47774ddbd5 media: remove symbols-home.png 2026-10-15 09:00:24 -04:00
Irakli Kourtis 34382cc8ab media: remove start.png 2026-10-15 09:00:23 -04:00
Irakli Kourtis 0dbab730e5 media: remove solved.png 2026-10-15 09:00:22 -04:00
Irakli Kourtis 68d25ea9df media: remove solved-fit.png 2026-10-15 09:00:20 -04:00
Irakli Kourtis 7c876b0027 media: remove setup.png 2026-10-15 09:00:19 -04:00
Irakli Kourtis 201f6ec696 media: remove rp-inside.png 2026-10-15 09:00:18 -04:00
Irakli Kourtis 94eeeea8a1 media: remove rp-inside-crop.png 2026-10-15 09:00:18 -04:00
Irakli Kourtis 7b91f4ec07 media: remove rp-behind.png 2026-10-15 09:00:17 -04:00
Irakli Kourtis 1c4d71f18e media: remove rp-behind-crop.png 2026-10-15 09:00:16 -04:00
Irakli Kourtis ca69f66184 media: remove pocket.png 2026-10-15 09:00:15 -04:00
Irakli Kourtis 3501852e5d media: remove pocket-s.png 2026-10-15 09:00:13 -04:00
Irakli Kourtis c2a923590f media: remove pocket-end.png 2026-10-15 09:00:12 -04:00
Irakli Kourtis 2814496028 media: remove pedalb.png 2026-10-15 09:00:11 -04:00
Irakli Kourtis 0628dfee0d media: remove pedal.png 2026-10-15 09:00:10 -04:00
Irakli Kourtis 7ef841e964 media: remove g-mirror.png 2026-10-15 09:00:09 -04:00
Irakli Kourtis 79025d97e3 media: remove g-arm.png 2026-10-15 09:00:08 -04:00
Irakli Kourtis 23bdf25cd6 media: remove crank-mirror.png 2026-10-15 09:00:07 -04:00
Irakli Kourtis d07b07f8e2 media: remove crank-mirror-s.png 2026-10-15 09:00:05 -04:00
Irakli Kourtis 1ce2de8546 media: remove crank-iso.png 2026-10-15 09:00:04 -04:00
Irakli Kourtis a453b36afa media: remove crank-arm.png 2026-10-15 09:00:03 -04:00
Irakli Kourtis 6f48f22848 media: remove crank-arm-s.png 2026-10-15 09:00:02 -04:00
Irakli Kourtis ab87e63830 media: remove cmp2.png 2026-10-15 09:00:01 -04:00
Irakli Kourtis e78f051957 media: remove cmp1.png 2026-10-15 09:00:00 -04:00
Irakli Kourtis 280192e203 media: remove cmp.png 2026-10-15 08:59:59 -04:00
Irakli Kourtis 72b3079867 media: remove closeups.png 2026-10-15 08:59:58 -04:00
Irakli Kourtis 9edde6f70c media: remove bore.png 2026-10-15 08:59:57 -04:00
Irakli Kourtis 8d702688bb media: remove b-s.png 2026-10-15 08:59:56 -04:00
Irakli Kourtis 3637a0b3fe media: ui-results x.png 2026-10-15 08:59:50 -04:00
Irakli Kourtis 69be8c1e56 media: ui-results top.png 2026-10-15 08:59:48 -04:00
Irakli Kourtis 251c9d5017 media: ui-results top-s.png 2026-10-15 08:59:47 -04:00
Irakli Kourtis 8c505bc6ca media: ui-results tm.png 2026-10-15 08:59:45 -04:00
Irakli Kourtis 446a33be09 media: ui-results thumbs.png 2026-10-15 08:59:44 -04:00
Irakli Kourtis 0c7570c034 media: ui-results t-s.png 2026-10-15 08:59:42 -04:00
Irakli Kourtis e023ec70b5 media: ui-results symbols-out.png 2026-10-15 08:59:41 -04:00
Irakli Kourtis 4b7134de02 media: ui-results symbols-in.png 2026-10-15 08:59:40 -04:00
Irakli Kourtis fae9258f87 media: ui-results symbols-home.png 2026-10-15 08:59:38 -04:00
Irakli Kourtis 6f4fdafed0 media: ui-results start.png 2026-10-15 08:59:37 -04:00
Irakli Kourtis cebf244f38 media: ui-results solved.png 2026-10-15 08:59:36 -04:00
Irakli Kourtis 6e307795f6 media: ui-results solved-fit.png 2026-10-15 08:59:34 -04:00
Irakli Kourtis 875bd6d15d media: ui-results setup.png 2026-10-15 08:59:33 -04:00
Irakli Kourtis b1906ab393 media: ui-results rp-inside.png 2026-10-15 08:59:31 -04:00
Irakli Kourtis 0ba476691f media: ui-results rp-inside-crop.png 2026-10-15 08:59:30 -04:00
Irakli Kourtis f3c2b282c6 media: ui-results rp-behind.png 2026-10-15 08:59:29 -04:00
Irakli Kourtis 464992a215 media: ui-results rp-behind-crop.png 2026-10-15 08:59:28 -04:00
Irakli Kourtis 5bb8554cb2 media: ui-results pocket.png 2026-10-15 08:59:26 -04:00
Irakli Kourtis 1f27e5d1dd media: ui-results pocket-s.png 2026-10-15 08:59:24 -04:00
Irakli Kourtis d9d3b7ce26 media: ui-results pocket-end.png 2026-10-15 08:59:23 -04:00
Irakli Kourtis 800dacc7c4 media: ui-results pedalb.png 2026-10-15 08:59:21 -04:00
Irakli Kourtis aa08a9a136 media: ui-results pedal.png 2026-10-15 08:59:20 -04:00
Irakli Kourtis 13c8b43211 media: ui-results g-mirror.png 2026-10-15 08:59:19 -04:00
Irakli Kourtis e7bb94b2e3 media: ui-results g-arm.png 2026-10-15 08:59:17 -04:00
Irakli Kourtis b194f2c0d4 media: ui-results crank-mirror.png 2026-10-15 08:59:15 -04:00
Irakli Kourtis 2da4e0af74 media: ui-results crank-mirror-s.png 2026-10-15 08:59:14 -04:00
Irakli Kourtis 3d603bfb73 media: ui-results crank-iso.png 2026-10-15 08:59:12 -04:00
Irakli Kourtis dbe7656ebb media: ui-results crank-arm.png 2026-10-15 08:59:10 -04:00
Irakli Kourtis 79f36c1ba0 media: ui-results crank-arm-s.png 2026-10-15 08:59:09 -04:00
Irakli Kourtis 8e613fdcf2 media: ui-results cmp2.png 2026-10-15 08:59:07 -04:00
Irakli Kourtis fad676d789 media: ui-results cmp1.png 2026-10-15 08:59:05 -04:00
Irakli Kourtis a0ecddcd59 media: ui-results cmp.png 2026-10-15 08:59:04 -04:00
Irakli Kourtis 06d9ecc386 media: ui-results closeups.png 2026-10-15 08:59:02 -04:00
Irakli Kourtis 9dfc78fe36 media: ui-results bore.png 2026-10-15 08:59:01 -04:00
Irakli Kourtis 4c8b14127c media: ui-results before-stale.png 2026-10-15 08:58:59 -04:00
Irakli Kourtis 94eeb7c0cf media: ui-results before-seal.png 2026-10-15 08:58:58 -04:00
Irakli Kourtis 855c6acfb1 media: ui-results before-seal-auto.png 2026-10-15 08:58:55 -04:00
Irakli Kourtis fbd222dd9b media: ui-results before-reactions.png 2026-10-15 08:58:54 -04:00
Irakli Kourtis 1770fd9fb1 media: ui-results before-probe.png 2026-10-15 08:58:52 -04:00
Irakli Kourtis 2c00b1f611 media: ui-results before-isolate.png 2026-10-15 08:58:51 -04:00
Irakli Kourtis 1337edc9bf media: ui-results before-drop.png 2026-10-15 08:58:49 -04:00
Irakli Kourtis 681beec6da media: ui-results before-cantilever-mode2.png 2026-10-15 08:58:48 -04:00
Irakli Kourtis dc7ae39f39 media: ui-results before-cantilever-load.png 2026-10-15 08:58:46 -04:00
Irakli Kourtis 773a97e212 media: ui-results before-bracket.png 2026-10-15 08:58:45 -04:00
Irakli Kourtis c1d4ebb282 media: ui-results before-bracket-solve-panel.png 2026-10-15 08:58:43 -04:00
Irakli Kourtis d0a9cdf1bd media: ui-results before-bracket-nomesh.png 2026-10-15 08:58:41 -04:00
Irakli Kourtis 538c8b760b media: ui-results b-s.png 2026-10-15 08:58:40 -04:00
Irakli Kourtis 86fafc7853 media: ui-results after-stale.png 2026-10-15 08:58:39 -04:00
Irakli Kourtis 7db56f4911 media: ui-results after-seal.png 2026-10-15 08:58:37 -04:00
Irakli Kourtis b798cdbdf8 media: ui-results after-probe-reactions.png 2026-10-15 08:58:35 -04:00
Irakli Kourtis 3c177ddd07 media: ui-results after-isolate.png 2026-10-15 08:58:34 -04:00
Irakli Kourtis 02afff31b5 media: ui-results after-drop.png 2026-10-15 08:58:32 -04:00
Irakli Kourtis 2c13977776 media: ui-results after-cantilever-mode2.png 2026-10-15 08:58:30 -04:00
Irakli Kourtis 967077d365 media: ui-results after-cantilever-load.png 2026-10-15 08:58:29 -04:00
Irakli Kourtis e1a9e19787 media: ui-results after-bracket-solve-panel.png 2026-10-15 08:58:27 -04:00
Irakli Kourtis 3c2494f295 media: ui-results after-bracket-nomesh.png 2026-10-15 08:58:26 -04:00
Irakli Kourtis 530d00b36e media: after-cantilever-tie-status.png 2026-10-15 08:45:50 -04:00
Irakli Kourtis cbfde06153 media: after-journal-crop.png 2026-10-15 08:45:49 -04:00
Irakli Kourtis 198715fdf0 media: after-us.png 2026-10-15 08:45:48 -04:00
Irakli Kourtis cffe894b91 media: after-seed-selected.png 2026-10-15 08:45:46 -04:00
Irakli Kourtis 91ac2e0097 media: after-trees.png 2026-10-15 08:45:45 -04:00
Irakli Kourtis 1b4e8acbaf media: after-crank-bodies.png 2026-10-15 08:45:43 -04:00
Irakli Kourtis 063a7beb2d media: after-bracket-set-stack.png 2026-10-15 08:45:42 -04:00
Irakli Kourtis 432b14d90c media: after-heated-heater.png 2026-10-15 08:45:40 -04:00
Irakli Kourtis 24dd11f04d media: after-rubber-seal-press.png 2026-10-15 08:45:38 -04:00
Irakli Kourtis 1f14b83820 media: before-crank-bodies.png 2026-10-15 08:45:37 -04:00
Irakli Kourtis b2ccdd0e5e media: before-bracket-set-stack.png 2026-10-15 08:45:35 -04:00
Irakli Kourtis 465b1db5e0 media: before-heated-heater.png 2026-10-15 08:45:34 -04:00
Irakli Kourtis 9c5d13c4f6 media: before-rubber-seal-press.png 2026-10-15 08:45:32 -04:00
Irakli Kourtis 04b46be8fe audit 2026-10-15 08:11:51 -04:00
Irakli Kourtis 06a5b622ef audit: a-seed-browser.png 2026-10-15 08:10:46 -04:00
Irakli Kourtis 67e7d833f8 audit: a-edit-menu-mirror.png 2026-10-15 08:10:45 -04:00
Irakli Kourtis 1ee9733d5e audit: a-bodies-panel.png 2026-10-15 08:10:44 -04:00
Irakli Kourtis 445b215a78 audit: a-partitioned-mesh-form.png 2026-10-15 08:10:42 -04:00
Irakli Kourtis 8e7f5d7864 audit: a-edge-sel-nomesh.png 2026-10-15 08:10:41 -04:00
Irakli Kourtis d1a4756924 audit: a-edge-sel-mesh.png 2026-10-15 08:10:39 -04:00
Irakli Kourtis 08b479461b audit 2026-10-15 08:10:30 -04:00
Irakli Kourtis 70b9776b33 audit: up-step-defaults.png 2026-10-15 08:10:23 -04:00
Irakli Kourtis 50a0054735 audit: up-set-json.png 2026-10-15 08:10:22 -04:00
Irakli Kourtis 4bea7855fb audit: up-press.png 2026-10-15 08:10:21 -04:00
Irakli Kourtis eb21b58220 audit: up-orphan.png 2026-10-15 08:10:20 -04:00
Irakli Kourtis f0e1f58938 audit: up-load-clip.png 2026-10-15 08:10:18 -04:00
Irakli Kourtis 45e5ad15e1 audit: up-journal.png 2026-10-15 08:10:17 -04:00
Irakli Kourtis 25ecc1bae3 audit: up-heater.png 2026-10-15 08:10:16 -04:00
Irakli Kourtis 7d86283c37 audit: up-bodies.png 2026-10-15 08:10:14 -04:00
Irakli Kourtis c5bdb16887 audit screenshot k1 2026-10-15 08:09:16 -04:00
Irakli Kourtis 4a8ad35f85 audit screenshot c5 2026-10-15 08:09:15 -04:00
Irakli Kourtis d46423546e audit screenshot s1 2026-10-15 08:09:14 -04:00
Irakli Kourtis f2fb6242bb audit screenshot r1 2026-10-15 08:09:12 -04:00
Irakli Kourtis 5b4599d17b audit screenshot p1 2026-10-15 08:09:11 -04:00
Irakli Kourtis 52339fa4b6 audit screenshot d2 2026-10-15 08:09:09 -04:00
Irakli Kourtis b090f213c7 audit screenshot c8 2026-10-15 08:09:08 -04:00
Irakli Kourtis 9678a8305a audit screenshot r5 2026-10-15 08:09:06 -04:00
Irakli Kourtis c0bf38efc2 audit screenshot c3 2026-10-15 08:09:05 -04:00
Irakli Kourtis 9345dea731 audit: tree status marks 2026-10-15 08:05:47 -04:00
Irakli Kourtis 297e96d145 media: releases/0.5.8/fieldcraft-0.5.8-setup-tree.png 2026-10-15 00:10:09 -04:00
Irakli Kourtis 12bb39d6f9 media: releases/0.5.8/fieldcraft-0.5.8-structured-hex.png 2026-10-15 00:10:07 -04:00
Irakli Kourtis 857a02b50f media: views framing 5-cantilever-solved-fit 2026-10-14 22:29:22 -04:00
Irakli Kourtis ce5d81f410 media: views framing 4-cantilever-front 2026-10-14 22:29:21 -04:00
Irakli Kourtis ad93e22d53 media: views framing 3-bracket-after-crank 2026-10-14 22:29:20 -04:00
Irakli Kourtis 035b23b395 media: views framing 2-crank-solved 2026-10-14 22:29:19 -04:00
Irakli Kourtis 353ed4be93 issue media: uiaudit-results-offscreen.png 2026-10-14 18:07:24 -04:00
Irakli Kourtis 2849f2d870 issue media: uiaudit-plasticity-no-material.png 2026-10-14 18:07:23 -04:00
Irakli Kourtis c82332054c issue media: uiaudit-plasticity-empty.png 2026-10-14 18:07:21 -04:00
Irakli Kourtis dc3d4c62b0 issue media: uiaudit-plasticity-carryover.png 2026-10-14 18:07:20 -04:00
Irakli Kourtis b647232433 issue media: uiaudit-narrow-plasticity.png 2026-10-14 18:07:18 -04:00
Irakli Kourtis 21fc85786f issue media: uiaudit-light-form-fields.png 2026-10-14 18:07:17 -04:00
Irakli Kourtis 25f7270d5a issue media: uiaudit-commandline-truncated.png 2026-10-14 18:07:15 -04:00
Irakli Kourtis 4457bd4646 issue media: uiaudit-check-json-status.png 2026-10-14 18:07:14 -04:00
jyvikoandClaude Opus 5.5 41fc6c23a0 issue media: Cook's membrane sketch (#83), octree over-refinement on thin parts (#85)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NmAttHhUZTokgPeEJia8sm
2026-10-14 08:15:27 -04:00
jyvikoandClaude Opus 5.5 8086a108fd issue media: a force at a reference point on the cantilever's end face, buried in the part
Captured from FieldCraft 0.1.0 (f1253b4) with ui.capture: iso view and the opposite side.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NmAttHhUZTokgPeEJia8sm
2026-10-14 08:02:51 -04:00
jyvikoandClaude Opus 5.5 0d06b956c0 issue media: Lamé cylinder path through the wall (#96), NAFEMS LE1 oracle case (#97)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NmAttHhUZTokgPeEJia8sm
2026-10-14 07:59:22 -04:00
jyvikoandClaude Opus 5.5 aaf64f7c0d issue media: start screen, results after solve, setup symbols at three zooms, demo tip load
Captured from FieldCraft 0.1.0 (f1253b4) with ui.capture; the tip-load crop is from docs/media/ibeam-analysis.gif.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NmAttHhUZTokgPeEJia8sm
2026-10-14 07:58:56 -04:00
jyvikoandClaude Opus 5.5 deae8f77bd issue media: screenshots referenced from issues
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NmAttHhUZTokgPeEJia8sm
2026-10-14 07:51:30 -04:00
664 changed files with 60 additions and 60885 deletions

No files matched your search

-2
View File
@@ -1,2 +0,0 @@
[alias]
xtask = "run --package xtask --"
-42
View File
@@ -1,42 +0,0 @@
name: CI
on:
pull_request:
push:
branches: [main]
workflow_dispatch:
permissions:
contents: read
concurrency:
group: ci-${{ github.ref }}
cancel-in-progress: ${{ github.event_name == 'pull_request' }}
env:
CARGO_TERM_COLOR: always
jobs:
ci:
name: cargo xtask ci
runs-on: ubuntu-24.04
timeout-minutes: 60
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- uses: dtolnay/rust-toolchain@stable
with:
components: rustfmt, clippy
targets: wasm32-unknown-unknown
- uses: Swatinem/rust-cache@6323deb102c322ba6fcbdcafc7e3dddab59af2b6 # v2.9.2
- run: cargo xtask ci
advisories:
name: Dependency advisories and sources
runs-on: ubuntu-24.04
timeout-minutes: 20
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- uses: dtolnay/rust-toolchain@stable
- name: Install cargo-deny
run: cargo install cargo-deny --version 0.20.2 --locked
- run: cargo deny --locked check --warn unmaintained advisories bans sources
-8
View File
@@ -1,8 +0,0 @@
/target*/
/plan/
/dist/
/.agent-files/
/worktrees/
*~
.DS_Store
*.swp
-113
View File
@@ -1,113 +0,0 @@
# ModelCraft — instructions for agents
ModelCraft is a clean-room, open-source, pure-Rust CAE modeling application: it turns geometry
into analysis-ready finite element models (volume meshes, materials, sections, boundary
conditions, loads and steps), writes them as Abaqus input, Nastran bulk data and LS-DYNA keyword
decks, and solves linear static and modal problems with its own solver. It targets the
pre-processing done today in Abaqus/CAE, Nastran pre-processors and LS-PrePost, and aims to beat
them on meshing robustness, speed, openness and agent control.
Siblings with the same conventions: `../solidcraft` (parametric CAD, Fusion-class), and the
storytold Craft apps (`storytold/cadcraft`, `vectorcraft`, `photocraft`, …). Code adapted from
them (MIT OR Apache-2.0) is noted in ATTRIBUTION.md.
## Product name
ModelCraft everywhere: crates `modelcraft-*`, binaries `modelcraft` and `modelcraft-cli`,
`.modelcraft` models, `MODELCRAFT_*` environment variables, docs, CI and packaging.
## Start every session here
1. Read `ROADMAP.md` (milestones, what is next) and your task.
2. `docs/architecture.md`: crates, layers, the meshing pipeline.
3. `docs/adr/`: library decisions (what we may depend on, what is rejected for licence reasons).
4. Meshing work: `docs/meshing/literature.md` (the papers each algorithm comes from).
## Never crash
People trust ModelCraft with their models; a crash loses their work. **This outranks feature work.**
- **No panics in non-test code:** no `unwrap()`, `expect()`, `panic!`, `unreachable!`, `todo!`,
`unimplemented!`; no `unsafe` (`unsafe_code = "forbid"`).
- **Errors are `Result<T, E>`** through the crate's error type and `?`. An unfinished feature
returns an error ("not supported yet: …"); it never panics.
- **Input-derived numbers are hostile** (command parameters, model files, solver decks,
control-channel input): `get()` not `[i]`, finite checks, caps on sizes and loop counts.
- **Bound every iterative algorithm.** Mesh refinement, smoothing, untangling and solver
iterations have explicit iteration and element-count caps and report when they stop early.
- **SolidCraft calls are guarded:** everything that calls `solidcraft-kernel` goes through
`solidcraft_kernel::guard` inside `modelcraft-geometry`, which turns a panic into an error.
- **Last-resort guard:** `Session::execute` runs every command under `catch_unwind`; an error or
an escaped panic restores the model and reports `EngineError`.
- **Prove it:** every crash fix lands with a regression test (see `hostile_params_never_panic`).
- Every production crate root carries
`#![deny(clippy::unwrap_used, clippy::expect_used, clippy::panic, clippy::unimplemented, clippy::todo, clippy::unreachable)]`.
## Non-negotiables
- **Independent.** Behaviour is designed from public documentation, published papers, general
CAE conventions and user feedback. Never copy another product's code, icons, artwork, help
text, element or material libraries, templates or examples.
- **No commercial CAE products.** Agents must not drive, script, automate or extract data from
commercial CAE or meshing products (Abaqus, MSC/NX/Simcenter Nastran, LS-DYNA, LS-PrePost,
HyperMesh, ANSA, Femap, Patran, ANSYS, …): no test data, measurements, decks, results or ids
produced with them. Deck formats come from the vendors' publicly available reference manuals;
we write our own descriptions and our own examples, never copy manual text or example decks.
- **Expected values are analytic.** Reference tests compare with closed-form solutions (patch
tests, beams, plates, Lamé cylinders, Kirsch plates, natural frequencies, wave and shock
solutions) and with mesh invariants (positive Jacobians, conserved volume, watertight
boundaries). A separate **benchmark** suite may compare with reference values published in
papers (lid-driven cavity, Schäfer–Turek, Turek–Hron, Taylor bar), each tagged with its source;
the analytic suite is the gate. Never values produced with a commercial product.
- **Algorithms come from papers.** Meshing and solver methods are implemented from published
papers and theses, cited in the module docs and in `docs/meshing/literature.md`.
- **Never read, copy or link GPL/LGPL/AGPL code**: TetGen, CGAL, Gmsh, Netgen, CalculiX,
Code_Aster, OpenRadioss, Elmer, deal.II, FreeFEM, Salome, OpenFOAM — don't even read their
sources. Permissively licensed code (MIT, BSD, Apache-2.0, MPL-2.0) may be read for reference;
anything adapted is noted in ATTRIBUTION.md with its licence.
- **Assets — absolutely essential.** ModelCraft contains **no iconography, images, fonts or
artwork from commercial CAE products — ever.** Icons are original artwork made with VectorCraft:
commit the editable `.vectorcraft` source beside the exported SVG/PNG. Any file asset must be
original or openly licensed and **must have a row in ATTRIBUTION.md** (`cargo xtask assets`
enforces it). Screenshots of commercial software are never committed.
- **Test geometry is our own.** Meshing and solver test parts are built with SolidCraft and
committed as recipes (scripts or designs) that regenerate them; analytic shapes are generated in
code. No public CAD datasets (ABC, MAMBO, Thingi10K, GrabCAD) and nothing made in a commercial
CAD or CAE product.
- **Everything is a command.** User-visible behaviour = a command in `crates/engine/src/cmd/*`
(`CommandSpec`: our own dotted, lower-case id `<area>.<thing>[.<variant>]` such as
`mesh.node.add` or `mesh.tet.generate`, never another product's keyword; label; params doc;
JSON `run`) + tests. The UI, scripts, CLI and control channel all reach the same commands.
- **Programmatic calls never open dialogs.**
- **Layering** is enforced by `cargo xtask layers` (`docs/architecture.md`): L0 `model` → L1
`geometry`, `mesh`, `fem`, `decks`, `render` → L2 solvers (`solver`; `explicit`, `lbm` later) →
L3 `fsi` (later) → L4 `doc` → L5 `io` → L6 `engine` → L7 `ui-egui`, `mcp` → apps. Nothing below
L7 depends on egui/eframe/winit/wgpu/rfd. **Only
`crates/geometry` may use `solidcraft-*`.**
- **Determinism.** The same input gives the same mesh, deck and CPU solver result, bit for bit, on
every platform: no hash-order iteration into output, no thread-count-dependent results. GPU
solver backends (wgpu, f32) are the one exception: deterministic per device, and checked against
the CPU reference within a stated tolerance.
- **Robust geometry.** Meshing decisions (orientation, in-sphere, intersection) use exact or
adaptive-precision predicates, never a bare floating-point sign.
- **Units.** The model is unit-consistent and never converts (the user picks e.g. mm, t, s, N,
MPa); geometry from SolidCraft is in millimetres. Z is up.
- **Rust only.** **Never break wasm**: everything below the apps builds for
`wasm32-unknown-unknown` (`cargo xtask wasm`, part of `cargo xtask ci`).
- **Quality gates:** GitHub CI runs `cargo xtask ci` (fmt, assets, licences, layers, clippy -D
warnings, tests, wasm) on every PR; don't run the full gate locally. Before pushing: `cargo fmt
--all`, `cargo check` the touched crates, and run the tests you added or changed. Commit after
each working step (a layer that compiles with its tests passing), not one big commit per PR.
- **Publishing**: `origin` is github.com/jyviko/modelcraft. Changes land through pull requests:
branch, push, open a PR, let CI run, then `gh pr merge --squash` when green. Rebase onto `main`
(never merge `main` into a branch); never force-push `main`. Never commit `plan/`,
`.agent-files/`, `worktrees/` or `target*/`; check `git ls-files` before pushing.
## Running
- `cargo run -p modelcraft-cli -- commands` lists every command with its parameters.
- `cargo run -p modelcraft-cli -- run script.json` runs a script (a JSON array of
`{"command", "params"}`) and prints the model summary.
- `cargo run --release -p modelcraft -- --sample --control PORT` opens the desktop app with the
sample model and a control channel on `127.0.0.1:PORT` (docs/control-protocol.md). For UI work,
look at the result: `ui.screenshot {path}` (needs a presented frame) or `ui.render {path}`
(CPU render, no window needed), then read the PNG.
- Build with `CARGO_TARGET_DIR=<repo>/target`. Parallel agents: separate target dirs, one
worktree each.
## Roadmap
`ROADMAP.md` (committed) tracks milestones. Update it whenever a milestone task lands.
-140
View File
@@ -1,140 +0,0 @@
# Attribution
Every non-code asset in this repository (images, icons, fonts, example geometry) is listed here
with its author, source and licence. `cargo xtask assets` (part of `cargo xtask ci`) fails if an
asset file is missing from this table.
**Policy (mandatory):** ModelCraft contains **no iconography, images, artwork, fonts, templates,
example decks or help text from commercial CAE products.** Every asset is original work by
ModelCraft contributors or third-party material under an open licence. Screenshots of commercial
software are never committed. Icons are made with VectorCraft; each icon's `.vectorcraft` source
is committed and listed here with its exports.
## Files
| 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
| File | Adapted from | Licence |
|---|---|---|
| xtask/src/layers.rs | SolidCraft `xtask/src/layers.rs` (itself adapted from CADCraft's xtask) | MIT OR Apache-2.0 |
| xtask/src/assets.rs, xtask/src/licences.rs, xtask/src/test.rs, xtask/src/main.rs | SolidCraft `xtask/src/` | MIT OR Apache-2.0 |
| 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), 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 |
## Test oracles
Used only by tests (dev-dependencies, not shipped); no code from them is copied or adapted.
| Used in | Oracle | Licence |
|---|---|---|
| crates/mesh/src/predicates/tests.rs, crates/mesh/tests/predicates_bench.rs | `robust` (georust), a port of Shewchuk's public-domain `predicates.c` | MIT OR Apache-2.0 |
| crates/mesh/src/predicates/tests.rs, crates/mesh/src/predicates/dyadic.rs (tests) | `num-bigint`, `num-rational`, `num-traits` (exact rationals) | MIT OR Apache-2.0 |
-1
View File
@@ -1 +0,0 @@
@AGENTS.md
-14
View File
@@ -1,14 +0,0 @@
# Contributing
Thanks for helping. Read [AGENTS.md](AGENTS.md) first: it holds the rules every change follows,
whether a person or an agent writes it.
1. Branch from `main`, keep a pull request to one topic.
2. Run `cargo xtask ci` before pushing; CI runs the same gates.
3. User-visible behaviour is a command (`crates/engine/src/cmd/`) with tests, including hostile
parameters.
4. Meshing and solver algorithms cite the paper they come from in the module docs.
5. Never contribute code, text or data from GPL-family projects or commercial CAE products
(see [docs/adr/0001-libraries.md](docs/adr/0001-libraries.md)).
By contributing you agree your work is licensed under MIT OR Apache-2.0.
Generated
-4949
View File
File diff suppressed because it is too large. Load diff
-106
View File
@@ -1,106 +0,0 @@
[workspace]
resolver = "3"
members = ["crates/*", "apps/*", "xtask"]
[workspace.package]
version = "0.1.0"
edition = "2024"
license = "MIT OR Apache-2.0"
rust-version = "1.95"
authors = ["ModelCraft contributors"]
repository = "https://github.com/jyviko/modelcraft"
[workspace.dependencies]
# internal
modelcraft-model = { path = "crates/model" }
modelcraft-geometry = { path = "crates/geometry" }
modelcraft-mesh = { path = "crates/mesh" }
modelcraft-decks = { path = "crates/decks" }
modelcraft-io = { path = "crates/io" }
modelcraft-fem = { path = "crates/fem" }
modelcraft-solver = { path = "crates/solver" }
modelcraft-engine = { path = "crates/engine" }
modelcraft-testkit = { path = "crates/testkit" }
modelcraft-render = { path = "crates/render" }
modelcraft-ui-egui = { path = "crates/ui-egui" }
# foundation
thiserror = "2"
serde = { version = "1", features = ["derive"] }
serde_json = { version = "1", features = ["float_roundtrip"] }
log = "0.4"
# 3MF packages (docs/formats/tagged-mesh.md): the same versions SolidCraft uses.
zip = { version = "3", default-features = false, features = ["deflate"] }
quick-xml = "0.41"
# content hashes and part checksums of .modelcraft files (the version SolidCraft uses)
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"
eframe = { version = "0.36", default-features = false }
egui-wgpu = "0.36"
# Geometry: SolidCraft's B-rep kernel (MIT OR Apache-2.0), pinned. Only crates/geometry uses it
# (plan/adr/0001-libraries.md).
solidcraft-geom = { git = "https://github.com/bherbruck/solidcraft", rev = "de1479029dd6821cffd28b70688a58e7f61f0cfd" }
solidcraft-kernel = { git = "https://github.com/bherbruck/solidcraft", rev = "de1479029dd6821cffd28b70688a58e7f61f0cfd" }
solidcraft-doc = { git = "https://github.com/bherbruck/solidcraft", rev = "de1479029dd6821cffd28b70688a58e7f61f0cfd" }
solidcraft-io = { git = "https://github.com/bherbruck/solidcraft", rev = "de1479029dd6821cffd28b70688a58e7f61f0cfd" }
# Runs SolidCraft command scripts (the test corpus recipes); only behind modelcraft-geometry's
# `scripts` feature.
solidcraft-engine = { git = "https://github.com/bherbruck/solidcraft", rev = "de1479029dd6821cffd28b70688a58e7f61f0cfd" }
[workspace.lints.rust]
unsafe_code = "forbid"
[workspace.lints.clippy]
dbg_macro = "warn"
todo = "warn"
too_many_arguments = "allow"
type_complexity = "allow"
# `!(x > tol)` is our idiom for "not a usable number" (NaN-safe).
neg_cmp_op_on_partial_ord = "allow"
[profile.dev.package."*"]
opt-level = 2
[profile.dev]
opt-level = 1
# Tests and lints (`cargo xtask ci`, GitHub CI). Debug assertions are off because truck's
# debug-only checks reject valid geometry (SolidCraft builds its tests the same way).
[profile.ci]
inherits = "dev"
opt-level = 1
debug = "line-tables-only"
debug-assertions = false
overflow-checks = true
incremental = false
[profile.ci.package."*"]
opt-level = 2
[profile.release]
opt-level = 3
lto = "thin"
codegen-units = 16
debug = "line-tables-only"
# SolidCraft builds truck and egui-wgpu with local fixes (its vendor/ directory). Patches don't
# reach a dependent workspace, so ModelCraft applies the same ones from the same pinned commit;
# keep this list and the rev in step with SolidCraft's [patch.crates-io].
[patch.crates-io]
truck-shapeops = { git = "https://github.com/bherbruck/solidcraft", rev = "de1479029dd6821cffd28b70688a58e7f61f0cfd" }
truck-stepio = { git = "https://github.com/bherbruck/solidcraft", rev = "de1479029dd6821cffd28b70688a58e7f61f0cfd" }
truck-meshalgo = { git = "https://github.com/bherbruck/solidcraft", rev = "de1479029dd6821cffd28b70688a58e7f61f0cfd" }
matext4cgmath = { git = "https://github.com/bherbruck/solidcraft", rev = "de1479029dd6821cffd28b70688a58e7f61f0cfd" }
# egui-wgpu with SolidCraft's fixes (vendor/egui-wgpu there): MSAA clamped to what the device
# supports and 1x on OpenGL adapters, so the requested 4x never fails pipeline validation at start.
egui-wgpu = { git = "https://github.com/bherbruck/solidcraft", rev = "de1479029dd6821cffd28b70688a58e7f61f0cfd" }
-177
View File
@@ -1,177 +0,0 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
-21
View File
@@ -1,21 +0,0 @@
MIT License
Copyright (c) 2026 ModelCraft contributors
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.
-19
View File
@@ -1,19 +0,0 @@
ModelCraft
Copyright (c) 2026 ModelCraft contributors.
Licensed under the MIT License or the Apache License, Version 2.0, at your option
(LICENSE-MIT, LICENSE-APACHE).
Third-party material
Software dependencies are listed in Cargo.lock; their licences are in THIRD-PARTY-LICENSES.txt
(`cargo xtask licences`). Geometry comes from SolidCraft (https://github.com/bherbruck/solidcraft,
MIT OR Apache-2.0), which builds on the truck crates (https://github.com/ricosjp/truck, Apache-2.0,
Copyright (c) RICOS Co. Ltd.), some with SolidCraft's modifications.
Some code is adapted from sibling projects (SolidCraft, CADCraft), licensed MIT OR Apache-2.0;
ATTRIBUTION.md lists the files.
ModelCraft is an independent project and is not affiliated with, sponsored by or endorsed by
Dassault Systèmes, MSC Software, Siemens Digital Industries Software or Ansys, Inc. Abaqus,
Nastran, MSC Nastran, Simcenter Nastran and LS-DYNA are trademarks of their respective owners;
they are used here only to describe file compatibility.
+2 -34
View File
@@ -1,35 +1,3 @@
# ModelCraft
# Issue media
An open-source, clean-room CAE modeling application in pure Rust: geometry to analysis-ready
finite element models, with robust tetrahedral and hexahedral meshing, solver decks for Abaqus,
Nastran and LS-DYNA, and its own linear static and modal solver. Desktop, browser and AI agents
drive the same commands.
**Status:** early. The workspace, quality gates, the FE model, the command engine and the
geometry boundary (SolidCraft's kernel and tessellator) are in place; meshing is next. See
[ROADMAP.md](ROADMAP.md).
## Build
```sh
cargo xtask ci # fmt, assets, licences, layers, clippy, tests, wasm
cargo run -p modelcraft-cli -- commands # every command and its parameters
cargo run -p modelcraft-cli -- run script.json # run a command script
```
Rust 1.95 or later, with the `wasm32-unknown-unknown` target for `cargo xtask ci`.
## Documentation
- [Architecture](docs/architecture.md): crates, layers and the meshing pipeline
- [Libraries and licences](docs/adr/0001-libraries.md)
- [Contributing](CONTRIBUTING.md) and [agent instructions](AGENTS.md)
## License
Dual-licensed under [MIT](LICENSE-MIT) or [Apache-2.0](LICENSE-APACHE), at your option. Notices
are in [NOTICE](NOTICE); third-party licences in [THIRD-PARTY-LICENSES.txt](THIRD-PARTY-LICENSES.txt).
ModelCraft is an independent project, not affiliated with, sponsored or endorsed by Dassault
Systèmes, MSC Software, Siemens or Ansys. Abaqus, Nastran, MSC Nastran, Simcenter Nastran and
LS-DYNA are trademarks of their owners and are named only to describe file compatibility.
Screenshots referenced from GitHub issues, kept off `main`. FieldCraft's own renders and captures (MIT OR Apache-2.0).
-36
View File
@@ -1,36 +0,0 @@
# Roadmap
ModelCraft's goal is CAE modeling on par with Abaqus/CAE, Nastran pre-processors and LS-PrePost,
with hexahedral meshing as the centre of gravity, plus its own linear solver. Abaqus/CAE is the
reference for scope (its documentation is excellent and its solver strong); its application is
where we aim to be clearly better: parametric geometry from SolidCraft, sets that survive
remeshing, automatic hex partitioning, undo, a text-diffable model and agent control.
The capability checklist is [docs/parity.md](docs/parity.md). Beyond the pre-processor and the
linear solver come our own explicit, CFD (lattice Boltzmann) and fluid–structure solvers (M10–M14;
methods and papers in [docs/solvers/literature.md](docs/solvers/literature.md)).
Order (revised 2026-10-13): one end-to-end slice first — *SolidCraft part → named faces → sets →
mesh → material and section → BCs and loads → static and frequency steps → Abaqus, Nastran and
LS-DYNA decks and our own solve → contour plot* — on tet meshes, so every hex mesher lands in a
pipeline that already produces solvable, verified models. Then hex: structured (sweep and mapped,
with partitions proposed automatically) before octree all-hex, because that is how analysts get
hex meshes today and it gives the best elements where stresses are read.
| Milestone | Scope | Status |
|---|---|---|
| M0 Foundation | Workspace, quality gates, FE model, command engine with rollback and panic guard, CLI, geometry boundary on SolidCraft | done |
| M1 Geometry in and surface preparation | Open `.solidcraft` designs with persistent face names, assemblies placed (done); face-tagged 3MF (done); test corpus, `cargo xtask corpus` (done); exact predicates (done); quality metrics and certified validity gate (done); weld, closed/manifold/orientation and self-intersection checks, feature edges (`modelcraft-mesh::surface`, `mesh.surface.check`, done) | in progress |
| M2 Tet meshing and size field | Size field (global, per face and edge seeds, curvature and proximity; the `modelcraft_mesh::size::SizeField` trait and edge-division helpers are in); Bowyer–Watson Delaunay (exact, symbolic perturbation, verified; `modelcraft-mesh::delaunay`, done); robust CDT boundary recovery (Diazzi et al. 2023); Delaunay refinement, ODT smoothing, sliver removal; tet4 and tet10 with mid-side nodes on the B-rep; mesh verify per set | in progress |
| M3 First deck | Sets and surfaces bound to SolidCraft face, edge, vertex and body names, resolved after meshing; materials (isotropic and orthotropic elastic, density) with a unit-system label and consistency check; sections (solid, shell, beam profiles) assigned by set; element formulation per region mapped to each solver; BCs (fixed, displacement, symmetry); loads (force and moment on reference points, pressure, gravity); reference points with kinematic and distributing coupling; steps (linear static, frequency) with explicit per-step load and BC tables and output presets; `model.check` naming every missing or bad item; `model.*` and `mesh.tag` commands (model definition: done); writers for Abaqus input (done: `deck.write`), Nastran SOL 101/103 (done: `deck.write`) and LS-DYNA implicit (done); the `.modelcraft` file (text definition, binary mesh, geometry references reopened on load, journal; atomic saves, autosave and recovery; undo/redo on the journal: done) | in progress |
| M4 Own solver and first results | Linear static and modal solver (tet4/10, wedge6, hex8, hex20; sparse direct, Lanczos), verified against analytic solutions (solver: done — `modelcraft-fem` kernels, `modelcraft-solver` with nested dissection, sparse Cholesky and block Lanczos, `solve.static`/`solve.frequency`/`solve.probe`, patch, cantilever, Lamé, Kirsch and beam-frequency tests; reference points with kinematic and distributing couplings and moments by master–slave constraint elimination, verified by rigid motion, clamping, Saint-Venant tension, bending and tube torsion); deformed shape, contours, mode shapes, probes, reaction sums | started |
| M5 Structured hex | 2D quad meshing of faces (`modelcraft-mesh::quad`: transfinite mapped meshes, free all-quad meshes of polygons with holes on prescribed boundary nodes, exact planar quad validity, shared `SizeField` and even edge divisions; done for planar faces); mapped hex of six-sided regions; sweep meshing; conforming interfaces and tet–hex transition; automatic decomposition into sweepable and mappable regions, proposed as SolidCraft splits | started |
| M6 Automatic hex | Octree/grid-dual all-hex for any part; hex-dominant by tet recombination; polycube for blocky parts; smoothing, untangling, boundary padding, layers through thin walls; mesh editing and orphan-mesh import | planned |
| M7 Assemblies and contact | Part instances from SolidCraft occurrences; tie between non-matching meshes; general and pairwise contact with automatic pair detection, friction; bolt pretension, springs, point masses; amplitudes, multiple steps; nonlinear static steps in decks | planned |
| M8 Materials, explicit, shells, composites | Plasticity, hyperelasticity, damage data per solver; explicit dynamics decks (Abaqus/Explicit, LS-DYNA); midsurface shells; composite layups and material orientations, continuum shells on swept hex; heat transfer | planned |
| M9 Post-processing and deck readers | Results readers for public formats (Nastran OP2, LS-DYNA d3plot, Abaqus `.fil`); XY and path plots, cuts, display groups, free-body forces; deck readers that keep unknown keywords; mesh convergence studies | planned |
| M10 Explicit dynamics | Shared element and material kernels with the implicit solver (`fem`); central-difference solver with lumped mass, stable time step, one-point hex8 with hourglass control and nodal-pressure tet4, bulk viscosity, energy accounting; large-deformation materials (objective rates, J2, Johnson–Cook, damage, erosion); contact (global search, penalty with friction, rigid walls); runs on hex and tet meshes | planned |
| M11 Equations of state and shells | Polynomial, ideal-gas, Mie–Grüneisen, JWL with programmed burn, tabulated; energy coupling; shock verification (Rankine–Hugoniot, Sod, Noh, Sedov); Belytschko–Lin–Tsay shells with self-contact on quad meshes | planned |
| 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; 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 |
-11
View File
@@ -1,11 +0,0 @@
# Security policy
ModelCraft is young; only `main` and the latest release get fixes.
Please **don't open a public issue** for a security problem. Report it privately through the
repository's [Security tab](https://github.com/jyviko/modelcraft/security/advisories/new) with
what you found, how to reproduce it (a model, deck or script), the version and platform, and the
impact you expect.
Reports are especially useful for opening untrusted models, decks or scripts (crashes, runaway
memory or CPU, path tricks) and for the control channel once it exists.
File diff suppressed because it is too large. Load diff
-13
View File
@@ -1,13 +0,0 @@
[package]
name = "modelcraft-cli"
description = "ModelCraft from the command line: list commands, run scripts"
version.workspace = true
edition.workspace = true
license.workspace = true
[lints]
workspace = true
[dependencies]
modelcraft-engine = { workspace = true }
serde_json = { workspace = true }
-65
View File
@@ -1,65 +0,0 @@
//! modelcraft-cli commands
//! modelcraft-cli run <script.json>
//! modelcraft-cli features
#![deny(clippy::unwrap_used, clippy::expect_used, clippy::panic, clippy::unimplemented, clippy::todo, clippy::unreachable)]
#![forbid(unsafe_code)]
use std::process::ExitCode;
use modelcraft_engine::Session;
use serde_json::json;
const USAGE: &str = "\
usage:
modelcraft-cli commands list every command with its parameters
modelcraft-cli run <script.json> 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).
const MAX_SCRIPT_BYTES: u64 = 256 * 1024 * 1024;
fn main() -> ExitCode {
let args: Vec<String> = std::env::args().skip(1).collect();
let result = match args.first().map(String::as_str) {
Some("commands") => {
for c in modelcraft_engine::commands() {
println!("{:<24} {:<18} {}", c.id, c.label, c.params);
}
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}");
Ok(())
}
Some(other) => Err(format!("unknown command `{other}`\n\n{USAGE}")),
};
match result {
Ok(()) => ExitCode::SUCCESS,
Err(e) => {
eprintln!("error: {e}");
ExitCode::FAILURE
}
}
}
fn run(path: &str) -> Result<(), String> {
let size = std::fs::metadata(path).map_err(|e| format!("{path}: {e}"))?.len();
if size > MAX_SCRIPT_BYTES {
return Err(format!("{path}: larger than {} MB", MAX_SCRIPT_BYTES / (1024 * 1024)));
}
let text = std::fs::read_to_string(path).map_err(|e| format!("{path}: {e}"))?;
let script: serde_json::Value = serde_json::from_str(&text).map_err(|e| format!("{path}: {e}"))?;
let mut session = Session::default();
session.run_script(&script).map_err(|e| e.to_string())?;
let info = session.execute("model.info", &json!({})).map_err(|e| e.to_string())?;
println!("{}", serde_json::to_string_pretty(&info).map_err(|e| e.to_string())?);
Ok(())
}
-18
View File
@@ -1,18 +0,0 @@
[package]
name = "modelcraft"
description = "ModelCraft desktop app"
version.workspace = true
edition.workspace = true
license.workspace = true
publish = false
[lints]
workspace = true
[dependencies]
modelcraft-engine = { workspace = true }
modelcraft-ui-egui = { workspace = true }
eframe = { workspace = true, features = ["default_fonts", "wgpu", "accesskit", "wayland", "x11"] }
egui = { workspace = true }
serde_json = { workspace = true }
log = { workspace = true }
-161
View File
@@ -1,161 +0,0 @@
//! Loopback JSON-lines control server: one request per line, one reply per line. Agents and
//! tests drive the app through it; the UI thread answers each request between frames
//! (`modelcraft_ui_egui::control`).
//!
//! Adapted from SolidCraft's `apps/solidcraft/src/control_server.rs` (MIT OR Apache-2.0), see
//! ATTRIBUTION.md.
use std::io::{BufRead, BufReader, Write};
use std::net::{TcpListener, TcpStream};
use std::sync::atomic::{AtomicUsize, Ordering};
use std::sync::mpsc::{Receiver, Sender, channel};
use std::time::Duration;
use modelcraft_ui_egui::ControlRequest;
use serde_json::{Value, json};
/// Longest request line (bytes).
const MAX_LINE: usize = 16 * 1024 * 1024;
/// Connections served at once. The channel has no authentication beyond being bound to
/// loopback, so a flood must not be able to spawn threads without end.
const MAX_CONNECTIONS: usize = 16;
/// Lines that are not JSON before the connection is closed, so garbage cannot loop forever.
const MAX_BAD_LINES: usize = 8;
/// How long a request waits for the UI thread.
const REPLY_TIMEOUT: Duration = Duration::from_secs(60);
static OPEN: AtomicUsize = AtomicUsize::new(0);
pub fn start(port: u16, ctx: egui::Context) -> Receiver<ControlRequest> {
let (tx, rx) = channel::<ControlRequest>();
let listener = match TcpListener::bind(("127.0.0.1", port)) {
Ok(l) => l,
Err(e) => {
eprintln!("modelcraft: control server failed to bind 127.0.0.1:{port}: {e}");
return rx;
}
};
eprintln!("modelcraft: control server listening on 127.0.0.1:{port}");
std::thread::spawn(move || {
for stream in listener.incoming().flatten() {
if OPEN.fetch_add(1, Ordering::Relaxed) >= MAX_CONNECTIONS {
OPEN.fetch_sub(1, Ordering::Relaxed);
let mut refused = stream;
let _ = writeln!(refused, "{}", json!({"ok": false, "error": "too many connections"}));
continue;
}
let tx = tx.clone();
let ctx = ctx.clone();
std::thread::spawn(move || {
serve(stream, tx, ctx);
OPEN.fetch_sub(1, Ordering::Relaxed);
});
}
});
rx
}
/// One line without its newline, or `None` at the end of the stream. A client that sends
/// gigabytes with no newline would otherwise make this thread allocate until the process is
/// killed, so the line is refused as soon as it passes `max`.
fn read_line(r: &mut impl BufRead, max: usize) -> std::io::Result<Option<Vec<u8>>> {
let mut line = Vec::new();
loop {
let (done, used) = {
let available = r.fill_buf()?;
if available.is_empty() {
return Ok((!line.is_empty()).then_some(line));
}
match available.iter().position(|b| *b == b'\n') {
Some(i) => {
line.extend_from_slice(available.get(..i).unwrap_or(&[]));
(true, i + 1)
}
None => {
line.extend_from_slice(available);
(false, available.len())
}
}
};
r.consume(used);
if line.len() > max {
return Err(std::io::Error::new(std::io::ErrorKind::InvalidData, "request too large"));
}
if done {
return Ok(Some(line));
}
}
}
fn serve(stream: TcpStream, tx: Sender<ControlRequest>, ctx: egui::Context) {
let Ok(read) = stream.try_clone() else { return };
let mut out = stream;
let mut reader = BufReader::new(read);
let mut bad = 0usize;
loop {
let line = match read_line(&mut reader, MAX_LINE) {
Ok(Some(l)) => String::from_utf8_lossy(&l).into_owned(),
Ok(None) => break,
Err(e) => {
let _ = writeln!(out, "{}", json!({"ok": false, "error": e.to_string()}));
break;
}
};
if line.trim().is_empty() {
continue;
}
let reply = match serde_json::from_str::<Value>(&line) {
Ok(msg) => {
let id = msg.get("id").cloned().unwrap_or(Value::Null);
let method = msg.get("method").and_then(Value::as_str).unwrap_or("").to_string();
let params = msg.get("params").cloned().unwrap_or(json!({}));
let (req, rrx) = ControlRequest::new(method, params);
if tx.send(req).is_err() {
break;
}
ctx.request_repaint();
let mut r = rrx.recv_timeout(REPLY_TIMEOUT).unwrap_or_else(|_| json!({"ok": false, "error": "timeout"}));
if let Some(o) = r.as_object_mut() {
o.insert("id".into(), id);
}
r
}
Err(e) => {
bad += 1;
json!({"ok": false, "error": format!("bad JSON: {e}")})
}
};
if writeln!(out, "{reply}").is_err() || bad >= MAX_BAD_LINES {
break;
}
}
}
#[cfg(test)]
mod tests {
use super::*;
/// A request longer than the cap is refused instead of allocated.
#[test]
fn lines_past_the_cap_are_refused() {
let flood = vec![b'A'; MAX_LINE + 2];
let mut r = BufReader::new(flood.as_slice());
let e = read_line(&mut r, MAX_LINE).unwrap_err();
assert_eq!(e.kind(), std::io::ErrorKind::InvalidData);
}
/// Lines split on newlines, blank lines kept, no trailing newline needed; a line spanning
/// several reads arrives whole.
#[test]
fn lines_split_on_newlines() {
let text = b"{\"a\":1}\n\n{\"b\":2}\nlast".to_vec();
let mut r = BufReader::with_capacity(3, text.as_slice());
let mut got = Vec::new();
while let Some(line) = read_line(&mut r, MAX_LINE).unwrap() {
got.push(String::from_utf8(line).unwrap());
}
assert_eq!(got, vec!["{\"a\":1}", "", "{\"b\":2}", "last"]);
let mut r = BufReader::with_capacity(4, b"0123456789\n".as_slice());
assert!(read_line(&mut r, 5).is_err());
}
}
-165
View File
@@ -1,165 +0,0 @@
//! ModelCraft desktop app.
//!
//! Usage: `modelcraft [--sample] [--control PORT]`
//!
//! `--sample` opens a sample model (`modelcraft_engine::sample`). `--control PORT` (or
//! `MODELCRAFT_CONTROL_PORT`) starts a localhost JSON-lines control server:
//! `{"id":1,"method":"engine.execute","params":{"command":"model.info","params":{}}}`. See
//! `modelcraft_ui_egui::control` and docs/control-protocol.md.
#![cfg_attr(all(target_os = "windows", not(debug_assertions)), windows_subsystem = "windows")]
#![deny(clippy::unwrap_used, clippy::expect_used, clippy::panic, clippy::unimplemented, clippy::todo, clippy::unreachable)]
#![forbid(unsafe_code)]
mod control_server;
use modelcraft_engine::Session;
use modelcraft_engine::autosave::{self, Autosaver};
use modelcraft_ui_egui::ModelApp;
const USAGE: &str = "usage: modelcraft [--sample] [--control PORT]";
const DEPTH_BITS: u8 = 24;
const MSAA: u16 = 4;
/// How often unsaved changes are autosaved for recovery (seconds).
const AUTOSAVE_SECONDS: f64 = 30.0;
struct App {
app: ModelApp,
/// Autosave for crash recovery (`None` when the recovery folder is unavailable).
autosaver: Option<Autosaver>,
/// App time of the last autosave check.
autosaved_at: f64,
}
impl App {
fn autosave(&mut self) {
if let Some(a) = &mut self.autosaver
&& let Err(e) = a.save(&self.app.session)
{
log::warn!("autosave: {e}");
}
}
}
impl eframe::App for App {
fn logic(&mut self, ctx: &egui::Context, _frame: &mut eframe::Frame) {
self.app.logic(ctx);
if self.app.now - self.autosaved_at >= AUTOSAVE_SECONDS {
self.autosaved_at = self.app.now;
self.autosave();
}
if self.autosaver.is_some() {
ctx.request_repaint_after(std::time::Duration::from_secs_f64(AUTOSAVE_SECONDS));
}
}
fn on_exit(&mut self) {
if let Some(a) = self.autosaver.take()
&& let Err(e) = a.close(&self.app.session)
{
log::warn!("autosave: {e}");
}
}
fn raw_input_hook(&mut self, _ctx: &egui::Context, raw: &mut egui::RawInput) {
self.app.raw_input_hook(raw);
}
fn ui(&mut self, ui: &mut egui::Ui, _frame: &mut eframe::Frame) {
self.app.ui(ui);
}
}
/// Command-line options.
#[derive(Debug, Default, PartialEq)]
struct Args {
sample: bool,
control: Option<u16>,
}
fn parse_args(args: impl IntoIterator<Item = String>, env_port: Option<String>) -> Result<Option<Args>, String> {
let mut out = Args { control: env_port.and_then(|p| p.trim().parse().ok()), ..Default::default() };
let mut args = args.into_iter();
while let Some(a) = args.next() {
match a.as_str() {
"--sample" => out.sample = true,
"--control" => {
let port = args.next().ok_or("--control needs a port")?;
out.control = Some(port.parse().map_err(|_| format!("--control: `{port}` is not a port number"))?);
}
"--version" | "-V" => {
println!("modelcraft {}", modelcraft_ui_egui::VERSION);
return Ok(None);
}
"--help" | "-h" => {
println!("{USAGE}");
return Ok(None);
}
other => return Err(format!("unknown argument `{other}`\n{USAGE}")),
}
}
Ok(Some(out))
}
fn main() -> eframe::Result {
let args = match parse_args(std::env::args().skip(1), std::env::var("MODELCRAFT_CONTROL_PORT").ok()) {
Ok(Some(a)) => a,
Ok(None) => return Ok(()),
Err(e) => {
eprintln!("modelcraft: {e}");
std::process::exit(2);
}
};
let options = eframe::NativeOptions {
viewport: egui::ViewportBuilder::default().with_title("ModelCraft").with_inner_size([1400.0, 900.0]).with_min_inner_size([800.0, 500.0]),
depth_buffer: DEPTH_BITS,
multisampling: MSAA,
..Default::default()
};
eframe::run_native(
"ModelCraft",
options,
Box::new(move |cc| {
let mut app = ModelApp::new(Session::default());
if let Some(rs) = &cc.wgpu_render_state {
let info = rs.adapter.get_info();
eprintln!("modelcraft: graphics {:?} {}, MSAA {}x (requested {MSAA}x)", info.backend, info.name, rs.msaa_samples);
app.set_wgpu(rs, DEPTH_BITS, rs.msaa_samples, &cc.egui_ctx);
}
if let Some(port) = args.control {
app = app.with_control(control_server::start(port, cc.egui_ctx.clone()));
}
if args.sample {
// The status bar reports a failure; the app still opens.
let _ = app.run_script(&modelcraft_engine::sample::script());
}
let autosaver = autosave::default_dir().and_then(|dir| {
let listed = app.session.execute("file.recovery.list", &serde_json::json!({"dir": dir}));
let recoverable = listed.ok().and_then(|v| v.as_array().map(Vec::len)).unwrap_or(0);
if recoverable > 0 {
app.set_status(format!("{recoverable} autosaved model(s) can be recovered (file.recovery.list, file.recover)"), false);
}
Autosaver::new(&dir).map_err(|e| log::warn!("autosave unavailable: {e}")).ok()
});
Ok(Box::new(App { app, autosaver, autosaved_at: 0.0 }))
}),
)
}
#[cfg(test)]
mod tests {
use super::*;
fn parse(a: &[&str], env: Option<&str>) -> Result<Option<Args>, String> {
parse_args(a.iter().map(|s| s.to_string()), env.map(str::to_string))
}
#[test]
fn arguments() {
assert_eq!(parse(&[], None), Ok(Some(Args::default())));
assert_eq!(parse(&["--sample", "--control", "7070"], None), Ok(Some(Args { sample: true, control: Some(7070) })));
assert_eq!(parse(&[], Some("9000")), Ok(Some(Args { sample: false, control: Some(9000) })));
assert_eq!(parse(&[], Some("nope")), Ok(Some(Args::default())));
assert!(parse(&["--control"], None).is_err());
assert!(parse(&["--control", "99999"], None).is_err());
assert!(parse(&["--frobnicate"], None).is_err());
assert_eq!(parse(&["--help"], None), Ok(None));
}
}
-11
View File
@@ -1,11 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="24" height="24" viewBox="0 0 24 24">
<title>assembly.instance</title>
<g id="Layer_1" data-name="Layer 1">
<path d="M8 10 L13 12.5 L13 17.5 L8 20 L3 17.5 L3 12.5 Z" fill="#2d4e70" stroke="#dde2ea" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M3 12.5 L8 15 L13 12.5 M8 15 L8 20" fill="none" stroke="#dde2ea" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M16 4 L21 6.5 L21 11.5 L16 14 L11 11.5 L11 6.5 Z" fill="none" stroke="#4f9ce8" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M11 6.5 L16 9 L21 6.5 M16 9 L16 14" fill="none" stroke="#4f9ce8" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M10 8 L13.5 6 M12.19 8.13 L13.5 6 L11 6.05" fill="none" stroke="#dde2ea" stroke-width="1.25" stroke-linecap="round" stroke-linejoin="round"/>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 1023 B

Binary file not shown.
-10
View File
@@ -1,10 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="24" height="24" viewBox="0 0 24 24">
<title>deck.read</title>
<g id="Layer_1" data-name="Layer 1">
<path d="M8 3 L16 3 L20 7 L20 21 L8 21 Z" fill="#2d4e70" stroke="#dde2ea" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M16 3 L16 7 L20 7" fill="none" stroke="#dde2ea" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M11 10 L17 10 M11 13 L17 13 M11 16 L15 16" fill="none" stroke="#dde2ea" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M2 15 L9 15 M6.19 16.53 L9 15 L6.19 13.47" fill="none" stroke="#4f9ce8" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 808 B

Binary file not shown.
-11
View File
@@ -1,11 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="24" height="24" viewBox="0 0 24 24">
<title>deck.write.abaqus</title>
<g id="Layer_1" data-name="Layer 1">
<path d="M4 3 L12 3 L16 7 L16 21 L4 21 Z" fill="#2d4e70" stroke="#dde2ea" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M12 3 L12 7 L16 7" fill="none" stroke="#dde2ea" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M7 10 L13 10 M7 13 L13 13 M7 16 L11 16" fill="none" stroke="#dde2ea" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M15 15 L21 15 M18.19 16.53 L21 15 L18.19 13.47" fill="none" stroke="#4f9ce8" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M16 6 C16 4.619 17.119 3.5 18.5 3.5 C19.881 3.5 21 4.619 21 6 C21 7.381 19.881 8.5 18.5 8.5 C17.119 8.5 16 7.381 16 6 Z" fill="#4f9ce8" stroke="#4f9ce8" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.
-11
View File
@@ -1,11 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="24" height="24" viewBox="0 0 24 24">
<title>deck.write.lsdyna</title>
<g id="Layer_1" data-name="Layer 1">
<path d="M4 3 L12 3 L16 7 L16 21 L4 21 Z" fill="#2d4e70" stroke="#dde2ea" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M12 3 L12 7 L16 7" fill="none" stroke="#dde2ea" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M7 10 L13 10 M7 13 L13 13 M7 16 L11 16" fill="none" stroke="#dde2ea" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M15 15 L21 15 M18.19 16.53 L21 15 L18.19 13.47" fill="none" stroke="#4f9ce8" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M18.5 3 L21.3 8.2 L15.7 8.2 Z" fill="#4f9ce8" stroke="#4f9ce8" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 962 B

Binary file not shown.
-11
View File
@@ -1,11 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="24" height="24" viewBox="0 0 24 24">
<title>deck.write.nastran</title>
<g id="Layer_1" data-name="Layer 1">
<path d="M4 3 L12 3 L16 7 L16 21 L4 21 Z" fill="#2d4e70" stroke="#dde2ea" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M12 3 L12 7 L16 7" fill="none" stroke="#dde2ea" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M7 10 L13 10 M7 13 L13 13 M7 16 L11 16" fill="none" stroke="#dde2ea" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M15 15 L21 15 M18.19 16.53 L21 15 L18.19 13.47" fill="none" stroke="#4f9ce8" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M16 3.5 L21 3.5 L21 8.5 L16 8.5 Z" fill="#4f9ce8" stroke="#4f9ce8" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 967 B

Binary file not shown.
-8
View File
@@ -1,8 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="24" height="24" viewBox="0 0 24 24">
<title>edit.redo</title>
<g id="Layer_1" data-name="Layer 1">
<path d="M19 9 L10 9 C7.239 9 5 11.239 5 14 C5 16.761 7.239 19 10 19 L16 19" fill="none" stroke="#4f9ce8" stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M16 5.5 L19.5 9 L16 12.5" fill="none" stroke="#4f9ce8" stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round"/>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 562 B

Binary file not shown.
-8
View File
@@ -1,8 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="24" height="24" viewBox="0 0 24 24">
<title>edit.undo</title>
<g id="Layer_1" data-name="Layer 1">
<path d="M5 9 L14 9 C16.761 9 19 11.239 19 14 C19 16.761 16.761 19 14 19 L8 19" fill="none" stroke="#4f9ce8" stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M8 5.5 L4.5 9 L8 12.5" fill="none" stroke="#4f9ce8" stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round"/>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 562 B

Binary file not shown.
-8
View File
@@ -1,8 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="24" height="24" viewBox="0 0 24 24">
<title>file.open</title>
<g id="Layer_1" data-name="Layer 1">
<path d="M3 5 L9 5 L11 7 L20 7 L20 19 L3 19 Z" fill="#2d4e70" stroke="#dde2ea" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M12 17 L12 10 M13.53 12.81 L12 10 L10.47 12.81" fill="none" stroke="#4f9ce8" stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round"/>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 556 B

Binary file not shown.
-9
View File
@@ -1,9 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="24" height="24" viewBox="0 0 24 24">
<title>file.recover</title>
<g id="Layer_1" data-name="Layer 1">
<path d="M4.5 12 C4.505 15.538 6.981 18.591 10.442 19.327 C13.903 20.062 17.406 18.278 18.849 15.048 C20.291 11.817 19.279 8.018 16.421 5.932 C13.564 3.846 9.637 4.041 7 6.4" fill="none" stroke="#4f9ce8" stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M3.4 4.6 L7 6.4 L5.6 10.2" fill="none" stroke="#4f9ce8" stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M12 8 L12 12 L15 14" fill="none" stroke="#dde2ea" stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round"/>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 796 B

Binary file not shown.
-8
View File
@@ -1,8 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="24" height="24" viewBox="0 0 24 24">
<title>file.save</title>
<g id="Layer_1" data-name="Layer 1">
<path d="M3 14 L3 20 L21 20 L21 14" fill="none" stroke="#dde2ea" stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M12 3 L12 15 M10.47 12.19 L12 15 L13.53 12.19" fill="none" stroke="#4f9ce8" stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round"/>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 542 B

Binary file not shown.
-9
View File
@@ -1,9 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="24" height="24" viewBox="0 0 24 24">
<title>file.save_as</title>
<g id="Layer_1" data-name="Layer 1">
<path d="M3 14 L3 20 L21 20 L21 14" fill="none" stroke="#dde2ea" stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M9 3 L9 15 M5.8 12 L9 15 L12.2 12" fill="none" stroke="#4f9ce8" stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M14 12 L19.5 6.5 L21.5 8.5 L16 14 L13.5 14.5 Z" fill="#2d4e70" stroke="#f0b44a" stroke-width="1.25" stroke-linecap="round" stroke-linejoin="round"/>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 695 B

Binary file not shown.
-10
View File
@@ -1,10 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="24" height="24" viewBox="0 0 24 24">
<title>flow.boundary</title>
<g id="Layer_1" data-name="Layer 1">
<path d="M3 5 L21 5 M3 19 L21 19" fill="none" stroke="#dde2ea" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M3 9.5 L9 9.5 M6.19 11.03 L9 9.5 L6.19 7.97" fill="none" stroke="#f0b44a" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M3 14.5 L9 14.5 M6.19 16.03 L9 14.5 L6.19 12.97" fill="none" stroke="#f0b44a" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M15 12 L21 12 M18.19 13.53 L21 12 L18.19 10.47" fill="none" stroke="#4f9ce8" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 857 B

Binary file not shown.
-9
View File
@@ -1,9 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="24" height="24" viewBox="0 0 24 24">
<title>flow.domain</title>
<g id="Layer_1" data-name="Layer 1">
<path d="M3 3 L21 3 L21 21 L3 21 Z" fill="none" stroke="#dde2ea" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
<path 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" fill="none" stroke="#dde2ea" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M7.5 12 C7.5 9.515 9.515 7.5 12 7.5 C14.485 7.5 16.5 9.515 16.5 12 C16.5 14.485 14.485 16.5 12 16.5 C9.515 16.5 7.5 14.485 7.5 12 Z" fill="#2d4e70" stroke="#4f9ce8" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 813 B

Binary file not shown.
-10
View File
@@ -1,10 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="24" height="24" viewBox="0 0 24 24">
<title>geometry.bodies</title>
<g id="Layer_1" data-name="Layer 1">
<path d="M9 8 L15 11 L15 18 L9 21 L3 18 L3 11 Z" fill="#2d4e70" stroke="#dde2ea" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M3 11 L9 14 L15 11 M9 14 L9 21" fill="none" stroke="#dde2ea" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M14 4 L19 6.5 L19 13 L16 14.5" fill="none" stroke="#4f9ce8" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M14 4 L9 6.5 L9 7" fill="none" stroke="#4f9ce8" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 817 B

Binary file not shown.
-10
View File
@@ -1,10 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="24" height="24" viewBox="0 0 24 24">
<title>geometry.datum</title>
<g id="Layer_1" data-name="Layer 1">
<path d="M3 15 L9 9 L21 9 L15 15 Z" fill="#2d4e70" stroke="#4f9ce8" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M12 12 L12 3 M13.53 5.81 L12 3 L10.47 5.81" fill="none" stroke="#dde2ea" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M10.5 12 C10.5 11.172 11.172 10.5 12 10.5 C12.828 10.5 13.5 11.172 13.5 12 C13.5 12.828 12.828 13.5 12 13.5 C11.172 13.5 10.5 12.828 10.5 12 Z" fill="#4f9ce8"/>
<path d="M12 15 L12 21" fill="none" stroke="#dde2ea" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" stroke-dasharray="1.5 2"/>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 869 B

Binary file not shown.
-10
View File
@@ -1,10 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="24" height="24" viewBox="0 0 24 24">
<title>geometry.import.mesh</title>
<g id="Layer_1" data-name="Layer 1">
<path d="M3 13 L12 9 L21 13 L12 17 Z" fill="#2d4e70" stroke="#dde2ea" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M7.5 11 L16.5 15 M7.5 15 L16.5 11 M12 9 L12 17" fill="none" stroke="#dde2ea" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M3 13 L3 16 L12 20 L21 16 L21 13" fill="none" stroke="#dde2ea" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M12 2 L12 8 M10.47 5.19 L12 8 L13.53 5.19" fill="none" stroke="#4f9ce8" stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round"/>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 836 B

Binary file not shown.
-9
View File
@@ -1,9 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="24" height="24" viewBox="0 0 24 24">
<title>geometry.midsurface</title>
<g id="Layer_1" data-name="Layer 1">
<path d="M3 9 L9 4 L21 4 L15 9 Z" fill="none" stroke="#dde2ea" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M3 14 L9 9 L21 9 L15 14 Z" fill="#2d4e70" stroke="#4f9ce8" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M3 19 L9 14 L21 14 L15 19 Z" fill="none" stroke="#dde2ea" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 670 B

Binary file not shown.
-9
View File
@@ -1,9 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="24" height="24" viewBox="0 0 24 24">
<title>geometry.open</title>
<g id="Layer_1" data-name="Layer 1">
<path d="M13 6 L20 9.5 L20 17.5 L13 21 L6 17.5 L6 9.5 Z" fill="#2d4e70" stroke="#dde2ea" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M6 9.5 L13 13 L20 9.5 M13 13 L13 21" fill="none" stroke="#dde2ea" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M3 3 L9 9 M5.93 8.1 L9 9 L8.1 5.93" fill="none" stroke="#4f9ce8" stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round"/>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 705 B

Binary file not shown.
-10
View File
@@ -1,10 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="24" height="24" viewBox="0 0 24 24">
<title>geometry.partition</title>
<g id="Layer_1" data-name="Layer 1">
<path d="M12 3 L20 7 L20 16 L12 20 L4 16 L4 7 Z" fill="#2d4e70" stroke="#dde2ea" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M4 7 L12 11 L20 7 M12 11 L12 20" fill="none" stroke="#dde2ea" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M8 5 L16 9 M16 9 L16 18 M16 9 L16 9" fill="none" stroke="#4f9ce8" stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M8 5 L8 14 L16 18" fill="none" stroke="#4f9ce8" stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round"/>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 829 B

Binary file not shown.
-9
View File
@@ -1,9 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="24" height="24" viewBox="0 0 24 24">
<title>geometry.tessellate</title>
<g id="Layer_1" data-name="Layer 1">
<path d="M3 12 C3 7.029 7.029 3 12 3 C16.971 3 21 7.029 21 12 C21 16.971 16.971 21 12 21 C7.029 21 3 16.971 3 12 Z" fill="#2d4e70" stroke="#dde2ea" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
<path 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" fill="none" stroke="#4f9ce8" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M19.79 16.5 L12 21 L4.21 16.5 L4.21 7.5 L12 3 L19.79 7.5 Z" fill="none" stroke="#4f9ce8" stroke-linecap="round" stroke-linejoin="round"/>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 818 B

Binary file not shown.
-11
View File
@@ -1,11 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="24" height="24" viewBox="0 0 24 24">
<title>interaction.bolt</title>
<g id="Layer_1" data-name="Layer 1">
<path d="M7 3 L17 3 L17 7 L7 7 Z" fill="#2d4e70" stroke="#dde2ea" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M9.5 7 L14.5 7 L14.5 21 L9.5 21 Z" fill="#2d4e70" stroke="#dde2ea" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M9.5 11 L14.5 12.5 M9.5 14 L14.5 15.5 M9.5 17 L14.5 18.5" fill="none" stroke="#dde2ea" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M4 13 L4 6 M5.2 8.19 L4 6 L2.8 8.19" fill="none" stroke="#f0b44a" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M20 13 L20 20 M18.8 17.81 L20 20 L21.2 17.81" fill="none" stroke="#f0b44a" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 991 B

Binary file not shown.
-10
View File
@@ -1,10 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="24" height="24" viewBox="0 0 24 24">
<title>interaction.connector</title>
<g id="Layer_1" data-name="Layer 1">
<path d="M2.2 18 C2.2 17.006 3.006 16.2 4 16.2 C4.994 16.2 5.8 17.006 5.8 18 C5.8 18.994 4.994 19.8 4 19.8 C3.006 19.8 2.2 18.994 2.2 18 Z" fill="#dde2ea"/>
<path d="M18.2 6 C18.2 5.006 19.006 4.2 20 4.2 C20.994 4.2 21.8 5.006 21.8 6 C21.8 6.994 20.994 7.8 20 7.8 C19.006 7.8 18.2 6.994 18.2 6 Z" fill="#dde2ea"/>
<path d="M4 18 L10 14 M14 10 L20 6" fill="none" stroke="#dde2ea" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M9.2 12 C9.2 10.454 10.454 9.2 12 9.2 C13.546 9.2 14.8 10.454 14.8 12 C14.8 13.546 13.546 14.8 12 14.8 C10.454 14.8 9.2 13.546 9.2 12 Z" fill="none" stroke="#4f9ce8" stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round"/>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 965 B

Binary file not shown.
-10
View File
@@ -1,10 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="24" height="24" viewBox="0 0 24 24">
<title>interaction.contact.find</title>
<g id="Layer_1" data-name="Layer 1">
<path d="M3 8 C3 5.239 5.239 3 8 3 C10.761 3 13 5.239 13 8 C13 10.761 10.761 13 8 13 C5.239 13 3 10.761 3 8 Z" fill="#2d4e70" stroke="#dde2ea" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M3 13 L13 13 L13 21 L3 21 Z" fill="#2d4e70" stroke="#dde2ea" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M12 15 C12 12.791 13.791 11 16 11 C18.209 11 20 12.791 20 15 C20 17.209 18.209 19 16 19 C13.791 19 12 17.209 12 15 Z" fill="none" stroke="#4f9ce8" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M18.83 17.83 L21.83 20.83" fill="none" stroke="#4f9ce8" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 981 B

Binary file not shown.
@@ -1,11 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="24" height="24" viewBox="0 0 24 24">
<title>interaction.contact.general</title>
<g id="Layer_1" data-name="Layer 1">
<path d="M3 8 C3 5.239 5.239 3 8 3 C10.761 3 13 5.239 13 8 C13 10.761 10.761 13 8 13 C5.239 13 3 10.761 3 8 Z" fill="#2d4e70" stroke="#dde2ea" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M3 15 L21 15 L21 21 L3 21 Z" fill="#2d4e70" stroke="#dde2ea" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M14 3 L21 3 L21 10 L14 10 Z" fill="#2d4e70" stroke="#dde2ea" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M6.5 14.3 C7.476 14.607 8.524 14.607 9.5 14.3" fill="none" stroke="#4f9ce8" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M13 6 L13 10" fill="none" stroke="#4f9ce8" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.
@@ -1,9 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="24" height="24" viewBox="0 0 24 24">
<title>interaction.contact.pair</title>
<g id="Layer_1" data-name="Layer 1">
<path d="M6 9 C6 5.686 8.686 3 12 3 C15.314 3 18 5.686 18 9 C18 12.314 15.314 15 12 15 C8.686 15 6 12.314 6 9 Z" fill="#2d4e70" stroke="#dde2ea" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M3 15 L21 15 L21 21 L3 21 Z" fill="#2d4e70" stroke="#dde2ea" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M8 15 L16 15" fill="none" stroke="#4f9ce8" stroke-width="2.25" stroke-linecap="round" stroke-linejoin="round"/>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 745 B

Binary file not shown.
-11
View File
@@ -1,11 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="24" height="24" viewBox="0 0 24 24">
<title>interaction.fsi</title>
<g id="Layer_1" data-name="Layer 1">
<path 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" fill="none" stroke="#4f9ce8" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
<path 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" fill="none" stroke="#4f9ce8" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
<path 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" fill="none" stroke="#4f9ce8" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M17 21 C17 15 18 9 20 3" fill="none" stroke="#dde2ea" stroke-width="2.25" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M15 21 L21 21" fill="none" stroke="#dde2ea" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.
-9
View File
@@ -1,9 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="24" height="24" viewBox="0 0 24 24">
<title>interaction.mass</title>
<g id="Layer_1" data-name="Layer 1">
<path d="M5 21 L7 9 L17 9 L19 21 Z" fill="#2d4e70" stroke="#dde2ea" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M9 9 C9 7.343 10.343 6 12 6 C13.657 6 15 7.343 15 9" fill="none" stroke="#dde2ea" stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M10 15 C10 13.895 10.895 13 12 13 C13.105 13 14 13.895 14 15 C14 16.105 13.105 17 12 17 C10.895 17 10 16.105 10 15 Z" fill="#4f9ce8"/>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 705 B

Binary file not shown.
-11
View File
@@ -1,11 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="24" height="24" viewBox="0 0 24 24">
<title>interaction.rigid_wall</title>
<g id="Layer_1" data-name="Layer 1">
<path d="M18 3 L18 21" fill="none" stroke="#dde2ea" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M18 4 L21 6.5 M18 8 L21 10.5 M18 12 L21 14.5 M18 16 L21 18.5" fill="none" stroke="#dde2ea" stroke-width="1.25" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M3 12 C3 9.791 4.791 8 7 8 C9.209 8 11 9.791 11 12 C11 14.209 9.209 16 7 16 C4.791 16 3 14.209 3 12 Z" fill="#2d4e70" stroke="#dde2ea" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M11.5 12 L15.5 12 M13.22 13.25 L15.5 12 L13.22 10.75" fill="none" stroke="#f0b44a" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M2 9 L4 9 M1.5 15 L3.5 15" fill="none" stroke="#dde2ea" stroke-linecap="round" stroke-linejoin="round"/>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.
-9
View File
@@ -1,9 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="24" height="24" viewBox="0 0 24 24">
<title>interaction.spring</title>
<g id="Layer_1" data-name="Layer 1">
<path d="M1.2 12 C1.2 11.006 2.006 10.2 3 10.2 C3.994 10.2 4.8 11.006 4.8 12 C4.8 12.994 3.994 13.8 3 13.8 C2.006 13.8 1.2 12.994 1.2 12 Z" fill="#dde2ea"/>
<path d="M19.2 12 C19.2 11.006 20.006 10.2 21 10.2 C21.994 10.2 22.8 11.006 22.8 12 C22.8 12.994 21.994 13.8 21 13.8 C20.006 13.8 19.2 12.994 19.2 12 Z" fill="#dde2ea"/>
<path d="M3 12 L6 12 L7.5 7 L10.5 17 L13.5 7 L16.5 17 L18 12 L21 12" fill="none" stroke="#4f9ce8" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 760 B

Binary file not shown.
-11
View File
@@ -1,11 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="24" height="24" viewBox="0 0 24 24">
<title>interaction.tie</title>
<g id="Layer_1" data-name="Layer 1">
<path d="M3 4 L12 4 L12 20 L3 20 Z" fill="#2d4e70" stroke="#dde2ea" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M7.5 4 L7.5 20 M3 12 L12 12" fill="none" stroke="#dde2ea" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M12 4 L21 4 L21 20 L12 20 Z" fill="#2d4e70" stroke="#dde2ea" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M15 4 L15 20 M12 9.33 L21 9.33 M18 4 L18 20 M12 14.67 L21 14.67" fill="none" stroke="#dde2ea" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M12 4 L12 20" fill="none" stroke="#4f9ce8" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 932 B

Binary file not shown.
-12
View File
@@ -1,12 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="24" height="24" viewBox="0 0 24 24">
<title>mesh.delaunay.points</title>
<g id="Layer_1" data-name="Layer 1">
<path d="M5 17 L11 6 L19 15 Z M5 17 L19 15 L14 21" fill="none" stroke="#dde2ea" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M3.8 13.4 C3.8 9.092 7.292 5.6 11.6 5.6 C15.908 5.6 19.4 9.092 19.4 13.4 C19.4 17.708 15.908 21.2 11.6 21.2 C7.292 21.2 3.8 17.708 3.8 13.4 Z" fill="none" stroke="#4f9ce8" stroke-width="1.25" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M3.5 17 C3.5 16.172 4.172 15.5 5 15.5 C5.828 15.5 6.5 16.172 6.5 17 C6.5 17.828 5.828 18.5 5 18.5 C4.172 18.5 3.5 17.828 3.5 17 Z" fill="#dde2ea"/>
<path d="M9.5 6 C9.5 5.172 10.172 4.5 11 4.5 C11.828 4.5 12.5 5.172 12.5 6 C12.5 6.828 11.828 7.5 11 7.5 C10.172 7.5 9.5 6.828 9.5 6 Z" fill="#dde2ea"/>
<path d="M17.5 15 C17.5 14.172 18.172 13.5 19 13.5 C19.828 13.5 20.5 14.172 20.5 15 C20.5 15.828 19.828 16.5 19 16.5 C18.172 16.5 17.5 15.828 17.5 15 Z" fill="#dde2ea"/>
<path d="M12.5 21 C12.5 20.172 13.172 19.5 14 19.5 C14.828 19.5 15.5 20.172 15.5 21 C15.5 21.828 14.828 22.5 14 22.5 C13.172 22.5 12.5 21.828 12.5 21 Z" fill="#dde2ea"/>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.
-12
View File
@@ -1,12 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="24" height="24" viewBox="0 0 24 24">
<title>mesh.element.add</title>
<g id="Layer_1" data-name="Layer 1">
<path d="M3 7 L13 4 L15 15 L5 17 Z" fill="#2d4e70" stroke="#dde2ea" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M1.5 7 C1.5 6.172 2.172 5.5 3 5.5 C3.828 5.5 4.5 6.172 4.5 7 C4.5 7.828 3.828 8.5 3 8.5 C2.172 8.5 1.5 7.828 1.5 7 Z" fill="#dde2ea"/>
<path d="M11.5 4 C11.5 3.172 12.172 2.5 13 2.5 C13.828 2.5 14.5 3.172 14.5 4 C14.5 4.828 13.828 5.5 13 5.5 C12.172 5.5 11.5 4.828 11.5 4 Z" fill="#dde2ea"/>
<path d="M13.5 15 C13.5 14.172 14.172 13.5 15 13.5 C15.828 13.5 16.5 14.172 16.5 15 C16.5 15.828 15.828 16.5 15 16.5 C14.172 16.5 13.5 15.828 13.5 15 Z" fill="#dde2ea"/>
<path d="M3.5 17 C3.5 16.172 4.172 15.5 5 15.5 C5.828 15.5 6.5 16.172 6.5 17 C6.5 17.828 5.828 18.5 5 18.5 C4.172 18.5 3.5 17.828 3.5 17 Z" fill="#dde2ea"/>
<path d="M15.5 18.5 L21.5 18.5 M18.5 15.5 L18.5 21.5" fill="none" stroke="#4f9ce8" stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round"/>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.
-8
View File
@@ -1,8 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="24" height="24" viewBox="0 0 24 24">
<title>mesh.hex.decompose</title>
<g id="Layer_1" data-name="Layer 1">
<path d="M3 4 L11 4 L11 12 L21 12 L21 20 L3 20 Z" fill="#2d4e70" stroke="#dde2ea" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M11 12 L11 20 M3 12 L11 12" fill="none" stroke="#4f9ce8" stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" stroke-dasharray="2 2.5"/>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 573 B

Binary file not shown.
-9
View File
@@ -1,9 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="24" height="24" viewBox="0 0 24 24">
<title>mesh.hex.dominant</title>
<g id="Layer_1" data-name="Layer 1">
<path d="M3 3 L21 3 L21 21 L3 21 Z" fill="#2d4e70" stroke="#dde2ea" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M9 3 L9 21 M15 3 L15 21 M3 9 L21 9 M3 15 L21 15" fill="none" stroke="#dde2ea" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M15 15 L21 21 M9 21 L15 15" fill="none" stroke="#4f9ce8" stroke-width="1.25" stroke-linecap="round" stroke-linejoin="round"/>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 673 B

Binary file not shown.
-9
View File
@@ -1,9 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="24" height="24" viewBox="0 0 24 24">
<title>mesh.hex.generate</title>
<g id="Layer_1" data-name="Layer 1">
<path d="M3 3 L21 3 L21 21 L3 21 Z" fill="#2d4e70" stroke="#dde2ea" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M12 3 L12 21 M3 12 L21 12" fill="none" stroke="#dde2ea" stroke-width="1.25" stroke-linecap="round" stroke-linejoin="round"/>
<path 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" fill="none" stroke="#4f9ce8" stroke-linecap="round" stroke-linejoin="round"/>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 697 B

Binary file not shown.
-9
View File
@@ -1,9 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="24" height="24" viewBox="0 0 24 24">
<title>mesh.hex.mapped</title>
<g id="Layer_1" data-name="Layer 1">
<path d="M12 3 L20 7 L20 16 L12 20 L4 16 L4 7 Z" fill="#2d4e70" stroke="#dde2ea" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M4 7 L12 11 L20 7 M12 11 L12 20" fill="none" stroke="#dde2ea" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
<path 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" fill="none" stroke="#4f9ce8" stroke-linecap="round" stroke-linejoin="round"/>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 882 B

Binary file not shown.
-12
View File
@@ -1,12 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="24" height="24" viewBox="0 0 24 24">
<title>mesh.hex.polycube</title>
<g id="Layer_1" data-name="Layer 1">
<path d="M8 9 L13 11.5 L13 16.5 L8 19 L3 16.5 L3 11.5 Z" fill="#2d4e70" stroke="#dde2ea" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M3 11.5 L8 14 L13 11.5 M8 14 L8 19" fill="none" stroke="#dde2ea" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M16 9 L21 11.5 L21 16.5 L16 19 L11 16.5 L11 11.5 Z" fill="#2d4e70" stroke="#dde2ea" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M11 11.5 L16 14 L21 11.5 M16 14 L16 19" fill="none" stroke="#dde2ea" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M12 3 L17 5.5 L17 10.5 L12 13 L7 10.5 L7 5.5 Z" fill="#2d4e70" stroke="#4f9ce8" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M7 5.5 L12 8 L17 5.5 M12 8 L12 13" fill="none" stroke="#4f9ce8" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.
-10
View File
@@ -1,10 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="24" height="24" viewBox="0 0 24 24">
<title>mesh.hex.sweep</title>
<g id="Layer_1" data-name="Layer 1">
<path d="M3 8 L12 8 L12 17 L3 17 Z" fill="#2d4e70" stroke="#dde2ea" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M7.5 8 L7.5 17 M3 12.5 L12 12.5" fill="none" stroke="#dde2ea" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M3 8 L8 4 L21 4 L21 13 L12 17 M12 8 L21 4" fill="none" stroke="#dde2ea" stroke-width="1.25" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M14 13 L20 10 M18.17 12.63 L20 10 L16.8 9.88" fill="none" stroke="#4f9ce8" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 825 B

Binary file not shown.
-9
View File
@@ -1,9 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="24" height="24" viewBox="0 0 24 24">
<title>mesh.import.orphan</title>
<g id="Layer_1" data-name="Layer 1">
<path d="M3 10 L21 10 L21 21 L3 21 Z" fill="none" stroke="#dde2ea" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
<path 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" fill="none" stroke="#dde2ea" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M12 2 L12 8 M10.47 5.19 L12 8 L13.53 5.19" fill="none" stroke="#4f9ce8" stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round"/>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 857 B

Binary file not shown.
-9
View File
@@ -1,9 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="24" height="24" viewBox="0 0 24 24">
<title>mesh.layers</title>
<g id="Layer_1" data-name="Layer 1">
<path d="M3 20 L21 20" fill="none" stroke="#dde2ea" stroke-width="2.25" stroke-linecap="round" stroke-linejoin="round"/>
<path 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" fill="none" stroke="#4f9ce8" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M9 4 L9 20 M15 4 L15 20" fill="none" stroke="#dde2ea" stroke-linecap="round" stroke-linejoin="round"/>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 658 B

Loaded 100 of 664 files, more files were not shown because too many files have changed in this diff. Show more