Commit fabe52d0 authored by Benedikt Zoennchen's avatar Benedikt Zoennchen
Browse files

gui: one can now display the mesh on which the eikonal equation was solved.

parent 7cce3d9c
Pipeline #73531 failed with stages
in 32 seconds
...@@ -267,6 +267,7 @@ SettingsDialog.lblPedestrianNoTarget.text=Without Target (-1) ...@@ -267,6 +267,7 @@ SettingsDialog.lblPedestrianNoTarget.text=Without Target (-1)
ProjectView.menuOpenFloorFieldFile.title=Add Floor Field File... ProjectView.menuOpenFloorFieldFile.title=Add Floor Field File...
ProjectView.btnDrawVoronoiDiagram.tooltip=Draw and display a Voronoi Diagram ProjectView.btnDrawVoronoiDiagram.tooltip=Draw and display a Voronoi Diagram
ProjectView.btnDrawMesh.tooltip=Draw and display a mesh
SettingsDialog.chbLogo.text=Show the Vadere logo SettingsDialog.chbLogo.text=Show the Vadere logo
ProjectView.btnShowWalkingDirection.tooltip=Show the walking direction of all pedestrians ProjectView.btnShowWalkingDirection.tooltip=Show the walking direction of all pedestrians
ProjectView.btnShowGroupInformation.tooltip=Draw pedestrians within one group with same shape and color ProjectView.btnShowGroupInformation.tooltip=Draw pedestrians within one group with same shape and color
......
...@@ -273,6 +273,8 @@ ProjectView.btnShowDensity.tooltip=Dichte anzeigen ...@@ -273,6 +273,8 @@ ProjectView.btnShowDensity.tooltip=Dichte anzeigen
ProjectView.btnSettings.tooltip=Einstellungen ProjectView.btnSettings.tooltip=Einstellungen
ProjectView.btnOk=OK ProjectView.btnOk=OK
ProjectView.btnCancel=Abbrechen ProjectView.btnCancel=Abbrechen
ProjectView.btnDrawVoronoiDiagram.tooltip=Voronoi-Diagramm zeichnen und anzeigen
ProjectView.btnDrawMesh.tooltip=Mesh zeichnen und anzeigen
TopographyCreator.btnMergeObstacles.tooltip=Hindernisse zusammenf\u00fchren TopographyCreator.btnMergeObstacles.tooltip=Hindernisse zusammenf\u00fchren
TopographyCreator.btnMinimizeTopography.tooltip=Select Viewport area TopographyCreator.btnMinimizeTopography.tooltip=Select Viewport area
......
...@@ -6,40 +6,17 @@ import org.apache.log4j.LogManager; ...@@ -6,40 +6,17 @@ import org.apache.log4j.LogManager;
import org.apache.log4j.Logger; import org.apache.log4j.Logger;
import org.vadere.gui.components.control.*; import org.vadere.gui.components.control.*;
import org.vadere.gui.components.view.ISelectScenarioElementListener; import org.vadere.gui.components.view.ISelectScenarioElementListener;
import org.vadere.simulator.models.potential.fields.IPotentialField;
import org.vadere.simulator.models.potential.fields.PotentialFieldDistancesBruteForce;
import org.vadere.simulator.utils.TexGraphGenerator;
import org.vadere.state.attributes.models.AttributesFloorField;
import org.vadere.state.scenario.Obstacle;
import org.vadere.state.scenario.ScenarioElement; import org.vadere.state.scenario.ScenarioElement;
import org.vadere.state.scenario.Topography;
import org.vadere.state.types.ScenarioElementType; import org.vadere.state.types.ScenarioElementType;
import org.vadere.util.geometry.shapes.VPoint; import org.vadere.util.geometry.shapes.VPoint;
import org.vadere.util.geometry.shapes.VRectangle;
import org.vadere.util.geometry.shapes.VShape; import org.vadere.util.geometry.shapes.VShape;
import org.vadere.meshing.mesh.gen.PFace;
import org.vadere.meshing.mesh.gen.PHalfEdge;
import org.vadere.meshing.mesh.gen.PVertex;
import org.vadere.meshing.mesh.inter.IIncrementalTriangulation;
import org.vadere.util.geometry.shapes.IPoint;
import org.vadere.util.geometry.shapes.VPolygon;
import org.vadere.util.geometry.shapes.VTriangle;
import org.vadere.util.data.cellgrid.CellGrid;
import org.vadere.util.data.cellgrid.CellState;
import org.vadere.util.data.cellgrid.PathFindingTag;
import org.vadere.util.math.DistanceFunction;
import org.vadere.util.math.IDistanceFunction;
import org.vadere.meshing.mesh.triangulation.improver.eikmesh.EikMeshPoint;
import org.vadere.meshing.mesh.triangulation.improver.eikmesh.impl.PEikMesh;
import org.vadere.util.voronoi.VoronoiDiagram; import org.vadere.util.voronoi.VoronoiDiagram;
import java.awt.*; import java.awt.*;
import java.awt.geom.Rectangle2D; import java.awt.geom.Rectangle2D;
import java.util.*; import java.util.*;
import java.util.List; import java.util.List;
import java.util.function.Function;
import java.util.function.Predicate; import java.util.function.Predicate;
import java.util.stream.Collectors;
import java.util.stream.Stream; import java.util.stream.Stream;
import java.util.stream.StreamSupport; import java.util.stream.StreamSupport;
...@@ -63,8 +40,6 @@ public abstract class DefaultModel<T extends DefaultConfig> extends Observable i ...@@ -63,8 +40,6 @@ public abstract class DefaultModel<T extends DefaultConfig> extends Observable i
private boolean showVoroniDiagram; private boolean showVoroniDiagram;
private boolean showTriangulation;
private VPoint cursorWorldPosition; private VPoint cursorWorldPosition;
private VPoint startSelectionPoint; private VPoint startSelectionPoint;
...@@ -87,12 +62,6 @@ public abstract class DefaultModel<T extends DefaultConfig> extends Observable i ...@@ -87,12 +62,6 @@ public abstract class DefaultModel<T extends DefaultConfig> extends Observable i
public T config; public T config;
private IIncrementalTriangulation<EikMeshPoint, PVertex<EikMeshPoint>, PHalfEdge<EikMeshPoint>, PFace<EikMeshPoint>> triangulation;
private Collection<VTriangle> triangles;
protected boolean triangulationTriggered = false;
public DefaultModel(final T config) { public DefaultModel(final T config) {
this.config = config; this.config = config;
this.scaleFactor = 50; this.scaleFactor = 50;
...@@ -101,13 +70,11 @@ public abstract class DefaultModel<T extends DefaultConfig> extends Observable i ...@@ -101,13 +70,11 @@ public abstract class DefaultModel<T extends DefaultConfig> extends Observable i
this.cursorWorldPosition = VPoint.ZERO; this.cursorWorldPosition = VPoint.ZERO;
this.selectScenarioElementListener = new LinkedList<>(); this.selectScenarioElementListener = new LinkedList<>();
this.voronoiDiagram = null; this.voronoiDiagram = null;
this.showTriangulation = false;
this.showVoroniDiagram = true; this.showVoroniDiagram = true;
this.showSelection = false; this.showSelection = false;
this.mouseSelectionMode = new DefaultSelectionMode(this); this.mouseSelectionMode = new DefaultSelectionMode(this);
this.viewportChangeListeners = new ArrayList<>(); this.viewportChangeListeners = new ArrayList<>();
this.scaleChangeListeners = new ArrayList<>(); this.scaleChangeListeners = new ArrayList<>();
this.triangulation = null;
} }
@Override @Override
...@@ -192,10 +159,6 @@ public abstract class DefaultModel<T extends DefaultConfig> extends Observable i ...@@ -192,10 +159,6 @@ public abstract class DefaultModel<T extends DefaultConfig> extends Observable i
} }
} }
public boolean isTriangulationVisible() {
return showTriangulation;
}
@Override @Override
public void notifyScaleListeners() { public void notifyScaleListeners() {
for (IScaleChangeListener listener : scaleChangeListeners) { for (IScaleChangeListener listener : scaleChangeListeners) {
...@@ -385,18 +348,6 @@ public abstract class DefaultModel<T extends DefaultConfig> extends Observable i ...@@ -385,18 +348,6 @@ public abstract class DefaultModel<T extends DefaultConfig> extends Observable i
setChanged(); setChanged();
} }
@Override
public void showTriangulation() {
showTriangulation = true;
setChanged();
}
@Override
public void hideTriangulation() {
showTriangulation = false;
setChanged();
}
@Override @Override
public void showSelection() { public void showSelection() {
showSelection = true; showSelection = true;
...@@ -543,95 +494,6 @@ public abstract class DefaultModel<T extends DefaultConfig> extends Observable i ...@@ -543,95 +494,6 @@ public abstract class DefaultModel<T extends DefaultConfig> extends Observable i
return config; return config;
} }
/*
* returns the adaptive triangulation (see persson-2004 'A Simple Mesh Generator in MATLAB.')
*/
public void startTriangulation() {
if(!triangulationTriggered) {
triangulationTriggered = true;
VRectangle bound = new VRectangle(getTopographyBound());
Collection<Obstacle> obstacles = Topography.createObstacleBoundary(getTopography());
obstacles.addAll(getTopography().getObstacles());
List<VShape> shapes = obstacles.stream().map(obstacle -> obstacle.getShape()).collect(Collectors.toList());
IPotentialField distanceField = new PotentialFieldDistancesBruteForce(
getTopography().getObstacles().stream().map(obs -> obs.getShape()).collect(Collectors.toList()),
new VRectangle(getTopography().getBounds()),
new AttributesFloorField());
Function<IPoint, Double> obstacleDistance = p -> distanceField.getPotential(p, null);
IDistanceFunction distanceFunc = new DistanceFunction(bound, shapes);
CellGrid cellGrid = new CellGrid(bound.getWidth(), bound.getHeight(), 0.1, new CellState(), bound.getMinX(), bound.getMinY());
cellGrid.pointStream().forEach(p -> cellGrid.setValue(p, new CellState(distanceFunc.apply(cellGrid.pointToCoord(p)), PathFindingTag.Reachable)));
Function<IPoint, Double> interpolationFunction = cellGrid.getInterpolationFunction();
IDistanceFunction approxDistance = p -> interpolationFunction.apply(p);
/*PPSMeshing meshImprover = new PPSMeshing(
distanceFunc,
p -> Math.min(1.0 + Math.pow(Math.max(-distanceFunc.apply(p), 0)*0.8, 2), 6.0),
0.3,
bound, getTopography().getObstacles().stream().map(obs -> obs.getShape()).collect(Collectors.toList()));*/
PEikMesh meshImprover = new PEikMesh(
distanceFunc,
p -> Math.min(1.0 + Math.max(approxDistance.apply(p)*approxDistance.apply(p), 0)*0.3, 5.0),
0.35,
bound, getTopography().getObstacles().stream().map(obs -> obs.getShape()).collect(Collectors.toList()));
/*PPSMeshing meshImprover = new PPSMeshing(
distanceFunc,
p -> 1.0,
1.0,
bound, getTopography().getObstacles().stream().map(obs -> obs.getShape()).collect(Collectors.toList()));*/
triangulation = meshImprover.getTriangulation();
Thread t = new Thread(() -> {
while(!meshImprover.isFinished()) {
meshImprover.improve();
/*try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}*/
setChanged();
notifyObservers();
}
//meshImprover.improve();
Function<PFace<EikMeshPoint>, Color> colorFunction = f -> {
float grayScale = (float) meshImprover.faceToQuality(f);
return triangulation.isValid(f) ? new Color(grayScale, grayScale, grayScale) : Color.RED;
};
log.info(TexGraphGenerator.toTikz(meshImprover.getMesh(), colorFunction, 1.0f));
log.info("number of points = " + meshImprover.getMesh().getVertices().size());
log.info("number of triangle = " + meshImprover.getMesh().getFaces().size());
log.info("avg-quality = " + meshImprover.getQuality());
log.info("min-quality = " + meshImprover.getMinQuality());
});
t.start();
}
}
public Collection<VTriangle> getTriangles() {
if(triangulation == null) {
return Collections.EMPTY_LIST;
}
synchronized (triangulation.getMesh()) {
return triangulation.streamTriangles().collect(Collectors.toList());
}
}
public Collection<VPolygon> getHoles() {
if(triangulation == null) {
return Collections.EMPTY_LIST;
}
synchronized (triangulation.getMesh()) {
return triangulation.getMesh().streamHoles().map(f -> triangulation.getMesh().toPolygon(f)).collect(Collectors.toList());
}
}
/*public void startTriangulation() { /*public void startTriangulation() {
if(!triangulationTriggered) { if(!triangulationTriggered) {
triangulationTriggered = true; triangulationTriggered = true;
......
...@@ -297,9 +297,5 @@ public interface IDefaultModel<T extends DefaultConfig> extends Iterable<Scenari ...@@ -297,9 +297,5 @@ public interface IDefaultModel<T extends DefaultConfig> extends Iterable<Scenari
*/ */
void notifyObservers(final Object args); void notifyObservers(final Object args);
void hideTriangulation();
void showTriangulation();
T getConfig(); T getConfig();
} }
...@@ -596,9 +596,12 @@ public abstract class DefaultRenderer { ...@@ -596,9 +596,12 @@ public abstract class DefaultRenderer {
} }
} }
protected void renderMesh(final Graphics2D g, @NotNull final IMesh<? extends IPotentialPoint, ?, ?, ?> mesh, final int width, final int height) { protected void renderMesh(
@NotNull final Graphics2D g,
@NotNull final IMesh<? extends IPotentialPoint, ?, ?, ?> mesh,
@NotNull final VRectangle bound) {
MeshRenderer<? extends IPotentialPoint, ?, ?, ?> meshRenderer = new MeshRenderer<>(mesh); MeshRenderer<? extends IPotentialPoint, ?, ?, ?> meshRenderer = new MeshRenderer<>(mesh);
meshRenderer.render(g, width, height); meshRenderer.renderGraphics(g, bound);
} }
protected void renderVoronoiDiagram(final Graphics2D g, final VoronoiDiagram voronoiDiagram) { protected void renderVoronoiDiagram(final Graphics2D g, final VoronoiDiagram voronoiDiagram) {
......
...@@ -100,7 +100,7 @@ public abstract class SimulationRenderer extends DefaultRenderer { ...@@ -100,7 +100,7 @@ public abstract class SimulationRenderer extends DefaultRenderer {
} }
if(model.config.isShowTargetPotentielFieldMesh()) { if(model.config.isShowTargetPotentielFieldMesh()) {
renderMesh(graphics, model.getDiscretization(), width, height); renderMesh(graphics, model.getDiscretization(), new VRectangle(model.getTopographyBound()));
} }
renderSimulationContent(graphics); renderSimulationContent(graphics);
...@@ -181,7 +181,7 @@ public abstract class SimulationRenderer extends DefaultRenderer { ...@@ -181,7 +181,7 @@ public abstract class SimulationRenderer extends DefaultRenderer {
private void renderPotentialFieldOnViewport(final Graphics2D g, final int xPos, final int yPos, final int width, final int height) { private void renderPotentialFieldOnViewport(final Graphics2D g, final int xPos, final int yPos, final int width, final int height) {
logger.info("resolution = " + width + ", " + height); //logger.info("resolution = " + width + ", " + height);
/* /*
* This calculation we need since the viewport.y = 0 if the user scrolls to the bottom * This calculation we need since the viewport.y = 0 if the user scrolls to the bottom
*/ */
......
...@@ -128,8 +128,11 @@ public class OnlineVisualization implements PassiveCallback { ...@@ -128,8 +128,11 @@ public class OnlineVisualization implements PassiveCallback {
IPotentialField pedPotentialField = null; IPotentialField pedPotentialField = null;
Agent selectedAgent = null; Agent selectedAgent = null;
if(model.config.isShowPotentialField() && model.getSelectedElement() instanceof Agent && potentialField != null) { if(model.getSelectedElement() instanceof Agent){
selectedAgent = (Agent)model.getSelectedElement(); selectedAgent = (Agent)model.getSelectedElement();
}
if(model.config.isShowPotentialField() && selectedAgent != null && potentialField != null) {
pedPotentialField = IPotentialField.copyAgentField(potentialField, selectedAgent, new VRectangle(model.getTopographyBound()), 0.1); pedPotentialField = IPotentialField.copyAgentField(potentialField, selectedAgent, new VRectangle(model.getTopographyBound()), 0.1);
} }
......
package org.vadere.gui.onlinevisualization.control;
import org.apache.log4j.LogManager;
import org.apache.log4j.Logger;
import org.vadere.gui.components.control.simulation.ActionVisualization;
import org.vadere.gui.components.model.DefaultSimulationConfig;
import org.vadere.gui.components.model.SimulationModel;
import java.awt.event.ActionEvent;
import javax.swing.*;
public class ActionShowMesh extends ActionVisualization {
private static Logger logger = LogManager.getLogger(ActionShowMesh.class);
public ActionShowMesh(final String name, Icon icon, final SimulationModel<? extends DefaultSimulationConfig> model) {
super(name, icon, model);
}
@Override
public void actionPerformed(final ActionEvent e) {
model.config.setShowTargetPotentielFieldMesh(!model.config.isShowTargetPotentielFieldMesh());
model.notifyObservers();
super.actionPerformed(e);
}
}
...@@ -195,7 +195,7 @@ public class OnlineVisualizationModel extends SimulationModel<DefaultSimulationC ...@@ -195,7 +195,7 @@ public class OnlineVisualizationModel extends SimulationModel<DefaultSimulationC
public Function<IPoint, Double> getPotentialField() { public Function<IPoint, Double> getPotentialField() {
Function<IPoint, Double> f = pos -> 0.0; Function<IPoint, Double> f = pos -> 0.0;
if(potentialField != null && config.isShowPotentialField() && agent.equals(getSelectedElement())) { if(agent != null && potentialField != null && config.isShowPotentialField() && agent.equals(getSelectedElement())) {
f = pos -> potentialField.getPotential(pos, agent); f = pos -> potentialField.getPotential(pos, agent);
} }
else if(potentialFieldTarget != null && config.isShowTargetPotentialField()) { else if(potentialFieldTarget != null && config.isShowTargetPotentialField()) {
...@@ -210,7 +210,7 @@ public class OnlineVisualizationModel extends SimulationModel<DefaultSimulationC ...@@ -210,7 +210,7 @@ public class OnlineVisualizationModel extends SimulationModel<DefaultSimulationC
@Override @Override
public IMesh<? extends IPotentialPoint, ?, ?, ?> getDiscretization() { public IMesh<? extends IPotentialPoint, ?, ?, ?> getDiscretization() {
if(discretizations != null && config.isShowTargetPotentielFieldMesh() && agent.equals(getSelectedElement())) { if(agent != null && discretizations != null && config.isShowTargetPotentielFieldMesh() && agent.equals(getSelectedElement())) {
return discretizations.apply(agent); return discretizations.apply(agent);
} }
......
...@@ -17,6 +17,7 @@ import org.vadere.gui.components.control.simulation.ActionGeneratePNG; ...@@ -17,6 +17,7 @@ import org.vadere.gui.components.control.simulation.ActionGeneratePNG;
import org.vadere.gui.components.control.simulation.ActionGenerateSVG; import org.vadere.gui.components.control.simulation.ActionGenerateSVG;
import org.vadere.gui.components.control.simulation.ActionGenerateTikz; import org.vadere.gui.components.control.simulation.ActionGenerateTikz;
import org.vadere.gui.onlinevisualization.control.ActionOnlineVisMenu; import org.vadere.gui.onlinevisualization.control.ActionOnlineVisMenu;
import org.vadere.gui.onlinevisualization.control.ActionShowMesh;
import org.vadere.gui.onlinevisualization.control.ActionShowPotentialField; import org.vadere.gui.onlinevisualization.control.ActionShowPotentialField;
import org.vadere.gui.onlinevisualization.model.OnlineVisualizationModel; import org.vadere.gui.onlinevisualization.model.OnlineVisualizationModel;
import org.vadere.gui.components.control.simulation.ActionSwapSelectionMode; import org.vadere.gui.components.control.simulation.ActionSwapSelectionMode;
...@@ -126,6 +127,9 @@ public class OnlineVisualisationWindow extends JPanel implements Observer { ...@@ -126,6 +127,9 @@ public class OnlineVisualisationWindow extends JPanel implements Observer {
AbstractAction drawVoronoiDiagram = new ActionSwapSelectionMode("draw_voronoi_diagram", resources.getIcon("voronoi.png", iconWidth, iconHeight), model); AbstractAction drawVoronoiDiagram = new ActionSwapSelectionMode("draw_voronoi_diagram", resources.getIcon("voronoi.png", iconWidth, iconHeight), model);
AbstractAction drawMesh = new ActionShowMesh("draw_mesh", resources.getIcon("triangulation.png", iconWidth, iconHeight), model);
AbstractAction paintGridAction = new AbstractAction("paintGridAction", AbstractAction paintGridAction = new AbstractAction("paintGridAction",
resources.getIcon("grid.png", iconWidth, iconHeight)) { resources.getIcon("grid.png", iconWidth, iconHeight)) {
...@@ -204,7 +208,8 @@ public class OnlineVisualisationWindow extends JPanel implements Observer { ...@@ -204,7 +208,8 @@ public class OnlineVisualisationWindow extends JPanel implements Observer {
Messages.getString("ProjectView.btnShowGroupInformation.tooltip")); Messages.getString("ProjectView.btnShowGroupInformation.tooltip"));
SwingUtils.addActionToToolbar(toolbar, drawVoronoiDiagram, SwingUtils.addActionToToolbar(toolbar, drawVoronoiDiagram,
Messages.getString("ProjectView.btnDrawVoronoiDiagram.tooltip")); Messages.getString("ProjectView.btnDrawVoronoiDiagram.tooltip"));
SwingUtils.addActionToToolbar(toolbar, drawMesh,
Messages.getString("ProjectView.btnDrawMesh.tooltip"));
toolbar.addSeparator(); toolbar.addSeparator();
......
...@@ -145,10 +145,6 @@ public class PostvisualizationModel extends SimulationModel<PostvisualizationCon ...@@ -145,10 +145,6 @@ public class PostvisualizationModel extends SimulationModel<PostvisualizationCon
} }
public void init(final Scenario vadere, final String projectPath) { public void init(final Scenario vadere, final String projectPath) {
// avoid the long computation
this.hideTriangulation();
this.triangulationTriggered = false;
this.vadere = vadere; this.vadere = vadere;
this.agentsByStep = new HashMap<>(); this.agentsByStep = new HashMap<>();
this.steps = new ArrayList<>(); this.steps = new ArrayList<>();
......
...@@ -166,25 +166,6 @@ public class PostvisualizationWindow extends JPanel implements Observer { ...@@ -166,25 +166,6 @@ public class PostvisualizationWindow extends JPanel implements Observer {
}, "ProjectView.btnShowTrajectories.tooltip"); }, "ProjectView.btnShowTrajectories.tooltip");
addActionToToolbar(toolbar,
new ActionVisualization("show_triangulation",
resources.getIcon("triangulation.png", iconWidth, iconHeight), model) {
@Override
public void actionPerformed(ActionEvent e) {
if(model.isTriangulationVisible()) {
model.hideTriangulation();
}
else {
model.showTriangulation();
}
model.notifyObservers();
}
;
}, "View.btnShowTriangulation.tooltip"
);
addActionToToolbar(toolbar, addActionToToolbar(toolbar,
new ActionVisualization("show_direction", new ActionVisualization("show_direction",
resources.getIcon("walking_direction.png", iconWidth, iconHeight), model) { resources.getIcon("walking_direction.png", iconWidth, iconHeight), model) {
......
...@@ -3,6 +3,7 @@ package org.vadere.meshing.mesh.gen; ...@@ -3,6 +3,7 @@ package org.vadere.meshing.mesh.gen;
import org.apache.log4j.LogManager; import org.apache.log4j.LogManager;
import org.apache.log4j.Logger; import org.apache.log4j.Logger;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.vadere.meshing.mesh.inter.IFace; import org.vadere.meshing.mesh.inter.IFace;
import org.vadere.meshing.mesh.inter.IHalfEdge; import org.vadere.meshing.mesh.inter.IHalfEdge;
import org.vadere.meshing.mesh.inter.IMesh; import org.vadere.meshing.mesh.inter.IMesh;
...@@ -52,7 +53,7 @@ public class MeshRenderer<P extends IPoint, V extends IVertex<P>, E extends IHal ...@@ -52,7 +53,7 @@ public class MeshRenderer<P extends IPoint, V extends IVertex<P>, E extends IHal
/** /**
* A function which decides by which color the face should be filled. * A function which decides by which color the face should be filled.
*/ */
private Function<F, Color> colorFunction; @Nullable private Function<F, Color> colorFunction;
/** /**
...@@ -65,7 +66,7 @@ public class MeshRenderer<P extends IPoint, V extends IVertex<P>, E extends IHal ...@@ -65,7 +66,7 @@ public class MeshRenderer<P extends IPoint, V extends IVertex<P>, E extends IHal
public MeshRenderer( public MeshRenderer(
@NotNull final IMesh<P, V, E, F> mesh, @NotNull final IMesh<P, V, E, F> mesh,
@NotNull final Predicate<F> alertPred, @NotNull final Predicate<F> alertPred,
@NotNull final Function<F, Color> colorFunction) { @Nullable final Function<F, Color> colorFunction) {
this.mesh = mesh; this.mesh = mesh;
this.alertPred = alertPred; this.alertPred = alertPred;
this.faces = new ArrayList<>(); this.faces = new ArrayList<>();
...@@ -73,7 +74,7 @@ public class MeshRenderer<P extends IPoint, V extends IVertex<P>, E extends IHal ...@@ -73,7 +74,7 @@ public class MeshRenderer<P extends IPoint, V extends IVertex<P>, E extends IHal
} }
/** /**
* Construct a mesh panel filling all faces with the color white. * Construct a mesh renderer which will not fill the faces.
* *
* @param mesh the mesh which will be rendered * @param mesh the mesh which will be rendered
* @param alertPred a {@link Predicate} of {@link F} which marks a face to be drawn in a special way. * @param alertPred a {@link Predicate} of {@link F} which marks a face to be drawn in a special way.
...@@ -81,51 +82,53 @@ public class MeshRenderer<P extends IPoint, V extends IVertex<P>, E extends IHal ...@@ -81,51 +82,53 @@ public class MeshRenderer<P extends IPoint, V extends IVertex<P>, E extends IHal
public MeshRenderer( public MeshRenderer(
@NotNull final IMesh<P, V, E, F> mesh, @NotNull final IMesh<P, V, E, F> mesh,
@NotNull final Predicate<F> alertPred) { @NotNull final Predicate<F> alertPred) {
this(mesh, alertPred, f -> Color.WHITE); this(mesh, alertPred, null);
} }