Commit 7fcdbcdd authored by Stefan Sechelmann's avatar Stefan Sechelmann

fix Garland&Heckbert algorithm and add test case

parent 2d3c639c
package de.jtem.halfedgetools.algorithm.simplification;
import java.io.InputStream;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import de.jreality.plugin.JRViewer;
import de.jreality.plugin.JRViewer.ContentType;
import de.jreality.reader.AbstractReader;
import de.jreality.reader.ReaderOBJ;
import de.jreality.scene.IndexedFaceSet;
import de.jreality.scene.SceneGraphComponent;
import de.jreality.util.Input;
import de.jreality.util.SceneGraphUtility;
import de.jtem.halfedgetools.adapter.AdapterSet;
import de.jtem.halfedgetools.jreality.ConverterJR2Heds;
import de.jtem.halfedgetools.jreality.adapter.JRNormalAdapter;
import de.jtem.halfedgetools.jreality.adapter.JRPositionAdapter;
import de.jtem.halfedgetools.jreality.node.DefaultJREdge;
import de.jtem.halfedgetools.jreality.node.DefaultJRFace;
import de.jtem.halfedgetools.jreality.node.DefaultJRHDS;
import de.jtem.halfedgetools.jreality.node.DefaultJRVertex;
import de.jtem.halfedgetools.plugin.HalfedgeInterface;
public class GarlandHeckbertTest {
private DefaultJRHDS
result = new DefaultJRHDS(),
expected = new DefaultJRHDS();
private AdapterSet
adapters = AdapterSet.createGenericAdapters();
public DefaultJRHDS loadGeometry(String resourceName, AbstractReader reader) throws Exception {
InputStream stream = GarlandHeckbertTest.class.getResourceAsStream(resourceName);
Input input = Input.getInput("", stream);
SceneGraphComponent component = reader.read(input);
IndexedFaceSet ifs = (IndexedFaceSet)SceneGraphUtility.getFirstGeometry(component);
ConverterJR2Heds converter = new ConverterJR2Heds();
DefaultJRHDS result = new DefaultJRHDS();
converter.ifs2heds(ifs, result, adapters);
return result;
}
@Before
public void setUp() throws Exception {
adapters.add(new JRPositionAdapter());
adapters.add(new JRNormalAdapter());
result = loadGeometry("cowSource.obj", new ReaderOBJ());
expected = loadGeometry("cowExpected.obj", new ReaderOBJ());
}
@Test
public void test() {
GarlandHeckbert<DefaultJRVertex, DefaultJREdge, DefaultJRFace, DefaultJRHDS>
gh = new GarlandHeckbert<DefaultJRVertex, DefaultJREdge, DefaultJRFace, DefaultJRHDS>(result, adapters);
gh.simplify(100);
Assert.assertEquals(expected.numVertices(), result.numVertices());
for (DefaultJRVertex vResult : result.getVertices()) {
DefaultJRVertex vExpected = expected.getVertex(vResult.getIndex());
double[] posResult = vResult.position;
double[] posExpected = vExpected.position;
Assert.assertArrayEquals("vertex " + vResult.getIndex(), posExpected, posResult, 1E-12);
}
}
public static void main(String[] args) throws Exception {
GarlandHeckbertTest test = new GarlandHeckbertTest();
test.setUp();
test.test();
JRViewer v = new JRViewer();
v.registerPlugin(HalfedgeInterface.class);
v.addContentSupport(ContentType.CenteredAndScaled);
v.addContentUI();
v.addBasicUI();
v.startup();
v.getPlugin(HalfedgeInterface.class).set(test.result);
}
}
package de.jtem.halfedgetools.algorithm.simplification;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.PriorityQueue;
import java.util.Set;
import javax.vecmath.Matrix3d;
import javax.vecmath.Tuple3d;
import javax.vecmath.Vector3d;
import de.jreality.math.Pn;
import de.jreality.math.Rn;
import de.jtem.halfedge.Edge;
import de.jtem.halfedge.Face;
......@@ -37,11 +35,11 @@ public class GarlandHeckbert <
activeMesh = null;
private AdapterSet
a = null;
private HashMap<E, EdgePQItem>
private Map<E, EdgePQItem>
edgeOperationMap = new HashMap<E, EdgePQItem>();
private PriorityQueue<EdgePQItem>
pq = new PriorityQueue<EdgePQItem>();
private HashMap<V, Quadric>
private Map<V, Quadric>
quadric_map = new HashMap<V, Quadric>();
private boolean
forceBoundary = false;
......@@ -52,7 +50,6 @@ public class GarlandHeckbert <
this.a = a;
}
private class Quadric {
public Matrix3d A;
......@@ -85,7 +82,7 @@ public class GarlandHeckbert <
return Double.compare(this.error, item.error);
}
public Set<E> collapse() {
public List<E> collapse() {
if (!isValidEdgeOperation(edge)) {
return null;
}
......@@ -113,8 +110,8 @@ public class GarlandHeckbert <
a.set(Position.class, v, location);
// get 2 ring (as sets)
Set<E> ring2EdgeSet = new HashSet<E>();
Set<V> ring2VertexSet = new HashSet<V>();
List<E> ring2EdgeSet = new LinkedList<E>();
List<V> ring2VertexSet = new LinkedList<V>();
List<V> ring1List = HalfEdgeUtilsExtra.getVertexStar(v);
for (V ring1Vertex : ring1List) {
......@@ -204,7 +201,7 @@ public class GarlandHeckbert <
System.out.println("ERROR: There is nothing left to simplify!");
return;
}
Set<E> l = p.collapse();
List<E> l = p.collapse();
if (l != null) {
for (E e : l) {
EdgePQItem edgePqItem = edgeOperationMap.get(e);
......@@ -293,8 +290,6 @@ public class GarlandHeckbert <
} else if (A.determinant() < Rn.TOLERANCE || (v1ob && v2ob)) {
double[] p1 = a.get(Position3d.class, v1, double[].class);
double[] p2 = a.get(Position3d.class, v2, double[].class);
Pn.dehomogenize(p1, p1);
Pn.dehomogenize(p2, p2);
v = Rn.linearCombination(null, 0.5, p1, 0.5, p2);
} else {
Ainv = new Matrix3d(A);
......
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