OHIF / Viewers

OHIF zero-footprint DICOM viewer and oncology specific Lesion Tracker, plus shared extension packages
https://docs.ohif.org/
MIT License
3.08k stars 3.25k forks source link

How to add 3D button with its features #2394

Closed MongiBr closed 10 months ago

MongiBr commented 3 years ago

I need to add a button 3d to Ohif viewer app vtk viewport mpr2D button i want to change it to 3D Button Someone help me please!

ArturRod commented 3 years ago

@MongiBr Hello, I have managed to apply a 3D button using https://react-vtkjs-viewport.netlify.app/. I have reused the MPR 2D button function and using the code from https://react-vtkjs-viewport.netlify.app/volume-rendering. You can see the code from Sources. Then upload the images by ID and it works. image

ed-morais commented 2 years ago

Hello, @ArturRod! I'm a student with little experience with VTK and OHIF. I've been trying to do the same thing as you did, but I don't know how exactly to do it. Could you tell me where can I find the MPR 2D and what code from sources I should use?

ArturRod commented 2 years ago

Hello, @ed-morais, let me tell you, you have the codes for the 3D generation here, you will only have to adapt it with your IDs of the images of your PACS. -> https://github.com/OHIF/react-vtkjs-viewport/tree/master/examples (I in this case use VTKVolumeRenderingExample.js, and presets.js is also necessary). On VTKVolumeRenderingExample.js -> From this class you have to adapt to load the IDs of the images. You have to implement that class in your code and make it call from a new button, for this I loaded a new event in commandsModule.js ->

render: {
      commandFn: actions.render,
      storeContexts: ['viewports'],
      options: {},
      context: 'VIEWER',
},
-------------------------------------------------------------------------
    render: async ({ viewports }) => {
      const displaySet =
        viewports.viewportSpecificData[viewports.activeViewportIndex];
      const viewportProps = [
        {
          orientation: {
            sliceNormal: [0, 0, 1],
            viewUp: [0, -1, 0],
          },
        },
      ];
      try {
        await setMPRLayout(displaySet, viewportProps, 1, 1);
      } catch (error) {
        throw new Error(error);
      }
      const vistaActivada = Array.from(
        document.getElementsByClassName('vtk-viewport-handler')
      );
      vistaActivada[0].innerHTML = '';
      ReactDOM.render(<Render3D />, vistaActivada[0]);
      Render3D.botones(false);
    },

TolbarModule create Button 3D: { id: '3D', label: '3D', icon: 'cube', type: TOOLBAR_BUTTON_TYPES.COMMAND, CustomComponent: VTKMPRToolbarButton, commandName: 'render', context: 'ACTIVE_VIEWPORT::CORNERSTONE', }, As you can see, duplicate the event from 2D and adapt them for the 3D view. I hope I can help you with this, you can ask me any questions.

ed-morais commented 2 years ago

The 3D render is now working perfectly. Thank you so much, @ArturRod! :)

ed-morais commented 2 years ago

Hello again, @ArturRod! I've been able to adapt the code to load the IDs, but I think I didn't manage to do it properly. Every time I click on a different study or series I need to reload the page so the 3D render can display the right image. I have tried to pass the data from the commandsModule.js (displaySet.StudyInstanceUID, displaySet.SeriesInstanceUID) via props to the VTKVolumeRenderingExample.js How did you manage to adapt the code so there is no need to reload the page?

ArturRod commented 2 years ago

Hi @ed-morais, the same thing happened to me too. It is a react-vtkjs-viewport problem, the problem is that the internal map generated by react-vtkjs-viewport cannot be updated, that is, it generates a cache but does not delete it. To solve it you have to do the following:

  1. React-vtkjs-viewport needs to be recompiled with a slight modification. To do this, download: https://github.com/OHIF/react-vtkjs-viewport
  2. Once you have it downloaded you will have to modify these files so that you can clear the cache: image
  3. Once you have it, compile it again, and it will generate the file index.umd.js
  4. When you have it, copy it into your project, overwriting the one you already have:OHIF/node_modules/react-vtkjs-viewport-master-master\dist.
  5. With this it will work for you, now you just have to call imageDataCache.clear (); in loadDataset, so it will clear the cache every time you load the data. image

The only problem is that every time you compile your project with yarn install again, you will have to copy the index.umd.js file I already mentioned this in react-vtkjs-viewport, their thing would be to put this in a committee and add it definitively.

I hope I have helped.

NicholasDascanio commented 2 years ago

Hi @ed-morais and @ArturRod ! Thanks both for these suggestions. I've applied your modifications and everything works. I've also inserted the coding for extracting the studyInstanceUID of the current study, by using studyMetadataManager. There is only one problem I haven't been able to solve yet, which is extracting SeriesInstanceUID parameter too. @ed-morais you mentioned you managed to pass the data from the commandsModule.js (displaySet.StudyInstanceUID, displaySet.SeriesInstanceUID) via props to the VTKVolumeRenderingExample.js . Can you please share the code?

Thanks again

ArturRod commented 2 years ago

Hello @NicholasDascanio! What I have put in the code to be able to obtain the UIDs, is to save the urls in localStorage with a viewer ID activated. So when I want to access I always have the UID available, then I have methods so that the local storage does not fill up and is cleaned every time you change your view. (I only save in localstorage the UIDs of the series that are in the views). This I have implemented in getViewportData: image I get the index from -> let index = this.props.viewportIndex;

Later in the 3D class, in the method -> createStudyImageIds I get the data of the selected view: image

NicholasDascanio commented 2 years ago

Hello @ArturRod !! Everything works now, thanks a lot! Your help has been precious :)

NicholasDascanio commented 2 years ago

Hello again @ArturRod !! I was wondering if you could help me out with an issue related to #2180 . I've add the 3D button and it's working perfectly thanks to your suggestions. However, I wanted to create a new toolbar for the 3D functionality with just an exit button, since the one i've used so far it's equal to the MPR one (which is obvious since the functionality is implemented in the VTK extension).

After having add a new context here (platform/viewer/src/context/AppContext.js), I tried to modify VTK extension toolbar, having no effects. Then I tried to create another extension (VTK-3D), equal to the VTK one except for the fact that it should use just 1 button and a different defaultContext, but i haven't managed to make it work, even though it gives me no error.

Do you have any idea about how to proceed? :)

ArturRod commented 2 years ago

Hello @NicholasDascanio What I did is a bit of a 'fix' since what I really do is generate the 2D view and then hide and modify the buttons. When I open I call this method true or false depending on whether I am going to hide or show the data:

//Makes the buttons visible or invisible, if true they are activated: image

Activado it is a global variable that has to be where you are going to put this method.

NicholasDascanio commented 2 years ago

Hello again @ArturRod ! Thanks a lot for the insights!! Basing my solution on your suggestions, I've solved every problem :)

Future-Zlb commented 2 years ago

Hello @ArturRod According to your steps, I have added 3D buttons. At this time, I want to freely control the window width and level of 3D view. What should I do with the same window width and level function as the MPR toolbar?

ArturRod commented 2 years ago

Hello @zlb8888 ! I don't know if this is what you mean? If not, let me know, since I still misunderstood about the levels or the width.

Currently do not modify the width and height of the window for the 3D view, leave it as the 2D MPR. But I think that the best solution in this case would be to modify the main canvas from js, that is, modify the structure of the view to your own, this will have to be done with some method. There is also the option that if you didn't want to modify the 2D MPR window and transform it to 3D, you could create a 3D button and make it open a new 3D view -> window.open (url," name of window "," width = 300, height = 200 ") These are some ideas that I can give you, I hope I can help you 😊

Future-Zlb commented 2 years ago

Hello again @ArturRod Thank you for your reply.I'm sorry. Maybe I didn't make myself clear.

At present, the window level can only be adjusted through the CT preset value of the existing 3D, that is, the window level can be set by writing the dead data in presets.js. // WWWC image

But what I want to do is to have the same effect as the WWW tool in the 2D MPR toolbar. The left mouse button can adjust the size of window level.

// Modified preset window level. image

tried this method, but it didn't work. image

Have you ever encountered such a problem?

ArturRod commented 2 years ago

Hello again @Zaid-Safadi Bffff ..... well this in particular I have not tried. I understand that what should be done is a contextual menu, which is activated if you have the WWWC button activated and modify the button event with the list of presets.js. Maybe this can help: https://www.youtube.com/watch?v=RHQfmpBEKf8&ab_channel=Codingflag You would have to apply what has been said, that when the WWWC is activated, the contextual menu with the pretests is put, I think it is quite simple to implement, and a good idea! For now I have it with the list, maybe I will implement it like you, since I liked the idea.

Future-Zlb commented 2 years ago

Hello again @ArturRod Thank you for your advice.

ed-morais commented 2 years ago

Hello! @ArturRod @NicholasDascanio I've been trying to pass data via props, but I think that's not the best way to do it, so I'm trying to implement the code the way you did, but I'm having some issues.

Here is the code using props:

commandsModule.js image

Render3D.js image image

First I tried to recompile react-vtkjs-viewport keeping the props and call imageDataCache.clear(); in loadDataset, but it didn't work. An error occurred after I changed the original index.umd.js for the recompiled one. And I think it may be because I'm using props.

Screenshot from 2021-10-20 11-35-26

Now I'm trying to get the StudyUID and SeriesUID the way you did, but I'm not sure in which file getViewportData is located and where I need to put the "let index = this.props.viewportIndex;" in the code.

I would really appreciate your help :)

NicholasDascanio commented 2 years ago

Hi @ed-morais ! I've not used props, I've used the localStorage workaround in the end.

In particular, I've put the "StudyInstanceUID" and "SeriesInstanceUID" into it (through the localStorage.setItem method ). You can do it basically everywhere: I personally do it in VTK3DToolbarButton, which is a customized version of VTKMPRToolbarButton.js for the 3D rendering, located in extensions/vtk/src/toolbarComponents.

Then, I'm able to retrieve them into Render3D.js (through the localStorage.getItem method). Afterwards, I delete these parameters, to keep the localStorage clean.

I don't know if it's the best workaround, but it works. I hope it'll work for you as well :)

ArturRod commented 2 years ago

Hi @ed-morais Indeed, as @NicholasDascanio comments, the problem may be due to the fact that the IDs of the images are not recovered well. That's why I decided to put it in localStorage and as @NicholasDascanio comments you can use it whenever you want. I take advantage of and also use it to generate reference lines or other tools that require a stackID of images. Then with what controls that only the data that is visible on the screen is saved in localStorage and the rest is deleted ... so that the memory is not full would be valid. I know it's not the best option, but for now it works fine :)

ed-morais commented 2 years ago

Thank you so much! @ArturRod @NicholasDascanio Everything is working just fine right now (:

ranasrule commented 2 years ago

Thank you so much! @ArturRod @NicholasDascanio Everything is working just fine right now (:

@ArturRod @ed-morais @NicholasDascanio would you please share your build of OHIF with 3D features?

ArturRod commented 2 years ago

Hi, @ranasrule Sorry but I can't upload a version with the changes publicly. Help how to implement 3D with code snippets and manuals, but I can't upload that version. If you have any questions, here it is explained how 3D can be activated, the other colleagues have achieved it 😊

ranasrule commented 2 years ago

Would you be willing to do it on a commercial basis?

On Thu, Nov 11, 2021, 4:26 PM Arturo Rodrigo @.***> wrote:

Hi, @ranasrule https://github.com/ranasrule Sorry but I can't upload a version with the changes publicly. Help how to implement 3D with code snippets and manuals, but I can't upload that version. If you have any questions, here it is explained how 3D can be activated, the other colleagues have achieved it 😊

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/OHIF/Viewers/issues/2394#issuecomment-966225480, or unsubscribe https://github.com/notifications/unsubscribe-auth/ABGKNOZHS5LOIWL62MOL2HLULOR7TANCNFSM44BTVXYA . Triage notifications on the go with GitHub Mobile for iOS https://apps.apple.com/app/apple-store/id1477376905?ct=notification-email&mt=8&pt=524675 or Android https://play.google.com/store/apps/details?id=com.github.android&referrer=utm_campaign%3Dnotification-email%26utm_medium%3Demail%26utm_source%3Dgithub.

ed-morais commented 2 years ago

Hello, @ArturRod @NicholasDascanio!

Now I'm trying to remove the buttons from the 3D toolbar. In fact, the code is working just fine removing the buttons from the 3D toolbar but the problem is: when I go back to the previous page or click the 2DMPR function the buttons removed in the 3D function are still removed. Something similar occurred to you guys, and do you have a clue on how to fix it?

When all buttons are visible: Screenshot from 2021-11-18 12-34-56 Clicking the 3D function: Screenshot from 2021-11-18 12-35-24 After clicking the "Sair do 3D" button: Screenshot from 2021-11-18 12-35-35 Some buttons missing in the 2DMPR as well: Screenshot from 2021-11-18 12-35-45 This is the code I'm using: Screenshot from 2021-07-20 11-40-20 I didn't get what lines 30 and 31 are doing and also there's an error in the console related to the line 31 Screenshot from 2021-11-18 13-25-04

Thank you for your time :)

ranasrule commented 2 years ago

Hello, @ArturRod @NicholasDascanio!

Now I'm trying to remove the buttons from the 3D toolbar. In fact, the code is working just fine removing the buttons from the 3D toolbar but the problem is: when I go back to the previous page or click the 2DMPR function the buttons removed in the 3D function are still removed. Something similar occurred to you guys, and do you have a clue on how to fix it?

When all buttons are visible: Screenshot from 2021-11-18 12-34-56 Clicking the 3D function: Screenshot from 2021-11-18 12-35-24 After clicking the "Sair do 3D" button: Screenshot from 2021-11-18 12-35-35 Some buttons missing in the 2DMPR as well: Screenshot from 2021-11-18 12-35-45 This is the code I'm using: Screenshot from 2021-07-20 11-40-20 I didn't get what lines 30 and 31 are doing and also there's an error in the console related to the line 31 Screenshot from 2021-11-18 13-25-04

Thank you for your time :)

@ed-morais would you please share your build of OHIF with 3D features? I'm also willing to pay for it if you like.

ArturRod commented 2 years ago

Hi @ed-morais and @ranasrule Indeed, the problem I see is that the previous state is not returned to the buttons. You have to make sure that when you exit you call this method: static buttons (activate) { being activate true; Since that's how it rebuilds the buttons. In case it does not detect let view = document.getElementsByClassName ( 'viewport-drop-target viewport-container active' ); You will have to check why you do not select the activated viewport. You must control the possible errors that the 3D may have, since if there is an error when generating it, you will have to call this method of buttons, because it will automatically exit the 3D. (This as a recommendation)

halitince commented 2 years ago

hello @ArturRod

i cant found Render3D.js

ArturRod commented 2 years ago

Hi @halitince The Render3D class is the name that I have given it, the original is this -> https://github.com/OHIF/react-vtkjs-viewport/blob/master/examples/VTKVolumeRenderingExample.js

halitince commented 2 years ago

Hi @ArturRod Would you contact me. I have a few question.

https://www.linkedin.com/in/halit-ince-aa809266/

jlurie98 commented 2 years ago

@ArturRod can you also contact me regarding this I have a question! My email is jordynnmlurie@gmail.com

ArturRod commented 2 years ago

Hi @jlurie98 You can ask the question here better, so if someone has the same question, they will find the answer now!

jlurie98 commented 2 years ago

Hi Arturo!

I'm trying to implement the 3D VTK Volume rendering button, and I understand how to add your code into toolbarModule.js and commandsModule.js but am unclear on where to add the VTKVolumeRenderingExample.js code. The react-vtkjs-viewport folder that came with the ohif viewer in node_modules pretty much only contains a file called index.umd.min.js with various functions in it. I tried downloading react-vtkjs-viewpor independently from the ohif download and replacing the original react-vtkjs-viewport, but this doesn't work. Let me know if you'd like me to clarify anything.

All the best, Jordynn

On Tue, Mar 8, 2022 at 4:32 AM Arturo Rodrigo @.***> wrote:

Hi @jlurie98 https://github.com/jlurie98 You can ask the question here better, so if someone has the same question, they will find the answer now!

— Reply to this email directly, view it on GitHub https://github.com/OHIF/Viewers/issues/2394#issuecomment-1061579026, or unsubscribe https://github.com/notifications/unsubscribe-auth/AXTDMODBYIYLY7UTFM5FVI3U64NDFANCNFSM44BTVXYA . Triage notifications on the go with GitHub Mobile for iOS https://apps.apple.com/app/apple-store/id1477376905?ct=notification-email&mt=8&pt=524675 or Android https://play.google.com/store/apps/details?id=com.github.android&referrer=utm_campaign%3Dnotification-email%26utm_medium%3Demail%26utm_source%3Dgithub.

You are receiving this because you were mentioned.Message ID: @.***>

-- Jordynn Lurie | Columbia Engineering M.S. Biomedical Engineering @.*** | (954) 789 8395

ArturRod commented 2 years ago

Hi @jlurie98 I tell you, the VTKVolumeRenderingExample.js file along with presets.js (https://github.com/OHIF/react-vtkjs-viewport/tree/master/examples) that you download, you have to put that in your project (where your you prefer) simply that it is in your project and adapt it, then you have to initialize it, that is, you can have it in the folder you prefer, the fact is that you can call it later to initialize it. About react-vtkjs-viewport what you have to do is download it independently, modify it and compile it, it will generate an index.umd file, you will copy that in node_modules\react-vtkjs-viewport\dist (only the file, you don't have to copy all the folder), I leave you attached in case you need the project with the changes made: https://github.com/ArturRod/react-vtkjs-viewport-master

jlurie98 commented 2 years ago

Thank you so much Arturo! A few more questions. How exactly do I compile to generate this index.umd file? And will I need the index.umd.min file as well?

On Thu, Mar 10, 2022 at 4:26 AM Arturo Rodrigo @.***> wrote:

Hi @jlurie98 https://github.com/jlurie98 I tell you, the VTKVolumeRenderingExample.js file along with presets.js ( https://github.com/OHIF/react-vtkjs-viewport/tree/master/examples) that you download, you have to put that in your project (where your you prefer) simply that it is in your project and adapt it, then you have to initialize it, that is, you can have it in the folder you prefer, the fact is that you can call it later to initialize it. About react-vtkjs-viewport what you have to do is download it independently, modify it and compile it, it will generate an index.umd file, you will copy that in node_modules\react-vtkjs-viewport\dist (only the file, you don't have to copy all the folder), I leave you attached in case you need the project with the changes made: https://github.com/ArturRod/react-vtkjs-viewport-master

— Reply to this email directly, view it on GitHub https://github.com/OHIF/Viewers/issues/2394#issuecomment-1063843161, or unsubscribe https://github.com/notifications/unsubscribe-auth/AXTDMOHIUAHF5UJ4FQTWPF3U7G55HANCNFSM44BTVXYA . Triage notifications on the go with GitHub Mobile for iOS https://apps.apple.com/app/apple-store/id1477376905?ct=notification-email&mt=8&pt=524675 or Android https://play.google.com/store/apps/details?id=com.github.android&referrer=utm_campaign%3Dnotification-email%26utm_medium%3Demail%26utm_source%3Dgithub.

You are receiving this because you were mentioned.Message ID: @.***>

-- Jordynn Lurie | Columbia Engineering M.S. Biomedical Engineering @.*** | (954) 789 8395

ArturRod commented 2 years ago

@jlurie98 You have to compile the project with 'yarn run build' and it will generate the file in the 'dist\' folder No, only index.umd is needed, the .min file is not needed.

jlurie98 commented 2 years ago

Great, I was able to compile the new react-vtkjs-viewports module! However, when I select the 3D button for a study, it does not show the volume rendering. I figure I need to set the current study/series through localStorage.setItem and retrieve it through localStorage.getItem, but I'm unclear on how to actually implement this. Thanks again for all your help so far!

On Fri, Mar 11, 2022 at 2:54 AM Arturo Rodrigo @.***> wrote:

@jlurie98 https://github.com/jlurie98 You have to compile the project with 'yarn run build' and it will generate the file in the 'dist' folder No, only index.umd is needed, the .min file is not needed.

— Reply to this email directly, view it on GitHub https://github.com/OHIF/Viewers/issues/2394#issuecomment-1064862059, or unsubscribe https://github.com/notifications/unsubscribe-auth/AXTDMOGXRGUDBKYBNQHKLB3U7L32XANCNFSM44BTVXYA . Triage notifications on the go with GitHub Mobile for iOS https://apps.apple.com/app/apple-store/id1477376905?ct=notification-email&mt=8&pt=524675 or Android https://play.google.com/store/apps/details?id=com.github.android&referrer=utm_campaign%3Dnotification-email%26utm_medium%3Demail%26utm_source%3Dgithub.

You are receiving this because you were mentioned.Message ID: @.***>

-- Jordynn Lurie | Columbia Engineering M.S. Biomedical Engineering @.*** | (954) 789 8395

mbilalsh commented 2 years ago

@ed-morais Hi Ed. Can you share your code.

eva-pomposo commented 2 years ago

Hello @ArturRod @ed-morais ! I'm trying to implement a 3D feature. I add the files VTKVolumeRenderingExample.js, presets.js and initCornerstone.js. But it's not working correctly. image

image

Can you please help me?

ArturRod commented 2 years ago

Hi @eva-pomposo To do this, as we mentioned in the previous steps, you have to duplicate the 2D MPR button and adapt the views for 3D, there are quite a few steps that need to be done but everything is documented in this forum. You have to adapt your elements to your visor.

eva-pomposo commented 2 years ago

@ArturRod I've already managed to implement the 3D functionality, but I was always looking for the same study.

So I tried to do like @NicholasDascanio and put the "StudyInstanceUID" and "SeriesInstanceUID" in localStorage, in the VTKMPRToolbarButton.js file: image

Then in the VTKVolumeRenderingExample.js file I will get these IDS: image image image

But then in 3d square images appear, or sometimes the image doesn't even appear: image image

Will you be able to help me? Thanks.

ArturRod commented 2 years ago

Hi @eva-pomposo In loadDataset the localStorage cache is not deleted, the 3D view cache is deleted, so that it does not always show the same image, to be able to do this you have to modify the react-vtkjs-viewport and recompile it, I explained this in previous lines. image

eva-pomposo commented 2 years ago

@ArturRod I've already did it, but instead modify the react-vtkjs-viewport, I modify in my project, and when I click in 3D appears always "Loading...": image

ranasrule commented 2 years ago

would someone be kind enough to share a compiled build of OHIF with 3D features implemented? I would be willing to pay if required.

MurilosSampaio commented 2 years ago

Did somebody manage to add a different widget? I'm trying to add a volumeClipPanel following the example in vtkjs page (https://kitware.github.io/vtk-js/examples/VolumeClipPlane.html).

I'm trying to add as a function that renders the clipPlane as the user changes the range sliders, so far didn't accomplish any significant progress.

mateozaratefw commented 1 year ago

The 3D render is now working perfectly. Thank you so much, @ArturRod! :)

Hi! where do you pasted the code? thank you!

EVAKKKK commented 1 year ago

Hello @ArturRod I have now implemented the function of activating 3D, but I don't know where is the getViewportData you mentioned, and how to do 3d rendering of the locally uploaded pictures.

ArturRod commented 1 year ago

Hi @EVAKKKK getViewportData It is inside OHIFCornerstoneViewport.js, inside this statement we will save the necessary data in local storage: let index = this.props.viewportIndex; let textoGuardado = 'viewportData' + index; localStorage.setItem(textoGuardado, JSON.stringify(viewportData));

fadjar340 commented 1 year ago

Hi...

I already follow the instructions above including using localstorage configuration, but I have error in the browser console as follow: image

Is there any part of the instructions is wrong?

Regards, Fadjar340

EDIT: I can manage it and working flawlessly at the moment

kratos46 commented 1 year ago

Hello, can anybody help me to implement volume 3D in Ohif Viewer 3?