Commit f7fcfdb6 authored by Alina Hinzmann's avatar Alina Hinzmann

implemented ttf lineset label visualization, library update

parent 02950fc4
......@@ -32,5 +32,7 @@
<classpathentry kind="lib" path="lib/itext/itext-pdfa-5.5.5.jar"/>
<classpathentry kind="lib" path="lib/itext/itext-xtra-5.5.5.jar"/>
<classpathentry kind="lib" path="lib/itext/itextpdf-5.5.5_dgdgitlab.jar"/>
<classpathentry kind="lib" path="lib/batik/batik-svggen-1.8.jar"/>
<classpathentry kind="lib" path="lib/batik/batik-util-1.8.jar"/>
<classpathentry kind="output" path="bin"/>
</classpath>
package de.jtem.halfedgetools.plugin.data.visualizer;
import de.jreality.geometry.BoundingBoxUtility;
import de.jreality.geometry.TTFLineSetFactory;
import de.jreality.math.Matrix;
import de.jreality.math.MatrixBuilder;
import de.jreality.math.Rn;
import de.jreality.scene.Appearance;
import de.jreality.scene.IndexedLineSet;
import de.jreality.scene.SceneGraphComponent;
import de.jreality.shader.CommonAttributes;
import de.jreality.util.Rectangle3D;
import de.jreality.util.SceneGraphUtility;
import de.jtem.halfedge.Edge;
import de.jtem.halfedge.Face;
import de.jtem.halfedge.Vertex;
import de.jtem.halfedgetools.adapter.Adapter;
import de.jtem.halfedgetools.adapter.AdapterSet;
import de.jtem.halfedgetools.adapter.type.Normal;
import de.jtem.halfedgetools.adapter.type.generic.BaryCenter3d;
import de.jtem.halfedgetools.adapter.type.generic.EdgeVector;
import de.jtem.halfedgetools.adapter.type.generic.Position3d;
import de.jtem.halfedgetools.plugin.HalfedgeInterface;
import de.jtem.halfedgetools.plugin.HalfedgeLayer;
import de.jtem.halfedgetools.plugin.data.AbstractDataVisualization;
import de.jtem.halfedgetools.plugin.data.DataVisualization;
import de.jtem.halfedgetools.plugin.data.DataVisualizer;
import de.jtem.halfedgetools.plugin.data.DataVisualizerPlugin;
import de.jtem.halfedgetools.plugin.image.ImageHook;
import de.jtem.jrworkspace.plugin.Controller;
import de.jtem.jrworkspace.plugin.PluginInfo;
public class LabelVisualizer extends DataVisualizerPlugin {
private HalfedgeInterface
hif = null;
private class LabelVisualization extends AbstractDataVisualization {
private SceneGraphComponent visualizationRoot = new SceneGraphComponent("Label visualization root");
private TTFLineSetFactory
ttfLineSetFactory = new TTFLineSetFactory();
public LabelVisualization(
HalfedgeLayer layer,
Adapter<?> source,
......@@ -20,10 +49,149 @@ public class LabelVisualizer extends DataVisualizerPlugin {
NodeType type
) {
super(layer, source, visualizer, type);
visualizationRoot.setName("Label for " + source.toString());
ttfLineSetFactory.setTTFFont(LabelVisualizer.class.getResource("Raleway-Thin.ttf").getPath());
ttfLineSetFactory.setSingleLineFont(false);
}
@Override
public void update() {
dispose();
AdapterSet a = hif.getAdapters();
visualizationRoot.removeAllChildren();
ttfLineSetFactory.setSize(0.03);
switch (getType()) {
case Vertex: {
int numDigits = (int) Math.ceil(Math.log10(getLayer().get().numVertices()));
for (Vertex<?, ?, ?> v : getLayer().get().getVertices()) {
String label = getSource().get(v, a).toString();
SceneGraphComponent sgc = new SceneGraphComponent("V" + String.format("%0"+numDigits+"d",v.getIndex()));
IndexedLineSet labelLineSet = ttfLineSetFactory.getIndexLineSet(label);
sgc.setGeometry(labelLineSet);
double[] labelCenter = BoundingBoxUtility.calculateBoundingBox(labelLineSet).getCenter();
double[] center = a.getD(Position3d.class, v);
double[] normal = a.getD(Normal.class, v);
Matrix M = MatrixBuilder.euclidean()
.translate(center)
.rotateFromTo(new double[]{0, 0,1}, normal)
.translate(Rn.negate(null, labelCenter))
.getMatrix();
M.assignTo(sgc);
SceneGraphUtility.addChildNode(visualizationRoot, sgc);
}
break;
}
case Edge: {
int numDigits = (int) Math.ceil(Math.log10(getLayer().get().numEdges()));
for (Edge<?, ?, ?> e : getLayer().get().getEdges()) {
String label = getSource().get(e, a).toString();
SceneGraphComponent sgc = new SceneGraphComponent("E" + String.format("%0"+numDigits+"d",e.getIndex()));
sgc.setGeometry(ttfLineSetFactory.getIndexLineSet(label));
Rectangle3D labelBoundingBox = BoundingBoxUtility.calculateBoundingBox(ttfLineSetFactory.getIndexLineSet(label));
double[] edgeVector = a.getD(EdgeVector.class, e);
double[][] localCoordinateSystem = getFaceCoordinateSystem(e.getLeftFace(),a);
double[] anchorPoint = getAnchorPoint(edgeVector, localCoordinateSystem, labelBoundingBox);
double[] edgeCenter = a.getD(BaryCenter3d.class, e);
double[] faceCenter = a.getD(BaryCenter3d.class, e.getLeftFace());
Rn.linearCombination(edgeCenter, 0.95, edgeCenter, 0.05, faceCenter);
Matrix M = getTransformationMatrix(localCoordinateSystem, edgeCenter);
M.multiplyOnRight(MatrixBuilder.euclidean().translate(Rn.negate(null, anchorPoint)).getMatrix());
M.assignTo(sgc);
SceneGraphUtility.addChildNode(visualizationRoot, sgc);
}
break;
}
case Face: {
int numDigits = (int) Math.ceil(Math.log10(getLayer().get().numFaces()));
for (Face<?, ?, ?> f : getLayer().get().getFaces()) {
String label = getSource().get(f, a).toString();
SceneGraphComponent sgc = new SceneGraphComponent("F" + String.format("%0"+numDigits+"d",f.getIndex()));
IndexedLineSet labelLineSet = ttfLineSetFactory.getIndexLineSet(label);
sgc.setGeometry(labelLineSet);
double[] bbCenter = BoundingBoxUtility.calculateBoundingBox(labelLineSet).getCenter();
double[] center = a.getD(BaryCenter3d.class, f);
double[][] localCoordinateSystem = getFaceCoordinateSystem(f,a);
Matrix M = getTransformationMatrix(localCoordinateSystem, center);
M.multiplyOnRight(MatrixBuilder.euclidean().translate(Rn.negate(null, bbCenter)).getMatrix());
M.assignTo(sgc);
SceneGraphUtility.addChildNode(visualizationRoot, sgc);
}
break;
}
}
Appearance app = ttfLineSetFactory.getStandardAppearance();
app.setAttribute(CommonAttributes.EDGE_DRAW, true);
visualizationRoot.setAppearance(app);
getLayer().addTemporaryGeometry(visualizationRoot);
}
@Override
public void dispose() {
getLayer().removeTemporaryGeometry(visualizationRoot);
}
@Override
public void setActive(boolean active) {
visualizationRoot.setVisible(active);
}
@Override
public boolean isActive() {
return visualizationRoot.isVisible();
}
private double[] getAnchorPoint(double[] edge, double[][] localCoordinateSystem, Rectangle3D bb) {
double signX = Rn.innerProduct(edge, localCoordinateSystem[1]); //comment!
double signY = -Rn.innerProduct(edge, localCoordinateSystem[0]);
double[] anchorPoint = new double[3];
anchorPoint[0] = (signX>0)?bb.getMaxX():bb.getMinX();
anchorPoint[1] = (signY>0)?bb.getMaxY():bb.getMinY();
if(Math.abs(signX) < 1E-6) {
anchorPoint[0] = bb.getCenter()[0];
}
if(Math.abs(signY) < 1E-6) {
anchorPoint[1] = bb.getCenter()[1];
}
anchorPoint[2] = bb.getMinZ();
return anchorPoint;
}
private double[][] getFaceCoordinateSystem(Face<?,?,?> f, AdapterSet as) {
double[] upDirection = new double[]{0,0,1};
double[][] faceCoordinateSystem = new double[3][3];
faceCoordinateSystem[2] = as.getD(Normal.class, f);
faceCoordinateSystem[1] = Rn.projectOntoComplement(null, upDirection, faceCoordinateSystem[2]);
if(Rn.euclideanNorm(faceCoordinateSystem[1]) < 1E-6) {
faceCoordinateSystem[1] = Rn.projectOntoComplement(null, new double[]{0, 1,0}, faceCoordinateSystem[2]);
}
Rn.normalize(faceCoordinateSystem[1], faceCoordinateSystem[1]);
faceCoordinateSystem[0] = Rn.crossProduct(null, faceCoordinateSystem[1], faceCoordinateSystem[2]);
return faceCoordinateSystem;
}
private Matrix getTransformationMatrix(double[][] faceCoordinateSystem, double[] faceCenter) {
Matrix matrix = new Matrix(
faceCoordinateSystem[0][0], faceCoordinateSystem[1][0], faceCoordinateSystem[2][0], faceCenter[0],
faceCoordinateSystem[0][1], faceCoordinateSystem[1][1], faceCoordinateSystem[2][1], faceCenter[1],
faceCoordinateSystem[0][2], faceCoordinateSystem[1][2], faceCoordinateSystem[2][2], faceCenter[2],
0,0,0,1
);
return matrix;
}
}
......@@ -51,7 +219,9 @@ public class LabelVisualizer extends DataVisualizerPlugin {
}
@Override
public void disposeVisualization(DataVisualization vis) {
public void install(Controller c) throws Exception {
super.install(c);
hif = c.getPlugin(HalfedgeInterface.class);
}
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment