public static void calculateAndSetNormalVectorsForCurve(IndexedLineSet ils) { double[][] polygon = ils.getVertexAttributes(Attribute.COORDINATES).toDoubleArrayArray(null); int n = polygon.length; double[][] normals = new double[n][4]; if (n <= 1) { throw new IllegalArgumentException("Can't tube a vertex list of length less than 2"); } double[][] polygon2 = new double[n + 2][]; for (int i = 0; i < n; ++i) { polygon2[i + 1] = polygon[i]; polygon2[0] = Rn.add(null, polygon[0], Rn.subtract(null, polygon[0], polygon[1])); polygon2[n + 1] = Rn.add(null, polygon[n - 1], Rn.subtract(null, polygon[n - 1], polygon[n - 2])); } FrameInfo[] frames = new TubeFactory().makeFrameField(polygon2, FrameFieldType.FRENET, Pn.EUCLIDEAN); for (int i = 0; i < n; ++i) { for (int j = 0; j < 4; ++j) { normals[i][j] = frames[i].frame[4 * j]; } normals[i][3] *= -1; Pn.normalize(normals[i], normals[i], Pn.EUCLIDEAN); } ils.setVertexAttributes( Attribute.NORMALS, StorageModel.DOUBLE_ARRAY.array(4).createReadOnly(normals)); }
static { int n = octagonalCrossSection.length; urTubeLength = n; urTubeVerts = new double[2 * n][3]; for (int i = 0; i < 2; ++i) { for (int j = 0; j < n; ++j) { int q = n - j - 1; System.arraycopy(octagonalCrossSection[j], 0, urTubeVerts[i * n + q], 0, 3); if (i == 0) urTubeVerts[i * n + q][2] = -0.5; else urTubeVerts[i * n + q][2] = 0.5; } } DataList verts = StorageModel.DOUBLE_ARRAY.array(urTubeVerts[0].length).createReadOnly(urTubeVerts); for (int k = 0; k < 3; ++k) { canonicalTranslation[k] = P3.makeTranslationMatrix(null, translation, metrics[k]); QuadMeshFactory qmf = new QuadMeshFactory(); // metrics[k], n, 2, true, false); qmf.setMetric(Pn.EUCLIDEAN); // metrics[k]); qmf.setULineCount(n); qmf.setVLineCount(2); qmf.setClosedInUDirection(true); qmf.setVertexCoordinates(verts); qmf.setGenerateEdgesFromFaces(true); qmf.setEdgeFromQuadMesh(true); qmf.setGenerateFaceNormals(true); qmf.setGenerateVertexNormals(true); qmf.setGenerateTextureCoordinates(true); qmf.update(); urTube[k] = qmf.getIndexedFaceSet(); urTube[k].setName("urTube" + k); if (k == 1) urTube[k].setGeometryAttributes( CommonAttributes.RMAN_PROXY_COMMAND, "Cylinder 1.0 -.5 .5 360"); } }