1 /* $RCSfile$ 2 * $Author: hansonr $ 3 * $Date: 2007-04-16 18:06:32 -0500 (Mon, 16 Apr 2007) $ 4 * $Revision: 7418 $ 5 * 6 * Copyright (C) 2002-2005 The Jmol Development Team 7 * 8 * Contact: jmol-developers@lists.sf.net 9 * 10 * This library is free software; you can redistribute it and/or 11 * modify it under the terms of the GNU Lesser General Public 12 * License as published by the Free Software Foundation; either 13 * version 2.1 of the License, or (at your option) any later version. 14 * 15 * This library is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 18 * Lesser General Public License for more details. 19 * 20 * You should have received a copy of the GNU Lesser General Public 21 * License along with this library; if not, write to the Free Software 22 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 23 */ 24 25 package org.jmol.shapesurface; 26 27 import java.util.Hashtable; 28 import java.util.Map; 29 30 import org.jmol.shape.Mesh; 31 32 import javajs.util.Measure; 33 import javajs.util.P3; 34 import javajs.util.T3; 35 import javajs.util.V3; 36 37 public class Pmesh extends Isosurface { 38 @Override initShape()39 public void initShape() { 40 super.initShape(); 41 myType = "pmesh"; 42 } 43 44 @Override getProperty(String property, int index)45 public Object getProperty(String property, int index) { 46 if (property == "face") { 47 Mesh m = currentMesh; 48 if (index >= 0 49 && (index >= meshCount || (m = meshes[index]) == null)) 50 return null; 51 return m == null ? null : getFace(m); 52 } 53 return getPropI(property, index); 54 } 55 56 /** 57 * return a cycle of points generating this face 58 * used after slabbing 59 * 60 * @param m 61 * @return set of points constituting this face 62 */ getFace(Mesh m)63 private P3[] getFace(Mesh m) { 64 if (m.haveQuads) 65 return null; 66 T3[] vs = m.vs; 67 Map<String, int[]> htEdges = new Hashtable<String, int[]>(); 68 int v1 = 0, v0, v01; 69 int n = 0; 70 int[] edge0 = null; 71 for (int i = m.pc; --i >= 0;) { 72 if (m.bsSlabDisplay != null && !m.bsSlabDisplay.get(i)) 73 continue; 74 int[] triangle = m.pis[i]; 75 int mask = triangle[3]; 76 for (int j = 0; j < 3; j++) 77 if ((mask & (1 << j)) != 0) { 78 v1 = triangle[j]; 79 int v2 = triangle[(j + 1) % 3]; 80 String key = v2 + "_" + v1; 81 if (htEdges.containsKey(key)) { 82 htEdges.remove(key); 83 n--; 84 } else { 85 n++; 86 edge0 = new int[] { v1, v2 }; 87 htEdges.put(v1 + "_" + v2, edge0); 88 htEdges.put("" + v1, edge0); 89 } 90 } 91 } 92 if (n == 0) 93 return null; 94 int[][] a = new int[n][2]; 95 a[0] = edge0; 96 V3 vectorBA = new V3(); 97 V3 vectorBC = new V3(); 98 v01 = v0 = a[0][0]; 99 v1 = a[0][1]; 100 int pt = 0; 101 float min = 0.0001f; 102 while (v1 != v0) { 103 int[] edge = htEdges.get("" + v1); 104 if (edge == null) 105 break; 106 float angle = Measure.computeAngle(vs[v01], vs[v1], vs[edge[1]], 107 vectorBA, vectorBC, true); 108 float d2 = vs[v1].distanceSquared(vs[edge[1]]); 109 //System.out.println("pmesh getFace " + angle + " " + d2 + " " + v01 + " " + v1 + " " + edge[1]); 110 //System.out.println("draw " + vs[v01] + " " + vs[v1] + " " + vs[edge[1]]); 111 v1 = edge[1]; 112 if (angle < 179 && d2 > min) { 113 a[++pt] = edge; 114 v01 = edge[0]; 115 } else { 116 a[pt][1] = v1; 117 } 118 } 119 if (Measure.computeAngle(vs[v01], vs[v1], vs[a[0][1]], 120 vectorBA, vectorBC, true) >= 179 || vs[v1].distanceSquared(vs[a[0][1]]) <= min) { 121 a[0][0] = a[pt--][0]; 122 } 123 n = (pt < 0 ? 1 : ++pt); 124 P3[] pts = new P3[n]; 125 for (int i = 0; i < n; i++) 126 pts[i] = P3.newP(vs[a[i][0]]); 127 //System.out.println("pmesh getFace now " + n); 128 return pts; 129 } 130 131 132 } 133