diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 16eb0e1..44a50eb 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -1,5 +1,4 @@ -# Builds Fry3DX for Linux (a portable .tar.gz and an AppImage), Windows (.zip), macOS (.zip with one -# app for Apple silicon and Intel) and Android (.apk). +# Builds Fry3DX for Linux (a portable .tar.gz and an AppImage), Windows (.zip) and Android (.apk). # A tag v* (git tag v0.4.0 && git push --tags) also makes a GitHub release with them; # otherwise they're the run's artifacts (Actions tab). # Android signing: secrets FRY_KEYSTORE_B64 (the keystore, base64) and FRY_KEYSTORE_PASS. Keep @@ -32,11 +31,6 @@ jobs: run: | cmake --preset portable -DGLSLC=$ANDROID_NDK_HOME/shader-tools/linux-x86_64/glslc cmake --build build/portable - - name: Test - # The modelling core, the scripts, and the fuzz test (random shapes, edits, broken files). - run: | - cmake --build build/portable --target check - build/portable/bin/fuzz_test 2000 - name: Package run: APPIMAGETOOL=$PWD/appimagetool python3 tools/package.py linux appimage - uses: actions/upload-artifact@v4 @@ -59,31 +53,6 @@ jobs: - uses: actions/upload-artifact@v4 with: { name: windows, path: "dist/*" } - macos: - # Built twice (Apple silicon, and Intel cross-built on the same Mac), then joined into one app. - runs-on: macos-15 - steps: - - uses: actions/checkout@v4 - - name: Tools - run: | - brew install ninja shaderc - # MoltenVK (Vulkan on Metal), for both kinds of Mac, carried inside the app. - curl -sfL https://github.com/KhronosGroup/MoltenVK/releases/download/v1.3.0/MoltenVK-macos.tar | tar -x -C "$RUNNER_TEMP" - MVK=$(find "$RUNNER_TEMP" -name libMoltenVK.dylib -path '*macOS*' | head -1) - lipo -info "$MVK" - echo "MVK=$MVK" >> "$GITHUB_ENV" - - name: Build - run: | - for arch in arm64 x64; do - cmake --preset macos-$arch -DFRY_MOLTENVK="$MVK" - cmake --build build/macos-$arch - done - cmake --build build/macos-arm64 --target check - - name: Package - run: python3 tools/package.py macos - - uses: actions/upload-artifact@v4 - with: { name: macos, path: "dist/*" } - android: runs-on: ubuntu-24.04 steps: @@ -93,7 +62,7 @@ jobs: - name: SDK run: | yes | "$ANDROID_HOME/cmdline-tools/latest/bin/sdkmanager" "ndk;27.2.12479018" "build-tools;35.0.0" "platforms;android-35" > /dev/null - sudo apt-get install -y ninja-build glslc + sudo apt-get install -y ninja-build - name: Build env: ANDROID_NDK_ROOT: ${{ env.ANDROID_HOME }}/ndk/27.2.12479018 @@ -108,7 +77,7 @@ jobs: release: if: startsWith(github.ref, 'refs/tags/v') - needs: [linux, windows, macos, android] + needs: [linux, windows, android] runs-on: ubuntu-latest permissions: { contents: write } steps: diff --git a/.gitignore b/.gitignore index ca88d80..a1ee074 100644 --- a/.gitignore +++ b/.gitignore @@ -4,7 +4,3 @@ build/ __pycache__/ *.fry~ dist/ - -# crash dumps and stray test programs -core.[0-9]* -a.out diff --git a/CMakeLists.txt b/CMakeLists.txt index e643c5b..6c4a0e8 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,6 +1,5 @@ cmake_minimum_required(VERSION 3.25) -include(cmake/Project.cmake) # project.json: the version, links, creators -project(Fry3DX VERSION ${FRY_VERSION} LANGUAGES C CXX) +project(Fry3DX VERSION 0.5.0 LANGUAGES C CXX) set(CMAKE_CXX_SCAN_FOR_MODULES OFF) # (no C++ modules; the scan can pick up a different clang than the NDK's) if(UNIX AND NOT APPLE) add_link_options(-rdynamic) # function names in crash reports @@ -31,32 +30,21 @@ set(CMAKE_CXX_EXTENSIONS OFF) set(CMAKE_EXPORT_COMPILE_COMMANDS ON) set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin) -# Where the content goes: next to the program; on a Mac, inside the app (Fry3DX.app/Contents/ -# Resources, where SDL_GetBasePath points). -if(APPLE) - set(FRY_CONTENT_DIR ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/Fry3DX.app/Contents/Resources) -else() - set(FRY_CONTENT_DIR ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}) -endif() - -# Libraries are linked in, not .so files beside the program (SDL says for itself). Set before -# any of them, so one that has its own BUILD_SHARED_LIBS option (Manifold) can't turn it on. -set(BUILD_SHARED_LIBS OFF CACHE BOOL "Build the libraries as shared ones" FORCE) include(cmake/Dependencies.cmake) include(cmake/Shaders.cmake) add_subdirectory(engine) add_subdirectory(src) -# Content next to the program: engine/ (the engine's: fonts, sky, config); Fry3DX/ (the app's own: scripts, branding). +# Content next to the program: bin/engine/ (the engine's: fonts, sky, config); bin/Fry3DX/ (the app's own, none yet). add_custom_target(content ALL - COMMAND ${CMAKE_COMMAND} -E copy_directory ${CMAKE_SOURCE_DIR}/content ${FRY_CONTENT_DIR} - COMMAND ${CMAKE_COMMAND} -E make_directory ${FRY_CONTENT_DIR}/engine/fonts ${FRY_CONTENT_DIR}/Fry3DX + COMMAND ${CMAKE_COMMAND} -E copy_directory ${CMAKE_SOURCE_DIR}/content ${CMAKE_RUNTIME_OUTPUT_DIRECTORY} + COMMAND ${CMAKE_COMMAND} -E make_directory ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/engine/fonts ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/Fry3DX COMMAND ${CMAKE_COMMAND} -E copy_if_different ${dejavu_SOURCE_DIR}/ttf/DejaVuSans.ttf ${dejavu_SOURCE_DIR}/ttf/DejaVuSans-Bold.ttf - ${dejavu_SOURCE_DIR}/LICENSE ${FRY_CONTENT_DIR}/engine/fonts/ + ${dejavu_SOURCE_DIR}/LICENSE ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/engine/fonts/ COMMENT "Copying content" VERBATIM) enable_testing() add_subdirectory(tests EXCLUDE_FROM_ALL) add_custom_target(check COMMAND ${CMAKE_CTEST_COMMAND} --test-dir ${CMAKE_BINARY_DIR} --output-on-failure - DEPENDS mesh_test script_test fuzz_test USES_TERMINAL VERBATIM) + DEPENDS mesh_test USES_TERMINAL VERBATIM) diff --git a/CMakePresets.json b/CMakePresets.json index 0be504f..54c2b77 100644 --- a/CMakePresets.json +++ b/CMakePresets.json @@ -7,10 +7,6 @@ { "name": "portable", "inherits": "base", "cacheVariables": { "CMAKE_BUILD_TYPE": "Release", "FRY_PORTABLE": "ON" } }, { "name": "windows", "inherits": "base", "toolchainFile": "${sourceDir}/cmake/toolchains/windows-msvc.cmake", "cacheVariables": { "CMAKE_BUILD_TYPE": "Release", "CMAKE_MSVC_RUNTIME_LIBRARY": "MultiThreaded" } }, - { "name": "macos-arm64", "inherits": "base", - "cacheVariables": { "CMAKE_BUILD_TYPE": "Release", "FRY_PORTABLE": "ON", "CMAKE_OSX_ARCHITECTURES": "arm64", "CMAKE_OSX_DEPLOYMENT_TARGET": "13.3" } }, - { "name": "macos-x64", "inherits": "base", - "cacheVariables": { "CMAKE_BUILD_TYPE": "Release", "FRY_PORTABLE": "ON", "CMAKE_OSX_ARCHITECTURES": "x86_64", "CMAKE_OSX_DEPLOYMENT_TARGET": "13.3" } }, { "name": "android", "inherits": "base", "toolchainFile": "$env{ANDROID_NDK_ROOT}/build/cmake/android.toolchain.cmake", "cacheVariables": { "CMAKE_BUILD_TYPE": "Release", "ANDROID_ABI": "arm64-v8a", "ANDROID_PLATFORM": "android-28", "ANDROID_STL": "c++_static" } } ], @@ -19,8 +15,6 @@ { "name": "release", "configurePreset": "release" }, { "name": "portable", "configurePreset": "portable" }, { "name": "windows", "configurePreset": "windows" }, - { "name": "macos-arm64", "configurePreset": "macos-arm64" }, - { "name": "macos-x64", "configurePreset": "macos-x64" }, { "name": "android", "configurePreset": "android" } ] } diff --git a/README.md b/README.md index 23789d7..bd88509 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@

Fry3DX

Frying 3D Extreme — a 3D modeller that does what you'd expect.
-Pick a tool, click, drag. On Windows, macOS, Linux and your phone.

+Pick a tool, click, drag. On Windows, Linux and your phone.

Website · Download · @@ -28,23 +28,15 @@ From [Releases](https://github.com/Nexoniarz/Fry3DX/releases): | | | |---|---| | **Windows** (10 and 11, x64) | `Fry3DX-…-windows-x64.zip`: unpack, run `fry3dx.exe` | -| **macOS** (13.3 and newer, Apple silicon and Intel) | `Fry3DX-…-macos.zip`: unzip, open `Fry3DX.app` (the first time: right-click it, Open) | | **Linux** (any distro from 2022 on, x64) | `Fry3DX-…-linux-x64.AppImage`: make it executable, run it. Or the `.tar.gz` | | **Android** (8.0 and newer, 64-bit, Vulkan) | `Fry3DX-…-android-arm64.apk`: open it on the phone to install | -Needs a graphics card (or phone) with Vulkan; on a PC, OpenGL 4.6 works too. On a Mac, Vulkan -comes inside the app (MoltenVK, on Metal), and OpenGL 4.1 is the fallback. +Needs a graphics card (or phone) with Vulkan; on a PC, OpenGL 4.6 works too. ## What it does Five tabs along the top: **Model**, **Paint**, **Layout**, **Render**, **Print** (Ctrl+1 to 5). -**Finding things** -- **Any command by name**: F3 or Ctrl+Space, type a few letters. **Round the mouse**: hold Space - for the tools, Shift+Space for the views. Give any command **your own key** (Help > Keys and - mouse). **Undo history** (Edit > Undo history): go back to any step. **Workspaces**: the panels as - you had them, kept under a name. - **Making shapes** - **Shapes that stay editable**: cube, rounded cube, plane, circle, cylinder, tube, cone, pyramid, sphere, capsule, torus, wedge, stairs, arch, and starter models (table, chair, shelf, barrel, @@ -52,126 +44,58 @@ Five tabs along the top: **Model**, **Paint**, **Layout**, **Render**, **Print** - **Draw shape** (D): click an outline on the ground, on a side view's plane, or straight on any face of another object: a new part standing on it, added to it, or cut into it. - **Move, turn, scale** (W, E, R): the arrows turn with the object. Scale keeps the other side - where it is; Shift scales both sides at once. Ctrl snaps: to steps, or to points and the middles - of edges and faces. -- **Exact sizes**: type a number while dragging (move, turn, scale, extrude, inset, round edges) - and Enter for exactly that. Dimensions in Properties; measure anything (View > Measure). Drawing - a shape shows each line's length: type one for exactly that, Shift holds it to 15° steps. -- **3D text** from any font (Add > Text). **Spin**: an outline turned round an axis into a vase or - a wheel, or rising into a screw thread. **Import** STL, OBJ, 3MF, glTF and GLB (Ctrl+Shift+O). + where it is; Shift scales both sides at once. Ctrl snaps. - **Round, smooth, mirror** any object, changeable any time, baked in when you like. -- **Materials**: gold, chrome, steel, wood, ceramic, rubber and more, or how metal and rough it - is; shown in the view (Solid too), exported with it. **Your own**: "Save its look as a - material" in the picker keeps one for every file. **Editing the shape** (Tab, or double-click) - Points, edges, faces (1, 2, 3). Extrude (X), inset (I), round edges (B), loop cut (C), knife (K), - cut in four, smooth, merge (M), make a face, flip, separate (P), smooth points, push out / - pull in along the surface (Alt+S), **bridge** two faces with a tunnel, **edge slide** (Alt+G). -- **Crease** (Shift+E): picked edges stay sharp when the shape is smoothed. **Mirror editing**: - both sides change together. **Select similar** (Shift+G), loops and rings. -- **Soft selection** (Shift+O): points near what you move follow it, less the further they are; - the wheel while dragging sets how far (Blender's proportional editing, Maya's soft select). + cut in four, smooth, merge (M), make a face, flip, separate (P). - **Hole** (O): round (M2–M8 screw sizes ready), rectangle, triangle or hexagon (M2–M8 nut sizes, with room for prints); all the way through, a pocket, or only its outline as a new face. - **Selecting**: click, box, brush or lasso. Shift+click a whole loop, Shift+Ctrl+click an edge's ring, Ctrl+click adds or takes one. **Whole objects** (the Object menu) -- **Add together, take one out of another, keep only where they overlap**: exact - ([Manifold](https://github.com/elalish/manifold)) and always closed, so always printable - (Ctrl+Shift+ and Ctrl+Shift−). -- **Cut out, editable**: the cutters stay objects. Move one, turn it, change its shape, and the - hole follows; they go with what they cut. Apply makes it for good. -- **Copies** in a row, round a circle, or **along a path** (turning as it turns); **make it thick** (a surface gets a back, a solid goes +- **Add together, take one out of another, keep only where they overlap**: always closed, so + always printable (Ctrl+Shift+ and Ctrl+Shift−). +- **Copies** in a row or round a circle; **make it thick** (a surface gets a back, a solid goes hollow); join objects; join flat faces. - **Layers** with folders inside folders, drag and drop, hide and lock whole groups, and a button - on every row that brings the camera to it. **Show only the selected** (/ or Shift+H; again: - everything). - -**Sculpting** (the Paint tab's other side: Tab) -- Raise, puff out, smooth, flatten, pinch and grab the surface (1 to 6); Ctrl goes the other way, - Shift smooths, X does the same on both sides. A shape with too few points is made finer first, - keeping its shape. + on every row that brings the camera to it. **Painting** -- Paint on the model or on its flat picture, on **both sides** at once, or only inside a - **stencil** you drag round an area. **Paste any picture** (Ctrl+V): it goes on like a +- Paint on the model or on its flat picture. **Paste any picture** (Ctrl+V): it goes on like a sticker that bends over edges and corners; Enter locks it as a layer, clicking it in the Picture panel unlocks it again. - **Layout tab**: move, turn and size the flat frames of the surface yourself; the paint follows. **Seeing it** -- **Getting round**, as in games, Unreal or Unity: right drag turns the camera where it stands, - and while it's held W A S D move where you look (Q / E: down, up). The **arrow keys** move any - time (Page Up / Down: down and up), the **wheel** goes forward and back, **Shift + wheel** sets - how fast it all goes. Alt + right drag orbits round what's picked; middle drag pans. Rather - orbit, as in Blender? **Shift+C** (or View > Camera) switches: right drag turns round what you - look at and the wheel zooms. - **Solid** view for modelling, **Rendered** with a real sky, sun and soft shadows (Z). Wireframe (Shift+Z), X-ray (Alt+Z). The Render tab: the sun, sky, ground, brightness, shadows, glow; F12 saves a picture of just the view. -- **Reference pictures** for the front, side and top views, see-through, shown only in their own - view if you like. **3D printing** (the Print tab) - Your printer's plate in the view (Prusa, Bambu, Creality, Elegoo, Anycubic, or your own), - sizes in millimetres, checks for holes and flipped faces with **one repair button**, overhangs - in red, **walls too thin** in yellow, weight and filament, measuring, lay flat on a face, save - 3MF or STL. -- **Size it**: by percent, ×½, ×2, inches or centimetres to millimetres, or as big as fits the - plate. **Slice preview**: one layer as the printer makes it, at any layer height. - -**Scripts** (the Script panel, F5) -- Lua with a `fry` library: add shapes and change their settings, combine them, move points by a - formula, sculpt, set the materials and the sun, make your own materials (`fry.material{}`). - One Ctrl+Z takes back all a script did; an error takes it back itself. Examples in - Script > Examples; the **?** button lists every function. It can't reach anything outside the - scene (no files, no programs). -- **Kept in the file**: the Script panel lists the `.fry`'s scripts (new, examples, open, - duplicate, rename, remove); they're saved with the model. - -**Plug-ins** (Script > Plug-ins) -- Scripts that stay loaded: put a `.lua` in the plug-ins folder and it can add **commands to the - Add, Object or Script menu** (`fry.command{name, menu, settings, run}`; the settings are asked - for in a small form first) and **materials** to the picker. Turn each on or off in the Plug-ins - window, look for one, or make your own copy of one to change. **Mouse tools** too - (`fry.tool{name, click}`): listed in the Toolbox, a click in the view calls it with the spot. - Four come with it: stairs (straight and spiral), scatter copies, stamp (a mouse tool), and more - materials. - -```lua -fry.plugin{name = "Shelves", about = "A bookcase from the Add menu"} -fry.command{name = "Bookcase", menu = "add", settings = {{"shelves", 5}, {"width", 0.8}}, - run = function(s) - for i = 0, s.shelves - 1 do - fry.add("cube", {width = s.width, depth = 0.3, height = 0.02}).position = {0, 0, i * 0.35} - end - end} -``` - -**The look**: light or dark, or following the desktop (View > Appearance), in -[Niveus](https://github.com/Nexoniarz/niveus): keys that look like keys, fields set into the panel. + sizes in millimetres, checks for holes and flipped faces with buttons that fix them, overhangs + in red, weight and filament, measuring, lay flat on a face, save 3MF or STL. **Files** - `.fry`: Fry3DX's own file, everything in one, packed small. **Autosave** in the background, - offered back after a crash; Save / Don't save / Cancel when closing. Drop a `.fry`, a script or - a picture on the window to open it. + offered back after a crash; Save / Don't save / Cancel when closing. - **Export**: GLB, glTF, FBX (Blender, Unity, Unreal, Maya), OBJ, 3MF, STL, PLY. **On a phone or tablet**: everything bigger, the side panels when you want them, a bar of big buttons (undo, redo, Shift and Ctrl that stay down, edit the shape, delete, frame). One finger turns the view (or drags the arrows), two fingers move it and pinch to zoom, holding a finger -still is a right-click. Files open and save through the phone's own file picker. It stays -sideways, and going to another app and back keeps your work. +still is a right-click. Files open and save through the phone's own file picker. F1 in the app lists every key. ## Build it yourself Everything it uses is downloaded while building; you need CMake 3.25+, Ninja, a C++20 compiler -(GCC 13+, Clang 17+, Xcode 15+ or clang-cl) and glslc (from shaderc or the Vulkan SDK). On NixOS, -`shell.nix` has it all; on a Mac, `brew install cmake ninja shaderc molten-vk`. +(GCC 13+, Clang 17+ or clang-cl) and glslc (from shaderc or the Vulkan SDK). On NixOS, +`shell.nix` has it all. ```sh git clone https://github.com/Nexoniarz/Fry3DX.git && cd Fry3DX @@ -185,10 +109,9 @@ cmake --build build/debug --target check # the tests (after | `debug`, `release` | for working on it | | `portable` | a Linux build to hand out: SDL and the C++ library inside the program | | `windows` | Windows, cross-built from Linux with clang-cl ([how](cmake/toolchains/windows-msvc.cmake)) | -| `macos-arm64`, `macos-x64` | `Fry3DX.app` for Apple silicon / Intel (both build on either Mac); `tools/package.py macos` joins them into one app | | `android` | the Android library; `android/build_apk.py` makes the APK ([how](android/build_apk.py)) | -`tools/package.py` packs builds into the downloads (zip, tar.gz, AppImage, the Mac app). Pushing a tag +`tools/package.py` packs builds into the downloads (zip, tar.gz, AppImage). Pushing a tag `v*` makes GitHub build all of them and put them in a release (`.github/workflows/build.yml`). ## What's where @@ -199,22 +122,19 @@ cmake --build build/debug --target check # the tests (after | `src/mesh.*`, `tools.cpp`, `cut.cpp` | polygon meshes and the edits on them (tested without a window) | | `src/boolean.cpp`, `modify.cpp` | combining shapes, thickness, joining flat faces | | `src/shapes.*` | the shape library and starter models | -| `src/scene.*`, `package.cpp` | objects, folders, materials, the `.fry` file | -| `src/sculpt.*` | the sculpting brushes | -| `src/script.*` | scripts: Lua and the `fry` library; examples in `content/Fry3DX/scripts/` | +| `src/scene.*`, `package.cpp` | objects, folders, the `.fry` file | | `src/export.cpp`, `print.cpp` | GLB/glTF/FBX/OBJ/3MF/STL/PLY, checks for printing | | `src/uv.cpp`, `sticker.cpp`, `image.cpp` | flat layouts, stickers, pictures | | `engine/` | window, Vulkan/OpenGL renderer, UI, files | | `android/`, `tools/`, `.github/` | builds and packages | | `docs/` | the website (GitHub Pages); its words are all in `docs/content.js` | -| `tests/` | `mesh_test`, `script_test` (every example script runs) | +| `tests/` | `mesh_test` | ## Coming -Animation; textures for materials (wood grain, brushed metal); dynamic detail while sculpting. +Sculpting, materials shown in the view, scripting; animation later. ## Licence [Apache License 2.0](LICENSE). Copyright 2026 Nexoniarz. -Sky pictures: Poly Haven, CC0. Fonts: Instrument Sans and JetBrains Mono (SIL Open Font -License), DejaVu (its own free licence). Lua: MIT. MoltenVK (in the Mac app): Apache 2.0. +Sky pictures: Poly Haven, CC0. DejaVu fonts: their own free licence (`engine/fonts/LICENSE` in builds). diff --git a/android/build_apk.py b/android/build_apk.py index 288d694..59ebb07 100644 --- a/android/build_apk.py +++ b/android/build_apk.py @@ -11,7 +11,6 @@ Signed with ~/.local/share/Nexoniarz/Fry3DX-signing/release.keystore (made the f or the key in $FRY_KEYSTORE / $FRY_KEYSTORE_PASS. Keep it safe and keep using it: Android only updates an app signed with the key it was installed with. """ -import json import os import secrets import shutil @@ -31,8 +30,11 @@ def run(*cmd, **kw): def app_version(): - with open(os.path.join(ROOT, "project.json")) as f: # (the version and the rest live there) - return json.load(f)["version"] + with open(os.path.join(ROOT, "CMakeLists.txt")) as f: + for line in f: + if line.startswith("project(Fry3DX VERSION "): + return line.split()[2] + return "0" def main(): @@ -42,12 +44,8 @@ def main(): llvm = os.path.join(ndk, "toolchains", "llvm", "prebuilt", "linux-x86_64", "bin") if not os.path.isdir(BUILD): - # A current glslc: $GLSLC, or the one on PATH. (Not the NDK's: its 2022 shaderc makes compute - # shaders some phone drivers can't build, e.g. the Galaxy S22's.) - glslc = os.environ.get("GLSLC") or shutil.which("glslc") - if not glslc: - sys.exit("No glslc: install shaderc (or the Vulkan SDK), or set GLSLC") - run("cmake", "--preset", "android", f"-DGLSLC={glslc}", cwd=ROOT) + glslc = os.environ.get("GLSLC") or os.path.join(ndk, "shader-tools", "linux-x86_64", "glslc") # (the NDK's own, if none's given) + run("cmake", "--preset", "android", *([f"-DGLSLC={glslc}"] if os.path.exists(glslc) else []), cwd=ROOT) run("cmake", "--build", "--preset", "android", cwd=ROOT) stage = os.path.join(BUILD, "apk") diff --git a/android/java/io/github/nexoniarz/fry3dx/FryActivity.java b/android/java/io/github/nexoniarz/fry3dx/FryActivity.java index 2f86144..f1b4fc4 100644 --- a/android/java/io/github/nexoniarz/fry3dx/FryActivity.java +++ b/android/java/io/github/nexoniarz/fry3dx/FryActivity.java @@ -1,9 +1,5 @@ package io.github.nexoniarz.fry3dx; -import android.os.Build; -import android.view.WindowInsets; -import android.view.WindowInsetsController; - import org.libsdl.app.SDLActivity; // Fry3DX's activity: SDL's, loading SDL and the app (libmain.so, whose SDL_main it runs). @@ -12,40 +8,4 @@ public class FryActivity extends SDLActivity { protected String[] getLibraries() { return new String[] {"SDL3", "main"}; } - - // The whole screen: the status and navigation bars hidden (a swipe from the edge shows them - // for a moment). SDL's own way (the old system-UI flags) doesn't do it on new Androids. - @Override - protected void onResume() { - super.onResume(); - hideBars(); - } - - @Override - public void onWindowFocusChanged(boolean hasFocus) { - super.onWindowFocusChanged(hasFocus); - if (hasFocus) hideBars(); - } - - // SDL sets the bars again (its old way) whenever the window changes: hidden again after it. - @Override - protected boolean sendCommand(int command, Object data) { - final boolean sent = super.sendCommand(command, data); - if (command == COMMAND_CHANGE_WINDOW_STYLE) getWindow().getDecorView().post(new Runnable() { // (no lambdas: built against android.jar alone) - @Override - public void run() { - hideBars(); - } - }); - return sent; - } - - private void hideBars() { - if (Build.VERSION.SDK_INT < 30) return; - getWindow().setDecorFitsSystemWindows(false); - WindowInsetsController c = getWindow().getInsetsController(); - if (c == null) return; - c.hide(WindowInsets.Type.systemBars()); - c.setSystemBarsBehavior(WindowInsetsController.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE); - } } diff --git a/android/res/mipmap-hdpi/ic_launcher.png b/android/res/mipmap-hdpi/ic_launcher.png index 532599a..33866dc 100644 Binary files a/android/res/mipmap-hdpi/ic_launcher.png and b/android/res/mipmap-hdpi/ic_launcher.png differ diff --git a/android/res/mipmap-mdpi/ic_launcher.png b/android/res/mipmap-mdpi/ic_launcher.png index cbbdedb..5dd2044 100644 Binary files a/android/res/mipmap-mdpi/ic_launcher.png and b/android/res/mipmap-mdpi/ic_launcher.png differ diff --git a/android/res/mipmap-xhdpi/ic_launcher.png b/android/res/mipmap-xhdpi/ic_launcher.png index a346e1e..4526bc4 100644 Binary files a/android/res/mipmap-xhdpi/ic_launcher.png and b/android/res/mipmap-xhdpi/ic_launcher.png differ diff --git a/android/res/mipmap-xxhdpi/ic_launcher.png b/android/res/mipmap-xxhdpi/ic_launcher.png index 8700b3e..401a2c3 100644 Binary files a/android/res/mipmap-xxhdpi/ic_launcher.png and b/android/res/mipmap-xxhdpi/ic_launcher.png differ diff --git a/android/res/mipmap-xxxhdpi/ic_launcher.png b/android/res/mipmap-xxxhdpi/ic_launcher.png index 4499799..09c7fc1 100644 Binary files a/android/res/mipmap-xxxhdpi/ic_launcher.png and b/android/res/mipmap-xxxhdpi/ic_launcher.png differ diff --git a/branding/fry3dx.icns b/branding/fry3dx.icns deleted file mode 100644 index 97056f3..0000000 Binary files a/branding/fry3dx.icns and /dev/null differ diff --git a/branding/fry3dx.ico b/branding/fry3dx.ico index 447b6be..09318c3 100644 Binary files a/branding/fry3dx.ico and b/branding/fry3dx.ico differ diff --git a/branding/icon.png b/branding/icon.png index e194f74..bb30490 100644 Binary files a/branding/icon.png and b/branding/icon.png differ diff --git a/branding/logo.png b/branding/logo.png index 470db04..76db8f9 100644 Binary files a/branding/logo.png and b/branding/logo.png differ diff --git a/branding/logo.svg b/branding/logo.svg index 774bfcd..2ca9d95 100644 --- a/branding/logo.svg +++ b/branding/logo.svg @@ -1,144 +1,34 @@ - - - - + + - - - + + - - - - - - - - - - - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + - - - - - - - + + + + + + + + + - - - - - - - - - - - - - - - - - - - - + + + + - - - - - - - - - - - - - - - - - - - diff --git a/cmake/Dependencies.cmake b/cmake/Dependencies.cmake index 7ffb1d5..be1f667 100644 --- a/cmake/Dependencies.cmake +++ b/cmake/Dependencies.cmake @@ -37,10 +37,6 @@ FetchContent_Declare(opusfile GIT_REPOSITORY https://github.com/xiph/opusfile.gi FetchContent_Declare(dejavu URL https://github.com/dejavu-fonts/dejavu-fonts/releases/download/version_2_37/dejavu-fonts-ttf-2.37.zip URL_HASH SHA256=7576310b219e04159d35ff61dd4a4ec4cdba4f35c00e002a136f00e96a908b0a DOWNLOAD_EXTRACT_TIMESTAMP ON SOURCE_SUBDIR no-cmake) -# Lua: the scripting language (Script panel, scripts/*.lua). Small, plain C, nothing else needed. -FetchContent_Declare(lua URL https://www.lua.org/ftp/lua-5.4.7.tar.gz - URL_HASH SHA256=9fbf5e28ef86c69858f6d3d34eccc32e911c1a28b4120ff3e84aaa70cfbf1e30 - DOWNLOAD_EXTRACT_TIMESTAMP ON SOURCE_SUBDIR no-cmake) # KEEL_YAPF_DIR=/path/to/YAPF uses a local checkout instead. FetchContent_Declare(yapf GIT_REPOSITORY https://github.com/Nexoniarz/yapf.git GIT_TAG 06a4e7db9e7e6d90132473e5606f0e6f5b1d6001 SYSTEM) # YAPF 2 (+ yapf_tex_to_rgba8: any surface as RGBA8) @@ -83,26 +79,13 @@ target_link_libraries(volk PUBLIC Vulkan::Headers) # Dear ImGui and YAPF have no CMake of their own; build them here. FetchContent_MakeAvailable(imgui yapf) -# One hook in ImGui: RenderFrame (the frame behind buttons, fields, checkboxes, combos) asks the -# engine's UI first, which draws Niveus's keys and wells instead (engine/ui/ui.cpp). -file(READ ${imgui_SOURCE_DIR}/imgui.cpp _imgui_cpp) -if(NOT _imgui_cpp MATCHES "GImRenderFrameHook") - set(_from "void ImGui::RenderFrame(ImVec2 p_min, ImVec2 p_max, ImU32 fill_col, bool borders, float rounding)\n{\n ImGuiContext& g = *GImGui;\n ImGuiWindow* window = g.CurrentWindow;\n") - string(FIND "${_imgui_cpp}" "${_from}" _at) - if(_at EQUAL -1) - message(FATAL_ERROR "ImGui's RenderFrame has changed: update the hook in cmake/Dependencies.cmake") - endif() - string(REPLACE "${_from}" "bool (*GImRenderFrameHook)(ImDrawList*, ImVec2, ImVec2, ImU32, bool, float) = nullptr;\n${_from} if (GImRenderFrameHook && GImRenderFrameHook(window->DrawList, p_min, p_max, fill_col, borders, rounding))\n return;\n" _imgui_cpp "${_imgui_cpp}") - file(WRITE ${imgui_SOURCE_DIR}/imgui.cpp "${_imgui_cpp}") -endif() add_library(imgui STATIC ${imgui_SOURCE_DIR}/imgui.cpp ${imgui_SOURCE_DIR}/imgui_draw.cpp ${imgui_SOURCE_DIR}/imgui_tables.cpp ${imgui_SOURCE_DIR}/imgui_widgets.cpp ${imgui_SOURCE_DIR}/imgui_demo.cpp ${imgui_SOURCE_DIR}/backends/imgui_impl_sdl3.cpp ${imgui_SOURCE_DIR}/backends/imgui_impl_vulkan.cpp - ${imgui_SOURCE_DIR}/backends/imgui_impl_opengl3.cpp - ${imgui_SOURCE_DIR}/backends/imgui_impl_sdlrenderer3.cpp) # (the crash screen) + ${imgui_SOURCE_DIR}/backends/imgui_impl_opengl3.cpp) target_include_directories(imgui SYSTEM PUBLIC ${imgui_SOURCE_DIR} ${imgui_SOURCE_DIR}/backends) target_compile_definitions(imgui PUBLIC IMGUI_IMPL_VULKAN_USE_VOLK) target_link_libraries(imgui PUBLIC volk SDL3::SDL3) @@ -118,24 +101,6 @@ if(NOT MSVC) target_compile_options(yapf PRIVATE -O2) # its codecs and the BC7 encoder, even in debug builds endif() -# Lua's core and the libraries scripts get (no io, os or loading modules: a script changes the -# scene, not the computer). -FetchContent_MakeAvailable(lua) -set(_lua_src lapi lcode lctype ldebug ldo ldump lfunc lgc llex lmem lobject lopcodes lparser lstate lstring ltable ltm lundump lvm lzio - lauxlib lbaselib lcorolib ldblib lmathlib lstrlib ltablib lutf8lib) -list(TRANSFORM _lua_src PREPEND ${lua_SOURCE_DIR}/src/) -list(TRANSFORM _lua_src APPEND .c) -# As C++: its errors are then exceptions, which unwind through the bindings' C++ properly. -set_source_files_properties(${_lua_src} PROPERTIES LANGUAGE CXX) -add_library(lua STATIC ${_lua_src}) -if(NOT MSVC) - target_compile_options(lua PRIVATE -w) -endif() -target_include_directories(lua SYSTEM PUBLIC ${lua_SOURCE_DIR}/src) -if(NOT WIN32) - target_link_libraries(lua PRIVATE m) -endif() - # Audio: miniaudio for output; Ogg Opus decoding (opusfile). set(OPUS_BUILD_TESTING OFF) set(OPUS_BUILD_PROGRAMS OFF) diff --git a/cmake/Info.plist.in b/cmake/Info.plist.in deleted file mode 100644 index 6c353c7..0000000 --- a/cmake/Info.plist.in +++ /dev/null @@ -1,42 +0,0 @@ - - - - - - CFBundleNameFry3DX - CFBundleDisplayNameFry3DX - CFBundleExecutableFry3DX - CFBundleIdentifierio.github.nexoniarz.fry3dx - CFBundleIconFilefry3dx - CFBundlePackageTypeAPPL - CFBundleInfoDictionaryVersion6.0 - CFBundleShortVersionString${PROJECT_VERSION} - CFBundleVersion${PROJECT_VERSION} - NSHumanReadableCopyrightCopyright 2026 Nexoniarz. Apache License 2.0. - LSMinimumSystemVersion${CMAKE_OSX_DEPLOYMENT_TARGET} - LSApplicationCategoryTypepublic.app-category.graphics-design - NSHighResolutionCapable - NSSupportsAutomaticGraphicsSwitching - - UTExportedTypeDeclarations - - - UTTypeIdentifierio.github.nexoniarz.fry3dx.fry - UTTypeDescriptionFry3DX model - UTTypeConformsTopublic.data - UTTypeIconFilefry3dx - UTTypeTagSpecification - public.filename-extensionfry - - - CFBundleDocumentTypes - - - CFBundleTypeNameFry3DX model - CFBundleTypeRoleEditor - LSHandlerRankOwner - LSItemContentTypesio.github.nexoniarz.fry3dx.fry - - - - diff --git a/cmake/Project.cmake b/cmake/Project.cmake deleted file mode 100644 index 33d93a9..0000000 --- a/cmake/Project.cmake +++ /dev/null @@ -1,81 +0,0 @@ -# project.json, read before project(): FRY_VERSION and the rest as FRY_; fry_project_header() -# writes them as C++ constants (fry_project.h) and Windows' file details (fry3dx.rc). -set(FRY_PROJECT_JSON ${CMAKE_CURRENT_LIST_DIR}/../project.json) -set_property(DIRECTORY APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS ${FRY_PROJECT_JSON}) -file(READ ${FRY_PROJECT_JSON} FRY_JSON) -foreach(key name long version tagline description website repo issues releases license copyright company look) - string(TOUPPER ${key} upper) - string(JSON FRY_${upper} GET "${FRY_JSON}" ${key}) -endforeach() - -# out: the header's path; rc: Windows' file details (the version as 0,8,1,0 too). -function(fry_project_header out rc) - set(h "// Made by CMake from project.json: change that, not this.\n#pragma once\n#include \n\nnamespace fry::project {\n") - foreach(key name long version tagline description website repo issues releases license copyright company look) - string(TOUPPER ${key} upper) - set(ident ${key}) - if(key STREQUAL "long") - set(ident long_) # (a C++ word) - endif() - string(APPEND h "inline constexpr const char* ${ident} = R\"fry(${FRY_${upper}})fry\";\n") - endforeach() - string(APPEND h "\nstruct Creator {\n const char* name;\n const char* role;\n const char* url;\n};\ninline constexpr Creator kCreators[] = {\n") - string(JSON n LENGTH "${FRY_JSON}" creators) - math(EXPR last "${n} - 1") - foreach(i RANGE ${last}) - string(JSON who GET "${FRY_JSON}" creators ${i} name) - string(JSON role ERROR_VARIABLE none GET "${FRY_JSON}" creators ${i} role) - string(JSON url ERROR_VARIABLE none GET "${FRY_JSON}" creators ${i} url) - if(role MATCHES "NOTFOUND$") - set(role "") - endif() - if(url MATCHES "NOTFOUND$") - set(url "") - endif() - string(APPEND h " {R\"fry(${who})fry\", R\"fry(${role})fry\", R\"fry(${url})fry\"},\n") - endforeach() - string(APPEND h "};\ninline constexpr std::span creators{kCreators};\n\n// What it's built on (for the About box).\ninline constexpr const char* builtWith = R\"fry(") - string(JSON n LENGTH "${FRY_JSON}" builtWith) - math(EXPR last "${n} - 1") - foreach(i RANGE ${last}) - string(JSON part GET "${FRY_JSON}" builtWith ${i}) - if(i GREATER 0) - if(i EQUAL last) - string(APPEND h " and ") - else() - string(APPEND h ", ") - endif() - endif() - string(APPEND h "${part}") - endforeach() - string(APPEND h ")fry\";\n} // namespace fry::project\n") - file(CONFIGURE OUTPUT ${out} CONTENT "${h}" @ONLY) - - string(REPLACE "." "," commas "${FRY_VERSION}") - file(CONFIGURE OUTPUT ${rc} CONTENT "// Made by CMake from project.json (Windows: the program's icon and details, Explorer's Properties). -1 ICON \"${PROJECT_SOURCE_DIR}/branding/fry3dx.ico\" -1 VERSIONINFO -FILEVERSION ${commas},0 -PRODUCTVERSION ${commas},0 -BEGIN - BLOCK \"StringFileInfo\" - BEGIN - BLOCK \"040904b0\" - BEGIN - VALUE \"CompanyName\", \"${FRY_COMPANY}\" - VALUE \"FileDescription\", \"${FRY_NAME} - ${FRY_LONG}\" - VALUE \"FileVersion\", \"${FRY_VERSION}\" - VALUE \"InternalName\", \"fry3dx\" - VALUE \"LegalCopyright\", \"${FRY_COPYRIGHT}, ${FRY_LICENSE}\" - VALUE \"OriginalFilename\", \"fry3dx.exe\" - VALUE \"ProductName\", \"${FRY_NAME}\" - VALUE \"ProductVersion\", \"${FRY_VERSION}\" - END - END - BLOCK \"VarFileInfo\" - BEGIN - VALUE \"Translation\", 0x409, 1200 - END -END -" @ONLY) -endfunction() diff --git a/content/Fry3DX/branding/icon.png b/content/Fry3DX/branding/icon.png index e194f74..bb30490 100644 Binary files a/content/Fry3DX/branding/icon.png and b/content/Fry3DX/branding/icon.png differ diff --git a/content/Fry3DX/branding/logo.png b/content/Fry3DX/branding/logo.png index 470db04..76db8f9 100644 Binary files a/content/Fry3DX/branding/logo.png and b/content/Fry3DX/branding/logo.png differ diff --git a/content/Fry3DX/plugins/more_materials.lua b/content/Fry3DX/plugins/more_materials.lua deleted file mode 100644 index fdaf8d1..0000000 --- a/content/Fry3DX/plugins/more_materials.lua +++ /dev/null @@ -1,13 +0,0 @@ --- More materials for the picker (Properties > Material), and for scripts: o.material = "marble". --- fry.material works in any script; in a plug-in they're there every time Fry3DX starts. -fry.plugin{name = "More materials", about = "Marble, rose gold, titanium, carbon, jade, walnut and others."} - -local list = { - {"Marble", "#e8e4dc", 0, 0.15}, {"Black marble", "#1d1d20", 0, 0.12}, {"Rose gold", "#f2b6a0", 1, 0.2}, - {"Silver", "#f2f2f0", 1, 0.12}, {"Titanium", "#a8a6a0", 1, 0.35}, {"Carbon", "#202224", 0, 0.25}, - {"Jade", "#4f9e74", 0, 0.2}, {"Terracotta", "#c0603c", 0, 0.9}, {"Walnut", "#5b3a26", 0, 0.6}, - {"Oak", "#c49a64", 0, 0.65}, {"Red car paint", "#b0101a", 0.3, 0.1}, {"Teal plastic", "#1f9a96", 0, 0.35}, -} -for _, m in ipairs(list) do - fry.material{name = m[1], color = m[2], metal = m[3], rough = m[4]} -end diff --git a/content/Fry3DX/plugins/scatter.lua b/content/Fry3DX/plugins/scatter.lua deleted file mode 100644 index e93cad5..0000000 --- a/content/Fry3DX/plugins/scatter.lua +++ /dev/null @@ -1,27 +0,0 @@ --- Scatter: copies of what's picked, strewn round it on the ground, each turned and sized a bit --- differently (rocks, trees, crates). In the Object menu. -fry.plugin{name = "Scatter", about = "Copies of the picked object strewn round it, each a little different."} - -fry.command{ - name = "Scatter copies", menu = "object", - help = "Copies of the last picked object round it on the ground.", - settings = {{"copies", 12}, {"radius", 2}, {"size_change", 0.3}, {"seed", 1}}, - run = function(s) - local picked = fry.selected() - local o = picked[#picked] - if not o then error("pick an object to scatter first") end - math.randomseed(math.floor(s.seed)) - local base = o.position - local made = {} - for i = 1, math.max(1, math.floor(s.copies)) do - local c = o:copy() - local a, r = math.random() * 2 * math.pi, math.sqrt(math.random()) * s.radius - c.position = {base.x + math.cos(a) * r, base.y + math.sin(a) * r, base.z} - c:rotate(0, 0, math.random() * 360) - c:scale(1 + (math.random() * 2 - 1) * s.size_change) - made[#made + 1] = c - end - fry.group(o.name .. " scattered", made) - fry.select(made) - end, -} diff --git a/content/Fry3DX/plugins/stairs.lua b/content/Fry3DX/plugins/stairs.lua deleted file mode 100644 index 37c6577..0000000 --- a/content/Fry3DX/plugins/stairs.lua +++ /dev/null @@ -1,40 +0,0 @@ --- Stairs, straight or round a post: two commands in the Add menu, each asking for its sizes. --- A plug-in is a script that stays loaded: fry.command puts a command in a menu, and its run --- function is called (with the settings asked for) each time it's picked. -fry.plugin{name = "Stairs", about = "Straight stairs and spiral stairs, from the Add menu."} - -fry.command{ - name = "Stairs", menu = "add", - help = "A flight of steps going up along Y.", - settings = {{"steps", 12}, {"rise", 0.18}, {"going", 0.28}, {"width", 0.9}}, - run = function(s) - local made = {} - for i = 0, math.max(1, math.floor(s.steps)) - 1 do - local step = fry.add("cube", {width = s.width, depth = s.going, height = s.rise * (i + 1), color = "#b07a4a", name = "Step"}) - step.position = {0, i * s.going, 0} - step:drop() -- (its bottom on the ground) - made[#made + 1] = step - end - fry.group("Stairs", made) - fry.select(made) - end, -} - -fry.command{ - name = "Spiral stairs", menu = "add", - help = "Steps turning round a post.", - settings = {{"steps", 18}, {"rise", 0.18}, {"turn", 22}, {"width", 0.9}}, - run = function(s) - local steps = math.max(1, math.floor(s.steps)) - local made = {fry.add("pillar", {radius = 0.12, height = steps * s.rise + 0.3, color = "#8a8a90", name = "Post"})} - for i = 0, steps - 1 do - local step = fry.add("cube", {width = s.width, depth = 0.32, height = 0.05, color = "#b07a4a", name = "Step"}) - local a = math.rad(i * s.turn) - step.turn = {0, 0, i * s.turn} - step.position = {math.cos(a) * s.width / 2, math.sin(a) * s.width / 2, (i + 1) * s.rise} - made[#made + 1] = step - end - fry.group("Spiral stairs", made) - fry.select(made) - end, -} diff --git a/content/Fry3DX/plugins/stamp.lua b/content/Fry3DX/plugins/stamp.lua deleted file mode 100644 index e4ddb0b..0000000 --- a/content/Fry3DX/plugins/stamp.lua +++ /dev/null @@ -1,22 +0,0 @@ --- Stamp: a mouse tool. Click on anything (or the ground) and a copy of the picked object is put --- there, standing on the surface. Shows how a plug-in adds a tool to the Toolbox (fry.tool). -fry.plugin{name = "Stamp", about = "A tool: click to put copies of the picked object on what you click, standing on it."} - -fry.tool{ - name = "Stamp copies", - help = "Click to put a copy of the picked object there, standing on the surface (pick one first).", - click = function(at, normal, onto) - local picked = fry.selected() - local o = picked[#picked] - if not o or (onto and o.id == onto.id) then - -- nothing picked to copy (or clicking on it): a little ball, to show where - o = fry.add("sphere", {radius = 0.1}) - o.position = at + normal * 0.1 - return - end - local c = o:copy() - local lo, hi = o:bounds() - c.position = at + normal * ((hi.z - lo.z) / 2) - o:select() - end, -} diff --git a/content/Fry3DX/scripts/box_with_lid.lua b/content/Fry3DX/scripts/box_with_lid.lua deleted file mode 100644 index 506650b..0000000 --- a/content/Fry3DX/scripts/box_with_lid.lua +++ /dev/null @@ -1,16 +0,0 @@ --- A box to print, with a lid and holes for M3 screws in its corners. -local w, d, h, wall = 0.08, 0.06, 0.04, 0.002 -local box = fry.add("rounded_cube", {width = w, depth = d, height = h, name = "Box", color = "#d9d4c7"}) -local inside = fry.add("cube", {width = w - 2 * wall, depth = d - 2 * wall, height = h}) -inside.position = {0, 0, wall} -box:subtract(inside) -local lid = fry.add("cube", {width = w, depth = d, height = wall, name = "Lid", color = "#ff7828"}) -lid.position = {w + 0.02, 0, 0} -for sx = -1, 1, 2 do - for sy = -1, 1, 2 do - local hole = fry.add("cylinder", {radius = 0.0016, height = 0.01, sides = 24}) - hole.position = {w + 0.02 + sx * (w / 2 - 0.006), sy * (d / 2 - 0.006), -0.002} - lid:subtract(hole) - end -end -fry.frame() diff --git a/content/Fry3DX/scripts/gear.lua b/content/Fry3DX/scripts/gear.lua deleted file mode 100644 index 4d88992..0000000 --- a/content/Fry3DX/scripts/gear.lua +++ /dev/null @@ -1,14 +0,0 @@ --- A gear for 3D printing, with a hole for an M5 screw. -local teeth, radius, depth, thick = 16, 0.03, 0.004, 0.006 -- metres -local outline = {} -for i = 0, teeth * 4 - 1 do - local a = i / (teeth * 4) * 2 * math.pi - local r = (i % 4 < 2) and radius + depth or radius - outline[#outline + 1] = {math.cos(a) * r, math.sin(a) * r} -end -local gear = fry.extrude(outline, thick, "Gear") -gear.color = "#e0a030" -local hole = fry.add("cylinder", {radius = 0.0027, height = 0.02, sides = 32}) -hole.position = {0, 0, -0.005} -gear:subtract(hole) -fry.frame() diff --git a/content/Fry3DX/scripts/little_town.lua b/content/Fry3DX/scripts/little_town.lua deleted file mode 100644 index 4846e52..0000000 --- a/content/Fry3DX/scripts/little_town.lua +++ /dev/null @@ -1,21 +0,0 @@ --- A little town: random houses on a grid, each a folder of its own. -math.randomseed(7) -local roofs = {"#a8432f", "#5a6470", "#8c5a3c"} -for x = -2, 2 do - for y = -2, 2 do - local w, d, h = 0.6 + math.random() * 0.3, 0.6 + math.random() * 0.3, 0.5 + math.random() * 0.9 - local walls = fry.add("cube", {width = w, depth = d, height = h, color = "#e8e0d0", name = "Walls"}) - walls.position = {x * 1.4, y * 1.4, 0} - -- a wedge rises towards -X: two of them back to back make a ridge - local roof = fry.add("wedge", {width = d + 0.1, length = w / 2 + 0.05, height = 0.35, name = "Roof"}) - local other = roof:copy() - roof.position = {x * 1.4 + w / 4 + 0.025, y * 1.4, h} - other.position = {x * 1.4 - w / 4 - 0.025, y * 1.4, h} - other.turn = {0, 0, 180} - local c = roofs[math.random(#roofs)] - roof.color, other.color = c, c - fry.group(string.format("House %d,%d", x, y), {walls, roof, other}) - end -end -fry.look{sun_turn = 60, sun_height = 35} -fry.frame() diff --git a/content/Fry3DX/scripts/spiral_stairs.lua b/content/Fry3DX/scripts/spiral_stairs.lua deleted file mode 100644 index 53adb16..0000000 --- a/content/Fry3DX/scripts/spiral_stairs.lua +++ /dev/null @@ -1,15 +0,0 @@ --- Spiral stairs round a pillar: change the numbers and run it again (F5). -local steps, rise, turn = 18, 0.18, 22 -- how many, how high each, degrees each -local width = 0.9 - -fry.add("pillar", {radius = 0.12, height = steps * rise + 0.3, color = "#8a8a90", name = "Post"}) -local made = {} -for i = 0, steps - 1 do - local step = fry.add("cube", {width = width, depth = 0.32, height = 0.05, color = "#b07a4a", name = "Step"}) - step.turn = {0, 0, i * turn} - local a = math.rad(i * turn) - step.position = {math.cos(a) * width / 2, math.sin(a) * width / 2, (i + 1) * rise} - made[#made + 1] = step -end -fry.group("Stairs", made) -fry.frame() diff --git a/content/Fry3DX/scripts/vase.lua b/content/Fry3DX/scripts/vase.lua deleted file mode 100644 index dd856ea..0000000 --- a/content/Fry3DX/scripts/vase.lua +++ /dev/null @@ -1,15 +0,0 @@ --- A vase turned on a lathe: the profile is {out, up} points from the bottom. -local profile = {} -local height, n = 0.4, 24 -for i = 0, n do - local t = i / n - -- a belly low down, a neck, a lip - local r = 0.06 + 0.07 * math.sin(t * math.pi * 1.1) + 0.02 * t * t - profile[#profile + 1] = {r, t * height} -end -table.insert(profile, 1, {0, 0}) -local vase = fry.lathe(profile, 64, "Vase") -vase.color = "#3c6e9f" -vase.rough = 0.25 -vase:thicken(0.004) -- walls, so it prints hollow -fry.frame() diff --git a/content/Fry3DX/scripts/waves.lua b/content/Fry3DX/scripts/waves.lua deleted file mode 100644 index 8b534b5..0000000 --- a/content/Fry3DX/scripts/waves.lua +++ /dev/null @@ -1,12 +0,0 @@ --- Points moved by a formula: a plane made into waves, then given a thickness. -local p = fry.add("plane", {width = 2, depth = 2, cuts = 40, name = "Waves"}) -local pts = p:points() -for i, v in ipairs(pts) do - v.z = 0.08 * math.sin(v.x * 6) * math.cos(v.y * 5) -end -p:setpoints(pts) -p:thicken(0.03) -p.smooth = true -p.color = "#2f8f9d" -p:move(0, 0, 0.12) -fry.frame() diff --git a/content/engine/fonts/InstrumentSans-Bold.ttf b/content/engine/fonts/InstrumentSans-Bold.ttf deleted file mode 100644 index 9a55c17..0000000 Binary files a/content/engine/fonts/InstrumentSans-Bold.ttf and /dev/null differ diff --git a/content/engine/fonts/InstrumentSans-Regular.ttf b/content/engine/fonts/InstrumentSans-Regular.ttf deleted file mode 100644 index 0eb2260..0000000 Binary files a/content/engine/fonts/InstrumentSans-Regular.ttf and /dev/null differ diff --git a/content/engine/fonts/InstrumentSans-SemiBold.ttf b/content/engine/fonts/InstrumentSans-SemiBold.ttf deleted file mode 100644 index 5c3a092..0000000 Binary files a/content/engine/fonts/InstrumentSans-SemiBold.ttf and /dev/null differ diff --git a/content/engine/fonts/JetBrainsMono-Regular.ttf b/content/engine/fonts/JetBrainsMono-Regular.ttf deleted file mode 100644 index 660323e..0000000 Binary files a/content/engine/fonts/JetBrainsMono-Regular.ttf and /dev/null differ diff --git a/content/engine/fonts/OFL-InstrumentSans.txt b/content/engine/fonts/OFL-InstrumentSans.txt deleted file mode 100644 index 26bd2f9..0000000 --- a/content/engine/fonts/OFL-InstrumentSans.txt +++ /dev/null @@ -1,93 +0,0 @@ -Copyright 2022 The Instrument Sans Project Authors (https://github.com/Instrument/instrument-sans) - -This Font Software is licensed under the SIL Open Font License, Version 1.1. -This license is copied below, and is also available with a FAQ at: -https://scripts.sil.org/OFL - - ------------------------------------------------------------ -SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007 ------------------------------------------------------------ - -PREAMBLE -The goals of the Open Font License (OFL) are to stimulate worldwide -development of collaborative font projects, to support the font creation -efforts of academic and linguistic communities, and to provide a free and -open framework in which fonts may be shared and improved in partnership -with others. - -The OFL allows the licensed fonts to be used, studied, modified and -redistributed freely as long as they are not sold by themselves. The -fonts, including any derivative works, can be bundled, embedded, -redistributed and/or sold with any software provided that any reserved -names are not used by derivative works. The fonts and derivatives, -however, cannot be released under any other type of license. The -requirement for fonts to remain under this license does not apply -to any document created using the fonts or their derivatives. - -DEFINITIONS -"Font Software" refers to the set of files released by the Copyright -Holder(s) under this license and clearly marked as such. This may -include source files, build scripts and documentation. - -"Reserved Font Name" refers to any names specified as such after the -copyright statement(s). - -"Original Version" refers to the collection of Font Software components as -distributed by the Copyright Holder(s). - -"Modified Version" refers to any derivative made by adding to, deleting, -or substituting -- in part or in whole -- any of the components of the -Original Version, by changing formats or by porting the Font Software to a -new environment. - -"Author" refers to any designer, engineer, programmer, technical -writer or other person who contributed to the Font Software. - -PERMISSION & CONDITIONS -Permission is hereby granted, free of charge, to any person obtaining -a copy of the Font Software, to use, study, copy, merge, embed, modify, -redistribute, and sell modified and unmodified copies of the Font -Software, subject to the following conditions: - -1) Neither the Font Software nor any of its individual components, -in Original or Modified Versions, may be sold by itself. - -2) Original or Modified Versions of the Font Software may be bundled, -redistributed and/or sold with any software, provided that each copy -contains the above copyright notice and this license. These can be -included either as stand-alone text files, human-readable headers or -in the appropriate machine-readable metadata fields within text or -binary files as long as those fields can be easily viewed by the user. - -3) No Modified Version of the Font Software may use the Reserved Font -Name(s) unless explicit written permission is granted by the corresponding -Copyright Holder. This restriction only applies to the primary font name as -presented to the users. - -4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font -Software shall not be used to promote, endorse or advertise any -Modified Version, except to acknowledge the contribution(s) of the -Copyright Holder(s) and the Author(s) or with their explicit written -permission. - -5) The Font Software, modified or unmodified, in part or in whole, -must be distributed entirely under this license, and must not be -distributed under any other license. The requirement for fonts to -remain under this license does not apply to any document created -using the Font Software. - -TERMINATION -This license becomes null and void if any of the above conditions are -not met. - -DISCLAIMER -THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT -OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE -COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, -INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL -DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM -OTHER DEALINGS IN THE FONT SOFTWARE. diff --git a/docs/content.js b/docs/content.js index f2c2920..46fbe15 100644 --- a/docs/content.js +++ b/docs/content.js @@ -7,7 +7,7 @@ window.FRY = { authorUrl: "https://github.com/Nexoniarz", repo: "https://github.com/Nexoniarz/Fry3DX", tagline: "A 3D modeller that does what you'd expect.", - intro: "Pick a tool, click, drag. Plain words instead of jargon, a toolbox like GIMP's, and the useful stuff from the big modellers without the hundred menus around it. On Windows, macOS, Linux and your phone.", + intro: "Pick a tool, click, drag. Plain words instead of jargon, a toolbox like GIMP's, and the useful stuff from the big modellers without the hundred menus around it. On Windows, Linux and your phone.", releases: "https://github.com/Nexoniarz/Fry3DX/releases/latest", why: { @@ -18,80 +18,31 @@ window.FRY = { ], }, - // The feature tabs, in order (each feature names its group). - featureGroups: [ - { id: "make", title: "Make" }, - { id: "paint", title: "Paint & sculpt" }, - { id: "print", title: "Render & print" }, - { id: "work", title: "Work" }, - ], - features: [ - { group: "make", icon: "cube", title: "Shapes that stay editable", text: "Cube, cylinder, sphere, torus, stairs, arch and more, plus starter models like a table, chair or barrel. Change their sizes any time in Properties." }, - { group: "make", icon: "pen", title: "Draw a shape anywhere", text: "Click an outline on the ground or straight on the face of another object: it becomes a new part, gets added to it, or cuts into it." }, - { group: "make", icon: "combine", title: "Add, subtract, overlap", text: "Combine objects: add them together, take one out of another, or keep only where they overlap. Exact, and always closed, so always ready to print." }, - { group: "make", icon: "hole", title: "Cuts you can still move", text: "Cut one object out of another and keep the cutter: move it, turn it, change its shape, and the hole follows. It goes with what it cuts. Apply when you're done." }, - { group: "make", icon: "ruler", title: "Exact sizes", text: "Type a number while you drag for exactly that: extrude, inset, round edges, move, turn, scale, a drawn line's length. Dimensions in Properties, snapping to points and the middles of edges and faces, measuring." }, - { group: "make", icon: "text", title: "Text, spin, import", text: "3D text from any font. An outline spun round an axis into a vase or a wheel, or up into a screw thread. STL, OBJ, 3MF and glTF brought in, the right way up." }, - { group: "make", icon: "points", title: "Real shape editing", text: "Points, edges and faces. Extrude, inset, round edges, loop cut, knife, bridge, push and pull, edge slide, creases that stay sharp when smoothed, both sides at once. Soft selection as in Blender and Maya: near points follow (Shift+O)." }, - { group: "make", icon: "hole", title: "Holes for screws and nuts", text: "Round, rectangle, triangle or hexagon. M2 to M8 screw and nut sizes ready, with a little room added so the print actually fits." }, - { group: "make", icon: "copies", title: "Copies and thickness", text: "Copies in a row, round in a circle, or along a path, turning as it turns. Make a surface thick, or a solid hollow with walls exactly as thick as you need." }, - { group: "paint", icon: "sculpt", title: "Sculpt it like clay", text: "Raise, puff out, smooth, flatten, pinch and grab the surface with a brush, the same on both sides if you like. A shape with too few points is made finer first, keeping its shape." }, - { group: "print", icon: "sphere", title: "Materials you can see", text: "Gold, chrome, brushed steel, wood, ceramic, rubber and more, or set how metal and rough it is yourself; save a look as your own material for every file. Shown in the view, and exported with it." }, - { group: "paint", icon: "brush", title: "Paint and stickers", text: "Paint on the model or on its flat picture, on both sides at once, or only inside a stencil. Paste any picture (Ctrl+V) and it goes on like a sticker that bends over edges and corners." }, - { group: "paint", icon: "layout", title: "Layout tab", text: "Move, turn and size the flat frames of the surface by hand. The paint follows, so the model looks the same." }, - { group: "print", icon: "print", title: "Made for 3D printing", text: "Your printer's plate in the view, sizes in millimetres and a scaler (percent, inches to mm, fit the plate), checks with one repair button, overhangs in red, walls too thin in yellow, a layer-by-layer slice preview, weight and filament." }, - { group: "print", icon: "sun", title: "See it rendered", text: "Solid view for modelling, a real renderer with sky, sun and soft shadows when you want to see it properly. Save a picture with F12." }, - { group: "work", icon: "sun", title: "Get round your way", text: "Fly through it as in a game: right drag looks, W A S D or the arrows move, the wheel goes forward and back, Shift + wheel sets the speed. Or orbit round what you look at, Blender style: Shift+C switches." }, - { group: "work", icon: "search", title: "Find anything", text: "F3 or Ctrl+Space finds any command by name. Hold Space for the tools round the mouse, Shift+Space for the views. Your own keys for any command, the undo history, and workspaces: the panels as you had them." }, - { group: "work", icon: "folder", title: "Folders and groups", text: "Layers with folders inside folders, drag and drop, show/hide and lock whole groups, and a button on every row that brings the camera to it." }, - { group: "work", icon: "phone", title: "On your phone too", text: "Not a viewer: the whole modeller. Big buttons, one finger turns the view, two move and pinch to zoom, holding still is a right-click. Files through the phone's own picker." }, - { group: "work", icon: "code", title: "Scripts, if you want them", text: "Lua in a Script panel: build a town in a loop, turn a profile into a vase, move points by a formula. Kept in the .fry with the model; F5 runs one, Ctrl+Z takes it all back." }, - { group: "work", icon: "plug", title: "Plug-ins", text: "A script in the plug-ins folder stays loaded: it adds commands to the Add, Object or Script menu (with a little form for their settings) and materials to the picker. Or a mouse tool in the Toolbox. Stairs, scatter, stamp and more materials come with it." }, - { group: "work", icon: "save", title: "Never lose work", text: "Its own packed .fry file, autosave in the background, recovery after a crash, and a Save / Don't save / Cancel when closing." }, + { icon: "▣", title: "Shapes that stay editable", text: "Cube, cylinder, sphere, torus, stairs, arch and more, plus starter models like a table, chair or barrel. Change their sizes any time in Properties." }, + { icon: "✎", title: "Draw a shape anywhere", text: "Click an outline on the ground or straight on the face of another object: it becomes a new part, gets added to it, or cuts into it." }, + { icon: "⊕", title: "Add, subtract, overlap", text: "Combine objects: add them together, take one out of another, or keep only where they overlap. The result is always closed and ready to print." }, + { icon: "◫", title: "Real shape editing", text: "Points, edges and faces. Extrude, inset, round edges, loop cut, knife, merge. Shift+click picks a whole loop, Shift+Ctrl+click a ring." }, + { icon: "◎", title: "Holes for screws and nuts", text: "Round, rectangle, triangle or hexagon. M2 to M8 screw and nut sizes ready, with a little room added so the print actually fits." }, + { icon: "▤", title: "Copies and thickness", text: "Copies in a row or round in a circle. Make a surface thick, or a solid hollow with walls exactly as thick as you need." }, + { icon: "✐", title: "Paint and stickers", text: "Paint on the model or on its flat picture. Paste any picture (Ctrl+V) and it goes on like a sticker that bends over edges and corners." }, + { icon: "▦", title: "Layout tab", text: "Move, turn and size the flat frames of the surface by hand. The paint follows, so the model looks the same." }, + { icon: "⎙", title: "Made for 3D printing", text: "Your printer's plate in the view, sizes in millimetres, checks for holes and flipped faces with fix buttons, overhangs shown red, weight and filament." }, + { icon: "☀", title: "See it rendered", text: "Solid view for modelling, a real renderer with sky, sun and soft shadows when you want to see it properly. Save a picture with F12." }, + { icon: "▭", title: "Folders and groups", text: "Layers with folders inside folders, drag and drop, show/hide and lock whole groups, and a button on every row that brings the camera to it." }, + { icon: "▯", title: "On your phone too", text: "Not a viewer: the whole modeller. Big buttons, one finger turns the view, two move and pinch to zoom, holding still is a right-click. Files through the phone's own picker." }, + { icon: "⟲", title: "Never lose work", text: "Its own packed .fry file, autosave in the background, recovery after a crash, and a Save / Don't save / Cancel when closing." }, ], shots: [ - { img: "img/model.webp", title: "Model", text: "Starter models with materials (wood, glossy glass, ceramic), a folder for what's on the table, rendered with sky and shadows while you work." }, - { img: "img/sculpt.webp", title: "Sculpt", text: "A ball pushed into a head with the brushes: a nose raised, eyes dug in, a smile pinched, ears grabbed out. Tab in the Paint tab." }, - { img: "img/materials.webp", title: "Materials", text: "Gold, chrome, wood, rubber, copper, ceramic, steel: picked in Properties, shown in the view, exported with the model." }, - { img: "img/paint.webp", title: "Paint", text: "The logo pasted onto a box as a sticker: drag its corners to fit, Enter to lock it on. The Picture panel shows where it lands." }, - { img: "img/layout.webp", title: "Layout", text: "The box's surface laid out flat: move, turn and size the frames, and the paint follows." }, - { img: "img/render.webp", title: "Render", text: "Sun, sky and ground, brightness, soft shadows and glow, and F12 for a picture of just the view." }, - { img: "img/print.webp", title: "Print", text: "Two gears and an arch on a Prusa's plate: sizes in millimetres, checked to be closed, the arch's overhang flagged, weight and filament." }, - { img: "img/combine.webp", title: "Combine", text: "A hole taken out of a box, pegs as copies in a folder, a plane made thick: everything stays closed." }, - { img: "img/scripts.webp", title: "Scripts", text: "A little town from a dozen lines of Lua: random houses, each a folder of walls and roof. F5 runs it, Ctrl+Z takes it back." }, - { img: "img/light.webp", title: "Light", text: "The light appearance, warm paper instead of graphite. Or let it follow your desktop (View > Appearance)." }, - { img: "img/phone.webp", title: "Phone", text: "The phone layout: big buttons along the bottom, Shift and Ctrl that stay down, panels when you want them." }, - { img: "img/crash.webp", title: "Even the crash screen", text: "If something does get burnt, it says so plainly, keeps a report for you, and your work comes back from the last autosave." }, + { img: "img/model.webp", title: "Model", text: "Starter models, a folder of parts, a shape drawn onto a cube's face, rendered with sky and shadows." }, + { img: "img/paint.webp", title: "Paint", text: "A picture pasted on as a sticker: it bends over the cube's edge like a real one." }, + { img: "img/print.webp", title: "Print", text: "The printer's plate, sizes in millimetres, checks and overhangs before you slice." }, + { img: "img/phone.webp", title: "Phone", text: "The phone layout: big buttons along the bottom, panels when you want them, fingers for the view." }, + { img: "img/combine.webp", title: "Combine", text: "A cylinder taken out of a cube, copies in a row in a folder, a plane made thick." }, + { img: "img/crash.webp", title: "Even the crash screen", text: "If something does get burnt, your work comes back from the last autosave." }, ], - scripting: { - title: "When clicking gets repetitive, write it down.", - text: "Fry3DX has Lua built in, and a Script panel to write it in. Everything you can click, a script can do: add shapes and change their settings, combine them, move every point by a formula, set the sun. It's optional, small, and can't touch anything outside the scene.", - points: [ - "F5 runs it; one Ctrl+Z takes back everything it did", - "If it stops with an error, nothing it did is kept", - "Examples to start from: stairs, a vase, a gear, a town, a box with a lid", - "The ? button lists every function, right next to your script", - "Scripts are saved in the .fry, a list of them per file", - "Plug-ins: a script in the plug-ins folder adds its own menu commands and materials", - ], - file: "spiral_stairs.lua", - code: `-- Spiral stairs round a pillar: change the numbers, press F5 again. -local steps, rise, turn = 18, 0.18, 22 - -fry.add("pillar", {radius = 0.12, height = steps * rise + 0.3}) -for i = 0, steps - 1 do - local step = fry.add("cube", {width = 0.9, depth = 0.32, height = 0.05, - color = "#b07a4a"}) - local a = math.rad(i * turn) - step.turn = {0, 0, i * turn} - step.position = {math.cos(a) * 0.45, math.sin(a) * 0.45, (i + 1) * rise} -end -fry.frame()`, - }, - formats: { open: [".fry"], save: [".fry (packed, with pictures)"], @@ -112,7 +63,6 @@ fry.frame()`, downloads: [ { os: "Windows", what: "10 and 11, 64-bit", file: "windows-x64.zip", how: "Unpack it, run fry3dx.exe." }, - { os: "macOS", what: "13.3 and newer, Apple silicon and Intel", file: "macos.zip", how: "Unzip it, open Fry3DX.app. The first time: right-click it and choose Open." }, { os: "Linux", what: "any distro from 2022 on, 64-bit", file: "linux-x64.AppImage", how: "Make it executable, run it. A .tar.gz is there too." }, { os: "Android", what: "8.0 and newer, 64-bit, Vulkan", file: "android-arm64.apk", how: "Open it on the phone to install (allow installing from your browser or files app)." }, ], @@ -125,14 +75,10 @@ fry.frame()`, "cmake --preset release && cmake --build build/release", "build/release/bin/fry3dx", ], - needs: "Needs: CMake 3.25+, Ninja, a C++20 compiler (GCC 13+, Clang 17+, Xcode 15+) and glslc. Presets for macOS, Windows (cross-built) and Android are in the README.", + needs: "Needs: CMake 3.25+, Ninja, a C++20 compiler (GCC 13+, Clang 17+) and glslc. Presets for Windows (cross-built) and Android are in the README.", }, versions: [ - { v: "0.8.1", date: "2026-10-21", items: ["Fixes", "Close up to big or long flat shapes the view no longer breaks into blocks, jitters or loses the sky and grid", "The grid drawn as in Blender: every size of line everywhere it's far enough apart, smooth, nothing smeared or popping as you move", "Far from the middle of the scene: steadier, and the wheel doesn't leap", "Help menu: the website, reporting a problem, the newest version; the About box lists who made it"] }, - { v: "0.8", date: "2026-10-21", items: ["Quicker to use, exact to size", "Find any command by name (F3), the tools round the mouse (Space), your own keys, the undo history, workspaces", "Typed sizes while dragging, snapping, measuring, a line's length while drawing", "Cuts you can still move; combining that's exact", "3D text, spin and screw, copies along a path, crease, edge slide, mirror editing", "Import STL, OBJ, 3MF and glTF", "Print: a scaler, thin walls, a slice preview, repair all at once", "Painting both sides and inside a stencil; plug-ins can add mouse tools", "A fly camera as in games (right drag, WASD, the wheel forward and back, Shift + wheel for speed), or the orbiting one (Shift+C)", "Smoother: dragging settings in Properties, a grid that doesn't crawl or jump, clean close-ups in Rendered", "Far away things no longer vanish; steadier and smoother on phones, which stay sideways"] }, - { v: "0.7", date: "2026-10-21", items: ["Steadier and tidier", "Cutting a shape inside an earlier cut no longer crashes, and cuts come out closed", "Edges hidden behind the surface stay hidden on big or cut-up shapes", "Every panel has a least size, so it stays readable; the first layout fits small windows", "Eye and padlock buttons in Layers; the tabs fit narrow windows", "A failed tool keeps your redo"] }, - { v: "0.6", date: "2026-10-20", items: ["Sculpting, scripts and a Mac app", "Sculpting: raise, puff out, smooth, flatten, pinch and grab", "Materials shown in the view, sixteen to start from", "Scripts: Lua and a Script panel, with examples, kept in the .fry", "Plug-ins: menu commands and materials, three to start with", "Your own materials", "Soft selection, bridge, push / pull, smooth points, show only the selected", "macOS: one app for Apple silicon and Intel", "A new look (Niveus): light and dark, following the desktop", "A new logo", "Drop a file on the window to open it"] }, { v: "0.5", date: "2026-10-19", items: ["Builds for Windows, Linux (AppImage) and Android", "A phone layout: big buttons, finger gestures, the phone's file picker", "Apache License 2.0"] }, { v: "0.4", date: "2026-10-19", items: ["Combine objects: add, subtract, overlap", "Draw shapes onto other objects", "Copies in a row or circle, thicken and hollow", "FBX export", "Folders and groups in Layers, go-to buttons", "Shift scales both sides, Shift+click loops and rings", "A crash screen of its own"] }, { v: "0.3", date: "2026-10-19", items: ["Stickers that bend over edges, picture layers", "Packed .fry files, autosave and recovery", "Layout tab, Print tab, 3MF / STL / OBJ / PLY / GLB export", "Hole tool: hexagon nut pockets, rectangles, outlines"] }, diff --git a/docs/fonts/InstrumentSans-Italic.woff2 b/docs/fonts/InstrumentSans-Italic.woff2 deleted file mode 100644 index 3266aee..0000000 Binary files a/docs/fonts/InstrumentSans-Italic.woff2 and /dev/null differ diff --git a/docs/fonts/InstrumentSans.woff2 b/docs/fonts/InstrumentSans.woff2 deleted file mode 100644 index 55fc752..0000000 Binary files a/docs/fonts/InstrumentSans.woff2 and /dev/null differ diff --git a/docs/fonts/JetBrainsMono.woff2 b/docs/fonts/JetBrainsMono.woff2 deleted file mode 100644 index 863db7f..0000000 Binary files a/docs/fonts/JetBrainsMono.woff2 and /dev/null differ diff --git a/docs/fonts/OFL-InstrumentSans.txt b/docs/fonts/OFL-InstrumentSans.txt deleted file mode 100644 index 26bd2f9..0000000 --- a/docs/fonts/OFL-InstrumentSans.txt +++ /dev/null @@ -1,93 +0,0 @@ -Copyright 2022 The Instrument Sans Project Authors (https://github.com/Instrument/instrument-sans) - -This Font Software is licensed under the SIL Open Font License, Version 1.1. -This license is copied below, and is also available with a FAQ at: -https://scripts.sil.org/OFL - - ------------------------------------------------------------ -SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007 ------------------------------------------------------------ - -PREAMBLE -The goals of the Open Font License (OFL) are to stimulate worldwide -development of collaborative font projects, to support the font creation -efforts of academic and linguistic communities, and to provide a free and -open framework in which fonts may be shared and improved in partnership -with others. - -The OFL allows the licensed fonts to be used, studied, modified and -redistributed freely as long as they are not sold by themselves. The -fonts, including any derivative works, can be bundled, embedded, -redistributed and/or sold with any software provided that any reserved -names are not used by derivative works. The fonts and derivatives, -however, cannot be released under any other type of license. The -requirement for fonts to remain under this license does not apply -to any document created using the fonts or their derivatives. - -DEFINITIONS -"Font Software" refers to the set of files released by the Copyright -Holder(s) under this license and clearly marked as such. This may -include source files, build scripts and documentation. - -"Reserved Font Name" refers to any names specified as such after the -copyright statement(s). - -"Original Version" refers to the collection of Font Software components as -distributed by the Copyright Holder(s). - -"Modified Version" refers to any derivative made by adding to, deleting, -or substituting -- in part or in whole -- any of the components of the -Original Version, by changing formats or by porting the Font Software to a -new environment. - -"Author" refers to any designer, engineer, programmer, technical -writer or other person who contributed to the Font Software. - -PERMISSION & CONDITIONS -Permission is hereby granted, free of charge, to any person obtaining -a copy of the Font Software, to use, study, copy, merge, embed, modify, -redistribute, and sell modified and unmodified copies of the Font -Software, subject to the following conditions: - -1) Neither the Font Software nor any of its individual components, -in Original or Modified Versions, may be sold by itself. - -2) Original or Modified Versions of the Font Software may be bundled, -redistributed and/or sold with any software, provided that each copy -contains the above copyright notice and this license. These can be -included either as stand-alone text files, human-readable headers or -in the appropriate machine-readable metadata fields within text or -binary files as long as those fields can be easily viewed by the user. - -3) No Modified Version of the Font Software may use the Reserved Font -Name(s) unless explicit written permission is granted by the corresponding -Copyright Holder. This restriction only applies to the primary font name as -presented to the users. - -4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font -Software shall not be used to promote, endorse or advertise any -Modified Version, except to acknowledge the contribution(s) of the -Copyright Holder(s) and the Author(s) or with their explicit written -permission. - -5) The Font Software, modified or unmodified, in part or in whole, -must be distributed entirely under this license, and must not be -distributed under any other license. The requirement for fonts to -remain under this license does not apply to any document created -using the Font Software. - -TERMINATION -This license becomes null and void if any of the above conditions are -not met. - -DISCLAIMER -THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT -OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE -COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, -INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL -DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM -OTHER DEALINGS IN THE FONT SOFTWARE. diff --git a/content/engine/fonts/OFL-JetBrainsMono.txt b/docs/fonts/OFL-Inter.txt similarity index 96% rename from content/engine/fonts/OFL-JetBrainsMono.txt rename to docs/fonts/OFL-Inter.txt index 821a3da..9b2ca37 100644 --- a/content/engine/fonts/OFL-JetBrainsMono.txt +++ b/docs/fonts/OFL-Inter.txt @@ -1,9 +1,8 @@ -Copyright 2020 The JetBrains Mono Project Authors (https://github.com/JetBrains/JetBrainsMono) +Copyright (c) 2016 The Inter Project Authors (https://github.com/rsms/inter) This Font Software is licensed under the SIL Open Font License, Version 1.1. - -This license is copied below, and is also available with a FAQ at: https://scripts.sil.org/OFL - +This license is copied below, and is also available with a FAQ at: +http://scripts.sil.org/OFL ----------------------------------------------------------- SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007 @@ -44,7 +43,7 @@ new environment. "Author" refers to any designer, engineer, programmer, technical writer or other person who contributed to the Font Software. -PERMISSION & CONDITIONS +PERMISSION AND CONDITIONS Permission is hereby granted, free of charge, to any person obtaining a copy of the Font Software, to use, study, copy, merge, embed, modify, redistribute, and sell modified and unmodified copies of the Font diff --git a/docs/fonts/inter-latin-wght-normal.woff2 b/docs/fonts/inter-latin-wght-normal.woff2 new file mode 100644 index 0000000..798d6d9 Binary files /dev/null and b/docs/fonts/inter-latin-wght-normal.woff2 differ diff --git a/docs/fonts/jetbrains-mono-latin-wght-normal.woff2 b/docs/fonts/jetbrains-mono-latin-wght-normal.woff2 new file mode 100644 index 0000000..cd5102a Binary files /dev/null and b/docs/fonts/jetbrains-mono-latin-wght-normal.woff2 differ diff --git a/docs/img/combine.webp b/docs/img/combine.webp index b2efe4b..2e66415 100644 Binary files a/docs/img/combine.webp and b/docs/img/combine.webp differ diff --git a/docs/img/crash.webp b/docs/img/crash.webp index 29e848f..4fc98d2 100644 Binary files a/docs/img/crash.webp and b/docs/img/crash.webp differ diff --git a/docs/img/icon.png b/docs/img/icon.png index e194f74..bb30490 100644 Binary files a/docs/img/icon.png and b/docs/img/icon.png differ diff --git a/docs/img/layout.webp b/docs/img/layout.webp deleted file mode 100644 index 787e72c..0000000 Binary files a/docs/img/layout.webp and /dev/null differ diff --git a/docs/img/light.webp b/docs/img/light.webp deleted file mode 100644 index acac722..0000000 Binary files a/docs/img/light.webp and /dev/null differ diff --git a/docs/img/logo.png b/docs/img/logo.png deleted file mode 100644 index 2ef7bc4..0000000 Binary files a/docs/img/logo.png and /dev/null differ diff --git a/docs/img/logo.svg b/docs/img/logo.svg index 774bfcd..2ca9d95 100644 --- a/docs/img/logo.svg +++ b/docs/img/logo.svg @@ -1,144 +1,34 @@ - - - - + + - - - + + - - - - - - - - - - - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + - - - - - - - + + + + + + + + + - - - - - - - - - - - - - - - - - - - - + + + + - - - - - - - - - - - - - - - - - - - diff --git a/docs/img/materials.webp b/docs/img/materials.webp deleted file mode 100644 index 3332c96..0000000 Binary files a/docs/img/materials.webp and /dev/null differ diff --git a/docs/img/model.webp b/docs/img/model.webp index 289af1a..829b27e 100644 Binary files a/docs/img/model.webp and b/docs/img/model.webp differ diff --git a/docs/img/paint.webp b/docs/img/paint.webp index a05b4b0..b8b63e8 100644 Binary files a/docs/img/paint.webp and b/docs/img/paint.webp differ diff --git a/docs/img/phone.webp b/docs/img/phone.webp index ae87ff8..178a897 100644 Binary files a/docs/img/phone.webp and b/docs/img/phone.webp differ diff --git a/docs/img/print.webp b/docs/img/print.webp index 27c455b..b23e10d 100644 Binary files a/docs/img/print.webp and b/docs/img/print.webp differ diff --git a/docs/img/render.webp b/docs/img/render.webp deleted file mode 100644 index 5c20de6..0000000 Binary files a/docs/img/render.webp and /dev/null differ diff --git a/docs/img/scripts.webp b/docs/img/scripts.webp deleted file mode 100644 index 97db006..0000000 Binary files a/docs/img/scripts.webp and /dev/null differ diff --git a/docs/img/sculpt.webp b/docs/img/sculpt.webp deleted file mode 100644 index 9ae6a6c..0000000 Binary files a/docs/img/sculpt.webp and /dev/null differ diff --git a/docs/index.html b/docs/index.html index df74152..05fb347 100644 --- a/docs/index.html +++ b/docs/index.html @@ -9,163 +9,76 @@ - - - - - - - + -

+
+ Fry3DX + +
-
-
-
- -

-

-

- -
-
-
-
-
-
- - - -
- Fry3DX — kitchen.fry -
- Fry3DX with a table, chair, barrel and crate +
+
+ -
+
Fry3DX with a table, chair, barrel and crate
+ -
-
-
-

-
-
+
+ +
+

What it does

+
+
+ +
+

How it looks

+
+
+
+ +
+
+

Files

+
+
+
+

Keys that make sense

+
-
-
- What it does -

The useful parts of the big modellers, without the hundred menus.

-
-
-
-
- -
-
- How it looks -

What you're doing, not where it's hidden.

-
-
-
-
- - - -
-
-

Files

-
-
-
-

Keys that make sense

-
-
-
- -
-
- Get it -

Free, open source, for the computer you've got.

-
+
+

Get it

-
-
-

-
-
- Terminal - -
-

-          
-

-
-
+

+
+

-
-
- Versions -

What's new

-
-
+
+

Versions

+
-