X-Git-Url: https://gerrit.simantics.org/r/gitweb?a=blobdiff_plain;f=org.simantics.g3d%2Fsrc%2Forg%2Fsimantics%2Fg3d%2Fshape%2FTube.java;h=dc7ff4e5270a31c0707df36e02a4531556781989;hb=53d55c24c779745f188bdb18d32f71d20acb61b2;hp=958993ed391a2cbdf5ccb3735a7a6fc89188e7d2;hpb=87b3241ec277ba3d8e414b26186a032c9cdcaeed;p=simantics%2F3d.git diff --git a/org.simantics.g3d/src/org/simantics/g3d/shape/Tube.java b/org.simantics.g3d/src/org/simantics/g3d/shape/Tube.java index 958993ed..dc7ff4e5 100644 --- a/org.simantics.g3d/src/org/simantics/g3d/shape/Tube.java +++ b/org.simantics.g3d/src/org/simantics/g3d/shape/Tube.java @@ -1,173 +1,259 @@ -package org.simantics.g3d.shape; - -import java.util.ArrayList; -import java.util.List; - -import javax.vecmath.AxisAngle4d; -import javax.vecmath.Vector3d; - -import org.simantics.g3d.math.MathTools; - - -public class Tube { - List vertices; - List colors; - List radiis; - Double radius = 1.0; - int resolution = 8; - - - public void setResolution(int resolution) { - if (resolution > 2) - this.resolution = resolution; - } - - public void setVertices(List vertices) { - this.vertices = vertices; - } - - public void setColors(List colors) { - this.colors = colors; - } - - public void setRadiis(List radiis) { - this.radiis = radiis; - } - - public void setRadius(Double radius) { - this.radius = radius; - } - - - - public Mesh create() { - if (vertices.size() < 2 ) - throw new IllegalArgumentException("Tube must have at least two vertices"); - - Vector3d t = new Vector3d(); - - for (int i = 0; i < vertices.size() - 1; i++) { - t.set(vertices.get(i+1)); - t.sub(vertices.get(i)); - if (t.lengthSquared() < 0.0001) - throw new IllegalArgumentException("vertices at index " + i + " are too close to each other"); - } - - List points = new ArrayList(vertices.size()*resolution); - List normals = new ArrayList(vertices.size()*resolution); - - for (int i = 0; i < vertices.size(); i++) { - createCircle(i,points,normals); - } - - int index[] = new int[(vertices.size()-1)*resolution*6]; - - createIndices(index); - List indices = new ArrayList(); - for (int i = 0; i < index.length; i++) { - indices.add(index[i]); - } - - - - vertices.clear(); - if (colors != null) - colors.clear(); - if (radiis != null) - radiis.clear(); - - return new Mesh(points, normals, indices); - - } - - private void createCircle(int i, List points, List normals) { - final Vector3d up = new Vector3d(0,1,0); - final Vector3d up2 = new Vector3d(0,0,1); - Vector3d p = vertices.get(i); - Vector3d t = getTangent(i); - Vector3d n = new Vector3d(); - if (up.dot(t) < 0.99) { - n.cross(up, t); - } else { - n.cross(up2, t); - } - n.normalize(); - if (radiis != null) { - n.scale(radiis.get(i)); - } else { - n.scale(radius); - } - - for (int index = 0; index < resolution; index ++) { - Vector3d v; - if (index == 0) { - v = new Vector3d(n); - - } else { - AxisAngle4d aa = new AxisAngle4d(t, (Math.PI * 2 * (double)index)/(double)resolution); - v = new Vector3d(); - MathTools.rotate(MathTools.getQuat(aa), n, v); - } - //int vIndex = (i*resolution + index)*3; - Vector3d pt = new Vector3d(p); - pt.add(v); - //points.set(vIndex, pt); - points.add(pt); - v.normalize(); - //normals.set(vIndex, v); - normals.add(v); - } - } - - private Vector3d getTangent(int i) { - Vector3d p,n; - if (i == 0) { - p = vertices.get(0); - n = vertices.get(1); - } else if (i == vertices.size() - 1) { - p = vertices.get(i-1); - n = vertices.get(i); - } else { - p = vertices.get(i-1); - n = vertices.get(i+1); - } - n = new Vector3d(n); - n.sub(p); - n.normalize(); - return n; - } - - private void createIndices(int index[]) { - for (int c = 0; c < vertices.size() - 1; c++) { - for (int s = 0; s < resolution; s++) { - int ii = (c * resolution + s) * 6; - int iv = c*resolution + s; - - /* - iv+1 ---- iv + resolution + 1 - | /| - |/ | - iv ---- iv + resolution - */ - if (s < resolution - 1) { - index[ii+2] = iv; - index[ii+1] = iv+resolution; - index[ii+0] = iv+resolution+1; - - index[ii+5] = iv; - index[ii+4] = iv+resolution+1; - index[ii+3] = iv+1; - } else { - index[ii+2] = iv; - index[ii+1] = iv+resolution; - index[ii+0] = iv+1; - - index[ii+5] = iv; - index[ii+4] = iv+1; - index[ii+3] = iv+1-resolution; - } - } - } - } - -} +/******************************************************************************* + * Copyright (c) 2012, 2013 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.g3d.shape; + +import java.util.ArrayList; +import java.util.List; + +import javax.vecmath.AxisAngle4d; +import javax.vecmath.Tuple3d; +import javax.vecmath.Vector3d; + +import org.simantics.g3d.math.MathTools; + + +public class Tube { + List vertices; + List tangents; + List colors; + List radiis; + Double radius = 1.0; + int resolution = 8; + + boolean cap = false; + + + public void setResolution(int resolution) { + if (resolution > 2) + this.resolution = resolution; + } + + public void setVertices(List vertices) { + this.vertices = vertices; + } + + public void setTangents(List tangents) { + this.tangents = tangents; + } + + public void setColors(List colors) { + this.colors = colors; + } + + public void setRadiis(List radiis) { + this.radiis = radiis; + } + + public void setRadius(Double radius) { + this.radius = radius; + } + + + public void setCap(boolean cap) { + this.cap = cap; + } + + + public Mesh create() { + if (vertices.size() < 2 ) + throw new IllegalArgumentException("Tube must have at least two vertices"); + + Vector3d t = new Vector3d(); + + for (int i = 0; i < vertices.size() - 1; i++) { + t.set(vertices.get(i+1)); + t.sub(vertices.get(i)); + if (t.lengthSquared() < 0.000001) + throw new IllegalArgumentException("vertices at index " + i + " are too close to each other"); + } + + int vcount = vertices.size()*resolution; + int icount = (vertices.size()-1)*resolution*6; + + if (cap) { + vcount+=2; + icount+=resolution * 6; + } + + List points = new ArrayList(vcount); + List normals = new ArrayList(vcount); + + for (int i = 0; i < vertices.size(); i++) { + createCircle(i,points,normals); + } + if (cap) { + int l = vertices.size()-1; + points.add(new Vector3d(vertices.get(0))); + points.add(new Vector3d(vertices.get(l))); + Vector3d n1 = new Vector3d(vertices.get(1)); + n1.sub(vertices.get(0)); + n1.normalize(); + normals.add(n1); + + Vector3d n2 = new Vector3d(vertices.get(l-1)); + n2.sub(vertices.get(l)); + n2.normalize(); + normals.add(n2); + } + + + + + int index[] = new int[icount]; + + createIndices(index); + List indices = new ArrayList(); + for (int i = 0; i < index.length; i++) { + indices.add(index[i]); + } + + + + vertices.clear(); + if (colors != null) + colors.clear(); + if (radiis != null) + radiis.clear(); + + return Mesh.create(points, normals, indices); + + } + + private void createCircle(int i, List points, List normals) { + final Vector3d up = new Vector3d(0,1,0); + final Vector3d up2 = new Vector3d(0,0,1); + Tuple3d p = vertices.get(i); + Vector3d t = getTangent(i); + Vector3d n = new Vector3d(); + if (Math.abs(up.dot(t)) < 0.99) { + n.cross(up, t); + } else { + n.cross(up2, t); + } + n.normalize(); + if (radiis != null) { + n.scale(radiis.get(i)); + } else { + n.scale(radius); + } + + for (int index = 0; index < resolution; index ++) { + Vector3d v; + if (index == 0) { + v = new Vector3d(n); + + } else { + AxisAngle4d aa = new AxisAngle4d(t, (Math.PI * 2 * (double)index)/(double)resolution); + v = new Vector3d(); + MathTools.rotate(MathTools.getQuat(aa), n, v); + } + //int vIndex = (i*resolution + index)*3; + Vector3d pt = new Vector3d(p); + pt.add(v); + //points.set(vIndex, pt); + points.add(pt); + v.normalize(); + //normals.set(vIndex, v); + normals.add(v); + } + } + + private Vector3d getTangent(int i) { + Tuple3d p,n; + if (tangents != null) + return tangents.get(i); + if (i == 0) { + p = vertices.get(0); + n = vertices.get(1); + } else if (i == vertices.size() - 1) { + p = vertices.get(i-1); + n = vertices.get(i); + } else { + p = vertices.get(i-1); + n = vertices.get(i+1); + } + Vector3d nn = new Vector3d(n); + nn.sub(p); + nn.normalize(); + return nn; + } + + private void createIndices(int index[]) { + for (int c = 0; c < vertices.size() - 1; c++) { + for (int s = 0; s < resolution; s++) { + int ii = (c * resolution + s) * 6; + int iv = c*resolution + s; + + /* + iv+1 ---- iv + resolution + 1 + | /| + |/ | + iv ---- iv + resolution + */ + if (s < resolution - 1) { + index[ii+2] = iv; + index[ii+1] = iv+resolution; + index[ii+0] = iv+resolution+1; + + index[ii+5] = iv; + index[ii+4] = iv+resolution+1; + index[ii+3] = iv+1; + } else { + index[ii+2] = iv; + index[ii+1] = iv+resolution; + index[ii+0] = iv+1; + + index[ii+5] = iv; + index[ii+4] = iv+1; + index[ii+3] = iv+1-resolution; + } + } + } + if (cap) { + int c = 0; + int isi = ((vertices.size()-1) * resolution) * 6; + int ivi = vertices.size() * resolution; + for (int s = 0; s < resolution; s++) { + int ii = isi + s*3; + int iv = c*resolution + s; + if (s < resolution - 1) { + index[ii+2] = iv; + index[ii+1] = iv+1; + index[ii+0] = ivi; + } else { + index[ii+2] = iv; + index[ii+1] = iv+1-resolution; + index[ii+0] = ivi; + } + + } + isi += resolution * 3; + c = (vertices.size()-1); + for (int s = 0; s < resolution; s++) { + int ii = isi + s*3; + int iv = c*resolution + s; + if (s < resolution - 1) { + index[ii+2] = iv; + index[ii+1] = iv+1; + index[ii+0] = ivi+1; + } else { + index[ii+2] = iv; + index[ii+1] = iv+1-resolution; + index[ii+0] = ivi+1; + } + + } + + } + } + +}