/* JWildfire - an image and animation processor written in Java Copyright (C) 1995-2017 Andreas Maschke This is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This software is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this software; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA, or see the FSF site: http://www.fsf.org. */ package org.jwildfire.create.tina.meshgen.marchingcubes; import java.util.ArrayList; import java.util.Collections; import java.util.List; import org.jwildfire.create.tina.variation.mesh.NeightboursList; public class Mesh { private List<Point3f> vertices; private List<Point3f> vertexNormals; private List<Face> faces; private List<Point2f> textureCoords; private boolean dirty; private Point3f[] bounds = null; public Mesh() { setVertices(null); setVertexNormals(null); setFaces(null); setTextureCoords(null); dirty = true; } public Mesh(List<Point3f> pVertices, List<Face> pFaces) { setVertices(pVertices); setVertexNormals(null); setFaces(pFaces); setTextureCoords(null); dirty = true; } public Mesh(List<Point3f> pVertices, List<Point3f> pVertexNormals, List<Face> pFaces) { setVertices(pVertices); setVertexNormals(pVertexNormals); setFaces(pFaces); setTextureCoords(null); dirty = true; } public List<Point3f> getVertices() { return vertices; } public void setVertices(List<Point3f> pVertices) { if (pVertices != null) { vertices = pVertices; } else { vertices = Collections.emptyList(); } dirty = true; } public List<Face> getFaces() { return faces; } public void setFaces(List<Face> pFaces) { if (pFaces != null) { faces = pFaces; } else { faces = Collections.emptyList(); } dirty = true; } private Point3f[] getBounds() { if (dirty) { Point3f min, max; bounds = new Point3f[2]; bounds[0] = min = new Point3f(); bounds[1] = max = new Point3f(); if (vertices.size() > 0) { Point3f first = vertices.get(0); bounds[0].x = bounds[1].x = first.x; bounds[0].y = bounds[1].y = first.y; bounds[0].z = bounds[1].z = first.z; for (int i = 1; i < vertices.size(); i++) { Point3f vertex = vertices.get(i); if (vertex.x < min.x) min.x = vertex.x; else if (vertex.x > max.x) max.x = vertex.x; if (vertex.y < min.y) min.y = vertex.y; else if (vertex.y > max.y) max.y = vertex.y; if (vertex.z < min.z) min.z = vertex.z; else if (vertex.z > max.z) max.z = vertex.z; } } dirty = false; } return bounds; } public Point3f getPMin() { return getBounds()[0]; } public Point3f getPMax() { return getBounds()[1]; } public List<Point3f> getVertexNormals() { return vertexNormals; } public void setVertexNormals(List<Point3f> pVertexNormals) { if (pVertexNormals != null) { vertexNormals = pVertexNormals; } else { vertexNormals = Collections.emptyList(); } } public List<Point2f> getTextureCoords() { return textureCoords; } public void setTextureCoords(List<Point2f> pTextureCoords) { if (pTextureCoords != null) { textureCoords = pTextureCoords; } else { textureCoords = Collections.emptyList(); } dirty = true; } public void laplaceSmooth(NeightboursList neighbours, double strength) { List<Point3f> displacements = new ArrayList<>(); // Calc displacements for (int i = 0; i < vertices.size(); i++) { Point3f d = new Point3f(); displacements.add(d); List<Integer> nList = neighbours.getNeighbours(i); if (nList.size() > 1) { double weight = 1.0 / (double) nList.size(); Point3f v = vertices.get(i); for (Integer n : nList) { Point3f vn = vertices.get(n); d.x += (vn.x - v.x) * weight; d.y += (vn.y - v.y) * weight; d.z += (vn.z - v.z) * weight; } } } // Apply displacements for (int i = 0; i < vertices.size(); i++) { Point3f v = vertices.get(i); Point3f d = displacements.get(i); v.x += d.x * strength; v.y += d.y * strength; v.z += d.z * strength; } } public void taubinSmooth(int passes, double lambda, double mu) { NeightboursList neightbours = new NeightboursList(this); for (int i = 0; i < passes; i++) { laplaceSmooth(neightbours, lambda); laplaceSmooth(neightbours, mu); } } }