/* * __ .__ .__ ._____. * _/ |_ _______ __|__| ____ | | |__\_ |__ ______ * \ __\/ _ \ \/ / |/ ___\| | | || __ \ / ___/ * | | ( <_> > <| \ \___| |_| || \_\ \\___ \ * |__| \____/__/\_ \__|\___ >____/__||___ /____ > * \/ \/ \/ \/ * * Copyright (c) 2006-2011 Karsten Schmidt * * This library 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. * * http://creativecommons.org/licenses/LGPL/2.1/ * * This library 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 library; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ package toxi.geom.mesh; import toxi.geom.Vec2D; import toxi.geom.Vec3D; /** * An extensible builder class for {@link TriangleMesh}es based on 3D surface * functions using spherical coordinates. In order to create a mesh, you'll need * to supply a {@link SurfaceFunction} implementation to the builder. */ public class SurfaceMeshBuilder { /** * */ protected SurfaceFunction function; /** * * @param function */ public SurfaceMeshBuilder(SurfaceFunction function) { this.function = function; } /** * * @param res * @return */ public Mesh3D createMesh(int res) { return createMesh(null, res, 1); } /** * * @param mesh * @param res * @param size * @return */ public Mesh3D createMesh(Mesh3D mesh, int res, float size) { return createMesh(mesh, res, size, true); } /** * * @param mesh * @param res * @param size * @param isClosed * @return */ public Mesh3D createMesh(Mesh3D mesh, int res, float size, boolean isClosed) { if (mesh == null) { mesh = new TriangleMesh(); } Vec3D a = new Vec3D(); Vec3D b = new Vec3D(); Vec3D pa = new Vec3D(), pb = new Vec3D(); Vec3D a0 = new Vec3D(), b0 = new Vec3D(); int phiRes = function.getPhiResolutionLimit(res); float phiRange = function.getPhiRange(); int thetaRes = function.getThetaResolutionLimit(res); float thetaRange = function.getThetaRange(); float pres = 1f / phiRes; float tres = 1f / thetaRes; float ires = 1f / res; Vec2D pauv = new Vec2D(); Vec2D pbuv = new Vec2D(); Vec2D auv = new Vec2D(); Vec2D buv = new Vec2D(); for (int p = 0; p < phiRes; p++) { float phi = p * phiRange * ires; float phiNext = (p + 1) * phiRange * ires; for (int t = 0; t <= thetaRes; t++) { float theta; theta = t * thetaRange * ires; a = function.computeVertexFor(a, phiNext, theta) .scaleSelf(size); auv.set(t * tres, 1 - (p + 1) * pres); b = function.computeVertexFor(b, phi, theta).scaleSelf(size); buv.set(t * tres, 1 - p * pres); if (b.equalsWithTolerance(a, 0.0001f)) { b.set(a); } if (t > 0) { if (t == thetaRes && isClosed) { a.set(a0); b.set(b0); } mesh.addFace(pa, pb, a, pauv.copy(), pbuv.copy(), auv.copy()); mesh.addFace(pb, b, a, pbuv.copy(), buv.copy(), auv.copy()); } else { a0.set(a); b0.set(b); } pa.set(a); pb.set(b); pauv.set(auv); pbuv.set(buv); } } return mesh; } /** * @return the function */ public SurfaceFunction getFunction() { return function; } /** * @param function * the function to set */ public void setFunction(SurfaceFunction function) { this.function = function; } }