use of maspack.matrix.Point3d in project artisynth_core by artisynth.
the class PointMeshRenderer method buildRenderObject.
@Override
protected RenderObject buildRenderObject(MeshBase mesh, RenderProps props) {
RenderObject r = super.buildRenderObject(mesh, props);
PointMesh pmesh = (PointMesh) mesh;
int[] nidxs = pmesh.hasNormals() ? pmesh.getNormalIndices() : null;
int[] cidxs = pmesh.hasColors() ? pmesh.getColorIndices() : null;
int[] tidxs = pmesh.hasTextureCoords() ? pmesh.getTextureIndices() : null;
int numv = pmesh.numVertices();
for (int i = 0; i < numv; i++) {
r.addVertex(i, nidxs != null ? nidxs[i] : -1, cidxs != null ? cidxs[i] : -1, tidxs != null ? tidxs[i] : -1);
r.addPoint(i);
}
Point3d tip = new Point3d();
double normalLen = pmesh.getNormalRenderLen();
if (normalLen > 0 && pmesh.hasNormals()) {
ArrayList<Vector3d> nrmls = pmesh.getNormals();
for (int i = 0; i < numv; i++) {
Point3d pnt = pmesh.getVertex(i).pnt;
tip.scaledAdd(normalLen, nrmls.get(nidxs[i]), pnt);
r.addPosition((float) tip.x, (float) tip.y, (float) tip.z);
r.addVertex(numv + i, nidxs[i], -1, -1);
r.addLine(i, numv + i);
}
}
return r;
}
use of maspack.matrix.Point3d in project artisynth_core by artisynth.
the class StlReader method readBinary.
public static PolygonalMesh readBinary(PolygonalMesh mesh, InputStream is, double tol) throws IOException {
boolean _printDebug = false;
// Byte ordering is assumed to be Little Endian (see wikipedia on STL format).
// Format of binary STL is
// 80 byte header (skip)
// 4 byte int indicating num facets to follow
is.skip(80);
byte[] bbuf = new byte[4];
is.read(bbuf, 0, 4);
// This is a simple way to read unsigned long from 4 bytes (LittleEndian)
// There is no other method for reading unsigned 4-byte Int with ByteBuffer!
long numFacets = 0;
numFacets |= bbuf[3] & 0xFF;
numFacets <<= 8;
numFacets |= bbuf[2] & 0xFF;
numFacets <<= 8;
numFacets |= bbuf[1] & 0xFF;
numFacets <<= 8;
numFacets |= bbuf[0] & 0xFF;
if (_printDebug) {
System.out.println("Num facets: " + numFacets);
}
ArrayList<Point3d> nodeList = new ArrayList<Point3d>();
ArrayList<ArrayList<Integer>> faceList = new ArrayList<ArrayList<Integer>>();
if (_printDebug) {
System.out.print("Reading file... ");
}
// For big files, it is slightly faster to read one facet
// at a time than the whole file at once (for some reason).
long start = System.nanoTime();
int facetSize = 50;
bbuf = new byte[facetSize];
List<Point3d> allPoints = new ArrayList<Point3d>(3 * (int) numFacets);
List<Point3d[]> allFaces = new ArrayList<Point3d[]>((int) numFacets);
for (long i = 0; i < numFacets; i++) {
int nBytesRead = is.read(bbuf, 0, facetSize);
if (nBytesRead < facetSize) {
throw new IOException("Invalid STL file detected! (non-matching size)");
}
ByteBuffer bb = ByteBuffer.wrap(bbuf);
bb.order(ByteOrder.LITTLE_ENDIAN);
// Ignore normal
bb.getFloat();
bb.getFloat();
bb.getFloat();
Point3d[] face = new Point3d[3];
// Read all 3 vertices
double[] vals = new double[3];
for (int j = 0; j < 3; j++) {
vals[0] = bb.getFloat();
vals[1] = bb.getFloat();
vals[2] = bb.getFloat();
Point3d pnt;
pnt = new Point3d(vals);
allPoints.add(pnt);
face[j] = pnt;
}
allFaces.add(face);
// Attribute byte count should = 0
bb.getShort();
}
if (_printDebug) {
System.out.println("(" + 1.e-9 * (System.nanoTime() - start) + ")");
System.out.print("Building spatial hash table... ");
start = System.nanoTime();
}
SpatialHashTable<Point3d> table = new SpatialHashTable<Point3d>(tol);
table.setup(allPoints, allPoints);
if (_printDebug) {
System.out.println("(" + 1.e-9 * (System.nanoTime() - start) + ")");
System.out.print("Scanning for unique verts... ");
start = System.nanoTime();
}
HashMap<Point3d, Integer> allToUniqueMap = new HashMap<Point3d, Integer>(allPoints.size());
double tolSq = tol * tol;
for (Point3d pnt : allPoints) {
if (allToUniqueMap.containsKey(pnt)) {
continue;
}
// Find all points within tol of pnt
List<Point3d> results = new ArrayList<Point3d>();
// table.getCellsNearOld (pnt);
List<Point3d> cell = table.getElsNear(pnt);
// continue;
if (cell != null) {
for (Point3d neighbour : cell) {
if (neighbour.distanceSquared(pnt) < tolSq) {
results.add(neighbour);
}
}
}
int idx = nodeList.size();
nodeList.add(pnt);
for (Point3d neighbour : results) {
allToUniqueMap.put(neighbour, idx);
}
}
if (_printDebug) {
System.out.println("(" + 1.e-9 * (System.nanoTime() - start) + ")");
System.out.print("Building faceList... ");
start = System.nanoTime();
}
// Build face list by looking up the index of the Unique vert through hashmap.
for (Point3d[] face : allFaces) {
ArrayList<Integer> faceNodes = new ArrayList<Integer>(3);
for (int i = 0; i < 3; i++) {
int idx = allToUniqueMap.get(face[i]);
faceNodes.add(idx);
}
faceList.add(faceNodes);
}
if (_printDebug) {
System.out.println("(" + 1.e-9 * (System.nanoTime() - start) + ")");
System.out.print("building mesh... ");
start = System.nanoTime();
}
mesh = buildMesh(mesh, nodeList, faceList);
if (_printDebug) {
System.out.println("(" + 1.e-9 * (System.nanoTime() - start) + ")");
System.out.println("Done!");
System.out.println("Unique verts: " + nodeList.size());
System.out.println("Unique faces: " + allFaces.size());
}
return mesh;
}
use of maspack.matrix.Point3d in project artisynth_core by artisynth.
the class StlReader method readFace.
private static ArrayList<Integer> readFace(ReaderTokenizer rtok, ArrayList<Point3d> nodes, double tol) throws IOException {
ArrayList<Integer> faceNodes = new ArrayList<Integer>(3);
String word = rtok.scanWord();
if (!word.toLowerCase().equals("normal")) {
throw new IOException("Expecting a normal on line " + rtok.lineno());
}
// read and discard normals
double[] vals = new double[3];
int n = rtok.scanNumbers(vals, 3);
toEOL(rtok);
// expecting "outer loop"
String line = readLine(rtok);
if (!line.toLowerCase().trim().equals("outer loop")) {
throw new IOException("Expecting 'outer loop' on line " + rtok.lineno());
}
word = rtok.scanWord();
while (word.toLowerCase().equals("vertex") && rtok.ttype != ReaderTokenizer.TT_EOF) {
n = rtok.scanNumbers(vals, 3);
if (n != 3) {
throw new IOException("Invalid vertex on line " + rtok.lineno());
}
int idx = findOrAddNode(new Point3d(vals), nodes, tol);
faceNodes.add(idx);
toEOL(rtok);
word = rtok.scanWord();
}
// endloop
if (!word.toLowerCase().equals("endloop")) {
throw new IOException("Expected 'endloop' on line " + rtok.lineno());
}
toEOL(rtok);
// endfacet
word = rtok.scanWord();
if (!word.toLowerCase().equals("endfacet")) {
throw new IOException("Expected 'endfacet' on line " + rtok.lineno());
}
toEOL(rtok);
return faceNodes;
}
use of maspack.matrix.Point3d in project artisynth_core by artisynth.
the class StlReader method readASCII.
public static PolygonalMesh readASCII(PolygonalMesh mesh, Reader reader, double tol) throws IOException {
ReaderTokenizer rtok = new ReaderTokenizer(reader);
ArrayList<Point3d> nodeList = new ArrayList<Point3d>();
ArrayList<ArrayList<Integer>> faceList = new ArrayList<ArrayList<Integer>>();
rtok.eolIsSignificant(true);
String solidName = "";
// read until we find "solid"
while (rtok.nextToken() != ReaderTokenizer.TT_EOF) {
if (rtok.ttype == ReaderTokenizer.TT_WORD) {
String word = rtok.sval.toLowerCase();
if (word.equals("solid")) {
rtok.nextToken();
if (rtok.ttype == ReaderTokenizer.TT_WORD) {
solidName = rtok.sval;
}
toEOL(rtok);
} else if (word.equals("facet")) {
ArrayList<Integer> face = readFace(rtok, nodeList, tol);
if (face != null) {
faceList.add(face);
}
} else if (word.equals("endsolid") || word.equals("end")) {
boolean setMeshName = true;
if (mesh != null) {
setMeshName = false;
}
mesh = buildMesh(mesh, nodeList, faceList);
if (setMeshName) {
mesh.setName(solidName);
}
return mesh;
}
}
}
return null;
}
use of maspack.matrix.Point3d in project artisynth_core by artisynth.
the class WavefrontReader method getVertexPoints.
public Point3d[] getVertexPoints() {
Point3d[] pnts = new Point3d[vertexList.size()];
int i = 0;
for (Iterator<?> it = vertexList.iterator(); it.hasNext(); ) {
pnts[i] = new Point3d();
pnts[i].setFromHomogeneous((Vector4d) it.next());
i++;
}
return pnts;
}
Aggregations