[FR] 3D Model Viewer
Please verify that this feature request has NOT been suggested before.
- [x] I checked and didn't find a similar feature request
Problem statement
It would be really nice to be able to view 3D models that are attached to parts.
Suggested solution
Option 1
Under attachments you could click the more actions and if the attachment was a supported 3D file you could choose the option to view it in a 3D viewer. Once in the viewer you could then take a 'capture' of the current view and set it as the part image.
Option 2
In the main part view you could upload a 3D model instead of a static image. You could then click on the image to open a 3D model viewer, rotate/manipulate the model to your liking and then 'capture' the current view and set it as the part image.
Describe alternatives you've considered
Not having a 3D viewer :)
Examples of other systems
I have found the Online3DViewer project that should aid in developing a solution. Although I'm not a frontend developer (or even a professional developer) it didn't look too difficult to implement (easy to say I know) in a webpage. They even give their whole site as part of the source files.
If I had time I might even look at adding it myself, but currently I have too many unfinished projects and I don't want to commit to another one. I don't think this would be a high priority feature, but it would be nice to have.
Do you want to develop this?
- [ ] I want to develop this.
This would be an ideal candidate to be developed as a plugin. @RedEchidnaUK would this be something you would be interested in developing?
@SchrodingersGat I’m going to reluctantly say no to developing a plugin. Sadly, I really don’t have time at the moment due to other projects I’m committed to. Of course if that changes, I’ll be sure to let you know.
@SchrodingersGat It would be really cool, if we would extend the plugin system to provide custom previewers for various file types. E.g. this would be helpful for your wirewiz plugin too, or an inline pdf previewer, ...
Having done a bit more searching I see there is already a FR for preview for attachment files that I missed in my previous search. Would it make more sense that this request is part of that FR?
I do not think that would cover it, that will probably be addressed by making thumbnails available
Just to update this, I’ve had a bit of free time and I’ve had a bit of a play about and I think I might be able to create a plugin to preview certain 3D CAD files.
I’ve no idea how long it will take me as I’m not very familiar with React and Typescript etc. and a 3D viewer is probably quite an ambitious thing to start with… I have also found out that the viewer I linked above is so poorly documented it’s almost impossible to work with for a newcomer. However, I still have a plan and a very basic proof of concept working, so there is still hope!
One question I do have, which version of React does Inventree use? It looks like React 18.3.1 from looking at the frontend package.json and the plugin creator seems to specify 18.3.18 in its package.json. However, I somehow ended up with React 19 when I used the creator? This could be (probably is) something I’ve inadvertently done.
@RedEchidnaUK good point regarding react version - the plugin creator should be pinned to use the same version! I'll look into this, likely a bug with the creator itself.
https://github.com/inventree/plugin-creator/issues/26
I’m getting close to having something working, but I have a question I’m hoping you can help with.
At some point I’m going to want to get a list of the attachments of the part and send them to my React component. This seems simple enough, but if I want my React component to send data back, such as a new image for the part, how would I go about it?
I thought I would just use the API directly, but from what I’ve read the user would have to sign in again to get an access token, which doesn’t seem great from a UX point. I’m probably looking at the problem wrong, and apologies if it seems simple, but I’m really not used to working with web based apps. If I’ve missed some documentation, feel free to point me at it. Thanks.
@RedEchidnaUK great question! The front-end plugins get passed a lot of context data - including the currently active API object which is already authenticated against the server.
You can use this API object to make requests to the server without any other auth interactions with the user.
Check out how the inventree-order-history plugin achieves this, for example:
https://github.com/inventree/inventree-order-history/blob/2f8287254283cd87a7e5fb45c91c5954b3405f4a/frontend/src/OrderHistoryPanel.tsx#L223
const historyQuery = useQuery(
{
queryKey: [
'order-history',
startDate,
endDate,
period,
orderType,
context.id,
context.model,
],
refetchOnMount: false,
refetchOnWindowFocus: false,
queryFn: async () => {
return context.api?.get(`/${ORDER_HISTORY_URL}`, {
params: queryParams,
}).then((response: any) => {
return response.data;
}).catch(() => {
return [];
}) ?? [];
}
},
queryClient
)
@SchrodingersGat thank you for the detailed answer. I had looked at a few plugins, but had completely missed that nugget of information. That should give me everything I need. Thanks for the help.
If you find any details that would be good to include in the docs please submit a PR to the documentation :)
What I think would be nice, from a documentation point of view, is a walkthrough of developing a simple plugin. Using the generator, create a panel plugin example, get information via the api, display the information, push data/a file back, how to enable support for light/dark mode etc.
I fully appreciate as developers this might not be the best use of your time, especially as I know you’re working really hard to get to 1.0.0. and documentation is the least fun part. Perhaps if I ever get to a point where I can do all of those things and no one has beaten me to it, I’ll give it a go and do a PR.
@RedEchidnaUK a "plugin development guide" has been on my wishlist for some time. But, only so many hours in the day! If you do find some time to add something to this effect, it would be greatly appreciated!
Getting ever closer to a beta release as I now have a basic, but functional, 3D viewer with controls and a panel with an API call working. I just need to marry the two together when I get time (@SchrodingersGat I know what you mean about only so many hours in the day!) One thing I’m not sure on, is how to get the base url of the site to combine with the returned attachment url. Unless I’m wrong, the API doesn’t seem to provide it. Any hints on where I’ve missed it would be much appreciated.
Edit: Sorry, I think you can ignore this question, it’s in the context RTFM! (I’m sure it wasn’t there earlier…)
Hopefully this will be the last question for a while (no promises 😄 ), and again apologies if it's stated somewhere and I've missed it.
It looks like you can get the base url from context, e.g.
console.log("BaseUrl: ",context.globalSettings.getSetting("INVENTREE_BASE_URL"));
However, I've noticed you can also get the host from context, e.g.
console.log("Host: ",context.host);
I'm guessing these are two different things? If they are, when would you use one over the other?
Thanks.
They are subtly different but I think for most purposes they should be the same.
INVENTREE_BASE_URLis the server's view of what it's URL is- 'host' is the client's address to connect to the host
Nominally they should be the same
Thanks @SchrodingersGat
@SchrodingersGat At the chance of out staying my welcome...
How would I get all of the attachments for a part from the Python backend? I can successfully do it via the API on the frontend, but it feels like that might not be the correct way on the backend. I've tried reading about mixins etc. as well as looking at the documentation and source code, but I'm not that experienced with Python (or at least not in the context Inventree uses it) and I'm probably more confused than when I started... Any pointers, once again, gratefully received.
I'll assume that you have the part instance available (i.e. the single part that the user is viewing).
so in python (server side) you can simply call:
attachments = part.attachments
This is because the Part Model inherits from the InvenTreeAttachmentMixin class which provides the attachments property
Once again, thanks @SchrodingersGat That is a lot easier than I was expecting. I’ll try and give it a go tonight!
I've finally had time to get it to a point that is good enough for a beta release! https://github.com/RedEchidnaUK/inventree-3d-viewer
Known issues
- It only supports STL and GLB files (the core engine is capable of supporting many more formats)
- It has to be built and installed via the
pluginsdocker folder (that's how I've been working with it and I'm not yet up to speed on the other install methods) - I have witnessed it causing the Inventree browser tab to slow to a crawl and become unusable until the tab is refreshed (even when not on the part/plugin panel). I've only seen it happen in the Ubuntu VM I develop in, so it could be an issue with the VM and its virtual graphics card. If anyone else sees this behaviour please let me know. I've no idea where to begin to fix it, but at least I will know it's not just a one off.
This looks pretty interesting. Thank you for creating such a plugin. I wonder if me may create a new frontend feature that is specific for attachment preview so that we don't have to add lots of panels for each type. That way we may could add a click on an attachment row in the existing panel, that opens a modal with a preview provided by a plugin. This could then be implemented for pdfs, images, kicad files (I think there was a js rendering engine developed as OSS a while ago), wirewiz, ... I think I already explained that idea in an issue before.
@RedEchidnaUK that looks awesome! Very nice work indeed. When you are ready for "release" we can add it to the inventree website for visibility.
that's how I've been working with it and I'm not yet up to speed on the other install methods
Releasing to pypi is pretty straight forward with the plugin creator. Happy to help walk you through that process if you like!
I have witnessed it causing the Inventree browser tab to slow to a crawl and become unusable until the tab is refreshed (even when not on the part/plugin panel)
I would be interested to see if this is due to rendering (on the frontend) or if it takes a long time to process the plugin panel request (backend).
This looks pretty interesting. Thank you for creating such a plugin. I wonder if me may create a new frontend feature that is specific for attachment preview so that we don't have to add lots of panels for each type. That way we may could add a click on an attachment row in the existing panel, that opens a modal with a preview provided by a plugin. This could then be implemented for pdfs, images, kicad files (I think there was a js rendering engine developed as OSS a while ago), wirewiz, ... I think I already explained that idea in an issue before.
I agree that this concept would be best served as a "preview" panel pop-out from the "attachments" page. Rather than a separate main panel. @wolflu05 do you want to look into developing a new frontend UI feature type if you have time?
It would be reasonably easy to migrate the functionality of this plugin to the preview pane once available.
Unfortunately, I won’t have time to develop this in the next months and its not my priority. I'd be happy if someone else has the time to develop this new frontend UI feature integration.
@wolflu05 and @SchrodingersGat thank you for the support and encouragement.
I agree, it would be awesome to have it as part of a 'preview' system directly in the attachment panel as that would open up so many file preview options. Sadly at this stage, it's probably beyond my knowledge to make those sorts of changes to Inventree.
@SchrodingersGat Thank you for the offer of assistance for PyPi once I get to release.
The thing that's holding me back making an official release at the moment is this slowdown issue. My gut is telling me it is a frontend issue and I only really see it from within my VM. If I browse the VM hosted instance from an external browser it almost works 100%. Inventree doesn't seem to suffer with slowdowns, but the 3D model drops frames when you start rotating/zooming... but then that only happens when you open another part, the first load is fine... very odd.
You may want to test if you only experience this error in dev mode or also in a react production build.
@wolflu05 Sorry, I probably should have been clearer. I’m doing the development work in a VM, but Inventree is running as a production Docker environment, so it is a production build. I do need to see if I get the same issue running just as a React build outside of Inventree.
So your not using the react dev server for your plugin panel at all? You're always build a react prod bundle and then see the changes after manually reloading the page?
@SchrodingersGat Is that not implemented in the plugin template? (React HMR directly inside the plugin panel) That was the first thing I setup on my plugins (haven't used the plugin creator yet).
@wolflu05 Correct. It’s not a very efficient way to work and I really should get the dev environment up and running properly. Most of the panel work was actually done outside of Inventree and then simple ported over to a plugin panel. As all the React code needs are the attachment urls from Inventree, which I do via the context.