/** * Calculates smoothing groups for data formatted in TriangleMesh style * @param flatFaces An array of faces, where each triangle face is represented by 6 (vertex and uv) indices * @param flatFaceNormals An array of face normals, where each triangle face is represented by 3 normal indices * @param normals The array of normals * @return An array of smooth groups, where the length of the array is the number of faces */ public static int[] calcSmoothGroups(TriangleMesh mesh, int[] flatFaces, int[] flatFaceNormals, float[] normals) { int faceElementSize = mesh.getFaceElementSize(); int[][] faces = new int[flatFaces.length/faceElementSize][faceElementSize]; for (int f = 0; f < faces.length; f++) { for (int e = 0; e < faceElementSize; e++) { faces[f][e] = flatFaces[f * faceElementSize + e]; } } int pointElementSize = mesh.getPointElementSize(); int[][] faceNormals = new int[flatFaceNormals.length/pointElementSize][pointElementSize]; for (int f = 0; f < faceNormals.length; f++) { for (int e = 0; e < pointElementSize; e++) { faceNormals[f][e] = flatFaceNormals[f * pointElementSize + e]; } } SmoothingGroups smoothGroups = new SmoothingGroups(faces, faceNormals, normals); return smoothGroups.calcSmoothGroups(); }
@Override public boolean checkConstruct() { try { triMesh = new TriangleMesh(); triMesh.getFaces().addAll(faces); triMesh.getPoints().addAll(points); triMesh.getTexCoords().addAll(texCoords); if (!checkPoints(triMesh.getPoints()) || !checkFaces(triMesh.getFaces()) || !checkTexCoords(triMesh.getTexCoords())) { return false; } } catch (Throwable t) { t.printStackTrace(); return false; } meshView.setMesh(triMesh); return true; }
protected TriangleMesh createMesh(MeshHelper mh) { float[] points0=mh.getPoints(); float[] f = mh.getF(); listVertices.clear(); listVertices.addAll(IntStream.range(0, points0.length/3) .mapToObj(i -> new Point3D(points0[3*i], points0[3*i+1], points0[3*i+2],f[i])) .collect(Collectors.toList())); textureCoords=mh.getTexCoords(); int[] faces0 = mh.getFaces(); listFaces.clear(); listFaces.addAll(IntStream.range(0, faces0.length/6) .mapToObj(i -> new Face3(faces0[6*i+0], faces0[6*i+2], faces0[6*i+4])) .collect(Collectors.toList())); listTextures.clear(); // listTextures.addAll(listFaces); listTextures.addAll(IntStream.range(0, faces0.length/6) .mapToObj(i -> new Face3(faces0[6*i+1], faces0[6*i+3], faces0[6*i+5])) .collect(Collectors.toList())); smoothingGroups=mh.getFaceSmoothingGroups(); return createMesh(); }
protected TriangleMesh createMesh(MeshHelper mh) { float[] points0=mh.getPoints(); float[] f = mh.getF(); listVertices.clear(); listVertices.addAll(IntStreams.range(0, points0.length/3) .mapToObj(i -> new Point3D(points0[3*i], points0[3*i+1], points0[3*i+2],f[i])) .collect(Collectors.toList())); textureCoords=mh.getTexCoords(); int[] faces0 = mh.getFaces(); listFaces.clear(); listFaces.addAll(IntStreams.range(0, faces0.length/6) .mapToObj(i -> new Face3(faces0[6*i+0], faces0[6*i+2], faces0[6*i+4])) .collect(Collectors.toList())); listTextures.clear(); // listTextures.addAll(listFaces); listTextures.addAll(IntStreams.range(0, faces0.length/6) .mapToObj(i -> new Face3(faces0[6*i+1], faces0[6*i+3], faces0[6*i+5])) .collect(Collectors.toList())); smoothingGroups=mh.getFaceSmoothingGroups(); return createMesh(); }
/** * Load a 3D file, always loaded as TriangleMesh. * * @param fileUrl the url of the 3D file to load * @return the loaded Node which could be a MeshView or a Group * @throws IOException if there is a problem loading the file */ public static Group load(final String fileUrl) throws IOException { final int dot = fileUrl.lastIndexOf('.'); if (dot <= 0) { throw new IOException("Unknown 3D file format, url missing extension [" + fileUrl + "]"); } final String extension = fileUrl.substring(dot + 1, fileUrl.length()).toLowerCase(); switch (extension) { case "3ds": ModelImporter tdsImporter = new TdsModelImporter(); tdsImporter.read(fileUrl); final Node[] tdsMesh = (Node[]) tdsImporter.getImport(); tdsImporter.close(); return new Group(tdsMesh); case "stl": StlMeshImporter stlImporter = new StlMeshImporter(); stlImporter.read(fileUrl); // STL includes only geometry data TriangleMesh cylinderHeadMesh = stlImporter.getImport(); stlImporter.close(); // Create Shape3D MeshView cylinderHeadMeshView = new MeshView(); cylinderHeadMeshView.setMaterial(new PhongMaterial(Color.GRAY)); cylinderHeadMeshView.setMesh(cylinderHeadMesh); stlImporter.close(); return new Group(cylinderHeadMeshView); default: throw new IOException("Unsupported 3D file format [" + extension + "]"); } }
private TriangleMesh buildTriMesh() { points = buildPoints(); texCoords = buildTexCoords(); faces = buildFaces(); smoothingGroups = null; TriangleMesh tmesh = new TriangleMesh(); tmesh.getFaces().addAll(faces); tmesh.getPoints().addAll(points); tmesh.getTexCoords().addAll(texCoords); return tmesh; }
private TriangleMesh buildTriangleMesh(int subDivX, int subDivY, float scale, int smooth) { TriangleMesh triangleMesh = new TriangleMesh(); triangleMesh.getPoints().addAll(getPoints(subDivX, subDivY, scale)); triangleMesh.getTexCoords().addAll(getTexCoords(subDivX, subDivY)); triangleMesh.getFaces().addAll(getFaces(subDivX, subDivY)); return triangleMesh; }
private static Point3D getMeshNormal(MeshView mesh){ TriangleMesh tm = (TriangleMesh) mesh.getMesh(); float[] fPoints = new float[tm.getPoints().size()]; tm.getPoints().toArray(fPoints); Point3D BA = new Point3D(fPoints[3] - fPoints[0], fPoints[4] - fPoints[1], fPoints[5] - fPoints[2]); Point3D CA = new Point3D(fPoints[6] - fPoints[0], fPoints[7] - fPoints[1], fPoints[8] - fPoints[2]); Point3D normal = BA.crossProduct(CA); Affine a = new Affine(mesh.getTransforms().get(0)); return a.transform(normal.normalize()); }
@Override public TriangleMesh getMesh(String type) { // Save the retrieved mesh last = super.getMesh(type); return last; }
@Override public TriangleMesh getMesh(EList<Triangle> triangles) { // Save the retrieved mesh last = super.getMesh(triangles); return last; }
/** * * @param width * @param height * @param depth */ public Plane(double width, double height, double depth, int segments) { TriangleMesh mesh = new TriangleMesh(); mesh.setVertexFormat(VertexFormat.POINT_TEXCOORD); generatePlane(mesh, width, height, depth, segments); }
private TriangleMesh createTrapezoid (double smallSize , double bigSize , double high ,double depth){ TriangleMesh m = new TriangleMesh(); float s = ((float)smallSize) ; float b = ((float)bigSize); float h = ((float)high); float d = ((float)depth); //create Points m.getPoints().addAll( -s/2 , -h/2 , d/2, // A = 0 s/2 , -h/2 , d/2, // B = 1 -b/2 , h/2 , d/2, // C = 2 b/2 , h/2 , d/2, // D = 3 -s/2 , -h/2 , -d/2, // E = 4 s/2 , -h/2 , -d/2, // F = 5 -b/2 , h/2 , -d/2, // G = 6 b/2 , h/2 , -d/2 // H = 7 ); m.getTexCoords().addAll(0,0); m.getFaces().addAll( 0 , 0 , 1 , 0 , 3 , 0 , // A-B-D 0 , 0 , 3 , 0 , 2 , 0 , // A-D-C 0 , 0 , 2 , 0 , 6 , 0 , // A-C-G 0 , 0 , 6 , 0 , 4 , 0 , // A-G-E 0 , 0 , 4 , 0 , 1 , 0 , // A-E-B 1 , 0 , 4 , 0 , 5 , 0 , // B-E-F 1 , 0 , 5 , 0 , 7 , 0 , // B-F-H 1 , 0 , 7 , 0 , 3 , 0 , // B-H-D 3 , 0 , 7 , 0 , 6 , 0 , // D-H-G 3 , 0 , 6 , 0 , 2 , 0 , // D-G-C 6 , 0 , 7 , 0 , 5 , 0 , // G-H-F 6 , 0 , 5 , 0 , 4 , 0 // G-F-E ); return m ; }
public MeshHelper(TriangleMesh tm) { this.points = tm.getPoints().toArray(points); this.texCoords = tm.getTexCoords().toArray(texCoords); this.faces = tm.getFaces().toArray(faces); this.faceSmoothingGroups = tm.getFaceSmoothingGroups().toArray(faceSmoothingGroups); this.f=new float[points.length/3]; }
private TriangleMesh createCone(int divisions, float radius, float height) { TriangleMesh mesh = new TriangleMesh(); //Start with the top of the cone, later we will build our faces from these mesh.getPoints().addAll(0,0,0); //Point 0: Top of the Cone //Generate the segments of the bottom circle (Cone Base) double segment_angle = 2.0 * Math.PI / divisions; float x, z; double angle; double halfCount = (Math.PI / 2 - Math.PI / (divisions / 2)); // Reverse loop for speed!! der for(int i=divisions+1;--i >= 0; ) { angle = segment_angle * i; x = (float)(radius * Math.cos(angle - halfCount)); z = (float)(radius * Math.sin(angle - halfCount)); mesh.getPoints().addAll(x,height,z); } mesh.getPoints().addAll(0,height,0); //Point N: Center of the Cone Base //@TODO Birdasaur for now we'll just make an empty texCoordinate group //@DUB HELP ME DUBi Wan Kanobi, you are my only hope! //I'm not good at determining Texture Coordinates mesh.getTexCoords().addAll(0,0); //Add the faces "winding" the points generally counter clock wise //Must loop through each face, not including first and last points for(int i=1;i<=divisions;i++) { mesh.getFaces().addAll( //use dummy texCoords, @TODO Upgrade face code to be real 0,0,i+1,0,i,0, // Vertical Faces "wind" counter clockwise divisions+2,0,i,0,i+1,0 // Base Faces "wind" clockwise ); } return mesh; }
private TriangleMesh createPyramid(double hypotenuse , double height){ TriangleMesh mesh = new TriangleMesh(); float hy = (float)hypotenuse; float he = (float)height; mesh.getPoints().addAll( 0 , 0 , 0, //point O 0 , he , -hy/2, //point A -hy/2, he , 0, //point B hy/2, he , 0, //point C 0 , he , hy/2 //point D ); mesh.getTexCoords().addAll(0,0); mesh.getFaces().addAll( 0 , 0 , 2 , 0 , 1 , 0 , // O-B-A 0 , 0 , 1 , 0 , 3 , 0 , // O-A-C 0 , 0 , 3 , 0 , 4 , 0 , // O-C-D 0 , 0 , 4 , 0 , 2 , 0 , // O-D-B 4 , 0 , 1 , 0 , 2 , 0 , // D-A-B 4 , 0 , 3 , 0 , 1 , 0 // D-C-A ); return mesh; }
private TriangleMesh createOctahedron(double hypotenuse , double height){ TriangleMesh mesh = new TriangleMesh(); float hy = (float)hypotenuse; float he = (float)height; mesh.getPoints().addAll( 0 , 0 , 0, //point O 0 , he , -hy/2, //point A -hy/2, he , 0, //point B hy/2, he , 0, //point C 0 , he , hy/2, //point D 0 , 2*he , 0 //point E ); mesh.getTexCoords().addAll(0,0); mesh.getFaces().addAll( 0 , 0 , 2 , 0 , 1 , 0 , // O-B-A 0 , 0 , 1 , 0 , 3 , 0 , // O-A-C 0 , 0 , 3 , 0 , 4 , 0 , // O-C-D 0 , 0 , 4 , 0 , 2 , 0 , // O-D-B 4 , 0 , 1 , 0 , 2 , 0 , // D-A-B 4 , 0 , 3 , 0 , 1 , 0 , // D-C-A 5 , 0 , 2 , 0 , 1 , 0 , // E-B-A 5 , 0 , 1 , 0 , 3 , 0 , // E-A-C 5 , 0 , 3 , 0 , 4 , 0 , // E-C-D 5 , 0 , 4 , 0 , 2 , 0 // E-D-B ); return mesh; }
public void validate(Mesh mesh) { if (!(mesh instanceof TriangleMesh)) { throw new AssertionError("Mesh is not TriangleMesh: " + mesh.getClass() + ", mesh = " + mesh); } TriangleMesh tMesh = (TriangleMesh) mesh; int numPoints = tMesh.getPoints().size() / tMesh.getPointElementSize(); int numTexCoords = tMesh.getTexCoords().size() / tMesh.getTexCoordElementSize(); int numFaces = tMesh.getFaces().size() / tMesh.getFaceElementSize(); if (numPoints == 0 || numPoints * tMesh.getPointElementSize() != tMesh.getPoints().size()) { throw new AssertionError("Points array size is not correct: " + tMesh.getPoints().size()); } if (numTexCoords == 0 || numTexCoords * tMesh.getTexCoordElementSize() != tMesh.getTexCoords().size()) { throw new AssertionError("TexCoords array size is not correct: " + tMesh.getPoints().size()); } if (numFaces == 0 || numFaces * tMesh.getFaceElementSize() != tMesh.getFaces().size()) { throw new AssertionError("Faces array size is not correct: " + tMesh.getPoints().size()); } if (numFaces != tMesh.getFaceSmoothingGroups().size() && tMesh.getFaceSmoothingGroups().size() > 0) { throw new AssertionError("FaceSmoothingGroups array size is not correct: " + tMesh.getPoints().size() + ", numFaces = " + numFaces); } ObservableIntegerArray faces = tMesh.getFaces(); for (int i = 0; i < faces.size(); i += 2) { int pIndex = faces.get(i); if (pIndex < 0 || pIndex > numPoints) { throw new AssertionError("Incorrect point index: " + pIndex + ", numPoints = " + numPoints); } int tcIndex = faces.get(i + 1); if (tcIndex < 0 || tcIndex > numTexCoords) { throw new AssertionError("Incorrect texCoord index: " + tcIndex + ", numTexCoords = " + numTexCoords); } } // System.out.println("Validation successfull of " + mesh); }
private TriangleMesh createCSGMesh(){ List<Vertex> vertices = new ArrayList<>(); List<List<Integer>> indices = new ArrayList<>(); listVertices.clear(); Iterables.forEach(primitive.getPolygons(), p -> { List<Integer> polyIndices = new ArrayList<>(); Iterables.forEach(p.vertices, v -> { if (!vertices.contains(v)) { vertices.add(v); listVertices.add(new Point3D((float)v.pos.x, (float)v.pos.y, (float)v.pos.z)); polyIndices.add(vertices.size()); } else { polyIndices.add(vertices.indexOf(v) + 1); } }); indices.add(polyIndices); }); textureCoords=new float[]{0f,0f}; listTextures.clear(); listFaces.clear(); Iterables.forEach(indices, pVerts-> { int index1 = pVerts.get(0); for (int i = 0; i < pVerts.size() - 2; i++) { int index2 = pVerts.get(i + 1); int index3 = pVerts.get(i + 2); listTextures.add(new Face3(0, 0, 0)); listFaces.add(new Face3(index1-1, index2-1, index3-1)); } }); int[] faceSmoothingGroups = new int[listFaces.size()]; smoothingGroups=faceSmoothingGroups; return createMesh(); }
public static CSG mesh2CSG(Mesh mesh) throws IOException { List<Polygon> polygons = new ArrayList<>(); List<Vector3d> vertices = new ArrayList<>(); if(mesh instanceof TriangleMesh){ // Get faces ObservableFaceArray faces = ((TriangleMesh)mesh).getFaces(); int[] f=new int[faces.size()]; faces.toArray(f); // Get vertices ObservableFloatArray points = ((TriangleMesh)mesh).getPoints(); float[] p = new float[points.size()]; points.toArray(p); // convert faces to polygons for(int i=0; i<faces.size()/6; i++){ int i0=f[6*i], i1=f[6*i+2], i2=f[6*i+4]; vertices.add(new Vector3d(p[3*i0], p[3*i0+1], p[3*i0+2])); vertices.add(new Vector3d(p[3*i1], p[3*i1+1], p[3*i1+2])); vertices.add(new Vector3d(p[3*i2], p[3*i2+1], p[3*i2+2])); polygons.add(Polygon.fromPoints(vertices)); vertices = new ArrayList<>(); } } return CSG.fromPolygons(new PropertyStorage(),polygons); }
private static Point3D getMeshNormal(MeshView mesh){ TriangleMesh tm=(TriangleMesh)mesh.getMesh(); float[] fPoints=new float[tm.getPoints().size()]; tm.getPoints().toArray(fPoints); Point3D BA=new Point3D(fPoints[3]-fPoints[0],fPoints[4]-fPoints[1],fPoints[5]-fPoints[2]); Point3D CA=new Point3D(fPoints[6]-fPoints[0],fPoints[7]-fPoints[1],fPoints[8]-fPoints[2]); Point3D normal=BA.crossProduct(CA); Affine a=new Affine(mesh.getTransforms().get(0)); return a.transform(normal.normalize()); }
/** * Adds the specified mesh to a group and returns it. In addition this * method allows the definition of a mouse event handler and colors. * * @param prev previous container (will be reused if possible) * @param mesh mesh * @param diffuse diffuse color * @param specular specular color * @param type eventhandler type (may be <code>null</code>) * @param evtHandler eventhandler (may be <code>null</code>) * @return container that contains the visualization of the specified mesh */ public static GeometryContainer meshToParent(GeometryContainer prev, TriangleMesh mesh, Color diffuse, Color specular, EventType<MouseEvent> type, EventHandler<MouseEvent> evtHandler) { // convert mesh to node (via meshview) final GeometryContainer meshNode = meshToNode(prev, mesh, diffuse, specular); // add the specified eventhandler (if any) if (type != null && evtHandler != null) { meshNode.getGroup().addEventHandler(type, evtHandler); } return meshNode; }
public static MeshView createMesh() { float[] points = { -0.866f, 0f, 0.5f, 0f, 0f, 1f, 0.866f, 0f, 0.5f, 0.866f, 0f, -0.5f, 0f, 0f, -1f, -0.866f, 0f, -0.5f, 0f, 0f, 0f }; float[] texCoords = { 0f, 0.25f, 0.5f, 0f, 1f, 0.25f, 1f, 0.75f, 0.5f, 1f, 0f, 0.75f, 0.5f, 0.5f }; int[] faces = { 6, 6, 1, 1, 0, 0, 6, 6, 2, 2, 1, 1, 6, 6, 3, 3, 2, 2, 6, 6, 4, 4, 3, 3, 6, 6, 5, 5, 4, 4, 6, 6, 0, 0, 5, 5, }; TriangleMesh mesh = new TriangleMesh(); mesh.getPoints().setAll(points); mesh.getTexCoords().setAll(texCoords); mesh.getFaces().setAll(faces); return new MeshView(mesh); }
/** * Constructs a rectangle Mesh which is an * extended class of meshView : a 3d object * @since v0.2 * * @param width defines the width of the mesh * @param height defines the height of the mesh * @param depth defines the depth of the mesh * @param texturePath defines the path of the mesh texture * @param textureFaceWidth defines the number of width pixels of the card front on the texture * @param textureFaceHeight defines the number of height pixels of the card front on the texture */ RectangleMesh(float width, float height, float depth, String texturePath, float textureFaceWidth, float textureFaceHeight) { super(); float textureWidth; float textureHeight; javafx.scene.image.Image image; image = new javafx.scene.image.Image(texturePath); textureHeight = (float)image.getHeight(); textureWidth = (float)image.getWidth(); float textureDepth = (textureHeight - textureFaceHeight)/2; TriangleMesh mesh = new TriangleMesh(); mesh.getPoints().addAll( 0, 0, 0, //P0 width, 0, 0, //P1 0, height, 0, //P2 width, height, 0, //P3 0, 0, depth, //P4 width, 0, depth, //P5 0, height, depth, //P6 width, height, depth //P7 ); mesh.getTexCoords().addAll( (textureDepth/textureWidth), 0, //T0 ((textureDepth+textureFaceWidth)/textureWidth), 0, //T1 0, (textureDepth/textureWidth), //T2 (textureDepth/textureWidth), (textureDepth/textureHeight), //T3 ((textureDepth+textureFaceWidth)/textureWidth), (textureDepth/textureHeight), //T4 ((2*textureDepth+textureFaceWidth)/textureWidth), (textureDepth/textureHeight), //T5 1, (textureDepth/textureHeight), //T6 0, ((textureDepth+textureFaceHeight)/textureHeight), //T7 (textureDepth/textureWidth), ((textureDepth+textureFaceHeight)/textureHeight), //T8 ((textureDepth+textureFaceWidth)/textureWidth), ((textureDepth+textureFaceHeight)/textureHeight), //T9 ((2*textureDepth+textureFaceWidth)/textureWidth), ((textureDepth+textureFaceHeight)/textureHeight), //T10 1, ((textureDepth+textureFaceHeight)/textureHeight), //T11 (textureDepth/textureWidth), 1, //T12 ((textureDepth+textureFaceWidth)/textureWidth), 1 //T13 ); mesh.getFaces().addAll( 5,1,4,0,0,3 //P5,T1 ,P4,T0 ,P0,T3 ,5,1,0,3,1,4 //P5,T1 ,P0,T3 ,P1,T4 ,0,3,4,2,6,7 //P0,T3 ,P4,T2 ,P6,T7 ,0,3,6,7,2,8 //P0,T3 ,P6,T7 ,P2,T8 ,1,4,0,3,2,8 //P1,T4 ,P0,T3 ,P2,T8 ,1,4,2,8,3,9 //P1,T4 ,P2,T8 ,P3,T9 ,5,5,1,4,3,9 //P5,T5 ,P1,T4 ,P3,T9 ,5,5,3,9,7,10 //P5,T5 ,P3,T9 ,P7,T10 ,4,6,5,5,7,10 //P4,T6 ,P5,T5 ,P7,T10 ,4,6,7,10,6,11 //P4,T6 ,P7,T10 ,P6,T11 ,3,9,2,8,6,12 //P3,T9 ,P2,T8 ,P6,T12 ,3,9,6,12,7,13 //P3,T9 ,P6,T12 ,P7,T13 ); this.setMesh(mesh); PhongMaterial material = new PhongMaterial(); material.setDiffuseMap(image); this.setMaterial(material); transformations = new Transformations(this); }
public TriangleMesh getTriangleMesh() { if (mesh == null) { rebuildMesh(); } return mesh; }
public TriangleMesh getMesh() { return meshes.values().iterator().next(); }
public TriangleMesh getMesh(String key) { return meshes.get(key); }
/** * The default constructor. */ private TestCache() { super(); // Create a triangle mesh mesh1 = new TriangleMesh(); mesh1.getPoints().addAll(0); typeCache.put("test", mesh1); // Create a triangle Triangle triangle = GeometryFactory.eINSTANCE.createTriangle(); triangle.getVertices() .add(GeometryFactory.eINSTANCE.createVertex()); triangle.getVertices().get(0).setX(2); triangle.getVertices().add(GeometryFactory.eINSTANCE.createVertex()); triangle.getVertices().add(GeometryFactory.eINSTANCE.createVertex()); // Create a second triangle Triangle triangle2 = GeometryFactory.eINSTANCE.createTriangle(); triangle2.getVertices() .add(GeometryFactory.eINSTANCE.createVertex()); triangle2.getVertices().get(0).setY(2); triangle2.getVertices().add(GeometryFactory.eINSTANCE.createVertex()); triangle2.getVertices().add(GeometryFactory.eINSTANCE.createVertex()); // Add the first triangle mesh and the first triangle list to the // caches with shared ID number 0. set1 = new HashSet<Triangle>(); set1.add(triangle); set1.add(triangle2); sourceTriangleCache.put(0, set1); triangleCache.put(0, mesh1); // Create a second triangle mesh mesh2 = new TriangleMesh(); mesh2.getPoints().addAll(1); // Create a third triangle Triangle triangle3 = GeometryFactory.eINSTANCE.createTriangle(); triangle3.getVertices() .add(GeometryFactory.eINSTANCE.createVertex()); triangle3.getVertices().get(0).setX(2); triangle3.getVertices().get(0).setZ(2); triangle3.getVertices().add(GeometryFactory.eINSTANCE.createVertex()); triangle3.getVertices().add(GeometryFactory.eINSTANCE.createVertex()); // Create a fourth triangle Triangle triangle4 = GeometryFactory.eINSTANCE.createTriangle(); triangle4.getVertices() .add(GeometryFactory.eINSTANCE.createVertex()); triangle4.getVertices().get(0).setY(2); triangle4.getVertices().get(0).setZ(2); triangle4.getVertices().add(GeometryFactory.eINSTANCE.createVertex()); triangle4.getVertices().add(GeometryFactory.eINSTANCE.createVertex()); // Create a second set set2 = new HashSet<Triangle>(); set2.add(triangle3); set2.add(triangle4); // Add the second triangle mesh and the second triangle list to the // caches with shared ID number 1. sourceTriangleCache.put(1, set2); triangleCache.put(1, mesh2); }
/** * The default constructor. * * @param source * The object to be rendered. * @param meshCache * The cache of TriangleMeshes from which this object will draw * the mesh to render. */ public FXRenderObject(INode source, MeshCache<TriangleMesh> meshCache) { super(); // Save the data members this.source = source; this.meshCache = meshCache; // Create a new, empty group for the render render = new Group(); // Try to get a mesh based on the source's type. TriangleMesh mesh = meshCache.getMesh(source.getType()); // If there was no mesh for the source's type, instead specify one by a // mesh of triangles if (mesh == null) { mesh = meshCache.getMesh(source.getTriangles()); } // If a mesh was returned, create a view from it and add it to the // render group. Otherwise, we will use an empty group to render the // object. if (mesh != null) { render.getChildren().add(new MeshView(mesh)); } // Register as a listener to the source object source.eAdapters().add(new AdapterImpl() { @Override public void notifyChanged(Notification notification) { handleUpdate(notification); } }); // Get the center of the data object from the source Vertex center = source.getCenter(); // Move the render to the correct location if (center != null) { render.setTranslateX(center.getX()); render.setTranslateY(center.getY()); render.setTranslateZ(center.getZ()); } }
/** * Handle a notification from the source object. * * @param notification * The message of from the source object, specifying what has * changed. */ protected void handleUpdate(Notification notification) { // If a changeDecoratorProperty() function was called, then update own // properties according to the special message format of the old value // being the property name and the new value being the property value if (notification.getFeatureID( GeometryPackage.class) == GeometryPackage.INODE___CHANGE_DECORATOR_PROPERTY__STRING_OBJECT || notification.getEventType() == Notification.NO_FEATURE_ID) { String propertyName = notification.getOldStringValue(); Object propertyValue = notification.getNewValue(); // If the property already had this value, ignore it if (propertyValue == null || !propertyValue.equals(properties.get(propertyName))) { properties.put(notification.getOldStringValue(), notification.getNewValue()); } else { // If nothing changed, there are no need for further updates return; } } // Cast the cache as a cache of TriangleMeshes MeshCacheImpl<TriangleMesh> castCache = (MeshCacheImpl<TriangleMesh>) meshCache; // For the base implementation, we simply clear the render group of all // nodes and add the new mesh to it. render = new Group(); // Try to get the mesh based on type TriangleMesh mesh = castCache.getMesh(source.getType()); // If no mesh was found, specify one with triangles if (mesh == null) { mesh = castCache.getMesh(source.getTriangles()); } // If a mesh was found, create a view for it and add it to the render // group. if (mesh != null) { render.getChildren().add(new MeshView(mesh)); } // Get the center of the data object from the source Vertex center = source.getCenter(); // Move the render to the correct location if (center != null) { render.setTranslateX(center.getX()); render.setTranslateY(center.getY()); render.setTranslateZ(center.getZ()); } // Pass the update on to own observer eNotify(notification); }
public void setHeightData(float[][] arrayY, int spacing, Color color, boolean ambient, boolean fill) { material = new PhongMaterial(); material.setSpecularColor(color); material.setDiffuseColor(color); mesh = new TriangleMesh(); // Fill Points for (int x = 0; x < arrayY.length; x++) { for (int z = 0; z < arrayY[0].length; z++) { mesh.getPoints().addAll(x * spacing, arrayY[x][z], z * spacing); } } //for now we'll just make an empty texCoordinate group mesh.getTexCoords().addAll(0, 0); int total = arrayY.length * arrayY.length; int nextRow = arrayY.length; //Add the faces "winding" the points generally counter clock wise for (int i = 0; i < total - nextRow -1; i++) { //Top upper left triangle mesh.getFaces().addAll(i,0,i+nextRow,0,i+1,0); //Top lower right triangle mesh.getFaces().addAll(i+nextRow,0,i+nextRow + 1,0,i+1,0); //Bottom } //Create a viewable MeshView to be added to the scene //To add a TriangleMesh to a 3D scene you need a MeshView container object meshView = new MeshView(mesh); //The MeshView allows you to control how the TriangleMesh is rendered if(fill) { meshView.setDrawMode(DrawMode.FILL); } else { meshView.setDrawMode(DrawMode.LINE); //show lines only by default } meshView.setCullFace(CullFace.BACK); //Removing culling to show back lines getChildren().add(meshView); meshView.setMaterial(material); if (ambient) { selfLight.getScope().add(meshView); if(!getChildren().contains(selfLight)) getChildren().add(selfLight); } else if(getChildren().contains(selfLight)) getChildren().remove(selfLight); setDepthTest(DepthTest.ENABLE); }
public PolyLine3D(List<Point3D> points, int width, Color color) { this.points = points; this.width = width; this.color = color; setDepthTest(DepthTest.ENABLE); mesh = new TriangleMesh(); //add each point. For each point add another point shifted on Z axis by width //This extra point allows us to build triangles later for(Point3D point: points) { mesh.getPoints().addAll(point.x,point.y,point.z); mesh.getPoints().addAll(point.x,point.y,point.z+width); } //add dummy Texture Coordinate mesh.getTexCoords().addAll(0,0); //Now generate trianglestrips for each line segment for(int i=2;i<points.size()*2;i+=2) { //add each segment //Vertices wound counter-clockwise which is the default front face of any Triange //These triangles live on the frontside of the line facing the camera mesh.getFaces().addAll(i,0,i-2,0,i+1,0); //add primary face mesh.getFaces().addAll(i+1,0,i-2,0,i-1,0); //add secondary Width face //Add the same faces but wind them clockwise so that the color looks correct when camera is rotated //These triangles live on the backside of the line facing away from initial the camera mesh.getFaces().addAll(i+1,0,i-2,0,i,0); //add primary face mesh.getFaces().addAll(i-1,0,i-2,0,i+1,0); //add secondary Width face } //Need to add the mesh to a MeshView before adding to our 3D scene meshView = new MeshView(mesh); meshView.setDrawMode(DrawMode.FILL); //Fill so that the line shows width material = new PhongMaterial(color); material.setDiffuseColor(color); material.setSpecularColor(color); meshView.setMaterial(material); //Make sure you Cull the Back so that no black shows through meshView.setCullFace(CullFace.BACK); //Add some ambient light so folks can see it AmbientLight light = new AmbientLight(Color.WHITE); light.getScope().add(meshView); getChildren().add(light); getChildren().add(meshView); }
private TriangleMesh createCube(float size) { TriangleMesh m = new TriangleMesh(); float hw = size / 2, hh = hw, hd = hh; //create points m.getPoints().addAll( hw, hh, hd, hw, hh, -hd, hw, -hh, hd, hw, -hh, -hd, -hw, hh, hd, -hw, hh, -hd, -hw, -hh, hd, -hw, -hh, -hd ); float x0 = 0.0f, x1 = 1.0f / 4.0f, x2 = 2.0f / 4.0f, x3 = 3.0f / 4.0f, x4 = 1.0f; float y0 = 0.0f, y1 = 1.0f /3.0f, y2 = 2.0f / 3.0f, y3 = 1.0f; m.getTexCoords().addAll( (x1 + getImagePadding()), (y0 + getImagePadding()), //0,1 (x2 - getImagePadding()), (y0 + getImagePadding()), //2,3 (x0) , (y1 + getImagePadding()), //4,5 (x1 + getImagePadding()), (y1 + getImagePadding()), //6,7 (x2 - getImagePadding()), (y1 + getImagePadding()), //8,9 (x3), (y1 + getImagePadding()), //10,11 (x4), (y1 + getImagePadding()), //12,13 (x0), (y2 - getImagePadding()), //14,15 (x1 + getImagePadding()), (y2 - getImagePadding()), //16,17 (x2 - getImagePadding()), (y2 - getImagePadding()), //18,19 (x3), (y2 - getImagePadding()), //20,21 (x4), (y2 - getImagePadding()), //22,23 (x1 + getImagePadding()), (y3 - getImagePadding()), //24,25 (x2), (y3 - getImagePadding()) //26,27 ); m.getFaces().addAll( 0, 10, 2, 5, 1, 9, 2, 5, 3, 4, 1, 9, 4, 7, 5, 8, 6, 2, 6, 2, 5, 8, 7, 3, 0, 13, 1, 9, 4, 12, 4, 12, 1, 9, 5, 8, 2, 1, 6, 0, 3, 4, 3, 4, 6, 0, 7, 3, 0, 10, 4, 11, 2, 5, 2, 5, 4, 11, 6, 6, 1, 9, 3, 4, 5, 8, 5, 8, 3, 4, 7, 3 ); return m; }
protected TriangleMesh createMesh(){ TriangleMesh triangleMesh = new TriangleMesh(); triangleMesh.getPoints().setAll(helper.updateVertices(listVertices)); switch(textureType.get()){ case NONE: triangleMesh.getTexCoords().setAll(textureCoords); triangleMesh.getFaces().setAll(helper.updateFacesWithTextures(listFaces,listTextures)); break; case PATTERN: if(areaMesh.getHeight()>0 && areaMesh.getWidth()>0){ triangleMesh.getTexCoords().setAll( helper.updateTexCoordsWithPattern((int)rectMesh.getWidth(), (int)rectMesh.getHeight(),patternScale.get(), areaMesh.getHeight()/areaMesh.getWidth())); } else { triangleMesh.getTexCoords().setAll( helper.updateTexCoordsWithPattern((int)rectMesh.getWidth(), (int)rectMesh.getHeight(),patternScale.get())); } triangleMesh.getFaces().setAll(helper.updateFacesWithTextures(listFaces,listTextures)); break; case IMAGE: triangleMesh.getTexCoords().setAll(textureCoords); if(listTextures.size()>0){ triangleMesh.getFaces().setAll(helper.updateFacesWithTextures(listFaces,listTextures)); } else { triangleMesh.getFaces().setAll(helper.updateFacesWithVertices(listFaces)); } break; case COLORED_VERTICES_1D: triangleMesh.getTexCoords().setAll(helper.getTexturePaletteArray()); triangleMesh.getFaces().setAll(helper.updateFacesWithFunctionMap(listVertices, listFaces)); break; case COLORED_VERTICES_3D: triangleMesh.getTexCoords().setAll(helper.getTexturePaletteArray()); triangleMesh.getFaces().setAll(helper.updateFacesWithDensityMap(listVertices, listFaces)); break; case COLORED_FACES: triangleMesh.getTexCoords().setAll(helper.getTexturePaletteArray()); triangleMesh.getFaces().setAll(helper.updateFacesWithFaces(listFaces)); break; } int[] faceSmoothingGroups = new int[listFaces.size()]; // 0 == hard edges Arrays.fill(faceSmoothingGroups, 1); // 1: soft edges, all the faces in same surface if(smoothingGroups!=null){ // for(int i=0; i<smoothingGroups.length; i++){ // System.out.println("i: "+smoothingGroups[i]); // } triangleMesh.getFaceSmoothingGroups().addAll(smoothingGroups); } else { triangleMesh.getFaceSmoothingGroups().addAll(faceSmoothingGroups); } System.out.println("nodes: "+listVertices.size()+", faces: "+listFaces.size()); // System.out.println("area: "+helper.getMeshArea(listVertices, listFaces)); return triangleMesh; }