]> gerrit.simantics Code Review - simantics/3d.git/blobdiff - org.simantics.g3d/src/org/simantics/g3d/shape/Tube.java
White space clean-up
[simantics/3d.git] / org.simantics.g3d / src / org / simantics / g3d / shape / Tube.java
index 958993ed391a2cbdf5ccb3735a7a6fc89188e7d2..dc7ff4e5270a31c0707df36e02a4531556781989 100644 (file)
-package org.simantics.g3d.shape;\r
-\r
-import java.util.ArrayList;\r
-import java.util.List;\r
-\r
-import javax.vecmath.AxisAngle4d;\r
-import javax.vecmath.Vector3d;\r
-\r
-import org.simantics.g3d.math.MathTools;\r
-\r
-\r
-public class Tube {\r
-       List<Vector3d> vertices;\r
-       List<Color4d> colors;\r
-       List<Double> radiis;\r
-       Double radius = 1.0;\r
-       int resolution = 8;\r
-       \r
-       \r
-       public void setResolution(int resolution) {\r
-               if (resolution > 2)\r
-                       this.resolution = resolution;\r
-       }\r
-       \r
-       public void setVertices(List<Vector3d> vertices) {\r
-               this.vertices = vertices;\r
-       }\r
-\r
-       public void setColors(List<Color4d> colors) {\r
-               this.colors = colors;\r
-       }\r
-       \r
-       public void setRadiis(List<Double> radiis) {\r
-               this.radiis = radiis;\r
-       }\r
-       \r
-       public void setRadius(Double radius) {\r
-               this.radius = radius;\r
-       }\r
-       \r
-       \r
-       \r
-       public Mesh create() {\r
-               if (vertices.size() < 2 )\r
-                       throw new IllegalArgumentException("Tube must have at least two vertices");\r
-               \r
-               Vector3d t = new Vector3d();\r
-               \r
-               for (int i = 0; i < vertices.size() - 1; i++) {\r
-                       t.set(vertices.get(i+1));\r
-                       t.sub(vertices.get(i));\r
-                       if (t.lengthSquared() < 0.0001)\r
-                               throw new IllegalArgumentException("vertices at index " + i + " are too close to each other");\r
-               }\r
-               \r
-               List<Vector3d> points = new ArrayList<Vector3d>(vertices.size()*resolution);\r
-               List<Vector3d> normals = new ArrayList<Vector3d>(vertices.size()*resolution);\r
-               \r
-               for (int i = 0; i < vertices.size(); i++) {\r
-                       createCircle(i,points,normals);\r
-               }\r
-               \r
-               int index[] = new int[(vertices.size()-1)*resolution*6];\r
-               \r
-               createIndices(index);\r
-               List<Integer> indices = new ArrayList<Integer>();\r
-               for (int i = 0; i < index.length; i++) {\r
-                       indices.add(index[i]);\r
-               }\r
-               \r
-               \r
-               \r
-               vertices.clear();\r
-               if (colors != null)\r
-                       colors.clear();\r
-               if (radiis != null)\r
-                       radiis.clear();\r
-               \r
-               return new Mesh(points, normals, indices);\r
-               \r
-       }\r
-       \r
-       private void createCircle(int i, List<Vector3d> points, List<Vector3d> normals) {\r
-               final Vector3d up = new Vector3d(0,1,0);\r
-               final Vector3d up2 = new Vector3d(0,0,1);\r
-               Vector3d p = vertices.get(i);\r
-               Vector3d t = getTangent(i);\r
-               Vector3d n = new Vector3d();\r
-               if (up.dot(t) < 0.99) {\r
-                       n.cross(up, t);\r
-               } else {\r
-                       n.cross(up2, t);\r
-               }\r
-               n.normalize();\r
-               if (radiis != null) {\r
-                       n.scale(radiis.get(i));\r
-               } else {\r
-                       n.scale(radius);\r
-               }\r
-               \r
-               for (int index = 0; index < resolution; index ++) {\r
-                       Vector3d v;\r
-                       if (index == 0) {\r
-                               v = new Vector3d(n);\r
-                               \r
-                       } else {\r
-                               AxisAngle4d aa = new AxisAngle4d(t, (Math.PI * 2 * (double)index)/(double)resolution);\r
-                               v = new Vector3d();\r
-                               MathTools.rotate(MathTools.getQuat(aa), n, v);\r
-                       }\r
-                       //int vIndex = (i*resolution + index)*3;\r
-                       Vector3d pt = new Vector3d(p);\r
-                       pt.add(v);\r
-                       //points.set(vIndex, pt);\r
-                       points.add(pt);\r
-                       v.normalize();\r
-                       //normals.set(vIndex, v);\r
-                       normals.add(v);\r
-               }\r
-       }\r
-       \r
-       private Vector3d getTangent(int i) {\r
-               Vector3d p,n;\r
-               if (i == 0) {\r
-                       p = vertices.get(0);\r
-                       n = vertices.get(1);\r
-               } else if (i == vertices.size() - 1) {\r
-                       p = vertices.get(i-1);\r
-                       n = vertices.get(i);\r
-               } else {\r
-                       p = vertices.get(i-1);\r
-                       n = vertices.get(i+1);\r
-               }\r
-               n = new Vector3d(n);\r
-               n.sub(p);\r
-               n.normalize();\r
-               return n;\r
-       }\r
-       \r
-       private void createIndices(int index[]) {\r
-               for (int c = 0; c < vertices.size() - 1; c++) {\r
-                       for (int s = 0; s < resolution; s++) {\r
-                               int ii = (c * resolution + s) * 6;\r
-                               int iv = c*resolution + s;\r
-                               \r
-                               /*\r
-                            iv+1 ---- iv + resolution + 1\r
-                                     | /|\r
-                                     |/ |\r
-                                  iv ---- iv + resolution \r
-                               */\r
-                               if (s < resolution - 1) {\r
-                                       index[ii+2] = iv;\r
-                                       index[ii+1] = iv+resolution;\r
-                                       index[ii+0] = iv+resolution+1;\r
-                                       \r
-                                       index[ii+5] = iv;\r
-                                       index[ii+4] = iv+resolution+1;\r
-                                       index[ii+3] = iv+1;\r
-                               } else {\r
-                                       index[ii+2] = iv;\r
-                                       index[ii+1] = iv+resolution;\r
-                                       index[ii+0] = iv+1;\r
-                                       \r
-                                       index[ii+5] = iv;\r
-                                       index[ii+4] = iv+1;\r
-                                       index[ii+3] = iv+1-resolution;\r
-                               }\r
-                       }\r
-               }\r
-       }\r
-\r
-}\r
+/*******************************************************************************
+ * 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<Tuple3d> vertices;
+       List<Vector3d> tangents;
+       List<Color4d> colors;
+       List<Double> 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<Tuple3d> vertices) {
+               this.vertices = vertices;
+       }
+       
+       public void setTangents(List<Vector3d> tangents) {
+               this.tangents = tangents;
+       }
+
+       public void setColors(List<Color4d> colors) {
+               this.colors = colors;
+       }
+       
+       public void setRadiis(List<Double> 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<Vector3d> points = new ArrayList<Vector3d>(vcount);
+               List<Vector3d> normals = new ArrayList<Vector3d>(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<Integer> indices = new ArrayList<Integer>();
+               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<Vector3d> points, List<Vector3d> 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;
+                               }
+                               
+                       }
+                       
+               }
+       }
+
+}