1 /*******************************************************************************
2 * Copyright (c) 2012, 2013 Association for Decentralized Information Management in
4 * All rights reserved. This program and the accompanying materials
5 * are made available under the terms of the Eclipse Public License v1.0
6 * which accompanies this distribution, and is available at
7 * http://www.eclipse.org/legal/epl-v10.html
10 * VTT Technical Research Centre of Finland - initial API and implementation
11 *******************************************************************************/
12 package org.simantics.g3d.shape;
14 import java.util.ArrayList;
15 import java.util.List;
17 import javax.vecmath.AxisAngle4d;
18 import javax.vecmath.Tuple3d;
19 import javax.vecmath.Vector3d;
21 import org.simantics.g3d.math.MathTools;
25 List<Tuple3d> vertices;
26 List<Vector3d> tangents;
35 public void setResolution(int resolution) {
37 this.resolution = resolution;
40 public void setVertices(List<Tuple3d> vertices) {
41 this.vertices = vertices;
44 public void setTangents(List<Vector3d> tangents) {
45 this.tangents = tangents;
48 public void setColors(List<Color4d> colors) {
52 public void setRadiis(List<Double> radiis) {
56 public void setRadius(Double radius) {
61 public void setCap(boolean cap) {
66 public Mesh create() {
67 if (vertices.size() < 2 )
68 throw new IllegalArgumentException("Tube must have at least two vertices");
70 Vector3d t = new Vector3d();
72 if (tangents == null) {
73 for (int i = 0; i < vertices.size() - 1; i++) {
74 t.set(vertices.get(i+1));
75 t.sub(vertices.get(i));
76 if (t.lengthSquared() < 0.0000001)
77 throw new IllegalArgumentException("vertices at index " + i + " are too close to each other");
81 int vcount = vertices.size()*resolution;
82 int icount = (vertices.size()-1)*resolution*6;
86 icount+=resolution * 6;
89 List<Vector3d> points = new ArrayList<Vector3d>(vcount);
90 List<Vector3d> normals = new ArrayList<Vector3d>(vcount);
92 for (int i = 0; i < vertices.size(); i++) {
93 createCircle(i,points,normals);
96 int l = vertices.size()-1;
97 points.add(new Vector3d(vertices.get(0)));
98 points.add(new Vector3d(vertices.get(l)));
99 Vector3d n1 = new Vector3d(vertices.get(1));
100 n1.sub(vertices.get(0));
104 Vector3d n2 = new Vector3d(vertices.get(l-1));
105 n2.sub(vertices.get(l));
113 int index[] = new int[icount];
115 createIndices(index);
116 List<Integer> indices = new ArrayList<Integer>();
117 for (int i = 0; i < index.length; i++) {
118 indices.add(index[i]);
129 return Mesh.create(points, normals, indices);
133 private void createCircle(int i, List<Vector3d> points, List<Vector3d> normals) {
134 final Vector3d up = new Vector3d(0,1,0);
135 final Vector3d up2 = new Vector3d(0,0,1);
136 Tuple3d p = vertices.get(i);
137 Vector3d t = getTangent(i);
138 Vector3d n = new Vector3d();
139 if (Math.abs(up.dot(t)) < 0.99) {
145 if (radiis != null) {
146 n.scale(radiis.get(i));
151 for (int index = 0; index < resolution; index ++) {
157 AxisAngle4d aa = new AxisAngle4d(t, (Math.PI * 2 * (double)index)/(double)resolution);
159 MathTools.rotate(MathTools.getQuat(aa), n, v);
161 //int vIndex = (i*resolution + index)*3;
162 Vector3d pt = new Vector3d(p);
164 //points.set(vIndex, pt);
167 //normals.set(vIndex, v);
172 private Vector3d getTangent(int i) {
174 if (tangents != null)
175 return tangents.get(i);
179 } else if (i == vertices.size() - 1) {
180 p = vertices.get(i-1);
183 p = vertices.get(i-1);
184 n = vertices.get(i+1);
186 Vector3d nn = new Vector3d(n);
192 private void createIndices(int index[]) {
193 for (int c = 0; c < vertices.size() - 1; c++) {
194 for (int s = 0; s < resolution; s++) {
195 int ii = (c * resolution + s) * 6;
196 int iv = c*resolution + s;
199 iv+1 ---- iv + resolution + 1
202 iv ---- iv + resolution
204 if (s < resolution - 1) {
206 index[ii+1] = iv+resolution;
207 index[ii+0] = iv+resolution+1;
210 index[ii+4] = iv+resolution+1;
214 index[ii+1] = iv+resolution;
219 index[ii+3] = iv+1-resolution;
225 int isi = ((vertices.size()-1) * resolution) * 6;
226 int ivi = vertices.size() * resolution;
227 for (int s = 0; s < resolution; s++) {
229 int iv = c*resolution + s;
230 if (s < resolution - 1) {
236 index[ii+1] = iv+1-resolution;
241 isi += resolution * 3;
242 c = (vertices.size()-1);
243 for (int s = 0; s < resolution; s++) {
245 int iv = c*resolution + s;
246 if (s < resolution - 1) {
252 index[ii+1] = iv+1-resolution;