dobkeratops / nodeeditor

yet another procedural node editor tool, quick experiment to see how this goes using rust macros by contrast to past c++ things I've written
2 stars 0 forks source link

Running the nodeeditor on Windows WSL2/Ubuntu 20.04 :: Image2D<T:ImgComp=f32,const Ch:usize=4> --> Image2D<T:ImgComp,const Ch:usize> #1

Open Twenkid opened 1 year ago

Twenkid commented 1 year ago

I managed to compile and run it in WSL2 with an X-Window GUI (in Windows it failed in linking with SDL2, it seemed I had to build a special SDL which I decided to avoid for now).

However I had to modify the code a bit, due to this error:

error[E0658]: default values for const generic parameters are experimental
   --> src\fnodes.rs:242:48
    |
242 | pub struct Image2D<T:ImgComp=f32,const Ch:usize=4>{
    |                                                ^^
    |
    = note: see issue #44580 <https://github.com/rust-lang/rust/issues/44580> for more information

I changed it to:

#[derive(Default, Clone, Debug)]
//pub struct Image2D<T:ImgComp=f32,const Ch:usize=4>{
    //pub struct Image2D<T:ImgComp=f32,const Ch:usize>{ // using type defaults and const parameters in the same parameter list is currently not permitted
    pub struct Image2D<T:ImgComp,const Ch:usize>{
    pub data:Vec<[T;Ch]>,
    pub size:V2u
}

These values are sent explicitly in the code anyway.

I guess you may be using the latest experimental "bleeding edge" or whatever they called it and not getting this error or it doesn't appear in debug. I compiled it straight to release, in order to save from huge debug obj files.

The interaction is unresponsive though, it lags the mouse actions, I guess that is the X-Window relaying, I don't know.

image

[derive(Default, Clone, Debug)]

//pub struct Image2D{ //pub struct Image2D{ // using type defaults and const parameters in the same parameter list is currently not permitted pub struct Image2D<T:ImgComp,const Ch:usize>{ pub data:Vec<[T;Ch]>, pub size:V2u }

How to run it (for other users)


in c:/rs/ (/mnt/c/rs)

git clone https://github.com/dobkeratops/nodeeditor/  node
cargo build --release
/mnt/c/rs/node/target/release/nodeeditor
Press ESC -Quit

I use also VcXsrv, an X-window manager. There are settings for this also, that's for another tutorial...

Sample console output:

/mnt/c/rs/node/target/release/nodeeditor
font - converting 94 chars
dragged(162, 195),(162, 195)
dragged(172, 182),(187, 227)
[src/main.rs:279] "dragged between" = "dragged between"
[src/main.rs:279] sslot = SlotAddr {
    node: 0,
    slot: 2,
}
[src/main.rs:279] eslot = SlotAddr {
    node: 1,
    slot: 1,
}
dragged(145, 188),(109, 248)
dragged(220, 304),(277, 425)
dragged(240, 280),(285, 488)
dragged(312, 182),(341, 86)
dragged(408, 219),(554, 254)
xxx@xxx:/mnt/c/rs/node$ /mnt/c/rs/node/target/release/nodeeditor
font - converting 94 chars
dragged(223, 175),(253, 65)
dragged(331, 221),(225, 527)
dragged(317, 279),(75, 536)
dragged(283, 198),(294, 236)
dragged(432, 227),(648, 550)
dragged(438, 245),(438, 245)
dragged(139, 183),(82, 150)
dragged(78, 21),(78, 21)
[src/main.rs:279] "dragged between" = "dragged between"
[src/main.rs:279] sslot = SlotAddr {
    node: 5,
    slot: 0,
}
[src/main.rs:279] eslot = SlotAddr {
    node: 5,
    slot: 0,
}
can't link node to self
dragged(95, 16),(95, 16)
dragged(144, 59),(888, 312)
dragged(314, 67),(484, 767)
dragged(381, 345),(364, 651)
dragged(383, 360),(383, 360)
dragged(450, 414),(450, 414)
[src/main.rs:279] "dragged between" = "dragged between"
[src/main.rs:279] sslot = SlotAddr {
    node: 5,
    slot: 2,
}
[src/main.rs:279] eslot = SlotAddr {
    node: 5,
    slot: 2,
}
can't link node to self
dragged(491, 407),(824, 414)
dragged(567, 412),(618, 399)
dragged(295, 311),(321, 382)
[src/main.rs:279] "dragged between" = "dragged between"
[src/main.rs:279] sslot = SlotAddr {
    node: 3,
    slot: 0,
}
[src/main.rs:279] eslot = SlotAddr {
    node: 5,
    slot: 0,
}
dragged(449, 417),(523, 390)
[src/main.rs:279] "dragged between" = "dragged between"
[src/main.rs:279] sslot = SlotAddr {
    node: 5,
    slot: 2,
}
[src/main.rs:279] eslot = SlotAddr {
    node: 6,
    slot: 0,
}
dragged(288, 216),(477, 118)
dragged(160, 175),(211, 124)
[src/main.rs:279] "dragged between" = "dragged between"
[src/main.rs:279] sslot = SlotAddr {
    node: 0,
    slot: 2,
}
[src/main.rs:279] eslot = SlotAddr {
    node: 1,
    slot: 0,
}
dragged(164, 181),(213, 157)
[src/main.rs:279] "dragged between" = "dragged between"
[src/main.rs:279] sslot = SlotAddr {
    node: 0,
    slot: 2,
}
[src/main.rs:279] eslot = SlotAddr {
    node: 1,
    slot: 1,
}
dragged(118, 176),(93, 109)
dragged(602, 431),(610, 407)
dragged(346, 200),(402, 164)
dragged(344, 167),(538, 131)
dragged(443, 150),(443, 150)
dragged(436, 163),(530, 143)
dragged(484, 156),(515, 448)
[src/main.rs:279] "dragged between" = "dragged between"
[src/main.rs:279] sslot = SlotAddr {
    node: 2,
    slot: 0,
}
[src/main.rs:279] eslot = SlotAddr {
    node: 6,
    slot: 1,
}
dragged(561, 394),(647, 521)
dragged(645, 515),(665, 125)
dragged(632, 371),(619, 222)
dragged(604, 343),(599, 234)
dragged(603, 315),(603, 313)
dragged(591, 315),(589, 202)
dragged(515, 396),(580, 512)
dragged(43, 20),(43, 20)
[src/main.rs:279] "dragged between" = "dragged between"
[src/main.rs:279] sslot = SlotAddr {
    node: 8,
    slot: 0,
}
[src/main.rs:279] eslot = SlotAddr {
    node: 8,
    slot: 0,
}
can't link node to self
dragged(374, 352),(376, 402)
dragged(376, 364),(358, 405)
Twenkid commented 1 year ago

I managed to make it crash while connecting:


eval "img_add"
(...)
eval "img_add"
eval "img_add"
eval "img_add"
eval "img_add"
eval "img_add"
eval "img_add"
dragged(330, 324),(351, 172)
[src/main.rs:279] "dragged between" = "dragged between"
[src/main.rs:279] sslot = SlotAddr {
    node: 2,
    slot: 0,
}
[src/main.rs:279] eslot = SlotAddr {
    node: 3,
    slot: 0,
}
thread 'main' panicked at 'index out of bounds: the len is 0 but the index is 0', src/main.rs:377:17
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
Twenkid commented 1 year ago

I tried again to run it on Windows with two methods, but without success so far. Either with installing SDL2 with a vcpkg package manager and with a vcpkg module for Rust, as suggested in: https://github.com/Rust-SDL2/rust-sdl2

Initially I tried to link to the existing .LIB file that I had and finally manually to the lib from vcpkg, but the way which is suggested from SDL2 repo causes errors.

cargo.toml

[dependencies]
serde = "1.0.147"
serde_derive = "1.0.147"
num-traits = {version = "0.2.15"}
sdl2 = {version  = "0.35.2", features=["unsafe_textures"]}
image = { version = "0.23.14", default-features = false, features = ["jpeg","png"] } 

[dependencies.sdl2]
version = "0.35.2"
default-features = false
features = ["ttf","image","gfx","mixer","static-link","use-vcpkg"]

[package.metadata.vcpkg]
dependencies = ["sdl2"]
dependencies= ["sdl2-image[libjpeg-turbo,tiff,libwebp]", "sdl2-ttf", "sdl2-gfx", "sdl2-mixer"]
git = "https://github.com/microsoft/vcpkg"
rev = "261c458af6e3eed5d099144aff95d2b5035f656b"

[package.metadata.vcpkg.target]
x86_64-pc-windows-msvc = { triplet = "x64-windows-static-md" }
cargo build --release
error: failed to parse manifest at `c:\rs\nodewin\Cargo.toml`

Caused by:
  could not parse inpu as TOML

Caused by:
  duplicate key: `dependencies` for key `package.metadata.vcpkg` at line 28 column 1

I couldn't fix it for now.

dobkeratops commented 1 year ago

right in principle SDL2 can be linked in different ways, and should allow Mac,linux,windows builds .. the lining details may vary though. In my main project I rolled my own SDL2 bindings and manually #[cfg()]'d the differences between 3 environments (linux, Mac, and Web - emscripten).
I'll copy those cargo changes in.

I do actually have a windows machine here but dont have it setup conveniently to get to on a regular basis. If I can change this collaboration will be easier. I have used Linux as my main environment for the past decade and stray into the Mac occasionally. The rust community does want to keep windows as a 1st class citizen.

Interesting that you got reasonably far on windows.

I'll remove the "=4" I'm considering changing this design anyway to a 4D image much like the neural net tensors, 'NHWC' format, and just special case "if C==4 .." programatically. Luma images = C=1, RGB= C=3, RGBA C=4, and get rid of the type-safe versions. make an assumption about repeating the last channel when it doesn't match the size of the first one to swap between grey and RGB inputs instead of all the type safe versions.

Regarding it crashing when you link nodes .. yeah all that is in progress, eventually the UI will either prevent you linking them incorrectly, or insert conversion nodes. (eg a float connected to an image could behave as just making an image expanded from that float, connecting an image to a float value could use the image's average intensity, and so on). but initially just preventing the link is easier.

Ultimately I'm not sure how far I wil take this: my original plan was really scrappy personal use UI only (I know all the bugs) - and develop the procedural back end to transplant into the more mature VisMut project - that guy has spent more time on UI, and a parallel execution engine. It should be possible to make the node declaration macro wrap my functions in a way that integrates into his tool

All this is for active experimentation.

I want to take this MUCH further, I have so many ideas to try out, but .. too many ideas to get everything done.

Like the VisMut project, I want to separate out the actual node definitions and processing from the editor UI.

dobkeratops commented 1 year ago

I will also likely write a little renderer layer with a wrapper functions to load a bitmap , draw_line() ,draw immediate mode textured quad, in principle allowing getting rid of the SDL renderer, and using GL instead, there's some other Rust graphics libs aswell suitable for this I think .. I'm just familiar with the lower level SDL bindings and have used SDL or GL successfully across windows/linux/Mac in the past from C++ before.

dobkeratops commented 1 year ago

FYI the update will take a while - a refactor is in progress, once thats done the project will look a bit better - I've actually got the "dont link incorrect nodes" fix in progress along with a single wrapped renderer object.

Twenkid commented 1 year ago

OK. In the meantime, I managed to fix it to compile on Win. :) No lagging of the GUI now. One issue I notice is that it probably idle-cycling?, it seems it loads a whole core while idle.

image

...

The first solution was to remove one of the sdl2 mentions in the .toml, they really were two, then other errors arised.

The final problems were with linking to the .lib file and with the vcpkg tool compiling/building from Rust to the right static target. The solution was: 1) to remove the additional vcpkg Rust dependencies [package.metadata.vcpkg] etc. and leave the original ones only; 2) to copy the .lib file that was produced by vcpkg in its installation directory to the project directory 3) the executable have to be copied into the root dir of the proj., because of the way it searches for the folders with assets (the exe is in node/target/release, while it's hard-coded to search in ./assets/

 let mut font = Font::new(&mut tc, "assets/font16.png", ...

Assets Paths - Config and Helper Libraries to search for files

These paths are always a little annoying thing to set up in experimental projects etc., they're more convenient with a simple config-file, a command line option and/or a GUI or an option to load it with a key from the program etc.

In general that may be more convenient with some helper library that searches for alternative folders or just "look around" and adjusts itself and do not directly open files.

I think once I made something like that for one of my projects, a bit smarter file opener. If you try to open something in one directory and it doesn't find it, it guesses to search in several other expected folders, or moves up, down etc. in the tree, until it finds the target file, or it may read the first of that type that it finds (e.g. jpg, png), especially if it's media, used for a texture or sample input, instead of immediately crashing.

Going even further, there could be a more systematic search in the file system, a cache with recently accessed files etc.

dobkeratops commented 1 year ago

I might be able to compile the font in there binary (incbin!), it shouldn't need many assets.. just data coming in what you edit