Commit 27380b79 authored by Stefan Schuhbaeck's avatar Stefan Schuhbaeck

rebase group_models to develop branch

parents 252ed8ea a9caddb3
......@@ -43,3 +43,4 @@ VadereGui/output/
#linux deskopt dotfiles
**/.directory
/VadereModelTests/TestStairs/output
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="744.09448819"
height="1052.3622047"
id="svg2"
version="1.1"
inkscape:version="0.48.4 r9939"
sodipodi:docname="source_icon.svg"
inkscape:export-filename="C:\Users\Benedikt\Repositories\Software\VadereGui\resources\icons\source_icon.png"
inkscape:export-xdpi="39.389999"
inkscape:export-ydpi="39.389999">
<defs
id="defs4" />
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="4"
inkscape:cx="508.27116"
inkscape:cy="318.54973"
inkscape:document-units="px"
inkscape:current-layer="layer1"
showgrid="false"
inkscape:window-width="1680"
inkscape:window-height="987"
inkscape:window-x="-8"
inkscape:window-y="-8"
inkscape:window-maximized="1" />
<metadata
id="metadata7">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<g
inkscape:groupmode="layer"
id="layer2"
inkscape:label="Ground">
<path
sodipodi:type="arc"
style="fill:#000000;fill-opacity:1;stroke:none"
id="path2999"
sodipodi:cx="567.25"
sodipodi:cy="745.61218"
sodipodi:rx="29"
sodipodi:ry="12.25"
d="m 596.25,745.61218 a 29,12.25 0 1 1 -58,0 29,12.25 0 1 1 58,0 z"
transform="matrix(1.2543104,0,0,1.132653,-152.88254,-93.532738)" />
</g>
<g
inkscape:label="Arrow Out"
inkscape:groupmode="layer"
id="layer1">
<path
style="fill:#800000"
d="m 523.54785,718.71229 c 3.67872,-11.89789 14.75259,-23.56593 25.00868,-26.35049 15.48687,-4.20472 28.23708,5.48211 29.97739,22.77504 0.84941,8.44048 0.94863,8.5832 5.84654,8.41155 7.70502,-0.27004 6.43547,2.77305 -5.6306,13.4965 l -11.11785,9.88075 -8.90828,-10.02363 c -4.89957,-5.51302 -8.8233,-10.84316 -8.71949,-11.84479 0.10385,-1.00163 2.96952,-1.86734 6.36816,-1.9238 5.73649,-0.0953 6.21234,-0.42061 6.63925,-4.53837 0.68171,-6.57556 -6.18382,-13.29468 -12.96608,-12.68957 -6.25183,0.5578 -17.03698,9.10527 -23.24218,18.41998 -5.07932,7.6246 -6.55947,5.07255 -3.25554,-5.61317 z"
id="path2996"
inkscape:connector-curvature="0" />
</g>
</svg>
......@@ -220,6 +220,7 @@ PostVis.chbShowStairs.text=Show Stairs
PostVis.btnSnapshot.tooltip=Snapshot
PostVis.btnPNGSnapshot.tooltip=PNG Snapshot
PostVis.btnSVGSnapshot.tooltip=SVG Snapshot
PostVis.btnTikZSnapshot.tooltip=TikZ Snapshot
PostVis.menuFile.title=File
PostVis.menuSettings.title=Setting
PostVis.menuRecentFiles.title=Recent Files
......
......@@ -220,6 +220,7 @@ PostVis.chbShowStairs.text=Treppen anzeigen
PostVis.btnSnapshot.tooltip=Snapshot
PostVis.btnPNGSnapshot.tooltip=PNG-Snapshot
PostVis.btnSVGSnapshot.tooltip=SVG-Snapshot
PostVis.btnTikZSnapshot.tooltip=TikZ Snapshot
PostVis.menuFile.title=Datei
PostVis.menuSettings.title=Einstellungen
PostVis.menuRecentFiles.title=K\u00FCrzlich verwendete Dateien
......
......@@ -106,12 +106,14 @@ public class ScenarioElementView extends JPanel implements ISelectScenarioElemen
}
@Override
public void removeUpdate(DocumentEvent e) {
public void removeUpdate(DocumentEvent e)
{
updateModel();
}
@Override
public void changedUpdate(DocumentEvent e) {
updateModel();
}
};
......@@ -126,7 +128,7 @@ public class ScenarioElementView extends JPanel implements ISelectScenarioElemen
ScenarioElement element = panelModel.getSelectedElement();
if (element != null) {
String json = txtrTextfiletextarea.getText();
//logger.info(json);
if (json.length() == 0)
return;
......@@ -143,7 +145,7 @@ public class ScenarioElementView extends JPanel implements ISelectScenarioElemen
} else {
try {
Attributes attributes = StateJsonConverter.deserializeScenarioElementType(json, element.getType());
ReflectionAttributeModifier.setAttributes(element, attributes);
element.setAttributes(attributes); // Replaces previous AttributeModifier.setAttributes (see #91)
ScenarioPanel.removeJsonParsingErrorMsg();
ProjectView.getMainWindow().refreshScenarioNames();
jsonValidIndicator.setValid();
......@@ -184,8 +186,8 @@ public class ScenarioElementView extends JPanel implements ISelectScenarioElemen
} else if (scenarioElement instanceof Pedestrian) {
this.txtrTextfiletextarea.setText(StateJsonConverter.serializeObject(scenarioElement));
} else {
this.txtrTextfiletextarea.setText(StateJsonConverter
.serializeObject(ReflectionAttributeModifier.getAttributes(scenarioElement)));
this.txtrTextfiletextarea.setText(StateJsonConverter
.serializeObject(scenarioElement.getAttributes()));
}
}
}
......
......@@ -36,7 +36,7 @@ public class OnlineVisualization implements PassiveCallback {
private OnlineVisualisationWindow onlineVisualisationPanel;
private OnlineVisualizationModel model;
private Topography scenario;
private IPotentialFieldTarget potentialFieldTarget;
private @Nullable IPotentialFieldTarget potentialFieldTarget;
private boolean enableVisualization;
public OnlineVisualization(boolean enableVisualization) {
......@@ -94,7 +94,7 @@ public class OnlineVisualization implements PassiveCallback {
new ObservationAreaSnapshotData(
simTimeInSec,
scenario.clone(),
model.config.isShowPotentialField() ? potentialFieldTarget.copyFields() : null));
(model.config.isShowPotentialField() && potentialFieldTarget != null) ? potentialFieldTarget.copyFields() : null));
}
}
......
package org.vadere.gui.onlinevisualization.control;
import org.apache.log4j.LogManager;
import org.apache.log4j.Logger;
import org.vadere.gui.components.model.DefaultSimulationConfig;
import org.vadere.gui.components.model.SimulationModel;
import org.vadere.gui.components.utils.Resources;
import org.vadere.gui.components.view.SimulationRenderer;
import org.vadere.gui.onlinevisualization.view.IRendererChangeListener;
import org.vadere.gui.postvisualization.PostVisualisation;
import org.vadere.gui.postvisualization.utils.SVGGenerator;
import org.vadere.gui.postvisualization.utils.TikzGenerator;
import javax.swing.*;
import java.awt.event.ActionEvent;
import java.io.File;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.prefs.Preferences;
public class ActionGenerateTikz extends AbstractAction implements IRendererChangeListener {
private static Logger logger = LogManager.getLogger(ActionGenerateTikz.class);
private static Resources resources = Resources.getInstance("postvisualization");
private final TikzGenerator tikzGenerator;
private final SimulationModel<? extends DefaultSimulationConfig> model;
public ActionGenerateTikz(final String name, final Icon icon, final SimulationRenderer renderer,
final SimulationModel<? extends DefaultSimulationConfig> model) {
super(name, icon);
this.tikzGenerator = new TikzGenerator(renderer, model);
this.model = model;
}
@Override
public void actionPerformed(ActionEvent e) {
Date todaysDate = new Date();
SimpleDateFormat formatter = new SimpleDateFormat(resources.getProperty("View.dataFormat"));
String formattedDate = formatter.format(todaysDate);
JFileChooser fileChooser = new JFileChooser(Preferences.userNodeForPackage(PostVisualisation.class).get("PostVis.snapshotDirectory.path", "."));
File outputFile = new File("pv_snapshot_" + formattedDate + ".tex");
fileChooser.setSelectedFile(outputFile);
int returnVal = fileChooser.showDialog(null, "Save");
if (returnVal == JFileChooser.APPROVE_OPTION) {
outputFile = fileChooser.getSelectedFile().toString().endsWith(".tex") ? fileChooser.getSelectedFile()
: new File(fileChooser.getSelectedFile().toString() + ".tex");
boolean completeDocument = true;
tikzGenerator.generateTikz(outputFile, completeDocument);
}
}
@Override
public void update(SimulationRenderer renderer) {}
}
......@@ -15,6 +15,7 @@ import org.vadere.gui.components.view.ScenarioScrollPane;
import org.vadere.gui.components.view.SimulationInfoPanel;
import org.vadere.gui.onlinevisualization.control.ActionGeneratePNG;
import org.vadere.gui.onlinevisualization.control.ActionGenerateSVG;
import org.vadere.gui.onlinevisualization.control.ActionGenerateTikz;
import org.vadere.gui.onlinevisualization.control.ActionOnlineVisMenu;
import org.vadere.gui.onlinevisualization.control.ActionShowPotentialField;
import org.vadere.gui.onlinevisualization.model.OnlineVisualizationModel;
......@@ -161,6 +162,12 @@ public class OnlineVisualisationWindow extends JPanel implements Observer {
new OnlinevisualizationRenderer(model),
model);
ActionGenerateTikz generateTikz = new ActionGenerateTikz(
"generateTikz",
resources.getIcon("camera_tikz.png", iconWidth, iconHeight),
new OnlinevisualizationRenderer(model),
model);
ActionShowPotentialField showPotentialField = new ActionShowPotentialField(
"showPotentialField",
resources.getIcon("potentialField.png", iconWidth, iconHeight),
......@@ -168,6 +175,7 @@ public class OnlineVisualisationWindow extends JPanel implements Observer {
mainPanel.addRendererChangeListener(generatePNG);
mainPanel.addRendererChangeListener(generateSVG);
mainPanel.addRendererChangeListener(generateTikz);
mainPanel.addRendererChangeListener(showPotentialField);
......@@ -190,6 +198,7 @@ public class OnlineVisualisationWindow extends JPanel implements Observer {
ArrayList<Action> imgOptions = new ArrayList<>();
imgOptions.add(generatePNG);
imgOptions.add(generateSVG);
imgOptions.add(generateTikz);
ActionOnlineVisMenu imgDialog = new ActionOnlineVisMenu(
"camera_menu",
......
package org.vadere.gui.postvisualization.control;
import org.apache.log4j.LogManager;
import org.apache.log4j.Logger;
import org.vadere.gui.components.utils.Resources;
import org.vadere.gui.postvisualization.PostVisualisation;
import org.vadere.gui.postvisualization.utils.TikzGenerator;
import org.vadere.gui.postvisualization.view.PostvisualizationRenderer;
import javax.swing.*;
import java.awt.event.ActionEvent;
import java.io.File;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.prefs.Preferences;
public class ActionGenerateTikz extends ActionVisualization {
private static Logger logger = LogManager.getLogger(ActionGenerateTikz.class);
private static Resources resources = Resources.getInstance("postvisualization");
private final TikzGenerator tikzGenerator;
public ActionGenerateTikz(final String name, final Icon icon, final PostvisualizationRenderer renderer) {
super(name, icon, renderer.getModel());
this.tikzGenerator = new TikzGenerator(renderer, renderer.getModel());
}
@Override
public void actionPerformed(ActionEvent e) {
Date todaysDate = new Date();
SimpleDateFormat formatter = new SimpleDateFormat(resources.getProperty("View.dataFormat"));
String formattedDate = formatter.format(todaysDate);
JFileChooser fileChooser = new JFileChooser(Preferences.userNodeForPackage(PostVisualisation.class).get("PostVis.snapshotDirectory.path", "."));
File outputFile = new File("pv_snapshot_" + formattedDate + ".tex");
fileChooser.setSelectedFile(outputFile);
int returnVal = fileChooser.showDialog(null, "Save");
if (returnVal == JFileChooser.APPROVE_OPTION) {
outputFile = fileChooser.getSelectedFile().toString().endsWith(".tex") ? fileChooser.getSelectedFile()
: new File(fileChooser.getSelectedFile().toString() + ".tex");
boolean completeDocument = true;
tikzGenerator.generateTikz(outputFile, completeDocument);
}
}
}
package org.vadere.gui.postvisualization.utils;
import org.apache.log4j.LogManager;
import org.apache.log4j.Logger;
import org.vadere.gui.components.model.DefaultSimulationConfig;
import org.vadere.gui.components.model.SimulationModel;
import org.vadere.gui.components.view.SimulationRenderer;
import org.vadere.state.scenario.*;
import java.awt.*;
import java.awt.geom.AffineTransform;
import java.awt.geom.PathIterator;
import java.io.*;
import java.util.*;
import static java.awt.geom.PathIterator.*;
/**
* Convert the (Java) scenario description into a TikZ representation.
*
* Usually, each (Java) scenario element is represented as a path via
* @see PathIterator This PathSeparator must be converted into its TikZ
* representation.
*
* For example, traversing a Java path with PathIterator returns two
* segments:
*
*
* segment type= 0 (SEG_MOVETO) with coords: [1.0, 1.0, 0.0, 0.0, 0.0, 0.0]
* segment type= 3 (SEG_LINETO) with coords: [2.0, 2.0, 0.0, 0.0, 0.0, 0.0]
*
* This must be transformed to TikZ:
*
* (1.0,1.0) to (2.0,2.0)
*
* The TikZGenerator should also respect the GUI settings (e.g., enabled
* elements, colors etc.).
*/
public class TikzGenerator {
private final static Logger logger = LogManager.getLogger(TikzGenerator.class);
private final SimulationRenderer renderer;
private final SimulationModel<? extends DefaultSimulationConfig> model;
private final String[] translationTable;
public TikzGenerator(final SimulationRenderer renderer,
final SimulationModel<? extends DefaultSimulationConfig> model) {
this.renderer = renderer;
this.model = model;
this.translationTable = new String[SEG_CLOSE + 1];
initializeTranslationTable(translationTable);
}
private void initializeTranslationTable(String[] translationTable) {
// Map Java path commands to TikZ commands.
translationTable[SEG_MOVETO] = "(%f,%f) ";
translationTable[SEG_LINETO] = "to (%f,%f) ";
translationTable[SEG_QUADTO] = ".. controls (%f,%f) .. (%f,%f) ";
translationTable[SEG_CUBICTO] = ".. controls (%f,%f) and (%f,%f) .. (%f,%f) ";
translationTable[SEG_CLOSE] = "to cycle;";
}
public void generateTikz(final File file, final boolean generateCompleteDocument) {
String texTemplate = "" +
"\\documentclass{standalone}\n" +
"\\usepackage{tikz}\n\n" +
"\\begin{document}\n" +
"\\begin{tikzpicture}\n" +
"%s" +
"\\end{tikzpicture}\n" +
"\\end{document}\n";
String tikzCode = "";
tikzCode += generateTikzColorDefinitions(model);
tikzCode += convertScenarioElementsToTikz();
String output = (generateCompleteDocument) ? String.format(texTemplate, tikzCode) : tikzCode ;
// TODO: maybe uses Java's resources notation (in general, writing the file should be done by the caller not here).
try {
file.createNewFile();
Writer out = new OutputStreamWriter(new FileOutputStream(file), "UTF-8");
out.write(output);
out.flush();
logger.info("generate new TikZ: " + file.getAbsolutePath());
} catch (IOException e1) {
logger.error(e1.getMessage());
e1.printStackTrace();
}
}
private String generateTikzColorDefinitions(SimulationModel<? extends DefaultSimulationConfig> model) {
String colorDefinitions = "% Color Definitions\n";
String colorTextPattern = "\\definecolor{%s}{RGB}{%d,%d,%d}\n";
Color sourceColor = model.getConfig().getSourceColor();
colorDefinitions += String.format(colorTextPattern, "SourceColor", sourceColor.getRed(), sourceColor.getGreen(), sourceColor.getBlue());
Color targetColor = model.getConfig().getTargetColor();
colorDefinitions += String.format(colorTextPattern, "TargetColor", targetColor.getRed(), targetColor.getGreen(), targetColor.getBlue());
Color obstacleColor = model.getConfig().getObstacleColor();
colorDefinitions += String.format(colorTextPattern, "ObstacleColor", obstacleColor.getRed(), obstacleColor.getGreen(), obstacleColor.getBlue());
Color stairColor = model.getConfig().getStairColor();
colorDefinitions += String.format(colorTextPattern, "StairColor", stairColor.getRed(), stairColor.getGreen(), stairColor.getBlue());
Color agentColor = model.getConfig().getPedestrianDefaultColor();
colorDefinitions += String.format(colorTextPattern, "AgentColor", agentColor.getRed(), agentColor.getGreen(), agentColor.getBlue());
return colorDefinitions;
}
private String convertScenarioElementsToTikz() {
String generatedCode = "";
DefaultSimulationConfig config = model.getConfig();
Topography topography = model.getTopography();
// Draw background elements first, then agents.
generatedCode += "% Ground\n";
String groundTextPattern = (config.isShowGrid()) ? "\\draw[help lines] (%f,%f) grid (%f,%f);\n" : "\\fill[white] (%f,%f) rectangle (%f,%f);\n";
generatedCode += String.format(groundTextPattern,
topography.getBounds().x,
topography.getBounds().y,
topography.getBounds().x + topography.getBounds().width,
topography.getBounds().y + topography.getBounds().height);
if (config.isShowSources()) {
generatedCode += "% Sources\n";
for (Source source : topography.getSources()) {
generatedCode += String.format("\\fill[SourceColor] %s\n", generatePathForScenarioElement(source));
}
} else {
generatedCode += "% Sources (not enabled in config)\n";
}
if (config.isShowTargets()) {
generatedCode += "% Targets\n";
for (Target target : topography.getTargets()) {
generatedCode += String.format("\\fill[TargetColor] %s\n", generatePathForScenarioElement(target));
}
} else {
generatedCode += "% Targets (not enabled in config)\n";
}
if (config.isShowObstacles()) {
generatedCode += "% Obstacles\n";
for (Obstacle obstacle : topography.getObstacles()) {
generatedCode += String.format("\\fill[ObstacleColor] %s\n", generatePathForScenarioElement(obstacle));
}
} else {
generatedCode += "% Obstacles (not enabled in config)\n";
}
if (config.isShowStairs()) {
generatedCode += "% Stairs\n";
for (Stairs stair : topography.getStairs()) {
generatedCode += String.format("\\fill[StairColor] %s\n", generatePathForScenarioElement(stair));
}
} else {
generatedCode += "% Stairs (not enabled in config)\n";
}
// TODO: maybe, draw also trajectories.
if (config.isShowPedestrians()) {
generatedCode += "% Agents\n";
for (Agent agent : model.getAgents()) {
String agentTextPattern = "\\fill[AgentColor] (%f,%f) circle [radius=%fcm];\n";
generatedCode += String.format(agentTextPattern, agent.getPosition().x, agent.getPosition().y, agent.getRadius());
// Do not draw agents as path for performance reasons. Usually, agents have a circular shape.
// generatedCode += String.format("\\fill[AgentColor] %s\n", generatePathForScenarioElement(agent));
}
} else {
generatedCode += "% Agents (not enabled in config)\n";
}
return generatedCode;
}
private String generatePathForScenarioElement(ScenarioElement element) {
String generatedPath = "";
AffineTransform noTransformation = new AffineTransform();
PathIterator pathIterator = element.getShape().getPathIterator(noTransformation);
while (!pathIterator.isDone()) {
float[] coords = new float[6];
int type = pathIterator.currentSegment(coords);
generatedPath += convertJavaToTikzPath(type, coords);
pathIterator.next();
}
return generatedPath;
}
private String convertJavaToTikzPath(int type, float[] coords) {
if (type < SEG_MOVETO || type > SEG_CLOSE) {
throw new IllegalStateException(String.format("Cannot process path segment type: %d (coordinates: %s)", type, Arrays.toString(coords)));
}
String convertedPath = translationTable[type];