[prev in list] [next in list] [prev in thread] [next in thread] 

List:       vtkusers
Subject:    Re: [vtkusers] Java multi-thread and model Observer
From:       Sebastien Jourdain via vtkusers <vtkusers () vtk ! org>
Date:       2019-02-22 18:08:33
Message-ID: CABObKxe4Kk8cTM5xFYYLnwE5RYRgW_aOW2ez3nbWv6__aW3x7g () mail ! gmail ! com
[Download RAW message or body]

[Attachment #2 (multipart/alternative)]


Hi Jean-Max,

I'm not sure to follow all the details of your implementation or why you
still have the use of a Timer.
The only things that you need to worry about is that any rendering action
(addActor/removeActor, update when actor connected, render) MUST BE in the
EDT.

HTH,

Seb

On Thu, Feb 21, 2019 at 2:19 AM Jean-Max Redonnet <jmax.red@gmail.com>
wrote:

> Hello everyone !
>
> I'm using vtk throught its java wrapper and I'm setting up a versatile
> viewer that can display an existing model and update display when this
> model is updated (and it will be continously updated).
>
> My Model is built around few classes: VtkObject that is the ancestor of
> many other classes like VtkSurface, VtkCurve, etc... and VtkModel that
> basically contains a list of VtkObjects and maintain Listeners. All these
> classes are of my own (please note uppercase "V" on VtkObject)
>
>
> public class VtkObject{
>     protected final PropertyChangeSupport pcs = new
> PropertyChangeSupport(this);
>     protected List<vtkActor> actors = new ArrayList<vtkActor>();
>     ...
> }
>
> public class VtkSurface extends VtkObject {
>     private vtkActor surfActor;
>     ...
> }
>
> public class VtkModel implements PropertyChangeListener{
>     protected List<VtkObject> objects;
>     protected PropertyChangeSupport support;
>     ...
> }
>
> For the viewer itself I wrote a VtkPanel that is mostly inspired by the
> example provided by SĂ©bastien Jourdain (
> https://github.com/Kitware/VTK/blob/master/Wrapping/Java/vtk/sample/Demo.java
> )
>
> I just make this panel model-aware implementing PropertyChangeListener:
>
>     @Override
>     public void propertyChange(PropertyChangeEvent evt) {
>         if (evt.getPropertyName() == "AddedObject") {
>             System.out.println("Added Object");
>             VtkObject o = (VtkObject) evt.getNewValue();
>             if(o.getActors().size()>0)
>                 exec.submit(new PipelineBuilder(o));
>         }
>         if (evt.getPropertyName() == "UpdatedObject") {
>             System.out.println("Updated Object");
>             VtkObject o = (VtkObject) evt.getNewValue();
>             if(o.getActors().size()>0)
>                 exec.submit(new PipelineBuilder(o));
>         }
>     }
>
> and slithly modify PipelineBuilder to make it able to manage VtkObjects
> that may contain several vtkActors
>
>     public class PipelineBuilder implements Callable<vtkActor> {
>         private int counter;
>         private List<vtkActor> actors;
>
>         public PipelineBuilder(VtkObject o) {
>             actors = o.getActors();
>             counter = 0;
>         }
>
>         @Override
>         public vtkActor call() throws Exception {
>             counter++;
>             if (counter < actors.size() + 1)
>                 return actors.get(counter - 1);
>             return null;
>         }
>     }
>
> Also, workers are setup to continously search for new actors:
>
>     private void setupWorkers() {
>         // Add actor thread: Consume the working queue and add the actor
> into
>         // the render inside the EDT thread
>         final AddActorRunnable adderRunnable = new AddActorRunnable();
>         adderRunnable.setRenderer(panel3d);
>         new Thread() {
>             public void run() {
>                 while (true) {
>                     try {
>                         adderRunnable.setActor(exec.take().get());
>                         SwingUtilities.invokeAndWait(adderRunnable);
>                         panel3d.repaint();
>                     } catch (InterruptedException e) {
>                         return;
>                     } catch (ExecutionException e) {
>                         e.printStackTrace();
>                     } catch (InvocationTargetException e) {
>                         e.printStackTrace();
>                     }
>                 }
>             };
>         }.start();
>     }
>
>
> Here is the test class I use:
>
> public class TestVtkPanel {
>     public VtkModel model;
>
>     public TestVtkPanel() {
>         SwingUtilities.invokeLater(new Runnable() {
>             public void run() {
>                 model = getModel();
>                 VtkPanel panel = new VtkPanel();
>                 model.addPropertyChangeListener(panel);
>
>                 JButton exitBtn = new JButton("Quitter");
>                 exitBtn.addActionListener(new ActionListener() {
>
>                     public void actionPerformed(ActionEvent e) {
>                         System.exit(0);
>                     }
>                 });
>                 JFrame f = new JFrame("Vtk Viewer");
>                 f.getContentPane().setLayout(new BorderLayout());
>                 f.getContentPane().add(panel, BorderLayout.CENTER);
>                 f.getContentPane().add(exitBtn, BorderLayout.SOUTH);
>
>                 f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
>                 f.setSize(800, 600);
>                 f.setVisible(true);
>                 f.validate();
>
>                 panel.startWorking(model);
>
>                 new Thread(new Runnable() {
>                     public void run() {
>                         updateModel();
>                     }
>                 }).start();
>
>             }
>         });
>
>     }
>
>
>     ...
>   }
>
>
>
> All this stuff works fine, but few questions remains.
>
> Is this way to do thing is the best for what I'm trying to achieve ? If a
> vtk guru can give a look to my code, it would be gratefully appreciated.
> Furthermore inside the VtkPanel constructor I tried to put the vtkPanel
> panel3d outside of the Timer but that do not work.
>
>     new Timer(1000, new ActionListener() {
>
>             public void actionPerformed(ActionEvent e) {
>                 if (nbSeconds++ < 1) {
>                     panel3d.resetCamera();
>                 }
>                 // Run GC in local thread (EDT)
>             ...
>      }
>
> I can't figure out why. Any hint on this point may help me to understand
> multithreading.
>
> Thanks for your help.
>
> jMax
> _______________________________________________
> Powered by www.kitware.com
>
> Visit other Kitware open-source projects at
> http://www.kitware.com/opensource/opensource.html
>
> Please keep messages on-topic and check the VTK FAQ at:
> http://www.vtk.org/Wiki/VTK_FAQ
>
> Search the list archives at: http://markmail.org/search/?q=vtkusers
>
> Follow this link to subscribe/unsubscribe:
> https://vtk.org/mailman/listinfo/vtkusers
>

[Attachment #5 (text/html)]

<div dir="ltr">Hi Jean-Max,<div><br></div><div>I&#39;m not sure to follow all the \
details of your implementation or why you still have the use of a \
Timer.</div><div>The only things that you need to worry about is that any rendering \
action (addActor/removeActor, update when actor connected, render) MUST BE in the \
EDT.</div><div><br></div><div>HTH,</div><div><br></div><div>Seb</div></div><br><div \
class="gmail_quote"><div dir="ltr" class="gmail_attr">On Thu, Feb 21, 2019 at 2:19 AM \
Jean-Max Redonnet &lt;<a href="mailto:jmax.red@gmail.com">jmax.red@gmail.com</a>&gt; \
wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px \
0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr"><div \
dir="ltr">Hello everyone !<br><br>I&#39;m using vtk throught its java wrapper and \
I&#39;m setting up a versatile viewer that can display an existing model and update \
display when this model is updated (and it will be continously updated).<br><br>My \
Model is built around few classes: VtkObject that is the ancestor of many other \
classes like VtkSurface, VtkCurve, etc... and VtkModel that basically contains a list \
of VtkObjects and maintain Listeners. All these classes are of my own (please note \
uppercase &quot;V&quot; on VtkObject)<br><br><br>public class VtkObject{<br>    \
protected final PropertyChangeSupport pcs = new PropertyChangeSupport(this);<br>    \
protected List&lt;vtkActor&gt; actors = new ArrayList&lt;vtkActor&gt;();<br>    \
...<br>}<br><br>public class VtkSurface extends VtkObject {<br>    private vtkActor \
surfActor;<br>    ...<br>}<br><br>public class VtkModel implements \
PropertyChangeListener{<br>    protected List&lt;VtkObject&gt; objects;<br>    \
protected PropertyChangeSupport support;<br>    ...<br>}<br><br>For the viewer itself \
I wrote a VtkPanel that is mostly inspired by the example provided by Sébastien \
Jourdain (<a href="https://github.com/Kitware/VTK/blob/master/Wrapping/Java/vtk/sample/Demo.java" \
target="_blank">https://github.com/Kitware/VTK/blob/master/Wrapping/Java/vtk/sample/Demo.java</a>)<br><br>I \
just make this panel model-aware implementing PropertyChangeListener:<br><br>    \
@Override<br>    public void propertyChange(PropertyChangeEvent evt) {<br>        if \
(evt.getPropertyName() == &quot;AddedObject&quot;) {<br>            \
System.out.println(&quot;Added Object&quot;);<br>            VtkObject o = \
(VtkObject) evt.getNewValue();<br>            if(o.getActors().size()&gt;0)<br>       \
exec.submit(new PipelineBuilder(o));<br>        }<br>        if \
(evt.getPropertyName() == &quot;UpdatedObject&quot;) {<br>            \
System.out.println(&quot;Updated Object&quot;);<br>            VtkObject o = \
(VtkObject) evt.getNewValue();<br>            if(o.getActors().size()&gt;0)<br>       \
exec.submit(new PipelineBuilder(o));<br>        }<br>    }<br><br>and slithly modify \
PipelineBuilder to make it able to manage VtkObjects that may contain several \
vtkActors<br><br>    public class PipelineBuilder implements Callable&lt;vtkActor&gt; \
{<br>        private int counter;<br>        private List&lt;vtkActor&gt; \
actors;<br><br>        public PipelineBuilder(VtkObject o) {<br>            actors = \
o.getActors();<br>            counter = 0;<br>        }<br><br>        @Override<br>  \
public vtkActor call() throws Exception {<br>            counter++;<br>            if \
(counter &lt; actors.size() + 1)<br>                return actors.get(counter - \
1);<br>            return null;<br>        }<br>    }<br><br>Also, workers are setup \
to continously search for new actors:<br><br>    private void setupWorkers() {<br>    \
// Add actor thread: Consume the working queue and add the actor into<br>        // \
the render inside the EDT thread<br>        final AddActorRunnable adderRunnable = \
new AddActorRunnable();<br>        adderRunnable.setRenderer(panel3d);<br>        new \
Thread() {<br>            public void run() {<br>                while (true) {<br>   \
try {<br>                        adderRunnable.setActor(exec.take().get());<br>       \
SwingUtilities.invokeAndWait(adderRunnable);<br>                        \
panel3d.repaint();<br>                    } catch (InterruptedException e) {<br>      \
return;<br>                    } catch (ExecutionException e) {<br>                   \
e.printStackTrace();<br>                    } catch (InvocationTargetException e) \
{<br>                        e.printStackTrace();<br>                    }<br>        \
}<br>            };<br>        }.start();<br>    }<br><br><br>Here is the test class \
I use:<br><br>public class TestVtkPanel {<br>    public VtkModel model;<br><br>    \
public TestVtkPanel() {<br>        SwingUtilities.invokeLater(new Runnable() {<br>    \
public void run() {<br>                model = getModel();<br>                \
VtkPanel panel = new VtkPanel();<br>                \
model.addPropertyChangeListener(panel);<br><br>                JButton exitBtn = new \
JButton(&quot;Quitter&quot;);<br>                exitBtn.addActionListener(new \
ActionListener() {<br><br>                    public void actionPerformed(ActionEvent \
e) {<br>                        System.exit(0);<br>                    }<br>          \
});<br>                JFrame f = new JFrame(&quot;Vtk Viewer&quot;);<br>             \
f.getContentPane().setLayout(new BorderLayout());<br>                \
f.getContentPane().add(panel, BorderLayout.CENTER);<br>                \
f.getContentPane().add(exitBtn, BorderLayout.SOUTH);<br><br>                \
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);<br>                f.setSize(800, \
600);<br>                f.setVisible(true);<br>                f.validate();<br><br> \
panel.startWorking(model);<br><br>                new Thread(new Runnable() {<br>     \
public void run() {<br>                        updateModel();<br>                    \
}<br>                }).start();<br><br>            }<br>        });<br><br>    }    \
<br>    <br><br>    ...<br>  }<br>    <br>    <br>    <br>All this stuff works fine, \
but few questions remains.<br><br>Is this way to do thing is the best for what \
I&#39;m trying to achieve ? If a vtk guru can give a look to my code, it would be \
gratefully appreciated. Furthermore inside the VtkPanel constructor I tried to put \
the vtkPanel panel3d outside of the Timer but that do not work.<br><br>    new \
Timer(1000, new ActionListener() {<br><br>            public void \
actionPerformed(ActionEvent e) {<br>                if (nbSeconds++ &lt; 1) {<br>     \
panel3d.resetCamera();<br>                }<br>                // Run GC in local \
thread (EDT)<br>            ...<br>     }<br>     <br>I can&#39;t figure out why. Any \
hint on this point may help me to understand multithreading.<br><br>Thanks for your \
help.<br><br></div><div>jMax</div></div> \
_______________________________________________<br> Powered by <a \
href="http://www.kitware.com" rel="noreferrer" \
target="_blank">www.kitware.com</a><br> <br>
Visit other Kitware open-source projects at <a \
href="http://www.kitware.com/opensource/opensource.html" rel="noreferrer" \
target="_blank">http://www.kitware.com/opensource/opensource.html</a><br> <br>
Please keep messages on-topic and check the VTK FAQ at: <a \
href="http://www.vtk.org/Wiki/VTK_FAQ" rel="noreferrer" \
target="_blank">http://www.vtk.org/Wiki/VTK_FAQ</a><br> <br>
Search the list archives at: <a href="http://markmail.org/search/?q=vtkusers" \
rel="noreferrer" target="_blank">http://markmail.org/search/?q=vtkusers</a><br> <br>
Follow this link to subscribe/unsubscribe:<br>
<a href="https://vtk.org/mailman/listinfo/vtkusers" rel="noreferrer" \
target="_blank">https://vtk.org/mailman/listinfo/vtkusers</a><br> </blockquote></div>



_______________________________________________
Powered by www.kitware.com

Visit other Kitware open-source projects at http://www.kitware.com/opensource/opensource.html

Please keep messages on-topic and check the VTK FAQ at: http://www.vtk.org/Wiki/VTK_FAQ

Search the list archives at: http://markmail.org/search/?q=vtkusers

Follow this link to subscribe/unsubscribe:
https://vtk.org/mailman/listinfo/vtkusers


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic