fixing concurrency issue on incremental delaunay demo

This commit is contained in:
Martin Pernollet 2016-04-14 14:59:27 +02:00
parent 89ebb76871
commit 5cfc459ece
3 changed files with 336 additions and 288 deletions

View File

@ -17,286 +17,311 @@ import org.jzy3d.plot3d.transform.Transform;
import com.jogamp.opengl.GL; import com.jogamp.opengl.GL;
import com.jogamp.opengl.glu.GLU; import com.jogamp.opengl.glu.GLU;
/**
/** * A Composite gathers several Drawable and provides default methods for
* A Composite gathers several Drawable and provides default methods * rendering them all in one call. <br>
* for rendering them all in one call.
* <br>
* *
* @author Martin Pernollet * @author Martin Pernollet
* *
*/ */
public abstract class AbstractComposite extends AbstractWireframeable implements ISingleColorable, IMultiColorable{ public abstract class AbstractComposite extends AbstractWireframeable implements ISingleColorable, IMultiColorable {
public AbstractComposite(){ public AbstractComposite() {
super(); super();
components = new ArrayList<AbstractDrawable>(); components = new ArrayList<AbstractDrawable>();
} }
/****************************************************************/ /****************************************************************/
/** Append a list of Drawables to this composite.*/
public void add(List<? extends AbstractDrawable> drawables){
components.addAll(drawables);
}
/** Clear the list of Drawables from this composite.*/
public void clear(){
components.clear();
}
/** Add a Drawable to this composite.*/
public void add(AbstractDrawable drawable){
components.add(drawable);
}
/** Remove a Drawable from this composite.*/
public void remove(AbstractDrawable drawable){
components.remove(drawable);
}
/** Get a Drawable stored by this composite.*/
public AbstractDrawable get(int p){
return components.get(p);
}
public List<AbstractDrawable> getDrawables(){
return components;
}
/** Return the number of Drawable stored by this composite.*/
public int size(){
return components.size();
}
/* */
/** Delegate rendering iteratively to all Drawable of this composite.*/ /** Append a list of Drawables to this composite. */
@Override public void add(List<? extends AbstractDrawable> drawables) {
public void draw(GL gl, GLU glu, Camera camera){ synchronized (components) {
if(mapper!=null) components.addAll(drawables);
mapper.preDraw(this); }
}
synchronized(components){ /** Clear the list of Drawables from this composite. */
for(AbstractDrawable c: components){ public void clear() {
if(c!=null) synchronized (components) {
c.draw(gl, glu, camera); components.clear();
} }
} }
if(mapper!=null) /** Add a Drawable to this composite. */
public void add(AbstractDrawable drawable) {
components.add(drawable);
}
/** Remove a Drawable from this composite. */
public void remove(AbstractDrawable drawable) {
components.remove(drawable);
}
/** Get a Drawable stored by this composite. */
public AbstractDrawable get(int p) {
return components.get(p);
}
public List<AbstractDrawable> getDrawables() {
return components;
}
/** Return the number of Drawable stored by this composite. */
public int size() {
return components.size();
}
/* */
/** Delegate rendering iteratively to all Drawable of this composite. */
@Override
public void draw(GL gl, GLU glu, Camera camera) {
if (mapper != null)
mapper.preDraw(this);
synchronized (components) {
for (AbstractDrawable c : components) {
if (c != null)
c.draw(gl, glu, camera);
}
}
if (mapper != null)
mapper.postDraw(this); mapper.postDraw(this);
doDrawBounds(gl, glu, camera); doDrawBounds(gl, glu, camera);
} }
/** Delegate transforming iteratively to all Drawable of this composite /**
* and stores the given transform for keeping the ability of retrieving it.*/ * Delegate transforming iteratively to all Drawable of this composite and
@Override * stores the given transform for keeping the ability of retrieving it.
public void setTransform(Transform transform){ */
this.transform = transform; @Override
public void setTransform(Transform transform) {
synchronized(components){ this.transform = transform;
for(AbstractDrawable c: components){
if(c!=null) synchronized (components) {
c.setTransform(transform); for (AbstractDrawable c : components) {
} if (c != null)
} c.setTransform(transform);
} }
}
@Override }
public void setTransformBefore(Transform transform){
@Override
public void setTransformBefore(Transform transform) {
this.transformBefore = transform; this.transformBefore = transform;
synchronized(components){ synchronized (components) {
for(AbstractDrawable c: components){ for (AbstractDrawable c : components) {
if(c!=null) if (c != null)
c.setTransformBefore(transform); c.setTransformBefore(transform);
} }
} }
} }
/** Return the transform that was affected to this composite.*/ /** Return the transform that was affected to this composite. */
@Override @Override
public Transform getTransform(){ public Transform getTransform() {
return transform; return transform;
} }
/** Creates and return a BoundingBox3d that embed all available Drawable bounds.*/ /**
@Override * Creates and return a BoundingBox3d that embed all available Drawable
public BoundingBox3d getBounds(){ * bounds.
updateBounds(); */
return bbox; @Override
} public BoundingBox3d getBounds() {
updateBounds();
return bbox;
}
@Override @Override
public void updateBounds() { public void updateBounds() {
BoundingBox3d box = new BoundingBox3d(); BoundingBox3d box = new BoundingBox3d();
synchronized(components){ synchronized (components) {
for(AbstractDrawable c: components){ for (AbstractDrawable c : components) {
if(c!=null && c.getBounds()!=null) if (c != null && c.getBounds() != null)
box.add(c.getBounds()); box.add(c.getBounds());
} }
} }
bbox = box; bbox = box;
} }
@Override @Override
public void applyGeometryTransform(Transform transform){ public void applyGeometryTransform(Transform transform) {
for(AbstractDrawable c: components){ synchronized (components) {
c.applyGeometryTransform(transform); for (AbstractDrawable c : components) {
c.applyGeometryTransform(transform);
}
} }
// updateBounds(); no need, as computed by getBounds() // updateBounds(); no need, as computed by getBounds()
} }
/****************************************************************/
/****************************************************************/
@Override
public void setWireframeColor(Color color){
super.setWireframeColor(color);
if(components != null)
for(AbstractDrawable c: components){
if(c!=null && c instanceof AbstractWireframeable)
((AbstractWireframeable)c).setWireframeColor(color);
}
}
@Override
public void setWireframeDisplayed(boolean status){
super.setWireframeDisplayed(status);
if(components != null)
for(AbstractDrawable c: components){
if(c!=null && c instanceof AbstractWireframeable)
((AbstractWireframeable)c).setWireframeDisplayed(status);
}
}
@Override
public void setWireframeWidth(float width){
super.setWireframeWidth(width);
if(components != null)
for(AbstractDrawable c: components){
if(c!=null && c instanceof AbstractWireframeable)
((AbstractWireframeable)c).setWireframeWidth(width);
}
}
@Override @Override
public void setFaceDisplayed(boolean status){ public void setWireframeColor(Color color) {
super.setFaceDisplayed(status); super.setWireframeColor(color);
if(components != null)
for(AbstractDrawable c: components){
if(c!=null && c instanceof AbstractWireframeable)
((AbstractWireframeable)c).setFaceDisplayed(status);
}
}
@Override
public void setDisplayed(boolean status){
super.setDisplayed(status);
if(components != null)
for(AbstractDrawable c: components){
if(c!=null && c instanceof AbstractWireframeable)
((AbstractWireframeable)c).setDisplayed(status);
}
}
/****************************************************************/
@Override if (components != null) {
public void setColorMapper(ColorMapper mapper){ synchronized (components) {
this.mapper = mapper; for (AbstractDrawable c : components) {
if (c != null && c instanceof AbstractWireframeable)
if(components != null){ ((AbstractWireframeable) c).setWireframeColor(color);
for(AbstractDrawable d: components){ }
if(d instanceof IMultiColorable) }
((IMultiColorable)d).setColorMapper(mapper); }
else if(d instanceof ISingleColorable) }
((ISingleColorable)d).setColor(mapper.getColor(d.getBarycentre()));
}
fireDrawableChanged(new DrawableChangedEvent(this, DrawableChangedEvent.FIELD_COLOR));
}
}
@Override
public ColorMapper getColorMapper(){
return mapper;
}
@Override
public void setColor(Color color){
this.color = color;
if(components != null){
for(AbstractDrawable d: components)
if(d instanceof ISingleColorable)
((ISingleColorable)d).setColor(color);
fireDrawableChanged(new DrawableChangedEvent(this, DrawableChangedEvent.FIELD_COLOR));
}
}
@Override
public Color getColor(){
return color;
}
/****************************************************************/
/** Print out information concerning all Drawable of this composite.*/
@Override
public String toString(){
return toString(0);
}
@Override
public String toString(int depth){
String output = Utils.blanks(depth) + "(Composite3d) #elements:"+ components.size()+ " | isDisplayed=" + isDisplayed();
if(detailedToString){
int k = 0;
for(AbstractDrawable c: components){
if(c!=null){
if(c instanceof AbstractComposite)
output += "\n" + ((AbstractComposite)c).toString(depth+1);
else
output += "\n" + Utils.blanks(depth+1) + " Composite element["+ (k++) +"]:" + c.toString();
}
else
output += Utils.blanks(depth+1) + "(null)\n";
}
}
return output;
}
public boolean isDetailedToString() {
return detailedToString;
}
/** When to true, the {@link toString()} method will give the detail of each element @Override
* of this composite object in a tree like layout. public void setWireframeDisplayed(boolean status) {
*/ super.setWireframeDisplayed(status);
public void setDetailedToString(boolean detailedToString) {
this.detailedToString = detailedToString;
}
if (components != null) {
synchronized (components) {
for (AbstractDrawable c : components) {
if (c != null && c instanceof AbstractWireframeable)
((AbstractWireframeable) c).setWireframeDisplayed(status);
}
}
}
}
@Override
public void setWireframeWidth(float width) {
super.setWireframeWidth(width);
/****************************************************************/ if (components != null) {
synchronized (components) {
protected List<AbstractDrawable> components = Collections.synchronizedList(new ArrayList<AbstractDrawable>()); for (AbstractDrawable c : components) {
protected Transform transform; if (c != null && c instanceof AbstractWireframeable)
((AbstractWireframeable) c).setWireframeWidth(width);
protected ColorMapper mapper; }
protected Color color; }
protected boolean detailedToString = false; }
}
@Override
public void setFaceDisplayed(boolean status) {
super.setFaceDisplayed(status);
if (components != null) {
synchronized (components) {
for (AbstractDrawable c : components) {
if (c != null && c instanceof AbstractWireframeable)
((AbstractWireframeable) c).setFaceDisplayed(status);
}
}
}
}
@Override
public void setDisplayed(boolean status) {
super.setDisplayed(status);
if (components != null) {
synchronized (components) {
for (AbstractDrawable c : components) {
if (c != null && c instanceof AbstractWireframeable)
((AbstractWireframeable) c).setDisplayed(status);
}
}
}
}
/****************************************************************/
@Override
public void setColorMapper(ColorMapper mapper) {
this.mapper = mapper;
if (components != null) {
synchronized (components) {
for (AbstractDrawable d : components) {
if (d instanceof IMultiColorable)
((IMultiColorable) d).setColorMapper(mapper);
else if (d instanceof ISingleColorable)
((ISingleColorable) d).setColor(mapper.getColor(d.getBarycentre()));
}
}
fireDrawableChanged(new DrawableChangedEvent(this, DrawableChangedEvent.FIELD_COLOR));
}
}
@Override
public ColorMapper getColorMapper() {
return mapper;
}
@Override
public void setColor(Color color) {
this.color = color;
if (components != null) {
synchronized (components) {
for (AbstractDrawable d : components)
if (d instanceof ISingleColorable)
((ISingleColorable) d).setColor(color);
}
fireDrawableChanged(new DrawableChangedEvent(this, DrawableChangedEvent.FIELD_COLOR));
}
}
@Override
public Color getColor() {
return color;
}
/****************************************************************/
/** Print out information concerning all Drawable of this composite. */
@Override
public String toString() {
return toString(0);
}
@Override
public String toString(int depth) {
String output = Utils.blanks(depth) + "(Composite3d) #elements:" + components.size() + " | isDisplayed=" + isDisplayed();
if (detailedToString) {
int k = 0;
for (AbstractDrawable c : components) {
if (c != null) {
if (c instanceof AbstractComposite)
output += "\n" + ((AbstractComposite) c).toString(depth + 1);
else
output += "\n" + Utils.blanks(depth + 1) + " Composite element[" + (k++) + "]:" + c.toString();
} else
output += Utils.blanks(depth + 1) + "(null)\n";
}
}
return output;
}
public boolean isDetailedToString() {
return detailedToString;
}
/**
* When to true, the {@link toString()} method will give the detail of each
* element of this composite object in a tree like layout.
*/
public void setDetailedToString(boolean detailedToString) {
this.detailedToString = detailedToString;
}
/****************************************************************/
protected List<AbstractDrawable> components = Collections.synchronizedList(new ArrayList<AbstractDrawable>());
protected Transform transform;
protected ColorMapper mapper;
protected Color color;
protected boolean detailedToString = false;
} }

View File

@ -6,34 +6,36 @@ import java.util.List;
import org.jzy3d.plot3d.primitives.AbstractComposite; import org.jzy3d.plot3d.primitives.AbstractComposite;
import org.jzy3d.plot3d.primitives.AbstractDrawable; import org.jzy3d.plot3d.primitives.AbstractDrawable;
public class Decomposition { public class Decomposition {
public static ArrayList<AbstractDrawable> getDecomposition(List<AbstractDrawable> drawables){ public static ArrayList<AbstractDrawable> getDecomposition(List<AbstractDrawable> drawables) {
ArrayList<AbstractDrawable> monotypes = new ArrayList<AbstractDrawable>(); ArrayList<AbstractDrawable> monotypes = new ArrayList<AbstractDrawable>();
for(AbstractDrawable c: drawables){ for (AbstractDrawable c : drawables) {
if(c!=null && c.isDisplayed()){ if (c != null && c.isDisplayed()) {
if(c instanceof AbstractComposite) if (c instanceof AbstractComposite)
monotypes.addAll(getDecomposition((AbstractComposite)c)); monotypes.addAll(getDecomposition((AbstractComposite) c));
else if(c instanceof AbstractDrawable) else if (c instanceof AbstractDrawable)
monotypes.add(c); monotypes.add(c);
} }
} }
return monotypes; return monotypes;
} }
/** Recursively expand all monotype Drawables from the given Composite.*/ /** Recursively expand all monotype Drawables from the given Composite. */
public static ArrayList<AbstractDrawable> getDecomposition(AbstractComposite input){ public static ArrayList<AbstractDrawable> getDecomposition(AbstractComposite input) {
ArrayList<AbstractDrawable> selection = new ArrayList<AbstractDrawable>(); ArrayList<AbstractDrawable> selection = new ArrayList<AbstractDrawable>();
for(AbstractDrawable c: input.getDrawables()){ // composite internally make use of synchronisation on its list of child, so we do so
if(c!=null && c.isDisplayed()){ synchronized (input.getDrawables()) {
if(c instanceof AbstractComposite) for (AbstractDrawable c : input.getDrawables()) {
selection.addAll(getDecomposition((AbstractComposite)c)); if (c != null && c.isDisplayed()) {
else if(c instanceof AbstractDrawable) if (c instanceof AbstractComposite)
selection.add(c); selection.addAll(getDecomposition((AbstractComposite) c));
} else if (c instanceof AbstractDrawable)
} selection.add(c);
return selection; }
} }
}
return selection;
}
} }

View File

@ -255,12 +255,12 @@ public class Graph {
public synchronized void setTransform(Transform transform) { public synchronized void setTransform(Transform transform) {
this.transform = transform; this.transform = transform;
// synchronized(components){ synchronized (components) {
for (AbstractDrawable c : components) { for (AbstractDrawable c : components) {
if (c != null) if (c != null)
c.setTransform(transform); c.setTransform(transform);
}
} }
// }
} }
/** Return the transform that was affected to this composite. */ /** Return the transform that was affected to this composite. */
@ -280,10 +280,10 @@ public class Graph {
for (AbstractDrawable c : components) { for (AbstractDrawable c : components) {
if (c != null && c.getBounds() != null) { if (c != null && c.getBounds() != null) {
BoundingBox3d drawableBounds= c.getBounds(); BoundingBox3d drawableBounds = c.getBounds();
if(!drawableBounds.isReset()){ if (!drawableBounds.isReset()) {
box.add(drawableBounds); box.add(drawableBounds);
} }
} }
} }
return box; return box;
@ -343,9 +343,30 @@ public class Graph {
// } // }
return output; return output;
} }
/* */ /* */
public boolean isSort() {
return sort;
}
/**
* Set sort to false to desactivate decomposition of drawable.
*
* This bypass ranking polygons w.r.t. camera. This will produce visual cue
* if the scene is dynamic (changing the list of polygons or viewpoints).
* @param sort
*/
public void setSort(boolean sort) {
this.sort = sort;
}
public Scene getScene() {
return scene;
}
protected List<AbstractDrawable> components; protected List<AbstractDrawable> components;
protected Scene scene; protected Scene scene;
protected Transform transform; protected Transform transform;