1 /* $RCSfile$
2  * $Author: hansonr $
3  * $Date: 2007-03-30 11:40:16 -0500 (Fri, 30 Mar 2007) $
4  * $Revision: 7273 $
5  *
6  * Copyright (C) 2007 Miguel, Bob, Jmol Development
7  *
8  * Contact: hansonr@stolaf.edu
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 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 package org.jmol.jvxl.readers;
25 
26 import java.io.BufferedReader;
27 import java.util.Hashtable;
28 import java.util.Map;
29 
30 
31 import javajs.util.BS;
32 
33 import javajs.util.CU;
34 import javajs.util.P3;
35 import javajs.util.PT;
36 
37 /*
38  *
39  * See at http://www.eg-models.de/formats/Format_Obj.html
40  * an extension of the Edinburgh pmesh file format
41  *   see http://i-sight.sourceforge.net/docs/GridView/MeshFileReader.html#ReadPMeshFile(java.lang.String,%20GridView.OutputPanel,%20javax.swing.JProgressBar)
42  *
43  * Here we are just looking for v, g, and f.
44  *
45  * Groups are designated as any multi-isosurface file using an
46  * integer after the file name. In this case, no integer
47  * means "read all the data"
48  *
49  * Header #obj or #pmesh will identify the mesh as an OBJ file format
50  *
51  */
52 
53 //  #obj 6825 vertices 12620 faces 9 groups
54 //
55 //  mtllib g_visible.mtl
56 //
57 //  v 111.025230 65.735298 2.483954
58 //  v 111.221596 65.772804 2.270540
59 //  v 111.046539 65.643066 2.200877
60 //  ...
61 //  g k000000
62 //  usemtl k000000
63 //  f 1 2 3
64 //  f 1 3 4
65 //  f 1 4 5
66 //
67 //  g k0066FF
68 //  usemtl k0066FF
69 //  f 6 7 8
70 //  f 8 7 9
71 //  ...
72 //  f 6825 6805 6824
73 //  f 6821 6808 6825
74 //  f 6808 6825 6804
75 //  f 6824 6807 6822
76 //  f 6807 6822 6815
77 //  f 6805 6824 6806
78 //  f 6806 6824 6807
79 //
80 
81 
82 class ObjReader extends PmeshReader {
83 
ObjReader()84   ObjReader(){}
85 
86   @Override
init2(SurfaceGenerator sg, BufferedReader br)87   void init2(SurfaceGenerator sg, BufferedReader br) {
88     init2PR(sg, br);
89     type = "obj";
90     setHeader();
91   }
92 
93   @Override
readVertices()94   protected boolean readVertices() throws Exception {
95     // also reads polygons
96     pmeshError = "pmesh ERROR: invalid vertex/face list";
97     P3 pt = new P3();
98     int color = 0;
99     int ia, ib, ic, id = 0;
100     int i = 0;
101     int nPts = 0;
102     Map<String, Integer> htPymol = new Hashtable<String, Integer>();
103     Integer ipt = null;
104     String spt = null;
105     int[] pymolMap = new int[3];
106     // pymol writes a crude file with much re-writing of vertices
107 
108     BS bsOK = new BS();
109     while (rd() != null) {
110       if (line.length() < 2 || line.charAt(1) != ' ') {
111         if (params.readAllData && line.startsWith("usemtl"))
112           // usemtl k00FF00
113             color = CU.getArgbFromString("[x" + line.substring(8) + "]");
114         continue;
115       }
116       switch (line.charAt(0)) {
117       case 'v':
118         next[0] = 2;
119         pt.set(PT.parseFloatNext(line, next), PT.parseFloatNext(line, next),
120             PT.parseFloatNext(line, next));
121         boolean addHt = false;
122         if (htPymol == null) {
123           i = nVertices;
124         } else if ((ipt = htPymol.get(spt = "" + pt)) == null) {
125           addHt = true;
126           i = nVertices;
127         } else {
128           i = ipt.intValue();
129         }
130 
131         int j = i;
132         if (i == nVertices) {
133           if (isAnisotropic)
134             setVertexAnisotropy(pt);
135           j = addVertexCopy(pt, 0, nVertices++, true);
136           if (j >= 0)
137             bsOK.set(i);
138         }
139         pymolMap[nPts % 3] = j;
140         if (addHt)
141           htPymol.put(spt, Integer.valueOf(i));
142         nPts++;
143         if (htPymol != null && nPts > 3)
144           htPymol = null;
145         break;
146       case 'f':
147         if (nPts == 3 && line.indexOf("//") < 0)
148           htPymol = null;
149         nPts = 0;
150         nPolygons++;
151         String[] tokens = PT.getTokens(line);
152         int vertexCount = tokens.length - 1;
153         if (vertexCount == 4)
154           htPymol = null;
155         if (htPymol == null) {
156           ia = PT.parseInt(tokens[1]) - 1;
157           ib = PT.parseInt(tokens[2]) - 1;
158           ic = PT.parseInt(tokens[3]) - 1;
159           pmeshError = " " + ia + " " + ib + " " + ic + " " + line;
160           if (!bsOK.get(ia) || !bsOK.get(ib) || !bsOK.get(ic))
161             continue;
162           if (vertexCount == 4) {
163             id = PT.parseInt(tokens[4]) - 1;
164             boolean isOK = (bsOK.get(id));
165             nTriangles = addTriangleCheck(ia, ib, ic, (isOK ? 3 : 7), 0, false, color);
166             if (isOK)
167               nTriangles = addTriangleCheck(ia, ic, id, 6, 0, false, color);
168             continue;
169           }
170         } else {
171           ia = pymolMap[0];
172           ib = pymolMap[1];
173           ic = pymolMap[2];
174           if (ia < 0 || ib < 0 || ic < 0)
175             continue;
176         }
177         nTriangles = addTriangleCheck(ia, ib, ic, 7, 0, false, color);
178         break;
179       case 'g':
180         htPymol = null;
181         if (params.readAllData)
182           try {
183             color = PT.parseIntRadix(line.substring(3), 16);
184           } catch (Throwable e) {
185             color = 0;
186           }
187         break;
188       }
189     }
190     pmeshError = null;
191     return true;
192   }
193 
194   @Override
readPolygons()195   protected boolean readPolygons() {
196     return true;
197   }
198 }
199