use of maspack.matrix.Point3d in project artisynth_core by artisynth.
the class WavefrontReader method getLocalFaceIndicesAndVertices.
public int[][] getLocalFaceIndicesAndVertices(ArrayList<Point3d> vtxList) throws IOException {
int[] indexMap = new int[vertexList.size()];
for (Face face : myCurrentGroup.faceList) {
markIndexMap(face.indices, indexMap, face.lineNum);
}
int idx = 0;
for (int i = 0; i < indexMap.length; i++) {
if (indexMap[i] == 1) {
indexMap[i] = idx++;
Point3d pnt = new Point3d();
pnt.setFromHomogeneous(vertexList.get(i));
vtxList.add(pnt);
}
}
if (idx == 0) {
return null;
}
int[][] indexList = new int[myCurrentGroup.faceList.size()][];
int i = 0;
for (Face face : myCurrentGroup.faceList) {
indexList[i++] = reindex(face.indices, indexMap);
}
return indexList;
}
use of maspack.matrix.Point3d in project artisynth_core by artisynth.
the class Polyline method computeLength.
/**
* Computes the length of this line.
*/
public double computeLength() {
double len = 0;
if (myVtxs.length > 1) {
Point3d last = myVtxs[0].pnt;
for (int i = 1; i < myVtxs.length; i++) {
len += last.distance(myVtxs[i].pnt);
last = myVtxs[i].pnt;
}
}
return len;
}
use of maspack.matrix.Point3d in project artisynth_core by artisynth.
the class RobustPreds method initialize.
static void initialize() {
// try loading in the native code
try {
NativeLibraryManager.load("RobustPreds.1.1");
nativeSupportLoaded = true;
// cache the x,y,z fieldIDs
jniInit(new Point3d());
} catch (UnsatisfiedLinkError e) {
System.out.println("err=" + e.getMessage() + " java.library.path=" + System.getProperty("java.library.path"));
throw new UnsupportedOperationException("Can't load native library \"RobustPreds\". java.library.path=" + System.getProperty("java.library.path"));
}
}
use of maspack.matrix.Point3d in project artisynth_core by artisynth.
the class RobustPreds method intersectEdgeTriangle.
/**
* Tests for the intersection of an edge and a triangle described by a
* face. Returns an intersection and a non-zero set of flags if there
* is. Flags may include {@link #INTERSECTS} (always set if there is an
* intersection), {@link #TAIL_OUTSIDE}, {@link #TAIL_ON_TRIANGLE}, {@link
* #HEAD_ON_TRIANGLE}, {@link #E01_ON_SEGMENT}, {@link #E12_ON_SEGMENT}, and
* {@link #E20_ON_SEGMENT}. If there is an intersection, and
* <code>ipnt</code> is non-<code>null</code>, then the intersection point
* is computed and returned in <code>ipnt</code>.
*
* <p>If {@code maxlen > 0}, the method first performs a quick numeric
* calculation to see if the intersection can be determined within to
* tolerance based on <code>maxlen</code>. If it cannot, then a more
* detailed calculation is performed using robust predicates. In order to
* work properly, <code>maxlen</code> must be {@code >=} the length of the
* edge and any of the face edges. If <code>maxlen</code> = 0, then the
* robust predicates are called directly.
*
* <p>If tie-breaking is needed, then this is done using "Simulation of
* Simplicity", as described in the class header, by assigning unique
* indices to each vertex based on their underlying mesh indices. If the
* meshes are different, then if <code>edgeOnMesh0</code> is
* <code>true</code>, we increment the face vertex indices by the number of
* vertices on the edge mesh, while if it is <code>false</code> we increment
* the edge vertex indices by the number of vertices on the face mesh.
*
* @param ipnt if non-<code>null</code> and if the edge and face intersect,
* returns the intersection point
* @param edge edge to test for intersection
* @param face face to test for intersection
* @param maxlen if {@code > 0}, specifies an upper bound for the length of
* the edge and face edges which is used to see if the intersection can be
* determined using regular double precision
* @param edgeOnMesh0 used to determine vertex indices for tie-breaking,
* as described above
* @param worldCoords if <code>true</code>, computes the intersection
* in world coordinates. Otherwise, mesh local coordinates are used.
*
* @return code 0 if there is no intersection; flags describing the
* intersection if there is
*/
public static int intersectEdgeTriangle(Point3d ipnt, HalfEdge edge, Face face, double maxlen, boolean edgeOnMesh0, boolean worldCoords) {
if (!nativeSupportLoaded) {
initialize();
}
Vertex3d vt = edge.getTail();
Vertex3d vh = edge.getHead();
Vertex3d v0 = face.he0.getTail();
Vertex3d v1 = face.he0.getHead();
Vertex3d v2 = face.he0.getNext().getHead();
Point3d pt, ph, p0, p1, p2;
if (worldCoords) {
pt = getWorldPoint(vt);
ph = getWorldPoint(vh);
p0 = getWorldPoint(v0);
p1 = getWorldPoint(v1);
p2 = getWorldPoint(v2);
} else {
pt = vt.pnt;
ph = vh.pnt;
p0 = v0.pnt;
p1 = v1.pnt;
p2 = v2.pnt;
}
int res = -1;
if (maxlen > 0) {
res = intersectSegmentTriangleFast(ipnt, pt, ph, p0, p1, p2, maxlen);
}
if (res == -1) {
// collect edge-face indices and call robust pred
int it = vt.getIndex();
int ih = vh.getIndex();
int i0 = v0.getIndex();
int i1 = v1.getIndex();
int i2 = v2.getIndex();
if (vt.getMesh() != v0.getMesh()) {
if (edgeOnMesh0) {
int numv0 = vt.getMesh().numVertices();
i0 += numv0;
i1 += numv0;
i2 += numv0;
} else {
int numv0 = v0.getMesh().numVertices();
it += numv0;
ih += numv0;
}
}
res = intersectSegmentTriangle(ipnt, it, pt, ih, ph, i0, p0, i1, p1, i2, p2);
}
return res;
}
use of maspack.matrix.Point3d in project artisynth_core by artisynth.
the class RobustPreds method orient3d.
/**
* Returns <code>true</code> if v3 is "below", or "inside" the plane formed
* by the counterclockwise triangle v0, v1, v2.
*
* <p>The computation first performs a quick numeric calculation to see if
* the intersection can be determined within regular double precision
* tolerances. If it cannot, then a more detailed calculation is performed
* using robust predicates.
*
* <p>If tie-breaking is needed, then this is done using "Simulation of
* Simplicity", as described in the class header, by assigning unique
* indices to each vertex based on their underlying mesh indices. If the
* meshes are different, then if <code>v3OnMesh0</code> is
* <code>true</code>, we increment the triangle vertex indices by the number
* of vertices on the v3 mesh, while if it is <code>false</code> we
* increment the v3 vertex index by the number of vertices on the triangle
* mesh.
*
* @param v0 first triangle vertex
* @param v1 second triangle vertex
* @param v2 third vertex
* @param v3 vertex to test
* @param v3OnMesh0 used to determine vertex indices for tie-breaking,
* as described above
* @param worldCoords if <code>true</code>, computes the intersection in
* world coordinates. Otherwise, mesh local coordinates are used.
* @return <code>true</code> if v3 is inside the triangle
*/
public static boolean orient3d(Vertex3d v0, Vertex3d v1, Vertex3d v2, Vertex3d v3, boolean v3OnMesh0, boolean worldCoords) {
Point3d p0, p1, p2, p3;
if (worldCoords) {
p0 = getWorldPoint(v0);
p1 = getWorldPoint(v1);
p2 = getWorldPoint(v2);
p3 = getWorldPoint(v3);
} else {
p0 = v0.pnt;
p1 = v1.pnt;
p2 = v2.pnt;
p3 = v3.pnt;
}
int i0 = v0.getIndex();
int i1 = v1.getIndex();
int i2 = v2.getIndex();
int i3 = v3.getIndex();
if (v0.getMesh() != v3.getMesh()) {
if (v3OnMesh0) {
int numv = v3.getMesh().numVertices();
i0 += numv;
i1 += numv;
i2 += numv;
} else {
i3 += v0.getMesh().numVertices();
}
}
if (!nativeSupportLoaded) {
initialize();
}
int result = jniOrient3d(i0, p0.x, p0.y, p0.z, i1, p1.x, p1.y, p1.z, i2, p2.x, p2.y, p2.z, i3, p3.x, p3.y, p3.z);
// System.out.println("Current CW: " + jniGetCW() );
if (result < 0)
throw new RuntimeException("RobustPreds failed with rc=" + result);
return result == 1;
}
Aggregations